1 /* 2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* radeon_cp.c -- CP support for Radeon -*- linux-c -*- */ 7 /* 8 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. 9 * Copyright 2000 VA Linux Systems, Inc., Fremont, California. 10 * All Rights Reserved. 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a 13 * copy of this software and associated documentation files (the "Software"), 14 * to deal in the Software without restriction, including without limitation 15 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 16 * and/or sell copies of the Software, and to permit persons to whom the 17 * Software is furnished to do so, subject to the following conditions: 18 * 19 * The above copyright notice and this permission notice (including the next 20 * paragraph) shall be included in all copies or substantial portions of the 21 * Software. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 26 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 27 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 28 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 29 * DEALINGS IN THE SOFTWARE. 30 * 31 * Authors: 32 * Kevin E. Martin <martin@valinux.com> 33 * Gareth Hughes <gareth@valinux.com> 34 */ 35 36 #pragma ident "%Z%%M% %I% %E% SMI" 37 38 #include "drmP.h" 39 #include "drm.h" 40 #include "radeon_drm.h" 41 #include "radeon_drv.h" 42 #include "r300_reg.h" 43 #include "radeon_io32.h" 44 45 static int radeon_do_cleanup_cp(drm_device_t *dev); 46 47 /* CP microcode (from ATI) */ 48 static const u32 R200_cp_microcode[][2] = { 49 {0x21007000, 0000000000}, 50 {0x20007000, 0000000000}, 51 {0x000000ab, 0x00000004}, 52 {0x000000af, 0x00000004}, 53 {0x66544a49, 0000000000}, 54 {0x49494174, 0000000000}, 55 {0x54517d83, 0000000000}, 56 {0x498d8b64, 0000000000}, 57 {0x49494949, 0000000000}, 58 {0x49da493c, 0000000000}, 59 {0x49989898, 0000000000}, 60 {0xd34949d5, 0000000000}, 61 {0x9dc90e11, 0000000000}, 62 {0xce9b9b9b, 0000000000}, 63 {0x000f0000, 0x00000016}, 64 {0x352e232c, 0000000000}, 65 {0x00000013, 0x00000004}, 66 {0x000f0000, 0x00000016}, 67 {0x352e272c, 0000000000}, 68 {0x000f0001, 0x00000016}, 69 {0x3239362f, 0000000000}, 70 {0x000077ef, 0x00000002}, 71 {0x00061000, 0x00000002}, 72 {0x00000020, 0x0000001a}, 73 {0x00004000, 0x0000001e}, 74 {0x00061000, 0x00000002}, 75 {0x00000020, 0x0000001a}, 76 {0x00004000, 0x0000001e}, 77 {0x00061000, 0x00000002}, 78 {0x00000020, 0x0000001a}, 79 {0x00004000, 0x0000001e}, 80 {0x00000016, 0x00000004}, 81 {0x0003802a, 0x00000002}, 82 {0x040067e0, 0x00000002}, 83 {0x00000016, 0x00000004}, 84 {0x000077e0, 0x00000002}, 85 {0x00065000, 0x00000002}, 86 {0x000037e1, 0x00000002}, 87 {0x040067e1, 0x00000006}, 88 {0x000077e0, 0x00000002}, 89 {0x000077e1, 0x00000002}, 90 {0x000077e1, 0x00000006}, 91 {0xffffffff, 0000000000}, 92 {0x10000000, 0000000000}, 93 {0x0003802a, 0x00000002}, 94 {0x040067e0, 0x00000006}, 95 {0x00007675, 0x00000002}, 96 {0x00007676, 0x00000002}, 97 {0x00007677, 0x00000002}, 98 {0x00007678, 0x00000006}, 99 {0x0003802b, 0x00000002}, 100 {0x04002676, 0x00000002}, 101 {0x00007677, 0x00000002}, 102 {0x00007678, 0x00000006}, 103 {0x0000002e, 0x00000018}, 104 {0x0000002e, 0x00000018}, 105 {0000000000, 0x00000006}, 106 {0x0000002f, 0x00000018}, 107 {0x0000002f, 0x00000018}, 108 {0000000000, 0x00000006}, 109 {0x01605000, 0x00000002}, 110 {0x00065000, 0x00000002}, 111 {0x00098000, 0x00000002}, 112 {0x00061000, 0x00000002}, 113 {0x64c0603d, 0x00000004}, 114 {0x00080000, 0x00000016}, 115 {0000000000, 0000000000}, 116 {0x0400251d, 0x00000002}, 117 {0x00007580, 0x00000002}, 118 {0x00067581, 0x00000002}, 119 {0x04002580, 0x00000002}, 120 {0x00067581, 0x00000002}, 121 {0x00000046, 0x00000004}, 122 {0x00005000, 0000000000}, 123 {0x00061000, 0x00000002}, 124 {0x0000750e, 0x00000002}, 125 {0x00019000, 0x00000002}, 126 {0x00011055, 0x00000014}, 127 {0x00000055, 0x00000012}, 128 {0x0400250f, 0x00000002}, 129 {0x0000504a, 0x00000004}, 130 {0x00007565, 0x00000002}, 131 {0x00007566, 0x00000002}, 132 {0x00000051, 0x00000004}, 133 {0x01e655b4, 0x00000002}, 134 {0x4401b0dc, 0x00000002}, 135 {0x01c110dc, 0x00000002}, 136 {0x2666705d, 0x00000018}, 137 {0x040c2565, 0x00000002}, 138 {0x0000005d, 0x00000018}, 139 {0x04002564, 0x00000002}, 140 {0x00007566, 0x00000002}, 141 {0x00000054, 0x00000004}, 142 {0x00401060, 0x00000008}, 143 {0x00101000, 0x00000002}, 144 {0x000d80ff, 0x00000002}, 145 {0x00800063, 0x00000008}, 146 {0x000f9000, 0x00000002}, 147 {0x000e00ff, 0x00000002}, 148 {0000000000, 0x00000006}, 149 {0x00000080, 0x00000018}, 150 {0x00000054, 0x00000004}, 151 {0x00007576, 0x00000002}, 152 {0x00065000, 0x00000002}, 153 {0x00009000, 0x00000002}, 154 {0x00041000, 0x00000002}, 155 {0x0c00350e, 0x00000002}, 156 {0x00049000, 0x00000002}, 157 {0x00051000, 0x00000002}, 158 {0x01e785f8, 0x00000002}, 159 {0x00200000, 0x00000002}, 160 {0x00600073, 0x0000000c}, 161 {0x00007563, 0x00000002}, 162 {0x006075f0, 0x00000021}, 163 {0x20007068, 0x00000004}, 164 {0x00005068, 0x00000004}, 165 {0x00007576, 0x00000002}, 166 {0x00007577, 0x00000002}, 167 {0x0000750e, 0x00000002}, 168 {0x0000750f, 0x00000002}, 169 {0x00a05000, 0x00000002}, 170 {0x00600076, 0x0000000c}, 171 {0x006075f0, 0x00000021}, 172 {0x000075f8, 0x00000002}, 173 {0x00000076, 0x00000004}, 174 {0x000a750e, 0x00000002}, 175 {0x0020750f, 0x00000002}, 176 {0x00600079, 0x00000004}, 177 {0x00007570, 0x00000002}, 178 {0x00007571, 0x00000002}, 179 {0x00007572, 0x00000006}, 180 {0x00005000, 0x00000002}, 181 {0x00a05000, 0x00000002}, 182 {0x00007568, 0x00000002}, 183 {0x00061000, 0x00000002}, 184 {0x00000084, 0x0000000c}, 185 {0x00058000, 0x00000002}, 186 {0x0c607562, 0x00000002}, 187 {0x00000086, 0x00000004}, 188 {0x00600085, 0x00000004}, 189 {0x400070dd, 0000000000}, 190 {0x000380dd, 0x00000002}, 191 {0x00000093, 0x0000001c}, 192 {0x00065095, 0x00000018}, 193 {0x040025bb, 0x00000002}, 194 {0x00061096, 0x00000018}, 195 {0x040075bc, 0000000000}, 196 {0x000075bb, 0x00000002}, 197 {0x000075bc, 0000000000}, 198 {0x00090000, 0x00000006}, 199 {0x00090000, 0x00000002}, 200 {0x000d8002, 0x00000006}, 201 {0x00005000, 0x00000002}, 202 {0x00007821, 0x00000002}, 203 {0x00007800, 0000000000}, 204 {0x00007821, 0x00000002}, 205 {0x00007800, 0000000000}, 206 {0x01665000, 0x00000002}, 207 {0x000a0000, 0x00000002}, 208 {0x000671cc, 0x00000002}, 209 {0x0286f1cd, 0x00000002}, 210 {0x000000a3, 0x00000010}, 211 {0x21007000, 0000000000}, 212 {0x000000aa, 0x0000001c}, 213 {0x00065000, 0x00000002}, 214 {0x000a0000, 0x00000002}, 215 {0x00061000, 0x00000002}, 216 {0x000b0000, 0x00000002}, 217 {0x38067000, 0x00000002}, 218 {0x000a00a6, 0x00000004}, 219 {0x20007000, 0000000000}, 220 {0x01200000, 0x00000002}, 221 {0x20077000, 0x00000002}, 222 {0x01200000, 0x00000002}, 223 {0x20007000, 0000000000}, 224 {0x00061000, 0x00000002}, 225 {0x0120751b, 0x00000002}, 226 {0x8040750a, 0x00000002}, 227 {0x8040750b, 0x00000002}, 228 {0x00110000, 0x00000002}, 229 {0x000380dd, 0x00000002}, 230 {0x000000bd, 0x0000001c}, 231 {0x00061096, 0x00000018}, 232 {0x844075bd, 0x00000002}, 233 {0x00061095, 0x00000018}, 234 {0x840075bb, 0x00000002}, 235 {0x00061096, 0x00000018}, 236 {0x844075bc, 0x00000002}, 237 {0x000000c0, 0x00000004}, 238 {0x804075bd, 0x00000002}, 239 {0x800075bb, 0x00000002}, 240 {0x804075bc, 0x00000002}, 241 {0x00108000, 0x00000002}, 242 {0x01400000, 0x00000002}, 243 {0x006000c4, 0x0000000c}, 244 {0x20c07000, 0x00000020}, 245 {0x000000c6, 0x00000012}, 246 {0x00800000, 0x00000006}, 247 {0x0080751d, 0x00000006}, 248 {0x000025bb, 0x00000002}, 249 {0x000040c0, 0x00000004}, 250 {0x0000775c, 0x00000002}, 251 {0x00a05000, 0x00000002}, 252 {0x00661000, 0x00000002}, 253 {0x0460275d, 0x00000020}, 254 {0x00004000, 0000000000}, 255 {0x00007999, 0x00000002}, 256 {0x00a05000, 0x00000002}, 257 {0x00661000, 0x00000002}, 258 {0x0460299b, 0x00000020}, 259 {0x00004000, 0000000000}, 260 {0x01e00830, 0x00000002}, 261 {0x21007000, 0000000000}, 262 {0x00005000, 0x00000002}, 263 {0x00038042, 0x00000002}, 264 {0x040025e0, 0x00000002}, 265 {0x000075e1, 0000000000}, 266 {0x00000001, 0000000000}, 267 {0x000380d9, 0x00000002}, 268 {0x04007394, 0000000000}, 269 {0000000000, 0000000000}, 270 {0000000000, 0000000000}, 271 {0000000000, 0000000000}, 272 {0000000000, 0000000000}, 273 {0000000000, 0000000000}, 274 {0000000000, 0000000000}, 275 {0000000000, 0000000000}, 276 {0000000000, 0000000000}, 277 {0000000000, 0000000000}, 278 {0000000000, 0000000000}, 279 {0000000000, 0000000000}, 280 {0000000000, 0000000000}, 281 {0000000000, 0000000000}, 282 {0000000000, 0000000000}, 283 {0000000000, 0000000000}, 284 {0000000000, 0000000000}, 285 {0000000000, 0000000000}, 286 {0000000000, 0000000000}, 287 {0000000000, 0000000000}, 288 {0000000000, 0000000000}, 289 {0000000000, 0000000000}, 290 {0000000000, 0000000000}, 291 {0000000000, 0000000000}, 292 {0000000000, 0000000000}, 293 {0000000000, 0000000000}, 294 {0000000000, 0000000000}, 295 {0000000000, 0000000000}, 296 {0000000000, 0000000000}, 297 {0000000000, 0000000000}, 298 {0000000000, 0000000000}, 299 {0000000000, 0000000000}, 300 {0000000000, 0000000000}, 301 {0000000000, 0000000000}, 302 {0000000000, 0000000000}, 303 {0000000000, 0000000000}, 304 {0000000000, 0000000000}, 305 }; 306 307 static const u32 radeon_cp_microcode[][2] = { 308 {0x21007000, 0000000000}, 309 {0x20007000, 0000000000}, 310 {0x000000b4, 0x00000004}, 311 {0x000000b8, 0x00000004}, 312 {0x6f5b4d4c, 0000000000}, 313 {0x4c4c427f, 0000000000}, 314 {0x5b568a92, 0000000000}, 315 {0x4ca09c6d, 0000000000}, 316 {0xad4c4c4c, 0000000000}, 317 {0x4ce1af3d, 0000000000}, 318 {0xd8afafaf, 0000000000}, 319 {0xd64c4cdc, 0000000000}, 320 {0x4cd10d10, 0000000000}, 321 {0x000f0000, 0x00000016}, 322 {0x362f242d, 0000000000}, 323 {0x00000012, 0x00000004}, 324 {0x000f0000, 0x00000016}, 325 {0x362f282d, 0000000000}, 326 {0x000380e7, 0x00000002}, 327 {0x04002c97, 0x00000002}, 328 {0x000f0001, 0x00000016}, 329 {0x333a3730, 0000000000}, 330 {0x000077ef, 0x00000002}, 331 {0x00061000, 0x00000002}, 332 {0x00000021, 0x0000001a}, 333 {0x00004000, 0x0000001e}, 334 {0x00061000, 0x00000002}, 335 {0x00000021, 0x0000001a}, 336 {0x00004000, 0x0000001e}, 337 {0x00061000, 0x00000002}, 338 {0x00000021, 0x0000001a}, 339 {0x00004000, 0x0000001e}, 340 {0x00000017, 0x00000004}, 341 {0x0003802b, 0x00000002}, 342 {0x040067e0, 0x00000002}, 343 {0x00000017, 0x00000004}, 344 {0x000077e0, 0x00000002}, 345 {0x00065000, 0x00000002}, 346 {0x000037e1, 0x00000002}, 347 {0x040067e1, 0x00000006}, 348 {0x000077e0, 0x00000002}, 349 {0x000077e1, 0x00000002}, 350 {0x000077e1, 0x00000006}, 351 {0xffffffff, 0000000000}, 352 {0x10000000, 0000000000}, 353 {0x0003802b, 0x00000002}, 354 {0x040067e0, 0x00000006}, 355 {0x00007675, 0x00000002}, 356 {0x00007676, 0x00000002}, 357 {0x00007677, 0x00000002}, 358 {0x00007678, 0x00000006}, 359 {0x0003802c, 0x00000002}, 360 {0x04002676, 0x00000002}, 361 {0x00007677, 0x00000002}, 362 {0x00007678, 0x00000006}, 363 {0x0000002f, 0x00000018}, 364 {0x0000002f, 0x00000018}, 365 {0000000000, 0x00000006}, 366 {0x00000030, 0x00000018}, 367 {0x00000030, 0x00000018}, 368 {0000000000, 0x00000006}, 369 {0x01605000, 0x00000002}, 370 {0x00065000, 0x00000002}, 371 {0x00098000, 0x00000002}, 372 {0x00061000, 0x00000002}, 373 {0x64c0603e, 0x00000004}, 374 {0x000380e6, 0x00000002}, 375 {0x040025c5, 0x00000002}, 376 {0x00080000, 0x00000016}, 377 {0000000000, 0000000000}, 378 {0x0400251d, 0x00000002}, 379 {0x00007580, 0x00000002}, 380 {0x00067581, 0x00000002}, 381 {0x04002580, 0x00000002}, 382 {0x00067581, 0x00000002}, 383 {0x00000049, 0x00000004}, 384 {0x00005000, 0000000000}, 385 {0x000380e6, 0x00000002}, 386 {0x040025c5, 0x00000002}, 387 {0x00061000, 0x00000002}, 388 {0x0000750e, 0x00000002}, 389 {0x00019000, 0x00000002}, 390 {0x00011055, 0x00000014}, 391 {0x00000055, 0x00000012}, 392 {0x0400250f, 0x00000002}, 393 {0x0000504f, 0x00000004}, 394 {0x000380e6, 0x00000002}, 395 {0x040025c5, 0x00000002}, 396 {0x00007565, 0x00000002}, 397 {0x00007566, 0x00000002}, 398 {0x00000058, 0x00000004}, 399 {0x000380e6, 0x00000002}, 400 {0x040025c5, 0x00000002}, 401 {0x01e655b4, 0x00000002}, 402 {0x4401b0e4, 0x00000002}, 403 {0x01c110e4, 0x00000002}, 404 {0x26667066, 0x00000018}, 405 {0x040c2565, 0x00000002}, 406 {0x00000066, 0x00000018}, 407 {0x04002564, 0x00000002}, 408 {0x00007566, 0x00000002}, 409 {0x0000005d, 0x00000004}, 410 {0x00401069, 0x00000008}, 411 {0x00101000, 0x00000002}, 412 {0x000d80ff, 0x00000002}, 413 {0x0080006c, 0x00000008}, 414 {0x000f9000, 0x00000002}, 415 {0x000e00ff, 0x00000002}, 416 {0000000000, 0x00000006}, 417 {0x0000008f, 0x00000018}, 418 {0x0000005b, 0x00000004}, 419 {0x000380e6, 0x00000002}, 420 {0x040025c5, 0x00000002}, 421 {0x00007576, 0x00000002}, 422 {0x00065000, 0x00000002}, 423 {0x00009000, 0x00000002}, 424 {0x00041000, 0x00000002}, 425 {0x0c00350e, 0x00000002}, 426 {0x00049000, 0x00000002}, 427 {0x00051000, 0x00000002}, 428 {0x01e785f8, 0x00000002}, 429 {0x00200000, 0x00000002}, 430 {0x0060007e, 0x0000000c}, 431 {0x00007563, 0x00000002}, 432 {0x006075f0, 0x00000021}, 433 {0x20007073, 0x00000004}, 434 {0x00005073, 0x00000004}, 435 {0x000380e6, 0x00000002}, 436 {0x040025c5, 0x00000002}, 437 {0x00007576, 0x00000002}, 438 {0x00007577, 0x00000002}, 439 {0x0000750e, 0x00000002}, 440 {0x0000750f, 0x00000002}, 441 {0x00a05000, 0x00000002}, 442 {0x00600083, 0x0000000c}, 443 {0x006075f0, 0x00000021}, 444 {0x000075f8, 0x00000002}, 445 {0x00000083, 0x00000004}, 446 {0x000a750e, 0x00000002}, 447 {0x000380e6, 0x00000002}, 448 {0x040025c5, 0x00000002}, 449 {0x0020750f, 0x00000002}, 450 {0x00600086, 0x00000004}, 451 {0x00007570, 0x00000002}, 452 {0x00007571, 0x00000002}, 453 {0x00007572, 0x00000006}, 454 {0x000380e6, 0x00000002}, 455 {0x040025c5, 0x00000002}, 456 {0x00005000, 0x00000002}, 457 {0x00a05000, 0x00000002}, 458 {0x00007568, 0x00000002}, 459 {0x00061000, 0x00000002}, 460 {0x00000095, 0x0000000c}, 461 {0x00058000, 0x00000002}, 462 {0x0c607562, 0x00000002}, 463 {0x00000097, 0x00000004}, 464 {0x000380e6, 0x00000002}, 465 {0x040025c5, 0x00000002}, 466 {0x00600096, 0x00000004}, 467 {0x400070e5, 0000000000}, 468 {0x000380e6, 0x00000002}, 469 {0x040025c5, 0x00000002}, 470 {0x000380e5, 0x00000002}, 471 {0x000000a8, 0x0000001c}, 472 {0x000650aa, 0x00000018}, 473 {0x040025bb, 0x00000002}, 474 {0x000610ab, 0x00000018}, 475 {0x040075bc, 0000000000}, 476 {0x000075bb, 0x00000002}, 477 {0x000075bc, 0000000000}, 478 {0x00090000, 0x00000006}, 479 {0x00090000, 0x00000002}, 480 {0x000d8002, 0x00000006}, 481 {0x00007832, 0x00000002}, 482 {0x00005000, 0x00000002}, 483 {0x000380e7, 0x00000002}, 484 {0x04002c97, 0x00000002}, 485 {0x00007820, 0x00000002}, 486 {0x00007821, 0x00000002}, 487 {0x00007800, 0000000000}, 488 {0x01200000, 0x00000002}, 489 {0x20077000, 0x00000002}, 490 {0x01200000, 0x00000002}, 491 {0x20007000, 0x00000002}, 492 {0x00061000, 0x00000002}, 493 {0x0120751b, 0x00000002}, 494 {0x8040750a, 0x00000002}, 495 {0x8040750b, 0x00000002}, 496 {0x00110000, 0x00000002}, 497 {0x000380e5, 0x00000002}, 498 {0x000000c6, 0x0000001c}, 499 {0x000610ab, 0x00000018}, 500 {0x844075bd, 0x00000002}, 501 {0x000610aa, 0x00000018}, 502 {0x840075bb, 0x00000002}, 503 {0x000610ab, 0x00000018}, 504 {0x844075bc, 0x00000002}, 505 {0x000000c9, 0x00000004}, 506 {0x804075bd, 0x00000002}, 507 {0x800075bb, 0x00000002}, 508 {0x804075bc, 0x00000002}, 509 {0x00108000, 0x00000002}, 510 {0x01400000, 0x00000002}, 511 {0x006000cd, 0x0000000c}, 512 {0x20c07000, 0x00000020}, 513 {0x000000cf, 0x00000012}, 514 {0x00800000, 0x00000006}, 515 {0x0080751d, 0x00000006}, 516 {0000000000, 0000000000}, 517 {0x0000775c, 0x00000002}, 518 {0x00a05000, 0x00000002}, 519 {0x00661000, 0x00000002}, 520 {0x0460275d, 0x00000020}, 521 {0x00004000, 0000000000}, 522 {0x01e00830, 0x00000002}, 523 {0x21007000, 0000000000}, 524 {0x6464614d, 0000000000}, 525 {0x69687420, 0000000000}, 526 {0x00000073, 0000000000}, 527 {0000000000, 0000000000}, 528 {0x00005000, 0x00000002}, 529 {0x000380d0, 0x00000002}, 530 {0x040025e0, 0x00000002}, 531 {0x000075e1, 0000000000}, 532 {0x00000001, 0000000000}, 533 {0x000380e0, 0x00000002}, 534 {0x04002394, 0x00000002}, 535 {0x00005000, 0000000000}, 536 {0000000000, 0000000000}, 537 {0000000000, 0000000000}, 538 {0x00000008, 0000000000}, 539 {0x00000004, 0000000000}, 540 {0000000000, 0000000000}, 541 {0000000000, 0000000000}, 542 {0000000000, 0000000000}, 543 {0000000000, 0000000000}, 544 {0000000000, 0000000000}, 545 {0000000000, 0000000000}, 546 {0000000000, 0000000000}, 547 {0000000000, 0000000000}, 548 {0000000000, 0000000000}, 549 {0000000000, 0000000000}, 550 {0000000000, 0000000000}, 551 {0000000000, 0000000000}, 552 {0000000000, 0000000000}, 553 {0000000000, 0000000000}, 554 {0000000000, 0000000000}, 555 {0000000000, 0000000000}, 556 {0000000000, 0000000000}, 557 {0000000000, 0000000000}, 558 {0000000000, 0000000000}, 559 {0000000000, 0000000000}, 560 {0000000000, 0000000000}, 561 {0000000000, 0000000000}, 562 {0000000000, 0000000000}, 563 {0000000000, 0000000000}, 564 }; 565 566 static const u32 R300_cp_microcode[][2] = { 567 { 0x4200e000, 0000000000 }, 568 { 0x4000e000, 0000000000 }, 569 { 0x000000af, 0x00000008 }, 570 { 0x000000b3, 0x00000008 }, 571 { 0x6c5a504f, 0000000000 }, 572 { 0x4f4f497a, 0000000000 }, 573 { 0x5a578288, 0000000000 }, 574 { 0x4f91906a, 0000000000 }, 575 { 0x4f4f4f4f, 0000000000 }, 576 { 0x4fe24f44, 0000000000 }, 577 { 0x4f9c9c9c, 0000000000 }, 578 { 0xdc4f4fde, 0000000000 }, 579 { 0xa1cd4f4f, 0000000000 }, 580 { 0xd29d9d9d, 0000000000 }, 581 { 0x4f0f9fd7, 0000000000 }, 582 { 0x000ca000, 0x00000004 }, 583 { 0x000d0012, 0x00000038 }, 584 { 0x0000e8b4, 0x00000004 }, 585 { 0x000d0014, 0x00000038 }, 586 { 0x0000e8b6, 0x00000004 }, 587 { 0x000d0016, 0x00000038 }, 588 { 0x0000e854, 0x00000004 }, 589 { 0x000d0018, 0x00000038 }, 590 { 0x0000e855, 0x00000004 }, 591 { 0x000d001a, 0x00000038 }, 592 { 0x0000e856, 0x00000004 }, 593 { 0x000d001c, 0x00000038 }, 594 { 0x0000e857, 0x00000004 }, 595 { 0x000d001e, 0x00000038 }, 596 { 0x0000e824, 0x00000004 }, 597 { 0x000d0020, 0x00000038 }, 598 { 0x0000e825, 0x00000004 }, 599 { 0x000d0022, 0x00000038 }, 600 { 0x0000e830, 0x00000004 }, 601 { 0x000d0024, 0x00000038 }, 602 { 0x0000f0c0, 0x00000004 }, 603 { 0x000d0026, 0x00000038 }, 604 { 0x0000f0c1, 0x00000004 }, 605 { 0x000d0028, 0x00000038 }, 606 { 0x0000f041, 0x00000004 }, 607 { 0x000d002a, 0x00000038 }, 608 { 0x0000f184, 0x00000004 }, 609 { 0x000d002c, 0x00000038 }, 610 { 0x0000f185, 0x00000004 }, 611 { 0x000d002e, 0x00000038 }, 612 { 0x0000f186, 0x00000004 }, 613 { 0x000d0030, 0x00000038 }, 614 { 0x0000f187, 0x00000004 }, 615 { 0x000d0032, 0x00000038 }, 616 { 0x0000f180, 0x00000004 }, 617 { 0x000d0034, 0x00000038 }, 618 { 0x0000f393, 0x00000004 }, 619 { 0x000d0036, 0x00000038 }, 620 { 0x0000f38a, 0x00000004 }, 621 { 0x000d0038, 0x00000038 }, 622 { 0x0000f38e, 0x00000004 }, 623 { 0x0000e821, 0x00000004 }, 624 { 0x0140a000, 0x00000004 }, 625 { 0x00000043, 0x00000018 }, 626 { 0x00cce800, 0x00000004 }, 627 { 0x001b0001, 0x00000004 }, 628 { 0x08004800, 0x00000004 }, 629 { 0x001b0001, 0x00000004 }, 630 { 0x08004800, 0x00000004 }, 631 { 0x001b0001, 0x00000004 }, 632 { 0x08004800, 0x00000004 }, 633 { 0x0000003a, 0x00000008 }, 634 { 0x0000a000, 0000000000 }, 635 { 0x02c0a000, 0x00000004 }, 636 { 0x000ca000, 0x00000004 }, 637 { 0x00130000, 0x00000004 }, 638 { 0x000c2000, 0x00000004 }, 639 { 0xc980c045, 0x00000008 }, 640 { 0x2000451d, 0x00000004 }, 641 { 0x0000e580, 0x00000004 }, 642 { 0x000ce581, 0x00000004 }, 643 { 0x08004580, 0x00000004 }, 644 { 0x000ce581, 0x00000004 }, 645 { 0x0000004c, 0x00000008 }, 646 { 0x0000a000, 0000000000 }, 647 { 0x000c2000, 0x00000004 }, 648 { 0x0000e50e, 0x00000004 }, 649 { 0x00032000, 0x00000004 }, 650 { 0x00022056, 0x00000028 }, 651 { 0x00000056, 0x00000024 }, 652 { 0x0800450f, 0x00000004 }, 653 { 0x0000a050, 0x00000008 }, 654 { 0x0000e565, 0x00000004 }, 655 { 0x0000e566, 0x00000004 }, 656 { 0x00000057, 0x00000008 }, 657 { 0x03cca5b4, 0x00000004 }, 658 { 0x05432000, 0x00000004 }, 659 { 0x00022000, 0x00000004 }, 660 { 0x4ccce063, 0x00000030 }, 661 { 0x08274565, 0x00000004 }, 662 { 0x00000063, 0x00000030 }, 663 { 0x08004564, 0x00000004 }, 664 { 0x0000e566, 0x00000004 }, 665 { 0x0000005a, 0x00000008 }, 666 { 0x00802066, 0x00000010 }, 667 { 0x00202000, 0x00000004 }, 668 { 0x001b00ff, 0x00000004 }, 669 { 0x01000069, 0x00000010 }, 670 { 0x001f2000, 0x00000004 }, 671 { 0x001c00ff, 0x00000004 }, 672 { 0000000000, 0x0000000c }, 673 { 0x00000085, 0x00000030 }, 674 { 0x0000005a, 0x00000008 }, 675 { 0x0000e576, 0x00000004 }, 676 { 0x000ca000, 0x00000004 }, 677 { 0x00012000, 0x00000004 }, 678 { 0x00082000, 0x00000004 }, 679 { 0x1800650e, 0x00000004 }, 680 { 0x00092000, 0x00000004 }, 681 { 0x000a2000, 0x00000004 }, 682 { 0x000f0000, 0x00000004 }, 683 { 0x00400000, 0x00000004 }, 684 { 0x00000079, 0x00000018 }, 685 { 0x0000e563, 0x00000004 }, 686 { 0x00c0e5f9, 0x000000c2 }, 687 { 0x0000006e, 0x00000008 }, 688 { 0x0000a06e, 0x00000008 }, 689 { 0x0000e576, 0x00000004 }, 690 { 0x0000e577, 0x00000004 }, 691 { 0x0000e50e, 0x00000004 }, 692 { 0x0000e50f, 0x00000004 }, 693 { 0x0140a000, 0x00000004 }, 694 { 0x0000007c, 0x00000018 }, 695 { 0x00c0e5f9, 0x000000c2 }, 696 { 0x0000007c, 0x00000008 }, 697 { 0x0014e50e, 0x00000004 }, 698 { 0x0040e50f, 0x00000004 }, 699 { 0x00c0007f, 0x00000008 }, 700 { 0x0000e570, 0x00000004 }, 701 { 0x0000e571, 0x00000004 }, 702 { 0x0000e572, 0x0000000c }, 703 { 0x0000a000, 0x00000004 }, 704 { 0x0140a000, 0x00000004 }, 705 { 0x0000e568, 0x00000004 }, 706 { 0x000c2000, 0x00000004 }, 707 { 0x00000089, 0x00000018 }, 708 { 0x000b0000, 0x00000004 }, 709 { 0x18c0e562, 0x00000004 }, 710 { 0x0000008b, 0x00000008 }, 711 { 0x00c0008a, 0x00000008 }, 712 { 0x000700e4, 0x00000004 }, 713 { 0x00000097, 0x00000038 }, 714 { 0x000ca099, 0x00000030 }, 715 { 0x080045bb, 0x00000004 }, 716 { 0x000c209a, 0x00000030 }, 717 { 0x0800e5bc, 0000000000 }, 718 { 0x0000e5bb, 0x00000004 }, 719 { 0x0000e5bc, 0000000000 }, 720 { 0x00120000, 0x0000000c }, 721 { 0x00120000, 0x00000004 }, 722 { 0x001b0002, 0x0000000c }, 723 { 0x0000a000, 0x00000004 }, 724 { 0x0000e821, 0x00000004 }, 725 { 0x0000e800, 0000000000 }, 726 { 0x0000e821, 0x00000004 }, 727 { 0x0000e82e, 0000000000 }, 728 { 0x02cca000, 0x00000004 }, 729 { 0x00140000, 0x00000004 }, 730 { 0x000ce1cc, 0x00000004 }, 731 { 0x050de1cd, 0x00000004 }, 732 { 0x000000a7, 0x00000020 }, 733 { 0x4200e000, 0000000000 }, 734 { 0x000000ae, 0x00000038 }, 735 { 0x000ca000, 0x00000004 }, 736 { 0x00140000, 0x00000004 }, 737 { 0x000c2000, 0x00000004 }, 738 { 0x00160000, 0x00000004 }, 739 { 0x700ce000, 0x00000004 }, 740 { 0x001400aa, 0x00000008 }, 741 { 0x4000e000, 0000000000 }, 742 { 0x02400000, 0x00000004 }, 743 { 0x400ee000, 0x00000004 }, 744 { 0x02400000, 0x00000004 }, 745 { 0x4000e000, 0000000000 }, 746 { 0x000c2000, 0x00000004 }, 747 { 0x0240e51b, 0x00000004 }, 748 { 0x0080e50a, 0x00000005 }, 749 { 0x0080e50b, 0x00000005 }, 750 { 0x00220000, 0x00000004 }, 751 { 0x000700e4, 0x00000004 }, 752 { 0x000000c1, 0x00000038 }, 753 { 0x000c209a, 0x00000030 }, 754 { 0x0880e5bd, 0x00000005 }, 755 { 0x000c2099, 0x00000030 }, 756 { 0x0800e5bb, 0x00000005 }, 757 { 0x000c209a, 0x00000030 }, 758 { 0x0880e5bc, 0x00000005 }, 759 { 0x000000c4, 0x00000008 }, 760 { 0x0080e5bd, 0x00000005 }, 761 { 0x0000e5bb, 0x00000005 }, 762 { 0x0080e5bc, 0x00000005 }, 763 { 0x00210000, 0x00000004 }, 764 { 0x02800000, 0x00000004 }, 765 { 0x00c000c8, 0x00000018 }, 766 { 0x4180e000, 0x00000040 }, 767 { 0x000000ca, 0x00000024 }, 768 { 0x01000000, 0x0000000c }, 769 { 0x0100e51d, 0x0000000c }, 770 { 0x000045bb, 0x00000004 }, 771 { 0x000080c4, 0x00000008 }, 772 { 0x0000f3ce, 0x00000004 }, 773 { 0x0140a000, 0x00000004 }, 774 { 0x00cc2000, 0x00000004 }, 775 { 0x08c053cf, 0x00000040 }, 776 { 0x00008000, 0000000000 }, 777 { 0x0000f3d2, 0x00000004 }, 778 { 0x0140a000, 0x00000004 }, 779 { 0x00cc2000, 0x00000004 }, 780 { 0x08c053d3, 0x00000040 }, 781 { 0x00008000, 0000000000 }, 782 { 0x0000f39d, 0x00000004 }, 783 { 0x0140a000, 0x00000004 }, 784 { 0x00cc2000, 0x00000004 }, 785 { 0x08c0539e, 0x00000040 }, 786 { 0x00008000, 0000000000 }, 787 { 0x03c00830, 0x00000004 }, 788 { 0x4200e000, 0000000000 }, 789 { 0x0000a000, 0x00000004 }, 790 { 0x200045e0, 0x00000004 }, 791 { 0x0000e5e1, 0000000000 }, 792 { 0x00000001, 0000000000 }, 793 { 0x000700e1, 0x00000004 }, 794 { 0x0800e394, 0000000000 }, 795 { 0000000000, 0000000000 }, 796 { 0000000000, 0000000000 }, 797 { 0000000000, 0000000000 }, 798 { 0000000000, 0000000000 }, 799 { 0000000000, 0000000000 }, 800 { 0000000000, 0000000000 }, 801 { 0000000000, 0000000000 }, 802 { 0000000000, 0000000000 }, 803 { 0000000000, 0000000000 }, 804 { 0000000000, 0000000000 }, 805 { 0000000000, 0000000000 }, 806 { 0000000000, 0000000000 }, 807 { 0000000000, 0000000000 }, 808 { 0000000000, 0000000000 }, 809 { 0000000000, 0000000000 }, 810 { 0000000000, 0000000000 }, 811 { 0000000000, 0000000000 }, 812 { 0000000000, 0000000000 }, 813 { 0000000000, 0000000000 }, 814 { 0000000000, 0000000000 }, 815 { 0000000000, 0000000000 }, 816 { 0000000000, 0000000000 }, 817 { 0000000000, 0000000000 }, 818 { 0000000000, 0000000000 }, 819 { 0000000000, 0000000000 }, 820 { 0000000000, 0000000000 }, 821 { 0000000000, 0000000000 }, 822 { 0000000000, 0000000000 }, 823 }; 824 825 static int RADEON_READ_PLL(drm_device_t *dev, int addr) 826 { 827 drm_radeon_private_t *dev_priv = dev->dev_private; 828 829 RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f); 830 return (RADEON_READ(RADEON_CLOCK_CNTL_DATA)); 831 } 832 833 static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) 834 { 835 RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); 836 return (RADEON_READ(RADEON_PCIE_DATA)); 837 } 838 839 #if RADEON_FIFO_DEBUG 840 static void radeon_status(drm_radeon_private_t *dev_priv) 841 { 842 cmn_err(CE_NOTE, "RBBM_STATUS = 0x%08x\n", 843 (unsigned int)RADEON_READ(RADEON_RBBM_STATUS)); 844 cmn_err(CE_NOTE, "CP_RB_RTPR = 0x%08x\n", 845 (unsigned int)RADEON_READ(RADEON_CP_RB_RPTR)); 846 cmn_err(CE_NOTE, "CP_RB_WTPR = 0x%08x\n", 847 (unsigned int)RADEON_READ(RADEON_CP_RB_WPTR)); 848 cmn_err(CE_NOTE, "AIC_CNTL = 0x%08x\n", 849 (unsigned int)RADEON_READ(RADEON_AIC_CNTL)); 850 cmn_err(CE_NOTE, "AIC_STAT = 0x%08x\n", 851 (unsigned int)RADEON_READ(RADEON_AIC_STAT)); 852 cmn_err(CE_NOTE, "AIC_PT_BASE = 0x%08x\n", 853 (unsigned int)RADEON_READ(RADEON_AIC_PT_BASE)); 854 cmn_err(CE_NOTE, "TLB_ADDR = 0x%08x\n", 855 (unsigned int)RADEON_READ(RADEON_AIC_TLB_ADDR)); 856 cmn_err(CE_NOTE, "TLB_DATA = 0x%08x\n", 857 (unsigned int)RADEON_READ(RADEON_AIC_TLB_DATA)); 858 } 859 #endif 860 861 /* 862 * Engine, FIFO control 863 */ 864 865 static int radeon_do_pixcache_flush(drm_radeon_private_t *dev_priv) 866 { 867 u32 tmp; 868 int i; 869 870 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 871 872 tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT); 873 tmp |= RADEON_RB3D_DC_FLUSH_ALL; 874 RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp); 875 876 for (i = 0; i < dev_priv->usec_timeout; i++) { 877 if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT) & 878 RADEON_RB3D_DC_BUSY)) { 879 return (0); 880 } 881 DRM_UDELAY(1); 882 } 883 884 #if RADEON_FIFO_DEBUG 885 DRM_ERROR("failed!\n"); 886 radeon_status(dev_priv); 887 #endif 888 return (EBUSY); 889 } 890 891 static int radeon_do_wait_for_fifo(drm_radeon_private_t *dev_priv, int entries) 892 { 893 int i; 894 895 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 896 897 for (i = 0; i < dev_priv->usec_timeout; i++) { 898 int slots = (RADEON_READ(RADEON_RBBM_STATUS) & 899 RADEON_RBBM_FIFOCNT_MASK); 900 if (slots >= entries) 901 return (0); 902 DRM_UDELAY(1); 903 } 904 905 906 DRM_ERROR("radeon_do_wait_for_fifo: failed timeout=%d", 907 dev_priv->usec_timeout); 908 #if RADEON_FIFO_DEBUG 909 radeon_status(dev_priv); 910 #endif 911 return (EBUSY); 912 } 913 914 static int radeon_do_wait_for_idle(drm_radeon_private_t *dev_priv) 915 { 916 int i, ret; 917 918 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 919 920 ret = radeon_do_wait_for_fifo(dev_priv, 64); 921 if (ret) 922 return (ret); 923 924 for (i = 0; i < dev_priv->usec_timeout; i++) { 925 if (!(RADEON_READ(RADEON_RBBM_STATUS) & 926 RADEON_RBBM_ACTIVE)) { 927 (void) radeon_do_pixcache_flush(dev_priv); 928 return (0); 929 } 930 DRM_UDELAY(1); 931 } 932 933 DRM_ERROR("radeon_do_wait_for_idle: failed timeout=%d", 934 dev_priv->usec_timeout); 935 936 #if RADEON_FIFO_DEBUG 937 radeon_status(dev_priv); 938 #endif 939 return (EBUSY); 940 } 941 942 /* 943 * CP control, initialization 944 */ 945 946 /* Load the microcode for the CP */ 947 static void radeon_cp_load_microcode(drm_radeon_private_t *dev_priv) 948 { 949 int i; 950 951 (void) radeon_do_wait_for_idle(dev_priv); 952 953 RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0); 954 955 if (dev_priv->microcode_version == UCODE_R200) { 956 DRM_INFO("Loading R200 Microcode\n"); 957 for (i = 0; i < 256; i++) { 958 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, 959 R200_cp_microcode[i][1]); 960 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, 961 R200_cp_microcode[i][0]); 962 } 963 } else if (dev_priv->microcode_version == UCODE_R300) { 964 DRM_INFO("Loading R300 Microcode\n"); 965 for (i = 0; i < 256; i++) { 966 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, 967 R300_cp_microcode[i][1]); 968 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, 969 R300_cp_microcode[i][0]); 970 } 971 } else { 972 for (i = 0; i < 256; i++) { 973 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, 974 radeon_cp_microcode[i][1]); 975 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, 976 radeon_cp_microcode[i][0]); 977 } 978 } 979 } 980 981 /* 982 * Flush any pending commands to the CP. This should only be used just 983 * prior to a wait for idle, as it informs the engine that the command 984 * stream is ending. 985 */ 986 /*ARGSUSED*/ 987 static void radeon_do_cp_flush(drm_radeon_private_t *dev_priv) 988 { 989 DRM_DEBUG("\n"); 990 991 #if 0 992 u32 tmp; 993 994 tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31); 995 RADEON_WRITE(RADEON_CP_RB_WPTR, tmp); 996 #endif 997 } 998 999 /* Wait for the CP to go idle. */ 1000 int 1001 radeon_do_cp_idle(drm_radeon_private_t *dev_priv) 1002 { 1003 RING_LOCALS; 1004 1005 BEGIN_RING(6); 1006 1007 RADEON_PURGE_CACHE(); 1008 RADEON_PURGE_ZCACHE(); 1009 RADEON_WAIT_UNTIL_IDLE(); 1010 1011 ADVANCE_RING(); 1012 COMMIT_RING(); 1013 1014 return (radeon_do_wait_for_idle(dev_priv)); 1015 } 1016 1017 /* Start the Command Processor. */ 1018 static void radeon_do_cp_start(drm_radeon_private_t *dev_priv) 1019 { 1020 RING_LOCALS; 1021 1022 (void) radeon_do_wait_for_idle(dev_priv); 1023 1024 RADEON_WRITE(RADEON_CP_CSQ_CNTL, dev_priv->cp_mode); 1025 1026 dev_priv->cp_running = 1; 1027 1028 BEGIN_RING(6); 1029 1030 RADEON_PURGE_CACHE(); 1031 RADEON_PURGE_ZCACHE(); 1032 RADEON_WAIT_UNTIL_IDLE(); 1033 1034 ADVANCE_RING(); 1035 COMMIT_RING(); 1036 } 1037 1038 /* 1039 * Reset the Command Processor. This will not flush any pending 1040 * commands, so you must wait for the CP command stream to complete 1041 * before calling this routine. 1042 */ 1043 static void radeon_do_cp_reset(drm_radeon_private_t *dev_priv) 1044 { 1045 u32 cur_read_ptr; 1046 DRM_DEBUG("\n"); 1047 1048 cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR); 1049 RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr); 1050 SET_RING_HEAD(dev_priv, cur_read_ptr); 1051 dev_priv->ring.tail = cur_read_ptr; 1052 } 1053 1054 /* 1055 * Stop the Command Processor. This will not flush any pending 1056 * commands, so you must flush the command stream and wait for the CP 1057 * to go idle before calling this routine. 1058 */ 1059 static void radeon_do_cp_stop(drm_radeon_private_t *dev_priv) 1060 { 1061 DRM_DEBUG("\n"); 1062 1063 RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS); 1064 1065 dev_priv->cp_running = 0; 1066 } 1067 1068 /* Reset the engine. This will stop the CP if it is running. */ 1069 static int radeon_do_engine_reset(drm_device_t *dev) 1070 { 1071 drm_radeon_private_t *dev_priv = dev->dev_private; 1072 u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset; 1073 DRM_DEBUG("\n"); 1074 1075 (void) radeon_do_pixcache_flush(dev_priv); 1076 1077 clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); 1078 mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL); 1079 1080 RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl | 1081 RADEON_FORCEON_MCLKA | 1082 RADEON_FORCEON_MCLKB | 1083 RADEON_FORCEON_YCLKA | 1084 RADEON_FORCEON_YCLKB | 1085 RADEON_FORCEON_MC | 1086 RADEON_FORCEON_AIC)); 1087 1088 rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET); 1089 1090 RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset | 1091 RADEON_SOFT_RESET_CP | 1092 RADEON_SOFT_RESET_HI | 1093 RADEON_SOFT_RESET_SE | 1094 RADEON_SOFT_RESET_RE | 1095 RADEON_SOFT_RESET_PP | 1096 RADEON_SOFT_RESET_E2 | 1097 RADEON_SOFT_RESET_RB)); 1098 (void) RADEON_READ(RADEON_RBBM_SOFT_RESET); 1099 RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & 1100 ~(RADEON_SOFT_RESET_CP | 1101 RADEON_SOFT_RESET_HI | 1102 RADEON_SOFT_RESET_SE | 1103 RADEON_SOFT_RESET_RE | 1104 RADEON_SOFT_RESET_PP | 1105 RADEON_SOFT_RESET_E2 | 1106 RADEON_SOFT_RESET_RB))); 1107 (void) RADEON_READ(RADEON_RBBM_SOFT_RESET); 1108 1109 RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl); 1110 RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); 1111 RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); 1112 1113 /* Reset the CP ring */ 1114 radeon_do_cp_reset(dev_priv); 1115 1116 /* The CP is no longer running after an engine reset */ 1117 dev_priv->cp_running = 0; 1118 1119 /* Reset any pending vertex, indirect buffers */ 1120 radeon_freelist_reset(dev); 1121 1122 return (0); 1123 } 1124 1125 static void 1126 radeon_cp_init_ring_buffer(drm_device_t *dev, drm_radeon_private_t *dev_priv) 1127 { 1128 u32 ring_start, cur_read_ptr; 1129 u32 tmp; 1130 1131 /* 1132 * Initialize the memory controller. With new memory map, the fb 1133 * location is not changed, it should have been properly initialized 1134 * already. Part of the problem is that the code below is bogus, 1135 * assuming the GART is always appended to the fb which is not 1136 * necessarily the case 1137 */ 1138 if (!dev_priv->new_memmap) 1139 RADEON_WRITE(RADEON_MC_FB_LOCATION, 1140 ((dev_priv->gart_vm_start - 1) & 0xffff0000) | 1141 (dev_priv->fb_location >> 16)); 1142 1143 #if __OS_HAS_AGP 1144 if (dev_priv->flags & RADEON_IS_AGP) { 1145 RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); 1146 RADEON_WRITE(RADEON_MC_AGP_LOCATION, 1147 (((dev_priv->gart_vm_start - 1 + 1148 dev_priv->gart_size) & 0xffff0000) | 1149 (dev_priv->gart_vm_start >> 16))); 1150 1151 ring_start = dev_priv->cp_ring->offset - 1152 dev->agp->base + dev_priv->gart_vm_start; 1153 } else 1154 #endif 1155 ring_start = (dev_priv->cp_ring->offset - 1156 (unsigned long)dev->sg->virtual + 1157 dev_priv->gart_vm_start); 1158 1159 RADEON_WRITE(RADEON_CP_RB_BASE, ring_start); 1160 1161 /* Set the write pointer delay */ 1162 RADEON_WRITE(RADEON_CP_RB_WPTR_DELAY, 0); 1163 1164 /* Initialize the ring buffer's read and write pointers */ 1165 cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR); 1166 RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr); 1167 SET_RING_HEAD(dev_priv, cur_read_ptr); 1168 dev_priv->ring.tail = cur_read_ptr; 1169 1170 #if __OS_HAS_AGP 1171 if (dev_priv->flags & RADEON_IS_AGP) { 1172 RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, 1173 dev_priv->ring_rptr->offset - 1174 dev->agp->base + dev_priv->gart_vm_start); 1175 } else 1176 #endif 1177 { 1178 drm_sg_mem_t *entry = dev->sg; 1179 unsigned long tmp_ofs, page_ofs; 1180 1181 tmp_ofs = dev_priv->ring_rptr->offset - 1182 (unsigned long)dev->sg->virtual; 1183 page_ofs = tmp_ofs >> PAGE_SHIFT; 1184 1185 RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]); 1186 DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n", 1187 (unsigned long)entry->busaddr[page_ofs], 1188 entry->handle + tmp_ofs); 1189 } 1190 1191 /* Set ring buffer size */ 1192 #ifdef __BIG_ENDIAN 1193 RADEON_WRITE(RADEON_CP_RB_CNTL, 1194 dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT); 1195 #else 1196 RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw); 1197 #endif 1198 1199 /* Start with assuming that writeback doesn't work */ 1200 dev_priv->writeback_works = 0; 1201 1202 /* 1203 * Initialize the scratch register pointer. This will cause 1204 * the scratch register values to be written out to memory 1205 * whenever they are updated. 1206 * 1207 * We simply put this behind the ring read pointer, this works 1208 * with PCI GART as well as (whatever kind of) AGP GART 1209 */ 1210 RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) 1211 + RADEON_SCRATCH_REG_OFFSET); 1212 1213 dev_priv->scratch = ((__volatile__ u32 *) 1214 dev_priv->ring_rptr->handle + 1215 (RADEON_SCRATCH_REG_OFFSET / sizeof (u32))); 1216 1217 RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); 1218 1219 /* Turn on bus mastering */ 1220 tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; 1221 RADEON_WRITE(RADEON_BUS_CNTL, tmp); 1222 1223 dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; 1224 RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); 1225 1226 dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0; 1227 RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 1228 dev_priv->sarea_priv->last_dispatch); 1229 1230 dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; 1231 RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear); 1232 1233 (void) radeon_do_wait_for_idle(dev_priv); 1234 1235 /* Sync everything up */ 1236 RADEON_WRITE(RADEON_ISYNC_CNTL, 1237 (RADEON_ISYNC_ANY2D_IDLE3D | 1238 RADEON_ISYNC_ANY3D_IDLE2D | 1239 RADEON_ISYNC_WAIT_IDLEGUI | 1240 RADEON_ISYNC_CPSCRATCH_IDLEGUI)); 1241 1242 } 1243 1244 static void radeon_test_writeback(drm_radeon_private_t *dev_priv) 1245 { 1246 #if 0 1247 u32 tmp; 1248 1249 /* 1250 * Writeback doesn't seem to work everywhere, test it here and possibly 1251 * enable it if it appears to work 1252 */ 1253 DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); 1254 RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); 1255 1256 for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { 1257 if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == 1258 0xdeadbeef) 1259 break; 1260 DRM_UDELAY(1); 1261 } 1262 1263 tmp = dev_priv->usec_timeout; 1264 1265 if (tmp < dev_priv->usec_timeout) { 1266 dev_priv->writeback_works = 1; 1267 DRM_INFO("writeback test succeeded in %d usecs\n", tmp); 1268 } else { 1269 dev_priv->writeback_works = 0; 1270 DRM_INFO("writeback test failed\n"); 1271 } 1272 if (radeon_no_wb == 1) { 1273 dev_priv->writeback_works = 0; 1274 DRM_INFO("writeback forced off\n"); 1275 } 1276 #else 1277 /* 1278 * Writeback doesn't work everywhere. And the timeout is so long 1279 * so Xserver needs more time to start itself. But dtlogin doesn't 1280 * want to wait for the timeout, and it just stops Xserver and 1281 * restart it again. As a result, Xserver cannot start. So, we 1282 * just ignore writeback here. 1283 */ 1284 dev_priv->writeback_works = 0; 1285 #endif 1286 1287 if (!dev_priv->writeback_works) { 1288 /* 1289 * Disable writeback to avoid unnecessary bus master 1290 * transfers 1291 */ 1292 RADEON_WRITE(RADEON_CP_RB_CNTL, 1293 RADEON_READ(RADEON_CP_RB_CNTL) | RADEON_RB_NO_UPDATE); 1294 RADEON_WRITE(RADEON_SCRATCH_UMSK, 0); 1295 } 1296 1297 } 1298 1299 /* Enable or disable PCI-E GART on the chip */ 1300 static void radeon_set_pciegart(drm_radeon_private_t *dev_priv, int on) 1301 { 1302 u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); 1303 if (on) { 1304 1305 DRM_DEBUG("programming pcie %08X %08lX %08X\n", 1306 dev_priv->gart_vm_start, 1307 (long)dev_priv->gart_info.bus_addr, 1308 dev_priv->gart_size); 1309 RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, 1310 dev_priv->gart_vm_start); 1311 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, 1312 dev_priv->gart_info.bus_addr); 1313 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, 1314 dev_priv->gart_vm_start); 1315 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO, 1316 dev_priv->gart_vm_start + dev_priv->gart_size - 1); 1317 1318 RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */ 1319 1320 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, 1321 RADEON_PCIE_TX_GART_EN); 1322 } else { 1323 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, 1324 tmp & ~RADEON_PCIE_TX_GART_EN); 1325 } 1326 } 1327 1328 /* Enable or disable PCI GART on the chip */ 1329 static void radeon_set_pcigart(drm_radeon_private_t *dev_priv, int on) 1330 { 1331 u32 tmp; 1332 1333 if (dev_priv->flags & RADEON_IS_PCIE) { 1334 radeon_set_pciegart(dev_priv, on); 1335 return; 1336 } 1337 1338 tmp = RADEON_READ(RADEON_AIC_CNTL); 1339 1340 if (on) { 1341 RADEON_WRITE(RADEON_AIC_CNTL, 1342 tmp | RADEON_PCIGART_TRANSLATE_EN); 1343 1344 /* set PCI GART page-table base address */ 1345 RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr); 1346 1347 /* set address range for PCI address translate */ 1348 RADEON_WRITE(RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start); 1349 RADEON_WRITE(RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start + 1350 dev_priv->gart_size - 1); 1351 1352 /* Turn off AGP aperture -- is this required for PCI GART? */ 1353 RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */ 1354 RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */ 1355 } else { 1356 RADEON_WRITE(RADEON_AIC_CNTL, 1357 tmp & ~RADEON_PCIGART_TRANSLATE_EN); 1358 } 1359 } 1360 1361 static int radeon_do_init_cp(drm_device_t *dev, drm_radeon_init_t *init) 1362 { 1363 drm_radeon_private_t *dev_priv = dev->dev_private; 1364 1365 /* if we require new memory map but we don't have it fail */ 1366 if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { 1367 DRM_ERROR("Cannot initialise DRM on this card\n" 1368 "This card requires a new X.org DDX for 3D\n"); 1369 (void) radeon_do_cleanup_cp(dev); 1370 return (EINVAL); 1371 } 1372 1373 if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { 1374 DRM_DEBUG("Forcing AGP card to PCI mode\n"); 1375 dev_priv->flags &= ~RADEON_IS_AGP; 1376 } else if (!(dev_priv->flags & 1377 (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) && 1378 !init->is_pci) { 1379 DRM_DEBUG("Restoring AGP flag\n"); 1380 dev_priv->flags |= RADEON_IS_AGP; 1381 } 1382 1383 if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) { 1384 DRM_ERROR("PCI GART memory not allocated!\n"); 1385 (void) radeon_do_cleanup_cp(dev); 1386 return (EINVAL); 1387 } 1388 1389 dev_priv->usec_timeout = init->usec_timeout; 1390 if (dev_priv->usec_timeout < 1 || 1391 dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { 1392 (void) radeon_do_cleanup_cp(dev); 1393 return (EINVAL); 1394 } 1395 1396 switch (init->func) { 1397 case RADEON_INIT_R200_CP: 1398 dev_priv->microcode_version = UCODE_R200; 1399 break; 1400 case RADEON_INIT_R300_CP: 1401 dev_priv->microcode_version = UCODE_R300; 1402 break; 1403 default: 1404 dev_priv->microcode_version = UCODE_R100; 1405 } 1406 1407 dev_priv->do_boxes = 0; 1408 dev_priv->cp_mode = init->cp_mode; 1409 1410 /* 1411 * We don't support anything other than bus-mastering ring mode, 1412 * but the ring can be in either AGP or PCI space for the ring 1413 * read pointer. 1414 */ 1415 if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && 1416 (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { 1417 DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); 1418 (void) radeon_do_cleanup_cp(dev); 1419 return (EINVAL); 1420 } 1421 1422 switch (init->fb_bpp) { 1423 case 16: 1424 dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; 1425 break; 1426 case 32: 1427 default: 1428 dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; 1429 break; 1430 } 1431 dev_priv->front_offset = init->front_offset; 1432 dev_priv->front_pitch = init->front_pitch; 1433 dev_priv->back_offset = init->back_offset; 1434 dev_priv->back_pitch = init->back_pitch; 1435 1436 switch (init->depth_bpp) { 1437 case 16: 1438 dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; 1439 break; 1440 case 32: 1441 default: 1442 dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; 1443 break; 1444 } 1445 dev_priv->depth_offset = init->depth_offset; 1446 dev_priv->depth_pitch = init->depth_pitch; 1447 1448 /* 1449 * Hardware state for depth clears. Remove this if/when we no 1450 * longer clear the depth buffer with a 3D rectangle. Hard-code 1451 * all values to prevent unwanted 3D state from slipping through 1452 * and screwing with the clear operation. 1453 */ 1454 dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | 1455 (dev_priv->color_fmt << 10) | 1456 (dev_priv->microcode_version == 1457 UCODE_R100 ? RADEON_ZBLOCK16 : 0)); 1458 1459 dev_priv->depth_clear.rb3d_zstencilcntl = 1460 (dev_priv->depth_fmt | 1461 RADEON_Z_TEST_ALWAYS | 1462 RADEON_STENCIL_TEST_ALWAYS | 1463 RADEON_STENCIL_S_FAIL_REPLACE | 1464 RADEON_STENCIL_ZPASS_REPLACE | 1465 RADEON_STENCIL_ZFAIL_REPLACE | RADEON_Z_WRITE_ENABLE); 1466 1467 dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | 1468 RADEON_BFACE_SOLID | 1469 RADEON_FFACE_SOLID | 1470 RADEON_FLAT_SHADE_VTX_LAST | 1471 RADEON_DIFFUSE_SHADE_FLAT | 1472 RADEON_ALPHA_SHADE_FLAT | 1473 RADEON_SPECULAR_SHADE_FLAT | 1474 RADEON_FOG_SHADE_FLAT | 1475 RADEON_VTX_PIX_CENTER_OGL | 1476 RADEON_ROUND_MODE_TRUNC | 1477 RADEON_ROUND_PREC_8TH_PIX); 1478 1479 DRM_GETSAREA(); 1480 1481 dev_priv->ring_offset = init->ring_offset; 1482 dev_priv->ring_rptr_offset = init->ring_rptr_offset; 1483 dev_priv->buffers_offset = init->buffers_offset; 1484 dev_priv->gart_textures_offset = init->gart_textures_offset; 1485 1486 if (!dev_priv->sarea) { 1487 DRM_ERROR("could not find sarea!\n"); 1488 (void) radeon_do_cleanup_cp(dev); 1489 return (EINVAL); 1490 } 1491 1492 dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); 1493 if (!dev_priv->cp_ring) { 1494 DRM_ERROR("could not find cp ring region, offset=0x%lx\n", 1495 init->ring_offset); 1496 (void) radeon_do_cleanup_cp(dev); 1497 return (EINVAL); 1498 } 1499 dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); 1500 if (!dev_priv->ring_rptr) { 1501 DRM_ERROR("could not find ring read pointer, offset=0x%lx\n", 1502 init->ring_rptr_offset); 1503 (void) radeon_do_cleanup_cp(dev); 1504 return (EINVAL); 1505 } 1506 dev->agp_buffer_token = init->buffers_offset; 1507 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 1508 if (!dev->agp_buffer_map) { 1509 DRM_ERROR("could not find dma buffer region, offset=0x%lx\n", 1510 init->buffers_offset); 1511 (void) radeon_do_cleanup_cp(dev); 1512 return (EINVAL); 1513 } 1514 1515 if (init->gart_textures_offset) { 1516 dev_priv->gart_textures = 1517 drm_core_findmap(dev, init->gart_textures_offset); 1518 if (!dev_priv->gart_textures) { 1519 DRM_ERROR("could not find GART texture region, " 1520 "offset=0x%lx\n", init->gart_textures_offset); 1521 (void) radeon_do_cleanup_cp(dev); 1522 return (EINVAL); 1523 } 1524 } 1525 1526 dev_priv->sarea_priv = (drm_radeon_sarea_t *)(uintptr_t) 1527 ((u8 *)(uintptr_t)dev_priv->sarea->handle + 1528 init->sarea_priv_offset); 1529 1530 #if __OS_HAS_AGP 1531 if (dev_priv->flags & RADEON_IS_AGP) { 1532 drm_core_ioremap(dev_priv->cp_ring, dev); 1533 drm_core_ioremap(dev_priv->ring_rptr, dev); 1534 drm_core_ioremap(dev->agp_buffer_map, dev); 1535 if (!dev_priv->cp_ring->handle || 1536 !dev_priv->ring_rptr->handle || 1537 !dev->agp_buffer_map->handle) { 1538 DRM_ERROR("radeon_do_init_cp: failed to find agp " 1539 "regions," 1540 "cp_ring=0x%x, ring_rptr=0x%x, agp_buf=0x%x", 1541 dev_priv->cp_ring->handle, 1542 dev_priv->ring_rptr->handle, 1543 dev->agp_buffer_map->handle); 1544 (void) radeon_do_cleanup_cp(dev); 1545 return (EINVAL); 1546 } 1547 } else 1548 #endif 1549 { 1550 dev_priv->cp_ring->handle = 1551 (void *)(intptr_t)dev_priv->cp_ring->offset; 1552 dev_priv->ring_rptr->handle = 1553 (void *)(intptr_t)dev_priv->ring_rptr->offset; 1554 dev->agp_buffer_map->handle = 1555 (void *)(intptr_t)dev->agp_buffer_map->offset; 1556 1557 DRM_DEBUG("dev_priv->cp_ring->handle %p\n", 1558 dev_priv->cp_ring->handle); 1559 DRM_DEBUG("dev_priv->ring_rptr->handle %p\n", 1560 dev_priv->ring_rptr->handle); 1561 DRM_DEBUG("dev->agp_buffer_map->handle %p\n", 1562 dev->agp_buffer_map->handle); 1563 } 1564 1565 dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION) & 1566 0xffff) << 16; 1567 dev_priv->fb_size = 1568 ((RADEON_READ(RADEON_MC_FB_LOCATION) & 0xffff0000u) + 0x10000) 1569 - dev_priv->fb_location; 1570 1571 dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | 1572 ((dev_priv->front_offset + dev_priv->fb_location) >> 10)); 1573 1574 dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) | 1575 ((dev_priv->back_offset + dev_priv->fb_location) >> 10)); 1576 1577 dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) | 1578 ((dev_priv->depth_offset + dev_priv->fb_location) >> 10)); 1579 1580 dev_priv->gart_size = init->gart_size; 1581 1582 /* New let's set the memory map ... */ 1583 if (dev_priv->new_memmap) { 1584 u32 base = 0; 1585 1586 DRM_INFO("Setting GART location based on new memory map\n"); 1587 1588 /* 1589 * If using AGP, try to locate the AGP aperture at the same 1590 * location in the card and on the bus, though we have to 1591 * align it down. 1592 */ 1593 #if __OS_HAS_AGP 1594 if (dev_priv->flags & RADEON_IS_AGP) { 1595 base = dev->agp->base; 1596 /* Check if valid */ 1597 if ((base + dev_priv->gart_size - 1) >= 1598 dev_priv->fb_location && 1599 base < (dev_priv->fb_location + 1600 dev_priv->fb_size - 1)) { 1601 DRM_INFO("Can't use AGP base @0x%08lx," 1602 "won't fit\n", dev->agp->base); 1603 base = 0; 1604 } 1605 } 1606 #endif 1607 /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ 1608 if (base == 0) { 1609 base = dev_priv->fb_location + dev_priv->fb_size; 1610 if (base < dev_priv->fb_location || 1611 ((base + dev_priv->gart_size) & 1612 0xfffffffful) < base) 1613 base = dev_priv->fb_location - 1614 dev_priv->gart_size; 1615 } 1616 dev_priv->gart_vm_start = base & 0xffc00000u; 1617 if (dev_priv->gart_vm_start != base) 1618 DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", 1619 base, dev_priv->gart_vm_start); 1620 } else { 1621 DRM_INFO("Setting GART location based on old memory map\n"); 1622 dev_priv->gart_vm_start = dev_priv->fb_location + 1623 RADEON_READ(RADEON_CONFIG_APER_SIZE); 1624 } 1625 1626 #if __OS_HAS_AGP 1627 if (dev_priv->flags & RADEON_IS_AGP) 1628 dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - 1629 dev->agp->base + dev_priv->gart_vm_start); 1630 else 1631 #endif 1632 dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - 1633 (unsigned long)dev->sg->virtual + dev_priv->gart_vm_start); 1634 1635 DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); 1636 DRM_DEBUG("dev_priv->gart_vm_start 0x%x\n", dev_priv->gart_vm_start); 1637 DRM_DEBUG("dev_priv->gart_buffers_offset 0x%lx\n", 1638 dev_priv->gart_buffers_offset); 1639 1640 dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle; 1641 dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle + 1642 init->ring_size / sizeof (u32)); 1643 dev_priv->ring.size = init->ring_size; 1644 dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); 1645 1646 dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof (u32)) - 1; 1647 1648 dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; 1649 1650 #if __OS_HAS_AGP 1651 if (dev_priv->flags & RADEON_IS_AGP) { 1652 /* Turn off PCI GART */ 1653 radeon_set_pcigart(dev_priv, 0); 1654 } else 1655 #endif 1656 { 1657 /* if we have an offset set from userspace */ 1658 if (dev_priv->pcigart_offset) { 1659 dev_priv->gart_info.bus_addr = 1660 dev_priv->pcigart_offset + dev_priv->fb_location; 1661 dev_priv->gart_info.mapping.offset = 1662 dev_priv->gart_info.bus_addr; 1663 dev_priv->gart_info.mapping.size = 1664 RADEON_PCIGART_TABLE_SIZE; 1665 1666 drm_core_ioremap(&dev_priv->gart_info.mapping, dev); 1667 dev_priv->gart_info.addr = 1668 dev_priv->gart_info.mapping.handle; 1669 1670 dev_priv->gart_info.is_pcie = 1671 !!(dev_priv->flags & RADEON_IS_PCIE); 1672 dev_priv->gart_info.gart_table_location = 1673 DRM_ATI_GART_FB; 1674 1675 DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", 1676 dev_priv->gart_info.addr, dev_priv->pcigart_offset); 1677 } else { 1678 dev_priv->gart_info.gart_table_location = 1679 DRM_ATI_GART_MAIN; 1680 dev_priv->gart_info.addr = NULL; 1681 dev_priv->gart_info.bus_addr = 0; 1682 if (dev_priv->flags & RADEON_IS_PCIE) { 1683 DRM_ERROR("Cannot use PCI Express without " 1684 "GART in FB memory\n"); 1685 (void) radeon_do_cleanup_cp(dev); 1686 return (EINVAL); 1687 } 1688 } 1689 1690 if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { 1691 DRM_ERROR("failed to init PCI GART!\n"); 1692 (void) radeon_do_cleanup_cp(dev); 1693 return (ENOMEM); 1694 } 1695 1696 /* Turn on PCI GART */ 1697 radeon_set_pcigart(dev_priv, 1); 1698 } 1699 1700 radeon_cp_load_microcode(dev_priv); 1701 radeon_cp_init_ring_buffer(dev, dev_priv); 1702 1703 dev_priv->last_buf = 0; 1704 1705 (void) radeon_do_engine_reset(dev); 1706 radeon_test_writeback(dev_priv); 1707 1708 return (0); 1709 } 1710 1711 static int radeon_do_cleanup_cp(drm_device_t *dev) 1712 { 1713 drm_radeon_private_t *dev_priv = dev->dev_private; 1714 1715 /* 1716 * Make sure interrupts are disabled here because the uninstall ioctl 1717 * may not have been called from userspace and after dev_private 1718 * is freed, it's too late. 1719 */ 1720 if (dev->irq_enabled) 1721 (void) drm_irq_uninstall(dev); 1722 1723 #if __OS_HAS_AGP 1724 if (dev_priv->flags & RADEON_IS_AGP) { 1725 if (dev_priv->cp_ring != NULL) { 1726 drm_core_ioremapfree(dev_priv->cp_ring, dev); 1727 dev_priv->cp_ring = NULL; 1728 } 1729 if (dev_priv->ring_rptr != NULL) { 1730 drm_core_ioremapfree(dev_priv->ring_rptr, dev); 1731 dev_priv->ring_rptr = NULL; 1732 } 1733 if (dev->agp_buffer_map != NULL) { 1734 drm_core_ioremapfree(dev->agp_buffer_map, dev); 1735 dev->agp_buffer_map = NULL; 1736 } 1737 } else 1738 #endif 1739 { 1740 1741 if (dev_priv->gart_info.bus_addr) { 1742 /* Turn off PCI GART */ 1743 radeon_set_pcigart(dev_priv, 0); 1744 if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) 1745 DRM_ERROR("failed to cleanup PCI GART!\n"); 1746 } 1747 1748 if (dev_priv->gart_info.gart_table_location == 1749 DRM_ATI_GART_FB) { 1750 drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); 1751 dev_priv->gart_info.addr = 0; 1752 } 1753 } 1754 /* only clear to the start of flags */ 1755 (void) memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); 1756 1757 return (0); 1758 } 1759 1760 /* 1761 * This code will reinit the Radeon CP hardware after a resume from disc. 1762 * AFAIK, it would be very difficult to pickle the state at suspend time, so 1763 * here we make sure that all Radeon hardware initialisation is re-done without 1764 * affecting running applications. 1765 * 1766 * Charl P. Botha <http://cpbotha.net> 1767 */ 1768 static int radeon_do_resume_cp(drm_device_t *dev) 1769 { 1770 drm_radeon_private_t *dev_priv = dev->dev_private; 1771 1772 if (!dev_priv) { 1773 DRM_ERROR("Called with no initialization\n"); 1774 return (EINVAL); 1775 } 1776 1777 DRM_DEBUG("Starting radeon_do_resume_cp()\n"); 1778 1779 #if __OS_HAS_AGP 1780 if (dev_priv->flags & RADEON_IS_AGP) { 1781 /* Turn off PCI GART */ 1782 radeon_set_pcigart(dev_priv, 0); 1783 } else 1784 #endif 1785 { 1786 /* Turn on PCI GART */ 1787 radeon_set_pcigart(dev_priv, 1); 1788 } 1789 1790 radeon_cp_load_microcode(dev_priv); 1791 radeon_cp_init_ring_buffer(dev, dev_priv); 1792 1793 (void) radeon_do_engine_reset(dev); 1794 1795 DRM_DEBUG("radeon_do_resume_cp() complete\n"); 1796 1797 return (0); 1798 } 1799 1800 /*ARGSUSED*/ 1801 int 1802 radeon_cp_init(DRM_IOCTL_ARGS) 1803 { 1804 DRM_DEVICE; 1805 drm_radeon_init_t init; 1806 1807 1808 LOCK_TEST_WITH_RETURN(dev, fpriv); 1809 1810 #ifdef _MULTI_DATAMODEL 1811 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) { 1812 drm_radeon_init_32_t init32; 1813 1814 DRM_COPYFROM_WITH_RETURN(&init32, (void *) data, 1815 sizeof (init32)); 1816 init.func = init32.func; 1817 init.sarea_priv_offset = init32.sarea_priv_offset; 1818 init.is_pci = init32.is_pci; 1819 init.cp_mode = init32.cp_mode; 1820 init.gart_size = init32.gart_size; 1821 init.ring_size = init32.ring_size; 1822 init.usec_timeout = init32.usec_timeout; 1823 init.fb_bpp = init32.fb_bpp; 1824 init.front_offset = init32.front_offset; 1825 init.front_pitch = init32.front_pitch; 1826 init.back_offset = init32.back_offset; 1827 init.back_pitch = init32.back_pitch; 1828 init.depth_bpp = init32.depth_bpp; 1829 init.depth_offset = init32.depth_offset; 1830 init.depth_pitch = init32.depth_pitch; 1831 init.ring_offset = init32.ring_offset; 1832 init.ring_rptr_offset = init32.ring_rptr_offset; 1833 init.buffers_offset = init32.buffers_offset; 1834 init.gart_textures_offset = init32.gart_textures_offset; 1835 } else { 1836 #endif 1837 DRM_COPYFROM_WITH_RETURN(&init, (void *) data, sizeof (init)); 1838 #ifdef _MULTI_DATAMODEL 1839 } 1840 #endif 1841 1842 if (init.func == RADEON_INIT_R300_CP) 1843 r300_init_reg_flags(); 1844 1845 switch (init.func) { 1846 case RADEON_INIT_CP: 1847 case RADEON_INIT_R200_CP: 1848 case RADEON_INIT_R300_CP: 1849 return (radeon_do_init_cp(dev, &init)); 1850 case RADEON_CLEANUP_CP: 1851 return (radeon_do_cleanup_cp(dev)); 1852 } 1853 1854 return (EINVAL); 1855 } 1856 1857 /*ARGSUSED*/ 1858 int 1859 radeon_cp_start(DRM_IOCTL_ARGS) 1860 { 1861 DRM_DEVICE; 1862 drm_radeon_private_t *dev_priv = dev->dev_private; 1863 1864 LOCK_TEST_WITH_RETURN(dev, fpriv); 1865 1866 if (dev_priv->cp_running) { 1867 return (0); 1868 } 1869 if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) { 1870 DRM_DEBUG("called with bogus CP mode (%d)\n", 1871 dev_priv->cp_mode); 1872 return (0); 1873 } 1874 1875 radeon_do_cp_start(dev_priv); 1876 1877 return (0); 1878 } 1879 1880 /* 1881 * Stop the CP. The engine must have been idled before calling this 1882 * routine. 1883 */ 1884 /*ARGSUSED*/ 1885 int 1886 radeon_cp_stop(DRM_IOCTL_ARGS) 1887 { 1888 DRM_DEVICE; 1889 drm_radeon_private_t *dev_priv = dev->dev_private; 1890 drm_radeon_cp_stop_t stop; 1891 int ret; 1892 1893 LOCK_TEST_WITH_RETURN(dev, fpriv); 1894 1895 DRM_COPYFROM_WITH_RETURN(&stop, (void *) data, sizeof (stop)); 1896 1897 if (!dev_priv->cp_running) 1898 return (0); 1899 1900 /* 1901 * Flush any pending CP commands. This ensures any outstanding 1902 * commands are exectuted by the engine before we turn it off. 1903 */ 1904 if (stop.flush) { 1905 radeon_do_cp_flush(dev_priv); 1906 } 1907 1908 /* 1909 * If we fail to make the engine go idle, we return an error 1910 * code so that the DRM ioctl wrapper can try again. 1911 */ 1912 if (stop.idle) { 1913 ret = radeon_do_cp_idle(dev_priv); 1914 if (ret) 1915 return (ret); 1916 } 1917 1918 /* 1919 * Finally, we can turn off the CP. If the engine isn't idle, 1920 * we will get some dropped triangles as they won't be fully 1921 * rendered before the CP is shut down. 1922 */ 1923 radeon_do_cp_stop(dev_priv); 1924 1925 /* Reset the engine */ 1926 (void) radeon_do_engine_reset(dev); 1927 1928 return (0); 1929 } 1930 1931 void 1932 radeon_do_release(drm_device_t *dev) 1933 { 1934 drm_radeon_private_t *dev_priv = dev->dev_private; 1935 int i, ret; 1936 1937 if (dev_priv) { 1938 if (dev_priv->cp_running) { 1939 /* Stop the cp */ 1940 while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { 1941 DRM_DEBUG("radeon_do_cp_idle %d\n", ret); 1942 #ifdef __linux__ 1943 schedule(); 1944 #else 1945 #if defined(__FreeBSD__) && __FreeBSD_version > 500000 1946 msleep(&ret, &dev->dev_lock, PZERO, 1947 "rdnrel", 1); 1948 #else 1949 #if defined(__SOLARIS__) || defined(sun) 1950 (void) drv_usectohz(5); 1951 #else 1952 tsleep(&ret, PZERO, "rdnrel", 1); 1953 #endif 1954 #endif 1955 #endif 1956 } 1957 radeon_do_cp_stop(dev_priv); 1958 (void) radeon_do_engine_reset(dev); 1959 } 1960 1961 /* Disable *all* interrupts */ 1962 /* remove this after permanent addmaps */ 1963 if (dev_priv->mmio) 1964 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); 1965 1966 if (dev_priv->mmio) { /* remove all surfaces */ 1967 for (i = 0; i < RADEON_MAX_SURFACES; i++) { 1968 RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); 1969 RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 1970 16 * i, 0); 1971 RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 1972 16 * i, 0); 1973 } 1974 } 1975 1976 /* Free memory heap structures */ 1977 radeon_mem_takedown(&(dev_priv->gart_heap)); 1978 radeon_mem_takedown(&(dev_priv->fb_heap)); 1979 1980 /* deallocate kernel resources */ 1981 (void) radeon_do_cleanup_cp(dev); 1982 } 1983 } 1984 1985 /* Just reset the CP ring. Called as part of an X Server engine reset. */ 1986 /*ARGSUSED*/ 1987 int 1988 radeon_cp_reset(DRM_IOCTL_ARGS) 1989 { 1990 DRM_DEVICE; 1991 drm_radeon_private_t *dev_priv = dev->dev_private; 1992 1993 LOCK_TEST_WITH_RETURN(dev, fpriv); 1994 1995 if (!dev_priv) { 1996 DRM_DEBUG("radeon_cp_reset called before init done\n"); 1997 return (EINVAL); 1998 } 1999 2000 radeon_do_cp_reset(dev_priv); 2001 2002 /* The CP is no longer running after an engine reset */ 2003 dev_priv->cp_running = 0; 2004 2005 return (0); 2006 } 2007 2008 /*ARGSUSED*/ 2009 int 2010 radeon_cp_idle(DRM_IOCTL_ARGS) 2011 { 2012 DRM_DEVICE; 2013 drm_radeon_private_t *dev_priv = dev->dev_private; 2014 2015 LOCK_TEST_WITH_RETURN(dev, fpriv); 2016 2017 return (radeon_do_cp_idle(dev_priv)); 2018 } 2019 2020 /* Added by Charl P. Botha to call radeon_do_resume_cp(). */ 2021 /*ARGSUSED*/ 2022 int 2023 radeon_cp_resume(DRM_IOCTL_ARGS) 2024 { 2025 DRM_DEVICE; 2026 2027 return (radeon_do_resume_cp(dev)); 2028 } 2029 2030 /*ARGSUSED*/ 2031 int 2032 radeon_engine_reset(DRM_IOCTL_ARGS) 2033 { 2034 DRM_DEVICE; 2035 2036 LOCK_TEST_WITH_RETURN(dev, fpriv); 2037 2038 return (radeon_do_engine_reset(dev)); 2039 } 2040 2041 /* 2042 * Fullscreen mode 2043 */ 2044 2045 /* KW: Deprecated to say the least: */ 2046 /*ARGSUSED*/ 2047 int 2048 radeon_fullscreen(DRM_IOCTL_ARGS) 2049 { 2050 return (0); 2051 } 2052 2053 /* 2054 * Freelist management 2055 */ 2056 2057 /* 2058 * Original comment: FIXME: ROTATE_BUFS is a hack to cycle through 2059 * bufs until freelist code is used. Note this hides a problem with 2060 * the scratch register * (used to keep track of last buffer 2061 * completed) being written to before * the last buffer has actually 2062 * completed rendering. 2063 * 2064 * KW: It's also a good way to find free buffers quickly. 2065 * 2066 * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't 2067 * sleep. However, bugs in older versions of radeon_accel.c mean that 2068 * we essentially have to do this, else old clients will break. 2069 * 2070 * However, it does leave open a potential deadlock where all the 2071 * buffers are held by other clients, which can't release them because 2072 * they can't get the lock. 2073 */ 2074 2075 drm_buf_t * 2076 radeon_freelist_get(drm_device_t *dev) 2077 { 2078 drm_device_dma_t *dma = dev->dma; 2079 drm_radeon_private_t *dev_priv = dev->dev_private; 2080 drm_radeon_buf_priv_t *buf_priv; 2081 drm_buf_t *buf; 2082 int i, t; 2083 int start; 2084 2085 if (++dev_priv->last_buf >= dma->buf_count) 2086 dev_priv->last_buf = 0; 2087 2088 start = dev_priv->last_buf; 2089 2090 for (t = 0; t < dev_priv->usec_timeout; t++) { 2091 u32 done_age = GET_SCRATCH(1); 2092 DRM_DEBUG("done_age = %d\n", done_age); 2093 for (i = start; i < dma->buf_count; i++) { 2094 buf = dma->buflist[i]; 2095 buf_priv = buf->dev_private; 2096 if (buf->filp == 0 || (buf->pending && 2097 buf_priv->age <= done_age)) { 2098 dev_priv->stats.requested_bufs++; 2099 buf->pending = 0; 2100 return (buf); 2101 } 2102 start = 0; 2103 } 2104 2105 if (t) { 2106 DRM_UDELAY(1); 2107 dev_priv->stats.freelist_loops++; 2108 } 2109 } 2110 2111 DRM_DEBUG("returning NULL!\n"); 2112 return (NULL); 2113 } 2114 2115 #if 0 2116 drm_buf_t * 2117 radeon_freelist_get(drm_device_t *dev) 2118 { 2119 drm_device_dma_t *dma = dev->dma; 2120 drm_radeon_private_t *dev_priv = dev->dev_private; 2121 drm_radeon_buf_priv_t *buf_priv; 2122 drm_buf_t *buf; 2123 int i, t; 2124 int start; 2125 u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); 2126 2127 if (++dev_priv->last_buf >= dma->buf_count) 2128 dev_priv->last_buf = 0; 2129 2130 start = dev_priv->last_buf; 2131 dev_priv->stats.freelist_loops++; 2132 2133 for (t = 0; t < 2; t++) { 2134 for (i = start; i < dma->buf_count; i++) { 2135 buf = dma->buflist[i]; 2136 buf_priv = buf->dev_private; 2137 if (buf->filp == 0 || (buf->pending && 2138 buf_priv->age <= done_age)) { 2139 dev_priv->stats.requested_bufs++; 2140 buf->pending = 0; 2141 return (buf); 2142 } 2143 } 2144 start = 0; 2145 } 2146 2147 return (NULL); 2148 } 2149 #endif 2150 2151 void 2152 radeon_freelist_reset(drm_device_t *dev) 2153 { 2154 drm_device_dma_t *dma = dev->dma; 2155 drm_radeon_private_t *dev_priv = dev->dev_private; 2156 int i; 2157 2158 dev_priv->last_buf = 0; 2159 for (i = 0; i < dma->buf_count; i++) { 2160 drm_buf_t *buf = dma->buflist[i]; 2161 drm_radeon_buf_priv_t *buf_priv = buf->dev_private; 2162 buf_priv->age = 0; 2163 } 2164 } 2165 2166 /* 2167 * CP command submission 2168 */ 2169 int 2170 radeon_wait_ring(drm_radeon_private_t *dev_priv, int n) 2171 { 2172 drm_radeon_ring_buffer_t *ring = &dev_priv->ring; 2173 int i; 2174 u32 last_head = GET_RING_HEAD(dev_priv); 2175 2176 for (i = 0; i < dev_priv->usec_timeout; i++) { 2177 u32 head = GET_RING_HEAD(dev_priv); 2178 2179 ring->space = (head - ring->tail) * sizeof (u32); 2180 if (ring->space <= 0) 2181 ring->space += ring->size; 2182 if (ring->space > n) 2183 return (0); 2184 2185 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 2186 2187 if (head != last_head) 2188 i = 0; 2189 last_head = head; 2190 2191 DRM_UDELAY(1); 2192 } 2193 2194 /* FIXME: This return value is ignored in the BEGIN_RING macro! */ 2195 #if RADEON_FIFO_DEBUG 2196 cmn_err(CE_WARN, "radeon_wait_ring failed\n"); 2197 radeon_status(dev_priv); 2198 DRM_ERROR("failed!\n"); 2199 #endif 2200 return (EBUSY); 2201 } 2202 2203 static int 2204 radeon_cp_get_buffers(drm_file_t *filp, drm_device_t *dev, drm_dma_t *d) 2205 { 2206 int i; 2207 drm_buf_t *buf; 2208 2209 for (i = d->granted_count; i < d->request_count; i++) { 2210 buf = radeon_freelist_get(dev); 2211 if (!buf) 2212 return (EBUSY); /* NOTE: broken client */ 2213 2214 buf->filp = filp; 2215 2216 if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, 2217 sizeof (buf->idx))) 2218 return (EFAULT); 2219 if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, 2220 sizeof (buf->total))) 2221 return (EFAULT); 2222 2223 d->granted_count++; 2224 } 2225 return (0); 2226 } 2227 2228 /*ARGSUSED*/ 2229 int 2230 radeon_cp_buffers(DRM_IOCTL_ARGS) 2231 { 2232 DRM_DEVICE; 2233 drm_device_dma_t *dma = dev->dma; 2234 int ret = 0; 2235 drm_dma_t d; 2236 2237 LOCK_TEST_WITH_RETURN(dev, fpriv); 2238 2239 #ifdef _MULTI_DATAMODEL 2240 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) { 2241 drm_dma_32_t dma32; 2242 2243 DRM_COPYFROM_WITH_RETURN(&dma32, (void *)data, sizeof (dma32)); 2244 d.context = dma32.context; 2245 d.send_count = dma32.send_count; 2246 d.send_indices = (void *)(uintptr_t)dma32.send_indices; 2247 d.send_sizes = (void *)(uintptr_t)dma32.send_sizes; 2248 d.flags = dma32.flags; 2249 d.request_count = dma32.request_count; 2250 d.request_size = dma32.request_size; 2251 d.request_indices = (void *)(uintptr_t)dma32.request_indices; 2252 d.request_sizes = (void *)(uintptr_t)dma32.request_sizes; 2253 d.granted_count = dma32.granted_count; 2254 } else { 2255 #endif 2256 DRM_COPYFROM_WITH_RETURN(&d, (void *)data, sizeof (d)); 2257 #ifdef _MULTI_DATAMODEL 2258 } 2259 #endif 2260 /* Please don't send us buffers. */ 2261 if (d.send_count != 0) { 2262 DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", 2263 DRM_CURRENTPID, d.send_count); 2264 return (EINVAL); 2265 } 2266 2267 /* We'll send you buffers. */ 2268 if (d.request_count < 0 || d.request_count > dma->buf_count) { 2269 DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", 2270 DRM_CURRENTPID, d.request_count, dma->buf_count); 2271 return (EINVAL); 2272 } 2273 2274 d.granted_count = 0; 2275 2276 if (d.request_count) { 2277 ret = radeon_cp_get_buffers(fpriv, dev, &d); 2278 } 2279 2280 #ifdef _MULTI_DATAMODEL 2281 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) { 2282 drm_dma_32_t dma32; 2283 2284 dma32.context = d.context; 2285 dma32.send_count = d.send_count; 2286 dma32.send_indices = (uintptr_t)d.send_indices; 2287 dma32.send_sizes = (uintptr_t)d.send_sizes; 2288 dma32.flags = d.flags; 2289 dma32.request_count = d.request_count; 2290 dma32.request_size = d.request_size; 2291 dma32.request_indices = (uintptr_t)d.request_indices; 2292 dma32.request_sizes = (uintptr_t)d.request_sizes; 2293 dma32.granted_count = d.granted_count; 2294 DRM_COPYTO_WITH_RETURN((void *)data, &dma32, sizeof (dma32)); 2295 } else { 2296 #endif 2297 DRM_COPYTO_WITH_RETURN((void *)data, &d, sizeof (d)); 2298 #ifdef _MULTI_DATAMODEL 2299 } 2300 #endif 2301 return (ret); 2302 } 2303 2304 int 2305 radeon_driver_load(struct drm_device *dev, unsigned long flags) 2306 { 2307 drm_radeon_private_t *dev_priv; 2308 int ret = 0; 2309 2310 dev_priv = drm_alloc(sizeof (drm_radeon_private_t), DRM_MEM_DRIVER); 2311 if (dev_priv == NULL) 2312 return (ENOMEM); 2313 2314 (void) memset(dev_priv, 0, sizeof (drm_radeon_private_t)); 2315 dev->dev_private = (void *)dev_priv; 2316 dev_priv->flags = (int)flags; 2317 2318 switch (flags & RADEON_FAMILY_MASK) { 2319 case CHIP_R100: 2320 case CHIP_RV200: 2321 case CHIP_R200: 2322 case CHIP_R300: 2323 case CHIP_R350: 2324 case CHIP_R420: 2325 case CHIP_RV410: 2326 dev_priv->flags |= RADEON_HAS_HIERZ; 2327 break; 2328 default: 2329 /* all other chips have no hierarchical z buffer */ 2330 break; 2331 } 2332 2333 if (drm_device_is_agp(dev)) 2334 dev_priv->flags |= RADEON_IS_AGP; 2335 else if (drm_device_is_pcie(dev)) 2336 dev_priv->flags |= RADEON_IS_PCIE; 2337 else 2338 dev_priv->flags |= RADEON_IS_PCI; 2339 2340 return (ret); 2341 } 2342 2343 /* 2344 * Create mappings for registers and framebuffer so userland doesn't necessarily 2345 * have to find them. 2346 */ 2347 int 2348 radeon_driver_firstopen(struct drm_device *dev) 2349 { 2350 int ret; 2351 drm_local_map_t *map; 2352 drm_radeon_private_t *dev_priv = dev->dev_private; 2353 2354 /* dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; */ 2355 2356 ret = drm_addmap(dev, (uint_t)drm_get_resource_start(dev, 2), 2357 (uint_t)drm_get_resource_len(dev, 2), _DRM_REGISTERS, 2358 _DRM_READ_ONLY, &dev_priv->mmio); 2359 2360 if (ret != 0) { 2361 cmn_err(CE_WARN, "radeon_driver_firstopen: " 2362 "failed to mmap BAR2 addr=0x%x, len=0x%x", 2363 (uint_t)drm_get_resource_start(dev, 2), 2364 (uint_t)drm_get_resource_len(dev, 2)); 2365 return (ret); 2366 } 2367 2368 ret = drm_addmap(dev, (uint_t)drm_get_resource_start(dev, 0), 2369 (uint_t)drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, 2370 _DRM_WRITE_COMBINING, &map); 2371 if (ret != 0) 2372 return (ret); 2373 2374 return (0); 2375 } 2376 2377 int 2378 radeon_driver_unload(struct drm_device *dev) 2379 { 2380 drm_radeon_private_t *dev_priv = dev->dev_private; 2381 2382 DRM_DEBUG("\n"); 2383 drm_free(dev_priv, sizeof (*dev_priv), DRM_MEM_DRIVER); 2384 2385 dev->dev_private = NULL; 2386 return (0); 2387 } 2388