~ubuntu-branches/ubuntu/precise/xserver-xorg-video-geode-lts-quantal/precise-updates

« back to all changes in this revision

Viewing changes to src/gfx/msr_rdcl.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2012-11-30 20:59:48 UTC
  • Revision ID: package-import@ubuntu.com-20121130205948-8p83molp6tff7m8o
Tags: upstream-2.11.13+git20120726
ImportĀ upstreamĀ versionĀ 2.11.13+git20120726

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2005 Advanced Micro Devices, Inc.
 
2
 *
 
3
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 
4
 * of this software and associated documentation files (the "Software"), to
 
5
 * deal in the Software without restriction, including without limitation the
 
6
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 
7
 * sell copies of the Software, and to permit persons to whom the Software is
 
8
 * furnished to do so, subject to the following conditions:
 
9
 *
 
10
 * The above copyright notice and this permission notice shall be included in
 
11
 * all copies or substantial portions of the Software.
 
12
 *
 
13
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
14
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
15
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
16
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
17
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
18
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 
19
 * IN THE SOFTWARE.
 
20
 *
 
21
 * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
 
22
 * contributors may be used to endorse or promote products derived from this
 
23
 * software without specific prior written permission.
 
24
 * */
 
25
 
 
26
/* 
 
27
 * This file contains MSR access routines for Redcloud.
 
28
 * */
 
29
 
 
30
void redcloud_build_mbus_tree(void);    /* private routine definition */
 
31
int redcloud_init_msr_devices(MSR aDev[], unsigned int array_size);
 
32
 
 
33
                                                                                /* private routine definition */
 
34
DEV_STATUS redcloud_find_msr_device(MSR * pDev);
 
35
 
 
36
                                                                                /* private routine definition */
 
37
 
 
38
/* REDCLOUD MSR BITMASKS */
 
39
 
 
40
#define MBD_MSR_CAP                     0x2000
 
41
#define MSR_CAP_ID_MASK         0xFF000
 
42
#define MSR_CAP_ID_SHIFT        12
 
43
#define MSR_CAP_REV_MASK    0x0F
 
44
#define MBIU_CAP                        0x86
 
45
#define NUM_PORTS_MASK          0x00380000
 
46
#define NUM_PORTS_SHIFT         19
 
47
#define MBIU_WHOAMI                     0x8B
 
48
#define WHOAMI_MASK                     0x07
 
49
 
 
50
/* REDCLOUD and CS5535 MSR DEVICES */
 
51
 
 
52
MSR msrDev[] = {
 
53
    {FOUND, RC_CC_MBIU, RC_MB0_MBIU0},
 
54
    {FOUND, RC_CC_MBIU, RC_MB0_MBIU1},
 
55
    {NOT_KNOWN, RC_CC_MCP, FAKE_ADDRESS},
 
56
    {NOT_KNOWN, RC_CC_MPCI, FAKE_ADDRESS},
 
57
    {NOT_KNOWN, RC_CC_MC, FAKE_ADDRESS},
 
58
    {NOT_KNOWN, RC_CC_GP, FAKE_ADDRESS},
 
59
    {NOT_KNOWN, RC_CC_VG, FAKE_ADDRESS},
 
60
    {NOT_KNOWN, RC_CC_DF, FAKE_ADDRESS},
 
61
    {NOT_KNOWN, RC_CC_FG, FAKE_ADDRESS},
 
62
    {FOUND, RC_CC_VA, RC_MB0_CPU},
 
63
    {FOUND, CP_CC_MBIU, CP_MB0_MBIU0},
 
64
    {NOT_KNOWN, CP_CC_MPCI, FAKE_ADDRESS},
 
65
    {NOT_KNOWN, CP_CC_USB2, FAKE_ADDRESS},
 
66
    {NOT_KNOWN, CP_CC_ATAC, FAKE_ADDRESS},
 
67
    {NOT_KNOWN, CP_CC_MDD, FAKE_ADDRESS},
 
68
    {NOT_KNOWN, CP_CC_ACC, FAKE_ADDRESS},
 
69
    {NOT_KNOWN, CP_CC_USB1, FAKE_ADDRESS},
 
70
    {NOT_KNOWN, CP_CC_MCP, FAKE_ADDRESS},
 
71
};
 
72
 
 
73
#define NUM_DEVS sizeof(msrDev) / sizeof(struct msr)
 
