Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
b39a982d
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
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看板
提交
b39a982d
编写于
8月 04, 2009
作者:
T
Tomi Valkeinen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
OMAP: DSS2: omapfb driver
Signed-off-by:
N
Tomi Valkeinen
<
tomi.valkeinen@nokia.com
>
上级
3de7a1dc
变更
11
展开全部
隐藏空白更改
内联
并排
Showing
11 changed file
with
3813 addition
and
3 deletion
+3813
-3
arch/arm/plat-omap/fb.c
arch/arm/plat-omap/fb.c
+46
-1
drivers/video/omap/Kconfig
drivers/video/omap/Kconfig
+3
-2
drivers/video/omap2/Kconfig
drivers/video/omap2/Kconfig
+1
-0
drivers/video/omap2/Makefile
drivers/video/omap2/Makefile
+1
-0
drivers/video/omap2/omapfb/Kconfig
drivers/video/omap2/omapfb/Kconfig
+37
-0
drivers/video/omap2/omapfb/Makefile
drivers/video/omap2/omapfb/Makefile
+2
-0
drivers/video/omap2/omapfb/omapfb-ioctl.c
drivers/video/omap2/omapfb/omapfb-ioctl.c
+755
-0
drivers/video/omap2/omapfb/omapfb-main.c
drivers/video/omap2/omapfb/omapfb-main.c
+2261
-0
drivers/video/omap2/omapfb/omapfb-sysfs.c
drivers/video/omap2/omapfb/omapfb-sysfs.c
+507
-0
drivers/video/omap2/omapfb/omapfb.h
drivers/video/omap2/omapfb/omapfb.h
+146
-0
include/linux/omapfb.h
include/linux/omapfb.h
+54
-0
未找到文件。
arch/arm/plat-omap/fb.c
浏览文件 @
b39a982d
...
@@ -55,6 +55,10 @@ static struct platform_device omap_fb_device = {
...
@@ -55,6 +55,10 @@ static struct platform_device omap_fb_device = {
.
num_resources
=
0
,
.
num_resources
=
0
,
};
};
void
omapfb_set_platform_data
(
struct
omapfb_platform_data
*
data
)
{
}
static
inline
int
ranges_overlap
(
unsigned
long
start1
,
unsigned
long
size1
,
static
inline
int
ranges_overlap
(
unsigned
long
start1
,
unsigned
long
size1
,
unsigned
long
start2
,
unsigned
long
size2
)
unsigned
long
start2
,
unsigned
long
size2
)
{
{
...
@@ -327,7 +331,33 @@ static inline int omap_init_fb(void)
...
@@ -327,7 +331,33 @@ static inline int omap_init_fb(void)
arch_initcall
(
omap_init_fb
);
arch_initcall
(
omap_init_fb
);
#else
#elif defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
static
u64
omap_fb_dma_mask
=
~
(
u32
)
0
;
static
struct
omapfb_platform_data
omapfb_config
;
static
struct
platform_device
omap_fb_device
=
{
.
name
=
"omapfb"
,
.
id
=
-
1
,
.
dev
=
{
.
dma_mask
=
&
omap_fb_dma_mask
,
.
coherent_dma_mask
=
~
(
u32
)
0
,
.
platform_data
=
&
omapfb_config
,
},
.
num_resources
=
0
,
};
void
omapfb_set_platform_data
(
struct
omapfb_platform_data
*
data
)
{
omapfb_config
=
*
data
;
}
static
inline
int
omap_init_fb
(
void
)
{
return
platform_device_register
(
&
omap_fb_device
);
}
arch_initcall
(
omap_init_fb
);
void
omapfb_reserve_sdram
(
void
)
{}
void
omapfb_reserve_sdram
(
void
)
{}
unsigned
long
omapfb_reserve_sram
(
unsigned
long
sram_pstart
,
unsigned
long
omapfb_reserve_sram
(
unsigned
long
sram_pstart
,
...
@@ -339,5 +369,20 @@ unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
...
@@ -339,5 +369,20 @@ unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
return
0
;
return
0
;
}
}
#else
void
omapfb_set_platform_data
(
struct
omapfb_platform_data
*
data
)
{
}
void
omapfb_reserve_sdram
(
void
)
{}
unsigned
long
omapfb_reserve_sram
(
unsigned
long
sram_pstart
,
unsigned
long
sram_vstart
,
unsigned
long
sram_size
,
unsigned
long
start_avail
,
unsigned
long
size_avail
)
{
return
0
;
}
#endif
#endif
drivers/video/omap/Kconfig
浏览文件 @
b39a982d
config FB_OMAP
config FB_OMAP
tristate "OMAP frame buffer support (EXPERIMENTAL)"
tristate "OMAP frame buffer support (EXPERIMENTAL)"
depends on FB && ARCH_OMAP
depends on FB && ARCH_OMAP && (OMAP2_DSS = "n")
select FB_CFB_FILLRECT
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_CFB_IMAGEBLIT
...
@@ -72,7 +73,7 @@ config FB_OMAP_LCD_MIPID
...
@@ -72,7 +73,7 @@ config FB_OMAP_LCD_MIPID
config FB_OMAP_BOOTLOADER_INIT
config FB_OMAP_BOOTLOADER_INIT
bool "Check bootloader initialization"
bool "Check bootloader initialization"
depends on FB_OMAP
depends on FB_OMAP
|| FB_OMAP2
help
help
Say Y here if you want to enable checking if the bootloader has
Say Y here if you want to enable checking if the bootloader has
already initialized the display controller. In this case the
already initialized the display controller. In this case the
...
...
drivers/video/omap2/Kconfig
浏览文件 @
b39a982d
...
@@ -5,3 +5,4 @@ config OMAP2_VRFB
...
@@ -5,3 +5,4 @@ config OMAP2_VRFB
bool
bool
source "drivers/video/omap2/dss/Kconfig"
source "drivers/video/omap2/dss/Kconfig"
source "drivers/video/omap2/omapfb/Kconfig"
drivers/video/omap2/Makefile
浏览文件 @
b39a982d
...
@@ -2,3 +2,4 @@ obj-$(CONFIG_OMAP2_VRAM) += vram.o
...
@@ -2,3 +2,4 @@ obj-$(CONFIG_OMAP2_VRAM) += vram.o
obj-$(CONFIG_OMAP2_VRFB)
+=
vrfb.o
obj-$(CONFIG_OMAP2_VRFB)
+=
vrfb.o
obj-y
+=
dss/
obj-y
+=
dss/
obj-y
+=
omapfb/
drivers/video/omap2/omapfb/Kconfig
0 → 100644
浏览文件 @
b39a982d
menuconfig FB_OMAP2
tristate "OMAP2/3 frame buffer support (EXPERIMENTAL)"
depends on FB && OMAP2_DSS
select OMAP2_VRAM
select OMAP2_VRFB
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
help
Frame buffer driver for OMAP2/3 based boards.
config FB_OMAP2_DEBUG_SUPPORT
bool "Debug support for OMAP2/3 FB"
default y
depends on FB_OMAP2
help
Support for debug output. You have to enable the actual printing
with debug module parameter.
config FB_OMAP2_FORCE_AUTO_UPDATE
bool "Force main display to automatic update mode"
depends on FB_OMAP2
help
Forces main display to automatic update mode (if possible),
and also enables tearsync (if possible). By default
displays that support manual update are started in manual
update mode.
config FB_OMAP2_NUM_FBS
int "Number of framebuffers"
range 1 10
default 3
depends on FB_OMAP2
help
Select the number of framebuffers created. OMAP2/3 has 3 overlays
so normally this would be 3.
drivers/video/omap2/omapfb/Makefile
0 → 100644
浏览文件 @
b39a982d
obj-$(CONFIG_FB_OMAP2)
+=
omapfb.o
omapfb-y
:=
omapfb-main.o omapfb-sysfs.o omapfb-ioctl.o
drivers/video/omap2/omapfb/omapfb-ioctl.c
0 → 100644
浏览文件 @
b39a982d
/*
* linux/drivers/video/omap2/omapfb-ioctl.c
*
* Copyright (C) 2008 Nokia Corporation
* Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
*
* Some code and ideas taken from drivers/video/omap/ driver
* by Imre Deak.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/fb.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/platform_device.h>
#include <linux/mm.h>
#include <linux/omapfb.h>
#include <linux/vmalloc.h>
#include <plat/display.h>
#include <plat/vrfb.h>
#include <plat/vram.h>
#include "omapfb.h"
static
int
omapfb_setup_plane
(
struct
fb_info
*
fbi
,
struct
omapfb_plane_info
*
pi
)
{
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
struct
omapfb2_device
*
fbdev
=
ofbi
->
fbdev
;
struct
omap_overlay
*
ovl
;
struct
omap_overlay_info
info
;
int
r
=
0
;
DBG
(
"omapfb_setup_plane
\n
"
);
if
(
ofbi
->
num_overlays
!=
1
)
{
r
=
-
EINVAL
;
goto
out
;
}
/* XXX uses only the first overlay */
ovl
=
ofbi
->
overlays
[
0
];
if
(
pi
->
enabled
&&
!
ofbi
->
region
.
size
)
{
/*
* This plane's memory was freed, can't enable it
* until it's reallocated.
*/
r
=
-
EINVAL
;
goto
out
;
}
ovl
->
get_overlay_info
(
ovl
,
&
info
);
info
.
pos_x
=
pi
->
pos_x
;
info
.
pos_y
=
pi
->
pos_y
;
info
.
out_width
=
pi
->
out_width
;
info
.
out_height
=
pi
->
out_height
;
info
.
enabled
=
pi
->
enabled
;
r
=
ovl
->
set_overlay_info
(
ovl
,
&
info
);
if
(
r
)
goto
out
;
if
(
ovl
->
manager
)
{
r
=
ovl
->
manager
->
apply
(
ovl
->
manager
);
if
(
r
)
goto
out
;
}
out:
if
(
r
)
dev_err
(
fbdev
->
dev
,
"setup_plane failed
\n
"
);
return
r
;
}
static
int
omapfb_query_plane
(
struct
fb_info
*
fbi
,
struct
omapfb_plane_info
*
pi
)
{
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
if
(
ofbi
->
num_overlays
!=
1
)
{
memset
(
pi
,
0
,
sizeof
(
*
pi
));
}
else
{
struct
omap_overlay_info
*
ovli
;
struct
omap_overlay
*
ovl
;
ovl
=
ofbi
->
overlays
[
0
];
ovli
=
&
ovl
->
info
;
pi
->
pos_x
=
ovli
->
pos_x
;
pi
->
pos_y
=
ovli
->
pos_y
;
pi
->
enabled
=
ovli
->
enabled
;
pi
->
channel_out
=
0
;
/* xxx */
pi
->
mirror
=
0
;
pi
->
out_width
=
ovli
->
out_width
;
pi
->
out_height
=
ovli
->
out_height
;
}
return
0
;
}
static
int
omapfb_setup_mem
(
struct
fb_info
*
fbi
,
struct
omapfb_mem_info
*
mi
)
{
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
struct
omapfb2_device
*
fbdev
=
ofbi
->
fbdev
;
struct
omapfb2_mem_region
*
rg
;
int
r
,
i
;
size_t
size
;
if
(
mi
->
type
>
OMAPFB_MEMTYPE_MAX
)
return
-
EINVAL
;
size
=
PAGE_ALIGN
(
mi
->
size
);
rg
=
&
ofbi
->
region
;
for
(
i
=
0
;
i
<
ofbi
->
num_overlays
;
i
++
)
{
if
(
ofbi
->
overlays
[
i
]
->
info
.
enabled
)
return
-
EBUSY
;
}
if
(
rg
->
size
!=
size
||
rg
->
type
!=
mi
->
type
)
{
r
=
omapfb_realloc_fbmem
(
fbi
,
size
,
mi
->
type
);
if
(
r
)
{
dev_err
(
fbdev
->
dev
,
"realloc fbmem failed
\n
"
);
return
r
;
}
}
return
0
;
}
static
int
omapfb_query_mem
(
struct
fb_info
*
fbi
,
struct
omapfb_mem_info
*
mi
)
{
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
struct
omapfb2_mem_region
*
rg
;
rg
=
&
ofbi
->
region
;
memset
(
mi
,
0
,
sizeof
(
*
mi
));
mi
->
size
=
rg
->
size
;
mi
->
type
=
rg
->
type
;
return
0
;
}
static
int
omapfb_update_window_nolock
(
struct
fb_info
*
fbi
,
u32
x
,
u32
y
,
u32
w
,
u32
h
)
{
struct
omap_dss_device
*
display
=
fb2display
(
fbi
);
u16
dw
,
dh
;
if
(
!
display
)
return
0
;
if
(
w
==
0
||
h
==
0
)
return
0
;
display
->
get_resolution
(
display
,
&
dw
,
&
dh
);
if
(
x
+
w
>
dw
||
y
+
h
>
dh
)
return
-
EINVAL
;
return
display
->
update
(
display
,
x
,
y
,
w
,
h
);
}
/* This function is exported for SGX driver use */
int
omapfb_update_window
(
struct
fb_info
*
fbi
,
u32
x
,
u32
y
,
u32
w
,
u32
h
)
{
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
struct
omapfb2_device
*
fbdev
=
ofbi
->
fbdev
;
int
r
;
omapfb_lock
(
fbdev
);
lock_fb_info
(
fbi
);
r
=
omapfb_update_window_nolock
(
fbi
,
x
,
y
,
w
,
h
);
unlock_fb_info
(
fbi
);
omapfb_unlock
(
fbdev
);
return
r
;
}
EXPORT_SYMBOL
(
omapfb_update_window
);
static
int
omapfb_set_update_mode
(
struct
fb_info
*
fbi
,
enum
omapfb_update_mode
mode
)
{
struct
omap_dss_device
*
display
=
fb2display
(
fbi
);
enum
omap_dss_update_mode
um
;
int
r
;
if
(
!
display
||
!
display
->
set_update_mode
)
return
-
EINVAL
;
switch
(
mode
)
{
case
OMAPFB_UPDATE_DISABLED
:
um
=
OMAP_DSS_UPDATE_DISABLED
;
break
;
case
OMAPFB_AUTO_UPDATE
:
um
=
OMAP_DSS_UPDATE_AUTO
;
break
;
case
OMAPFB_MANUAL_UPDATE
:
um
=
OMAP_DSS_UPDATE_MANUAL
;
break
;
default:
return
-
EINVAL
;
}
r
=
display
->
set_update_mode
(
display
,
um
);
return
r
;
}
static
int
omapfb_get_update_mode
(
struct
fb_info
*
fbi
,
enum
omapfb_update_mode
*
mode
)
{
struct
omap_dss_device
*
display
=
fb2display
(
fbi
);
enum
omap_dss_update_mode
m
;
if
(
!
display
||
!
display
->
get_update_mode
)
return
-
EINVAL
;
m
=
display
->
get_update_mode
(
display
);
switch
(
m
)
{
case
OMAP_DSS_UPDATE_DISABLED
:
*
mode
=
OMAPFB_UPDATE_DISABLED
;
break
;
case
OMAP_DSS_UPDATE_AUTO
:
*
mode
=
OMAPFB_AUTO_UPDATE
;
break
;
case
OMAP_DSS_UPDATE_MANUAL
:
*
mode
=
OMAPFB_MANUAL_UPDATE
;
break
;
default:
BUG
();
}
return
0
;
}
/* XXX this color key handling is a hack... */
static
struct
omapfb_color_key
omapfb_color_keys
[
2
];
static
int
_omapfb_set_color_key
(
struct
omap_overlay_manager
*
mgr
,
struct
omapfb_color_key
*
ck
)
{
struct
omap_overlay_manager_info
info
;
enum
omap_dss_trans_key_type
kt
;
int
r
;
mgr
->
get_manager_info
(
mgr
,
&
info
);
if
(
ck
->
key_type
==
OMAPFB_COLOR_KEY_DISABLED
)
{
info
.
trans_enabled
=
false
;
omapfb_color_keys
[
mgr
->
id
]
=
*
ck
;
r
=
mgr
->
set_manager_info
(
mgr
,
&
info
);
if
(
r
)
return
r
;
r
=
mgr
->
apply
(
mgr
);
return
r
;
}
switch
(
ck
->
key_type
)
{
case
OMAPFB_COLOR_KEY_GFX_DST
:
kt
=
OMAP_DSS_COLOR_KEY_GFX_DST
;
break
;
case
OMAPFB_COLOR_KEY_VID_SRC
:
kt
=
OMAP_DSS_COLOR_KEY_VID_SRC
;
break
;
default:
return
-
EINVAL
;
}
info
.
default_color
=
ck
->
background
;
info
.
trans_key
=
ck
->
trans_key
;
info
.
trans_key_type
=
kt
;
info
.
trans_enabled
=
true
;
omapfb_color_keys
[
mgr
->
id
]
=
*
ck
;
r
=
mgr
->
set_manager_info
(
mgr
,
&
info
);
if
(
r
)
return
r
;
r
=
mgr
->
apply
(
mgr
);
return
r
;
}
static
int
omapfb_set_color_key
(
struct
fb_info
*
fbi
,
struct
omapfb_color_key
*
ck
)
{
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
struct
omapfb2_device
*
fbdev
=
ofbi
->
fbdev
;
int
r
;
int
i
;
struct
omap_overlay_manager
*
mgr
=
NULL
;
omapfb_lock
(
fbdev
);
for
(
i
=
0
;
i
<
ofbi
->
num_overlays
;
i
++
)
{
if
(
ofbi
->
overlays
[
i
]
->
manager
)
{
mgr
=
ofbi
->
overlays
[
i
]
->
manager
;
break
;
}
}
if
(
!
mgr
)
{
r
=
-
EINVAL
;
goto
err
;
}
r
=
_omapfb_set_color_key
(
mgr
,
ck
);
err:
omapfb_unlock
(
fbdev
);
return
r
;
}
static
int
omapfb_get_color_key
(
struct
fb_info
*
fbi
,
struct
omapfb_color_key
*
ck
)
{
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
struct
omapfb2_device
*
fbdev
=
ofbi
->
fbdev
;
struct
omap_overlay_manager
*
mgr
=
NULL
;
int
r
=
0
;
int
i
;
omapfb_lock
(
fbdev
);
for
(
i
=
0
;
i
<
ofbi
->
num_overlays
;
i
++
)
{
if
(
ofbi
->
overlays
[
i
]
->
manager
)
{
mgr
=
ofbi
->
overlays
[
i
]
->
manager
;
break
;
}
}
if
(
!
mgr
)
{
r
=
-
EINVAL
;
goto
err
;
}
*
ck
=
omapfb_color_keys
[
mgr
->
id
];
err:
omapfb_unlock
(
fbdev
);
return
r
;
}
static
int
omapfb_memory_read
(
struct
fb_info
*
fbi
,
struct
omapfb_memory_read
*
mr
)
{
struct
omap_dss_device
*
display
=
fb2display
(
fbi
);
void
*
buf
;
int
r
;
if
(
!
display
||
!
display
->
memory_read
)
return
-
ENOENT
;
if
(
!
access_ok
(
VERIFY_WRITE
,
mr
->
buffer
,
mr
->
buffer_size
))
return
-
EFAULT
;
if
(
mr
->
w
*
mr
->
h
*
3
>
mr
->
buffer_size
)
return
-
EINVAL
;
buf
=
vmalloc
(
mr
->
buffer_size
);
if
(
!
buf
)
{
DBG
(
"vmalloc failed
\n
"
);
return
-
ENOMEM
;
}
r
=
display
->
memory_read
(
display
,
buf
,
mr
->
buffer_size
,
mr
->
x
,
mr
->
y
,
mr
->
w
,
mr
->
h
);
if
(
r
>
0
)
{
if
(
copy_to_user
(
mr
->
buffer
,
buf
,
mr
->
buffer_size
))
r
=
-
EFAULT
;
}
vfree
(
buf
);
return
r
;
}
static
int
omapfb_get_ovl_colormode
(
struct
omapfb2_device
*
fbdev
,
struct
omapfb_ovl_colormode
*
mode
)
{
int
ovl_idx
=
mode
->
overlay_idx
;
int
mode_idx
=
mode
->
mode_idx
;
struct
omap_overlay
*
ovl
;
enum
omap_color_mode
supported_modes
;
struct
fb_var_screeninfo
var
;
int
i
;
if
(
ovl_idx
>=
fbdev
->
num_overlays
)
return
-
ENODEV
;
ovl
=
fbdev
->
overlays
[
ovl_idx
];
supported_modes
=
ovl
->
supported_modes
;
mode_idx
=
mode
->
mode_idx
;
for
(
i
=
0
;
i
<
sizeof
(
supported_modes
)
*
8
;
i
++
)
{
if
(
!
(
supported_modes
&
(
1
<<
i
)))
continue
;
/*
* It's possible that the FB doesn't support a mode
* that is supported by the overlay, so call the
* following here.
*/
if
(
dss_mode_to_fb_mode
(
1
<<
i
,
&
var
)
<
0
)
continue
;
mode_idx
--
;
if
(
mode_idx
<
0
)
break
;
}
if
(
i
==
sizeof
(
supported_modes
)
*
8
)
return
-
ENOENT
;
mode
->
bits_per_pixel
=
var
.
bits_per_pixel
;
mode
->
nonstd
=
var
.
nonstd
;
mode
->
red
=
var
.
red
;
mode
->
green
=
var
.
green
;
mode
->
blue
=
var
.
blue
;
mode
->
transp
=
var
.
transp
;
return
0
;
}
static
int
omapfb_wait_for_go
(
struct
fb_info
*
fbi
)
{
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
int
r
=
0
;
int
i
;
for
(
i
=
0
;
i
<
ofbi
->
num_overlays
;
++
i
)
{
struct
omap_overlay
*
ovl
=
ofbi
->
overlays
[
i
];
r
=
ovl
->
wait_for_go
(
ovl
);
if
(
r
)
break
;
}
return
r
;
}
int
omapfb_ioctl
(
struct
fb_info
*
fbi
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
struct
omapfb2_device
*
fbdev
=
ofbi
->
fbdev
;
struct
omap_dss_device
*
display
=
fb2display
(
fbi
);
union
{
struct
omapfb_update_window_old
uwnd_o
;
struct
omapfb_update_window
uwnd
;
struct
omapfb_plane_info
plane_info
;
struct
omapfb_caps
caps
;
struct
omapfb_mem_info
mem_info
;
struct
omapfb_color_key
color_key
;
struct
omapfb_ovl_colormode
ovl_colormode
;
enum
omapfb_update_mode
update_mode
;
int
test_num
;
struct
omapfb_memory_read
memory_read
;
struct
omapfb_vram_info
vram_info
;
struct
omapfb_tearsync_info
tearsync_info
;
}
p
;
int
r
=
0
;
switch
(
cmd
)
{
case
OMAPFB_SYNC_GFX
:
DBG
(
"ioctl SYNC_GFX
\n
"
);
if
(
!
display
||
!
display
->
sync
)
{
/* DSS1 never returns an error here, so we neither */
/*r = -EINVAL;*/
break
;
}
r
=
display
->
sync
(
display
);
break
;
case
OMAPFB_UPDATE_WINDOW_OLD
:
DBG
(
"ioctl UPDATE_WINDOW_OLD
\n
"
);
if
(
!
display
||
!
display
->
update
)
{
r
=
-
EINVAL
;
break
;
}
if
(
copy_from_user
(
&
p
.
uwnd_o
,
(
void
__user
*
)
arg
,
sizeof
(
p
.
uwnd_o
)))
{
r
=
-
EFAULT
;
break
;
}
r
=
omapfb_update_window_nolock
(
fbi
,
p
.
uwnd_o
.
x
,
p
.
uwnd_o
.
y
,
p
.
uwnd_o
.
width
,
p
.
uwnd_o
.
height
);
break
;
case
OMAPFB_UPDATE_WINDOW
:
DBG
(
"ioctl UPDATE_WINDOW
\n
"
);
if
(
!
display
||
!
display
->
update
)
{
r
=
-
EINVAL
;
break
;
}
if
(
copy_from_user
(
&
p
.
uwnd
,
(
void
__user
*
)
arg
,
sizeof
(
p
.
uwnd
)))
{
r
=
-
EFAULT
;
break
;
}
r
=
omapfb_update_window_nolock
(
fbi
,
p
.
uwnd
.
x
,
p
.
uwnd
.
y
,
p
.
uwnd
.
width
,
p
.
uwnd
.
height
);
break
;
case
OMAPFB_SETUP_PLANE
:
DBG
(
"ioctl SETUP_PLANE
\n
"
);
if
(
copy_from_user
(
&
p
.
plane_info
,
(
void
__user
*
)
arg
,
sizeof
(
p
.
plane_info
)))
r
=
-
EFAULT
;
else
r
=
omapfb_setup_plane
(
fbi
,
&
p
.
plane_info
);
break
;
case
OMAPFB_QUERY_PLANE
:
DBG
(
"ioctl QUERY_PLANE
\n
"
);
r
=
omapfb_query_plane
(
fbi
,
&
p
.
plane_info
);
if
(
r
<
0
)
break
;
if
(
copy_to_user
((
void
__user
*
)
arg
,
&
p
.
plane_info
,
sizeof
(
p
.
plane_info
)))
r
=
-
EFAULT
;
break
;
case
OMAPFB_SETUP_MEM
:
DBG
(
"ioctl SETUP_MEM
\n
"
);
if
(
copy_from_user
(
&
p
.
mem_info
,
(
void
__user
*
)
arg
,
sizeof
(
p
.
mem_info
)))
r
=
-
EFAULT
;
else
r
=
omapfb_setup_mem
(
fbi
,
&
p
.
mem_info
);
break
;
case
OMAPFB_QUERY_MEM
:
DBG
(
"ioctl QUERY_MEM
\n
"
);
r
=
omapfb_query_mem
(
fbi
,
&
p
.
mem_info
);
if
(
r
<
0
)
break
;
if
(
copy_to_user
((
void
__user
*
)
arg
,
&
p
.
mem_info
,
sizeof
(
p
.
mem_info
)))
r
=
-
EFAULT
;
break
;
case
OMAPFB_GET_CAPS
:
DBG
(
"ioctl GET_CAPS
\n
"
);
if
(
!
display
)
{
r
=
-
EINVAL
;
break
;
}
memset
(
&
p
.
caps
,
0
,
sizeof
(
p
.
caps
));
if
(
display
->
caps
&
OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE
)
p
.
caps
.
ctrl
|=
OMAPFB_CAPS_MANUAL_UPDATE
;
if
(
display
->
caps
&
OMAP_DSS_DISPLAY_CAP_TEAR_ELIM
)
p
.
caps
.
ctrl
|=
OMAPFB_CAPS_TEARSYNC
;
if
(
copy_to_user
((
void
__user
*
)
arg
,
&
p
.
caps
,
sizeof
(
p
.
caps
)))
r
=
-
EFAULT
;
break
;
case
OMAPFB_GET_OVERLAY_COLORMODE
:
DBG
(
"ioctl GET_OVERLAY_COLORMODE
\n
"
);
if
(
copy_from_user
(
&
p
.
ovl_colormode
,
(
void
__user
*
)
arg
,
sizeof
(
p
.
ovl_colormode
)))
{
r
=
-
EFAULT
;
break
;
}
r
=
omapfb_get_ovl_colormode
(
fbdev
,
&
p
.
ovl_colormode
);
if
(
r
<
0
)
break
;
if
(
copy_to_user
((
void
__user
*
)
arg
,
&
p
.
ovl_colormode
,
sizeof
(
p
.
ovl_colormode
)))
r
=
-
EFAULT
;
break
;
case
OMAPFB_SET_UPDATE_MODE
:
DBG
(
"ioctl SET_UPDATE_MODE
\n
"
);
if
(
get_user
(
p
.
update_mode
,
(
int
__user
*
)
arg
))
r
=
-
EFAULT
;
else
r
=
omapfb_set_update_mode
(
fbi
,
p
.
update_mode
);
break
;
case
OMAPFB_GET_UPDATE_MODE
:
DBG
(
"ioctl GET_UPDATE_MODE
\n
"
);
r
=
omapfb_get_update_mode
(
fbi
,
&
p
.
update_mode
);
if
(
r
)
break
;
if
(
put_user
(
p
.
update_mode
,
(
enum
omapfb_update_mode
__user
*
)
arg
))
r
=
-
EFAULT
;
break
;
case
OMAPFB_SET_COLOR_KEY
:
DBG
(
"ioctl SET_COLOR_KEY
\n
"
);
if
(
copy_from_user
(
&
p
.
color_key
,
(
void
__user
*
)
arg
,
sizeof
(
p
.
color_key
)))
r
=
-
EFAULT
;
else
r
=
omapfb_set_color_key
(
fbi
,
&
p
.
color_key
);
break
;
case
OMAPFB_GET_COLOR_KEY
:
DBG
(
"ioctl GET_COLOR_KEY
\n
"
);
r
=
omapfb_get_color_key
(
fbi
,
&
p
.
color_key
);
if
(
r
)
break
;
if
(
copy_to_user
((
void
__user
*
)
arg
,
&
p
.
color_key
,
sizeof
(
p
.
color_key
)))
r
=
-
EFAULT
;
break
;
case
OMAPFB_WAITFORVSYNC
:
DBG
(
"ioctl WAITFORVSYNC
\n
"
);
if
(
!
display
)
{
r
=
-
EINVAL
;
break
;
}
r
=
display
->
wait_vsync
(
display
);
break
;
case
OMAPFB_WAITFORGO
:
DBG
(
"ioctl WAITFORGO
\n
"
);
if
(
!
display
)
{
r
=
-
EINVAL
;
break
;
}
r
=
omapfb_wait_for_go
(
fbi
);
break
;
/* LCD and CTRL tests do the same thing for backward
* compatibility */
case
OMAPFB_LCD_TEST
:
DBG
(
"ioctl LCD_TEST
\n
"
);
if
(
get_user
(
p
.
test_num
,
(
int
__user
*
)
arg
))
{
r
=
-
EFAULT
;
break
;
}
if
(
!
display
||
!
display
->
run_test
)
{
r
=
-
EINVAL
;
break
;
}
r
=
display
->
run_test
(
display
,
p
.
test_num
);
break
;
case
OMAPFB_CTRL_TEST
:
DBG
(
"ioctl CTRL_TEST
\n
"
);
if
(
get_user
(
p
.
test_num
,
(
int
__user
*
)
arg
))
{
r
=
-
EFAULT
;
break
;
}
if
(
!
display
||
!
display
->
run_test
)
{
r
=
-
EINVAL
;
break
;
}
r
=
display
->
run_test
(
display
,
p
.
test_num
);
break
;
case
OMAPFB_MEMORY_READ
:
DBG
(
"ioctl MEMORY_READ
\n
"
);
if
(
copy_from_user
(
&
p
.
memory_read
,
(
void
__user
*
)
arg
,
sizeof
(
p
.
memory_read
)))
{
r
=
-
EFAULT
;
break
;
}
r
=
omapfb_memory_read
(
fbi
,
&
p
.
memory_read
);
break
;
case
OMAPFB_GET_VRAM_INFO
:
{
unsigned
long
vram
,
free
,
largest
;
DBG
(
"ioctl GET_VRAM_INFO
\n
"
);
omap_vram_get_info
(
&
vram
,
&
free
,
&
largest
);
p
.
vram_info
.
total
=
vram
;
p
.
vram_info
.
free
=
free
;
p
.
vram_info
.
largest_free_block
=
largest
;
if
(
copy_to_user
((
void
__user
*
)
arg
,
&
p
.
vram_info
,
sizeof
(
p
.
vram_info
)))
r
=
-
EFAULT
;
break
;
}
case
OMAPFB_SET_TEARSYNC
:
{
DBG
(
"ioctl SET_TEARSYNC
\n
"
);
if
(
copy_from_user
(
&
p
.
tearsync_info
,
(
void
__user
*
)
arg
,
sizeof
(
p
.
tearsync_info
)))
{
r
=
-
EFAULT
;
break
;
}
if
(
!
display
->
enable_te
)
{
r
=
-
ENODEV
;
break
;
}
r
=
display
->
enable_te
(
display
,
!!
p
.
tearsync_info
.
enabled
);
break
;
}
default:
dev_err
(
fbdev
->
dev
,
"Unknown ioctl 0x%x
\n
"
,
cmd
);
r
=
-
EINVAL
;
}
if
(
r
<
0
)
DBG
(
"ioctl failed: %d
\n
"
,
r
);
return
r
;
}
drivers/video/omap2/omapfb/omapfb-main.c
0 → 100644
浏览文件 @
b39a982d
此差异已折叠。
点击以展开。
drivers/video/omap2/omapfb/omapfb-sysfs.c
0 → 100644
浏览文件 @
b39a982d
/*
* linux/drivers/video/omap2/omapfb-sysfs.c
*
* Copyright (C) 2008 Nokia Corporation
* Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
*
* Some code and ideas taken from drivers/video/omap/ driver
* by Imre Deak.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/fb.h>
#include <linux/sysfs.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/omapfb.h>
#include <plat/display.h>
#include <plat/vrfb.h>
#include "omapfb.h"
static
ssize_t
show_rotate_type
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
fb_info
*
fbi
=
dev_get_drvdata
(
dev
);
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
return
snprintf
(
buf
,
PAGE_SIZE
,
"%d
\n
"
,
ofbi
->
rotation_type
);
}
static
ssize_t
store_rotate_type
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
fb_info
*
fbi
=
dev_get_drvdata
(
dev
);
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
enum
omap_dss_rotation_type
rot_type
;
int
r
;
rot_type
=
simple_strtoul
(
buf
,
NULL
,
0
);
if
(
rot_type
!=
OMAP_DSS_ROT_DMA
&&
rot_type
!=
OMAP_DSS_ROT_VRFB
)
return
-
EINVAL
;
lock_fb_info
(
fbi
);
r
=
0
;
if
(
rot_type
==
ofbi
->
rotation_type
)
goto
out
;
if
(
ofbi
->
region
.
size
)
{
r
=
-
EBUSY
;
goto
out
;
}
ofbi
->
rotation_type
=
rot_type
;
/*
* Since the VRAM for this FB is not allocated at the moment we don't
* need to do any further parameter checking at this point.
*/
out:
unlock_fb_info
(
fbi
);
return
r
?
r
:
count
;
}
static
ssize_t
show_mirror
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
fb_info
*
fbi
=
dev_get_drvdata
(
dev
);
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
return
snprintf
(
buf
,
PAGE_SIZE
,
"%d
\n
"
,
ofbi
->
mirror
);
}
static
ssize_t
store_mirror
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
fb_info
*
fbi
=
dev_get_drvdata
(
dev
);
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
bool
mirror
;
int
r
;
struct
fb_var_screeninfo
new_var
;
mirror
=
simple_strtoul
(
buf
,
NULL
,
0
);
if
(
mirror
!=
0
&&
mirror
!=
1
)
return
-
EINVAL
;
lock_fb_info
(
fbi
);
ofbi
->
mirror
=
mirror
;
memcpy
(
&
new_var
,
&
fbi
->
var
,
sizeof
(
new_var
));
r
=
check_fb_var
(
fbi
,
&
new_var
);
if
(
r
)
goto
out
;
memcpy
(
&
fbi
->
var
,
&
new_var
,
sizeof
(
fbi
->
var
));
set_fb_fix
(
fbi
);
r
=
omapfb_apply_changes
(
fbi
,
0
);
if
(
r
)
goto
out
;
r
=
count
;
out:
unlock_fb_info
(
fbi
);
return
r
;
}
static
ssize_t
show_overlays
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
fb_info
*
fbi
=
dev_get_drvdata
(
dev
);
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
struct
omapfb2_device
*
fbdev
=
ofbi
->
fbdev
;
ssize_t
l
=
0
;
int
t
;
omapfb_lock
(
fbdev
);
lock_fb_info
(
fbi
);
for
(
t
=
0
;
t
<
ofbi
->
num_overlays
;
t
++
)
{
struct
omap_overlay
*
ovl
=
ofbi
->
overlays
[
t
];
int
ovlnum
;
for
(
ovlnum
=
0
;
ovlnum
<
fbdev
->
num_overlays
;
++
ovlnum
)
if
(
ovl
==
fbdev
->
overlays
[
ovlnum
])
break
;
l
+=
snprintf
(
buf
+
l
,
PAGE_SIZE
-
l
,
"%s%d"
,
t
==
0
?
""
:
","
,
ovlnum
);
}
l
+=
snprintf
(
buf
+
l
,
PAGE_SIZE
-
l
,
"
\n
"
);
unlock_fb_info
(
fbi
);
omapfb_unlock
(
fbdev
);
return
l
;
}
static
struct
omapfb_info
*
get_overlay_fb
(
struct
omapfb2_device
*
fbdev
,
struct
omap_overlay
*
ovl
)
{
int
i
,
t
;
for
(
i
=
0
;
i
<
fbdev
->
num_fbs
;
i
++
)
{
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbdev
->
fbs
[
i
]);
for
(
t
=
0
;
t
<
ofbi
->
num_overlays
;
t
++
)
{
if
(
ofbi
->
overlays
[
t
]
==
ovl
)
return
ofbi
;
}
}
return
NULL
;
}
static
ssize_t
store_overlays
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
fb_info
*
fbi
=
dev_get_drvdata
(
dev
);
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
struct
omapfb2_device
*
fbdev
=
ofbi
->
fbdev
;
struct
omap_overlay
*
ovls
[
OMAPFB_MAX_OVL_PER_FB
];
struct
omap_overlay
*
ovl
;
int
num_ovls
,
r
,
i
;
int
len
;
bool
added
=
false
;
num_ovls
=
0
;
len
=
strlen
(
buf
);
if
(
buf
[
len
-
1
]
==
'\n'
)
len
=
len
-
1
;
omapfb_lock
(
fbdev
);
lock_fb_info
(
fbi
);
if
(
len
>
0
)
{
char
*
p
=
(
char
*
)
buf
;
int
ovlnum
;
while
(
p
<
buf
+
len
)
{
int
found
;
if
(
num_ovls
==
OMAPFB_MAX_OVL_PER_FB
)
{
r
=
-
EINVAL
;
goto
out
;
}
ovlnum
=
simple_strtoul
(
p
,
&
p
,
0
);
if
(
ovlnum
>
fbdev
->
num_overlays
)
{
r
=
-
EINVAL
;
goto
out
;
}
found
=
0
;
for
(
i
=
0
;
i
<
num_ovls
;
++
i
)
{
if
(
ovls
[
i
]
==
fbdev
->
overlays
[
ovlnum
])
{
found
=
1
;
break
;
}
}
if
(
!
found
)
ovls
[
num_ovls
++
]
=
fbdev
->
overlays
[
ovlnum
];
p
++
;
}
}
for
(
i
=
0
;
i
<
num_ovls
;
++
i
)
{
struct
omapfb_info
*
ofbi2
=
get_overlay_fb
(
fbdev
,
ovls
[
i
]);
if
(
ofbi2
&&
ofbi2
!=
ofbi
)
{
dev_err
(
fbdev
->
dev
,
"overlay already in use
\n
"
);
r
=
-
EINVAL
;
goto
out
;
}
}
/* detach unused overlays */
for
(
i
=
0
;
i
<
ofbi
->
num_overlays
;
++
i
)
{
int
t
,
found
;
ovl
=
ofbi
->
overlays
[
i
];
found
=
0
;
for
(
t
=
0
;
t
<
num_ovls
;
++
t
)
{
if
(
ovl
==
ovls
[
t
])
{
found
=
1
;
break
;
}
}
if
(
found
)
continue
;
DBG
(
"detaching %d
\n
"
,
ofbi
->
overlays
[
i
]
->
id
);
omapfb_overlay_enable
(
ovl
,
0
);
if
(
ovl
->
manager
)
ovl
->
manager
->
apply
(
ovl
->
manager
);
for
(
t
=
i
+
1
;
t
<
ofbi
->
num_overlays
;
t
++
)
{
ofbi
->
rotation
[
t
-
1
]
=
ofbi
->
rotation
[
t
];
ofbi
->
overlays
[
t
-
1
]
=
ofbi
->
overlays
[
t
];
}
ofbi
->
num_overlays
--
;
i
--
;
}
for
(
i
=
0
;
i
<
num_ovls
;
++
i
)
{
int
t
,
found
;
ovl
=
ovls
[
i
];
found
=
0
;
for
(
t
=
0
;
t
<
ofbi
->
num_overlays
;
++
t
)
{
if
(
ovl
==
ofbi
->
overlays
[
t
])
{
found
=
1
;
break
;
}
}
if
(
found
)
continue
;
ofbi
->
rotation
[
ofbi
->
num_overlays
]
=
0
;
ofbi
->
overlays
[
ofbi
->
num_overlays
++
]
=
ovl
;
added
=
true
;
}
if
(
added
)
{
r
=
omapfb_apply_changes
(
fbi
,
0
);
if
(
r
)
goto
out
;
}
r
=
count
;
out:
unlock_fb_info
(
fbi
);
omapfb_unlock
(
fbdev
);
return
r
;
}
static
ssize_t
show_overlays_rotate
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
fb_info
*
fbi
=
dev_get_drvdata
(
dev
);
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
ssize_t
l
=
0
;
int
t
;
lock_fb_info
(
fbi
);
for
(
t
=
0
;
t
<
ofbi
->
num_overlays
;
t
++
)
{
l
+=
snprintf
(
buf
+
l
,
PAGE_SIZE
-
l
,
"%s%d"
,
t
==
0
?
""
:
","
,
ofbi
->
rotation
[
t
]);
}
l
+=
snprintf
(
buf
+
l
,
PAGE_SIZE
-
l
,
"
\n
"
);
unlock_fb_info
(
fbi
);
return
l
;
}
static
ssize_t
store_overlays_rotate
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
fb_info
*
fbi
=
dev_get_drvdata
(
dev
);
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
int
num_ovls
=
0
,
r
,
i
;
int
len
;
bool
changed
=
false
;
u8
rotation
[
OMAPFB_MAX_OVL_PER_FB
];
len
=
strlen
(
buf
);
if
(
buf
[
len
-
1
]
==
'\n'
)
len
=
len
-
1
;
lock_fb_info
(
fbi
);
if
(
len
>
0
)
{
char
*
p
=
(
char
*
)
buf
;
while
(
p
<
buf
+
len
)
{
int
rot
;
if
(
num_ovls
==
ofbi
->
num_overlays
)
{
r
=
-
EINVAL
;
goto
out
;
}
rot
=
simple_strtoul
(
p
,
&
p
,
0
);
if
(
rot
<
0
||
rot
>
3
)
{
r
=
-
EINVAL
;
goto
out
;
}
if
(
ofbi
->
rotation
[
num_ovls
]
!=
rot
)
changed
=
true
;
rotation
[
num_ovls
++
]
=
rot
;
p
++
;
}
}
if
(
num_ovls
!=
ofbi
->
num_overlays
)
{
r
=
-
EINVAL
;
goto
out
;
}
if
(
changed
)
{
for
(
i
=
0
;
i
<
num_ovls
;
++
i
)
ofbi
->
rotation
[
i
]
=
rotation
[
i
];
r
=
omapfb_apply_changes
(
fbi
,
0
);
if
(
r
)
goto
out
;
/* FIXME error handling? */
}
r
=
count
;
out:
unlock_fb_info
(
fbi
);
return
r
;
}
static
ssize_t
show_size
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
fb_info
*
fbi
=
dev_get_drvdata
(
dev
);
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
return
snprintf
(
buf
,
PAGE_SIZE
,
"%lu
\n
"
,
ofbi
->
region
.
size
);
}
static
ssize_t
store_size
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
fb_info
*
fbi
=
dev_get_drvdata
(
dev
);
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
unsigned
long
size
;
int
r
;
int
i
;
size
=
PAGE_ALIGN
(
simple_strtoul
(
buf
,
NULL
,
0
));
lock_fb_info
(
fbi
);
for
(
i
=
0
;
i
<
ofbi
->
num_overlays
;
i
++
)
{
if
(
ofbi
->
overlays
[
i
]
->
info
.
enabled
)
{
r
=
-
EBUSY
;
goto
out
;
}
}
if
(
size
!=
ofbi
->
region
.
size
)
{
r
=
omapfb_realloc_fbmem
(
fbi
,
size
,
ofbi
->
region
.
type
);
if
(
r
)
{
dev_err
(
dev
,
"realloc fbmem failed
\n
"
);
goto
out
;
}
}
r
=
count
;
out:
unlock_fb_info
(
fbi
);
return
r
;
}
static
ssize_t
show_phys
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
fb_info
*
fbi
=
dev_get_drvdata
(
dev
);
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
return
snprintf
(
buf
,
PAGE_SIZE
,
"%0x
\n
"
,
ofbi
->
region
.
paddr
);
}
static
ssize_t
show_virt
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
fb_info
*
fbi
=
dev_get_drvdata
(
dev
);
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
return
snprintf
(
buf
,
PAGE_SIZE
,
"%p
\n
"
,
ofbi
->
region
.
vaddr
);
}
static
struct
device_attribute
omapfb_attrs
[]
=
{
__ATTR
(
rotate_type
,
S_IRUGO
|
S_IWUSR
,
show_rotate_type
,
store_rotate_type
),
__ATTR
(
mirror
,
S_IRUGO
|
S_IWUSR
,
show_mirror
,
store_mirror
),
__ATTR
(
size
,
S_IRUGO
|
S_IWUSR
,
show_size
,
store_size
),
__ATTR
(
overlays
,
S_IRUGO
|
S_IWUSR
,
show_overlays
,
store_overlays
),
__ATTR
(
overlays_rotate
,
S_IRUGO
|
S_IWUSR
,
show_overlays_rotate
,
store_overlays_rotate
),
__ATTR
(
phys_addr
,
S_IRUGO
,
show_phys
,
NULL
),
__ATTR
(
virt_addr
,
S_IRUGO
,
show_virt
,
NULL
),
};
int
omapfb_create_sysfs
(
struct
omapfb2_device
*
fbdev
)
{
int
i
;
int
r
;
DBG
(
"create sysfs for fbs
\n
"
);
for
(
i
=
0
;
i
<
fbdev
->
num_fbs
;
i
++
)
{
int
t
;
for
(
t
=
0
;
t
<
ARRAY_SIZE
(
omapfb_attrs
);
t
++
)
{
r
=
device_create_file
(
fbdev
->
fbs
[
i
]
->
dev
,
&
omapfb_attrs
[
t
]);
if
(
r
)
{
dev_err
(
fbdev
->
dev
,
"failed to create sysfs "
"file
\n
"
);
return
r
;
}
}
}
return
0
;
}
void
omapfb_remove_sysfs
(
struct
omapfb2_device
*
fbdev
)
{
int
i
,
t
;
DBG
(
"remove sysfs for fbs
\n
"
);
for
(
i
=
0
;
i
<
fbdev
->
num_fbs
;
i
++
)
{
for
(
t
=
0
;
t
<
ARRAY_SIZE
(
omapfb_attrs
);
t
++
)
device_remove_file
(
fbdev
->
fbs
[
i
]
->
dev
,
&
omapfb_attrs
[
t
]);
}
}
drivers/video/omap2/omapfb/omapfb.h
0 → 100644
浏览文件 @
b39a982d
/*
* linux/drivers/video/omap2/omapfb.h
*
* Copyright (C) 2008 Nokia Corporation
* Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
*
* Some code and ideas taken from drivers/video/omap/ driver
* by Imre Deak.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __DRIVERS_VIDEO_OMAP2_OMAPFB_H__
#define __DRIVERS_VIDEO_OMAP2_OMAPFB_H__
#ifdef CONFIG_FB_OMAP2_DEBUG_SUPPORT
#define DEBUG
#endif
#include <plat/display.h>
#ifdef DEBUG
extern
unsigned
int
omapfb_debug
;
#define DBG(format, ...) \
if (omapfb_debug) \
printk(KERN_DEBUG "OMAPFB: " format, ## __VA_ARGS__)
#else
#define DBG(format, ...)
#endif
#define FB2OFB(fb_info) ((struct omapfb_info *)(fb_info->par))
/* max number of overlays to which a framebuffer data can be direct */
#define OMAPFB_MAX_OVL_PER_FB 3
struct
omapfb2_mem_region
{
u32
paddr
;
void
__iomem
*
vaddr
;
struct
vrfb
vrfb
;
unsigned
long
size
;
u8
type
;
/* OMAPFB_PLANE_MEM_* */
bool
alloc
;
/* allocated by the driver */
bool
map
;
/* kernel mapped by the driver */
};
/* appended to fb_info */
struct
omapfb_info
{
int
id
;
struct
omapfb2_mem_region
region
;
atomic_t
map_count
;
int
num_overlays
;
struct
omap_overlay
*
overlays
[
OMAPFB_MAX_OVL_PER_FB
];
struct
omapfb2_device
*
fbdev
;
enum
omap_dss_rotation_type
rotation_type
;
u8
rotation
[
OMAPFB_MAX_OVL_PER_FB
];
bool
mirror
;
};
struct
omapfb2_device
{
struct
device
*
dev
;
struct
mutex
mtx
;
u32
pseudo_palette
[
17
];
int
state
;
unsigned
num_fbs
;
struct
fb_info
*
fbs
[
10
];
unsigned
num_displays
;
struct
omap_dss_device
*
displays
[
10
];
unsigned
num_overlays
;
struct
omap_overlay
*
overlays
[
10
];
unsigned
num_managers
;
struct
omap_overlay_manager
*
managers
[
10
];
};
struct
omapfb_colormode
{
enum
omap_color_mode
dssmode
;
u32
bits_per_pixel
;
u32
nonstd
;
struct
fb_bitfield
red
;
struct
fb_bitfield
green
;
struct
fb_bitfield
blue
;
struct
fb_bitfield
transp
;
};
void
set_fb_fix
(
struct
fb_info
*
fbi
);
int
check_fb_var
(
struct
fb_info
*
fbi
,
struct
fb_var_screeninfo
*
var
);
int
omapfb_realloc_fbmem
(
struct
fb_info
*
fbi
,
unsigned
long
size
,
int
type
);
int
omapfb_apply_changes
(
struct
fb_info
*
fbi
,
int
init
);
int
omapfb_create_sysfs
(
struct
omapfb2_device
*
fbdev
);
void
omapfb_remove_sysfs
(
struct
omapfb2_device
*
fbdev
);
int
omapfb_ioctl
(
struct
fb_info
*
fbi
,
unsigned
int
cmd
,
unsigned
long
arg
);
int
dss_mode_to_fb_mode
(
enum
omap_color_mode
dssmode
,
struct
fb_var_screeninfo
*
var
);
/* find the display connected to this fb, if any */
static
inline
struct
omap_dss_device
*
fb2display
(
struct
fb_info
*
fbi
)
{
struct
omapfb_info
*
ofbi
=
FB2OFB
(
fbi
);
int
i
;
/* XXX: returns the display connected to first attached overlay */
for
(
i
=
0
;
i
<
ofbi
->
num_overlays
;
i
++
)
{
if
(
ofbi
->
overlays
[
i
]
->
manager
)
return
ofbi
->
overlays
[
i
]
->
manager
->
device
;
}
return
NULL
;
}
static
inline
void
omapfb_lock
(
struct
omapfb2_device
*
fbdev
)
{
mutex_lock
(
&
fbdev
->
mtx
);
}
static
inline
void
omapfb_unlock
(
struct
omapfb2_device
*
fbdev
)
{
mutex_unlock
(
&
fbdev
->
mtx
);
}
static
inline
int
omapfb_overlay_enable
(
struct
omap_overlay
*
ovl
,
int
enable
)
{
struct
omap_overlay_info
info
;
ovl
->
get_overlay_info
(
ovl
,
&
info
);
info
.
enabled
=
enable
;
return
ovl
->
set_overlay_info
(
ovl
,
&
info
);
}
#endif
include/linux/omapfb.h
浏览文件 @
b39a982d
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#ifndef __LINUX_OMAPFB_H__
#ifndef __LINUX_OMAPFB_H__
#define __LINUX_OMAPFB_H__
#define __LINUX_OMAPFB_H__
#include <linux/fb.h>
#include <linux/ioctl.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <linux/types.h>
...
@@ -50,6 +51,12 @@
...
@@ -50,6 +51,12 @@
#define OMAPFB_UPDATE_WINDOW OMAP_IOW(54, struct omapfb_update_window)
#define OMAPFB_UPDATE_WINDOW OMAP_IOW(54, struct omapfb_update_window)
#define OMAPFB_SETUP_MEM OMAP_IOW(55, struct omapfb_mem_info)
#define OMAPFB_SETUP_MEM OMAP_IOW(55, struct omapfb_mem_info)
#define OMAPFB_QUERY_MEM OMAP_IOW(56, struct omapfb_mem_info)
#define OMAPFB_QUERY_MEM OMAP_IOW(56, struct omapfb_mem_info)
#define OMAPFB_WAITFORVSYNC OMAP_IO(57)
#define OMAPFB_MEMORY_READ OMAP_IOR(58, struct omapfb_memory_read)
#define OMAPFB_GET_OVERLAY_COLORMODE OMAP_IOR(59, struct omapfb_ovl_colormode)
#define OMAPFB_WAITFORGO OMAP_IO(60)
#define OMAPFB_GET_VRAM_INFO OMAP_IOR(61, struct omapfb_vram_info)
#define OMAPFB_SET_TEARSYNC OMAP_IOW(62, struct omapfb_tearsync_info)
#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
...
@@ -87,6 +94,13 @@ enum omapfb_color_format {
...
@@ -87,6 +94,13 @@ enum omapfb_color_format {
OMAPFB_COLOR_CLUT_1BPP
,
OMAPFB_COLOR_CLUT_1BPP
,
OMAPFB_COLOR_RGB444
,
OMAPFB_COLOR_RGB444
,
OMAPFB_COLOR_YUY422
,
OMAPFB_COLOR_YUY422
,
OMAPFB_COLOR_ARGB16
,
OMAPFB_COLOR_RGB24U
,
/* RGB24, 32-bit container */
OMAPFB_COLOR_RGB24P
,
/* RGB24, 24-bit container */
OMAPFB_COLOR_ARGB32
,
OMAPFB_COLOR_RGBA32
,
OMAPFB_COLOR_RGBX32
,
};
};
struct
omapfb_update_window
{
struct
omapfb_update_window
{
...
@@ -158,6 +172,40 @@ enum omapfb_update_mode {
...
@@ -158,6 +172,40 @@ enum omapfb_update_mode {
OMAPFB_MANUAL_UPDATE
OMAPFB_MANUAL_UPDATE
};
};
struct
omapfb_memory_read
{
__u16
x
;
__u16
y
;
__u16
w
;
__u16
h
;
size_t
buffer_size
;
void
__user
*
buffer
;
};
struct
omapfb_ovl_colormode
{
__u8
overlay_idx
;
__u8
mode_idx
;
__u32
bits_per_pixel
;
__u32
nonstd
;
struct
fb_bitfield
red
;
struct
fb_bitfield
green
;
struct
fb_bitfield
blue
;
struct
fb_bitfield
transp
;
};
struct
omapfb_vram_info
{
__u32
total
;
__u32
free
;
__u32
largest_free_block
;
__u32
reserved
[
5
];
};
struct
omapfb_tearsync_info
{
__u8
enabled
;
__u8
reserved1
[
3
];
__u16
line
;
__u16
reserved2
;
};
#ifdef __KERNEL__
#ifdef __KERNEL__
#include <plat/board.h>
#include <plat/board.h>
...
@@ -173,6 +221,11 @@ struct omapfb_mem_region {
...
@@ -173,6 +221,11 @@ struct omapfb_mem_region {
void
__iomem
*
vaddr
;
void
__iomem
*
vaddr
;
unsigned
long
size
;
unsigned
long
size
;
u8
type
;
/* OMAPFB_PLANE_MEM_* */
u8
type
;
/* OMAPFB_PLANE_MEM_* */
enum
omapfb_color_format
format
;
/* OMAPFB_COLOR_* */
unsigned
format_used
:
1
;
/* Must be set when format is set.
* Needed b/c of the badly chosen 0
* base for OMAPFB_COLOR_* values
*/
unsigned
alloc
:
1
;
/* allocated by the driver */
unsigned
alloc
:
1
;
/* allocated by the driver */
unsigned
map
:
1
;
/* kernel mapped by the driver */
unsigned
map
:
1
;
/* kernel mapped by the driver */
};
};
...
@@ -189,6 +242,7 @@ struct omapfb_platform_data {
...
@@ -189,6 +242,7 @@ struct omapfb_platform_data {
};
};
/* in arch/arm/plat-omap/fb.c */
/* in arch/arm/plat-omap/fb.c */
extern
void
omapfb_set_platform_data
(
struct
omapfb_platform_data
*
data
);
extern
void
omapfb_set_ctrl_platform_data
(
void
*
pdata
);
extern
void
omapfb_set_ctrl_platform_data
(
void
*
pdata
);
extern
void
omapfb_reserve_sdram
(
void
);
extern
void
omapfb_reserve_sdram
(
void
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录