1
2
3
4
5#include <dm/platform_data/serial_sh.h>
6
7struct uart_port {
8 unsigned long iobase;
9 unsigned char *membase;
10 unsigned long mapbase;
11 enum sh_serial_type type;
12 enum sh_clk_mode clk_mode;
13};
14
15#if defined(CONFIG_CPU_SH7721) || \
16 defined(CONFIG_SH73A0) || \
17 defined(CONFIG_R8A7740)
18# define SCSCR_INIT(port) 0x0030
19# define PORT_PTCR 0xA405011EUL
20# define PORT_PVCR 0xA4050122UL
21# define SCIF_ORER 0x0200
22#elif defined(CONFIG_CPU_SH7750) || \
23 defined(CONFIG_CPU_SH7750R) || \
24 defined(CONFIG_CPU_SH7750S) || \
25 defined(CONFIG_CPU_SH7751) || \
26 defined(CONFIG_CPU_SH7751R)
27# define SCSPTR1 0xffe0001c
28# define SCSPTR2 0xFFE80020
29# define SCIF_ORER 0x0001
30# define SCSCR_INIT(port) (((port)->type == PORT_SCI) ? \
31 0x30 : \
32 0x38 )
33#elif defined(CONFIG_CPU_SH7722)
34# define PADR 0xA4050120
35# undef PSDR
36# define PSDR 0xA405013e
37# define PWDR 0xA4050166
38# define PSCR 0xA405011E
39# define SCIF_ORER 0x0001
40# define SCSCR_INIT(port) 0x0038
41#elif defined(CONFIG_CPU_SH7723)
42# define SCSPTR0 0xa4050160
43# define SCSPTR1 0xa405013e
44# define SCSPTR2 0xa4050160
45# define SCSPTR3 0xa405013e
46# define SCSPTR4 0xa4050128
47# define SCSPTR5 0xa4050128
48# define SCIF_ORER 0x0001
49# define SCSCR_INIT(port) 0x0038
50#elif defined(CONFIG_CPU_SH7734)
51# define SCSPTR0 0xFFE40020
52# define SCSPTR1 0xFFE41020
53# define SCSPTR2 0xFFE42020
54# define SCSPTR3 0xFFE43020
55# define SCSPTR4 0xFFE44020
56# define SCSPTR5 0xFFE45020
57# define SCIF_ORER 0x0001
58# define SCSCR_INIT(port) 0x0038
59#elif defined(CONFIG_CPU_SH7757) || \
60 defined(CONFIG_CPU_SH7752) || \
61 defined(CONFIG_CPU_SH7753)
62# define SCSPTR0 0xfe4b0020
63# define SCSPTR1 0xfe4b0020
64# define SCSPTR2 0xfe4b0020
65# define SCIF_ORER 0x0001
66# define SCSCR_INIT(port) 0x38
67# define SCIF_ONLY
68#elif defined(CONFIG_CPU_SH7763)
69# define SCSPTR0 0xffe00024
70# define SCSPTR1 0xffe08024
71# define SCSPTR2 0xffe10020
72# define SCIF_ORER 0x0001
73# define SCSCR_INIT(port) 0x38
74#elif defined(CONFIG_CPU_SH7780)
75# define SCSPTR0 0xffe00024
76# define SCSPTR1 0xffe10024
77# define SCIF_ORER 0x0001
78
79
80# define SCSCR_INIT(port) 0x3a
81
82#elif defined(CONFIG_RZA1)
83# define SCSPTR0 0xe8007020
84# define SCSPTR1 0xe8007820
85# define SCSPTR2 0xe8008020
86# define SCSPTR3 0xe8008820
87# define SCSPTR4 0xe8009020
88# define SCSPTR5 0xe8009820
89# define SCSPTR6 0xe800a020
90# define SCSPTR7 0xe800a820
91# define SCSCR_INIT(port) 0x38
92# define SCIF_ORER 0x0001
93#elif defined(CONFIG_RCAR_GEN2) || defined(CONFIG_RCAR_GEN3) || \
94 defined(CONFIG_R7S72100)
95# if defined(CONFIG_SCIF_A)
96# define SCIF_ORER 0x0200
97# else
98# define SCIF_ORER 0x0001
99# endif
100# define SCSCR_INIT(port) (port->clk_mode == EXT_CLK ? 0x32 : 0x30)
101
102#else
103# error CPU subtype not defined
104#endif
105
106
107#define SCI_CTRL_FLAGS_TIE 0x80
108#define SCI_CTRL_FLAGS_RIE 0x40
109#define SCI_CTRL_FLAGS_TE 0x20
110#define SCI_CTRL_FLAGS_RE 0x10
111#if defined(CONFIG_CPU_SH7750) || \
112 defined(CONFIG_CPU_SH7750R) || \
113 defined(CONFIG_CPU_SH7722) || \
114 defined(CONFIG_CPU_SH7734) || \
115 defined(CONFIG_CPU_SH7750S) || \
116 defined(CONFIG_CPU_SH7751) || \
117 defined(CONFIG_CPU_SH7751R) || \
118 defined(CONFIG_CPU_SH7763) || \
119 defined(CONFIG_CPU_SH7780)
120#define SCI_CTRL_FLAGS_REIE 0x08
121#else
122#define SCI_CTRL_FLAGS_REIE 0
123#endif
124
125
126
127
128
129
130#define SCI_TDRE 0x80
131#define SCI_RDRF 0x40
132#define SCI_ORER 0x20
133#define SCI_FER 0x10
134#define SCI_PER 0x08
135#define SCI_TEND 0x04
136
137
138
139#define SCI_ERRORS ( SCI_PER | SCI_FER | SCI_ORER)
140
141
142#define SCIF_ER 0x0080
143#define SCIF_TEND 0x0040
144#define SCIF_TDFE 0x0020
145#define SCIF_BRK 0x0010
146#define SCIF_FER 0x0008
147#define SCIF_PER 0x0004
148#define SCIF_RDF 0x0002
149#define SCIF_DR 0x0001
150
151#if defined(CONFIG_CPU_SH7721) || \
152 defined(CONFIG_SH73A0) || \
153 defined(CONFIG_R8A7740)
154# define SCIF_ORER 0x0200
155# define SCIF_ERRORS (SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
156# define SCIF_RFDC_MASK 0x007f
157# define SCIF_TXROOM_MAX 64
158#elif defined(CONFIG_CPU_SH7763)
159# define SCIF_ERRORS (SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
160# define SCIF_RFDC_MASK 0x007f
161# define SCIF_TXROOM_MAX 64
162
163# define SCIF2_RFDC_MASK 0x001f
164# define SCIF2_TXROOM_MAX 16
165#elif defined(CONFIG_RCAR_GEN2)
166# define SCIF_ERRORS (SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
167# if defined(CONFIG_SCIF_A)
168# define SCIF_RFDC_MASK 0x007f
169# else
170# define SCIF_RFDC_MASK 0x001f
171# endif
172#else
173# define SCIF_ERRORS (SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
174# define SCIF_RFDC_MASK 0x001f
175# define SCIF_TXROOM_MAX 16
176#endif
177
178#ifndef SCIF_ORER
179#define SCIF_ORER 0x0000
180#endif
181
182#define SCxSR_TEND(port)\
183 (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND)
184#define SCxSR_ERRORS(port)\
185 (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS)
186#define SCxSR_RDxF(port)\
187 (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF)
188#define SCxSR_TDxE(port)\
189 (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE)
190#define SCxSR_FER(port)\
191 (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER)
192#define SCxSR_PER(port)\
193 (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER)
194#define SCxSR_BRK(port)\
195 ((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK)
196#define SCxSR_ORER(port)\
197 (((port)->type == PORT_SCI) ? SCI_ORER : SCIF_ORER)
198
199#if defined(CONFIG_CPU_SH7721) || \
200 defined(CONFIG_SH73A0) || \
201 defined(CONFIG_R8A7740)
202# define SCxSR_RDxF_CLEAR(port) (sci_in(port, SCxSR) & 0xfffc)
203# define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73)
204# define SCxSR_TDxE_CLEAR(port) (sci_in(port, SCxSR) & 0xffdf)
205# define SCxSR_BREAK_CLEAR(port) (sci_in(port, SCxSR) & 0xffe3)
206#else
207# define SCxSR_RDxF_CLEAR(port) (((port)->type == PORT_SCI) ? 0xbc : 0x00fc)
208# define SCxSR_ERROR_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x0073)
209# define SCxSR_TDxE_CLEAR(port) (((port)->type == PORT_SCI) ? 0x78 : 0x00df)
210# define SCxSR_BREAK_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x00e3)
211#endif
212
213
214#define SCFCR_RFRST 0x0002
215#define SCFCR_TFRST 0x0004
216#define SCFCR_TCRST 0x4000
217#define SCFCR_MCE 0x0008
218
219#define SCI_MAJOR 204
220#define SCI_MINOR_START 8
221
222
223#define SCI_RX_THROTTLE 0x0000001
224
225#define SCI_MAGIC 0xbabeface
226
227
228
229
230
231#define SCI_EVENT_WRITE_WAKEUP 0
232
233#define SCI_IN(size, offset)\
234 if ((size) == 8) {\
235 return readb(port->membase + (offset));\
236 } else {\
237 return readw(port->membase + (offset));\
238 }
239#define SCI_OUT(size, offset, value)\
240 if ((size) == 8) {\
241 writeb(value, port->membase + (offset));\
242 } else if ((size) == 16) {\
243 writew(value, port->membase + (offset));\
244 }
245
246#define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
247 static inline unsigned int sci_##name##_in(struct uart_port *port) {\
248 if (port->type == PORT_SCIF || port->type == PORT_SCIFB) {\
249 SCI_IN(scif_size, scif_offset)\
250 } else { \
251 SCI_IN(sci_size, sci_offset);\
252 }\
253 }\
254static inline void sci_##name##_out(struct uart_port *port,\
255 unsigned int value) {\
256 if (port->type == PORT_SCIF || port->type == PORT_SCIFB) {\
257 SCI_OUT(scif_size, scif_offset, value)\
258 } else { \
259 SCI_OUT(sci_size, sci_offset, value);\
260 }\
261}
262
263#define CPU_SCIF_FNS(name, scif_offset, scif_size) \
264 static inline unsigned int sci_##name##_in(struct uart_port *port) {\
265 SCI_IN(scif_size, scif_offset);\
266 }\
267 static inline void sci_##name##_out(struct uart_port *port,\
268 unsigned int value) {\
269 SCI_OUT(scif_size, scif_offset, value);\
270 }
271
272#define CPU_SCI_FNS(name, sci_offset, sci_size)\
273 static inline unsigned int sci_##name##_in(struct uart_port *port) {\
274 SCI_IN(sci_size, sci_offset);\
275 }\
276 static inline void sci_##name##_out(struct uart_port *port,\
277 unsigned int value) {\
278 SCI_OUT(sci_size, sci_offset, value);\
279 }
280
281#if defined(CONFIG_SH73A0) || \
282 defined(CONFIG_R8A7740)
283#if defined(CONFIG_CPU_SH7721) || \
284 defined(CONFIG_SH73A0)
285#define SCIF_FNS(name, scif_offset, scif_size) \
286 CPU_SCIF_FNS(name, scif_offset, scif_size)
287#elif defined(CONFIG_R8A7740)
288#define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size,\
289 sh4_scifb_offset, sh4_scifb_size) \
290 CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size,\
291 sh4_scifb_offset, sh4_scifb_size)
292#define SCIF_FNS(name, scif_offset, scif_size) \
293 CPU_SCIF_FNS(name, scif_offset, scif_size)
294#else
295#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size,\
296 sh4_sci_offset, sh4_sci_size, \
297 sh3_scif_offset, sh3_scif_size,\
298 sh4_scif_offset, sh4_scif_size, \
299 h8_sci_offset, h8_sci_size) \
300 CPU_SCIx_FNS(name, sh3_sci_offset, sh3_sci_size,\
301 sh3_scif_offset, sh3_scif_size)
302#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size,\
303 sh4_scif_offset, sh4_scif_size) \
304 CPU_SCIF_FNS(name, sh3_scif_offset, sh3_scif_size)
305#endif
306#elif defined(CONFIG_CPU_SH7723)
307 #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size,\
308 sh4_scif_offset, sh4_scif_size) \
309 CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size,\
310 sh4_scif_offset, sh4_scif_size)
311 #define SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) \
312 CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
313#else
314#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size,\
315 sh4_sci_offset, sh4_sci_size, \
316 sh3_scif_offset, sh3_scif_size,\
317 sh4_scif_offset, sh4_scif_size, \
318 h8_sci_offset, h8_sci_size) \
319 CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size,\
320 sh4_scif_offset, sh4_scif_size)
321#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, \
322 sh4_scif_offset, sh4_scif_size) \
323 CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
324#endif
325
326#if defined(CONFIG_CPU_SH7721) || \
327 defined(CONFIG_SH73A0)
328
329SCIF_FNS(SCSMR, 0x00, 16)
330SCIF_FNS(SCBRR, 0x04, 8)
331SCIF_FNS(SCSCR, 0x08, 16)
332SCIF_FNS(SCTDSR, 0x0c, 8)
333SCIF_FNS(SCFER, 0x10, 16)
334SCIF_FNS(SCxSR, 0x14, 16)
335SCIF_FNS(SCFCR, 0x18, 16)
336SCIF_FNS(SCFDR, 0x1c, 16)
337SCIF_FNS(SCxTDR, 0x20, 8)
338SCIF_FNS(SCxRDR, 0x24, 8)
339SCIF_FNS(SCLSR, 0x00, 0)
340SCIF_FNS(DL, 0x00, 0)
341#elif defined(CONFIG_R8A7740)
342SCIF_FNS(SCSMR, 0x00, 16)
343SCIF_FNS(SCBRR, 0x04, 8)
344SCIF_FNS(SCSCR, 0x08, 16)
345SCIF_FNS(SCTDSR, 0x0c, 16)
346SCIF_FNS(SCFER, 0x10, 16)
347SCIF_FNS(SCxSR, 0x14, 16)
348SCIF_FNS(SCFCR, 0x18, 16)
349SCIF_FNS(SCFDR, 0x1c, 16)
350SCIF_FNS(SCTFDR, 0x38, 16)
351SCIF_FNS(SCRFDR, 0x3c, 16)
352SCIx_FNS(SCxTDR, 0x20, 8, 0x40, 8)
353SCIx_FNS(SCxRDR, 0x24, 8, 0x60, 8)
354SCIF_FNS(SCLSR, 0x00, 0)
355SCIF_FNS(DL, 0x00, 0)
356#elif defined(CONFIG_CPU_SH7723)
357SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16)
358SCIx_FNS(SCBRR, 0x04, 8, 0x04, 8)
359SCIx_FNS(SCSCR, 0x08, 16, 0x08, 16)
360SCIx_FNS(SCxTDR, 0x20, 8, 0x0c, 8)
361SCIx_FNS(SCxSR, 0x14, 16, 0x10, 16)
362SCIx_FNS(SCxRDR, 0x24, 8, 0x14, 8)
363SCIx_FNS(SCSPTR, 0, 0, 0, 0)
364SCIF_FNS(SCTDSR, 0x0c, 8)
365SCIF_FNS(SCFER, 0x10, 16)
366SCIF_FNS(SCFCR, 0x18, 16)
367SCIF_FNS(SCFDR, 0x1c, 16)
368SCIF_FNS(SCLSR, 0x24, 16)
369SCIF_FNS(DL, 0x00, 0)
370#elif defined(CONFIG_RCAR_GEN2)
371
372SCIx_FNS(SCSMR, 0, 0, 0x00, 16, 0, 0, 0x00, 16, 0, 0)
373SCIx_FNS(SCBRR, 0, 0, 0x04, 8, 0, 0, 0x04, 8, 0, 0)
374SCIx_FNS(SCSCR, 0, 0, 0x08, 16, 0, 0, 0x08, 16, 0, 0)
375SCIx_FNS(SCxTDR, 0, 0, 0x20, 8, 0, 0, 0x0C, 8, 0, 0)
376SCIx_FNS(SCxSR, 0, 0, 0x14, 16, 0, 0, 0x10, 16, 0, 0)
377SCIx_FNS(SCxRDR, 0, 0, 0x24, 8, 0, 0, 0x14, 8, 0, 0)
378SCIF_FNS(SCFCR, 0, 0, 0x18, 16)
379SCIF_FNS(SCFDR, 0, 0, 0x1C, 16)
380SCIF_FNS(SCSPTR, 0, 0, 0x20, 16)
381SCIF_FNS(DL, 0, 0, 0x30, 16)
382SCIF_FNS(CKS, 0, 0, 0x34, 16)
383#if defined(CONFIG_SCIF_A)
384SCIF_FNS(SCLSR, 0, 0, 0x14, 16)
385#else
386SCIF_FNS(SCLSR, 0, 0, 0x24, 16)
387#endif
388#else
389
390
391SCIx_FNS(SCSMR, 0x00, 8, 0x00, 8, 0x00, 8, 0x00, 16, 0x00, 8)
392SCIx_FNS(SCBRR, 0x02, 8, 0x04, 8, 0x02, 8, 0x04, 8, 0x01, 8)
393SCIx_FNS(SCSCR, 0x04, 8, 0x08, 8, 0x04, 8, 0x08, 16, 0x02, 8)
394SCIx_FNS(SCxTDR, 0x06, 8, 0x0c, 8, 0x06, 8, 0x0C, 8, 0x03, 8)
395SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8)
396SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8)
397SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
398#if defined(CONFIG_CPU_SH7780)
399SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
400SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
401SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
402SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
403SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
404#elif defined(CONFIG_CPU_SH7763)
405SCIF_FNS(SCFDR, 0, 0, 0x1C, 16)
406SCIF_FNS(SCSPTR2, 0, 0, 0x20, 16)
407SCIF_FNS(SCLSR2, 0, 0, 0x24, 16)
408SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
409SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
410SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
411SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
412#else
413
414SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
415#if defined(CONFIG_CPU_SH7722)
416SCIF_FNS(SCSPTR, 0, 0, 0, 0)
417#else
418SCIF_FNS(SCSPTR, 0, 0, 0x20, 16)
419#endif
420SCIF_FNS(SCLSR, 0, 0, 0x24, 16)
421#endif
422SCIF_FNS(DL, 0, 0, 0x0, 0)
423#endif
424#define sci_in(port, reg) sci_##reg##_in(port)
425#define sci_out(port, reg, value) sci_##reg##_out(port, value)
426
427#if defined(CONFIG_CPU_SH7750) || \
428 defined(CONFIG_CPU_SH7751) || \
429 defined(CONFIG_CPU_SH7751R) || \
430 defined(CONFIG_CPU_SH7750R) || \
431 defined(CONFIG_CPU_SH7750S)
432static inline int sci_rxd_in(struct uart_port *port)
433{
434 if (port->mapbase == 0xffe00000)
435 return __raw_readb(SCSPTR1)&0x01 ? 1 : 0;
436 return 1;
437}
438#else
439static inline int sci_rxd_in(struct uart_port *port)
440{
441 return 1;
442}
443#endif
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477#if defined(CONFIG_CPU_SH7780)
478#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1)
479#elif defined(CONFIG_CPU_SH7721) || \
480 defined(CONFIG_SH73A0) || \
481 defined(CONFIG_R8A7740)
482#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1)
483#elif defined(CONFIG_CPU_SH7723)
484static inline int scbrr_calc(struct uart_port *port, int bps, int clk)
485{
486 if (port->type == PORT_SCIF)
487 return (clk+16*bps)/(32*bps)-1;
488 else
489 return ((clk*2)+16*bps)/(16*bps)-1;
490}
491#define SCBRR_VALUE(bps, clk) scbrr_calc(port, bps, clk)
492#elif defined(CONFIG_RCAR_GEN2)
493#define DL_VALUE(bps, clk) (clk / bps / 16)
494 #if defined(CONFIG_SCIF_A)
495 #define SCBRR_VALUE(bps, clk) (clk / bps / 16 - 1)
496 #else
497 #define SCBRR_VALUE(bps, clk) (clk / bps / 32 - 1)
498 #endif
499#else
500#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1)
501#endif
502
503#ifndef DL_VALUE
504#define DL_VALUE(bps, clk) 0
505#endif
506