--- /dev/null
+/*
+ * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+#define SCIF_INTERNAL_CLK 0
+#define SCIF_EXTARNAL_CLK 1
+#define SCIF_CLK SCIF_INTERNAL_CLK
+
+/* product register */
+#define PRR (0xFFF00044)
+#define PRR_PRODUCT_MASK (0x00007F00)
+#define PRR_CUT_MASK (0x000000FF)
+#define PRR_PRODUCT_H3_VER_10 (0x00004F00)
+#define PRR_PRODUCT_E3 (0x00005700)
+
+/* module stop */
+#define CPG_BASE (0xE6150000)
+#define CPG_SMSTPCR3 (0x013C)
+#define CPG_MSTPSR3 (0x0048)
+#define MSTP310 (1 << 10)
+#define CPG_CPGWPR (0x0900)
+
+/* scif */
+#define SCIF2_BASE (0xE6E88000)
+#define SCIF_SCSMR (0x00)
+#define SCIF_SCBRR (0x04)
+#define SCIF_SCSCR (0x08)
+#define SCIF_SCFTDR (0x0C)
+#define SCIF_SCFSR (0x10)
+#define SCIF_SCFRDR (0x14)
+#define SCIF_SCFCR (0x18)
+#define SCIF_SCFDR (0x1C)
+#define SCIF_SCSPTR (0x20)
+#define SCIF_SCLSR (0x24)
+#define SCIF_DL (0x30)
+#define SCIF_CKS (0x34)
+
+/* mode pin */
+#define RST_MODEMR (0xE6160060)
+#define MODEMR_MD12 (0x00001000)
+
+#define SCSMR_CA_MASK (1 << 7)
+#define SCSMR_CA_ASYNC (0x0000)
+#define SCSMR_CHR_MASK (1 << 6)
+#define SCSMR_CHR_8 (0x0000)
+#define SCSMR_PE_MASK (1 << 5)
+#define SCSMR_PE_DIS (0x0000)
+#define SCSMR_STOP_MASK (1 << 3)
+#define SCSMR_STOP_1 (0x0000)
+#define SCSMR_CKS_MASK (3 << 0)
+#define SCSMR_CKS_DIV1 (0x0000)
+#define SCSMR_INIT_DATA (SCSMR_CA_ASYNC + \
+ SCSMR_CHR_8 + \
+ SCSMR_PE_DIS + \
+ SCSMR_STOP_1 + \
+ SCSMR_CKS_DIV1)
+#define SCBRR_115200BPS (17)
+#define SCBRR_115200BPS_E3_SSCG (15)
+#define SCBRR_230400BPS (8)
+
+#define SCSCR_TE_MASK (1 << 5)
+#define SCSCR_TE_DIS (0x0000)
+#define SCSCR_TE_EN (0x0020)
+#define SCSCR_RE_MASK (1 << 4)
+#define SCSCR_RE_DIS (0x0000)
+#define SCSCR_RE_EN (0x0010)
+#define SCSCR_CKE_MASK (3 << 0)
+#define SCSCR_CKE_INT (0x0000)
+#define SCSCR_CKE_BRG (0x0002)
+#if SCIF_CLK == SCIF_EXTARNAL_CLK
+#define SCSCR_CKE_INT_CLK (SCSCR_CKE_BRG)
+#else
+#define SCSCR_CKE_INT_CLK (SCSCR_CKE_INT)
+#endif
+#define SCFSR_INIT_DATA (0x0000)
+#define SCFCR_TTRG_MASK (3 << 4)
+#define SCFCR_TTRG_8 (0x0000)
+#define SCFCR_TTRG_0 (0x0030)
+#define SCFCR_TFRST_MASK (1 << 2)
+#define SCFCR_TFRST_DIS (0x0000)
+#define SCFCR_TFRST_EN (0x0004)
+#define SCFCR_RFRS_MASK (1 << 1)
+#define SCFCR_RFRS_DIS (0x0000)
+#define SCFCR_RFRS_EN (0x0002)
+#define SCFCR_INIT_DATA (SCFCR_TTRG_8)
+#define SCFDR_T_MASK (0x1f << 8)
+#define DL_INIT_DATA (8)
+#define CKS_CKS_DIV_MASK (1 << 15)
+#define CKS_CKS_DIV_CLK (0x0000)
+#define CKS_XIN_MASK (1 << 14)
+#define CKS_XIN_SCIF_CLK (0x0000)
+#define CKS_INIT_DATA (CKS_CKS_DIV_CLK + CKS_XIN_SCIF_CLK)
+
+ .globl console_init
+ .globl console_uninit
+ .globl console_putc
+ .globl console_core_init
+ .globl console_core_putc
+ .globl console_getc
+ .globl console_flush
+
+ /*
+ * The console base is in the data section and not in .bss
+ * even though it is zero-init. In particular, this allows
+ * the console functions to start using this variable before
+ * the runtime memory is initialized for images which do not
+ * need to copy the .data section from ROM to RAM.
+ */
+ /* -----------------------------------------------
+ * int console_init(unsigned long base_addr,
+ * unsigned int uart_clk, unsigned int baud_rate)
+ * Function to initialize the console without a
+ * C Runtime to print debug information. It saves
+ * the console base to the data section.
+ * In: x0 - console base address
+ * w1 - Uart clock in Hz
+ * w2 - Baud rate
+ * out: return 1 on success.
+ * Clobber list : x1 - x3
+ * -----------------------------------------------
+ */
+func console_init
+ b console_core_init
+endfunc console_init
+
+func console_uninit
+ ret
+endfunc console_uninit
+
+ /* -----------------------------------------------
+ * int console_core_init(unsigned long base_addr,
+ * unsigned int uart_clk, unsigned int baud_rate)
+ * Function to initialize the console without a
+ * C Runtime to print debug information. This
+ * function will be accessed by console_init and
+ * crash reporting.
+ * In: x0 - console base address
+ * w1 - Uart clock in Hz
+ * w2 - Baud rate
+ * Out: return 1 on success
+ * Clobber list : x1, x2
+ * -----------------------------------------------
+ */
+func console_core_init
+ ldr x0, =CPG_BASE
+ ldr w1, [x0, #CPG_SMSTPCR3]
+ and w1, w1, #~MSTP310 /* MSTP310=0 */
+ mvn w2, w1
+ str w2, [x0, #CPG_CPGWPR]
+ str w1, [x0, #CPG_SMSTPCR3]
+5:
+ ldr w1, [x0, #CPG_MSTPSR3]
+ and w1, w1, #MSTP310
+ cbnz w1, 5b
+
+ ldr x0, =SCIF2_BASE
+ /* Clear bits TE and RE in SCSCR to 0 */
+ mov w1, #(SCSCR_TE_DIS + SCSCR_RE_DIS)
+ strh w1, [x0, #SCIF_SCSCR]
+ /* Set bits TFRST and RFRST in SCFCR to 1 */
+ ldrh w1, [x0, #SCIF_SCFCR]
+ orr w1, w1, #(SCFCR_TFRST_EN + SCFCR_RFRS_EN)
+ strh w1, [x0, #SCIF_SCFCR]
+ /* Read flags of ER, DR, BRK, and RDF in SCFSR and those of TO and ORER
+ in SCLSR, then clear them to 0 */
+ mov w1, #SCFSR_INIT_DATA
+ strh w1, [x0, #SCIF_SCFSR]
+ mov w1, #0
+ strh w1, [x0, #SCIF_SCLSR]
+ /* Set bits CKE[1:0] in SCSCR */
+ ldrh w1, [x0, #SCIF_SCSCR]
+ and w1, w1, #~SCSCR_CKE_MASK
+ mov w2, #SCSCR_CKE_INT_CLK
+ orr w1, w1, w2
+ strh w1, [x0, #SCIF_SCSCR]
+ /* Set data transfer format in SCSMR */
+ mov w1, #SCSMR_INIT_DATA
+ strh w1, [x0, #SCIF_SCSMR]
+ /* Set value in SCBRR */
+#if SCIF_CLK == SCIF_INTERNAL_CLK
+ ldr x1, =PRR
+ ldr w1, [x1]
+ and w1, w1, #(PRR_PRODUCT_MASK | PRR_CUT_MASK)
+ mov w2, #PRR_PRODUCT_H3_VER_10
+ cmp w1, w2
+ beq 3f
+ and w1, w1, #PRR_PRODUCT_MASK
+ mov w2, #PRR_PRODUCT_E3
+ cmp w1, w2
+ bne 4f
+
+ ldr x1, =RST_MODEMR
+ ldr w1, [x1]
+ and w1, w1, #MODEMR_MD12
+ mov w2, #MODEMR_MD12
+ cmp w1, w2
+ bne 4f
+
+ mov w1, #SCBRR_115200BPS_E3_SSCG
+ b 2f
+4:
+ mov w1, #SCBRR_115200BPS
+ b 2f
+3:
+ mov w1, #SCBRR_230400BPS
+2:
+ strb w1, [x0, SCIF_SCBRR]
+#else
+ mov w1, #DL_INIT_DATA
+ strh w1, [x0, #SCIF_DL]
+ mov w1, #CKS_INIT_DATA
+ strh w1, [x0, #SCIF_CKS]
+#endif
+ /* 1-bit interval elapsed */
+ mov w1, #100
+1:
+ subs w1, w1, #1
+ cbnz w1, 1b
+ /*
+ * Set bits RTRG[1:0], TTRG[1:0], and MCE in SCFCR
+ * Clear bits FRST and RFRST to 0
+ */
+ mov w1, #SCFCR_INIT_DATA
+ strh w1, [x0, #SCIF_SCFCR]
+ /* Set bits TE and RE in SCSCR to 1 */
+ ldrh w1, [x0, #SCIF_SCSCR]
+ orr w1, w1, #(SCSCR_TE_EN + SCSCR_RE_EN)
+ strh w1, [x0, #SCIF_SCSCR]
+ mov x0, #1
+
+ ret
+endfunc console_core_init
+
+ /* ---------------------------------------------
+ * int console_putc(int c)
+ * Function to output a character over the
+ * console. It returns the character printed on
+ * success or -1 on error.
+ * In : x0 - character to be printed
+ * Out : return -1 on error else return character.
+ * Clobber list : x1, x2
+ * ---------------------------------------------
+ */
+func console_putc
+ b console_core_putc
+endfunc console_putc
+
+ /* --------------------------------------------------------
+ * int console_core_putc(int c, unsigned int base_addr)
+ * Function to output a character over the console. It
+ * returns the character printed on success or -1 on error.
+ * In : w0 - character to be printed
+ * x1 - console base address
+ * Out : return -1 on error else return character.
+ * Clobber list : x2
+ * --------------------------------------------------------
+ */
+func console_core_putc
+ ldr x1, =SCIF2_BASE
+ cmp w0, #0xA
+ /* Prepend '\r' to '\n' */
+ bne 2f
+1:
+ /* Check if the transmit FIFO is full */
+ ldrh w2, [x1, #SCIF_SCFDR]
+ ubfx w2, w2, #8, #5
+ cmp w2, #16
+ bcs 1b
+ mov w2, #0x0D
+ strb w2, [x1, #SCIF_SCFTDR]
+2:
+ /* Check if the transmit FIFO is full */
+ ldrh w2, [x1, #SCIF_SCFDR]
+ ubfx w2, w2, #8, #5
+ cmp w2, #16
+ bcs 2b
+ strb w0, [x1, #SCIF_SCFTDR]
+
+ ret
+endfunc console_core_putc
+
+ /* ---------------------------------------------
+ * int console_getc(void)
+ * Function to get a character from the console.
+ * It returns the character grabbed on success
+ * or -1 on error.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_getc
+ mov w0, #-1
+ ret
+endfunc console_getc
+
+ /* ---------------------------------------------
+ * int console_flush(void)
+ * Function to force a write of all buffered
+ * data that hasn't been output. It returns 0
+ * upon successful completion, otherwise it
+ * returns -1.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_flush
+ ldr x0, =SCIF2_BASE
+1:
+ ldrh w1, [x0, #SCIF_SCFDR]
+ ubfx w1, w1, #8, #5
+ cmp w1, #0
+ bne 1b
+
+ mov x0, #100
+ mov x3, x30
+ bl rcar_micro_delay
+ mov x30, x3
+
+ ldr x0, =SCIF2_BASE
+ ldrh w1, [x0, #SCIF_SCSCR]
+ and w1, w1, #~(SCSCR_TE_EN + SCSCR_RE_EN)
+ strh w1, [x0, #SCIF_SCSCR]
+
+ mov w0, #0
+ ret
+endfunc console_flush