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
50312ce9
Commit
50312ce9
authored
Jun 29, 2006
by
David S. Miller
Committed by
David S. Miller
Jun 29, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SPARC]: Convert all FB SBUS drivers to of_driver framework.
Signed-off-by:
David S. Miller
<
davem@davemloft.net
>
parent
3ca9fab4
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1179 additions
and
1149 deletions
+1179
-1149
drivers/video/bw2.c
drivers/video/bw2.c
+96
-117
drivers/video/cg14.c
drivers/video/cg14.c
+153
-173
drivers/video/cg3.c
drivers/video/cg3.c
+111
-106
drivers/video/cg6.c
drivers/video/cg6.c
+183
-154
drivers/video/ffb.c
drivers/video/ffb.c
+217
-249
drivers/video/leo.c
drivers/video/leo.c
+160
-134
drivers/video/p9100.c
drivers/video/p9100.c
+131
-120
drivers/video/tcx.c
drivers/video/tcx.c
+128
-96
No files found.
drivers/video/bw2.c
View file @
50312ce9
/* bw2.c: BWTWO frame buffer driver
*
* Copyright (C) 2003
David S. Miller (davem@redhat.com
)
* Copyright (C) 2003
, 2006 David S. Miller (davem@davemloft.net
)
* Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
...
...
@@ -19,14 +19,11 @@
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/sbus.h>
#include <asm/oplib.h>
#include <asm/prom.h>
#include <asm/of_device.h>
#include <asm/fbio.h>
#ifdef CONFIG_SPARC32
#include <asm/sun4paddr.h>
#endif
#include "sbuslib.h"
/*
...
...
@@ -59,30 +56,30 @@ static struct fb_ops bw2_ops = {
#define BWTWO_REGISTER_OFFSET 0x400000
struct
bt_regs
{
volatile
u32
addr
;
volatile
u32
color_map
;
volatile
u32
control
;
volatile
u32
cursor
;
u32
addr
;
u32
color_map
;
u32
control
;
u32
cursor
;
};
struct
bw2_regs
{
struct
bt_regs
cmap
;
volatile
u8
control
;
volatile
u8
status
;
volatile
u8
cursor_start
;
volatile
u8
cursor_end
;
volatile
u8
h_blank_start
;
volatile
u8
h_blank_end
;
volatile
u8
h_sync_start
;
volatile
u8
h_sync_end
;
volatile
u8
comp_sync_end
;
volatile
u8
v_blank_start_high
;
volatile
u8
v_blank_start_low
;
volatile
u8
v_blank_end
;
volatile
u8
v_sync_start
;
volatile
u8
v_sync_end
;
volatile
u8
xfer_holdoff_start
;
volatile
u8
xfer_holdoff_end
;
u8
control
;
u8
status
;
u8
cursor_start
;
u8
cursor_end
;
u8
h_blank_start
;
u8
h_blank_end
;
u8
h_sync_start
;
u8
h_sync_end
;
u8
comp_sync_end
;
u8
v_blank_start_high
;
u8
v_blank_start_low
;
u8
v_blank_end
;
u8
v_sync_start
;
u8
v_sync_end
;
u8
xfer_holdoff_start
;
u8
xfer_holdoff_end
;
};
/* Status Register Constants */
...
...
@@ -117,9 +114,8 @@ struct bw2_par {
#define BW2_FLAG_BLANKED 0x00000001
unsigned
long
physbase
;
unsigned
long
which_io
;
unsigned
long
fbsize
;
struct
sbus_dev
*
sdev
;
};
/**
...
...
@@ -174,9 +170,7 @@ static int bw2_mmap(struct fb_info *info, struct vm_area_struct *vma)
return
sbusfb_mmap_helper
(
bw2_mmap_map
,
par
->
physbase
,
par
->
fbsize
,
(
par
->
sdev
?
par
->
sdev
->
reg_addrs
[
0
].
which_io
:
0
),
par
->
which_io
,
vma
);
}
...
...
@@ -288,139 +282,124 @@ static void bw2_do_default_mode(struct bw2_par *par, struct fb_info *info,
struct
all_info
{
struct
fb_info
info
;
struct
bw2_par
par
;
struct
list_head
list
;
};
static
LIST_HEAD
(
bw2_list
);
static
void
bw2_init_one
(
struct
sbus_dev
*
sdev
)
static
int
__devinit
bw2_init_one
(
struct
of_device
*
op
)
{
struct
device_node
*
dp
=
op
->
node
;
struct
all_info
*
all
;
struct
resource
*
resp
;
#ifdef CONFIG_SUN4
struct
resource
res
;
#endif
int
linebytes
;
int
linebytes
,
err
;
all
=
kmalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
{
printk
(
KERN_ERR
"bw2: Cannot allocate memory.
\n
"
);
return
;
}
memset
(
all
,
0
,
sizeof
(
*
all
));
INIT_LIST_HEAD
(
&
all
->
list
);
all
=
kzalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
return
-
ENOMEM
;
spin_lock_init
(
&
all
->
par
.
lock
);
all
->
par
.
sdev
=
sdev
;
#ifdef CONFIG_SUN4
if
(
!
sdev
)
{
all
->
par
.
physbase
=
sun4_bwtwo_physaddr
;
res
.
start
=
sun4_bwtwo_physaddr
;
res
.
end
=
res
.
start
+
BWTWO_REGISTER_OFFSET
+
sizeof
(
struct
bw2_regs
)
-
1
;
res
.
flags
=
IORESOURCE_IO
;
resp
=
&
res
;
all
->
info
.
var
.
xres
=
all
->
info
.
var
.
xres_virtual
=
1152
;
all
->
info
.
var
.
yres
=
all
->
info
.
var
.
yres_virtual
=
900
;
all
->
info
.
var
.
bits_per_pixel
=
1
;
linebytes
=
1152
/
8
;
}
else
#else
{
BUG_ON
(
!
sdev
);
all
->
par
.
physbase
=
sdev
->
reg_addrs
[
0
].
phys_addr
;
resp
=
&
sdev
->
resource
[
0
];
sbusfb_fill_var
(
&
all
->
info
.
var
,
(
sdev
?
sdev
->
prom_node
:
0
),
1
);
linebytes
=
prom_getintdefault
(
sdev
->
prom_node
,
"linebytes"
,
all
->
info
.
var
.
xres
);
}
#endif
all
->
par
.
physbase
=
op
->
resource
[
0
].
start
;
all
->
par
.
which_io
=
op
->
resource
[
0
].
flags
&
IORESOURCE_BITS
;
sbusfb_fill_var
(
&
all
->
info
.
var
,
dp
->
node
,
1
);
linebytes
=
of_getintprop_default
(
dp
,
"linebytes"
,
all
->
info
.
var
.
xres
);
all
->
info
.
var
.
red
.
length
=
all
->
info
.
var
.
green
.
length
=
all
->
info
.
var
.
blue
.
length
=
all
->
info
.
var
.
bits_per_pixel
;
all
->
info
.
var
.
red
.
offset
=
all
->
info
.
var
.
green
.
offset
=
all
->
info
.
var
.
blue
.
offset
=
0
;
all
->
par
.
regs
=
sbus_ioremap
(
resp
,
BWTWO_REGISTER_OFFSET
,
sizeof
(
struct
bw2_regs
),
"bw2 regs"
);
all
->
par
.
regs
=
of_ioremap
(
&
op
->
resource
[
0
]
,
BWTWO_REGISTER_OFFSET
,
sizeof
(
struct
bw2_regs
),
"bw2 regs"
);
if
(
sdev
&&
!
prom_getbool
(
sdev
->
prom_node
,
"width"
))
if
(
!
of_find_property
(
dp
,
"width"
,
NULL
))
bw2_do_default_mode
(
&
all
->
par
,
&
all
->
info
,
&
linebytes
);
all
->
par
.
fbsize
=
PAGE_ALIGN
(
linebytes
*
all
->
info
.
var
.
yres
);
all
->
info
.
flags
=
FBINFO_DEFAULT
;
all
->
info
.
fbops
=
&
bw2_ops
;
#if defined(CONFIG_SPARC32)
if
(
sdev
)
all
->
info
.
screen_base
=
(
char
__iomem
*
)
prom_getintdefault
(
sdev
->
prom_node
,
"address"
,
0
);
#endif
if
(
!
all
->
info
.
screen_base
)
all
->
info
.
screen_base
=
sbus_ioremap
(
resp
,
0
,
all
->
par
.
fbsize
,
"bw2 ram"
);
all
->
info
.
screen_base
=
sbus_ioremap
(
&
op
->
resource
[
0
],
0
,
all
->
par
.
fbsize
,
"bw2 ram"
);
all
->
info
.
par
=
&
all
->
par
;
bw2_blank
(
0
,
&
all
->
info
);
bw2_init_fix
(
&
all
->
info
,
linebytes
);
if
(
register_framebuffer
(
&
all
->
info
)
<
0
)
{
printk
(
KERN_ERR
"bw2: Could not register framebuffer.
\n
"
);
err
=
register_framebuffer
(
&
all
->
info
);
if
(
err
<
0
)
{
of_iounmap
(
all
->
par
.
regs
,
sizeof
(
struct
bw2_regs
));
of_iounmap
(
all
->
info
.
screen_base
,
all
->
par
.
fbsize
);
kfree
(
all
);
return
;
return
err
;
}
list_add
(
&
all
->
list
,
&
bw2_list
);
dev_set_drvdata
(
&
op
->
dev
,
all
);
printk
(
"%s: bwtwo at %lx:%lx
\n
"
,
dp
->
full_name
,
all
->
par
.
which_io
,
all
->
par
.
physbase
);
printk
(
"bw2: bwtwo at %lx:%lx
\n
"
,
(
long
)
(
sdev
?
sdev
->
reg_addrs
[
0
].
which_io
:
0
),
(
long
)
all
->
par
.
physbase
);
return
0
;
}
int
__init
bw2_init
(
void
)
static
int
__devinit
bw2_probe
(
struct
of_device
*
dev
,
const
struct
of_device_id
*
match
)
{
struct
sbus_bus
*
sbus
;
struct
sbus_dev
*
sdev
;
struct
of_device
*
op
=
to_of_device
(
&
dev
->
dev
);
if
(
fb_get_options
(
"bw2fb"
,
NULL
))
return
-
ENODEV
;
return
bw2_init_one
(
op
);
}
#ifdef CONFIG_SUN4
bw2_init_one
(
NULL
);
#endif
for_all_sbusdev
(
sdev
,
sbus
)
{
if
(
!
strcmp
(
sdev
->
prom_name
,
"bwtwo"
))
bw2_init_one
(
sdev
);
}
static
int
__devexit
bw2_remove
(
struct
of_device
*
dev
)
{
struct
all_info
*
all
=
dev_get_drvdata
(
&
dev
->
dev
);
unregister_framebuffer
(
&
all
->
info
);
of_iounmap
(
all
->
par
.
regs
,
sizeof
(
struct
bw2_regs
));
of_iounmap
(
all
->
info
.
screen_base
,
all
->
par
.
fbsize
);
kfree
(
all
);
dev_set_drvdata
(
&
dev
->
dev
,
NULL
);
return
0
;
}
void
__exit
bw2_exit
(
void
)
{
struct
list_head
*
pos
,
*
tmp
;
static
struct
of_device_id
bw2_match
[]
=
{
{
.
name
=
"bwtwo"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
bw2_match
);
list_for_each_safe
(
pos
,
tmp
,
&
bw2_list
)
{
struct
all_info
*
all
=
list_entry
(
pos
,
typeof
(
*
all
),
list
);
static
struct
of_platform_driver
bw2_driver
=
{
.
name
=
"bw2"
,
.
match_table
=
bw2_match
,
.
probe
=
bw2_probe
,
.
remove
=
__devexit_p
(
bw2_remove
),
};
unregister_framebuffer
(
&
all
->
info
);
kfree
(
all
);
}
static
int
__init
bw2_init
(
void
)
{
if
(
fb_get_options
(
"bw2fb"
,
NULL
))
return
-
ENODEV
;
return
of_register_driver
(
&
bw2_driver
,
&
of_bus_type
);
}
int
__init
bw2_setup
(
char
*
arg
)
static
void
__exit
bw2_exit
(
void
)
{
/* No cmdline options yet... */
return
0
;
return
of_unregister_driver
(
&
bw2_driver
);
}
module_init
(
bw2_init
);
#ifdef MODULE
module_init
(
bw2_init
);
module_exit
(
bw2_exit
);
#endif
MODULE_DESCRIPTION
(
"framebuffer driver for BWTWO chipsets"
);
MODULE_AUTHOR
(
"David S. Miller <davem@redhat.com>"
);
MODULE_AUTHOR
(
"David S. Miller <davem@davemloft.net>"
);
MODULE_VERSION
(
"2.0"
);
MODULE_LICENSE
(
"GPL"
);
drivers/video/cg14.c
View file @
50312ce9
/* cg14.c: CGFOURTEEN frame buffer driver
*
* Copyright (C) 2003
David S. Miller (davem@redhat.com
)
* Copyright (C) 2003
, 2006 David S. Miller (davem@davemloft.net
)
* Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
* Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
*
...
...
@@ -18,8 +18,8 @@
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/
sbus
.h>
#include <asm/o
plib
.h>
#include <asm/
prom
.h>
#include <asm/o
f_device
.h>
#include <asm/fbio.h>
#include "sbuslib.h"
...
...
@@ -99,73 +99,73 @@ static struct fb_ops cg14_ops = {
#define CG14_MCR_PIXMODE_32 3
struct
cg14_regs
{
volatile
u8
mcr
;
/* Master Control Reg */
volatile
u8
ppr
;
/* Packed Pixel Reg */
volatile
u8
tms
[
2
];
/* Test Mode Status Regs */
volatile
u8
msr
;
/* Master Status Reg */
volatile
u8
fsr
;
/* Fault Status Reg */
volatile
u8
rev
;
/* Revision & Impl */
volatile
u8
ccr
;
/* Clock Control Reg */
volatile
u32
tmr
;
/* Test Mode Read Back */
volatile
u8
mod
;
/* Monitor Operation Data Reg */
volatile
u8
acr
;
/* Aux Control */
u8
mcr
;
/* Master Control Reg */
u8
ppr
;
/* Packed Pixel Reg */
u8
tms
[
2
];
/* Test Mode Status Regs */
u8
msr
;
/* Master Status Reg */
u8
fsr
;
/* Fault Status Reg */
u8
rev
;
/* Revision & Impl */
u8
ccr
;
/* Clock Control Reg */
u32
tmr
;
/* Test Mode Read Back */
u8
mod
;
/* Monitor Operation Data Reg */
u8
acr
;
/* Aux Control */
u8
xxx0
[
6
];
volatile
u16
hct
;
/* Hor Counter */
volatile
u16
vct
;
/* Vert Counter */
volatile
u16
hbs
;
/* Hor Blank Start */
volatile
u16
hbc
;
/* Hor Blank Clear */
volatile
u16
hss
;
/* Hor Sync Start */
volatile
u16
hsc
;
/* Hor Sync Clear */
volatile
u16
csc
;
/* Composite Sync Clear */
volatile
u16
vbs
;
/* Vert Blank Start */
volatile
u16
vbc
;
/* Vert Blank Clear */
volatile
u16
vss
;
/* Vert Sync Start */
volatile
u16
vsc
;
/* Vert Sync Clear */
volatile
u16
xcs
;
volatile
u16
xcc
;
volatile
u16
fsa
;
/* Fault Status Address */
volatile
u16
adr
;
/* Address Registers */
u16
hct
;
/* Hor Counter */
u16
vct
;
/* Vert Counter */
u16
hbs
;
/* Hor Blank Start */
u16
hbc
;
/* Hor Blank Clear */
u16
hss
;
/* Hor Sync Start */
u16
hsc
;
/* Hor Sync Clear */
u16
csc
;
/* Composite Sync Clear */
u16
vbs
;
/* Vert Blank Start */
u16
vbc
;
/* Vert Blank Clear */
u16
vss
;
/* Vert Sync Start */
u16
vsc
;
/* Vert Sync Clear */
u16
xcs
;
u16
xcc
;
u16
fsa
;
/* Fault Status Address */
u16
adr
;
/* Address Registers */
u8
xxx1
[
0xce
];
volatile
u8
pcg
[
0x100
];
/* Pixel Clock Generator */
volatile
u32
vbr
;
/* Frame Base Row */
volatile
u32
vmcr
;
/* VBC Master Control */
volatile
u32
vcr
;
/* VBC refresh */
volatile
u32
vca
;
/* VBC Config */
u8
pcg
[
0x100
];
/* Pixel Clock Generator */
u32
vbr
;
/* Frame Base Row */
u32
vmcr
;
/* VBC Master Control */
u32
vcr
;
/* VBC refresh */
u32
vca
;
/* VBC Config */
};
#define CG14_CCR_ENABLE 0x04
#define CG14_CCR_SELECT 0x02
/* HW/Full screen */
struct
cg14_cursor
{
volatile
u32
cpl0
[
32
];
/* Enable plane 0 */
volatile
u32
cpl1
[
32
];
/* Color selection plane */
volatile
u8
ccr
;
/* Cursor Control Reg */
u32
cpl0
[
32
];
/* Enable plane 0 */
u32
cpl1
[
32
];
/* Color selection plane */
u8
ccr
;
/* Cursor Control Reg */
u8
xxx0
[
3
];
volatile
u16
cursx
;
/* Cursor x,y position */
volatile
u16
cursy
;
/* Cursor x,y position */
volatile
u32
color0
;
volatile
u32
color1
;
u16
cursx
;
/* Cursor x,y position */
u16
cursy
;
/* Cursor x,y position */
u32
color0
;
u32
color1
;
u32
xxx1
[
0x1bc
];
volatile
u32
cpl0i
[
32
];
/* Enable plane 0 autoinc */
volatile
u32
cpl1i
[
32
];
/* Color selection autoinc */
u32
cpl0i
[
32
];
/* Enable plane 0 autoinc */
u32
cpl1i
[
32
];
/* Color selection autoinc */
};
struct
cg14_dac
{
volatile
u8
addr
;
/* Address Register */
u8
addr
;
/* Address Register */
u8
xxx0
[
255
];
volatile
u8
glut
;
/* Gamma table */
u8
glut
;
/* Gamma table */
u8
xxx1
[
255
];
volatile
u8
select
;
/* Register Select */
u8
select
;
/* Register Select */
u8
xxx2
[
255
];
volatile
u8
mode
;
/* Mode Register */
u8
mode
;
/* Mode Register */
};
struct
cg14_xlut
{
volatile
u8
x_xlut
[
256
];
volatile
u8
x_xlutd
[
256
];
u8
x_xlut
[
256
];
u8
x_xlutd
[
256
];
u8
xxx0
[
0x600
];
volatile
u8
x_xlut_inc
[
256
];
volatile
u8
x_xlutd_inc
[
256
];
u8
x_xlut_inc
[
256
];
u8
x_xlutd_inc
[
256
];
};
/* Color look up table (clut) */
...
...
@@ -204,7 +204,6 @@ struct cg14_par {
int
mode
;
int
ramsize
;
struct
sbus_dev
*
sdev
;
};
static
void
__cg14_reset
(
struct
cg14_par
*
par
)
...
...
@@ -355,14 +354,9 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
* Initialisation
*/
static
void
cg14_init_fix
(
struct
fb_info
*
info
,
int
linebytes
)
static
void
cg14_init_fix
(
struct
fb_info
*
info
,
int
linebytes
,
struct
device_node
*
dp
)
{
struct
cg14_par
*
par
=
(
struct
cg14_par
*
)
info
->
par
;
const
char
*
name
;
name
=
"cgfourteen"
;
if
(
par
->
sdev
)
name
=
par
->
sdev
->
prom_name
;
const
char
*
name
=
dp
->
name
;
strlcpy
(
info
->
fix
.
id
,
name
,
sizeof
(
info
->
fix
.
id
));
...
...
@@ -456,98 +450,81 @@ static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __initdata = {
struct
all_info
{
struct
fb_info
info
;
struct
cg14_par
par
;
struct
list_head
list
;
};
static
LIST_HEAD
(
cg14_list
);
static
void
cg14_
init_one
(
struct
sbus_dev
*
sdev
,
int
node
,
int
parent_node
)
static
void
cg14_
unmap_regs
(
struct
all_info
*
all
)
{
struct
all_info
*
all
;
unsigned
long
phys
,
rphys
;
u32
bases
[
6
];
int
is_8mb
,
linebytes
,
i
;
if
(
!
sdev
)
{
if
(
prom_getproperty
(
node
,
"address"
,
(
char
*
)
&
bases
[
0
],
sizeof
(
bases
))
<=
0
||
!
bases
[
0
])
{
printk
(
KERN_ERR
"cg14: Device is not mapped.
\n
"
);
return
;
}
if
(
__get_iospace
(
bases
[
0
])
!=
__get_iospace
(
bases
[
1
]))
{
printk
(
KERN_ERR
"cg14: I/O spaces don't match.
\n
"
);
return
;
}
}
if
(
all
->
par
.
regs
)
of_iounmap
(
all
->
par
.
regs
,
sizeof
(
struct
cg14_regs
));
if
(
all
->
par
.
clut
)
of_iounmap
(
all
->
par
.
clut
,
sizeof
(
struct
cg14_clut
));
if
(
all
->
par
.
cursor
)
of_iounmap
(
all
->
par
.
cursor
,
sizeof
(
struct
cg14_cursor
));
if
(
all
->
info
.
screen_base
)
of_iounmap
(
all
->
info
.
screen_base
,
all
->
par
.
fbsize
);
}
all
=
kmalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
{
printk
(
KERN_ERR
"cg14: Cannot allocate memory.
\n
"
);
return
;
}
memset
(
all
,
0
,
sizeof
(
*
all
));
static
int
__devinit
cg14_init_one
(
struct
of_device
*
op
)
{
struct
device_node
*
dp
=
op
->
node
;
struct
all_info
*
all
;
int
is_8mb
,
linebytes
,
i
,
err
;
INIT_LIST_HEAD
(
&
all
->
list
);
all
=
kzalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
return
-
ENOMEM
;
spin_lock_init
(
&
all
->
par
.
lock
);
sbusfb_fill_var
(
&
all
->
info
.
var
,
node
,
8
);
sbusfb_fill_var
(
&
all
->
info
.
var
,
dp
->
node
,
8
);
all
->
info
.
var
.
red
.
length
=
8
;
all
->
info
.
var
.
green
.
length
=
8
;
all
->
info
.
var
.
blue
.
length
=
8
;
linebytes
=
prom_getintdefault
(
node
,
"linebytes"
,
all
->
info
.
var
.
xres
);
linebytes
=
of_getintprop_default
(
dp
,
"linebytes"
,
all
->
info
.
var
.
xres
);
all
->
par
.
fbsize
=
PAGE_ALIGN
(
linebytes
*
all
->
info
.
var
.
yres
);
all
->
par
.
sdev
=
sdev
;
if
(
sdev
)
{
rphys
=
sdev
->
reg_addrs
[
0
].
phys_addr
;
all
->
par
.
physbase
=
phys
=
sdev
->
reg_addrs
[
1
].
phys_addr
;
all
->
par
.
iospace
=
sdev
->
reg_addrs
[
0
].
which_io
;
all
->
par
.
regs
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
0
,
sizeof
(
struct
cg14_regs
),
"cg14 regs"
);
all
->
par
.
clut
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
CG14_CLUT1
,
sizeof
(
struct
cg14_clut
),
"cg14 clut"
);
all
->
par
.
cursor
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
CG14_CURSORREGS
,
sizeof
(
struct
cg14_cursor
),
"cg14 cursor"
);
all
->
info
.
screen_base
=
sbus_ioremap
(
&
sdev
->
resource
[
1
],
0
,
all
->
par
.
fbsize
,
"cg14 ram"
);
if
(
!
strcmp
(
dp
->
parent
->
name
,
"sbus"
)
||
!
strcmp
(
dp
->
parent
->
name
,
"sbi"
))
{
all
->
par
.
physbase
=
op
->
resource
[
0
].
start
;
all
->
par
.
iospace
=
op
->
resource
[
0
].
flags
&
IORESOURCE_BITS
;
}
else
{
rphys
=
__get_phys
(
bases
[
0
]);
all
->
par
.
physbase
=
phys
=
__get_phys
(
bases
[
1
]);
all
->
par
.
iospace
=
__get_iospace
(
bases
[
0
]);
all
->
par
.
regs
=
(
struct
cg14_regs
__iomem
*
)(
unsigned
long
)
bases
[
0
];
all
->
par
.
clut
=
(
struct
cg14_clut
__iomem
*
)((
unsigned
long
)
bases
[
0
]
+
CG14_CLUT1
);
all
->
par
.
cursor
=
(
struct
cg14_cursor
__iomem
*
)((
unsigned
long
)
bases
[
0
]
+
CG14_CURSORREGS
);
all
->
info
.
screen_base
=
(
char
__iomem
*
)(
unsigned
long
)
bases
[
1
];
all
->
par
.
physbase
=
op
->
resource
[
1
].
start
;
all
->
par
.
iospace
=
op
->
resource
[
0
].
flags
&
IORESOURCE_BITS
;
}
prom_getproperty
(
node
,
"reg"
,
(
char
*
)
&
bases
[
0
],
sizeof
(
bases
));
is_8mb
=
(
bases
[
5
]
==
0x800000
);
all
->
par
.
regs
=
of_ioremap
(
&
op
->
resource
[
0
],
0
,
sizeof
(
struct
cg14_regs
),
"cg14 regs"
);
all
->
par
.
clut
=
of_ioremap
(
&
op
->
resource
[
0
],
CG14_CLUT1
,
sizeof
(
struct
cg14_clut
),
"cg14 clut"
);
all
->
par
.
cursor
=
of_ioremap
(
&
op
->
resource
[
0
],
CG14_CURSORREGS
,
sizeof
(
struct
cg14_cursor
),
"cg14 cursor"
);
if
(
sizeof
(
all
->
par
.
mmap_map
)
!=
sizeof
(
__cg14_mmap_map
))
{
extern
void
__cg14_mmap_sized_wrongly
(
void
);
all
->
info
.
screen_base
=
of_ioremap
(
&
op
->
resource
[
1
],
0
,
all
->
par
.
fbsize
,
"cg14 ram"
);
__cg14_mmap_sized_wrongly
();
}
if
(
!
all
->
par
.
regs
||
!
all
->
par
.
clut
||
!
all
->
par
.
cursor
||
!
all
->
info
.
screen_base
)
cg14_unmap_regs
(
all
);
is_8mb
=
(((
op
->
resource
[
1
].
end
-
op
->
resource
[
1
].
start
)
+
1
)
==
(
8
*
1024
*
1024
));
BUILD_BUG_ON
(
sizeof
(
all
->
par
.
mmap_map
)
!=
sizeof
(
__cg14_mmap_map
));
memcpy
(
&
all
->
par
.
mmap_map
,
&
__cg14_mmap_map
,
sizeof
(
all
->
par
.
mmap_map
));
memcpy
(
&
all
->
par
.
mmap_map
,
&
__cg14_mmap_map
,
sizeof
(
all
->
par
.
mmap_map
));
for
(
i
=
0
;
i
<
CG14_MMAP_ENTRIES
;
i
++
)
{
struct
sbus_mmap_map
*
map
=
&
all
->
par
.
mmap_map
[
i
];
if
(
!
map
->
size
)
break
;
if
(
map
->
poff
&
0x80000000
)
map
->
poff
=
(
map
->
poff
&
0x7fffffff
)
+
rphys
-
phys
;
map
->
poff
=
(
map
->
poff
&
0x7fffffff
)
+
(
op
->
resource
[
0
].
start
-
op
->
resource
[
1
].
start
);
if
(
is_8mb
&&
map
->
size
>=
0x100000
&&
map
->
size
<=
0x400000
)
...
...
@@ -564,84 +541,87 @@ static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node)
__cg14_reset
(
&
all
->
par
);
if
(
fb_alloc_cmap
(
&
all
->
info
.
cmap
,
256
,
0
))
{
printk
(
KERN_ERR
"cg14: Could not allocate color map.
\n
"
);
cg14_unmap_regs
(
all
);
kfree
(
all
);
return
;
return
-
ENOMEM
;
}
fb_set_cmap
(
&
all
->
info
.
cmap
,
&
all
->
info
);
cg14_init_fix
(
&
all
->
info
,
linebytes
);
cg14_init_fix
(
&
all
->
info
,
linebytes
,
dp
);
if
(
register_framebuffer
(
&
all
->
info
)
<
0
)
{
printk
(
KERN_ERR
"cg14: Could not register framebuffer.
\n
"
);
err
=
register_framebuffer
(
&
all
->
info
);
if
(
err
<
0
)
{
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
cg14_unmap_regs
(
all
);
kfree
(
all
);
return
;
return
err
;
}
list_add
(
&
all
->
list
,
&
cg14_list
);
dev_set_drvdata
(
&
op
->
dev
,
all
);
printk
(
"cg14: cgfourteen at %lx:%lx, %dMB
\n
"
,
all
->
par
.
iospace
,
all
->
par
.
physbase
,
all
->
par
.
ramsize
>>
20
);
printk
(
"%s: cgfourteen at %lx:%lx, %dMB
\n
"
,
dp
->
full_name
,
all
->
par
.
iospace
,
all
->
par
.
physbase
,
all
->
par
.
ramsize
>>
20
);
return
0
;
}
int
__init
cg14_init
(
void
)
static
int
__devinit
cg14_probe
(
struct
of_device
*
dev
,
const
struct
of_device_id
*
match
)
{
struct
sbus_bus
*
sbus
;
struct
sbus_dev
*
sdev
;
struct
of_device
*
op
=
to_of_device
(
&
dev
->
dev
);
if
(
fb_get_options
(
"cg14fb"
,
NULL
))
return
-
ENODEV
;
return
cg14_init_one
(
op
);
}
#ifdef CONFIG_SPARC32
{
int
root
,
node
;
root
=
prom_getchild
(
prom_root_node
);
root
=
prom_searchsiblings
(
root
,
"obio"
);
if
(
root
)
{
node
=
prom_searchsiblings
(
prom_getchild
(
root
),
"cgfourteen"
);
if
(
node
)
cg14_init_one
(
NULL
,
node
,
root
);
}
}
#endif
for_all_sbusdev
(
sdev
,
sbus
)
{
if
(
!
strcmp
(
sdev
->
prom_name
,
"cgfourteen"
))
cg14_init_one
(
sdev
,
sdev
->
prom_node
,
sbus
->
prom_node
);
}
static
int
__devexit
cg14_remove
(
struct
of_device
*
dev
)
{
struct
all_info
*
all
=
dev_get_drvdata
(
&
dev
->
dev
);
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
cg14_unmap_regs
(
all
);
kfree
(
all
);
dev_set_drvdata
(
&
dev
->
dev
,
NULL
);
return
0
;
}
void
__exit
cg14_exit
(
void
)
{
struct
list_head
*
pos
,
*
tmp
;
static
struct
of_device_id
cg14_match
[]
=
{
{
.
name
=
"cgfourteen"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
cg14_match
);
list_for_each_safe
(
pos
,
tmp
,
&
cg14_list
)
{
struct
all_info
*
all
=
list_entry
(
pos
,
typeof
(
*
all
),
list
);
static
struct
of_platform_driver
cg14_driver
=
{
.
name
=
"cg14"
,
.
match_table
=
cg14_match
,
.
probe
=
cg14_probe
,
.
remove
=
__devexit_p
(
cg14_remove
),
};
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
kfree
(
all
);
}
int
__init
cg14_init
(
void
)
{
if
(
fb_get_options
(
"cg14fb"
,
NULL
))
return
-
ENODEV
;
return
of_register_driver
(
&
cg14_driver
,
&
of_bus_type
);
}
int
__init
cg14_setup
(
char
*
arg
)
void
__exit
cg14_exit
(
void
)
{
/* No cmdline options yet... */
return
0
;
of_unregister_driver
(
&
cg14_driver
);
}
module_init
(
cg14_init
);
#ifdef MODULE
module_exit
(
cg14_exit
);
#endif
MODULE_DESCRIPTION
(
"framebuffer driver for CGfourteen chipsets"
);
MODULE_AUTHOR
(
"David S. Miller <davem@redhat.com>"
);
MODULE_AUTHOR
(
"David S. Miller <davem@davemloft.net>"
);
MODULE_VERSION
(
"2.0"
);
MODULE_LICENSE
(
"GPL"
);
drivers/video/cg3.c
View file @
50312ce9
/* cg3.c: CGTHREE frame buffer driver
*
* Copyright (C) 2003
David S. Miller (davem@redhat.com
)
* Copyright (C) 2003
, 2006 David S. Miller (davem@davemloft.net
)
* Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
...
...
@@ -19,8 +19,9 @@
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/sbus.h>
#include <asm/oplib.h>
#include <asm/prom.h>
#include <asm/of_device.h>
#include <asm/fbio.h>
#include "sbuslib.h"
...
...
@@ -80,30 +81,30 @@ enum cg3_type {
};
struct
bt_regs
{
volatile
u32
addr
;
volatile
u32
color_map
;
volatile
u32
control
;
volatile
u32
cursor
;
u32
addr
;
u32
color_map
;
u32
control
;
u32
cursor
;
};
struct
cg3_regs
{
struct
bt_regs
cmap
;
volatile
u8
control
;
volatile
u8
status
;
volatile
u8
cursor_start
;
volatile
u8
cursor_end
;
volatile
u8
h_blank_start
;
volatile
u8
h_blank_end
;
volatile
u8
h_sync_start
;
volatile
u8
h_sync_end
;
volatile
u8
comp_sync_end
;
volatile
u8
v_blank_start_high
;
volatile
u8
v_blank_start_low
;
volatile
u8
v_blank_end
;
volatile
u8
v_sync_start
;
volatile
u8
v_sync_end
;
volatile
u8
xfer_holdoff_start
;
volatile
u8
xfer_holdoff_end
;
u8
control
;
u8
status
;
u8
cursor_start
;
u8
cursor_end
;
u8
h_blank_start
;
u8
h_blank_end
;
u8
h_sync_start
;
u8
h_sync_end
;
u8
comp_sync_end
;
u8
v_blank_start_high
;
u8
v_blank_start_low
;
u8
v_blank_end
;
u8
v_sync_start
;
u8
v_sync_end
;
u8
xfer_holdoff_start
;
u8
xfer_holdoff_end
;
};
/* Offset of interesting structures in the OBIO space */
...
...
@@ -120,9 +121,8 @@ struct cg3_par {
#define CG3_FLAG_RDI 0x00000002
unsigned
long
physbase
;
unsigned
long
which_io
;
unsigned
long
fbsize
;
struct
sbus_dev
*
sdev
;
};
/**
...
...
@@ -235,7 +235,7 @@ static int cg3_mmap(struct fb_info *info, struct vm_area_struct *vma)
return
sbusfb_mmap_helper
(
cg3_mmap_map
,
par
->
physbase
,
par
->
fbsize
,
par
->
sdev
->
reg_addrs
[
0
].
which_io
,
par
->
which_io
,
vma
);
}
...
...
@@ -252,11 +252,9 @@ static int cg3_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
*/
static
void
cg3_init_fix
(
struct
fb_info
*
info
,
int
linebytes
)
cg3_init_fix
(
struct
fb_info
*
info
,
int
linebytes
,
struct
device_node
*
dp
)
{
struct
cg3_par
*
par
=
(
struct
cg3_par
*
)
info
->
par
;
strlcpy
(
info
->
fix
.
id
,
par
->
sdev
->
prom_name
,
sizeof
(
info
->
fix
.
id
));
strlcpy
(
info
->
fix
.
id
,
dp
->
name
,
sizeof
(
info
->
fix
.
id
));
info
->
fix
.
type
=
FB_TYPE_PACKED_PIXELS
;
info
->
fix
.
visual
=
FB_VISUAL_PSEUDOCOLOR
;
...
...
@@ -267,16 +265,15 @@ cg3_init_fix(struct fb_info *info, int linebytes)
}
static
void
cg3_rdi_maybe_fixup_var
(
struct
fb_var_screeninfo
*
var
,
struct
sbus_dev
*
sdev
)
struct
device_node
*
dp
)
{
char
buffer
[
40
]
;
char
*
params
;
char
*
p
;
int
ww
,
hh
;
*
buffer
=
0
;
prom_getstring
(
sdev
->
prom_node
,
"params"
,
buffer
,
sizeof
(
buffer
));
if
(
*
buffer
)
{
ww
=
simple_strtoul
(
buffer
,
&
p
,
10
);
params
=
of_get_property
(
dp
,
"params"
,
NULL
);
if
(
params
)
{
ww
=
simple_strtoul
(
params
,
&
p
,
10
);
if
(
ww
&&
*
p
==
'x'
)
{
hh
=
simple_strtoul
(
p
+
1
,
&
p
,
10
);
if
(
hh
&&
*
p
==
'-'
)
{
...
...
@@ -348,11 +345,11 @@ static void cg3_do_default_mode(struct cg3_par *par)
sbus_writeb
(
p
[
1
],
regp
);
}
for
(
p
=
cg3_dacvals
;
*
p
;
p
+=
2
)
{
volatile
u8
__iomem
*
regp
;
u8
__iomem
*
regp
;
regp
=
(
volatile
u8
__iomem
*
)
&
par
->
regs
->
cmap
.
addr
;
regp
=
(
u8
__iomem
*
)
&
par
->
regs
->
cmap
.
addr
;
sbus_writeb
(
p
[
0
],
regp
);
regp
=
(
volatile
u8
__iomem
*
)
&
par
->
regs
->
cmap
.
control
;
regp
=
(
u8
__iomem
*
)
&
par
->
regs
->
cmap
.
control
;
sbus_writeb
(
p
[
1
],
regp
);
}
}
...
...
@@ -360,129 +357,137 @@ static void cg3_do_default_mode(struct cg3_par *par)
struct
all_info
{
struct
fb_info
info
;
struct
cg3_par
par
;
struct
list_head
list
;
};
static
LIST_HEAD
(
cg3_list
);
static
void
cg3_init_one
(
struct
sbus_dev
*
sdev
)
static
int
__devinit
cg3_init_one
(
struct
of_device
*
op
)
{
struct
device_node
*
dp
=
op
->
node
;
struct
all_info
*
all
;
int
linebytes
;
all
=
kmalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
{
printk
(
KERN_ERR
"cg3: Cannot allocate memory.
\n
"
);
return
;
}
memset
(
all
,
0
,
sizeof
(
*
all
));
int
linebytes
,
err
;
INIT_LIST_HEAD
(
&
all
->
list
);
all
=
kzalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
return
-
ENOMEM
;
spin_lock_init
(
&
all
->
par
.
lock
);
all
->
par
.
sdev
=
sdev
;
all
->
par
.
physbase
=
sdev
->
reg_addrs
[
0
].
phys_addr
;
all
->
par
.
physbase
=
op
->
resource
[
0
].
start
;
all
->
par
.
which_io
=
op
->
resource
[
0
].
flags
&
IORESOURCE_BITS
;
sbusfb_fill_var
(
&
all
->
info
.
var
,
sdev
->
prom_
node
,
8
);
sbusfb_fill_var
(
&
all
->
info
.
var
,
dp
->
node
,
8
);
all
->
info
.
var
.
red
.
length
=
8
;
all
->
info
.
var
.
green
.
length
=
8
;
all
->
info
.
var
.
blue
.
length
=
8
;
if
(
!
strcmp
(
sdev
->
prom_
name
,
"cgRDI"
))
if
(
!
strcmp
(
dp
->
name
,
"cgRDI"
))
all
->
par
.
flags
|=
CG3_FLAG_RDI
;
if
(
all
->
par
.
flags
&
CG3_FLAG_RDI
)
cg3_rdi_maybe_fixup_var
(
&
all
->
info
.
var
,
sdev
);
cg3_rdi_maybe_fixup_var
(
&
all
->
info
.
var
,
dp
);
linebytes
=
prom_getintdefault
(
sdev
->
prom_node
,
"linebytes"
,
all
->
info
.
var
.
xres
);
linebytes
=
of_getintprop_default
(
dp
,
"linebytes"
,
all
->
info
.
var
.
xres
);
all
->
par
.
fbsize
=
PAGE_ALIGN
(
linebytes
*
all
->
info
.
var
.
yres
);
all
->
par
.
regs
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
CG3_REGS_OFFSET
,
sizeof
(
struct
cg3_regs
),
"cg3 regs"
);
all
->
par
.
regs
=
of_ioremap
(
&
op
->
resource
[
0
],
CG3_REGS_OFFSET
,
sizeof
(
struct
cg3_regs
),
"cg3 regs"
);
all
->
info
.
flags
=
FBINFO_DEFAULT
;
all
->
info
.
fbops
=
&
cg3_ops
;
#ifdef CONFIG_SPARC32
all
->
info
.
screen_base
=
(
char
__iomem
*
)
prom_getintdefault
(
sdev
->
prom_node
,
"address"
,
0
);
#endif
if
(
!
all
->
info
.
screen_base
)
all
->
info
.
screen_base
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
CG3_RAM_OFFSET
,
all
->
par
.
fbsize
,
"cg3 ram"
);
all
->
info
.
screen_base
=
of_ioremap
(
&
op
->
resource
[
0
],
CG3_RAM_OFFSET
,
all
->
par
.
fbsize
,
"cg3 ram"
);
all
->
info
.
par
=
&
all
->
par
;
cg3_blank
(
0
,
&
all
->
info
);
if
(
!
prom_getbool
(
sdev
->
prom_node
,
"width"
))
if
(
!
of_find_property
(
dp
,
"width"
,
NULL
))
cg3_do_default_mode
(
&
all
->
par
);
if
(
fb_alloc_cmap
(
&
all
->
info
.
cmap
,
256
,
0
))
{
printk
(
KERN_ERR
"cg3: Could not allocate color map.
\n
"
);
of_iounmap
(
all
->
par
.
regs
,
sizeof
(
struct
cg3_regs
));
of_iounmap
(
all
->
info
.
screen_base
,
all
->
par
.
fbsize
);
kfree
(
all
);
return
;
return
-
ENOMEM
;
}
fb_set_cmap
(
&
all
->
info
.
cmap
,
&
all
->
info
);
cg3_init_fix
(
&
all
->
info
,
linebytes
);
cg3_init_fix
(
&
all
->
info
,
linebytes
,
dp
);
if
(
register_framebuffer
(
&
all
->
info
)
<
0
)
{
printk
(
KERN_ERR
"cg3: Could not register framebuffer.
\n
"
);
err
=
register_framebuffer
(
&
all
->
info
);
if
(
err
<
0
)
{
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
of_iounmap
(
all
->
par
.
regs
,
sizeof
(
struct
cg3_regs
));
of_iounmap
(
all
->
info
.
screen_base
,
all
->
par
.
fbsize
);
kfree
(
all
);
return
;
return
err
;
}
list_add
(
&
all
->
list
,
&
cg3_list
);
dev_set_drvdata
(
&
op
->
dev
,
all
);
printk
(
"%s: cg3 at %lx:%lx
\n
"
,
dp
->
full_name
,
all
->
par
.
which_io
,
all
->
par
.
physbase
);
printk
(
"cg3: %s at %lx:%lx
\n
"
,
sdev
->
prom_name
,
(
long
)
sdev
->
reg_addrs
[
0
].
which_io
,
(
long
)
sdev
->
reg_addrs
[
0
].
phys_addr
);
return
0
;
}
int
__init
cg3_init
(
void
)
static
int
__devinit
cg3_probe
(
struct
of_device
*
dev
,
const
struct
of_device_id
*
match
)
{
struct
sbus_bus
*
sbus
;
struct
sbus_dev
*
sdev
;
struct
of_device
*
op
=
to_of_device
(
&
dev
->
dev
);
if
(
fb_get_options
(
"cg3fb"
,
NULL
))
return
-
ENODEV
;
return
cg3_init_one
(
op
);
}
for_all_sbusdev
(
sdev
,
sbus
)
{
if
(
!
strcmp
(
sdev
->
prom_name
,
"cgthree"
)
||
!
strcmp
(
sdev
->
prom_name
,
"cgRDI"
))
cg3_init_one
(
sdev
);
}
static
int
__devexit
cg3_remove
(
struct
of_device
*
dev
)
{
struct
all_info
*
all
=
dev_get_drvdata
(
&
dev
->
dev
);
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
of_iounmap
(
all
->
par
.
regs
,
sizeof
(
struct
cg3_regs
));
of_iounmap
(
all
->
info
.
screen_base
,
all
->
par
.
fbsize
);
kfree
(
all
);
dev_set_drvdata
(
&
dev
->
dev
,
NULL
);
return
0
;
}
void
__exit
cg3_exit
(
void
)
{
struct
list_head
*
pos
,
*
tmp
;
static
struct
of_device_id
cg3_match
[]
=
{
{
.
name
=
"cgthree"
,
},
{
.
name
=
"cgRDI"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
cg3_match
);
list_for_each_safe
(
pos
,
tmp
,
&
cg3_list
)
{
struct
all_info
*
all
=
list_entry
(
pos
,
typeof
(
*
all
),
list
);
static
struct
of_platform_driver
cg3_driver
=
{
.
name
=
"cg3"
,
.
match_table
=
cg3_match
,
.
probe
=
cg3_probe
,
.
remove
=
__devexit_p
(
cg3_remove
),
};
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
kfree
(
all
);
}
static
int
__init
cg3_init
(
void
)
{
if
(
fb_get_options
(
"cg3fb"
,
NULL
))
return
-
ENODEV
;
return
of_register_driver
(
&
cg3_driver
,
&
of_bus_type
);
}
int
__init
cg3_setup
(
char
*
arg
)
static
void
__exit
cg3_exit
(
void
)
{
/* No cmdline options yet... */
return
0
;
of_unregister_driver
(
&
cg3_driver
);
}
module_init
(
cg3_init
);
#ifdef MODULE
module_exit
(
cg3_exit
);
#endif
MODULE_DESCRIPTION
(
"framebuffer driver for CGthree chipsets"
);
MODULE_AUTHOR
(
"David S. Miller <davem@redhat.com>"
);
MODULE_AUTHOR
(
"David S. Miller <davem@davemloft.net>"
);
MODULE_VERSION
(
"2.0"
);
MODULE_LICENSE
(
"GPL"
);
drivers/video/cg6.c
View file @
50312ce9
/* cg6.c: CGSIX (GX, GXplus, TGX) frame buffer driver
*
* Copyright (C) 2003
David S. Miller (davem@redhat.com
)
* Copyright (C) 2003
, 2006 David S. Miller (davem@davemloft.net
)
* Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
* Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
...
...
@@ -19,8 +19,8 @@
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/
sbus
.h>
#include <asm/o
plib
.h>
#include <asm/
prom
.h>
#include <asm/o
f_device
.h>
#include <asm/fbio.h>
#include "sbuslib.h"
...
...
@@ -164,89 +164,89 @@ static struct fb_ops cg6_ops = {
/* The contents are unknown */
struct
cg6_tec
{
volatile
int
tec_matrix
;
volatile
int
tec_clip
;
volatile
int
tec_vdc
;
int
tec_matrix
;
int
tec_clip
;
int
tec_vdc
;
};
struct
cg6_thc
{
u
int
thc_pad0
[
512
];
volatile
uint
thc_hs
;
/* hsync timing */
volatile
uint
thc_hsdvs
;
volatile
uint
thc_hd
;
volatile
uint
thc_vs
;
/* vsync timing */
volatile
uint
thc_vd
;
volatile
uint
thc_refresh
;
volatile
uint
thc_misc
;
u
int
thc_pad1
[
56
];
volatile
uint
thc_cursxy
;
/* cursor x,y position (16 bits each) */
volatile
uint
thc_cursmask
[
32
];
/* cursor mask bits */
volatile
uint
thc_cursbits
[
32
];
/* what to show where mask enabled */
u
32
thc_pad0
[
512
];
u32
thc_hs
;
/* hsync timing */
u32
thc_hsdvs
;
u32
thc_hd
;
u32
thc_vs
;
/* vsync timing */
u32
thc_vd
;
u32
thc_refresh
;
u32
thc_misc
;
u
32
thc_pad1
[
56
];
u32
thc_cursxy
;
/* cursor x,y position (16 bits each) */
u32
thc_cursmask
[
32
];
/* cursor mask bits */
u32
thc_cursbits
[
32
];
/* what to show where mask enabled */
};
struct
cg6_fbc
{
u32
xxx0
[
1
];
volatile
u32
mode
;
volatile
u32
clip
;
u32
xxx1
[
1
];
volatile
u32
s
;
volatile
u32
draw
;
volatile
u32
blit
;
volatile
u32
font
;
u32
xxx2
[
24
];
volatile
u32
x0
,
y0
,
z0
,
color0
;
volatile
u32
x1
,
y1
,
z1
,
color1
;
volatile
u32
x2
,
y2
,
z2
,
color2
;
volatile
u32
x3
,
y3
,
z3
,
color3
;
volatile
u32
offx
,
offy
;
u32
xxx3
[
2
];
volatile
u32
incx
,
incy
;
u32
xxx4
[
2
];
volatile
u32
clipminx
,
clipminy
;
u32
xxx5
[
2
];
volatile
u32
clipmaxx
,
clipmaxy
;
u32
xxx6
[
2
];
volatile
u32
fg
;
volatile
u32
bg
;
volatile
u32
alu
;
volatile
u32
pm
;
volatile
u32
pixelm
;
u32
xxx7
[
2
];
volatile
u32
patalign
;
volatile
u32
pattern
[
8
];
u32
xxx8
[
432
];
volatile
u32
apointx
,
apointy
,
apointz
;
u32
xxx9
[
1
];
volatile
u32
rpointx
,
rpointy
,
rpointz
;
u32
xxx10
[
5
];
volatile
u32
pointr
,
pointg
,
pointb
,
pointa
;
volatile
u32
alinex
,
aliney
,
alinez
;
u32
xxx11
[
1
];
volatile
u32
rlinex
,
rliney
,
rlinez
;
u32
xxx12
[
5
];
volatile
u32
liner
,
lineg
,
lineb
,
linea
;
volatile
u32
atrix
,
atriy
,
atriz
;
u32
xxx13
[
1
];
volatile
u32
rtrix
,
rtriy
,
rtriz
;
u32
xxx14
[
5
];
volatile
u32
trir
,
trig
,
trib
,
tria
;
volatile
u32
aquadx
,
aquady
,
aquadz
;
u32
xxx15
[
1
];
volatile
u32
rquadx
,
rquady
,
rquadz
;
u32
xxx16
[
5
];
volatile
u32
quadr
,
quadg
,
quadb
,
quada
;
volatile
u32
arectx
,
arecty
,
arectz
;
u32
xxx17
[
1
];
volatile
u32
rrectx
,
rrecty
,
rrectz
;
u32
xxx18
[
5
];
volatile
u32
rectr
,
rectg
,
rectb
,
recta
;
u32
xxx0
[
1
];
u32
mode
;
u32
clip
;
u32
xxx1
[
1
];
u32
s
;
u32
draw
;
u32
blit
;
u32
font
;
u32
xxx2
[
24
];
u32
x0
,
y0
,
z0
,
color0
;
u32
x1
,
y1
,
z1
,
color1
;
u32
x2
,
y2
,
z2
,
color2
;
u32
x3
,
y3
,
z3
,
color3
;
u32
offx
,
offy
;
u32
xxx3
[
2
];
u32
incx
,
incy
;
u32
xxx4
[
2
];
u32
clipminx
,
clipminy
;
u32
xxx5
[
2
];
u32
clipmaxx
,
clipmaxy
;
u32
xxx6
[
2
];
u32
fg
;
u32
bg
;
u32
alu
;
u32
pm
;
u32
pixelm
;
u32
xxx7
[
2
];
u32
patalign
;
u32
pattern
[
8
];
u32
xxx8
[
432
];
u32
apointx
,
apointy
,
apointz
;
u32
xxx9
[
1
];
u32
rpointx
,
rpointy
,
rpointz
;
u32
xxx10
[
5
];
u32
pointr
,
pointg
,
pointb
,
pointa
;
u32
alinex
,
aliney
,
alinez
;
u32
xxx11
[
1
];
u32
rlinex
,
rliney
,
rlinez
;
u32
xxx12
[
5
];
u32
liner
,
lineg
,
lineb
,
linea
;
u32
atrix
,
atriy
,
atriz
;
u32
xxx13
[
1
];
u32
rtrix
,
rtriy
,
rtriz
;
u32
xxx14
[
5
];
u32
trir
,
trig
,
trib
,
tria
;
u32
aquadx
,
aquady
,
aquadz
;
u32
xxx15
[
1
];
u32
rquadx
,
rquady
,
rquadz
;
u32
xxx16
[
5
];
u32
quadr
,
quadg
,
quadb
,
quada
;
u32
arectx
,
arecty
,
arectz
;
u32
xxx17
[
1
];
u32
rrectx
,
rrecty
,
rrectz
;
u32
xxx18
[
5
];
u32
rectr
,
rectg
,
rectb
,
recta
;
};
struct
bt_regs
{
volatile
u32
addr
;
volatile
u32
color_map
;
volatile
u32
control
;
volatile
u32
cursor
;
u32
addr
;
u32
color_map
;
u32
control
;
u32
cursor
;
};
struct
cg6_par
{
...
...
@@ -255,15 +255,14 @@ struct cg6_par {
struct
cg6_fbc
__iomem
*
fbc
;
struct
cg6_thc
__iomem
*
thc
;
struct
cg6_tec
__iomem
*
tec
;
volatile
u32
__iomem
*
fhc
;
u32
__iomem
*
fhc
;
u32
flags
;
#define CG6_FLAG_BLANKED 0x00000001
unsigned
long
physbase
;
unsigned
long
which_io
;
unsigned
long
fbsize
;
struct
sbus_dev
*
sdev
;
};
static
int
cg6_sync
(
struct
fb_info
*
info
)
...
...
@@ -529,8 +528,7 @@ static int cg6_mmap(struct fb_info *info, struct vm_area_struct *vma)
return
sbusfb_mmap_helper
(
cg6_mmap_map
,
par
->
physbase
,
par
->
fbsize
,
par
->
sdev
->
reg_addrs
[
0
].
which_io
,
vma
);
par
->
which_io
,
vma
);
}
static
int
cg6_ioctl
(
struct
fb_info
*
info
,
unsigned
int
cmd
,
unsigned
long
arg
)
...
...
@@ -658,62 +656,75 @@ static void cg6_chip_init(struct fb_info *info)
struct
all_info
{
struct
fb_info
info
;
struct
cg6_par
par
;
struct
list_head
list
;
};
static
LIST_HEAD
(
cg6_list
);
static
void
cg6_
init_one
(
struct
sbus_dev
*
sdev
)
static
void
cg6_
unmap_regs
(
struct
all_info
*
all
)
{
struct
all_info
*
all
;
int
linebytes
;
if
(
all
->
par
.
fbc
)
of_iounmap
(
all
->
par
.
fbc
,
4096
);
if
(
all
->
par
.
tec
)
of_iounmap
(
all
->
par
.
tec
,
sizeof
(
struct
cg6_tec
));
if
(
all
->
par
.
thc
)
of_iounmap
(
all
->
par
.
thc
,
sizeof
(
struct
cg6_thc
));
if
(
all
->
par
.
bt
)
of_iounmap
(
all
->
par
.
bt
,
sizeof
(
struct
bt_regs
));
if
(
all
->
par
.
fhc
)
of_iounmap
(
all
->
par
.
fhc
,
sizeof
(
u32
));
if
(
all
->
info
.
screen_base
)
of_iounmap
(
all
->
info
.
screen_base
,
all
->
par
.
fbsize
);
}
all
=
kmalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
{
printk
(
KERN_ERR
"cg6: Cannot allocate memory.
\n
"
);
return
;
}
memset
(
all
,
0
,
sizeof
(
*
all
));
static
int
__devinit
cg6_init_one
(
struct
of_device
*
op
)
{
struct
device_node
*
dp
=
op
->
node
;
struct
all_info
*
all
;
int
linebytes
,
err
;
INIT_LIST_HEAD
(
&
all
->
list
);
all
=
kzalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
return
-
ENOMEM
;
spin_lock_init
(
&
all
->
par
.
lock
);
all
->
par
.
sdev
=
sdev
;
all
->
par
.
physbase
=
sdev
->
reg_addrs
[
0
].
phys_addr
;
all
->
par
.
physbase
=
op
->
resource
[
0
].
start
;
all
->
par
.
which_io
=
op
->
resource
[
0
].
flags
&
IORESOURCE_BITS
;
sbusfb_fill_var
(
&
all
->
info
.
var
,
sdev
->
prom_
node
,
8
);
sbusfb_fill_var
(
&
all
->
info
.
var
,
dp
->
node
,
8
);
all
->
info
.
var
.
red
.
length
=
8
;
all
->
info
.
var
.
green
.
length
=
8
;
all
->
info
.
var
.
blue
.
length
=
8
;
linebytes
=
prom_getintdefault
(
sdev
->
prom_node
,
"linebytes"
,
all
->
info
.
var
.
xres
);
linebytes
=
of_getintprop_default
(
dp
,
"linebytes"
,
all
->
info
.
var
.
xres
);
all
->
par
.
fbsize
=
PAGE_ALIGN
(
linebytes
*
all
->
info
.
var
.
yres
);
if
(
prom_getbool
(
sdev
->
prom_node
,
"dblbuf"
))
if
(
of_find_property
(
dp
,
"dblbuf"
,
NULL
))
all
->
par
.
fbsize
*=
4
;
all
->
par
.
fbc
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
CG6_FBC_OFFSET
,
4096
,
"cgsix fbc"
);
all
->
par
.
tec
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
CG6_TEC_OFFSET
,
sizeof
(
struct
cg6_tec
),
"cgsix tec"
);
all
->
par
.
thc
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
CG6_THC_OFFSET
,
sizeof
(
struct
cg6_thc
),
"cgsix thc"
);
all
->
par
.
bt
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
CG6_BROOKTREE_OFFSET
,
sizeof
(
struct
bt_regs
),
"cgsix dac"
);
all
->
par
.
fhc
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
CG6_FHC_OFFSET
,
sizeof
(
u32
),
"cgsix fhc"
);
all
->
par
.
fbc
=
of_ioremap
(
&
op
->
resource
[
0
],
CG6_FBC_OFFSET
,
4096
,
"cgsix fbc"
);
all
->
par
.
tec
=
of_ioremap
(
&
op
->
resource
[
0
],
CG6_TEC_OFFSET
,
sizeof
(
struct
cg6_tec
),
"cgsix tec"
);
all
->
par
.
thc
=
of_ioremap
(
&
op
->
resource
[
0
],
CG6_THC_OFFSET
,
sizeof
(
struct
cg6_thc
),
"cgsix thc"
);
all
->
par
.
bt
=
of_ioremap
(
&
op
->
resource
[
0
],
CG6_BROOKTREE_OFFSET
,
sizeof
(
struct
bt_regs
),
"cgsix dac"
);
all
->
par
.
fhc
=
of_ioremap
(
&
op
->
resource
[
0
],
CG6_FHC_OFFSET
,
sizeof
(
u32
),
"cgsix fhc"
);
all
->
info
.
flags
=
FBINFO_DEFAULT
|
FBINFO_HWACCEL_IMAGEBLIT
|
FBINFO_HWACCEL_COPYAREA
|
FBINFO_HWACCEL_FILLRECT
;
all
->
info
.
fbops
=
&
cg6_ops
;
#ifdef CONFIG_SPARC32
all
->
info
.
screen_base
=
(
char
__iomem
*
)
prom_getintdefault
(
sdev
->
prom_node
,
"address"
,
0
);
#endif
if
(
!
all
->
info
.
screen_base
)
all
->
info
.
screen_base
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
CG6_RAM_OFFSET
,
all
->
par
.
fbsize
,
"cgsix ram"
);
all
->
info
.
screen_base
=
of_ioremap
(
&
op
->
resource
[
0
],
CG6_RAM_OFFSET
,
all
->
par
.
fbsize
,
"cgsix ram"
);
if
(
!
all
->
par
.
fbc
||
!
all
->
par
.
tec
||
!
all
->
par
.
thc
||
!
all
->
par
.
bt
||
!
all
->
par
.
fhc
||
!
all
->
info
.
screen_base
)
{
cg6_unmap_regs
(
all
);
kfree
(
all
);
return
-
ENOMEM
;
}
all
->
info
.
par
=
&
all
->
par
;
all
->
info
.
var
.
accel_flags
=
FB_ACCELF_TEXT
;
...
...
@@ -723,72 +734,90 @@ static void cg6_init_one(struct sbus_dev *sdev)
cg6_blank
(
0
,
&
all
->
info
);
if
(
fb_alloc_cmap
(
&
all
->
info
.
cmap
,
256
,
0
))
{
printk
(
KERN_ERR
"cg6: Could not allocate color map.
\n
"
);
cg6_unmap_regs
(
all
);
kfree
(
all
);
return
;
return
-
ENOMEM
;
}
fb_set_cmap
(
&
all
->
info
.
cmap
,
&
all
->
info
);
cg6_init_fix
(
&
all
->
info
,
linebytes
);
if
(
register_framebuffer
(
&
all
->
info
)
<
0
)
{
printk
(
KERN_ERR
"cg6: Could not register framebuffer.
\n
"
);
err
=
register_framebuffer
(
&
all
->
info
);
if
(
err
<
0
)
{
cg6_unmap_regs
(
all
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
kfree
(
all
);
return
;
return
err
;
}
list_add
(
&
all
->
list
,
&
cg6_list
);
dev_set_drvdata
(
&
op
->
dev
,
all
);
printk
(
"cg6: CGsix [%s] at %lx:%lx
\n
"
,
printk
(
"%s: CGsix [%s] at %lx:%lx
\n
"
,
dp
->
full_name
,
all
->
info
.
fix
.
id
,
(
long
)
sdev
->
reg_addrs
[
0
].
which_io
,
(
long
)
sdev
->
reg_addrs
[
0
].
phys_addr
);
all
->
par
.
which_io
,
all
->
par
.
physbase
);
return
0
;
}
int
__init
cg6_init
(
void
)
static
int
__devinit
cg6_probe
(
struct
of_device
*
dev
,
const
struct
of_device_id
*
match
)
{
struct
sbus_bus
*
sbus
;
struct
sbus_dev
*
sdev
;
struct
of_device
*
op
=
to_of_device
(
&
dev
->
dev
);
if
(
fb_get_options
(
"cg6fb"
,
NULL
))
return
-
ENODEV
;
return
cg6_init_one
(
op
);
}
for_all_sbusdev
(
sdev
,
sbus
)
{
if
(
!
strcmp
(
sdev
->
prom_name
,
"cgsix"
)
||
!
strcmp
(
sdev
->
prom_name
,
"cgthree+"
))
cg6_init_one
(
sdev
);
}
static
int
__devexit
cg6_remove
(
struct
of_device
*
dev
)
{
struct
all_info
*
all
=
dev_get_drvdata
(
&
dev
->
dev
);
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
cg6_unmap_regs
(
all
);
kfree
(
all
);
dev_set_drvdata
(
&
dev
->
dev
,
NULL
);
return
0
;
}
void
__exit
cg6_exit
(
void
)
{
struct
list_head
*
pos
,
*
tmp
;
static
struct
of_device_id
cg6_match
[]
=
{
{
.
name
=
"cgsix"
,
},
{
.
name
=
"cgthree+"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
cg6_match
);
list_for_each_safe
(
pos
,
tmp
,
&
cg6_list
)
{
struct
all_info
*
all
=
list_entry
(
pos
,
typeof
(
*
all
),
list
);
static
struct
of_platform_driver
cg6_driver
=
{
.
name
=
"cg6"
,
.
match_table
=
cg6_match
,
.
probe
=
cg6_probe
,
.
remove
=
__devexit_p
(
cg6_remove
),
};
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
kfree
(
all
);
}
static
int
__init
cg6_init
(
void
)
{
if
(
fb_get_options
(
"cg6fb"
,
NULL
))
return
-
ENODEV
;
return
of_register_driver
(
&
cg6_driver
,
&
of_bus_type
);
}
int
__init
cg6_setup
(
char
*
arg
)
static
void
__exit
cg6_exit
(
void
)
{
/* No cmdline options yet... */
return
0
;
of_unregister_driver
(
&
cg6_driver
);
}
module_init
(
cg6_init
);
#ifdef MODULE
module_exit
(
cg6_exit
);
#endif
MODULE_DESCRIPTION
(
"framebuffer driver for CGsix chipsets"
);
MODULE_AUTHOR
(
"David S. Miller <davem@redhat.com>"
);
MODULE_AUTHOR
(
"David S. Miller <davem@davemloft.net>"
);
MODULE_VERSION
(
"2.0"
);
MODULE_LICENSE
(
"GPL"
);
drivers/video/ffb.c
View file @
50312ce9
/* ffb.c: Creator/Elite3D frame buffer driver
*
* Copyright (C) 2003
David S. Miller (davem@redhat.com
)
* Copyright (C) 2003
, 2006 David S. Miller (davem@davemloft.net
)
* Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
*
* Driver layout based loosely on tgafb.c, see that file for credits.
...
...
@@ -19,7 +19,8 @@
#include <asm/io.h>
#include <asm/upa.h>
#include <asm/oplib.h>
#include <asm/prom.h>
#include <asm/of_device.h>
#include <asm/fbio.h>
#include "sbuslib.h"
...
...
@@ -184,161 +185,161 @@ static struct fb_ops ffb_ops = {
struct
ffb_fbc
{
/* Next vertex registers */
u32
xxx1
[
3
];
volatile
u32
alpha
;
volatile
u32
red
;
volatile
u32
green
;
volatile
u32
blue
;
volatile
u32
depth
;
volatile
u32
y
;
volatile
u32
x
;
u32
xxx2
[
2
];
volatile
u32
ryf
;
volatile
u32
rxf
;
u32
xxx3
[
2
];
u32
xxx1
[
3
];
u32
alpha
;
u32
red
;
u32
green
;
u32
blue
;
u32
depth
;
u32
y
;
u32
x
;
u32
xxx2
[
2
];
u32
ryf
;
u32
rxf
;
u32
xxx3
[
2
];
volatile
u32
dmyf
;
volatile
u32
dmxf
;
u32
xxx4
[
2
];
volatile
u32
ebyi
;
volatile
u32
ebxi
;
u32
xxx5
[
2
];
volatile
u32
by
;
volatile
u32
bx
;
u32
dy
;
u32
dx
;
volatile
u32
bh
;
volatile
u32
bw
;
u32
xxx6
[
2
];
u32
dmyf
;
u32
dmxf
;
u32
xxx4
[
2
];
u32
ebyi
;
u32
ebxi
;
u32
xxx5
[
2
];
u32
by
;
u32
bx
;
u32
dy
;
u32
dx
;
u32
bh
;
u32
bw
;
u32
xxx6
[
2
];
u32
xxx7
[
32
];
u32
xxx7
[
32
];
/* Setup unit vertex state register */
volatile
u32
suvtx
;
u32
xxx8
[
63
];
u32
suvtx
;
u32
xxx8
[
63
];
/* Control registers */
volatile
u32
ppc
;
volatile
u32
wid
;
volatile
u32
fg
;
volatile
u32
bg
;
volatile
u32
consty
;
volatile
u32
constz
;
volatile
u32
xclip
;
volatile
u32
dcss
;
volatile
u32
vclipmin
;
volatile
u32
vclipmax
;
volatile
u32
vclipzmin
;
volatile
u32
vclipzmax
;
volatile
u32
dcsf
;
volatile
u32
dcsb
;
volatile
u32
dczf
;
volatile
u32
dczb
;
u32
ppc
;
u32
wid
;
u32
fg
;
u32
bg
;
u32
consty
;
u32
constz
;
u32
xclip
;
u32
dcss
;
u32
vclipmin
;
u32
vclipmax
;
u32
vclipzmin
;
u32
vclipzmax
;
u32
dcsf
;
u32
dcsb
;
u32
dczf
;
u32
dczb
;
u32
xxx9
;
volatile
u32
blendc
;
volatile
u32
blendc1
;
volatile
u32
blendc2
;
volatile
u32
fbramitc
;
volatile
u32
fbc
;
volatile
u32
rop
;
volatile
u32
cmp
;
volatile
u32
matchab
;
volatile
u32
matchc
;
volatile
u32
magnab
;
volatile
u32
magnc
;
volatile
u32
fbcfg0
;
volatile
u32
fbcfg1
;
volatile
u32
fbcfg2
;
volatile
u32
fbcfg3
;
u32
xxx9
;
u32
blendc
;
u32
blendc1
;
u32
blendc2
;
u32
fbramitc
;
u32
fbc
;
u32
rop
;
u32
cmp
;
u32
matchab
;
u32
matchc
;
u32
magnab
;
u32
magnc
;
u32
fbcfg0
;
u32
fbcfg1
;
u32
fbcfg2
;
u32
fbcfg3
;
u32
ppcfg
;
volatile
u32
pick
;
volatile
u32
fillmode
;
volatile
u32
fbramwac
;
volatile
u32
pmask
;
volatile
u32
xpmask
;
volatile
u32
ypmask
;
volatile
u32
zpmask
;
volatile
u32
clip0min
;
volatile
u32
clip0max
;
volatile
u32
clip1min
;
volatile
u32
clip1max
;
volatile
u32
clip2min
;
volatile
u32
clip2max
;
volatile
u32
clip3min
;
volatile
u32
clip3max
;
u32
ppcfg
;
u32
pick
;
u32
fillmode
;
u32
fbramwac
;
u32
pmask
;
u32
xpmask
;
u32
ypmask
;
u32
zpmask
;
u32
clip0min
;
u32
clip0max
;
u32
clip1min
;
u32
clip1max
;
u32
clip2min
;
u32
clip2max
;
u32
clip3min
;
u32
clip3max
;
/* New 3dRAM III support regs */
volatile
u32
rawblend2
;
volatile
u32
rawpreblend
;
volatile
u32
rawstencil
;
volatile
u32
rawstencilctl
;
volatile
u32
threedram1
;
volatile
u32
threedram2
;
volatile
u32
passin
;
volatile
u32
rawclrdepth
;
volatile
u32
rawpmask
;
volatile
u32
rawcsrc
;
volatile
u32
rawmatch
;
volatile
u32
rawmagn
;
volatile
u32
rawropblend
;
volatile
u32
rawcmp
;
volatile
u32
rawwac
;
volatile
u32
fbramid
;
u32
rawblend2
;
u32
rawpreblend
;
u32
rawstencil
;
u32
rawstencilctl
;
u32
threedram1
;
u32
threedram2
;
u32
passin
;
u32
rawclrdepth
;
u32
rawpmask
;
u32
rawcsrc
;
u32
rawmatch
;
u32
rawmagn
;
u32
rawropblend
;
u32
rawcmp
;
u32
rawwac
;
u32
fbramid
;
volatile
u32
drawop
;
u32
xxx10
[
2
];
volatile
u32
fontlpat
;
u32
xxx11
;
volatile
u32
fontxy
;
volatile
u32
fontw
;
volatile
u32
fontinc
;
volatile
u32
font
;
u32
xxx12
[
3
];
volatile
u32
blend2
;
volatile
u32
preblend
;
volatile
u32
stencil
;
volatile
u32
stencilctl
;
u32
xxx13
[
4
];
volatile
u32
dcss1
;
volatile
u32
dcss2
;
volatile
u32
dcss3
;
volatile
u32
widpmask
;
volatile
u32
dcs2
;
volatile
u32
dcs3
;
volatile
u32
dcs4
;
u32
xxx14
;
volatile
u32
dcd2
;
volatile
u32
dcd3
;
volatile
u32
dcd4
;
u32
xxx15
;
u32
drawop
;
u32
xxx10
[
2
];
u32
fontlpat
;
u32
xxx11
;
u32
fontxy
;
u32
fontw
;
u32
fontinc
;
u32
font
;
u32
xxx12
[
3
];
u32
blend2
;
u32
preblend
;
u32
stencil
;
u32
stencilctl
;
u32
xxx13
[
4
];
u32
dcss1
;
u32
dcss2
;
u32
dcss3
;
u32
widpmask
;
u32
dcs2
;
u32
dcs3
;
u32
dcs4
;
u32
xxx14
;
u32
dcd2
;
u32
dcd3
;
u32
dcd4
;
u32
xxx15
;
volatile
u32
pattern
[
32
];
u32
pattern
[
32
];
u32
xxx16
[
256
];
u32
xxx16
[
256
];
volatile
u32
devid
;
u32
xxx17
[
63
];
u32
devid
;
u32
xxx17
[
63
];
volatile
u32
ucsr
;
u32
xxx18
[
31
];
u32
ucsr
;
u32
xxx18
[
31
];
volatile
u32
mer
;
u32
mer
;
};
struct
ffb_dac
{
volatile
u32
type
;
volatile
u32
value
;
volatile
u32
type2
;
volatile
u32
value2
;
u32
type
;
u32
value
;
u32
type2
;
u32
value2
;
};
struct
ffb_par
{
spinlock_t
lock
;
struct
ffb_fbc
*
fbc
;
struct
ffb_dac
*
dac
;
struct
ffb_fbc
__iomem
*
fbc
;
struct
ffb_dac
__iomem
*
dac
;
u32
flags
;
#define FFB_FLAG_AFB 0x00000001
...
...
@@ -353,16 +354,13 @@ struct ffb_par {
unsigned
long
physbase
;
unsigned
long
fbsize
;
char
name
[
64
];
int
prom_node
;
int
prom_parent_node
;
int
dac_rev
;
int
board_type
;
};
static
void
FFBFifo
(
struct
ffb_par
*
par
,
int
n
)
{
struct
ffb_fbc
*
fbc
;
struct
ffb_fbc
__iomem
*
fbc
;
int
cache
=
par
->
fifo_cache
;
if
(
cache
-
n
<
0
)
{
...
...
@@ -375,7 +373,7 @@ static void FFBFifo(struct ffb_par *par, int n)
static
void
FFBWait
(
struct
ffb_par
*
par
)
{
struct
ffb_fbc
*
fbc
;
struct
ffb_fbc
__iomem
*
fbc
;
int
limit
=
10000
;
fbc
=
par
->
fbc
;
...
...
@@ -408,8 +406,8 @@ static __inline__ void ffb_rop(struct ffb_par *par, u32 rop)
static
void
ffb_switch_from_graph
(
struct
ffb_par
*
par
)
{
struct
ffb_fbc
*
fbc
=
par
->
fbc
;
struct
ffb_dac
*
dac
=
par
->
dac
;
struct
ffb_fbc
__iomem
*
fbc
=
par
->
fbc
;
struct
ffb_dac
__iomem
*
dac
=
par
->
dac
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
par
->
lock
,
flags
);
...
...
@@ -462,7 +460,7 @@ static int ffb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
static
void
ffb_fillrect
(
struct
fb_info
*
info
,
const
struct
fb_fillrect
*
rect
)
{
struct
ffb_par
*
par
=
(
struct
ffb_par
*
)
info
->
par
;
struct
ffb_fbc
*
fbc
=
par
->
fbc
;
struct
ffb_fbc
__iomem
*
fbc
=
par
->
fbc
;
unsigned
long
flags
;
u32
fg
;
...
...
@@ -505,7 +503,7 @@ static void
ffb_copyarea
(
struct
fb_info
*
info
,
const
struct
fb_copyarea
*
area
)
{
struct
ffb_par
*
par
=
(
struct
ffb_par
*
)
info
->
par
;
struct
ffb_fbc
*
fbc
=
par
->
fbc
;
struct
ffb_fbc
__iomem
*
fbc
=
par
->
fbc
;
unsigned
long
flags
;
if
(
area
->
dx
!=
area
->
sx
||
...
...
@@ -541,7 +539,7 @@ ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
static
void
ffb_imageblit
(
struct
fb_info
*
info
,
const
struct
fb_image
*
image
)
{
struct
ffb_par
*
par
=
(
struct
ffb_par
*
)
info
->
par
;
struct
ffb_fbc
*
fbc
=
par
->
fbc
;
struct
ffb_fbc
__iomem
*
fbc
=
par
->
fbc
;
const
u8
*
data
=
image
->
data
;
unsigned
long
flags
;
u32
fg
,
bg
,
xy
;
...
...
@@ -664,7 +662,7 @@ static int
ffb_blank
(
int
blank
,
struct
fb_info
*
info
)
{
struct
ffb_par
*
par
=
(
struct
ffb_par
*
)
info
->
par
;
struct
ffb_dac
*
dac
=
par
->
dac
;
struct
ffb_dac
__iomem
*
dac
=
par
->
dac
;
unsigned
long
flags
;
u32
tmp
;
...
...
@@ -883,78 +881,42 @@ ffb_init_fix(struct fb_info *info)
info
->
fix
.
accel
=
FB_ACCEL_SUN_CREATOR
;
}
static
int
ffb_apply_upa_parent_ranges
(
int
parent
,
struct
linux_prom64_registers
*
regs
)
{
struct
linux_prom64_ranges
ranges
[
PROMREG_MAX
];
char
name
[
128
];
int
len
,
i
;
prom_getproperty
(
parent
,
"name"
,
name
,
sizeof
(
name
));
if
(
strcmp
(
name
,
"upa"
)
!=
0
)
return
0
;
len
=
prom_getproperty
(
parent
,
"ranges"
,
(
void
*
)
ranges
,
sizeof
(
ranges
));
if
(
len
<=
0
)
return
1
;
len
/=
sizeof
(
struct
linux_prom64_ranges
);
for
(
i
=
0
;
i
<
len
;
i
++
)
{
struct
linux_prom64_ranges
*
rng
=
&
ranges
[
i
];
u64
phys_addr
=
regs
->
phys_addr
;
if
(
phys_addr
>=
rng
->
ot_child_base
&&
phys_addr
<
(
rng
->
ot_child_base
+
rng
->
or_size
))
{
regs
->
phys_addr
-=
rng
->
ot_child_base
;
regs
->
phys_addr
+=
rng
->
ot_parent_base
;
return
0
;
}
}
return
1
;
}
struct
all_info
{
struct
fb_info
info
;
struct
ffb_par
par
;
u32
pseudo_palette
[
256
];
struct
list_head
list
;
};
static
LIST_HEAD
(
ffb_list
);
static
void
ffb_init_one
(
int
node
,
int
parent
)
static
int
ffb_init_one
(
struct
of_device
*
op
)
{
struct
linux_prom64_registers
regs
[
2
*
PROMREG_MAX
]
;
struct
ffb_fbc
*
fbc
;
struct
ffb_dac
*
dac
;
struct
device_node
*
dp
=
op
->
node
;
struct
ffb_fbc
__iomem
*
fbc
;
struct
ffb_dac
__iomem
*
dac
;
struct
all_info
*
all
;
int
err
;
if
(
prom_getproperty
(
node
,
"reg"
,
(
void
*
)
regs
,
sizeof
(
regs
))
<=
0
)
{
printk
(
"ffb: Cannot get reg device node property.
\n
"
);
return
;
}
all
=
kzalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
return
-
ENOMEM
;
if
(
ffb_apply_upa_parent_ranges
(
parent
,
&
regs
[
0
]))
{
printk
(
"ffb: Cannot apply parent ranges to regs.
\n
"
);
return
;
spin_lock_init
(
&
all
->
par
.
lock
);
all
->
par
.
fbc
=
of_ioremap
(
&
op
->
resource
[
2
],
0
,
sizeof
(
struct
ffb_fbc
),
"ffb fbc"
);
if
(
!
all
->
par
.
fbc
)
{
kfree
(
all
);
return
-
ENOMEM
;
}
all
=
kmalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
{
printk
(
KERN_ERR
"ffb: Cannot allocate memory.
\n
"
);
return
;
all
->
par
.
dac
=
of_ioremap
(
&
op
->
resource
[
1
],
0
,
sizeof
(
struct
ffb_dac
),
"ffb dac"
);
if
(
!
all
->
par
.
dac
)
{
of_iounmap
(
all
->
par
.
fbc
,
sizeof
(
struct
ffb_fbc
));
kfree
(
all
);
return
-
ENOMEM
;
}
memset
(
all
,
0
,
sizeof
(
*
all
));
INIT_LIST_HEAD
(
&
all
->
list
);
spin_lock_init
(
&
all
->
par
.
lock
);
all
->
par
.
fbc
=
(
struct
ffb_fbc
*
)(
regs
[
0
].
phys_addr
+
FFB_FBC_REGS_POFF
);
all
->
par
.
dac
=
(
struct
ffb_dac
*
)(
regs
[
0
].
phys_addr
+
FFB_DAC_POFF
);
all
->
par
.
rop_cache
=
FFB_ROP_NEW
;
all
->
par
.
physbase
=
regs
[
0
].
phys_addr
;
all
->
par
.
prom_node
=
node
;
all
->
par
.
prom_parent_node
=
parent
;
all
->
par
.
physbase
=
op
->
resource
[
0
].
start
;
/* Don't mention copyarea, so SCROLL_REDRAW is always
* used. It is the fastest on this chip.
...
...
@@ -968,7 +930,7 @@ static void ffb_init_one(int node, int parent)
all
->
info
.
par
=
&
all
->
par
;
all
->
info
.
pseudo_palette
=
all
->
pseudo_palette
;
sbusfb_fill_var
(
&
all
->
info
.
var
,
all
->
par
.
prom_
node
,
32
);
sbusfb_fill_var
(
&
all
->
info
.
var
,
dp
->
node
,
32
);
all
->
par
.
fbsize
=
PAGE_ALIGN
(
all
->
info
.
var
.
xres
*
all
->
info
.
var
.
yres
*
4
);
...
...
@@ -976,14 +938,13 @@ static void ffb_init_one(int node, int parent)
all
->
info
.
var
.
accel_flags
=
FB_ACCELF_TEXT
;
prom_getstring
(
node
,
"name"
,
all
->
par
.
name
,
sizeof
(
all
->
par
.
name
));
if
(
!
strcmp
(
all
->
par
.
name
,
"SUNW,afb"
))
if
(
!
strcmp
(
dp
->
name
,
"SUNW,afb"
))
all
->
par
.
flags
|=
FFB_FLAG_AFB
;
all
->
par
.
board_type
=
prom_getintdefault
(
node
,
"board_type"
,
0
);
all
->
par
.
board_type
=
of_getintprop_default
(
dp
,
"board_type"
,
0
);
fbc
=
all
->
par
.
fbc
;
if
((
upa_readl
(
&
fbc
->
ucsr
)
&
FFB_UCSR_ALL_ERRORS
)
!=
0
)
if
((
upa_readl
(
&
fbc
->
ucsr
)
&
FFB_UCSR_ALL_ERRORS
)
!=
0
)
upa_writel
(
FFB_UCSR_ALL_ERRORS
,
&
fbc
->
ucsr
);
ffb_switch_from_graph
(
&
all
->
par
);
...
...
@@ -1008,81 +969,88 @@ static void ffb_init_one(int node, int parent)
if
(
fb_alloc_cmap
(
&
all
->
info
.
cmap
,
256
,
0
))
{
printk
(
KERN_ERR
"ffb: Could not allocate color map.
\n
"
);
kfree
(
all
);
return
;
return
-
ENOMEM
;
}
ffb_init_fix
(
&
all
->
info
);
if
(
register_framebuffer
(
&
all
->
info
)
<
0
)
{
err
=
register_framebuffer
(
&
all
->
info
);
if
(
err
<
0
)
{
printk
(
KERN_ERR
"ffb: Could not register framebuffer.
\n
"
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
kfree
(
all
);
return
;
return
err
;
}
list_add
(
&
all
->
list
,
&
ffb_list
);
dev_set_drvdata
(
&
op
->
dev
,
all
);
printk
(
"ffb: %s at %016lx type %d DAC %d
\n
"
,
printk
(
"%s: %s at %016lx, type %d, DAC revision %d
\n
"
,
dp
->
full_name
,
((
all
->
par
.
flags
&
FFB_FLAG_AFB
)
?
"AFB"
:
"FFB"
),
regs
[
0
].
phys_addr
,
all
->
par
.
board_type
,
all
->
par
.
dac_rev
);
all
->
par
.
physbase
,
all
->
par
.
board_type
,
all
->
par
.
dac_rev
);
return
0
;
}
static
void
ffb_scan_siblings
(
int
root
)
static
int
__devinit
ffb_probe
(
struct
of_device
*
dev
,
const
struct
of_device_id
*
match
)
{
int
node
,
child
;
child
=
prom_getchild
(
root
);
for
(
node
=
prom_searchsiblings
(
child
,
"SUNW,ffb"
);
node
;
node
=
prom_searchsiblings
(
prom_getsibling
(
node
),
"SUNW,ffb"
))
ffb_init_one
(
node
,
root
);
for
(
node
=
prom_searchsiblings
(
child
,
"SUNW,afb"
);
node
;
node
=
prom_searchsiblings
(
prom_getsibling
(
node
),
"SUNW,afb"
))
ffb_init_one
(
node
,
root
);
struct
of_device
*
op
=
to_of_device
(
&
dev
->
dev
);
return
ffb_init_one
(
op
);
}
int
__init
ffb_init
(
void
)
static
int
__devexit
ffb_remove
(
struct
of_device
*
dev
)
{
int
root
;
struct
all_info
*
all
=
dev_get_drvdata
(
&
dev
->
dev
)
;
if
(
fb_get_options
(
"ffb"
,
NULL
))
return
-
ENODEV
;
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
)
;
ffb_scan_siblings
(
prom_root_node
);
of_iounmap
(
all
->
par
.
fbc
,
sizeof
(
struct
ffb_fbc
));
of_iounmap
(
all
->
par
.
dac
,
sizeof
(
struct
ffb_dac
));
root
=
prom_getchild
(
prom_root_node
);
for
(
root
=
prom_searchsiblings
(
root
,
"upa"
);
root
;
root
=
prom_searchsiblings
(
prom_getsibling
(
root
),
"upa"
))
ffb_scan_siblings
(
root
);
kfree
(
all
);
dev_set_drvdata
(
&
dev
->
dev
,
NULL
);
return
0
;
}
void
__exit
ffb_exit
(
void
)
{
struct
list_head
*
pos
,
*
tmp
;
static
struct
of_device_id
ffb_match
[]
=
{
{
.
name
=
"SUNW,ffb"
,
},
{
.
name
=
"SUNW,afb"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
ffb_match
);
static
struct
of_platform_driver
ffb_driver
=
{
.
name
=
"ffb"
,
.
match_table
=
ffb_match
,
.
probe
=
ffb_probe
,
.
remove
=
__devexit_p
(
ffb_remove
),
};
list_for_each_safe
(
pos
,
tmp
,
&
ffb_list
)
{
struct
all_info
*
all
=
list_entry
(
pos
,
typeof
(
*
all
),
list
);
int
__init
ffb_init
(
void
)
{
if
(
fb_get_options
(
"ffb"
,
NULL
))
return
-
ENODEV
;
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
kfree
(
all
);
}
return
of_register_driver
(
&
ffb_driver
,
&
of_bus_type
);
}
int
__init
ffb_setup
(
char
*
arg
)
void
__exit
ffb_exit
(
void
)
{
/* No cmdline options yet... */
return
0
;
of_unregister_driver
(
&
ffb_driver
);
}
module_init
(
ffb_init
);
#ifdef MODULE
module_exit
(
ffb_exit
);
#endif
MODULE_DESCRIPTION
(
"framebuffer driver for Creator/Elite3D chipsets"
);
MODULE_AUTHOR
(
"David S. Miller <davem@redhat.com>"
);
MODULE_AUTHOR
(
"David S. Miller <davem@davemloft.net>"
);
MODULE_VERSION
(
"2.0"
);
MODULE_LICENSE
(
"GPL"
);
drivers/video/leo.c
View file @
50312ce9
/* leo.c: LEO frame buffer driver
*
* Copyright (C) 2003
David S. Miller (davem@redhat.com
)
* Copyright (C) 2003
, 2006 David S. Miller (davem@davemloft.net
)
* Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz)
* Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz)
*
...
...
@@ -18,8 +18,8 @@
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/
sbus
.h>
#include <asm/o
plib
.h>
#include <asm/
prom
.h>
#include <asm/o
f_device
.h>
#include <asm/fbio.h>
#include "sbuslib.h"
...
...
@@ -80,10 +80,10 @@ static struct fb_ops leo_ops = {
struct
leo_cursor
{
u8
xxx0
[
16
];
volatile
u32
cur_type
;
volatile
u32
cur_misc
;
volatile
u32
cur_cursxy
;
volatile
u32
cur_data
;
u32
cur_type
;
u32
cur_misc
;
u32
cur_cursxy
;
u32
cur_data
;
};
#define LEO_KRN_TYPE_CLUT0 0x00001000
...
...
@@ -99,27 +99,27 @@ struct leo_cursor {
#define LEO_KRN_CSR_UNK2 0x00000001
struct
leo_lx_krn
{
volatile
u32
krn_type
;
volatile
u32
krn_csr
;
volatile
u32
krn_value
;
u32
krn_type
;
u32
krn_csr
;
u32
krn_value
;
};
struct
leo_lc_ss0_krn
{
volatile
u32
misc
;
u32
misc
;
u8
xxx0
[
0x800
-
4
];
volatile
u32
rev
;
u32
rev
;
};
struct
leo_lc_ss0_usr
{
volatile
u32
csr
;
volatile
u32
addrspace
;
volatile
u32
fontmsk
;
volatile
u32
fontt
;
volatile
u32
extent
;
volatile
u32
src
;
u32
csr
;
u32
addrspace
;
u32
fontmsk
;
u32
fontt
;
u32
extent
;
u32
src
;
u32
dst
;
volatile
u32
copy
;
volatile
u32
fill
;
u32
copy
;
u32
fill
;
};
struct
leo_lc_ss1_krn
{
...
...
@@ -132,47 +132,47 @@ struct leo_lc_ss1_usr {
struct
leo_ld
{
u8
xxx0
[
0xe00
];
volatile
u32
csr
;
volatile
u32
wid
;
volatile
u32
wmask
;
volatile
u32
widclip
;
volatile
u32
vclipmin
;
volatile
u32
vclipmax
;
volatile
u32
pickmin
;
/* SS1 only */
volatile
u32
pickmax
;
/* SS1 only */
volatile
u32
fg
;
volatile
u32
bg
;
volatile
u32
src
;
/* Copy/Scroll (SS0 only) */
volatile
u32
dst
;
/* Copy/Scroll/Fill (SS0 only) */
volatile
u32
extent
;
/* Copy/Scroll/Fill size (SS0 only) */
u32
csr
;
u32
wid
;
u32
wmask
;
u32
widclip
;
u32
vclipmin
;
u32
vclipmax
;
u32
pickmin
;
/* SS1 only */
u32
pickmax
;
/* SS1 only */
u32
fg
;
u32
bg
;
u32
src
;
/* Copy/Scroll (SS0 only) */
u32
dst
;
/* Copy/Scroll/Fill (SS0 only) */
u32
extent
;
/* Copy/Scroll/Fill size (SS0 only) */
u32
xxx1
[
3
];
volatile
u32
setsem
;
/* SS1 only */
volatile
u32
clrsem
;
/* SS1 only */
volatile
u32
clrpick
;
/* SS1 only */
volatile
u32
clrdat
;
/* SS1 only */
volatile
u32
alpha
;
/* SS1 only */
u32
setsem
;
/* SS1 only */
u32
clrsem
;
/* SS1 only */
u32
clrpick
;
/* SS1 only */
u32
clrdat
;
/* SS1 only */
u32
alpha
;
/* SS1 only */
u8
xxx2
[
0x2c
];
volatile
u32
winbg
;
volatile
u32
planemask
;
volatile
u32
rop
;
volatile
u32
z
;
volatile
u32
dczf
;
/* SS1 only */
volatile
u32
dczb
;
/* SS1 only */
volatile
u32
dcs
;
/* SS1 only */
volatile
u32
dczs
;
/* SS1 only */
volatile
u32
pickfb
;
/* SS1 only */
volatile
u32
pickbb
;
/* SS1 only */
volatile
u32
dcfc
;
/* SS1 only */
volatile
u32
forcecol
;
/* SS1 only */
volatile
u32
door
[
8
];
/* SS1 only */
volatile
u32
pick
[
5
];
/* SS1 only */
u32
winbg
;
u32
planemask
;
u32
rop
;
u32
z
;
u32
dczf
;
/* SS1 only */
u32
dczb
;
/* SS1 only */
u32
dcs
;
/* SS1 only */
u32
dczs
;
/* SS1 only */
u32
pickfb
;
/* SS1 only */
u32
pickbb
;
/* SS1 only */
u32
dcfc
;
/* SS1 only */
u32
forcecol
;
/* SS1 only */
u32
door
[
8
];
/* SS1 only */
u32
pick
[
5
];
/* SS1 only */
};
#define LEO_SS1_MISC_ENABLE 0x00000001
#define LEO_SS1_MISC_STEREO 0x00000002
struct
leo_ld_ss1
{
u8
xxx0
[
0xef4
];
volatile
u32
ss1_misc
;
u8
xxx0
[
0xef4
];
u32
ss1_misc
;
};
struct
leo_ld_gbl
{
...
...
@@ -193,9 +193,8 @@ struct leo_par {
#define LEO_FLAG_BLANKED 0x00000001
unsigned
long
physbase
;
unsigned
long
which_io
;
unsigned
long
fbsize
;
struct
sbus_dev
*
sdev
;
};
static
void
leo_wait
(
struct
leo_lx_krn
__iomem
*
lx_krn
)
...
...
@@ -368,8 +367,7 @@ static int leo_mmap(struct fb_info *info, struct vm_area_struct *vma)
return
sbusfb_mmap_helper
(
leo_mmap_map
,
par
->
physbase
,
par
->
fbsize
,
par
->
sdev
->
reg_addrs
[
0
].
which_io
,
vma
);
par
->
which_io
,
vma
);
}
static
int
leo_ioctl
(
struct
fb_info
*
info
,
unsigned
int
cmd
,
unsigned
long
arg
)
...
...
@@ -385,11 +383,9 @@ static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
*/
static
void
leo_init_fix
(
struct
fb_info
*
info
)
leo_init_fix
(
struct
fb_info
*
info
,
struct
device_node
*
dp
)
{
struct
leo_par
*
par
=
(
struct
leo_par
*
)
info
->
par
;
strlcpy
(
info
->
fix
.
id
,
par
->
sdev
->
prom_name
,
sizeof
(
info
->
fix
.
id
));
strlcpy
(
info
->
fix
.
id
,
dp
->
name
,
sizeof
(
info
->
fix
.
id
));
info
->
fix
.
type
=
FB_TYPE_PACKED_PIXELS
;
info
->
fix
.
visual
=
FB_VISUAL_TRUECOLOR
;
...
...
@@ -532,60 +528,74 @@ static void leo_fixup_var_rgb(struct fb_var_screeninfo *var)
struct
all_info
{
struct
fb_info
info
;
struct
leo_par
par
;
struct
list_head
list
;
};
static
LIST_HEAD
(
leo_list
);
static
void
leo_
init_one
(
struct
sbus_dev
*
sdev
)
static
void
leo_
unmap_regs
(
struct
all_info
*
all
)
{
struct
all_info
*
all
;
int
linebytes
;
if
(
all
->
par
.
lc_ss0_usr
)
of_iounmap
(
all
->
par
.
lc_ss0_usr
,
0x1000
);
if
(
all
->
par
.
ld_ss0
)
of_iounmap
(
all
->
par
.
ld_ss0
,
0x1000
);
if
(
all
->
par
.
ld_ss1
)
of_iounmap
(
all
->
par
.
ld_ss1
,
0x1000
);
if
(
all
->
par
.
lx_krn
)
of_iounmap
(
all
->
par
.
lx_krn
,
0x1000
);
if
(
all
->
par
.
cursor
)
of_iounmap
(
all
->
par
.
cursor
,
sizeof
(
struct
leo_cursor
));
if
(
all
->
info
.
screen_base
)
of_iounmap
(
all
->
info
.
screen_base
,
0x800000
);
}
all
=
kmalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
{
printk
(
KERN_ERR
"leo: Cannot allocate memory.
\n
"
);
return
;
}
memset
(
all
,
0
,
sizeof
(
*
all
));
static
int
__devinit
leo_init_one
(
struct
of_device
*
op
)
{
struct
device_node
*
dp
=
op
->
node
;
struct
all_info
*
all
;
int
linebytes
,
err
;
INIT_LIST_HEAD
(
&
all
->
list
);
all
=
kzalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
return
-
ENOMEM
;
spin_lock_init
(
&
all
->
par
.
lock
);
all
->
par
.
sdev
=
sdev
;
all
->
par
.
physbase
=
sdev
->
reg_addrs
[
0
].
phys_addr
;
all
->
par
.
physbase
=
op
->
resource
[
0
].
start
;
all
->
par
.
which_io
=
op
->
resource
[
0
].
flags
&
IORESOURCE_BITS
;
sbusfb_fill_var
(
&
all
->
info
.
var
,
sdev
->
prom_
node
,
32
);
sbusfb_fill_var
(
&
all
->
info
.
var
,
dp
->
node
,
32
);
leo_fixup_var_rgb
(
&
all
->
info
.
var
);
linebytes
=
prom_getintdefault
(
sdev
->
prom_node
,
"linebytes"
,
all
->
info
.
var
.
xres
);
linebytes
=
of_getintprop_default
(
dp
,
"linebytes"
,
all
->
info
.
var
.
xres
);
all
->
par
.
fbsize
=
PAGE_ALIGN
(
linebytes
*
all
->
info
.
var
.
yres
);
#ifdef CONFIG_SPARC32
all
->
info
.
screen_base
=
(
char
__iomem
*
)
prom_getintdefault
(
sdev
->
prom_node
,
"address"
,
0
);
#endif
if
(
!
all
->
info
.
screen_base
)
all
->
info
.
screen_base
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
LEO_OFF_SS0
,
0x800000
,
"leo ram"
);
all
->
par
.
lc_ss0_usr
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
LEO_OFF_LC_SS0_USR
,
0x1000
,
"leolc ss0usr"
);
of_ioremap
(
&
op
->
resource
[
0
],
LEO_OFF_LC_SS0_USR
,
0x1000
,
"leolc ss0usr"
);
all
->
par
.
ld_ss0
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
LEO_OFF_LD_SS0
,
0x1000
,
"leold ss0"
);
of_ioremap
(
&
op
->
resource
[
0
],
LEO_OFF_LD_SS0
,
0x1000
,
"leold ss0"
);
all
->
par
.
ld_ss1
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
LEO_OFF_LD_SS1
,
0x1000
,
"leold ss1"
);
of_ioremap
(
&
op
->
resource
[
0
],
LEO_OFF_LD_SS1
,
0x1000
,
"leold ss1"
);
all
->
par
.
lx_krn
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
LEO_OFF_LX_KRN
,
0x1000
,
"leolx krn"
);
of_ioremap
(
&
op
->
resource
[
0
],
LEO_OFF_LX_KRN
,
0x1000
,
"leolx krn"
);
all
->
par
.
cursor
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
LEO_OFF_LX_CURSOR
,
sizeof
(
struct
leo_cursor
),
"leolx cursor"
);
of_ioremap
(
&
op
->
resource
[
0
],
LEO_OFF_LX_CURSOR
,
sizeof
(
struct
leo_cursor
),
"leolx cursor"
);
all
->
info
.
screen_base
=
of_ioremap
(
&
op
->
resource
[
0
],
LEO_OFF_SS0
,
0x800000
,
"leo ram"
);
if
(
!
all
->
par
.
lc_ss0_usr
||
!
all
->
par
.
ld_ss0
||
!
all
->
par
.
ld_ss1
||
!
all
->
par
.
lx_krn
||
!
all
->
par
.
cursor
||
!
all
->
info
.
screen_base
)
{
leo_unmap_regs
(
all
);
kfree
(
all
);
return
-
ENOMEM
;
}
all
->
info
.
flags
=
FBINFO_DEFAULT
|
FBINFO_HWACCEL_YPAN
;
all
->
info
.
fbops
=
&
leo_ops
;
...
...
@@ -597,69 +607,85 @@ static void leo_init_one(struct sbus_dev *sdev)
leo_blank
(
0
,
&
all
->
info
);
if
(
fb_alloc_cmap
(
&
all
->
info
.
cmap
,
256
,
0
))
{
printk
(
KERN_ERR
"leo: Could not allocate color map.
\n
"
);
leo_unmap_regs
(
all
);
kfree
(
all
);
return
;
return
-
ENOMEM
;
;
}
leo_init_fix
(
&
all
->
info
);
leo_init_fix
(
&
all
->
info
,
dp
);
if
(
register_framebuffer
(
&
all
->
info
)
<
0
)
{
printk
(
KERN_ERR
"leo: Could not register framebuffer.
\n
"
);
err
=
register_framebuffer
(
&
all
->
info
);
if
(
err
<
0
)
{
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
leo_unmap_regs
(
all
);
kfree
(
all
);
return
;
return
err
;
}
list_add
(
&
all
->
list
,
&
leo_list
);
dev_set_drvdata
(
&
op
->
dev
,
all
);
printk
(
"%s: leo at %lx:%lx
\n
"
,
dp
->
full_name
,
all
->
par
.
which_io
,
all
->
par
.
physbase
);
printk
(
"leo: %s at %lx:%lx
\n
"
,
sdev
->
prom_name
,
(
long
)
sdev
->
reg_addrs
[
0
].
which_io
,
(
long
)
sdev
->
reg_addrs
[
0
].
phys_addr
);
return
0
;
}
int
__init
leo_init
(
void
)
static
int
__devinit
leo_probe
(
struct
of_device
*
dev
,
const
struct
of_device_id
*
match
)
{
struct
sbus_bus
*
sbus
;
struct
sbus_dev
*
sdev
;
struct
of_device
*
op
=
to_of_device
(
&
dev
->
dev
);
if
(
fb_get_options
(
"leofb"
,
NULL
))
return
-
ENODEV
;
return
leo_init_one
(
op
);
}
for_all_sbusdev
(
sdev
,
sbus
)
{
if
(
!
strcmp
(
sdev
->
prom_name
,
"leo"
))
leo_init_one
(
sdev
);
}
static
int
__devexit
leo_remove
(
struct
of_device
*
dev
)
{
struct
all_info
*
all
=
dev_get_drvdata
(
&
dev
->
dev
);
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
leo_unmap_regs
(
all
);
kfree
(
all
);
dev_set_drvdata
(
&
dev
->
dev
,
NULL
);
return
0
;
}
void
__exit
leo_exit
(
void
)
{
struct
list_head
*
pos
,
*
tmp
;
static
struct
of_device_id
leo_match
[]
=
{
{
.
name
=
"leo"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
leo_match
);
static
struct
of_platform_driver
leo_driver
=
{
.
name
=
"leo"
,
.
match_table
=
leo_match
,
.
probe
=
leo_probe
,
.
remove
=
__devexit_p
(
leo_remove
),
};
list_for_each_safe
(
pos
,
tmp
,
&
leo_list
)
{
struct
all_info
*
all
=
list_entry
(
pos
,
typeof
(
*
all
),
list
);
static
int
__init
leo_init
(
void
)
{
if
(
fb_get_options
(
"leofb"
,
NULL
))
return
-
ENODEV
;
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
kfree
(
all
);
}
return
of_register_driver
(
&
leo_driver
,
&
of_bus_type
);
}
int
__init
leo_setup
(
char
*
arg
)
static
void
__exit
leo_exit
(
void
)
{
/* No cmdline options yet... */
return
0
;
of_unregister_driver
(
&
leo_driver
);
}
module_init
(
leo_init
);
#ifdef MODULE
module_exit
(
leo_exit
);
#endif
MODULE_DESCRIPTION
(
"framebuffer driver for LEO chipsets"
);
MODULE_AUTHOR
(
"David S. Miller <davem@redhat.com>"
);
MODULE_AUTHOR
(
"David S. Miller <davem@davemloft.net>"
);
MODULE_VERSION
(
"2.0"
);
MODULE_LICENSE
(
"GPL"
);
drivers/video/p9100.c
View file @
50312ce9
/* p9100.c: P9100 frame buffer driver
*
* Copyright (C) 2003
David S. Miller (davem@redhat.com
)
* Copyright (C) 2003
, 2006 David S. Miller (davem@davemloft.net
)
* Copyright 1999 Derrick J Brashear (shadow@dementia.org)
*
* Driver layout based loosely on tgafb.c, see that file for credits.
...
...
@@ -17,8 +17,8 @@
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/
sbus
.h>
#include <asm/o
plib
.h>
#include <asm/
prom
.h>
#include <asm/o
f_device
.h>
#include <asm/fbio.h>
#include "sbuslib.h"
...
...
@@ -72,60 +72,60 @@ static struct fb_ops p9100_ops = {
struct
p9100_regs
{
/* Registers for the system control */
volatile
u32
sys_base
;
volatile
u32
sys_config
;
volatile
u32
sys_intr
;
volatile
u32
sys_int_ena
;
volatile
u32
sys_alt_rd
;
volatile
u32
sys_alt_wr
;
volatile
u32
sys_xxx
[
58
];
u32
sys_base
;
u32
sys_config
;
u32
sys_intr
;
u32
sys_int_ena
;
u32
sys_alt_rd
;
u32
sys_alt_wr
;
u32
sys_xxx
[
58
];
/* Registers for the video control */
volatile
u32
vid_base
;
volatile
u32
vid_hcnt
;
volatile
u32
vid_htotal
;
volatile
u32
vid_hsync_rise
;
volatile
u32
vid_hblank_rise
;
volatile
u32
vid_hblank_fall
;
volatile
u32
vid_hcnt_preload
;
volatile
u32
vid_vcnt
;
volatile
u32
vid_vlen
;
volatile
u32
vid_vsync_rise
;
volatile
u32
vid_vblank_rise
;
volatile
u32
vid_vblank_fall
;
volatile
u32
vid_vcnt_preload
;
volatile
u32
vid_screenpaint_addr
;
volatile
u32
vid_screenpaint_timectl1
;
volatile
u32
vid_screenpaint_qsfcnt
;
volatile
u32
vid_screenpaint_timectl2
;
volatile
u32
vid_xxx
[
15
];
u32
vid_base
;
u32
vid_hcnt
;
u32
vid_htotal
;
u32
vid_hsync_rise
;
u32
vid_hblank_rise
;
u32
vid_hblank_fall
;
u32
vid_hcnt_preload
;
u32
vid_vcnt
;
u32
vid_vlen
;
u32
vid_vsync_rise
;
u32
vid_vblank_rise
;
u32
vid_vblank_fall
;
u32
vid_vcnt_preload
;
u32
vid_screenpaint_addr
;
u32
vid_screenpaint_timectl1
;
u32
vid_screenpaint_qsfcnt
;
u32
vid_screenpaint_timectl2
;
u32
vid_xxx
[
15
];
/* Registers for the video control */
volatile
u32
vram_base
;
volatile
u32
vram_memcfg
;
volatile
u32
vram_refresh_pd
;
volatile
u32
vram_refresh_cnt
;
volatile
u32
vram_raslo_max
;
volatile
u32
vram_raslo_cur
;
volatile
u32
pwrup_cfg
;
volatile
u32
vram_xxx
[
25
];
u32
vram_base
;
u32
vram_memcfg
;
u32
vram_refresh_pd
;
u32
vram_refresh_cnt
;
u32
vram_raslo_max
;
u32
vram_raslo_cur
;
u32
pwrup_cfg
;
u32
vram_xxx
[
25
];
/* Registers for IBM RGB528 Palette */
volatile
u32
ramdac_cmap_wridx
;
volatile
u32
ramdac_palette_data
;
volatile
u32
ramdac_pixel_mask
;
volatile
u32
ramdac_palette_rdaddr
;
volatile
u32
ramdac_idx_lo
;
volatile
u32
ramdac_idx_hi
;
volatile
u32
ramdac_idx_data
;
volatile
u32
ramdac_idx_ctl
;
volatile
u32
ramdac_xxx
[
1784
];
u32
ramdac_cmap_wridx
;
u32
ramdac_palette_data
;
u32
ramdac_pixel_mask
;
u32
ramdac_palette_rdaddr
;
u32
ramdac_idx_lo
;
u32
ramdac_idx_hi
;
u32
ramdac_idx_data
;
u32
ramdac_idx_ctl
;
u32
ramdac_xxx
[
1784
];
};
struct
p9100_cmd_parameng
{
volatile
u32
parameng_status
;
volatile
u32
parameng_bltcmd
;
volatile
u32
parameng_quadcmd
;
u32
parameng_status
;
u32
parameng_bltcmd
;
u32
parameng_quadcmd
;
};
struct
p9100_par
{
...
...
@@ -136,9 +136,8 @@ struct p9100_par {
#define P9100_FLAG_BLANKED 0x00000001
unsigned
long
physbase
;
unsigned
long
which_io
;
unsigned
long
fbsize
;
struct
sbus_dev
*
sdev
;
};
/**
...
...
@@ -227,8 +226,7 @@ static int p9100_mmap(struct fb_info *info, struct vm_area_struct *vma)
return
sbusfb_mmap_helper
(
p9100_mmap_map
,
par
->
physbase
,
par
->
fbsize
,
par
->
sdev
->
reg_addrs
[
0
].
which_io
,
vma
);
par
->
which_io
,
vma
);
}
static
int
p9100_ioctl
(
struct
fb_info
*
info
,
unsigned
int
cmd
,
...
...
@@ -245,12 +243,9 @@ static int p9100_ioctl(struct fb_info *info, unsigned int cmd,
* Initialisation
*/
static
void
p9100_init_fix
(
struct
fb_info
*
info
,
int
linebytes
)
static
void
p9100_init_fix
(
struct
fb_info
*
info
,
int
linebytes
,
struct
device_node
*
dp
)
{
struct
p9100_par
*
par
=
(
struct
p9100_par
*
)
info
->
par
;
strlcpy
(
info
->
fix
.
id
,
par
->
sdev
->
prom_name
,
sizeof
(
info
->
fix
.
id
));
strlcpy
(
info
->
fix
.
id
,
dp
->
name
,
sizeof
(
info
->
fix
.
id
));
info
->
fix
.
type
=
FB_TYPE_PACKED_PIXELS
;
info
->
fix
.
visual
=
FB_VISUAL_PSEUDOCOLOR
;
...
...
@@ -263,121 +258,137 @@ p9100_init_fix(struct fb_info *info, int linebytes)
struct
all_info
{
struct
fb_info
info
;
struct
p9100_par
par
;
struct
list_head
list
;
};
static
LIST_HEAD
(
p9100_list
);
static
void
p9100_init_one
(
struct
sbus_dev
*
sdev
)
static
int
__devinit
p9100_init_one
(
struct
of_device
*
op
)
{
struct
device_node
*
dp
=
op
->
node
;
struct
all_info
*
all
;
int
linebytes
;
all
=
kmalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
{
printk
(
KERN_ERR
"p9100: Cannot allocate memory.
\n
"
);
return
;
}
memset
(
all
,
0
,
sizeof
(
*
all
));
int
linebytes
,
err
;
INIT_LIST_HEAD
(
&
all
->
list
);
all
=
kzalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
return
-
ENOMEM
;
spin_lock_init
(
&
all
->
par
.
lock
);
all
->
par
.
sdev
=
sdev
;
/* This is the framebuffer and the only resource apps can mmap. */
all
->
par
.
physbase
=
sdev
->
reg_addrs
[
2
].
phys_addr
;
all
->
par
.
physbase
=
op
->
resource
[
2
].
start
;
all
->
par
.
which_io
=
op
->
resource
[
2
].
flags
&
IORESOURCE_BITS
;
sbusfb_fill_var
(
&
all
->
info
.
var
,
sdev
->
prom_
node
,
8
);
sbusfb_fill_var
(
&
all
->
info
.
var
,
dp
->
node
,
8
);
all
->
info
.
var
.
red
.
length
=
8
;
all
->
info
.
var
.
green
.
length
=
8
;
all
->
info
.
var
.
blue
.
length
=
8
;
linebytes
=
prom_getintdefault
(
sdev
->
prom_node
,
"linebytes"
,
all
->
info
.
var
.
xres
);
linebytes
=
of_getintprop_default
(
dp
,
"linebytes"
,
all
->
info
.
var
.
xres
);
all
->
par
.
fbsize
=
PAGE_ALIGN
(
linebytes
*
all
->
info
.
var
.
yres
);
all
->
par
.
regs
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
0
,
sizeof
(
struct
p9100_regs
),
"p9100 regs"
);
all
->
par
.
regs
=
of_ioremap
(
&
op
->
resource
[
0
],
0
,
sizeof
(
struct
p9100_regs
),
"p9100 regs"
);
if
(
!
all
->
par
.
regs
)
{
kfree
(
all
);
return
-
ENOMEM
;
}
all
->
info
.
flags
=
FBINFO_DEFAULT
;
all
->
info
.
fbops
=
&
p9100_ops
;
#ifdef CONFIG_SPARC32
all
->
info
.
screen_base
=
(
char
__iomem
*
)
prom_getintdefault
(
sdev
->
prom_node
,
"address"
,
0
);
#endif
if
(
!
all
->
info
.
screen_base
)
all
->
info
.
screen_base
=
sbus_ioremap
(
&
sdev
->
resource
[
2
],
0
,
all
->
par
.
fbsize
,
"p9100 ram"
);
all
->
info
.
screen_base
=
of_ioremap
(
&
op
->
resource
[
2
],
0
,
all
->
par
.
fbsize
,
"p9100 ram"
);
if
(
!
all
->
info
.
screen_base
)
{
of_iounmap
(
all
->
par
.
regs
,
sizeof
(
struct
p9100_regs
));
kfree
(
all
);
return
-
ENOMEM
;
}
all
->
info
.
par
=
&
all
->
par
;
p9100_blank
(
0
,
&
all
->
info
);
if
(
fb_alloc_cmap
(
&
all
->
info
.
cmap
,
256
,
0
))
{
printk
(
KERN_ERR
"p9100: Could not allocate color map.
\n
"
);
of_iounmap
(
all
->
par
.
regs
,
sizeof
(
struct
p9100_regs
));
of_iounmap
(
all
->
info
.
screen_base
,
all
->
par
.
fbsize
);
kfree
(
all
);
return
;
return
-
ENOMEM
;
}
p9100_init_fix
(
&
all
->
info
,
linebytes
);
p9100_init_fix
(
&
all
->
info
,
linebytes
,
dp
);
if
(
register_framebuffer
(
&
all
->
info
)
<
0
)
{
printk
(
KERN_ERR
"p9100: Could not register framebuffer.
\n
"
);
err
=
register_framebuffer
(
&
all
->
info
);
if
(
err
<
0
)
{
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
of_iounmap
(
all
->
par
.
regs
,
sizeof
(
struct
p9100_regs
));
of_iounmap
(
all
->
info
.
screen_base
,
all
->
par
.
fbsize
);
kfree
(
all
);
return
;
return
err
;
}
fb_set_cmap
(
&
all
->
info
.
cmap
,
&
all
->
info
);
list_add
(
&
all
->
list
,
&
p9100_list
);
dev_set_drvdata
(
&
op
->
dev
,
all
);
printk
(
"%s: p9100 at %lx:%lx
\n
"
,
dp
->
full_name
,
all
->
par
.
which_io
,
all
->
par
.
physbase
);
printk
(
"p9100: %s at %lx:%lx
\n
"
,
sdev
->
prom_name
,
(
long
)
sdev
->
reg_addrs
[
0
].
which_io
,
(
long
)
sdev
->
reg_addrs
[
0
].
phys_addr
);
return
0
;
}
int
__init
p9100_init
(
void
)
static
int
__devinit
p9100_probe
(
struct
of_device
*
dev
,
const
struct
of_device_id
*
match
)
{
struct
sbus_bus
*
sbus
;
struct
sbus_dev
*
sdev
;
struct
of_device
*
op
=
to_of_device
(
&
dev
->
dev
);
if
(
fb_get_options
(
"p9100fb"
,
NULL
))
return
-
ENODEV
;
return
p9100_init_one
(
op
);
}
for_all_sbusdev
(
sdev
,
sbus
)
{
if
(
!
strcmp
(
sdev
->
prom_name
,
"p9100"
))
p9100_init_one
(
sdev
);
}
static
int
__devexit
p9100_remove
(
struct
of_device
*
dev
)
{
struct
all_info
*
all
=
dev_get_drvdata
(
&
dev
->
dev
);
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
of_iounmap
(
all
->
par
.
regs
,
sizeof
(
struct
p9100_regs
));
of_iounmap
(
all
->
info
.
screen_base
,
all
->
par
.
fbsize
);
kfree
(
all
);
dev_set_drvdata
(
&
dev
->
dev
,
NULL
);
return
0
;
}
void
__exit
p9100_exit
(
void
)
{
struct
list_head
*
pos
,
*
tmp
;
static
struct
of_device_id
p9100_match
[]
=
{
{
.
name
=
"p9100"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
p9100_match
);
list_for_each_safe
(
pos
,
tmp
,
&
p9100_list
)
{
struct
all_info
*
all
=
list_entry
(
pos
,
typeof
(
*
all
),
list
);
static
struct
of_platform_driver
p9100_driver
=
{
.
name
=
"p9100"
,
.
match_table
=
p9100_match
,
.
probe
=
p9100_probe
,
.
remove
=
__devexit_p
(
p9100_remove
),
};
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
kfree
(
all
);
}
static
int
__init
p9100_init
(
void
)
{
if
(
fb_get_options
(
"p9100fb"
,
NULL
))
return
-
ENODEV
;
return
of_register_driver
(
&
p9100_driver
,
&
of_bus_type
);
}
int
__init
p9100_setup
(
char
*
arg
)
static
void
__exit
p9100_exit
(
void
)
{
/* No cmdline options yet... */
return
0
;
of_unregister_driver
(
&
p9100_driver
);
}
module_init
(
p9100_init
);
#ifdef MODULE
module_exit
(
p9100_exit
);
#endif
MODULE_DESCRIPTION
(
"framebuffer driver for P9100 chipsets"
);
MODULE_AUTHOR
(
"David S. Miller <davem@redhat.com>"
);
MODULE_AUTHOR
(
"David S. Miller <davem@davemloft.net>"
);
MODULE_VERSION
(
"2.0"
);
MODULE_LICENSE
(
"GPL"
);
drivers/video/tcx.c
View file @
50312ce9
/* tcx.c: TCX frame buffer driver
*
* Copyright (C) 2003
David S. Miller (davem@redhat.com
)
* Copyright (C) 2003
, 2006 David S. Miller (davem@davemloft.net
)
* Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
* Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
...
...
@@ -19,8 +19,8 @@
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/
sbus
.h>
#include <asm/o
plib
.h>
#include <asm/
prom
.h>
#include <asm/o
f_device
.h>
#include <asm/fbio.h>
#include "sbuslib.h"
...
...
@@ -77,32 +77,32 @@ static struct fb_ops tcx_ops = {
/* The contents are unknown */
struct
tcx_tec
{
volatile
u32
tec_matrix
;
volatile
u32
tec_clip
;
volatile
u32
tec_vdc
;
u32
tec_matrix
;
u32
tec_clip
;
u32
tec_vdc
;
};
struct
tcx_thc
{
volatile
u32
thc_rev
;
u32
thc_rev
;
u32
thc_pad0
[
511
];
volatile
u32
thc_hs
;
/* hsync timing */
volatile
u32
thc_hsdvs
;
volatile
u32
thc_hd
;
volatile
u32
thc_vs
;
/* vsync timing */
volatile
u32
thc_vd
;
volatile
u32
thc_refresh
;
volatile
u32
thc_misc
;
u32
thc_hs
;
/* hsync timing */
u32
thc_hsdvs
;
u32
thc_hd
;
u32
thc_vs
;
/* vsync timing */
u32
thc_vd
;
u32
thc_refresh
;
u32
thc_misc
;
u32
thc_pad1
[
56
];
volatile
u32
thc_cursxy
;
/* cursor x,y position (16 bits each) */
volatile
u32
thc_cursmask
[
32
];
/* cursor mask bits */
volatile
u32
thc_cursbits
[
32
];
/* what to show where mask enabled */
u32
thc_cursxy
;
/* cursor x,y position (16 bits each) */
u32
thc_cursmask
[
32
];
/* cursor mask bits */
u32
thc_cursbits
[
32
];
/* what to show where mask enabled */
};
struct
bt_regs
{
volatile
u32
addr
;
volatile
u32
color_map
;
volatile
u32
control
;
volatile
u32
cursor
;
u32
addr
;
u32
color_map
;
u32
control
;
u32
cursor
;
};
#define TCX_MMAP_ENTRIES 14
...
...
@@ -112,24 +112,23 @@ struct tcx_par {
struct
bt_regs
__iomem
*
bt
;
struct
tcx_thc
__iomem
*
thc
;
struct
tcx_tec
__iomem
*
tec
;
volatile
u32
__iomem
*
cplane
;
u32
__iomem
*
cplane
;
u32
flags
;
#define TCX_FLAG_BLANKED 0x00000001
unsigned
long
physbase
;
unsigned
long
which_io
;
unsigned
long
fbsize
;
struct
sbus_mmap_map
mmap_map
[
TCX_MMAP_ENTRIES
];
int
lowdepth
;
struct
sbus_dev
*
sdev
;
};
/* Reset control plane so that WID is 8-bit plane. */
static
void
__tcx_set_control_plane
(
struct
tcx_par
*
par
)
{
volatile
u32
__iomem
*
p
,
*
pend
;
u32
__iomem
*
p
,
*
pend
;
if
(
par
->
lowdepth
)
return
;
...
...
@@ -307,8 +306,7 @@ static int tcx_mmap(struct fb_info *info, struct vm_area_struct *vma)
return
sbusfb_mmap_helper
(
par
->
mmap_map
,
par
->
physbase
,
par
->
fbsize
,
par
->
sdev
->
reg_addrs
[
0
].
which_io
,
vma
);
par
->
which_io
,
vma
);
}
static
int
tcx_ioctl
(
struct
fb_info
*
info
,
unsigned
int
cmd
,
...
...
@@ -350,48 +348,71 @@ tcx_init_fix(struct fb_info *info, int linebytes)
struct
all_info
{
struct
fb_info
info
;
struct
tcx_par
par
;
struct
list_head
list
;
};
static
LIST_HEAD
(
tcx_list
);
static
void
tcx_
init_one
(
struct
sbus_dev
*
sdev
)
static
void
tcx_
unmap_regs
(
struct
all_info
*
all
)
{
struct
all_info
*
all
;
int
linebytes
,
i
;
if
(
all
->
par
.
tec
)
of_iounmap
(
all
->
par
.
tec
,
sizeof
(
struct
tcx_tec
));
if
(
all
->
par
.
thc
)
of_iounmap
(
all
->
par
.
thc
,
sizeof
(
struct
tcx_thc
));
if
(
all
->
par
.
bt
)
of_iounmap
(
all
->
par
.
bt
,
sizeof
(
struct
bt_regs
));
if
(
all
->
par
.
cplane
)
of_iounmap
(
all
->
par
.
cplane
,
all
->
par
.
fbsize
*
sizeof
(
u32
));
if
(
all
->
info
.
screen_base
)
of_iounmap
(
all
->
info
.
screen_base
,
all
->
par
.
fbsize
);
}
all
=
kmalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
{
printk
(
KERN_ERR
"tcx: Cannot allocate memory.
\n
"
);
return
;
}
memset
(
all
,
0
,
sizeof
(
*
all
));
static
int
__devinit
tcx_init_one
(
struct
of_device
*
op
)
{
struct
device_node
*
dp
=
op
->
node
;
struct
all_info
*
all
;
int
linebytes
,
i
,
err
;
INIT_LIST_HEAD
(
&
all
->
list
);
all
=
kzalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
return
-
ENOMEM
;
spin_lock_init
(
&
all
->
par
.
lock
);
all
->
par
.
sdev
=
sdev
;
all
->
par
.
lowdepth
=
prom_getbool
(
sdev
->
prom_node
,
"tcx-8-bit"
);
all
->
par
.
lowdepth
=
(
of_find_property
(
dp
,
"tcx-8-bit"
,
NULL
)
!=
NULL
);
sbusfb_fill_var
(
&
all
->
info
.
var
,
sdev
->
prom_
node
,
8
);
sbusfb_fill_var
(
&
all
->
info
.
var
,
dp
->
node
,
8
);
all
->
info
.
var
.
red
.
length
=
8
;
all
->
info
.
var
.
green
.
length
=
8
;
all
->
info
.
var
.
blue
.
length
=
8
;
linebytes
=
prom_getintdefault
(
sdev
->
prom_node
,
"linebytes"
,
all
->
info
.
var
.
xres
);
linebytes
=
of_getintprop_default
(
dp
,
"linebytes"
,
all
->
info
.
var
.
xres
);
all
->
par
.
fbsize
=
PAGE_ALIGN
(
linebytes
*
all
->
info
.
var
.
yres
);
all
->
par
.
tec
=
sbus_ioremap
(
&
sdev
->
resource
[
7
],
0
,
sizeof
(
struct
tcx_tec
),
"tcx tec"
);
all
->
par
.
thc
=
sbus_ioremap
(
&
sdev
->
resource
[
9
],
0
,
sizeof
(
struct
tcx_thc
),
"tcx thc"
);
all
->
par
.
bt
=
sbus_ioremap
(
&
sdev
->
resource
[
8
],
0
,
sizeof
(
struct
bt_regs
),
"tcx dac"
);
all
->
par
.
tec
=
of_ioremap
(
&
op
->
resource
[
7
],
0
,
sizeof
(
struct
tcx_tec
),
"tcx tec"
);
all
->
par
.
thc
=
of_ioremap
(
&
op
->
resource
[
9
],
0
,
sizeof
(
struct
tcx_thc
),
"tcx thc"
);
all
->
par
.
bt
=
of_ioremap
(
&
op
->
resource
[
8
],
0
,
sizeof
(
struct
bt_regs
),
"tcx dac"
);
all
->
info
.
screen_base
=
of_ioremap
(
&
op
->
resource
[
0
],
0
,
all
->
par
.
fbsize
,
"tcx ram"
);
if
(
!
all
->
par
.
tec
||
!
all
->
par
.
thc
||
!
all
->
par
.
bt
||
!
all
->
info
.
screen_base
)
{
tcx_unmap_regs
(
all
);
kfree
(
all
);
return
-
ENOMEM
;
}
memcpy
(
&
all
->
par
.
mmap_map
,
&
__tcx_mmap_map
,
sizeof
(
all
->
par
.
mmap_map
));
if
(
!
all
->
par
.
lowdepth
)
{
all
->
par
.
cplane
=
sbus_ioremap
(
&
sdev
->
resource
[
4
],
0
,
all
->
par
.
fbsize
*
sizeof
(
u32
),
"tcx cplane"
);
all
->
par
.
cplane
=
of_ioremap
(
&
op
->
resource
[
4
],
0
,
all
->
par
.
fbsize
*
sizeof
(
u32
),
"tcx cplane"
);
if
(
!
all
->
par
.
cplane
)
{
tcx_unmap_regs
(
all
);
kfree
(
all
);
return
-
ENOMEM
;
}
}
else
{
all
->
par
.
mmap_map
[
1
].
size
=
SBUS_MMAP_EMPTY
;
all
->
par
.
mmap_map
[
4
].
size
=
SBUS_MMAP_EMPTY
;
...
...
@@ -400,6 +421,8 @@ static void tcx_init_one(struct sbus_dev *sdev)
}
all
->
par
.
physbase
=
0
;
all
->
par
.
which_io
=
op
->
resource
[
0
].
flags
&
IORESOURCE_BITS
;
for
(
i
=
0
;
i
<
TCX_MMAP_ENTRIES
;
i
++
)
{
int
j
;
...
...
@@ -416,18 +439,11 @@ static void tcx_init_one(struct sbus_dev *sdev)
j
=
i
;
break
;
};
all
->
par
.
mmap_map
[
i
].
poff
=
sdev
->
reg_addrs
[
j
].
phys_addr
;
all
->
par
.
mmap_map
[
i
].
poff
=
op
->
resource
[
j
].
start
;
}
all
->
info
.
flags
=
FBINFO_DEFAULT
;
all
->
info
.
fbops
=
&
tcx_ops
;
#ifdef CONFIG_SPARC32
all
->
info
.
screen_base
=
(
char
__iomem
*
)
prom_getintdefault
(
sdev
->
prom_node
,
"address"
,
0
);
#endif
if
(
!
all
->
info
.
screen_base
)
all
->
info
.
screen_base
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
0
,
all
->
par
.
fbsize
,
"tcx ram"
);
all
->
info
.
par
=
&
all
->
par
;
/* Initialize brooktree DAC. */
...
...
@@ -445,72 +461,88 @@ static void tcx_init_one(struct sbus_dev *sdev)
tcx_blank
(
FB_BLANK_UNBLANK
,
&
all
->
info
);
if
(
fb_alloc_cmap
(
&
all
->
info
.
cmap
,
256
,
0
))
{
printk
(
KERN_ERR
"tcx: Could not allocate color map.
\n
"
);
tcx_unmap_regs
(
all
);
kfree
(
all
);
return
;
return
-
ENOMEM
;
}
fb_set_cmap
(
&
all
->
info
.
cmap
,
&
all
->
info
);
tcx_init_fix
(
&
all
->
info
,
linebytes
);
if
(
register_framebuffer
(
&
all
->
info
)
<
0
)
{
printk
(
KERN_ERR
"tcx: Could not register framebuffer.
\n
"
);
err
=
register_framebuffer
(
&
all
->
info
);
if
(
err
<
0
)
{
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
tcx_unmap_regs
(
all
);
kfree
(
all
);
return
;
return
err
;
}
list_add
(
&
all
->
list
,
&
tcx_list
);
dev_set_drvdata
(
&
op
->
dev
,
all
);
printk
(
"
tcx: %s
at %lx:%lx, %s
\n
"
,
sdev
->
prom
_name
,
(
long
)
sdev
->
reg_addrs
[
0
]
.
which_io
,
(
long
)
sdev
->
reg_addrs
[
0
].
phys_addr
,
printk
(
"
%s: TCX
at %lx:%lx, %s
\n
"
,
dp
->
full
_name
,
all
->
par
.
which_io
,
op
->
resource
[
0
].
start
,
all
->
par
.
lowdepth
?
"8-bit only"
:
"24-bit depth"
);
return
0
;
}
int
__init
tcx_init
(
void
)
static
int
__devinit
tcx_probe
(
struct
of_device
*
dev
,
const
struct
of_device_id
*
match
)
{
struct
sbus_bus
*
sbus
;
struct
sbus_dev
*
sdev
;
struct
of_device
*
op
=
to_of_device
(
&
dev
->
dev
);
if
(
fb_get_options
(
"tcxfb"
,
NULL
))
return
-
ENODEV
;
return
tcx_init_one
(
op
);
}
for_all_sbusdev
(
sdev
,
sbus
)
{
if
(
!
strcmp
(
sdev
->
prom_name
,
"SUNW,tcx"
))
tcx_init_one
(
sdev
);
}
static
int
__devexit
tcx_remove
(
struct
of_device
*
dev
)
{
struct
all_info
*
all
=
dev_get_drvdata
(
&
dev
->
dev
);
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
tcx_unmap_regs
(
all
);
kfree
(
all
);
dev_set_drvdata
(
&
dev
->
dev
,
NULL
);
return
0
;
}
void
__exit
tcx_exit
(
void
)
{
struct
list_head
*
pos
,
*
tmp
;
static
struct
of_device_id
tcx_match
[]
=
{
{
.
name
=
"SUNW,tcx"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
tcx_match
);
list_for_each_safe
(
pos
,
tmp
,
&
tcx_list
)
{
struct
all_info
*
all
=
list_entry
(
pos
,
typeof
(
*
all
),
list
);
static
struct
of_platform_driver
tcx_driver
=
{
.
name
=
"tcx"
,
.
match_table
=
tcx_match
,
.
probe
=
tcx_probe
,
.
remove
=
__devexit_p
(
tcx_remove
),
};
unregister_framebuffer
(
&
all
->
info
);
fb_dealloc_cmap
(
&
all
->
info
.
cmap
);
kfree
(
all
);
}
int
__init
tcx_init
(
void
)
{
if
(
fb_get_options
(
"tcxfb"
,
NULL
))
return
-
ENODEV
;
return
of_register_driver
(
&
tcx_driver
,
&
of_bus_type
);
}
int
__init
tcx_setup
(
char
*
arg
)
void
__exit
tcx_exit
(
void
)
{
/* No cmdline options yet... */
return
0
;
of_unregister_driver
(
&
tcx_driver
);
}
module_init
(
tcx_init
);
#ifdef MODULE
module_exit
(
tcx_exit
);
#endif
MODULE_DESCRIPTION
(
"framebuffer driver for TCX chipsets"
);
MODULE_AUTHOR
(
"David S. Miller <davem@redhat.com>"
);
MODULE_AUTHOR
(
"David S. Miller <davem@davemloft.net>"
);
MODULE_VERSION
(
"2.0"
);
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