1 /* 2 Copyright (c) 2002, Thomas Kurschel 3 4 5 Part of Radeon kernel driver 6 7 AGP fix. Some motherboard BIOSes enable FastWrite even 8 though the graphics card doesn't support it. Here, we'll 9 fix that (hopefully it is generic enough). 10 */ 11 12 13 #include "radeon_driver.h" 14 15 16 // missing PCI definitions 17 #define PCI_status_cap_list 0x10 /* Support Capability List */ 18 19 #define PCI_header_type_normal 0 20 #define PCI_header_type_bridge 1 21 //#define PCI_header_type_cardbus 2 22 23 #define PCI_capability_list 0x34 /* Offset of first capability list entry */ 24 #define PCI_cb_capability_list 0x14 25 26 #define PCI_cap_list_id 0 /* Capability ID */ 27 #define PCI_cap_id_pm 0x01 /* Power Management */ 28 #define PCI_cap_id_agp 0x02 /* Accelerated Graphics Port */ 29 #define PCI_cap_id_vpd 0x03 /* Vital Product Data */ 30 #define PCI_cap_id_slotid 0x04 /* Slot Identification */ 31 #define PCI_cap_id_msi 0x05 /* Message Signalled Interrupts */ 32 #define PCI_cap_id_chswp 0x06 /* CompactPCI HotSwap */ 33 #define PCI_cap_list_next 1 /* Next capability in the list */ 34 #define PCI_cap_flags 2 /* Capability defined flags (16 bits) */ 35 #define PCI_cap_sizeof 4 36 37 38 #define PCI_agp_status 4 /* Status register */ 39 #define PCI_agp_status_rq_mask 0xff000000 /* Maximum number of requests - 1 */ 40 #define PCI_agp_status_sba 0x0200 /* Sideband addressing supported */ 41 #define PCI_agp_status_64bit 0x0020 /* 64-bit addressing supported */ 42 #define PCI_agp_status_fw 0x0010 /* FW transfers supported */ 43 #define PCI_agp_status_rate4 0x0004 /* 4x transfer rate supported */ 44 #define PCI_agp_status_rate2 0x0002 /* 2x transfer rate supported */ 45 #define PCI_agp_status_rate1 0x0001 /* 1x transfer rate supported */ 46 47 #define PCI_agp_command 8 /* Control register */ 48 #define PCI_agp_command_rq_mask 0xff000000 /* Master: Maximum number of requests */ 49 #define PCI_agp_command_sba 0x0200 /* Sideband addressing enabled */ 50 #define PCI_agp_command_agp 0x0100 /* Allow processing of AGP transactions */ 51 #define PCI_agp_command_64bit 0x0020 /* Allow processing of 64-bit addresses */ 52 #define PCI_agp_command_fw 0x0010 /* Force FW transfers */ 53 #define PCI_agp_command_rate4 0x0004 /* Use 4x rate */ 54 #define PCI_agp_command_rate2 0x0002 /* Use 2x rate */ 55 #define PCI_agp_command_rate1 0x0001 /* Use 1x rate */ 56 57 58 59 // helper macros for easier PCI access 60 #define get_pci(o, s) (*pci_bus->read_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s)) 61 #define set_pci(o, s, v) (*pci_bus->write_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s), (v)) 62 63 int find_capability( pci_info *pcii, uint8 capability ); 64 void Radeon_Fix_AGP( void ); 65 66 67 // show AGP capabilities 68 static void show_agp_status( uint32 status ) 69 { 70 SHOW_FLOW( 3, "Status (%08lx): %s%s%s%s%s%s", status, 71 (status & PCI_agp_status_sba) != 0 ? "Sideband addressing " : "", 72 (status & PCI_agp_status_64bit) != 0 ? "64-bit " : "", 73 (status & PCI_agp_status_fw) != 0 ? "FastWrite " : "", 74 (status & PCI_agp_status_rate4) != 0 ? "4x " : "", 75 (status & PCI_agp_status_rate2) != 0 ? "2x " : "", 76 (status & PCI_agp_status_rate1) != 0 ? "1x " : "" ); 77 } 78 79 80 // show AGP settings 81 static void show_agp_command( uint32 command ) 82 { 83 SHOW_FLOW( 3, "Command (%08lx): %s%s%s%s%s%s%s", command, 84 (command & PCI_agp_command_sba) != 0 ? "Sideband addressing " : "", 85 (command & PCI_agp_command_agp) != 0 ? "AGP-Enabled " : "AGP-Disabled ", 86 (command & PCI_agp_command_64bit) != 0 ? "64-bit " : "", 87 (command & PCI_agp_command_fw) != 0 ? "FastWrite " : "", 88 (command & PCI_agp_command_rate4) != 0 ? "4x " : "", 89 (command & PCI_agp_command_rate2) != 0 ? "2x " : "", 90 (command & PCI_agp_command_rate1) != 0 ? "1x " : "" ); 91 } 92 93 94 // find PCI capability 95 int find_capability( pci_info *pcii, uint8 capability ) 96 { 97 int try_count; 98 uint16 status; 99 uint8 pos; 100 101 // check whether PCI capabilities are supported at all 102 status = get_pci( PCI_status, 2 ); 103 104 if( (status & PCI_status_cap_list) == 0 ) 105 return B_NAME_NOT_FOUND; 106 107 SHOW_FLOW0( 3, "Device supports capabilities" ); 108 109 // get offset of first capability in list 110 switch( pcii->header_type & PCI_header_type_mask ) { 111 case PCI_header_type_normal: 112 case PCI_header_type_bridge: 113 pos = get_pci( PCI_capability_list, 1 ); 114 break; 115 case PCI_header_type_cardbus: 116 pos = get_pci( PCI_cb_capability_list, 1 ); 117 break; 118 default: 119 SHOW_FLOW( 3, "Unknown type (%x)", pcii->header_type & PCI_header_type_mask ); 120 return B_ERROR; 121 } 122 123 // search for whished capability in linked list 124 for( try_count = 48; try_count > 0 && pos >= 0x40; --try_count ) { 125 uint8 id; 126 127 pos &= ~3; 128 129 id = get_pci( pos + PCI_cap_list_id, 1 ); 130 if( id == 0xff ) 131 return B_NAME_NOT_FOUND; 132 133 if( id == capability ) { 134 SHOW_FLOW( 3, "Found capability %d", capability ); 135 return pos; 136 } 137 138 SHOW_FLOW( 3, "Ignored capability %d", id ); 139 140 pos = get_pci( pos + PCI_cap_list_next, 1 ); 141 } 142 143 return B_NAME_NOT_FOUND; 144 } 145 146 147 // fix invalid AGP settings 148 void Radeon_Fix_AGP() 149 { 150 long pci_index; 151 pci_info pci_data, *pcii; 152 153 uint32 common_caps = 154 PCI_agp_status_sba | PCI_agp_status_64bit | PCI_agp_status_fw | 155 PCI_agp_status_rate4 | PCI_agp_status_rate2 | PCI_agp_status_rate1; 156 uint32 read_queue_depth = PCI_agp_status_rq_mask; 157 158 SHOW_FLOW0( 4, "Composing common feature list" ); 159 160 // only required to make get_pci/set_pci working 161 pcii = &pci_data; 162 163 // find common feature set 164 for( pci_index = 0; 165 (*pci_bus->get_nth_pci_info)(pci_index, &pci_data) == B_NO_ERROR; 166 ++pci_index ) 167 { 168 int offset; 169 170 SHOW_FLOW( 3, "Checking bus %d, device %d, function %d (vendor_id=%04x, device_id=%04x):", 171 pcii->bus, pcii->device, pcii->function, 172 pcii->vendor_id, pcii->device_id ); 173 174 offset = find_capability( pcii, PCI_cap_id_agp ); 175 176 if( offset > 0 ) { 177 uint32 agp_status, agp_command; 178 179 agp_status = get_pci( offset + PCI_agp_status, 4 ); 180 agp_command = get_pci( offset + PCI_agp_command, 4 ); 181 182 SHOW_FLOW( 3, "bus %d, device %d, function %d (vendor_id=%04x, device_id=%04x):", 183 pcii->bus, pcii->device, pcii->function, 184 pcii->vendor_id, pcii->device_id ); 185 show_agp_status( agp_status ); 186 show_agp_command( agp_command ); 187 188 common_caps &= agp_status; 189 read_queue_depth = min( read_queue_depth, agp_status & PCI_agp_status_rq_mask ); 190 } 191 } 192 193 SHOW_FLOW0( 3, "Combined:" ); 194 show_agp_command( common_caps ); 195 196 // choose features that all devices support 197 for( pci_index = 0; 198 (*pci_bus->get_nth_pci_info)(pci_index, &pci_data) == B_NO_ERROR; 199 ++pci_index ) 200 { 201 int offset; 202 203 offset = find_capability( pcii, PCI_cap_id_agp ); 204 205 if( offset > 0 ) { 206 SHOW_FLOW( 3, "Modifying bus %d, device %d, function %d (vendor_id=%04x, device_id=%04x):", 207 pcii->bus, pcii->device, pcii->function, 208 pcii->vendor_id, pcii->device_id ); 209 210 set_pci( offset + PCI_agp_command, 4, common_caps | read_queue_depth ); 211 } 212 } 213 } 214