From c2800a5a60f6b914f9a62c7ab301cfd49f97075f Mon Sep 17 00:00:00 2001 From: Rajesh Patil Date: Fri, 18 Jun 2021 09:17:34 +0530 Subject: soc/qualcomm/common: Move UART SC7180 driver to common section Move existing UART driver from sc7180 to common folder. This implements UART driver for QCOM SoC's BUG=b:182963902 TEST=Validated on qualcomm sc7180 and sc7280 development board. Signed-off-by: Rajesh Patil Change-Id: I7bc2d3765f956e04bae3e45c3a9b9e2ad424c7b1 Reviewed-on: https://review.coreboot.org/c/coreboot/+/55954 Tested-by: build bot (Jenkins) Reviewed-by: Shelley Chen --- src/soc/qualcomm/common/qupv3_uart.c | 154 +++++++++++++++++++++++++++++++++++ src/soc/qualcomm/sc7180/Makefile.inc | 6 +- src/soc/qualcomm/sc7180/qupv3_uart.c | 154 ----------------------------------- 3 files changed, 157 insertions(+), 157 deletions(-) create mode 100644 src/soc/qualcomm/common/qupv3_uart.c delete mode 100644 src/soc/qualcomm/sc7180/qupv3_uart.c (limited to 'src') diff --git a/src/soc/qualcomm/common/qupv3_uart.c b/src/soc/qualcomm/common/qupv3_uart.c new file mode 100644 index 0000000000..2086c1df70 --- /dev/null +++ b/src/soc/qualcomm/common/qupv3_uart.c @@ -0,0 +1,154 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* COMMON STATUS/CONFIGURATION REGISTERS AND MASKS */ + +#define GENI_STATUS_M_GENI_CMD_ACTIVE_MASK 0x1 +#define GENI_STATUS_S_GENI_CMD_ACTIVE_MASK 0x1000 + +#define UART_TX_WATERMARK_MARGIN 4 /* Represented in words */ +#define UART_RX_WATERMARK_MARGIN 8 /* Represented in words */ +#define UART_RX_RFR_WATERMARK_MARGIN 4 /* Represented in words */ +#define UART_TX_BITS_PER_WORD 8 +#define UART_RX_BITS_PER_WORD 8 +#define START_UART_TX 0x8000000 +#define START_UART_RX 0x8000000 + +/* UART FIFO Packing Configuration. */ +/* Start_idx:0, direction:0, len:7, stop:0 */ +#define UART_TX_PACK_VECTOR0 0x0E +/* Start_idx:8, direction:0, len:7, stop:0 */ +#define UART_TX_PACK_VECTOR1 0x10E +/* Start_idx:16, direction:0, len:7, stop:0 */ +#define UART_TX_PACK_VECTOR2 0x20E +/* Start_idx:24, direction:0, len:7, stop:1 */ +#define UART_TX_PACK_VECTOR3 0x30F +/* Start_idx:0, direction:0, len:7, stop:1 */ +#define UART_RX_PACK_VECTOR0 0xF +#define UART_RX_PACK_VECTOR2 0x00 + +void uart_tx_flush(unsigned int idx) +{ + struct qup_regs *regs = qup[idx].regs; + + while (read32(®s->geni_status) & + GENI_STATUS_M_GENI_CMD_ACTIVE_MASK) + ; +} + +void uart_init(unsigned int idx) +{ + struct qup_regs *regs = qup[idx].regs; + unsigned int reg_value; + unsigned int div, baud_rate, uart_freq; + + /* + * If the RX (secondary) sequencer is already active, it means the core + * has been already initialized in the previous stage. Skip + * configuration + */ + if (read32(®s->geni_status) & GENI_STATUS_S_GENI_CMD_ACTIVE_MASK) + return; + + qupv3_se_fw_load_and_init(idx, SE_PROTOCOL_UART, FIFO); + clock_enable_qup(idx); + + reg_value = read32(®s->geni_fw_revision_ro); + reg_value &= GENI_FW_REVISION_RO_PROTOCOL_MASK; + reg_value >>= GENI_FW_REVISION_RO_PROTOCOL_SHIFT; + + assert(reg_value == SE_PROTOCOL_UART); + + baud_rate = get_uart_baudrate(); + + /*requires 16 clock pulses to sample 1 bit of data */ + uart_freq = baud_rate * 16; + + div = DIV_ROUND_CLOSEST(SRC_XO_HZ, uart_freq); + write32(®s->geni_ser_m_clk_cfg, (div << 4) | 1); + write32(®s->geni_ser_s_clk_cfg, (div << 4) | 1); + + /* GPIO Configuration */ + gpio_configure(qup[idx].pin[2], qup[idx].func[2], GPIO_PULL_UP, + GPIO_2MA, GPIO_OUTPUT); + gpio_configure(qup[idx].pin[3], qup[idx].func[3], GPIO_PULL_UP, + GPIO_2MA, GPIO_INPUT); + + write32(®s->geni_tx_watermark_reg, UART_TX_WATERMARK_MARGIN); + write32(®s->geni_rx_watermark_reg, FIFO_DEPTH + - UART_RX_WATERMARK_MARGIN); + write32(®s->geni_rx_rfr_watermark_reg, + FIFO_DEPTH - UART_RX_RFR_WATERMARK_MARGIN); + + write32(®s->uart_tx_word_len, UART_TX_BITS_PER_WORD); + write32(®s->uart_rx_word_len, UART_RX_BITS_PER_WORD); + + /* Disable TX parity calculation */ + write32(®s->uart_tx_parity_cfg, 0x0); + /* Ignore CTS line status for TX communication */ + write32(®s->uart_tx_trans_cfg_reg, 0x2); + /* Disable RX parity calculation */ + write32(®s->uart_rx_parity_cfg, 0x0); + /* Disable parity, framing and break check on received word */ + write32(®s->uart_rx_trans_cfg, 0x0); + /* Set UART TX stop bit len to one UART bit length */ + write32(®s->uart_tx_stop_bit_len, 0x0); + write32(®s->uart_rx_stale_cnt, 0x16 * 10); + + write32(®s->geni_tx_packing_cfg0, UART_TX_PACK_VECTOR0 | + (UART_TX_PACK_VECTOR1 << 10)); + write32(®s->geni_tx_packing_cfg1, UART_TX_PACK_VECTOR2 | + (UART_TX_PACK_VECTOR3 << 10)); + write32(®s->geni_rx_packing_cfg0, UART_RX_PACK_VECTOR0); + write32(®s->geni_rx_packing_cfg1, UART_RX_PACK_VECTOR2); + + /* Start RX */ + write32(®s->geni_s_cmd0, START_UART_RX); +} + +unsigned char uart_rx_byte(unsigned int idx) +{ + struct qup_regs *regs = qup[idx].regs; + + if (read32(®s->geni_rx_fifo_status) & RX_FIFO_WC_MSK) + return read32(®s->geni_rx_fifon) & 0xFF; + return 0; +} + +void uart_tx_byte(unsigned int idx, unsigned char data) +{ + struct qup_regs *regs = qup[idx].regs; + + uart_tx_flush(idx); + + write32(®s->uart_tx_trans_len, 1); + /* Start TX */ + write32(®s->geni_m_cmd0, START_UART_TX); + write32(®s->geni_tx_fifon, data); +} + +uintptr_t uart_platform_base(unsigned int idx) +{ + return (uintptr_t)qup[idx].regs; +} + +void uart_fill_lb(void *data) +{ + struct lb_serial serial = {0}; + + serial.type = LB_SERIAL_TYPE_MEMORY_MAPPED; + serial.baseaddr = (uint32_t)uart_platform_base(CONFIG_UART_FOR_CONSOLE); + serial.baud = get_uart_baudrate(); + serial.regwidth = 4; + serial.input_hertz = SRC_XO_HZ; + + lb_add_serial(&serial, data); +} diff --git a/src/soc/qualcomm/sc7180/Makefile.inc b/src/soc/qualcomm/sc7180/Makefile.inc index 8fb8b48e10..7c393b3fac 100644 --- a/src/soc/qualcomm/sc7180/Makefile.inc +++ b/src/soc/qualcomm/sc7180/Makefile.inc @@ -21,7 +21,7 @@ bootblock-y += bootblock.c bootblock-y += mmu.c bootblock-$(CONFIG_DRIVERS_UART) += ../common/uart_bitbang.c ################################################################################ -verstage-$(CONFIG_DRIVERS_UART) += qupv3_uart.c +verstage-$(CONFIG_DRIVERS_UART) += ../common/qupv3_uart.c ################################################################################ romstage-y += cbmem.c @@ -31,14 +31,14 @@ romstage-y += ../common/mmu.c romstage-y += mmu.c romstage-y += usb.c romstage-y += carve_out.c -romstage-$(CONFIG_DRIVERS_UART) += qupv3_uart.c +romstage-$(CONFIG_DRIVERS_UART) += ../common/qupv3_uart.c ################################################################################ ramstage-y += soc.c ramstage-y += carve_out.c ramstage-y += aop_load_reset.c ramstage-y += usb.c -ramstage-$(CONFIG_DRIVERS_UART) += qupv3_uart.c +ramstage-$(CONFIG_DRIVERS_UART) += ../common/qupv3_uart.c ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += display/dsi_phy_pll.c ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += display/dsi_phy.c ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += display/dsi.c diff --git a/src/soc/qualcomm/sc7180/qupv3_uart.c b/src/soc/qualcomm/sc7180/qupv3_uart.c deleted file mode 100644 index 862c950cfb..0000000000 --- a/src/soc/qualcomm/sc7180/qupv3_uart.c +++ /dev/null @@ -1,154 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* COMMON STATUS/CONFIGURATION REGISTERS AND MASKS */ - -#define GENI_STATUS_M_GENI_CMD_ACTIVE_MASK 0x1 -#define GENI_STATUS_S_GENI_CMD_ACTIVE_MASK 0x1000 - -#define UART_TX_WATERMARK_MARGIN 4 /* Represented in words */ -#define UART_RX_WATERMARK_MARGIN 8 /* Represented in words */ -#define UART_RX_RFR_WATERMARK_MARGIN 4 /* Represented in words */ -#define UART_TX_BITS_PER_WORD 8 -#define UART_RX_BITS_PER_WORD 8 -#define START_UART_TX 0x8000000 -#define START_UART_RX 0x8000000 - -/* UART FIFO Packing Configuration. */ -/* Start_idx:0, direction:0, len:7, stop:0 */ -#define UART_TX_PACK_VECTOR0 0x0E -/* Start_idx:8, direction:0, len:7, stop:0 */ -#define UART_TX_PACK_VECTOR1 0x10E -/* Start_idx:16, direction:0, len:7, stop:0 */ -#define UART_TX_PACK_VECTOR2 0x20E -/* Start_idx:24, direction:0, len:7, stop:1 */ -#define UART_TX_PACK_VECTOR3 0x30F -/* Start_idx:0, direction:0, len:7, stop:1 */ -#define UART_RX_PACK_VECTOR0 0xF -#define UART_RX_PACK_VECTOR2 0x00 - -void uart_tx_flush(unsigned int idx) -{ - struct qup_regs *regs = qup[idx].regs; - - while (read32(®s->geni_status) & - GENI_STATUS_M_GENI_CMD_ACTIVE_MASK) - ; -} - -void uart_init(unsigned int idx) -{ - struct qup_regs *regs = qup[idx].regs; - unsigned int reg_value; - unsigned int div, baud_rate, uart_freq; - - /* - * If the RX (secondary) sequencer is already active, it means the core - * has been already initialized in the previous stage. Skip - * configuration - */ - if (read32(®s->geni_status) & GENI_STATUS_S_GENI_CMD_ACTIVE_MASK) - return; - - qupv3_se_fw_load_and_init(idx, SE_PROTOCOL_UART, FIFO); - clock_enable_qup(idx); - - reg_value = read32(®s->geni_fw_revision_ro); - reg_value &= GENI_FW_REVISION_RO_PROTOCOL_MASK; - reg_value >>= GENI_FW_REVISION_RO_PROTOCOL_SHIFT; - - assert(reg_value == SE_PROTOCOL_UART); - - baud_rate = get_uart_baudrate(); - - /* sc7180 requires 16 clock pulses to sample 1 bit of data */ - uart_freq = baud_rate * 16; - - div = DIV_ROUND_CLOSEST(SRC_XO_HZ, uart_freq); - write32(®s->geni_ser_m_clk_cfg, (div << 4) | 1); - write32(®s->geni_ser_s_clk_cfg, (div << 4) | 1); - - /* GPIO Configuration */ - gpio_configure(qup[idx].pin[2], qup[idx].func[2], GPIO_PULL_UP, - GPIO_2MA, GPIO_OUTPUT); - gpio_configure(qup[idx].pin[3], qup[idx].func[3], GPIO_PULL_UP, - GPIO_2MA, GPIO_INPUT); - - write32(®s->geni_tx_watermark_reg, UART_TX_WATERMARK_MARGIN); - write32(®s->geni_rx_watermark_reg, FIFO_DEPTH - - UART_RX_WATERMARK_MARGIN); - write32(®s->geni_rx_rfr_watermark_reg, - FIFO_DEPTH - UART_RX_RFR_WATERMARK_MARGIN); - - write32(®s->uart_tx_word_len, UART_TX_BITS_PER_WORD); - write32(®s->uart_rx_word_len, UART_RX_BITS_PER_WORD); - - /* Disable TX parity calculation */ - write32(®s->uart_tx_parity_cfg, 0x0); - /* Ignore CTS line status for TX communication */ - write32(®s->uart_tx_trans_cfg_reg, 0x2); - /* Disable RX parity calculation */ - write32(®s->uart_rx_parity_cfg, 0x0); - /* Disable parity, framing and break check on received word */ - write32(®s->uart_rx_trans_cfg, 0x0); - /* Set UART TX stop bit len to one UART bit length */ - write32(®s->uart_tx_stop_bit_len, 0x0); - write32(®s->uart_rx_stale_cnt, 0x16 * 10); - - write32(®s->geni_tx_packing_cfg0, UART_TX_PACK_VECTOR0 | - (UART_TX_PACK_VECTOR1 << 10)); - write32(®s->geni_tx_packing_cfg1, UART_TX_PACK_VECTOR2 | - (UART_TX_PACK_VECTOR3 << 10)); - write32(®s->geni_rx_packing_cfg0, UART_RX_PACK_VECTOR0); - write32(®s->geni_rx_packing_cfg1, UART_RX_PACK_VECTOR2); - - /* Start RX */ - write32(®s->geni_s_cmd0, START_UART_RX); -} - -unsigned char uart_rx_byte(unsigned int idx) -{ - struct qup_regs *regs = qup[idx].regs; - - if (read32(®s->geni_rx_fifo_status) & RX_FIFO_WC_MSK) - return read32(®s->geni_rx_fifon) & 0xFF; - return 0; -} - -void uart_tx_byte(unsigned int idx, unsigned char data) -{ - struct qup_regs *regs = qup[idx].regs; - - uart_tx_flush(idx); - - write32(®s->uart_tx_trans_len, 1); - /* Start TX */ - write32(®s->geni_m_cmd0, START_UART_TX); - write32(®s->geni_tx_fifon, data); -} - -uintptr_t uart_platform_base(unsigned int idx) -{ - return (uintptr_t)qup[idx].regs; -} - -void uart_fill_lb(void *data) -{ - struct lb_serial serial = {0}; - - serial.type = LB_SERIAL_TYPE_MEMORY_MAPPED; - serial.baseaddr = (uint32_t)uart_platform_base(CONFIG_UART_FOR_CONSOLE); - serial.baud = get_uart_baudrate(); - serial.regwidth = 4; - serial.input_hertz = SRC_XO_HZ; - - lb_add_serial(&serial, data); -} -- cgit v1.2.3