Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 7 kB image not shown  

Quelle  i2c_.fuc   Sprache: unbekannt

 
/*
 * Copyright 2013 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: Ben Skeggs
 */

#define T_TIMEOUT  2200000
#define T_RISEFALL 1000
#define T_HOLD     5000

#ifdef INCLUDE_PROC
process(PROC_I2C_, #i2c_init, #i2c_recv)
#endif

/******************************************************************************
 * I2C_ data segment
 *****************************************************************************/
#ifdef INCLUDE_DATA
i2c_scl_map:
.b32 NV_PPWR_OUTPUT_I2C_0_SCL
.b32 NV_PPWR_OUTPUT_I2C_1_SCL
.b32 NV_PPWR_OUTPUT_I2C_2_SCL
.b32 NV_PPWR_OUTPUT_I2C_3_SCL
.b32 NV_PPWR_OUTPUT_I2C_4_SCL
.b32 NV_PPWR_OUTPUT_I2C_5_SCL
.b32 NV_PPWR_OUTPUT_I2C_6_SCL
.b32 NV_PPWR_OUTPUT_I2C_7_SCL
.b32 NV_PPWR_OUTPUT_I2C_8_SCL
.b32 NV_PPWR_OUTPUT_I2C_9_SCL
i2c_sda_map:
.b32 NV_PPWR_OUTPUT_I2C_0_SDA
.b32 NV_PPWR_OUTPUT_I2C_1_SDA
.b32 NV_PPWR_OUTPUT_I2C_2_SDA
.b32 NV_PPWR_OUTPUT_I2C_3_SDA
.b32 NV_PPWR_OUTPUT_I2C_4_SDA
.b32 NV_PPWR_OUTPUT_I2C_5_SDA
.b32 NV_PPWR_OUTPUT_I2C_6_SDA
.b32 NV_PPWR_OUTPUT_I2C_7_SDA
.b32 NV_PPWR_OUTPUT_I2C_8_SDA
.b32 NV_PPWR_OUTPUT_I2C_9_SDA
#if NVKM_PPWR_CHIPSET < GF119
i2c_ctrl:
.b32 0x00e138
.b32 0x00e150
.b32 0x00e168
.b32 0x00e180
.b32 0x00e254
.b32 0x00e274
.b32 0x00e764
.b32 0x00e780
.b32 0x00e79c
.b32 0x00e7b8
#endif
#endif

/******************************************************************************
 * I2C_ code segment
 *****************************************************************************/
#ifdef INCLUDE_CODE

// $r3  - value
// $r2  - sda line
// $r1  - scl line
// $r0  - zero
i2c_drive_scl:
 cmp b32 $r3 0
 bra e #i2c_drive_scl_lo
 nv_iowr(NV_PPWR_OUTPUT_SET, $r1)
 ret
 i2c_drive_scl_lo:
 nv_iowr(NV_PPWR_OUTPUT_CLR, $r1)
 ret

i2c_drive_sda:
 cmp b32 $r3 0
 bra e #i2c_drive_sda_lo
 nv_iowr(NV_PPWR_OUTPUT_SET, $r2)
 ret
 i2c_drive_sda_lo:
 nv_iowr(NV_PPWR_OUTPUT_CLR, $r2)
 ret

i2c_sense_scl:
 bclr $flags $p1
 nv_iord($r3, NV_PPWR_INPUT)
 and $r3 $r1
 bra z #i2c_sense_scl_done
  bset $flags $p1
 i2c_sense_scl_done:
 ret

i2c_sense_sda:
 bclr $flags $p1
 nv_iord($r3, NV_PPWR_INPUT)
 and $r3 $r2
 bra z #i2c_sense_sda_done
  bset $flags $p1
 i2c_sense_sda_done:
 ret

#define i2c_drive_scl(v) /*
*/ mov $r3 (v) /*
*/ call(i2c_drive_scl)
#define i2c_drive_sda(v) /*
*/ mov $r3 (v) /*
*/ call(i2c_drive_sda)
#define i2c_sense_scl() /*
*/ call(i2c_sense_scl)
#define i2c_sense_sda() /*
*/ call(i2c_sense_sda)
#define i2c_delay(v) /*
*/ mov $r14 (v) /*
*/ call(nsec)

#define i2c_trace_init() /*
*/ imm32($r6, 0x10000000) /*
*/ sub b32 $r7 $r6 1 /*
*/
#define i2c_trace_down() /*
*/ shr b32 $r6 4 /*
*/ push $r5 /*
*/ shl b32 $r5 $r6 4 /*
*/ sub b32 $r5 $r6 /*
*/ not b32 $r5 /*
*/ and $r7 $r5 /*
*/ pop $r5 /*
*/
#define i2c_trace_exit() /*
*/ shl b32 $r6 4 /*
*/
#define i2c_trace_next() /*
*/ add b32 $r7 $r6 /*
*/
#define i2c_trace_call(func) /*
*/ i2c_trace_next() /*
*/ i2c_trace_down() /*
*/ call(func) /*
*/ i2c_trace_exit() /*
*/

i2c_raise_scl:
 push $r4
 mov $r4 (T_TIMEOUT / T_RISEFALL)
 i2c_drive_scl(1)
 i2c_raise_scl_wait:
  i2c_delay(T_RISEFALL)
  i2c_sense_scl()
  bra $p1 #i2c_raise_scl_done
  sub b32 $r4 1
  bra nz #i2c_raise_scl_wait
 i2c_raise_scl_done:
 pop $r4
 ret

i2c_start:
 i2c_sense_scl()
 bra not $p1 #i2c_start_rep
 i2c_sense_sda()
 bra not $p1 #i2c_start_rep
 bra #i2c_start_send
 i2c_start_rep:
  i2c_drive_scl(0)
  i2c_drive_sda(1)
  i2c_trace_call(i2c_raise_scl)
  bra not $p1 #i2c_start_out
 i2c_start_send:
 i2c_drive_sda(0)
 i2c_delay(T_HOLD)
 i2c_drive_scl(0)
 i2c_delay(T_HOLD)
 i2c_start_out:
 ret

i2c_stop:
 i2c_drive_scl(0)
 i2c_drive_sda(0)
 i2c_delay(T_RISEFALL)
 i2c_drive_scl(1)
 i2c_delay(T_HOLD)
 i2c_drive_sda(1)
 i2c_delay(T_HOLD)
 ret

// $r3  - value
// $r2  - sda line
// $r1  - scl line
// $r0  - zero
i2c_bitw:
 call(i2c_drive_sda)
 i2c_delay(T_RISEFALL)
 i2c_trace_call(i2c_raise_scl)
 bra not $p1 #i2c_bitw_out
 i2c_delay(T_HOLD)
 i2c_drive_scl(0)
 i2c_delay(T_HOLD)
 i2c_bitw_out:
 ret

// $r3  - value (out)
// $r2  - sda line
// $r1  - scl line
// $r0  - zero
i2c_bitr:
 i2c_drive_sda(1)
 i2c_delay(T_RISEFALL)
 i2c_trace_call(i2c_raise_scl)
 bra not $p1 #i2c_bitr_done
 i2c_sense_sda()
 i2c_drive_scl(0)
 i2c_delay(T_HOLD)
 xbit $r3 $flags $p1
 bset $flags $p1
 i2c_bitr_done:
 ret

i2c_get_byte:
 mov $r5 0
 mov $r4 8
 i2c_get_byte_next:
  shl b32 $r5 1
  i2c_trace_call(i2c_bitr)
  bra not $p1 #i2c_get_byte_done
  or $r5 $r3
  sub b32 $r4 1
  bra nz #i2c_get_byte_next
 mov $r3 1
 i2c_trace_call(i2c_bitw)
 i2c_get_byte_done:
 ret

i2c_put_byte:
 mov $r4 8
 i2c_put_byte_next:
  sub b32 $r4 1
  xbit $r3 $r5 $r4
  i2c_trace_call(i2c_bitw)
  bra not $p1 #i2c_put_byte_done
  cmp b32 $r4 0
  bra ne #i2c_put_byte_next
 i2c_trace_call(i2c_bitr)
 bra not $p1 #i2c_put_byte_done
 i2c_trace_next()
 cmp b32 $r3 1
 bra ne #i2c_put_byte_done
 bclr $flags $p1 // nack
 i2c_put_byte_done:
 ret

i2c_addr:
 i2c_trace_call(i2c_start)
 bra not $p1 #i2c_addr_done
 extr $r3 $r12 I2C__MSG_DATA0_ADDR
 shl b32 $r3 1
 or $r5 $r3
 i2c_trace_call(i2c_put_byte)
 i2c_addr_done:
 ret

i2c_acquire_addr:
 extr $r14 $r12 I2C__MSG_DATA0_PORT
#if NVKM_PPWR_CHIPSET < GF119
 shl b32 $r14 2
 add b32 $r14 #i2c_ctrl
 ld b32 $r14 D[$r14]
#else
 shl b32 $r14 5
 add b32 $r14 0x00d014
#endif
 ret

i2c_acquire:
 call(i2c_acquire_addr)
 call(rd32)
 bset $r13 3
 call(wr32)
 ret

i2c_release:
 call(i2c_acquire_addr)
 call(rd32)
 bclr $r13 3
 call(wr32)
 ret

// description
//
// $r15 - current (i2c)
// $r14 - sender process name
// $r13 - message
// $r12 - data0
// $r11 - data1
// $r0  - zero
i2c_recv:
 bclr $flags $p1
 extr $r1 $r12 I2C__MSG_DATA0_PORT
 shl b32 $r1 2
 cmp b32 $r1 (#i2c_sda_map - #i2c_scl_map)
 bra ge #i2c_recv_done
 add b32 $r3 $r1 #i2c_sda_map
 ld b32 $r2 D[$r3]
 add b32 $r3 $r1 #i2c_scl_map
 ld b32 $r1 D[$r3]

 bset $flags $p2
 push $r13
 push $r14

 push $r13
 i2c_trace_init()
 i2c_trace_call(i2c_acquire)
 pop $r13

 cmp b32 $r13 I2C__MSG_RD08
 bra ne #i2c_recv_not_rd08
  mov $r5 0
  i2c_trace_call(i2c_addr)
  bra not $p1 #i2c_recv_done
  extr $r5 $r12 I2C__MSG_DATA0_RD08_REG
  i2c_trace_call(i2c_put_byte)
  bra not $p1 #i2c_recv_done
  mov $r5 1
  i2c_trace_call(i2c_addr)
  bra not $p1 #i2c_recv_done
  i2c_trace_call(i2c_get_byte)
  bra not $p1 #i2c_recv_done
  ins $r11 $r5 I2C__MSG_DATA1_RD08_VAL
  i2c_trace_call(i2c_stop)
  mov b32 $r11 $r5
  clear b32 $r7
  bra #i2c_recv_done

 i2c_recv_not_rd08:
 cmp b32 $r13 I2C__MSG_WR08
 bra ne #i2c_recv_not_wr08
  mov $r5 0
  call(i2c_addr)
  bra not $p1 #i2c_recv_done
  extr $r5 $r12 I2C__MSG_DATA0_WR08_REG
  call(i2c_put_byte)
  bra not $p1 #i2c_recv_done
  mov $r5 0
  call(i2c_addr)
  bra not $p1 #i2c_recv_done
  extr $r5 $r11 I2C__MSG_DATA1_WR08_VAL
  call(i2c_put_byte)
  bra not $p1 #i2c_recv_done
  call(i2c_stop)
  clear b32 $r7
  extr $r5 $r12 I2C__MSG_DATA0_WR08_SYNC
  bra nz #i2c_recv_done
  bclr $flags $p2
  bra #i2c_recv_done

 i2c_recv_not_wr08:

 i2c_recv_done:
 extr $r14 $r12 I2C__MSG_DATA0_PORT
 call(i2c_release)

 pop $r14
 pop $r13
 bra not $p2 #i2c_recv_exit
 mov b32 $r12 $r7
 call(send)

 i2c_recv_exit:
 ret

// description
//
// $r15 - current (i2c)
// $r0  - zero
i2c_init:
 ret
#endif

[ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ]