aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorJordan Crouse <jordan.crouse@amd.com>2006-12-08 05:40:54 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:29:08 -0500
commitab1db0cfcf69f94a5c6831db230982cd6bbeb2e1 (patch)
tree9c8178a6c5a0f5a62498cb47648046ae22a30ec8 /drivers/video
parentf378819a19e2b9639f17a1a82c5e12adc9512390 (diff)
[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>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/geode/display_gx.h4
-rw-r--r--drivers/video/geode/gxfb_core.c10
-rw-r--r--drivers/video/geode/video_gx.c76
-rw-r--r--drivers/video/geode/video_gx.h16
4 files changed, 95 insertions, 11 deletions
diff --git a/drivers/video/geode/display_gx.h b/drivers/video/geode/display_gx.h
index e962c7679d08..ba0ccc82bf22 100644
--- a/drivers/video/geode/display_gx.h
+++ b/drivers/video/geode/display_gx.h
@@ -16,6 +16,10 @@ int gx_line_delta(int xres, int bpp);
16 16
17extern struct geode_dc_ops gx_dc_ops; 17extern struct geode_dc_ops gx_dc_ops;
18 18
19/* MSR that tells us if a TFT or CRT is attached */
20#define GLD_MSR_CONFIG 0xC0002001
21#define GLD_MSR_CONFIG_FMT_FP 0x01
22
19/* Display controller registers */ 23/* Display controller registers */
20 24
21#define DC_UNLOCK 0x00 25#define DC_UNLOCK 0x00
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
index 742fd04178c3..1e0d47ea0e43 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/geode/gxfb_core.c
@@ -308,6 +308,7 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
308 struct geodefb_par *par; 308 struct geodefb_par *par;
309 struct fb_info *info; 309 struct fb_info *info;
310 int ret; 310 int ret;
311 unsigned long val;
311 312
312 info = gxfb_init_fbinfo(&pdev->dev); 313 info = gxfb_init_fbinfo(&pdev->dev);
313 if (!info) 314 if (!info)
@@ -323,6 +324,15 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
323 goto err; 324 goto err;
324 } 325 }
325 326
327 /* Figure out if this is a TFT or CRT part */
328
329 rdmsrl(GLD_MSR_CONFIG, val);
330
331 if (val & GLD_MSR_CONFIG_FMT_FP)
332 par->enable_crt = 0;
333 else
334 par->enable_crt = 1;
335
326 ret = fb_find_mode(&info->var, info, mode_option, 336 ret = fb_find_mode(&info->var, info, mode_option,
327 gx_modedb, ARRAY_SIZE(gx_modedb), NULL, 16); 337 gx_modedb, ARRAY_SIZE(gx_modedb), NULL, 16);
328 if (ret == 0 || ret == 4) { 338 if (ret == 0 || ret == 4) {
diff --git a/drivers/video/geode/video_gx.c b/drivers/video/geode/video_gx.c
index 616ce339c5fa..bee0741794a3 100644
--- a/drivers/video/geode/video_gx.c
+++ b/drivers/video/geode/video_gx.c
@@ -175,10 +175,62 @@ static void gx_set_dclk_frequency(struct fb_info *info)
175 } while (timeout-- && !(dotpll & MSR_GLCP_DOTPLL_LOCK)); 175 } while (timeout-- && !(dotpll & MSR_GLCP_DOTPLL_LOCK));
176} 176}
177 177
178static void
179gx_configure_tft(struct fb_info *info)
180{
181 struct geodefb_par *par = info->par;
182 unsigned long val;
183 unsigned long fp;
184
185 /* Set up the DF pad select MSR */
186
187 rdmsrl(GX_VP_MSR_PAD_SELECT, val);
188 val &= ~GX_VP_PAD_SELECT_MASK;
189 val |= GX_VP_PAD_SELECT_TFT;
190 wrmsrl(GX_VP_MSR_PAD_SELECT, val);
191
192 /* Turn off the panel */
193
194 fp = readl(par->vid_regs + GX_FP_PM);
195 fp &= ~GX_FP_PM_P;
196 writel(fp, par->vid_regs + GX_FP_PM);
197
198 /* Set timing 1 */
199
200 fp = readl(par->vid_regs + GX_FP_PT1);
201 fp &= GX_FP_PT1_VSIZE_MASK;
202 fp |= info->var.yres << GX_FP_PT1_VSIZE_SHIFT;
203 writel(fp, par->vid_regs + GX_FP_PT1);
204
205 /* Timing 2 */
206 /* Set bits that are always on for TFT */
207
208 fp = 0x0F100000;
209
210 /* Add sync polarity */
211
212 if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
213 fp |= GX_FP_PT2_VSP;
214
215 if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
216 fp |= GX_FP_PT2_HSP;
217
218 writel(fp, par->vid_regs + GX_FP_PT2);
219
220 /* Set the dither control */
221 writel(0x70, par->vid_regs + GX_FP_DFC);
222
223 /* Turn on the device */
224
225 fp = readl(par->vid_regs + GX_FP_PM);
226 fp |= GX_FP_PM_P;
227 writel(fp, par->vid_regs + GX_FP_PM);
228}
229
178static void gx_configure_display(struct fb_info *info) 230static void gx_configure_display(struct fb_info *info)
179{ 231{
180 struct geodefb_par *par = info->par; 232 struct geodefb_par *par = info->par;
181 u32 dcfg, fp_pm, misc; 233 u32 dcfg, misc;
182 234
183 /* Set up the MISC register */ 235 /* Set up the MISC register */
184 236
@@ -222,11 +274,10 @@ static void gx_configure_display(struct fb_info *info)
222 274
223 writel(dcfg, par->vid_regs + GX_DCFG); 275 writel(dcfg, par->vid_regs + GX_DCFG);
224 276
225 /* Power on flat panel. */ 277 /* Set up the flat panel (if it is enabled) */
226 278
227 fp_pm = readl(par->vid_regs + GX_FP_PM); 279 if (par->enable_crt == 0)
228 fp_pm |= GX_FP_PM_P; 280 gx_configure_tft(info);
229 writel(fp_pm, par->vid_regs + GX_FP_PM);
230} 281}
231 282
232static int gx_blank_display(struct fb_info *info, int blank_mode) 283static 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)
267 writel(dcfg, par->vid_regs + GX_DCFG); 318 writel(dcfg, par->vid_regs + GX_DCFG);
268 319
269 /* Power on/off flat panel. */ 320 /* Power on/off flat panel. */
270 fp_pm = readl(par->vid_regs + GX_FP_PM); 321
271 if (blank_mode == FB_BLANK_POWERDOWN) 322 if (par->enable_crt == 0) {
272 fp_pm &= ~GX_FP_PM_P; 323 fp_pm = readl(par->vid_regs + GX_FP_PM);
273 else 324 if (blank_mode == FB_BLANK_POWERDOWN)
274 fp_pm |= GX_FP_PM_P; 325 fp_pm &= ~GX_FP_PM_P;
275 writel(fp_pm, par->vid_regs + GX_FP_PM); 326 else
327 fp_pm |= GX_FP_PM_P;
328 writel(fp_pm, par->vid_regs + GX_FP_PM);
329 }
276 330
277 return 0; 331 return 0;
278} 332}
diff --git a/drivers/video/geode/video_gx.h b/drivers/video/geode/video_gx.h
index 238181a7d536..8f1e85bfa945 100644
--- a/drivers/video/geode/video_gx.h
+++ b/drivers/video/geode/video_gx.h
@@ -13,6 +13,11 @@
13 13
14extern struct geode_vid_ops gx_vid_ops; 14extern struct geode_vid_ops gx_vid_ops;
15 15
16/* GX Flatpanel control MSR */
17#define GX_VP_MSR_PAD_SELECT 0x2011
18#define GX_VP_PAD_SELECT_MASK 0x3FFFFFFF
19#define GX_VP_PAD_SELECT_TFT 0x1FFFFFFF
20
16/* Geode GX video processor registers */ 21/* Geode GX video processor registers */
17 22
18#define GX_DCFG 0x0008 23#define GX_DCFG 0x0008
@@ -36,9 +41,20 @@ extern struct geode_vid_ops gx_vid_ops;
36#define GX_MISC_A_PWRDN 0x00000800 41#define GX_MISC_A_PWRDN 0x00000800
37 42
38/* Geode GX flat panel display control registers */ 43/* Geode GX flat panel display control registers */
44
45#define GX_FP_PT1 0x0400
46#define GX_FP_PT1_VSIZE_MASK 0x7FF0000
47#define GX_FP_PT1_VSIZE_SHIFT 16
48
49#define GX_FP_PT2 0x408
50#define GX_FP_PT2_VSP (1 << 23)
51#define GX_FP_PT2_HSP (1 << 22)
52
39#define GX_FP_PM 0x410 53#define GX_FP_PM 0x410
40# define GX_FP_PM_P 0x01000000 54# define GX_FP_PM_P 0x01000000
41 55
56#define GX_FP_DFC 0x418
57
42/* Geode GX clock control MSRs */ 58/* Geode GX clock control MSRs */
43 59
44#define MSR_GLCP_SYS_RSTPLL 0x4c000014 60#define MSR_GLCP_SYS_RSTPLL 0x4c000014