rcar_gen3: drivers: serial controller interface
authorJorge Ramirez-Ortiz <jramirez@baylibre.com>
Sun, 23 Sep 2018 07:41:53 +0000 (09:41 +0200)
committerldts <jorge.ramirez.ortiz@gmail.com>
Wed, 17 Oct 2018 16:42:17 +0000 (18:42 +0200)
Signed-off-by: ldts <jramirez@baylibre.com>
drivers/renesas/rcar/scif/scif.S [new file with mode: 0644]

diff --git a/drivers/renesas/rcar/scif/scif.S b/drivers/renesas/rcar/scif/scif.S
new file mode 100644 (file)
index 0000000..1cc0d59
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * 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