~gma500/+junk/emgd152-natty

« back to all changes in this revision

Viewing changes to emgd-dkms-1.5.15.3082/emgd/state/reg/tnc/reg_tnc.c

  • Committer: Luca Forina
  • Date: 2011-02-06 15:11:54 UTC
  • Revision ID: luca.forina@gmail.com-20110206151154-9dzn5ugxjub9qenb
Upload Emgd 1.5.2 for Natty (override Maverick)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- pse-c -*-
 
2
 *-----------------------------------------------------------------------------
 
3
 * Filename: reg_tnc.c
 
4
 * $Revision: 1.12 $
 
5
 *-----------------------------------------------------------------------------
 
6
 * Copyright © 2002-2010, Intel Corporation.
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify it
 
9
 * under the terms and conditions of the GNU General Public License,
 
10
 * version 2, as published by the Free Software Foundation.
 
11
 *
 
12
 * This program is distributed in the hope it will be useful, but WITHOUT
 
13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
14
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 
15
 * more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License along with
 
18
 * this program; if not, write to the Free Software Foundation, Inc.,
 
19
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 
20
 *
 
21
 *-----------------------------------------------------------------------------
 
22
 * Description:
 
23
 *  This is the implementation file for the register module's main API's called
 
24
 *  by external devices.
 
25
 *-----------------------------------------------------------------------------
 
26
 */
 
27
 
 
28
#define MODULE_NAME hal.state
 
29
 
 
30
#include <io.h>
 
31
#include <memory.h>
 
32
#include <sched.h>
 
33
 
 
34
#include <igd_init.h>
 
35
#include <igd_mode.h>
 
36
#include <igd_pwr.h>
 
37
#include <igd_errno.h>
 
38
 
 
39
#include <context.h>
 
40
#include <utils.h>
 
41
#include <dsp.h>
 
42
#include <mode.h>
 
43
#include <utils.h>
 
44
#include <vga.h>
 
45
#include <intelpci.h>
 
46
 
 
47
#include <tnc/regs.h>
 
48
#include <plb/context.h>
 
49
 
 
50
#include "../cmn/reg_dispatch.h"
 
51
 
 
52
/*!
 
53
 * @addtogroup state_group
 
54
 * @{
 
55
 */
 
56
 
 
57
#define PLANE_LATCH_COUNT  4
 
58
 
 
59
#define RING_BUFFER        0
 
60
#define MMIO_MISC          1
 
61
 
 
62
static reg_buffer_t *reg_alloc_tnc(igd_context_t *context,
 
63
        unsigned long flags, void *_platform_context);
 
64
static void reg_free_tnc(igd_context_t *context, reg_buffer_t *reg_buffer,
 
65
        void *_platform_context);
 
66
static int reg_save_tnc(igd_context_t *context, reg_buffer_t *reg_buffer,
 
67
        void *_platform_context);
 
68
static int reg_restore_tnc(igd_context_t *context, reg_buffer_t *reg_buffer,
 
69
        void *_platform_context);
 
70
 
 
71
/* GR registers being saved */
 
72
static unsigned char gr_regs_tnc[] = {
 
73
        0x00, 0x01, 0x02, 0x03, 0x04,
 
74
        0x05, 0x06, 0x07, 0x08,
 
75
        0x10, 0x11,
 
76
        0x18,
 
77
        0xff
 
78
};
 
79
#define GR_REG_COUNT sizeof(gr_regs_tnc)
 
80
 
 
81
/* SR registers being saved */
 
82
static unsigned char sr_regs_tnc[] = {
 
83
        0x00, 0x01, 0x02, 0x03, 0x04,
 
84
        0x07,
 
85
        0xff
 
86
};
 
87
#define SR_REG_COUNT sizeof(sr_regs_tnc)
 
88
 
 
89
/* AR registers being saved */
 
90
static unsigned char ar_regs_tnc[] = {
 
91
        0x00, 0x01, 0x02, 0x03, 0x04,
 
92
        0x05, 0x06, 0x07, 0x08, 0x09,
 
93
        0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
 
94
        0x0f, 0x10, 0x11, 0x12, 0x13,
 
95
        0x14,
 
96
        0xff,
 
97
};
 
98
#define AR_REG_COUNT sizeof(ar_regs_tnc)
 
99
 
 
100
/* CR registers being saved */
 
101
static unsigned char cr_regs_tnc[] = {
 
102
        0x00, 0x01, 0x02, 0x03, 0x04,
 
103
        0x05, 0x06, 0x07, 0x08, 0x09,
 
104
        0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
 
105
        0x0f, 0x10, 0x11, 0x12, 0x13,
 
106
        0x14, 0x15, 0x16, 0x17, 0x18,
 
107
        0xff
 
108
};
 
109
#define CR_REG_COUNT sizeof(cr_regs_tnc)
 
110
 
 
111
 
 
112
/* MMIO states register to be saved */
 
