There is no reason to access the DC registers via VGA memory mapping if we could the access via memory.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/geodevga.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-)
diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index 5c6caf0..8ce9ed1 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -206,37 +206,33 @@ static void dc_unmap(void) ****************************************************************/
/* Set up the dc (display controller) portion of the geodelx -* The dc provides hardware support for VGA graphics -* for features not accessible from the VGA registers, -* the dc's pci bar can be mapped to a vga memory segment +* The dc provides hardware support for VGA graphics. */ static int dc_setup(void) { - u32 fb, dc_fb; - u16 seg; + u32 fb, dc_fb, dc_base;
dprintf(2, "DC_SETUP\n");
- seg = dc_map(SEG_GRAPH); - dc_unlock(seg); + dc_base = pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_2); + geode_memWrite(dc_base + DC_UNLOCK, 0x0, DC_LOCK_UNLOCK);
/* zero memory config */ - dc_write(seg,DC_FB_ST_OFFSET,0x0); - dc_write(seg,DC_CB_ST_OFFSET,0x0); - dc_write(seg,DC_CURS_ST_OFFSET,0x0); + geode_memWrite(dc_base + DC_FB_ST_OFFSET, 0x0, 0x0); + geode_memWrite(dc_base + DC_CB_ST_OFFSET, 0x0, 0x0); + geode_memWrite(dc_base + DC_CURS_ST_OFFSET, 0x0, 0x0);
/* read fb-bar from pci, then point dc to the fb base */ - dc_fb = dc_read(seg,DC_GLIU0_MEM_OFFSET); + dc_fb = geode_memRead(dc_base + DC_GLIU0_MEM_OFFSET); fb = pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_0); if (fb!=dc_fb) { - dc_write(seg,DC_GLIU0_MEM_OFFSET,fb); + geode_memWrite(dc_base + DC_GLIU0_MEM_OFFSET, 0x0, fb); }
- dc_set(seg,DC_DISPLAY_CFG,DC_CFG_MSK,DC_GDEN+DC_TRUP); - dc_set(seg,DC_GENERAL_CFG,0,DC_VGAE); + geode_memWrite(dc_base + DC_DISPLAY_CFG, DC_CFG_MSK, DC_GDEN+DC_TRUP); + geode_memWrite(dc_base + DC_GENERAL_CFG, 0, DC_VGAE);
- dc_lock(seg); - dc_unmap(); + geode_memWrite(dc_base + DC_UNLOCK, 0x0, DC_LOCK_LOCK);
return 0; }
As we access teh DC registers via memory we do not need all the DC-VGA-mapping functions anymore.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/geodevga.c | 65 ------------------------------------------------------- 1 file changed, 65 deletions(-)
diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index 8ce9ed1..2cf11a0 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -137,71 +137,6 @@ static void crtce_write(u8 reg, u8 val) }
/**************************************************************** -* Display Controller Functions -****************************************************************/ -static u32 dc_read(u16 seg, u32 reg) -{ - u32 val, *dest_far = (void*)reg; - val = GET_FARVAR(seg,*dest_far); - return val; -} - -static void dc_write(u16 seg, u32 reg, u32 val) -{ - u32 *dest_far = (void*)reg; - SET_FARVAR(seg,*dest_far,val); -} - -static void dc_set(u16 seg, u32 reg, u32 and, u32 or) -{ - u32 val = dc_read(seg,reg); - val &=and; - val |=or; - dc_write(seg,reg,val); -} - -static void dc_unlock(u16 seg) -{ - dc_write(seg,DC_UNLOCK,DC_LOCK_UNLOCK); -} - -static void dc_lock(u16 seg) -{ - dc_write(seg,DC_UNLOCK,DC_LOCK_LOCK); -} - -static u16 dc_map(u16 seg) -{ - u8 reg; - - reg = crtce_read(EXTENDED_MODE_CONTROL); - reg &= 0xf9; - switch (seg) { - case SEG_GRAPH: - reg |= 0x02; - break; - case SEG_MTEXT: - reg |= 0x04; - break; - case SEG_CTEXT: - reg |= 0x06; - break; - default: - seg=0; - break; - } - - crtce_write(EXTENDED_MODE_CONTROL,reg); - return seg; -} - -static void dc_unmap(void) -{ - dc_map(0); -} - - -/**************************************************************** * Init Functions ****************************************************************/
As the access the DC registers via memory, we dont need to work with the extended CRTC register to setup the DC-VGA-mapping.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/geodevga.c | 29 ----------------------------- vgasrc/geodevga.h | 7 ------- 2 files changed, 36 deletions(-)
diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index 2cf11a0..ae606a7 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -106,35 +106,6 @@ static int legacyio_check(void) return ret; }
-/**************************************************************** -* Extened CRTC Register functions -****************************************************************/ -static void crtce_lock(void) -{ - stdvga_crtc_write(VGAREG_VGA_CRTC_ADDRESS, EXTENDED_REGISTER_LOCK - , CRTCE_LOCK); -} - -static void crtce_unlock(void) -{ - stdvga_crtc_write(VGAREG_VGA_CRTC_ADDRESS, EXTENDED_REGISTER_LOCK - , CRTCE_UNLOCK); -} - -static u8 crtce_read(u8 reg) -{ - crtce_unlock(); - u8 val = stdvga_crtc_read(VGAREG_VGA_CRTC_ADDRESS, reg); - crtce_lock(); - return val; -} - -static void crtce_write(u8 reg, u8 val) -{ - crtce_unlock(); - stdvga_crtc_write(VGAREG_VGA_CRTC_ADDRESS, reg, val); - crtce_lock(); -}
/**************************************************************** * Init Functions diff --git a/vgasrc/geodevga.h b/vgasrc/geodevga.h index fd7ce43..7098037 100644 --- a/vgasrc/geodevga.h +++ b/vgasrc/geodevga.h @@ -13,13 +13,6 @@ #define VRC_DATA 0xAC1E // Data register #define VR_UNLOCK 0xFC53 // Virtual register unlock code
-#define EXTENDED_REGISTER_LOCK 0x30 -#define EXTENDED_MODE_CONTROL 0x43 -#define EXTENDED_START_ADDR 0x44 - -#define CRTCE_UNLOCK 0x4c -#define CRTCE_LOCK 0xff - // Graphics-specific registers: #define OEM_BAR0 0x50 #define OEM_BAR1 0x54
As all supported graphic adapters are supporting VGA we should list them in int10 (AX = 4F00h). Also clext.c and bochsvga.c are haveing a function named like is_XXX_mode() which checks if its a default VGA mode or a VESA mode. If its a normal VGA mode stdvga_set_mode() gets called.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/stdvgamodes.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/vgasrc/stdvgamodes.c b/vgasrc/stdvgamodes.c index 5497da8..1756ade 100644 --- a/vgasrc/stdvgamodes.c +++ b/vgasrc/stdvgamodes.c @@ -334,6 +334,16 @@ stdvga_find_mode(int mode) void stdvga_list_modes(u16 seg, u16 *dest, u16 *last) { + int i; + for (i = 0; i < ARRAY_SIZE(vga_modes); i++) { + struct stdvga_mode_s *stdmode_g = &vga_modes[i]; + u16 mode = GET_GLOBAL(stdmode_g->mode); + if (mode == 0xffff) + continue; + SET_FARVAR(seg, *dest, mode); + dest++; + } + SET_FARVAR(seg, *dest, 0xffff); }
On Sat, Sep 01, 2012 at 05:12:55PM +0200, Christian Gmeiner wrote:
As all supported graphic adapters are supporting VGA we should list them in int10 (AX = 4F00h). Also clext.c and bochsvga.c are haveing a function named like is_XXX_mode() which checks if its a default VGA mode or a VESA mode. If its a normal VGA mode stdvga_set_mode() gets called.
[...]
void stdvga_list_modes(u16 seg, u16 *dest, u16 *last) {
- int i;
- for (i = 0; i < ARRAY_SIZE(vga_modes); i++) {
struct stdvga_mode_s *stdmode_g = &vga_modes[i];
u16 mode = GET_GLOBAL(stdmode_g->mode);
if (mode == 0xffff)
continue;
SET_FARVAR(seg, *dest, mode);
dest++;
- }
- SET_FARVAR(seg, *dest, 0xffff);
}
This is a good idea. However, I don't think vbe_104f01() will correctly handle all the standard vga modes as it is coded today.
-Kevin
2012/9/3 Kevin O'Connor kevin@koconnor.net:
On Sat, Sep 01, 2012 at 05:12:55PM +0200, Christian Gmeiner wrote:
As all supported graphic adapters are supporting VGA we should list them in int10 (AX = 4F00h). Also clext.c and bochsvga.c are haveing a function named like is_XXX_mode() which checks if its a default VGA mode or a VESA mode. If its a normal VGA mode stdvga_set_mode() gets called.
[...]
void stdvga_list_modes(u16 seg, u16 *dest, u16 *last) {
- int i;
- for (i = 0; i < ARRAY_SIZE(vga_modes); i++) {
struct stdvga_mode_s *stdmode_g = &vga_modes[i];
u16 mode = GET_GLOBAL(stdmode_g->mode);
if (mode == 0xffff)
continue;
SET_FARVAR(seg, *dest, mode);
dest++;
- }
- SET_FARVAR(seg, *dest, 0xffff);
}
This is a good idea. However, I don't think vbe_104f01() will correctly handle all the standard vga modes as it is coded today.
I will have a closer look at it during my following patches. If you want you can skip this patch.
--- Christian Gmeiner, MSc
It is possible to read out the framebuffer size via msr. The size information is needed for VESA later.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/geodevga.c | 27 +++++++++++++++++++++++++++ vgasrc/geodevga.h | 1 + 2 files changed, 28 insertions(+)
diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index ae606a7..636d55b 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -106,6 +106,30 @@ static int legacyio_check(void) return ret; }
+static u32 framebuffer_size(void) +{ + u32 val; + union u64_u32_u msr; + + /* We use the P2D_R0 msr to read out the number of pages. + * One page has a size of 4k + * + * Bit Name Description + * 39:20 PMAX Physical Memory Address Max + * 19:0 PMIX Physical Memory Address Min + * + */ + msr = geode_msrRead(GLIU0_P2D_RO); + + u32 pmax = ((msr.hi & 0xff) << 12) | ((msr.lo & 0xfff00000) >> 20); + u32 pmin = (msr.lo & 0x000fffff); + + val = pmax - pmin; + val += 1; + + /* The page size is 4k */ + return (val << 12); +}
/**************************************************************** * Init Functions @@ -140,6 +164,9 @@ static int dc_setup(void)
geode_memWrite(dc_base + DC_UNLOCK, 0x0, DC_LOCK_LOCK);
+ u32 fb_size = framebuffer_size(); // in byte + dprintf(1, "%d KB of video memory at 0x%08x\n", fb_size / 1024, fb); + return 0; }
diff --git a/vgasrc/geodevga.h b/vgasrc/geodevga.h index 7098037..14e33d6 100644 --- a/vgasrc/geodevga.h +++ b/vgasrc/geodevga.h @@ -26,6 +26,7 @@ #define MSR_GLIU0 (1 << 28) #define MSR_GLIU0_BASE4 (MSR_GLIU0 + 0x23) /* LX */ #define GLIU0_P2D_BM_4 (MSR_GLIU0 + 0x24) /* GX2 */ +#define GLIU0_P2D_RO (MSR_GLIU0 + 0x29) #define GLIU0_IOD_BM_0 (MSR_GLIU0 + 0xE0) #define GLIU0_IOD_BM_1 (MSR_GLIU0 + 0xE1) #define DC_SPARE 0x80000011
In oder to support VESA we need to provide mode table and some functions to work with modes. mode_setting will be added later.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/geodevga.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ vgasrc/geodevga.h | 2 ++ 2 files changed, 51 insertions(+)
diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index 636d55b..a1a79c9 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -17,6 +17,55 @@
/**************************************************************** + * Mode tables + ****************************************************************/ + +static struct geodevga_mode +{ + u16 mode; + struct vgamode_s info; +} geodevga_modes[] VAR16 = { + /* VESA modes */ + { 0x101, { MM_PACKED, 640, 480, 8, 8, 16, SEG_GRAPH } }, + { 0x103, { MM_PACKED, 800, 600, 8, 8, 16, SEG_GRAPH } }, + { 0x105, { MM_PACKED, 1024, 768, 8, 8, 16, SEG_GRAPH } }, + { 0x107, { MM_PACKED, 1280, 1024, 8, 8, 16, SEG_GRAPH } }, + { 0x110, { MM_DIRECT, 640, 480, 15, 8, 16, SEG_GRAPH } }, + { 0x111, { MM_DIRECT, 640, 480, 16, 8, 16, SEG_GRAPH } }, + { 0x112, { MM_DIRECT, 640, 480, 24, 8, 16, SEG_GRAPH } }, + { 0x113, { MM_DIRECT, 800, 600, 15, 8, 16, SEG_GRAPH } }, + { 0x114, { MM_DIRECT, 800, 600, 16, 8, 16, SEG_GRAPH } }, + { 0x115, { MM_DIRECT, 800, 600, 24, 8, 16, SEG_GRAPH } }, + { 0x116, { MM_DIRECT, 1024, 768, 15, 8, 16, SEG_GRAPH } }, + { 0x117, { MM_DIRECT, 1024, 768, 16, 8, 16, SEG_GRAPH } }, + { 0x118, { MM_DIRECT, 1024, 768, 24, 8, 16, SEG_GRAPH } }, + { 0x119, { MM_DIRECT, 1280, 1024, 15, 8, 16, SEG_GRAPH } }, + { 0x11A, { MM_DIRECT, 1280, 1024, 16, 8, 16, SEG_GRAPH } }, +}; + +struct vgamode_s *geodevga_find_mode(int mode) +{ + struct geodevga_mode *m = geodevga_modes; + for (; m < &geodevga_modes[ARRAY_SIZE(geodevga_modes)]; m++) + if (GET_GLOBAL(m->mode) == mode) + return &m->info; + return stdvga_find_mode(mode); +} + +void geodevga_list_modes(u16 seg, u16 *dest, u16 *last) +{ + struct geodevga_mode *m = geodevga_modes; + for (; m < &geodevga_modes[ARRAY_SIZE(geodevga_modes)] && dest<last; m++) { + u16 mode = GET_GLOBAL(m->mode); + if (mode == 0xffff) + continue; + SET_FARVAR(seg, *dest, mode); + dest++; + } + stdvga_list_modes(seg, dest, last); +} + +/**************************************************************** * MSR and High Mem access through VSA Virtual Register ****************************************************************/
diff --git a/vgasrc/geodevga.h b/vgasrc/geodevga.h index 14e33d6..fe149df 100644 --- a/vgasrc/geodevga.h +++ b/vgasrc/geodevga.h @@ -65,5 +65,7 @@ #define DC_CFG_MSK 0xf000a6
int geodevga_init(); +struct vgamode_s *geodevga_find_mode(int mode); +void geodevga_list_modes(u16 seg, u16 *dest, u16 *last);
#endif
With this patch it is possible to get and find all defined geode VESA modes.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/vgahw.h | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h index 044cd32..1842934 100644 --- a/vgasrc/vgahw.h +++ b/vgasrc/vgahw.h @@ -14,6 +14,8 @@ static inline struct vgamode_s *vgahw_find_mode(int mode) { return clext_find_mode(mode); if (CONFIG_VGA_BOCHS) return bochsvga_find_mode(mode); + if (CONFIG_VGA_GEODELX) + return geodevga_find_mode(mode); return stdvga_find_mode(mode); }
@@ -30,6 +32,8 @@ static inline void vgahw_list_modes(u16 seg, u16 *dest, u16 *last) { clext_list_modes(seg, dest, last); else if (CONFIG_VGA_BOCHS) bochsvga_list_modes(seg, dest, last); + else if (CONFIG_VGA_GEODELX) + geodevga_list_modes(seg, dest, last); else stdvga_list_modes(seg, dest, last); }
With the current code the following happens:
VBE mode info request: 4101 VBE mode 4101 not found get_mode failed.
Looking at the provided mode (cx register) only bits 8-0 define the video mode number. I am not sure if the current code ever worked.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/vbe.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index 227a244..af72324 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -72,9 +72,24 @@ vbe_104f01(struct bregs *regs) struct vbe_mode_info *info = (void*)(regs->di+0); u16 mode = regs->cx;
+ /* + * Bitfields for VESA/VBE video mode number: + * + * Bit(s) Description (Table 04082) + * 15 preserve display memory on mode change + * 14 (VBE v2.0+) use linear (flat) frame buffer + * 13 (VBE/AF 1.0P) VBE/AF initializes accelerator hardware + * 12 reserved for VBE/AF + * 11 (VBE v3.0) user user-specified CRTC refresh rate values + * 10-9 reserved for future expansion + * 8-0 video mode number (0xxh are non-VESA modes, 1xxh are VESA-defined) + * + * see http://www.ctyme.com/intr/rb-0274.htm + */ + dprintf(1, "VBE mode info request: %x\n", mode);
- struct vgamode_s *vmode_g = vgahw_find_mode(mode); + struct vgamode_s *vmode_g = vgahw_find_mode(mode & 0x1FF); if (! vmode_g) { dprintf(1, "VBE mode %x not found\n", mode); regs->ax = 0x014f;
On Sat, Sep 01, 2012 at 05:12:59PM +0200, Christian Gmeiner wrote:
With the current code the following happens:
VBE mode info request: 4101 VBE mode 4101 not found get_mode failed.
Looking at the provided mode (cx register) only bits 8-0 define the video mode number. I am not sure if the current code ever worked.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com
vgasrc/vbe.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index 227a244..af72324 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -72,9 +72,24 @@ vbe_104f01(struct bregs *regs) struct vbe_mode_info *info = (void*)(regs->di+0); u16 mode = regs->cx;
- /*
* Bitfields for VESA/VBE video mode number:
*
* Bit(s) Description (Table 04082)
* 15 preserve display memory on mode change
* 14 (VBE v2.0+) use linear (flat) frame buffer
* 13 (VBE/AF 1.0P) VBE/AF initializes accelerator hardware
* 12 reserved for VBE/AF
* 11 (VBE v3.0) user user-specified CRTC refresh rate values
* 10-9 reserved for future expansion
* 8-0 video mode number (0xxh are non-VESA modes, 1xxh are VESA-defined)
*
* see http://www.ctyme.com/intr/rb-0274.htm
*/
This is true for the call to set mode (vbe_104f02), but the spec does not say this for the get mode info call (104f01). It would be odd to pass in these additional bits when the caller just wants to get info on the given mode.
-Kevin
2012/9/3 Kevin O'Connor kevin@koconnor.net:
On Sat, Sep 01, 2012 at 05:12:59PM +0200, Christian Gmeiner wrote:
With the current code the following happens:
VBE mode info request: 4101 VBE mode 4101 not found get_mode failed.
Looking at the provided mode (cx register) only bits 8-0 define the video mode number. I am not sure if the current code ever worked.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com
vgasrc/vbe.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c index 227a244..af72324 100644 --- a/vgasrc/vbe.c +++ b/vgasrc/vbe.c @@ -72,9 +72,24 @@ vbe_104f01(struct bregs *regs) struct vbe_mode_info *info = (void*)(regs->di+0); u16 mode = regs->cx;
- /*
* Bitfields for VESA/VBE video mode number:
*
* Bit(s) Description (Table 04082)
* 15 preserve display memory on mode change
* 14 (VBE v2.0+) use linear (flat) frame buffer
* 13 (VBE/AF 1.0P) VBE/AF initializes accelerator hardware
* 12 reserved for VBE/AF
* 11 (VBE v3.0) user user-specified CRTC refresh rate values
* 10-9 reserved for future expansion
* 8-0 video mode number (0xxh are non-VESA modes, 1xxh are VESA-defined)
*
* see http://www.ctyme.com/intr/rb-0274.htm
*/
This is true for the call to set mode (vbe_104f02), but the spec does not say this for the get mode info call (104f01). It would be odd to pass in these additional bits when the caller just wants to get info on the given mode.
But if I want more information's about mode 0x101 with linear framebuffer support - thats the only way to get it. Also this is triggered by src/bootsplash.c so it seems to be a valid use-case.
Does this mean you will not merge it?
--- Christian Gmeiner, MSc
This commit adds a simple mode setting stub to the geode driver part. In later commits mode setting will be completed.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/geodevga.c | 26 ++++++++++++++++++++++++++ vgasrc/geodevga.h | 1 + vgasrc/vgahw.h | 2 ++ 3 files changed, 29 insertions(+)
diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index a1a79c9..867ad87 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -43,6 +43,12 @@ static struct geodevga_mode { 0x11A, { MM_DIRECT, 1280, 1024, 16, 8, 16, SEG_GRAPH } }, };
+static int is_geodevga_mode(struct vgamode_s *vmode_g) +{ + return (vmode_g >= &geodevga_modes[0].info + && vmode_g <= &geodevga_modes[ARRAY_SIZE(geodevga_modes)-1].info); +} + struct vgamode_s *geodevga_find_mode(int mode) { struct geodevga_mode *m = geodevga_modes; @@ -259,6 +265,26 @@ int vp_setup(void) return 0; }
+/**************************************************************** + * Mode setting + ****************************************************************/ + +int geodevga_set_mode(struct vgamode_s *vmode_g, int flags) +{ + if (! is_geodevga_mode(vmode_g)) + return stdvga_set_mode(vmode_g, flags); + + u16 width = GET_GLOBAL(vmode_g->width); + u16 height = GET_GLOBAL(vmode_g->height); + u8 depth = GET_GLOBAL(vmode_g->depth); + + dprintf(1, "Setting up VESA mode %ux%ux%u\n", width, height, depth); + + /* TODO stub */ + + return -1; +} + static u8 geode_crtc_01[] VAR16 = { 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, diff --git a/vgasrc/geodevga.h b/vgasrc/geodevga.h index fe149df..2651640 100644 --- a/vgasrc/geodevga.h +++ b/vgasrc/geodevga.h @@ -67,5 +67,6 @@ int geodevga_init(); struct vgamode_s *geodevga_find_mode(int mode); void geodevga_list_modes(u16 seg, u16 *dest, u16 *last); +int geodevga_set_mode(struct vgamode_s *vmode_g, int flags);
#endif diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h index 1842934..c903109 100644 --- a/vgasrc/vgahw.h +++ b/vgasrc/vgahw.h @@ -24,6 +24,8 @@ static inline int vgahw_set_mode(struct vgamode_s *vmode_g, int flags) { return clext_set_mode(vmode_g, flags); if (CONFIG_VGA_BOCHS) return bochsvga_set_mode(vmode_g, flags); + if (CONFIG_VGA_GEODELX) + return geodevga_set_mode(vmode_g, flags); return stdvga_set_mode(vmode_g, flags); }
On Sat, Sep 01, 2012 at 05:13:00PM +0200, Christian Gmeiner wrote:
This commit adds a simple mode setting stub to the geode driver part. In later commits mode setting will be completed.
I'm okay with patches 6, 7, and 9. However, I'm not sure what the gain is in advertising modes that can't actually be switched to. I'd prefer to commit them all once actual support is ready.
-Kevin
2012/9/3 Kevin O'Connor kevin@koconnor.net:
On Sat, Sep 01, 2012 at 05:13:00PM +0200, Christian Gmeiner wrote:
This commit adds a simple mode setting stub to the geode driver part. In later commits mode setting will be completed.
I'm okay with patches 6, 7, and 9. However, I'm not sure what the gain is in advertising modes that can't actually be switched to. I'd prefer to commit them all once actual support is ready.
I am okay with this. Will come up with the mode setting patches in the next days. --- Christian Gmeiner, MSc
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/geodevga.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index 867ad87..a0cbe1f 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -221,6 +221,10 @@ static int dc_setup(void)
u32 fb_size = framebuffer_size(); // in byte dprintf(1, "%d KB of video memory at 0x%08x\n", fb_size / 1024, fb); + + /* update VBE variables */ + SET_VGA(VBE_framebuffer, fb); + SET_VGA(VBE_total_memory, fb_size / 1024 / 64); // number of 64K blocks
return 0; }
This struct is used to store some PCI BAR values, which are used during hw init.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/geodevga.c | 66 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 25 deletions(-)
diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index a0cbe1f..17d5a37 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -138,6 +138,17 @@ static void geode_memWrite(u32 addr, u32 and, u32 or ) ); }
+/**************************************************************** + * Helper functions + ****************************************************************/ + +struct geode { + u32 fb; + u32 dc; + u32 vp; +}; +struct geode geode VAR16; + static int legacyio_check(void) { int ret=0; @@ -195,35 +206,33 @@ static u32 framebuffer_size(void) */ static int dc_setup(void) { - u32 fb, dc_fb, dc_base; + u32 dc_fb;
dprintf(2, "DC_SETUP\n");
- dc_base = pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_2); - geode_memWrite(dc_base + DC_UNLOCK, 0x0, DC_LOCK_UNLOCK); + geode_memWrite(geode.dc + DC_UNLOCK, 0x0, DC_LOCK_UNLOCK);
/* zero memory config */ - geode_memWrite(dc_base + DC_FB_ST_OFFSET, 0x0, 0x0); - geode_memWrite(dc_base + DC_CB_ST_OFFSET, 0x0, 0x0); - geode_memWrite(dc_base + DC_CURS_ST_OFFSET, 0x0, 0x0); + geode_memWrite(geode.dc + DC_FB_ST_OFFSET, 0x0, 0x0); + geode_memWrite(geode.dc + DC_CB_ST_OFFSET, 0x0, 0x0); + geode_memWrite(geode.dc + DC_CURS_ST_OFFSET, 0x0, 0x0);
/* read fb-bar from pci, then point dc to the fb base */ - dc_fb = geode_memRead(dc_base + DC_GLIU0_MEM_OFFSET); - fb = pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_0); - if (fb!=dc_fb) { - geode_memWrite(dc_base + DC_GLIU0_MEM_OFFSET, 0x0, fb); + dc_fb = geode_memRead(geode.dc + DC_GLIU0_MEM_OFFSET); + if (geode.fb != dc_fb) { + geode_memWrite(geode.dc + DC_GLIU0_MEM_OFFSET, 0x0, geode.fb); }
- geode_memWrite(dc_base + DC_DISPLAY_CFG, DC_CFG_MSK, DC_GDEN+DC_TRUP); - geode_memWrite(dc_base + DC_GENERAL_CFG, 0, DC_VGAE); + geode_memWrite(geode.dc + DC_DISPLAY_CFG, DC_CFG_MSK, DC_GDEN+DC_TRUP); + geode_memWrite(geode.dc + DC_GENERAL_CFG, 0, DC_VGAE);
- geode_memWrite(dc_base + DC_UNLOCK, 0x0, DC_LOCK_LOCK); + geode_memWrite(geode.dc + DC_UNLOCK, 0x0, DC_LOCK_LOCK);
u32 fb_size = framebuffer_size(); // in byte - dprintf(1, "%d KB of video memory at 0x%08x\n", fb_size / 1024, fb); + dprintf(1, "%d KB of video memory at 0x%08x\n", fb_size / 1024, geode.fb);
/* update VBE variables */ - SET_VGA(VBE_framebuffer, fb); + SET_VGA(VBE_framebuffer, geode.fb); SET_VGA(VBE_total_memory, fb_size / 1024 / 64); // number of 64K blocks
return 0; @@ -237,7 +246,7 @@ static int dc_setup(void) */ int vp_setup(void) { - u32 reg,vp; + u32 reg;
dprintf(2,"VP_SETUP\n"); /* set output to crt and RGB/YUV */ @@ -246,24 +255,21 @@ int vp_setup(void) else geode_msrWrite(VP_MSR_CONFIG_LX, ~0, ~0xf8, 0, 0);
- /* get vp register base from pci */ - vp = pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_3); - /* Set mmio registers * there may be some timing issues here, the reads seem * to slow things down enough work reliably */
- reg = geode_memRead(vp+VP_MISC); + reg = geode_memRead(geode.vp + VP_MISC); dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg); - geode_memWrite(vp+VP_MISC,0,VP_BYP_BOTH); - reg = geode_memRead(vp+VP_MISC); + geode_memWrite(geode.vp + VP_MISC,0,VP_BYP_BOTH); + reg = geode_memRead(geode.vp + VP_MISC); dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg);
- reg = geode_memRead(vp+VP_DCFG); + reg = geode_memRead(geode.vp + VP_DCFG); dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg); - geode_memWrite(vp+VP_DCFG, ~0,VP_CRT_EN+VP_HSYNC_EN+VP_VSYNC_EN+VP_DAC_BL_EN+VP_CRT_SKEW); - reg = geode_memRead(vp+VP_DCFG); + geode_memWrite(geode.vp + VP_DCFG, ~0,VP_CRT_EN+VP_HSYNC_EN+VP_VSYNC_EN+VP_DAC_BL_EN+VP_CRT_SKEW); + reg = geode_memRead(geode.vp + VP_DCFG); dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg);
return 0; @@ -374,6 +380,16 @@ int geodevga_init(void) if (GET_GLOBAL(VgaBDF) < 0) // Device should be at 00:01.1 SET_VGA(VgaBDF, pci_to_bdf(0, 1, 1)); + + // setup geode struct which is used for register access + geode.fb = pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_0); + geode.dc = pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_2); + geode.vp = pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_3); + + dprintf(1, "fb addr: 0x%08x\n", geode.fb); + dprintf(1, "dc addr: 0x%08x\n", geode.dc); + dprintf(1, "vp addr: 0x%08x\n", geode.vp); + ret |= vp_setup(); ret |= dc_setup();
There is no reason to have a return code for vp_setup() and dc_setup(). So get rid of them.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/geodevga.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index 17d5a37..61b54d1 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -204,7 +204,7 @@ static u32 framebuffer_size(void) /* Set up the dc (display controller) portion of the geodelx * The dc provides hardware support for VGA graphics. */ -static int dc_setup(void) +static void dc_setup(void) { u32 dc_fb;
@@ -234,8 +234,6 @@ static int dc_setup(void) /* update VBE variables */ SET_VGA(VBE_framebuffer, geode.fb); SET_VGA(VBE_total_memory, fb_size / 1024 / 64); // number of 64K blocks - - return 0; }
/* Setup the vp (video processor) portion of the geodelx @@ -244,7 +242,7 @@ static int dc_setup(void) * The High Mem Access virtual register is used to configure the * pci mmio bar from 16bit friendly io space. */ -int vp_setup(void) +static void vp_setup(void) { u32 reg;
@@ -271,8 +269,6 @@ int vp_setup(void) geode_memWrite(geode.vp + VP_DCFG, ~0,VP_CRT_EN+VP_HSYNC_EN+VP_VSYNC_EN+VP_DAC_BL_EN+VP_CRT_SKEW); reg = geode_memRead(geode.vp + VP_DCFG); dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg); - - return 0; }
/**************************************************************** @@ -390,8 +386,8 @@ int geodevga_init(void) dprintf(1, "dc addr: 0x%08x\n", geode.dc); dprintf(1, "vp addr: 0x%08x\n", geode.vp);
- ret |= vp_setup(); - ret |= dc_setup(); + vp_setup(); + dc_setup();
- return ret; + return 0; }
This change introduces some helper functions, which are making the code more readable and easier to debug.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/geodevga.c | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-)
diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index 61b54d1..21b7eff 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -149,6 +149,32 @@ struct geode { }; struct geode geode VAR16;
+static u32 read_dc(int reg) +{ + u32 val = geode_memRead(geode.dc + reg); + dprintf(4, "%s(0x%08x) = 0x%08x\n", __func__, geode.dc + reg, val); + return val; +} + +static u32 read_vp(int reg) +{ + u32 val = geode_memRead(geode.vp + reg); + dprintf(4, "%s(0x%08x) = 0x%08x\n", __func__, geode.vp + reg, val); + return val; +} + +static void write_dc(int reg, u32 val) +{ + dprintf(4, "%s(0x%08x, 0x%08x)\n", __func__, geode.dc + reg, val); + geode_memWrite(geode.dc + reg, 0x0, val); +} + +static void write_vp(int reg, u32 val) +{ + dprintf(4, "%s(0x%08x, 0x%08x)\n", __func__, geode.vp + reg, val); + geode_memWrite(geode.vp + reg, 0x0, val); +} + static int legacyio_check(void) { int ret=0; @@ -210,23 +236,23 @@ static void dc_setup(void)
dprintf(2, "DC_SETUP\n");
- geode_memWrite(geode.dc + DC_UNLOCK, 0x0, DC_LOCK_UNLOCK); + write_dc(DC_UNLOCK, DC_LOCK_UNLOCK);
/* zero memory config */ - geode_memWrite(geode.dc + DC_FB_ST_OFFSET, 0x0, 0x0); - geode_memWrite(geode.dc + DC_CB_ST_OFFSET, 0x0, 0x0); - geode_memWrite(geode.dc + DC_CURS_ST_OFFSET, 0x0, 0x0); + write_dc(DC_FB_ST_OFFSET, 0x0); + write_dc(DC_CB_ST_OFFSET, 0x0); + write_dc(DC_CURS_ST_OFFSET, 0x0);
/* read fb-bar from pci, then point dc to the fb base */ - dc_fb = geode_memRead(geode.dc + DC_GLIU0_MEM_OFFSET); + dc_fb = read_dc(DC_GLIU0_MEM_OFFSET); if (geode.fb != dc_fb) { - geode_memWrite(geode.dc + DC_GLIU0_MEM_OFFSET, 0x0, geode.fb); + write_dc(DC_GLIU0_MEM_OFFSET, geode.fb); }
geode_memWrite(geode.dc + DC_DISPLAY_CFG, DC_CFG_MSK, DC_GDEN+DC_TRUP); - geode_memWrite(geode.dc + DC_GENERAL_CFG, 0, DC_VGAE); + write_dc(DC_GENERAL_CFG, DC_VGAE);
- geode_memWrite(geode.dc + DC_UNLOCK, 0x0, DC_LOCK_LOCK); + write_dc(DC_UNLOCK, DC_LOCK_LOCK);
u32 fb_size = framebuffer_size(); // in byte dprintf(1, "%d KB of video memory at 0x%08x\n", fb_size / 1024, geode.fb); @@ -258,16 +284,16 @@ static void vp_setup(void) * to slow things down enough work reliably */
- reg = geode_memRead(geode.vp + VP_MISC); + reg = read_vp(VP_MISC); dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg); - geode_memWrite(geode.vp + VP_MISC,0,VP_BYP_BOTH); - reg = geode_memRead(geode.vp + VP_MISC); + write_vp(VP_MISC, VP_BYP_BOTH); + reg = read_vp(VP_MISC); dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg);
- reg = geode_memRead(geode.vp + VP_DCFG); + reg = read_vp(VP_DCFG); dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg); geode_memWrite(geode.vp + VP_DCFG, ~0,VP_CRT_EN+VP_HSYNC_EN+VP_VSYNC_EN+VP_DAC_BL_EN+VP_CRT_SKEW); - reg = geode_memRead(geode.vp + VP_DCFG); + reg = read_vp(VP_DCFG); dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg); }
This is the first change to have a working Flat Panel support.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/geodevga.c | 15 ++++++++++++--- vgasrc/geodevga.h | 5 +++++ 2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index 21b7eff..8520f2e 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -270,14 +270,23 @@ static void dc_setup(void) */ static void vp_setup(void) { + union u64_u32_u msr; + u32 msr_addr; u32 reg;
dprintf(2,"VP_SETUP\n"); - /* set output to crt and RGB/YUV */ + if (CONFIG_VGA_GEODEGX2) - geode_msrWrite(VP_MSR_CONFIG_GX2, ~0, ~0xf8, 0, 0); + msr_addr = VP_MSR_CONFIG_GX2; else - geode_msrWrite(VP_MSR_CONFIG_LX, ~0, ~0xf8, 0, 0); + msr_addr = VP_MSR_CONFIG_LX; + + /* set output to crc and flat panel (RGB/YUV) */ + msr = geode_msrRead(msr_addr); + msr.lo &= ~VP_MSR_CONFIG_FMT; // mask out FMT (bits 5:3) + msr.lo |= VP_MSR_CONFIG_FMT_FP; // flat panel + msr.lo |= VP_MSR_CONFIG_FPC; // Simultaneous Flat Panel and CRT + geode_msrWrite(msr_addr, 0x0, 0x0, msr.hi, msr.lo);
/* Set mmio registers * there may be some timing issues here, the reads seem diff --git a/vgasrc/geodevga.h b/vgasrc/geodevga.h index 2651640..ccc23d0 100644 --- a/vgasrc/geodevga.h +++ b/vgasrc/geodevga.h @@ -33,6 +33,11 @@ #define VP_MSR_CONFIG_GX2 0xc0002001 /* GX2 */ #define VP_MSR_CONFIG_LX 0x48002001 /* LX */
+/* VP_MSR_CONFIG bits */ +#define VP_MSR_CONFIG_FMT_FP (1 << 3) +#define VP_MSR_CONFIG_FPC (1 << 15) +#define VP_MSR_CONFIG_FMT ((1 << 3) | (1 << 4) | (1 << 5)) + /* DC REG OFFSET */ #define DC_UNLOCK 0x0 #define DC_GENERAL_CFG 0x4
On Sat, Sep 01, 2012 at 05:13:05PM +0200, Christian Gmeiner wrote:
This is the first change to have a working Flat Panel support.
What's the impact of this change (and patch 15) to users that don't have a flat panel?
-Kevin
2012/9/3 Kevin O'Connor kevin@koconnor.net:
On Sat, Sep 01, 2012 at 05:13:05PM +0200, Christian Gmeiner wrote:
This is the first change to have a working Flat Panel support.
What's the impact of this change (and patch 15) to users that don't have a flat panel?
I think that nothing will break etc. I also had no VGA connector stuff on my development board until yesterday. But we can make a config option to select which outputs to use.
--- Christian Gmeiner, MSc
Add functions, defines etc. to be able to control the power state of the Flat Panel. Turn it on on per default.
Signed-off-by: Christian Gmeiner christian.gmeiner@gmail.com --- vgasrc/geodevga.c | 20 ++++++++++++++++++++ vgasrc/geodevga.h | 5 +++++ 2 files changed, 25 insertions(+)
diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index 8520f2e..facaafd 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -149,6 +149,8 @@ struct geode { }; struct geode geode VAR16;
+#define VP_FP_START 0x400 + static u32 read_dc(int reg) { u32 val = geode_memRead(geode.dc + reg); @@ -163,6 +165,13 @@ static u32 read_vp(int reg) return val; }
+static u32 read_fp(int reg) +{ + u32 val = geode_memRead(geode.vp + VP_FP_START +reg); + dprintf(4, "%s(0x%08x) = 0x%08x\n", __func__, geode.vp + VP_FP_START + reg, val); + return val; +} + static void write_dc(int reg, u32 val) { dprintf(4, "%s(0x%08x, 0x%08x)\n", __func__, geode.dc + reg, val); @@ -175,6 +184,12 @@ static void write_vp(int reg, u32 val) geode_memWrite(geode.vp + reg, 0x0, val); }
+static void write_fp(int reg, u32 val) +{ + dprintf(4, "%s(0x%08x, 0x%08x)\n", __func__, geode.vp + VP_FP_START + reg, val); + geode_memWrite(geode.vp + VP_FP_START + reg, 0x0, val); +} + static int legacyio_check(void) { int ret=0; @@ -304,6 +319,11 @@ static void vp_setup(void) geode_memWrite(geode.vp + VP_DCFG, ~0,VP_CRT_EN+VP_HSYNC_EN+VP_VSYNC_EN+VP_DAC_BL_EN+VP_CRT_SKEW); reg = read_vp(VP_DCFG); dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg); + + /* turn the panel on (if it isn't already) */ + reg = read_fp(FP_PM); + reg |= FP_PM_P; + write_fp(FP_PM, reg); }
/**************************************************************** diff --git a/vgasrc/geodevga.h b/vgasrc/geodevga.h index ccc23d0..358c9da 100644 --- a/vgasrc/geodevga.h +++ b/vgasrc/geodevga.h @@ -52,6 +52,8 @@ #define VP_DCFG 0x8 #define VP_MISC 0x50
+/* FP REG OFFSET */ +#define FP_PM 0x10
/* DC bits */ #define DC_VGAE (1 << 7) @@ -66,6 +68,9 @@ #define VP_CRT_SKEW (1 << 16) #define VP_BYP_BOTH (1 << 0)
+/* FP bits */ +#define FP_PM_P (1 << 24) /* panel power ctl */ + /* Mask */ #define DC_CFG_MSK 0xf000a6
On Sat, Sep 01, 2012 at 05:12:52PM +0200, Christian Gmeiner wrote:
There is no reason to access the DC registers via VGA memory mapping if we could the access via memory.
The patch series looks okay to me. Are these patches specific to the board you have, or will they work with all the boards currently supported by the SeaVGABIOS Geode code?
-Kevin
Am 02.09.2012 19:59 schrieb "Kevin O'Connor" kevin@koconnor.net:
On Sat, Sep 01, 2012 at 05:12:52PM +0200, Christian Gmeiner wrote:
There is no reason to access the DC registers via VGA memory mapping if we could the access via memory.
The patch series looks okay to me. Are these patches specific to the board you have, or will they work with all the boards currently supported by the SeaVGABIOS Geode code?
The patches are for all supported Geode devices. I try to get access to GX hardware so that I could test the patches in real hardware. I am working on a lx800 hardware. I am waiting for the edid patches get merged to come up with more patches :)
-Kevin
On Sat, Sep 01, 2012 at 05:12:52PM +0200, Christian Gmeiner wrote:
There is no reason to access the DC registers via VGA memory mapping if we could the access via memory.
Thanks. I pushed patches 1, 2, 3, 5, 10, 11, 12, 13 from your series.
-Kevin