drm/mgag200: Add support for a new rev of G200e
- Added PLL algorithm for a new rev of G200e - Removed the bandwidth limitation for the new G200e Signed-off-by: Mathieu Larouche <mathieu.larouche@matrox.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:

committed by
Dave Airlie

parent
6d857c18ae
commit
e829d7ef9f
@@ -104,6 +104,8 @@ static bool mga_crtc_mode_fixup(struct drm_crtc *crtc,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define P_ARRAY_SIZE 9
|
||||||
|
|
||||||
static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
|
static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
|
||||||
{
|
{
|
||||||
unsigned int vcomax, vcomin, pllreffreq;
|
unsigned int vcomax, vcomin, pllreffreq;
|
||||||
@@ -111,37 +113,97 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
|
|||||||
unsigned int testp, testm, testn;
|
unsigned int testp, testm, testn;
|
||||||
unsigned int p, m, n;
|
unsigned int p, m, n;
|
||||||
unsigned int computed;
|
unsigned int computed;
|
||||||
|
unsigned int pvalues_e4[P_ARRAY_SIZE] = {16, 14, 12, 10, 8, 6, 4, 2, 1};
|
||||||
|
unsigned int fvv;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
m = n = p = 0;
|
if (mdev->unique_rev_id <= 0x03) {
|
||||||
vcomax = 320000;
|
|
||||||
vcomin = 160000;
|
|
||||||
pllreffreq = 25000;
|
|
||||||
|
|
||||||
delta = 0xffffffff;
|
m = n = p = 0;
|
||||||
permitteddelta = clock * 5 / 1000;
|
vcomax = 320000;
|
||||||
|
vcomin = 160000;
|
||||||
|
pllreffreq = 25000;
|
||||||
|
|
||||||
for (testp = 8; testp > 0; testp /= 2) {
|
delta = 0xffffffff;
|
||||||
if (clock * testp > vcomax)
|
permitteddelta = clock * 5 / 1000;
|
||||||
continue;
|
|
||||||
if (clock * testp < vcomin)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (testn = 17; testn < 256; testn++) {
|
for (testp = 8; testp > 0; testp /= 2) {
|
||||||
for (testm = 1; testm < 32; testm++) {
|
if (clock * testp > vcomax)
|
||||||
computed = (pllreffreq * testn) /
|
continue;
|
||||||
(testm * testp);
|
if (clock * testp < vcomin)
|
||||||
if (computed > clock)
|
continue;
|
||||||
tmpdelta = computed - clock;
|
|
||||||
else
|
for (testn = 17; testn < 256; testn++) {
|
||||||
tmpdelta = clock - computed;
|
for (testm = 1; testm < 32; testm++) {
|
||||||
if (tmpdelta < delta) {
|
computed = (pllreffreq * testn) /
|
||||||
delta = tmpdelta;
|
(testm * testp);
|
||||||
m = testm - 1;
|
if (computed > clock)
|
||||||
n = testn - 1;
|
tmpdelta = computed - clock;
|
||||||
p = testp - 1;
|
else
|
||||||
|
tmpdelta = clock - computed;
|
||||||
|
if (tmpdelta < delta) {
|
||||||
|
delta = tmpdelta;
|
||||||
|
m = testm - 1;
|
||||||
|
n = testn - 1;
|
||||||
|
p = testp - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
|
||||||
|
m = n = p = 0;
|
||||||
|
vcomax = 1600000;
|
||||||
|
vcomin = 800000;
|
||||||
|
pllreffreq = 25000;
|
||||||
|
|
||||||
|
if (clock < 25000)
|
||||||
|
clock = 25000;
|
||||||
|
|
||||||
|
clock = clock * 2;
|
||||||
|
|
||||||
|
delta = 0xFFFFFFFF;
|
||||||
|
/* Permited delta is 0.5% as VESA Specification */
|
||||||
|
permitteddelta = clock * 5 / 1000;
|
||||||
|
|
||||||
|
for (i = 0 ; i < P_ARRAY_SIZE ; i++) {
|
||||||
|
testp = pvalues_e4[i];
|
||||||
|
|
||||||
|
if ((clock * testp) > vcomax)
|
||||||
|
continue;
|
||||||
|
if ((clock * testp) < vcomin)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (testn = 50; testn <= 256; testn++) {
|
||||||
|
for (testm = 1; testm <= 32; testm++) {
|
||||||
|
computed = (pllreffreq * testn) /
|
||||||
|
(testm * testp);
|
||||||
|
if (computed > clock)
|
||||||
|
tmpdelta = computed - clock;
|
||||||
|
else
|
||||||
|
tmpdelta = clock - computed;
|
||||||
|
|
||||||
|
if (tmpdelta < delta) {
|
||||||
|
delta = tmpdelta;
|
||||||
|
m = testm - 1;
|
||||||
|
n = testn - 1;
|
||||||
|
p = testp - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fvv = pllreffreq * testn / testm;
|
||||||
|
fvv = (fvv - 800000) / 50000;
|
||||||
|
|
||||||
|
if (fvv > 15)
|
||||||
|
fvv = 15;
|
||||||
|
|
||||||
|
p |= (fvv << 4);
|
||||||
|
m |= 0x80;
|
||||||
|
|
||||||
|
clock = clock / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delta > permitteddelta) {
|
if (delta > permitteddelta) {
|
||||||
@@ -1540,7 +1602,7 @@ static int mga_vga_mode_valid(struct drm_connector *connector,
|
|||||||
if (mga_vga_calculate_mode_bandwidth(mode, bpp)
|
if (mga_vga_calculate_mode_bandwidth(mode, bpp)
|
||||||
> (24400 * 1024))
|
> (24400 * 1024))
|
||||||
return MODE_BANDWIDTH;
|
return MODE_BANDWIDTH;
|
||||||
} else if (mdev->unique_rev_id >= 0x02) {
|
} else if (mdev->unique_rev_id == 0x02) {
|
||||||
if (mode->hdisplay > 1920)
|
if (mode->hdisplay > 1920)
|
||||||
return MODE_VIRTUAL_X;
|
return MODE_VIRTUAL_X;
|
||||||
if (mode->vdisplay > 1200)
|
if (mode->vdisplay > 1200)
|
||||||
|
Reference in New Issue
Block a user