radeon_cp.c revision 119895
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 119895 2003-09-09 00:24:31Z 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, 860119895Sanholt (dev_priv->gart_vm_start - 1) & 0xffff0000 ); 86195584Sanholt 862119895Sanholt#if __REALLY_HAVE_AGP 86395584Sanholt if ( !dev_priv->is_pci ) { 86495584Sanholt RADEON_WRITE( RADEON_MC_AGP_LOCATION, 865119895Sanholt (((dev_priv->gart_vm_start - 1 + 866119895Sanholt dev_priv->gart_size) & 0xffff0000) | 867119895Sanholt (dev_priv->gart_vm_start >> 16)) ); 86895584Sanholt 86995584Sanholt ring_start = (dev_priv->cp_ring->offset 87095584Sanholt - dev->agp->base 871119895Sanholt + dev_priv->gart_vm_start); 872119895Sanholt } else 87395584Sanholt#endif 87495584Sanholt ring_start = (dev_priv->cp_ring->offset 87595584Sanholt - dev->sg->handle 876119895Sanholt + dev_priv->gart_vm_start); 87795584Sanholt 87895584Sanholt RADEON_WRITE( RADEON_CP_RB_BASE, ring_start ); 87995584Sanholt 88095584Sanholt /* Set the write pointer delay */ 88195584Sanholt RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 ); 88295584Sanholt 88395584Sanholt /* Initialize the ring buffer's read and write pointers */ 88495584Sanholt cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); 88595584Sanholt RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); 886113995Sanholt SET_RING_HEAD( dev_priv, cur_read_ptr ); 88795584Sanholt dev_priv->ring.tail = cur_read_ptr; 88895584Sanholt 889113995Sanholt#if __REALLY_HAVE_AGP 89095584Sanholt if ( !dev_priv->is_pci ) { 89195584Sanholt RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, 892113995Sanholt dev_priv->ring_rptr->offset 893113995Sanholt - dev->agp->base 894119895Sanholt + dev_priv->gart_vm_start); 895113995Sanholt } else 896113995Sanholt#endif 897113995Sanholt { 89895584Sanholt drm_sg_mem_t *entry = dev->sg; 89995584Sanholt unsigned long tmp_ofs, page_ofs; 90095584Sanholt 90195584Sanholt tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle; 90295584Sanholt page_ofs = tmp_ofs >> PAGE_SHIFT; 90395584Sanholt 90495584Sanholt RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, 90595584Sanholt entry->busaddr[page_ofs]); 906113995Sanholt DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n", 907119098Sanholt (unsigned long) entry->busaddr[page_ofs], 90895584Sanholt entry->handle + tmp_ofs ); 90995584Sanholt } 91095584Sanholt 911112015Sanholt /* Initialize the scratch register pointer. This will cause 912112015Sanholt * the scratch register values to be written out to memory 913112015Sanholt * whenever they are updated. 914112015Sanholt * 915112015Sanholt * We simply put this behind the ring read pointer, this works 916112015Sanholt * with PCI GART as well as (whatever kind of) AGP GART 917112015Sanholt */ 918112015Sanholt RADEON_WRITE( RADEON_SCRATCH_ADDR, RADEON_READ( RADEON_CP_RB_RPTR_ADDR ) 919112015Sanholt + RADEON_SCRATCH_REG_OFFSET ); 920112015Sanholt 921112015Sanholt dev_priv->scratch = ((__volatile__ u32 *) 922113995Sanholt dev_priv->ring_rptr->handle + 923112015Sanholt (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); 924112015Sanholt 925112015Sanholt RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); 926112015Sanholt 927112015Sanholt /* Writeback doesn't seem to work everywhere, test it first */ 928112015Sanholt DRM_WRITE32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0 ); 929112015Sanholt RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef ); 930112015Sanholt 931112015Sanholt for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) { 932112015Sanholt if ( DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1) ) == 0xdeadbeef ) 933112015Sanholt break; 934112015Sanholt DRM_UDELAY( 1 ); 935112015Sanholt } 936112015Sanholt 937112015Sanholt if ( tmp < dev_priv->usec_timeout ) { 938112015Sanholt dev_priv->writeback_works = 1; 939112015Sanholt DRM_DEBUG( "writeback test succeeded, tmp=%d\n", tmp ); 940112015Sanholt } else { 941112015Sanholt dev_priv->writeback_works = 0; 942112015Sanholt DRM_DEBUG( "writeback test failed\n" ); 943112015Sanholt } 944112015Sanholt 945112015Sanholt dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; 946112015Sanholt RADEON_WRITE( RADEON_LAST_FRAME_REG, 947112015Sanholt dev_priv->sarea_priv->last_frame ); 948112015Sanholt 949112015Sanholt dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0; 950112015Sanholt RADEON_WRITE( RADEON_LAST_DISPATCH_REG, 951112015Sanholt dev_priv->sarea_priv->last_dispatch ); 952112015Sanholt 953112015Sanholt dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; 954112015Sanholt RADEON_WRITE( RADEON_LAST_CLEAR_REG, 955112015Sanholt dev_priv->sarea_priv->last_clear ); 956112015Sanholt 95795584Sanholt /* Set ring buffer size */ 958112015Sanholt#ifdef __BIG_ENDIAN 959112015Sanholt RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT ); 960112015Sanholt#else 96195584Sanholt RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw ); 962112015Sanholt#endif 96395584Sanholt 96495584Sanholt radeon_do_wait_for_idle( dev_priv ); 96595584Sanholt 96695584Sanholt /* Turn on bus mastering */ 96795584Sanholt tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS; 96895584Sanholt RADEON_WRITE( RADEON_BUS_CNTL, tmp ); 96995584Sanholt 97095584Sanholt /* Sync everything up */ 97195584Sanholt RADEON_WRITE( RADEON_ISYNC_CNTL, 97295584Sanholt (RADEON_ISYNC_ANY2D_IDLE3D | 97395584Sanholt RADEON_ISYNC_ANY3D_IDLE2D | 97495584Sanholt RADEON_ISYNC_WAIT_IDLEGUI | 97595584Sanholt RADEON_ISYNC_CPSCRATCH_IDLEGUI) ); 97695584Sanholt} 97795584Sanholt 978119098Sanholt/* Enable or disable PCI GART on the chip */ 979119098Sanholtstatic void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on ) 980119098Sanholt{ 981119098Sanholt u32 tmp = RADEON_READ( RADEON_AIC_CNTL ); 982119098Sanholt 983119098Sanholt if ( on ) { 984119098Sanholt RADEON_WRITE( RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN ); 985119098Sanholt 986119098Sanholt /* set PCI GART page-table base address 987119098Sanholt */ 988119098Sanholt RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart ); 989119098Sanholt 990119098Sanholt /* set address range for PCI address translate 991119098Sanholt */ 992119895Sanholt RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start ); 993119895Sanholt RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start 994119895Sanholt + dev_priv->gart_size - 1); 995119098Sanholt 996119895Sanholt /* Turn off AGP aperture -- is this required for PCI GART? 997119098Sanholt */ 998119098Sanholt RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ 999119098Sanholt RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ 1000119098Sanholt } else { 1001119098Sanholt RADEON_WRITE( RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN ); 1002119098Sanholt } 1003119098Sanholt} 1004119098Sanholt 100595584Sanholtstatic int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) 100695584Sanholt{ 100795584Sanholt drm_radeon_private_t *dev_priv; 1008112015Sanholt DRM_DEBUG( "\n" ); 100995584Sanholt 101095584Sanholt dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); 101195584Sanholt if ( dev_priv == NULL ) 1012112015Sanholt return DRM_ERR(ENOMEM); 101395584Sanholt 101495584Sanholt memset( dev_priv, 0, sizeof(drm_radeon_private_t) ); 101595584Sanholt 101695584Sanholt dev_priv->is_pci = init->is_pci; 101795584Sanholt 101895584Sanholt if ( dev_priv->is_pci && !dev->sg ) { 101995584Sanholt DRM_ERROR( "PCI GART memory not allocated!\n" ); 102095584Sanholt dev->dev_private = (void *)dev_priv; 102195584Sanholt radeon_do_cleanup_cp(dev); 1022112015Sanholt return DRM_ERR(EINVAL); 102395584Sanholt } 102495584Sanholt 102595584Sanholt dev_priv->usec_timeout = init->usec_timeout; 102695584Sanholt if ( dev_priv->usec_timeout < 1 || 102795584Sanholt dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) { 102895584Sanholt DRM_DEBUG( "TIMEOUT problem!\n" ); 102995584Sanholt dev->dev_private = (void *)dev_priv; 103095584Sanholt radeon_do_cleanup_cp(dev); 1031112015Sanholt return DRM_ERR(EINVAL); 103295584Sanholt } 103395584Sanholt 1034112015Sanholt dev_priv->is_r200 = (init->func == RADEON_INIT_R200_CP); 1035112015Sanholt dev_priv->do_boxes = 0; 103695584Sanholt dev_priv->cp_mode = init->cp_mode; 103795584Sanholt 103895584Sanholt /* We don't support anything other than bus-mastering ring mode, 103995584Sanholt * but the ring can be in either AGP or PCI space for the ring 104095584Sanholt * read pointer. 104195584Sanholt */ 104295584Sanholt if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) && 104395584Sanholt ( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) { 104495584Sanholt DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode ); 104595584Sanholt dev->dev_private = (void *)dev_priv; 104695584Sanholt radeon_do_cleanup_cp(dev); 1047112015Sanholt return DRM_ERR(EINVAL); 104895584Sanholt } 104995584Sanholt 105095584Sanholt switch ( init->fb_bpp ) { 105195584Sanholt case 16: 105295584Sanholt dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; 105395584Sanholt break; 105495584Sanholt case 32: 105595584Sanholt default: 105695584Sanholt dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; 105795584Sanholt break; 105895584Sanholt } 105995584Sanholt dev_priv->front_offset = init->front_offset; 106095584Sanholt dev_priv->front_pitch = init->front_pitch; 106195584Sanholt dev_priv->back_offset = init->back_offset; 106295584Sanholt dev_priv->back_pitch = init->back_pitch; 106395584Sanholt 106495584Sanholt switch ( init->depth_bpp ) { 106595584Sanholt case 16: 106695584Sanholt dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; 106795584Sanholt break; 106895584Sanholt case 32: 106995584Sanholt default: 107095584Sanholt dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; 107195584Sanholt break; 107295584Sanholt } 107395584Sanholt dev_priv->depth_offset = init->depth_offset; 107495584Sanholt dev_priv->depth_pitch = init->depth_pitch; 107595584Sanholt 107695584Sanholt dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) | 107795584Sanholt (dev_priv->front_offset >> 10)); 107895584Sanholt dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) | 107995584Sanholt (dev_priv->back_offset >> 10)); 108095584Sanholt dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) | 108195584Sanholt (dev_priv->depth_offset >> 10)); 108295584Sanholt 108395584Sanholt /* Hardware state for depth clears. Remove this if/when we no 108495584Sanholt * longer clear the depth buffer with a 3D rectangle. Hard-code 108595584Sanholt * all values to prevent unwanted 3D state from slipping through 108695584Sanholt * and screwing with the clear operation. 108795584Sanholt */ 108895584Sanholt dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | 108995584Sanholt (dev_priv->color_fmt << 10) | 1090112015Sanholt (1<<15)); 109195584Sanholt 1092112015Sanholt dev_priv->depth_clear.rb3d_zstencilcntl = 1093112015Sanholt (dev_priv->depth_fmt | 1094112015Sanholt RADEON_Z_TEST_ALWAYS | 1095112015Sanholt RADEON_STENCIL_TEST_ALWAYS | 1096112015Sanholt RADEON_STENCIL_S_FAIL_REPLACE | 1097112015Sanholt RADEON_STENCIL_ZPASS_REPLACE | 1098112015Sanholt RADEON_STENCIL_ZFAIL_REPLACE | 1099112015Sanholt RADEON_Z_WRITE_ENABLE); 110095584Sanholt 110195584Sanholt dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | 110295584Sanholt RADEON_BFACE_SOLID | 110395584Sanholt RADEON_FFACE_SOLID | 110495584Sanholt RADEON_FLAT_SHADE_VTX_LAST | 110595584Sanholt RADEON_DIFFUSE_SHADE_FLAT | 110695584Sanholt RADEON_ALPHA_SHADE_FLAT | 110795584Sanholt RADEON_SPECULAR_SHADE_FLAT | 110895584Sanholt RADEON_FOG_SHADE_FLAT | 110995584Sanholt RADEON_VTX_PIX_CENTER_OGL | 111095584Sanholt RADEON_ROUND_MODE_TRUNC | 111195584Sanholt RADEON_ROUND_PREC_8TH_PIX); 111295584Sanholt 1113112015Sanholt DRM_GETSAREA(); 1114113995Sanholt 1115113995Sanholt dev_priv->fb_offset = init->fb_offset; 1116113995Sanholt dev_priv->mmio_offset = init->mmio_offset; 1117113995Sanholt dev_priv->ring_offset = init->ring_offset; 1118113995Sanholt dev_priv->ring_rptr_offset = init->ring_rptr_offset; 1119113995Sanholt dev_priv->buffers_offset = init->buffers_offset; 1120119895Sanholt dev_priv->gart_textures_offset = init->gart_textures_offset; 1121112015Sanholt 112295584Sanholt if(!dev_priv->sarea) { 112395584Sanholt DRM_ERROR("could not find sarea!\n"); 112495584Sanholt dev->dev_private = (void *)dev_priv; 112595584Sanholt radeon_do_cleanup_cp(dev); 1126112015Sanholt return DRM_ERR(EINVAL); 112795584Sanholt } 112895584Sanholt 112995584Sanholt DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); 113095584Sanholt if(!dev_priv->fb) { 113195584Sanholt DRM_ERROR("could not find framebuffer!\n"); 113295584Sanholt dev->dev_private = (void *)dev_priv; 113395584Sanholt radeon_do_cleanup_cp(dev); 1134112015Sanholt return DRM_ERR(EINVAL); 113595584Sanholt } 113695584Sanholt DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); 113795584Sanholt if(!dev_priv->mmio) { 113895584Sanholt DRM_ERROR("could not find mmio region!\n"); 113995584Sanholt dev->dev_private = (void *)dev_priv; 114095584Sanholt radeon_do_cleanup_cp(dev); 1141112015Sanholt return DRM_ERR(EINVAL); 114295584Sanholt } 114395584Sanholt DRM_FIND_MAP( dev_priv->cp_ring, init->ring_offset ); 114495584Sanholt if(!dev_priv->cp_ring) { 114595584Sanholt DRM_ERROR("could not find cp ring region!\n"); 114695584Sanholt dev->dev_private = (void *)dev_priv; 114795584Sanholt radeon_do_cleanup_cp(dev); 1148112015Sanholt return DRM_ERR(EINVAL); 114995584Sanholt } 115095584Sanholt DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); 115195584Sanholt if(!dev_priv->ring_rptr) { 115295584Sanholt DRM_ERROR("could not find ring read pointer!\n"); 115395584Sanholt dev->dev_private = (void *)dev_priv; 115495584Sanholt radeon_do_cleanup_cp(dev); 1155112015Sanholt return DRM_ERR(EINVAL); 115695584Sanholt } 115795584Sanholt DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); 115895584Sanholt if(!dev_priv->buffers) { 115995584Sanholt DRM_ERROR("could not find dma buffer region!\n"); 116095584Sanholt dev->dev_private = (void *)dev_priv; 116195584Sanholt radeon_do_cleanup_cp(dev); 1162112015Sanholt return DRM_ERR(EINVAL); 116395584Sanholt } 116495584Sanholt 1165119895Sanholt if ( init->gart_textures_offset ) { 1166119895Sanholt DRM_FIND_MAP( dev_priv->gart_textures, init->gart_textures_offset ); 1167119895Sanholt if ( !dev_priv->gart_textures ) { 1168119895Sanholt DRM_ERROR("could not find GART texture region!\n"); 116995584Sanholt dev->dev_private = (void *)dev_priv; 117095584Sanholt radeon_do_cleanup_cp(dev); 1171112015Sanholt return DRM_ERR(EINVAL); 117295584Sanholt } 117395584Sanholt } 117495584Sanholt 117595584Sanholt dev_priv->sarea_priv = 117695584Sanholt (drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle + 117795584Sanholt init->sarea_priv_offset); 117895584Sanholt 1179119098Sanholt#if __REALLY_HAVE_AGP 118095584Sanholt if ( !dev_priv->is_pci ) { 1181119098Sanholt DRM_IOREMAP( dev_priv->cp_ring, dev ); 1182119098Sanholt DRM_IOREMAP( dev_priv->ring_rptr, dev ); 1183119098Sanholt DRM_IOREMAP( dev_priv->buffers, dev ); 118495584Sanholt if(!dev_priv->cp_ring->handle || 118595584Sanholt !dev_priv->ring_rptr->handle || 118695584Sanholt !dev_priv->buffers->handle) { 118795584Sanholt DRM_ERROR("could not find ioremap agp regions!\n"); 118895584Sanholt dev->dev_private = (void *)dev_priv; 118995584Sanholt radeon_do_cleanup_cp(dev); 1190112015Sanholt return DRM_ERR(EINVAL); 119195584Sanholt } 1192119098Sanholt } else 1193119098Sanholt#endif 1194119098Sanholt { 119595584Sanholt dev_priv->cp_ring->handle = 119695584Sanholt (void *)dev_priv->cp_ring->offset; 119795584Sanholt dev_priv->ring_rptr->handle = 119895584Sanholt (void *)dev_priv->ring_rptr->offset; 119995584Sanholt dev_priv->buffers->handle = (void *)dev_priv->buffers->offset; 120095584Sanholt 120195584Sanholt DRM_DEBUG( "dev_priv->cp_ring->handle %p\n", 120295584Sanholt dev_priv->cp_ring->handle ); 120395584Sanholt DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n", 120495584Sanholt dev_priv->ring_rptr->handle ); 120595584Sanholt DRM_DEBUG( "dev_priv->buffers->handle %p\n", 120695584Sanholt dev_priv->buffers->handle ); 120795584Sanholt } 120895584Sanholt 120995584Sanholt 1210119895Sanholt dev_priv->gart_size = init->gart_size; 1211119895Sanholt dev_priv->gart_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE ); 121295584Sanholt#if __REALLY_HAVE_AGP 121395584Sanholt if ( !dev_priv->is_pci ) 1214119895Sanholt dev_priv->gart_buffers_offset = (dev_priv->buffers->offset 121595584Sanholt - dev->agp->base 1216119895Sanholt + dev_priv->gart_vm_start); 121795584Sanholt else 121895584Sanholt#endif 1219119895Sanholt dev_priv->gart_buffers_offset = (dev_priv->buffers->offset 122095584Sanholt - dev->sg->handle 1221119895Sanholt + dev_priv->gart_vm_start); 122295584Sanholt 1223119895Sanholt DRM_DEBUG( "dev_priv->gart_size %d\n", 1224119895Sanholt dev_priv->gart_size ); 1225119895Sanholt DRM_DEBUG( "dev_priv->gart_vm_start 0x%x\n", 1226119895Sanholt dev_priv->gart_vm_start ); 1227119895Sanholt DRM_DEBUG( "dev_priv->gart_buffers_offset 0x%lx\n", 1228119895Sanholt dev_priv->gart_buffers_offset ); 122995584Sanholt 123095584Sanholt dev_priv->ring.start = (u32 *)dev_priv->cp_ring->handle; 123195584Sanholt dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle 123295584Sanholt + init->ring_size / sizeof(u32)); 123395584Sanholt dev_priv->ring.size = init->ring_size; 123495584Sanholt dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 ); 123595584Sanholt 123695584Sanholt dev_priv->ring.tail_mask = 123795584Sanholt (dev_priv->ring.size / sizeof(u32)) - 1; 123895584Sanholt 123995584Sanholt dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; 124095584Sanholt 1241119098Sanholt#if __REALLY_HAVE_AGP 1242119098Sanholt if ( !dev_priv->is_pci ) { 1243119098Sanholt /* Turn off PCI GART */ 1244119098Sanholt radeon_set_pcigart( dev_priv, 0 ); 1245119098Sanholt } else 1246119098Sanholt#endif 1247119098Sanholt { 124895584Sanholt if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, 124995584Sanholt &dev_priv->bus_pci_gart)) { 125095584Sanholt DRM_ERROR( "failed to init PCI GART!\n" ); 125195584Sanholt dev->dev_private = (void *)dev_priv; 125295584Sanholt radeon_do_cleanup_cp(dev); 1253112015Sanholt return DRM_ERR(ENOMEM); 125495584Sanholt } 125595584Sanholt 1256119098Sanholt /* Turn on PCI GART */ 1257119098Sanholt radeon_set_pcigart( dev_priv, 1 ); 125895584Sanholt } 125995584Sanholt 126095584Sanholt radeon_cp_load_microcode( dev_priv ); 126195584Sanholt radeon_cp_init_ring_buffer( dev, dev_priv ); 126295584Sanholt 126395584Sanholt dev_priv->last_buf = 0; 126495584Sanholt 126595584Sanholt dev->dev_private = (void *)dev_priv; 126695584Sanholt 126795584Sanholt radeon_do_engine_reset( dev ); 126895584Sanholt 126995584Sanholt return 0; 127095584Sanholt} 127195584Sanholt 127295584Sanholtint radeon_do_cleanup_cp( drm_device_t *dev ) 127395584Sanholt{ 1274112015Sanholt DRM_DEBUG( "\n" ); 127595584Sanholt 1276119098Sanholt#if _HAVE_DMA_IRQ 1277119098Sanholt /* Make sure interrupts are disabled here because the uninstall ioctl 1278119098Sanholt * may not have been called from userspace and after dev_private 1279119098Sanholt * is freed, it's too late. 1280119098Sanholt */ 1281119098Sanholt if ( dev->irq ) DRM(irq_uninstall)(dev); 1282119098Sanholt#endif 1283119098Sanholt 128495584Sanholt if ( dev->dev_private ) { 128595584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 128695584Sanholt 1287119098Sanholt#if __REALLY_HAVE_AGP 128895584Sanholt if ( !dev_priv->is_pci ) { 1289113995Sanholt if ( dev_priv->cp_ring != NULL ) 1290119098Sanholt DRM_IOREMAPFREE( dev_priv->cp_ring, dev ); 1291113995Sanholt if ( dev_priv->ring_rptr != NULL ) 1292119098Sanholt DRM_IOREMAPFREE( dev_priv->ring_rptr, dev ); 1293113995Sanholt if ( dev_priv->buffers != NULL ) 1294119098Sanholt DRM_IOREMAPFREE( dev_priv->buffers, dev ); 1295119098Sanholt } else 1296119098Sanholt#endif 1297119098Sanholt { 129895584Sanholt if (!DRM(ati_pcigart_cleanup)( dev, 129995584Sanholt dev_priv->phys_pci_gart, 130095584Sanholt dev_priv->bus_pci_gart )) 130195584Sanholt DRM_ERROR( "failed to cleanup PCI GART!\n" ); 130295584Sanholt } 130395584Sanholt 130495584Sanholt DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t), 130595584Sanholt DRM_MEM_DRIVER ); 130695584Sanholt dev->dev_private = NULL; 130795584Sanholt } 130895584Sanholt 130995584Sanholt return 0; 131095584Sanholt} 131195584Sanholt 1312119098Sanholt/* This code will reinit the Radeon CP hardware after a resume from disc. 1313119098Sanholt * AFAIK, it would be very difficult to pickle the state at suspend time, so 1314119098Sanholt * here we make sure that all Radeon hardware initialisation is re-done without 1315119098Sanholt * affecting running applications. 1316119098Sanholt * 1317119098Sanholt * Charl P. Botha <http://cpbotha.net> 1318119098Sanholt */ 1319119098Sanholtstatic int radeon_do_resume_cp( drm_device_t *dev ) 1320119098Sanholt{ 1321119098Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1322119098Sanholt 1323119098Sanholt if ( !dev_priv ) { 1324119098Sanholt DRM_ERROR( "Called with no initialization\n" ); 1325119098Sanholt return DRM_ERR( EINVAL ); 1326119098Sanholt } 1327119098Sanholt 1328119098Sanholt DRM_DEBUG("Starting radeon_do_resume_cp()\n"); 1329119098Sanholt 1330119098Sanholt#if __REALLY_HAVE_AGP 1331119098Sanholt if ( !dev_priv->is_pci ) { 1332119098Sanholt /* Turn off PCI GART */ 1333119098Sanholt radeon_set_pcigart( dev_priv, 0 ); 1334119098Sanholt } else 1335119098Sanholt#endif 1336119098Sanholt { 1337119098Sanholt /* Turn on PCI GART */ 1338119098Sanholt radeon_set_pcigart( dev_priv, 1 ); 1339119098Sanholt } 1340119098Sanholt 1341119098Sanholt radeon_cp_load_microcode( dev_priv ); 1342119098Sanholt radeon_cp_init_ring_buffer( dev, dev_priv ); 1343119098Sanholt 1344119098Sanholt radeon_do_engine_reset( dev ); 1345119098Sanholt 1346119098Sanholt DRM_DEBUG("radeon_do_resume_cp() complete\n"); 1347119098Sanholt 1348119098Sanholt return 0; 1349119098Sanholt} 1350119098Sanholt 1351119098Sanholt 1352112015Sanholtint radeon_cp_init( DRM_IOCTL_ARGS ) 135395584Sanholt{ 1354112015Sanholt DRM_DEVICE; 135595584Sanholt drm_radeon_init_t init; 135695584Sanholt 1357119098Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 1358119098Sanholt 1359112015Sanholt DRM_COPY_FROM_USER_IOCTL( init, (drm_radeon_init_t *)data, sizeof(init) ); 136095584Sanholt 136195584Sanholt switch ( init.func ) { 136295584Sanholt case RADEON_INIT_CP: 1363112015Sanholt case RADEON_INIT_R200_CP: 136495584Sanholt return radeon_do_init_cp( dev, &init ); 136595584Sanholt case RADEON_CLEANUP_CP: 136695584Sanholt return radeon_do_cleanup_cp( dev ); 136795584Sanholt } 136895584Sanholt 1369112015Sanholt return DRM_ERR(EINVAL); 137095584Sanholt} 137195584Sanholt 1372112015Sanholtint radeon_cp_start( DRM_IOCTL_ARGS ) 137395584Sanholt{ 1374112015Sanholt DRM_DEVICE; 137595584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1376112015Sanholt DRM_DEBUG( "\n" ); 137795584Sanholt 1378113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 137995584Sanholt 138095584Sanholt if ( dev_priv->cp_running ) { 1381112015Sanholt DRM_DEBUG( "%s while CP running\n", __FUNCTION__ ); 138295584Sanholt return 0; 138395584Sanholt } 138495584Sanholt if ( dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS ) { 138595584Sanholt DRM_DEBUG( "%s called with bogus CP mode (%d)\n", 1386112015Sanholt __FUNCTION__, dev_priv->cp_mode ); 138795584Sanholt return 0; 138895584Sanholt } 138995584Sanholt 139095584Sanholt radeon_do_cp_start( dev_priv ); 139195584Sanholt 139295584Sanholt return 0; 139395584Sanholt} 139495584Sanholt 139595584Sanholt/* Stop the CP. The engine must have been idled before calling this 139695584Sanholt * routine. 139795584Sanholt */ 1398112015Sanholtint radeon_cp_stop( DRM_IOCTL_ARGS ) 139995584Sanholt{ 1400112015Sanholt DRM_DEVICE; 140195584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 140295584Sanholt drm_radeon_cp_stop_t stop; 140395584Sanholt int ret; 1404112015Sanholt DRM_DEBUG( "\n" ); 140595584Sanholt 1406113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 140795584Sanholt 1408112015Sanholt DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t *)data, sizeof(stop) ); 140995584Sanholt 1410112015Sanholt if (!dev_priv->cp_running) 1411112015Sanholt return 0; 1412112015Sanholt 141395584Sanholt /* Flush any pending CP commands. This ensures any outstanding 141495584Sanholt * commands are exectuted by the engine before we turn it off. 141595584Sanholt */ 141695584Sanholt if ( stop.flush ) { 141795584Sanholt radeon_do_cp_flush( dev_priv ); 141895584Sanholt } 141995584Sanholt 142095584Sanholt /* If we fail to make the engine go idle, we return an error 142195584Sanholt * code so that the DRM ioctl wrapper can try again. 142295584Sanholt */ 142395584Sanholt if ( stop.idle ) { 142495584Sanholt ret = radeon_do_cp_idle( dev_priv ); 142595584Sanholt if ( ret ) return ret; 142695584Sanholt } 142795584Sanholt 142895584Sanholt /* Finally, we can turn off the CP. If the engine isn't idle, 142995584Sanholt * we will get some dropped triangles as they won't be fully 143095584Sanholt * rendered before the CP is shut down. 143195584Sanholt */ 143295584Sanholt radeon_do_cp_stop( dev_priv ); 143395584Sanholt 143495584Sanholt /* Reset the engine */ 143595584Sanholt radeon_do_engine_reset( dev ); 143695584Sanholt 143795584Sanholt return 0; 143895584Sanholt} 143995584Sanholt 1440112015Sanholt 1441112015Sanholtvoid radeon_do_release( drm_device_t *dev ) 1442112015Sanholt{ 1443112015Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1444112015Sanholt int ret; 1445112015Sanholt 1446112015Sanholt if (dev_priv) { 1447112015Sanholt if (dev_priv->cp_running) { 1448112015Sanholt /* Stop the cp */ 1449112015Sanholt while ((ret = radeon_do_cp_idle( dev_priv )) != 0) { 1450112015Sanholt DRM_DEBUG("radeon_do_cp_idle %d\n", ret); 1451112015Sanholt#ifdef __linux__ 1452112015Sanholt schedule(); 1453112015Sanholt#else 1454112015Sanholt tsleep(&ret, PZERO, "rdnrel", 1); 1455112015Sanholt#endif 1456112015Sanholt } 1457112015Sanholt radeon_do_cp_stop( dev_priv ); 1458112015Sanholt radeon_do_engine_reset( dev ); 1459112015Sanholt } 1460112015Sanholt 1461112015Sanholt /* Disable *all* interrupts */ 1462112015Sanholt RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); 1463112015Sanholt 1464112015Sanholt /* Free memory heap structures */ 1465119895Sanholt radeon_mem_takedown( &(dev_priv->gart_heap) ); 1466112015Sanholt radeon_mem_takedown( &(dev_priv->fb_heap) ); 1467112015Sanholt 1468112015Sanholt /* deallocate kernel resources */ 1469112015Sanholt radeon_do_cleanup_cp( dev ); 1470112015Sanholt } 1471112015Sanholt} 1472112015Sanholt 147395584Sanholt/* Just reset the CP ring. Called as part of an X Server engine reset. 147495584Sanholt */ 1475112015Sanholtint radeon_cp_reset( DRM_IOCTL_ARGS ) 147695584Sanholt{ 1477112015Sanholt DRM_DEVICE; 147895584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1479112015Sanholt DRM_DEBUG( "\n" ); 148095584Sanholt 1481113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 148295584Sanholt 148395584Sanholt if ( !dev_priv ) { 1484112015Sanholt DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); 1485112015Sanholt return DRM_ERR(EINVAL); 148695584Sanholt } 148795584Sanholt 148895584Sanholt radeon_do_cp_reset( dev_priv ); 148995584Sanholt 149095584Sanholt /* The CP is no longer running after an engine reset */ 149195584Sanholt dev_priv->cp_running = 0; 149295584Sanholt 149395584Sanholt return 0; 149495584Sanholt} 149595584Sanholt 1496112015Sanholtint radeon_cp_idle( DRM_IOCTL_ARGS ) 149795584Sanholt{ 1498112015Sanholt DRM_DEVICE; 149995584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1500112015Sanholt DRM_DEBUG( "\n" ); 150195584Sanholt 1502113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 150395584Sanholt 150495584Sanholt return radeon_do_cp_idle( dev_priv ); 150595584Sanholt} 150695584Sanholt 1507119098Sanholt/* Added by Charl P. Botha to call radeon_do_resume_cp(). 1508119098Sanholt */ 1509119098Sanholtint radeon_cp_resume( DRM_IOCTL_ARGS ) 1510119098Sanholt{ 1511119098Sanholt DRM_DEVICE; 1512119098Sanholt 1513119098Sanholt return radeon_do_resume_cp(dev); 1514119098Sanholt} 1515119098Sanholt 1516119098Sanholt 1517112015Sanholtint radeon_engine_reset( DRM_IOCTL_ARGS ) 151895584Sanholt{ 1519112015Sanholt DRM_DEVICE; 1520112015Sanholt DRM_DEBUG( "\n" ); 152195584Sanholt 1522113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 152395584Sanholt 152495584Sanholt return radeon_do_engine_reset( dev ); 152595584Sanholt} 152695584Sanholt 152795584Sanholt 152895584Sanholt/* ================================================================ 152995584Sanholt * Fullscreen mode 153095584Sanholt */ 153195584Sanholt 1532112015Sanholt/* KW: Deprecated to say the least: 1533112015Sanholt */ 1534112015Sanholtint radeon_fullscreen( DRM_IOCTL_ARGS ) 153595584Sanholt{ 153695584Sanholt return 0; 153795584Sanholt} 153895584Sanholt 153995584Sanholt 154095584Sanholt/* ================================================================ 154195584Sanholt * Freelist management 154295584Sanholt */ 154395584Sanholt 1544112015Sanholt/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through 1545112015Sanholt * bufs until freelist code is used. Note this hides a problem with 1546112015Sanholt * the scratch register * (used to keep track of last buffer 1547112015Sanholt * completed) being written to before * the last buffer has actually 1548112015Sanholt * completed rendering. 1549112015Sanholt * 1550112015Sanholt * KW: It's also a good way to find free buffers quickly. 1551112015Sanholt * 1552112015Sanholt * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't 1553112015Sanholt * sleep. However, bugs in older versions of radeon_accel.c mean that 1554112015Sanholt * we essentially have to do this, else old clients will break. 1555112015Sanholt * 1556112015Sanholt * However, it does leave open a potential deadlock where all the 1557112015Sanholt * buffers are held by other clients, which can't release them because 1558112015Sanholt * they can't get the lock. 1559112015Sanholt */ 1560112015Sanholt 1561112015Sanholtdrm_buf_t *radeon_freelist_get( drm_device_t *dev ) 156295584Sanholt{ 156395584Sanholt drm_device_dma_t *dma = dev->dma; 156495584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1565112015Sanholt drm_radeon_buf_priv_t *buf_priv; 156695584Sanholt drm_buf_t *buf; 1567112015Sanholt int i, t; 1568112015Sanholt int start; 156995584Sanholt 1570112015Sanholt if ( ++dev_priv->last_buf >= dma->buf_count ) 1571112015Sanholt dev_priv->last_buf = 0; 157295584Sanholt 1573112015Sanholt start = dev_priv->last_buf; 157495584Sanholt 1575112015Sanholt for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { 1576112015Sanholt u32 done_age = GET_SCRATCH( 1 ); 1577112015Sanholt DRM_DEBUG("done_age = %d\n",done_age); 1578112015Sanholt for ( i = start ; i < dma->buf_count ; i++ ) { 1579112015Sanholt buf = dma->buflist[i]; 1580112015Sanholt buf_priv = buf->dev_private; 1581113995Sanholt if ( buf->filp == 0 || (buf->pending && 1582112015Sanholt buf_priv->age <= done_age) ) { 1583112015Sanholt dev_priv->stats.requested_bufs++; 1584112015Sanholt buf->pending = 0; 1585112015Sanholt return buf; 1586112015Sanholt } 1587112015Sanholt start = 0; 1588112015Sanholt } 158995584Sanholt 1590112015Sanholt if (t) { 1591112015Sanholt DRM_UDELAY( 1 ); 1592112015Sanholt dev_priv->stats.freelist_loops++; 1593112015Sanholt } 159495584Sanholt } 159595584Sanholt 1596112015Sanholt DRM_DEBUG( "returning NULL!\n" ); 1597112015Sanholt return NULL; 159895584Sanholt} 1599112015Sanholt#if 0 160095584Sanholtdrm_buf_t *radeon_freelist_get( drm_device_t *dev ) 160195584Sanholt{ 160295584Sanholt drm_device_dma_t *dma = dev->dma; 160395584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 160495584Sanholt drm_radeon_buf_priv_t *buf_priv; 160595584Sanholt drm_buf_t *buf; 160695584Sanholt int i, t; 160795584Sanholt int start; 1608112015Sanholt u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); 160995584Sanholt 161095584Sanholt if ( ++dev_priv->last_buf >= dma->buf_count ) 161195584Sanholt dev_priv->last_buf = 0; 1612112015Sanholt 161395584Sanholt start = dev_priv->last_buf; 1614112015Sanholt dev_priv->stats.freelist_loops++; 1615112015Sanholt 1616112015Sanholt for ( t = 0 ; t < 2 ; t++ ) { 161795584Sanholt for ( i = start ; i < dma->buf_count ; i++ ) { 161895584Sanholt buf = dma->buflist[i]; 161995584Sanholt buf_priv = buf->dev_private; 1620113995Sanholt if ( buf->filp == 0 || (buf->pending && 1621112015Sanholt buf_priv->age <= done_age) ) { 1622112015Sanholt dev_priv->stats.requested_bufs++; 162395584Sanholt buf->pending = 0; 162495584Sanholt return buf; 162595584Sanholt } 162695584Sanholt } 1627112015Sanholt start = 0; 162895584Sanholt } 162995584Sanholt 163095584Sanholt return NULL; 163195584Sanholt} 1632112015Sanholt#endif 163395584Sanholt 163495584Sanholtvoid radeon_freelist_reset( drm_device_t *dev ) 163595584Sanholt{ 163695584Sanholt drm_device_dma_t *dma = dev->dma; 163795584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 163895584Sanholt int i; 163995584Sanholt 164095584Sanholt dev_priv->last_buf = 0; 164195584Sanholt for ( i = 0 ; i < dma->buf_count ; i++ ) { 164295584Sanholt drm_buf_t *buf = dma->buflist[i]; 164395584Sanholt drm_radeon_buf_priv_t *buf_priv = buf->dev_private; 164495584Sanholt buf_priv->age = 0; 164595584Sanholt } 164695584Sanholt} 164795584Sanholt 164895584Sanholt 164995584Sanholt/* ================================================================ 165095584Sanholt * CP command submission 165195584Sanholt */ 165295584Sanholt 165395584Sanholtint radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ) 165495584Sanholt{ 165595584Sanholt drm_radeon_ring_buffer_t *ring = &dev_priv->ring; 165695584Sanholt int i; 1657113995Sanholt u32 last_head = GET_RING_HEAD( dev_priv ); 165895584Sanholt 165995584Sanholt for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 1660113995Sanholt u32 head = GET_RING_HEAD( dev_priv ); 1661112015Sanholt 1662112015Sanholt ring->space = (head - ring->tail) * sizeof(u32); 1663112015Sanholt if ( ring->space <= 0 ) 1664112015Sanholt ring->space += ring->size; 166595584Sanholt if ( ring->space > n ) 166695584Sanholt return 0; 1667112015Sanholt 1668112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 1669112015Sanholt 1670112015Sanholt if (head != last_head) 1671112015Sanholt i = 0; 1672112015Sanholt last_head = head; 1673112015Sanholt 1674112015Sanholt DRM_UDELAY( 1 ); 167595584Sanholt } 167695584Sanholt 167795584Sanholt /* FIXME: This return value is ignored in the BEGIN_RING macro! */ 167895584Sanholt#if RADEON_FIFO_DEBUG 167995584Sanholt radeon_status( dev_priv ); 168095584Sanholt DRM_ERROR( "failed!\n" ); 168195584Sanholt#endif 1682112015Sanholt return DRM_ERR(EBUSY); 168395584Sanholt} 168495584Sanholt 1685113995Sanholtstatic int radeon_cp_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d ) 168695584Sanholt{ 168795584Sanholt int i; 168895584Sanholt drm_buf_t *buf; 168995584Sanholt 169095584Sanholt for ( i = d->granted_count ; i < d->request_count ; i++ ) { 169195584Sanholt buf = radeon_freelist_get( dev ); 1692112015Sanholt if ( !buf ) return DRM_ERR(EBUSY); /* NOTE: broken client */ 169395584Sanholt 1694113995Sanholt buf->filp = filp; 169595584Sanholt 1696112015Sanholt if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, 169795584Sanholt sizeof(buf->idx) ) ) 1698112015Sanholt return DRM_ERR(EFAULT); 1699112015Sanholt if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, 170095584Sanholt sizeof(buf->total) ) ) 1701112015Sanholt return DRM_ERR(EFAULT); 170295584Sanholt 170395584Sanholt d->granted_count++; 170495584Sanholt } 170595584Sanholt return 0; 170695584Sanholt} 170795584Sanholt 1708112015Sanholtint radeon_cp_buffers( DRM_IOCTL_ARGS ) 170995584Sanholt{ 1710112015Sanholt DRM_DEVICE; 171195584Sanholt drm_device_dma_t *dma = dev->dma; 171295584Sanholt int ret = 0; 171395584Sanholt drm_dma_t d; 171495584Sanholt 1715113995Sanholt LOCK_TEST_WITH_RETURN( dev, filp ); 171695584Sanholt 1717112015Sanholt DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); 171895584Sanholt 171995584Sanholt /* Please don't send us buffers. 172095584Sanholt */ 172195584Sanholt if ( d.send_count != 0 ) { 172295584Sanholt DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", 1723112015Sanholt DRM_CURRENTPID, d.send_count ); 1724112015Sanholt return DRM_ERR(EINVAL); 172595584Sanholt } 172695584Sanholt 172795584Sanholt /* We'll send you buffers. 172895584Sanholt */ 172995584Sanholt if ( d.request_count < 0 || d.request_count > dma->buf_count ) { 173095584Sanholt DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", 1731112015Sanholt DRM_CURRENTPID, d.request_count, dma->buf_count ); 1732112015Sanholt return DRM_ERR(EINVAL); 173395584Sanholt } 173495584Sanholt 173595584Sanholt d.granted_count = 0; 173695584Sanholt 173795584Sanholt if ( d.request_count ) { 1738113995Sanholt ret = radeon_cp_get_buffers( filp, dev, &d ); 173995584Sanholt } 174095584Sanholt 1741112015Sanholt DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); 174295584Sanholt 174395584Sanholt return ret; 174495584Sanholt} 1745