113
static unsigned long mmio_regs_tnc[] = {
 
114
#if  MMIO_MISC
 
115
        /* Fence Registers */
 
116
        FENCE0, FENCE1, FENCE2, FENCE3, FENCE4, FENCE5, FENCE6, FENCE7,  // Fence
 
117
        FENCE8, FENCE9, FENCE10, FENCE11, FENCE12, FENCE13, FENCE14, FENCE15,
 
118
 
 
119
        /* GTT Control */
 
120
        PGTBL_CTL,
 
121
#endif
 
122
 
 
123
        /* Memory Arbitration */
 
124
        FW_BLC_SELF, MI_ARB_STATE, G_DEBUG,
 
125
 
 
126
        /* Program Clocks */
 
127
        VGA0_DIVISOR, VGA1_DIVISOR, VGA_PD,
 
128
 
 
129
        FPA0, FPA1, FPB0, FPB1, P2D_CG_DIS, 
 
130
 
 
131
        DPLLACNTR, DPLLBCNTR,
 
132
 
 
133
        /* Enable Ports */
 
134
        /* SDVO Port Enable */
 
135
        SDVOBCNTR,
 
136
 
 
137
        /* Panel Power */
 
138
        LVDS_PNL_PWR_CTL, PP_ON_DELAYS, PP_OFF_DELAYS, PP_DIVISOR,
 
139
 
 
140
        /* Panel Fitting */
 
141
        PFIT_CONTROL, PFIT_PGM_RATIOS,
 
142
 
 
143
        /* Backlight Control */
 
144
        BLC_PWM_CTL2, BLC_PWM_CTL, BLM_HIST_CTL,
 
145
 
 
146
        /* LVDS Port Enable */
 
147
        LVDSCNTR,
 
148
 
 
149
        /* Program Pipe A */
 
150
        PIPEA_STAT, PIPEA_DISP_ARB_CTRL, HTOTAL_A, HBLANK_A, HSYNC_A, VTOTAL_A,
 
151
        VBLANK_A, VSYNC_A, PIPEASRC, BCLRPAT_A,
 
152
 
 
153
        /* Program Pipe B */
 
154
        PIPEB_STAT, HTOTAL_B, HBLANK_B, HSYNC_B, VTOTAL_B,
 
155
        VBLANK_B, VSYNC_B, PIPEBSRC, BCLRPAT_B,
 
156
 
 
157
 
 
158
        /* Enable Pipes */
 
159
        PIPEA_CONF, PIPEB_CONF,
 
160
 
 
161
        /* Plane A */
 
162
        DSPASTRIDE, DSPAKEYVAL, DSPAKEYMASK,
 
163
 
 
164
        /* Plane B */
 
165
        DSPBSTRIDE, DSPBKEYVAL, DSPBKEYMASK,
 
166
 
 
167
        /* Plane C */
 
168
        DSPCSTRIDE, DSPCPOS, DSPCSIZE, DSPCKEYMASK,
 
169
        DSPCKEYMINVAL, DSPCKEYMAXVAL, DCLRC0, DCLRC1, DPYC_GAMC5,
 
170
        DPYC_GAMC4, DPYC_GAMC3, DPYC_GAMC2, DPYC_GAMC1, DPYC_GAMC0,
 
171
 
 
172
        /* Enable Plane C */
 
173
        DSPCCNTR, DSPCLINOFF,
 
174
 
 
175
        /* Enable Plane B */
 
176
        DSPBCNTR, DSPBLINOFF,
 
177
 
 
178
        /* Enable Plane A */
 
179
        DSPACNTR, DSPALINOFF,
 
180
 
 
181
        /* Enable VGA Plane */
 
182
        VGACNTRL,
 
183
 
 
184
        /* Software Flags A */
 
185
        SWF00, SWF01, SWF02, SWF03, SWF04, SWF05, SWF06, SWF07,
 
186
        SWF08, SWF09, SWF0A, SWF0B, SWF0C, SWF0D, SWF0E, SWF0F,
 
187
 
 
188
        /* Software Flags B */
 
189
        SWF10, SWF11, SWF12, SWF13, SWF14, SWF15, SWF16, SWF17,
 
190
        SWF18, SWF19, SWF1A, SWF1B, SWF1C, SWF1D, SWF1E, SWF1F,
 
191
 
 
192
        /* Cursor A */
 
193
        CURSOR_A_BASE, CURSOR_A_POS, CURSOR_A_PAL0, CURSOR_A_PAL1,
 
194
        CURSOR_A_PAL2, CURSOR_A_PAL3,
 
195
 
 
196
        /* Cursor B */
 
197
        CURSOR_B_BASE, CURSOR_B_POS, CURSOR_B_PAL0, CURSOR_B_PAL1,
 
198
        CURSOR_B_PAL2, CURSOR_B_PAL3,
 
199
 
 
200
        /* Interrupt and hardware status */
 
201
        HWS_PGA, HWSTAM, SCPD0, IER, IMR, EIR, EMR,
 
202
 
 
203
        0xffffffff
 
204
};
 
205
#define MMIO_REG_COUNT(x) (sizeof(mmio_regs_tnc)/4)
 
206
 
 
207
/* MMIO states register to be saved */
 
208
static unsigned long mmio_regs_sdvo_tnc[] = {
 
209
 
 
210
        /* Program Clocks */
 
211
        VGA0_DIVISOR, 
 
212
 
 
213
        FPB0, P2D_CG_DIS,
 
214
 
 
215
        DPLLBCNTR,
 
216
 
 
217
        /* Enable Ports */
 
218
        /* SDVO Port Enable */
 
219
        SDVOBCNTR,
 
220
 
 
221
        /* Program Pipe B */
 
222
        PIPEB_STAT, HTOTAL_B, HBLANK_B, HSYNC_B, VTOTAL_B,
 
223
        VBLANK_B, VSYNC_B, PIPEBSRC, BCLRPAT_B, PROG_STALL, 
 
224
 
 
225
        /* CDVO */
 
226
        /* CDVO_CTRL,*/
 
227
        CDVO_SLEW_RATE, CDVO_STRENGTH, CDVO_RCOMP_UPDATE,
 
228
 
 
229
        /* TNC_SDVORAM */
 
230
        DPLL_ANACORE_CTRL, DPLL_MISC, DPLL_MONITOR, DPLL_MONITOR2,
 
231
        DPLL_TEST_COMPARATOR, 
 
232
 
 
233
        /* Enable Pipes */
 
234
        PIPEB_CONF,
 
235
 
 
236
        /* Interrupt and hardware status */
 
237
        IER, IMR, 
 
238
 
 
239
        0xffffffff
 
240
};
 
241
#define MMIO_REG_SDVO_COUNT(x) (sizeof(mmio_regs_sdvo_tnc)/4)
 
242
 
 
243
typedef struct _reg_platform_context_tnc {
 
244
        unsigned long *mmio_regs;
 
245
        unsigned long *mmio_regs_sdvo;
 
246
        unsigned char *ar;
 
247
        unsigned char *cr;
 
248
        unsigned char *sr;
 
249
        unsigned char *gr;
 
250
        unsigned long pipes;
 
251
} reg_platform_context_tnc_t;
 
252
 
 
253
typedef struct _vga_state_tnc  {
 
254
        unsigned char fcr; // Feature Control register
 
255
        unsigned char msr; // Miscellaneous Output register
 
256
        unsigned char sr_index; // Sequencer index register
 
257
        unsigned char cr_index; // CRT Controller index register
 
258
        unsigned char ar_index; // Attribute Controller index register
 
259
        unsigned char gr_index; // Graphics Controller index register
 
260
        unsigned char ar[AR_REG_COUNT];  // Attribute Contr regs (AR00-AR14)
 
261
        unsigned char sr[SR_REG_COUNT];  // Sequencer registers (SR01-SR04)
 
262
        unsigned char cr[CR_REG_COUNT];  // CRT Controller regs (CR00-CR18)
 
263
        unsigned char gr[GR_REG_COUNT];  // Graphics Contr regs
 
264
        unsigned char plane_latches[PLANE_LATCH_COUNT];
 
265
} vga_state_tnc_t;
 
266
 
 
267
#define DAC_DATA_COUNT  256  /* 256 sets of (R, G, B) data */
 
268
typedef struct _dac_state_tnc {
 
269
        unsigned long palette_a[DAC_DATA_COUNT]; /* Pipe A palette data */
 
270
        unsigned long palette_b[DAC_DATA_COUNT]; /* Pipe B palette data */
 
271
        unsigned char mode;  // DAC state register
 
272
        unsigned char index; // DAC index register
 
273
        unsigned char mask;  // 0x3C6, Palette Pixel Mask Register
 
274
} dac_state_tnc_t;
 
