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_rq_shift 24 41 #define PCI_agp_status_sba 0x0200 /* Sideband addressing supported */ 42 #define PCI_agp_status_64bit 0x0020 /* 64-bit addressing supported */ 43 #define PCI_agp_status_fw 0x0010 /* FW transfers supported */ 44 #define PCI_agp_status_rate4 0x0004 /* 4x transfer rate supported */ 45 #define PCI_agp_status_rate2 0x0002 /* 2x transfer rate supported */ 46 #define PCI_agp_status_rate1 0x0001 /* 1x transfer rate supported */ 47 48 #define PCI_agp_command 8 /* Control register */ 49 #define PCI_agp_command_rq_mask 0xff000000 /* Master: Maximum number of requests */ 50 #define PCI_agp_command_rq_shift 24 51 #define PCI_agp_command_sba 0x0200 /* Sideband addressing enabled */ 52 #define PCI_agp_command_agp 0x0100 /* Allow processing of AGP transactions */ 53 #define PCI_agp_command_64bit 0x0020 /* Allow processing of 64-bit addresses */ 54 #define PCI_agp_command_fw 0x0010 /* Force FW transfers */ 55 #define PCI_agp_command_rate4 0x0004 /* Use 4x rate */ 56 #define PCI_agp_command_rate2 0x0002 /* Use 2x rate */ 57 #define PCI_agp_command_rate1 0x0001 /* Use 1x rate */ 58 59 60 61 // helper macros for easier PCI access 62 #define get_pci(o, s) (*pci_bus->read_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s)) 63 #define set_pci(o, s, v) (*pci_bus->write_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s), (v)) 64 65 66 // show AGP capabilities 67 static void show_agp_status( uint32 status ) 68 { 69 SHOW_FLOW( 3, "Status (%08lx): Max Queue Depth=%ld %s%s%s%s%s%s", status, 70 (status & PCI_agp_status_rq_mask) >> PCI_agp_status_rq_shift, 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): Queue Depth=%ld %s%s%s%s%s%s%s", command, 84 (command & PCI_agp_command_rq_mask) >> PCI_agp_command_rq_shift, 85 (command & PCI_agp_command_sba) != 0 ? "Sideband addressing " : "", 86 (command & PCI_agp_command_agp) != 0 ? "AGP-Enabled " : "AGP-Disabled ", 87 (command & PCI_agp_command_64bit) != 0 ? "64-bit " : "", 88 (command & PCI_agp_command_fw) != 0 ? "FastWrite " : "", 89 (command & PCI_agp_command_rate4) != 0 ? "4x " : "", 90 (command & PCI_agp_command_rate2) != 0 ? "2x " : "", 91 (command & PCI_agp_command_rate1) != 0 ? "1x " : "" ); 92 } 93 94 95 // find PCI capability 96 int find_capability( pci_info *pcii, uint8 capability ) 97 { 98 int try_count; 99 uint16 status; 100 uint8 pos; 101 102 // check whether PCI capabilities are supported at all 103 status = get_pci( PCI_status, 2 ); 104 105 if( (status & PCI_status_cap_list) == 0 ) 106 return B_NAME_NOT_FOUND; 107 108 SHOW_FLOW0( 3, "Device supports capabilities" ); 109 110 // get offset of first capability in list 111 switch( pcii->header_type & PCI_header_type_mask ) { 112 case PCI_header_type_normal: 113 case PCI_header_type_bridge: 114 pos = get_pci( PCI_capability_list, 1 ); 115 break; 116 case PCI_header_type_cardbus: 117 pos = get_pci( PCI_cb_capability_list, 1 ); 118 break; 119 default: 120 SHOW_FLOW( 3, "Unknown type (%x)", pcii->header_type & PCI_header_type_mask ); 121 return B_ERROR; 122 } 123 124 // search for whished capability in linked list 125 for( try_count = 48; try_count > 0 && pos >= 0x40; --try_count ) { 126 uint8 id; 127 128 pos &= ~3; 129 130 id = get_pci( pos + PCI_cap_list_id, 1 ); 131 if( id == 0xff ) 132 return B_NAME_NOT_FOUND; 133 134 if( id == capability ) { 135 SHOW_FLOW( 3, "Found capability %d", capability ); 136 return pos; 137 } 138 139 SHOW_FLOW( 3, "Ignored capability %d", id ); 140 141 pos = get_pci( pos + PCI_cap_list_next, 1 ); 142 } 143 144 return B_NAME_NOT_FOUND; 145 } 146 147 148 // fix invalid AGP settings 149 void Radeon_Fix_AGP(void) 150 { 151 long pci_index; 152 pci_info pci_data, *pcii; 153 154 // start with all features enabled, queue depth bits must be 0 155 uint32 common_caps = 156 PCI_agp_status_sba | PCI_agp_status_64bit | PCI_agp_status_fw | 157 PCI_agp_status_rate4 | PCI_agp_status_rate2 | PCI_agp_status_rate1; 158 uint32 read_queue_depth = PCI_agp_status_rq_mask; 159 160 SHOW_FLOW0( 4, "Composing common feature list" ); 161 162 // only required to make get_pci/set_pci working 163 pcii = &pci_data; 164 165 // find common feature set 166 for( pci_index = 0; 167 (*pci_bus->get_nth_pci_info)(pci_index, &pci_data) == B_NO_ERROR; 168 ++pci_index ) 169 { 170 int offset; 171 172 /*SHOW_FLOW( 3, "Checking bus %d, device %d, function %d (vendor_id=%04x, device_id=%04x):", 173 pcii->bus, pcii->device, pcii->function, 174 pcii->vendor_id, pcii->device_id );*/ 175 176 offset = find_capability( pcii, PCI_cap_id_agp ); 177 178 if( offset > 0 ) { 179 uint32 agp_status, agp_command; 180 181 agp_status = get_pci( offset + PCI_agp_status, 4 ); 182 agp_command = get_pci( offset + PCI_agp_command, 4 ); 183 184 SHOW_FLOW( 3, "bus %d, device %d, function %d (vendor_id=%04x, device_id=%04x):", 185 pcii->bus, pcii->device, pcii->function, 186 pcii->vendor_id, pcii->device_id ); 187 show_agp_status( agp_status ); 188 show_agp_command( agp_command ); 189 190 common_caps &= agp_status; 191 read_queue_depth = min( read_queue_depth, agp_status & PCI_agp_status_rq_mask ); 192 } 193 } 194 195 // explicitely enable AGP - it's not part of status register 196 common_caps |= PCI_agp_command_agp; 197 198 // choose fastest transmission speed and disable lower ones 199 if( (common_caps & PCI_agp_status_rate4) != 0 ) 200 common_caps &= ~(PCI_agp_status_rate2 | PCI_agp_status_rate1); 201 else if( (common_caps & PCI_agp_status_rate2) != 0 ) 202 common_caps &= ~PCI_agp_status_rate1; 203 else if( (common_caps & PCI_agp_status_rate1) == 0 ) 204 // no speed found - disable AGP 205 common_caps &= ~PCI_agp_command_agp; 206 207 common_caps |= read_queue_depth; 208 209 SHOW_FLOW0( 3, "Combined:" ); 210 show_agp_command( common_caps ); 211 212 // choose features that all devices support 213 for( pci_index = 0; 214 (*pci_bus->get_nth_pci_info)(pci_index, &pci_data) == B_NO_ERROR; 215 ++pci_index ) 216 { 217 int offset; 218 219 offset = find_capability( pcii, PCI_cap_id_agp ); 220 221 if( offset > 0 ) { 222 SHOW_FLOW( 3, "Modifying bus %d, device %d, function %d (vendor_id=%04x, device_id=%04x):", 223 pcii->bus, pcii->device, pcii->function, 224 pcii->vendor_id, pcii->device_id ); 225 226 set_pci( offset + PCI_agp_command, 4, common_caps ); 227 } 228 } 229 } 230