summaryrefslogtreecommitdiff
path: root/drivers/imx/uart/imx_crash_uart.S
blob: aa987b3feb4217c9d9afb975bbfee025445e6b7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * Copyright (c) Linaro 2018 Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#include <arch.h>
#include <asm_macros.S>
#include <assert_macros.S>
#include <imx_uart.h>
#include <platform_def.h>

	.globl	imx_crash_uart_init
	.globl	imx_crash_uart_putc

	/* -----------------------------------------------
	 * int imx_crash_uart_init(uintptr_t 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: r0 - console base address
	 *     r1 - Uart clock in Hz
	 *     r2 - Baud rate
	 * Out: return 1 on success else 0 on error
	 * Clobber list : r1, r2, r3, r4
	 * -----------------------------------------------
	 */
func imx_crash_uart_init
	/* Free up r1 as a scratch reg */
	mov     r4, r0
	mov     r0, r1

	/* Reset UART via CR2 */
	add     r1, r4, #IMX_UART_CR2_OFFSET
	movs    r3, #0
	str     r3, [r4, #IMX_UART_CR2_OFFSET]

	/* Wait for reset complete */
__wait_cr2_reset:
	ldr     r3, [r1, #0]
	ands    r3, #IMX_UART_CR2_SRST
	beq     __wait_cr2_reset

	/* Enable UART */
	movs    r3, #IMX_UART_CR1_UARTEN
	mov     r1, r2
	str     r3, [r4, #IMX_UART_CR1_OFFSET]

	/*
	 * Ignore RTC/CTS - disable reset
	 * Magic value #16423 =>
	 * IMX_UART_CR2_IRTS | IMX_UART_CR2_WS | IMX_UART_CR2_TXEN | IMX_UART_CR2_RXEN | IMX_UART_CR2_SRST
	 */
	movw    r3, #16423
	str     r3, [r4, #IMX_UART_CR2_OFFSET]

	/*
	 * No parity, autobaud detect-old, rxdmuxsel=1 (fixed i.mx7)
	 * Magic value => #132
	 * IMX_UART_CR3_ADNIMP | IMX_UART_CR3_RXDMUXSEL
	 */
	movs    r3, #132
	str     r3, [r4, #IMX_UART_CR3_OFFSET]

	/*
	 * Set CTS FIFO trigger to 32 bytes bits 15:10
	 * Magic value => #32768
	 * FIFO trigger bitmask 100000
	 * */
	mov     r3, #32768
	str     r3, [r4, #IMX_UART_CR4_OFFSET]

	/*
	 * TX/RX-thresh = 2 bytes, DCE (bit6 = 0), refclk @24MHz / 4
	 * Magic value #2562
	 * IMX_UART_FCR_TXTL(TX_RX_THRESH) | IMX_UART_FCR_RXTL(TX_RX_THRESH) | IMX_UART_FCR_RFDIV2
	 */
	#ifdef IMX_UART_DTE
	movw    r3, #2626
	#else
	movw    r3, #2562
	#endif
	str     r3, [r4, #IMX_UART_FCR_OFFSET]

	/* This BIR should be set to 0x0F prior to writing the BMR */
	movs    r3, #15
	str     r3, [r4, #IMX_UART_BIR_OFFSET]

	/* Hard-code to 115200 @ 24 MHz */
	movs	r0, #104
	str     r0, [r4, #IMX_UART_BMR_OFFSET]

	/* Indicate success */
	movs    r0, #1
	bx	lr
endfunc imx_crash_uart_init

	/* --------------------------------------------------------
	 * int imx_crash_uart_putc(int c, uintptr_t base_addr)
	 * Function to output a character over the console. It
	 * returns the character printed on success or -1 on error.
	 * In : r0 - character to be printed
	 *      r1 - console base address
	 * Out : return -1 on error else return character.
	 * Clobber list : r2
	 * --------------------------------------------------------
	 */
func imx_crash_uart_putc
	/* Output specified character to UART shift-register */
	str	r0, [r1, #IMX_UART_TXD_OFFSET]

        /* Wait for transmit IMX_UART_STAT2_OFFSET.IMX_UART_STAT2_TXDC == 1 */
__putc_spin_ready:
	ldr	r2, [r1, #IMX_UART_STAT2_OFFSET]
	ands	r2, #IMX_UART_STAT2_TXDC
	beq	__putc_spin_ready

        /* Transmit complete do we need to fixup \n to \n\r */
	cmp	r0, #10
	beq	__putc_fixup_lf

	/* No fixup necessary - exit here */
	movs	r0, #0
	bx	lr

	/* Fixup \n to \n\r */
__putc_fixup_lf:
	movs	r0, #13
	b	imx_crash_uart_putc
endfunc imx_crash_uart_putc