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
e9fe8a71
Commit
e9fe8a71
authored
Mar 20, 2012
by
Florian Tobias Schandinat
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-3.4' of
git://gitorious.org/linux-omap-dss2/linux
into fbdev-next
parents
f413070e
df01d530
Changes
52
Hide whitespace changes
Inline
Side-by-side
Showing
52 changed files
with
1001 additions
and
5201 deletions
+1001
-5201
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/board-ams-delta.c
+3
-6
arch/arm/mach-omap1/board-fsample.c
arch/arm/mach-omap1/board-fsample.c
+3
-12
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h2.c
+3
-12
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-h3.c
+3
-6
arch/arm/mach-omap1/board-htcherald.c
arch/arm/mach-omap1/board-htcherald.c
+3
-6
arch/arm/mach-omap1/board-innovator.c
arch/arm/mach-omap1/board-innovator.c
+3
-8
arch/arm/mach-omap1/board-nokia770.c
arch/arm/mach-omap1/board-nokia770.c
+7
-12
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/board-osk.c
+6
-8
arch/arm/mach-omap1/board-palmte.c
arch/arm/mach-omap1/board-palmte.c
+3
-7
arch/arm/mach-omap1/board-palmtt.c
arch/arm/mach-omap1/board-palmtt.c
+3
-7
arch/arm/mach-omap1/board-palmz71.c
arch/arm/mach-omap1/board-palmz71.c
+3
-7
arch/arm/mach-omap1/board-perseus2.c
arch/arm/mach-omap1/board-perseus2.c
+3
-12
arch/arm/mach-omap1/board-sx1.c
arch/arm/mach-omap1/board-sx1.c
+3
-13
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/io.c
+0
-1
arch/arm/plat-omap/common.c
arch/arm/plat-omap/common.c
+0
-2
arch/arm/plat-omap/fb.c
arch/arm/plat-omap/fb.c
+9
-325
arch/arm/plat-omap/fb.h
arch/arm/plat-omap/fb.h
+0
-10
arch/arm/plat-omap/include/plat/blizzard.h
arch/arm/plat-omap/include/plat/blizzard.h
+0
-12
arch/arm/plat-omap/include/plat/board.h
arch/arm/plat-omap/include/plat/board.h
+0
-2
arch/arm/plat-omap/include/plat/hwa742.h
arch/arm/plat-omap/include/plat/hwa742.h
+0
-8
arch/arm/plat-omap/include/plat/vram.h
arch/arm/plat-omap/include/plat/vram.h
+1
-20
drivers/video/omap/Kconfig
drivers/video/omap/Kconfig
+4
-12
drivers/video/omap/Makefile
drivers/video/omap/Makefile
+3
-9
drivers/video/omap/blizzard.c
drivers/video/omap/blizzard.c
+0
-1648
drivers/video/omap/dispc.c
drivers/video/omap/dispc.c
+0
-1547
drivers/video/omap/dispc.h
drivers/video/omap/dispc.h
+0
-46
drivers/video/omap/hwa742.c
drivers/video/omap/hwa742.c
+5
-16
drivers/video/omap/omapfb.h
drivers/video/omap/omapfb.h
+21
-4
drivers/video/omap/omapfb_main.c
drivers/video/omap/omapfb_main.c
+2
-28
drivers/video/omap/rfbi.c
drivers/video/omap/rfbi.c
+0
-598
drivers/video/omap2/displays/panel-generic-dpi.c
drivers/video/omap2/displays/panel-generic-dpi.c
+23
-0
drivers/video/omap2/displays/panel-tpo-td043mtea1.c
drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+109
-44
drivers/video/omap2/dss/apply.c
drivers/video/omap2/dss/apply.c
+221
-54
drivers/video/omap2/dss/dispc.c
drivers/video/omap2/dss/dispc.c
+80
-41
drivers/video/omap2/dss/dispc_coefs.c
drivers/video/omap2/dss/dispc_coefs.c
+4
-5
drivers/video/omap2/dss/display.c
drivers/video/omap2/dss/display.c
+0
-10
drivers/video/omap2/dss/dsi.c
drivers/video/omap2/dss/dsi.c
+22
-43
drivers/video/omap2/dss/dss.c
drivers/video/omap2/dss/dss.c
+6
-11
drivers/video/omap2/dss/dss.h
drivers/video/omap2/dss/dss.h
+2
-8
drivers/video/omap2/dss/dss_features.c
drivers/video/omap2/dss/dss_features.c
+144
-37
drivers/video/omap2/dss/dss_features.h
drivers/video/omap2/dss/dss_features.h
+29
-25
drivers/video/omap2/dss/hdmi.c
drivers/video/omap2/dss/hdmi.c
+126
-152
drivers/video/omap2/dss/manager.c
drivers/video/omap2/dss/manager.c
+11
-1
drivers/video/omap2/dss/rfbi.c
drivers/video/omap2/dss/rfbi.c
+15
-21
drivers/video/omap2/dss/ti_hdmi.h
drivers/video/omap2/dss/ti_hdmi.h
+47
-9
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+43
-51
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
+0
-47
drivers/video/omap2/dss/venc.c
drivers/video/omap2/dss/venc.c
+19
-13
drivers/video/omap2/omapfb/omapfb-ioctl.c
drivers/video/omap2/omapfb/omapfb-ioctl.c
+1
-1
drivers/video/omap2/omapfb/omapfb-main.c
drivers/video/omap2/omapfb/omapfb-main.c
+2
-99
drivers/video/omap2/vram.c
drivers/video/omap2/vram.c
+5
-94
include/linux/omapfb.h
include/linux/omapfb.h
+1
-31
No files found.
arch/arm/mach-omap1/board-ams-delta.c
View file @
e9fe8a71
...
...
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/export.h>
#include <linux/omapfb.h>
#include <media/soc_camera.h>
...
...
@@ -169,10 +170,6 @@ static struct omap_usb_config ams_delta_usb_config __initdata = {
.
pins
[
0
]
=
2
,
};
static
struct
omap_board_config_kernel
ams_delta_config
[]
__initdata
=
{
{
OMAP_TAG_LCD
,
&
ams_delta_lcd_config
},
};
static
struct
resource
ams_delta_nand_resources
[]
=
{
[
0
]
=
{
.
start
=
OMAP1_MPUIO_BASE
,
...
...
@@ -302,8 +299,6 @@ static void __init ams_delta_init(void)
omap_cfg_reg
(
J19_1610_CAM_D6
);
omap_cfg_reg
(
J18_1610_CAM_D7
);
omap_board_config
=
ams_delta_config
;
omap_board_config_size
=
ARRAY_SIZE
(
ams_delta_config
);
omap_serial_init
();
omap_register_i2c_bus
(
1
,
100
,
NULL
,
0
);
...
...
@@ -321,6 +316,8 @@ static void __init ams_delta_init(void)
ams_delta_init_fiq
();
omap_writew
(
omap_readw
(
ARM_RSTCT1
)
|
0x0004
,
ARM_RSTCT1
);
omapfb_set_lcd_config
(
&
ams_delta_lcd_config
);
}
static
struct
plat_serial8250_port
ams_delta_modem_ports
[]
=
{
...
...
arch/arm/mach-omap1/board-fsample.c
View file @
e9fe8a71
...
...
@@ -21,6 +21,7 @@
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/smc91x.h>
#include <linux/omapfb.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
...
...
@@ -273,27 +274,17 @@ static struct platform_device kp_device = {
.
resource
=
kp_resources
,
};
static
struct
platform_device
lcd_device
=
{
.
name
=
"lcd_p2"
,
.
id
=
-
1
,
};
static
struct
platform_device
*
devices
[]
__initdata
=
{
&
nor_device
,
&
nand_device
,
&
smc91x_device
,
&
kp_device
,
&
lcd_device
,
};
static
struct
omap_lcd_config
fsample_lcd_config
=
{
.
ctrl_name
=
"internal"
,
};
static
struct
omap_board_config_kernel
fsample_config
[]
__initdata
=
{
{
OMAP_TAG_LCD
,
&
fsample_lcd_config
},
};
static
void
__init
omap_fsample_init
(
void
)
{
/* Early, board-dependent init */
...
...
@@ -352,10 +343,10 @@ static void __init omap_fsample_init(void)
platform_add_devices
(
devices
,
ARRAY_SIZE
(
devices
));
omap_board_config
=
fsample_config
;
omap_board_config_size
=
ARRAY_SIZE
(
fsample_config
);
omap_serial_init
();
omap_register_i2c_bus
(
1
,
100
,
NULL
,
0
);
omapfb_set_lcd_config
(
&
fsample_lcd_config
);
}
/* Only FPGA needs to be mapped here. All others are done with ioremap */
...
...
arch/arm/mach-omap1/board-h2.c
View file @
e9fe8a71
...
...
@@ -30,6 +30,7 @@
#include <linux/input.h>
#include <linux/i2c/tps65010.h>
#include <linux/smc91x.h>
#include <linux/omapfb.h>
#include <mach/hardware.h>
...
...
@@ -325,18 +326,12 @@ static struct platform_device h2_irda_device = {
.
resource
=
h2_irda_resources
,
};
static
struct
platform_device
h2_lcd_device
=
{
.
name
=
"lcd_h2"
,
.
id
=
-
1
,
};
static
struct
platform_device
*
h2_devices
[]
__initdata
=
{
&
h2_nor_device
,
&
h2_nand_device
,
&
h2_smc91x_device
,
&
h2_irda_device
,
&
h2_kp_device
,
&
h2_lcd_device
,
};
static
void
__init
h2_init_smc91x
(
void
)
...
...
@@ -391,10 +386,6 @@ static struct omap_lcd_config h2_lcd_config __initdata = {
.
ctrl_name
=
"internal"
,
};
static
struct
omap_board_config_kernel
h2_config
[]
__initdata
=
{
{
OMAP_TAG_LCD
,
&
h2_lcd_config
},
};
static
void
__init
h2_init
(
void
)
{
h2_init_smc91x
();
...
...
@@ -438,13 +429,13 @@ static void __init h2_init(void)
omap_cfg_reg
(
N19_1610_KBR5
);
platform_add_devices
(
h2_devices
,
ARRAY_SIZE
(
h2_devices
));
omap_board_config
=
h2_config
;
omap_board_config_size
=
ARRAY_SIZE
(
h2_config
);
omap_serial_init
();
omap_register_i2c_bus
(
1
,
100
,
h2_i2c_board_info
,
ARRAY_SIZE
(
h2_i2c_board_info
));
omap1_usb_init
(
&
h2_usb_config
);
h2_mmc_init
();
omapfb_set_lcd_config
(
&
h2_lcd_config
);
}
MACHINE_START
(
OMAP_H2
,
"TI-H2"
)
...
...
arch/arm/mach-omap1/board-h3.c
View file @
e9fe8a71
...
...
@@ -30,6 +30,7 @@
#include <linux/spi/spi.h>
#include <linux/i2c/tps65010.h>
#include <linux/smc91x.h>
#include <linux/omapfb.h>
#include <asm/setup.h>
#include <asm/page.h>
...
...
@@ -370,10 +371,6 @@ static struct omap_lcd_config h3_lcd_config __initdata = {
.
ctrl_name
=
"internal"
,
};
static
struct
omap_board_config_kernel
h3_config
[]
__initdata
=
{
{
OMAP_TAG_LCD
,
&
h3_lcd_config
},
};
static
struct
i2c_board_info
__initdata
h3_i2c_board_info
[]
=
{
{
I2C_BOARD_INFO
(
"tps65013"
,
0x48
),
...
...
@@ -426,13 +423,13 @@ static void __init h3_init(void)
platform_add_devices
(
devices
,
ARRAY_SIZE
(
devices
));
spi_register_board_info
(
h3_spi_board_info
,
ARRAY_SIZE
(
h3_spi_board_info
));
omap_board_config
=
h3_config
;
omap_board_config_size
=
ARRAY_SIZE
(
h3_config
);
omap_serial_init
();
omap_register_i2c_bus
(
1
,
100
,
h3_i2c_board_info
,
ARRAY_SIZE
(
h3_i2c_board_info
));
omap1_usb_init
(
&
h3_usb_config
);
h3_mmc_init
();
omapfb_set_lcd_config
(
&
h3_lcd_config
);
}
MACHINE_START
(
OMAP_H3
,
"TI OMAP1710 H3 board"
)
...
...
arch/arm/mach-omap1/board-htcherald.c
View file @
e9fe8a71
...
...
@@ -36,6 +36,7 @@
#include <linux/leds.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/omapfb.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
...
...
@@ -398,10 +399,6 @@ static struct omap_lcd_config htcherald_lcd_config __initdata = {
.
ctrl_name
=
"internal"
,
};
static
struct
omap_board_config_kernel
htcherald_config
[]
__initdata
=
{
{
OMAP_TAG_LCD
,
&
htcherald_lcd_config
},
};
static
struct
platform_device
lcd_device
=
{
.
name
=
"lcd_htcherald"
,
.
id
=
-
1
,
...
...
@@ -580,8 +577,6 @@ static void __init htcherald_init(void)
printk
(
KERN_INFO
"HTC Herald init.
\n
"
);
/* Do board initialization before we register all the devices */
omap_board_config
=
htcherald_config
;
omap_board_config_size
=
ARRAY_SIZE
(
htcherald_config
);
platform_add_devices
(
devices
,
ARRAY_SIZE
(
devices
));
htcherald_disable_watchdog
();
...
...
@@ -598,6 +593,8 @@ static void __init htcherald_init(void)
htc_mmc_data
[
0
]
=
&
htc_mmc1_data
;
omap1_init_mmc
(
htc_mmc_data
,
1
);
#endif
omapfb_set_lcd_config
(
&
htcherald_lcd_config
);
}
MACHINE_START
(
HERALD
,
"HTC Herald"
)
...
...
arch/arm/mach-omap1/board-innovator.c
View file @
e9fe8a71
...
...
@@ -25,6 +25,7 @@
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/smc91x.h>
#include <linux/omapfb.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
...
...
@@ -370,10 +371,6 @@ static inline void innovator_mmc_init(void)
}
#endif
static
struct
omap_board_config_kernel
innovator_config
[]
=
{
{
OMAP_TAG_LCD
,
NULL
},
};
static
void
__init
innovator_init
(
void
)
{
if
(
cpu_is_omap1510
())
...
...
@@ -416,17 +413,15 @@ static void __init innovator_init(void)
#ifdef CONFIG_ARCH_OMAP15XX
if
(
cpu_is_omap1510
())
{
omap1_usb_init
(
&
innovator1510_usb_config
);
innovator_config
[
0
].
data
=
&
innovator1510_lcd_config
;
omapfb_set_lcd_config
(
&
innovator1510_lcd_config
)
;
}
#endif
#ifdef CONFIG_ARCH_OMAP16XX
if
(
cpu_is_omap1610
())
{
omap1_usb_init
(
&
h2_usb_config
);
innovator_config
[
0
].
data
=
&
innovator1610_lcd_config
;
omapfb_set_lcd_config
(
&
innovator1610_lcd_config
)
;
}
#endif
omap_board_config
=
innovator_config
;
omap_board_config_size
=
ARRAY_SIZE
(
innovator_config
);
omap_serial_init
();
omap_register_i2c_bus
(
1
,
100
,
NULL
,
0
);
innovator_mmc_init
();
...
...
arch/arm/mach-omap1/board-nokia770.c
View file @
e9fe8a71
...
...
@@ -31,7 +31,6 @@
#include <plat/board.h>
#include <plat/keypad.h>
#include "common.h"
#include <plat/hwa742.h>
#include <plat/lcd_mipid.h>
#include <plat/mmc.h>
#include <plat/clock.h>
...
...
@@ -99,15 +98,16 @@ static struct mipid_platform_data nokia770_mipid_platform_data = {
.
shutdown
=
mipid_shutdown
,
};
static
struct
omap_lcd_config
nokia770_lcd_config
__initdata
=
{
.
ctrl_name
=
"hwa742"
,
};
static
void
__init
mipid_dev_init
(
void
)
{
const
struct
omap_lcd_config
*
conf
;
nokia770_mipid_platform_data
.
nreset_gpio
=
13
;
nokia770_mipid_platform_data
.
data_lines
=
16
;
conf
=
omap_get_config
(
OMAP_TAG_LCD
,
struct
omap_lcd_config
);
if
(
conf
!=
NULL
)
{
nokia770_mipid_platform_data
.
nreset_gpio
=
conf
->
nreset_gpio
;
nokia770_mipid_platform_data
.
data_lines
=
conf
->
data_lines
;
}
omapfb_set_lcd_config
(
&
nokia770_lcd_config
);
}
static
void
__init
ads7846_dev_init
(
void
)
...
...
@@ -150,14 +150,9 @@ static struct spi_board_info nokia770_spi_board_info[] __initdata = {
},
};
static
struct
hwa742_platform_data
nokia770_hwa742_platform_data
=
{
.
te_connected
=
1
,
};
static
void
__init
hwa742_dev_init
(
void
)
{
clk_add_alias
(
"hwa_sys_ck"
,
NULL
,
"bclk"
,
NULL
);
omapfb_set_ctrl_platform_data
(
&
nokia770_hwa742_platform_data
);
}
/* assume no Mini-AB port */
...
...
arch/arm/mach-omap1/board-osk.c
View file @
e9fe8a71
...
...
@@ -34,6 +34,7 @@
#include <linux/i2c.h>
#include <linux/leds.h>
#include <linux/smc91x.h>
#include <linux/omapfb.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
...
...
@@ -300,12 +301,6 @@ static struct omap_lcd_config osk_lcd_config __initdata = {
};
#endif
static
struct
omap_board_config_kernel
osk_config
[]
__initdata
=
{
#ifdef CONFIG_OMAP_OSK_MISTRAL
{
OMAP_TAG_LCD
,
&
osk_lcd_config
},
#endif
};
#ifdef CONFIG_OMAP_OSK_MISTRAL
#include <linux/input.h>
...
...
@@ -549,8 +544,6 @@ static void __init osk_init(void)
osk_flash_resource
.
end
=
osk_flash_resource
.
start
=
omap_cs3_phys
();
osk_flash_resource
.
end
+=
SZ_32M
-
1
;
platform_add_devices
(
osk5912_devices
,
ARRAY_SIZE
(
osk5912_devices
));
omap_board_config
=
osk_config
;
omap_board_config_size
=
ARRAY_SIZE
(
osk_config
);
l
=
omap_readl
(
USB_TRANSCEIVER_CTRL
);
l
|=
(
3
<<
1
);
...
...
@@ -567,6 +560,11 @@ static void __init osk_init(void)
omap_register_i2c_bus
(
1
,
400
,
osk_i2c_board_info
,
ARRAY_SIZE
(
osk_i2c_board_info
));
osk_mistral_init
();
#ifdef CONFIG_OMAP_OSK_MISTRAL
omapfb_set_lcd_config
(
&
osk_lcd_config
);
#endif
}
MACHINE_START
(
OMAP_OSK
,
"TI-OSK"
)
...
...
arch/arm/mach-omap1/board-palmte.c
View file @
e9fe8a71
...
...
@@ -27,6 +27,7 @@
#include <linux/spi/spi.h>
#include <linux/interrupt.h>
#include <linux/apm-emulation.h>
#include <linux/omapfb.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
...
...
@@ -209,10 +210,6 @@ static struct omap_lcd_config palmte_lcd_config __initdata = {
.
ctrl_name
=
"internal"
,
};
static
struct
omap_board_config_kernel
palmte_config
[]
__initdata
=
{
{
OMAP_TAG_LCD
,
&
palmte_lcd_config
},
};
static
struct
spi_board_info
palmte_spi_info
[]
__initdata
=
{
{
.
modalias
=
"tsc2102"
,
...
...
@@ -250,9 +247,6 @@ static void __init omap_palmte_init(void)
omap_cfg_reg
(
UART3_TX
);
omap_cfg_reg
(
UART3_RX
);
omap_board_config
=
palmte_config
;
omap_board_config_size
=
ARRAY_SIZE
(
palmte_config
);
platform_add_devices
(
palmte_devices
,
ARRAY_SIZE
(
palmte_devices
));
spi_register_board_info
(
palmte_spi_info
,
ARRAY_SIZE
(
palmte_spi_info
));
...
...
@@ -260,6 +254,8 @@ static void __init omap_palmte_init(void)
omap_serial_init
();
omap1_usb_init
(
&
palmte_usb_config
);
omap_register_i2c_bus
(
1
,
100
,
NULL
,
0
);
omapfb_set_lcd_config
(
&
palmte_lcd_config
);
}
MACHINE_START
(
OMAP_PALMTE
,
"OMAP310 based Palm Tungsten E"
)
...
...
arch/arm/mach-omap1/board-palmtt.c
View file @
e9fe8a71
...
...
@@ -24,6 +24,7 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/leds.h>
#include <linux/omapfb.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
...
...
@@ -273,10 +274,6 @@ static struct omap_lcd_config palmtt_lcd_config __initdata = {
.
ctrl_name
=
"internal"
,
};
static
struct
omap_board_config_kernel
palmtt_config
[]
__initdata
=
{
{
OMAP_TAG_LCD
,
&
palmtt_lcd_config
},
};
static
void
__init
omap_mpu_wdt_mode
(
int
mode
)
{
if
(
mode
)
omap_writew
(
0x8000
,
OMAP_WDT_TIMER_MODE
);
...
...
@@ -298,15 +295,14 @@ static void __init omap_palmtt_init(void)
omap_mpu_wdt_mode
(
0
);
omap_board_config
=
palmtt_config
;
omap_board_config_size
=
ARRAY_SIZE
(
palmtt_config
);
platform_add_devices
(
palmtt_devices
,
ARRAY_SIZE
(
palmtt_devices
));
spi_register_board_info
(
palmtt_boardinfo
,
ARRAY_SIZE
(
palmtt_boardinfo
));
omap_serial_init
();
omap1_usb_init
(
&
palmtt_usb_config
);
omap_register_i2c_bus
(
1
,
100
,
NULL
,
0
);
omapfb_set_lcd_config
(
&
palmtt_lcd_config
);
}
MACHINE_START
(
OMAP_PALMTT
,
"OMAP1510 based Palm Tungsten|T"
)
...
...
arch/arm/mach-omap1/board-palmz71.c
View file @
e9fe8a71
...
...
@@ -27,6 +27,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/omapfb.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
...
...
@@ -239,10 +240,6 @@ static struct omap_lcd_config palmz71_lcd_config __initdata = {
.
ctrl_name
=
"internal"
,
};
static
struct
omap_board_config_kernel
palmz71_config
[]
__initdata
=
{
{
OMAP_TAG_LCD
,
&
palmz71_lcd_config
},
};
static
irqreturn_t
palmz71_powercable
(
int
irq
,
void
*
dev_id
)
{
...
...
@@ -313,9 +310,6 @@ omap_palmz71_init(void)
palmz71_gpio_setup
(
1
);
omap_mpu_wdt_mode
(
0
);
omap_board_config
=
palmz71_config
;
omap_board_config_size
=
ARRAY_SIZE
(
palmz71_config
);
platform_add_devices
(
devices
,
ARRAY_SIZE
(
devices
));
spi_register_board_info
(
palmz71_boardinfo
,
...
...
@@ -324,6 +318,8 @@ omap_palmz71_init(void)
omap_serial_init
();
omap_register_i2c_bus
(
1
,
100
,
NULL
,
0
);
palmz71_gpio_setup
(
0
);
omapfb_set_lcd_config
(
&
palmz71_lcd_config
);
}
MACHINE_START
(
OMAP_PALMZ71
,
"OMAP310 based Palm Zire71"
)
...
...
arch/arm/mach-omap1/board-perseus2.c
View file @
e9fe8a71
...
...
@@ -21,6 +21,7 @@
#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/smc91x.h>
#include <linux/omapfb.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
...
...
@@ -232,27 +233,17 @@ static struct platform_device kp_device = {
.
resource
=
kp_resources
,
};
static
struct
platform_device
lcd_device
=
{
.
name
=
"lcd_p2"
,
.
id
=
-
1
,
};
static
struct
platform_device
*
devices
[]
__initdata
=
{
&
nor_device
,
&
nand_device
,
&
smc91x_device
,
&
kp_device
,
&
lcd_device
,
};
static
struct
omap_lcd_config
perseus2_lcd_config
__initdata
=
{
.
ctrl_name
=
"internal"
,
};
static
struct
omap_board_config_kernel
perseus2_config
[]
__initdata
=
{
{
OMAP_TAG_LCD
,
&
perseus2_lcd_config
},
};
static
void
__init
perseus2_init_smc91x
(
void
)
{
fpga_write
(
1
,
H2P2_DBG_FPGA_LAN_RESET
);
...
...
@@ -320,10 +311,10 @@ static void __init omap_perseus2_init(void)
platform_add_devices
(
devices
,
ARRAY_SIZE
(
devices
));
omap_board_config
=
perseus2_config
;
omap_board_config_size
=
ARRAY_SIZE
(
perseus2_config
);
omap_serial_init
();
omap_register_i2c_bus
(
1
,
100
,
NULL
,
0
);
omapfb_set_lcd_config
(
&
perseus2_lcd_config
);
}
/* Only FPGA needs to be mapped here. All others are done with ioremap */
...
...
arch/arm/mach-omap1/board-sx1.c
View file @
e9fe8a71
...
...
@@ -27,6 +27,7 @@
#include <linux/i2c.h>
#include <linux/errno.h>
#include <linux/export.h>
#include <linux/omapfb.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
...
...
@@ -355,11 +356,6 @@ static struct omap_usb_config sx1_usb_config __initdata = {
/*----------- LCD -------------------------*/
static
struct
platform_device
sx1_lcd_device
=
{
.
name
=
"lcd_sx1"
,
.
id
=
-
1
,
};
static
struct
omap_lcd_config
sx1_lcd_config
__initdata
=
{
.
ctrl_name
=
"internal"
,
};
...
...
@@ -368,14 +364,8 @@ static struct omap_lcd_config sx1_lcd_config __initdata = {
static
struct
platform_device
*
sx1_devices
[]
__initdata
=
{
&
sx1_flash_device
,
&
sx1_kp_device
,
&
sx1_lcd_device
,
&
sx1_irda_device
,
};
/*-----------------------------------------*/
static
struct
omap_board_config_kernel
sx1_config
[]
__initdata
=
{
{
OMAP_TAG_LCD
,
&
sx1_lcd_config
},
};
/*-----------------------------------------*/
...
...
@@ -391,8 +381,6 @@ static void __init omap_sx1_init(void)
platform_add_devices
(
sx1_devices
,
ARRAY_SIZE
(
sx1_devices
));
omap_board_config
=
sx1_config
;
omap_board_config_size
=
ARRAY_SIZE
(
sx1_config
);
omap_serial_init
();
omap_register_i2c_bus
(
1
,
100
,
NULL
,
0
);
omap1_usb_init
(
&
sx1_usb_config
);
...
...
@@ -406,6 +394,8 @@ static void __init omap_sx1_init(void)
gpio_direction_output
(
1
,
1
);
/*A_IRDA_OFF = 1 */
gpio_direction_output
(
11
,
0
);
/*A_SWITCH = 0 */
gpio_direction_output
(
15
,
0
);
/*A_USB_ON = 0 */
omapfb_set_lcd_config
(
&
sx1_lcd_config
);
}
MACHINE_START
(
SX1
,
"OMAP310 based Siemens SX1"
)
...
...
arch/arm/mach-omap2/io.c
View file @
e9fe8a71
...
...
@@ -21,7 +21,6 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/omapfb.h>
#include <asm/tlb.h>
...
...
arch/arm/plat-omap/common.c
View file @
e9fe8a71
...
...
@@ -15,7 +15,6 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/omapfb.h>
#include <plat/common.h>
#include <plat/board.h>
...
...
@@ -65,7 +64,6 @@ const void *__init omap_get_var_config(u16 tag, size_t *len)
void
__init
omap_reserve
(
void
)
{
omapfb_reserve_sdram_memblock
();
omap_vram_reserve_sdram_memblock
();
omap_dsp_reserve_sdram_memblock
();
omap_secure_ram_reserve_memblock
();
...
...
arch/arm/plat-omap/fb.c
View file @
e9fe8a71
...
...
@@ -34,15 +34,11 @@
#include <asm/mach/map.h>
#include <plat/board.h>
#include <plat/sram.h>
#include "fb.h"
#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
static
bool
omapfb_lcd_configured
;
static
struct
omapfb_platform_data
omapfb_config
;
static
int
config_invalid
;
static
int
configured_regions
;
static
u64
omap_fb_dma_mask
=
~
(
u32
)
0
;
...
...
@@ -57,302 +53,21 @@ 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
)
{
return
(
start1
>=
start2
&&
start1
<
start2
+
size2
)
||
(
start2
>=
start1
&&
start2
<
start1
+
size1
);
}
static
inline
int
range_included
(
unsigned
long
start1
,
unsigned
long
size1
,
unsigned
long
start2
,
unsigned
long
size2
)
{
return
start1
>=
start2
&&
start1
+
size1
<=
start2
+
size2
;
}
/* Check if there is an overlapping region. */
static
int
fbmem_region_reserved
(
unsigned
long
start
,
size_t
size
)
{
struct
omapfb_mem_region
*
rg
;
int
i
;
rg
=
&
omapfb_config
.
mem_desc
.
region
[
0
];
for
(
i
=
0
;
i
<
OMAPFB_PLANE_NUM
;
i
++
,
rg
++
)
{
if
(
!
rg
->
paddr
)
/* Empty slot. */
continue
;
if
(
ranges_overlap
(
start
,
size
,
rg
->
paddr
,
rg
->
size
))
return
1
;
}
return
0
;
}
/*
* Get the region_idx`th region from board config/ATAG and convert it to
* our internal format.
*/
static
int
__init
get_fbmem_region
(
int
region_idx
,
struct
omapfb_mem_region
*
rg
)
void
__init
omapfb_set_lcd_config
(
const
struct
omap_lcd_config
*
config
)
{
const
struct
omap_fbmem_config
*
conf
;
u32
paddr
;
conf
=
omap_get_nr_config
(
OMAP_TAG_FBMEM
,
struct
omap_fbmem_config
,
region_idx
);
if
(
conf
==
NULL
)
return
-
ENOENT
;
paddr
=
conf
->
start
;
/*
* Low bits encode the page allocation mode, if high bits
* are zero. Otherwise we need a page aligned fixed
* address.
*/
memset
(
rg
,
0
,
sizeof
(
*
rg
));
rg
->
type
=
paddr
&
~
PAGE_MASK
;
rg
->
paddr
=
paddr
&
PAGE_MASK
;
rg
->
size
=
PAGE_ALIGN
(
conf
->
size
);
return
0
;
omapfb_config
.
lcd
=
*
config
;
omapfb_lcd_configured
=
true
;
}
static
int
set_fbmem_region_type
(
struct
omapfb_mem_region
*
rg
,
int
mem_type
,
unsigned
long
mem_start
,
unsigned
long
mem_size
)
{
/*
* Check if the configuration specifies the type explicitly.
* type = 0 && paddr = 0, a default don't care case maps to
* the SDRAM type.
*/
if
(
rg
->
type
||
!
rg
->
paddr
)
return
0
;
if
(
ranges_overlap
(
rg
->
paddr
,
rg
->
size
,
mem_start
,
mem_size
))
{
rg
->
type
=
mem_type
;
return
0
;
}
/* Can't determine it. */
return
-
1
;
}
static
int
check_fbmem_region
(
int
region_idx
,
struct
omapfb_mem_region
*
rg
,
unsigned
long
start_avail
,
unsigned
size_avail
)
static
int
__init
omap_init_fb
(
void
)
{
unsigned
long
paddr
=
rg
->
paddr
;
size_t
size
=
rg
->
size
;
if
(
rg
->
type
>
OMAPFB_MEMTYPE_MAX
)
{
printk
(
KERN_ERR
"Invalid start address for FB region %d
\n
"
,
region_idx
);
return
-
EINVAL
;
}
if
(
!
rg
->
size
)
{
printk
(
KERN_ERR
"Zero size for FB region %d
\n
"
,
region_idx
);
return
-
EINVAL
;
}
if
(
!
paddr
)
/* Allocate this dynamically, leave paddr 0 for now. */
return
0
;
/*
*
Fixed region for the given RAM range. Check if it's already
*
reserved by the FB code or someone else.
*
If the board file has not set the lcd config with
*
omapfb_set_lcd_config(), don't bother registering the omapfb device
*/
if
(
fbmem_region_reserved
(
paddr
,
size
)
||
!
range_included
(
paddr
,
size
,
start_avail
,
size_avail
))
{
printk
(
KERN_ERR
"Trying to use reserved memory "
"for FB region %d
\n
"
,
region_idx
);
return
-
EINVAL
;
}
return
0
;
}
static
int
valid_sdram
(
unsigned
long
addr
,
unsigned
long
size
)
{
return
memblock_is_region_memory
(
addr
,
size
);
}
static
int
reserve_sdram
(
unsigned
long
addr
,
unsigned
long
size
)
{
if
(
memblock_is_region_reserved
(
addr
,
size
))
return
-
EBUSY
;
if
(
memblock_reserve
(
addr
,
size
))
return
-
ENOMEM
;
return
0
;
}
/*
* Called from map_io. We need to call to this early enough so that we
* can reserve the fixed SDRAM regions before VM could get hold of them.
*/
void
__init
omapfb_reserve_sdram_memblock
(
void
)
{
unsigned
long
reserved
=
0
;
int
i
;
if
(
config_invalid
)
return
;
for
(
i
=
0
;
;
i
++
)
{
struct
omapfb_mem_region
rg
;
if
(
get_fbmem_region
(
i
,
&
rg
)
<
0
)
break
;
if
(
i
==
OMAPFB_PLANE_NUM
)
{
pr_err
(
"Extraneous FB mem configuration entries
\n
"
);
config_invalid
=
1
;
return
;
}
/* Check if it's our memory type. */
if
(
rg
.
type
!=
OMAPFB_MEMTYPE_SDRAM
)
continue
;
/* Check if the region falls within SDRAM */
if
(
rg
.
paddr
&&
!
valid_sdram
(
rg
.
paddr
,
rg
.
size
))
continue
;
if
(
rg
.
size
==
0
)
{
pr_err
(
"Zero size for FB region %d
\n
"
,
i
);
config_invalid
=
1
;
return
;
}
if
(
rg
.
paddr
)
{
if
(
reserve_sdram
(
rg
.
paddr
,
rg
.
size
))
{
pr_err
(
"Trying to use reserved memory for FB region %d
\n
"
,
i
);
config_invalid
=
1
;
return
;
}
reserved
+=
rg
.
size
;
}
if
(
omapfb_config
.
mem_desc
.
region
[
i
].
size
)
{
pr_err
(
"FB region %d already set
\n
"
,
i
);
config_invalid
=
1
;
return
;
}
omapfb_config
.
mem_desc
.
region
[
i
]
=
rg
;
configured_regions
++
;
}
omapfb_config
.
mem_desc
.
region_cnt
=
i
;
if
(
reserved
)
pr_info
(
"Reserving %lu bytes SDRAM for frame buffer
\n
"
,
reserved
);
}
/*
* Called at sram init time, before anything is pushed to the SRAM stack.
* Because of the stack scheme, we will allocate everything from the
* start of the lowest address region to the end of SRAM. This will also
* include padding for page alignment and possible holes between regions.
*
* As opposed to the SDRAM case, we'll also do any dynamic allocations at
* this point, since the driver built as a module would have problem with
* freeing / reallocating the regions.
*/
unsigned
long
__init
omapfb_reserve_sram
(
unsigned
long
sram_pstart
,
unsigned
long
sram_vstart
,
unsigned
long
sram_size
,
unsigned
long
pstart_avail
,
unsigned
long
size_avail
)
{
struct
omapfb_mem_region
rg
;
unsigned
long
pend_avail
;
unsigned
long
reserved
;
int
i
;
if
(
config_invalid
)
if
(
!
omapfb_lcd_configured
)
return
0
;
reserved
=
0
;
pend_avail
=
pstart_avail
+
size_avail
;
for
(
i
=
0
;
;
i
++
)
{
if
(
get_fbmem_region
(
i
,
&
rg
)
<
0
)
break
;
if
(
i
==
OMAPFB_PLANE_NUM
)
{
printk
(
KERN_ERR
"Extraneous FB mem configuration entries
\n
"
);
config_invalid
=
1
;
return
0
;
}
/* Check if it's our memory type. */
if
(
set_fbmem_region_type
(
&
rg
,
OMAPFB_MEMTYPE_SRAM
,
sram_pstart
,
sram_size
)
<
0
||
(
rg
.
type
!=
OMAPFB_MEMTYPE_SRAM
))
continue
;
BUG_ON
(
omapfb_config
.
mem_desc
.
region
[
i
].
size
);
if
(
check_fbmem_region
(
i
,
&
rg
,
pstart_avail
,
size_avail
)
<
0
)
{
config_invalid
=
1
;
return
0
;
}
if
(
!
rg
.
paddr
)
{
/* Dynamic allocation */
if
((
size_avail
&
PAGE_MASK
)
<
rg
.
size
)
{
printk
(
"Not enough SRAM for FB region %d
\n
"
,
i
);
config_invalid
=
1
;
return
0
;
}
size_avail
=
(
size_avail
-
rg
.
size
)
&
PAGE_MASK
;
rg
.
paddr
=
pstart_avail
+
size_avail
;
}
/* Reserve everything above the start of the region. */
if
(
pend_avail
-
rg
.
paddr
>
reserved
)
reserved
=
pend_avail
-
rg
.
paddr
;
size_avail
=
pend_avail
-
reserved
-
pstart_avail
;
/*
* We have a kernel mapping for this already, so the
* driver won't have to make one.
*/
rg
.
vaddr
=
(
void
*
)(
sram_vstart
+
rg
.
paddr
-
sram_pstart
);
omapfb_config
.
mem_desc
.
region
[
i
]
=
rg
;
configured_regions
++
;
}
omapfb_config
.
mem_desc
.
region_cnt
=
i
;
if
(
reserved
)
pr_info
(
"Reserving %lu bytes SRAM for frame buffer
\n
"
,
reserved
);
return
reserved
;
}
void
omapfb_set_ctrl_platform_data
(
void
*
data
)
{
omapfb_config
.
ctrl_platform_data
=
data
;
}
static
int
__init
omap_init_fb
(
void
)
{
const
struct
omap_lcd_config
*
conf
;
if
(
config_invalid
)
return
0
;
if
(
configured_regions
!=
omapfb_config
.
mem_desc
.
region_cnt
)
{
printk
(
KERN_ERR
"Invalid FB mem configuration entries
\n
"
);
return
0
;
}
conf
=
omap_get_config
(
OMAP_TAG_LCD
,
struct
omap_lcd_config
);
if
(
conf
==
NULL
)
{
if
(
configured_regions
)
/* FB mem config, but no LCD config? */
printk
(
KERN_ERR
"Missing LCD configuration
\n
"
);
return
0
;
}
omapfb_config
.
lcd
=
*
conf
;
return
platform_device_register
(
&
omap_fb_device
);
}
...
...
@@ -374,11 +89,6 @@ static struct platform_device omap_fb_device = {
.
num_resources
=
0
,
};
void
omapfb_set_platform_data
(
struct
omapfb_platform_data
*
data
)
{
omapfb_config
=
*
data
;
}
static
int
__init
omap_init_fb
(
void
)
{
return
platform_device_register
(
&
omap_fb_device
);
...
...
@@ -386,36 +96,10 @@ static int __init omap_init_fb(void)
arch_initcall
(
omap_init_fb
);
void
omapfb_reserve_sdram_memblock
(
void
)
{
}
unsigned
long
__init
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
;
}
#else
void
omapfb_set_platform_data
(
struct
omapfb_platform_data
*
data
)
{
}
void
omapfb_reserve_sdram_memblock
(
void
)
{
}
unsigned
long
__init
omapfb_reserve_sram
(
unsigned
long
sram_pstart
,
unsigned
long
sram_vstart
,
unsigned
long
sram_size
,
unsigned
long
start_avail
,
unsigned
long
size_avail
)
void
__init
omapfb_set_lcd_config
(
const
struct
omap_lcd_config
*
config
)
{
return
0
;
}
#endif
arch/arm/plat-omap/fb.h
deleted
100644 → 0
View file @
f413070e
#ifndef __PLAT_OMAP_FB_H__
#define __PLAT_OMAP_FB_H__
extern
unsigned
long
omapfb_reserve_sram
(
unsigned
long
sram_pstart
,
unsigned
long
sram_vstart
,
unsigned
long
sram_size
,
unsigned
long
pstart_avail
,
unsigned
long
size_avail
);
#endif
/* __PLAT_OMAP_FB_H__ */
arch/arm/plat-omap/include/plat/blizzard.h
deleted
100644 → 0
View file @
f413070e
#ifndef _BLIZZARD_H
#define _BLIZZARD_H
struct
blizzard_platform_data
{
void
(
*
power_up
)(
struct
device
*
dev
);
void
(
*
power_down
)(
struct
device
*
dev
);
unsigned
long
(
*
get_clock_rate
)(
struct
device
*
dev
);
unsigned
te_connected
:
1
;
};
#endif
arch/arm/plat-omap/include/plat/board.h
View file @
e9fe8a71
...
...
@@ -28,9 +28,7 @@ enum {
/* Different peripheral ids */
#define OMAP_TAG_CLOCK 0x4f01
#define OMAP_TAG_LCD 0x4f05
#define OMAP_TAG_GPIO_SWITCH 0x4f06
#define OMAP_TAG_FBMEM 0x4f08
#define OMAP_TAG_STI_CONSOLE 0x4f09
#define OMAP_TAG_CAMERA_SENSOR 0x4f0a
...
...
arch/arm/plat-omap/include/plat/hwa742.h
deleted
100644 → 0
View file @
f413070e
#ifndef _HWA742_H
#define _HWA742_H
struct
hwa742_platform_data
{
unsigned
te_connected
:
1
;
};
#endif
arch/arm/plat-omap/include/plat/vram.h
View file @
e9fe8a71
...
...
@@ -23,40 +23,21 @@
#include <linux/types.h>
#define OMAP_VRAM_MEMTYPE_SDRAM 0
#define OMAP_VRAM_MEMTYPE_SRAM 1
#define OMAP_VRAM_MEMTYPE_MAX 1
extern
int
omap_vram_add_region
(
unsigned
long
paddr
,
size_t
size
);
extern
int
omap_vram_free
(
unsigned
long
paddr
,
size_t
size
);
extern
int
omap_vram_alloc
(
int
mtype
,
size_t
size
,
unsigned
long
*
paddr
);
extern
int
omap_vram_alloc
(
size_t
size
,
unsigned
long
*
paddr
);
extern
int
omap_vram_reserve
(
unsigned
long
paddr
,
size_t
size
);
extern
void
omap_vram_get_info
(
unsigned
long
*
vram
,
unsigned
long
*
free_vram
,
unsigned
long
*
largest_free_block
);
#ifdef CONFIG_OMAP2_VRAM
extern
void
omap_vram_set_sdram_vram
(
u32
size
,
u32
start
);
extern
void
omap_vram_set_sram_vram
(
u32
size
,
u32
start
);
extern
void
omap_vram_reserve_sdram_memblock
(
void
);
extern
unsigned
long
omap_vram_reserve_sram
(
unsigned
long
sram_pstart
,
unsigned
long
sram_vstart
,
unsigned
long
sram_size
,
unsigned
long
pstart_avail
,
unsigned
long
size_avail
);
#else
static
inline
void
omap_vram_set_sdram_vram
(
u32
size
,
u32
start
)
{
}
static
inline
void
omap_vram_set_sram_vram
(
u32
size
,
u32
start
)
{
}
static
inline
void
omap_vram_reserve_sdram_memblock
(
void
)
{
}
static
inline
unsigned
long
omap_vram_reserve_sram
(
unsigned
long
sram_pstart
,
unsigned
long
sram_vstart
,
unsigned
long
sram_size
,
unsigned
long
pstart_avail
,
unsigned
long
size_avail
)
{
return
0
;
}
#endif
#endif
drivers/video/omap/Kconfig
View file @
e9fe8a71
config FB_OMAP
tristate "OMAP frame buffer support (EXPERIMENTAL)"
depends on FB
&& (OMAP2_DSS = "n")
depends on ARCH_OMAP1
|| ARCH_OMAP2 || ARCH_OMAP3
depends on FB
depends on ARCH_OMAP1
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select TWL4030_CORE if MACH_OMAP_2430SDP
help
Frame buffer driver for OMAP based boards.
...
...
@@ -23,13 +22,6 @@ config FB_OMAP_LCDC_HWA742
Say Y here if you want to have support for the external
Epson HWA742 LCD controller.
config FB_OMAP_LCDC_BLIZZARD
bool "Epson Blizzard LCD controller support"
depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
help
Say Y here if you want to have support for the external
Epson Blizzard LCD controller.
config FB_OMAP_MANUAL_UPDATE
bool "Default to manual update mode"
depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
...
...
@@ -49,7 +41,7 @@ config FB_OMAP_LCD_MIPID
config FB_OMAP_BOOTLOADER_INIT
bool "Check bootloader initialization"
depends on FB_OMAP
|| FB_OMAP2
depends on FB_OMAP
help
Say Y here if you want to enable checking if the bootloader has
already initialized the display controller. In this case the
...
...
@@ -68,7 +60,7 @@ config FB_OMAP_CONSISTENT_DMA_SIZE
config FB_OMAP_DMA_TUNE
bool "Set DMA SDRAM access priority high"
depends on FB_OMAP
&& ARCH_OMAP1
depends on FB_OMAP
help
On systems in which video memory is in system memory
(SDRAM) this will speed up graphics DMA operations.
...
...
drivers/video/omap/Makefile
View file @
e9fe8a71
#
# Makefile for the
new OMAP
framebuffer device driver
# Makefile for the
OMAP1
framebuffer device driver
#
obj-$(CONFIG_FB_OMAP)
+=
omapfb.o
objs-yy
:=
omapfb_main.o
objs-yy
:=
omapfb_main.o
lcdc.o
objs-y$(CONFIG_ARCH_OMAP1)
+=
lcdc.o
objs-y$(CONFIG_ARCH_OMAP2)
+=
dispc.o
objs-y$(CONFIG_ARCH_OMAP3)
+=
dispc.o
objs-$(CONFIG_ARCH_OMAP1)$(CONFIG_FB_OMAP_LCDC_EXTERNAL)
+=
sossi.o
objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL)
+=
rfbi.o
objs-y$(CONFIG_FB_OMAP_LCDC_EXTERNAL)
+=
sossi.o
objs-y$(CONFIG_FB_OMAP_LCDC_HWA742)
+=
hwa742.o
objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD)
+=
blizzard.o
objs-y$(CONFIG_MACH_AMS_DELTA)
+=
lcd_ams_delta.o
objs-y$(CONFIG_MACH_OMAP_H3)
+=
lcd_h3.o
...
...
drivers/video/omap/blizzard.c
deleted
100644 → 0
View file @
f413070e
/*
* Epson Blizzard LCD controller driver
*
* Copyright (C) 2004-2005 Nokia Corporation
* Authors: Juha Yrjola <juha.yrjola@nokia.com>
* Imre Deak <imre.deak@nokia.com>
* YUV support: Jussi Laako <jussi.laako@nokia.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* 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, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <plat/dma.h>
#include <plat/blizzard.h>
#include "omapfb.h"
#include "dispc.h"
#define MODULE_NAME "blizzard"
#define BLIZZARD_REV_CODE 0x00
#define BLIZZARD_CONFIG 0x02
#define BLIZZARD_PLL_DIV 0x04
#define BLIZZARD_PLL_LOCK_RANGE 0x06
#define BLIZZARD_PLL_CLOCK_SYNTH_0 0x08
#define BLIZZARD_PLL_CLOCK_SYNTH_1 0x0a
#define BLIZZARD_PLL_MODE 0x0c
#define BLIZZARD_CLK_SRC 0x0e
#define BLIZZARD_MEM_BANK0_ACTIVATE 0x10
#define BLIZZARD_MEM_BANK0_STATUS 0x14
#define BLIZZARD_PANEL_CONFIGURATION 0x28
#define BLIZZARD_HDISP 0x2a
#define BLIZZARD_HNDP 0x2c
#define BLIZZARD_VDISP0 0x2e
#define BLIZZARD_VDISP1 0x30
#define BLIZZARD_VNDP 0x32
#define BLIZZARD_HSW 0x34
#define BLIZZARD_VSW 0x38
#define BLIZZARD_DISPLAY_MODE 0x68
#define BLIZZARD_INPUT_WIN_X_START_0 0x6c
#define BLIZZARD_DATA_SOURCE_SELECT 0x8e
#define BLIZZARD_DISP_MEM_DATA_PORT 0x90
#define BLIZZARD_DISP_MEM_READ_ADDR0 0x92
#define BLIZZARD_POWER_SAVE 0xE6
#define BLIZZARD_NDISP_CTRL_STATUS 0xE8
/* Data source select */
/* For S1D13745 */
#define BLIZZARD_SRC_WRITE_LCD_BACKGROUND 0x00
#define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE 0x01
#define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE 0x04
#define BLIZZARD_SRC_DISABLE_OVERLAY 0x05
/* For S1D13744 */
#define BLIZZARD_SRC_WRITE_LCD 0x00
#define BLIZZARD_SRC_BLT_LCD 0x06
#define BLIZZARD_COLOR_RGB565 0x01
#define BLIZZARD_COLOR_YUV420 0x09
#define BLIZZARD_VERSION_S1D13745 0x01
/* Hailstorm */
#define BLIZZARD_VERSION_S1D13744 0x02
/* Blizzard */
#define BLIZZARD_AUTO_UPDATE_TIME (HZ / 20)
/* Reserve 4 request slots for requests in irq context */
#define REQ_POOL_SIZE 24
#define IRQ_REQ_POOL_SIZE 4
#define REQ_FROM_IRQ_POOL 0x01
#define REQ_COMPLETE 0
#define REQ_PENDING 1
struct
blizzard_reg_list
{
int
start
;
int
end
;
};
/* These need to be saved / restored separately from the rest. */
static
const
struct
blizzard_reg_list
blizzard_pll_regs
[]
=
{
{
.
start
=
0x04
,
/* Don't save PLL ctrl (0x0C) */
.
end
=
0x0a
,
},
{
.
start
=
0x0e
,
/* Clock configuration */
.
end
=
0x0e
,
},
};
static
const
struct
blizzard_reg_list
blizzard_gen_regs
[]
=
{
{
.
start
=
0x18
,
/* SDRAM control */
.
end
=
0x20
,
},
{
.
start
=
0x28
,
/* LCD Panel configuration */
.
end
=
0x5a
,
/* HSSI interface, TV configuration */
},
};
static
u8
blizzard_reg_cache
[
0x5a
/
2
];
struct
update_param
{
int
plane
;
int
x
,
y
,
width
,
height
;
int
out_x
,
out_y
;
int
out_width
,
out_height
;
int
color_mode
;
int
bpp
;
int
flags
;
};
struct
blizzard_request
{
struct
list_head
entry
;
unsigned
int
flags
;
int
(
*
handler
)(
struct
blizzard_request
*
req
);
void
(
*
complete
)(
void
*
data
);
void
*
complete_data
;
union
{
struct
update_param
update
;
struct
completion
*
sync
;
}
par
;
};
struct
plane_info
{
unsigned
long
offset
;
int
pos_x
,
pos_y
;
int
width
,
height
;
int
out_width
,
out_height
;
int
scr_width
;
int
color_mode
;
int
bpp
;
};
struct
blizzard_struct
{
enum
omapfb_update_mode
update_mode
;
enum
omapfb_update_mode
update_mode_before_suspend
;
struct
timer_list
auto_update_timer
;
int
stop_auto_update
;
struct
omapfb_update_window
auto_update_window
;
int
enabled_planes
;
int
vid_nonstd_color
;
int
vid_scaled
;
int
last_color_mode
;
int
zoom_on
;
int
zoom_area_gx1
;
int
zoom_area_gx2
;
int
zoom_area_gy1
;
int
zoom_area_gy2
;
int
screen_width
;
int
screen_height
;
unsigned
te_connected
:
1
;
unsigned
vsync_only
:
1
;
struct
plane_info
plane
[
OMAPFB_PLANE_NUM
];
struct
blizzard_request
req_pool
[
REQ_POOL_SIZE
];
struct
list_head
pending_req_list
;
struct
list_head
free_req_list
;
struct
semaphore
req_sema
;
spinlock_t
req_lock
;
unsigned
long
sys_ck_rate
;
struct
extif_timings
reg_timings
,
lut_timings
;
u32
max_transmit_size
;
u32
extif_clk_period
;
int
extif_clk_div
;
unsigned
long
pix_tx_time
;
unsigned
long
line_upd_time
;
struct
omapfb_device
*
fbdev
;
struct
lcd_ctrl_extif
*
extif
;
const
struct
lcd_ctrl
*
int_ctrl
;
void
(
*
power_up
)(
struct
device
*
dev
);
void
(
*
power_down
)(
struct
device
*
dev
);
int
version
;
}
blizzard
;
struct
lcd_ctrl
blizzard_ctrl
;
static
u8
blizzard_read_reg
(
u8
reg
)
{
u8
data
;
blizzard
.
extif
->
set_bits_per_cycle
(
8
);
blizzard
.
extif
->
write_command
(
&
reg
,
1
);
blizzard
.
extif
->
read_data
(
&
data
,
1
);
return
data
;
}
static
void
blizzard_write_reg
(
u8
reg
,
u8
val
)
{
blizzard
.
extif
->
set_bits_per_cycle
(
8
);
blizzard
.
extif
->
write_command
(
&
reg
,
1
);
blizzard
.
extif
->
write_data
(
&
val
,
1
);
}
static
void
blizzard_restart_sdram
(
void
)
{
unsigned
long
tmo
;
blizzard_write_reg
(
BLIZZARD_MEM_BANK0_ACTIVATE
,
0
);
udelay
(
50
);
blizzard_write_reg
(
BLIZZARD_MEM_BANK0_ACTIVATE
,
1
);
tmo
=
jiffies
+
msecs_to_jiffies
(
200
);
while
(
!
(
blizzard_read_reg
(
BLIZZARD_MEM_BANK0_STATUS
)
&
0x01
))
{
if
(
time_after
(
jiffies
,
tmo
))
{
dev_err
(
blizzard
.
fbdev
->
dev
,
"s1d1374x: SDRAM not ready
\n
"
);
break
;
}
msleep
(
1
);
}
}
static
void
blizzard_stop_sdram
(
void
)
{
blizzard_write_reg
(
BLIZZARD_MEM_BANK0_ACTIVATE
,
0
);
}
/* Wait until the last window was completely written into the controllers
* SDRAM and we can start transferring the next window.
*/
static
void
blizzard_wait_line_buffer
(
void
)
{
unsigned
long
tmo
=
jiffies
+
msecs_to_jiffies
(
30
);
while
(
blizzard_read_reg
(
BLIZZARD_NDISP_CTRL_STATUS
)
&
(
1
<<
7
))
{
if
(
time_after
(
jiffies
,
tmo
))
{
if
(
printk_ratelimit
())
dev_err
(
blizzard
.
fbdev
->
dev
,
"s1d1374x: line buffer not ready
\n
"
);
break
;
}
}
}
/* Wait until the YYC color space converter is idle. */
static
void
blizzard_wait_yyc
(
void
)
{
unsigned
long
tmo
=
jiffies
+
msecs_to_jiffies
(
30
);
while
(
blizzard_read_reg
(
BLIZZARD_NDISP_CTRL_STATUS
)
&
(
1
<<
4
))
{
if
(
time_after
(
jiffies
,
tmo
))
{
if
(
printk_ratelimit
())
dev_err
(
blizzard
.
fbdev
->
dev
,
"s1d1374x: YYC not ready
\n
"
);
break
;
}
}
}
static
void
disable_overlay
(
void
)
{
blizzard_write_reg
(
BLIZZARD_DATA_SOURCE_SELECT
,
BLIZZARD_SRC_DISABLE_OVERLAY
);
}
static
void
set_window_regs
(
int
x_start
,
int
y_start
,
int
x_end
,
int
y_end
,
int
x_out_start
,
int
y_out_start
,
int
x_out_end
,
int
y_out_end
,
int
color_mode
,
int
zoom_off
,
int
flags
)
{
u8
tmp
[
18
];
u8
cmd
;
x_end
--
;
y_end
--
;
tmp
[
0
]
=
x_start
;
tmp
[
1
]
=
x_start
>>
8
;
tmp
[
2
]
=
y_start
;
tmp
[
3
]
=
y_start
>>
8
;
tmp
[
4
]
=
x_end
;
tmp
[
5
]
=
x_end
>>
8
;
tmp
[
6
]
=
y_end
;
tmp
[
7
]
=
y_end
>>
8
;
x_out_end
--
;
y_out_end
--
;
tmp
[
8
]
=
x_out_start
;
tmp
[
9
]
=
x_out_start
>>
8
;
tmp
[
10
]
=
y_out_start
;
tmp
[
11
]
=
y_out_start
>>
8
;
tmp
[
12
]
=
x_out_end
;
tmp
[
13
]
=
x_out_end
>>
8
;
tmp
[
14
]
=
y_out_end
;
tmp
[
15
]
=
y_out_end
>>
8
;
tmp
[
16
]
=
color_mode
;
if
(
zoom_off
&&
blizzard
.
version
==
BLIZZARD_VERSION_S1D13745
)
tmp
[
17
]
=
BLIZZARD_SRC_WRITE_LCD_BACKGROUND
;
else
if
(
flags
&
OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY
)
tmp
[
17
]
=
BLIZZARD_SRC_WRITE_OVERLAY_ENABLE
;
else
tmp
[
17
]
=
blizzard
.
version
==
BLIZZARD_VERSION_S1D13744
?
BLIZZARD_SRC_WRITE_LCD
:
BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE
;
blizzard
.
extif
->
set_bits_per_cycle
(
8
);
cmd
=
BLIZZARD_INPUT_WIN_X_START_0
;
blizzard
.
extif
->
write_command
(
&
cmd
,
1
);
blizzard
.
extif
->
write_data
(
tmp
,
18
);
}
static
void
enable_tearsync
(
int
y
,
int
width
,
int
height
,
int
screen_height
,
int
out_height
,
int
force_vsync
)
{
u8
b
;
b
=
blizzard_read_reg
(
BLIZZARD_NDISP_CTRL_STATUS
);
b
|=
1
<<
3
;
blizzard_write_reg
(
BLIZZARD_NDISP_CTRL_STATUS
,
b
);
if
(
likely
(
blizzard
.
vsync_only
||
force_vsync
))
{
blizzard
.
extif
->
enable_tearsync
(
1
,
0
);
return
;
}
if
(
width
*
blizzard
.
pix_tx_time
<
blizzard
.
line_upd_time
)
{
blizzard
.
extif
->
enable_tearsync
(
1
,
0
);
return
;
}
if
((
width
*
blizzard
.
pix_tx_time
/
1000
)
*
height
<
(
y
+
out_height
)
*
(
blizzard
.
line_upd_time
/
1000
))
{
blizzard
.
extif
->
enable_tearsync
(
1
,
0
);
return
;
}
blizzard
.
extif
->
enable_tearsync
(
1
,
y
+
1
);
}
static
void
disable_tearsync
(
void
)
{
u8
b
;
blizzard
.
extif
->
enable_tearsync
(
0
,
0
);
b
=
blizzard_read_reg
(
BLIZZARD_NDISP_CTRL_STATUS
);
b
&=
~
(
1
<<
3
);
blizzard_write_reg
(
BLIZZARD_NDISP_CTRL_STATUS
,
b
);
b
=
blizzard_read_reg
(
BLIZZARD_NDISP_CTRL_STATUS
);
}
static
inline
void
set_extif_timings
(
const
struct
extif_timings
*
t
);
static
inline
struct
blizzard_request
*
alloc_req
(
void
)
{
unsigned
long
flags
;
struct
blizzard_request
*
req
;
int
req_flags
=
0
;
if
(
!
in_interrupt
())
down
(
&
blizzard
.
req_sema
);
else
req_flags
=
REQ_FROM_IRQ_POOL
;
spin_lock_irqsave
(
&
blizzard
.
req_lock
,
flags
);
BUG_ON
(
list_empty
(
&
blizzard
.
free_req_list
));
req
=
list_entry
(
blizzard
.
free_req_list
.
next
,
struct
blizzard_request
,
entry
);
list_del
(
&
req
->
entry
);
spin_unlock_irqrestore
(
&
blizzard
.
req_lock
,
flags
);
INIT_LIST_HEAD
(
&
req
->
entry
);
req
->
flags
=
req_flags
;
return
req
;
}
static
inline
void
free_req
(
struct
blizzard_request
*
req
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
blizzard
.
req_lock
,
flags
);
list_move
(
&
req
->
entry
,
&
blizzard
.
free_req_list
);
if
(
!
(
req
->
flags
&
REQ_FROM_IRQ_POOL
))
up
(
&
blizzard
.
req_sema
);
spin_unlock_irqrestore
(
&
blizzard
.
req_lock
,
flags
);
}
static
void
process_pending_requests
(
void
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
blizzard
.
req_lock
,
flags
);
while
(
!
list_empty
(
&
blizzard
.
pending_req_list
))
{
struct
blizzard_request
*
req
;
void
(
*
complete
)(
void
*
);
void
*
complete_data
;
req
=
list_entry
(
blizzard
.
pending_req_list
.
next
,
struct
blizzard_request
,
entry
);
spin_unlock_irqrestore
(
&
blizzard
.
req_lock
,
flags
);
if
(
req
->
handler
(
req
)
==
REQ_PENDING
)
return
;
complete
=
req
->
complete
;
complete_data
=
req
->
complete_data
;
free_req
(
req
);
if
(
complete
)
complete
(
complete_data
);
spin_lock_irqsave
(
&
blizzard
.
req_lock
,
flags
);
}
spin_unlock_irqrestore
(
&
blizzard
.
req_lock
,
flags
);
}
static
void
submit_req_list
(
struct
list_head
*
head
)
{
unsigned
long
flags
;
int
process
=
1
;
spin_lock_irqsave
(
&
blizzard
.
req_lock
,
flags
);
if
(
likely
(
!
list_empty
(
&
blizzard
.
pending_req_list
)))
process
=
0
;
list_splice_init
(
head
,
blizzard
.
pending_req_list
.
prev
);
spin_unlock_irqrestore
(
&
blizzard
.
req_lock
,
flags
);
if
(
process
)
process_pending_requests
();
}
static
void
request_complete
(
void
*
data
)
{
struct
blizzard_request
*
req
=
(
struct
blizzard_request
*
)
data
;
void
(
*
complete
)(
void
*
);
void
*
complete_data
;
complete
=
req
->
complete
;
complete_data
=
req
->
complete_data
;
free_req
(
req
);
if
(
complete
)
complete
(
complete_data
);
process_pending_requests
();
}
static
int
do_full_screen_update
(
struct
blizzard_request
*
req
)
{
int
i
;
int
flags
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
struct
plane_info
*
p
=
&
blizzard
.
plane
[
i
];
if
(
!
(
blizzard
.
enabled_planes
&
(
1
<<
i
)))
{
blizzard
.
int_ctrl
->
enable_plane
(
i
,
0
);
continue
;
}
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"pw %d ph %d
\n
"
,
p
->
width
,
p
->
height
);
blizzard
.
int_ctrl
->
setup_plane
(
i
,
OMAPFB_CHANNEL_OUT_LCD
,
p
->
offset
,
p
->
scr_width
,
p
->
pos_x
,
p
->
pos_y
,
p
->
width
,
p
->
height
,
p
->
color_mode
);
blizzard
.
int_ctrl
->
enable_plane
(
i
,
1
);
}
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"sw %d sh %d
\n
"
,
blizzard
.
screen_width
,
blizzard
.
screen_height
);
blizzard_wait_line_buffer
();
flags
=
req
->
par
.
update
.
flags
;
if
(
flags
&
OMAPFB_FORMAT_FLAG_TEARSYNC
)
enable_tearsync
(
0
,
blizzard
.
screen_width
,
blizzard
.
screen_height
,
blizzard
.
screen_height
,
blizzard
.
screen_height
,
flags
&
OMAPFB_FORMAT_FLAG_FORCE_VSYNC
);
else
disable_tearsync
();
set_window_regs
(
0
,
0
,
blizzard
.
screen_width
,
blizzard
.
screen_height
,
0
,
0
,
blizzard
.
screen_width
,
blizzard
.
screen_height
,
BLIZZARD_COLOR_RGB565
,
blizzard
.
zoom_on
,
flags
);
blizzard
.
zoom_on
=
0
;
blizzard
.
extif
->
set_bits_per_cycle
(
16
);
/* set_window_regs has left the register index at the right
* place, so no need to set it here.
*/
blizzard
.
extif
->
transfer_area
(
blizzard
.
screen_width
,
blizzard
.
screen_height
,
request_complete
,
req
);
return
REQ_PENDING
;
}
static
int
check_1d_intersect
(
int
a1
,
int
a2
,
int
b1
,
int
b2
)
{
if
(
a2
<=
b1
||
b2
<=
a1
)
return
0
;
return
1
;
}
/* Setup all planes with an overlapping area with the update window. */
static
int
do_partial_update
(
struct
blizzard_request
*
req
,
int
plane
,
int
x
,
int
y
,
int
w
,
int
h
,
int
x_out
,
int
y_out
,
int
w_out
,
int
h_out
,
int
wnd_color_mode
,
int
bpp
)
{
int
i
;
int
gx1
,
gy1
,
gx2
,
gy2
;
int
gx1_out
,
gy1_out
,
gx2_out
,
gy2_out
;
int
color_mode
;
int
flags
;
int
zoom_off
;
int
have_zoom_for_this_update
=
0
;
/* Global coordinates, relative to pixel 0,0 of the LCD */
gx1
=
x
+
blizzard
.
plane
[
plane
].
pos_x
;
gy1
=
y
+
blizzard
.
plane
[
plane
].
pos_y
;
gx2
=
gx1
+
w
;
gy2
=
gy1
+
h
;
flags
=
req
->
par
.
update
.
flags
;
if
(
flags
&
OMAPFB_FORMAT_FLAG_DOUBLE
)
{
gx1_out
=
gx1
;
gy1_out
=
gy1
;
gx2_out
=
gx1
+
w
*
2
;
gy2_out
=
gy1
+
h
*
2
;
}
else
{
gx1_out
=
x_out
+
blizzard
.
plane
[
plane
].
pos_x
;
gy1_out
=
y_out
+
blizzard
.
plane
[
plane
].
pos_y
;
gx2_out
=
gx1_out
+
w_out
;
gy2_out
=
gy1_out
+
h_out
;
}
for
(
i
=
0
;
i
<
OMAPFB_PLANE_NUM
;
i
++
)
{
struct
plane_info
*
p
=
&
blizzard
.
plane
[
i
];
int
px1
,
py1
;
int
px2
,
py2
;
int
pw
,
ph
;
int
pposx
,
pposy
;
unsigned
long
offset
;
if
(
!
(
blizzard
.
enabled_planes
&
(
1
<<
i
))
||
(
wnd_color_mode
&&
i
!=
plane
))
{
blizzard
.
int_ctrl
->
enable_plane
(
i
,
0
);
continue
;
}
/* Plane coordinates */
if
(
i
==
plane
)
{
/* Plane in which we are doing the update.
* Local coordinates are the one in the update
* request.
*/
px1
=
x
;
py1
=
y
;
px2
=
x
+
w
;
py2
=
y
+
h
;
pposx
=
0
;
pposy
=
0
;
}
else
{
/* Check if this plane has an overlapping part */
px1
=
gx1
-
p
->
pos_x
;
py1
=
gy1
-
p
->
pos_y
;
px2
=
gx2
-
p
->
pos_x
;
py2
=
gy2
-
p
->
pos_y
;
if
(
px1
>=
p
->
width
||
py1
>=
p
->
height
||
px2
<=
0
||
py2
<=
0
)
{
blizzard
.
int_ctrl
->
enable_plane
(
i
,
0
);
continue
;
}
/* Calculate the coordinates for the overlapping
* part in the plane's local coordinates.
*/
pposx
=
-
px1
;
pposy
=
-
py1
;
if
(
px1
<
0
)
px1
=
0
;
if
(
py1
<
0
)
py1
=
0
;
if
(
px2
>
p
->
width
)
px2
=
p
->
width
;
if
(
py2
>
p
->
height
)
py2
=
p
->
height
;
if
(
pposx
<
0
)
pposx
=
0
;
if
(
pposy
<
0
)
pposy
=
0
;
}
pw
=
px2
-
px1
;
ph
=
py2
-
py1
;
offset
=
p
->
offset
+
(
p
->
scr_width
*
py1
+
px1
)
*
p
->
bpp
/
8
;
if
(
wnd_color_mode
)
/* Window embedded in the plane with a differing
* color mode / bpp. Calculate the number of DMA
* transfer elements in terms of the plane's bpp.
*/
pw
=
(
pw
+
1
)
*
bpp
/
p
->
bpp
;
#ifdef VERBOSE
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"plane %d offset %#08lx pposx %d pposy %d "
"px1 %d py1 %d pw %d ph %d
\n
"
,
i
,
offset
,
pposx
,
pposy
,
px1
,
py1
,
pw
,
ph
);
#endif
blizzard
.
int_ctrl
->
setup_plane
(
i
,
OMAPFB_CHANNEL_OUT_LCD
,
offset
,
p
->
scr_width
,
pposx
,
pposy
,
pw
,
ph
,
p
->
color_mode
);
blizzard
.
int_ctrl
->
enable_plane
(
i
,
1
);
}
switch
(
wnd_color_mode
)
{
case
OMAPFB_COLOR_YUV420
:
color_mode
=
BLIZZARD_COLOR_YUV420
;
/* Currently only the 16 bits/pixel cycle format is
* supported on the external interface. Adjust the number
* of transfer elements per line for 12bpp format.
*/
w
=
(
w
+
1
)
*
3
/
4
;
break
;
default:
color_mode
=
BLIZZARD_COLOR_RGB565
;
break
;
}
blizzard_wait_line_buffer
();
if
(
blizzard
.
last_color_mode
==
BLIZZARD_COLOR_YUV420
)
blizzard_wait_yyc
();
blizzard
.
last_color_mode
=
color_mode
;
if
(
flags
&
OMAPFB_FORMAT_FLAG_TEARSYNC
)
enable_tearsync
(
gy1
,
w
,
h
,
blizzard
.
screen_height
,
h_out
,
flags
&
OMAPFB_FORMAT_FLAG_FORCE_VSYNC
);
else
disable_tearsync
();
if
((
gx2_out
-
gx1_out
)
!=
(
gx2
-
gx1
)
||
(
gy2_out
-
gy1_out
)
!=
(
gy2
-
gy1
))
have_zoom_for_this_update
=
1
;
/* 'background' type of screen update (as opposed to 'destructive')
can be used to disable scaling if scaling is active */
zoom_off
=
blizzard
.
zoom_on
&&
!
have_zoom_for_this_update
&&
(
gx1_out
==
0
)
&&
(
gx2_out
==
blizzard
.
screen_width
)
&&
(
gy1_out
==
0
)
&&
(
gy2_out
==
blizzard
.
screen_height
)
&&
(
gx1
==
0
)
&&
(
gy1
==
0
);
if
(
blizzard
.
zoom_on
&&
!
have_zoom_for_this_update
&&
!
zoom_off
&&
check_1d_intersect
(
blizzard
.
zoom_area_gx1
,
blizzard
.
zoom_area_gx2
,
gx1_out
,
gx2_out
)
&&
check_1d_intersect
(
blizzard
.
zoom_area_gy1
,
blizzard
.
zoom_area_gy2
,
gy1_out
,
gy2_out
))
{
/* Previous screen update was using scaling, current update
* is not using it. Additionally, current screen update is
* going to overlap with the scaled area. Scaling needs to be
* disabled in order to avoid 'magnifying glass' effect.
* Dummy setup of background window can be used for this.
*/
set_window_regs
(
0
,
0
,
blizzard
.
screen_width
,
blizzard
.
screen_height
,
0
,
0
,
blizzard
.
screen_width
,
blizzard
.
screen_height
,
BLIZZARD_COLOR_RGB565
,
1
,
flags
);
blizzard
.
zoom_on
=
0
;
}
/* remember scaling settings if we have scaled update */
if
(
have_zoom_for_this_update
)
{
blizzard
.
zoom_on
=
1
;
blizzard
.
zoom_area_gx1
=
gx1_out
;
blizzard
.
zoom_area_gx2
=
gx2_out
;
blizzard
.
zoom_area_gy1
=
gy1_out
;
blizzard
.
zoom_area_gy2
=
gy2_out
;
}
set_window_regs
(
gx1
,
gy1
,
gx2
,
gy2
,
gx1_out
,
gy1_out
,
gx2_out
,
gy2_out
,
color_mode
,
zoom_off
,
flags
);
if
(
zoom_off
)
blizzard
.
zoom_on
=
0
;
blizzard
.
extif
->
set_bits_per_cycle
(
16
);
/* set_window_regs has left the register index at the right
* place, so no need to set it here.
*/
blizzard
.
extif
->
transfer_area
(
w
,
h
,
request_complete
,
req
);
return
REQ_PENDING
;
}
static
int
send_frame_handler
(
struct
blizzard_request
*
req
)
{
struct
update_param
*
par
=
&
req
->
par
.
update
;
int
plane
=
par
->
plane
;
#ifdef VERBOSE
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"send_frame: x %d y %d w %d h %d "
"x_out %d y_out %d w_out %d h_out %d "
"color_mode %04x flags %04x planes %01x
\n
"
,
par
->
x
,
par
->
y
,
par
->
width
,
par
->
height
,
par
->
out_x
,
par
->
out_y
,
par
->
out_width
,
par
->
out_height
,
par
->
color_mode
,
par
->
flags
,
blizzard
.
enabled_planes
);
#endif
if
(
par
->
flags
&
OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY
)
disable_overlay
();
if
((
blizzard
.
enabled_planes
&
blizzard
.
vid_nonstd_color
)
||
(
blizzard
.
enabled_planes
&
blizzard
.
vid_scaled
))
return
do_full_screen_update
(
req
);
return
do_partial_update
(
req
,
plane
,
par
->
x
,
par
->
y
,
par
->
width
,
par
->
height
,
par
->
out_x
,
par
->
out_y
,
par
->
out_width
,
par
->
out_height
,
par
->
color_mode
,
par
->
bpp
);
}
static
void
send_frame_complete
(
void
*
data
)
{
}
#define ADD_PREQ(_x, _y, _w, _h, _x_out, _y_out, _w_out, _h_out) do { \
req = alloc_req(); \
req->handler = send_frame_handler; \
req->complete = send_frame_complete; \
req->par.update.plane = plane_idx; \
req->par.update.x = _x; \
req->par.update.y = _y; \
req->par.update.width = _w; \
req->par.update.height = _h; \
req->par.update.out_x = _x_out; \
req->par.update.out_y = _y_out; \
req->par.update.out_width = _w_out; \
req->par.update.out_height = _h_out; \
req->par.update.bpp = bpp; \
req->par.update.color_mode = color_mode;\
req->par.update.flags = flags; \
list_add_tail(&req->entry, req_head); \
} while(0)
static
void
create_req_list
(
int
plane_idx
,
struct
omapfb_update_window
*
win
,
struct
list_head
*
req_head
)
{
struct
blizzard_request
*
req
;
int
x
=
win
->
x
;
int
y
=
win
->
y
;
int
width
=
win
->
width
;
int
height
=
win
->
height
;
int
x_out
=
win
->
out_x
;
int
y_out
=
win
->
out_y
;
int
width_out
=
win
->
out_width
;
int
height_out
=
win
->
out_height
;
int
color_mode
;
int
bpp
;
int
flags
;
unsigned
int
ystart
=
y
;
unsigned
int
yspan
=
height
;
unsigned
int
ystart_out
=
y_out
;
unsigned
int
yspan_out
=
height_out
;
flags
=
win
->
format
&
~
OMAPFB_FORMAT_MASK
;
color_mode
=
win
->
format
&
OMAPFB_FORMAT_MASK
;
switch
(
color_mode
)
{
case
OMAPFB_COLOR_YUV420
:
/* Embedded window with different color mode */
bpp
=
12
;
/* X, Y, height must be aligned at 2, width at 4 pixels */
x
&=
~
1
;
y
&=
~
1
;
height
=
yspan
=
height
&
~
1
;
width
=
width
&
~
3
;
break
;
default:
/* Same as the plane color mode */
bpp
=
blizzard
.
plane
[
plane_idx
].
bpp
;
break
;
}
if
(
width
*
height
*
bpp
/
8
>
blizzard
.
max_transmit_size
)
{
yspan
=
blizzard
.
max_transmit_size
/
(
width
*
bpp
/
8
);
yspan_out
=
yspan
*
height_out
/
height
;
ADD_PREQ
(
x
,
ystart
,
width
,
yspan
,
x_out
,
ystart_out
,
width_out
,
yspan_out
);
ystart
+=
yspan
;
ystart_out
+=
yspan_out
;
yspan
=
height
-
yspan
;
yspan_out
=
height_out
-
yspan_out
;
flags
&=
~
OMAPFB_FORMAT_FLAG_TEARSYNC
;
}
ADD_PREQ
(
x
,
ystart
,
width
,
yspan
,
x_out
,
ystart_out
,
width_out
,
yspan_out
);
}
static
void
auto_update_complete
(
void
*
data
)
{
if
(
!
blizzard
.
stop_auto_update
)
mod_timer
(
&
blizzard
.
auto_update_timer
,
jiffies
+
BLIZZARD_AUTO_UPDATE_TIME
);
}
static
void
blizzard_update_window_auto
(
unsigned
long
arg
)
{
LIST_HEAD
(
req_list
);
struct
blizzard_request
*
last
;
struct
omapfb_plane_struct
*
plane
;
plane
=
blizzard
.
fbdev
->
fb_info
[
0
]
->
par
;
create_req_list
(
plane
->
idx
,
&
blizzard
.
auto_update_window
,
&
req_list
);
last
=
list_entry
(
req_list
.
prev
,
struct
blizzard_request
,
entry
);
last
->
complete
=
auto_update_complete
;
last
->
complete_data
=
NULL
;
submit_req_list
(
&
req_list
);
}
int
blizzard_update_window_async
(
struct
fb_info
*
fbi
,
struct
omapfb_update_window
*
win
,
void
(
*
complete_callback
)(
void
*
arg
),
void
*
complete_callback_data
)
{
LIST_HEAD
(
req_list
);
struct
blizzard_request
*
last
;
struct
omapfb_plane_struct
*
plane
=
fbi
->
par
;
if
(
unlikely
(
blizzard
.
update_mode
!=
OMAPFB_MANUAL_UPDATE
))
return
-
EINVAL
;
if
(
unlikely
(
!
blizzard
.
te_connected
&&
(
win
->
format
&
OMAPFB_FORMAT_FLAG_TEARSYNC
)))
return
-
EINVAL
;
create_req_list
(
plane
->
idx
,
win
,
&
req_list
);
last
=
list_entry
(
req_list
.
prev
,
struct
blizzard_request
,
entry
);
last
->
complete
=
complete_callback
;
last
->
complete_data
=
(
void
*
)
complete_callback_data
;
submit_req_list
(
&
req_list
);
return
0
;
}
EXPORT_SYMBOL
(
blizzard_update_window_async
);
static
int
update_full_screen
(
void
)
{
return
blizzard_update_window_async
(
blizzard
.
fbdev
->
fb_info
[
0
],
&
blizzard
.
auto_update_window
,
NULL
,
NULL
);
}
static
int
blizzard_setup_plane
(
int
plane
,
int
channel_out
,
unsigned
long
offset
,
int
screen_width
,
int
pos_x
,
int
pos_y
,
int
width
,
int
height
,
int
color_mode
)
{
struct
plane_info
*
p
;
#ifdef VERBOSE
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"plane %d ch_out %d offset %#08lx scr_width %d "
"pos_x %d pos_y %d width %d height %d color_mode %d
\n
"
,
plane
,
channel_out
,
offset
,
screen_width
,
pos_x
,
pos_y
,
width
,
height
,
color_mode
);
#endif
if
((
unsigned
)
plane
>
OMAPFB_PLANE_NUM
)
return
-
EINVAL
;
p
=
&
blizzard
.
plane
[
plane
];
switch
(
color_mode
)
{
case
OMAPFB_COLOR_YUV422
:
case
OMAPFB_COLOR_YUY422
:
p
->
bpp
=
16
;
blizzard
.
vid_nonstd_color
&=
~
(
1
<<
plane
);
break
;
case
OMAPFB_COLOR_YUV420
:
p
->
bpp
=
12
;
blizzard
.
vid_nonstd_color
|=
1
<<
plane
;
break
;
case
OMAPFB_COLOR_RGB565
:
p
->
bpp
=
16
;
blizzard
.
vid_nonstd_color
&=
~
(
1
<<
plane
);
break
;
default:
return
-
EINVAL
;
}
p
->
offset
=
offset
;
p
->
pos_x
=
pos_x
;
p
->
pos_y
=
pos_y
;
p
->
width
=
width
;
p
->
height
=
height
;
p
->
scr_width
=
screen_width
;
if
(
!
p
->
out_width
)
p
->
out_width
=
width
;
if
(
!
p
->
out_height
)
p
->
out_height
=
height
;
p
->
color_mode
=
color_mode
;
return
0
;
}
static
int
blizzard_set_scale
(
int
plane
,
int
orig_w
,
int
orig_h
,
int
out_w
,
int
out_h
)
{
struct
plane_info
*
p
=
&
blizzard
.
plane
[
plane
];
int
r
;
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"plane %d orig_w %d orig_h %d out_w %d out_h %d
\n
"
,
plane
,
orig_w
,
orig_h
,
out_w
,
out_h
);
if
((
unsigned
)
plane
>
OMAPFB_PLANE_NUM
)
return
-
ENODEV
;
r
=
blizzard
.
int_ctrl
->
set_scale
(
plane
,
orig_w
,
orig_h
,
out_w
,
out_h
);
if
(
r
<
0
)
return
r
;
p
->
width
=
orig_w
;
p
->
height
=
orig_h
;
p
->
out_width
=
out_w
;
p
->
out_height
=
out_h
;
if
(
orig_w
==
out_w
&&
orig_h
==
out_h
)
blizzard
.
vid_scaled
&=
~
(
1
<<
plane
);
else
blizzard
.
vid_scaled
|=
1
<<
plane
;
return
0
;
}
static
int
blizzard_set_rotate
(
int
angle
)
{
u32
l
;
l
=
blizzard_read_reg
(
BLIZZARD_PANEL_CONFIGURATION
);
l
&=
~
0x03
;
switch
(
angle
)
{
case
0
:
l
=
l
|
0x00
;
break
;
case
90
:
l
=
l
|
0x03
;
break
;
case
180
:
l
=
l
|
0x02
;
break
;
case
270
:
l
=
l
|
0x01
;
break
;
default:
return
-
EINVAL
;
}
blizzard_write_reg
(
BLIZZARD_PANEL_CONFIGURATION
,
l
);
return
0
;
}
static
int
blizzard_enable_plane
(
int
plane
,
int
enable
)
{
if
(
enable
)
blizzard
.
enabled_planes
|=
1
<<
plane
;
else
blizzard
.
enabled_planes
&=
~
(
1
<<
plane
);
return
0
;
}
static
int
sync_handler
(
struct
blizzard_request
*
req
)
{
complete
(
req
->
par
.
sync
);
return
REQ_COMPLETE
;
}
static
void
blizzard_sync
(
void
)
{
LIST_HEAD
(
req_list
);
struct
blizzard_request
*
req
;
struct
completion
comp
;
req
=
alloc_req
();
req
->
handler
=
sync_handler
;
req
->
complete
=
NULL
;
init_completion
(
&
comp
);
req
->
par
.
sync
=
&
comp
;
list_add
(
&
req
->
entry
,
&
req_list
);
submit_req_list
(
&
req_list
);
wait_for_completion
(
&
comp
);
}
static
void
blizzard_bind_client
(
struct
omapfb_notifier_block
*
nb
)
{
if
(
blizzard
.
update_mode
==
OMAPFB_MANUAL_UPDATE
)
{
omapfb_notify_clients
(
blizzard
.
fbdev
,
OMAPFB_EVENT_READY
);
}
}
static
int
blizzard_set_update_mode
(
enum
omapfb_update_mode
mode
)
{
if
(
unlikely
(
mode
!=
OMAPFB_MANUAL_UPDATE
&&
mode
!=
OMAPFB_AUTO_UPDATE
&&
mode
!=
OMAPFB_UPDATE_DISABLED
))
return
-
EINVAL
;
if
(
mode
==
blizzard
.
update_mode
)
return
0
;
dev_info
(
blizzard
.
fbdev
->
dev
,
"s1d1374x: setting update mode to %s
\n
"
,
mode
==
OMAPFB_UPDATE_DISABLED
?
"disabled"
:
(
mode
==
OMAPFB_AUTO_UPDATE
?
"auto"
:
"manual"
));
switch
(
blizzard
.
update_mode
)
{
case
OMAPFB_MANUAL_UPDATE
:
omapfb_notify_clients
(
blizzard
.
fbdev
,
OMAPFB_EVENT_DISABLED
);
break
;
case
OMAPFB_AUTO_UPDATE
:
blizzard
.
stop_auto_update
=
1
;
del_timer_sync
(
&
blizzard
.
auto_update_timer
);
break
;
case
OMAPFB_UPDATE_DISABLED
:
break
;
}
blizzard
.
update_mode
=
mode
;
blizzard_sync
();
blizzard
.
stop_auto_update
=
0
;
switch
(
mode
)
{
case
OMAPFB_MANUAL_UPDATE
:
omapfb_notify_clients
(
blizzard
.
fbdev
,
OMAPFB_EVENT_READY
);
break
;
case
OMAPFB_AUTO_UPDATE
:
blizzard_update_window_auto
(
0
);
break
;
case
OMAPFB_UPDATE_DISABLED
:
break
;
}
return
0
;
}
static
enum
omapfb_update_mode
blizzard_get_update_mode
(
void
)
{
return
blizzard
.
update_mode
;
}
static
inline
void
set_extif_timings
(
const
struct
extif_timings
*
t
)
{
blizzard
.
extif
->
set_timings
(
t
);
}
static
inline
unsigned
long
round_to_extif_ticks
(
unsigned
long
ps
,
int
div
)
{
int
bus_tick
=
blizzard
.
extif_clk_period
*
div
;
return
(
ps
+
bus_tick
-
1
)
/
bus_tick
*
bus_tick
;
}
static
int
calc_reg_timing
(
unsigned
long
sysclk
,
int
div
)
{
struct
extif_timings
*
t
;
unsigned
long
systim
;
/* CSOnTime 0, WEOnTime 2 ns, REOnTime 2 ns,
* AccessTime 2 ns + 12.2 ns (regs),
* WEOffTime = WEOnTime + 1 ns,
* REOffTime = REOnTime + 12 ns (regs),
* CSOffTime = REOffTime + 1 ns
* ReadCycle = 2ns + 2*SYSCLK (regs),
* WriteCycle = 2*SYSCLK + 2 ns,
* CSPulseWidth = 10 ns */
systim
=
1000000000
/
(
sysclk
/
1000
);
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"Blizzard systim %lu ps extif_clk_period %u div %d
\n
"
,
systim
,
blizzard
.
extif_clk_period
,
div
);
t
=
&
blizzard
.
reg_timings
;
memset
(
t
,
0
,
sizeof
(
*
t
));
t
->
clk_div
=
div
;
t
->
cs_on_time
=
0
;
t
->
we_on_time
=
round_to_extif_ticks
(
t
->
cs_on_time
+
2000
,
div
);
t
->
re_on_time
=
round_to_extif_ticks
(
t
->
cs_on_time
+
2000
,
div
);
t
->
access_time
=
round_to_extif_ticks
(
t
->
re_on_time
+
12200
,
div
);
t
->
we_off_time
=
round_to_extif_ticks
(
t
->
we_on_time
+
1000
,
div
);
t
->
re_off_time
=
round_to_extif_ticks
(
t
->
re_on_time
+
13000
,
div
);
t
->
cs_off_time
=
round_to_extif_ticks
(
t
->
re_off_time
+
1000
,
div
);
t
->
we_cycle_time
=
round_to_extif_ticks
(
2
*
systim
+
2000
,
div
);
if
(
t
->
we_cycle_time
<
t
->
we_off_time
)
t
->
we_cycle_time
=
t
->
we_off_time
;
t
->
re_cycle_time
=
round_to_extif_ticks
(
2
*
systim
+
2000
,
div
);
if
(
t
->
re_cycle_time
<
t
->
re_off_time
)
t
->
re_cycle_time
=
t
->
re_off_time
;
t
->
cs_pulse_width
=
0
;
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"[reg]cson %d csoff %d reon %d reoff %d
\n
"
,
t
->
cs_on_time
,
t
->
cs_off_time
,
t
->
re_on_time
,
t
->
re_off_time
);
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"[reg]weon %d weoff %d recyc %d wecyc %d
\n
"
,
t
->
we_on_time
,
t
->
we_off_time
,
t
->
re_cycle_time
,
t
->
we_cycle_time
);
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"[reg]rdaccess %d cspulse %d
\n
"
,
t
->
access_time
,
t
->
cs_pulse_width
);
return
blizzard
.
extif
->
convert_timings
(
t
);
}
static
int
calc_lut_timing
(
unsigned
long
sysclk
,
int
div
)
{
struct
extif_timings
*
t
;
unsigned
long
systim
;
/* CSOnTime 0, WEOnTime 2 ns, REOnTime 2 ns,
* AccessTime 2 ns + 4 * SYSCLK + 26 (lut),
* WEOffTime = WEOnTime + 1 ns,
* REOffTime = REOnTime + 4*SYSCLK + 26 ns (lut),
* CSOffTime = REOffTime + 1 ns
* ReadCycle = 2ns + 4*SYSCLK + 26 ns (lut),
* WriteCycle = 2*SYSCLK + 2 ns,
* CSPulseWidth = 10 ns */
systim
=
1000000000
/
(
sysclk
/
1000
);
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"Blizzard systim %lu ps extif_clk_period %u div %d
\n
"
,
systim
,
blizzard
.
extif_clk_period
,
div
);
t
=
&
blizzard
.
lut_timings
;
memset
(
t
,
0
,
sizeof
(
*
t
));
t
->
clk_div
=
div
;
t
->
cs_on_time
=
0
;
t
->
we_on_time
=
round_to_extif_ticks
(
t
->
cs_on_time
+
2000
,
div
);
t
->
re_on_time
=
round_to_extif_ticks
(
t
->
cs_on_time
+
2000
,
div
);
t
->
access_time
=
round_to_extif_ticks
(
t
->
re_on_time
+
4
*
systim
+
26000
,
div
);
t
->
we_off_time
=
round_to_extif_ticks
(
t
->
we_on_time
+
1000
,
div
);
t
->
re_off_time
=
round_to_extif_ticks
(
t
->
re_on_time
+
4
*
systim
+
26000
,
div
);
t
->
cs_off_time
=
round_to_extif_ticks
(
t
->
re_off_time
+
1000
,
div
);
t
->
we_cycle_time
=
round_to_extif_ticks
(
2
*
systim
+
2000
,
div
);
if
(
t
->
we_cycle_time
<
t
->
we_off_time
)
t
->
we_cycle_time
=
t
->
we_off_time
;
t
->
re_cycle_time
=
round_to_extif_ticks
(
2000
+
4
*
systim
+
26000
,
div
);
if
(
t
->
re_cycle_time
<
t
->
re_off_time
)
t
->
re_cycle_time
=
t
->
re_off_time
;
t
->
cs_pulse_width
=
0
;
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"[lut]cson %d csoff %d reon %d reoff %d
\n
"
,
t
->
cs_on_time
,
t
->
cs_off_time
,
t
->
re_on_time
,
t
->
re_off_time
);
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"[lut]weon %d weoff %d recyc %d wecyc %d
\n
"
,
t
->
we_on_time
,
t
->
we_off_time
,
t
->
re_cycle_time
,
t
->
we_cycle_time
);
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"[lut]rdaccess %d cspulse %d
\n
"
,
t
->
access_time
,
t
->
cs_pulse_width
);
return
blizzard
.
extif
->
convert_timings
(
t
);
}
static
int
calc_extif_timings
(
unsigned
long
sysclk
,
int
*
extif_mem_div
)
{
int
max_clk_div
;
int
div
;
blizzard
.
extif
->
get_clk_info
(
&
blizzard
.
extif_clk_period
,
&
max_clk_div
);
for
(
div
=
1
;
div
<=
max_clk_div
;
div
++
)
{
if
(
calc_reg_timing
(
sysclk
,
div
)
==
0
)
break
;
}
if
(
div
>
max_clk_div
)
{
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"reg timing failed
\n
"
);
goto
err
;
}
*
extif_mem_div
=
div
;
for
(
div
=
1
;
div
<=
max_clk_div
;
div
++
)
{
if
(
calc_lut_timing
(
sysclk
,
div
)
==
0
)
break
;
}
if
(
div
>
max_clk_div
)
goto
err
;
blizzard
.
extif_clk_div
=
div
;
return
0
;
err:
dev_err
(
blizzard
.
fbdev
->
dev
,
"can't setup timings
\n
"
);
return
-
1
;
}
static
void
calc_blizzard_clk_rates
(
unsigned
long
ext_clk
,
unsigned
long
*
sys_clk
,
unsigned
long
*
pix_clk
)
{
int
pix_clk_src
;
int
sys_div
=
0
,
sys_mul
=
0
;
int
pix_div
;
pix_clk_src
=
blizzard_read_reg
(
BLIZZARD_CLK_SRC
);
pix_div
=
((
pix_clk_src
>>
3
)
&
0x1f
)
+
1
;
if
((
pix_clk_src
&
(
0x3
<<
1
))
==
0
)
{
/* Source is the PLL */
sys_div
=
(
blizzard_read_reg
(
BLIZZARD_PLL_DIV
)
&
0x3f
)
+
1
;
sys_mul
=
blizzard_read_reg
(
BLIZZARD_PLL_CLOCK_SYNTH_0
);
sys_mul
|=
((
blizzard_read_reg
(
BLIZZARD_PLL_CLOCK_SYNTH_1
)
&
0x0f
)
<<
11
);
*
sys_clk
=
ext_clk
*
sys_mul
/
sys_div
;
}
else
/* else source is ext clk, or oscillator */
*
sys_clk
=
ext_clk
;
*
pix_clk
=
*
sys_clk
/
pix_div
;
/* HZ */
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"ext_clk %ld pix_src %d pix_div %d sys_div %d sys_mul %d
\n
"
,
ext_clk
,
pix_clk_src
&
(
0x3
<<
1
),
pix_div
,
sys_div
,
sys_mul
);
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"sys_clk %ld pix_clk %ld
\n
"
,
*
sys_clk
,
*
pix_clk
);
}
static
int
setup_tearsync
(
unsigned
long
pix_clk
,
int
extif_div
)
{
int
hdisp
,
vdisp
;
int
hndp
,
vndp
;
int
hsw
,
vsw
;
int
hs
,
vs
;
int
hs_pol_inv
,
vs_pol_inv
;
int
use_hsvs
,
use_ndp
;
u8
b
;
hsw
=
blizzard_read_reg
(
BLIZZARD_HSW
);
vsw
=
blizzard_read_reg
(
BLIZZARD_VSW
);
hs_pol_inv
=
!
(
hsw
&
0x80
);
vs_pol_inv
=
!
(
vsw
&
0x80
);
hsw
=
hsw
&
0x7f
;
vsw
=
vsw
&
0x3f
;
hdisp
=
blizzard_read_reg
(
BLIZZARD_HDISP
)
*
8
;
vdisp
=
blizzard_read_reg
(
BLIZZARD_VDISP0
)
+
((
blizzard_read_reg
(
BLIZZARD_VDISP1
)
&
0x3
)
<<
8
);
hndp
=
blizzard_read_reg
(
BLIZZARD_HNDP
)
&
0x3f
;
vndp
=
blizzard_read_reg
(
BLIZZARD_VNDP
);
/* time to transfer one pixel (16bpp) in ps */
blizzard
.
pix_tx_time
=
blizzard
.
reg_timings
.
we_cycle_time
;
if
(
blizzard
.
extif
->
get_max_tx_rate
!=
NULL
)
{
/* The external interface might have a rate limitation,
* if so, we have to maximize our transfer rate.
*/
unsigned
long
min_tx_time
;
unsigned
long
max_tx_rate
=
blizzard
.
extif
->
get_max_tx_rate
();
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"max_tx_rate %ld HZ
\n
"
,
max_tx_rate
);
min_tx_time
=
1000000000
/
(
max_tx_rate
/
1000
);
/* ps */
if
(
blizzard
.
pix_tx_time
<
min_tx_time
)
blizzard
.
pix_tx_time
=
min_tx_time
;
}
/* time to update one line in ps */
blizzard
.
line_upd_time
=
(
hdisp
+
hndp
)
*
1000000
/
(
pix_clk
/
1000
);
blizzard
.
line_upd_time
*=
1000
;
if
(
hdisp
*
blizzard
.
pix_tx_time
>
blizzard
.
line_upd_time
)
/* transfer speed too low, we might have to use both
* HS and VS */
use_hsvs
=
1
;
else
/* decent transfer speed, we'll always use only VS */
use_hsvs
=
0
;
if
(
use_hsvs
&&
(
hs_pol_inv
||
vs_pol_inv
))
{
/* HS or'ed with VS doesn't work, use the active high
* TE signal based on HNDP / VNDP */
use_ndp
=
1
;
hs_pol_inv
=
0
;
vs_pol_inv
=
0
;
hs
=
hndp
;
vs
=
vndp
;
}
else
{
/* Use HS or'ed with VS as a TE signal if both are needed
* or VNDP if only vsync is needed. */
use_ndp
=
0
;
hs
=
hsw
;
vs
=
vsw
;
if
(
!
use_hsvs
)
{
hs_pol_inv
=
0
;
vs_pol_inv
=
0
;
}
}
hs
=
hs
*
1000000
/
(
pix_clk
/
1000
);
/* ps */
hs
*=
1000
;
vs
=
vs
*
(
hdisp
+
hndp
)
*
1000000
/
(
pix_clk
/
1000
);
/* ps */
vs
*=
1000
;
if
(
vs
<=
hs
)
return
-
EDOM
;
/* set VS to 120% of HS to minimize VS detection time */
vs
=
hs
*
12
/
10
;
/* minimize HS too */
if
(
hs
>
10000
)
hs
=
10000
;
b
=
blizzard_read_reg
(
BLIZZARD_NDISP_CTRL_STATUS
);
b
&=
~
0x3
;
b
|=
use_hsvs
?
1
:
0
;
b
|=
(
use_ndp
&&
use_hsvs
)
?
0
:
2
;
blizzard_write_reg
(
BLIZZARD_NDISP_CTRL_STATUS
,
b
);
blizzard
.
vsync_only
=
!
use_hsvs
;
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"pix_clk %ld HZ pix_tx_time %ld ps line_upd_time %ld ps
\n
"
,
pix_clk
,
blizzard
.
pix_tx_time
,
blizzard
.
line_upd_time
);
dev_dbg
(
blizzard
.
fbdev
->
dev
,
"hs %d ps vs %d ps mode %d vsync_only %d
\n
"
,
hs
,
vs
,
b
&
0x3
,
!
use_hsvs
);
return
blizzard
.
extif
->
setup_tearsync
(
1
,
hs
,
vs
,
hs_pol_inv
,
vs_pol_inv
,
extif_div
);
}
static
void
blizzard_get_caps
(
int
plane
,
struct
omapfb_caps
*
caps
)
{
blizzard
.
int_ctrl
->
get_caps
(
plane
,
caps
);
caps
->
ctrl
|=
OMAPFB_CAPS_MANUAL_UPDATE
|
OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE
|
OMAPFB_CAPS_WINDOW_SCALE
|
OMAPFB_CAPS_WINDOW_OVERLAY
|
OMAPFB_CAPS_WINDOW_ROTATE
;
if
(
blizzard
.
te_connected
)
caps
->
ctrl
|=
OMAPFB_CAPS_TEARSYNC
;
caps
->
wnd_color
|=
(
1
<<
OMAPFB_COLOR_RGB565
)
|
(
1
<<
OMAPFB_COLOR_YUV420
);
}
static
void
_save_regs
(
const
struct
blizzard_reg_list
*
list
,
int
cnt
)
{
int
i
;
for
(
i
=
0
;
i
<
cnt
;
i
++
,
list
++
)
{
int
reg
;
for
(
reg
=
list
->
start
;
reg
<=
list
->
end
;
reg
+=
2
)
blizzard_reg_cache
[
reg
/
2
]
=
blizzard_read_reg
(
reg
);
}
}
static
void
_restore_regs
(
const
struct
blizzard_reg_list
*
list
,
int
cnt
)
{
int
i
;
for
(
i
=
0
;
i
<
cnt
;
i
++
,
list
++
)
{
int
reg
;
for
(
reg
=
list
->
start
;
reg
<=
list
->
end
;
reg
+=
2
)
blizzard_write_reg
(
reg
,
blizzard_reg_cache
[
reg
/
2
]);
}
}
static
void
blizzard_save_all_regs
(
void
)
{
_save_regs
(
blizzard_pll_regs
,
ARRAY_SIZE
(
blizzard_pll_regs
));
_save_regs
(
blizzard_gen_regs
,
ARRAY_SIZE
(
blizzard_gen_regs
));
}
static
void
blizzard_restore_pll_regs
(
void
)
{
_restore_regs
(
blizzard_pll_regs
,
ARRAY_SIZE
(
blizzard_pll_regs
));
}
static
void
blizzard_restore_gen_regs
(
void
)
{
_restore_regs
(
blizzard_gen_regs
,
ARRAY_SIZE
(
blizzard_gen_regs
));
}
static
void
blizzard_suspend
(
void
)
{
u32
l
;
unsigned
long
tmo
;
if
(
blizzard
.
last_color_mode
)
{
update_full_screen
();
blizzard_sync
();
}
blizzard
.
update_mode_before_suspend
=
blizzard
.
update_mode
;
/* the following will disable clocks as well */
blizzard_set_update_mode
(
OMAPFB_UPDATE_DISABLED
);
blizzard_save_all_regs
();
blizzard_stop_sdram
();
l
=
blizzard_read_reg
(
BLIZZARD_POWER_SAVE
);
/* Standby, Sleep. We assume we use an external clock. */
l
|=
0x03
;
blizzard_write_reg
(
BLIZZARD_POWER_SAVE
,
l
);
tmo
=
jiffies
+
msecs_to_jiffies
(
100
);
while
(
!
(
blizzard_read_reg
(
BLIZZARD_PLL_MODE
)
&
(
1
<<
1
)))
{
if
(
time_after
(
jiffies
,
tmo
))
{
dev_err
(
blizzard
.
fbdev
->
dev
,
"s1d1374x: sleep timeout, stopping PLL manually
\n
"
);
l
=
blizzard_read_reg
(
BLIZZARD_PLL_MODE
);
l
&=
~
0x03
;
/* Disable PLL, counter function */
l
|=
0x2
;
blizzard_write_reg
(
BLIZZARD_PLL_MODE
,
l
);
break
;
}
msleep
(
1
);
}
if
(
blizzard
.
power_down
!=
NULL
)
blizzard
.
power_down
(
blizzard
.
fbdev
->
dev
);
}
static
void
blizzard_resume
(
void
)
{
u32
l
;
if
(
blizzard
.
power_up
!=
NULL
)
blizzard
.
power_up
(
blizzard
.
fbdev
->
dev
);
l
=
blizzard_read_reg
(
BLIZZARD_POWER_SAVE
);
/* Standby, Sleep */
l
&=
~
0x03
;
blizzard_write_reg
(
BLIZZARD_POWER_SAVE
,
l
);
blizzard_restore_pll_regs
();
l
=
blizzard_read_reg
(
BLIZZARD_PLL_MODE
);
l
&=
~
0x03
;
/* Enable PLL, counter function */
l
|=
0x1
;
blizzard_write_reg
(
BLIZZARD_PLL_MODE
,
l
);
while
(
!
(
blizzard_read_reg
(
BLIZZARD_PLL_DIV
)
&
(
1
<<
7
)))
msleep
(
1
);
blizzard_restart_sdram
();
blizzard_restore_gen_regs
();
/* Enable display */
blizzard_write_reg
(
BLIZZARD_DISPLAY_MODE
,
0x01
);
/* the following will enable clocks as necessary */
blizzard_set_update_mode
(
blizzard
.
update_mode_before_suspend
);
/* Force a background update */
blizzard
.
zoom_on
=
1
;
update_full_screen
();
blizzard_sync
();
}
static
int
blizzard_init
(
struct
omapfb_device
*
fbdev
,
int
ext_mode
,
struct
omapfb_mem_desc
*
req_vram
)
{
int
r
=
0
,
i
;
u8
rev
,
conf
;
unsigned
long
ext_clk
;
int
extif_div
;
unsigned
long
sys_clk
,
pix_clk
;
struct
omapfb_platform_data
*
omapfb_conf
;
struct
blizzard_platform_data
*
ctrl_conf
;
blizzard
.
fbdev
=
fbdev
;
BUG_ON
(
!
fbdev
->
ext_if
||
!
fbdev
->
int_ctrl
);
blizzard
.
fbdev
=
fbdev
;
blizzard
.
extif
=
fbdev
->
ext_if
;
blizzard
.
int_ctrl
=
fbdev
->
int_ctrl
;
omapfb_conf
=
fbdev
->
dev
->
platform_data
;
ctrl_conf
=
omapfb_conf
->
ctrl_platform_data
;
if
(
ctrl_conf
==
NULL
||
ctrl_conf
->
get_clock_rate
==
NULL
)
{
dev_err
(
fbdev
->
dev
,
"s1d1374x: missing platform data
\n
"
);
r
=
-
ENOENT
;
goto
err1
;
}
blizzard
.
power_down
=
ctrl_conf
->
power_down
;
blizzard
.
power_up
=
ctrl_conf
->
power_up
;
spin_lock_init
(
&
blizzard
.
req_lock
);
if
((
r
=
blizzard
.
int_ctrl
->
init
(
fbdev
,
1
,
req_vram
))
<
0
)
goto
err1
;
if
((
r
=
blizzard
.
extif
->
init
(
fbdev
))
<
0
)
goto
err2
;
blizzard_ctrl
.
set_color_key
=
blizzard
.
int_ctrl
->
set_color_key
;
blizzard_ctrl
.
get_color_key
=
blizzard
.
int_ctrl
->
get_color_key
;
blizzard_ctrl
.
setup_mem
=
blizzard
.
int_ctrl
->
setup_mem
;
blizzard_ctrl
.
mmap
=
blizzard
.
int_ctrl
->
mmap
;
ext_clk
=
ctrl_conf
->
get_clock_rate
(
fbdev
->
dev
);
if
((
r
=
calc_extif_timings
(
ext_clk
,
&
extif_div
))
<
0
)
goto
err3
;
set_extif_timings
(
&
blizzard
.
reg_timings
);
if
(
blizzard
.
power_up
!=
NULL
)
blizzard
.
power_up
(
fbdev
->
dev
);
calc_blizzard_clk_rates
(
ext_clk
,
&
sys_clk
,
&
pix_clk
);
if
((
r
=
calc_extif_timings
(
sys_clk
,
&
extif_div
))
<
0
)
goto
err3
;
set_extif_timings
(
&
blizzard
.
reg_timings
);
if
(
!
(
blizzard_read_reg
(
BLIZZARD_PLL_DIV
)
&
0x80
))
{
dev_err
(
fbdev
->
dev
,
"controller not initialized by the bootloader
\n
"
);
r
=
-
ENODEV
;
goto
err3
;
}
if
(
ctrl_conf
->
te_connected
)
{
if
((
r
=
setup_tearsync
(
pix_clk
,
extif_div
))
<
0
)
goto
err3
;
blizzard
.
te_connected
=
1
;
}
rev
=
blizzard_read_reg
(
BLIZZARD_REV_CODE
);
conf
=
blizzard_read_reg
(
BLIZZARD_CONFIG
);
switch
(
rev
&
0xfc
)
{
case
0x9c
:
blizzard
.
version
=
BLIZZARD_VERSION_S1D13744
;
pr_info
(
"omapfb: s1d13744 LCD controller rev %d "
"initialized (CNF pins %x)
\n
"
,
rev
&
0x03
,
conf
&
0x07
);
break
;
case
0xa4
:
blizzard
.
version
=
BLIZZARD_VERSION_S1D13745
;
pr_info
(
"omapfb: s1d13745 LCD controller rev %d "
"initialized (CNF pins %x)
\n
"
,
rev
&
0x03
,
conf
&
0x07
);
break
;
default:
dev_err
(
fbdev
->
dev
,
"invalid s1d1374x revision %02x
\n
"
,
rev
);
r
=
-
ENODEV
;
goto
err3
;
}
blizzard
.
max_transmit_size
=
blizzard
.
extif
->
max_transmit_size
;
blizzard
.
update_mode
=
OMAPFB_UPDATE_DISABLED
;
blizzard
.
auto_update_window
.
x
=
0
;
blizzard
.
auto_update_window
.
y
=
0
;
blizzard
.
auto_update_window
.
width
=
fbdev
->
panel
->
x_res
;
blizzard
.
auto_update_window
.
height
=
fbdev
->
panel
->
y_res
;
blizzard
.
auto_update_window
.
out_x
=
0
;
blizzard
.
auto_update_window
.
out_y
=
0
;
blizzard
.
auto_update_window
.
out_width
=
fbdev
->
panel
->
x_res
;
blizzard
.
auto_update_window
.
out_height
=
fbdev
->
panel
->
y_res
;
blizzard
.
auto_update_window
.
format
=
0
;
blizzard
.
screen_width
=
fbdev
->
panel
->
x_res
;
blizzard
.
screen_height
=
fbdev
->
panel
->
y_res
;
init_timer
(
&
blizzard
.
auto_update_timer
);
blizzard
.
auto_update_timer
.
function
=
blizzard_update_window_auto
;
blizzard
.
auto_update_timer
.
data
=
0
;
INIT_LIST_HEAD
(
&
blizzard
.
free_req_list
);
INIT_LIST_HEAD
(
&
blizzard
.
pending_req_list
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
blizzard
.
req_pool
);
i
++
)
list_add
(
&
blizzard
.
req_pool
[
i
].
entry
,
&
blizzard
.
free_req_list
);
BUG_ON
(
i
<=
IRQ_REQ_POOL_SIZE
);
sema_init
(
&
blizzard
.
req_sema
,
i
-
IRQ_REQ_POOL_SIZE
);
return
0
;
err3:
if
(
blizzard
.
power_down
!=
NULL
)
blizzard
.
power_down
(
fbdev
->
dev
);
blizzard
.
extif
->
cleanup
();
err2:
blizzard
.
int_ctrl
->
cleanup
();
err1:
return
r
;
}
static
void
blizzard_cleanup
(
void
)
{
blizzard_set_update_mode
(
OMAPFB_UPDATE_DISABLED
);
blizzard
.
extif
->
cleanup
();
blizzard
.
int_ctrl
->
cleanup
();
if
(
blizzard
.
power_down
!=
NULL
)
blizzard
.
power_down
(
blizzard
.
fbdev
->
dev
);
}
struct
lcd_ctrl
blizzard_ctrl
=
{
.
name
=
"blizzard"
,
.
init
=
blizzard_init
,
.
cleanup
=
blizzard_cleanup
,
.
bind_client
=
blizzard_bind_client
,
.
get_caps
=
blizzard_get_caps
,
.
set_update_mode
=
blizzard_set_update_mode
,
.
get_update_mode
=
blizzard_get_update_mode
,
.
setup_plane
=
blizzard_setup_plane
,
.
set_scale
=
blizzard_set_scale
,
.
enable_plane
=
blizzard_enable_plane
,
.
set_rotate
=
blizzard_set_rotate
,
.
update_window
=
blizzard_update_window_async
,
.
sync
=
blizzard_sync
,
.
suspend
=
blizzard_suspend
,
.
resume
=
blizzard_resume
,
};
drivers/video/omap/dispc.c
deleted
100644 → 0
View file @
f413070e
/*
* OMAP2 display controller support
*
* Copyright (C) 2005 Nokia Corporation
* Author: Imre Deak <imre.deak@nokia.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* 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, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <plat/sram.h>
#include <plat/board.h>
#include "omapfb.h"
#include "dispc.h"
#define MODULE_NAME "dispc"
#define DSS_BASE 0x48050000
#define DSS_SYSCONFIG 0x0010
#define DISPC_BASE 0x48050400
/* DISPC common */
#define DISPC_REVISION 0x0000
#define DISPC_SYSCONFIG 0x0010
#define DISPC_SYSSTATUS 0x0014
#define DISPC_IRQSTATUS 0x0018
#define DISPC_IRQENABLE 0x001C
#define DISPC_CONTROL 0x0040
#define DISPC_CONFIG 0x0044
#define DISPC_CAPABLE 0x0048
#define DISPC_DEFAULT_COLOR0 0x004C
#define DISPC_DEFAULT_COLOR1 0x0050
#define DISPC_TRANS_COLOR0 0x0054
#define DISPC_TRANS_COLOR1 0x0058
#define DISPC_LINE_STATUS 0x005C
#define DISPC_LINE_NUMBER 0x0060
#define DISPC_TIMING_H 0x0064
#define DISPC_TIMING_V 0x0068
#define DISPC_POL_FREQ 0x006C
#define DISPC_DIVISOR 0x0070
#define DISPC_SIZE_DIG 0x0078
#define DISPC_SIZE_LCD 0x007C
#define DISPC_DATA_CYCLE1 0x01D4
#define DISPC_DATA_CYCLE2 0x01D8
#define DISPC_DATA_CYCLE3 0x01DC
/* DISPC GFX plane */
#define DISPC_GFX_BA0 0x0080
#define DISPC_GFX_BA1 0x0084
#define DISPC_GFX_POSITION 0x0088
#define DISPC_GFX_SIZE 0x008C
#define DISPC_GFX_ATTRIBUTES 0x00A0
#define DISPC_GFX_FIFO_THRESHOLD 0x00A4
#define DISPC_GFX_FIFO_SIZE_STATUS 0x00A8
#define DISPC_GFX_ROW_INC 0x00AC
#define DISPC_GFX_PIXEL_INC 0x00B0
#define DISPC_GFX_WINDOW_SKIP 0x00B4
#define DISPC_GFX_TABLE_BA 0x00B8
/* DISPC Video plane 1/2 */
#define DISPC_VID1_BASE 0x00BC
#define DISPC_VID2_BASE 0x014C
/* Offsets into DISPC_VID1/2_BASE */
#define DISPC_VID_BA0 0x0000
#define DISPC_VID_BA1 0x0004
#define DISPC_VID_POSITION 0x0008
#define DISPC_VID_SIZE 0x000C
#define DISPC_VID_ATTRIBUTES 0x0010
#define DISPC_VID_FIFO_THRESHOLD 0x0014
#define DISPC_VID_FIFO_SIZE_STATUS 0x0018
#define DISPC_VID_ROW_INC 0x001C
#define DISPC_VID_PIXEL_INC 0x0020
#define DISPC_VID_FIR 0x0024
#define DISPC_VID_PICTURE_SIZE 0x0028
#define DISPC_VID_ACCU0 0x002C
#define DISPC_VID_ACCU1 0x0030
/* 8 elements in 8 byte increments */
#define DISPC_VID_FIR_COEF_H0 0x0034
/* 8 elements in 8 byte increments */
#define DISPC_VID_FIR_COEF_HV0 0x0038
/* 5 elements in 4 byte increments */
#define DISPC_VID_CONV_COEF0 0x0074
#define DISPC_IRQ_FRAMEMASK 0x0001
#define DISPC_IRQ_VSYNC 0x0002
#define DISPC_IRQ_EVSYNC_EVEN 0x0004
#define DISPC_IRQ_EVSYNC_ODD 0x0008
#define DISPC_IRQ_ACBIAS_COUNT_STAT 0x0010
#define DISPC_IRQ_PROG_LINE_NUM 0x0020
#define DISPC_IRQ_GFX_FIFO_UNDERFLOW 0x0040
#define DISPC_IRQ_GFX_END_WIN 0x0080
#define DISPC_IRQ_PAL_GAMMA_MASK 0x0100
#define DISPC_IRQ_OCP_ERR 0x0200
#define DISPC_IRQ_VID1_FIFO_UNDERFLOW 0x0400
#define DISPC_IRQ_VID1_END_WIN 0x0800
#define DISPC_IRQ_VID2_FIFO_UNDERFLOW 0x1000
#define DISPC_IRQ_VID2_END_WIN 0x2000
#define DISPC_IRQ_SYNC_LOST 0x4000
#define DISPC_IRQ_MASK_ALL 0x7fff
#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
DISPC_IRQ_SYNC_LOST)
#define RFBI_CONTROL 0x48050040
#define MAX_PALETTE_SIZE (256 * 16)
#define FLD_MASK(pos, len) (((1 << len) - 1) << pos)
#define MOD_REG_FLD(reg, mask, val) \
dispc_write_reg((reg), (dispc_read_reg(reg) & ~(mask)) | (val));
#define OMAP2_SRAM_START 0x40200000
/* Maximum size, in reality this is smaller if SRAM is partially locked. */
#define OMAP2_SRAM_SIZE 0xa0000
/* 640k */
/* We support the SDRAM / SRAM types. See OMAPFB_PLANE_MEMTYPE_* in omapfb.h */
#define DISPC_MEMTYPE_NUM 2
#define RESMAP_SIZE(_page_cnt) \
((_page_cnt + (sizeof(unsigned long) * 8) - 1) / 8)
#define RESMAP_PTR(_res_map, _page_nr) \
(((_res_map)->map) + (_page_nr) / (sizeof(unsigned long) * 8))
#define RESMAP_MASK(_page_nr) \
(1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1)))
struct
resmap
{
unsigned
long
start
;
unsigned
page_cnt
;
unsigned
long
*
map
;
};
#define MAX_IRQ_HANDLERS 4
static
struct
{
void
__iomem
*
base
;
struct
omapfb_mem_desc
mem_desc
;
struct
resmap
*
res_map
[
DISPC_MEMTYPE_NUM
];
atomic_t
map_count
[
OMAPFB_PLANE_NUM
];
dma_addr_t
palette_paddr
;
void
*
palette_vaddr
;
int
ext_mode
;
struct
{
u32
irq_mask
;
void
(
*
callback
)(
void
*
);
void
*
data
;
}
irq_handlers
[
MAX_IRQ_HANDLERS
];
struct
completion
frame_done
;
int
fir_hinc
[
OMAPFB_PLANE_NUM
];
int
fir_vinc
[
OMAPFB_PLANE_NUM
];
struct
clk
*
dss_ick
,
*
dss1_fck
;
struct
clk
*
dss_54m_fck
;
enum
omapfb_update_mode
update_mode
;
struct
omapfb_device
*
fbdev
;
struct
omapfb_color_key
color_key
;
}
dispc
;
static
void
enable_lcd_clocks
(
int
enable
);
static
void
inline
dispc_write_reg
(
int
idx
,
u32
val
)
{
__raw_writel
(
val
,
dispc
.
base
+
idx
);
}
static
u32
inline
dispc_read_reg
(
int
idx
)
{
u32
l
=
__raw_readl
(
dispc
.
base
+
idx
);
return
l
;
}
/* Select RFBI or bypass mode */
static
void
enable_rfbi_mode
(
int
enable
)
{
void
__iomem
*
rfbi_control
;
u32
l
;
l
=
dispc_read_reg
(
DISPC_CONTROL
);
/* Enable RFBI, GPIO0/1 */
l
&=
~
((
1
<<
11
)
|
(
1
<<
15
)
|
(
1
<<
16
));
l
|=
enable
?
(
1
<<
11
)
:
0
;
/* RFBI En: GPIO0/1=10 RFBI Dis: GPIO0/1=11 */
l
|=
1
<<
15
;
l
|=
enable
?
0
:
(
1
<<
16
);
dispc_write_reg
(
DISPC_CONTROL
,
l
);
/* Set bypass mode in RFBI module */
rfbi_control
=
ioremap
(
RFBI_CONTROL
,
SZ_1K
);
if
(
!
rfbi_control
)
{
pr_err
(
"Unable to ioremap rfbi_control
\n
"
);
return
;
}
l
=
__raw_readl
(
rfbi_control
);
l
|=
enable
?
0
:
(
1
<<
1
);
__raw_writel
(
l
,
rfbi_control
);
iounmap
(
rfbi_control
);
}
static
void
set_lcd_data_lines
(
int
data_lines
)
{
u32
l
;
int
code
=
0
;
switch
(
data_lines
)
{
case
12
:
code
=
0
;
break
;
case
16
:
code
=
1
;
break
;
case
18
:
code
=
2
;
break
;
case
24
:
code
=
3
;
break
;
default:
BUG
();
}
l
=
dispc_read_reg
(
DISPC_CONTROL
);
l
&=
~
(
0x03
<<
8
);
l
|=
code
<<
8
;
dispc_write_reg
(
DISPC_CONTROL
,
l
);
}
static
void
set_load_mode
(
int
mode
)
{
BUG_ON
(
mode
&
~
(
DISPC_LOAD_CLUT_ONLY
|
DISPC_LOAD_FRAME_ONLY
|
DISPC_LOAD_CLUT_ONCE_FRAME
));
MOD_REG_FLD
(
DISPC_CONFIG
,
0x03
<<
1
,
mode
<<
1
);
}
void
omap_dispc_set_lcd_size
(
int
x
,
int
y
)
{
BUG_ON
((
x
>
(
1
<<
11
))
||
(
y
>
(
1
<<
11
)));
enable_lcd_clocks
(
1
);
MOD_REG_FLD
(
DISPC_SIZE_LCD
,
FLD_MASK
(
16
,
11
)
|
FLD_MASK
(
0
,
11
),
((
y
-
1
)
<<
16
)
|
(
x
-
1
));
enable_lcd_clocks
(
0
);
}
EXPORT_SYMBOL
(
omap_dispc_set_lcd_size
);
void
omap_dispc_set_digit_size
(
int
x
,
int
y
)
{
BUG_ON
((
x
>
(
1
<<
11
))
||
(
y
>
(
1
<<
11
)));
enable_lcd_clocks
(
1
);
MOD_REG_FLD
(
DISPC_SIZE_DIG
,
FLD_MASK
(
16
,
11
)
|
FLD_MASK
(
0
,
11
),
((
y
-
1
)
<<
16
)
|
(
x
-
1
));
enable_lcd_clocks
(
0
);
}
EXPORT_SYMBOL
(
omap_dispc_set_digit_size
);
static
void
setup_plane_fifo
(
int
plane
,
int
ext_mode
)
{
const
u32
ftrs_reg
[]
=
{
DISPC_GFX_FIFO_THRESHOLD
,
DISPC_VID1_BASE
+
DISPC_VID_FIFO_THRESHOLD
,
DISPC_VID2_BASE
+
DISPC_VID_FIFO_THRESHOLD
};
const
u32
fsz_reg
[]
=
{
DISPC_GFX_FIFO_SIZE_STATUS
,
DISPC_VID1_BASE
+
DISPC_VID_FIFO_SIZE_STATUS
,
DISPC_VID2_BASE
+
DISPC_VID_FIFO_SIZE_STATUS
};
int
low
,
high
;
u32
l
;
BUG_ON
(
plane
>
2
);
l
=
dispc_read_reg
(
fsz_reg
[
plane
]);
l
&=
FLD_MASK
(
0
,
11
);
if
(
ext_mode
)
{
low
=
l
*
3
/
4
;
high
=
l
;
}
else
{
low
=
l
/
4
;
high
=
l
*
3
/
4
;
}
MOD_REG_FLD
(
ftrs_reg
[
plane
],
FLD_MASK
(
16
,
12
)
|
FLD_MASK
(
0
,
12
),
(
high
<<
16
)
|
low
);
}
void
omap_dispc_enable_lcd_out
(
int
enable
)
{
enable_lcd_clocks
(
1
);
MOD_REG_FLD
(
DISPC_CONTROL
,
1
,
enable
?
1
:
0
);
enable_lcd_clocks
(
0
);
}
EXPORT_SYMBOL
(
omap_dispc_enable_lcd_out
);
void
omap_dispc_enable_digit_out
(
int
enable
)
{
enable_lcd_clocks
(
1
);
MOD_REG_FLD
(
DISPC_CONTROL
,
1
<<
1
,
enable
?
1
<<
1
:
0
);
enable_lcd_clocks
(
0
);
}
EXPORT_SYMBOL
(
omap_dispc_enable_digit_out
);
static
inline
int
_setup_plane
(
int
plane
,
int
channel_out
,
u32
paddr
,
int
screen_width
,
int
pos_x
,
int
pos_y
,
int
width
,
int
height
,
int
color_mode
)
{
const
u32
at_reg
[]
=
{
DISPC_GFX_ATTRIBUTES
,
DISPC_VID1_BASE
+
DISPC_VID_ATTRIBUTES
,
DISPC_VID2_BASE
+
DISPC_VID_ATTRIBUTES
};
const
u32
ba_reg
[]
=
{
DISPC_GFX_BA0
,
DISPC_VID1_BASE
+
DISPC_VID_BA0
,
DISPC_VID2_BASE
+
DISPC_VID_BA0
};
const
u32
ps_reg
[]
=
{
DISPC_GFX_POSITION
,
DISPC_VID1_BASE
+
DISPC_VID_POSITION
,
DISPC_VID2_BASE
+
DISPC_VID_POSITION
};
const
u32
sz_reg
[]
=
{
DISPC_GFX_SIZE
,
DISPC_VID1_BASE
+
DISPC_VID_PICTURE_SIZE
,
DISPC_VID2_BASE
+
DISPC_VID_PICTURE_SIZE
};
const
u32
ri_reg
[]
=
{
DISPC_GFX_ROW_INC
,
DISPC_VID1_BASE
+
DISPC_VID_ROW_INC
,
DISPC_VID2_BASE
+
DISPC_VID_ROW_INC
};
const
u32
vs_reg
[]
=
{
0
,
DISPC_VID1_BASE
+
DISPC_VID_SIZE
,
DISPC_VID2_BASE
+
DISPC_VID_SIZE
};
int
chout_shift
,
burst_shift
;
int
chout_val
;
int
color_code
;
int
bpp
;
int
cconv_en
;
int
set_vsize
;
u32
l
;
#ifdef VERBOSE
dev_dbg
(
dispc
.
fbdev
->
dev
,
"plane %d channel %d paddr %#08x scr_width %d"
" pos_x %d pos_y %d width %d height %d color_mode %d
\n
"
,
plane
,
channel_out
,
paddr
,
screen_width
,
pos_x
,
pos_y
,
width
,
height
,
color_mode
);
#endif
set_vsize
=
0
;
switch
(
plane
)
{
case
OMAPFB_PLANE_GFX
:
burst_shift
=
6
;
chout_shift
=
8
;
break
;
case
OMAPFB_PLANE_VID1
:
case
OMAPFB_PLANE_VID2
:
burst_shift
=
14
;
chout_shift
=
16
;
set_vsize
=
1
;
break
;
default:
return
-
EINVAL
;
}
switch
(
channel_out
)
{
case
OMAPFB_CHANNEL_OUT_LCD
:
chout_val
=
0
;
break
;
case
OMAPFB_CHANNEL_OUT_DIGIT
:
chout_val
=
1
;
break
;
default:
return
-
EINVAL
;
}
cconv_en
=
0
;
switch
(
color_mode
)
{
case
OMAPFB_COLOR_RGB565
:
color_code
=
DISPC_RGB_16_BPP
;
bpp
=
16
;
break
;
case
OMAPFB_COLOR_YUV422
:
if
(
plane
==
0
)
return
-
EINVAL
;
color_code
=
DISPC_UYVY_422
;
cconv_en
=
1
;
bpp
=
16
;
break
;
case
OMAPFB_COLOR_YUY422
:
if
(
plane
==
0
)
return
-
EINVAL
;
color_code
=
DISPC_YUV2_422
;
cconv_en
=
1
;
bpp
=
16
;
break
;
default:
return
-
EINVAL
;
}
l
=
dispc_read_reg
(
at_reg
[
plane
]);
l
&=
~
(
0x0f
<<
1
);
l
|=
color_code
<<
1
;
l
&=
~
(
1
<<
9
);
l
|=
cconv_en
<<
9
;
l
&=
~
(
0x03
<<
burst_shift
);
l
|=
DISPC_BURST_8x32
<<
burst_shift
;
l
&=
~
(
1
<<
chout_shift
);
l
|=
chout_val
<<
chout_shift
;
dispc_write_reg
(
at_reg
[
plane
],
l
);
dispc_write_reg
(
ba_reg
[
plane
],
paddr
);
MOD_REG_FLD
(
ps_reg
[
plane
],
FLD_MASK
(
16
,
11
)
|
FLD_MASK
(
0
,
11
),
(
pos_y
<<
16
)
|
pos_x
);
MOD_REG_FLD
(
sz_reg
[
plane
],
FLD_MASK
(
16
,
11
)
|
FLD_MASK
(
0
,
11
),
((
height
-
1
)
<<
16
)
|
(
width
-
1
));
if
(
set_vsize
)
{
/* Set video size if set_scale hasn't set it */
if
(
!
dispc
.
fir_vinc
[
plane
])
MOD_REG_FLD
(
vs_reg
[
plane
],
FLD_MASK
(
16
,
11
),
(
height
-
1
)
<<
16
);
if
(
!
dispc
.
fir_hinc
[
plane
])
MOD_REG_FLD
(
vs_reg
[
plane
],
FLD_MASK
(
0
,
11
),
width
-
1
);
}
dispc_write_reg
(
ri_reg
[
plane
],
(
screen_width
-
width
)
*
bpp
/
8
+
1
);
return
height
*
screen_width
*
bpp
/
8
;
}
static
int
omap_dispc_setup_plane
(
int
plane
,
int
channel_out
,
unsigned
long
offset
,
int
screen_width
,
int
pos_x
,
int
pos_y
,
int
width
,
int
height
,
int
color_mode
)
{
u32
paddr
;
int
r
;
if
((
unsigned
)
plane
>
dispc
.
mem_desc
.
region_cnt
)
return
-
EINVAL
;
paddr
=
dispc
.
mem_desc
.
region
[
plane
].
paddr
+
offset
;
enable_lcd_clocks
(
1
);
r
=
_setup_plane
(
plane
,
channel_out
,
paddr
,
screen_width
,
pos_x
,
pos_y
,
width
,
height
,
color_mode
);
enable_lcd_clocks
(
0
);
return
r
;
}
static
void
write_firh_reg
(
int
plane
,
int
reg
,
u32
value
)
{
u32
base
;
if
(
plane
==
1
)
base
=
DISPC_VID1_BASE
+
DISPC_VID_FIR_COEF_H0
;
else
base
=
DISPC_VID2_BASE
+
DISPC_VID_FIR_COEF_H0
;
dispc_write_reg
(
base
+
reg
*
8
,
value
);
}
static
void
write_firhv_reg
(
int
plane
,
int
reg
,
u32
value
)
{
u32
base
;
if
(
plane
==
1
)
base
=
DISPC_VID1_BASE
+
DISPC_VID_FIR_COEF_HV0
;
else
base
=
DISPC_VID2_BASE
+
DISPC_VID_FIR_COEF_HV0
;
dispc_write_reg
(
base
+
reg
*
8
,
value
);
}
static
void
set_upsampling_coef_table
(
int
plane
)
{
const
u32
coef
[][
2
]
=
{
{
0x00800000
,
0x00800000
},
{
0x0D7CF800
,
0x037B02FF
},
{
0x1E70F5FF
,
0x0C6F05FE
},
{
0x335FF5FE
,
0x205907FB
},
{
0xF74949F7
,
0x00404000
},
{
0xF55F33FB
,
0x075920FE
},
{
0xF5701EFE
,
0x056F0CFF
},
{
0xF87C0DFF
,
0x027B0300
},
};
int
i
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
write_firh_reg
(
plane
,
i
,
coef
[
i
][
0
]);
write_firhv_reg
(
plane
,
i
,
coef
[
i
][
1
]);
}
}
static
int
omap_dispc_set_scale
(
int
plane
,
int
orig_width
,
int
orig_height
,
int
out_width
,
int
out_height
)
{
const
u32
at_reg
[]
=
{
0
,
DISPC_VID1_BASE
+
DISPC_VID_ATTRIBUTES
,
DISPC_VID2_BASE
+
DISPC_VID_ATTRIBUTES
};
const
u32
vs_reg
[]
=
{
0
,
DISPC_VID1_BASE
+
DISPC_VID_SIZE
,
DISPC_VID2_BASE
+
DISPC_VID_SIZE
};
const
u32
fir_reg
[]
=
{
0
,
DISPC_VID1_BASE
+
DISPC_VID_FIR
,
DISPC_VID2_BASE
+
DISPC_VID_FIR
};
u32
l
;
int
fir_hinc
;
int
fir_vinc
;
if
((
unsigned
)
plane
>
OMAPFB_PLANE_NUM
)
return
-
ENODEV
;
if
(
plane
==
OMAPFB_PLANE_GFX
&&
(
out_width
!=
orig_width
||
out_height
!=
orig_height
))
return
-
EINVAL
;
enable_lcd_clocks
(
1
);
if
(
orig_width
<
out_width
)
{
/*
* Upsampling.
* Currently you can only scale both dimensions in one way.
*/
if
(
orig_height
>
out_height
||
orig_width
*
8
<
out_width
||
orig_height
*
8
<
out_height
)
{
enable_lcd_clocks
(
0
);
return
-
EINVAL
;
}
set_upsampling_coef_table
(
plane
);
}
else
if
(
orig_width
>
out_width
)
{
/* Downsampling not yet supported
*/
enable_lcd_clocks
(
0
);
return
-
EINVAL
;
}
if
(
!
orig_width
||
orig_width
==
out_width
)
fir_hinc
=
0
;
else
fir_hinc
=
1024
*
orig_width
/
out_width
;
if
(
!
orig_height
||
orig_height
==
out_height
)
fir_vinc
=
0
;
else
fir_vinc
=
1024
*
orig_height
/
out_height
;
dispc
.
fir_hinc
[
plane
]
=
fir_hinc
;
dispc
.
fir_vinc
[
plane
]
=
fir_vinc
;
MOD_REG_FLD
(
fir_reg
[
plane
],
FLD_MASK
(
16
,
12
)
|
FLD_MASK
(
0
,
12
),
((
fir_vinc
&
4095
)
<<
16
)
|
(
fir_hinc
&
4095
));
dev_dbg
(
dispc
.
fbdev
->
dev
,
"out_width %d out_height %d orig_width %d "
"orig_height %d fir_hinc %d fir_vinc %d
\n
"
,
out_width
,
out_height
,
orig_width
,
orig_height
,
fir_hinc
,
fir_vinc
);
MOD_REG_FLD
(
vs_reg
[
plane
],
FLD_MASK
(
16
,
11
)
|
FLD_MASK
(
0
,
11
),
((
out_height
-
1
)
<<
16
)
|
(
out_width
-
1
));
l
=
dispc_read_reg
(
at_reg
[
plane
]);
l
&=
~
(
0x03
<<
5
);
l
|=
fir_hinc
?
(
1
<<
5
)
:
0
;
l
|=
fir_vinc
?
(
1
<<
6
)
:
0
;
dispc_write_reg
(
at_reg
[
plane
],
l
);
enable_lcd_clocks
(
0
);
return
0
;
}
static
int
omap_dispc_enable_plane
(
int
plane
,
int
enable
)
{
const
u32
at_reg
[]
=
{
DISPC_GFX_ATTRIBUTES
,
DISPC_VID1_BASE
+
DISPC_VID_ATTRIBUTES
,
DISPC_VID2_BASE
+
DISPC_VID_ATTRIBUTES
};
if
((
unsigned
int
)
plane
>
dispc
.
mem_desc
.
region_cnt
)
return
-
EINVAL
;
enable_lcd_clocks
(
1
);
MOD_REG_FLD
(
at_reg
[
plane
],
1
,
enable
?
1
:
0
);
enable_lcd_clocks
(
0
);
return
0
;
}
static
int
omap_dispc_set_color_key
(
struct
omapfb_color_key
*
ck
)
{
u32
df_reg
,
tr_reg
;
int
shift
,
val
;
switch
(
ck
->
channel_out
)
{
case
OMAPFB_CHANNEL_OUT_LCD
:
df_reg
=
DISPC_DEFAULT_COLOR0
;
tr_reg
=
DISPC_TRANS_COLOR0
;
shift
=
10
;
break
;
case
OMAPFB_CHANNEL_OUT_DIGIT
:
df_reg
=
DISPC_DEFAULT_COLOR1
;
tr_reg
=
DISPC_TRANS_COLOR1
;
shift
=
12
;
break
;
default:
return
-
EINVAL
;
}
switch
(
ck
->
key_type
)
{
case
OMAPFB_COLOR_KEY_DISABLED
:
val
=
0
;
break
;
case
OMAPFB_COLOR_KEY_GFX_DST
:
val
=
1
;
break
;
case
OMAPFB_COLOR_KEY_VID_SRC
:
val
=
3
;
break
;
default:
return
-
EINVAL
;
}
enable_lcd_clocks
(
1
);
MOD_REG_FLD
(
DISPC_CONFIG
,
FLD_MASK
(
shift
,
2
),
val
<<
shift
);
if
(
val
!=
0
)
dispc_write_reg
(
tr_reg
,
ck
->
trans_key
);
dispc_write_reg
(
df_reg
,
ck
->
background
);
enable_lcd_clocks
(
0
);
dispc
.
color_key
=
*
ck
;
return
0
;
}
static
int
omap_dispc_get_color_key
(
struct
omapfb_color_key
*
ck
)
{
*
ck
=
dispc
.
color_key
;
return
0
;
}
static
void
load_palette
(
void
)
{
}
static
int
omap_dispc_set_update_mode
(
enum
omapfb_update_mode
mode
)
{
int
r
=
0
;
if
(
mode
!=
dispc
.
update_mode
)
{
switch
(
mode
)
{
case
OMAPFB_AUTO_UPDATE
:
case
OMAPFB_MANUAL_UPDATE
:
enable_lcd_clocks
(
1
);
omap_dispc_enable_lcd_out
(
1
);
dispc
.
update_mode
=
mode
;
break
;
case
OMAPFB_UPDATE_DISABLED
:
init_completion
(
&
dispc
.
frame_done
);
omap_dispc_enable_lcd_out
(
0
);
if
(
!
wait_for_completion_timeout
(
&
dispc
.
frame_done
,
msecs_to_jiffies
(
500
)))
{
dev_err
(
dispc
.
fbdev
->
dev
,
"timeout waiting for FRAME DONE
\n
"
);
}
dispc
.
update_mode
=
mode
;
enable_lcd_clocks
(
0
);
break
;
default:
r
=
-
EINVAL
;
}
}
return
r
;
}
static
void
omap_dispc_get_caps
(
int
plane
,
struct
omapfb_caps
*
caps
)
{
caps
->
ctrl
|=
OMAPFB_CAPS_PLANE_RELOCATE_MEM
;
if
(
plane
>
0
)
caps
->
ctrl
|=
OMAPFB_CAPS_PLANE_SCALE
;
caps
->
plane_color
|=
(
1
<<
OMAPFB_COLOR_RGB565
)
|
(
1
<<
OMAPFB_COLOR_YUV422
)
|
(
1
<<
OMAPFB_COLOR_YUY422
);
if
(
plane
==
0
)
caps
->
plane_color
|=
(
1
<<
OMAPFB_COLOR_CLUT_8BPP
)
|
(
1
<<
OMAPFB_COLOR_CLUT_4BPP
)
|
(
1
<<
OMAPFB_COLOR_CLUT_2BPP
)
|
(
1
<<
OMAPFB_COLOR_CLUT_1BPP
)
|
(
1
<<
OMAPFB_COLOR_RGB444
);
}
static
enum
omapfb_update_mode
omap_dispc_get_update_mode
(
void
)
{
return
dispc
.
update_mode
;
}
static
void
setup_color_conv_coef
(
void
)
{
u32
mask
=
FLD_MASK
(
16
,
11
)
|
FLD_MASK
(
0
,
11
);
int
cf1_reg
=
DISPC_VID1_BASE
+
DISPC_VID_CONV_COEF0
;
int
cf2_reg
=
DISPC_VID2_BASE
+
DISPC_VID_CONV_COEF0
;
int
at1_reg
=
DISPC_VID1_BASE
+
DISPC_VID_ATTRIBUTES
;
int
at2_reg
=
DISPC_VID2_BASE
+
DISPC_VID_ATTRIBUTES
;
const
struct
color_conv_coef
{
int
ry
,
rcr
,
rcb
,
gy
,
gcr
,
gcb
,
by
,
bcr
,
bcb
;
int
full_range
;
}
ctbl_bt601_5
=
{
298
,
409
,
0
,
298
,
-
208
,
-
100
,
298
,
0
,
517
,
0
,
};
const
struct
color_conv_coef
*
ct
;
#define CVAL(x, y) (((x & 2047) << 16) | (y & 2047))
ct
=
&
ctbl_bt601_5
;
MOD_REG_FLD
(
cf1_reg
,
mask
,
CVAL
(
ct
->
rcr
,
ct
->
ry
));
MOD_REG_FLD
(
cf1_reg
+
4
,
mask
,
CVAL
(
ct
->
gy
,
ct
->
rcb
));
MOD_REG_FLD
(
cf1_reg
+
8
,
mask
,
CVAL
(
ct
->
gcb
,
ct
->
gcr
));
MOD_REG_FLD
(
cf1_reg
+
12
,
mask
,
CVAL
(
ct
->
bcr
,
ct
->
by
));
MOD_REG_FLD
(
cf1_reg
+
16
,
mask
,
CVAL
(
0
,
ct
->
bcb
));
MOD_REG_FLD
(
cf2_reg
,
mask
,
CVAL
(
ct
->
rcr
,
ct
->
ry
));
MOD_REG_FLD
(
cf2_reg
+
4
,
mask
,
CVAL
(
ct
->
gy
,
ct
->
rcb
));
MOD_REG_FLD
(
cf2_reg
+
8
,
mask
,
CVAL
(
ct
->
gcb
,
ct
->
gcr
));
MOD_REG_FLD
(
cf2_reg
+
12
,
mask
,
CVAL
(
ct
->
bcr
,
ct
->
by
));
MOD_REG_FLD
(
cf2_reg
+
16
,
mask
,
CVAL
(
0
,
ct
->
bcb
));
#undef CVAL
MOD_REG_FLD
(
at1_reg
,
(
1
<<
11
),
ct
->
full_range
);
MOD_REG_FLD
(
at2_reg
,
(
1
<<
11
),
ct
->
full_range
);
}
static
void
calc_ck_div
(
int
is_tft
,
int
pck
,
int
*
lck_div
,
int
*
pck_div
)
{
unsigned
long
fck
,
lck
;
*
lck_div
=
1
;
pck
=
max
(
1
,
pck
);
fck
=
clk_get_rate
(
dispc
.
dss1_fck
);
lck
=
fck
;
*
pck_div
=
(
lck
+
pck
-
1
)
/
pck
;
if
(
is_tft
)
*
pck_div
=
max
(
2
,
*
pck_div
);
else
*
pck_div
=
max
(
3
,
*
pck_div
);
if
(
*
pck_div
>
255
)
{
*
pck_div
=
255
;
lck
=
pck
*
*
pck_div
;
*
lck_div
=
fck
/
lck
;
BUG_ON
(
*
lck_div
<
1
);
if
(
*
lck_div
>
255
)
{
*
lck_div
=
255
;
dev_warn
(
dispc
.
fbdev
->
dev
,
"pixclock %d kHz too low.
\n
"
,
pck
/
1000
);
}
}
}
static
void
set_lcd_tft_mode
(
int
enable
)
{
u32
mask
;
mask
=
1
<<
3
;
MOD_REG_FLD
(
DISPC_CONTROL
,
mask
,
enable
?
mask
:
0
);
}
static
void
set_lcd_timings
(
void
)
{
u32
l
;
int
lck_div
,
pck_div
;
struct
lcd_panel
*
panel
=
dispc
.
fbdev
->
panel
;
int
is_tft
=
panel
->
config
&
OMAP_LCDC_PANEL_TFT
;
unsigned
long
fck
;
l
=
dispc_read_reg
(
DISPC_TIMING_H
);
l
&=
~
(
FLD_MASK
(
0
,
6
)
|
FLD_MASK
(
8
,
8
)
|
FLD_MASK
(
20
,
8
));
l
|=
(
max
(
1
,
(
min
(
64
,
panel
->
hsw
)))
-
1
)
<<
0
;
l
|=
(
max
(
1
,
(
min
(
256
,
panel
->
hfp
)))
-
1
)
<<
8
;
l
|=
(
max
(
1
,
(
min
(
256
,
panel
->
hbp
)))
-
1
)
<<
20
;
dispc_write_reg
(
DISPC_TIMING_H
,
l
);
l
=
dispc_read_reg
(
DISPC_TIMING_V
);
l
&=
~
(
FLD_MASK
(
0
,
6
)
|
FLD_MASK
(
8
,
8
)
|
FLD_MASK
(
20
,
8
));
l
|=
(
max
(
1
,
(
min
(
64
,
panel
->
vsw
)))
-
1
)
<<
0
;
l
|=
(
max
(
0
,
(
min
(
255
,
panel
->
vfp
)))
-
0
)
<<
8
;
l
|=
(
max
(
0
,
(
min
(
255
,
panel
->
vbp
)))
-
0
)
<<
20
;
dispc_write_reg
(
DISPC_TIMING_V
,
l
);
l
=
dispc_read_reg
(
DISPC_POL_FREQ
);
l
&=
~
FLD_MASK
(
12
,
6
);
l
|=
(
panel
->
config
&
OMAP_LCDC_SIGNAL_MASK
)
<<
12
;
l
|=
panel
->
acb
&
0xff
;
dispc_write_reg
(
DISPC_POL_FREQ
,
l
);
calc_ck_div
(
is_tft
,
panel
->
pixel_clock
*
1000
,
&
lck_div
,
&
pck_div
);
l
=
dispc_read_reg
(
DISPC_DIVISOR
);
l
&=
~
(
FLD_MASK
(
16
,
8
)
|
FLD_MASK
(
0
,
8
));
l
|=
(
lck_div
<<
16
)
|
(
pck_div
<<
0
);
dispc_write_reg
(
DISPC_DIVISOR
,
l
);
/* update panel info with the exact clock */
fck
=
clk_get_rate
(
dispc
.
dss1_fck
);
panel
->
pixel_clock
=
fck
/
lck_div
/
pck_div
/
1000
;
}
static
void
recalc_irq_mask
(
void
)
{
int
i
;
unsigned
long
irq_mask
=
DISPC_IRQ_MASK_ERROR
;
for
(
i
=
0
;
i
<
MAX_IRQ_HANDLERS
;
i
++
)
{
if
(
!
dispc
.
irq_handlers
[
i
].
callback
)
continue
;
irq_mask
|=
dispc
.
irq_handlers
[
i
].
irq_mask
;
}
enable_lcd_clocks
(
1
);
MOD_REG_FLD
(
DISPC_IRQENABLE
,
0x7fff
,
irq_mask
);
enable_lcd_clocks
(
0
);
}
int
omap_dispc_request_irq
(
unsigned
long
irq_mask
,
void
(
*
callback
)(
void
*
data
),
void
*
data
)
{
int
i
;
BUG_ON
(
callback
==
NULL
);
for
(
i
=
0
;
i
<
MAX_IRQ_HANDLERS
;
i
++
)
{
if
(
dispc
.
irq_handlers
[
i
].
callback
)
continue
;
dispc
.
irq_handlers
[
i
].
irq_mask
=
irq_mask
;
dispc
.
irq_handlers
[
i
].
callback
=
callback
;
dispc
.
irq_handlers
[
i
].
data
=
data
;
recalc_irq_mask
();
return
0
;
}
return
-
EBUSY
;
}
EXPORT_SYMBOL
(
omap_dispc_request_irq
);
void
omap_dispc_free_irq
(
unsigned
long
irq_mask
,
void
(
*
callback
)(
void
*
data
),
void
*
data
)
{
int
i
;
for
(
i
=
0
;
i
<
MAX_IRQ_HANDLERS
;
i
++
)
{
if
(
dispc
.
irq_handlers
[
i
].
callback
==
callback
&&
dispc
.
irq_handlers
[
i
].
data
==
data
)
{
dispc
.
irq_handlers
[
i
].
irq_mask
=
0
;
dispc
.
irq_handlers
[
i
].
callback
=
NULL
;
dispc
.
irq_handlers
[
i
].
data
=
NULL
;
recalc_irq_mask
();
return
;
}
}
BUG
();
}
EXPORT_SYMBOL
(
omap_dispc_free_irq
);
static
irqreturn_t
omap_dispc_irq_handler
(
int
irq
,
void
*
dev
)
{
u32
stat
;
int
i
=
0
;
enable_lcd_clocks
(
1
);
stat
=
dispc_read_reg
(
DISPC_IRQSTATUS
);
if
(
stat
&
DISPC_IRQ_FRAMEMASK
)
complete
(
&
dispc
.
frame_done
);
if
(
stat
&
DISPC_IRQ_MASK_ERROR
)
{
if
(
printk_ratelimit
())
{
dev_err
(
dispc
.
fbdev
->
dev
,
"irq error status %04x
\n
"
,
stat
&
0x7fff
);
}
}
for
(
i
=
0
;
i
<
MAX_IRQ_HANDLERS
;
i
++
)
{
if
(
unlikely
(
dispc
.
irq_handlers
[
i
].
callback
&&
(
stat
&
dispc
.
irq_handlers
[
i
].
irq_mask
)))
dispc
.
irq_handlers
[
i
].
callback
(
dispc
.
irq_handlers
[
i
].
data
);
}
dispc_write_reg
(
DISPC_IRQSTATUS
,
stat
);
enable_lcd_clocks
(
0
);
return
IRQ_HANDLED
;
}
static
int
get_dss_clocks
(
void
)
{
dispc
.
dss_ick
=
clk_get
(
&
dispc
.
fbdev
->
dssdev
->
dev
,
"ick"
);
if
(
IS_ERR
(
dispc
.
dss_ick
))
{
dev_err
(
dispc
.
fbdev
->
dev
,
"can't get ick
\n
"
);
return
PTR_ERR
(
dispc
.
dss_ick
);
}
dispc
.
dss1_fck
=
clk_get
(
&
dispc
.
fbdev
->
dssdev
->
dev
,
"fck"
);
if
(
IS_ERR
(
dispc
.
dss1_fck
))
{
dev_err
(
dispc
.
fbdev
->
dev
,
"can't get dss1_fck
\n
"
);
clk_put
(
dispc
.
dss_ick
);
return
PTR_ERR
(
dispc
.
dss1_fck
);
}
dispc
.
dss_54m_fck
=
clk_get
(
&
dispc
.
fbdev
->
dssdev
->
dev
,
"tv_clk"
);
if
(
IS_ERR
(
dispc
.
dss_54m_fck
))
{
dev_err
(
dispc
.
fbdev
->
dev
,
"can't get tv_fck
\n
"
);
clk_put
(
dispc
.
dss_ick
);
clk_put
(
dispc
.
dss1_fck
);
return
PTR_ERR
(
dispc
.
dss_54m_fck
);
}
return
0
;
}
static
void
put_dss_clocks
(
void
)
{
clk_put
(
dispc
.
dss_54m_fck
);
clk_put
(
dispc
.
dss1_fck
);
clk_put
(
dispc
.
dss_ick
);
}
static
void
enable_lcd_clocks
(
int
enable
)
{
if
(
enable
)
{
clk_enable
(
dispc
.
dss_ick
);
clk_enable
(
dispc
.
dss1_fck
);
}
else
{
clk_disable
(
dispc
.
dss1_fck
);
clk_disable
(
dispc
.
dss_ick
);
}
}
static
void
enable_digit_clocks
(
int
enable
)
{
if
(
enable
)
clk_enable
(
dispc
.
dss_54m_fck
);
else
clk_disable
(
dispc
.
dss_54m_fck
);
}
static
void
omap_dispc_suspend
(
void
)
{
if
(
dispc
.
update_mode
==
OMAPFB_AUTO_UPDATE
)
{
init_completion
(
&
dispc
.
frame_done
);
omap_dispc_enable_lcd_out
(
0
);
if
(
!
wait_for_completion_timeout
(
&
dispc
.
frame_done
,
msecs_to_jiffies
(
500
)))
{
dev_err
(
dispc
.
fbdev
->
dev
,
"timeout waiting for FRAME DONE
\n
"
);
}
enable_lcd_clocks
(
0
);
}
}
static
void
omap_dispc_resume
(
void
)
{
if
(
dispc
.
update_mode
==
OMAPFB_AUTO_UPDATE
)
{
enable_lcd_clocks
(
1
);
if
(
!
dispc
.
ext_mode
)
{
set_lcd_timings
();
load_palette
();
}
omap_dispc_enable_lcd_out
(
1
);
}
}
static
int
omap_dispc_update_window
(
struct
fb_info
*
fbi
,
struct
omapfb_update_window
*
win
,
void
(
*
complete_callback
)(
void
*
arg
),
void
*
complete_callback_data
)
{
return
dispc
.
update_mode
==
OMAPFB_UPDATE_DISABLED
?
-
ENODEV
:
0
;
}
static
int
mmap_kern
(
struct
omapfb_mem_region
*
region
)
{
struct
vm_struct
*
kvma
;
struct
vm_area_struct
vma
;
pgprot_t
pgprot
;
unsigned
long
vaddr
;
kvma
=
get_vm_area
(
region
->
size
,
VM_IOREMAP
);
if
(
kvma
==
NULL
)
{
dev_err
(
dispc
.
fbdev
->
dev
,
"can't get kernel vm area
\n
"
);
return
-
ENOMEM
;
}
vma
.
vm_mm
=
&
init_mm
;
vaddr
=
(
unsigned
long
)
kvma
->
addr
;
pgprot
=
pgprot_writecombine
(
pgprot_kernel
);
vma
.
vm_start
=
vaddr
;
vma
.
vm_end
=
vaddr
+
region
->
size
;
if
(
io_remap_pfn_range
(
&
vma
,
vaddr
,
region
->
paddr
>>
PAGE_SHIFT
,
region
->
size
,
pgprot
)
<
0
)
{
dev_err
(
dispc
.
fbdev
->
dev
,
"kernel mmap for FBMEM failed
\n
"
);
return
-
EAGAIN
;
}
region
->
vaddr
=
(
void
*
)
vaddr
;
return
0
;
}
static
void
mmap_user_open
(
struct
vm_area_struct
*
vma
)
{
int
plane
=
(
int
)
vma
->
vm_private_data
;
atomic_inc
(
&
dispc
.
map_count
[
plane
]);
}
static
void
mmap_user_close
(
struct
vm_area_struct
*
vma
)
{
int
plane
=
(
int
)
vma
->
vm_private_data
;
atomic_dec
(
&
dispc
.
map_count
[
plane
]);
}
static
const
struct
vm_operations_struct
mmap_user_ops
=
{
.
open
=
mmap_user_open
,
.
close
=
mmap_user_close
,
};
static
int
omap_dispc_mmap_user
(
struct
fb_info
*
info
,
struct
vm_area_struct
*
vma
)
{
struct
omapfb_plane_struct
*
plane
=
info
->
par
;
unsigned
long
off
;
unsigned
long
start
;
u32
len
;
if
(
vma
->
vm_end
-
vma
->
vm_start
==
0
)
return
0
;
if
(
vma
->
vm_pgoff
>
(
~
0UL
>>
PAGE_SHIFT
))
return
-
EINVAL
;
off
=
vma
->
vm_pgoff
<<
PAGE_SHIFT
;
start
=
info
->
fix
.
smem_start
;
len
=
info
->
fix
.
smem_len
;
if
(
off
>=
len
)
return
-
EINVAL
;
if
((
vma
->
vm_end
-
vma
->
vm_start
+
off
)
>
len
)
return
-
EINVAL
;
off
+=
start
;
vma
->
vm_pgoff
=
off
>>
PAGE_SHIFT
;
vma
->
vm_flags
|=
VM_IO
|
VM_RESERVED
;
vma
->
vm_page_prot
=
pgprot_writecombine
(
vma
->
vm_page_prot
);
vma
->
vm_ops
=
&
mmap_user_ops
;
vma
->
vm_private_data
=
(
void
*
)
plane
->
idx
;
if
(
io_remap_pfn_range
(
vma
,
vma
->
vm_start
,
off
>>
PAGE_SHIFT
,
vma
->
vm_end
-
vma
->
vm_start
,
vma
->
vm_page_prot
))
return
-
EAGAIN
;
/* vm_ops.open won't be called for mmap itself. */
atomic_inc
(
&
dispc
.
map_count
[
plane
->
idx
]);
return
0
;
}
static
void
unmap_kern
(
struct
omapfb_mem_region
*
region
)
{
vunmap
(
region
->
vaddr
);
}
static
int
alloc_palette_ram
(
void
)
{
dispc
.
palette_vaddr
=
dma_alloc_writecombine
(
dispc
.
fbdev
->
dev
,
MAX_PALETTE_SIZE
,
&
dispc
.
palette_paddr
,
GFP_KERNEL
);
if
(
dispc
.
palette_vaddr
==
NULL
)
{
dev_err
(
dispc
.
fbdev
->
dev
,
"failed to alloc palette memory
\n
"
);
return
-
ENOMEM
;
}
return
0
;
}
static
void
free_palette_ram
(
void
)
{
dma_free_writecombine
(
dispc
.
fbdev
->
dev
,
MAX_PALETTE_SIZE
,
dispc
.
palette_vaddr
,
dispc
.
palette_paddr
);
}
static
int
alloc_fbmem
(
struct
omapfb_mem_region
*
region
)
{
region
->
vaddr
=
dma_alloc_writecombine
(
dispc
.
fbdev
->
dev
,
region
->
size
,
&
region
->
paddr
,
GFP_KERNEL
);
if
(
region
->
vaddr
==
NULL
)
{
dev_err
(
dispc
.
fbdev
->
dev
,
"unable to allocate FB DMA memory
\n
"
);
return
-
ENOMEM
;
}
return
0
;
}
static
void
free_fbmem
(
struct
omapfb_mem_region
*
region
)
{
dma_free_writecombine
(
dispc
.
fbdev
->
dev
,
region
->
size
,
region
->
vaddr
,
region
->
paddr
);
}
static
struct
resmap
*
init_resmap
(
unsigned
long
start
,
size_t
size
)
{
unsigned
page_cnt
;
struct
resmap
*
res_map
;
page_cnt
=
PAGE_ALIGN
(
size
)
/
PAGE_SIZE
;
res_map
=
kzalloc
(
sizeof
(
struct
resmap
)
+
RESMAP_SIZE
(
page_cnt
),
GFP_KERNEL
);
if
(
res_map
==
NULL
)
return
NULL
;
res_map
->
start
=
start
;
res_map
->
page_cnt
=
page_cnt
;
res_map
->
map
=
(
unsigned
long
*
)(
res_map
+
1
);
return
res_map
;
}
static
void
cleanup_resmap
(
struct
resmap
*
res_map
)
{
kfree
(
res_map
);
}
static
inline
int
resmap_mem_type
(
unsigned
long
start
)
{
if
(
start
>=
OMAP2_SRAM_START
&&
start
<
OMAP2_SRAM_START
+
OMAP2_SRAM_SIZE
)
return
OMAPFB_MEMTYPE_SRAM
;
else
return
OMAPFB_MEMTYPE_SDRAM
;
}
static
inline
int
resmap_page_reserved
(
struct
resmap
*
res_map
,
unsigned
page_nr
)
{
return
*
RESMAP_PTR
(
res_map
,
page_nr
)
&
RESMAP_MASK
(
page_nr
)
?
1
:
0
;
}
static
inline
void
resmap_reserve_page
(
struct
resmap
*
res_map
,
unsigned
page_nr
)
{
BUG_ON
(
resmap_page_reserved
(
res_map
,
page_nr
));
*
RESMAP_PTR
(
res_map
,
page_nr
)
|=
RESMAP_MASK
(
page_nr
);
}
static
inline
void
resmap_free_page
(
struct
resmap
*
res_map
,
unsigned
page_nr
)
{
BUG_ON
(
!
resmap_page_reserved
(
res_map
,
page_nr
));
*
RESMAP_PTR
(
res_map
,
page_nr
)
&=
~
RESMAP_MASK
(
page_nr
);
}
static
void
resmap_reserve_region
(
unsigned
long
start
,
size_t
size
)
{
struct
resmap
*
res_map
;
unsigned
start_page
;
unsigned
end_page
;
int
mtype
;
unsigned
i
;
mtype
=
resmap_mem_type
(
start
);
res_map
=
dispc
.
res_map
[
mtype
];
dev_dbg
(
dispc
.
fbdev
->
dev
,
"reserve mem type %d start %08lx size %d
\n
"
,
mtype
,
start
,
size
);
start_page
=
(
start
-
res_map
->
start
)
/
PAGE_SIZE
;
end_page
=
start_page
+
PAGE_ALIGN
(
size
)
/
PAGE_SIZE
;
for
(
i
=
start_page
;
i
<
end_page
;
i
++
)
resmap_reserve_page
(
res_map
,
i
);
}
static
void
resmap_free_region
(
unsigned
long
start
,
size_t
size
)
{
struct
resmap
*
res_map
;
unsigned
start_page
;
unsigned
end_page
;
unsigned
i
;
int
mtype
;
mtype
=
resmap_mem_type
(
start
);
res_map
=
dispc
.
res_map
[
mtype
];
dev_dbg
(
dispc
.
fbdev
->
dev
,
"free mem type %d start %08lx size %d
\n
"
,
mtype
,
start
,
size
);
start_page
=
(
start
-
res_map
->
start
)
/
PAGE_SIZE
;
end_page
=
start_page
+
PAGE_ALIGN
(
size
)
/
PAGE_SIZE
;
for
(
i
=
start_page
;
i
<
end_page
;
i
++
)
resmap_free_page
(
res_map
,
i
);
}
static
unsigned
long
resmap_alloc_region
(
int
mtype
,
size_t
size
)
{
unsigned
i
;
unsigned
total
;
unsigned
start_page
;
unsigned
long
start
;
struct
resmap
*
res_map
=
dispc
.
res_map
[
mtype
];
BUG_ON
(
mtype
>=
DISPC_MEMTYPE_NUM
||
res_map
==
NULL
||
!
size
);
size
=
PAGE_ALIGN
(
size
)
/
PAGE_SIZE
;
start_page
=
0
;
total
=
0
;
for
(
i
=
0
;
i
<
res_map
->
page_cnt
;
i
++
)
{
if
(
resmap_page_reserved
(
res_map
,
i
))
{
start_page
=
i
+
1
;
total
=
0
;
}
else
if
(
++
total
==
size
)
break
;
}
if
(
total
<
size
)
return
0
;
start
=
res_map
->
start
+
start_page
*
PAGE_SIZE
;
resmap_reserve_region
(
start
,
size
*
PAGE_SIZE
);
return
start
;
}
/* Note that this will only work for user mappings, we don't deal with
* kernel mappings here, so fbcon will keep using the old region.
*/
static
int
omap_dispc_setup_mem
(
int
plane
,
size_t
size
,
int
mem_type
,
unsigned
long
*
paddr
)
{
struct
omapfb_mem_region
*
rg
;
unsigned
long
new_addr
=
0
;
if
((
unsigned
)
plane
>
dispc
.
mem_desc
.
region_cnt
)
return
-
EINVAL
;
if
(
mem_type
>=
DISPC_MEMTYPE_NUM
)
return
-
EINVAL
;
if
(
dispc
.
res_map
[
mem_type
]
==
NULL
)
return
-
ENOMEM
;
rg
=
&
dispc
.
mem_desc
.
region
[
plane
];
if
(
size
==
rg
->
size
&&
mem_type
==
rg
->
type
)
return
0
;
if
(
atomic_read
(
&
dispc
.
map_count
[
plane
]))
return
-
EBUSY
;
if
(
rg
->
size
!=
0
)
resmap_free_region
(
rg
->
paddr
,
rg
->
size
);
if
(
size
!=
0
)
{
new_addr
=
resmap_alloc_region
(
mem_type
,
size
);
if
(
!
new_addr
)
{
/* Reallocate old region. */
resmap_reserve_region
(
rg
->
paddr
,
rg
->
size
);
return
-
ENOMEM
;
}
}
rg
->
paddr
=
new_addr
;
rg
->
size
=
size
;
rg
->
type
=
mem_type
;
*
paddr
=
new_addr
;
return
0
;
}
static
int
setup_fbmem
(
struct
omapfb_mem_desc
*
req_md
)
{
struct
omapfb_mem_region
*
rg
;
int
i
;
int
r
;
unsigned
long
mem_start
[
DISPC_MEMTYPE_NUM
];
unsigned
long
mem_end
[
DISPC_MEMTYPE_NUM
];
if
(
!
req_md
->
region_cnt
)
{
dev_err
(
dispc
.
fbdev
->
dev
,
"no memory regions defined
\n
"
);
return
-
ENOENT
;
}
rg
=
&
req_md
->
region
[
0
];
memset
(
mem_start
,
0xff
,
sizeof
(
mem_start
));
memset
(
mem_end
,
0
,
sizeof
(
mem_end
));
for
(
i
=
0
;
i
<
req_md
->
region_cnt
;
i
++
,
rg
++
)
{
int
mtype
;
if
(
rg
->
paddr
)
{
rg
->
alloc
=
0
;
if
(
rg
->
vaddr
==
NULL
)
{
rg
->
map
=
1
;
if
((
r
=
mmap_kern
(
rg
))
<
0
)
return
r
;
}
}
else
{
if
(
rg
->
type
!=
OMAPFB_MEMTYPE_SDRAM
)
{
dev_err
(
dispc
.
fbdev
->
dev
,
"unsupported memory type
\n
"
);
return
-
EINVAL
;
}
rg
->
alloc
=
rg
->
map
=
1
;
if
((
r
=
alloc_fbmem
(
rg
))
<
0
)
return
r
;
}
mtype
=
rg
->
type
;
if
(
rg
->
paddr
<
mem_start
[
mtype
])
mem_start
[
mtype
]
=
rg
->
paddr
;
if
(
rg
->
paddr
+
rg
->
size
>
mem_end
[
mtype
])
mem_end
[
mtype
]
=
rg
->
paddr
+
rg
->
size
;
}
for
(
i
=
0
;
i
<
DISPC_MEMTYPE_NUM
;
i
++
)
{
unsigned
long
start
;
size_t
size
;
if
(
mem_end
[
i
]
==
0
)
continue
;
start
=
mem_start
[
i
];
size
=
mem_end
[
i
]
-
start
;
dispc
.
res_map
[
i
]
=
init_resmap
(
start
,
size
);
r
=
-
ENOMEM
;
if
(
dispc
.
res_map
[
i
]
==
NULL
)
goto
fail
;
/* Initial state is that everything is reserved. This
* includes possible holes as well, which will never be
* freed.
*/
resmap_reserve_region
(
start
,
size
);
}
dispc
.
mem_desc
=
*
req_md
;
return
0
;
fail:
for
(
i
=
0
;
i
<
DISPC_MEMTYPE_NUM
;
i
++
)
{
if
(
dispc
.
res_map
[
i
]
!=
NULL
)
cleanup_resmap
(
dispc
.
res_map
[
i
]);
}
return
r
;
}
static
void
cleanup_fbmem
(
void
)
{
struct
omapfb_mem_region
*
rg
;
int
i
;
for
(
i
=
0
;
i
<
DISPC_MEMTYPE_NUM
;
i
++
)
{
if
(
dispc
.
res_map
[
i
]
!=
NULL
)
cleanup_resmap
(
dispc
.
res_map
[
i
]);
}
rg
=
&
dispc
.
mem_desc
.
region
[
0
];
for
(
i
=
0
;
i
<
dispc
.
mem_desc
.
region_cnt
;
i
++
,
rg
++
)
{
if
(
rg
->
alloc
)
free_fbmem
(
rg
);
else
{
if
(
rg
->
map
)
unmap_kern
(
rg
);
}
}
}
static
int
omap_dispc_init
(
struct
omapfb_device
*
fbdev
,
int
ext_mode
,
struct
omapfb_mem_desc
*
req_vram
)
{
int
r
;
u32
l
;
struct
lcd_panel
*
panel
=
fbdev
->
panel
;
void
__iomem
*
ram_fw_base
;
int
tmo
=
10000
;
int
skip_init
=
0
;
int
i
;
memset
(
&
dispc
,
0
,
sizeof
(
dispc
));
dispc
.
base
=
ioremap
(
DISPC_BASE
,
SZ_1K
);
if
(
!
dispc
.
base
)
{
dev_err
(
fbdev
->
dev
,
"can't ioremap DISPC
\n
"
);
return
-
ENOMEM
;
}
dispc
.
fbdev
=
fbdev
;
dispc
.
ext_mode
=
ext_mode
;
init_completion
(
&
dispc
.
frame_done
);
if
((
r
=
get_dss_clocks
())
<
0
)
goto
fail0
;
enable_lcd_clocks
(
1
);
#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
l
=
dispc_read_reg
(
DISPC_CONTROL
);
/* LCD enabled ? */
if
(
l
&
1
)
{
pr_info
(
"omapfb: skipping hardware initialization
\n
"
);
skip_init
=
1
;
}
#endif
if
(
!
skip_init
)
{
/* Reset monitoring works only w/ the 54M clk */
enable_digit_clocks
(
1
);
/* Soft reset */
MOD_REG_FLD
(
DISPC_SYSCONFIG
,
1
<<
1
,
1
<<
1
);
while
(
!
(
dispc_read_reg
(
DISPC_SYSSTATUS
)
&
1
))
{
if
(
!--
tmo
)
{
dev_err
(
dispc
.
fbdev
->
dev
,
"soft reset failed
\n
"
);
r
=
-
ENODEV
;
enable_digit_clocks
(
0
);
goto
fail1
;
}
}
enable_digit_clocks
(
0
);
}
/* Enable smart standby/idle, autoidle and wakeup */
l
=
dispc_read_reg
(
DISPC_SYSCONFIG
);
l
&=
~
((
3
<<
12
)
|
(
3
<<
3
));
l
|=
(
2
<<
12
)
|
(
2
<<
3
)
|
(
1
<<
2
)
|
(
1
<<
0
);
dispc_write_reg
(
DISPC_SYSCONFIG
,
l
);
omap_writel
(
1
<<
0
,
DSS_BASE
+
DSS_SYSCONFIG
);
/* Set functional clock autogating */
l
=
dispc_read_reg
(
DISPC_CONFIG
);
l
|=
1
<<
9
;
dispc_write_reg
(
DISPC_CONFIG
,
l
);
l
=
dispc_read_reg
(
DISPC_IRQSTATUS
);
dispc_write_reg
(
DISPC_IRQSTATUS
,
l
);
recalc_irq_mask
();
if
((
r
=
request_irq
(
INT_24XX_DSS_IRQ
,
omap_dispc_irq_handler
,
0
,
MODULE_NAME
,
fbdev
))
<
0
)
{
dev_err
(
dispc
.
fbdev
->
dev
,
"can't get DSS IRQ
\n
"
);
goto
fail1
;
}
/* L3 firewall setting: enable access to OCM RAM */
ram_fw_base
=
ioremap
(
0x68005000
,
SZ_1K
);
if
(
!
ram_fw_base
)
{
dev_err
(
dispc
.
fbdev
->
dev
,
"Cannot ioremap to enable OCM RAM
\n
"
);
goto
fail1
;
}
__raw_writel
(
0x402000b0
,
ram_fw_base
+
0xa0
);
iounmap
(
ram_fw_base
);
if
((
r
=
alloc_palette_ram
())
<
0
)
goto
fail2
;
if
((
r
=
setup_fbmem
(
req_vram
))
<
0
)
goto
fail3
;
if
(
!
skip_init
)
{
for
(
i
=
0
;
i
<
dispc
.
mem_desc
.
region_cnt
;
i
++
)
{
memset
(
dispc
.
mem_desc
.
region
[
i
].
vaddr
,
0
,
dispc
.
mem_desc
.
region
[
i
].
size
);
}
/* Set logic clock to fck, pixel clock to fck/2 for now */
MOD_REG_FLD
(
DISPC_DIVISOR
,
FLD_MASK
(
16
,
8
),
1
<<
16
);
MOD_REG_FLD
(
DISPC_DIVISOR
,
FLD_MASK
(
0
,
8
),
2
<<
0
);
setup_plane_fifo
(
0
,
ext_mode
);
setup_plane_fifo
(
1
,
ext_mode
);
setup_plane_fifo
(
2
,
ext_mode
);
setup_color_conv_coef
();
set_lcd_tft_mode
(
panel
->
config
&
OMAP_LCDC_PANEL_TFT
);
set_load_mode
(
DISPC_LOAD_FRAME_ONLY
);
if
(
!
ext_mode
)
{
set_lcd_data_lines
(
panel
->
data_lines
);
omap_dispc_set_lcd_size
(
panel
->
x_res
,
panel
->
y_res
);
set_lcd_timings
();
}
else
set_lcd_data_lines
(
panel
->
bpp
);
enable_rfbi_mode
(
ext_mode
);
}
l
=
dispc_read_reg
(
DISPC_REVISION
);
pr_info
(
"omapfb: DISPC version %d.%d initialized
\n
"
,
l
>>
4
&
0x0f
,
l
&
0x0f
);
enable_lcd_clocks
(
0
);
return
0
;
fail3:
free_palette_ram
();
fail2:
free_irq
(
INT_24XX_DSS_IRQ
,
fbdev
);
fail1:
enable_lcd_clocks
(
0
);
put_dss_clocks
();
fail0:
iounmap
(
dispc
.
base
);
return
r
;
}
static
void
omap_dispc_cleanup
(
void
)
{
int
i
;
omap_dispc_set_update_mode
(
OMAPFB_UPDATE_DISABLED
);
/* This will also disable clocks that are on */
for
(
i
=
0
;
i
<
dispc
.
mem_desc
.
region_cnt
;
i
++
)
omap_dispc_enable_plane
(
i
,
0
);
cleanup_fbmem
();
free_palette_ram
();
free_irq
(
INT_24XX_DSS_IRQ
,
dispc
.
fbdev
);
put_dss_clocks
();
iounmap
(
dispc
.
base
);
}
const
struct
lcd_ctrl
omap2_int_ctrl
=
{
.
name
=
"internal"
,
.
init
=
omap_dispc_init
,
.
cleanup
=
omap_dispc_cleanup
,
.
get_caps
=
omap_dispc_get_caps
,
.
set_update_mode
=
omap_dispc_set_update_mode
,
.
get_update_mode
=
omap_dispc_get_update_mode
,
.
update_window
=
omap_dispc_update_window
,
.
suspend
=
omap_dispc_suspend
,
.
resume
=
omap_dispc_resume
,
.
setup_plane
=
omap_dispc_setup_plane
,
.
setup_mem
=
omap_dispc_setup_mem
,
.
set_scale
=
omap_dispc_set_scale
,
.
enable_plane
=
omap_dispc_enable_plane
,
.
set_color_key
=
omap_dispc_set_color_key
,
.
get_color_key
=
omap_dispc_get_color_key
,
.
mmap
=
omap_dispc_mmap_user
,
};
drivers/video/omap/dispc.h
deleted
100644 → 0
View file @
f413070e
#ifndef _DISPC_H
#define _DISPC_H
#include <linux/interrupt.h>
#define DISPC_PLANE_GFX 0
#define DISPC_PLANE_VID1 1
#define DISPC_PLANE_VID2 2
#define DISPC_RGB_1_BPP 0x00
#define DISPC_RGB_2_BPP 0x01
#define DISPC_RGB_4_BPP 0x02
#define DISPC_RGB_8_BPP 0x03
#define DISPC_RGB_12_BPP 0x04
#define DISPC_RGB_16_BPP 0x06
#define DISPC_RGB_24_BPP 0x08
#define DISPC_RGB_24_BPP_UNPACK_32 0x09
#define DISPC_YUV2_422 0x0a
#define DISPC_UYVY_422 0x0b
#define DISPC_BURST_4x32 0
#define DISPC_BURST_8x32 1
#define DISPC_BURST_16x32 2
#define DISPC_LOAD_CLUT_AND_FRAME 0x00
#define DISPC_LOAD_CLUT_ONLY 0x01
#define DISPC_LOAD_FRAME_ONLY 0x02
#define DISPC_LOAD_CLUT_ONCE_FRAME 0x03
#define DISPC_TFT_DATA_LINES_12 0
#define DISPC_TFT_DATA_LINES_16 1
#define DISPC_TFT_DATA_LINES_18 2
#define DISPC_TFT_DATA_LINES_24 3
extern
void
omap_dispc_set_lcd_size
(
int
width
,
int
height
);
extern
void
omap_dispc_enable_lcd_out
(
int
enable
);
extern
void
omap_dispc_enable_digit_out
(
int
enable
);
extern
int
omap_dispc_request_irq
(
unsigned
long
irq_mask
,
void
(
*
callback
)(
void
*
data
),
void
*
data
);
extern
void
omap_dispc_free_irq
(
unsigned
long
irq_mask
,
void
(
*
callback
)(
void
*
data
),
void
*
data
);
extern
const
struct
lcd_ctrl
omap2_int_ctrl
;
#endif
drivers/video/omap/hwa742.c
View file @
e9fe8a71
...
...
@@ -28,7 +28,6 @@
#include <linux/interrupt.h>
#include <plat/dma.h>
#include <plat/hwa742.h>
#include "omapfb.h"
#define HWA742_REV_CODE_REG 0x0
...
...
@@ -942,7 +941,6 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
unsigned
long
sys_clk
,
pix_clk
;
int
extif_mem_div
;
struct
omapfb_platform_data
*
omapfb_conf
;
struct
hwa742_platform_data
*
ctrl_conf
;
BUG_ON
(
!
fbdev
->
ext_if
||
!
fbdev
->
int_ctrl
);
...
...
@@ -951,13 +949,6 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
hwa742
.
int_ctrl
=
fbdev
->
int_ctrl
;
omapfb_conf
=
fbdev
->
dev
->
platform_data
;
ctrl_conf
=
omapfb_conf
->
ctrl_platform_data
;
if
(
ctrl_conf
==
NULL
)
{
dev_err
(
fbdev
->
dev
,
"HWA742: missing platform data
\n
"
);
r
=
-
ENOENT
;
goto
err1
;
}
hwa742
.
sys_ck
=
clk_get
(
NULL
,
"hwa_sys_ck"
);
...
...
@@ -995,14 +986,12 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
goto
err4
;
}
if
(
ctrl_conf
->
te_connected
)
{
if
((
r
=
setup_tearsync
(
pix_clk
,
extif_mem_div
))
<
0
)
{
dev_err
(
hwa742
.
fbdev
->
dev
,
"HWA742: can't setup tearing synchronization
\n
"
);
goto
err4
;
}
hwa742
.
te_connected
=
1
;
if
((
r
=
setup_tearsync
(
pix_clk
,
extif_mem_div
))
<
0
)
{
dev_err
(
hwa742
.
fbdev
->
dev
,
"HWA742: can't setup tearing synchronization
\n
"
);
goto
err4
;
}
hwa742
.
te_connected
=
1
;
hwa742
.
max_transmit_size
=
hwa742
.
extif
->
max_transmit_size
;
...
...
drivers/video/omap/omapfb.h
View file @
e9fe8a71
...
...
@@ -47,6 +47,27 @@
struct
omapfb_device
;
#define OMAPFB_PLANE_NUM 1
struct
omapfb_mem_region
{
u32
paddr
;
void
__iomem
*
vaddr
;
unsigned
long
size
;
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
map
:
1
;
/* kernel mapped by the driver */
};
struct
omapfb_mem_desc
{
int
region_cnt
;
struct
omapfb_mem_region
region
[
OMAPFB_PLANE_NUM
];
};
struct
lcd_panel
{
const
char
*
name
;
int
config
;
/* TFT/STN, signal inversion */
...
...
@@ -207,11 +228,7 @@ struct omapfb_device {
struct
platform_device
*
dssdev
;
/* dummy dev for clocks */
};
#ifdef CONFIG_ARCH_OMAP1
extern
struct
lcd_ctrl
omap1_lcd_ctrl
;
#else
extern
struct
lcd_ctrl
omap2_disp_ctrl
;
#endif
extern
void
omapfb_register_panel
(
struct
lcd_panel
*
panel
);
extern
void
omapfb_write_first_pixel
(
struct
omapfb_device
*
fbdev
,
u16
pixval
);
...
...
drivers/video/omap/omapfb_main.c
View file @
e9fe8a71
...
...
@@ -34,7 +34,6 @@
#include "omapfb.h"
#include "lcdc.h"
#include "dispc.h"
#define MODULE_NAME "omapfb"
...
...
@@ -104,29 +103,17 @@ static struct platform_device omapdss_device = {
* ---------------------------------------------------------------------------
*/
extern
struct
lcd_ctrl
hwa742_ctrl
;
extern
struct
lcd_ctrl
blizzard_ctrl
;
static
const
struct
lcd_ctrl
*
ctrls
[]
=
{
#ifdef CONFIG_ARCH_OMAP1
&
omap1_int_ctrl
,
#else
&
omap2_int_ctrl
,
#endif
#ifdef CONFIG_FB_OMAP_LCDC_HWA742
&
hwa742_ctrl
,
#endif
#ifdef CONFIG_FB_OMAP_LCDC_BLIZZARD
&
blizzard_ctrl
,
#endif
};
#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
#ifdef CONFIG_ARCH_OMAP1
extern
struct
lcd_ctrl_extif
omap1_ext_if
;
#else
extern
struct
lcd_ctrl_extif
omap2_ext_if
;
#endif
#endif
static
void
omapfb_rqueue_lock
(
struct
omapfb_device
*
fbdev
)
...
...
@@ -170,11 +157,6 @@ static int ctrl_init(struct omapfb_device *fbdev)
fbdev
->
mem_desc
.
region
[
i
].
size
=
PAGE_ALIGN
(
def_vram
[
i
]);
fbdev
->
mem_desc
.
region_cnt
=
i
;
}
else
{
struct
omapfb_platform_data
*
conf
;
conf
=
fbdev
->
dev
->
platform_data
;
fbdev
->
mem_desc
=
conf
->
mem_desc
;
}
if
(
!
fbdev
->
mem_desc
.
region_cnt
)
{
...
...
@@ -880,7 +862,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
if
(
fbdev
->
ctrl
->
setup_mem
==
NULL
)
return
-
ENODEV
;
if
(
mi
->
type
>
OMAPFB_MEMTYPE_MAX
)
if
(
mi
->
type
!=
OMAPFB_MEMTYPE_SDRAM
)
return
-
EINVAL
;
size
=
PAGE_ALIGN
(
mi
->
size
);
...
...
@@ -1721,16 +1703,9 @@ static int omapfb_do_probe(struct platform_device *pdev,
mutex_init
(
&
fbdev
->
rqueue_mutex
);
#ifdef CONFIG_ARCH_OMAP1
fbdev
->
int_ctrl
=
&
omap1_int_ctrl
;
#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
fbdev
->
ext_if
=
&
omap1_ext_if
;
#endif
#else
/* OMAP2 */
fbdev
->
int_ctrl
=
&
omap2_int_ctrl
;
#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
fbdev
->
ext_if
=
&
omap2_ext_if
;
#endif
#endif
if
(
omapfb_find_ctrl
(
fbdev
)
<
0
)
{
dev_err
(
fbdev
->
dev
,
...
...
@@ -1766,8 +1741,7 @@ static int omapfb_do_probe(struct platform_device *pdev,
#ifdef CONFIG_FB_OMAP_DMA_TUNE
/* Set DMA priority for EMIFF access to highest */
if
(
cpu_class_is_omap1
())
omap_set_dma_priority
(
0
,
OMAP_DMA_PORT_EMIFF
,
15
);
omap_set_dma_priority
(
0
,
OMAP_DMA_PORT_EMIFF
,
15
);
#endif
r
=
ctrl_change_mode
(
fbdev
->
fb_info
[
0
]);
...
...
drivers/video/omap/rfbi.c
deleted
100644 → 0
View file @
f413070e
/*
* OMAP2 Remote Frame Buffer Interface support
*
* Copyright (C) 2005 Nokia Corporation
* Author: Juha Yrjölä <juha.yrjola@nokia.com>
* Imre Deak <imre.deak@nokia.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* 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, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include "omapfb.h"
#include "dispc.h"
/* To work around an RFBI transfer rate limitation */
#define OMAP_RFBI_RATE_LIMIT 1
#define RFBI_BASE 0x48050800
#define RFBI_REVISION 0x0000
#define RFBI_SYSCONFIG 0x0010
#define RFBI_SYSSTATUS 0x0014
#define RFBI_CONTROL 0x0040
#define RFBI_PIXEL_CNT 0x0044
#define RFBI_LINE_NUMBER 0x0048
#define RFBI_CMD 0x004c
#define RFBI_PARAM 0x0050
#define RFBI_DATA 0x0054
#define RFBI_READ 0x0058
#define RFBI_STATUS 0x005c
#define RFBI_CONFIG0 0x0060
#define RFBI_ONOFF_TIME0 0x0064
#define RFBI_CYCLE_TIME0 0x0068
#define RFBI_DATA_CYCLE1_0 0x006c
#define RFBI_DATA_CYCLE2_0 0x0070
#define RFBI_DATA_CYCLE3_0 0x0074
#define RFBI_VSYNC_WIDTH 0x0090
#define RFBI_HSYNC_WIDTH 0x0094
#define DISPC_BASE 0x48050400
#define DISPC_CONTROL 0x0040
#define DISPC_IRQ_FRAMEMASK 0x0001
static
struct
{
void
__iomem
*
base
;
void
(
*
lcdc_callback
)(
void
*
data
);
void
*
lcdc_callback_data
;
unsigned
long
l4_khz
;
int
bits_per_cycle
;
struct
omapfb_device
*
fbdev
;
struct
clk
*
dss_ick
;
struct
clk
*
dss1_fck
;
unsigned
tearsync_pin_cnt
;
unsigned
tearsync_mode
;
}
rfbi
;
static
inline
void
rfbi_write_reg
(
int
idx
,
u32
val
)
{
__raw_writel
(
val
,
rfbi
.
base
+
idx
);
}
static
inline
u32
rfbi_read_reg
(
int
idx
)
{
return
__raw_readl
(
rfbi
.
base
+
idx
);
}
static
int
rfbi_get_clocks
(
void
)
{
rfbi
.
dss_ick
=
clk_get
(
&
rfbi
.
fbdev
->
dssdev
->
dev
,
"ick"
);
if
(
IS_ERR
(
rfbi
.
dss_ick
))
{
dev_err
(
rfbi
.
fbdev
->
dev
,
"can't get ick
\n
"
);
return
PTR_ERR
(
rfbi
.
dss_ick
);
}
rfbi
.
dss1_fck
=
clk_get
(
&
rfbi
.
fbdev
->
dssdev
->
dev
,
"fck"
);
if
(
IS_ERR
(
rfbi
.
dss1_fck
))
{
dev_err
(
rfbi
.
fbdev
->
dev
,
"can't get dss1_fck
\n
"
);
clk_put
(
rfbi
.
dss_ick
);
return
PTR_ERR
(
rfbi
.
dss1_fck
);
}
return
0
;
}
static
void
rfbi_put_clocks
(
void
)
{
clk_put
(
rfbi
.
dss1_fck
);
clk_put
(
rfbi
.
dss_ick
);
}
static
void
rfbi_enable_clocks
(
int
enable
)
{
if
(
enable
)
{
clk_enable
(
rfbi
.
dss_ick
);
clk_enable
(
rfbi
.
dss1_fck
);
}
else
{
clk_disable
(
rfbi
.
dss1_fck
);
clk_disable
(
rfbi
.
dss_ick
);
}
}
#ifdef VERBOSE
static
void
rfbi_print_timings
(
void
)
{
u32
l
;
u32
time
;
l
=
rfbi_read_reg
(
RFBI_CONFIG0
);
time
=
1000000000
/
rfbi
.
l4_khz
;
if
(
l
&
(
1
<<
4
))
time
*=
2
;
dev_dbg
(
rfbi
.
fbdev
->
dev
,
"Tick time %u ps
\n
"
,
time
);
l
=
rfbi_read_reg
(
RFBI_ONOFF_TIME0
);
dev_dbg
(
rfbi
.
fbdev
->
dev
,
"CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, "
"REONTIME %d, REOFFTIME %d
\n
"
,
l
&
0x0f
,
(
l
>>
4
)
&
0x3f
,
(
l
>>
10
)
&
0x0f
,
(
l
>>
14
)
&
0x3f
,
(
l
>>
20
)
&
0x0f
,
(
l
>>
24
)
&
0x3f
);
l
=
rfbi_read_reg
(
RFBI_CYCLE_TIME0
);
dev_dbg
(
rfbi
.
fbdev
->
dev
,
"WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, "
"ACCESSTIME %d
\n
"
,
(
l
&
0x3f
),
(
l
>>
6
)
&
0x3f
,
(
l
>>
12
)
&
0x3f
,
(
l
>>
22
)
&
0x3f
);
}
#else
static
void
rfbi_print_timings
(
void
)
{}
#endif
static
void
rfbi_set_timings
(
const
struct
extif_timings
*
t
)
{
u32
l
;
BUG_ON
(
!
t
->
converted
);
rfbi_enable_clocks
(
1
);
rfbi_write_reg
(
RFBI_ONOFF_TIME0
,
t
->
tim
[
0
]);
rfbi_write_reg
(
RFBI_CYCLE_TIME0
,
t
->
tim
[
1
]);
l
=
rfbi_read_reg
(
RFBI_CONFIG0
);
l
&=
~
(
1
<<
4
);
l
|=
(
t
->
tim
[
2
]
?
1
:
0
)
<<
4
;
rfbi_write_reg
(
RFBI_CONFIG0
,
l
);
rfbi_print_timings
();
rfbi_enable_clocks
(
0
);
}
static
void
rfbi_get_clk_info
(
u32
*
clk_period
,
u32
*
max_clk_div
)
{
*
clk_period
=
1000000000
/
rfbi
.
l4_khz
;
*
max_clk_div
=
2
;
}
static
int
ps_to_rfbi_ticks
(
int
time
,
int
div
)
{
unsigned
long
tick_ps
;
int
ret
;
/* Calculate in picosecs to yield more exact results */
tick_ps
=
1000000000
/
(
rfbi
.
l4_khz
)
*
div
;
ret
=
(
time
+
tick_ps
-
1
)
/
tick_ps
;
return
ret
;
}
#ifdef OMAP_RFBI_RATE_LIMIT
static
unsigned
long
rfbi_get_max_tx_rate
(
void
)
{
unsigned
long
l4_rate
,
dss1_rate
;
int
min_l4_ticks
=
0
;
int
i
;
/* According to TI this can't be calculated so make the
* adjustments for a couple of known frequencies and warn for
* others.
*/
static
const
struct
{
unsigned
long
l4_clk
;
/* HZ */
unsigned
long
dss1_clk
;
/* HZ */
unsigned
long
min_l4_ticks
;
}
ftab
[]
=
{
{
55
,
132
,
7
,
},
/* 7.86 MPix/s */
{
110
,
110
,
12
,
},
/* 9.16 MPix/s */
{
110
,
132
,
10
,
},
/* 11 Mpix/s */
{
120
,
120
,
10
,
},
/* 12 Mpix/s */
{
133
,
133
,
10
,
},
/* 13.3 Mpix/s */
};
l4_rate
=
rfbi
.
l4_khz
/
1000
;
dss1_rate
=
clk_get_rate
(
rfbi
.
dss1_fck
)
/
1000000
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ftab
);
i
++
)
{
/* Use a window instead of an exact match, to account
* for different DPLL multiplier / divider pairs.
*/
if
(
abs
(
ftab
[
i
].
l4_clk
-
l4_rate
)
<
3
&&
abs
(
ftab
[
i
].
dss1_clk
-
dss1_rate
)
<
3
)
{
min_l4_ticks
=
ftab
[
i
].
min_l4_ticks
;
break
;
}
}
if
(
i
==
ARRAY_SIZE
(
ftab
))
{
/* Can't be sure, return anyway the maximum not
* rate-limited. This might cause a problem only for the
* tearing synchronisation.
*/
dev_err
(
rfbi
.
fbdev
->
dev
,
"can't determine maximum RFBI transfer rate
\n
"
);
return
rfbi
.
l4_khz
*
1000
;
}
return
rfbi
.
l4_khz
*
1000
/
min_l4_ticks
;
}
#else
static
int
rfbi_get_max_tx_rate
(
void
)
{
return
rfbi
.
l4_khz
*
1000
;
}
#endif
static
int
rfbi_convert_timings
(
struct
extif_timings
*
t
)
{
u32
l
;
int
reon
,
reoff
,
weon
,
weoff
,
cson
,
csoff
,
cs_pulse
;
int
actim
,
recyc
,
wecyc
;
int
div
=
t
->
clk_div
;
if
(
div
<=
0
||
div
>
2
)
return
-
1
;
/* Make sure that after conversion it still holds that:
* weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff,
* csoff > cson, csoff >= max(weoff, reoff), actim > reon
*/
weon
=
ps_to_rfbi_ticks
(
t
->
we_on_time
,
div
);
weoff
=
ps_to_rfbi_ticks
(
t
->
we_off_time
,
div
);
if
(
weoff
<=
weon
)
weoff
=
weon
+
1
;
if
(
weon
>
0x0f
)
return
-
1
;
if
(
weoff
>
0x3f
)
return
-
1
;
reon
=
ps_to_rfbi_ticks
(
t
->
re_on_time
,
div
);
reoff
=
ps_to_rfbi_ticks
(
t
->
re_off_time
,
div
);
if
(
reoff
<=
reon
)
reoff
=
reon
+
1
;
if
(
reon
>
0x0f
)
return
-
1
;
if
(
reoff
>
0x3f
)
return
-
1
;
cson
=
ps_to_rfbi_ticks
(
t
->
cs_on_time
,
div
);
csoff
=
ps_to_rfbi_ticks
(
t
->
cs_off_time
,
div
);
if
(
csoff
<=
cson
)
csoff
=
cson
+
1
;
if
(
csoff
<
max
(
weoff
,
reoff
))
csoff
=
max
(
weoff
,
reoff
);
if
(
cson
>
0x0f
)
return
-
1
;
if
(
csoff
>
0x3f
)
return
-
1
;
l
=
cson
;
l
|=
csoff
<<
4
;
l
|=
weon
<<
10
;
l
|=
weoff
<<
14
;
l
|=
reon
<<
20
;
l
|=
reoff
<<
24
;
t
->
tim
[
0
]
=
l
;
actim
=
ps_to_rfbi_ticks
(
t
->
access_time
,
div
);
if
(
actim
<=
reon
)
actim
=
reon
+
1
;
if
(
actim
>
0x3f
)
return
-
1
;
wecyc
=
ps_to_rfbi_ticks
(
t
->
we_cycle_time
,
div
);
if
(
wecyc
<
weoff
)
wecyc
=
weoff
;
if
(
wecyc
>
0x3f
)
return
-
1
;
recyc
=
ps_to_rfbi_ticks
(
t
->
re_cycle_time
,
div
);
if
(
recyc
<
reoff
)
recyc
=
reoff
;
if
(
recyc
>
0x3f
)
return
-
1
;
cs_pulse
=
ps_to_rfbi_ticks
(
t
->
cs_pulse_width
,
div
);
if
(
cs_pulse
>
0x3f
)
return
-
1
;
l
=
wecyc
;
l
|=
recyc
<<
6
;
l
|=
cs_pulse
<<
12
;
l
|=
actim
<<
22
;
t
->
tim
[
1
]
=
l
;
t
->
tim
[
2
]
=
div
-
1
;
t
->
converted
=
1
;
return
0
;
}
static
int
rfbi_setup_tearsync
(
unsigned
pin_cnt
,
unsigned
hs_pulse_time
,
unsigned
vs_pulse_time
,
int
hs_pol_inv
,
int
vs_pol_inv
,
int
extif_div
)
{
int
hs
,
vs
;
int
min
;
u32
l
;
if
(
pin_cnt
!=
1
&&
pin_cnt
!=
2
)
return
-
EINVAL
;
hs
=
ps_to_rfbi_ticks
(
hs_pulse_time
,
1
);
vs
=
ps_to_rfbi_ticks
(
vs_pulse_time
,
1
);
if
(
hs
<
2
)
return
-
EDOM
;
if
(
pin_cnt
==
2
)
min
=
2
;
else
min
=
4
;
if
(
vs
<
min
)
return
-
EDOM
;
if
(
vs
==
hs
)
return
-
EINVAL
;
rfbi
.
tearsync_pin_cnt
=
pin_cnt
;
dev_dbg
(
rfbi
.
fbdev
->
dev
,
"setup_tearsync: pins %d hs %d vs %d hs_inv %d vs_inv %d
\n
"
,
pin_cnt
,
hs
,
vs
,
hs_pol_inv
,
vs_pol_inv
);
rfbi_enable_clocks
(
1
);
rfbi_write_reg
(
RFBI_HSYNC_WIDTH
,
hs
);
rfbi_write_reg
(
RFBI_VSYNC_WIDTH
,
vs
);
l
=
rfbi_read_reg
(
RFBI_CONFIG0
);
if
(
hs_pol_inv
)
l
&=
~
(
1
<<
21
);
else
l
|=
1
<<
21
;
if
(
vs_pol_inv
)
l
&=
~
(
1
<<
20
);
else
l
|=
1
<<
20
;
rfbi_enable_clocks
(
0
);
return
0
;
}
static
int
rfbi_enable_tearsync
(
int
enable
,
unsigned
line
)
{
u32
l
;
dev_dbg
(
rfbi
.
fbdev
->
dev
,
"tearsync %d line %d mode %d
\n
"
,
enable
,
line
,
rfbi
.
tearsync_mode
);
if
(
line
>
(
1
<<
11
)
-
1
)
return
-
EINVAL
;
rfbi_enable_clocks
(
1
);
l
=
rfbi_read_reg
(
RFBI_CONFIG0
);
l
&=
~
(
0x3
<<
2
);
if
(
enable
)
{
rfbi
.
tearsync_mode
=
rfbi
.
tearsync_pin_cnt
;
l
|=
rfbi
.
tearsync_mode
<<
2
;
}
else
rfbi
.
tearsync_mode
=
0
;
rfbi_write_reg
(
RFBI_CONFIG0
,
l
);
rfbi_write_reg
(
RFBI_LINE_NUMBER
,
line
);
rfbi_enable_clocks
(
0
);
return
0
;
}
static
void
rfbi_write_command
(
const
void
*
buf
,
unsigned
int
len
)
{
rfbi_enable_clocks
(
1
);
if
(
rfbi
.
bits_per_cycle
==
16
)
{
const
u16
*
w
=
buf
;
BUG_ON
(
len
&
1
);
for
(;
len
;
len
-=
2
)
rfbi_write_reg
(
RFBI_CMD
,
*
w
++
);
}
else
{
const
u8
*
b
=
buf
;
BUG_ON
(
rfbi
.
bits_per_cycle
!=
8
);
for
(;
len
;
len
--
)
rfbi_write_reg
(
RFBI_CMD
,
*
b
++
);
}
rfbi_enable_clocks
(
0
);
}
static
void
rfbi_read_data
(
void
*
buf
,
unsigned
int
len
)
{
rfbi_enable_clocks
(
1
);
if
(
rfbi
.
bits_per_cycle
==
16
)
{
u16
*
w
=
buf
;
BUG_ON
(
len
&
~
1
);
for
(;
len
;
len
-=
2
)
{
rfbi_write_reg
(
RFBI_READ
,
0
);
*
w
++
=
rfbi_read_reg
(
RFBI_READ
);
}
}
else
{
u8
*
b
=
buf
;
BUG_ON
(
rfbi
.
bits_per_cycle
!=
8
);
for
(;
len
;
len
--
)
{
rfbi_write_reg
(
RFBI_READ
,
0
);
*
b
++
=
rfbi_read_reg
(
RFBI_READ
);
}
}
rfbi_enable_clocks
(
0
);
}
static
void
rfbi_write_data
(
const
void
*
buf
,
unsigned
int
len
)
{
rfbi_enable_clocks
(
1
);
if
(
rfbi
.
bits_per_cycle
==
16
)
{
const
u16
*
w
=
buf
;
BUG_ON
(
len
&
1
);
for
(;
len
;
len
-=
2
)
rfbi_write_reg
(
RFBI_PARAM
,
*
w
++
);
}
else
{
const
u8
*
b
=
buf
;
BUG_ON
(
rfbi
.
bits_per_cycle
!=
8
);
for
(;
len
;
len
--
)
rfbi_write_reg
(
RFBI_PARAM
,
*
b
++
);
}
rfbi_enable_clocks
(
0
);
}
static
void
rfbi_transfer_area
(
int
width
,
int
height
,
void
(
callback
)(
void
*
data
),
void
*
data
)
{
u32
w
;
BUG_ON
(
callback
==
NULL
);
rfbi_enable_clocks
(
1
);
omap_dispc_set_lcd_size
(
width
,
height
);
rfbi
.
lcdc_callback
=
callback
;
rfbi
.
lcdc_callback_data
=
data
;
rfbi_write_reg
(
RFBI_PIXEL_CNT
,
width
*
height
);
w
=
rfbi_read_reg
(
RFBI_CONTROL
);
w
|=
1
;
/* enable */
if
(
!
rfbi
.
tearsync_mode
)
w
|=
1
<<
4
;
/* internal trigger, reset by HW */
rfbi_write_reg
(
RFBI_CONTROL
,
w
);
omap_dispc_enable_lcd_out
(
1
);
}
static
inline
void
_stop_transfer
(
void
)
{
u32
w
;
w
=
rfbi_read_reg
(
RFBI_CONTROL
);
rfbi_write_reg
(
RFBI_CONTROL
,
w
&
~
(
1
<<
0
));
rfbi_enable_clocks
(
0
);
}
static
void
rfbi_dma_callback
(
void
*
data
)
{
_stop_transfer
();
rfbi
.
lcdc_callback
(
rfbi
.
lcdc_callback_data
);
}
static
void
rfbi_set_bits_per_cycle
(
int
bpc
)
{
u32
l
;
rfbi_enable_clocks
(
1
);
l
=
rfbi_read_reg
(
RFBI_CONFIG0
);
l
&=
~
(
0x03
<<
0
);
switch
(
bpc
)
{
case
8
:
break
;
case
16
:
l
|=
3
;
break
;
default:
BUG
();
}
rfbi_write_reg
(
RFBI_CONFIG0
,
l
);
rfbi
.
bits_per_cycle
=
bpc
;
rfbi_enable_clocks
(
0
);
}
static
int
rfbi_init
(
struct
omapfb_device
*
fbdev
)
{
u32
l
;
int
r
;
rfbi
.
fbdev
=
fbdev
;
rfbi
.
base
=
ioremap
(
RFBI_BASE
,
SZ_1K
);
if
(
!
rfbi
.
base
)
{
dev_err
(
fbdev
->
dev
,
"can't ioremap RFBI
\n
"
);
return
-
ENOMEM
;
}
if
((
r
=
rfbi_get_clocks
())
<
0
)
return
r
;
rfbi_enable_clocks
(
1
);
rfbi
.
l4_khz
=
clk_get_rate
(
rfbi
.
dss_ick
)
/
1000
;
/* Reset */
rfbi_write_reg
(
RFBI_SYSCONFIG
,
1
<<
1
);
while
(
!
(
rfbi_read_reg
(
RFBI_SYSSTATUS
)
&
(
1
<<
0
)));
l
=
rfbi_read_reg
(
RFBI_SYSCONFIG
);
/* Enable autoidle and smart-idle */
l
|=
(
1
<<
0
)
|
(
2
<<
3
);
rfbi_write_reg
(
RFBI_SYSCONFIG
,
l
);
/* 16-bit interface, ITE trigger mode, 16-bit data */
l
=
(
0x03
<<
0
)
|
(
0x00
<<
2
)
|
(
0x01
<<
5
)
|
(
0x02
<<
7
);
l
|=
(
0
<<
9
)
|
(
1
<<
20
)
|
(
1
<<
21
);
rfbi_write_reg
(
RFBI_CONFIG0
,
l
);
rfbi_write_reg
(
RFBI_DATA_CYCLE1_0
,
0x00000010
);
l
=
rfbi_read_reg
(
RFBI_CONTROL
);
/* Select CS0, clear bypass mode */
l
=
(
0x01
<<
2
);
rfbi_write_reg
(
RFBI_CONTROL
,
l
);
r
=
omap_dispc_request_irq
(
DISPC_IRQ_FRAMEMASK
,
rfbi_dma_callback
,
NULL
);
if
(
r
<
0
)
{
dev_err
(
fbdev
->
dev
,
"can't get DISPC irq
\n
"
);
rfbi_enable_clocks
(
0
);
return
r
;
}
l
=
rfbi_read_reg
(
RFBI_REVISION
);
pr_info
(
"omapfb: RFBI version %d.%d initialized
\n
"
,
(
l
>>
4
)
&
0x0f
,
l
&
0x0f
);
rfbi_enable_clocks
(
0
);
return
0
;
}
static
void
rfbi_cleanup
(
void
)
{
omap_dispc_free_irq
(
DISPC_IRQ_FRAMEMASK
,
rfbi_dma_callback
,
NULL
);
rfbi_put_clocks
();
iounmap
(
rfbi
.
base
);
}
const
struct
lcd_ctrl_extif
omap2_ext_if
=
{
.
init
=
rfbi_init
,
.
cleanup
=
rfbi_cleanup
,
.
get_clk_info
=
rfbi_get_clk_info
,
.
get_max_tx_rate
=
rfbi_get_max_tx_rate
,
.
set_bits_per_cycle
=
rfbi_set_bits_per_cycle
,
.
convert_timings
=
rfbi_convert_timings
,
.
set_timings
=
rfbi_set_timings
,
.
write_command
=
rfbi_write_command
,
.
read_data
=
rfbi_read_data
,
.
write_data
=
rfbi_write_data
,
.
transfer_area
=
rfbi_transfer_area
,
.
setup_tearsync
=
rfbi_setup_tearsync
,
.
enable_tearsync
=
rfbi_enable_tearsync
,
.
max_transmit_size
=
(
u32
)
~
0
,
};
drivers/video/omap2/displays/panel-generic-dpi.c
View file @
e9fe8a71
...
...
@@ -363,6 +363,29 @@ static struct panel_config generic_dpi_panels[] = {
.
name
=
"ortustech_com43h4m10xtc"
,
},
/* Innolux AT080TN52 */
{
{
.
x_res
=
800
,
.
y_res
=
600
,
.
pixel_clock
=
41142
,
.
hsw
=
20
,
.
hfp
=
210
,
.
hbp
=
46
,
.
vsw
=
10
,
.
vfp
=
12
,
.
vbp
=
23
,
},
.
acb
=
0x0
,
.
config
=
OMAP_DSS_LCD_TFT
|
OMAP_DSS_LCD_IVS
|
OMAP_DSS_LCD_IHS
|
OMAP_DSS_LCD_IEO
,
.
name
=
"innolux_at080tn52"
,
},
};
struct
panel_drv_data
{
...
...
drivers/video/omap2/displays/panel-tpo-td043mtea1.c
View file @
e9fe8a71
...
...
@@ -47,16 +47,20 @@
TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)
static
const
u16
tpo_td043_def_gamma
[
12
]
=
{
10
6
,
200
,
289
,
375
,
460
,
543
,
625
,
705
,
785
,
864
,
942
,
1020
10
5
,
315
,
381
,
431
,
490
,
537
,
579
,
686
,
780
,
837
,
880
,
1023
};
struct
tpo_td043_device
{
struct
spi_device
*
spi
;
struct
regulator
*
vcc_reg
;
int
nreset_gpio
;
u16
gamma
[
12
];
u32
mode
;
u32
hmirror
:
1
;
u32
vmirror
:
1
;
u32
powered_on
:
1
;
u32
spi_suspended
:
1
;
u32
power_on_resume
:
1
;
};
static
int
tpo_td043_write
(
struct
spi_device
*
spi
,
u8
addr
,
u8
data
)
...
...
@@ -265,28 +269,16 @@ static const struct omap_video_timings tpo_td043_timings = {
.
vbp
=
34
,
};
static
int
tpo_td043_power_on
(
struct
omap_dss_device
*
dssdev
)
static
int
tpo_td043_power_on
(
struct
tpo_td043_device
*
tpo_td043
)
{
struct
tpo_td043_device
*
tpo_td043
=
dev_get_drvdata
(
&
dssdev
->
dev
);
int
nreset_gpio
=
dssdev
->
reset_gpio
;
int
r
;
int
nreset_gpio
=
tpo_td043
->
nreset_gpio
;
if
(
dssdev
->
state
==
OMAP_DSS_DISPLAY_ACTIVE
)
if
(
tpo_td043
->
powered_on
)
return
0
;
r
=
omapdss_dpi_display_enable
(
dssdev
);
if
(
r
)
goto
err0
;
if
(
dssdev
->
platform_enable
)
{
r
=
dssdev
->
platform_enable
(
dssdev
);
if
(
r
)
goto
err1
;
}
regulator_enable
(
tpo_td043
->
vcc_reg
);
/* wait for
power up
*/
/* wait for
regulator to stabilize
*/
msleep
(
160
);
if
(
gpio_is_valid
(
nreset_gpio
))
...
...
@@ -301,19 +293,15 @@ static int tpo_td043_power_on(struct omap_dss_device *dssdev)
tpo_td043
->
vmirror
);
tpo_td043_write_gamma
(
tpo_td043
->
spi
,
tpo_td043
->
gamma
);
tpo_td043
->
powered_on
=
1
;
return
0
;
err1:
omapdss_dpi_display_disable
(
dssdev
);
err0:
return
r
;
}
static
void
tpo_td043_power_off
(
struct
omap_dss_device
*
dssdev
)
static
void
tpo_td043_power_off
(
struct
tpo_td043_device
*
tpo_td043
)
{
struct
tpo_td043_device
*
tpo_td043
=
dev_get_drvdata
(
&
dssdev
->
dev
);
int
nreset_gpio
=
dssdev
->
reset_gpio
;
int
nreset_gpio
=
tpo_td043
->
nreset_gpio
;
if
(
dssdev
->
state
!=
OMAP_DSS_DISPLAY_ACTIVE
)
if
(
!
tpo_td043
->
powered_on
)
return
;
tpo_td043_write
(
tpo_td043
->
spi
,
3
,
...
...
@@ -329,54 +317,94 @@ static void tpo_td043_power_off(struct omap_dss_device *dssdev)
regulator_disable
(
tpo_td043
->
vcc_reg
);
tpo_td043
->
powered_on
=
0
;
}
static
int
tpo_td043_enable_dss
(
struct
omap_dss_device
*
dssdev
)
{
struct
tpo_td043_device
*
tpo_td043
=
dev_get_drvdata
(
&
dssdev
->
dev
);
int
r
;
if
(
dssdev
->
state
==
OMAP_DSS_DISPLAY_ACTIVE
)
return
0
;
r
=
omapdss_dpi_display_enable
(
dssdev
);
if
(
r
)
goto
err0
;
if
(
dssdev
->
platform_enable
)
{
r
=
dssdev
->
platform_enable
(
dssdev
);
if
(
r
)
goto
err1
;
}
/*
* If we are resuming from system suspend, SPI clocks might not be
* enabled yet, so we'll program the LCD from SPI PM resume callback.
*/
if
(
!
tpo_td043
->
spi_suspended
)
{
r
=
tpo_td043_power_on
(
tpo_td043
);
if
(
r
)
goto
err1
;
}
dssdev
->
state
=
OMAP_DSS_DISPLAY_ACTIVE
;
return
0
;
err1:
omapdss_dpi_display_disable
(
dssdev
);
err0:
return
r
;
}
static
void
tpo_td043_disable_dss
(
struct
omap_dss_device
*
dssdev
)
{
struct
tpo_td043_device
*
tpo_td043
=
dev_get_drvdata
(
&
dssdev
->
dev
);
if
(
dssdev
->
state
!=
OMAP_DSS_DISPLAY_ACTIVE
)
return
;
if
(
dssdev
->
platform_disable
)
dssdev
->
platform_disable
(
dssdev
);
omapdss_dpi_display_disable
(
dssdev
);
if
(
!
tpo_td043
->
spi_suspended
)
tpo_td043_power_off
(
tpo_td043
);
}
static
int
tpo_td043_enable
(
struct
omap_dss_device
*
dssdev
)
{
int
ret
;
dev_dbg
(
&
dssdev
->
dev
,
"enable
\n
"
);
ret
=
tpo_td043_power_on
(
dssdev
);
if
(
ret
)
return
ret
;
dssdev
->
state
=
OMAP_DSS_DISPLAY_ACTIVE
;
return
0
;
return
tpo_td043_enable_dss
(
dssdev
);
}
static
void
tpo_td043_disable
(
struct
omap_dss_device
*
dssdev
)
{
dev_dbg
(
&
dssdev
->
dev
,
"disable
\n
"
);
tpo_td043_
power_off
(
dssdev
);
tpo_td043_
disable_dss
(
dssdev
);
dssdev
->
state
=
OMAP_DSS_DISPLAY_DISABLED
;
}
static
int
tpo_td043_suspend
(
struct
omap_dss_device
*
dssdev
)
{
tpo_td043_power_off
(
dssdev
);
dev_dbg
(
&
dssdev
->
dev
,
"suspend
\n
"
);
tpo_td043_disable_dss
(
dssdev
);
dssdev
->
state
=
OMAP_DSS_DISPLAY_SUSPENDED
;
return
0
;
}
static
int
tpo_td043_resume
(
struct
omap_dss_device
*
dssdev
)
{
int
r
=
0
;
r
=
tpo_td043_power_on
(
dssdev
);
if
(
r
)
return
r
;
dssdev
->
state
=
OMAP_DSS_DISPLAY_ACTIVE
;
dev_dbg
(
&
dssdev
->
dev
,
"resume
\n
"
);
return
0
;
return
tpo_td043_enable_dss
(
dssdev
)
;
}
static
int
tpo_td043_probe
(
struct
omap_dss_device
*
dssdev
)
...
...
@@ -484,6 +512,7 @@ static int tpo_td043_spi_probe(struct spi_device *spi)
return
-
ENOMEM
;
tpo_td043
->
spi
=
spi
;
tpo_td043
->
nreset_gpio
=
dssdev
->
reset_gpio
;
dev_set_drvdata
(
&
spi
->
dev
,
tpo_td043
);
dev_set_drvdata
(
&
dssdev
->
dev
,
tpo_td043
);
...
...
@@ -502,10 +531,46 @@ static int __devexit tpo_td043_spi_remove(struct spi_device *spi)
return
0
;
}
#ifdef CONFIG_PM_SLEEP
static
int
tpo_td043_spi_suspend
(
struct
device
*
dev
)
{
struct
tpo_td043_device
*
tpo_td043
=
dev_get_drvdata
(
dev
);
dev_dbg
(
dev
,
"tpo_td043_spi_suspend, tpo %p
\n
"
,
tpo_td043
);
tpo_td043
->
power_on_resume
=
tpo_td043
->
powered_on
;
tpo_td043_power_off
(
tpo_td043
);
tpo_td043
->
spi_suspended
=
1
;
return
0
;
}
static
int
tpo_td043_spi_resume
(
struct
device
*
dev
)
{
struct
tpo_td043_device
*
tpo_td043
=
dev_get_drvdata
(
dev
);
int
ret
;
dev_dbg
(
dev
,
"tpo_td043_spi_resume
\n
"
);
if
(
tpo_td043
->
power_on_resume
)
{
ret
=
tpo_td043_power_on
(
tpo_td043
);
if
(
ret
)
return
ret
;
}
tpo_td043
->
spi_suspended
=
0
;
return
0
;
}
#endif
static
SIMPLE_DEV_PM_OPS
(
tpo_td043_spi_pm
,
tpo_td043_spi_suspend
,
tpo_td043_spi_resume
);
static
struct
spi_driver
tpo_td043_spi_driver
=
{
.
driver
=
{
.
name
=
"tpo_td043mtea1_panel_spi"
,
.
owner
=
THIS_MODULE
,
.
pm
=
&
tpo_td043_spi_pm
,
},
.
probe
=
tpo_td043_spi_probe
,
.
remove
=
__devexit_p
(
tpo_td043_spi_remove
),
...
...
drivers/video/omap2/dss/apply.c
View file @
e9fe8a71
...
...
@@ -105,6 +105,9 @@ static struct {
struct
ovl_priv_data
ovl_priv_data_array
[
MAX_DSS_OVERLAYS
];
struct
mgr_priv_data
mgr_priv_data_array
[
MAX_DSS_MANAGERS
];
bool
fifo_merge_dirty
;
bool
fifo_merge
;
bool
irq_enabled
;
}
dss_data
;
...
...
@@ -351,6 +354,7 @@ static void wait_pending_extra_info_updates(void)
bool
updating
;
unsigned
long
flags
;
unsigned
long
t
;
int
r
;
spin_lock_irqsave
(
&
data_lock
,
flags
);
...
...
@@ -366,11 +370,11 @@ static void wait_pending_extra_info_updates(void)
spin_unlock_irqrestore
(
&
data_lock
,
flags
);
t
=
msecs_to_jiffies
(
500
);
wait_for_completion_timeout
(
&
extra_updated_completion
,
t
);
updating
=
extra_info_update_ongoing
(
);
WARN_ON
(
updating
);
r
=
wait_for_completion_timeout
(
&
extra_updated_completion
,
t
);
if
(
r
==
0
)
DSSWARN
(
"timeout in wait_pending_extra_info_updates
\n
"
);
else
if
(
r
<
0
)
DSSERR
(
"wait_pending_extra_info_updates failed: %d
\n
"
,
r
);
}
int
dss_mgr_wait_for_go
(
struct
omap_overlay_manager
*
mgr
)
...
...
@@ -388,6 +392,10 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
if
(
mgr_manual_update
(
mgr
))
return
0
;
r
=
dispc_runtime_get
();
if
(
r
)
return
r
;
irq
=
dispc_mgr_get_vsync_irq
(
mgr
->
id
);
mp
=
get_mgr_priv
(
mgr
);
...
...
@@ -428,6 +436,8 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
}
}
dispc_runtime_put
();
return
r
;
}
...
...
@@ -451,6 +461,10 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
if
(
ovl_manual_update
(
ovl
))
return
0
;
r
=
dispc_runtime_get
();
if
(
r
)
return
r
;
irq
=
dispc_mgr_get_vsync_irq
(
ovl
->
manager
->
id
);
op
=
get_ovl_priv
(
ovl
);
...
...
@@ -491,6 +505,8 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
}
}
dispc_runtime_put
();
return
r
;
}
...
...
@@ -585,11 +601,40 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
}
}
static
void
dss_write_regs_common
(
void
)
{
const
int
num_mgrs
=
omap_dss_get_num_overlay_managers
();
int
i
;
if
(
!
dss_data
.
fifo_merge_dirty
)
return
;
for
(
i
=
0
;
i
<
num_mgrs
;
++
i
)
{
struct
omap_overlay_manager
*
mgr
;
struct
mgr_priv_data
*
mp
;
mgr
=
omap_dss_get_overlay_manager
(
i
);
mp
=
get_mgr_priv
(
mgr
);
if
(
mp
->
enabled
)
{
if
(
dss_data
.
fifo_merge_dirty
)
{
dispc_enable_fifomerge
(
dss_data
.
fifo_merge
);
dss_data
.
fifo_merge_dirty
=
false
;
}
if
(
mp
->
updating
)
mp
->
shadow_info_dirty
=
true
;
}
}
}
static
void
dss_write_regs
(
void
)
{
const
int
num_mgrs
=
omap_dss_get_num_overlay_managers
();
int
i
;
dss_write_regs_common
();
for
(
i
=
0
;
i
<
num_mgrs
;
++
i
)
{
struct
omap_overlay_manager
*
mgr
;
struct
mgr_priv_data
*
mp
;
...
...
@@ -640,6 +685,22 @@ static void dss_set_go_bits(void)
}
static
void
mgr_clear_shadow_dirty
(
struct
omap_overlay_manager
*
mgr
)
{
struct
omap_overlay
*
ovl
;
struct
mgr_priv_data
*
mp
;
struct
ovl_priv_data
*
op
;
mp
=
get_mgr_priv
(
mgr
);
mp
->
shadow_info_dirty
=
false
;
list_for_each_entry
(
ovl
,
&
mgr
->
overlays
,
list
)
{
op
=
get_ovl_priv
(
ovl
);
op
->
shadow_info_dirty
=
false
;
op
->
shadow_extra_info_dirty
=
false
;
}
}
void
dss_mgr_start_update
(
struct
omap_overlay_manager
*
mgr
)
{
struct
mgr_priv_data
*
mp
=
get_mgr_priv
(
mgr
);
...
...
@@ -659,6 +720,8 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
dss_mgr_write_regs
(
mgr
);
dss_write_regs_common
();
mp
->
updating
=
true
;
if
(
!
dss_data
.
irq_enabled
&&
need_isr
())
...
...
@@ -666,6 +729,8 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
dispc_mgr_enable
(
mgr
->
id
,
true
);
mgr_clear_shadow_dirty
(
mgr
);
spin_unlock_irqrestore
(
&
data_lock
,
flags
);
}
...
...
@@ -709,22 +774,6 @@ static void dss_unregister_vsync_isr(void)
dss_data
.
irq_enabled
=
false
;
}
static
void
mgr_clear_shadow_dirty
(
struct
omap_overlay_manager
*
mgr
)
{
struct
omap_overlay
*
ovl
;
struct
mgr_priv_data
*
mp
;
struct
ovl_priv_data
*
op
;
mp
=
get_mgr_priv
(
mgr
);
mp
->
shadow_info_dirty
=
false
;
list_for_each_entry
(
ovl
,
&
mgr
->
overlays
,
list
)
{
op
=
get_ovl_priv
(
ovl
);
op
->
shadow_info_dirty
=
false
;
op
->
shadow_extra_info_dirty
=
false
;
}
}
static
void
dss_apply_irq_handler
(
void
*
data
,
u32
mask
)
{
const
int
num_mgrs
=
dss_feat_get_num_mgrs
();
...
...
@@ -754,9 +803,6 @@ static void dss_apply_irq_handler(void *data, u32 mask)
if
(
was_busy
&&
!
mp
->
busy
)
mgr_clear_shadow_dirty
(
mgr
);
}
else
{
if
(
was_updating
&&
!
mp
->
updating
)
mgr_clear_shadow_dirty
(
mgr
);
}
}
...
...
@@ -859,11 +905,20 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl,
op
->
extra_info_dirty
=
true
;
}
static
void
dss_ovl_setup_fifo
(
struct
omap_overlay
*
ovl
)
static
void
dss_apply_fifo_merge
(
bool
use_fifo_merge
)
{
if
(
dss_data
.
fifo_merge
==
use_fifo_merge
)
return
;
dss_data
.
fifo_merge
=
use_fifo_merge
;
dss_data
.
fifo_merge_dirty
=
true
;
}
static
void
dss_ovl_setup_fifo
(
struct
omap_overlay
*
ovl
,
bool
use_fifo_merge
)
{
struct
ovl_priv_data
*
op
=
get_ovl_priv
(
ovl
);
struct
omap_dss_device
*
dssdev
;
u32
size
,
burst_size
;
u32
fifo_low
,
fifo_high
;
if
(
!
op
->
enabled
&&
!
op
->
enabling
)
...
...
@@ -871,33 +926,14 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
dssdev
=
ovl
->
manager
->
device
;
size
=
dispc_ovl_get_fifo_size
(
ovl
->
id
);
burst_size
=
dispc_ovl_get_burst_size
(
ovl
->
id
);
switch
(
dssdev
->
type
)
{
case
OMAP_DISPLAY_TYPE_DPI
:
case
OMAP_DISPLAY_TYPE_DBI
:
case
OMAP_DISPLAY_TYPE_SDI
:
case
OMAP_DISPLAY_TYPE_VENC
:
case
OMAP_DISPLAY_TYPE_HDMI
:
default_get_overlay_fifo_thresholds
(
ovl
->
id
,
size
,
burst_size
,
&
fifo_low
,
&
fifo_high
);
break
;
#ifdef CONFIG_OMAP2_DSS_DSI
case
OMAP_DISPLAY_TYPE_DSI
:
dsi_get_overlay_fifo_thresholds
(
ovl
->
id
,
size
,
burst_size
,
&
fifo_low
,
&
fifo_high
);
break
;
#endif
default:
BUG
();
}
dispc_ovl_compute_fifo_thresholds
(
ovl
->
id
,
&
fifo_low
,
&
fifo_high
,
use_fifo_merge
);
dss_apply_ovl_fifo_thresholds
(
ovl
,
fifo_low
,
fifo_high
);
}
static
void
dss_mgr_setup_fifos
(
struct
omap_overlay_manager
*
mgr
)
static
void
dss_mgr_setup_fifos
(
struct
omap_overlay_manager
*
mgr
,
bool
use_fifo_merge
)
{
struct
omap_overlay
*
ovl
;
struct
mgr_priv_data
*
mp
;
...
...
@@ -908,19 +944,94 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
return
;
list_for_each_entry
(
ovl
,
&
mgr
->
overlays
,
list
)
dss_ovl_setup_fifo
(
ovl
);
dss_ovl_setup_fifo
(
ovl
,
use_fifo_merge
);
}
static
void
dss_setup_fifos
(
bool
use_fifo_merge
)
{
const
int
num_mgrs
=
omap_dss_get_num_overlay_managers
();
struct
omap_overlay_manager
*
mgr
;
int
i
;
for
(
i
=
0
;
i
<
num_mgrs
;
++
i
)
{
mgr
=
omap_dss_get_overlay_manager
(
i
);
dss_mgr_setup_fifos
(
mgr
,
use_fifo_merge
);
}
}
static
void
dss_setup_fifo
s
(
void
)
static
int
get_num_used_manager
s
(
void
)
{
const
int
num_mgrs
=
omap_dss_get_num_overlay_managers
();
struct
omap_overlay_manager
*
mgr
;
struct
mgr_priv_data
*
mp
;
int
i
;
int
enabled_mgrs
;
enabled_mgrs
=
0
;
for
(
i
=
0
;
i
<
num_mgrs
;
++
i
)
{
mgr
=
omap_dss_get_overlay_manager
(
i
);
dss_mgr_setup_fifos
(
mgr
);
mp
=
get_mgr_priv
(
mgr
);
if
(
!
mp
->
enabled
)
continue
;
enabled_mgrs
++
;
}
return
enabled_mgrs
;
}
static
int
get_num_used_overlays
(
void
)
{
const
int
num_ovls
=
omap_dss_get_num_overlays
();
struct
omap_overlay
*
ovl
;
struct
ovl_priv_data
*
op
;
struct
mgr_priv_data
*
mp
;
int
i
;
int
enabled_ovls
;
enabled_ovls
=
0
;
for
(
i
=
0
;
i
<
num_ovls
;
++
i
)
{
ovl
=
omap_dss_get_overlay
(
i
);
op
=
get_ovl_priv
(
ovl
);
if
(
!
op
->
enabled
&&
!
op
->
enabling
)
continue
;
mp
=
get_mgr_priv
(
ovl
->
manager
);
if
(
!
mp
->
enabled
)
continue
;
enabled_ovls
++
;
}
return
enabled_ovls
;
}
static
bool
get_use_fifo_merge
(
void
)
{
int
enabled_mgrs
=
get_num_used_managers
();
int
enabled_ovls
=
get_num_used_overlays
();
if
(
!
dss_has_feature
(
FEAT_FIFO_MERGE
))
return
false
;
/*
* In theory the only requirement for fifomerge is enabled_ovls <= 1.
* However, if we have two managers enabled and set/unset the fifomerge,
* we need to set the GO bits in particular sequence for the managers,
* and wait in between.
*
* This is rather difficult as new apply calls can happen at any time,
* so we simplify the problem by requiring also that enabled_mgrs <= 1.
* In practice this shouldn't matter, because when only one overlay is
* enabled, most likely only one output is enabled.
*/
return
enabled_mgrs
<=
1
&&
enabled_ovls
<=
1
;
}
int
dss_mgr_enable
(
struct
omap_overlay_manager
*
mgr
)
...
...
@@ -928,6 +1039,7 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
struct
mgr_priv_data
*
mp
=
get_mgr_priv
(
mgr
);
unsigned
long
flags
;
int
r
;
bool
fifo_merge
;
mutex_lock
(
&
apply_lock
);
...
...
@@ -945,11 +1057,23 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
goto
err
;
}
dss_setup_fifos
();
/* step 1: setup fifos/fifomerge before enabling the manager */
fifo_merge
=
get_use_fifo_merge
();
dss_setup_fifos
(
fifo_merge
);
dss_apply_fifo_merge
(
fifo_merge
);
dss_write_regs
();
dss_set_go_bits
();
spin_unlock_irqrestore
(
&
data_lock
,
flags
);
/* wait until fifo config is in */
wait_pending_extra_info_updates
();
/* step 2: enable the manager */
spin_lock_irqsave
(
&
data_lock
,
flags
);
if
(
!
mgr_manual_update
(
mgr
))
mp
->
updating
=
true
;
...
...
@@ -974,6 +1098,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
{
struct
mgr_priv_data
*
mp
=
get_mgr_priv
(
mgr
);
unsigned
long
flags
;
bool
fifo_merge
;
mutex_lock
(
&
apply_lock
);
...
...
@@ -988,8 +1113,16 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
mp
->
updating
=
false
;
mp
->
enabled
=
false
;
fifo_merge
=
get_use_fifo_merge
();
dss_setup_fifos
(
fifo_merge
);
dss_apply_fifo_merge
(
fifo_merge
);
dss_write_regs
();
dss_set_go_bits
();
spin_unlock_irqrestore
(
&
data_lock
,
flags
);
wait_pending_extra_info_updates
();
out:
mutex_unlock
(
&
apply_lock
);
}
...
...
@@ -1241,6 +1374,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
{
struct
ovl_priv_data
*
op
=
get_ovl_priv
(
ovl
);
unsigned
long
flags
;
bool
fifo_merge
;
int
r
;
mutex_lock
(
&
apply_lock
);
...
...
@@ -1266,7 +1400,22 @@ int dss_ovl_enable(struct omap_overlay *ovl)
goto
err2
;
}
dss_setup_fifos
();
/* step 1: configure fifos/fifomerge for currently enabled ovls */
fifo_merge
=
get_use_fifo_merge
();
dss_setup_fifos
(
fifo_merge
);
dss_apply_fifo_merge
(
fifo_merge
);
dss_write_regs
();
dss_set_go_bits
();
spin_unlock_irqrestore
(
&
data_lock
,
flags
);
/* wait for fifo configs to go in */
wait_pending_extra_info_updates
();
/* step 2: enable the overlay */
spin_lock_irqsave
(
&
data_lock
,
flags
);
op
->
enabling
=
false
;
dss_apply_ovl_enable
(
ovl
,
true
);
...
...
@@ -1294,6 +1443,7 @@ int dss_ovl_disable(struct omap_overlay *ovl)
{
struct
ovl_priv_data
*
op
=
get_ovl_priv
(
ovl
);
unsigned
long
flags
;
bool
fifo_merge
;
int
r
;
mutex_lock
(
&
apply_lock
);
...
...
@@ -1308,9 +1458,11 @@ int dss_ovl_disable(struct omap_overlay *ovl)
goto
err
;
}
/* step 1: disable the overlay */
spin_lock_irqsave
(
&
data_lock
,
flags
);
dss_apply_ovl_enable
(
ovl
,
false
);
dss_write_regs
();
dss_set_go_bits
();
...
...
@@ -1319,6 +1471,21 @@ int dss_ovl_disable(struct omap_overlay *ovl)
/* wait for the overlay to be disabled */
wait_pending_extra_info_updates
();
/* step 2: configure fifos/fifomerge */
spin_lock_irqsave
(
&
data_lock
,
flags
);
fifo_merge
=
get_use_fifo_merge
();
dss_setup_fifos
(
fifo_merge
);
dss_apply_fifo_merge
(
fifo_merge
);
dss_write_regs
();
dss_set_go_bits
();
spin_unlock_irqrestore
(
&
data_lock
,
flags
);
/* wait for fifo config to go in */
wait_pending_extra_info_updates
();
mutex_unlock
(
&
apply_lock
);
return
0
;
...
...
drivers/video/omap2/dss/dispc.c
View file @
e9fe8a71
...
...
@@ -37,7 +37,6 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <plat/sram.h>
#include <plat/clock.h>
#include <video/omapdss.h>
...
...
@@ -736,11 +735,11 @@ static void dispc_ovl_set_color_mode(enum omap_plane plane,
switch
(
color_mode
)
{
case
OMAP_DSS_COLOR_NV12
:
m
=
0x0
;
break
;
case
OMAP_DSS_COLOR_RGB
12U
:
case
OMAP_DSS_COLOR_RGB
X16
:
m
=
0x1
;
break
;
case
OMAP_DSS_COLOR_RGBA16
:
m
=
0x2
;
break
;
case
OMAP_DSS_COLOR_RGB
X16
:
case
OMAP_DSS_COLOR_RGB
12U
:
m
=
0x4
;
break
;
case
OMAP_DSS_COLOR_ARGB16
:
m
=
0x5
;
break
;
...
...
@@ -789,9 +788,9 @@ static void dispc_ovl_set_color_mode(enum omap_plane plane,
m
=
0x8
;
break
;
case
OMAP_DSS_COLOR_RGB24P
:
m
=
0x9
;
break
;
case
OMAP_DSS_COLOR_
YUV2
:
case
OMAP_DSS_COLOR_
RGBX16
:
m
=
0xa
;
break
;
case
OMAP_DSS_COLOR_
UYVY
:
case
OMAP_DSS_COLOR_
RGBA16
:
m
=
0xb
;
break
;
case
OMAP_DSS_COLOR_ARGB32
:
m
=
0xc
;
break
;
...
...
@@ -909,7 +908,7 @@ static void dispc_configure_burst_sizes(void)
dispc_ovl_set_burst_size
(
i
,
burst_size
);
}
u32
dispc_ovl_get_burst_size
(
enum
omap_plane
plane
)
static
u32
dispc_ovl_get_burst_size
(
enum
omap_plane
plane
)
{
unsigned
unit
=
dss_feat_get_burst_size_unit
();
/* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */
...
...
@@ -1018,7 +1017,7 @@ static void dispc_read_plane_fifo_sizes(void)
}
}
u32
dispc_ovl_get_fifo_size
(
enum
omap_plane
plane
)
static
u32
dispc_ovl_get_fifo_size
(
enum
omap_plane
plane
)
{
return
dispc
.
fifo_size
[
plane
];
}
...
...
@@ -1039,13 +1038,13 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
dss_feat_get_reg_field
(
FEAT_REG_FIFOHIGHTHRESHOLD
,
&
hi_start
,
&
hi_end
);
dss_feat_get_reg_field
(
FEAT_REG_FIFOLOWTHRESHOLD
,
&
lo_start
,
&
lo_end
);
DSSDBG
(
"fifo(%d)
low/high
old %u/%u, new %u/%u
\n
"
,
DSSDBG
(
"fifo(%d)
threshold (bytes),
old %u/%u, new %u/%u
\n
"
,
plane
,
REG_GET
(
DISPC_OVL_FIFO_THRESHOLD
(
plane
),
lo_start
,
lo_end
),
lo_start
,
lo_end
)
*
unit
,
REG_GET
(
DISPC_OVL_FIFO_THRESHOLD
(
plane
),
hi_start
,
hi_end
),
low
,
high
);
hi_start
,
hi_end
)
*
unit
,
low
*
unit
,
high
*
unit
);
dispc_write_reg
(
DISPC_OVL_FIFO_THRESHOLD
(
plane
),
FLD_VAL
(
high
,
hi_start
,
hi_end
)
|
...
...
@@ -1054,10 +1053,53 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
void
dispc_enable_fifomerge
(
bool
enable
)
{
if
(
!
dss_has_feature
(
FEAT_FIFO_MERGE
))
{
WARN_ON
(
enable
);
return
;
}
DSSDBG
(
"FIFO merge %s
\n
"
,
enable
?
"enabled"
:
"disabled"
);
REG_FLD_MOD
(
DISPC_CONFIG
,
enable
?
1
:
0
,
14
,
14
);
}
void
dispc_ovl_compute_fifo_thresholds
(
enum
omap_plane
plane
,
u32
*
fifo_low
,
u32
*
fifo_high
,
bool
use_fifomerge
)
{
/*
* All sizes are in bytes. Both the buffer and burst are made of
* buffer_units, and the fifo thresholds must be buffer_unit aligned.
*/
unsigned
buf_unit
=
dss_feat_get_buffer_size_unit
();
unsigned
ovl_fifo_size
,
total_fifo_size
,
burst_size
;
int
i
;
burst_size
=
dispc_ovl_get_burst_size
(
plane
);
ovl_fifo_size
=
dispc_ovl_get_fifo_size
(
plane
);
if
(
use_fifomerge
)
{
total_fifo_size
=
0
;
for
(
i
=
0
;
i
<
omap_dss_get_num_overlays
();
++
i
)
total_fifo_size
+=
dispc_ovl_get_fifo_size
(
i
);
}
else
{
total_fifo_size
=
ovl_fifo_size
;
}
/*
* We use the same low threshold for both fifomerge and non-fifomerge
* cases, but for fifomerge we calculate the high threshold using the
* combined fifo size
*/
if
(
dss_has_feature
(
FEAT_OMAP3_DSI_FIFO_BUG
))
{
*
fifo_low
=
ovl_fifo_size
-
burst_size
*
2
;
*
fifo_high
=
total_fifo_size
-
burst_size
;
}
else
{
*
fifo_low
=
ovl_fifo_size
-
burst_size
;
*
fifo_high
=
total_fifo_size
-
buf_unit
;
}
}
static
void
dispc_ovl_set_fir
(
enum
omap_plane
plane
,
int
hinc
,
int
vinc
,
enum
omap_color_component
color_comp
)
...
...
@@ -1651,6 +1693,7 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
u16
height
,
u16
out_width
,
u16
out_height
)
{
unsigned
int
hf
,
vf
;
unsigned
long
pclk
=
dispc_mgr_pclk_rate
(
channel
);
/*
* FIXME how to determine the 'A' factor
...
...
@@ -1673,13 +1716,16 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
if
(
cpu_is_omap24xx
())
{
if
(
vf
>
1
&&
hf
>
1
)
return
dispc_mgr_pclk_rate
(
channel
)
*
4
;
return
pclk
*
4
;
else
return
dispc_mgr_pclk_rate
(
channel
)
*
2
;
return
pclk
*
2
;
}
else
if
(
cpu_is_omap34xx
())
{
return
dispc_mgr_pclk_rate
(
channel
)
*
vf
*
hf
;
return
pclk
*
vf
*
hf
;
}
else
{
return
dispc_mgr_pclk_rate
(
channel
)
*
hf
;
if
(
hf
>
1
)
return
DIV_ROUND_UP
(
pclk
,
out_width
)
*
width
;
else
return
pclk
;
}
}
...
...
@@ -3298,15 +3344,6 @@ static int omap_dispchw_probe(struct platform_device *pdev)
dispc
.
pdev
=
pdev
;
clk
=
clk_get
(
&
pdev
->
dev
,
"fck"
);
if
(
IS_ERR
(
clk
))
{
DSSERR
(
"can't get fck
\n
"
);
r
=
PTR_ERR
(
clk
);
goto
err_get_clk
;
}
dispc
.
dss_clk
=
clk
;
spin_lock_init
(
&
dispc
.
irq_lock
);
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
...
...
@@ -3319,29 +3356,38 @@ static int omap_dispchw_probe(struct platform_device *pdev)
dispc_mem
=
platform_get_resource
(
dispc
.
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
dispc_mem
)
{
DSSERR
(
"can't get IORESOURCE_MEM DISPC
\n
"
);
r
=
-
EINVAL
;
goto
err_ioremap
;
return
-
EINVAL
;
}
dispc
.
base
=
ioremap
(
dispc_mem
->
start
,
resource_size
(
dispc_mem
));
dispc
.
base
=
devm_ioremap
(
&
pdev
->
dev
,
dispc_mem
->
start
,
resource_size
(
dispc_mem
));
if
(
!
dispc
.
base
)
{
DSSERR
(
"can't ioremap DISPC
\n
"
);
r
=
-
ENOMEM
;
goto
err_ioremap
;
return
-
ENOMEM
;
}
dispc
.
irq
=
platform_get_irq
(
dispc
.
pdev
,
0
);
if
(
dispc
.
irq
<
0
)
{
DSSERR
(
"platform_get_irq failed
\n
"
);
r
=
-
ENODEV
;
goto
err_irq
;
return
-
ENODEV
;
}
r
=
request_irq
(
dispc
.
irq
,
omap_dispc_irq_handler
,
IRQF_SHARED
,
"OMAP DISPC"
,
dispc
.
pdev
);
r
=
devm_request_irq
(
&
pdev
->
dev
,
dispc
.
irq
,
omap_dispc_irq_handler
,
IRQF_SHARED
,
"OMAP DISPC"
,
dispc
.
pdev
);
if
(
r
<
0
)
{
DSSERR
(
"request_irq failed
\n
"
);
goto
err_irq
;
return
r
;
}
clk
=
clk_get
(
&
pdev
->
dev
,
"fck"
);
if
(
IS_ERR
(
clk
))
{
DSSERR
(
"can't get fck
\n
"
);
r
=
PTR_ERR
(
clk
);
return
r
;
}
dispc
.
dss_clk
=
clk
;
pm_runtime_enable
(
&
pdev
->
dev
);
r
=
dispc_runtime_get
();
...
...
@@ -3362,12 +3408,7 @@ static int omap_dispchw_probe(struct platform_device *pdev)
err_runtime_get:
pm_runtime_disable
(
&
pdev
->
dev
);
free_irq
(
dispc
.
irq
,
dispc
.
pdev
);
err_irq:
iounmap
(
dispc
.
base
);
err_ioremap:
clk_put
(
dispc
.
dss_clk
);
err_get_clk:
return
r
;
}
...
...
@@ -3377,8 +3418,6 @@ static int omap_dispchw_remove(struct platform_device *pdev)
clk_put
(
dispc
.
dss_clk
);
free_irq
(
dispc
.
irq
,
dispc
.
pdev
);
iounmap
(
dispc
.
base
);
return
0
;
}
...
...
drivers/video/omap2/dss/dispc_coefs.c
View file @
e9fe8a71
...
...
@@ -19,14 +19,13 @@
#include <linux/kernel.h>
#include <video/omapdss.h>
#include "dispc.h"
#
define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
#
include "dispc.h"
static
const
struct
dispc_coef
coef3_M8
[
8
]
=
{
{
0
,
0
,
128
,
0
,
0
},
{
0
,
-
4
,
123
,
9
,
0
},
{
0
,
-
4
,
108
,
87
,
0
},
{
0
,
-
4
,
108
,
24
,
0
},
{
0
,
-
2
,
87
,
43
,
0
},
{
0
,
64
,
64
,
0
,
0
},
{
0
,
43
,
87
,
-
2
,
0
},
...
...
@@ -168,7 +167,7 @@ static const struct dispc_coef coef5_M8[8] = {
static
const
struct
dispc_coef
coef5_M9
[
8
]
=
{
{
-
3
,
10
,
114
,
10
,
-
3
},
{
-
6
,
24
,
11
0
,
0
,
-
1
},
{
-
6
,
24
,
11
1
,
0
,
-
1
},
{
-
8
,
40
,
103
,
-
7
,
0
},
{
-
11
,
58
,
91
,
-
11
,
1
},
{
0
,
-
12
,
76
,
76
,
-
12
},
...
...
@@ -319,7 +318,7 @@ const struct dispc_coef *dispc_ovl_get_scale_coef(int inc, int five_taps)
};
inc
/=
128
;
for
(
i
=
0
;
i
<
ARRAY_
LEN
(
coefs
);
++
i
)
for
(
i
=
0
;
i
<
ARRAY_
SIZE
(
coefs
);
++
i
)
if
(
inc
>=
coefs
[
i
].
Mmin
&&
inc
<=
coefs
[
i
].
Mmax
)
return
five_taps
?
coefs
[
i
].
coef_5
:
coefs
[
i
].
coef_3
;
return
NULL
;
...
...
drivers/video/omap2/dss/display.c
View file @
e9fe8a71
...
...
@@ -279,16 +279,6 @@ void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL
(
omapdss_default_get_resolution
);
void
default_get_overlay_fifo_thresholds
(
enum
omap_plane
plane
,
u32
fifo_size
,
u32
burst_size
,
u32
*
fifo_low
,
u32
*
fifo_high
)
{
unsigned
buf_unit
=
dss_feat_get_buffer_size_unit
();
*
fifo_high
=
fifo_size
-
buf_unit
;
*
fifo_low
=
fifo_size
-
burst_size
;
}
int
omapdss_default_get_recommended_bpp
(
struct
omap_dss_device
*
dssdev
)
{
switch
(
dssdev
->
type
)
{
...
...
drivers/video/omap2/dss/dsi.c
View file @
e9fe8a71
...
...
@@ -4524,14 +4524,6 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
}
EXPORT_SYMBOL
(
omapdss_dsi_enable_te
);
void
dsi_get_overlay_fifo_thresholds
(
enum
omap_plane
plane
,
u32
fifo_size
,
u32
burst_size
,
u32
*
fifo_low
,
u32
*
fifo_high
)
{
*
fifo_high
=
fifo_size
-
burst_size
;
*
fifo_low
=
fifo_size
-
burst_size
*
2
;
}
int
dsi_init_display
(
struct
omap_dss_device
*
dssdev
)
{
struct
platform_device
*
dsidev
=
dsi_get_dsidev_from_dssdev
(
dssdev
);
...
...
@@ -4695,11 +4687,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
struct
resource
*
dsi_mem
;
struct
dsi_data
*
dsi
;
dsi
=
kzalloc
(
sizeof
(
*
dsi
),
GFP_KERNEL
);
if
(
!
dsi
)
{
r
=
-
ENOMEM
;
goto
err_alloc
;
}
dsi
=
devm_kzalloc
(
&
dsidev
->
dev
,
sizeof
(
*
dsi
),
GFP_KERNEL
);
if
(
!
dsi
)
return
-
ENOMEM
;
dsi
->
pdev
=
dsidev
;
dsi_pdev_map
[
dsi_module
]
=
dsidev
;
...
...
@@ -4722,12 +4712,6 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
mutex_init
(
&
dsi
->
lock
);
sema_init
(
&
dsi
->
bus_lock
,
1
);
r
=
dsi_get_clocks
(
dsidev
);
if
(
r
)
goto
err_get_clk
;
pm_runtime_enable
(
&
dsidev
->
dev
);
INIT_DELAYED_WORK_DEFERRABLE
(
&
dsi
->
framedone_timeout_work
,
dsi_framedone_timeout_work_callback
);
...
...
@@ -4739,27 +4723,27 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
dsi_mem
=
platform_get_resource
(
dsi
->
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
dsi_mem
)
{
DSSERR
(
"can't get IORESOURCE_MEM DSI
\n
"
);
r
=
-
EINVAL
;
goto
err_ioremap
;
return
-
EINVAL
;
}
dsi
->
base
=
ioremap
(
dsi_mem
->
start
,
resource_size
(
dsi_mem
));
dsi
->
base
=
devm_ioremap
(
&
dsidev
->
dev
,
dsi_mem
->
start
,
resource_size
(
dsi_mem
));
if
(
!
dsi
->
base
)
{
DSSERR
(
"can't ioremap DSI
\n
"
);
r
=
-
ENOMEM
;
goto
err_ioremap
;
return
-
ENOMEM
;
}
dsi
->
irq
=
platform_get_irq
(
dsi
->
pdev
,
0
);
if
(
dsi
->
irq
<
0
)
{
DSSERR
(
"platform_get_irq failed
\n
"
);
r
=
-
ENODEV
;
goto
err_get_irq
;
return
-
ENODEV
;
}
r
=
request_irq
(
dsi
->
irq
,
omap_dsi_irq_handler
,
IRQF_SHARED
,
dev_name
(
&
dsidev
->
dev
),
dsi
->
pdev
);
r
=
devm_request_irq
(
&
dsidev
->
dev
,
dsi
->
irq
,
omap_dsi_irq_handler
,
IRQF_SHARED
,
dev_name
(
&
dsidev
->
dev
),
dsi
->
pdev
);
if
(
r
<
0
)
{
DSSERR
(
"request_irq failed
\n
"
);
goto
err_get_irq
;
return
r
;
}
/* DSI VCs initialization */
...
...
@@ -4771,9 +4755,15 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
dsi_calc_clock_param_ranges
(
dsidev
);
r
=
dsi_get_clocks
(
dsidev
);
if
(
r
)
return
r
;
pm_runtime_enable
(
&
dsidev
->
dev
);
r
=
dsi_runtime_get
(
dsidev
);
if
(
r
)
goto
err_
get_dsi
;
goto
err_
runtime_get
;
rev
=
dsi_read_reg
(
dsidev
,
DSI_REVISION
);
dev_dbg
(
&
dsidev
->
dev
,
"OMAP DSI rev %d.%d
\n
"
,
...
...
@@ -4791,15 +4781,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
return
0
;
err_get_dsi:
free_irq
(
dsi
->
irq
,
dsi
->
pdev
);
err_get_irq:
iounmap
(
dsi
->
base
);
err_ioremap:
err_runtime_get:
pm_runtime_disable
(
&
dsidev
->
dev
);
err_get_clk:
kfree
(
dsi
);
err_alloc:
dsi_put_clocks
(
dsidev
);
return
r
;
}
...
...
@@ -4823,11 +4807,6 @@ static int omap_dsihw_remove(struct platform_device *dsidev)
dsi
->
vdds_dsi_reg
=
NULL
;
}
free_irq
(
dsi
->
irq
,
dsi
->
pdev
);
iounmap
(
dsi
->
base
);
kfree
(
dsi
);
return
0
;
}
...
...
drivers/video/omap2/dss/dss.c
View file @
e9fe8a71
...
...
@@ -748,19 +748,19 @@ static int omap_dsshw_probe(struct platform_device *pdev)
dss_mem
=
platform_get_resource
(
dss
.
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
dss_mem
)
{
DSSERR
(
"can't get IORESOURCE_MEM DSS
\n
"
);
r
=
-
EINVAL
;
goto
err_ioremap
;
return
-
EINVAL
;
}
dss
.
base
=
ioremap
(
dss_mem
->
start
,
resource_size
(
dss_mem
));
dss
.
base
=
devm_ioremap
(
&
pdev
->
dev
,
dss_mem
->
start
,
resource_size
(
dss_mem
));
if
(
!
dss
.
base
)
{
DSSERR
(
"can't ioremap DSS
\n
"
);
r
=
-
ENOMEM
;
goto
err_ioremap
;
return
-
ENOMEM
;
}
r
=
dss_get_clocks
();
if
(
r
)
goto
err_clocks
;
return
r
;
pm_runtime_enable
(
&
pdev
->
dev
);
...
...
@@ -808,9 +808,6 @@ static int omap_dsshw_probe(struct platform_device *pdev)
err_runtime_get:
pm_runtime_disable
(
&
pdev
->
dev
);
dss_put_clocks
();
err_clocks:
iounmap
(
dss
.
base
);
err_ioremap:
return
r
;
}
...
...
@@ -819,8 +816,6 @@ static int omap_dsshw_remove(struct platform_device *pdev)
dpi_exit
();
sdi_exit
();
iounmap
(
dss
.
base
);
pm_runtime_disable
(
&
pdev
->
dev
);
dss_put_clocks
();
...
...
drivers/video/omap2/dss/dss.h
View file @
e9fe8a71
...
...
@@ -202,9 +202,6 @@ void dss_uninit_device(struct platform_device *pdev,
struct
omap_dss_device
*
dssdev
);
bool
dss_use_replication
(
struct
omap_dss_device
*
dssdev
,
enum
omap_color_mode
mode
);
void
default_get_overlay_fifo_thresholds
(
enum
omap_plane
plane
,
u32
fifo_size
,
u32
burst_size
,
u32
*
fifo_low
,
u32
*
fifo_high
);
/* manager */
int
dss_init_overlay_managers
(
struct
platform_device
*
pdev
);
...
...
@@ -313,9 +310,6 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
int
dsi_pll_init
(
struct
platform_device
*
dsidev
,
bool
enable_hsclk
,
bool
enable_hsdiv
);
void
dsi_pll_uninit
(
struct
platform_device
*
dsidev
,
bool
disconnect_lanes
);
void
dsi_get_overlay_fifo_thresholds
(
enum
omap_plane
plane
,
u32
fifo_size
,
u32
burst_size
,
u32
*
fifo_low
,
u32
*
fifo_high
);
void
dsi_wait_pll_hsdiv_dispc_active
(
struct
platform_device
*
dsidev
);
void
dsi_wait_pll_hsdiv_dsi_active
(
struct
platform_device
*
dsidev
);
struct
platform_device
*
dsi_get_dsidev_from_id
(
int
module
);
...
...
@@ -429,8 +423,8 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
void
dispc_ovl_set_fifo_threshold
(
enum
omap_plane
plane
,
u32
low
,
u32
high
);
u32
dispc_ovl_get_fifo_size
(
enum
omap_plane
plane
);
u32
dispc_ovl_get_burst_size
(
enum
omap_plane
plan
e
);
void
dispc_ovl_compute_fifo_thresholds
(
enum
omap_plane
plane
,
u32
*
fifo_low
,
u32
*
fifo_high
,
bool
use_fifomerg
e
);
int
dispc_ovl_setup
(
enum
omap_plane
plane
,
struct
omap_overlay_info
*
oi
,
bool
ilace
,
bool
replication
);
int
dispc_ovl_enable
(
enum
omap_plane
plane
,
bool
enable
);
...
...
drivers/video/omap2/dss/dss_features.c
View file @
e9fe8a71
...
...
@@ -41,7 +41,8 @@ struct omap_dss_features {
const
struct
dss_reg_field
*
reg_fields
;
const
int
num_reg_fields
;
const
u32
has_feature
;
const
enum
dss_feat_id
*
features
;
const
int
num_features
;
const
int
num_mgrs
;
const
int
num_ovls
;
...
...
@@ -189,7 +190,8 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
OMAP_DSS_COLOR_RGB16
|
OMAP_DSS_COLOR_RGB24U
|
OMAP_DSS_COLOR_RGB24P
|
OMAP_DSS_COLOR_ARGB32
|
OMAP_DSS_COLOR_RGBA32
|
OMAP_DSS_COLOR_RGBX32
|
OMAP_DSS_COLOR_ARGB16_1555
,
OMAP_DSS_COLOR_ARGB16_1555
|
OMAP_DSS_COLOR_RGBX16
|
OMAP_DSS_COLOR_RGBA16
|
OMAP_DSS_COLOR_XRGB16_1555
,
/* OMAP_DSS_VIDEO1 */
OMAP_DSS_COLOR_RGB16
|
OMAP_DSS_COLOR_RGB12U
|
...
...
@@ -337,15 +339,110 @@ static const struct dss_param_range omap4_dss_param_range[] = {
[
FEAT_PARAM_LINEWIDTH
]
=
{
1
,
2048
},
};
static
const
enum
dss_feat_id
omap2_dss_feat_list
[]
=
{
FEAT_LCDENABLEPOL
,
FEAT_LCDENABLESIGNAL
,
FEAT_PCKFREEENABLE
,
FEAT_FUNCGATED
,
FEAT_ROWREPEATENABLE
,
FEAT_RESIZECONF
,
};
static
const
enum
dss_feat_id
omap3430_dss_feat_list
[]
=
{
FEAT_LCDENABLEPOL
,
FEAT_LCDENABLESIGNAL
,
FEAT_PCKFREEENABLE
,
FEAT_FUNCGATED
,
FEAT_LINEBUFFERSPLIT
,
FEAT_ROWREPEATENABLE
,
FEAT_RESIZECONF
,
FEAT_DSI_PLL_FREQSEL
,
FEAT_DSI_REVERSE_TXCLKESC
,
FEAT_VENC_REQUIRES_TV_DAC_CLK
,
FEAT_CPR
,
FEAT_PRELOAD
,
FEAT_FIR_COEF_V
,
FEAT_ALPHA_FIXED_ZORDER
,
FEAT_FIFO_MERGE
,
FEAT_OMAP3_DSI_FIFO_BUG
,
};
static
const
enum
dss_feat_id
omap3630_dss_feat_list
[]
=
{
FEAT_LCDENABLEPOL
,
FEAT_LCDENABLESIGNAL
,
FEAT_PCKFREEENABLE
,
FEAT_FUNCGATED
,
FEAT_LINEBUFFERSPLIT
,
FEAT_ROWREPEATENABLE
,
FEAT_RESIZECONF
,
FEAT_DSI_PLL_PWR_BUG
,
FEAT_DSI_PLL_FREQSEL
,
FEAT_CPR
,
FEAT_PRELOAD
,
FEAT_FIR_COEF_V
,
FEAT_ALPHA_FIXED_ZORDER
,
FEAT_FIFO_MERGE
,
FEAT_OMAP3_DSI_FIFO_BUG
,
};
static
const
enum
dss_feat_id
omap4430_es1_0_dss_feat_list
[]
=
{
FEAT_MGR_LCD2
,
FEAT_CORE_CLK_DIV
,
FEAT_LCD_CLK_SRC
,
FEAT_DSI_DCS_CMD_CONFIG_VC
,
FEAT_DSI_VC_OCP_WIDTH
,
FEAT_DSI_GNQ
,
FEAT_HANDLE_UV_SEPARATE
,
FEAT_ATTR2
,
FEAT_CPR
,
FEAT_PRELOAD
,
FEAT_FIR_COEF_V
,
FEAT_ALPHA_FREE_ZORDER
,
FEAT_FIFO_MERGE
,
};
static
const
enum
dss_feat_id
omap4430_es2_0_1_2_dss_feat_list
[]
=
{
FEAT_MGR_LCD2
,
FEAT_CORE_CLK_DIV
,
FEAT_LCD_CLK_SRC
,
FEAT_DSI_DCS_CMD_CONFIG_VC
,
FEAT_DSI_VC_OCP_WIDTH
,
FEAT_DSI_GNQ
,
FEAT_HDMI_CTS_SWMODE
,
FEAT_HANDLE_UV_SEPARATE
,
FEAT_ATTR2
,
FEAT_CPR
,
FEAT_PRELOAD
,
FEAT_FIR_COEF_V
,
FEAT_ALPHA_FREE_ZORDER
,
FEAT_FIFO_MERGE
,
};
static
const
enum
dss_feat_id
omap4_dss_feat_list
[]
=
{
FEAT_MGR_LCD2
,
FEAT_CORE_CLK_DIV
,
FEAT_LCD_CLK_SRC
,
FEAT_DSI_DCS_CMD_CONFIG_VC
,
FEAT_DSI_VC_OCP_WIDTH
,
FEAT_DSI_GNQ
,
FEAT_HDMI_CTS_SWMODE
,
FEAT_HDMI_AUDIO_USE_MCLK
,
FEAT_HANDLE_UV_SEPARATE
,
FEAT_ATTR2
,
FEAT_CPR
,
FEAT_PRELOAD
,
FEAT_FIR_COEF_V
,
FEAT_ALPHA_FREE_ZORDER
,
FEAT_FIFO_MERGE
,
};
/* OMAP2 DSS Features */
static
const
struct
omap_dss_features
omap2_dss_features
=
{
.
reg_fields
=
omap2_dss_reg_fields
,
.
num_reg_fields
=
ARRAY_SIZE
(
omap2_dss_reg_fields
),
.
has_feature
=
FEAT_LCDENABLEPOL
|
FEAT_LCDENABLESIGNAL
|
FEAT_PCKFREEENABLE
|
FEAT_FUNCGATED
|
FEAT_ROWREPEATENABLE
|
FEAT_RESIZECONF
,
.
features
=
omap2_dss_feat_list
,
.
num_features
=
ARRAY_SIZE
(
omap2_dss_feat_list
),
.
num_mgrs
=
2
,
.
num_ovls
=
3
,
...
...
@@ -363,14 +460,8 @@ static const struct omap_dss_features omap3430_dss_features = {
.
reg_fields
=
omap3_dss_reg_fields
,
.
num_reg_fields
=
ARRAY_SIZE
(
omap3_dss_reg_fields
),
.
has_feature
=
FEAT_LCDENABLEPOL
|
FEAT_LCDENABLESIGNAL
|
FEAT_PCKFREEENABLE
|
FEAT_FUNCGATED
|
FEAT_ROWREPEATENABLE
|
FEAT_LINEBUFFERSPLIT
|
FEAT_RESIZECONF
|
FEAT_DSI_PLL_FREQSEL
|
FEAT_DSI_REVERSE_TXCLKESC
|
FEAT_VENC_REQUIRES_TV_DAC_CLK
|
FEAT_CPR
|
FEAT_PRELOAD
|
FEAT_FIR_COEF_V
|
FEAT_ALPHA_FIXED_ZORDER
,
.
features
=
omap3430_dss_feat_list
,
.
num_features
=
ARRAY_SIZE
(
omap3430_dss_feat_list
),
.
num_mgrs
=
2
,
.
num_ovls
=
3
,
...
...
@@ -387,14 +478,8 @@ static const struct omap_dss_features omap3630_dss_features = {
.
reg_fields
=
omap3_dss_reg_fields
,
.
num_reg_fields
=
ARRAY_SIZE
(
omap3_dss_reg_fields
),
.
has_feature
=
FEAT_LCDENABLEPOL
|
FEAT_LCDENABLESIGNAL
|
FEAT_PCKFREEENABLE
|
FEAT_FUNCGATED
|
FEAT_ROWREPEATENABLE
|
FEAT_LINEBUFFERSPLIT
|
FEAT_RESIZECONF
|
FEAT_DSI_PLL_PWR_BUG
|
FEAT_DSI_PLL_FREQSEL
|
FEAT_CPR
|
FEAT_PRELOAD
|
FEAT_FIR_COEF_V
|
FEAT_ALPHA_FIXED_ZORDER
,
.
features
=
omap3630_dss_feat_list
,
.
num_features
=
ARRAY_SIZE
(
omap3630_dss_feat_list
),
.
num_mgrs
=
2
,
.
num_ovls
=
3
,
...
...
@@ -413,13 +498,27 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
.
reg_fields
=
omap4_dss_reg_fields
,
.
num_reg_fields
=
ARRAY_SIZE
(
omap4_dss_reg_fields
),
.
has_feature
=
FEAT_MGR_LCD2
|
FEAT_CORE_CLK_DIV
|
FEAT_LCD_CLK_SRC
|
FEAT_DSI_DCS_CMD_CONFIG_VC
|
FEAT_DSI_VC_OCP_WIDTH
|
FEAT_DSI_GNQ
|
FEAT_HANDLE_UV_SEPARATE
|
FEAT_ATTR2
|
FEAT_CPR
|
FEAT_PRELOAD
|
FEAT_FIR_COEF_V
|
FEAT_ALPHA_FREE_ZORDER
,
.
features
=
omap4430_es1_0_dss_feat_list
,
.
num_features
=
ARRAY_SIZE
(
omap4430_es1_0_dss_feat_list
),
.
num_mgrs
=
3
,
.
num_ovls
=
4
,
.
supported_displays
=
omap4_dss_supported_displays
,
.
supported_color_modes
=
omap4_dss_supported_color_modes
,
.
overlay_caps
=
omap4_dss_overlay_caps
,
.
clksrc_names
=
omap4_dss_clk_source_names
,
.
dss_params
=
omap4_dss_param_range
,
.
buffer_size_unit
=
16
,
.
burst_size_unit
=
16
,
};
/* For OMAP4430 ES 2.0, 2.1 and 2.2 revisions */
static
const
struct
omap_dss_features
omap4430_es2_0_1_2_dss_features
=
{
.
reg_fields
=
omap4_dss_reg_fields
,
.
num_reg_fields
=
ARRAY_SIZE
(
omap4_dss_reg_fields
),
.
features
=
omap4430_es2_0_1_2_dss_feat_list
,
.
num_features
=
ARRAY_SIZE
(
omap4430_es2_0_1_2_dss_feat_list
),
.
num_mgrs
=
3
,
.
num_ovls
=
4
,
...
...
@@ -437,13 +536,8 @@ static const struct omap_dss_features omap4_dss_features = {
.
reg_fields
=
omap4_dss_reg_fields
,
.
num_reg_fields
=
ARRAY_SIZE
(
omap4_dss_reg_fields
),
.
has_feature
=
FEAT_MGR_LCD2
|
FEAT_CORE_CLK_DIV
|
FEAT_LCD_CLK_SRC
|
FEAT_DSI_DCS_CMD_CONFIG_VC
|
FEAT_DSI_VC_OCP_WIDTH
|
FEAT_DSI_GNQ
|
FEAT_HDMI_CTS_SWMODE
|
FEAT_HANDLE_UV_SEPARATE
|
FEAT_ATTR2
|
FEAT_CPR
|
FEAT_PRELOAD
|
FEAT_FIR_COEF_V
|
FEAT_ALPHA_FREE_ZORDER
,
.
features
=
omap4_dss_feat_list
,
.
num_features
=
ARRAY_SIZE
(
omap4_dss_feat_list
),
.
num_mgrs
=
3
,
.
num_ovls
=
4
,
...
...
@@ -547,7 +641,16 @@ u32 dss_feat_get_burst_size_unit(void)
/* DSS has_feature check */
bool
dss_has_feature
(
enum
dss_feat_id
id
)
{
return
omap_current_dss_features
->
has_feature
&
id
;
int
i
;
const
enum
dss_feat_id
*
features
=
omap_current_dss_features
->
features
;
const
int
num_features
=
omap_current_dss_features
->
num_features
;
for
(
i
=
0
;
i
<
num_features
;
i
++
)
{
if
(
features
[
i
]
==
id
)
return
true
;
}
return
false
;
}
void
dss_feat_get_reg_field
(
enum
dss_feat_reg_field
id
,
u8
*
start
,
u8
*
end
)
...
...
@@ -569,6 +672,10 @@ void dss_features_init(void)
omap_current_dss_features
=
&
omap3430_dss_features
;
else
if
(
omap_rev
()
==
OMAP4430_REV_ES1_0
)
omap_current_dss_features
=
&
omap4430_es1_0_dss_features
;
else
if
(
omap_rev
()
==
OMAP4430_REV_ES2_0
||
omap_rev
()
==
OMAP4430_REV_ES2_1
||
omap_rev
()
==
OMAP4430_REV_ES2_2
)
omap_current_dss_features
=
&
omap4430_es2_0_1_2_dss_features
;
else
if
(
cpu_is_omap44xx
())
omap_current_dss_features
=
&
omap4_dss_features
;
else
...
...
drivers/video/omap2/dss/dss_features.h
View file @
e9fe8a71
...
...
@@ -31,33 +31,37 @@
/* DSS has feature id */
enum
dss_feat_id
{
FEAT_LCDENABLEPOL
=
1
<<
3
,
FEAT_LCDENABLESIGNAL
=
1
<<
4
,
FEAT_PCKFREEENABLE
=
1
<<
5
,
FEAT_FUNCGATED
=
1
<<
6
,
FEAT_MGR_LCD2
=
1
<<
7
,
FEAT_LINEBUFFERSPLIT
=
1
<<
8
,
FEAT_ROWREPEATENABLE
=
1
<<
9
,
FEAT_RESIZECONF
=
1
<<
10
,
FEAT_LCDENABLEPOL
,
FEAT_LCDENABLESIGNAL
,
FEAT_PCKFREEENABLE
,
FEAT_FUNCGATED
,
FEAT_MGR_LCD2
,
FEAT_LINEBUFFERSPLIT
,
FEAT_ROWREPEATENABLE
,
FEAT_RESIZECONF
,
/* Independent core clk divider */
FEAT_CORE_CLK_DIV
=
1
<<
11
,
FEAT_LCD_CLK_SRC
=
1
<<
12
,
FEAT_CORE_CLK_DIV
,
FEAT_LCD_CLK_SRC
,
/* DSI-PLL power command 0x3 is not working */
FEAT_DSI_PLL_PWR_BUG
=
1
<<
13
,
FEAT_DSI_PLL_FREQSEL
=
1
<<
14
,
FEAT_DSI_DCS_CMD_CONFIG_VC
=
1
<<
15
,
FEAT_DSI_VC_OCP_WIDTH
=
1
<<
16
,
FEAT_DSI_REVERSE_TXCLKESC
=
1
<<
17
,
FEAT_DSI_GNQ
=
1
<<
18
,
FEAT_HDMI_CTS_SWMODE
=
1
<<
19
,
FEAT_HANDLE_UV_SEPARATE
=
1
<<
20
,
FEAT_ATTR2
=
1
<<
21
,
FEAT_VENC_REQUIRES_TV_DAC_CLK
=
1
<<
22
,
FEAT_CPR
=
1
<<
23
,
FEAT_PRELOAD
=
1
<<
24
,
FEAT_FIR_COEF_V
=
1
<<
25
,
FEAT_ALPHA_FIXED_ZORDER
=
1
<<
26
,
FEAT_ALPHA_FREE_ZORDER
=
1
<<
27
,
FEAT_DSI_PLL_PWR_BUG
,
FEAT_DSI_PLL_FREQSEL
,
FEAT_DSI_DCS_CMD_CONFIG_VC
,
FEAT_DSI_VC_OCP_WIDTH
,
FEAT_DSI_REVERSE_TXCLKESC
,
FEAT_DSI_GNQ
,
FEAT_HDMI_CTS_SWMODE
,
FEAT_HDMI_AUDIO_USE_MCLK
,
FEAT_HANDLE_UV_SEPARATE
,
FEAT_ATTR2
,
FEAT_VENC_REQUIRES_TV_DAC_CLK
,
FEAT_CPR
,
FEAT_PRELOAD
,
FEAT_FIR_COEF_V
,
FEAT_ALPHA_FIXED_ZORDER
,
FEAT_ALPHA_FREE_ZORDER
,
FEAT_FIFO_MERGE
,
/* An unknown HW bug causing the normal FIFO thresholds not to work */
FEAT_OMAP3_DSI_FIFO_BUG
,
};
/* DSS register field id */
...
...
drivers/video/omap2/dss/hdmi.c
View file @
e9fe8a71
...
...
@@ -58,8 +58,6 @@
#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
#define OMAP_HDMI_TIMINGS_NB 34
#define HDMI_DEFAULT_REGN 16
#define HDMI_DEFAULT_REGM2 1
...
...
@@ -68,8 +66,6 @@ static struct {
struct
omap_display_platform_data
*
pdata
;
struct
platform_device
*
pdev
;
struct
hdmi_ip_data
ip_data
;
int
code
;
int
mode
;
struct
clk
*
sys_clk
;
}
hdmi
;
...
...
@@ -88,77 +84,46 @@ static struct {
* map it to corresponding CEA or VESA index.
*/
static
const
struct
hdmi_timings
cea_vesa_timings
[
OMAP_HDMI_TIMINGS_NB
]
=
{
{
{
640
,
480
,
25200
,
96
,
16
,
48
,
2
,
10
,
33
}
,
0
,
0
},
{
{
1280
,
720
,
74250
,
40
,
440
,
220
,
5
,
5
,
20
},
1
,
1
},
{
{
1280
,
720
,
74250
,
40
,
110
,
220
,
5
,
5
,
20
},
1
,
1
},
{
{
720
,
480
,
27027
,
62
,
16
,
60
,
6
,
9
,
30
},
0
,
0
},
{
{
2880
,
576
,
108000
,
256
,
48
,
272
,
5
,
5
,
39
},
0
,
0
},
{
{
1440
,
240
,
27027
,
124
,
38
,
114
,
3
,
4
,
15
},
0
,
0
},
{
{
1440
,
288
,
27000
,
126
,
24
,
138
,
3
,
2
,
19
},
0
,
0
},
{
{
1920
,
540
,
74250
,
44
,
528
,
148
,
5
,
2
,
15
},
1
,
1
},
{
{
1920
,
540
,
74250
,
44
,
88
,
148
,
5
,
2
,
15
},
1
,
1
},
{
{
1920
,
1080
,
148500
,
44
,
88
,
148
,
5
,
4
,
36
},
1
,
1
},
{
{
720
,
576
,
27000
,
64
,
12
,
68
,
5
,
5
,
39
},
0
,
0
},
{
{
1440
,
576
,
54000
,
128
,
24
,
136
,
5
,
5
,
39
},
0
,
0
},
{
{
1920
,
1080
,
148500
,
44
,
528
,
148
,
5
,
4
,
36
},
1
,
1
},
{
{
2880
,
480
,
108108
,
248
,
64
,
240
,
6
,
9
,
30
},
0
,
0
},
{
{
1920
,
1080
,
74250
,
44
,
638
,
148
,
5
,
4
,
36
},
1
,
1
},
/* VESA From Here */
{
{
640
,
480
,
25175
,
96
,
16
,
48
,
2
,
11
,
31
},
0
,
0
},
{
{
800
,
600
,
40000
,
128
,
40
,
88
,
4
,
1
,
23
},
1
,
1
},
{
{
848
,
480
,
33750
,
112
,
16
,
112
,
8
,
6
,
23
},
1
,
1
},
{
{
1280
,
768
,
79500
,
128
,
64
,
192
,
7
,
3
,
20
},
1
,
0
},
{
{
1280
,
800
,
83500
,
128
,
72
,
200
,
6
,
3
,
22
},
1
,
0
},
{
{
1360
,
768
,
85500
,
112
,
64
,
256
,
6
,
3
,
18
},
1
,
1
},
{
{
1280
,
960
,
108000
,
112
,
96
,
312
,
3
,
1
,
36
},
1
,
1
},
{
{
1280
,
1024
,
108000
,
112
,
48
,
248
,
3
,
1
,
38
},
1
,
1
},
{
{
1024
,
768
,
65000
,
136
,
24
,
160
,
6
,
3
,
29
},
0
,
0
},
{
{
1400
,
1050
,
121750
,
144
,
88
,
232
,
4
,
3
,
32
},
1
,
0
},
{
{
1440
,
900
,
106500
,
152
,
80
,
232
,
6
,
3
,
25
},
1
,
0
},
{
{
1680
,
1050
,
146250
,
176
,
104
,
280
,
6
,
3
,
30
},
1
,
0
},
{
{
1366
,
768
,
85500
,
143
,
70
,
213
,
3
,
3
,
24
},
1
,
1
},
{
{
1920
,
1080
,
148500
,
44
,
148
,
80
,
5
,
4
,
36
},
1
,
1
},
{
{
1280
,
768
,
68250
,
32
,
48
,
80
,
7
,
3
,
12
},
0
,
1
},
{
{
1400
,
1050
,
101000
,
32
,
48
,
80
,
4
,
3
,
23
},
0
,
1
},
{
{
1680
,
1050
,
119000
,
32
,
48
,
80
,
6
,
3
,
21
},
0
,
1
},
{
{
1280
,
800
,
79500
,
32
,
48
,
80
,
6
,
3
,
14
},
0
,
1
},
{
{
1280
,
720
,
74250
,
40
,
110
,
220
,
5
,
5
,
20
},
1
,
1
}
};
/*
* This is a static mapping array which maps the timing values
* with corresponding CEA / VESA code
*/
static
const
int
code_index
[
OMAP_HDMI_TIMINGS_NB
]
=
{
1
,
19
,
4
,
2
,
37
,
6
,
21
,
20
,
5
,
16
,
17
,
29
,
31
,
35
,
32
,
/* <--15 CEA 17--> vesa*/
4
,
9
,
0xE
,
0x17
,
0x1C
,
0x27
,
0x20
,
0x23
,
0x10
,
0x2A
,
0X2F
,
0x3A
,
0X51
,
0X52
,
0x16
,
0x29
,
0x39
,
0x1B
static
const
struct
hdmi_config
cea_timings
[]
=
{
{
{
640
,
480
,
25200
,
96
,
16
,
48
,
2
,
10
,
33
,
0
,
0
,
0
},
{
1
,
HDMI_HDMI
}
},
{
{
720
,
480
,
27027
,
62
,
16
,
60
,
6
,
9
,
30
,
0
,
0
,
0
},
{
2
,
HDMI_HDMI
}
},
{
{
1280
,
720
,
74250
,
40
,
110
,
220
,
5
,
5
,
20
,
1
,
1
,
0
},
{
4
,
HDMI_HDMI
}
},
{
{
1920
,
540
,
74250
,
44
,
88
,
148
,
5
,
2
,
15
,
1
,
1
,
1
},
{
5
,
HDMI_HDMI
}
},
{
{
1440
,
240
,
27027
,
124
,
38
,
114
,
3
,
4
,
15
,
0
,
0
,
1
},
{
6
,
HDMI_HDMI
}
},
{
{
1920
,
1080
,
148500
,
44
,
88
,
148
,
5
,
4
,
36
,
1
,
1
,
0
},
{
16
,
HDMI_HDMI
}
},
{
{
720
,
576
,
27000
,
64
,
12
,
68
,
5
,
5
,
39
,
0
,
0
,
0
},
{
17
,
HDMI_HDMI
}
},
{
{
1280
,
720
,
74250
,
40
,
440
,
220
,
5
,
5
,
20
,
1
,
1
,
0
},
{
19
,
HDMI_HDMI
}
},
{
{
1920
,
540
,
74250
,
44
,
528
,
148
,
5
,
2
,
15
,
1
,
1
,
1
},
{
20
,
HDMI_HDMI
}
},
{
{
1440
,
288
,
27000
,
126
,
24
,
138
,
3
,
2
,
19
,
0
,
0
,
1
},
{
21
,
HDMI_HDMI
}
},
{
{
1440
,
576
,
54000
,
128
,
24
,
136
,
5
,
5
,
39
,
0
,
0
,
0
},
{
29
,
HDMI_HDMI
}
},
{
{
1920
,
1080
,
148500
,
44
,
528
,
148
,
5
,
4
,
36
,
1
,
1
,
0
},
{
31
,
HDMI_HDMI
}
},
{
{
1920
,
1080
,
74250
,
44
,
638
,
148
,
5
,
4
,
36
,
1
,
1
,
0
},
{
32
,
HDMI_HDMI
}
},
{
{
2880
,
480
,
108108
,
248
,
64
,
240
,
6
,
9
,
30
,
0
,
0
,
0
},
{
35
,
HDMI_HDMI
}
},
{
{
2880
,
576
,
108000
,
256
,
48
,
272
,
5
,
5
,
39
,
0
,
0
,
0
},
{
37
,
HDMI_HDMI
}
},
};
/*
* This is reverse static mapping which maps the CEA / VESA code
* to the corresponding timing values
*/
static
const
int
code_cea
[
39
]
=
{
-
1
,
0
,
3
,
3
,
2
,
8
,
5
,
5
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
9
,
10
,
10
,
1
,
7
,
6
,
6
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
11
,
11
,
12
,
14
,
-
1
,
-
1
,
13
,
13
,
4
,
4
static
const
struct
hdmi_config
vesa_timings
[]
=
{
/* VESA From Here */
{
{
640
,
480
,
25175
,
96
,
16
,
48
,
2
,
11
,
31
,
0
,
0
,
0
},
{
4
,
HDMI_DVI
}
},
{
{
800
,
600
,
40000
,
128
,
40
,
88
,
4
,
1
,
23
,
1
,
1
,
0
},
{
9
,
HDMI_DVI
}
},
{
{
848
,
480
,
33750
,
112
,
16
,
112
,
8
,
6
,
23
,
1
,
1
,
0
},
{
0xE
,
HDMI_DVI
}
},
{
{
1280
,
768
,
79500
,
128
,
64
,
192
,
7
,
3
,
20
,
1
,
0
,
0
},
{
0x17
,
HDMI_DVI
}
},
{
{
1280
,
800
,
83500
,
128
,
72
,
200
,
6
,
3
,
22
,
1
,
0
,
0
},
{
0x1C
,
HDMI_DVI
}
},
{
{
1360
,
768
,
85500
,
112
,
64
,
256
,
6
,
3
,
18
,
1
,
1
,
0
},
{
0x27
,
HDMI_DVI
}
},
{
{
1280
,
960
,
108000
,
112
,
96
,
312
,
3
,
1
,
36
,
1
,
1
,
0
},
{
0x20
,
HDMI_DVI
}
},
{
{
1280
,
1024
,
108000
,
112
,
48
,
248
,
3
,
1
,
38
,
1
,
1
,
0
},
{
0x23
,
HDMI_DVI
}
},
{
{
1024
,
768
,
65000
,
136
,
24
,
160
,
6
,
3
,
29
,
0
,
0
,
0
},
{
0x10
,
HDMI_DVI
}
},
{
{
1400
,
1050
,
121750
,
144
,
88
,
232
,
4
,
3
,
32
,
1
,
0
,
0
},
{
0x2A
,
HDMI_DVI
}
},
{
{
1440
,
900
,
106500
,
152
,
80
,
232
,
6
,
3
,
25
,
1
,
0
,
0
},
{
0x2F
,
HDMI_DVI
}
},
{
{
1680
,
1050
,
146250
,
176
,
104
,
280
,
6
,
3
,
30
,
1
,
0
,
0
},
{
0x3A
,
HDMI_DVI
}
},
{
{
1366
,
768
,
85500
,
143
,
70
,
213
,
3
,
3
,
24
,
1
,
1
,
0
},
{
0x51
,
HDMI_DVI
}
},
{
{
1920
,
1080
,
148500
,
44
,
148
,
80
,
5
,
4
,
36
,
1
,
1
,
0
},
{
0x52
,
HDMI_DVI
}
},
{
{
1280
,
768
,
68250
,
32
,
48
,
80
,
7
,
3
,
12
,
0
,
1
,
0
},
{
0x16
,
HDMI_DVI
}
},
{
{
1400
,
1050
,
101000
,
32
,
48
,
80
,
4
,
3
,
23
,
0
,
1
,
0
},
{
0x29
,
HDMI_DVI
}
},
{
{
1680
,
1050
,
119000
,
32
,
48
,
80
,
6
,
3
,
21
,
0
,
1
,
0
},
{
0x39
,
HDMI_DVI
}
},
{
{
1280
,
800
,
79500
,
32
,
48
,
80
,
6
,
3
,
14
,
0
,
1
,
0
},
{
0x1B
,
HDMI_DVI
}
},
{
{
1280
,
720
,
74250
,
40
,
110
,
220
,
5
,
5
,
20
,
1
,
1
,
0
},
{
0x55
,
HDMI_DVI
}
}
};
static
const
int
code_vesa
[
85
]
=
{
-
1
,
-
1
,
-
1
,
-
1
,
15
,
-
1
,
-
1
,
-
1
,
-
1
,
16
,
-
1
,
-
1
,
-
1
,
-
1
,
17
,
-
1
,
23
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
29
,
18
,
-
1
,
-
1
,
-
1
,
32
,
19
,
-
1
,
-
1
,
-
1
,
21
,
-
1
,
-
1
,
22
,
-
1
,
-
1
,
-
1
,
20
,
-
1
,
30
,
24
,
-
1
,
-
1
,
-
1
,
-
1
,
25
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
31
,
26
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
27
,
28
,
-
1
,
33
};
static
int
hdmi_runtime_get
(
void
)
{
int
r
;
...
...
@@ -210,88 +175,89 @@ int hdmi_init_display(struct omap_dss_device *dssdev)
return
0
;
}
static
int
get_timings_index
(
void
)
static
const
struct
hdmi_config
*
hdmi_find_timing
(
const
struct
hdmi_config
*
timings_arr
,
int
len
)
{
int
code
;
int
i
;
if
(
hdmi
.
mode
==
0
)
code
=
code_vesa
[
hdmi
.
code
];
else
code
=
code_cea
[
hdmi
.
code
];
for
(
i
=
0
;
i
<
len
;
i
++
)
{
if
(
timings_arr
[
i
].
cm
.
code
==
hdmi
.
ip_data
.
cfg
.
cm
.
code
)
return
&
timings_arr
[
i
];
}
return
NULL
;
}
if
(
code
==
-
1
)
{
/* HDMI code 4 corresponds to 640 * 480 VGA */
hdmi
.
code
=
4
;
/* DVI mode 1 corresponds to HDMI 0 to DVI */
hdmi
.
mode
=
HDMI_DVI
;
static
const
struct
hdmi_config
*
hdmi_get_timings
(
void
)
{
const
struct
hdmi_config
*
arr
;
int
len
;
if
(
hdmi
.
ip_data
.
cfg
.
cm
.
mode
==
HDMI_DVI
)
{
arr
=
vesa_timings
;
len
=
ARRAY_SIZE
(
vesa_timings
);
}
else
{
arr
=
cea_timings
;
len
=
ARRAY_SIZE
(
cea_timings
);
}
return
hdmi_find_timing
(
arr
,
len
);
}
static
bool
hdmi_timings_compare
(
struct
omap_video_timings
*
timing1
,
const
struct
hdmi_video_timings
*
timing2
)
{
int
timing1_vsync
,
timing1_hsync
,
timing2_vsync
,
timing2_hsync
;
code
=
code_vesa
[
hdmi
.
code
];
if
((
timing2
->
pixel_clock
==
timing1
->
pixel_clock
)
&&
(
timing2
->
x_res
==
timing1
->
x_res
)
&&
(
timing2
->
y_res
==
timing1
->
y_res
))
{
timing2_hsync
=
timing2
->
hfp
+
timing2
->
hsw
+
timing2
->
hbp
;
timing1_hsync
=
timing1
->
hfp
+
timing1
->
hsw
+
timing1
->
hbp
;
timing2_vsync
=
timing2
->
vfp
+
timing2
->
vsw
+
timing2
->
vbp
;
timing1_vsync
=
timing2
->
vfp
+
timing2
->
vsw
+
timing2
->
vbp
;
DSSDBG
(
"timing1_hsync = %d timing1_vsync = %d"
\
"timing2_hsync = %d timing2_vsync = %d
\n
"
,
timing1_hsync
,
timing1_vsync
,
timing2_hsync
,
timing2_vsync
);
if
((
timing1_hsync
==
timing2_hsync
)
&&
(
timing1_vsync
==
timing2_vsync
))
{
return
true
;
}
}
return
cod
e
;
return
fals
e
;
}
static
struct
hdmi_cm
hdmi_get_code
(
struct
omap_video_timings
*
timing
)
{
int
i
=
0
,
code
=
-
1
,
temp_vsync
=
0
,
temp_hsync
=
0
;
int
timing_vsync
=
0
,
timing_hsync
=
0
;
struct
hdmi_video_timings
temp
;
int
i
;
struct
hdmi_cm
cm
=
{
-
1
};
DSSDBG
(
"hdmi_get_code
\n
"
);
for
(
i
=
0
;
i
<
OMAP_HDMI_TIMINGS_NB
;
i
++
)
{
temp
=
cea_vesa_timings
[
i
].
timings
;
if
((
temp
.
pixel_clock
==
timing
->
pixel_clock
)
&&
(
temp
.
x_res
==
timing
->
x_res
)
&&
(
temp
.
y_res
==
timing
->
y_res
))
{
temp_hsync
=
temp
.
hfp
+
temp
.
hsw
+
temp
.
hbp
;
timing_hsync
=
timing
->
hfp
+
timing
->
hsw
+
timing
->
hbp
;
temp_vsync
=
temp
.
vfp
+
temp
.
vsw
+
temp
.
vbp
;
timing_vsync
=
timing
->
vfp
+
timing
->
vsw
+
timing
->
vbp
;
DSSDBG
(
"temp_hsync = %d , temp_vsync = %d"
"timing_hsync = %d, timing_vsync = %d
\n
"
,
temp_hsync
,
temp_hsync
,
timing_hsync
,
timing_vsync
);
if
((
temp_hsync
==
timing_hsync
)
&&
(
temp_vsync
==
timing_vsync
))
{
code
=
i
;
cm
.
code
=
code_index
[
i
];
if
(
code
<
14
)
cm
.
mode
=
HDMI_HDMI
;
else
cm
.
mode
=
HDMI_DVI
;
DSSDBG
(
"Hdmi_code = %d mode = %d
\n
"
,
cm
.
code
,
cm
.
mode
);
break
;
}
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
cea_timings
);
i
++
)
{
if
(
hdmi_timings_compare
(
timing
,
&
cea_timings
[
i
].
timings
))
{
cm
=
cea_timings
[
i
].
cm
;
goto
end
;
}
}
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
vesa_timings
);
i
++
)
{
if
(
hdmi_timings_compare
(
timing
,
&
vesa_timings
[
i
].
timings
))
{
cm
=
vesa_timings
[
i
].
cm
;
goto
end
;
}
}
return
cm
;
}
end:
return
cm
;
static
void
update_hdmi_timings
(
struct
hdmi_config
*
cfg
,
struct
omap_video_timings
*
timings
,
int
code
)
{
cfg
->
timings
.
timings
.
x_res
=
timings
->
x_res
;
cfg
->
timings
.
timings
.
y_res
=
timings
->
y_res
;
cfg
->
timings
.
timings
.
hbp
=
timings
->
hbp
;
cfg
->
timings
.
timings
.
hfp
=
timings
->
hfp
;
cfg
->
timings
.
timings
.
hsw
=
timings
->
hsw
;
cfg
->
timings
.
timings
.
vbp
=
timings
->
vbp
;
cfg
->
timings
.
timings
.
vfp
=
timings
->
vfp
;
cfg
->
timings
.
timings
.
vsw
=
timings
->
vsw
;
cfg
->
timings
.
timings
.
pixel_clock
=
timings
->
pixel_clock
;
cfg
->
timings
.
vsync_pol
=
cea_vesa_timings
[
code
].
vsync_pol
;
cfg
->
timings
.
hsync_pol
=
cea_vesa_timings
[
code
].
hsync_pol
;
}
unsigned
long
hdmi_get_pixel_clock
(
void
)
{
/* HDMI Pixel Clock in Mhz */
return
hdmi
.
ip_data
.
cfg
.
timings
.
timings
.
pixel_clock
*
1000
;
return
hdmi
.
ip_data
.
cfg
.
timings
.
pixel_clock
*
1000
;
}
static
void
hdmi_compute_pll
(
struct
omap_dss_device
*
dssdev
,
int
phy
,
...
...
@@ -312,24 +278,24 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
refclk
=
clkin
/
pi
->
regn
;
/*
* multiplier is pixel_clk/ref_clk
* Multiplying by 100 to avoid fractional part removal
*/
pi
->
regm
=
(
phy
*
100
/
(
refclk
))
/
100
;
if
(
dssdev
->
clocks
.
hdmi
.
regm2
==
0
)
pi
->
regm2
=
HDMI_DEFAULT_REGM2
;
else
pi
->
regm2
=
dssdev
->
clocks
.
hdmi
.
regm2
;
/*
* multiplier is pixel_clk/ref_clk
* Multiplying by 100 to avoid fractional part removal
*/
pi
->
regm
=
phy
*
pi
->
regm2
/
refclk
;
/*
* fractional multiplier is remainder of the difference between
* multiplier and actual phy(required pixel clock thus should be
* multiplied by 2^18(262144) divided by the reference clock
*/
mf
=
(
phy
-
pi
->
regm
*
refclk
)
*
262144
;
pi
->
regmf
=
mf
/
(
refclk
)
;
mf
=
(
phy
-
pi
->
regm
/
pi
->
regm2
*
refclk
)
*
262144
;
pi
->
regmf
=
pi
->
regm2
*
mf
/
refclk
;
/*
* Dcofreq should be set to 1 if required pixel clock
...
...
@@ -347,7 +313,8 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
static
int
hdmi_power_on
(
struct
omap_dss_device
*
dssdev
)
{
int
r
,
code
=
0
;
int
r
;
const
struct
hdmi_config
*
timing
;
struct
omap_video_timings
*
p
;
unsigned
long
phy
;
...
...
@@ -363,9 +330,16 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
dssdev
->
panel
.
timings
.
x_res
,
dssdev
->
panel
.
timings
.
y_res
);
code
=
get_timings_index
();
update_hdmi_timings
(
&
hdmi
.
ip_data
.
cfg
,
p
,
code
);
timing
=
hdmi_get_timings
();
if
(
timing
==
NULL
)
{
/* HDMI code 4 corresponds to 640 * 480 VGA */
hdmi
.
ip_data
.
cfg
.
cm
.
code
=
4
;
/* DVI mode 1 corresponds to HDMI 0 to DVI */
hdmi
.
ip_data
.
cfg
.
cm
.
mode
=
HDMI_DVI
;
hdmi
.
ip_data
.
cfg
=
vesa_timings
[
0
];
}
else
{
hdmi
.
ip_data
.
cfg
=
*
timing
;
}
phy
=
p
->
pixel_clock
;
hdmi_compute_pll
(
dssdev
,
phy
,
&
hdmi
.
ip_data
.
pll_data
);
...
...
@@ -385,8 +359,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
goto
err
;
}
hdmi
.
ip_data
.
cfg
.
cm
.
mode
=
hdmi
.
mode
;
hdmi
.
ip_data
.
cfg
.
cm
.
code
=
hdmi
.
code
;
hdmi
.
ip_data
.
ops
->
video_configure
(
&
hdmi
.
ip_data
);
/* Make selection of HDMI in DSS */
...
...
@@ -453,8 +425,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
struct
hdmi_cm
cm
;
cm
=
hdmi_get_code
(
&
dssdev
->
panel
.
timings
);
hdmi
.
code
=
cm
.
code
;
hdmi
.
mode
=
cm
.
mode
;
hdmi
.
ip_data
.
cfg
.
cm
.
code
=
cm
.
code
;
hdmi
.
ip_data
.
cfg
.
cm
.
mode
=
cm
.
mode
;
if
(
dssdev
->
state
==
OMAP_DSS_DISPLAY_ACTIVE
)
{
int
r
;
...
...
@@ -717,13 +689,15 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
if
(
dss_has_feature
(
FEAT_HDMI_CTS_SWMODE
))
{
core_cfg
.
aud_par_busclk
=
0
;
core_cfg
.
cts_mode
=
HDMI_AUDIO_CTS_MODE_SW
;
core_cfg
.
use_mclk
=
false
;
core_cfg
.
use_mclk
=
dss_has_feature
(
FEAT_HDMI_AUDIO_USE_MCLK
)
;
}
else
{
core_cfg
.
aud_par_busclk
=
(((
128
*
31
)
-
1
)
<<
8
);
core_cfg
.
cts_mode
=
HDMI_AUDIO_CTS_MODE_HW
;
core_cfg
.
use_mclk
=
true
;
core_cfg
.
mclk_mode
=
HDMI_AUDIO_MCLK_128FS
;
}
if
(
core_cfg
.
use_mclk
)
core_cfg
.
mclk_mode
=
HDMI_AUDIO_MCLK_128FS
;
core_cfg
.
layout
=
HDMI_AUDIO_LAYOUT_2CH
;
core_cfg
.
en_spdif
=
false
;
/* Use sample frequency from channel status word */
...
...
@@ -756,7 +730,7 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
static
int
hdmi_audio_startup
(
struct
snd_pcm_substream
*
substream
,
struct
snd_soc_dai
*
dai
)
{
if
(
!
hdmi
.
mode
)
{
if
(
!
hdmi
.
ip_data
.
cfg
.
cm
.
mode
)
{
pr_err
(
"Current video settings do not support audio.
\n
"
);
return
-
EIO
;
}
...
...
drivers/video/omap2/dss/manager.c
View file @
e9fe8a71
...
...
@@ -494,6 +494,11 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
{
unsigned
long
timeout
=
msecs_to_jiffies
(
500
);
u32
irq
;
int
r
;
r
=
dispc_runtime_get
();
if
(
r
)
return
r
;
if
(
mgr
->
device
->
type
==
OMAP_DISPLAY_TYPE_VENC
)
{
irq
=
DISPC_IRQ_EVSYNC_ODD
;
...
...
@@ -505,7 +510,12 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
else
irq
=
DISPC_IRQ_VSYNC2
;
}
return
omap_dispc_wait_for_irq_interruptible_timeout
(
irq
,
timeout
);
r
=
omap_dispc_wait_for_irq_interruptible_timeout
(
irq
,
timeout
);
dispc_runtime_put
();
return
r
;
}
int
dss_init_overlay_managers
(
struct
platform_device
*
pdev
)
...
...
drivers/video/omap2/dss/rfbi.c
View file @
e9fe8a71
...
...
@@ -922,35 +922,34 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
rfbi_mem
=
platform_get_resource
(
rfbi
.
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
rfbi_mem
)
{
DSSERR
(
"can't get IORESOURCE_MEM RFBI
\n
"
);
r
=
-
EINVAL
;
goto
err_ioremap
;
return
-
EINVAL
;
}
rfbi
.
base
=
ioremap
(
rfbi_mem
->
start
,
resource_size
(
rfbi_mem
));
rfbi
.
base
=
devm_ioremap
(
&
pdev
->
dev
,
rfbi_mem
->
start
,
resource_size
(
rfbi_mem
));
if
(
!
rfbi
.
base
)
{
DSSERR
(
"can't ioremap RFBI
\n
"
);
r
=
-
ENOMEM
;
goto
err_ioremap
;
return
-
ENOMEM
;
}
pm_runtime_enable
(
&
pdev
->
dev
);
r
=
rfbi_runtime_get
();
if
(
r
)
goto
err_get_rfbi
;
msleep
(
10
);
clk
=
clk_get
(
&
pdev
->
dev
,
"ick"
);
if
(
IS_ERR
(
clk
))
{
DSSERR
(
"can't get ick
\n
"
);
r
=
PTR_ERR
(
clk
);
goto
err_get_ick
;
return
PTR_ERR
(
clk
);
}
rfbi
.
l4_khz
=
clk_get_rate
(
clk
)
/
1000
;
clk_put
(
clk
);
pm_runtime_enable
(
&
pdev
->
dev
);
r
=
rfbi_runtime_get
();
if
(
r
)
goto
err_runtime_get
;
msleep
(
10
);
rev
=
rfbi_read_reg
(
RFBI_REVISION
);
dev_dbg
(
&
pdev
->
dev
,
"OMAP RFBI rev %d.%d
\n
"
,
FLD_GET
(
rev
,
7
,
4
),
FLD_GET
(
rev
,
3
,
0
));
...
...
@@ -959,19 +958,14 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
return
0
;
err_get_ick:
rfbi_runtime_put
();
err_get_rfbi:
err_runtime_get:
pm_runtime_disable
(
&
pdev
->
dev
);
iounmap
(
rfbi
.
base
);
err_ioremap:
return
r
;
}
static
int
omap_rfbihw_remove
(
struct
platform_device
*
pdev
)
{
pm_runtime_disable
(
&
pdev
->
dev
);
iounmap
(
rfbi
.
base
);
return
0
;
}
...
...
drivers/video/omap2/dss/ti_hdmi.h
View file @
e9fe8a71
...
...
@@ -42,6 +42,7 @@ enum hdmi_clk_refsel {
HDMI_REFSEL_SYSCLK
=
3
};
/* HDMI timing structure */
struct
hdmi_video_timings
{
u16
x_res
;
u16
y_res
;
...
...
@@ -53,13 +54,9 @@ struct hdmi_video_timings {
u16
vsw
;
u16
vfp
;
u16
vbp
;
};
/* HDMI timing structure */
struct
hdmi_timings
{
struct
hdmi_video_timings
timings
;
int
vsync_pol
;
int
hsync_pol
;
bool
vsync_pol
;
bool
hsync_pol
;
bool
interlace
;
};
struct
hdmi_cm
{
...
...
@@ -68,8 +65,7 @@ struct hdmi_cm {
};
struct
hdmi_config
{
struct
hdmi_timings
timings
;
u16
interlace
;
struct
hdmi_video_timings
timings
;
struct
hdmi_cm
cm
;
};
...
...
@@ -117,6 +113,47 @@ struct ti_hdmi_ip_ops {
};
/*
* Refer to section 8.2 in HDMI 1.3 specification for
* details about infoframe databytes
*/
struct
hdmi_core_infoframe_avi
{
/* Y0, Y1 rgb,yCbCr */
u8
db1_format
;
/* A0 Active information Present */
u8
db1_active_info
;
/* B0, B1 Bar info data valid */
u8
db1_bar_info_dv
;
/* S0, S1 scan information */
u8
db1_scan_info
;
/* C0, C1 colorimetry */
u8
db2_colorimetry
;
/* M0, M1 Aspect ratio (4:3, 16:9) */
u8
db2_aspect_ratio
;
/* R0...R3 Active format aspect ratio */
u8
db2_active_fmt_ar
;
/* ITC IT content. */
u8
db3_itc
;
/* EC0, EC1, EC2 Extended colorimetry */
u8
db3_ec
;
/* Q1, Q0 Quantization range */
u8
db3_q_range
;
/* SC1, SC0 Non-uniform picture scaling */
u8
db3_nup_scaling
;
/* VIC0..6 Video format identification */
u8
db4_videocode
;
/* PR0..PR3 Pixel repetition factor */
u8
db5_pixel_repeat
;
/* Line number end of top bar */
u16
db6_7_line_eoftop
;
/* Line number start of bottom bar */
u16
db8_9_line_sofbottom
;
/* Pixel number end of left bar */
u16
db10_11_pixel_eofleft
;
/* Pixel number start of right bar */
u16
db12_13_pixel_sofright
;
};
struct
hdmi_ip_data
{
void
__iomem
*
base_wp
;
/* HDMI wrapper */
unsigned
long
core_sys_offset
;
...
...
@@ -126,6 +163,7 @@ struct hdmi_ip_data {
const
struct
ti_hdmi_ip_ops
*
ops
;
struct
hdmi_config
cfg
;
struct
hdmi_pll_info
pll_data
;
struct
hdmi_core_infoframe_avi
avi_cfg
;
/* ti_hdmi_4xxx_ip private data. These should be in a separate struct */
int
hpd_gpio
;
...
...
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
View file @
e9fe8a71
...
...
@@ -587,12 +587,12 @@ static void hdmi_core_video_config(struct hdmi_ip_data *ip_data,
HDMI_CORE_SYS_TMDS_CTRL
,
cfg
->
tclk_sel_clkmult
,
6
,
5
);
}
static
void
hdmi_core_aux_infoframe_avi_config
(
struct
hdmi_ip_data
*
ip_data
,
struct
hdmi_core_infoframe_avi
info_avi
)
static
void
hdmi_core_aux_infoframe_avi_config
(
struct
hdmi_ip_data
*
ip_data
)
{
u32
val
;
char
sum
=
0
,
checksum
=
0
;
void
__iomem
*
av_base
=
hdmi_av_base
(
ip_data
);
struct
hdmi_core_infoframe_avi
info_avi
=
ip_data
->
avi_cfg
;
sum
+=
0x82
+
0x002
+
0x00D
;
hdmi_write_reg
(
av_base
,
HDMI_CORE_AV_AVI_TYPE
,
0x082
);
...
...
@@ -682,8 +682,7 @@ static void hdmi_core_av_packet_config(struct hdmi_ip_data *ip_data,
}
static
void
hdmi_wp_init
(
struct
omap_video_timings
*
timings
,
struct
hdmi_video_format
*
video_fmt
,
struct
hdmi_video_interface
*
video_int
)
struct
hdmi_video_format
*
video_fmt
)
{
pr_debug
(
"Enter hdmi_wp_init
\n
"
);
...
...
@@ -698,12 +697,6 @@ static void hdmi_wp_init(struct omap_video_timings *timings,
video_fmt
->
y_res
=
0
;
video_fmt
->
x_res
=
0
;
video_int
->
vsp
=
0
;
video_int
->
hsp
=
0
;
video_int
->
interlacing
=
0
;
video_int
->
tm
=
0
;
/* HDMI_TIMING_SLAVE */
}
void
ti_hdmi_4xxx_wp_video_start
(
struct
hdmi_ip_data
*
ip_data
,
bool
start
)
...
...
@@ -716,15 +709,15 @@ static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
{
pr_debug
(
"Enter hdmi_wp_video_init_format
\n
"
);
video_fmt
->
y_res
=
param
->
timings
.
timings
.
y_res
;
video_fmt
->
x_res
=
param
->
timings
.
timings
.
x_res
;
video_fmt
->
y_res
=
param
->
timings
.
y_res
;
video_fmt
->
x_res
=
param
->
timings
.
x_res
;
timings
->
hbp
=
param
->
timings
.
timings
.
hbp
;
timings
->
hfp
=
param
->
timings
.
timings
.
hfp
;
timings
->
hsw
=
param
->
timings
.
timings
.
hsw
;
timings
->
vbp
=
param
->
timings
.
timings
.
vbp
;
timings
->
vfp
=
param
->
timings
.
timings
.
vfp
;
timings
->
vsw
=
param
->
timings
.
timings
.
vsw
;
timings
->
hbp
=
param
->
timings
.
hbp
;
timings
->
hfp
=
param
->
timings
.
hfp
;
timings
->
hsw
=
param
->
timings
.
hsw
;
timings
->
vbp
=
param
->
timings
.
vbp
;
timings
->
vfp
=
param
->
timings
.
vfp
;
timings
->
vsw
=
param
->
timings
.
vsw
;
}
static
void
hdmi_wp_video_config_format
(
struct
hdmi_ip_data
*
ip_data
,
...
...
@@ -740,17 +733,16 @@ static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data,
hdmi_write_reg
(
hdmi_wp_base
(
ip_data
),
HDMI_WP_VIDEO_SIZE
,
l
);
}
static
void
hdmi_wp_video_config_interface
(
struct
hdmi_ip_data
*
ip_data
,
struct
hdmi_video_interface
*
video_int
)
static
void
hdmi_wp_video_config_interface
(
struct
hdmi_ip_data
*
ip_data
)
{
u32
r
;
pr_debug
(
"Enter hdmi_wp_video_config_interface
\n
"
);
r
=
hdmi_read_reg
(
hdmi_wp_base
(
ip_data
),
HDMI_WP_VIDEO_CFG
);
r
=
FLD_MOD
(
r
,
video_int
->
vsp
,
7
,
7
);
r
=
FLD_MOD
(
r
,
video_int
->
hsp
,
6
,
6
);
r
=
FLD_MOD
(
r
,
video_int
->
interlacing
,
3
,
3
);
r
=
FLD_MOD
(
r
,
video_int
->
tm
,
1
,
0
);
r
=
FLD_MOD
(
r
,
ip_data
->
cfg
.
timings
.
vsync_pol
,
7
,
7
);
r
=
FLD_MOD
(
r
,
ip_data
->
cfg
.
timings
.
hsync_pol
,
6
,
6
);
r
=
FLD_MOD
(
r
,
ip_data
->
cfg
.
timings
.
interlace
,
3
,
3
);
r
=
FLD_MOD
(
r
,
1
,
1
,
0
);
/* HDMI_TIMING_MASTER_24BIT */
hdmi_write_reg
(
hdmi_wp_base
(
ip_data
),
HDMI_WP_VIDEO_CFG
,
r
);
}
...
...
@@ -778,15 +770,13 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)
/* HDMI */
struct
omap_video_timings
video_timing
;
struct
hdmi_video_format
video_format
;
struct
hdmi_video_interface
video_interface
;
/* HDMI core */
struct
hdmi_core_infoframe_avi
avi_cfg
;
struct
hdmi_core_infoframe_avi
avi_cfg
=
ip_data
->
avi_cfg
;
struct
hdmi_core_video_config
v_core_cfg
;
struct
hdmi_core_packet_enable_repeat
repeat_cfg
;
struct
hdmi_config
*
cfg
=
&
ip_data
->
cfg
;
hdmi_wp_init
(
&
video_timing
,
&
video_format
,
&
video_interface
);
hdmi_wp_init
(
&
video_timing
,
&
video_format
);
hdmi_core_init
(
&
v_core_cfg
,
&
avi_cfg
,
...
...
@@ -801,12 +791,7 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)
hdmi_wp_video_config_format
(
ip_data
,
&
video_format
);
video_interface
.
vsp
=
cfg
->
timings
.
vsync_pol
;
video_interface
.
hsp
=
cfg
->
timings
.
hsync_pol
;
video_interface
.
interlacing
=
cfg
->
interlace
;
video_interface
.
tm
=
1
;
/* HDMI_TIMING_MASTER_24BIT */
hdmi_wp_video_config_interface
(
ip_data
,
&
video_interface
);
hdmi_wp_video_config_interface
(
ip_data
);
/*
* configure core video part
...
...
@@ -848,7 +833,7 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)
avi_cfg
.
db10_11_pixel_eofleft
=
0
;
avi_cfg
.
db12_13_pixel_sofright
=
0
;
hdmi_core_aux_infoframe_avi_config
(
ip_data
,
avi_cfg
);
hdmi_core_aux_infoframe_avi_config
(
ip_data
);
/* enable/repeat the infoframe */
repeat_cfg
.
avi_infoframe
=
HDMI_PACKETENABLE
;
...
...
@@ -1076,13 +1061,9 @@ void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
u32
r
;
void
__iomem
*
av_base
=
hdmi_av_base
(
ip_data
);
/* audio clock recovery parameters */
r
=
hdmi_read_reg
(
av_base
,
HDMI_CORE_AV_ACR_CTRL
);
r
=
FLD_MOD
(
r
,
cfg
->
use_mclk
,
2
,
2
);
r
=
FLD_MOD
(
r
,
cfg
->
en_acr_pkt
,
1
,
1
);
r
=
FLD_MOD
(
r
,
cfg
->
cts_mode
,
0
,
0
);
hdmi_write_reg
(
av_base
,
HDMI_CORE_AV_ACR_CTRL
,
r
);
/*
* Parameters for generation of Audio Clock Recovery packets
*/
REG_FLD_MOD
(
av_base
,
HDMI_CORE_AV_N_SVAL1
,
cfg
->
n
,
7
,
0
);
REG_FLD_MOD
(
av_base
,
HDMI_CORE_AV_N_SVAL2
,
cfg
->
n
>>
8
,
7
,
0
);
REG_FLD_MOD
(
av_base
,
HDMI_CORE_AV_N_SVAL3
,
cfg
->
n
>>
16
,
7
,
0
);
...
...
@@ -1094,14 +1075,6 @@ void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
REG_FLD_MOD
(
av_base
,
HDMI_CORE_AV_CTS_SVAL3
,
cfg
->
cts
>>
16
,
7
,
0
);
}
else
{
/*
* HDMI IP uses this configuration to divide the MCLK to
* update CTS value.
*/
REG_FLD_MOD
(
av_base
,
HDMI_CORE_AV_FREQ_SVAL
,
cfg
->
mclk_mode
,
2
,
0
);
/* Configure clock for audio packets */
REG_FLD_MOD
(
av_base
,
HDMI_CORE_AV_AUD_PAR_BUSCLK_1
,
cfg
->
aud_par_busclk
,
7
,
0
);
REG_FLD_MOD
(
av_base
,
HDMI_CORE_AV_AUD_PAR_BUSCLK_2
,
...
...
@@ -1110,6 +1083,25 @@ void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
(
cfg
->
aud_par_busclk
>>
16
),
7
,
0
);
}
/* Set ACR clock divisor */
REG_FLD_MOD
(
av_base
,
HDMI_CORE_AV_FREQ_SVAL
,
cfg
->
mclk_mode
,
2
,
0
);
r
=
hdmi_read_reg
(
av_base
,
HDMI_CORE_AV_ACR_CTRL
);
/*
* Use TMDS clock for ACR packets. For devices that use
* the MCLK, this is the first part of the MCLK initialization.
*/
r
=
FLD_MOD
(
r
,
0
,
2
,
2
);
r
=
FLD_MOD
(
r
,
cfg
->
en_acr_pkt
,
1
,
1
);
r
=
FLD_MOD
(
r
,
cfg
->
cts_mode
,
0
,
0
);
hdmi_write_reg
(
av_base
,
HDMI_CORE_AV_ACR_CTRL
,
r
);
/* For devices using MCLK, this completes its initialization. */
if
(
cfg
->
use_mclk
)
REG_FLD_MOD
(
av_base
,
HDMI_CORE_AV_ACR_CTRL
,
1
,
2
,
2
);
/* Override of SPDIF sample frequency with value in I2S_CHST4 */
REG_FLD_MOD
(
av_base
,
HDMI_CORE_AV_SPDIF_CTRL
,
cfg
->
fs_override
,
1
,
1
);
...
...
@@ -1205,7 +1197,7 @@ int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
{
u32
r
;
u32
deep_color
=
0
;
u32
pclk
=
ip_data
->
cfg
.
timings
.
timings
.
pixel_clock
;
u32
pclk
=
ip_data
->
cfg
.
timings
.
pixel_clock
;
if
(
n
==
NULL
||
cts
==
NULL
)
return
-
EINVAL
;
...
...
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
View file @
e9fe8a71
...
...
@@ -446,46 +446,6 @@ struct hdmi_core_video_config {
enum
hdmi_core_tclkselclkmult
tclk_sel_clkmult
;
};
/*
* Refer to section 8.2 in HDMI 1.3 specification for
* details about infoframe databytes
*/
struct
hdmi_core_infoframe_avi
{
/* Y0, Y1 rgb,yCbCr */
u8
db1_format
;
/* A0 Active information Present */
u8
db1_active_info
;
/* B0, B1 Bar info data valid */
u8
db1_bar_info_dv
;
/* S0, S1 scan information */
u8
db1_scan_info
;
/* C0, C1 colorimetry */
u8
db2_colorimetry
;
/* M0, M1 Aspect ratio (4:3, 16:9) */
u8
db2_aspect_ratio
;
/* R0...R3 Active format aspect ratio */
u8
db2_active_fmt_ar
;
/* ITC IT content. */
u8
db3_itc
;
/* EC0, EC1, EC2 Extended colorimetry */
u8
db3_ec
;
/* Q1, Q0 Quantization range */
u8
db3_q_range
;
/* SC1, SC0 Non-uniform picture scaling */
u8
db3_nup_scaling
;
/* VIC0..6 Video format identification */
u8
db4_videocode
;
/* PR0..PR3 Pixel repetition factor */
u8
db5_pixel_repeat
;
/* Line number end of top bar */
u16
db6_7_line_eoftop
;
/* Line number start of bottom bar */
u16
db8_9_line_sofbottom
;
/* Pixel number end of left bar */
u16
db10_11_pixel_eofleft
;
/* Pixel number start of right bar */
u16
db12_13_pixel_sofright
;
};
/*
* Refer to section 8.2 in HDMI 1.3 specification for
* details about infoframe databytes
...
...
@@ -517,13 +477,6 @@ struct hdmi_video_format {
u32
x_res
;
/* pixel per line */
};
struct
hdmi_video_interface
{
int
vsp
;
/* Vsync polarity */
int
hsp
;
/* Hsync polarity */
int
interlacing
;
int
tm
;
/* Timing mode */
};
struct
hdmi_audio_format
{
enum
hdmi_stereo_channels
stereo_channels
;
u8
active_chnnls_msk
;
...
...
drivers/video/omap2/dss/venc.c
View file @
e9fe8a71
...
...
@@ -699,6 +699,11 @@ void venc_dump_regs(struct seq_file *s)
{
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
if
(
cpu_is_omap44xx
())
{
seq_printf
(
s
,
"VENC currently disabled on OMAP44xx
\n
"
);
return
;
}
if
(
venc_runtime_get
())
return
;
...
...
@@ -790,39 +795,41 @@ static int omap_venchw_probe(struct platform_device *pdev)
venc_mem
=
platform_get_resource
(
venc
.
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
venc_mem
)
{
DSSERR
(
"can't get IORESOURCE_MEM VENC
\n
"
);
r
=
-
EINVAL
;
goto
err_ioremap
;
return
-
EINVAL
;
}
venc
.
base
=
ioremap
(
venc_mem
->
start
,
resource_size
(
venc_mem
));
venc
.
base
=
devm_ioremap
(
&
pdev
->
dev
,
venc_mem
->
start
,
resource_size
(
venc_mem
));
if
(
!
venc
.
base
)
{
DSSERR
(
"can't ioremap VENC
\n
"
);
r
=
-
ENOMEM
;
goto
err_ioremap
;
return
-
ENOMEM
;
}
r
=
venc_get_clocks
(
pdev
);
if
(
r
)
goto
err_get_clk
;
return
r
;
pm_runtime_enable
(
&
pdev
->
dev
);
r
=
venc_runtime_get
();
if
(
r
)
goto
err_
get_venc
;
goto
err_
runtime_get
;
rev_id
=
(
u8
)(
venc_read_reg
(
VENC_REV_ID
)
&
0xff
);
dev_dbg
(
&
pdev
->
dev
,
"OMAP VENC rev %d
\n
"
,
rev_id
);
venc_runtime_put
();
return
omap_dss_register_driver
(
&
venc_driver
);
r
=
omap_dss_register_driver
(
&
venc_driver
);
if
(
r
)
goto
err_reg_panel_driver
;
return
0
;
err_get_venc:
err_reg_panel_driver:
err_runtime_get:
pm_runtime_disable
(
&
pdev
->
dev
);
venc_put_clocks
();
err_get_clk:
iounmap
(
venc
.
base
);
err_ioremap:
return
r
;
}
...
...
@@ -837,7 +844,6 @@ static int omap_venchw_remove(struct platform_device *pdev)
pm_runtime_disable
(
&
pdev
->
dev
);
venc_put_clocks
();
iounmap
(
venc
.
base
);
return
0
;
}
...
...
drivers/video/omap2/omapfb/omapfb-ioctl.c
View file @
e9fe8a71
...
...
@@ -215,7 +215,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
int
r
=
0
,
i
;
size_t
size
;
if
(
mi
->
type
>
OMAPFB_MEMTYPE_MAX
)
if
(
mi
->
type
!=
OMAPFB_MEMTYPE_SDRAM
)
return
-
EINVAL
;
size
=
PAGE_ALIGN
(
mi
->
size
);
...
...
drivers/video/omap2/omapfb/omapfb-main.c
View file @
e9fe8a71
...
...
@@ -1399,7 +1399,7 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
if
(
!
paddr
)
{
DBG
(
"allocating %lu bytes for fb %d
\n
"
,
size
,
ofbi
->
id
);
r
=
omap_vram_alloc
(
OMAP_VRAM_MEMTYPE_SDRAM
,
size
,
&
paddr
);
r
=
omap_vram_alloc
(
size
,
&
paddr
);
}
else
{
DBG
(
"reserving %lu bytes at %lx for fb %d
\n
"
,
size
,
paddr
,
ofbi
->
id
);
...
...
@@ -1487,60 +1487,6 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
return
omapfb_alloc_fbmem
(
fbi
,
size
,
paddr
);
}
static
enum
omap_color_mode
fb_format_to_dss_mode
(
enum
omapfb_color_format
fmt
)
{
enum
omap_color_mode
mode
;
switch
(
fmt
)
{
case
OMAPFB_COLOR_RGB565
:
mode
=
OMAP_DSS_COLOR_RGB16
;
break
;
case
OMAPFB_COLOR_YUV422
:
mode
=
OMAP_DSS_COLOR_YUV2
;
break
;
case
OMAPFB_COLOR_CLUT_8BPP
:
mode
=
OMAP_DSS_COLOR_CLUT8
;
break
;
case
OMAPFB_COLOR_CLUT_4BPP
:
mode
=
OMAP_DSS_COLOR_CLUT4
;
break
;
case
OMAPFB_COLOR_CLUT_2BPP
:
mode
=
OMAP_DSS_COLOR_CLUT2
;
break
;
case
OMAPFB_COLOR_CLUT_1BPP
:
mode
=
OMAP_DSS_COLOR_CLUT1
;
break
;
case
OMAPFB_COLOR_RGB444
:
mode
=
OMAP_DSS_COLOR_RGB12U
;
break
;
case
OMAPFB_COLOR_YUY422
:
mode
=
OMAP_DSS_COLOR_UYVY
;
break
;
case
OMAPFB_COLOR_ARGB16
:
mode
=
OMAP_DSS_COLOR_ARGB16
;
break
;
case
OMAPFB_COLOR_RGB24U
:
mode
=
OMAP_DSS_COLOR_RGB24U
;
break
;
case
OMAPFB_COLOR_RGB24P
:
mode
=
OMAP_DSS_COLOR_RGB24P
;
break
;
case
OMAPFB_COLOR_ARGB32
:
mode
=
OMAP_DSS_COLOR_ARGB32
;
break
;
case
OMAPFB_COLOR_RGBA32
:
mode
=
OMAP_DSS_COLOR_RGBA32
;
break
;
case
OMAPFB_COLOR_RGBX32
:
mode
=
OMAP_DSS_COLOR_RGBX32
;
break
;
default:
mode
=
-
EINVAL
;
}
return
mode
;
}
static
int
omapfb_parse_vram_param
(
const
char
*
param
,
int
max_entries
,
unsigned
long
*
sizes
,
unsigned
long
*
paddrs
)
{
...
...
@@ -1614,23 +1560,6 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev)
memset
(
&
vram_paddrs
,
0
,
sizeof
(
vram_paddrs
));
}
if
(
fbdev
->
dev
->
platform_data
)
{
struct
omapfb_platform_data
*
opd
;
opd
=
fbdev
->
dev
->
platform_data
;
for
(
i
=
0
;
i
<
opd
->
mem_desc
.
region_cnt
;
++
i
)
{
if
(
!
vram_sizes
[
i
])
{
unsigned
long
size
;
unsigned
long
paddr
;
size
=
opd
->
mem_desc
.
region
[
i
].
size
;
paddr
=
opd
->
mem_desc
.
region
[
i
].
paddr
;
vram_sizes
[
i
]
=
size
;
vram_paddrs
[
i
]
=
paddr
;
}
}
}
for
(
i
=
0
;
i
<
fbdev
->
num_fbs
;
i
++
)
{
/* allocate memory automatically only for fb0, or if
* excplicitly defined with vram or plat data option */
...
...
@@ -1669,7 +1598,7 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
int
old_type
=
rg
->
type
;
int
r
;
if
(
type
>
OMAPFB_MEMTYPE_MAX
)
if
(
type
!=
OMAPFB_MEMTYPE_SDRAM
)
return
-
EINVAL
;
size
=
PAGE_ALIGN
(
size
);
...
...
@@ -1828,32 +1757,6 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
var
->
rotate
=
def_rotate
;
/*
* Check if there is a default color format set in the board file,
* and use this format instead the default deducted from the
* display bpp.
*/
if
(
fbdev
->
dev
->
platform_data
)
{
struct
omapfb_platform_data
*
opd
;
int
id
=
ofbi
->
id
;
opd
=
fbdev
->
dev
->
platform_data
;
if
(
opd
->
mem_desc
.
region
[
id
].
format_used
)
{
enum
omap_color_mode
mode
;
enum
omapfb_color_format
format
;
format
=
opd
->
mem_desc
.
region
[
id
].
format
;
mode
=
fb_format_to_dss_mode
(
format
);
if
(
mode
<
0
)
{
r
=
mode
;
goto
err
;
}
r
=
dss_mode_to_fb_mode
(
mode
,
var
);
if
(
r
<
0
)
goto
err
;
}
}
if
(
display
)
{
u16
w
,
h
;
int
rotation
=
(
var
->
rotate
+
ofbi
->
rotation
[
0
])
%
4
;
...
...
drivers/video/omap2/vram.c
View file @
e9fe8a71
...
...
@@ -33,7 +33,6 @@
#include <asm/setup.h>
#include <plat/sram.h>
#include <plat/vram.h>
#include <plat/dma.h>
...
...
@@ -43,10 +42,6 @@
#define DBG(format, ...)
#endif
#define OMAP2_SRAM_START 0x40200000
/* Maximum size, in reality this is smaller if SRAM is partially locked. */
#define OMAP2_SRAM_SIZE 0xa0000
/* 640k */
/* postponed regions are used to temporarily store region information at boot
* time when we cannot yet allocate the region list */
#define MAX_POSTPONED_REGIONS 10
...
...
@@ -74,15 +69,6 @@ struct vram_region {
static
DEFINE_MUTEX
(
region_mutex
);
static
LIST_HEAD
(
region_list
);
static
inline
int
region_mem_type
(
unsigned
long
paddr
)
{
if
(
paddr
>=
OMAP2_SRAM_START
&&
paddr
<
OMAP2_SRAM_START
+
OMAP2_SRAM_SIZE
)
return
OMAP_VRAM_MEMTYPE_SRAM
;
else
return
OMAP_VRAM_MEMTYPE_SDRAM
;
}
static
struct
vram_region
*
omap_vram_create_region
(
unsigned
long
paddr
,
unsigned
pages
)
{
...
...
@@ -212,9 +198,6 @@ static int _omap_vram_reserve(unsigned long paddr, unsigned pages)
DBG
(
"checking region %lx %d
\n
"
,
rm
->
paddr
,
rm
->
pages
);
if
(
region_mem_type
(
rm
->
paddr
)
!=
region_mem_type
(
paddr
))
continue
;
start
=
rm
->
paddr
;
end
=
start
+
(
rm
->
pages
<<
PAGE_SHIFT
)
-
1
;
if
(
start
>
paddr
||
end
<
paddr
+
size
-
1
)
...
...
@@ -320,7 +303,7 @@ static int _omap_vram_clear(u32 paddr, unsigned pages)
return
r
;
}
static
int
_omap_vram_alloc
(
int
mtype
,
unsigned
pages
,
unsigned
long
*
paddr
)
static
int
_omap_vram_alloc
(
unsigned
pages
,
unsigned
long
*
paddr
)
{
struct
vram_region
*
rm
;
struct
vram_alloc
*
alloc
;
...
...
@@ -330,9 +313,6 @@ static int _omap_vram_alloc(int mtype, unsigned pages, unsigned long *paddr)
DBG
(
"checking region %lx %d
\n
"
,
rm
->
paddr
,
rm
->
pages
);
if
(
region_mem_type
(
rm
->
paddr
)
!=
mtype
)
continue
;
start
=
rm
->
paddr
;
list_for_each_entry
(
alloc
,
&
rm
->
alloc_list
,
list
)
{
...
...
@@ -365,21 +345,21 @@ static int _omap_vram_alloc(int mtype, unsigned pages, unsigned long *paddr)
return
-
ENOMEM
;
}
int
omap_vram_alloc
(
int
mtype
,
size_t
size
,
unsigned
long
*
paddr
)
int
omap_vram_alloc
(
size_t
size
,
unsigned
long
*
paddr
)
{
unsigned
pages
;
int
r
;
BUG_ON
(
mtype
>
OMAP_VRAM_MEMTYPE_MAX
||
!
size
);
BUG_ON
(
!
size
);
DBG
(
"alloc mem
type %d size %d
\n
"
,
mtype
,
size
);
DBG
(
"alloc mem
size %d
\n
"
,
size
);
size
=
PAGE_ALIGN
(
size
);
pages
=
size
>>
PAGE_SHIFT
;
mutex_lock
(
&
region_mutex
);
r
=
_omap_vram_alloc
(
mtype
,
pages
,
paddr
);
r
=
_omap_vram_alloc
(
pages
,
paddr
);
mutex_unlock
(
&
region_mutex
);
...
...
@@ -500,10 +480,6 @@ arch_initcall(omap_vram_init);
/* boottime vram alloc stuff */
/* set from board file */
static
u32
omap_vram_sram_start
__initdata
;
static
u32
omap_vram_sram_size
__initdata
;
/* set from board file */
static
u32
omap_vram_sdram_start
__initdata
;
static
u32
omap_vram_sdram_size
__initdata
;
...
...
@@ -587,73 +563,8 @@ void __init omap_vram_reserve_sdram_memblock(void)
pr_info
(
"Reserving %u bytes SDRAM for VRAM
\n
"
,
size
);
}
/*
* Called at sram init time, before anything is pushed to the SRAM stack.
* Because of the stack scheme, we will allocate everything from the
* start of the lowest address region to the end of SRAM. This will also
* include padding for page alignment and possible holes between regions.
*
* As opposed to the SDRAM case, we'll also do any dynamic allocations at
* this point, since the driver built as a module would have problem with
* freeing / reallocating the regions.
*/
unsigned
long
__init
omap_vram_reserve_sram
(
unsigned
long
sram_pstart
,
unsigned
long
sram_vstart
,
unsigned
long
sram_size
,
unsigned
long
pstart_avail
,
unsigned
long
size_avail
)
{
unsigned
long
pend_avail
;
unsigned
long
reserved
;
u32
paddr
;
u32
size
;
paddr
=
omap_vram_sram_start
;
size
=
omap_vram_sram_size
;
if
(
!
size
)
return
0
;
reserved
=
0
;
pend_avail
=
pstart_avail
+
size_avail
;
if
(
!
paddr
)
{
/* Dynamic allocation */
if
((
size_avail
&
PAGE_MASK
)
<
size
)
{
pr_err
(
"Not enough SRAM for VRAM
\n
"
);
return
0
;
}
size_avail
=
(
size_avail
-
size
)
&
PAGE_MASK
;
paddr
=
pstart_avail
+
size_avail
;
}
if
(
paddr
<
sram_pstart
||
paddr
+
size
>
sram_pstart
+
sram_size
)
{
pr_err
(
"Illegal SRAM region for VRAM
\n
"
);
return
0
;
}
/* Reserve everything above the start of the region. */
if
(
pend_avail
-
paddr
>
reserved
)
reserved
=
pend_avail
-
paddr
;
size_avail
=
pend_avail
-
reserved
-
pstart_avail
;
omap_vram_add_region
(
paddr
,
size
);
if
(
reserved
)
pr_info
(
"Reserving %lu bytes SRAM for VRAM
\n
"
,
reserved
);
return
reserved
;
}
void
__init
omap_vram_set_sdram_vram
(
u32
size
,
u32
start
)
{
omap_vram_sdram_start
=
start
;
omap_vram_sdram_size
=
size
;
}
void
__init
omap_vram_set_sram_vram
(
u32
size
,
u32
start
)
{
omap_vram_sram_start
=
start
;
omap_vram_sram_size
=
size
;
}
include/linux/omapfb.h
View file @
e9fe8a71
...
...
@@ -222,41 +222,11 @@ struct omapfb_display_info {
#include <plat/board.h>
#ifdef CONFIG_ARCH_OMAP1
#define OMAPFB_PLANE_NUM 1
#else
#define OMAPFB_PLANE_NUM 3
#endif
struct
omapfb_mem_region
{
u32
paddr
;
void
__iomem
*
vaddr
;
unsigned
long
size
;
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
map
:
1
;
/* kernel mapped by the driver */
};
struct
omapfb_mem_desc
{
int
region_cnt
;
struct
omapfb_mem_region
region
[
OMAPFB_PLANE_NUM
];
};
struct
omapfb_platform_data
{
struct
omap_lcd_config
lcd
;
struct
omapfb_mem_desc
mem_desc
;
void
*
ctrl_platform_data
;
};
/* 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_reserve_sdram_memblock
(
void
);
void
__init
omapfb_set_lcd_config
(
const
struct
omap_lcd_config
*
config
);
#endif
...
...
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