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
062dffea
Commit
062dffea
authored
Aug 16, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://matroxfb.bkbits.net/linux-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
273cbb5a
75273dcb
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1405 additions
and
1083 deletions
+1405
-1083
drivers/video/Config.help
drivers/video/Config.help
+30
-28
drivers/video/Config.in
drivers/video/Config.in
+7
-2
drivers/video/matrox/Makefile
drivers/video/matrox/Makefile
+3
-3
drivers/video/matrox/g450_pll.c
drivers/video/matrox/g450_pll.c
+46
-39
drivers/video/matrox/g450_pll.h
drivers/video/matrox/g450_pll.h
+2
-0
drivers/video/matrox/i2c-matroxfb.c
drivers/video/matrox/i2c-matroxfb.c
+63
-196
drivers/video/matrox/matroxfb_DAC1064.c
drivers/video/matrox/matroxfb_DAC1064.c
+224
-108
drivers/video/matrox/matroxfb_DAC1064.h
drivers/video/matrox/matroxfb_DAC1064.h
+3
-1
drivers/video/matrox/matroxfb_Ti3026.c
drivers/video/matrox/matroxfb_Ti3026.c
+16
-6
drivers/video/matrox/matroxfb_accel.c
drivers/video/matrox/matroxfb_accel.c
+17
-17
drivers/video/matrox/matroxfb_accel.h
drivers/video/matrox/matroxfb_accel.h
+1
-1
drivers/video/matrox/matroxfb_base.c
drivers/video/matrox/matroxfb_base.c
+301
-307
drivers/video/matrox/matroxfb_base.h
drivers/video/matrox/matroxfb_base.h
+33
-21
drivers/video/matrox/matroxfb_crtc2.c
drivers/video/matrox/matroxfb_crtc2.c
+214
-163
drivers/video/matrox/matroxfb_crtc2.h
drivers/video/matrox/matroxfb_crtc2.h
+2
-1
drivers/video/matrox/matroxfb_g450.c
drivers/video/matrox/matroxfb_g450.c
+369
-96
drivers/video/matrox/matroxfb_g450.h
drivers/video/matrox/matroxfb_g450.h
+8
-6
drivers/video/matrox/matroxfb_maven.c
drivers/video/matrox/matroxfb_maven.c
+53
-71
drivers/video/matrox/matroxfb_maven.h
drivers/video/matrox/matroxfb_maven.h
+5
-11
drivers/video/matrox/matroxfb_misc.c
drivers/video/matrox/matroxfb_misc.c
+8
-6
No files found.
drivers/video/Config.help
View file @
062dffea
...
...
@@ -387,8 +387,7 @@ CONFIG_FB_MATROX
Say Y here if you have a Matrox Millennium, Matrox Millennium II,
Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video,
Matrox G400, G450 or G550 card in your box. At this time, support for
the G-series digital output is almost non-existant.
Matrox G400, G450 or G550 card in your box.
This driver is also available as a module ( = code which can be
inserted and removed from the running kernel whenever you want).
...
...
@@ -413,7 +412,7 @@ CONFIG_FB_MATROX_MYSTIQUE
packed pixel and 32 bpp packed pixel. You can also use font widths
different from 8.
CONFIG_FB_MATROX_G
10
0
CONFIG_FB_MATROX_G
45
0
Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based
video card. If you select "Advanced lowlevel driver options", you
should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed
...
...
@@ -423,11 +422,35 @@ CONFIG_FB_MATROX_G100
If you need support for G400 secondary head, you must first say Y to
"I2C support" and "I2C bit-banging support" in the character devices
section, and then to "Matrox I2C support" and "G400 second head
support" here in the framebuffer section.
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).
If you have G550, you must also compile support for G450/G550 secondary
head into kernel, otherwise picture will be shown only on output you
are probably not using...
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
should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed
pixel and 32 bpp packed pixel. You can also use font widths
different from 8.
If you need support for G400 secondary head, you must first say Y to
"I2C support" and "I2C bit-banging support" in the character devices
section, and then to "Matrox I2C support" and "G400 second head
support" here in the framebuffer section.
CONFIG_FB_MATROX_I2C
This drivers creates I2C buses which are needed for accessing the
...
...
@@ -470,27 +493,6 @@ CONFIG_FB_MATROX_MAVEN
painting procedures (the secondary head does not use acceleration
engine).
CONFIG_FB_MATROX_G450
Say Y or M here if you want to use a secondary head (meaning two
monitors in parallel) on G450, or if you are using analog output
of G550.
If you compile it as module, two modules are created,
matroxfb_crtc2.o and matroxfb_g450.o. Both modules are needed if you
want two independent display devices.
The driver starts in monitor mode and currently does not support
output in TV modes. You must use the matroxset tool (available
at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to swap
primary and secondary head outputs. Secondary head driver always
start in 640x480 resolution and you must use fbset to change it.
Also 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).
CONFIG_FB_MATROX_MULTIHEAD
Say Y here if you have more than one (supported) Matrox device in
your computer and you want to use all of them for different monitors
...
...
drivers/video/Config.in
View file @
062dffea
...
...
@@ -130,14 +130,19 @@ if [ "$CONFIG_FB" = "y" ]; then
if [ "$CONFIG_FB_MATROX" != "n" ]; then
bool ' Millennium I/II support' CONFIG_FB_MATROX_MILLENIUM
bool ' Mystique support' CONFIG_FB_MATROX_MYSTIQUE
bool ' G100/G200/G400/G450/G550 support' CONFIG_FB_MATROX_G100
bool ' G100/G200/G400/G450/G550 support' CONFIG_FB_MATROX_G450
if [ "$CONFIG_FB_MATROX_G450" = "n" ]; then
bool ' G100/G200/G400 support' CONFIG_FB_MATROX_G100A
fi
if [ "$CONFIG_FB_MATROX_G450" = "y" -o "$CONFIG_FB_MATROX_G100A" = "y" ]; then
define_bool CONFIG_FB_MATROX_G100 y
fi
if [ "$CONFIG_I2C" != "n" ]; then
dep_tristate ' Matrox I2C support' CONFIG_FB_MATROX_I2C $CONFIG_FB_MATROX $CONFIG_I2C_ALGOBIT
if [ "$CONFIG_FB_MATROX_G100" = "y" ]; then
dep_tristate ' G400 second head support' CONFIG_FB_MATROX_MAVEN $CONFIG_FB_MATROX_I2C
fi
fi
dep_tristate ' G450/G550 second head support (mandatory for G550)' CONFIG_FB_MATROX_G450 $CONFIG_FB_MATROX_G100
bool ' Multihead support' CONFIG_FB_MATROX_MULTIHEAD
fi
tristate ' ATI Mach64 display support (EXPERIMENTAL)' CONFIG_FB_ATY
...
...
drivers/video/matrox/Makefile
View file @
062dffea
...
...
@@ -5,16 +5,16 @@
# All of the (potential) objects that export symbols.
# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
export-objs
:=
matroxfb_base.o matroxfb_accel.o matroxfb_DAC1064.o matroxfb_Ti3026.o matroxfb_misc.o g450_pll.o
export-objs
:=
matroxfb_base.o matroxfb_accel.o matroxfb_DAC1064.o matroxfb_Ti3026.o matroxfb_misc.o g450_pll.o
matroxfb_g450.o
# Each configuration option enables a list of files.
my-obj-$(CONFIG_FB_MATROX_G100)
:=
g450_pll.o
my-obj-$(CONFIG_FB_MATROX_G100)
+=
g450_pll.o
my-obj-$(CONFIG_FB_MATROX_G450)
+=
matroxfb_g450.o matroxfb_crtc2.o
obj-$(CONFIG_FB_MATROX)
+=
matroxfb_base.o matroxfb_accel.o matroxfb_DAC1064.o matroxfb_Ti3026.o matroxfb_misc.o
$
(
my-obj-y
)
obj-$(CONFIG_FB_MATROX_I2C)
+=
i2c-matroxfb.o
obj-$(CONFIG_FB_MATROX_MAVEN)
+=
matroxfb_maven.o matroxfb_crtc2.o
obj-$(CONFIG_FB_MATROX_G450)
+=
matroxfb_g450.o matroxfb_crtc2.o
include
$(TOPDIR)/Rules.make
...
...
drivers/video/matrox/g450_pll.c
View file @
062dffea
...
...
@@ -2,11 +2,11 @@
*
* Hardware accelerated Matrox PCI cards - G450/G550 PLL control.
*
* (c) 2001 Petr Vandrovec <vandrove@vc.cvut.cz>
* (c) 2001
-2002
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
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
...
...
@@ -33,6 +33,10 @@ static unsigned int g450_mnp2vco(CPMINFO unsigned int mnp) {
return
(
ACCESS_FBINFO
(
features
).
pll
.
ref_freq
*
n
+
(
m
>>
1
))
/
m
;
}
unsigned
int
g450_mnp2f
(
CPMINFO
unsigned
int
mnp
)
{
return
g450_vco2f
(
mnp
,
g450_mnp2vco
(
PMINFO
mnp
));
}
static
inline
unsigned
int
pll_freq_delta
(
unsigned
int
f1
,
unsigned
int
f2
)
{
if
(
f2
<
f1
)
{
f2
=
f1
-
f2
;
...
...
@@ -52,40 +56,42 @@ static unsigned int g450_nextpll(CPMINFO const struct matrox_pll_limits* pi, uns
m
=
(
mnp
>>
16
)
&
0xFF
;
p
=
mnp
&
0xFF
;
if
(
m
==
0
||
m
==
0xFF
)
{
if
(
m
==
0
)
{
if
(
p
&
0x40
)
{
return
NO_MORE_MNP
;
do
{
if
(
m
==
0
||
m
==
0xFF
)
{
if
(
m
==
0
)
{
if
(
p
&
0x40
)
{
return
NO_MORE_MNP
;
}
if
(
p
&
3
)
{
p
--
;
}
else
{
p
=
0x40
;
}
tvco
>>=
1
;
if
(
tvco
<
pi
->
vcomin
)
{
return
NO_MORE_MNP
;
}
*
fvco
=
tvco
;
}
if
(
p
&
3
)
{
p
--
;
p
&=
0x43
;
if
(
tvco
<
550000
)
{
/* p |= 0x00; */
}
else
if
(
tvco
<
700000
)
{
p
|=
0x08
;
}
else
if
(
tvco
<
1000000
)
{
p
|=
0x10
;
}
else
if
(
tvco
<
1150000
)
{
p
|=
0x18
;
}
else
{
p
=
0x4
0
;
p
|=
0x2
0
;
}
tvco
>>=
1
;
if
(
tvco
<
pi
->
vcomin
)
{
return
NO_MORE_MNP
;
}
*
fvco
=
tvco
;
}
p
&=
0x43
;
if
(
tvco
<
550000
)
{
/* p |= 0x00; */
}
else
if
(
tvco
<
700000
)
{
p
|=
0x08
;
}
else
if
(
tvco
<
1000000
)
{
p
|=
0x10
;
}
else
if
(
tvco
<
1150000
)
{
p
|=
0x18
;
m
=
9
;
}
else
{
p
|=
0x20
;
m
--
;
}
m
=
9
;
}
else
{
m
--
;
}
n
=
((
tvco
*
(
m
+
1
)
+
ACCESS_FBINFO
(
features
).
pll
.
ref_freq
)
/
(
ACCESS_FBINFO
(
features
).
pll
.
ref_freq
*
2
))
-
2
;
n
=
((
tvco
*
(
m
+
1
)
+
ACCESS_FBINFO
(
features
).
pll
.
ref_freq
)
/
(
ACCESS_FBINFO
(
features
).
pll
.
ref_freq
*
2
))
-
2
;
}
while
(
n
<
0x03
||
n
>
0x7A
);
return
(
m
<<
16
)
|
(
n
<<
8
)
|
p
;
}
...
...
@@ -219,7 +225,7 @@ static void updatehwstate_clk(struct matrox_hw_state* hw, unsigned int mnp, unsi
}
}
static
inline
void
g450_setpll_cond
(
WPMINFO
unsigned
int
mnp
,
unsigned
int
pll
)
{
void
matroxfb_
g450_setpll_cond
(
WPMINFO
unsigned
int
mnp
,
unsigned
int
pll
)
{
if
(
g450_cmppll
(
PMINFO
mnp
,
pll
))
{
g450_setpll
(
PMINFO
mnp
,
pll
);
}
...
...
@@ -385,10 +391,8 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
unsigned
int
vco
;
unsigned
int
delta
;
if
((
mnp
&
0xFF00
)
<
0x0300
||
(
mnp
&
0xFF00
)
>
0x7A00
)
{
continue
;
}
vco
=
g450_mnp2vco
(
PMINFO
mnp
);
#if 0
if (pll == M_VIDEO_PLL) {
unsigned int big, small;
...
...
@@ -406,6 +410,7 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
continue;
}
}
#endif
delta
=
pll_freq_delta
(
fout
,
g450_vco2f
(
mnp
,
vco
));
for
(
idx
=
mnpcount
;
idx
>
0
;
idx
--
)
{
/* == is important; due to nextpll algorithm we get
...
...
@@ -426,7 +431,7 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
}
/* VideoPLL and PixelPLL matched: do nothing... In all other cases we should get at least one frequency */
if
(
!
mnpcount
)
{
return
1
;
return
-
EBUSY
;
}
{
unsigned
long
flags
;
...
...
@@ -435,15 +440,15 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
matroxfb_DAC_lock_irqsave
(
flags
);
mnp
=
g450_checkcache
(
PMINFO
ci
,
mnparray
[
0
]);
if
(
mnp
!=
NO_MORE_MNP
)
{
g450_setpll_cond
(
PMINFO
mnp
,
pll
);
matroxfb_
g450_setpll_cond
(
PMINFO
mnp
,
pll
);
}
else
{
mnp
=
g450_findworkingpll
(
PMINFO
pll
,
mnparray
,
mnpcount
);
g450_addcache
(
ci
,
mnparray
[
0
],
mnp
);
}
updatehwstate_clk
(
&
ACCESS_FBINFO
(
hw
),
mnp
,
pll
);
matroxfb_DAC_unlock_irqrestore
(
flags
);
return
mnp
;
}
return
0
;
}
/* It must be greater than number of possible PLL values.
...
...
@@ -465,8 +470,10 @@ int matroxfb_g450_setclk(WPMINFO unsigned int fout, unsigned int pll) {
}
EXPORT_SYMBOL
(
matroxfb_g450_setclk
);
EXPORT_SYMBOL
(
g450_mnp2f
);
EXPORT_SYMBOL
(
matroxfb_g450_setpll_cond
);
MODULE_AUTHOR
(
"(c) 2001 Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_AUTHOR
(
"(c) 2001
-2002
Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_DESCRIPTION
(
"Matrox G450/G550 PLL driver"
);
MODULE_LICENSE
(
"GPL"
);
drivers/video/matrox/g450_pll.h
View file @
062dffea
...
...
@@ -4,5 +4,7 @@
#include "matroxfb_base.h"
int
matroxfb_g450_setclk
(
WPMINFO
unsigned
int
fout
,
unsigned
int
pll
);
unsigned
int
g450_mnp2f
(
CPMINFO
unsigned
int
mnp
);
void
matroxfb_g450_setpll_cond
(
WPMINFO
unsigned
int
mnp
,
unsigned
int
pll
);
#endif
/* __G450_PLL_H__ */
drivers/video/matrox/i2c-matroxfb.c
View file @
062dffea
...
...
@@ -2,9 +2,9 @@
*
* 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>
*
* Version: 1.
51 2001/01/19
* Version: 1.
64 2002/06/10
*
* See matroxfb_base.c for contributors.
*
...
...
@@ -30,6 +30,12 @@
/******************************************************/
struct
matroxfb_dh_maven_info
{
struct
i2c_bit_adapter
maven
;
struct
i2c_bit_adapter
ddc1
;
struct
i2c_bit_adapter
ddc2
;
};
static
int
matroxfb_read_gpio
(
struct
matrox_fb_info
*
minfo
)
{
unsigned
long
flags
;
int
v
;
...
...
@@ -40,7 +46,7 @@ static int matroxfb_read_gpio(struct matrox_fb_info* minfo) {
return
v
;
}
static
inline
void
matroxfb_set_gpio
(
struct
matrox_fb_info
*
minfo
,
int
mask
,
int
val
)
{
static
void
matroxfb_set_gpio
(
struct
matrox_fb_info
*
minfo
,
int
mask
,
int
val
)
{
unsigned
long
flags
;
int
v
;
...
...
@@ -53,7 +59,7 @@ static inline void matroxfb_set_gpio(struct matrox_fb_info* minfo, int mask, int
}
/* software I2C functions */
static
void
matroxfb_i2c_set
(
struct
matrox_fb_info
*
minfo
,
int
mask
,
int
state
)
{
static
inline
void
matroxfb_i2c_set
(
struct
matrox_fb_info
*
minfo
,
int
mask
,
int
state
)
{
if
(
state
)
state
=
0
;
else
...
...
@@ -61,68 +67,24 @@ static void matroxfb_i2c_set(struct matrox_fb_info* minfo, int mask, int state)
matroxfb_set_gpio
(
minfo
,
~
mask
,
state
);
}
static
void
matroxfb_maven_setsda
(
void
*
data
,
int
state
)
{
matroxfb_i2c_set
(
data
,
MAT_DATA
,
state
);
}
static
void
matroxfb_maven_setscl
(
void
*
data
,
int
state
)
{
matroxfb_i2c_set
(
data
,
MAT_CLK
,
state
);
}
static
int
matroxfb_maven_getsda
(
void
*
data
)
{
return
(
matroxfb_read_gpio
(
data
)
&
MAT_DATA
)
?
1
:
0
;
}
static
int
matroxfb_maven_getscl
(
void
*
data
)
{
return
(
matroxfb_read_gpio
(
data
)
&
MAT_CLK
)
?
1
:
0
;
}
static
void
matroxfb_ddc1_setsda
(
void
*
data
,
int
state
)
{
matroxfb_i2c_set
(
data
,
DDC1_DATA
,
state
);
}
static
void
matroxfb_ddc1_setscl
(
void
*
data
,
int
state
)
{
matroxfb_i2c_set
(
data
,
DDC1_CLK
,
state
);
}
static
int
matroxfb_ddc1_getsda
(
void
*
data
)
{
return
(
matroxfb_read_gpio
(
data
)
&
DDC1_DATA
)
?
1
:
0
;
}
static
int
matroxfb_ddc1_getscl
(
void
*
data
)
{
return
(
matroxfb_read_gpio
(
data
)
&
DDC1_CLK
)
?
1
:
0
;
}
static
void
matroxfb_ddc1b_setsda
(
void
*
data
,
int
state
)
{
matroxfb_i2c_set
(
data
,
DDC1B_DATA
,
state
);
}
static
void
matroxfb_ddc1b_setscl
(
void
*
data
,
int
state
)
{
matroxfb_i2c_set
(
data
,
DDC1B_CLK
,
state
);
}
static
int
matroxfb_ddc1b_getsda
(
void
*
data
)
{
return
(
matroxfb_read_gpio
(
data
)
&
DDC1B_DATA
)
?
1
:
0
;
}
static
int
matroxfb_ddc1b_getscl
(
void
*
data
)
{
return
(
matroxfb_read_gpio
(
data
)
&
DDC1B_CLK
)
?
1
:
0
;
static
void
matroxfb_gpio_setsda
(
void
*
data
,
int
state
)
{
struct
i2c_bit_adapter
*
b
=
data
;
matroxfb_i2c_set
(
b
->
minfo
,
b
->
mask
.
data
,
state
);
}
static
void
matroxfb_ddc2_setsda
(
void
*
data
,
int
state
)
{
matroxfb_i2c_set
(
data
,
DDC2_DATA
,
state
);
static
void
matroxfb_gpio_setscl
(
void
*
data
,
int
state
)
{
struct
i2c_bit_adapter
*
b
=
data
;
matroxfb_i2c_set
(
b
->
minfo
,
b
->
mask
.
clock
,
state
);
}
static
void
matroxfb_ddc2_setscl
(
void
*
data
,
int
state
)
{
matroxfb_i2c_set
(
data
,
DDC2_CLK
,
state
);
static
int
matroxfb_gpio_getsda
(
void
*
data
)
{
struct
i2c_bit_adapter
*
b
=
data
;
return
(
matroxfb_read_gpio
(
b
->
minfo
)
&
b
->
mask
.
data
)
?
1
:
0
;
}
static
int
matroxfb_ddc2_getsda
(
void
*
data
)
{
return
(
matroxfb_read_gpio
(
data
)
&
DDC2_DATA
)
?
1
:
0
;
}
static
int
matroxfb_ddc2_getscl
(
void
*
data
)
{
return
(
matroxfb_read_gpio
(
data
)
&
DDC2_CLK
)
?
1
:
0
;
static
int
matroxfb_gpio_getscl
(
void
*
data
)
{
struct
i2c_bit_adapter
*
b
=
data
;
return
(
matroxfb_read_gpio
(
b
->
minfo
)
&
b
->
mask
.
clock
)
?
1
:
0
;
}
static
void
matroxfb_dh_inc_use
(
struct
i2c_adapter
*
dummy
)
{
...
...
@@ -133,97 +95,36 @@ static void matroxfb_dh_dec_use(struct i2c_adapter* dummy) {
MOD_DEC_USE_COUNT
;
}
static
struct
i2c_adapter
matroxmaven_i2c_adapter_template
=
{
""
,
I2C_HW_B_G400
,
NULL
,
NULL
,
matroxfb_dh_inc_use
,
matroxfb_dh_dec_use
,
NULL
,
NULL
,
NULL
,
};
static
struct
i2c_algo_bit_data
matroxmaven_i2c_algo_template
=
{
NULL
,
matroxfb_maven_setsda
,
matroxfb_maven_setscl
,
matroxfb_maven_getsda
,
matroxfb_maven_getscl
,
10
,
10
,
100
,
};
static
struct
i2c_adapter
matrox_ddc1_adapter_template
=
{
""
,
I2C_HW_B_G400
,
/* DDC */
NULL
,
NULL
,
matroxfb_dh_inc_use
,
matroxfb_dh_dec_use
,
NULL
,
NULL
,
NULL
,
};
static
struct
i2c_algo_bit_data
matrox_ddc1_algo_template
=
static
struct
i2c_adapter
matrox_i2c_adapter_template
=
{
NULL
,
matroxfb_ddc1_setsda
,
matroxfb_ddc1_setscl
,
matroxfb_ddc1_getsda
,
matroxfb_ddc1_getscl
,
10
,
10
,
100
,
};
static
struct
i2c_algo_bit_data
matrox_ddc1b_algo_template
=
{
NULL
,
matroxfb_ddc1b_setsda
,
matroxfb_ddc1b_setscl
,
matroxfb_ddc1b_getsda
,
matroxfb_ddc1b_getscl
,
10
,
10
,
100
,
};
static
struct
i2c_adapter
matrox_ddc2_adapter_template
=
{
""
,
I2C_HW_B_G400
,
/* DDC */
NULL
,
NULL
,
matroxfb_dh_inc_use
,
/* should increment matroxfb_maven usage too, this DDC is coupled with maven_client */
matroxfb_dh_dec_use
,
/* should decrement matroxfb_maven usage too */
NULL
,
NULL
,
NULL
,
.
id
=
I2C_HW_B_G400
,
.
inc_use
=
matroxfb_dh_inc_use
,
.
dec_use
=
matroxfb_dh_dec_use
,
};
static
struct
i2c_algo_bit_data
matrox_
ddc2
_algo_template
=
static
struct
i2c_algo_bit_data
matrox_
i2c
_algo_template
=
{
NULL
,
matroxfb_
ddc2
_setsda
,
matroxfb_
ddc2
_setscl
,
matroxfb_
ddc2
_getsda
,
matroxfb_
ddc2
_getscl
,
matroxfb_
gpio
_setsda
,
matroxfb_
gpio
_setscl
,
matroxfb_
gpio
_getsda
,
matroxfb_
gpio
_getscl
,
10
,
10
,
100
,
};
static
int
i2c_bus_reg
(
struct
i2c_bit_adapter
*
b
,
struct
matrox_fb_info
*
minfo
)
{
static
int
i2c_bus_reg
(
struct
i2c_bit_adapter
*
b
,
struct
matrox_fb_info
*
minfo
,
unsigned
int
data
,
unsigned
int
clock
,
const
char
*
name
)
{
int
err
;
b
->
adapter
.
data
=
minfo
;
b
->
minfo
=
minfo
;
b
->
mask
.
data
=
data
;
b
->
mask
.
clock
=
clock
;
b
->
adapter
=
matrox_i2c_adapter_template
;
sprintf
(
b
->
adapter
.
name
,
name
,
GET_FB_IDX
(
minfo
->
fbcon
.
node
));
b
->
adapter
.
data
=
b
;
b
->
adapter
.
algo_data
=
&
b
->
bac
;
b
->
bac
.
data
=
minfo
;
b
->
bac
=
matrox_i2c_algo_template
;
b
->
bac
.
data
=
b
;
err
=
i2c_bit_add_bus
(
&
b
->
adapter
);
b
->
initialized
=
!
err
;
return
err
;
...
...
@@ -236,50 +137,14 @@ static void i2c_bit_bus_del(struct i2c_bit_adapter* b) {
}
}
static
inline
int
i2c_maven_init
(
struct
matroxfb_dh_maven_info
*
minfo2
)
{
struct
i2c_bit_adapter
*
b
=
&
minfo2
->
maven
;
b
->
adapter
=
matroxmaven_i2c_adapter_template
;
b
->
bac
=
matroxmaven_i2c_algo_template
;
sprintf
(
b
->
adapter
.
name
,
"MAVEN:fb%u on i2c-matroxfb"
,
GET_FB_IDX
(
minfo2
->
primary_dev
->
fbcon
.
node
));
return
i2c_bus_reg
(
b
,
minfo2
->
primary_dev
);
}
static
inline
void
i2c_maven_done
(
struct
matroxfb_dh_maven_info
*
minfo2
)
{
i2c_bit_bus_del
(
&
minfo2
->
maven
);
}
static
inline
int
i2c_ddc1_init
(
struct
matroxfb_dh_maven_info
*
minfo2
)
{
struct
i2c_bit_adapter
*
b
=
&
minfo2
->
ddc1
;
b
->
adapter
=
matrox_ddc1_adapter_template
;
b
->
bac
=
matrox_ddc1_algo_template
;
sprintf
(
b
->
adapter
.
name
,
"DDC:fb%u #0 on i2c-matroxfb"
,
GET_FB_IDX
(
minfo2
->
primary_dev
->
fbcon
.
node
));
return
i2c_bus_reg
(
b
,
minfo2
->
primary_dev
);
}
static
inline
int
i2c_ddc1b_init
(
struct
matroxfb_dh_maven_info
*
minfo2
)
{
struct
i2c_bit_adapter
*
b
=
&
minfo2
->
ddc1
;
b
->
adapter
=
matrox_ddc1_adapter_template
;
b
->
bac
=
matrox_ddc1b_algo_template
;
sprintf
(
b
->
adapter
.
name
,
"DDC:fb%u #0 on i2c-matroxfb"
,
GET_FB_IDX
(
minfo2
->
primary_dev
->
fbcon
.
node
));
return
i2c_bus_reg
(
b
,
minfo2
->
primary_dev
);
}
static
inline
void
i2c_ddc1_done
(
struct
matroxfb_dh_maven_info
*
minfo2
)
{
i2c_bit_bus_del
(
&
minfo2
->
ddc1
);
}
static
inline
int
i2c_ddc2_init
(
struct
matroxfb_dh_maven_info
*
minfo2
)
{
struct
i2c_bit_adapter
*
b
=
&
minfo2
->
ddc2
;
b
->
adapter
=
matrox_ddc2_adapter_template
;
b
->
bac
=
matrox_ddc2_algo_template
;
sprintf
(
b
->
adapter
.
name
,
"DDC:fb%u #1 on i2c-matroxfb"
,
GET_FB_IDX
(
minfo2
->
primary_dev
->
fbcon
.
node
));
return
i2c_bus_reg
(
b
,
minfo2
->
primary_dev
);
}
static
inline
void
i2c_ddc2_done
(
struct
matroxfb_dh_maven_info
*
minfo2
)
{
i2c_bit_bus_del
(
&
minfo2
->
ddc2
);
}
...
...
@@ -299,24 +164,26 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
matroxfb_DAC_unlock_irqrestore
(
flags
);
memset
(
m2info
,
0
,
sizeof
(
*
m2info
));
m2info
->
maven
.
minfo
=
m2info
;
m2info
->
ddc1
.
minfo
=
m2info
;
m2info
->
ddc2
.
minfo
=
m2info
;
m2info
->
primary_dev
=
minfo
;
if
(
ACCESS_FBINFO
(
devflags
.
accelerator
)
==
FB_ACCEL_MATROX_MGA2064W
||
ACCESS_FBINFO
(
devflags
.
accelerator
)
==
FB_ACCEL_MATROX_MGA2164W
||
ACCESS_FBINFO
(
devflags
.
accelerator
)
==
FB_ACCEL_MATROX_MGA2164W_AGP
)
err
=
i2c_ddc1b_init
(
m2info
);
else
err
=
i2c_ddc1_init
(
m2info
);
switch
(
ACCESS_FBINFO
(
chip
))
{
case
MGA_2064
:
case
MGA_2164
:
err
=
i2c_bus_reg
(
&
m2info
->
ddc1
,
minfo
,
DDC1B_DATA
,
DDC1B_CLK
,
"DDC:fb%u #0 on i2c-matroxfb"
);
break
;
default:
err
=
i2c_bus_reg
(
&
m2info
->
ddc1
,
minfo
,
DDC1_DATA
,
DDC1_CLK
,
"DDC:fb%u #0 on i2c-matroxfb"
);
break
;
}
if
(
err
)
goto
fail_ddc1
;
if
(
ACCESS_FBINFO
(
devflags
.
maven_capable
))
{
err
=
i2c_ddc2_init
(
m2info
);
if
(
err
)
if
(
ACCESS_FBINFO
(
devflags
.
dualhead
))
{
err
=
i2c_bus_reg
(
&
m2info
->
ddc2
,
minfo
,
DDC2_DATA
,
DDC2_CLK
,
"DDC:fb%u #1 on i2c-matroxfb"
);
if
(
err
==
-
ENODEV
)
{
printk
(
KERN_INFO
"i2c-matroxfb: VGA->TV plug detected, DDC unavailable.
\n
"
);
}
else
if
(
err
)
printk
(
KERN_INFO
"i2c-matroxfb: Could not register secondary output i2c bus. Continuing anyway.
\n
"
);
err
=
i2c_maven_init
(
m2info
);
/* Register maven bus even on G450/G550 */
err
=
i2c_bus_reg
(
&
m2info
->
maven
,
minfo
,
MAT_DATA
,
MAT_CLK
,
"MAVEN:fb%u on i2c-matroxfb"
);
if
(
err
)
printk
(
KERN_INFO
"i2c-matroxfb: Could not register Maven i2c bus. Continuing anyway.
\n
"
);
}
...
...
@@ -337,10 +204,10 @@ static void i2c_matroxfb_remove(struct matrox_fb_info* minfo, void* data) {
}
static
struct
matroxfb_driver
i2c_matroxfb
=
{
LIST_HEAD_INIT
(
i2c_matroxfb
.
node
),
"i2c-matroxfb"
,
i2c_matroxfb_probe
,
i2c_matroxfb_remove
,
.
node
=
LIST_HEAD_INIT
(
i2c_matroxfb
.
node
),
.
name
=
"i2c-matroxfb"
,
.
probe
=
i2c_matroxfb_probe
,
.
remove
=
i2c_matroxfb_remove
,
};
static
int
__init
i2c_matroxfb_init
(
void
)
{
...
...
@@ -355,7 +222,7 @@ static void __exit i2c_matroxfb_exit(void) {
matroxfb_unregister_driver
(
&
i2c_matroxfb
);
}
MODULE_AUTHOR
(
"(c) 1999-200
1
Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_AUTHOR
(
"(c) 1999-200
2
Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_DESCRIPTION
(
"Support module providing I2C buses present on Matrox videocards"
);
module_init
(
i2c_matroxfb_init
);
...
...
drivers/video/matrox/matroxfb_DAC1064.c
View file @
062dffea
...
...
@@ -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
5 2002/08/14
*
* See matroxfb_base.c for contributors.
*
...
...
@@ -150,7 +150,7 @@ static int matroxfb_DAC1064_setfont(struct display* p, int width, int height) {
return
0
;
}
static
int
DAC1064_selhwcursor
(
WPMINFO
struct
display
*
p
)
{
static
int
DAC1064_selhwcursor
(
WPMINFO
2
)
{
ACCESS_FBINFO
(
dispsw
.
cursor
)
=
matroxfb_DAC1064_cursor
;
ACCESS_FBINFO
(
dispsw
.
set_font
)
=
matroxfb_DAC1064_setfont
;
return
0
;
...
...
@@ -161,37 +161,20 @@ static void DAC1064_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsi
unsigned
int
p
;
DBG
(
"DAC1064_calcclock"
)
/* only for devices older than G450 */
fvco
=
PLL_calcclock
(
PMINFO
freq
,
fmax
,
in
,
feed
,
&
p
);
if
(
ACCESS_FBINFO
(
devflags
.
g450dac
))
{
if
(
fvco
<=
300000
)
/* 276-324 */
;
else
if
(
fvco
<=
400000
)
/* 378-438 */
p
|=
0x08
;
else
if
(
fvco
<=
550000
)
/* 540-567 */
p
|=
0x10
;
else
if
(
fvco
<=
690000
)
/* 675-695 */
p
|=
0x18
;
else
if
(
fvco
<=
800000
)
/* 776-803 */
p
|=
0x20
;
else
if
(
fvco
<=
891000
)
/* 891-891 */
p
|=
0x28
;
else
if
(
fvco
<=
940000
)
/* 931-945 */
p
|=
0x30
;
else
/* <959 */
p
|=
0x38
;
}
else
{
p
=
(
1
<<
p
)
-
1
;
if
(
fvco
<=
100000
)
;
else
if
(
fvco
<=
140000
)
p
|=
0x08
;
else
if
(
fvco
<=
180000
)
p
|=
0x10
;
else
p
|=
0x18
;
}
p
=
(
1
<<
p
)
-
1
;
if
(
fvco
<=
100000
)
;
else
if
(
fvco
<=
140000
)
p
|=
0x08
;
else
if
(
fvco
<=
180000
)
p
|=
0x10
;
else
p
|=
0x18
;
*
post
=
p
;
}
...
...
@@ -293,31 +276,164 @@ static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) {
hw
->
MXoptionReg
=
mx
;
}
static
void
g450_set_plls
(
WPMINFO2
)
{
u_int32_t
c2_ctl
;
unsigned
int
pxc
;
struct
matrox_hw_state
*
hw
=
&
ACCESS_FBINFO
(
hw
);
int
pixelmnp
;
int
videomnp
;
c2_ctl
=
hw
->
crtc2
.
ctl
&
~
0x4007
;
/* Clear PLL + enable for CRTC2 */
c2_ctl
|=
0x0001
;
/* Enable CRTC2 */
hw
->
DACreg
[
POS1064_XPWRCTRL
]
&=
~
0x02
;
/* Stop VIDEO PLL */
pixelmnp
=
ACCESS_FBINFO
(
crtc1
).
mnp
;
videomnp
=
ACCESS_FBINFO
(
crtc2
).
mnp
;
if
(
videomnp
<
0
)
{
c2_ctl
&=
~
0x0001
;
/* Disable CRTC2 */
hw
->
DACreg
[
POS1064_XPWRCTRL
]
&=
~
0x10
;
/* Powerdown CRTC2 */
}
else
if
(
ACCESS_FBINFO
(
crtc2
).
pixclock
==
ACCESS_FBINFO
(
features
).
pll
.
ref_freq
)
{
c2_ctl
|=
0x4002
;
/* Use reference directly */
}
else
if
(
videomnp
==
pixelmnp
)
{
c2_ctl
|=
0x0004
;
/* Use pixel PLL */
}
else
{
if
(
0
==
((
videomnp
^
pixelmnp
)
&
0xFFFFFF00
))
{
/* PIXEL and VIDEO PLL must not use same frequency. We modify N
of PIXEL PLL in such case because of VIDEO PLL may be source
of TVO clocks, and chroma subcarrier is derived from its
pixel clocks */
pixelmnp
+=
0x000100
;
}
c2_ctl
|=
0x0006
;
/* Use video PLL */
hw
->
DACreg
[
POS1064_XPWRCTRL
]
|=
0x02
;
outDAC1064
(
PMINFO
M1064_XPWRCTRL
,
hw
->
DACreg
[
POS1064_XPWRCTRL
]);
matroxfb_g450_setpll_cond
(
PMINFO
videomnp
,
M_VIDEO_PLL
);
}
hw
->
DACreg
[
POS1064_XPIXCLKCTRL
]
&=
~
M1064_XPIXCLKCTRL_PLL_UP
;
if
(
pixelmnp
>=
0
)
{
hw
->
DACreg
[
POS1064_XPIXCLKCTRL
]
|=
M1064_XPIXCLKCTRL_PLL_UP
;
outDAC1064
(
PMINFO
M1064_XPIXCLKCTRL
,
hw
->
DACreg
[
POS1064_XPIXCLKCTRL
]);
matroxfb_g450_setpll_cond
(
PMINFO
pixelmnp
,
M_PIXEL_PLL_C
);
}
if
(
c2_ctl
!=
hw
->
crtc2
.
ctl
)
{
hw
->
crtc2
.
ctl
=
c2_ctl
;
mga_outl
(
0x3C10
,
c2_ctl
);
}
pxc
=
ACCESS_FBINFO
(
crtc1
).
pixclock
;
if
(
pxc
==
0
||
ACCESS_FBINFO
(
outputs
[
2
]).
src
==
MATROXFB_SRC_CRTC2
)
{
pxc
=
ACCESS_FBINFO
(
crtc2
).
pixclock
;
}
if
(
ACCESS_FBINFO
(
chip
)
==
MGA_G550
)
{
if
(
pxc
<
45000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x00
;
/* 0-50 */
}
else
if
(
pxc
<
55000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x08
;
/* 34-62 */
}
else
if
(
pxc
<
70000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x10
;
/* 42-78 */
}
else
if
(
pxc
<
85000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x18
;
/* 62-92 */
}
else
if
(
pxc
<
100000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x20
;
/* 74-108 */
}
else
if
(
pxc
<
115000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x28
;
/* 94-122 */
}
else
if
(
pxc
<
125000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x30
;
/* 108-132 */
}
else
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x38
;
/* 120-168 */
}
}
else
{
/* G450 */
if
(
pxc
<
45000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x00
;
/* 0-54 */
}
else
if
(
pxc
<
65000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x08
;
/* 38-70 */
}
else
if
(
pxc
<
85000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x10
;
/* 56-96 */
}
else
if
(
pxc
<
105000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x18
;
/* 80-114 */
}
else
if
(
pxc
<
135000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x20
;
/* 102-144 */
}
else
if
(
pxc
<
160000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x28
;
/* 132-166 */
}
else
if
(
pxc
<
175000
)
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x30
;
/* 154-182 */
}
else
{
hw
->
DACreg
[
POS1064_XPANMODE
]
=
0x38
;
/* 170-204 */
}
}
}
void
DAC1064_global_init
(
WPMINFO2
)
{
struct
matrox_hw_state
*
hw
=
&
ACCESS_FBINFO
(
hw
);
hw
->
DACreg
[
POS1064_XMISCCTRL
]
&=
M1064_XMISCCTRL_DAC_WIDTHMASK
;
hw
->
DACreg
[
POS1064_XMISCCTRL
]
|=
M1064_XMISCCTRL_LUT_EN
;
hw
->
DACreg
[
POS1064_XPIXCLKCTRL
]
=
M1064_XPIXCLKCTRL_PLL_UP
|
M1064_XPIXCLKCTRL_EN
|
M1064_XPIXCLKCTRL_SRC_PLL
;
hw
->
DACreg
[
POS1064_XOUTPUTCONN
]
=
0x01
;
/* output #1 enabled */
if
(
ACCESS_FBINFO
(
output
.
ph
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
{
if
(
ACCESS_FBINFO
(
devflags
.
g450dac
))
{
hw
->
DACreg
[
POS1064_XPIXCLKCTRL
]
=
M1064_XPIXCLKCTRL_PLL_UP
|
M1064_XPIXCLKCTRL_EN
|
M1064_XPIXCLKCTRL_SRC_PLL2
;
hw
->
DACreg
[
POS1064_XOUTPUTCONN
]
=
0x05
;
/* output #1 enabled; CRTC1 connected to output #2 */
}
else
{
if
(
ACCESS_FBINFO
(
devflags
.
g450dac
))
{
hw
->
DACreg
[
POS1064_XPWRCTRL
]
=
0x1F
;
/* powerup everything */
hw
->
DACreg
[
POS1064_XOUTPUTCONN
]
=
0x00
;
/* disable outputs */
hw
->
DACreg
[
POS1064_XMISCCTRL
]
|=
M1064_XMISCCTRL_DAC_EN
;
switch
(
ACCESS_FBINFO
(
outputs
[
0
]).
src
)
{
case
MATROXFB_SRC_CRTC1
:
case
MATROXFB_SRC_CRTC2
:
hw
->
DACreg
[
POS1064_XOUTPUTCONN
]
|=
0x01
;
/* enable output; CRTC1/2 selection is in CRTC2 ctl */
break
;
case
MATROXFB_SRC_NONE
:
hw
->
DACreg
[
POS1064_XMISCCTRL
]
&=
~
M1064_XMISCCTRL_DAC_EN
;
break
;
}
switch
(
ACCESS_FBINFO
(
outputs
[
1
]).
src
)
{
case
MATROXFB_SRC_CRTC1
:
hw
->
DACreg
[
POS1064_XOUTPUTCONN
]
|=
0x04
;
break
;
case
MATROXFB_SRC_CRTC2
:
if
(
ACCESS_FBINFO
(
outputs
[
1
]).
mode
==
MATROXFB_OUTPUT_MODE_MONITOR
)
{
hw
->
DACreg
[
POS1064_XOUTPUTCONN
]
|=
0x08
;
}
else
{
hw
->
DACreg
[
POS1064_XOUTPUTCONN
]
|=
0x0C
;
}
break
;
case
MATROXFB_SRC_NONE
:
hw
->
DACreg
[
POS1064_XPWRCTRL
]
&=
~
0x01
;
/* Poweroff DAC2 */
break
;
}
switch
(
ACCESS_FBINFO
(
outputs
[
2
]).
src
)
{
case
MATROXFB_SRC_CRTC1
:
hw
->
DACreg
[
POS1064_XOUTPUTCONN
]
|=
0x20
;
break
;
case
MATROXFB_SRC_CRTC2
:
hw
->
DACreg
[
POS1064_XOUTPUTCONN
]
|=
0x40
;
break
;
case
MATROXFB_SRC_NONE
:
#if 0
/* HELP! If we boot without DFP connected to DVI, we can
poweroff TMDS. But if we boot with DFP connected,
TMDS generated clocks are used instead of ALL pixclocks
available... If someone knows which register
handles it, please reveal this secret to me... */
hw->DACreg[POS1064_XPWRCTRL] &= ~0x04; /* Poweroff TMDS */
#endif
break
;
}
/* Now set timming related variables... */
g450_set_plls
(
PMINFO2
);
}
else
{
if
(
ACCESS_FBINFO
(
outputs
[
1
]).
src
==
MATROXFB_SRC_CRTC1
)
{
hw
->
DACreg
[
POS1064_XPIXCLKCTRL
]
=
M1064_XPIXCLKCTRL_PLL_UP
|
M1064_XPIXCLKCTRL_EN
|
M1064_XPIXCLKCTRL_SRC_EXT
;
hw
->
DACreg
[
POS1064_XMISCCTRL
]
|=
GX00_XMISCCTRL_MFC_MAFC
|
G400_XMISCCTRL_VDO_MAFC12
;
}
}
else
if
(
ACCESS_FBINFO
(
output
.
sh
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
{
hw
->
DACreg
[
POS1064_XMISCCTRL
]
|=
GX00_XMISCCTRL_MFC_MAFC
|
G400_XMISCCTRL_VDO_C2_MAFC12
;
hw
->
DACreg
[
POS1064_XOUTPUTCONN
]
=
0x09
;
/* output #1 enabled; CRTC2 connected to output #2 */
}
else
if
(
ACCESS_FBINFO
(
output
.
ph
)
&
MATROXFB_OUTPUT_CONN_DFP
)
hw
->
DACreg
[
POS1064_XMISCCTRL
]
|=
GX00_XMISCCTRL_MFC_PANELLINK
|
G400_XMISCCTRL_VDO_MAFC12
;
else
hw
->
DACreg
[
POS1064_XMISCCTRL
]
|=
GX00_XMISCCTRL_MFC_DIS
;
}
else
if
(
ACCESS_FBINFO
(
outputs
[
1
]).
src
==
MATROXFB_SRC_CRTC2
)
{
hw
->
DACreg
[
POS1064_XMISCCTRL
]
|=
GX00_XMISCCTRL_MFC_MAFC
|
G400_XMISCCTRL_VDO_C2_MAFC12
;
}
else
if
(
ACCESS_FBINFO
(
outputs
[
2
]).
src
==
MATROXFB_SRC_CRTC1
)
hw
->
DACreg
[
POS1064_XMISCCTRL
]
|=
GX00_XMISCCTRL_MFC_PANELLINK
|
G400_XMISCCTRL_VDO_MAFC12
;
else
hw
->
DACreg
[
POS1064_XMISCCTRL
]
|=
GX00_XMISCCTRL_MFC_DIS
;
if
((
ACCESS_FBINFO
(
output
.
ph
)
|
ACCESS_FBINFO
(
output
.
sh
))
&
MATROXFB_OUTPUT_CONN_PRIMARY
)
hw
->
DACreg
[
POS1064_XMISCCTRL
]
|=
M1064_XMISCCTRL_DAC_EN
;
if
(
ACCESS_FBINFO
(
outputs
[
0
]).
src
!=
MATROXFB_SRC_NONE
)
hw
->
DACreg
[
POS1064_XMISCCTRL
]
|=
M1064_XMISCCTRL_DAC_EN
;
}
}
void
DAC1064_global_restore
(
WPMINFO2
)
{
...
...
@@ -329,31 +445,32 @@ void DAC1064_global_restore(WPMINFO2) {
outDAC1064
(
PMINFO
0x20
,
0x04
);
outDAC1064
(
PMINFO
0x1F
,
ACCESS_FBINFO
(
devflags
.
dfp_type
));
if
(
ACCESS_FBINFO
(
devflags
.
g450dac
))
{
outDAC1064
(
PMINFO
M1064_XSYNCCTRL
,
0xCC
);
/* only matrox know... */
outDAC1064
(
PMINFO
M1064_XPWRCTRL
,
0x1F
);
/* powerup everything */
outDAC1064
(
PMINFO
M1064_XSYNCCTRL
,
0xCC
);
outDAC1064
(
PMINFO
M1064_XPWRCTRL
,
hw
->
DACreg
[
POS1064_XPWRCTRL
]);
outDAC1064
(
PMINFO
M1064_XPANMODE
,
hw
->
DACreg
[
POS1064_XPANMODE
]);
outDAC1064
(
PMINFO
M1064_XOUTPUTCONN
,
hw
->
DACreg
[
POS1064_XOUTPUTCONN
]);
}
}
}
static
int
DAC1064_init_1
(
WPMINFO
struct
my_timming
*
m
,
struct
display
*
p
)
{
static
int
DAC1064_init_1
(
WPMINFO
struct
my_timming
*
m
)
{
struct
matrox_hw_state
*
hw
=
&
ACCESS_FBINFO
(
hw
);
DBG
(
"DAC1064_init_1"
)
memcpy
(
hw
->
DACreg
,
MGA1064_DAC
,
sizeof
(
MGA1064_DAC_regs
));
if
(
p
->
type
==
FB_TYPE_TEXT
)
{
if
(
ACCESS_FBINFO
(
fbcon
).
fix
.
type
==
FB_TYPE_TEXT
)
{
hw
->
DACreg
[
POS1064_XMISCCTRL
]
=
M1064_XMISCCTRL_DAC_6BIT
;
hw
->
DACreg
[
POS1064_XMULCTRL
]
=
M1064_XMULCTRL_DEPTH_8BPP
|
M1064_XMULCTRL_GRAPHICS_PALETIZED
;
}
else
{
switch
(
p
->
var
.
bits_per_pixel
)
{
switch
(
ACCESS_FBINFO
(
fbcon
).
var
.
bits_per_pixel
)
{
/* case 4: not supported by MGA1064 DAC */
case
8
:
hw
->
DACreg
[
POS1064_XMULCTRL
]
=
M1064_XMULCTRL_DEPTH_8BPP
|
M1064_XMULCTRL_GRAPHICS_PALETIZED
;
break
;
case
16
:
if
(
p
->
var
.
green
.
length
==
5
)
if
(
ACCESS_FBINFO
(
fbcon
).
var
.
green
.
length
==
5
)
hw
->
DACreg
[
POS1064_XMULCTRL
]
=
M1064_XMULCTRL_DEPTH_15BPP_1BPP
|
M1064_XMULCTRL_GRAPHICS_PALETIZED
;
else
hw
->
DACreg
[
POS1064_XMULCTRL
]
=
M1064_XMULCTRL_DEPTH_16BPP
|
M1064_XMULCTRL_GRAPHICS_PALETIZED
;
...
...
@@ -368,22 +485,22 @@ static int DAC1064_init_1(WPMINFO struct my_timming* m, struct display *p) {
return
1
;
/* unsupported depth */
}
}
DAC1064_global_init
(
PMINFO2
);
hw
->
DACreg
[
POS1064_XVREFCTRL
]
=
ACCESS_FBINFO
(
features
.
DAC1064
.
xvrefctrl
);
hw
->
DACreg
[
POS1064_XGENCTRL
]
&=
~
M1064_XGENCTRL_SYNC_ON_GREEN_MASK
;
hw
->
DACreg
[
POS1064_XGENCTRL
]
|=
(
m
->
sync
&
FB_SYNC_ON_GREEN
)
?
M1064_XGENCTRL_SYNC_ON_GREEN
:
M1064_XGENCTRL_NO_SYNC_ON_GREEN
;
hw
->
DACreg
[
POS1064_XCURADDL
]
=
ACCESS_FBINFO
(
features
.
DAC1064
.
cursorimage
)
>>
10
;
hw
->
DACreg
[
POS1064_XCURADDH
]
=
ACCESS_FBINFO
(
features
.
DAC1064
.
cursorimage
)
>>
18
;
DAC1064_global_init
(
PMINFO2
);
return
0
;
}
static
int
DAC1064_init_2
(
WPMINFO
struct
my_timming
*
m
,
struct
display
*
p
)
{
static
int
DAC1064_init_2
(
WPMINFO
struct
my_timming
*
m
)
{
struct
matrox_hw_state
*
hw
=
&
ACCESS_FBINFO
(
hw
);
DBG
(
"DAC1064_init_2"
)
if
(
p
->
var
.
bits_per_pixel
>
16
)
{
/* 256 entries */
if
(
ACCESS_FBINFO
(
fbcon
).
var
.
bits_per_pixel
>
16
)
{
/* 256 entries */
int
i
;
for
(
i
=
0
;
i
<
256
;
i
++
)
{
...
...
@@ -391,8 +508,8 @@ static int DAC1064_init_2(WPMINFO struct my_timming* m, struct display* p) {
hw
->
DACpal
[
i
*
3
+
1
]
=
i
;
hw
->
DACpal
[
i
*
3
+
2
]
=
i
;
}
}
else
if
(
p
->
var
.
bits_per_pixel
>
8
)
{
if
(
p
->
var
.
green
.
length
==
5
)
{
/* 0..31, 128..159 */
}
else
if
(
ACCESS_FBINFO
(
fbcon
).
var
.
bits_per_pixel
>
8
)
{
if
(
ACCESS_FBINFO
(
fbcon
).
var
.
green
.
length
==
5
)
{
/* 0..31, 128..159 */
int
i
;
for
(
i
=
0
;
i
<
32
;
i
++
)
{
...
...
@@ -471,13 +588,8 @@ static void DAC1064_restore_2(WPMINFO struct display* p) {
#endif
}
static
int
m1064_compute
(
void
*
outdev
,
struct
my_timming
*
m
)
{
#define minfo ((struct matrox_fb_info*)outdev)
#ifdef CONFIG_FB_MATROX_G450
if
(
ACCESS_FBINFO
(
devflags
.
g450dac
))
{
matroxfb_g450_setclk
(
PMINFO
m
->
pixclock
,
M_PIXEL_PLL_C
);
}
else
#endif
static
int
m1064_compute
(
void
*
out
,
struct
my_timming
*
m
)
{
#define minfo ((struct matrox_fb_info*)out)
{
int
i
;
int
tmout
;
...
...
@@ -504,37 +616,26 @@ static int m1064_compute(void* outdev, struct my_timming* m) {
return
0
;
}
static
int
m1064_program
(
void
*
outdev
)
{
/* nothing, hardware is set in m1064_compute */
return
0
;
}
static
int
m1064_start
(
void
*
outdev
)
{
/* nothing */
return
0
;
}
static
void
m1064_incuse
(
void
*
outdev
)
{
/* nothing yet; MODULE_INC_USE in future... */
}
static
void
m1064_decuse
(
void
*
outdev
)
{
/* nothing yet; MODULE_DEC_USE in future... */
}
static
struct
matrox_altout
m1064
=
{
.
name
=
"Primary output"
,
.
compute
=
m1064_compute
,
};
static
int
m1064_setmode
(
void
*
outdev
,
u_int32_t
mode
)
{
if
(
mode
!=
MATROXFB_OUTPUT_MODE_MONITOR
)
return
-
EINVAL
;
static
int
g450_compute
(
void
*
out
,
struct
my_timming
*
m
)
{
#define minfo ((struct matrox_fb_info*)out)
if
(
m
->
mnp
<
0
)
{
m
->
mnp
=
matroxfb_g450_setclk
(
PMINFO
m
->
pixclock
,
(
m
->
crtc
==
MATROXFB_SRC_CRTC1
)
?
M_PIXEL_PLL_C
:
M_VIDEO_PLL
);
if
(
m
->
mnp
>=
0
)
{
m
->
pixclock
=
g450_mnp2f
(
PMINFO
m
->
mnp
);
}
}
#undef minfo
return
0
;
}
static
struct
matrox_altout
m1064
=
{
m1064_compute
,
m1064_program
,
m1064_start
,
m1064_incuse
,
m1064_decuse
,
m1064_setmode
static
struct
matrox_altout
g450out
=
{
.
name
=
"Primary output"
,
.
compute
=
g450_compute
,
};
#endif
/* NEED_DAC1064 */
...
...
@@ -545,7 +646,7 @@ static int MGA1064_init(WPMINFO struct my_timming* m, struct display* p) {
DBG
(
"MGA1064_init"
)
if
(
DAC1064_init_1
(
PMINFO
m
,
p
))
return
1
;
if
(
DAC1064_init_1
(
PMINFO
m
))
return
1
;
if
(
matroxfb_vgaHWinit
(
PMINFO
m
,
p
))
return
1
;
hw
->
MiscOutReg
=
0xCB
;
...
...
@@ -556,7 +657,7 @@ static int MGA1064_init(WPMINFO struct my_timming* m, struct display* p) {
if
(
m
->
sync
&
FB_SYNC_COMP_HIGH_ACT
)
/* should be only FB_SYNC_COMP */
hw
->
CRTCEXT
[
3
]
|=
0x40
;
if
(
DAC1064_init_2
(
PMINFO
m
,
p
))
return
1
;
if
(
DAC1064_init_2
(
PMINFO
m
))
return
1
;
return
0
;
}
#endif
...
...
@@ -567,7 +668,7 @@ static int MGAG100_init(WPMINFO struct my_timming* m, struct display* p) {
DBG
(
"MGAG100_init"
)
if
(
DAC1064_init_1
(
PMINFO
m
,
p
))
return
1
;
if
(
DAC1064_init_1
(
PMINFO
m
))
return
1
;
hw
->
MXoptionReg
&=
~
0x2000
;
if
(
matroxfb_vgaHWinit
(
PMINFO
m
,
p
))
return
1
;
...
...
@@ -579,7 +680,7 @@ static int MGAG100_init(WPMINFO struct my_timming* m, struct display* p) {
if
(
m
->
sync
&
FB_SYNC_COMP_HIGH_ACT
)
/* should be only FB_SYNC_COMP */
hw
->
CRTCEXT
[
3
]
|=
0x40
;
if
(
DAC1064_init_2
(
PMINFO
m
,
p
))
return
1
;
if
(
DAC1064_init_2
(
PMINFO
m
))
return
1
;
return
0
;
}
#endif
/* G100 */
...
...
@@ -680,7 +781,10 @@ static int MGA1064_preinit(WPMINFO2) {
ACCESS_FBINFO
(
features
.
accel
.
has_cacheflush
)
=
1
;
ACCESS_FBINFO
(
cursor
.
timer
.
function
)
=
matroxfb_DAC1064_flashcursor
;
ACCESS_FBINFO
(
primout
)
=
&
m1064
;
ACCESS_FBINFO
(
outputs
[
0
]).
output
=
&
m1064
;
ACCESS_FBINFO
(
outputs
[
0
]).
src
=
MATROXFB_SRC_CRTC1
;
ACCESS_FBINFO
(
outputs
[
0
]).
data
=
MINFO
;
ACCESS_FBINFO
(
outputs
[
0
]).
mode
=
MATROXFB_OUTPUT_MODE_MONITOR
;
if
(
ACCESS_FBINFO
(
devflags
.
noinit
))
return
0
;
/* do not modify settings */
...
...
@@ -726,8 +830,13 @@ static void g450_mclk_init(WPMINFO2) {
((
ACCESS_FBINFO
(
values
).
reg
.
opt3
&
0x300000
)
==
0x300000
))
{
matroxfb_g450_setclk
(
PMINFO
ACCESS_FBINFO
(
values
.
pll
.
video
),
M_VIDEO_PLL
);
}
else
{
/* slow down video clocks... */
matroxfb_g450_setclk
(
PMINFO
0
,
M_VIDEO_PLL
);
unsigned
long
flags
;
unsigned
int
pwr
;
matroxfb_DAC_lock_irqsave
(
flags
);
pwr
=
inDAC1064
(
PMINFO
M1064_XPWRCTRL
)
&
~
0x02
;
outDAC1064
(
PMINFO
M1064_XPWRCTRL
,
pwr
);
matroxfb_DAC_unlock_irqrestore
(
flags
);
}
matroxfb_g450_setclk
(
PMINFO
ACCESS_FBINFO
(
values
.
pll
.
system
),
M_SYSTEM_PLL
);
...
...
@@ -864,7 +973,14 @@ static int MGAG100_preinit(WPMINFO2) {
ACCESS_FBINFO
(
capable
.
plnwt
)
=
ACCESS_FBINFO
(
devflags
.
accelerator
)
==
FB_ACCEL_MATROX_MGAG100
?
ACCESS_FBINFO
(
devflags
.
sgram
)
:
1
;
ACCESS_FBINFO
(
primout
)
=
&
m1064
;
if
(
ACCESS_FBINFO
(
devflags
.
g450dac
))
{
ACCESS_FBINFO
(
outputs
[
0
]).
output
=
&
g450out
;
}
else
{
ACCESS_FBINFO
(
outputs
[
0
]).
output
=
&
m1064
;
}
ACCESS_FBINFO
(
outputs
[
0
]).
src
=
MATROXFB_SRC_CRTC1
;
ACCESS_FBINFO
(
outputs
[
0
]).
data
=
MINFO
;
ACCESS_FBINFO
(
outputs
[
0
]).
mode
=
MATROXFB_OUTPUT_MODE_MONITOR
;
if
(
ACCESS_FBINFO
(
devflags
.
g450dac
))
{
/* we must do this always, BIOS does not do it for us
...
...
@@ -895,8 +1011,7 @@ static int MGAG100_preinit(WPMINFO2) {
hw
->
MXoptionReg
|=
0x1080
;
pci_write_config_dword
(
ACCESS_FBINFO
(
pcidev
),
PCI_OPTION_REG
,
hw
->
MXoptionReg
);
mga_outl
(
M_CTLWTST
,
0x00000300
);
/* mga_outl(M_CTLWTST, 0x03258A31); */
mga_outl
(
M_CTLWTST
,
ACCESS_FBINFO
(
values
).
reg
.
mctlwtst
);
udelay
(
100
);
mga_outb
(
0x1C05
,
0x00
);
mga_outb
(
0x1C05
,
0x80
);
...
...
@@ -947,17 +1062,18 @@ static int MGAG100_preinit(WPMINFO2) {
pci_write_config_dword
(
ACCESS_FBINFO
(
pcidev
),
PCI_OPTION2_REG
,
reg50
);
if
(
ACCESS_FBINFO
(
devflags
.
memtype
)
==
-
1
)
ACCESS_FBINFO
(
devflags
.
memtype
)
=
0
;
hw
->
MXoptionReg
|=
(
ACCESS_FBINFO
(
devflags
.
memtype
)
&
7
)
<<
10
;
hw
->
MXoptionReg
|=
ACCESS_FBINFO
(
values
).
reg
.
opt
&
0x1C00
;
else
hw
->
MXoptionReg
|=
(
ACCESS_FBINFO
(
devflags
.
memtype
)
&
7
)
<<
10
;
if
(
ACCESS_FBINFO
(
devflags
.
sgram
))
hw
->
MXoptionReg
|=
0x4000
;
mga_outl
(
M_CTLWTST
,
0x042450A1
);
mga_outl
(
M_MEMRDBK
,
0x00000108
);
mga_outl
(
M_CTLWTST
,
ACCESS_FBINFO
(
values
).
reg
.
mctlwtst
);
mga_outl
(
M_MEMRDBK
,
ACCESS_FBINFO
(
values
).
reg
.
memrdbk
);
udelay
(
200
);
mga_outl
(
M_MACCESS
,
0x00000000
);
mga_outl
(
M_MACCESS
,
0x00008000
);
udelay
(
100
);
mga_outl
(
M_MEMRDBK
,
0x00000108
);
mga_outl
(
M_MEMRDBK
,
ACCESS_FBINFO
(
values
).
reg
.
memrdbk
);
hw
->
MXoptionReg
|=
0x00040020
;
}
pci_write_config_dword
(
ACCESS_FBINFO
(
pcidev
),
PCI_OPTION_REG
,
hw
->
MXoptionReg
);
...
...
drivers/video/matrox/matroxfb_DAC1064.h
View file @
062dffea
...
...
@@ -146,6 +146,8 @@ void DAC1064_global_restore(WPMINFO2);
#define M1064_XPWRCTRL 0xA0
#define M1064_XPANMODE 0xA2
enum
POS1064
{
POS1064_XCURADDL
=
0
,
POS1064_XCURADDH
,
POS1064_XCURCTRL
,
POS1064_XCURCOL0RED
,
POS1064_XCURCOL0GREEN
,
POS1064_XCURCOL0BLUE
,
...
...
@@ -156,7 +158,7 @@ enum POS1064 {
POS1064_XGENIOCTRL
,
POS1064_XGENIODATA
,
POS1064_XZOOMCTRL
,
POS1064_XSENSETEST
,
POS1064_XCRCBITSEL
,
POS1064_XCOLKEYMASKL
,
POS1064_XCOLKEYMASKH
,
POS1064_XCOLKEYL
,
POS1064_XCOLKEYH
,
POS1064_XOUTPUTCONN
};
POS1064_XOUTPUTCONN
,
POS1064_XPANMODE
,
POS1064_XPWRCTRL
};
#endif
/* __MATROXFB_DAC1064_H__ */
drivers/video/matrox/matroxfb_Ti3026.c
View file @
062dffea
...
...
@@ -2,11 +2,11 @@
*
* Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
*
* (c) 1998
,1999,2000
Petr Vandrovec <vandrove@vc.cvut.cz>
* (c) 1998
-2002
Petr Vandrovec <vandrove@vc.cvut.cz>
*
* Portions Copyright (c) 2001 Matrox Graphics Inc.
*
* Version: 1.6
2 2000/11/29
* Version: 1.6
5 2002/08/14
*
* MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
*
...
...
@@ -84,6 +84,7 @@
#include "matroxfb_Ti3026.h"
#include "matroxfb_misc.h"
#include "matroxfb_accel.h"
#include <linux/matroxfb.h>
#ifdef CONFIG_FB_MATROX_MILLENIUM
#define outTi3026 matroxfb_DAC_out
...
...
@@ -401,7 +402,7 @@ static int matroxfb_ti3026_setfont(struct display* p, int width, int height) {
return
0
;
}
static
int
matroxfb_ti3026_selhwcursor
(
WPMINFO
struct
display
*
p
)
{
static
int
matroxfb_ti3026_selhwcursor
(
WPMINFO
2
)
{
ACCESS_FBINFO
(
dispsw
.
cursor
)
=
matroxfb_ti3026_cursor
;
ACCESS_FBINFO
(
dispsw
.
set_font
)
=
matroxfb_ti3026_setfont
;
return
0
;
...
...
@@ -433,7 +434,7 @@ static int Ti3026_setpclk(WPMINFO int clk, struct display* p) {
hw
->
DACclk
[
1
]
=
pixfeed
;
hw
->
DACclk
[
2
]
=
pixpost
|
0xB0
;
if
(
p
->
type
==
FB_TYPE_TEXT
)
{
if
(
ACCESS_FBINFO
(
fbcon
).
fix
.
type
==
FB_TYPE_TEXT
)
{
hw
->
DACreg
[
POS3026_XMEMPLLCTRL
]
=
TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL
|
TVP3026_XMEMPLLCTRL_RCLK_PIXPLL
;
hw
->
DACclk
[
3
]
=
0xFD
;
hw
->
DACclk
[
4
]
=
0x3D
;
...
...
@@ -501,7 +502,7 @@ static int Ti3026_init(WPMINFO struct my_timming* m, struct display* p) {
DBG
(
"Ti3026_init"
)
memcpy
(
hw
->
DACreg
,
MGADACbpp32
,
sizeof
(
hw
->
DACreg
));
if
(
p
->
type
==
FB_TYPE_TEXT
)
{
if
(
ACCESS_FBINFO
(
fbcon
).
fix
.
type
==
FB_TYPE_TEXT
)
{
hw
->
DACreg
[
POS3026_XLATCHCTRL
]
=
TVP3026_XLATCHCTRL_8_1
;
hw
->
DACreg
[
POS3026_XTRUECOLORCTRL
]
=
TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR
;
hw
->
DACreg
[
POS3026_XMUXCTRL
]
=
TVP3026_XMUXCTRL_VGA
;
...
...
@@ -568,7 +569,7 @@ static int Ti3026_init(WPMINFO struct my_timming* m, struct display* p) {
/* set interleaving */
hw
->
MXoptionReg
&=
~
0x00001000
;
if
((
p
->
type
!=
FB_TYPE_TEXT
)
&&
isInterleave
(
MINFO
))
hw
->
MXoptionReg
|=
0x00001000
;
if
((
ACCESS_FBINFO
(
fbcon
).
fix
.
type
!=
FB_TYPE_TEXT
)
&&
isInterleave
(
MINFO
))
hw
->
MXoptionReg
|=
0x00001000
;
/* set DAC */
Ti3026_setpclk
(
PMINFO
m
->
pixclock
,
p
);
...
...
@@ -811,6 +812,10 @@ static void Ti3026_reset(WPMINFO2) {
ti3026_ramdac_init
(
PMINFO2
);
}
static
struct
matrox_altout
ti3026_output
=
{
.
name
=
"Primary output"
,
};
static
int
Ti3026_preinit
(
WPMINFO2
)
{
static
const
int
vxres_mill2
[]
=
{
512
,
640
,
768
,
800
,
832
,
960
,
1024
,
1152
,
1280
,
1600
,
1664
,
1920
,
...
...
@@ -829,6 +834,11 @@ static int Ti3026_preinit(WPMINFO2) {
ACCESS_FBINFO
(
capable
.
vxres
)
=
isMilleniumII
(
MINFO
)
?
vxres_mill2
:
vxres_mill1
;
ACCESS_FBINFO
(
cursor
.
timer
.
function
)
=
matroxfb_ti3026_flashcursor
;
ACCESS_FBINFO
(
outputs
[
0
]).
data
=
MINFO
;
ACCESS_FBINFO
(
outputs
[
0
]).
output
=
&
ti3026_output
;
ACCESS_FBINFO
(
outputs
[
0
]).
src
=
MATROXFB_SRC_CRTC1
;
ACCESS_FBINFO
(
outputs
[
0
]).
mode
=
MATROXFB_OUTPUT_MODE_MONITOR
;
if
(
ACCESS_FBINFO
(
devflags
.
noinit
))
return
0
;
/* preserve VGA I/O, BIOS and PPC */
...
...
drivers/video/matrox/matroxfb_accel.c
View file @
062dffea
...
...
@@ -2,9 +2,9 @@
*
* Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
*
* (c) 1998-200
1
Petr Vandrovec <vandrove@vc.cvut.cz>
* (c) 1998-200
2
Petr Vandrovec <vandrove@vc.cvut.cz>
*
* Version: 1.
51 2001/06/18
* Version: 1.
65 2002/08/14
*
* MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
*
...
...
@@ -85,21 +85,21 @@
#define mga_ydstlen(y,l) mga_outl(M_YDSTLEN | M_EXEC, ((y) << 16) | (l))
void
matrox_cfbX_init
(
WPMINFO
struct
display
*
p
)
{
void
matrox_cfbX_init
(
WPMINFO
2
)
{
u_int32_t
maccess
;
u_int32_t
mpitch
;
u_int32_t
mopmode
;
DBG
(
"matrox_cfbX_init"
)
mpitch
=
p
->
var
.
xres_virtual
;
mpitch
=
ACCESS_FBINFO
(
fbcon
).
var
.
xres_virtual
;
if
(
p
->
type
==
FB_TYPE_TEXT
)
{
if
(
ACCESS_FBINFO
(
fbcon
).
fix
.
type
==
FB_TYPE_TEXT
)
{
maccess
=
0x00000000
;
mpitch
=
(
mpitch
>>
4
)
|
0x8000
;
/* set something */
mopmode
=
M_OPMODE_8BPP
;
}
else
{
switch
(
p
->
var
.
bits_per_pixel
)
{
switch
(
ACCESS_FBINFO
(
fbcon
).
var
.
bits_per_pixel
)
{
case
4
:
maccess
=
0x00000000
;
/* accelerate as 8bpp video */
mpitch
=
(
mpitch
>>
1
)
|
0x8000
;
/* disable linearization */
mopmode
=
M_OPMODE_4BPP
;
...
...
@@ -107,7 +107,7 @@ void matrox_cfbX_init(WPMINFO struct display* p) {
case
8
:
maccess
=
0x00000000
;
mopmode
=
M_OPMODE_8BPP
;
break
;
case
16
:
if
(
p
->
var
.
green
.
length
==
5
)
case
16
:
if
(
ACCESS_FBINFO
(
fbcon
).
var
.
green
.
length
==
5
)
maccess
=
0xC0000001
;
else
maccess
=
0x40000001
;
...
...
@@ -816,7 +816,7 @@ static void matrox_cfbX_clear_margins(struct vc_data* conp, struct display* p, i
static
void
matrox_text_setup
(
struct
display
*
p
)
{
MINFO_FROM_DISP
(
p
);
p
->
next_line
=
p
->
line_length
?
p
->
line_length
:
((
p
->
var
.
xres_virtual
/
(
fontwidth
(
p
)
?
fontwidth
(
p
)
:
8
))
*
ACCESS_FBINFO
(
devflags
.
textstep
));
p
->
next_line
=
ACCESS_FBINFO
(
fbcon
).
fix
.
line_length
?
ACCESS_FBINFO
(
fbcon
).
fix
.
line_length
:
((
p
->
var
.
xres_virtual
/
(
fontwidth
(
p
)
?
fontwidth
(
p
)
:
8
))
*
ACCESS_FBINFO
(
devflags
.
textstep
));
p
->
next_plane
=
0
;
}
...
...
@@ -1040,7 +1040,7 @@ static int matrox_text_setfont(struct display* p, int width, int height) {
MINFO_FROM_DISP
(
p
);
matrox_text_round
(
PMINFO
&
p
->
var
,
p
);
p
->
next_line
=
p
->
line_length
=
((
p
->
var
.
xres_virtual
/
(
fontwidth
(
p
)
?
fontwidth
(
p
)
:
8
))
*
ACCESS_FBINFO
(
devflags
.
textstep
));
p
->
next_line
=
ACCESS_FBINFO
(
fbcon
).
fix
.
line_length
=
((
p
->
var
.
xres_virtual
/
(
fontwidth
(
p
)
?
fontwidth
(
p
)
:
8
))
*
ACCESS_FBINFO
(
devflags
.
textstep
));
if
(
p
->
conp
)
matrox_text_createcursor
(
PMINFO
p
);
...
...
@@ -1144,11 +1144,11 @@ void initMatrox(WPMINFO struct display* p) {
if
(
p
->
dispsw
&&
p
->
conp
)
fb_con
.
con_cursor
(
p
->
conp
,
CM_ERASE
);
p
->
dispsw_data
=
NULL
;
if
((
p
->
var
.
accel_flags
&
FB_ACCELF_TEXT
)
!=
FB_ACCELF_TEXT
)
{
if
(
p
->
type
==
FB_TYPE_TEXT
)
{
if
((
ACCESS_FBINFO
(
fbcon
).
var
.
accel_flags
&
FB_ACCELF_TEXT
)
!=
FB_ACCELF_TEXT
)
{
if
(
ACCESS_FBINFO
(
fbcon
).
fix
.
type
==
FB_TYPE_TEXT
)
{
swtmp
=
&
matroxfb_text
;
}
else
{
switch
(
p
->
var
.
bits_per_pixel
)
{
switch
(
ACCESS_FBINFO
(
fbcon
).
var
.
bits_per_pixel
)
{
#ifdef FBCON_HAS_CFB4
case
4
:
swtmp
=
&
fbcon_cfb4
;
...
...
@@ -1183,10 +1183,10 @@ void initMatrox(WPMINFO struct display* p) {
}
}
dprintk
(
KERN_INFO
"matroxfb: acceleration disabled
\n
"
);
}
else
if
(
p
->
type
==
FB_TYPE_TEXT
)
{
}
else
if
(
ACCESS_FBINFO
(
fbcon
).
fix
.
type
==
FB_TYPE_TEXT
)
{
swtmp
=
&
matroxfb_text
;
}
else
{
switch
(
p
->
var
.
bits_per_pixel
)
{
switch
(
ACCESS_FBINFO
(
fbcon
).
var
.
bits_per_pixel
)
{
#ifdef FBCON_HAS_CFB4
case
4
:
swtmp
=
&
matroxfb_cfb4
;
...
...
@@ -1222,8 +1222,8 @@ void initMatrox(WPMINFO struct display* p) {
}
memcpy
(
&
ACCESS_FBINFO
(
dispsw
),
swtmp
,
sizeof
(
ACCESS_FBINFO
(
dispsw
)));
p
->
dispsw
=
&
ACCESS_FBINFO
(
dispsw
);
if
((
p
->
type
!=
FB_TYPE_TEXT
)
&&
ACCESS_FBINFO
(
devflags
.
hwcursor
))
{
ACCESS_FBINFO
(
hw_switch
)
->
selhwcursor
(
PMINFO
p
);
if
((
ACCESS_FBINFO
(
fbcon
).
fix
.
type
!=
FB_TYPE_TEXT
)
&&
ACCESS_FBINFO
(
devflags
.
hwcursor
))
{
ACCESS_FBINFO
(
hw_switch
)
->
selhwcursor
(
PMINFO
2
);
}
}
...
...
@@ -1233,7 +1233,7 @@ void matrox_init_putc(WPMINFO struct display* p, void (*dac_createcursor)(WPMINF
int
i
;
if
(
p
&&
p
->
conp
)
{
if
(
p
->
type
==
FB_TYPE_TEXT
)
{
if
(
ACCESS_FBINFO
(
fbcon
).
fix
.
type
==
FB_TYPE_TEXT
)
{
matrox_text_createcursor
(
PMINFO
p
);
matrox_text_loadfont
(
PMINFO
p
);
i
=
0
;
...
...
drivers/video/matrox/matroxfb_accel.h
View file @
062dffea
...
...
@@ -4,7 +4,7 @@
#include "matroxfb_base.h"
void
matrox_init_putc
(
WPMINFO
struct
display
*
p
,
void
(
*
)(
WPMINFO
struct
display
*
p
));
void
matrox_cfbX_init
(
WPMINFO
struct
display
*
p
);
void
matrox_cfbX_init
(
WPMINFO
2
);
void
matrox_text_round
(
CPMINFO
struct
fb_var_screeninfo
*
var
,
struct
display
*
p
);
void
initMatrox
(
WPMINFO
struct
display
*
p
);
...
...
drivers/video/matrox/matroxfb_base.c
View file @
062dffea
...
...
@@ -2,11 +2,11 @@
*
* Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
*
* (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
5 2002/08/14
*
* MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
*
...
...
@@ -77,6 +77,15 @@
* "Uns Lider" <unslider@miranda.org>
* G100 PLNWT fixes
*
* "Denis Zaitsev" <zzz@cd-club.ru>
* Fixes
*
* "Mike Pieper" <mike@pieper-family.de>
* TVOut enhandcements, V4L2 control interface.
*
* "Diego Biurrun" <diego@biurrun.de>
* DFP testing
*
* (following author is not in any relation with this code, but his code
* is included in this driver)
*
...
...
@@ -100,6 +109,7 @@
#include "matroxfb_Ti3026.h"
#include "matroxfb_maven.h"
#include "matroxfb_crtc2.h"
#include "matroxfb_g450.h"
#include <linux/matroxfb.h>
#include <asm/uaccess.h>
...
...
@@ -169,11 +179,13 @@ static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {
if
(
ACCESS_FBINFO
(
dead
))
return
;
ACCESS_FBINFO
(
fbcon
).
var
.
xoffset
=
var
->
xoffset
;
ACCESS_FBINFO
(
fbcon
).
var
.
yoffset
=
var
->
yoffset
;
disp
=
ACCESS_FBINFO
(
currcon_display
);
if
(
disp
->
type
==
FB_TYPE_TEXT
)
{
pos
=
var
->
yoffset
/
fontheight
(
disp
)
*
disp
->
next_line
/
ACCESS_FBINFO
(
devflags
.
textstep
)
+
var
->
xoffset
/
(
fontwidth
(
disp
)
?
fontwidth
(
disp
)
:
8
);
if
(
ACCESS_FBINFO
(
fbcon
).
fix
.
type
==
FB_TYPE_TEXT
)
{
pos
=
ACCESS_FBINFO
(
fbcon
).
var
.
yoffset
/
fontheight
(
disp
)
*
disp
->
next_line
/
ACCESS_FBINFO
(
devflags
.
textstep
)
+
ACCESS_FBINFO
(
fbcon
).
var
.
xoffset
/
(
fontwidth
(
disp
)
?
fontwidth
(
disp
)
:
8
);
}
else
{
pos
=
(
var
->
yoffset
*
var
->
xres_virtual
+
var
->
xoffset
)
*
ACCESS_FBINFO
(
curr
.
final_bppShift
)
/
32
;
pos
=
(
ACCESS_FBINFO
(
fbcon
).
var
.
yoffset
*
ACCESS_FBINFO
(
fbcon
).
var
.
xres_virtual
+
ACCESS_FBINFO
(
fbcon
).
var
.
xoffset
)
*
ACCESS_FBINFO
(
curr
.
final_bppShift
)
/
32
;
pos
+=
ACCESS_FBINFO
(
curr
.
ydstorg
.
chunks
);
}
p0
=
ACCESS_FBINFO
(
hw
).
CRTC
[
0x0D
]
=
pos
&
0xFF
;
...
...
@@ -212,6 +224,7 @@ static void matroxfb_remove(WPMINFO int dummy) {
}
matroxfb_unregister_device
(
MINFO
);
unregister_framebuffer
(
&
ACCESS_FBINFO
(
fbcon
));
matroxfb_g450_shutdown
(
PMINFO2
);
del_timer_sync
(
&
ACCESS_FBINFO
(
cursor
.
timer
));
#ifdef CONFIG_MTRR
if
(
ACCESS_FBINFO
(
mtrr
.
vram_valid
))
...
...
@@ -233,7 +246,7 @@ static void matroxfb_remove(WPMINFO int dummy) {
static
int
matroxfb_open
(
struct
fb_info
*
info
,
int
user
)
{
#define minfo (
(struct matrox_fb_info*)info
)
#define minfo (
container_of(info, struct matrox_fb_info, fbcon)
)
DBG_LOOP
(
"matroxfb_open"
)
if
(
ACCESS_FBINFO
(
dead
))
{
...
...
@@ -246,7 +259,7 @@ static int matroxfb_open(struct fb_info *info, int user)
static
int
matroxfb_release
(
struct
fb_info
*
info
,
int
user
)
{
#define minfo (
(struct matrox_fb_info*)info
)
#define minfo (
container_of(info, struct matrox_fb_info, fbcon)
)
DBG_LOOP
(
"matroxfb_release"
)
if
(
!
(
--
ACCESS_FBINFO
(
usecount
))
&&
ACCESS_FBINFO
(
dead
))
{
...
...
@@ -258,7 +271,7 @@ static int matroxfb_release(struct fb_info *info, int user)
static
int
matroxfb_pan_display
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
info
)
{
#define minfo (
(struct matrox_fb_info*)info
)
#define minfo (
container_of(info, struct matrox_fb_info, fbcon)
)
DBG
(
"matroxfb_pan_display"
)
...
...
@@ -284,7 +297,7 @@ static int matroxfb_pan_display(struct fb_var_screeninfo *var, int con,
static
int
matroxfb_updatevar
(
int
con
,
struct
fb_info
*
info
)
{
#define minfo (
(struct matrox_fb_info*)info
)
#define minfo (
container_of(info, struct matrox_fb_info, fbcon)
)
DBG
(
"matroxfb_updatevar"
);
matrox_pan_var
(
PMINFO
&
fb_display
[
con
].
var
);
...
...
@@ -404,12 +417,43 @@ static int matroxfb_get_cmap_len(struct fb_var_screeninfo *var) {
}
static
int
matroxfb_decode_var
(
CPMINFO
struct
display
*
p
,
struct
fb_var_screeninfo
*
var
,
int
*
visual
,
int
*
video_cmap_len
,
unsigned
int
*
ydstorg
)
{
struct
RGBT
{
unsigned
char
bpp
;
struct
{
unsigned
char
offset
,
length
;
}
red
,
green
,
blue
,
transp
;
signed
char
visual
;
};
static
const
struct
RGBT
table
[]
=
{
#if defined FBCON_HAS_VGATEXT
{
0
,{
0
,
6
},{
0
,
6
},{
0
,
6
},{
0
,
0
},
MX_VISUAL_PSEUDOCOLOR
},
#endif
#if defined FBCON_HAS_CFB4 || defined FBCON_HAS_CFB8
{
8
,{
0
,
8
},{
0
,
8
},{
0
,
8
},{
0
,
0
},
MX_VISUAL_PSEUDOCOLOR
},
#endif
#if defined FBCON_HAS_CFB16
{
15
,{
10
,
5
},{
5
,
5
},{
0
,
5
},{
15
,
1
},
MX_VISUAL_DIRECTCOLOR
},
{
16
,{
11
,
5
},{
5
,
6
},{
0
,
5
},{
0
,
0
},
MX_VISUAL_DIRECTCOLOR
},
#endif
#if defined FBCON_HAS_CFB24
{
24
,{
16
,
8
},{
8
,
8
},{
0
,
8
},{
0
,
0
},
MX_VISUAL_DIRECTCOLOR
},
#endif
#if defined FBCON_HAS_CFB32
{
32
,{
16
,
8
},{
8
,
8
},{
0
,
8
},{
24
,
8
},
MX_VISUAL_DIRECTCOLOR
}
#endif
};
struct
RGBT
const
*
rgbt
;
unsigned
int
bpp
=
var
->
bits_per_pixel
;
unsigned
int
vramlen
;
unsigned
int
memlen
;
DBG
(
"matroxfb_decode_var"
)
switch
(
var
->
bits_per_pixel
)
{
switch
(
bpp
)
{
#ifdef FBCON_HAS_VGATEXT
case
0
:
if
(
!
ACCESS_FBINFO
(
capable
.
text
))
return
-
EINVAL
;
break
;
...
...
@@ -438,22 +482,22 @@ static int matroxfb_decode_var(CPMINFO struct display* p, struct fb_var_screenin
var
->
yres_virtual
=
var
->
yres
;
if
(
var
->
xres_virtual
<
var
->
xres
)
var
->
xres_virtual
=
var
->
xres
;
if
(
var
->
bits_per_pixel
)
{
var
->
xres_virtual
=
matroxfb_pitch_adjust
(
PMINFO
var
->
xres_virtual
,
var
->
bits_per_pixel
);
memlen
=
var
->
xres_virtual
*
var
->
bits_per_pixel
*
var
->
yres_virtual
/
8
;
if
(
bpp
)
{
var
->
xres_virtual
=
matroxfb_pitch_adjust
(
PMINFO
var
->
xres_virtual
,
bpp
);
memlen
=
var
->
xres_virtual
*
bpp
*
var
->
yres_virtual
/
8
;
if
(
memlen
>
vramlen
)
{
var
->
yres_virtual
=
vramlen
*
8
/
(
var
->
xres_virtual
*
var
->
bits_per_pixel
);
memlen
=
var
->
xres_virtual
*
var
->
bits_per_pixel
*
var
->
yres_virtual
/
8
;
var
->
yres_virtual
=
vramlen
*
8
/
(
var
->
xres_virtual
*
bpp
);
memlen
=
var
->
xres_virtual
*
bpp
*
var
->
yres_virtual
/
8
;
}
/* There is hardware bug that no line can cross 4MB boundary */
/* give up for CFB24, it is impossible to easy workaround it */
/* for other try to do something */
if
(
!
ACCESS_FBINFO
(
capable
.
cross4MB
)
&&
(
memlen
>
0x400000
))
{
if
(
var
->
bits_per_pixel
==
24
)
{
if
(
bpp
==
24
)
{
/* sorry */
}
else
{
unsigned
int
linelen
;
unsigned
int
m1
=
linelen
=
var
->
xres_virtual
*
var
->
bits_per_pixel
/
8
;
unsigned
int
m1
=
linelen
=
var
->
xres_virtual
*
bpp
/
8
;
unsigned
int
m2
=
PAGE_SIZE
;
/* or 128 if you do not need PAGE ALIGNED address */
unsigned
int
max_yres
;
...
...
@@ -497,88 +541,27 @@ static int matroxfb_decode_var(CPMINFO struct display* p, struct fb_var_screenin
if
(
var
->
yoffset
+
var
->
yres
>
var
->
yres_virtual
)
var
->
yoffset
=
var
->
yres_virtual
-
var
->
yres
;
if
(
var
->
bits_per_pixel
==
0
)
{
var
->
red
.
offset
=
0
;
var
->
red
.
length
=
6
;
var
->
green
.
offset
=
0
;
var
->
green
.
length
=
6
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
6
;
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
*
visual
=
MX_VISUAL_PSEUDOCOLOR
;
}
else
if
(
var
->
bits_per_pixel
==
4
)
{
var
->
red
.
offset
=
0
;
var
->
red
.
length
=
8
;
var
->
green
.
offset
=
0
;
var
->
green
.
length
=
8
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
8
;
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
*
visual
=
MX_VISUAL_PSEUDOCOLOR
;
}
else
if
(
var
->
bits_per_pixel
<=
8
)
{
var
->
red
.
offset
=
0
;
var
->
red
.
length
=
8
;
var
->
green
.
offset
=
0
;
var
->
green
.
length
=
8
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
8
;
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
*
visual
=
MX_VISUAL_PSEUDOCOLOR
;
}
else
{
if
(
var
->
bits_per_pixel
<=
16
)
{
if
(
var
->
green
.
length
==
5
)
{
var
->
red
.
offset
=
10
;
var
->
red
.
length
=
5
;
var
->
green
.
offset
=
5
;
var
->
green
.
length
=
5
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
5
;
var
->
transp
.
offset
=
15
;
var
->
transp
.
length
=
1
;
}
else
{
var
->
red
.
offset
=
11
;
var
->
red
.
length
=
5
;
var
->
green
.
offset
=
5
;
var
->
green
.
length
=
6
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
5
;
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
}
}
else
if
(
var
->
bits_per_pixel
<=
24
)
{
var
->
red
.
offset
=
16
;
var
->
red
.
length
=
8
;
var
->
green
.
offset
=
8
;
var
->
green
.
length
=
8
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
8
;
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
}
else
{
var
->
red
.
offset
=
16
;
var
->
red
.
length
=
8
;
var
->
green
.
offset
=
8
;
var
->
green
.
length
=
8
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
8
;
var
->
transp
.
offset
=
24
;
var
->
transp
.
length
=
8
;
}
dprintk
(
"matroxfb: truecolor: "
"size=%d:%d:%d:%d, shift=%d:%d:%d:%d
\n
"
,
var
->
transp
.
length
,
var
->
red
.
length
,
var
->
green
.
length
,
var
->
blue
.
length
,
var
->
transp
.
offset
,
var
->
red
.
offset
,
var
->
green
.
offset
,
var
->
blue
.
offset
);
*
visual
=
MX_VISUAL_DIRECTCOLOR
;
if
(
bpp
==
16
&&
var
->
green
.
length
==
5
)
{
bpp
--
;
/* an artifical value - 15 */
}
for
(
rgbt
=
table
;
rgbt
->
bpp
<
bpp
;
rgbt
++
);
#define SETCLR(clr)\
var->clr.offset = rgbt->clr.offset;\
var->clr.length = rgbt->clr.length
SETCLR
(
red
);
SETCLR
(
green
);
SETCLR
(
blue
);
SETCLR
(
transp
);
#undef SETCLR
*
visual
=
rgbt
->
visual
;
if
(
bpp
>
8
)
dprintk
(
"matroxfb: truecolor: "
"size=%d:%d:%d:%d, shift=%d:%d:%d:%d
\n
"
,
var
->
transp
.
length
,
var
->
red
.
length
,
var
->
green
.
length
,
var
->
blue
.
length
,
var
->
transp
.
offset
,
var
->
red
.
offset
,
var
->
green
.
offset
,
var
->
blue
.
offset
);
*
video_cmap_len
=
matroxfb_get_cmap_len
(
var
);
dprintk
(
KERN_INFO
"requested %d*%d/%dbpp (%d*%d)
\n
"
,
var
->
xres
,
var
->
yres
,
var
->
bits_per_pixel
,
var
->
xres_virtual
,
var
->
yres_virtual
);
...
...
@@ -589,9 +572,8 @@ static int matroxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned
blue
,
unsigned
transp
,
struct
fb_info
*
fb_info
)
{
struct
display
*
p
;
#ifdef CONFIG_FB_MATROX_MULTIHEAD
struct
matrox_fb_info
*
minfo
=
(
struct
matrox_fb_info
*
)
fb_info
;
struct
matrox_fb_info
*
minfo
=
container_of
(
fb_info
,
struct
matrox_fb_info
,
fbcon
)
;
#endif
DBG
(
"matroxfb_setcolreg"
)
...
...
@@ -611,18 +593,17 @@ static int matroxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
ACCESS_FBINFO
(
palette
[
regno
].
blue
)
=
blue
;
ACCESS_FBINFO
(
palette
[
regno
].
transp
)
=
transp
;
p
=
ACCESS_FBINFO
(
currcon_display
);
if
(
p
->
var
.
grayscale
)
{
if
(
ACCESS_FBINFO
(
fbcon
).
var
.
grayscale
)
{
/* gray = 0.30*R + 0.59*G + 0.11*B */
red
=
green
=
blue
=
(
red
*
77
+
green
*
151
+
blue
*
28
)
>>
8
;
}
red
=
CNVT_TOHW
(
red
,
p
->
var
.
red
.
length
);
green
=
CNVT_TOHW
(
green
,
p
->
var
.
green
.
length
);
blue
=
CNVT_TOHW
(
blue
,
p
->
var
.
blue
.
length
);
transp
=
CNVT_TOHW
(
transp
,
p
->
var
.
transp
.
length
);
red
=
CNVT_TOHW
(
red
,
ACCESS_FBINFO
(
fbcon
).
var
.
red
.
length
);
green
=
CNVT_TOHW
(
green
,
ACCESS_FBINFO
(
fbcon
).
var
.
green
.
length
);
blue
=
CNVT_TOHW
(
blue
,
ACCESS_FBINFO
(
fbcon
).
var
.
blue
.
length
);
transp
=
CNVT_TOHW
(
transp
,
ACCESS_FBINFO
(
fbcon
).
var
.
transp
.
length
);
switch
(
p
->
var
.
bits_per_pixel
)
{
switch
(
ACCESS_FBINFO
(
fbcon
).
var
.
bits_per_pixel
)
{
#if defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB4) || defined(FBCON_HAS_VGATEXT)
#ifdef FBCON_HAS_VGATEXT
case
0
:
...
...
@@ -642,87 +623,54 @@ static int matroxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
#ifdef FBCON_HAS_CFB16
case
16
:
ACCESS_FBINFO
(
cmap
.
cfb16
[
regno
])
=
(
red
<<
p
->
var
.
red
.
offset
)
|
(
green
<<
p
->
var
.
green
.
offset
)
|
(
blue
<<
p
->
var
.
blue
.
offset
)
|
(
transp
<<
p
->
var
.
transp
.
offset
);
/* for 1:5:5:5 */
(
red
<<
ACCESS_FBINFO
(
fbcon
).
var
.
red
.
offset
)
|
(
green
<<
ACCESS_FBINFO
(
fbcon
).
var
.
green
.
offset
)
|
(
blue
<<
ACCESS_FBINFO
(
fbcon
).
var
.
blue
.
offset
)
|
(
transp
<<
ACCESS_FBINFO
(
fbcon
).
var
.
transp
.
offset
);
/* for 1:5:5:5 */
break
;
#endif
#ifdef FBCON_HAS_CFB24
case
24
:
ACCESS_FBINFO
(
cmap
.
cfb24
[
regno
])
=
(
red
<<
p
->
var
.
red
.
offset
)
|
(
green
<<
p
->
var
.
green
.
offset
)
|
(
blue
<<
p
->
var
.
blue
.
offset
);
(
red
<<
ACCESS_FBINFO
(
fbcon
).
var
.
red
.
offset
)
|
(
green
<<
ACCESS_FBINFO
(
fbcon
).
var
.
green
.
offset
)
|
(
blue
<<
ACCESS_FBINFO
(
fbcon
).
var
.
blue
.
offset
);
break
;
#endif
#ifdef FBCON_HAS_CFB32
case
32
:
ACCESS_FBINFO
(
cmap
.
cfb32
[
regno
])
=
(
red
<<
p
->
var
.
red
.
offset
)
|
(
green
<<
p
->
var
.
green
.
offset
)
|
(
blue
<<
p
->
var
.
blue
.
offset
)
|
(
transp
<<
p
->
var
.
transp
.
offset
);
/* 8:8:8:8 */
(
red
<<
ACCESS_FBINFO
(
fbcon
).
var
.
red
.
offset
)
|
(
green
<<
ACCESS_FBINFO
(
fbcon
).
var
.
green
.
offset
)
|
(
blue
<<
ACCESS_FBINFO
(
fbcon
).
var
.
blue
.
offset
)
|
(
transp
<<
ACCESS_FBINFO
(
fbcon
).
var
.
transp
.
offset
);
/* 8:8:8:8 */
break
;
#endif
}
return
0
;
}
static
int
matroxfb_get_fix
(
struct
fb_fix_screeninfo
*
fix
,
int
con
,
struct
fb_info
*
info
)
static
void
matroxfb_update_fix
(
WPMINFO2
)
{
struct
display
*
p
;
struct
fb_fix_screeninfo
*
fix
=
&
ACCESS_FBINFO
(
fbcon
).
fix
;
DBG
(
"matroxfb_get_fix"
)
#define minfo ((struct matrox_fb_info*)info)
if
(
ACCESS_FBINFO
(
dead
))
{
return
-
ENXIO
;
}
if
(
con
>=
0
)
p
=
fb_display
+
con
;
else
p
=
ACCESS_FBINFO
(
fbcon
.
disp
);
memset
(
fix
,
0
,
sizeof
(
struct
fb_fix_screeninfo
));
strcpy
(
fix
->
id
,
"MATROX"
);
fix
->
smem_start
=
ACCESS_FBINFO
(
video
.
base
)
+
ACCESS_FBINFO
(
curr
.
ydstorg
.
bytes
);
fix
->
smem_len
=
ACCESS_FBINFO
(
video
.
len_usable
)
-
ACCESS_FBINFO
(
curr
.
ydstorg
.
bytes
);
fix
->
type
=
p
->
type
;
fix
->
type_aux
=
p
->
type_aux
;
fix
->
visual
=
p
->
visual
;
fix
->
xpanstep
=
8
;
/* 8 for 8bpp, 4 for 16bpp, 2 for 32bpp */
fix
->
xpanstep
=
8
;
/* 8 for 8bpp, 4 for 16bpp, 2 for 32bpp */
fix
->
ypanstep
=
1
;
fix
->
ywrapstep
=
0
;
fix
->
line_length
=
p
->
line_length
;
fix
->
mmio_start
=
ACCESS_FBINFO
(
mmio
.
base
);
fix
->
mmio_len
=
ACCESS_FBINFO
(
mmio
.
len
);
fix
->
accel
=
ACCESS_FBINFO
(
devflags
.
accelerator
);
return
0
;
#undef minfo
}
static
int
matroxfb_get_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
info
)
{
#define minfo ((struct matrox_fb_info*)info)
DBG
(
"matroxfb_get_var"
)
if
(
con
<
0
)
*
var
=
ACCESS_FBINFO
(
fbcon
.
disp
)
->
var
;
else
*
var
=
fb_display
[
con
].
var
;
return
0
;
#undef minfo
}
static
int
matroxfb_set_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
info
)
{
#define minfo (
(struct matrox_fb_info*)info
)
#define minfo (
container_of(info, struct matrox_fb_info, fbcon)
)
int
err
;
int
visual
;
int
cmap_len
;
...
...
@@ -763,17 +711,19 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,
display
->
var
=
*
var
;
/* cmap */
ACCESS_FBINFO
(
fbcon
.
screen_base
)
=
vaddr_va
(
ACCESS_FBINFO
(
video
.
vbase
))
+
ydstorg
;
display
->
visual
=
visual
;
display
->
ypanstep
=
1
;
display
->
ywrapstep
=
0
;
if
(
var
->
bits_per_pixel
)
{
display
->
type
=
FB_TYPE_PACKED_PIXELS
;
display
->
type_aux
=
0
;
display
->
next_line
=
display
->
line_length
=
(
var
->
xres_virtual
*
var
->
bits_per_pixel
)
>>
3
;
}
else
{
display
->
type
=
FB_TYPE_TEXT
;
display
->
type_aux
=
ACCESS_FBINFO
(
devflags
.
text_type_aux
);
display
->
next_line
=
display
->
line_length
=
(
var
->
xres_virtual
/
(
fontwidth
(
display
)
?
fontwidth
(
display
)
:
8
))
*
ACCESS_FBINFO
(
devflags
.
textstep
);
if
(
display
==
ACCESS_FBINFO
(
currcon_display
))
{
ACCESS_FBINFO
(
fbcon
).
var
=
*
var
;
matroxfb_update_fix
(
PMINFO2
);
ACCESS_FBINFO
(
fbcon
).
fix
.
visual
=
visual
;
if
(
var
->
bits_per_pixel
)
{
ACCESS_FBINFO
(
fbcon
).
fix
.
type
=
FB_TYPE_PACKED_PIXELS
;
ACCESS_FBINFO
(
fbcon
).
fix
.
type_aux
=
0
;
display
->
next_line
=
ACCESS_FBINFO
(
fbcon
).
fix
.
line_length
=
(
var
->
xres_virtual
*
var
->
bits_per_pixel
)
>>
3
;
}
else
{
ACCESS_FBINFO
(
fbcon
).
fix
.
type
=
FB_TYPE_TEXT
;
ACCESS_FBINFO
(
fbcon
).
fix
.
type_aux
=
ACCESS_FBINFO
(
devflags
.
text_type_aux
);
display
->
next_line
=
ACCESS_FBINFO
(
fbcon
).
fix
.
line_length
=
(
var
->
xres_virtual
/
(
fontwidth
(
display
)
?
fontwidth
(
display
)
:
8
))
*
ACCESS_FBINFO
(
devflags
.
textstep
);
}
}
display
->
can_soft_blank
=
1
;
display
->
inverse
=
ACCESS_FBINFO
(
devflags
.
inverse
);
...
...
@@ -788,7 +738,7 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,
unsigned
int
pos
;
ACCESS_FBINFO
(
curr
.
cmap_len
)
=
cmap_len
;
if
(
display
->
type
==
FB_TYPE_TEXT
)
{
if
(
ACCESS_FBINFO
(
fbcon
).
fix
.
type
==
FB_TYPE_TEXT
)
{
/* textmode must be in first megabyte, so no ydstorg allowed */
ACCESS_FBINFO
(
curr
.
ydstorg
.
bytes
)
=
0
;
ACCESS_FBINFO
(
curr
.
ydstorg
.
chunks
)
=
0
;
...
...
@@ -818,8 +768,10 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,
{
struct
my_timming
mt
;
struct
matrox_hw_state
*
hw
;
int
out
;
matroxfb_var2my
(
var
,
&
mt
);
mt
.
crtc
=
MATROXFB_SRC_CRTC1
;
/* CRTC1 delays */
switch
(
var
->
bits_per_pixel
)
{
case
0
:
mt
.
delay
=
31
+
0
;
break
;
...
...
@@ -834,8 +786,18 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,
del_timer_sync
(
&
ACCESS_FBINFO
(
cursor
.
timer
));
ACCESS_FBINFO
(
cursor
.
state
)
=
CM_ERASE
;
down_read
(
&
ACCESS_FBINFO
(
altout
).
lock
);
for
(
out
=
0
;
out
<
MATROXFB_MAX_OUTPUTS
;
out
++
)
{
if
(
ACCESS_FBINFO
(
outputs
[
out
]).
src
==
MATROXFB_SRC_CRTC1
&&
ACCESS_FBINFO
(
outputs
[
out
]).
output
->
compute
)
{
ACCESS_FBINFO
(
outputs
[
out
]).
output
->
compute
(
ACCESS_FBINFO
(
outputs
[
out
]).
data
,
&
mt
);
}
}
up_read
(
&
ACCESS_FBINFO
(
altout
).
lock
);
ACCESS_FBINFO
(
crtc1
).
pixclock
=
mt
.
pixclock
;
ACCESS_FBINFO
(
crtc1
).
mnp
=
mt
.
mnp
;
ACCESS_FBINFO
(
hw_switch
->
init
(
PMINFO
&
mt
,
display
));
if
(
display
->
type
==
FB_TYPE_TEXT
)
{
if
(
ACCESS_FBINFO
(
fbcon
).
fix
.
type
==
FB_TYPE_TEXT
)
{
if
(
fontheight
(
display
))
pos
=
var
->
yoffset
/
fontheight
(
display
)
*
display
->
next_line
/
ACCESS_FBINFO
(
devflags
.
textstep
)
+
var
->
xoffset
/
(
fontwidth
(
display
)
?
fontwidth
(
display
)
:
8
);
else
...
...
@@ -849,39 +811,23 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,
hw
->
CRTC
[
0x0C
]
=
(
pos
&
0xFF00
)
>>
8
;
hw
->
CRTCEXT
[
0
]
=
(
hw
->
CRTCEXT
[
0
]
&
0xF0
)
|
((
pos
>>
16
)
&
0x0F
)
|
((
pos
>>
14
)
&
0x40
);
hw
->
CRTCEXT
[
8
]
=
pos
>>
21
;
if
(
ACCESS_FBINFO
(
output
.
ph
)
&
(
MATROXFB_OUTPUT_CONN_PRIMARY
|
MATROXFB_OUTPUT_CONN_DFP
))
{
if
(
ACCESS_FBINFO
(
primout
))
ACCESS_FBINFO
(
primout
)
->
compute
(
MINFO
,
&
mt
);
}
if
(
ACCESS_FBINFO
(
output
.
ph
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
{
down_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
if
(
ACCESS_FBINFO
(
altout
.
output
))
ACCESS_FBINFO
(
altout
.
output
)
->
compute
(
ACCESS_FBINFO
(
altout
.
device
),
&
mt
);
up_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
}
ACCESS_FBINFO
(
hw_switch
->
restore
(
PMINFO
display
));
if
(
ACCESS_FBINFO
(
output
.
ph
)
&
(
MATROXFB_OUTPUT_CONN_PRIMARY
|
MATROXFB_OUTPUT_CONN_DFP
))
{
if
(
ACCESS_FBINFO
(
primout
))
ACCESS_FBINFO
(
primout
)
->
program
(
MINFO
);
}
if
(
ACCESS_FBINFO
(
output
.
ph
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
{
down_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
if
(
ACCESS_FBINFO
(
altout
.
output
))
ACCESS_FBINFO
(
altout
.
output
)
->
program
(
ACCESS_FBINFO
(
altout
.
device
));
up_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
down_read
(
&
ACCESS_FBINFO
(
altout
).
lock
);
for
(
out
=
0
;
out
<
MATROXFB_MAX_OUTPUTS
;
out
++
)
{
if
(
ACCESS_FBINFO
(
outputs
[
out
]).
src
==
MATROXFB_SRC_CRTC1
&&
ACCESS_FBINFO
(
outputs
[
out
]).
output
->
program
)
{
ACCESS_FBINFO
(
outputs
[
out
]).
output
->
program
(
ACCESS_FBINFO
(
outputs
[
out
]).
data
);
}
}
ACCESS_FBINFO
(
cursor
.
redraw
)
=
1
;
if
(
ACCESS_FBINFO
(
output
.
ph
)
&
(
MATROXFB_OUTPUT_CONN_PRIMARY
|
MATROXFB_OUTPUT_CONN_DFP
))
{
if
(
ACCESS_FBINFO
(
primout
))
ACCESS_FBINFO
(
primout
)
->
start
(
MINFO
);
}
if
(
ACCESS_FBINFO
(
output
.
ph
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
{
down_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
if
(
ACCESS_FBINFO
(
altout
.
output
))
ACCESS_FBINFO
(
altout
.
output
)
->
start
(
ACCESS_FBINFO
(
altout
.
device
));
up_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
for
(
out
=
0
;
out
<
MATROXFB_MAX_OUTPUTS
;
out
++
)
{
if
(
ACCESS_FBINFO
(
outputs
[
out
]).
src
==
MATROXFB_SRC_CRTC1
&&
ACCESS_FBINFO
(
outputs
[
out
]).
output
->
start
)
{
ACCESS_FBINFO
(
outputs
[
out
]).
output
->
start
(
ACCESS_FBINFO
(
outputs
[
out
]).
data
);
}
}
matrox_cfbX_init
(
PMINFO
display
);
up_read
(
&
ACCESS_FBINFO
(
altout
).
lock
);
matrox_cfbX_init
(
PMINFO2
);
my_install_cmap
(
PMINFO2
);
}
}
...
...
@@ -896,7 +842,7 @@ static int matrox_getcolreg(unsigned regno, unsigned *red, unsigned *green,
DBG
(
"matrox_getcolreg"
)
#define minfo (
(struct matrox_fb_info*)info
)
#define minfo (
container_of(info, struct matrox_fb_info, fbcon)
)
/*
* Read a single color register and split it into colors/transparent.
* Return != 0 for invalid regno.
...
...
@@ -916,7 +862,7 @@ static int matrox_getcolreg(unsigned regno, unsigned *red, unsigned *green,
static
int
matroxfb_get_cmap
(
struct
fb_cmap
*
cmap
,
int
kspc
,
int
con
,
struct
fb_info
*
info
)
{
#define minfo (
(struct matrox_fb_info*)info
)
#define minfo (
container_of(info, struct matrox_fb_info, fbcon)
)
struct
display
*
dsp
=
(
con
<
0
)
?
ACCESS_FBINFO
(
fbcon
.
disp
)
:
fb_display
+
con
;
...
...
@@ -942,7 +888,7 @@ static int matroxfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
{
unsigned
int
cmap_len
;
struct
display
*
dsp
=
(
con
<
0
)
?
info
->
disp
:
(
fb_display
+
con
);
#define minfo (
(struct matrox_fb_info*)info
)
#define minfo (
container_of(info, struct matrox_fb_info, fbcon)
)
DBG
(
"matroxfb_set_cmap"
)
...
...
@@ -982,18 +928,22 @@ static int matroxfb_get_vblank(CPMINFO struct fb_vblank *vblank)
vblank
->
flags
|=
FB_VBLANK_HBLANKING
;
if
(
sts1
&
8
)
vblank
->
flags
|=
FB_VBLANK_VSYNCING
;
if
(
vblank
->
vcount
>=
ACCESS_FBINFO
(
currcon_display
)
->
var
.
yres
)
if
(
vblank
->
vcount
>=
ACCESS_FBINFO
(
fbcon
).
var
.
yres
)
vblank
->
flags
|=
FB_VBLANK_VBLANKING
;
vblank
->
hcount
=
0
;
vblank
->
count
=
0
;
return
0
;
}
static
struct
matrox_altout
panellink_output
=
{
.
name
=
"Panellink output"
,
};
static
int
matroxfb_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
,
int
con
,
struct
fb_info
*
info
)
{
#define minfo (
(struct matrox_fb_info*)info
)
#define minfo (
container_of(info, struct matrox_fb_info, fbcon)
)
DBG
(
"matroxfb_ioctl"
)
if
(
ACCESS_FBINFO
(
dead
))
{
...
...
@@ -1016,80 +966,74 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
case
MATROXFB_SET_OUTPUT_MODE
:
{
struct
matroxioc_output_mode
mom
;
struct
matrox_altout
*
oproc
;
int
val
;
if
(
copy_from_user
(
&
mom
,
(
struct
matroxioc_output_mode
*
)
arg
,
sizeof
(
mom
)))
return
-
EFAULT
;
if
(
mom
.
output
>=
sizeof
(
u_int32_t
))
return
-
EINVAL
;
switch
(
mom
.
output
)
{
case
MATROXFB_OUTPUT_PRIMARY
:
if
(
mom
.
mode
!=
MATROXFB_OUTPUT_MODE_MONITOR
)
return
-
EINVAL
;
/* mode did not change... */
return
0
;
case
MATROXFB_OUTPUT_SECONDARY
:
if
(
mom
.
output
>=
MATROXFB_MAX_OUTPUTS
)
return
-
ENXIO
;
down_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
oproc
=
ACCESS_FBINFO
(
outputs
[
mom
.
output
]).
output
;
if
(
!
oproc
)
{
val
=
-
ENXIO
;
}
else
if
(
!
oproc
->
verifymode
)
{
if
(
mom
.
mode
==
MATROXFB_OUTPUT_MODE_MONITOR
)
{
val
=
0
;
}
else
{
val
=
-
EINVAL
;
down_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
if
(
ACCESS_FBINFO
(
altout
.
output
)
&&
ACCESS_FBINFO
(
altout
.
device
))
val
=
ACCESS_FBINFO
(
altout
.
output
)
->
setmode
(
ACCESS_FBINFO
(
altout
.
device
),
mom
.
mode
);
up_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
if
(
val
!=
1
)
return
val
;
if
(
ACCESS_FBINFO
(
output
.
ph
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
matroxfb_switch
(
ACCESS_FBINFO
(
fbcon
.
currcon
),
info
);
if
(
ACCESS_FBINFO
(
output
.
sh
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
{
}
}
else
{
val
=
oproc
->
verifymode
(
ACCESS_FBINFO
(
outputs
[
mom
.
output
]).
data
,
mom
.
mode
);
}
if
(
!
val
)
{
if
(
ACCESS_FBINFO
(
outputs
[
mom
.
output
]).
mode
!=
mom
.
mode
)
{
ACCESS_FBINFO
(
outputs
[
mom
.
output
]).
mode
=
mom
.
mode
;
val
=
1
;
}
}
up_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
if
(
val
!=
1
)
return
val
;
switch
(
ACCESS_FBINFO
(
outputs
[
mom
.
output
]).
src
)
{
case
MATROXFB_SRC_CRTC1
:
matroxfb_switch
(
ACCESS_FBINFO
(
fbcon
.
currcon
),
info
);
break
;
case
MATROXFB_SRC_CRTC2
:
{
struct
matroxfb_dh_fb_info
*
crtc2
;
down_read
(
&
ACCESS_FBINFO
(
crtc2
.
lock
));
crtc2
=
(
struct
matroxfb_dh_fb_info
*
)(
ACCESS_FBINFO
(
crtc2
.
info
)
);
crtc2
=
ACCESS_FBINFO
(
crtc2
.
info
);
if
(
crtc2
)
crtc2
->
fbcon
.
switch_con
(
crtc2
->
currcon
,
&
crtc2
->
fbcon
);
crtc2
->
fbcon
.
switch_con
(
crtc2
->
fbcon
.
currcon
,
&
crtc2
->
fbcon
);
up_read
(
&
ACCESS_FBINFO
(
crtc2
.
lock
));
}
return
0
;
case
MATROXFB_OUTPUT_DFP
:
if
(
!
(
ACCESS_FBINFO
(
output
.
all
)
&
MATROXFB_OUTPUT_CONN_DFP
))
return
-
ENXIO
;
if
(
mom
.
mode
!=
MATROXFB_OUTPUT_MODE_MONITOR
)
return
-
EINVAL
;
/* mode did not change... */
return
0
;
default:
return
-
EINVAL
;
break
;
}
return
0
;
}
case
MATROXFB_GET_OUTPUT_MODE
:
{
struct
matroxioc_output_mode
mom
;
struct
matrox_altout
*
oproc
;
int
val
;
if
(
copy_from_user
(
&
mom
,
(
struct
matroxioc_output_mode
*
)
arg
,
sizeof
(
mom
)))
return
-
EFAULT
;
if
(
mom
.
output
>=
sizeof
(
u_int32_t
))
return
-
EINVAL
;
switch
(
mom
.
output
)
{
case
MATROXFB_OUTPUT_PRIMARY
:
mom
.
mode
=
MATROXFB_OUTPUT_MODE_MONITOR
;
break
;
case
MATROXFB_OUTPUT_SECONDARY
:
val
=
-
EINVAL
;
down_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
if
(
ACCESS_FBINFO
(
altout
.
output
)
&&
ACCESS_FBINFO
(
altout
.
device
))
val
=
ACCESS_FBINFO
(
altout
.
output
)
->
getmode
(
ACCESS_FBINFO
(
altout
.
device
),
&
mom
.
mode
);
up_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
if
(
val
)
return
val
;
break
;
case
MATROXFB_OUTPUT_DFP
:
if
(
!
(
ACCESS_FBINFO
(
output
.
all
)
&
MATROXFB_OUTPUT_CONN_DFP
))
return
-
ENXIO
;
mom
.
mode
=
MATROXFB_OUTPUT_MODE_MONITOR
;
break
;
default:
return
-
EINVAL
;
if
(
mom
.
output
>=
MATROXFB_MAX_OUTPUTS
)
return
-
ENXIO
;
down_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
oproc
=
ACCESS_FBINFO
(
outputs
[
mom
.
output
]).
output
;
if
(
!
oproc
)
{
val
=
-
ENXIO
;
}
else
{
mom
.
mode
=
ACCESS_FBINFO
(
outputs
[
mom
.
output
]).
mode
;
val
=
0
;
}
up_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
if
(
val
)
return
val
;
if
(
copy_to_user
((
struct
matroxioc_output_mode
*
)
arg
,
&
mom
,
sizeof
(
mom
)))
return
-
EFAULT
;
return
0
;
...
...
@@ -1097,52 +1041,109 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
case
MATROXFB_SET_OUTPUT_CONNECTION
:
{
u_int32_t
tmp
;
int
i
;
int
changes
;
if
(
copy_from_user
(
&
tmp
,
(
u_int32_t
*
)
arg
,
sizeof
(
tmp
)))
return
-
EFAULT
;
if
(
tmp
&
~
ACCESS_FBINFO
(
output
.
all
))
return
-
EINVAL
;
if
(
tmp
&
ACCESS_FBINFO
(
output
.
sh
))
return
-
EINVAL
;
if
(
tmp
&
MATROXFB_OUTPUT_CONN_DFP
)
{
if
(
tmp
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
return
-
EINVAL
;
if
(
ACCESS_FBINFO
(
output
.
sh
))
return
-
EINVAL
;
for
(
i
=
0
;
i
<
32
;
i
++
)
{
if
(
tmp
&
(
1
<<
i
))
{
if
(
i
>=
MATROXFB_MAX_OUTPUTS
)
return
-
ENXIO
;
if
(
!
ACCESS_FBINFO
(
outputs
[
i
]).
output
)
return
-
ENXIO
;
switch
(
ACCESS_FBINFO
(
outputs
[
i
]).
src
)
{
case
MATROXFB_SRC_NONE
:
case
MATROXFB_SRC_CRTC1
:
break
;
default:
return
-
EBUSY
;
}
}
}
if
(
tmp
==
ACCESS_FBINFO
(
output
.
ph
))
if
(
ACCESS_FBINFO
(
devflags
.
panellink
))
{
if
(
tmp
&
MATROXFB_OUTPUT_CONN_DFP
)
{
if
(
tmp
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
return
-
EINVAL
;
for
(
i
=
0
;
i
<
MATROXFB_MAX_OUTPUTS
;
i
++
)
{
if
(
ACCESS_FBINFO
(
outputs
[
i
]).
src
==
MATROXFB_SRC_CRTC2
)
{
return
-
EBUSY
;
}
}
}
}
changes
=
0
;
for
(
i
=
0
;
i
<
MATROXFB_MAX_OUTPUTS
;
i
++
)
{
if
(
tmp
&
(
1
<<
i
))
{
if
(
ACCESS_FBINFO
(
outputs
[
i
]).
src
!=
MATROXFB_SRC_CRTC1
)
{
changes
=
1
;
ACCESS_FBINFO
(
outputs
[
i
]).
src
=
MATROXFB_SRC_CRTC1
;
}
}
else
if
(
ACCESS_FBINFO
(
outputs
[
i
]).
src
==
MATROXFB_SRC_CRTC1
)
{
changes
=
1
;
ACCESS_FBINFO
(
outputs
[
i
]).
src
=
MATROXFB_SRC_NONE
;
}
}
if
(
!
changes
)
return
0
;
ACCESS_FBINFO
(
output
.
ph
)
=
tmp
;
matroxfb_switch
(
ACCESS_FBINFO
(
fbcon
.
currcon
),
info
);
return
0
;
}
case
MATROXFB_GET_OUTPUT_CONNECTION
:
{
if
(
put_user
(
ACCESS_FBINFO
(
output
.
ph
),
(
u_int32_t
*
)
arg
))
u_int32_t
conn
=
0
;
int
i
;
for
(
i
=
0
;
i
<
MATROXFB_MAX_OUTPUTS
;
i
++
)
{
if
(
ACCESS_FBINFO
(
outputs
[
i
]).
src
==
MATROXFB_SRC_CRTC1
)
{
conn
|=
1
<<
i
;
}
}
if
(
put_user
(
conn
,
(
u_int32_t
*
)
arg
))
return
-
EFAULT
;
return
0
;
}
case
MATROXFB_GET_AVAILABLE_OUTPUTS
:
{
u_int32_t
tmp
;
tmp
=
ACCESS_FBINFO
(
output
.
all
)
&
~
ACCESS_FBINFO
(
output
.
sh
);
if
(
ACCESS_FBINFO
(
output
.
ph
)
&
MATROXFB_OUTPUT_CONN_DFP
)
tmp
&=
~
MATROXFB_OUTPUT_CONN_SECONDARY
;
if
(
ACCESS_FBINFO
(
output
.
ph
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
tmp
&=
~
MATROXFB_OUTPUT_CONN_DFP
;
if
(
put_user
(
tmp
,
(
u_int32_t
*
)
arg
))
u_int32_t
conn
=
0
;
int
i
;
for
(
i
=
0
;
i
<
MATROXFB_MAX_OUTPUTS
;
i
++
)
{
if
(
ACCESS_FBINFO
(
outputs
[
i
]).
output
)
{
switch
(
ACCESS_FBINFO
(
outputs
[
i
]).
src
)
{
case
MATROXFB_SRC_NONE
:
case
MATROXFB_SRC_CRTC1
:
conn
|=
1
<<
i
;
break
;
}
}
}
if
(
ACCESS_FBINFO
(
devflags
.
panellink
))
{
if
(
conn
&
MATROXFB_OUTPUT_CONN_DFP
)
conn
&=
~
MATROXFB_OUTPUT_CONN_SECONDARY
;
if
(
conn
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
conn
&=
~
MATROXFB_OUTPUT_CONN_DFP
;
}
if
(
put_user
(
conn
,
(
u_int32_t
*
)
arg
))
return
-
EFAULT
;
return
0
;
}
case
MATROXFB_GET_ALL_OUTPUTS
:
{
if
(
put_user
(
ACCESS_FBINFO
(
output
.
all
),
(
u_int32_t
*
)
arg
))
u_int32_t
conn
=
0
;
int
i
;
for
(
i
=
0
;
i
<
MATROXFB_MAX_OUTPUTS
;
i
++
)
{
if
(
ACCESS_FBINFO
(
outputs
[
i
]).
output
)
{
conn
|=
1
<<
i
;
}
}
if
(
put_user
(
conn
,
(
u_int32_t
*
)
arg
))
return
-
EFAULT
;
return
0
;
}
}
return
-
E
INVAL
;
return
-
E
NOTTY
;
#undef minfo
}
...
...
@@ -1150,7 +1151,7 @@ static int matroxfb_ioctl(struct inode *inode, struct file *file,
static
int
matroxfb_blank
(
int
blank
,
struct
fb_info
*
info
)
{
#define minfo (
(struct matrox_fb_info*)info
)
#define minfo (
container_of(info, struct matrox_fb_info, fbcon)
)
int
seq
;
int
crtc
;
CRITFLAGS
...
...
@@ -1184,8 +1185,6 @@ static struct fb_ops matroxfb_ops = {
.
owner
=
THIS_MODULE
,
.
fb_open
=
matroxfb_open
,
.
fb_release
=
matroxfb_release
,
.
fb_get_fix
=
matroxfb_get_fix
,
.
fb_get_var
=
matroxfb_get_var
,
.
fb_set_var
=
matroxfb_set_var
,
.
fb_get_cmap
=
matroxfb_get_cmap
,
.
fb_set_cmap
=
matroxfb_set_cmap
,
...
...
@@ -1197,7 +1196,7 @@ static struct fb_ops matroxfb_ops = {
int
matroxfb_switch
(
int
con
,
struct
fb_info
*
info
)
{
#define minfo (
(struct matrox_fb_info*)info
)
#define minfo (
container_of(info, struct matrox_fb_info, fbcon)
)
struct
fb_cmap
*
cmap
;
struct
display
*
p
;
...
...
@@ -1392,10 +1391,10 @@ static struct video_board vbG400 = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG4
#define DEVF_VIDEO64BIT 0x0001
#define DEVF_SWAPS 0x0002
#define DEVF_SRCORG 0x0004
#define DEVF_
BOTHDACS 0x0008
/* put CRTC1 on both outputs by default */
#define DEVF_
DUALHEAD 0x0008
#define DEVF_CROSS4MB 0x0010
#define DEVF_TEXT4B 0x0020
#define DEVF_DDC_8_2 0x0040
/* #define DEVF_recycled 0x0040 */
/* #define DEVF_recycled 0x0080 */
#define DEVF_SUPPORT32MB 0x0100
#define DEVF_ANY_VXRES 0x0200
...
...
@@ -1405,14 +1404,14 @@ static struct video_board vbG400 = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG4
#define DEVF_PANELLINK_CAPABLE 0x2000
#define DEVF_G450DAC 0x4000
#define DEVF_GCORE (DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB
| DEVF_DDC_8_2
)
#define DEVF_G2CORE (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_MAVEN_CAPABLE | DEVF_PANELLINK_CAPABLE | DEVF_SRCORG)
#define DEVF_GCORE (DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB)
#define DEVF_G2CORE (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_MAVEN_CAPABLE | DEVF_PANELLINK_CAPABLE | DEVF_SRCORG
| DEVF_DUALHEAD
)
#define DEVF_G100 (DEVF_GCORE)
/* no doc, no vxres... */
#define DEVF_G200 (DEVF_G2CORE)
#define DEVF_G400 (DEVF_G2CORE | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2)
/* if you'll find how to drive DFP... */
#define DEVF_G450 (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2 | DEVF_G450DAC | DEVF_SRCORG)
#define DEVF_G550 (DEVF_G450
| DEVF_BOTHDACS
)
#define DEVF_G450 (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2 | DEVF_G450DAC | DEVF_SRCORG
| DEVF_DUALHEAD
)
#define DEVF_G550 (DEVF_G450)
static
struct
board
{
unsigned
short
vendor
,
device
,
rev
,
svid
,
sid
;
...
...
@@ -1606,27 +1605,24 @@ static int initMatrox2(WPMINFO struct display* d, struct board* b){
ACCESS_FBINFO
(
devflags
.
text_type_aux
)
=
FB_AUX_TEXT_MGA_STEP8
;
}
#ifdef CONFIG_FB_MATROX_32MB
ACCESS_FBINFO
(
devflags
.
support32MB
)
=
b
->
flags
&
DEVF_SUPPORT32MB
;
ACCESS_FBINFO
(
devflags
.
support32MB
)
=
(
b
->
flags
&
DEVF_SUPPORT32MB
)
!=
0
;
#endif
ACCESS_FBINFO
(
devflags
.
precise_width
)
=
!
(
b
->
flags
&
DEVF_ANY_VXRES
);
ACCESS_FBINFO
(
devflags
.
crtc2
)
=
b
->
flags
&
DEVF_CRTC2
;
ACCESS_FBINFO
(
devflags
.
maven_capable
)
=
b
->
flags
&
DEVF_MAVEN_CAPABLE
;
ACCESS_FBINFO
(
devflags
.
crtc2
)
=
(
b
->
flags
&
DEVF_CRTC2
)
!=
0
;
ACCESS_FBINFO
(
devflags
.
maven_capable
)
=
(
b
->
flags
&
DEVF_MAVEN_CAPABLE
)
!=
0
;
ACCESS_FBINFO
(
devflags
.
dualhead
)
=
(
b
->
flags
&
DEVF_DUALHEAD
)
!=
0
;
if
(
b
->
flags
&
DEVF_PANELLINK_CAPABLE
)
{
ACCESS_FBINFO
(
output
.
all
)
|=
MATROXFB_OUTPUT_CONN_DFP
;
ACCESS_FBINFO
(
outputs
[
2
]).
data
=
MINFO
;
ACCESS_FBINFO
(
outputs
[
2
]).
output
=
&
panellink_output
;
if
(
dfp
)
ACCESS_FBINFO
(
output
.
ph
)
|=
MATROXFB_OUTPUT_CONN_DFP
;
}
if
(
b
->
flags
&
DEVF_BOTHDACS
)
{
#ifdef CONFIG_FB_MATROX_G450
ACCESS_FBINFO
(
output
.
all
)
|=
MATROXFB_OUTPUT_CONN_SECONDARY
;
ACCESS_FBINFO
(
output
.
ph
)
|=
MATROXFB_OUTPUT_CONN_SECONDARY
;
#else
printk
(
KERN_INFO
"Only digital output of G550 is now working (in analog mode). Enable G450 support in
\n
"
);
printk
(
KERN_INFO
"kernel configuration if you have analog monitor connected to G550 analog output.
\n
"
);
#endif
ACCESS_FBINFO
(
outputs
[
2
]).
src
=
MATROXFB_SRC_CRTC1
;
else
ACCESS_FBINFO
(
outputs
[
2
]).
src
=
MATROXFB_SRC_NONE
;
ACCESS_FBINFO
(
outputs
[
2
]).
mode
=
MATROXFB_OUTPUT_MODE_MONITOR
;
ACCESS_FBINFO
(
devflags
.
panellink
)
=
1
;
}
ACCESS_FBINFO
(
devflags
.
dfp_type
)
=
dfp_type
;
ACCESS_FBINFO
(
devflags
.
g450dac
)
=
b
->
flags
&
DEVF_G450DAC
;
ACCESS_FBINFO
(
devflags
.
g450dac
)
=
(
b
->
flags
&
DEVF_G450DAC
)
!=
0
;
ACCESS_FBINFO
(
devflags
.
textstep
)
=
ACCESS_FBINFO
(
devflags
.
vgastep
)
*
ACCESS_FBINFO
(
devflags
.
textmode
);
ACCESS_FBINFO
(
devflags
.
textvram
)
=
65536
/
ACCESS_FBINFO
(
devflags
.
textmode
);
...
...
@@ -1732,6 +1728,7 @@ static int initMatrox2(WPMINFO struct display* d, struct board* b){
if
(
!
ACCESS_FBINFO
(
devflags
.
novga
))
request_region
(
0x3C0
,
32
,
"matrox"
);
matroxfb_g450_connect
(
PMINFO2
);
ACCESS_FBINFO
(
hw_switch
->
reset
(
PMINFO2
));
ACCESS_FBINFO
(
fbcon
.
monspecs
.
hfmin
)
=
0
;
...
...
@@ -1885,6 +1882,7 @@ static int initMatrox2(WPMINFO struct display* d, struct board* b){
}
return
0
;
failVideoIO:
;
matroxfb_g450_shutdown
(
PMINFO2
);
mga_iounmap
(
ACCESS_FBINFO
(
video
.
vbase
));
failCtrlIO:
;
mga_iounmap
(
ACCESS_FBINFO
(
mmio
.
vbase
));
...
...
@@ -2072,10 +2070,6 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm
init_rwsem
(
&
ACCESS_FBINFO
(
crtc2
.
lock
));
init_rwsem
(
&
ACCESS_FBINFO
(
altout
.
lock
));
ACCESS_FBINFO
(
output
.
all
)
=
MATROXFB_OUTPUT_CONN_PRIMARY
;
ACCESS_FBINFO
(
output
.
ph
)
=
MATROXFB_OUTPUT_CONN_PRIMARY
;
ACCESS_FBINFO
(
output
.
sh
)
=
0
;
err
=
initMatrox2
(
PMINFO
d
,
b
);
if
(
!
err
)
{
#ifndef CONFIG_FB_MATROX_MULTIHEAD
...
...
@@ -2489,8 +2483,8 @@ int __init matroxfb_init(void)
/* *************************** init module code **************************** */
MODULE_AUTHOR
(
"(c) 1998-200
1
Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_DESCRIPTION
(
"Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400/G450"
);
MODULE_AUTHOR
(
"(c) 1998-200
2
Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_DESCRIPTION
(
"Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400/G450
/G550
"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_PARM
(
mem
,
"i"
);
...
...
drivers/video/matrox/matroxfb_base.h
View file @
062dffea
...
...
@@ -2,7 +2,7 @@
*
* Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450
*
* (c) 1998
,1999,2000,2001
Petr Vandrovec <vandrove@vc.cvut.cz>
* (c) 1998
-2002
Petr Vandrovec <vandrove@vc.cvut.cz>
*
*/
#ifndef __MATROXFB_H__
...
...
@@ -288,6 +288,8 @@ static inline void mga_iounmap(vaddr_t va) {
struct
my_timming
{
unsigned
int
pixclock
;
int
mnp
;
unsigned
int
crtc
;
unsigned
int
HDisplay
;
unsigned
int
HSyncStart
;
unsigned
int
HSyncEnd
;
...
...
@@ -364,6 +366,10 @@ struct mavenregs {
u_int16_t
hcorr
;
};
struct
matrox_crtc2
{
u_int32_t
ctl
;
};
struct
matrox_hw_state
{
u_int32_t
MXoptionReg
;
unsigned
char
DACclk
[
6
];
...
...
@@ -381,10 +387,7 @@ struct matrox_hw_state {
/* TVOut only */
struct
mavenregs
maven
;
/* CRTC2 only */
/* u_int32_t TBD */
unsigned
int
vidclk
;
struct
matrox_crtc2
crtc2
;
};
struct
matrox_accel_data
{
...
...
@@ -396,15 +399,17 @@ struct matrox_accel_data {
};
struct
matrox_altout
{
const
char
*
name
;
int
(
*
compute
)(
void
*
altout_dev
,
struct
my_timming
*
input
);
int
(
*
program
)(
void
*
altout_dev
);
int
(
*
start
)(
void
*
altout_dev
);
void
(
*
incuse
)(
void
*
altout_dev
);
void
(
*
decuse
)(
void
*
altout_dev
);
int
(
*
setmode
)(
void
*
altout_dev
,
u_int32_t
mode
);
int
(
*
getmode
)(
void
*
altout_dev
,
u_int32_t
*
mode
);
int
(
*
verifymode
)(
void
*
altout_dev
,
u_int32_t
mode
);
};
#define MATROXFB_SRC_NONE 0
#define MATROXFB_SRC_CRTC1 1
#define MATROXFB_SRC_CRTC2 2
enum
mga_chip
{
MGA_2064
,
MGA_2164
,
MGA_1064
,
MGA_1164
,
MGA_G100
,
MGA_G200
,
MGA_G400
,
MGA_G450
,
MGA_G550
};
struct
matrox_bios
{
...
...
@@ -421,9 +426,9 @@ struct matrox_bios {
struct
matrox_switch
;
struct
matroxfb_driver
;
struct
matroxfb_dh_fb_info
;
struct
matrox_fb_info
{
/* fb_info must be first */
struct
fb_info
fbcon
;
struct
list_head
next_fb
;
...
...
@@ -439,20 +444,25 @@ struct matrox_fb_info {
struct
pci_dev
*
pcidev
;
struct
{
u_int32_t
all
;
u_int32_t
ph
;
u_int32_t
sh
;
}
output
;
struct
matrox_altout
*
primout
;
unsigned
int
pixclock
;
int
mnp
;
}
crtc1
;
struct
{
struct
fb_info
*
info
;
unsigned
int
pixclock
;
int
mnp
;
struct
matroxfb_dh_fb_info
*
info
;
struct
rw_semaphore
lock
;
}
crtc2
;
struct
{
struct
matrox_altout
*
output
;
void
*
device
;
struct
rw_semaphore
lock
;
struct
rw_semaphore
lock
;
}
altout
;
#define MATROXFB_MAX_OUTPUTS 3
struct
{
unsigned
int
src
;
struct
matrox_altout
*
output
;
void
*
data
;
unsigned
int
mode
;
}
outputs
[
MATROXFB_MAX_OUTPUTS
];
#define MATROXFB_MAX_FB_DRIVERS 5
struct
matroxfb_driver
*
(
drivers
[
MATROXFB_MAX_FB_DRIVERS
]);
...
...
@@ -541,6 +551,8 @@ struct matrox_fb_info {
int
memtype
;
int
g450dac
;
int
dfp_type
;
int
panellink
;
/* G400 DFP possible (not G450/G550) */
int
dualhead
;
unsigned
int
fbResource
;
}
devflags
;
struct
display_switch
dispsw
;
...
...
@@ -618,7 +630,7 @@ struct matrox_fb_info {
#define PMINFO PMINFO2 ,
static
inline
struct
matrox_fb_info
*
mxinfo
(
const
struct
display
*
p
)
{
return
(
struct
matrox_fb_info
*
)
p
->
fb_info
;
return
container_of
(
p
->
fb_info
,
struct
matrox_fb_info
,
fbcon
)
;
}
#define PMXINFO(p) mxinfo(p),
...
...
@@ -658,7 +670,7 @@ struct matrox_switch {
void
(
*
reset
)(
WPMINFO2
);
int
(
*
init
)(
WPMINFO
struct
my_timming
*
,
struct
display
*
);
void
(
*
restore
)(
WPMINFO
struct
display
*
);
int
(
*
selhwcursor
)(
WPMINFO
struct
display
*
);
int
(
*
selhwcursor
)(
WPMINFO
2
);
};
struct
matroxfb_driver
{
...
...
drivers/video/matrox/matroxfb_crtc2.c
View file @
062dffea
...
...
@@ -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
5 2002/08/14
*
*/
...
...
@@ -28,7 +28,7 @@ MODULE_PARM_DESC(mem, "Memory size reserved for dualhead (default=8MB)");
static
int
matroxfb_dh_getcolreg
(
unsigned
regno
,
unsigned
*
red
,
unsigned
*
green
,
unsigned
*
blue
,
unsigned
*
transp
,
struct
fb_info
*
info
)
{
#define m2info (
(struct matroxfb_dh_fb_info*)info
)
#define m2info (
container_of(info, struct matroxfb_dh_fb_info, fbcon)
)
if
(
regno
>=
16
)
return
1
;
*
red
=
m2info
->
palette
[
regno
].
red
;
...
...
@@ -41,8 +41,7 @@ static int matroxfb_dh_getcolreg(unsigned regno, unsigned *red, unsigned *green,
static
int
matroxfb_dh_setcolreg
(
unsigned
regno
,
unsigned
red
,
unsigned
green
,
unsigned
blue
,
unsigned
transp
,
struct
fb_info
*
info
)
{
#define m2info ((struct matroxfb_dh_fb_info*)info)
struct
display
*
p
;
#define m2info (container_of(info, struct matroxfb_dh_fb_info, fbcon))
if
(
regno
>=
16
)
return
1
;
...
...
@@ -50,33 +49,32 @@ static int matroxfb_dh_setcolreg(unsigned regno, unsigned red, unsigned green,
m2info
->
palette
[
regno
].
blue
=
blue
;
m2info
->
palette
[
regno
].
green
=
green
;
m2info
->
palette
[
regno
].
transp
=
transp
;
p
=
m2info
->
currcon_display
;
if
(
p
->
var
.
grayscale
)
{
if
(
m2info
->
fbcon
.
var
.
grayscale
)
{
/* gray = 0.30*R + 0.59*G + 0.11*B */
red
=
green
=
blue
=
(
red
*
77
+
green
*
151
+
blue
*
28
)
>>
8
;
}
red
=
CNVT_TOHW
(
red
,
p
->
var
.
red
.
length
);
green
=
CNVT_TOHW
(
green
,
p
->
var
.
green
.
length
);
blue
=
CNVT_TOHW
(
blue
,
p
->
var
.
blue
.
length
);
transp
=
CNVT_TOHW
(
transp
,
p
->
var
.
transp
.
length
);
red
=
CNVT_TOHW
(
red
,
m2info
->
fbcon
.
var
.
red
.
length
);
green
=
CNVT_TOHW
(
green
,
m2info
->
fbcon
.
var
.
green
.
length
);
blue
=
CNVT_TOHW
(
blue
,
m2info
->
fbcon
.
var
.
blue
.
length
);
transp
=
CNVT_TOHW
(
transp
,
m2info
->
fbcon
.
var
.
transp
.
length
);
switch
(
p
->
var
.
bits_per_pixel
)
{
switch
(
m2info
->
fbcon
.
var
.
bits_per_pixel
)
{
#ifdef FBCON_HAS_CFB16
case
16
:
m2info
->
cmap
.
cfb16
[
regno
]
=
(
red
<<
p
->
var
.
red
.
offset
)
|
(
green
<<
p
->
var
.
green
.
offset
)
|
(
blue
<<
p
->
var
.
blue
.
offset
)
|
(
transp
<<
p
->
var
.
transp
.
offset
);
(
red
<<
m2info
->
fbcon
.
var
.
red
.
offset
)
|
(
green
<<
m2info
->
fbcon
.
var
.
green
.
offset
)
|
(
blue
<<
m2info
->
fbcon
.
var
.
blue
.
offset
)
|
(
transp
<<
m2info
->
fbcon
.
var
.
transp
.
offset
);
break
;
#endif
#ifdef FBCON_HAS_CFB32
case
32
:
m2info
->
cmap
.
cfb32
[
regno
]
=
(
red
<<
p
->
var
.
red
.
offset
)
|
(
green
<<
p
->
var
.
green
.
offset
)
|
(
blue
<<
p
->
var
.
blue
.
offset
)
|
(
transp
<<
p
->
var
.
transp
.
offset
);
(
red
<<
m2info
->
fbcon
.
var
.
red
.
offset
)
|
(
green
<<
m2info
->
fbcon
.
var
.
green
.
offset
)
|
(
blue
<<
m2info
->
fbcon
.
var
.
blue
.
offset
)
|
(
transp
<<
m2info
->
fbcon
.
var
.
transp
.
offset
);
break
;
#endif
}
...
...
@@ -99,10 +97,10 @@ static inline void my_install_cmap(struct matroxfb_dh_fb_info* m2info)
static
void
matroxfb_dh_restore
(
struct
matroxfb_dh_fb_info
*
m2info
,
struct
my_timming
*
mt
,
struct
display
*
p
,
int
mode
,
unsigned
int
pos
)
{
u_int32_t
tmp
;
u_int32_t
datactl
;
MINFO_FROM
(
m2info
->
primary_dev
);
switch
(
mode
)
{
...
...
@@ -117,26 +115,26 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
tmp
=
0x00800000
;
break
;
}
if
(
ACCESS_FBINFO
(
output
.
sh
))
{
tmp
|=
0x00000001
;
/* enable CRTC2 */
if
(
ACCESS_FBINFO
(
output
.
sh
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
{
if
(
ACCESS_FBINFO
(
devflags
.
g450dac
))
{
tmp
|=
0x00000006
;
/* source from secondary pixel PLL */
/* no vidrst */
}
else
{
tmp
|=
0x00000002
;
/* source from VDOCLK */
tmp
|=
0xC0000000
;
/* enable vvidrst & hvidrst */
/* MGA TVO is our clock source */
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 when in monitor mode */
if
(
ACCESS_FBINFO
(
outputs
[
1
]).
mode
!=
MATROXFB_OUTPUT_MODE_MONITOR
)
{
tmp
|=
0xC0001000
;
/* Enable H/V vidrst */
}
}
else
if
(
ACCESS_FBINFO
(
output
.
sh
)
&
MATROXFB_OUTPUT_CONN_PRIMARY
)
{
tmp
|=
0x00000004
;
/* source from pixclock */
/* PIXPLL is our clock source */
}
else
{
tmp
|=
0x00000002
;
/* source from VDOCLK */
tmp
|=
0xC0000000
;
/* enable vvidrst & hvidrst */
/* MGA TVO is our clock source */
}
if
(
ACCESS_FBINFO
(
output
.
sh
)
&
MATROXFB_OUTPUT_CONN_PRIMARY
)
tmp
|=
0x00100000
;
/* connect CRTC2 to DAC */
}
else
if
(
ACCESS_FBINFO
(
outputs
[
0
]).
src
==
MATROXFB_SRC_CRTC2
)
{
tmp
|=
0x00000004
;
/* source from pixclock */
/* PIXPLL is our clock source */
}
if
(
ACCESS_FBINFO
(
outputs
[
0
]).
src
==
MATROXFB_SRC_CRTC2
)
{
tmp
|=
0x00100000
;
/* connect CRTC2 to DAC */
}
if
(
mt
->
interlaced
)
{
tmp
|=
0x02000000
;
/* interlaced, second field is bigger, as G450 apparently ignores it */
...
...
@@ -145,35 +143,63 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
mt
->
VSyncEnd
>>=
1
;
mt
->
VTotal
>>=
1
;
}
mga_outl
(
0x3C10
,
tmp
|
0x10000000
);
/* depth and so on... 0x10000000 is VIDRST polarity */
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
));
mga_outl
(
0x3C1C
,
((
mt
->
VDisplay
-
1
)
<<
16
)
|
(
mt
->
VTotal
-
1
));
mga_outl
(
0x3C20
,
((
mt
->
VSyncEnd
-
1
)
<<
16
)
|
(
mt
->
VSyncStart
-
1
));
mga_outl
(
0x3C24
,
((
mt
->
VSyncStart
)
<<
16
)
|
(
mt
->
HSyncStart
));
/* preload */
{
u_int32_t
linelen
=
p
->
var
.
xres_virtual
*
(
p
->
var
.
bits_per_pixel
>>
3
);
if
(
mt
->
interlaced
)
{
u_int32_t
linelen
=
m2info
->
fbcon
.
var
.
xres_virtual
*
(
m2info
->
fbcon
.
var
.
bits_per_pixel
>>
3
);
if
(
tmp
&
0x02000000
)
{
/* field #0 is smaller, so... */
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
,
datactl
);
/* data control */
if
(
tmp
&
0x02000000
)
{
int
i
;
mga_outl
(
0x3C10
,
tmp
&
~
0x02000000
);
for
(
i
=
0
;
i
<
2
;
i
++
)
{
unsigned
int
nl
;
unsigned
int
lastl
=
0
;
while
((
nl
=
mga_inl
(
0x3C48
)
&
0xFFF
)
>=
lastl
)
{
lastl
=
nl
;
}
}
}
mga_outl
(
0x3C10
,
tmp
);
ACCESS_FBINFO
(
hw
).
crtc2
.
ctl
=
tmp
;
tmp
=
0x0FFF0000
;
/* line compare */
if
(
mt
->
sync
&
FB_SYNC_HOR_HIGH_ACT
)
tmp
|=
0x00000100
;
if
(
mt
->
sync
&
FB_SYNC_VERT_HIGH_ACT
)
tmp
|=
0x00000200
;
mga_outl
(
0x3C44
,
tmp
);
mga_outl
(
0x3C4C
,
0
);
/* data control */
}
static
void
matroxfb_dh_cfbX_init
(
struct
matroxfb_dh_fb_info
*
m2info
,
struct
display
*
p
)
{
static
void
matroxfb_dh_disable
(
struct
matroxfb_dh_fb_info
*
m2info
)
{
MINFO_FROM
(
m2info
->
primary_dev
);
mga_outl
(
0x3C10
,
0x00000004
);
/* disable CRTC2, CRTC1->DAC1, PLL as clock source */
ACCESS_FBINFO
(
hw
).
crtc2
.
ctl
=
0x00000004
;
}
static
void
matroxfb_dh_cfbX_init
(
struct
matroxfb_dh_fb_info
*
m2info
)
{
/* no acceleration for secondary head... */
}
...
...
@@ -182,23 +208,23 @@ static void matroxfb_dh_pan_var(struct matroxfb_dh_fb_info* m2info,
unsigned
int
pos
;
unsigned
int
linelen
;
unsigned
int
pixelsize
;
MINFO_FROM
(
m2info
->
primary_dev
);
#define minfo (m2info->primary_dev)
pixelsize
=
var
->
bits_per_pixel
>>
3
;
linelen
=
var
->
xres_virtual
*
pixelsize
;
pos
=
var
->
yoffset
*
linelen
+
var
->
xoffset
*
pixelsize
;
m2info
->
fbcon
.
var
.
xoffset
=
var
->
xoffset
;
m2info
->
fbcon
.
var
.
yoffset
=
var
->
yoffset
;
pixelsize
=
m2info
->
fbcon
.
var
.
bits_per_pixel
>>
3
;
linelen
=
m2info
->
fbcon
.
var
.
xres_virtual
*
pixelsize
;
pos
=
m2info
->
fbcon
.
var
.
yoffset
*
linelen
+
m2info
->
fbcon
.
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
{
mga_outl
(
0x3C28
,
pos
);
}
#undef minfo
}
static
int
matroxfb_dh_decode_var
(
struct
matroxfb_dh_fb_info
*
m2info
,
struct
display
*
p
,
struct
fb_var_screeninfo
*
var
,
int
*
visual
,
int
*
video_cmap_len
,
...
...
@@ -277,7 +303,7 @@ static int matroxfb_dh_decode_var(struct matroxfb_dh_fb_info* m2info,
}
static
void
initMatroxDH
(
struct
matroxfb_dh_fb_info
*
m2info
,
struct
display
*
p
)
{
switch
(
p
->
var
.
bits_per_pixel
)
{
switch
(
m2info
->
fbcon
.
var
.
bits_per_pixel
)
{
#ifdef FBCON_HAS_CFB16
case
16
:
p
->
dispsw_data
=
m2info
->
cmap
.
cfb16
;
...
...
@@ -298,7 +324,7 @@ static void initMatroxDH(struct matroxfb_dh_fb_info* m2info, struct display* p)
}
static
int
matroxfb_dh_open
(
struct
fb_info
*
info
,
int
user
)
{
#define m2info (
(struct matroxfb_dh_fb_info*)info
)
#define m2info (
container_of(info, struct matroxfb_dh_fb_info, fbcon)
)
MINFO_FROM
(
m2info
->
primary_dev
);
if
(
MINFO
)
{
...
...
@@ -311,7 +337,7 @@ static int matroxfb_dh_open(struct fb_info* info, int user) {
}
static
int
matroxfb_dh_release
(
struct
fb_info
*
info
,
int
user
)
{
#define m2info (
(struct matroxfb_dh_fb_info*)info
)
#define m2info (
container_of(info, struct matroxfb_dh_fb_info, fbcon)
)
MINFO_FROM
(
m2info
->
primary_dev
);
if
(
MINFO
)
{
...
...
@@ -320,49 +346,24 @@ static int matroxfb_dh_release(struct fb_info* info, int user) {
#undef m2info
}
static
int
matroxfb_dh_get_fix
(
struct
fb_fix_screeninfo
*
fix
,
int
con
,
struct
fb_info
*
info
)
{
#define m2info ((struct matroxfb_dh_fb_info*)info)
struct
display
*
p
;
static
void
matroxfb_dh_update_fix
(
struct
matroxfb_dh_fb_info
*
m2info
)
{
struct
fb_fix_screeninfo
*
fix
=
&
m2info
->
fbcon
.
fix
;
if
(
con
>=
0
)
p
=
fb_display
+
con
;
else
p
=
m2info
->
fbcon
.
disp
;
memset
(
fix
,
0
,
sizeof
(
*
fix
));
strcpy
(
fix
->
id
,
"MATROX DH"
);
fix
->
smem_start
=
m2info
->
video
.
base
;
fix
->
smem_len
=
m2info
->
video
.
len_usable
;
fix
->
type
=
p
->
type
;
fix
->
type_aux
=
p
->
type_aux
;
fix
->
visual
=
p
->
visual
;
fix
->
xpanstep
=
8
;
/* TBD */
fix
->
ypanstep
=
1
;
fix
->
ywrapstep
=
0
;
fix
->
line_length
=
p
->
line_length
;
fix
->
xpanstep
=
8
;
/* TBD */
fix
->
mmio_start
=
m2info
->
mmio
.
base
;
fix
->
mmio_len
=
m2info
->
mmio
.
len
;
fix
->
accel
=
0
;
/* no accel... */
return
0
;
#undef m2info
}
static
int
matroxfb_dh_get_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
info
)
{
#define m2info ((struct matroxfb_dh_fb_info*)info)
if
(
con
<
0
)
*
var
=
m2info
->
fbcon
.
disp
->
var
;
else
*
var
=
fb_display
[
con
].
var
;
return
0
;
#undef m2info
}
static
int
matroxfb_dh_set_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
info
)
{
#define m2info (
(struct matroxfb_dh_fb_info*)info
)
#define m2info (
container_of(info, struct matroxfb_dh_fb_info, fbcon)
)
struct
display
*
p
;
int
chgvar
;
int
visual
;
...
...
@@ -375,7 +376,7 @@ static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con,
p
=
m2info
->
fbcon
.
disp
;
else
p
=
fb_display
+
con
;
if
((
err
=
matroxfb_dh_decode_var
(
m2info
,
p
,
var
,
&
visual
,
&
cmap_len
,
&
mode
))
!=
0
)
if
((
err
=
matroxfb_dh_decode_var
(
m2info
,
var
,
&
visual
,
&
cmap_len
,
&
mode
))
!=
0
)
return
err
;
switch
(
var
->
activate
&
FB_ACTIVATE_MASK
)
{
case
FB_ACTIVATE_TEST
:
return
0
;
...
...
@@ -396,13 +397,15 @@ static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con,
chgvar
=
0
;
p
->
var
=
*
var
;
/* cmap */
m2info
->
fbcon
.
screen_base
=
vaddr_va
(
m2info
->
video
.
vbase
);
p
->
visual
=
visual
;
p
->
ypanstep
=
1
;
p
->
ywrapstep
=
0
;
p
->
type
=
FB_TYPE_PACKED_PIXELS
;
p
->
type_aux
=
0
;
p
->
next_line
=
p
->
line_length
=
(
var
->
xres_virtual
*
var
->
bits_per_pixel
)
>>
3
;
if
(
con
==
m2info
->
fbcon
.
currcon
)
{
m2info
->
fbcon
.
screen_base
=
vaddr_va
(
m2info
->
video
.
vbase
);
m2info
->
fbcon
.
var
=
*
var
;
m2info
->
fbcon
.
fix
.
visual
=
visual
;
m2info
->
fbcon
.
fix
.
type
=
FB_TYPE_PACKED_PIXELS
;
m2info
->
fbcon
.
fix
.
type_aux
=
0
;
p
->
next_line
=
m2info
->
fbcon
.
fix
.
line_length
=
(
var
->
xres_virtual
*
var
->
bits_per_pixel
)
>>
3
;
matroxfb_dh_update_fix
(
m2info
);
}
p
->
can_soft_blank
=
0
;
p
->
inverse
=
0
;
/* TBD */
initMatroxDH
(
m2info
,
p
);
...
...
@@ -411,47 +414,51 @@ static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con,
if
(
con
==
m2info
->
fbcon
.
currcon
)
{
struct
my_timming
mt
;
unsigned
int
pos
;
int
out
;
int
cnt
;
matroxfb_var2my
(
var
,
&
mt
);
matroxfb_var2my
(
&
m2info
->
fbcon
.
var
,
&
mt
);
mt
.
crtc
=
MATROXFB_SRC_CRTC2
;
/* CRTC2 delay */
mt
.
delay
=
34
;
pos
=
(
var
->
yoffset
*
var
->
xres_virtual
+
var
->
xoffset
)
*
var
->
bits_per_pixel
>>
3
;
pos
=
(
m2info
->
fbcon
.
var
.
yoffset
*
m2info
->
fbcon
.
var
.
xres_virtual
+
m2info
->
fbcon
.
var
.
xoffset
)
*
m2info
->
fbcon
.
var
.
bits_per_pixel
>>
3
;
pos
+=
m2info
->
video
.
offbase
;
DAC1064_global_init
(
PMINFO2
);
if
(
ACCESS_FBINFO
(
output
.
sh
)
&
MATROXFB_OUTPUT_CONN_PRIMARY
)
{
if
(
ACCESS_FBINFO
(
primout
))
ACCESS_FBINFO
(
primout
)
->
compute
(
MINFO
,
&
mt
);
cnt
=
0
;
down_read
(
&
ACCESS_FBINFO
(
altout
).
lock
);
for
(
out
=
0
;
out
<
MATROXFB_MAX_OUTPUTS
;
out
++
)
{
if
(
ACCESS_FBINFO
(
outputs
[
out
]).
src
==
MATROXFB_SRC_CRTC2
)
{
cnt
++
;
if
(
ACCESS_FBINFO
(
outputs
[
out
]).
output
->
compute
)
{
ACCESS_FBINFO
(
outputs
[
out
]).
output
->
compute
(
ACCESS_FBINFO
(
outputs
[
out
]).
data
,
&
mt
);
}
}
}
if
(
ACCESS_FBINFO
(
output
.
sh
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
{
down_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
if
(
ACCESS_FBINFO
(
altout
.
output
))
ACCESS_FBINFO
(
altout
.
output
)
->
compute
(
ACCESS_FBINFO
(
altout
.
device
),
&
mt
);
up_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
ACCESS_FBINFO
(
crtc2
).
pixclock
=
mt
.
pixclock
;
ACCESS_FBINFO
(
crtc2
).
mnp
=
mt
.
mnp
;
up_read
(
&
ACCESS_FBINFO
(
altout
).
lock
);
if
(
cnt
)
{
matroxfb_dh_restore
(
m2info
,
&
mt
,
mode
,
pos
);
}
else
{
matroxfb_dh_disable
(
m2info
);
}
matroxfb_dh_restore
(
m2info
,
&
mt
,
p
,
mode
,
pos
);
DAC1064_global_init
(
PMINFO2
);
DAC1064_global_restore
(
PMINFO2
);
if
(
ACCESS_FBINFO
(
output
.
sh
)
&
MATROXFB_OUTPUT_CONN_PRIMARY
)
{
if
(
ACCESS_FBINFO
(
primout
))
ACCESS_FBINFO
(
primout
)
->
program
(
MINFO
);
}
if
(
ACCESS_FBINFO
(
output
.
sh
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
{
down_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
if
(
ACCESS_FBINFO
(
altout
.
output
))
ACCESS_FBINFO
(
altout
.
output
)
->
program
(
ACCESS_FBINFO
(
altout
.
device
));
up_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
}
if
(
ACCESS_FBINFO
(
output
.
sh
)
&
MATROXFB_OUTPUT_CONN_PRIMARY
)
{
if
(
ACCESS_FBINFO
(
primout
))
ACCESS_FBINFO
(
primout
)
->
start
(
MINFO
);
down_read
(
&
ACCESS_FBINFO
(
altout
).
lock
);
for
(
out
=
0
;
out
<
MATROXFB_MAX_OUTPUTS
;
out
++
)
{
if
(
ACCESS_FBINFO
(
outputs
[
out
]).
src
==
MATROXFB_SRC_CRTC2
&&
ACCESS_FBINFO
(
outputs
[
out
]).
output
->
program
)
{
ACCESS_FBINFO
(
outputs
[
out
]).
output
->
program
(
ACCESS_FBINFO
(
outputs
[
out
]).
data
);
}
}
if
(
ACCESS_FBINFO
(
output
.
sh
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
{
down_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
if
(
ACCESS_FBINFO
(
altout
.
output
))
ACCESS_FBINFO
(
altout
.
output
)
->
start
(
ACCESS_FBINFO
(
altout
.
device
)
);
up_read
(
&
ACCESS_FBINFO
(
altout
.
lock
));
for
(
out
=
0
;
out
<
MATROXFB_MAX_OUTPUTS
;
out
++
)
{
if
(
ACCESS_FBINFO
(
outputs
[
out
]).
src
==
MATROXFB_SRC_CRTC2
&&
ACCESS_FBINFO
(
outputs
[
out
]).
output
->
start
)
{
ACCESS_FBINFO
(
outputs
[
out
]).
output
->
start
(
ACCESS_FBINFO
(
outputs
[
out
]).
data
);
}
}
matroxfb_dh_cfbX_init
(
m2info
,
p
);
up_read
(
&
ACCESS_FBINFO
(
altout
).
lock
);
matroxfb_dh_cfbX_init
(
m2info
);
my_install_cmap
(
m2info
);
}
return
0
;
...
...
@@ -460,7 +467,7 @@ static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con,
static
int
matroxfb_dh_get_cmap
(
struct
fb_cmap
*
cmap
,
int
kspc
,
int
con
,
struct
fb_info
*
info
)
{
#define m2info (
(struct matroxfb_dh_fb_info*)info
)
#define m2info (
container_of(info, struct matroxfb_dh_fb_info, fbcon)
)
struct
display
*
dsp
;
if
(
con
<
0
)
...
...
@@ -479,7 +486,7 @@ static int matroxfb_dh_get_cmap(struct fb_cmap* cmap, int kspc, int con,
static
int
matroxfb_dh_set_cmap
(
struct
fb_cmap
*
cmap
,
int
kspc
,
int
con
,
struct
fb_info
*
info
)
{
#define m2info (
(struct matroxfb_dh_fb_info*)info
)
#define m2info (
container_of(info, struct matroxfb_dh_fb_info, fbcon)
)
struct
display
*
dsp
;
if
(
con
<
0
)
...
...
@@ -503,7 +510,7 @@ static int matroxfb_dh_set_cmap(struct fb_cmap* cmap, int kspc, int con,
static
int
matroxfb_dh_pan_display
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
info
)
{
#define m2info (
(struct matroxfb_dh_fb_info*)info
)
#define m2info (
container_of(info, struct matroxfb_dh_fb_info, fbcon)
)
if
(
var
->
xoffset
+
fb_display
[
con
].
var
.
xres
>
fb_display
[
con
].
var
.
xres_virtual
||
var
->
yoffset
+
fb_display
[
con
].
var
.
yres
>
fb_display
[
con
].
var
.
yres_virtual
)
return
-
EINVAL
;
...
...
@@ -525,7 +532,7 @@ static int matroxfb_dh_get_vblank(const struct matroxfb_dh_fb_info* m2info, stru
/* mask out reserved bits + field number (odd/even) */
vblank
->
vcount
=
mga_inl
(
0x3C48
)
&
0x000007FF
;
/* compatibility stuff */
if
(
vblank
->
vcount
>=
m2info
->
currcon_display
->
var
.
yres
)
if
(
vblank
->
vcount
>=
m2info
->
fbcon
.
var
.
yres
)
vblank
->
flags
|=
FB_VBLANK_VBLANKING
;
return
0
;
}
...
...
@@ -536,7 +543,7 @@ static int matroxfb_dh_ioctl(struct inode* inode,
unsigned
long
arg
,
int
con
,
struct
fb_info
*
info
)
{
#define m2info (
(struct matroxfb_dh_fb_info*)info
)
#define m2info (
container_of(info, struct matroxfb_dh_fb_info, fbcon)
)
MINFO_FROM
(
m2info
->
primary_dev
);
DBG
(
"matroxfb_crtc2_ioctl"
)
...
...
@@ -563,49 +570,95 @@ static int matroxfb_dh_ioctl(struct inode* inode,
case
MATROXFB_SET_OUTPUT_CONNECTION
:
{
u_int32_t
tmp
;
int
out
;
int
changes
;
if
(
get_user
(
tmp
,
(
u_int32_t
*
)
arg
))
return
-
EFAULT
;
if
(
tmp
&
~
ACCESS_FBINFO
(
output
.
all
))
return
-
EINVAL
;
if
(
tmp
&
ACCESS_FBINFO
(
output
.
ph
))
return
-
EINVAL
;
if
(
tmp
&
MATROXFB_OUTPUT_CONN_DFP
)
return
-
EINVAL
;
if
((
ACCESS_FBINFO
(
output
.
ph
)
&
MATROXFB_OUTPUT_CONN_DFP
)
&&
tmp
)
return
-
EINVAL
;
if
(
tmp
==
ACCESS_FBINFO
(
output
.
sh
))
for
(
out
=
0
;
out
<
32
;
out
++
)
{
if
(
tmp
&
(
1
<<
out
))
{
if
(
out
>=
MATROXFB_MAX_OUTPUTS
)
return
-
ENXIO
;
if
(
!
ACCESS_FBINFO
(
outputs
[
out
]).
output
)
return
-
ENXIO
;
switch
(
ACCESS_FBINFO
(
outputs
[
out
]).
src
)
{
case
MATROXFB_SRC_NONE
:
case
MATROXFB_SRC_CRTC2
:
break
;
default:
return
-
EBUSY
;
}
}
}
if
(
ACCESS_FBINFO
(
devflags
.
panellink
))
{
if
(
tmp
&
MATROXFB_OUTPUT_CONN_DFP
)
return
-
EINVAL
;
if
((
ACCESS_FBINFO
(
outputs
[
2
]).
src
==
MATROXFB_SRC_CRTC1
)
&&
tmp
)
return
-
EBUSY
;
}
changes
=
0
;
for
(
out
=
0
;
out
<
MATROXFB_MAX_OUTPUTS
;
out
++
)
{
if
(
tmp
&
(
1
<<
out
))
{
if
(
ACCESS_FBINFO
(
outputs
[
out
]).
src
!=
MATROXFB_SRC_CRTC2
)
{
changes
=
1
;
ACCESS_FBINFO
(
outputs
[
out
]).
src
=
MATROXFB_SRC_CRTC2
;
}
}
else
if
(
ACCESS_FBINFO
(
outputs
[
out
]).
src
==
MATROXFB_SRC_CRTC2
)
{
changes
=
1
;
ACCESS_FBINFO
(
outputs
[
out
]).
src
=
MATROXFB_SRC_NONE
;
}
}
if
(
!
changes
)
return
0
;
ACCESS_FBINFO
(
output
.
sh
)
=
tmp
;
matroxfb_dh_switch
(
m2info
->
fbcon
.
currcon
,
info
);
return
0
;
}
case
MATROXFB_GET_OUTPUT_CONNECTION
:
{
if
(
put_user
(
ACCESS_FBINFO
(
output
.
sh
),
(
u_int32_t
*
)
arg
))
u_int32_t
conn
=
0
;
int
out
;
for
(
out
=
0
;
out
<
MATROXFB_MAX_OUTPUTS
;
out
++
)
{
if
(
ACCESS_FBINFO
(
outputs
[
out
]).
src
==
MATROXFB_SRC_CRTC2
)
{
conn
|=
1
<<
out
;
}
}
if
(
put_user
(
conn
,
(
u_int32_t
*
)
arg
))
return
-
EFAULT
;
return
0
;
}
case
MATROXFB_GET_AVAILABLE_OUTPUTS
:
{
u_int32_t
tmp
;
/* we do not support DFP from CRTC2 */
tmp
=
ACCESS_FBINFO
(
output
.
all
)
&
~
ACCESS_FBINFO
(
output
.
ph
)
&
~
MATROXFB_OUTPUT_CONN_DFP
;
/* CRTC1 in DFP mode disables CRTC2 at all (I know, I'm lazy) */
if
(
ACCESS_FBINFO
(
output
.
ph
)
&
MATROXFB_OUTPUT_CONN_DFP
)
tmp
=
0
;
u_int32_t
tmp
=
0
;
int
out
;
for
(
out
=
0
;
out
<
MATROXFB_MAX_OUTPUTS
;
out
++
)
{
if
(
ACCESS_FBINFO
(
outputs
[
out
]).
output
)
{
switch
(
ACCESS_FBINFO
(
outputs
[
out
]).
src
)
{
case
MATROXFB_SRC_NONE
:
case
MATROXFB_SRC_CRTC2
:
tmp
|=
1
<<
out
;
break
;
}
}
}
if
(
ACCESS_FBINFO
(
devflags
.
panellink
))
{
tmp
&=
~
MATROXFB_OUTPUT_CONN_DFP
;
if
(
ACCESS_FBINFO
(
outputs
[
2
]).
src
==
MATROXFB_SRC_CRTC1
)
{
tmp
=
0
;
}
}
if
(
put_user
(
tmp
,
(
u_int32_t
*
)
arg
))
return
-
EFAULT
;
return
0
;
}
}
return
-
E
INVAL
;
return
-
E
NOTTY
;
#undef m2info
}
static
int
matroxfb_dh_blank
(
int
blank
,
struct
fb_info
*
info
)
{
#define m2info (
(struct matroxfb_dh_fb_info*)info
)
#define m2info (
container_of(info, struct matroxfb_dh_fb_info, fbcon)
)
switch
(
blank
)
{
case
1
:
case
2
:
...
...
@@ -622,8 +675,6 @@ static struct fb_ops matroxfb_dh_ops = {
.
owner
=
THIS_MODULE
,
.
fb_open
=
matroxfb_dh_open
,
.
fb_release
=
matroxfb_dh_release
,
.
fb_get_fix
=
matroxfb_dh_get_fix
,
.
fb_get_var
=
matroxfb_dh_get_var
,
.
fb_set_var
=
matroxfb_dh_set_var
,
.
fb_get_cmap
=
matroxfb_dh_get_cmap
,
.
fb_set_cmap
=
matroxfb_dh_set_cmap
,
...
...
@@ -634,7 +685,7 @@ static struct fb_ops matroxfb_dh_ops = {
};
static
int
matroxfb_dh_switch
(
int
con
,
struct
fb_info
*
info
)
{
#define m2info (
(struct matroxfb_dh_fb_info*)info
)
#define m2info (
container_of(info, struct matroxfb_dh_fb_info, fbcon)
)
struct
fb_cmap
*
cmap
;
struct
display
*
p
;
...
...
@@ -657,7 +708,7 @@ static int matroxfb_dh_switch(int con, struct fb_info* info) {
}
static
int
matroxfb_dh_updatevar
(
int
con
,
struct
fb_info
*
info
)
{
#define m2info (
(struct matroxfb_dh_fb_info*)info
)
#define m2info (
container_of(info, struct matroxfb_dh_fb_info, fbcon)
)
matroxfb_dh_pan_var
(
m2info
,
&
fb_display
[
con
].
var
);
return
0
;
#undef m2info
...
...
@@ -730,11 +781,10 @@ static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) {
/*
* If we have unused output, connect CRTC2 to it...
*/
if
((
ACCESS_FBINFO
(
output
.
all
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
&&
!
(
ACCESS_FBINFO
(
output
.
ph
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
&&
!
(
ACCESS_FBINFO
(
output
.
ph
)
&
MATROXFB_OUTPUT_CONN_DFP
))
{
ACCESS_FBINFO
(
output
.
sh
)
|=
MATROXFB_OUTPUT_CONN_SECONDARY
;
ACCESS_FBINFO
(
output
.
sh
)
&=
~
MATROXFB_OUTPUT_CONN_DFP
;
if
(
ACCESS_FBINFO
(
outputs
[
1
]).
output
&&
ACCESS_FBINFO
(
outputs
[
1
]).
src
==
MATROXFB_SRC_NONE
&&
ACCESS_FBINFO
(
outputs
[
2
]).
src
==
MATROXFB_SRC_NONE
)
{
ACCESS_FBINFO
(
outputs
[
1
]).
src
=
MATROXFB_SRC_CRTC2
;
}
matroxfb_dh_set_var
(
&
matroxfb_dh_defined
,
-
2
,
&
m2info
->
fbcon
);
...
...
@@ -747,7 +797,7 @@ static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) {
}
down_write
(
&
ACCESS_FBINFO
(
crtc2
.
lock
));
oldcrtc2
=
ACCESS_FBINFO
(
crtc2
.
info
);
ACCESS_FBINFO
(
crtc2
.
info
)
=
&
m2info
->
fbcon
;
ACCESS_FBINFO
(
crtc2
.
info
)
=
m2info
;
up_write
(
&
ACCESS_FBINFO
(
crtc2
.
lock
));
if
(
oldcrtc2
)
{
printk
(
KERN_ERR
"matroxfb_crtc2: Internal consistency check failed: crtc2 already present: %p
\n
"
,
...
...
@@ -776,16 +826,16 @@ static void matroxfb_dh_deregisterfb(struct matroxfb_dh_fb_info* m2info) {
#define minfo (m2info->primary_dev)
if
(
m2info
->
fbcon_registered
)
{
int
id
;
struct
fb_info
*
crtc2
;
struct
matroxfb_dh_
fb_info
*
crtc2
;
down_write
(
&
ACCESS_FBINFO
(
crtc2
.
lock
));
crtc2
=
ACCESS_FBINFO
(
crtc2
.
info
);
if
(
crtc2
==
&
m2info
->
fbcon
)
if
(
crtc2
==
m2info
)
ACCESS_FBINFO
(
crtc2
.
info
)
=
NULL
;
up_write
(
&
ACCESS_FBINFO
(
crtc2
.
lock
));
if
(
crtc2
!=
&
m2info
->
fbcon
)
{
if
(
crtc2
!=
m2info
)
{
printk
(
KERN_ERR
"matroxfb_crtc2: Internal consistency check failed: crtc2 mismatch at unload: %p != %p
\n
"
,
crtc2
,
&
m2info
->
fbcon
);
crtc2
,
m2info
);
printk
(
KERN_ERR
"matroxfb_crtc2: Expect kernel crash after module unload.
\n
"
);
return
;
}
...
...
@@ -823,6 +873,7 @@ static void* matroxfb_crtc2_probe(struct matrox_fb_info* minfo) {
static
void
matroxfb_crtc2_remove
(
struct
matrox_fb_info
*
minfo
,
void
*
crtc2
)
{
matroxfb_dh_deregisterfb
(
crtc2
);
kfree
(
crtc2
);
}
static
struct
matroxfb_driver
crtc2
=
{
...
...
@@ -839,7 +890,7 @@ static void matroxfb_crtc2_exit(void) {
matroxfb_unregister_driver
(
&
crtc2
);
}
MODULE_AUTHOR
(
"(c) 1999-200
1
Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_AUTHOR
(
"(c) 1999-200
2
Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_DESCRIPTION
(
"Matrox G400 CRTC2 driver"
);
MODULE_LICENSE
(
"GPL"
);
module_init
(
matroxfb_crtc2_init
);
...
...
drivers/video/matrox/matroxfb_crtc2.h
View file @
062dffea
...
...
@@ -27,8 +27,9 @@ struct matroxfb_dh_fb_info {
unsigned
int
len
;
}
mmio
;
int
currcon
;
struct
display
*
currcon_display
;
int
interlaced
:
1
;
union
{
#ifdef FBCON_HAS_CFB16
...
...
drivers/video/matrox/matroxfb_g450.c
View file @
062dffea
...
...
@@ -2,145 +2,418 @@
*
* 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
int
matroxfb_g450_compute
(
void
*
md
,
struct
my_timming
*
mt
)
{
#define m2info ((struct matroxfb_g450_info*)md)
#define minfo (m2info->primary_dev)
ACCESS_FBINFO
(
hw
).
vidclk
=
mt
->
pixclock
;
#undef minfo
#undef m2info
return
0
;
}
static
void
cve2_set_reg
(
WPMINFO
int
reg
,
int
val
)
{
unsigned
long
flags
;
static
int
matroxfb_g450_program
(
void
*
md
)
{
#define m2info ((struct matroxfb_g450_info*)md)
#define minfo (m2info->primary_dev)
matroxfb_g450_setclk
(
PMINFO
ACCESS_FBINFO
(
hw
).
vidclk
,
M_VIDEO_PLL
);
#undef minfo
#undef m2info
return
0
;
matroxfb_DAC_lock_irqsave
(
flags
);
matroxfb_DAC_out
(
PMINFO
0x87
,
reg
);
matroxfb_DAC_out
(
PMINFO
0x88
,
val
);
matroxfb_DAC_unlock_irqrestore
(
flags
);
}
static
int
matroxfb_g450_start
(
void
*
md
)
{
return
0
;
}
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
matroxfb_g450_incuse
(
void
*
md
)
{
MOD_INC_USE_COUNT
;
}
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
);
static
void
matroxfb_g450_decuse
(
void
*
md
)
{
MOD_DEC_USE_COUNT
;
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
int
matroxfb_g450_set_mode
(
void
*
md
,
u_int32_t
arg
)
{
if
(
arg
==
MATROXFB_OUTPUT_MODE_MONITOR
)
{
return
1
;
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
-
EINVAL
;
return
;
}
static
int
matroxfb_g450_get_mode
(
void
*
md
,
u_int32_t
*
arg
)
{
*
arg
=
MATROXFB_OUTPUT_MODE_MONITOR
;
return
0
;
#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
struct
matrox_altout
matroxfb_g450_altout
=
{
matroxfb_g450_compute
,
matroxfb_g450_program
,
matroxfb_g450_start
,
matroxfb_g450_incuse
,
matroxfb_g450_decuse
,
matroxfb_g450_set_mode
,
matroxfb_g450_get_mode
};
static
int
matroxfb_g450_compute
(
void
*
md
,
struct
my_timming
*
mt
)
{
MINFO_FROM
(
md
);
dprintk
(
KERN_DEBUG
"Computing, mode=%u
\n
"
,
ACCESS_FBINFO
(
outputs
[
1
]).
mode
);
static
int
matroxfb_g450_connect
(
struct
matroxfb_g450_info
*
m2info
)
{
MINFO_FROM
(
m2info
->
primary_dev
);
if
(
mt
->
crtc
==
MATROXFB_SRC_CRTC2
&&
ACCESS_FBINFO
(
outputs
[
1
]).
mode
!=
MATROXFB_OUTPUT_MODE_MONITOR
)
{
const
struct
output_desc
*
outd
;
down_write
(
&
ACCESS_FBINFO
(
altout
.
lock
));
ACCESS_FBINFO
(
altout
.
device
)
=
m2info
;
ACCESS_FBINFO
(
altout
.
output
)
=
&
matroxfb_g450_altout
;
up_write
(
&
ACCESS_FBINFO
(
altout
.
lock
));
ACCESS_FBINFO
(
output
.
all
)
|=
MATROXFB_OUTPUT_CONN_SECONDARY
;
matroxfb_switch
(
ACCESS_FBINFO
(
fbcon
.
currcon
),
(
struct
fb_info
*
)
MINFO
);
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
void
matroxfb_g450_shutdown
(
struct
matroxfb_g450_info
*
m2info
)
{
MINFO_FROM
(
m
2info
->
primary_dev
);
static
int
matroxfb_g450_program
(
void
*
md
)
{
MINFO_FROM
(
m
d
);
if
(
MINFO
)
{
ACCESS_FBINFO
(
output
.
all
)
&=
~
MATROXFB_OUTPUT_CONN_SECONDARY
;
ACCESS_FBINFO
(
output
.
ph
)
&=
~
MATROXFB_OUTPUT_CONN_SECONDARY
;
ACCESS_FBINFO
(
output
.
sh
)
&=
~
MATROXFB_OUTPUT_CONN_SECONDARY
;
down_write
(
&
ACCESS_FBINFO
(
altout
.
lock
));
ACCESS_FBINFO
(
altout
.
device
)
=
NULL
;
ACCESS_FBINFO
(
altout
.
output
)
=
NULL
;
up_write
(
&
ACCESS_FBINFO
(
altout
.
lock
));
m2info
->
primary_dev
=
NULL
;
if
(
ACCESS_FBINFO
(
outputs
[
1
]).
mode
!=
MATROXFB_OUTPUT_MODE_MONITOR
)
{
cve2_init_TV
(
PMINFO
&
ACCESS_FBINFO
(
hw
).
maven
);
}
return
0
;
}
/* we do not have __setup() yet */
static
void
*
matroxfb_g450_probe
(
struct
matrox_fb_info
*
minfo
)
{
struct
matroxfb_g450_info
*
m2info
;
/* hardware is not G450... */
if
(
!
ACCESS_FBINFO
(
devflags
.
g450dac
))
return
NULL
;
m2info
=
(
struct
matroxfb_g450_info
*
)
kmalloc
(
sizeof
(
*
m2info
),
GFP_KERNEL
);
if
(
!
m2info
)
{
printk
(
KERN_ERR
"matroxfb_g450: Not enough memory for G450 DAC control structs
\n
"
);
return
NULL
;
}
memset
(
m2info
,
0
,
sizeof
(
*
m2info
));
m2info
->
primary_dev
=
MINFO
;
if
(
matroxfb_g450_connect
(
m2info
))
{
kfree
(
m2info
);
printk
(
KERN_ERR
"matroxfb_g450: G450 DAC failed to initialize
\n
"
);
return
NULL
;
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
m2info
;
return
-
EINVAL
;
}
static
void
matroxfb_g450_remove
(
struct
matrox_fb_info
*
minfo
,
void
*
g450
)
{
matroxfb_g450_shutdown
(
g450
);
kfree
(
g450
);
static
int
g450_dvi_compute
(
void
*
md
,
struct
my_timming
*
mt
)
{
MINFO_FROM
(
md
);
if
(
mt
->
mnp
<
0
)
{
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
);
}
return
0
;
}
static
struct
matroxfb_driver
g450
=
{
.
name
=
"Matrox G450 output #2"
,
.
probe
=
matroxfb_g450_probe
,
.
remove
=
matroxfb_g450_remove
};
static
struct
matrox_altout
matroxfb_g450_altout
=
{
.
name
=
"Secondary output"
,
.
compute
=
matroxfb_g450_compute
,
.
program
=
matroxfb_g450_program
,
.
verifymode
=
matroxfb_g450_verify_mode
,
};
static
int
matroxfb_g450_init
(
void
)
{
matroxfb_register_driver
(
&
g450
);
return
0
;
static
struct
matrox_altout
matroxfb_g450_dvi
=
{
.
name
=
"DVI output"
,
.
compute
=
g450_dvi_compute
,
};
void
matroxfb_g450_connect
(
WPMINFO2
)
{
if
(
ACCESS_FBINFO
(
devflags
.
g450dac
))
{
down_write
(
&
ACCESS_FBINFO
(
altout
.
lock
));
ACCESS_FBINFO
(
outputs
[
1
]).
src
=
MATROXFB_SRC_CRTC1
;
ACCESS_FBINFO
(
outputs
[
1
]).
data
=
MINFO
;
ACCESS_FBINFO
(
outputs
[
1
]).
output
=
&
matroxfb_g450_altout
;
ACCESS_FBINFO
(
outputs
[
1
]).
mode
=
MATROXFB_OUTPUT_MODE_MONITOR
;
ACCESS_FBINFO
(
outputs
[
2
]).
src
=
MATROXFB_SRC_CRTC1
;
ACCESS_FBINFO
(
outputs
[
2
]).
data
=
MINFO
;
ACCESS_FBINFO
(
outputs
[
2
]).
output
=
&
matroxfb_g450_dvi
;
ACCESS_FBINFO
(
outputs
[
2
]).
mode
=
MATROXFB_OUTPUT_MODE_MONITOR
;
up_write
(
&
ACCESS_FBINFO
(
altout
.
lock
));
}
}
static
void
matroxfb_g450_exit
(
void
)
{
matroxfb_unregister_driver
(
&
g450
);
void
matroxfb_g450_shutdown
(
WPMINFO2
)
{
if
(
ACCESS_FBINFO
(
devflags
.
g450dac
))
{
down_write
(
&
ACCESS_FBINFO
(
altout
.
lock
));
ACCESS_FBINFO
(
outputs
[
1
]).
src
=
MATROXFB_SRC_NONE
;
ACCESS_FBINFO
(
outputs
[
1
]).
output
=
NULL
;
ACCESS_FBINFO
(
outputs
[
1
]).
data
=
NULL
;
ACCESS_FBINFO
(
outputs
[
1
]).
mode
=
MATROXFB_OUTPUT_MODE_MONITOR
;
ACCESS_FBINFO
(
outputs
[
2
]).
src
=
MATROXFB_SRC_NONE
;
ACCESS_FBINFO
(
outputs
[
2
]).
output
=
NULL
;
ACCESS_FBINFO
(
outputs
[
2
]).
data
=
NULL
;
ACCESS_FBINFO
(
outputs
[
2
]).
mode
=
MATROXFB_OUTPUT_MODE_MONITOR
;
up_write
(
&
ACCESS_FBINFO
(
altout
.
lock
));
}
}
MODULE_AUTHOR
(
"(c) 2000-2001 Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_DESCRIPTION
(
"Matrox G450 secondary output driver"
);
EXPORT_SYMBOL
(
matroxfb_g450_connect
);
EXPORT_SYMBOL
(
matroxfb_g450_shutdown
);
MODULE_AUTHOR
(
"(c) 2000-2002 Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_DESCRIPTION
(
"Matrox G450/G550 output driver"
);
MODULE_LICENSE
(
"GPL"
);
module_init
(
matroxfb_g450_init
);
module_exit
(
matroxfb_g450_exit
);
drivers/video/matrox/matroxfb_g450.h
View file @
062dffea
#ifndef __MATROXFB_G450_H__
#define __MATROXFB_G450_H__
#include <linux/ioctl.h>
#include "matroxfb_base.h"
struct
matroxfb_g450_info
{
struct
matrox_fb_info
*
primary_dev
;
unsigned
int
timmings
;
};
#ifdef CONFIG_FB_MATROX_G450
void
matroxfb_g450_connect
(
WPMINFO2
);
void
matroxfb_g450_shutdown
(
WPMINFO2
);
#else
static
inline
void
matroxfb_g450_connect
(
WPMINFO2
)
{
};
static
inline
void
matroxfb_g450_shutdown
(
WPMINFO2
)
{
};
#endif
#endif
/* __MATROXFB_
MAVEN
_H__ */
#endif
/* __MATROXFB_
G450
_H__ */
drivers/video/matrox/matroxfb_maven.c
View file @
062dffea
...
...
@@ -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
*
* See matroxfb_base.c for contributors.
*
...
...
@@ -22,18 +22,12 @@
#define MAVEN_I2CID (0x1B)
#define MODE_PAL MATROXFB_OUTPUT_MODE_PAL
#define MODE_NTSC MATROXFB_OUTPUT_MODE_NTSC
#define MODE_TV(x) (((x) == MODE_PAL) || ((x) == MODE_NTSC))
#define MODE_MONITOR MATROXFB_OUTPUT_MODE_MONITOR
#define MGATVO_B 1
#define MGATVO_C 2
struct
maven_data
{
struct
matrox_fb_info
*
primary_head
;
struct
i2c_client
*
client
;
int
mode
;
int
version
;
};
...
...
@@ -127,7 +121,7 @@ static int matroxfb_PLL_mavenclock(const struct matrox_pll_features2* pll,
fwant
=
htotal
*
vtotal
;
fmax
=
pll
->
vco_freq_max
/
ctl
->
den
;
printk
(
KERN_DEBUG
"want: %u, xtal: %u, h: %u, v: %u, fmax: %u
\n
"
,
d
printk
(
KERN_DEBUG
"want: %u, xtal: %u, h: %u, v: %u, fmax: %u
\n
"
,
fwant
,
fxtal
,
htotal
,
vtotal
,
fmax
);
for
(
p
=
1
;
p
<=
pll
->
post_shift_max
;
p
++
)
{
if
(
fwant
*
2
>
fmax
)
...
...
@@ -163,9 +157,9 @@ static int matroxfb_PLL_mavenclock(const struct matrox_pll_features2* pll,
ln
=
ln
-
scrlen
;
if
(
ln
>
htotal
)
continue
;
printk
(
KERN_DEBUG
"Match: %u / %u / %u / %u
\n
"
,
n
,
m
,
p
,
ln
);
d
printk
(
KERN_DEBUG
"Match: %u / %u / %u / %u
\n
"
,
n
,
m
,
p
,
ln
);
if
(
ln
>
besth2
)
{
printk
(
KERN_DEBUG
"Better...
\n
"
);
d
printk
(
KERN_DEBUG
"Better...
\n
"
);
*
h2
=
besth2
=
ln
;
*
post
=
p
;
*
in
=
m
;
...
...
@@ -221,6 +215,13 @@ static void DAC1064_calcclock(unsigned int freq, unsigned int fmax,
return
;
}
static
unsigned
char
maven_compute_deflicker
(
const
struct
maven_data
*
md
)
{
unsigned
char
df
;
df
=
(
md
->
version
==
MGATVO_B
?
0x40
:
0x00
);
return
df
;
}
static
void
maven_init_TVdata
(
const
struct
maven_data
*
md
,
struct
mavenregs
*
data
)
{
static
struct
mavenregs
palregs
=
{
{
0x2A
,
0x09
,
0x8A
,
0xCB
,
/* 00: chroma subcarrier */
...
...
@@ -273,7 +274,7 @@ static void maven_init_TVdata(const struct maven_data* md, struct mavenregs* dat
0x3F
,
0x03
,
/* 3C-3D */
0x00
,
/* 3E written multiple times */
0x00
,
/* 3F not written */
},
MODE_PAL
,
625
,
50
};
},
M
ATROXFB_OUTPUT_M
ODE_PAL
,
625
,
50
};
static
struct
mavenregs
ntscregs
=
{
{
0x21
,
0xF0
,
0x7C
,
0x1F
,
/* 00: chroma subcarrier */
0x00
,
...
...
@@ -325,14 +326,16 @@ static void maven_init_TVdata(const struct maven_data* md, struct mavenregs* dat
0x3C
,
0x00
,
/* 3C-3D */
0x00
,
/* 3E written multiple times */
0x00
,
/* never written */
},
MODE_NTSC
,
525
,
60
};
},
MATROXFB_OUTPUT_MODE_NTSC
,
525
,
60
};
MINFO_FROM
(
md
->
primary_head
);
if
(
md
->
mode
&
MODE_PAL
)
if
(
ACCESS_FBINFO
(
outputs
[
1
]).
mode
==
MATROXFB_OUTPUT_
MODE_PAL
)
*
data
=
palregs
;
else
*
data
=
ntscregs
;
data
->
regs
[
0x93
]
=
0xA2
;
/* Set deflicker */
data
->
regs
[
0x93
]
=
maven_compute_deflicker
(
md
);
/* gamma correction registers */
data
->
regs
[
0x83
]
=
0x00
;
...
...
@@ -386,7 +389,7 @@ static void maven_init_TV(struct i2c_client* c, const struct mavenregs* m) {
LRP
(
0x17
);
LR
(
0x0B
);
LR
(
0x0C
);
if
(
m
->
mode
&
MODE_PAL
)
{
if
(
m
->
mode
==
MATROXFB_OUTPUT_
MODE_PAL
)
{
maven_set_reg
(
c
,
0x35
,
0x10
);
/* ... */
}
else
{
maven_set_reg
(
c
,
0x35
,
0x0F
);
/* ... */
...
...
@@ -424,7 +427,7 @@ static void maven_init_TV(struct i2c_client* c, const struct mavenregs* m) {
LR
(
0x27
);
LR
(
0x21
);
LRP
(
0x2A
);
if
(
m
->
mode
&
MODE_PAL
)
if
(
m
->
mode
==
MATROXFB_OUTPUT_
MODE_PAL
)
maven_set_reg
(
c
,
0x35
,
0x1D
);
/* ... */
else
maven_set_reg
(
c
,
0x35
,
0x1C
);
...
...
@@ -473,7 +476,7 @@ static void maven_init_TV(struct i2c_client* c, const struct mavenregs* m) {
LR
(
0xC2
);
maven_get_reg
(
c
,
0x8D
);
maven_set_reg
(
c
,
0x8D
,
0x0
0
);
maven_set_reg
(
c
,
0x8D
,
0x0
4
);
LR
(
0x20
);
/* saturation #1 */
LR
(
0x22
);
/* saturation #2 */
...
...
@@ -498,7 +501,7 @@ static void maven_init_TV(struct i2c_client* c, const struct mavenregs* m) {
LR
(
0x8B
);
val
=
maven_get_reg
(
c
,
0x8D
);
val
&=
0x1
0
;
/* 0x10 or anything ored with it */
val
&=
0x1
4
;
/* 0x10 or anything ored with it */
maven_set_reg
(
c
,
0x8D
,
val
);
LR
(
0x33
);
...
...
@@ -524,7 +527,7 @@ static void maven_init_TV(struct i2c_client* c, const struct mavenregs* m) {
LR
(
0x27
);
LR
(
0x21
);
LRP
(
0x2A
);
if
(
m
->
mode
&
MODE_PAL
)
if
(
m
->
mode
==
MATROXFB_OUTPUT_
MODE_PAL
)
maven_set_reg
(
c
,
0x35
,
0x1D
);
else
maven_set_reg
(
c
,
0x35
,
0x1C
);
...
...
@@ -562,7 +565,7 @@ static int maven_find_exact_clocks(unsigned int ht, unsigned int vt,
unsigned
int
a
,
b
,
c
,
h2
;
unsigned
int
h
=
ht
+
2
+
x
;
if
(
!
matroxfb_mavenclock
((
m
->
mode
&
MODE_PAL
)
?
&
maven_PAL
:
&
maven_NTSC
,
h
,
vt
,
&
a
,
&
b
,
&
c
,
&
h2
))
{
if
(
!
matroxfb_mavenclock
((
m
->
mode
==
MATROXFB_OUTPUT_
MODE_PAL
)
?
&
maven_PAL
:
&
maven_NTSC
,
h
,
vt
,
&
a
,
&
b
,
&
c
,
&
h2
))
{
unsigned
int
diff
=
h
-
h2
;
if
(
diff
<
err
)
{
...
...
@@ -583,9 +586,10 @@ static inline int maven_compute_timming(struct maven_data* md,
struct
mavenregs
*
m
)
{
unsigned
int
tmpi
;
unsigned
int
a
,
bv
,
c
;
MINFO_FROM
(
md
->
primary_head
);
m
->
mode
=
md
->
mode
;
if
(
MODE_TV
(
md
->
mode
)
)
{
m
->
mode
=
ACCESS_FBINFO
(
outputs
[
1
]).
mode
;
if
(
m
->
mode
!=
MATROXFB_OUTPUT_MODE_MONITOR
)
{
unsigned
int
lmargin
;
unsigned
int
umargin
;
unsigned
int
vslen
;
...
...
@@ -804,7 +808,7 @@ static inline int maven_compute_timming(struct maven_data* md,
m
->
regs
[
0xB0
]
=
0x03
;
/* output: monitor */
m
->
regs
[
0xB1
]
=
0xA0
;
/* ??? */
m
->
regs
[
0x8C
]
=
0x20
;
/* must be set... */
m
->
regs
[
0x8D
]
=
0x0
0
;
/* defaults to 0x10: test signal */
m
->
regs
[
0x8D
]
=
0x0
4
;
/* defaults to 0x10: test signal */
m
->
regs
[
0xB9
]
=
0x1A
;
/* defaults to 0x2C: too bright */
m
->
regs
[
0xBF
]
=
0x22
;
/* makes picture stable */
...
...
@@ -815,7 +819,7 @@ static inline int maven_program_timming(struct maven_data* md,
const
struct
mavenregs
*
m
)
{
struct
i2c_client
*
c
=
md
->
client
;
if
(
m
->
mode
&
MODE_MONITOR
)
{
if
(
m
->
mode
==
MATROXFB_OUTPUT_
MODE_MONITOR
)
{
LR
(
0x80
);
LR
(
0x81
);
LR
(
0x82
);
...
...
@@ -855,22 +859,16 @@ static inline int maven_resync(struct maven_data* md) {
return
0
;
}
static
int
maven_
set
_output_mode
(
struct
maven_data
*
md
,
u_int32_t
arg
)
{
static
int
maven_
verify
_output_mode
(
struct
maven_data
*
md
,
u_int32_t
arg
)
{
switch
(
arg
)
{
case
MATROXFB_OUTPUT_MODE_PAL
:
case
MATROXFB_OUTPUT_MODE_NTSC
:
case
MATROXFB_OUTPUT_MODE_MONITOR
:
md
->
mode
=
arg
;
return
1
;
return
0
;
}
return
-
EINVAL
;
}
static
int
maven_get_output_mode
(
struct
maven_data
*
md
,
u_int32_t
*
arg
)
{
*
arg
=
md
->
mode
;
return
0
;
}
/******************************************************/
static
int
maven_out_compute
(
void
*
md
,
struct
my_timming
*
mt
)
{
...
...
@@ -893,48 +891,31 @@ static int maven_out_start(void* md) {
return
maven_resync
(
md
);
}
static
void
maven_out_incuse
(
void
*
md
)
{
if
(
md
)
i2c_inc_use_client
(((
struct
maven_data
*
)
md
)
->
client
);
}
static
void
maven_out_decuse
(
void
*
md
)
{
if
(
md
)
i2c_dec_use_client
(((
struct
maven_data
*
)
md
)
->
client
);
}
static
int
maven_out_set_mode
(
void
*
md
,
u_int32_t
arg
)
{
return
maven_set_output_mode
(
md
,
arg
);
}
static
int
maven_out_get_mode
(
void
*
md
,
u_int32_t
*
arg
)
{
return
maven_get_output_mode
(
md
,
arg
);
static
int
maven_out_verify_mode
(
void
*
md
,
u_int32_t
arg
)
{
return
maven_verify_output_mode
(
md
,
arg
);
}
static
struct
matrox_altout
maven_altout
=
{
maven_out_compute
,
maven_out_program
,
maven_out_start
,
maven_out_incuse
,
maven_out_decuse
,
maven_out_set_mode
,
maven_out_get_mode
.
name
=
"Secondary output"
,
.
compute
=
maven_out_compute
,
.
program
=
maven_out_program
,
.
start
=
maven_out_start
,
.
verifymode
=
maven_out_verify_mode
,
};
static
int
maven_init_client
(
struct
i2c_client
*
clnt
)
{
struct
i2c_adapter
*
a
=
clnt
->
adapter
;
struct
maven_data
*
md
=
clnt
->
data
;
struct
matroxfb_dh_maven_info
*
m2info
__attribute__
((
unused
))
=
((
struct
i2c_bit_adapter
*
)
a
)
->
minfo
;
MINFO_FROM
(
m2info
->
primary_dev
);
MINFO_FROM
(
container_of
(
a
,
struct
i2c_bit_adapter
,
adapter
)
->
minfo
);
md
->
mode
=
MODE_MONITOR
;
md
->
primary_head
=
MINFO
;
md
->
client
=
clnt
;
down_write
(
&
ACCESS_FBINFO
(
altout
.
lock
));
ACCESS_FBINFO
(
altout
.
device
)
=
md
;
ACCESS_FBINFO
(
altout
.
output
)
=
&
maven_altout
;
ACCESS_FBINFO
(
outputs
[
1
]).
output
=
&
maven_altout
;
ACCESS_FBINFO
(
outputs
[
1
]).
src
=
MATROXFB_SRC_NONE
;
ACCESS_FBINFO
(
outputs
[
1
]).
data
=
md
;
ACCESS_FBINFO
(
outputs
[
1
]).
mode
=
MATROXFB_OUTPUT_MODE_MONITOR
;
up_write
(
&
ACCESS_FBINFO
(
altout
.
lock
));
ACCESS_FBINFO
(
output
.
all
)
|=
MATROXFB_OUTPUT_CONN_SECONDARY
;
if
(
maven_get_reg
(
clnt
,
0xB2
)
<
0x14
)
{
md
->
version
=
MGATVO_B
;
}
else
{
...
...
@@ -947,13 +928,14 @@ static int maven_shutdown_client(struct i2c_client* clnt) {
struct
maven_data
*
md
=
clnt
->
data
;
if
(
md
->
primary_head
)
{
md
->
primary_head
->
output
.
all
&=
~
MATROXFB_OUTPUT_CONN_SECONDARY
;
md
->
primary_head
->
output
.
ph
&=
~
MATROXFB_OUTPUT_CONN_SECONDARY
;
md
->
primary_head
->
output
.
sh
&=
~
MATROXFB_OUTPUT_CONN_SECONDARY
;
down_write
(
&
md
->
primary_head
->
altout
.
lock
);
md
->
primary_head
->
altout
.
device
=
NULL
;
md
->
primary_head
->
altout
.
output
=
NULL
;
up_write
(
&
md
->
primary_head
->
altout
.
lock
);
MINFO_FROM
(
md
->
primary_head
);
down_write
(
&
ACCESS_FBINFO
(
altout
.
lock
));
ACCESS_FBINFO
(
outputs
[
1
]).
src
=
MATROXFB_SRC_NONE
;
ACCESS_FBINFO
(
outputs
[
1
]).
output
=
NULL
;
ACCESS_FBINFO
(
outputs
[
1
]).
data
=
NULL
;
ACCESS_FBINFO
(
outputs
[
1
]).
mode
=
MATROXFB_OUTPUT_MODE_MONITOR
;
up_write
(
&
ACCESS_FBINFO
(
altout
.
lock
));
md
->
primary_head
=
NULL
;
}
return
0
;
...
...
@@ -983,7 +965,7 @@ static int maven_detect_client(struct i2c_adapter* adapter, int address, unsigne
I2C_FUNC_SMBUS_BYTE_DATA
|
I2C_FUNC_PROTOCOL_MANGLING
))
goto
ERROR0
;
if
(
!
(
new_client
=
(
struct
i2c_client
*
)
kmalloc
(
sizeof
(
struct
i2c_client
)
+
sizeof
(
struct
maven_
data
),
if
(
!
(
new_client
=
(
struct
i2c_client
*
)
kmalloc
(
sizeof
(
*
new_client
)
+
sizeof
(
*
data
),
GFP_KERNEL
)))
{
err
=
-
ENOMEM
;
goto
ERROR0
;
...
...
@@ -1066,7 +1048,7 @@ static void matroxfb_maven_exit(void) {
i2c_del_driver
(
&
maven_driver
);
}
MODULE_AUTHOR
(
"(c) 1999-200
1
Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_AUTHOR
(
"(c) 1999-200
2
Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_DESCRIPTION
(
"Matrox G200/G400 Matrox MGA-TVO driver"
);
MODULE_LICENSE
(
"GPL"
);
module_init
(
matroxfb_maven_init
);
...
...
drivers/video/matrox/matroxfb_maven.h
View file @
062dffea
...
...
@@ -6,21 +6,15 @@
#include <linux/i2c-algo-bit.h>
#include "matroxfb_base.h"
struct
matroxfb_dh_maven_info
;
struct
i2c_bit_adapter
{
struct
i2c_adapter
adapter
;
int
initialized
;
struct
i2c_algo_bit_data
bac
;
struct
matroxfb_dh_maven_info
*
minfo
;
};
struct
matroxfb_dh_maven_info
{
struct
matrox_fb_info
*
primary_dev
;
struct
i2c_bit_adapter
maven
;
struct
i2c_bit_adapter
ddc1
;
struct
i2c_bit_adapter
ddc2
;
struct
matrox_fb_info
*
minfo
;
struct
{
unsigned
int
data
;
unsigned
int
clock
;
}
mask
;
};
#endif
/* __MATROXFB_MAVEN_H__ */
drivers/video/matrox/matroxfb_misc.c
View file @
062dffea
...
...
@@ -2,11 +2,11 @@
*
* Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
*
* (c) 1998
,1999,2000,2001
Petr Vandrovec <vandrove@vc.cvut.cz>
* (c) 1998
-2002
Petr Vandrovec <vandrove@vc.cvut.cz>
*
* Portions Copyright (c) 2001 Matrox Graphics Inc.
*
* Version: 1.6
2 2001/11/29
* Version: 1.6
5 2002/08/14
*
* MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
*
...
...
@@ -146,6 +146,7 @@ void matroxfb_var2my(struct fb_var_screeninfo* var, struct my_timming* mt) {
if
(
!
pixclock
)
pixclock
=
10000
;
/* 10ns = 100MHz */
mt
->
pixclock
=
1000000000
/
pixclock
;
if
(
mt
->
pixclock
<
1
)
mt
->
pixclock
=
1
;
mt
->
mnp
=
-
1
;
mt
->
dblscan
=
var
->
vmode
&
FB_VMODE_DOUBLE
;
mt
->
interlaced
=
var
->
vmode
&
FB_VMODE_INTERLACED
;
mt
->
HDisplay
=
var
->
xres
;
...
...
@@ -226,7 +227,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m, struct display* p) {
unsigned
int
wd
;
unsigned
int
divider
;
int
i
;
int
text
=
p
->
type
==
FB_TYPE_TEXT
;
int
text
=
ACCESS_FBINFO
(
fbcon
).
fix
.
type
==
FB_TYPE_TEXT
;
int
fwidth
;
struct
matrox_hw_state
*
const
hw
=
&
ACCESS_FBINFO
(
hw
);
...
...
@@ -360,7 +361,8 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m, struct display* p) {
((
hd
&
0x100
)
>>
7
)
|
/* blanking */
((
hs
&
0x100
)
>>
6
)
|
/* sync start */
(
hbe
&
0x040
);
/* end hor. blanking */
if
(
ACCESS_FBINFO
(
output
.
ph
)
&
MATROXFB_OUTPUT_CONN_SECONDARY
)
/* FIXME: Enable vidrst only on G400, and only if TV-out is used */
if
(
ACCESS_FBINFO
(
outputs
[
1
]).
src
==
MATROXFB_SRC_CRTC1
)
hw
->
CRTCEXT
[
1
]
|=
0x88
;
/* enable horizontal and vertical vidrst */
hw
->
CRTCEXT
[
2
]
=
((
vt
&
0xC00
)
>>
10
)
|
((
vd
&
0x400
)
>>
8
)
|
/* disp end */
...
...
@@ -872,7 +874,7 @@ static int parse_pins5(WPMINFO const struct matrox_bios* bd) {
mult
=
bd
->
pins
[
4
]
?
8000
:
6000
;
MINFO
->
limits
.
pixel
.
vcomax
=
(
bd
->
pins
[
38
]
==
0xFF
)
?
600000
:
bd
->
pins
[
38
]
*
mult
;
MINFO
->
limits
.
system
.
vcomax
=
(
bd
->
pins
[
36
]
==
0xFF
)
?
MINFO
->
limits
.
pixel
.
vcomax
:
bd
->
pins
[
3
9
]
*
mult
;
MINFO
->
limits
.
system
.
vcomax
=
(
bd
->
pins
[
36
]
==
0xFF
)
?
MINFO
->
limits
.
pixel
.
vcomax
:
bd
->
pins
[
3
6
]
*
mult
;
MINFO
->
limits
.
video
.
vcomax
=
(
bd
->
pins
[
37
]
==
0xFF
)
?
MINFO
->
limits
.
system
.
vcomax
:
bd
->
pins
[
37
]
*
mult
;
MINFO
->
limits
.
pixel
.
vcomin
=
(
bd
->
pins
[
123
]
==
0xFF
)
?
256000
:
bd
->
pins
[
123
]
*
mult
;
MINFO
->
limits
.
system
.
vcomin
=
(
bd
->
pins
[
121
]
==
0xFF
)
?
MINFO
->
limits
.
pixel
.
vcomin
:
bd
->
pins
[
121
]
*
mult
;
...
...
@@ -1011,6 +1013,6 @@ EXPORT_SYMBOL(matroxfb_vgaHWinit); /* DAC1064, Ti3026 */
EXPORT_SYMBOL
(
matroxfb_vgaHWrestore
);
/* DAC1064, Ti3026 */
EXPORT_SYMBOL
(
matroxfb_read_pins
);
MODULE_AUTHOR
(
"(c) 1999-200
1
Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_AUTHOR
(
"(c) 1999-200
2
Petr Vandrovec <vandrove@vc.cvut.cz>"
);
MODULE_DESCRIPTION
(
"Miscellaneous support for Matrox video cards"
);
MODULE_LICENSE
(
"GPL"
);
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