added 2.6.29.6 aldebaran kernel
[nao-ulib.git] / kernel / 2.6.29.6-aldebaran-rt / lib / cimarron / cim / cim_init.c
blob837a5f1b70b983af61ae03735c725a842787e7c3
1 /*
2 * <LIC_AMD_STD>
3 * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
4 * </LIC_AMD_STD>
6 * <CTL_AMD_STD>
7 * </CTL_AMD_STD>
9 * <DOC_AMD_STD>
10 * Cimarron initialization routines. These routines detect a Geode LX and read
11 * all hardware base addresses.
12 * </DOC_AMD_STD>
16 CIMARRON_STATIC unsigned long init_video_base = 0x80000900;
18 /*---------------------------------------------------------------------------
19 * init_detect_cpu
21 * This routine verifies that a Geode LX is present and returns the processor revision
22 * ID. For compatibility, this routine can also detect a Redcloud processor.
23 * bits[24:16] = minor version
24 * bits[15:8] = major version
25 * bits[7:0] = type (1 = Geode GX, 2 = Geode LX)
26 *---------------------------------------------------------------------------*/
28 int init_detect_cpu (unsigned long *cpu_revision, unsigned long *companion_revision)
30 unsigned long bus, device, i;
31 unsigned long cpu_bus = 0, cpu_device = 0;
32 unsigned long address, data;
33 unsigned long num_bars, function;
34 int cpu_found, sb_found;
35 Q_WORD msr_value;
37 /* SEARCH THROUGH PCI BUS */
38 /* We search the PCI bus for the Geode LX or Geode GX northbridge. */
39 /* We then verify that one of its functions is the graphics */
40 /* controller and that all bars are filled in. */
42 cpu_found = sb_found = 0;
43 for (bus = 0; bus < 256; bus++)
45 for (device = 0; device < 21; device++)
47 address = 0x80000000 | (bus << 16) | (device << 11);
49 data = init_read_pci (address);
51 if (data == PCI_VENDOR_DEVICE_GEODEGX || data == PCI_VENDOR_DEVICE_GEODELX)
53 cpu_found = 1;
54 cpu_device = device;
55 cpu_bus = bus;
56 if (data == PCI_VENDOR_DEVICE_GEODEGX)
57 *cpu_revision = CIM_CPU_GEODEGX;
58 else
59 *cpu_revision = CIM_CPU_GEODELX;
61 else if (data == PCI_VENDOR_5535 || data == PCI_VENDOR_5536)
63 sb_found = 1;
64 if (data == PCI_VENDOR_5535)
65 *companion_revision = CIM_SB_5535;
66 else
67 *companion_revision = CIM_SB_5536;
70 if (cpu_found && sb_found)
71 break;
73 if (device != 21)
74 break;
77 if (bus == 256)
79 *cpu_revision = 0;
80 return CIM_STATUS_CPUNOTFOUND;
83 msr_init_table();
85 if (msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REVID, &msr_value) != CIM_STATUS_OK)
87 *cpu_revision = 0;
88 return CIM_STATUS_CPUNOTFOUND;
91 *cpu_revision |= ((msr_value.low & 0xF0) << 4) |
92 ((msr_value.low & 0x0F) << 16);
94 if (msr_read64 (MSR_DEVICE_5535_GLCP, GLCP_REVID, &msr_value) != CIM_STATUS_OK)
96 *cpu_revision = 0;
97 return CIM_STATUS_CPUNOTFOUND;
100 *companion_revision |= ((msr_value.low & 0xF0) << 4) |
101 ((msr_value.low & 0x0F) << 16);
103 /* SEARCH ALL FUNCTIONS FOR INTEGRATED GRAPHICS */
105 num_bars = 0;
106 for (function = 0; function < 7; function++)
108 address = 0x80000000 | (cpu_bus << 16) | (cpu_device << 11) | (function << 8);
109 data = init_read_pci (address);
111 if (data == PCI_VENDOR_DEVICE_GEODEGX_VIDEO)
113 num_bars = 4;
114 break;
116 else if (data == PCI_VENDOR_DEVICE_GEODELX_VIDEO)
118 num_bars = 5;
119 break;
123 /* VERIFY THAT ALL BARS ARE PRESENT */
125 if (function == 7)
126 return CIM_STATUS_DISPLAYUNAVAILABLE;
128 for (i = 0; i < num_bars; i++)
130 data = init_read_pci (address + 0x10 + (i << 2));
132 if (data == 0 || data == 0xFFFFFFFF)
133 break;
136 if (i != num_bars)
137 return CIM_STATUS_DISPLAYUNAVAILABLE;
139 /* SAVE VIDEO BASE ADDRESS FOR FUTURE CALLS */
141 init_video_base = address;
143 return CIM_STATUS_OK;
146 /*---------------------------------------------------------------------------
147 * init_read_pci
149 * This routine reads an unsigned long value from a PCI address.
150 *---------------------------------------------------------------------------*/
152 unsigned long init_read_pci (unsigned long address)
154 OUTD (0xCF8, address);
155 return IND (0xCFC);
158 /*---------------------------------------------------------------------------
159 * init_read_base_addresses
161 * This routine reads all base addresses for the peripherals from the PCI BARs.
162 *---------------------------------------------------------------------------*/
164 int init_read_base_addresses (INIT_BASE_ADDRESSES *base_addresses)
166 unsigned long value;
168 /* READ ALL BASE ADDRESSES */
170 base_addresses->framebuffer_base = init_read_pci (init_video_base + 0x10);
171 base_addresses->gp_register_base = init_read_pci (init_video_base + 0x14);
172 base_addresses->vg_register_base = init_read_pci (init_video_base + 0x18);
173 base_addresses->df_register_base = init_read_pci (init_video_base + 0x1C);
174 base_addresses->vip_register_base = init_read_pci (init_video_base + 0x20);
176 /* READ FRAME BUFFER SIZE */
177 /* The frame buffer size is reported by a VSM in VSA II */
178 /* Virtual Register Class = 0x02 */
179 /* VG_MEM_SIZE (1MB units) = 0x00 */
181 OUTW (0xAC1C, 0xFC53);
182 OUTW (0xAC1C, 0x0200);
184 value = (unsigned long)(INW (0xAC1E)) & 0xFE;
186 base_addresses->framebuffer_size = value << 20;
188 return CIM_STATUS_OK;
191 /*---------------------------------------------------------------------------
192 * init_read_cpu_frequency
194 * This routine returns the current CPU core frequency, in MHz.
195 *---------------------------------------------------------------------------*/
197 int init_read_cpu_frequency (unsigned long *cpu_frequency)
199 /* CPU SPEED IS REPORTED BY A VSM IN VSA II */
200 /* Virtual Register Class = 0x12 (Sysinfo) */
201 /* CPU Speed Register = 0x01 */
203 OUTW (0xAC1C, 0xFC53);
204 OUTW (0xAC1C, 0x1201);
206 *cpu_frequency = (unsigned long)(INW (0xAC1E));
208 return CIM_STATUS_OK;