📄 nvidia.c
字号:
.left_margin = 40, .right_margin = 24, .upper_margin = 32, .lower_margin = 11, .hsync_len = 96, .vsync_len = 2, .vmode = FB_VMODE_NONINTERLACED};/* * Backlight control */#ifdef CONFIG_PMAC_BACKLIGHTstatic int nvidia_backlight_levels[] = { 0x158, 0x192, 0x1c6, 0x200, 0x234, 0x268, 0x2a2, 0x2d6, 0x310, 0x344, 0x378, 0x3b2, 0x3e6, 0x41a, 0x454, 0x534,};/* ------------------------------------------------------------------------- * * * Backlight operations * * ------------------------------------------------------------------------- */static int nvidia_set_backlight_enable(int on, int level, void *data){ struct nvidia_par *par = (struct nvidia_par *)data; u32 tmp_pcrt, tmp_pmc, fpcontrol; tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF; tmp_pcrt = NV_RD32(par->PCRTC0, 0x081C) & 0xFFFFFFFC; fpcontrol = NV_RD32(par->PRAMDAC, 0x0848) & 0xCFFFFFCC; if (on && (level > BACKLIGHT_OFF)) { tmp_pcrt |= 0x1; tmp_pmc |= (1 << 31); // backlight bit tmp_pmc |= nvidia_backlight_levels[level - 1] << 16; } if (on) fpcontrol |= par->fpSyncs; else fpcontrol |= 0x20000022; NV_WR32(par->PCRTC0, 0x081C, tmp_pcrt); NV_WR32(par->PMC, 0x10F0, tmp_pmc); NV_WR32(par->PRAMDAC, 0x848, fpcontrol); return 0;}static int nvidia_set_backlight_level(int level, void *data){ return nvidia_set_backlight_enable(1, level, data);}static struct backlight_controller nvidia_backlight_controller = { nvidia_set_backlight_enable, nvidia_set_backlight_level};#endif /* CONFIG_PMAC_BACKLIGHT */static void nvidiafb_load_cursor_image(struct nvidia_par *par, u8 * data8, u16 bg, u16 fg, u32 w, u32 h){ u32 *data = (u32 *) data8; int i, j, k = 0; u32 b, tmp; w = (w + 1) & ~1; for (i = 0; i < h; i++) { b = *data++; reverse_order(&b); for (j = 0; j < w / 2; j++) { tmp = 0;#if defined (__BIG_ENDIAN) tmp = (b & (1 << 31)) ? fg << 16 : bg << 16; b <<= 1; tmp |= (b & (1 << 31)) ? fg : bg; b <<= 1;#else tmp = (b & 1) ? fg : bg; b >>= 1; tmp |= (b & 1) ? fg << 16 : bg << 16; b >>= 1;#endif NV_WR32(&par->CURSOR[k++], 0, tmp); } k += (MAX_CURS - w) / 2; }}static void nvidia_write_clut(struct nvidia_par *par, u8 regnum, u8 red, u8 green, u8 blue){ NVWriteDacMask(par, 0xff); NVWriteDacWriteAddr(par, regnum); NVWriteDacData(par, red); NVWriteDacData(par, green); NVWriteDacData(par, blue);}static void nvidia_read_clut(struct nvidia_par *par, u8 regnum, u8 * red, u8 * green, u8 * blue){ NVWriteDacMask(par, 0xff); NVWriteDacReadAddr(par, regnum); *red = NVReadDacData(par); *green = NVReadDacData(par); *blue = NVReadDacData(par);}static int nvidia_panel_tweak(struct nvidia_par *par, struct _riva_hw_state *state){ int tweak = 0; if (par->paneltweak) { tweak = par->paneltweak; } else { /* begin flat panel hacks */ /* This is unfortunate, but some chips need this register tweaked or else you get artifacts where adjacent pixels are swapped. There are no hard rules for what to set here so all we can do is experiment and apply hacks. */ if(((par->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) { /* At least one NV34 laptop needs this workaround. */ tweak = -1; } if((par->Chipset & 0xfff0) == 0x0310) { tweak = 1; } /* end flat panel hacks */ } return tweak;}static void nvidia_save_vga(struct nvidia_par *par, struct _riva_hw_state *state){ int i; NVTRACE_ENTER(); NVLockUnlock(par, 0); NVUnloadStateExt(par, state); state->misc_output = NVReadMiscOut(par); for (i = 0; i < NUM_CRT_REGS; i++) state->crtc[i] = NVReadCrtc(par, i); for (i = 0; i < NUM_ATC_REGS; i++) state->attr[i] = NVReadAttr(par, i); for (i = 0; i < NUM_GRC_REGS; i++) state->gra[i] = NVReadGr(par, i); for (i = 0; i < NUM_SEQ_REGS; i++) state->seq[i] = NVReadSeq(par, i); NVTRACE_LEAVE();}static void nvidia_write_regs(struct nvidia_par *par){ struct _riva_hw_state *state = &par->ModeReg; int i; NVTRACE_ENTER(); NVWriteCrtc(par, 0x11, 0x00); NVLockUnlock(par, 0); NVLoadStateExt(par, state); NVWriteMiscOut(par, state->misc_output); for (i = 0; i < NUM_CRT_REGS; i++) { switch (i) { case 0x19: case 0x20 ... 0x40: break; default: NVWriteCrtc(par, i, state->crtc[i]); } } for (i = 0; i < NUM_ATC_REGS; i++) NVWriteAttr(par, i, state->attr[i]); for (i = 0; i < NUM_GRC_REGS; i++) NVWriteGr(par, i, state->gra[i]); for (i = 0; i < NUM_SEQ_REGS; i++) NVWriteSeq(par, i, state->seq[i]); NVTRACE_LEAVE();}static int nvidia_calc_regs(struct fb_info *info){ struct nvidia_par *par = info->par; struct _riva_hw_state *state = &par->ModeReg; int i, depth = fb_get_color_depth(&info->var, &info->fix); int h_display = info->var.xres / 8 - 1; int h_start = (info->var.xres + info->var.right_margin) / 8 - 1; int h_end = (info->var.xres + info->var.right_margin + info->var.hsync_len) / 8 - 1; int h_total = (info->var.xres + info->var.right_margin + info->var.hsync_len + info->var.left_margin) / 8 - 5; int h_blank_s = h_display; int h_blank_e = h_total + 4; int v_display = info->var.yres - 1; int v_start = info->var.yres + info->var.lower_margin - 1; int v_end = (info->var.yres + info->var.lower_margin + info->var.vsync_len) - 1; int v_total = (info->var.yres + info->var.lower_margin + info->var.vsync_len + info->var.upper_margin) - 2; int v_blank_s = v_display; int v_blank_e = v_total + 1; /* * Set all CRTC values. */ if (info->var.vmode & FB_VMODE_INTERLACED) v_total |= 1; if (par->FlatPanel == 1) { v_start = v_total - 3; v_end = v_total - 2; v_blank_s = v_start; h_start = h_total - 5; h_end = h_total - 2; h_blank_e = h_total + 4; } state->crtc[0x0] = Set8Bits(h_total); state->crtc[0x1] = Set8Bits(h_display); state->crtc[0x2] = Set8Bits(h_blank_s); state->crtc[0x3] = SetBitField(h_blank_e, 4: 0, 4:0) | SetBit(7); state->crtc[0x4] = Set8Bits(h_start); state->crtc[0x5] = SetBitField(h_blank_e, 5: 5, 7:7) | SetBitField(h_end, 4: 0, 4:0); state->crtc[0x6] = SetBitField(v_total, 7: 0, 7:0); state->crtc[0x7] = SetBitField(v_total, 8: 8, 0:0) | SetBitField(v_display, 8: 8, 1:1) | SetBitField(v_start, 8: 8, 2:2) | SetBitField(v_blank_s, 8: 8, 3:3) | SetBit(4) | SetBitField(v_total, 9: 9, 5:5) | SetBitField(v_display, 9: 9, 6:6) | SetBitField(v_start, 9: 9, 7:7); state->crtc[0x9] = SetBitField(v_blank_s, 9: 9, 5:5) | SetBit(6) | ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0x00); state->crtc[0x10] = Set8Bits(v_start); state->crtc[0x11] = SetBitField(v_end, 3: 0, 3:0) | SetBit(5); state->crtc[0x12] = Set8Bits(v_display); state->crtc[0x13] = ((info->var.xres_virtual / 8) * (info->var.bits_per_pixel / 8)); state->crtc[0x15] = Set8Bits(v_blank_s); state->crtc[0x16] = Set8Bits(v_blank_e); state->attr[0x10] = 0x01; if (par->Television) state->attr[0x11] = 0x00; state->screen = SetBitField(h_blank_e, 6: 6, 4:4) | SetBitField(v_blank_s, 10: 10, 3:3) | SetBitField(v_start, 10: 10, 2:2) | SetBitField(v_display, 10: 10, 1:1) | SetBitField(v_total, 10: 10, 0:0); state->horiz = SetBitField(h_total, 8: 8, 0:0) | SetBitField(h_display, 8: 8, 1:1) | SetBitField(h_blank_s, 8: 8, 2:2) | SetBitField(h_start, 8: 8, 3:3); state->extra = SetBitField(v_total, 11: 11, 0:0) | SetBitField(v_display, 11: 11, 2:2) | SetBitField(v_start, 11: 11, 4:4) | SetBitField(v_blank_s, 11: 11, 6:6); if (info->var.vmode & FB_VMODE_INTERLACED) { h_total = (h_total >> 1) & ~1; state->interlace = Set8Bits(h_total); state->horiz |= SetBitField(h_total, 8: 8, 4:4); } else { state->interlace = 0xff; /* interlace off */ } /* * Calculate the extended registers. */ if (depth < 24) i = depth; else i = 32; if (par->Architecture >= NV_ARCH_10) par->CURSOR = (volatile u32 __iomem *)(info->screen_base + par->CursorStart); if (info->var.sync & FB_SYNC_HOR_HIGH_ACT) state->misc_output &= ~0x40; else state->misc_output |= 0x40; if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) state->misc_output &= ~0x80; else state->misc_output |= 0x80; NVCalcStateExt(par, state, i, info->var.xres_virtual, info->var.xres, info->var.yres_virtual, 1000000000 / info->var.pixclock, info->var.vmode); state->scale = NV_RD32(par->PRAMDAC, 0x00000848) & 0xfff000ff; if (par->FlatPanel == 1) { state->pixel |= (1 << 7); if (!par->fpScaler || (par->fpWidth <= info->var.xres) || (par->fpHeight <= info->var.yres)) { state->scale |= (1 << 8); } if (!par->crtcSync_read) { state->crtcSync = NV_RD32(par->PRAMDAC, 0x0828); par->crtcSync_read = 1; } par->PanelTweak = nvidia_panel_tweak(par, state); } state->vpll = state->pll; state->vpll2 = state->pll; state->vpllB = state->pllB; state->vpll2B = state->pllB; VGA_WR08(par->PCIO, 0x03D4, 0x1C); state->fifo = VGA_RD08(par->PCIO, 0x03D5) & ~(1<<5); if (par->CRTCnumber) { state->head = NV_RD32(par->PCRTC0, 0x00000860) & ~0x00001000; state->head2 = NV_RD32(par->PCRTC0, 0x00002860) | 0x00001000; state->crtcOwner = 3; state->pllsel |= 0x20000800; state->vpll = NV_RD32(par->PRAMDAC0, 0x00000508); if (par->twoStagePLL) state->vpllB = NV_RD32(par->PRAMDAC0, 0x00000578); } else if (par->twoHeads) { state->head = NV_RD32(par->PCRTC0, 0x00000860) | 0x00001000; state->head2 = NV_RD32(par->PCRTC0, 0x00002860) & ~0x00001000; state->crtcOwner = 0; state->vpll2 = NV_RD32(par->PRAMDAC0, 0x0520); if (par->twoStagePLL) state->vpll2B = NV_RD32(par->PRAMDAC0, 0x057C); } state->cursorConfig = 0x00000100; if (info->var.vmode & FB_VMODE_DOUBLE) state->cursorConfig |= (1 << 4); if (par->alphaCursor) { if ((par->Chipset & 0x0ff0) != 0x0110) state->cursorConfig |= 0x04011000; else state->cursorConfig |= 0x14011000; state->general |= (1 << 29); } else state->cursorConfig |= 0x02000000; if (par->twoHeads) { if ((par->Chipset & 0x0ff0) == 0x0110) { state->dither = NV_RD32(par->PRAMDAC, 0x0528) & ~0x00010000; if (par->FPDither) state->dither |= 0x00010000; } else { state->dither = NV_RD32(par->PRAMDAC, 0x083C) & ~1; if (par->FPDither) state->dither |= 1; } } state->timingH = 0; state->timingV = 0; state->displayV = info->var.xres; return 0;}static void nvidia_init_vga(struct fb_info *info){ struct nvidia_par *par = info->par; struct _riva_hw_state *state = &par->ModeReg; int i; for (i = 0; i < 0x10; i++) state->attr[i] = i; state->attr[0x10] = 0x41; state->attr[0x11] = 0x01; state->attr[0x12] = 0x0f; state->attr[0x13] = 0x00; state->attr[0x14] = 0x00; memset(state->crtc, 0x00, NUM_CRT_REGS); state->crtc[0x0a] = 0x20; state->crtc[0x17] = 0xe3; state->crtc[0x18] = 0xff; state->crtc[0x28] = 0x40; memset(state->gra, 0x00, NUM_GRC_REGS);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -