OLPC + Geode GX framebuffer updates
cover OLPC + Geode GX framebuffer updates
The following series adds updates to the GXFB driver to support the OLPC effort. These were sent before, but I didn't correctly follow up like I should have.
Signature · 4 lines
Jordan Crouse Senior Linux Engineer Advanced Micro Devices, Inc. <www.amd.com/embeddedprocessors>
PATCH 1/4 FB: Get the Geode GX frambuffer size from the BIOS
From: Jordan Crouse <[email protected]>
Use the Geode GX BIOS virtual registers to get the actual size of the framebuffer.
---
drivers/video/geode/display_gx.c | 15 ++++++++++++--- drivers/video/geode/display_gx.h | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-)
drivers/video/geode/display_gx.c +12 -3
@@ -21,10 +21,19 @@ #include <asm/delay.h>#include "geodefb.h" #include "display_gx.h" -int gx_frame_buffer_size (void ) +unsigned int gx_frame_buffer_size (void ) { -/* Assuming 16 MiB. */ -return 16 *1024 *1024 ; +unsigned int val; + +/* FB size is reported by a virtual register */ +/* Virtual register class = 0x02 */ +/* VG_MEM_SIZE(512Kb units) = 0x00 */ + +outw (0xFC53 ,0xAC1C ); +outw (0x0200 ,0xAC1C ); + + val = (unsigned int )(inw (0xAC1E )) &0xFFl ; +return (val <<19 ); }int gx_line_delta (int xres,int bpp)
drivers/video/geode/display_gx.h +1 -1
@@ -11,7 +11,7 @@#ifndef __DISPLAY_GX_H__#define __DISPLAY_GX_H__ -int gx_frame_buffer_size (void ); +unsigned int gx_frame_buffer_size (void );int gx_line_delta (int xres,int bpp);extern struct geode_dc_ops gx_dc_ops;
PATCH 2/4 gxfb: Fixups for the AMD Geode GX framebuffer driver
In reply to Jordan CrouseFrom: Jordan Crouse <[email protected]>
We cannot assume that the BIOS will be correctly setting up the hardware, so set some bits in various display registers to enable video output. Allow an advanced user to specify a frambuffer size, rather then probing the BIOS. All of these fixes were prompted by the OLPC effort.
---
drivers/video/geode/Kconfig | 20 ++++++++++++++++++++ drivers/video/geode/display_gx.c | 7 +++++++ drivers/video/geode/display_gx.h | 1 + drivers/video/geode/gxfb_core.c | 6 ++++++ drivers/video/geode/video_gx.c | 24 +++++++++++++++++++++++- drivers/video/geode/video_gx.h | 7 +++++++ 6 files changed, 64 insertions(+), 1 deletions(-)
drivers/video/geode/Kconfig +20 -0
@@ -23,6 +23,26 @@ config FB_GEODE_GX If unsure, say N. +config FB_GEODE_GX_SET_FBSIZE + bool "Manually specify the Geode GX framebuffer size" + depends on FB_GEODE_GX + default n + ---help--- + If you want to manually specify the size of your GX framebuffer, + say Y here, otherwise say N to dynamically probe it. + + Say N unless you know what you are doing. + +config FB_GEODE_GX_FBSIZE + hex "Size of the GX framebuffer, in bytes" + depends on FB_GEODE_GX_SET_FBSIZE + default "0x1600000" + ---help--- + Specify the size of the GX framebuffer. Normally, you will + want this to be MB aligned. Common values are 0x80000 (8MB) + and 0x1600000 (16MB). Don't change this unless you know what + you are doing + config FB_GEODE_GX1 tristate "AMD Geode GX1 framebuffer support (EXPERIMENTAL)" depends on FB && FB_GEODE && EXPERIMENTAL
drivers/video/geode/display_gx.c +7 -0
@@ -21,6 +21,11 @@ #include <asm/delay.h>#include "geodefb.h" #include "display_gx.h" +#ifdef CONFIG_FB_GEODE_GX_SET_FBSIZE +unsigned int gx_frame_buffer_size (void ) { +return CONFIG_FB_GEODE_GX_FBSIZE ; +} +#else unsigned int gx_frame_buffer_size (void ) {unsigned int val;
@@ -35,6 +40,7 @@ unsigned int gx_frame_buffer_size(void) val = (unsigned int )(inw (0xAC1E )) &0xFFl ; return (val << 19); } +#endif int gx_line_delta (int xres,int bpp) {
@@ -90,6 +96,7 @@ static void gx_set_mode(struct fb_info *writel (((info->var.xres * info->var.bits_per_pixel/8 ) >>3 ) +2 , par->dc_regs +DC_LINE_SIZE ); +/* Enable graphics and video data and unmask address lines. */ dcfg |=DC_DCFG_GDEN |DC_DCFG_VDEN |DC_DCFG_A20M |DC_DCFG_A18M ;
drivers/video/geode/display_gx.h +1 -0
@@ -93,4 +93,5 @@ #define DC_V_SYNC_TIMING 0x58#define DC_PAL_ADDRESS 0x70#define DC_PAL_DATA 0x74 +#define DC_GLIU0_MEM_OFFSET 0x84#endif /* !__DISPLAY_GX1_H__ */
drivers/video/geode/gxfb_core.c +6 -0
@@ -240,6 +240,12 @@ static int __init gxfb_map_video_memory(if (!info->screen_base)return -ENOMEM ; +/* Set the 16MB aligned base address of the graphics memory region +* in the display controller */ + +writel (info->fix.smem_start &0xFF000000 , + par->dc_regs +DC_GLIU0_MEM_OFFSET ); +dev_info (&dev->dev,"%d Kibyte of video memory at 0x%lx\n" , info->fix.smem_len /1024 , info->fix.smem_start);
drivers/video/geode/video_gx.c +23 -1
@@ -178,7 +178,21 @@ static void gx_set_dclk_frequency(structstatic void gx_configure_display (struct fb_info *info) {struct geodefb_par *par = info->par; -u32 dcfg, fp_pm; +u32 dcfg, fp_pm, misc; + +/* Set up the MISC register */ + + misc =readl (par->vid_regs +GX_MISC ); + +/* Power up the DAC */ + misc &= ~(GX_MISC_A_PWRDN |GX_MISC_DAC_PWRDN ); + +/* Disable gamma correction */ + misc |=GX_MISC_GAM_EN ; + +writel (misc, par->vid_regs +GX_MISC ); + +/* Write the display configuration */ dcfg =readl (par->vid_regs +GX_DCFG );
@@ -199,9 +213,17 @@ static void gx_configure_display(structif (info->var.sync &FB_SYNC_VERT_HIGH_ACT ) dcfg |=GX_DCFG_CRT_VSYNC_POL ; +/* Enable the display logic */ +/* Set up the DACS to blank normally */ + + dcfg |=GX_DCFG_CRT_EN |GX_DCFG_DAC_BL_EN ; + +/* Enable the external DAC VREF? */ +writel (dcfg, par->vid_regs +GX_DCFG );/* Power on flat panel. */ + fp_pm =readl (par->vid_regs +GX_FP_PM ); fp_pm |=GX_FP_PM_P ;writel (fp_pm, par->vid_regs +GX_FP_PM );
drivers/video/geode/video_gx.h +7 -0
@@ -28,6 +28,13 @@ # define GX_DCFG_VG_CK 0x00100000# define GX_DCFG_GV_GAM 0x00200000# define GX_DCFG_DAC_VREF 0x04000000 +/* Geode GX MISC video configuration */ + +#define GX_MISC 0x50 +#define GX_MISC_GAM_EN 0x00000001 +#define GX_MISC_DAC_PWRDN 0x00000400 +#define GX_MISC_A_PWRDN 0x00000800 +/* Geode GX flat panel display control registers */ #define GX_FP_PM 0x410# define GX_FP_PM_P 0x01000000
Re: [PATCH 2/4] [PATCH] gxfb: Fixups for the AMD Geode GX framebuffer driver
drivers/video/geode/display_gx.c unsigned int gx_frame_buffer_size(void) · line 43
Quoted 13 lines · Jordan Crouse
drivers/video/geode/display_gx.c +6
-0+#ifdef CONFIG_FB_GEODE_GX_SET_FBSIZE +unsigned int gx_frame_buffer_size (void ) { +return CONFIG_FB_GEODE_GX_FBSIZE ; +} +#else unsigned int gx_frame_buffer_size (void ) {unsigned int val;@@ -35,6 +40,7 @@ unsigned int gx_frame_buffer_size(void) val = (unsigned int )(inw (0xAC1E )) &0xFFl ; return (val << 19); } +#endif
GAK, please fix your firmware to follow your own docs 8). I mean while VGA emulation is hard honouring the frame buffer size query is trivial to stick in the GPL'd VSA firmware and belongs there.
PATCH 3/4 gxfb: Support flat panel timings
In reply to Jordan CrouseFrom: Jordan Crouse <[email protected]>
Support TFT panels by correctly setting up the flat panel registers
---
drivers/video/geode/display_gx.h | 4 ++ drivers/video/geode/gxfb_core.c | 10 +++++ drivers/video/geode/video_gx.c | 76 +++++++++++++++++++++++++++++++++----- drivers/video/geode/video_gx.h | 16 ++++++++ 4 files changed, 95 insertions(+), 11 deletions(-)
drivers/video/geode/display_gx.h +4 -0
@@ -16,6 +16,10 @@ int gx_line_delta(int xres, int bpp);extern struct geode_dc_ops gx_dc_ops; +/* MSR that tells us if a TFT or CRT is attached */ +#define GLD_MSR_CONFIG 0xC0002001 +#define GLD_MSR_CONFIG_FMT_FP 0x01 +/* Display controller registers */ #define DC_UNLOCK 0x00
drivers/video/geode/gxfb_core.c +10 -0
@@ -308,6 +308,7 @@ static int __init gxfb_probe(struct pci_struct geodefb_par *par;struct fb_info *info;int ret; +unsigned long val; info =gxfb_init_fbinfo (&pdev->dev);if (!info)
@@ -323,6 +324,15 @@ static int __init gxfb_probe(struct pci_ goto err; } +/* Figure out if this is a TFT or CRT part */ + +rdmsrl (GLD_MSR_CONFIG , val); + +if (val &GLD_MSR_CONFIG_FMT_FP ) + par->enable_crt =0 ; +else + par->enable_crt =1 ; + ret =fb_find_mode (&info->var, info, mode_option, gx_modedb,ARRAY_SIZE (gx_modedb),NULL ,16 );if (ret ==0 || ret ==4 ) {
drivers/video/geode/video_gx.c +65 -11
98 lines not on this page · raw message
drivers/video/geode/video_gx.h +16 -0
@@ -13,6 +13,11 @@ #define __VIDEO_GX_H__extern struct geode_vid_ops gx_vid_ops; +/* GX Flatpanel control MSR */ +#define GX_VP_MSR_PAD_SELECT 0x2011 +#define GX_VP_PAD_SELECT_MASK 0x3FFFFFFF +#define GX_VP_PAD_SELECT_TFT 0x1FFFFFFF +/* Geode GX video processor registers */ #define GX_DCFG 0x0008
@@ -36,9 +41,20 @@ #define GX_MISC_DAC_PWRDN 0x00000400#define GX_MISC_A_PWRDN 0x00000800/* Geode GX flat panel display control registers */ + +#define GX_FP_PT1 0x0400 +#define GX_FP_PT1_VSIZE_MASK 0x7FF0000 +#define GX_FP_PT1_VSIZE_SHIFT 16 + +#define GX_FP_PT2 0x408 +#define GX_FP_PT2_VSP (1 << 23) +#define GX_FP_PT2_HSP (1 << 22) +#define GX_FP_PM 0x410# define GX_FP_PM_P 0x01000000 +#define GX_FP_DFC 0x418 +/* Geode GX clock control MSRs */ #define MSR_GLCP_SYS_RSTPLL 0x4c000014
PATCH 4/4 gxfb: Add timings for the OLPC LCD
In reply to Jordan CrouseFrom: Jordan Crouse <[email protected]>
Add a mode for the OLPC LCD.
---
drivers/video/geode/gxfb_core.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
drivers/video/geode/gxfb_core.c +3 -0
@@ -103,6 +103,9 @@ static const struct fb_videomode __initd {NULL ,85 ,1600 ,1200 ,4357 ,304 ,64 ,46 ,1 ,192 ,3 ,FB_SYNC_HOR_HIGH_ACT |FB_SYNC_VERT_HIGH_ACT , FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, + { "OLPC-1", 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3, +FB_SYNC_HOR_HIGH_ACT |FB_SYNC_VERT_HIGH_ACT , + FB_VMODE_NONINTERLACED, 0 } };static int gxfb_check_var (struct fb_var_screeninfo *var,struct fb_info *info)