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
/*
2
 * Copyright 2007, 2008  Luc Verhaegen 
3
 * Copyright 2007, 2008  Matthias Hopf 
4
 * Copyright 2007, 2008  Egbert Eich   
5
 * Copyright 2007, 2008  Advanced Micro Devices, Inc.
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 shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
21
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 */
25
 
26
#ifdef HAVE_CONFIG_H
27
#include "config.h"
28
#endif
29
 
30
#include "xf86.h"
31
 
32
#if HAVE_XF86_ANSIC_H
33
# include "xf86_ansic.h"
34
#else
35
# include 
36
#endif
37
 
38
#include "rhd.h"
39
#include "rhd_crtc.h"
40
#include "rhd_pll.h"
41
#include "rhd_lut.h"
42
#include "rhd_regs.h"
43
#include "rhd_modes.h"
44
#include "rhd_mc.h"
45
#if defined (ATOM_BIOS) && defined (ATOM_BIOS_PARSER)
46
# include "rhd_atombios.h"
47
 
48
# define D1_REG_OFFSET 0x0000
49
# define D2_REG_OFFSET 0x0800
50
 
51
struct rhdCrtcScalePrivate {
52
    void *RegList;
53
    CARD32 StoreViewportSize;
54
    CARD32 StoreViewportStart;
55
};
56
 
57
/*
58
 *
59
 */
60
static void
61
rhdAtomCrtcRestore(struct rhdCrtc *Crtc, void *Store)
62
{
63
    RHDPtr rhdPtr = RHDPTRI(Crtc);
64
    union AtomBiosArg data;
65
 
66
    RHDFUNC(rhdPtr);
67
 
68
    data.Address = Store;
69
    RHDAtomBiosFunc(Crtc->scrnIndex, rhdPtr->atomBIOS, ATOM_RESTORE_REGISTERS, &data);
70
}
71
 
72
/*
73
 *
74
 */
75
static void
76
rhdAtomScaleSet(struct rhdCrtc *Crtc, enum rhdCrtcScaleType Type,
77
	   DisplayModePtr Mode, DisplayModePtr ScaledToMode)
78
{
79
    RHDPtr rhdPtr = RHDPTRI(Crtc);
80
    struct rhdScalerOverscan Overscan;
81
    struct atomCrtcOverscan AtomOverscan;
82
    enum atomCrtc AtomCrtc = RHD_CRTC_1;
83
    enum atomScaler Scaler  = 0;
84
    enum atomScaleMode ScaleMode = 0;
85
    union AtomBiosArg data;
86
    CARD32 RegOff = 0;
87
 
88
    RHDDebug(Crtc->scrnIndex, "FUNCTION: %s: %s viewport: %ix%i\n", __func__, Crtc->Name,
89
	     Mode->CrtcHDisplay, Mode->CrtcVDisplay);
90
 
91
    /* D1Mode registers */
92
    if (Crtc->Id == RHD_CRTC_1)
93
	RegOff = D1_REG_OFFSET;
94
    else
95
	RegOff = D2_REG_OFFSET;
96
 
97
    RHDRegWrite(Crtc, RegOff + D1MODE_VIEWPORT_SIZE,
98
		Mode->CrtcVDisplay | (Mode->CrtcHDisplay << 16));
99
    RHDRegWrite(Crtc, RegOff + D1MODE_VIEWPORT_START, 0);
100
 
101
    Overscan = rhdCalculateOverscan(Mode, ScaledToMode, Type);
102
    Type = Overscan.Type;
103
 
104
    ASSERT(Crtc->ScalePriv);
105
    data.Address = &((Crtc->ScalePriv)->RegList);
106
    RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
107
 
108
    AtomOverscan.ovscnLeft = Overscan.OverscanLeft;
109
    AtomOverscan.ovscnRight = Overscan.OverscanRight;
110
    AtomOverscan.ovscnTop = Overscan.OverscanTop;
111
    AtomOverscan.ovscnBottom = Overscan.OverscanBottom;
112
 
113
    switch (Crtc->Id) {
114
	case  RHD_CRTC_1:
115
	    Scaler = atomScaler1;
116
	    AtomCrtc = atomCrtc1;
117
	    break;
118
	case RHD_CRTC_2:
119
	    Scaler = atomScaler2;
120
	    AtomCrtc = atomCrtc2;
121
	    break;
122
    }
123
 
124
    rhdAtomSetCRTCOverscan(rhdPtr->atomBIOS, AtomCrtc, &AtomOverscan);
125
 
126
    switch (Type) {
127
	case RHD_CRTC_SCALE_TYPE_NONE:
128
	    ScaleMode = atomScaleDisable;
129
	    break;
130
	case RHD_CRTC_SCALE_TYPE_CENTER:
131
	    ScaleMode = atomScaleCenter;
132
	    break;
133
	case RHD_CRTC_SCALE_TYPE_SCALE:
134
	case RHD_CRTC_SCALE_TYPE_SCALE_KEEP_ASPECT_RATIO: /* scaled to fullscreen */
135
	    ScaleMode = atomScaleExpand;
136
	    break;
137
    }
138
    rhdAtomSetScaler(rhdPtr->atomBIOS, Scaler, ScaleMode);
139
 
140
    data.Address = NULL;
141
    RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
142
 
143
    RHDMCTuneAccessForDisplay(rhdPtr, Crtc->Id, Mode,
144
			      ScaledToMode ? ScaledToMode : Mode);
145
}
146
 
