radeon_cp.c revision 112015
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 112015 2003-03-09 02:08: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 41112015Sanholt#if defined(__alpha__) || defined(__powerpc__) 4295584Sanholt# define PCIGART_ENABLED 4395584Sanholt#else 4495584Sanholt# undef PCIGART_ENABLED 4595584Sanholt#endif 4695584Sanholt 4795584Sanholt 4895584Sanholt/* CP microcode (from ATI) */ 49112015Sanholtstatic u32 R200_cp_microcode[][2] = { 50112015Sanholt { 0x21007000, 0000000000 }, 51112015Sanholt { 0x20007000, 0000000000 }, 52112015Sanholt { 0x000000ab, 0x00000004 }, 53112015Sanholt { 0x000000af, 0x00000004 }, 54112015Sanholt { 0x66544a49, 0000000000 }, 55112015Sanholt { 0x49494174, 0000000000 }, 56112015Sanholt { 0x54517d83, 0000000000 }, 57112015Sanholt { 0x498d8b64, 0000000000 }, 58112015Sanholt { 0x49494949, 0000000000 }, 59112015Sanholt { 0x49da493c, 0000000000 }, 60112015Sanholt { 0x49989898, 0000000000 }, 61112015Sanholt { 0xd34949d5, 0000000000 }, 62112015Sanholt { 0x9dc90e11, 0000000000 }, 63112015Sanholt { 0xce9b9b9b, 0000000000 }, 64112015Sanholt { 0x000f0000, 0x00000016 }, 65112015Sanholt { 0x352e232c, 0000000000 }, 66112015Sanholt { 0x00000013, 0x00000004 }, 67112015Sanholt { 0x000f0000, 0x00000016 }, 68112015Sanholt { 0x352e272c, 0000000000 }, 69112015Sanholt { 0x000f0001, 0x00000016 }, 70112015Sanholt { 0x3239362f, 0000000000 }, 71112015Sanholt { 0x000077ef, 0x00000002 }, 72112015Sanholt { 0x00061000, 0x00000002 }, 73112015Sanholt { 0x00000020, 0x0000001a }, 74112015Sanholt { 0x00004000, 0x0000001e }, 75112015Sanholt { 0x00061000, 0x00000002 }, 76112015Sanholt { 0x00000020, 0x0000001a }, 77112015Sanholt { 0x00004000, 0x0000001e }, 78112015Sanholt { 0x00061000, 0x00000002 }, 79112015Sanholt { 0x00000020, 0x0000001a }, 80112015Sanholt { 0x00004000, 0x0000001e }, 81112015Sanholt { 0x00000016, 0x00000004 }, 82112015Sanholt { 0x0003802a, 0x00000002 }, 83112015Sanholt { 0x040067e0, 0x00000002 }, 84112015Sanholt { 0x00000016, 0x00000004 }, 85112015Sanholt { 0x000077e0, 0x00000002 }, 86112015Sanholt { 0x00065000, 0x00000002 }, 87112015Sanholt { 0x000037e1, 0x00000002 }, 88112015Sanholt { 0x040067e1, 0x00000006 }, 89112015Sanholt { 0x000077e0, 0x00000002 }, 90112015Sanholt { 0x000077e1, 0x00000002 }, 91112015Sanholt { 0x000077e1, 0x00000006 }, 92112015Sanholt { 0xffffffff, 0000000000 }, 93112015Sanholt { 0x10000000, 0000000000 }, 94112015Sanholt { 0x0003802a, 0x00000002 }, 95112015Sanholt { 0x040067e0, 0x00000006 }, 96112015Sanholt { 0x00007675, 0x00000002 }, 97112015Sanholt { 0x00007676, 0x00000002 }, 98112015Sanholt { 0x00007677, 0x00000002 }, 99112015Sanholt { 0x00007678, 0x00000006 }, 100112015Sanholt { 0x0003802b, 0x00000002 }, 101112015Sanholt { 0x04002676, 0x00000002 }, 102112015Sanholt { 0x00007677, 0x00000002 }, 103112015Sanholt { 0x00007678, 0x00000006 }, 104112015Sanholt { 0x0000002e, 0x00000018 }, 105112015Sanholt { 0x0000002e, 0x00000018 }, 106112015Sanholt { 0000000000, 0x00000006 }, 107112015Sanholt { 0x0000002f, 0x00000018 }, 108112015Sanholt { 0x0000002f, 0x00000018 }, 109112015Sanholt { 0000000000, 0x00000006 }, 110112015Sanholt { 0x01605000, 0x00000002 }, 111112015Sanholt { 0x00065000, 0x00000002 }, 112112015Sanholt { 0x00098000, 0x00000002 }, 113112015Sanholt { 0x00061000, 0x00000002 }, 114112015Sanholt { 0x64c0603d, 0x00000004 }, 115112015Sanholt { 0x00080000, 0x00000016 }, 116112015Sanholt { 0000000000, 0000000000 }, 117112015Sanholt { 0x0400251d, 0x00000002 }, 118112015Sanholt { 0x00007580, 0x00000002 }, 119112015Sanholt { 0x00067581, 0x00000002 }, 120112015Sanholt { 0x04002580, 0x00000002 }, 121112015Sanholt { 0x00067581, 0x00000002 }, 122112015Sanholt { 0x00000046, 0x00000004 }, 123112015Sanholt { 0x00005000, 0000000000 }, 124112015Sanholt { 0x00061000, 0x00000002 }, 125112015Sanholt { 0x0000750e, 0x00000002 }, 126112015Sanholt { 0x00019000, 0x00000002 }, 127112015Sanholt { 0x00011055, 0x00000014 }, 128112015Sanholt { 0x00000055, 0x00000012 }, 129112015Sanholt { 0x0400250f, 0x00000002 }, 130112015Sanholt { 0x0000504a, 0x00000004 }, 131112015Sanholt { 0x00007565, 0x00000002 }, 132112015Sanholt { 0x00007566, 0x00000002 }, 133112015Sanholt { 0x00000051, 0x00000004 }, 134112015Sanholt { 0x01e655b4, 0x00000002 }, 135112015Sanholt { 0x4401b0dc, 0x00000002 }, 136112015Sanholt { 0x01c110dc, 0x00000002 }, 137112015Sanholt { 0x2666705d, 0x00000018 }, 138112015Sanholt { 0x040c2565, 0x00000002 }, 139112015Sanholt { 0x0000005d, 0x00000018 }, 140112015Sanholt { 0x04002564, 0x00000002 }, 141112015Sanholt { 0x00007566, 0x00000002 }, 142112015Sanholt { 0x00000054, 0x00000004 }, 143112015Sanholt { 0x00401060, 0x00000008 }, 144112015Sanholt { 0x00101000, 0x00000002 }, 145112015Sanholt { 0x000d80ff, 0x00000002 }, 146112015Sanholt { 0x00800063, 0x00000008 }, 147112015Sanholt { 0x000f9000, 0x00000002 }, 148112015Sanholt { 0x000e00ff, 0x00000002 }, 149112015Sanholt { 0000000000, 0x00000006 }, 150112015Sanholt { 0x00000080, 0x00000018 }, 151112015Sanholt { 0x00000054, 0x00000004 }, 152112015Sanholt { 0x00007576, 0x00000002 }, 153112015Sanholt { 0x00065000, 0x00000002 }, 154112015Sanholt { 0x00009000, 0x00000002 }, 155112015Sanholt { 0x00041000, 0x00000002 }, 156112015Sanholt { 0x0c00350e, 0x00000002 }, 157112015Sanholt { 0x00049000, 0x00000002 }, 158112015Sanholt { 0x00051000, 0x00000002 }, 159112015Sanholt { 0x01e785f8, 0x00000002 }, 160112015Sanholt { 0x00200000, 0x00000002 }, 161112015Sanholt { 0x00600073, 0x0000000c }, 162112015Sanholt { 0x00007563, 0x00000002 }, 163112015Sanholt { 0x006075f0, 0x00000021 }, 164112015Sanholt { 0x20007068, 0x00000004 }, 165112015Sanholt { 0x00005068, 0x00000004 }, 166112015Sanholt { 0x00007576, 0x00000002 }, 167112015Sanholt { 0x00007577, 0x00000002 }, 168112015Sanholt { 0x0000750e, 0x00000002 }, 169112015Sanholt { 0x0000750f, 0x00000002 }, 170112015Sanholt { 0x00a05000, 0x00000002 }, 171112015Sanholt { 0x00600076, 0x0000000c }, 172112015Sanholt { 0x006075f0, 0x00000021 }, 173112015Sanholt { 0x000075f8, 0x00000002 }, 174112015Sanholt { 0x00000076, 0x00000004 }, 175112015Sanholt { 0x000a750e, 0x00000002 }, 176112015Sanholt { 0x0020750f, 0x00000002 }, 177112015Sanholt { 0x00600079, 0x00000004 }, 178112015Sanholt { 0x00007570, 0x00000002 }, 179112015Sanholt { 0x00007571, 0x00000002 }, 180112015Sanholt { 0x00007572, 0x00000006 }, 181112015Sanholt { 0x00005000, 0x00000002 }, 182112015Sanholt { 0x00a05000, 0x00000002 }, 183112015Sanholt { 0x00007568, 0x00000002 }, 184112015Sanholt { 0x00061000, 0x00000002 }, 185112015Sanholt { 0x00000084, 0x0000000c }, 186112015Sanholt { 0x00058000, 0x00000002 }, 187112015Sanholt { 0x0c607562, 0x00000002 }, 188112015Sanholt { 0x00000086, 0x00000004 }, 189112015Sanholt { 0x00600085, 0x00000004 }, 190112015Sanholt { 0x400070dd, 0000000000 }, 191112015Sanholt { 0x000380dd, 0x00000002 }, 192112015Sanholt { 0x00000093, 0x0000001c }, 193112015Sanholt { 0x00065095, 0x00000018 }, 194112015Sanholt { 0x040025bb, 0x00000002 }, 195112015Sanholt { 0x00061096, 0x00000018 }, 196112015Sanholt { 0x040075bc, 0000000000 }, 197112015Sanholt { 0x000075bb, 0x00000002 }, 198112015Sanholt { 0x000075bc, 0000000000 }, 199112015Sanholt { 0x00090000, 0x00000006 }, 200112015Sanholt { 0x00090000, 0x00000002 }, 201112015Sanholt { 0x000d8002, 0x00000006 }, 202112015Sanholt { 0x00005000, 0x00000002 }, 203112015Sanholt { 0x00007821, 0x00000002 }, 204112015Sanholt { 0x00007800, 0000000000 }, 205112015Sanholt { 0x00007821, 0x00000002 }, 206112015Sanholt { 0x00007800, 0000000000 }, 207112015Sanholt { 0x01665000, 0x00000002 }, 208112015Sanholt { 0x000a0000, 0x00000002 }, 209112015Sanholt { 0x000671cc, 0x00000002 }, 210112015Sanholt { 0x0286f1cd, 0x00000002 }, 211112015Sanholt { 0x000000a3, 0x00000010 }, 212112015Sanholt { 0x21007000, 0000000000 }, 213112015Sanholt { 0x000000aa, 0x0000001c }, 214112015Sanholt { 0x00065000, 0x00000002 }, 215112015Sanholt { 0x000a0000, 0x00000002 }, 216112015Sanholt { 0x00061000, 0x00000002 }, 217112015Sanholt { 0x000b0000, 0x00000002 }, 218112015Sanholt { 0x38067000, 0x00000002 }, 219112015Sanholt { 0x000a00a6, 0x00000004 }, 220112015Sanholt { 0x20007000, 0000000000 }, 221112015Sanholt { 0x01200000, 0x00000002 }, 222112015Sanholt { 0x20077000, 0x00000002 }, 223112015Sanholt { 0x01200000, 0x00000002 }, 224112015Sanholt { 0x20007000, 0000000000 }, 225112015Sanholt { 0x00061000, 0x00000002 }, 226112015Sanholt { 0x0120751b, 0x00000002 }, 227112015Sanholt { 0x8040750a, 0x00000002 }, 228112015Sanholt { 0x8040750b, 0x00000002 }, 229112015Sanholt { 0x00110000, 0x00000002 }, 230112015Sanholt { 0x000380dd, 0x00000002 }, 231112015Sanholt { 0x000000bd, 0x0000001c }, 232112015Sanholt { 0x00061096, 0x00000018 }, 233112015Sanholt { 0x844075bd, 0x00000002 }, 234112015Sanholt { 0x00061095, 0x00000018 }, 235112015Sanholt { 0x840075bb, 0x00000002 }, 236112015Sanholt { 0x00061096, 0x00000018 }, 237112015Sanholt { 0x844075bc, 0x00000002 }, 238112015Sanholt { 0x000000c0, 0x00000004 }, 239112015Sanholt { 0x804075bd, 0x00000002 }, 240112015Sanholt { 0x800075bb, 0x00000002 }, 241112015Sanholt { 0x804075bc, 0x00000002 }, 242112015Sanholt { 0x00108000, 0x00000002 }, 243112015Sanholt { 0x01400000, 0x00000002 }, 244112015Sanholt { 0x006000c4, 0x0000000c }, 245112015Sanholt { 0x20c07000, 0x00000020 }, 246112015Sanholt { 0x000000c6, 0x00000012 }, 247112015Sanholt { 0x00800000, 0x00000006 }, 248112015Sanholt { 0x0080751d, 0x00000006 }, 249112015Sanholt { 0x000025bb, 0x00000002 }, 250112015Sanholt { 0x000040c0, 0x00000004 }, 251112015Sanholt { 0x0000775c, 0x00000002 }, 252112015Sanholt { 0x00a05000, 0x00000002 }, 253112015Sanholt { 0x00661000, 0x00000002 }, 254112015Sanholt { 0x0460275d, 0x00000020 }, 255112015Sanholt { 0x00004000, 0000000000 }, 256112015Sanholt { 0x00007999, 0x00000002 }, 257112015Sanholt { 0x00a05000, 0x00000002 }, 258112015Sanholt { 0x00661000, 0x00000002 }, 259112015Sanholt { 0x0460299b, 0x00000020 }, 260112015Sanholt { 0x00004000, 0000000000 }, 261112015Sanholt { 0x01e00830, 0x00000002 }, 262112015Sanholt { 0x21007000, 0000000000 }, 263112015Sanholt { 0x00005000, 0x00000002 }, 264112015Sanholt { 0x00038042, 0x00000002 }, 265112015Sanholt { 0x040025e0, 0x00000002 }, 266112015Sanholt { 0x000075e1, 0000000000 }, 267112015Sanholt { 0x00000001, 0000000000 }, 268112015Sanholt { 0x000380d9, 0x00000002 }, 269112015Sanholt { 0x04007394, 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 { 0000000000, 0000000000 }, 301112015Sanholt { 0000000000, 0000000000 }, 302112015Sanholt { 0000000000, 0000000000 }, 303112015Sanholt { 0000000000, 0000000000 }, 304112015Sanholt { 0000000000, 0000000000 }, 305112015Sanholt { 0000000000, 0000000000 }, 306112015Sanholt}; 307112015Sanholt 308112015Sanholt 30995584Sanholtstatic u32 radeon_cp_microcode[][2] = { 31095584Sanholt { 0x21007000, 0000000000 }, 31195584Sanholt { 0x20007000, 0000000000 }, 31295584Sanholt { 0x000000b4, 0x00000004 }, 31395584Sanholt { 0x000000b8, 0x00000004 }, 31495584Sanholt { 0x6f5b4d4c, 0000000000 }, 31595584Sanholt { 0x4c4c427f, 0000000000 }, 31695584Sanholt { 0x5b568a92, 0000000000 }, 31795584Sanholt { 0x4ca09c6d, 0000000000 }, 31895584Sanholt { 0xad4c4c4c, 0000000000 }, 31995584Sanholt { 0x4ce1af3d, 0000000000 }, 32095584Sanholt { 0xd8afafaf, 0000000000 }, 32195584Sanholt { 0xd64c4cdc, 0000000000 }, 32295584Sanholt { 0x4cd10d10, 0000000000 }, 32395584Sanholt { 0x000f0000, 0x00000016 }, 32495584Sanholt { 0x362f242d, 0000000000 }, 32595584Sanholt { 0x00000012, 0x00000004 }, 32695584Sanholt { 0x000f0000, 0x00000016 }, 32795584Sanholt { 0x362f282d, 0000000000 }, 32895584Sanholt { 0x000380e7, 0x00000002 }, 32995584Sanholt { 0x04002c97, 0x00000002 }, 33095584Sanholt { 0x000f0001, 0x00000016 }, 33195584Sanholt { 0x333a3730, 0000000000 }, 33295584Sanholt { 0x000077ef, 0x00000002 }, 33395584Sanholt { 0x00061000, 0x00000002 }, 33495584Sanholt { 0x00000021, 0x0000001a }, 33595584Sanholt { 0x00004000, 0x0000001e }, 33695584Sanholt { 0x00061000, 0x00000002 }, 33795584Sanholt { 0x00000021, 0x0000001a }, 33895584Sanholt { 0x00004000, 0x0000001e }, 33995584Sanholt { 0x00061000, 0x00000002 }, 34095584Sanholt { 0x00000021, 0x0000001a }, 34195584Sanholt { 0x00004000, 0x0000001e }, 34295584Sanholt { 0x00000017, 0x00000004 }, 34395584Sanholt { 0x0003802b, 0x00000002 }, 34495584Sanholt { 0x040067e0, 0x00000002 }, 34595584Sanholt { 0x00000017, 0x00000004 }, 34695584Sanholt { 0x000077e0, 0x00000002 }, 34795584Sanholt { 0x00065000, 0x00000002 }, 34895584Sanholt { 0x000037e1, 0x00000002 }, 34995584Sanholt { 0x040067e1, 0x00000006 }, 35095584Sanholt { 0x000077e0, 0x00000002 }, 35195584Sanholt { 0x000077e1, 0x00000002 }, 35295584Sanholt { 0x000077e1, 0x00000006 }, 35395584Sanholt { 0xffffffff, 0000000000 }, 35495584Sanholt { 0x10000000, 0000000000 }, 35595584Sanholt { 0x0003802b, 0x00000002 }, 35695584Sanholt { 0x040067e0, 0x00000006 }, 35795584Sanholt { 0x00007675, 0x00000002 }, 35895584Sanholt { 0x00007676, 0x00000002 }, 35995584Sanholt { 0x00007677, 0x00000002 }, 36095584Sanholt { 0x00007678, 0x00000006 }, 36195584Sanholt { 0x0003802c, 0x00000002 }, 36295584Sanholt { 0x04002676, 0x00000002 }, 36395584Sanholt { 0x00007677, 0x00000002 }, 36495584Sanholt { 0x00007678, 0x00000006 }, 36595584Sanholt { 0x0000002f, 0x00000018 }, 36695584Sanholt { 0x0000002f, 0x00000018 }, 36795584Sanholt { 0000000000, 0x00000006 }, 36895584Sanholt { 0x00000030, 0x00000018 }, 36995584Sanholt { 0x00000030, 0x00000018 }, 37095584Sanholt { 0000000000, 0x00000006 }, 37195584Sanholt { 0x01605000, 0x00000002 }, 37295584Sanholt { 0x00065000, 0x00000002 }, 37395584Sanholt { 0x00098000, 0x00000002 }, 37495584Sanholt { 0x00061000, 0x00000002 }, 37595584Sanholt { 0x64c0603e, 0x00000004 }, 37695584Sanholt { 0x000380e6, 0x00000002 }, 37795584Sanholt { 0x040025c5, 0x00000002 }, 37895584Sanholt { 0x00080000, 0x00000016 }, 37995584Sanholt { 0000000000, 0000000000 }, 38095584Sanholt { 0x0400251d, 0x00000002 }, 38195584Sanholt { 0x00007580, 0x00000002 }, 38295584Sanholt { 0x00067581, 0x00000002 }, 38395584Sanholt { 0x04002580, 0x00000002 }, 38495584Sanholt { 0x00067581, 0x00000002 }, 38595584Sanholt { 0x00000049, 0x00000004 }, 38695584Sanholt { 0x00005000, 0000000000 }, 38795584Sanholt { 0x000380e6, 0x00000002 }, 38895584Sanholt { 0x040025c5, 0x00000002 }, 38995584Sanholt { 0x00061000, 0x00000002 }, 39095584Sanholt { 0x0000750e, 0x00000002 }, 39195584Sanholt { 0x00019000, 0x00000002 }, 39295584Sanholt { 0x00011055, 0x00000014 }, 39395584Sanholt { 0x00000055, 0x00000012 }, 39495584Sanholt { 0x0400250f, 0x00000002 }, 39595584Sanholt { 0x0000504f, 0x00000004 }, 39695584Sanholt { 0x000380e6, 0x00000002 }, 39795584Sanholt { 0x040025c5, 0x00000002 }, 39895584Sanholt { 0x00007565, 0x00000002 }, 39995584Sanholt { 0x00007566, 0x00000002 }, 40095584Sanholt { 0x00000058, 0x00000004 }, 40195584Sanholt { 0x000380e6, 0x00000002 }, 40295584Sanholt { 0x040025c5, 0x00000002 }, 40395584Sanholt { 0x01e655b4, 0x00000002 }, 40495584Sanholt { 0x4401b0e4, 0x00000002 }, 40595584Sanholt { 0x01c110e4, 0x00000002 }, 40695584Sanholt { 0x26667066, 0x00000018 }, 40795584Sanholt { 0x040c2565, 0x00000002 }, 40895584Sanholt { 0x00000066, 0x00000018 }, 40995584Sanholt { 0x04002564, 0x00000002 }, 41095584Sanholt { 0x00007566, 0x00000002 }, 41195584Sanholt { 0x0000005d, 0x00000004 }, 41295584Sanholt { 0x00401069, 0x00000008 }, 41395584Sanholt { 0x00101000, 0x00000002 }, 41495584Sanholt { 0x000d80ff, 0x00000002 }, 41595584Sanholt { 0x0080006c, 0x00000008 }, 41695584Sanholt { 0x000f9000, 0x00000002 }, 41795584Sanholt { 0x000e00ff, 0x00000002 }, 41895584Sanholt { 0000000000, 0x00000006 }, 41995584Sanholt { 0x0000008f, 0x00000018 }, 42095584Sanholt { 0x0000005b, 0x00000004 }, 42195584Sanholt { 0x000380e6, 0x00000002 }, 42295584Sanholt { 0x040025c5, 0x00000002 }, 42395584Sanholt { 0x00007576, 0x00000002 }, 42495584Sanholt { 0x00065000, 0x00000002 }, 42595584Sanholt { 0x00009000, 0x00000002 }, 42695584Sanholt { 0x00041000, 0x00000002 }, 42795584Sanholt { 0x0c00350e, 0x00000002 }, 42895584Sanholt { 0x00049000, 0x00000002 }, 42995584Sanholt { 0x00051000, 0x00000002 }, 43095584Sanholt { 0x01e785f8, 0x00000002 }, 43195584Sanholt { 0x00200000, 0x00000002 }, 43295584Sanholt { 0x0060007e, 0x0000000c }, 43395584Sanholt { 0x00007563, 0x00000002 }, 43495584Sanholt { 0x006075f0, 0x00000021 }, 43595584Sanholt { 0x20007073, 0x00000004 }, 43695584Sanholt { 0x00005073, 0x00000004 }, 43795584Sanholt { 0x000380e6, 0x00000002 }, 43895584Sanholt { 0x040025c5, 0x00000002 }, 43995584Sanholt { 0x00007576, 0x00000002 }, 44095584Sanholt { 0x00007577, 0x00000002 }, 44195584Sanholt { 0x0000750e, 0x00000002 }, 44295584Sanholt { 0x0000750f, 0x00000002 }, 44395584Sanholt { 0x00a05000, 0x00000002 }, 44495584Sanholt { 0x00600083, 0x0000000c }, 44595584Sanholt { 0x006075f0, 0x00000021 }, 44695584Sanholt { 0x000075f8, 0x00000002 }, 44795584Sanholt { 0x00000083, 0x00000004 }, 44895584Sanholt { 0x000a750e, 0x00000002 }, 44995584Sanholt { 0x000380e6, 0x00000002 }, 45095584Sanholt { 0x040025c5, 0x00000002 }, 45195584Sanholt { 0x0020750f, 0x00000002 }, 45295584Sanholt { 0x00600086, 0x00000004 }, 45395584Sanholt { 0x00007570, 0x00000002 }, 45495584Sanholt { 0x00007571, 0x00000002 }, 45595584Sanholt { 0x00007572, 0x00000006 }, 45695584Sanholt { 0x000380e6, 0x00000002 }, 45795584Sanholt { 0x040025c5, 0x00000002 }, 45895584Sanholt { 0x00005000, 0x00000002 }, 45995584Sanholt { 0x00a05000, 0x00000002 }, 46095584Sanholt { 0x00007568, 0x00000002 }, 46195584Sanholt { 0x00061000, 0x00000002 }, 46295584Sanholt { 0x00000095, 0x0000000c }, 46395584Sanholt { 0x00058000, 0x00000002 }, 46495584Sanholt { 0x0c607562, 0x00000002 }, 46595584Sanholt { 0x00000097, 0x00000004 }, 46695584Sanholt { 0x000380e6, 0x00000002 }, 46795584Sanholt { 0x040025c5, 0x00000002 }, 46895584Sanholt { 0x00600096, 0x00000004 }, 46995584Sanholt { 0x400070e5, 0000000000 }, 47095584Sanholt { 0x000380e6, 0x00000002 }, 47195584Sanholt { 0x040025c5, 0x00000002 }, 47295584Sanholt { 0x000380e5, 0x00000002 }, 47395584Sanholt { 0x000000a8, 0x0000001c }, 47495584Sanholt { 0x000650aa, 0x00000018 }, 47595584Sanholt { 0x040025bb, 0x00000002 }, 47695584Sanholt { 0x000610ab, 0x00000018 }, 47795584Sanholt { 0x040075bc, 0000000000 }, 47895584Sanholt { 0x000075bb, 0x00000002 }, 47995584Sanholt { 0x000075bc, 0000000000 }, 48095584Sanholt { 0x00090000, 0x00000006 }, 48195584Sanholt { 0x00090000, 0x00000002 }, 48295584Sanholt { 0x000d8002, 0x00000006 }, 48395584Sanholt { 0x00007832, 0x00000002 }, 48495584Sanholt { 0x00005000, 0x00000002 }, 48595584Sanholt { 0x000380e7, 0x00000002 }, 48695584Sanholt { 0x04002c97, 0x00000002 }, 48795584Sanholt { 0x00007820, 0x00000002 }, 48895584Sanholt { 0x00007821, 0x00000002 }, 48995584Sanholt { 0x00007800, 0000000000 }, 49095584Sanholt { 0x01200000, 0x00000002 }, 49195584Sanholt { 0x20077000, 0x00000002 }, 49295584Sanholt { 0x01200000, 0x00000002 }, 49395584Sanholt { 0x20007000, 0x00000002 }, 49495584Sanholt { 0x00061000, 0x00000002 }, 49595584Sanholt { 0x0120751b, 0x00000002 }, 49695584Sanholt { 0x8040750a, 0x00000002 }, 49795584Sanholt { 0x8040750b, 0x00000002 }, 49895584Sanholt { 0x00110000, 0x00000002 }, 49995584Sanholt { 0x000380e5, 0x00000002 }, 50095584Sanholt { 0x000000c6, 0x0000001c }, 50195584Sanholt { 0x000610ab, 0x00000018 }, 50295584Sanholt { 0x844075bd, 0x00000002 }, 50395584Sanholt { 0x000610aa, 0x00000018 }, 50495584Sanholt { 0x840075bb, 0x00000002 }, 50595584Sanholt { 0x000610ab, 0x00000018 }, 50695584Sanholt { 0x844075bc, 0x00000002 }, 50795584Sanholt { 0x000000c9, 0x00000004 }, 50895584Sanholt { 0x804075bd, 0x00000002 }, 50995584Sanholt { 0x800075bb, 0x00000002 }, 51095584Sanholt { 0x804075bc, 0x00000002 }, 51195584Sanholt { 0x00108000, 0x00000002 }, 51295584Sanholt { 0x01400000, 0x00000002 }, 51395584Sanholt { 0x006000cd, 0x0000000c }, 51495584Sanholt { 0x20c07000, 0x00000020 }, 51595584Sanholt { 0x000000cf, 0x00000012 }, 51695584Sanholt { 0x00800000, 0x00000006 }, 51795584Sanholt { 0x0080751d, 0x00000006 }, 51895584Sanholt { 0000000000, 0000000000 }, 51995584Sanholt { 0x0000775c, 0x00000002 }, 52095584Sanholt { 0x00a05000, 0x00000002 }, 52195584Sanholt { 0x00661000, 0x00000002 }, 52295584Sanholt { 0x0460275d, 0x00000020 }, 52395584Sanholt { 0x00004000, 0000000000 }, 52495584Sanholt { 0x01e00830, 0x00000002 }, 52595584Sanholt { 0x21007000, 0000000000 }, 52695584Sanholt { 0x6464614d, 0000000000 }, 52795584Sanholt { 0x69687420, 0000000000 }, 52895584Sanholt { 0x00000073, 0000000000 }, 52995584Sanholt { 0000000000, 0000000000 }, 53095584Sanholt { 0x00005000, 0x00000002 }, 53195584Sanholt { 0x000380d0, 0x00000002 }, 53295584Sanholt { 0x040025e0, 0x00000002 }, 53395584Sanholt { 0x000075e1, 0000000000 }, 53495584Sanholt { 0x00000001, 0000000000 }, 53595584Sanholt { 0x000380e0, 0x00000002 }, 53695584Sanholt { 0x04002394, 0x00000002 }, 53795584Sanholt { 0x00005000, 0000000000 }, 53895584Sanholt { 0000000000, 0000000000 }, 53995584Sanholt { 0000000000, 0000000000 }, 54095584Sanholt { 0x00000008, 0000000000 }, 54195584Sanholt { 0x00000004, 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 { 0000000000, 0000000000 }, 56195584Sanholt { 0000000000, 0000000000 }, 56295584Sanholt { 0000000000, 0000000000 }, 56395584Sanholt { 0000000000, 0000000000 }, 56495584Sanholt { 0000000000, 0000000000 }, 56595584Sanholt { 0000000000, 0000000000 }, 56695584Sanholt}; 56795584Sanholt 56895584Sanholt 56995584Sanholtint RADEON_READ_PLL(drm_device_t *dev, int addr) 57095584Sanholt{ 57195584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 57295584Sanholt 57395584Sanholt RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f); 57495584Sanholt return RADEON_READ(RADEON_CLOCK_CNTL_DATA); 57595584Sanholt} 57695584Sanholt 57795584Sanholt#if RADEON_FIFO_DEBUG 57895584Sanholtstatic void radeon_status( drm_radeon_private_t *dev_priv ) 57995584Sanholt{ 580112015Sanholt printk( "%s:\n", __FUNCTION__ ); 58195584Sanholt printk( "RBBM_STATUS = 0x%08x\n", 58295584Sanholt (unsigned int)RADEON_READ( RADEON_RBBM_STATUS ) ); 58395584Sanholt printk( "CP_RB_RTPR = 0x%08x\n", 58495584Sanholt (unsigned int)RADEON_READ( RADEON_CP_RB_RPTR ) ); 58595584Sanholt printk( "CP_RB_WTPR = 0x%08x\n", 58695584Sanholt (unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) ); 58795584Sanholt printk( "AIC_CNTL = 0x%08x\n", 58895584Sanholt (unsigned int)RADEON_READ( RADEON_AIC_CNTL ) ); 58995584Sanholt printk( "AIC_STAT = 0x%08x\n", 59095584Sanholt (unsigned int)RADEON_READ( RADEON_AIC_STAT ) ); 59195584Sanholt printk( "AIC_PT_BASE = 0x%08x\n", 59295584Sanholt (unsigned int)RADEON_READ( RADEON_AIC_PT_BASE ) ); 59395584Sanholt printk( "TLB_ADDR = 0x%08x\n", 59495584Sanholt (unsigned int)RADEON_READ( RADEON_AIC_TLB_ADDR ) ); 59595584Sanholt printk( "TLB_DATA = 0x%08x\n", 59695584Sanholt (unsigned int)RADEON_READ( RADEON_AIC_TLB_DATA ) ); 59795584Sanholt} 59895584Sanholt#endif 59995584Sanholt 60095584Sanholt 60195584Sanholt/* ================================================================ 60295584Sanholt * Engine, FIFO control 60395584Sanholt */ 60495584Sanholt 60595584Sanholtstatic int radeon_do_pixcache_flush( drm_radeon_private_t *dev_priv ) 60695584Sanholt{ 60795584Sanholt u32 tmp; 60895584Sanholt int i; 60995584Sanholt 610112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 611112015Sanholt 61295584Sanholt tmp = RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT ); 61395584Sanholt tmp |= RADEON_RB2D_DC_FLUSH_ALL; 61495584Sanholt RADEON_WRITE( RADEON_RB2D_DSTCACHE_CTLSTAT, tmp ); 61595584Sanholt 61695584Sanholt for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 61795584Sanholt if ( !(RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT ) 61895584Sanholt & RADEON_RB2D_DC_BUSY) ) { 61995584Sanholt return 0; 62095584Sanholt } 621112015Sanholt DRM_UDELAY( 1 ); 62295584Sanholt } 62395584Sanholt 62495584Sanholt#if RADEON_FIFO_DEBUG 62595584Sanholt DRM_ERROR( "failed!\n" ); 62695584Sanholt radeon_status( dev_priv ); 62795584Sanholt#endif 628112015Sanholt return DRM_ERR(EBUSY); 62995584Sanholt} 63095584Sanholt 63195584Sanholtstatic int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv, 63295584Sanholt int entries ) 63395584Sanholt{ 63495584Sanholt int i; 63595584Sanholt 636112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 637112015Sanholt 63895584Sanholt for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 63995584Sanholt int slots = ( RADEON_READ( RADEON_RBBM_STATUS ) 64095584Sanholt & RADEON_RBBM_FIFOCNT_MASK ); 64195584Sanholt if ( slots >= entries ) return 0; 642112015Sanholt DRM_UDELAY( 1 ); 64395584Sanholt } 64495584Sanholt 64595584Sanholt#if RADEON_FIFO_DEBUG 64695584Sanholt DRM_ERROR( "failed!\n" ); 64795584Sanholt radeon_status( dev_priv ); 64895584Sanholt#endif 649112015Sanholt return DRM_ERR(EBUSY); 65095584Sanholt} 65195584Sanholt 65295584Sanholtstatic int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv ) 65395584Sanholt{ 65495584Sanholt int i, ret; 65595584Sanholt 656112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 657112015Sanholt 65895584Sanholt ret = radeon_do_wait_for_fifo( dev_priv, 64 ); 65995584Sanholt if ( ret ) return ret; 660112015Sanholt 66195584Sanholt for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 66295584Sanholt if ( !(RADEON_READ( RADEON_RBBM_STATUS ) 66395584Sanholt & RADEON_RBBM_ACTIVE) ) { 66495584Sanholt radeon_do_pixcache_flush( dev_priv ); 66595584Sanholt return 0; 66695584Sanholt } 667112015Sanholt DRM_UDELAY( 1 ); 66895584Sanholt } 66995584Sanholt 67095584Sanholt#if RADEON_FIFO_DEBUG 67195584Sanholt DRM_ERROR( "failed!\n" ); 67295584Sanholt radeon_status( dev_priv ); 67395584Sanholt#endif 674112015Sanholt return DRM_ERR(EBUSY); 67595584Sanholt} 67695584Sanholt 67795584Sanholt 67895584Sanholt/* ================================================================ 67995584Sanholt * CP control, initialization 68095584Sanholt */ 68195584Sanholt 68295584Sanholt/* Load the microcode for the CP */ 68395584Sanholtstatic void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv ) 68495584Sanholt{ 68595584Sanholt int i; 686112015Sanholt DRM_DEBUG( "\n" ); 68795584Sanholt 68895584Sanholt radeon_do_wait_for_idle( dev_priv ); 68995584Sanholt 69095584Sanholt RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 ); 691112015Sanholt 692112015Sanholt if (dev_priv->is_r200) 693112015Sanholt { 694112015Sanholt DRM_INFO("Loading R200 Microcode\n"); 695112015Sanholt for ( i = 0 ; i < 256 ; i++ ) 696112015Sanholt { 697112015Sanholt RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, 698112015Sanholt R200_cp_microcode[i][1] ); 699112015Sanholt RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, 700112015Sanholt R200_cp_microcode[i][0] ); 701112015Sanholt } 70295584Sanholt } 703112015Sanholt else 704112015Sanholt { 705112015Sanholt for ( i = 0 ; i < 256 ; i++ ) { 706112015Sanholt RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, 707112015Sanholt radeon_cp_microcode[i][1] ); 708112015Sanholt RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, 709112015Sanholt radeon_cp_microcode[i][0] ); 710112015Sanholt } 711112015Sanholt } 71295584Sanholt} 71395584Sanholt 71495584Sanholt/* Flush any pending commands to the CP. This should only be used just 71595584Sanholt * prior to a wait for idle, as it informs the engine that the command 71695584Sanholt * stream is ending. 71795584Sanholt */ 71895584Sanholtstatic void radeon_do_cp_flush( drm_radeon_private_t *dev_priv ) 71995584Sanholt{ 720112015Sanholt DRM_DEBUG( "\n" ); 72195584Sanholt#if 0 72295584Sanholt u32 tmp; 72395584Sanholt 72495584Sanholt tmp = RADEON_READ( RADEON_CP_RB_WPTR ) | (1 << 31); 72595584Sanholt RADEON_WRITE( RADEON_CP_RB_WPTR, tmp ); 72695584Sanholt#endif 72795584Sanholt} 72895584Sanholt 72995584Sanholt/* Wait for the CP to go idle. 73095584Sanholt */ 73195584Sanholtint radeon_do_cp_idle( drm_radeon_private_t *dev_priv ) 73295584Sanholt{ 73395584Sanholt RING_LOCALS; 734112015Sanholt DRM_DEBUG( "\n" ); 73595584Sanholt 73695584Sanholt BEGIN_RING( 6 ); 73795584Sanholt 73895584Sanholt RADEON_PURGE_CACHE(); 73995584Sanholt RADEON_PURGE_ZCACHE(); 74095584Sanholt RADEON_WAIT_UNTIL_IDLE(); 74195584Sanholt 74295584Sanholt ADVANCE_RING(); 743112015Sanholt COMMIT_RING(); 74495584Sanholt 74595584Sanholt return radeon_do_wait_for_idle( dev_priv ); 74695584Sanholt} 74795584Sanholt 74895584Sanholt/* Start the Command Processor. 74995584Sanholt */ 75095584Sanholtstatic void radeon_do_cp_start( drm_radeon_private_t *dev_priv ) 75195584Sanholt{ 75295584Sanholt RING_LOCALS; 753112015Sanholt DRM_DEBUG( "\n" ); 75495584Sanholt 75595584Sanholt radeon_do_wait_for_idle( dev_priv ); 75695584Sanholt 75795584Sanholt RADEON_WRITE( RADEON_CP_CSQ_CNTL, dev_priv->cp_mode ); 75895584Sanholt 75995584Sanholt dev_priv->cp_running = 1; 76095584Sanholt 76195584Sanholt BEGIN_RING( 6 ); 76295584Sanholt 76395584Sanholt RADEON_PURGE_CACHE(); 76495584Sanholt RADEON_PURGE_ZCACHE(); 76595584Sanholt RADEON_WAIT_UNTIL_IDLE(); 76695584Sanholt 76795584Sanholt ADVANCE_RING(); 768112015Sanholt COMMIT_RING(); 76995584Sanholt} 77095584Sanholt 77195584Sanholt/* Reset the Command Processor. This will not flush any pending 77295584Sanholt * commands, so you must wait for the CP command stream to complete 77395584Sanholt * before calling this routine. 77495584Sanholt */ 77595584Sanholtstatic void radeon_do_cp_reset( drm_radeon_private_t *dev_priv ) 77695584Sanholt{ 77795584Sanholt u32 cur_read_ptr; 778112015Sanholt DRM_DEBUG( "\n" ); 77995584Sanholt 78095584Sanholt cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); 78195584Sanholt RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); 78295584Sanholt *dev_priv->ring.head = cur_read_ptr; 78395584Sanholt dev_priv->ring.tail = cur_read_ptr; 78495584Sanholt} 78595584Sanholt 78695584Sanholt/* Stop the Command Processor. This will not flush any pending 78795584Sanholt * commands, so you must flush the command stream and wait for the CP 78895584Sanholt * to go idle before calling this routine. 78995584Sanholt */ 79095584Sanholtstatic void radeon_do_cp_stop( drm_radeon_private_t *dev_priv ) 79195584Sanholt{ 792112015Sanholt DRM_DEBUG( "\n" ); 79395584Sanholt 79495584Sanholt RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS ); 79595584Sanholt 79695584Sanholt dev_priv->cp_running = 0; 79795584Sanholt} 79895584Sanholt 79995584Sanholt/* Reset the engine. This will stop the CP if it is running. 80095584Sanholt */ 80195584Sanholtstatic int radeon_do_engine_reset( drm_device_t *dev ) 80295584Sanholt{ 80395584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 80495584Sanholt u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset; 805112015Sanholt DRM_DEBUG( "\n" ); 80695584Sanholt 80795584Sanholt radeon_do_pixcache_flush( dev_priv ); 80895584Sanholt 80995584Sanholt clock_cntl_index = RADEON_READ( RADEON_CLOCK_CNTL_INDEX ); 81095584Sanholt mclk_cntl = RADEON_READ_PLL( dev, RADEON_MCLK_CNTL ); 81195584Sanholt 81295584Sanholt RADEON_WRITE_PLL( RADEON_MCLK_CNTL, ( mclk_cntl | 81395584Sanholt RADEON_FORCEON_MCLKA | 81495584Sanholt RADEON_FORCEON_MCLKB | 81595584Sanholt RADEON_FORCEON_YCLKA | 81695584Sanholt RADEON_FORCEON_YCLKB | 81795584Sanholt RADEON_FORCEON_MC | 81895584Sanholt RADEON_FORCEON_AIC ) ); 81995584Sanholt 82095584Sanholt rbbm_soft_reset = RADEON_READ( RADEON_RBBM_SOFT_RESET ); 82195584Sanholt 82295584Sanholt RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset | 82395584Sanholt RADEON_SOFT_RESET_CP | 82495584Sanholt RADEON_SOFT_RESET_HI | 82595584Sanholt RADEON_SOFT_RESET_SE | 82695584Sanholt RADEON_SOFT_RESET_RE | 82795584Sanholt RADEON_SOFT_RESET_PP | 82895584Sanholt RADEON_SOFT_RESET_E2 | 82995584Sanholt RADEON_SOFT_RESET_RB ) ); 83095584Sanholt RADEON_READ( RADEON_RBBM_SOFT_RESET ); 83195584Sanholt RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset & 83295584Sanholt ~( RADEON_SOFT_RESET_CP | 83395584Sanholt RADEON_SOFT_RESET_HI | 83495584Sanholt RADEON_SOFT_RESET_SE | 83595584Sanholt RADEON_SOFT_RESET_RE | 83695584Sanholt RADEON_SOFT_RESET_PP | 83795584Sanholt RADEON_SOFT_RESET_E2 | 83895584Sanholt RADEON_SOFT_RESET_RB ) ) ); 83995584Sanholt RADEON_READ( RADEON_RBBM_SOFT_RESET ); 84095584Sanholt 84195584Sanholt 84295584Sanholt RADEON_WRITE_PLL( RADEON_MCLK_CNTL, mclk_cntl ); 84395584Sanholt RADEON_WRITE( RADEON_CLOCK_CNTL_INDEX, clock_cntl_index ); 84495584Sanholt RADEON_WRITE( RADEON_RBBM_SOFT_RESET, rbbm_soft_reset ); 84595584Sanholt 84695584Sanholt /* Reset the CP ring */ 84795584Sanholt radeon_do_cp_reset( dev_priv ); 84895584Sanholt 84995584Sanholt /* The CP is no longer running after an engine reset */ 85095584Sanholt dev_priv->cp_running = 0; 85195584Sanholt 85295584Sanholt /* Reset any pending vertex, indirect buffers */ 85395584Sanholt radeon_freelist_reset( dev ); 85495584Sanholt 85595584Sanholt return 0; 85695584Sanholt} 85795584Sanholt 85895584Sanholtstatic void radeon_cp_init_ring_buffer( drm_device_t *dev, 85995584Sanholt drm_radeon_private_t *dev_priv ) 86095584Sanholt{ 86195584Sanholt u32 ring_start, cur_read_ptr; 86295584Sanholt u32 tmp; 86395584Sanholt 86495584Sanholt /* Initialize the memory controller */ 86595584Sanholt RADEON_WRITE( RADEON_MC_FB_LOCATION, 86695584Sanholt (dev_priv->agp_vm_start - 1) & 0xffff0000 ); 86795584Sanholt 86895584Sanholt if ( !dev_priv->is_pci ) { 86995584Sanholt RADEON_WRITE( RADEON_MC_AGP_LOCATION, 87095584Sanholt (((dev_priv->agp_vm_start - 1 + 87195584Sanholt dev_priv->agp_size) & 0xffff0000) | 87295584Sanholt (dev_priv->agp_vm_start >> 16)) ); 87395584Sanholt } 87495584Sanholt 87595584Sanholt#if __REALLY_HAVE_AGP 87695584Sanholt if ( !dev_priv->is_pci ) 87795584Sanholt ring_start = (dev_priv->cp_ring->offset 87895584Sanholt - dev->agp->base 87995584Sanholt + dev_priv->agp_vm_start); 88095584Sanholt else 88195584Sanholt#endif 88295584Sanholt ring_start = (dev_priv->cp_ring->offset 88395584Sanholt - dev->sg->handle 88495584Sanholt + dev_priv->agp_vm_start); 88595584Sanholt 88695584Sanholt RADEON_WRITE( RADEON_CP_RB_BASE, ring_start ); 88795584Sanholt 88895584Sanholt /* Set the write pointer delay */ 88995584Sanholt RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 ); 89095584Sanholt 89195584Sanholt /* Initialize the ring buffer's read and write pointers */ 89295584Sanholt cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); 89395584Sanholt RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); 89495584Sanholt *dev_priv->ring.head = cur_read_ptr; 89595584Sanholt dev_priv->ring.tail = cur_read_ptr; 89695584Sanholt 89795584Sanholt if ( !dev_priv->is_pci ) { 89895584Sanholt RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, 89995584Sanholt dev_priv->ring_rptr->offset ); 90095584Sanholt } else { 90195584Sanholt drm_sg_mem_t *entry = dev->sg; 90295584Sanholt unsigned long tmp_ofs, page_ofs; 90395584Sanholt 90495584Sanholt tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle; 90595584Sanholt page_ofs = tmp_ofs >> PAGE_SHIFT; 90695584Sanholt 90795584Sanholt RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, 90895584Sanholt entry->busaddr[page_ofs]); 90995584Sanholt DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n", 91095584Sanholt entry->busaddr[page_ofs], 91195584Sanholt entry->handle + tmp_ofs ); 91295584Sanholt } 91395584Sanholt 914112015Sanholt /* Initialize the scratch register pointer. This will cause 915112015Sanholt * the scratch register values to be written out to memory 916112015Sanholt * whenever they are updated. 917112015Sanholt * 918112015Sanholt * We simply put this behind the ring read pointer, this works 919112015Sanholt * with PCI GART as well as (whatever kind of) AGP GART 920112015Sanholt */ 921112015Sanholt RADEON_WRITE( RADEON_SCRATCH_ADDR, RADEON_READ( RADEON_CP_RB_RPTR_ADDR ) 922112015Sanholt + RADEON_SCRATCH_REG_OFFSET ); 923112015Sanholt 924112015Sanholt dev_priv->scratch = ((__volatile__ u32 *) 925112015Sanholt dev_priv->ring.head + 926112015Sanholt (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); 927112015Sanholt 928112015Sanholt RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); 929112015Sanholt 930112015Sanholt /* Writeback doesn't seem to work everywhere, test it first */ 931112015Sanholt DRM_WRITE32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0 ); 932112015Sanholt RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef ); 933112015Sanholt 934112015Sanholt for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) { 935112015Sanholt if ( DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1) ) == 0xdeadbeef ) 936112015Sanholt break; 937112015Sanholt DRM_UDELAY( 1 ); 938112015Sanholt } 939112015Sanholt 940112015Sanholt if ( tmp < dev_priv->usec_timeout ) { 941112015Sanholt dev_priv->writeback_works = 1; 942112015Sanholt DRM_DEBUG( "writeback test succeeded, tmp=%d\n", tmp ); 943112015Sanholt } else { 944112015Sanholt dev_priv->writeback_works = 0; 945112015Sanholt DRM_DEBUG( "writeback test failed\n" ); 946112015Sanholt } 947112015Sanholt 948112015Sanholt dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; 949112015Sanholt RADEON_WRITE( RADEON_LAST_FRAME_REG, 950112015Sanholt dev_priv->sarea_priv->last_frame ); 951112015Sanholt 952112015Sanholt dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0; 953112015Sanholt RADEON_WRITE( RADEON_LAST_DISPATCH_REG, 954112015Sanholt dev_priv->sarea_priv->last_dispatch ); 955112015Sanholt 956112015Sanholt dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; 957112015Sanholt RADEON_WRITE( RADEON_LAST_CLEAR_REG, 958112015Sanholt dev_priv->sarea_priv->last_clear ); 959112015Sanholt 96095584Sanholt /* Set ring buffer size */ 961112015Sanholt#ifdef __BIG_ENDIAN 962112015Sanholt RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT ); 963112015Sanholt#else 96495584Sanholt RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw ); 965112015Sanholt#endif 96695584Sanholt 96795584Sanholt radeon_do_wait_for_idle( dev_priv ); 96895584Sanholt 96995584Sanholt /* Turn on bus mastering */ 97095584Sanholt tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS; 97195584Sanholt RADEON_WRITE( RADEON_BUS_CNTL, tmp ); 97295584Sanholt 97395584Sanholt /* Sync everything up */ 97495584Sanholt RADEON_WRITE( RADEON_ISYNC_CNTL, 97595584Sanholt (RADEON_ISYNC_ANY2D_IDLE3D | 97695584Sanholt RADEON_ISYNC_ANY3D_IDLE2D | 97795584Sanholt RADEON_ISYNC_WAIT_IDLEGUI | 97895584Sanholt RADEON_ISYNC_CPSCRATCH_IDLEGUI) ); 97995584Sanholt} 98095584Sanholt 98195584Sanholtstatic int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) 98295584Sanholt{ 98395584Sanholt drm_radeon_private_t *dev_priv; 98495584Sanholt u32 tmp; 985112015Sanholt DRM_DEBUG( "\n" ); 98695584Sanholt 98795584Sanholt dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); 98895584Sanholt if ( dev_priv == NULL ) 989112015Sanholt return DRM_ERR(ENOMEM); 99095584Sanholt 99195584Sanholt memset( dev_priv, 0, sizeof(drm_radeon_private_t) ); 99295584Sanholt 99395584Sanholt dev_priv->is_pci = init->is_pci; 99495584Sanholt 99595584Sanholt#if !defined(PCIGART_ENABLED) 99695584Sanholt /* PCI support is not 100% working, so we disable it here. 99795584Sanholt */ 99895584Sanholt if ( dev_priv->is_pci ) { 99995584Sanholt DRM_ERROR( "PCI GART not yet supported for Radeon!\n" ); 100095584Sanholt dev->dev_private = (void *)dev_priv; 100195584Sanholt radeon_do_cleanup_cp(dev); 1002112015Sanholt return DRM_ERR(EINVAL); 100395584Sanholt } 100495584Sanholt#endif 100595584Sanholt 100695584Sanholt if ( dev_priv->is_pci && !dev->sg ) { 100795584Sanholt DRM_ERROR( "PCI GART memory not allocated!\n" ); 100895584Sanholt dev->dev_private = (void *)dev_priv; 100995584Sanholt radeon_do_cleanup_cp(dev); 1010112015Sanholt return DRM_ERR(EINVAL); 101195584Sanholt } 101295584Sanholt 101395584Sanholt dev_priv->usec_timeout = init->usec_timeout; 101495584Sanholt if ( dev_priv->usec_timeout < 1 || 101595584Sanholt dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) { 101695584Sanholt DRM_DEBUG( "TIMEOUT problem!\n" ); 101795584Sanholt dev->dev_private = (void *)dev_priv; 101895584Sanholt radeon_do_cleanup_cp(dev); 1019112015Sanholt return DRM_ERR(EINVAL); 102095584Sanholt } 102195584Sanholt 1022112015Sanholt dev_priv->is_r200 = (init->func == RADEON_INIT_R200_CP); 1023112015Sanholt dev_priv->do_boxes = 0; 102495584Sanholt dev_priv->cp_mode = init->cp_mode; 102595584Sanholt 102695584Sanholt /* We don't support anything other than bus-mastering ring mode, 102795584Sanholt * but the ring can be in either AGP or PCI space for the ring 102895584Sanholt * read pointer. 102995584Sanholt */ 103095584Sanholt if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) && 103195584Sanholt ( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) { 103295584Sanholt DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode ); 103395584Sanholt dev->dev_private = (void *)dev_priv; 103495584Sanholt radeon_do_cleanup_cp(dev); 1035112015Sanholt return DRM_ERR(EINVAL); 103695584Sanholt } 103795584Sanholt 103895584Sanholt switch ( init->fb_bpp ) { 103995584Sanholt case 16: 104095584Sanholt dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; 104195584Sanholt break; 104295584Sanholt case 32: 104395584Sanholt default: 104495584Sanholt dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; 104595584Sanholt break; 104695584Sanholt } 104795584Sanholt dev_priv->front_offset = init->front_offset; 104895584Sanholt dev_priv->front_pitch = init->front_pitch; 104995584Sanholt dev_priv->back_offset = init->back_offset; 105095584Sanholt dev_priv->back_pitch = init->back_pitch; 105195584Sanholt 105295584Sanholt switch ( init->depth_bpp ) { 105395584Sanholt case 16: 105495584Sanholt dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; 105595584Sanholt break; 105695584Sanholt case 32: 105795584Sanholt default: 105895584Sanholt dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; 105995584Sanholt break; 106095584Sanholt } 106195584Sanholt dev_priv->depth_offset = init->depth_offset; 106295584Sanholt dev_priv->depth_pitch = init->depth_pitch; 106395584Sanholt 106495584Sanholt dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) | 106595584Sanholt (dev_priv->front_offset >> 10)); 106695584Sanholt dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) | 106795584Sanholt (dev_priv->back_offset >> 10)); 106895584Sanholt dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) | 106995584Sanholt (dev_priv->depth_offset >> 10)); 107095584Sanholt 107195584Sanholt /* Hardware state for depth clears. Remove this if/when we no 107295584Sanholt * longer clear the depth buffer with a 3D rectangle. Hard-code 107395584Sanholt * all values to prevent unwanted 3D state from slipping through 107495584Sanholt * and screwing with the clear operation. 107595584Sanholt */ 107695584Sanholt dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | 107795584Sanholt (dev_priv->color_fmt << 10) | 1078112015Sanholt (1<<15)); 107995584Sanholt 1080112015Sanholt dev_priv->depth_clear.rb3d_zstencilcntl = 1081112015Sanholt (dev_priv->depth_fmt | 1082112015Sanholt RADEON_Z_TEST_ALWAYS | 1083112015Sanholt RADEON_STENCIL_TEST_ALWAYS | 1084112015Sanholt RADEON_STENCIL_S_FAIL_REPLACE | 1085112015Sanholt RADEON_STENCIL_ZPASS_REPLACE | 1086112015Sanholt RADEON_STENCIL_ZFAIL_REPLACE | 1087112015Sanholt RADEON_Z_WRITE_ENABLE); 108895584Sanholt 108995584Sanholt dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | 109095584Sanholt RADEON_BFACE_SOLID | 109195584Sanholt RADEON_FFACE_SOLID | 109295584Sanholt RADEON_FLAT_SHADE_VTX_LAST | 109395584Sanholt RADEON_DIFFUSE_SHADE_FLAT | 109495584Sanholt RADEON_ALPHA_SHADE_FLAT | 109595584Sanholt RADEON_SPECULAR_SHADE_FLAT | 109695584Sanholt RADEON_FOG_SHADE_FLAT | 109795584Sanholt RADEON_VTX_PIX_CENTER_OGL | 109895584Sanholt RADEON_ROUND_MODE_TRUNC | 109995584Sanholt RADEON_ROUND_PREC_8TH_PIX); 110095584Sanholt 1101112015Sanholt DRM_GETSAREA(); 1102112015Sanholt 110395584Sanholt if(!dev_priv->sarea) { 110495584Sanholt DRM_ERROR("could not find sarea!\n"); 110595584Sanholt dev->dev_private = (void *)dev_priv; 110695584Sanholt radeon_do_cleanup_cp(dev); 1107112015Sanholt return DRM_ERR(EINVAL); 110895584Sanholt } 110995584Sanholt 111095584Sanholt DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); 111195584Sanholt if(!dev_priv->fb) { 111295584Sanholt DRM_ERROR("could not find framebuffer!\n"); 111395584Sanholt dev->dev_private = (void *)dev_priv; 111495584Sanholt radeon_do_cleanup_cp(dev); 1115112015Sanholt return DRM_ERR(EINVAL); 111695584Sanholt } 111795584Sanholt DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); 111895584Sanholt if(!dev_priv->mmio) { 111995584Sanholt DRM_ERROR("could not find mmio region!\n"); 112095584Sanholt dev->dev_private = (void *)dev_priv; 112195584Sanholt radeon_do_cleanup_cp(dev); 1122112015Sanholt return DRM_ERR(EINVAL); 112395584Sanholt } 112495584Sanholt DRM_FIND_MAP( dev_priv->cp_ring, init->ring_offset ); 112595584Sanholt if(!dev_priv->cp_ring) { 112695584Sanholt DRM_ERROR("could not find cp ring region!\n"); 112795584Sanholt dev->dev_private = (void *)dev_priv; 112895584Sanholt radeon_do_cleanup_cp(dev); 1129112015Sanholt return DRM_ERR(EINVAL); 113095584Sanholt } 113195584Sanholt DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); 113295584Sanholt if(!dev_priv->ring_rptr) { 113395584Sanholt DRM_ERROR("could not find ring read pointer!\n"); 113495584Sanholt dev->dev_private = (void *)dev_priv; 113595584Sanholt radeon_do_cleanup_cp(dev); 1136112015Sanholt return DRM_ERR(EINVAL); 113795584Sanholt } 113895584Sanholt DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); 113995584Sanholt if(!dev_priv->buffers) { 114095584Sanholt DRM_ERROR("could not find dma buffer region!\n"); 114195584Sanholt dev->dev_private = (void *)dev_priv; 114295584Sanholt radeon_do_cleanup_cp(dev); 1143112015Sanholt return DRM_ERR(EINVAL); 114495584Sanholt } 114595584Sanholt 114695584Sanholt if ( !dev_priv->is_pci ) { 114795584Sanholt DRM_FIND_MAP( dev_priv->agp_textures, 114895584Sanholt init->agp_textures_offset ); 114995584Sanholt if(!dev_priv->agp_textures) { 115095584Sanholt DRM_ERROR("could not find agp texture region!\n"); 115195584Sanholt dev->dev_private = (void *)dev_priv; 115295584Sanholt radeon_do_cleanup_cp(dev); 1153112015Sanholt return DRM_ERR(EINVAL); 115495584Sanholt } 115595584Sanholt } 115695584Sanholt 115795584Sanholt dev_priv->sarea_priv = 115895584Sanholt (drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle + 115995584Sanholt init->sarea_priv_offset); 116095584Sanholt 116195584Sanholt if ( !dev_priv->is_pci ) { 116295584Sanholt DRM_IOREMAP( dev_priv->cp_ring ); 116395584Sanholt DRM_IOREMAP( dev_priv->ring_rptr ); 116495584Sanholt DRM_IOREMAP( dev_priv->buffers ); 116595584Sanholt if(!dev_priv->cp_ring->handle || 116695584Sanholt !dev_priv->ring_rptr->handle || 116795584Sanholt !dev_priv->buffers->handle) { 116895584Sanholt DRM_ERROR("could not find ioremap agp regions!\n"); 116995584Sanholt dev->dev_private = (void *)dev_priv; 117095584Sanholt radeon_do_cleanup_cp(dev); 1171112015Sanholt return DRM_ERR(EINVAL); 117295584Sanholt } 117395584Sanholt } else { 117495584Sanholt dev_priv->cp_ring->handle = 117595584Sanholt (void *)dev_priv->cp_ring->offset; 117695584Sanholt dev_priv->ring_rptr->handle = 117795584Sanholt (void *)dev_priv->ring_rptr->offset; 117895584Sanholt dev_priv->buffers->handle = (void *)dev_priv->buffers->offset; 117995584Sanholt 118095584Sanholt DRM_DEBUG( "dev_priv->cp_ring->handle %p\n", 118195584Sanholt dev_priv->cp_ring->handle ); 118295584Sanholt DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n", 118395584Sanholt dev_priv->ring_rptr->handle ); 118495584Sanholt DRM_DEBUG( "dev_priv->buffers->handle %p\n", 118595584Sanholt dev_priv->buffers->handle ); 118695584Sanholt } 118795584Sanholt 118895584Sanholt 118995584Sanholt dev_priv->agp_size = init->agp_size; 119095584Sanholt dev_priv->agp_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE ); 119195584Sanholt#if __REALLY_HAVE_AGP 119295584Sanholt if ( !dev_priv->is_pci ) 119395584Sanholt dev_priv->agp_buffers_offset = (dev_priv->buffers->offset 119495584Sanholt - dev->agp->base 119595584Sanholt + dev_priv->agp_vm_start); 119695584Sanholt else 119795584Sanholt#endif 119895584Sanholt dev_priv->agp_buffers_offset = (dev_priv->buffers->offset 119995584Sanholt - dev->sg->handle 120095584Sanholt + dev_priv->agp_vm_start); 120195584Sanholt 120295584Sanholt DRM_DEBUG( "dev_priv->agp_size %d\n", 120395584Sanholt dev_priv->agp_size ); 120495584Sanholt DRM_DEBUG( "dev_priv->agp_vm_start 0x%x\n", 120595584Sanholt dev_priv->agp_vm_start ); 120695584Sanholt DRM_DEBUG( "dev_priv->agp_buffers_offset 0x%lx\n", 120795584Sanholt dev_priv->agp_buffers_offset ); 120895584Sanholt 120995584Sanholt dev_priv->ring.head = ((__volatile__ u32 *) 121095584Sanholt dev_priv->ring_rptr->handle); 121195584Sanholt 121295584Sanholt dev_priv->ring.start = (u32 *)dev_priv->cp_ring->handle; 121395584Sanholt dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle 121495584Sanholt + init->ring_size / sizeof(u32)); 121595584Sanholt dev_priv->ring.size = init->ring_size; 121695584Sanholt dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 ); 121795584Sanholt 121895584Sanholt dev_priv->ring.tail_mask = 121995584Sanholt (dev_priv->ring.size / sizeof(u32)) - 1; 122095584Sanholt 122195584Sanholt dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; 1222112015Sanholt dev_priv->ring.ring_rptr = dev_priv->ring_rptr; 122395584Sanholt 122495584Sanholt#if __REALLY_HAVE_SG 122595584Sanholt if ( dev_priv->is_pci ) { 122695584Sanholt if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, 122795584Sanholt &dev_priv->bus_pci_gart)) { 122895584Sanholt DRM_ERROR( "failed to init PCI GART!\n" ); 122995584Sanholt dev->dev_private = (void *)dev_priv; 123095584Sanholt radeon_do_cleanup_cp(dev); 1231112015Sanholt return DRM_ERR(ENOMEM); 123295584Sanholt } 123395584Sanholt /* Turn on PCI GART 123495584Sanholt */ 123595584Sanholt tmp = RADEON_READ( RADEON_AIC_CNTL ) 123695584Sanholt | RADEON_PCIGART_TRANSLATE_EN; 123795584Sanholt RADEON_WRITE( RADEON_AIC_CNTL, tmp ); 123895584Sanholt 123995584Sanholt /* set PCI GART page-table base address 124095584Sanholt */ 124195584Sanholt RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart ); 124295584Sanholt 124395584Sanholt /* set address range for PCI address translate 124495584Sanholt */ 124595584Sanholt RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start ); 124695584Sanholt RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start 124795584Sanholt + dev_priv->agp_size - 1); 124895584Sanholt 124995584Sanholt /* Turn off AGP aperture -- is this required for PCIGART? 125095584Sanholt */ 125195584Sanholt RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ 125295584Sanholt RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ 125395584Sanholt } else { 1254112015Sanholt#endif /* __REALLY_HAVE_SG */ 125595584Sanholt /* Turn off PCI GART 125695584Sanholt */ 125795584Sanholt tmp = RADEON_READ( RADEON_AIC_CNTL ) 125895584Sanholt & ~RADEON_PCIGART_TRANSLATE_EN; 125995584Sanholt RADEON_WRITE( RADEON_AIC_CNTL, tmp ); 126095584Sanholt#if __REALLY_HAVE_SG 126195584Sanholt } 1262112015Sanholt#endif /* __REALLY_HAVE_SG */ 126395584Sanholt 126495584Sanholt radeon_cp_load_microcode( dev_priv ); 126595584Sanholt radeon_cp_init_ring_buffer( dev, dev_priv ); 126695584Sanholt 126795584Sanholt dev_priv->last_buf = 0; 126895584Sanholt 126995584Sanholt dev->dev_private = (void *)dev_priv; 127095584Sanholt 127195584Sanholt radeon_do_engine_reset( dev ); 127295584Sanholt 127395584Sanholt return 0; 127495584Sanholt} 127595584Sanholt 127695584Sanholtint radeon_do_cleanup_cp( drm_device_t *dev ) 127795584Sanholt{ 1278112015Sanholt DRM_DEBUG( "\n" ); 127995584Sanholt 128095584Sanholt if ( dev->dev_private ) { 128195584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 128295584Sanholt 128395584Sanholt if ( !dev_priv->is_pci ) { 128495584Sanholt DRM_IOREMAPFREE( dev_priv->cp_ring ); 128595584Sanholt DRM_IOREMAPFREE( dev_priv->ring_rptr ); 128695584Sanholt DRM_IOREMAPFREE( dev_priv->buffers ); 1287112015Sanholt } else { 128895584Sanholt#if __REALLY_HAVE_SG 128995584Sanholt if (!DRM(ati_pcigart_cleanup)( dev, 129095584Sanholt dev_priv->phys_pci_gart, 129195584Sanholt dev_priv->bus_pci_gart )) 129295584Sanholt DRM_ERROR( "failed to cleanup PCI GART!\n" ); 1293112015Sanholt#endif /* __REALLY_HAVE_SG */ 129495584Sanholt } 129595584Sanholt 129695584Sanholt DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t), 129795584Sanholt DRM_MEM_DRIVER ); 129895584Sanholt dev->dev_private = NULL; 129995584Sanholt } 130095584Sanholt 130195584Sanholt return 0; 130295584Sanholt} 130395584Sanholt 1304112015Sanholtint radeon_cp_init( DRM_IOCTL_ARGS ) 130595584Sanholt{ 1306112015Sanholt DRM_DEVICE; 130795584Sanholt drm_radeon_init_t init; 130895584Sanholt 1309112015Sanholt DRM_COPY_FROM_USER_IOCTL( init, (drm_radeon_init_t *)data, sizeof(init) ); 131095584Sanholt 131195584Sanholt switch ( init.func ) { 131295584Sanholt case RADEON_INIT_CP: 1313112015Sanholt case RADEON_INIT_R200_CP: 131495584Sanholt return radeon_do_init_cp( dev, &init ); 131595584Sanholt case RADEON_CLEANUP_CP: 131695584Sanholt return radeon_do_cleanup_cp( dev ); 131795584Sanholt } 131895584Sanholt 1319112015Sanholt return DRM_ERR(EINVAL); 132095584Sanholt} 132195584Sanholt 1322112015Sanholtint radeon_cp_start( DRM_IOCTL_ARGS ) 132395584Sanholt{ 1324112015Sanholt DRM_DEVICE; 132595584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1326112015Sanholt DRM_DEBUG( "\n" ); 132795584Sanholt 132895584Sanholt LOCK_TEST_WITH_RETURN( dev ); 132995584Sanholt 133095584Sanholt if ( dev_priv->cp_running ) { 1331112015Sanholt DRM_DEBUG( "%s while CP running\n", __FUNCTION__ ); 133295584Sanholt return 0; 133395584Sanholt } 133495584Sanholt if ( dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS ) { 133595584Sanholt DRM_DEBUG( "%s called with bogus CP mode (%d)\n", 1336112015Sanholt __FUNCTION__, dev_priv->cp_mode ); 133795584Sanholt return 0; 133895584Sanholt } 133995584Sanholt 134095584Sanholt radeon_do_cp_start( dev_priv ); 134195584Sanholt 134295584Sanholt return 0; 134395584Sanholt} 134495584Sanholt 134595584Sanholt/* Stop the CP. The engine must have been idled before calling this 134695584Sanholt * routine. 134795584Sanholt */ 1348112015Sanholtint radeon_cp_stop( DRM_IOCTL_ARGS ) 134995584Sanholt{ 1350112015Sanholt DRM_DEVICE; 135195584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 135295584Sanholt drm_radeon_cp_stop_t stop; 135395584Sanholt int ret; 1354112015Sanholt DRM_DEBUG( "\n" ); 135595584Sanholt 135695584Sanholt LOCK_TEST_WITH_RETURN( dev ); 135795584Sanholt 1358112015Sanholt DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t *)data, sizeof(stop) ); 135995584Sanholt 1360112015Sanholt if (!dev_priv->cp_running) 1361112015Sanholt return 0; 1362112015Sanholt 136395584Sanholt /* Flush any pending CP commands. This ensures any outstanding 136495584Sanholt * commands are exectuted by the engine before we turn it off. 136595584Sanholt */ 136695584Sanholt if ( stop.flush ) { 136795584Sanholt radeon_do_cp_flush( dev_priv ); 136895584Sanholt } 136995584Sanholt 137095584Sanholt /* If we fail to make the engine go idle, we return an error 137195584Sanholt * code so that the DRM ioctl wrapper can try again. 137295584Sanholt */ 137395584Sanholt if ( stop.idle ) { 137495584Sanholt ret = radeon_do_cp_idle( dev_priv ); 137595584Sanholt if ( ret ) return ret; 137695584Sanholt } 137795584Sanholt 137895584Sanholt /* Finally, we can turn off the CP. If the engine isn't idle, 137995584Sanholt * we will get some dropped triangles as they won't be fully 138095584Sanholt * rendered before the CP is shut down. 138195584Sanholt */ 138295584Sanholt radeon_do_cp_stop( dev_priv ); 138395584Sanholt 138495584Sanholt /* Reset the engine */ 138595584Sanholt radeon_do_engine_reset( dev ); 138695584Sanholt 138795584Sanholt return 0; 138895584Sanholt} 138995584Sanholt 1390112015Sanholt 1391112015Sanholtvoid radeon_do_release( drm_device_t *dev ) 1392112015Sanholt{ 1393112015Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1394112015Sanholt int ret; 1395112015Sanholt 1396112015Sanholt if (dev_priv) { 1397112015Sanholt if (dev_priv->cp_running) { 1398112015Sanholt /* Stop the cp */ 1399112015Sanholt while ((ret = radeon_do_cp_idle( dev_priv )) != 0) { 1400112015Sanholt DRM_DEBUG("radeon_do_cp_idle %d\n", ret); 1401112015Sanholt#ifdef __linux__ 1402112015Sanholt schedule(); 1403112015Sanholt#else 1404112015Sanholt tsleep(&ret, PZERO, "rdnrel", 1); 1405112015Sanholt#endif 1406112015Sanholt } 1407112015Sanholt radeon_do_cp_stop( dev_priv ); 1408112015Sanholt radeon_do_engine_reset( dev ); 1409112015Sanholt } 1410112015Sanholt 1411112015Sanholt /* Disable *all* interrupts */ 1412112015Sanholt RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); 1413112015Sanholt 1414112015Sanholt /* Free memory heap structures */ 1415112015Sanholt radeon_mem_takedown( &(dev_priv->agp_heap) ); 1416112015Sanholt radeon_mem_takedown( &(dev_priv->fb_heap) ); 1417112015Sanholt 1418112015Sanholt /* deallocate kernel resources */ 1419112015Sanholt radeon_do_cleanup_cp( dev ); 1420112015Sanholt } 1421112015Sanholt} 1422112015Sanholt 142395584Sanholt/* Just reset the CP ring. Called as part of an X Server engine reset. 142495584Sanholt */ 1425112015Sanholtint radeon_cp_reset( DRM_IOCTL_ARGS ) 142695584Sanholt{ 1427112015Sanholt DRM_DEVICE; 142895584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1429112015Sanholt DRM_DEBUG( "\n" ); 143095584Sanholt 143195584Sanholt LOCK_TEST_WITH_RETURN( dev ); 143295584Sanholt 143395584Sanholt if ( !dev_priv ) { 1434112015Sanholt DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); 1435112015Sanholt return DRM_ERR(EINVAL); 143695584Sanholt } 143795584Sanholt 143895584Sanholt radeon_do_cp_reset( dev_priv ); 143995584Sanholt 144095584Sanholt /* The CP is no longer running after an engine reset */ 144195584Sanholt dev_priv->cp_running = 0; 144295584Sanholt 144395584Sanholt return 0; 144495584Sanholt} 144595584Sanholt 1446112015Sanholtint radeon_cp_idle( DRM_IOCTL_ARGS ) 144795584Sanholt{ 1448112015Sanholt DRM_DEVICE; 144995584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1450112015Sanholt DRM_DEBUG( "\n" ); 145195584Sanholt 145295584Sanholt LOCK_TEST_WITH_RETURN( dev ); 145395584Sanholt 145495584Sanholt return radeon_do_cp_idle( dev_priv ); 145595584Sanholt} 145695584Sanholt 1457112015Sanholtint radeon_engine_reset( DRM_IOCTL_ARGS ) 145895584Sanholt{ 1459112015Sanholt DRM_DEVICE; 1460112015Sanholt DRM_DEBUG( "\n" ); 146195584Sanholt 146295584Sanholt LOCK_TEST_WITH_RETURN( dev ); 146395584Sanholt 146495584Sanholt return radeon_do_engine_reset( dev ); 146595584Sanholt} 146695584Sanholt 146795584Sanholt 146895584Sanholt/* ================================================================ 146995584Sanholt * Fullscreen mode 147095584Sanholt */ 147195584Sanholt 1472112015Sanholt/* KW: Deprecated to say the least: 1473112015Sanholt */ 1474112015Sanholtint radeon_fullscreen( DRM_IOCTL_ARGS ) 147595584Sanholt{ 147695584Sanholt return 0; 147795584Sanholt} 147895584Sanholt 147995584Sanholt 148095584Sanholt/* ================================================================ 148195584Sanholt * Freelist management 148295584Sanholt */ 148395584Sanholt 1484112015Sanholt/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through 1485112015Sanholt * bufs until freelist code is used. Note this hides a problem with 1486112015Sanholt * the scratch register * (used to keep track of last buffer 1487112015Sanholt * completed) being written to before * the last buffer has actually 1488112015Sanholt * completed rendering. 1489112015Sanholt * 1490112015Sanholt * KW: It's also a good way to find free buffers quickly. 1491112015Sanholt * 1492112015Sanholt * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't 1493112015Sanholt * sleep. However, bugs in older versions of radeon_accel.c mean that 1494112015Sanholt * we essentially have to do this, else old clients will break. 1495112015Sanholt * 1496112015Sanholt * However, it does leave open a potential deadlock where all the 1497112015Sanholt * buffers are held by other clients, which can't release them because 1498112015Sanholt * they can't get the lock. 1499112015Sanholt */ 1500112015Sanholt 1501112015Sanholtdrm_buf_t *radeon_freelist_get( drm_device_t *dev ) 150295584Sanholt{ 150395584Sanholt drm_device_dma_t *dma = dev->dma; 150495584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 1505112015Sanholt drm_radeon_buf_priv_t *buf_priv; 150695584Sanholt drm_buf_t *buf; 1507112015Sanholt int i, t; 1508112015Sanholt int start; 150995584Sanholt 1510112015Sanholt if ( ++dev_priv->last_buf >= dma->buf_count ) 1511112015Sanholt dev_priv->last_buf = 0; 151295584Sanholt 1513112015Sanholt start = dev_priv->last_buf; 151495584Sanholt 1515112015Sanholt for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { 1516112015Sanholt u32 done_age = GET_SCRATCH( 1 ); 1517112015Sanholt DRM_DEBUG("done_age = %d\n",done_age); 1518112015Sanholt for ( i = start ; i < dma->buf_count ; i++ ) { 1519112015Sanholt buf = dma->buflist[i]; 1520112015Sanholt buf_priv = buf->dev_private; 1521112015Sanholt if ( buf->pid == 0 || (buf->pending && 1522112015Sanholt buf_priv->age <= done_age) ) { 1523112015Sanholt dev_priv->stats.requested_bufs++; 1524112015Sanholt buf->pending = 0; 1525112015Sanholt return buf; 1526112015Sanholt } 1527112015Sanholt start = 0; 1528112015Sanholt } 152995584Sanholt 1530112015Sanholt if (t) { 1531112015Sanholt DRM_UDELAY( 1 ); 1532112015Sanholt dev_priv->stats.freelist_loops++; 1533112015Sanholt } 153495584Sanholt } 153595584Sanholt 1536112015Sanholt DRM_DEBUG( "returning NULL!\n" ); 1537112015Sanholt return NULL; 153895584Sanholt} 1539112015Sanholt#if 0 154095584Sanholtdrm_buf_t *radeon_freelist_get( drm_device_t *dev ) 154195584Sanholt{ 154295584Sanholt drm_device_dma_t *dma = dev->dma; 154395584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 154495584Sanholt drm_radeon_buf_priv_t *buf_priv; 154595584Sanholt drm_buf_t *buf; 154695584Sanholt int i, t; 154795584Sanholt int start; 1548112015Sanholt u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); 154995584Sanholt 155095584Sanholt if ( ++dev_priv->last_buf >= dma->buf_count ) 155195584Sanholt dev_priv->last_buf = 0; 1552112015Sanholt 155395584Sanholt start = dev_priv->last_buf; 1554112015Sanholt dev_priv->stats.freelist_loops++; 1555112015Sanholt 1556112015Sanholt for ( t = 0 ; t < 2 ; t++ ) { 155795584Sanholt for ( i = start ; i < dma->buf_count ; i++ ) { 155895584Sanholt buf = dma->buflist[i]; 155995584Sanholt buf_priv = buf->dev_private; 1560112015Sanholt if ( buf->pid == 0 || (buf->pending && 1561112015Sanholt buf_priv->age <= done_age) ) { 1562112015Sanholt dev_priv->stats.requested_bufs++; 156395584Sanholt buf->pending = 0; 156495584Sanholt return buf; 156595584Sanholt } 156695584Sanholt } 1567112015Sanholt start = 0; 156895584Sanholt } 156995584Sanholt 157095584Sanholt return NULL; 157195584Sanholt} 1572112015Sanholt#endif 157395584Sanholt 157495584Sanholtvoid radeon_freelist_reset( drm_device_t *dev ) 157595584Sanholt{ 157695584Sanholt drm_device_dma_t *dma = dev->dma; 157795584Sanholt drm_radeon_private_t *dev_priv = dev->dev_private; 157895584Sanholt int i; 157995584Sanholt 158095584Sanholt dev_priv->last_buf = 0; 158195584Sanholt for ( i = 0 ; i < dma->buf_count ; i++ ) { 158295584Sanholt drm_buf_t *buf = dma->buflist[i]; 158395584Sanholt drm_radeon_buf_priv_t *buf_priv = buf->dev_private; 158495584Sanholt buf_priv->age = 0; 158595584Sanholt } 158695584Sanholt} 158795584Sanholt 158895584Sanholt 158995584Sanholt/* ================================================================ 159095584Sanholt * CP command submission 159195584Sanholt */ 159295584Sanholt 159395584Sanholtint radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ) 159495584Sanholt{ 159595584Sanholt drm_radeon_ring_buffer_t *ring = &dev_priv->ring; 159695584Sanholt int i; 1597112015Sanholt u32 last_head = GET_RING_HEAD(ring); 159895584Sanholt 159995584Sanholt for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { 1600112015Sanholt u32 head = GET_RING_HEAD(ring); 1601112015Sanholt 1602112015Sanholt ring->space = (head - ring->tail) * sizeof(u32); 1603112015Sanholt if ( ring->space <= 0 ) 1604112015Sanholt ring->space += ring->size; 160595584Sanholt if ( ring->space > n ) 160695584Sanholt return 0; 1607112015Sanholt 1608112015Sanholt dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 1609112015Sanholt 1610112015Sanholt if (head != last_head) 1611112015Sanholt i = 0; 1612112015Sanholt last_head = head; 1613112015Sanholt 1614112015Sanholt DRM_UDELAY( 1 ); 161595584Sanholt } 161695584Sanholt 161795584Sanholt /* FIXME: This return value is ignored in the BEGIN_RING macro! */ 161895584Sanholt#if RADEON_FIFO_DEBUG 161995584Sanholt radeon_status( dev_priv ); 162095584Sanholt DRM_ERROR( "failed!\n" ); 162195584Sanholt#endif 1622112015Sanholt return DRM_ERR(EBUSY); 162395584Sanholt} 162495584Sanholt 162595584Sanholtstatic int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d ) 162695584Sanholt{ 162795584Sanholt int i; 162895584Sanholt drm_buf_t *buf; 162995584Sanholt 163095584Sanholt for ( i = d->granted_count ; i < d->request_count ; i++ ) { 163195584Sanholt buf = radeon_freelist_get( dev ); 1632112015Sanholt if ( !buf ) return DRM_ERR(EBUSY); /* NOTE: broken client */ 163395584Sanholt 1634112015Sanholt buf->pid = DRM_CURRENTPID; 163595584Sanholt 1636112015Sanholt if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, 163795584Sanholt sizeof(buf->idx) ) ) 1638112015Sanholt return DRM_ERR(EFAULT); 1639112015Sanholt if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, 164095584Sanholt sizeof(buf->total) ) ) 1641112015Sanholt return DRM_ERR(EFAULT); 164295584Sanholt 164395584Sanholt d->granted_count++; 164495584Sanholt } 164595584Sanholt return 0; 164695584Sanholt} 164795584Sanholt 1648112015Sanholtint radeon_cp_buffers( DRM_IOCTL_ARGS ) 164995584Sanholt{ 1650112015Sanholt DRM_DEVICE; 165195584Sanholt drm_device_dma_t *dma = dev->dma; 165295584Sanholt int ret = 0; 165395584Sanholt drm_dma_t d; 165495584Sanholt 165595584Sanholt LOCK_TEST_WITH_RETURN( dev ); 165695584Sanholt 1657112015Sanholt DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); 165895584Sanholt 165995584Sanholt /* Please don't send us buffers. 166095584Sanholt */ 166195584Sanholt if ( d.send_count != 0 ) { 166295584Sanholt DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", 1663112015Sanholt DRM_CURRENTPID, d.send_count ); 1664112015Sanholt return DRM_ERR(EINVAL); 166595584Sanholt } 166695584Sanholt 166795584Sanholt /* We'll send you buffers. 166895584Sanholt */ 166995584Sanholt if ( d.request_count < 0 || d.request_count > dma->buf_count ) { 167095584Sanholt DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", 1671112015Sanholt DRM_CURRENTPID, d.request_count, dma->buf_count ); 1672112015Sanholt return DRM_ERR(EINVAL); 167395584Sanholt } 167495584Sanholt 167595584Sanholt d.granted_count = 0; 167695584Sanholt 167795584Sanholt if ( d.request_count ) { 167895584Sanholt ret = radeon_cp_get_buffers( dev, &d ); 167995584Sanholt } 168095584Sanholt 1681112015Sanholt DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); 168295584Sanholt 168395584Sanholt return ret; 168495584Sanholt} 1685