Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1029 serge 1
#define RADEON_SCRATCH_REG0     0x15e0
2
#define RADEON_SCRATCH_REG1		0x15e4
3
#define RADEON_SCRATCH_REG2		0x15e8
4
#define RADEON_SCRATCH_REG3		0x15ec
5
#define RADEON_SCRATCH_REG4		0x15f0
6
#define RADEON_SCRATCH_REG5		0x15f4
7
#define RADEON_SCRATCH_UMSK		0x0770
8
#define RADEON_SCRATCH_ADDR		0x0774
9
 
10
#   define RS400_BUS_MASTER_DIS      (1 << 14)
11
//#   define RADEON_BUS_MASTER_DIS     (1 <<  6)
12
 
13
#define RADEON_ISYNC_CNTL       0x1724
14
#	define RADEON_ISYNC_ANY2D_IDLE3D	(1 << 0)
15
#	define RADEON_ISYNC_ANY3D_IDLE2D	(1 << 1)
16
#	define RADEON_ISYNC_TRIG2D_IDLE3D	(1 << 2)
17
#	define RADEON_ISYNC_TRIG3D_IDLE2D	(1 << 3)
18
#	define RADEON_ISYNC_WAIT_IDLEGUI	(1 << 4)
19
#	define RADEON_ISYNC_CPSCRATCH_IDLEGUI	(1 << 5)
20
 
21
 
22
void RADEONEngineFlush(RHDPtr info)
23
{
24
     int i;
25
 
26
     if (info->ChipFamily <= CHIP_FAMILY_RV280)
27
     {
28
        MASKREG(RADEON_RB3D_DSTCACHE_CTLSTAT,RADEON_RB3D_DC_FLUSH_ALL,
29
                                             ~RADEON_RB3D_DC_FLUSH_ALL);
30
        for (i = 0; i < RADEON_TIMEOUT; i++) {
31
           if (!(INREG(RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY))
32
            break;
33
        }
34
        if (i == RADEON_TIMEOUT) {
35
           dbgprintf("DC flush timeout: %x\n",
36
                     (u32_t)INREG(RADEON_RB3D_DSTCACHE_CTLSTAT));
37
        }
38
     }
39
     else
40
     {
41
//        MASKREG(R300_DSTCACHE_CTLSTAT,R300_RB2D_DC_FLUSH_ALL,
42
//                                      ~R300_RB2D_DC_FLUSH_ALL);
43
//        for (i = 0; i < RADEON_TIMEOUT; i++) {
44
//            if (!(INREG(R300_DSTCACHE_CTLSTAT) & R300_RB2D_DC_BUSY))
45
//            break;
46
//        }
47
//        if (i == RADEON_TIMEOUT) {
48
//           dbgprintf("DC flush timeout: %x\n",
49
//                     (u32_t)INREG(R300_DSTCACHE_CTLSTAT));
50
//        }
51
     }
52
}
53
 
54
 
55
static int radeon_do_wait_for_idle()
56
{
57
	int i, ret;
58
 
59
    ret = R5xxFIFOWaitLocal(64);
60
	if (ret)
61
		return ret;
62
 
63
    for (i = 0; i < RADEON_TIMEOUT; i++)
64
    {
65
        if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) {
66
            RADEONEngineFlush(&rhd);
67
			return 0;
68
		}
69
        usleep(1);
70
	}
71
    dbgprintf("wait idle failed status : 0x%08X 0x%08X\n",
72
               INREG(RADEON_RBBM_STATUS),
73
               INREG(R300_VAP_CNTL_STATUS));
74
 
75
    return 1;
76
}
77
 
78
 
79
 
80
/* ================================================================
81
 * CP control, initialization
82
 */
83
 
84
/* Load the microcode for the CP */
85
 
86
#include "radeon_microcode.h"
87
 
