drm/mgag200: Add support for a new G200eW3 chipset
- Added support for the new deviceID for G200eW3 - Added PLL algorithm for the G200eW3 - Added some initialization code for G200eW3 Signed-off-by: Mathieu Larouche <mathieu.larouche@matrox.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
44790462d0
commit
6d857c18ae
|
@ -35,6 +35,7 @@ static const struct pci_device_id pciidlist[] = {
|
|||
{ PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB },
|
||||
{ PCI_VENDOR_ID_MATROX, 0x533, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EH },
|
||||
{ PCI_VENDOR_ID_MATROX, 0x534, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_ER },
|
||||
{ PCI_VENDOR_ID_MATROX, 0x536, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EW3 },
|
||||
{0,}
|
||||
};
|
||||
|
||||
|
|
|
@ -180,6 +180,7 @@ enum mga_type {
|
|||
G200_EV,
|
||||
G200_EH,
|
||||
G200_ER,
|
||||
G200_EW3,
|
||||
};
|
||||
|
||||
#define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
|
||||
|
|
|
@ -101,6 +101,7 @@ struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev)
|
|||
case G200_SE_B:
|
||||
case G200_EV:
|
||||
case G200_WB:
|
||||
case G200_EW3:
|
||||
data = 1;
|
||||
clock = 2;
|
||||
break;
|
||||
|
|
|
@ -82,12 +82,19 @@ static int mga_probe_vram(struct mga_device *mdev, void __iomem *mem)
|
|||
int orig;
|
||||
int test1, test2;
|
||||
int orig1, orig2;
|
||||
unsigned int vram_size;
|
||||
|
||||
/* Probe */
|
||||
orig = ioread16(mem);
|
||||
iowrite16(0, mem);
|
||||
|
||||
for (offset = 0x100000; offset < mdev->mc.vram_window; offset += 0x4000) {
|
||||
vram_size = mdev->mc.vram_window;
|
||||
|
||||
if ((mdev->type == G200_EW3) && (vram_size >= 0x1000000)) {
|
||||
vram_size = vram_size - 0x400000;
|
||||
}
|
||||
|
||||
for (offset = 0x100000; offset < vram_size; offset += 0x4000) {
|
||||
orig1 = ioread8(mem + offset);
|
||||
orig2 = ioread8(mem + offset + 0x100);
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
|
|||
{
|
||||
unsigned int vcomax, vcomin, pllreffreq;
|
||||
unsigned int delta, tmpdelta;
|
||||
unsigned int testp, testm, testn;
|
||||
unsigned int testp, testm, testn, testp2;
|
||||
unsigned int p, m, n;
|
||||
unsigned int computed;
|
||||
int i, j, tmpcount, vcount;
|
||||
|
@ -167,31 +167,71 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
|
|||
u8 tmp;
|
||||
|
||||
m = n = p = 0;
|
||||
vcomax = 550000;
|
||||
vcomin = 150000;
|
||||
pllreffreq = 48000;
|
||||
|
||||
delta = 0xffffffff;
|
||||
|
||||
for (testp = 1; testp < 9; testp++) {
|
||||
if (clock * testp > vcomax)
|
||||
continue;
|
||||
if (clock * testp < vcomin)
|
||||
continue;
|
||||
if (mdev->type == G200_EW3) {
|
||||
|
||||
for (testm = 1; testm < 17; testm++) {
|
||||
for (testn = 1; testn < 151; 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) | ((n >> 1) & 0x80);
|
||||
p = testp - 1;
|
||||
vcomax = 800000;
|
||||
vcomin = 400000;
|
||||
pllreffreq = 25000;
|
||||
|
||||
for (testp = 1; testp < 8; testp++) {
|
||||
for (testp2 = 1; testp2 < 8; testp2++) {
|
||||
if (testp < testp2)
|
||||
continue;
|
||||
if ((clock * testp * testp2) > vcomax)
|
||||
continue;
|
||||
if ((clock * testp * testp2) < vcomin)
|
||||
continue;
|
||||
for (testm = 1; testm < 26; testm++) {
|
||||
for (testn = 32; testn < 2048 ; testn++) {
|
||||
computed = (pllreffreq * testn) /
|
||||
(testm * testp * testp2);
|
||||
if (computed > clock)
|
||||
tmpdelta = computed - clock;
|
||||
else
|
||||
tmpdelta = clock - computed;
|
||||
if (tmpdelta < delta) {
|
||||
delta = tmpdelta;
|
||||
m = ((testn & 0x100) >> 1) |
|
||||
(testm);
|
||||
n = (testn & 0xFF);
|
||||
p = ((testn & 0x600) >> 3) |
|
||||
(testp2 << 3) |
|
||||
(testp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
vcomax = 550000;
|
||||
vcomin = 150000;
|
||||
pllreffreq = 48000;
|
||||
|
||||
for (testp = 1; testp < 9; testp++) {
|
||||
if (clock * testp > vcomax)
|
||||
continue;
|
||||
if (clock * testp < vcomin)
|
||||
continue;
|
||||
|
||||
for (testm = 1; testm < 17; testm++) {
|
||||
for (testn = 1; testn < 151; 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) |
|
||||
((n >> 1) & 0x80);
|
||||
p = testp - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -569,6 +609,7 @@ static int mga_crtc_set_plls(struct mga_device *mdev, long clock)
|
|||
return mga_g200se_set_plls(mdev, clock);
|
||||
break;
|
||||
case G200_WB:
|
||||
case G200_EW3:
|
||||
return mga_g200wb_set_plls(mdev, clock);
|
||||
break;
|
||||
case G200_EV:
|
||||
|
@ -820,6 +861,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
|
|||
option2 = 0x00008000;
|
||||
break;
|
||||
case G200_WB:
|
||||
case G200_EW3:
|
||||
dacvalue[MGA1064_VREF_CTL] = 0x07;
|
||||
option = 0x41049120;
|
||||
option2 = 0x0000b000;
|
||||
|
@ -875,7 +917,10 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
|
|||
if (IS_G200_SE(mdev) &&
|
||||
((i == 0x2c) || (i == 0x2d) || (i == 0x2e)))
|
||||
continue;
|
||||
if ((mdev->type == G200_EV || mdev->type == G200_WB || mdev->type == G200_EH) &&
|
||||
if ((mdev->type == G200_EV ||
|
||||
mdev->type == G200_WB ||
|
||||
mdev->type == G200_EH ||
|
||||
mdev->type == G200_EW3) &&
|
||||
(i >= 0x44) && (i <= 0x4e))
|
||||
continue;
|
||||
|
||||
|
@ -977,7 +1022,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
|
|||
else
|
||||
ext_vga[3] = ((1 << bppshift) - 1) | 0x80;
|
||||
ext_vga[4] = 0;
|
||||
if (mdev->type == G200_WB)
|
||||
if (mdev->type == G200_WB || mdev->type == G200_EW3)
|
||||
ext_vga[1] |= 0x88;
|
||||
|
||||
/* Set pixel clocks */
|
||||
|
@ -993,6 +1038,9 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
|
|||
if (mdev->type == G200_ER)
|
||||
WREG_ECRT(0x24, 0x5);
|
||||
|
||||
if (mdev->type == G200_EW3)
|
||||
WREG_ECRT(0x34, 0x5);
|
||||
|
||||
if (mdev->type == G200_EV) {
|
||||
WREG_ECRT(6, 0);
|
||||
}
|
||||
|
@ -1205,7 +1253,7 @@ static void mga_crtc_prepare(struct drm_crtc *crtc)
|
|||
WREG_SEQ(1, tmp | 0x20);
|
||||
}
|
||||
|
||||
if (mdev->type == G200_WB)
|
||||
if (mdev->type == G200_WB || mdev->type == G200_EW3)
|
||||
mga_g200wb_prepare(crtc);
|
||||
|
||||
WREG_CRT(17, 0);
|
||||
|
@ -1222,7 +1270,7 @@ static void mga_crtc_commit(struct drm_crtc *crtc)
|
|||
const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
|
||||
u8 tmp;
|
||||
|
||||
if (mdev->type == G200_WB)
|
||||
if (mdev->type == G200_WB || mdev->type == G200_EW3)
|
||||
mga_g200wb_commit(crtc);
|
||||
|
||||
if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) {
|
||||
|
|
Loading…
Reference in New Issue