g80_dma.c revision fc5a983d
1fc5a983dSmrg/*
2fc5a983dSmrg * Copyright (c) 2007 NVIDIA, Corporation
3fc5a983dSmrg *
4fc5a983dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
5fc5a983dSmrg * copy of this software and associated documentation files (the
6fc5a983dSmrg * "Software"), to deal in the Software without restriction, including
7fc5a983dSmrg * without limitation the rights to use, copy, modify, merge, publish,
8fc5a983dSmrg * distribute, sublicense, and/or sell copies of the Software, and to
9fc5a983dSmrg * permit persons to whom the Software is furnished to do so, subject to
10fc5a983dSmrg * the following conditions:
11fc5a983dSmrg *
12fc5a983dSmrg * The above copyright notice and this permission notice shall be included
13fc5a983dSmrg * in all copies or substantial portions of the Software.
14fc5a983dSmrg *
15fc5a983dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16fc5a983dSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17fc5a983dSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18fc5a983dSmrg * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19fc5a983dSmrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20fc5a983dSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21fc5a983dSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22fc5a983dSmrg */
23fc5a983dSmrg
24fc5a983dSmrg#ifdef HAVE_CONFIG_H
25fc5a983dSmrg#include "config.h"
26fc5a983dSmrg#endif
27fc5a983dSmrg
28fc5a983dSmrg#include "g80_type.h"
29fc5a983dSmrg#include "g80_dma.h"
30fc5a983dSmrg
31fc5a983dSmrgvoid G80DmaKickoff(G80Ptr pNv)
32fc5a983dSmrg{
33fc5a983dSmrg    if(pNv->dmaCurrent != pNv->dmaPut) {
34fc5a983dSmrg        pNv->dmaPut = pNv->dmaCurrent;
35fc5a983dSmrg        pNv->reg[0x00c02040/4] = pNv->dmaPut << 2;
36fc5a983dSmrg    }
37fc5a983dSmrg}
38fc5a983dSmrg
39fc5a983dSmrgvoid G80DmaWait(G80Ptr pNv, int size)
40fc5a983dSmrg{
41fc5a983dSmrg    CARD32 dmaGet;
42fc5a983dSmrg
43fc5a983dSmrg    size++;
44fc5a983dSmrg
45fc5a983dSmrg    while(pNv->dmaFree < size) {
46fc5a983dSmrg        dmaGet = pNv->reg[0x00c02044/4] >> 2;
47fc5a983dSmrg
48fc5a983dSmrg        if(pNv->dmaPut >= dmaGet) {
49fc5a983dSmrg            pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent;
50fc5a983dSmrg            if(pNv->dmaFree < size) {
51fc5a983dSmrg                G80DmaNext(pNv, 0x20000000);
52fc5a983dSmrg                if(dmaGet <= SKIPS) {
53fc5a983dSmrg                    if(pNv->dmaPut <= SKIPS) /* corner case - will be idle */
54fc5a983dSmrg                        pNv->reg[0x00c02040/4] = (SKIPS + 1) << 2;
55fc5a983dSmrg                    do { dmaGet = pNv->reg[0x00c02044/4] >> 2; }
56fc5a983dSmrg                    while(dmaGet <= SKIPS);
57fc5a983dSmrg                }
58fc5a983dSmrg                pNv->reg[0x00c02040/4] = SKIPS << 2;
59fc5a983dSmrg                pNv->dmaCurrent = pNv->dmaPut = SKIPS;
60fc5a983dSmrg                pNv->dmaFree = dmaGet - (SKIPS + 1);
61fc5a983dSmrg            }
62fc5a983dSmrg        } else
63fc5a983dSmrg            pNv->dmaFree = dmaGet - pNv->dmaCurrent - 1;
64fc5a983dSmrg    }
65fc5a983dSmrg}
66