patch-2.1.129 linux/drivers/video/imsttfb.c
Next file: linux/drivers/video/matroxfb.c
Previous file: linux/drivers/video/fonts.c
Back to the patch index
Back to the overall index
- Lines: 997
- Date:
Fri Nov 13 10:10:12 1998
- Orig file:
v2.1.128/linux/drivers/video/imsttfb.c
- Orig date:
Fri Oct 23 22:01:22 1998
diff -u --recursive --new-file v2.1.128/linux/drivers/video/imsttfb.c linux/drivers/video/imsttfb.c
@@ -130,17 +130,17 @@
CLKCTL = 0x02, /* (0x01) Miscellaneous Clock Control */
SYNCCTL = 0x03, /* (0x00) Sync Control */
HSYNCPOS = 0x04, /* (0x00) Horizontal Sync Position */
- PWRMNGMT = 0x05, /* (0x00) Power Management [multiples of 4 unblack screen] */
- DACOP = 0x06, /* (0x02) DAC Operation [0-3 coloured, 4-7 green, odd light, even dark] */
+ PWRMNGMT = 0x05, /* (0x00) Power Management */
+ DACOP = 0x06, /* (0x02) DAC Operation */
PALETCTL = 0x07, /* (0x00) Palette Control */
SYSCLKCTL = 0x08, /* (0x01) System Clock Control */
PIXFMT = 0x0a, /* () Pixel Format [bpp >> 3 + 2] */
BPP8 = 0x0b, /* () 8 Bits/Pixel Control */
- BPP16 = 0x0c, /* () 16 Bits/Pixel Control [15 or 1 for 555] */
+ BPP16 = 0x0c, /* () 16 Bits/Pixel Control [bit 1=1 for 565] */
BPP24 = 0x0d, /* () 24 Bits/Pixel Control */
BPP32 = 0x0e, /* () 32 Bits/Pixel Control */
- PIXCTL1 = 0x10, /* (0x05) Pixel PLL Control 1 [5-7 ok] */
- PIXCTL2 = 0x11, /* (0x00) Pixel PLL Control 2 [multiples of 20 ok] */
+ PIXCTL1 = 0x10, /* (0x05) Pixel PLL Control 1 */
+ PIXCTL2 = 0x11, /* (0x00) Pixel PLL Control 2 */
SYSCLKN = 0x15, /* () System Clock N (System PLL Reference Divider) */
SYSCLKM = 0x16, /* () System Clock M (System PLL VCO Divider) */
SYSCLKP = 0x17, /* () System Clock P */
@@ -149,18 +149,19 @@
* Dot clock rate is 20MHz * (m + 1) / ((n + 1) * (p ? 2 * p : 1)
* c is charge pump bias which depends on the VCO frequency
*/
- PIXCLKM = 0x20, /* () Pixel Clock M */
- PIXCLKN = 0x21, /* () Pixel Clock N */
- PIXCLKP = 0x22, /* () Pixel Clock P */
- PIXCLKC = 0x23, /* () Pixel Clock C */
- CURSCTL = 0x30, /* (0x00) Cursor Control [1=curs1, 2=curs2, 5=curs3] */
+ PIXM0 = 0x20, /* () Pixel M 0 */
+ PIXN0 = 0x21, /* () Pixel N 0 */
+ PIXP0 = 0x22, /* () Pixel P 0 */
+ PIXC0 = 0x23, /* () Pixel C 0 */
+ CURSCTL = 0x30, /* (0x00) Cursor Control */
CURSXLO = 0x31, /* () Cursor X position, low 8 bits */
CURSXHI = 0x32, /* () Cursor X position, high 8 bits */
CURSYLO = 0x33, /* () Cursor Y position, low 8 bits */
CURSYHI = 0x34, /* () Cursor Y position, high 8 bits */
- CURSHOTX = 0x35, /* () ??? [position relative to CURSX] */
- CURSHOTY = 0x36, /* () ??? [position relative to CURSY] */
- CURSACAEN = 0x37, /* () ??? [even=cursor on, odd=cursor off] */
+ CURSHOTX = 0x35, /* () Cursor Hot Spot X */
+ CURSHOTY = 0x36, /* () Cursor Hot Spot Y */
+ CURSACCTL = 0x37, /* () Advanced Cursor Control Enable */
+ CURSACATTR = 0x38, /* () Advanced Cursor Attribute */
CURS1R = 0x40, /* () Cursor 1 Red */
CURS1G = 0x41, /* () Cursor 1 Green */
CURS1B = 0x42, /* () Cursor 1 Blue */
@@ -238,7 +239,7 @@
__u8 addr, value;
};
-static struct initvalues ibm_initregs[] = {
+static struct initvalues ibm_initregs[] __initdata = {
{ CLKCTL, 0x21 },
{ SYNCCTL, 0x00 },
{ HSYNCPOS, 0x00 },
@@ -264,10 +265,18 @@
{ SYSCLKM, 0x4f },
{ SYSCLKP, 0x00 },
{ SYSCLKC, 0x00 },
- { CURSCTL, 0x00 },
+ { CURSCTL, 0x02 },
+ { CURSACCTL, 0x01 },
+ { CURSACATTR, 0xa8 },
+ { CURS1R, 0xff },
+ { CURS1G, 0xff },
+ { CURS1B, 0xff },
{ CURS2R, 0xff },
{ CURS2G, 0xff },
{ CURS2B, 0xff },
+ { CURS3R, 0xff },
+ { CURS3G, 0xff },
+ { CURS3B, 0xff },
{ BORDR, 0xff },
{ BORDG, 0xff },
{ BORDB, 0xff },
@@ -277,7 +286,7 @@
{ KEYCTL, 0x00 }
};
-static struct initvalues tvp_initregs[] = {
+static struct initvalues tvp_initregs[] __initdata = {
{ 0x6, 0x00 },
{ 0x7, 0xe4 },
{ 0xf, 0x06 },
@@ -320,12 +329,12 @@
};
struct imstt_cursor {
+ struct timer_list timer;
int enable;
int on;
int vbl_cnt;
int blink_rate;
- __u16 x, y;
- struct timer_list timer;
+ __u16 x, y, width, height;
};
struct fb_info_imstt {
@@ -349,9 +358,9 @@
} palette[256];
struct imstt_regvals init;
struct imstt_cursor cursor;
- __u8 *frame_buffer_phys, *frame_buffer;
- __u32 *dc_regs_phys, *dc_regs;
- __u8 *cmap_regs_phys, *cmap_regs;
+ volatile __u8 *frame_buffer_phys, *frame_buffer;
+ volatile __u32 *dc_regs_phys, *dc_regs;
+ volatile __u8 *cmap_regs_phys, *cmap_regs;
__u32 total_vram;
__u32 ramdac;
};
@@ -364,6 +373,12 @@
#define CURSOR_DRAW_DELAY 2
static int currcon = 0;
+static char fontname[40] __initdata = { 0 };
+static char curblink __initdata = 1;
+static char noaccel __initdata = 0;
+#if defined(CONFIG_PPC)
+static signed char init_vmode __initdata = -1, init_cmode __initdata = -1;
+#endif
static struct imstt_regvals tvp_reg_init_2 = {
512,
@@ -504,7 +519,7 @@
init->hes = hes;
init->heb = heb;
- init->hsb = init->heb + xres / 8;
+ init->hsb = init->heb + (xres >> 3);
init->ht = init->hsb + htp;
init->ves = 0x0003;
init->veb = veb;
@@ -568,16 +583,15 @@
__u8 pformat = (bpp >> 3) + 2;
p->cmap_regs[PIDXHI] = 0; eieio();
- p->cmap_regs[PIDXLO] = PIXCLKM; eieio();
+ p->cmap_regs[PIDXLO] = PIXM0; eieio();
p->cmap_regs[PIDXDATA] = init->pclk_m; eieio();
- p->cmap_regs[PIDXLO] = PIXCLKN; eieio();
+ p->cmap_regs[PIDXLO] = PIXN0; eieio();
p->cmap_regs[PIDXDATA] = init->pclk_n; eieio();
- p->cmap_regs[PIDXLO] = PIXCLKP; eieio();
+ p->cmap_regs[PIDXLO] = PIXP0; eieio();
p->cmap_regs[PIDXDATA] = init->pclk_p; eieio();
- p->cmap_regs[PIDXLO] = PIXCLKC; eieio();
+ p->cmap_regs[PIDXLO] = PIXC0; eieio();
p->cmap_regs[PIDXDATA] = 0x02; eieio();
- p->cmap_regs[PIDXHI] = 0; eieio();
p->cmap_regs[PIDXLO] = PIXFMT; eieio();
p->cmap_regs[PIDXDATA] = pformat; eieio();
}
@@ -652,7 +666,7 @@
set_imstt_regvals (struct fb_info_imstt *p, u_int bpp)
{
struct imstt_regvals *init = &p->init;
- __u32 ctl, pitch, byteswap, scr;
+ __u32 ctl, pitch, byteswap, scr, line_pitch = init->pitch * (bpp >> 3);
if (p->ramdac == IBM)
set_imstt_regvals_ibm(p, bpp);
@@ -674,23 +688,23 @@
switch (bpp) {
case 8:
ctl = 0x17b1;
- pitch = init->pitch / 4;
- byteswap = 0x0;
+ pitch = init->pitch >> 2;
+ byteswap = 0x000;
break;
case 16:
ctl = 0x17b3;
- pitch = init->pitch / 2;
- byteswap = 0x1;
+ pitch = init->pitch >> 1;
+ byteswap = 0x100;
break;
case 24:
ctl = 0x17b9;
- pitch = init->pitch - (p->init.pitch / 4);
- byteswap = 0x2;
+ pitch = init->pitch - (p->init.pitch >> 2);
+ byteswap = 0x200;
break;
case 32:
ctl = 0x17b5;
pitch = init->pitch;
- byteswap = 0x3;
+ byteswap = 0x300;
break;
}
if (p->ramdac == TVP)
@@ -712,7 +726,6 @@
out_le32(&p->dc_regs[RRSC], 0x980);
out_le32(&p->dc_regs[RRCR], 0x11);
- out_le32(&p->dc_regs[SSR], 0);
if (p->ramdac == IBM) {
out_le32(&p->dc_regs[HRIR], 0x0100);
out_le32(&p->dc_regs[CMR], 0x00ff);
@@ -725,20 +738,19 @@
switch (p->total_vram) {
case 0x00200000:
- scr = 0x059d | (byteswap << 8);
+ scr = 0x059d | byteswap;
break;
case 0x00400000:
- pitch /= 2;
- scr = 0xd0dc | (byteswap << 8);
- break;
case 0x00800000:
pitch /= 2;
- scr = 0x150dd | (byteswap << 8);
+ scr = 0x150dd | byteswap;
break;
}
out_le32(&p->dc_regs[SCR], scr);
out_le32(&p->dc_regs[SPR], pitch);
+ out_le32(&p->dc_regs[SP], (line_pitch << 16) | line_pitch);
+ out_le32(&p->dc_regs[DP_OCTRL], line_pitch);
out_le32(&p->dc_regs[STGCTL], ctl);
}
@@ -755,8 +767,8 @@
}
}
-#define set_555(_p) set_16(_p, 15)
-#define set_565(_p) set_16(_p, 0) /* 220, 224 is darker in X */
+#define set_555(_p) set_16(_p, 0x01)
+#define set_565(_p) set_16(_p, 0x03)
static void
imstt_set_cursor (struct fb_info_imstt *p, int on)
@@ -765,19 +777,19 @@
p->cmap_regs[PIDXHI] = 0;
if (!on) {
- p->cmap_regs[PIDXLO] = CURSCTL;
- p->cmap_regs[PIDXDATA] = 0x00;
+ p->cmap_regs[PIDXLO] = CURSCTL; eieio();
+ p->cmap_regs[PIDXDATA] = 0x00; eieio();
} else {
- p->cmap_regs[PIDXLO] = CURSXHI;
- p->cmap_regs[PIDXDATA] = c->x >> 8;
- p->cmap_regs[PIDXLO] = CURSXLO;
- p->cmap_regs[PIDXDATA] = c->x & 0xff;
- p->cmap_regs[PIDXLO] = CURSYHI;
- p->cmap_regs[PIDXDATA] = c->y >> 8;
- p->cmap_regs[PIDXLO] = CURSYLO;
- p->cmap_regs[PIDXDATA] = c->y & 0xff;
- p->cmap_regs[PIDXLO] = CURSCTL;
- p->cmap_regs[PIDXDATA] = 0x02;
+ p->cmap_regs[PIDXLO] = CURSXHI; eieio();
+ p->cmap_regs[PIDXDATA] = c->x >> 8; eieio();
+ p->cmap_regs[PIDXLO] = CURSXLO; eieio();
+ p->cmap_regs[PIDXDATA] = c->x & 0xff; eieio();
+ p->cmap_regs[PIDXLO] = CURSYHI; eieio();
+ p->cmap_regs[PIDXDATA] = c->y >> 8; eieio();
+ p->cmap_regs[PIDXLO] = CURSYLO; eieio();
+ p->cmap_regs[PIDXDATA] = c->y & 0xff; eieio();
+ p->cmap_regs[PIDXLO] = CURSCTL; eieio();
+ p->cmap_regs[PIDXDATA] = 0x02; eieio();
}
}
@@ -796,8 +808,8 @@
c->enable = 0;
if (c->on)
imstt_set_cursor(p, 0);
- c->x = x;
- c->y = y;
+ c->x = x - disp->var.xoffset;
+ c->y = y - disp->var.yoffset;
switch (mode) {
case CM_ERASE:
@@ -817,6 +829,28 @@
static int
imsttfb_set_font (struct display *disp, int width, int height)
{
+ struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info;
+ struct imstt_cursor *c = &p->cursor;
+ u_int x, y;
+
+ if (width > 32 || height > 32)
+ return -EINVAL;
+
+ c->height = height;
+ c->width = width;
+
+ p->cmap_regs[PIDXHI] = 1; eieio();
+ for (x = 0; x < 0x100; x++) {
+ p->cmap_regs[PIDXLO] = x; eieio();
+ p->cmap_regs[PIDXDATA] = 0x00; eieio();
+ }
+ p->cmap_regs[PIDXHI] = 1; eieio();
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width >> 2; x++) {
+ p->cmap_regs[PIDXLO] = x + y * 8; eieio();
+ p->cmap_regs[PIDXDATA] = 0xff; eieio();
+ }
+
return 1;
}
@@ -845,64 +879,59 @@
{
struct imstt_cursor *c = &p->cursor;
+ imsttfb_set_font(&p->disp, fontwidth(&p->disp), fontheight(&p->disp));
+
c->enable = 1;
c->on = 1;
- c->blink_rate = CURSOR_BLINK_RATE;
- c->vbl_cnt = CURSOR_DRAW_DELAY;
c->x = c->y = 0;
+ c->blink_rate = 0;
+ c->vbl_cnt = CURSOR_DRAW_DELAY;
- init_timer(&c->timer);
- c->timer.expires = jiffies + (HZ / 50);
- c->timer.data = (unsigned long)p;
- c->timer.function = imstt_cursor_timer_handler;
- add_timer(&c->timer);
+ if (curblink) {
+ c->blink_rate = CURSOR_BLINK_RATE;
+ init_timer(&c->timer);
+ c->timer.expires = jiffies + (HZ / 50);
+ c->timer.data = (unsigned long)p;
+ c->timer.function = imstt_cursor_timer_handler;
+ add_timer(&c->timer);
+ }
}
static void
imsttfb_rectcopy (struct display *disp, int sy, int sx, int dy, int dx, int height, int width)
{
struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info;
- __u32 cnt_reg, stat, xxx = 0;
- __u32 line_pitch = disp->var.xres * (disp->var.bits_per_pixel >> 3),
- rect_height = height,
- rect_width = width * (disp->var.bits_per_pixel >> 3),
- fb_offset_old = sy * line_pitch + (sx * (disp->var.bits_per_pixel >> 3)),
- fb_offset_new = dy * line_pitch + (dx * (disp->var.bits_per_pixel >> 3));
+ __u32 Bpp = disp->var.bits_per_pixel >> 3,
+ line_pitch = disp->line_length,
+ fb_offset_old, fb_offset_new;
- stat = in_le32(&p->dc_regs[SSTATUS]) & 0xff;
+ fb_offset_old = sy * line_pitch + sx * Bpp;
+ fb_offset_new = dy * line_pitch + dx * Bpp;
- cnt_reg = ((rect_height - 1) << 16) | (rect_width - 1);
- out_le32(&p->dc_regs[CNT], cnt_reg);
+ while (in_le32(&p->dc_regs[SSTATUS]) & 0x80);
+ out_le32(&p->dc_regs[CNT], ((height - 1) << 16) | (width * Bpp - 1));
out_le32(&p->dc_regs[S1SA], fb_offset_old);
- out_le32(&p->dc_regs[DSA], fb_offset_old);
- out_le32(&p->dc_regs[SP], line_pitch);
- out_le32(&p->dc_regs[DP_OCTRL], line_pitch);
- out_le32(&p->dc_regs[BLTCTL], 0x5);
-
- if (++stat == 0x20)
- stat = 0x10;
- while ((in_le32(&p->dc_regs[SSTATUS]) & 0xff) != stat && xxx++ < 0xff)
- eieio();
-
- cnt_reg = ((rect_height - 1) << 16) | (0xffff - (rect_width - 2));
- out_le32(&p->dc_regs[CNT], cnt_reg);
+ /* out_le32(&p->dc_regs[S2SA], fb_offset_new); */
out_le32(&p->dc_regs[DSA], fb_offset_new);
-#if 0
- out_le32(&p->dc_regs[S1SA], fb_offset_old);
- out_le32(&p->dc_regs[SP], line_pitch);
- out_le32(&p->dc_regs[DP_OCTRL], line_pitch);
-#endif
- out_le32(&p->dc_regs[BLTCTL], 0x85);
-
- if (++stat == 0x20)
- stat = 0x10;
- while ((in_le32(&p->dc_regs[SSTATUS]) & 0xff) != stat && xxx++ < 0xff)
- eieio();
+ out_le32(&p->dc_regs[BLTCTL], 0xc0000005);
+ while (in_le32(&p->dc_regs[SSTATUS]) & 0x80);
+ while (in_le32(&p->dc_regs[SSTATUS]) & 0x40);
}
static void
imsttfbcon_bmove (struct display *disp, int sy, int sx, int dy, int dx, int height, int width)
{
+ /* XXX .. */
+ if (sy < dy || (sy == dy && sx < dx)) {
+ switch (disp->var.bits_per_pixel) {
+ case 8: fbcon_cfb8_bmove(disp, sy, sx, dy, dx, height, width); break;
+ case 16: fbcon_cfb16_bmove(disp, sy, sx, dy, dx, height, width); break;
+ case 24: fbcon_cfb24_bmove(disp, sy, sx, dy, dx, height, width); break;
+ case 32: fbcon_cfb32_bmove(disp, sy, sx, dy, dx, height, width); break;
+ }
+ return;
+ }
+
sy *= fontheight(disp);
sx *= fontwidth(disp);
dy *= fontheight(disp);
@@ -1020,7 +1049,7 @@
p->palette[regno].blue = blue;
/* PADDRW/PDATA are the same as TVPPADDRW/TVPPDATA */
- if (p->ramdac == TVP && fb_display[currcon].var.green.length == 5 /* && bpp == 16 */) {
+ if (bpp == 16 && p->ramdac == TVP && fb_display[currcon].var.green.length == 5) {
p->cmap_regs[PADDRW] = regno << 3; eieio();
} else {
p->cmap_regs[PADDRW] = regno; eieio();
@@ -1100,12 +1129,10 @@
}
static void
-set_dispsw (struct display *disp, struct fb_info_imstt *p)
+set_disp (struct display *disp, struct fb_info_imstt *p)
{
u_int accel = disp->var.accel_flags & FB_ACCELF_TEXT;
- disp->visual = disp->var.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR
- : FB_VISUAL_DIRECTCOLOR;
p->dispsw = fbcon_dummy;
disp->dispsw = &p->dispsw;
disp->dispsw_data = 0;
@@ -1124,7 +1151,7 @@
#endif
break;
case 16: /* RGB 555 */
- if (disp->var.red.offset != 11)
+ if (disp->var.green.length != 6)
disp->var.red.offset = 10;
disp->var.red.length = 5;
disp->var.green.offset = 5;
@@ -1173,6 +1200,47 @@
p->dispsw.cursor = imsttfb_cursor;
p->dispsw.set_font = imsttfb_set_font;
}
+
+ disp->visual = disp->var.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR
+ : FB_VISUAL_DIRECTCOLOR;
+ disp->screen_base = (__u8 *)p->frame_buffer;
+ disp->visual = p->fix.visual;
+ disp->type = p->fix.type;
+ disp->type_aux = p->fix.type_aux;
+ disp->line_length = disp->var.xres * (disp->var.bits_per_pixel >> 3);
+ disp->can_soft_blank = 1;
+ disp->inverse = 0;
+ disp->ypanstep = 1;
+ disp->ywrapstep = 0;
+ if (accel) {
+ disp->scrollmode = SCROLL_YNOMOVE;
+ if (disp->var.yres == disp->var.yres_virtual) {
+ __u32 vram = (p->total_vram - (PAGE_SIZE << 2));
+ disp->var.yres_virtual = ((vram << 3) / disp->var.bits_per_pixel) / disp->var.xres_virtual;
+ if (disp->var.yres_virtual < disp->var.yres)
+ disp->var.yres_virtual = disp->var.yres;
+ }
+ } else {
+ disp->scrollmode = SCROLL_YREDRAW;
+ disp->var.yoffset = disp->var.xoffset = 0;
+ out_le32(&p->dc_regs[SSR], 0);
+ }
+
+ disp->var.activate = 0;
+ disp->var.red.msb_right = 0;
+ disp->var.green.msb_right = 0;
+ disp->var.blue.msb_right = 0;
+ disp->var.transp.msb_right = 0;
+ disp->var.height = -1;
+ disp->var.width = -1;
+ disp->var.vmode = FB_VMODE_NONINTERLACED;
+ disp->var.left_margin = disp->var.right_margin = 16;
+ disp->var.upper_margin = disp->var.lower_margin = 16;
+ disp->var.hsync_len = disp->var.vsync_len = 8;
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+ set_display_info(disp);
+#endif
}
static int
@@ -1180,7 +1248,7 @@
{
struct fb_info_imstt *p = (struct fb_info_imstt *)info;
struct display *disp;
- u_int oldbpp, oldxres, oldyres, oldgreenlen, oldaccel;
+ u_int oldbpp, oldxres, oldyres, oldgreenlen;
disp = &fb_display[con];
@@ -1205,37 +1273,16 @@
oldxres = disp->var.xres;
oldyres = disp->var.yres;
oldgreenlen = disp->var.green.length;
- oldaccel = disp->var.accel_flags;
-
- disp->var = *var;
-
- disp->var.activate = 0;
- disp->var.red.msb_right = 0;
- disp->var.green.msb_right = 0;
- disp->var.blue.msb_right = 0;
- disp->var.transp.msb_right = 0;
- disp->var.height = -1;
- disp->var.width = -1;
- disp->var.vmode = FB_VMODE_NONINTERLACED;
- disp->var.left_margin = disp->var.right_margin = 16;
- disp->var.upper_margin = disp->var.lower_margin = 16;
- disp->var.hsync_len = disp->var.vsync_len = 8;
- disp->screen_base = p->frame_buffer;
- disp->inverse = 0;
- disp->ypanstep = 1;
- disp->ywrapstep = 0;
- disp->scrollmode = SCROLL_YREDRAW;
+ disp->var.bits_per_pixel = var->bits_per_pixel;
+ disp->var.xres = var->xres;
+ disp->var.yres = var->yres;
+ disp->var.xres_virtual = var->xres_virtual;
+ disp->var.yres_virtual = var->yres_virtual;
+ disp->var.green.length = var->green.length;
+ disp->var.accel_flags = var->accel_flags;
- if (oldbpp != disp->var.bits_per_pixel || oldgreenlen != disp->var.green.length || oldaccel != disp->var.accel_flags)
- set_dispsw(disp, p);
-
- if (oldxres != disp->var.xres || oldbpp != disp->var.bits_per_pixel)
- disp->line_length = disp->var.xres * (disp->var.bits_per_pixel >> 3);
-
-#ifdef CONFIG_FB_COMPAT_XPMAC
- set_display_info(disp);
-#endif
+ set_disp(disp, p);
if (info->changevar)
(*info->changevar)(con);
@@ -1267,17 +1314,18 @@
imsttfb_pan_display (struct fb_var_screeninfo *var, int con, struct fb_info *info)
{
struct fb_info_imstt *p = (struct fb_info_imstt *)info;
- u_int off;
+ struct display *disp = &fb_display[con];
+ __u32 off;
- if (var->xoffset + fb_display[con].var.xres > fb_display[con].var.xres_virtual
- || var->yoffset + fb_display[con].var.yres > fb_display[con].var.yres_virtual)
+ if (var->xoffset + disp->var.xres > disp->var.xres_virtual
+ || var->yoffset + disp->var.yres > disp->var.yres_virtual)
return -EINVAL;
- fb_display[con].var.xoffset = var->xoffset;
- fb_display[con].var.yoffset = var->yoffset;
+ disp->var.xoffset = var->xoffset;
+ disp->var.yoffset = var->yoffset;
if (con == currcon) {
- off = var->yoffset * (fb_display[con].line_length / 8)
- + (var->xoffset * (fb_display[con].var.bits_per_pixel >> 3)) / 8;
+ off = var->yoffset * (disp->line_length >> 3)
+ + ((var->xoffset * (disp->var.bits_per_pixel >> 3)) >> 3);
out_le32(&p->dc_regs[SSR], off);
}
@@ -1321,8 +1369,8 @@
#define FBIMSTT_GETREG 0x545402
#define FBIMSTT_SETCMAPREG 0x545403
#define FBIMSTT_GETCMAPREG 0x545404
-#define FBIMSTT_SETINITREG 0x545405
-#define FBIMSTT_GETINITREG 0x545406
+#define FBIMSTT_SETIDXREG 0x545405
+#define FBIMSTT_GETIDXREG 0x545406
static int
imsttfb_ioctl (struct inode *inode, struct file *file, u_int cmd,
@@ -1337,34 +1385,34 @@
if (copy_from_user(reg, (void *)arg, 8) || reg[0] > (0x40000 - sizeof(reg[0])) / sizeof(reg[0]))
return -EFAULT;
out_le32(&p->dc_regs[reg[0]], reg[1]);
- break;
+ return 0;
case FBIMSTT_GETREG:
if (copy_from_user(reg, (void *)arg, 4) || reg[0] > (0x40000 - sizeof(reg[0])) / sizeof(reg[0]))
return -EFAULT;
reg[1] = in_le32(&p->dc_regs[reg[0]]);
if (copy_to_user((void *)(arg + 4), ®[1], 4))
return -EFAULT;
- break;
+ return 0;
case FBIMSTT_SETCMAPREG:
if (copy_from_user(reg, (void *)arg, 8) || reg[0] > (0x17c0000 - sizeof(reg[0])) / sizeof(reg[0]))
return -EFAULT;
out_le32(&((u_int *)p->cmap_regs)[reg[0]], reg[1]);
- break;
+ return 0;
case FBIMSTT_GETCMAPREG:
if (copy_from_user(reg, (void *)arg, 4) || reg[0] > (0x17c0000 - sizeof(reg[0])) / sizeof(reg[0]))
return -EFAULT;
reg[1] = in_le32(&((u_int *)p->cmap_regs)[reg[0]]);
if (copy_to_user((void *)(arg + 4), ®[1], 4))
return -EFAULT;
- break;
- case FBIMSTT_SETINITREG:
+ return 0;
+ case FBIMSTT_SETIDXREG:
if (copy_from_user(init, (void *)arg, 2))
return -EFAULT;
p->cmap_regs[PIDXHI] = 0; eieio();
p->cmap_regs[PIDXLO] = init[0]; eieio();
p->cmap_regs[PIDXDATA] = init[1]; eieio();
- break;
- case FBIMSTT_GETINITREG:
+ return 0;
+ case FBIMSTT_GETIDXREG:
if (copy_from_user(init, (void *)arg, 1))
return -EFAULT;
p->cmap_regs[PIDXHI] = 0; eieio();
@@ -1372,12 +1420,10 @@
init[1] = p->cmap_regs[PIDXDATA];
if (copy_to_user((void *)(arg + 1), &init[1], 1))
return -EFAULT;
- break;
+ return 0;
default:
return -ENOIOCTLCMD;
}
-
- return 0;
}
static struct fb_ops imsttfb_ops = {
@@ -1397,6 +1443,7 @@
{
struct fb_info_imstt *p = (struct fb_info_imstt *)info;
struct display *old = &fb_display[currcon], *new = &fb_display[con];
+ __u32 off;
if (old->cmap.len)
fb_get_cmap(&old->cmap, 1, imsttfb_getcolreg, info);
@@ -1410,7 +1457,7 @@
|| old->var.yres != new->var.yres
|| old->var.bits_per_pixel != new->var.bits_per_pixel
|| old->var.green.length != new->var.green.length) {
- set_dispsw(new, p);
+ set_disp(new, p);
if (!compute_imstt_regvals(p, new->var.xres, new->var.yres))
return -1;
if (new->var.bits_per_pixel == 16) {
@@ -1420,9 +1467,11 @@
set_555(p);
}
set_imstt_regvals(p, new->var.bits_per_pixel);
-#ifdef CONFIG_FB_COMPAT_XPMAC
- set_display_info(new);
-#endif
+ }
+ if (old->var.yoffset != new->var.yoffset || old->var.xoffset != new->var.xoffset) {
+ off = new->var.yoffset * (new->line_length >> 3)
+ + ((new->var.xoffset * (new->var.bits_per_pixel >> 3)) >> 3);
+ out_le32(&p->dc_regs[SSR], off);
}
do_install_cmap(con, info);
@@ -1430,18 +1479,44 @@
return 0;
}
+static inline void
+imsttfb_rectfill (struct display *disp, u_int sy, u_int sx, u_int height, u_int width, __u32 bgx)
+{
+ memset(disp->screen_base + sy + sx, bgx, height * width * (disp->var.bits_per_pixel >> 3));
+}
+
static int
imsttfbcon_updatevar (int con, struct fb_info *info)
{
struct fb_info_imstt *p = (struct fb_info_imstt *)info;
- u_int off;
+ struct display *disp = &fb_display[con];
+ struct vc_data *conp = disp->conp;
+ __u32 off, yres, yoffset, sy, height;
- if (con == currcon) {
- off = fb_display[con].var.yoffset * (fb_display[con].line_length / 8)
- + (fb_display[con].var.xoffset * (fb_display[con].var.bits_per_pixel >> 3)) / 8;
- out_le32(&p->dc_regs[SSR], off);
+ if (con != currcon)
+ goto out;
+
+ yres = disp->var.yres;
+ yoffset = disp->var.yoffset;
+ sy = (conp->vc_rows + disp->yscroll) * fontheight(disp);
+ height = yres - conp->vc_rows * fontheight(disp);
+
+ if (height && (yoffset + yres > sy)) {
+ __u32 bgx = attr_bgcol_ec(disp, conp);
+
+ if (sy + height > disp->var.yres_virtual)
+ printk("updatevar: %u + %u > %u\n", sy, height, disp->var.yres_virtual);
+ imsttfb_rectfill(disp, sy, disp->var.xoffset, height, disp->var.xres, bgx);
}
+ if (p->ramdac == IBM && (yoffset + yres <= sy))
+ imsttfb_cursor(disp, CM_ERASE, p->cursor.x, p->cursor.y);
+
+ off = disp->var.yoffset * (disp->line_length >> 3)
+ + ((disp->var.xoffset * (disp->var.bits_per_pixel >> 3)) >> 3);
+ out_le32(&p->dc_regs[SSR], off);
+
+out:
return 0;
}
@@ -1455,7 +1530,21 @@
if (blank > 0) {
switch (blank - 1) {
case VESA_NO_BLANKING:
+ case VESA_POWERDOWN:
ctrl &= ~0x00000380;
+ if (p->ramdac == IBM) {
+ p->cmap_regs[PIDXHI] = 0; eieio();
+ p->cmap_regs[PIDXLO] = MISCTL2; eieio();
+ p->cmap_regs[PIDXDATA] = 0x55; eieio();
+ p->cmap_regs[PIDXLO] = MISCTL1; eieio();
+ p->cmap_regs[PIDXDATA] = 0x11; eieio();
+ p->cmap_regs[PIDXLO] = SYNCCTL; eieio();
+ p->cmap_regs[PIDXDATA] = 0x0f; eieio();
+ p->cmap_regs[PIDXLO] = PWRMNGMT;eieio();
+ p->cmap_regs[PIDXDATA] = 0x1f; eieio();
+ p->cmap_regs[PIDXLO] = CLKCTL; eieio();
+ p->cmap_regs[PIDXDATA] = 0xc0;
+ }
break;
case VESA_VSYNC_SUSPEND:
ctrl &= ~0x00000020;
@@ -1463,12 +1552,23 @@
case VESA_HSYNC_SUSPEND:
ctrl &= ~0x00000010;
break;
- case VESA_POWERDOWN:
- ctrl &= ~0x00000380;
- break;
}
} else {
- ctrl |= p->ramdac == IBM ? 0x000017b0 : 0x00001780;
+ if (p->ramdac == IBM) {
+ ctrl |= 0x000017b0;
+ p->cmap_regs[PIDXHI] = 0; eieio();
+ p->cmap_regs[PIDXLO] = CLKCTL; eieio();
+ p->cmap_regs[PIDXDATA] = 0x01; eieio();
+ p->cmap_regs[PIDXLO] = PWRMNGMT;eieio();
+ p->cmap_regs[PIDXDATA] = 0x00; eieio();
+ p->cmap_regs[PIDXLO] = SYNCCTL; eieio();
+ p->cmap_regs[PIDXDATA] = 0x00; eieio();
+ p->cmap_regs[PIDXLO] = MISCTL1; eieio();
+ p->cmap_regs[PIDXDATA] = 0x01; eieio();
+ p->cmap_regs[PIDXLO] = MISCTL2; eieio();
+ p->cmap_regs[PIDXDATA] = 0x45; eieio();
+ } else
+ ctrl |= 0x00001780;
}
out_le32(&p->dc_regs[STGCTL], ctrl);
}
@@ -1477,6 +1577,7 @@
init_imstt(struct fb_info_imstt *p))
{
__u32 i, tmp;
+ __u32 *ip, *end;
tmp = in_le32(&p->dc_regs[PRC]);
if (p->ramdac == IBM)
@@ -1484,15 +1585,19 @@
else
p->total_vram = 0x00800000;
- memset(p->frame_buffer, 0, p->total_vram);
+ ip = (__u32 *)p->frame_buffer;
+ end = (__u32 *)(p->frame_buffer + p->total_vram);
+ while (ip < end)
+ *ip++ = 0;
/* initialize the card */
tmp = in_le32(&p->dc_regs[STGCTL]);
out_le32(&p->dc_regs[STGCTL], tmp & ~0x1);
+ out_le32(&p->dc_regs[SSR], 0);
/* set default values for DAC registers */
if (p->ramdac == IBM) {
- p->cmap_regs[PPMASK] = 0xff;
+ p->cmap_regs[PPMASK] = 0xff; eieio();
p->cmap_regs[PIDXHI] = 0; eieio();
for (i = 0; i < sizeof(ibm_initregs) / sizeof(*ibm_initregs); i++) {
p->cmap_regs[PIDXLO] = ibm_initregs[i].addr; eieio();
@@ -1507,14 +1612,18 @@
#if USE_NV_MODES && defined(CONFIG_PPC)
{
- int vmode, cmode;
+ int vmode = init_vmode, cmode = init_cmode;
- vmode = nvram_read_byte(NV_VMODE);
- if (vmode <= 0 || vmode > VMODE_MAX)
- vmode = VMODE_640_480_67;
- cmode = nvram_read_byte(NV_CMODE);
- if (cmode < CMODE_8 || cmode > CMODE_32)
- cmode = CMODE_8;
+ if (vmode == -1) {
+ vmode = nvram_read_byte(NV_VMODE);
+ if (vmode <= 0 || vmode > VMODE_MAX)
+ vmode = VMODE_640_480_67;
+ }
+ if (cmode == -1) {
+ cmode = nvram_read_byte(NV_CMODE);
+ if (cmode < CMODE_8 || cmode > CMODE_32)
+ cmode = CMODE_8;
+ }
if (mac_vmode_to_var(vmode, cmode, &p->disp.var)) {
p->disp.var.xres = p->disp.var.xres_virtual = INIT_XRES;
p->disp.var.yres = p->disp.var.yres_virtual = INIT_YRES;
@@ -1527,22 +1636,6 @@
p->disp.var.bits_per_pixel = INIT_BPP;
#endif
- p->disp.var.height = p->disp.var.width = -1;
- p->disp.var.vmode = FB_VMODE_NONINTERLACED;
- p->disp.var.left_margin = p->disp.var.right_margin = 16;
- p->disp.var.upper_margin = p->disp.var.lower_margin = 16;
- p->disp.var.hsync_len = p->disp.var.vsync_len = 8;
- p->disp.var.accel_flags = 0; /* FB_ACCELF_TEXT; */
-
- set_dispsw(&p->disp, p);
- if (p->ramdac == IBM)
- imstt_cursor_init(p);
-
- if (p->disp.var.green.length == 6)
- set_565(p);
- else
- set_555(p);
-
if ((p->disp.var.xres * p->disp.var.yres) * (p->disp.var.bits_per_pixel >> 3) > p->total_vram
|| !(compute_imstt_regvals(p, p->disp.var.xres, p->disp.var.yres))) {
printk("imsttfb: %ux%ux%u not supported\n", p->disp.var.xres, p->disp.var.yres, p->disp.var.bits_per_pixel);
@@ -1550,10 +1643,6 @@
return;
}
- set_imstt_regvals(p, p->disp.var.bits_per_pixel);
-
- p->disp.var.pixclock = 1000000 / getclkMHz(p);
-
sprintf(p->fix.id, "IMS TT (%s)", p->ramdac == IBM ? "IBM" : "TVP");
p->fix.smem_start = (__u8 *)p->frame_buffer_phys;
p->fix.smem_len = p->total_vram;
@@ -1568,21 +1657,24 @@
p->fix.ypanstep = 1;
p->fix.ywrapstep = 0;
- p->disp.screen_base = p->frame_buffer;
- p->disp.visual = p->fix.visual;
- p->disp.type = p->fix.type;
- p->disp.type_aux = p->fix.type_aux;
- p->disp.line_length = p->fix.line_length;
- p->disp.can_soft_blank = 1;
- p->disp.ypanstep = 1;
- p->disp.ywrapstep = 0;
- p->disp.scrollmode = SCROLL_YREDRAW;
+ p->disp.var.accel_flags = noaccel ? 0 : FB_ACCELF_TEXT;
+ set_disp(&p->disp, p);
+
+ if (p->ramdac == IBM)
+ imstt_cursor_init(p);
+ if (p->disp.var.green.length == 6)
+ set_565(p);
+ else
+ set_555(p);
+ set_imstt_regvals(p, p->disp.var.bits_per_pixel);
+
+ p->disp.var.pixclock = 1000000 / getclkMHz(p);
strcpy(p->info.modename, p->fix.id);
+ strcpy(p->info.fontname, fontname);
p->info.node = -1;
p->info.fbops = &imsttfb_ops;
p->info.disp = &p->disp;
- p->info.fontname[0] = 0;
p->info.changevar = 0;
p->info.switch_con = &imsttfbcon_switch;
p->info.updatevar = &imsttfbcon_updatevar;
@@ -1606,18 +1698,18 @@
GET_FB_IDX(p->info.node), p->fix.id, p->total_vram >> 20, tmp);
#ifdef CONFIG_FB_COMPAT_XPMAC
- strncpy(display_info.name, p->fix.id, sizeof display_info.name);
+ strncpy(display_info.name, "IMS,tt128mb", sizeof(display_info.name));
display_info.fb_address = (__u32)p->frame_buffer_phys;
display_info.cmap_adr_address = (__u32)&p->cmap_regs_phys[PADDRW];
display_info.cmap_data_address = (__u32)&p->cmap_regs_phys[PDATA];
- display_info.disp_reg_address = 0;
+ display_info.disp_reg_address = (__u32)p->dc_regs_phys;
set_display_info(&p->disp);
if (!console_fb_info)
console_fb_info = &p->info;
#endif /* CONFIG_FB_COMPAT_XPMAC */
}
-#if defined(CONFIG_FB_OF) || defined(CONFIG_PPC)
+#if defined(CONFIG_FB_OF)
__initfunc(void
imsttfb_of_init(struct device_node *dp))
{
@@ -1667,22 +1759,60 @@
__initfunc(void
imsttfb_init(void))
{
-#if defined(CONFIG_PPC)
- u_int i;
- struct device_node *dp;
- char *names[4] = {"IMS,tt128mb","IMS,tt128mbA","IMS,tt128mb8","IMS,tt128mb8A"};
+#if !defined(CONFIG_FB_OF)
+ /* ... */
+#endif
+}
-#ifdef CONFIG_FB_OF
- if (prom_num_displays)
+__initfunc(void
+imsttfb_setup(char *options, int *ints))
+{
+ char *this_opt;
+
+ if (!options || !*options)
return;
-#endif
- for (i = 0; i < 4; i++) {
- dp = find_devices(names[i]);
- if (dp)
- imsttfb_of_init(dp);
- }
-#else
- /* ... */
+ for (this_opt = strtok(options, ","); this_opt;
+ this_opt = strtok(NULL, ",")) {
+ if (!strncmp(this_opt, "font:", 5)) {
+ char *p;
+ int i;
+
+ p = this_opt + 5;
+ for (i = 0; i < sizeof(fontname) - 1; i++)
+ if (!*p || *p == ' ' || *p == ',')
+ break;
+ memcpy(fontname, this_opt + 5, i);
+ fontname[i] = 0;
+ } else if (!strncmp(this_opt, "noblink", 7)) {
+ curblink = 0;
+ } else if (!strncmp(this_opt, "noaccel", 7)) {
+ noaccel = 1;
+ }
+#if defined(CONFIG_PPC)
+ else if (!strncmp(this_opt, "vmode:", 6)) {
+ int vmode = simple_strtoul(this_opt+6, NULL, 0);
+ if (vmode > 0 && vmode <= VMODE_MAX)
+ init_vmode = vmode;
+ } else if (!strncmp(this_opt, "cmode:", 6)) {
+ int cmode = simple_strtoul(this_opt+6, NULL, 0);
+ switch (cmode) {
+ case CMODE_8:
+ case 8:
+ init_cmode = CMODE_8;
+ break;
+ case CMODE_16:
+ case 15:
+ case 16:
+ init_cmode = CMODE_16;
+ break;
+ case CMODE_32:
+ case 24:
+ case 32:
+ init_cmode = CMODE_32;
+ break;
+ }
+ }
#endif
+ }
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov