diff options
author | Andres Salomon <dilinger@queued.net> | 2008-04-28 05:14:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 11:58:36 -0400 |
commit | ab06aaf6a6d5de896e4c52e158be2881036cbee9 (patch) | |
tree | 3d79964d83d71f2e77955e5b4dada8bec5912c40 /drivers/video/geode | |
parent | fa20c8a6e520d9ccd68c8101155ffdbc19c977c3 (diff) |
gxfb: create DC/VP/FP-specific handlers rather than using readl/writel
This creates read_dc/write_dc, read_vp/write_vp, and read_fp/write_fp for
reading and updating those registers. It creates gxfb.h to house these.
We also drop a no-op readl() from gx_set_mode. Other than that, there should
be no functionality change.
Signed-off-by: Andres Salomon <dilinger@debian.org>
Cc: Jordan Crouse <jordan.crouse@amd.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/geode')
-rw-r--r-- | drivers/video/geode/display_gx.c | 48 | ||||
-rw-r--r-- | drivers/video/geode/gxfb.h | 47 | ||||
-rw-r--r-- | drivers/video/geode/gxfb_core.c | 4 | ||||
-rw-r--r-- | drivers/video/geode/video_gx.c | 41 |
4 files changed, 97 insertions, 43 deletions
diff --git a/drivers/video/geode/display_gx.c b/drivers/video/geode/display_gx.c index 8cd75725a31b..47f422e19974 100644 --- a/drivers/video/geode/display_gx.c +++ b/drivers/video/geode/display_gx.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include "geodefb.h" | 21 | #include "geodefb.h" |
22 | #include "display_gx.h" | 22 | #include "display_gx.h" |
23 | #include "gxfb.h" | ||
23 | 24 | ||
24 | unsigned int gx_frame_buffer_size(void) | 25 | unsigned int gx_frame_buffer_size(void) |
25 | { | 26 | { |
@@ -50,22 +51,21 @@ static void gx_set_mode(struct fb_info *info) | |||
50 | int vactive, vblankstart, vsyncstart, vsyncend, vblankend, vtotal; | 51 | int vactive, vblankstart, vsyncstart, vsyncend, vblankend, vtotal; |
51 | 52 | ||
52 | /* Unlock the display controller registers. */ | 53 | /* Unlock the display controller registers. */ |
53 | readl(par->dc_regs + DC_UNLOCK); | 54 | write_dc(par, DC_UNLOCK, DC_UNLOCK_CODE); |
54 | writel(DC_UNLOCK_CODE, par->dc_regs + DC_UNLOCK); | ||
55 | 55 | ||
56 | gcfg = readl(par->dc_regs + DC_GENERAL_CFG); | 56 | gcfg = read_dc(par, DC_GENERAL_CFG); |
57 | dcfg = readl(par->dc_regs + DC_DISPLAY_CFG); | 57 | dcfg = read_dc(par, DC_DISPLAY_CFG); |
58 | 58 | ||
59 | /* Disable the timing generator. */ | 59 | /* Disable the timing generator. */ |
60 | dcfg &= ~(DC_DCFG_TGEN); | 60 | dcfg &= ~(DC_DCFG_TGEN); |
61 | writel(dcfg, par->dc_regs + DC_DISPLAY_CFG); | 61 | write_dc(par, DC_DISPLAY_CFG, dcfg); |
62 | 62 | ||
63 | /* Wait for pending memory requests before disabling the FIFO load. */ | 63 | /* Wait for pending memory requests before disabling the FIFO load. */ |
64 | udelay(100); | 64 | udelay(100); |
65 | 65 | ||
66 | /* Disable FIFO load and compression. */ | 66 | /* Disable FIFO load and compression. */ |
67 | gcfg &= ~(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE); | 67 | gcfg &= ~(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE); |
68 | writel(gcfg, par->dc_regs + DC_GENERAL_CFG); | 68 | write_dc(par, DC_GENERAL_CFG, gcfg); |
69 | 69 | ||
70 | /* Setup DCLK and its divisor. */ | 70 | /* Setup DCLK and its divisor. */ |
71 | par->vid_ops->set_dclk(info); | 71 | par->vid_ops->set_dclk(info); |
@@ -83,12 +83,12 @@ static void gx_set_mode(struct fb_info *info) | |||
83 | gcfg |= (6 << DC_GCFG_DFHPEL_POS) | (5 << DC_GCFG_DFHPSL_POS) | DC_GCFG_DFLE; | 83 | gcfg |= (6 << DC_GCFG_DFHPEL_POS) | (5 << DC_GCFG_DFHPSL_POS) | DC_GCFG_DFLE; |
84 | 84 | ||
85 | /* Framebuffer start offset. */ | 85 | /* Framebuffer start offset. */ |
86 | writel(0, par->dc_regs + DC_FB_ST_OFFSET); | 86 | write_dc(par, DC_FB_ST_OFFSET, 0); |
87 | 87 | ||
88 | /* Line delta and line buffer length. */ | 88 | /* Line delta and line buffer length. */ |
89 | writel(info->fix.line_length >> 3, par->dc_regs + DC_GFX_PITCH); | 89 | write_dc(par, DC_GFX_PITCH, info->fix.line_length >> 3); |
90 | writel(((info->var.xres * info->var.bits_per_pixel/8) >> 3) + 2, | 90 | write_dc(par, DC_LINE_SIZE, |
91 | par->dc_regs + DC_LINE_SIZE); | 91 | ((info->var.xres * info->var.bits_per_pixel/8) >> 3) + 2); |
92 | 92 | ||
93 | 93 | ||
94 | /* Enable graphics and video data and unmask address lines. */ | 94 | /* Enable graphics and video data and unmask address lines. */ |
@@ -127,22 +127,28 @@ static void gx_set_mode(struct fb_info *info) | |||
127 | vblankend = vsyncend + info->var.upper_margin; | 127 | vblankend = vsyncend + info->var.upper_margin; |
128 | vtotal = vblankend; | 128 | vtotal = vblankend; |
129 | 129 | ||
130 | writel((hactive - 1) | ((htotal - 1) << 16), par->dc_regs + DC_H_ACTIVE_TIMING); | 130 | write_dc(par, DC_H_ACTIVE_TIMING, (hactive - 1) | |
131 | writel((hblankstart - 1) | ((hblankend - 1) << 16), par->dc_regs + DC_H_BLANK_TIMING); | 131 | ((htotal - 1) << 16)); |
132 | writel((hsyncstart - 1) | ((hsyncend - 1) << 16), par->dc_regs + DC_H_SYNC_TIMING); | 132 | write_dc(par, DC_H_BLANK_TIMING, (hblankstart - 1) | |
133 | ((hblankend - 1) << 16)); | ||
134 | write_dc(par, DC_H_SYNC_TIMING, (hsyncstart - 1) | | ||
135 | ((hsyncend - 1) << 16)); | ||
133 | 136 | ||
134 | writel((vactive - 1) | ((vtotal - 1) << 16), par->dc_regs + DC_V_ACTIVE_TIMING); | 137 | write_dc(par, DC_V_ACTIVE_TIMING, (vactive - 1) | |
135 | writel((vblankstart - 1) | ((vblankend - 1) << 16), par->dc_regs + DC_V_BLANK_TIMING); | 138 | ((vtotal - 1) << 16)); |
136 | writel((vsyncstart - 1) | ((vsyncend - 1) << 16), par->dc_regs + DC_V_SYNC_TIMING); | 139 | write_dc(par, DC_V_BLANK_TIMING, (vblankstart - 1) | |
140 | ((vblankend - 1) << 16)); | ||
141 | write_dc(par, DC_V_SYNC_TIMING, (vsyncstart - 1) | | ||
142 | ((vsyncend - 1) << 16)); | ||
137 | 143 | ||
138 | /* Write final register values. */ | 144 | /* Write final register values. */ |
139 | writel(dcfg, par->dc_regs + DC_DISPLAY_CFG); | 145 | write_dc(par, DC_DISPLAY_CFG, dcfg); |
140 | writel(gcfg, par->dc_regs + DC_GENERAL_CFG); | 146 | write_dc(par, DC_GENERAL_CFG, gcfg); |
141 | 147 | ||
142 | par->vid_ops->configure_display(info); | 148 | par->vid_ops->configure_display(info); |
143 | 149 | ||
144 | /* Relock display controller registers */ | 150 | /* Relock display controller registers */ |
145 | writel(0, par->dc_regs + DC_UNLOCK); | 151 | write_dc(par, DC_UNLOCK, 0); |
146 | } | 152 | } |
147 | 153 | ||
148 | static void gx_set_hw_palette_reg(struct fb_info *info, unsigned regno, | 154 | static void gx_set_hw_palette_reg(struct fb_info *info, unsigned regno, |
@@ -156,8 +162,8 @@ static void gx_set_hw_palette_reg(struct fb_info *info, unsigned regno, | |||
156 | val |= (green) & 0x00ff00; | 162 | val |= (green) & 0x00ff00; |
157 | val |= (blue >> 8) & 0x0000ff; | 163 | val |= (blue >> 8) & 0x0000ff; |
158 | 164 | ||
159 | writel(regno, par->dc_regs + DC_PAL_ADDRESS); | 165 | write_dc(par, DC_PAL_ADDRESS, regno); |
160 | writel(val, par->dc_regs + DC_PAL_DATA); | 166 | write_dc(par, DC_PAL_DATA, val); |
161 | } | 167 | } |
162 | 168 | ||
163 | struct geode_dc_ops gx_dc_ops = { | 169 | struct geode_dc_ops gx_dc_ops = { |
diff --git a/drivers/video/geode/gxfb.h b/drivers/video/geode/gxfb.h new file mode 100644 index 000000000000..42fa10db619a --- /dev/null +++ b/drivers/video/geode/gxfb.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Andres Salomon <dilinger@debian.org> | ||
3 | * | ||
4 | * Geode GX2 register tables | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | #ifndef _GXFB_H_ | ||
12 | #define _GXFB_H_ | ||
13 | |||
14 | #include <linux/io.h> | ||
15 | |||
16 | static inline uint32_t read_dc(struct geodefb_par *par, int reg) | ||
17 | { | ||
18 | return readl(par->dc_regs + reg); | ||
19 | } | ||
20 | |||
21 | static inline void write_dc(struct geodefb_par *par, int reg, uint32_t val) | ||
22 | { | ||
23 | writel(val, par->dc_regs + reg); | ||
24 | |||
25 | } | ||
26 | |||
27 | static inline uint32_t read_vp(struct geodefb_par *par, int reg) | ||
28 | { | ||
29 | return readl(par->vid_regs + reg); | ||
30 | } | ||
31 | |||
32 | static inline void write_vp(struct geodefb_par *par, int reg, uint32_t val) | ||
33 | { | ||
34 | writel(val, par->vid_regs + reg); | ||
35 | } | ||
36 | |||
37 | static inline uint32_t read_fp(struct geodefb_par *par, int reg) | ||
38 | { | ||
39 | return readl(par->vid_regs + reg); | ||
40 | } | ||
41 | |||
42 | static inline void write_fp(struct geodefb_par *par, int reg, uint32_t val) | ||
43 | { | ||
44 | writel(val, par->vid_regs + reg); | ||
45 | } | ||
46 | |||
47 | #endif | ||
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c index 8021bcb9ab6a..fd58dcc44670 100644 --- a/drivers/video/geode/gxfb_core.c +++ b/drivers/video/geode/gxfb_core.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include "geodefb.h" | 35 | #include "geodefb.h" |
36 | #include "display_gx.h" | 36 | #include "display_gx.h" |
37 | #include "video_gx.h" | 37 | #include "video_gx.h" |
38 | #include "gxfb.h" | ||
38 | 39 | ||
39 | static char *mode_option; | 40 | static char *mode_option; |
40 | static int vram; | 41 | static int vram; |
@@ -243,8 +244,7 @@ static int __init gxfb_map_video_memory(struct fb_info *info, struct pci_dev *de | |||
243 | /* Set the 16MiB aligned base address of the graphics memory region | 244 | /* Set the 16MiB aligned base address of the graphics memory region |
244 | * in the display controller */ | 245 | * in the display controller */ |
245 | 246 | ||
246 | writel(info->fix.smem_start & 0xFF000000, | 247 | write_dc(par, DC_GLIU0_MEM_OFFSET, info->fix.smem_start & 0xFF000000); |
247 | par->dc_regs + DC_GLIU0_MEM_OFFSET); | ||
248 | 248 | ||
249 | dev_info(&dev->dev, "%d KiB of video memory at 0x%lx\n", | 249 | dev_info(&dev->dev, "%d KiB of video memory at 0x%lx\n", |
250 | info->fix.smem_len / 1024, info->fix.smem_start); | 250 | info->fix.smem_len / 1024, info->fix.smem_start); |
diff --git a/drivers/video/geode/video_gx.c b/drivers/video/geode/video_gx.c index cfe2c80b025d..e45d94143da0 100644 --- a/drivers/video/geode/video_gx.c +++ b/drivers/video/geode/video_gx.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include "geodefb.h" | 21 | #include "geodefb.h" |
22 | #include "video_gx.h" | 22 | #include "video_gx.h" |
23 | #include "gxfb.h" | ||
23 | 24 | ||
24 | 25 | ||
25 | /* | 26 | /* |
@@ -192,16 +193,16 @@ gx_configure_tft(struct fb_info *info) | |||
192 | 193 | ||
193 | /* Turn off the panel */ | 194 | /* Turn off the panel */ |
194 | 195 | ||
195 | fp = readl(par->vid_regs + GX_FP_PM); | 196 | fp = read_fp(par, GX_FP_PM); |
196 | fp &= ~GX_FP_PM_P; | 197 | fp &= ~GX_FP_PM_P; |
197 | writel(fp, par->vid_regs + GX_FP_PM); | 198 | write_fp(par, GX_FP_PM, fp); |
198 | 199 | ||
199 | /* Set timing 1 */ | 200 | /* Set timing 1 */ |
200 | 201 | ||
201 | fp = readl(par->vid_regs + GX_FP_PT1); | 202 | fp = read_fp(par, GX_FP_PT1); |
202 | fp &= GX_FP_PT1_VSIZE_MASK; | 203 | fp &= GX_FP_PT1_VSIZE_MASK; |
203 | fp |= info->var.yres << GX_FP_PT1_VSIZE_SHIFT; | 204 | fp |= info->var.yres << GX_FP_PT1_VSIZE_SHIFT; |
204 | writel(fp, par->vid_regs + GX_FP_PT1); | 205 | write_fp(par, GX_FP_PT1, fp); |
205 | 206 | ||
206 | /* Timing 2 */ | 207 | /* Timing 2 */ |
207 | /* Set bits that are always on for TFT */ | 208 | /* Set bits that are always on for TFT */ |
@@ -216,22 +217,22 @@ gx_configure_tft(struct fb_info *info) | |||
216 | if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT)) | 217 | if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT)) |
217 | fp |= GX_FP_PT2_HSP; | 218 | fp |= GX_FP_PT2_HSP; |
218 | 219 | ||
219 | writel(fp, par->vid_regs + GX_FP_PT2); | 220 | write_fp(par, GX_FP_PT2, fp); |
220 | 221 | ||
221 | /* Set the dither control */ | 222 | /* Set the dither control */ |
222 | writel(0x70, par->vid_regs + GX_FP_DFC); | 223 | write_fp(par, GX_FP_DFC, 0x70); |
223 | 224 | ||
224 | /* Enable the FP data and power (in case the BIOS didn't) */ | 225 | /* Enable the FP data and power (in case the BIOS didn't) */ |
225 | 226 | ||
226 | fp = readl(par->vid_regs + GX_DCFG); | 227 | fp = read_vp(par, GX_DCFG); |
227 | fp |= GX_DCFG_FP_PWR_EN | GX_DCFG_FP_DATA_EN; | 228 | fp |= GX_DCFG_FP_PWR_EN | GX_DCFG_FP_DATA_EN; |
228 | writel(fp, par->vid_regs + GX_DCFG); | 229 | write_vp(par, GX_DCFG, fp); |
229 | 230 | ||
230 | /* Unblank the panel */ | 231 | /* Unblank the panel */ |
231 | 232 | ||
232 | fp = readl(par->vid_regs + GX_FP_PM); | 233 | fp = read_fp(par, GX_FP_PM); |
233 | fp |= GX_FP_PM_P; | 234 | fp |= GX_FP_PM_P; |
234 | writel(fp, par->vid_regs + GX_FP_PM); | 235 | write_fp(par, GX_FP_PM, fp); |
235 | } | 236 | } |
236 | 237 | ||
237 | static void gx_configure_display(struct fb_info *info) | 238 | static void gx_configure_display(struct fb_info *info) |
@@ -240,11 +241,11 @@ static void gx_configure_display(struct fb_info *info) | |||
240 | u32 dcfg, misc; | 241 | u32 dcfg, misc; |
241 | 242 | ||
242 | /* Write the display configuration */ | 243 | /* Write the display configuration */ |
243 | dcfg = readl(par->vid_regs + GX_DCFG); | 244 | dcfg = read_vp(par, GX_DCFG); |
244 | 245 | ||
245 | /* Disable hsync and vsync */ | 246 | /* Disable hsync and vsync */ |
246 | dcfg &= ~(GX_DCFG_VSYNC_EN | GX_DCFG_HSYNC_EN); | 247 | dcfg &= ~(GX_DCFG_VSYNC_EN | GX_DCFG_HSYNC_EN); |
247 | writel(dcfg, par->vid_regs + GX_DCFG); | 248 | write_vp(par, GX_DCFG, dcfg); |
248 | 249 | ||
249 | /* Clear bits from existing mode. */ | 250 | /* Clear bits from existing mode. */ |
250 | dcfg &= ~(GX_DCFG_CRT_SYNC_SKW_MASK | 251 | dcfg &= ~(GX_DCFG_CRT_SYNC_SKW_MASK |
@@ -257,7 +258,7 @@ static void gx_configure_display(struct fb_info *info) | |||
257 | /* Enable hsync and vsync. */ | 258 | /* Enable hsync and vsync. */ |
258 | dcfg |= GX_DCFG_HSYNC_EN | GX_DCFG_VSYNC_EN; | 259 | dcfg |= GX_DCFG_HSYNC_EN | GX_DCFG_VSYNC_EN; |
259 | 260 | ||
260 | misc = readl(par->vid_regs + GX_MISC); | 261 | misc = read_vp(par, GX_MISC); |
261 | 262 | ||
262 | /* Disable gamma correction */ | 263 | /* Disable gamma correction */ |
263 | misc |= GX_MISC_GAM_EN; | 264 | misc |= GX_MISC_GAM_EN; |
@@ -266,7 +267,7 @@ static void gx_configure_display(struct fb_info *info) | |||
266 | 267 | ||
267 | /* Power up the CRT DACs */ | 268 | /* Power up the CRT DACs */ |
268 | misc &= ~(GX_MISC_A_PWRDN | GX_MISC_DAC_PWRDN); | 269 | misc &= ~(GX_MISC_A_PWRDN | GX_MISC_DAC_PWRDN); |
269 | writel(misc, par->vid_regs + GX_MISC); | 270 | write_vp(par, GX_MISC, misc); |
270 | 271 | ||
271 | /* Only change the sync polarities if we are running | 272 | /* Only change the sync polarities if we are running |
272 | * in CRT mode. The FP polarities will be handled in | 273 | * in CRT mode. The FP polarities will be handled in |
@@ -278,7 +279,7 @@ static void gx_configure_display(struct fb_info *info) | |||
278 | } else { | 279 | } else { |
279 | /* Power down the CRT DACs if in FP mode */ | 280 | /* Power down the CRT DACs if in FP mode */ |
280 | misc |= (GX_MISC_A_PWRDN | GX_MISC_DAC_PWRDN); | 281 | misc |= (GX_MISC_A_PWRDN | GX_MISC_DAC_PWRDN); |
281 | writel(misc, par->vid_regs + GX_MISC); | 282 | write_vp(par, GX_MISC, misc); |
282 | } | 283 | } |
283 | 284 | ||
284 | /* Enable the display logic */ | 285 | /* Enable the display logic */ |
@@ -288,7 +289,7 @@ static void gx_configure_display(struct fb_info *info) | |||
288 | 289 | ||
289 | /* Enable the external DAC VREF? */ | 290 | /* Enable the external DAC VREF? */ |
290 | 291 | ||
291 | writel(dcfg, par->vid_regs + GX_DCFG); | 292 | write_vp(par, GX_DCFG, dcfg); |
292 | 293 | ||
293 | /* Set up the flat panel (if it is enabled) */ | 294 | /* Set up the flat panel (if it is enabled) */ |
294 | 295 | ||
@@ -322,7 +323,7 @@ static int gx_blank_display(struct fb_info *info, int blank_mode) | |||
322 | default: | 323 | default: |
323 | return -EINVAL; | 324 | return -EINVAL; |
324 | } | 325 | } |
325 | dcfg = readl(par->vid_regs + GX_DCFG); | 326 | dcfg = read_vp(par, GX_DCFG); |
326 | dcfg &= ~(GX_DCFG_DAC_BL_EN | 327 | dcfg &= ~(GX_DCFG_DAC_BL_EN |
327 | | GX_DCFG_HSYNC_EN | GX_DCFG_VSYNC_EN); | 328 | | GX_DCFG_HSYNC_EN | GX_DCFG_VSYNC_EN); |
328 | if (!blank) | 329 | if (!blank) |
@@ -331,17 +332,17 @@ static int gx_blank_display(struct fb_info *info, int blank_mode) | |||
331 | dcfg |= GX_DCFG_HSYNC_EN; | 332 | dcfg |= GX_DCFG_HSYNC_EN; |
332 | if (vsync) | 333 | if (vsync) |
333 | dcfg |= GX_DCFG_VSYNC_EN; | 334 | dcfg |= GX_DCFG_VSYNC_EN; |
334 | writel(dcfg, par->vid_regs + GX_DCFG); | 335 | write_vp(par, GX_DCFG, dcfg); |
335 | 336 | ||
336 | /* Power on/off flat panel. */ | 337 | /* Power on/off flat panel. */ |
337 | 338 | ||
338 | if (par->enable_crt == 0) { | 339 | if (par->enable_crt == 0) { |
339 | fp_pm = readl(par->vid_regs + GX_FP_PM); | 340 | fp_pm = read_fp(par, GX_FP_PM); |
340 | if (blank_mode == FB_BLANK_POWERDOWN) | 341 | if (blank_mode == FB_BLANK_POWERDOWN) |
341 | fp_pm &= ~GX_FP_PM_P; | 342 | fp_pm &= ~GX_FP_PM_P; |
342 | else | 343 | else |
343 | fp_pm |= GX_FP_PM_P; | 344 | fp_pm |= GX_FP_PM_P; |
344 | writel(fp_pm, par->vid_regs + GX_FP_PM); | 345 | write_fp(par, GX_FP_PM, fp_pm); |
345 | } | 346 | } |
346 | 347 | ||
347 | return 0; | 348 | return 0; |