88
static void load_microcode(RHDPtr info)
89
{
90
	int i;
91
    const u32_t (*microcode)[2];
92
 
93
     OUTREG(RADEON_CP_ME_RAM_ADDR, 0);
94
 
95
     if ( (info->ChipFamily  == CHIP_FAMILY_LEGACY ) ||
96
          (info->ChipFamily  == CHIP_FAMILY_RADEON ) ||
97
          (info->ChipFamily  == CHIP_FAMILY_RV100  ) ||
98
          (info->ChipFamily  == CHIP_FAMILY_RV200  ) ||
99
          (info->ChipFamily  == CHIP_FAMILY_RS100  ) ||
100
          (info->ChipFamily  == CHIP_FAMILY_RS200  ))
101
     {
102
        microcode = R100_cp_microcode;
103
        dbgprintf("Loading R100 Microcode\n");
104
     }
105
     else if ((info->ChipFamily == CHIP_FAMILY_R200 ) ||
106
              (info->ChipFamily == CHIP_FAMILY_RV250) ||
107
              (info->ChipFamily == CHIP_FAMILY_RV280) ||
108
              (info->ChipFamily == CHIP_FAMILY_RS300))
109
     {
110
        microcode = R200_cp_microcode;
111
        dbgprintf("Loading R200 Microcode\n");
112
     }
113
     else if ((info->ChipFamily == CHIP_FAMILY_R300)  ||
114
              (info->ChipFamily == CHIP_FAMILY_R350)  ||
115
              (info->ChipFamily == CHIP_FAMILY_RV350) ||
116
              (info->ChipFamily == CHIP_FAMILY_RV380) ||
117
              (info->ChipFamily == CHIP_FAMILY_RS400) ||
118
              (info->ChipFamily == CHIP_FAMILY_RS480))
119
     {
120
        dbgprintf("Loading R300 Microcode\n");
121
        microcode = R300_cp_microcode;
122
     }
123
     else if ((info->ChipFamily == CHIP_FAMILY_R420)  ||
124
              (info->ChipFamily == CHIP_FAMILY_RV410))
125
     {
126
        dbgprintf("Loading R400 Microcode\n");
127
        microcode = R420_cp_microcode;
128
 
129
     }
130
     else if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
131
              (info->ChipFamily == CHIP_FAMILY_RS690) ||
132
              (info->ChipFamily == CHIP_FAMILY_RS740))
133
     {
134
        dbgprintf("Loading RS690/RS740 Microcode\n");
135
        microcode = RS690_cp_microcode;
136
     }
137
     else if ((info->ChipFamily == CHIP_FAMILY_RV515) ||
138
              (info->ChipFamily == CHIP_FAMILY_R520)  ||
139
              (info->ChipFamily == CHIP_FAMILY_RV530) ||
140
              (info->ChipFamily == CHIP_FAMILY_R580)  ||
141
              (info->ChipFamily == CHIP_FAMILY_RV560) ||
142
              (info->ChipFamily == CHIP_FAMILY_RV570))
143
     {
144
        dbgprintf("Loading R500 Microcode\n");
145
        microcode = R520_cp_microcode;
146
     }
147
 
148
     for (i = 0; i < 256; i++) {
149
       OUTREG(RADEON_CP_ME_RAM_DATAH, microcode[i][1]);
150
       OUTREG(RADEON_CP_ME_RAM_DATAL, microcode[i][0]);
151
     }
152
}
153
 
154
 
155
void init_ring_buffer(RHDPtr info)
156
{
157
     u32_t ring_base;
158
     u32_t tmp;
159
 
160
     info->ringBase = CreateRingBuffer( 64*1024, PG_SW);
161
 
162
     dbgprintf("create cp ring buffer %x\n", rhd.ringBase);
163
     ring_base = GetPgAddr(rhd.ringBase);
164
     dbgprintf("ring base %x\n", ring_base);
165
 
166
     OUTREG(RADEON_CP_RB_BASE, ring_base);
167
 
168
     info->ring_avail = 64*1024/4 ;
169
 
170
	/* Set the write pointer delay */
171
     OUTREG(RADEON_CP_RB_WPTR_DELAY, 0);
172
 
173
	/* Initialize the ring buffer's read and write pointers */
174
     rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR);
175
     rhd.host_rp =  rhd.ring_rp;
176
 
177
     OUTREG(RADEON_CP_RB_WPTR,rhd.ring_rp);
178
 
179
     tmp = (((u32_t)&rhd.host_rp) & 4095) + GetPgAddr((void*)&rhd.host_rp);
180
 
181
     OUTREG(RADEON_CP_RB_RPTR_ADDR, tmp); // ring buffer read pointer
182
 
183
	/* Set ring buffer size */
184
     OUTREG(RADEON_CP_RB_CNTL, (1<<27)|(0<<18)|(10<<8)|13);
185
 
186
	/* Initialize the scratch register pointer.  This will cause
187
	 * the scratch register values to be written out to memory
188
	 * whenever they are updated.
189
	 *
190
	 * We simply put this behind the ring read pointer, this works
191
	 * with PCI GART as well as (whatever kind of) AGP GART
192
	 */
193
 
194
     tmp = (((u32_t)&rhd.scratch0) & 4095) + GetPgAddr((void*)&rhd.scratch0);
195
     OUTREG(RADEON_SCRATCH_ADDR, tmp);
196
 
197
     OUTREG(RADEON_SCRATCH_UMSK, 0x0);
198
     //OUTREG(0x778, 1);
199
 
200
	/* Turn on bus mastering */
201
     if ( (info->ChipFamily == CHIP_FAMILY_RS400) ||
202
          (info->ChipFamily == CHIP_FAMILY_RS690) ||
203
          (info->ChipFamily == CHIP_FAMILY_RS740) )
