radeon_cp.c revision 122580
195584Sanholt/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- 295584Sanholt * 395584Sanholt * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. 495584Sanholt * Copyright 2000 VA Linux Systems, Inc., Fremont, California. 595584Sanholt * All Rights Reserved. 695584Sanholt * 795584Sanholt * Permission is hereby granted, free of charge, to any person obtaining a 895584Sanholt * copy of this software and associated documentation files (the "Software"), 995584Sanholt * to deal in the Software without restriction, including without limitation 1095584Sanholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1195584Sanholt * and/or sell copies of the Software, and to permit persons to whom the 1295584Sanholt * Software is furnished to do so, subject to the following conditions: 1395584Sanholt * 1495584Sanholt * The above copyright notice and this permission notice (including the next 1595584Sanholt * paragraph) shall be included in all copies or substantial portions of the 1695584Sanholt * Software. 1795584Sanholt * 1895584Sanholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1995584Sanholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2095584Sanholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2195584Sanholt * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 2295584Sanholt * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 2395584Sanholt * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2495584Sanholt * DEALINGS IN THE SOFTWARE. 2595584Sanholt * 2695584Sanholt * Authors: 2795584Sanholt * Kevin E. Martin <martin@valinux.com> 2895584Sanholt * Gareth Hughes <gareth@valinux.com> 2995584Sanholt * 3095584Sanholt * $FreeBSD: head/sys/dev/drm/radeon_cp.c 122580 2003-11-12 20:56:30Z anholt $ 3195584Sanholt */ 3295584Sanholt 3395584Sanholt#include "dev/drm/radeon.h" 3495584Sanholt#include "dev/drm/drmP.h" 35112015Sanholt#include "dev/drm/drm.h" 3695746Sanholt#include "dev/drm/radeon_drm.h" 3795584Sanholt#include "dev/drm/radeon_drv.h" 3895584Sanholt 3995584Sanholt#define RADEON_FIFO_DEBUG 0 4095584Sanholt 4195584Sanholt 4295584Sanholt/* CP microcode (from ATI) */ 43112015Sanholtstatic u32 R200_cp_microcode[][2] = { 44112015Sanholt { 0x21007000, 0000000000 }, 45112015Sanholt { 0x20007000, 0000000000 }, 46112015Sanholt { 0x000000ab, 0x00000004 }, 47112015Sanholt { 0x000000af, 0x00000004 }, 48112015Sanholt { 0x66544a49, 0000000000 }, 49112015Sanholt { 0x49494174, 0000000000 }, 50112015Sanholt { 0x54517d83, 0000000000 }, 51112015Sanholt { 0x498d8b64, 0000000000 }, 52112015Sanholt { 0x49494949, 0000000000 }, 53112015Sanholt { 0x49da493c, 0000000000 }, 54112015Sanholt { 0x49989898, 0000000000 }, 55112015Sanholt { 0xd34949d5, 0000000000 }, 56112015Sanholt { 0x9dc90e11, 0000000000 }, 57112015Sanholt { 0xce9b9b9b, 0000000000 }, 58112015Sanholt { 0x000f0000, 0x00000016 }, 59112015Sanholt { 0x352e232c, 0000000000 }, 60112015Sanholt { 0x00000013, 0x00000004 }, 61112015Sanholt { 0x000f0000, 0x00000016 }, 62112015Sanholt { 0x352e272c, 0000000000 }, 63112015Sanholt { 0x000f0001, 0x00000016 }, 64112015Sanholt { 0x3239362f, 0000000000 }, 65112015Sanholt { 0x000077ef, 0x00000002 }, 66112015Sanholt { 0x00061000, 0x00000002 }, 67112015Sanholt { 0x00000020, 0x0000001a }, 68112015Sanholt { 0x00004000, 0x0000001e }, 69112015Sanholt { 0x00061000, 0x00000002 }, 70112015Sanholt { 0x00000020, 0x0000001a }, 71112015Sanholt { 0x00004000, 0x0000001e }, 72112015Sanholt { 0x00061000, 0x00000002 }, 73112015Sanholt { 0x00000020, 0x0000001a }, 74112015Sanholt { 0x00004000, 0x0000001e }, 75112015Sanholt { 0x00000016, 0x00000004 }, 76112015Sanholt { 0x0003802a, 0x00000002 }, 77112015Sanholt { 0x040067e0, 0x00000002 }, 78112015Sanholt { 0x00000016, 0x00000004 }, 79112015Sanholt { 0x000077e0, 0x00000002 }, 80112015Sanholt { 0x00065000, 0x00000002 }, 81112015Sanholt { 0x000037e1, 0x00000002 }, 82112015Sanholt { 0x040067e1, 0x00000006 }, 83112015Sanholt { 0x000077e0, 0x00000002 }, 84112015Sanholt { 0x000077e1, 0x00000002 }, 85112015Sanholt { 0x000077e1, 0x00000006 }, 86112015Sanholt { 0xffffffff, 0000000000 }, 87112015Sanholt { 0x10000000, 0000000000 }, 88112015Sanholt { 0x0003802a, 0x00000002 }, 89112015Sanholt { 0x040067e0, 0x00000006 }, 90112015Sanholt { 0x00007675, 0x00000002 }, 91112015Sanholt { 0x00007676, 0x00000002 }, 92112015Sanholt { 0x00007677, 0x00000002 }, 93112015Sanholt { 0x00007678, 0x00000006 }, 94112015Sanholt { 0x0003802b, 0x00000002 }, 95112015Sanholt { 0x04002676, 0x00000002 }, 96112015Sanholt { 0x00007677, 0x00000002 }, 97112015Sanholt { 0x00007678, 0x00000006 }, 98112015Sanholt { 0x0000002e, 0x00000018 }, 99112015Sanholt { 0x0000002e, 0x00000018 }, 100112015Sanholt { 0000000000, 0x00000006 }, 101112015Sanholt { 0x0000002f, 0x00000018 }, 102112015Sanholt { 0x0000002f, 0x00000018 }, 103112015Sanholt { 0000000000, 0x00000006 }, 104112015Sanholt { 0x01605000, 0x00000002 }, 105112015Sanholt { 0x00065000, 0x00000002 }, 106112015Sanholt { 0x00098000, 0x00000002 }, 107112015Sanholt { 0x00061000, 0x00000002 }, 108112015Sanholt { 0x64c0603d, 0x00000004 }, 109112015Sanholt { 0x00080000, 0x00000016 }, 110112015Sanholt { 0000000000, 0000000000 }, 111112015Sanholt { 0x0400251d, 0x00000002 }, 112112015Sanholt { 0x00007580, 0x00000002 }, 113112015Sanholt { 0x00067581, 0x00000002 }, 114112015Sanholt { 0x04002580, 0x00000002 }, 115112015Sanholt { 0x00067581, 0x00000002 }, 116112015Sanholt { 0x00000046, 0x00000004 }, 117112015Sanholt { 0x00005000, 0000000000 }, 118112015Sanholt { 0x00061000, 0x00000002 }, 119112015Sanholt { 0x0000750e, 0x00000002 }, 120112015Sanholt { 0x00019000, 0x00000002 }, 121112015Sanholt { 0x00011055, 0x00000014 }, 122112015Sanholt { 0x00000055, 0x00000012 }, 123112015Sanholt { 0x0400250f, 0x00000002 }, 124112015Sanholt { 0x0000504a, 0x00000004 }, 125112015Sanholt { 0x00007565, 0x00000002 }, 126112015Sanholt { 0x00007566, 0x00000002 }, 127112015Sanholt { 0x00000051, 0x00000004 }, 128112015Sanholt { 0x01e655b4, 0x00000002 }, 129112015Sanholt { 0x4401b0dc, 0x00000002 }, 130112015Sanholt { 0x01c110dc, 0x00000002 }, 131112015Sanholt { 0x2666705d, 0x00000018 }, 132112015Sanholt { 0x040c2565, 0x00000002 }, 133112015Sanholt { 0x0000005d, 0x00000018 }, 134112015Sanholt { 0x04002564, 0x00000002 }, 135112015Sanholt { 0x00007566, 0x00000002 }, 136112015Sanholt { 0x00000054, 0x00000004 }, 137112015Sanholt { 0x00401060, 0x00000008 }, 138112015Sanholt { 0x00101000, 0x00000002 }, 139112015Sanholt { 0x000d80ff, 0x00000002 }, 140112015Sanholt { 0x00800063, 0x00000008 }, 141112015Sanholt { 0x000f9000, 0x00000002 }, 142112015Sanholt { 0x000e00ff, 0x00000002 }, 143112015Sanholt { 0000000000, 0x00000006 }, 144112015Sanholt { 0x00000080, 0x00000018 }, 145112015Sanholt { 0x00000054, 0x00000004 }, 146112015Sanholt { 0x00007576, 0x00000002 }, 147112015Sanholt { 0x00065000, 0x00000002 }, 148112015Sanholt { 0x00009000, 0x00000002 }, 149112015Sanholt { 0x00041000, 0x00000002 }, 150112015Sanholt { 0x0c00350e, 0x00000002 }, 151112015Sanholt { 0x00049000, 0x00000002 }, 152112015Sanholt { 0x00051000, 0x00000002 }, 153112015Sanholt { 0x01e785f8, 0x00000002 }, 154112015Sanholt { 0x00200000, 0x00000002 }, 155112015Sanholt { 0x00600073, 0x0000000c }, 156112015Sanholt { 0x00007563, 0x00000002 }, 157112015Sanholt { 0x006075f0, 0x00000021 }, 158112015Sanholt { 0x20007068, 0x00000004 }, 159112015Sanholt { 0x00005068, 0x00000004 }, 160112015Sanholt { 0x00007576, 0x00000002 }, 161112015Sanholt { 0x00007577, 0x00000002 }, 162112015Sanholt { 0x0000750e, 0x00000002 }, 163112015Sanholt { 0x0000750f, 0x00000002 }, 164112015Sanholt { 0x00a05000, 0x00000002 }, 165112015Sanholt { 0x00600076, 0x0000000c }, 166112015Sanholt { 0x006075f0, 0x00000021 }, 167112015Sanholt { 0x000075f8, 0x00000002 }, 168112015Sanholt { 0x00000076, 0x00000004 }, 169112015Sanholt { 0x000a750e, 0x00000002 }, 170112015Sanholt { 0x0020750f, 0x00000002 }, 171112015Sanholt { 0x00600079, 0x00000004 }, 172112015Sanholt { 0x00007570, 0x00000002 }, 173112015Sanholt { 0x00007571, 0x00000002 }, 174112015Sanholt { 0x00007572, 0x00000006 }, 175112015Sanholt { 0x00005000, 0x00000002 }, 176112015Sanholt { 0x00a05000, 0x00000002 }, 177112015Sanholt { 0x00007568, 0x00000002 }, 178112015Sanholt { 0x00061000, 0x00000002 }, 179112015Sanholt { 0x00000084, 0x0000000c }, 180112015Sanholt { 0x00058000, 0x00000002 }, 181112015Sanholt { 0x0c607562, 0x00000002 }, 182112015Sanholt { 0x00000086, 0x00000004 }, 183112015Sanholt { 0x00600085, 0x00000004 }, 184112015Sanholt { 0x400070dd, 0000000000 }, 185112015Sanholt { 0x000380dd, 0x00000002 }, 186112015Sanholt { 0x00000093, 0x0000001c }, 187112015Sanholt { 0x00065095, 0x00000018 }, 188112015Sanholt { 0x040025bb, 0x00000002 }, 189112015Sanholt { 0x00061096, 0x00000018 }, 190112015Sanholt { 0x040075bc, 0000000000 }, 191112015Sanholt { 0x000075bb, 0x00000002 }, 192112015Sanholt { 0x000075bc, 0000000000 }, 193112015Sanholt { 0x00090000, 0x00000006 }, 194112015Sanholt { 0x00090000, 0x00000002 }, 195112015Sanholt { 0x000d8002, 0x00000006 }, 196112015Sanholt { 0x00005000, 0x00000002 }, 197112015Sanholt { 0x00007821, 0x00000002 }, 198112015Sanholt { 0x00007800, 0000000000 }, 199112015Sanholt { 0x00007821, 0x00000002 }, 200112015Sanholt { 0x00007800, 0000000000 }, 201112015Sanholt { 0x01665000, 0x00000002 }, 202112015Sanholt { 0x000a0000, 0x00000002 }, 203112015Sanholt { 0x000671cc, 0x00000002 }, 204112015Sanholt { 0x0286f1cd, 0x00000002 }, 205112015Sanholt { 0x000000a3, 0x00000010 }, 206112015Sanholt { 0x21007000, 0000000000 }, 207112015Sanholt { 0x000000aa, 0x0000001c }, 208112015Sanholt { 0x00065000, 0x00000002 }, 209112015Sanholt { 0x000a0000, 0x00000002 }, 210112015Sanholt { 0x00061000, 0x00000002 }, 211112015Sanholt { 0x000b0000, 0x00000002 }, 212112015Sanholt { 0x38067000, 0x00000002 }, 213112015Sanholt { 0x000a00a6, 0x00000004 }, 214112015Sanholt { 0x20007000, 0000000000 }, 215112015Sanholt { 0x01200000, 0x00000002 }, 216112015Sanholt { 0x20077000, 0x00000002 }, 217112015Sanholt { 0x01200000, 0x00000002 }, 218112015Sanholt { 0x20007000, 0000000000 }, 219112015Sanholt { 0x00061000, 0x00000002 }, 220112015Sanholt { 0x0120751b, 0x00000002 }, 221112015Sanholt { 0x8040750a, 0x00000002 }, 222112015Sanholt { 0x8040750b, 0x00000002 }, 223112015Sanholt { 0x00110000, 0x00000002 }, 224112015Sanholt { 0x000380dd, 0x00000002 }, 225112015Sanholt { 0x000000bd, 0x0000001c }, 226112015Sanholt { 0x00061096, 0x00000018 }, 227112015Sanholt { 0x844075bd, 0x00000002 }, 228112015Sanholt { 0x00061095, 0x00000018 }, 229112015Sanholt { 0x840075bb, 0x00000002 }, 230112015Sanholt { 0x00061096, 0x00000018 }, 231112015Sanholt { 0x844075bc, 0x00000002 }, 232112015Sanholt { 0x000000c0, 0x00000004 }, 233112015Sanholt { 0x804075bd, 0x00000002 }, 234112015Sanholt { 0x800075bb, 0x00000002 }, 235112015Sanholt { 0x804075bc, 0x00000002 }, 236112015Sanholt { 0x00108000, 0x00000002 }, 237112015Sanholt { 0x01400000, 0x00000002 }, 238112015Sanholt { 0x006000c4, 0x0000000c }, 239112015Sanholt { 0x20c07000, 0x00000020 }, 240112015Sanholt { 0x000000c6, 0x00000012 }, 241112015Sanholt { 0x00800000, 0x00000006 }, 242112015Sanholt { 0x0080751d, 0x00000006 }, 243112015Sanholt { 0x000025bb, 0x00000002 }, 244112015Sanholt { 0x000040c0, 0x00000004 }, 245112015Sanholt { 0x0000775c, 0x00000002 }, 246112015Sanholt { 0x00a05000, 0x00000002 }, 247112015Sanholt { 0x00661000, 0x00000002 }, 248112015Sanholt { 0x0460275d, 0x00000020 }, 249112015Sanholt { 0x00004000, 0000000000 }, 250112015Sanholt { 0x00007999, 0x00000002 }, 251112015Sanholt { 0x00a05000, 0x00000002 }, 252112015Sanholt { 0x00661000, 0x00000002 }, 253112015Sanholt { 0x0460299b, 0x00000020 }, 254112015Sanholt { 0x00004000, 0000000000 }, 255112015Sanholt { 0x01e00830, 0x00000002 }, 256112015Sanholt { 0x21007000, 0000000000 }, 257112015Sanholt { 0x00005000, 0x00000002 }, 258112015Sanholt { 0x00038042, 0x00000002 }, 259112015Sanholt { 0x040025e0, 0x00000002 }, 260112015Sanholt { 0x000075e1, 0000000000 }, 261112015Sanholt { 0x00000001, 0000000000 }, 262112015Sanholt { 0x000380d9, 0x00000002 }, 263112015Sanholt { 0x04007394, 0000000000 }, 264112015Sanholt { 0000000000, 0000000000 }, 265112015Sanholt { 0000000000, 0000000000 }, 266112015Sanholt { 0000000000, 0000000000 }, 267112015Sanholt { 0000000000, 0000000000 }, 268112015Sanholt { 0000000000, 0000000000 }, 269112015Sanholt { 0000000000, 0000000000 }, 270112015Sanholt { 0000000000, 0000000000 }, 271112015Sanholt { 0000000000, 0000000000 }, 272112015Sanholt { 0000000000, 0000000000 }, 273112015Sanholt { 0000000000, 0000000000 }, 274112015Sanholt { 0000000000, 0000000000 }, 275112015Sanholt { 0000000000, 0000000000 }, 276112015Sanholt { 0000000000, 0000000000 }, 277112015Sanholt { 0000000000, 0000000000 }, 278112015Sanholt { 0000000000, 0000000000 }, 279112015Sanholt { 0000000000, 0000000000 }, 280112015Sanholt { 0000000000, 0000000000 }, 281112015Sanholt { 0000000000, 0000000000 }, 282112015Sanholt { 0000000000, 0000000000 }, 283112015Sanholt { 0000000000, 0000000000 }, 284112015Sanholt { 0000000000, 0000000000 }, 285112015Sanholt { 0000000000, 0000000000 }, 286112015Sanholt { 0000000000, 0000000000 }, 287112015Sanholt { 0000000000, 0000000000 }, 288112015Sanholt { 0000000000, 0000000000 }, 289112015Sanholt { 0000000000, 0000000000 }, 290112015Sanholt { 0000000000, 0000000000 }, 291112015Sanholt { 0000000000, 0000000000 }, 292112015Sanholt { 0000000000, 0000000000 }, 293112015Sanholt { 0000000000, 0000000000 }, 294112015Sanholt { 0000000000, 0000000000 }, 295112015Sanholt { 0000000000, 0000000000 }, 296112015Sanholt { 0000000000, 0000000000 }, 297112015Sanholt { 0000000000, 0000000000 }, 298112015Sanholt { 0000000000, 0000000000 }, 299112015Sanholt { 0000000000, 0000000000 }, 300112015Sanholt}; 301112015Sanholt 302112015Sanholt 30395584Sanholtstatic u32 radeon_cp_microcode[][2] = { 30495584Sanholt { 0x21007000, 0000000000 }, 30595584Sanholt { 0x20007000, 0000000000 }, 30695584Sanholt { 0x000000b4, 0x00000004 }, 30795584Sanholt { 0x000000b8, 0x00000004 }, 30895584Sanholt { 0x6f5b4d4c, 0000000000 }, 30995584Sanholt { 0x4c4c427f, 0000000000 }, 31095584Sanholt { 0x5b568a92, 0000000000 }, 31195584Sanholt { 0x4ca09c6d, 0000000000 }, 31295584Sanholt { 0xad4c4c4c, 0000000000 }, 31395584Sanholt { 0x4ce1af3d, 0000000000 }, 31495584Sanholt { 0xd8afafaf, 0000000000 }, 31595584Sanholt { 0xd64c4cdc, 0000000000 }, 31695584Sanholt { 0x4cd10d10, 0000000000 }, 31795584Sanholt { 0x000f0000, 0x00000016 }, 31895584Sanholt { 0x362f242d, 0000000000 }, 31995584Sanholt { 0x00000012, 0x00000004 }, 32095584Sanholt { 0x000f0000, 0x00000016 }, 32195584Sanholt { 0x362f282d, 0000000000 }, 32295584Sanholt { 0x000380e7, 0x00000002 }, 32395584Sanholt { 0x04002c97, 0x00000002 }, 32495584Sanholt { 0x000f0001, 0x00000016 }, 32595584Sanholt { 0x333a3730, 0000000000 }, 32695584Sanholt { 0x000077ef, 0x00000002 }, 32795584Sanholt { 0x00061000, 0x00000002 }, 32895584Sanholt { 0x00000021, 0x0000001a }, 32995584Sanholt { 0x00004000, 0x0000001e }, 33095584Sanholt { 0x00061000, 0x00000002 }, 33195584Sanholt { 0x00000021, 0x0000001a }, 33295584Sanholt { 0x00004000, 0x0000001e }, 33395584Sanholt { 0x00061000, 0x00000002 }, 33495584Sanholt { 0x00000021, 0x0000001a }, 33595584Sanholt { 0x00004000, 0x0000001e }, 33695584Sanholt { 0x00000017, 0x00000004 }, 33795584Sanholt { 0x0003802b, 0x00000002 }, 33895584Sanholt { 0x040067e0, 0x00000002 }, 33995584Sanholt { 0x00000017, 0x00000004 }, 34095584Sanholt { 0x000077e0, 0x00000002 }, 34195584Sanholt { 0x00065000, 0x00000002 }, 34295584Sanholt { 0x000037e1, 0x00000002 }, 34395584Sanholt { 0x040067e1, 0x00000006 }, 34495584Sanholt { 0x000077e0, 0x00000002 }, 34595584Sanholt { 0x000077e1, 0x00000002 }, 34695584Sanholt { 0x000077e1, 0x00000006 }, 34795584Sanholt { 0xffffffff, 0000000000 }, 34895584Sanholt { 0x10000000, 0000000000 }, 34995584Sanholt { 0x0003802b, 0x00000002 }, 35095584Sanholt { 0x040067e0, 0x00000006 }, 35195584Sanholt { 0x00007675, 0x00000002 }, 35295584Sanholt { 0x00007676, 0x00000002 }, 35395584Sanholt { 0x00007677, 0x00000002 }, 35495584Sanholt { 0x00007678, 0x00000006 }, 35595584Sanholt { 0x0003802c, 0x00000002 }, 35695584Sanholt { 0x04002676, 0x00000002 }, 35795584Sanholt { 0x00007677, 0x00000002 }, 35895584Sanholt { 0x00007678, 0x00000006 }, 35995584Sanholt { 0x0000002f, 0x00000018 }, 36095584Sanholt { 0x0000002f, 0x00000018 }, 36195584Sanholt { 0000000000, 0x00000006 }, 36295584Sanholt { 0x00000030, 0x00000018 }, 36395584Sanholt { 0x00000030, 0x00000018 }, 36495584Sanholt { 0000000000, 0x00000006 }, 36595584Sanholt { 0x01605000, 0x00000002 }, 36695584Sanholt { 0x00065000, 0x00000002 }, 36795584Sanholt { 0x00098000, 0x00000002 }, 36895584Sanholt { 0x00061000, 0x00000002 }, 36995584Sanholt { 0x64c0603e, 0x00000004 }, 37095584Sanholt { 0x000380e6, 0x00000002 }, 37195584Sanholt { 0x040025c5, 0x00000002 }, 37295584Sanholt { 0x00080000, 0x00000016 }, 37395584Sanholt { 0000000000, 0000000000 }, 37495584Sanholt { 0x0400251d, 0x00000002 }, 37595584Sanholt { 0x00007580, 0x00000002 }, 37695584Sanholt { 0x00067581, 0x00000002 }, 37795584Sanholt { 0x04002580, 0x00000002 }, 37895584Sanholt { 0x00067581, 0x00000002 }, 37995584Sanholt { 0x00000049, 0x00000004 }, 38095584Sanholt { 0x00005000, 0000000000 }, 38195584Sanholt { 0x000380e6, 0x00000002 }, 38295584Sanholt { 0x040025c5, 0x00000002 }, 38395584Sanholt { 0x00061000, 0x00000002 }, 38495584Sanholt { 0x0000750e, 0x00000002 }, 38595584Sanholt { 0x00019000, 0x00000002 }, 38695584Sanholt { 0x00011055, 0x00000014 }, 38795584Sanholt { 0x00000055, 0x00000012 }, 38895584Sanholt { 0x0400250f, 0x00000002 }, 38995584Sanholt { 0x0000504f, 0x00000004 }, 39095584Sanholt { 0x000380e6, 0x00000002 }, 39195584Sanholt { 0x040025c5, 0x00000002 }, 39295584Sanholt { 0x00007565, 0x00000002 }, 39395584Sanholt { 0x00007566, 0x00000002 }, 39495584Sanholt { 0x00000058, 0x00000004 }, 39595584Sanholt { 0x000380e6, 0x00000002 }, 39695584Sanholt { 0x040025c5, 0x00000002 }, 39795584Sanholt { 0x01e655b4, 0x00000002 }, 39895584Sanholt { 0x4401b0e4, 0x00000002 }, 39995584Sanholt { 0x01c110e4, 0x00000002 }, 40095584Sanholt { 0x26667066, 0x00000018 }, 40195584Sanholt { 0x040c2565, 0x00000002 }, 40295584Sanholt { 0x00000066, 0x00000018 }, 40395584Sanholt { 0x04002564, 0x00000002 }, 40495584Sanholt { 0x00007566, 0x00000002 }, 40595584Sanholt { 0x0000005d, 0x00000004 }, 40695584Sanholt { 0x00401069, 0x00000008 }, 40795584Sanholt { 0x00101000, 0x00000002 }, 40895584Sanholt { 0x000d80ff, 0x00000002 }, 40995584Sanholt { 0x0080006c, 0x00000008 }, 41095584Sanholt { 0x000f9000, 0x00000002 }, 41195584Sanholt { 0x000e00ff, 0x00000002 }, 41295584Sanholt { 0000000000, 0x00000006 }, 41395584Sanholt { 0x0000008f, 0x00000018 }, 41495584Sanholt { 0x0000005b, 0x00000004 }, 41595584Sanholt { 0x000380e6, 0x00000002 }, 41695584Sanholt { 0x040025c5, 0x00000002 }, 41795584Sanholt { 0x00007576, 0x00000002 }, 41895584Sanholt { 0x00065000, 0x00000002 }, 41995584Sanholt { 0x00009000, 0x00000002 }, 42095584Sanholt { 0x00041000, 0x00000002 }, 42195584Sanholt { 0x0c00350e, 0x00000002 }, 42295584Sanholt { 0x00049000, 0x00000002 }, 42395584Sanholt { 0x00051000, 0x00000002 }, 42495584Sanholt { 0x01e785f8, 0x00000002 }, 42595584Sanholt { 0x00200000, 0x00000002 }, 42695584Sanholt { 0x0060007e, 0x0000000c }, 42795584Sanholt { 0x00007563, 0x00000002 }, 42895584Sanholt { 0x006075f0, 0x00000021 }, 42995584Sanholt { 0x20007073, 0x00000004 }, 43095584Sanholt { 0x00005073, 0x00000004 }, 43195584Sanholt { 0x000380e6, 0x00000002 }, 43295584Sanholt { 0x040025c5, 0x00000002 }, 43395584Sanholt { 0x00007576, 0x00000002 }, 43495584Sanholt { 0x00007577, 0x00000002 }, 43595584Sanholt { 0x0000750e, 0x00000002 }, 43695584Sanholt { 0x0000750f, 0x00000002 }, 43795584Sanholt { 0x00a05000, 0x00000002 }, 43895584Sanholt { 0x00600083, 0x0000000c }, 43995584Sanholt { 0x006075f0, 0x00000021 }, 44095584Sanholt { 0x000075f8, 0x00000002 }, 44195584Sanholt { 0x00000083, 0x00000004 }, 44295584Sanholt { 0x000a750e, 0x00000002 }, 44395584Sanholt { 0x000380e6, 0x00000002 }, 44495584Sanholt { 0x040025c5, 0x00000002 }, 44595584Sanholt { 0x0020750f, 0x00000002 }, 44695584Sanholt { 0x00600086, 0x00000004 }, 44795584Sanholt { 0x00007570, 0x00000002 }, 44895584Sanholt { 0x00007571, 0x00000002 }, 44995584Sanholt { 0x00007572, 0x00000006 }, 45095584Sanholt { 0x000380e6, 0x00000002 }, 45195584Sanholt { 0x040025c5, 0x00000002 }, 45295584Sanholt { 0x00005000, 0x00000002 }, 45395584Sanholt { 0x00a05000, 0x00000002 }, 45495584Sanholt { 0x00007568, 0x00000002 }, 45595584Sanholt { 0x00061000, 0x00000002 }, 45695584Sanholt { 0x00000095, 0x0000000c }, 45795584Sanholt { 0x00058000, 0x00000002 }, 45895584Sanholt { 0x0c607562, 0x00000002 }, 45995584Sanholt { 0x00000097, 0x00000004 }, 46095584Sanholt { 0x000380e6, 0x00000002 }, 46195584Sanholt { 0x040025c5, 0x00000002 }, 46295584Sanholt { 0x00600096, 0x00000004 }, 46395584Sanholt { 0x400070e5, 0000000000 }, 46495584Sanholt { 0x000380e6, 0x00000002 }, 46595584Sanholt { 0x040025c5, 0x00000002 }, 46695584Sanholt { 0x000380e5, 0x00000002 }, 46795584Sanholt { 0x000000a8, 0x0000001c }, 46895584Sanholt { 0x000650aa, 0x00000018 }, 46995584Sanholt { 0x040025bb, 0x00000002 }, 47095584Sanholt { 0x000610ab, 0x00000018 }, 47195584Sanholt { 0x040075bc, 0000000000 }, 47295584Sanholt { 0x000075bb, 0x00000002 }, 47395584Sanholt { 0x000075bc, 0000000000 }, 47495584Sanholt { 0x00090000, 0x00000006 }, 47595584Sanholt { 0x00090000, 0x00000002 }, 47695584Sanholt { 0x000d8002, 0x00000006 }, 47795584Sanholt { 0x00007832, 0x00000002 }, 47895584Sanholt { 0x00005000, 0x00000002 }, 47995584Sanholt { 0x000380e7, 0x00000002 }, 48095584Sanholt { 0x04002c97, 0x00000002 }, 48195584Sanholt { 0x00007820, 0x00000002 }, 48295584Sanholt { 0x00007821, 0x00000002 }, 48395584Sanholt { 0x00007800, 0000000000 }, 48495584Sanholt { 0x01200000, 0x00000002 }, 48595584Sanholt { 0x20077000, 0x00000002 }, 48695584Sanholt { 0x01200000, 0x00000002 }, 48795584Sanholt { 0x20007000, 0x00000002 }, 48895584Sanholt { 0x00061000, 0x00000002 }, 48995584Sanholt { 0x0120751b, 0x00000002 }, 49095584Sanholt { 0x8040750a, 0x00000002 }, 49195584Sanholt { 0x8040750b, 0x00000002 }, 49295584Sanholt { 0x00110000, 0x00000002 }, 49395584Sanholt { 0x000380e5, 0x00000002 }, 49495584Sanholt { 0x000000c6, 0x0000001c }, 49595584Sanholt { 0x000610ab, 0x00000018 }, 49695584Sanholt { 0x844075bd, 0x00000002 }, 49795584Sanholt { 0x000610aa, 0x00000018 }, 49895584Sanholt { 0x840075bb, 0x00000002 }, 49995584Sanholt { 0x000610ab, 0x00000018 }, 50095584Sanholt { 0x844075bc, 0x00000002 }, 50195584Sanholt { 0x000000c9, 0x00000004 }, 50295584Sanholt { 0x804075bd, 0x00000002 }, 50395584Sanholt { 0x800075bb, 0x00000002 }, 50495584Sanholt { 0x804075bc, 0x00000002 }, 50595584Sanholt { 0x00108000, 0x00000002 }, 50695584Sanholt { 0x01400000, 0x00000002 }, 50795584Sanholt { 0x006000cd, 0x0000000c }, 50895584Sanholt { 0x20c07000, 0x00000020 }, 50995584Sanholt { 0x000000cf, 0x00000012 }, 51095584Sanholt { 0x00800000, 0x00000006 }, 51195584Sanholt { 0x0080751d, 0x00000006 }, 51295584Sanholt { 0000000000, 0000000000 }, 51395584Sanholt { 0x0000775c, 0x00000002 }, 51495584Sanholt { 0x00a05000, 0x00000002 }, 51595584Sanholt { 0x00661000, 0x00000002 }, 51695584Sanholt { 0x0460275d, 0x00000020 }, 51795584Sanholt { 0x00004000, 0000000000 }, 51895584Sanholt { 0x01e00830, 0x00000002 }, 51995584Sanholt { 0x21007000, 0000000000 }, 52095584Sanholt { 0x6464614d, 0000000000 }, 52195584Sanholt { 0x69687420, 0000000000 }, 52295584Sanholt { 0x00000073, 0000000000 }, 52395584Sanholt { 0000000000, 0000000000 }, 52495584Sanholt { 0x00005000, 0x00000002 }, 52595584Sanholt { 0x000380d0, 0x00000002 }, 52695584Sanholt { 0x040025e0, 0x00000002 }, 52795584Sanholt { 0x000075e1, 0000000000 }, 52895584Sanholt { 0x00000001, 0000000000 }, 52995584Sanholt { 0x000380e0, 0x00000002 }, 53095584Sanholt { 0x04002394, 0x00000002 }, 53195584Sanholt { 0x00005000, 0000000000 }, 53295584Sanholt { 0000000000, 0000000000 }, 53395584Sanholt { 0000000000, 0000000000 }, 53495584Sanholt { 0x00000008, 0000000000 }, 53595584Sanholt { 0x00000004, 0000000000 }, 53695584Sanholt { 0000000000, 0000000000 }, 53795584Sanholt { 0000000000, 0000000000 }, 53895584Sanholt { 0000000000, 0000000000 }, 53995584Sanholt { 0000000000, 0000000000 }, 54095584Sanholt { 0000000000, 0000000000 }, 54195584Sanholt { 0000000000, 0000000000 }, 54295584Sanholt { 0000000000, 0000000000 }, 54395584Sanholt { 0000000000, 0000000000 }, 54495584Sanholt { 0000000000, 0000000000 }, 54595584Sanholt { 0000000000, 0000000000 }, 54695584Sanholt { 0000000000, 0000000000 }, 54795584Sanholt { 0000000000, 0000000000 }, 54895584Sanholt { 0000000000, 0000000000 }, 54995584Sanholt { 0000000000, 0000000000 }, 55095584Sanholt { 0000000000, 0000000000 }, 55195584Sanholt { 0000000000, 0000000000 }, 55295584Sanholt { 0000000000, 0000000000 }, 55395584Sanholt { 0000000000, 0000000000 }, 55495584Sanholt { 0000000000, 0000000000 }, 55595584Sanholt { 0000000000, 0000000000 }, 55695584Sanholt { 0000000000, 0000000000 }, 55795584Sanholt { 0000000000, 0000000000 }, 55895584Sanholt { 0000000000, 0000000000 }, 55995584Sanholt { 0000000000, 0000000000 }, 56095584Sanholt}; 56195584Sanholt 56295584Sanholt 56395584Sanholtint RADEON_READ_PLL(drm_device_t *dev, int addr) 56495584Sanholt{ 56595584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 56695584Sanholt 56795584Sanholt RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f); 56895584Sanholt return RADEON_READ(RADEON_CLOCK_CNTL_DATA); 56995584Sanholt} 57095584Sanholt 57195584Sanholt#if RADEON_FIFO_DEBUG 57295584Sanholtstatic void radeon_status( drm_radeon_private_t *dev_priv ) 57395584Sanholt{ 574112015Sanholt printk( "%s:\n", __FUNCTION__ ); 57595584Sanholt printk( "RBBM_STATUS = 0x%08x\n", 57695584Sanholt (unsigned int)RADEON_READ( RADEON_RBBM_STATUS ) ); 57795584Sanholt printk( "CP_RB_RTPR = 0x%08x\n", 57895584Sanholt (unsigned int)RADEON_READ( RADEON_CP_RB_RPTR ) ); 57995584Sanholt printk( "CP_RB_WTPR = 0x%08x\n", 58095584Sanholt (unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) ); 58195584Sanholt printk( "AIC_CNTL = 0x%08x\n", 58295584Sanholt (unsigned int)RADEON_READ( RADEON_AIC_CNTL ) ); 58395584Sanholt printk( "AIC_STAT = 0x%08x\n", 58495584Sanholt (unsigned int)RADEON_READ( RADEON_AIC_STAT ) ); 58595584Sanholt printk( "AIC_PT_BASE = 0x%08x\n", 58695584Sanholt (unsigned int)RADEON_READ( RADEON_AIC_PT_BASE ) ); 58795584Sanholt printk( "TLB_ADDR = 0x%08x\n", 58895584Sanholt (unsigned int)RADEON_READ( RADEON_AIC_TLB_ADDR ) ); 58995584Sanholt printk( "TLB_DATA = 0x%08x\n", 59095584Sanholt (unsigned int)RADEON_READ( RADEON_AIC_TLB_DATA ) ); 59195584Sanholt} 59295584Sanholt#endif 59395584Sanholt 59495584Sanholt 59595584Sanholt/* ================================================================ 59695584Sanholt * Engine, FIFO control 59795584Sanholt */ 59895584Sanholt 59995584Sanholtstatic int radeon_do_pixcache_flush( drm_radeon_private_t *dev_priv ) 60095584Sanholt{ 60195584Sanholt u32 tmp; 60295584Sanholt int i; 60395584Sanholt 604112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 605112015Sanholt 60695584Sanholt tmp = RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT ); 60795584Sanholt tmp |= RADEON_RB2D_DC_FLUSH_ALL; 60895584Sanholt RADEON_WRITE( RADEON_RB2D_DSTCACHE_CTLSTAT, tmp ); 60995584Sanholt 61095584Sanholt for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 61195584Sanholt if ( !(RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT ) 61295584Sanholt & RADEON_RB2D_DC_BUSY) ) { 61395584Sanholt return 0; 61495584Sanholt } 615112015Sanholt DRM_UDELAY( 1 ); 61695584Sanholt } 61795584Sanholt 61895584Sanholt#if RADEON_FIFO_DEBUG 61995584Sanholt DRM_ERROR( "failed!\n" ); 62095584Sanholt radeon_status( dev_priv ); 62195584Sanholt#endif 622112015Sanholt return DRM_ERR(EBUSY); 62395584Sanholt} 62495584Sanholt 62595584Sanholtstatic int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv, 62695584Sanholt int entries ) 62795584Sanholt{ 62895584Sanholt int i; 62995584Sanholt 630112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 631112015Sanholt 63295584Sanholt for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 63395584Sanholt int slots = ( RADEON_READ( RADEON_RBBM_STATUS ) 63495584Sanholt & RADEON_RBBM_FIFOCNT_MASK ); 63595584Sanholt if ( slots >= entries ) return 0; 636112015Sanholt DRM_UDELAY( 1 ); 63795584Sanholt } 63895584Sanholt 63995584Sanholt#if RADEON_FIFO_DEBUG 64095584Sanholt DRM_ERROR( "failed!\n" ); 64195584Sanholt radeon_status( dev_priv ); 64295584Sanholt#endif 643112015Sanholt return DRM_ERR(EBUSY); 64495584Sanholt} 64595584Sanholt 64695584Sanholtstatic int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv ) 64795584Sanholt{ 64895584Sanholt int i, ret; 64995584Sanholt 650112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 651112015Sanholt 65295584Sanholt ret = radeon_do_wait_for_fifo( dev_priv, 64 ); 65395584Sanholt if ( ret ) return ret; 654112015Sanholt 65595584Sanholt for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 65695584Sanholt if ( !(RADEON_READ( RADEON_RBBM_STATUS ) 65795584Sanholt & RADEON_RBBM_ACTIVE) ) { 65895584Sanholt radeon_do_pixcache_flush( dev_priv ); 65995584Sanholt return 0; 66095584Sanholt } 661112015Sanholt DRM_UDELAY( 1 ); 66295584Sanholt } 66395584Sanholt 66495584Sanholt#if RADEON_FIFO_DEBUG 66595584Sanholt DRM_ERROR( "failed!\n" ); 66695584Sanholt radeon_status( dev_priv ); 66795584Sanholt#endif 668112015Sanholt return DRM_ERR(EBUSY); 66995584Sanholt} 67095584Sanholt 67195584Sanholt 67295584Sanholt/* ================================================================ 67395584Sanholt * CP control, initialization 67495584Sanholt */ 67595584Sanholt 67695584Sanholt/* Load the microcode for the CP */ 67795584Sanholtstatic void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv ) 67895584Sanholt{ 67995584Sanholt int i; 680112015Sanholt DRM_DEBUG( "\n" ); 68195584Sanholt 68295584Sanholt radeon_do_wait_for_idle( dev_priv ); 68395584Sanholt 68495584Sanholt RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 ); 685112015Sanholt 686112015Sanholt if (dev_priv->is_r200) 687112015Sanholt { 688112015Sanholt DRM_INFO("Loading R200 Microcode\n"); 689112015Sanholt for ( i = 0 ; i < 256 ; i++ ) 690112015Sanholt { 691112015Sanholt RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, 692112015Sanholt R200_cp_microcode[i][1] ); 693112015Sanholt RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, 694112015Sanholt R200_cp_microcode[i][0] ); 695112015Sanholt } 69695584Sanholt } 697112015Sanholt else 698112015Sanholt { 699112015Sanholt for ( i = 0 ; i < 256 ; i++ ) { 700112015Sanholt RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, 701112015Sanholt radeon_cp_microcode[i][1] ); 702112015Sanholt RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, 703112015Sanholt radeon_cp_microcode[i][0] ); 704112015Sanholt } 705112015Sanholt } 70695584Sanholt} 70795584Sanholt 70895584Sanholt/* Flush any pending commands to the CP. This should only be used just 70995584Sanholt * prior to a wait for idle, as it informs the engine that the command 71095584Sanholt * stream is ending. 71195584Sanholt */ 71295584Sanholtstatic void radeon_do_cp_flush( drm_radeon_private_t *dev_priv ) 71395584Sanholt{ 714112015Sanholt DRM_DEBUG( "\n" ); 71595584Sanholt#if 0 71695584Sanholt u32 tmp; 71795584Sanholt 71895584Sanholt tmp = RADEON_READ( RADEON_CP_RB_WPTR ) | (1 << 31); 71995584Sanholt RADEON_WRITE( RADEON_CP_RB_WPTR, tmp ); 72095584Sanholt#endif 72195584Sanholt} 72295584Sanholt 72395584Sanholt/* Wait for the CP to go idle. 72495584Sanholt */ 72595584Sanholtint radeon_do_cp_idle( drm_radeon_private_t *dev_priv ) 72695584Sanholt{ 72795584Sanholt RING_LOCALS; 728112015Sanholt DRM_DEBUG( "\n" ); 72995584Sanholt 73095584Sanholt BEGIN_RING( 6 ); 73195584Sanholt 73295584Sanholt RADEON_PURGE_CACHE(); 73395584Sanholt RADEON_PURGE_ZCACHE(); 73495584Sanholt RADEON_WAIT_UNTIL_IDLE(); 73595584Sanholt 73695584Sanholt ADVANCE_RING(); 737112015Sanholt COMMIT_RING(); 73895584Sanholt 73995584Sanholt return radeon_do_wait_for_idle( dev_priv ); 74095584Sanholt} 74195584Sanholt 74295584Sanholt/* Start the Command Processor. 74395584Sanholt */ 74495584Sanholtstatic void radeon_do_cp_start( drm_radeon_private_t *dev_priv ) 74595584Sanholt{ 74695584Sanholt RING_LOCALS; 747112015Sanholt DRM_DEBUG( "\n" ); 74895584Sanholt 74995584Sanholt radeon_do_wait_for_idle( dev_priv ); 75095584Sanholt 75195584Sanholt RADEON_WRITE( RADEON_CP_CSQ_CNTL, dev_priv->cp_mode ); 75295584Sanholt 75395584Sanholt dev_priv->cp_running = 1; 75495584Sanholt 75595584Sanholt BEGIN_RING( 6 ); 75695584Sanholt 75795584Sanholt RADEON_PURGE_CACHE(); 75895584Sanholt RADEON_PURGE_ZCACHE(); 75995584Sanholt RADEON_WAIT_UNTIL_IDLE(); 76095584Sanholt 76195584Sanholt ADVANCE_RING(); 762112015Sanholt COMMIT_RING(); 76395584Sanholt} 76495584Sanholt 76595584Sanholt/* Reset the Command Processor. This will not flush any pending 76695584Sanholt * commands, so you must wait for the CP command stream to complete 76795584Sanholt * before calling this routine. 76895584Sanholt */ 76995584Sanholtstatic void radeon_do_cp_reset( drm_radeon_private_t *dev_priv ) 77095584Sanholt{ 77195584Sanholt u32 cur_read_ptr; 772112015Sanholt DRM_DEBUG( "\n" ); 77395584Sanholt 77495584Sanholt cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); 77595584Sanholt RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); 776113995Sanholt SET_RING_HEAD( dev_priv, cur_read_ptr ); 77795584Sanholt dev_priv->ring.tail = cur_read_ptr; 77895584Sanholt} 77995584Sanholt 78095584Sanholt/* Stop the Command Processor. This will not flush any pending 78195584Sanholt * commands, so you must flush the command stream and wait for the CP 78295584Sanholt * to go idle before calling this routine. 78395584Sanholt */ 78495584Sanholtstatic void radeon_do_cp_stop( drm_radeon_private_t *dev_priv ) 78595584Sanholt{ 786112015Sanholt DRM_DEBUG( "\n" ); 78795584Sanholt 78895584Sanholt RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS ); 78995584Sanholt 79095584Sanholt dev_priv->cp_running = 0; 79195584Sanholt} 79295584Sanholt 79395584Sanholt/* Reset the engine. This will stop the CP if it is running. 79495584Sanholt */ 79595584Sanholtstatic int radeon_do_engine_reset( drm_device_t *dev ) 79695584Sanholt{ 79795584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 79895584Sanholt u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset; 799112015Sanholt DRM_DEBUG( "\n" ); 80095584Sanholt 80195584Sanholt radeon_do_pixcache_flush( dev_priv ); 80295584Sanholt 80395584Sanholt clock_cntl_index = RADEON_READ( RADEON_CLOCK_CNTL_INDEX ); 80495584Sanholt mclk_cntl = RADEON_READ_PLL( dev, RADEON_MCLK_CNTL ); 80595584Sanholt 80695584Sanholt RADEON_WRITE_PLL( RADEON_MCLK_CNTL, ( mclk_cntl | 80795584Sanholt RADEON_FORCEON_MCLKA | 80895584Sanholt RADEON_FORCEON_MCLKB | 80995584Sanholt RADEON_FORCEON_YCLKA | 81095584Sanholt RADEON_FORCEON_YCLKB | 81195584Sanholt RADEON_FORCEON_MC | 81295584Sanholt RADEON_FORCEON_AIC ) ); 81395584Sanholt 81495584Sanholt rbbm_soft_reset = RADEON_READ( RADEON_RBBM_SOFT_RESET ); 81595584Sanholt 81695584Sanholt RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset | 81795584Sanholt RADEON_SOFT_RESET_CP | 81895584Sanholt RADEON_SOFT_RESET_HI | 81995584Sanholt RADEON_SOFT_RESET_SE | 82095584Sanholt RADEON_SOFT_RESET_RE | 82195584Sanholt RADEON_SOFT_RESET_PP | 82295584Sanholt RADEON_SOFT_RESET_E2 | 82395584Sanholt RADEON_SOFT_RESET_RB ) ); 82495584Sanholt RADEON_READ( RADEON_RBBM_SOFT_RESET ); 82595584Sanholt RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset & 82695584Sanholt ~( RADEON_SOFT_RESET_CP | 82795584Sanholt RADEON_SOFT_RESET_HI | 82895584Sanholt RADEON_SOFT_RESET_SE | 82995584Sanholt RADEON_SOFT_RESET_RE | 83095584Sanholt RADEON_SOFT_RESET_PP | 83195584Sanholt RADEON_SOFT_RESET_E2 | 83295584Sanholt RADEON_SOFT_RESET_RB ) ) ); 83395584Sanholt RADEON_READ( RADEON_RBBM_SOFT_RESET ); 83495584Sanholt 83595584Sanholt 83695584Sanholt RADEON_WRITE_PLL( RADEON_MCLK_CNTL, mclk_cntl ); 83795584Sanholt RADEON_WRITE( RADEON_CLOCK_CNTL_INDEX, clock_cntl_index ); 83895584Sanholt RADEON_WRITE( RADEON_RBBM_SOFT_RESET, rbbm_soft_reset ); 83995584Sanholt 84095584Sanholt /* Reset the CP ring */ 84195584Sanholt radeon_do_cp_reset( dev_priv ); 84295584Sanholt 84395584Sanholt /* The CP is no longer running after an engine reset */ 84495584Sanholt dev_priv->cp_running = 0; 84595584Sanholt 84695584Sanholt /* Reset any pending vertex, indirect buffers */ 84795584Sanholt radeon_freelist_reset( dev ); 84895584Sanholt 84995584Sanholt return 0; 85095584Sanholt} 85195584Sanholt 85295584Sanholtstatic void radeon_cp_init_ring_buffer( drm_device_t *dev, 85395584Sanholt drm_radeon_private_t *dev_priv ) 85495584Sanholt{ 85595584Sanholt u32 ring_start, cur_read_ptr; 85695584Sanholt u32 tmp; 85795584Sanholt 85895584Sanholt /* Initialize the memory controller */ 85995584Sanholt RADEON_WRITE( RADEON_MC_FB_LOCATION, 860122580Sanholt ( ( dev_priv->gart_vm_start - 1 ) & 0xffff0000 ) 861122580Sanholt | ( dev_priv->fb_location >> 16 ) ); 86295584Sanholt 863119895Sanholt#if __REALLY_HAVE_AGP 86495584Sanholt if ( !dev_priv->is_pci ) { 86595584Sanholt RADEON_WRITE( RADEON_MC_AGP_LOCATION, 866119895Sanholt (((dev_priv->gart_vm_start - 1 + 867119895Sanholt dev_priv->gart_size) & 0xffff0000) | 868119895Sanholt (dev_priv->gart_vm_start >> 16)) ); 86995584Sanholt 87095584Sanholt ring_start = (dev_priv->cp_ring->offset 87195584Sanholt - dev->agp->base 872119895Sanholt + dev_priv->gart_vm_start); 873119895Sanholt } else 87495584Sanholt#endif 87595584Sanholt ring_start = (dev_priv->cp_ring->offset 87695584Sanholt - dev->sg->handle 877119895Sanholt + dev_priv->gart_vm_start); 87895584Sanholt 87995584Sanholt RADEON_WRITE( RADEON_CP_RB_BASE, ring_start ); 88095584Sanholt 88195584Sanholt /* Set the write pointer delay */ 88295584Sanholt RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 ); 88395584Sanholt 88495584Sanholt /* Initialize the ring buffer's read and write pointers */ 88595584Sanholt cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); 88695584Sanholt RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); 887113995Sanholt SET_RING_HEAD( dev_priv, cur_read_ptr ); 88895584Sanholt dev_priv->ring.tail = cur_read_ptr; 88995584Sanholt 890113995Sanholt#if __REALLY_HAVE_AGP 89195584Sanholt if ( !dev_priv->is_pci ) { 89295584Sanholt RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, 893113995Sanholt dev_priv->ring_rptr->offset 894113995Sanholt - dev->agp->base 895119895Sanholt + dev_priv->gart_vm_start); 896113995Sanholt } else 897113995Sanholt#endif 898113995Sanholt { 89995584Sanholt drm_sg_mem_t *entry = dev->sg; 90095584Sanholt unsigned long tmp_ofs, page_ofs; 90195584Sanholt 90295584Sanholt tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle; 90395584Sanholt page_ofs = tmp_ofs >> PAGE_SHIFT; 90495584Sanholt 90595584Sanholt RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, 90695584Sanholt entry->busaddr[page_ofs]); 907113995Sanholt DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n", 908119098Sanholt (unsigned long) entry->busaddr[page_ofs], 90995584Sanholt entry->handle + tmp_ofs ); 91095584Sanholt } 91195584Sanholt 912112015Sanholt /* Initialize the scratch register pointer. This will cause 913112015Sanholt * the scratch register values to be written out to memory 914112015Sanholt * whenever they are updated. 915112015Sanholt * 916112015Sanholt * We simply put this behind the ring read pointer, this works 917112015Sanholt * with PCI GART as well as (whatever kind of) AGP GART 918112015Sanholt */ 919112015Sanholt RADEON_WRITE( RADEON_SCRATCH_ADDR, RADEON_READ( RADEON_CP_RB_RPTR_ADDR ) 920112015Sanholt + RADEON_SCRATCH_REG_OFFSET ); 921112015Sanholt 922112015Sanholt dev_priv->scratch = ((__volatile__ u32 *) 923113995Sanholt dev_priv->ring_rptr->handle + 924112015Sanholt (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); 925112015Sanholt 926112015Sanholt RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); 927112015Sanholt 928112015Sanholt /* Writeback doesn't seem to work everywhere, test it first */ 929112015Sanholt DRM_WRITE32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0 ); 930112015Sanholt RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef ); 931112015Sanholt 932112015Sanholt for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) { 933112015Sanholt if ( DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1) ) == 0xdeadbeef ) 934112015Sanholt break; 935112015Sanholt DRM_UDELAY( 1 ); 936112015Sanholt } 937112015Sanholt 938112015Sanholt if ( tmp < dev_priv->usec_timeout ) { 939112015Sanholt dev_priv->writeback_works = 1; 940112015Sanholt DRM_DEBUG( "writeback test succeeded, tmp=%d\n", tmp ); 941112015Sanholt } else { 942112015Sanholt dev_priv->writeback_works = 0; 943112015Sanholt DRM_DEBUG( "writeback test failed\n" ); 944112015Sanholt } 945112015Sanholt 946112015Sanholt dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; 947112015Sanholt RADEON_WRITE( RADEON_LAST_FRAME_REG, 948112015Sanholt dev_priv->sarea_priv->last_frame ); 949112015Sanholt 950112015Sanholt dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0; 951112015Sanholt RADEON_WRITE( RADEON_LAST_DISPATCH_REG, 952112015Sanholt dev_priv->sarea_priv->last_dispatch ); 953112015Sanholt 954112015Sanholt dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; 955112015Sanholt RADEON_WRITE( RADEON_LAST_CLEAR_REG, 956112015Sanholt dev_priv->sarea_priv->last_clear ); 957112015Sanholt 95895584Sanholt /* Set ring buffer size */ 959112015Sanholt#ifdef __BIG_ENDIAN 960112015Sanholt RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT ); 961112015Sanholt#else 96295584Sanholt RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw ); 963112015Sanholt#endif 96495584Sanholt 96595584Sanholt radeon_do_wait_for_idle( dev_priv ); 96695584Sanholt 96795584Sanholt /* Turn on bus mastering */ 96895584Sanholt tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS; 96995584Sanholt RADEON_WRITE( RADEON_BUS_CNTL, tmp ); 97095584Sanholt 97195584Sanholt /* Sync everything up */ 97295584Sanholt RADEON_WRITE( RADEON_ISYNC_CNTL, 97395584Sanholt (RADEON_ISYNC_ANY2D_IDLE3D | 97495584Sanholt RADEON_ISYNC_ANY3D_IDLE2D | 97595584Sanholt RADEON_ISYNC_WAIT_IDLEGUI | 97695584Sanholt RADEON_ISYNC_CPSCRATCH_IDLEGUI) ); 97795584Sanholt} 97895584Sanholt 979119098Sanholt/* Enable or disable PCI GART on the chip */ 980119098Sanholtstatic void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on ) 981119098Sanholt{ 982119098Sanholt u32 tmp = RADEON_READ( RADEON_AIC_CNTL ); 983119098Sanholt 984119098Sanholt if ( on ) { 985119098Sanholt RADEON_WRITE( RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN ); 986119098Sanholt 987119098Sanholt /* set PCI GART page-table base address 988119098Sanholt */ 989119098Sanholt RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart ); 990119098Sanholt 991119098Sanholt /* set address range for PCI address translate 992119098Sanholt */ 993119895Sanholt RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start ); 994119895Sanholt RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start 995119895Sanholt + dev_priv->gart_size - 1); 996119098Sanholt 997119895Sanholt /* Turn off AGP aperture -- is this required for PCI GART? 998119098Sanholt */ 999119098Sanholt RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ 1000119098Sanholt RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ 1001119098Sanholt } else { 1002119098Sanholt RADEON_WRITE( RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN ); 1003119098Sanholt } 1004119098Sanholt} 1005119098Sanholt 100695584Sanholtstatic int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) 100795584Sanholt{ 100895584Sanholt drm_radeon_private_t *dev_priv; 1009112015Sanholt DRM_DEBUG( "\n" ); 101095584Sanholt 101195584Sanholt dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); 101295584Sanholt if ( dev_priv == NULL ) 1013112015Sanholt return DRM_ERR(ENOMEM); 101495584Sanholt 101595584Sanholt memset( dev_priv, 0, sizeof(drm_radeon_private_t) ); 101695584Sanholt 101795584Sanholt dev_priv->is_pci = init->is_pci; 101895584Sanholt 101995584Sanholt if ( dev_priv->is_pci && !dev->sg ) { 102095584Sanholt DRM_ERROR( "PCI GART memory not allocated!\n" ); 102195584Sanholt dev->dev_private = (void *)dev_priv; 102295584Sanholt radeon_do_cleanup_cp(dev); 1023112015Sanholt return DRM_ERR(EINVAL); 102495584Sanholt } 102595584Sanholt 102695584Sanholt dev_priv->usec_timeout = init->usec_timeout; 102795584Sanholt if ( dev_priv->usec_timeout < 1 || 102895584Sanholt dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) { 102995584Sanholt DRM_DEBUG( "TIMEOUT problem!\n" ); 103095584Sanholt dev->dev_private = (void *)dev_priv; 103195584Sanholt radeon_do_cleanup_cp(dev); 1032112015Sanholt return DRM_ERR(EINVAL); 103395584Sanholt } 103495584Sanholt 1035112015Sanholt dev_priv->is_r200 = (init->func == RADEON_INIT_R200_CP); 1036112015Sanholt dev_priv->do_boxes = 0; 103795584Sanholt dev_priv->cp_mode = init->cp_mode; 103895584Sanholt 103995584Sanholt /* We don't support anything other than bus-mastering ring mode, 104095584Sanholt * but the ring can be in either AGP or PCI space for the ring 104195584Sanholt * read pointer. 104295584Sanholt */ 104395584Sanholt if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) && 104495584Sanholt ( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) { 104595584Sanholt DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode ); 104695584Sanholt dev->dev_private = (void *)dev_priv; 104795584Sanholt radeon_do_cleanup_cp(dev); 1048112015Sanholt return DRM_ERR(EINVAL); 104995584Sanholt } 105095584Sanholt 105195584Sanholt switch ( init->fb_bpp ) { 105295584Sanholt case 16: 105395584Sanholt dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; 105495584Sanholt break; 105595584Sanholt case 32: 105695584Sanholt default: 105795584Sanholt dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; 105895584Sanholt break; 105995584Sanholt } 106095584Sanholt dev_priv->front_offset = init->front_offset; 106195584Sanholt dev_priv->front_pitch = init->front_pitch; 106295584Sanholt dev_priv->back_offset = init->back_offset; 106395584Sanholt dev_priv->back_pitch = init->back_pitch; 106495584Sanholt 106595584Sanholt switch ( init->depth_bpp ) { 106695584Sanholt case 16: 106795584Sanholt dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; 106895584Sanholt break; 106995584Sanholt case 32: 107095584Sanholt default: 107195584Sanholt dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; 107295584Sanholt break; 107395584Sanholt } 107495584Sanholt dev_priv->depth_offset = init->depth_offset; 107595584Sanholt dev_priv->depth_pitch = init->depth_pitch; 107695584Sanholt 107795584Sanholt /* Hardware state for depth clears. Remove this if/when we no 107895584Sanholt * longer clear the depth buffer with a 3D rectangle. Hard-code 107995584Sanholt * all values to prevent unwanted 3D state from slipping through 108095584Sanholt * and screwing with the clear operation. 108195584Sanholt */ 108295584Sanholt dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | 108395584Sanholt (dev_priv->color_fmt << 10) | 1084112015Sanholt (1<<15)); 108595584Sanholt 1086112015Sanholt dev_priv->depth_clear.rb3d_zstencilcntl = 1087112015Sanholt (dev_priv->depth_fmt | 1088112015Sanholt RADEON_Z_TEST_ALWAYS | 1089112015Sanholt RADEON_STENCIL_TEST_ALWAYS | 1090112015Sanholt RADEON_STENCIL_S_FAIL_REPLACE | 1091112015Sanholt RADEON_STENCIL_ZPASS_REPLACE | 1092112015Sanholt RADEON_STENCIL_ZFAIL_REPLACE | 1093112015Sanholt RADEON_Z_WRITE_ENABLE); 109495584Sanholt 109595584Sanholt dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | 109695584Sanholt RADEON_BFACE_SOLID | 109795584Sanholt RADEON_FFACE_SOLID | 109895584Sanholt RADEON_FLAT_SHADE_VTX_LAST | 109995584Sanholt RADEON_DIFFUSE_SHADE_FLAT | 110095584Sanholt RADEON_ALPHA_SHADE_FLAT | 110195584Sanholt RADEON_SPECULAR_SHADE_FLAT | 110295584Sanholt RADEON_FOG_SHADE_FLAT | 110395584Sanholt RADEON_VTX_PIX_CENTER_OGL | 110495584Sanholt RADEON_ROUND_MODE_TRUNC | 110595584Sanholt RADEON_ROUND_PREC_8TH_PIX); 110695584Sanholt 1107112015Sanholt DRM_GETSAREA(); 1108113995Sanholt 1109113995Sanholt dev_priv->fb_offset = init->fb_offset; 1110113995Sanholt dev_priv->mmio_offset = init->mmio_offset; 1111113995Sanholt dev_priv->ring_offset = init->ring_offset; 1112113995Sanholt dev_priv->ring_rptr_offset = init->ring_rptr_offset; 1113113995Sanholt dev_priv->buffers_offset = init->buffers_offset; 1114119895Sanholt dev_priv->gart_textures_offset = init->gart_textures_offset; 1115112015Sanholt 111695584Sanholt if(!dev_priv->sarea) { 111795584Sanholt DRM_ERROR("could not find sarea!\n"); 111895584Sanholt dev->dev_private = (void *)dev_priv; 111995584Sanholt radeon_do_cleanup_cp(dev); 1120112015Sanholt return DRM_ERR(EINVAL); 112195584Sanholt } 112295584Sanholt 112395584Sanholt DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); 112495584Sanholt if(!dev_priv->fb) { 112595584Sanholt DRM_ERROR("could not find framebuffer!\n"); 112695584Sanholt dev->dev_private = (void *)dev_priv; 112795584Sanholt radeon_do_cleanup_cp(dev); 1128112015Sanholt return DRM_ERR(EINVAL); 112995584Sanholt } 113095584Sanholt DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); 113195584Sanholt if(!dev_priv->mmio) { 113295584Sanholt DRM_ERROR("could not find mmio region!\n"); 113395584Sanholt dev->dev_private = (void *)dev_priv; 113495584Sanholt radeon_do_cleanup_cp(dev); 1135112015Sanholt return DRM_ERR(EINVAL); 113695584Sanholt } 113795584Sanholt DRM_FIND_MAP( dev_priv->cp_ring, init->ring_offset ); 113895584Sanholt if(!dev_priv->cp_ring) { 113995584Sanholt DRM_ERROR("could not find cp ring region!\n"); 114095584Sanholt dev->dev_private = (void *)dev_priv; 114195584Sanholt radeon_do_cleanup_cp(dev); 1142112015Sanholt return DRM_ERR(EINVAL); 114395584Sanholt } 114495584Sanholt DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); 114595584Sanholt if(!dev_priv->ring_rptr) { 114695584Sanholt DRM_ERROR("could not find ring read pointer!\n"); 114795584Sanholt dev->dev_private = (void *)dev_priv; 114895584Sanholt radeon_do_cleanup_cp(dev); 1149112015Sanholt return DRM_ERR(EINVAL); 115095584Sanholt } 115195584Sanholt DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); 115295584Sanholt if(!dev_priv->buffers) { 115395584Sanholt DRM_ERROR("could not find dma buffer region!\n"); 115495584Sanholt dev->dev_private = (void *)dev_priv; 115595584Sanholt radeon_do_cleanup_cp(dev); 1156112015Sanholt return DRM_ERR(EINVAL); 115795584Sanholt } 115895584Sanholt 1159119895Sanholt if ( init->gart_textures_offset ) { 1160119895Sanholt DRM_FIND_MAP( dev_priv->gart_textures, init->gart_textures_offset ); 1161119895Sanholt if ( !dev_priv->gart_textures ) { 1162119895Sanholt DRM_ERROR("could not find GART texture region!\n"); 116395584Sanholt dev->dev_private = (void *)dev_priv; 116495584Sanholt radeon_do_cleanup_cp(dev); 1165112015Sanholt return DRM_ERR(EINVAL); 116695584Sanholt } 116795584Sanholt } 116895584Sanholt 116995584Sanholt dev_priv->sarea_priv = 117095584Sanholt (drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle + 117195584Sanholt init->sarea_priv_offset); 117295584Sanholt 1173119098Sanholt#if __REALLY_HAVE_AGP 117495584Sanholt if ( !dev_priv->is_pci ) { 1175119098Sanholt DRM_IOREMAP( dev_priv->cp_ring, dev ); 1176119098Sanholt DRM_IOREMAP( dev_priv->ring_rptr, dev ); 1177119098Sanholt DRM_IOREMAP( dev_priv->buffers, dev ); 117895584Sanholt if(!dev_priv->cp_ring->handle || 117995584Sanholt !dev_priv->ring_rptr->handle || 118095584Sanholt !dev_priv->buffers->handle) { 118195584Sanholt DRM_ERROR("could not find ioremap agp regions!\n"); 118295584Sanholt dev->dev_private = (void *)dev_priv; 118395584Sanholt radeon_do_cleanup_cp(dev); 1184112015Sanholt return DRM_ERR(EINVAL); 118595584Sanholt } 1186119098Sanholt } else 1187119098Sanholt#endif 1188119098Sanholt { 118995584Sanholt dev_priv->cp_ring->handle = 119095584Sanholt (void *)dev_priv->cp_ring->offset; 119195584Sanholt dev_priv->ring_rptr->handle = 119295584Sanholt (void *)dev_priv->ring_rptr->offset; 119395584Sanholt dev_priv->buffers->handle = (void *)dev_priv->buffers->offset; 119495584Sanholt 119595584Sanholt DRM_DEBUG( "dev_priv->cp_ring->handle %p\n", 119695584Sanholt dev_priv->cp_ring->handle ); 119795584Sanholt DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n", 119895584Sanholt dev_priv->ring_rptr->handle ); 119995584Sanholt DRM_DEBUG( "dev_priv->buffers->handle %p\n", 120095584Sanholt dev_priv->buffers->handle ); 120195584Sanholt } 120295584Sanholt 1203122580Sanholt dev_priv->fb_location = ( RADEON_READ( RADEON_MC_FB_LOCATION ) 1204122580Sanholt & 0xffff ) << 16; 120595584Sanholt 1206122580Sanholt dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) | 1207122580Sanholt ( ( dev_priv->front_offset 1208122580Sanholt + dev_priv->fb_location ) >> 10 ) ); 1209122580Sanholt 1210122580Sanholt dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) | 1211122580Sanholt ( ( dev_priv->back_offset 1212122580Sanholt + dev_priv->fb_location ) >> 10 ) ); 1213122580Sanholt 1214122580Sanholt dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) | 1215122580Sanholt ( ( dev_priv->depth_offset 1216122580Sanholt + dev_priv->fb_location ) >> 10 ) ); 1217122580Sanholt 1218122580Sanholt 1219119895Sanholt dev_priv->gart_size = init->gart_size; 1220122580Sanholt dev_priv->gart_vm_start = dev_priv->fb_location 1221122580Sanholt + RADEON_READ( RADEON_CONFIG_APER_SIZE ); 1222122580Sanholt 122395584Sanholt#if __REALLY_HAVE_AGP 122495584Sanholt if ( !dev_priv->is_pci ) 1225119895Sanholt dev_priv->gart_buffers_offset = (dev_priv->buffers->offset 122695584Sanholt - dev->agp->base 1227119895Sanholt + dev_priv->gart_vm_start); 122895584Sanholt else 122995584Sanholt#endif 1230119895Sanholt dev_priv->gart_buffers_offset = (dev_priv->buffers->offset 123195584Sanholt - dev->sg->handle 1232119895Sanholt + dev_priv->gart_vm_start); 123395584Sanholt 1234119895Sanholt DRM_DEBUG( "dev_priv->gart_size %d\n", 1235119895Sanholt dev_priv->gart_size ); 1236119895Sanholt DRM_DEBUG( "dev_priv->gart_vm_start 0x%x\n", 1237119895Sanholt dev_priv->gart_vm_start ); 1238119895Sanholt DRM_DEBUG( "dev_priv->gart_buffers_offset 0x%lx\n", 1239119895Sanholt dev_priv->gart_buffers_offset ); 124095584Sanholt 124195584Sanholt dev_priv->ring.start = (u32 *)dev_priv->cp_ring->handle; 124295584Sanholt dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle 124395584Sanholt + init->ring_size / sizeof(u32)); 124495584Sanholt dev_priv->ring.size = init->ring_size; 124595584Sanholt dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 ); 124695584Sanholt 124795584Sanholt dev_priv->ring.tail_mask = 124895584Sanholt (dev_priv->ring.size / sizeof(u32)) - 1; 124995584Sanholt 125095584Sanholt dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; 125195584Sanholt 1252119098Sanholt#if __REALLY_HAVE_AGP 1253119098Sanholt if ( !dev_priv->is_pci ) { 1254119098Sanholt /* Turn off PCI GART */ 1255119098Sanholt radeon_set_pcigart( dev_priv, 0 ); 1256119098Sanholt } else 1257119098Sanholt#endif 1258119098Sanholt { 125995584Sanholt if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, 126095584Sanholt &dev_priv->bus_pci_gart)) { 126195584Sanholt DRM_ERROR( "failed to init PCI GART!\n" ); 126295584Sanholt dev->dev_private = (void *)dev_priv; 126395584Sanholt radeon_do_cleanup_cp(dev); 1264112015Sanholt return DRM_ERR(ENOMEM); 126595584Sanholt } 126695584Sanholt 1267119098Sanholt /* Turn on PCI GART */ 1268119098Sanholt radeon_set_pcigart( dev_priv, 1 ); 126995584Sanholt } 127095584Sanholt 127195584Sanholt radeon_cp_load_microcode( dev_priv ); 127295584Sanholt radeon_cp_init_ring_buffer( dev, dev_priv ); 127395584Sanholt 127495584Sanholt dev_priv->last_buf = 0; 127595584Sanholt 127695584Sanholt dev->dev_private = (void *)dev_priv; 127795584Sanholt 127895584Sanholt radeon_do_engine_reset( dev ); 127995584Sanholt 128095584Sanholt return 0; 128195584Sanholt} 128295584Sanholt 128395584Sanholtint radeon_do_cleanup_cp( drm_device_t *dev ) 128495584Sanholt{ 1285112015Sanholt DRM_DEBUG( "\n" ); 128695584Sanholt 1287121447Sanholt#if __HAVE_IRQ 1288119098Sanholt /* Make sure interrupts are disabled here because the uninstall ioctl 1289119098Sanholt * may not have been called from userspace and after dev_private 1290119098Sanholt * is freed, it's too late. 1291119098Sanholt */ 1292122580Sanholt if ( dev->irq_enabled ) DRM(irq_uninstall)(dev); 1293119098Sanholt#endif 1294119098Sanholt 129595584Sanholt if ( dev->dev_private ) { 129695584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 129795584Sanholt 1298119098Sanholt#if __REALLY_HAVE_AGP 129995584Sanholt if ( !dev_priv->is_pci ) { 1300113995Sanholt if ( dev_priv->cp_ring != NULL ) 1301119098Sanholt DRM_IOREMAPFREE( dev_priv->cp_ring, dev ); 1302113995Sanholt if ( dev_priv->ring_rptr != NULL ) 1303119098Sanholt DRM_IOREMAPFREE( dev_priv->ring_rptr, dev ); 1304113995Sanholt if ( dev_priv->buffers != NULL ) 1305119098Sanholt DRM_IOREMAPFREE( dev_priv->buffers, dev ); 1306119098Sanholt } else 1307119098Sanholt#endif 1308119098Sanholt { 130995584Sanholt if (!DRM(ati_pcigart_cleanup)( dev, 131095584Sanholt dev_priv->phys_pci_gart, 131195584Sanholt dev_priv->bus_pci_gart )) 131295584Sanholt DRM_ERROR( "failed to cleanup PCI GART!\n" ); 131395584Sanholt } 131495584Sanholt 131595584Sanholt DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t), 131695584Sanholt DRM_MEM_DRIVER ); 131795584Sanholt dev->dev_private = NULL; 131895584Sanholt } 131995584Sanholt 132095584Sanholt return 0; 132195584Sanholt} 132295584Sanholt 1323119098Sanholt/* This code will reinit the Radeon CP hardware after a resume from disc. 1324119098Sanholt * AFAIK, it would be very difficult to pickle the state at suspend time, so 1325119098Sanholt * here we make sure that all Radeon hardware initialisation is re-done without 1326119098Sanholt * affecting running applications. 1327119098Sanholt * 1328119098Sanholt * Charl P. Botha <http://cpbotha.net> 1329119098Sanholt */ 1330119098Sanholtstatic int radeon_do_resume_cp( drm_device_t *dev ) 1331119098Sanholt{ 1332119098Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1333119098Sanholt 1334119098Sanholt if ( !dev_priv ) { 1335119098Sanholt DRM_ERROR( "Called with no initialization\n" ); 1336119098Sanholt return DRM_ERR( EINVAL ); 1337119098Sanholt } 1338119098Sanholt 1339119098Sanholt DRM_DEBUG("Starting radeon_do_resume_cp()\n"); 1340119098Sanholt 1341119098Sanholt#if __REALLY_HAVE_AGP 1342119098Sanholt if ( !dev_priv->is_pci ) { 1343119098Sanholt /* Turn off PCI GART */ 1344119098Sanholt radeon_set_pcigart( dev_priv, 0 ); 1345119098Sanholt } else 1346119098Sanholt#endif 1347119098Sanholt { 1348119098Sanholt /* Turn on PCI GART */ 1349119098Sanholt radeon_set_pcigart( dev_priv, 1 ); 1350119098Sanholt } 1351119098Sanholt 1352119098Sanholt radeon_cp_load_microcode( dev_priv ); 1353119098Sanholt radeon_cp_init_ring_buffer( dev, dev_priv ); 1354119098Sanholt 1355119098Sanholt radeon_do_engine_reset( dev ); 1356119098Sanholt 1357119098Sanholt DRM_DEBUG("radeon_do_resume_cp() complete\n"); 1358119098Sanholt 1359119098Sanholt return 0; 1360119098Sanholt} 1361119098Sanholt 1362119098Sanholt 1363112015Sanholtint radeon_cp_init( DRM_IOCTL_ARGS ) 136495584Sanholt{ 1365112015Sanholt DRM_DEVICE; 136695584Sanholt drm_radeon_init_t init; 136795584Sanholt 1368119098Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 1369119098Sanholt 1370112015Sanholt DRM_COPY_FROM_USER_IOCTL( init, (drm_radeon_init_t *)data, sizeof(init) ); 137195584Sanholt 137295584Sanholt switch ( init.func ) { 137395584Sanholt case RADEON_INIT_CP: 1374112015Sanholt case RADEON_INIT_R200_CP: 137595584Sanholt return radeon_do_init_cp( dev, &init ); 137695584Sanholt case RADEON_CLEANUP_CP: 137795584Sanholt return radeon_do_cleanup_cp( dev ); 137895584Sanholt } 137995584Sanholt 1380112015Sanholt return DRM_ERR(EINVAL); 138195584Sanholt} 138295584Sanholt 1383112015Sanholtint radeon_cp_start( DRM_IOCTL_ARGS ) 138495584Sanholt{ 1385112015Sanholt DRM_DEVICE; 138695584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1387112015Sanholt DRM_DEBUG( "\n" ); 138895584Sanholt 1389113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 139095584Sanholt 139195584Sanholt if ( dev_priv->cp_running ) { 1392112015Sanholt DRM_DEBUG( "%s while CP running\n", __FUNCTION__ ); 139395584Sanholt return 0; 139495584Sanholt } 139595584Sanholt if ( dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS ) { 139695584Sanholt DRM_DEBUG( "%s called with bogus CP mode (%d)\n", 1397112015Sanholt __FUNCTION__, dev_priv->cp_mode ); 139895584Sanholt return 0; 139995584Sanholt } 140095584Sanholt 140195584Sanholt radeon_do_cp_start( dev_priv ); 140295584Sanholt 140395584Sanholt return 0; 140495584Sanholt} 140595584Sanholt 140695584Sanholt/* Stop the CP. The engine must have been idled before calling this 140795584Sanholt * routine. 140895584Sanholt */ 1409112015Sanholtint radeon_cp_stop( DRM_IOCTL_ARGS ) 141095584Sanholt{ 1411112015Sanholt DRM_DEVICE; 141295584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 141395584Sanholt drm_radeon_cp_stop_t stop; 141495584Sanholt int ret; 1415112015Sanholt DRM_DEBUG( "\n" ); 141695584Sanholt 1417113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 141895584Sanholt 1419112015Sanholt DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t *)data, sizeof(stop) ); 142095584Sanholt 1421112015Sanholt if (!dev_priv->cp_running) 1422112015Sanholt return 0; 1423112015Sanholt 142495584Sanholt /* Flush any pending CP commands. This ensures any outstanding 142595584Sanholt * commands are exectuted by the engine before we turn it off. 142695584Sanholt */ 142795584Sanholt if ( stop.flush ) { 142895584Sanholt radeon_do_cp_flush( dev_priv ); 142995584Sanholt } 143095584Sanholt 143195584Sanholt /* If we fail to make the engine go idle, we return an error 143295584Sanholt * code so that the DRM ioctl wrapper can try again. 143395584Sanholt */ 143495584Sanholt if ( stop.idle ) { 143595584Sanholt ret = radeon_do_cp_idle( dev_priv ); 143695584Sanholt if ( ret ) return ret; 143795584Sanholt } 143895584Sanholt 143995584Sanholt /* Finally, we can turn off the CP. If the engine isn't idle, 144095584Sanholt * we will get some dropped triangles as they won't be fully 144195584Sanholt * rendered before the CP is shut down. 144295584Sanholt */ 144395584Sanholt radeon_do_cp_stop( dev_priv ); 144495584Sanholt 144595584Sanholt /* Reset the engine */ 144695584Sanholt radeon_do_engine_reset( dev ); 144795584Sanholt 144895584Sanholt return 0; 144995584Sanholt} 145095584Sanholt 1451112015Sanholt 1452112015Sanholtvoid radeon_do_release( drm_device_t *dev ) 1453112015Sanholt{ 1454112015Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1455112015Sanholt int ret; 1456112015Sanholt 1457112015Sanholt if (dev_priv) { 1458112015Sanholt if (dev_priv->cp_running) { 1459112015Sanholt /* Stop the cp */ 1460112015Sanholt while ((ret = radeon_do_cp_idle( dev_priv )) != 0) { 1461112015Sanholt DRM_DEBUG("radeon_do_cp_idle %d\n", ret); 1462112015Sanholt#ifdef __linux__ 1463112015Sanholt schedule(); 1464112015Sanholt#else 1465112015Sanholt tsleep(&ret, PZERO, "rdnrel", 1); 1466112015Sanholt#endif 1467112015Sanholt } 1468112015Sanholt radeon_do_cp_stop( dev_priv ); 1469112015Sanholt radeon_do_engine_reset( dev ); 1470112015Sanholt } 1471112015Sanholt 1472112015Sanholt /* Disable *all* interrupts */ 1473112015Sanholt RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); 1474112015Sanholt 1475112015Sanholt /* Free memory heap structures */ 1476119895Sanholt radeon_mem_takedown( &(dev_priv->gart_heap) ); 1477112015Sanholt radeon_mem_takedown( &(dev_priv->fb_heap) ); 1478112015Sanholt 1479112015Sanholt /* deallocate kernel resources */ 1480112015Sanholt radeon_do_cleanup_cp( dev ); 1481112015Sanholt } 1482112015Sanholt} 1483112015Sanholt 148495584Sanholt/* Just reset the CP ring. Called as part of an X Server engine reset. 148595584Sanholt */ 1486112015Sanholtint radeon_cp_reset( DRM_IOCTL_ARGS ) 148795584Sanholt{ 1488112015Sanholt DRM_DEVICE; 148995584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1490112015Sanholt DRM_DEBUG( "\n" ); 149195584Sanholt 1492113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 149395584Sanholt 149495584Sanholt if ( !dev_priv ) { 1495112015Sanholt DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); 1496112015Sanholt return DRM_ERR(EINVAL); 149795584Sanholt } 149895584Sanholt 149995584Sanholt radeon_do_cp_reset( dev_priv ); 150095584Sanholt 150195584Sanholt /* The CP is no longer running after an engine reset */ 150295584Sanholt dev_priv->cp_running = 0; 150395584Sanholt 150495584Sanholt return 0; 150595584Sanholt} 150695584Sanholt 1507112015Sanholtint radeon_cp_idle( DRM_IOCTL_ARGS ) 150895584Sanholt{ 1509112015Sanholt DRM_DEVICE; 151095584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1511112015Sanholt DRM_DEBUG( "\n" ); 151295584Sanholt 1513113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 151495584Sanholt 151595584Sanholt return radeon_do_cp_idle( dev_priv ); 151695584Sanholt} 151795584Sanholt 1518119098Sanholt/* Added by Charl P. Botha to call radeon_do_resume_cp(). 1519119098Sanholt */ 1520119098Sanholtint radeon_cp_resume( DRM_IOCTL_ARGS ) 1521119098Sanholt{ 1522119098Sanholt DRM_DEVICE; 1523119098Sanholt 1524119098Sanholt return radeon_do_resume_cp(dev); 1525119098Sanholt} 1526119098Sanholt 1527119098Sanholt 1528112015Sanholtint radeon_engine_reset( DRM_IOCTL_ARGS ) 152995584Sanholt{ 1530112015Sanholt DRM_DEVICE; 1531112015Sanholt DRM_DEBUG( "\n" ); 153295584Sanholt 1533113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 153495584Sanholt 153595584Sanholt return radeon_do_engine_reset( dev ); 153695584Sanholt} 153795584Sanholt 153895584Sanholt 153995584Sanholt/* ================================================================ 154095584Sanholt * Fullscreen mode 154195584Sanholt */ 154295584Sanholt 1543112015Sanholt/* KW: Deprecated to say the least: 1544112015Sanholt */ 1545112015Sanholtint radeon_fullscreen( DRM_IOCTL_ARGS ) 154695584Sanholt{ 154795584Sanholt return 0; 154895584Sanholt} 154995584Sanholt 155095584Sanholt 155195584Sanholt/* ================================================================ 155295584Sanholt * Freelist management 155395584Sanholt */ 155495584Sanholt 1555112015Sanholt/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through 1556112015Sanholt * bufs until freelist code is used. Note this hides a problem with 1557112015Sanholt * the scratch register * (used to keep track of last buffer 1558112015Sanholt * completed) being written to before * the last buffer has actually 1559112015Sanholt * completed rendering. 1560112015Sanholt * 1561112015Sanholt * KW: It's also a good way to find free buffers quickly. 1562112015Sanholt * 1563112015Sanholt * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't 1564112015Sanholt * sleep. However, bugs in older versions of radeon_accel.c mean that 1565112015Sanholt * we essentially have to do this, else old clients will break. 1566112015Sanholt * 1567112015Sanholt * However, it does leave open a potential deadlock where all the 1568112015Sanholt * buffers are held by other clients, which can't release them because 1569112015Sanholt * they can't get the lock. 1570112015Sanholt */ 1571112015Sanholt 1572112015Sanholtdrm_buf_t *radeon_freelist_get( drm_device_t *dev ) 157395584Sanholt{ 157495584Sanholt drm_device_dma_t *dma = dev->dma; 157595584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1576112015Sanholt drm_radeon_buf_priv_t *buf_priv; 157795584Sanholt drm_buf_t *buf; 1578112015Sanholt int i, t; 1579112015Sanholt int start; 158095584Sanholt 1581112015Sanholt if ( ++dev_priv->last_buf >= dma->buf_count ) 1582112015Sanholt dev_priv->last_buf = 0; 158395584Sanholt 1584112015Sanholt start = dev_priv->last_buf; 158595584Sanholt 1586112015Sanholt for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { 1587112015Sanholt u32 done_age = GET_SCRATCH( 1 ); 1588112015Sanholt DRM_DEBUG("done_age = %d\n",done_age); 1589112015Sanholt for ( i = start ; i < dma->buf_count ; i++ ) { 1590112015Sanholt buf = dma->buflist[i]; 1591112015Sanholt buf_priv = buf->dev_private; 1592113995Sanholt if ( buf->filp == 0 || (buf->pending && 1593112015Sanholt buf_priv->age <= done_age) ) { 1594112015Sanholt dev_priv->stats.requested_bufs++; 1595112015Sanholt buf->pending = 0; 1596112015Sanholt return buf; 1597112015Sanholt } 1598112015Sanholt start = 0; 1599112015Sanholt } 160095584Sanholt 1601112015Sanholt if (t) { 1602112015Sanholt DRM_UDELAY( 1 ); 1603112015Sanholt dev_priv->stats.freelist_loops++; 1604112015Sanholt } 160595584Sanholt } 160695584Sanholt 1607112015Sanholt DRM_DEBUG( "returning NULL!\n" ); 1608112015Sanholt return NULL; 160995584Sanholt} 1610112015Sanholt#if 0 161195584Sanholtdrm_buf_t *radeon_freelist_get( drm_device_t *dev ) 161295584Sanholt{ 161395584Sanholt drm_device_dma_t *dma = dev->dma; 161495584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 161595584Sanholt drm_radeon_buf_priv_t *buf_priv; 161695584Sanholt drm_buf_t *buf; 161795584Sanholt int i, t; 161895584Sanholt int start; 1619112015Sanholt u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); 162095584Sanholt 162195584Sanholt if ( ++dev_priv->last_buf >= dma->buf_count ) 162295584Sanholt dev_priv->last_buf = 0; 1623112015Sanholt 162495584Sanholt start = dev_priv->last_buf; 1625112015Sanholt dev_priv->stats.freelist_loops++; 1626112015Sanholt 1627112015Sanholt for ( t = 0 ; t < 2 ; t++ ) { 162895584Sanholt for ( i = start ; i < dma->buf_count ; i++ ) { 162995584Sanholt buf = dma->buflist[i]; 163095584Sanholt buf_priv = buf->dev_private; 1631113995Sanholt if ( buf->filp == 0 || (buf->pending && 1632112015Sanholt buf_priv->age <= done_age) ) { 1633112015Sanholt dev_priv->stats.requested_bufs++; 163495584Sanholt buf->pending = 0; 163595584Sanholt return buf; 163695584Sanholt } 163795584Sanholt } 1638112015Sanholt start = 0; 163995584Sanholt } 164095584Sanholt 164195584Sanholt return NULL; 164295584Sanholt} 1643112015Sanholt#endif 164495584Sanholt 164595584Sanholtvoid radeon_freelist_reset( drm_device_t *dev ) 164695584Sanholt{ 164795584Sanholt drm_device_dma_t *dma = dev->dma; 164895584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 164995584Sanholt int i; 165095584Sanholt 165195584Sanholt dev_priv->last_buf = 0; 165295584Sanholt for ( i = 0 ; i < dma->buf_count ; i++ ) { 165395584Sanholt drm_buf_t *buf = dma->buflist[i]; 165495584Sanholt drm_radeon_buf_priv_t *buf_priv = buf->dev_private; 165595584Sanholt buf_priv->age = 0; 165695584Sanholt } 165795584Sanholt} 165895584Sanholt 165995584Sanholt 166095584Sanholt/* ================================================================ 166195584Sanholt * CP command submission 166295584Sanholt */ 166395584Sanholt 166495584Sanholtint radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ) 166595584Sanholt{ 166695584Sanholt drm_radeon_ring_buffer_t *ring = &dev_priv->ring; 166795584Sanholt int i; 1668113995Sanholt u32 last_head = GET_RING_HEAD( dev_priv ); 166995584Sanholt 167095584Sanholt for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 1671113995Sanholt u32 head = GET_RING_HEAD( dev_priv ); 1672112015Sanholt 1673112015Sanholt ring->space = (head - ring->tail) * sizeof(u32); 1674112015Sanholt if ( ring->space <= 0 ) 1675112015Sanholt ring->space += ring->size; 167695584Sanholt if ( ring->space > n ) 167795584Sanholt return 0; 1678112015Sanholt 1679112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 1680112015Sanholt 1681112015Sanholt if (head != last_head) 1682112015Sanholt i = 0; 1683112015Sanholt last_head = head; 1684112015Sanholt 1685112015Sanholt DRM_UDELAY( 1 ); 168695584Sanholt } 168795584Sanholt 168895584Sanholt /* FIXME: This return value is ignored in the BEGIN_RING macro! */ 168995584Sanholt#if RADEON_FIFO_DEBUG 169095584Sanholt radeon_status( dev_priv ); 169195584Sanholt DRM_ERROR( "failed!\n" ); 169295584Sanholt#endif 1693112015Sanholt return DRM_ERR(EBUSY); 169495584Sanholt} 169595584Sanholt 1696113995Sanholtstatic int radeon_cp_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d ) 169795584Sanholt{ 169895584Sanholt int i; 169995584Sanholt drm_buf_t *buf; 170095584Sanholt 170195584Sanholt for ( i = d->granted_count ; i < d->request_count ; i++ ) { 170295584Sanholt buf = radeon_freelist_get( dev ); 1703112015Sanholt if ( !buf ) return DRM_ERR(EBUSY); /* NOTE: broken client */ 170495584Sanholt 1705113995Sanholt buf->filp = filp; 170695584Sanholt 1707112015Sanholt if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, 170895584Sanholt sizeof(buf->idx) ) ) 1709112015Sanholt return DRM_ERR(EFAULT); 1710112015Sanholt if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, 171195584Sanholt sizeof(buf->total) ) ) 1712112015Sanholt return DRM_ERR(EFAULT); 171395584Sanholt 171495584Sanholt d->granted_count++; 171595584Sanholt } 171695584Sanholt return 0; 171795584Sanholt} 171895584Sanholt 1719112015Sanholtint radeon_cp_buffers( DRM_IOCTL_ARGS ) 172095584Sanholt{ 1721112015Sanholt DRM_DEVICE; 172295584Sanholt drm_device_dma_t *dma = dev->dma; 172395584Sanholt int ret = 0; 172495584Sanholt drm_dma_t d; 172595584Sanholt 1726113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 172795584Sanholt 1728112015Sanholt DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); 172995584Sanholt 173095584Sanholt /* Please don't send us buffers. 173195584Sanholt */ 173295584Sanholt if ( d.send_count != 0 ) { 173395584Sanholt DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", 1734112015Sanholt DRM_CURRENTPID, d.send_count ); 1735112015Sanholt return DRM_ERR(EINVAL); 173695584Sanholt } 173795584Sanholt 173895584Sanholt /* We'll send you buffers. 173995584Sanholt */ 174095584Sanholt if ( d.request_count < 0 || d.request_count > dma->buf_count ) { 174195584Sanholt DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", 1742112015Sanholt DRM_CURRENTPID, d.request_count, dma->buf_count ); 1743112015Sanholt return DRM_ERR(EINVAL); 174495584Sanholt } 174595584Sanholt 174695584Sanholt d.granted_count = 0; 174795584Sanholt 174895584Sanholt if ( d.request_count ) { 1749113995Sanholt ret = radeon_cp_get_buffers( filp, dev, &d ); 175095584Sanholt } 175195584Sanholt 1752112015Sanholt DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); 175395584Sanholt 175495584Sanholt return ret; 175595584Sanholt} 1756