xref: /OK3568_Linux_fs/kernel/drivers/net/can/c_can/c_can.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * CAN bus driver for Bosch C_CAN controller
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (C) 2010 ST Microelectronics
5*4882a593Smuzhiyun  * Bhupesh Sharma <bhupesh.sharma@st.com>
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Borrowed heavily from the C_CAN driver originally written by:
8*4882a593Smuzhiyun  * Copyright (C) 2007
9*4882a593Smuzhiyun  * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de>
10*4882a593Smuzhiyun  * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch>
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B.
13*4882a593Smuzhiyun  * Bosch C_CAN user manual can be obtained from:
14*4882a593Smuzhiyun  * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/
15*4882a593Smuzhiyun  * users_manual_c_can.pdf
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  * This file is licensed under the terms of the GNU General Public
18*4882a593Smuzhiyun  * License version 2. This program is licensed "as is" without any
19*4882a593Smuzhiyun  * warranty of any kind, whether express or implied.
20*4882a593Smuzhiyun  */
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #ifndef C_CAN_H
23*4882a593Smuzhiyun #define C_CAN_H
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun /* message object split */
26*4882a593Smuzhiyun #define C_CAN_NO_OF_OBJECTS	32
27*4882a593Smuzhiyun #define C_CAN_MSG_OBJ_RX_NUM	16
28*4882a593Smuzhiyun #define C_CAN_MSG_OBJ_TX_NUM	16
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define C_CAN_MSG_OBJ_RX_FIRST	1
31*4882a593Smuzhiyun #define C_CAN_MSG_OBJ_RX_LAST	(C_CAN_MSG_OBJ_RX_FIRST + \
32*4882a593Smuzhiyun 				C_CAN_MSG_OBJ_RX_NUM - 1)
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #define C_CAN_MSG_OBJ_TX_FIRST	(C_CAN_MSG_OBJ_RX_LAST + 1)
35*4882a593Smuzhiyun #define C_CAN_MSG_OBJ_TX_LAST	(C_CAN_MSG_OBJ_TX_FIRST + \
36*4882a593Smuzhiyun 				C_CAN_MSG_OBJ_TX_NUM - 1)
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #define C_CAN_MSG_OBJ_RX_SPLIT	9
39*4882a593Smuzhiyun #define C_CAN_MSG_RX_LOW_LAST	(C_CAN_MSG_OBJ_RX_SPLIT - 1)
40*4882a593Smuzhiyun #define RECEIVE_OBJECT_BITS	0x0000ffff
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun enum reg {
43*4882a593Smuzhiyun 	C_CAN_CTRL_REG = 0,
44*4882a593Smuzhiyun 	C_CAN_CTRL_EX_REG,
45*4882a593Smuzhiyun 	C_CAN_STS_REG,
46*4882a593Smuzhiyun 	C_CAN_ERR_CNT_REG,
47*4882a593Smuzhiyun 	C_CAN_BTR_REG,
48*4882a593Smuzhiyun 	C_CAN_INT_REG,
49*4882a593Smuzhiyun 	C_CAN_TEST_REG,
50*4882a593Smuzhiyun 	C_CAN_BRPEXT_REG,
51*4882a593Smuzhiyun 	C_CAN_IF1_COMREQ_REG,
52*4882a593Smuzhiyun 	C_CAN_IF1_COMMSK_REG,
53*4882a593Smuzhiyun 	C_CAN_IF1_MASK1_REG,
54*4882a593Smuzhiyun 	C_CAN_IF1_MASK2_REG,
55*4882a593Smuzhiyun 	C_CAN_IF1_ARB1_REG,
56*4882a593Smuzhiyun 	C_CAN_IF1_ARB2_REG,
57*4882a593Smuzhiyun 	C_CAN_IF1_MSGCTRL_REG,
58*4882a593Smuzhiyun 	C_CAN_IF1_DATA1_REG,
59*4882a593Smuzhiyun 	C_CAN_IF1_DATA2_REG,
60*4882a593Smuzhiyun 	C_CAN_IF1_DATA3_REG,
61*4882a593Smuzhiyun 	C_CAN_IF1_DATA4_REG,
62*4882a593Smuzhiyun 	C_CAN_IF2_COMREQ_REG,
63*4882a593Smuzhiyun 	C_CAN_IF2_COMMSK_REG,
64*4882a593Smuzhiyun 	C_CAN_IF2_MASK1_REG,
65*4882a593Smuzhiyun 	C_CAN_IF2_MASK2_REG,
66*4882a593Smuzhiyun 	C_CAN_IF2_ARB1_REG,
67*4882a593Smuzhiyun 	C_CAN_IF2_ARB2_REG,
68*4882a593Smuzhiyun 	C_CAN_IF2_MSGCTRL_REG,
69*4882a593Smuzhiyun 	C_CAN_IF2_DATA1_REG,
70*4882a593Smuzhiyun 	C_CAN_IF2_DATA2_REG,
71*4882a593Smuzhiyun 	C_CAN_IF2_DATA3_REG,
72*4882a593Smuzhiyun 	C_CAN_IF2_DATA4_REG,
73*4882a593Smuzhiyun 	C_CAN_TXRQST1_REG,
74*4882a593Smuzhiyun 	C_CAN_TXRQST2_REG,
75*4882a593Smuzhiyun 	C_CAN_NEWDAT1_REG,
76*4882a593Smuzhiyun 	C_CAN_NEWDAT2_REG,
77*4882a593Smuzhiyun 	C_CAN_INTPND1_REG,
78*4882a593Smuzhiyun 	C_CAN_INTPND2_REG,
79*4882a593Smuzhiyun 	C_CAN_MSGVAL1_REG,
80*4882a593Smuzhiyun 	C_CAN_MSGVAL2_REG,
81*4882a593Smuzhiyun 	C_CAN_FUNCTION_REG,
82*4882a593Smuzhiyun };
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun static const u16 __maybe_unused reg_map_c_can[] = {
85*4882a593Smuzhiyun 	[C_CAN_CTRL_REG]	= 0x00,
86*4882a593Smuzhiyun 	[C_CAN_STS_REG]		= 0x02,
87*4882a593Smuzhiyun 	[C_CAN_ERR_CNT_REG]	= 0x04,
88*4882a593Smuzhiyun 	[C_CAN_BTR_REG]		= 0x06,
89*4882a593Smuzhiyun 	[C_CAN_INT_REG]		= 0x08,
90*4882a593Smuzhiyun 	[C_CAN_TEST_REG]	= 0x0A,
91*4882a593Smuzhiyun 	[C_CAN_BRPEXT_REG]	= 0x0C,
92*4882a593Smuzhiyun 	[C_CAN_IF1_COMREQ_REG]	= 0x10,
93*4882a593Smuzhiyun 	[C_CAN_IF1_COMMSK_REG]	= 0x12,
94*4882a593Smuzhiyun 	[C_CAN_IF1_MASK1_REG]	= 0x14,
95*4882a593Smuzhiyun 	[C_CAN_IF1_MASK2_REG]	= 0x16,
96*4882a593Smuzhiyun 	[C_CAN_IF1_ARB1_REG]	= 0x18,
97*4882a593Smuzhiyun 	[C_CAN_IF1_ARB2_REG]	= 0x1A,
98*4882a593Smuzhiyun 	[C_CAN_IF1_MSGCTRL_REG]	= 0x1C,
99*4882a593Smuzhiyun 	[C_CAN_IF1_DATA1_REG]	= 0x1E,
100*4882a593Smuzhiyun 	[C_CAN_IF1_DATA2_REG]	= 0x20,
101*4882a593Smuzhiyun 	[C_CAN_IF1_DATA3_REG]	= 0x22,
102*4882a593Smuzhiyun 	[C_CAN_IF1_DATA4_REG]	= 0x24,
103*4882a593Smuzhiyun 	[C_CAN_IF2_COMREQ_REG]	= 0x40,
104*4882a593Smuzhiyun 	[C_CAN_IF2_COMMSK_REG]	= 0x42,
105*4882a593Smuzhiyun 	[C_CAN_IF2_MASK1_REG]	= 0x44,
106*4882a593Smuzhiyun 	[C_CAN_IF2_MASK2_REG]	= 0x46,
107*4882a593Smuzhiyun 	[C_CAN_IF2_ARB1_REG]	= 0x48,
108*4882a593Smuzhiyun 	[C_CAN_IF2_ARB2_REG]	= 0x4A,
109*4882a593Smuzhiyun 	[C_CAN_IF2_MSGCTRL_REG]	= 0x4C,
110*4882a593Smuzhiyun 	[C_CAN_IF2_DATA1_REG]	= 0x4E,
111*4882a593Smuzhiyun 	[C_CAN_IF2_DATA2_REG]	= 0x50,
112*4882a593Smuzhiyun 	[C_CAN_IF2_DATA3_REG]	= 0x52,
113*4882a593Smuzhiyun 	[C_CAN_IF2_DATA4_REG]	= 0x54,
114*4882a593Smuzhiyun 	[C_CAN_TXRQST1_REG]	= 0x80,
115*4882a593Smuzhiyun 	[C_CAN_TXRQST2_REG]	= 0x82,
116*4882a593Smuzhiyun 	[C_CAN_NEWDAT1_REG]	= 0x90,
117*4882a593Smuzhiyun 	[C_CAN_NEWDAT2_REG]	= 0x92,
118*4882a593Smuzhiyun 	[C_CAN_INTPND1_REG]	= 0xA0,
119*4882a593Smuzhiyun 	[C_CAN_INTPND2_REG]	= 0xA2,
120*4882a593Smuzhiyun 	[C_CAN_MSGVAL1_REG]	= 0xB0,
121*4882a593Smuzhiyun 	[C_CAN_MSGVAL2_REG]	= 0xB2,
122*4882a593Smuzhiyun };
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun static const u16 __maybe_unused reg_map_d_can[] = {
125*4882a593Smuzhiyun 	[C_CAN_CTRL_REG]	= 0x00,
126*4882a593Smuzhiyun 	[C_CAN_CTRL_EX_REG]	= 0x02,
127*4882a593Smuzhiyun 	[C_CAN_STS_REG]		= 0x04,
128*4882a593Smuzhiyun 	[C_CAN_ERR_CNT_REG]	= 0x08,
129*4882a593Smuzhiyun 	[C_CAN_BTR_REG]		= 0x0C,
130*4882a593Smuzhiyun 	[C_CAN_BRPEXT_REG]	= 0x0E,
131*4882a593Smuzhiyun 	[C_CAN_INT_REG]		= 0x10,
132*4882a593Smuzhiyun 	[C_CAN_TEST_REG]	= 0x14,
133*4882a593Smuzhiyun 	[C_CAN_FUNCTION_REG]	= 0x18,
134*4882a593Smuzhiyun 	[C_CAN_TXRQST1_REG]	= 0x88,
135*4882a593Smuzhiyun 	[C_CAN_TXRQST2_REG]	= 0x8A,
136*4882a593Smuzhiyun 	[C_CAN_NEWDAT1_REG]	= 0x9C,
137*4882a593Smuzhiyun 	[C_CAN_NEWDAT2_REG]	= 0x9E,
138*4882a593Smuzhiyun 	[C_CAN_INTPND1_REG]	= 0xB0,
139*4882a593Smuzhiyun 	[C_CAN_INTPND2_REG]	= 0xB2,
140*4882a593Smuzhiyun 	[C_CAN_MSGVAL1_REG]	= 0xC4,
141*4882a593Smuzhiyun 	[C_CAN_MSGVAL2_REG]	= 0xC6,
142*4882a593Smuzhiyun 	[C_CAN_IF1_COMREQ_REG]	= 0x100,
143*4882a593Smuzhiyun 	[C_CAN_IF1_COMMSK_REG]	= 0x102,
144*4882a593Smuzhiyun 	[C_CAN_IF1_MASK1_REG]	= 0x104,
145*4882a593Smuzhiyun 	[C_CAN_IF1_MASK2_REG]	= 0x106,
146*4882a593Smuzhiyun 	[C_CAN_IF1_ARB1_REG]	= 0x108,
147*4882a593Smuzhiyun 	[C_CAN_IF1_ARB2_REG]	= 0x10A,
148*4882a593Smuzhiyun 	[C_CAN_IF1_MSGCTRL_REG]	= 0x10C,
149*4882a593Smuzhiyun 	[C_CAN_IF1_DATA1_REG]	= 0x110,
150*4882a593Smuzhiyun 	[C_CAN_IF1_DATA2_REG]	= 0x112,
151*4882a593Smuzhiyun 	[C_CAN_IF1_DATA3_REG]	= 0x114,
152*4882a593Smuzhiyun 	[C_CAN_IF1_DATA4_REG]	= 0x116,
153*4882a593Smuzhiyun 	[C_CAN_IF2_COMREQ_REG]	= 0x120,
154*4882a593Smuzhiyun 	[C_CAN_IF2_COMMSK_REG]	= 0x122,
155*4882a593Smuzhiyun 	[C_CAN_IF2_MASK1_REG]	= 0x124,
156*4882a593Smuzhiyun 	[C_CAN_IF2_MASK2_REG]	= 0x126,
157*4882a593Smuzhiyun 	[C_CAN_IF2_ARB1_REG]	= 0x128,
158*4882a593Smuzhiyun 	[C_CAN_IF2_ARB2_REG]	= 0x12A,
159*4882a593Smuzhiyun 	[C_CAN_IF2_MSGCTRL_REG]	= 0x12C,
160*4882a593Smuzhiyun 	[C_CAN_IF2_DATA1_REG]	= 0x130,
161*4882a593Smuzhiyun 	[C_CAN_IF2_DATA2_REG]	= 0x132,
162*4882a593Smuzhiyun 	[C_CAN_IF2_DATA3_REG]	= 0x134,
163*4882a593Smuzhiyun 	[C_CAN_IF2_DATA4_REG]	= 0x136,
164*4882a593Smuzhiyun };
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun enum c_can_dev_id {
167*4882a593Smuzhiyun 	BOSCH_C_CAN_PLATFORM,
168*4882a593Smuzhiyun 	BOSCH_C_CAN,
169*4882a593Smuzhiyun 	BOSCH_D_CAN,
170*4882a593Smuzhiyun };
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun struct raminit_bits {
173*4882a593Smuzhiyun 	u8 start;
174*4882a593Smuzhiyun 	u8 done;
175*4882a593Smuzhiyun };
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun struct c_can_driver_data {
178*4882a593Smuzhiyun 	enum c_can_dev_id id;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	/* RAMINIT register description. Optional. */
181*4882a593Smuzhiyun 	const struct raminit_bits *raminit_bits; /* Array of START/DONE bit positions */
182*4882a593Smuzhiyun 	u8 raminit_num;		/* Number of CAN instances on the SoC */
183*4882a593Smuzhiyun 	bool raminit_pulse;	/* If set, sets and clears START bit (pulse) */
184*4882a593Smuzhiyun };
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun /* Out of band RAMINIT register access via syscon regmap */
187*4882a593Smuzhiyun struct c_can_raminit {
188*4882a593Smuzhiyun 	struct regmap *syscon;	/* for raminit ctrl. reg. access */
189*4882a593Smuzhiyun 	unsigned int reg;	/* register index within syscon */
190*4882a593Smuzhiyun 	struct raminit_bits bits;
191*4882a593Smuzhiyun 	bool needs_pulse;
192*4882a593Smuzhiyun };
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun /* c_can private data structure */
195*4882a593Smuzhiyun struct c_can_priv {
196*4882a593Smuzhiyun 	struct can_priv can;	/* must be the first member */
197*4882a593Smuzhiyun 	struct napi_struct napi;
198*4882a593Smuzhiyun 	struct net_device *dev;
199*4882a593Smuzhiyun 	struct device *device;
200*4882a593Smuzhiyun 	atomic_t tx_active;
201*4882a593Smuzhiyun 	atomic_t sie_pending;
202*4882a593Smuzhiyun 	unsigned long tx_dir;
203*4882a593Smuzhiyun 	int last_status;
204*4882a593Smuzhiyun 	u16 (*read_reg) (const struct c_can_priv *priv, enum reg index);
205*4882a593Smuzhiyun 	void (*write_reg) (const struct c_can_priv *priv, enum reg index, u16 val);
206*4882a593Smuzhiyun 	u32 (*read_reg32) (const struct c_can_priv *priv, enum reg index);
207*4882a593Smuzhiyun 	void (*write_reg32) (const struct c_can_priv *priv, enum reg index, u32 val);
208*4882a593Smuzhiyun 	void __iomem *base;
209*4882a593Smuzhiyun 	const u16 *regs;
210*4882a593Smuzhiyun 	void *priv;		/* for board-specific data */
211*4882a593Smuzhiyun 	enum c_can_dev_id type;
212*4882a593Smuzhiyun 	struct c_can_raminit raminit_sys;	/* RAMINIT via syscon regmap */
213*4882a593Smuzhiyun 	void (*raminit) (const struct c_can_priv *priv, bool enable);
214*4882a593Smuzhiyun 	u32 comm_rcv_high;
215*4882a593Smuzhiyun 	u32 rxmasked;
216*4882a593Smuzhiyun 	u32 dlc[C_CAN_MSG_OBJ_TX_NUM];
217*4882a593Smuzhiyun };
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun struct net_device *alloc_c_can_dev(void);
220*4882a593Smuzhiyun void free_c_can_dev(struct net_device *dev);
221*4882a593Smuzhiyun int register_c_can_dev(struct net_device *dev);
222*4882a593Smuzhiyun void unregister_c_can_dev(struct net_device *dev);
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun #ifdef CONFIG_PM
225*4882a593Smuzhiyun int c_can_power_up(struct net_device *dev);
226*4882a593Smuzhiyun int c_can_power_down(struct net_device *dev);
227*4882a593Smuzhiyun #endif
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun #endif /* C_CAN_H */
230