~ubuntu-branches/ubuntu/trusty/xserver-xorg-video-geode-lts-utopic/trusty-proposed

« back to all changes in this revision

Viewing changes to src/cim/cim_init.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2015-01-06 10:39:17 UTC
  • Revision ID: package-import@ubuntu.com-20150106103917-bumwel1243pseqs6
Tags: upstream-2.11.16
ImportĀ upstreamĀ versionĀ 2.11.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2006 Advanced Micro Devices, Inc.
 
3
 *
 
4
 * Permission is hereby granted, free of charge, to any person obtaining a
 
5
 * copy of this software and associated documentation files (the "Software"),
 
6
 * to deal in the Software without restriction, including without limitation
 
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
8
 * and/or sell copies of the Software, and to permit persons to whom the
 
9
 * Software is furnished to do so, subject to the following conditions:
 
10
 *
 
11
 * The above copyright notice and this permission notice shall be included in
 
12
 * all copies or substantial portions of the Software.
 
13
 *
 
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
19
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
20
 * DEALINGS IN THE SOFTWARE.
 
21
 *
 
22
 * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
 
23
 * contributors may be used to endorse or promote products derived from this
 
24
 * software without specific prior written permission.
 
25
 */
 
26
 
 
27
 /*
 
28
  * Cimarron initialization routines.  These routines detect a Geode LX and
 
29
  * read all hardware base addresses.
 
30
  */
 
31
 
 
32
CIMARRON_STATIC unsigned long init_video_base = 0x80000900;
 
33
 
 
34
/*---------------------------------------------------------------------------
 
35
 * init_detect_cpu
 
36
 *
 
37
 * This routine verifies that a Geode LX is present and returns the processor
 
38
 * revision ID.  For compatibility, this routine can also detect a Redcloud
 
39
 * processor.
 
40
 *     bits[24:16] = minor version
 
41
 *     bits[15:8]  = major version
 
42
 *     bits[7:0]   = type (1 = Geode GX, 2 = Geode LX)
 
43
 *---------------------------------------------------------------------------*/
 
44
 
 
45
int
 
46
init_detect_cpu(unsigned long *cpu_revision, unsigned long *companion_revision)
 
47
{
 
48
    unsigned long bus, device, i;
 
49
    unsigned long cpu_bus = 0, cpu_device = 0;
 
50
    unsigned long address, data;
 
51
    unsigned long num_bars, function;
 
52
    int cpu_found, sb_found;
 
53
    Q_WORD msr_value;
 
54
 
 
55
    /* SEARCH THROUGH PCI BUS                                          */
 
56
    /* We search the PCI bus for the Geode LX or Geode GX northbridge. */
 
57
    /* We then verify that one of its functions is the graphics        */
 
58
    /* controller and that all bars are filled in.                     */
 
59
 
 
60
    cpu_found = sb_found = 0;
 
61
    for (bus = 0; bus < 256; bus++) {
 
62
        for (device = 0; device < 21; device++) {
 
63
            address = 0x80000000 | (bus << 16) | (device << 11);
 
64
 
 
65
            data = init_read_pci(address);
 
66
 
 
67
            if (data == PCI_VENDOR_DEVICE_GEODEGX
 
68
                || data == PCI_VENDOR_DEVICE_GEODELX) {
 
69
                cpu_found = 1;
 
70
                cpu_device = device;
 
71
                cpu_bus = bus;
 
72
                if (data == PCI_VENDOR_DEVICE_GEODEGX)
 
73
                    *cpu_revision = CIM_CPU_GEODEGX;
 
74
                else
 
75
                    *cpu_revision = CIM_CPU_GEODELX;
 
76
            }
 
77
            else if (data == PCI_VENDOR_5535 || data == PCI_VENDOR_5536) {
 
78
                sb_found = 1;
 
79
                if (data == PCI_VENDOR_5535)
 
80
                    *companion_revision = CIM_SB_5535;
 
81
                else
 
82
                    *companion_revision = CIM_SB_5536;
 
83
            }
 
84
 
 
85
            if (cpu_found && sb_found)
 
86
                break;
 
87
        }
 
88
        if (device != 21)
 
89
            break;
 
90
    }
 
91
 
 
92
    if (bus == 256) {
 
93
        *cpu_revision = 0;
 
94
        return CIM_STATUS_CPUNOTFOUND;
 
95
    }
 
96
 
 
97
    msr_init_table();
 
98
 
 
99
    if (msr_read64(MSR_DEVICE_GEODELX_GLCP, GLCP_REVID,
 
100
                   &msr_value) != CIM_STATUS_OK) {
 
101
        *cpu_revision = 0;
 
102
        return CIM_STATUS_CPUNOTFOUND;
 
103
    }
 
104
 
 
105
    *cpu_revision |= ((msr_value.low & 0xF0) << 4) |
 
106
        ((msr_value.low & 0x0F) << 16);
 
107
 
 
108
    if (msr_read64(MSR_DEVICE_5535_GLCP, GLCP_REVID,
 
109
                   &msr_value) != CIM_STATUS_OK) {
 
110
        *cpu_revision = 0;
 
111
        return CIM_STATUS_CPUNOTFOUND;
 
112
    }
 
113
 
 
114
    *companion_revision |= ((msr_value.low & 0xF0) << 4) |
 
115
        ((msr_value.low & 0x0F) << 16);
 
116
 
 
117
    /* SEARCH ALL FUNCTIONS FOR INTEGRATED GRAPHICS */
 
118
 
 
119
    num_bars = 0;
 
120
    for (function = 0; function < 7; function++) {
 
121
        address = 0x80000000 | (cpu_bus << 16) | (cpu_device << 11) |
 
122
            (function << 8);
 
123
        data = init_read_pci(address);
 
124
 
 
125
        if (data == PCI_VENDOR_DEVICE_GEODEGX_VIDEO) {
 
126
            num_bars = 4;
 
127
            break;
 
128
        }
 
129
        else if (data == PCI_VENDOR_DEVICE_GEODELX_VIDEO) {
 
130
            num_bars = 5;
 
131
            break;
 
132
        }
 
133
    }
 
134
 
 
135
    /* VERIFY THAT ALL BARS ARE PRESENT */
 
136
 
 
137
    if (function == 7)
 
138
        return CIM_STATUS_DISPLAYUNAVAILABLE;
 
139
 
 
140
    for (i = 0; i < num_bars; i++) {
 
141
        data = init_read_pci(address + 0x10 + (i << 2));
 
142
 
 
143
        if (data == 0 || data == 0xFFFFFFFF)
 
144
            break;
 
145
    }
 
146
 
 
147
    if (i != num_bars)
 
148
        return CIM_STATUS_DISPLAYUNAVAILABLE;
 
149
 
 
150
    /* SAVE VIDEO BASE ADDRESS FOR FUTURE CALLS */
 
151
 
 
152
    init_video_base = address;
 
153
 
 
154
    return CIM_STATUS_OK;
 
155
}
 
