Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab1db0cf authored by Jordan Crouse's avatar Jordan Crouse Committed by Linus Torvalds
Browse files

[PATCH] gxfb: Support flat panel timings



Support TFT panels by correctly setting up the flat panel registers

[akpm@osdl.org: cleanups]
Signed-off-by: default avatarJordan Crouse <jordan.crouse@amd.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Acked-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f378819a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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
+10 −0
Original line number Diff line number Diff line
@@ -308,6 +308,7 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
	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_dev *pdev, const struct pci_device_id *i
		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) {
+65 −11
Original line number Diff line number Diff line
@@ -175,10 +175,62 @@ static void gx_set_dclk_frequency(struct fb_info *info)
	} 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)
{
	struct geodefb_par *par = info->par;
	u32 dcfg, fp_pm, misc;
	u32 dcfg, misc;

	/* 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);

	/* Power on flat panel. */
	/* Set up the flat panel (if it is enabled) */

	fp_pm = readl(par->vid_regs + GX_FP_PM);
	fp_pm |= GX_FP_PM_P;
	writel(fp_pm, par->vid_regs + GX_FP_PM);
	if (par->enable_crt == 0)
		gx_configure_tft(info);
}

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);

	/* Power on/off flat panel. */

	if (par->enable_crt == 0) {
		fp_pm = readl(par->vid_regs + GX_FP_PM);
		if (blank_mode == FB_BLANK_POWERDOWN)
			fp_pm &= ~GX_FP_PM_P;
		else
			fp_pm |= GX_FP_PM_P;
		writel(fp_pm, par->vid_regs + GX_FP_PM);
	}

	return 0;
}
+16 −0
Original line number Diff line number Diff line
@@ -13,6 +13,11 @@

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 @@ extern struct geode_vid_ops gx_vid_ops;
#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