1*91f16700Schasinglulu/* 2*91f16700Schasinglulu * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu#include <arch.h> 8*91f16700Schasinglulu#include <asm_macros.S> 9*91f16700Schasinglulu#include <console_macros.S> 10*91f16700Schasinglulu#include <drivers/renesas/rcar/console/console.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu#define SCIF_INTERNAL_CLK 0 13*91f16700Schasinglulu#define SCIF_EXTARNAL_CLK 1 14*91f16700Schasinglulu#define SCIF_CLK SCIF_INTERNAL_CLK 15*91f16700Schasinglulu 16*91f16700Schasinglulu/* product register */ 17*91f16700Schasinglulu#define PRR (0xFFF00044) 18*91f16700Schasinglulu#define PRR_PRODUCT_MASK (0x00007F00) 19*91f16700Schasinglulu#define PRR_CUT_MASK (0x000000FF) 20*91f16700Schasinglulu#define PRR_PRODUCT_H3_VER_10 (0x00004F00) 21*91f16700Schasinglulu#define PRR_PRODUCT_E3 (0x00005700) 22*91f16700Schasinglulu#define PRR_PRODUCT_D3 (0x00005800) 23*91f16700Schasinglulu 24*91f16700Schasinglulu/* module stop */ 25*91f16700Schasinglulu#define CPG_BASE (0xE6150000) 26*91f16700Schasinglulu#define CPG_SMSTPCR2 (0x0138) 27*91f16700Schasinglulu#define CPG_SMSTPCR3 (0x013C) 28*91f16700Schasinglulu#define CPG_MSTPSR2 (0x0040) 29*91f16700Schasinglulu#define CPG_MSTPSR3 (0x0048) 30*91f16700Schasinglulu#define MSTP207 (1 << 7) 31*91f16700Schasinglulu#define MSTP310 (1 << 10) 32*91f16700Schasinglulu#define CPG_CPGWPR (0x0900) 33*91f16700Schasinglulu 34*91f16700Schasinglulu/* scif */ 35*91f16700Schasinglulu#define SCIF0_BASE (0xE6E60000) 36*91f16700Schasinglulu#define SCIF2_BASE (0xE6E88000) 37*91f16700Schasinglulu#define SCIF_SCSMR (0x00) 38*91f16700Schasinglulu#define SCIF_SCBRR (0x04) 39*91f16700Schasinglulu#define SCIF_SCSCR (0x08) 40*91f16700Schasinglulu#define SCIF_SCFTDR (0x0C) 41*91f16700Schasinglulu#define SCIF_SCFSR (0x10) 42*91f16700Schasinglulu#define SCIF_SCFRDR (0x14) 43*91f16700Schasinglulu#define SCIF_SCFCR (0x18) 44*91f16700Schasinglulu#define SCIF_SCFDR (0x1C) 45*91f16700Schasinglulu#define SCIF_SCSPTR (0x20) 46*91f16700Schasinglulu#define SCIF_SCLSR (0x24) 47*91f16700Schasinglulu#define SCIF_DL (0x30) 48*91f16700Schasinglulu#define SCIF_CKS (0x34) 49*91f16700Schasinglulu 50*91f16700Schasinglulu#if RCAR_LSI == RCAR_V3M 51*91f16700Schasinglulu#define SCIF_BASE SCIF0_BASE 52*91f16700Schasinglulu#define CPG_SMSTPCR CPG_SMSTPCR2 53*91f16700Schasinglulu#define CPG_MSTPSR CPG_MSTPSR2 54*91f16700Schasinglulu#define MSTP MSTP207 55*91f16700Schasinglulu#else 56*91f16700Schasinglulu#define SCIF_BASE SCIF2_BASE 57*91f16700Schasinglulu#define CPG_SMSTPCR CPG_SMSTPCR3 58*91f16700Schasinglulu#define CPG_MSTPSR CPG_MSTPSR3 59*91f16700Schasinglulu#define MSTP MSTP310 60*91f16700Schasinglulu#endif 61*91f16700Schasinglulu 62*91f16700Schasinglulu/* mode pin */ 63*91f16700Schasinglulu#define RST_MODEMR (0xE6160060) 64*91f16700Schasinglulu#define MODEMR_MD12 (0x00001000) 65*91f16700Schasinglulu 66*91f16700Schasinglulu#define SCSMR_CA_MASK (1 << 7) 67*91f16700Schasinglulu#define SCSMR_CA_ASYNC (0x0000) 68*91f16700Schasinglulu#define SCSMR_CHR_MASK (1 << 6) 69*91f16700Schasinglulu#define SCSMR_CHR_8 (0x0000) 70*91f16700Schasinglulu#define SCSMR_PE_MASK (1 << 5) 71*91f16700Schasinglulu#define SCSMR_PE_DIS (0x0000) 72*91f16700Schasinglulu#define SCSMR_STOP_MASK (1 << 3) 73*91f16700Schasinglulu#define SCSMR_STOP_1 (0x0000) 74*91f16700Schasinglulu#define SCSMR_CKS_MASK (3 << 0) 75*91f16700Schasinglulu#define SCSMR_CKS_DIV1 (0x0000) 76*91f16700Schasinglulu#define SCSMR_INIT_DATA (SCSMR_CA_ASYNC + \ 77*91f16700Schasinglulu SCSMR_CHR_8 + \ 78*91f16700Schasinglulu SCSMR_PE_DIS + \ 79*91f16700Schasinglulu SCSMR_STOP_1 + \ 80*91f16700Schasinglulu SCSMR_CKS_DIV1) 81*91f16700Schasinglulu#define SCBRR_115200BPS (17) 82*91f16700Schasinglulu#define SCBRR_115200BPS_D3_SSCG (16) 83*91f16700Schasinglulu#define SCBRR_115200BPS_E3_SSCG (15) 84*91f16700Schasinglulu#define SCBRR_230400BPS (8) 85*91f16700Schasinglulu 86*91f16700Schasinglulu#define SCSCR_TE_MASK (1 << 5) 87*91f16700Schasinglulu#define SCSCR_TE_DIS (0x0000) 88*91f16700Schasinglulu#define SCSCR_TE_EN (0x0020) 89*91f16700Schasinglulu#define SCSCR_RE_MASK (1 << 4) 90*91f16700Schasinglulu#define SCSCR_RE_DIS (0x0000) 91*91f16700Schasinglulu#define SCSCR_RE_EN (0x0010) 92*91f16700Schasinglulu#define SCSCR_CKE_MASK (3 << 0) 93*91f16700Schasinglulu#define SCSCR_CKE_INT (0x0000) 94*91f16700Schasinglulu#define SCSCR_CKE_BRG (0x0002) 95*91f16700Schasinglulu#if SCIF_CLK == SCIF_EXTARNAL_CLK 96*91f16700Schasinglulu#define SCSCR_CKE_INT_CLK (SCSCR_CKE_BRG) 97*91f16700Schasinglulu#else 98*91f16700Schasinglulu#define SCFSR_TEND_MASK (1 << 6) 99*91f16700Schasinglulu#define SCFSR_TEND_TRANS_END (0x0040) 100*91f16700Schasinglulu#define SCSCR_CKE_INT_CLK (SCSCR_CKE_INT) 101*91f16700Schasinglulu#endif 102*91f16700Schasinglulu#define SCFSR_INIT_DATA (0x0000) 103*91f16700Schasinglulu#define SCFCR_TTRG_MASK (3 << 4) 104*91f16700Schasinglulu#define SCFCR_TTRG_8 (0x0000) 105*91f16700Schasinglulu#define SCFCR_TTRG_0 (0x0030) 106*91f16700Schasinglulu#define SCFCR_TFRST_MASK (1 << 2) 107*91f16700Schasinglulu#define SCFCR_TFRST_DIS (0x0000) 108*91f16700Schasinglulu#define SCFCR_TFRST_EN (0x0004) 109*91f16700Schasinglulu#define SCFCR_RFRS_MASK (1 << 1) 110*91f16700Schasinglulu#define SCFCR_RFRS_DIS (0x0000) 111*91f16700Schasinglulu#define SCFCR_RFRS_EN (0x0002) 112*91f16700Schasinglulu#define SCFCR_INIT_DATA (SCFCR_TTRG_8) 113*91f16700Schasinglulu#define SCFDR_T_MASK (0x1f << 8) 114*91f16700Schasinglulu#define DL_INIT_DATA (8) 115*91f16700Schasinglulu#define CKS_CKS_DIV_MASK (1 << 15) 116*91f16700Schasinglulu#define CKS_CKS_DIV_CLK (0x0000) 117*91f16700Schasinglulu#define CKS_XIN_MASK (1 << 14) 118*91f16700Schasinglulu#define CKS_XIN_SCIF_CLK (0x0000) 119*91f16700Schasinglulu#define CKS_INIT_DATA (CKS_CKS_DIV_CLK + CKS_XIN_SCIF_CLK) 120*91f16700Schasinglulu 121*91f16700Schasinglulu .globl console_rcar_register 122*91f16700Schasinglulu .globl console_rcar_init 123*91f16700Schasinglulu .globl console_rcar_putc 124*91f16700Schasinglulu .globl console_rcar_flush 125*91f16700Schasinglulu 126*91f16700Schasinglulu /* 127*91f16700Schasinglulu * ----------------------------------------------- 128*91f16700Schasinglulu * int console_rcar_register( 129*91f16700Schasinglulu * uintptr_t base, uint32_t clk, uint32_t baud, 130*91f16700Schasinglulu * console_t *console) 131*91f16700Schasinglulu * Function to initialize and register a new rcar 132*91f16700Schasinglulu * console. Storage passed in for the console struct 133*91f16700Schasinglulu * *must* be persistent (i.e. not from the stack). 134*91f16700Schasinglulu * In: x0 - UART register base address 135*91f16700Schasinglulu * w1 - UART clock in Hz 136*91f16700Schasinglulu * w2 - Baud rate 137*91f16700Schasinglulu * x3 - pointer to empty console_t struct 138*91f16700Schasinglulu * Out: return 1 on success, 0 on error 139*91f16700Schasinglulu * Clobber list : x0, x1, x2, x6, x7, x14 140*91f16700Schasinglulu * ----------------------------------------------- 141*91f16700Schasinglulu */ 142*91f16700Schasinglulufunc console_rcar_register 143*91f16700Schasinglulu mov x7, x30 144*91f16700Schasinglulu mov x6, x3 145*91f16700Schasinglulu cbz x6, register_fail 146*91f16700Schasinglulu str x0, [x6, #CONSOLE_T_BASE] 147*91f16700Schasinglulu 148*91f16700Schasinglulu bl console_rcar_init 149*91f16700Schasinglulu 150*91f16700Schasinglulu mov x0, x6 151*91f16700Schasinglulu mov x30, x7 152*91f16700Schasinglulu finish_console_register rcar, putc=1, getc=0, flush=1 153*91f16700Schasinglulu 154*91f16700Schasingluluregister_fail: 155*91f16700Schasinglulu ret x7 156*91f16700Schasingluluendfunc console_rcar_register 157*91f16700Schasinglulu 158*91f16700Schasinglulu /* 159*91f16700Schasinglulu * int console_rcar_init(unsigned long base_addr, 160*91f16700Schasinglulu * unsigned int uart_clk, unsigned int baud_rate) 161*91f16700Schasinglulu * Function to initialize the console without a 162*91f16700Schasinglulu * C Runtime to print debug information. This 163*91f16700Schasinglulu * function will be accessed by console_rcar_register 164*91f16700Schasinglulu * and crash reporting. 165*91f16700Schasinglulu * In: x0 - console base address 166*91f16700Schasinglulu * w1 - Uart clock in Hz 167*91f16700Schasinglulu * w2 - Baud rate 168*91f16700Schasinglulu * Out: return 1 on success 169*91f16700Schasinglulu * Clobber list : x1, x2 170*91f16700Schasinglulu */ 171*91f16700Schasinglulufunc console_rcar_init 172*91f16700Schasinglulu ldr x0, =CPG_BASE 173*91f16700Schasinglulu ldr w1, [x0, #CPG_SMSTPCR] 174*91f16700Schasinglulu and w1, w1, #~MSTP 175*91f16700Schasinglulu mvn w2, w1 176*91f16700Schasinglulu str w2, [x0, #CPG_CPGWPR] 177*91f16700Schasinglulu str w1, [x0, #CPG_SMSTPCR] 178*91f16700Schasinglulu5: 179*91f16700Schasinglulu ldr w1, [x0, #CPG_MSTPSR] 180*91f16700Schasinglulu and w1, w1, #MSTP 181*91f16700Schasinglulu cbnz w1, 5b 182*91f16700Schasinglulu 183*91f16700Schasinglulu ldr x0, =SCIF_BASE 184*91f16700Schasinglulu /* Clear bits TE and RE in SCSCR to 0 */ 185*91f16700Schasinglulu mov w1, #(SCSCR_TE_DIS + SCSCR_RE_DIS) 186*91f16700Schasinglulu strh w1, [x0, #SCIF_SCSCR] 187*91f16700Schasinglulu /* Set bits TFRST and RFRST in SCFCR to 1 */ 188*91f16700Schasinglulu ldrh w1, [x0, #SCIF_SCFCR] 189*91f16700Schasinglulu orr w1, w1, #(SCFCR_TFRST_EN + SCFCR_RFRS_EN) 190*91f16700Schasinglulu strh w1, [x0, #SCIF_SCFCR] 191*91f16700Schasinglulu /* 192*91f16700Schasinglulu * Read flags of ER, DR, BRK, and RDF in SCFSR and those of TO and ORER 193*91f16700Schasinglulu * in SCLSR, then clear them to 0 194*91f16700Schasinglulu */ 195*91f16700Schasinglulu mov w1, #SCFSR_INIT_DATA 196*91f16700Schasinglulu strh w1, [x0, #SCIF_SCFSR] 197*91f16700Schasinglulu mov w1, #0 198*91f16700Schasinglulu strh w1, [x0, #SCIF_SCLSR] 199*91f16700Schasinglulu /* Set bits CKE[1:0] in SCSCR */ 200*91f16700Schasinglulu ldrh w1, [x0, #SCIF_SCSCR] 201*91f16700Schasinglulu and w1, w1, #~SCSCR_CKE_MASK 202*91f16700Schasinglulu mov w2, #SCSCR_CKE_INT_CLK 203*91f16700Schasinglulu orr w1, w1, w2 204*91f16700Schasinglulu strh w1, [x0, #SCIF_SCSCR] 205*91f16700Schasinglulu /* Set data transfer format in SCSMR */ 206*91f16700Schasinglulu mov w1, #SCSMR_INIT_DATA 207*91f16700Schasinglulu strh w1, [x0, #SCIF_SCSMR] 208*91f16700Schasinglulu /* Set value in SCBRR */ 209*91f16700Schasinglulu#if SCIF_CLK == SCIF_INTERNAL_CLK 210*91f16700Schasinglulu ldr x1, =PRR 211*91f16700Schasinglulu ldr w1, [x1] 212*91f16700Schasinglulu and w1, w1, #(PRR_PRODUCT_MASK | PRR_CUT_MASK) 213*91f16700Schasinglulu mov w2, #PRR_PRODUCT_H3_VER_10 214*91f16700Schasinglulu cmp w1, w2 215*91f16700Schasinglulu beq 3f 216*91f16700Schasinglulu and w1, w1, #PRR_PRODUCT_MASK 217*91f16700Schasinglulu mov w2, #PRR_PRODUCT_D3 218*91f16700Schasinglulu cmp w1, w2 219*91f16700Schasinglulu beq 5f 220*91f16700Schasinglulu and w1, w1, #PRR_PRODUCT_MASK 221*91f16700Schasinglulu mov w2, #PRR_PRODUCT_E3 222*91f16700Schasinglulu cmp w1, w2 223*91f16700Schasinglulu bne 4f 224*91f16700Schasinglulu 225*91f16700Schasinglulu /* When SSCG(MD12) on (E3) */ 226*91f16700Schasinglulu ldr x1, =RST_MODEMR 227*91f16700Schasinglulu ldr w1, [x1] 228*91f16700Schasinglulu and w1, w1, #MODEMR_MD12 229*91f16700Schasinglulu mov w2, #MODEMR_MD12 230*91f16700Schasinglulu cmp w1, w2 231*91f16700Schasinglulu bne 4f 232*91f16700Schasinglulu 233*91f16700Schasinglulu /* When SSCG(MD12) on (E3) */ 234*91f16700Schasinglulu mov w1, #SCBRR_115200BPS_E3_SSCG 235*91f16700Schasinglulu b 2f 236*91f16700Schasinglulu5: 237*91f16700Schasinglulu /* In case of D3 */ 238*91f16700Schasinglulu ldr x1, =RST_MODEMR 239*91f16700Schasinglulu ldr w1, [x1] 240*91f16700Schasinglulu and w1, w1, #MODEMR_MD12 241*91f16700Schasinglulu mov w2, #MODEMR_MD12 242*91f16700Schasinglulu cmp w1, w2 243*91f16700Schasinglulu bne 4f 244*91f16700Schasinglulu 245*91f16700Schasinglulu /* When SSCG(MD12) on (D3) */ 246*91f16700Schasinglulu mov w1, #SCBRR_115200BPS_D3_SSCG 247*91f16700Schasinglulu b 2f 248*91f16700Schasinglulu4: 249*91f16700Schasinglulu /* In case of H3/M3/M3N or when SSCG(MD12) is off in E3/D3 */ 250*91f16700Schasinglulu mov w1, #SCBRR_115200BPS 251*91f16700Schasinglulu b 2f 252*91f16700Schasinglulu3: 253*91f16700Schasinglulu mov w1, #SCBRR_230400BPS 254*91f16700Schasinglulu2: 255*91f16700Schasinglulu strb w1, [x0, SCIF_SCBRR] 256*91f16700Schasinglulu#else 257*91f16700Schasinglulu mov w1, #DL_INIT_DATA 258*91f16700Schasinglulu strh w1, [x0, #SCIF_DL] 259*91f16700Schasinglulu mov w1, #CKS_INIT_DATA 260*91f16700Schasinglulu strh w1, [x0, #SCIF_CKS] 261*91f16700Schasinglulu#endif 262*91f16700Schasinglulu /* 1-bit interval elapsed */ 263*91f16700Schasinglulu mov w1, #100 264*91f16700Schasinglulu1: 265*91f16700Schasinglulu subs w1, w1, #1 266*91f16700Schasinglulu cbnz w1, 1b 267*91f16700Schasinglulu /* 268*91f16700Schasinglulu * Set bits RTRG[1:0], TTRG[1:0], and MCE in SCFCR 269*91f16700Schasinglulu * Clear bits FRST and RFRST to 0 270*91f16700Schasinglulu */ 271*91f16700Schasinglulu mov w1, #SCFCR_INIT_DATA 272*91f16700Schasinglulu strh w1, [x0, #SCIF_SCFCR] 273*91f16700Schasinglulu /* Set bits TE and RE in SCSCR to 1 */ 274*91f16700Schasinglulu ldrh w1, [x0, #SCIF_SCSCR] 275*91f16700Schasinglulu orr w1, w1, #(SCSCR_TE_EN + SCSCR_RE_EN) 276*91f16700Schasinglulu strh w1, [x0, #SCIF_SCSCR] 277*91f16700Schasinglulu mov x0, #1 278*91f16700Schasinglulu 279*91f16700Schasinglulu ret 280*91f16700Schasingluluendfunc console_rcar_init 281*91f16700Schasinglulu 282*91f16700Schasinglulu /* 283*91f16700Schasinglulu * int console_rcar_putc(int c, unsigned int base_addr) 284*91f16700Schasinglulu * Function to output a character over the console. It 285*91f16700Schasinglulu * returns the character printed on success or -1 on error. 286*91f16700Schasinglulu * In : w0 - character to be printed 287*91f16700Schasinglulu * x1 - pointer to console_t structure 288*91f16700Schasinglulu * Out : return -1 on error else return character. 289*91f16700Schasinglulu * Clobber list : x2 290*91f16700Schasinglulu */ 291*91f16700Schasinglulufunc console_rcar_putc 292*91f16700Schasinglulu ldr x1, =SCIF_BASE 293*91f16700Schasinglulu cmp w0, #0xA 294*91f16700Schasinglulu /* Prepend '\r' to '\n' */ 295*91f16700Schasinglulu bne 2f 296*91f16700Schasinglulu1: 297*91f16700Schasinglulu /* Check if the transmit FIFO is full */ 298*91f16700Schasinglulu ldrh w2, [x1, #SCIF_SCFDR] 299*91f16700Schasinglulu ubfx w2, w2, #8, #5 300*91f16700Schasinglulu cmp w2, #16 301*91f16700Schasinglulu bcs 1b 302*91f16700Schasinglulu mov w2, #0x0D 303*91f16700Schasinglulu strb w2, [x1, #SCIF_SCFTDR] 304*91f16700Schasinglulu2: 305*91f16700Schasinglulu /* Check if the transmit FIFO is full */ 306*91f16700Schasinglulu ldrh w2, [x1, #SCIF_SCFDR] 307*91f16700Schasinglulu ubfx w2, w2, #8, #5 308*91f16700Schasinglulu cmp w2, #16 309*91f16700Schasinglulu bcs 2b 310*91f16700Schasinglulu strb w0, [x1, #SCIF_SCFTDR] 311*91f16700Schasinglulu 312*91f16700Schasinglulu /* Clear TEND flag */ 313*91f16700Schasinglulu ldrh w2, [x1, #SCIF_SCFSR] 314*91f16700Schasinglulu and w2, w2, #~SCFSR_TEND_MASK 315*91f16700Schasinglulu strh w2, [x1, #SCIF_SCFSR] 316*91f16700Schasinglulu 317*91f16700Schasinglulu ret 318*91f16700Schasingluluendfunc console_rcar_putc 319*91f16700Schasinglulu 320*91f16700Schasinglulu /* 321*91f16700Schasinglulu * void console_rcar_flush(void) 322*91f16700Schasinglulu * Function to force a write of all buffered 323*91f16700Schasinglulu * data that hasn't been output. It returns void 324*91f16700Schasinglulu * Clobber list : x0, x1 325*91f16700Schasinglulu */ 326*91f16700Schasinglulufunc console_rcar_flush 327*91f16700Schasinglulu ldr x0, =SCIF_BASE 328*91f16700Schasinglulu1: 329*91f16700Schasinglulu /* Check TEND flag */ 330*91f16700Schasinglulu ldrh w1, [x0, #SCIF_SCFSR] 331*91f16700Schasinglulu and w1, w1, #SCFSR_TEND_MASK 332*91f16700Schasinglulu cmp w1, #SCFSR_TEND_TRANS_END 333*91f16700Schasinglulu bne 1b 334*91f16700Schasinglulu 335*91f16700Schasinglulu ldr x0, =SCIF_BASE 336*91f16700Schasinglulu ldrh w1, [x0, #SCIF_SCSCR] 337*91f16700Schasinglulu and w1, w1, #~(SCSCR_TE_EN + SCSCR_RE_EN) 338*91f16700Schasinglulu strh w1, [x0, #SCIF_SCSCR] 339*91f16700Schasinglulu 340*91f16700Schasinglulu ret 341*91f16700Schasingluluendfunc console_rcar_flush 342