147
/*
148
 *
149
 */
150
static void
151
rhdAtomScaleSave(struct rhdCrtc *Crtc)
152
{
153
    struct rhdCrtcScalePrivate* ScalePriv;
154
    CARD32 RegOff = 0;
155
 
156
    RHDFUNC(Crtc);
157
 
158
    if (!Crtc->ScalePriv) {
159
	if(!(ScalePriv = (struct rhdCrtcScalePrivate*)xnfcalloc(1, sizeof(struct rhdCrtcScalePrivate))))
160
	    return;
161
	Crtc->ScalePriv = ScalePriv;
162
    } else
163
	ScalePriv = Crtc->ScalePriv;
164
 
165
    if (Crtc->Id == RHD_CRTC_1)
166
	RegOff = D1_REG_OFFSET;
167
    else
168
	RegOff = D2_REG_OFFSET;
169
 
170
    ScalePriv->StoreViewportSize  = RHDRegRead(Crtc, RegOff + D1MODE_VIEWPORT_SIZE);
171
    ScalePriv->StoreViewportStart = RHDRegRead(Crtc, RegOff + D1MODE_VIEWPORT_START);
172
    ScalePriv->RegList = NULL;
173
}
174
 
175
/*
176
 *
177
 */
178
static void
179
rhdAtomCrtcScaleRestore(struct rhdCrtc *Crtc)
180
{
181
    struct rhdCrtcScalePrivate* ScalePriv;
182
    CARD32 RegOff = 0;
183
 
184
    RHDFUNC(Crtc);
185
 
186
    rhdAtomCrtcRestore(Crtc, &(((struct rhdCrtcScalePrivate*)Crtc->ScalePriv)->RegList));
187
 
188
    if (Crtc->Id == RHD_CRTC_1)
189
	RegOff = D1_REG_OFFSET;
190
    else
191
	RegOff = D2_REG_OFFSET;
192
 
193
    ScalePriv = (struct rhdCrtcScalePrivate*)Crtc->ScalePriv;
194
    RHDRegWrite(Crtc, RegOff + D1MODE_VIEWPORT_SIZE, ScalePriv->StoreViewportSize);
195
    RHDRegWrite(Crtc, RegOff + D1MODE_VIEWPORT_START, ScalePriv->StoreViewportStart);
196
}
197
 
198
/*
199
 *
200
 */
201
static void
202
rhdAtomCrtcScaleDestroy(struct rhdCrtc *Crtc)
203
{
204
    RHDFUNC(Crtc);
205
 
206
    if (Crtc->ScalePriv) {
207
	xfree(Crtc->ScalePriv->RegList);
208
	xfree(Crtc->ScalePriv);
209
	Crtc->ScalePriv = NULL;
210
    }
211
}
212
 
213
/*
214
 *
215
 */
216
struct rhdCrtcModePrivate {
217
    void *RegList;
218
    CARD32 StoreModeDataFormat;
219
};
220
 
221
static void
222
rhdAtomModeSet(struct rhdCrtc *Crtc, DisplayModePtr Mode)
223
{
224
    RHDPtr rhdPtr = RHDPTRI(Crtc);
225
    union AtomBiosArg data;
226
    CARD32 RegOff = 0;
227
 
228
    RHDFUNC(rhdPtr);
229
 
230
    ASSERT(Crtc->ModePriv);
231
    data.Address = &((Crtc->ModePriv)->RegList);
232
    RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
233
 
234
    if (!rhdAtomSetCRTCTimings(rhdPtr->atomBIOS,
235
			      Crtc->Id == RHD_CRTC_1 ? atomCrtc1 : atomCrtc2,
236
                  Mode, 32))
237
	xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "%s: failed to set mode.\n",__func__);
