@@ -95,6 +95,7 @@ struct controller {
95
95
u8 function ;
96
96
u8 slot_device_offset ;
97
97
u8 add_support ;
98
+ u32 pcix_misc2_reg ; /* for amd pogo errata */
98
99
enum pci_bus_speed speed ;
99
100
u32 first_slot ; /* First physical slot number */
100
101
u8 slot_bus ; /* Bus where the slots handled by this controller sit */
@@ -113,6 +114,26 @@ struct hotplug_params {
113
114
114
115
/* Define AMD SHPC ID */
115
116
#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450
117
+ #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458
118
+
119
+ /* AMD PCIX bridge registers */
120
+
121
+ #define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C
122
+ #define PCIX_MISCII_OFFSET 0x48
123
+ #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80
124
+
125
+ /* AMD PCIX_MISCII masks and offsets */
126
+ #define PERRNONFATALENABLE_MASK 0x00040000
127
+ #define PERRFATALENABLE_MASK 0x00080000
128
+ #define PERRFLOODENABLE_MASK 0x00100000
129
+ #define SERRNONFATALENABLE_MASK 0x00200000
130
+ #define SERRFATALENABLE_MASK 0x00400000
131
+
132
+ /* AMD PCIX_MISC_BRIDGE_ERRORS masks and offsets */
133
+ #define PERR_OBSERVED_MASK 0x00000001
134
+
135
+ /* AMD PCIX_MEM_BASE_LIMIT masks */
136
+ #define RSE_MASK 0x40000000
116
137
117
138
#define INT_BUTTON_IGNORE 0
118
139
#define INT_PRESENCE_ON 1
@@ -333,6 +354,79 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl)
333
354
return retval ;
334
355
}
335
356
357
+ static inline void amd_pogo_errata_save_misc_reg (struct slot * p_slot )
358
+ {
359
+ u32 pcix_misc2_temp ;
360
+
361
+ /* save MiscII register */
362
+ pci_read_config_dword (p_slot -> ctrl -> pci_dev , PCIX_MISCII_OFFSET , & pcix_misc2_temp );
363
+
364
+ p_slot -> ctrl -> pcix_misc2_reg = pcix_misc2_temp ;
365
+
366
+ /* clear SERR/PERR enable bits */
367
+ pcix_misc2_temp &= ~SERRFATALENABLE_MASK ;
368
+ pcix_misc2_temp &= ~SERRNONFATALENABLE_MASK ;
369
+ pcix_misc2_temp &= ~PERRFLOODENABLE_MASK ;
370
+ pcix_misc2_temp &= ~PERRFATALENABLE_MASK ;
371
+ pcix_misc2_temp &= ~PERRNONFATALENABLE_MASK ;
372
+ pci_write_config_dword (p_slot -> ctrl -> pci_dev , PCIX_MISCII_OFFSET , pcix_misc2_temp );
373
+ }
374
+
375
+ static inline void amd_pogo_errata_restore_misc_reg (struct slot * p_slot )
376
+ {
377
+ u32 pcix_misc2_temp ;
378
+ u32 pcix_bridge_errors_reg ;
379
+ u32 pcix_mem_base_reg ;
380
+ u8 perr_set ;
381
+ u8 rse_set ;
382
+
383
+ /* write-one-to-clear Bridge_Errors[ PERR_OBSERVED ] */
384
+ pci_read_config_dword (p_slot -> ctrl -> pci_dev , PCIX_MISC_BRIDGE_ERRORS_OFFSET , & pcix_bridge_errors_reg );
385
+ perr_set = pcix_bridge_errors_reg & PERR_OBSERVED_MASK ;
386
+ if (perr_set ) {
387
+ dbg ("%s W1C: Bridge_Errors[ PERR_OBSERVED = %08X]\n" ,__FUNCTION__ , perr_set );
388
+
389
+ pci_write_config_dword (p_slot -> ctrl -> pci_dev , PCIX_MISC_BRIDGE_ERRORS_OFFSET , perr_set );
390
+ }
391
+
392
+ /* write-one-to-clear Memory_Base_Limit[ RSE ] */
393
+ pci_read_config_dword (p_slot -> ctrl -> pci_dev , PCIX_MEM_BASE_LIMIT_OFFSET , & pcix_mem_base_reg );
394
+ rse_set = pcix_mem_base_reg & RSE_MASK ;
395
+ if (rse_set ) {
396
+ dbg ("%s W1C: Memory_Base_Limit[ RSE ]\n" ,__FUNCTION__ );
397
+
398
+ pci_write_config_dword (p_slot -> ctrl -> pci_dev , PCIX_MEM_BASE_LIMIT_OFFSET , rse_set );
399
+ }
400
+ /* restore MiscII register */
401
+ pci_read_config_dword ( p_slot -> ctrl -> pci_dev , PCIX_MISCII_OFFSET , & pcix_misc2_temp );
402
+
403
+ if (p_slot -> ctrl -> pcix_misc2_reg & SERRFATALENABLE_MASK )
404
+ pcix_misc2_temp |= SERRFATALENABLE_MASK ;
405
+ else
406
+ pcix_misc2_temp &= ~SERRFATALENABLE_MASK ;
407
+
408
+ if (p_slot -> ctrl -> pcix_misc2_reg & SERRNONFATALENABLE_MASK )
409
+ pcix_misc2_temp |= SERRNONFATALENABLE_MASK ;
410
+ else
411
+ pcix_misc2_temp &= ~SERRNONFATALENABLE_MASK ;
412
+
413
+ if (p_slot -> ctrl -> pcix_misc2_reg & PERRFLOODENABLE_MASK )
414
+ pcix_misc2_temp |= PERRFLOODENABLE_MASK ;
415
+ else
416
+ pcix_misc2_temp &= ~PERRFLOODENABLE_MASK ;
417
+
418
+ if (p_slot -> ctrl -> pcix_misc2_reg & PERRFATALENABLE_MASK )
419
+ pcix_misc2_temp |= PERRFATALENABLE_MASK ;
420
+ else
421
+ pcix_misc2_temp &= ~PERRFATALENABLE_MASK ;
422
+
423
+ if (p_slot -> ctrl -> pcix_misc2_reg & PERRNONFATALENABLE_MASK )
424
+ pcix_misc2_temp |= PERRNONFATALENABLE_MASK ;
425
+ else
426
+ pcix_misc2_temp &= ~PERRNONFATALENABLE_MASK ;
427
+ pci_write_config_dword (p_slot -> ctrl -> pci_dev , PCIX_MISCII_OFFSET , pcix_misc2_temp );
428
+ }
429
+
336
430
#define SLOT_NAME_SIZE 10
337
431
338
432
static inline void make_slot_name (char * buffer , int buffer_size , struct slot * slot )
0 commit comments