275
 
 
276
/* Structure to store the 3D registers during power management
 
277
 * These are 3D specific registers, but named as D3D because
 
278
 * variabl names cannot start with a number*/
 
279
typedef struct _d3d_state_tnc {
 
280
        unsigned long cin_ctl;
 
281
        unsigned long bin_scene;
 
282
        unsigned long bmp_buffer;
 
283
        unsigned long bmp_get;
 
284
        unsigned long bmp_put;
 
285
} d3d_state_tnc_t;
 
286
 
 
287
typedef struct _reg_buffer_tnc {
 
288
        unsigned long *mmio_state;
 
289
        unsigned long *mmio_state_sdvo;
 
290
        //unsigned long mem_mode; /* Reg 0x20CC */
 
291
        //unsigned long instpm;   /* Reg 0x20C0 */
 
292
        unsigned long gtt[128*1024]; /* PLB is 128 */
 
293
        unsigned long sgx_phyaddr;
 
294
        void *vga_mem;
 
295
        vga_state_tnc_t vga_state;
 
296
        dac_state_tnc_t dac_state;
 
297
        d3d_state_tnc_t d3d_state;
 
298
        void *rb_state;
 
299
        unsigned long clk_gating_ctl;
 
300
} reg_buffer_tnc_t;
 
301
 
 
302
static reg_platform_context_tnc_t reg_platform_context_tnc = {
 
303
        mmio_regs_tnc,
 
304
        mmio_regs_sdvo_tnc,
 
305
        ar_regs_tnc,
 
306
        cr_regs_tnc,
 
307
        sr_regs_tnc,
 
308
        gr_regs_tnc,
 
309
        2
 
310
};
 
311
 
 
312
reg_dispatch_t reg_dispatch_tnc = {
 
313
        reg_alloc_tnc,
 
314
        reg_free_tnc,
 
315
        reg_save_tnc,
 
316
        reg_restore_tnc,
 
317
        &reg_platform_context_tnc
 
318
};
 
319
 
 
320
/******************************************************************************
 
321
 *  Local Functions
 
322
 *****************************************************************************/
 
323
static int reg_save_gtt_tnc(igd_context_t *context, unsigned char *mmio,
 
324
        reg_buffer_tnc_t *reg_args);
 
325
static int reg_restore_gtt_tnc(igd_context_t *context,
 
326
        reg_buffer_tnc_t *reg_args);
 
327
 
 
328
/*!
 
329
 * This procedure simply waits for the next vertical syncing (vertical retrace)
 
330
 * period. If the display is already in a vertical syncing period, this
 
331
 * procedure exits unlike "util_Wait_VSync_Start()" function that waits for
 
332
 * the beginning of the next vertical sync period.
 
333
 *
 
334
 * Note: A timeout is included to prevent an endless loop.
 
335
 *
 
336
 * @param context
 
337
 *
 
338
 * @return FALSE if timed out
 
339
 * @return TRUE otherwise
 
340
 */
 
341
int reg_wait_vsync_tnc(igd_context_t *context)
 
342
{
 
343
        unsigned long i = 0;
 
344
        unsigned char *mmio;
 
345
 
 
346
        mmio = context->device_context.virt_mmadr;
 
347
 
 
348
        if ((EMGD_READ32(mmio + VP00) & BIT31)) {
 
349
                return 1;
 
350
        }
 
351
 
 
352
        while ((i++ < 0x100000) &&  /* Check for timeout */
 
353
                ((EMGD_READ8(mmio + STATUS_REG_01) & BIT3) == 0x00)) {
 
354
                ;
 
355
        }
 
356
 
 
357
        if (i >= 0x100000) {
 
358
                return 0;
 
359
        }
 
360
        return 1;
 
361
}
 
362
 
 
363
/*!
 
364
 * Saves the current VGA register state of the video chipset into the
 
365
 * given state buffer.
 
366
 *
 
367
 * This function first saves the 4 plane latches, and then it saves
 
368
 * the SR, GR, AR, CR registers.
 
369
 *
 
370
 * @param context the current device context
 
371
 * @param vga_buffer this is where the VGA register state is saved
 
372
 * @param ar_regs AR registers to save
 
373
 * @param cr_regs CR registers to save
 
374
 * @param sr_regs SR registers to save
 
375
 * @param gr_regs GR registers to save
 
376
 *
 
377
 * @return 0
 
378
 */
 
379
static int reg_save_vga_tnc(
 
380
        igd_context_t *context,
 
381
        vga_state_tnc_t *vga_buffer,
 
382
        unsigned char *ar_regs,
 
383
        unsigned char *cr_regs,
 
384
        unsigned char *sr_regs,
 
385
        unsigned char *gr_regs)
 
