Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
b0f3e5d4
Commit
b0f3e5d4
authored
Aug 14, 2002
by
Petr Vandrovec
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add TV-Out support for Matrox G450/G550. Due to the hardware only secondary
CRTC can be used as a source for TV output.
parent
705e41f8
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
356 additions
and
10 deletions
+356
-10
drivers/video/Config.help
drivers/video/Config.help
+9
-0
drivers/video/matrox/matroxfb_crtc2.c
drivers/video/matrox/matroxfb_crtc2.c
+16
-6
drivers/video/matrox/matroxfb_crtc2.h
drivers/video/matrox/matroxfb_crtc2.h
+2
-0
drivers/video/matrox/matroxfb_g450.c
drivers/video/matrox/matroxfb_g450.c
+329
-4
No files found.
drivers/video/Config.help
View file @
b0f3e5d4
...
...
@@ -425,12 +425,21 @@ CONFIG_FB_MATROX_G450
support" here in the framebuffer section. G450/G550 secondary head
and digital output are supported without additional modules.
The driver starts in monitor mode. You must use the matroxset tool
(available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to
swap primary and secondary head outputs, or to change output mode.
Secondary head driver always start in 640x480 resolution and you
must use fbset to change it.
Do not forget that second head supports only 16 and 32 bpp
packed pixels, so it is a good idea to compile them into the kernel
too. You can use only some font widths, as the driver uses generic
painting procedures (the secondary head does not use acceleration
engine).
G450/G550 hardware can display TV picture only from secondary CRTC,
and it performs no scaling, so picture must have 525 or 625 lines.
CONFIG_FB_MATROX_G100A
Say Y here if you have a Matrox G100, G200 or G400 based
video card. If you select "Advanced lowlevel driver options", you
...
...
drivers/video/matrox/matroxfb_crtc2.c
View file @
b0f3e5d4
...
...
@@ -2,11 +2,11 @@
*
* Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
*
* (c) 1998-200
1
Petr Vandrovec <vandrove@vc.cvut.cz>
* (c) 1998-200
2
Petr Vandrovec <vandrove@vc.cvut.cz>
*
* Portions Copyright (c) 2001 Matrox Graphics Inc.
*
* Version: 1.6
2 2001/11/29
* Version: 1.6
4 2002/06/10
*
*/
...
...
@@ -103,6 +103,7 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
int
mode
,
unsigned
int
pos
)
{
u_int32_t
tmp
;
u_int32_t
datactl
;
MINFO_FROM
(
m2info
->
primary_dev
);
switch
(
mode
)
{
...
...
@@ -117,12 +118,15 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
tmp
=
0x00800000
;
break
;
}
tmp
|=
0x00000001
;
/* enable CRTC2 */
datactl
=
0
;
if
(
ACCESS_FBINFO
(
outputs
[
1
]).
src
==
MATROXFB_SRC_CRTC2
)
{
if
(
ACCESS_FBINFO
(
devflags
.
g450dac
))
{
tmp
|=
0x00000006
;
/* source from secondary pixel PLL */
/* no vidrst */
/* no vidrst when in monitor mode */
if
(
ACCESS_FBINFO
(
outputs
[
1
]).
mode
!=
MATROXFB_OUTPUT_MODE_MONITOR
)
{
tmp
|=
0xC0001000
;
/* Enable H/V vidrst */
}
}
else
{
tmp
|=
0x00000002
;
/* source from VDOCLK */
tmp
|=
0xC0000000
;
/* enable vvidrst & hvidrst */
...
...
@@ -142,6 +146,10 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
mt
->
VSyncEnd
>>=
1
;
mt
->
VTotal
>>=
1
;
}
if
((
mt
->
HTotal
&
7
)
==
2
)
{
datactl
|=
0x00000010
;
mt
->
HTotal
&=
~
7
;
}
tmp
|=
0x10000000
;
/* 0x10000000 is VIDRST polarity */
mga_outl
(
0x3C14
,
((
mt
->
HDisplay
-
8
)
<<
16
)
|
(
mt
->
HTotal
-
8
));
mga_outl
(
0x3C18
,
((
mt
->
HSyncEnd
-
8
)
<<
16
)
|
(
mt
->
HSyncStart
-
8
));
...
...
@@ -155,12 +163,14 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
mga_outl
(
0x3C2C
,
pos
);
/* field #1 vmemory start */
mga_outl
(
0x3C28
,
pos
+
linelen
);
/* field #0 vmemory start */
linelen
<<=
1
;
m2info
->
interlaced
=
1
;
}
else
{
mga_outl
(
0x3C28
,
pos
);
/* vmemory start */
m2info
->
interlaced
=
0
;
}
mga_outl
(
0x3C40
,
linelen
);
}
mga_outl
(
0x3C4C
,
0
);
/* data control */
mga_outl
(
0x3C4C
,
datactl
);
/* data control */
if
(
tmp
&
0x02000000
)
{
int
i
;
...
...
@@ -208,7 +218,7 @@ static void matroxfb_dh_pan_var(struct matroxfb_dh_fb_info* m2info,
linelen
=
var
->
xres_virtual
*
pixelsize
;
pos
=
var
->
yoffset
*
linelen
+
var
->
xoffset
*
pixelsize
;
pos
+=
m2info
->
video
.
offbase
;
if
(
var
->
vmode
&
FB_VMODE_INTERLACED
)
{
if
(
m2info
->
interlaced
)
{
mga_outl
(
0x3C2C
,
pos
);
mga_outl
(
0x3C28
,
pos
+
linelen
);
}
else
{
...
...
drivers/video/matrox/matroxfb_crtc2.h
View file @
b0f3e5d4
...
...
@@ -30,6 +30,8 @@ struct matroxfb_dh_fb_info {
int
currcon
;
struct
display
*
currcon_display
;
int
interlaced
:
1
;
union
{
#ifdef FBCON_HAS_CFB16
u_int16_t
cfb16
[
16
];
...
...
drivers/video/matrox/matroxfb_g450.c
View file @
b0f3e5d4
...
...
@@ -2,39 +2,363 @@
*
* Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
*
* (c) 1998-200
1
Petr Vandrovec <vandrove@vc.cvut.cz>
* (c) 1998-200
2
Petr Vandrovec <vandrove@vc.cvut.cz>
*
* Portions Copyright (c) 2001 Matrox Graphics Inc.
*
* Version: 1.6
2 2001/11/29
* Version: 1.6
4 2002/06/02
*
* See matroxfb_base.c for contributors.
*
*/
#include "matroxfb_
g450
.h"
#include "matroxfb_
base
.h"
#include "matroxfb_misc.h"
#include "matroxfb_DAC1064.h"
#include "g450_pll.h"
#include <linux/matroxfb.h>
#include <asm/uaccess.h>
#include <asm/div64.h>
static
void
cve2_set_reg
(
WPMINFO
int
reg
,
int
val
)
{
unsigned
long
flags
;
matroxfb_DAC_lock_irqsave
(
flags
);
matroxfb_DAC_out
(
PMINFO
0x87
,
reg
);
matroxfb_DAC_out
(
PMINFO
0x88
,
val
);
matroxfb_DAC_unlock_irqrestore
(
flags
);
}
struct
output_desc
{
unsigned
int
h_vis
;
unsigned
int
h_f_porch
;
unsigned
int
h_sync
;
unsigned
int
h_b_porch
;
unsigned
long
long
int
chromasc
;
unsigned
int
burst
;
unsigned
int
v_total
;
};
static
void
computeRegs
(
WPMINFO
struct
mavenregs
*
r
,
struct
my_timming
*
mt
,
const
struct
output_desc
*
outd
)
{
u_int32_t
chromasc
;
u_int32_t
hlen
;
u_int32_t
hsl
;
u_int32_t
hbp
;
u_int32_t
hfp
;
u_int32_t
hvis
;
unsigned
int
pixclock
;
unsigned
long
long
piic
;
int
mnp
;
int
over
;
r
->
regs
[
0x80
]
=
0x03
;
/* | 0x40 for SCART */
hvis
=
((
mt
->
HDisplay
<<
1
)
+
3
)
&
~
3
;
if
(
hvis
>=
2048
)
{
hvis
=
2044
;
}
piic
=
1000000000ULL
*
hvis
;
do_div
(
piic
,
outd
->
h_vis
);
dprintk
(
KERN_DEBUG
"Want %u kHz pixclock
\n
"
,
(
unsigned
int
)
piic
);
mnp
=
matroxfb_g450_setclk
(
PMINFO
piic
,
M_VIDEO_PLL
);
mt
->
mnp
=
mnp
;
mt
->
pixclock
=
g450_mnp2f
(
PMINFO
mnp
);
dprintk
(
KERN_DEBUG
"MNP=%08X
\n
"
,
mnp
);
pixclock
=
1000000000U
/
mt
->
pixclock
;
dprintk
(
KERN_DEBUG
"Got %u ps pixclock
\n
"
,
pixclock
);
piic
=
outd
->
chromasc
;
do_div
(
piic
,
mt
->
pixclock
);
chromasc
=
piic
;
dprintk
(
KERN_DEBUG
"Chroma is %08X
\n
"
,
chromasc
);
r
->
regs
[
0
]
=
piic
>>
24
;
r
->
regs
[
1
]
=
piic
>>
16
;
r
->
regs
[
2
]
=
piic
>>
8
;
r
->
regs
[
3
]
=
piic
>>
0
;
hbp
=
(((
outd
->
h_b_porch
+
pixclock
)
/
pixclock
))
&
~
1
;
hfp
=
(((
outd
->
h_f_porch
+
pixclock
)
/
pixclock
))
&
~
1
;
hsl
=
(((
outd
->
h_sync
+
pixclock
)
/
pixclock
))
&
~
1
;
hlen
=
hvis
+
hfp
+
hsl
+
hbp
;
over
=
hlen
&
0x0F
;
dprintk
(
KERN_DEBUG
"WL: vis=%u, hf=%u, hs=%u, hb=%u, total=%u
\n
"
,
hvis
,
hfp
,
hsl
,
hbp
,
hlen
);
if
(
over
)
{
hfp
-=
over
;
hlen
-=
over
;
if
(
over
<=
2
)
{
}
else
if
(
over
<
10
)
{
hfp
+=
4
;
hlen
+=
4
;
}
else
{
hfp
+=
16
;
hlen
+=
16
;
}
}
/* maybe cve2 has requirement 800 < hlen < 1184 */
r
->
regs
[
0x08
]
=
hsl
;
r
->
regs
[
0x09
]
=
(
outd
->
burst
+
pixclock
-
1
)
/
pixclock
;
/* burst length */
r
->
regs
[
0x0A
]
=
hbp
;
r
->
regs
[
0x2C
]
=
hfp
;
r
->
regs
[
0x31
]
=
hvis
/
8
;
r
->
regs
[
0x32
]
=
hvis
&
7
;
dprintk
(
KERN_DEBUG
"PG: vis=%04X, hf=%02X, hs=%02X, hb=%02X, total=%04X
\n
"
,
hvis
,
hfp
,
hsl
,
hbp
,
hlen
);
r
->
regs
[
0x84
]
=
1
;
/* x sync point */
r
->
regs
[
0x85
]
=
0
;
hvis
=
hvis
>>
1
;
hlen
=
hlen
>>
1
;
dprintk
(
KERN_DEBUG
"hlen=%u hvis=%u
\n
"
,
hlen
,
hvis
);
mt
->
interlaced
=
1
;
mt
->
HDisplay
=
hvis
&
~
7
;
mt
->
HSyncStart
=
mt
->
HDisplay
+
8
;
mt
->
HSyncEnd
=
(
hlen
&
~
7
)
-
8
;
mt
->
HTotal
=
hlen
;
{
int
upper
;
unsigned
int
vtotal
;
unsigned
int
vsyncend
;
unsigned
int
vdisplay
;
vtotal
=
mt
->
VTotal
;
vsyncend
=
mt
->
VSyncEnd
;
vdisplay
=
mt
->
VDisplay
;
if
(
vtotal
<
outd
->
v_total
)
{
unsigned
int
yovr
=
outd
->
v_total
-
vtotal
;
vsyncend
+=
yovr
>>
1
;
}
else
if
(
vtotal
>
outd
->
v_total
)
{
vdisplay
=
outd
->
v_total
-
4
;
vsyncend
=
outd
->
v_total
;
}
upper
=
(
outd
->
v_total
-
vsyncend
)
>>
1
;
/* in field lines */
r
->
regs
[
0x17
]
=
outd
->
v_total
/
4
;
r
->
regs
[
0x18
]
=
outd
->
v_total
&
3
;
r
->
regs
[
0x33
]
=
upper
-
1
;
/* upper blanking */
r
->
regs
[
0x82
]
=
upper
;
/* y sync point */
r
->
regs
[
0x83
]
=
upper
>>
8
;
mt
->
VDisplay
=
vdisplay
;
mt
->
VSyncStart
=
outd
->
v_total
-
2
;
mt
->
VSyncEnd
=
outd
->
v_total
;
mt
->
VTotal
=
outd
->
v_total
;
}
}
static
void
cve2_init_TVdata
(
int
norm
,
struct
mavenregs
*
data
,
const
struct
output_desc
**
outd
)
{
static
const
struct
output_desc
paloutd
=
{
.
h_vis
=
52148148
,
// ps
.
h_f_porch
=
1407407
,
// ps
.
h_sync
=
4666667
,
// ps
.
h_b_porch
=
5777778
,
// ps
.
chromasc
=
19042247534182ULL
,
// 4433618.750 Hz
.
burst
=
2518518
,
// ps
.
v_total
=
625
,
};
static
const
struct
output_desc
ntscoutd
=
{
.
h_vis
=
52888889
,
// ps
.
h_f_porch
=
1333333
,
// ps
.
h_sync
=
4666667
,
// ps
.
h_b_porch
=
4666667
,
// ps
.
chromasc
=
15374030659475ULL
,
// 3579545.454 Hz
.
burst
=
2418418
,
// ps
.
v_total
=
525
,
// lines
};
static
const
struct
mavenregs
palregs
=
{
{
0x2A
,
0x09
,
0x8A
,
0xCB
,
/* 00: chroma subcarrier */
0x00
,
0x00
,
/* test */
0xF9
,
/* modified by code (F9 written...) */
0x00
,
/* ? not written */
0x7E
,
/* 08 */
0x44
,
/* 09 */
0x9C
,
/* 0A */
0x2E
,
/* 0B */
0x21
,
/* 0C */
0x00
,
/* ? not written */
// 0x3F, 0x03, /* 0E-0F */
0x3C
,
0x03
,
0x3C
,
0x03
,
/* 10-11 */
0x1A
,
/* 12 */
0x2A
,
/* 13 */
0x1C
,
0x3D
,
0x14
,
/* 14-16 */
0x9C
,
0x01
,
/* 17-18 */
0x00
,
/* 19 */
0xFE
,
/* 1A */
0x7E
,
/* 1B */
0x60
,
/* 1C */
0x05
,
/* 1D */
// 0x89, 0x03, /* 1E-1F */
0xAD
,
0x03
,
// 0x72, /* 20 */
0xA5
,
0x07
,
/* 21 */
// 0x72, /* 22 */
0xA5
,
0x00
,
/* 23 */
0x00
,
/* 24 */
0x00
,
/* 25 */
0x08
,
/* 26 */
0x04
,
/* 27 */
0x00
,
/* 28 */
0x1A
,
/* 29 */
0x55
,
0x01
,
/* 2A-2B */
0x26
,
/* 2C */
0x07
,
0x7E
,
/* 2D-2E */
0x02
,
0x54
,
/* 2F-30 */
0xB0
,
0x00
,
/* 31-32 */
0x14
,
/* 33 */
0x49
,
/* 34 */
0x00
,
/* 35 written multiple times */
0x00
,
/* 36 not written */
0xA3
,
/* 37 */
0xC8
,
/* 38 */
0x22
,
/* 39 */
0x02
,
/* 3A */
0x22
,
/* 3B */
0x3F
,
0x03
,
/* 3C-3D */
0x00
,
/* 3E written multiple times */
0x00
,
/* 3F not written */
}
};
static
struct
mavenregs
ntscregs
=
{
{
0x21
,
0xF0
,
0x7C
,
0x1F
,
/* 00: chroma subcarrier */
0x00
,
0x00
,
/* test */
0xF9
,
/* modified by code (F9 written...) */
0x00
,
/* ? not written */
0x7E
,
/* 08 */
0x43
,
/* 09 */
0x7E
,
/* 0A */
0x3D
,
/* 0B */
0x00
,
/* 0C */
0x00
,
/* ? not written */
0x41
,
0x00
,
/* 0E-0F */
0x3C
,
0x00
,
/* 10-11 */
0x17
,
/* 12 */
0x21
,
/* 13 */
0x1B
,
0x1B
,
0x24
,
/* 14-16 */
0x83
,
0x01
,
/* 17-18 */
0x00
,
/* 19 */
0x0F
,
/* 1A */
0x0F
,
/* 1B */
0x60
,
/* 1C */
0x05
,
/* 1D */
//0x89, 0x02, /* 1E-1F */
0xC0
,
0x02
,
/* 1E-1F */
//0x5F, /* 20 */
0x9C
,
/* 20 */
0x04
,
/* 21 */
//0x5F, /* 22 */
0x9C
,
/* 22 */
0x01
,
/* 23 */
0x02
,
/* 24 */
0x00
,
/* 25 */
0x0A
,
/* 26 */
0x05
,
/* 27 */
0x00
,
/* 28 */
0x10
,
/* 29 */
0xFF
,
0x03
,
/* 2A-2B */
0x24
,
/* 2C */
0x0F
,
0x78
,
/* 2D-2E */
0x00
,
0x00
,
/* 2F-30 */
0xB2
,
0x04
,
/* 31-32 */
0x14
,
/* 33 */
0x02
,
/* 34 */
0x00
,
/* 35 written multiple times */
0x00
,
/* 36 not written */
0xA3
,
/* 37 */
0xC8
,
/* 38 */
0x15
,
/* 39 */
0x05
,
/* 3A */
0x3B
,
/* 3B */
0x3C
,
0x00
,
/* 3C-3D */
0x00
,
/* 3E written multiple times */
0x00
,
/* never written */
}
};
if
(
norm
==
MATROXFB_OUTPUT_MODE_PAL
)
{
*
data
=
palregs
;
*
outd
=
&
paloutd
;
}
else
{
*
data
=
ntscregs
;
*
outd
=
&
ntscoutd
;
}
return
;
}
#define LR(x) cve2_set_reg(PMINFO (x), m->regs[(x)])
static
void
cve2_init_TV
(
WPMINFO
const
struct
mavenregs
*
m
)
{
int
i
;
LR
(
0x80
);
LR
(
0x82
);
LR
(
0x83
);
LR
(
0x84
);
LR
(
0x85
);
cve2_set_reg
(
PMINFO
0x3E
,
0x01
);
for
(
i
=
0
;
i
<
0x3E
;
i
++
)
{
LR
(
i
);
}
cve2_set_reg
(
PMINFO
0x3E
,
0x00
);
}
static
int
matroxfb_g450_compute
(
void
*
md
,
struct
my_timming
*
mt
)
{
MINFO_FROM
(
md
);
if
(
mt
->
mnp
<
0
)
{
dprintk
(
KERN_DEBUG
"Computing, mode=%u
\n
"
,
ACCESS_FBINFO
(
outputs
[
1
]).
mode
);
if
(
mt
->
crtc
==
MATROXFB_SRC_CRTC2
&&
ACCESS_FBINFO
(
outputs
[
1
]).
mode
!=
MATROXFB_OUTPUT_MODE_MONITOR
)
{
const
struct
output_desc
*
outd
;
cve2_init_TVdata
(
ACCESS_FBINFO
(
outputs
[
1
]).
mode
,
&
ACCESS_FBINFO
(
hw
).
maven
,
&
outd
);
computeRegs
(
PMINFO
&
ACCESS_FBINFO
(
hw
).
maven
,
mt
,
outd
);
}
else
if
(
mt
->
mnp
<
0
)
{
/* We must program clocks before CRTC2, otherwise interlaced mode
startup may fail */
mt
->
mnp
=
matroxfb_g450_setclk
(
PMINFO
mt
->
pixclock
,
(
mt
->
crtc
==
MATROXFB_SRC_CRTC1
)
?
M_PIXEL_PLL_C
:
M_VIDEO_PLL
);
mt
->
pixclock
=
g450_mnp2f
(
PMINFO
mt
->
mnp
);
}
dprintk
(
KERN_DEBUG
"Pixclock = %u
\n
"
,
mt
->
pixclock
);
return
0
;
}
static
int
matroxfb_g450_program
(
void
*
md
)
{
MINFO_FROM
(
md
);
if
(
ACCESS_FBINFO
(
outputs
[
1
]).
mode
!=
MATROXFB_OUTPUT_MODE_MONITOR
)
{
cve2_init_TV
(
PMINFO
&
ACCESS_FBINFO
(
hw
).
maven
);
}
return
0
;
}
static
int
matroxfb_g450_verify_mode
(
void
*
md
,
u_int32_t
arg
)
{
switch
(
arg
)
{
case
MATROXFB_OUTPUT_MODE_PAL
:
case
MATROXFB_OUTPUT_MODE_NTSC
:
case
MATROXFB_OUTPUT_MODE_MONITOR
:
return
0
;
}
return
-
EINVAL
;
}
static
int
g450_dvi_compute
(
void
*
md
,
struct
my_timming
*
mt
)
{
MINFO_FROM
(
md
);
...
...
@@ -49,6 +373,7 @@ static struct matrox_altout matroxfb_g450_altout = {
.
name
=
"Secondary output"
,
.
compute
=
matroxfb_g450_compute
,
.
program
=
matroxfb_g450_program
,
.
verifymode
=
matroxfb_g450_verify_mode
,
};
static
struct
matrox_altout
matroxfb_g450_dvi
=
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment