diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
commit | 86464aed71025541805e7b1515541aee89879e33 (patch) | |
tree | e01a457a4912a8553bc65524aa3125d51f29f810 /drivers/video/atyfb.c | |
parent | 88f99939ecc6a95a79614574cb7d95ffccfc3466 (diff) |
Merge with Linux 2.2.1.
Diffstat (limited to 'drivers/video/atyfb.c')
-rw-r--r-- | drivers/video/atyfb.c | 179 |
1 files changed, 137 insertions, 42 deletions
diff --git a/drivers/video/atyfb.c b/drivers/video/atyfb.c index e3f1b1d8d..6a3625d23 100644 --- a/drivers/video/atyfb.c +++ b/drivers/video/atyfb.c @@ -1,4 +1,4 @@ -/* $Id: atyfb.c,v 1.90 1998/11/20 12:27:03 geert Exp $ +/* $Id: atyfb.c,v 1.98 1999/01/14 08:50:53 geert Exp $ * linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64 * * Copyright (C) 1997-1998 Geert Uytterhoeven @@ -222,6 +222,7 @@ struct fb_info_aty { u32 cfb32[16]; #endif } fbcon_cmap; + u8 blitter_may_be_busy; #ifdef __sparc__ u8 open; u8 mmaped; @@ -320,8 +321,7 @@ static char *strtoke(char *s, const char *ct); #endif static void reset_engine(const struct fb_info_aty *info); -static void init_engine(const struct atyfb_par *par, - const struct fb_info_aty *info); +static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info); static void aty_st_514(int offset, u8 val, const struct fb_info_aty *info); static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info); #if defined(__sparc__) || defined(DEBUG) @@ -533,10 +533,11 @@ static inline void wait_for_fifo(u16 entries, const struct fb_info_aty *info) ((u32)(0x8000 >> entries))); } -static inline void wait_for_idle(const struct fb_info_aty *info) +static inline void wait_for_idle(struct fb_info_aty *info) { wait_for_fifo(16, info); while ((aty_ld_le32(GUI_STAT, info) & 1)!= 0); + info->blitter_may_be_busy = 0; } static void reset_engine(const struct fb_info_aty *info) @@ -553,8 +554,7 @@ static void reset_engine(const struct fb_info_aty *info) BUS_FIFO_ERR_ACK, info); } -static void init_engine(const struct atyfb_par *par, - const struct fb_info_aty *info) +static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info) { u32 pitch_value; @@ -872,7 +872,8 @@ aty_set_cursor(struct fb_info_aty *fb, int on) aty_ld_le32(GEN_TEST_CNTL, fb) & ~HWCURSOR_ENABLE, fb); } - wait_for_idle(fb); + if (fb->blitter_may_be_busy) + wait_for_idle(fb); } static void @@ -1457,7 +1458,7 @@ static int aty_pll_gx_to_var(const struct pll_gx *pll, u32 *vclk_per) vco_div_count = pll->m & 0x3f; ref_div_count = pll->n; - *vclk_per = (ref_clk_per*(vco_div_count+65)/ref_div_count)>>(3-df); + *vclk_per = ((ref_clk_per*ref_div_count)<<(3-df))/(vco_div_count+65); return 0; } @@ -1608,6 +1609,7 @@ static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per, return err; if ((((Gx == GT_CHIP_ID) && (Rev & 0x03)) || (Gx == GU_CHIP_ID) || + (Gx == GV_CHIP_ID) || (Gx == GW_CHIP_ID) || (Gx == GZ_CHIP_ID) || (Gx == LG_CHIP_ID) || (Gx == GB_CHIP_ID) || (Gx == GD_CHIP_ID) || (Gx == GI_CHIP_ID) || (Gx == GP_CHIP_ID) || (Gx == GQ_CHIP_ID) || (Gx == VU_CHIP_ID)) && (info->ram_type >= SDRAM)) @@ -1703,6 +1705,8 @@ static void atyfb_set_par(const struct atyfb_par *par, info->current_par = *par; + if (info->blitter_may_be_busy) + wait_for_idle(info); aty_set_crtc(info, &par->crtc); aty_st_8(CLOCK_CNTL, 0, info); aty_st_8(CLOCK_CNTL, CLOCK_STROBE, info); @@ -1717,8 +1721,24 @@ static void atyfb_set_par(const struct atyfb_par *par, break; } aty_set_pll_gx(info, &par->pll.gx); - aty_st_le32(BUS_CNTL, 0x890e20f1, info); - aty_st_le32(DAC_CNTL, 0x47052100, info); + aty_st_le32(BUS_CNTL, 0x590e10ff, info); + aty_st_le32(DAC_CNTL, 0x47012100, info); + + /* Don't forget MEM_CNTL */ + i = aty_ld_le32(MEM_CNTL, info) & 0xf0ffffff; + switch (par->crtc.bpp) { + case 8: + i |= 0x02000000; + break; + case 16: + i |= 0x03000000; + break; + case 32: + i |= 0x06000000; + break; + } + aty_st_le32(MEM_CNTL, i, info); + } else { aty_set_pll_ct(info, &par->pll.ct); i = aty_ld_le32(MEM_CNTL, info) & 0xf30fffff; @@ -2456,9 +2476,13 @@ __initfunc(static int aty_init(struct fb_info_aty *info, const char *name)) (Rev == 0x48))) || ((Gx == VT_CHIP_ID) && ((Rev == 0x01) || (Rev == 0x9a))) || - (Gx == VU_CHIP_ID)) { + Gx == VU_CHIP_ID) { /* VTA4 or VTB */ pll = 200; + } else if (Gx == VV_CHIP_ID) { + /* VT4 */ + pll = 230; + mclk = 83; } else if (Gx == VT_CHIP_ID) { /* other VT */ pll = 135; @@ -2470,15 +2494,19 @@ __initfunc(static int aty_init(struct fb_info_aty *info, const char *name)) (Gx == GU_CHIP_ID)) { /* RAGE II+ */ pll = 200; + } else if (Gx == GV_CHIP_ID || Gx == GW_CHIP_ID || + Gx == GZ_CHIP_ID) { + /* RAGE IIC */ + pll = 230; + mclk = 83; } else if (Gx == GB_CHIP_ID || Gx == GD_CHIP_ID || Gx == GI_CHIP_ID || Gx == GP_CHIP_ID || - Gx == GQ_CHIP_ID || Gx == VV_CHIP_ID || - Gx == GV_CHIP_ID || Gx == GW_CHIP_ID || - Gx == GZ_CHIP_ID || Gx == LD_CHIP_ID || - Gx == LG_CHIP_ID || Gx == LB_CHIP_ID || + Gx == GQ_CHIP_ID || Gx == LB_CHIP_ID || + Gx == LD_CHIP_ID || Gx == LG_CHIP_ID || Gx == LI_CHIP_ID || Gx == LP_CHIP_ID) { - /* RAGE PRO or IIC */ + /* RAGE PRO or LT PRO */ pll = 230; + mclk = 100; } else { /* other RAGE */ pll = 135; @@ -2736,6 +2764,7 @@ __initfunc(void atyfb_init(void)) addr = pdev->base_address[1]; if (!addr) continue; + addr &= PCI_BASE_ADDRESS_MEM_MASK; #ifdef __sparc__ /* @@ -3006,12 +3035,9 @@ __initfunc(void atyfb_init(void)) * Map the video memory (physical address given) to somewhere in the * kernel address space. */ - info->frame_buffer = kernel_map(phys_vmembase[m64_num], - phys_size[m64_num], - KERNELMAP_NOCACHE_SER, NULL); + info->frame_buffer = ioremap(phys_vmembase[m64_num], phys_size[m64_num]); info->frame_buffer_phys = info->frame_buffer; - info->ati_regbase = kernel_map(phys_guiregbase[m64_num], 0x10000, - KERNELMAP_NOCACHE_SER, NULL)+0xFC00ul; + info->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000)+0xFC00ul; info->ati_regbase_phys = info->ati_regbase; if (!aty_init(info, "ISA bus")) { @@ -3399,6 +3425,7 @@ static inline void draw_rect(s16 x, s16 y, u16 width, u16 height, wait_for_fifo(2, info); aty_st_le32(DST_Y_X, (x << 16) | y, info); aty_st_le32(DST_HEIGHT_WIDTH, (width << 16) | height, info); + info->blitter_may_be_busy = 1; } static inline void aty_rectcopy(int srcx, int srcy, int dstx, int dsty, @@ -3561,14 +3588,15 @@ static void fbcon_aty_clear(struct vc_data *conp, struct display *p, int sy, static void fbcon_aty8_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx) { -#ifdef __sparc__ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); +#ifdef __sparc__ if (fb->mmaped && currcon == fb->vtconsole) return; #endif - wait_for_idle((struct fb_info_aty *)p->fb_info); + if (fb->blitter_may_be_busy) + wait_for_idle((struct fb_info_aty *)p->fb_info); fbcon_cfb8_putc(conp, p, c, yy, xx); } @@ -3576,20 +3604,36 @@ static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p, const unsigned short *s, int count, int yy, int xx) { -#ifdef __sparc__ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); +#ifdef __sparc__ if (fb->mmaped && currcon == fb->vtconsole) return; #endif - wait_for_idle((struct fb_info_aty *)p->fb_info); + if (fb->blitter_may_be_busy) + wait_for_idle((struct fb_info_aty *)p->fb_info); fbcon_cfb8_putcs(conp, p, s, count, yy, xx); } +static void fbcon_aty8_clear_margins(struct vc_data *conp, struct display *p, + int bottom_only) +{ + struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); + +#ifdef __sparc__ + if (fb->mmaped && currcon == fb->vtconsole) + return; +#endif + + if (fb->blitter_may_be_busy) + wait_for_idle((struct fb_info_aty *)p->fb_info); + fbcon_cfb8_clear_margins(conp, p, bottom_only); +} + static struct display_switch fbcon_aty8 = { fbcon_cfb8_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty8_putc, - fbcon_aty8_putcs, fbcon_cfb8_revc, NULL, NULL, fbcon_cfb8_clear_margins, + fbcon_aty8_putcs, fbcon_cfb8_revc, NULL, NULL, fbcon_aty8_clear_margins, FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif @@ -3598,14 +3642,15 @@ static struct display_switch fbcon_aty8 = { static void fbcon_aty16_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx) { -#ifdef __sparc__ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); +#ifdef __sparc__ if (fb->mmaped && currcon == fb->vtconsole) return; #endif - wait_for_idle((struct fb_info_aty *)p->fb_info); + if (fb->blitter_may_be_busy) + wait_for_idle((struct fb_info_aty *)p->fb_info); fbcon_cfb16_putc(conp, p, c, yy, xx); } @@ -3613,20 +3658,36 @@ static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p, const unsigned short *s, int count, int yy, int xx) { -#ifdef __sparc__ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); +#ifdef __sparc__ if (fb->mmaped && currcon == fb->vtconsole) return; #endif - wait_for_idle((struct fb_info_aty *)p->fb_info); + if (fb->blitter_may_be_busy) + wait_for_idle((struct fb_info_aty *)p->fb_info); fbcon_cfb16_putcs(conp, p, s, count, yy, xx); } +static void fbcon_aty16_clear_margins(struct vc_data *conp, struct display *p, + int bottom_only) +{ + struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); + +#ifdef __sparc__ + if (fb->mmaped && currcon == fb->vtconsole) + return; +#endif + + if (fb->blitter_may_be_busy) + wait_for_idle((struct fb_info_aty *)p->fb_info); + fbcon_cfb16_clear_margins(conp, p, bottom_only); +} + static struct display_switch fbcon_aty16 = { fbcon_cfb16_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty16_putc, - fbcon_aty16_putcs, fbcon_cfb16_revc, NULL, NULL, fbcon_cfb16_clear_margins, + fbcon_aty16_putcs, fbcon_cfb16_revc, NULL, NULL, fbcon_aty16_clear_margins, FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif @@ -3635,14 +3696,15 @@ static struct display_switch fbcon_aty16 = { static void fbcon_aty24_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx) { -#ifdef __sparc__ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); +#ifdef __sparc__ if (fb->mmaped && currcon == fb->vtconsole) return; #endif - wait_for_idle((struct fb_info_aty *)p->fb_info); + if (fb->blitter_may_be_busy) + wait_for_idle((struct fb_info_aty *)p->fb_info); fbcon_cfb24_putc(conp, p, c, yy, xx); } @@ -3650,20 +3712,36 @@ static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p, const unsigned short *s, int count, int yy, int xx) { -#ifdef __sparc__ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); +#ifdef __sparc__ if (fb->mmaped && currcon == fb->vtconsole) return; #endif - wait_for_idle((struct fb_info_aty *)p->fb_info); + if (fb->blitter_may_be_busy) + wait_for_idle((struct fb_info_aty *)p->fb_info); fbcon_cfb24_putcs(conp, p, s, count, yy, xx); } +static void fbcon_aty24_clear_margins(struct vc_data *conp, struct display *p, + int bottom_only) +{ + struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); + +#ifdef __sparc__ + if (fb->mmaped && currcon == fb->vtconsole) + return; +#endif + + if (fb->blitter_may_be_busy) + wait_for_idle((struct fb_info_aty *)p->fb_info); + fbcon_cfb24_clear_margins(conp, p, bottom_only); +} + static struct display_switch fbcon_aty24 = { - fbcon_cfb24_setup, fbcon_cfb24_bmove, fbcon_cfb24_clear, fbcon_aty24_putc, - fbcon_aty24_putcs, fbcon_cfb24_revc, NULL, NULL, fbcon_cfb24_clear_margins, + fbcon_cfb24_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty24_putc, + fbcon_aty24_putcs, fbcon_cfb24_revc, NULL, NULL, fbcon_aty24_clear_margins, FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif @@ -3672,14 +3750,15 @@ static struct display_switch fbcon_aty24 = { static void fbcon_aty32_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx) { -#ifdef __sparc__ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); +#ifdef __sparc__ if (fb->mmaped && currcon == fb->vtconsole) return; #endif - wait_for_idle((struct fb_info_aty *)p->fb_info); + if (fb->blitter_may_be_busy) + wait_for_idle((struct fb_info_aty *)p->fb_info); fbcon_cfb32_putc(conp, p, c, yy, xx); } @@ -3687,20 +3766,36 @@ static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p, const unsigned short *s, int count, int yy, int xx) { -#ifdef __sparc__ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); +#ifdef __sparc__ if (fb->mmaped && currcon == fb->vtconsole) return; #endif - wait_for_idle((struct fb_info_aty *)p->fb_info); + if (fb->blitter_may_be_busy) + wait_for_idle((struct fb_info_aty *)p->fb_info); fbcon_cfb32_putcs(conp, p, s, count, yy, xx); } +static void fbcon_aty32_clear_margins(struct vc_data *conp, struct display *p, + int bottom_only) +{ + struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); + +#ifdef __sparc__ + if (fb->mmaped && currcon == fb->vtconsole) + return; +#endif + + if (fb->blitter_may_be_busy) + wait_for_idle((struct fb_info_aty *)p->fb_info); + fbcon_cfb32_clear_margins(conp, p, bottom_only); +} + static struct display_switch fbcon_aty32 = { fbcon_cfb32_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty32_putc, - fbcon_aty32_putcs, fbcon_cfb32_revc, NULL, NULL, fbcon_cfb32_clear_margins, + fbcon_aty32_putcs, fbcon_cfb32_revc, NULL, NULL, fbcon_aty32_clear_margins, FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) }; #endif |