summaryrefslogtreecommitdiff
path: root/firmware/export
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/export')
-rw-r--r--firmware/export/s5l8702.h9
-rw-r--r--firmware/export/uc870x.h372
2 files changed, 377 insertions, 4 deletions
diff --git a/firmware/export/s5l8702.h b/firmware/export/s5l8702.h
index 00d92a58b1..59170b04ea 100644
--- a/firmware/export/s5l8702.h
+++ b/firmware/export/s5l8702.h
@@ -711,9 +711,10 @@
711 711
712 712
713/////UART///// 713/////UART/////
714/* UC8702 uart controller */ 714/* s5l8702 UC870X HW: 1 UARTC, 4 ports */
715#define S5L8702_UART_BASE 0x3cc00000 715#define UARTC_BASE_ADDR 0x3CC00000
716#define S5L8702_UART_PORT_MAX 4 716#define UARTC_N_PORTS 4
717#define UARTC_PORT_OFFSET 0x4000
717 718
718 719
719/////CLOCK GATES///// 720/////CLOCK GATES/////
@@ -737,7 +738,7 @@
737#define CLOCKGATE_TIMER 37 738#define CLOCKGATE_TIMER 37
738#define CLOCKGATE_I2C1 38 739#define CLOCKGATE_I2C1 38
739#define CLOCKGATE_I2S0 39 740#define CLOCKGATE_I2S0 39
740#define CLOCKGATE_UART 41 741#define CLOCKGATE_UARTC 41
741#define CLOCKGATE_I2S1 42 742#define CLOCKGATE_I2S1 42
742#define CLOCKGATE_SPI1 43 743#define CLOCKGATE_SPI1 43
743#define CLOCKGATE_GPIO 44 744#define CLOCKGATE_GPIO 44
diff --git a/firmware/export/uc870x.h b/firmware/export/uc870x.h
new file mode 100644
index 0000000000..ad7168fe64
--- /dev/null
+++ b/firmware/export/uc870x.h
@@ -0,0 +1,372 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2014 by Cástor Muñoz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __UC870X_H__
22#define __UC870X_H__
23
24#include <stdint.h>
25#include <stdbool.h>
26
27#include "config.h"
28#include "system.h"
29#include "uart-target.h"
30
31
32/*
33 * UC870x: UART controller for s5l870x
34 *
35 * This UART is similar to the UART described in s5l8700 datasheet,
36 * (see also s3c2416 and s3c6400 datasheets). On s5l8701/2 the UC870x
37 * includes autobauding, and fine tunning for Tx/Rx on s5l8702.
38 */
39
40/*
41 * Controller registers
42 */
43#define REG32_PTR_T volatile uint32_t *
44
45#define ULCON(ba) (*((REG32_PTR_T)((ba) + 0x00))) /* line control */
46#define UCON(ba) (*((REG32_PTR_T)((ba) + 0x04))) /* control */
47#define UFCON(ba) (*((REG32_PTR_T)((ba) + 0x08))) /* FIFO control */
48#define UMCON(ba) (*((REG32_PTR_T)((ba) + 0x0C))) /* modem control */
49#define UTRSTAT(ba) (*((REG32_PTR_T)((ba) + 0x10))) /* Tx/Rx status */
50#define UERSTAT(ba) (*((REG32_PTR_T)((ba) + 0x14))) /* Rx error status */
51#define UFSTAT(ba) (*((REG32_PTR_T)((ba) + 0x18))) /* FIFO status */
52#define UMSTAT(ba) (*((REG32_PTR_T)((ba) + 0x1C))) /* modem status */
53#define UTXH(ba) (*((REG32_PTR_T)((ba) + 0x20))) /* transmission hold */
54#define URXH(ba) (*((REG32_PTR_T)((ba) + 0x24))) /* receive buffer */
55#define UBRDIV(ba) (*((REG32_PTR_T)((ba) + 0x28))) /* baud rate divisor */
56#if CONFIG_CPU != S5L8700
57#define UABRCNT(ba) (*((REG32_PTR_T)((ba) + 0x2c))) /* autobaud counter */
58#define UABRSTAT(ba) (*((REG32_PTR_T)((ba) + 0x30))) /* autobaud status */
59#endif
60#if CONFIG_CPU == S5L8702
61#define UBRCONTX(ba) (*((REG32_PTR_T)((ba) + 0x34))) /* Tx frame config */
62#define UBRCONRX(ba) (*((REG32_PTR_T)((ba) + 0x38))) /* Rx frame config */
63#endif
64
65/* ULCON register */
66#define ULCON_DATA_BITS_MASK 0x3
67#define ULCON_DATA_BITS_POS 0
68#define ULCON_DATA_BITS_5 0
69#define ULCON_DATA_BITS_6 1
70#define ULCON_DATA_BITS_7 2
71#define ULCON_DATA_BITS_8 3
72
73#define ULCON_STOP_BITS_MASK 0x1
74#define ULCON_STOP_BITS_POS 2
75#define ULCON_STOP_BITS_1 0
76#define ULCON_STOP_BITS_2 1
77
78#define ULCON_PARITY_MASK 0x7
79#define ULCON_PARITY_POS 3
80#define ULCON_PARITY_NONE 0
81#define ULCON_PARITY_ODD 4
82#define ULCON_PARITY_EVEN 5
83#define ULCON_PARITY_FORCE_1 6
84#define ULCON_PARITY_FORCE_0 7
85
86#define ULCON_INFRARED_EN_BIT (1 << 6)
87
88/* UCON register */
89#define UCON_RX_MODE_MASK 0x3
90#define UCON_RX_MODE_POS 0
91
92#define UCON_TX_MODE_MASK 0x3
93#define UCON_TX_MODE_POS 2
94
95#define UCON_MODE_DISABLED 0
96#define UCON_MODE_INTREQ 1 /* INT request or polling mode */
97#define UCON_MODE_UNDEFINED 2 /* Not defined, DMAREQ signal 1 ??? */
98#define UCON_MODE_DMAREQ 3 /* DMA request (signal 0) */
99
100#define UCON_SEND_BREAK_BIT (1 << 4)
101#define UCON_LOOPBACK_BIT (1 << 5)
102#define UCON_RX_TOUT_EN_BIT (1 << 7) /* Rx timeout enable */
103
104#define UCON_CLKSEL_MASK 0x1
105#define UCON_CLKSEL_POS 10
106#define UCON_CLKSEL_PCLK 0 /* internal */
107#define UCON_CLKSEL_ECLK 1 /* external */
108
109#if CONFIG_CPU == S5L8702
110#define UCON_RX_TOUT_INT_BIT (1 << 11) /* Rx timeout INT enable */
111#endif
112#define UCON_RX_INT_BIT (1 << 12) /* Rx INT enable */
113#define UCON_TX_INT_BIT (1 << 13) /* Tx INT enable */
114#define UCON_ERR_INT_BIT (1 << 14) /* Rx error INT enable */
115#define UCON_MODEM_INT_BIT (1 << 15) /* modem INT enable (TBC) */
116#if CONFIG_CPU != S5L8700
117#define UCON_AUTOBR_INT_BIT (1 << 16) /* autobauding INT enable */
118#define UCON_AUTOBR_START_BIT (1 << 17) /* autobauding start/stop */
119#endif
120
121#if CONFIG_CPU == S5L8701
122/* WTF! ABR bits are swapped on reads, so don't forget to
123 always use this workaround to read the UCON register. */
124static inline uint32_t _UCON_RD(uint32_t ba)
125{
126 uint32_t ucon = UCON(ba);
127 return ((ucon & 0xffff) |
128 ((ucon & UCON_AUTOBR_INT_BIT) << 1) |
129 ((ucon & UCON_AUTOBR_START_BIT) >> 1));
130}
131#else
132#define _UCON_RD(ba) UCON(ba)
133#endif
134
135/* UFCON register */
136#define UFCON_FIFO_ENABLE_BIT (1 << 0)
137#define UFCON_RX_FIFO_RST_BIT (1 << 1)
138#define UFCON_TX_FIFO_RST_BIT (1 << 2)
139
140#define UFCON_RX_FIFO_TRG_MASK 0x3
141#define UFCON_RX_FIFO_TRG_POS 4
142#define UFCON_RX_FIFO_TRG_4 0
143#define UFCON_RX_FIFO_TRG_8 1
144#define UFCON_RX_FIFO_TRG_12 2
145#define UFCON_RX_FIFO_TRG_16 3
146
147#define UFCON_TX_FIFO_TRG_MASK 0x3
148#define UFCON_TX_FIFO_TRG_POS 6
149#define UFCON_TX_FIFO_TRG_EMPTY 0
150#define UFCON_TX_FIFO_TRG_4 1
151#define UFCON_TX_FIFO_TRG_8 2
152#define UFCON_TX_FIFO_TRG_12 3
153
154/* UMCON register */
155#define UMCON_RTS_BIT (1 << 0)
156#define UMCON_AUTO_FLOW_CTRL_BIT (1 << 4)
157
158/* UTRSTAT register */
159#define UTRSTAT_RXBUF_RDY_BIT (1 << 0)
160#define UTRSTAT_TXBUF_EMPTY_BIT (1 << 1)
161#define UTRSTAT_TX_EMPTY_BIT (1 << 2)
162#if CONFIG_CPU == S5L8702
163#define UTRSTAT_RX_TOUT_INT_BIT (1 << 3) /* Rx timeout INT status */
164#endif
165#define UTRSTAT_RX_INT_BIT (1 << 4)
166#define UTRSTAT_TX_INT_BIT (1 << 5)
167#define UTRSTAT_ERR_INT_BIT (1 << 6)
168#define UTRSTAT_MODEM_INT_BIT (1 << 7) /* modem INT status */
169#if CONFIG_CPU != S5L8700
170#define UTRSTAT_AUTOBR_INT_BIT (1 << 8) /* autobauding INT status */
171#endif
172
173/* UERSTAT register */
174#define UERSTAT_OVERRUN_BIT (1 << 0)
175#define UERSTAT_PARITY_ERR_BIT (1 << 1)
176#define UERSTAT_FRAME_ERR_BIT (1 << 2)
177#define UERSTAT_BREAK_DETECT_BIT (1 << 3)
178
179/* UFSTAT register */
180#define UFSTAT_RX_FIFO_CNT_MASK 0xf
181#define UFSTAT_RX_FIFO_CNT_POS 0
182
183#define UFSTAT_TX_FIFO_CNT_MASK 0xf
184#define UFSTAT_TX_FIFO_CNT_POS 4
185
186#define UFSTAT_RX_FIFO_FULL_BIT (1 << 8)
187#define UFSTAT_TX_FIFO_FULL_BIT (1 << 9)
188#define UFSTAT_RX_FIFO_ERR_BIT (1 << 10) /* clears when reading UERSTAT
189 for the last pending error */
190/* UMSTAT register */
191#define UMSTAT_CTS_ACTIVE_BIT (1 << 0)
192#define UMSTAT_CTS_DELTA_BIT (1 << 4)
193
194
195#if CONFIG_CPU == S5L8702
196/* Bitrate:
197 *
198 * Master UCLK clock is divided by 16 to serialize data, UBRDIV is
199 * used to configure nominal bit width, NBW = (UBRDIV+1)*16 in UCLK
200 * clock ticks.
201 *
202 * Fine tuning works shrining/expanding each individual bit of each
203 * frame. Each bit width can be incremented/decremented by 1/16 of
204 * nominal bit width, it seems UCLK is divided by 17 for expanded
205 * bits and divided by 15 for compressed bits. A whole frame of N
206 * bits can be shrined or expanded up to (NBW * N / 16) UCLK clock
207 * ticks (in 1/16 steps).
208 */
209/* UBRCONx register */
210#define UC_FRAME_MAX_LEN 12 /* 1 start + 8 data + 1 par + 2 stop */
211#define UBRCON_JITTER_MASK 0x3
212#define UBRCON_JITTER_POS(bit) ((bit) << 1) /* 0..UC_FRAME_MAX_LEN-1 */
213
214#define UBRCON_JITTER_NONE 0 /* no jitter for this bit */
215#define UBRCON_JITTER_INC 1 /* increment 1/16 bit width */
216#define UBRCON_JITTER_UNUSED 2 /* does nothing */
217#define UBRCON_JITTER_DEC 3 /* decremet 1/16 bit width */
218#endif /* CONFIG_CPU == S5L8702 */
219
220
221#if CONFIG_CPU != S5L8700
222/* Autobauding:
223 *
224 * Initial UABRSTAT is NOT_INIT, it goes to READY when either of
225 * UCON_AUTOBR bits are enabled for the first time.
226 *
227 * Interrupts are enabled/disabled using UCON_AUTOBR_INT_BIT and
228 * checked using UTRSTAT_AUTOBR_INT_BIT, writing this bit cleans the
229 * interrupt.
230 *
231 * When UCON_AUTOBR_START_BIT is enabled, autobauding starts and the
232 * hardware waits for a low pulse on RX line.
233 *
234 * Once autobauding is started, when a falling edge is detected on
235 * the RX line, UABRSTAT changes to COUNTING status, an internal
236 * counter starts incrementing at UCLK clock frequency. During
237 * COUNTING state, UABRCNT reads as the value of the previous ABR
238 * count, not the value of the current internal count.
239 *
240 * Count finish when a rising edge is detected on the line, at this
241 * moment internal counter stops and it can be read using UABRCNT
242 * register, UABRSTAT goes to READY, AUTOBR_START_BIT is disabled,
243 * and an interrupt is raised if UCON_AUTOBR_INT_BIT is enabled.
244 */
245/* UABRSTAT register */
246#define UABRSTAT_STATUS_MASK 0x3
247#define UABRSTAT_STATUS_POS 0
248
249#define UABRSTAT_STATUS_NOT_INIT 0 /* initial status */
250#define UABRSTAT_STATUS_READY 1 /* machine is ready */
251#define UABRSTAT_STATUS_COUNTING 2 /* count in progress */
252#endif /* CONFIG_CPU != S5L8700 */
253
254
255/*
256 * other HW definitions
257 */
258#define UART_FIFO_SIZE 16
259
260
261/*
262 * structs
263 */
264struct uartc
265{
266 /* static configuration */
267 uint8_t id;
268 uint8_t n_ports;
269 uint16_t port_off;
270 uint32_t baddr;
271 struct uartc_port **port_l;
272};
273
274struct uartc_port
275{
276 /* static configuration */
277 const struct uartc * const uartc;
278 const uint8_t id; /* port number */
279 const uint8_t rx_trg; /* UFCON_RX_FIFO_TRG_xxx */
280 const uint8_t tx_trg; /* UFCON_TX_FIFO_TRG_xxx */
281 const uint8_t clksel; /* UFCON_CLKSEL_xxx */
282 const uint32_t clkhz; /* UCLK (PCLK or ECLK) frequency */
283 void (* const tx_cb) (int len); /* ISRs */
284#if CONFIG_CPU != S5L8700
285 void (* const rx_cb) (int len, char *data, char *err, uint32_t abr_cnt);
286#else
287 void (* const rx_cb) (int len, char *data, char *err);
288#endif
289
290 /* private */
291 uint32_t baddr;
292 uint32_t utrstat_int_mask;
293 uint8_t rx_data[UART_FIFO_SIZE]; /* data buffer for rx_cb */
294 uint8_t rx_err[UART_FIFO_SIZE]; /* error buffer for rx_cb */
295#if CONFIG_CPU != S5L8700
296 bool abr_aborted;
297#endif
298
299#ifdef UC870X_DEBUG
300 uint32_t n_tx_bytes;
301 uint32_t n_rx_bytes;
302 uint32_t n_ovr_err;
303 uint32_t n_parity_err;
304 uint32_t n_frame_err;
305 uint32_t n_break_detect;
306#if CONFIG_CPU != S5L8700
307 /* autobauding */
308 uint32_t n_abnormal0;
309 uint32_t n_abnormal1;
310#endif
311#endif
312};
313
314
315/*
316 * uc870x low level API
317 */
318
319/* Initialization */
320void uartc_open(const struct uartc* uartc);
321void uartc_close(const struct uartc* uartc);
322void uartc_port_open(struct uartc_port *port);
323void uartc_port_close(struct uartc_port *port);
324void uartc_port_rx_onoff(struct uartc_port *port, bool onoff);
325void uartc_port_tx_onoff(struct uartc_port *port, bool onoff);
326
327/* Configuration */
328void uartc_port_config(struct uartc_port *port,
329 uint8_t data_bits, uint8_t parity, uint8_t stop_bits);
330void uartc_port_set_bitrate_raw(struct uartc_port *port, uint32_t brdata);
331void uartc_port_set_bitrate(struct uartc_port *port, unsigned int speed);
332void uartc_port_set_rx_mode(struct uartc_port *port, uint32_t mode);
333void uartc_port_set_tx_mode(struct uartc_port *port, uint32_t mode);
334
335/* Transmit */
336bool uartc_port_tx_ready(struct uartc_port *port);
337void uartc_port_tx_byte(struct uartc_port *port, uint8_t ch);
338void uartc_port_send_byte(struct uartc_port *port, uint8_t ch);
339
340/* Receive */
341bool uartc_port_rx_ready(struct uartc_port *port);
342uint8_t uartc_port_rx_byte(struct uartc_port *port);
343uint8_t uartc_port_read_byte(struct uartc_port *port);
344
345#if CONFIG_CPU != S5L8700
346/* Autobauding */
347void uartc_port_abr_start(struct uartc_port *port);
348void uartc_port_abr_stop(struct uartc_port *port);
349#endif
350
351/* ISR */
352void uartc_callback(const struct uartc *uartc, int port_id);
353
354/* Debug */
355#ifdef UC870X_DEBUG
356void uartc_port_get_line_info(struct uartc_port *port,
357 int *tx_status, int *rx_status,
358 int *tx_speed, int *rx_speed, char *line_cfg);
359
360#if CONFIG_CPU != S5L8700
361enum {
362 ABR_INFO_ST_IDLE,
363 ABR_INFO_ST_LAUNCHED,
364 ABR_INFO_ST_COUNTING,
365 ABR_INFO_ST_ABNORMAL
366};
367
368int uartc_port_get_abr_info(struct uartc_port *port, uint32_t *abr_cnt);
369#endif
370#endif /* UC870X_DEBUG */
371
372#endif /* __UC870X_H__ */