Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / gpu / drm / nouveau / nvkm / subdev / pmu / fuc / i2c_.fuc
1 /*
2  * Copyright 2013 Red Hat Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: Ben Skeggs
23  */
24
25 #define T_TIMEOUT  2200000
26 #define T_RISEFALL 1000
27 #define T_HOLD     5000
28
29 #ifdef INCLUDE_PROC
30 process(PROC_I2C_, #i2c_init, #i2c_recv)
31 #endif
32
33 /******************************************************************************
34  * I2C_ data segment
35  *****************************************************************************/
36 #ifdef INCLUDE_DATA
37 i2c_scl_map:
38 .b32 NV_PPWR_OUTPUT_I2C_0_SCL
39 .b32 NV_PPWR_OUTPUT_I2C_1_SCL
40 .b32 NV_PPWR_OUTPUT_I2C_2_SCL
41 .b32 NV_PPWR_OUTPUT_I2C_3_SCL
42 .b32 NV_PPWR_OUTPUT_I2C_4_SCL
43 .b32 NV_PPWR_OUTPUT_I2C_5_SCL
44 .b32 NV_PPWR_OUTPUT_I2C_6_SCL
45 .b32 NV_PPWR_OUTPUT_I2C_7_SCL
46 .b32 NV_PPWR_OUTPUT_I2C_8_SCL
47 .b32 NV_PPWR_OUTPUT_I2C_9_SCL
48 i2c_sda_map:
49 .b32 NV_PPWR_OUTPUT_I2C_0_SDA
50 .b32 NV_PPWR_OUTPUT_I2C_1_SDA
51 .b32 NV_PPWR_OUTPUT_I2C_2_SDA
52 .b32 NV_PPWR_OUTPUT_I2C_3_SDA
53 .b32 NV_PPWR_OUTPUT_I2C_4_SDA
54 .b32 NV_PPWR_OUTPUT_I2C_5_SDA
55 .b32 NV_PPWR_OUTPUT_I2C_6_SDA
56 .b32 NV_PPWR_OUTPUT_I2C_7_SDA
57 .b32 NV_PPWR_OUTPUT_I2C_8_SDA
58 .b32 NV_PPWR_OUTPUT_I2C_9_SDA
59 #if NVKM_PPWR_CHIPSET < GF119
60 i2c_ctrl:
61 .b32 0x00e138
62 .b32 0x00e150
63 .b32 0x00e168
64 .b32 0x00e180
65 .b32 0x00e254
66 .b32 0x00e274
67 .b32 0x00e764
68 .b32 0x00e780
69 .b32 0x00e79c
70 .b32 0x00e7b8
71 #endif
72 #endif
73
74 /******************************************************************************
75  * I2C_ code segment
76  *****************************************************************************/
77 #ifdef INCLUDE_CODE
78
79 // $r3  - value
80 // $r2  - sda line
81 // $r1  - scl line
82 // $r0  - zero
83 i2c_drive_scl:
84         cmp b32 $r3 0
85         bra e #i2c_drive_scl_lo
86         nv_iowr(NV_PPWR_OUTPUT_SET, $r1)
87         ret
88         i2c_drive_scl_lo:
89         nv_iowr(NV_PPWR_OUTPUT_CLR, $r1)
90         ret
91
92 i2c_drive_sda:
93         cmp b32 $r3 0
94         bra e #i2c_drive_sda_lo
95         nv_iowr(NV_PPWR_OUTPUT_SET, $r2)
96         ret
97         i2c_drive_sda_lo:
98         nv_iowr(NV_PPWR_OUTPUT_CLR, $r2)
99         ret
100
101 i2c_sense_scl:
102         bclr $flags $p1
103         nv_iord($r3, NV_PPWR_INPUT)
104         and $r3 $r1
105         bra z #i2c_sense_scl_done
106                 bset $flags $p1
107         i2c_sense_scl_done:
108         ret
109
110 i2c_sense_sda:
111         bclr $flags $p1
112         nv_iord($r3, NV_PPWR_INPUT)
113         and $r3 $r2
114         bra z #i2c_sense_sda_done
115                 bset $flags $p1
116         i2c_sense_sda_done:
117         ret
118
119 #define i2c_drive_scl(v) /*
120 */      mov $r3 (v) /*
121 */      call(i2c_drive_scl)
122 #define i2c_drive_sda(v) /*
123 */      mov $r3 (v) /*
124 */      call(i2c_drive_sda)
125 #define i2c_sense_scl() /*
126 */      call(i2c_sense_scl)
127 #define i2c_sense_sda() /*
128 */      call(i2c_sense_sda)
129 #define i2c_delay(v) /*
130 */      mov $r14 (v) /*
131 */      call(nsec)
132
133 #define i2c_trace_init() /*
134 */      imm32($r6, 0x10000000) /*
135 */      sub b32 $r7 $r6 1 /*
136 */
137 #define i2c_trace_down() /*
138 */      shr b32 $r6 4 /*
139 */      push $r5 /*
140 */      shl b32 $r5 $r6 4 /*
141 */      sub b32 $r5 $r6 /*
142 */      not b32 $r5 /*
143 */      and $r7 $r5 /*
144 */      pop $r5 /*
145 */
146 #define i2c_trace_exit() /*
147 */      shl b32 $r6 4 /*
148 */
149 #define i2c_trace_next() /*
150 */      add b32 $r7 $r6 /*
151 */
152 #define i2c_trace_call(func) /*
153 */      i2c_trace_next() /*
154 */      i2c_trace_down() /*
155 */      call(func) /*
156 */      i2c_trace_exit() /*
157 */
158
159 i2c_raise_scl:
160         push $r4
161         mov $r4 (T_TIMEOUT / T_RISEFALL)
162         i2c_drive_scl(1)
163         i2c_raise_scl_wait:
164                 i2c_delay(T_RISEFALL)
165                 i2c_sense_scl()
166                 bra $p1 #i2c_raise_scl_done
167                 sub b32 $r4 1
168                 bra nz #i2c_raise_scl_wait
169         i2c_raise_scl_done:
170         pop $r4
171         ret
172
173 i2c_start:
174         i2c_sense_scl()
175         bra not $p1 #i2c_start_rep
176         i2c_sense_sda()
177         bra not $p1 #i2c_start_rep
178         bra #i2c_start_send
179         i2c_start_rep:
180                 i2c_drive_scl(0)
181                 i2c_drive_sda(1)
182                 i2c_trace_call(i2c_raise_scl)
183                 bra not $p1 #i2c_start_out
184         i2c_start_send:
185         i2c_drive_sda(0)
186         i2c_delay(T_HOLD)
187         i2c_drive_scl(0)
188         i2c_delay(T_HOLD)
189         i2c_start_out:
190         ret
191
192 i2c_stop:
193         i2c_drive_scl(0)
194         i2c_drive_sda(0)
195         i2c_delay(T_RISEFALL)
196         i2c_drive_scl(1)
197         i2c_delay(T_HOLD)
198         i2c_drive_sda(1)
199         i2c_delay(T_HOLD)
200         ret
201
202 // $r3  - value
203 // $r2  - sda line
204 // $r1  - scl line
205 // $r0  - zero
206 i2c_bitw:
207         call(i2c_drive_sda)
208         i2c_delay(T_RISEFALL)
209         i2c_trace_call(i2c_raise_scl)
210         bra not $p1 #i2c_bitw_out
211         i2c_delay(T_HOLD)
212         i2c_drive_scl(0)
213         i2c_delay(T_HOLD)
214         i2c_bitw_out:
215         ret
216
217 // $r3  - value (out)
218 // $r2  - sda line
219 // $r1  - scl line
220 // $r0  - zero
221 i2c_bitr:
222         i2c_drive_sda(1)
223         i2c_delay(T_RISEFALL)
224         i2c_trace_call(i2c_raise_scl)
225         bra not $p1 #i2c_bitr_done
226         i2c_sense_sda()
227         i2c_drive_scl(0)
228         i2c_delay(T_HOLD)
229         xbit $r3 $flags $p1
230         bset $flags $p1
231         i2c_bitr_done:
232         ret
233
234 i2c_get_byte:
235         mov $r5 0
236         mov $r4 8
237         i2c_get_byte_next:
238                 shl b32 $r5 1
239                 i2c_trace_call(i2c_bitr)
240                 bra not $p1 #i2c_get_byte_done
241                 or $r5 $r3
242                 sub b32 $r4 1
243                 bra nz #i2c_get_byte_next
244         mov $r3 1
245         i2c_trace_call(i2c_bitw)
246         i2c_get_byte_done:
247         ret
248
249 i2c_put_byte:
250         mov $r4 8
251         i2c_put_byte_next:
252                 sub b32 $r4 1
253                 xbit $r3 $r5 $r4
254                 i2c_trace_call(i2c_bitw)
255                 bra not $p1 #i2c_put_byte_done
256                 cmp b32 $r4 0
257                 bra ne #i2c_put_byte_next
258         i2c_trace_call(i2c_bitr)
259         bra not $p1 #i2c_put_byte_done
260         i2c_trace_next()
261         cmp b32 $r3 1
262         bra ne #i2c_put_byte_done
263         bclr $flags $p1 // nack
264         i2c_put_byte_done:
265         ret
266
267 i2c_addr:
268         i2c_trace_call(i2c_start)
269         bra not $p1 #i2c_addr_done
270         extr $r3 $r12 I2C__MSG_DATA0_ADDR
271         shl b32 $r3 1
272         or $r5 $r3
273         i2c_trace_call(i2c_put_byte)
274         i2c_addr_done:
275         ret
276
277 i2c_acquire_addr:
278         extr $r14 $r12 I2C__MSG_DATA0_PORT
279 #if NVKM_PPWR_CHIPSET < GF119
280         shl b32 $r14 2
281         add b32 $r14 #i2c_ctrl
282         ld b32 $r14 D[$r14]
283 #else
284         shl b32 $r14 5
285         add b32 $r14 0x00d014
286 #endif
287         ret
288
289 i2c_acquire:
290         call(i2c_acquire_addr)
291         call(rd32)
292         bset $r13 3
293         call(wr32)
294         ret
295
296 i2c_release:
297         call(i2c_acquire_addr)
298         call(rd32)
299         bclr $r13 3
300         call(wr32)
301         ret
302
303 // description
304 //
305 // $r15 - current (i2c)
306 // $r14 - sender process name
307 // $r13 - message
308 // $r12 - data0
309 // $r11 - data1
310 // $r0  - zero
311 i2c_recv:
312         bclr $flags $p1
313         extr $r1 $r12 I2C__MSG_DATA0_PORT
314         shl b32 $r1 2
315         cmp b32 $r1 (#i2c_sda_map - #i2c_scl_map)
316         bra ge #i2c_recv_done
317         add b32 $r3 $r1 #i2c_sda_map
318         ld b32 $r2 D[$r3]
319         add b32 $r3 $r1 #i2c_scl_map
320         ld b32 $r1 D[$r3]
321
322         bset $flags $p2
323         push $r13
324         push $r14
325
326         push $r13
327         i2c_trace_init()
328         i2c_trace_call(i2c_acquire)
329         pop $r13
330
331         cmp b32 $r13 I2C__MSG_RD08
332         bra ne #i2c_recv_not_rd08
333                 mov $r5 0
334                 i2c_trace_call(i2c_addr)
335                 bra not $p1 #i2c_recv_done
336                 extr $r5 $r12 I2C__MSG_DATA0_RD08_REG
337                 i2c_trace_call(i2c_put_byte)
338                 bra not $p1 #i2c_recv_done
339                 mov $r5 1
340                 i2c_trace_call(i2c_addr)
341                 bra not $p1 #i2c_recv_done
342                 i2c_trace_call(i2c_get_byte)
343                 bra not $p1 #i2c_recv_done
344                 ins $r11 $r5 I2C__MSG_DATA1_RD08_VAL
345                 i2c_trace_call(i2c_stop)
346                 mov b32 $r11 $r5
347                 clear b32 $r7
348                 bra #i2c_recv_done
349
350         i2c_recv_not_rd08:
351         cmp b32 $r13 I2C__MSG_WR08
352         bra ne #i2c_recv_not_wr08
353                 mov $r5 0
354                 call(i2c_addr)
355                 bra not $p1 #i2c_recv_done
356                 extr $r5 $r12 I2C__MSG_DATA0_WR08_REG
357                 call(i2c_put_byte)
358                 bra not $p1 #i2c_recv_done
359                 mov $r5 0
360                 call(i2c_addr)
361                 bra not $p1 #i2c_recv_done
362                 extr $r5 $r11 I2C__MSG_DATA1_WR08_VAL
363                 call(i2c_put_byte)
364                 bra not $p1 #i2c_recv_done
365                 call(i2c_stop)
366                 clear b32 $r7
367                 extr $r5 $r12 I2C__MSG_DATA0_WR08_SYNC
368                 bra nz #i2c_recv_done
369                 bclr $flags $p2
370                 bra #i2c_recv_done
371
372         i2c_recv_not_wr08:
373
374         i2c_recv_done:
375         extr $r14 $r12 I2C__MSG_DATA0_PORT
376         call(i2c_release)
377
378         pop $r14
379         pop $r13
380         bra not $p2 #i2c_recv_exit
381         mov b32 $r12 $r7
382         call(send)
383
384         i2c_recv_exit:
385         ret
386
387 // description
388 //
389 // $r15 - current (i2c)
390 // $r0  - zero
391 i2c_init:
392         ret
393 #endif