386
{
 
387
        unsigned char *mmio;
 
388
        int i;
 
389
 
 
390
        mmio = context->device_context.virt_mmadr;
 
391
 
 
392
        /* First, save a few registers that will be modified to read the latches.
 
393
         * We need to use GR04 to go through all the latches.  Therefore, we must
 
394
         * first save GR04 before continuing.  However, GR04 will only behave the
 
395
         * way we want it to if we are not in Odd/Even mode and not in Chain 4
 
396
         * mode.  Therefore, we have to make sure GR05 (GFX mode reg),
 
397
         * and SR04 (Mem Mode reg) are set properly.
 
398
         * According to B-spec, we are not supposed to program GR06 via MMIO.
 
399
         */
 
400
        READ_VGA(mmio, GR_PORT, GR04, vga_buffer->gr[0x04]);
 
401
        READ_VGA(mmio, SR_PORT, SR04, vga_buffer->sr[0x04]); /* Memory Mode */
 
402
        READ_VGA(mmio, GR_PORT, GR05, vga_buffer->gr[0x05]); /* GFX Mode Reg */
 
403
        READ_VGA(mmio, GR_PORT, GR06, vga_buffer->gr[0x06]); /* Misc Reg */
 
404
 
 
405
        WRITE_VGA(mmio, SR_PORT, SR04, 0x06);
 
406
        WRITE_VGA(mmio, GR_PORT, GR05, 0x00);
 
407
        WRITE_VGA(mmio, GR_PORT, GR06, 0x05);
 
408
 
 
409
        /* Save Memory Latch Data latches */
 
410
        for (i=0; i<PLANE_LATCH_COUNT; i++) {
 
411
                WRITE_VGA(mmio, GR_PORT, GR04, (unsigned char)i);
 
412
                READ_VGA(mmio, CR_PORT, CR22, vga_buffer->plane_latches[i]);
 
413
        }
 
414
 
 
415
        /* Restore the modified regs */
 
416
        WRITE_VGA(mmio, GR_PORT, GR06, vga_buffer->gr[0x06]);
 
417
        WRITE_VGA(mmio, GR_PORT, GR05, vga_buffer->gr[0x05]);
 
418
        WRITE_VGA(mmio, GR_PORT, GR04, vga_buffer->gr[0x04]);
 
419
        WRITE_VGA(mmio, SR_PORT, SR04, vga_buffer->sr[0x04]);
 
420
 
 
421
 
 
422
        /* Save Feature Controller register. */
 
423
        vga_buffer->fcr = EMGD_READ8(mmio + FEATURE_CONT_REG_READ);
 
424
 
 
425
        /* Save Miscellaneous Output Register. */
 
426
        vga_buffer->msr = EMGD_READ8(mmio + MSR_READ_PORT);
 
427
 
 
428
        /* Save index registers. */
 
429
        vga_buffer->sr_index = EMGD_READ8(mmio + SR_PORT);
 
430
        vga_buffer->cr_index = EMGD_READ8(mmio + CR_PORT);
 
431
        vga_buffer->gr_index = EMGD_READ8(mmio + GR_PORT);
 
432
 
 
433
#if 0
 
434
        /*
 
435
         * Save the AR index register and last write status. Not sure that
 
436
         * this is really necessary so skip it for now.
 
437
         */
 
438
        READ_VGA(mmio, CR_PORT, CR24, isARData);  // Next write to AR index reg
 
439
        isARData &= 0x80;
 
440
 
 
441
        // Save AR index and last write status
 
442
        vga_buffer->ar_index = EMGD_READ8(mmio + AR_PORT) | isARData;
 
443
#endif
 
444
 
 
445
        /* Save CRT Controller registers. */
 
446
        for (i=0; cr_regs[i] != 0xff; i++) {
 
447
                READ_VGA(mmio, CR_PORT, cr_regs[i], vga_buffer->cr[i]);
 
448
        }
 
449
 
 
450
        /* Save Attribute Controller registers. */
 
451
        for (i=0; ar_regs[i] != 0xff; i++) {
 
452
                reg_wait_vsync_tnc(context);
 
453
                READ_AR(mmio, (unsigned char)i, vga_buffer->ar[i]);
 
454
        }
 
455
 
 
456
        /* Save Graphics Controller registers. */
 
457
        for (i=0; gr_regs[i] != 0xff; i++) {
 
458
                READ_VGA(mmio, GR_PORT, gr_regs[i], vga_buffer->gr[i]);
 
459
        }
 
460
 
 
461
        /* Save Sequencer registers. */
 
462
        for (i=0; sr_regs[i] != 0xff; i++) {
 
463
                READ_VGA(mmio, SR_PORT, sr_regs[i], vga_buffer->sr[i]);
 
464
        }
 
465
 
 
466
        return 0;
 
467
}
 
468
 
 
469
/*!
 
470
 * Restore the VGA Register state from the specifed state buffer.
 
471
 *
 
472
 * @param context the current device context
 
473
 * @param vga_buffer this is where the VGA register state is saved
 
474
 * @param ar_regs AR registers to save
 
475
 * @param cr_regs CR registers to save
 
476
 * @param sr_regs SR registers to save
 
477
 * @param gr_regs GR registers to save
 
478
 *
 
479
 * @return 0
 
480
 */
 
481
static int reg_restore_vga_tnc(
 
482
        igd_context_t *context,
 
483
        vga_state_tnc_t *vga_buffer,
 
484
        unsigned char *ar_regs,
 
485
        unsigned char *cr_regs,
 
486
        unsigned char *sr_regs,
 
487
        unsigned char *gr_regs)
 
488
{
 
489
        unsigned long i;
 
490
        unsigned char *mmio;
 
491
        unsigned long bit_mask;
 
492
        mmio = context->device_context.virt_mmadr;
 
493
 
 
494
        /* Restore the plane latches.
 
495
         *
 
496
         * BP: I don't understand what this block is doing and it doesn't
 
497
         * seem necessary. Should check this against the spec and figure
 
498
         * out what it really does.
 
499
         */
 
500
 
 
501
        /* Memory Mode Register */
 
502
        WRITE_VGA(mmio, SR_PORT, SR04, 0x06);
 
503
        /* GR05, Graphics Mode Register */
 
504
        WRITE_VGA(mmio, GR_PORT, GR05, 0x00);
 
505
        /* GR06, Micsellaneous Register */
 
506
        WRITE_VGA(mmio, GR_PORT, GR06, 0x05);
 
507
        /* GR08, Bit Mask Register */
 
508
        WRITE_VGA(mmio, GR_PORT, GR08, 0xFF);
 
509
 
 
510
        for (i=0, bit_mask=1; i<PLANE_LATCH_COUNT; i++, bit_mask<<= 1)  {
 
511
                /* Set plane select register */
 
512
                WRITE_VGA(mmio, GR_PORT, GR04, i);
 
513
                /* Plane/Map mask register */
 
514
                WRITE_VGA(mmio, SR_PORT, SR02, bit_mask);
 
515
        }
 
516
 
 
517
        for (i=0, bit_mask=1; i<PLANE_LATCH_COUNT; i++, bit_mask<<= 1)  {
 
518
                /* Plane/Map mask register again?? */
 
519
                WRITE_VGA(mmio, SR_PORT, SR02, bit_mask);
 
520
        }
 
521
 
 
522
        /* Restore standard VGA registers.
 
523
         * 2) Sequence registers
 
524
         * 1) MSR register
 
525
         * 3) CRTC registers
 
526
         * 4) Graphics registers
 
527
         * 5) Attribute registers
 
528
         * 6) VGA Feature register
 
529
         * 7) Index restisters
 
530
         */
 
531
 
 
532
 
 
533
        WRITE_VGA(mmio, SR_PORT, SR00, 01); /* Do sync reset */
 
534
 
 
535
        for (i=0; sr_regs[i] != 0xff; i++) {
 
536
                 WRITE_VGA(mmio, SR_PORT, sr_regs[i], vga_buffer->sr[i]);
 
537
        }
 
538
 
 
539
 
 
540
        EMGD_WRITE8(vga_buffer->msr, mmio + MSR_PORT);
 
541
        WRITE_VGA(mmio, SR_PORT, SR00, 0x03); /* Set to normal operation */
 
542
 
 
543
        /* Unlock CRTC */
 
544
        WRITE_VGA(mmio, CR_PORT, CR11, vga_buffer->cr[0x11] & 0x7F);
 
545
        for (i=0; cr_regs[i] != 0xff; i++) {
 
546
                 WRITE_VGA(mmio, CR_PORT, cr_regs[i], vga_buffer->cr[i]);
 
547
        }
 
548
 
 
549
        for (i=0; gr_regs[i] != 0xff; i++) {
 
550
                 WRITE_VGA(mmio, GR_PORT, gr_regs[i], vga_buffer->gr[i]);
 
551
        }
 
552
 
 
553
        for (i=0; ar_regs[i] != 0xff; i++) {
 
554
                 WRITE_AR(mmio, ar_regs[i], vga_buffer->ar[i]);
 
555
        }
 
556
 
 
557
        EMGD_WRITE8(vga_buffer->fcr, mmio + FEATURE_CONT_REG);
 
558
 
 
559
        /* Restore index registers. Is this necessary?  */
 
560
        EMGD_WRITE8(vga_buffer->sr_index, mmio + SR_PORT);
 
561
        EMGD_WRITE8(vga_buffer->cr_index, mmio + CR_PORT);
 
562
        EMGD_WRITE8(vga_buffer->gr_index, mmio + GR_PORT);
 
563
 
 
564
        /* Lock CRTC */
 
565
        WRITE_VGA(mmio, CR_PORT, CR11, vga_buffer->cr[0x11] | 0x80);
 
566
 
 
567
        return 0;
 
568
}
 
