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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
|
#ifndef __MTK_UART_H__
#define __MTK_UART_H__
#include <mach/hardware.h>
#ifndef CONFIG_OF
#include <mach/mt_reg_base.h>
#endif
#include <mach/sync_write.h>
#include "platform_uart.h"
/*---------------------------------------------------------------------------*/
#if defined(ENABLE_VFIFO_DEBUG)
/*---------------------------------------------------------------------------*/
#define DGBUF_INIT(v) \
do { \
if (UART_DEBUG_EVT(DBG_EVT_BUF)) { \
v->dbgidx = (v->dbgidx+1)%(ARRAY_SIZE(v->dbg)); \
v->cur = &v->dbg[v->dbgidx]; \
v->cur->idx = 0; \
} \
} while (0)
/*---------------------------------------------------------------------------*/
#define DGBUF_PUSH_CH(v, c) \
do { \
if (UART_DEBUG_EVT(DBG_EVT_BUF)) \
v->cur->dat[v->cur->idx++] = (char)(c); \
} while (0)
/*---------------------------------------------------------------------------*/
#define DGBUF_PUSH_STR(v, s, l) \
do { \
if (UART_DEBUG_EVT(DBG_EVT_BUF)) {\
memcpy(&v->cur->dat[v->cur->idx], (s), (l)); \
v->cur->idx += (l); \
} \
} while (0)
#else
/*---------------------------------------------------------------------------*/
#define DGBUF_INIT(v)
#define DGBUF_PUSH_CH(v, c)
#define DGBUF_PUSH_STR(v, s, l)
#endif
/******************************************************************************
* ENUM & STRUCT
******************************************************************************/
typedef enum {
UART_NON_DMA,
UART_TX_DMA,
UART_TX_VFIFO_DMA,
UART_RX_VFIFO_DMA,
} UART_DMA_TYPE;
/*---------------------------------------------------------------------------*/
typedef enum {
UART_TX_VFIFO,
UART_RX_VFIFO,
UART_VFIFO_NUM
} UART_VFF_TYPE;
/*---------------------------------------------------------------------------*/
/* uart dma mode */
enum {
UART_DMA_MODE_0,
UART_DMA_MODE_1,
};
/*---------------------------------------------------------------------------*/
/* flow control mode */
enum {
UART_FC_NONE, /*NO flow control */
UART_FC_SW, /*MTK SW Flow Control, differs from Linux Flow Control */
UART_FC_HW, /*HW Flow Control */
};
/*---------------------------------------------------------------------------*/
struct mtk_uart_setting {
u8 tx_mode;
u8 rx_mode;
u8 dma_mode;
u8 sysrq;
int tx_trig;
int rx_trig;
unsigned long uart_base;
#ifdef CONFIG_OF
unsigned long uart_phys_base;
unsigned long irq_flags;
#endif
u8 irq_num;
u8 irq_sen;
u8 set_bit; /*APMCU_CG_SET0 */
u8 clr_bit; /*APMCU_CG_CLR0 */
int pll_id;
u8 hw_flow; /*support hardware flow control or not?! */
u8 vff; /*support vfifo or not!? */
u16 _align;
};
/*---------------------------------------------------------------------------*/
#define C_UART_DEBUG_BUF_NUM (5)
/*---------------------------------------------------------------------------*/
struct mtk_uart_buf {
unsigned char *dat;
unsigned int idx;
unsigned int len;
};
/*---------------------------------------------------------------------------*/
struct mtk_uart_vfifo {
struct mtk_uart_dma *dma; /* vfifo dma owner */
/*configuration */
u16 ch;
u16 size;
u16 trig;
u16 type; /*UART_RX_VFIFO / UART_TX_VFIFO */
void *base;
void *port; /*only tx */
void *addr;
atomic_t reg_cb;
atomic_t entry; /* entry count */
spinlock_t iolock;
struct timer_list timer; /* vfifo timer */
struct hrtimer flush;
dma_addr_t dmahd; /* dma handle */
struct tasklet_struct flush_tasklet;
struct mtk_uart_buf dbg[C_UART_DEBUG_BUF_NUM];
struct mtk_uart_buf *cur;
int dbgidx;
unsigned int irq_id;
};
/*---------------------------------------------------------------------------*/
struct mtk_uart_dma {
struct mtk_uart *uart; /* dma uart */
atomic_t free; /* dma channel free */
unsigned short mode; /* dma mode */
unsigned short dir; /* dma transfer direction */
struct tasklet_struct tasklet; /* dma handling tasklet */
struct completion done; /* dma transfer done */
struct mtk_uart_vfifo *vfifo; /* dma vfifo */
};
/*---------------------------------------------------------------------------*/
struct mtk_uart_register {
unsigned int dll;
unsigned int dlh;
unsigned int ier;
unsigned int lcr;
unsigned int mcr;
unsigned int fcr;
unsigned int lsr;
unsigned int efr;
unsigned int highspeed;
unsigned int sample_count;
unsigned int sample_point;
unsigned int fracdiv_l;
unsigned int fracdiv_m;
unsigned int escape_en;
unsigned int guard;
unsigned int rx_sel;
};
/*---------------------------------------------------------------------------*/
struct mtk_uart {
struct uart_port port;
unsigned long base;
int nport;
unsigned int old_status;
unsigned int tx_stop;
unsigned int rx_stop;
unsigned int ms_enable;
unsigned int auto_baud;
unsigned int line_status;
unsigned int ignore_rx;
unsigned int flow_ctrl;
unsigned long pending_tx_reqs;
unsigned long tx_trig; /* tx fifo trigger level */
unsigned long rx_trig; /* rx fifo trigger level */
unsigned long sysclk;
unsigned long evt_mask;
unsigned long lsr_status;
int baudrate; /*current baudrate */
int custom_baud; /*custom baudrate passed from serial_struct */
int dma_mode;
int tx_mode;
int rx_mode;
int fctl_mode; /*flow control */
int poweron_count;
int timeout_count; /*for console write */
unsigned int fcr_back_up; /* FCR register is a write only register */
struct mtk_uart_register registers;
struct mtk_uart_dma dma_tx;
struct mtk_uart_dma dma_rx;
struct mtk_uart_vfifo *tx_vfifo;
struct mtk_uart_vfifo *rx_vfifo;
struct mtk_uart_setting *setting;
unsigned int (*write_allow) (struct mtk_uart *uart);
unsigned int (*read_allow) (struct mtk_uart *uart);
void (*write_byte) (struct mtk_uart *uart, unsigned int byte);
unsigned int (*read_byte) (struct mtk_uart *uart);
unsigned int (*read_status) (struct mtk_uart *uart);
};
/*---------------------------------------------------------------------------*/
/* fiq debugger */
/*---------------------------------------------------------------------------*/
struct fiq_dbg_event {
u32 iir;
int data;
};
/*---------------------------------------------------------------------------*/
/* #define UART_READ8(REG) __raw_readb(REG) */
/* #define UART_READ16(REG) __raw_readw(REG) */
/* #define UART_READ32(REG) __raw_readl(REG) */
#define UART_READ8(REG) (*(volatile unsigned char*)(REG))
#define UART_READ16(REG) (*(volatile unsigned short*)(REG))
#define UART_READ32(REG) (*(volatile unsigned int*)(REG))
#define reg_sync_writeb(v, a) mt_reg_sync_writeb(v, a)
#define reg_sync_writel(v, a) mt_reg_sync_writel(v, a)
/*---------------------------------------------------------------------------*/
#define UART_SET_BITS(BS, REG) ((*(volatile u32*)(REG)) |= (u32)(BS))
#define UART_CLR_BITS(BS, REG) ((*(volatile u32*)(REG)) &= ~((u32)(BS)))
/*---------------------------------------------------------------------------*/
extern spinlock_t mtk_console_lock;
extern struct mtk_uart *console_port;
unsigned int mtk_uart_pdn_enable(char *port, int enable);
extern void update_history_byte(char is_tx, int nport, unsigned char byte);
extern void update_history_time(char is_tx, int nport);
extern void update_history_bulk(char is_tx, int nport, unsigned char *chars, int count);
extern struct resource fiq_resource[];
#endif /* MTK_UART_H */
|