diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-01-04 16:03:48 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-01-04 16:03:48 +0000 |
commit | 78c388aed2b7184182c08428db1de6c872d815f5 (patch) | |
tree | 4b2003b1b4ceb241a17faa995da8dd1004bb8e45 /drivers/video/chipsfb.c | |
parent | eb7a5bf93aaa4be1d7c6181100ab7639e74d67f7 (diff) |
Merge with Linux 2.1.131 and more MIPS goodies.
(Did I mention that CVS is buggy ...)
Diffstat (limited to 'drivers/video/chipsfb.c')
-rw-r--r-- | drivers/video/chipsfb.c | 239 |
1 files changed, 195 insertions, 44 deletions
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c index c13954030..699ae96ff 100644 --- a/drivers/video/chipsfb.c +++ b/drivers/video/chipsfb.c @@ -38,10 +38,10 @@ #include <asm/adb.h> #include <asm/pmu.h> -#include "fbcon.h" -#include "fbcon-cfb8.h" -#include "fbcon-cfb16.h" -#include "macmodes.h" +#include <video/fbcon.h> +#include <video/fbcon-cfb8.h> +#include <video/fbcon-cfb16.h> +#include <video/macmodes.h> static int currcon = 0; @@ -62,15 +62,40 @@ struct fb_info_chips { #ifdef CONFIG_PMAC_PBOOK unsigned char *save_framebuffer; #endif +#ifdef FBCON_HAS_CFB16 + u16 fbcon_cfb16_cmap[16]; +#endif }; -#define write_xr(num,val) { out_8(p->io_base + 0x3D6, num); out_8(p->io_base + 0x3D7, val); } -#define read_xr(num,var) { out_8(p->io_base + 0x3D6, num); var = in_8(p->io_base + 0x3D7); } -#define write_fr(num,val) { out_8(p->io_base + 0x3D0, num); out_8(p->io_base + 0x3D1, val); } -#define read_fr(num,var) { out_8(p->io_base + 0x3D0, num); var = in_8(p->io_base + 0x3D1); } -#define write_cr(num,val) { out_8(p->io_base + 0x3D4, num); out_8(p->io_base + 0x3D5, val); } -#define read_cr(num,var) { out_8(p->io_base + 0x3D4, num); var = in_8(p->io_base + 0x3D5); } - +#define write_ind(num, val, ap, dp) do { \ + out_8(p->io_base + (ap), (num)); out_8(p->io_base + (dp), (val)); \ +} while (0) +#define read_ind(num, var, ap, dp) do { \ + out_8(p->io_base + (ap), (num)); var = in_8(p->io_base + (dp)); \ +} while (0); + +/* extension registers */ +#define write_xr(num, val) write_ind(num, val, 0x3d6, 0x3d7) +#define read_xr(num, var) read_ind(num, var, 0x3d6, 0x3d7) +/* flat panel registers */ +#define write_fr(num, val) write_ind(num, val, 0x3d0, 0x3d1) +#define read_fr(num, var) read_ind(num, var, 0x3d0, 0x3d1) +/* CRTC registers */ +#define write_cr(num, val) write_ind(num, val, 0x3d4, 0x3d5) +#define read_cr(num, var) read_ind(num, var, 0x3d4, 0x3d5) +/* graphics registers */ +#define write_gr(num, val) write_ind(num, val, 0x3ce, 0x3cf) +#define read_gr(num, var) read_ind(num, var, 0x3ce, 0x3cf) +/* sequencer registers */ +#define write_sr(num, val) write_ind(num, val, 0x3c4, 0x3c5) +#define read_sr(num, var) read_ind(num, var, 0x3c4, 0x3c5) +/* attribute registers - slightly strange */ +#define write_ar(num, val) do { \ + in_8(p->io_base + 0x3da); write_ind(num, val, 0x3c0, 0x3c0); \ +} while (0) +#define read_ar(num, var) do { \ + in_8(p->io_base + 0x3da); read_ind(num, var, 0x3c0, 0x3c1); \ +} while (0) static struct fb_info_chips *all_chips; @@ -187,8 +212,7 @@ static int chips_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { if (con == currcon) /* current console? */ - return fb_get_cmap(cmap, &fb_display[con].var, kspc, - chipsfb_getcolreg, info); + return fb_get_cmap(cmap, kspc, chipsfb_getcolreg, info); if (fb_display[con].cmap.len) /* non default colormap? */ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc? 0: 2); else @@ -209,8 +233,7 @@ static int chips_set_cmap(struct fb_cmap *cmap, int kspc, int con, } if (con == currcon) - return fb_set_cmap(cmap, &disp->var, kspc, chipsfb_setcolreg, - info); + return fb_set_cmap(cmap, kspc, chipsfb_setcolreg, info); fb_copy_cmap(cmap, &disp->cmap, kspc==0); return 0; } @@ -229,9 +252,7 @@ static int chipsfb_switch(int con, struct fb_info *info) int bit_depth; if (fb_display[currcon].cmap.len) - fb_get_cmap(&old_disp->cmap, - &old_disp->var, 1, chipsfb_getcolreg, - info); + fb_get_cmap(&old_disp->cmap, 1, chipsfb_getcolreg, info); bit_depth = new_disp->var.bits_per_pixel; if (old_disp->var.bits_per_pixel != bit_depth) @@ -279,9 +300,10 @@ static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green, if (regno > 255) return 1; - *red = p->palette[regno].red; - *green = p->palette[regno].green; - *blue = p->palette[regno].blue; + *red = (p->palette[regno].red<<8) | p->palette[regno].red; + *green = (p->palette[regno].green<<8) | p->palette[regno].green; + *blue = (p->palette[regno].blue<<8) | p->palette[regno].blue; + *transp = 0; return 0; } @@ -289,21 +311,26 @@ static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { struct fb_info_chips *p = (struct fb_info_chips *) info; + int hr; - if (regno > 255) + hr = (p->fix.visual != FB_VISUAL_PSEUDOCOLOR)? (regno << 3): regno; + if (hr > 255) return 1; + red >>= 8; + green >>= 8; + blue >>= 8; p->palette[regno].red = red; p->palette[regno].green = green; p->palette[regno].blue = blue; - out_8(p->io_base + 0x3c8, regno); + out_8(p->io_base + 0x3c8, hr); udelay(1); out_8(p->io_base + 0x3c9, red); out_8(p->io_base + 0x3c9, green); out_8(p->io_base + 0x3c9, blue); #ifdef FBCON_HAS_CFB16 - if (regno < 16) - fbcon_cfb16_cmap[regno] = (red << 10) | (green << 5) | blue; + if (regno < 16) + p->fbcon_cfb16_cmap[regno] = (red << 10) | (green << 5) | blue; #endif return 0; @@ -314,18 +341,13 @@ static void do_install_cmap(int con, struct fb_info *info) if (con != currcon) return; if (fb_display[con].cmap.len) - fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1, - chipsfb_setcolreg, info); - else - fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), &fb_display[con].var, 1, - chipsfb_setcolreg, info); + fb_set_cmap(&fb_display[con].cmap, 1, chipsfb_setcolreg, info); + else { + int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256; + fb_set_cmap(fb_default_cmap(size), 1, chipsfb_setcolreg, info); + } } -#ifdef CONFIG_FB_COMPAT_XPMAC -/* from drivers/macintosh/pmac-cons.h */ -#define VMODE_800_600_60 10 /* 800x600, 60Hz */ -#endif /* CONFIG_FB_COMPAT_XPMAC */ - static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, int con, int bpp) { int err; @@ -336,12 +358,11 @@ static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, in if (con == currcon) { write_cr(0x13, 200); // 16 bit display width (decimal) write_xr(0x81, 0x14); // 15 bit (TrueColor) color mode - write_xr(0x82, 0x00); // disable palettes write_xr(0x20, 0x10); // 16 bit blitter mode } fix->line_length = 800*2; - fix->visual = FB_VISUAL_TRUECOLOR; + fix->visual = FB_VISUAL_DIRECTCOLOR; var->red.offset = 10; var->green.offset = 5; @@ -350,14 +371,14 @@ static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, in #ifdef FBCON_HAS_CFB16 disp->dispsw = &fbcon_cfb16; + disp->dispsw_data = p->fbcon_cfb16_cmap; #else - disp->dispsw = NULL; + disp->dispsw = &fbcon_dummy; #endif - } else if (bpp == 8) { + } else if (bpp == 8) { if (con == currcon) { write_cr(0x13, 100); // 8 bit display width (decimal) write_xr(0x81, 0x12); // 8 bit color mode - write_xr(0x82, 0x08); // Graphics gamma enable write_xr(0x20, 0x00); // 8 bit blitter mode } @@ -370,7 +391,7 @@ static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, in #ifdef FBCON_HAS_CFB8 disp->dispsw = &fbcon_cfb8; #else - disp->dispsw = NULL; + disp->dispsw = &fbcon_dummy; #endif } @@ -392,11 +413,139 @@ static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, in do_install_cmap(con, (struct fb_info *)p); } +struct chips_init_reg { + unsigned char addr; + unsigned char data; +}; + +#define N_ELTS(x) (sizeof(x) / sizeof(x[0])) + +static struct chips_init_reg chips_init_sr[] = { + { 0x00, 0x03 }, + { 0x01, 0x01 }, + { 0x02, 0x0f }, + { 0x04, 0x0e } +}; + +static struct chips_init_reg chips_init_gr[] = { + { 0x05, 0x00 }, + { 0x06, 0x0d }, + { 0x08, 0xff } +}; + +static struct chips_init_reg chips_init_ar[] = { + { 0x10, 0x01 }, + { 0x12, 0x0f }, + { 0x13, 0x00 } +}; + +static struct chips_init_reg chips_init_cr[] = { + { 0x00, 0x7f }, + { 0x01, 0x63 }, + { 0x02, 0x63 }, + { 0x03, 0x83 }, + { 0x04, 0x66 }, + { 0x05, 0x10 }, + { 0x06, 0x72 }, + { 0x07, 0x3e }, + { 0x08, 0x00 }, + { 0x09, 0x40 }, + { 0x0c, 0x00 }, + { 0x0d, 0x00 }, + { 0x10, 0x59 }, + { 0x11, 0x0d }, + { 0x12, 0x57 }, + { 0x13, 0x64 }, + { 0x14, 0x00 }, + { 0x15, 0x57 }, + { 0x16, 0x73 }, + { 0x17, 0xe3 }, + { 0x18, 0xff }, + { 0x30, 0x02 }, + { 0x31, 0x02 }, + { 0x32, 0x02 }, + { 0x33, 0x02 }, + { 0x40, 0x00 }, + { 0x41, 0x00 }, + { 0x40, 0x80 } +}; + +static struct chips_init_reg chips_init_fr[] = { + { 0x01, 0x02 }, + { 0x03, 0x08 }, + { 0x04, 0x81 }, + { 0x05, 0x21 }, + { 0x08, 0x0c }, + { 0x0a, 0x74 }, + { 0x0b, 0x11 }, + { 0x10, 0x0c }, + { 0x11, 0xe0 }, + /* { 0x12, 0x40 }, -- 3400 needs 40, 2400 needs 48, no way to tell */ + { 0x20, 0x63 }, + { 0x21, 0x68 }, + { 0x22, 0x19 }, + { 0x23, 0x7f }, + { 0x24, 0x68 }, + { 0x26, 0x00 }, + { 0x27, 0x0f }, + { 0x30, 0x57 }, + { 0x31, 0x58 }, + { 0x32, 0x0d }, + { 0x33, 0x72 }, + { 0x34, 0x02 }, + { 0x35, 0x22 }, + { 0x36, 0x02 }, + { 0x37, 0x00 } +}; + +static struct chips_init_reg chips_init_xr[] = { + { 0xce, 0x00 }, /* set default memory clock */ + { 0xcc, 0x43 }, /* memory clock ratio */ + { 0xcd, 0x18 }, + { 0xce, 0xa1 }, + { 0xc8, 0x84 }, + { 0xc9, 0x0a }, + { 0xca, 0x00 }, + { 0xcb, 0x20 }, + { 0xcf, 0x06 }, + { 0xd0, 0x0e }, + { 0x09, 0x01 }, + { 0x0a, 0x02 }, + { 0x0b, 0x01 }, + { 0x20, 0x00 }, + { 0x40, 0x03 }, + { 0x41, 0x01 }, + { 0x42, 0x00 }, + { 0x80, 0x82 }, + { 0x81, 0x12 }, + { 0x82, 0x08 }, + { 0xa0, 0x00 }, + { 0xa8, 0x00 } +}; + +__initfunc(static void chips_hw_init(struct fb_info_chips *p)) +{ + int i; + + for (i = 0; i < N_ELTS(chips_init_xr); ++i) + write_xr(chips_init_xr[i].addr, chips_init_xr[i].data); + out_8(p->io_base + 0x3c2, 0x29); /* set misc output reg */ + for (i = 0; i < N_ELTS(chips_init_sr); ++i) + write_sr(chips_init_sr[i].addr, chips_init_sr[i].data); + for (i = 0; i < N_ELTS(chips_init_gr); ++i) + write_gr(chips_init_gr[i].addr, chips_init_gr[i].data); + for (i = 0; i < N_ELTS(chips_init_ar); ++i) + write_ar(chips_init_ar[i].addr, chips_init_ar[i].data); + for (i = 0; i < N_ELTS(chips_init_cr); ++i) + write_cr(chips_init_cr[i].addr, chips_init_cr[i].data); + for (i = 0; i < N_ELTS(chips_init_fr); ++i) + write_fr(chips_init_fr[i].addr, chips_init_fr[i].data); +} + __initfunc(static void init_chips(struct fb_info_chips *p)) { int i; - memset(&p->fix, 0, sizeof(p->fix)); strcpy(p->fix.id, "C&T 65550"); p->fix.smem_start = (char *) p->chips_base_phys; p->fix.smem_len = 800 * 600; @@ -405,7 +554,6 @@ __initfunc(static void init_chips(struct fb_info_chips *p)) p->fix.visual = FB_VISUAL_PSEUDOCOLOR; p->fix.line_length = 800; - memset(&p->var, 0, sizeof(p->var)); p->var.xres = 800; p->var.yres = 600; p->var.xres_virtual = 800; @@ -419,7 +567,6 @@ __initfunc(static void init_chips(struct fb_info_chips *p)) p->var.upper_margin = p->var.lower_margin = 16; p->var.hsync_len = p->var.vsync_len = 8; - memset(&p->disp, 0, sizeof(p->disp)); p->disp.var = p->var; p->disp.cmap.red = NULL; p->disp.cmap.green = NULL; @@ -443,6 +590,7 @@ __initfunc(static void init_chips(struct fb_info_chips *p)) p->info.switch_con = &chipsfb_switch; p->info.updatevar = &chipsfb_updatevar; p->info.blank = &chipsfb_blank; + p->info.flags = FBINFO_FLAG_DEFAULT; for (i = 0; i < 16; ++i) { int j = color_table[i]; @@ -458,6 +606,8 @@ __initfunc(static void init_chips(struct fb_info_chips *p)) printk("fb%d: Chips 65550 frame buffer\n", GET_FB_IDX(p->info.node)); + chips_hw_init(p); + #ifdef CONFIG_FB_COMPAT_XPMAC if (!console_fb_info) { display_info.height = p->var.yres; @@ -507,6 +657,7 @@ __initfunc(void chips_of_init(struct device_node *dp)) p = kmalloc(sizeof(*p), GFP_ATOMIC); if (p == 0) return; + memset(p, 0, sizeof(*p)); addr = dp->addrs[0].address; p->chips_base_phys = addr; p->frame_buffer = __ioremap(addr+0x800000, 0x100000, _PAGE_NO_CACHE); |