569
 
 
570
/*!
 
571
 * Saves the DAC registers and lookup table.
 
572
 *
 
573
 * @param context
 
574
 * @param dac_state
 
575
 * @param platform_context
 
576
 *
 
577
 * @return 0
 
578
 */
 
579
static int reg_save_dac_tnc(
 
580
        igd_context_t *context,
 
581
        dac_state_tnc_t *dac_state,
 
582
        reg_platform_context_tnc_t *platform_context)
 
583
{
 
584
        unsigned char *mmio;
 
585
        int     i;
 
586
 
 
587
        mmio = context->device_context.virt_mmadr;
 
588
 
 
589
        /* Save DACMASK register */
 
590
        dac_state->mask = EMGD_READ8(mmio + DAC_PEL_MASK);
 
591
 
 
592
        /* Save DAC State register */
 
593
        dac_state->mode = EMGD_READ8(mmio + DAC_STATE);
 
594
 
 
595
        /* Save DAC Index register */
 
596
        dac_state->index = EMGD_READ8(mmio + DAC_WRITE_INDEX);
 
597
 
 
598
        /*
 
599
         * Save DAC data
 
600
         * Start from first DAC location
 
601
         */
 
602
        EMGD_WRITE8(0, mmio + DAC_WRITE_INDEX);
 
603
 
 
604
        /* Save Pipe A Palette */
 
605
        /* Or if Pipe A is used for VGA */
 
606
        if (((EMGD_READ32(mmio + PIPEA_CONF) & PIPE_ENABLE) &&
 
607
                (EMGD_READ32(mmio + PIPEASRC))) ||
 
608
                ((!(EMGD_READ32(mmio + 0x71400) & 0x80000000)) &&
 
609
                (!(EMGD_READ32(mmio + 0x71400) & 0x20000000)))) {
 
610
                for (i=0; i<DAC_DATA_COUNT; i++)  {
 
611
                        dac_state->palette_a[i] = EMGD_READ32(mmio + i*4 + DPALETTE_A);
 
612
                }
 
613
        }
 
614
 
 
615
        if (platform_context->pipes == 2) {
 
616
                /* If Pipe B is enabled, save Pipe B Palette */
 
617
                /* Or if Pipe B is used for VGA */
 
618
                if (((EMGD_READ32(mmio + PIPEB_CONF) & PIPE_ENABLE) &&
 
619
                        (EMGD_READ32(mmio + PIPEBSRC)))  ||
 
620
                        ((! (EMGD_READ32(mmio + 0x71400) & 0x80000000)) &&
 
621
                        ((EMGD_READ32(mmio + 0x71400) & 0x20000000)))) {
 
622
 
 
623
                        for (i=0; i<DAC_DATA_COUNT; i++)  {
 
624
                                dac_state->palette_b[i] = EMGD_READ32(mmio + i*4 + DPALETTE_B);
 
625
                        }
 
626
                }
 
627
        }
 
628
 
 
629
        return 0;
 
630
}
 
631
 
 
632
/*!
 
633
 * Restore previously saved DAC palette from the specifed state buffer.
 
634
 *
 
635
 * @param context
 
636
 * @param dac_state
 
637
 * @param platform_context
 
638
 *
 
639
 * @return 0
 
640
 */
 
641
static int reg_restore_dac_tnc(
 
642
        igd_context_t *context,
 
643
        dac_state_tnc_t *dac_state,
 
644
        reg_platform_context_tnc_t *platform_context)
 
645
{
 
646
        int i;
 
647
        unsigned char *mmio;
 
648
        unsigned char temp;
 
649
 
 
650
        mmio = context->device_context.virt_mmadr;
 
651
 
 
652
        /* If Pipe A is enabled, restore Palette */
 
653
        /* Or if Pipe A is used for VGA */
 
654
        if (((EMGD_READ32(mmio + PIPEA_CONF) & PIPE_ENABLE) &&
 
655
                (EMGD_READ32(mmio + PIPEASRC))) ||
 
656
                ((! (EMGD_READ32(mmio + 0x71400) & 0x80000000)) &&
 
657
                (! (EMGD_READ32(mmio + 0x71400) & 0x20000000)))) {
 
658
 
 
659
                /*
 
660
                 * Restore DAC data
 
661
                 * Start from first DAC location
 
662
                 */
 
663
                EMGD_WRITE8(0, mmio + DAC_WRITE_INDEX);
 
664
 
 
665
                /* Restore Pipe A Palette */
 
666
                for (i=0; i<DAC_DATA_COUNT; i++)  {
 
667
                        EMGD_WRITE32(dac_state->palette_a[i], mmio + i*4 + DPALETTE_A);
 
668
                }
 
669
        }
 
670
 
 
671
        /* If this is a single pipe device. */
 
672
        if (platform_context->pipes == 2) {
 
673
                /* If Pipe B is enabled, restore Palette */
 
674
                /* Or if Pipe B is used for VGA */
 
675
                if (((EMGD_READ32(mmio + PIPEB_CONF) & PIPE_ENABLE) &&
 
676
                        (EMGD_READ32(mmio + PIPEBSRC)))  ||
 
677
                        ((! (EMGD_READ32(mmio + 0x71400) & 0x80000000)) &&
 
678
                        ((EMGD_READ32(mmio + 0x71400) & 0x20000000)))) {
 
679
 
 
680
                        for (i=0; i<DAC_DATA_COUNT; i++)  {
 
681
                                EMGD_WRITE32(dac_state->palette_b[i], mmio + i*4 + DPALETTE_B);
 
682
                        }
 
683
                }
 
684
        }
 
685
 
 
686
        /* Restore DACMASK register */
 
687
        EMGD_WRITE8(dac_state->mask, mmio + DAC_PEL_MASK);
 
688
 
 
689
        /* Restore DAC Index register */
 
690
        if (dac_state->mode & 1) {  /* Last write was to "write index register" */
 
691
                EMGD_WRITE8(dac_state->index, mmio + DAC_WRITE_INDEX);
 
692
        } else {  /* Last index write was to "read index register" */
 
693
                EMGD_WRITE8(dac_state->index - 1, mmio + DAC_READ_INDEX);
 
694
 
 
695
                /* Dummy read to set DACSTATE register and to increment read index to
 
696
                 * last saved.
 
697
                 */
 
698
                temp = EMGD_READ8(mmio + DAC_DATA_REG);
 
699
        }
 
700
 
 
701
        return 0;
 
702
}
 
