Merge 3.15-rc2 into staging-next
[firefly-linux-kernel-4.4.55.git] / drivers / staging / sbe-2t3e3 / cpld.c
1 /*
2  * SBE 2T3E3 synchronous serial card driver for Linux
3  *
4  * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of version 2 of the GNU General Public License
8  * as published by the Free Software Foundation.
9  *
10  * This code is based on a driver written by SBE Inc.
11  */
12
13 #include <linux/delay.h>
14 #include "2t3e3.h"
15 #include "ctrl.h"
16
17 #define bootrom_set_bit(sc, reg, bit)                           \
18         bootrom_write((sc), (reg),                              \
19                       bootrom_read((sc), (reg)) | (bit))
20
21 #define bootrom_clear_bit(sc, reg, bit)                         \
22         bootrom_write((sc), (reg),                              \
23                       bootrom_read((sc), (reg)) & ~(bit))
24
25 static inline void cpld_set_bit(struct channel *channel, unsigned reg, u32 bit)
26 {
27         unsigned long flags;
28         spin_lock_irqsave(&channel->card->bootrom_lock, flags);
29         bootrom_set_bit(channel, CPLD_MAP_REG(reg, channel), bit);
30         spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
31 }
32
33 static inline void cpld_clear_bit(struct channel *channel,
34                                 unsigned reg, u32 bit)
35 {
36         unsigned long flags;
37         spin_lock_irqsave(&channel->card->bootrom_lock, flags);
38         bootrom_clear_bit(channel, CPLD_MAP_REG(reg, channel), bit);
39         spin_unlock_irqrestore(&channel->card->bootrom_lock, flags);
40 }
41
42 void cpld_init(struct channel *sc)
43 {
44         u32 val;
45
46         /* PCRA */
47         val = SBE_2T3E3_CPLD_VAL_CRC32 |
48                 cpld_val_map[SBE_2T3E3_CPLD_VAL_LOOP_TIMING_SOURCE][sc->h.slot];
49         cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRA, val);
50
51         /* PCRB */
52         val = 0;
53         cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
54
55         /* PCRC */
56         val = 0;
57         cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC, val);
58
59         /* PBWF */
60         val = 0;
61         cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, val);
62
63         /* PBWL */
64         val = 0;
65         cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, val);
66
67         /* PLTR */
68         val = SBE_2T3E3_CPLD_VAL_LCV_COUNTER;
69         cpld_write(sc, SBE_2T3E3_CPLD_REG_PLTR, val);
70         udelay(1000);
71
72         /* PLCR */
73         val = 0;
74         cpld_write(sc, SBE_2T3E3_CPLD_REG_PLCR, val);
75         udelay(1000);
76
77         /* PPFR */
78         val = 0x55;
79         cpld_write(sc, SBE_2T3E3_CPLD_REG_PPFR, val);
80         /* TODO: this doesn't work!!! */
81
82         /* SERIAL_CHIP_SELECT */
83         val = 0;
84         cpld_write(sc, SBE_2T3E3_CPLD_REG_SERIAL_CHIP_SELECT, val);
85
86         /* PICSR */
87         val = SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED |
88                 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED |
89                 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED;
90         cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR, val);
91
92         cpld_start_intr(sc);
93
94         udelay(1000);
95 }
96
97 void cpld_start_intr(struct channel *sc)
98 {
99         u32 val;
100
101         /* PIER */
102         val = SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_ETHERNET_ENABLE |
103                 SBE_2T3E3_CPLD_VAL_INTERRUPT_FROM_FRAMER_ENABLE;
104         cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
105 }
106
107 void cpld_stop_intr(struct channel *sc)
108 {
109         u32 val;
110
111         /* PIER */
112         val = 0;
113         cpld_write(sc, SBE_2T3E3_CPLD_REG_PIER, val);
114 }
115
116 void cpld_set_frame_mode(struct channel *sc, u32 mode)
117 {
118         if (sc->p.frame_mode == mode)
119                 return;
120
121         switch (mode) {
122         case SBE_2T3E3_FRAME_MODE_HDLC:
123                 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
124                                SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE |
125                                SBE_2T3E3_CPLD_VAL_RAW_MODE);
126                 exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF);
127                 exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF);
128                 break;
129         case SBE_2T3E3_FRAME_MODE_TRANSPARENT:
130                 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
131                                SBE_2T3E3_CPLD_VAL_RAW_MODE);
132                 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
133                              SBE_2T3E3_CPLD_VAL_TRANSPARENT_MODE);
134                 exar7250_unipolar_onoff(sc, SBE_2T3E3_OFF);
135                 exar7300_unipolar_onoff(sc, SBE_2T3E3_OFF);
136                 break;
137         case SBE_2T3E3_FRAME_MODE_RAW:
138                 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
139                              SBE_2T3E3_CPLD_VAL_RAW_MODE);
140                 exar7250_unipolar_onoff(sc, SBE_2T3E3_ON);
141                 exar7300_unipolar_onoff(sc, SBE_2T3E3_ON);
142                 break;
143         default:
144                 return;
145         }
146
147         sc->p.frame_mode = mode;
148 }
149
150 /* set rate of the local clock */
151 void cpld_set_frame_type(struct channel *sc, u32 type)
152 {
153         switch (type) {
154         case SBE_2T3E3_FRAME_TYPE_E3_G751:
155         case SBE_2T3E3_FRAME_TYPE_E3_G832:
156                 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
157                              SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3);
158                 break;
159         case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
160         case SBE_2T3E3_FRAME_TYPE_T3_M13:
161                 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
162                                SBE_2T3E3_CPLD_VAL_LOCAL_CLOCK_E3);
163                 break;
164         default:
165                 return;
166         }
167 }
168
169 void cpld_set_scrambler(struct channel *sc, u32 mode)
170 {
171         if (sc->p.scrambler == mode)
172                 return;
173
174         switch (mode) {
175         case SBE_2T3E3_SCRAMBLER_OFF:
176                 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
177                                SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
178                 break;
179         case SBE_2T3E3_SCRAMBLER_LARSCOM:
180                 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
181                                SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE);
182                 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
183                              SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
184                 break;
185         case SBE_2T3E3_SCRAMBLER_ADC_KENTROX_DIGITAL:
186                 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
187                              SBE_2T3E3_CPLD_VAL_SCRAMBLER_TYPE);
188                 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
189                              SBE_2T3E3_CPLD_VAL_SCRAMBLER_ENABLE);
190                 break;
191         default:
192                 return;
193         }
194
195         sc->p.scrambler = mode;
196 }
197
198
199 void cpld_set_crc(struct channel *sc, u32 crc)
200 {
201         if (sc->p.crc == crc)
202                 return;
203
204         switch (crc) {
205         case SBE_2T3E3_CRC_16:
206                 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
207                                SBE_2T3E3_CPLD_VAL_CRC32);
208                 break;
209         case SBE_2T3E3_CRC_32:
210                 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
211                              SBE_2T3E3_CPLD_VAL_CRC32);
212                 break;
213         default:
214                 return;
215         }
216
217         sc->p.crc = crc;
218 }
219
220
221 void cpld_select_panel(struct channel *sc, u32 panel)
222 {
223         if (sc->p.panel == panel)
224                 return;
225         switch (panel) {
226         case SBE_2T3E3_PANEL_FRONT:
227                 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
228                                SBE_2T3E3_CPLD_VAL_REAR_PANEL);
229                 break;
230         case SBE_2T3E3_PANEL_REAR:
231                 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
232                              SBE_2T3E3_CPLD_VAL_REAR_PANEL);
233                 break;
234         default:
235                 return;
236         }
237
238         udelay(100);
239
240         sc->p.panel = panel;
241 }
242
243
244 void cpld_set_clock(struct channel *sc, u32 mode)
245 {
246         if (sc->p.clock_source == mode)
247                 return;
248
249         switch (mode) {
250         case SBE_2T3E3_TIMING_LOCAL:
251                 cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
252                              SBE_2T3E3_CPLD_VAL_ALT);
253                 break;
254         case SBE_2T3E3_TIMING_LOOP:
255                 cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRA,
256                                SBE_2T3E3_CPLD_VAL_ALT);
257                 break;
258         default:
259                 return;
260         }
261
262         sc->p.clock_source = mode;
263 }
264
265 void cpld_set_pad_count(struct channel *sc, u32 count)
266 {
267         u32 val;
268
269         if (sc->p.pad_count == count)
270                 return;
271
272         switch (count) {
273         case SBE_2T3E3_PAD_COUNT_1:
274                 val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_1;
275                 break;
276         case SBE_2T3E3_PAD_COUNT_2:
277                 val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_2;
278                 break;
279         case SBE_2T3E3_PAD_COUNT_3:
280                 val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_3;
281                 break;
282         case SBE_2T3E3_PAD_COUNT_4:
283                 val = SBE_2T3E3_CPLD_VAL_PAD_COUNT_4;
284                 break;
285         default:
286                 return;
287         }
288
289         cpld_clear_bit(sc, SBE_2T3E3_CPLD_REG_PCRB,
290                        SBE_2T3E3_CPLD_VAL_PAD_COUNT);
291         cpld_set_bit(sc, SBE_2T3E3_CPLD_REG_PCRB, val);
292         sc->p.pad_count = count;
293 }
294
295 void cpld_LOS_update(struct channel *sc)
296 {
297         u_int8_t los;
298
299         cpld_write(sc, SBE_2T3E3_CPLD_REG_PICSR,
300                    SBE_2T3E3_CPLD_VAL_DMO_SIGNAL_DETECTED |
301                    SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_LOCK_DETECTED |
302                    SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED);
303         los = cpld_read(sc, SBE_2T3E3_CPLD_REG_PICSR) &
304                 SBE_2T3E3_CPLD_VAL_RECEIVE_LOSS_OF_SIGNAL_DETECTED;
305
306         if (los != sc->s.LOS)
307                 dev_info(&sc->pdev->dev, "SBE 2T3E3: LOS status: %s\n",
308                          los ? "Loss of signal" : "Signal OK");
309         sc->s.LOS = los;
310 }
311
312 void cpld_set_fractional_mode(struct channel *sc, u32 mode,
313                               u32 start, u32 stop)
314 {
315         if (mode == SBE_2T3E3_FRACTIONAL_MODE_NONE) {
316                 start = 0;
317                 stop = 0;
318         }
319
320         if (sc->p.fractional_mode == mode && sc->p.bandwidth_start == start &&
321             sc->p.bandwidth_stop == stop)
322                 return;
323
324         switch (mode) {
325         case SBE_2T3E3_FRACTIONAL_MODE_NONE:
326                 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
327                            SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_NONE);
328                 break;
329         case SBE_2T3E3_FRACTIONAL_MODE_0:
330                 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
331                            SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_0);
332                 break;
333         case SBE_2T3E3_FRACTIONAL_MODE_1:
334                 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
335                            SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_1);
336                 break;
337         case SBE_2T3E3_FRACTIONAL_MODE_2:
338                 cpld_write(sc, SBE_2T3E3_CPLD_REG_PCRC,
339                            SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2);
340                 break;
341         default:
342                 netdev_err(sc->dev, "wrong mode in set_fractional_mode\n");
343                 return;
344         }
345
346         cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWF, start);
347         cpld_write(sc, SBE_2T3E3_CPLD_REG_PBWL, stop);
348
349         sc->p.fractional_mode = mode;
350         sc->p.bandwidth_start = start;
351         sc->p.bandwidth_stop = stop;
352 }