Lines Matching +full:switch +full:- +full:freq

1 // SPDX-License-Identifier: GPL-2.0-only
3 * i740fb - framebuffer driver for Intel740
6 * Based on old i740fb driver (c) 2001-2002 Andrey Ulanov <drey@rt.mipt.ru>
8 * VGA 16-color framebuffer driver (c) 1999 Ben Pfaff <pfaffben@debian.org>
10 * i740 driver from XFree86 (c) 1998-1999 Precision Insight, Inc., Cedar Park,
28 #include <linux/i2c-algo-bit.h>
98 vga_mm_w(par->regs, port, val); in i740outb()
102 return vga_mm_r(par->regs, port); in i740inb()
106 vga_mm_w_fast(par->regs, port, reg, val); in i740outreg()
110 vga_mm_w(par->regs, port, reg); in i740inreg()
111 return vga_mm_r(par->regs, port+1); in i740inreg()
116 vga_mm_w_fast(par->regs, port, reg, (val & mask) in i740outreg_mask()
161 struct i740fb_par *par = info->par; in i740fb_setup_ddc_bus()
163 strscpy(par->ddc_adapter.name, info->fix.id, in i740fb_setup_ddc_bus()
164 sizeof(par->ddc_adapter.name)); in i740fb_setup_ddc_bus()
165 par->ddc_adapter.owner = THIS_MODULE; in i740fb_setup_ddc_bus()
166 par->ddc_adapter.algo_data = &par->ddc_algo; in i740fb_setup_ddc_bus()
167 par->ddc_adapter.dev.parent = info->device; in i740fb_setup_ddc_bus()
168 par->ddc_algo.setsda = i740fb_ddc_setsda; in i740fb_setup_ddc_bus()
169 par->ddc_algo.setscl = i740fb_ddc_setscl; in i740fb_setup_ddc_bus()
170 par->ddc_algo.getsda = i740fb_ddc_getsda; in i740fb_setup_ddc_bus()
171 par->ddc_algo.getscl = i740fb_ddc_getscl; in i740fb_setup_ddc_bus()
172 par->ddc_algo.udelay = 10; in i740fb_setup_ddc_bus()
173 par->ddc_algo.timeout = 20; in i740fb_setup_ddc_bus()
174 par->ddc_algo.data = par; in i740fb_setup_ddc_bus()
176 i2c_set_adapdata(&par->ddc_adapter, par); in i740fb_setup_ddc_bus()
178 return i2c_bit_add_bus(&par->ddc_adapter); in i740fb_setup_ddc_bus()
183 struct i740fb_par *par = info->par; in i740fb_open()
185 mutex_lock(&(par->open_lock)); in i740fb_open()
186 par->ref_count++; in i740fb_open()
187 mutex_unlock(&(par->open_lock)); in i740fb_open()
194 struct i740fb_par *par = info->par; in i740fb_release()
196 mutex_lock(&(par->open_lock)); in i740fb_release()
197 if (par->ref_count == 0) { in i740fb_release()
199 mutex_unlock(&(par->open_lock)); in i740fb_release()
200 return -EINVAL; in i740fb_release()
203 par->ref_count--; in i740fb_release()
204 mutex_unlock(&(par->open_lock)); in i740fb_release()
209 static u32 i740_calc_fifo(struct i740fb_par *par, u32 freq, int bpp) in i740_calc_fifo() argument
221 switch (bpp) { in i740_calc_fifo()
223 if (freq > 200) in i740_calc_fifo()
225 else if (freq > 175) in i740_calc_fifo()
227 else if (freq > 135) in i740_calc_fifo()
234 if (par->has_sgram) { in i740_calc_fifo()
235 if (freq > 140) in i740_calc_fifo()
237 else if (freq > 120) in i740_calc_fifo()
239 else if (freq > 100) in i740_calc_fifo()
241 else if (freq > 90) in i740_calc_fifo()
243 else if (freq > 50) in i740_calc_fifo()
245 else if (freq > 32) in i740_calc_fifo()
250 if (freq > 160) in i740_calc_fifo()
252 else if (freq > 140) in i740_calc_fifo()
254 else if (freq > 130) in i740_calc_fifo()
256 else if (freq > 120) in i740_calc_fifo()
258 else if (freq > 100) in i740_calc_fifo()
260 else if (freq > 90) in i740_calc_fifo()
262 else if (freq > 50) in i740_calc_fifo()
264 else if (freq > 32) in i740_calc_fifo()
271 if (par->has_sgram) { in i740_calc_fifo()
272 if (freq > 130) in i740_calc_fifo()
274 else if (freq > 120) in i740_calc_fifo()
276 else if (freq > 100) in i740_calc_fifo()
278 else if (freq > 80) in i740_calc_fifo()
280 else if (freq > 64) in i740_calc_fifo()
282 else if (freq > 49) in i740_calc_fifo()
284 else if (freq > 32) in i740_calc_fifo()
289 if (freq > 120) in i740_calc_fifo()
291 else if (freq > 100) in i740_calc_fifo()
293 else if (freq > 80) in i740_calc_fifo()
295 else if (freq > 64) in i740_calc_fifo()
297 else if (freq > 49) in i740_calc_fifo()
299 else if (freq > 32) in i740_calc_fifo()
306 if (par->has_sgram) { in i740_calc_fifo()
307 if (freq > 80) in i740_calc_fifo()
309 else if (freq > 60) in i740_calc_fifo()
311 else if (freq > 49) in i740_calc_fifo()
313 else if (freq > 32) in i740_calc_fifo()
318 if (freq > 80) in i740_calc_fifo()
320 else if (freq > 60) in i740_calc_fifo()
322 else if (freq > 49) in i740_calc_fifo()
324 else if (freq > 32) in i740_calc_fifo()
344 static void i740_calc_vclk(u32 freq, struct i740fb_par *par) in i740_calc_vclk() argument
346 const u32 err_max = freq / (200 * I740_RFREQ / I740_FFIX); in i740_calc_vclk()
347 const u32 err_target = freq / (1000 * I740_RFREQ / I740_FFIX); in i740_calc_vclk()
353 p_best = min(15, ilog2(I740_MAX_VCO_FREQ / (freq / I740_RFREQ_FIX))); in i740_calc_vclk()
354 f_vco = (freq * (1 << p_best)) / I740_RFREQ_FIX; in i740_calc_vclk()
355 freq = freq / I740_RFREQ_FIX; in i740_calc_vclk()
369 f_err = (freq - f_out); in i740_calc_vclk()
385 par->video_clk2_m = (m_best - 2) & 0xFF; in i740_calc_vclk()
386 par->video_clk2_n = (n_best - 2) & 0xFF; in i740_calc_vclk()
387 par->video_clk2_mn_msbs = ((((n_best - 2) >> 4) & VCO_N_MSBS) in i740_calc_vclk()
388 | (((m_best - 2) >> 8) & VCO_M_MSBS)); in i740_calc_vclk()
389 par->video_clk2_div_sel = ((p_best << 4) | REF_DIV_1); in i740_calc_vclk()
397 * If a value doesn't fit, round it up, if it's too big, return -EINVAL. in i740fb_decode_var()
403 u32 bpp, base, dacspeed24, mem, freq; in i740fb_decode_var() local
407 dev_dbg(info->device, "decode_var: xres: %i, yres: %i, xres_v: %i, xres_v: %i\n", in i740fb_decode_var()
408 var->xres, var->yres, var->xres_virtual, var->xres_virtual); in i740fb_decode_var()
409 dev_dbg(info->device, " xoff: %i, yoff: %i, bpp: %i, graysc: %i\n", in i740fb_decode_var()
410 var->xoffset, var->yoffset, var->bits_per_pixel, in i740fb_decode_var()
411 var->grayscale); in i740fb_decode_var()
412 dev_dbg(info->device, " activate: %i, nonstd: %i, vmode: %i\n", in i740fb_decode_var()
413 var->activate, var->nonstd, var->vmode); in i740fb_decode_var()
414 dev_dbg(info->device, " pixclock: %i, hsynclen:%i, vsynclen:%i\n", in i740fb_decode_var()
415 var->pixclock, var->hsync_len, var->vsync_len); in i740fb_decode_var()
416 dev_dbg(info->device, " left: %i, right: %i, up:%i, lower:%i\n", in i740fb_decode_var()
417 var->left_margin, var->right_margin, var->upper_margin, in i740fb_decode_var()
418 var->lower_margin); in i740fb_decode_var()
421 bpp = var->bits_per_pixel; in i740fb_decode_var()
422 switch (bpp) { in i740fb_decode_var()
425 if ((1000000 / var->pixclock) > DACSPEED8) { in i740fb_decode_var()
426 dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 8bpp)\n", in i740fb_decode_var()
427 1000000 / var->pixclock, DACSPEED8); in i740fb_decode_var()
428 return -EINVAL; in i740fb_decode_var()
435 if ((1000000 / var->pixclock) > DACSPEED16) { in i740fb_decode_var()
436 dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 15/16bpp)\n", in i740fb_decode_var()
437 1000000 / var->pixclock, DACSPEED16); in i740fb_decode_var()
438 return -EINVAL; in i740fb_decode_var()
443 dacspeed24 = par->has_sgram ? DACSPEED24_SG : DACSPEED24_SD; in i740fb_decode_var()
444 if ((1000000 / var->pixclock) > dacspeed24) { in i740fb_decode_var()
445 dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 24bpp)\n", in i740fb_decode_var()
446 1000000 / var->pixclock, dacspeed24); in i740fb_decode_var()
447 return -EINVAL; in i740fb_decode_var()
452 if ((1000000 / var->pixclock) > DACSPEED32) { in i740fb_decode_var()
453 dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 32bpp)\n", in i740fb_decode_var()
454 1000000 / var->pixclock, DACSPEED32); in i740fb_decode_var()
455 return -EINVAL; in i740fb_decode_var()
459 return -EINVAL; in i740fb_decode_var()
462 xres = ALIGN(var->xres, 8); in i740fb_decode_var()
463 vxres = ALIGN(var->xres_virtual, 16); in i740fb_decode_var()
467 xoffset = ALIGN(var->xoffset, 8); in i740fb_decode_var()
469 xoffset = vxres - xres; in i740fb_decode_var()
471 left = ALIGN(var->left_margin, 8); in i740fb_decode_var()
472 right = ALIGN(var->right_margin, 8); in i740fb_decode_var()
473 hslen = ALIGN(var->hsync_len, 8); in i740fb_decode_var()
475 yres = var->yres; in i740fb_decode_var()
476 vyres = var->yres_virtual; in i740fb_decode_var()
480 yoffset = var->yoffset; in i740fb_decode_var()
482 yoffset = vyres - yres; in i740fb_decode_var()
484 lower = var->lower_margin; in i740fb_decode_var()
485 vslen = var->vsync_len; in i740fb_decode_var()
486 upper = var->upper_margin; in i740fb_decode_var()
489 if (mem > info->screen_size) { in i740fb_decode_var()
490 dev_err(info->device, "not enough video memory (%d KB requested, %ld KB available)\n", in i740fb_decode_var()
491 mem >> 10, info->screen_size >> 10); in i740fb_decode_var()
492 return -ENOMEM; in i740fb_decode_var()
496 yoffset = vyres - yres; in i740fb_decode_var()
501 par->crtc[VGA_CRTC_H_TOTAL] = (xtotal >> 3) - 5; in i740fb_decode_var()
502 par->crtc[VGA_CRTC_H_DISP] = (xres >> 3) - 1; in i740fb_decode_var()
503 par->crtc[VGA_CRTC_H_BLANK_START] = ((xres + right) >> 3) - 1; in i740fb_decode_var()
504 par->crtc[VGA_CRTC_H_SYNC_START] = (xres + right) >> 3; in i740fb_decode_var()
505 par->crtc[VGA_CRTC_H_SYNC_END] = (((xres + right + hslen) >> 3) & 0x1F) in i740fb_decode_var()
507 par->crtc[VGA_CRTC_H_BLANK_END] = ((xres + right + hslen) >> 3 & 0x1F) in i740fb_decode_var()
510 par->crtc[VGA_CRTC_V_TOTAL] = ytotal - 2; in i740fb_decode_var()
518 par->crtc[VGA_CRTC_PRESET_ROW] = 0; in i740fb_decode_var()
519 par->crtc[VGA_CRTC_MAX_SCAN] = 0x40; /* 1 scanline, no linecmp */ in i740fb_decode_var()
520 if (var->vmode & FB_VMODE_DOUBLE) in i740fb_decode_var()
521 par->crtc[VGA_CRTC_MAX_SCAN] |= 0x80; in i740fb_decode_var()
522 par->crtc[VGA_CRTC_CURSOR_START] = 0x00; in i740fb_decode_var()
523 par->crtc[VGA_CRTC_CURSOR_END] = 0x00; in i740fb_decode_var()
524 par->crtc[VGA_CRTC_CURSOR_HI] = 0x00; in i740fb_decode_var()
525 par->crtc[VGA_CRTC_CURSOR_LO] = 0x00; in i740fb_decode_var()
526 par->crtc[VGA_CRTC_V_DISP_END] = yres-1; in i740fb_decode_var()
527 if ((yres-1) & 0x100) in i740fb_decode_var()
529 if ((yres-1) & 0x200) in i740fb_decode_var()
532 par->crtc[VGA_CRTC_V_BLANK_START] = yres + lower - 1; in i740fb_decode_var()
533 par->crtc[VGA_CRTC_V_SYNC_START] = yres + lower - 1; in i740fb_decode_var()
534 if ((yres + lower - 1) & 0x100) in i740fb_decode_var()
536 if ((yres + lower - 1) & 0x200) { in i740fb_decode_var()
537 par->crtc[VGA_CRTC_MAX_SCAN] |= 0x20; in i740fb_decode_var()
542 par->crtc[VGA_CRTC_V_SYNC_END] = in i740fb_decode_var()
543 ((yres + lower - 1 + vslen) & 0x0F) & ~0x10; in i740fb_decode_var()
545 par->crtc[VGA_CRTC_V_BLANK_END] = (yres + lower - 1 + vslen) & 0xFF; in i740fb_decode_var()
547 par->crtc[VGA_CRTC_UNDERLINE] = 0x00; in i740fb_decode_var()
548 par->crtc[VGA_CRTC_MODE] = 0xC3 ; in i740fb_decode_var()
549 par->crtc[VGA_CRTC_LINE_COMPARE] = 0xFF; in i740fb_decode_var()
550 par->crtc[VGA_CRTC_OVERFLOW] = r7; in i740fb_decode_var()
552 par->vss = 0x00; /* 3DA */ in i740fb_decode_var()
555 par->atc[i] = i; in i740fb_decode_var()
556 par->atc[VGA_ATC_MODE] = 0x81; in i740fb_decode_var()
557 par->atc[VGA_ATC_OVERSCAN] = 0x00; /* 0 for EGA, 0xFF for VGA */ in i740fb_decode_var()
558 par->atc[VGA_ATC_PLANE_ENABLE] = 0x0F; in i740fb_decode_var()
559 par->atc[VGA_ATC_COLOR_PAGE] = 0x00; in i740fb_decode_var()
561 par->misc = 0xC3; in i740fb_decode_var()
562 if (var->sync & FB_SYNC_HOR_HIGH_ACT) in i740fb_decode_var()
563 par->misc &= ~0x40; in i740fb_decode_var()
564 if (var->sync & FB_SYNC_VERT_HIGH_ACT) in i740fb_decode_var()
565 par->misc &= ~0x80; in i740fb_decode_var()
567 par->seq[VGA_SEQ_CLOCK_MODE] = 0x01; in i740fb_decode_var()
568 par->seq[VGA_SEQ_PLANE_WRITE] = 0x0F; in i740fb_decode_var()
569 par->seq[VGA_SEQ_CHARACTER_MAP] = 0x00; in i740fb_decode_var()
570 par->seq[VGA_SEQ_MEMORY_MODE] = 0x06; in i740fb_decode_var()
572 par->gdc[VGA_GFX_SR_VALUE] = 0x00; in i740fb_decode_var()
573 par->gdc[VGA_GFX_SR_ENABLE] = 0x00; in i740fb_decode_var()
574 par->gdc[VGA_GFX_COMPARE_VALUE] = 0x00; in i740fb_decode_var()
575 par->gdc[VGA_GFX_DATA_ROTATE] = 0x00; in i740fb_decode_var()
576 par->gdc[VGA_GFX_PLANE_READ] = 0; in i740fb_decode_var()
577 par->gdc[VGA_GFX_MODE] = 0x02; in i740fb_decode_var()
578 par->gdc[VGA_GFX_MISC] = 0x05; in i740fb_decode_var()
579 par->gdc[VGA_GFX_COMPARE_MASK] = 0x0F; in i740fb_decode_var()
580 par->gdc[VGA_GFX_BIT_MASK] = 0xFF; in i740fb_decode_var()
583 switch (bpp) { in i740fb_decode_var()
585 par->crtc[VGA_CRTC_OFFSET] = vxres >> 3; in i740fb_decode_var()
586 par->ext_offset = vxres >> 11; in i740fb_decode_var()
587 par->pixelpipe_cfg1 = DISPLAY_8BPP_MODE; in i740fb_decode_var()
588 par->bitblt_cntl = COLEXP_8BPP; in i740fb_decode_var()
592 par->pixelpipe_cfg1 = (var->green.length == 6) ? in i740fb_decode_var()
594 par->crtc[VGA_CRTC_OFFSET] = vxres >> 2; in i740fb_decode_var()
595 par->ext_offset = vxres >> 10; in i740fb_decode_var()
596 par->bitblt_cntl = COLEXP_16BPP; in i740fb_decode_var()
600 par->crtc[VGA_CRTC_OFFSET] = (vxres * 3) >> 3; in i740fb_decode_var()
601 par->ext_offset = (vxres * 3) >> 11; in i740fb_decode_var()
602 par->pixelpipe_cfg1 = DISPLAY_24BPP_MODE; in i740fb_decode_var()
603 par->bitblt_cntl = COLEXP_24BPP; in i740fb_decode_var()
608 par->crtc[VGA_CRTC_OFFSET] = vxres >> 1; in i740fb_decode_var()
609 par->ext_offset = vxres >> 9; in i740fb_decode_var()
610 par->pixelpipe_cfg1 = DISPLAY_32BPP_MODE; in i740fb_decode_var()
611 par->bitblt_cntl = COLEXP_RESERVED; /* Unimplemented on i740 */ in i740fb_decode_var()
616 par->crtc[VGA_CRTC_START_LO] = base & 0x000000FF; in i740fb_decode_var()
617 par->crtc[VGA_CRTC_START_HI] = (base & 0x0000FF00) >> 8; in i740fb_decode_var()
618 par->ext_start_addr = in i740fb_decode_var()
620 par->ext_start_addr_hi = (base & 0x3FC00000) >> 22; in i740fb_decode_var()
622 par->pixelpipe_cfg0 = DAC_8_BIT; in i740fb_decode_var()
624 par->pixelpipe_cfg2 = DISPLAY_GAMMA_ENABLE | OVERLAY_GAMMA_ENABLE; in i740fb_decode_var()
625 par->io_cntl = EXTENDED_CRTC_CNTL; in i740fb_decode_var()
626 par->address_mapping = LINEAR_MODE_ENABLE | PAGE_MAPPING_ENABLE; in i740fb_decode_var()
627 par->display_cntl = HIRES_MODE; in i740fb_decode_var()
629 /* Set the MCLK freq */ in i740fb_decode_var()
630 par->pll_cntl = PLL_MEMCLK_100000KHZ; /* 100 MHz -- use as default */ in i740fb_decode_var()
633 par->ext_vert_total = (ytotal - 2) >> 8; in i740fb_decode_var()
634 par->ext_vert_disp_end = (yres - 1) >> 8; in i740fb_decode_var()
635 par->ext_vert_sync_start = (yres + lower) >> 8; in i740fb_decode_var()
636 par->ext_vert_blank_start = (yres + lower) >> 8; in i740fb_decode_var()
637 par->ext_horiz_total = ((xtotal >> 3) - 5) >> 8; in i740fb_decode_var()
638 par->ext_horiz_blank = (((xres + right) >> 3) & 0x40) >> 6; in i740fb_decode_var()
640 par->interlace_cntl = INTERLACE_DISABLE; in i740fb_decode_var()
643 par->atc[VGA_ATC_OVERSCAN] = 0; in i740fb_decode_var()
646 freq = (((u32)1e9) / var->pixclock) * (u32)(1e3); in i740fb_decode_var()
647 if (freq < I740_RFREQ_FIX) { in i740fb_decode_var()
649 freq = I740_RFREQ_FIX; in i740fb_decode_var()
651 i740_calc_vclk(freq, par); in i740fb_decode_var()
654 par->misc |= 0x0C; in i740fb_decode_var()
657 par->lmi_fifo_watermark = in i740fb_decode_var()
658 i740_calc_fifo(par, 1000000 / var->pixclock, bpp); in i740fb_decode_var()
665 if (!var->pixclock) in i740fb_check_var()
666 return -EINVAL; in i740fb_check_var()
668 switch (var->bits_per_pixel) { in i740fb_check_var()
670 var->red.offset = var->green.offset = var->blue.offset = 0; in i740fb_check_var()
671 var->red.length = var->green.length = var->blue.length = 8; in i740fb_check_var()
674 switch (var->green.length) { in i740fb_check_var()
677 var->red.offset = 10; in i740fb_check_var()
678 var->green.offset = 5; in i740fb_check_var()
679 var->blue.offset = 0; in i740fb_check_var()
680 var->red.length = 5; in i740fb_check_var()
681 var->green.length = 5; in i740fb_check_var()
682 var->blue.length = 5; in i740fb_check_var()
685 var->red.offset = 11; in i740fb_check_var()
686 var->green.offset = 5; in i740fb_check_var()
687 var->blue.offset = 0; in i740fb_check_var()
688 var->red.length = var->blue.length = 5; in i740fb_check_var()
693 var->red.offset = 16; in i740fb_check_var()
694 var->green.offset = 8; in i740fb_check_var()
695 var->blue.offset = 0; in i740fb_check_var()
696 var->red.length = var->green.length = var->blue.length = 8; in i740fb_check_var()
699 var->transp.offset = 24; in i740fb_check_var()
700 var->red.offset = 16; in i740fb_check_var()
701 var->green.offset = 8; in i740fb_check_var()
702 var->blue.offset = 0; in i740fb_check_var()
703 var->transp.length = 8; in i740fb_check_var()
704 var->red.length = var->green.length = var->blue.length = 8; in i740fb_check_var()
707 return -EINVAL; in i740fb_check_var()
710 if (var->xres > var->xres_virtual) in i740fb_check_var()
711 var->xres_virtual = var->xres; in i740fb_check_var()
713 if (var->yres > var->yres_virtual) in i740fb_check_var()
714 var->yres_virtual = var->yres; in i740fb_check_var()
716 if (info->monspecs.hfmax && info->monspecs.vfmax && in i740fb_check_var()
717 info->monspecs.dclkmax && fb_validate_mode(var, info) < 0) in i740fb_check_var()
718 return -EINVAL; in i740fb_check_var()
743 struct i740fb_par *par = info->par; in i740fb_set_par()
747 i = i740fb_decode_var(&info->var, par, info); in i740fb_set_par()
751 memset_io(info->screen_base, 0, info->screen_size); in i740fb_set_par()
759 i740outreg(par, XRX, VCLK2_VCO_M, par->video_clk2_m); in i740fb_set_par()
760 i740outreg(par, XRX, VCLK2_VCO_N, par->video_clk2_n); in i740fb_set_par()
761 i740outreg(par, XRX, VCLK2_VCO_MN_MSBS, par->video_clk2_mn_msbs); in i740fb_set_par()
762 i740outreg(par, XRX, VCLK2_VCO_DIV_SEL, par->video_clk2_div_sel); in i740fb_set_par()
765 par->pixelpipe_cfg0 & DAC_8_BIT, 0x80); in i740fb_set_par()
771 i740outb(par, VGA_MIS_W, par->misc | 0x01); in i740fb_set_par()
777 par->seq[VGA_SEQ_CLOCK_MODE] | 0x20); in i740fb_set_par()
779 i740outreg(par, VGA_SEQ_I, i, par->seq[i]); in i740fb_set_par()
784 /* deprotect CRT registers 0-7 */ in i740fb_set_par()
786 par->crtc[VGA_CRTC_V_SYNC_END]); in i740fb_set_par()
790 i740outreg(par, VGA_CRT_IC, i, par->crtc[i]); in i740fb_set_par()
794 i740outreg(par, VGA_GFX_I, i, par->gdc[i]); in i740fb_set_par()
798 i740inb(par, VGA_IS1_RC); /* reset flip-flop */ in i740fb_set_par()
800 i740outb(par, VGA_ATT_IW, par->atc[i]); in i740fb_set_par()
806 i740outreg(par, VGA_CRT_IC, EXT_VERT_TOTAL, par->ext_vert_total); in i740fb_set_par()
807 i740outreg(par, VGA_CRT_IC, EXT_VERT_DISPLAY, par->ext_vert_disp_end); in i740fb_set_par()
809 par->ext_vert_sync_start); in i740fb_set_par()
811 par->ext_vert_blank_start); in i740fb_set_par()
812 i740outreg(par, VGA_CRT_IC, EXT_HORIZ_TOTAL, par->ext_horiz_total); in i740fb_set_par()
813 i740outreg(par, VGA_CRT_IC, EXT_HORIZ_BLANK, par->ext_horiz_blank); in i740fb_set_par()
814 i740outreg(par, VGA_CRT_IC, EXT_OFFSET, par->ext_offset); in i740fb_set_par()
815 i740outreg(par, VGA_CRT_IC, EXT_START_ADDR_HI, par->ext_start_addr_hi); in i740fb_set_par()
816 i740outreg(par, VGA_CRT_IC, EXT_START_ADDR, par->ext_start_addr); in i740fb_set_par()
819 par->interlace_cntl, INTERLACE_ENABLE); in i740fb_set_par()
820 i740outreg_mask(par, XRX, ADDRESS_MAPPING, par->address_mapping, 0x1F); in i740fb_set_par()
821 i740outreg_mask(par, XRX, BITBLT_CNTL, par->bitblt_cntl, COLEXP_MODE); in i740fb_set_par()
823 par->display_cntl, VGA_WRAP_MODE | GUI_MODE); in i740fb_set_par()
824 i740outreg_mask(par, XRX, PIXPIPE_CONFIG_0, par->pixelpipe_cfg0, 0x9B); in i740fb_set_par()
825 i740outreg_mask(par, XRX, PIXPIPE_CONFIG_2, par->pixelpipe_cfg2, 0x0C); in i740fb_set_par()
827 i740outreg(par, XRX, PLL_CNTL, par->pll_cntl); in i740fb_set_par()
830 par->pixelpipe_cfg1, DISPLAY_COLOR_MODE); in i740fb_set_par()
832 itemp = readl(par->regs + FWATER_BLC); in i740fb_set_par()
834 itemp |= par->lmi_fifo_watermark; in i740fb_set_par()
835 writel(itemp, par->regs + FWATER_BLC); in i740fb_set_par()
841 par->io_cntl, EXTENDED_ATTR_CNTL | EXTENDED_CRTC_CNTL); in i740fb_set_par()
843 if (par->pixelpipe_cfg1 != DISPLAY_8BPP_MODE) { in i740fb_set_par()
847 itemp = (par->pixelpipe_cfg0 & DAC_8_BIT) ? i : i >> 2; in i740fb_set_par()
858 info->fix.line_length = in i740fb_set_par()
859 info->var.xres_virtual * info->var.bits_per_pixel / 8; in i740fb_set_par()
860 if (info->var.bits_per_pixel == 8) in i740fb_set_par()
861 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; in i740fb_set_par()
863 info->fix.visual = FB_VISUAL_TRUECOLOR; in i740fb_set_par()
874 dev_dbg(info->device, "setcolreg: regno: %i, red=%d, green=%d, blue=%d, transp=%d, bpp=%d\n", in i740fb_setcolreg()
875 regno, red, green, blue, transp, info->var.bits_per_pixel); in i740fb_setcolreg()
877 switch (info->fix.visual) { in i740fb_setcolreg()
880 return -EINVAL; in i740fb_setcolreg()
881 i740outb(info->par, VGA_PEL_IW, regno); in i740fb_setcolreg()
882 i740outb(info->par, VGA_PEL_D, red >> 8); in i740fb_setcolreg()
883 i740outb(info->par, VGA_PEL_D, green >> 8); in i740fb_setcolreg()
884 i740outb(info->par, VGA_PEL_D, blue >> 8); in i740fb_setcolreg()
888 return -EINVAL; in i740fb_setcolreg()
889 r = (red >> (16 - info->var.red.length)) in i740fb_setcolreg()
890 << info->var.red.offset; in i740fb_setcolreg()
891 b = (blue >> (16 - info->var.blue.length)) in i740fb_setcolreg()
892 << info->var.blue.offset; in i740fb_setcolreg()
893 g = (green >> (16 - info->var.green.length)) in i740fb_setcolreg()
894 << info->var.green.offset; in i740fb_setcolreg()
895 ((u32 *) info->pseudo_palette)[regno] = r | g | b; in i740fb_setcolreg()
898 return -EINVAL; in i740fb_setcolreg()
907 struct i740fb_par *par = info->par; in i740fb_pan_display()
908 u32 base = (var->yoffset * info->var.xres_virtual in i740fb_pan_display()
909 + (var->xoffset & ~7)) >> 2; in i740fb_pan_display()
911 dev_dbg(info->device, "pan_display: xoffset: %i yoffset: %i base: %i\n", in i740fb_pan_display()
912 var->xoffset, var->yoffset, base); in i740fb_pan_display()
914 switch (info->var.bits_per_pixel) { in i740fb_pan_display()
934 par->crtc[VGA_CRTC_START_LO] = base & 0x000000FF; in i740fb_pan_display()
935 par->crtc[VGA_CRTC_START_HI] = (base & 0x0000FF00) >> 8; in i740fb_pan_display()
936 par->ext_start_addr_hi = (base & 0x3FC00000) >> 22; in i740fb_pan_display()
937 par->ext_start_addr = in i740fb_pan_display()
953 struct i740fb_par *par = info->par; in i740fb_blank()
958 switch (blank_mode) { in i740fb_blank()
977 return -EINVAL; in i740fb_blank()
1004 /* ------------------------------------------------------------------------- */
1018 info = framebuffer_alloc(sizeof(struct i740fb_par), &(dev->dev)); in i740fb_probe()
1020 return -ENOMEM; in i740fb_probe()
1022 par = info->par; in i740fb_probe()
1023 mutex_init(&par->open_lock); in i740fb_probe()
1025 info->var.activate = FB_ACTIVATE_NOW; in i740fb_probe()
1026 info->var.bits_per_pixel = 8; in i740fb_probe()
1027 info->fbops = &i740fb_ops; in i740fb_probe()
1028 info->pseudo_palette = par->pseudo_palette; in i740fb_probe()
1032 dev_err(info->device, "cannot enable PCI device\n"); in i740fb_probe()
1036 ret = pci_request_regions(dev, info->fix.id); in i740fb_probe()
1038 dev_err(info->device, "error requesting regions\n"); in i740fb_probe()
1042 info->screen_base = pci_ioremap_wc_bar(dev, 0); in i740fb_probe()
1043 if (!info->screen_base) { in i740fb_probe()
1044 dev_err(info->device, "error remapping base\n"); in i740fb_probe()
1045 ret = -ENOMEM; in i740fb_probe()
1049 par->regs = pci_ioremap_bar(dev, 1); in i740fb_probe()
1050 if (!par->regs) { in i740fb_probe()
1051 dev_err(info->device, "error remapping MMIO\n"); in i740fb_probe()
1052 ret = -ENOMEM; in i740fb_probe()
1062 info->screen_size = i740inb(par, XRX + 1) * 1024 * 1024; in i740fb_probe()
1065 par->has_sgram = !((tmp & DRAM_RAS_TIMING) || in i740fb_probe()
1069 pci_name(dev), info->screen_size >> 10, in i740fb_probe()
1070 par->has_sgram ? "SGRAM" : "SDRAM"); in i740fb_probe()
1072 info->fix = i740fb_fix; in i740fb_probe()
1073 info->fix.mmio_start = pci_resource_start(dev, 1); in i740fb_probe()
1074 info->fix.mmio_len = pci_resource_len(dev, 1); in i740fb_probe()
1075 info->fix.smem_start = pci_resource_start(dev, 0); in i740fb_probe()
1076 info->fix.smem_len = info->screen_size; in i740fb_probe()
1077 info->flags = FBINFO_HWACCEL_YPAN; in i740fb_probe()
1080 par->ddc_registered = true; in i740fb_probe()
1081 edid = fb_ddc_read(&par->ddc_adapter); in i740fb_probe()
1083 fb_edid_to_monspecs(edid, &info->monspecs); in i740fb_probe()
1085 if (!info->monspecs.modedb) in i740fb_probe()
1086 dev_err(info->device, in i740fb_probe()
1092 info->monspecs.modedb, in i740fb_probe()
1093 info->monspecs.modedb_len, in i740fb_probe()
1094 &info->modelist); in i740fb_probe()
1095 m = fb_find_best_display(&info->monspecs, in i740fb_probe()
1096 &info->modelist); in i740fb_probe()
1098 fb_videomode_to_var(&info->var, m); in i740fb_probe()
1099 /* fill all other info->var's fields */ in i740fb_probe()
1100 if (!i740fb_check_var(&info->var, info)) in i740fb_probe()
1108 mode_option = "640x480-8@60"; in i740fb_probe()
1111 ret = fb_find_mode(&info->var, info, mode_option, in i740fb_probe()
1112 info->monspecs.modedb, in i740fb_probe()
1113 info->monspecs.modedb_len, in i740fb_probe()
1114 NULL, info->var.bits_per_pixel); in i740fb_probe()
1116 dev_err(info->device, "mode %s not found\n", in i740fb_probe()
1118 ret = -EINVAL; in i740fb_probe()
1122 fb_destroy_modedb(info->monspecs.modedb); in i740fb_probe()
1123 info->monspecs.modedb = NULL; in i740fb_probe()
1126 info->var.yres_virtual = info->fix.smem_len * 8 / in i740fb_probe()
1127 (info->var.bits_per_pixel * info->var.xres_virtual); in i740fb_probe()
1129 if (ret == -EINVAL) in i740fb_probe()
1132 ret = fb_alloc_cmap(&info->cmap, 256, 0); in i740fb_probe()
1134 dev_err(info->device, "cannot allocate colormap\n"); in i740fb_probe()
1140 dev_err(info->device, "error registering framebuffer\n"); in i740fb_probe()
1144 fb_info(info, "%s frame buffer device\n", info->fix.id); in i740fb_probe()
1147 par->wc_cookie = arch_phys_wc_add(info->fix.smem_start, in i740fb_probe()
1148 info->fix.smem_len); in i740fb_probe()
1152 fb_dealloc_cmap(&info->cmap); in i740fb_probe()
1155 if (par->ddc_registered) in i740fb_probe()
1156 i2c_del_adapter(&par->ddc_adapter); in i740fb_probe()
1157 pci_iounmap(dev, par->regs); in i740fb_probe()
1159 pci_iounmap(dev, info->screen_base); in i740fb_probe()
1174 struct i740fb_par *par = info->par; in i740fb_remove()
1175 arch_phys_wc_del(par->wc_cookie); in i740fb_remove()
1177 fb_dealloc_cmap(&info->cmap); in i740fb_remove()
1178 if (par->ddc_registered) in i740fb_remove()
1179 i2c_del_adapter(&par->ddc_adapter); in i740fb_remove()
1180 pci_iounmap(dev, par->regs); in i740fb_remove()
1181 pci_iounmap(dev, info->screen_base); in i740fb_remove()
1191 struct i740fb_par *par = info->par; in i740fb_suspend()
1194 mutex_lock(&(par->open_lock)); in i740fb_suspend()
1197 if (par->ref_count == 0) { in i740fb_suspend()
1198 mutex_unlock(&(par->open_lock)); in i740fb_suspend()
1205 mutex_unlock(&(par->open_lock)); in i740fb_suspend()
1214 struct i740fb_par *par = info->par; in i740fb_resume()
1217 mutex_lock(&(par->open_lock)); in i740fb_resume()
1219 if (par->ref_count == 0) in i740fb_resume()
1226 mutex_unlock(&(par->open_lock)); in i740fb_resume()
1288 return -ENODEV; in i740fb_init()
1292 return -ENODEV; in i740fb_init()
1307 MODULE_AUTHOR("(c) 2011 Ondrej Zary <linux@rainbow-software.org>");
1312 MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
1315 MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");