aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 21:09:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 21:09:33 -0400
commit9e9ac896667a55ae9a3df119611ee5322abe2890 (patch)
tree82d486ff50b822aff5691bd396247f8cbc1aa800 /drivers/video
parent34b20e6df6970e36b93f445669ba5ef7a05fe01a (diff)
parente4e42b8ad24cabf4d6d3c20a63f18dd6b954d9c2 (diff)
Merge tag 'fbdev-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux
Pull fbdev updates from Tomi Valkeinen: - much better HDMI infoframe support for OMAP - Cirrus Logic CLPS711X framebuffer driver - DT support for PL11x CLCD driver - various small fixes * tag 'fbdev-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (35 commits) OMAPDSS: DSI: fix depopulating dsi peripherals video: hyperv: hyperv_fb: refresh the VM screen by force on VM panic video: ARM CLCD: Fix DT-related build problems drivers: video: fbdev: atmel_lcdfb.c: Add ability to inverted backlight PWM. video: ARM CLCD: Add DT support drm/omap: Add infoframe & dvi/hdmi mode support OMAPDSS: HDMI: remove the unused code OMAPDSS: HDMI5: add support to set infoframe & HDMI mode OMAPDSS: HDMI4: add support to set infoframe & HDMI mode OMAPDSS: HDMI: add infoframe and hdmi_dvi_mode fields OMAPDSS: add hdmi ops to hdmi-connector and tpd12s015 OMAPDSS: add hdmi ops to hdmi_ops and omap_dss_driver OMAPDSS: HDMI: remove custom avi infoframe OMAPDSS: HDMI5: use common AVI infoframe support OMAPDSS: HDMI4: use common AVI infoframe support OMAPDSS: Kconfig: select HDMI OMAPDSS: HDMI: fix name conflict OMAPDSS: DISPC: clean up dispc_mgr_timings_ok OMAPDSS: DISPC: reject interlace for lcd out OMAPDSS: DISPC: fix debugfs reg dump ...
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fbdev/68328fb.c8
-rw-r--r--drivers/video/fbdev/Kconfig23
-rw-r--r--drivers/video/fbdev/Makefile3
-rw-r--r--drivers/video/fbdev/amba-clcd.c263
-rw-r--r--drivers/video/fbdev/atmel_lcdfb.c3
-rw-r--r--drivers/video/fbdev/clps711x-fb.c397
-rw-r--r--drivers/video/fbdev/da8xx-fb.c9
-rw-r--r--drivers/video/fbdev/hyperv_fb.c62
-rw-r--r--drivers/video/fbdev/mbx/mbxfb.c4
-rw-r--r--drivers/video/fbdev/msm/mddi_client_dummy.c19
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-hdmi.c19
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c20
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c5
-rw-r--r--drivers/video/fbdev/omap2/dss/Kconfig1
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc.c22
-rw-r--r--drivers/video/fbdev/omap2/dss/dsi.c9
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi.h107
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4.c53
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4_core.c164
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4_core.h1
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi5.c53
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi5_core.c124
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_common.c316
-rw-r--r--drivers/video/fbdev/s3c2410fb.c10
-rw-r--r--drivers/video/fbdev/sis/init.c2
-rw-r--r--drivers/video/fbdev/sis/sis_main.c4
26 files changed, 950 insertions, 751 deletions
diff --git a/drivers/video/fbdev/68328fb.c b/drivers/video/fbdev/68328fb.c
index 552258c8f99d..17f21cedff9b 100644
--- a/drivers/video/fbdev/68328fb.c
+++ b/drivers/video/fbdev/68328fb.c
@@ -49,12 +49,6 @@
49#error wrong architecture for the MC68x328 frame buffer device 49#error wrong architecture for the MC68x328 frame buffer device
50#endif 50#endif
51 51
52#if defined(CONFIG_FB_68328_INVERT)
53#define MC68X328FB_MONO_VISUAL FB_VISUAL_MONO01
54#else
55#define MC68X328FB_MONO_VISUAL FB_VISUAL_MONO10
56#endif
57
58static u_long videomemory; 52static u_long videomemory;
59static u_long videomemorysize; 53static u_long videomemorysize;
60 54
@@ -462,7 +456,7 @@ int __init mc68x328fb_init(void)
462 fb_info.fix.line_length = 456 fb_info.fix.line_length =
463 get_line_length(mc68x328fb_default.xres_virtual, mc68x328fb_default.bits_per_pixel); 457 get_line_length(mc68x328fb_default.xres_virtual, mc68x328fb_default.bits_per_pixel);
464 fb_info.fix.visual = (mc68x328fb_default.bits_per_pixel) == 1 ? 458 fb_info.fix.visual = (mc68x328fb_default.bits_per_pixel) == 1 ?
465 MC68X328FB_MONO_VISUAL : FB_VISUAL_PSEUDOCOLOR; 459 FB_VISUAL_MONO10 : FB_VISUAL_PSEUDOCOLOR;
466 if (fb_info.var.bits_per_pixel == 1) { 460 if (fb_info.var.bits_per_pixel == 1) {
467 fb_info.var.red.length = fb_info.var.green.length = fb_info.var.blue.length = 1; 461 fb_info.var.red.length = fb_info.var.green.length = fb_info.var.blue.length = 1;
468 fb_info.var.red.offset = fb_info.var.green.offset = fb_info.var.blue.offset = 0; 462 fb_info.var.red.offset = fb_info.var.green.offset = fb_info.var.blue.offset = 0;
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index e05a58d759be..e911b9c96e19 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -280,6 +280,8 @@ config FB_ARMCLCD
280 select FB_CFB_FILLRECT 280 select FB_CFB_FILLRECT
281 select FB_CFB_COPYAREA 281 select FB_CFB_COPYAREA
282 select FB_CFB_IMAGEBLIT 282 select FB_CFB_IMAGEBLIT
283 select FB_MODE_HELPERS if OF
284 select VIDEOMODE_HELPERS if OF
283 help 285 help
284 This framebuffer device driver is for the ARM PrimeCell PL110 286 This framebuffer device driver is for the ARM PrimeCell PL110
285 Colour LCD controller. ARM PrimeCells provide the building 287 Colour LCD controller. ARM PrimeCells provide the building
@@ -307,15 +309,26 @@ config FB_ACORN
307 hardware found in Acorn RISC PCs and other ARM-based machines. If 309 hardware found in Acorn RISC PCs and other ARM-based machines. If
308 unsure, say N. 310 unsure, say N.
309 311
310config FB_CLPS711X 312config FB_CLPS711X_OLD
311 bool "CLPS711X LCD support" 313 tristate
312 depends on (FB = y) && ARM && ARCH_CLPS711X
313 select FB_CFB_FILLRECT 314 select FB_CFB_FILLRECT
314 select FB_CFB_COPYAREA 315 select FB_CFB_COPYAREA
315 select FB_CFB_IMAGEBLIT 316 select FB_CFB_IMAGEBLIT
317
318config FB_CLPS711X
319 tristate "CLPS711X LCD support"
320 depends on FB && (ARCH_CLPS711X || COMPILE_TEST)
321 select FB_CLPS711X_OLD if ARCH_CLPS711X && !ARCH_MULTIPLATFORM
322 select BACKLIGHT_LCD_SUPPORT
323 select FB_MODE_HELPERS
324 select FB_SYS_FILLRECT
325 select FB_SYS_COPYAREA
326 select FB_SYS_IMAGEBLIT
327 select LCD_CLASS_DEVICE
328 select VIDEOMODE_HELPERS
316 help 329 help
317 Say Y to enable the Framebuffer driver for the CLPS7111 and 330 Say Y to enable the Framebuffer driver for the Cirrus Logic
318 EP7212 processors. 331 CLPS711X CPUs.
319 332
320config FB_SA1100 333config FB_SA1100
321 bool "SA-1100 LCD support" 334 bool "SA-1100 LCD support"
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 0b2090d2e52e..1979afffccfe 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -14,7 +14,8 @@ obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o
14# Hardware specific drivers go first 14# Hardware specific drivers go first
15obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o 15obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
16obj-$(CONFIG_FB_ARC) += arcfb.o 16obj-$(CONFIG_FB_ARC) += arcfb.o
17obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o 17obj-$(CONFIG_FB_CLPS711X) += clps711x-fb.o
18obj-$(CONFIG_FB_CLPS711X_OLD) += clps711xfb.o
18obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o 19obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
19obj-$(CONFIG_FB_GRVGA) += grvga.o 20obj-$(CONFIG_FB_GRVGA) += grvga.o
20obj-$(CONFIG_FB_PM2) += pm2fb.o 21obj-$(CONFIG_FB_PM2) += pm2fb.o
diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
index 14d6b3793e0a..beadd3edaa17 100644
--- a/drivers/video/fbdev/amba-clcd.c
+++ b/drivers/video/fbdev/amba-clcd.c
@@ -26,6 +26,13 @@
26#include <linux/amba/clcd.h> 26#include <linux/amba/clcd.h>
27#include <linux/clk.h> 27#include <linux/clk.h>
28#include <linux/hardirq.h> 28#include <linux/hardirq.h>
29#include <linux/dma-mapping.h>
30#include <linux/of.h>
31#include <linux/of_address.h>
32#include <linux/of_graph.h>
33#include <video/display_timing.h>
34#include <video/of_display_timing.h>
35#include <video/videomode.h>
29 36
30#include <asm/sizes.h> 37#include <asm/sizes.h>
31 38
@@ -543,6 +550,259 @@ static int clcdfb_register(struct clcd_fb *fb)
543 return ret; 550 return ret;
544} 551}
545 552
553#ifdef CONFIG_OF
554static int clcdfb_of_get_dpi_panel_mode(struct device_node *node,
555 struct fb_videomode *mode)
556{
557 int err;
558 struct display_timing timing;
559 struct videomode video;
560
561 err = of_get_display_timing(node, "panel-timing", &timing);
562 if (err)
563 return err;
564
565 videomode_from_timing(&timing, &video);
566
567 err = fb_videomode_from_videomode(&video, mode);
568 if (err)
569 return err;
570
571 return 0;
572}
573
574static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode)
575{
576 return snprintf(buf, size, "%ux%u@%u", mode->xres, mode->yres,
577 mode->refresh);
578}
579
580static int clcdfb_of_get_mode(struct device *dev, struct device_node *endpoint,
581 struct fb_videomode *mode)
582{
583 int err;
584 struct device_node *panel;
585 char *name;
586 int len;
587
588 panel = of_graph_get_remote_port_parent(endpoint);
589 if (!panel)
590 return -ENODEV;
591
592 /* Only directly connected DPI panels supported for now */
593 if (of_device_is_compatible(panel, "panel-dpi"))
594 err = clcdfb_of_get_dpi_panel_mode(panel, mode);
595 else
596 err = -ENOENT;
597 if (err)
598 return err;
599
600 len = clcdfb_snprintf_mode(NULL, 0, mode);
601 name = devm_kzalloc(dev, len + 1, GFP_KERNEL);
602 clcdfb_snprintf_mode(name, len + 1, mode);
603 mode->name = name;
604
605 return 0;
606}
607
608static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0)
609{
610 static struct {
611 unsigned int part;
612 u32 r0, g0, b0;
613 u32 caps;
614 } panels[] = {
615 { 0x110, 1, 7, 13, CLCD_CAP_5551 },
616 { 0x110, 0, 8, 16, CLCD_CAP_888 },
617 { 0x111, 4, 14, 20, CLCD_CAP_444 },
618 { 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 },
619 { 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 |
620 CLCD_CAP_565 },
621 { 0x111, 0, 8, 16, CLCD_CAP_444 | CLCD_CAP_5551 |
622 CLCD_CAP_565 | CLCD_CAP_888 },
623 };
624 int i;
625
626 /* Bypass pixel clock divider, data output on the falling edge */
627 fb->panel->tim2 = TIM2_BCD | TIM2_IPC;
628
629 /* TFT display, vert. comp. interrupt at the start of the back porch */
630 fb->panel->cntl |= CNTL_LCDTFT | CNTL_LCDVCOMP(1);
631
632 fb->panel->caps = 0;
633
634 /* Match the setup with known variants */
635 for (i = 0; i < ARRAY_SIZE(panels) && !fb->panel->caps; i++) {
636 if (amba_part(fb->dev) != panels[i].part)
637 continue;
638 if (g0 != panels[i].g0)
639 continue;
640 if (r0 == panels[i].r0 && b0 == panels[i].b0)
641 fb->panel->caps = panels[i].caps & CLCD_CAP_RGB;
642 if (r0 == panels[i].b0 && b0 == panels[i].r0)
643 fb->panel->caps = panels[i].caps & CLCD_CAP_BGR;
644 }
645
646 return fb->panel->caps ? 0 : -EINVAL;
647}
648
649static int clcdfb_of_init_display(struct clcd_fb *fb)
650{
651 struct device_node *endpoint;
652 int err;
653 u32 max_bandwidth;
654 u32 tft_r0b0g0[3];
655
656 fb->panel = devm_kzalloc(&fb->dev->dev, sizeof(*fb->panel), GFP_KERNEL);
657 if (!fb->panel)
658 return -ENOMEM;
659
660 endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL);
661 if (!endpoint)
662 return -ENODEV;
663
664 err = clcdfb_of_get_mode(&fb->dev->dev, endpoint, &fb->panel->mode);
665 if (err)
666 return err;
667
668 err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth",
669 &max_bandwidth);
670 if (!err)
671 fb->panel->bpp = 8 * max_bandwidth / (fb->panel->mode.xres *
672 fb->panel->mode.yres * fb->panel->mode.refresh);
673 else
674 fb->panel->bpp = 32;
675
676#ifdef CONFIG_CPU_BIG_ENDIAN
677 fb->panel->cntl |= CNTL_BEBO;
678#endif
679 fb->panel->width = -1;
680 fb->panel->height = -1;
681
682 if (of_property_read_u32_array(endpoint,
683 "arm,pl11x,tft-r0g0b0-pads",
684 tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) == 0)
685 return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0],
686 tft_r0b0g0[1], tft_r0b0g0[2]);
687
688 return -ENOENT;
689}
690
691static int clcdfb_of_vram_setup(struct clcd_fb *fb)
692{
693 int err;
694 struct device_node *memory;
695 u64 size;
696
697 err = clcdfb_of_init_display(fb);
698 if (err)
699 return err;
700
701 memory = of_parse_phandle(fb->dev->dev.of_node, "memory-region", 0);
702 if (!memory)
703 return -ENODEV;
704
705 fb->fb.screen_base = of_iomap(memory, 0);
706 if (!fb->fb.screen_base)
707 return -ENOMEM;
708
709 fb->fb.fix.smem_start = of_translate_address(memory,
710 of_get_address(memory, 0, &size, NULL));
711 fb->fb.fix.smem_len = size;
712
713 return 0;
714}
715
716static int clcdfb_of_vram_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
717{
718 unsigned long off, user_size, kernel_size;
719
720
721 off = vma->vm_pgoff << PAGE_SHIFT;
722 user_size = vma->vm_end - vma->vm_start;
723 kernel_size = fb->fb.fix.smem_len;
724
725 if (off >= kernel_size || user_size > (kernel_size - off))
726 return -ENXIO;
727
728 return remap_pfn_range(vma, vma->vm_start,
729 __phys_to_pfn(fb->fb.fix.smem_start) + vma->vm_pgoff,
730 user_size,
731 pgprot_writecombine(vma->vm_page_prot));
732}
733
734static void clcdfb_of_vram_remove(struct clcd_fb *fb)
735{
736 iounmap(fb->fb.screen_base);
737}
738
739static int clcdfb_of_dma_setup(struct clcd_fb *fb)
740{
741 unsigned long framesize;
742 dma_addr_t dma;
743 int err;
744
745 err = clcdfb_of_init_display(fb);
746 if (err)
747 return err;
748
749 framesize = fb->panel->mode.xres * fb->panel->mode.yres *
750 fb->panel->bpp / 8;
751 fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize,
752 &dma, GFP_KERNEL);
753 if (!fb->fb.screen_base)
754 return -ENOMEM;
755
756 fb->fb.fix.smem_start = dma;
757 fb->fb.fix.smem_len = framesize;
758
759 return 0;
760}
761
762static int clcdfb_of_dma_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
763{
764 return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base,
765 fb->fb.fix.smem_start, fb->fb.fix.smem_len);
766}
767
768static void clcdfb_of_dma_remove(struct clcd_fb *fb)
769{
770 dma_free_coherent(&fb->dev->dev, fb->fb.fix.smem_len,
771 fb->fb.screen_base, fb->fb.fix.smem_start);
772}
773
774static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
775{
776 struct clcd_board *board = devm_kzalloc(&dev->dev, sizeof(*board),
777 GFP_KERNEL);
778 struct device_node *node = dev->dev.of_node;
779
780 if (!board)
781 return NULL;
782
783 board->name = of_node_full_name(node);
784 board->caps = CLCD_CAP_ALL;
785 board->check = clcdfb_check;
786 board->decode = clcdfb_decode;
787 if (of_find_property(node, "memory-region", NULL)) {
788 board->setup = clcdfb_of_vram_setup;
789 board->mmap = clcdfb_of_vram_mmap;
790 board->remove = clcdfb_of_vram_remove;
791 } else {
792 board->setup = clcdfb_of_dma_setup;
793 board->mmap = clcdfb_of_dma_mmap;
794 board->remove = clcdfb_of_dma_remove;
795 }
796
797 return board;
798}
799#else
800static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
801{
802 return NULL;
803}
804#endif
805
546static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id) 806static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
547{ 807{
548 struct clcd_board *board = dev_get_platdata(&dev->dev); 808 struct clcd_board *board = dev_get_platdata(&dev->dev);
@@ -550,6 +810,9 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
550 int ret; 810 int ret;
551 811
552 if (!board) 812 if (!board)
813 board = clcdfb_of_get_board(dev);
814
815 if (!board)
553 return -EINVAL; 816 return -EINVAL;
554 817
555 ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); 818 ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
index d36e830d6fc6..92640d46770a 100644
--- a/drivers/video/fbdev/atmel_lcdfb.c
+++ b/drivers/video/fbdev/atmel_lcdfb.c
@@ -290,7 +290,7 @@ static void init_contrast(struct atmel_lcdfb_info *sinfo)
290 290
291 /* contrast pwm can be 'inverted' */ 291 /* contrast pwm can be 'inverted' */
292 if (pdata->lcdcon_pol_negative) 292 if (pdata->lcdcon_pol_negative)
293 contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE); 293 contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);
294 294
295 /* have some default contrast/backlight settings */ 295 /* have some default contrast/backlight settings */
296 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr); 296 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
@@ -1097,6 +1097,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
1097 pdata->lcd_wiring_mode = ret; 1097 pdata->lcd_wiring_mode = ret;
1098 1098
1099 pdata->lcdcon_is_backlight = of_property_read_bool(display_np, "atmel,lcdcon-backlight"); 1099 pdata->lcdcon_is_backlight = of_property_read_bool(display_np, "atmel,lcdcon-backlight");
1100 pdata->lcdcon_pol_negative = of_property_read_bool(display_np, "atmel,lcdcon-backlight-inverted");
1100 1101
1101 timings = of_get_display_timings(display_np); 1102 timings = of_get_display_timings(display_np);
1102 if (!timings) { 1103 if (!timings) {
diff --git a/drivers/video/fbdev/clps711x-fb.c b/drivers/video/fbdev/clps711x-fb.c
new file mode 100644
index 000000000000..49a7bb4ef02f
--- /dev/null
+++ b/drivers/video/fbdev/clps711x-fb.c
@@ -0,0 +1,397 @@
1/*
2 * Cirrus Logic CLPS711X FB driver
3 *
4 * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
5 * Based on driver by Russell King <rmk@arm.linux.org.uk>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/clk.h>
14#include <linux/fb.h>
15#include <linux/io.h>
16#include <linux/lcd.h>
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/platform_device.h>
20#include <linux/regmap.h>
21#include <linux/mfd/syscon.h>
22#include <linux/mfd/syscon/clps711x.h>
23#include <linux/regulator/consumer.h>
24#include <video/of_display_timing.h>
25
26#define CLPS711X_FB_NAME "clps711x-fb"
27#define CLPS711X_FB_BPP_MAX (4)
28
29/* Registers relative to LCDCON */
30#define CLPS711X_LCDCON (0x0000)
31# define LCDCON_GSEN BIT(30)
32# define LCDCON_GSMD BIT(31)
33#define CLPS711X_PALLSW (0x0280)
34#define CLPS711X_PALMSW (0x02c0)
35#define CLPS711X_FBADDR (0x0d40)
36
37struct clps711x_fb_info {
38 struct clk *clk;
39 void __iomem *base;
40 struct regmap *syscon;
41 resource_size_t buffsize;
42 struct fb_videomode mode;
43 struct regulator *lcd_pwr;
44 u32 ac_prescale;
45 bool cmap_invert;
46};
47
48static int clps711x_fb_setcolreg(u_int regno, u_int red, u_int green,
49 u_int blue, u_int transp, struct fb_info *info)
50{
51 struct clps711x_fb_info *cfb = info->par;
52 u32 level, mask, shift;
53
54 if (regno >= BIT(info->var.bits_per_pixel))
55 return -EINVAL;
56
57 shift = 4 * (regno & 7);
58 mask = 0xf << shift;
59 /* gray = 0.30*R + 0.58*G + 0.11*B */
60 level = (((red * 77 + green * 151 + blue * 28) >> 20) << shift) & mask;
61 if (cfb->cmap_invert)
62 level = 0xf - level;
63
64 regno = (regno < 8) ? CLPS711X_PALLSW : CLPS711X_PALMSW;
65
66 writel((readl(cfb->base + regno) & ~mask) | level, cfb->base + regno);
67
68 return 0;
69}
70
71static int clps711x_fb_check_var(struct fb_var_screeninfo *var,
72 struct fb_info *info)
73{
74 u32 val;
75
76 if (var->bits_per_pixel < 1 ||
77 var->bits_per_pixel > CLPS711X_FB_BPP_MAX)
78 return -EINVAL;
79
80 if (!var->pixclock)
81 return -EINVAL;
82
83 val = DIV_ROUND_UP(var->xres, 16) - 1;
84 if (val < 0x01 || val > 0x3f)
85 return -EINVAL;
86
87 val = DIV_ROUND_UP(var->yres * var->xres * var->bits_per_pixel, 128);
88 val--;
89 if (val < 0x001 || val > 0x1fff)
90 return -EINVAL;
91
92 var->transp.msb_right = 0;
93 var->transp.offset = 0;
94 var->transp.length = 0;
95 var->red.msb_right = 0;
96 var->red.offset = 0;
97 var->red.length = var->bits_per_pixel;
98 var->green = var->red;
99 var->blue = var->red;
100 var->grayscale = var->bits_per_pixel > 1;
101
102 return 0;
103}
104
105static int clps711x_fb_set_par(struct fb_info *info)
106{
107 struct clps711x_fb_info *cfb = info->par;
108 resource_size_t size;
109 u32 lcdcon, pps;
110
111 size = (info->var.xres * info->var.yres * info->var.bits_per_pixel) / 8;
112 if (size > cfb->buffsize)
113 return -EINVAL;
114
115 switch (info->var.bits_per_pixel) {
116 case 1:
117 info->fix.visual = FB_VISUAL_MONO01;
118 break;
119 case 2:
120 case 4:
121 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
122 break;
123 default:
124 return -EINVAL;
125 }
126
127 info->fix.line_length = info->var.xres * info->var.bits_per_pixel / 8;
128 info->fix.smem_len = size;
129
130 lcdcon = (info->var.xres * info->var.yres *
131 info->var.bits_per_pixel) / 128 - 1;
132 lcdcon |= ((info->var.xres / 16) - 1) << 13;
133 lcdcon |= (cfb->ac_prescale & 0x1f) << 25;
134
135 pps = clk_get_rate(cfb->clk) / (PICOS2KHZ(info->var.pixclock) * 1000);
136 if (pps)
137 pps--;
138 lcdcon |= (pps & 0x3f) << 19;
139
140 if (info->var.bits_per_pixel == 4)
141 lcdcon |= LCDCON_GSMD;
142 if (info->var.bits_per_pixel >= 2)
143 lcdcon |= LCDCON_GSEN;
144
145 /* LCDCON must only be changed while the LCD is disabled */
146 regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
147 writel(lcdcon, cfb->base + CLPS711X_LCDCON);
148 regmap_update_bits(cfb->syscon, SYSCON_OFFSET,
149 SYSCON1_LCDEN, SYSCON1_LCDEN);
150
151 return 0;
152}
153
154static int clps711x_fb_blank(int blank, struct fb_info *info)
155{
156 /* Return happy */
157 return 0;
158}
159
160static struct fb_ops clps711x_fb_ops = {
161 .owner = THIS_MODULE,
162 .fb_setcolreg = clps711x_fb_setcolreg,
163 .fb_check_var = clps711x_fb_check_var,
164 .fb_set_par = clps711x_fb_set_par,
165 .fb_blank = clps711x_fb_blank,
166 .fb_fillrect = sys_fillrect,
167 .fb_copyarea = sys_copyarea,
168 .fb_imageblit = sys_imageblit,
169};
170
171static int clps711x_lcd_check_fb(struct lcd_device *lcddev, struct fb_info *fi)
172{
173 struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
174
175 return (!fi || fi->par == cfb) ? 1 : 0;
176}
177
178static int clps711x_lcd_get_power(struct lcd_device *lcddev)
179{
180 struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
181
182 if (!IS_ERR_OR_NULL(cfb->lcd_pwr))
183 if (!regulator_is_enabled(cfb->lcd_pwr))
184 return FB_BLANK_NORMAL;
185
186 return FB_BLANK_UNBLANK;
187}
188
189static int clps711x_lcd_set_power(struct lcd_device *lcddev, int blank)
190{
191 struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
192
193 if (!IS_ERR_OR_NULL(cfb->lcd_pwr)) {
194 if (blank == FB_BLANK_UNBLANK) {
195 if (!regulator_is_enabled(cfb->lcd_pwr))
196 return regulator_enable(cfb->lcd_pwr);
197 } else {
198 if (regulator_is_enabled(cfb->lcd_pwr))
199 return regulator_disable(cfb->lcd_pwr);
200 }
201 }
202
203 return 0;
204}
205
206static struct lcd_ops clps711x_lcd_ops = {
207 .check_fb = clps711x_lcd_check_fb,
208 .get_power = clps711x_lcd_get_power,
209 .set_power = clps711x_lcd_set_power,
210};
211
212static int clps711x_fb_probe(struct platform_device *pdev)
213{
214 struct device *dev = &pdev->dev;
215 struct device_node *disp, *np = dev->of_node;
216 struct clps711x_fb_info *cfb;
217 struct lcd_device *lcd;
218 struct fb_info *info;
219 struct resource *res;
220 int ret = -ENOENT;
221 u32 val;
222
223 if (fb_get_options(CLPS711X_FB_NAME, NULL))
224 return -ENODEV;
225
226 info = framebuffer_alloc(sizeof(*cfb), dev);
227 if (!info)
228 return -ENOMEM;
229
230 cfb = info->par;
231 platform_set_drvdata(pdev, info);
232
233 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
234 if (!res)
235 goto out_fb_release;
236 cfb->base = devm_ioremap(dev, res->start, resource_size(res));
237 if (!cfb->base) {
238 ret = -ENOMEM;
239 goto out_fb_release;
240 }
241
242 info->fix.mmio_start = res->start;
243 info->fix.mmio_len = resource_size(res);
244
245 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
246 info->screen_base = devm_ioremap_resource(dev, res);
247 if (IS_ERR(info->screen_base)) {
248 ret = PTR_ERR(info->screen_base);
249 goto out_fb_release;
250 }
251
252 /* Physical address should be aligned to 256 MiB */
253 if (res->start & 0x0fffffff) {
254 ret = -EINVAL;
255 goto out_fb_release;
256 }
257
258 info->apertures = alloc_apertures(1);
259 if (!info->apertures) {
260 ret = -ENOMEM;
261 goto out_fb_release;
262 }
263
264 cfb->buffsize = resource_size(res);
265 info->fix.smem_start = res->start;
266 info->apertures->ranges[0].base = info->fix.smem_start;
267 info->apertures->ranges[0].size = cfb->buffsize;
268
269 cfb->clk = devm_clk_get(dev, NULL);
270 if (IS_ERR(cfb->clk)) {
271 ret = PTR_ERR(cfb->clk);
272 goto out_fb_release;
273 }
274
275 cfb->syscon =
276 syscon_regmap_lookup_by_compatible("cirrus,clps711x-syscon1");
277 if (IS_ERR(cfb->syscon)) {
278 ret = PTR_ERR(cfb->syscon);
279 goto out_fb_release;
280 }
281
282 disp = of_parse_phandle(np, "display", 0);
283 if (!disp) {
284 dev_err(&pdev->dev, "No display defined\n");
285 ret = -ENODATA;
286 goto out_fb_release;
287 }
288
289 ret = of_get_fb_videomode(disp, &cfb->mode, OF_USE_NATIVE_MODE);
290 if (ret)
291 goto out_fb_release;
292
293 of_property_read_u32(disp, "ac-prescale", &cfb->ac_prescale);
294 cfb->cmap_invert = of_property_read_bool(disp, "cmap-invert");
295
296 ret = of_property_read_u32(disp, "bits-per-pixel",
297 &info->var.bits_per_pixel);
298 if (ret)
299 goto out_fb_release;
300
301 /* Force disable LCD on any mismatch */
302 if (info->fix.smem_start != (readb(cfb->base + CLPS711X_FBADDR) << 28))
303 regmap_update_bits(cfb->syscon, SYSCON_OFFSET,
304 SYSCON1_LCDEN, 0);
305
306 ret = regmap_read(cfb->syscon, SYSCON_OFFSET, &val);
307 if (ret)
308 goto out_fb_release;
309
310 if (!(val & SYSCON1_LCDEN)) {
311 /* Setup start FB address */
312 writeb(info->fix.smem_start >> 28, cfb->base + CLPS711X_FBADDR);
313 /* Clean FB memory */
314 memset_io(info->screen_base, 0, cfb->buffsize);
315 }
316
317 cfb->lcd_pwr = devm_regulator_get(dev, "lcd");
318 if (PTR_ERR(cfb->lcd_pwr) == -EPROBE_DEFER) {
319 ret = -EPROBE_DEFER;
320 goto out_fb_release;
321 }
322
323 info->fbops = &clps711x_fb_ops;
324 info->flags = FBINFO_DEFAULT;
325 info->var.activate = FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
326 info->var.height = -1;
327 info->var.width = -1;
328 info->var.vmode = FB_VMODE_NONINTERLACED;
329 info->fix.type = FB_TYPE_PACKED_PIXELS;
330 info->fix.accel = FB_ACCEL_NONE;
331 strlcpy(info->fix.id, CLPS711X_FB_NAME, sizeof(info->fix.id));
332 fb_videomode_to_var(&info->var, &cfb->mode);
333
334 ret = fb_alloc_cmap(&info->cmap, BIT(CLPS711X_FB_BPP_MAX), 0);
335 if (ret)
336 goto out_fb_release;
337
338 ret = fb_set_var(info, &info->var);
339 if (ret)
340 goto out_fb_dealloc_cmap;
341
342 ret = register_framebuffer(info);
343 if (ret)
344 goto out_fb_dealloc_cmap;
345
346 lcd = devm_lcd_device_register(dev, "clps711x-lcd", dev, cfb,
347 &clps711x_lcd_ops);
348 if (!IS_ERR(lcd))
349 return 0;
350
351 ret = PTR_ERR(lcd);
352 unregister_framebuffer(info);
353
354out_fb_dealloc_cmap:
355 regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
356 fb_dealloc_cmap(&info->cmap);
357
358out_fb_release:
359 framebuffer_release(info);
360
361 return ret;
362}
363
364static int clps711x_fb_remove(struct platform_device *pdev)
365{
366 struct fb_info *info = platform_get_drvdata(pdev);
367 struct clps711x_fb_info *cfb = info->par;
368
369 regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
370
371 unregister_framebuffer(info);
372 fb_dealloc_cmap(&info->cmap);
373 framebuffer_release(info);
374
375 return 0;
376}
377
378static const struct of_device_id clps711x_fb_dt_ids[] = {
379 { .compatible = "cirrus,clps711x-fb", },
380 { }
381};
382MODULE_DEVICE_TABLE(of, clps711x_fb_dt_ids);
383
384static struct platform_driver clps711x_fb_driver = {
385 .driver = {
386 .name = CLPS711X_FB_NAME,
387 .owner = THIS_MODULE,
388 .of_match_table = clps711x_fb_dt_ids,
389 },
390 .probe = clps711x_fb_probe,
391 .remove = clps711x_fb_remove,
392};
393module_platform_driver(clps711x_fb_driver);
394
395MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
396MODULE_DESCRIPTION("Cirrus Logic CLPS711X FB driver");
397MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c
index a8484f768d04..788f6b37fce7 100644
--- a/drivers/video/fbdev/da8xx-fb.c
+++ b/drivers/video/fbdev/da8xx-fb.c
@@ -1447,18 +1447,15 @@ static int fb_probe(struct platform_device *device)
1447 da8xx_fb_fix.line_length - 1; 1447 da8xx_fb_fix.line_length - 1;
1448 1448
1449 /* allocate palette buffer */ 1449 /* allocate palette buffer */
1450 par->v_palette_base = dma_alloc_coherent(NULL, 1450 par->v_palette_base = dma_zalloc_coherent(NULL, PALETTE_SIZE,
1451 PALETTE_SIZE, 1451 (resource_size_t *)&par->p_palette_base,
1452 (resource_size_t *) 1452 GFP_KERNEL | GFP_DMA);
1453 &par->p_palette_base,
1454 GFP_KERNEL | GFP_DMA);
1455 if (!par->v_palette_base) { 1453 if (!par->v_palette_base) {
1456 dev_err(&device->dev, 1454 dev_err(&device->dev,
1457 "GLCD: kmalloc for palette buffer failed\n"); 1455 "GLCD: kmalloc for palette buffer failed\n");
1458 ret = -EINVAL; 1456 ret = -EINVAL;
1459 goto err_release_fb_mem; 1457 goto err_release_fb_mem;
1460 } 1458 }
1461 memset(par->v_palette_base, 0, PALETTE_SIZE);
1462 1459
1463 par->irq = platform_get_irq(device, 0); 1460 par->irq = platform_get_irq(device, 0);
1464 if (par->irq < 0) { 1461 if (par->irq < 0) {
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index e23392ec5af3..569e7562fa3d 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -224,6 +224,11 @@ struct hvfb_par {
224 u32 pseudo_palette[16]; 224 u32 pseudo_palette[16];
225 u8 init_buf[MAX_VMBUS_PKT_SIZE]; 225 u8 init_buf[MAX_VMBUS_PKT_SIZE];
226 u8 recv_buf[MAX_VMBUS_PKT_SIZE]; 226 u8 recv_buf[MAX_VMBUS_PKT_SIZE];
227
228 /* If true, the VSC notifies the VSP on every framebuffer change */
229 bool synchronous_fb;
230
231 struct notifier_block hvfb_panic_nb;
227}; 232};
228 233
229static uint screen_width = HVFB_WIDTH; 234static uint screen_width = HVFB_WIDTH;
@@ -532,6 +537,19 @@ static void hvfb_update_work(struct work_struct *w)
532 schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY); 537 schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY);
533} 538}
534 539
540static int hvfb_on_panic(struct notifier_block *nb,
541 unsigned long e, void *p)
542{
543 struct hvfb_par *par;
544 struct fb_info *info;
545
546 par = container_of(nb, struct hvfb_par, hvfb_panic_nb);
547 par->synchronous_fb = true;
548 info = par->info;
549 synthvid_update(info);
550
551 return NOTIFY_DONE;
552}
535 553
536/* Framebuffer operation handlers */ 554/* Framebuffer operation handlers */
537 555
@@ -582,14 +600,44 @@ static int hvfb_blank(int blank, struct fb_info *info)
582 return 1; /* get fb_blank to set the colormap to all black */ 600 return 1; /* get fb_blank to set the colormap to all black */
583} 601}
584 602
603static void hvfb_cfb_fillrect(struct fb_info *p,
604 const struct fb_fillrect *rect)
605{
606 struct hvfb_par *par = p->par;
607
608 cfb_fillrect(p, rect);
609 if (par->synchronous_fb)
610 synthvid_update(p);
611}
612
613static void hvfb_cfb_copyarea(struct fb_info *p,
614 const struct fb_copyarea *area)
615{
616 struct hvfb_par *par = p->par;
617
618 cfb_copyarea(p, area);
619 if (par->synchronous_fb)
620 synthvid_update(p);
621}
622
623static void hvfb_cfb_imageblit(struct fb_info *p,
624 const struct fb_image *image)
625{
626 struct hvfb_par *par = p->par;
627
628 cfb_imageblit(p, image);
629 if (par->synchronous_fb)
630 synthvid_update(p);
631}
632
585static struct fb_ops hvfb_ops = { 633static struct fb_ops hvfb_ops = {
586 .owner = THIS_MODULE, 634 .owner = THIS_MODULE,
587 .fb_check_var = hvfb_check_var, 635 .fb_check_var = hvfb_check_var,
588 .fb_set_par = hvfb_set_par, 636 .fb_set_par = hvfb_set_par,
589 .fb_setcolreg = hvfb_setcolreg, 637 .fb_setcolreg = hvfb_setcolreg,
590 .fb_fillrect = cfb_fillrect, 638 .fb_fillrect = hvfb_cfb_fillrect,
591 .fb_copyarea = cfb_copyarea, 639 .fb_copyarea = hvfb_cfb_copyarea,
592 .fb_imageblit = cfb_imageblit, 640 .fb_imageblit = hvfb_cfb_imageblit,
593 .fb_blank = hvfb_blank, 641 .fb_blank = hvfb_blank,
594}; 642};
595 643
@@ -801,6 +849,11 @@ static int hvfb_probe(struct hv_device *hdev,
801 849
802 par->fb_ready = true; 850 par->fb_ready = true;
803 851
852 par->synchronous_fb = false;
853 par->hvfb_panic_nb.notifier_call = hvfb_on_panic;
854 atomic_notifier_chain_register(&panic_notifier_list,
855 &par->hvfb_panic_nb);
856
804 return 0; 857 return 0;
805 858
806error: 859error:
@@ -820,6 +873,9 @@ static int hvfb_remove(struct hv_device *hdev)
820 struct fb_info *info = hv_get_drvdata(hdev); 873 struct fb_info *info = hv_get_drvdata(hdev);
821 struct hvfb_par *par = info->par; 874 struct hvfb_par *par = info->par;
822 875
876 atomic_notifier_chain_unregister(&panic_notifier_list,
877 &par->hvfb_panic_nb);
878
823 par->update = false; 879 par->update = false;
824 par->fb_ready = false; 880 par->fb_ready = false;
825 881
diff --git a/drivers/video/fbdev/mbx/mbxfb.c b/drivers/video/fbdev/mbx/mbxfb.c
index 2bd52ed8832c..698df9543e30 100644
--- a/drivers/video/fbdev/mbx/mbxfb.c
+++ b/drivers/video/fbdev/mbx/mbxfb.c
@@ -628,14 +628,14 @@ static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd,
628 case MBXFB_IOCS_PLANEORDER: 628 case MBXFB_IOCS_PLANEORDER:
629 if (copy_from_user(&porder, (void __user*)arg, 629 if (copy_from_user(&porder, (void __user*)arg,
630 sizeof(struct mbxfb_planeorder))) 630 sizeof(struct mbxfb_planeorder)))
631 return -EFAULT; 631 return -EFAULT;
632 632
633 return mbxfb_ioctl_planeorder(&porder); 633 return mbxfb_ioctl_planeorder(&porder);
634 634
635 case MBXFB_IOCS_ALPHA: 635 case MBXFB_IOCS_ALPHA:
636 if (copy_from_user(&alpha, (void __user*)arg, 636 if (copy_from_user(&alpha, (void __user*)arg,
637 sizeof(struct mbxfb_alphaCtl))) 637 sizeof(struct mbxfb_alphaCtl)))
638 return -EFAULT; 638 return -EFAULT;
639 639
640 return mbxfb_ioctl_alphactl(&alpha); 640 return mbxfb_ioctl_alphactl(&alpha);
641 641
diff --git a/drivers/video/fbdev/msm/mddi_client_dummy.c b/drivers/video/fbdev/msm/mddi_client_dummy.c
index f1b0dfcc9717..cdb8f69a5d88 100644
--- a/drivers/video/fbdev/msm/mddi_client_dummy.c
+++ b/drivers/video/fbdev/msm/mddi_client_dummy.c
@@ -15,6 +15,7 @@
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 */ 16 */
17 17
18#include <linux/device.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/kernel.h> 21#include <linux/kernel.h>
@@ -51,8 +52,7 @@ static int mddi_dummy_probe(struct platform_device *pdev)
51{ 52{
52 struct msm_mddi_client_data *client_data = pdev->dev.platform_data; 53 struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
53 struct panel_info *panel = 54 struct panel_info *panel =
54 kzalloc(sizeof(struct panel_info), GFP_KERNEL); 55 devm_kzalloc(&pdev->dev, sizeof(struct panel_info), GFP_KERNEL);
55 int ret;
56 if (!panel) 56 if (!panel)
57 return -ENOMEM; 57 return -ENOMEM;
58 platform_set_drvdata(pdev, panel); 58 platform_set_drvdata(pdev, panel);
@@ -67,24 +67,11 @@ static int mddi_dummy_probe(struct platform_device *pdev)
67 client_data->fb_resource, 1); 67 client_data->fb_resource, 1);
68 panel->panel_data.fb_data = client_data->private_client_data; 68 panel->panel_data.fb_data = client_data->private_client_data;
69 panel->pdev.dev.platform_data = &panel->panel_data; 69 panel->pdev.dev.platform_data = &panel->panel_data;
70 ret = platform_device_register(&panel->pdev); 70 return platform_device_register(&panel->pdev);
71 if (ret) {
72 kfree(panel);
73 return ret;
74 }
75 return 0;
76}
77
78static int mddi_dummy_remove(struct platform_device *pdev)
79{
80 struct panel_info *panel = platform_get_drvdata(pdev);
81 kfree(panel);
82 return 0;
83} 71}
84 72
85static struct platform_driver mddi_client_dummy = { 73static struct platform_driver mddi_client_dummy = {
86 .probe = mddi_dummy_probe, 74 .probe = mddi_dummy_probe,
87 .remove = mddi_dummy_remove,
88 .driver = { .name = "mddi_c_dummy" }, 75 .driver = { .name = "mddi_c_dummy" },
89}; 76};
90 77
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
index 4420ccb69aa9..131c6e260898 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
@@ -262,6 +262,23 @@ static int hdmic_audio_config(struct omap_dss_device *dssdev,
262 return 0; 262 return 0;
263} 263}
264 264
265static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode)
266{
267 struct panel_drv_data *ddata = to_panel_data(dssdev);
268 struct omap_dss_device *in = ddata->in;
269
270 return in->ops.hdmi->set_hdmi_mode(in, hdmi_mode);
271}
272
273static int hdmic_set_infoframe(struct omap_dss_device *dssdev,
274 const struct hdmi_avi_infoframe *avi)
275{
276 struct panel_drv_data *ddata = to_panel_data(dssdev);
277 struct omap_dss_device *in = ddata->in;
278
279 return in->ops.hdmi->set_infoframe(in, avi);
280}
281
265static struct omap_dss_driver hdmic_driver = { 282static struct omap_dss_driver hdmic_driver = {
266 .connect = hdmic_connect, 283 .connect = hdmic_connect,
267 .disconnect = hdmic_disconnect, 284 .disconnect = hdmic_disconnect,
@@ -277,6 +294,8 @@ static struct omap_dss_driver hdmic_driver = {
277 294
278 .read_edid = hdmic_read_edid, 295 .read_edid = hdmic_read_edid,
279 .detect = hdmic_detect, 296 .detect = hdmic_detect,
297 .set_hdmi_mode = hdmic_set_hdmi_mode,
298 .set_hdmi_infoframe = hdmic_set_infoframe,
280 299
281 .audio_enable = hdmic_audio_enable, 300 .audio_enable = hdmic_audio_enable,
282 .audio_disable = hdmic_audio_disable, 301 .audio_disable = hdmic_audio_disable,
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
index 7e33686171e3..c891d8f84cb2 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
@@ -242,6 +242,24 @@ static int tpd_audio_config(struct omap_dss_device *dssdev,
242 return in->ops.hdmi->audio_config(in, audio); 242 return in->ops.hdmi->audio_config(in, audio);
243} 243}
244 244
245static int tpd_set_infoframe(struct omap_dss_device *dssdev,
246 const struct hdmi_avi_infoframe *avi)
247{
248 struct panel_drv_data *ddata = to_panel_data(dssdev);
249 struct omap_dss_device *in = ddata->in;
250
251 return in->ops.hdmi->set_infoframe(in, avi);
252}
253
254static int tpd_set_hdmi_mode(struct omap_dss_device *dssdev,
255 bool hdmi_mode)
256{
257 struct panel_drv_data *ddata = to_panel_data(dssdev);
258 struct omap_dss_device *in = ddata->in;
259
260 return in->ops.hdmi->set_hdmi_mode(in, hdmi_mode);
261}
262
245static const struct omapdss_hdmi_ops tpd_hdmi_ops = { 263static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
246 .connect = tpd_connect, 264 .connect = tpd_connect,
247 .disconnect = tpd_disconnect, 265 .disconnect = tpd_disconnect,
@@ -255,6 +273,8 @@ static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
255 273
256 .read_edid = tpd_read_edid, 274 .read_edid = tpd_read_edid,
257 .detect = tpd_detect, 275 .detect = tpd_detect,
276 .set_infoframe = tpd_set_infoframe,
277 .set_hdmi_mode = tpd_set_hdmi_mode,
258 278
259 .audio_enable = tpd_audio_enable, 279 .audio_enable = tpd_audio_enable,
260 .audio_disable = tpd_audio_disable, 280 .audio_disable = tpd_audio_disable,
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
index c7ba4d8b928a..617f8d2f5127 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
@@ -817,6 +817,10 @@ static int acx565akm_probe(struct spi_device *spi)
817 817
818 bldev = backlight_device_register("acx565akm", &ddata->spi->dev, 818 bldev = backlight_device_register("acx565akm", &ddata->spi->dev,
819 ddata, &acx565akm_bl_ops, &props); 819 ddata, &acx565akm_bl_ops, &props);
820 if (IS_ERR(bldev)) {
821 r = PTR_ERR(bldev);
822 goto err_reg_bl;
823 }
820 ddata->bl_dev = bldev; 824 ddata->bl_dev = bldev;
821 if (ddata->has_cabc) { 825 if (ddata->has_cabc) {
822 r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group); 826 r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group);
@@ -862,6 +866,7 @@ err_reg:
862 sysfs_remove_group(&bldev->dev.kobj, &bldev_attr_group); 866 sysfs_remove_group(&bldev->dev.kobj, &bldev_attr_group);
863err_sysfs: 867err_sysfs:
864 backlight_device_unregister(bldev); 868 backlight_device_unregister(bldev);
869err_reg_bl:
865err_detect: 870err_detect:
866err_gpio: 871err_gpio:
867 omap_dss_put_device(ddata->in); 872 omap_dss_put_device(ddata->in);
diff --git a/drivers/video/fbdev/omap2/dss/Kconfig b/drivers/video/fbdev/omap2/dss/Kconfig
index 285bcd103dce..3d5eb6c36c22 100644
--- a/drivers/video/fbdev/omap2/dss/Kconfig
+++ b/drivers/video/fbdev/omap2/dss/Kconfig
@@ -5,6 +5,7 @@ menuconfig OMAP2_DSS
5 tristate "OMAP2+ Display Subsystem support" 5 tristate "OMAP2+ Display Subsystem support"
6 select VIDEOMODE_HELPERS 6 select VIDEOMODE_HELPERS
7 select OMAP2_DSS_INIT 7 select OMAP2_DSS_INIT
8 select HDMI
8 help 9 help
9 OMAP2+ Display Subsystem support. 10 OMAP2+ Display Subsystem support.
10 11
diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 7aa33b0f4a1f..be053aa80880 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -2879,19 +2879,24 @@ static bool _dispc_mgr_pclk_ok(enum omap_channel channel,
2879bool dispc_mgr_timings_ok(enum omap_channel channel, 2879bool dispc_mgr_timings_ok(enum omap_channel channel,
2880 const struct omap_video_timings *timings) 2880 const struct omap_video_timings *timings)
2881{ 2881{
2882 bool timings_ok; 2882 if (!_dispc_mgr_size_ok(timings->x_res, timings->y_res))
2883 2883 return false;
2884 timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
2885 2884
2886 timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixelclock); 2885 if (!_dispc_mgr_pclk_ok(channel, timings->pixelclock))
2886 return false;
2887 2887
2888 if (dss_mgr_is_lcd(channel)) { 2888 if (dss_mgr_is_lcd(channel)) {
2889 timings_ok &= _dispc_lcd_timings_ok(timings->hsw, timings->hfp, 2889 /* TODO: OMAP4+ supports interlace for LCD outputs */
2890 if (timings->interlace)
2891 return false;
2892
2893 if (!_dispc_lcd_timings_ok(timings->hsw, timings->hfp,
2890 timings->hbp, timings->vsw, timings->vfp, 2894 timings->hbp, timings->vsw, timings->vfp,
2891 timings->vbp); 2895 timings->vbp))
2896 return false;
2892 } 2897 }
2893 2898
2894 return timings_ok; 2899 return true;
2895} 2900}
2896 2901
2897static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, 2902static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
@@ -3257,13 +3262,10 @@ static void dispc_dump_regs(struct seq_file *s)
3257 if (i == OMAP_DSS_CHANNEL_DIGIT) 3262 if (i == OMAP_DSS_CHANNEL_DIGIT)
3258 continue; 3263 continue;
3259 3264
3260 DUMPREG(i, DISPC_DEFAULT_COLOR);
3261 DUMPREG(i, DISPC_TRANS_COLOR);
3262 DUMPREG(i, DISPC_TIMING_H); 3265 DUMPREG(i, DISPC_TIMING_H);
3263 DUMPREG(i, DISPC_TIMING_V); 3266 DUMPREG(i, DISPC_TIMING_V);
3264 DUMPREG(i, DISPC_POL_FREQ); 3267 DUMPREG(i, DISPC_POL_FREQ);
3265 DUMPREG(i, DISPC_DIVISORo); 3268 DUMPREG(i, DISPC_DIVISORo);
3266 DUMPREG(i, DISPC_SIZE_MGR);
3267 3269
3268 DUMPREG(i, DISPC_DATA_CYCLE1); 3270 DUMPREG(i, DISPC_DATA_CYCLE1);
3269 DUMPREG(i, DISPC_DATA_CYCLE2); 3271 DUMPREG(i, DISPC_DATA_CYCLE2);
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 4755a34a5422..56b92444c54f 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -5658,18 +5658,11 @@ err_runtime_get:
5658 return r; 5658 return r;
5659} 5659}
5660 5660
5661static int dsi_unregister_child(struct device *dev, void *data)
5662{
5663 struct platform_device *pdev = to_platform_device(dev);
5664 platform_device_unregister(pdev);
5665 return 0;
5666}
5667
5668static int __exit omap_dsihw_remove(struct platform_device *dsidev) 5661static int __exit omap_dsihw_remove(struct platform_device *dsidev)
5669{ 5662{
5670 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 5663 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
5671 5664
5672 device_for_each_child(&dsidev->dev, NULL, dsi_unregister_child); 5665 of_platform_depopulate(&dsidev->dev);
5673 5666
5674 WARN_ON(dsi->scp_clk_refcount > 0); 5667 WARN_ON(dsi->scp_clk_refcount > 0);
5675 5668
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h
index fbee07816337..262771b9b76b 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -22,6 +22,7 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/hdmi.h>
25#include <video/omapdss.h> 26#include <video/omapdss.h>
26 27
27#include "dss.h" 28#include "dss.h"
@@ -142,7 +143,7 @@ enum hdmi_audio_samples_perword {
142 HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1 143 HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1
143}; 144};
144 145
145enum hdmi_audio_sample_size { 146enum hdmi_audio_sample_size_omap {
146 HDMI_AUDIO_SAMPLE_16BITS = 0, 147 HDMI_AUDIO_SAMPLE_16BITS = 0,
147 HDMI_AUDIO_SAMPLE_24BITS = 1 148 HDMI_AUDIO_SAMPLE_24BITS = 1
148}; 149};
@@ -178,59 +179,6 @@ enum hdmi_audio_mclk_mode {
178 HDMI_AUDIO_MCLK_192FS = 7 179 HDMI_AUDIO_MCLK_192FS = 7
179}; 180};
180 181
181/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */
182enum hdmi_core_infoframe {
183 HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
184 HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
185 HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2,
186 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0,
187 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1,
188 HDMI_INFOFRAME_AVI_DB1B_NO = 0,
189 HDMI_INFOFRAME_AVI_DB1B_VERT = 1,
190 HDMI_INFOFRAME_AVI_DB1B_HORI = 2,
191 HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3,
192 HDMI_INFOFRAME_AVI_DB1S_0 = 0,
193 HDMI_INFOFRAME_AVI_DB1S_1 = 1,
194 HDMI_INFOFRAME_AVI_DB1S_2 = 2,
195 HDMI_INFOFRAME_AVI_DB2C_NO = 0,
196 HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1,
197 HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2,
198 HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3,
199 HDMI_INFOFRAME_AVI_DB2M_NO = 0,
200 HDMI_INFOFRAME_AVI_DB2M_43 = 1,
201 HDMI_INFOFRAME_AVI_DB2M_169 = 2,
202 HDMI_INFOFRAME_AVI_DB2R_SAME = 8,
203 HDMI_INFOFRAME_AVI_DB2R_43 = 9,
204 HDMI_INFOFRAME_AVI_DB2R_169 = 10,
205 HDMI_INFOFRAME_AVI_DB2R_149 = 11,
206 HDMI_INFOFRAME_AVI_DB3ITC_NO = 0,
207 HDMI_INFOFRAME_AVI_DB3ITC_YES = 1,
208 HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0,
209 HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1,
210 HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0,
211 HDMI_INFOFRAME_AVI_DB3Q_LR = 1,
212 HDMI_INFOFRAME_AVI_DB3Q_FR = 2,
213 HDMI_INFOFRAME_AVI_DB3SC_NO = 0,
214 HDMI_INFOFRAME_AVI_DB3SC_HORI = 1,
215 HDMI_INFOFRAME_AVI_DB3SC_VERT = 2,
216 HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3,
217 HDMI_INFOFRAME_AVI_DB5PR_NO = 0,
218 HDMI_INFOFRAME_AVI_DB5PR_2 = 1,
219 HDMI_INFOFRAME_AVI_DB5PR_3 = 2,
220 HDMI_INFOFRAME_AVI_DB5PR_4 = 3,
221 HDMI_INFOFRAME_AVI_DB5PR_5 = 4,
222 HDMI_INFOFRAME_AVI_DB5PR_6 = 5,
223 HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
224 HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
225 HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
226 HDMI_INFOFRAME_AVI_DB5PR_10 = 9,
227};
228
229struct hdmi_cm {
230 int code;
231 int mode;
232};
233
234struct hdmi_video_format { 182struct hdmi_video_format {
235 enum hdmi_packing_mode packing_mode; 183 enum hdmi_packing_mode packing_mode;
236 u32 y_res; /* Line per panel */ 184 u32 y_res; /* Line per panel */
@@ -239,7 +187,8 @@ struct hdmi_video_format {
239 187
240struct hdmi_config { 188struct hdmi_config {
241 struct omap_video_timings timings; 189 struct omap_video_timings timings;
242 struct hdmi_cm cm; 190 struct hdmi_avi_infoframe infoframe;
191 enum hdmi_core_hdmi_dvi hdmi_dvi_mode;
243}; 192};
244 193
245/* HDMI PLL structure */ 194/* HDMI PLL structure */
@@ -260,7 +209,7 @@ struct hdmi_audio_format {
260 enum hdmi_audio_justify justification; 209 enum hdmi_audio_justify justification;
261 enum hdmi_audio_sample_order sample_order; 210 enum hdmi_audio_sample_order sample_order;
262 enum hdmi_audio_samples_perword samples_per_word; 211 enum hdmi_audio_samples_perword samples_per_word;
263 enum hdmi_audio_sample_size sample_size; 212 enum hdmi_audio_sample_size_omap sample_size;
264 enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end; 213 enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end;
265}; 214};
266 215
@@ -298,47 +247,6 @@ struct hdmi_core_audio_config {
298 bool en_spdif; 247 bool en_spdif;
299}; 248};
300 249
301/*
302 * Refer to section 8.2 in HDMI 1.3 specification for
303 * details about infoframe databytes
304 */
305struct hdmi_core_infoframe_avi {
306 /* Y0, Y1 rgb,yCbCr */
307 u8 db1_format;
308 /* A0 Active information Present */
309 u8 db1_active_info;
310 /* B0, B1 Bar info data valid */
311 u8 db1_bar_info_dv;
312 /* S0, S1 scan information */
313 u8 db1_scan_info;
314 /* C0, C1 colorimetry */
315 u8 db2_colorimetry;
316 /* M0, M1 Aspect ratio (4:3, 16:9) */
317 u8 db2_aspect_ratio;
318 /* R0...R3 Active format aspect ratio */
319 u8 db2_active_fmt_ar;
320 /* ITC IT content. */
321 u8 db3_itc;
322 /* EC0, EC1, EC2 Extended colorimetry */
323 u8 db3_ec;
324 /* Q1, Q0 Quantization range */
325 u8 db3_q_range;
326 /* SC1, SC0 Non-uniform picture scaling */
327 u8 db3_nup_scaling;
328 /* VIC0..6 Video format identification */
329 u8 db4_videocode;
330 /* PR0..PR3 Pixel repetition factor */
331 u8 db5_pixel_repeat;
332 /* Line number end of top bar */
333 u16 db6_7_line_eoftop;
334 /* Line number start of bottom bar */
335 u16 db8_9_line_sofbottom;
336 /* Pixel number end of left bar */
337 u16 db10_11_pixel_eofleft;
338 /* Pixel number start of right bar */
339 u16 db12_13_pixel_sofright;
340};
341
342struct hdmi_wp_data { 250struct hdmi_wp_data {
343 void __iomem *base; 251 void __iomem *base;
344}; 252};
@@ -358,8 +266,6 @@ struct hdmi_phy_data {
358 266
359struct hdmi_core_data { 267struct hdmi_core_data {
360 void __iomem *base; 268 void __iomem *base;
361
362 struct hdmi_core_infoframe_avi avi_cfg;
363}; 269};
364 270
365static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx, 271static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx,
@@ -425,9 +331,6 @@ int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy);
425int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes); 331int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
426 332
427/* HDMI common funcs */ 333/* HDMI common funcs */
428const struct hdmi_config *hdmi_default_timing(void);
429const struct hdmi_config *hdmi_get_timings(int mode, int code);
430struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing);
431int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep, 334int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
432 struct hdmi_phy_data *phy); 335 struct hdmi_phy_data *phy);
433 336
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 626aad2bef46..6a8550cf43e5 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -281,29 +281,11 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
281static void hdmi_display_set_timing(struct omap_dss_device *dssdev, 281static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
282 struct omap_video_timings *timings) 282 struct omap_video_timings *timings)
283{ 283{
284 struct hdmi_cm cm;
285 const struct hdmi_config *t;
286
287 mutex_lock(&hdmi.lock); 284 mutex_lock(&hdmi.lock);
288 285
289 cm = hdmi_get_code(timings); 286 hdmi.cfg.timings = *timings;
290 hdmi.cfg.cm = cm;
291
292 t = hdmi_get_timings(cm.mode, cm.code);
293 if (t != NULL) {
294 hdmi.cfg = *t;
295
296 dispc_set_tv_pclk(t->timings.pixelclock);
297 } else {
298 hdmi.cfg.timings = *timings;
299 hdmi.cfg.cm.code = 0;
300 hdmi.cfg.cm.mode = HDMI_DVI;
301
302 dispc_set_tv_pclk(timings->pixelclock);
303 }
304 287
305 DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ? 288 dispc_set_tv_pclk(timings->pixelclock);
306 "DVI" : "HDMI", hdmi.cfg.cm.code);
307 289
308 mutex_unlock(&hdmi.lock); 290 mutex_unlock(&hdmi.lock);
309} 291}
@@ -311,14 +293,7 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
311static void hdmi_display_get_timings(struct omap_dss_device *dssdev, 293static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
312 struct omap_video_timings *timings) 294 struct omap_video_timings *timings)
313{ 295{
314 const struct hdmi_config *cfg; 296 *timings = hdmi.cfg.timings;
315 struct hdmi_cm cm = hdmi.cfg.cm;
316
317 cfg = hdmi_get_timings(cm.mode, cm.code);
318 if (cfg == NULL)
319 cfg = hdmi_default_timing();
320
321 memcpy(timings, &cfg->timings, sizeof(cfg->timings));
322} 297}
323 298
324static void hdmi_dump_regs(struct seq_file *s) 299static void hdmi_dump_regs(struct seq_file *s)
@@ -516,7 +491,7 @@ static int hdmi_audio_enable(struct omap_dss_device *dssdev)
516 491
517 mutex_lock(&hdmi.lock); 492 mutex_lock(&hdmi.lock);
518 493
519 if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { 494 if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
520 r = -EPERM; 495 r = -EPERM;
521 goto err; 496 goto err;
522 } 497 }
@@ -554,7 +529,7 @@ static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
554 529
555 mutex_lock(&hdmi.lock); 530 mutex_lock(&hdmi.lock);
556 531
557 r = hdmi_mode_has_audio(hdmi.cfg.cm.mode); 532 r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode);
558 533
559 mutex_unlock(&hdmi.lock); 534 mutex_unlock(&hdmi.lock);
560 return r; 535 return r;
@@ -568,7 +543,7 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
568 543
569 mutex_lock(&hdmi.lock); 544 mutex_lock(&hdmi.lock);
570 545
571 if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { 546 if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
572 r = -EPERM; 547 r = -EPERM;
573 goto err; 548 goto err;
574 } 549 }
@@ -615,6 +590,20 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
615} 590}
616#endif 591#endif
617 592
593static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
594 const struct hdmi_avi_infoframe *avi)
595{
596 hdmi.cfg.infoframe = *avi;
597 return 0;
598}
599
600static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
601 bool hdmi_mode)
602{
603 hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
604 return 0;
605}
606
618static const struct omapdss_hdmi_ops hdmi_ops = { 607static const struct omapdss_hdmi_ops hdmi_ops = {
619 .connect = hdmi_connect, 608 .connect = hdmi_connect,
620 .disconnect = hdmi_disconnect, 609 .disconnect = hdmi_disconnect,
@@ -627,6 +616,8 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
627 .get_timings = hdmi_display_get_timings, 616 .get_timings = hdmi_display_get_timings,
628 617
629 .read_edid = hdmi_read_edid, 618 .read_edid = hdmi_read_edid,
619 .set_infoframe = hdmi_set_infoframe,
620 .set_hdmi_mode = hdmi_set_hdmi_mode,
630 621
631 .audio_enable = hdmi_audio_enable, 622 .audio_enable = hdmi_audio_enable,
632 .audio_disable = hdmi_audio_disable, 623 .audio_disable = hdmi_audio_disable,
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.c b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
index 8bde7b7e95ff..4ad39cfce254 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
@@ -197,9 +197,7 @@ int hdmi4_read_edid(struct hdmi_core_data *core, u8 *edid, int len)
197 return l; 197 return l;
198} 198}
199 199
200static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, 200static void hdmi_core_init(struct hdmi_core_video_config *video_cfg)
201 struct hdmi_core_infoframe_avi *avi_cfg,
202 struct hdmi_core_packet_enable_repeat *repeat_cfg)
203{ 201{
204 DSSDBG("Enter hdmi_core_init\n"); 202 DSSDBG("Enter hdmi_core_init\n");
205 203
@@ -210,35 +208,6 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
210 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE; 208 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
211 video_cfg->hdmi_dvi = HDMI_DVI; 209 video_cfg->hdmi_dvi = HDMI_DVI;
212 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK; 210 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
213
214 /* info frame */
215 avi_cfg->db1_format = 0;
216 avi_cfg->db1_active_info = 0;
217 avi_cfg->db1_bar_info_dv = 0;
218 avi_cfg->db1_scan_info = 0;
219 avi_cfg->db2_colorimetry = 0;
220 avi_cfg->db2_aspect_ratio = 0;
221 avi_cfg->db2_active_fmt_ar = 0;
222 avi_cfg->db3_itc = 0;
223 avi_cfg->db3_ec = 0;
224 avi_cfg->db3_q_range = 0;
225 avi_cfg->db3_nup_scaling = 0;
226 avi_cfg->db4_videocode = 0;
227 avi_cfg->db5_pixel_repeat = 0;
228 avi_cfg->db6_7_line_eoftop = 0;
229 avi_cfg->db8_9_line_sofbottom = 0;
230 avi_cfg->db10_11_pixel_eofleft = 0;
231 avi_cfg->db12_13_pixel_sofright = 0;
232
233 /* packet enable and repeat */
234 repeat_cfg->audio_pkt = 0;
235 repeat_cfg->audio_pkt_repeat = 0;
236 repeat_cfg->avi_infoframe = 0;
237 repeat_cfg->avi_infoframe_repeat = 0;
238 repeat_cfg->gen_cntrl_pkt = 0;
239 repeat_cfg->gen_cntrl_pkt_repeat = 0;
240 repeat_cfg->generic_pkt = 0;
241 repeat_cfg->generic_pkt_repeat = 0;
242} 211}
243 212
244static void hdmi_core_powerdown_disable(struct hdmi_core_data *core) 213static void hdmi_core_powerdown_disable(struct hdmi_core_data *core)
@@ -303,80 +272,22 @@ static void hdmi_core_video_config(struct hdmi_core_data *core,
303 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5); 272 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);
304} 273}
305 274
306static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core) 275static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core,
276 struct hdmi_avi_infoframe *frame)
307{ 277{
308 u32 val;
309 char sum = 0, checksum = 0;
310 void __iomem *av_base = hdmi_av_base(core); 278 void __iomem *av_base = hdmi_av_base(core);
311 struct hdmi_core_infoframe_avi info_avi = core->avi_cfg; 279 u8 data[HDMI_INFOFRAME_SIZE(AVI)];
312 280 int i;
313 sum += 0x82 + 0x002 + 0x00D;
314 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082);
315 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_VERS, 0x002);
316 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_LEN, 0x00D);
317
318 val = (info_avi.db1_format << 5) |
319 (info_avi.db1_active_info << 4) |
320 (info_avi.db1_bar_info_dv << 2) |
321 (info_avi.db1_scan_info);
322 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(0), val);
323 sum += val;
324
325 val = (info_avi.db2_colorimetry << 6) |
326 (info_avi.db2_aspect_ratio << 4) |
327 (info_avi.db2_active_fmt_ar);
328 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(1), val);
329 sum += val;
330
331 val = (info_avi.db3_itc << 7) |
332 (info_avi.db3_ec << 4) |
333 (info_avi.db3_q_range << 2) |
334 (info_avi.db3_nup_scaling);
335 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(2), val);
336 sum += val;
337
338 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(3),
339 info_avi.db4_videocode);
340 sum += info_avi.db4_videocode;
341
342 val = info_avi.db5_pixel_repeat;
343 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(4), val);
344 sum += val;
345
346 val = info_avi.db6_7_line_eoftop & 0x00FF;
347 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(5), val);
348 sum += val;
349
350 val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
351 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(6), val);
352 sum += val;
353
354 val = info_avi.db8_9_line_sofbottom & 0x00FF;
355 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(7), val);
356 sum += val;
357
358 val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
359 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(8), val);
360 sum += val;
361
362 val = info_avi.db10_11_pixel_eofleft & 0x00FF;
363 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(9), val);
364 sum += val;
365
366 val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
367 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(10), val);
368 sum += val;
369
370 val = info_avi.db12_13_pixel_sofright & 0x00FF;
371 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(11), val);
372 sum += val;
373
374 val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
375 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(12), val);
376 sum += val;
377 281
378 checksum = 0x100 - sum; 282 hdmi_avi_infoframe_pack(frame, data, sizeof(data));
379 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_CHSUM, checksum); 283
284 print_hex_dump_debug("AVI: ", DUMP_PREFIX_NONE, 16, 1, data,
285 HDMI_INFOFRAME_SIZE(AVI), false);
286
287 for (i = 0; i < sizeof(data); ++i) {
288 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_BASE + i * 4,
289 data[i]);
290 }
380} 291}
381 292
382static void hdmi_core_av_packet_config(struct hdmi_core_data *core, 293static void hdmi_core_av_packet_config(struct hdmi_core_data *core,
@@ -404,11 +315,10 @@ void hdmi4_configure(struct hdmi_core_data *core,
404 struct omap_video_timings video_timing; 315 struct omap_video_timings video_timing;
405 struct hdmi_video_format video_format; 316 struct hdmi_video_format video_format;
406 /* HDMI core */ 317 /* HDMI core */
407 struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg;
408 struct hdmi_core_video_config v_core_cfg; 318 struct hdmi_core_video_config v_core_cfg;
409 struct hdmi_core_packet_enable_repeat repeat_cfg; 319 struct hdmi_core_packet_enable_repeat repeat_cfg = { 0 };
410 320
411 hdmi_core_init(&v_core_cfg, avi_cfg, &repeat_cfg); 321 hdmi_core_init(&v_core_cfg);
412 322
413 hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg); 323 hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg);
414 324
@@ -431,44 +341,24 @@ void hdmi4_configure(struct hdmi_core_data *core,
431 hdmi_core_powerdown_disable(core); 341 hdmi_core_powerdown_disable(core);
432 342
433 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL; 343 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
434 v_core_cfg.hdmi_dvi = cfg->cm.mode; 344 v_core_cfg.hdmi_dvi = cfg->hdmi_dvi_mode;
435 345
436 hdmi_core_video_config(core, &v_core_cfg); 346 hdmi_core_video_config(core, &v_core_cfg);
437 347
438 /* release software reset in the core */ 348 /* release software reset in the core */
439 hdmi_core_swreset_release(core); 349 hdmi_core_swreset_release(core);
440 350
441 /* 351 if (cfg->hdmi_dvi_mode == HDMI_HDMI) {
442 * configure packet 352 hdmi_core_write_avi_infoframe(core, &cfg->infoframe);
443 * info frame video see doc CEA861-D page 65 353
444 */ 354 /* enable/repeat the infoframe */
445 avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; 355 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
446 avi_cfg->db1_active_info = 356 repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
447 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; 357 /* wakeup */
448 avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; 358 repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
449 avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; 359 repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
450 avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; 360 }
451 avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
452 avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
453 avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
454 avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
455 avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
456 avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
457 avi_cfg->db4_videocode = cfg->cm.code;
458 avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
459 avi_cfg->db6_7_line_eoftop = 0;
460 avi_cfg->db8_9_line_sofbottom = 0;
461 avi_cfg->db10_11_pixel_eofleft = 0;
462 avi_cfg->db12_13_pixel_sofright = 0;
463
464 hdmi_core_aux_infoframe_avi_config(core);
465 361
466 /* enable/repeat the infoframe */
467 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
468 repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
469 /* wakeup */
470 repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
471 repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
472 hdmi_core_av_packet_config(core, repeat_cfg); 362 hdmi_core_av_packet_config(core, repeat_cfg);
473} 363}
474 364
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.h b/drivers/video/fbdev/omap2/dss/hdmi4_core.h
index bb646896fa82..827909eb6c50 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4_core.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.h
@@ -145,6 +145,7 @@
145#define HDMI_CORE_AV_DPD 0xF4 145#define HDMI_CORE_AV_DPD 0xF4
146#define HDMI_CORE_AV_PB_CTRL1 0xF8 146#define HDMI_CORE_AV_PB_CTRL1 0xF8
147#define HDMI_CORE_AV_PB_CTRL2 0xFC 147#define HDMI_CORE_AV_PB_CTRL2 0xFC
148#define HDMI_CORE_AV_AVI_BASE 0x100
148#define HDMI_CORE_AV_AVI_TYPE 0x100 149#define HDMI_CORE_AV_AVI_TYPE 0x100
149#define HDMI_CORE_AV_AVI_VERS 0x104 150#define HDMI_CORE_AV_AVI_VERS 0x104
150#define HDMI_CORE_AV_AVI_LEN 0x108 151#define HDMI_CORE_AV_AVI_LEN 0x108
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c
index c468b9e1f295..32d02ec34d23 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5.c
@@ -299,29 +299,11 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
299static void hdmi_display_set_timing(struct omap_dss_device *dssdev, 299static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
300 struct omap_video_timings *timings) 300 struct omap_video_timings *timings)
301{ 301{
302 struct hdmi_cm cm;
303 const struct hdmi_config *t;
304
305 mutex_lock(&hdmi.lock); 302 mutex_lock(&hdmi.lock);
306 303
307 cm = hdmi_get_code(timings); 304 hdmi.cfg.timings = *timings;
308 hdmi.cfg.cm = cm;
309
310 t = hdmi_get_timings(cm.mode, cm.code);
311 if (t != NULL) {
312 hdmi.cfg = *t;
313
314 dispc_set_tv_pclk(t->timings.pixelclock);
315 } else {
316 hdmi.cfg.timings = *timings;
317 hdmi.cfg.cm.code = 0;
318 hdmi.cfg.cm.mode = HDMI_DVI;
319
320 dispc_set_tv_pclk(timings->pixelclock);
321 }
322 305
323 DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ? 306 dispc_set_tv_pclk(timings->pixelclock);
324 "DVI" : "HDMI", hdmi.cfg.cm.code);
325 307
326 mutex_unlock(&hdmi.lock); 308 mutex_unlock(&hdmi.lock);
327} 309}
@@ -329,14 +311,7 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
329static void hdmi_display_get_timings(struct omap_dss_device *dssdev, 311static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
330 struct omap_video_timings *timings) 312 struct omap_video_timings *timings)
331{ 313{
332 const struct hdmi_config *cfg; 314 *timings = hdmi.cfg.timings;
333 struct hdmi_cm cm = hdmi.cfg.cm;
334
335 cfg = hdmi_get_timings(cm.mode, cm.code);
336 if (cfg == NULL)
337 cfg = hdmi_default_timing();
338
339 memcpy(timings, &cfg->timings, sizeof(cfg->timings));
340} 315}
341 316
342static void hdmi_dump_regs(struct seq_file *s) 317static void hdmi_dump_regs(struct seq_file *s)
@@ -541,7 +516,7 @@ static int hdmi_audio_enable(struct omap_dss_device *dssdev)
541 516
542 mutex_lock(&hdmi.lock); 517 mutex_lock(&hdmi.lock);
543 518
544 if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { 519 if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
545 r = -EPERM; 520 r = -EPERM;
546 goto err; 521 goto err;
547 } 522 }
@@ -579,7 +554,7 @@ static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
579 554
580 mutex_lock(&hdmi.lock); 555 mutex_lock(&hdmi.lock);
581 556
582 r = hdmi_mode_has_audio(hdmi.cfg.cm.mode); 557 r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode);
583 558
584 mutex_unlock(&hdmi.lock); 559 mutex_unlock(&hdmi.lock);
585 return r; 560 return r;
@@ -593,7 +568,7 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
593 568
594 mutex_lock(&hdmi.lock); 569 mutex_lock(&hdmi.lock);
595 570
596 if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { 571 if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
597 r = -EPERM; 572 r = -EPERM;
598 goto err; 573 goto err;
599 } 574 }
@@ -640,6 +615,20 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
640} 615}
641#endif 616#endif
642 617
618static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
619 const struct hdmi_avi_infoframe *avi)
620{
621 hdmi.cfg.infoframe = *avi;
622 return 0;
623}
624
625static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
626 bool hdmi_mode)
627{
628 hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
629 return 0;
630}
631
643static const struct omapdss_hdmi_ops hdmi_ops = { 632static const struct omapdss_hdmi_ops hdmi_ops = {
644 .connect = hdmi_connect, 633 .connect = hdmi_connect,
645 .disconnect = hdmi_disconnect, 634 .disconnect = hdmi_disconnect,
@@ -652,6 +641,8 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
652 .get_timings = hdmi_display_get_timings, 641 .get_timings = hdmi_display_get_timings,
653 642
654 .read_edid = hdmi_read_edid, 643 .read_edid = hdmi_read_edid,
644 .set_infoframe = hdmi_set_infoframe,
645 .set_hdmi_mode = hdmi_set_hdmi_mode,
655 646
656 .audio_enable = hdmi_audio_enable, 647 .audio_enable = hdmi_audio_enable,
657 .audio_disable = hdmi_audio_disable, 648 .audio_disable = hdmi_audio_disable,
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.c b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
index 7528c7a42aa5..83acbf7a8c89 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
@@ -290,7 +290,6 @@ void hdmi5_core_dump(struct hdmi_core_data *core, struct seq_file *s)
290} 290}
291 291
292static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg, 292static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg,
293 struct hdmi_core_infoframe_avi *avi_cfg,
294 struct hdmi_config *cfg) 293 struct hdmi_config *cfg)
295{ 294{
296 DSSDBG("hdmi_core_init\n"); 295 DSSDBG("hdmi_core_init\n");
@@ -312,27 +311,8 @@ static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg,
312 video_cfg->vblank_osc = 0; /* Always 0 - need to confirm */ 311 video_cfg->vblank_osc = 0; /* Always 0 - need to confirm */
313 video_cfg->vblank = cfg->timings.vsw + 312 video_cfg->vblank = cfg->timings.vsw +
314 cfg->timings.vfp + cfg->timings.vbp; 313 cfg->timings.vfp + cfg->timings.vbp;
315 video_cfg->v_fc_config.cm.mode = cfg->cm.mode; 314 video_cfg->v_fc_config.hdmi_dvi_mode = cfg->hdmi_dvi_mode;
316 video_cfg->v_fc_config.timings.interlace = cfg->timings.interlace; 315 video_cfg->v_fc_config.timings.interlace = cfg->timings.interlace;
317
318 /* info frame */
319 avi_cfg->db1_format = 0;
320 avi_cfg->db1_active_info = 0;
321 avi_cfg->db1_bar_info_dv = 0;
322 avi_cfg->db1_scan_info = 0;
323 avi_cfg->db2_colorimetry = 0;
324 avi_cfg->db2_aspect_ratio = 0;
325 avi_cfg->db2_active_fmt_ar = 0;
326 avi_cfg->db3_itc = 0;
327 avi_cfg->db3_ec = 0;
328 avi_cfg->db3_q_range = 0;
329 avi_cfg->db3_nup_scaling = 0;
330 avi_cfg->db4_videocode = 0;
331 avi_cfg->db5_pixel_repeat = 0;
332 avi_cfg->db6_7_line_eoftop = 0;
333 avi_cfg->db8_9_line_sofbottom = 0;
334 avi_cfg->db10_11_pixel_eofleft = 0;
335 avi_cfg->db12_13_pixel_sofright = 0;
336} 316}
337 317
338/* DSS_HDMI_CORE_VIDEO_CONFIG */ 318/* DSS_HDMI_CORE_VIDEO_CONFIG */
@@ -398,7 +378,7 @@ static void hdmi_core_video_config(struct hdmi_core_data *core,
398 378
399 /* select DVI mode */ 379 /* select DVI mode */
400 REG_FLD_MOD(base, HDMI_CORE_FC_INVIDCONF, 380 REG_FLD_MOD(base, HDMI_CORE_FC_INVIDCONF,
401 cfg->v_fc_config.cm.mode, 3, 3); 381 cfg->v_fc_config.hdmi_dvi_mode, 3, 3);
402} 382}
403 383
404static void hdmi_core_config_video_packetizer(struct hdmi_core_data *core) 384static void hdmi_core_config_video_packetizer(struct hdmi_core_data *core)
@@ -438,24 +418,60 @@ static void hdmi_core_config_video_sampler(struct hdmi_core_data *core)
438 REG_FLD_MOD(core->base, HDMI_CORE_TX_INVID0, video_mapping, 4, 0); 418 REG_FLD_MOD(core->base, HDMI_CORE_TX_INVID0, video_mapping, 4, 0);
439} 419}
440 420
441static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core) 421static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core,
422 struct hdmi_avi_infoframe *frame)
442{ 423{
443 void __iomem *base = core->base; 424 void __iomem *base = core->base;
444 struct hdmi_core_infoframe_avi avi = core->avi_cfg; 425 u8 data[HDMI_INFOFRAME_SIZE(AVI)];
445 426 u8 *ptr;
446 REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_format, 1, 0); 427 unsigned y, a, b, s;
447 REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_active_info, 6, 6); 428 unsigned c, m, r;
448 REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_bar_info_dv, 3, 2); 429 unsigned itc, ec, q, sc;
449 REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_scan_info, 5, 4); 430 unsigned vic;
450 REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_colorimetry, 7, 6); 431 unsigned yq, cn, pr;
451 REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_aspect_ratio, 5, 4); 432
452 REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_active_fmt_ar, 3, 0); 433 hdmi_avi_infoframe_pack(frame, data, sizeof(data));
453 REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_itc, 7, 7); 434
454 REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_ec, 6, 4); 435 print_hex_dump_debug("AVI: ", DUMP_PREFIX_NONE, 16, 1, data,
455 REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_q_range, 3, 2); 436 HDMI_INFOFRAME_SIZE(AVI), false);
456 REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_nup_scaling, 1, 0); 437
457 REG_FLD_MOD(base, HDMI_CORE_FC_AVIVID, avi.db4_videocode, 6, 0); 438 ptr = data + HDMI_INFOFRAME_HEADER_SIZE;
458 REG_FLD_MOD(base, HDMI_CORE_FC_PRCONF, avi.db5_pixel_repeat, 3, 0); 439
440 y = (ptr[0] >> 5) & 0x3;
441 a = (ptr[0] >> 4) & 0x1;
442 b = (ptr[0] >> 2) & 0x3;
443 s = (ptr[0] >> 0) & 0x3;
444
445 c = (ptr[1] >> 6) & 0x3;
446 m = (ptr[1] >> 4) & 0x3;
447 r = (ptr[1] >> 0) & 0x3;
448
449 itc = (ptr[2] >> 7) & 0x1;
450 ec = (ptr[2] >> 4) & 0x7;
451 q = (ptr[2] >> 2) & 0x3;
452 sc = (ptr[2] >> 0) & 0x3;
453
454 vic = ptr[3];
455
456 yq = (ptr[4] >> 6) & 0x3;
457 cn = (ptr[4] >> 4) & 0x3;
458 pr = (ptr[4] >> 0) & 0xf;
459
460 hdmi_write_reg(base, HDMI_CORE_FC_AVICONF0,
461 (a << 6) | (s << 4) | (b << 2) | (y << 0));
462
463 hdmi_write_reg(base, HDMI_CORE_FC_AVICONF1,
464 (c << 6) | (m << 4) | (r << 0));
465
466 hdmi_write_reg(base, HDMI_CORE_FC_AVICONF2,
467 (itc << 7) | (ec << 4) | (q << 2) | (sc << 0));
468
469 hdmi_write_reg(base, HDMI_CORE_FC_AVIVID, vic);
470
471 hdmi_write_reg(base, HDMI_CORE_FC_AVICONF3,
472 (yq << 2) | (cn << 0));
473
474 REG_FLD_MOD(base, HDMI_CORE_FC_PRCONF, pr, 3, 0);
459} 475}
460 476
461static void hdmi_core_csc_config(struct hdmi_core_data *core, 477static void hdmi_core_csc_config(struct hdmi_core_data *core,
@@ -497,10 +513,8 @@ static void hdmi_core_configure_range(struct hdmi_core_data *core)
497 513
498 /* support limited range with 24 bit color depth for now */ 514 /* support limited range with 24 bit color depth for now */
499 csc_coeff = csc_table_deepcolor[0]; 515 csc_coeff = csc_table_deepcolor[0];
500 core->avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_LR;
501 516
502 hdmi_core_csc_config(core, csc_coeff); 517 hdmi_core_csc_config(core, csc_coeff);
503 hdmi_core_aux_infoframe_avi_config(core);
504} 518}
505 519
506static void hdmi_core_enable_video_path(struct hdmi_core_data *core) 520static void hdmi_core_enable_video_path(struct hdmi_core_data *core)
@@ -591,11 +605,10 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
591 struct omap_video_timings video_timing; 605 struct omap_video_timings video_timing;
592 struct hdmi_video_format video_format; 606 struct hdmi_video_format video_format;
593 struct hdmi_core_vid_config v_core_cfg; 607 struct hdmi_core_vid_config v_core_cfg;
594 struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg;
595 608
596 hdmi_core_mask_interrupts(core); 609 hdmi_core_mask_interrupts(core);
597 610
598 hdmi_core_init(&v_core_cfg, avi_cfg, cfg); 611 hdmi_core_init(&v_core_cfg, cfg);
599 612
600 hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg); 613 hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg);
601 614
@@ -608,7 +621,9 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
608 621
609 hdmi_wp_video_config_interface(wp, &video_timing); 622 hdmi_wp_video_config_interface(wp, &video_timing);
610 623
624 /* support limited range with 24 bit color depth for now */
611 hdmi_core_configure_range(core); 625 hdmi_core_configure_range(core);
626 cfg->infoframe.quantization_range = HDMI_QUANTIZATION_RANGE_LIMITED;
612 627
613 /* 628 /*
614 * configure core video part, set software reset in the core 629 * configure core video part, set software reset in the core
@@ -621,29 +636,8 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
621 hdmi_core_config_csc(core); 636 hdmi_core_config_csc(core);
622 hdmi_core_config_video_sampler(core); 637 hdmi_core_config_video_sampler(core);
623 638
624 /* 639 if (cfg->hdmi_dvi_mode == HDMI_HDMI)
625 * configure packet info frame video see doc CEA861-D page 65 640 hdmi_core_write_avi_infoframe(core, &cfg->infoframe);
626 */
627 avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
628 avi_cfg->db1_active_info =
629 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
630 avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
631 avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
632 avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
633 avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
634 avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
635 avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
636 avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
637 avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
638 avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
639 avi_cfg->db4_videocode = cfg->cm.code;
640 avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
641 avi_cfg->db6_7_line_eoftop = 0;
642 avi_cfg->db8_9_line_sofbottom = 0;
643 avi_cfg->db10_11_pixel_eofleft = 0;
644 avi_cfg->db12_13_pixel_sofright = 0;
645
646 hdmi_core_aux_infoframe_avi_config(core);
647 641
648 hdmi_core_enable_video_path(core); 642 hdmi_core_enable_video_path(core);
649 643
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_common.c b/drivers/video/fbdev/omap2/dss/hdmi_common.c
index 9a2c39cf297f..7d5f1039de9f 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_common.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_common.c
@@ -1,18 +1,4 @@
1 1
2/*
3 * Logic for the below structure :
4 * user enters the CEA or VESA timings by specifying the HDMI/DVI code.
5 * There is a correspondence between CEA/VESA timing and code, please
6 * refer to section 6.3 in HDMI 1.3 specification for timing code.
7 *
8 * In the below structure, cea_vesa_timings corresponds to all OMAP4
9 * supported CEA and VESA timing values.code_cea corresponds to the CEA
10 * code, It is used to get the timing from cea_vesa_timing array.Similarly
11 * with code_vesa. Code_index is used for back mapping, that is once EDID
12 * is read from the TV, EDID is parsed to find the timing values and then
13 * map it to corresponding CEA or VESA index.
14 */
15
16#define DSS_SUBSYS_NAME "HDMI" 2#define DSS_SUBSYS_NAME "HDMI"
17 3
18#include <linux/kernel.h> 4#include <linux/kernel.h>
@@ -22,308 +8,6 @@
22 8
23#include "hdmi.h" 9#include "hdmi.h"
24 10
25static const struct hdmi_config cea_timings[] = {
26 {
27 { 640, 480, 25200000, 96, 16, 48, 2, 10, 33,
28 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
29 false, },
30 { 1, HDMI_HDMI },
31 },
32 {
33 { 720, 480, 27027000, 62, 16, 60, 6, 9, 30,
34 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
35 false, },
36 { 2, HDMI_HDMI },
37 },
38 {
39 { 1280, 720, 74250000, 40, 110, 220, 5, 5, 20,
40 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
41 false, },
42 { 4, HDMI_HDMI },
43 },
44 {
45 { 1920, 540, 74250000, 44, 88, 148, 5, 2, 15,
46 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
47 true, },
48 { 5, HDMI_HDMI },
49 },
50 {
51 { 1440, 240, 27027000, 124, 38, 114, 3, 4, 15,
52 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
53 true, },
54 { 6, HDMI_HDMI },
55 },
56 {
57 { 1920, 1080, 148500000, 44, 88, 148, 5, 4, 36,
58 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
59 false, },
60 { 16, HDMI_HDMI },
61 },
62 {
63 { 720, 576, 27000000, 64, 12, 68, 5, 5, 39,
64 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
65 false, },
66 { 17, HDMI_HDMI },
67 },
68 {
69 { 1280, 720, 74250000, 40, 440, 220, 5, 5, 20,
70 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
71 false, },
72 { 19, HDMI_HDMI },
73 },
74 {
75 { 1920, 540, 74250000, 44, 528, 148, 5, 2, 15,
76 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
77 true, },
78 { 20, HDMI_HDMI },
79 },
80 {
81 { 1440, 288, 27000000, 126, 24, 138, 3, 2, 19,
82 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
83 true, },
84 { 21, HDMI_HDMI },
85 },
86 {
87 { 1440, 576, 54000000, 128, 24, 136, 5, 5, 39,
88 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
89 false, },
90 { 29, HDMI_HDMI },
91 },
92 {
93 { 1920, 1080, 148500000, 44, 528, 148, 5, 4, 36,
94 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
95 false, },
96 { 31, HDMI_HDMI },
97 },
98 {
99 { 1920, 1080, 74250000, 44, 638, 148, 5, 4, 36,
100 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
101 false, },
102 { 32, HDMI_HDMI },
103 },
104 {
105 { 2880, 480, 108108000, 248, 64, 240, 6, 9, 30,
106 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
107 false, },
108 { 35, HDMI_HDMI },
109 },
110 {
111 { 2880, 576, 108000000, 256, 48, 272, 5, 5, 39,
112 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
113 false, },
114 { 37, HDMI_HDMI },
115 },
116};
117
118static const struct hdmi_config vesa_timings[] = {
119/* VESA From Here */
120 {
121 { 640, 480, 25175000, 96, 16, 48, 2, 11, 31,
122 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
123 false, },
124 { 4, HDMI_DVI },
125 },
126 {
127 { 800, 600, 40000000, 128, 40, 88, 4, 1, 23,
128 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
129 false, },
130 { 9, HDMI_DVI },
131 },
132 {
133 { 848, 480, 33750000, 112, 16, 112, 8, 6, 23,
134 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
135 false, },
136 { 0xE, HDMI_DVI },
137 },
138 {
139 { 1280, 768, 79500000, 128, 64, 192, 7, 3, 20,
140 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
141 false, },
142 { 0x17, HDMI_DVI },
143 },
144 {
145 { 1280, 800, 83500000, 128, 72, 200, 6, 3, 22,
146 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
147 false, },
148 { 0x1C, HDMI_DVI },
149 },
150 {
151 { 1360, 768, 85500000, 112, 64, 256, 6, 3, 18,
152 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
153 false, },
154 { 0x27, HDMI_DVI },
155 },
156 {
157 { 1280, 960, 108000000, 112, 96, 312, 3, 1, 36,
158 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
159 false, },
160 { 0x20, HDMI_DVI },
161 },
162 {
163 { 1280, 1024, 108000000, 112, 48, 248, 3, 1, 38,
164 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
165 false, },
166 { 0x23, HDMI_DVI },
167 },
168 {
169 { 1024, 768, 65000000, 136, 24, 160, 6, 3, 29,
170 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
171 false, },
172 { 0x10, HDMI_DVI },
173 },
174 {
175 { 1400, 1050, 121750000, 144, 88, 232, 4, 3, 32,
176 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
177 false, },
178 { 0x2A, HDMI_DVI },
179 },
180 {
181 { 1440, 900, 106500000, 152, 80, 232, 6, 3, 25,
182 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
183 false, },
184 { 0x2F, HDMI_DVI },
185 },
186 {
187 { 1680, 1050, 146250000, 176 , 104, 280, 6, 3, 30,
188 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
189 false, },
190 { 0x3A, HDMI_DVI },
191 },
192 {
193 { 1366, 768, 85500000, 143, 70, 213, 3, 3, 24,
194 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
195 false, },
196 { 0x51, HDMI_DVI },
197 },
198 {
199 { 1920, 1080, 148500000, 44, 148, 80, 5, 4, 36,
200 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
201 false, },
202 { 0x52, HDMI_DVI },
203 },
204 {
205 { 1280, 768, 68250000, 32, 48, 80, 7, 3, 12,
206 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
207 false, },
208 { 0x16, HDMI_DVI },
209 },
210 {
211 { 1400, 1050, 101000000, 32, 48, 80, 4, 3, 23,
212 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
213 false, },
214 { 0x29, HDMI_DVI },
215 },
216 {
217 { 1680, 1050, 119000000, 32, 48, 80, 6, 3, 21,
218 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
219 false, },
220 { 0x39, HDMI_DVI },
221 },
222 {
223 { 1280, 800, 79500000, 32, 48, 80, 6, 3, 14,
224 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
225 false, },
226 { 0x1B, HDMI_DVI },
227 },
228 {
229 { 1280, 720, 74250000, 40, 110, 220, 5, 5, 20,
230 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
231 false, },
232 { 0x55, HDMI_DVI },
233 },
234 {
235 { 1920, 1200, 154000000, 32, 48, 80, 6, 3, 26,
236 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
237 false, },
238 { 0x44, HDMI_DVI },
239 },
240};
241
242const struct hdmi_config *hdmi_default_timing(void)
243{
244 return &vesa_timings[0];
245}
246
247static const struct hdmi_config *hdmi_find_timing(int code,
248 const struct hdmi_config *timings_arr, int len)
249{
250 int i;
251
252 for (i = 0; i < len; i++) {
253 if (timings_arr[i].cm.code == code)
254 return &timings_arr[i];
255 }
256
257 return NULL;
258}
259
260const struct hdmi_config *hdmi_get_timings(int mode, int code)
261{
262 const struct hdmi_config *arr;
263 int len;
264
265 if (mode == HDMI_DVI) {
266 arr = vesa_timings;
267 len = ARRAY_SIZE(vesa_timings);
268 } else {
269 arr = cea_timings;
270 len = ARRAY_SIZE(cea_timings);
271 }
272
273 return hdmi_find_timing(code, arr, len);
274}
275
276static bool hdmi_timings_compare(struct omap_video_timings *timing1,
277 const struct omap_video_timings *timing2)
278{
279 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
280
281 if ((DIV_ROUND_CLOSEST(timing2->pixelclock, 1000000) ==
282 DIV_ROUND_CLOSEST(timing1->pixelclock, 1000000)) &&
283 (timing2->x_res == timing1->x_res) &&
284 (timing2->y_res == timing1->y_res)) {
285
286 timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp;
287 timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp;
288 timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
289 timing1_vsync = timing1->vfp + timing1->vsw + timing1->vbp;
290
291 DSSDBG("timing1_hsync = %d timing1_vsync = %d"\
292 "timing2_hsync = %d timing2_vsync = %d\n",
293 timing1_hsync, timing1_vsync,
294 timing2_hsync, timing2_vsync);
295
296 if ((timing1_hsync == timing2_hsync) &&
297 (timing1_vsync == timing2_vsync)) {
298 return true;
299 }
300 }
301 return false;
302}
303
304struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
305{
306 int i;
307 struct hdmi_cm cm = {-1};
308 DSSDBG("hdmi_get_code\n");
309
310 for (i = 0; i < ARRAY_SIZE(cea_timings); i++) {
311 if (hdmi_timings_compare(timing, &cea_timings[i].timings)) {
312 cm = cea_timings[i].cm;
313 goto end;
314 }
315 }
316 for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) {
317 if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) {
318 cm = vesa_timings[i].cm;
319 goto end;
320 }
321 }
322
323end:
324 return cm;
325}
326
327int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep, 11int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
328 struct hdmi_phy_data *phy) 12 struct hdmi_phy_data *phy)
329{ 13{
diff --git a/drivers/video/fbdev/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c
index 81af5a63e9e1..d68595dcc5fd 100644
--- a/drivers/video/fbdev/s3c2410fb.c
+++ b/drivers/video/fbdev/s3c2410fb.c
@@ -932,7 +932,7 @@ static int s3c24xxfb_probe(struct platform_device *pdev,
932 goto release_irq; 932 goto release_irq;
933 } 933 }
934 934
935 clk_enable(info->clk); 935 clk_prepare_enable(info->clk);
936 dprintk("got and enabled clock\n"); 936 dprintk("got and enabled clock\n");
937 937
938 usleep_range(1000, 1100); 938 usleep_range(1000, 1100);
@@ -996,7 +996,7 @@ static int s3c24xxfb_probe(struct platform_device *pdev,
996free_video_memory: 996free_video_memory:
997 s3c2410fb_unmap_video_memory(fbinfo); 997 s3c2410fb_unmap_video_memory(fbinfo);
998release_clock: 998release_clock:
999 clk_disable(info->clk); 999 clk_disable_unprepare(info->clk);
1000 clk_put(info->clk); 1000 clk_put(info->clk);
1001release_irq: 1001release_irq:
1002 free_irq(irq, info); 1002 free_irq(irq, info);
@@ -1038,7 +1038,7 @@ static int s3c2410fb_remove(struct platform_device *pdev)
1038 s3c2410fb_unmap_video_memory(fbinfo); 1038 s3c2410fb_unmap_video_memory(fbinfo);
1039 1039
1040 if (info->clk) { 1040 if (info->clk) {
1041 clk_disable(info->clk); 1041 clk_disable_unprepare(info->clk);
1042 clk_put(info->clk); 1042 clk_put(info->clk);
1043 info->clk = NULL; 1043 info->clk = NULL;
1044 } 1044 }
@@ -1070,7 +1070,7 @@ static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state)
1070 * before the clock goes off again (bjd) */ 1070 * before the clock goes off again (bjd) */
1071 1071
1072 usleep_range(1000, 1100); 1072 usleep_range(1000, 1100);
1073 clk_disable(info->clk); 1073 clk_disable_unprepare(info->clk);
1074 1074
1075 return 0; 1075 return 0;
1076} 1076}
@@ -1080,7 +1080,7 @@ static int s3c2410fb_resume(struct platform_device *dev)
1080 struct fb_info *fbinfo = platform_get_drvdata(dev); 1080 struct fb_info *fbinfo = platform_get_drvdata(dev);
1081 struct s3c2410fb_info *info = fbinfo->par; 1081 struct s3c2410fb_info *info = fbinfo->par;
1082 1082
1083 clk_enable(info->clk); 1083 clk_prepare_enable(info->clk);
1084 usleep_range(1000, 1100); 1084 usleep_range(1000, 1100);
1085 1085
1086 s3c2410fb_init_registers(fbinfo); 1086 s3c2410fb_init_registers(fbinfo);
diff --git a/drivers/video/fbdev/sis/init.c b/drivers/video/fbdev/sis/init.c
index bd40f5ecd901..dfe3eb769638 100644
--- a/drivers/video/fbdev/sis/init.c
+++ b/drivers/video/fbdev/sis/init.c
@@ -1511,7 +1511,7 @@ SiS_Get310DRAMType(struct SiS_Private *SiS_Pr)
1511 } else if(SiS_Pr->ChipType >= SIS_340) { 1511 } else if(SiS_Pr->ChipType >= SIS_340) {
1512 /* TODO */ 1512 /* TODO */
1513 data = 0; 1513 data = 0;
1514 } if(SiS_Pr->ChipType >= SIS_661) { 1514 } else if(SiS_Pr->ChipType >= SIS_661) {
1515 if(SiS_Pr->SiS_ROMNew) { 1515 if(SiS_Pr->SiS_ROMNew) {
1516 data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6); 1516 data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
1517 } else { 1517 } else {
diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c
index 22ad028bf123..3f12a2dd959a 100644
--- a/drivers/video/fbdev/sis/sis_main.c
+++ b/drivers/video/fbdev/sis/sis_main.c
@@ -1572,10 +1572,6 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1572 /* Adapt RGB settings */ 1572 /* Adapt RGB settings */
1573 sisfb_bpp_to_var(ivideo, var); 1573 sisfb_bpp_to_var(ivideo, var);
1574 1574
1575 /* Sanity check for offsets */
1576 if(var->xoffset < 0) var->xoffset = 0;
1577 if(var->yoffset < 0) var->yoffset = 0;
1578
1579 if(var->xres > var->xres_virtual) 1575 if(var->xres > var->xres_virtual)
1580 var->xres_virtual = var->xres; 1576 var->xres_virtual = var->xres;
1581 1577