74
 
 
75
/* CAPISTRANO DEVICE INDEX LIMITS */
 
76
/* These defines represent the start and stop indexes into the device array
 
77
 * for all Capistrano devices.  These should be updated whenever a device is
 
78
 * added or removed to the Capistrano list.
 
79
 * */
 
80
 
 
81
#define CP_INDEX_START CP_ID_MBIU
 
82
#define CP_INDEX_STOP  CP_ID_MCP
 
83
 
 
84
/* GLOBAL MBUS CACHE STRUCTURES */
 
85
/* These structures contain a "cached" copy of the MBUS topology */
 
86
/* for easy future lookup.                                       */
 
87
 
 
88
MBUS_NODE MBIU0[8], MBIU1[8], MBIU2[8];
 
89
 
 
90
/* REGISTER MACROS */
 
91
 
 
92
#define GET_DEVICE_ID( CAPABILITIES_HIGH, CAPABILITIES_LOW ) \
 
93
                                         ((unsigned int)(( (CAPABILITIES_LOW) & MSR_CAP_ID_MASK ) >> MSR_CAP_ID_SHIFT ))
 
94
 
 
95
#define GET_NUM_PORTS( MBIU_CAP_HIGH, MBIU_CAP_LOW ) (((MBIU_CAP_HIGH) & NUM_PORTS_MASK ) >> NUM_PORTS_SHIFT)
 
96
 
 
97
/*----------------------------------------------------------------------------
 
98
 * gfx_msr_init
 
99
 * 
 
100
 * This routine initializes the base addresses of all known MBUS devices.  
 
101
 *----------------------------------------------------------------------------
 
102
 */
 
103
#if GFX_MSR_DYNAMIC
 
104
int
 
105
redcloud_msr_init(void)
 
106
#else
 
107
int
 
108
gfx_msr_init(void)
 
109
#endif
 
