diff options
Diffstat (limited to 'drivers/gpu/drm/mgag200/mgag200_mode.c')
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_mode.c | 100 |
1 files changed, 70 insertions, 30 deletions
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 3a03ac4045d8..3938120e5051 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -38,11 +38,11 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc) WREG8(DAC_INDEX + MGA1064_INDEX, 0); - if (fb && fb->bits_per_pixel == 16) { - int inc = (fb->depth == 15) ? 8 : 4; + if (fb && fb->format->cpp[0] * 8 == 16) { + int inc = (fb->format->depth == 15) ? 8 : 4; u8 r, b; for (i = 0; i < MGAG200_LUT_SIZE; i += inc) { - if (fb->depth == 16) { + if (fb->format->depth == 16) { if (i > (MGAG200_LUT_SIZE >> 1)) { r = b = 0; } else { @@ -497,34 +497,70 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock) bool pll_locked = false; m = n = p = 0; - vcomax = 800000; - vcomin = 400000; - pllreffreq = 33333; - delta = 0xffffffff; + if (mdev->type == G200_EH3) { + vcomax = 3000000; + vcomin = 1500000; + pllreffreq = 25000; - for (testp = 16; testp > 0; testp >>= 1) { - if (clock * testp > vcomax) - continue; - if (clock * testp < vcomin) - continue; + delta = 0xffffffff; - for (testm = 1; testm < 33; testm++) { - for (testn = 17; testn < 257; testn++) { - computed = (pllreffreq * testn) / - (testm * testp); + testp = 0; + + for (testm = 150; testm >= 6; testm--) { + if (clock * testm > vcomax) + continue; + if (clock * testm < vcomin) + continue; + for (testn = 120; testn >= 60; testn--) { + computed = (pllreffreq * testn) / testm; if (computed > clock) tmpdelta = computed - clock; else tmpdelta = clock - computed; if (tmpdelta < delta) { delta = tmpdelta; - n = testn - 1; - m = (testm - 1); - p = testp - 1; + n = testn; + m = testm; + p = testp; + } + if (delta == 0) + break; + } + if (delta == 0) + break; + } + } else { + + vcomax = 800000; + vcomin = 400000; + pllreffreq = 33333; + + delta = 0xffffffff; + + for (testp = 16; testp > 0; testp >>= 1) { + if (clock * testp > vcomax) + continue; + if (clock * testp < vcomin) + continue; + + for (testm = 1; testm < 33; testm++) { + for (testn = 17; testn < 257; testn++) { + computed = (pllreffreq * testn) / + (testm * testp); + if (computed > clock) + tmpdelta = computed - clock; + else + tmpdelta = clock - computed; + if (tmpdelta < delta) { + delta = tmpdelta; + n = testn - 1; + m = (testm - 1); + p = testp - 1; + } + if ((clock * testp) >= 600000) + p |= 0x80; } - if ((clock * testp) >= 600000) - p |= 0x80; } } } @@ -674,6 +710,7 @@ static int mga_crtc_set_plls(struct mga_device *mdev, long clock) return mga_g200ev_set_plls(mdev, clock); break; case G200_EH: + case G200_EH3: return mga_g200eh_set_plls(mdev, clock); break; case G200_ER: @@ -880,6 +917,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct mga_device *mdev = dev->dev_private; + const struct drm_framebuffer *fb = crtc->primary->fb; int hdisplay, hsyncstart, hsyncend, htotal; int vdisplay, vsyncstart, vsyncend, vtotal; int pitch; @@ -902,7 +940,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, /* 0x48: */ 0, 0, 0, 0, 0, 0, 0, 0 }; - bppshift = mdev->bpp_shifts[(crtc->primary->fb->bits_per_pixel >> 3) - 1]; + bppshift = mdev->bpp_shifts[fb->format->cpp[0] - 1]; switch (mdev->type) { case G200_SE_A: @@ -932,6 +970,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, option2 = 0x0000b000; break; case G200_EH: + case G200_EH3: dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 | MGA1064_MISC_CTL_DAC_RAM_CS; option = 0x00000120; @@ -941,12 +980,12 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, break; } - switch (crtc->primary->fb->bits_per_pixel) { + switch (fb->format->cpp[0] * 8) { case 8: dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_8bits; break; case 16: - if (crtc->primary->fb->depth == 15) + if (fb->format->depth == 15) dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_15bits; else dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_16bits; @@ -978,7 +1017,8 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, if ((mdev->type == G200_EV || mdev->type == G200_WB || mdev->type == G200_EH || - mdev->type == G200_EW3) && + mdev->type == G200_EW3 || + mdev->type == G200_EH3) && (i >= 0x44) && (i <= 0x4e)) continue; @@ -997,8 +1037,8 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, WREG_SEQ(3, 0); WREG_SEQ(4, 0xe); - pitch = crtc->primary->fb->pitches[0] / (crtc->primary->fb->bits_per_pixel / 8); - if (crtc->primary->fb->bits_per_pixel == 24) + pitch = fb->pitches[0] / fb->format->cpp[0]; + if (fb->format->cpp[0] * 8 == 24) pitch = (pitch * 3) >> (4 - bppshift); else pitch = pitch >> (4 - bppshift); @@ -1075,7 +1115,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, ((vdisplay & 0xc00) >> 7) | ((vsyncstart & 0xc00) >> 5) | ((vdisplay & 0x400) >> 3); - if (crtc->primary->fb->bits_per_pixel == 24) + if (fb->format->cpp[0] * 8 == 24) ext_vga[3] = (((1 << bppshift) * 3) - 1) | 0x80; else ext_vga[3] = ((1 << bppshift) - 1) | 0x80; @@ -1138,9 +1178,9 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, u32 bpp; u32 mb; - if (crtc->primary->fb->bits_per_pixel > 16) + if (fb->format->cpp[0] * 8 > 16) bpp = 32; - else if (crtc->primary->fb->bits_per_pixel > 8) + else if (fb->format->cpp[0] * 8 > 8) bpp = 16; else bpp = 8; |