aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 16:15:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 16:15:58 -0400
commit467cbd207abdbfe29514b5804a22661ab6e80dc6 (patch)
tree026a03bfcb0f755c5d61fcf288d98582ebd55093 /drivers/video
parent7125764c5d1a5c72d522f1011b6cc8b8100b48fe (diff)
parentb5660ba76b41af69a0c09d434927bb4b4cadd4b1 (diff)
Merge branch 'x86-nuke-platforms-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 old platform removal from Peter Anvin: "This patchset removes support for several completely obsolete platforms, where the maintainers either have completely vanished or acked the removal. For some of them it is questionable if there even exists functional specimens of the hardware" Geert Uytterhoeven apparently thought this was a April Fool's pull request ;) * 'x86-nuke-platforms-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86, platforms: Remove NUMAQ x86, platforms: Remove SGI Visual Workstation x86, apic: Remove support for IBM Summit/EXA chipset x86, apic: Remove support for ia32-based Unisys ES7000
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig11
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/gbefb.c4
-rw-r--r--drivers/video/logo/Kconfig2
-rw-r--r--drivers/video/logo/logo.c2
-rw-r--r--drivers/video/sgivwfb.c889
6 files changed, 3 insertions, 906 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 97a8f3a12a7b..b4b209ce8029 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -796,18 +796,9 @@ config FB_HGA
796 As this card technology is at least 25 years old, 796 As this card technology is at least 25 years old,
797 most people will answer N here. 797 most people will answer N here.
798 798
799config FB_SGIVW
800 tristate "SGI Visual Workstation framebuffer support"
801 depends on FB && X86_VISWS
802 select FB_CFB_FILLRECT
803 select FB_CFB_COPYAREA
804 select FB_CFB_IMAGEBLIT
805 help
806 SGI Visual Workstation support for framebuffer graphics.
807
808config FB_GBE 799config FB_GBE
809 bool "SGI Graphics Backend frame buffer support" 800 bool "SGI Graphics Backend frame buffer support"
810 depends on (FB = y) && (SGI_IP32 || X86_VISWS) 801 depends on (FB = y) && SGI_IP32
811 select FB_CFB_FILLRECT 802 select FB_CFB_FILLRECT
812 select FB_CFB_COPYAREA 803 select FB_CFB_COPYAREA
813 select FB_CFB_IMAGEBLIT 804 select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 08d6a4ab3ace..1be26fe10592 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -75,7 +75,6 @@ obj-$(CONFIG_FB_CG14) += cg14.o sbuslib.o
75obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o 75obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o
76obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o 76obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o
77obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o 77obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o
78obj-$(CONFIG_FB_SGIVW) += sgivwfb.o
79obj-$(CONFIG_FB_ACORN) += acornfb.o 78obj-$(CONFIG_FB_ACORN) += acornfb.o
80obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \ 79obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \
81 atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o 80 atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 4c7cb368a9dc..3ec65a878ac8 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -45,10 +45,6 @@ struct gbefb_par {
45#define GBE_BASE 0x16000000 /* SGI O2 */ 45#define GBE_BASE 0x16000000 /* SGI O2 */
46#endif 46#endif
47 47
48#ifdef CONFIG_X86_VISWS
49#define GBE_BASE 0xd0000000 /* SGI Visual Workstation */
50#endif
51
52/* macro for fastest write-though access to the framebuffer */ 48/* macro for fastest write-though access to the framebuffer */
53#ifdef CONFIG_MIPS 49#ifdef CONFIG_MIPS
54#ifdef CONFIG_CPU_R10000 50#ifdef CONFIG_CPU_R10000
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index 39ac49e0682c..0037104d66ac 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -54,7 +54,7 @@ config LOGO_PARISC_CLUT224
54 54
55config LOGO_SGI_CLUT224 55config LOGO_SGI_CLUT224
56 bool "224-color SGI Linux logo" 56 bool "224-color SGI Linux logo"
57 depends on SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS 57 depends on SGI_IP22 || SGI_IP27 || SGI_IP32
58 default y 58 default y
59 59
60config LOGO_SUN_CLUT224 60config LOGO_SUN_CLUT224
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
index b670cbda38e3..940cd196eef5 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -81,7 +81,7 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
81 logo = &logo_parisc_clut224; 81 logo = &logo_parisc_clut224;
82#endif 82#endif
83#ifdef CONFIG_LOGO_SGI_CLUT224 83#ifdef CONFIG_LOGO_SGI_CLUT224
84 /* SGI Linux logo on MIPS/MIPS64 and VISWS */ 84 /* SGI Linux logo on MIPS/MIPS64 */
85 logo = &logo_sgi_clut224; 85 logo = &logo_sgi_clut224;
86#endif 86#endif
87#ifdef CONFIG_LOGO_SUN_CLUT224 87#ifdef CONFIG_LOGO_SUN_CLUT224
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
deleted file mode 100644
index bc74d0408998..000000000000
--- a/drivers/video/sgivwfb.c
+++ /dev/null
@@ -1,889 +0,0 @@
1/*
2 * linux/drivers/video/sgivwfb.c -- SGI DBE frame buffer device
3 *
4 * Copyright (C) 1999 Silicon Graphics, Inc.
5 * Jeffrey Newquist, newquist@engr.sgi.som
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive for
9 * more details.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/mm.h>
15#include <linux/errno.h>
16#include <linux/delay.h>
17#include <linux/fb.h>
18#include <linux/init.h>
19#include <linux/ioport.h>
20#include <linux/platform_device.h>
21
22#include <asm/io.h>
23#include <asm/mtrr.h>
24#include <asm/visws/sgivw.h>
25
26#define INCLUDE_TIMING_TABLE_DATA
27#define DBE_REG_BASE par->regs
28#include <video/sgivw.h>
29
30struct sgivw_par {
31 struct asregs *regs;
32 u32 cmap_fifo;
33 u_long timing_num;
34};
35
36#define FLATPANEL_SGI_1600SW 5
37
38/*
39 * RAM we reserve for the frame buffer. This defines the maximum screen
40 * size
41 *
42 * The default can be overridden if the driver is compiled as a module
43 */
44
45static int ypan = 0;
46static int ywrap = 0;
47
48static int flatpanel_id = -1;
49
50static struct fb_fix_screeninfo sgivwfb_fix = {
51 .id = "SGI Vis WS FB",
52 .type = FB_TYPE_PACKED_PIXELS,
53 .visual = FB_VISUAL_PSEUDOCOLOR,
54 .mmio_start = DBE_REG_PHYS,
55 .mmio_len = DBE_REG_SIZE,
56 .accel = FB_ACCEL_NONE,
57 .line_length = 640,
58};
59
60static struct fb_var_screeninfo sgivwfb_var = {
61 /* 640x480, 8 bpp */
62 .xres = 640,
63 .yres = 480,
64 .xres_virtual = 640,
65 .yres_virtual = 480,
66 .bits_per_pixel = 8,
67 .red = { 0, 8, 0 },
68 .green = { 0, 8, 0 },
69 .blue = { 0, 8, 0 },
70 .height = -1,
71 .width = -1,
72 .pixclock = 20000,
73 .left_margin = 64,
74 .right_margin = 64,
75 .upper_margin = 32,
76 .lower_margin = 32,
77 .hsync_len = 64,
78 .vsync_len = 2,
79 .vmode = FB_VMODE_NONINTERLACED
80};
81
82static struct fb_var_screeninfo sgivwfb_var1600sw = {
83 /* 1600x1024, 8 bpp */
84 .xres = 1600,
85 .yres = 1024,
86 .xres_virtual = 1600,
87 .yres_virtual = 1024,
88 .bits_per_pixel = 8,
89 .red = { 0, 8, 0 },
90 .green = { 0, 8, 0 },
91 .blue = { 0, 8, 0 },
92 .height = -1,
93 .width = -1,
94 .pixclock = 9353,
95 .left_margin = 20,
96 .right_margin = 30,
97 .upper_margin = 37,
98 .lower_margin = 3,
99 .hsync_len = 20,
100 .vsync_len = 3,
101 .vmode = FB_VMODE_NONINTERLACED
102};
103
104/*
105 * Interface used by the world
106 */
107int sgivwfb_init(void);
108
109static int sgivwfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
110static int sgivwfb_set_par(struct fb_info *info);
111static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,
112 u_int blue, u_int transp,
113 struct fb_info *info);
114static int sgivwfb_mmap(struct fb_info *info,
115 struct vm_area_struct *vma);
116
117static struct fb_ops sgivwfb_ops = {
118 .owner = THIS_MODULE,
119 .fb_check_var = sgivwfb_check_var,
120 .fb_set_par = sgivwfb_set_par,
121 .fb_setcolreg = sgivwfb_setcolreg,
122 .fb_fillrect = cfb_fillrect,
123 .fb_copyarea = cfb_copyarea,
124 .fb_imageblit = cfb_imageblit,
125 .fb_mmap = sgivwfb_mmap,
126};
127
128/*
129 * Internal routines
130 */
131static unsigned long bytes_per_pixel(int bpp)
132{
133 switch (bpp) {
134 case 8:
135 return 1;
136 case 16:
137 return 2;
138 case 32:
139 return 4;
140 default:
141 printk(KERN_INFO "sgivwfb: unsupported bpp %d\n", bpp);
142 return 0;
143 }
144}
145
146static unsigned long get_line_length(int xres_virtual, int bpp)
147{
148 return (xres_virtual * bytes_per_pixel(bpp));
149}
150
151/*
152 * Function: dbe_TurnOffDma
153 * Parameters: (None)
154 * Description: This should turn off the monitor and dbe. This is used
155 * when switching between the serial console and the graphics
156 * console.
157 */
158
159static void dbe_TurnOffDma(struct sgivw_par *par)
160{
161 unsigned int readVal;
162 int i;
163
164 // Check to see if things are already turned off:
165 // 1) Check to see if dbe is not using the internal dotclock.
166 // 2) Check to see if the xy counter in dbe is already off.
167
168 DBE_GETREG(ctrlstat, readVal);
169 if (GET_DBE_FIELD(CTRLSTAT, PCLKSEL, readVal) < 2)
170 return;
171
172 DBE_GETREG(vt_xy, readVal);
173 if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1)
174 return;
175
176 // Otherwise, turn off dbe
177
178 DBE_GETREG(ovr_control, readVal);
179 SET_DBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, readVal, 0);
180 DBE_SETREG(ovr_control, readVal);
181 udelay(1000);
182 DBE_GETREG(frm_control, readVal);
183 SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, readVal, 0);
184 DBE_SETREG(frm_control, readVal);
185 udelay(1000);
186 DBE_GETREG(did_control, readVal);
187 SET_DBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, readVal, 0);
188 DBE_SETREG(did_control, readVal);
189 udelay(1000);
190
191 // XXX HACK:
192 //
193 // This was necessary for GBE--we had to wait through two
194 // vertical retrace periods before the pixel DMA was
195 // turned off for sure. I've left this in for now, in
196 // case dbe needs it.
197
198 for (i = 0; i < 10000; i++) {
199 DBE_GETREG(frm_inhwctrl, readVal);
200 if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) ==
201 0)
202 udelay(10);
203 else {
204 DBE_GETREG(ovr_inhwctrl, readVal);
205 if (GET_DBE_FIELD
206 (OVR_INHWCTRL, OVR_DMA_ENABLE, readVal) == 0)
207 udelay(10);
208 else {
209 DBE_GETREG(did_inhwctrl, readVal);
210 if (GET_DBE_FIELD
211 (DID_INHWCTRL, DID_DMA_ENABLE,
212 readVal) == 0)
213 udelay(10);
214 else
215 break;
216 }
217 }
218 }
219}
220
221/*
222 * Set the User Defined Part of the Display. Again if par use it to get
223 * real video mode.
224 */
225static int sgivwfb_check_var(struct fb_var_screeninfo *var,
226 struct fb_info *info)
227{
228 struct sgivw_par *par = (struct sgivw_par *)info->par;
229 struct dbe_timing_info *timing;
230 u_long line_length;
231 u_long min_mode;
232 int req_dot;
233 int test_mode;
234
235 /*
236 * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
237 * as FB_VMODE_SMOOTH_XPAN is only used internally
238 */
239
240 if (var->vmode & FB_VMODE_CONUPDATE) {
241 var->vmode |= FB_VMODE_YWRAP;
242 var->xoffset = info->var.xoffset;
243 var->yoffset = info->var.yoffset;
244 }
245
246 /* XXX FIXME - forcing var's */
247 var->xoffset = 0;
248 var->yoffset = 0;
249
250 /* Limit bpp to 8, 16, and 32 */
251 if (var->bits_per_pixel <= 8)
252 var->bits_per_pixel = 8;
253 else if (var->bits_per_pixel <= 16)
254 var->bits_per_pixel = 16;
255 else if (var->bits_per_pixel <= 32)
256 var->bits_per_pixel = 32;
257 else
258 return -EINVAL;
259
260 var->grayscale = 0; /* No grayscale for now */
261
262 /* determine valid resolution and timing */
263 for (min_mode = 0; min_mode < ARRAY_SIZE(dbeVTimings); min_mode++) {
264 if (dbeVTimings[min_mode].width >= var->xres &&
265 dbeVTimings[min_mode].height >= var->yres)
266 break;
267 }
268
269 if (min_mode == ARRAY_SIZE(dbeVTimings))
270 return -EINVAL; /* Resolution to high */
271
272 /* XXX FIXME - should try to pick best refresh rate */
273 /* for now, pick closest dot-clock within 3MHz */
274 req_dot = PICOS2KHZ(var->pixclock);
275 printk(KERN_INFO "sgivwfb: requested pixclock=%d ps (%d KHz)\n",
276 var->pixclock, req_dot);
277 test_mode = min_mode;
278 while (dbeVTimings[min_mode].width == dbeVTimings[test_mode].width) {
279 if (dbeVTimings[test_mode].cfreq + 3000 > req_dot)
280 break;
281 test_mode++;
282 }
283 if (dbeVTimings[min_mode].width != dbeVTimings[test_mode].width)
284 test_mode--;
285 min_mode = test_mode;
286 timing = &dbeVTimings[min_mode];
287 printk(KERN_INFO "sgivwfb: granted dot-clock=%d KHz\n", timing->cfreq);
288
289 /* Adjust virtual resolution, if necessary */
290 if (var->xres > var->xres_virtual || (!ywrap && !ypan))
291 var->xres_virtual = var->xres;
292 if (var->yres > var->yres_virtual || (!ywrap && !ypan))
293 var->yres_virtual = var->yres;
294
295 /*
296 * Memory limit
297 */
298 line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
299 if (line_length * var->yres_virtual > sgivwfb_mem_size)
300 return -ENOMEM; /* Virtual resolution to high */
301
302 info->fix.line_length = line_length;
303
304 switch (var->bits_per_pixel) {
305 case 8:
306 var->red.offset = 0;
307 var->red.length = 8;
308 var->green.offset = 0;
309 var->green.length = 8;
310 var->blue.offset = 0;
311 var->blue.length = 8;
312 var->transp.offset = 0;
313 var->transp.length = 0;
314 break;
315 case 16: /* RGBA 5551 */
316 var->red.offset = 11;
317 var->red.length = 5;
318 var->green.offset = 6;
319 var->green.length = 5;
320 var->blue.offset = 1;
321 var->blue.length = 5;
322 var->transp.offset = 0;
323 var->transp.length = 0;
324 break;
325 case 32: /* RGB 8888 */
326 var->red.offset = 0;
327 var->red.length = 8;
328 var->green.offset = 8;
329 var->green.length = 8;
330 var->blue.offset = 16;
331 var->blue.length = 8;
332 var->transp.offset = 24;
333 var->transp.length = 8;
334 break;
335 }
336 var->red.msb_right = 0;
337 var->green.msb_right = 0;
338 var->blue.msb_right = 0;
339 var->transp.msb_right = 0;
340
341 /* set video timing information */
342 var->pixclock = KHZ2PICOS(timing->cfreq);
343 var->left_margin = timing->htotal - timing->hsync_end;
344 var->right_margin = timing->hsync_start - timing->width;
345 var->upper_margin = timing->vtotal - timing->vsync_end;
346 var->lower_margin = timing->vsync_start - timing->height;
347 var->hsync_len = timing->hsync_end - timing->hsync_start;
348 var->vsync_len = timing->vsync_end - timing->vsync_start;
349
350 /* Ouch. This breaks the rules but timing_num is only important if you
351 * change a video mode */
352 par->timing_num = min_mode;
353
354 printk(KERN_INFO "sgivwfb: new video mode xres=%d yres=%d bpp=%d\n",
355 var->xres, var->yres, var->bits_per_pixel);
356 printk(KERN_INFO " vxres=%d vyres=%d\n", var->xres_virtual,
357 var->yres_virtual);
358 return 0;
359}
360
361/*
362 * Setup flatpanel related registers.
363 */
364static void sgivwfb_setup_flatpanel(struct sgivw_par *par, struct dbe_timing_info *currentTiming)
365{
366 int fp_wid, fp_hgt, fp_vbs, fp_vbe;
367 u32 outputVal = 0;
368
369 SET_DBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal,
370 (currentTiming->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1);
371 SET_DBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal,
372 (currentTiming->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1);
373 DBE_SETREG(vt_flags, outputVal);
374
375 /* Turn on the flat panel */
376 switch (flatpanel_id) {
377 case FLATPANEL_SGI_1600SW:
378 fp_wid = 1600;
379 fp_hgt = 1024;
380 fp_vbs = 0;
381 fp_vbe = 1600;
382 currentTiming->pll_m = 4;
383 currentTiming->pll_n = 1;
384 currentTiming->pll_p = 0;
385 break;
386 default:
387 fp_wid = fp_hgt = fp_vbs = fp_vbe = 0xfff;
388 }
389
390 outputVal = 0;
391 SET_DBE_FIELD(FP_DE, FP_DE_ON, outputVal, fp_vbs);
392 SET_DBE_FIELD(FP_DE, FP_DE_OFF, outputVal, fp_vbe);
393 DBE_SETREG(fp_de, outputVal);
394 outputVal = 0;
395 SET_DBE_FIELD(FP_HDRV, FP_HDRV_OFF, outputVal, fp_wid);
396 DBE_SETREG(fp_hdrv, outputVal);
397 outputVal = 0;
398 SET_DBE_FIELD(FP_VDRV, FP_VDRV_ON, outputVal, 1);
399 SET_DBE_FIELD(FP_VDRV, FP_VDRV_OFF, outputVal, fp_hgt + 1);
400 DBE_SETREG(fp_vdrv, outputVal);
401}
402
403/*
404 * Set the hardware according to 'par'.
405 */
406static int sgivwfb_set_par(struct fb_info *info)
407{
408 struct sgivw_par *par = info->par;
409 int i, j, htmp, temp;
410 u32 readVal, outputVal;
411 int wholeTilesX, maxPixelsPerTileX;
412 int frmWrite1, frmWrite2, frmWrite3b;
413 struct dbe_timing_info *currentTiming; /* Current Video Timing */
414 int xpmax, ypmax; // Monitor resolution
415 int bytesPerPixel; // Bytes per pixel
416
417 currentTiming = &dbeVTimings[par->timing_num];
418 bytesPerPixel = bytes_per_pixel(info->var.bits_per_pixel);
419 xpmax = currentTiming->width;
420 ypmax = currentTiming->height;
421
422 /* dbe_InitGraphicsBase(); */
423 /* Turn on dotclock PLL */
424 DBE_SETREG(ctrlstat, 0x20000000);
425
426 dbe_TurnOffDma(par);
427
428 /* dbe_CalculateScreenParams(); */
429 maxPixelsPerTileX = 512 / bytesPerPixel;
430 wholeTilesX = xpmax / maxPixelsPerTileX;
431 if (wholeTilesX * maxPixelsPerTileX < xpmax)
432 wholeTilesX++;
433
434 printk(KERN_DEBUG "sgivwfb: pixPerTile=%d wholeTilesX=%d\n",
435 maxPixelsPerTileX, wholeTilesX);
436
437 /* dbe_InitGammaMap(); */
438 udelay(10);
439
440 for (i = 0; i < 256; i++) {
441 DBE_ISETREG(gmap, i, (i << 24) | (i << 16) | (i << 8));
442 }
443
444 /* dbe_TurnOn(); */
445 DBE_GETREG(vt_xy, readVal);
446 if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1) {
447 DBE_SETREG(vt_xy, 0x00000000);
448 udelay(1);
449 } else
450 dbe_TurnOffDma(par);
451
452 /* dbe_Initdbe(); */
453 for (i = 0; i < 256; i++) {
454 for (j = 0; j < 100; j++) {
455 DBE_GETREG(cm_fifo, readVal);
456 if (readVal != 0x00000000)
457 break;
458 else
459 udelay(10);
460 }
461
462 // DBE_ISETREG(cmap, i, 0x00000000);
463 DBE_ISETREG(cmap, i, (i << 8) | (i << 16) | (i << 24));
464 }
465
466 /* dbe_InitFramebuffer(); */
467 frmWrite1 = 0;
468 SET_DBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, frmWrite1,
469 wholeTilesX);
470 SET_DBE_FIELD(FRM_SIZE_TILE, FRM_RHS, frmWrite1, 0);
471
472 switch (bytesPerPixel) {
473 case 1:
474 SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
475 DBE_FRM_DEPTH_8);
476 break;
477 case 2:
478 SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
479 DBE_FRM_DEPTH_16);
480 break;
481 case 4:
482 SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
483 DBE_FRM_DEPTH_32);
484 break;
485 }
486
487 frmWrite2 = 0;
488 SET_DBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, frmWrite2, ypmax);
489
490 // Tell dbe about the framebuffer location and type
491 // XXX What format is the FRM_TILE_PTR?? 64K aligned address?
492 frmWrite3b = 0;
493 SET_DBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, frmWrite3b,
494 sgivwfb_mem_phys >> 9);
495 SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, frmWrite3b, 1);
496 SET_DBE_FIELD(FRM_CONTROL, FRM_LINEAR, frmWrite3b, 1);
497
498 /* Initialize DIDs */
499
500 outputVal = 0;
501 switch (bytesPerPixel) {
502 case 1:
503 SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_I8);
504 break;
505 case 2:
506 SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGBA5);
507 break;
508 case 4:
509 SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGB8);
510 break;
511 }
512 SET_DBE_FIELD(WID, BUF, outputVal, DBE_BMODE_BOTH);
513
514 for (i = 0; i < 32; i++) {
515 DBE_ISETREG(mode_regs, i, outputVal);
516 }
517
518 /* dbe_InitTiming(); */
519 DBE_SETREG(vt_intr01, 0xffffffff);
520 DBE_SETREG(vt_intr23, 0xffffffff);
521
522 DBE_GETREG(dotclock, readVal);
523 DBE_SETREG(dotclock, readVal & 0xffff);
524
525 DBE_SETREG(vt_xymax, 0x00000000);
526 outputVal = 0;
527 SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_ON, outputVal,
528 currentTiming->vsync_start);
529 SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_OFF, outputVal,
530 currentTiming->vsync_end);
531 DBE_SETREG(vt_vsync, outputVal);
532 outputVal = 0;
533 SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_ON, outputVal,
534 currentTiming->hsync_start);
535 SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_OFF, outputVal,
536 currentTiming->hsync_end);
537 DBE_SETREG(vt_hsync, outputVal);
538 outputVal = 0;
539 SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_ON, outputVal,
540 currentTiming->vblank_start);
541 SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_OFF, outputVal,
542 currentTiming->vblank_end);
543 DBE_SETREG(vt_vblank, outputVal);
544 outputVal = 0;
545 SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_ON, outputVal,
546 currentTiming->hblank_start);
547 SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_OFF, outputVal,
548 currentTiming->hblank_end - 3);
549 DBE_SETREG(vt_hblank, outputVal);
550 outputVal = 0;
551 SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_ON, outputVal,
552 currentTiming->vblank_start);
553 SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_OFF, outputVal,
554 currentTiming->vblank_end);
555 DBE_SETREG(vt_vcmap, outputVal);
556 outputVal = 0;
557 SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_ON, outputVal,
558 currentTiming->hblank_start);
559 SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_OFF, outputVal,
560 currentTiming->hblank_end - 3);
561 DBE_SETREG(vt_hcmap, outputVal);
562
563 if (flatpanel_id != -1)
564 sgivwfb_setup_flatpanel(par, currentTiming);
565
566 outputVal = 0;
567 temp = currentTiming->vblank_start - currentTiming->vblank_end - 1;
568 if (temp > 0)
569 temp = -temp;
570
571 SET_DBE_FIELD(DID_START_XY, DID_STARTY, outputVal, (u32) temp);
572 if (currentTiming->hblank_end >= 20)
573 SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
574 currentTiming->hblank_end - 20);
575 else
576 SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
577 currentTiming->htotal - (20 -
578 currentTiming->
579 hblank_end));
580 DBE_SETREG(did_start_xy, outputVal);
581
582 outputVal = 0;
583 SET_DBE_FIELD(CRS_START_XY, CRS_STARTY, outputVal,
584 (u32) (temp + 1));
585 if (currentTiming->hblank_end >= DBE_CRS_MAGIC)
586 SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
587 currentTiming->hblank_end - DBE_CRS_MAGIC);
588 else
589 SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
590 currentTiming->htotal - (DBE_CRS_MAGIC -
591 currentTiming->
592 hblank_end));
593 DBE_SETREG(crs_start_xy, outputVal);
594
595 outputVal = 0;
596 SET_DBE_FIELD(VC_START_XY, VC_STARTY, outputVal, (u32) temp);
597 SET_DBE_FIELD(VC_START_XY, VC_STARTX, outputVal,
598 currentTiming->hblank_end - 4);
599 DBE_SETREG(vc_start_xy, outputVal);
600
601 DBE_SETREG(frm_size_tile, frmWrite1);
602 DBE_SETREG(frm_size_pixel, frmWrite2);
603
604 outputVal = 0;
605 SET_DBE_FIELD(DOTCLK, M, outputVal, currentTiming->pll_m - 1);
606 SET_DBE_FIELD(DOTCLK, N, outputVal, currentTiming->pll_n - 1);
607 SET_DBE_FIELD(DOTCLK, P, outputVal, currentTiming->pll_p);
608 SET_DBE_FIELD(DOTCLK, RUN, outputVal, 1);
609 DBE_SETREG(dotclock, outputVal);
610
611 udelay(11 * 1000);
612
613 DBE_SETREG(vt_vpixen, 0xffffff);
614 DBE_SETREG(vt_hpixen, 0xffffff);
615
616 outputVal = 0;
617 SET_DBE_FIELD(VT_XYMAX, VT_MAXX, outputVal, currentTiming->htotal);
618 SET_DBE_FIELD(VT_XYMAX, VT_MAXY, outputVal, currentTiming->vtotal);
619 DBE_SETREG(vt_xymax, outputVal);
620
621 outputVal = frmWrite1;
622 SET_DBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, outputVal, 1);
623 DBE_SETREG(frm_size_tile, outputVal);
624 DBE_SETREG(frm_size_tile, frmWrite1);
625
626 outputVal = 0;
627 SET_DBE_FIELD(OVR_WIDTH_TILE, OVR_FIFO_RESET, outputVal, 1);
628 DBE_SETREG(ovr_width_tile, outputVal);
629 DBE_SETREG(ovr_width_tile, 0);
630
631 DBE_SETREG(frm_control, frmWrite3b);
632 DBE_SETREG(did_control, 0);
633
634 // Wait for dbe to take frame settings
635 for (i = 0; i < 100000; i++) {
636 DBE_GETREG(frm_inhwctrl, readVal);
637 if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) !=
638 0)
639 break;
640 else
641 udelay(1);
642 }
643
644 if (i == 100000)
645 printk(KERN_INFO
646 "sgivwfb: timeout waiting for frame DMA enable.\n");
647
648 outputVal = 0;
649 htmp = currentTiming->hblank_end - 19;
650 if (htmp < 0)
651 htmp += currentTiming->htotal; /* allow blank to wrap around */
652 SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_ON, outputVal, htmp);
653 SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_OFF, outputVal,
654 ((htmp + currentTiming->width -
655 2) % currentTiming->htotal));
656 DBE_SETREG(vt_hpixen, outputVal);
657
658 outputVal = 0;
659 SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_OFF, outputVal,
660 currentTiming->vblank_start);
661 SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_ON, outputVal,
662 currentTiming->vblank_end);
663 DBE_SETREG(vt_vpixen, outputVal);
664
665 // Turn off mouse cursor
666 par->regs->crs_ctl = 0;
667
668 // XXX What's this section for??
669 DBE_GETREG(ctrlstat, readVal);
670 readVal &= 0x02000000;
671
672 if (readVal != 0) {
673 DBE_SETREG(ctrlstat, 0x30000000);
674 }
675 return 0;
676}
677
678/*
679 * Set a single color register. The values supplied are already
680 * rounded down to the hardware's capabilities (according to the
681 * entries in the var structure). Return != 0 for invalid regno.
682 */
683
684static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,
685 u_int blue, u_int transp,
686 struct fb_info *info)
687{
688 struct sgivw_par *par = (struct sgivw_par *) info->par;
689
690 if (regno > 255)
691 return 1;
692 red >>= 8;
693 green >>= 8;
694 blue >>= 8;
695
696 /* wait for the color map FIFO to have a free entry */
697 while (par->cmap_fifo == 0)
698 par->cmap_fifo = par->regs->cm_fifo;
699
700 par->regs->cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
701 par->cmap_fifo--; /* assume FIFO is filling up */
702 return 0;
703}
704
705static int sgivwfb_mmap(struct fb_info *info,
706 struct vm_area_struct *vma)
707{
708 int r;
709
710 pgprot_val(vma->vm_page_prot) =
711 pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
712
713 r = vm_iomap_memory(vma, sgivwfb_mem_phys, sgivwfb_mem_size);
714
715 printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n",
716 sgivwfb_mem_phys + (vma->vm_pgoff << PAGE_SHIFT), vma->vm_start);
717
718 return r;
719}
720
721int __init sgivwfb_setup(char *options)
722{
723 char *this_opt;
724
725 if (!options || !*options)
726 return 0;
727
728 while ((this_opt = strsep(&options, ",")) != NULL) {
729 if (!strncmp(this_opt, "monitor:", 8)) {
730 if (!strncmp(this_opt + 8, "crt", 3))
731 flatpanel_id = -1;
732 else if (!strncmp(this_opt + 8, "1600sw", 6))
733 flatpanel_id = FLATPANEL_SGI_1600SW;
734 }
735 }
736 return 0;
737}
738
739/*
740 * Initialisation
741 */
742static int sgivwfb_probe(struct platform_device *dev)
743{
744 struct sgivw_par *par;
745 struct fb_info *info;
746 char *monitor;
747
748 info = framebuffer_alloc(sizeof(struct sgivw_par) + sizeof(u32) * 16, &dev->dev);
749 if (!info)
750 return -ENOMEM;
751 par = info->par;
752
753 if (!request_mem_region(DBE_REG_PHYS, DBE_REG_SIZE, "sgivwfb")) {
754 printk(KERN_ERR "sgivwfb: couldn't reserve mmio region\n");
755 framebuffer_release(info);
756 return -EBUSY;
757 }
758
759 par->regs = (struct asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);
760 if (!par->regs) {
761 printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n");
762 goto fail_ioremap_regs;
763 }
764
765 mtrr_add(sgivwfb_mem_phys, sgivwfb_mem_size, MTRR_TYPE_WRCOMB, 1);
766
767 sgivwfb_fix.smem_start = sgivwfb_mem_phys;
768 sgivwfb_fix.smem_len = sgivwfb_mem_size;
769 sgivwfb_fix.ywrapstep = ywrap;
770 sgivwfb_fix.ypanstep = ypan;
771
772 info->fix = sgivwfb_fix;
773
774 switch (flatpanel_id) {
775 case FLATPANEL_SGI_1600SW:
776 info->var = sgivwfb_var1600sw;
777 monitor = "SGI 1600SW flatpanel";
778 break;
779 default:
780 info->var = sgivwfb_var;
781 monitor = "CRT";
782 }
783
784 printk(KERN_INFO "sgivwfb: %s monitor selected\n", monitor);
785
786 info->fbops = &sgivwfb_ops;
787 info->pseudo_palette = (void *) (par + 1);
788 info->flags = FBINFO_DEFAULT;
789
790 info->screen_base = ioremap_nocache((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size);
791 if (!info->screen_base) {
792 printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n");
793 goto fail_ioremap_fbmem;
794 }
795
796 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
797 goto fail_color_map;
798
799 if (register_framebuffer(info) < 0) {
800 printk(KERN_ERR "sgivwfb: couldn't register framebuffer\n");
801 goto fail_register_framebuffer;
802 }
803
804 platform_set_drvdata(dev, info);
805
806 fb_info(info, "SGI DBE frame buffer device, using %ldK of video memory at %#lx\n",
807 sgivwfb_mem_size >> 10, sgivwfb_mem_phys);
808 return 0;
809
810fail_register_framebuffer:
811 fb_dealloc_cmap(&info->cmap);
812fail_color_map:
813 iounmap((char *) info->screen_base);
814fail_ioremap_fbmem:
815 iounmap(par->regs);
816fail_ioremap_regs:
817 release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE);
818 framebuffer_release(info);
819 return -ENXIO;
820}
821
822static int sgivwfb_remove(struct platform_device *dev)
823{
824 struct fb_info *info = platform_get_drvdata(dev);
825
826 if (info) {
827 struct sgivw_par *par = info->par;
828
829 unregister_framebuffer(info);
830 dbe_TurnOffDma(par);
831 iounmap(par->regs);
832 iounmap(info->screen_base);
833 release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE);
834 fb_dealloc_cmap(&info->cmap);
835 framebuffer_release(info);
836 }
837 return 0;
838}
839
840static struct platform_driver sgivwfb_driver = {
841 .probe = sgivwfb_probe,
842 .remove = sgivwfb_remove,
843 .driver = {
844 .name = "sgivwfb",
845 },
846};
847
848static struct platform_device *sgivwfb_device;
849
850int __init sgivwfb_init(void)
851{
852 int ret;
853
854#ifndef MODULE
855 char *option = NULL;
856
857 if (fb_get_options("sgivwfb", &option))
858 return -ENODEV;
859 sgivwfb_setup(option);
860#endif
861 ret = platform_driver_register(&sgivwfb_driver);
862 if (!ret) {
863 sgivwfb_device = platform_device_alloc("sgivwfb", 0);
864 if (sgivwfb_device) {
865 ret = platform_device_add(sgivwfb_device);
866 } else
867 ret = -ENOMEM;
868 if (ret) {
869 platform_driver_unregister(&sgivwfb_driver);
870 platform_device_put(sgivwfb_device);
871 }
872 }
873 return ret;
874}
875
876module_init(sgivwfb_init);
877
878#ifdef MODULE
879MODULE_LICENSE("GPL");
880
881static void __exit sgivwfb_exit(void)
882{
883 platform_device_unregister(sgivwfb_device);
884 platform_driver_unregister(&sgivwfb_driver);
885}
886
887module_exit(sgivwfb_exit);
888
889#endif /* MODULE */