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