summaryrefslogtreecommitdiffstats
path: root/arch/mips/mach-ath79/include/mach/debug_ll.h
blob: 04bd3ea72bec494fbfb4497b99669ee07d1d81a5 (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*
 * based on linux.git/drivers/tty/serial/ar933x_uart.c
 *
 * This file is part of barebox.
 * See file CREDITS for list of people who contributed to this project.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#ifndef __AR933X_DEBUG_LL__
#define __AR933X_DEBUG_LL__

#include <asm/addrspace.h>
#include <mach/ar71xx_regs.h>

#define DEBUG_LL_UART_ADDR	KSEG1ADDR(AR933X_UART_BASE)

#define AR933X_UART_DATA_REG            0x00
#define AR933X_UART_DATA_TX_RX_MASK     0xff
#define AR933X_UART_DATA_TX_CSR		0x200
#define AR933X_UART_DATA_RX_CSR		0x100

#ifndef __ASSEMBLY__

#include <io.h>

/*
 * C macros
 */

static inline void ar933x_debug_ll_writel(u32 b, int offset)
{
	__raw_writel(b, (u8 *)DEBUG_LL_UART_ADDR + offset);
}

static inline u32 ar933x_debug_ll_readl(int offset)
{
	return __raw_readl((u8 *)DEBUG_LL_UART_ADDR + offset);
}

static inline void PUTC_LL(int ch)
{
	u32 data;

	/* wait transmitter ready */
	data = ar933x_debug_ll_readl(AR933X_UART_DATA_REG);
	while (!(data & AR933X_UART_DATA_TX_CSR))
		data = ar933x_debug_ll_readl(AR933X_UART_DATA_REG);

	data = (ch & AR933X_UART_DATA_TX_RX_MASK) | AR933X_UART_DATA_TX_CSR;
	ar933x_debug_ll_writel(data, AR933X_UART_DATA_REG);
}
#else /* __ASSEMBLY__ */
/*
 * Macros for use in assembly language code
 */

#define AR933X_UART_CS_REG		0x04
#define UART_CS_REG	((KSEG1 | AR933X_UART_BASE) | AR933X_UART_CS_REG)
#define AR933X_UART_CS_IF_MODE_S	2
#define	  AR933X_UART_CS_IF_MODE_DCE	2
#define AR933X_UART_CS_TX_READY_ORIDE	BIT(7)
#define AR933X_UART_CS_RX_READY_ORIDE	BIT(8)

/*
 * simple uart clock setup
 * from u-boot_mod/u-boot/cpu/mips/ar7240/hornet_serial.c
 */
#define BAUD_CLOCK 25000000
#define CLOCK_SCALE ((BAUD_CLOCK / (16 * CONFIG_BAUDRATE)) - 1)
#define CLOCK_STEP 0x2000

#define AR933X_UART_CLOCK_REG		0x08
#define CLOCK_REG	((KSEG1 | AR933X_UART_BASE) | AR933X_UART_CLOCK_REG)

.macro debug_ll_ar9331_init
#ifdef CONFIG_DEBUG_LL

	pbl_reg_writel ((AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S) \
			| AR933X_UART_CS_TX_READY_ORIDE \
			| AR933X_UART_CS_RX_READY_ORIDE), UART_CS_REG
	pbl_reg_writel ((CLOCK_SCALE << 16) | CLOCK_STEP), CLOCK_REG

#endif /* CONFIG_DEBUG_LL */
.endm

/*
 * output a character in a0
 */
.macro	debug_ll_outc_a0
#ifdef CONFIG_DEBUG_LL
	.set	push
	.set	reorder

	la	t0, DEBUG_LL_UART_ADDR
201:
	lw	t1, AR933X_UART_DATA_REG(t0)	/* get line status */
	andi	t1, t1, AR933X_UART_DATA_TX_CSR	/* check for transmitter empty */
	beqz	t1, 201b	/* try again */
	andi	a0, a0, AR933X_UART_DATA_TX_RX_MASK
	ori	a0, a0, AR933X_UART_DATA_TX_CSR
	sw	a0, 0(t0)	/* write the character */
	.set	pop
#endif /* CONFIG_DEBUG_LL */
.endm

/*
 * output a character
 */
.macro	debug_ll_outc chr
#ifdef CONFIG_DEBUG_LL
	li	a0, \chr
	debug_ll_outc_a0
#endif /* CONFIG_DEBUG_LL */
.endm

/*
 * check character in input buffer
 * return value:
 *  v0 = 0   no character in input buffer
 *  v0 != 0  character in input buffer
 */
/* FIXME: use tstc */
.macro	debug_ll_tstc
#ifdef CONFIG_DEBUG_LL
	.set	push
	.set	reorder

	la	t0, DEBUG_LL_UART_ADDR

	/* get line status and check for data present */
	lw	v0, AR933X_UART_DATA_REG(t0)
	andi	v0, v0, AR933X_UART_DATA_RX_CSR

	.set	pop
#endif /* CONFIG_DEBUG_LL */
.endm

/*
 * get character to v0
 */
.macro	debug_ll_getc
#ifdef CONFIG_DEBUG_LL
	.set	push
	.set	reorder

	la	t0, DEBUG_LL_UART_ADDR
204:
	lw	v0, AR933X_UART_DATA_REG(t0)
	andi	v0, v0, AR933X_UART_DATA_RX_CSR

	/* try again */
	beqz	v0, 204b

	/* read a character */
	lw	v0, AR933X_UART_DATA_REG(t0)
	andi	v0, v0, AR933X_UART_DATA_TX_RX_MASK

	/* remove the character from the FIFO */
	li	t1, AR933X_UART_DATA_RX_CSR
	sw  t1, AR933X_UART_DATA_REG(t0)

	.set	pop
#endif /* CONFIG_DEBUG_LL */
.endm
#endif /* __ASSEMBLY__ */

#endif /* __AR933X_DEBUG_LL__ */