703
 
 
704
/*!
 
705
 * Initializes memory to store register values
 
706
 *
 
707
 * @param context pointer to igd_context
 
708
 * @param flags indicate which register type to save
 
709
 * @param _platform_context
 
710
 *
 
711
 * @return pointer to structure which will eventually be saved data defining
 
712
 *      register state
 
713
 * @return NULL on failure
 
714
 */
 
715
static reg_buffer_t *reg_alloc_tnc(igd_context_t *context,
 
716
        unsigned long flags,
 
717
        void *_platform_context)
 
718
{
 
719
        reg_buffer_tnc_t* reg_args;
 
720
        reg_buffer_t *reg_buffer;
 
721
 
 
722
        EMGD_DEBUG("Entry - reg_alloc");
 
723
 
 
724
        reg_buffer = (reg_buffer_t*)OS_ALLOC(sizeof(reg_buffer_t));
 
725
        if (reg_buffer == NULL) {
 
726
                return NULL;
 
727
        }
 
728
 
 
729
        reg_args = (reg_buffer_tnc_t*)OS_ALLOC(sizeof(reg_buffer_tnc_t));
 
730
        if (reg_args == NULL) {
 
731
                OS_FREE(reg_buffer);
 
732
                return NULL;
 
733
        }
 
734
        reg_buffer->mode_buffer = NULL;
 
735
        reg_buffer->platform_buffer = reg_args;
 
736
 
 
737
        OS_MEMSET(reg_args, 0, sizeof(reg_buffer_tnc_t));
 
738
        reg_buffer->flags = flags;
 
739
 
 
740
        reg_args->mmio_state = (void *)OS_ALLOC(sizeof(mmio_regs_tnc));
 
741
        reg_args->mmio_state_sdvo = (void *)OS_ALLOC(sizeof(mmio_regs_sdvo_tnc));
 
742
 
 
743
        if (!reg_args->mmio_state) {
 
744
                EMGD_DEBUG("Failed Allocating mmio memory");
 
745
                /* free the "parent" memory*/
 
746
                OS_FREE(reg_args);
 
747
                return NULL;
 
748
        }
 
749
 
 
750
        if (!reg_args->mmio_state_sdvo) {
 
751
                EMGD_DEBUG("Failed Allocating sdvo mmio memory");
 
752
                /*Free other dependaant memory*/
 
753
                OS_FREE(reg_args->mmio_state);
 
754
                OS_FREE(reg_args);
 
755
                return NULL;
 
756
        }
 
757
 
 
758
        return reg_buffer;
 
759
}
 
760
 
 
761
/*!
 
762
 * This function calculates the size of memory to store data
 
763
 *
 
764
 * @param context void pointer to main igd context
 
765
 * @param reg_buffer pointer to register structure returned from a reg_alloc
 
766
 * @param _platform_context
 
767
 *
 
768
 * @return 0
 
769
 */
 
770
static void reg_free_tnc(igd_context_t *context,
 
771
        reg_buffer_t *reg_buffer,
 
772
        void *_platform_context)
 
773
{
 
774
        reg_buffer_tnc_t* reg_args;
 
775
 
 
776
        EMGD_DEBUG("Entry - reg_free");
 
777
 
 
778
        if (reg_buffer) {
 
779
                reg_args = (reg_buffer_tnc_t*)reg_buffer->platform_buffer;
 
780
 
 
781
                if (reg_args) {
 
782
                        if (NULL != reg_args->mmio_state) {
 
783
                                OS_FREE(reg_args->mmio_state);
 
784
                        }
 
785
 
 
786
                        if (NULL != reg_args->mmio_state_sdvo) {
 
787
                                OS_FREE(reg_args->mmio_state_sdvo);
 
788
                        }
 
789
 
 
790
                        if (NULL != reg_args->vga_mem) {
 
791
                                OS_FREE(reg_args->vga_mem);
 
792
                        }
 
793
 
 
794
                        if (NULL != reg_args->rb_state) {
 
795
                                OS_FREE(reg_args->rb_state);
 
796
                        }
 
797
                        OS_FREE(reg_args);
 
798
                }
 
799
                OS_FREE(reg_buffer);
 
800
        }
 
801
 
 
802
        return;
 
803
}
 
804
 
 
805
/*!
 
806
 * This functions save the regs
 
807
 *
 
808
 * @param context void pointer to main igd context
 
809
 * @param reg_buffer pointer to register structure returned from a reg_alloc
 
810
 * @param _platform_context
 
811
 *
 
812
 * @return 0 on success
 
813
 * @return -1 on failure
 
814
 */
 
815
static int reg_save_tnc(igd_context_t *context,
 
816
        reg_buffer_t *reg_buffer,
 
817
        void *_platform_context)
 
