1865e3474SBiju Das/* 2*14f0a081SToshiyuki Ogasahara * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. 3865e3474SBiju Das * 4865e3474SBiju Das * SPDX-License-Identifier: BSD-3-Clause 5865e3474SBiju Das */ 6865e3474SBiju Das 7865e3474SBiju Das#include <arch.h> 8865e3474SBiju Das#include <asm_macros.S> 9865e3474SBiju Das#include <console_macros.S> 10865e3474SBiju Das#include <drivers/renesas/rcar/console/console.h> 11865e3474SBiju Das 12865e3474SBiju Das#define SCIF_INTERNAL_CLK 0 13865e3474SBiju Das#define SCIF_EXTARNAL_CLK 1 14865e3474SBiju Das#define SCIF_CLK SCIF_INTERNAL_CLK 15865e3474SBiju Das 16865e3474SBiju Das/* product register */ 17865e3474SBiju Das#define PRR (0xFFF00044) 18865e3474SBiju Das#define PRR_PRODUCT_MASK (0x00007F00) 19865e3474SBiju Das#define PRR_CUT_MASK (0x000000FF) 20865e3474SBiju Das#define PRR_PRODUCT_H3_VER_10 (0x00004F00) 21865e3474SBiju Das#define PRR_PRODUCT_E3 (0x00005700) 22865e3474SBiju Das#define PRR_PRODUCT_D3 (0x00005800) 23865e3474SBiju Das 24865e3474SBiju Das/* module stop */ 25865e3474SBiju Das#define CPG_BASE (0xE6150000) 26865e3474SBiju Das#define CPG_SMSTPCR2 (0x0138) 27865e3474SBiju Das#define CPG_SMSTPCR3 (0x013C) 28865e3474SBiju Das#define CPG_MSTPSR2 (0x0040) 29865e3474SBiju Das#define CPG_MSTPSR3 (0x0048) 30865e3474SBiju Das#define MSTP207 (1 << 7) 31865e3474SBiju Das#define MSTP310 (1 << 10) 32865e3474SBiju Das#define CPG_CPGWPR (0x0900) 33865e3474SBiju Das 34865e3474SBiju Das/* scif */ 35865e3474SBiju Das#define SCIF0_BASE (0xE6E60000) 36865e3474SBiju Das#define SCIF2_BASE (0xE6E88000) 37865e3474SBiju Das#define SCIF_SCSMR (0x00) 38865e3474SBiju Das#define SCIF_SCBRR (0x04) 39865e3474SBiju Das#define SCIF_SCSCR (0x08) 40865e3474SBiju Das#define SCIF_SCFTDR (0x0C) 41865e3474SBiju Das#define SCIF_SCFSR (0x10) 42865e3474SBiju Das#define SCIF_SCFRDR (0x14) 43865e3474SBiju Das#define SCIF_SCFCR (0x18) 44865e3474SBiju Das#define SCIF_SCFDR (0x1C) 45865e3474SBiju Das#define SCIF_SCSPTR (0x20) 46865e3474SBiju Das#define SCIF_SCLSR (0x24) 47865e3474SBiju Das#define SCIF_DL (0x30) 48865e3474SBiju Das#define SCIF_CKS (0x34) 49865e3474SBiju Das 50865e3474SBiju Das#if RCAR_LSI == RCAR_V3M 51865e3474SBiju Das#define SCIF_BASE SCIF0_BASE 52865e3474SBiju Das#define CPG_SMSTPCR CPG_SMSTPCR2 53865e3474SBiju Das#define CPG_MSTPSR CPG_MSTPSR2 54865e3474SBiju Das#define MSTP MSTP207 55865e3474SBiju Das#else 56865e3474SBiju Das#define SCIF_BASE SCIF2_BASE 57865e3474SBiju Das#define CPG_SMSTPCR CPG_SMSTPCR3 58865e3474SBiju Das#define CPG_MSTPSR CPG_MSTPSR3 59865e3474SBiju Das#define MSTP MSTP310 60865e3474SBiju Das#endif 61865e3474SBiju Das 62865e3474SBiju Das/* mode pin */ 63865e3474SBiju Das#define RST_MODEMR (0xE6160060) 64865e3474SBiju Das#define MODEMR_MD12 (0x00001000) 65865e3474SBiju Das 66865e3474SBiju Das#define SCSMR_CA_MASK (1 << 7) 67865e3474SBiju Das#define SCSMR_CA_ASYNC (0x0000) 68865e3474SBiju Das#define SCSMR_CHR_MASK (1 << 6) 69865e3474SBiju Das#define SCSMR_CHR_8 (0x0000) 70865e3474SBiju Das#define SCSMR_PE_MASK (1 << 5) 71865e3474SBiju Das#define SCSMR_PE_DIS (0x0000) 72865e3474SBiju Das#define SCSMR_STOP_MASK (1 << 3) 73865e3474SBiju Das#define SCSMR_STOP_1 (0x0000) 74865e3474SBiju Das#define SCSMR_CKS_MASK (3 << 0) 75865e3474SBiju Das#define SCSMR_CKS_DIV1 (0x0000) 76865e3474SBiju Das#define SCSMR_INIT_DATA (SCSMR_CA_ASYNC + \ 77865e3474SBiju Das SCSMR_CHR_8 + \ 78865e3474SBiju Das SCSMR_PE_DIS + \ 79865e3474SBiju Das SCSMR_STOP_1 + \ 80865e3474SBiju Das SCSMR_CKS_DIV1) 81865e3474SBiju Das#define SCBRR_115200BPS (17) 82*14f0a081SToshiyuki Ogasahara#define SCBRR_115200BPS_D3_SSCG (16) 83865e3474SBiju Das#define SCBRR_115200BPS_E3_SSCG (15) 84865e3474SBiju Das#define SCBRR_230400BPS (8) 85865e3474SBiju Das 86865e3474SBiju Das#define SCSCR_TE_MASK (1 << 5) 87865e3474SBiju Das#define SCSCR_TE_DIS (0x0000) 88865e3474SBiju Das#define SCSCR_TE_EN (0x0020) 89865e3474SBiju Das#define SCSCR_RE_MASK (1 << 4) 90865e3474SBiju Das#define SCSCR_RE_DIS (0x0000) 91865e3474SBiju Das#define SCSCR_RE_EN (0x0010) 92865e3474SBiju Das#define SCSCR_CKE_MASK (3 << 0) 93865e3474SBiju Das#define SCSCR_CKE_INT (0x0000) 94865e3474SBiju Das#define SCSCR_CKE_BRG (0x0002) 95865e3474SBiju Das#if SCIF_CLK == SCIF_EXTARNAL_CLK 96865e3474SBiju Das#define SCSCR_CKE_INT_CLK (SCSCR_CKE_BRG) 97865e3474SBiju Das#else 98865e3474SBiju Das#define SCFSR_TEND_MASK (1 << 6) 99865e3474SBiju Das#define SCFSR_TEND_TRANS_END (0x0040) 100865e3474SBiju Das#define SCSCR_CKE_INT_CLK (SCSCR_CKE_INT) 101865e3474SBiju Das#endif 102865e3474SBiju Das#define SCFSR_INIT_DATA (0x0000) 103865e3474SBiju Das#define SCFCR_TTRG_MASK (3 << 4) 104865e3474SBiju Das#define SCFCR_TTRG_8 (0x0000) 105865e3474SBiju Das#define SCFCR_TTRG_0 (0x0030) 106865e3474SBiju Das#define SCFCR_TFRST_MASK (1 << 2) 107865e3474SBiju Das#define SCFCR_TFRST_DIS (0x0000) 108865e3474SBiju Das#define SCFCR_TFRST_EN (0x0004) 109865e3474SBiju Das#define SCFCR_RFRS_MASK (1 << 1) 110865e3474SBiju Das#define SCFCR_RFRS_DIS (0x0000) 111865e3474SBiju Das#define SCFCR_RFRS_EN (0x0002) 112865e3474SBiju Das#define SCFCR_INIT_DATA (SCFCR_TTRG_8) 113865e3474SBiju Das#define SCFDR_T_MASK (0x1f << 8) 114865e3474SBiju Das#define DL_INIT_DATA (8) 115865e3474SBiju Das#define CKS_CKS_DIV_MASK (1 << 15) 116865e3474SBiju Das#define CKS_CKS_DIV_CLK (0x0000) 117865e3474SBiju Das#define CKS_XIN_MASK (1 << 14) 118865e3474SBiju Das#define CKS_XIN_SCIF_CLK (0x0000) 119865e3474SBiju Das#define CKS_INIT_DATA (CKS_CKS_DIV_CLK + CKS_XIN_SCIF_CLK) 120865e3474SBiju Das 121865e3474SBiju Das .globl console_rcar_register 122865e3474SBiju Das .globl console_rcar_init 123865e3474SBiju Das .globl console_rcar_putc 124865e3474SBiju Das .globl console_rcar_flush 125865e3474SBiju Das 126865e3474SBiju Das /* 127865e3474SBiju Das * ----------------------------------------------- 128865e3474SBiju Das * int console_rcar_register( 129865e3474SBiju Das * uintptr_t base, uint32_t clk, uint32_t baud, 130865e3474SBiju Das * console_t *console) 131865e3474SBiju Das * Function to initialize and register a new rcar 132865e3474SBiju Das * console. Storage passed in for the console struct 133865e3474SBiju Das * *must* be persistent (i.e. not from the stack). 134865e3474SBiju Das * In: x0 - UART register base address 135865e3474SBiju Das * w1 - UART clock in Hz 136865e3474SBiju Das * w2 - Baud rate 137865e3474SBiju Das * x3 - pointer to empty console_t struct 138865e3474SBiju Das * Out: return 1 on success, 0 on error 139865e3474SBiju Das * Clobber list : x0, x1, x2, x6, x7, x14 140865e3474SBiju Das * ----------------------------------------------- 141865e3474SBiju Das */ 142865e3474SBiju Dasfunc console_rcar_register 143865e3474SBiju Das mov x7, x30 144865e3474SBiju Das mov x6, x3 145865e3474SBiju Das cbz x6, register_fail 146865e3474SBiju Das str x0, [x6, #CONSOLE_T_BASE] 147865e3474SBiju Das 148865e3474SBiju Das bl console_rcar_init 149865e3474SBiju Das 150865e3474SBiju Das mov x0, x6 151865e3474SBiju Das mov x30, x7 152865e3474SBiju Das finish_console_register rcar, putc=1, getc=0, flush=1 153865e3474SBiju Das 154865e3474SBiju Dasregister_fail: 155865e3474SBiju Das ret x7 156865e3474SBiju Dasendfunc console_rcar_register 157865e3474SBiju Das 158865e3474SBiju Das /* 159865e3474SBiju Das * int console_rcar_init(unsigned long base_addr, 160865e3474SBiju Das * unsigned int uart_clk, unsigned int baud_rate) 161865e3474SBiju Das * Function to initialize the console without a 162865e3474SBiju Das * C Runtime to print debug information. This 163865e3474SBiju Das * function will be accessed by console_rcar_register 164865e3474SBiju Das * and crash reporting. 165865e3474SBiju Das * In: x0 - console base address 166865e3474SBiju Das * w1 - Uart clock in Hz 167865e3474SBiju Das * w2 - Baud rate 168865e3474SBiju Das * Out: return 1 on success 169865e3474SBiju Das * Clobber list : x1, x2 170865e3474SBiju Das */ 171865e3474SBiju Dasfunc console_rcar_init 172865e3474SBiju Das ldr x0, =CPG_BASE 173865e3474SBiju Das ldr w1, [x0, #CPG_SMSTPCR] 174865e3474SBiju Das and w1, w1, #~MSTP 175865e3474SBiju Das mvn w2, w1 176865e3474SBiju Das str w2, [x0, #CPG_CPGWPR] 177865e3474SBiju Das str w1, [x0, #CPG_SMSTPCR] 178865e3474SBiju Das5: 179865e3474SBiju Das ldr w1, [x0, #CPG_MSTPSR] 180865e3474SBiju Das and w1, w1, #MSTP 181865e3474SBiju Das cbnz w1, 5b 182865e3474SBiju Das 183865e3474SBiju Das ldr x0, =SCIF_BASE 184865e3474SBiju Das /* Clear bits TE and RE in SCSCR to 0 */ 185865e3474SBiju Das mov w1, #(SCSCR_TE_DIS + SCSCR_RE_DIS) 186865e3474SBiju Das strh w1, [x0, #SCIF_SCSCR] 187865e3474SBiju Das /* Set bits TFRST and RFRST in SCFCR to 1 */ 188865e3474SBiju Das ldrh w1, [x0, #SCIF_SCFCR] 189865e3474SBiju Das orr w1, w1, #(SCFCR_TFRST_EN + SCFCR_RFRS_EN) 190865e3474SBiju Das strh w1, [x0, #SCIF_SCFCR] 191865e3474SBiju Das /* 192865e3474SBiju Das * Read flags of ER, DR, BRK, and RDF in SCFSR and those of TO and ORER 193865e3474SBiju Das * in SCLSR, then clear them to 0 194865e3474SBiju Das */ 195865e3474SBiju Das mov w1, #SCFSR_INIT_DATA 196865e3474SBiju Das strh w1, [x0, #SCIF_SCFSR] 197865e3474SBiju Das mov w1, #0 198865e3474SBiju Das strh w1, [x0, #SCIF_SCLSR] 199865e3474SBiju Das /* Set bits CKE[1:0] in SCSCR */ 200865e3474SBiju Das ldrh w1, [x0, #SCIF_SCSCR] 201865e3474SBiju Das and w1, w1, #~SCSCR_CKE_MASK 202865e3474SBiju Das mov w2, #SCSCR_CKE_INT_CLK 203865e3474SBiju Das orr w1, w1, w2 204865e3474SBiju Das strh w1, [x0, #SCIF_SCSCR] 205865e3474SBiju Das /* Set data transfer format in SCSMR */ 206865e3474SBiju Das mov w1, #SCSMR_INIT_DATA 207865e3474SBiju Das strh w1, [x0, #SCIF_SCSMR] 208865e3474SBiju Das /* Set value in SCBRR */ 209865e3474SBiju Das#if SCIF_CLK == SCIF_INTERNAL_CLK 210865e3474SBiju Das ldr x1, =PRR 211865e3474SBiju Das ldr w1, [x1] 212865e3474SBiju Das and w1, w1, #(PRR_PRODUCT_MASK | PRR_CUT_MASK) 213865e3474SBiju Das mov w2, #PRR_PRODUCT_H3_VER_10 214865e3474SBiju Das cmp w1, w2 215865e3474SBiju Das beq 3f 216865e3474SBiju Das and w1, w1, #PRR_PRODUCT_MASK 217865e3474SBiju Das mov w2, #PRR_PRODUCT_D3 218865e3474SBiju Das cmp w1, w2 219*14f0a081SToshiyuki Ogasahara beq 5f 220865e3474SBiju Das and w1, w1, #PRR_PRODUCT_MASK 221865e3474SBiju Das mov w2, #PRR_PRODUCT_E3 222865e3474SBiju Das cmp w1, w2 223*14f0a081SToshiyuki Ogasahara bne 4f 224865e3474SBiju Das 225*14f0a081SToshiyuki Ogasahara /* When SSCG(MD12) on (E3) */ 226865e3474SBiju Das ldr x1, =RST_MODEMR 227865e3474SBiju Das ldr w1, [x1] 228865e3474SBiju Das and w1, w1, #MODEMR_MD12 229865e3474SBiju Das mov w2, #MODEMR_MD12 230865e3474SBiju Das cmp w1, w2 231*14f0a081SToshiyuki Ogasahara bne 4f 232865e3474SBiju Das 233*14f0a081SToshiyuki Ogasahara /* When SSCG(MD12) on (E3) */ 234865e3474SBiju Das mov w1, #SCBRR_115200BPS_E3_SSCG 235865e3474SBiju Das b 2f 236865e3474SBiju Das5: 237*14f0a081SToshiyuki Ogasahara /* In case of D3 */ 238*14f0a081SToshiyuki Ogasahara ldr x1, =RST_MODEMR 239*14f0a081SToshiyuki Ogasahara ldr w1, [x1] 240*14f0a081SToshiyuki Ogasahara and w1, w1, #MODEMR_MD12 241*14f0a081SToshiyuki Ogasahara mov w2, #MODEMR_MD12 242*14f0a081SToshiyuki Ogasahara cmp w1, w2 243*14f0a081SToshiyuki Ogasahara bne 4f 244*14f0a081SToshiyuki Ogasahara 245*14f0a081SToshiyuki Ogasahara /* When SSCG(MD12) on (D3) */ 246*14f0a081SToshiyuki Ogasahara mov w1, #SCBRR_115200BPS_D3_SSCG 247865e3474SBiju Das b 2f 248865e3474SBiju Das4: 249*14f0a081SToshiyuki Ogasahara /* In case of H3/M3/M3N or when SSCG(MD12) is off in E3/D3 */ 250*14f0a081SToshiyuki Ogasahara mov w1, #SCBRR_115200BPS 251865e3474SBiju Das b 2f 252865e3474SBiju Das3: 253865e3474SBiju Das mov w1, #SCBRR_230400BPS 254865e3474SBiju Das2: 255865e3474SBiju Das strb w1, [x0, SCIF_SCBRR] 256865e3474SBiju Das#else 257865e3474SBiju Das mov w1, #DL_INIT_DATA 258865e3474SBiju Das strh w1, [x0, #SCIF_DL] 259865e3474SBiju Das mov w1, #CKS_INIT_DATA 260865e3474SBiju Das strh w1, [x0, #SCIF_CKS] 261865e3474SBiju Das#endif 262865e3474SBiju Das /* 1-bit interval elapsed */ 263865e3474SBiju Das mov w1, #100 264865e3474SBiju Das1: 265865e3474SBiju Das subs w1, w1, #1 266865e3474SBiju Das cbnz w1, 1b 267865e3474SBiju Das /* 268865e3474SBiju Das * Set bits RTRG[1:0], TTRG[1:0], and MCE in SCFCR 269865e3474SBiju Das * Clear bits FRST and RFRST to 0 270865e3474SBiju Das */ 271865e3474SBiju Das mov w1, #SCFCR_INIT_DATA 272865e3474SBiju Das strh w1, [x0, #SCIF_SCFCR] 273865e3474SBiju Das /* Set bits TE and RE in SCSCR to 1 */ 274865e3474SBiju Das ldrh w1, [x0, #SCIF_SCSCR] 275865e3474SBiju Das orr w1, w1, #(SCSCR_TE_EN + SCSCR_RE_EN) 276865e3474SBiju Das strh w1, [x0, #SCIF_SCSCR] 277865e3474SBiju Das mov x0, #1 278865e3474SBiju Das 279865e3474SBiju Das ret 280865e3474SBiju Dasendfunc console_rcar_init 281865e3474SBiju Das 282865e3474SBiju Das /* 283865e3474SBiju Das * int console_rcar_putc(int c, unsigned int base_addr) 284865e3474SBiju Das * Function to output a character over the console. It 285865e3474SBiju Das * returns the character printed on success or -1 on error. 286865e3474SBiju Das * In : w0 - character to be printed 287865e3474SBiju Das * x1 - pointer to console_t structure 288865e3474SBiju Das * Out : return -1 on error else return character. 289865e3474SBiju Das * Clobber list : x2 290865e3474SBiju Das */ 291865e3474SBiju Dasfunc console_rcar_putc 292865e3474SBiju Das ldr x1, =SCIF_BASE 293865e3474SBiju Das cmp w0, #0xA 294865e3474SBiju Das /* Prepend '\r' to '\n' */ 295865e3474SBiju Das bne 2f 296865e3474SBiju Das1: 297865e3474SBiju Das /* Check if the transmit FIFO is full */ 298865e3474SBiju Das ldrh w2, [x1, #SCIF_SCFDR] 299865e3474SBiju Das ubfx w2, w2, #8, #5 300865e3474SBiju Das cmp w2, #16 301865e3474SBiju Das bcs 1b 302865e3474SBiju Das mov w2, #0x0D 303865e3474SBiju Das strb w2, [x1, #SCIF_SCFTDR] 304865e3474SBiju Das2: 305865e3474SBiju Das /* Check if the transmit FIFO is full */ 306865e3474SBiju Das ldrh w2, [x1, #SCIF_SCFDR] 307865e3474SBiju Das ubfx w2, w2, #8, #5 308865e3474SBiju Das cmp w2, #16 309865e3474SBiju Das bcs 2b 310865e3474SBiju Das strb w0, [x1, #SCIF_SCFTDR] 311865e3474SBiju Das 312865e3474SBiju Das /* Clear TEND flag */ 313865e3474SBiju Das ldrh w2, [x1, #SCIF_SCFSR] 314865e3474SBiju Das and w2, w2, #~SCFSR_TEND_MASK 315865e3474SBiju Das strh w2, [x1, #SCIF_SCFSR] 316865e3474SBiju Das 317865e3474SBiju Das ret 318865e3474SBiju Dasendfunc console_rcar_putc 319865e3474SBiju Das 320865e3474SBiju Das /* 321865e3474SBiju Das * void console_rcar_flush(void) 322865e3474SBiju Das * Function to force a write of all buffered 323865e3474SBiju Das * data that hasn't been output. It returns void 324865e3474SBiju Das * Clobber list : x0, x1 325865e3474SBiju Das */ 326865e3474SBiju Dasfunc console_rcar_flush 327865e3474SBiju Das ldr x0, =SCIF_BASE 328865e3474SBiju Das1: 329865e3474SBiju Das /* Check TEND flag */ 330865e3474SBiju Das ldrh w1, [x0, #SCIF_SCFSR] 331865e3474SBiju Das and w1, w1, #SCFSR_TEND_MASK 332865e3474SBiju Das cmp w1, #SCFSR_TEND_TRANS_END 333865e3474SBiju Das bne 1b 334865e3474SBiju Das 335865e3474SBiju Das ldr x0, =SCIF_BASE 336865e3474SBiju Das ldrh w1, [x0, #SCIF_SCSCR] 337865e3474SBiju Das and w1, w1, #~(SCSCR_TE_EN + SCSCR_RE_EN) 338865e3474SBiju Das strh w1, [x0, #SCIF_SCSCR] 339865e3474SBiju Das 340865e3474SBiju Das ret 341865e3474SBiju Dasendfunc console_rcar_flush 342