Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
50312ce9
K
Kernel
项目概览
openeuler
/
Kernel
大约 1 年 前同步成功
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
50312ce9
编写于
6月 29, 2006
作者:
D
David S. Miller
提交者:
David S. Miller
6月 29, 2006
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[SPARC]: Convert all FB SBUS drivers to of_driver framework.
Signed-off-by:
N
David S. Miller
<
davem@davemloft.net
>
上级
3ca9fab4
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
1179 addition
and
1149 deletion
+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
未找到文件。
drivers/video/bw2.c
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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"
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录