110
{
 
111
    Q_WORD msrValue;
 
112
    int return_value = 1;
 
113
 
 
114
    /* CHECK FOR VALID MBUS CONFIGURATION */
 
115
    /* The CPU and the two MBIUs are assumed to be at known static addresses,
 
116
     * so we will check the device IDs at these addresses as proof of a valid
 
117
     * mbus  configuration.
 
118
     * */
 
119
 
 
120
    MSR_READ(MBD_MSR_CAP, RC_MB0_CPU, &(msrValue.high), &(msrValue.low));
 
121
    if (GET_DEVICE_ID(msrValue.high, msrValue.low) != RC_CC_VA)
 
122
        return_value = 0;
 
123
 
 
124
    MSR_READ(MBD_MSR_CAP, RC_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
 
125
    if (GET_DEVICE_ID(msrValue.high, msrValue.low) != RC_CC_MBIU)
 
126
        return_value = 0;
 
127
 
 
128
    MSR_READ(MBD_MSR_CAP, RC_MB0_MBIU1, &(msrValue.high), &(msrValue.low));
 
129
    if (GET_DEVICE_ID(msrValue.high, msrValue.low) != RC_CC_MBIU)
 
130
        return_value = 0;
 
131
 
 
132
    /* ENUMERATE VALID BUS */
 
133
    /* If all static devices were identified, continue with the enumeration */
 
134
 
 
135
    if (return_value) {
 
136
        /* OPTIMIZATION */
 
137
        /* Build a local copy of the MBUS topology.  This allows us to  */
 
138
        /* quickly search the entire MBUS for a given device ID without */
 
139
        /* repeated MSR accesses.                                       */
 
140
 
 
141
        redcloud_build_mbus_tree();
 
142
 
 
143
        /* INITIALIZE MSR DEVICES */
 
144
 
 
145
        return_value = redcloud_init_msr_devices(msrDev, NUM_DEVS);
 
146
 
 
147
    }
 
148
 
 
149
    return return_value;
 
150
 
 
151
}
 
152
 
 
153
/*--------------------------------------------------------------------------
 
154
 * void redcloud_build_mbus_tree() (PRIVATE ROUTINE - NOT PART OF DURANGO API)
 
155
 *
 
156
 * This routine walks through the MBUS and records the address value and 
 
157
 * device ID found at each node.  If a node (aka port) is not populated, 
 
158
 * that node returns '0'.  The deviceID for that node is set to '0' 
 
159
 * (NOT_POPULATED) to reflect this. If the node being queried points back to 
 
160
 * Vail or MBIU0, the deviceID for that node is set to 'REFLECTIVE'.  
 
161
 * Reflective nodes are nodes that forward the given MBUS address BACK to the
 
162
 *  initiator.
 
163
 *----------------------------------------------------------------------------
 
164
 */
 
165
void
 
166
redcloud_build_mbus_tree(void)
 
167
{
 
168
    unsigned long mbiu_port_count, reflective;
 
169
    unsigned long port;
 
170
    Q_WORD msrValue;
 
171
 
 
172
    /*                  */
 
173
    /* ENUMERATE MBIU0  */
 
174
    /*                  */
 
175
 
 
176
    /* COUNT MBIU PORTS */
 
177
 
 
178
    MSR_READ(MBIU_CAP, RC_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
 
179
    mbiu_port_count = GET_NUM_PORTS(msrValue.high, msrValue.low);
 
180
 
 
181
    /* FIND REFLECTIVE PORT */
 
182
    /* Query the MBIU for the port through which we are communicating. */
 
183
    /* We will avoid accesses to this port to avoid a self-reference.  */
 
184
 
 
185
    MSR_READ(MBIU_WHOAMI, RC_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
 
186
    reflective = msrValue.low & WHOAMI_MASK;
 
187
 
 
188
    /* ENUMERATE ALL PORTS */
 
189
    /* For every possible port, set the MBIU.deviceId to something. */
 
190
 
 
191
    for (port = 0; port < 8; port++) {
 
192
        /* FILL IN CLAIMED FIELD */
 
193
        /* All MBIU ports can only be assigned to one device from the */
 
194
        /* Durango table                                              */
 
195
 
 
196
        MBIU0[port].claimed = 0;
 
197
 
 
198
        /* MBIU0 PORT NUMBERS ARE IN ADDRESS BITS 31:29 */
 
199
 
 
200
        MBIU0[port].address = port << 29;
 
201
 
 
202
        /* SPECIAL CASE FOR MBIU0 */
 
203
        /* MBIU0 port 0 is a special case, as it points back to MBIU0.  MBIU0
 
204
         * responds at address 0x40000xxx, which does not equal 0 << 29.
 
205
         * */
 
206
 
 
207
        if (port == 0)
 
208
            MBIU0[port].deviceId = RC_CC_MBIU;
 
209
        else if (port == reflective)
 
210
            MBIU0[port].deviceId = REFLECTIVE;
 
211
        else if (port > mbiu_port_count)
 
212
            MBIU0[port].deviceId = NOT_POPULATED;
 
213
        else {
 
214
            MSR_READ(MBD_MSR_CAP, MBIU0[port].address, &(msrValue.high),
 
215
                     &(msrValue.low));
 
216
            MBIU0[port].deviceId = GET_DEVICE_ID(msrValue.high, msrValue.low);
 
217
        }
 
218
    }
 
219
 
 
220
    /*                  */
 
221
    /* ENUMERATE MBIU1  */
 
222
    /*                  */
 
223
 
 
224
    /* COUNT MBIU PORTS */
 
225
 
 
226
    MSR_READ(MBIU_CAP, RC_MB0_MBIU1, &(msrValue.high), &(msrValue.low));
 
227
    mbiu_port_count = GET_NUM_PORTS(msrValue.high, msrValue.low);
 
228
 
 
229
    /* FIND REFLECTIVE PORT */
 
230
    /* Query the MBIU for the port through which we are communicating. */
 
231
    /* We will avoid accesses to this port to avoid a self-reference.  */
 
232
 
 
233
    MSR_READ(MBIU_WHOAMI, RC_MB0_MBIU1, &(msrValue.high), &(msrValue.low));
 
234
    reflective = msrValue.low & WHOAMI_MASK;
 
235
 
 
236
    /* ENUMERATE ALL PORTS */
 
237
    /* For every possible port, set the MBIU.deviceId to something. */
 
238
 
 
239
    for (port = 0; port < 8; port++) {
 
240
        /* FILL IN CLAIMED FIELD */
 
241
        /* All MBIU ports can only be assigned to one device from the */
 
242
        /* Durango table                                              */
 
243
 
 
244
        MBIU1[port].claimed = 0;
 
245
 
 
246
        /* MBIU1 PORT NUMBERS ARE IN 28:26 AND 31:29 = 010B */
 
247
 
 
248
        MBIU1[port].address = (0x02l << 29) + (port << 26);
 
249
 
 
250
        if (port == reflective)
 
251
            MBIU1[port].deviceId = REFLECTIVE;
 
252
        else if (port > mbiu_port_count)
 
253
            MBIU1[port].deviceId = NOT_POPULATED;
 
254
        else {
 
255
            MSR_READ(MBD_MSR_CAP, MBIU1[port].address, &(msrValue.high),
 
256
                     &(msrValue.low));
 
257
            MBIU1[port].deviceId = GET_DEVICE_ID(msrValue.high, msrValue.low);
 
258
        }
 
259
    }
 
260
 
 
261
    /*                          */
 
262
    /* ENUMERATE MBIU2 (CS5535) */
 
263
    /*  (if present)            */
 
264
 
 
265
    MSR_READ(MBD_MSR_CAP, CP_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
 
266
    if (GET_DEVICE_ID(msrValue.high, msrValue.low) == CP_CC_MBIU) {
 
267
        /* COUNT MBIU PORTS */
 
268
 
 
269
        MSR_READ(MBIU_CAP, CP_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
 
270
        mbiu_port_count = GET_NUM_PORTS(msrValue.high, msrValue.low);
 
271
 
 
272
        /* FIND REFLECTIVE PORT */
 
273
        /* Query the MBIU for the port through which we are communicating. */
 
274
        /* We will avoid accesses to this port to avoid a self-reference.  */
 
275
 
 
276
        MSR_READ(MBIU_WHOAMI, CP_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
 
277
        reflective = msrValue.low & WHOAMI_MASK;
 
278
 
 
279
        /* ENUMERATE ALL PORTS */
 
280
        /* For every possible port, set the MBIU.deviceId to something. */
 
281
 
 
282
        for (port = 0; port < 8; port++) {
 
283
            /* FILL IN CLAIMED FIELD */
 
284
            /* All MBIU ports can only be assigned to one device from the */
 
285
            /* Durango table                                              */
 
286
 
 
287
            MBIU2[port].claimed = 0;
 
288
 
 
289
            /* MBIU2 PORT NUMBERS ARE IN 22:20 AND 31:23 = 010100010B */
 
290
 
 
291
            MBIU2[port].address =
 
292
                (0x02l << 29) + (0x04l << 26) + (0x02l << 23) + (port << 20);
 
293
 
 
294
            if (port == reflective)
 
295
                MBIU2[port].deviceId = REFLECTIVE;
 
296
            else if (port > mbiu_port_count)
 
297
                MBIU2[port].deviceId = NOT_POPULATED;
 
298
            else {
 
299
                MSR_READ(MBD_MSR_CAP, MBIU2[port].address, &(msrValue.high),
 
300
                         &(msrValue.low));
 
301
                MBIU2[port].deviceId =
 
302
                    GET_DEVICE_ID(msrValue.high, msrValue.low);
 
303
            }
 
304
        }
 
305
    }
 
306
    else {
 
307
        /* NO 5535                                                  */
 
308
        /* If the CS5535 is not installed, fill in the cached table */
 
309
        /* with the 'NOT_INSTALLED' flag.  Also, fill in the device */
 
310
        /* status from NOT_KNOWN to REQ_NOT_INSTALLED.              */
 
311
 
 
312
        for (port = 0; port < 8; port++) {
 
313
            MBIU2[port].claimed = 0;
 
314
            MBIU2[port].deviceId = NOT_INSTALLED;
 
315
            MBIU2[port].address =
 
316
                (0x02l << 29) + (0x04l << 26) + (0x02l << 23) + (port << 20);
 
317
        }
 
318
        for (port = CP_INDEX_START; port <= CP_INDEX_STOP; port++) {
 
319
            msrDev[port].Present = REQ_NOT_INSTALLED;
 
320
        }
 
321
    }
 
322
}
 
323
 
 
324
/*------------------------------------------------------------------
 
325
 * redcloud_init_msr_devices (PRIVATE ROUTINE - NOT PART OF DURANGO API)
 
326
 *
 
327
 * Handles the details of finding each possible device on the MBUS.
 
328
 * If a given device is not found, its structure is left uninitialized.
 
329
 * If a given device is found, its structure is updated.
 
330
 *
 
331
 * This init routine only checks for devices in aDev[].
 
332
 *
 
333
 *  Passed:
 
334
 *              aDev - is a pointer to the array of MBUS devices.
 
335
 *              arraySize - number of elements in aDev.
 
336
 *
 
337
 *      Returns:
 
338
 *              1 - If, for every device, its address was found.
 
339
 *              0 - If, for any device, an error was encountered.
 
340
 *------------------------------------------------------------------
 
341
 */
 
342
int
 
343
redcloud_init_msr_devices(MSR aDev[], unsigned int array_size)
 
344
{
 
345
    unsigned int i, issues = 0;
 
346
 
 
347
    /* TRY TO FIND EACH ITEM IN THE ARRAY */
 
348
 
 
349
    for (i = 0; i < array_size; i++) {
 
350
        /* IGNORE DEVICES THAT ARE ALREADY FOUND                */
 
351
        /* The addresses for "found" devices are already known. */
 
352
 
 
353
        if (aDev[i].Present == FOUND || aDev[i].Present == REQ_NOT_INSTALLED)
 
354
            continue;
 
355
 
 
356
        /* TRY TO FIND THE DEVICE ON THE MBUS */
 
357
 
 
358
        aDev[i].Present = redcloud_find_msr_device(&aDev[i]);
 
359
 
 
360
        /* INCREMENT ERROR COUNT IF DEVICE NOT FOUND */
 
361
 
 
362
        if (aDev[i].Present != FOUND)
 
363
            issues++;
 
364
    }
 
365
 
 
366
    return (issues == 0);
 
367
}
 
368
 
 
369
/*------------------------------------------------------------------
 
370
 *  redcloud_find_msr_device (PRIVATE ROUTINE - NOT PART OF DURANGO API)
 
371
 *
 
372
 *  Passed:
 
373
 *          pDev - is a pointer to one element in the array of MBUS devices
 
374
 *
 
375
 *  Returns:
 
376
 *          FOUND - Device was found and pDev->Address has been updated.
 
377
 *
 
378
 *              REQ_NOT_FOUND - Device was not found and pDev->Address has not
 
379
 *                                              been updated.
 
380
 *
 
381
 *------------------------------------------------------------------
 
382
 */
 
383
DEV_STATUS
 
384
redcloud_find_msr_device(MSR * pDev)
 
385
{
 
386
    unsigned int i;
 
387
 
 
388
    /* SEARCH DURANGO'S CACHED MBUS TOPOLOGY */
 
389
    /* This gets a little tricky.  As the only identifier we have for each   
 
390
     * device is the device ID and we have multiple devices of the same type 
 
391
     * MCP, MPCI, USB, etc. we need to make some assumptions based on table  
 
392
     * order.  These are as follows:                                         
 
393
     * 1. All Redcloud nodes are searched first, as we assume that they      
 
394
     *    are first in the table.                                            
 
395
     * 2. If two devices have the same device ID and are found on the same   
 
396
     *    device (GX2, CS5535, etc.) we assume that they are listed such     
 
397
     *    that the first device in the table with this device ID has a lower 
 
398
     *    port address.                                                      
 
399
     * 3. After a device ID has been matched, the port is marked as          
 
400
     *    'claimed', such that future enumerations continue searching the    
 
401
     *    GeodeLink topology.
 
402
     */
 
403
 
 
404
    /* SEARCH MBIU0 */
 
405
 
 
406
    for (i = 0; i < 8; i++) {
 
407
        if (MBIU0[i].deviceId == pDev->Id && !(MBIU0[i].claimed)) {
 
408
            MBIU0[i].claimed = 1;
 
409
            pDev->Address = MBIU0[i].address;
 
410
            return FOUND;
 
411
        }
 
412
    }
 
413
 
 
414
    /* SEARCH MBIU1 */
 
415
 
 
416
    for (i = 0; i < 8; i++) {
 
417
        if (MBIU1[i].deviceId == pDev->Id && !(MBIU1[i].claimed)) {
 
418
            MBIU1[i].claimed = 1;
 
419
            pDev->Address = MBIU1[i].address;
 
420
            return FOUND;
 
421
        }
 
422
    }
 
423
 
 
424
    /* SEARCH MBIU2 */
 
425
 
 
426
    for (i = 0; i < 8; i++) {
 
427
        if (MBIU2[i].deviceId == pDev->Id && !(MBIU2[i].claimed)) {
 
428
            MBIU2[i].claimed = 1;
 
429
            pDev->Address = MBIU2[i].address;
 
430
            return FOUND;
 
431
        }
 
432
    }
 
433
 
 
434
    return REQ_NOT_FOUND;
 
435
}
 
436
 
 
437
/*--------------------------------------------------------------------
 
438
 * gfx_id_msr_device 
 
439
 *
 
440
 *      This routine handles reading the capabilities MSR register (typically 
 
441
 *      0x2000) and checking if the 'id' field matchs  pDev.Id.  This routine is
 
442
 *  used by applications/drivers that need to extend the list of known
 
443
 *  MBUS devices beyond those known by Durango.
 
444
 *
 
445
 *              Passed:
 
446
 *                      pDev - Pointer to MSR structure containing the device's ID.
 
447
 *                  address - device address.
 
448
 *
 
449
 *              Returns:
 
450
 *                      FOUND - The IDs do match.
 
451
 *                      REQ_NOT_FOUND - There was not a match.
 
452
 *
 
453
 *--------------------------------------------------------------------
 
454
 */
 
455
#if GFX_MSR_DYNAMIC
 
456
DEV_STATUS
 
457
redcloud_id_msr_device(MSR * pDev, unsigned long address)
 
458
#else
 
459
DEV_STATUS
 
460
gfx_id_msr_device(MSR * pDev, unsigned long address)
 
461
#endif
 
462
{
 
463
    Q_WORD msrValue;
 
464
 
 
465
    MSR_READ(MBD_MSR_CAP, address, &(msrValue.high), &(msrValue.low));
 
466
 
 
467
    if (GET_DEVICE_ID(msrValue.high, msrValue.low) == pDev->Id)
 
468
        return FOUND;
 
469
    else
 
470
        return REQ_NOT_FOUND;
 
471
}
 
472
 
 
473
/*--------------------------------------------------------------------
 
474
 * gfx_get_msr_dev_address
 
475
 * 
 
476
 * This function returns the 32-bit address of the requested device.
 
477
 * The device must be a known MBUS device.  (It must be in Durango's 
 
478
 * device table.)  DEV_STATUS should be checked to verify that the address 
 
479
 * was updated.
 
480
 *
 
481
 *
 
482
 * Passed:
 
483
 *     device - device index of the device in question.
 
484
 *         *address - ptr to location where address should be stored.
 
485
 *         
 
486
 * Returns:
 
487
 *         DEV_STATUS of device in question.  (NOT_KNOWN if device is out of range.)
 
488
 *     *address - updated if 'device' is within range
 
489
 *   
 
490
 *      Notes:
 
491
 *     This function should only be called after gfx_msr_init
 
492
 *
 
493
 *--------------------------------------------------------------------
 
494
 */
 
495
#if GFX_MSR_DYNAMIC
 
496
DEV_STATUS
 
497
redcloud_get_msr_dev_address(unsigned int device, unsigned long *address)
 
498
#else
 
499
DEV_STATUS
 
500
gfx_get_msr_dev_address(unsigned int device, unsigned long *address)
 
501
#endif
 
502
{
 
503
    if (device < NUM_DEVS) {
 
504
        if (msrDev[device].Present == FOUND)
 
505
            *address = msrDev[device].Address;
 
506
 
 
507
        return msrDev[device].Present;
 
508
    }
 
509
    return NOT_KNOWN;
 
510
 
 
511
}
 
512
 
 
513
/*--------------------------------------------------------------------
 
514
 *  gfx_get_glink_id_at_address
 
515
 *   
 
516
 *      This function returns the 16-bit deviceId at the requested address.
 
517
 *  DEV_STATUS should be checked to make sure that device was updated.
 
518
 *
 
519
 *      Passed:
 
520
 *          device - ptr to location where device ID should be stored.
 
521
 *              address - address of desired device ID.
 
522
 *         
 
523
 *  Returns:
 
524
 *          FOUND if address is a valid address, NOT_KNOWN if address cannot be 
 
525
 *          found on the mbus.
 
526
 *      *device - updated with device Id info.
 
527
 *
 
528
 *      Notes:
 
529
 *      This function should be called after gfx_msr_init 
 
530
 *
 
531
 *--------------------------------------------------------------------
 
532
 */
 
533
#if GFX_MSR_DYNAMIC
 
534
DEV_STATUS
 
535
redcloud_get_glink_id_at_address(unsigned int *device, unsigned long address)
 
536
#else
 
537
DEV_STATUS
 
538
gfx_get_glink_id_at_address(unsigned int *device, unsigned long address)
 
539
#endif
 
540
{
 
541
    int port;
 
542
 
 
543
    for (port = 0; port < 8; port++) {
 
544
        if (MBIU0[port].address == address) {
 
545
            *device = MBIU0[port].deviceId;
 
546
            return FOUND;
 
547
        }
 
548
        else if (MBIU1[port].address == address) {
 
549
            *device = MBIU1[port].deviceId;
 
550
            return FOUND;
 
551
        }
 
552
        else if (MBIU2[port].address == address) {
 
553
            *device = MBIU2[port].deviceId;
 
554
            return FOUND;
 
555
        }
 
556
    }
 
557
 
 
558
    return NOT_KNOWN;
 
559
 
 
560
}
 
561
 
 
562
/*--------------------------------------------------------------------
 
563
 * gfx_msr_read
 
564
 *
 
565
 * Performs a 64-bit read from 'msrRegister' in device 'device'.  'device' is 
 
566
 * an index into Durango's table of known MBUS devices.
 
567
 *
 
568
 * Returns:
 
569
 *     FOUND                    - if no errors were detected and msrValue has been 
 
570
 *                                              updated.
 
571
 *         NOT_KNOWN            - an error was detected.  msrValue is not updated.
 
572
 *         REQ_NOT_FOUND        - 'msrAddress' for 'devID' is unknown.  Caller
 
573
 *                                                      should call msrInit() first.  msrValue is not 
 
574
 *                                                      updated.
 
575
 * Notes:
 
576
 *       This function should be called after gfx_msr_init
 
577
 *--------------------------------------------------------------------
 
578
 */
 
579
#if GFX_MSR_DYNAMIC
 
580
DEV_STATUS
 
581
redcloud_msr_read(unsigned int device, unsigned int msrRegister,
 
582
                  Q_WORD * msrValue)
 
583
#else
 
584
DEV_STATUS
 
585
gfx_msr_read(unsigned int device, unsigned int msrRegister, Q_WORD * msrValue)
 
586
#endif
 
587
{
 
588
    if (device < NUM_DEVS) {
 
589
        if (msrDev[device].Present == FOUND)
 
590
            MSR_READ(msrRegister, msrDev[device].Address, &(msrValue->high),
 
591
                     &(msrValue->low));
 
592
 
 
593
        return msrDev[device].Present;
 
594
    }
 
595
    return NOT_KNOWN;
 
596
}
 
597
 
 
598
/*--------------------------------------------------------------------
 
599
 * gfx_msr_write
 
600
 *
 
601
 *              Performs a 64-bit write to 'msrRegister' in device 'devID'.
 
602
 *
 
603
 * Returns:
 
604
 *              FOUND                   - if no errors were detected and msrValue has been 
 
605
 *                                                      updated.
 
606
 *              NOT_KNOWN               - an error was detected.  msrValue is not updated.
 
607
 *              REQ_NOT_FOUND   - 'msrAddress' for 'devID' is unknown.  Caller
 
608
 *                                                      should call msrInit() first.  msrValue is not 
 
609
 *                                                      updated.
 
610
 *
 
611
 *Notes:
 
612
 *      This function is valid to call after initMSR_API() 
 
613
 *
 
614
 *--------------------------------------------------------------------
 
615
 */
 
616
#if GFX_MSR_DYNAMIC
 
617
DEV_STATUS
 
618
redcloud_msr_write(unsigned int device, unsigned int msrRegister,
 
619
                   Q_WORD * msrValue)
 
620
#else
 
621
DEV_STATUS
 
622
gfx_msr_write(unsigned int device, unsigned int msrRegister, Q_WORD * msrValue)
 
623
#endif
 
624
{
 
625
    if (device < NUM_DEVS) {
 
626
        if (msrDev[device].Present == FOUND)
 
627
            MSR_WRITE(msrRegister, msrDev[device].Address, &(msrValue->high),
 
628
                      &(msrValue->low));
 
629
 
 
630
        return msrDev[device].Present;
 
631
    }
 
632
 
 
633
    return NOT_KNOWN;
 
634
}