aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c9
-rw-r--r--arch/arm/mach-omap1/board-fsample.c15
-rw-r--r--arch/arm/mach-omap1/board-h2.c15
-rw-r--r--arch/arm/mach-omap1/board-h3.c9
-rw-r--r--arch/arm/mach-omap1/board-htcherald.c9
-rw-r--r--arch/arm/mach-omap1/board-innovator.c11
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c19
-rw-r--r--arch/arm/mach-omap1/board-osk.c14
-rw-r--r--arch/arm/mach-omap1/board-palmte.c10
-rw-r--r--arch/arm/mach-omap1/board-palmtt.c10
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c10
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c15
-rw-r--r--arch/arm/mach-omap1/board-sx1.c16
-rw-r--r--arch/arm/mach-omap2/io.c1
-rw-r--r--arch/arm/plat-omap/common.c2
-rw-r--r--arch/arm/plat-omap/fb.c336
-rw-r--r--arch/arm/plat-omap/fb.h10
-rw-r--r--arch/arm/plat-omap/include/plat/blizzard.h12
-rw-r--r--arch/arm/plat-omap/include/plat/board.h2
-rw-r--r--arch/arm/plat-omap/include/plat/hwa742.h8
-rw-r--r--arch/arm/plat-omap/include/plat/vram.h21
-rw-r--r--drivers/video/omap/Kconfig16
-rw-r--r--drivers/video/omap/Makefile12
-rw-r--r--drivers/video/omap/blizzard.c1648
-rw-r--r--drivers/video/omap/dispc.c1547
-rw-r--r--drivers/video/omap/dispc.h46
-rw-r--r--drivers/video/omap/hwa742.c21
-rw-r--r--drivers/video/omap/omapfb.h25
-rw-r--r--drivers/video/omap/omapfb_main.c30
-rw-r--r--drivers/video/omap/rfbi.c598
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c23
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c153
-rw-r--r--drivers/video/omap2/dss/apply.c215
-rw-r--r--drivers/video/omap2/dss/dispc.c113
-rw-r--r--drivers/video/omap2/dss/display.c10
-rw-r--r--drivers/video/omap2/dss/dsi.c65
-rw-r--r--drivers/video/omap2/dss/dss.c17
-rw-r--r--drivers/video/omap2/dss/dss.h10
-rw-r--r--drivers/video/omap2/dss/dss_features.c178
-rw-r--r--drivers/video/omap2/dss/dss_features.h54
-rw-r--r--drivers/video/omap2/dss/hdmi.c262
-rw-r--r--drivers/video/omap2/dss/rfbi.c36
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h56
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c94
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h47
-rw-r--r--drivers/video/omap2/dss/venc.c32
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c2
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c101
-rw-r--r--drivers/video/omap2/vram.c99
-rw-r--r--include/linux/omapfb.h32
50 files changed, 936 insertions, 5160 deletions
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 88909cc0b254..e0e8245f3c9f 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -20,6 +20,7 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/serial_8250.h> 21#include <linux/serial_8250.h>
22#include <linux/export.h> 22#include <linux/export.h>
23#include <linux/omapfb.h>
23 24
24#include <media/soc_camera.h> 25#include <media/soc_camera.h>
25 26
@@ -169,10 +170,6 @@ static struct omap_usb_config ams_delta_usb_config __initdata = {
169 .pins[0] = 2, 170 .pins[0] = 2,
170}; 171};
171 172
172static struct omap_board_config_kernel ams_delta_config[] __initdata = {
173 { OMAP_TAG_LCD, &ams_delta_lcd_config },
174};
175
176static struct resource ams_delta_nand_resources[] = { 173static struct resource ams_delta_nand_resources[] = {
177 [0] = { 174 [0] = {
178 .start = OMAP1_MPUIO_BASE, 175 .start = OMAP1_MPUIO_BASE,
@@ -302,8 +299,6 @@ static void __init ams_delta_init(void)
302 omap_cfg_reg(J19_1610_CAM_D6); 299 omap_cfg_reg(J19_1610_CAM_D6);
303 omap_cfg_reg(J18_1610_CAM_D7); 300 omap_cfg_reg(J18_1610_CAM_D7);
304 301
305 omap_board_config = ams_delta_config;
306 omap_board_config_size = ARRAY_SIZE(ams_delta_config);
307 omap_serial_init(); 302 omap_serial_init();
308 omap_register_i2c_bus(1, 100, NULL, 0); 303 omap_register_i2c_bus(1, 100, NULL, 0);
309 304
@@ -321,6 +316,8 @@ static void __init ams_delta_init(void)
321 ams_delta_init_fiq(); 316 ams_delta_init_fiq();
322 317
323 omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1); 318 omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
319
320 omapfb_set_lcd_config(&ams_delta_lcd_config);
324} 321}
325 322
326static struct plat_serial8250_port ams_delta_modem_ports[] = { 323static struct plat_serial8250_port ams_delta_modem_ports[] = {
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 0b9464b41212..7afaf3c5bdc6 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -21,6 +21,7 @@
21#include <linux/mtd/physmap.h> 21#include <linux/mtd/physmap.h>
22#include <linux/input.h> 22#include <linux/input.h>
23#include <linux/smc91x.h> 23#include <linux/smc91x.h>
24#include <linux/omapfb.h>
24 25
25#include <mach/hardware.h> 26#include <mach/hardware.h>
26#include <asm/mach-types.h> 27#include <asm/mach-types.h>
@@ -273,27 +274,17 @@ static struct platform_device kp_device = {
273 .resource = kp_resources, 274 .resource = kp_resources,
274}; 275};
275 276
276static struct platform_device lcd_device = {
277 .name = "lcd_p2",
278 .id = -1,
279};
280
281static struct platform_device *devices[] __initdata = { 277static struct platform_device *devices[] __initdata = {
282 &nor_device, 278 &nor_device,
283 &nand_device, 279 &nand_device,
284 &smc91x_device, 280 &smc91x_device,
285 &kp_device, 281 &kp_device,
286 &lcd_device,
287}; 282};
288 283
289static struct omap_lcd_config fsample_lcd_config = { 284static struct omap_lcd_config fsample_lcd_config = {
290 .ctrl_name = "internal", 285 .ctrl_name = "internal",
291}; 286};
292 287
293static struct omap_board_config_kernel fsample_config[] __initdata = {
294 { OMAP_TAG_LCD, &fsample_lcd_config },
295};
296
297static void __init omap_fsample_init(void) 288static void __init omap_fsample_init(void)
298{ 289{
299 /* Early, board-dependent init */ 290 /* Early, board-dependent init */
@@ -352,10 +343,10 @@ static void __init omap_fsample_init(void)
352 343
353 platform_add_devices(devices, ARRAY_SIZE(devices)); 344 platform_add_devices(devices, ARRAY_SIZE(devices));
354 345
355 omap_board_config = fsample_config;
356 omap_board_config_size = ARRAY_SIZE(fsample_config);
357 omap_serial_init(); 346 omap_serial_init();
358 omap_register_i2c_bus(1, 100, NULL, 0); 347 omap_register_i2c_bus(1, 100, NULL, 0);
348
349 omapfb_set_lcd_config(&fsample_lcd_config);
359} 350}
360 351
361/* Only FPGA needs to be mapped here. All others are done with ioremap */ 352/* Only FPGA needs to be mapped here. All others are done with ioremap */
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 00ad6b22d60a..af2be8c12c07 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -30,6 +30,7 @@
30#include <linux/input.h> 30#include <linux/input.h>
31#include <linux/i2c/tps65010.h> 31#include <linux/i2c/tps65010.h>
32#include <linux/smc91x.h> 32#include <linux/smc91x.h>
33#include <linux/omapfb.h>
33 34
34#include <mach/hardware.h> 35#include <mach/hardware.h>
35 36
@@ -325,18 +326,12 @@ static struct platform_device h2_irda_device = {
325 .resource = h2_irda_resources, 326 .resource = h2_irda_resources,
326}; 327};
327 328
328static struct platform_device h2_lcd_device = {
329 .name = "lcd_h2",
330 .id = -1,
331};
332
333static struct platform_device *h2_devices[] __initdata = { 329static struct platform_device *h2_devices[] __initdata = {
334 &h2_nor_device, 330 &h2_nor_device,
335 &h2_nand_device, 331 &h2_nand_device,
336 &h2_smc91x_device, 332 &h2_smc91x_device,
337 &h2_irda_device, 333 &h2_irda_device,
338 &h2_kp_device, 334 &h2_kp_device,
339 &h2_lcd_device,
340}; 335};
341 336
342static void __init h2_init_smc91x(void) 337static void __init h2_init_smc91x(void)
@@ -391,10 +386,6 @@ static struct omap_lcd_config h2_lcd_config __initdata = {
391 .ctrl_name = "internal", 386 .ctrl_name = "internal",
392}; 387};
393 388
394static struct omap_board_config_kernel h2_config[] __initdata = {
395 { OMAP_TAG_LCD, &h2_lcd_config },
396};
397
398static void __init h2_init(void) 389static void __init h2_init(void)
399{ 390{
400 h2_init_smc91x(); 391 h2_init_smc91x();
@@ -438,13 +429,13 @@ static void __init h2_init(void)
438 omap_cfg_reg(N19_1610_KBR5); 429 omap_cfg_reg(N19_1610_KBR5);
439 430
440 platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices)); 431 platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
441 omap_board_config = h2_config;
442 omap_board_config_size = ARRAY_SIZE(h2_config);
443 omap_serial_init(); 432 omap_serial_init();
444 omap_register_i2c_bus(1, 100, h2_i2c_board_info, 433 omap_register_i2c_bus(1, 100, h2_i2c_board_info,
445 ARRAY_SIZE(h2_i2c_board_info)); 434 ARRAY_SIZE(h2_i2c_board_info));
446 omap1_usb_init(&h2_usb_config); 435 omap1_usb_init(&h2_usb_config);
447 h2_mmc_init(); 436 h2_mmc_init();
437
438 omapfb_set_lcd_config(&h2_lcd_config);
448} 439}
449 440
450MACHINE_START(OMAP_H2, "TI-H2") 441MACHINE_START(OMAP_H2, "TI-H2")
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 4a7f25149703..7cfd25b90735 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -30,6 +30,7 @@
30#include <linux/spi/spi.h> 30#include <linux/spi/spi.h>
31#include <linux/i2c/tps65010.h> 31#include <linux/i2c/tps65010.h>
32#include <linux/smc91x.h> 32#include <linux/smc91x.h>
33#include <linux/omapfb.h>
33 34
34#include <asm/setup.h> 35#include <asm/setup.h>
35#include <asm/page.h> 36#include <asm/page.h>
@@ -370,10 +371,6 @@ static struct omap_lcd_config h3_lcd_config __initdata = {
370 .ctrl_name = "internal", 371 .ctrl_name = "internal",
371}; 372};
372 373
373static struct omap_board_config_kernel h3_config[] __initdata = {
374 { OMAP_TAG_LCD, &h3_lcd_config },
375};
376
377static struct i2c_board_info __initdata h3_i2c_board_info[] = { 374static struct i2c_board_info __initdata h3_i2c_board_info[] = {
378 { 375 {
379 I2C_BOARD_INFO("tps65013", 0x48), 376 I2C_BOARD_INFO("tps65013", 0x48),
@@ -426,13 +423,13 @@ static void __init h3_init(void)
426 platform_add_devices(devices, ARRAY_SIZE(devices)); 423 platform_add_devices(devices, ARRAY_SIZE(devices));
427 spi_register_board_info(h3_spi_board_info, 424 spi_register_board_info(h3_spi_board_info,
428 ARRAY_SIZE(h3_spi_board_info)); 425 ARRAY_SIZE(h3_spi_board_info));
429 omap_board_config = h3_config;
430 omap_board_config_size = ARRAY_SIZE(h3_config);
431 omap_serial_init(); 426 omap_serial_init();
432 omap_register_i2c_bus(1, 100, h3_i2c_board_info, 427 omap_register_i2c_bus(1, 100, h3_i2c_board_info,
433 ARRAY_SIZE(h3_i2c_board_info)); 428 ARRAY_SIZE(h3_i2c_board_info));
434 omap1_usb_init(&h3_usb_config); 429 omap1_usb_init(&h3_usb_config);
435 h3_mmc_init(); 430 h3_mmc_init();
431
432 omapfb_set_lcd_config(&h3_lcd_config);
436} 433}
437 434
438MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") 435MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index 731cc3db7ab3..af2afcf24f75 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -36,6 +36,7 @@
36#include <linux/leds.h> 36#include <linux/leds.h>
37#include <linux/spi/spi.h> 37#include <linux/spi/spi.h>
38#include <linux/spi/ads7846.h> 38#include <linux/spi/ads7846.h>
39#include <linux/omapfb.h>
39 40
40#include <asm/mach-types.h> 41#include <asm/mach-types.h>
41#include <asm/mach/arch.h> 42#include <asm/mach/arch.h>
@@ -398,10 +399,6 @@ static struct omap_lcd_config htcherald_lcd_config __initdata = {
398 .ctrl_name = "internal", 399 .ctrl_name = "internal",
399}; 400};
400 401
401static struct omap_board_config_kernel htcherald_config[] __initdata = {
402 { OMAP_TAG_LCD, &htcherald_lcd_config },
403};
404
405static struct platform_device lcd_device = { 402static struct platform_device lcd_device = {
406 .name = "lcd_htcherald", 403 .name = "lcd_htcherald",
407 .id = -1, 404 .id = -1,
@@ -580,8 +577,6 @@ static void __init htcherald_init(void)
580 printk(KERN_INFO "HTC Herald init.\n"); 577 printk(KERN_INFO "HTC Herald init.\n");
581 578
582 /* Do board initialization before we register all the devices */ 579 /* Do board initialization before we register all the devices */
583 omap_board_config = htcherald_config;
584 omap_board_config_size = ARRAY_SIZE(htcherald_config);
585 platform_add_devices(devices, ARRAY_SIZE(devices)); 580 platform_add_devices(devices, ARRAY_SIZE(devices));
586 581
587 htcherald_disable_watchdog(); 582 htcherald_disable_watchdog();
@@ -598,6 +593,8 @@ static void __init htcherald_init(void)
598 htc_mmc_data[0] = &htc_mmc1_data; 593 htc_mmc_data[0] = &htc_mmc1_data;
599 omap1_init_mmc(htc_mmc_data, 1); 594 omap1_init_mmc(htc_mmc_data, 1);
600#endif 595#endif
596
597 omapfb_set_lcd_config(&htcherald_lcd_config);
601} 598}
602 599
603MACHINE_START(HERALD, "HTC Herald") 600MACHINE_START(HERALD, "HTC Herald")
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index be2002f42dea..1d5ab6606b9f 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -25,6 +25,7 @@
25#include <linux/mtd/physmap.h> 25#include <linux/mtd/physmap.h>
26#include <linux/input.h> 26#include <linux/input.h>
27#include <linux/smc91x.h> 27#include <linux/smc91x.h>
28#include <linux/omapfb.h>
28 29
29#include <mach/hardware.h> 30#include <mach/hardware.h>
30#include <asm/mach-types.h> 31#include <asm/mach-types.h>
@@ -370,10 +371,6 @@ static inline void innovator_mmc_init(void)
370} 371}
371#endif 372#endif
372 373
373static struct omap_board_config_kernel innovator_config[] = {
374 { OMAP_TAG_LCD, NULL },
375};
376
377static void __init innovator_init(void) 374static void __init innovator_init(void)
378{ 375{
379 if (cpu_is_omap1510()) 376 if (cpu_is_omap1510())
@@ -416,17 +413,15 @@ static void __init innovator_init(void)
416#ifdef CONFIG_ARCH_OMAP15XX 413#ifdef CONFIG_ARCH_OMAP15XX
417 if (cpu_is_omap1510()) { 414 if (cpu_is_omap1510()) {
418 omap1_usb_init(&innovator1510_usb_config); 415 omap1_usb_init(&innovator1510_usb_config);
419 innovator_config[0].data = &innovator1510_lcd_config; 416 omapfb_set_lcd_config(&innovator1510_lcd_config);
420 } 417 }
421#endif 418#endif
422#ifdef CONFIG_ARCH_OMAP16XX 419#ifdef CONFIG_ARCH_OMAP16XX
423 if (cpu_is_omap1610()) { 420 if (cpu_is_omap1610()) {
424 omap1_usb_init(&h2_usb_config); 421 omap1_usb_init(&h2_usb_config);
425 innovator_config[0].data = &innovator1610_lcd_config; 422 omapfb_set_lcd_config(&innovator1610_lcd_config);
426 } 423 }
427#endif 424#endif
428 omap_board_config = innovator_config;
429 omap_board_config_size = ARRAY_SIZE(innovator_config);
430 omap_serial_init(); 425 omap_serial_init();
431 omap_register_i2c_bus(1, 100, NULL, 0); 426 omap_register_i2c_bus(1, 100, NULL, 0);
432 innovator_mmc_init(); 427 innovator_mmc_init();
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index f9efc036ba96..9b6332a31fb6 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -31,7 +31,6 @@
31#include <plat/board.h> 31#include <plat/board.h>
32#include <plat/keypad.h> 32#include <plat/keypad.h>
33#include "common.h" 33#include "common.h"
34#include <plat/hwa742.h>
35#include <plat/lcd_mipid.h> 34#include <plat/lcd_mipid.h>
36#include <plat/mmc.h> 35#include <plat/mmc.h>
37#include <plat/clock.h> 36#include <plat/clock.h>
@@ -99,15 +98,16 @@ static struct mipid_platform_data nokia770_mipid_platform_data = {
99 .shutdown = mipid_shutdown, 98 .shutdown = mipid_shutdown,
100}; 99};
101 100
101static struct omap_lcd_config nokia770_lcd_config __initdata = {
102 .ctrl_name = "hwa742",
103};
104
102static void __init mipid_dev_init(void) 105static void __init mipid_dev_init(void)
103{ 106{
104 const struct omap_lcd_config *conf; 107 nokia770_mipid_platform_data.nreset_gpio = 13;
108 nokia770_mipid_platform_data.data_lines = 16;
105 109
106 conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config); 110 omapfb_set_lcd_config(&nokia770_lcd_config);
107 if (conf != NULL) {
108 nokia770_mipid_platform_data.nreset_gpio = conf->nreset_gpio;
109 nokia770_mipid_platform_data.data_lines = conf->data_lines;
110 }
111} 111}
112 112
113static void __init ads7846_dev_init(void) 113static void __init ads7846_dev_init(void)
@@ -150,14 +150,9 @@ static struct spi_board_info nokia770_spi_board_info[] __initdata = {
150 }, 150 },
151}; 151};
152 152
153static struct hwa742_platform_data nokia770_hwa742_platform_data = {
154 .te_connected = 1,
155};
156
157static void __init hwa742_dev_init(void) 153static void __init hwa742_dev_init(void)
158{ 154{
159 clk_add_alias("hwa_sys_ck", NULL, "bclk", NULL); 155 clk_add_alias("hwa_sys_ck", NULL, "bclk", NULL);
160 omapfb_set_ctrl_platform_data(&nokia770_hwa742_platform_data);
161} 156}
162 157
163/* assume no Mini-AB port */ 158/* assume no Mini-AB port */
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 675de06557aa..ef874655fbd3 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -34,6 +34,7 @@
34#include <linux/i2c.h> 34#include <linux/i2c.h>
35#include <linux/leds.h> 35#include <linux/leds.h>
36#include <linux/smc91x.h> 36#include <linux/smc91x.h>
37#include <linux/omapfb.h>
37 38
38#include <linux/mtd/mtd.h> 39#include <linux/mtd/mtd.h>
39#include <linux/mtd/partitions.h> 40#include <linux/mtd/partitions.h>
@@ -300,12 +301,6 @@ static struct omap_lcd_config osk_lcd_config __initdata = {
300}; 301};
301#endif 302#endif
302 303
303static struct omap_board_config_kernel osk_config[] __initdata = {
304#ifdef CONFIG_OMAP_OSK_MISTRAL
305 { OMAP_TAG_LCD, &osk_lcd_config },
306#endif
307};
308
309#ifdef CONFIG_OMAP_OSK_MISTRAL 304#ifdef CONFIG_OMAP_OSK_MISTRAL
310 305
311#include <linux/input.h> 306#include <linux/input.h>
@@ -549,8 +544,6 @@ static void __init osk_init(void)
549 osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys(); 544 osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys();
550 osk_flash_resource.end += SZ_32M - 1; 545 osk_flash_resource.end += SZ_32M - 1;
551 platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices)); 546 platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
552 omap_board_config = osk_config;
553 omap_board_config_size = ARRAY_SIZE(osk_config);
554 547
555 l = omap_readl(USB_TRANSCEIVER_CTRL); 548 l = omap_readl(USB_TRANSCEIVER_CTRL);
556 l |= (3 << 1); 549 l |= (3 << 1);
@@ -567,6 +560,11 @@ static void __init osk_init(void)
567 omap_register_i2c_bus(1, 400, osk_i2c_board_info, 560 omap_register_i2c_bus(1, 400, osk_i2c_board_info,
568 ARRAY_SIZE(osk_i2c_board_info)); 561 ARRAY_SIZE(osk_i2c_board_info));
569 osk_mistral_init(); 562 osk_mistral_init();
563
564#ifdef CONFIG_OMAP_OSK_MISTRAL
565 omapfb_set_lcd_config(&osk_lcd_config);
566#endif
567
570} 568}
571 569
572MACHINE_START(OMAP_OSK, "TI-OSK") 570MACHINE_START(OMAP_OSK, "TI-OSK")
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 81fa27f88369..612342cb2a2d 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -27,6 +27,7 @@
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/apm-emulation.h> 29#include <linux/apm-emulation.h>
30#include <linux/omapfb.h>
30 31
31#include <mach/hardware.h> 32#include <mach/hardware.h>
32#include <asm/mach-types.h> 33#include <asm/mach-types.h>
@@ -209,10 +210,6 @@ static struct omap_lcd_config palmte_lcd_config __initdata = {
209 .ctrl_name = "internal", 210 .ctrl_name = "internal",
210}; 211};
211 212
212static struct omap_board_config_kernel palmte_config[] __initdata = {
213 { OMAP_TAG_LCD, &palmte_lcd_config },
214};
215
216static struct spi_board_info palmte_spi_info[] __initdata = { 213static struct spi_board_info palmte_spi_info[] __initdata = {
217 { 214 {
218 .modalias = "tsc2102", 215 .modalias = "tsc2102",
@@ -250,9 +247,6 @@ static void __init omap_palmte_init(void)
250 omap_cfg_reg(UART3_TX); 247 omap_cfg_reg(UART3_TX);
251 omap_cfg_reg(UART3_RX); 248 omap_cfg_reg(UART3_RX);
252 249
253 omap_board_config = palmte_config;
254 omap_board_config_size = ARRAY_SIZE(palmte_config);
255
256 platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices)); 250 platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices));
257 251
258 spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info)); 252 spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
@@ -260,6 +254,8 @@ static void __init omap_palmte_init(void)
260 omap_serial_init(); 254 omap_serial_init();
261 omap1_usb_init(&palmte_usb_config); 255 omap1_usb_init(&palmte_usb_config);
262 omap_register_i2c_bus(1, 100, NULL, 0); 256 omap_register_i2c_bus(1, 100, NULL, 0);
257
258 omapfb_set_lcd_config(&palmte_lcd_config);
263} 259}
264 260
265MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") 261MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index 81cb82178388..b63350bc88fd 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -24,6 +24,7 @@
24#include <linux/mtd/partitions.h> 24#include <linux/mtd/partitions.h>
25#include <linux/mtd/physmap.h> 25#include <linux/mtd/physmap.h>
26#include <linux/leds.h> 26#include <linux/leds.h>
27#include <linux/omapfb.h>
27 28
28#include <mach/hardware.h> 29#include <mach/hardware.h>
29#include <asm/mach-types.h> 30#include <asm/mach-types.h>
@@ -273,10 +274,6 @@ static struct omap_lcd_config palmtt_lcd_config __initdata = {
273 .ctrl_name = "internal", 274 .ctrl_name = "internal",
274}; 275};
275 276
276static struct omap_board_config_kernel palmtt_config[] __initdata = {
277 { OMAP_TAG_LCD, &palmtt_lcd_config },
278};
279
280static void __init omap_mpu_wdt_mode(int mode) { 277static void __init omap_mpu_wdt_mode(int mode) {
281 if (mode) 278 if (mode)
282 omap_writew(0x8000, OMAP_WDT_TIMER_MODE); 279 omap_writew(0x8000, OMAP_WDT_TIMER_MODE);
@@ -298,15 +295,14 @@ static void __init omap_palmtt_init(void)
298 295
299 omap_mpu_wdt_mode(0); 296 omap_mpu_wdt_mode(0);
300 297
301 omap_board_config = palmtt_config;
302 omap_board_config_size = ARRAY_SIZE(palmtt_config);
303
304 platform_add_devices(palmtt_devices, ARRAY_SIZE(palmtt_devices)); 298 platform_add_devices(palmtt_devices, ARRAY_SIZE(palmtt_devices));
305 299
306 spi_register_board_info(palmtt_boardinfo,ARRAY_SIZE(palmtt_boardinfo)); 300 spi_register_board_info(palmtt_boardinfo,ARRAY_SIZE(palmtt_boardinfo));
307 omap_serial_init(); 301 omap_serial_init();
308 omap1_usb_init(&palmtt_usb_config); 302 omap1_usb_init(&palmtt_usb_config);
309 omap_register_i2c_bus(1, 100, NULL, 0); 303 omap_register_i2c_bus(1, 100, NULL, 0);
304
305 omapfb_set_lcd_config(&palmtt_lcd_config);
310} 306}
311 307
312MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T") 308MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T")
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index e881945ce8ec..9924c70af09f 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -27,6 +27,7 @@
27#include <linux/mtd/mtd.h> 27#include <linux/mtd/mtd.h>
28#include <linux/mtd/partitions.h> 28#include <linux/mtd/partitions.h>
29#include <linux/mtd/physmap.h> 29#include <linux/mtd/physmap.h>
30#include <linux/omapfb.h>
30 31
31#include <mach/hardware.h> 32#include <mach/hardware.h>
32#include <asm/mach-types.h> 33#include <asm/mach-types.h>
@@ -239,10 +240,6 @@ static struct omap_lcd_config palmz71_lcd_config __initdata = {
239 .ctrl_name = "internal", 240 .ctrl_name = "internal",
240}; 241};
241 242
242static struct omap_board_config_kernel palmz71_config[] __initdata = {
243 {OMAP_TAG_LCD, &palmz71_lcd_config},
244};
245
246static irqreturn_t 243static irqreturn_t
247palmz71_powercable(int irq, void *dev_id) 244palmz71_powercable(int irq, void *dev_id)
248{ 245{
@@ -313,9 +310,6 @@ omap_palmz71_init(void)
313 palmz71_gpio_setup(1); 310 palmz71_gpio_setup(1);
314 omap_mpu_wdt_mode(0); 311 omap_mpu_wdt_mode(0);
315 312
316 omap_board_config = palmz71_config;
317 omap_board_config_size = ARRAY_SIZE(palmz71_config);
318
319 platform_add_devices(devices, ARRAY_SIZE(devices)); 313 platform_add_devices(devices, ARRAY_SIZE(devices));
320 314
321 spi_register_board_info(palmz71_boardinfo, 315 spi_register_board_info(palmz71_boardinfo,
@@ -324,6 +318,8 @@ omap_palmz71_init(void)
324 omap_serial_init(); 318 omap_serial_init();
325 omap_register_i2c_bus(1, 100, NULL, 0); 319 omap_register_i2c_bus(1, 100, NULL, 0);
326 palmz71_gpio_setup(0); 320 palmz71_gpio_setup(0);
321
322 omapfb_set_lcd_config(&palmz71_lcd_config);
327} 323}
328 324
329MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71") 325MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71")
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index c000bed76276..8e0153447c6d 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -21,6 +21,7 @@
21#include <linux/mtd/physmap.h> 21#include <linux/mtd/physmap.h>
22#include <linux/input.h> 22#include <linux/input.h>
23#include <linux/smc91x.h> 23#include <linux/smc91x.h>
24#include <linux/omapfb.h>
24 25
25#include <mach/hardware.h> 26#include <mach/hardware.h>
26#include <asm/mach-types.h> 27#include <asm/mach-types.h>
@@ -232,27 +233,17 @@ static struct platform_device kp_device = {
232 .resource = kp_resources, 233 .resource = kp_resources,
233}; 234};
234 235
235static struct platform_device lcd_device = {
236 .name = "lcd_p2",
237 .id = -1,
238};
239
240static struct platform_device *devices[] __initdata = { 236static struct platform_device *devices[] __initdata = {
241 &nor_device, 237 &nor_device,
242 &nand_device, 238 &nand_device,
243 &smc91x_device, 239 &smc91x_device,
244 &kp_device, 240 &kp_device,
245 &lcd_device,
246}; 241};
247 242
248static struct omap_lcd_config perseus2_lcd_config __initdata = { 243static struct omap_lcd_config perseus2_lcd_config __initdata = {
249 .ctrl_name = "internal", 244 .ctrl_name = "internal",
250}; 245};
251 246
252static struct omap_board_config_kernel perseus2_config[] __initdata = {
253 { OMAP_TAG_LCD, &perseus2_lcd_config },
254};
255
256static void __init perseus2_init_smc91x(void) 247static void __init perseus2_init_smc91x(void)
257{ 248{
258 fpga_write(1, H2P2_DBG_FPGA_LAN_RESET); 249 fpga_write(1, H2P2_DBG_FPGA_LAN_RESET);
@@ -320,10 +311,10 @@ static void __init omap_perseus2_init(void)
320 311
321 platform_add_devices(devices, ARRAY_SIZE(devices)); 312 platform_add_devices(devices, ARRAY_SIZE(devices));
322 313
323 omap_board_config = perseus2_config;
324 omap_board_config_size = ARRAY_SIZE(perseus2_config);
325 omap_serial_init(); 314 omap_serial_init();
326 omap_register_i2c_bus(1, 100, NULL, 0); 315 omap_register_i2c_bus(1, 100, NULL, 0);
316
317 omapfb_set_lcd_config(&perseus2_lcd_config);
327} 318}
328 319
329/* Only FPGA needs to be mapped here. All others are done with ioremap */ 320/* Only FPGA needs to be mapped here. All others are done with ioremap */
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 7bcd82ab0fd0..0c76e12337d9 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -27,6 +27,7 @@
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/errno.h> 28#include <linux/errno.h>
29#include <linux/export.h> 29#include <linux/export.h>
30#include <linux/omapfb.h>
30 31
31#include <mach/hardware.h> 32#include <mach/hardware.h>
32#include <asm/mach-types.h> 33#include <asm/mach-types.h>
@@ -355,11 +356,6 @@ static struct omap_usb_config sx1_usb_config __initdata = {
355 356
356/*----------- LCD -------------------------*/ 357/*----------- LCD -------------------------*/
357 358
358static struct platform_device sx1_lcd_device = {
359 .name = "lcd_sx1",
360 .id = -1,
361};
362
363static struct omap_lcd_config sx1_lcd_config __initdata = { 359static struct omap_lcd_config sx1_lcd_config __initdata = {
364 .ctrl_name = "internal", 360 .ctrl_name = "internal",
365}; 361};
@@ -368,14 +364,8 @@ static struct omap_lcd_config sx1_lcd_config __initdata = {
368static struct platform_device *sx1_devices[] __initdata = { 364static struct platform_device *sx1_devices[] __initdata = {
369 &sx1_flash_device, 365 &sx1_flash_device,
370 &sx1_kp_device, 366 &sx1_kp_device,
371 &sx1_lcd_device,
372 &sx1_irda_device, 367 &sx1_irda_device,
373}; 368};
374/*-----------------------------------------*/
375
376static struct omap_board_config_kernel sx1_config[] __initdata = {
377 { OMAP_TAG_LCD, &sx1_lcd_config },
378};
379 369
380/*-----------------------------------------*/ 370/*-----------------------------------------*/
381 371
@@ -391,8 +381,6 @@ static void __init omap_sx1_init(void)
391 381
392 platform_add_devices(sx1_devices, ARRAY_SIZE(sx1_devices)); 382 platform_add_devices(sx1_devices, ARRAY_SIZE(sx1_devices));
393 383
394 omap_board_config = sx1_config;
395 omap_board_config_size = ARRAY_SIZE(sx1_config);
396 omap_serial_init(); 384 omap_serial_init();
397 omap_register_i2c_bus(1, 100, NULL, 0); 385 omap_register_i2c_bus(1, 100, NULL, 0);
398 omap1_usb_init(&sx1_usb_config); 386 omap1_usb_init(&sx1_usb_config);
@@ -406,6 +394,8 @@ static void __init omap_sx1_init(void)
406 gpio_direction_output(1, 1); /*A_IRDA_OFF = 1 */ 394 gpio_direction_output(1, 1); /*A_IRDA_OFF = 1 */
407 gpio_direction_output(11, 0); /*A_SWITCH = 0 */ 395 gpio_direction_output(11, 0); /*A_SWITCH = 0 */
408 gpio_direction_output(15, 0); /*A_USB_ON = 0 */ 396 gpio_direction_output(15, 0); /*A_USB_ON = 0 */
397
398 omapfb_set_lcd_config(&sx1_lcd_config);
409} 399}
410 400
411MACHINE_START(SX1, "OMAP310 based Siemens SX1") 401MACHINE_START(SX1, "OMAP310 based Siemens SX1")
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index fb11b44fbdec..e501b4972a64 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -21,7 +21,6 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/omapfb.h>
25 24
26#include <asm/tlb.h> 25#include <asm/tlb.h>
27 26
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 4de7d1e79e73..f1e46ea6b81d 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -15,7 +15,6 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/dma-mapping.h> 17#include <linux/dma-mapping.h>
18#include <linux/omapfb.h>
19 18
20#include <plat/common.h> 19#include <plat/common.h>
21#include <plat/board.h> 20#include <plat/board.h>
@@ -65,7 +64,6 @@ const void *__init omap_get_var_config(u16 tag, size_t *len)
65 64
66void __init omap_reserve(void) 65void __init omap_reserve(void)
67{ 66{
68 omapfb_reserve_sdram_memblock();
69 omap_vram_reserve_sdram_memblock(); 67 omap_vram_reserve_sdram_memblock();
70 omap_dsp_reserve_sdram_memblock(); 68 omap_dsp_reserve_sdram_memblock();
71 omap_secure_ram_reserve_memblock(); 69 omap_secure_ram_reserve_memblock();
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index c9e5d7298c40..24e62693b809 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -34,15 +34,11 @@
34#include <asm/mach/map.h> 34#include <asm/mach/map.h>
35 35
36#include <plat/board.h> 36#include <plat/board.h>
37#include <plat/sram.h>
38
39#include "fb.h"
40 37
41#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE) 38#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
42 39
40static bool omapfb_lcd_configured;
43static struct omapfb_platform_data omapfb_config; 41static struct omapfb_platform_data omapfb_config;
44static int config_invalid;
45static int configured_regions;
46 42
47static u64 omap_fb_dma_mask = ~(u32)0; 43static u64 omap_fb_dma_mask = ~(u32)0;
48 44
@@ -57,301 +53,20 @@ static struct platform_device omap_fb_device = {
57 .num_resources = 0, 53 .num_resources = 0,
58}; 54};
59 55
60void omapfb_set_platform_data(struct omapfb_platform_data *data) 56void __init omapfb_set_lcd_config(const struct omap_lcd_config *config)
61{
62}
63
64static inline int ranges_overlap(unsigned long start1, unsigned long size1,
65 unsigned long start2, unsigned long size2)
66{
67 return (start1 >= start2 && start1 < start2 + size2) ||
68 (start2 >= start1 && start2 < start1 + size1);
69}
70
71static inline int range_included(unsigned long start1, unsigned long size1,
72 unsigned long start2, unsigned long size2)
73{
74 return start1 >= start2 && start1 + size1 <= start2 + size2;
75}
76
77
78/* Check if there is an overlapping region. */
79static int fbmem_region_reserved(unsigned long start, size_t size)
80{
81 struct omapfb_mem_region *rg;
82 int i;
83
84 rg = &omapfb_config.mem_desc.region[0];
85 for (i = 0; i < OMAPFB_PLANE_NUM; i++, rg++) {
86 if (!rg->paddr)
87 /* Empty slot. */
88 continue;
89 if (ranges_overlap(start, size, rg->paddr, rg->size))
90 return 1;
91 }
92 return 0;
93}
94
95/*
96 * Get the region_idx`th region from board config/ATAG and convert it to
97 * our internal format.
98 */
99static int __init get_fbmem_region(int region_idx, struct omapfb_mem_region *rg)
100{
101 const struct omap_fbmem_config *conf;
102 u32 paddr;
103
104 conf = omap_get_nr_config(OMAP_TAG_FBMEM,
105 struct omap_fbmem_config, region_idx);
106 if (conf == NULL)
107 return -ENOENT;
108
109 paddr = conf->start;
110 /*
111 * Low bits encode the page allocation mode, if high bits
112 * are zero. Otherwise we need a page aligned fixed
113 * address.
114 */
115 memset(rg, 0, sizeof(*rg));
116 rg->type = paddr & ~PAGE_MASK;
117 rg->paddr = paddr & PAGE_MASK;
118 rg->size = PAGE_ALIGN(conf->size);
119 return 0;
120}
121
122static int set_fbmem_region_type(struct omapfb_mem_region *rg, int mem_type,
123 unsigned long mem_start,
124 unsigned long mem_size)
125{ 57{
126 /* 58 omapfb_config.lcd = *config;
127 * Check if the configuration specifies the type explicitly. 59 omapfb_lcd_configured = true;
128 * type = 0 && paddr = 0, a default don't care case maps to
129 * the SDRAM type.
130 */
131 if (rg->type || !rg->paddr)
132 return 0;
133 if (ranges_overlap(rg->paddr, rg->size, mem_start, mem_size)) {
134 rg->type = mem_type;
135 return 0;
136 }
137 /* Can't determine it. */
138 return -1;
139} 60}
140 61
141static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg, 62static int __init omap_init_fb(void)
142 unsigned long start_avail, unsigned size_avail)
143{ 63{
144 unsigned long paddr = rg->paddr;
145 size_t size = rg->size;
146
147 if (rg->type > OMAPFB_MEMTYPE_MAX) {
148 printk(KERN_ERR
149 "Invalid start address for FB region %d\n", region_idx);
150 return -EINVAL;
151 }
152
153 if (!rg->size) {
154 printk(KERN_ERR "Zero size for FB region %d\n", region_idx);
155 return -EINVAL;
156 }
157
158 if (!paddr)
159 /* Allocate this dynamically, leave paddr 0 for now. */
160 return 0;
161
162 /* 64 /*
163 * Fixed region for the given RAM range. Check if it's already 65 * If the board file has not set the lcd config with
164 * reserved by the FB code or someone else. 66 * omapfb_set_lcd_config(), don't bother registering the omapfb device
165 */ 67 */
166 if (fbmem_region_reserved(paddr, size) || 68 if (!omapfb_lcd_configured)
167 !range_included(paddr, size, start_avail, size_avail)) {
168 printk(KERN_ERR "Trying to use reserved memory "
169 "for FB region %d\n", region_idx);
170 return -EINVAL;
171 }
172
173 return 0;
174}
175
176static int valid_sdram(unsigned long addr, unsigned long size)
177{
178 return memblock_is_region_memory(addr, size);
179}
180
181static int reserve_sdram(unsigned long addr, unsigned long size)
182{
183 if (memblock_is_region_reserved(addr, size))
184 return -EBUSY;
185 if (memblock_reserve(addr, size))
186 return -ENOMEM;
187 return 0;
188}
189
190/*
191 * Called from map_io. We need to call to this early enough so that we
192 * can reserve the fixed SDRAM regions before VM could get hold of them.
193 */
194void __init omapfb_reserve_sdram_memblock(void)
195{
196 unsigned long reserved = 0;
197 int i;
198
199 if (config_invalid)
200 return;
201
202 for (i = 0; ; i++) {
203 struct omapfb_mem_region rg;
204
205 if (get_fbmem_region(i, &rg) < 0)
206 break;
207
208 if (i == OMAPFB_PLANE_NUM) {
209 pr_err("Extraneous FB mem configuration entries\n");
210 config_invalid = 1;
211 return;
212 }
213
214 /* Check if it's our memory type. */
215 if (rg.type != OMAPFB_MEMTYPE_SDRAM)
216 continue;
217
218 /* Check if the region falls within SDRAM */
219 if (rg.paddr && !valid_sdram(rg.paddr, rg.size))
220 continue;
221
222 if (rg.size == 0) {
223 pr_err("Zero size for FB region %d\n", i);
224 config_invalid = 1;
225 return;
226 }
227
228 if (rg.paddr) {
229 if (reserve_sdram(rg.paddr, rg.size)) {
230 pr_err("Trying to use reserved memory for FB region %d\n",
231 i);
232 config_invalid = 1;
233 return;
234 }
235 reserved += rg.size;
236 }
237
238 if (omapfb_config.mem_desc.region[i].size) {
239 pr_err("FB region %d already set\n", i);
240 config_invalid = 1;
241 return;
242 }
243
244 omapfb_config.mem_desc.region[i] = rg;
245 configured_regions++;
246 }
247 omapfb_config.mem_desc.region_cnt = i;
248 if (reserved)
249 pr_info("Reserving %lu bytes SDRAM for frame buffer\n",
250 reserved);
251}
252
253/*
254 * Called at sram init time, before anything is pushed to the SRAM stack.
255 * Because of the stack scheme, we will allocate everything from the
256 * start of the lowest address region to the end of SRAM. This will also
257 * include padding for page alignment and possible holes between regions.
258 *
259 * As opposed to the SDRAM case, we'll also do any dynamic allocations at
260 * this point, since the driver built as a module would have problem with
261 * freeing / reallocating the regions.
262 */
263unsigned long __init omapfb_reserve_sram(unsigned long sram_pstart,
264 unsigned long sram_vstart,
265 unsigned long sram_size,
266 unsigned long pstart_avail,
267 unsigned long size_avail)
268{
269 struct omapfb_mem_region rg;
270 unsigned long pend_avail;
271 unsigned long reserved;
272 int i;
273
274 if (config_invalid)
275 return 0;
276
277 reserved = 0;
278 pend_avail = pstart_avail + size_avail;
279 for (i = 0; ; i++) {
280 if (get_fbmem_region(i, &rg) < 0)
281 break;
282 if (i == OMAPFB_PLANE_NUM) {
283 printk(KERN_ERR
284 "Extraneous FB mem configuration entries\n");
285 config_invalid = 1;
286 return 0;
287 }
288
289 /* Check if it's our memory type. */
290 if (set_fbmem_region_type(&rg, OMAPFB_MEMTYPE_SRAM,
291 sram_pstart, sram_size) < 0 ||
292 (rg.type != OMAPFB_MEMTYPE_SRAM))
293 continue;
294 BUG_ON(omapfb_config.mem_desc.region[i].size);
295
296 if (check_fbmem_region(i, &rg, pstart_avail, size_avail) < 0) {
297 config_invalid = 1;
298 return 0;
299 }
300
301 if (!rg.paddr) {
302 /* Dynamic allocation */
303 if ((size_avail & PAGE_MASK) < rg.size) {
304 printk("Not enough SRAM for FB region %d\n",
305 i);
306 config_invalid = 1;
307 return 0;
308 }
309 size_avail = (size_avail - rg.size) & PAGE_MASK;
310 rg.paddr = pstart_avail + size_avail;
311 }
312 /* Reserve everything above the start of the region. */
313 if (pend_avail - rg.paddr > reserved)
314 reserved = pend_avail - rg.paddr;
315 size_avail = pend_avail - reserved - pstart_avail;
316
317 /*
318 * We have a kernel mapping for this already, so the
319 * driver won't have to make one.
320 */
321 rg.vaddr = (void *)(sram_vstart + rg.paddr - sram_pstart);
322 omapfb_config.mem_desc.region[i] = rg;
323 configured_regions++;
324 }
325 omapfb_config.mem_desc.region_cnt = i;
326 if (reserved)
327 pr_info("Reserving %lu bytes SRAM for frame buffer\n",
328 reserved);
329 return reserved;
330}
331
332void omapfb_set_ctrl_platform_data(void *data)
333{
334 omapfb_config.ctrl_platform_data = data;
335}
336
337static int __init omap_init_fb(void)
338{
339 const struct omap_lcd_config *conf;
340
341 if (config_invalid)
342 return 0;
343 if (configured_regions != omapfb_config.mem_desc.region_cnt) {
344 printk(KERN_ERR "Invalid FB mem configuration entries\n");
345 return 0; 69 return 0;
346 }
347 conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
348 if (conf == NULL) {
349 if (configured_regions)
350 /* FB mem config, but no LCD config? */
351 printk(KERN_ERR "Missing LCD configuration\n");
352 return 0;
353 }
354 omapfb_config.lcd = *conf;
355 70
356 return platform_device_register(&omap_fb_device); 71 return platform_device_register(&omap_fb_device);
357} 72}
@@ -374,11 +89,6 @@ static struct platform_device omap_fb_device = {
374 .num_resources = 0, 89 .num_resources = 0,
375}; 90};
376 91
377void omapfb_set_platform_data(struct omapfb_platform_data *data)
378{
379 omapfb_config = *data;
380}
381
382static int __init omap_init_fb(void) 92static int __init omap_init_fb(void)
383{ 93{
384 return platform_device_register(&omap_fb_device); 94 return platform_device_register(&omap_fb_device);
@@ -386,36 +96,8 @@ static int __init omap_init_fb(void)
386 96
387arch_initcall(omap_init_fb); 97arch_initcall(omap_init_fb);
388 98
389void omapfb_reserve_sdram_memblock(void)
390{
391}
392
393unsigned long __init omapfb_reserve_sram(unsigned long sram_pstart,
394 unsigned long sram_vstart,
395 unsigned long sram_size,
396 unsigned long start_avail,
397 unsigned long size_avail)
398{
399 return 0;
400}
401
402#else 99#else
403 100
404void omapfb_set_platform_data(struct omapfb_platform_data *data) 101void __init omapfb_set_lcd_config(omap_lcd_config *config) { }
405{
406}
407
408void omapfb_reserve_sdram_memblock(void)
409{
410}
411
412unsigned long __init omapfb_reserve_sram(unsigned long sram_pstart,
413 unsigned long sram_vstart,
414 unsigned long sram_size,
415 unsigned long start_avail,
416 unsigned long size_avail)
417{
418 return 0;
419}
420 102
421#endif 103#endif
diff --git a/arch/arm/plat-omap/fb.h b/arch/arm/plat-omap/fb.h
deleted file mode 100644
index d765d0bd8520..000000000000
--- a/arch/arm/plat-omap/fb.h
+++ /dev/null
@@ -1,10 +0,0 @@
1#ifndef __PLAT_OMAP_FB_H__
2#define __PLAT_OMAP_FB_H__
3
4extern unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
5 unsigned long sram_vstart,
6 unsigned long sram_size,
7 unsigned long pstart_avail,
8 unsigned long size_avail);
9
10#endif /* __PLAT_OMAP_FB_H__ */
diff --git a/arch/arm/plat-omap/include/plat/blizzard.h b/arch/arm/plat-omap/include/plat/blizzard.h
deleted file mode 100644
index 56e7f2e7d12f..000000000000
--- a/arch/arm/plat-omap/include/plat/blizzard.h
+++ /dev/null
@@ -1,12 +0,0 @@
1#ifndef _BLIZZARD_H
2#define _BLIZZARD_H
3
4struct blizzard_platform_data {
5 void (*power_up)(struct device *dev);
6 void (*power_down)(struct device *dev);
7 unsigned long (*get_clock_rate)(struct device *dev);
8
9 unsigned te_connected:1;
10};
11
12#endif
diff --git a/arch/arm/plat-omap/include/plat/board.h b/arch/arm/plat-omap/include/plat/board.h
index 97126dfd2888..d5eb4c87db9d 100644
--- a/arch/arm/plat-omap/include/plat/board.h
+++ b/arch/arm/plat-omap/include/plat/board.h
@@ -28,9 +28,7 @@ enum {
28 28
29/* Different peripheral ids */ 29/* Different peripheral ids */
30#define OMAP_TAG_CLOCK 0x4f01 30#define OMAP_TAG_CLOCK 0x4f01
31#define OMAP_TAG_LCD 0x4f05
32#define OMAP_TAG_GPIO_SWITCH 0x4f06 31#define OMAP_TAG_GPIO_SWITCH 0x4f06
33#define OMAP_TAG_FBMEM 0x4f08
34#define OMAP_TAG_STI_CONSOLE 0x4f09 32#define OMAP_TAG_STI_CONSOLE 0x4f09
35#define OMAP_TAG_CAMERA_SENSOR 0x4f0a 33#define OMAP_TAG_CAMERA_SENSOR 0x4f0a
36 34
diff --git a/arch/arm/plat-omap/include/plat/hwa742.h b/arch/arm/plat-omap/include/plat/hwa742.h
deleted file mode 100644
index 886248d32b49..000000000000
--- a/arch/arm/plat-omap/include/plat/hwa742.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#ifndef _HWA742_H
2#define _HWA742_H
3
4struct hwa742_platform_data {
5 unsigned te_connected:1;
6};
7
8#endif
diff --git a/arch/arm/plat-omap/include/plat/vram.h b/arch/arm/plat-omap/include/plat/vram.h
index 0aa4ecd12c7d..4d65b7d06e6c 100644
--- a/arch/arm/plat-omap/include/plat/vram.h
+++ b/arch/arm/plat-omap/include/plat/vram.h
@@ -23,40 +23,21 @@
23 23
24#include <linux/types.h> 24#include <linux/types.h>
25 25
26#define OMAP_VRAM_MEMTYPE_SDRAM 0
27#define OMAP_VRAM_MEMTYPE_SRAM 1
28#define OMAP_VRAM_MEMTYPE_MAX 1
29
30extern int omap_vram_add_region(unsigned long paddr, size_t size); 26extern int omap_vram_add_region(unsigned long paddr, size_t size);
31extern int omap_vram_free(unsigned long paddr, size_t size); 27extern int omap_vram_free(unsigned long paddr, size_t size);
32extern int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr); 28extern int omap_vram_alloc(size_t size, unsigned long *paddr);
33extern int omap_vram_reserve(unsigned long paddr, size_t size); 29extern int omap_vram_reserve(unsigned long paddr, size_t size);
34extern void omap_vram_get_info(unsigned long *vram, unsigned long *free_vram, 30extern void omap_vram_get_info(unsigned long *vram, unsigned long *free_vram,
35 unsigned long *largest_free_block); 31 unsigned long *largest_free_block);
36 32
37#ifdef CONFIG_OMAP2_VRAM 33#ifdef CONFIG_OMAP2_VRAM
38extern void omap_vram_set_sdram_vram(u32 size, u32 start); 34extern void omap_vram_set_sdram_vram(u32 size, u32 start);
39extern void omap_vram_set_sram_vram(u32 size, u32 start);
40 35
41extern void omap_vram_reserve_sdram_memblock(void); 36extern void omap_vram_reserve_sdram_memblock(void);
42extern unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
43 unsigned long sram_vstart,
44 unsigned long sram_size,
45 unsigned long pstart_avail,
46 unsigned long size_avail);
47#else 37#else
48static inline void omap_vram_set_sdram_vram(u32 size, u32 start) { } 38static inline void omap_vram_set_sdram_vram(u32 size, u32 start) { }
49static inline void omap_vram_set_sram_vram(u32 size, u32 start) { }
50 39
51static inline void omap_vram_reserve_sdram_memblock(void) { } 40static inline void omap_vram_reserve_sdram_memblock(void) { }
52static inline unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
53 unsigned long sram_vstart,
54 unsigned long sram_size,
55 unsigned long pstart_avail,
56 unsigned long size_avail)
57{
58 return 0;
59}
60#endif 41#endif
61 42
62#endif 43#endif
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index 84ff23208c25..1e7536d9a8fc 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -1,11 +1,10 @@
1config FB_OMAP 1config FB_OMAP
2 tristate "OMAP frame buffer support (EXPERIMENTAL)" 2 tristate "OMAP frame buffer support (EXPERIMENTAL)"
3 depends on FB && (OMAP2_DSS = "n") 3 depends on FB
4 depends on ARCH_OMAP1 || ARCH_OMAP2 || ARCH_OMAP3 4 depends on ARCH_OMAP1
5 select FB_CFB_FILLRECT 5 select FB_CFB_FILLRECT
6 select FB_CFB_COPYAREA 6 select FB_CFB_COPYAREA
7 select FB_CFB_IMAGEBLIT 7 select FB_CFB_IMAGEBLIT
8 select TWL4030_CORE if MACH_OMAP_2430SDP
9 help 8 help
10 Frame buffer driver for OMAP based boards. 9 Frame buffer driver for OMAP based boards.
11 10
@@ -23,13 +22,6 @@ config FB_OMAP_LCDC_HWA742
23 Say Y here if you want to have support for the external 22 Say Y here if you want to have support for the external
24 Epson HWA742 LCD controller. 23 Epson HWA742 LCD controller.
25 24
26config FB_OMAP_LCDC_BLIZZARD
27 bool "Epson Blizzard LCD controller support"
28 depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
29 help
30 Say Y here if you want to have support for the external
31 Epson Blizzard LCD controller.
32
33config FB_OMAP_MANUAL_UPDATE 25config FB_OMAP_MANUAL_UPDATE
34 bool "Default to manual update mode" 26 bool "Default to manual update mode"
35 depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL 27 depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
@@ -49,7 +41,7 @@ config FB_OMAP_LCD_MIPID
49 41
50config FB_OMAP_BOOTLOADER_INIT 42config FB_OMAP_BOOTLOADER_INIT
51 bool "Check bootloader initialization" 43 bool "Check bootloader initialization"
52 depends on FB_OMAP || FB_OMAP2 44 depends on FB_OMAP
53 help 45 help
54 Say Y here if you want to enable checking if the bootloader has 46 Say Y here if you want to enable checking if the bootloader has
55 already initialized the display controller. In this case the 47 already initialized the display controller. In this case the
@@ -68,7 +60,7 @@ config FB_OMAP_CONSISTENT_DMA_SIZE
68 60
69config FB_OMAP_DMA_TUNE 61config FB_OMAP_DMA_TUNE
70 bool "Set DMA SDRAM access priority high" 62 bool "Set DMA SDRAM access priority high"
71 depends on FB_OMAP && ARCH_OMAP1 63 depends on FB_OMAP
72 help 64 help
73 On systems in which video memory is in system memory 65 On systems in which video memory is in system memory
74 (SDRAM) this will speed up graphics DMA operations. 66 (SDRAM) this will speed up graphics DMA operations.
diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile
index ef78550917ff..1927faffb5bc 100644
--- a/drivers/video/omap/Makefile
+++ b/drivers/video/omap/Makefile
@@ -1,20 +1,14 @@
1# 1#
2# Makefile for the new OMAP framebuffer device driver 2# Makefile for the OMAP1 framebuffer device driver
3# 3#
4 4
5obj-$(CONFIG_FB_OMAP) += omapfb.o 5obj-$(CONFIG_FB_OMAP) += omapfb.o
6 6
7objs-yy := omapfb_main.o 7objs-yy := omapfb_main.o lcdc.o
8 8
9objs-y$(CONFIG_ARCH_OMAP1) += lcdc.o 9objs-y$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o
10objs-y$(CONFIG_ARCH_OMAP2) += dispc.o
11objs-y$(CONFIG_ARCH_OMAP3) += dispc.o
12
13objs-$(CONFIG_ARCH_OMAP1)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o
14objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += rfbi.o
15 10
16objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o 11objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o
17objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o
18 12
19objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o 13objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o
20objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o 14objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
deleted file mode 100644
index c0504a8a5079..000000000000
--- a/drivers/video/omap/blizzard.c
+++ /dev/null
@@ -1,1648 +0,0 @@
1/*
2 * Epson Blizzard LCD controller driver
3 *
4 * Copyright (C) 2004-2005 Nokia Corporation
5 * Authors: Juha Yrjola <juha.yrjola@nokia.com>
6 * Imre Deak <imre.deak@nokia.com>
7 * YUV support: Jussi Laako <jussi.laako@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23#include <linux/module.h>
24#include <linux/mm.h>
25#include <linux/fb.h>
26#include <linux/delay.h>
27#include <linux/clk.h>
28
29#include <plat/dma.h>
30#include <plat/blizzard.h>
31
32#include "omapfb.h"
33#include "dispc.h"
34
35#define MODULE_NAME "blizzard"
36
37#define BLIZZARD_REV_CODE 0x00
38#define BLIZZARD_CONFIG 0x02
39#define BLIZZARD_PLL_DIV 0x04
40#define BLIZZARD_PLL_LOCK_RANGE 0x06
41#define BLIZZARD_PLL_CLOCK_SYNTH_0 0x08
42#define BLIZZARD_PLL_CLOCK_SYNTH_1 0x0a
43#define BLIZZARD_PLL_MODE 0x0c
44#define BLIZZARD_CLK_SRC 0x0e
45#define BLIZZARD_MEM_BANK0_ACTIVATE 0x10
46#define BLIZZARD_MEM_BANK0_STATUS 0x14
47#define BLIZZARD_PANEL_CONFIGURATION 0x28
48#define BLIZZARD_HDISP 0x2a
49#define BLIZZARD_HNDP 0x2c
50#define BLIZZARD_VDISP0 0x2e
51#define BLIZZARD_VDISP1 0x30
52#define BLIZZARD_VNDP 0x32
53#define BLIZZARD_HSW 0x34
54#define BLIZZARD_VSW 0x38
55#define BLIZZARD_DISPLAY_MODE 0x68
56#define BLIZZARD_INPUT_WIN_X_START_0 0x6c
57#define BLIZZARD_DATA_SOURCE_SELECT 0x8e
58#define BLIZZARD_DISP_MEM_DATA_PORT 0x90
59#define BLIZZARD_DISP_MEM_READ_ADDR0 0x92
60#define BLIZZARD_POWER_SAVE 0xE6
61#define BLIZZARD_NDISP_CTRL_STATUS 0xE8
62
63/* Data source select */
64/* For S1D13745 */
65#define BLIZZARD_SRC_WRITE_LCD_BACKGROUND 0x00
66#define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE 0x01
67#define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE 0x04
68#define BLIZZARD_SRC_DISABLE_OVERLAY 0x05
69/* For S1D13744 */
70#define BLIZZARD_SRC_WRITE_LCD 0x00
71#define BLIZZARD_SRC_BLT_LCD 0x06
72
73#define BLIZZARD_COLOR_RGB565 0x01
74#define BLIZZARD_COLOR_YUV420 0x09
75
76#define BLIZZARD_VERSION_S1D13745 0x01 /* Hailstorm */
77#define BLIZZARD_VERSION_S1D13744 0x02 /* Blizzard */
78
79#define BLIZZARD_AUTO_UPDATE_TIME (HZ / 20)
80
81/* Reserve 4 request slots for requests in irq context */
82#define REQ_POOL_SIZE 24
83#define IRQ_REQ_POOL_SIZE 4
84
85#define REQ_FROM_IRQ_POOL 0x01
86
87#define REQ_COMPLETE 0
88#define REQ_PENDING 1
89
90struct blizzard_reg_list {
91 int start;
92 int end;
93};
94
95/* These need to be saved / restored separately from the rest. */
96static const struct blizzard_reg_list blizzard_pll_regs[] = {
97 {
98 .start = 0x04, /* Don't save PLL ctrl (0x0C) */
99 .end = 0x0a,
100 },
101 {
102 .start = 0x0e, /* Clock configuration */
103 .end = 0x0e,
104 },
105};
106
107static const struct blizzard_reg_list blizzard_gen_regs[] = {
108 {
109 .start = 0x18, /* SDRAM control */
110 .end = 0x20,
111 },
112 {
113 .start = 0x28, /* LCD Panel configuration */
114 .end = 0x5a, /* HSSI interface, TV configuration */
115 },
116};
117
118static u8 blizzard_reg_cache[0x5a / 2];
119
120struct update_param {
121 int plane;
122 int x, y, width, height;
123 int out_x, out_y;
124 int out_width, out_height;
125 int color_mode;
126 int bpp;
127 int flags;
128};
129
130struct blizzard_request {
131 struct list_head entry;
132 unsigned int flags;
133
134 int (*handler)(struct blizzard_request *req);
135 void (*complete)(void *data);
136 void *complete_data;
137
138 union {
139 struct update_param update;
140 struct completion *sync;
141 } par;
142};
143
144struct plane_info {
145 unsigned long offset;
146 int pos_x, pos_y;
147 int width, height;
148 int out_width, out_height;
149 int scr_width;
150 int color_mode;
151 int bpp;
152};
153
154struct blizzard_struct {
155 enum omapfb_update_mode update_mode;
156 enum omapfb_update_mode update_mode_before_suspend;
157
158 struct timer_list auto_update_timer;
159 int stop_auto_update;
160 struct omapfb_update_window auto_update_window;
161 int enabled_planes;
162 int vid_nonstd_color;
163 int vid_scaled;
164 int last_color_mode;
165 int zoom_on;
166 int zoom_area_gx1;
167 int zoom_area_gx2;
168 int zoom_area_gy1;
169 int zoom_area_gy2;
170 int screen_width;
171 int screen_height;
172 unsigned te_connected:1;
173 unsigned vsync_only:1;
174
175 struct plane_info plane[OMAPFB_PLANE_NUM];
176
177 struct blizzard_request req_pool[REQ_POOL_SIZE];
178 struct list_head pending_req_list;
179 struct list_head free_req_list;
180 struct semaphore req_sema;
181 spinlock_t req_lock;
182
183 unsigned long sys_ck_rate;
184 struct extif_timings reg_timings, lut_timings;
185
186 u32 max_transmit_size;
187 u32 extif_clk_period;
188 int extif_clk_div;
189 unsigned long pix_tx_time;
190 unsigned long line_upd_time;
191
192 struct omapfb_device *fbdev;
193 struct lcd_ctrl_extif *extif;
194 const struct lcd_ctrl *int_ctrl;
195
196 void (*power_up)(struct device *dev);
197 void (*power_down)(struct device *dev);
198
199 int version;
200} blizzard;
201
202struct lcd_ctrl blizzard_ctrl;
203
204static u8 blizzard_read_reg(u8 reg)
205{
206 u8 data;
207
208 blizzard.extif->set_bits_per_cycle(8);
209 blizzard.extif->write_command(&reg, 1);
210 blizzard.extif->read_data(&data, 1);
211
212 return data;
213}
214
215static void blizzard_write_reg(u8 reg, u8 val)
216{
217 blizzard.extif->set_bits_per_cycle(8);
218 blizzard.extif->write_command(&reg, 1);
219 blizzard.extif->write_data(&val, 1);
220}
221
222static void blizzard_restart_sdram(void)
223{
224 unsigned long tmo;
225
226 blizzard_write_reg(BLIZZARD_MEM_BANK0_ACTIVATE, 0);
227 udelay(50);
228 blizzard_write_reg(BLIZZARD_MEM_BANK0_ACTIVATE, 1);
229 tmo = jiffies + msecs_to_jiffies(200);
230 while (!(blizzard_read_reg(BLIZZARD_MEM_BANK0_STATUS) & 0x01)) {
231 if (time_after(jiffies, tmo)) {
232 dev_err(blizzard.fbdev->dev,
233 "s1d1374x: SDRAM not ready\n");
234 break;
235 }
236 msleep(1);
237 }
238}
239
240static void blizzard_stop_sdram(void)
241{
242 blizzard_write_reg(BLIZZARD_MEM_BANK0_ACTIVATE, 0);
243}
244
245/* Wait until the last window was completely written into the controllers
246 * SDRAM and we can start transferring the next window.
247 */
248static void blizzard_wait_line_buffer(void)
249{
250 unsigned long tmo = jiffies + msecs_to_jiffies(30);
251
252 while (blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS) & (1 << 7)) {
253 if (time_after(jiffies, tmo)) {
254 if (printk_ratelimit())
255 dev_err(blizzard.fbdev->dev,
256 "s1d1374x: line buffer not ready\n");
257 break;
258 }
259 }
260}
261
262/* Wait until the YYC color space converter is idle. */
263static void blizzard_wait_yyc(void)
264{
265 unsigned long tmo = jiffies + msecs_to_jiffies(30);
266
267 while (blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS) & (1 << 4)) {
268 if (time_after(jiffies, tmo)) {
269 if (printk_ratelimit())
270 dev_err(blizzard.fbdev->dev,
271 "s1d1374x: YYC not ready\n");
272 break;
273 }
274 }
275}
276
277static void disable_overlay(void)
278{
279 blizzard_write_reg(BLIZZARD_DATA_SOURCE_SELECT,
280 BLIZZARD_SRC_DISABLE_OVERLAY);
281}
282
283static void set_window_regs(int x_start, int y_start, int x_end, int y_end,
284 int x_out_start, int y_out_start,
285 int x_out_end, int y_out_end, int color_mode,
286 int zoom_off, int flags)
287{
288 u8 tmp[18];
289 u8 cmd;
290
291 x_end--;
292 y_end--;
293 tmp[0] = x_start;
294 tmp[1] = x_start >> 8;
295 tmp[2] = y_start;
296 tmp[3] = y_start >> 8;
297 tmp[4] = x_end;
298 tmp[5] = x_end >> 8;
299 tmp[6] = y_end;
300 tmp[7] = y_end >> 8;
301
302 x_out_end--;
303 y_out_end--;
304 tmp[8] = x_out_start;
305 tmp[9] = x_out_start >> 8;
306 tmp[10] = y_out_start;
307 tmp[11] = y_out_start >> 8;
308 tmp[12] = x_out_end;
309 tmp[13] = x_out_end >> 8;
310 tmp[14] = y_out_end;
311 tmp[15] = y_out_end >> 8;
312
313 tmp[16] = color_mode;
314 if (zoom_off && blizzard.version == BLIZZARD_VERSION_S1D13745)
315 tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND;
316 else if (flags & OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY)
317 tmp[17] = BLIZZARD_SRC_WRITE_OVERLAY_ENABLE;
318 else
319 tmp[17] = blizzard.version == BLIZZARD_VERSION_S1D13744 ?
320 BLIZZARD_SRC_WRITE_LCD :
321 BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
322
323 blizzard.extif->set_bits_per_cycle(8);
324 cmd = BLIZZARD_INPUT_WIN_X_START_0;
325 blizzard.extif->write_command(&cmd, 1);
326 blizzard.extif->write_data(tmp, 18);
327}
328
329static void enable_tearsync(int y, int width, int height, int screen_height,
330 int out_height, int force_vsync)
331{
332 u8 b;
333
334 b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
335 b |= 1 << 3;
336 blizzard_write_reg(BLIZZARD_NDISP_CTRL_STATUS, b);
337
338 if (likely(blizzard.vsync_only || force_vsync)) {
339 blizzard.extif->enable_tearsync(1, 0);
340 return;
341 }
342
343 if (width * blizzard.pix_tx_time < blizzard.line_upd_time) {
344 blizzard.extif->enable_tearsync(1, 0);
345 return;
346 }
347
348 if ((width * blizzard.pix_tx_time / 1000) * height <
349 (y + out_height) * (blizzard.line_upd_time / 1000)) {
350 blizzard.extif->enable_tearsync(1, 0);
351 return;
352 }
353
354 blizzard.extif->enable_tearsync(1, y + 1);
355}
356
357static void disable_tearsync(void)
358{
359 u8 b;
360
361 blizzard.extif->enable_tearsync(0, 0);
362 b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
363 b &= ~(1 << 3);
364 blizzard_write_reg(BLIZZARD_NDISP_CTRL_STATUS, b);
365 b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
366}
367
368static inline void set_extif_timings(const struct extif_timings *t);
369
370static inline struct blizzard_request *alloc_req(void)
371{
372 unsigned long flags;
373 struct blizzard_request *req;
374 int req_flags = 0;
375
376 if (!in_interrupt())
377 down(&blizzard.req_sema);
378 else
379 req_flags = REQ_FROM_IRQ_POOL;
380
381 spin_lock_irqsave(&blizzard.req_lock, flags);
382 BUG_ON(list_empty(&blizzard.free_req_list));
383 req = list_entry(blizzard.free_req_list.next,
384 struct blizzard_request, entry);
385 list_del(&req->entry);
386 spin_unlock_irqrestore(&blizzard.req_lock, flags);
387
388 INIT_LIST_HEAD(&req->entry);
389 req->flags = req_flags;
390
391 return req;
392}
393
394static inline void free_req(struct blizzard_request *req)
395{
396 unsigned long flags;
397
398 spin_lock_irqsave(&blizzard.req_lock, flags);
399
400 list_move(&req->entry, &blizzard.free_req_list);
401 if (!(req->flags & REQ_FROM_IRQ_POOL))
402 up(&blizzard.req_sema);
403
404 spin_unlock_irqrestore(&blizzard.req_lock, flags);
405}
406
407static void process_pending_requests(void)
408{
409 unsigned long flags;
410
411 spin_lock_irqsave(&blizzard.req_lock, flags);
412
413 while (!list_empty(&blizzard.pending_req_list)) {
414 struct blizzard_request *req;
415 void (*complete)(void *);
416 void *complete_data;
417
418 req = list_entry(blizzard.pending_req_list.next,
419 struct blizzard_request, entry);
420 spin_unlock_irqrestore(&blizzard.req_lock, flags);
421
422 if (req->handler(req) == REQ_PENDING)
423 return;
424
425 complete = req->complete;
426 complete_data = req->complete_data;
427 free_req(req);
428
429 if (complete)
430 complete(complete_data);
431
432 spin_lock_irqsave(&blizzard.req_lock, flags);
433 }
434
435 spin_unlock_irqrestore(&blizzard.req_lock, flags);
436}
437
438static void submit_req_list(struct list_head *head)
439{
440 unsigned long flags;
441 int process = 1;
442
443 spin_lock_irqsave(&blizzard.req_lock, flags);
444 if (likely(!list_empty(&blizzard.pending_req_list)))
445 process = 0;
446 list_splice_init(head, blizzard.pending_req_list.prev);
447 spin_unlock_irqrestore(&blizzard.req_lock, flags);
448
449 if (process)
450 process_pending_requests();
451}
452
453static void request_complete(void *data)
454{
455 struct blizzard_request *req = (struct blizzard_request *)data;
456 void (*complete)(void *);
457 void *complete_data;
458
459 complete = req->complete;
460 complete_data = req->complete_data;
461
462 free_req(req);
463
464 if (complete)
465 complete(complete_data);
466
467 process_pending_requests();
468}
469
470
471static int do_full_screen_update(struct blizzard_request *req)
472{
473 int i;
474 int flags;
475
476 for (i = 0; i < 3; i++) {
477 struct plane_info *p = &blizzard.plane[i];
478 if (!(blizzard.enabled_planes & (1 << i))) {
479 blizzard.int_ctrl->enable_plane(i, 0);
480 continue;
481 }
482 dev_dbg(blizzard.fbdev->dev, "pw %d ph %d\n",
483 p->width, p->height);
484 blizzard.int_ctrl->setup_plane(i,
485 OMAPFB_CHANNEL_OUT_LCD, p->offset,
486 p->scr_width, p->pos_x, p->pos_y,
487 p->width, p->height,
488 p->color_mode);
489 blizzard.int_ctrl->enable_plane(i, 1);
490 }
491
492 dev_dbg(blizzard.fbdev->dev, "sw %d sh %d\n",
493 blizzard.screen_width, blizzard.screen_height);
494 blizzard_wait_line_buffer();
495 flags = req->par.update.flags;
496 if (flags & OMAPFB_FORMAT_FLAG_TEARSYNC)
497 enable_tearsync(0, blizzard.screen_width,
498 blizzard.screen_height,
499 blizzard.screen_height,
500 blizzard.screen_height,
501 flags & OMAPFB_FORMAT_FLAG_FORCE_VSYNC);
502 else
503 disable_tearsync();
504
505 set_window_regs(0, 0, blizzard.screen_width, blizzard.screen_height,
506 0, 0, blizzard.screen_width, blizzard.screen_height,
507 BLIZZARD_COLOR_RGB565, blizzard.zoom_on, flags);
508 blizzard.zoom_on = 0;
509
510 blizzard.extif->set_bits_per_cycle(16);
511 /* set_window_regs has left the register index at the right
512 * place, so no need to set it here.
513 */
514 blizzard.extif->transfer_area(blizzard.screen_width,
515 blizzard.screen_height,
516 request_complete, req);
517 return REQ_PENDING;
518}
519
520static int check_1d_intersect(int a1, int a2, int b1, int b2)
521{
522 if (a2 <= b1 || b2 <= a1)
523 return 0;
524 return 1;
525}
526
527/* Setup all planes with an overlapping area with the update window. */
528static int do_partial_update(struct blizzard_request *req, int plane,
529 int x, int y, int w, int h,
530 int x_out, int y_out, int w_out, int h_out,
531 int wnd_color_mode, int bpp)
532{
533 int i;
534 int gx1, gy1, gx2, gy2;
535 int gx1_out, gy1_out, gx2_out, gy2_out;
536 int color_mode;
537 int flags;
538 int zoom_off;
539 int have_zoom_for_this_update = 0;
540
541 /* Global coordinates, relative to pixel 0,0 of the LCD */
542 gx1 = x + blizzard.plane[plane].pos_x;
543 gy1 = y + blizzard.plane[plane].pos_y;
544 gx2 = gx1 + w;
545 gy2 = gy1 + h;
546
547 flags = req->par.update.flags;
548 if (flags & OMAPFB_FORMAT_FLAG_DOUBLE) {
549 gx1_out = gx1;
550 gy1_out = gy1;
551 gx2_out = gx1 + w * 2;
552 gy2_out = gy1 + h * 2;
553 } else {
554 gx1_out = x_out + blizzard.plane[plane].pos_x;
555 gy1_out = y_out + blizzard.plane[plane].pos_y;
556 gx2_out = gx1_out + w_out;
557 gy2_out = gy1_out + h_out;
558 }
559
560 for (i = 0; i < OMAPFB_PLANE_NUM; i++) {
561 struct plane_info *p = &blizzard.plane[i];
562 int px1, py1;
563 int px2, py2;
564 int pw, ph;
565 int pposx, pposy;
566 unsigned long offset;
567
568 if (!(blizzard.enabled_planes & (1 << i)) ||
569 (wnd_color_mode && i != plane)) {
570 blizzard.int_ctrl->enable_plane(i, 0);
571 continue;
572 }
573 /* Plane coordinates */
574 if (i == plane) {
575 /* Plane in which we are doing the update.
576 * Local coordinates are the one in the update
577 * request.
578 */
579 px1 = x;
580 py1 = y;
581 px2 = x + w;
582 py2 = y + h;
583 pposx = 0;
584 pposy = 0;
585 } else {
586 /* Check if this plane has an overlapping part */
587 px1 = gx1 - p->pos_x;
588 py1 = gy1 - p->pos_y;
589 px2 = gx2 - p->pos_x;
590 py2 = gy2 - p->pos_y;
591 if (px1 >= p->width || py1 >= p->height ||
592 px2 <= 0 || py2 <= 0) {
593 blizzard.int_ctrl->enable_plane(i, 0);
594 continue;
595 }
596 /* Calculate the coordinates for the overlapping
597 * part in the plane's local coordinates.
598 */
599 pposx = -px1;
600 pposy = -py1;
601 if (px1 < 0)
602 px1 = 0;
603 if (py1 < 0)
604 py1 = 0;
605 if (px2 > p->width)
606 px2 = p->width;
607 if (py2 > p->height)
608 py2 = p->height;
609 if (pposx < 0)
610 pposx = 0;
611 if (pposy < 0)
612 pposy = 0;
613 }
614 pw = px2 - px1;
615 ph = py2 - py1;
616 offset = p->offset + (p->scr_width * py1 + px1) * p->bpp / 8;
617 if (wnd_color_mode)
618 /* Window embedded in the plane with a differing
619 * color mode / bpp. Calculate the number of DMA
620 * transfer elements in terms of the plane's bpp.
621 */
622 pw = (pw + 1) * bpp / p->bpp;
623#ifdef VERBOSE
624 dev_dbg(blizzard.fbdev->dev,
625 "plane %d offset %#08lx pposx %d pposy %d "
626 "px1 %d py1 %d pw %d ph %d\n",
627 i, offset, pposx, pposy, px1, py1, pw, ph);
628#endif
629 blizzard.int_ctrl->setup_plane(i,
630 OMAPFB_CHANNEL_OUT_LCD, offset,
631 p->scr_width,
632 pposx, pposy, pw, ph,
633 p->color_mode);
634
635 blizzard.int_ctrl->enable_plane(i, 1);
636 }
637
638 switch (wnd_color_mode) {
639 case OMAPFB_COLOR_YUV420:
640 color_mode = BLIZZARD_COLOR_YUV420;
641 /* Currently only the 16 bits/pixel cycle format is
642 * supported on the external interface. Adjust the number
643 * of transfer elements per line for 12bpp format.
644 */
645 w = (w + 1) * 3 / 4;
646 break;
647 default:
648 color_mode = BLIZZARD_COLOR_RGB565;
649 break;
650 }
651
652 blizzard_wait_line_buffer();
653 if (blizzard.last_color_mode == BLIZZARD_COLOR_YUV420)
654 blizzard_wait_yyc();
655 blizzard.last_color_mode = color_mode;
656 if (flags & OMAPFB_FORMAT_FLAG_TEARSYNC)
657 enable_tearsync(gy1, w, h,
658 blizzard.screen_height,
659 h_out,
660 flags & OMAPFB_FORMAT_FLAG_FORCE_VSYNC);
661 else
662 disable_tearsync();
663
664 if ((gx2_out - gx1_out) != (gx2 - gx1) ||
665 (gy2_out - gy1_out) != (gy2 - gy1))
666 have_zoom_for_this_update = 1;
667
668 /* 'background' type of screen update (as opposed to 'destructive')
669 can be used to disable scaling if scaling is active */
670 zoom_off = blizzard.zoom_on && !have_zoom_for_this_update &&
671 (gx1_out == 0) && (gx2_out == blizzard.screen_width) &&
672 (gy1_out == 0) && (gy2_out == blizzard.screen_height) &&
673 (gx1 == 0) && (gy1 == 0);
674
675 if (blizzard.zoom_on && !have_zoom_for_this_update && !zoom_off &&
676 check_1d_intersect(blizzard.zoom_area_gx1, blizzard.zoom_area_gx2,
677 gx1_out, gx2_out) &&
678 check_1d_intersect(blizzard.zoom_area_gy1, blizzard.zoom_area_gy2,
679 gy1_out, gy2_out)) {
680 /* Previous screen update was using scaling, current update
681 * is not using it. Additionally, current screen update is
682 * going to overlap with the scaled area. Scaling needs to be
683 * disabled in order to avoid 'magnifying glass' effect.
684 * Dummy setup of background window can be used for this.
685 */
686 set_window_regs(0, 0, blizzard.screen_width,
687 blizzard.screen_height,
688 0, 0, blizzard.screen_width,
689 blizzard.screen_height,
690 BLIZZARD_COLOR_RGB565, 1, flags);
691 blizzard.zoom_on = 0;
692 }
693
694 /* remember scaling settings if we have scaled update */
695 if (have_zoom_for_this_update) {
696 blizzard.zoom_on = 1;
697 blizzard.zoom_area_gx1 = gx1_out;
698 blizzard.zoom_area_gx2 = gx2_out;
699 blizzard.zoom_area_gy1 = gy1_out;
700 blizzard.zoom_area_gy2 = gy2_out;
701 }
702
703 set_window_regs(gx1, gy1, gx2, gy2, gx1_out, gy1_out, gx2_out, gy2_out,
704 color_mode, zoom_off, flags);
705 if (zoom_off)
706 blizzard.zoom_on = 0;
707
708 blizzard.extif->set_bits_per_cycle(16);
709 /* set_window_regs has left the register index at the right
710 * place, so no need to set it here.
711 */
712 blizzard.extif->transfer_area(w, h, request_complete, req);
713
714 return REQ_PENDING;
715}
716
717static int send_frame_handler(struct blizzard_request *req)
718{
719 struct update_param *par = &req->par.update;
720 int plane = par->plane;
721
722#ifdef VERBOSE
723 dev_dbg(blizzard.fbdev->dev,
724 "send_frame: x %d y %d w %d h %d "
725 "x_out %d y_out %d w_out %d h_out %d "
726 "color_mode %04x flags %04x planes %01x\n",
727 par->x, par->y, par->width, par->height,
728 par->out_x, par->out_y, par->out_width, par->out_height,
729 par->color_mode, par->flags, blizzard.enabled_planes);
730#endif
731 if (par->flags & OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY)
732 disable_overlay();
733
734 if ((blizzard.enabled_planes & blizzard.vid_nonstd_color) ||
735 (blizzard.enabled_planes & blizzard.vid_scaled))
736 return do_full_screen_update(req);
737
738 return do_partial_update(req, plane, par->x, par->y,
739 par->width, par->height,
740 par->out_x, par->out_y,
741 par->out_width, par->out_height,
742 par->color_mode, par->bpp);
743}
744
745static void send_frame_complete(void *data)
746{
747}
748
749#define ADD_PREQ(_x, _y, _w, _h, _x_out, _y_out, _w_out, _h_out) do { \
750 req = alloc_req(); \
751 req->handler = send_frame_handler; \
752 req->complete = send_frame_complete; \
753 req->par.update.plane = plane_idx; \
754 req->par.update.x = _x; \
755 req->par.update.y = _y; \
756 req->par.update.width = _w; \
757 req->par.update.height = _h; \
758 req->par.update.out_x = _x_out; \
759 req->par.update.out_y = _y_out; \
760 req->par.update.out_width = _w_out; \
761 req->par.update.out_height = _h_out; \
762 req->par.update.bpp = bpp; \
763 req->par.update.color_mode = color_mode;\
764 req->par.update.flags = flags; \
765 list_add_tail(&req->entry, req_head); \
766} while(0)
767
768static void create_req_list(int plane_idx,
769 struct omapfb_update_window *win,
770 struct list_head *req_head)
771{
772 struct blizzard_request *req;
773 int x = win->x;
774 int y = win->y;
775 int width = win->width;
776 int height = win->height;
777 int x_out = win->out_x;
778 int y_out = win->out_y;
779 int width_out = win->out_width;
780 int height_out = win->out_height;
781 int color_mode;
782 int bpp;
783 int flags;
784 unsigned int ystart = y;
785 unsigned int yspan = height;
786 unsigned int ystart_out = y_out;
787 unsigned int yspan_out = height_out;
788
789 flags = win->format & ~OMAPFB_FORMAT_MASK;
790 color_mode = win->format & OMAPFB_FORMAT_MASK;
791 switch (color_mode) {
792 case OMAPFB_COLOR_YUV420:
793 /* Embedded window with different color mode */
794 bpp = 12;
795 /* X, Y, height must be aligned at 2, width at 4 pixels */
796 x &= ~1;
797 y &= ~1;
798 height = yspan = height & ~1;
799 width = width & ~3;
800 break;
801 default:
802 /* Same as the plane color mode */
803 bpp = blizzard.plane[plane_idx].bpp;
804 break;
805 }
806 if (width * height * bpp / 8 > blizzard.max_transmit_size) {
807 yspan = blizzard.max_transmit_size / (width * bpp / 8);
808 yspan_out = yspan * height_out / height;
809 ADD_PREQ(x, ystart, width, yspan, x_out, ystart_out,
810 width_out, yspan_out);
811 ystart += yspan;
812 ystart_out += yspan_out;
813 yspan = height - yspan;
814 yspan_out = height_out - yspan_out;
815 flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC;
816 }
817
818 ADD_PREQ(x, ystart, width, yspan, x_out, ystart_out,
819 width_out, yspan_out);
820}
821
822static void auto_update_complete(void *data)
823{
824 if (!blizzard.stop_auto_update)
825 mod_timer(&blizzard.auto_update_timer,
826 jiffies + BLIZZARD_AUTO_UPDATE_TIME);
827}
828
829static void blizzard_update_window_auto(unsigned long arg)
830{
831 LIST_HEAD(req_list);
832 struct blizzard_request *last;
833 struct omapfb_plane_struct *plane;
834
835 plane = blizzard.fbdev->fb_info[0]->par;
836 create_req_list(plane->idx,
837 &blizzard.auto_update_window, &req_list);
838 last = list_entry(req_list.prev, struct blizzard_request, entry);
839
840 last->complete = auto_update_complete;
841 last->complete_data = NULL;
842
843 submit_req_list(&req_list);
844}
845
846int blizzard_update_window_async(struct fb_info *fbi,
847 struct omapfb_update_window *win,
848 void (*complete_callback)(void *arg),
849 void *complete_callback_data)
850{
851 LIST_HEAD(req_list);
852 struct blizzard_request *last;
853 struct omapfb_plane_struct *plane = fbi->par;
854
855 if (unlikely(blizzard.update_mode != OMAPFB_MANUAL_UPDATE))
856 return -EINVAL;
857 if (unlikely(!blizzard.te_connected &&
858 (win->format & OMAPFB_FORMAT_FLAG_TEARSYNC)))
859 return -EINVAL;
860
861 create_req_list(plane->idx, win, &req_list);
862 last = list_entry(req_list.prev, struct blizzard_request, entry);
863
864 last->complete = complete_callback;
865 last->complete_data = (void *)complete_callback_data;
866
867 submit_req_list(&req_list);
868
869 return 0;
870}
871EXPORT_SYMBOL(blizzard_update_window_async);
872
873static int update_full_screen(void)
874{
875 return blizzard_update_window_async(blizzard.fbdev->fb_info[0],
876 &blizzard.auto_update_window, NULL, NULL);
877
878}
879
880static int blizzard_setup_plane(int plane, int channel_out,
881 unsigned long offset, int screen_width,
882 int pos_x, int pos_y, int width, int height,
883 int color_mode)
884{
885 struct plane_info *p;
886
887#ifdef VERBOSE
888 dev_dbg(blizzard.fbdev->dev,
889 "plane %d ch_out %d offset %#08lx scr_width %d "
890 "pos_x %d pos_y %d width %d height %d color_mode %d\n",
891 plane, channel_out, offset, screen_width,
892 pos_x, pos_y, width, height, color_mode);
893#endif
894 if ((unsigned)plane > OMAPFB_PLANE_NUM)
895 return -EINVAL;
896 p = &blizzard.plane[plane];
897
898 switch (color_mode) {
899 case OMAPFB_COLOR_YUV422:
900 case OMAPFB_COLOR_YUY422:
901 p->bpp = 16;
902 blizzard.vid_nonstd_color &= ~(1 << plane);
903 break;
904 case OMAPFB_COLOR_YUV420:
905 p->bpp = 12;
906 blizzard.vid_nonstd_color |= 1 << plane;
907 break;
908 case OMAPFB_COLOR_RGB565:
909 p->bpp = 16;
910 blizzard.vid_nonstd_color &= ~(1 << plane);
911 break;
912 default:
913 return -EINVAL;
914 }
915
916 p->offset = offset;
917 p->pos_x = pos_x;
918 p->pos_y = pos_y;
919 p->width = width;
920 p->height = height;
921 p->scr_width = screen_width;
922 if (!p->out_width)
923 p->out_width = width;
924 if (!p->out_height)
925 p->out_height = height;
926
927 p->color_mode = color_mode;
928
929 return 0;
930}
931
932static int blizzard_set_scale(int plane, int orig_w, int orig_h,
933 int out_w, int out_h)
934{
935 struct plane_info *p = &blizzard.plane[plane];
936 int r;
937
938 dev_dbg(blizzard.fbdev->dev,
939 "plane %d orig_w %d orig_h %d out_w %d out_h %d\n",
940 plane, orig_w, orig_h, out_w, out_h);
941 if ((unsigned)plane > OMAPFB_PLANE_NUM)
942 return -ENODEV;
943
944 r = blizzard.int_ctrl->set_scale(plane, orig_w, orig_h, out_w, out_h);
945 if (r < 0)
946 return r;
947
948 p->width = orig_w;
949 p->height = orig_h;
950 p->out_width = out_w;
951 p->out_height = out_h;
952 if (orig_w == out_w && orig_h == out_h)
953 blizzard.vid_scaled &= ~(1 << plane);
954 else
955 blizzard.vid_scaled |= 1 << plane;
956
957 return 0;
958}
959
960static int blizzard_set_rotate(int angle)
961{
962 u32 l;
963
964 l = blizzard_read_reg(BLIZZARD_PANEL_CONFIGURATION);
965 l &= ~0x03;
966
967 switch (angle) {
968 case 0:
969 l = l | 0x00;
970 break;
971 case 90:
972 l = l | 0x03;
973 break;
974 case 180:
975 l = l | 0x02;
976 break;
977 case 270:
978 l = l | 0x01;
979 break;
980 default:
981 return -EINVAL;
982 }
983
984 blizzard_write_reg(BLIZZARD_PANEL_CONFIGURATION, l);
985
986 return 0;
987}
988
989static int blizzard_enable_plane(int plane, int enable)
990{
991 if (enable)
992 blizzard.enabled_planes |= 1 << plane;
993 else
994 blizzard.enabled_planes &= ~(1 << plane);
995
996 return 0;
997}
998
999static int sync_handler(struct blizzard_request *req)
1000{
1001 complete(req->par.sync);
1002 return REQ_COMPLETE;
1003}
1004
1005static void blizzard_sync(void)
1006{
1007 LIST_HEAD(req_list);
1008 struct blizzard_request *req;
1009 struct completion comp;
1010
1011 req = alloc_req();
1012
1013 req->handler = sync_handler;
1014 req->complete = NULL;
1015 init_completion(&comp);
1016 req->par.sync = &comp;
1017
1018 list_add(&req->entry, &req_list);
1019 submit_req_list(&req_list);
1020
1021 wait_for_completion(&comp);
1022}
1023
1024
1025static void blizzard_bind_client(struct omapfb_notifier_block *nb)
1026{
1027 if (blizzard.update_mode == OMAPFB_MANUAL_UPDATE) {
1028 omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_READY);
1029 }
1030}
1031
1032static int blizzard_set_update_mode(enum omapfb_update_mode mode)
1033{
1034 if (unlikely(mode != OMAPFB_MANUAL_UPDATE &&
1035 mode != OMAPFB_AUTO_UPDATE &&
1036 mode != OMAPFB_UPDATE_DISABLED))
1037 return -EINVAL;
1038
1039 if (mode == blizzard.update_mode)
1040 return 0;
1041
1042 dev_info(blizzard.fbdev->dev, "s1d1374x: setting update mode to %s\n",
1043 mode == OMAPFB_UPDATE_DISABLED ? "disabled" :
1044 (mode == OMAPFB_AUTO_UPDATE ? "auto" : "manual"));
1045
1046 switch (blizzard.update_mode) {
1047 case OMAPFB_MANUAL_UPDATE:
1048 omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_DISABLED);
1049 break;
1050 case OMAPFB_AUTO_UPDATE:
1051 blizzard.stop_auto_update = 1;
1052 del_timer_sync(&blizzard.auto_update_timer);
1053 break;
1054 case OMAPFB_UPDATE_DISABLED:
1055 break;
1056 }
1057
1058 blizzard.update_mode = mode;
1059 blizzard_sync();
1060 blizzard.stop_auto_update = 0;
1061
1062 switch (mode) {
1063 case OMAPFB_MANUAL_UPDATE:
1064 omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_READY);
1065 break;
1066 case OMAPFB_AUTO_UPDATE:
1067 blizzard_update_window_auto(0);
1068 break;
1069 case OMAPFB_UPDATE_DISABLED:
1070 break;
1071 }
1072
1073 return 0;
1074}
1075
1076static enum omapfb_update_mode blizzard_get_update_mode(void)
1077{
1078 return blizzard.update_mode;
1079}
1080
1081static inline void set_extif_timings(const struct extif_timings *t)
1082{
1083 blizzard.extif->set_timings(t);
1084}
1085
1086static inline unsigned long round_to_extif_ticks(unsigned long ps, int div)
1087{
1088 int bus_tick = blizzard.extif_clk_period * div;
1089 return (ps + bus_tick - 1) / bus_tick * bus_tick;
1090}
1091
1092static int calc_reg_timing(unsigned long sysclk, int div)
1093{
1094 struct extif_timings *t;
1095 unsigned long systim;
1096
1097 /* CSOnTime 0, WEOnTime 2 ns, REOnTime 2 ns,
1098 * AccessTime 2 ns + 12.2 ns (regs),
1099 * WEOffTime = WEOnTime + 1 ns,
1100 * REOffTime = REOnTime + 12 ns (regs),
1101 * CSOffTime = REOffTime + 1 ns
1102 * ReadCycle = 2ns + 2*SYSCLK (regs),
1103 * WriteCycle = 2*SYSCLK + 2 ns,
1104 * CSPulseWidth = 10 ns */
1105
1106 systim = 1000000000 / (sysclk / 1000);
1107 dev_dbg(blizzard.fbdev->dev,
1108 "Blizzard systim %lu ps extif_clk_period %u div %d\n",
1109 systim, blizzard.extif_clk_period, div);
1110
1111 t = &blizzard.reg_timings;
1112 memset(t, 0, sizeof(*t));
1113
1114 t->clk_div = div;
1115
1116 t->cs_on_time = 0;
1117 t->we_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);
1118 t->re_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);
1119 t->access_time = round_to_extif_ticks(t->re_on_time + 12200, div);
1120 t->we_off_time = round_to_extif_ticks(t->we_on_time + 1000, div);
1121 t->re_off_time = round_to_extif_ticks(t->re_on_time + 13000, div);
1122 t->cs_off_time = round_to_extif_ticks(t->re_off_time + 1000, div);
1123 t->we_cycle_time = round_to_extif_ticks(2 * systim + 2000, div);
1124 if (t->we_cycle_time < t->we_off_time)
1125 t->we_cycle_time = t->we_off_time;
1126 t->re_cycle_time = round_to_extif_ticks(2 * systim + 2000, div);
1127 if (t->re_cycle_time < t->re_off_time)
1128 t->re_cycle_time = t->re_off_time;
1129 t->cs_pulse_width = 0;
1130
1131 dev_dbg(blizzard.fbdev->dev, "[reg]cson %d csoff %d reon %d reoff %d\n",
1132 t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time);
1133 dev_dbg(blizzard.fbdev->dev, "[reg]weon %d weoff %d recyc %d wecyc %d\n",
1134 t->we_on_time, t->we_off_time, t->re_cycle_time,
1135 t->we_cycle_time);
1136 dev_dbg(blizzard.fbdev->dev, "[reg]rdaccess %d cspulse %d\n",
1137 t->access_time, t->cs_pulse_width);
1138
1139 return blizzard.extif->convert_timings(t);
1140}
1141
1142static int calc_lut_timing(unsigned long sysclk, int div)
1143{
1144 struct extif_timings *t;
1145 unsigned long systim;
1146
1147 /* CSOnTime 0, WEOnTime 2 ns, REOnTime 2 ns,
1148 * AccessTime 2 ns + 4 * SYSCLK + 26 (lut),
1149 * WEOffTime = WEOnTime + 1 ns,
1150 * REOffTime = REOnTime + 4*SYSCLK + 26 ns (lut),
1151 * CSOffTime = REOffTime + 1 ns
1152 * ReadCycle = 2ns + 4*SYSCLK + 26 ns (lut),
1153 * WriteCycle = 2*SYSCLK + 2 ns,
1154 * CSPulseWidth = 10 ns */
1155
1156 systim = 1000000000 / (sysclk / 1000);
1157 dev_dbg(blizzard.fbdev->dev,
1158 "Blizzard systim %lu ps extif_clk_period %u div %d\n",
1159 systim, blizzard.extif_clk_period, div);
1160
1161 t = &blizzard.lut_timings;
1162 memset(t, 0, sizeof(*t));
1163
1164 t->clk_div = div;
1165
1166 t->cs_on_time = 0;
1167 t->we_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);
1168 t->re_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);
1169 t->access_time = round_to_extif_ticks(t->re_on_time + 4 * systim +
1170 26000, div);
1171 t->we_off_time = round_to_extif_ticks(t->we_on_time + 1000, div);
1172 t->re_off_time = round_to_extif_ticks(t->re_on_time + 4 * systim +
1173 26000, div);
1174 t->cs_off_time = round_to_extif_ticks(t->re_off_time + 1000, div);
1175 t->we_cycle_time = round_to_extif_ticks(2 * systim + 2000, div);
1176 if (t->we_cycle_time < t->we_off_time)
1177 t->we_cycle_time = t->we_off_time;
1178 t->re_cycle_time = round_to_extif_ticks(2000 + 4 * systim + 26000, div);
1179 if (t->re_cycle_time < t->re_off_time)
1180 t->re_cycle_time = t->re_off_time;
1181 t->cs_pulse_width = 0;
1182
1183 dev_dbg(blizzard.fbdev->dev,
1184 "[lut]cson %d csoff %d reon %d reoff %d\n",
1185 t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time);
1186 dev_dbg(blizzard.fbdev->dev,
1187 "[lut]weon %d weoff %d recyc %d wecyc %d\n",
1188 t->we_on_time, t->we_off_time, t->re_cycle_time,
1189 t->we_cycle_time);
1190 dev_dbg(blizzard.fbdev->dev, "[lut]rdaccess %d cspulse %d\n",
1191 t->access_time, t->cs_pulse_width);
1192
1193 return blizzard.extif->convert_timings(t);
1194}
1195
1196static int calc_extif_timings(unsigned long sysclk, int *extif_mem_div)
1197{
1198 int max_clk_div;
1199 int div;
1200
1201 blizzard.extif->get_clk_info(&blizzard.extif_clk_period, &max_clk_div);
1202 for (div = 1; div <= max_clk_div; div++) {
1203 if (calc_reg_timing(sysclk, div) == 0)
1204 break;
1205 }
1206 if (div > max_clk_div) {
1207 dev_dbg(blizzard.fbdev->dev, "reg timing failed\n");
1208 goto err;
1209 }
1210 *extif_mem_div = div;
1211
1212 for (div = 1; div <= max_clk_div; div++) {
1213 if (calc_lut_timing(sysclk, div) == 0)
1214 break;
1215 }
1216
1217 if (div > max_clk_div)
1218 goto err;
1219
1220 blizzard.extif_clk_div = div;
1221
1222 return 0;
1223err:
1224 dev_err(blizzard.fbdev->dev, "can't setup timings\n");
1225 return -1;
1226}
1227
1228static void calc_blizzard_clk_rates(unsigned long ext_clk,
1229 unsigned long *sys_clk, unsigned long *pix_clk)
1230{
1231 int pix_clk_src;
1232 int sys_div = 0, sys_mul = 0;
1233 int pix_div;
1234
1235 pix_clk_src = blizzard_read_reg(BLIZZARD_CLK_SRC);
1236 pix_div = ((pix_clk_src >> 3) & 0x1f) + 1;
1237 if ((pix_clk_src & (0x3 << 1)) == 0) {
1238 /* Source is the PLL */
1239 sys_div = (blizzard_read_reg(BLIZZARD_PLL_DIV) & 0x3f) + 1;
1240 sys_mul = blizzard_read_reg(BLIZZARD_PLL_CLOCK_SYNTH_0);
1241 sys_mul |= ((blizzard_read_reg(BLIZZARD_PLL_CLOCK_SYNTH_1)
1242 & 0x0f) << 11);
1243 *sys_clk = ext_clk * sys_mul / sys_div;
1244 } else /* else source is ext clk, or oscillator */
1245 *sys_clk = ext_clk;
1246
1247 *pix_clk = *sys_clk / pix_div; /* HZ */
1248 dev_dbg(blizzard.fbdev->dev,
1249 "ext_clk %ld pix_src %d pix_div %d sys_div %d sys_mul %d\n",
1250 ext_clk, pix_clk_src & (0x3 << 1), pix_div, sys_div, sys_mul);
1251 dev_dbg(blizzard.fbdev->dev, "sys_clk %ld pix_clk %ld\n",
1252 *sys_clk, *pix_clk);
1253}
1254
1255static int setup_tearsync(unsigned long pix_clk, int extif_div)
1256{
1257 int hdisp, vdisp;
1258 int hndp, vndp;
1259 int hsw, vsw;
1260 int hs, vs;
1261 int hs_pol_inv, vs_pol_inv;
1262 int use_hsvs, use_ndp;
1263 u8 b;
1264
1265 hsw = blizzard_read_reg(BLIZZARD_HSW);
1266 vsw = blizzard_read_reg(BLIZZARD_VSW);
1267 hs_pol_inv = !(hsw & 0x80);
1268 vs_pol_inv = !(vsw & 0x80);
1269 hsw = hsw & 0x7f;
1270 vsw = vsw & 0x3f;
1271
1272 hdisp = blizzard_read_reg(BLIZZARD_HDISP) * 8;
1273 vdisp = blizzard_read_reg(BLIZZARD_VDISP0) +
1274 ((blizzard_read_reg(BLIZZARD_VDISP1) & 0x3) << 8);
1275
1276 hndp = blizzard_read_reg(BLIZZARD_HNDP) & 0x3f;
1277 vndp = blizzard_read_reg(BLIZZARD_VNDP);
1278
1279 /* time to transfer one pixel (16bpp) in ps */
1280 blizzard.pix_tx_time = blizzard.reg_timings.we_cycle_time;
1281 if (blizzard.extif->get_max_tx_rate != NULL) {
1282 /* The external interface might have a rate limitation,
1283 * if so, we have to maximize our transfer rate.
1284 */
1285 unsigned long min_tx_time;
1286 unsigned long max_tx_rate = blizzard.extif->get_max_tx_rate();
1287
1288 dev_dbg(blizzard.fbdev->dev, "max_tx_rate %ld HZ\n",
1289 max_tx_rate);
1290 min_tx_time = 1000000000 / (max_tx_rate / 1000); /* ps */
1291 if (blizzard.pix_tx_time < min_tx_time)
1292 blizzard.pix_tx_time = min_tx_time;
1293 }
1294
1295 /* time to update one line in ps */
1296 blizzard.line_upd_time = (hdisp + hndp) * 1000000 / (pix_clk / 1000);
1297 blizzard.line_upd_time *= 1000;
1298 if (hdisp * blizzard.pix_tx_time > blizzard.line_upd_time)
1299 /* transfer speed too low, we might have to use both
1300 * HS and VS */
1301 use_hsvs = 1;
1302 else
1303 /* decent transfer speed, we'll always use only VS */
1304 use_hsvs = 0;
1305
1306 if (use_hsvs && (hs_pol_inv || vs_pol_inv)) {
1307 /* HS or'ed with VS doesn't work, use the active high
1308 * TE signal based on HNDP / VNDP */
1309 use_ndp = 1;
1310 hs_pol_inv = 0;
1311 vs_pol_inv = 0;
1312 hs = hndp;
1313 vs = vndp;
1314 } else {
1315 /* Use HS or'ed with VS as a TE signal if both are needed
1316 * or VNDP if only vsync is needed. */
1317 use_ndp = 0;
1318 hs = hsw;
1319 vs = vsw;
1320 if (!use_hsvs) {
1321 hs_pol_inv = 0;
1322 vs_pol_inv = 0;
1323 }
1324 }
1325
1326 hs = hs * 1000000 / (pix_clk / 1000); /* ps */
1327 hs *= 1000;
1328
1329 vs = vs * (hdisp + hndp) * 1000000 / (pix_clk / 1000); /* ps */
1330 vs *= 1000;
1331
1332 if (vs <= hs)
1333 return -EDOM;
1334 /* set VS to 120% of HS to minimize VS detection time */
1335 vs = hs * 12 / 10;
1336 /* minimize HS too */
1337 if (hs > 10000)
1338 hs = 10000;
1339
1340 b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
1341 b &= ~0x3;
1342 b |= use_hsvs ? 1 : 0;
1343 b |= (use_ndp && use_hsvs) ? 0 : 2;
1344 blizzard_write_reg(BLIZZARD_NDISP_CTRL_STATUS, b);
1345
1346 blizzard.vsync_only = !use_hsvs;
1347
1348 dev_dbg(blizzard.fbdev->dev,
1349 "pix_clk %ld HZ pix_tx_time %ld ps line_upd_time %ld ps\n",
1350 pix_clk, blizzard.pix_tx_time, blizzard.line_upd_time);
1351 dev_dbg(blizzard.fbdev->dev,
1352 "hs %d ps vs %d ps mode %d vsync_only %d\n",
1353 hs, vs, b & 0x3, !use_hsvs);
1354
1355 return blizzard.extif->setup_tearsync(1, hs, vs,
1356 hs_pol_inv, vs_pol_inv,
1357 extif_div);
1358}
1359
1360static void blizzard_get_caps(int plane, struct omapfb_caps *caps)
1361{
1362 blizzard.int_ctrl->get_caps(plane, caps);
1363 caps->ctrl |= OMAPFB_CAPS_MANUAL_UPDATE |
1364 OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE |
1365 OMAPFB_CAPS_WINDOW_SCALE |
1366 OMAPFB_CAPS_WINDOW_OVERLAY |
1367 OMAPFB_CAPS_WINDOW_ROTATE;
1368 if (blizzard.te_connected)
1369 caps->ctrl |= OMAPFB_CAPS_TEARSYNC;
1370 caps->wnd_color |= (1 << OMAPFB_COLOR_RGB565) |
1371 (1 << OMAPFB_COLOR_YUV420);
1372}
1373
1374static void _save_regs(const struct blizzard_reg_list *list, int cnt)
1375{
1376 int i;
1377
1378 for (i = 0; i < cnt; i++, list++) {
1379 int reg;
1380 for (reg = list->start; reg <= list->end; reg += 2)
1381 blizzard_reg_cache[reg / 2] = blizzard_read_reg(reg);
1382 }
1383}
1384
1385static void _restore_regs(const struct blizzard_reg_list *list, int cnt)
1386{
1387 int i;
1388
1389 for (i = 0; i < cnt; i++, list++) {
1390 int reg;
1391 for (reg = list->start; reg <= list->end; reg += 2)
1392 blizzard_write_reg(reg, blizzard_reg_cache[reg / 2]);
1393 }
1394}
1395
1396static void blizzard_save_all_regs(void)
1397{
1398 _save_regs(blizzard_pll_regs, ARRAY_SIZE(blizzard_pll_regs));
1399 _save_regs(blizzard_gen_regs, ARRAY_SIZE(blizzard_gen_regs));
1400}
1401
1402static void blizzard_restore_pll_regs(void)
1403{
1404 _restore_regs(blizzard_pll_regs, ARRAY_SIZE(blizzard_pll_regs));
1405}
1406
1407static void blizzard_restore_gen_regs(void)
1408{
1409 _restore_regs(blizzard_gen_regs, ARRAY_SIZE(blizzard_gen_regs));
1410}
1411
1412static void blizzard_suspend(void)
1413{
1414 u32 l;
1415 unsigned long tmo;
1416
1417 if (blizzard.last_color_mode) {
1418 update_full_screen();
1419 blizzard_sync();
1420 }
1421 blizzard.update_mode_before_suspend = blizzard.update_mode;
1422 /* the following will disable clocks as well */
1423 blizzard_set_update_mode(OMAPFB_UPDATE_DISABLED);
1424
1425 blizzard_save_all_regs();
1426
1427 blizzard_stop_sdram();
1428
1429 l = blizzard_read_reg(BLIZZARD_POWER_SAVE);
1430 /* Standby, Sleep. We assume we use an external clock. */
1431 l |= 0x03;
1432 blizzard_write_reg(BLIZZARD_POWER_SAVE, l);
1433
1434 tmo = jiffies + msecs_to_jiffies(100);
1435 while (!(blizzard_read_reg(BLIZZARD_PLL_MODE) & (1 << 1))) {
1436 if (time_after(jiffies, tmo)) {
1437 dev_err(blizzard.fbdev->dev,
1438 "s1d1374x: sleep timeout, stopping PLL manually\n");
1439 l = blizzard_read_reg(BLIZZARD_PLL_MODE);
1440 l &= ~0x03;
1441 /* Disable PLL, counter function */
1442 l |= 0x2;
1443 blizzard_write_reg(BLIZZARD_PLL_MODE, l);
1444 break;
1445 }
1446 msleep(1);
1447 }
1448
1449 if (blizzard.power_down != NULL)
1450 blizzard.power_down(blizzard.fbdev->dev);
1451}
1452
1453static void blizzard_resume(void)
1454{
1455 u32 l;
1456
1457 if (blizzard.power_up != NULL)
1458 blizzard.power_up(blizzard.fbdev->dev);
1459
1460 l = blizzard_read_reg(BLIZZARD_POWER_SAVE);
1461 /* Standby, Sleep */
1462 l &= ~0x03;
1463 blizzard_write_reg(BLIZZARD_POWER_SAVE, l);
1464
1465 blizzard_restore_pll_regs();
1466 l = blizzard_read_reg(BLIZZARD_PLL_MODE);
1467 l &= ~0x03;
1468 /* Enable PLL, counter function */
1469 l |= 0x1;
1470 blizzard_write_reg(BLIZZARD_PLL_MODE, l);
1471
1472 while (!(blizzard_read_reg(BLIZZARD_PLL_DIV) & (1 << 7)))
1473 msleep(1);
1474
1475 blizzard_restart_sdram();
1476
1477 blizzard_restore_gen_regs();
1478
1479 /* Enable display */
1480 blizzard_write_reg(BLIZZARD_DISPLAY_MODE, 0x01);
1481
1482 /* the following will enable clocks as necessary */
1483 blizzard_set_update_mode(blizzard.update_mode_before_suspend);
1484
1485 /* Force a background update */
1486 blizzard.zoom_on = 1;
1487 update_full_screen();
1488 blizzard_sync();
1489}
1490
1491static int blizzard_init(struct omapfb_device *fbdev, int ext_mode,
1492 struct omapfb_mem_desc *req_vram)
1493{
1494 int r = 0, i;
1495 u8 rev, conf;
1496 unsigned long ext_clk;
1497 int extif_div;
1498 unsigned long sys_clk, pix_clk;
1499 struct omapfb_platform_data *omapfb_conf;
1500 struct blizzard_platform_data *ctrl_conf;
1501
1502 blizzard.fbdev = fbdev;
1503
1504 BUG_ON(!fbdev->ext_if || !fbdev->int_ctrl);
1505
1506 blizzard.fbdev = fbdev;
1507 blizzard.extif = fbdev->ext_if;
1508 blizzard.int_ctrl = fbdev->int_ctrl;
1509
1510 omapfb_conf = fbdev->dev->platform_data;
1511 ctrl_conf = omapfb_conf->ctrl_platform_data;
1512 if (ctrl_conf == NULL || ctrl_conf->get_clock_rate == NULL) {
1513 dev_err(fbdev->dev, "s1d1374x: missing platform data\n");
1514 r = -ENOENT;
1515 goto err1;
1516 }
1517
1518 blizzard.power_down = ctrl_conf->power_down;
1519 blizzard.power_up = ctrl_conf->power_up;
1520
1521 spin_lock_init(&blizzard.req_lock);
1522
1523 if ((r = blizzard.int_ctrl->init(fbdev, 1, req_vram)) < 0)
1524 goto err1;
1525
1526 if ((r = blizzard.extif->init(fbdev)) < 0)
1527 goto err2;
1528
1529 blizzard_ctrl.set_color_key = blizzard.int_ctrl->set_color_key;
1530 blizzard_ctrl.get_color_key = blizzard.int_ctrl->get_color_key;
1531 blizzard_ctrl.setup_mem = blizzard.int_ctrl->setup_mem;
1532 blizzard_ctrl.mmap = blizzard.int_ctrl->mmap;
1533
1534 ext_clk = ctrl_conf->get_clock_rate(fbdev->dev);
1535 if ((r = calc_extif_timings(ext_clk, &extif_div)) < 0)
1536 goto err3;
1537
1538 set_extif_timings(&blizzard.reg_timings);
1539
1540 if (blizzard.power_up != NULL)
1541 blizzard.power_up(fbdev->dev);
1542
1543 calc_blizzard_clk_rates(ext_clk, &sys_clk, &pix_clk);
1544
1545 if ((r = calc_extif_timings(sys_clk, &extif_div)) < 0)
1546 goto err3;
1547 set_extif_timings(&blizzard.reg_timings);
1548
1549 if (!(blizzard_read_reg(BLIZZARD_PLL_DIV) & 0x80)) {
1550 dev_err(fbdev->dev,
1551 "controller not initialized by the bootloader\n");
1552 r = -ENODEV;
1553 goto err3;
1554 }
1555
1556 if (ctrl_conf->te_connected) {
1557 if ((r = setup_tearsync(pix_clk, extif_div)) < 0)
1558 goto err3;
1559 blizzard.te_connected = 1;
1560 }
1561
1562 rev = blizzard_read_reg(BLIZZARD_REV_CODE);
1563 conf = blizzard_read_reg(BLIZZARD_CONFIG);
1564
1565 switch (rev & 0xfc) {
1566 case 0x9c:
1567 blizzard.version = BLIZZARD_VERSION_S1D13744;
1568 pr_info("omapfb: s1d13744 LCD controller rev %d "
1569 "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
1570 break;
1571 case 0xa4:
1572 blizzard.version = BLIZZARD_VERSION_S1D13745;
1573 pr_info("omapfb: s1d13745 LCD controller rev %d "
1574 "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
1575 break;
1576 default:
1577 dev_err(fbdev->dev, "invalid s1d1374x revision %02x\n",
1578 rev);
1579 r = -ENODEV;
1580 goto err3;
1581 }
1582
1583 blizzard.max_transmit_size = blizzard.extif->max_transmit_size;
1584
1585 blizzard.update_mode = OMAPFB_UPDATE_DISABLED;
1586
1587 blizzard.auto_update_window.x = 0;
1588 blizzard.auto_update_window.y = 0;
1589 blizzard.auto_update_window.width = fbdev->panel->x_res;
1590 blizzard.auto_update_window.height = fbdev->panel->y_res;
1591 blizzard.auto_update_window.out_x = 0;
1592 blizzard.auto_update_window.out_y = 0;
1593 blizzard.auto_update_window.out_width = fbdev->panel->x_res;
1594 blizzard.auto_update_window.out_height = fbdev->panel->y_res;
1595 blizzard.auto_update_window.format = 0;
1596
1597 blizzard.screen_width = fbdev->panel->x_res;
1598 blizzard.screen_height = fbdev->panel->y_res;
1599
1600 init_timer(&blizzard.auto_update_timer);
1601 blizzard.auto_update_timer.function = blizzard_update_window_auto;
1602 blizzard.auto_update_timer.data = 0;
1603
1604 INIT_LIST_HEAD(&blizzard.free_req_list);
1605 INIT_LIST_HEAD(&blizzard.pending_req_list);
1606 for (i = 0; i < ARRAY_SIZE(blizzard.req_pool); i++)
1607 list_add(&blizzard.req_pool[i].entry, &blizzard.free_req_list);
1608 BUG_ON(i <= IRQ_REQ_POOL_SIZE);
1609 sema_init(&blizzard.req_sema, i - IRQ_REQ_POOL_SIZE);
1610
1611 return 0;
1612err3:
1613 if (blizzard.power_down != NULL)
1614 blizzard.power_down(fbdev->dev);
1615 blizzard.extif->cleanup();
1616err2:
1617 blizzard.int_ctrl->cleanup();
1618err1:
1619 return r;
1620}
1621
1622static void blizzard_cleanup(void)
1623{
1624 blizzard_set_update_mode(OMAPFB_UPDATE_DISABLED);
1625 blizzard.extif->cleanup();
1626 blizzard.int_ctrl->cleanup();
1627 if (blizzard.power_down != NULL)
1628 blizzard.power_down(blizzard.fbdev->dev);
1629}
1630
1631struct lcd_ctrl blizzard_ctrl = {
1632 .name = "blizzard",
1633 .init = blizzard_init,
1634 .cleanup = blizzard_cleanup,
1635 .bind_client = blizzard_bind_client,
1636 .get_caps = blizzard_get_caps,
1637 .set_update_mode = blizzard_set_update_mode,
1638 .get_update_mode = blizzard_get_update_mode,
1639 .setup_plane = blizzard_setup_plane,
1640 .set_scale = blizzard_set_scale,
1641 .enable_plane = blizzard_enable_plane,
1642 .set_rotate = blizzard_set_rotate,
1643 .update_window = blizzard_update_window_async,
1644 .sync = blizzard_sync,
1645 .suspend = blizzard_suspend,
1646 .resume = blizzard_resume,
1647};
1648
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
deleted file mode 100644
index 6f61e781f15a..000000000000
--- a/drivers/video/omap/dispc.c
+++ /dev/null
@@ -1,1547 +0,0 @@
1/*
2 * OMAP2 display controller support
3 *
4 * Copyright (C) 2005 Nokia Corporation
5 * Author: Imre Deak <imre.deak@nokia.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/dma-mapping.h>
24#include <linux/mm.h>
25#include <linux/vmalloc.h>
26#include <linux/clk.h>
27#include <linux/io.h>
28#include <linux/platform_device.h>
29#include <linux/slab.h>
30
31#include <plat/sram.h>
32#include <plat/board.h>
33
34#include "omapfb.h"
35#include "dispc.h"
36
37#define MODULE_NAME "dispc"
38
39#define DSS_BASE 0x48050000
40#define DSS_SYSCONFIG 0x0010
41
42#define DISPC_BASE 0x48050400
43
44/* DISPC common */
45#define DISPC_REVISION 0x0000
46#define DISPC_SYSCONFIG 0x0010
47#define DISPC_SYSSTATUS 0x0014
48#define DISPC_IRQSTATUS 0x0018
49#define DISPC_IRQENABLE 0x001C
50#define DISPC_CONTROL 0x0040
51#define DISPC_CONFIG 0x0044
52#define DISPC_CAPABLE 0x0048
53#define DISPC_DEFAULT_COLOR0 0x004C
54#define DISPC_DEFAULT_COLOR1 0x0050
55#define DISPC_TRANS_COLOR0 0x0054
56#define DISPC_TRANS_COLOR1 0x0058
57#define DISPC_LINE_STATUS 0x005C
58#define DISPC_LINE_NUMBER 0x0060
59#define DISPC_TIMING_H 0x0064
60#define DISPC_TIMING_V 0x0068
61#define DISPC_POL_FREQ 0x006C
62#define DISPC_DIVISOR 0x0070
63#define DISPC_SIZE_DIG 0x0078
64#define DISPC_SIZE_LCD 0x007C
65
66#define DISPC_DATA_CYCLE1 0x01D4
67#define DISPC_DATA_CYCLE2 0x01D8
68#define DISPC_DATA_CYCLE3 0x01DC
69
70/* DISPC GFX plane */
71#define DISPC_GFX_BA0 0x0080
72#define DISPC_GFX_BA1 0x0084
73#define DISPC_GFX_POSITION 0x0088
74#define DISPC_GFX_SIZE 0x008C
75#define DISPC_GFX_ATTRIBUTES 0x00A0
76#define DISPC_GFX_FIFO_THRESHOLD 0x00A4
77#define DISPC_GFX_FIFO_SIZE_STATUS 0x00A8
78#define DISPC_GFX_ROW_INC 0x00AC
79#define DISPC_GFX_PIXEL_INC 0x00B0
80#define DISPC_GFX_WINDOW_SKIP 0x00B4
81#define DISPC_GFX_TABLE_BA 0x00B8
82
83/* DISPC Video plane 1/2 */
84#define DISPC_VID1_BASE 0x00BC
85#define DISPC_VID2_BASE 0x014C
86
87/* Offsets into DISPC_VID1/2_BASE */
88#define DISPC_VID_BA0 0x0000
89#define DISPC_VID_BA1 0x0004
90#define DISPC_VID_POSITION 0x0008
91#define DISPC_VID_SIZE 0x000C
92#define DISPC_VID_ATTRIBUTES 0x0010
93#define DISPC_VID_FIFO_THRESHOLD 0x0014
94#define DISPC_VID_FIFO_SIZE_STATUS 0x0018
95#define DISPC_VID_ROW_INC 0x001C
96#define DISPC_VID_PIXEL_INC 0x0020
97#define DISPC_VID_FIR 0x0024
98#define DISPC_VID_PICTURE_SIZE 0x0028
99#define DISPC_VID_ACCU0 0x002C
100#define DISPC_VID_ACCU1 0x0030
101
102/* 8 elements in 8 byte increments */
103#define DISPC_VID_FIR_COEF_H0 0x0034
104/* 8 elements in 8 byte increments */
105#define DISPC_VID_FIR_COEF_HV0 0x0038
106/* 5 elements in 4 byte increments */
107#define DISPC_VID_CONV_COEF0 0x0074
108
109#define DISPC_IRQ_FRAMEMASK 0x0001
110#define DISPC_IRQ_VSYNC 0x0002
111#define DISPC_IRQ_EVSYNC_EVEN 0x0004
112#define DISPC_IRQ_EVSYNC_ODD 0x0008
113#define DISPC_IRQ_ACBIAS_COUNT_STAT 0x0010
114#define DISPC_IRQ_PROG_LINE_NUM 0x0020
115#define DISPC_IRQ_GFX_FIFO_UNDERFLOW 0x0040
116#define DISPC_IRQ_GFX_END_WIN 0x0080
117#define DISPC_IRQ_PAL_GAMMA_MASK 0x0100
118#define DISPC_IRQ_OCP_ERR 0x0200
119#define DISPC_IRQ_VID1_FIFO_UNDERFLOW 0x0400
120#define DISPC_IRQ_VID1_END_WIN 0x0800
121#define DISPC_IRQ_VID2_FIFO_UNDERFLOW 0x1000
122#define DISPC_IRQ_VID2_END_WIN 0x2000
123#define DISPC_IRQ_SYNC_LOST 0x4000
124
125#define DISPC_IRQ_MASK_ALL 0x7fff
126
127#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
128 DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
129 DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
130 DISPC_IRQ_SYNC_LOST)
131
132#define RFBI_CONTROL 0x48050040
133
134#define MAX_PALETTE_SIZE (256 * 16)
135
136#define FLD_MASK(pos, len) (((1 << len) - 1) << pos)
137
138#define MOD_REG_FLD(reg, mask, val) \
139 dispc_write_reg((reg), (dispc_read_reg(reg) & ~(mask)) | (val));
140
141#define OMAP2_SRAM_START 0x40200000
142/* Maximum size, in reality this is smaller if SRAM is partially locked. */
143#define OMAP2_SRAM_SIZE 0xa0000 /* 640k */
144
145/* We support the SDRAM / SRAM types. See OMAPFB_PLANE_MEMTYPE_* in omapfb.h */
146#define DISPC_MEMTYPE_NUM 2
147
148#define RESMAP_SIZE(_page_cnt) \
149 ((_page_cnt + (sizeof(unsigned long) * 8) - 1) / 8)
150#define RESMAP_PTR(_res_map, _page_nr) \
151 (((_res_map)->map) + (_page_nr) / (sizeof(unsigned long) * 8))
152#define RESMAP_MASK(_page_nr) \
153 (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1)))
154
155struct resmap {
156 unsigned long start;
157 unsigned page_cnt;
158 unsigned long *map;
159};
160
161#define MAX_IRQ_HANDLERS 4
162
163static struct {
164 void __iomem *base;
165
166 struct omapfb_mem_desc mem_desc;
167 struct resmap *res_map[DISPC_MEMTYPE_NUM];
168 atomic_t map_count[OMAPFB_PLANE_NUM];
169
170 dma_addr_t palette_paddr;
171 void *palette_vaddr;
172
173 int ext_mode;
174
175 struct {
176 u32 irq_mask;
177 void (*callback)(void *);
178 void *data;
179 } irq_handlers[MAX_IRQ_HANDLERS];
180 struct completion frame_done;
181
182 int fir_hinc[OMAPFB_PLANE_NUM];
183 int fir_vinc[OMAPFB_PLANE_NUM];
184
185 struct clk *dss_ick, *dss1_fck;
186 struct clk *dss_54m_fck;
187
188 enum omapfb_update_mode update_mode;
189 struct omapfb_device *fbdev;
190
191 struct omapfb_color_key color_key;
192} dispc;
193
194static void enable_lcd_clocks(int enable);
195
196static void inline dispc_write_reg(int idx, u32 val)
197{
198 __raw_writel(val, dispc.base + idx);
199}
200
201static u32 inline dispc_read_reg(int idx)
202{
203 u32 l = __raw_readl(dispc.base + idx);
204 return l;
205}
206
207/* Select RFBI or bypass mode */
208static void enable_rfbi_mode(int enable)
209{
210 void __iomem *rfbi_control;
211 u32 l;
212
213 l = dispc_read_reg(DISPC_CONTROL);
214 /* Enable RFBI, GPIO0/1 */
215 l &= ~((1 << 11) | (1 << 15) | (1 << 16));
216 l |= enable ? (1 << 11) : 0;
217 /* RFBI En: GPIO0/1=10 RFBI Dis: GPIO0/1=11 */
218 l |= 1 << 15;
219 l |= enable ? 0 : (1 << 16);
220 dispc_write_reg(DISPC_CONTROL, l);
221
222 /* Set bypass mode in RFBI module */
223 rfbi_control = ioremap(RFBI_CONTROL, SZ_1K);
224 if (!rfbi_control) {
225 pr_err("Unable to ioremap rfbi_control\n");
226 return;
227 }
228 l = __raw_readl(rfbi_control);
229 l |= enable ? 0 : (1 << 1);
230 __raw_writel(l, rfbi_control);
231 iounmap(rfbi_control);
232}
233
234static void set_lcd_data_lines(int data_lines)
235{
236 u32 l;
237 int code = 0;
238
239 switch (data_lines) {
240 case 12:
241 code = 0;
242 break;
243 case 16:
244 code = 1;
245 break;
246 case 18:
247 code = 2;
248 break;
249 case 24:
250 code = 3;
251 break;
252 default:
253 BUG();
254 }
255
256 l = dispc_read_reg(DISPC_CONTROL);
257 l &= ~(0x03 << 8);
258 l |= code << 8;
259 dispc_write_reg(DISPC_CONTROL, l);
260}
261
262static void set_load_mode(int mode)
263{
264 BUG_ON(mode & ~(DISPC_LOAD_CLUT_ONLY | DISPC_LOAD_FRAME_ONLY |
265 DISPC_LOAD_CLUT_ONCE_FRAME));
266 MOD_REG_FLD(DISPC_CONFIG, 0x03 << 1, mode << 1);
267}
268
269void omap_dispc_set_lcd_size(int x, int y)
270{
271 BUG_ON((x > (1 << 11)) || (y > (1 << 11)));
272 enable_lcd_clocks(1);
273 MOD_REG_FLD(DISPC_SIZE_LCD, FLD_MASK(16, 11) | FLD_MASK(0, 11),
274 ((y - 1) << 16) | (x - 1));
275 enable_lcd_clocks(0);
276}
277EXPORT_SYMBOL(omap_dispc_set_lcd_size);
278
279void omap_dispc_set_digit_size(int x, int y)
280{
281 BUG_ON((x > (1 << 11)) || (y > (1 << 11)));
282 enable_lcd_clocks(1);
283 MOD_REG_FLD(DISPC_SIZE_DIG, FLD_MASK(16, 11) | FLD_MASK(0, 11),
284 ((y - 1) << 16) | (x - 1));
285 enable_lcd_clocks(0);
286}
287EXPORT_SYMBOL(omap_dispc_set_digit_size);
288
289static void setup_plane_fifo(int plane, int ext_mode)
290{
291 const u32 ftrs_reg[] = { DISPC_GFX_FIFO_THRESHOLD,
292 DISPC_VID1_BASE + DISPC_VID_FIFO_THRESHOLD,
293 DISPC_VID2_BASE + DISPC_VID_FIFO_THRESHOLD };
294 const u32 fsz_reg[] = { DISPC_GFX_FIFO_SIZE_STATUS,
295 DISPC_VID1_BASE + DISPC_VID_FIFO_SIZE_STATUS,
296 DISPC_VID2_BASE + DISPC_VID_FIFO_SIZE_STATUS };
297 int low, high;
298 u32 l;
299
300 BUG_ON(plane > 2);
301
302 l = dispc_read_reg(fsz_reg[plane]);
303 l &= FLD_MASK(0, 11);
304 if (ext_mode) {
305 low = l * 3 / 4;
306 high = l;
307 } else {
308 low = l / 4;
309 high = l * 3 / 4;
310 }
311 MOD_REG_FLD(ftrs_reg[plane], FLD_MASK(16, 12) | FLD_MASK(0, 12),
312 (high << 16) | low);
313}
314
315void omap_dispc_enable_lcd_out(int enable)
316{
317 enable_lcd_clocks(1);
318 MOD_REG_FLD(DISPC_CONTROL, 1, enable ? 1 : 0);
319 enable_lcd_clocks(0);
320}
321EXPORT_SYMBOL(omap_dispc_enable_lcd_out);
322
323void omap_dispc_enable_digit_out(int enable)
324{
325 enable_lcd_clocks(1);
326 MOD_REG_FLD(DISPC_CONTROL, 1 << 1, enable ? 1 << 1 : 0);
327 enable_lcd_clocks(0);
328}
329EXPORT_SYMBOL(omap_dispc_enable_digit_out);
330
331static inline int _setup_plane(int plane, int channel_out,
332 u32 paddr, int screen_width,
333 int pos_x, int pos_y, int width, int height,
334 int color_mode)
335{
336 const u32 at_reg[] = { DISPC_GFX_ATTRIBUTES,
337 DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES,
338 DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES };
339 const u32 ba_reg[] = { DISPC_GFX_BA0, DISPC_VID1_BASE + DISPC_VID_BA0,
340 DISPC_VID2_BASE + DISPC_VID_BA0 };
341 const u32 ps_reg[] = { DISPC_GFX_POSITION,
342 DISPC_VID1_BASE + DISPC_VID_POSITION,
343 DISPC_VID2_BASE + DISPC_VID_POSITION };
344 const u32 sz_reg[] = { DISPC_GFX_SIZE,
345 DISPC_VID1_BASE + DISPC_VID_PICTURE_SIZE,
346 DISPC_VID2_BASE + DISPC_VID_PICTURE_SIZE };
347 const u32 ri_reg[] = { DISPC_GFX_ROW_INC,
348 DISPC_VID1_BASE + DISPC_VID_ROW_INC,
349 DISPC_VID2_BASE + DISPC_VID_ROW_INC };
350 const u32 vs_reg[] = { 0, DISPC_VID1_BASE + DISPC_VID_SIZE,
351 DISPC_VID2_BASE + DISPC_VID_SIZE };
352
353 int chout_shift, burst_shift;
354 int chout_val;
355 int color_code;
356 int bpp;
357 int cconv_en;
358 int set_vsize;
359 u32 l;
360
361#ifdef VERBOSE
362 dev_dbg(dispc.fbdev->dev, "plane %d channel %d paddr %#08x scr_width %d"
363 " pos_x %d pos_y %d width %d height %d color_mode %d\n",
364 plane, channel_out, paddr, screen_width, pos_x, pos_y,
365 width, height, color_mode);
366#endif
367
368 set_vsize = 0;
369 switch (plane) {
370 case OMAPFB_PLANE_GFX:
371 burst_shift = 6;
372 chout_shift = 8;
373 break;
374 case OMAPFB_PLANE_VID1:
375 case OMAPFB_PLANE_VID2:
376 burst_shift = 14;
377 chout_shift = 16;
378 set_vsize = 1;
379 break;
380 default:
381 return -EINVAL;
382 }
383
384 switch (channel_out) {
385 case OMAPFB_CHANNEL_OUT_LCD:
386 chout_val = 0;
387 break;
388 case OMAPFB_CHANNEL_OUT_DIGIT:
389 chout_val = 1;
390 break;
391 default:
392 return -EINVAL;
393 }
394
395 cconv_en = 0;
396 switch (color_mode) {
397 case OMAPFB_COLOR_RGB565:
398 color_code = DISPC_RGB_16_BPP;
399 bpp = 16;
400 break;
401 case OMAPFB_COLOR_YUV422:
402 if (plane == 0)
403 return -EINVAL;
404 color_code = DISPC_UYVY_422;
405 cconv_en = 1;
406 bpp = 16;
407 break;
408 case OMAPFB_COLOR_YUY422:
409 if (plane == 0)
410 return -EINVAL;
411 color_code = DISPC_YUV2_422;
412 cconv_en = 1;
413 bpp = 16;
414 break;
415 default:
416 return -EINVAL;
417 }
418
419 l = dispc_read_reg(at_reg[plane]);
420
421 l &= ~(0x0f << 1);
422 l |= color_code << 1;
423 l &= ~(1 << 9);
424 l |= cconv_en << 9;
425
426 l &= ~(0x03 << burst_shift);
427 l |= DISPC_BURST_8x32 << burst_shift;
428
429 l &= ~(1 << chout_shift);
430 l |= chout_val << chout_shift;
431
432 dispc_write_reg(at_reg[plane], l);
433
434 dispc_write_reg(ba_reg[plane], paddr);
435 MOD_REG_FLD(ps_reg[plane],
436 FLD_MASK(16, 11) | FLD_MASK(0, 11), (pos_y << 16) | pos_x);
437
438 MOD_REG_FLD(sz_reg[plane], FLD_MASK(16, 11) | FLD_MASK(0, 11),
439 ((height - 1) << 16) | (width - 1));
440
441 if (set_vsize) {
442 /* Set video size if set_scale hasn't set it */
443 if (!dispc.fir_vinc[plane])
444 MOD_REG_FLD(vs_reg[plane],
445 FLD_MASK(16, 11), (height - 1) << 16);
446 if (!dispc.fir_hinc[plane])
447 MOD_REG_FLD(vs_reg[plane],
448 FLD_MASK(0, 11), width - 1);
449 }
450
451 dispc_write_reg(ri_reg[plane], (screen_width - width) * bpp / 8 + 1);
452
453 return height * screen_width * bpp / 8;
454}
455
456static int omap_dispc_setup_plane(int plane, int channel_out,
457 unsigned long offset,
458 int screen_width,
459 int pos_x, int pos_y, int width, int height,
460 int color_mode)
461{
462 u32 paddr;
463 int r;
464
465 if ((unsigned)plane > dispc.mem_desc.region_cnt)
466 return -EINVAL;
467 paddr = dispc.mem_desc.region[plane].paddr + offset;
468 enable_lcd_clocks(1);
469 r = _setup_plane(plane, channel_out, paddr,
470 screen_width,
471 pos_x, pos_y, width, height, color_mode);
472 enable_lcd_clocks(0);
473 return r;
474}
475
476static void write_firh_reg(int plane, int reg, u32 value)
477{
478 u32 base;
479
480 if (plane == 1)
481 base = DISPC_VID1_BASE + DISPC_VID_FIR_COEF_H0;
482 else
483 base = DISPC_VID2_BASE + DISPC_VID_FIR_COEF_H0;
484 dispc_write_reg(base + reg * 8, value);
485}
486
487static void write_firhv_reg(int plane, int reg, u32 value)
488{
489 u32 base;
490
491 if (plane == 1)
492 base = DISPC_VID1_BASE + DISPC_VID_FIR_COEF_HV0;
493 else
494 base = DISPC_VID2_BASE + DISPC_VID_FIR_COEF_HV0;
495 dispc_write_reg(base + reg * 8, value);
496}
497
498static void set_upsampling_coef_table(int plane)
499{
500 const u32 coef[][2] = {
501 { 0x00800000, 0x00800000 },
502 { 0x0D7CF800, 0x037B02FF },
503 { 0x1E70F5FF, 0x0C6F05FE },
504 { 0x335FF5FE, 0x205907FB },
505 { 0xF74949F7, 0x00404000 },
506 { 0xF55F33FB, 0x075920FE },
507 { 0xF5701EFE, 0x056F0CFF },
508 { 0xF87C0DFF, 0x027B0300 },
509 };
510 int i;
511
512 for (i = 0; i < 8; i++) {
513 write_firh_reg(plane, i, coef[i][0]);
514 write_firhv_reg(plane, i, coef[i][1]);
515 }
516}
517
518static int omap_dispc_set_scale(int plane,
519 int orig_width, int orig_height,
520 int out_width, int out_height)
521{
522 const u32 at_reg[] = { 0, DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES,
523 DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES };
524 const u32 vs_reg[] = { 0, DISPC_VID1_BASE + DISPC_VID_SIZE,
525 DISPC_VID2_BASE + DISPC_VID_SIZE };
526 const u32 fir_reg[] = { 0, DISPC_VID1_BASE + DISPC_VID_FIR,
527 DISPC_VID2_BASE + DISPC_VID_FIR };
528
529 u32 l;
530 int fir_hinc;
531 int fir_vinc;
532
533 if ((unsigned)plane > OMAPFB_PLANE_NUM)
534 return -ENODEV;
535
536 if (plane == OMAPFB_PLANE_GFX &&
537 (out_width != orig_width || out_height != orig_height))
538 return -EINVAL;
539
540 enable_lcd_clocks(1);
541 if (orig_width < out_width) {
542 /*
543 * Upsampling.
544 * Currently you can only scale both dimensions in one way.
545 */
546 if (orig_height > out_height ||
547 orig_width * 8 < out_width ||
548 orig_height * 8 < out_height) {
549 enable_lcd_clocks(0);
550 return -EINVAL;
551 }
552 set_upsampling_coef_table(plane);
553 } else if (orig_width > out_width) {
554 /* Downsampling not yet supported
555 */
556
557 enable_lcd_clocks(0);
558 return -EINVAL;
559 }
560 if (!orig_width || orig_width == out_width)
561 fir_hinc = 0;
562 else
563 fir_hinc = 1024 * orig_width / out_width;
564 if (!orig_height || orig_height == out_height)
565 fir_vinc = 0;
566 else
567 fir_vinc = 1024 * orig_height / out_height;
568 dispc.fir_hinc[plane] = fir_hinc;
569 dispc.fir_vinc[plane] = fir_vinc;
570
571 MOD_REG_FLD(fir_reg[plane],
572 FLD_MASK(16, 12) | FLD_MASK(0, 12),
573 ((fir_vinc & 4095) << 16) |
574 (fir_hinc & 4095));
575
576 dev_dbg(dispc.fbdev->dev, "out_width %d out_height %d orig_width %d "
577 "orig_height %d fir_hinc %d fir_vinc %d\n",
578 out_width, out_height, orig_width, orig_height,
579 fir_hinc, fir_vinc);
580
581 MOD_REG_FLD(vs_reg[plane],
582 FLD_MASK(16, 11) | FLD_MASK(0, 11),
583 ((out_height - 1) << 16) | (out_width - 1));
584
585 l = dispc_read_reg(at_reg[plane]);
586 l &= ~(0x03 << 5);
587 l |= fir_hinc ? (1 << 5) : 0;
588 l |= fir_vinc ? (1 << 6) : 0;
589 dispc_write_reg(at_reg[plane], l);
590
591 enable_lcd_clocks(0);
592 return 0;
593}
594
595static int omap_dispc_enable_plane(int plane, int enable)
596{
597 const u32 at_reg[] = { DISPC_GFX_ATTRIBUTES,
598 DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES,
599 DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES };
600 if ((unsigned int)plane > dispc.mem_desc.region_cnt)
601 return -EINVAL;
602
603 enable_lcd_clocks(1);
604 MOD_REG_FLD(at_reg[plane], 1, enable ? 1 : 0);
605 enable_lcd_clocks(0);
606
607 return 0;
608}
609
610static int omap_dispc_set_color_key(struct omapfb_color_key *ck)
611{
612 u32 df_reg, tr_reg;
613 int shift, val;
614
615 switch (ck->channel_out) {
616 case OMAPFB_CHANNEL_OUT_LCD:
617 df_reg = DISPC_DEFAULT_COLOR0;
618 tr_reg = DISPC_TRANS_COLOR0;
619 shift = 10;
620 break;
621 case OMAPFB_CHANNEL_OUT_DIGIT:
622 df_reg = DISPC_DEFAULT_COLOR1;
623 tr_reg = DISPC_TRANS_COLOR1;
624 shift = 12;
625 break;
626 default:
627 return -EINVAL;
628 }
629 switch (ck->key_type) {
630 case OMAPFB_COLOR_KEY_DISABLED:
631 val = 0;
632 break;
633 case OMAPFB_COLOR_KEY_GFX_DST:
634 val = 1;
635 break;
636 case OMAPFB_COLOR_KEY_VID_SRC:
637 val = 3;
638 break;
639 default:
640 return -EINVAL;
641 }
642 enable_lcd_clocks(1);
643 MOD_REG_FLD(DISPC_CONFIG, FLD_MASK(shift, 2), val << shift);
644
645 if (val != 0)
646 dispc_write_reg(tr_reg, ck->trans_key);
647 dispc_write_reg(df_reg, ck->background);
648 enable_lcd_clocks(0);
649
650 dispc.color_key = *ck;
651
652 return 0;
653}
654
655static int omap_dispc_get_color_key(struct omapfb_color_key *ck)
656{
657 *ck = dispc.color_key;
658 return 0;
659}
660
661static void load_palette(void)
662{
663}
664
665static int omap_dispc_set_update_mode(enum omapfb_update_mode mode)
666{
667 int r = 0;
668
669 if (mode != dispc.update_mode) {
670 switch (mode) {
671 case OMAPFB_AUTO_UPDATE:
672 case OMAPFB_MANUAL_UPDATE:
673 enable_lcd_clocks(1);
674 omap_dispc_enable_lcd_out(1);
675 dispc.update_mode = mode;
676 break;
677 case OMAPFB_UPDATE_DISABLED:
678 init_completion(&dispc.frame_done);
679 omap_dispc_enable_lcd_out(0);
680 if (!wait_for_completion_timeout(&dispc.frame_done,
681 msecs_to_jiffies(500))) {
682 dev_err(dispc.fbdev->dev,
683 "timeout waiting for FRAME DONE\n");
684 }
685 dispc.update_mode = mode;
686 enable_lcd_clocks(0);
687 break;
688 default:
689 r = -EINVAL;
690 }
691 }
692
693 return r;
694}
695
696static void omap_dispc_get_caps(int plane, struct omapfb_caps *caps)
697{
698 caps->ctrl |= OMAPFB_CAPS_PLANE_RELOCATE_MEM;
699 if (plane > 0)
700 caps->ctrl |= OMAPFB_CAPS_PLANE_SCALE;
701 caps->plane_color |= (1 << OMAPFB_COLOR_RGB565) |
702 (1 << OMAPFB_COLOR_YUV422) |
703 (1 << OMAPFB_COLOR_YUY422);
704 if (plane == 0)
705 caps->plane_color |= (1 << OMAPFB_COLOR_CLUT_8BPP) |
706 (1 << OMAPFB_COLOR_CLUT_4BPP) |
707 (1 << OMAPFB_COLOR_CLUT_2BPP) |
708 (1 << OMAPFB_COLOR_CLUT_1BPP) |
709 (1 << OMAPFB_COLOR_RGB444);
710}
711
712static enum omapfb_update_mode omap_dispc_get_update_mode(void)
713{
714 return dispc.update_mode;
715}
716
717static void setup_color_conv_coef(void)
718{
719 u32 mask = FLD_MASK(16, 11) | FLD_MASK(0, 11);
720 int cf1_reg = DISPC_VID1_BASE + DISPC_VID_CONV_COEF0;
721 int cf2_reg = DISPC_VID2_BASE + DISPC_VID_CONV_COEF0;
722 int at1_reg = DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES;
723 int at2_reg = DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES;
724 const struct color_conv_coef {
725 int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb;
726 int full_range;
727 } ctbl_bt601_5 = {
728 298, 409, 0, 298, -208, -100, 298, 0, 517, 0,
729 };
730 const struct color_conv_coef *ct;
731#define CVAL(x, y) (((x & 2047) << 16) | (y & 2047))
732
733 ct = &ctbl_bt601_5;
734
735 MOD_REG_FLD(cf1_reg, mask, CVAL(ct->rcr, ct->ry));
736 MOD_REG_FLD(cf1_reg + 4, mask, CVAL(ct->gy, ct->rcb));
737 MOD_REG_FLD(cf1_reg + 8, mask, CVAL(ct->gcb, ct->gcr));
738 MOD_REG_FLD(cf1_reg + 12, mask, CVAL(ct->bcr, ct->by));
739 MOD_REG_FLD(cf1_reg + 16, mask, CVAL(0, ct->bcb));
740
741 MOD_REG_FLD(cf2_reg, mask, CVAL(ct->rcr, ct->ry));
742 MOD_REG_FLD(cf2_reg + 4, mask, CVAL(ct->gy, ct->rcb));
743 MOD_REG_FLD(cf2_reg + 8, mask, CVAL(ct->gcb, ct->gcr));
744 MOD_REG_FLD(cf2_reg + 12, mask, CVAL(ct->bcr, ct->by));
745 MOD_REG_FLD(cf2_reg + 16, mask, CVAL(0, ct->bcb));
746#undef CVAL
747
748 MOD_REG_FLD(at1_reg, (1 << 11), ct->full_range);
749 MOD_REG_FLD(at2_reg, (1 << 11), ct->full_range);
750}
751
752static void calc_ck_div(int is_tft, int pck, int *lck_div, int *pck_div)
753{
754 unsigned long fck, lck;
755
756 *lck_div = 1;
757 pck = max(1, pck);
758 fck = clk_get_rate(dispc.dss1_fck);
759 lck = fck;
760 *pck_div = (lck + pck - 1) / pck;
761 if (is_tft)
762 *pck_div = max(2, *pck_div);
763 else
764 *pck_div = max(3, *pck_div);
765 if (*pck_div > 255) {
766 *pck_div = 255;
767 lck = pck * *pck_div;
768 *lck_div = fck / lck;
769 BUG_ON(*lck_div < 1);
770 if (*lck_div > 255) {
771 *lck_div = 255;
772 dev_warn(dispc.fbdev->dev, "pixclock %d kHz too low.\n",
773 pck / 1000);
774 }
775 }
776}
777
778static void set_lcd_tft_mode(int enable)
779{
780 u32 mask;
781
782 mask = 1 << 3;
783 MOD_REG_FLD(DISPC_CONTROL, mask, enable ? mask : 0);
784}
785
786static void set_lcd_timings(void)
787{
788 u32 l;
789 int lck_div, pck_div;
790 struct lcd_panel *panel = dispc.fbdev->panel;
791 int is_tft = panel->config & OMAP_LCDC_PANEL_TFT;
792 unsigned long fck;
793
794 l = dispc_read_reg(DISPC_TIMING_H);
795 l &= ~(FLD_MASK(0, 6) | FLD_MASK(8, 8) | FLD_MASK(20, 8));
796 l |= ( max(1, (min(64, panel->hsw))) - 1 ) << 0;
797 l |= ( max(1, (min(256, panel->hfp))) - 1 ) << 8;
798 l |= ( max(1, (min(256, panel->hbp))) - 1 ) << 20;
799 dispc_write_reg(DISPC_TIMING_H, l);
800
801 l = dispc_read_reg(DISPC_TIMING_V);
802 l &= ~(FLD_MASK(0, 6) | FLD_MASK(8, 8) | FLD_MASK(20, 8));
803 l |= ( max(1, (min(64, panel->vsw))) - 1 ) << 0;
804 l |= ( max(0, (min(255, panel->vfp))) - 0 ) << 8;
805 l |= ( max(0, (min(255, panel->vbp))) - 0 ) << 20;
806 dispc_write_reg(DISPC_TIMING_V, l);
807
808 l = dispc_read_reg(DISPC_POL_FREQ);
809 l &= ~FLD_MASK(12, 6);
810 l |= (panel->config & OMAP_LCDC_SIGNAL_MASK) << 12;
811 l |= panel->acb & 0xff;
812 dispc_write_reg(DISPC_POL_FREQ, l);
813
814 calc_ck_div(is_tft, panel->pixel_clock * 1000, &lck_div, &pck_div);
815
816 l = dispc_read_reg(DISPC_DIVISOR);
817 l &= ~(FLD_MASK(16, 8) | FLD_MASK(0, 8));
818 l |= (lck_div << 16) | (pck_div << 0);
819 dispc_write_reg(DISPC_DIVISOR, l);
820
821 /* update panel info with the exact clock */
822 fck = clk_get_rate(dispc.dss1_fck);
823 panel->pixel_clock = fck / lck_div / pck_div / 1000;
824}
825
826static void recalc_irq_mask(void)
827{
828 int i;
829 unsigned long irq_mask = DISPC_IRQ_MASK_ERROR;
830
831 for (i = 0; i < MAX_IRQ_HANDLERS; i++) {
832 if (!dispc.irq_handlers[i].callback)
833 continue;
834
835 irq_mask |= dispc.irq_handlers[i].irq_mask;
836 }
837
838 enable_lcd_clocks(1);
839 MOD_REG_FLD(DISPC_IRQENABLE, 0x7fff, irq_mask);
840 enable_lcd_clocks(0);
841}
842
843int omap_dispc_request_irq(unsigned long irq_mask, void (*callback)(void *data),
844 void *data)
845{
846 int i;
847
848 BUG_ON(callback == NULL);
849
850 for (i = 0; i < MAX_IRQ_HANDLERS; i++) {
851 if (dispc.irq_handlers[i].callback)
852 continue;
853
854 dispc.irq_handlers[i].irq_mask = irq_mask;
855 dispc.irq_handlers[i].callback = callback;
856 dispc.irq_handlers[i].data = data;
857 recalc_irq_mask();
858
859 return 0;
860 }
861
862 return -EBUSY;
863}
864EXPORT_SYMBOL(omap_dispc_request_irq);
865
866void omap_dispc_free_irq(unsigned long irq_mask, void (*callback)(void *data),
867 void *data)
868{
869 int i;
870
871 for (i = 0; i < MAX_IRQ_HANDLERS; i++) {
872 if (dispc.irq_handlers[i].callback == callback &&
873 dispc.irq_handlers[i].data == data) {
874 dispc.irq_handlers[i].irq_mask = 0;
875 dispc.irq_handlers[i].callback = NULL;
876 dispc.irq_handlers[i].data = NULL;
877 recalc_irq_mask();
878 return;
879 }
880 }
881
882 BUG();
883}
884EXPORT_SYMBOL(omap_dispc_free_irq);
885
886static irqreturn_t omap_dispc_irq_handler(int irq, void *dev)
887{
888 u32 stat;
889 int i = 0;
890
891 enable_lcd_clocks(1);
892
893 stat = dispc_read_reg(DISPC_IRQSTATUS);
894 if (stat & DISPC_IRQ_FRAMEMASK)
895 complete(&dispc.frame_done);
896
897 if (stat & DISPC_IRQ_MASK_ERROR) {
898 if (printk_ratelimit()) {
899 dev_err(dispc.fbdev->dev, "irq error status %04x\n",
900 stat & 0x7fff);
901 }
902 }
903
904 for (i = 0; i < MAX_IRQ_HANDLERS; i++) {
905 if (unlikely(dispc.irq_handlers[i].callback &&
906 (stat & dispc.irq_handlers[i].irq_mask)))
907 dispc.irq_handlers[i].callback(
908 dispc.irq_handlers[i].data);
909 }
910
911 dispc_write_reg(DISPC_IRQSTATUS, stat);
912
913 enable_lcd_clocks(0);
914
915 return IRQ_HANDLED;
916}
917
918static int get_dss_clocks(void)
919{
920 dispc.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick");
921 if (IS_ERR(dispc.dss_ick)) {
922 dev_err(dispc.fbdev->dev, "can't get ick\n");
923 return PTR_ERR(dispc.dss_ick);
924 }
925
926 dispc.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "fck");
927 if (IS_ERR(dispc.dss1_fck)) {
928 dev_err(dispc.fbdev->dev, "can't get dss1_fck\n");
929 clk_put(dispc.dss_ick);
930 return PTR_ERR(dispc.dss1_fck);
931 }
932
933 dispc.dss_54m_fck = clk_get(&dispc.fbdev->dssdev->dev, "tv_clk");
934 if (IS_ERR(dispc.dss_54m_fck)) {
935 dev_err(dispc.fbdev->dev, "can't get tv_fck\n");
936 clk_put(dispc.dss_ick);
937 clk_put(dispc.dss1_fck);
938 return PTR_ERR(dispc.dss_54m_fck);
939 }
940
941 return 0;
942}
943
944static void put_dss_clocks(void)
945{
946 clk_put(dispc.dss_54m_fck);
947 clk_put(dispc.dss1_fck);
948 clk_put(dispc.dss_ick);
949}
950
951static void enable_lcd_clocks(int enable)
952{
953 if (enable) {
954 clk_enable(dispc.dss_ick);
955 clk_enable(dispc.dss1_fck);
956 } else {
957 clk_disable(dispc.dss1_fck);
958 clk_disable(dispc.dss_ick);
959 }
960}
961
962static void enable_digit_clocks(int enable)
963{
964 if (enable)
965 clk_enable(dispc.dss_54m_fck);
966 else
967 clk_disable(dispc.dss_54m_fck);
968}
969
970static void omap_dispc_suspend(void)
971{
972 if (dispc.update_mode == OMAPFB_AUTO_UPDATE) {
973 init_completion(&dispc.frame_done);
974 omap_dispc_enable_lcd_out(0);
975 if (!wait_for_completion_timeout(&dispc.frame_done,
976 msecs_to_jiffies(500))) {
977 dev_err(dispc.fbdev->dev,
978 "timeout waiting for FRAME DONE\n");
979 }
980 enable_lcd_clocks(0);
981 }
982}
983
984static void omap_dispc_resume(void)
985{
986 if (dispc.update_mode == OMAPFB_AUTO_UPDATE) {
987 enable_lcd_clocks(1);
988 if (!dispc.ext_mode) {
989 set_lcd_timings();
990 load_palette();
991 }
992 omap_dispc_enable_lcd_out(1);
993 }
994}
995
996
997static int omap_dispc_update_window(struct fb_info *fbi,
998 struct omapfb_update_window *win,
999 void (*complete_callback)(void *arg),
1000 void *complete_callback_data)
1001{
1002 return dispc.update_mode == OMAPFB_UPDATE_DISABLED ? -ENODEV : 0;
1003}
1004
1005static int mmap_kern(struct omapfb_mem_region *region)
1006{
1007 struct vm_struct *kvma;
1008 struct vm_area_struct vma;
1009 pgprot_t pgprot;
1010 unsigned long vaddr;
1011
1012 kvma = get_vm_area(region->size, VM_IOREMAP);
1013 if (kvma == NULL) {
1014 dev_err(dispc.fbdev->dev, "can't get kernel vm area\n");
1015 return -ENOMEM;
1016 }
1017 vma.vm_mm = &init_mm;
1018
1019 vaddr = (unsigned long)kvma->addr;
1020
1021 pgprot = pgprot_writecombine(pgprot_kernel);
1022 vma.vm_start = vaddr;
1023 vma.vm_end = vaddr + region->size;
1024 if (io_remap_pfn_range(&vma, vaddr, region->paddr >> PAGE_SHIFT,
1025 region->size, pgprot) < 0) {
1026 dev_err(dispc.fbdev->dev, "kernel mmap for FBMEM failed\n");
1027 return -EAGAIN;
1028 }
1029 region->vaddr = (void *)vaddr;
1030
1031 return 0;
1032}
1033
1034static void mmap_user_open(struct vm_area_struct *vma)
1035{
1036 int plane = (int)vma->vm_private_data;
1037
1038 atomic_inc(&dispc.map_count[plane]);
1039}
1040
1041static void mmap_user_close(struct vm_area_struct *vma)
1042{
1043 int plane = (int)vma->vm_private_data;
1044
1045 atomic_dec(&dispc.map_count[plane]);
1046}
1047
1048static const struct vm_operations_struct mmap_user_ops = {
1049 .open = mmap_user_open,
1050 .close = mmap_user_close,
1051};
1052
1053static int omap_dispc_mmap_user(struct fb_info *info,
1054 struct vm_area_struct *vma)
1055{
1056 struct omapfb_plane_struct *plane = info->par;
1057 unsigned long off;
1058 unsigned long start;
1059 u32 len;
1060
1061 if (vma->vm_end - vma->vm_start == 0)
1062 return 0;
1063 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1064 return -EINVAL;
1065 off = vma->vm_pgoff << PAGE_SHIFT;
1066
1067 start = info->fix.smem_start;
1068 len = info->fix.smem_len;
1069 if (off >= len)
1070 return -EINVAL;
1071 if ((vma->vm_end - vma->vm_start + off) > len)
1072 return -EINVAL;
1073 off += start;
1074 vma->vm_pgoff = off >> PAGE_SHIFT;
1075 vma->vm_flags |= VM_IO | VM_RESERVED;
1076 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
1077 vma->vm_ops = &mmap_user_ops;
1078 vma->vm_private_data = (void *)plane->idx;
1079 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
1080 vma->vm_end - vma->vm_start, vma->vm_page_prot))
1081 return -EAGAIN;
1082 /* vm_ops.open won't be called for mmap itself. */
1083 atomic_inc(&dispc.map_count[plane->idx]);
1084 return 0;
1085}
1086
1087static void unmap_kern(struct omapfb_mem_region *region)
1088{
1089 vunmap(region->vaddr);
1090}
1091
1092static int alloc_palette_ram(void)
1093{
1094 dispc.palette_vaddr = dma_alloc_writecombine(dispc.fbdev->dev,
1095 MAX_PALETTE_SIZE, &dispc.palette_paddr, GFP_KERNEL);
1096 if (dispc.palette_vaddr == NULL) {
1097 dev_err(dispc.fbdev->dev, "failed to alloc palette memory\n");
1098 return -ENOMEM;
1099 }
1100
1101 return 0;
1102}
1103
1104static void free_palette_ram(void)
1105{
1106 dma_free_writecombine(dispc.fbdev->dev, MAX_PALETTE_SIZE,
1107 dispc.palette_vaddr, dispc.palette_paddr);
1108}
1109
1110static int alloc_fbmem(struct omapfb_mem_region *region)
1111{
1112 region->vaddr = dma_alloc_writecombine(dispc.fbdev->dev,
1113 region->size, &region->paddr, GFP_KERNEL);
1114
1115 if (region->vaddr == NULL) {
1116 dev_err(dispc.fbdev->dev, "unable to allocate FB DMA memory\n");
1117 return -ENOMEM;
1118 }
1119
1120 return 0;
1121}
1122
1123static void free_fbmem(struct omapfb_mem_region *region)
1124{
1125 dma_free_writecombine(dispc.fbdev->dev, region->size,
1126 region->vaddr, region->paddr);
1127}
1128
1129static struct resmap *init_resmap(unsigned long start, size_t size)
1130{
1131 unsigned page_cnt;
1132 struct resmap *res_map;
1133
1134 page_cnt = PAGE_ALIGN(size) / PAGE_SIZE;
1135 res_map =
1136 kzalloc(sizeof(struct resmap) + RESMAP_SIZE(page_cnt), GFP_KERNEL);
1137 if (res_map == NULL)
1138 return NULL;
1139 res_map->start = start;
1140 res_map->page_cnt = page_cnt;
1141 res_map->map = (unsigned long *)(res_map + 1);
1142 return res_map;
1143}
1144
1145static void cleanup_resmap(struct resmap *res_map)
1146{
1147 kfree(res_map);
1148}
1149
1150static inline int resmap_mem_type(unsigned long start)
1151{
1152 if (start >= OMAP2_SRAM_START &&
1153 start < OMAP2_SRAM_START + OMAP2_SRAM_SIZE)
1154 return OMAPFB_MEMTYPE_SRAM;
1155 else
1156 return OMAPFB_MEMTYPE_SDRAM;
1157}
1158
1159static inline int resmap_page_reserved(struct resmap *res_map, unsigned page_nr)
1160{
1161 return *RESMAP_PTR(res_map, page_nr) & RESMAP_MASK(page_nr) ? 1 : 0;
1162}
1163
1164static inline void resmap_reserve_page(struct resmap *res_map, unsigned page_nr)
1165{
1166 BUG_ON(resmap_page_reserved(res_map, page_nr));
1167 *RESMAP_PTR(res_map, page_nr) |= RESMAP_MASK(page_nr);
1168}
1169
1170static inline void resmap_free_page(struct resmap *res_map, unsigned page_nr)
1171{
1172 BUG_ON(!resmap_page_reserved(res_map, page_nr));
1173 *RESMAP_PTR(res_map, page_nr) &= ~RESMAP_MASK(page_nr);
1174}
1175
1176static void resmap_reserve_region(unsigned long start, size_t size)
1177{
1178
1179 struct resmap *res_map;
1180 unsigned start_page;
1181 unsigned end_page;
1182 int mtype;
1183 unsigned i;
1184
1185 mtype = resmap_mem_type(start);
1186 res_map = dispc.res_map[mtype];
1187 dev_dbg(dispc.fbdev->dev, "reserve mem type %d start %08lx size %d\n",
1188 mtype, start, size);
1189 start_page = (start - res_map->start) / PAGE_SIZE;
1190 end_page = start_page + PAGE_ALIGN(size) / PAGE_SIZE;
1191 for (i = start_page; i < end_page; i++)
1192 resmap_reserve_page(res_map, i);
1193}
1194
1195static void resmap_free_region(unsigned long start, size_t size)
1196{
1197 struct resmap *res_map;
1198 unsigned start_page;
1199 unsigned end_page;
1200 unsigned i;
1201 int mtype;
1202
1203 mtype = resmap_mem_type(start);
1204 res_map = dispc.res_map[mtype];
1205 dev_dbg(dispc.fbdev->dev, "free mem type %d start %08lx size %d\n",
1206 mtype, start, size);
1207 start_page = (start - res_map->start) / PAGE_SIZE;
1208 end_page = start_page + PAGE_ALIGN(size) / PAGE_SIZE;
1209 for (i = start_page; i < end_page; i++)
1210 resmap_free_page(res_map, i);
1211}
1212
1213static unsigned long resmap_alloc_region(int mtype, size_t size)
1214{
1215 unsigned i;
1216 unsigned total;
1217 unsigned start_page;
1218 unsigned long start;
1219 struct resmap *res_map = dispc.res_map[mtype];
1220
1221 BUG_ON(mtype >= DISPC_MEMTYPE_NUM || res_map == NULL || !size);
1222
1223 size = PAGE_ALIGN(size) / PAGE_SIZE;
1224 start_page = 0;
1225 total = 0;
1226 for (i = 0; i < res_map->page_cnt; i++) {
1227 if (resmap_page_reserved(res_map, i)) {
1228 start_page = i + 1;
1229 total = 0;
1230 } else if (++total == size)
1231 break;
1232 }
1233 if (total < size)
1234 return 0;
1235
1236 start = res_map->start + start_page * PAGE_SIZE;
1237 resmap_reserve_region(start, size * PAGE_SIZE);
1238
1239 return start;
1240}
1241
1242/* Note that this will only work for user mappings, we don't deal with
1243 * kernel mappings here, so fbcon will keep using the old region.
1244 */
1245static int omap_dispc_setup_mem(int plane, size_t size, int mem_type,
1246 unsigned long *paddr)
1247{
1248 struct omapfb_mem_region *rg;
1249 unsigned long new_addr = 0;
1250
1251 if ((unsigned)plane > dispc.mem_desc.region_cnt)
1252 return -EINVAL;
1253 if (mem_type >= DISPC_MEMTYPE_NUM)
1254 return -EINVAL;
1255 if (dispc.res_map[mem_type] == NULL)
1256 return -ENOMEM;
1257 rg = &dispc.mem_desc.region[plane];
1258 if (size == rg->size && mem_type == rg->type)
1259 return 0;
1260 if (atomic_read(&dispc.map_count[plane]))
1261 return -EBUSY;
1262 if (rg->size != 0)
1263 resmap_free_region(rg->paddr, rg->size);
1264 if (size != 0) {
1265 new_addr = resmap_alloc_region(mem_type, size);
1266 if (!new_addr) {
1267 /* Reallocate old region. */
1268 resmap_reserve_region(rg->paddr, rg->size);
1269 return -ENOMEM;
1270 }
1271 }
1272 rg->paddr = new_addr;
1273 rg->size = size;
1274 rg->type = mem_type;
1275
1276 *paddr = new_addr;
1277
1278 return 0;
1279}
1280
1281static int setup_fbmem(struct omapfb_mem_desc *req_md)
1282{
1283 struct omapfb_mem_region *rg;
1284 int i;
1285 int r;
1286 unsigned long mem_start[DISPC_MEMTYPE_NUM];
1287 unsigned long mem_end[DISPC_MEMTYPE_NUM];
1288
1289 if (!req_md->region_cnt) {
1290 dev_err(dispc.fbdev->dev, "no memory regions defined\n");
1291 return -ENOENT;
1292 }
1293
1294 rg = &req_md->region[0];
1295 memset(mem_start, 0xff, sizeof(mem_start));
1296 memset(mem_end, 0, sizeof(mem_end));
1297
1298 for (i = 0; i < req_md->region_cnt; i++, rg++) {
1299 int mtype;
1300 if (rg->paddr) {
1301 rg->alloc = 0;
1302 if (rg->vaddr == NULL) {
1303 rg->map = 1;
1304 if ((r = mmap_kern(rg)) < 0)
1305 return r;
1306 }
1307 } else {
1308 if (rg->type != OMAPFB_MEMTYPE_SDRAM) {
1309 dev_err(dispc.fbdev->dev,
1310 "unsupported memory type\n");
1311 return -EINVAL;
1312 }
1313 rg->alloc = rg->map = 1;
1314 if ((r = alloc_fbmem(rg)) < 0)
1315 return r;
1316 }
1317 mtype = rg->type;
1318
1319 if (rg->paddr < mem_start[mtype])
1320 mem_start[mtype] = rg->paddr;
1321 if (rg->paddr + rg->size > mem_end[mtype])
1322 mem_end[mtype] = rg->paddr + rg->size;
1323 }
1324
1325 for (i = 0; i < DISPC_MEMTYPE_NUM; i++) {
1326 unsigned long start;
1327 size_t size;
1328 if (mem_end[i] == 0)
1329 continue;
1330 start = mem_start[i];
1331 size = mem_end[i] - start;
1332 dispc.res_map[i] = init_resmap(start, size);
1333 r = -ENOMEM;
1334 if (dispc.res_map[i] == NULL)
1335 goto fail;
1336 /* Initial state is that everything is reserved. This
1337 * includes possible holes as well, which will never be
1338 * freed.
1339 */
1340 resmap_reserve_region(start, size);
1341 }
1342
1343 dispc.mem_desc = *req_md;
1344
1345 return 0;
1346fail:
1347 for (i = 0; i < DISPC_MEMTYPE_NUM; i++) {
1348 if (dispc.res_map[i] != NULL)
1349 cleanup_resmap(dispc.res_map[i]);
1350 }
1351 return r;
1352}
1353
1354static void cleanup_fbmem(void)
1355{
1356 struct omapfb_mem_region *rg;
1357 int i;
1358
1359 for (i = 0; i < DISPC_MEMTYPE_NUM; i++) {
1360 if (dispc.res_map[i] != NULL)
1361 cleanup_resmap(dispc.res_map[i]);
1362 }
1363 rg = &dispc.mem_desc.region[0];
1364 for (i = 0; i < dispc.mem_desc.region_cnt; i++, rg++) {
1365 if (rg->alloc)
1366 free_fbmem(rg);
1367 else {
1368 if (rg->map)
1369 unmap_kern(rg);
1370 }
1371 }
1372}
1373
1374static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
1375 struct omapfb_mem_desc *req_vram)
1376{
1377 int r;
1378 u32 l;
1379 struct lcd_panel *panel = fbdev->panel;
1380 void __iomem *ram_fw_base;
1381 int tmo = 10000;
1382 int skip_init = 0;
1383 int i;
1384
1385 memset(&dispc, 0, sizeof(dispc));
1386
1387 dispc.base = ioremap(DISPC_BASE, SZ_1K);
1388 if (!dispc.base) {
1389 dev_err(fbdev->dev, "can't ioremap DISPC\n");
1390 return -ENOMEM;
1391 }
1392
1393 dispc.fbdev = fbdev;
1394 dispc.ext_mode = ext_mode;
1395
1396 init_completion(&dispc.frame_done);
1397
1398 if ((r = get_dss_clocks()) < 0)
1399 goto fail0;
1400
1401 enable_lcd_clocks(1);
1402
1403#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
1404 l = dispc_read_reg(DISPC_CONTROL);
1405 /* LCD enabled ? */
1406 if (l & 1) {
1407 pr_info("omapfb: skipping hardware initialization\n");
1408 skip_init = 1;
1409 }
1410#endif
1411
1412 if (!skip_init) {
1413 /* Reset monitoring works only w/ the 54M clk */
1414 enable_digit_clocks(1);
1415
1416 /* Soft reset */
1417 MOD_REG_FLD(DISPC_SYSCONFIG, 1 << 1, 1 << 1);
1418
1419 while (!(dispc_read_reg(DISPC_SYSSTATUS) & 1)) {
1420 if (!--tmo) {
1421 dev_err(dispc.fbdev->dev, "soft reset failed\n");
1422 r = -ENODEV;
1423 enable_digit_clocks(0);
1424 goto fail1;
1425 }
1426 }
1427
1428 enable_digit_clocks(0);
1429 }
1430
1431 /* Enable smart standby/idle, autoidle and wakeup */
1432 l = dispc_read_reg(DISPC_SYSCONFIG);
1433 l &= ~((3 << 12) | (3 << 3));
1434 l |= (2 << 12) | (2 << 3) | (1 << 2) | (1 << 0);
1435 dispc_write_reg(DISPC_SYSCONFIG, l);
1436 omap_writel(1 << 0, DSS_BASE + DSS_SYSCONFIG);
1437
1438 /* Set functional clock autogating */
1439 l = dispc_read_reg(DISPC_CONFIG);
1440 l |= 1 << 9;
1441 dispc_write_reg(DISPC_CONFIG, l);
1442
1443 l = dispc_read_reg(DISPC_IRQSTATUS);
1444 dispc_write_reg(DISPC_IRQSTATUS, l);
1445
1446 recalc_irq_mask();
1447
1448 if ((r = request_irq(INT_24XX_DSS_IRQ, omap_dispc_irq_handler,
1449 0, MODULE_NAME, fbdev)) < 0) {
1450 dev_err(dispc.fbdev->dev, "can't get DSS IRQ\n");
1451 goto fail1;
1452 }
1453
1454 /* L3 firewall setting: enable access to OCM RAM */
1455 ram_fw_base = ioremap(0x68005000, SZ_1K);
1456 if (!ram_fw_base) {
1457 dev_err(dispc.fbdev->dev, "Cannot ioremap to enable OCM RAM\n");
1458 goto fail1;
1459 }
1460 __raw_writel(0x402000b0, ram_fw_base + 0xa0);
1461 iounmap(ram_fw_base);
1462
1463 if ((r = alloc_palette_ram()) < 0)
1464 goto fail2;
1465
1466 if ((r = setup_fbmem(req_vram)) < 0)
1467 goto fail3;
1468
1469 if (!skip_init) {
1470 for (i = 0; i < dispc.mem_desc.region_cnt; i++) {
1471 memset(dispc.mem_desc.region[i].vaddr, 0,
1472 dispc.mem_desc.region[i].size);
1473 }
1474
1475 /* Set logic clock to fck, pixel clock to fck/2 for now */
1476 MOD_REG_FLD(DISPC_DIVISOR, FLD_MASK(16, 8), 1 << 16);
1477 MOD_REG_FLD(DISPC_DIVISOR, FLD_MASK(0, 8), 2 << 0);
1478
1479 setup_plane_fifo(0, ext_mode);
1480 setup_plane_fifo(1, ext_mode);
1481 setup_plane_fifo(2, ext_mode);
1482
1483 setup_color_conv_coef();
1484
1485 set_lcd_tft_mode(panel->config & OMAP_LCDC_PANEL_TFT);
1486 set_load_mode(DISPC_LOAD_FRAME_ONLY);
1487
1488 if (!ext_mode) {
1489 set_lcd_data_lines(panel->data_lines);
1490 omap_dispc_set_lcd_size(panel->x_res, panel->y_res);
1491 set_lcd_timings();
1492 } else
1493 set_lcd_data_lines(panel->bpp);
1494 enable_rfbi_mode(ext_mode);
1495 }
1496
1497 l = dispc_read_reg(DISPC_REVISION);
1498 pr_info("omapfb: DISPC version %d.%d initialized\n",
1499 l >> 4 & 0x0f, l & 0x0f);
1500 enable_lcd_clocks(0);
1501
1502 return 0;
1503fail3:
1504 free_palette_ram();
1505fail2:
1506 free_irq(INT_24XX_DSS_IRQ, fbdev);
1507fail1:
1508 enable_lcd_clocks(0);
1509 put_dss_clocks();
1510fail0:
1511 iounmap(dispc.base);
1512 return r;
1513}
1514
1515static void omap_dispc_cleanup(void)
1516{
1517 int i;
1518
1519 omap_dispc_set_update_mode(OMAPFB_UPDATE_DISABLED);
1520 /* This will also disable clocks that are on */
1521 for (i = 0; i < dispc.mem_desc.region_cnt; i++)
1522 omap_dispc_enable_plane(i, 0);
1523 cleanup_fbmem();
1524 free_palette_ram();
1525 free_irq(INT_24XX_DSS_IRQ, dispc.fbdev);
1526 put_dss_clocks();
1527 iounmap(dispc.base);
1528}
1529
1530const struct lcd_ctrl omap2_int_ctrl = {
1531 .name = "internal",
1532 .init = omap_dispc_init,
1533 .cleanup = omap_dispc_cleanup,
1534 .get_caps = omap_dispc_get_caps,
1535 .set_update_mode = omap_dispc_set_update_mode,
1536 .get_update_mode = omap_dispc_get_update_mode,
1537 .update_window = omap_dispc_update_window,
1538 .suspend = omap_dispc_suspend,
1539 .resume = omap_dispc_resume,
1540 .setup_plane = omap_dispc_setup_plane,
1541 .setup_mem = omap_dispc_setup_mem,
1542 .set_scale = omap_dispc_set_scale,
1543 .enable_plane = omap_dispc_enable_plane,
1544 .set_color_key = omap_dispc_set_color_key,
1545 .get_color_key = omap_dispc_get_color_key,
1546 .mmap = omap_dispc_mmap_user,
1547};
diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h
deleted file mode 100644
index c15ea77f0604..000000000000
--- a/drivers/video/omap/dispc.h
+++ /dev/null
@@ -1,46 +0,0 @@
1#ifndef _DISPC_H
2#define _DISPC_H
3
4#include <linux/interrupt.h>
5
6#define DISPC_PLANE_GFX 0
7#define DISPC_PLANE_VID1 1
8#define DISPC_PLANE_VID2 2
9
10#define DISPC_RGB_1_BPP 0x00
11#define DISPC_RGB_2_BPP 0x01
12#define DISPC_RGB_4_BPP 0x02
13#define DISPC_RGB_8_BPP 0x03
14#define DISPC_RGB_12_BPP 0x04
15#define DISPC_RGB_16_BPP 0x06
16#define DISPC_RGB_24_BPP 0x08
17#define DISPC_RGB_24_BPP_UNPACK_32 0x09
18#define DISPC_YUV2_422 0x0a
19#define DISPC_UYVY_422 0x0b
20
21#define DISPC_BURST_4x32 0
22#define DISPC_BURST_8x32 1
23#define DISPC_BURST_16x32 2
24
25#define DISPC_LOAD_CLUT_AND_FRAME 0x00
26#define DISPC_LOAD_CLUT_ONLY 0x01
27#define DISPC_LOAD_FRAME_ONLY 0x02
28#define DISPC_LOAD_CLUT_ONCE_FRAME 0x03
29
30#define DISPC_TFT_DATA_LINES_12 0
31#define DISPC_TFT_DATA_LINES_16 1
32#define DISPC_TFT_DATA_LINES_18 2
33#define DISPC_TFT_DATA_LINES_24 3
34
35extern void omap_dispc_set_lcd_size(int width, int height);
36
37extern void omap_dispc_enable_lcd_out(int enable);
38extern void omap_dispc_enable_digit_out(int enable);
39
40extern int omap_dispc_request_irq(unsigned long irq_mask,
41 void (*callback)(void *data), void *data);
42extern void omap_dispc_free_irq(unsigned long irq_mask,
43 void (*callback)(void *data), void *data);
44
45extern const struct lcd_ctrl omap2_int_ctrl;
46#endif
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index 084aa0ac562b..9f1d23c319cb 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -28,7 +28,6 @@
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29 29
30#include <plat/dma.h> 30#include <plat/dma.h>
31#include <plat/hwa742.h>
32#include "omapfb.h" 31#include "omapfb.h"
33 32
34#define HWA742_REV_CODE_REG 0x0 33#define HWA742_REV_CODE_REG 0x0
@@ -942,7 +941,6 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
942 unsigned long sys_clk, pix_clk; 941 unsigned long sys_clk, pix_clk;
943 int extif_mem_div; 942 int extif_mem_div;
944 struct omapfb_platform_data *omapfb_conf; 943 struct omapfb_platform_data *omapfb_conf;
945 struct hwa742_platform_data *ctrl_conf;
946 944
947 BUG_ON(!fbdev->ext_if || !fbdev->int_ctrl); 945 BUG_ON(!fbdev->ext_if || !fbdev->int_ctrl);
948 946
@@ -951,13 +949,6 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
951 hwa742.int_ctrl = fbdev->int_ctrl; 949 hwa742.int_ctrl = fbdev->int_ctrl;
952 950
953 omapfb_conf = fbdev->dev->platform_data; 951 omapfb_conf = fbdev->dev->platform_data;
954 ctrl_conf = omapfb_conf->ctrl_platform_data;
955
956 if (ctrl_conf == NULL) {
957 dev_err(fbdev->dev, "HWA742: missing platform data\n");
958 r = -ENOENT;
959 goto err1;
960 }
961 952
962 hwa742.sys_ck = clk_get(NULL, "hwa_sys_ck"); 953 hwa742.sys_ck = clk_get(NULL, "hwa_sys_ck");
963 954
@@ -995,14 +986,12 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
995 goto err4; 986 goto err4;
996 } 987 }
997 988
998 if (ctrl_conf->te_connected) { 989 if ((r = setup_tearsync(pix_clk, extif_mem_div)) < 0) {
999 if ((r = setup_tearsync(pix_clk, extif_mem_div)) < 0) { 990 dev_err(hwa742.fbdev->dev,
1000 dev_err(hwa742.fbdev->dev, 991 "HWA742: can't setup tearing synchronization\n");
1001 "HWA742: can't setup tearing synchronization\n"); 992 goto err4;
1002 goto err4;
1003 }
1004 hwa742.te_connected = 1;
1005 } 993 }
994 hwa742.te_connected = 1;
1006 995
1007 hwa742.max_transmit_size = hwa742.extif->max_transmit_size; 996 hwa742.max_transmit_size = hwa742.extif->max_transmit_size;
1008 997
diff --git a/drivers/video/omap/omapfb.h b/drivers/video/omap/omapfb.h
index af3c9e571ec3..2921d20e4fba 100644
--- a/drivers/video/omap/omapfb.h
+++ b/drivers/video/omap/omapfb.h
@@ -47,6 +47,27 @@
47 47
48struct omapfb_device; 48struct omapfb_device;
49 49
50#define OMAPFB_PLANE_NUM 1
51
52struct omapfb_mem_region {
53 u32 paddr;
54 void __iomem *vaddr;
55 unsigned long size;
56 u8 type; /* OMAPFB_PLANE_MEM_* */
57 enum omapfb_color_format format;/* OMAPFB_COLOR_* */
58 unsigned format_used:1; /* Must be set when format is set.
59 * Needed b/c of the badly chosen 0
60 * base for OMAPFB_COLOR_* values
61 */
62 unsigned alloc:1; /* allocated by the driver */
63 unsigned map:1; /* kernel mapped by the driver */
64};
65
66struct omapfb_mem_desc {
67 int region_cnt;
68 struct omapfb_mem_region region[OMAPFB_PLANE_NUM];
69};
70
50struct lcd_panel { 71struct lcd_panel {
51 const char *name; 72 const char *name;
52 int config; /* TFT/STN, signal inversion */ 73 int config; /* TFT/STN, signal inversion */
@@ -207,11 +228,7 @@ struct omapfb_device {
207 struct platform_device *dssdev; /* dummy dev for clocks */ 228 struct platform_device *dssdev; /* dummy dev for clocks */
208}; 229};
209 230
210#ifdef CONFIG_ARCH_OMAP1
211extern struct lcd_ctrl omap1_lcd_ctrl; 231extern struct lcd_ctrl omap1_lcd_ctrl;
212#else
213extern struct lcd_ctrl omap2_disp_ctrl;
214#endif
215 232
216extern void omapfb_register_panel(struct lcd_panel *panel); 233extern void omapfb_register_panel(struct lcd_panel *panel);
217extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval); 234extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index b291bfaac80e..f54b463709e9 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -34,7 +34,6 @@
34 34
35#include "omapfb.h" 35#include "omapfb.h"
36#include "lcdc.h" 36#include "lcdc.h"
37#include "dispc.h"
38 37
39#define MODULE_NAME "omapfb" 38#define MODULE_NAME "omapfb"
40 39
@@ -104,29 +103,17 @@ static struct platform_device omapdss_device = {
104 * --------------------------------------------------------------------------- 103 * ---------------------------------------------------------------------------
105 */ 104 */
106extern struct lcd_ctrl hwa742_ctrl; 105extern struct lcd_ctrl hwa742_ctrl;
107extern struct lcd_ctrl blizzard_ctrl;
108 106
109static const struct lcd_ctrl *ctrls[] = { 107static const struct lcd_ctrl *ctrls[] = {
110#ifdef CONFIG_ARCH_OMAP1
111 &omap1_int_ctrl, 108 &omap1_int_ctrl,
112#else
113 &omap2_int_ctrl,
114#endif
115 109
116#ifdef CONFIG_FB_OMAP_LCDC_HWA742 110#ifdef CONFIG_FB_OMAP_LCDC_HWA742
117 &hwa742_ctrl, 111 &hwa742_ctrl,
118#endif 112#endif
119#ifdef CONFIG_FB_OMAP_LCDC_BLIZZARD
120 &blizzard_ctrl,
121#endif
122}; 113};
123 114
124#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL 115#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
125#ifdef CONFIG_ARCH_OMAP1
126extern struct lcd_ctrl_extif omap1_ext_if; 116extern struct lcd_ctrl_extif omap1_ext_if;
127#else
128extern struct lcd_ctrl_extif omap2_ext_if;
129#endif
130#endif 117#endif
131 118
132static void omapfb_rqueue_lock(struct omapfb_device *fbdev) 119static void omapfb_rqueue_lock(struct omapfb_device *fbdev)
@@ -170,11 +157,6 @@ static int ctrl_init(struct omapfb_device *fbdev)
170 fbdev->mem_desc.region[i].size = 157 fbdev->mem_desc.region[i].size =
171 PAGE_ALIGN(def_vram[i]); 158 PAGE_ALIGN(def_vram[i]);
172 fbdev->mem_desc.region_cnt = i; 159 fbdev->mem_desc.region_cnt = i;
173 } else {
174 struct omapfb_platform_data *conf;
175
176 conf = fbdev->dev->platform_data;
177 fbdev->mem_desc = conf->mem_desc;
178 } 160 }
179 161
180 if (!fbdev->mem_desc.region_cnt) { 162 if (!fbdev->mem_desc.region_cnt) {
@@ -880,7 +862,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
880 862
881 if (fbdev->ctrl->setup_mem == NULL) 863 if (fbdev->ctrl->setup_mem == NULL)
882 return -ENODEV; 864 return -ENODEV;
883 if (mi->type > OMAPFB_MEMTYPE_MAX) 865 if (mi->type != OMAPFB_MEMTYPE_SDRAM)
884 return -EINVAL; 866 return -EINVAL;
885 867
886 size = PAGE_ALIGN(mi->size); 868 size = PAGE_ALIGN(mi->size);
@@ -1721,17 +1703,10 @@ static int omapfb_do_probe(struct platform_device *pdev,
1721 1703
1722 mutex_init(&fbdev->rqueue_mutex); 1704 mutex_init(&fbdev->rqueue_mutex);
1723 1705
1724#ifdef CONFIG_ARCH_OMAP1
1725 fbdev->int_ctrl = &omap1_int_ctrl; 1706 fbdev->int_ctrl = &omap1_int_ctrl;
1726#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL 1707#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
1727 fbdev->ext_if = &omap1_ext_if; 1708 fbdev->ext_if = &omap1_ext_if;
1728#endif 1709#endif
1729#else /* OMAP2 */
1730 fbdev->int_ctrl = &omap2_int_ctrl;
1731#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
1732 fbdev->ext_if = &omap2_ext_if;
1733#endif
1734#endif
1735 if (omapfb_find_ctrl(fbdev) < 0) { 1710 if (omapfb_find_ctrl(fbdev) < 0) {
1736 dev_err(fbdev->dev, 1711 dev_err(fbdev->dev,
1737 "LCD controller not found, board not supported\n"); 1712 "LCD controller not found, board not supported\n");
@@ -1766,8 +1741,7 @@ static int omapfb_do_probe(struct platform_device *pdev,
1766 1741
1767#ifdef CONFIG_FB_OMAP_DMA_TUNE 1742#ifdef CONFIG_FB_OMAP_DMA_TUNE
1768 /* Set DMA priority for EMIFF access to highest */ 1743 /* Set DMA priority for EMIFF access to highest */
1769 if (cpu_class_is_omap1()) 1744 omap_set_dma_priority(0, OMAP_DMA_PORT_EMIFF, 15);
1770 omap_set_dma_priority(0, OMAP_DMA_PORT_EMIFF, 15);
1771#endif 1745#endif
1772 1746
1773 r = ctrl_change_mode(fbdev->fb_info[0]); 1747 r = ctrl_change_mode(fbdev->fb_info[0]);
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c
deleted file mode 100644
index 2c1a3402bef0..000000000000
--- a/drivers/video/omap/rfbi.c
+++ /dev/null
@@ -1,598 +0,0 @@
1/*
2 * OMAP2 Remote Frame Buffer Interface support
3 *
4 * Copyright (C) 2005 Nokia Corporation
5 * Author: Juha Yrjölä <juha.yrjola@nokia.com>
6 * Imre Deak <imre.deak@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22#include <linux/module.h>
23#include <linux/delay.h>
24#include <linux/i2c.h>
25#include <linux/err.h>
26#include <linux/interrupt.h>
27#include <linux/clk.h>
28#include <linux/io.h>
29#include <linux/platform_device.h>
30
31#include "omapfb.h"
32#include "dispc.h"
33
34/* To work around an RFBI transfer rate limitation */
35#define OMAP_RFBI_RATE_LIMIT 1
36
37#define RFBI_BASE 0x48050800
38#define RFBI_REVISION 0x0000
39#define RFBI_SYSCONFIG 0x0010
40#define RFBI_SYSSTATUS 0x0014
41#define RFBI_CONTROL 0x0040
42#define RFBI_PIXEL_CNT 0x0044
43#define RFBI_LINE_NUMBER 0x0048
44#define RFBI_CMD 0x004c
45#define RFBI_PARAM 0x0050
46#define RFBI_DATA 0x0054
47#define RFBI_READ 0x0058
48#define RFBI_STATUS 0x005c
49#define RFBI_CONFIG0 0x0060
50#define RFBI_ONOFF_TIME0 0x0064
51#define RFBI_CYCLE_TIME0 0x0068
52#define RFBI_DATA_CYCLE1_0 0x006c
53#define RFBI_DATA_CYCLE2_0 0x0070
54#define RFBI_DATA_CYCLE3_0 0x0074
55#define RFBI_VSYNC_WIDTH 0x0090
56#define RFBI_HSYNC_WIDTH 0x0094
57
58#define DISPC_BASE 0x48050400
59#define DISPC_CONTROL 0x0040
60#define DISPC_IRQ_FRAMEMASK 0x0001
61
62static struct {
63 void __iomem *base;
64 void (*lcdc_callback)(void *data);
65 void *lcdc_callback_data;
66 unsigned long l4_khz;
67 int bits_per_cycle;
68 struct omapfb_device *fbdev;
69 struct clk *dss_ick;
70 struct clk *dss1_fck;
71 unsigned tearsync_pin_cnt;
72 unsigned tearsync_mode;
73} rfbi;
74
75static inline void rfbi_write_reg(int idx, u32 val)
76{
77 __raw_writel(val, rfbi.base + idx);
78}
79
80static inline u32 rfbi_read_reg(int idx)
81{
82 return __raw_readl(rfbi.base + idx);
83}
84
85static int rfbi_get_clocks(void)
86{
87 rfbi.dss_ick = clk_get(&rfbi.fbdev->dssdev->dev, "ick");
88 if (IS_ERR(rfbi.dss_ick)) {
89 dev_err(rfbi.fbdev->dev, "can't get ick\n");
90 return PTR_ERR(rfbi.dss_ick);
91 }
92
93 rfbi.dss1_fck = clk_get(&rfbi.fbdev->dssdev->dev, "fck");
94 if (IS_ERR(rfbi.dss1_fck)) {
95 dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n");
96 clk_put(rfbi.dss_ick);
97 return PTR_ERR(rfbi.dss1_fck);
98 }
99
100 return 0;
101}
102
103static void rfbi_put_clocks(void)
104{
105 clk_put(rfbi.dss1_fck);
106 clk_put(rfbi.dss_ick);
107}
108
109static void rfbi_enable_clocks(int enable)
110{
111 if (enable) {
112 clk_enable(rfbi.dss_ick);
113 clk_enable(rfbi.dss1_fck);
114 } else {
115 clk_disable(rfbi.dss1_fck);
116 clk_disable(rfbi.dss_ick);
117 }
118}
119
120
121#ifdef VERBOSE
122static void rfbi_print_timings(void)
123{
124 u32 l;
125 u32 time;
126
127 l = rfbi_read_reg(RFBI_CONFIG0);
128 time = 1000000000 / rfbi.l4_khz;
129 if (l & (1 << 4))
130 time *= 2;
131
132 dev_dbg(rfbi.fbdev->dev, "Tick time %u ps\n", time);
133 l = rfbi_read_reg(RFBI_ONOFF_TIME0);
134 dev_dbg(rfbi.fbdev->dev,
135 "CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, "
136 "REONTIME %d, REOFFTIME %d\n",
137 l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f,
138 (l >> 20) & 0x0f, (l >> 24) & 0x3f);
139
140 l = rfbi_read_reg(RFBI_CYCLE_TIME0);
141 dev_dbg(rfbi.fbdev->dev,
142 "WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, "
143 "ACCESSTIME %d\n",
144 (l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f,
145 (l >> 22) & 0x3f);
146}
147#else
148static void rfbi_print_timings(void) {}
149#endif
150
151static void rfbi_set_timings(const struct extif_timings *t)
152{
153 u32 l;
154
155 BUG_ON(!t->converted);
156
157 rfbi_enable_clocks(1);
158 rfbi_write_reg(RFBI_ONOFF_TIME0, t->tim[0]);
159 rfbi_write_reg(RFBI_CYCLE_TIME0, t->tim[1]);
160
161 l = rfbi_read_reg(RFBI_CONFIG0);
162 l &= ~(1 << 4);
163 l |= (t->tim[2] ? 1 : 0) << 4;
164 rfbi_write_reg(RFBI_CONFIG0, l);
165
166 rfbi_print_timings();
167 rfbi_enable_clocks(0);
168}
169
170static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
171{
172 *clk_period = 1000000000 / rfbi.l4_khz;
173 *max_clk_div = 2;
174}
175
176static int ps_to_rfbi_ticks(int time, int div)
177{
178 unsigned long tick_ps;
179 int ret;
180
181 /* Calculate in picosecs to yield more exact results */
182 tick_ps = 1000000000 / (rfbi.l4_khz) * div;
183
184 ret = (time + tick_ps - 1) / tick_ps;
185
186 return ret;
187}
188
189#ifdef OMAP_RFBI_RATE_LIMIT
190static unsigned long rfbi_get_max_tx_rate(void)
191{
192 unsigned long l4_rate, dss1_rate;
193 int min_l4_ticks = 0;
194 int i;
195
196 /* According to TI this can't be calculated so make the
197 * adjustments for a couple of known frequencies and warn for
198 * others.
199 */
200 static const struct {
201 unsigned long l4_clk; /* HZ */
202 unsigned long dss1_clk; /* HZ */
203 unsigned long min_l4_ticks;
204 } ftab[] = {
205 { 55, 132, 7, }, /* 7.86 MPix/s */
206 { 110, 110, 12, }, /* 9.16 MPix/s */
207 { 110, 132, 10, }, /* 11 Mpix/s */
208 { 120, 120, 10, }, /* 12 Mpix/s */
209 { 133, 133, 10, }, /* 13.3 Mpix/s */
210 };
211
212 l4_rate = rfbi.l4_khz / 1000;
213 dss1_rate = clk_get_rate(rfbi.dss1_fck) / 1000000;
214
215 for (i = 0; i < ARRAY_SIZE(ftab); i++) {
216 /* Use a window instead of an exact match, to account
217 * for different DPLL multiplier / divider pairs.
218 */
219 if (abs(ftab[i].l4_clk - l4_rate) < 3 &&
220 abs(ftab[i].dss1_clk - dss1_rate) < 3) {
221 min_l4_ticks = ftab[i].min_l4_ticks;
222 break;
223 }
224 }
225 if (i == ARRAY_SIZE(ftab)) {
226 /* Can't be sure, return anyway the maximum not
227 * rate-limited. This might cause a problem only for the
228 * tearing synchronisation.
229 */
230 dev_err(rfbi.fbdev->dev,
231 "can't determine maximum RFBI transfer rate\n");
232 return rfbi.l4_khz * 1000;
233 }
234 return rfbi.l4_khz * 1000 / min_l4_ticks;
235}
236#else
237static int rfbi_get_max_tx_rate(void)
238{
239 return rfbi.l4_khz * 1000;
240}
241#endif
242
243
244static int rfbi_convert_timings(struct extif_timings *t)
245{
246 u32 l;
247 int reon, reoff, weon, weoff, cson, csoff, cs_pulse;
248 int actim, recyc, wecyc;
249 int div = t->clk_div;
250
251 if (div <= 0 || div > 2)
252 return -1;
253
254 /* Make sure that after conversion it still holds that:
255 * weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff,
256 * csoff > cson, csoff >= max(weoff, reoff), actim > reon
257 */
258 weon = ps_to_rfbi_ticks(t->we_on_time, div);
259 weoff = ps_to_rfbi_ticks(t->we_off_time, div);
260 if (weoff <= weon)
261 weoff = weon + 1;
262 if (weon > 0x0f)
263 return -1;
264 if (weoff > 0x3f)
265 return -1;
266
267 reon = ps_to_rfbi_ticks(t->re_on_time, div);
268 reoff = ps_to_rfbi_ticks(t->re_off_time, div);
269 if (reoff <= reon)
270 reoff = reon + 1;
271 if (reon > 0x0f)
272 return -1;
273 if (reoff > 0x3f)
274 return -1;
275
276 cson = ps_to_rfbi_ticks(t->cs_on_time, div);
277 csoff = ps_to_rfbi_ticks(t->cs_off_time, div);
278 if (csoff <= cson)
279 csoff = cson + 1;
280 if (csoff < max(weoff, reoff))
281 csoff = max(weoff, reoff);
282 if (cson > 0x0f)
283 return -1;
284 if (csoff > 0x3f)
285 return -1;
286
287 l = cson;
288 l |= csoff << 4;
289 l |= weon << 10;
290 l |= weoff << 14;
291 l |= reon << 20;
292 l |= reoff << 24;
293
294 t->tim[0] = l;
295
296 actim = ps_to_rfbi_ticks(t->access_time, div);
297 if (actim <= reon)
298 actim = reon + 1;
299 if (actim > 0x3f)
300 return -1;
301
302 wecyc = ps_to_rfbi_ticks(t->we_cycle_time, div);
303 if (wecyc < weoff)
304 wecyc = weoff;
305 if (wecyc > 0x3f)
306 return -1;
307
308 recyc = ps_to_rfbi_ticks(t->re_cycle_time, div);
309 if (recyc < reoff)
310 recyc = reoff;
311 if (recyc > 0x3f)
312 return -1;
313
314 cs_pulse = ps_to_rfbi_ticks(t->cs_pulse_width, div);
315 if (cs_pulse > 0x3f)
316 return -1;
317
318 l = wecyc;
319 l |= recyc << 6;
320 l |= cs_pulse << 12;
321 l |= actim << 22;
322
323 t->tim[1] = l;
324
325 t->tim[2] = div - 1;
326
327 t->converted = 1;
328
329 return 0;
330}
331
332static int rfbi_setup_tearsync(unsigned pin_cnt,
333 unsigned hs_pulse_time, unsigned vs_pulse_time,
334 int hs_pol_inv, int vs_pol_inv, int extif_div)
335{
336 int hs, vs;
337 int min;
338 u32 l;
339
340 if (pin_cnt != 1 && pin_cnt != 2)
341 return -EINVAL;
342
343 hs = ps_to_rfbi_ticks(hs_pulse_time, 1);
344 vs = ps_to_rfbi_ticks(vs_pulse_time, 1);
345 if (hs < 2)
346 return -EDOM;
347 if (pin_cnt == 2)
348 min = 2;
349 else
350 min = 4;
351 if (vs < min)
352 return -EDOM;
353 if (vs == hs)
354 return -EINVAL;
355 rfbi.tearsync_pin_cnt = pin_cnt;
356 dev_dbg(rfbi.fbdev->dev,
357 "setup_tearsync: pins %d hs %d vs %d hs_inv %d vs_inv %d\n",
358 pin_cnt, hs, vs, hs_pol_inv, vs_pol_inv);
359
360 rfbi_enable_clocks(1);
361 rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
362 rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);
363
364 l = rfbi_read_reg(RFBI_CONFIG0);
365 if (hs_pol_inv)
366 l &= ~(1 << 21);
367 else
368 l |= 1 << 21;
369 if (vs_pol_inv)
370 l &= ~(1 << 20);
371 else
372 l |= 1 << 20;
373 rfbi_enable_clocks(0);
374
375 return 0;
376}
377
378static int rfbi_enable_tearsync(int enable, unsigned line)
379{
380 u32 l;
381
382 dev_dbg(rfbi.fbdev->dev, "tearsync %d line %d mode %d\n",
383 enable, line, rfbi.tearsync_mode);
384 if (line > (1 << 11) - 1)
385 return -EINVAL;
386
387 rfbi_enable_clocks(1);
388 l = rfbi_read_reg(RFBI_CONFIG0);
389 l &= ~(0x3 << 2);
390 if (enable) {
391 rfbi.tearsync_mode = rfbi.tearsync_pin_cnt;
392 l |= rfbi.tearsync_mode << 2;
393 } else
394 rfbi.tearsync_mode = 0;
395 rfbi_write_reg(RFBI_CONFIG0, l);
396 rfbi_write_reg(RFBI_LINE_NUMBER, line);
397 rfbi_enable_clocks(0);
398
399 return 0;
400}
401
402static void rfbi_write_command(const void *buf, unsigned int len)
403{
404 rfbi_enable_clocks(1);
405 if (rfbi.bits_per_cycle == 16) {
406 const u16 *w = buf;
407 BUG_ON(len & 1);
408 for (; len; len -= 2)
409 rfbi_write_reg(RFBI_CMD, *w++);
410 } else {
411 const u8 *b = buf;
412 BUG_ON(rfbi.bits_per_cycle != 8);
413 for (; len; len--)
414 rfbi_write_reg(RFBI_CMD, *b++);
415 }
416 rfbi_enable_clocks(0);
417}
418
419static void rfbi_read_data(void *buf, unsigned int len)
420{
421 rfbi_enable_clocks(1);
422 if (rfbi.bits_per_cycle == 16) {
423 u16 *w = buf;
424 BUG_ON(len & ~1);
425 for (; len; len -= 2) {
426 rfbi_write_reg(RFBI_READ, 0);
427 *w++ = rfbi_read_reg(RFBI_READ);
428 }
429 } else {
430 u8 *b = buf;
431 BUG_ON(rfbi.bits_per_cycle != 8);
432 for (; len; len--) {
433 rfbi_write_reg(RFBI_READ, 0);
434 *b++ = rfbi_read_reg(RFBI_READ);
435 }
436 }
437 rfbi_enable_clocks(0);
438}
439
440static void rfbi_write_data(const void *buf, unsigned int len)
441{
442 rfbi_enable_clocks(1);
443 if (rfbi.bits_per_cycle == 16) {
444 const u16 *w = buf;
445 BUG_ON(len & 1);
446 for (; len; len -= 2)
447 rfbi_write_reg(RFBI_PARAM, *w++);
448 } else {
449 const u8 *b = buf;
450 BUG_ON(rfbi.bits_per_cycle != 8);
451 for (; len; len--)
452 rfbi_write_reg(RFBI_PARAM, *b++);
453 }
454 rfbi_enable_clocks(0);
455}
456
457static void rfbi_transfer_area(int width, int height,
458 void (callback)(void * data), void *data)
459{
460 u32 w;
461
462 BUG_ON(callback == NULL);
463
464 rfbi_enable_clocks(1);
465 omap_dispc_set_lcd_size(width, height);
466
467 rfbi.lcdc_callback = callback;
468 rfbi.lcdc_callback_data = data;
469
470 rfbi_write_reg(RFBI_PIXEL_CNT, width * height);
471
472 w = rfbi_read_reg(RFBI_CONTROL);
473 w |= 1; /* enable */
474 if (!rfbi.tearsync_mode)
475 w |= 1 << 4; /* internal trigger, reset by HW */
476 rfbi_write_reg(RFBI_CONTROL, w);
477
478 omap_dispc_enable_lcd_out(1);
479}
480
481static inline void _stop_transfer(void)
482{
483 u32 w;
484
485 w = rfbi_read_reg(RFBI_CONTROL);
486 rfbi_write_reg(RFBI_CONTROL, w & ~(1 << 0));
487 rfbi_enable_clocks(0);
488}
489
490static void rfbi_dma_callback(void *data)
491{
492 _stop_transfer();
493 rfbi.lcdc_callback(rfbi.lcdc_callback_data);
494}
495
496static void rfbi_set_bits_per_cycle(int bpc)
497{
498 u32 l;
499
500 rfbi_enable_clocks(1);
501 l = rfbi_read_reg(RFBI_CONFIG0);
502 l &= ~(0x03 << 0);
503
504 switch (bpc) {
505 case 8:
506 break;
507 case 16:
508 l |= 3;
509 break;
510 default:
511 BUG();
512 }
513 rfbi_write_reg(RFBI_CONFIG0, l);
514 rfbi.bits_per_cycle = bpc;
515 rfbi_enable_clocks(0);
516}
517
518static int rfbi_init(struct omapfb_device *fbdev)
519{
520 u32 l;
521 int r;
522
523 rfbi.fbdev = fbdev;
524 rfbi.base = ioremap(RFBI_BASE, SZ_1K);
525 if (!rfbi.base) {
526 dev_err(fbdev->dev, "can't ioremap RFBI\n");
527 return -ENOMEM;
528 }
529
530 if ((r = rfbi_get_clocks()) < 0)
531 return r;
532 rfbi_enable_clocks(1);
533
534 rfbi.l4_khz = clk_get_rate(rfbi.dss_ick) / 1000;
535
536 /* Reset */
537 rfbi_write_reg(RFBI_SYSCONFIG, 1 << 1);
538 while (!(rfbi_read_reg(RFBI_SYSSTATUS) & (1 << 0)));
539
540 l = rfbi_read_reg(RFBI_SYSCONFIG);
541 /* Enable autoidle and smart-idle */
542 l |= (1 << 0) | (2 << 3);
543 rfbi_write_reg(RFBI_SYSCONFIG, l);
544
545 /* 16-bit interface, ITE trigger mode, 16-bit data */
546 l = (0x03 << 0) | (0x00 << 2) | (0x01 << 5) | (0x02 << 7);
547 l |= (0 << 9) | (1 << 20) | (1 << 21);
548 rfbi_write_reg(RFBI_CONFIG0, l);
549
550 rfbi_write_reg(RFBI_DATA_CYCLE1_0, 0x00000010);
551
552 l = rfbi_read_reg(RFBI_CONTROL);
553 /* Select CS0, clear bypass mode */
554 l = (0x01 << 2);
555 rfbi_write_reg(RFBI_CONTROL, l);
556
557 r = omap_dispc_request_irq(DISPC_IRQ_FRAMEMASK, rfbi_dma_callback,
558 NULL);
559 if (r < 0) {
560 dev_err(fbdev->dev, "can't get DISPC irq\n");
561 rfbi_enable_clocks(0);
562 return r;
563 }
564
565 l = rfbi_read_reg(RFBI_REVISION);
566 pr_info("omapfb: RFBI version %d.%d initialized\n",
567 (l >> 4) & 0x0f, l & 0x0f);
568
569 rfbi_enable_clocks(0);
570
571 return 0;
572}
573
574static void rfbi_cleanup(void)
575{
576 omap_dispc_free_irq(DISPC_IRQ_FRAMEMASK, rfbi_dma_callback, NULL);
577 rfbi_put_clocks();
578 iounmap(rfbi.base);
579}
580
581const struct lcd_ctrl_extif omap2_ext_if = {
582 .init = rfbi_init,
583 .cleanup = rfbi_cleanup,
584 .get_clk_info = rfbi_get_clk_info,
585 .get_max_tx_rate = rfbi_get_max_tx_rate,
586 .set_bits_per_cycle = rfbi_set_bits_per_cycle,
587 .convert_timings = rfbi_convert_timings,
588 .set_timings = rfbi_set_timings,
589 .write_command = rfbi_write_command,
590 .read_data = rfbi_read_data,
591 .write_data = rfbi_write_data,
592 .transfer_area = rfbi_transfer_area,
593 .setup_tearsync = rfbi_setup_tearsync,
594 .enable_tearsync = rfbi_enable_tearsync,
595
596 .max_transmit_size = (u32) ~0,
597};
598
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 28b9a6d61b0f..30fe4dfeb227 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -363,6 +363,29 @@ static struct panel_config generic_dpi_panels[] = {
363 363
364 .name = "ortustech_com43h4m10xtc", 364 .name = "ortustech_com43h4m10xtc",
365 }, 365 },
366
367 /* Innolux AT080TN52 */
368 {
369 {
370 .x_res = 800,
371 .y_res = 600,
372
373 .pixel_clock = 41142,
374
375 .hsw = 20,
376 .hfp = 210,
377 .hbp = 46,
378
379 .vsw = 10,
380 .vfp = 12,
381 .vbp = 23,
382 },
383 .acb = 0x0,
384 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
385 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO,
386
387 .name = "innolux_at080tn52",
388 },
366}; 389};
367 390
368struct panel_drv_data { 391struct panel_drv_data {
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index e6649aa89591..d63e5e5dbbfa 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -47,16 +47,20 @@
47 TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL) 47 TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)
48 48
49static const u16 tpo_td043_def_gamma[12] = { 49static const u16 tpo_td043_def_gamma[12] = {
50 106, 200, 289, 375, 460, 543, 625, 705, 785, 864, 942, 1020 50 105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023
51}; 51};
52 52
53struct tpo_td043_device { 53struct tpo_td043_device {
54 struct spi_device *spi; 54 struct spi_device *spi;
55 struct regulator *vcc_reg; 55 struct regulator *vcc_reg;
56 int nreset_gpio;
56 u16 gamma[12]; 57 u16 gamma[12];
57 u32 mode; 58 u32 mode;
58 u32 hmirror:1; 59 u32 hmirror:1;
59 u32 vmirror:1; 60 u32 vmirror:1;
61 u32 powered_on:1;
62 u32 spi_suspended:1;
63 u32 power_on_resume:1;
60}; 64};
61 65
62static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data) 66static 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 = {
265 .vbp = 34, 269 .vbp = 34,
266}; 270};
267 271
268static int tpo_td043_power_on(struct omap_dss_device *dssdev) 272static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043)
269{ 273{
270 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 274 int nreset_gpio = tpo_td043->nreset_gpio;
271 int nreset_gpio = dssdev->reset_gpio;
272 int r;
273 275
274 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 276 if (tpo_td043->powered_on)
275 return 0; 277 return 0;
276 278
277 r = omapdss_dpi_display_enable(dssdev);
278 if (r)
279 goto err0;
280
281 if (dssdev->platform_enable) {
282 r = dssdev->platform_enable(dssdev);
283 if (r)
284 goto err1;
285 }
286
287 regulator_enable(tpo_td043->vcc_reg); 279 regulator_enable(tpo_td043->vcc_reg);
288 280
289 /* wait for power up */ 281 /* wait for regulator to stabilize */
290 msleep(160); 282 msleep(160);
291 283
292 if (gpio_is_valid(nreset_gpio)) 284 if (gpio_is_valid(nreset_gpio))
@@ -301,19 +293,15 @@ static int tpo_td043_power_on(struct omap_dss_device *dssdev)
301 tpo_td043->vmirror); 293 tpo_td043->vmirror);
302 tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); 294 tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
303 295
296 tpo_td043->powered_on = 1;
304 return 0; 297 return 0;
305err1:
306 omapdss_dpi_display_disable(dssdev);
307err0:
308 return r;
309} 298}
310 299
311static void tpo_td043_power_off(struct omap_dss_device *dssdev) 300static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043)
312{ 301{
313 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 302 int nreset_gpio = tpo_td043->nreset_gpio;
314 int nreset_gpio = dssdev->reset_gpio;
315 303
316 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 304 if (!tpo_td043->powered_on)
317 return; 305 return;
318 306
319 tpo_td043_write(tpo_td043->spi, 3, 307 tpo_td043_write(tpo_td043->spi, 3,
@@ -329,54 +317,94 @@ static void tpo_td043_power_off(struct omap_dss_device *dssdev)
329 317
330 regulator_disable(tpo_td043->vcc_reg); 318 regulator_disable(tpo_td043->vcc_reg);
331 319
320 tpo_td043->powered_on = 0;
321}
322
323static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
324{
325 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
326 int r;
327
328 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
329 return 0;
330
331 r = omapdss_dpi_display_enable(dssdev);
332 if (r)
333 goto err0;
334
335 if (dssdev->platform_enable) {
336 r = dssdev->platform_enable(dssdev);
337 if (r)
338 goto err1;
339 }
340
341 /*
342 * If we are resuming from system suspend, SPI clocks might not be
343 * enabled yet, so we'll program the LCD from SPI PM resume callback.
344 */
345 if (!tpo_td043->spi_suspended) {
346 r = tpo_td043_power_on(tpo_td043);
347 if (r)
348 goto err1;
349 }
350
351 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
352
353 return 0;
354err1:
355 omapdss_dpi_display_disable(dssdev);
356err0:
357 return r;
358}
359
360static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
361{
362 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
363
364 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
365 return;
366
332 if (dssdev->platform_disable) 367 if (dssdev->platform_disable)
333 dssdev->platform_disable(dssdev); 368 dssdev->platform_disable(dssdev);
334 369
335 omapdss_dpi_display_disable(dssdev); 370 omapdss_dpi_display_disable(dssdev);
371
372 if (!tpo_td043->spi_suspended)
373 tpo_td043_power_off(tpo_td043);
336} 374}
337 375
338static int tpo_td043_enable(struct omap_dss_device *dssdev) 376static int tpo_td043_enable(struct omap_dss_device *dssdev)
339{ 377{
340 int ret;
341
342 dev_dbg(&dssdev->dev, "enable\n"); 378 dev_dbg(&dssdev->dev, "enable\n");
343 379
344 ret = tpo_td043_power_on(dssdev); 380 return tpo_td043_enable_dss(dssdev);
345 if (ret)
346 return ret;
347
348 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
349
350 return 0;
351} 381}
352 382
353static void tpo_td043_disable(struct omap_dss_device *dssdev) 383static void tpo_td043_disable(struct omap_dss_device *dssdev)
354{ 384{
355 dev_dbg(&dssdev->dev, "disable\n"); 385 dev_dbg(&dssdev->dev, "disable\n");
356 386
357 tpo_td043_power_off(dssdev); 387 tpo_td043_disable_dss(dssdev);
358 388
359 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 389 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
360} 390}
361 391
362static int tpo_td043_suspend(struct omap_dss_device *dssdev) 392static int tpo_td043_suspend(struct omap_dss_device *dssdev)
363{ 393{
364 tpo_td043_power_off(dssdev); 394 dev_dbg(&dssdev->dev, "suspend\n");
395
396 tpo_td043_disable_dss(dssdev);
397
365 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; 398 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
399
366 return 0; 400 return 0;
367} 401}
368 402
369static int tpo_td043_resume(struct omap_dss_device *dssdev) 403static int tpo_td043_resume(struct omap_dss_device *dssdev)
370{ 404{
371 int r = 0; 405 dev_dbg(&dssdev->dev, "resume\n");
372
373 r = tpo_td043_power_on(dssdev);
374 if (r)
375 return r;
376
377 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
378 406
379 return 0; 407 return tpo_td043_enable_dss(dssdev);
380} 408}
381 409
382static int tpo_td043_probe(struct omap_dss_device *dssdev) 410static int tpo_td043_probe(struct omap_dss_device *dssdev)
@@ -491,6 +519,7 @@ static int tpo_td043_spi_probe(struct spi_device *spi)
491 return -ENOMEM; 519 return -ENOMEM;
492 520
493 tpo_td043->spi = spi; 521 tpo_td043->spi = spi;
522 tpo_td043->nreset_gpio = dssdev->reset_gpio;
494 dev_set_drvdata(&spi->dev, tpo_td043); 523 dev_set_drvdata(&spi->dev, tpo_td043);
495 dev_set_drvdata(&dssdev->dev, tpo_td043); 524 dev_set_drvdata(&dssdev->dev, tpo_td043);
496 525
@@ -509,10 +538,46 @@ static int __devexit tpo_td043_spi_remove(struct spi_device *spi)
509 return 0; 538 return 0;
510} 539}
511 540
541#ifdef CONFIG_PM_SLEEP
542static int tpo_td043_spi_suspend(struct device *dev)
543{
544 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
545
546 dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", tpo_td043);
547
548 tpo_td043->power_on_resume = tpo_td043->powered_on;
549 tpo_td043_power_off(tpo_td043);
550 tpo_td043->spi_suspended = 1;
551
552 return 0;
553}
554
555static int tpo_td043_spi_resume(struct device *dev)
556{
557 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
558 int ret;
559
560 dev_dbg(dev, "tpo_td043_spi_resume\n");
561
562 if (tpo_td043->power_on_resume) {
563 ret = tpo_td043_power_on(tpo_td043);
564 if (ret)
565 return ret;
566 }
567 tpo_td043->spi_suspended = 0;
568
569 return 0;
570}
571#endif
572
573static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm,
574 tpo_td043_spi_suspend, tpo_td043_spi_resume);
575
512static struct spi_driver tpo_td043_spi_driver = { 576static struct spi_driver tpo_td043_spi_driver = {
513 .driver = { 577 .driver = {
514 .name = "tpo_td043mtea1_panel_spi", 578 .name = "tpo_td043mtea1_panel_spi",
515 .owner = THIS_MODULE, 579 .owner = THIS_MODULE,
580 .pm = &tpo_td043_spi_pm,
516 }, 581 },
517 .probe = tpo_td043_spi_probe, 582 .probe = tpo_td043_spi_probe,
518 .remove = __devexit_p(tpo_td043_spi_remove), 583 .remove = __devexit_p(tpo_td043_spi_remove),
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 87b3e25294cf..b0264a164652 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -105,6 +105,9 @@ static struct {
105 struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; 105 struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
106 struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; 106 struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
107 107
108 bool fifo_merge_dirty;
109 bool fifo_merge;
110
108 bool irq_enabled; 111 bool irq_enabled;
109} dss_data; 112} dss_data;
110 113
@@ -585,11 +588,40 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
585 } 588 }
586} 589}
587 590
591static void dss_write_regs_common(void)
592{
593 const int num_mgrs = omap_dss_get_num_overlay_managers();
594 int i;
595
596 if (!dss_data.fifo_merge_dirty)
597 return;
598
599 for (i = 0; i < num_mgrs; ++i) {
600 struct omap_overlay_manager *mgr;
601 struct mgr_priv_data *mp;
602
603 mgr = omap_dss_get_overlay_manager(i);
604 mp = get_mgr_priv(mgr);
605
606 if (mp->enabled) {
607 if (dss_data.fifo_merge_dirty) {
608 dispc_enable_fifomerge(dss_data.fifo_merge);
609 dss_data.fifo_merge_dirty = false;
610 }
611
612 if (mp->updating)
613 mp->shadow_info_dirty = true;
614 }
615 }
616}
617
588static void dss_write_regs(void) 618static void dss_write_regs(void)
589{ 619{
590 const int num_mgrs = omap_dss_get_num_overlay_managers(); 620 const int num_mgrs = omap_dss_get_num_overlay_managers();
591 int i; 621 int i;
592 622
623 dss_write_regs_common();
624
593 for (i = 0; i < num_mgrs; ++i) { 625 for (i = 0; i < num_mgrs; ++i) {
594 struct omap_overlay_manager *mgr; 626 struct omap_overlay_manager *mgr;
595 struct mgr_priv_data *mp; 627 struct mgr_priv_data *mp;
@@ -659,6 +691,8 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
659 691
660 dss_mgr_write_regs(mgr); 692 dss_mgr_write_regs(mgr);
661 693
694 dss_write_regs_common();
695
662 mp->updating = true; 696 mp->updating = true;
663 697
664 if (!dss_data.irq_enabled && need_isr()) 698 if (!dss_data.irq_enabled && need_isr())
@@ -859,11 +893,20 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl,
859 op->extra_info_dirty = true; 893 op->extra_info_dirty = true;
860} 894}
861 895
862static void dss_ovl_setup_fifo(struct omap_overlay *ovl) 896static void dss_apply_fifo_merge(bool use_fifo_merge)
897{
898 if (dss_data.fifo_merge == use_fifo_merge)
899 return;
900
901 dss_data.fifo_merge = use_fifo_merge;
902 dss_data.fifo_merge_dirty = true;
903}
904
905static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
906 bool use_fifo_merge)
863{ 907{
864 struct ovl_priv_data *op = get_ovl_priv(ovl); 908 struct ovl_priv_data *op = get_ovl_priv(ovl);
865 struct omap_dss_device *dssdev; 909 struct omap_dss_device *dssdev;
866 u32 size, burst_size;
867 u32 fifo_low, fifo_high; 910 u32 fifo_low, fifo_high;
868 911
869 if (!op->enabled && !op->enabling) 912 if (!op->enabled && !op->enabling)
@@ -871,33 +914,14 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
871 914
872 dssdev = ovl->manager->device; 915 dssdev = ovl->manager->device;
873 916
874 size = dispc_ovl_get_fifo_size(ovl->id); 917 dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high,
875 918 use_fifo_merge);
876 burst_size = dispc_ovl_get_burst_size(ovl->id);
877
878 switch (dssdev->type) {
879 case OMAP_DISPLAY_TYPE_DPI:
880 case OMAP_DISPLAY_TYPE_DBI:
881 case OMAP_DISPLAY_TYPE_SDI:
882 case OMAP_DISPLAY_TYPE_VENC:
883 case OMAP_DISPLAY_TYPE_HDMI:
884 default_get_overlay_fifo_thresholds(ovl->id, size,
885 burst_size, &fifo_low, &fifo_high);
886 break;
887#ifdef CONFIG_OMAP2_DSS_DSI
888 case OMAP_DISPLAY_TYPE_DSI:
889 dsi_get_overlay_fifo_thresholds(ovl->id, size,
890 burst_size, &fifo_low, &fifo_high);
891 break;
892#endif
893 default:
894 BUG();
895 }
896 919
897 dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); 920 dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
898} 921}
899 922
900static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) 923static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr,
924 bool use_fifo_merge)
901{ 925{
902 struct omap_overlay *ovl; 926 struct omap_overlay *ovl;
903 struct mgr_priv_data *mp; 927 struct mgr_priv_data *mp;
@@ -908,10 +932,10 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
908 return; 932 return;
909 933
910 list_for_each_entry(ovl, &mgr->overlays, list) 934 list_for_each_entry(ovl, &mgr->overlays, list)
911 dss_ovl_setup_fifo(ovl); 935 dss_ovl_setup_fifo(ovl, use_fifo_merge);
912} 936}
913 937
914static void dss_setup_fifos(void) 938static void dss_setup_fifos(bool use_fifo_merge)
915{ 939{
916 const int num_mgrs = omap_dss_get_num_overlay_managers(); 940 const int num_mgrs = omap_dss_get_num_overlay_managers();
917 struct omap_overlay_manager *mgr; 941 struct omap_overlay_manager *mgr;
@@ -919,15 +943,91 @@ static void dss_setup_fifos(void)
919 943
920 for (i = 0; i < num_mgrs; ++i) { 944 for (i = 0; i < num_mgrs; ++i) {
921 mgr = omap_dss_get_overlay_manager(i); 945 mgr = omap_dss_get_overlay_manager(i);
922 dss_mgr_setup_fifos(mgr); 946 dss_mgr_setup_fifos(mgr, use_fifo_merge);
923 } 947 }
924} 948}
925 949
950static int get_num_used_managers(void)
951{
952 const int num_mgrs = omap_dss_get_num_overlay_managers();
953 struct omap_overlay_manager *mgr;
954 struct mgr_priv_data *mp;
955 int i;
956 int enabled_mgrs;
957
958 enabled_mgrs = 0;
959
960 for (i = 0; i < num_mgrs; ++i) {
961 mgr = omap_dss_get_overlay_manager(i);
962 mp = get_mgr_priv(mgr);
963
964 if (!mp->enabled)
965 continue;
966
967 enabled_mgrs++;
968 }
969
970 return enabled_mgrs;
971}
972
973static int get_num_used_overlays(void)
974{
975 const int num_ovls = omap_dss_get_num_overlays();
976 struct omap_overlay *ovl;
977 struct ovl_priv_data *op;
978 struct mgr_priv_data *mp;
979 int i;
980 int enabled_ovls;
981
982 enabled_ovls = 0;
983
984 for (i = 0; i < num_ovls; ++i) {
985 ovl = omap_dss_get_overlay(i);
986 op = get_ovl_priv(ovl);
987
988 if (!op->enabled && !op->enabling)
989 continue;
990
991 mp = get_mgr_priv(ovl->manager);
992
993 if (!mp->enabled)
994 continue;
995
996 enabled_ovls++;
997 }
998
999 return enabled_ovls;
1000}
1001
1002static bool get_use_fifo_merge(void)
1003{
1004 int enabled_mgrs = get_num_used_managers();
1005 int enabled_ovls = get_num_used_overlays();
1006
1007 if (!dss_has_feature(FEAT_FIFO_MERGE))
1008 return false;
1009
1010 /*
1011 * In theory the only requirement for fifomerge is enabled_ovls <= 1.
1012 * However, if we have two managers enabled and set/unset the fifomerge,
1013 * we need to set the GO bits in particular sequence for the managers,
1014 * and wait in between.
1015 *
1016 * This is rather difficult as new apply calls can happen at any time,
1017 * so we simplify the problem by requiring also that enabled_mgrs <= 1.
1018 * In practice this shouldn't matter, because when only one overlay is
1019 * enabled, most likely only one output is enabled.
1020 */
1021
1022 return enabled_mgrs <= 1 && enabled_ovls <= 1;
1023}
1024
926int dss_mgr_enable(struct omap_overlay_manager *mgr) 1025int dss_mgr_enable(struct omap_overlay_manager *mgr)
927{ 1026{
928 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1027 struct mgr_priv_data *mp = get_mgr_priv(mgr);
929 unsigned long flags; 1028 unsigned long flags;
930 int r; 1029 int r;
1030 bool fifo_merge;
931 1031
932 mutex_lock(&apply_lock); 1032 mutex_lock(&apply_lock);
933 1033
@@ -945,11 +1045,23 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
945 goto err; 1045 goto err;
946 } 1046 }
947 1047
948 dss_setup_fifos(); 1048 /* step 1: setup fifos/fifomerge before enabling the manager */
1049
1050 fifo_merge = get_use_fifo_merge();
1051 dss_setup_fifos(fifo_merge);
1052 dss_apply_fifo_merge(fifo_merge);
949 1053
950 dss_write_regs(); 1054 dss_write_regs();
951 dss_set_go_bits(); 1055 dss_set_go_bits();
952 1056
1057 spin_unlock_irqrestore(&data_lock, flags);
1058
1059 /* wait until fifo config is in */
1060 wait_pending_extra_info_updates();
1061
1062 /* step 2: enable the manager */
1063 spin_lock_irqsave(&data_lock, flags);
1064
953 if (!mgr_manual_update(mgr)) 1065 if (!mgr_manual_update(mgr))
954 mp->updating = true; 1066 mp->updating = true;
955 1067
@@ -974,6 +1086,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
974{ 1086{
975 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1087 struct mgr_priv_data *mp = get_mgr_priv(mgr);
976 unsigned long flags; 1088 unsigned long flags;
1089 bool fifo_merge;
977 1090
978 mutex_lock(&apply_lock); 1091 mutex_lock(&apply_lock);
979 1092
@@ -988,8 +1101,16 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
988 mp->updating = false; 1101 mp->updating = false;
989 mp->enabled = false; 1102 mp->enabled = false;
990 1103
1104 fifo_merge = get_use_fifo_merge();
1105 dss_setup_fifos(fifo_merge);
1106 dss_apply_fifo_merge(fifo_merge);
1107
1108 dss_write_regs();
1109 dss_set_go_bits();
1110
991 spin_unlock_irqrestore(&data_lock, flags); 1111 spin_unlock_irqrestore(&data_lock, flags);
992 1112
1113 wait_pending_extra_info_updates();
993out: 1114out:
994 mutex_unlock(&apply_lock); 1115 mutex_unlock(&apply_lock);
995} 1116}
@@ -1241,6 +1362,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1241{ 1362{
1242 struct ovl_priv_data *op = get_ovl_priv(ovl); 1363 struct ovl_priv_data *op = get_ovl_priv(ovl);
1243 unsigned long flags; 1364 unsigned long flags;
1365 bool fifo_merge;
1244 int r; 1366 int r;
1245 1367
1246 mutex_lock(&apply_lock); 1368 mutex_lock(&apply_lock);
@@ -1266,7 +1388,22 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1266 goto err2; 1388 goto err2;
1267 } 1389 }
1268 1390
1269 dss_setup_fifos(); 1391 /* step 1: configure fifos/fifomerge for currently enabled ovls */
1392
1393 fifo_merge = get_use_fifo_merge();
1394 dss_setup_fifos(fifo_merge);
1395 dss_apply_fifo_merge(fifo_merge);
1396
1397 dss_write_regs();
1398 dss_set_go_bits();
1399
1400 spin_unlock_irqrestore(&data_lock, flags);
1401
1402 /* wait for fifo configs to go in */
1403 wait_pending_extra_info_updates();
1404
1405 /* step 2: enable the overlay */
1406 spin_lock_irqsave(&data_lock, flags);
1270 1407
1271 op->enabling = false; 1408 op->enabling = false;
1272 dss_apply_ovl_enable(ovl, true); 1409 dss_apply_ovl_enable(ovl, true);
@@ -1294,6 +1431,7 @@ int dss_ovl_disable(struct omap_overlay *ovl)
1294{ 1431{
1295 struct ovl_priv_data *op = get_ovl_priv(ovl); 1432 struct ovl_priv_data *op = get_ovl_priv(ovl);
1296 unsigned long flags; 1433 unsigned long flags;
1434 bool fifo_merge;
1297 int r; 1435 int r;
1298 1436
1299 mutex_lock(&apply_lock); 1437 mutex_lock(&apply_lock);
@@ -1308,9 +1446,11 @@ int dss_ovl_disable(struct omap_overlay *ovl)
1308 goto err; 1446 goto err;
1309 } 1447 }
1310 1448
1449 /* step 1: disable the overlay */
1311 spin_lock_irqsave(&data_lock, flags); 1450 spin_lock_irqsave(&data_lock, flags);
1312 1451
1313 dss_apply_ovl_enable(ovl, false); 1452 dss_apply_ovl_enable(ovl, false);
1453
1314 dss_write_regs(); 1454 dss_write_regs();
1315 dss_set_go_bits(); 1455 dss_set_go_bits();
1316 1456
@@ -1319,6 +1459,21 @@ int dss_ovl_disable(struct omap_overlay *ovl)
1319 /* wait for the overlay to be disabled */ 1459 /* wait for the overlay to be disabled */
1320 wait_pending_extra_info_updates(); 1460 wait_pending_extra_info_updates();
1321 1461
1462 /* step 2: configure fifos/fifomerge */
1463 spin_lock_irqsave(&data_lock, flags);
1464
1465 fifo_merge = get_use_fifo_merge();
1466 dss_setup_fifos(fifo_merge);
1467 dss_apply_fifo_merge(fifo_merge);
1468
1469 dss_write_regs();
1470 dss_set_go_bits();
1471
1472 spin_unlock_irqrestore(&data_lock, flags);
1473
1474 /* wait for fifo config to go in */
1475 wait_pending_extra_info_updates();
1476
1322 mutex_unlock(&apply_lock); 1477 mutex_unlock(&apply_lock);
1323 1478
1324 return 0; 1479 return 0;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index e1626a1d5c45..700bb563cfcd 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -37,7 +37,6 @@
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/pm_runtime.h> 38#include <linux/pm_runtime.h>
39 39
40#include <plat/sram.h>
41#include <plat/clock.h> 40#include <plat/clock.h>
42 41
43#include <video/omapdss.h> 42#include <video/omapdss.h>
@@ -909,7 +908,7 @@ static void dispc_configure_burst_sizes(void)
909 dispc_ovl_set_burst_size(i, burst_size); 908 dispc_ovl_set_burst_size(i, burst_size);
910} 909}
911 910
912u32 dispc_ovl_get_burst_size(enum omap_plane plane) 911static u32 dispc_ovl_get_burst_size(enum omap_plane plane)
913{ 912{
914 unsigned unit = dss_feat_get_burst_size_unit(); 913 unsigned unit = dss_feat_get_burst_size_unit();
915 /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ 914 /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */
@@ -1018,7 +1017,7 @@ static void dispc_read_plane_fifo_sizes(void)
1018 } 1017 }
1019} 1018}
1020 1019
1021u32 dispc_ovl_get_fifo_size(enum omap_plane plane) 1020static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
1022{ 1021{
1023 return dispc.fifo_size[plane]; 1022 return dispc.fifo_size[plane];
1024} 1023}
@@ -1039,13 +1038,13 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
1039 dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end); 1038 dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end);
1040 dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end); 1039 dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end);
1041 1040
1042 DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n", 1041 DSSDBG("fifo(%d) threshold (bytes), old %u/%u, new %u/%u\n",
1043 plane, 1042 plane,
1044 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), 1043 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
1045 lo_start, lo_end), 1044 lo_start, lo_end) * unit,
1046 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), 1045 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
1047 hi_start, hi_end), 1046 hi_start, hi_end) * unit,
1048 low, high); 1047 low * unit, high * unit);
1049 1048
1050 dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane), 1049 dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane),
1051 FLD_VAL(high, hi_start, hi_end) | 1050 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)
1054 1053
1055void dispc_enable_fifomerge(bool enable) 1054void dispc_enable_fifomerge(bool enable)
1056{ 1055{
1056 if (!dss_has_feature(FEAT_FIFO_MERGE)) {
1057 WARN_ON(enable);
1058 return;
1059 }
1060
1057 DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); 1061 DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled");
1058 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); 1062 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14);
1059} 1063}
1060 1064
1065void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
1066 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge)
1067{
1068 /*
1069 * All sizes are in bytes. Both the buffer and burst are made of
1070 * buffer_units, and the fifo thresholds must be buffer_unit aligned.
1071 */
1072
1073 unsigned buf_unit = dss_feat_get_buffer_size_unit();
1074 unsigned ovl_fifo_size, total_fifo_size, burst_size;
1075 int i;
1076
1077 burst_size = dispc_ovl_get_burst_size(plane);
1078 ovl_fifo_size = dispc_ovl_get_fifo_size(plane);
1079
1080 if (use_fifomerge) {
1081 total_fifo_size = 0;
1082 for (i = 0; i < omap_dss_get_num_overlays(); ++i)
1083 total_fifo_size += dispc_ovl_get_fifo_size(i);
1084 } else {
1085 total_fifo_size = ovl_fifo_size;
1086 }
1087
1088 /*
1089 * We use the same low threshold for both fifomerge and non-fifomerge
1090 * cases, but for fifomerge we calculate the high threshold using the
1091 * combined fifo size
1092 */
1093
1094 if (dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) {
1095 *fifo_low = ovl_fifo_size - burst_size * 2;
1096 *fifo_high = total_fifo_size - burst_size;
1097 } else {
1098 *fifo_low = ovl_fifo_size - burst_size;
1099 *fifo_high = total_fifo_size - buf_unit;
1100 }
1101}
1102
1061static void dispc_ovl_set_fir(enum omap_plane plane, 1103static void dispc_ovl_set_fir(enum omap_plane plane,
1062 int hinc, int vinc, 1104 int hinc, int vinc,
1063 enum omap_color_component color_comp) 1105 enum omap_color_component color_comp)
@@ -1651,6 +1693,7 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
1651 u16 height, u16 out_width, u16 out_height) 1693 u16 height, u16 out_width, u16 out_height)
1652{ 1694{
1653 unsigned int hf, vf; 1695 unsigned int hf, vf;
1696 unsigned long pclk = dispc_mgr_pclk_rate(channel);
1654 1697
1655 /* 1698 /*
1656 * FIXME how to determine the 'A' factor 1699 * FIXME how to determine the 'A' factor
@@ -1673,13 +1716,16 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
1673 1716
1674 if (cpu_is_omap24xx()) { 1717 if (cpu_is_omap24xx()) {
1675 if (vf > 1 && hf > 1) 1718 if (vf > 1 && hf > 1)
1676 return dispc_mgr_pclk_rate(channel) * 4; 1719 return pclk * 4;
1677 else 1720 else
1678 return dispc_mgr_pclk_rate(channel) * 2; 1721 return pclk * 2;
1679 } else if (cpu_is_omap34xx()) { 1722 } else if (cpu_is_omap34xx()) {
1680 return dispc_mgr_pclk_rate(channel) * vf * hf; 1723 return pclk * vf * hf;
1681 } else { 1724 } else {
1682 return dispc_mgr_pclk_rate(channel) * hf; 1725 if (hf > 1)
1726 return DIV_ROUND_UP(pclk, out_width) * width;
1727 else
1728 return pclk;
1683 } 1729 }
1684} 1730}
1685 1731
@@ -3298,15 +3344,6 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3298 3344
3299 dispc.pdev = pdev; 3345 dispc.pdev = pdev;
3300 3346
3301 clk = clk_get(&pdev->dev, "fck");
3302 if (IS_ERR(clk)) {
3303 DSSERR("can't get fck\n");
3304 r = PTR_ERR(clk);
3305 goto err_get_clk;
3306 }
3307
3308 dispc.dss_clk = clk;
3309
3310 spin_lock_init(&dispc.irq_lock); 3347 spin_lock_init(&dispc.irq_lock);
3311 3348
3312#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 3349#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
@@ -3319,29 +3356,38 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3319 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0); 3356 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
3320 if (!dispc_mem) { 3357 if (!dispc_mem) {
3321 DSSERR("can't get IORESOURCE_MEM DISPC\n"); 3358 DSSERR("can't get IORESOURCE_MEM DISPC\n");
3322 r = -EINVAL; 3359 return -EINVAL;
3323 goto err_ioremap;
3324 } 3360 }
3325 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem)); 3361
3362 dispc.base = devm_ioremap(&pdev->dev, dispc_mem->start,
3363 resource_size(dispc_mem));
3326 if (!dispc.base) { 3364 if (!dispc.base) {
3327 DSSERR("can't ioremap DISPC\n"); 3365 DSSERR("can't ioremap DISPC\n");
3328 r = -ENOMEM; 3366 return -ENOMEM;
3329 goto err_ioremap;
3330 } 3367 }
3368
3331 dispc.irq = platform_get_irq(dispc.pdev, 0); 3369 dispc.irq = platform_get_irq(dispc.pdev, 0);
3332 if (dispc.irq < 0) { 3370 if (dispc.irq < 0) {
3333 DSSERR("platform_get_irq failed\n"); 3371 DSSERR("platform_get_irq failed\n");
3334 r = -ENODEV; 3372 return -ENODEV;
3335 goto err_irq;
3336 } 3373 }
3337 3374
3338 r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED, 3375 r = devm_request_irq(&pdev->dev, dispc.irq, omap_dispc_irq_handler,
3339 "OMAP DISPC", dispc.pdev); 3376 IRQF_SHARED, "OMAP DISPC", dispc.pdev);
3340 if (r < 0) { 3377 if (r < 0) {
3341 DSSERR("request_irq failed\n"); 3378 DSSERR("request_irq failed\n");
3342 goto err_irq; 3379 return r;
3380 }
3381
3382 clk = clk_get(&pdev->dev, "fck");
3383 if (IS_ERR(clk)) {
3384 DSSERR("can't get fck\n");
3385 r = PTR_ERR(clk);
3386 return r;
3343 } 3387 }
3344 3388
3389 dispc.dss_clk = clk;
3390
3345 pm_runtime_enable(&pdev->dev); 3391 pm_runtime_enable(&pdev->dev);
3346 3392
3347 r = dispc_runtime_get(); 3393 r = dispc_runtime_get();
@@ -3362,12 +3408,7 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3362 3408
3363err_runtime_get: 3409err_runtime_get:
3364 pm_runtime_disable(&pdev->dev); 3410 pm_runtime_disable(&pdev->dev);
3365 free_irq(dispc.irq, dispc.pdev);
3366err_irq:
3367 iounmap(dispc.base);
3368err_ioremap:
3369 clk_put(dispc.dss_clk); 3411 clk_put(dispc.dss_clk);
3370err_get_clk:
3371 return r; 3412 return r;
3372} 3413}
3373 3414
@@ -3377,8 +3418,6 @@ static int omap_dispchw_remove(struct platform_device *pdev)
3377 3418
3378 clk_put(dispc.dss_clk); 3419 clk_put(dispc.dss_clk);
3379 3420
3380 free_irq(dispc.irq, dispc.pdev);
3381 iounmap(dispc.base);
3382 return 0; 3421 return 0;
3383} 3422}
3384 3423
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index be331dc5a61b..4424c198dbcd 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -279,16 +279,6 @@ void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
279} 279}
280EXPORT_SYMBOL(omapdss_default_get_resolution); 280EXPORT_SYMBOL(omapdss_default_get_resolution);
281 281
282void default_get_overlay_fifo_thresholds(enum omap_plane plane,
283 u32 fifo_size, u32 burst_size,
284 u32 *fifo_low, u32 *fifo_high)
285{
286 unsigned buf_unit = dss_feat_get_buffer_size_unit();
287
288 *fifo_high = fifo_size - buf_unit;
289 *fifo_low = fifo_size - burst_size;
290}
291
292int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) 282int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
293{ 283{
294 switch (dssdev->type) { 284 switch (dssdev->type) {
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 52f36ec1c8bb..662d14f8c2c3 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4524,14 +4524,6 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
4524} 4524}
4525EXPORT_SYMBOL(omapdss_dsi_enable_te); 4525EXPORT_SYMBOL(omapdss_dsi_enable_te);
4526 4526
4527void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
4528 u32 fifo_size, u32 burst_size,
4529 u32 *fifo_low, u32 *fifo_high)
4530{
4531 *fifo_high = fifo_size - burst_size;
4532 *fifo_low = fifo_size - burst_size * 2;
4533}
4534
4535int dsi_init_display(struct omap_dss_device *dssdev) 4527int dsi_init_display(struct omap_dss_device *dssdev)
4536{ 4528{
4537 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4529 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4695,11 +4687,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
4695 struct resource *dsi_mem; 4687 struct resource *dsi_mem;
4696 struct dsi_data *dsi; 4688 struct dsi_data *dsi;
4697 4689
4698 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); 4690 dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL);
4699 if (!dsi) { 4691 if (!dsi)
4700 r = -ENOMEM; 4692 return -ENOMEM;
4701 goto err_alloc;
4702 }
4703 4693
4704 dsi->pdev = dsidev; 4694 dsi->pdev = dsidev;
4705 dsi_pdev_map[dsi_module] = dsidev; 4695 dsi_pdev_map[dsi_module] = dsidev;
@@ -4722,12 +4712,6 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
4722 mutex_init(&dsi->lock); 4712 mutex_init(&dsi->lock);
4723 sema_init(&dsi->bus_lock, 1); 4713 sema_init(&dsi->bus_lock, 1);
4724 4714
4725 r = dsi_get_clocks(dsidev);
4726 if (r)
4727 goto err_get_clk;
4728
4729 pm_runtime_enable(&dsidev->dev);
4730
4731 INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work, 4715 INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work,
4732 dsi_framedone_timeout_work_callback); 4716 dsi_framedone_timeout_work_callback);
4733 4717
@@ -4739,27 +4723,27 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
4739 dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0); 4723 dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0);
4740 if (!dsi_mem) { 4724 if (!dsi_mem) {
4741 DSSERR("can't get IORESOURCE_MEM DSI\n"); 4725 DSSERR("can't get IORESOURCE_MEM DSI\n");
4742 r = -EINVAL; 4726 return -EINVAL;
4743 goto err_ioremap;
4744 } 4727 }
4745 dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem)); 4728
4729 dsi->base = devm_ioremap(&dsidev->dev, dsi_mem->start,
4730 resource_size(dsi_mem));
4746 if (!dsi->base) { 4731 if (!dsi->base) {
4747 DSSERR("can't ioremap DSI\n"); 4732 DSSERR("can't ioremap DSI\n");
4748 r = -ENOMEM; 4733 return -ENOMEM;
4749 goto err_ioremap;
4750 } 4734 }
4735
4751 dsi->irq = platform_get_irq(dsi->pdev, 0); 4736 dsi->irq = platform_get_irq(dsi->pdev, 0);
4752 if (dsi->irq < 0) { 4737 if (dsi->irq < 0) {
4753 DSSERR("platform_get_irq failed\n"); 4738 DSSERR("platform_get_irq failed\n");
4754 r = -ENODEV; 4739 return -ENODEV;
4755 goto err_get_irq;
4756 } 4740 }
4757 4741
4758 r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED, 4742 r = devm_request_irq(&dsidev->dev, dsi->irq, omap_dsi_irq_handler,
4759 dev_name(&dsidev->dev), dsi->pdev); 4743 IRQF_SHARED, dev_name(&dsidev->dev), dsi->pdev);
4760 if (r < 0) { 4744 if (r < 0) {
4761 DSSERR("request_irq failed\n"); 4745 DSSERR("request_irq failed\n");
4762 goto err_get_irq; 4746 return r;
4763 } 4747 }
4764 4748
4765 /* DSI VCs initialization */ 4749 /* DSI VCs initialization */
@@ -4771,9 +4755,15 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
4771 4755
4772 dsi_calc_clock_param_ranges(dsidev); 4756 dsi_calc_clock_param_ranges(dsidev);
4773 4757
4758 r = dsi_get_clocks(dsidev);
4759 if (r)
4760 return r;
4761
4762 pm_runtime_enable(&dsidev->dev);
4763
4774 r = dsi_runtime_get(dsidev); 4764 r = dsi_runtime_get(dsidev);
4775 if (r) 4765 if (r)
4776 goto err_get_dsi; 4766 goto err_runtime_get;
4777 4767
4778 rev = dsi_read_reg(dsidev, DSI_REVISION); 4768 rev = dsi_read_reg(dsidev, DSI_REVISION);
4779 dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n", 4769 dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n",
@@ -4791,15 +4781,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
4791 4781
4792 return 0; 4782 return 0;
4793 4783
4794err_get_dsi: 4784err_runtime_get:
4795 free_irq(dsi->irq, dsi->pdev);
4796err_get_irq:
4797 iounmap(dsi->base);
4798err_ioremap:
4799 pm_runtime_disable(&dsidev->dev); 4785 pm_runtime_disable(&dsidev->dev);
4800err_get_clk: 4786 dsi_put_clocks(dsidev);
4801 kfree(dsi);
4802err_alloc:
4803 return r; 4787 return r;
4804} 4788}
4805 4789
@@ -4823,11 +4807,6 @@ static int omap_dsihw_remove(struct platform_device *dsidev)
4823 dsi->vdds_dsi_reg = NULL; 4807 dsi->vdds_dsi_reg = NULL;
4824 } 4808 }
4825 4809
4826 free_irq(dsi->irq, dsi->pdev);
4827 iounmap(dsi->base);
4828
4829 kfree(dsi);
4830
4831 return 0; 4810 return 0;
4832} 4811}
4833 4812
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 77c2b5a32b5d..4a6b5eeef6a7 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -748,19 +748,19 @@ static int omap_dsshw_probe(struct platform_device *pdev)
748 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0); 748 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
749 if (!dss_mem) { 749 if (!dss_mem) {
750 DSSERR("can't get IORESOURCE_MEM DSS\n"); 750 DSSERR("can't get IORESOURCE_MEM DSS\n");
751 r = -EINVAL; 751 return -EINVAL;
752 goto err_ioremap;
753 } 752 }
754 dss.base = ioremap(dss_mem->start, resource_size(dss_mem)); 753
754 dss.base = devm_ioremap(&pdev->dev, dss_mem->start,
755 resource_size(dss_mem));
755 if (!dss.base) { 756 if (!dss.base) {
756 DSSERR("can't ioremap DSS\n"); 757 DSSERR("can't ioremap DSS\n");
757 r = -ENOMEM; 758 return -ENOMEM;
758 goto err_ioremap;
759 } 759 }
760 760
761 r = dss_get_clocks(); 761 r = dss_get_clocks();
762 if (r) 762 if (r)
763 goto err_clocks; 763 return r;
764 764
765 pm_runtime_enable(&pdev->dev); 765 pm_runtime_enable(&pdev->dev);
766 766
@@ -808,9 +808,6 @@ err_dpi:
808err_runtime_get: 808err_runtime_get:
809 pm_runtime_disable(&pdev->dev); 809 pm_runtime_disable(&pdev->dev);
810 dss_put_clocks(); 810 dss_put_clocks();
811err_clocks:
812 iounmap(dss.base);
813err_ioremap:
814 return r; 811 return r;
815} 812}
816 813
@@ -819,8 +816,6 @@ static int omap_dsshw_remove(struct platform_device *pdev)
819 dpi_exit(); 816 dpi_exit();
820 sdi_exit(); 817 sdi_exit();
821 818
822 iounmap(dss.base);
823
824 pm_runtime_disable(&pdev->dev); 819 pm_runtime_disable(&pdev->dev);
825 820
826 dss_put_clocks(); 821 dss_put_clocks();
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 32ff69fb3333..d4b3dff2ead3 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -202,9 +202,6 @@ void dss_uninit_device(struct platform_device *pdev,
202 struct omap_dss_device *dssdev); 202 struct omap_dss_device *dssdev);
203bool dss_use_replication(struct omap_dss_device *dssdev, 203bool dss_use_replication(struct omap_dss_device *dssdev,
204 enum omap_color_mode mode); 204 enum omap_color_mode mode);
205void default_get_overlay_fifo_thresholds(enum omap_plane plane,
206 u32 fifo_size, u32 burst_size,
207 u32 *fifo_low, u32 *fifo_high);
208 205
209/* manager */ 206/* manager */
210int dss_init_overlay_managers(struct platform_device *pdev); 207int 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,
313int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, 310int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
314 bool enable_hsdiv); 311 bool enable_hsdiv);
315void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); 312void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
316void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
317 u32 fifo_size, u32 burst_size,
318 u32 *fifo_low, u32 *fifo_high);
319void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); 313void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev);
320void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); 314void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev);
321struct platform_device *dsi_get_dsidev_from_id(int module); 315struct platform_device *dsi_get_dsidev_from_id(int module);
@@ -429,8 +423,8 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
429 423
430 424
431void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); 425void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
432u32 dispc_ovl_get_fifo_size(enum omap_plane plane); 426void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
433u32 dispc_ovl_get_burst_size(enum omap_plane plane); 427 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge);
434int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, 428int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
435 bool ilace, bool replication); 429 bool ilace, bool replication);
436int dispc_ovl_enable(enum omap_plane plane, bool enable); 430int dispc_ovl_enable(enum omap_plane plane, bool enable);
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index afcb59301c37..0a926432ccdc 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -41,7 +41,8 @@ struct omap_dss_features {
41 const struct dss_reg_field *reg_fields; 41 const struct dss_reg_field *reg_fields;
42 const int num_reg_fields; 42 const int num_reg_fields;
43 43
44 const u32 has_feature; 44 const enum dss_feat_id *features;
45 const int num_features;
45 46
46 const int num_mgrs; 47 const int num_mgrs;
47 const int num_ovls; 48 const int num_ovls;
@@ -337,15 +338,110 @@ static const struct dss_param_range omap4_dss_param_range[] = {
337 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, 338 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
338}; 339};
339 340
341static const enum dss_feat_id omap2_dss_feat_list[] = {
342 FEAT_LCDENABLEPOL,
343 FEAT_LCDENABLESIGNAL,
344 FEAT_PCKFREEENABLE,
345 FEAT_FUNCGATED,
346 FEAT_ROWREPEATENABLE,
347 FEAT_RESIZECONF,
348};
349
350static const enum dss_feat_id omap3430_dss_feat_list[] = {
351 FEAT_LCDENABLEPOL,
352 FEAT_LCDENABLESIGNAL,
353 FEAT_PCKFREEENABLE,
354 FEAT_FUNCGATED,
355 FEAT_LINEBUFFERSPLIT,
356 FEAT_ROWREPEATENABLE,
357 FEAT_RESIZECONF,
358 FEAT_DSI_PLL_FREQSEL,
359 FEAT_DSI_REVERSE_TXCLKESC,
360 FEAT_VENC_REQUIRES_TV_DAC_CLK,
361 FEAT_CPR,
362 FEAT_PRELOAD,
363 FEAT_FIR_COEF_V,
364 FEAT_ALPHA_FIXED_ZORDER,
365 FEAT_FIFO_MERGE,
366 FEAT_OMAP3_DSI_FIFO_BUG,
367};
368
369static const enum dss_feat_id omap3630_dss_feat_list[] = {
370 FEAT_LCDENABLEPOL,
371 FEAT_LCDENABLESIGNAL,
372 FEAT_PCKFREEENABLE,
373 FEAT_FUNCGATED,
374 FEAT_LINEBUFFERSPLIT,
375 FEAT_ROWREPEATENABLE,
376 FEAT_RESIZECONF,
377 FEAT_DSI_PLL_PWR_BUG,
378 FEAT_DSI_PLL_FREQSEL,
379 FEAT_CPR,
380 FEAT_PRELOAD,
381 FEAT_FIR_COEF_V,
382 FEAT_ALPHA_FIXED_ZORDER,
383 FEAT_FIFO_MERGE,
384 FEAT_OMAP3_DSI_FIFO_BUG,
385};
386
387static const enum dss_feat_id omap4430_es1_0_dss_feat_list[] = {
388 FEAT_MGR_LCD2,
389 FEAT_CORE_CLK_DIV,
390 FEAT_LCD_CLK_SRC,
391 FEAT_DSI_DCS_CMD_CONFIG_VC,
392 FEAT_DSI_VC_OCP_WIDTH,
393 FEAT_DSI_GNQ,
394 FEAT_HANDLE_UV_SEPARATE,
395 FEAT_ATTR2,
396 FEAT_CPR,
397 FEAT_PRELOAD,
398 FEAT_FIR_COEF_V,
399 FEAT_ALPHA_FREE_ZORDER,
400 FEAT_FIFO_MERGE,
401};
402
403static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = {
404 FEAT_MGR_LCD2,
405 FEAT_CORE_CLK_DIV,
406 FEAT_LCD_CLK_SRC,
407 FEAT_DSI_DCS_CMD_CONFIG_VC,
408 FEAT_DSI_VC_OCP_WIDTH,
409 FEAT_DSI_GNQ,
410 FEAT_HDMI_CTS_SWMODE,
411 FEAT_HANDLE_UV_SEPARATE,
412 FEAT_ATTR2,
413 FEAT_CPR,
414 FEAT_PRELOAD,
415 FEAT_FIR_COEF_V,
416 FEAT_ALPHA_FREE_ZORDER,
417 FEAT_FIFO_MERGE,
418};
419
420static const enum dss_feat_id omap4_dss_feat_list[] = {
421 FEAT_MGR_LCD2,
422 FEAT_CORE_CLK_DIV,
423 FEAT_LCD_CLK_SRC,
424 FEAT_DSI_DCS_CMD_CONFIG_VC,
425 FEAT_DSI_VC_OCP_WIDTH,
426 FEAT_DSI_GNQ,
427 FEAT_HDMI_CTS_SWMODE,
428 FEAT_HDMI_AUDIO_USE_MCLK,
429 FEAT_HANDLE_UV_SEPARATE,
430 FEAT_ATTR2,
431 FEAT_CPR,
432 FEAT_PRELOAD,
433 FEAT_FIR_COEF_V,
434 FEAT_ALPHA_FREE_ZORDER,
435 FEAT_FIFO_MERGE,
436};
437
340/* OMAP2 DSS Features */ 438/* OMAP2 DSS Features */
341static const struct omap_dss_features omap2_dss_features = { 439static const struct omap_dss_features omap2_dss_features = {
342 .reg_fields = omap2_dss_reg_fields, 440 .reg_fields = omap2_dss_reg_fields,
343 .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields), 441 .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields),
344 442
345 .has_feature = 443 .features = omap2_dss_feat_list,
346 FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL | 444 .num_features = ARRAY_SIZE(omap2_dss_feat_list),
347 FEAT_PCKFREEENABLE | FEAT_FUNCGATED |
348 FEAT_ROWREPEATENABLE | FEAT_RESIZECONF,
349 445
350 .num_mgrs = 2, 446 .num_mgrs = 2,
351 .num_ovls = 3, 447 .num_ovls = 3,
@@ -363,14 +459,8 @@ static const struct omap_dss_features omap3430_dss_features = {
363 .reg_fields = omap3_dss_reg_fields, 459 .reg_fields = omap3_dss_reg_fields,
364 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 460 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
365 461
366 .has_feature = 462 .features = omap3430_dss_feat_list,
367 FEAT_LCDENABLEPOL | 463 .num_features = ARRAY_SIZE(omap3430_dss_feat_list),
368 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
369 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
370 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF |
371 FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC |
372 FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD |
373 FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER,
374 464
375 .num_mgrs = 2, 465 .num_mgrs = 2,
376 .num_ovls = 3, 466 .num_ovls = 3,
@@ -387,14 +477,8 @@ static const struct omap_dss_features omap3630_dss_features = {
387 .reg_fields = omap3_dss_reg_fields, 477 .reg_fields = omap3_dss_reg_fields,
388 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 478 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
389 479
390 .has_feature = 480 .features = omap3630_dss_feat_list,
391 FEAT_LCDENABLEPOL | 481 .num_features = ARRAY_SIZE(omap3630_dss_feat_list),
392 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
393 FEAT_FUNCGATED |
394 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
395 FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG |
396 FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD |
397 FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER,
398 482
399 .num_mgrs = 2, 483 .num_mgrs = 2,
400 .num_ovls = 3, 484 .num_ovls = 3,
@@ -413,13 +497,27 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
413 .reg_fields = omap4_dss_reg_fields, 497 .reg_fields = omap4_dss_reg_fields,
414 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields), 498 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
415 499
416 .has_feature = 500 .features = omap4430_es1_0_dss_feat_list,
417 FEAT_MGR_LCD2 | 501 .num_features = ARRAY_SIZE(omap4430_es1_0_dss_feat_list),
418 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC | 502
419 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | 503 .num_mgrs = 3,
420 FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | 504 .num_ovls = 4,
421 FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V | 505 .supported_displays = omap4_dss_supported_displays,
422 FEAT_ALPHA_FREE_ZORDER, 506 .supported_color_modes = omap4_dss_supported_color_modes,
507 .overlay_caps = omap4_dss_overlay_caps,
508 .clksrc_names = omap4_dss_clk_source_names,
509 .dss_params = omap4_dss_param_range,
510 .buffer_size_unit = 16,
511 .burst_size_unit = 16,
512};
513
514/* For OMAP4430 ES 2.0, 2.1 and 2.2 revisions */
515static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
516 .reg_fields = omap4_dss_reg_fields,
517 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
518
519 .features = omap4430_es2_0_1_2_dss_feat_list,
520 .num_features = ARRAY_SIZE(omap4430_es2_0_1_2_dss_feat_list),
423 521
424 .num_mgrs = 3, 522 .num_mgrs = 3,
425 .num_ovls = 4, 523 .num_ovls = 4,
@@ -437,13 +535,8 @@ static const struct omap_dss_features omap4_dss_features = {
437 .reg_fields = omap4_dss_reg_fields, 535 .reg_fields = omap4_dss_reg_fields,
438 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields), 536 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
439 537
440 .has_feature = 538 .features = omap4_dss_feat_list,
441 FEAT_MGR_LCD2 | 539 .num_features = ARRAY_SIZE(omap4_dss_feat_list),
442 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
443 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
444 FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE |
445 FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR |
446 FEAT_PRELOAD | FEAT_FIR_COEF_V | FEAT_ALPHA_FREE_ZORDER,
447 540
448 .num_mgrs = 3, 541 .num_mgrs = 3,
449 .num_ovls = 4, 542 .num_ovls = 4,
@@ -547,7 +640,16 @@ u32 dss_feat_get_burst_size_unit(void)
547/* DSS has_feature check */ 640/* DSS has_feature check */
548bool dss_has_feature(enum dss_feat_id id) 641bool dss_has_feature(enum dss_feat_id id)
549{ 642{
550 return omap_current_dss_features->has_feature & id; 643 int i;
644 const enum dss_feat_id *features = omap_current_dss_features->features;
645 const int num_features = omap_current_dss_features->num_features;
646
647 for (i = 0; i < num_features; i++) {
648 if (features[i] == id)
649 return true;
650 }
651
652 return false;
551} 653}
552 654
553void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end) 655void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end)
@@ -569,6 +671,10 @@ void dss_features_init(void)
569 omap_current_dss_features = &omap3430_dss_features; 671 omap_current_dss_features = &omap3430_dss_features;
570 else if (omap_rev() == OMAP4430_REV_ES1_0) 672 else if (omap_rev() == OMAP4430_REV_ES1_0)
571 omap_current_dss_features = &omap4430_es1_0_dss_features; 673 omap_current_dss_features = &omap4430_es1_0_dss_features;
674 else if (omap_rev() == OMAP4430_REV_ES2_0 ||
675 omap_rev() == OMAP4430_REV_ES2_1 ||
676 omap_rev() == OMAP4430_REV_ES2_2)
677 omap_current_dss_features = &omap4430_es2_0_1_2_dss_features;
572 else if (cpu_is_omap44xx()) 678 else if (cpu_is_omap44xx())
573 omap_current_dss_features = &omap4_dss_features; 679 omap_current_dss_features = &omap4_dss_features;
574 else 680 else
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index cd833bbaac3d..c332e7ddfce1 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -31,33 +31,37 @@
31 31
32/* DSS has feature id */ 32/* DSS has feature id */
33enum dss_feat_id { 33enum dss_feat_id {
34 FEAT_LCDENABLEPOL = 1 << 3, 34 FEAT_LCDENABLEPOL,
35 FEAT_LCDENABLESIGNAL = 1 << 4, 35 FEAT_LCDENABLESIGNAL,
36 FEAT_PCKFREEENABLE = 1 << 5, 36 FEAT_PCKFREEENABLE,
37 FEAT_FUNCGATED = 1 << 6, 37 FEAT_FUNCGATED,
38 FEAT_MGR_LCD2 = 1 << 7, 38 FEAT_MGR_LCD2,
39 FEAT_LINEBUFFERSPLIT = 1 << 8, 39 FEAT_LINEBUFFERSPLIT,
40 FEAT_ROWREPEATENABLE = 1 << 9, 40 FEAT_ROWREPEATENABLE,
41 FEAT_RESIZECONF = 1 << 10, 41 FEAT_RESIZECONF,
42 /* Independent core clk divider */ 42 /* Independent core clk divider */
43 FEAT_CORE_CLK_DIV = 1 << 11, 43 FEAT_CORE_CLK_DIV,
44 FEAT_LCD_CLK_SRC = 1 << 12, 44 FEAT_LCD_CLK_SRC,
45 /* DSI-PLL power command 0x3 is not working */ 45 /* DSI-PLL power command 0x3 is not working */
46 FEAT_DSI_PLL_PWR_BUG = 1 << 13, 46 FEAT_DSI_PLL_PWR_BUG,
47 FEAT_DSI_PLL_FREQSEL = 1 << 14, 47 FEAT_DSI_PLL_FREQSEL,
48 FEAT_DSI_DCS_CMD_CONFIG_VC = 1 << 15, 48 FEAT_DSI_DCS_CMD_CONFIG_VC,
49 FEAT_DSI_VC_OCP_WIDTH = 1 << 16, 49 FEAT_DSI_VC_OCP_WIDTH,
50 FEAT_DSI_REVERSE_TXCLKESC = 1 << 17, 50 FEAT_DSI_REVERSE_TXCLKESC,
51 FEAT_DSI_GNQ = 1 << 18, 51 FEAT_DSI_GNQ,
52 FEAT_HDMI_CTS_SWMODE = 1 << 19, 52 FEAT_HDMI_CTS_SWMODE,
53 FEAT_HANDLE_UV_SEPARATE = 1 << 20, 53 FEAT_HDMI_AUDIO_USE_MCLK,
54 FEAT_ATTR2 = 1 << 21, 54 FEAT_HANDLE_UV_SEPARATE,
55 FEAT_VENC_REQUIRES_TV_DAC_CLK = 1 << 22, 55 FEAT_ATTR2,
56 FEAT_CPR = 1 << 23, 56 FEAT_VENC_REQUIRES_TV_DAC_CLK,
57 FEAT_PRELOAD = 1 << 24, 57 FEAT_CPR,
58 FEAT_FIR_COEF_V = 1 << 25, 58 FEAT_PRELOAD,
59 FEAT_ALPHA_FIXED_ZORDER = 1 << 26, 59 FEAT_FIR_COEF_V,
60 FEAT_ALPHA_FREE_ZORDER = 1 << 27, 60 FEAT_ALPHA_FIXED_ZORDER,
61 FEAT_ALPHA_FREE_ZORDER,
62 FEAT_FIFO_MERGE,
63 /* An unknown HW bug causing the normal FIFO thresholds not to work */
64 FEAT_OMAP3_DSI_FIFO_BUG,
61}; 65};
62 66
63/* DSS register field id */ 67/* DSS register field id */
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index a36b934b2db4..a229d0f83652 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -58,8 +58,6 @@
58#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4 58#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
59#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4 59#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
60 60
61#define OMAP_HDMI_TIMINGS_NB 34
62
63#define HDMI_DEFAULT_REGN 16 61#define HDMI_DEFAULT_REGN 16
64#define HDMI_DEFAULT_REGM2 1 62#define HDMI_DEFAULT_REGM2 1
65 63
@@ -68,8 +66,6 @@ static struct {
68 struct omap_display_platform_data *pdata; 66 struct omap_display_platform_data *pdata;
69 struct platform_device *pdev; 67 struct platform_device *pdev;
70 struct hdmi_ip_data ip_data; 68 struct hdmi_ip_data ip_data;
71 int code;
72 int mode;
73 69
74 struct clk *sys_clk; 70 struct clk *sys_clk;
75} hdmi; 71} hdmi;
@@ -88,77 +84,46 @@ static struct {
88 * map it to corresponding CEA or VESA index. 84 * map it to corresponding CEA or VESA index.
89 */ 85 */
90 86
91static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { 87static const struct hdmi_config cea_timings[] = {
92 { {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0}, 88{ {640, 480, 25200, 96, 16, 48, 2, 10, 33, 0, 0, 0}, {1, HDMI_HDMI} },
93 { {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1}, 89{ {720, 480, 27027, 62, 16, 60, 6, 9, 30, 0, 0, 0}, {2, HDMI_HDMI} },
94 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}, 90{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {4, HDMI_HDMI} },
95 { {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0}, 91{ {1920, 540, 74250, 44, 88, 148, 5, 2, 15, 1, 1, 1}, {5, HDMI_HDMI} },
96 { {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0}, 92{ {1440, 240, 27027, 124, 38, 114, 3, 4, 15, 0, 0, 1}, {6, HDMI_HDMI} },
97 { {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0}, 93{ {1920, 1080, 148500, 44, 88, 148, 5, 4, 36, 1, 1, 0}, {16, HDMI_HDMI} },
98 { {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0}, 94{ {720, 576, 27000, 64, 12, 68, 5, 5, 39, 0, 0, 0}, {17, HDMI_HDMI} },
99 { {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1}, 95{ {1280, 720, 74250, 40, 440, 220, 5, 5, 20, 1, 1, 0}, {19, HDMI_HDMI} },
100 { {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1}, 96{ {1920, 540, 74250, 44, 528, 148, 5, 2, 15, 1, 1, 1}, {20, HDMI_HDMI} },
101 { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1}, 97{ {1440, 288, 27000, 126, 24, 138, 3, 2, 19, 0, 0, 1}, {21, HDMI_HDMI} },
102 { {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0}, 98{ {1440, 576, 54000, 128, 24, 136, 5, 5, 39, 0, 0, 0}, {29, HDMI_HDMI} },
103 { {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0}, 99{ {1920, 1080, 148500, 44, 528, 148, 5, 4, 36, 1, 1, 0}, {31, HDMI_HDMI} },
104 { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1}, 100{ {1920, 1080, 74250, 44, 638, 148, 5, 4, 36, 1, 1, 0}, {32, HDMI_HDMI} },
105 { {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0}, 101{ {2880, 480, 108108, 248, 64, 240, 6, 9, 30, 0, 0, 0}, {35, HDMI_HDMI} },
106 { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1}, 102{ {2880, 576, 108000, 256, 48, 272, 5, 5, 39, 0, 0, 0}, {37, HDMI_HDMI} },
107 /* VESA From Here */
108 { {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0},
109 { {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1},
110 { {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1},
111 { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0},
112 { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0},
113 { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18}, 1, 1},
114 { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1},
115 { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1},
116 { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0},
117 { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0},
118 { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0},
119 { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0},
120 { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1},
121 { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1},
122 { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1},
123 { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1},
124 { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1},
125 { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1},
126 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}
127}; 103};
128 104static const struct hdmi_config vesa_timings[] = {
129/* 105/* VESA From Here */
130 * This is a static mapping array which maps the timing values 106{ {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} },
131 * with corresponding CEA / VESA code 107{ {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} },
132 */ 108{ {848, 480, 33750, 112, 16, 112, 8 , 6, 23, 1, 1, 0}, {0xE, HDMI_DVI} },
133static const int code_index[OMAP_HDMI_TIMINGS_NB] = { 109{ {1280, 768, 79500, 128, 64, 192, 7 , 3, 20, 1, 0, 0}, {0x17, HDMI_DVI} },
134 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32, 110{ {1280, 800, 83500, 128, 72, 200, 6 , 3, 22, 1, 0, 0}, {0x1C, HDMI_DVI} },
135 /* <--15 CEA 17--> vesa*/ 111{ {1360, 768, 85500, 112, 64, 256, 6 , 3, 18, 1, 1, 0}, {0x27, HDMI_DVI} },
136 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A, 112{ {1280, 960, 108000, 112, 96, 312, 3 , 1, 36, 1, 1, 0}, {0x20, HDMI_DVI} },
137 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B 113{ {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38, 1, 1, 0}, {0x23, HDMI_DVI} },
114{ {1024, 768, 65000, 136, 24, 160, 6, 3, 29, 0, 0, 0}, {0x10, HDMI_DVI} },
115{ {1400, 1050, 121750, 144, 88, 232, 4, 3, 32, 1, 0, 0}, {0x2A, HDMI_DVI} },
116{ {1440, 900, 106500, 152, 80, 232, 6, 3, 25, 1, 0, 0}, {0x2F, HDMI_DVI} },
117{ {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, 1, 0, 0}, {0x3A, HDMI_DVI} },
118{ {1366, 768, 85500, 143, 70, 213, 3, 3, 24, 1, 1, 0}, {0x51, HDMI_DVI} },
119{ {1920, 1080, 148500, 44, 148, 80, 5, 4, 36, 1, 1, 0}, {0x52, HDMI_DVI} },
120{ {1280, 768, 68250, 32, 48, 80, 7, 3, 12, 0, 1, 0}, {0x16, HDMI_DVI} },
121{ {1400, 1050, 101000, 32, 48, 80, 4, 3, 23, 0, 1, 0}, {0x29, HDMI_DVI} },
122{ {1680, 1050, 119000, 32, 48, 80, 6, 3, 21, 0, 1, 0}, {0x39, HDMI_DVI} },
123{ {1280, 800, 79500, 32, 48, 80, 6, 3, 14, 0, 1, 0}, {0x1B, HDMI_DVI} },
124{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {0x55, HDMI_DVI} }
138}; 125};
139 126
140/*
141 * This is reverse static mapping which maps the CEA / VESA code
142 * to the corresponding timing values
143 */
144static const int code_cea[39] = {
145 -1, 0, 3, 3, 2, 8, 5, 5, -1, -1,
146 -1, -1, -1, -1, -1, -1, 9, 10, 10, 1,
147 7, 6, 6, -1, -1, -1, -1, -1, -1, 11,
148 11, 12, 14, -1, -1, 13, 13, 4, 4
149};
150
151static const int code_vesa[85] = {
152 -1, -1, -1, -1, 15, -1, -1, -1, -1, 16,
153 -1, -1, -1, -1, 17, -1, 23, -1, -1, -1,
154 -1, -1, 29, 18, -1, -1, -1, 32, 19, -1,
155 -1, -1, 21, -1, -1, 22, -1, -1, -1, 20,
156 -1, 30, 24, -1, -1, -1, -1, 25, -1, -1,
157 -1, -1, -1, -1, -1, -1, -1, 31, 26, -1,
158 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
159 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
160 -1, 27, 28, -1, 33};
161
162static int hdmi_runtime_get(void) 127static int hdmi_runtime_get(void)
163{ 128{
164 int r; 129 int r;
@@ -210,88 +175,89 @@ int hdmi_init_display(struct omap_dss_device *dssdev)
210 return 0; 175 return 0;
211} 176}
212 177
213static int get_timings_index(void) 178static const struct hdmi_config *hdmi_find_timing(
179 const struct hdmi_config *timings_arr,
180 int len)
214{ 181{
215 int code; 182 int i;
216 183
217 if (hdmi.mode == 0) 184 for (i = 0; i < len; i++) {
218 code = code_vesa[hdmi.code]; 185 if (timings_arr[i].cm.code == hdmi.ip_data.cfg.cm.code)
219 else 186 return &timings_arr[i];
220 code = code_cea[hdmi.code]; 187 }
188 return NULL;
189}
221 190
222 if (code == -1) { 191static const struct hdmi_config *hdmi_get_timings(void)
223 /* HDMI code 4 corresponds to 640 * 480 VGA */ 192{
224 hdmi.code = 4; 193 const struct hdmi_config *arr;
225 /* DVI mode 1 corresponds to HDMI 0 to DVI */ 194 int len;
226 hdmi.mode = HDMI_DVI; 195
196 if (hdmi.ip_data.cfg.cm.mode == HDMI_DVI) {
197 arr = vesa_timings;
198 len = ARRAY_SIZE(vesa_timings);
199 } else {
200 arr = cea_timings;
201 len = ARRAY_SIZE(cea_timings);
202 }
203
204 return hdmi_find_timing(arr, len);
205}
206
207static bool hdmi_timings_compare(struct omap_video_timings *timing1,
208 const struct hdmi_video_timings *timing2)
209{
210 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
227 211
228 code = code_vesa[hdmi.code]; 212 if ((timing2->pixel_clock == timing1->pixel_clock) &&
213 (timing2->x_res == timing1->x_res) &&
214 (timing2->y_res == timing1->y_res)) {
215
216 timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp;
217 timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp;
218 timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
219 timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
220
221 DSSDBG("timing1_hsync = %d timing1_vsync = %d"\
222 "timing2_hsync = %d timing2_vsync = %d\n",
223 timing1_hsync, timing1_vsync,
224 timing2_hsync, timing2_vsync);
225
226 if ((timing1_hsync == timing2_hsync) &&
227 (timing1_vsync == timing2_vsync)) {
228 return true;
229 }
229 } 230 }
230 return code; 231 return false;
231} 232}
232 233
233static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) 234static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
234{ 235{
235 int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0; 236 int i;
236 int timing_vsync = 0, timing_hsync = 0;
237 struct hdmi_video_timings temp;
238 struct hdmi_cm cm = {-1}; 237 struct hdmi_cm cm = {-1};
239 DSSDBG("hdmi_get_code\n"); 238 DSSDBG("hdmi_get_code\n");
240 239
241 for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) { 240 for (i = 0; i < ARRAY_SIZE(cea_timings); i++) {
242 temp = cea_vesa_timings[i].timings; 241 if (hdmi_timings_compare(timing, &cea_timings[i].timings)) {
243 if ((temp.pixel_clock == timing->pixel_clock) && 242 cm = cea_timings[i].cm;
244 (temp.x_res == timing->x_res) && 243 goto end;
245 (temp.y_res == timing->y_res)) { 244 }
246 245 }
247 temp_hsync = temp.hfp + temp.hsw + temp.hbp; 246 for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) {
248 timing_hsync = timing->hfp + timing->hsw + timing->hbp; 247 if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) {
249 temp_vsync = temp.vfp + temp.vsw + temp.vbp; 248 cm = vesa_timings[i].cm;
250 timing_vsync = timing->vfp + timing->vsw + timing->vbp; 249 goto end;
251
252 DSSDBG("temp_hsync = %d , temp_vsync = %d"
253 "timing_hsync = %d, timing_vsync = %d\n",
254 temp_hsync, temp_hsync,
255 timing_hsync, timing_vsync);
256
257 if ((temp_hsync == timing_hsync) &&
258 (temp_vsync == timing_vsync)) {
259 code = i;
260 cm.code = code_index[i];
261 if (code < 14)
262 cm.mode = HDMI_HDMI;
263 else
264 cm.mode = HDMI_DVI;
265 DSSDBG("Hdmi_code = %d mode = %d\n",
266 cm.code, cm.mode);
267 break;
268 }
269 } 250 }
270 } 251 }
271 252
272 return cm; 253end: return cm;
273}
274 254
275static void update_hdmi_timings(struct hdmi_config *cfg,
276 struct omap_video_timings *timings, int code)
277{
278 cfg->timings.timings.x_res = timings->x_res;
279 cfg->timings.timings.y_res = timings->y_res;
280 cfg->timings.timings.hbp = timings->hbp;
281 cfg->timings.timings.hfp = timings->hfp;
282 cfg->timings.timings.hsw = timings->hsw;
283 cfg->timings.timings.vbp = timings->vbp;
284 cfg->timings.timings.vfp = timings->vfp;
285 cfg->timings.timings.vsw = timings->vsw;
286 cfg->timings.timings.pixel_clock = timings->pixel_clock;
287 cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol;
288 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
289} 255}
290 256
291unsigned long hdmi_get_pixel_clock(void) 257unsigned long hdmi_get_pixel_clock(void)
292{ 258{
293 /* HDMI Pixel Clock in Mhz */ 259 /* HDMI Pixel Clock in Mhz */
294 return hdmi.ip_data.cfg.timings.timings.pixel_clock * 1000; 260 return hdmi.ip_data.cfg.timings.pixel_clock * 1000;
295} 261}
296 262
297static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, 263static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
@@ -347,7 +313,8 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
347 313
348static int hdmi_power_on(struct omap_dss_device *dssdev) 314static int hdmi_power_on(struct omap_dss_device *dssdev)
349{ 315{
350 int r, code = 0; 316 int r;
317 const struct hdmi_config *timing;
351 struct omap_video_timings *p; 318 struct omap_video_timings *p;
352 unsigned long phy; 319 unsigned long phy;
353 320
@@ -363,9 +330,16 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
363 dssdev->panel.timings.x_res, 330 dssdev->panel.timings.x_res,
364 dssdev->panel.timings.y_res); 331 dssdev->panel.timings.y_res);
365 332
366 code = get_timings_index(); 333 timing = hdmi_get_timings();
367 update_hdmi_timings(&hdmi.ip_data.cfg, p, code); 334 if (timing == NULL) {
368 335 /* HDMI code 4 corresponds to 640 * 480 VGA */
336 hdmi.ip_data.cfg.cm.code = 4;
337 /* DVI mode 1 corresponds to HDMI 0 to DVI */
338 hdmi.ip_data.cfg.cm.mode = HDMI_DVI;
339 hdmi.ip_data.cfg = vesa_timings[0];
340 } else {
341 hdmi.ip_data.cfg = *timing;
342 }
369 phy = p->pixel_clock; 343 phy = p->pixel_clock;
370 344
371 hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); 345 hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
@@ -385,8 +359,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
385 goto err; 359 goto err;
386 } 360 }
387 361
388 hdmi.ip_data.cfg.cm.mode = hdmi.mode;
389 hdmi.ip_data.cfg.cm.code = hdmi.code;
390 hdmi.ip_data.ops->video_configure(&hdmi.ip_data); 362 hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
391 363
392 /* Make selection of HDMI in DSS */ 364 /* Make selection of HDMI in DSS */
@@ -453,8 +425,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
453 struct hdmi_cm cm; 425 struct hdmi_cm cm;
454 426
455 cm = hdmi_get_code(&dssdev->panel.timings); 427 cm = hdmi_get_code(&dssdev->panel.timings);
456 hdmi.code = cm.code; 428 hdmi.ip_data.cfg.cm.code = cm.code;
457 hdmi.mode = cm.mode; 429 hdmi.ip_data.cfg.cm.mode = cm.mode;
458 430
459 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 431 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
460 int r; 432 int r;
@@ -717,13 +689,15 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
717 if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) { 689 if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) {
718 core_cfg.aud_par_busclk = 0; 690 core_cfg.aud_par_busclk = 0;
719 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW; 691 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW;
720 core_cfg.use_mclk = false; 692 core_cfg.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK);
721 } else { 693 } else {
722 core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8); 694 core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8);
723 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW; 695 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW;
724 core_cfg.use_mclk = true; 696 core_cfg.use_mclk = true;
725 core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS;
726 } 697 }
698
699 if (core_cfg.use_mclk)
700 core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS;
727 core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH; 701 core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH;
728 core_cfg.en_spdif = false; 702 core_cfg.en_spdif = false;
729 /* Use sample frequency from channel status word */ 703 /* Use sample frequency from channel status word */
@@ -756,7 +730,7 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
756static int hdmi_audio_startup(struct snd_pcm_substream *substream, 730static int hdmi_audio_startup(struct snd_pcm_substream *substream,
757 struct snd_soc_dai *dai) 731 struct snd_soc_dai *dai)
758{ 732{
759 if (!hdmi.mode) { 733 if (!hdmi.ip_data.cfg.cm.mode) {
760 pr_err("Current video settings do not support audio.\n"); 734 pr_err("Current video settings do not support audio.\n");
761 return -EIO; 735 return -EIO;
762 } 736 }
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 55f398014f33..788a0ef6323a 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -922,35 +922,34 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
922 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0); 922 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
923 if (!rfbi_mem) { 923 if (!rfbi_mem) {
924 DSSERR("can't get IORESOURCE_MEM RFBI\n"); 924 DSSERR("can't get IORESOURCE_MEM RFBI\n");
925 r = -EINVAL; 925 return -EINVAL;
926 goto err_ioremap;
927 } 926 }
928 rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem)); 927
928 rfbi.base = devm_ioremap(&pdev->dev, rfbi_mem->start,
929 resource_size(rfbi_mem));
929 if (!rfbi.base) { 930 if (!rfbi.base) {
930 DSSERR("can't ioremap RFBI\n"); 931 DSSERR("can't ioremap RFBI\n");
931 r = -ENOMEM; 932 return -ENOMEM;
932 goto err_ioremap;
933 } 933 }
934 934
935 pm_runtime_enable(&pdev->dev);
936
937 r = rfbi_runtime_get();
938 if (r)
939 goto err_get_rfbi;
940
941 msleep(10);
942
943 clk = clk_get(&pdev->dev, "ick"); 935 clk = clk_get(&pdev->dev, "ick");
944 if (IS_ERR(clk)) { 936 if (IS_ERR(clk)) {
945 DSSERR("can't get ick\n"); 937 DSSERR("can't get ick\n");
946 r = PTR_ERR(clk); 938 return PTR_ERR(clk);
947 goto err_get_ick;
948 } 939 }
949 940
950 rfbi.l4_khz = clk_get_rate(clk) / 1000; 941 rfbi.l4_khz = clk_get_rate(clk) / 1000;
951 942
952 clk_put(clk); 943 clk_put(clk);
953 944
945 pm_runtime_enable(&pdev->dev);
946
947 r = rfbi_runtime_get();
948 if (r)
949 goto err_runtime_get;
950
951 msleep(10);
952
954 rev = rfbi_read_reg(RFBI_REVISION); 953 rev = rfbi_read_reg(RFBI_REVISION);
955 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n", 954 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
956 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 955 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
@@ -959,19 +958,14 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
959 958
960 return 0; 959 return 0;
961 960
962err_get_ick: 961err_runtime_get:
963 rfbi_runtime_put();
964err_get_rfbi:
965 pm_runtime_disable(&pdev->dev); 962 pm_runtime_disable(&pdev->dev);
966 iounmap(rfbi.base);
967err_ioremap:
968 return r; 963 return r;
969} 964}
970 965
971static int omap_rfbihw_remove(struct platform_device *pdev) 966static int omap_rfbihw_remove(struct platform_device *pdev)
972{ 967{
973 pm_runtime_disable(&pdev->dev); 968 pm_runtime_disable(&pdev->dev);
974 iounmap(rfbi.base);
975 return 0; 969 return 0;
976} 970}
977 971
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
index 50dadba5070a..1f58b84d6901 100644
--- a/drivers/video/omap2/dss/ti_hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -42,6 +42,7 @@ enum hdmi_clk_refsel {
42 HDMI_REFSEL_SYSCLK = 3 42 HDMI_REFSEL_SYSCLK = 3
43}; 43};
44 44
45/* HDMI timing structure */
45struct hdmi_video_timings { 46struct hdmi_video_timings {
46 u16 x_res; 47 u16 x_res;
47 u16 y_res; 48 u16 y_res;
@@ -53,13 +54,9 @@ struct hdmi_video_timings {
53 u16 vsw; 54 u16 vsw;
54 u16 vfp; 55 u16 vfp;
55 u16 vbp; 56 u16 vbp;
56}; 57 bool vsync_pol;
57 58 bool hsync_pol;
58/* HDMI timing structure */ 59 bool interlace;
59struct hdmi_timings {
60 struct hdmi_video_timings timings;
61 int vsync_pol;
62 int hsync_pol;
63}; 60};
64 61
65struct hdmi_cm { 62struct hdmi_cm {
@@ -68,8 +65,7 @@ struct hdmi_cm {
68}; 65};
69 66
70struct hdmi_config { 67struct hdmi_config {
71 struct hdmi_timings timings; 68 struct hdmi_video_timings timings;
72 u16 interlace;
73 struct hdmi_cm cm; 69 struct hdmi_cm cm;
74}; 70};
75 71
@@ -117,6 +113,47 @@ struct ti_hdmi_ip_ops {
117 113
118}; 114};
119 115
116/*
117 * Refer to section 8.2 in HDMI 1.3 specification for
118 * details about infoframe databytes
119 */
120struct hdmi_core_infoframe_avi {
121 /* Y0, Y1 rgb,yCbCr */
122 u8 db1_format;
123 /* A0 Active information Present */
124 u8 db1_active_info;
125 /* B0, B1 Bar info data valid */
126 u8 db1_bar_info_dv;
127 /* S0, S1 scan information */
128 u8 db1_scan_info;
129 /* C0, C1 colorimetry */
130 u8 db2_colorimetry;
131 /* M0, M1 Aspect ratio (4:3, 16:9) */
132 u8 db2_aspect_ratio;
133 /* R0...R3 Active format aspect ratio */
134 u8 db2_active_fmt_ar;
135 /* ITC IT content. */
136 u8 db3_itc;
137 /* EC0, EC1, EC2 Extended colorimetry */
138 u8 db3_ec;
139 /* Q1, Q0 Quantization range */
140 u8 db3_q_range;
141 /* SC1, SC0 Non-uniform picture scaling */
142 u8 db3_nup_scaling;
143 /* VIC0..6 Video format identification */
144 u8 db4_videocode;
145 /* PR0..PR3 Pixel repetition factor */
146 u8 db5_pixel_repeat;
147 /* Line number end of top bar */
148 u16 db6_7_line_eoftop;
149 /* Line number start of bottom bar */
150 u16 db8_9_line_sofbottom;
151 /* Pixel number end of left bar */
152 u16 db10_11_pixel_eofleft;
153 /* Pixel number start of right bar */
154 u16 db12_13_pixel_sofright;
155};
156
120struct hdmi_ip_data { 157struct hdmi_ip_data {
121 void __iomem *base_wp; /* HDMI wrapper */ 158 void __iomem *base_wp; /* HDMI wrapper */
122 unsigned long core_sys_offset; 159 unsigned long core_sys_offset;
@@ -126,6 +163,7 @@ struct hdmi_ip_data {
126 const struct ti_hdmi_ip_ops *ops; 163 const struct ti_hdmi_ip_ops *ops;
127 struct hdmi_config cfg; 164 struct hdmi_config cfg;
128 struct hdmi_pll_info pll_data; 165 struct hdmi_pll_info pll_data;
166 struct hdmi_core_infoframe_avi avi_cfg;
129 167
130 /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */ 168 /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */
131 int hpd_gpio; 169 int hpd_gpio;
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index 6847a478b459..bfe6fe65c8be 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -587,12 +587,12 @@ static void hdmi_core_video_config(struct hdmi_ip_data *ip_data,
587 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5); 587 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);
588} 588}
589 589
590static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data, 590static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data)
591 struct hdmi_core_infoframe_avi info_avi)
592{ 591{
593 u32 val; 592 u32 val;
594 char sum = 0, checksum = 0; 593 char sum = 0, checksum = 0;
595 void __iomem *av_base = hdmi_av_base(ip_data); 594 void __iomem *av_base = hdmi_av_base(ip_data);
595 struct hdmi_core_infoframe_avi info_avi = ip_data->avi_cfg;
596 596
597 sum += 0x82 + 0x002 + 0x00D; 597 sum += 0x82 + 0x002 + 0x00D;
598 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082); 598 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,
682} 682}
683 683
684static void hdmi_wp_init(struct omap_video_timings *timings, 684static void hdmi_wp_init(struct omap_video_timings *timings,
685 struct hdmi_video_format *video_fmt, 685 struct hdmi_video_format *video_fmt)
686 struct hdmi_video_interface *video_int)
687{ 686{
688 pr_debug("Enter hdmi_wp_init\n"); 687 pr_debug("Enter hdmi_wp_init\n");
689 688
@@ -698,12 +697,6 @@ static void hdmi_wp_init(struct omap_video_timings *timings,
698 video_fmt->y_res = 0; 697 video_fmt->y_res = 0;
699 video_fmt->x_res = 0; 698 video_fmt->x_res = 0;
700 699
701 video_int->vsp = 0;
702 video_int->hsp = 0;
703
704 video_int->interlacing = 0;
705 video_int->tm = 0; /* HDMI_TIMING_SLAVE */
706
707} 700}
708 701
709void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start) 702void 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,
716{ 709{
717 pr_debug("Enter hdmi_wp_video_init_format\n"); 710 pr_debug("Enter hdmi_wp_video_init_format\n");
718 711
719 video_fmt->y_res = param->timings.timings.y_res; 712 video_fmt->y_res = param->timings.y_res;
720 video_fmt->x_res = param->timings.timings.x_res; 713 video_fmt->x_res = param->timings.x_res;
721 714
722 timings->hbp = param->timings.timings.hbp; 715 timings->hbp = param->timings.hbp;
723 timings->hfp = param->timings.timings.hfp; 716 timings->hfp = param->timings.hfp;
724 timings->hsw = param->timings.timings.hsw; 717 timings->hsw = param->timings.hsw;
725 timings->vbp = param->timings.timings.vbp; 718 timings->vbp = param->timings.vbp;
726 timings->vfp = param->timings.timings.vfp; 719 timings->vfp = param->timings.vfp;
727 timings->vsw = param->timings.timings.vsw; 720 timings->vsw = param->timings.vsw;
728} 721}
729 722
730static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data, 723static 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,
740 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l); 733 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l);
741} 734}
742 735
743static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data, 736static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data)
744 struct hdmi_video_interface *video_int)
745{ 737{
746 u32 r; 738 u32 r;
747 pr_debug("Enter hdmi_wp_video_config_interface\n"); 739 pr_debug("Enter hdmi_wp_video_config_interface\n");
748 740
749 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); 741 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG);
750 r = FLD_MOD(r, video_int->vsp, 7, 7); 742 r = FLD_MOD(r, ip_data->cfg.timings.vsync_pol, 7, 7);
751 r = FLD_MOD(r, video_int->hsp, 6, 6); 743 r = FLD_MOD(r, ip_data->cfg.timings.hsync_pol, 6, 6);
752 r = FLD_MOD(r, video_int->interlacing, 3, 3); 744 r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3);
753 r = FLD_MOD(r, video_int->tm, 1, 0); 745 r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */
754 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); 746 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r);
755} 747}
756 748
@@ -778,15 +770,13 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)
778 /* HDMI */ 770 /* HDMI */
779 struct omap_video_timings video_timing; 771 struct omap_video_timings video_timing;
780 struct hdmi_video_format video_format; 772 struct hdmi_video_format video_format;
781 struct hdmi_video_interface video_interface;
782 /* HDMI core */ 773 /* HDMI core */
783 struct hdmi_core_infoframe_avi avi_cfg; 774 struct hdmi_core_infoframe_avi avi_cfg = ip_data->avi_cfg;
784 struct hdmi_core_video_config v_core_cfg; 775 struct hdmi_core_video_config v_core_cfg;
785 struct hdmi_core_packet_enable_repeat repeat_cfg; 776 struct hdmi_core_packet_enable_repeat repeat_cfg;
786 struct hdmi_config *cfg = &ip_data->cfg; 777 struct hdmi_config *cfg = &ip_data->cfg;
787 778
788 hdmi_wp_init(&video_timing, &video_format, 779 hdmi_wp_init(&video_timing, &video_format);
789 &video_interface);
790 780
791 hdmi_core_init(&v_core_cfg, 781 hdmi_core_init(&v_core_cfg,
792 &avi_cfg, 782 &avi_cfg,
@@ -801,12 +791,7 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)
801 791
802 hdmi_wp_video_config_format(ip_data, &video_format); 792 hdmi_wp_video_config_format(ip_data, &video_format);
803 793
804 video_interface.vsp = cfg->timings.vsync_pol; 794 hdmi_wp_video_config_interface(ip_data);
805 video_interface.hsp = cfg->timings.hsync_pol;
806 video_interface.interlacing = cfg->interlace;
807 video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
808
809 hdmi_wp_video_config_interface(ip_data, &video_interface);
810 795
811 /* 796 /*
812 * configure core video part 797 * configure core video part
@@ -848,7 +833,7 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)
848 avi_cfg.db10_11_pixel_eofleft = 0; 833 avi_cfg.db10_11_pixel_eofleft = 0;
849 avi_cfg.db12_13_pixel_sofright = 0; 834 avi_cfg.db12_13_pixel_sofright = 0;
850 835
851 hdmi_core_aux_infoframe_avi_config(ip_data, avi_cfg); 836 hdmi_core_aux_infoframe_avi_config(ip_data);
852 837
853 /* enable/repeat the infoframe */ 838 /* enable/repeat the infoframe */
854 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE; 839 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
@@ -1076,13 +1061,9 @@ void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
1076 u32 r; 1061 u32 r;
1077 void __iomem *av_base = hdmi_av_base(ip_data); 1062 void __iomem *av_base = hdmi_av_base(ip_data);
1078 1063
1079 /* audio clock recovery parameters */ 1064 /*
1080 r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL); 1065 * Parameters for generation of Audio Clock Recovery packets
1081 r = FLD_MOD(r, cfg->use_mclk, 2, 2); 1066 */
1082 r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
1083 r = FLD_MOD(r, cfg->cts_mode, 0, 0);
1084 hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r);
1085
1086 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0); 1067 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0);
1087 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0); 1068 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0);
1088 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0); 1069 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,
1094 REG_FLD_MOD(av_base, 1075 REG_FLD_MOD(av_base,
1095 HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0); 1076 HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0);
1096 } else { 1077 } else {
1097 /*
1098 * HDMI IP uses this configuration to divide the MCLK to
1099 * update CTS value.
1100 */
1101 REG_FLD_MOD(av_base,
1102 HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
1103
1104 /* Configure clock for audio packets */
1105 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1, 1078 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
1106 cfg->aud_par_busclk, 7, 0); 1079 cfg->aud_par_busclk, 7, 0);
1107 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_2, 1080 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,
1110 (cfg->aud_par_busclk >> 16), 7, 0); 1083 (cfg->aud_par_busclk >> 16), 7, 0);
1111 } 1084 }
1112 1085
1086 /* Set ACR clock divisor */
1087 REG_FLD_MOD(av_base,
1088 HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
1089
1090 r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL);
1091 /*
1092 * Use TMDS clock for ACR packets. For devices that use
1093 * the MCLK, this is the first part of the MCLK initialization.
1094 */
1095 r = FLD_MOD(r, 0, 2, 2);
1096
1097 r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
1098 r = FLD_MOD(r, cfg->cts_mode, 0, 0);
1099 hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r);
1100
1101 /* For devices using MCLK, this completes its initialization. */
1102 if (cfg->use_mclk)
1103 REG_FLD_MOD(av_base, HDMI_CORE_AV_ACR_CTRL, 1, 2, 2);
1104
1113 /* Override of SPDIF sample frequency with value in I2S_CHST4 */ 1105 /* Override of SPDIF sample frequency with value in I2S_CHST4 */
1114 REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL, 1106 REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL,
1115 cfg->fs_override, 1, 1); 1107 cfg->fs_override, 1, 1);
@@ -1205,7 +1197,7 @@ int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
1205{ 1197{
1206 u32 r; 1198 u32 r;
1207 u32 deep_color = 0; 1199 u32 deep_color = 0;
1208 u32 pclk = ip_data->cfg.timings.timings.pixel_clock; 1200 u32 pclk = ip_data->cfg.timings.pixel_clock;
1209 1201
1210 if (n == NULL || cts == NULL) 1202 if (n == NULL || cts == NULL)
1211 return -EINVAL; 1203 return -EINVAL;
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
index a442998980f1..a14d1a0e6e41 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
@@ -450,46 +450,6 @@ struct hdmi_core_video_config {
450 * Refer to section 8.2 in HDMI 1.3 specification for 450 * Refer to section 8.2 in HDMI 1.3 specification for
451 * details about infoframe databytes 451 * details about infoframe databytes
452 */ 452 */
453struct hdmi_core_infoframe_avi {
454 /* Y0, Y1 rgb,yCbCr */
455 u8 db1_format;
456 /* A0 Active information Present */
457 u8 db1_active_info;
458 /* B0, B1 Bar info data valid */
459 u8 db1_bar_info_dv;
460 /* S0, S1 scan information */
461 u8 db1_scan_info;
462 /* C0, C1 colorimetry */
463 u8 db2_colorimetry;
464 /* M0, M1 Aspect ratio (4:3, 16:9) */
465 u8 db2_aspect_ratio;
466 /* R0...R3 Active format aspect ratio */
467 u8 db2_active_fmt_ar;
468 /* ITC IT content. */
469 u8 db3_itc;
470 /* EC0, EC1, EC2 Extended colorimetry */
471 u8 db3_ec;
472 /* Q1, Q0 Quantization range */
473 u8 db3_q_range;
474 /* SC1, SC0 Non-uniform picture scaling */
475 u8 db3_nup_scaling;
476 /* VIC0..6 Video format identification */
477 u8 db4_videocode;
478 /* PR0..PR3 Pixel repetition factor */
479 u8 db5_pixel_repeat;
480 /* Line number end of top bar */
481 u16 db6_7_line_eoftop;
482 /* Line number start of bottom bar */
483 u16 db8_9_line_sofbottom;
484 /* Pixel number end of left bar */
485 u16 db10_11_pixel_eofleft;
486 /* Pixel number start of right bar */
487 u16 db12_13_pixel_sofright;
488};
489/*
490 * Refer to section 8.2 in HDMI 1.3 specification for
491 * details about infoframe databytes
492 */
493struct hdmi_core_infoframe_audio { 453struct hdmi_core_infoframe_audio {
494 u8 db1_coding_type; 454 u8 db1_coding_type;
495 u8 db1_channel_count; 455 u8 db1_channel_count;
@@ -517,13 +477,6 @@ struct hdmi_video_format {
517 u32 x_res; /* pixel per line */ 477 u32 x_res; /* pixel per line */
518}; 478};
519 479
520struct hdmi_video_interface {
521 int vsp; /* Vsync polarity */
522 int hsp; /* Hsync polarity */
523 int interlacing;
524 int tm; /* Timing mode */
525};
526
527struct hdmi_audio_format { 480struct hdmi_audio_format {
528 enum hdmi_stereo_channels stereo_channels; 481 enum hdmi_stereo_channels stereo_channels;
529 u8 active_chnnls_msk; 482 u8 active_chnnls_msk;
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 5c3d0f901510..9c3daf71750c 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -699,6 +699,11 @@ void venc_dump_regs(struct seq_file *s)
699{ 699{
700#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r)) 700#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
701 701
702 if (cpu_is_omap44xx()) {
703 seq_printf(s, "VENC currently disabled on OMAP44xx\n");
704 return;
705 }
706
702 if (venc_runtime_get()) 707 if (venc_runtime_get())
703 return; 708 return;
704 709
@@ -790,39 +795,41 @@ static int omap_venchw_probe(struct platform_device *pdev)
790 venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0); 795 venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
791 if (!venc_mem) { 796 if (!venc_mem) {
792 DSSERR("can't get IORESOURCE_MEM VENC\n"); 797 DSSERR("can't get IORESOURCE_MEM VENC\n");
793 r = -EINVAL; 798 return -EINVAL;
794 goto err_ioremap;
795 } 799 }
796 venc.base = ioremap(venc_mem->start, resource_size(venc_mem)); 800
801 venc.base = devm_ioremap(&pdev->dev, venc_mem->start,
802 resource_size(venc_mem));
797 if (!venc.base) { 803 if (!venc.base) {
798 DSSERR("can't ioremap VENC\n"); 804 DSSERR("can't ioremap VENC\n");
799 r = -ENOMEM; 805 return -ENOMEM;
800 goto err_ioremap;
801 } 806 }
802 807
803 r = venc_get_clocks(pdev); 808 r = venc_get_clocks(pdev);
804 if (r) 809 if (r)
805 goto err_get_clk; 810 return r;
806 811
807 pm_runtime_enable(&pdev->dev); 812 pm_runtime_enable(&pdev->dev);
808 813
809 r = venc_runtime_get(); 814 r = venc_runtime_get();
810 if (r) 815 if (r)
811 goto err_get_venc; 816 goto err_runtime_get;
812 817
813 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff); 818 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
814 dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id); 819 dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id);
815 820
816 venc_runtime_put(); 821 venc_runtime_put();
817 822
818 return omap_dss_register_driver(&venc_driver); 823 r = omap_dss_register_driver(&venc_driver);
824 if (r)
825 goto err_reg_panel_driver;
826
827 return 0;
819 828
820err_get_venc: 829err_reg_panel_driver:
830err_runtime_get:
821 pm_runtime_disable(&pdev->dev); 831 pm_runtime_disable(&pdev->dev);
822 venc_put_clocks(); 832 venc_put_clocks();
823err_get_clk:
824 iounmap(venc.base);
825err_ioremap:
826 return r; 833 return r;
827} 834}
828 835
@@ -837,7 +844,6 @@ static int omap_venchw_remove(struct platform_device *pdev)
837 pm_runtime_disable(&pdev->dev); 844 pm_runtime_disable(&pdev->dev);
838 venc_put_clocks(); 845 venc_put_clocks();
839 846
840 iounmap(venc.base);
841 return 0; 847 return 0;
842} 848}
843 849
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 16ba6196f330..6a09ef87e14f 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -215,7 +215,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
215 int r = 0, i; 215 int r = 0, i;
216 size_t size; 216 size_t size;
217 217
218 if (mi->type > OMAPFB_MEMTYPE_MAX) 218 if (mi->type != OMAPFB_MEMTYPE_SDRAM)
219 return -EINVAL; 219 return -EINVAL;
220 220
221 size = PAGE_ALIGN(mi->size); 221 size = PAGE_ALIGN(mi->size);
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index ce158311ff59..b00db4068d21 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1399,7 +1399,7 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
1399 1399
1400 if (!paddr) { 1400 if (!paddr) {
1401 DBG("allocating %lu bytes for fb %d\n", size, ofbi->id); 1401 DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
1402 r = omap_vram_alloc(OMAP_VRAM_MEMTYPE_SDRAM, size, &paddr); 1402 r = omap_vram_alloc(size, &paddr);
1403 } else { 1403 } else {
1404 DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr, 1404 DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr,
1405 ofbi->id); 1405 ofbi->id);
@@ -1487,60 +1487,6 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
1487 return omapfb_alloc_fbmem(fbi, size, paddr); 1487 return omapfb_alloc_fbmem(fbi, size, paddr);
1488} 1488}
1489 1489
1490static enum omap_color_mode fb_format_to_dss_mode(enum omapfb_color_format fmt)
1491{
1492 enum omap_color_mode mode;
1493
1494 switch (fmt) {
1495 case OMAPFB_COLOR_RGB565:
1496 mode = OMAP_DSS_COLOR_RGB16;
1497 break;
1498 case OMAPFB_COLOR_YUV422:
1499 mode = OMAP_DSS_COLOR_YUV2;
1500 break;
1501 case OMAPFB_COLOR_CLUT_8BPP:
1502 mode = OMAP_DSS_COLOR_CLUT8;
1503 break;
1504 case OMAPFB_COLOR_CLUT_4BPP:
1505 mode = OMAP_DSS_COLOR_CLUT4;
1506 break;
1507 case OMAPFB_COLOR_CLUT_2BPP:
1508 mode = OMAP_DSS_COLOR_CLUT2;
1509 break;
1510 case OMAPFB_COLOR_CLUT_1BPP:
1511 mode = OMAP_DSS_COLOR_CLUT1;
1512 break;
1513 case OMAPFB_COLOR_RGB444:
1514 mode = OMAP_DSS_COLOR_RGB12U;
1515 break;
1516 case OMAPFB_COLOR_YUY422:
1517 mode = OMAP_DSS_COLOR_UYVY;
1518 break;
1519 case OMAPFB_COLOR_ARGB16:
1520 mode = OMAP_DSS_COLOR_ARGB16;
1521 break;
1522 case OMAPFB_COLOR_RGB24U:
1523 mode = OMAP_DSS_COLOR_RGB24U;
1524 break;
1525 case OMAPFB_COLOR_RGB24P:
1526 mode = OMAP_DSS_COLOR_RGB24P;
1527 break;
1528 case OMAPFB_COLOR_ARGB32:
1529 mode = OMAP_DSS_COLOR_ARGB32;
1530 break;
1531 case OMAPFB_COLOR_RGBA32:
1532 mode = OMAP_DSS_COLOR_RGBA32;
1533 break;
1534 case OMAPFB_COLOR_RGBX32:
1535 mode = OMAP_DSS_COLOR_RGBX32;
1536 break;
1537 default:
1538 mode = -EINVAL;
1539 }
1540
1541 return mode;
1542}
1543
1544static int omapfb_parse_vram_param(const char *param, int max_entries, 1490static int omapfb_parse_vram_param(const char *param, int max_entries,
1545 unsigned long *sizes, unsigned long *paddrs) 1491 unsigned long *sizes, unsigned long *paddrs)
1546{ 1492{
@@ -1614,23 +1560,6 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev)
1614 memset(&vram_paddrs, 0, sizeof(vram_paddrs)); 1560 memset(&vram_paddrs, 0, sizeof(vram_paddrs));
1615 } 1561 }
1616 1562
1617 if (fbdev->dev->platform_data) {
1618 struct omapfb_platform_data *opd;
1619 opd = fbdev->dev->platform_data;
1620 for (i = 0; i < opd->mem_desc.region_cnt; ++i) {
1621 if (!vram_sizes[i]) {
1622 unsigned long size;
1623 unsigned long paddr;
1624
1625 size = opd->mem_desc.region[i].size;
1626 paddr = opd->mem_desc.region[i].paddr;
1627
1628 vram_sizes[i] = size;
1629 vram_paddrs[i] = paddr;
1630 }
1631 }
1632 }
1633
1634 for (i = 0; i < fbdev->num_fbs; i++) { 1563 for (i = 0; i < fbdev->num_fbs; i++) {
1635 /* allocate memory automatically only for fb0, or if 1564 /* allocate memory automatically only for fb0, or if
1636 * excplicitly defined with vram or plat data option */ 1565 * 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)
1669 int old_type = rg->type; 1598 int old_type = rg->type;
1670 int r; 1599 int r;
1671 1600
1672 if (type > OMAPFB_MEMTYPE_MAX) 1601 if (type != OMAPFB_MEMTYPE_SDRAM)
1673 return -EINVAL; 1602 return -EINVAL;
1674 1603
1675 size = PAGE_ALIGN(size); 1604 size = PAGE_ALIGN(size);
@@ -1828,32 +1757,6 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
1828 1757
1829 var->rotate = def_rotate; 1758 var->rotate = def_rotate;
1830 1759
1831 /*
1832 * Check if there is a default color format set in the board file,
1833 * and use this format instead the default deducted from the
1834 * display bpp.
1835 */
1836 if (fbdev->dev->platform_data) {
1837 struct omapfb_platform_data *opd;
1838 int id = ofbi->id;
1839
1840 opd = fbdev->dev->platform_data;
1841 if (opd->mem_desc.region[id].format_used) {
1842 enum omap_color_mode mode;
1843 enum omapfb_color_format format;
1844
1845 format = opd->mem_desc.region[id].format;
1846 mode = fb_format_to_dss_mode(format);
1847 if (mode < 0) {
1848 r = mode;
1849 goto err;
1850 }
1851 r = dss_mode_to_fb_mode(mode, var);
1852 if (r < 0)
1853 goto err;
1854 }
1855 }
1856
1857 if (display) { 1760 if (display) {
1858 u16 w, h; 1761 u16 w, h;
1859 int rotation = (var->rotate + ofbi->rotation[0]) % 4; 1762 int rotation = (var->rotate + ofbi->rotation[0]) % 4;
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
index 9441e2eb3dee..87e421e25afe 100644
--- a/drivers/video/omap2/vram.c
+++ b/drivers/video/omap2/vram.c
@@ -33,7 +33,6 @@
33 33
34#include <asm/setup.h> 34#include <asm/setup.h>
35 35
36#include <plat/sram.h>
37#include <plat/vram.h> 36#include <plat/vram.h>
38#include <plat/dma.h> 37#include <plat/dma.h>
39 38
@@ -43,10 +42,6 @@
43#define DBG(format, ...) 42#define DBG(format, ...)
44#endif 43#endif
45 44
46#define OMAP2_SRAM_START 0x40200000
47/* Maximum size, in reality this is smaller if SRAM is partially locked. */
48#define OMAP2_SRAM_SIZE 0xa0000 /* 640k */
49
50/* postponed regions are used to temporarily store region information at boot 45/* postponed regions are used to temporarily store region information at boot
51 * time when we cannot yet allocate the region list */ 46 * time when we cannot yet allocate the region list */
52#define MAX_POSTPONED_REGIONS 10 47#define MAX_POSTPONED_REGIONS 10
@@ -74,15 +69,6 @@ struct vram_region {
74static DEFINE_MUTEX(region_mutex); 69static DEFINE_MUTEX(region_mutex);
75static LIST_HEAD(region_list); 70static LIST_HEAD(region_list);
76 71
77static inline int region_mem_type(unsigned long paddr)
78{
79 if (paddr >= OMAP2_SRAM_START &&
80 paddr < OMAP2_SRAM_START + OMAP2_SRAM_SIZE)
81 return OMAP_VRAM_MEMTYPE_SRAM;
82 else
83 return OMAP_VRAM_MEMTYPE_SDRAM;
84}
85
86static struct vram_region *omap_vram_create_region(unsigned long paddr, 72static struct vram_region *omap_vram_create_region(unsigned long paddr,
87 unsigned pages) 73 unsigned pages)
88{ 74{
@@ -212,9 +198,6 @@ static int _omap_vram_reserve(unsigned long paddr, unsigned pages)
212 198
213 DBG("checking region %lx %d\n", rm->paddr, rm->pages); 199 DBG("checking region %lx %d\n", rm->paddr, rm->pages);
214 200
215 if (region_mem_type(rm->paddr) != region_mem_type(paddr))
216 continue;
217
218 start = rm->paddr; 201 start = rm->paddr;
219 end = start + (rm->pages << PAGE_SHIFT) - 1; 202 end = start + (rm->pages << PAGE_SHIFT) - 1;
220 if (start > paddr || end < paddr + size - 1) 203 if (start > paddr || end < paddr + size - 1)
@@ -320,7 +303,7 @@ err:
320 return r; 303 return r;
321} 304}
322 305
323static int _omap_vram_alloc(int mtype, unsigned pages, unsigned long *paddr) 306static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
324{ 307{
325 struct vram_region *rm; 308 struct vram_region *rm;
326 struct vram_alloc *alloc; 309 struct vram_alloc *alloc;
@@ -330,9 +313,6 @@ static int _omap_vram_alloc(int mtype, unsigned pages, unsigned long *paddr)
330 313
331 DBG("checking region %lx %d\n", rm->paddr, rm->pages); 314 DBG("checking region %lx %d\n", rm->paddr, rm->pages);
332 315
333 if (region_mem_type(rm->paddr) != mtype)
334 continue;
335
336 start = rm->paddr; 316 start = rm->paddr;
337 317
338 list_for_each_entry(alloc, &rm->alloc_list, list) { 318 list_for_each_entry(alloc, &rm->alloc_list, list) {
@@ -365,21 +345,21 @@ found:
365 return -ENOMEM; 345 return -ENOMEM;
366} 346}
367 347
368int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr) 348int omap_vram_alloc(size_t size, unsigned long *paddr)
369{ 349{
370 unsigned pages; 350 unsigned pages;
371 int r; 351 int r;
372 352
373 BUG_ON(mtype > OMAP_VRAM_MEMTYPE_MAX || !size); 353 BUG_ON(!size);
374 354
375 DBG("alloc mem type %d size %d\n", mtype, size); 355 DBG("alloc mem size %d\n", size);
376 356
377 size = PAGE_ALIGN(size); 357 size = PAGE_ALIGN(size);
378 pages = size >> PAGE_SHIFT; 358 pages = size >> PAGE_SHIFT;
379 359
380 mutex_lock(&region_mutex); 360 mutex_lock(&region_mutex);
381 361
382 r = _omap_vram_alloc(mtype, pages, paddr); 362 r = _omap_vram_alloc(pages, paddr);
383 363
384 mutex_unlock(&region_mutex); 364 mutex_unlock(&region_mutex);
385 365
@@ -501,10 +481,6 @@ arch_initcall(omap_vram_init);
501/* boottime vram alloc stuff */ 481/* boottime vram alloc stuff */
502 482
503/* set from board file */ 483/* set from board file */
504static u32 omap_vram_sram_start __initdata;
505static u32 omap_vram_sram_size __initdata;
506
507/* set from board file */
508static u32 omap_vram_sdram_start __initdata; 484static u32 omap_vram_sdram_start __initdata;
509static u32 omap_vram_sdram_size __initdata; 485static u32 omap_vram_sdram_size __initdata;
510 486
@@ -587,73 +563,8 @@ void __init omap_vram_reserve_sdram_memblock(void)
587 pr_info("Reserving %u bytes SDRAM for VRAM\n", size); 563 pr_info("Reserving %u bytes SDRAM for VRAM\n", size);
588} 564}
589 565
590/*
591 * Called at sram init time, before anything is pushed to the SRAM stack.
592 * Because of the stack scheme, we will allocate everything from the
593 * start of the lowest address region to the end of SRAM. This will also
594 * include padding for page alignment and possible holes between regions.
595 *
596 * As opposed to the SDRAM case, we'll also do any dynamic allocations at
597 * this point, since the driver built as a module would have problem with
598 * freeing / reallocating the regions.
599 */
600unsigned long __init omap_vram_reserve_sram(unsigned long sram_pstart,
601 unsigned long sram_vstart,
602 unsigned long sram_size,
603 unsigned long pstart_avail,
604 unsigned long size_avail)
605{
606 unsigned long pend_avail;
607 unsigned long reserved;
608 u32 paddr;
609 u32 size;
610
611 paddr = omap_vram_sram_start;
612 size = omap_vram_sram_size;
613
614 if (!size)
615 return 0;
616
617 reserved = 0;
618 pend_avail = pstart_avail + size_avail;
619
620 if (!paddr) {
621 /* Dynamic allocation */
622 if ((size_avail & PAGE_MASK) < size) {
623 pr_err("Not enough SRAM for VRAM\n");
624 return 0;
625 }
626 size_avail = (size_avail - size) & PAGE_MASK;
627 paddr = pstart_avail + size_avail;
628 }
629
630 if (paddr < sram_pstart ||
631 paddr + size > sram_pstart + sram_size) {
632 pr_err("Illegal SRAM region for VRAM\n");
633 return 0;
634 }
635
636 /* Reserve everything above the start of the region. */
637 if (pend_avail - paddr > reserved)
638 reserved = pend_avail - paddr;
639 size_avail = pend_avail - reserved - pstart_avail;
640
641 omap_vram_add_region(paddr, size);
642
643 if (reserved)
644 pr_info("Reserving %lu bytes SRAM for VRAM\n", reserved);
645
646 return reserved;
647}
648
649void __init omap_vram_set_sdram_vram(u32 size, u32 start) 566void __init omap_vram_set_sdram_vram(u32 size, u32 start)
650{ 567{
651 omap_vram_sdram_start = start; 568 omap_vram_sdram_start = start;
652 omap_vram_sdram_size = size; 569 omap_vram_sdram_size = size;
653} 570}
654
655void __init omap_vram_set_sram_vram(u32 size, u32 start)
656{
657 omap_vram_sram_start = start;
658 omap_vram_sram_size = size;
659}
diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h
index c0b018790f07..4ff57e81051d 100644
--- a/include/linux/omapfb.h
+++ b/include/linux/omapfb.h
@@ -222,41 +222,11 @@ struct omapfb_display_info {
222 222
223#include <plat/board.h> 223#include <plat/board.h>
224 224
225#ifdef CONFIG_ARCH_OMAP1
226#define OMAPFB_PLANE_NUM 1
227#else
228#define OMAPFB_PLANE_NUM 3
229#endif
230
231struct omapfb_mem_region {
232 u32 paddr;
233 void __iomem *vaddr;
234 unsigned long size;
235 u8 type; /* OMAPFB_PLANE_MEM_* */
236 enum omapfb_color_format format;/* OMAPFB_COLOR_* */
237 unsigned format_used:1; /* Must be set when format is set.
238 * Needed b/c of the badly chosen 0
239 * base for OMAPFB_COLOR_* values
240 */
241 unsigned alloc:1; /* allocated by the driver */
242 unsigned map:1; /* kernel mapped by the driver */
243};
244
245struct omapfb_mem_desc {
246 int region_cnt;
247 struct omapfb_mem_region region[OMAPFB_PLANE_NUM];
248};
249
250struct omapfb_platform_data { 225struct omapfb_platform_data {
251 struct omap_lcd_config lcd; 226 struct omap_lcd_config lcd;
252 struct omapfb_mem_desc mem_desc;
253 void *ctrl_platform_data;
254}; 227};
255 228
256/* in arch/arm/plat-omap/fb.c */ 229void __init omapfb_set_lcd_config(const struct omap_lcd_config *config);
257extern void omapfb_set_platform_data(struct omapfb_platform_data *data);
258extern void omapfb_set_ctrl_platform_data(void *pdata);
259extern void omapfb_reserve_sdram_memblock(void);
260 230
261#endif 231#endif
262 232