Annotation of qemu/roms/seabios/vgasrc/geodevga.c, revision 1.1.1.1

1.1       root        1: // 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
                     10: #include "farptr.h" // SET_FARVAR
                     11: #include "biosvar.h" // GET_BDA
                     12: #include "vgabios.h" // VGAREG_*
                     13: #include "util.h" // memset
                     14: #include "stdvga.h" // stdvga_crtc_write
                     15: #include "pci.h" // pci_config_readl
                     16: #include "pci_regs.h" // PCI_BASE_ADDRESS_0
                     17: 
                     18: 
                     19: /****************************************************************
                     20: * MSR and High Mem access through VSA Virtual Register
                     21: ****************************************************************/
                     22: 
                     23: static union u64_u32_u geode_msrRead(u32 msrAddr)
                     24: {
                     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:     );
                     36:     return val;
                     37: }
                     38: 
                     39: static void geode_msrWrite(u32 msrAddr,u32 andhi, u32 andlo, u32 orhi, u32 orlo)
                     40: {
                     41:     asm __volatile__ (
                     42:         "push   %%eax                   \n"
                     43:         "movw   $0x0AC1C, %%dx          \n"
                     44:         "movl   $0xFC530007, %%eax      \n"
                     45:         "outl   %%eax, %%dx             \n"
                     46:         "addb   $2, %%dl                \n"
                     47:         "pop    %%eax                   \n"
                     48:         "outw   %%ax, %%dx              \n"
                     49:         :
                     50:         : "c"(msrAddr), "S" (andhi), "D" (andlo), "b" (orhi), "a" (orlo)
                     51:         : "%edx","cc"
                     52:     );
                     53: }
                     54: 
                     55: static u32 geode_memRead(u32 addr)
                     56: {
                     57:     u32 val;
                     58:     asm __volatile__ (
                     59:         "movw   $0x0AC1C, %%dx          \n"
                     60:         "movl   $0xFC530001, %%eax      \n"
                     61:         "outl   %%eax, %%dx             \n"
                     62:         "addb   $2, %%dl                \n"
                     63:         "inw    %%dx, %%ax              \n"
                     64:         : "=a" (val)
                     65:         : "b"(addr)
                     66:         : "cc"
                     67:     );
                     68: 
                     69:     return val;
                     70: }
                     71: 
                     72: static void geode_memWrite(u32 addr, u32 and, u32 or )
                     73: {
                     74:     asm __volatile__ (
                     75:         "movw   $0x0AC1C, %%dx          \n"
                     76:         "movl   $0xFC530001, %%eax      \n"
                     77:         "outl   %%eax, %%dx             \n"
                     78:         "addb   $2, %%dl                \n"
                     79:         "outw   %%ax, %%dx              \n"
                     80:         :
                     81:         : "b"(addr), "S" (and), "D" (or)
                     82:         : "%eax","cc"
                     83:     );
                     84: }
                     85: 
                     86: static int legacyio_check(void)
                     87: {
                     88:     int ret=0;
                     89:     union u64_u32_u val;
                     90: 
                     91:     if (CONFIG_VGA_GEODEGX2)
                     92:         val=geode_msrRead(GLIU0_P2D_BM_4);
                     93:     else
                     94:         val=geode_msrRead(MSR_GLIU0_BASE4);
                     95:     if (val.lo != 0x0A0fffe0)
                     96:         ret|=1;
                     97: 
                     98:     val=geode_msrRead(GLIU0_IOD_BM_0);
                     99:     if (val.lo != 0x3c0ffff0)
                    100:         ret|=2;
                    101: 
                    102:     val=geode_msrRead(GLIU0_IOD_BM_1);
                    103:     if (val.lo != 0x3d0ffff0)
                    104:         ret|=4;
                    105: 
                    106:     return ret;
                    107: }
                    108: 
                    109: /****************************************************************
                    110: * Extened CRTC Register functions
                    111: ****************************************************************/
                    112: static void crtce_lock(void)
                    113: {
                    114:     stdvga_crtc_write(VGAREG_VGA_CRTC_ADDRESS, EXTENDED_REGISTER_LOCK
                    115:                       , CRTCE_LOCK);
                    116: }
                    117: 
                    118: static void crtce_unlock(void)
                    119: {
                    120:     stdvga_crtc_write(VGAREG_VGA_CRTC_ADDRESS, EXTENDED_REGISTER_LOCK
                    121:                       , CRTCE_UNLOCK);
                    122: }
                    123: 
                    124: static u8 crtce_read(u8 reg)
                    125: {
                    126:     crtce_unlock();
                    127:     u8 val = stdvga_crtc_read(VGAREG_VGA_CRTC_ADDRESS, reg);
                    128:     crtce_lock();
                    129:     return val;
                    130: }
                    131: 
                    132: static void crtce_write(u8 reg, u8 val)
                    133: {
                    134:     crtce_unlock();
                    135:     stdvga_crtc_write(VGAREG_VGA_CRTC_ADDRESS, reg, val);
                    136:     crtce_lock();
                    137: }
                    138: 
                    139: /****************************************************************
                    140: * Display Controller Functions
                    141: ****************************************************************/
                    142: static u32 dc_read(u16 seg, u32 reg)
                    143: {
                    144:     u32 val, *dest_far = (void*)reg;
                    145:     val = GET_FARVAR(seg,*dest_far);
                    146:     return val;
                    147: }
                    148: 
                    149: static void dc_write(u16 seg, u32 reg, u32 val)
                    150: {
                    151:     u32 *dest_far = (void*)reg;
                    152:     SET_FARVAR(seg,*dest_far,val);
                    153: }
                    154: 
                    155: static void dc_set(u16 seg, u32 reg, u32 and, u32 or)
                    156: {
                    157:     u32 val = dc_read(seg,reg);
                    158:     val &=and;
                    159:     val |=or;
                    160:     dc_write(seg,reg,val);
                    161: }
                    162: 
                    163: static void dc_unlock(u16 seg)
                    164: {
                    165:     dc_write(seg,DC_UNLOCK,DC_LOCK_UNLOCK);
                    166: }
                    167: 
                    168: static void dc_lock(u16 seg)
                    169: {
                    170:     dc_write(seg,DC_UNLOCK,DC_LOCK_LOCK);
                    171: }
                    172: 
                    173: static u16 dc_map(u16 seg)
                    174: {
                    175:     u8 reg;
                    176: 
                    177:     reg = crtce_read(EXTENDED_MODE_CONTROL);
                    178:     reg &= 0xf9;
                    179:     switch (seg) {
                    180:     case SEG_GRAPH:
                    181:         reg |= 0x02;
                    182:         break;
                    183:     case SEG_MTEXT:
                    184:         reg |= 0x04;
                    185:         break;
                    186:     case SEG_CTEXT:
                    187:         reg |= 0x06;
                    188:         break;
                    189:     default:
                    190:         seg=0;
                    191:         break;
                    192:     }
                    193: 
                    194:     crtce_write(EXTENDED_MODE_CONTROL,reg);
                    195:     return seg;
                    196: }
                    197: 
                    198: static void dc_unmap(void)
                    199: {
                    200:     dc_map(0);
                    201: }
                    202: 
                    203: 
                    204: /****************************************************************
                    205: * Init Functions
                    206: ****************************************************************/
                    207: 
                    208: /* Set up the dc (display controller) portion of the geodelx
                    209: *  The dc provides hardware support for VGA graphics
                    210: *  for features not accessible from the VGA registers,
                    211: *  the dc's pci bar can be mapped to a vga memory segment
                    212: */
                    213: static int dc_setup(void)
                    214: {
                    215:     u32 fb, dc_fb;
                    216:     u16 seg;
                    217: 
                    218:     dprintf(2, "DC_SETUP\n");
                    219: 
                    220:     seg = dc_map(SEG_GRAPH);
                    221:     dc_unlock(seg);
                    222: 
                    223:     /* zero memory config */
                    224:     dc_write(seg,DC_FB_ST_OFFSET,0x0);
                    225:     dc_write(seg,DC_CB_ST_OFFSET,0x0);
                    226:     dc_write(seg,DC_CURS_ST_OFFSET,0x0);
                    227: 
                    228:     /* read fb-bar from pci, then point dc to the fb base */
                    229:     dc_fb = dc_read(seg,DC_GLIU0_MEM_OFFSET);
                    230:     fb = pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_0);
                    231:     if (fb!=dc_fb) {
                    232:         dc_write(seg,DC_GLIU0_MEM_OFFSET,fb);
                    233:     }
                    234: 
                    235:     dc_set(seg,DC_DISPLAY_CFG,DC_CFG_MSK,DC_GDEN+DC_TRUP);
                    236:     dc_set(seg,DC_GENERAL_CFG,0,DC_VGAE);
                    237: 
                    238:     dc_lock(seg);
                    239:     dc_unmap();
                    240: 
                    241:     return 0;
                    242: }
                    243: 
                    244: /* Setup the vp (video processor) portion of the geodelx
                    245: *  Under VGA modes the vp was handled by softvg from inside VSA2.
                    246: *  Without a softvg module, access is only available through a pci bar.
                    247: *  The High Mem Access virtual register is used to  configure the
                    248: *   pci mmio bar from 16bit friendly io space.
                    249: */
                    250: int vp_setup(void)
                    251: {
                    252:     u32 reg,vp;
                    253: 
                    254:     dprintf(2,"VP_SETUP\n");
                    255:     /* set output to crt and RGB/YUV */
                    256:     if (CONFIG_VGA_GEODEGX2)
                    257:         geode_msrWrite(VP_MSR_CONFIG_GX2, ~0, ~0xf8, 0, 0);
                    258:     else
                    259:         geode_msrWrite(VP_MSR_CONFIG_LX, ~0, ~0xf8, 0, 0);
                    260: 
                    261:     /* get vp register base from pci */
                    262:     vp = pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_3);
                    263: 
                    264:     /* Set mmio registers
                    265:     * there may be some timing issues here, the reads seem
                    266:     * to slow things down enough work reliably
                    267:     */
                    268: 
                    269:     reg = geode_memRead(vp+VP_MISC);
                    270:     dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg);
                    271:     geode_memWrite(vp+VP_MISC,0,VP_BYP_BOTH);
                    272:     reg = geode_memRead(vp+VP_MISC);
                    273:     dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg);
                    274: 
                    275:     reg = geode_memRead(vp+VP_DCFG);
                    276:     dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg);
                    277:     geode_memWrite(vp+VP_DCFG, ~0,VP_CRT_EN+VP_HSYNC_EN+VP_VSYNC_EN+VP_DAC_BL_EN+VP_CRT_SKEW);
                    278:     reg = geode_memRead(vp+VP_DCFG);
                    279:     dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg);
                    280: 
                    281:     return 0;
                    282: }
                    283: 
                    284: static u8 geode_crtc_01[] VAR16 = {
                    285:     0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
                    286:     0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
                    287:     0x9b, 0x8d, 0x8f, 0x14, 0x1f, 0x97, 0xb9, 0xa3,
                    288:     0xff };
                    289: static u8 geode_crtc_03[] VAR16 = {
                    290:     0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
                    291:     0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
                    292:     0x9b, 0x8d, 0x8f, 0x28, 0x1f, 0x97, 0xb9, 0xa3,
                    293:     0xff };
                    294: static u8 geode_crtc_04[] VAR16 = {
                    295:     0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
                    296:     0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    297:     0x9b, 0x8d, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xa2,
                    298:     0xff };
                    299: static u8 geode_crtc_05[] VAR16 = {
                    300:     0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
                    301:     0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    302:     0x9b, 0x8e, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xa2,
                    303:     0xff };
                    304: static u8 geode_crtc_06[] VAR16 = {
                    305:     0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
                    306:     0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    307:     0x9b, 0x8d, 0x8f, 0x28, 0x00, 0x97, 0xb9, 0xc2,
                    308:     0xff };
                    309: static u8 geode_crtc_07[] VAR16 = {
                    310:     0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
                    311:     0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
                    312:     0x9b, 0x8d, 0x8f, 0x28, 0x0f, 0x97, 0xb9, 0xa3,
                    313:     0xff };
                    314: static u8 geode_crtc_0d[] VAR16 = {
                    315:     0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f,
                    316:     0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    317:     0x9b, 0x8d, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xe3,
                    318:     0xff };
                    319: static u8 geode_crtc_0e[] VAR16 = {
                    320:     0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
                    321:     0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    322:     0x9b, 0x8d, 0x8f, 0x28, 0x00, 0x97, 0xb9, 0xe3,
                    323:     0xff };
                    324: static u8 geode_crtc_0f[] VAR16 = {
                    325:     0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
                    326:     0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    327:     0x83, 0x85, 0x5d, 0x28, 0x0f, 0x65, 0xb9, 0xe3,
                    328:     0xff };
                    329: static u8 geode_crtc_11[] VAR16 = {
                    330:     0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0x0b, 0x3e,
                    331:     0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    332:     0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
                    333:     0xff };
                    334: static u8 geode_crtc_13[] VAR16 = {
                    335:     0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f,
                    336:     0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    337:     0x9b, 0x8d, 0x8f, 0x28, 0x40, 0x98, 0xb9, 0xa3,
                    338:     0xff };
                    339: 
                    340: int geodevga_init(void)
                    341: {
                    342:     int ret = stdvga_init();
                    343:     if (ret)
                    344:         return ret;
                    345: 
                    346:     dprintf(1,"GEODEVGA_INIT\n");
                    347: 
                    348:     if ((ret=legacyio_check())) {
                    349:         dprintf(1,"GEODEVGA_INIT legacyio_check=0x%x\n",ret);
                    350:     }
                    351: 
                    352:     // Updated timings from geode datasheets, table 6-53 in particular
                    353:     static u8 *new_crtc[] VAR16 = {
                    354:         geode_crtc_01, geode_crtc_01, geode_crtc_03, geode_crtc_03,
                    355:         geode_crtc_04, geode_crtc_05, geode_crtc_06, geode_crtc_07,
                    356:         0, 0, 0, 0, 0,
                    357:         geode_crtc_0d, geode_crtc_0e, geode_crtc_0f, geode_crtc_0f,
                    358:         geode_crtc_11, geode_crtc_11, geode_crtc_13 };
                    359:     int i;
                    360:     for (i=0; i<ARRAY_SIZE(new_crtc); i++) {
                    361:         u8 *crtc = GET_GLOBAL(new_crtc[i]);
                    362:         if (crtc)
                    363:             stdvga_override_crtc(i, crtc);
                    364:     }
                    365: 
                    366:     if (GET_GLOBAL(VgaBDF) < 0)
                    367:         // Device should be at 00:01.1
                    368:         SET_VGA(VgaBDF, pci_to_bdf(0, 1, 1));
                    369:     ret |= vp_setup();
                    370:     ret |= dc_setup();
                    371: 
                    372:     return ret;
                    373: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.