Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xenomai
ipipe
Commits
b39a982d
Commit
b39a982d
authored
Aug 04, 2009
by
Tomi Valkeinen
Browse files
OMAP: DSS2: omapfb driver
Signed-off-by:
Tomi Valkeinen
<
tomi.valkeinen@nokia.com
>
parent
3de7a1dc
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
arch/arm/plat-omap/fb.c
View file @
b39a982d
...
...
@@ -55,6 +55,10 @@ static struct platform_device omap_fb_device = {
.
num_resources
=
0
,
};
void
omapfb_set_platform_data
(
struct
omapfb_platform_data
*
data
)
{
}
static
inline
int
ranges_overlap
(
unsigned
long
start1
,
unsigned
long
size1
,
unsigned
long
start2
,
unsigned
long
size2
)
{
...
...
@@ -327,7 +331,33 @@ static inline int omap_init_fb(void)
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
)
{}
unsigned
long
omapfb_reserve_sram
(
unsigned
long
sram_pstart
,
...
...
@@ -339,5 +369,20 @@ unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
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
drivers/video/omap/Kconfig
View file @
b39a982d
config FB_OMAP
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_COPYAREA
select FB_CFB_IMAGEBLIT
...
...
@@ -72,7 +73,7 @@ config FB_OMAP_LCD_MIPID
config FB_OMAP_BOOTLOADER_INIT
bool "Check bootloader initialization"
depends on FB_OMAP
depends on FB_OMAP
|| FB_OMAP2
help
Say Y here if you want to enable checking if the bootloader has
already initialized the display controller. In this case the
...
...
drivers/video/omap2/Kconfig
View file @
b39a982d
...
...
@@ -5,3 +5,4 @@ config OMAP2_VRFB
bool
source "drivers/video/omap2/dss/Kconfig"
source "drivers/video/omap2/omapfb/Kconfig"
drivers/video/omap2/Makefile
View file @
b39a982d
...
...
@@ -2,3 +2,4 @@ obj-$(CONFIG_OMAP2_VRAM) += vram.o
obj-$(CONFIG_OMAP2_VRFB)
+=
vrfb.o
obj-y
+=
dss/
obj-y
+=
omapfb/
drivers/video/omap2/omapfb/Kconfig
0 → 100644
View file @
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
View file @
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
View file @
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
;