Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
343684ff
Commit
343684ff
authored
Mar 19, 2009
by
Sascha Hauer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
imxfb: Add support for multiple displays
Signed-off-by:
Sascha Hauer
<
s.hauer@pengutronix.de
>
parent
d6b51502
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
208 additions
and
128 deletions
+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
No files found.
arch/arm/mach-mx2/mx27ads.c
View file @
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
View file @
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
View file @
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
View file @
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
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment