Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
343684ff
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
343684ff
编写于
3月 19, 2009
作者:
S
Sascha Hauer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
imxfb: Add support for multiple displays
Signed-off-by:
N
Sascha Hauer
<
s.hauer@pengutronix.de
>
上级
d6b51502
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
208 addition
and
128 deletion
+208
-128
arch/arm/mach-mx2/mx27ads.c
arch/arm/mach-mx2/mx27ads.c
+22
-14
arch/arm/mach-mx2/pcm970-baseboard.c
arch/arm/mach-mx2/pcm970-baseboard.c
+56
-27
arch/arm/plat-mxc/include/mach/imxfb.h
arch/arm/plat-mxc/include/mach/imxfb.h
+10
-16
drivers/video/imxfb.c
drivers/video/imxfb.c
+120
-71
未找到文件。
arch/arm/mach-mx2/mx27ads.c
浏览文件 @
343684ff
...
...
@@ -183,20 +183,29 @@ void lcd_power(int on)
__raw_writew
(
PBC_BCTRL1_LCDON
,
PBC_BCTRL1_CLEAR_REG
);
}
static
struct
imx_fb_platform_data
mx27ads_fb_data
=
{
.
pixclock
=
188679
,
static
struct
imx_fb_videomode
mx27ads_modes
[]
=
{
{
.
mode
=
{
.
name
=
"Sharp-LQ035Q7"
,
.
refresh
=
60
,
.
xres
=
240
,
.
yres
=
320
,
.
bpp
=
16
,
.
pixclock
=
188679
,
/* in ps (5.3MHz) */
.
hsync_len
=
1
,
.
left_margin
=
9
,
.
right_margin
=
16
,
.
vsync_len
=
1
,
.
upper_margin
=
7
,
.
lower_margin
=
9
,
.
fixed_screen_cpu
=
0
,
},
.
bpp
=
16
,
.
pcr
=
0xFB008BC0
,
},
};
static
struct
imx_fb_platform_data
mx27ads_fb_data
=
{
.
mode
=
mx27ads_modes
,
.
num_modes
=
ARRAY_SIZE
(
mx27ads_modes
),
/*
* - HSYNC active high
...
...
@@ -207,7 +216,6 @@ static struct imx_fb_platform_data mx27ads_fb_data = {
* - data enable low active
* - enable sharp mode
*/
.
pcr
=
0xFB008BC0
,
.
pwmr
=
0x00A903FF
,
.
lscr1
=
0x00120300
,
.
dmacr
=
0x00020010
,
...
...
arch/arm/mach-mx2/pcm970-baseboard.c
浏览文件 @
343684ff
...
...
@@ -125,25 +125,21 @@ static struct imxmmc_platform_data sdhc_pdata = {
.
exit
=
pcm970_sdhc2_exit
,
};
/*
* Connected is a portrait Sharp-QVGA display
* of type: LQ035Q7DH06
*/
static
struct
imx_fb_platform_data
pcm038_fb_data
=
{
.
pixclock
=
188679
,
/* in ps (5.3MHz) */
static
struct
imx_fb_videomode
pcm970_modes
[]
=
{
{
.
mode
=
{
.
name
=
"Sharp-LQ035Q7"
,
.
refresh
=
60
,
.
xres
=
240
,
.
yres
=
320
,
.
bpp
=
16
,
.
pixclock
=
188679
,
/* in ps (5.3MHz) */
.
hsync_len
=
7
,
.
left_margin
=
5
,
.
right_margin
=
16
,
.
vsync_len
=
1
,
.
upper_margin
=
7
,
.
lower_margin
=
9
,
.
fixed_screen_cpu
=
0
,
},
/*
* - HSYNC active high
* - VSYNC active high
...
...
@@ -153,7 +149,40 @@ static struct imx_fb_platform_data pcm038_fb_data = {
* - data enable low active
* - enable sharp mode
*/
.
pcr
=
0xFA0080C0
,
.
pcr
=
0xF00080C0
,
.
bpp
=
16
,
},
{
.
mode
=
{
.
name
=
"TX090"
,
.
refresh
=
60
,
.
xres
=
240
,
.
yres
=
320
,
.
pixclock
=
38255
,
.
left_margin
=
144
,
.
right_margin
=
0
,
.
upper_margin
=
7
,
.
lower_margin
=
40
,
.
hsync_len
=
96
,
.
vsync_len
=
1
,
},
/*
* - HSYNC active low (1 << 22)
* - VSYNC active low (1 << 23)
* - clk notenabled while idle
* - clock not inverted
* - data not inverted
* - data enable low active
* - enable sharp mode
*/
.
pcr
=
0xF0008080
|
(
1
<<
22
)
|
(
1
<<
23
)
|
(
1
<<
19
),
.
bpp
=
32
,
},
};
static
struct
imx_fb_platform_data
pcm038_fb_data
=
{
.
mode
=
pcm970_modes
,
.
num_modes
=
ARRAY_SIZE
(
pcm970_modes
),
.
pwmr
=
0x00A903FF
,
.
lscr1
=
0x00120300
,
.
dmacr
=
0x00020010
,
...
...
arch/arm/plat-mxc/include/mach/imxfb.h
浏览文件 @
343684ff
...
...
@@ -2,6 +2,8 @@
* This structure describes the machine which we are running on.
*/
#include <linux/fb.h>
#define PCR_TFT (1 << 31)
#define PCR_COLOR (1 << 30)
#define PCR_PBSIZ_1 (0 << 28)
...
...
@@ -47,29 +49,21 @@
#define DMACR_HM(x) (((x) & 0xf) << 16)
#define DMACR_TM(x) ((x) & 0xf)
struct
imx_fb_platform_data
{
u_long
pixclock
;
u_short
xres
;
u_short
yres
;
u_int
nonstd
;
u_char
bpp
;
u_char
hsync_len
;
u_char
left_margin
;
u_char
right_margin
;
struct
imx_fb_videomode
{
struct
fb_videomode
mode
;
u32
pcr
;
unsigned
char
bpp
;
};
u_char
vsync_len
;
u_char
upper_margin
;
u_char
lower_margin
;
u_char
sync
;
struct
imx_fb_platform_data
{
struct
imx_fb_videomode
*
mode
;
int
num_modes
;
u_int
cmap_greyscale
:
1
,
cmap_inverse:
1
,
cmap_static:
1
,
unused:
29
;
u_int
pcr
;
u_int
pwmr
;
u_int
lscr1
;
u_int
dmacr
;
...
...
drivers/video/imxfb.c
浏览文件 @
343684ff
...
...
@@ -130,6 +130,10 @@
#define LCDISR_EOF (1<<1)
#define LCDISR_BOF (1<<0)
/* Used fb-mode. Can be set on kernel command line, therefore file-static. */
static
const
char
*
fb_mode
;
/*
* These are the bitfields for each
* display depth that we support.
...
...
@@ -146,10 +150,6 @@ struct imxfb_info {
void
__iomem
*
regs
;
struct
clk
*
clk
;
u_int
max_bpp
;
u_int
max_xres
;
u_int
max_yres
;
/*
* These are the addresses we mapped
* the framebuffer memory region to.
...
...
@@ -173,6 +173,9 @@ struct imxfb_info {
cmap_static:
1
,
unused:
30
;
struct
imx_fb_videomode
*
mode
;
int
num_modes
;
void
(
*
lcd_power
)(
int
);
void
(
*
backlight_power
)(
int
);
};
...
...
@@ -299,6 +302,18 @@ static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
return
ret
;
}
static
const
struct
imx_fb_videomode
*
imxfb_find_mode
(
struct
imxfb_info
*
fbi
)
{
struct
imx_fb_videomode
*
m
;
int
i
;
for
(
i
=
0
,
m
=
&
fbi
->
mode
[
0
];
i
<
fbi
->
num_modes
;
i
++
,
m
++
)
{
if
(
!
strcmp
(
m
->
mode
.
name
,
fb_mode
))
return
m
;
}
return
NULL
;
}
/*
* imxfb_check_var():
* Round up in the following order: bits_per_pixel, xres,
...
...
@@ -309,35 +324,81 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct
imxfb_info
*
fbi
=
info
->
par
;
struct
imxfb_rgb
*
rgb
;
const
struct
imx_fb_videomode
*
imxfb_mode
;
unsigned
long
lcd_clk
;
unsigned
long
long
tmp
;
u32
pcr
=
0
;
if
(
var
->
xres
<
MIN_XRES
)
var
->
xres
=
MIN_XRES
;
if
(
var
->
yres
<
MIN_YRES
)
var
->
yres
=
MIN_YRES
;
if
(
var
->
xres
>
fbi
->
max_xres
)
var
->
xres
=
fbi
->
max_xres
;
if
(
var
->
yres
>
fbi
->
max_yres
)
var
->
yres
=
fbi
->
max_yres
;
imxfb_mode
=
imxfb_find_mode
(
fbi
);
if
(
!
imxfb_mode
)
return
-
EINVAL
;
var
->
xres
=
imxfb_mode
->
mode
.
xres
;
var
->
yres
=
imxfb_mode
->
mode
.
yres
;
var
->
bits_per_pixel
=
imxfb_mode
->
bpp
;
var
->
pixclock
=
imxfb_mode
->
mode
.
pixclock
;
var
->
hsync_len
=
imxfb_mode
->
mode
.
hsync_len
;
var
->
left_margin
=
imxfb_mode
->
mode
.
left_margin
;
var
->
right_margin
=
imxfb_mode
->
mode
.
right_margin
;
var
->
vsync_len
=
imxfb_mode
->
mode
.
vsync_len
;
var
->
upper_margin
=
imxfb_mode
->
mode
.
upper_margin
;
var
->
lower_margin
=
imxfb_mode
->
mode
.
lower_margin
;
var
->
sync
=
imxfb_mode
->
mode
.
sync
;
var
->
xres_virtual
=
max
(
var
->
xres_virtual
,
var
->
xres
);
var
->
yres_virtual
=
max
(
var
->
yres_virtual
,
var
->
yres
);
pr_debug
(
"var->bits_per_pixel=%d
\n
"
,
var
->
bits_per_pixel
);
lcd_clk
=
clk_get_rate
(
fbi
->
clk
);
tmp
=
var
->
pixclock
*
(
unsigned
long
long
)
lcd_clk
;
do_div
(
tmp
,
1000000
);
if
(
do_div
(
tmp
,
1000000
)
>
500000
)
tmp
++
;
pcr
=
(
unsigned
int
)
tmp
;
if
(
--
pcr
>
0x3F
)
{
pcr
=
0x3F
;
printk
(
KERN_WARNING
"Must limit pixel clock to %luHz
\n
"
,
lcd_clk
/
pcr
);
}
switch
(
var
->
bits_per_pixel
)
{
case
32
:
pcr
|=
PCR_BPIX_18
;
rgb
=
&
def_rgb_18
;
break
;
case
16
:
default:
if
(
fbi
->
pcr
&
PCR_TFT
)
if
(
cpu_is_mx1
())
pcr
|=
PCR_BPIX_12
;
else
pcr
|=
PCR_BPIX_16
;
if
(
imxfb_mode
->
pcr
&
PCR_TFT
)
rgb
=
&
def_rgb_16_tft
;
else
rgb
=
&
def_rgb_16_stn
;
break
;
case
8
:
pcr
|=
PCR_BPIX_8
;
rgb
=
&
def_rgb_8
;
break
;
}
/* add sync polarities */
pcr
|=
imxfb_mode
->
pcr
&
~
(
0x3f
|
(
7
<<
25
));
fbi
->
pcr
=
pcr
;
/*
* Copy the RGB parameters for this display
* from the machine specific parameters.
...
...
@@ -394,10 +455,6 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
writel
(
fbi
->
screen_dma
,
fbi
->
regs
+
LCDC_SSA
);
/* physical screen start address */
writel
(
VPW_VPW
(
fbi
->
max_xres
*
fbi
->
max_bpp
/
8
/
4
),
fbi
->
regs
+
LCDC_VPW
);
/* panning offset 0 (0 pixel offset) */
writel
(
0x00000000
,
fbi
->
regs
+
LCDC_POS
);
...
...
@@ -469,8 +526,6 @@ static struct fb_ops imxfb_ops = {
static
int
imxfb_activate_var
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
{
struct
imxfb_info
*
fbi
=
info
->
par
;
unsigned
int
pcr
,
lcd_clk
;
unsigned
long
long
tmp
;
pr_debug
(
"var: xres=%d hslen=%d lm=%d rm=%d
\n
"
,
var
->
xres
,
var
->
hsync_len
,
...
...
@@ -506,6 +561,10 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
info
->
fix
.
id
,
var
->
lower_margin
);
#endif
/* physical screen start address */
writel
(
VPW_VPW
(
var
->
xres
*
var
->
bits_per_pixel
/
8
/
4
),
fbi
->
regs
+
LCDC_VPW
);
writel
(
HCR_H_WIDTH
(
var
->
hsync_len
-
1
)
|
HCR_H_WAIT_1
(
var
->
right_margin
-
1
)
|
HCR_H_WAIT_2
(
var
->
left_margin
-
3
),
...
...
@@ -519,38 +578,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
writel
(
SIZE_XMAX
(
var
->
xres
)
|
SIZE_YMAX
(
var
->
yres
),
fbi
->
regs
+
LCDC_SIZE
);
lcd_clk
=
clk_get_rate
(
fbi
->
clk
);
tmp
=
var
->
pixclock
*
(
unsigned
long
long
)
lcd_clk
;
do_div
(
tmp
,
1000000
);
if
(
do_div
(
tmp
,
1000000
)
>
500000
)
tmp
++
;
pcr
=
(
unsigned
int
)
tmp
;
if
(
--
pcr
>
0x3F
)
{
pcr
=
0x3F
;
printk
(
KERN_WARNING
"Must limit pixel clock to %uHz
\n
"
,
lcd_clk
/
pcr
);
}
switch
(
var
->
bits_per_pixel
)
{
case
32
:
pcr
|=
PCR_BPIX_18
;
break
;
case
16
:
default:
if
(
cpu_is_mx1
())
pcr
|=
PCR_BPIX_12
;
else
pcr
|=
PCR_BPIX_16
;
break
;
case
8
:
pcr
|=
PCR_BPIX_8
;
break
;
}
/* add sync polarities */
pcr
|=
fbi
->
pcr
&
~
(
0x3f
|
(
7
<<
25
));
writel
(
pcr
,
fbi
->
regs
+
LCDC_PCR
);
writel
(
fbi
->
pcr
,
fbi
->
regs
+
LCDC_PCR
);
writel
(
fbi
->
pwmr
,
fbi
->
regs
+
LCDC_PWMR
);
writel
(
fbi
->
lscr1
,
fbi
->
regs
+
LCDC_LSCR1
);
writel
(
fbi
->
dmacr
,
fbi
->
regs
+
LCDC_DMACR
);
...
...
@@ -592,6 +620,8 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
struct
imx_fb_platform_data
*
pdata
=
pdev
->
dev
.
platform_data
;
struct
fb_info
*
info
=
dev_get_drvdata
(
&
pdev
->
dev
);
struct
imxfb_info
*
fbi
=
info
->
par
;
struct
imx_fb_videomode
*
m
;
int
i
;
pr_debug
(
"%s
\n
"
,
__func__
);
...
...
@@ -620,35 +650,18 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
info
->
fbops
=
&
imxfb_ops
;
info
->
flags
=
FBINFO_FLAG_DEFAULT
|
FBINFO_READS_FAST
;
fbi
->
max_xres
=
pdata
->
xres
;
info
->
var
.
xres
=
pdata
->
xres
;
info
->
var
.
xres_virtual
=
pdata
->
xres
;
fbi
->
max_yres
=
pdata
->
yres
;
info
->
var
.
yres
=
pdata
->
yres
;
info
->
var
.
yres_virtual
=
pdata
->
yres
;
fbi
->
max_bpp
=
pdata
->
bpp
;
info
->
var
.
bits_per_pixel
=
pdata
->
bpp
;
info
->
var
.
nonstd
=
pdata
->
nonstd
;
info
->
var
.
pixclock
=
pdata
->
pixclock
;
info
->
var
.
hsync_len
=
pdata
->
hsync_len
;
info
->
var
.
left_margin
=
pdata
->
left_margin
;
info
->
var
.
right_margin
=
pdata
->
right_margin
;
info
->
var
.
vsync_len
=
pdata
->
vsync_len
;
info
->
var
.
upper_margin
=
pdata
->
upper_margin
;
info
->
var
.
lower_margin
=
pdata
->
lower_margin
;
info
->
var
.
sync
=
pdata
->
sync
;
info
->
var
.
grayscale
=
pdata
->
cmap_greyscale
;
fbi
->
cmap_inverse
=
pdata
->
cmap_inverse
;
fbi
->
cmap_static
=
pdata
->
cmap_static
;
fbi
->
pcr
=
pdata
->
pcr
;
fbi
->
lscr1
=
pdata
->
lscr1
;
fbi
->
dmacr
=
pdata
->
dmacr
;
fbi
->
pwmr
=
pdata
->
pwmr
;
fbi
->
lcd_power
=
pdata
->
lcd_power
;
fbi
->
backlight_power
=
pdata
->
backlight_power
;
info
->
fix
.
smem_len
=
fbi
->
max_xres
*
fbi
->
max_yres
*
fbi
->
max_bpp
/
8
;
for
(
i
=
0
,
m
=
&
pdata
->
mode
[
0
];
i
<
pdata
->
num_modes
;
i
++
,
m
++
)
info
->
fix
.
smem_len
=
max_t
(
size_t
,
info
->
fix
.
smem_len
,
m
->
mode
.
xres
*
m
->
mode
.
yres
*
m
->
bpp
/
8
);
return
0
;
}
...
...
@@ -659,7 +672,7 @@ static int __init imxfb_probe(struct platform_device *pdev)
struct
fb_info
*
info
;
struct
imx_fb_platform_data
*
pdata
;
struct
resource
*
res
;
int
ret
;
int
ret
,
i
;
dev_info
(
&
pdev
->
dev
,
"i.MX Framebuffer driver
\n
"
);
...
...
@@ -679,6 +692,9 @@ static int __init imxfb_probe(struct platform_device *pdev)
fbi
=
info
->
par
;
if
(
!
fb_mode
)
fb_mode
=
pdata
->
mode
[
0
].
mode
.
name
;
platform_set_drvdata
(
pdev
,
info
);
ret
=
imxfb_init_fbinfo
(
pdev
);
...
...
@@ -736,6 +752,13 @@ static int __init imxfb_probe(struct platform_device *pdev)
goto
failed_platform_init
;
}
fbi
->
mode
=
pdata
->
mode
;
fbi
->
num_modes
=
pdata
->
num_modes
;
INIT_LIST_HEAD
(
&
info
->
modelist
);
for
(
i
=
0
;
i
<
pdata
->
num_modes
;
i
++
)
fb_add_videomode
(
&
pdata
->
mode
[
i
].
mode
,
&
info
->
modelist
);
/*
* This makes sure that our colour bitfield
* descriptors are correctly initialised.
...
...
@@ -828,8 +851,34 @@ static struct platform_driver imxfb_driver = {
},
};
static
int
imxfb_setup
(
void
)
{
#ifndef MODULE
char
*
opt
,
*
options
=
NULL
;
if
(
fb_get_options
(
"imxfb"
,
&
options
))
return
-
ENODEV
;
if
(
!
options
||
!*
options
)
return
0
;
while
((
opt
=
strsep
(
&
options
,
","
))
!=
NULL
)
{
if
(
!*
opt
)
continue
;
else
fb_mode
=
opt
;
}
#endif
return
0
;
}
int
__init
imxfb_init
(
void
)
{
int
ret
=
imxfb_setup
();
if
(
ret
<
0
)
return
ret
;
return
platform_driver_probe
(
&
imxfb_driver
,
imxfb_probe
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录