1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2018-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #ifndef _ROM_NVSWITCH_H_
25 #define _ROM_NVSWITCH_H_
26 
27 #include "pmgr_nvswitch.h"
28 #include "io_nvswitch.h"
29 
30 //
31 // When parsing BIOS tables these wrappers help protect against reading and using
32 // fields that may not be present in the ROM image by checking the offset against
33 // the structure size.
34 //
35 #define NV_OFFSETOF_MEMBER(_basePtr, _member)                                  \
36     ((NvUPtr)(((NvU8 *)(&((_basePtr)->_member))) - ((NvU8 *)(_basePtr))))
37 
38 #define NVSWITCH_ELEMENT_PRESENT(_ptr, _element, _size)          \
39     (NV_OFFSETOF_MEMBER((_ptr), _element) + sizeof((_ptr)->_element) <= (_size))
40 
41 #define NVSWITCH_ELEMENT_READ(_ptr, _element, _size, _default)   \
42     (NVSWITCH_ELEMENT_PRESENT(_ptr, _element, _size) ?           \
43         ((_ptr)->_element) : (_default))
44 
45 #define NVSWITCH_ELEMENT_VALIDATE(_ptr, _element, _size, _default, _expected)   \
46     do                                                                          \
47     {                                                                           \
48         NvU32 data = NVSWITCH_ELEMENT_READ(_ptr, _element, _size, _default);    \
49         if (data != (_expected))                                                \
50         {                                                                       \
51             NVSWITCH_PRINT(device, SETUP,                                       \
52                 "Element '%s->%s'=0x%x but expected 0x%x\n",                    \
53                 #_ptr, #_element, data, (NvU32) (_expected));                   \
54         }                                                                       \
55     } while(0)
56 
57 #define NVSWITCH_ELEMENT_CHECK(_ptr, _element, _size, _default)                 \
58     NVSWITCH_ELEMENT_VALIDATE(_ptr, _element, _size, _default, _default)
59 
60 #define NVSWITCH_STRUCT_PACKED_ALIGNED(typeName, bytes)                        \
61     typedef struct __attribute__((packed, aligned(bytes)))
62 
63 #define NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
64 
65 //
66 // AT24CM02 EEPROM
67 // https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8828-SEEPROM-AT24CM02-Datasheet.pdf
68 //
69 
70 #define AT24CM02_INDEX_SIZE     18          // Addressing bits
71 #define AT24CM02_BLOCK_SIZE     256         // R/W block size (bytes)
72 
73 //
74 // AT24C02C EEPROM
75 // https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8700-SEEPROM-AT24C01C-02C-Datasheet.pdf
76 //
77 
78 #define AT24C02C_INDEX_SIZE     8           // Addressing bits
79 #define AT24C02C_BLOCK_SIZE     8           // R/W block size (bytes)
80 
81 //
82 // AT24C02D EEPROM
83 // https://ww1.microchip.com/downloads/en/devicedoc/atmel-8871f-seeprom-at24c01d-02d-datasheet.pdf
84 // 2kb EEPROM used on LR10 P4790 B00 platform
85 //
86 
87 #define AT24C02D_INDEX_SIZE     8           // Addressing bits
88 #define AT24C02D_BLOCK_SIZE     8           // R/W block size (bytes)
89 
90 typedef struct
91 {
92     NvU32 i2c_port;
93     NvU32 i2c_address;
94     NvU32 device_type;
95     NvU32 index_size;
96     NvU32 block_size;
97     NvU32 block_count;
98     NvU32 eeprom_size;
99 } NVSWITCH_EEPROM_TYPE;
100 
101 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_EEPROM_HEADER, 1)
102 {
103     char    signature[4];
104     NvU16   version;
105     NvU16   header_size;
106     NvU16   pci_vendor_id;
107     NvU16   pci_device_id;
108     NvU16   pci_system_vendor_id;
109     NvU16   pci_system_device_id;
110     NvU16   firmware_size;
111     NvU8    reserved[13];
112     NvU8    checksum;
113 } NVSWITCH_EEPROM_HEADER;
114 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
115 
116 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_BIT_HEADER, 1)
117 {
118     NvU16   id;
119     char    signature[4];
120     NvU16   bcd_version;
121     NvU8    header_size;
122     NvU8    token_size;
123     NvU8    token_entries;
124     NvU8    checksum;
125 } NVSWITCH_BIT_HEADER;
126 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
127 
128 #define NVSWITCH_BIT_TOKEN_CLOCK_PTRS                0x43
129 #define NVSWITCH_BIT_TOKEN_NVINIT_PTRS               0x49
130 #define NVSWITCH_BIT_TOKEN_NOP                       0x4E
131 #define NVSWITCH_BIT_TOKEN_PERF_PTRS                 0x50
132 #define NVSWITCH_BIT_TOKEN_BRIDGE_FW_DATA            0x52
133 #define NVSWITCH_BIT_TOKEN_DCB_PTRS                  0x6E
134 
135 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_BIT_TOKEN, 1)
136 {
137     NvU8    id;
138     NvU8    data_version;
139     NvU16   data_size;
140     NvU16   data_offset;
141 } NVSWITCH_BIT_TOKEN;
142 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
143 
144 // 0x43: BIT_TOKEN_CLOCK_PTRS
145 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_BIT_CLOCK_PTRS, 1)
146 {
147     NvU32 pll_info_table;
148     NvU32 vbe_mode_pclk;
149     NvU32 clocks_table;
150     NvU32 clocks_programming;
151     NvU32 nafll;
152     NvU32 adc_table;
153     NvU32 freq_control;
154 } NVSWITCH_BIT_CLOCK_PTRS;
155 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
156 
157 #define NVSWITCH_CLOCK_PTRS_PLL_INFO_VERSION    0x50
158 
159 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_PLL_INFO_HEADER, 1)
160 {
161     NvU8  version;
162     NvU8  header_size;
163     NvU8  entry_size;
164     NvU8  entry_count;
165 } NVSWITCH_PLL_INFO_HEADER;
166 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
167 
168 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_PLL_INFO_ENTRY, 1)
169 {
170     NvU8  pll_id;
171     NvU16 ref_min_mhz;
172     NvU16 ref_max_mhz;
173     NvU16 vco_min_mhz;
174     NvU16 vco_max_mhz;
175     NvU16 update_min_mhz;
176     NvU16 update_max_mhz;
177     NvU8  m_min;
178     NvU8  m_max;
179     NvU8  n_min;
180     NvU8  n_max;
181     NvU8  pl_min;
182     NvU8  pl_max;
183 } NVSWITCH_PLL_INFO_ENTRY;
184 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
185 
186 #define NVSWITCH_PLL_ID_SYSPLL      0x07
187 
188 // 0x49: BIT_TOKEN_NVINIT_PTRS
189 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_BIT_NVINIT_PTRS, 1)
190 {
191     NvU16 init_script;
192     NvU16 macro_index;
193     NvU16 macro_table;
194     NvU16 condition;
195     NvU16 io_condition;
196     NvU16 io_flag_condition;
197     NvU16 init_function;
198     NvU16 private_boot;
199     NvU16 data_arrays;
200     NvU16 pcie_settings;
201     NvU16 devinit;
202     NvU16 devinit_size;
203     NvU16 boot_script;
204     NvU16 boot_script_size;
205     NvU16 nvlink_config;
206     NvU16 boot_script_nonGC6;
207     NvU16 boot_script_nonGC6_size;
208 } NVSWITCH_BIT_NVINIT_PTRS;
209 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
210 
211 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_NVLINK_CONFIG, 1)
212 {
213     NvU8    version;
214     NvU8    size;
215     NvU16   reserved;
216     NvU64   link_disable_mask;      // 1 = disable
217     NvU64   link_speed_mask;        // 1 = safe mode
218     NvU64   link_refclk_mask;       // 0 = 100MHz, 1 = 133MHz
219     NvU8    flags;
220     NvU64   ac_coupled_mask;        // 0 = DC, 1 = AC
221 } NVSWITCH_NVLINK_CONFIG;
222 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
223 
224 // 0x52: BIT_TOKEN_BRIDGE_FW_DATA
225 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_BIT_BRIDGE_FW_DATA, 1)
226 {
227     NvU32 firmware_version;
228     NvU8  oem_version;
229     NvU16 firmware_size;
230     char  BIOS_MOD_date[8];
231     NvU32 firmware_flags;
232     NvU16 eng_product_name;
233     NvU8  eng_product_name_size;
234     NvU16 nvswitch_instance_id;
235 } NVSWITCH_BIT_BRIDGE_FW_DATA;
236 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
237 
238 #define NVSWITCH_BIT_BRIDGE_FW_DATA_FLAGS_BUILD               0:0
239 #define NVSWITCH_BIT_BRIDGE_FW_DATA_FLAGS_BUILD_REL           0
240 #define NVSWITCH_BIT_BRIDGE_FW_DATA_FLAGS_BUILD_ENG           1
241 #define NVSWITCH_BIT_BRIDGE_FW_DATA_FLAGS_I2C                 1:1
242 #define NVSWITCH_BIT_BRIDGE_FW_DATA_FLAGS_I2C_MASTER          0
243 #define NVSWITCH_BIT_BRIDGE_FW_DATA_FLAGS_I2C_NOT_MASTER      1
244 
245 // 0x6E: BIT_TOKEN_DCB_PTRS
246 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_BIT_DCB_PTRS, 1)
247 {
248     NvU16 dcb_header_ptr;
249 } NVSWITCH_BIT_DCB_PTRS;
250 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
251 
252 #define NVSWITCH_DCB_HEADER_VERSION_41  0x41
253 #define NVSWITCH_DCB_HEADER_SIGNATURE   0x4edcbdcb
254 
255 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_DCB_HEADER, 1)
256 {
257     NvU8  version;
258     NvU8  header_size;
259     NvU8  entry_count;
260     NvU8  entry_size;
261     NvU16 ccb_block_ptr;
262     NvU32 dcb_signature;
263     NvU16 gpio_table;
264     NvU16 input_devices;
265     NvU16 personal_cinema;
266     NvU16 spread_spectrum;
267     NvU16 i2c_devices;
268     NvU16 connectors;
269     NvU8  flags;
270     NvU16 hdtv;
271     NvU16 switched_outputs;
272     NvU32 display_patch;
273     NvU32 connector_patch;
274 } NVSWITCH_DCB_HEADER;
275 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
276 
277 #define NVSWITCH_GPIO_TABLE_VERSION_42  0x42
278 
279 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_GPIO_TABLE, 1)
280 {
281     NvU8    version;
282     NvU8    header_size;
283     NvU8    entry_count;
284     NvU8    entry_size;
285     NvU16   ext_gpio_master;
286 } NVSWITCH_GPIO_TABLE;
287 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
288 
289 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_GPIO_ENTRY, 1)
290 {
291     NvU8    pin;
292     NvU8    function;
293     NvU8    output;
294     NvU8    input;
295     NvU8    misc;
296 } NVSWITCH_GPIO_ENTRY;
297 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
298 
299 #define NVSWITCH_GPIO_ENTRY_PIN_NUM                   5:0
300 #define NVSWITCH_GPIO_ENTRY_PIN_IO_TYPE               6:6
301 #define NVSWITCH_GPIO_ENTRY_PIN_INIT_STATE            7:7
302 
303 #define NVSWITCH_GPIO_ENTRY_FUNCTION                  7:0
304 #define NVSWITCH_GPIO_ENTRY_FUNCTION_THERMAL_EVENT    17
305 #define NVSWITCH_GPIO_ENTRY_FUNCTION_OVERTEMP         35
306 #define NVSWITCH_GPIO_ENTRY_FUNCTION_THERMAL_ALERT    52
307 #define NVSWITCH_GPIO_ENTRY_FUNCTION_THERMAL_CRITICAL 53
308 #define NVSWITCH_GPIO_ENTRY_FUNCTION_POWER_ALERT      76
309 #define NVSWITCH_GPIO_ENTRY_FUNCTION_INSTANCE_ID0    209
310 #define NVSWITCH_GPIO_ENTRY_FUNCTION_INSTANCE_ID1    210
311 #define NVSWITCH_GPIO_ENTRY_FUNCTION_INSTANCE_ID2    211
312 #define NVSWITCH_GPIO_ENTRY_FUNCTION_INSTANCE_ID3    212
313 #define NVSWITCH_GPIO_ENTRY_FUNCTION_INSTANCE_ID4    213
314 #define NVSWITCH_GPIO_ENTRY_FUNCTION_INSTANCE_ID5    214
315 #define NVSWITCH_GPIO_ENTRY_FUNCTION_INSTANCE_ID6    215
316 #define NVSWITCH_GPIO_ENTRY_FUNCTION_INSTANCE_ID7    216
317 #define NVSWITCH_GPIO_ENTRY_FUNCTION_INSTANCE_ID8    217
318 #define NVSWITCH_GPIO_ENTRY_FUNCTION_INSTANCE_ID9    218
319 #define NVSWITCH_GPIO_ENTRY_FUNCTION_SKIP_ENTRY      255
320 
321 #define NVSWITCH_GPIO_ENTRY_OUTPUT                    7:0
322 
323 #define NVSWITCH_GPIO_ENTRY_INPUT_HW_SELECT           4:0
324 #define NVSWITCH_GPIO_ENTRY_INPUT_HW_SELECT_NONE            0
325 #define NVSWITCH_GPIO_ENTRY_INPUT_HW_SELECT_THERMAL_ALERT   22
326 #define NVSWITCH_GPIO_ENTRY_INPUT_HW_SELECT_POWER_ALERT     23
327 #define NVSWITCH_GPIO_ENTRY_INPUT_GSYNC               5:5
328 #define NVSWITCH_GPIO_ENTRY_INPUT_OPEN_DRAIN          6:6
329 #define NVSWITCH_GPIO_ENTRY_INPUT_PWM                 7:7
330 //#define NVSWITCH_GPIO_ENTRY_INPUT_3V3                ?:?
331 
332 #define NVSWITCH_GPIO_ENTRY_MISC_LOCK                 3:0
333 #define NVSWITCH_GPIO_ENTRY_MISC_IO                   7:4
334 #define NVSWITCH_GPIO_ENTRY_MISC_IO_UNUSED              0x0
335 #define NVSWITCH_GPIO_ENTRY_MISC_IO_INV_OUT             0x1
336 #define NVSWITCH_GPIO_ENTRY_MISC_IO_INV_OUT_TRISTATE    0x3
337 #define NVSWITCH_GPIO_ENTRY_MISC_IO_OUT                 0x4
338 #define NVSWITCH_GPIO_ENTRY_MISC_IO_IN_STEREO_TRISTATE  0x6
339 #define NVSWITCH_GPIO_ENTRY_MISC_IO_INV_OUT_TRISTATE_LO 0x9
340 #define NVSWITCH_GPIO_ENTRY_MISC_IO_INV_IN              0xB
341 #define NVSWITCH_GPIO_ENTRY_MISC_IO_OUT_TRISTATE        0xC
342 #define NVSWITCH_GPIO_ENTRY_MISC_IO_IN                  0xE
343 
344 #define NVSWITCH_I2C_VERSION            0x40
345 
346 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_I2C_TABLE, 1)
347 {
348     NvU8    version;
349     NvU8    header_size;
350     NvU8    entry_count;
351     NvU8    entry_size;
352     NvU8    flags;
353 } NVSWITCH_I2C_TABLE;
354 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
355 
356 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_I2C_ENTRY, 1)
357 {
358     NvU32   device;
359 } NVSWITCH_I2C_ENTRY;
360 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
361 
362 #define NVSWITCH_I2C_ENTRY_TYPE         7:0
363 #define NVSWITCH_I2C_ENTRY_ADDRESS      15:8
364 #define NVSWITCH_I2C_ENTRY_RESERVED1    19:16
365 #define NVSWITCH_I2C_ENTRY_PORT_1       20:20
366 #define NVSWITCH_I2C_ENTRY_WR_ACCESS    23:21
367 #define NVSWITCH_I2C_ENTRY_RD_ACCESS    26:24
368 #define NVSWITCH_I2C_ENTRY_PORT_2       27:27
369 #define NVSWITCH_I2C_ENTRY_RESERVED2    31:28
370 
371 #define NVSWITCH_CCB_VERSION            0x41
372 
373 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_CCB_TABLE, 1)
374 {
375     NvU8    version;
376     NvU8    header_size;
377     NvU8    entry_count;
378     NvU8    entry_size;
379     NvU8    comm_port[4];
380 } NVSWITCH_CCB_TABLE;
381 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
382 
383 NVSWITCH_STRUCT_PACKED_ALIGNED(_NVSWITCH_CCB_ENTRY, 1)
384 {
385     NvU32   device;
386 } NVSWITCH_CCB_ENTRY;
387 NVSWITCH_STRUCT_PACKED_ALIGNED_SUFFIX
388 
389 #define NVSWITCH_CCB_DEVICE_I2C_PORT    4:0
390 #define NVSWITCH_CCB_DEVICE_DPAUX       9:5
391 #define NVSWITCH_CCB_DEVICE_VOLTAGE     10:10
392 #define NVSWITCH_CCB_DEVICE_RESERVED    27:11
393 #define NVSWITCH_CCB_DEVICE_I2C_SPEED   31:28
394 
395 #define NVSWITCH_CCB_DEVICE_I2C_SPEED_DEFAULT   0x0
396 #define NVSWITCH_CCB_DEVICE_I2C_SPEED_100KHZ    0x1
397 #define NVSWITCH_CCB_DEVICE_I2C_SPEED_200KHZ    0x2
398 #define NVSWITCH_CCB_DEVICE_I2C_SPEED_400KHZ    0x3
399 #define NVSWITCH_CCB_DEVICE_I2C_SPEED_800KHZ    0x4
400 #define NVSWITCH_CCB_DEVICE_I2C_SPEED_1600KHZ   0x5
401 #define NVSWITCH_CCB_DEVICE_I2C_SPEED_3400KHZ   0x6
402 #define NVSWITCH_CCB_DEVICE_I2C_SPEED_60KHZ     0x7
403 #define NVSWITCH_CCB_DEVICE_I2C_SPEED_300KHZ    0x8
404 
405 //
406 // Firmware data
407 //
408 
409 #define NVSWITCH_PRODUCT_NAME_MAX_LEN       64
410 
411 typedef struct
412 {
413     NvBool valid;
414     NvU32 ref_min_mhz;
415     NvU32 ref_max_mhz;
416     NvU32 vco_min_mhz;
417     NvU32 vco_max_mhz;
418     NvU32 update_min_mhz;
419     NvU32 update_max_mhz;
420     NvU32 m_min;
421     NvU32 m_max;
422     NvU32 n_min;
423     NvU32 n_max;
424     NvU32 pl_min;
425     NvU32 pl_max;
426 } NVSWITCH_PLL_LIMITS;
427 
428 typedef struct
429 {
430     NvBool valid;
431     NvU32  i2c_speed;
432     NvBool i2c_33v;
433 } NVSWITCH_I2C_PORT;
434 
435 #define NVSWITCH_MAX_I2C_DEVICES    16
436 
437 typedef struct
438 {
439     NvU32   pin;
440     NvU32   function;
441     NvU32   hw_select;
442     NvU32   misc;
443 } NVSWITCH_GPIO_INFO;
444 
445 #define NVSWITCH_MAX_GPIO_PINS      25
446 
447 typedef struct
448 {
449     NvU32   firmware_size;
450 
451     // ROM Header
452     NvU16   pci_vendor_id;
453     NvU16   pci_device_id;
454     NvU16   pci_system_vendor_id;
455     NvU16   pci_system_device_id;
456 
457     // Firmware data
458     struct
459     {
460         NvBool bridge_fw_found;
461         NvU32 firmware_version;
462         NvU8  oem_version;
463         char  BIOS_MOD_date[8];
464         NvBool fw_release_build;
465         char  product_name[NVSWITCH_PRODUCT_NAME_MAX_LEN+1];
466         NvU16 instance_id;
467     } bridge;
468 
469     // Clocks
470     struct
471     {
472         NvBool clocks_found;
473         NVSWITCH_PLL_LIMITS sys_pll;
474     } clocks;
475 
476     // NVLink init
477     struct
478     {
479         NvBool link_config_found;
480         NvU64 link_enable_mask;             // 1 = enabled
481         NvU64 link_ac_coupled_mask;         // 0 = DC, 1 = AC
482     } nvlink;
483 
484     // DCB
485     struct
486     {
487         NvBool              dcb_found;
488         NVSWITCH_I2C_PORT   i2c[NVSWITCH_MAX_I2C_PORTS];
489         NvU32               i2c_device_count;
490         NVSWITCH_I2C_DEVICE_DESCRIPTOR_TYPE i2c_device[NVSWITCH_MAX_I2C_DEVICES];
491         NvU32               gpio_pin_count;
492         NVSWITCH_GPIO_INFO  gpio_pin[NVSWITCH_MAX_GPIO_PINS];
493     } dcb;
494 
495 } NVSWITCH_FIRMWARE;
496 
497 #define NVSWITCH_FIRMWARE_BRIDGE_INSTANCE_ID_UNKNOWN    0xFFFF
498 #define NVSWITCH_FIRMWARE_BRIDGE_INSTANCE_ID_NORMAL     0xFFFE
499 
500 void
501 nvswitch_read_rom_tables
502 (
503     nvswitch_device *device,
504     NVSWITCH_FIRMWARE *firmware
505 );
506 
507 
508 #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
509 #define BYTE_TO_BINARY(byte)  \
510   (byte & 0x80 ? '1' : '0'), \
511   (byte & 0x40 ? '1' : '0'), \
512   (byte & 0x20 ? '1' : '0'), \
513   (byte & 0x10 ? '1' : '0'), \
514   (byte & 0x08 ? '1' : '0'), \
515   (byte & 0x04 ? '1' : '0'), \
516   (byte & 0x02 ? '1' : '0'), \
517   (byte & 0x01 ? '1' : '0')
518 
519 #if !defined(BIOSTYPES_H_FILE)
520 #define bios_U008  NvU32
521 #define bios_U016  NvU32
522 #define bios_U032  NvU32
523 #define bios_S008  NvS32
524 #define bios_S016  NvS32
525 #define bios_S032  NvS32
526 #endif // !defined(BIOSTYPES_H_FILE)
527 
528 /**************************************************************************************************************
529 *   Description:
530 *       Definitions of BIOS BIT structures as defined starting in Core 5
531 *
532 **************************************************************************************************************/
533 #if !defined(_BIT_H_)
534 #define BIT_HEADER_ID                     0xB8FF
535 #define BIT_HEADER_SIGNATURE              0x00544942  // "BIT\0"
536 #define BIT_HEADER_SIZE_OFFSET            8
537 #define BIT_HEADER_LATEST_KNOWN_VERSION   0x100
538 #endif // !defined(_BIT_H_)
539 
540 #define PCI_ROM_HEADER_SIZE               0x18
541 #define PCI_DATA_STRUCT_SIZE              0x1c
542 #define PCI_ROM_HEADER_PCI_DATA_SIZE      (PCI_ROM_HEADER_SIZE + PCI_DATA_STRUCT_SIZE) // ROM Header + PCI Dat Structure size
543 #define PCI_EXP_ROM_SIGNATURE             0xaa55
544 #define PCI_DATA_STRUCT_SIGNATURE         0x52494350 // "PCIR" in dword format
545 
546 #define NVLINK_CONFIG_DATA_HEADER_VER_20    0x2
547 #define NVLINK_CONFIG_DATA_HEADER_20_SIZE   8
548 #define NVLINK_CONFIG_DATA_HEADER_20_FMT    "6b1w"
549 
550 #define NVLINK_CONFIG_DATA_HEADER_VER_30    0x3
551 #define NVLINK_CONFIG_DATA_HEADER_30_SIZE   8
552 
553 typedef struct _PCI_DATA_STRUCT
554 {
555     bios_U032       sig;                    //  00h: Signature, the string "PCIR" or NVIDIA's alternate "NPDS"
556     bios_U016       vendorID;               //  04h: Vendor Identification
557     bios_U016       deviceID;               //  06h: Device Identification
558     bios_U016       deviceListPtr;          //  08h: Device List Pointer
559     bios_U016       pciDataStructLen;       //  0Ah: PCI Data Structure Length
560     bios_U008       pciDataStructRev;       //  0Ch: PCI Data Structure Revision
561     bios_U008       classCode[3];           //  0Dh: Class Code
562     bios_U016       imageLen;               //  10h: Image Length (units of 512 bytes)
563     bios_U016       vendorRomRev;           //  12h: Revision Level of the Vendor's ROM
564     bios_U008       codeType;               //  14h: holds NBSI_OBJ_CODE_TYPE (0x70) and others
565     bios_U008       lastImage;              //  15h: Last Image Indicator: bit7=1 is lastImage
566     bios_U016       maxRunTimeImageLen;     //  16h: Maximum Run-time Image Length (units of 512 bytes)
567     bios_U016       configUtilityCodePtr;   //  18h: Pointer to Configurations Utility Code Header
568     bios_U016       CMDTFCLPEntryPointPtr;  //  1Ah: Pointer to DMTF CLP Entry Point
569 } PCI_DATA_STRUCT, *PPCI_DATA_STRUCT;
570 #define PCI_DATA_STRUCT_FMT "1d4w4b2w2b3w"
571 
572 // BIT_TOKEN_NVINIT_PTRS       0x49 // 'I' Initialization Table Pointers
573 struct BIT_DATA_NVINIT_PTRS_V1
574 {
575    bios_U016 InitScriptTablePtr;      // Init script table pointer
576    bios_U016 MacroIndexTablePtr;      // Macro index table pointer
577    bios_U016 MacroTablePtr;           // Macro table pointer
578    bios_U016 ConditionTablePtr;       // Condition table pointer
579    bios_U016 IoConditionTablePtr;     // IO Condition table pointer
580    bios_U016 IoFlagConditionTablePtr; // IO Flag Condition table pointer
581    bios_U016 InitFunctionTablePtr;    // Init Function table pointer
582    bios_U016 VBIOSPrivateTablePtr;    // VBIOS private table pointer
583    bios_U016 DataArraysTablePtr;      // Data arrays table pointer
584    bios_U016 PCIESettingsScriptPtr;   // PCI-E settings script pointer
585    bios_U016 DevinitTablesPtr;        // Pointer to tables required by Devinit opcodes
586    bios_U016 DevinitTablesSize;       // Size of tables required by Devinit opcodes
587    bios_U016 BootScriptsPtr;          // Pointer to Devinit Boot Scripts
588    bios_U016 BootScriptsSize;         // Size of Devinit Boot Scripts
589    bios_U016 NvlinkConfigDataPtr;     // Pointer to NVLink Config Data
590 };
591 #define BIT_DATA_NVINIT_PTRS_V1_30_FMT "15w"
592 typedef struct BIT_DATA_NVINIT_PTRS_V1 BIT_DATA_NVINIT_PTRS_V1;
593 
594 #define BIT_TOKEN_BIOSDATA          0x42 // 'B' BIOS Data
595 #define BIT_TOKEN_NVINIT_PTRS       0x49 // 'I'
596 
597 struct BIT_HEADER_V1_00
598 {
599     bios_U016 Id;            // BMP=0x7FFF/BIT=0xB8FF
600     bios_U032 Signature;     // 0x00544942 - BIT Data Structure Signature
601     bios_U016 BCD_Version;   // BIT Version - 0x0100 for 1.00
602     bios_U008 HeaderSize;    // This version is 12 bytes long
603     bios_U008 TokenSize;     // This version has 6 byte long Tokens
604     bios_U008 TokenEntries;  // Number of Entries
605     bios_U008 HeaderChksum;  // 0 Checksum of the header
606 };
607 #define BIT_HEADER_V1_00_FMT "1w1d1w4b"
608 typedef struct BIT_HEADER_V1_00 BIT_HEADER_V1_00;
609 
610 struct BIT_TOKEN_V1_00
611 {
612     bios_U008 TokenId;
613     bios_U008 DataVersion;
614     bios_U016 DataSize;
615     bios_U016 DataPtr;
616 };
617 #define BIT_TOKEN_V1_00_FMT "2b2w"
618 typedef struct BIT_TOKEN_V1_00 BIT_TOKEN_V1_00;
619 
620 
621 // BIT_TOKEN_BIOSDATA          0x42 // 'B' BIOS Data
622 struct BIT_DATA_BIOSDATA_V1
623 {
624     bios_U032 Version;                // BIOS Binary Version Ex. 5.40.00.01.12 = 0x05400001
625     bios_U008 OemVersion;             // OEM Version Number  Ex. 5.40.00.01.12 = 0x12
626                                       // OEM can override the two fields above
627     bios_U008 Checksum;               // Filled by MakeVGA
628     bios_U016 Int15CallbacksPost;     //
629     bios_U016 Int15CallbacksSystem;   //
630     bios_U016 BoardId;                //
631     bios_U016 FrameCount;             // Frame count for signon message delay
632     bios_U008 BiosmodDate[8];         // '00/00/04' Date BIOSMod was last run
633 };
634 #define BIT_DATA_BIOSDATA_V1_FMT    "1d2b4w8b"
635 typedef struct BIT_DATA_BIOSDATA_V1 BIT_DATA_BIOSDATA_V1;
636 
637 struct BIT_DATA_BIOSDATA_V2
638 {
639     bios_U032 Version;                // BIOS Binary Version Ex. 5.40.00.01.12 = 0x05400001
640     bios_U008 OemVersion;             // OEM Version Number  Ex. 5.40.00.01.12 = 0x12
641     // OEM can override the two fields above
642     bios_U008 Checksum;               // Filled by MakeVGA
643     bios_U016 Int15CallbacksPost;     //
644     bios_U016 Int15CallbacksSystem;   //
645     bios_U016 FrameCount;             // Frame count for signon message delay
646     bios_U032 Reserved1;
647     bios_U032 Reserved2;
648     bios_U008 MaxHeadsAtPost;
649     bios_U008 MemorySizeReport;
650     bios_U008 HorizontalScaleFactor;
651     bios_U008 VerticalScaleFactor;
652     bios_U016 DataTablePtr;
653     bios_U016 RomPackPtr;
654     bios_U016 AppliedRomPacksPtr;
655     bios_U008 AppliedRomPackMax;
656     bios_U008 AppliedRomPackCount;
657     bios_U008 ModuleMapExternal;
658     bios_U032 CompressionInfoPtr;
659 };
660 #define BIT_DATA_BIOSDATA_V2_FMT "1d2b3w2d4b3w3b1d"
661 typedef struct BIT_DATA_BIOSDATA_V2 BIT_DATA_BIOSDATA_V2;
662 
663 #ifndef PCI_VENDOR_ID_NVIDIA
664 #define PCI_VENDOR_ID_NVIDIA            0x10DE
665 #endif
666 
667 typedef struct _nvlink_Config_Data_Header_20
668 {
669     bios_U008 Version;           // NVLink Config Data Structure version
670     bios_U008 HeaderSize;        // Size of header
671     bios_U008 BaseEntrySize;
672     bios_U008 BaseEntryCount;
673     bios_U008 LinkEntrySize;
674     bios_U008 LinkEntryCount;
675     bios_U016 Reserved;          // Reserved
676 } NVLINK_CONFIG_DATA_HEADER_20, *PNVLINK_CONFIG_DATA_HEADER_20;
677 
678 #define NV_NVLINK_VBIOS_PARAM0_LINK                             0:0
679 #define NV_NVLINK_VBIOS_PARAM0_LINK_ENABLE                      0x0
680 #define NV_NVLINK_VBIOS_PARAM0_LINK_DISABLE                     0x1
681 #define NV_NVLINK_VBIOS_PARAM0_RESERVED1                        1:1
682 #define NV_NVLINK_VBIOS_PARAM0_ACDC_MODE                        2:2
683 #define NV_NVLINK_VBIOS_PARAM0_ACDC_MODE_DC                     0x0
684 #define NV_NVLINK_VBIOS_PARAM0_ACDC_MODE_AC                     0x1
685 #define NV_NVLINK_VBIOS_PARAM0_RECEIVER_DETECT                  3:3
686 #define NV_NVLINK_VBIOS_PARAM0_RECEIVER_DETECT_DISABLE          0x0
687 #define NV_NVLINK_VBIOS_PARAM0_RECEIVER_DETECT_ENABLE           0x1
688 #define NV_NVLINK_VBIOS_PARAM0_RESTORE_PHY_TRAINING             4:4
689 #define NV_NVLINK_VBIOS_PARAM0_RESTORE_PHY_TRAINING_DISABLE     0x0
690 #define NV_NVLINK_VBIOS_PARAM0_RESTORE_PHY_TRAINING_ENABLE      0x1
691 #define NV_NVLINK_VBIOS_PARAM0_SLM                              5:5
692 #define NV_NVLINK_VBIOS_PARAM0_SLM_DISABLE                      0x0
693 #define NV_NVLINK_VBIOS_PARAM0_SLM_ENABLE                       0x1
694 #define NV_NVLINK_VBIOS_PARAM0_L2                               6:6
695 #define NV_NVLINK_VBIOS_PARAM0_L2_DISABLE                       0x0
696 #define NV_NVLINK_VBIOS_PARAM0_L2_ENABLE                        0x1
697 #define NV_NVLINK_VBIOS_PARAM0_RESERVED2                        7:7
698 
699 #define NV_NVLINK_VBIOS_PARAM1_LINE_RATE                        7:0
700 #define NV_NVLINK_VBIOS_PARAM1_LINE_RATE_50_00000               0x00
701 #define NV_NVLINK_VBIOS_PARAM1_LINE_RATE_16_00000               0x01
702 #define NV_NVLINK_VBIOS_PARAM1_LINE_RATE_20_00000               0x02
703 #define NV_NVLINK_VBIOS_PARAM1_LINE_RATE_25_00000               0x03
704 #define NV_NVLINK_VBIOS_PARAM1_LINE_RATE_25_78125               0x04
705 #define NV_NVLINK_VBIOS_PARAM1_LINE_RATE_32_00000               0x05
706 #define NV_NVLINK_VBIOS_PARAM1_LINE_RATE_40_00000               0x06
707 #define NV_NVLINK_VBIOS_PARAM1_LINE_RATE_53_12500               0x07
708 
709 #define NV_NVLINK_VBIOS_PARAM2_LINE_CODE_MODE                   7:0
710 #define NV_NVLINK_VBIOS_PARAM2_LINE_CODE_MODE_NRZ               0x00
711 #define NV_NVLINK_VBIOS_PARAM2_LINE_CODE_MODE_NRZ_128B130       0x01
712 #define NV_NVLINK_VBIOS_PARAM2_LINE_CODE_MODE_NRZ_PAM4          0x03
713 
714 #define NV_NVLINK_VBIOS_PARAM3_REFERENCE_CLOCK_MODE                     1:0
715 #define NV_NVLINK_VBIOS_PARAM3_REFERENCE_CLOCK_MODE_COMMON              0x0
716 #define NV_NVLINK_VBIOS_PARAM3_REFERENCE_CLOCK_MODE_RSVD                0x1
717 #define NV_NVLINK_VBIOS_PARAM3_REFERENCE_CLOCK_MODE_NON_COMMON_NO_SS    0x2
718 #define NV_NVLINK_VBIOS_PARAM3_REFERENCE_CLOCK_MODE_NON_COMMON_SS       0x3
719 
720 #define NV_NVLINK_VBIOS_PARAM3_RESERVED1                        3:2
721 #define NV_NVLINK_VBIOS_PARAM3_CLOCK_MODE_BLOCK_CODE            5:4
722 #define NV_NVLINK_VBIOS_PARAM3_CLOCK_MODE_BLOCK_CODE_OFF        0x0
723 #define NV_NVLINK_VBIOS_PARAM3_CLOCK_MODE_BLOCK_CODE_ECC96      0x1
724 #define NV_NVLINK_VBIOS_PARAM3_CLOCK_MODE_BLOCK_CODE_ECC88      0x2
725 #define NV_NVLINK_VBIOS_PARAM3_RESERVED2                        7:6
726 
727 #define NV_NVLINK_VBIOS_PARAM4_TXTRAIN_OPTIMIZATION_ALGORITHM                               7:0
728 #define NV_NVLINK_VBIOS_PARAM4_TXTRAIN_OPTIMIZATION_ALGORITHM_RSVD                          0x00
729 #define NV_NVLINK_VBIOS_PARAM4_TXTRAIN_OPTIMIZATION_ALGORITHM_A0_SINGLE_PRESENT             0x01
730 #define NV_NVLINK_VBIOS_PARAM4_TXTRAIN_OPTIMIZATION_ALGORITHM_A1_PRESENT_ARRAY              0x02
731 #define NV_NVLINK_VBIOS_PARAM4_TXTRAIN_OPTIMIZATION_ALGORITHM_A2_FINE_GRAINED_EXHAUSTIVE    0x04
732 #define NV_NVLINK_VBIOS_PARAM4_TXTRAIN_OPTIMIZATION_ALGORITHM_A3_RSVD                       0x08
733 #define NV_NVLINK_VBIOS_PARAM4_TXTRAIN_OPTIMIZATION_ALGORITHM_A4_FOM_CENTRIOD               0x10
734 #define NV_NVLINK_VBIOS_PARAM4_TXTRAIN_OPTIMIZATION_ALGORITHM_A5_RSVD                       0x20
735 #define NV_NVLINK_VBIOS_PARAM4_TXTRAIN_OPTIMIZATION_ALGORITHM_A6_RSVD                       0x40
736 #define NV_NVLINK_VBIOS_PARAM4_TXTRAIN_OPTIMIZATION_ALGORITHM_A7_RSVD                       0x80
737 
738 #define NV_NVLINK_VBIOS_PARAM5_TXTRAIN_ADJUSTMENT_ALGORITHM                                 4:0
739 #define NV_NVLINK_VBIOS_PARAM5_TXTRAIN_ADJUSTMENT_ALGORITHM_B0_NO_ADJUSTMENT                0x1
740 #define NV_NVLINK_VBIOS_PARAM5_TXTRAIN_ADJUSTMENT_ALGORITHM_B1_FIXED_ADJUSTMENT             0x2
741 #define NV_NVLINK_VBIOS_PARAM5_TXTRAIN_ADJUSTMENT_ALGORITHM_B2_RSVD                         0x4
742 #define NV_NVLINK_VBIOS_PARAM5_TXTRAIN_ADJUSTMENT_ALGORITHM_B3_RSVD                         0x8
743 
744 #define NV_NVLINK_VBIOS_PARAM5_TXTRAIN_FOM_FORMAT                           7:5
745 #define NV_NVLINK_VBIOS_PARAM5_TXTRAIN_FOM_FORMAT_FOM_A                     0x1
746 #define NV_NVLINK_VBIOS_PARAM5_TXTRAIN_FOM_FORMAT_FOM_B                     0x2
747 #define NV_NVLINK_VBIOS_PARAM5_TXTRAIN_FOM_FORMAT_FOM_C                     0x4
748 
749 #define NV_NVLINK_VBIOS_PARAM6_TXTRAIN_MINIMUM_TRAIN_TIME_MANTISSA           3:0
750 #define NV_NVLINK_VBIOS_PARAM6_TXTRAIN_MINIMUM_TRAIN_TIME_EXPONENT           7:4
751 
752 #define NVLINK_CONFIG_DATA_BASEENTRY_FMT "1b"
753 #define NVLINK_CONFIG_DATA_LINKENTRY_FMT_20 "7b"
754 #define NVLINK_CONFIG_DATA_LINKENTRY_FMT_30 "10b"
755 
756 // Version 2.0 Link Entry and Base Entry
757 typedef struct _nvlink_config_data_baseentry_20
758 {
759      NvU8  positionId;
760 } NVLINK_CONFIG_DATA_BASEENTRY;
761 
762 typedef struct _nvlink_config_data_linkentry_20
763 {
764     // VBIOS configuration Data
765      NvU8  nvLinkparam0;
766      NvU8  nvLinkparam1;
767      NvU8  nvLinkparam2;
768      NvU8  nvLinkparam3;
769      NvU8  nvLinkparam4;
770      NvU8  nvLinkparam5;
771      NvU8  nvLinkparam6;
772      NvU8  nvLinkparam7;
773      NvU8  nvLinkparam8;
774      NvU8  nvLinkparam9;
775 } NVLINK_CONFIG_DATA_LINKENTRY;
776 
777 // Union of different VBIOS configuration table formats
778 typedef union __nvlink_Config_Data_Header
779 {
780     NVLINK_CONFIG_DATA_HEADER_20 ver_20;
781 } NVLINK_CONFIG_DATA_HEADER, *PNVLINK_CONFIG_DATA_HEADER;
782 
783 typedef struct _nvlink_vbios_config_data_baseentry_20
784 {
785      bios_U008  positionId;
786 } NVLINK_VBIOS_CONFIG_DATA_BASEENTRY;
787 
788 typedef struct _nvlink_vbios_config_data_linkentry_20
789 {
790     // VBIOS configuration Data
791      bios_U008  nvLinkparam0;
792      bios_U008  nvLinkparam1;
793      bios_U008  nvLinkparam2;
794      bios_U008  nvLinkparam3;
795      bios_U008  nvLinkparam4;
796      bios_U008  nvLinkparam5;
797      bios_U008  nvLinkparam6;
798 } NVLINK_VBIOS_CONFIG_DATA_LINKENTRY_20, *PNVLINK_VBIOS_CONFIG_DATA_LINKENTRY_20;
799 
800 typedef struct _nvlink_vbios_config_data_linkentry_30
801 {
802     // VBIOS configuration Data
803      bios_U008  nvLinkparam0;
804      bios_U008  nvLinkparam1;
805      bios_U008  nvLinkparam2;
806      bios_U008  nvLinkparam3;
807      bios_U008  nvLinkparam4;
808      bios_U008  nvLinkparam5;
809      bios_U008  nvLinkparam6;
810      bios_U008  nvLinkparam7;
811      bios_U008  nvLinkparam8;
812      bios_U008  nvLinkparam9;
813 } NVLINK_VBIOS_CONFIG_DATA_LINKENTRY_30, *PNVLINK_VBIOS_CONFIG_DATA_LINKENTRY_30;
814 
815 //
816 // NVSwitch driver structures
817 //
818 
819 #define NVSWITCH_NUM_BIOS_NVLINK_CONFIG_BASE_ENTRY    12
820 
821 typedef struct
822 {
823     NVLINK_CONFIG_DATA_BASEENTRY link_vbios_base_entry[NVSWITCH_NUM_BIOS_NVLINK_CONFIG_BASE_ENTRY];
824     NVLINK_CONFIG_DATA_LINKENTRY link_vbios_entry[NVSWITCH_NUM_BIOS_NVLINK_CONFIG_BASE_ENTRY][NVSWITCH_MAX_LINK_COUNT];
825     NvU32                        identified_Link_entries[NVSWITCH_NUM_BIOS_NVLINK_CONFIG_BASE_ENTRY];
826     NvU32                        link_base_entry_assigned;
827     NvU64                        vbios_disabled_link_mask;
828 
829     NvU32                        bit_address;
830     NvU32                        pci_image_address;
831     NvU32                        nvlink_config_table_address;
832 } NVSWITCH_BIOS_NVLINK_CONFIG;
833 
834 #define NVSWITCH_DCB_PTR_OFFSET 0x36
835 
836 typedef struct _nvswitch_vbios_dcb_header_41
837 {
838     bios_U008 version;
839     bios_U008 header_size;
840     bios_U008 entry_count;
841     bios_U008 entry_size;
842     bios_U016 ccb_block_ptr;
843     bios_U032 dcb_signature;
844     bios_U016 gpio_table;
845     bios_U016 input_devices;
846     bios_U016 personal_cinema;
847     bios_U016 spread_spectrum;
848     bios_U016 i2c_devices;
849     bios_U016 connectors;
850     bios_U008 flags;
851     bios_U016 hdtv;
852     bios_U016 switched_outputs;
853     bios_U032 display_patch;
854     bios_U032 connector_patch;
855 } NVSWITCH_VBIOS_DCB_HEADER;
856 #define NVSWITCH_VBIOS_DCB_HEADER_FMT "4b1w1d6w1b2w2d"
857 
858 typedef struct _nvswitch_vbios_ccb_table_41
859 {
860     bios_U008    version;
861     bios_U008    header_size;
862     bios_U008    entry_count;
863     bios_U008    entry_size;
864     bios_U008    comm_port[4];
865 } NVSWITCH_VBIOS_CCB_TABLE;
866 #define NVSWITCH_VBIOS_CCB_TABLE_FMT "8b"
867 
868 typedef struct _nvswitch_vbios_i2c_table_40
869 {
870     bios_U008    version;
871     bios_U008    header_size;
872     bios_U008    entry_count;
873     bios_U008    entry_size;
874     bios_U008    flags;
875 } NVSWITCH_VBIOS_I2C_TABLE;
876 #define NVSWITCH_I2C_TABLE_FMT "5b"
877 
878 typedef struct _nvswitch_vbios_i2c_entry
879 {
880     bios_U032   device;
881 } NVSWITCH_VBIOS_I2C_ENTRY;
882 #define NVSWITCH_I2C_ENTRY_FMT "1d"
883 
884 #endif //_ROM_NVSWITCH_H_
885 
886