mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 16:54:20 +08:00
[PATCH] gxfb: Support flat panel timings
Support TFT panels by correctly setting up the flat panel registers [akpm@osdl.org: cleanups] Signed-off-by: Jordan Crouse <jordan.crouse@amd.com> Cc: "Antonino A. Daplas" <adaplas@pol.net> Acked-by: James Simmons <jsimmons@infradead.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
f378819a19
commit
ab1db0cfcf
@ -16,6 +16,10 @@ int gx_line_delta(int xres, int bpp);
|
|||||||
|
|
||||||
extern struct geode_dc_ops gx_dc_ops;
|
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 */
|
/* Display controller registers */
|
||||||
|
|
||||||
#define DC_UNLOCK 0x00
|
#define DC_UNLOCK 0x00
|
||||||
|
@ -308,6 +308,7 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
|
|||||||
struct geodefb_par *par;
|
struct geodefb_par *par;
|
||||||
struct fb_info *info;
|
struct fb_info *info;
|
||||||
int ret;
|
int ret;
|
||||||
|
unsigned long val;
|
||||||
|
|
||||||
info = gxfb_init_fbinfo(&pdev->dev);
|
info = gxfb_init_fbinfo(&pdev->dev);
|
||||||
if (!info)
|
if (!info)
|
||||||
@ -323,6 +324,15 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
|
|||||||
goto err;
|
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,
|
ret = fb_find_mode(&info->var, info, mode_option,
|
||||||
gx_modedb, ARRAY_SIZE(gx_modedb), NULL, 16);
|
gx_modedb, ARRAY_SIZE(gx_modedb), NULL, 16);
|
||||||
if (ret == 0 || ret == 4) {
|
if (ret == 0 || ret == 4) {
|
||||||
|
@ -175,10 +175,62 @@ static void gx_set_dclk_frequency(struct fb_info *info)
|
|||||||
} while (timeout-- && !(dotpll & MSR_GLCP_DOTPLL_LOCK));
|
} while (timeout-- && !(dotpll & MSR_GLCP_DOTPLL_LOCK));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gx_configure_tft(struct fb_info *info)
|
||||||
|
{
|
||||||
|
struct geodefb_par *par = info->par;
|
||||||
|
unsigned long val;
|
||||||
|
unsigned long fp;
|
||||||
|
|
||||||
|
/* Set up the DF pad select MSR */
|
||||||
|
|
||||||
|
rdmsrl(GX_VP_MSR_PAD_SELECT, val);
|
||||||
|
val &= ~GX_VP_PAD_SELECT_MASK;
|
||||||
|
val |= GX_VP_PAD_SELECT_TFT;
|
||||||
|
wrmsrl(GX_VP_MSR_PAD_SELECT, val);
|
||||||
|
|
||||||
|
/* Turn off the panel */
|
||||||
|
|
||||||
|
fp = readl(par->vid_regs + GX_FP_PM);
|
||||||
|
fp &= ~GX_FP_PM_P;
|
||||||
|
writel(fp, par->vid_regs + GX_FP_PM);
|
||||||
|
|
||||||
|
/* Set timing 1 */
|
||||||
|
|
||||||
|
fp = readl(par->vid_regs + GX_FP_PT1);
|
||||||
|
fp &= GX_FP_PT1_VSIZE_MASK;
|
||||||
|
fp |= info->var.yres << GX_FP_PT1_VSIZE_SHIFT;
|
||||||
|
writel(fp, par->vid_regs + GX_FP_PT1);
|
||||||
|
|
||||||
|
/* Timing 2 */
|
||||||
|
/* Set bits that are always on for TFT */
|
||||||
|
|
||||||
|
fp = 0x0F100000;
|
||||||
|
|
||||||
|
/* Add sync polarity */
|
||||||
|
|
||||||
|
if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
|
||||||
|
fp |= GX_FP_PT2_VSP;
|
||||||
|
|
||||||
|
if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
|
||||||
|
fp |= GX_FP_PT2_HSP;
|
||||||
|
|
||||||
|
writel(fp, par->vid_regs + GX_FP_PT2);
|
||||||
|
|
||||||
|
/* Set the dither control */
|
||||||
|
writel(0x70, par->vid_regs + GX_FP_DFC);
|
||||||
|
|
||||||
|
/* Turn on the device */
|
||||||
|
|
||||||
|
fp = readl(par->vid_regs + GX_FP_PM);
|
||||||
|
fp |= GX_FP_PM_P;
|
||||||
|
writel(fp, par->vid_regs + GX_FP_PM);
|
||||||
|
}
|
||||||
|
|
||||||
static void gx_configure_display(struct fb_info *info)
|
static void gx_configure_display(struct fb_info *info)
|
||||||
{
|
{
|
||||||
struct geodefb_par *par = info->par;
|
struct geodefb_par *par = info->par;
|
||||||
u32 dcfg, fp_pm, misc;
|
u32 dcfg, misc;
|
||||||
|
|
||||||
/* Set up the MISC register */
|
/* Set up the MISC register */
|
||||||
|
|
||||||
@ -222,11 +274,10 @@ static void gx_configure_display(struct fb_info *info)
|
|||||||
|
|
||||||
writel(dcfg, par->vid_regs + GX_DCFG);
|
writel(dcfg, par->vid_regs + GX_DCFG);
|
||||||
|
|
||||||
/* Power on flat panel. */
|
/* Set up the flat panel (if it is enabled) */
|
||||||
|
|
||||||
fp_pm = readl(par->vid_regs + GX_FP_PM);
|
if (par->enable_crt == 0)
|
||||||
fp_pm |= GX_FP_PM_P;
|
gx_configure_tft(info);
|
||||||
writel(fp_pm, par->vid_regs + GX_FP_PM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gx_blank_display(struct fb_info *info, int blank_mode)
|
static int gx_blank_display(struct fb_info *info, int blank_mode)
|
||||||
@ -267,12 +318,15 @@ static int gx_blank_display(struct fb_info *info, int blank_mode)
|
|||||||
writel(dcfg, par->vid_regs + GX_DCFG);
|
writel(dcfg, par->vid_regs + GX_DCFG);
|
||||||
|
|
||||||
/* Power on/off flat panel. */
|
/* Power on/off flat panel. */
|
||||||
fp_pm = readl(par->vid_regs + GX_FP_PM);
|
|
||||||
if (blank_mode == FB_BLANK_POWERDOWN)
|
if (par->enable_crt == 0) {
|
||||||
fp_pm &= ~GX_FP_PM_P;
|
fp_pm = readl(par->vid_regs + GX_FP_PM);
|
||||||
else
|
if (blank_mode == FB_BLANK_POWERDOWN)
|
||||||
fp_pm |= GX_FP_PM_P;
|
fp_pm &= ~GX_FP_PM_P;
|
||||||
writel(fp_pm, par->vid_regs + GX_FP_PM);
|
else
|
||||||
|
fp_pm |= GX_FP_PM_P;
|
||||||
|
writel(fp_pm, par->vid_regs + GX_FP_PM);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,11 @@
|
|||||||
|
|
||||||
extern struct geode_vid_ops gx_vid_ops;
|
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 */
|
/* Geode GX video processor registers */
|
||||||
|
|
||||||
#define GX_DCFG 0x0008
|
#define GX_DCFG 0x0008
|
||||||
@ -36,9 +41,20 @@ extern struct geode_vid_ops gx_vid_ops;
|
|||||||
#define GX_MISC_A_PWRDN 0x00000800
|
#define GX_MISC_A_PWRDN 0x00000800
|
||||||
|
|
||||||
/* Geode GX flat panel display control registers */
|
/* 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 0x410
|
||||||
# define GX_FP_PM_P 0x01000000
|
# define GX_FP_PM_P 0x01000000
|
||||||
|
|
||||||
|
#define GX_FP_DFC 0x418
|
||||||
|
|
||||||
/* Geode GX clock control MSRs */
|
/* Geode GX clock control MSRs */
|
||||||
|
|
||||||
#define MSR_GLCP_SYS_RSTPLL 0x4c000014
|
#define MSR_GLCP_SYS_RSTPLL 0x4c000014
|
||||||
|
Loading…
Reference in New Issue
Block a user