204
     {
205
		/* rs400, rs690/rs740 */
206
        tmp = INREG(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS;
207
        OUTREG(RADEON_BUS_CNTL, tmp);
208
     }
209
     else if (!((info->ChipFamily == CHIP_FAMILY_RV380) ||
210
                (info->ChipFamily >= CHIP_FAMILY_R420)))
211
     {
212
		/* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */
213
        tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
214
        OUTREG(RADEON_BUS_CNTL, tmp);
215
	} /* PCIE cards appears to not need this */
216
 
217
    tmp = INREG(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
218
    OUTREG(RADEON_BUS_CNTL, tmp);
219
 
220
    radeon_do_wait_for_idle();
221
 
222
	/* Sync everything up */
223
    OUTREG(RADEON_ISYNC_CNTL,
224
          (RADEON_ISYNC_ANY2D_IDLE3D |
225
           RADEON_ISYNC_ANY3D_IDLE2D |
226
           RADEON_ISYNC_WAIT_IDLEGUI |
227
           RADEON_ISYNC_CPSCRATCH_IDLEGUI));
228
}
229
 
230
 
231
 
232
#define RADEON_WAIT_UNTIL_IDLE() do {                   \
233
    OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 1 ) );         \
234
	OUT_RING( (RADEON_WAIT_2D_IDLECLEAN |				\
235
		   RADEON_WAIT_3D_IDLECLEAN |				\
236
		   RADEON_WAIT_HOST_IDLECLEAN) );			\
237
} while (0)
238
 
239
#define R300_ZB_ZCACHE_CTLSTAT                  0x4f18
240
#   define RADEON_RB3D_ZC_FLUSH     (1 << 0)
241
#	define RADEON_RB3D_ZC_FREE		(1 << 2)
242
#	define RADEON_RB3D_ZC_FLUSH_ALL		0x5
243
#   define RADEON_RB3D_ZC_BUSY      (1 << 31)
244
#   define R300_ZC_FLUSH                (1 << 0)
245
#	define R300_ZC_FREE		        (1 << 1)
246
#   define R300_ZC_BUSY             (1 << 31)
247
#   define RADEON_RB3D_DC_FLUSH     (3 << 0)
248
#	define RADEON_RB3D_DC_FREE		(3 << 2)
249
#	define RADEON_RB3D_DC_FLUSH_ALL		0xf
250
#   define RADEON_RB3D_DC_BUSY      (1 << 31)
251
#   define R300_RB3D_DC_FLUSH       (2 << 0)
252
#	define R300_RB3D_DC_FREE		(2 << 2)
253
#
254
#define RADEON_PURGE_CACHE() do {                                    \
255
    if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) {                      \
256
            OUT_RING(CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 1));  \
257
            OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE);    \
258
    } else {                                                         \
259
            OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 1));     \
260
            OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE );       \
261
        }                                                            \
262
} while (0)
263
 
264
#define RADEON_FLUSH_ZCACHE() do {                                   \
265
    if ( rhd.ChipFamily <= CHIP_FAMILY_RV280) {     \
266
            OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 1 ) ); \
267
            OUT_RING( RADEON_RB3D_ZC_FLUSH );                        \
268
    } else {                                                         \
269
            OUT_RING( CP_PACKET0( R300_ZB_ZCACHE_CTLSTAT, 1 ) );     \
270
            OUT_RING( R300_ZC_FLUSH );                               \
271
        }                                                            \
272
} while (0)
273
#define RADEON_PURGE_ZCACHE() do {                  \
274
    if (rhd.ChipFamily <= CHIP_FAMILY_RV280) { \
275
            OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 1));    \
276
	        OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE);	\
277
	} else {                                                        \
278
            OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 1));    \
279
	        OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE);			\
280
        }                                                               \
281
} while (0)
282
 
283
static int radeon_cp_start(RHDPtr info)
284
{
285
     u32_t *ring, write;
286
     u32_t ifl;
287
     radeon_do_wait_for_idle(64);
288
 
289
     OUTREG(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM);
290
 
291
     ifl = safe_cli();
292
 
293
     BEGIN_RING(8);
294
	/* isync can only be written through cp on r5xx write it here */
295
       OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 1));
296
       OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D |
297
                RADEON_ISYNC_ANY3D_IDLE2D |
298
                RADEON_ISYNC_WAIT_IDLEGUI |
299
                RADEON_ISYNC_CPSCRATCH_IDLEGUI);
300
       RADEON_PURGE_CACHE();
301
       RADEON_PURGE_ZCACHE();
302
       RADEON_WAIT_UNTIL_IDLE();
303
       ADVANCE_RING();
304
    COMMIT_RING();
305
 
306
    safe_sti(ifl);
307
 
308
    radeon_do_wait_for_idle();
309
};
310
 
311
 
312
Bool init_cp(RHDPtr info)
313
{
314
     load_microcode(&rhd);
315
 
316
     init_ring_buffer(&rhd);
317
 
318
     radeon_engine_reset(&rhd);
319
 
320
     rhd.ring_rp = rhd.ring_wp = INREG(RADEON_CP_RB_RPTR);
321
     OUTREG(RADEON_CP_RB_WPTR, rhd.ring_rp);
322
 
323
     radeon_cp_start(&rhd);
324
 
325
    return TRUE;
326
};
327
 
328