The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/drm/radeon_cp.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 7ba38a481728b81264a8329cb707f836


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.