156
 
 
157
/*---------------------------------------------------------------------------
 
158
 * init_read_pci
 
159
 *
 
160
 * This routine reads an unsigned long value from a PCI address.
 
161
 *---------------------------------------------------------------------------*/
 
162
 
 
163
unsigned long
 
164
init_read_pci(unsigned long address)
 
165
{
 
166
    OUTD(0xCF8, address);
 
167
    return IND(0xCFC);
 
168
}
 
169
 
 
170
/*---------------------------------------------------------------------------
 
171
 * init_read_base_addresses
 
172
 *
 
173
 * This routine reads all base addresses for the peripherals from the PCI
 
174
 * BARs.
 
175
 *---------------------------------------------------------------------------*/
 
176
 
 
177
int
 
178
init_read_base_addresses(INIT_BASE_ADDRESSES * base_addresses)
 
179
{
 
180
    unsigned long value;
 
181
 
 
182
    /* READ ALL BASE ADDRESSES */
 
183
 
 
184
    base_addresses->framebuffer_base = init_read_pci(init_video_base + 0x10);
 
185
    base_addresses->gp_register_base = init_read_pci(init_video_base + 0x14);
 
186
    base_addresses->vg_register_base = init_read_pci(init_video_base + 0x18);
 
187
    base_addresses->df_register_base = init_read_pci(init_video_base + 0x1C);
 
188
    base_addresses->vip_register_base = init_read_pci(init_video_base + 0x20);
 
189
 
 
190
    /* READ FRAME BUFFER SIZE */
 
191
    /* The frame buffer size is reported by a VSM in VSA II */
 
192
    /* Virtual Register Class    = 0x02                    */
 
193
    /* VG_MEM_SIZE (1MB units)   = 0x00                    */
 
194
 
 
195
    OUTW(0xAC1C, 0xFC53);
 
196
    OUTW(0xAC1C, 0x0200);
 
197
 
 
198
    value = (unsigned long) (INW(0xAC1E)) & 0xFE;
 
199
 
 
200
    base_addresses->framebuffer_size = value << 20;
 
201
 
 
202
    return CIM_STATUS_OK;
 
203
}
 
204
 
 
205
/*---------------------------------------------------------------------------
 
206
 * init_read_cpu_frequency
 
207
 *
 
208
 * This routine returns the current CPU core frequency, in MHz.
 
209
 *---------------------------------------------------------------------------*/
 
210
 
 
211
int
 
212
init_read_cpu_frequency(unsigned long *cpu_frequency)
 
213
{
 
214
    /* CPU SPEED IS REPORTED BY A VSM IN VSA II */
 
215
    /* Virtual Register Class = 0x12 (Sysinfo)  */
 
216
    /* CPU Speed Register     = 0x01            */
 
217
 
 
218
    OUTW(0xAC1C, 0xFC53);
 
219
    OUTW(0xAC1C, 0x1201);
 
220
 
 
221
    *cpu_frequency = (unsigned long) (INW(0xAC1E));
 
222
 
 
223
    return CIM_STATUS_OK;
 
224
}