1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Driver for CPM (SCC/SMC) serial ports
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2004 Freescale Semiconductor, Inc.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * 2006 (c) MontaVista Software, Inc.
8*4882a593Smuzhiyun * Vitaly Bordug <vbordug@ru.mvista.com>
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun #ifndef CPM_UART_H
11*4882a593Smuzhiyun #define CPM_UART_H
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include <linux/platform_device.h>
14*4882a593Smuzhiyun #include <linux/fs_uart_pd.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun struct gpio_desc;
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #if defined(CONFIG_CPM2)
19*4882a593Smuzhiyun #include "cpm_uart_cpm2.h"
20*4882a593Smuzhiyun #elif defined(CONFIG_CPM1)
21*4882a593Smuzhiyun #include "cpm_uart_cpm1.h"
22*4882a593Smuzhiyun #endif
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #define SERIAL_CPM_MAJOR 204
25*4882a593Smuzhiyun #define SERIAL_CPM_MINOR 46
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #define IS_SMC(pinfo) (pinfo->flags & FLAG_SMC)
28*4882a593Smuzhiyun #define IS_DISCARDING(pinfo) (pinfo->flags & FLAG_DISCARDING)
29*4882a593Smuzhiyun #define FLAG_DISCARDING 0x00000004 /* when set, don't discard */
30*4882a593Smuzhiyun #define FLAG_SMC 0x00000002
31*4882a593Smuzhiyun #define FLAG_CONSOLE 0x00000001
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #define UART_SMC1 fsid_smc1_uart
34*4882a593Smuzhiyun #define UART_SMC2 fsid_smc2_uart
35*4882a593Smuzhiyun #define UART_SCC1 fsid_scc1_uart
36*4882a593Smuzhiyun #define UART_SCC2 fsid_scc2_uart
37*4882a593Smuzhiyun #define UART_SCC3 fsid_scc3_uart
38*4882a593Smuzhiyun #define UART_SCC4 fsid_scc4_uart
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #define UART_NR fs_uart_nr
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun #define RX_NUM_FIFO 4
43*4882a593Smuzhiyun #define RX_BUF_SIZE 32
44*4882a593Smuzhiyun #define TX_NUM_FIFO 4
45*4882a593Smuzhiyun #define TX_BUF_SIZE 32
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun #define SCC_WAIT_CLOSING 100
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun #define GPIO_CTS 0
50*4882a593Smuzhiyun #define GPIO_RTS 1
51*4882a593Smuzhiyun #define GPIO_DCD 2
52*4882a593Smuzhiyun #define GPIO_DSR 3
53*4882a593Smuzhiyun #define GPIO_DTR 4
54*4882a593Smuzhiyun #define GPIO_RI 5
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun #define NUM_GPIOS (GPIO_RI+1)
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun struct uart_cpm_port {
59*4882a593Smuzhiyun struct uart_port port;
60*4882a593Smuzhiyun u16 rx_nrfifos;
61*4882a593Smuzhiyun u16 rx_fifosize;
62*4882a593Smuzhiyun u16 tx_nrfifos;
63*4882a593Smuzhiyun u16 tx_fifosize;
64*4882a593Smuzhiyun smc_t __iomem *smcp;
65*4882a593Smuzhiyun smc_uart_t __iomem *smcup;
66*4882a593Smuzhiyun scc_t __iomem *sccp;
67*4882a593Smuzhiyun scc_uart_t __iomem *sccup;
68*4882a593Smuzhiyun cbd_t __iomem *rx_bd_base;
69*4882a593Smuzhiyun cbd_t __iomem *rx_cur;
70*4882a593Smuzhiyun cbd_t __iomem *tx_bd_base;
71*4882a593Smuzhiyun cbd_t __iomem *tx_cur;
72*4882a593Smuzhiyun unsigned char *tx_buf;
73*4882a593Smuzhiyun unsigned char *rx_buf;
74*4882a593Smuzhiyun u32 flags;
75*4882a593Smuzhiyun struct clk *clk;
76*4882a593Smuzhiyun u8 brg;
77*4882a593Smuzhiyun uint dp_addr;
78*4882a593Smuzhiyun void *mem_addr;
79*4882a593Smuzhiyun dma_addr_t dma_addr;
80*4882a593Smuzhiyun u32 mem_size;
81*4882a593Smuzhiyun /* wait on close if needed */
82*4882a593Smuzhiyun int wait_closing;
83*4882a593Smuzhiyun /* value to combine with opcode to form cpm command */
84*4882a593Smuzhiyun u32 command;
85*4882a593Smuzhiyun struct gpio_desc *gpios[NUM_GPIOS];
86*4882a593Smuzhiyun };
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun extern int cpm_uart_nr;
89*4882a593Smuzhiyun extern struct uart_cpm_port cpm_uart_ports[UART_NR];
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /* these are located in their respective files */
92*4882a593Smuzhiyun void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd);
93*4882a593Smuzhiyun void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
94*4882a593Smuzhiyun struct device_node *np);
95*4882a593Smuzhiyun void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram);
96*4882a593Smuzhiyun int cpm_uart_init_portdesc(void);
97*4882a593Smuzhiyun int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con);
98*4882a593Smuzhiyun void cpm_uart_freebuf(struct uart_cpm_port *pinfo);
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun void smc1_lineif(struct uart_cpm_port *pinfo);
101*4882a593Smuzhiyun void smc2_lineif(struct uart_cpm_port *pinfo);
102*4882a593Smuzhiyun void scc1_lineif(struct uart_cpm_port *pinfo);
103*4882a593Smuzhiyun void scc2_lineif(struct uart_cpm_port *pinfo);
104*4882a593Smuzhiyun void scc3_lineif(struct uart_cpm_port *pinfo);
105*4882a593Smuzhiyun void scc4_lineif(struct uart_cpm_port *pinfo);
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun /*
108*4882a593Smuzhiyun virtual to phys transtalion
109*4882a593Smuzhiyun */
cpu2cpm_addr(void * addr,struct uart_cpm_port * pinfo)110*4882a593Smuzhiyun static inline unsigned long cpu2cpm_addr(void *addr,
111*4882a593Smuzhiyun struct uart_cpm_port *pinfo)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun int offset;
114*4882a593Smuzhiyun u32 val = (u32)addr;
115*4882a593Smuzhiyun u32 mem = (u32)pinfo->mem_addr;
116*4882a593Smuzhiyun /* sane check */
117*4882a593Smuzhiyun if (likely(val >= mem && val < mem + pinfo->mem_size)) {
118*4882a593Smuzhiyun offset = val - mem;
119*4882a593Smuzhiyun return pinfo->dma_addr + offset;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun /* something nasty happened */
122*4882a593Smuzhiyun BUG();
123*4882a593Smuzhiyun return 0;
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun
cpm2cpu_addr(unsigned long addr,struct uart_cpm_port * pinfo)126*4882a593Smuzhiyun static inline void *cpm2cpu_addr(unsigned long addr,
127*4882a593Smuzhiyun struct uart_cpm_port *pinfo)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun int offset;
130*4882a593Smuzhiyun u32 val = addr;
131*4882a593Smuzhiyun u32 dma = (u32)pinfo->dma_addr;
132*4882a593Smuzhiyun /* sane check */
133*4882a593Smuzhiyun if (likely(val >= dma && val < dma + pinfo->mem_size)) {
134*4882a593Smuzhiyun offset = val - dma;
135*4882a593Smuzhiyun return pinfo->mem_addr + offset;
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun /* something nasty happened */
138*4882a593Smuzhiyun BUG();
139*4882a593Smuzhiyun return NULL;
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun #endif /* CPM_UART_H */
144