238
 
239
    /* set interlaced - AtomBIOS never sets the data format - never tested? */
240
    if (Crtc->Id == RHD_CRTC_1)
241
	RegOff = D1_REG_OFFSET;
242
    else
243
	RegOff = D2_REG_OFFSET;
244
 
245
    if (Mode->Flags & V_INTERLACE)
246
	RHDRegWrite(Crtc, RegOff + D1MODE_DATA_FORMAT, 0x1);
247
    else
248
	RHDRegWrite(Crtc, RegOff + D1MODE_DATA_FORMAT, 0x0);
249
 
250
    data.Address = NULL;
251
    RHDAtomBiosFunc(Crtc->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
252
}
253
 
254
/*
255
 *
256
 */
257
static Bool
258
rhdAtomCrtcPower(struct rhdCrtc *Crtc, int Power)
259
{
260
    RHDPtr rhdPtr = RHDPTRI(Crtc);
261
    enum atomCrtc AtomCrtc = atomCrtc1;
262
    union AtomBiosArg data;
263
 
264
    RHDFUNC(Crtc);
265
 
266
    switch (Crtc->Id) {
267
	case RHD_CRTC_1:
268
	    AtomCrtc = atomCrtc1;
269
	    break;
270
	case RHD_CRTC_2:
271
	    AtomCrtc = atomCrtc2;
272
	    break;
273
    }
274
    data.Address = &((Crtc->ModePriv)->RegList);
275
    RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
276
 
277
    /*
278
     * We call  rhdAtomEnableCrtcMemReq blindly as this table seemed to have existed in all
279
     * versions of AtomBIOS on the hardware we support
280
     */
281
    switch (Power) {
282
	case RHD_POWER_ON:
283
	    rhdAtomEnableCrtcMemReq(rhdPtr->atomBIOS, AtomCrtc, atomCrtcEnable);
284
	    rhdAtomEnableCrtc(rhdPtr->atomBIOS, AtomCrtc, atomCrtcEnable);
285
	    break;
286
	case RHD_POWER_RESET:
287
	case RHD_POWER_SHUTDOWN:
288
	default:
289
	    rhdAtomEnableCrtc(rhdPtr->atomBIOS, AtomCrtc, atomCrtcDisable);
290
	    rhdAtomEnableCrtcMemReq(rhdPtr->atomBIOS, AtomCrtc, atomCrtcDisable);
291
	    break;
292
    }
293
    data.Address = NULL;
294
    RHDAtomBiosFunc(Crtc->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
295
 
296
    /*
297
     * we always claim we succeeded here, after all, we know, AtomBIOS knows
298
     * how to do things, right?
299
     * Err, no, when we use AtomBIOS we should not have a clue how to find out.
300
     */
301
    return TRUE;
302
}
303
 
304
/*
305
 *
306
 */
307
static void
308
rhdAtomCrtcBlank(struct rhdCrtc *Crtc, Bool Blank)
309
{
310
    RHDPtr rhdPtr = RHDPTRI(Crtc);
311
    enum atomCrtc AtomCrtc = atomCrtc1;
312
    struct atomCrtcBlank Config;
313
    union AtomBiosArg data;
314
 
315
    RHDFUNC(Crtc);
316
 
317
    switch (Crtc->Id) {
318
	case RHD_CRTC_1:
319
	    AtomCrtc = atomCrtc1;
320
	    break;
321
	case RHD_CRTC_2:
322
	    AtomCrtc = atomCrtc2;
323
	    break;
324
    }
325
    if (Blank)
326
	Config.Action = atomBlankOn;
327
    else
328
	Config.Action = atomBlankOff;
329
 
330
    Config.r = Config.g = Config.b = 0;
331
 
332
    data.Address = &((Crtc->ModePriv)->RegList);
333
    RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
334
 
335
    rhdAtomBlankCRTC(rhdPtr->atomBIOS, AtomCrtc , &Config);
336
 
337
    data.Address = NULL;
338
    RHDAtomBiosFunc(Crtc->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
339
}
340
 
341
/*
342
 *
343
 */
344
static void
345
rhdAtomModeSave(struct rhdCrtc *Crtc)
346
{
347
    struct rhdCrtcModePrivate* ModePriv;
348
    CARD32 RegOff = 0;
349
 
350
    if (!Crtc->ModePriv) {
351
	if(!(ModePriv = (struct rhdCrtcModePrivate*)xnfcalloc(1, sizeof(struct rhdCrtcModePrivate))))
352
	    return;
353
	Crtc->ModePriv = ModePriv;
354
    } else
355
	ModePriv = Crtc->ModePriv;
356
 
357
    if (Crtc->Id == RHD_CRTC_1)
358
	RegOff = D1_REG_OFFSET;
359
    else
360
	RegOff = D2_REG_OFFSET;
361
 
362
    ModePriv->StoreModeDataFormat  = RHDRegRead(Crtc, RegOff + D1MODE_DATA_FORMAT);
363
    ModePriv->RegList = NULL;
364
}
365
 
366
/*
367
 *
368
 */
369
static void
370
rhdAtomModeRestore(struct rhdCrtc *Crtc)
371
{
372
    struct rhdCrtcModePrivate* ModePriv;
373
    CARD32 RegOff = 0;
374
 
375
    if (Crtc->Id == RHD_CRTC_1)
376
	RegOff = D1_REG_OFFSET;
377
    else
378
	RegOff = D2_REG_OFFSET;
379
 
380
    ModePriv = Crtc->ModePriv;
381
 
382
    rhdAtomCrtcRestore(Crtc, &ModePriv->RegList);
383
 
384
   RHDRegWrite(Crtc, RegOff + D1MODE_DATA_FORMAT, ModePriv->StoreModeDataFormat);
385
}
386
 
387
/*
388
 *
389
 */
390
static void
391
rhdAtomModeDestroy(struct rhdCrtc *Crtc)
392
{
393
    RHDFUNC(Crtc);
394
 
395
    if (Crtc->ModePriv) {
396
	xfree(Crtc->ModePriv->RegList);
397
	xfree(Crtc->ModePriv);
398
	Crtc->ModePriv = NULL;
399
    }
400
}
401
 
402
/*
403
 *
404
 */
405
void
406
RHDAtomCrtcsInit(RHDPtr rhdPtr)
407
{
408
    struct rhdCrtc *Crtc;
409
    int i;
410
 
411
    RHDFUNC(rhdPtr);
412
 
413
    if (rhdPtr->Crtc[0] == NULL || rhdPtr->Crtc[1] == NULL) {
414
	xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "%s: CRTCs not initialized\n",__func__);
415
	return;
416
    }
417
 
418
    for (i = 0; i < 2; i++) {
419
 
420
	Crtc = rhdPtr->Crtc[i];
421
 
422
	if (i == 0) {
423
	    Crtc->Name = "ATOM CRTC 1";
424
	    Crtc->Id = RHD_CRTC_1;
425
	} else {
426
	    Crtc->Name = "ATOM CRTC 2";
427
	    Crtc->Id = RHD_CRTC_2;
428
	}
429
 
430
	/* EnableGraphSurfaces is only a BIOS internal table. So use the hardcoded path.
431
	Crtc->FBValid = atomFBValid;
432
	Crtc->FBSet = atomFBSet;
433
	Crtc->FBSave = atomSave;
434
	Crtc->FBRestore = atomRestore;
435
	*/
436
 
437
	/* There is no separate function to set up the LUT thru AtomBIOS */
438
 
439
	/* Crtc->ScaleValid: From rhd_crtc.c */
440
	Crtc->ScaleSet = rhdAtomScaleSet;
441
	Crtc->ScaleSave = rhdAtomScaleSave;
442
	Crtc->ScaleRestore = rhdAtomCrtcScaleRestore;
443
	Crtc->ScaleDestroy = rhdAtomCrtcScaleDestroy;
444
 
445
	/* No such AtomBIOS table */
446
	/* Crtc->FrameSet = atomViewPortStart; */
447
 
448
	/* Crtc->ModeValid: From rhd_crtc.c */
449
	Crtc->ModeSet = rhdAtomModeSet;
450
	Crtc->ModeSave = rhdAtomModeSave;
451
	Crtc->ModeRestore = rhdAtomModeRestore;
452
	Crtc->ModeDestroy = rhdAtomModeDestroy;
453
 
454
	Crtc->Power = rhdAtomCrtcPower;
455
	Crtc->Blank = rhdAtomCrtcBlank;
456
    }
457
}
458
 
459
#endif /* ATOM_BIOS && ATOM_BIOS_PARSER */