818
{
 
819
        reg_buffer_tnc_t           *reg_args;
 
820
        unsigned long              *buffer, *buffer_sdvo;
 
821
        reg_platform_context_tnc_t *platform_context =
 
822
                (reg_platform_context_tnc_t *)_platform_context;
 
823
        int                        i;
 
824
        unsigned char              *mmio, *mmio_sdvo;
 
825
 
 
826
        EMGD_TRACE_ENTER;
 
827
 
 
828
        if (reg_buffer == NULL) {
 
829
                return 0;
 
830
        }
 
831
 
 
832
        /* Before save need to idle the ring buffer */
 
833
        context->dispatch.idle((igd_driver_h)context);
 
834
 
 
835
        reg_args = (reg_buffer_tnc_t *)reg_buffer->platform_buffer;
 
836
        if (reg_args == NULL) {
 
837
                return 0;
 
838
        }
 
839
 
 
840
        mmio = context->device_context.virt_mmadr;
 
841
        mmio_sdvo = context->device_context.virt_mmadr_sdvo;
 
842
 
 
843
 
 
844
        /* Save vga registers */
 
845
        if (reg_buffer->flags & IGD_REG_SAVE_VGA) {
 
846
                EMGD_DEBUG("Saving VGA registers");
 
847
                reg_save_vga_tnc(context, &reg_args->vga_state,
 
848
                        platform_context->ar, platform_context->cr, platform_context->sr,
 
849
                        platform_context->gr);
 
850
        }
 
851
 
 
852
        /* Save VGA memory */
 
853
#if 0
 
854
        if (reg_buffer->flags & IGD_REG_SAVE_VGA_MEM) {
 
855
                EMGD_DEBUG("Saving VGA memory");
 
856
                if (!reg_args->vga_mem) {
 
857
                        reg_args->vga_mem = (void *)OS_ALLOC_LARGE(64 * 1024);
 
858
                        if (reg_args->vga_mem != NULL) {
 
859
                                OS_MEMCPY(reg_args->vga_mem,
 
860
                            (void *)context->device_context.virt_fb_adr, 64*1024);
 
861
                        } else {
 
862
                                EMGD_ERROR("Unable to allocate memory for vga memory");
 
863
                        }
 
864
                } else {
 
865
                        OS_MEMCPY(reg_args->vga_mem,
 
866
                    (void *)context->device_context.virt_fb_adr, 64*1024);
 
867
                }
 
868
        }
 
869
#endif
 
870
 
 
871
        /* Save mmio registers */
 
872
        if (reg_buffer->flags & IGD_REG_SAVE_MMIO) {
 
873
                EMGD_DEBUG("Saving MMIO registers");
 
874
                buffer = reg_args->mmio_state;
 
875
                for (i=0; platform_context->mmio_regs[i] != 0xffffffff; i++) {
 
876
                        *buffer++ = EMGD_READ32(mmio + platform_context->mmio_regs[i]);
 
877
                }
 
878
 
 
879
                buffer_sdvo = reg_args->mmio_state_sdvo;
 
880
                for (i=0; platform_context->mmio_regs_sdvo[i] != 0xffffffff; i++) {
 
881
                        *buffer_sdvo++ = EMGD_READ32(mmio_sdvo + platform_context->mmio_regs_sdvo[i]);
 
882
                }
 
883
 
 
884
                        reg_save_gtt_tnc(context, mmio, reg_args);
 
885
        }
 
886
 
 
887
        /* Save DAC registers */
 
888
        if (reg_buffer->flags & IGD_REG_SAVE_DAC) {
 
889
                EMGD_DEBUG("Saving DAC registers");
 
890
                reg_save_dac_tnc(context, &reg_args->dac_state, platform_context);
 
891
        }
 
892
 
 
893
        /* Save Mode state */
 
894
        if(reg_buffer->flags & IGD_REG_SAVE_MODE) {
 
895
                EMGD_DEBUG("Saving mode state");
 
896
                /* At driver initialization though mode_save is requested, mode isn't
 
897
                 * initialized. So skip the mode_save if dispatch function isn't
 
898
                 * available. In this case, mode_save() will be done as part of
 
899
                 * mode_init(). */
 
900
                if (context->mod_dispatch.mode_save && !reg_buffer->mode_buffer) {
 
901
                        context->mod_dispatch.mode_save(context,
 
902
                                &reg_buffer->mode_buffer,
 
903
                                &reg_buffer->flags);
 
904
                } else {
 
905
                        EMGD_DEBUG("mode_save() is skipped as mode_init() isn't done.");
 
906
                }
 
907
        }
 
908
 
 
909
        /* Save the SGX clock gating settings */
 
910
        reg_args->clk_gating_ctl = EMGD_READ32(mmio + PSB_CR_CLKGATECTL);
 
911
 
 
912
        return 0;
 
913
} /* reg_save */
 
914
 
 
915
/*!
 
916
 * This function restores the regs states
 
917
 *
 
918
 * @param context void pointer to main igd context
 
919
 * @param reg_buffer pointer to register structure returned from a reg_alloc
 
920
 * @param _platform_context
 
921
 *
 
922
 * @return 0 on success
 
923
 * @return -1 on failure
 
924
 */
 
925
int reg_restore_tnc(igd_context_t *context,
 
926
        reg_buffer_t *reg_buffer,
 
927
        void *_platform_context)
 
928
{
 
929
        reg_buffer_tnc_t* reg_args;
 
930
        reg_platform_context_tnc_t *platform_context =
 
931
                (reg_platform_context_tnc_t *)_platform_context;
 
932
        unsigned char *mmio, *mmio_sdvo;
 
933
        unsigned long *buffer, *buffer_sdvo;
 
934
        int i;
 
935
 
 
936
        EMGD_DEBUG("Entry - reg_restore");
 
937
 
 
938
        if (reg_buffer == NULL) {
 
939
                return 0;
 
940
        }
 
941
 
 
942
        reg_args = (reg_buffer_tnc_t *)reg_buffer->platform_buffer;
 
943
        if (reg_args == NULL) {
 
944
                return 0;
 
945
        }
 
946
 
 
947
        EMGD_DEBUG(" flags = 0x%lx", reg_buffer->flags);
 
948
 
 
949
        mmio = context->device_context.virt_mmadr;
 
950
        mmio_sdvo = context->device_context.virt_mmadr_sdvo;
 
951
 
 
952
        /* Restore Mode state */
 
953
        if (reg_buffer->flags & IGD_REG_SAVE_MODE) {
 
954
                if (reg_buffer->mode_buffer) {
 
955
                        context->mod_dispatch.mode_restore(context,
 
956
                                &reg_buffer->mode_buffer,
 
957
                                &reg_buffer->flags);
 
958
                } else {
 
959
                        EMGD_DEBUG("mode_restore() already happened in mode_shutdown().");
 
960
                }
 
961
        }
 
962
 
 
963
        /* Restore MMIO registers */
 
964
        if (reg_buffer->flags & IGD_REG_SAVE_MMIO) {
 
965
                EMGD_DEBUG("Restoring MMIO registers");
 
966
                buffer = reg_args->mmio_state;
 
967
                for (i=0; platform_context->mmio_regs[i] != 0xffffffff; i++) {
 
968
                        if (platform_context->mmio_regs[i] == MI_ARB_STATE) {
 
969
                                EMGD_DEBUG("Handle special masked register case");
 
970
                                EMGD_WRITE32(0x04100000 | *buffer++, mmio +
 
971
                                        platform_context->mmio_regs[i]);
 
972
                        } else if (platform_context->mmio_regs[i] == DPLLACNTR ||
 
973
                                platform_context->mmio_regs[i] == DPLLBCNTR) {
 
974
 
 
975
                                        EMGD_DEBUG("Handle special DPLL settling");
 
976
                                        EMGD_WRITE32(*buffer++,
 
977
                                                mmio + platform_context->mmio_regs[i]);
 
978
                                        OS_SLEEP(150);
 
979
                        } else {
 
980
                                EMGD_WRITE32(*buffer++, mmio + platform_context->mmio_regs[i]);
 
981
                        }
 
982
                }
 
983
//              reg_restore_gtt_tnc(context, reg_args);
 
984
 
 
985
                buffer_sdvo = reg_args->mmio_state_sdvo;
 
986
                for (i=0; platform_context->mmio_regs_sdvo[i] != 0xffffffff; i++) {
 
987
                        if (platform_context->mmio_regs_sdvo[i] == MI_ARB_STATE) {
 
988
                                EMGD_DEBUG("Handle special masked register case");
 
989
                                EMGD_WRITE32(0x04100000 | *buffer_sdvo++, mmio_sdvo +
 
990
                                        platform_context->mmio_regs_sdvo[i]);
 
991
                        } else if (platform_context->mmio_regs_sdvo[i] == DPLLACNTR ||
 
992
                                platform_context->mmio_regs_sdvo[i] == DPLLBCNTR) {
 
993
 
 
994
                                        EMGD_DEBUG("Handle special DPLL settling");
 
995
                                        EMGD_WRITE32(*buffer_sdvo++,
 
996
                                                mmio_sdvo + platform_context->mmio_regs_sdvo[i]);
 
997
                                        OS_SLEEP(150);
 
998
                        } else {
 
999
                                EMGD_WRITE32(*buffer_sdvo++, mmio_sdvo + platform_context->mmio_regs_sdvo[i]);
 
1000
                        }
 
1001
                }
 
1002
                reg_restore_gtt_tnc(context, reg_args);
 
1003
        }
 
1004
 
 
1005
#if 0
 
1006
        /* Restore VGA memory */
 
1007
        if (reg_buffer->flags & IGD_REG_SAVE_VGA_MEM) {
 
1008
                if (reg_args->vga_mem) {
 
1009
                        OS_MEMCPY((void *)context->device_context.virt_fb_adr,
 
1010
                                        reg_args->vga_mem, 64*1024);
 
1011
                } else {
 
1012
                        EMGD_ERROR("Trying to restore NULL VGA memory");
 
1013
                }
 
1014
        }
 
1015
#endif
 
1016
 
 
1017
        /* Restore DAC registers */
 
1018
        if (reg_buffer->flags & IGD_REG_SAVE_DAC) {
 
1019
                reg_restore_dac_tnc(context, &reg_args->dac_state, platform_context);
 
1020
        }
 
1021
 
 
1022
        /* Restore VGA registers */
 
1023
        if (reg_buffer->flags & IGD_REG_SAVE_VGA) {
 
1024
                reg_restore_vga_tnc(context, &reg_args->vga_state,
 
1025
                        platform_context->ar, platform_context->cr, platform_context->sr,
 
1026
                        platform_context->gr);
 
1027
        }
 
1028
 
 
1029
        /* Restore the SGX clock gating settings */
 
1030
        EMGD_WRITE32(reg_args->clk_gating_ctl, mmio + PSB_CR_CLKGATECTL);
 
1031
 
 
1032
        return 0;
 
1033
}
 
