OSDN Git Service

nouveau: Try to get nv35 pgraph switching working. Doesn't quite yet.
[android-x86/external-libdrm.git] / shared-core / nv30_graph.c
1 /*
2  * Based on nv40_graph.c
3  *  Someday this will all go away...
4  */
5 #include "drmP.h"
6 #include "drm.h"
7 #include "nouveau_drv.h"
8 #include "nouveau_drm.h"
9
10 /*
11  *  TODO: In the dump start seems to be 7654b0 while end is 76ac28.
12  *  This is obviously not the correct size. 
13  */
14 #define NV30_GRCTX_SIZE (23840)
15
16 /*TODO: deciper what each offset in the context represents. The below
17  *      contexts are taken from dumps just after the 3D object is
18  *      created.
19  */
20 static void nv30_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
21 {
22         drm_nouveau_private_t *dev_priv = dev->dev_private;
23         int i;
24         
25         INSTANCE_WR(ctx, 0x28/4,  0x10000000);
26         INSTANCE_WR(ctx, 0x40c/4, 0x00000101);
27         INSTANCE_WR(ctx, 0x420/4, 0x00000111);
28         INSTANCE_WR(ctx, 0x424/4, 0x00000060);
29         INSTANCE_WR(ctx, 0x440/4, 0x00000080);
30         INSTANCE_WR(ctx, 0x444/4, 0xffff0000);
31         INSTANCE_WR(ctx, 0x448/4, 0x00000001);
32         INSTANCE_WR(ctx, 0x45c/4, 0x44400000);
33         INSTANCE_WR(ctx, 0x448/4, 0xffff0000);
34         INSTANCE_WR(ctx, 0x4dc/4, 0xfff00000);
35         INSTANCE_WR(ctx, 0x4e0/4, 0xfff00000);
36         INSTANCE_WR(ctx, 0x4e8/4, 0x00011100);
37
38         for (i = 0x504; i <= 0x540; i += 4)
39                 INSTANCE_WR(ctx, i/4, 0x7ff00000);
40
41         INSTANCE_WR(ctx, 0x54c/4, 0x4b7fffff);
42         INSTANCE_WR(ctx, 0x588/4, 0x00000080);
43         INSTANCE_WR(ctx, 0x58c/4, 0x30201000);
44         INSTANCE_WR(ctx, 0x590/4, 0x70605040);
45         INSTANCE_WR(ctx, 0x594/4, 0xb8a89888);
46         INSTANCE_WR(ctx, 0x598/4, 0xf8e8d8c8);
47         INSTANCE_WR(ctx, 0x5ac/4, 0xb0000000);
48
49         for (i = 0x604; i <= 0x640; i += 4)
50                 INSTANCE_WR(ctx, i/4, 0x00010588);
51
52         for (i = 0x644; i <= 0x680; i += 4)
53                 INSTANCE_WR(ctx, i/4, 0x00030303);
54
55         for (i = 0x6c4; i <= 0x700; i += 4)
56                 INSTANCE_WR(ctx, i/4, 0x0008aae4);
57
58         for (i = 0x704; i <= 0x740; i += 4)
59                 INSTANCE_WR(ctx, i/4, 0x1012000);
60
61         for (i = 0x744; i <= 0x780; i += 4)
62                 INSTANCE_WR(ctx, i/4, 0x0080008);
63
64         INSTANCE_WR(ctx, 0x860/4, 0x00040000);
65         INSTANCE_WR(ctx, 0x864/4, 0x00010000);
66         INSTANCE_WR(ctx, 0x868/4, 0x00040000);
67         INSTANCE_WR(ctx, 0x86c/4, 0x00040000);
68         INSTANCE_WR(ctx, 0x870/4, 0x00040000);
69         INSTANCE_WR(ctx, 0x874/4, 0x00040000);
70
71         for (i = 0x00; i <= 0x1170; i += 0x10)
72         {
73                 INSTANCE_WR(ctx, (0x1f24 + i)/4, 0x000c001b);
74                 INSTANCE_WR(ctx, (0x1f20 + i)/4, 0x0436086c);
75                 INSTANCE_WR(ctx, (0x1f1c + i)/4, 0x10700ff9);
76         }
77
78         INSTANCE_WR(ctx, 0x30bc/4, 0x0000ffff);
79         INSTANCE_WR(ctx, 0x30c0/4, 0x0000ffff);
80         INSTANCE_WR(ctx, 0x30c4/4, 0x0000ffff);
81         INSTANCE_WR(ctx, 0x30c8/4, 0x0000ffff);
82
83         INSTANCE_WR(ctx, 0x380c/4, 0x3f800000);
84         INSTANCE_WR(ctx, 0x3450/4, 0x3f800000);
85         INSTANCE_WR(ctx, 0x3820/4, 0x3f800000);
86         INSTANCE_WR(ctx, 0x3854/4, 0x3f800000);
87         INSTANCE_WR(ctx, 0x3850/4, 0x3f000000);
88         INSTANCE_WR(ctx, 0x384c/4, 0x40000000);
89         INSTANCE_WR(ctx, 0x3868/4, 0xbf800000);
90         INSTANCE_WR(ctx, 0x3860/4, 0x3f800000);
91         INSTANCE_WR(ctx, 0x386c/4, 0x40000000);
92         INSTANCE_WR(ctx, 0x3870/4, 0xbf800000);
93
94         for (i = 0x4e0; i <= 0x4e1c; i += 4)
95                 INSTANCE_WR(ctx, i/4, 0x001c527d);
96         INSTANCE_WR(ctx, 0x4e40, 0x001c527c);
97
98         INSTANCE_WR(ctx, 0x5680/4, 0x000a0000);
99         INSTANCE_WR(ctx, 0x87c/4, 0x10000000);
100         INSTANCE_WR(ctx, 0x28/4, 0x10000011);
101 }
102
103
104 int nv30_graph_context_create(drm_device_t *dev, int channel)
105 {
106         drm_nouveau_private_t *dev_priv =
107                 (drm_nouveau_private_t *)dev->dev_private;
108         struct nouveau_fifo *chan = &dev_priv->fifos[channel];
109         void (*ctx_init)(drm_device_t *, struct mem_block *);
110         unsigned int ctx_size;
111         int i, chipset;
112
113         chipset = (NV_READ(NV_PMC_BOOT_0) & 0x0ff00000) >> 20;
114         switch (chipset) {
115         default:
116                 ctx_size = NV30_GRCTX_SIZE;
117                 ctx_init = nv30_graph_context_init;
118                 break;
119         }
120
121         /* Alloc and clear RAMIN to store the context */
122         chan->ramin_grctx = nouveau_instmem_alloc(dev, ctx_size, 4);
123         if (!chan->ramin_grctx)
124                 return DRM_ERR(ENOMEM);
125         for (i=0; i<ctx_size; i+=4)
126                 INSTANCE_WR(chan->ramin_grctx, i/4, 0x00000000);
127
128         /* Initialise default context values */
129         ctx_init(dev, chan->ramin_grctx);
130         
131         INSTANCE_WR(chan->ramin_grctx, 10, channel << 24); /* CTX_USER */
132         INSTANCE_WR(dev_priv->ctx_table, channel, nouveau_chip_instance_get(dev, chan->ramin_grctx));
133
134         return 0;
135 }
136
137 int nv30_graph_init(drm_device_t *dev)
138 {
139         drm_nouveau_private_t *dev_priv =
140                 (drm_nouveau_private_t *)dev->dev_private;
141         int i, chipset;
142
143         chipset = (NV_READ(NV_PMC_BOOT_0) & 0x0ff00000) >> 20;
144         DRM_DEBUG("chipset (from PMC_BOOT_0): NV%02X\n", chipset);
145
146         /* Create Context Pointer Table */
147         dev_priv->ctx_table_size = 32 * 4;
148         dev_priv->ctx_table = nouveau_instmem_alloc(dev, dev_priv->ctx_table_size, 4);
149         if (!dev_priv->ctx_table)
150                 return DRM_ERR(ENOMEM);
151
152         for (i=0; i< dev_priv->ctx_table_size; i+=4)
153                 INSTANCE_WR(dev_priv->ctx_table, i/4, 0x00000000);
154
155         NV_WRITE(NV_PGRAPH_CHANNEL_CTX_TABLE, nouveau_chip_instance_get(dev, dev_priv->ctx_table));
156
157         return 0;
158 }
159