xref: /rk3399_ARM-atf/drivers/imx/uart/imx_crash_uart.S (revision 36044baf08a9f816a8a062a8a50ede12a816a6dd)
1*2f5307d6SBryan O'Donoghue/*
2*2f5307d6SBryan O'Donoghue * Copyright (c) Linaro 2018 Limited and Contributors. All rights reserved.
3*2f5307d6SBryan O'Donoghue *
4*2f5307d6SBryan O'Donoghue * SPDX-License-Identifier: BSD-3-Clause
5*2f5307d6SBryan O'Donoghue */
6*2f5307d6SBryan O'Donoghue#include <arch.h>
7*2f5307d6SBryan O'Donoghue#include <asm_macros.S>
8*2f5307d6SBryan O'Donoghue#include <assert_macros.S>
9*2f5307d6SBryan O'Donoghue#include <imx_uart.h>
10*2f5307d6SBryan O'Donoghue#include <platform_def.h>
11*2f5307d6SBryan O'Donoghue
12*2f5307d6SBryan O'Donoghue	.globl	imx_crash_uart_init
13*2f5307d6SBryan O'Donoghue	.globl	imx_crash_uart_putc
14*2f5307d6SBryan O'Donoghue
15*2f5307d6SBryan O'Donoghue	/* -----------------------------------------------
16*2f5307d6SBryan O'Donoghue	 * int imx_crash_uart_init(uintptr_t base_addr,
17*2f5307d6SBryan O'Donoghue	 * unsigned int uart_clk, unsigned int baud_rate)
18*2f5307d6SBryan O'Donoghue	 * Function to initialize the console without a
19*2f5307d6SBryan O'Donoghue	 * C Runtime to print debug information. This
20*2f5307d6SBryan O'Donoghue	 * function will be accessed by console_init and
21*2f5307d6SBryan O'Donoghue	 * crash reporting.
22*2f5307d6SBryan O'Donoghue	 * In: r0 - console base address
23*2f5307d6SBryan O'Donoghue	 *     r1 - Uart clock in Hz
24*2f5307d6SBryan O'Donoghue	 *     r2 - Baud rate
25*2f5307d6SBryan O'Donoghue	 * Out: return 1 on success else 0 on error
26*2f5307d6SBryan O'Donoghue	 * Clobber list : r1, r2, r3, r4
27*2f5307d6SBryan O'Donoghue	 * -----------------------------------------------
28*2f5307d6SBryan O'Donoghue	 */
29*2f5307d6SBryan O'Donoghuefunc imx_crash_uart_init
30*2f5307d6SBryan O'Donoghue	/* Free up r1 as a scratch reg */
31*2f5307d6SBryan O'Donoghue	mov     r4, r0
32*2f5307d6SBryan O'Donoghue	mov     r0, r1
33*2f5307d6SBryan O'Donoghue
34*2f5307d6SBryan O'Donoghue	/* Reset UART via CR2 */
35*2f5307d6SBryan O'Donoghue	add     r1, r4, #IMX_UART_CR2_OFFSET
36*2f5307d6SBryan O'Donoghue	movs    r3, #0
37*2f5307d6SBryan O'Donoghue	str     r3, [r4, #IMX_UART_CR2_OFFSET]
38*2f5307d6SBryan O'Donoghue
39*2f5307d6SBryan O'Donoghue	/* Wait for reset complete */
40*2f5307d6SBryan O'Donoghue__wait_cr2_reset:
41*2f5307d6SBryan O'Donoghue	ldr     r3, [r1, #0]
42*2f5307d6SBryan O'Donoghue	ands    r3, #IMX_UART_CR2_SRST
43*2f5307d6SBryan O'Donoghue	beq     __wait_cr2_reset
44*2f5307d6SBryan O'Donoghue
45*2f5307d6SBryan O'Donoghue	/* Enable UART */
46*2f5307d6SBryan O'Donoghue	movs    r3, #IMX_UART_CR1_UARTEN
47*2f5307d6SBryan O'Donoghue	mov     r1, r2
48*2f5307d6SBryan O'Donoghue	str     r3, [r4, #IMX_UART_CR1_OFFSET]
49*2f5307d6SBryan O'Donoghue
50*2f5307d6SBryan O'Donoghue	/*
51*2f5307d6SBryan O'Donoghue	 * Ignore RTC/CTS - disable reset
52*2f5307d6SBryan O'Donoghue	 * Magic value #16423 =>
53*2f5307d6SBryan O'Donoghue	 * IMX_UART_CR2_IRTS | IMX_UART_CR2_WS | IMX_UART_CR2_TXEN | IMX_UART_CR2_RXEN | IMX_UART_CR2_SRST
54*2f5307d6SBryan O'Donoghue	 */
55*2f5307d6SBryan O'Donoghue	movw    r3, #16423
56*2f5307d6SBryan O'Donoghue	str     r3, [r4, #IMX_UART_CR2_OFFSET]
57*2f5307d6SBryan O'Donoghue
58*2f5307d6SBryan O'Donoghue	/*
59*2f5307d6SBryan O'Donoghue	 * No parity, autobaud detect-old, rxdmuxsel=1 (fixed i.mx7)
60*2f5307d6SBryan O'Donoghue	 * Magic value => #132
61*2f5307d6SBryan O'Donoghue	 * IMX_UART_CR3_ADNIMP | IMX_UART_CR3_RXDMUXSEL
62*2f5307d6SBryan O'Donoghue	 */
63*2f5307d6SBryan O'Donoghue	movs    r3, #132
64*2f5307d6SBryan O'Donoghue	str     r3, [r4, #IMX_UART_CR3_OFFSET]
65*2f5307d6SBryan O'Donoghue
66*2f5307d6SBryan O'Donoghue	/*
67*2f5307d6SBryan O'Donoghue	 * Set CTS FIFO trigger to 32 bytes bits 15:10
68*2f5307d6SBryan O'Donoghue	 * Magic value => #32768
69*2f5307d6SBryan O'Donoghue	 * FIFO trigger bitmask 100000
70*2f5307d6SBryan O'Donoghue	 * */
71*2f5307d6SBryan O'Donoghue	mov     r3, #32768
72*2f5307d6SBryan O'Donoghue	str     r3, [r4, #IMX_UART_CR4_OFFSET]
73*2f5307d6SBryan O'Donoghue
74*2f5307d6SBryan O'Donoghue	/*
75*2f5307d6SBryan O'Donoghue	 * TX/RX-thresh = 2 bytes, DCE (bit6 = 0), refclk @24MHz / 4
76*2f5307d6SBryan O'Donoghue	 * Magic value #2562
77*2f5307d6SBryan O'Donoghue	 * IMX_UART_FCR_TXTL(TX_RX_THRESH) | IMX_UART_FCR_RXTL(TX_RX_THRESH) | IMX_UART_FCR_RFDIV2
78*2f5307d6SBryan O'Donoghue	 */
79*2f5307d6SBryan O'Donoghue	#ifdef IMX_UART_DTE
80*2f5307d6SBryan O'Donoghue	movw    r3, #2626
81*2f5307d6SBryan O'Donoghue	#else
82*2f5307d6SBryan O'Donoghue	movw    r3, #2562
83*2f5307d6SBryan O'Donoghue	#endif
84*2f5307d6SBryan O'Donoghue	str     r3, [r4, #IMX_UART_FCR_OFFSET]
85*2f5307d6SBryan O'Donoghue
86*2f5307d6SBryan O'Donoghue	/* This BIR should be set to 0x0F prior to writing the BMR */
87*2f5307d6SBryan O'Donoghue	movs    r3, #15
88*2f5307d6SBryan O'Donoghue	str     r3, [r4, #IMX_UART_BIR_OFFSET]
89*2f5307d6SBryan O'Donoghue
90*2f5307d6SBryan O'Donoghue	/* Hard-code to 115200 @ 24 MHz */
91*2f5307d6SBryan O'Donoghue	movs	r0, #104
92*2f5307d6SBryan O'Donoghue	str     r0, [r4, #IMX_UART_BMR_OFFSET]
93*2f5307d6SBryan O'Donoghue
94*2f5307d6SBryan O'Donoghue	/* Indicate success */
95*2f5307d6SBryan O'Donoghue	movs    r0, #1
96*2f5307d6SBryan O'Donoghue	bx	lr
97*2f5307d6SBryan O'Donoghueendfunc imx_crash_uart_init
98*2f5307d6SBryan O'Donoghue
99*2f5307d6SBryan O'Donoghue	/* --------------------------------------------------------
100*2f5307d6SBryan O'Donoghue	 * int imx_crash_uart_putc(int c, uintptr_t base_addr)
101*2f5307d6SBryan O'Donoghue	 * Function to output a character over the console. It
102*2f5307d6SBryan O'Donoghue	 * returns the character printed on success or -1 on error.
103*2f5307d6SBryan O'Donoghue	 * In : r0 - character to be printed
104*2f5307d6SBryan O'Donoghue	 *      r1 - console base address
105*2f5307d6SBryan O'Donoghue	 * Out : return -1 on error else return character.
106*2f5307d6SBryan O'Donoghue	 * Clobber list : r2
107*2f5307d6SBryan O'Donoghue	 * --------------------------------------------------------
108*2f5307d6SBryan O'Donoghue	 */
109*2f5307d6SBryan O'Donoghuefunc imx_crash_uart_putc
110*2f5307d6SBryan O'Donoghue	/* Output specified character to UART shift-register */
111*2f5307d6SBryan O'Donoghue	str	r0, [r1, #IMX_UART_TXD_OFFSET]
112*2f5307d6SBryan O'Donoghue
113*2f5307d6SBryan O'Donoghue        /* Wait for transmit IMX_UART_STAT2_OFFSET.IMX_UART_STAT2_TXDC == 1 */
114*2f5307d6SBryan O'Donoghue__putc_spin_ready:
115*2f5307d6SBryan O'Donoghue	ldr	r2, [r1, #IMX_UART_STAT2_OFFSET]
116*2f5307d6SBryan O'Donoghue	ands	r2, #IMX_UART_STAT2_TXDC
117*2f5307d6SBryan O'Donoghue	beq	__putc_spin_ready
118*2f5307d6SBryan O'Donoghue
119*2f5307d6SBryan O'Donoghue        /* Transmit complete do we need to fixup \n to \n\r */
120*2f5307d6SBryan O'Donoghue	cmp	r0, #10
121*2f5307d6SBryan O'Donoghue	beq	__putc_fixup_lf
122*2f5307d6SBryan O'Donoghue
123*2f5307d6SBryan O'Donoghue	/* No fixup necessary - exit here */
124*2f5307d6SBryan O'Donoghue	movs	r0, #0
125*2f5307d6SBryan O'Donoghue	bx	lr
126*2f5307d6SBryan O'Donoghue
127*2f5307d6SBryan O'Donoghue	/* Fixup \n to \n\r */
128*2f5307d6SBryan O'Donoghue__putc_fixup_lf:
129*2f5307d6SBryan O'Donoghue	movs	r0, #13
130*2f5307d6SBryan O'Donoghue	b	imx_crash_uart_putc
131*2f5307d6SBryan O'Donoghueendfunc imx_crash_uart_putc
132