1034
 
 
1035
/*!
 
1036
 * This function saves the GTT table entries into a buffer so that the GTT
 
1037
 * can be restored later.
 
1038
 *
 
1039
 * @param context needs this to get the GTT table size and to get the
 
1040
 *      virtual address to the GTT table
 
1041
 * @param mmio virtual address to MMIO
 
1042
 * @param reg_args a pre-allocated context where GTT entries are saved
 
1043
 *
 
1044
 * @return 0 on success
 
1045
 * @return -1 on failure
 
1046
 */
 
1047
static int reg_save_gtt_tnc(igd_context_t *context, unsigned char *mmio,
 
1048
        reg_buffer_tnc_t *reg_args)
 
1049
{
 
1050
        unsigned int  i;
 
1051
 
 
1052
        /* Read the GTT entries from GTT ADR and save it in the array. */
 
1053
        for (i = 0; i < (context->device_context.gatt_pages); i++) {
 
1054
                reg_args->gtt[i] = EMGD_READ32(
 
1055
                        context->device_context.virt_gttadr + i);
 
1056
        }
 
1057
 
 
1058
        /* Save the address of the SGX MMU */
 
1059
        reg_args->sgx_phyaddr = EMGD_READ32(mmio + PSB_CR_BIF_DIR_LIST_BASE0);
 
1060
 
 
1061
        return 0;
 
1062
}
 
1063
 
 
1064
/*!
 
1065
 *  This function restores the GTT table entries.
 
1066
 *
 
1067
 * @param context the context contains the GTT size and address
 
1068
 * @param reg_args this has the saved GTT entries
 
1069
 *
 
1070
 * @return 0 on success
 
1071
 * @return -1 on failure
 
1072
 */
 
1073
static int reg_restore_gtt_tnc(igd_context_t *context,
 
1074
        reg_buffer_tnc_t *reg_args)
 
1075
{
 
1076
        unsigned int i;
 
1077
        unsigned char *mmio;
 
1078
        unsigned long sgx_mmu;
 
1079
 
 
1080
        /* If the first element is 0, then nothing was saved */
 
1081
        if (0 == reg_args->gtt[0]) {
 
1082
                return 0;
 
1083
        }
 
1084
 
 
1085
        /* Restore the GTT tablep */
 
1086
        for (i=0; i < context->device_context.gatt_pages; i++) {
 
1087
                EMGD_WRITE32(reg_args->gtt[i],
 
1088
                        context->device_context.virt_gttadr + i);
 
1089
        }
 
1090
 
 
1091
        mmio = context->device_context.virt_mmadr;
 
1092
 
 
1093
        /*
 
1094
         * FIXME: The following code restore the SGX MMU. This
 
1095
         * is probably not necessary and may be incorrect.
 
1096
         */
 
1097
        /* Invalidate directory cache */
 
1098
        sgx_mmu = EMGD_READ32(mmio + PSB_CR_BIF_CTRL);
 
1099
        sgx_mmu |= 0x1E;
 
1100
        EMGD_WRITE32(sgx_mmu, mmio + PSB_CR_BIF_CTRL);
 
1101
        EMGD_READ32(mmio + PSB_CR_BIF_CTRL);
 
1102
 
 
1103
        EMGD_WRITE32(reg_args->sgx_phyaddr, mmio + PSB_CR_BIF_DIR_LIST_BASE0);
 
1104
        EMGD_READ32(mmio + PSB_CR_BIF_DIR_LIST_BASE0);
 
1105
 
 
1106
        /* Turn on host access to aperture via the MMU */
 
1107
        sgx_mmu = EMGD_READ32(mmio + PSB_CR_BIF_CTRL);
 
1108
        sgx_mmu &= 0xFFFF0000;
 
1109
        EMGD_WRITE32(sgx_mmu, mmio + PSB_CR_BIF_CTRL);
 
1110
        EMGD_READ32(mmio + PSB_CR_BIF_CTRL);
 
1111
 
 
1112
        return 0;
 
1113
}