blob: 5b42e00eadb06fa1d9087498f91a3e09f72eb067 [file] [log] [blame]
Nils31eabf92012-01-14 12:11:41 -05001// Geode GX2/LX VGA functions
2//
3// Copyright (C) 2009 Chris Kindt
4//
5// Written for Google Summer of Code 2009 for the coreboot project
6//
7// This file may be distributed under the terms of the GNU LGPLv3 license.
8
9#include "geodevga.h" // geodevga_init
Nils31eabf92012-01-14 12:11:41 -050010#include "farptr.h" // SET_FARVAR
11#include "biosvar.h" // GET_BDA
12#include "vgabios.h" // VGAREG_*
13#include "util.h" // memset
Kevin O'Connor2c23a7a2012-01-14 22:18:18 -050014#include "stdvga.h" // stdvga_crtc_write
Kevin O'Connor707d2162012-01-15 00:06:33 -050015#include "pci.h" // pci_config_readl
16#include "pci_regs.h" // PCI_BASE_ADDRESS_0
Nils31eabf92012-01-14 12:11:41 -050017
18
19/****************************************************************
20* MSR and High Mem access through VSA Virtual Register
21****************************************************************/
22
Kevin O'Connorf47461f2012-09-03 12:32:01 -040023static u64 geode_msr_read(u32 msrAddr)
Nils31eabf92012-01-14 12:11:41 -050024{
25 union u64_u32_u val;
26 asm __volatile__ (
27 "movw $0x0AC1C, %%dx \n"
28 "movl $0xFC530007, %%eax \n"
29 "outl %%eax, %%dx \n"
30 "addb $2, %%dl \n"
31 "inw %%dx, %%ax \n"
32 : "=a" (val.lo), "=d"(val.hi)
33 : "c"(msrAddr)
34 : "cc"
35 );
Kevin O'Connorf47461f2012-09-03 12:32:01 -040036 return val.val;
Nils31eabf92012-01-14 12:11:41 -050037}
38
Kevin O'Connorf47461f2012-09-03 12:32:01 -040039static void geode_msr_mask(u32 msrAddr, u64 off, u64 on)
Nils31eabf92012-01-14 12:11:41 -050040{
Kevin O'Connorf47461f2012-09-03 12:32:01 -040041 union u64_u32_u uand, uor;
42 uand.val = ~off;
43 uor.val = on;
Nils31eabf92012-01-14 12:11:41 -050044 asm __volatile__ (
45 "push %%eax \n"
46 "movw $0x0AC1C, %%dx \n"
47 "movl $0xFC530007, %%eax \n"
48 "outl %%eax, %%dx \n"
49 "addb $2, %%dl \n"
50 "pop %%eax \n"
51 "outw %%ax, %%dx \n"
52 :
Kevin O'Connorf47461f2012-09-03 12:32:01 -040053 : "c"(msrAddr), "S" (uand.hi), "D" (uand.lo), "b" (uor.hi), "a" (uor.lo)
Nils31eabf92012-01-14 12:11:41 -050054 : "%edx","cc"
55 );
56}
57
Kevin O'Connorf47461f2012-09-03 12:32:01 -040058static u32 geode_mem_read(u32 addr)
Nils31eabf92012-01-14 12:11:41 -050059{
60 u32 val;
61 asm __volatile__ (
62 "movw $0x0AC1C, %%dx \n"
63 "movl $0xFC530001, %%eax \n"
64 "outl %%eax, %%dx \n"
65 "addb $2, %%dl \n"
66 "inw %%dx, %%ax \n"
67 : "=a" (val)
68 : "b"(addr)
69 : "cc"
70 );
71
72 return val;
73}
74
Kevin O'Connorf47461f2012-09-03 12:32:01 -040075static void geode_mem_mask(u32 addr, u32 off, u32 or)
Nils31eabf92012-01-14 12:11:41 -050076{
77 asm __volatile__ (
78 "movw $0x0AC1C, %%dx \n"
79 "movl $0xFC530001, %%eax \n"
80 "outl %%eax, %%dx \n"
81 "addb $2, %%dl \n"
82 "outw %%ax, %%dx \n"
83 :
Kevin O'Connorf47461f2012-09-03 12:32:01 -040084 : "b"(addr), "S" (~off), "D" (or)
Nils31eabf92012-01-14 12:11:41 -050085 : "%eax","cc"
86 );
87}
88
Christian Gmeiner119ece92012-10-01 14:02:43 +020089#define VP_FP_START 0x400
90
Kevin O'Connoref7f73f2012-09-16 13:24:30 -040091static u32 GeodeFB VAR16;
92static u32 GeodeDC VAR16;
93static u32 GeodeVP VAR16;
Christian Gmeiner7bec6db2012-09-01 17:13:02 +020094
Kevin O'Connorf47461f2012-09-03 12:32:01 -040095static u32 geode_dc_read(int reg)
Christian Gmeinerd136fd72012-09-01 17:13:04 +020096{
Kevin O'Connoref7f73f2012-09-16 13:24:30 -040097 u32 val = geode_mem_read(GET_GLOBAL(GeodeDC) + reg);
98 dprintf(4, "%s(0x%08x) = 0x%08x\n"
99 , __func__, GET_GLOBAL(GeodeDC) + reg, val);
Christian Gmeinerd136fd72012-09-01 17:13:04 +0200100 return val;
101}
102
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400103static void geode_dc_write(int reg, u32 val)
Christian Gmeinerd136fd72012-09-01 17:13:04 +0200104{
Kevin O'Connoref7f73f2012-09-16 13:24:30 -0400105 dprintf(4, "%s(0x%08x, 0x%08x)\n"
106 , __func__, GET_GLOBAL(GeodeDC) + reg, val);
107 geode_mem_mask(GET_GLOBAL(GeodeDC) + reg, ~0, val);
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400108}
109
110static void geode_dc_mask(int reg, u32 off, u32 on)
111{
Kevin O'Connoref7f73f2012-09-16 13:24:30 -0400112 dprintf(4, "%s(0x%08x, 0x%08x, 0x%08x)\n"
113 , __func__, GET_GLOBAL(GeodeDC) + reg, off, on);
114 geode_mem_mask(GET_GLOBAL(GeodeDC) + reg, off, on);
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400115}
116
117static u32 geode_vp_read(int reg)
118{
Kevin O'Connoref7f73f2012-09-16 13:24:30 -0400119 u32 val = geode_mem_read(GET_GLOBAL(GeodeVP) + reg);
120 dprintf(4, "%s(0x%08x) = 0x%08x\n"
121 , __func__, GET_GLOBAL(GeodeVP) + reg, val);
Christian Gmeinerd136fd72012-09-01 17:13:04 +0200122 return val;
123}
124
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400125static void geode_vp_write(int reg, u32 val)
Christian Gmeinerd136fd72012-09-01 17:13:04 +0200126{
Kevin O'Connoref7f73f2012-09-16 13:24:30 -0400127 dprintf(4, "%s(0x%08x, 0x%08x)\n"
128 , __func__, GET_GLOBAL(GeodeVP) + reg, val);
129 geode_mem_mask(GET_GLOBAL(GeodeVP) + reg, ~0, val);
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400130}
131
132static void geode_vp_mask(int reg, u32 off, u32 on)
133{
Kevin O'Connoref7f73f2012-09-16 13:24:30 -0400134 dprintf(4, "%s(0x%08x, 0x%08x, 0x%08x)\n"
135 , __func__, GET_GLOBAL(GeodeVP) + reg, off, on);
136 geode_mem_mask(GET_GLOBAL(GeodeVP) + reg, off, on);
Christian Gmeinerd136fd72012-09-01 17:13:04 +0200137}
138
Christian Gmeiner119ece92012-10-01 14:02:43 +0200139static u32 geode_fp_read(int reg)
140{
141 u32 val = geode_mem_read(GET_GLOBAL(GeodeVP) + VP_FP_START + reg);
142 dprintf(4, "%s(0x%08x) = 0x%08x\n"
143 , __func__, GET_GLOBAL(GeodeVP) + reg, val);
144 return val;
145}
146
147static void geode_fp_write(int reg, u32 val)
148{
149 dprintf(4, "%s(0x%08x, 0x%08x)\n"
150 , __func__, GET_GLOBAL(GeodeVP) + VP_FP_START + reg, val);
151 geode_mem_mask(GET_GLOBAL(GeodeVP) + reg, ~0, val);
152}
153
Kevin O'Connoref7f73f2012-09-16 13:24:30 -0400154/****************************************************************
155 * Helper functions
156 ****************************************************************/
157
Nils31eabf92012-01-14 12:11:41 -0500158static int legacyio_check(void)
159{
160 int ret=0;
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400161 u64 val;
Nils31eabf92012-01-14 12:11:41 -0500162
Nils24ddd862012-01-14 12:15:14 -0500163 if (CONFIG_VGA_GEODEGX2)
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400164 val = geode_msr_read(GLIU0_P2D_BM_4);
Nils24ddd862012-01-14 12:15:14 -0500165 else
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400166 val = geode_msr_read(MSR_GLIU0_BASE4);
167 if ((val & 0xffffffff) != 0x0A0fffe0)
Nils31eabf92012-01-14 12:11:41 -0500168 ret|=1;
169
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400170 val = geode_msr_read(GLIU0_IOD_BM_0);
171 if ((val & 0xffffffff) != 0x3c0ffff0)
Nils31eabf92012-01-14 12:11:41 -0500172 ret|=2;
173
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400174 val = geode_msr_read(GLIU0_IOD_BM_1);
175 if ((val & 0xffffffff) != 0x3d0ffff0)
Nils31eabf92012-01-14 12:11:41 -0500176 ret|=4;
177
178 return ret;
179}
180
Christian Gmeiner9de339d2012-09-01 17:12:56 +0200181static u32 framebuffer_size(void)
182{
Christian Gmeiner9de339d2012-09-01 17:12:56 +0200183 /* We use the P2D_R0 msr to read out the number of pages.
184 * One page has a size of 4k
185 *
186 * Bit Name Description
187 * 39:20 PMAX Physical Memory Address Max
188 * 19:0 PMIX Physical Memory Address Min
189 *
190 */
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400191 u64 msr = geode_msr_read(GLIU0_P2D_RO);
Christian Gmeiner9de339d2012-09-01 17:12:56 +0200192
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400193 u32 pmax = (msr >> 20) & 0x000fffff;
194 u32 pmin = msr & 0x000fffff;
195
196 u32 val = pmax - pmin;
Christian Gmeiner9de339d2012-09-01 17:12:56 +0200197 val += 1;
198
199 /* The page size is 4k */
200 return (val << 12);
201}
Nils31eabf92012-01-14 12:11:41 -0500202
203/****************************************************************
Nils31eabf92012-01-14 12:11:41 -0500204* Init Functions
205****************************************************************/
206
207/* Set up the dc (display controller) portion of the geodelx
Christian Gmeinerc13c1812012-09-01 17:12:52 +0200208* The dc provides hardware support for VGA graphics.
Nils31eabf92012-01-14 12:11:41 -0500209*/
Christian Gmeiner11ebc7d2012-09-01 17:13:03 +0200210static void dc_setup(void)
Nils31eabf92012-01-14 12:11:41 -0500211{
Nils31eabf92012-01-14 12:11:41 -0500212 dprintf(2, "DC_SETUP\n");
213
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400214 geode_dc_write(DC_UNLOCK, DC_LOCK_UNLOCK);
Nils31eabf92012-01-14 12:11:41 -0500215
216 /* zero memory config */
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400217 geode_dc_write(DC_FB_ST_OFFSET, 0x0);
218 geode_dc_write(DC_CB_ST_OFFSET, 0x0);
219 geode_dc_write(DC_CURS_ST_OFFSET, 0x0);
Nils31eabf92012-01-14 12:11:41 -0500220
221 /* read fb-bar from pci, then point dc to the fb base */
Kevin O'Connoref7f73f2012-09-16 13:24:30 -0400222 u32 fb = GET_GLOBAL(GeodeFB);
223 if (geode_dc_read(DC_GLIU0_MEM_OFFSET) != fb)
224 geode_dc_write(DC_GLIU0_MEM_OFFSET, fb);
Nils31eabf92012-01-14 12:11:41 -0500225
Christian Gmeiner286e0132012-10-01 14:02:42 +0200226 geode_dc_mask(DC_DISPLAY_CFG, ~DC_CFG_MSK, DC_DISPLAY_CFG_GDEN|DC_DISPLAY_CFG_TRUP);
227 geode_dc_write(DC_GENERAL_CFG, DC_DISPLAY_CFG_VGAE);
Nils31eabf92012-01-14 12:11:41 -0500228
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400229 geode_dc_write(DC_UNLOCK, DC_LOCK_LOCK);
Nils31eabf92012-01-14 12:11:41 -0500230
Christian Gmeiner9de339d2012-09-01 17:12:56 +0200231 u32 fb_size = framebuffer_size(); // in byte
Kevin O'Connoref7f73f2012-09-16 13:24:30 -0400232 dprintf(1, "%d KB of video memory at 0x%08x\n", fb_size / 1024, fb);
Christian Gmeiner517f7422012-09-01 17:13:01 +0200233
234 /* update VBE variables */
Kevin O'Connoref7f73f2012-09-16 13:24:30 -0400235 SET_VGA(VBE_framebuffer, fb);
Christian Gmeiner517f7422012-09-01 17:13:01 +0200236 SET_VGA(VBE_total_memory, fb_size / 1024 / 64); // number of 64K blocks
Nils31eabf92012-01-14 12:11:41 -0500237}
238
239/* Setup the vp (video processor) portion of the geodelx
240* Under VGA modes the vp was handled by softvg from inside VSA2.
241* Without a softvg module, access is only available through a pci bar.
242* The High Mem Access virtual register is used to configure the
243* pci mmio bar from 16bit friendly io space.
244*/
Christian Gmeiner11ebc7d2012-09-01 17:13:03 +0200245static void vp_setup(void)
Nils31eabf92012-01-14 12:11:41 -0500246{
Christian Gmeinereac884d2012-10-01 14:02:46 +0200247 u32 msr_addr;
248 u64 msr;
249
Nils31eabf92012-01-14 12:11:41 -0500250 dprintf(2,"VP_SETUP\n");
Christian Gmeinereac884d2012-10-01 14:02:46 +0200251
Nils31eabf92012-01-14 12:11:41 -0500252 /* set output to crt and RGB/YUV */
Nils24ddd862012-01-14 12:15:14 -0500253 if (CONFIG_VGA_GEODEGX2)
Christian Gmeinereac884d2012-10-01 14:02:46 +0200254 msr_addr = VP_MSR_CONFIG_GX2;
Nils24ddd862012-01-14 12:15:14 -0500255 else
Christian Gmeinereac884d2012-10-01 14:02:46 +0200256 msr_addr = VP_MSR_CONFIG_LX;
257
258 /* set output mode (RGB/YUV) */
259 msr = geode_msr_read(msr_addr);
260 msr &= ~VP_MSR_CONFIG_FMT; // mask out FMT (bits 5:3)
261
262 if (CONFIG_VGA_OUTPUT_PANEL || CONFIG_VGA_OUTPUT_CRT_PANEL) {
263 msr |= VP_MSR_CONFIG_FMT_FP; // flat panel
264
265 if (CONFIG_VGA_OUTPUT_CRT_PANEL) {
266 msr |= VP_MSR_CONFIG_FPC; // simultaneous Flat Panel and CRT
267 dprintf(1, "output: simultaneous Flat Panel and CRT\n");
268 } else {
269 msr &= ~VP_MSR_CONFIG_FPC; // no simultaneous Flat Panel and CRT
270 dprintf(1, "ouput: flat panel\n");
271 }
272 } else {
273 msr |= VP_MSR_CONFIG_FMT_CRT; // CRT only
274 dprintf(1, "output: CRT\n");
275 }
276 geode_msr_mask(msr_addr, ~msr, msr);
277
Nils31eabf92012-01-14 12:11:41 -0500278
Nils31eabf92012-01-14 12:11:41 -0500279 /* Set mmio registers
280 * there may be some timing issues here, the reads seem
281 * to slow things down enough work reliably
282 */
283
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400284 u32 reg = geode_vp_read(VP_MISC);
Nils31eabf92012-01-14 12:11:41 -0500285 dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg);
Christian Gmeiner286e0132012-10-01 14:02:42 +0200286 geode_vp_write(VP_MISC, VP_DCFG_BYP_BOTH);
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400287 reg = geode_vp_read(VP_MISC);
Nils31eabf92012-01-14 12:11:41 -0500288 dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg);
289
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400290 reg = geode_vp_read(VP_DCFG);
Nils31eabf92012-01-14 12:11:41 -0500291 dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg);
Christian Gmeiner286e0132012-10-01 14:02:42 +0200292 geode_vp_mask(VP_DCFG, 0, VP_DCFG_CRT_EN|VP_DCFG_HSYNC_EN|VP_DCFG_VSYNC_EN|VP_DCFG_DAC_BL_EN|VP_DCFG_CRT_SKEW);
Kevin O'Connorf47461f2012-09-03 12:32:01 -0400293 reg = geode_vp_read(VP_DCFG);
Nils31eabf92012-01-14 12:11:41 -0500294 dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg);
Christian Gmeiner02203b52012-10-01 14:02:49 +0200295
296 /* setup flat panel */
297 if (CONFIG_VGA_OUTPUT_PANEL || CONFIG_VGA_OUTPUT_CRT_PANEL) {
298 dprintf(1, "Setting up flat panel\n");
299 /* write timing register */
300 geode_fp_write(FP_PT1, 0x0);
301 geode_fp_write(FP_PT2, FP_PT2_SCRC);
302
303 /* set pad select for TFT/LVDS */
304 msr = VP_MSR_PADSEL_TFT_SEL_HIGH;
305 msr = msr << 32;
306 msr |= VP_MSR_PADSEL_TFT_SEL_LOW;
307 geode_msr_mask(VP_MSR_PADSEL, ~msr, msr);
308
309 /* turn the panel on (if it isn't already) */
310 reg = geode_fp_read(FP_PM);
311 reg |= FP_PM_P;
312 geode_fp_write(FP_PM, reg);
313 }
Nils31eabf92012-01-14 12:11:41 -0500314}
315
316static u8 geode_crtc_01[] VAR16 = {
317 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
318 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
319 0x9b, 0x8d, 0x8f, 0x14, 0x1f, 0x97, 0xb9, 0xa3,
320 0xff };
321static u8 geode_crtc_03[] VAR16 = {
322 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
323 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
324 0x9b, 0x8d, 0x8f, 0x28, 0x1f, 0x97, 0xb9, 0xa3,
325 0xff };
326static u8 geode_crtc_04[] VAR16 = {
327 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
328 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x9b, 0x8d, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xa2,
330 0xff };
331static u8 geode_crtc_05[] VAR16 = {
332 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
333 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x9b, 0x8e, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xa2,
335 0xff };
336static u8 geode_crtc_06[] VAR16 = {
337 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
338 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x9b, 0x8d, 0x8f, 0x28, 0x00, 0x97, 0xb9, 0xc2,
340 0xff };
341static u8 geode_crtc_07[] VAR16 = {
342 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
343 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
344 0x9b, 0x8d, 0x8f, 0x28, 0x0f, 0x97, 0xb9, 0xa3,
345 0xff };
346static u8 geode_crtc_0d[] VAR16 = {
347 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
348 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x9b, 0x8d, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xe3,
350 0xff };
351static u8 geode_crtc_0e[] VAR16 = {
352 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
353 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x9b, 0x8d, 0x8f, 0x28, 0x00, 0x97, 0xb9, 0xe3,
355 0xff };
356static u8 geode_crtc_0f[] VAR16 = {
357 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
358 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x65, 0xb9, 0xe3,
360 0xff };
361static u8 geode_crtc_11[] VAR16 = {
362 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0x0b, 0x3e,
363 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
365 0xff };
366static u8 geode_crtc_13[] VAR16 = {
367 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
368 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x9b, 0x8d, 0x8f, 0x28, 0x40, 0x98, 0xb9, 0xa3,
370 0xff };
371
372int geodevga_init(void)
373{
374 int ret = stdvga_init();
375 if (ret)
376 return ret;
377
378 dprintf(1,"GEODEVGA_INIT\n");
379
380 if ((ret=legacyio_check())) {
381 dprintf(1,"GEODEVGA_INIT legacyio_check=0x%x\n",ret);
382 }
383
384 // Updated timings from geode datasheets, table 6-53 in particular
385 static u8 *new_crtc[] VAR16 = {
386 geode_crtc_01, geode_crtc_01, geode_crtc_03, geode_crtc_03,
387 geode_crtc_04, geode_crtc_05, geode_crtc_06, geode_crtc_07,
388 0, 0, 0, 0, 0,
389 geode_crtc_0d, geode_crtc_0e, geode_crtc_0f, geode_crtc_0f,
390 geode_crtc_11, geode_crtc_11, geode_crtc_13 };
391 int i;
392 for (i=0; i<ARRAY_SIZE(new_crtc); i++) {
393 u8 *crtc = GET_GLOBAL(new_crtc[i]);
Kevin O'Connor69b01cb2012-01-14 23:25:24 -0500394 if (crtc)
395 stdvga_override_crtc(i, crtc);
Nils31eabf92012-01-14 12:11:41 -0500396 }
397
Kevin O'Connor8cf8f8e2012-01-16 19:05:27 -0500398 if (GET_GLOBAL(VgaBDF) < 0)
399 // Device should be at 00:01.1
400 SET_VGA(VgaBDF, pci_to_bdf(0, 1, 1));
Kevin O'Connoref7f73f2012-09-16 13:24:30 -0400401
Christian Gmeiner7bec6db2012-09-01 17:13:02 +0200402 // setup geode struct which is used for register access
Kevin O'Connoref7f73f2012-09-16 13:24:30 -0400403 SET_VGA(GeodeFB, pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_0));
404 SET_VGA(GeodeDC, pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_2));
405 SET_VGA(GeodeVP, pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_3));
406
407 dprintf(1, "fb addr: 0x%08x\n", GET_GLOBAL(GeodeFB));
408 dprintf(1, "dc addr: 0x%08x\n", GET_GLOBAL(GeodeDC));
409 dprintf(1, "vp addr: 0x%08x\n", GET_GLOBAL(GeodeVP));
410
Christian Gmeiner11ebc7d2012-09-01 17:13:03 +0200411 vp_setup();
412 dc_setup();
Nils31eabf92012-01-14 12:11:41 -0500413
Christian Gmeiner11ebc7d2012-09-01 17:13:03 +0200414 return 0;
Nils31eabf92012-01-14 12:11:41 -0500415}