aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 10:56:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 10:56:52 -0400
commit4cc4d24efce4672f9b0e7fa27963770ae602998f (patch)
treee69e7209db5500164eedb82c46ea657499b72287 /drivers/video
parentb81a618dcd3ea99de292dbe624f41ca68f464376 (diff)
parent56be1416453c31d32f984328b5193489ab63ffcf (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6: (140 commits) MAINTAINERS: de-orphan fbdev. MAINTAINERS: Add file pattern for fb dt bindings. video: Move sm501fb devicetree binding documentation to a better place. fbcon: fix situation where fbcon gets deinitialised and can't reinit. video, sm501: add OF binding to support SM501 video, sm501: add edid and commandline support video, sm501: add I/O functions for use on powerpc video: Fix EDID macros H_SYNC_WIDTH and H_SYNC_OFFSET fbcon: Bugfix soft cursor detection in Tile Blitting video: add missing framebuffer_release in error path video: metronomefb: add __devexit_p around reference to metronomefb_remove video: hecubafb: add __devexit_p around reference to hecubafb_remove drivers:video:aty:radeon_base Fix typo occationally to occasionally atmel_lcdfb: add fb_blank function atmel_lcdfb: implement inverted contrast pwm video: s3c-fb: return proper error if clk_get fails uvesafb,vesafb: create WC or WB PAT-entries video: ffb: fix ffb_probe error path radeonfb: Let hwmon driver probe the "monid" I2C bus fbdev: sh_mobile_lcdc: checking NULL instead of IS_ERR() ...
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/arkfb.c160
-rw-r--r--drivers/video/atmel_lcdfb.c31
-rw-r--r--drivers/video/aty/radeon_base.c2
-rw-r--r--drivers/video/aty/radeon_i2c.c3
-rw-r--r--drivers/video/cg14.c1
-rw-r--r--drivers/video/cg6.c1
-rw-r--r--drivers/video/console/fbcon.c4
-rw-r--r--drivers/video/console/tileblit.c2
-rw-r--r--drivers/video/edid.h4
-rw-r--r--drivers/video/ffb.c2
-rw-r--r--drivers/video/hecubafb.c2
-rw-r--r--drivers/video/hpfb.c6
-rw-r--r--drivers/video/metronomefb.c2
-rw-r--r--drivers/video/omap/Kconfig7
-rw-r--r--drivers/video/omap/blizzard.c3
-rw-r--r--drivers/video/omap/hwa742.c3
-rw-r--r--drivers/video/omap2/displays/Kconfig6
-rw-r--r--drivers/video/omap2/displays/Makefile1
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c25
-rw-r--r--drivers/video/omap2/displays/panel-lgphilips-lb035q02.c279
-rw-r--r--drivers/video/omap2/displays/panel-taal.c123
-rw-r--r--drivers/video/omap2/dss/Kconfig14
-rw-r--r--drivers/video/omap2/dss/Makefile2
-rw-r--r--drivers/video/omap2/dss/core.c480
-rw-r--r--drivers/video/omap2/dss/dispc.c335
-rw-r--r--drivers/video/omap2/dss/display.c35
-rw-r--r--drivers/video/omap2/dss/dpi.c45
-rw-r--r--drivers/video/omap2/dss/dsi.c967
-rw-r--r--drivers/video/omap2/dss/dss.c763
-rw-r--r--drivers/video/omap2/dss/dss.h153
-rw-r--r--drivers/video/omap2/dss/dss_features.c163
-rw-r--r--drivers/video/omap2/dss/dss_features.h27
-rw-r--r--drivers/video/omap2/dss/hdmi.c1332
-rw-r--r--drivers/video/omap2/dss/hdmi.h415
-rw-r--r--drivers/video/omap2/dss/hdmi_omap4_panel.c222
-rw-r--r--drivers/video/omap2/dss/manager.c13
-rw-r--r--drivers/video/omap2/dss/overlay.c10
-rw-r--r--drivers/video/omap2/dss/rfbi.c128
-rw-r--r--drivers/video/omap2/dss/sdi.c62
-rw-r--r--drivers/video/omap2/dss/venc.c128
-rw-r--r--drivers/video/omap2/omapfb/Kconfig6
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c23
-rw-r--r--drivers/video/s3c-fb.c1
-rw-r--r--drivers/video/s3fb.c341
-rw-r--r--drivers/video/sh7760fb.c4
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c5
-rw-r--r--drivers/video/sis/sis.h1
-rw-r--r--drivers/video/sis/sis_main.c315
-rw-r--r--drivers/video/sis/vgatypes.h1
-rw-r--r--drivers/video/sm501fb.c275
-rw-r--r--drivers/video/svgalib.c175
-rw-r--r--drivers/video/tcx.c1
-rw-r--r--drivers/video/uvesafb.c49
-rw-r--r--drivers/video/vermilion/vermilion.c3
-rw-r--r--drivers/video/vesafb.c44
-rw-r--r--drivers/video/vt8623fb.c157
56 files changed, 5542 insertions, 1820 deletions
diff --git a/drivers/video/arkfb.c b/drivers/video/arkfb.c
index 391ac939f01..8686429cbdf 100644
--- a/drivers/video/arkfb.c
+++ b/drivers/video/arkfb.c
@@ -158,12 +158,19 @@ static void arkfb_settile(struct fb_info *info, struct fb_tilemap *map)
158 } 158 }
159} 159}
160 160
161static void arkfb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
162{
163 struct arkfb_info *par = info->par;
164
165 svga_tilecursor(par->state.vgabase, info, cursor);
166}
167
161static struct fb_tile_ops arkfb_tile_ops = { 168static struct fb_tile_ops arkfb_tile_ops = {
162 .fb_settile = arkfb_settile, 169 .fb_settile = arkfb_settile,
163 .fb_tilecopy = svga_tilecopy, 170 .fb_tilecopy = svga_tilecopy,
164 .fb_tilefill = svga_tilefill, 171 .fb_tilefill = svga_tilefill,
165 .fb_tileblit = svga_tileblit, 172 .fb_tileblit = svga_tileblit,
166 .fb_tilecursor = svga_tilecursor, 173 .fb_tilecursor = arkfb_tilecursor,
167 .fb_get_tilemax = svga_get_tilemax, 174 .fb_get_tilemax = svga_get_tilemax,
168}; 175};
169 176
@@ -466,32 +473,40 @@ static unsigned short dac_regs[4] = {0x3c8, 0x3c9, 0x3c6, 0x3c7};
466 473
467static void ark_dac_read_regs(void *data, u8 *code, int count) 474static void ark_dac_read_regs(void *data, u8 *code, int count)
468{ 475{
469 u8 regval = vga_rseq(NULL, 0x1C); 476 struct fb_info *info = data;
477 struct arkfb_info *par;
478 u8 regval;
470 479
480 par = info->par;
481 regval = vga_rseq(par->state.vgabase, 0x1C);
471 while (count != 0) 482 while (count != 0)
472 { 483 {
473 vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0)); 484 vga_wseq(par->state.vgabase, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
474 code[1] = vga_r(NULL, dac_regs[code[0] & 3]); 485 code[1] = vga_r(par->state.vgabase, dac_regs[code[0] & 3]);
475 count--; 486 count--;
476 code += 2; 487 code += 2;
477 } 488 }
478 489
479 vga_wseq(NULL, 0x1C, regval); 490 vga_wseq(par->state.vgabase, 0x1C, regval);
480} 491}
481 492
482static void ark_dac_write_regs(void *data, u8 *code, int count) 493static void ark_dac_write_regs(void *data, u8 *code, int count)
483{ 494{
484 u8 regval = vga_rseq(NULL, 0x1C); 495 struct fb_info *info = data;
496 struct arkfb_info *par;
497 u8 regval;
485 498
499 par = info->par;
500 regval = vga_rseq(par->state.vgabase, 0x1C);
486 while (count != 0) 501 while (count != 0)
487 { 502 {
488 vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0)); 503 vga_wseq(par->state.vgabase, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
489 vga_w(NULL, dac_regs[code[0] & 3], code[1]); 504 vga_w(par->state.vgabase, dac_regs[code[0] & 3], code[1]);
490 count--; 505 count--;
491 code += 2; 506 code += 2;
492 } 507 }
493 508
494 vga_wseq(NULL, 0x1C, regval); 509 vga_wseq(par->state.vgabase, 0x1C, regval);
495} 510}
496 511
497 512
@@ -507,8 +522,8 @@ static void ark_set_pixclock(struct fb_info *info, u32 pixclock)
507 } 522 }
508 523
509 /* Set VGA misc register */ 524 /* Set VGA misc register */
510 regval = vga_r(NULL, VGA_MIS_R); 525 regval = vga_r(par->state.vgabase, VGA_MIS_R);
511 vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 526 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
512} 527}
513 528
514 529
@@ -520,7 +535,10 @@ static int arkfb_open(struct fb_info *info, int user)
520 535
521 mutex_lock(&(par->open_lock)); 536 mutex_lock(&(par->open_lock));
522 if (par->ref_count == 0) { 537 if (par->ref_count == 0) {
538 void __iomem *vgabase = par->state.vgabase;
539
523 memset(&(par->state), 0, sizeof(struct vgastate)); 540 memset(&(par->state), 0, sizeof(struct vgastate));
541 par->state.vgabase = vgabase;
524 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 542 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
525 par->state.num_crtc = 0x60; 543 par->state.num_crtc = 0x60;
526 par->state.num_seq = 0x30; 544 par->state.num_seq = 0x30;
@@ -646,50 +664,50 @@ static int arkfb_set_par(struct fb_info *info)
646 info->var.activate = FB_ACTIVATE_NOW; 664 info->var.activate = FB_ACTIVATE_NOW;
647 665
648 /* Unlock registers */ 666 /* Unlock registers */
649 svga_wcrt_mask(0x11, 0x00, 0x80); 667 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
650 668
651 /* Blank screen and turn off sync */ 669 /* Blank screen and turn off sync */
652 svga_wseq_mask(0x01, 0x20, 0x20); 670 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
653 svga_wcrt_mask(0x17, 0x00, 0x80); 671 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
654 672
655 /* Set default values */ 673 /* Set default values */
656 svga_set_default_gfx_regs(); 674 svga_set_default_gfx_regs(par->state.vgabase);
657 svga_set_default_atc_regs(); 675 svga_set_default_atc_regs(par->state.vgabase);
658 svga_set_default_seq_regs(); 676 svga_set_default_seq_regs(par->state.vgabase);
659 svga_set_default_crt_regs(); 677 svga_set_default_crt_regs(par->state.vgabase);
660 svga_wcrt_multi(ark_line_compare_regs, 0xFFFFFFFF); 678 svga_wcrt_multi(par->state.vgabase, ark_line_compare_regs, 0xFFFFFFFF);
661 svga_wcrt_multi(ark_start_address_regs, 0); 679 svga_wcrt_multi(par->state.vgabase, ark_start_address_regs, 0);
662 680
663 /* ARK specific initialization */ 681 /* ARK specific initialization */
664 svga_wseq_mask(0x10, 0x1F, 0x1F); /* enable linear framebuffer and full memory access */ 682 svga_wseq_mask(par->state.vgabase, 0x10, 0x1F, 0x1F); /* enable linear framebuffer and full memory access */
665 svga_wseq_mask(0x12, 0x03, 0x03); /* 4 MB linear framebuffer size */ 683 svga_wseq_mask(par->state.vgabase, 0x12, 0x03, 0x03); /* 4 MB linear framebuffer size */
666 684
667 vga_wseq(NULL, 0x13, info->fix.smem_start >> 16); 685 vga_wseq(par->state.vgabase, 0x13, info->fix.smem_start >> 16);
668 vga_wseq(NULL, 0x14, info->fix.smem_start >> 24); 686 vga_wseq(par->state.vgabase, 0x14, info->fix.smem_start >> 24);
669 vga_wseq(NULL, 0x15, 0); 687 vga_wseq(par->state.vgabase, 0x15, 0);
670 vga_wseq(NULL, 0x16, 0); 688 vga_wseq(par->state.vgabase, 0x16, 0);
671 689
672 /* Set the FIFO threshold register */ 690 /* Set the FIFO threshold register */
673 /* It is fascinating way to store 5-bit value in 8-bit register */ 691 /* It is fascinating way to store 5-bit value in 8-bit register */
674 regval = 0x10 | ((threshold & 0x0E) >> 1) | (threshold & 0x01) << 7 | (threshold & 0x10) << 1; 692 regval = 0x10 | ((threshold & 0x0E) >> 1) | (threshold & 0x01) << 7 | (threshold & 0x10) << 1;
675 vga_wseq(NULL, 0x18, regval); 693 vga_wseq(par->state.vgabase, 0x18, regval);
676 694
677 /* Set the offset register */ 695 /* Set the offset register */
678 pr_debug("fb%d: offset register : %d\n", info->node, offset_value); 696 pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
679 svga_wcrt_multi(ark_offset_regs, offset_value); 697 svga_wcrt_multi(par->state.vgabase, ark_offset_regs, offset_value);
680 698
681 /* fix for hi-res textmode */ 699 /* fix for hi-res textmode */
682 svga_wcrt_mask(0x40, 0x08, 0x08); 700 svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08);
683 701
684 if (info->var.vmode & FB_VMODE_DOUBLE) 702 if (info->var.vmode & FB_VMODE_DOUBLE)
685 svga_wcrt_mask(0x09, 0x80, 0x80); 703 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
686 else 704 else
687 svga_wcrt_mask(0x09, 0x00, 0x80); 705 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
688 706
689 if (info->var.vmode & FB_VMODE_INTERLACED) 707 if (info->var.vmode & FB_VMODE_INTERLACED)
690 svga_wcrt_mask(0x44, 0x04, 0x04); 708 svga_wcrt_mask(par->state.vgabase, 0x44, 0x04, 0x04);
691 else 709 else
692 svga_wcrt_mask(0x44, 0x00, 0x04); 710 svga_wcrt_mask(par->state.vgabase, 0x44, 0x00, 0x04);
693 711
694 hmul = 1; 712 hmul = 1;
695 hdiv = 1; 713 hdiv = 1;
@@ -699,40 +717,40 @@ static int arkfb_set_par(struct fb_info *info)
699 switch (mode) { 717 switch (mode) {
700 case 0: 718 case 0:
701 pr_debug("fb%d: text mode\n", info->node); 719 pr_debug("fb%d: text mode\n", info->node);
702 svga_set_textmode_vga_regs(); 720 svga_set_textmode_vga_regs(par->state.vgabase);
703 721
704 vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */ 722 vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
705 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 723 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
706 dac_set_mode(par->dac, DAC_PSEUDO8_8); 724 dac_set_mode(par->dac, DAC_PSEUDO8_8);
707 725
708 break; 726 break;
709 case 1: 727 case 1:
710 pr_debug("fb%d: 4 bit pseudocolor\n", info->node); 728 pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
711 vga_wgfx(NULL, VGA_GFX_MODE, 0x40); 729 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
712 730
713 vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */ 731 vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
714 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 732 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
715 dac_set_mode(par->dac, DAC_PSEUDO8_8); 733 dac_set_mode(par->dac, DAC_PSEUDO8_8);
716 break; 734 break;
717 case 2: 735 case 2:
718 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); 736 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
719 737
720 vga_wseq(NULL, 0x11, 0x10); /* basic VGA mode */ 738 vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */
721 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 739 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
722 dac_set_mode(par->dac, DAC_PSEUDO8_8); 740 dac_set_mode(par->dac, DAC_PSEUDO8_8);
723 break; 741 break;
724 case 3: 742 case 3:
725 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 743 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
726 744
727 vga_wseq(NULL, 0x11, 0x16); /* 8bpp accel mode */ 745 vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode */
728 746
729 if (info->var.pixclock > 20000) { 747 if (info->var.pixclock > 20000) {
730 pr_debug("fb%d: not using multiplex\n", info->node); 748 pr_debug("fb%d: not using multiplex\n", info->node);
731 svga_wcrt_mask(0x46, 0x00, 0x04); /* 8bit pixel path */ 749 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */
732 dac_set_mode(par->dac, DAC_PSEUDO8_8); 750 dac_set_mode(par->dac, DAC_PSEUDO8_8);
733 } else { 751 } else {
734 pr_debug("fb%d: using multiplex\n", info->node); 752 pr_debug("fb%d: using multiplex\n", info->node);
735 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 753 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
736 dac_set_mode(par->dac, DAC_PSEUDO8_16); 754 dac_set_mode(par->dac, DAC_PSEUDO8_16);
737 hdiv = 2; 755 hdiv = 2;
738 } 756 }
@@ -740,22 +758,22 @@ static int arkfb_set_par(struct fb_info *info)
740 case 4: 758 case 4:
741 pr_debug("fb%d: 5/5/5 truecolor\n", info->node); 759 pr_debug("fb%d: 5/5/5 truecolor\n", info->node);
742 760
743 vga_wseq(NULL, 0x11, 0x1A); /* 16bpp accel mode */ 761 vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */
744 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 762 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
745 dac_set_mode(par->dac, DAC_RGB1555_16); 763 dac_set_mode(par->dac, DAC_RGB1555_16);
746 break; 764 break;
747 case 5: 765 case 5:
748 pr_debug("fb%d: 5/6/5 truecolor\n", info->node); 766 pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
749 767
750 vga_wseq(NULL, 0x11, 0x1A); /* 16bpp accel mode */ 768 vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */
751 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 769 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
752 dac_set_mode(par->dac, DAC_RGB0565_16); 770 dac_set_mode(par->dac, DAC_RGB0565_16);
753 break; 771 break;
754 case 6: 772 case 6:
755 pr_debug("fb%d: 8/8/8 truecolor\n", info->node); 773 pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
756 774
757 vga_wseq(NULL, 0x11, 0x16); /* 8bpp accel mode ??? */ 775 vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode ??? */
758 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 776 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
759 dac_set_mode(par->dac, DAC_RGB0888_16); 777 dac_set_mode(par->dac, DAC_RGB0888_16);
760 hmul = 3; 778 hmul = 3;
761 hdiv = 2; 779 hdiv = 2;
@@ -763,8 +781,8 @@ static int arkfb_set_par(struct fb_info *info)
763 case 7: 781 case 7:
764 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node); 782 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node);
765 783
766 vga_wseq(NULL, 0x11, 0x1E); /* 32bpp accel mode */ 784 vga_wseq(par->state.vgabase, 0x11, 0x1E); /* 32bpp accel mode */
767 svga_wcrt_mask(0x46, 0x04, 0x04); /* 16bit pixel path */ 785 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */
768 dac_set_mode(par->dac, DAC_RGB8888_16); 786 dac_set_mode(par->dac, DAC_RGB8888_16);
769 hmul = 2; 787 hmul = 2;
770 break; 788 break;
@@ -774,7 +792,7 @@ static int arkfb_set_par(struct fb_info *info)
774 } 792 }
775 793
776 ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul); 794 ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul);
777 svga_set_timings(&ark_timing_regs, &(info->var), hmul, hdiv, 795 svga_set_timings(par->state.vgabase, &ark_timing_regs, &(info->var), hmul, hdiv,
778 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 796 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1,
779 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1, 797 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
780 hmul, info->node); 798 hmul, info->node);
@@ -782,12 +800,12 @@ static int arkfb_set_par(struct fb_info *info)
782 /* Set interlaced mode start/end register */ 800 /* Set interlaced mode start/end register */
783 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len; 801 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
784 value = ((value * hmul / hdiv) / 8) - 5; 802 value = ((value * hmul / hdiv) / 8) - 5;
785 vga_wcrt(NULL, 0x42, (value + 1) / 2); 803 vga_wcrt(par->state.vgabase, 0x42, (value + 1) / 2);
786 804
787 memset_io(info->screen_base, 0x00, screen_size); 805 memset_io(info->screen_base, 0x00, screen_size);
788 /* Device and screen back on */ 806 /* Device and screen back on */
789 svga_wcrt_mask(0x17, 0x80, 0x80); 807 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
790 svga_wseq_mask(0x01, 0x00, 0x20); 808 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
791 809
792 return 0; 810 return 0;
793} 811}
@@ -857,23 +875,25 @@ static int arkfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
857 875
858static int arkfb_blank(int blank_mode, struct fb_info *info) 876static int arkfb_blank(int blank_mode, struct fb_info *info)
859{ 877{
878 struct arkfb_info *par = info->par;
879
860 switch (blank_mode) { 880 switch (blank_mode) {
861 case FB_BLANK_UNBLANK: 881 case FB_BLANK_UNBLANK:
862 pr_debug("fb%d: unblank\n", info->node); 882 pr_debug("fb%d: unblank\n", info->node);
863 svga_wseq_mask(0x01, 0x00, 0x20); 883 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
864 svga_wcrt_mask(0x17, 0x80, 0x80); 884 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
865 break; 885 break;
866 case FB_BLANK_NORMAL: 886 case FB_BLANK_NORMAL:
867 pr_debug("fb%d: blank\n", info->node); 887 pr_debug("fb%d: blank\n", info->node);
868 svga_wseq_mask(0x01, 0x20, 0x20); 888 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
869 svga_wcrt_mask(0x17, 0x80, 0x80); 889 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
870 break; 890 break;
871 case FB_BLANK_POWERDOWN: 891 case FB_BLANK_POWERDOWN:
872 case FB_BLANK_HSYNC_SUSPEND: 892 case FB_BLANK_HSYNC_SUSPEND:
873 case FB_BLANK_VSYNC_SUSPEND: 893 case FB_BLANK_VSYNC_SUSPEND:
874 pr_debug("fb%d: sync down\n", info->node); 894 pr_debug("fb%d: sync down\n", info->node);
875 svga_wseq_mask(0x01, 0x20, 0x20); 895 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
876 svga_wcrt_mask(0x17, 0x00, 0x80); 896 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
877 break; 897 break;
878 } 898 }
879 return 0; 899 return 0;
@@ -884,6 +904,7 @@ static int arkfb_blank(int blank_mode, struct fb_info *info)
884 904
885static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 905static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
886{ 906{
907 struct arkfb_info *par = info->par;
887 unsigned int offset; 908 unsigned int offset;
888 909
889 /* Calculate the offset */ 910 /* Calculate the offset */
@@ -897,7 +918,7 @@ static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info
897 } 918 }
898 919
899 /* Set the offset */ 920 /* Set the offset */
900 svga_wcrt_multi(ark_start_address_regs, offset); 921 svga_wcrt_multi(par->state.vgabase, ark_start_address_regs, offset);
901 922
902 return 0; 923 return 0;
903} 924}
@@ -930,6 +951,8 @@ static struct fb_ops arkfb_ops = {
930/* PCI probe */ 951/* PCI probe */
931static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 952static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
932{ 953{
954 struct pci_bus_region bus_reg;
955 struct resource vga_res;
933 struct fb_info *info; 956 struct fb_info *info;
934 struct arkfb_info *par; 957 struct arkfb_info *par;
935 int rc; 958 int rc;
@@ -985,8 +1008,17 @@ static int __devinit ark_pci_probe(struct pci_dev *dev, const struct pci_device_
985 goto err_iomap; 1008 goto err_iomap;
986 } 1009 }
987 1010
1011 bus_reg.start = 0;
1012 bus_reg.end = 64 * 1024;
1013
1014 vga_res.flags = IORESOURCE_IO;
1015
1016 pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
1017
1018 par->state.vgabase = (void __iomem *) vga_res.start;
1019
988 /* FIXME get memsize */ 1020 /* FIXME get memsize */
989 regval = vga_rseq(NULL, 0x10); 1021 regval = vga_rseq(par->state.vgabase, 0x10);
990 info->screen_size = (1 << (regval >> 6)) << 20; 1022 info->screen_size = (1 << (regval >> 6)) << 20;
991 info->fix.smem_len = info->screen_size; 1023 info->fix.smem_len = info->screen_size;
992 1024
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 4b4e8dadd6b..ccecf997458 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -68,7 +68,7 @@ static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
68} 68}
69#endif 69#endif
70 70
71static const u32 contrast_ctr = ATMEL_LCDC_PS_DIV8 71static u32 contrast_ctr = ATMEL_LCDC_PS_DIV8
72 | ATMEL_LCDC_POL_POSITIVE 72 | ATMEL_LCDC_POL_POSITIVE
73 | ATMEL_LCDC_ENA_PWMENABLE; 73 | ATMEL_LCDC_ENA_PWMENABLE;
74 74
@@ -164,6 +164,10 @@ static void exit_backlight(struct atmel_lcdfb_info *sinfo)
164 164
165static void init_contrast(struct atmel_lcdfb_info *sinfo) 165static void init_contrast(struct atmel_lcdfb_info *sinfo)
166{ 166{
167 /* contrast pwm can be 'inverted' */
168 if (sinfo->lcdcon_pol_negative)
169 contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);
170
167 /* have some default contrast/backlight settings */ 171 /* have some default contrast/backlight settings */
168 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr); 172 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
169 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT); 173 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);
@@ -711,11 +715,35 @@ static int atmel_lcdfb_pan_display(struct fb_var_screeninfo *var,
711 return 0; 715 return 0;
712} 716}
713 717
718static int atmel_lcdfb_blank(int blank_mode, struct fb_info *info)
719{
720 struct atmel_lcdfb_info *sinfo = info->par;
721
722 switch (blank_mode) {
723 case FB_BLANK_UNBLANK:
724 case FB_BLANK_NORMAL:
725 atmel_lcdfb_start(sinfo);
726 break;
727 case FB_BLANK_VSYNC_SUSPEND:
728 case FB_BLANK_HSYNC_SUSPEND:
729 break;
730 case FB_BLANK_POWERDOWN:
731 atmel_lcdfb_stop(sinfo);
732 break;
733 default:
734 return -EINVAL;
735 }
736
737 /* let fbcon do a soft blank for us */
738 return ((blank_mode == FB_BLANK_NORMAL) ? 1 : 0);
739}
740
714static struct fb_ops atmel_lcdfb_ops = { 741static struct fb_ops atmel_lcdfb_ops = {
715 .owner = THIS_MODULE, 742 .owner = THIS_MODULE,
716 .fb_check_var = atmel_lcdfb_check_var, 743 .fb_check_var = atmel_lcdfb_check_var,
717 .fb_set_par = atmel_lcdfb_set_par, 744 .fb_set_par = atmel_lcdfb_set_par,
718 .fb_setcolreg = atmel_lcdfb_setcolreg, 745 .fb_setcolreg = atmel_lcdfb_setcolreg,
746 .fb_blank = atmel_lcdfb_blank,
719 .fb_pan_display = atmel_lcdfb_pan_display, 747 .fb_pan_display = atmel_lcdfb_pan_display,
720 .fb_fillrect = cfb_fillrect, 748 .fb_fillrect = cfb_fillrect,
721 .fb_copyarea = cfb_copyarea, 749 .fb_copyarea = cfb_copyarea,
@@ -817,6 +845,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
817 sinfo->guard_time = pdata_sinfo->guard_time; 845 sinfo->guard_time = pdata_sinfo->guard_time;
818 sinfo->smem_len = pdata_sinfo->smem_len; 846 sinfo->smem_len = pdata_sinfo->smem_len;
819 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight; 847 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight;
848 sinfo->lcdcon_pol_negative = pdata_sinfo->lcdcon_pol_negative;
820 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode; 849 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode;
821 } else { 850 } else {
822 dev_err(dev, "cannot get default configuration\n"); 851 dev_err(dev, "cannot get default configuration\n");
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 3c1e13ed1cb..32f8cf6200a 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -1248,7 +1248,7 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
1248 1248
1249 /* Workaround from XFree */ 1249 /* Workaround from XFree */
1250 if (rinfo->is_mobility) { 1250 if (rinfo->is_mobility) {
1251 /* A temporal workaround for the occational blanking on certain laptop 1251 /* A temporal workaround for the occasional blanking on certain laptop
1252 * panels. This appears to related to the PLL divider registers 1252 * panels. This appears to related to the PLL divider registers
1253 * (fail to lock?). It occurs even when all dividers are the same 1253 * (fail to lock?). It occurs even when all dividers are the same
1254 * with their old settings. In this case we really don't need to 1254 * with their old settings. In this case we really don't need to
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 78d1f4cd1fe..ab1d0fd7631 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -100,6 +100,9 @@ void radeon_create_i2c_busses(struct radeonfb_info *rinfo)
100{ 100{
101 rinfo->i2c[0].rinfo = rinfo; 101 rinfo->i2c[0].rinfo = rinfo;
102 rinfo->i2c[0].ddc_reg = GPIO_MONID; 102 rinfo->i2c[0].ddc_reg = GPIO_MONID;
103#ifndef CONFIG_PPC
104 rinfo->i2c[0].adapter.class = I2C_CLASS_HWMON;
105#endif
103 radeon_setup_i2c_bus(&rinfo->i2c[0], "monid"); 106 radeon_setup_i2c_bus(&rinfo->i2c[0], "monid");
104 107
105 rinfo->i2c[1].rinfo = rinfo; 108 rinfo->i2c[1].rinfo = rinfo;
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index e2c85b0db63..f1889500662 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -565,6 +565,7 @@ out_dealloc_cmap:
565 565
566out_unmap_regs: 566out_unmap_regs:
567 cg14_unmap_regs(op, info, par); 567 cg14_unmap_regs(op, info, par);
568 framebuffer_release(info);
568 569
569out_err: 570out_err:
570 return err; 571 return err;
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 4ffad90bde4..179e96cdb32 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -821,6 +821,7 @@ out_dealloc_cmap:
821 821
822out_unmap_regs: 822out_unmap_regs:
823 cg6_unmap_regs(op, info, par); 823 cg6_unmap_regs(op, info, par);
824 framebuffer_release(info);
824 825
825out_err: 826out_err:
826 return err; 827 return err;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 9c092b8d64e..c58393402da 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -823,10 +823,10 @@ static int set_con2fb_map(int unit, int newidx, int user)
823 if (oldidx == newidx) 823 if (oldidx == newidx)
824 return 0; 824 return 0;
825 825
826 if (!info || fbcon_has_exited) 826 if (!info)
827 return -EINVAL; 827 return -EINVAL;
828 828
829 if (!err && !search_for_mapped_con()) { 829 if (!search_for_mapped_con() || !con_is_bound(&fb_con)) {
830 info_idx = newidx; 830 info_idx = newidx;
831 return fbcon_takeover(0); 831 return fbcon_takeover(0);
832 } 832 }
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c
index 0056a41e5c3..15e8e1a89c4 100644
--- a/drivers/video/console/tileblit.c
+++ b/drivers/video/console/tileblit.c
@@ -83,7 +83,7 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
83 int softback_lines, int fg, int bg) 83 int softback_lines, int fg, int bg)
84{ 84{
85 struct fb_tilecursor cursor; 85 struct fb_tilecursor cursor;
86 int use_sw = (vc->vc_cursor_type & 0x01); 86 int use_sw = (vc->vc_cursor_type & 0x10);
87 87
88 cursor.sx = vc->vc_x; 88 cursor.sx = vc->vc_x;
89 cursor.sy = vc->vc_y; 89 cursor.sy = vc->vc_y;
diff --git a/drivers/video/edid.h b/drivers/video/edid.h
index bd89fb3be8c..d03a232d90b 100644
--- a/drivers/video/edid.h
+++ b/drivers/video/edid.h
@@ -101,8 +101,8 @@
101#define V_SYNC_WIDTH COMBINE_HI_4LO( V_SYNC_WIDTH_HI, V_SYNC_WIDTH_LO ) 101#define V_SYNC_WIDTH COMBINE_HI_4LO( V_SYNC_WIDTH_HI, V_SYNC_WIDTH_LO )
102#define V_SYNC_OFFSET COMBINE_HI_4LO( V_SYNC_OFFSET_HI, V_SYNC_OFFSET_LO ) 102#define V_SYNC_OFFSET COMBINE_HI_4LO( V_SYNC_OFFSET_HI, V_SYNC_OFFSET_LO )
103 103
104#define H_SYNC_WIDTH COMBINE_HI_4LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO ) 104#define H_SYNC_WIDTH COMBINE_HI_8LO( H_SYNC_WIDTH_HI, H_SYNC_WIDTH_LO )
105#define H_SYNC_OFFSET COMBINE_HI_4LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO ) 105#define H_SYNC_OFFSET COMBINE_HI_8LO( H_SYNC_OFFSET_HI, H_SYNC_OFFSET_LO )
106 106
107#define H_SIZE_LO (unsigned)block[ 12 ] 107#define H_SIZE_LO (unsigned)block[ 12 ]
108#define V_SIZE_LO (unsigned)block[ 13 ] 108#define V_SIZE_LO (unsigned)block[ 13 ]
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 910c5e6f670..14102a3f70f 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -1010,7 +1010,7 @@ out_dealloc_cmap:
1010 fb_dealloc_cmap(&info->cmap); 1010 fb_dealloc_cmap(&info->cmap);
1011 1011
1012out_unmap_dac: 1012out_unmap_dac:
1013 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc)); 1013 of_iounmap(&op->resource[1], par->dac, sizeof(struct ffb_dac));
1014 1014
1015out_unmap_fbc: 1015out_unmap_fbc:
1016 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc)); 1016 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
index c77bcc6ab46..1b94643ecbc 100644
--- a/drivers/video/hecubafb.c
+++ b/drivers/video/hecubafb.c
@@ -299,7 +299,7 @@ static int __devexit hecubafb_remove(struct platform_device *dev)
299 299
300static struct platform_driver hecubafb_driver = { 300static struct platform_driver hecubafb_driver = {
301 .probe = hecubafb_probe, 301 .probe = hecubafb_probe,
302 .remove = hecubafb_remove, 302 .remove = __devexit_p(hecubafb_remove),
303 .driver = { 303 .driver = {
304 .owner = THIS_MODULE, 304 .owner = THIS_MODULE,
305 .name = "hecubafb", 305 .name = "hecubafb",
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index c8e280f1bb0..ebf8495ff19 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -321,11 +321,11 @@ static int __devinit hpfb_dio_probe(struct dio_dev * d, const struct dio_device_
321 unsigned long paddr, vaddr; 321 unsigned long paddr, vaddr;
322 322
323 paddr = d->resource.start; 323 paddr = d->resource.start;
324 if (!request_mem_region(d->resource.start, d->resource.end - d->resource.start, d->name)) 324 if (!request_mem_region(d->resource.start, resource_size(&d->resource), d->name))
325 return -EBUSY; 325 return -EBUSY;
326 326
327 if (d->scode >= DIOII_SCBASE) { 327 if (d->scode >= DIOII_SCBASE) {
328 vaddr = (unsigned long)ioremap(paddr, d->resource.end - d->resource.start); 328 vaddr = (unsigned long)ioremap(paddr, resource_size(&d->resource));
329 } else { 329 } else {
330 vaddr = paddr + DIO_VIRADDRBASE; 330 vaddr = paddr + DIO_VIRADDRBASE;
331 } 331 }
@@ -344,7 +344,7 @@ static void __devexit hpfb_remove_one(struct dio_dev *d)
344 unregister_framebuffer(&fb_info); 344 unregister_framebuffer(&fb_info);
345 if (d->scode >= DIOII_SCBASE) 345 if (d->scode >= DIOII_SCBASE)
346 iounmap((void *)fb_regs); 346 iounmap((void *)fb_regs);
347 release_mem_region(d->resource.start, d->resource.end - d->resource.start); 347 release_mem_region(d->resource.start, resource_size(&d->resource));
348} 348}
349 349
350static struct dio_device_id hpfb_dio_tbl[] = { 350static struct dio_device_id hpfb_dio_tbl[] = {
diff --git a/drivers/video/metronomefb.c b/drivers/video/metronomefb.c
index 63ed3b72b01..ed64edfd2c4 100644
--- a/drivers/video/metronomefb.c
+++ b/drivers/video/metronomefb.c
@@ -765,7 +765,7 @@ static int __devexit metronomefb_remove(struct platform_device *dev)
765 765
766static struct platform_driver metronomefb_driver = { 766static struct platform_driver metronomefb_driver = {
767 .probe = metronomefb_probe, 767 .probe = metronomefb_probe,
768 .remove = metronomefb_remove, 768 .remove = __devexit_p(metronomefb_remove),
769 .driver = { 769 .driver = {
770 .owner = THIS_MODULE, 770 .owner = THIS_MODULE,
771 .name = "metronomefb", 771 .name = "metronomefb",
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index 083c8fe53e2..15e7f1912af 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -5,13 +5,18 @@ config FB_OMAP
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
8 help 9 help
9 Frame buffer driver for OMAP based boards. 10 Frame buffer driver for OMAP based boards.
10 11
11config FB_OMAP_LCD_VGA 12config FB_OMAP_LCD_VGA
12 bool "Use LCD in VGA mode" 13 bool "Use LCD in VGA mode"
13 depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP 14 depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP
14 15 help
16 Set LCD resolution as VGA (640 X 480).
17 Default resolution without this option is QVGA(320 X 240).
18 Please take a look at drivers/video/omap/lcd_ldp.c file
19 for lcd driver code.
15choice 20choice
16 depends on FB_OMAP && MACH_OVERO 21 depends on FB_OMAP && MACH_OVERO
17 prompt "Screen resolution" 22 prompt "Screen resolution"
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
index 87785c215a5..c0504a8a507 100644
--- a/drivers/video/omap/blizzard.c
+++ b/drivers/video/omap/blizzard.c
@@ -397,8 +397,7 @@ static inline void free_req(struct blizzard_request *req)
397 397
398 spin_lock_irqsave(&blizzard.req_lock, flags); 398 spin_lock_irqsave(&blizzard.req_lock, flags);
399 399
400 list_del(&req->entry); 400 list_move(&req->entry, &blizzard.free_req_list);
401 list_add(&req->entry, &blizzard.free_req_list);
402 if (!(req->flags & REQ_FROM_IRQ_POOL)) 401 if (!(req->flags & REQ_FROM_IRQ_POOL))
403 up(&blizzard.req_sema); 402 up(&blizzard.req_sema);
404 403
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index 0016f77cd13..084aa0ac562 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -269,8 +269,7 @@ static inline void free_req(struct hwa742_request *req)
269 269
270 spin_lock_irqsave(&hwa742.req_lock, flags); 270 spin_lock_irqsave(&hwa742.req_lock, flags);
271 271
272 list_del(&req->entry); 272 list_move(&req->entry, &hwa742.free_req_list);
273 list_add(&req->entry, &hwa742.free_req_list);
274 if (!(req->flags & REQ_FROM_IRQ_POOL)) 273 if (!(req->flags & REQ_FROM_IRQ_POOL))
275 up(&hwa742.req_sema); 274 up(&hwa742.req_sema);
276 275
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 940cab394c2..d18ad6b2372 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -9,6 +9,12 @@ config PANEL_GENERIC_DPI
9 Supports LCD Panel used in TI SDP3430 and EVM boards, 9 Supports LCD Panel used in TI SDP3430 and EVM boards,
10 OMAP3517 EVM boards and CM-T35. 10 OMAP3517 EVM boards and CM-T35.
11 11
12config PANEL_LGPHILIPS_LB035Q02
13 tristate "LG.Philips LB035Q02 LCD Panel"
14 depends on OMAP2_DSS && SPI
15 help
16 LCD Panel used on the Gumstix Overo Palo35
17
12config PANEL_SHARP_LS037V7DW01 18config PANEL_SHARP_LS037V7DW01
13 tristate "Sharp LS037V7DW01 LCD Panel" 19 tristate "Sharp LS037V7DW01 LCD Panel"
14 depends on OMAP2_DSS 20 depends on OMAP2_DSS
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
index 861f0255ec6..0f601ab3abf 100644
--- a/drivers/video/omap2/displays/Makefile
+++ b/drivers/video/omap2/displays/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o 1obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o
2obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
2obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o 3obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
3obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o 4obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
4 5
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 07eb30ee59c..4a9b9ff5946 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -156,6 +156,31 @@ static struct panel_config generic_dpi_panels[] = {
156 .power_off_delay = 0, 156 .power_off_delay = 0,
157 .name = "toppoly_tdo35s", 157 .name = "toppoly_tdo35s",
158 }, 158 },
159
160 /* Samsung LTE430WQ-F0C */
161 {
162 {
163 .x_res = 480,
164 .y_res = 272,
165
166 .pixel_clock = 9200,
167
168 .hfp = 8,
169 .hsw = 41,
170 .hbp = 45 - 41,
171
172 .vfp = 4,
173 .vsw = 10,
174 .vbp = 12 - 10,
175 },
176 .acbi = 0x0,
177 .acb = 0x0,
178 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
179 OMAP_DSS_LCD_IHS,
180 .power_on_delay = 0,
181 .power_off_delay = 0,
182 .name = "samsung_lte430wq_f0c",
183 },
159}; 184};
160 185
161struct panel_drv_data { 186struct panel_drv_data {
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
new file mode 100644
index 00000000000..271324db243
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -0,0 +1,279 @@
1/*
2 * LCD panel driver for LG.Philips LB035Q02
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/module.h>
20#include <linux/delay.h>
21#include <linux/spi/spi.h>
22#include <linux/mutex.h>
23
24#include <plat/display.h>
25
26struct lb035q02_data {
27 struct mutex lock;
28};
29
30static struct omap_video_timings lb035q02_timings = {
31 .x_res = 320,
32 .y_res = 240,
33
34 .pixel_clock = 6500,
35
36 .hsw = 2,
37 .hfp = 20,
38 .hbp = 68,
39
40 .vsw = 2,
41 .vfp = 4,
42 .vbp = 18,
43};
44
45static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
46{
47 int r;
48
49 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
50 return 0;
51
52 r = omapdss_dpi_display_enable(dssdev);
53 if (r)
54 goto err0;
55
56 if (dssdev->platform_enable) {
57 r = dssdev->platform_enable(dssdev);
58 if (r)
59 goto err1;
60 }
61
62 return 0;
63err1:
64 omapdss_dpi_display_disable(dssdev);
65err0:
66 return r;
67}
68
69static void lb035q02_panel_power_off(struct omap_dss_device *dssdev)
70{
71 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
72 return;
73
74 if (dssdev->platform_disable)
75 dssdev->platform_disable(dssdev);
76
77 omapdss_dpi_display_disable(dssdev);
78}
79
80static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
81{
82 struct lb035q02_data *ld;
83 int r;
84
85 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
86 OMAP_DSS_LCD_IHS;
87 dssdev->panel.timings = lb035q02_timings;
88
89 ld = kzalloc(sizeof(*ld), GFP_KERNEL);
90 if (!ld) {
91 r = -ENOMEM;
92 goto err;
93 }
94 mutex_init(&ld->lock);
95 dev_set_drvdata(&dssdev->dev, ld);
96 return 0;
97err:
98 return r;
99}
100
101static void lb035q02_panel_remove(struct omap_dss_device *dssdev)
102{
103 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
104
105 kfree(ld);
106}
107
108static int lb035q02_panel_enable(struct omap_dss_device *dssdev)
109{
110 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
111 int r;
112
113 mutex_lock(&ld->lock);
114
115 r = lb035q02_panel_power_on(dssdev);
116 if (r)
117 goto err;
118 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
119
120 mutex_unlock(&ld->lock);
121 return 0;
122err:
123 mutex_unlock(&ld->lock);
124 return r;
125}
126
127static void lb035q02_panel_disable(struct omap_dss_device *dssdev)
128{
129 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
130
131 mutex_lock(&ld->lock);
132
133 lb035q02_panel_power_off(dssdev);
134 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
135
136 mutex_unlock(&ld->lock);
137}
138
139static int lb035q02_panel_suspend(struct omap_dss_device *dssdev)
140{
141 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
142
143 mutex_lock(&ld->lock);
144
145 lb035q02_panel_power_off(dssdev);
146 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
147
148 mutex_unlock(&ld->lock);
149 return 0;
150}
151
152static int lb035q02_panel_resume(struct omap_dss_device *dssdev)
153{
154 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
155 int r;
156
157 mutex_lock(&ld->lock);
158
159 r = lb035q02_panel_power_on(dssdev);
160 if (r)
161 goto err;
162 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
163
164 mutex_unlock(&ld->lock);
165 return 0;
166err:
167 mutex_unlock(&ld->lock);
168 return r;
169}
170
171static struct omap_dss_driver lb035q02_driver = {
172 .probe = lb035q02_panel_probe,
173 .remove = lb035q02_panel_remove,
174
175 .enable = lb035q02_panel_enable,
176 .disable = lb035q02_panel_disable,
177 .suspend = lb035q02_panel_suspend,
178 .resume = lb035q02_panel_resume,
179
180 .driver = {
181 .name = "lgphilips_lb035q02_panel",
182 .owner = THIS_MODULE,
183 },
184};
185
186static int lb035q02_write_reg(struct spi_device *spi, u8 reg, u16 val)
187{
188 struct spi_message msg;
189 struct spi_transfer index_xfer = {
190 .len = 3,
191 .cs_change = 1,
192 };
193 struct spi_transfer value_xfer = {
194 .len = 3,
195 };
196 u8 buffer[16];
197
198 spi_message_init(&msg);
199
200 /* register index */
201 buffer[0] = 0x70;
202 buffer[1] = 0x00;
203 buffer[2] = reg & 0x7f;
204 index_xfer.tx_buf = buffer;
205 spi_message_add_tail(&index_xfer, &msg);
206
207 /* register value */
208 buffer[4] = 0x72;
209 buffer[5] = val >> 8;
210 buffer[6] = val;
211 value_xfer.tx_buf = buffer + 4;
212 spi_message_add_tail(&value_xfer, &msg);
213
214 return spi_sync(spi, &msg);
215}
216
217static void init_lb035q02_panel(struct spi_device *spi)
218{
219 /* Init sequence from page 28 of the lb035q02 spec */
220 lb035q02_write_reg(spi, 0x01, 0x6300);
221 lb035q02_write_reg(spi, 0x02, 0x0200);
222 lb035q02_write_reg(spi, 0x03, 0x0177);
223 lb035q02_write_reg(spi, 0x04, 0x04c7);
224 lb035q02_write_reg(spi, 0x05, 0xffc0);
225 lb035q02_write_reg(spi, 0x06, 0xe806);
226 lb035q02_write_reg(spi, 0x0a, 0x4008);
227 lb035q02_write_reg(spi, 0x0b, 0x0000);
228 lb035q02_write_reg(spi, 0x0d, 0x0030);
229 lb035q02_write_reg(spi, 0x0e, 0x2800);
230 lb035q02_write_reg(spi, 0x0f, 0x0000);
231 lb035q02_write_reg(spi, 0x16, 0x9f80);
232 lb035q02_write_reg(spi, 0x17, 0x0a0f);
233 lb035q02_write_reg(spi, 0x1e, 0x00c1);
234 lb035q02_write_reg(spi, 0x30, 0x0300);
235 lb035q02_write_reg(spi, 0x31, 0x0007);
236 lb035q02_write_reg(spi, 0x32, 0x0000);
237 lb035q02_write_reg(spi, 0x33, 0x0000);
238 lb035q02_write_reg(spi, 0x34, 0x0707);
239 lb035q02_write_reg(spi, 0x35, 0x0004);
240 lb035q02_write_reg(spi, 0x36, 0x0302);
241 lb035q02_write_reg(spi, 0x37, 0x0202);
242 lb035q02_write_reg(spi, 0x3a, 0x0a0d);
243 lb035q02_write_reg(spi, 0x3b, 0x0806);
244}
245
246static int __devinit lb035q02_panel_spi_probe(struct spi_device *spi)
247{
248 init_lb035q02_panel(spi);
249 return omap_dss_register_driver(&lb035q02_driver);
250}
251
252static int __devexit lb035q02_panel_spi_remove(struct spi_device *spi)
253{
254 omap_dss_unregister_driver(&lb035q02_driver);
255 return 0;
256}
257
258static struct spi_driver lb035q02_spi_driver = {
259 .driver = {
260 .name = "lgphilips_lb035q02_panel-spi",
261 .owner = THIS_MODULE,
262 },
263 .probe = lb035q02_panel_spi_probe,
264 .remove = __devexit_p(lb035q02_panel_spi_remove),
265};
266
267static int __init lb035q02_panel_drv_init(void)
268{
269 return spi_register_driver(&lb035q02_spi_driver);
270}
271
272static void __exit lb035q02_panel_drv_exit(void)
273{
274 spi_unregister_driver(&lb035q02_spi_driver);
275}
276
277module_init(lb035q02_panel_drv_init);
278module_exit(lb035q02_panel_drv_exit);
279MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index c74e8b778ba..adc9900458e 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -218,6 +218,8 @@ struct taal_data {
218 u16 w; 218 u16 w;
219 u16 h; 219 u16 h;
220 } update_region; 220 } update_region;
221 int channel;
222
221 struct delayed_work te_timeout_work; 223 struct delayed_work te_timeout_work;
222 224
223 bool use_dsi_bl; 225 bool use_dsi_bl;
@@ -257,12 +259,12 @@ static void hw_guard_wait(struct taal_data *td)
257 } 259 }
258} 260}
259 261
260static int taal_dcs_read_1(u8 dcs_cmd, u8 *data) 262static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
261{ 263{
262 int r; 264 int r;
263 u8 buf[1]; 265 u8 buf[1];
264 266
265 r = dsi_vc_dcs_read(TCH, dcs_cmd, buf, 1); 267 r = dsi_vc_dcs_read(td->channel, dcs_cmd, buf, 1);
266 268
267 if (r < 0) 269 if (r < 0)
268 return r; 270 return r;
@@ -272,17 +274,17 @@ static int taal_dcs_read_1(u8 dcs_cmd, u8 *data)
272 return 0; 274 return 0;
273} 275}
274 276
275static int taal_dcs_write_0(u8 dcs_cmd) 277static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
276{ 278{
277 return dsi_vc_dcs_write(TCH, &dcs_cmd, 1); 279 return dsi_vc_dcs_write(td->channel, &dcs_cmd, 1);
278} 280}
279 281
280static int taal_dcs_write_1(u8 dcs_cmd, u8 param) 282static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
281{ 283{
282 u8 buf[2]; 284 u8 buf[2];
283 buf[0] = dcs_cmd; 285 buf[0] = dcs_cmd;
284 buf[1] = param; 286 buf[1] = param;
285 return dsi_vc_dcs_write(TCH, buf, 2); 287 return dsi_vc_dcs_write(td->channel, buf, 2);
286} 288}
287 289
288static int taal_sleep_in(struct taal_data *td) 290static int taal_sleep_in(struct taal_data *td)
@@ -294,7 +296,7 @@ static int taal_sleep_in(struct taal_data *td)
294 hw_guard_wait(td); 296 hw_guard_wait(td);
295 297
296 cmd = DCS_SLEEP_IN; 298 cmd = DCS_SLEEP_IN;
297 r = dsi_vc_dcs_write_nosync(TCH, &cmd, 1); 299 r = dsi_vc_dcs_write_nosync(td->channel, &cmd, 1);
298 if (r) 300 if (r)
299 return r; 301 return r;
300 302
@@ -312,7 +314,7 @@ static int taal_sleep_out(struct taal_data *td)
312 314
313 hw_guard_wait(td); 315 hw_guard_wait(td);
314 316
315 r = taal_dcs_write_0(DCS_SLEEP_OUT); 317 r = taal_dcs_write_0(td, DCS_SLEEP_OUT);
316 if (r) 318 if (r)
317 return r; 319 return r;
318 320
@@ -324,30 +326,30 @@ static int taal_sleep_out(struct taal_data *td)
324 return 0; 326 return 0;
325} 327}
326 328
327static int taal_get_id(u8 *id1, u8 *id2, u8 *id3) 329static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3)
328{ 330{
329 int r; 331 int r;
330 332
331 r = taal_dcs_read_1(DCS_GET_ID1, id1); 333 r = taal_dcs_read_1(td, DCS_GET_ID1, id1);
332 if (r) 334 if (r)
333 return r; 335 return r;
334 r = taal_dcs_read_1(DCS_GET_ID2, id2); 336 r = taal_dcs_read_1(td, DCS_GET_ID2, id2);
335 if (r) 337 if (r)
336 return r; 338 return r;
337 r = taal_dcs_read_1(DCS_GET_ID3, id3); 339 r = taal_dcs_read_1(td, DCS_GET_ID3, id3);
338 if (r) 340 if (r)
339 return r; 341 return r;
340 342
341 return 0; 343 return 0;
342} 344}
343 345
344static int taal_set_addr_mode(u8 rotate, bool mirror) 346static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
345{ 347{
346 int r; 348 int r;
347 u8 mode; 349 u8 mode;
348 int b5, b6, b7; 350 int b5, b6, b7;
349 351
350 r = taal_dcs_read_1(DCS_READ_MADCTL, &mode); 352 r = taal_dcs_read_1(td, DCS_READ_MADCTL, &mode);
351 if (r) 353 if (r)
352 return r; 354 return r;
353 355
@@ -381,10 +383,11 @@ static int taal_set_addr_mode(u8 rotate, bool mirror)
381 mode &= ~((1<<7) | (1<<6) | (1<<5)); 383 mode &= ~((1<<7) | (1<<6) | (1<<5));
382 mode |= (b7 << 7) | (b6 << 6) | (b5 << 5); 384 mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
383 385
384 return taal_dcs_write_1(DCS_MEM_ACC_CTRL, mode); 386 return taal_dcs_write_1(td, DCS_MEM_ACC_CTRL, mode);
385} 387}
386 388
387static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h) 389static int taal_set_update_window(struct taal_data *td,
390 u16 x, u16 y, u16 w, u16 h)
388{ 391{
389 int r; 392 int r;
390 u16 x1 = x; 393 u16 x1 = x;
@@ -399,7 +402,7 @@ static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
399 buf[3] = (x2 >> 8) & 0xff; 402 buf[3] = (x2 >> 8) & 0xff;
400 buf[4] = (x2 >> 0) & 0xff; 403 buf[4] = (x2 >> 0) & 0xff;
401 404
402 r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf)); 405 r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
403 if (r) 406 if (r)
404 return r; 407 return r;
405 408
@@ -409,11 +412,11 @@ static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h)
409 buf[3] = (y2 >> 8) & 0xff; 412 buf[3] = (y2 >> 8) & 0xff;
410 buf[4] = (y2 >> 0) & 0xff; 413 buf[4] = (y2 >> 0) & 0xff;
411 414
412 r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf)); 415 r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
413 if (r) 416 if (r)
414 return r; 417 return r;
415 418
416 dsi_vc_send_bta_sync(TCH); 419 dsi_vc_send_bta_sync(td->channel);
417 420
418 return r; 421 return r;
419} 422}
@@ -439,7 +442,7 @@ static int taal_bl_update_status(struct backlight_device *dev)
439 if (td->use_dsi_bl) { 442 if (td->use_dsi_bl) {
440 if (td->enabled) { 443 if (td->enabled) {
441 dsi_bus_lock(); 444 dsi_bus_lock();
442 r = taal_dcs_write_1(DCS_BRIGHTNESS, level); 445 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
443 dsi_bus_unlock(); 446 dsi_bus_unlock();
444 } else { 447 } else {
445 r = 0; 448 r = 0;
@@ -502,7 +505,7 @@ static ssize_t taal_num_errors_show(struct device *dev,
502 505
503 if (td->enabled) { 506 if (td->enabled) {
504 dsi_bus_lock(); 507 dsi_bus_lock();
505 r = taal_dcs_read_1(DCS_READ_NUM_ERRORS, &errors); 508 r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
506 dsi_bus_unlock(); 509 dsi_bus_unlock();
507 } else { 510 } else {
508 r = -ENODEV; 511 r = -ENODEV;
@@ -528,7 +531,7 @@ static ssize_t taal_hw_revision_show(struct device *dev,
528 531
529 if (td->enabled) { 532 if (td->enabled) {
530 dsi_bus_lock(); 533 dsi_bus_lock();
531 r = taal_get_id(&id1, &id2, &id3); 534 r = taal_get_id(td, &id1, &id2, &id3);
532 dsi_bus_unlock(); 535 dsi_bus_unlock();
533 } else { 536 } else {
534 r = -ENODEV; 537 r = -ENODEV;
@@ -590,7 +593,7 @@ static ssize_t store_cabc_mode(struct device *dev,
590 if (td->enabled) { 593 if (td->enabled) {
591 dsi_bus_lock(); 594 dsi_bus_lock();
592 if (!td->cabc_broken) 595 if (!td->cabc_broken)
593 taal_dcs_write_1(DCS_WRITE_CABC, i); 596 taal_dcs_write_1(td, DCS_WRITE_CABC, i);
594 dsi_bus_unlock(); 597 dsi_bus_unlock();
595 } 598 }
596 599
@@ -776,14 +779,29 @@ static int taal_probe(struct omap_dss_device *dssdev)
776 dev_dbg(&dssdev->dev, "Using GPIO TE\n"); 779 dev_dbg(&dssdev->dev, "Using GPIO TE\n");
777 } 780 }
778 781
782 r = omap_dsi_request_vc(dssdev, &td->channel);
783 if (r) {
784 dev_err(&dssdev->dev, "failed to get virtual channel\n");
785 goto err_req_vc;
786 }
787
788 r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
789 if (r) {
790 dev_err(&dssdev->dev, "failed to set VC_ID\n");
791 goto err_vc_id;
792 }
793
779 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group); 794 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
780 if (r) { 795 if (r) {
781 dev_err(&dssdev->dev, "failed to create sysfs files\n"); 796 dev_err(&dssdev->dev, "failed to create sysfs files\n");
782 goto err_sysfs; 797 goto err_vc_id;
783 } 798 }
784 799
785 return 0; 800 return 0;
786err_sysfs: 801
802err_vc_id:
803 omap_dsi_release_vc(dssdev, td->channel);
804err_req_vc:
787 if (panel_data->use_ext_te) 805 if (panel_data->use_ext_te)
788 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev); 806 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
789err_irq: 807err_irq:
@@ -810,6 +828,7 @@ static void taal_remove(struct omap_dss_device *dssdev)
810 dev_dbg(&dssdev->dev, "remove\n"); 828 dev_dbg(&dssdev->dev, "remove\n");
811 829
812 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group); 830 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
831 omap_dsi_release_vc(dssdev, td->channel);
813 832
814 if (panel_data->use_ext_te) { 833 if (panel_data->use_ext_te) {
815 int gpio = panel_data->ext_te_gpio; 834 int gpio = panel_data->ext_te_gpio;
@@ -848,13 +867,13 @@ static int taal_power_on(struct omap_dss_device *dssdev)
848 867
849 taal_hw_reset(dssdev); 868 taal_hw_reset(dssdev);
850 869
851 omapdss_dsi_vc_enable_hs(TCH, false); 870 omapdss_dsi_vc_enable_hs(td->channel, false);
852 871
853 r = taal_sleep_out(td); 872 r = taal_sleep_out(td);
854 if (r) 873 if (r)
855 goto err; 874 goto err;
856 875
857 r = taal_get_id(&id1, &id2, &id3); 876 r = taal_get_id(td, &id1, &id2, &id3);
858 if (r) 877 if (r)
859 goto err; 878 goto err;
860 879
@@ -863,30 +882,30 @@ static int taal_power_on(struct omap_dss_device *dssdev)
863 (id2 == 0x00 || id2 == 0xff || id2 == 0x81)) 882 (id2 == 0x00 || id2 == 0xff || id2 == 0x81))
864 td->cabc_broken = true; 883 td->cabc_broken = true;
865 884
866 r = taal_dcs_write_1(DCS_BRIGHTNESS, 0xff); 885 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff);
867 if (r) 886 if (r)
868 goto err; 887 goto err;
869 888
870 r = taal_dcs_write_1(DCS_CTRL_DISPLAY, 889 r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY,
871 (1<<2) | (1<<5)); /* BL | BCTRL */ 890 (1<<2) | (1<<5)); /* BL | BCTRL */
872 if (r) 891 if (r)
873 goto err; 892 goto err;
874 893
875 r = taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */ 894 r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
876 if (r) 895 if (r)
877 goto err; 896 goto err;
878 897
879 r = taal_set_addr_mode(td->rotate, td->mirror); 898 r = taal_set_addr_mode(td, td->rotate, td->mirror);
880 if (r) 899 if (r)
881 goto err; 900 goto err;
882 901
883 if (!td->cabc_broken) { 902 if (!td->cabc_broken) {
884 r = taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode); 903 r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode);
885 if (r) 904 if (r)
886 goto err; 905 goto err;
887 } 906 }
888 907
889 r = taal_dcs_write_0(DCS_DISPLAY_ON); 908 r = taal_dcs_write_0(td, DCS_DISPLAY_ON);
890 if (r) 909 if (r)
891 goto err; 910 goto err;
892 911
@@ -905,7 +924,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
905 td->intro_printed = true; 924 td->intro_printed = true;
906 } 925 }
907 926
908 omapdss_dsi_vc_enable_hs(TCH, true); 927 omapdss_dsi_vc_enable_hs(td->channel, true);
909 928
910 return 0; 929 return 0;
911err: 930err:
@@ -923,7 +942,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
923 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 942 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
924 int r; 943 int r;
925 944
926 r = taal_dcs_write_0(DCS_DISPLAY_OFF); 945 r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
927 if (!r) { 946 if (!r) {
928 r = taal_sleep_in(td); 947 r = taal_sleep_in(td);
929 /* HACK: wait a bit so that the message goes through */ 948 /* HACK: wait a bit so that the message goes through */
@@ -1091,7 +1110,7 @@ static irqreturn_t taal_te_isr(int irq, void *data)
1091 if (old) { 1110 if (old) {
1092 cancel_delayed_work(&td->te_timeout_work); 1111 cancel_delayed_work(&td->te_timeout_work);
1093 1112
1094 r = omap_dsi_update(dssdev, TCH, 1113 r = omap_dsi_update(dssdev, td->channel,
1095 td->update_region.x, 1114 td->update_region.x,
1096 td->update_region.y, 1115 td->update_region.y,
1097 td->update_region.w, 1116 td->update_region.w,
@@ -1141,7 +1160,7 @@ static int taal_update(struct omap_dss_device *dssdev,
1141 if (r) 1160 if (r)
1142 goto err; 1161 goto err;
1143 1162
1144 r = taal_set_update_window(x, y, w, h); 1163 r = taal_set_update_window(td, x, y, w, h);
1145 if (r) 1164 if (r)
1146 goto err; 1165 goto err;
1147 1166
@@ -1155,7 +1174,7 @@ static int taal_update(struct omap_dss_device *dssdev,
1155 msecs_to_jiffies(250)); 1174 msecs_to_jiffies(250));
1156 atomic_set(&td->do_update, 1); 1175 atomic_set(&td->do_update, 1);
1157 } else { 1176 } else {
1158 r = omap_dsi_update(dssdev, TCH, x, y, w, h, 1177 r = omap_dsi_update(dssdev, td->channel, x, y, w, h,
1159 taal_framedone_cb, dssdev); 1178 taal_framedone_cb, dssdev);
1160 if (r) 1179 if (r)
1161 goto err; 1180 goto err;
@@ -1193,9 +1212,9 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1193 int r; 1212 int r;
1194 1213
1195 if (enable) 1214 if (enable)
1196 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1215 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
1197 else 1216 else
1198 r = taal_dcs_write_0(DCS_TEAR_OFF); 1217 r = taal_dcs_write_0(td, DCS_TEAR_OFF);
1199 1218
1200 if (!panel_data->use_ext_te) 1219 if (!panel_data->use_ext_te)
1201 omapdss_dsi_enable_te(dssdev, enable); 1220 omapdss_dsi_enable_te(dssdev, enable);
@@ -1265,7 +1284,7 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
1265 dsi_bus_lock(); 1284 dsi_bus_lock();
1266 1285
1267 if (td->enabled) { 1286 if (td->enabled) {
1268 r = taal_set_addr_mode(rotate, td->mirror); 1287 r = taal_set_addr_mode(td, rotate, td->mirror);
1269 if (r) 1288 if (r)
1270 goto err; 1289 goto err;
1271 } 1290 }
@@ -1308,7 +1327,7 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
1308 1327
1309 dsi_bus_lock(); 1328 dsi_bus_lock();
1310 if (td->enabled) { 1329 if (td->enabled) {
1311 r = taal_set_addr_mode(td->rotate, enable); 1330 r = taal_set_addr_mode(td, td->rotate, enable);
1312 if (r) 1331 if (r)
1313 goto err; 1332 goto err;
1314 } 1333 }
@@ -1352,13 +1371,13 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1352 1371
1353 dsi_bus_lock(); 1372 dsi_bus_lock();
1354 1373
1355 r = taal_dcs_read_1(DCS_GET_ID1, &id1); 1374 r = taal_dcs_read_1(td, DCS_GET_ID1, &id1);
1356 if (r) 1375 if (r)
1357 goto err2; 1376 goto err2;
1358 r = taal_dcs_read_1(DCS_GET_ID2, &id2); 1377 r = taal_dcs_read_1(td, DCS_GET_ID2, &id2);
1359 if (r) 1378 if (r)
1360 goto err2; 1379 goto err2;
1361 r = taal_dcs_read_1(DCS_GET_ID3, &id3); 1380 r = taal_dcs_read_1(td, DCS_GET_ID3, &id3);
1362 if (r) 1381 if (r)
1363 goto err2; 1382 goto err2;
1364 1383
@@ -1406,9 +1425,9 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1406 else 1425 else
1407 plen = 2; 1426 plen = 2;
1408 1427
1409 taal_set_update_window(x, y, w, h); 1428 taal_set_update_window(td, x, y, w, h);
1410 1429
1411 r = dsi_vc_set_max_rx_packet_size(TCH, plen); 1430 r = dsi_vc_set_max_rx_packet_size(td->channel, plen);
1412 if (r) 1431 if (r)
1413 goto err2; 1432 goto err2;
1414 1433
@@ -1416,7 +1435,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1416 u8 dcs_cmd = first ? 0x2e : 0x3e; 1435 u8 dcs_cmd = first ? 0x2e : 0x3e;
1417 first = 0; 1436 first = 0;
1418 1437
1419 r = dsi_vc_dcs_read(TCH, dcs_cmd, 1438 r = dsi_vc_dcs_read(td->channel, dcs_cmd,
1420 buf + buf_used, size - buf_used); 1439 buf + buf_used, size - buf_used);
1421 1440
1422 if (r < 0) { 1441 if (r < 0) {
@@ -1442,7 +1461,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1442 r = buf_used; 1461 r = buf_used;
1443 1462
1444err3: 1463err3:
1445 dsi_vc_set_max_rx_packet_size(TCH, 1); 1464 dsi_vc_set_max_rx_packet_size(td->channel, 1);
1446err2: 1465err2:
1447 dsi_bus_unlock(); 1466 dsi_bus_unlock();
1448err1: 1467err1:
@@ -1468,7 +1487,7 @@ static void taal_esd_work(struct work_struct *work)
1468 1487
1469 dsi_bus_lock(); 1488 dsi_bus_lock();
1470 1489
1471 r = taal_dcs_read_1(DCS_RDDSDR, &state1); 1490 r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
1472 if (r) { 1491 if (r) {
1473 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1492 dev_err(&dssdev->dev, "failed to read Taal status\n");
1474 goto err; 1493 goto err;
@@ -1481,7 +1500,7 @@ static void taal_esd_work(struct work_struct *work)
1481 goto err; 1500 goto err;
1482 } 1501 }
1483 1502
1484 r = taal_dcs_read_1(DCS_RDDSDR, &state2); 1503 r = taal_dcs_read_1(td, DCS_RDDSDR, &state2);
1485 if (r) { 1504 if (r) {
1486 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1505 dev_err(&dssdev->dev, "failed to read Taal status\n");
1487 goto err; 1506 goto err;
@@ -1497,7 +1516,7 @@ static void taal_esd_work(struct work_struct *work)
1497 /* Self-diagnostics result is also shown on TE GPIO line. We need 1516 /* Self-diagnostics result is also shown on TE GPIO line. We need
1498 * to re-enable TE after self diagnostics */ 1517 * to re-enable TE after self diagnostics */
1499 if (td->te_enabled && panel_data->use_ext_te) { 1518 if (td->te_enabled && panel_data->use_ext_te) {
1500 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1519 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
1501 if (r) 1520 if (r)
1502 goto err; 1521 goto err;
1503 } 1522 }
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 43b64403eaa..bfc5da0e970 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -1,8 +1,8 @@
1menuconfig OMAP2_DSS 1menuconfig OMAP2_DSS
2 tristate "OMAP2/3 Display Subsystem support (EXPERIMENTAL)" 2 tristate "OMAP2+ Display Subsystem support (EXPERIMENTAL)"
3 depends on ARCH_OMAP2 || ARCH_OMAP3 3 depends on ARCH_OMAP2PLUS
4 help 4 help
5 OMAP2/3 Display Subsystem support. 5 OMAP2+ Display Subsystem support.
6 6
7if OMAP2_DSS 7if OMAP2_DSS
8 8
@@ -60,6 +60,14 @@ config OMAP2_DSS_VENC
60 help 60 help
61 OMAP Video Encoder support for S-Video and composite TV-out. 61 OMAP Video Encoder support for S-Video and composite TV-out.
62 62
63config OMAP4_DSS_HDMI
64 bool "HDMI support"
65 depends on ARCH_OMAP4
66 default y
67 help
68 HDMI Interface. This adds the High Definition Multimedia Interface.
69 See http://www.hdmi.org/ for HDMI specification.
70
63config OMAP2_DSS_SDI 71config OMAP2_DSS_SDI
64 bool "SDI support" 72 bool "SDI support"
65 depends on ARCH_OMAP3 73 depends on ARCH_OMAP3
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 7db17b5e570..10d9d3bb3e2 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -5,3 +5,5 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
5omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o 5omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
6omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o 6omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
7omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o 7omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
8omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
9 hdmi_omap4_panel.o
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 8e89f604928..1aa2ed1e786 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -34,332 +34,26 @@
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35 35
36#include <plat/display.h> 36#include <plat/display.h>
37#include <plat/clock.h>
38 37
39#include "dss.h" 38#include "dss.h"
40#include "dss_features.h" 39#include "dss_features.h"
41 40
42static struct { 41static struct {
43 struct platform_device *pdev; 42 struct platform_device *pdev;
44 int ctx_id;
45
46 struct clk *dss_ick;
47 struct clk *dss1_fck;
48 struct clk *dss2_fck;
49 struct clk *dss_54m_fck;
50 struct clk *dss_96m_fck;
51 unsigned num_clks_enabled;
52 43
53 struct regulator *vdds_dsi_reg; 44 struct regulator *vdds_dsi_reg;
54 struct regulator *vdds_sdi_reg; 45 struct regulator *vdds_sdi_reg;
55 struct regulator *vdda_dac_reg;
56} core; 46} core;
57 47
58static void dss_clk_enable_all_no_ctx(void);
59static void dss_clk_disable_all_no_ctx(void);
60static void dss_clk_enable_no_ctx(enum dss_clock clks);
61static void dss_clk_disable_no_ctx(enum dss_clock clks);
62
63static char *def_disp_name; 48static char *def_disp_name;
64module_param_named(def_disp, def_disp_name, charp, 0); 49module_param_named(def_disp, def_disp_name, charp, 0);
65MODULE_PARM_DESC(def_disp_name, "default display name"); 50MODULE_PARM_DESC(def_disp, "default display name");
66 51
67#ifdef DEBUG 52#ifdef DEBUG
68unsigned int dss_debug; 53unsigned int dss_debug;
69module_param_named(debug, dss_debug, bool, 0644); 54module_param_named(debug, dss_debug, bool, 0644);
70#endif 55#endif
71 56
72/* CONTEXT */
73static int dss_get_ctx_id(void)
74{
75 struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
76 int r;
77
78 if (!pdata->get_last_off_on_transaction_id)
79 return 0;
80 r = pdata->get_last_off_on_transaction_id(&core.pdev->dev);
81 if (r < 0) {
82 dev_err(&core.pdev->dev, "getting transaction ID failed, "
83 "will force context restore\n");
84 r = -1;
85 }
86 return r;
87}
88
89int dss_need_ctx_restore(void)
90{
91 int id = dss_get_ctx_id();
92
93 if (id < 0 || id != core.ctx_id) {
94 DSSDBG("ctx id %d -> id %d\n",
95 core.ctx_id, id);
96 core.ctx_id = id;
97 return 1;
98 } else {
99 return 0;
100 }
101}
102
103static void save_all_ctx(void)
104{
105 DSSDBG("save context\n");
106
107 dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
108
109 dss_save_context();
110 dispc_save_context();
111#ifdef CONFIG_OMAP2_DSS_DSI
112 dsi_save_context();
113#endif
114
115 dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
116}
117
118static void restore_all_ctx(void)
119{
120 DSSDBG("restore context\n");
121
122 dss_clk_enable_all_no_ctx();
123
124 dss_restore_context();
125 dispc_restore_context();
126#ifdef CONFIG_OMAP2_DSS_DSI
127 dsi_restore_context();
128#endif
129
130 dss_clk_disable_all_no_ctx();
131}
132
133#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
134/* CLOCKS */
135static void core_dump_clocks(struct seq_file *s)
136{
137 int i;
138 struct clk *clocks[5] = {
139 core.dss_ick,
140 core.dss1_fck,
141 core.dss2_fck,
142 core.dss_54m_fck,
143 core.dss_96m_fck
144 };
145
146 seq_printf(s, "- CORE -\n");
147
148 seq_printf(s, "internal clk count\t\t%u\n", core.num_clks_enabled);
149
150 for (i = 0; i < 5; i++) {
151 if (!clocks[i])
152 continue;
153 seq_printf(s, "%-15s\t%lu\t%d\n",
154 clocks[i]->name,
155 clk_get_rate(clocks[i]),
156 clocks[i]->usecount);
157 }
158}
159#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
160
161static int dss_get_clock(struct clk **clock, const char *clk_name)
162{
163 struct clk *clk;
164
165 clk = clk_get(&core.pdev->dev, clk_name);
166
167 if (IS_ERR(clk)) {
168 DSSERR("can't get clock %s", clk_name);
169 return PTR_ERR(clk);
170 }
171
172 *clock = clk;
173
174 DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
175
176 return 0;
177}
178
179static int dss_get_clocks(void)
180{
181 int r;
182
183 core.dss_ick = NULL;
184 core.dss1_fck = NULL;
185 core.dss2_fck = NULL;
186 core.dss_54m_fck = NULL;
187 core.dss_96m_fck = NULL;
188
189 r = dss_get_clock(&core.dss_ick, "ick");
190 if (r)
191 goto err;
192
193 r = dss_get_clock(&core.dss1_fck, "dss1_fck");
194 if (r)
195 goto err;
196
197 r = dss_get_clock(&core.dss2_fck, "dss2_fck");
198 if (r)
199 goto err;
200
201 r = dss_get_clock(&core.dss_54m_fck, "tv_fck");
202 if (r)
203 goto err;
204
205 r = dss_get_clock(&core.dss_96m_fck, "video_fck");
206 if (r)
207 goto err;
208
209 return 0;
210
211err:
212 if (core.dss_ick)
213 clk_put(core.dss_ick);
214 if (core.dss1_fck)
215 clk_put(core.dss1_fck);
216 if (core.dss2_fck)
217 clk_put(core.dss2_fck);
218 if (core.dss_54m_fck)
219 clk_put(core.dss_54m_fck);
220 if (core.dss_96m_fck)
221 clk_put(core.dss_96m_fck);
222
223 return r;
224}
225
226static void dss_put_clocks(void)
227{
228 if (core.dss_96m_fck)
229 clk_put(core.dss_96m_fck);
230 clk_put(core.dss_54m_fck);
231 clk_put(core.dss1_fck);
232 clk_put(core.dss2_fck);
233 clk_put(core.dss_ick);
234}
235
236unsigned long dss_clk_get_rate(enum dss_clock clk)
237{
238 switch (clk) {
239 case DSS_CLK_ICK:
240 return clk_get_rate(core.dss_ick);
241 case DSS_CLK_FCK1:
242 return clk_get_rate(core.dss1_fck);
243 case DSS_CLK_FCK2:
244 return clk_get_rate(core.dss2_fck);
245 case DSS_CLK_54M:
246 return clk_get_rate(core.dss_54m_fck);
247 case DSS_CLK_96M:
248 return clk_get_rate(core.dss_96m_fck);
249 }
250
251 BUG();
252 return 0;
253}
254
255static unsigned count_clk_bits(enum dss_clock clks)
256{
257 unsigned num_clks = 0;
258
259 if (clks & DSS_CLK_ICK)
260 ++num_clks;
261 if (clks & DSS_CLK_FCK1)
262 ++num_clks;
263 if (clks & DSS_CLK_FCK2)
264 ++num_clks;
265 if (clks & DSS_CLK_54M)
266 ++num_clks;
267 if (clks & DSS_CLK_96M)
268 ++num_clks;
269
270 return num_clks;
271}
272
273static void dss_clk_enable_no_ctx(enum dss_clock clks)
274{
275 unsigned num_clks = count_clk_bits(clks);
276
277 if (clks & DSS_CLK_ICK)
278 clk_enable(core.dss_ick);
279 if (clks & DSS_CLK_FCK1)
280 clk_enable(core.dss1_fck);
281 if (clks & DSS_CLK_FCK2)
282 clk_enable(core.dss2_fck);
283 if (clks & DSS_CLK_54M)
284 clk_enable(core.dss_54m_fck);
285 if (clks & DSS_CLK_96M)
286 clk_enable(core.dss_96m_fck);
287
288 core.num_clks_enabled += num_clks;
289}
290
291void dss_clk_enable(enum dss_clock clks)
292{
293 bool check_ctx = core.num_clks_enabled == 0;
294
295 dss_clk_enable_no_ctx(clks);
296
297 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
298 restore_all_ctx();
299}
300
301static void dss_clk_disable_no_ctx(enum dss_clock clks)
302{
303 unsigned num_clks = count_clk_bits(clks);
304
305 if (clks & DSS_CLK_ICK)
306 clk_disable(core.dss_ick);
307 if (clks & DSS_CLK_FCK1)
308 clk_disable(core.dss1_fck);
309 if (clks & DSS_CLK_FCK2)
310 clk_disable(core.dss2_fck);
311 if (clks & DSS_CLK_54M)
312 clk_disable(core.dss_54m_fck);
313 if (clks & DSS_CLK_96M)
314 clk_disable(core.dss_96m_fck);
315
316 core.num_clks_enabled -= num_clks;
317}
318
319void dss_clk_disable(enum dss_clock clks)
320{
321 if (cpu_is_omap34xx()) {
322 unsigned num_clks = count_clk_bits(clks);
323
324 BUG_ON(core.num_clks_enabled < num_clks);
325
326 if (core.num_clks_enabled == num_clks)
327 save_all_ctx();
328 }
329
330 dss_clk_disable_no_ctx(clks);
331}
332
333static void dss_clk_enable_all_no_ctx(void)
334{
335 enum dss_clock clks;
336
337 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
338 if (cpu_is_omap34xx())
339 clks |= DSS_CLK_96M;
340 dss_clk_enable_no_ctx(clks);
341}
342
343static void dss_clk_disable_all_no_ctx(void)
344{
345 enum dss_clock clks;
346
347 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
348 if (cpu_is_omap34xx())
349 clks |= DSS_CLK_96M;
350 dss_clk_disable_no_ctx(clks);
351}
352
353static void dss_clk_disable_all(void)
354{
355 enum dss_clock clks;
356
357 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
358 if (cpu_is_omap34xx())
359 clks |= DSS_CLK_96M;
360 dss_clk_disable(clks);
361}
362
363/* REGULATORS */ 57/* REGULATORS */
364 58
365struct regulator *dss_get_vdds_dsi(void) 59struct regulator *dss_get_vdds_dsi(void)
@@ -390,32 +84,7 @@ struct regulator *dss_get_vdds_sdi(void)
390 return reg; 84 return reg;
391} 85}
392 86
393struct regulator *dss_get_vdda_dac(void)
394{
395 struct regulator *reg;
396
397 if (core.vdda_dac_reg != NULL)
398 return core.vdda_dac_reg;
399
400 reg = regulator_get(&core.pdev->dev, "vdda_dac");
401 if (!IS_ERR(reg))
402 core.vdda_dac_reg = reg;
403
404 return reg;
405}
406
407/* DEBUGFS */
408#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 87#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
409static void dss_debug_dump_clocks(struct seq_file *s)
410{
411 core_dump_clocks(s);
412 dss_dump_clocks(s);
413 dispc_dump_clocks(s);
414#ifdef CONFIG_OMAP2_DSS_DSI
415 dsi_dump_clocks(s);
416#endif
417}
418
419static int dss_debug_show(struct seq_file *s, void *unused) 88static int dss_debug_show(struct seq_file *s, void *unused)
420{ 89{
421 void (*func)(struct seq_file *) = s->private; 90 void (*func)(struct seq_file *) = s->private;
@@ -497,7 +166,6 @@ static inline void dss_uninitialize_debugfs(void)
497static int omap_dss_probe(struct platform_device *pdev) 166static int omap_dss_probe(struct platform_device *pdev)
498{ 167{
499 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 168 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
500 int skip_init = 0;
501 int r; 169 int r;
502 int i; 170 int i;
503 171
@@ -508,63 +176,43 @@ static int omap_dss_probe(struct platform_device *pdev)
508 dss_init_overlay_managers(pdev); 176 dss_init_overlay_managers(pdev);
509 dss_init_overlays(pdev); 177 dss_init_overlays(pdev);
510 178
511 r = dss_get_clocks(); 179 r = dss_init_platform_driver();
512 if (r)
513 goto err_clocks;
514
515 dss_clk_enable_all_no_ctx();
516
517 core.ctx_id = dss_get_ctx_id();
518 DSSDBG("initial ctx id %u\n", core.ctx_id);
519
520#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
521 /* DISPC_CONTROL */
522 if (omap_readl(0x48050440) & 1) /* LCD enabled? */
523 skip_init = 1;
524#endif
525
526 r = dss_init(skip_init);
527 if (r) { 180 if (r) {
528 DSSERR("Failed to initialize DSS\n"); 181 DSSERR("Failed to initialize DSS platform driver\n");
529 goto err_dss; 182 goto err_dss;
530 } 183 }
531 184
532 r = rfbi_init(); 185 /* keep clocks enabled to prevent context saves/restores during init */
533 if (r) { 186 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
534 DSSERR("Failed to initialize rfbi\n");
535 goto err_rfbi;
536 }
537 187
538 r = dpi_init(pdev); 188 r = rfbi_init_platform_driver();
539 if (r) { 189 if (r) {
540 DSSERR("Failed to initialize dpi\n"); 190 DSSERR("Failed to initialize rfbi platform driver\n");
541 goto err_dpi; 191 goto err_rfbi;
542 } 192 }
543 193
544 r = dispc_init(); 194 r = dispc_init_platform_driver();
545 if (r) { 195 if (r) {
546 DSSERR("Failed to initialize dispc\n"); 196 DSSERR("Failed to initialize dispc platform driver\n");
547 goto err_dispc; 197 goto err_dispc;
548 } 198 }
549 199
550 r = venc_init(pdev); 200 r = venc_init_platform_driver();
551 if (r) { 201 if (r) {
552 DSSERR("Failed to initialize venc\n"); 202 DSSERR("Failed to initialize venc platform driver\n");
553 goto err_venc; 203 goto err_venc;
554 } 204 }
555 205
556 if (cpu_is_omap34xx()) { 206 r = dsi_init_platform_driver();
557 r = sdi_init(skip_init); 207 if (r) {
558 if (r) { 208 DSSERR("Failed to initialize DSI platform driver\n");
559 DSSERR("Failed to initialize SDI\n"); 209 goto err_dsi;
560 goto err_sdi; 210 }
561 }
562 211
563 r = dsi_init(pdev); 212 r = hdmi_init_platform_driver();
564 if (r) { 213 if (r) {
565 DSSERR("Failed to initialize DSI\n"); 214 DSSERR("Failed to initialize hdmi\n");
566 goto err_dsi; 215 goto err_hdmi;
567 }
568 } 216 }
569 217
570 r = dss_initialize_debugfs(); 218 r = dss_initialize_debugfs();
@@ -589,32 +237,25 @@ static int omap_dss_probe(struct platform_device *pdev)
589 pdata->default_device = dssdev; 237 pdata->default_device = dssdev;
590 } 238 }
591 239
592 dss_clk_disable_all(); 240 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
593 241
594 return 0; 242 return 0;
595 243
596err_register: 244err_register:
597 dss_uninitialize_debugfs(); 245 dss_uninitialize_debugfs();
598err_debugfs: 246err_debugfs:
599 if (cpu_is_omap34xx()) 247 hdmi_uninit_platform_driver();
600 dsi_exit(); 248err_hdmi:
249 dsi_uninit_platform_driver();
601err_dsi: 250err_dsi:
602 if (cpu_is_omap34xx()) 251 venc_uninit_platform_driver();
603 sdi_exit();
604err_sdi:
605 venc_exit();
606err_venc: 252err_venc:
607 dispc_exit(); 253 dispc_uninit_platform_driver();
608err_dispc: 254err_dispc:
609 dpi_exit(); 255 rfbi_uninit_platform_driver();
610err_dpi:
611 rfbi_exit();
612err_rfbi: 256err_rfbi:
613 dss_exit(); 257 dss_uninit_platform_driver();
614err_dss: 258err_dss:
615 dss_clk_disable_all_no_ctx();
616 dss_put_clocks();
617err_clocks:
618 259
619 return r; 260 return r;
620} 261}
@@ -623,61 +264,15 @@ static int omap_dss_remove(struct platform_device *pdev)
623{ 264{
624 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 265 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
625 int i; 266 int i;
626 int c;
627 267
628 dss_uninitialize_debugfs(); 268 dss_uninitialize_debugfs();
629 269
630 venc_exit(); 270 venc_uninit_platform_driver();
631 dispc_exit(); 271 dispc_uninit_platform_driver();
632 dpi_exit(); 272 rfbi_uninit_platform_driver();
633 rfbi_exit(); 273 dsi_uninit_platform_driver();
634 if (cpu_is_omap34xx()) { 274 hdmi_uninit_platform_driver();
635 dsi_exit(); 275 dss_uninit_platform_driver();
636 sdi_exit();
637 }
638
639 dss_exit();
640
641 /* these should be removed at some point */
642 c = core.dss_ick->usecount;
643 if (c > 0) {
644 DSSERR("warning: dss_ick usecount %d, disabling\n", c);
645 while (c-- > 0)
646 clk_disable(core.dss_ick);
647 }
648
649 c = core.dss1_fck->usecount;
650 if (c > 0) {
651 DSSERR("warning: dss1_fck usecount %d, disabling\n", c);
652 while (c-- > 0)
653 clk_disable(core.dss1_fck);
654 }
655
656 c = core.dss2_fck->usecount;
657 if (c > 0) {
658 DSSERR("warning: dss2_fck usecount %d, disabling\n", c);
659 while (c-- > 0)
660 clk_disable(core.dss2_fck);
661 }
662
663 c = core.dss_54m_fck->usecount;
664 if (c > 0) {
665 DSSERR("warning: dss_54m_fck usecount %d, disabling\n", c);
666 while (c-- > 0)
667 clk_disable(core.dss_54m_fck);
668 }
669
670 if (core.dss_96m_fck) {
671 c = core.dss_96m_fck->usecount;
672 if (c > 0) {
673 DSSERR("warning: dss_96m_fck usecount %d, disabling\n",
674 c);
675 while (c-- > 0)
676 clk_disable(core.dss_96m_fck);
677 }
678 }
679
680 dss_put_clocks();
681 276
682 dss_uninit_overlays(pdev); 277 dss_uninit_overlays(pdev);
683 dss_uninit_overlay_managers(pdev); 278 dss_uninit_overlay_managers(pdev);
@@ -965,11 +560,6 @@ static void __exit omap_dss_exit(void)
965 core.vdds_sdi_reg = NULL; 560 core.vdds_sdi_reg = NULL;
966 } 561 }
967 562
968 if (core.vdda_dac_reg != NULL) {
969 regulator_put(core.vdda_dac_reg);
970 core.vdda_dac_reg = NULL;
971 }
972
973 platform_driver_unregister(&omap_dss_driver); 563 platform_driver_unregister(&omap_dss_driver);
974 564
975 omap_dss_bus_unregister(); 565 omap_dss_bus_unregister();
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 9f8c69f16e6..7804779c9da 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -32,6 +32,7 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/workqueue.h> 33#include <linux/workqueue.h>
34#include <linux/hardirq.h> 34#include <linux/hardirq.h>
35#include <linux/interrupt.h>
35 36
36#include <plat/sram.h> 37#include <plat/sram.h>
37#include <plat/clock.h> 38#include <plat/clock.h>
@@ -42,8 +43,6 @@
42#include "dss_features.h" 43#include "dss_features.h"
43 44
44/* DISPC */ 45/* DISPC */
45#define DISPC_BASE 0x48050400
46
47#define DISPC_SZ_REGS SZ_4K 46#define DISPC_SZ_REGS SZ_4K
48 47
49struct dispc_reg { u16 idx; }; 48struct dispc_reg { u16 idx; };
@@ -74,7 +73,7 @@ struct dispc_reg { u16 idx; };
74#define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400) 73#define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400)
75#define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404) 74#define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404)
76#define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408) 75#define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408)
77#define DISPC_DIVISOR(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C) 76#define DISPC_DIVISORo(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C)
78#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074) 77#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074)
79#define DISPC_SIZE_DIG DISPC_REG(0x0078) 78#define DISPC_SIZE_DIG DISPC_REG(0x0078)
80#define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC) 79#define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC)
@@ -129,6 +128,7 @@ struct dispc_reg { u16 idx; };
129 128
130#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04) 129#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04)
131 130
131#define DISPC_DIVISOR DISPC_REG(0x0804)
132 132
133#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \ 133#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
134 DISPC_IRQ_OCP_ERR | \ 134 DISPC_IRQ_OCP_ERR | \
@@ -178,7 +178,9 @@ struct dispc_irq_stats {
178}; 178};
179 179
180static struct { 180static struct {
181 struct platform_device *pdev;
181 void __iomem *base; 182 void __iomem *base;
183 int irq;
182 184
183 u32 fifo_size[3]; 185 u32 fifo_size[3];
184 186
@@ -230,7 +232,7 @@ void dispc_save_context(void)
230 SR(TIMING_H(0)); 232 SR(TIMING_H(0));
231 SR(TIMING_V(0)); 233 SR(TIMING_V(0));
232 SR(POL_FREQ(0)); 234 SR(POL_FREQ(0));
233 SR(DIVISOR(0)); 235 SR(DIVISORo(0));
234 SR(GLOBAL_ALPHA); 236 SR(GLOBAL_ALPHA);
235 SR(SIZE_DIG); 237 SR(SIZE_DIG);
236 SR(SIZE_LCD(0)); 238 SR(SIZE_LCD(0));
@@ -242,7 +244,7 @@ void dispc_save_context(void)
242 SR(TIMING_H(2)); 244 SR(TIMING_H(2));
243 SR(TIMING_V(2)); 245 SR(TIMING_V(2));
244 SR(POL_FREQ(2)); 246 SR(POL_FREQ(2));
245 SR(DIVISOR(2)); 247 SR(DIVISORo(2));
246 SR(CONFIG2); 248 SR(CONFIG2);
247 } 249 }
248 250
@@ -373,6 +375,9 @@ void dispc_save_context(void)
373 SR(VID_FIR_COEF_V(1, 7)); 375 SR(VID_FIR_COEF_V(1, 7));
374 376
375 SR(VID_PRELOAD(1)); 377 SR(VID_PRELOAD(1));
378
379 if (dss_has_feature(FEAT_CORE_CLK_DIV))
380 SR(DIVISOR);
376} 381}
377 382
378void dispc_restore_context(void) 383void dispc_restore_context(void)
@@ -389,7 +394,7 @@ void dispc_restore_context(void)
389 RR(TIMING_H(0)); 394 RR(TIMING_H(0));
390 RR(TIMING_V(0)); 395 RR(TIMING_V(0));
391 RR(POL_FREQ(0)); 396 RR(POL_FREQ(0));
392 RR(DIVISOR(0)); 397 RR(DIVISORo(0));
393 RR(GLOBAL_ALPHA); 398 RR(GLOBAL_ALPHA);
394 RR(SIZE_DIG); 399 RR(SIZE_DIG);
395 RR(SIZE_LCD(0)); 400 RR(SIZE_LCD(0));
@@ -400,7 +405,7 @@ void dispc_restore_context(void)
400 RR(TIMING_H(2)); 405 RR(TIMING_H(2));
401 RR(TIMING_V(2)); 406 RR(TIMING_V(2));
402 RR(POL_FREQ(2)); 407 RR(POL_FREQ(2));
403 RR(DIVISOR(2)); 408 RR(DIVISORo(2));
404 RR(CONFIG2); 409 RR(CONFIG2);
405 } 410 }
406 411
@@ -532,6 +537,9 @@ void dispc_restore_context(void)
532 537
533 RR(VID_PRELOAD(1)); 538 RR(VID_PRELOAD(1));
534 539
540 if (dss_has_feature(FEAT_CORE_CLK_DIV))
541 RR(DIVISOR);
542
535 /* enable last, because LCD & DIGIT enable are here */ 543 /* enable last, because LCD & DIGIT enable are here */
536 RR(CONTROL); 544 RR(CONTROL);
537 if (dss_has_feature(FEAT_MGR_LCD2)) 545 if (dss_has_feature(FEAT_MGR_LCD2))
@@ -552,9 +560,9 @@ void dispc_restore_context(void)
552static inline void enable_clocks(bool enable) 560static inline void enable_clocks(bool enable)
553{ 561{
554 if (enable) 562 if (enable)
555 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 563 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
556 else 564 else
557 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 565 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
558} 566}
559 567
560bool dispc_go_busy(enum omap_channel channel) 568bool dispc_go_busy(enum omap_channel channel)
@@ -1000,6 +1008,20 @@ void dispc_set_burst_size(enum omap_plane plane,
1000 enable_clocks(0); 1008 enable_clocks(0);
1001} 1009}
1002 1010
1011void dispc_enable_gamma_table(bool enable)
1012{
1013 /*
1014 * This is partially implemented to support only disabling of
1015 * the gamma table.
1016 */
1017 if (enable) {
1018 DSSWARN("Gamma table enabling for TV not yet supported");
1019 return;
1020 }
1021
1022 REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
1023}
1024
1003static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) 1025static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
1004{ 1026{
1005 u32 val; 1027 u32 val;
@@ -1129,10 +1151,16 @@ static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
1129 u32 val; 1151 u32 val;
1130 const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0), 1152 const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0),
1131 DISPC_VID_ACCU0(1) }; 1153 DISPC_VID_ACCU0(1) };
1154 u8 hor_start, hor_end, vert_start, vert_end;
1132 1155
1133 BUG_ON(plane == OMAP_DSS_GFX); 1156 BUG_ON(plane == OMAP_DSS_GFX);
1134 1157
1135 val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); 1158 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
1159 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
1160
1161 val = FLD_VAL(vaccu, vert_start, vert_end) |
1162 FLD_VAL(haccu, hor_start, hor_end);
1163
1136 dispc_write_reg(ac0_reg[plane-1], val); 1164 dispc_write_reg(ac0_reg[plane-1], val);
1137} 1165}
1138 1166
@@ -1141,10 +1169,16 @@ static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
1141 u32 val; 1169 u32 val;
1142 const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0), 1170 const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0),
1143 DISPC_VID_ACCU1(1) }; 1171 DISPC_VID_ACCU1(1) };
1172 u8 hor_start, hor_end, vert_start, vert_end;
1144 1173
1145 BUG_ON(plane == OMAP_DSS_GFX); 1174 BUG_ON(plane == OMAP_DSS_GFX);
1146 1175
1147 val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); 1176 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
1177 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
1178
1179 val = FLD_VAL(vaccu, vert_start, vert_end) |
1180 FLD_VAL(haccu, hor_start, hor_end);
1181
1148 dispc_write_reg(ac1_reg[plane-1], val); 1182 dispc_write_reg(ac1_reg[plane-1], val);
1149} 1183}
1150 1184
@@ -1182,16 +1216,25 @@ static void _dispc_set_scaling(enum omap_plane plane,
1182 _dispc_set_fir(plane, fir_hinc, fir_vinc); 1216 _dispc_set_fir(plane, fir_hinc, fir_vinc);
1183 1217
1184 l = dispc_read_reg(dispc_reg_att[plane]); 1218 l = dispc_read_reg(dispc_reg_att[plane]);
1185 l &= ~((0x0f << 5) | (0x3 << 21));
1186 1219
1220 /* RESIZEENABLE and VERTICALTAPS */
1221 l &= ~((0x3 << 5) | (0x1 << 21));
1187 l |= fir_hinc ? (1 << 5) : 0; 1222 l |= fir_hinc ? (1 << 5) : 0;
1188 l |= fir_vinc ? (1 << 6) : 0; 1223 l |= fir_vinc ? (1 << 6) : 0;
1224 l |= five_taps ? (1 << 21) : 0;
1189 1225
1190 l |= hscaleup ? 0 : (1 << 7); 1226 /* VRESIZECONF and HRESIZECONF */
1191 l |= vscaleup ? 0 : (1 << 8); 1227 if (dss_has_feature(FEAT_RESIZECONF)) {
1228 l &= ~(0x3 << 7);
1229 l |= hscaleup ? 0 : (1 << 7);
1230 l |= vscaleup ? 0 : (1 << 8);
1231 }
1192 1232
1193 l |= five_taps ? (1 << 21) : 0; 1233 /* LINEBUFFERSPLIT */
1194 l |= five_taps ? (1 << 22) : 0; 1234 if (dss_has_feature(FEAT_LINEBUFFERSPLIT)) {
1235 l &= ~(0x1 << 22);
1236 l |= five_taps ? (1 << 22) : 0;
1237 }
1195 1238
1196 dispc_write_reg(dispc_reg_att[plane], l); 1239 dispc_write_reg(dispc_reg_att[plane], l);
1197 1240
@@ -1215,9 +1258,11 @@ static void _dispc_set_scaling(enum omap_plane plane,
1215static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation, 1258static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1216 bool mirroring, enum omap_color_mode color_mode) 1259 bool mirroring, enum omap_color_mode color_mode)
1217{ 1260{
1261 bool row_repeat = false;
1262 int vidrot = 0;
1263
1218 if (color_mode == OMAP_DSS_COLOR_YUV2 || 1264 if (color_mode == OMAP_DSS_COLOR_YUV2 ||
1219 color_mode == OMAP_DSS_COLOR_UYVY) { 1265 color_mode == OMAP_DSS_COLOR_UYVY) {
1220 int vidrot = 0;
1221 1266
1222 if (mirroring) { 1267 if (mirroring) {
1223 switch (rotation) { 1268 switch (rotation) {
@@ -1251,16 +1296,15 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1251 } 1296 }
1252 } 1297 }
1253 1298
1254 REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
1255
1256 if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270) 1299 if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270)
1257 REG_FLD_MOD(dispc_reg_att[plane], 0x1, 18, 18); 1300 row_repeat = true;
1258 else 1301 else
1259 REG_FLD_MOD(dispc_reg_att[plane], 0x0, 18, 18); 1302 row_repeat = false;
1260 } else {
1261 REG_FLD_MOD(dispc_reg_att[plane], 0, 13, 12);
1262 REG_FLD_MOD(dispc_reg_att[plane], 0, 18, 18);
1263 } 1303 }
1304
1305 REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
1306 if (dss_has_feature(FEAT_ROWREPEATENABLE))
1307 REG_FLD_MOD(dispc_reg_att[plane], row_repeat ? 1 : 0, 18, 18);
1264} 1308}
1265 1309
1266static int color_mode_to_bpp(enum omap_color_mode color_mode) 1310static int color_mode_to_bpp(enum omap_color_mode color_mode)
@@ -2293,7 +2337,7 @@ static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
2293 BUG_ON(pck_div < 2); 2337 BUG_ON(pck_div < 2);
2294 2338
2295 enable_clocks(1); 2339 enable_clocks(1);
2296 dispc_write_reg(DISPC_DIVISOR(channel), 2340 dispc_write_reg(DISPC_DIVISORo(channel),
2297 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); 2341 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
2298 enable_clocks(0); 2342 enable_clocks(0);
2299} 2343}
@@ -2302,7 +2346,7 @@ static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
2302 int *pck_div) 2346 int *pck_div)
2303{ 2347{
2304 u32 l; 2348 u32 l;
2305 l = dispc_read_reg(DISPC_DIVISOR(channel)); 2349 l = dispc_read_reg(DISPC_DIVISORo(channel));
2306 *lck_div = FLD_GET(l, 23, 16); 2350 *lck_div = FLD_GET(l, 23, 16);
2307 *pck_div = FLD_GET(l, 7, 0); 2351 *pck_div = FLD_GET(l, 7, 0);
2308} 2352}
@@ -2311,14 +2355,17 @@ unsigned long dispc_fclk_rate(void)
2311{ 2355{
2312 unsigned long r = 0; 2356 unsigned long r = 0;
2313 2357
2314 if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) 2358 switch (dss_get_dispc_clk_source()) {
2315 r = dss_clk_get_rate(DSS_CLK_FCK1); 2359 case DSS_CLK_SRC_FCK:
2316 else 2360 r = dss_clk_get_rate(DSS_CLK_FCK);
2317#ifdef CONFIG_OMAP2_DSS_DSI 2361 break;
2318 r = dsi_get_dsi1_pll_rate(); 2362 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2319#else 2363 r = dsi_get_pll_hsdiv_dispc_rate();
2320 BUG(); 2364 break;
2321#endif 2365 default:
2366 BUG();
2367 }
2368
2322 return r; 2369 return r;
2323} 2370}
2324 2371
@@ -2328,47 +2375,72 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
2328 unsigned long r; 2375 unsigned long r;
2329 u32 l; 2376 u32 l;
2330 2377
2331 l = dispc_read_reg(DISPC_DIVISOR(channel)); 2378 l = dispc_read_reg(DISPC_DIVISORo(channel));
2332 2379
2333 lcd = FLD_GET(l, 23, 16); 2380 lcd = FLD_GET(l, 23, 16);
2334 2381
2335 r = dispc_fclk_rate(); 2382 switch (dss_get_lcd_clk_source(channel)) {
2383 case DSS_CLK_SRC_FCK:
2384 r = dss_clk_get_rate(DSS_CLK_FCK);
2385 break;
2386 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2387 r = dsi_get_pll_hsdiv_dispc_rate();
2388 break;
2389 default:
2390 BUG();
2391 }
2336 2392
2337 return r / lcd; 2393 return r / lcd;
2338} 2394}
2339 2395
2340unsigned long dispc_pclk_rate(enum omap_channel channel) 2396unsigned long dispc_pclk_rate(enum omap_channel channel)
2341{ 2397{
2342 int lcd, pcd; 2398 int pcd;
2343 unsigned long r; 2399 unsigned long r;
2344 u32 l; 2400 u32 l;
2345 2401
2346 l = dispc_read_reg(DISPC_DIVISOR(channel)); 2402 l = dispc_read_reg(DISPC_DIVISORo(channel));
2347 2403
2348 lcd = FLD_GET(l, 23, 16);
2349 pcd = FLD_GET(l, 7, 0); 2404 pcd = FLD_GET(l, 7, 0);
2350 2405
2351 r = dispc_fclk_rate(); 2406 r = dispc_lclk_rate(channel);
2352 2407
2353 return r / lcd / pcd; 2408 return r / pcd;
2354} 2409}
2355 2410
2356void dispc_dump_clocks(struct seq_file *s) 2411void dispc_dump_clocks(struct seq_file *s)
2357{ 2412{
2358 int lcd, pcd; 2413 int lcd, pcd;
2414 u32 l;
2415 enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
2416 enum dss_clk_source lcd_clk_src;
2359 2417
2360 enable_clocks(1); 2418 enable_clocks(1);
2361 2419
2362 seq_printf(s, "- DISPC -\n"); 2420 seq_printf(s, "- DISPC -\n");
2363 2421
2364 seq_printf(s, "dispc fclk source = %s\n", 2422 seq_printf(s, "dispc fclk source = %s (%s)\n",
2365 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 2423 dss_get_generic_clk_source_name(dispc_clk_src),
2366 "dss1_alwon_fclk" : "dsi1_pll_fclk"); 2424 dss_feat_get_clk_source_name(dispc_clk_src));
2367 2425
2368 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); 2426 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
2369 2427
2428 if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
2429 seq_printf(s, "- DISPC-CORE-CLK -\n");
2430 l = dispc_read_reg(DISPC_DIVISOR);
2431 lcd = FLD_GET(l, 23, 16);
2432
2433 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2434 (dispc_fclk_rate()/lcd), lcd);
2435 }
2370 seq_printf(s, "- LCD1 -\n"); 2436 seq_printf(s, "- LCD1 -\n");
2371 2437
2438 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD);
2439
2440 seq_printf(s, "lcd1_clk source = %s (%s)\n",
2441 dss_get_generic_clk_source_name(lcd_clk_src),
2442 dss_feat_get_clk_source_name(lcd_clk_src));
2443
2372 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd); 2444 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
2373 2445
2374 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2446 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
@@ -2378,6 +2450,12 @@ void dispc_dump_clocks(struct seq_file *s)
2378 if (dss_has_feature(FEAT_MGR_LCD2)) { 2450 if (dss_has_feature(FEAT_MGR_LCD2)) {
2379 seq_printf(s, "- LCD2 -\n"); 2451 seq_printf(s, "- LCD2 -\n");
2380 2452
2453 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD2);
2454
2455 seq_printf(s, "lcd2_clk source = %s (%s)\n",
2456 dss_get_generic_clk_source_name(lcd_clk_src),
2457 dss_feat_get_clk_source_name(lcd_clk_src));
2458
2381 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd); 2459 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd);
2382 2460
2383 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2461 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
@@ -2440,7 +2518,7 @@ void dispc_dump_regs(struct seq_file *s)
2440{ 2518{
2441#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) 2519#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r))
2442 2520
2443 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 2521 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
2444 2522
2445 DUMPREG(DISPC_REVISION); 2523 DUMPREG(DISPC_REVISION);
2446 DUMPREG(DISPC_SYSCONFIG); 2524 DUMPREG(DISPC_SYSCONFIG);
@@ -2459,7 +2537,7 @@ void dispc_dump_regs(struct seq_file *s)
2459 DUMPREG(DISPC_TIMING_H(0)); 2537 DUMPREG(DISPC_TIMING_H(0));
2460 DUMPREG(DISPC_TIMING_V(0)); 2538 DUMPREG(DISPC_TIMING_V(0));
2461 DUMPREG(DISPC_POL_FREQ(0)); 2539 DUMPREG(DISPC_POL_FREQ(0));
2462 DUMPREG(DISPC_DIVISOR(0)); 2540 DUMPREG(DISPC_DIVISORo(0));
2463 DUMPREG(DISPC_GLOBAL_ALPHA); 2541 DUMPREG(DISPC_GLOBAL_ALPHA);
2464 DUMPREG(DISPC_SIZE_DIG); 2542 DUMPREG(DISPC_SIZE_DIG);
2465 DUMPREG(DISPC_SIZE_LCD(0)); 2543 DUMPREG(DISPC_SIZE_LCD(0));
@@ -2471,7 +2549,7 @@ void dispc_dump_regs(struct seq_file *s)
2471 DUMPREG(DISPC_TIMING_H(2)); 2549 DUMPREG(DISPC_TIMING_H(2));
2472 DUMPREG(DISPC_TIMING_V(2)); 2550 DUMPREG(DISPC_TIMING_V(2));
2473 DUMPREG(DISPC_POL_FREQ(2)); 2551 DUMPREG(DISPC_POL_FREQ(2));
2474 DUMPREG(DISPC_DIVISOR(2)); 2552 DUMPREG(DISPC_DIVISORo(2));
2475 DUMPREG(DISPC_SIZE_LCD(2)); 2553 DUMPREG(DISPC_SIZE_LCD(2));
2476 } 2554 }
2477 2555
@@ -2597,7 +2675,7 @@ void dispc_dump_regs(struct seq_file *s)
2597 DUMPREG(DISPC_VID_PRELOAD(0)); 2675 DUMPREG(DISPC_VID_PRELOAD(0));
2598 DUMPREG(DISPC_VID_PRELOAD(1)); 2676 DUMPREG(DISPC_VID_PRELOAD(1));
2599 2677
2600 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 2678 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
2601#undef DUMPREG 2679#undef DUMPREG
2602} 2680}
2603 2681
@@ -2713,8 +2791,8 @@ int dispc_get_clock_div(enum omap_channel channel,
2713 2791
2714 fck = dispc_fclk_rate(); 2792 fck = dispc_fclk_rate();
2715 2793
2716 cinfo->lck_div = REG_GET(DISPC_DIVISOR(channel), 23, 16); 2794 cinfo->lck_div = REG_GET(DISPC_DIVISORo(channel), 23, 16);
2717 cinfo->pck_div = REG_GET(DISPC_DIVISOR(channel), 7, 0); 2795 cinfo->pck_div = REG_GET(DISPC_DIVISORo(channel), 7, 0);
2718 2796
2719 cinfo->lck = fck / cinfo->lck_div; 2797 cinfo->lck = fck / cinfo->lck_div;
2720 cinfo->pck = cinfo->lck / cinfo->pck_div; 2798 cinfo->pck = cinfo->lck / cinfo->pck_div;
@@ -2791,6 +2869,9 @@ int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
2791 break; 2869 break;
2792 } 2870 }
2793 2871
2872 if (ret)
2873 goto err;
2874
2794 _omap_dispc_set_irqs(); 2875 _omap_dispc_set_irqs();
2795 2876
2796 spin_unlock_irqrestore(&dispc.irq_lock, flags); 2877 spin_unlock_irqrestore(&dispc.irq_lock, flags);
@@ -2866,10 +2947,10 @@ static void print_irq_status(u32 status)
2866 * but we presume they are on because we got an IRQ. However, 2947 * but we presume they are on because we got an IRQ. However,
2867 * an irq handler may turn the clocks off, so we may not have 2948 * an irq handler may turn the clocks off, so we may not have
2868 * clock later in the function. */ 2949 * clock later in the function. */
2869void dispc_irq_handler(void) 2950static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
2870{ 2951{
2871 int i; 2952 int i;
2872 u32 irqstatus; 2953 u32 irqstatus, irqenable;
2873 u32 handledirqs = 0; 2954 u32 handledirqs = 0;
2874 u32 unhandled_errors; 2955 u32 unhandled_errors;
2875 struct omap_dispc_isr_data *isr_data; 2956 struct omap_dispc_isr_data *isr_data;
@@ -2878,6 +2959,13 @@ void dispc_irq_handler(void)
2878 spin_lock(&dispc.irq_lock); 2959 spin_lock(&dispc.irq_lock);
2879 2960
2880 irqstatus = dispc_read_reg(DISPC_IRQSTATUS); 2961 irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
2962 irqenable = dispc_read_reg(DISPC_IRQENABLE);
2963
2964 /* IRQ is not for us */
2965 if (!(irqstatus & irqenable)) {
2966 spin_unlock(&dispc.irq_lock);
2967 return IRQ_NONE;
2968 }
2881 2969
2882#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 2970#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
2883 spin_lock(&dispc.irq_stats_lock); 2971 spin_lock(&dispc.irq_stats_lock);
@@ -2929,6 +3017,8 @@ void dispc_irq_handler(void)
2929 } 3017 }
2930 3018
2931 spin_unlock(&dispc.irq_lock); 3019 spin_unlock(&dispc.irq_lock);
3020
3021 return IRQ_HANDLED;
2932} 3022}
2933 3023
2934static void dispc_error_worker(struct work_struct *work) 3024static void dispc_error_worker(struct work_struct *work)
@@ -3253,6 +3343,15 @@ static void _omap_dispc_initial_config(void)
3253 l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */ 3343 l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */
3254 dispc_write_reg(DISPC_SYSCONFIG, l); 3344 dispc_write_reg(DISPC_SYSCONFIG, l);
3255 3345
3346 /* Exclusively enable DISPC_CORE_CLK and set divider to 1 */
3347 if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
3348 l = dispc_read_reg(DISPC_DIVISOR);
3349 /* Use DISPC_DIVISOR.LCD, instead of DISPC_DIVISOR1.LCD */
3350 l = FLD_MOD(l, 1, 0, 0);
3351 l = FLD_MOD(l, 1, 23, 16);
3352 dispc_write_reg(DISPC_DIVISOR, l);
3353 }
3354
3256 /* FUNCGATED */ 3355 /* FUNCGATED */
3257 if (dss_has_feature(FEAT_FUNCGATED)) 3356 if (dss_has_feature(FEAT_FUNCGATED))
3258 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); 3357 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
@@ -3269,47 +3368,6 @@ static void _omap_dispc_initial_config(void)
3269 dispc_read_plane_fifo_sizes(); 3368 dispc_read_plane_fifo_sizes();
3270} 3369}
3271 3370
3272int dispc_init(void)
3273{
3274 u32 rev;
3275
3276 spin_lock_init(&dispc.irq_lock);
3277
3278#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3279 spin_lock_init(&dispc.irq_stats_lock);
3280 dispc.irq_stats.last_reset = jiffies;
3281#endif
3282
3283 INIT_WORK(&dispc.error_work, dispc_error_worker);
3284
3285 dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS);
3286 if (!dispc.base) {
3287 DSSERR("can't ioremap DISPC\n");
3288 return -ENOMEM;
3289 }
3290
3291 enable_clocks(1);
3292
3293 _omap_dispc_initial_config();
3294
3295 _omap_dispc_initialize_irq();
3296
3297 dispc_save_context();
3298
3299 rev = dispc_read_reg(DISPC_REVISION);
3300 printk(KERN_INFO "OMAP DISPC rev %d.%d\n",
3301 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3302
3303 enable_clocks(0);
3304
3305 return 0;
3306}
3307
3308void dispc_exit(void)
3309{
3310 iounmap(dispc.base);
3311}
3312
3313int dispc_enable_plane(enum omap_plane plane, bool enable) 3371int dispc_enable_plane(enum omap_plane plane, bool enable)
3314{ 3372{
3315 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); 3373 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
@@ -3359,3 +3417,94 @@ int dispc_setup_plane(enum omap_plane plane,
3359 3417
3360 return r; 3418 return r;
3361} 3419}
3420
3421/* DISPC HW IP initialisation */
3422static int omap_dispchw_probe(struct platform_device *pdev)
3423{
3424 u32 rev;
3425 int r = 0;
3426 struct resource *dispc_mem;
3427
3428 dispc.pdev = pdev;
3429
3430 spin_lock_init(&dispc.irq_lock);
3431
3432#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3433 spin_lock_init(&dispc.irq_stats_lock);
3434 dispc.irq_stats.last_reset = jiffies;
3435#endif
3436
3437 INIT_WORK(&dispc.error_work, dispc_error_worker);
3438
3439 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
3440 if (!dispc_mem) {
3441 DSSERR("can't get IORESOURCE_MEM DISPC\n");
3442 r = -EINVAL;
3443 goto fail0;
3444 }
3445 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem));
3446 if (!dispc.base) {
3447 DSSERR("can't ioremap DISPC\n");
3448 r = -ENOMEM;
3449 goto fail0;
3450 }
3451 dispc.irq = platform_get_irq(dispc.pdev, 0);
3452 if (dispc.irq < 0) {
3453 DSSERR("platform_get_irq failed\n");
3454 r = -ENODEV;
3455 goto fail1;
3456 }
3457
3458 r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED,
3459 "OMAP DISPC", dispc.pdev);
3460 if (r < 0) {
3461 DSSERR("request_irq failed\n");
3462 goto fail1;
3463 }
3464
3465 enable_clocks(1);
3466
3467 _omap_dispc_initial_config();
3468
3469 _omap_dispc_initialize_irq();
3470
3471 dispc_save_context();
3472
3473 rev = dispc_read_reg(DISPC_REVISION);
3474 dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
3475 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3476
3477 enable_clocks(0);
3478
3479 return 0;
3480fail1:
3481 iounmap(dispc.base);
3482fail0:
3483 return r;
3484}
3485
3486static int omap_dispchw_remove(struct platform_device *pdev)
3487{
3488 free_irq(dispc.irq, dispc.pdev);
3489 iounmap(dispc.base);
3490 return 0;
3491}
3492
3493static struct platform_driver omap_dispchw_driver = {
3494 .probe = omap_dispchw_probe,
3495 .remove = omap_dispchw_remove,
3496 .driver = {
3497 .name = "omapdss_dispc",
3498 .owner = THIS_MODULE,
3499 },
3500};
3501
3502int dispc_init_platform_driver(void)
3503{
3504 return platform_driver_register(&omap_dispchw_driver);
3505}
3506
3507void dispc_uninit_platform_driver(void)
3508{
3509 return platform_driver_unregister(&omap_dispchw_driver);
3510}
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 22dd7a474f7..a85a6f38b40 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -25,14 +25,11 @@
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/jiffies.h> 27#include <linux/jiffies.h>
28#include <linux/list.h>
29#include <linux/platform_device.h> 28#include <linux/platform_device.h>
30 29
31#include <plat/display.h> 30#include <plat/display.h>
32#include "dss.h" 31#include "dss.h"
33 32
34static LIST_HEAD(display_list);
35
36static ssize_t display_enabled_show(struct device *dev, 33static ssize_t display_enabled_show(struct device *dev,
37 struct device_attribute *attr, char *buf) 34 struct device_attribute *attr, char *buf)
38{ 35{
@@ -345,6 +342,7 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
345 return 16; 342 return 16;
346 case OMAP_DISPLAY_TYPE_VENC: 343 case OMAP_DISPLAY_TYPE_VENC:
347 case OMAP_DISPLAY_TYPE_SDI: 344 case OMAP_DISPLAY_TYPE_SDI:
345 case OMAP_DISPLAY_TYPE_HDMI:
348 return 24; 346 return 24;
349 default: 347 default:
350 BUG(); 348 BUG();
@@ -371,6 +369,7 @@ bool dss_use_replication(struct omap_dss_device *dssdev,
371 case OMAP_DISPLAY_TYPE_DPI: 369 case OMAP_DISPLAY_TYPE_DPI:
372 bpp = dssdev->phy.dpi.data_lines; 370 bpp = dssdev->phy.dpi.data_lines;
373 break; 371 break;
372 case OMAP_DISPLAY_TYPE_HDMI:
374 case OMAP_DISPLAY_TYPE_VENC: 373 case OMAP_DISPLAY_TYPE_VENC:
375 case OMAP_DISPLAY_TYPE_SDI: 374 case OMAP_DISPLAY_TYPE_SDI:
376 bpp = 24; 375 bpp = 24;
@@ -396,29 +395,6 @@ void dss_init_device(struct platform_device *pdev,
396 switch (dssdev->type) { 395 switch (dssdev->type) {
397#ifdef CONFIG_OMAP2_DSS_DPI 396#ifdef CONFIG_OMAP2_DSS_DPI
398 case OMAP_DISPLAY_TYPE_DPI: 397 case OMAP_DISPLAY_TYPE_DPI:
399#endif
400#ifdef CONFIG_OMAP2_DSS_RFBI
401 case OMAP_DISPLAY_TYPE_DBI:
402#endif
403#ifdef CONFIG_OMAP2_DSS_SDI
404 case OMAP_DISPLAY_TYPE_SDI:
405#endif
406#ifdef CONFIG_OMAP2_DSS_DSI
407 case OMAP_DISPLAY_TYPE_DSI:
408#endif
409#ifdef CONFIG_OMAP2_DSS_VENC
410 case OMAP_DISPLAY_TYPE_VENC:
411#endif
412 break;
413 default:
414 DSSERR("Support for display '%s' not compiled in.\n",
415 dssdev->name);
416 return;
417 }
418
419 switch (dssdev->type) {
420#ifdef CONFIG_OMAP2_DSS_DPI
421 case OMAP_DISPLAY_TYPE_DPI:
422 r = dpi_init_display(dssdev); 398 r = dpi_init_display(dssdev);
423 break; 399 break;
424#endif 400#endif
@@ -442,8 +418,13 @@ void dss_init_device(struct platform_device *pdev,
442 r = dsi_init_display(dssdev); 418 r = dsi_init_display(dssdev);
443 break; 419 break;
444#endif 420#endif
421 case OMAP_DISPLAY_TYPE_HDMI:
422 r = hdmi_init_display(dssdev);
423 break;
445 default: 424 default:
446 BUG(); 425 DSSERR("Support for display '%s' not compiled in.\n",
426 dssdev->name);
427 return;
447 } 428 }
448 429
449 if (r) { 430 if (r) {
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 75fb0a51543..2d3ca4ca4a0 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -57,13 +57,13 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
57 if (r) 57 if (r)
58 return r; 58 return r;
59 59
60 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); 60 dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC);
61 61
62 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); 62 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
63 if (r) 63 if (r)
64 return r; 64 return r;
65 65
66 *fck = dsi_cinfo.dsi1_pll_fclk; 66 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
67 *lck_div = dispc_cinfo.lck_div; 67 *lck_div = dispc_cinfo.lck_div;
68 *pck_div = dispc_cinfo.pck_div; 68 *pck_div = dispc_cinfo.pck_div;
69 69
@@ -107,7 +107,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
107 bool is_tft; 107 bool is_tft;
108 int r = 0; 108 int r = 0;
109 109
110 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 110 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
111 111
112 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, 112 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
113 dssdev->panel.acbi, dssdev->panel.acb); 113 dssdev->panel.acbi, dssdev->panel.acb);
@@ -137,7 +137,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
137 dispc_set_lcd_timings(dssdev->manager->id, t); 137 dispc_set_lcd_timings(dssdev->manager->id, t);
138 138
139err0: 139err0:
140 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 140 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
141 return r; 141 return r;
142} 142}
143 143
@@ -173,14 +173,14 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
173 goto err1; 173 goto err1;
174 } 174 }
175 175
176 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 176 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
177 177
178 r = dpi_basic_init(dssdev); 178 r = dpi_basic_init(dssdev);
179 if (r) 179 if (r)
180 goto err2; 180 goto err2;
181 181
182#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 182#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
183 dss_clk_enable(DSS_CLK_FCK2); 183 dss_clk_enable(DSS_CLK_SYSCK);
184 r = dsi_pll_init(dssdev, 0, 1); 184 r = dsi_pll_init(dssdev, 0, 1);
185 if (r) 185 if (r)
186 goto err3; 186 goto err3;
@@ -199,10 +199,10 @@ err4:
199#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 199#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
200 dsi_pll_uninit(); 200 dsi_pll_uninit();
201err3: 201err3:
202 dss_clk_disable(DSS_CLK_FCK2); 202 dss_clk_disable(DSS_CLK_SYSCK);
203#endif 203#endif
204err2: 204err2:
205 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 205 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
206 if (cpu_is_omap34xx()) 206 if (cpu_is_omap34xx())
207 regulator_disable(dpi.vdds_dsi_reg); 207 regulator_disable(dpi.vdds_dsi_reg);
208err1: 208err1:
@@ -217,12 +217,12 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
217 dssdev->manager->disable(dssdev->manager); 217 dssdev->manager->disable(dssdev->manager);
218 218
219#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 219#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
220 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 220 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
221 dsi_pll_uninit(); 221 dsi_pll_uninit();
222 dss_clk_disable(DSS_CLK_FCK2); 222 dss_clk_disable(DSS_CLK_SYSCK);
223#endif 223#endif
224 224
225 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 225 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
226 226
227 if (cpu_is_omap34xx()) 227 if (cpu_is_omap34xx())
228 regulator_disable(dpi.vdds_dsi_reg); 228 regulator_disable(dpi.vdds_dsi_reg);
@@ -271,7 +271,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
271 if (r) 271 if (r)
272 return r; 272 return r;
273 273
274 fck = dsi_cinfo.dsi1_pll_fclk; 274 fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
275 lck_div = dispc_cinfo.lck_div; 275 lck_div = dispc_cinfo.lck_div;
276 pck_div = dispc_cinfo.pck_div; 276 pck_div = dispc_cinfo.pck_div;
277 } 277 }
@@ -303,22 +303,27 @@ int dpi_init_display(struct omap_dss_device *dssdev)
303{ 303{
304 DSSDBG("init_display\n"); 304 DSSDBG("init_display\n");
305 305
306 return 0; 306 if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) {
307} 307 struct regulator *vdds_dsi;
308 308
309int dpi_init(struct platform_device *pdev) 309 vdds_dsi = dss_get_vdds_dsi();
310{ 310
311 if (cpu_is_omap34xx()) { 311 if (IS_ERR(vdds_dsi)) {
312 dpi.vdds_dsi_reg = dss_get_vdds_dsi();
313 if (IS_ERR(dpi.vdds_dsi_reg)) {
314 DSSERR("can't get VDDS_DSI regulator\n"); 312 DSSERR("can't get VDDS_DSI regulator\n");
315 return PTR_ERR(dpi.vdds_dsi_reg); 313 return PTR_ERR(vdds_dsi);
316 } 314 }
315
316 dpi.vdds_dsi_reg = vdds_dsi;
317 } 317 }
318 318
319 return 0; 319 return 0;
320} 320}
321 321
322int dpi_init(void)
323{
324 return 0;
325}
326
322void dpi_exit(void) 327void dpi_exit(void)
323{ 328{
324} 329}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index ddf3a056082..0a7f1a47f8e 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -38,12 +38,11 @@
38#include <plat/clock.h> 38#include <plat/clock.h>
39 39
40#include "dss.h" 40#include "dss.h"
41#include "dss_features.h"
41 42
42/*#define VERBOSE_IRQ*/ 43/*#define VERBOSE_IRQ*/
43#define DSI_CATCH_MISSING_TE 44#define DSI_CATCH_MISSING_TE
44 45
45#define DSI_BASE 0x4804FC00
46
47struct dsi_reg { u16 idx; }; 46struct dsi_reg { u16 idx; };
48 47
49#define DSI_REG(idx) ((const struct dsi_reg) { idx }) 48#define DSI_REG(idx) ((const struct dsi_reg) { idx })
@@ -186,13 +185,15 @@ struct dsi_reg { u16 idx; };
186#define DSI_DT_RX_SHORT_READ_1 0x21 185#define DSI_DT_RX_SHORT_READ_1 0x21
187#define DSI_DT_RX_SHORT_READ_2 0x22 186#define DSI_DT_RX_SHORT_READ_2 0x22
188 187
189#define FINT_MAX 2100000 188typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
190#define FINT_MIN 750000 189
191#define REGN_MAX (1 << 7) 190#define DSI_MAX_NR_ISRS 2
192#define REGM_MAX ((1 << 11) - 1) 191
193#define REGM3_MAX (1 << 4) 192struct dsi_isr_data {
194#define REGM4_MAX (1 << 4) 193 omap_dsi_isr_t isr;
195#define LP_DIV_MAX ((1 << 13) - 1) 194 void *arg;
195 u32 mask;
196};
196 197
197enum fifo_size { 198enum fifo_size {
198 DSI_FIFO_SIZE_0 = 0, 199 DSI_FIFO_SIZE_0 = 0,
@@ -220,9 +221,17 @@ struct dsi_irq_stats {
220 unsigned cio_irqs[32]; 221 unsigned cio_irqs[32];
221}; 222};
222 223
224struct dsi_isr_tables {
225 struct dsi_isr_data isr_table[DSI_MAX_NR_ISRS];
226 struct dsi_isr_data isr_table_vc[4][DSI_MAX_NR_ISRS];
227 struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
228};
229
223static struct 230static struct
224{ 231{
232 struct platform_device *pdev;
225 void __iomem *base; 233 void __iomem *base;
234 int irq;
226 235
227 struct dsi_clock_info current_cinfo; 236 struct dsi_clock_info current_cinfo;
228 237
@@ -232,6 +241,7 @@ static struct
232 enum dsi_vc_mode mode; 241 enum dsi_vc_mode mode;
233 struct omap_dss_device *dssdev; 242 struct omap_dss_device *dssdev;
234 enum fifo_size fifo_size; 243 enum fifo_size fifo_size;
244 int vc_id;
235 } vc[4]; 245 } vc[4];
236 246
237 struct mutex lock; 247 struct mutex lock;
@@ -239,8 +249,10 @@ static struct
239 249
240 unsigned pll_locked; 250 unsigned pll_locked;
241 251
242 struct completion bta_completion; 252 spinlock_t irq_lock;
243 void (*bta_callback)(void); 253 struct dsi_isr_tables isr_tables;
254 /* space for a copy used by the interrupt handler */
255 struct dsi_isr_tables isr_tables_copy;
244 256
245 int update_channel; 257 int update_channel;
246 struct dsi_update_region update_region; 258 struct dsi_update_region update_region;
@@ -275,6 +287,11 @@ static struct
275 spinlock_t irq_stats_lock; 287 spinlock_t irq_stats_lock;
276 struct dsi_irq_stats irq_stats; 288 struct dsi_irq_stats irq_stats;
277#endif 289#endif
290 /* DSI PLL Parameter Ranges */
291 unsigned long regm_max, regn_max;
292 unsigned long regm_dispc_max, regm_dsi_max;
293 unsigned long fint_min, fint_max;
294 unsigned long lpdiv_max;
278} dsi; 295} dsi;
279 296
280#ifdef DEBUG 297#ifdef DEBUG
@@ -318,6 +335,11 @@ static bool dsi_bus_is_locked(void)
318 return dsi.bus_lock.count == 0; 335 return dsi.bus_lock.count == 0;
319} 336}
320 337
338static void dsi_completion_handler(void *data, u32 mask)
339{
340 complete((struct completion *)data);
341}
342
321static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, 343static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
322 int value) 344 int value)
323{ 345{
@@ -387,6 +409,9 @@ static void dsi_perf_show(const char *name)
387 409
388static void print_irq_status(u32 status) 410static void print_irq_status(u32 status)
389{ 411{
412 if (status == 0)
413 return;
414
390#ifndef VERBOSE_IRQ 415#ifndef VERBOSE_IRQ
391 if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0) 416 if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0)
392 return; 417 return;
@@ -422,6 +447,9 @@ static void print_irq_status(u32 status)
422 447
423static void print_irq_status_vc(int channel, u32 status) 448static void print_irq_status_vc(int channel, u32 status)
424{ 449{
450 if (status == 0)
451 return;
452
425#ifndef VERBOSE_IRQ 453#ifndef VERBOSE_IRQ
426 if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0) 454 if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0)
427 return; 455 return;
@@ -448,6 +476,9 @@ static void print_irq_status_vc(int channel, u32 status)
448 476
449static void print_irq_status_cio(u32 status) 477static void print_irq_status_cio(u32 status)
450{ 478{
479 if (status == 0)
480 return;
481
451 printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status); 482 printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status);
452 483
453#define PIS(x) \ 484#define PIS(x) \
@@ -478,22 +509,33 @@ static void print_irq_status_cio(u32 status)
478 printk("\n"); 509 printk("\n");
479} 510}
480 511
481static int debug_irq; 512#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
482 513static void dsi_collect_irq_stats(u32 irqstatus, u32 *vcstatus, u32 ciostatus)
483/* called from dss */
484void dsi_irq_handler(void)
485{ 514{
486 u32 irqstatus, vcstatus, ciostatus;
487 int i; 515 int i;
488 516
489 irqstatus = dsi_read_reg(DSI_IRQSTATUS);
490
491#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
492 spin_lock(&dsi.irq_stats_lock); 517 spin_lock(&dsi.irq_stats_lock);
518
493 dsi.irq_stats.irq_count++; 519 dsi.irq_stats.irq_count++;
494 dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs); 520 dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs);
521
522 for (i = 0; i < 4; ++i)
523 dss_collect_irq_stats(vcstatus[i], dsi.irq_stats.vc_irqs[i]);
524
525 dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs);
526
527 spin_unlock(&dsi.irq_stats_lock);
528}
529#else
530#define dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus)
495#endif 531#endif
496 532
533static int debug_irq;
534
535static void dsi_handle_irq_errors(u32 irqstatus, u32 *vcstatus, u32 ciostatus)
536{
537 int i;
538
497 if (irqstatus & DSI_IRQ_ERROR_MASK) { 539 if (irqstatus & DSI_IRQ_ERROR_MASK) {
498 DSSERR("DSI error, irqstatus %x\n", irqstatus); 540 DSSERR("DSI error, irqstatus %x\n", irqstatus);
499 print_irq_status(irqstatus); 541 print_irq_status(irqstatus);
@@ -504,37 +546,88 @@ void dsi_irq_handler(void)
504 print_irq_status(irqstatus); 546 print_irq_status(irqstatus);
505 } 547 }
506 548
507#ifdef DSI_CATCH_MISSING_TE 549 for (i = 0; i < 4; ++i) {
508 if (irqstatus & DSI_IRQ_TE_TRIGGER) 550 if (vcstatus[i] & DSI_VC_IRQ_ERROR_MASK) {
509 del_timer(&dsi.te_timer); 551 DSSERR("DSI VC(%d) error, vc irqstatus %x\n",
510#endif 552 i, vcstatus[i]);
553 print_irq_status_vc(i, vcstatus[i]);
554 } else if (debug_irq) {
555 print_irq_status_vc(i, vcstatus[i]);
556 }
557 }
558
559 if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) {
560 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus);
561 print_irq_status_cio(ciostatus);
562 } else if (debug_irq) {
563 print_irq_status_cio(ciostatus);
564 }
565}
566
567static void dsi_call_isrs(struct dsi_isr_data *isr_array,
568 unsigned isr_array_size, u32 irqstatus)
569{
570 struct dsi_isr_data *isr_data;
571 int i;
572
573 for (i = 0; i < isr_array_size; i++) {
574 isr_data = &isr_array[i];
575 if (isr_data->isr && isr_data->mask & irqstatus)
576 isr_data->isr(isr_data->arg, irqstatus);
577 }
578}
579
580static void dsi_handle_isrs(struct dsi_isr_tables *isr_tables,
581 u32 irqstatus, u32 *vcstatus, u32 ciostatus)
582{
583 int i;
584
585 dsi_call_isrs(isr_tables->isr_table,
586 ARRAY_SIZE(isr_tables->isr_table),
587 irqstatus);
511 588
512 for (i = 0; i < 4; ++i) { 589 for (i = 0; i < 4; ++i) {
513 if ((irqstatus & (1<<i)) == 0) 590 if (vcstatus[i] == 0)
514 continue; 591 continue;
592 dsi_call_isrs(isr_tables->isr_table_vc[i],
593 ARRAY_SIZE(isr_tables->isr_table_vc[i]),
594 vcstatus[i]);
595 }
515 596
516 vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i)); 597 if (ciostatus != 0)
598 dsi_call_isrs(isr_tables->isr_table_cio,
599 ARRAY_SIZE(isr_tables->isr_table_cio),
600 ciostatus);
601}
517 602
518#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 603static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
519 dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]); 604{
520#endif 605 u32 irqstatus, vcstatus[4], ciostatus;
606 int i;
521 607
522 if (vcstatus & DSI_VC_IRQ_BTA) { 608 spin_lock(&dsi.irq_lock);
523 complete(&dsi.bta_completion);
524 609
525 if (dsi.bta_callback) 610 irqstatus = dsi_read_reg(DSI_IRQSTATUS);
526 dsi.bta_callback();
527 }
528 611
529 if (vcstatus & DSI_VC_IRQ_ERROR_MASK) { 612 /* IRQ is not for us */
530 DSSERR("DSI VC(%d) error, vc irqstatus %x\n", 613 if (!irqstatus) {
531 i, vcstatus); 614 spin_unlock(&dsi.irq_lock);
532 print_irq_status_vc(i, vcstatus); 615 return IRQ_NONE;
533 } else if (debug_irq) { 616 }
534 print_irq_status_vc(i, vcstatus); 617
618 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
619 /* flush posted write */
620 dsi_read_reg(DSI_IRQSTATUS);
621
622 for (i = 0; i < 4; ++i) {
623 if ((irqstatus & (1 << i)) == 0) {
624 vcstatus[i] = 0;
625 continue;
535 } 626 }
536 627
537 dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus); 628 vcstatus[i] = dsi_read_reg(DSI_VC_IRQSTATUS(i));
629
630 dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus[i]);
538 /* flush posted write */ 631 /* flush posted write */
539 dsi_read_reg(DSI_VC_IRQSTATUS(i)); 632 dsi_read_reg(DSI_VC_IRQSTATUS(i));
540 } 633 }
@@ -542,117 +635,307 @@ void dsi_irq_handler(void)
542 if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { 635 if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) {
543 ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 636 ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
544 637
545#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
546 dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs);
547#endif
548
549 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); 638 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus);
550 /* flush posted write */ 639 /* flush posted write */
551 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 640 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
641 } else {
642 ciostatus = 0;
643 }
552 644
553 if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) { 645#ifdef DSI_CATCH_MISSING_TE
554 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus); 646 if (irqstatus & DSI_IRQ_TE_TRIGGER)
555 print_irq_status_cio(ciostatus); 647 del_timer(&dsi.te_timer);
556 } else if (debug_irq) { 648#endif
557 print_irq_status_cio(ciostatus); 649
558 } 650 /* make a copy and unlock, so that isrs can unregister
651 * themselves */
652 memcpy(&dsi.isr_tables_copy, &dsi.isr_tables, sizeof(dsi.isr_tables));
653
654 spin_unlock(&dsi.irq_lock);
655
656 dsi_handle_isrs(&dsi.isr_tables_copy, irqstatus, vcstatus, ciostatus);
657
658 dsi_handle_irq_errors(irqstatus, vcstatus, ciostatus);
659
660 dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus);
661
662 return IRQ_HANDLED;
663}
664
665/* dsi.irq_lock has to be locked by the caller */
666static void _omap_dsi_configure_irqs(struct dsi_isr_data *isr_array,
667 unsigned isr_array_size, u32 default_mask,
668 const struct dsi_reg enable_reg,
669 const struct dsi_reg status_reg)
670{
671 struct dsi_isr_data *isr_data;
672 u32 mask;
673 u32 old_mask;
674 int i;
675
676 mask = default_mask;
677
678 for (i = 0; i < isr_array_size; i++) {
679 isr_data = &isr_array[i];
680
681 if (isr_data->isr == NULL)
682 continue;
683
684 mask |= isr_data->mask;
559 } 685 }
560 686
561 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); 687 old_mask = dsi_read_reg(enable_reg);
562 /* flush posted write */ 688 /* clear the irqstatus for newly enabled irqs */
563 dsi_read_reg(DSI_IRQSTATUS); 689 dsi_write_reg(status_reg, (mask ^ old_mask) & mask);
690 dsi_write_reg(enable_reg, mask);
564 691
565#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 692 /* flush posted writes */
566 spin_unlock(&dsi.irq_stats_lock); 693 dsi_read_reg(enable_reg);
694 dsi_read_reg(status_reg);
695}
696
697/* dsi.irq_lock has to be locked by the caller */
698static void _omap_dsi_set_irqs(void)
699{
700 u32 mask = DSI_IRQ_ERROR_MASK;
701#ifdef DSI_CATCH_MISSING_TE
702 mask |= DSI_IRQ_TE_TRIGGER;
567#endif 703#endif
704 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table,
705 ARRAY_SIZE(dsi.isr_tables.isr_table), mask,
706 DSI_IRQENABLE, DSI_IRQSTATUS);
707}
708
709/* dsi.irq_lock has to be locked by the caller */
710static void _omap_dsi_set_irqs_vc(int vc)
711{
712 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_vc[vc],
713 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[vc]),
714 DSI_VC_IRQ_ERROR_MASK,
715 DSI_VC_IRQENABLE(vc), DSI_VC_IRQSTATUS(vc));
568} 716}
569 717
718/* dsi.irq_lock has to be locked by the caller */
719static void _omap_dsi_set_irqs_cio(void)
720{
721 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_cio,
722 ARRAY_SIZE(dsi.isr_tables.isr_table_cio),
723 DSI_CIO_IRQ_ERROR_MASK,
724 DSI_COMPLEXIO_IRQ_ENABLE, DSI_COMPLEXIO_IRQ_STATUS);
725}
570 726
571static void _dsi_initialize_irq(void) 727static void _dsi_initialize_irq(void)
572{ 728{
573 u32 l; 729 unsigned long flags;
730 int vc;
731
732 spin_lock_irqsave(&dsi.irq_lock, flags);
733
734 memset(&dsi.isr_tables, 0, sizeof(dsi.isr_tables));
735
736 _omap_dsi_set_irqs();
737 for (vc = 0; vc < 4; ++vc)
738 _omap_dsi_set_irqs_vc(vc);
739 _omap_dsi_set_irqs_cio();
740
741 spin_unlock_irqrestore(&dsi.irq_lock, flags);
742}
743
744static int _dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
745 struct dsi_isr_data *isr_array, unsigned isr_array_size)
746{
747 struct dsi_isr_data *isr_data;
748 int free_idx;
574 int i; 749 int i;
575 750
576 /* disable all interrupts */ 751 BUG_ON(isr == NULL);
577 dsi_write_reg(DSI_IRQENABLE, 0);
578 for (i = 0; i < 4; ++i)
579 dsi_write_reg(DSI_VC_IRQENABLE(i), 0);
580 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, 0);
581 752
582 /* clear interrupt status */ 753 /* check for duplicate entry and find a free slot */
583 l = dsi_read_reg(DSI_IRQSTATUS); 754 free_idx = -1;
584 dsi_write_reg(DSI_IRQSTATUS, l & ~DSI_IRQ_CHANNEL_MASK); 755 for (i = 0; i < isr_array_size; i++) {
756 isr_data = &isr_array[i];
585 757
586 for (i = 0; i < 4; ++i) { 758 if (isr_data->isr == isr && isr_data->arg == arg &&
587 l = dsi_read_reg(DSI_VC_IRQSTATUS(i)); 759 isr_data->mask == mask) {
588 dsi_write_reg(DSI_VC_IRQSTATUS(i), l); 760 return -EINVAL;
761 }
762
763 if (isr_data->isr == NULL && free_idx == -1)
764 free_idx = i;
589 } 765 }
590 766
591 l = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 767 if (free_idx == -1)
592 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, l); 768 return -EBUSY;
593 769
594 /* enable error irqs */ 770 isr_data = &isr_array[free_idx];
595 l = DSI_IRQ_ERROR_MASK; 771 isr_data->isr = isr;
596#ifdef DSI_CATCH_MISSING_TE 772 isr_data->arg = arg;
597 l |= DSI_IRQ_TE_TRIGGER; 773 isr_data->mask = mask;
598#endif
599 dsi_write_reg(DSI_IRQENABLE, l);
600 774
601 l = DSI_VC_IRQ_ERROR_MASK; 775 return 0;
602 for (i = 0; i < 4; ++i) 776}
603 dsi_write_reg(DSI_VC_IRQENABLE(i), l); 777
778static int _dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
779 struct dsi_isr_data *isr_array, unsigned isr_array_size)
780{
781 struct dsi_isr_data *isr_data;
782 int i;
783
784 for (i = 0; i < isr_array_size; i++) {
785 isr_data = &isr_array[i];
786 if (isr_data->isr != isr || isr_data->arg != arg ||
787 isr_data->mask != mask)
788 continue;
789
790 isr_data->isr = NULL;
791 isr_data->arg = NULL;
792 isr_data->mask = 0;
793
794 return 0;
795 }
604 796
605 l = DSI_CIO_IRQ_ERROR_MASK; 797 return -EINVAL;
606 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, l);
607} 798}
608 799
609static u32 dsi_get_errors(void) 800static int dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask)
610{ 801{
611 unsigned long flags; 802 unsigned long flags;
612 u32 e; 803 int r;
613 spin_lock_irqsave(&dsi.errors_lock, flags); 804
614 e = dsi.errors; 805 spin_lock_irqsave(&dsi.irq_lock, flags);
615 dsi.errors = 0; 806
616 spin_unlock_irqrestore(&dsi.errors_lock, flags); 807 r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table,
617 return e; 808 ARRAY_SIZE(dsi.isr_tables.isr_table));
809
810 if (r == 0)
811 _omap_dsi_set_irqs();
812
813 spin_unlock_irqrestore(&dsi.irq_lock, flags);
814
815 return r;
618} 816}
619 817
620static void dsi_vc_enable_bta_irq(int channel) 818static int dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask)
621{ 819{
622 u32 l; 820 unsigned long flags;
821 int r;
822
823 spin_lock_irqsave(&dsi.irq_lock, flags);
824
825 r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table,
826 ARRAY_SIZE(dsi.isr_tables.isr_table));
827
828 if (r == 0)
829 _omap_dsi_set_irqs();
623 830
624 dsi_write_reg(DSI_VC_IRQSTATUS(channel), DSI_VC_IRQ_BTA); 831 spin_unlock_irqrestore(&dsi.irq_lock, flags);
625 832
626 l = dsi_read_reg(DSI_VC_IRQENABLE(channel)); 833 return r;
627 l |= DSI_VC_IRQ_BTA;
628 dsi_write_reg(DSI_VC_IRQENABLE(channel), l);
629} 834}
630 835
631static void dsi_vc_disable_bta_irq(int channel) 836static int dsi_register_isr_vc(int channel, omap_dsi_isr_t isr, void *arg,
837 u32 mask)
632{ 838{
633 u32 l; 839 unsigned long flags;
840 int r;
841
842 spin_lock_irqsave(&dsi.irq_lock, flags);
843
844 r = _dsi_register_isr(isr, arg, mask,
845 dsi.isr_tables.isr_table_vc[channel],
846 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel]));
847
848 if (r == 0)
849 _omap_dsi_set_irqs_vc(channel);
850
851 spin_unlock_irqrestore(&dsi.irq_lock, flags);
852
853 return r;
854}
855
856static int dsi_unregister_isr_vc(int channel, omap_dsi_isr_t isr, void *arg,
857 u32 mask)
858{
859 unsigned long flags;
860 int r;
861
862 spin_lock_irqsave(&dsi.irq_lock, flags);
863
864 r = _dsi_unregister_isr(isr, arg, mask,
865 dsi.isr_tables.isr_table_vc[channel],
866 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel]));
867
868 if (r == 0)
869 _omap_dsi_set_irqs_vc(channel);
870
871 spin_unlock_irqrestore(&dsi.irq_lock, flags);
872
873 return r;
874}
875
876static int dsi_register_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask)
877{
878 unsigned long flags;
879 int r;
880
881 spin_lock_irqsave(&dsi.irq_lock, flags);
882
883 r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio,
884 ARRAY_SIZE(dsi.isr_tables.isr_table_cio));
885
886 if (r == 0)
887 _omap_dsi_set_irqs_cio();
888
889 spin_unlock_irqrestore(&dsi.irq_lock, flags);
890
891 return r;
892}
893
894static int dsi_unregister_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask)
895{
896 unsigned long flags;
897 int r;
898
899 spin_lock_irqsave(&dsi.irq_lock, flags);
900
901 r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio,
902 ARRAY_SIZE(dsi.isr_tables.isr_table_cio));
903
904 if (r == 0)
905 _omap_dsi_set_irqs_cio();
906
907 spin_unlock_irqrestore(&dsi.irq_lock, flags);
634 908
635 l = dsi_read_reg(DSI_VC_IRQENABLE(channel)); 909 return r;
636 l &= ~DSI_VC_IRQ_BTA;
637 dsi_write_reg(DSI_VC_IRQENABLE(channel), l);
638} 910}
639 911
640/* DSI func clock. this could also be DSI2_PLL_FCLK */ 912static u32 dsi_get_errors(void)
913{
914 unsigned long flags;
915 u32 e;
916 spin_lock_irqsave(&dsi.errors_lock, flags);
917 e = dsi.errors;
918 dsi.errors = 0;
919 spin_unlock_irqrestore(&dsi.errors_lock, flags);
920 return e;
921}
922
923/* DSI func clock. this could also be dsi_pll_hsdiv_dsi_clk */
641static inline void enable_clocks(bool enable) 924static inline void enable_clocks(bool enable)
642{ 925{
643 if (enable) 926 if (enable)
644 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 927 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
645 else 928 else
646 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 929 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
647} 930}
648 931
649/* source clock for DSI PLL. this could also be PCLKFREE */ 932/* source clock for DSI PLL. this could also be PCLKFREE */
650static inline void dsi_enable_pll_clock(bool enable) 933static inline void dsi_enable_pll_clock(bool enable)
651{ 934{
652 if (enable) 935 if (enable)
653 dss_clk_enable(DSS_CLK_FCK2); 936 dss_clk_enable(DSS_CLK_SYSCK);
654 else 937 else
655 dss_clk_disable(DSS_CLK_FCK2); 938 dss_clk_disable(DSS_CLK_SYSCK);
656 939
657 if (enable && dsi.pll_locked) { 940 if (enable && dsi.pll_locked) {
658 if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) 941 if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1)
@@ -707,14 +990,14 @@ static inline int dsi_if_enable(bool enable)
707 return 0; 990 return 0;
708} 991}
709 992
710unsigned long dsi_get_dsi1_pll_rate(void) 993unsigned long dsi_get_pll_hsdiv_dispc_rate(void)
711{ 994{
712 return dsi.current_cinfo.dsi1_pll_fclk; 995 return dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk;
713} 996}
714 997
715static unsigned long dsi_get_dsi2_pll_rate(void) 998static unsigned long dsi_get_pll_hsdiv_dsi_rate(void)
716{ 999{
717 return dsi.current_cinfo.dsi2_pll_fclk; 1000 return dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk;
718} 1001}
719 1002
720static unsigned long dsi_get_txbyteclkhs(void) 1003static unsigned long dsi_get_txbyteclkhs(void)
@@ -726,12 +1009,12 @@ static unsigned long dsi_fclk_rate(void)
726{ 1009{
727 unsigned long r; 1010 unsigned long r;
728 1011
729 if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) { 1012 if (dss_get_dsi_clk_source() == DSS_CLK_SRC_FCK) {
730 /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ 1013 /* DSI FCLK source is DSS_CLK_FCK */
731 r = dss_clk_get_rate(DSS_CLK_FCK1); 1014 r = dss_clk_get_rate(DSS_CLK_FCK);
732 } else { 1015 } else {
733 /* DSI FCLK source is DSI2_PLL_FCLK */ 1016 /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */
734 r = dsi_get_dsi2_pll_rate(); 1017 r = dsi_get_pll_hsdiv_dsi_rate();
735 } 1018 }
736 1019
737 return r; 1020 return r;
@@ -745,7 +1028,7 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
745 1028
746 lp_clk_div = dssdev->phy.dsi.div.lp_clk_div; 1029 lp_clk_div = dssdev->phy.dsi.div.lp_clk_div;
747 1030
748 if (lp_clk_div == 0 || lp_clk_div > LP_DIV_MAX) 1031 if (lp_clk_div == 0 || lp_clk_div > dsi.lpdiv_max)
749 return -EINVAL; 1032 return -EINVAL;
750 1033
751 dsi_fclk = dsi_fclk_rate(); 1034 dsi_fclk = dsi_fclk_rate();
@@ -795,22 +1078,22 @@ static int dsi_pll_power(enum dsi_pll_power_state state)
795static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, 1078static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
796 struct dsi_clock_info *cinfo) 1079 struct dsi_clock_info *cinfo)
797{ 1080{
798 if (cinfo->regn == 0 || cinfo->regn > REGN_MAX) 1081 if (cinfo->regn == 0 || cinfo->regn > dsi.regn_max)
799 return -EINVAL; 1082 return -EINVAL;
800 1083
801 if (cinfo->regm == 0 || cinfo->regm > REGM_MAX) 1084 if (cinfo->regm == 0 || cinfo->regm > dsi.regm_max)
802 return -EINVAL; 1085 return -EINVAL;
803 1086
804 if (cinfo->regm3 > REGM3_MAX) 1087 if (cinfo->regm_dispc > dsi.regm_dispc_max)
805 return -EINVAL; 1088 return -EINVAL;
806 1089
807 if (cinfo->regm4 > REGM4_MAX) 1090 if (cinfo->regm_dsi > dsi.regm_dsi_max)
808 return -EINVAL; 1091 return -EINVAL;
809 1092
810 if (cinfo->use_dss2_fck) { 1093 if (cinfo->use_sys_clk) {
811 cinfo->clkin = dss_clk_get_rate(DSS_CLK_FCK2); 1094 cinfo->clkin = dss_clk_get_rate(DSS_CLK_SYSCK);
812 /* XXX it is unclear if highfreq should be used 1095 /* XXX it is unclear if highfreq should be used
813 * with DSS2_FCK source also */ 1096 * with DSS_SYS_CLK source also */
814 cinfo->highfreq = 0; 1097 cinfo->highfreq = 0;
815 } else { 1098 } else {
816 cinfo->clkin = dispc_pclk_rate(dssdev->manager->id); 1099 cinfo->clkin = dispc_pclk_rate(dssdev->manager->id);
@@ -823,7 +1106,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
823 1106
824 cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1)); 1107 cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1));
825 1108
826 if (cinfo->fint > FINT_MAX || cinfo->fint < FINT_MIN) 1109 if (cinfo->fint > dsi.fint_max || cinfo->fint < dsi.fint_min)
827 return -EINVAL; 1110 return -EINVAL;
828 1111
829 cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint; 1112 cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint;
@@ -831,15 +1114,17 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
831 if (cinfo->clkin4ddr > 1800 * 1000 * 1000) 1114 if (cinfo->clkin4ddr > 1800 * 1000 * 1000)
832 return -EINVAL; 1115 return -EINVAL;
833 1116
834 if (cinfo->regm3 > 0) 1117 if (cinfo->regm_dispc > 0)
835 cinfo->dsi1_pll_fclk = cinfo->clkin4ddr / cinfo->regm3; 1118 cinfo->dsi_pll_hsdiv_dispc_clk =
1119 cinfo->clkin4ddr / cinfo->regm_dispc;
836 else 1120 else
837 cinfo->dsi1_pll_fclk = 0; 1121 cinfo->dsi_pll_hsdiv_dispc_clk = 0;
838 1122
839 if (cinfo->regm4 > 0) 1123 if (cinfo->regm_dsi > 0)
840 cinfo->dsi2_pll_fclk = cinfo->clkin4ddr / cinfo->regm4; 1124 cinfo->dsi_pll_hsdiv_dsi_clk =
1125 cinfo->clkin4ddr / cinfo->regm_dsi;
841 else 1126 else
842 cinfo->dsi2_pll_fclk = 0; 1127 cinfo->dsi_pll_hsdiv_dsi_clk = 0;
843 1128
844 return 0; 1129 return 0;
845} 1130}
@@ -852,23 +1137,25 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
852 struct dispc_clock_info best_dispc; 1137 struct dispc_clock_info best_dispc;
853 int min_fck_per_pck; 1138 int min_fck_per_pck;
854 int match = 0; 1139 int match = 0;
855 unsigned long dss_clk_fck2; 1140 unsigned long dss_sys_clk, max_dss_fck;
1141
1142 dss_sys_clk = dss_clk_get_rate(DSS_CLK_SYSCK);
856 1143
857 dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_FCK2); 1144 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
858 1145
859 if (req_pck == dsi.cache_req_pck && 1146 if (req_pck == dsi.cache_req_pck &&
860 dsi.cache_cinfo.clkin == dss_clk_fck2) { 1147 dsi.cache_cinfo.clkin == dss_sys_clk) {
861 DSSDBG("DSI clock info found from cache\n"); 1148 DSSDBG("DSI clock info found from cache\n");
862 *dsi_cinfo = dsi.cache_cinfo; 1149 *dsi_cinfo = dsi.cache_cinfo;
863 dispc_find_clk_divs(is_tft, req_pck, dsi_cinfo->dsi1_pll_fclk, 1150 dispc_find_clk_divs(is_tft, req_pck,
864 dispc_cinfo); 1151 dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo);
865 return 0; 1152 return 0;
866 } 1153 }
867 1154
868 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 1155 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
869 1156
870 if (min_fck_per_pck && 1157 if (min_fck_per_pck &&
871 req_pck * min_fck_per_pck > DISPC_MAX_FCK) { 1158 req_pck * min_fck_per_pck > max_dss_fck) {
872 DSSERR("Requested pixel clock not possible with the current " 1159 DSSERR("Requested pixel clock not possible with the current "
873 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " 1160 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
874 "the constraint off.\n"); 1161 "the constraint off.\n");
@@ -882,24 +1169,24 @@ retry:
882 memset(&best_dispc, 0, sizeof(best_dispc)); 1169 memset(&best_dispc, 0, sizeof(best_dispc));
883 1170
884 memset(&cur, 0, sizeof(cur)); 1171 memset(&cur, 0, sizeof(cur));
885 cur.clkin = dss_clk_fck2; 1172 cur.clkin = dss_sys_clk;
886 cur.use_dss2_fck = 1; 1173 cur.use_sys_clk = 1;
887 cur.highfreq = 0; 1174 cur.highfreq = 0;
888 1175
889 /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ 1176 /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */
890 /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ 1177 /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */
891 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ 1178 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */
892 for (cur.regn = 1; cur.regn < REGN_MAX; ++cur.regn) { 1179 for (cur.regn = 1; cur.regn < dsi.regn_max; ++cur.regn) {
893 if (cur.highfreq == 0) 1180 if (cur.highfreq == 0)
894 cur.fint = cur.clkin / cur.regn; 1181 cur.fint = cur.clkin / cur.regn;
895 else 1182 else
896 cur.fint = cur.clkin / (2 * cur.regn); 1183 cur.fint = cur.clkin / (2 * cur.regn);
897 1184
898 if (cur.fint > FINT_MAX || cur.fint < FINT_MIN) 1185 if (cur.fint > dsi.fint_max || cur.fint < dsi.fint_min)
899 continue; 1186 continue;
900 1187
901 /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ 1188 /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */
902 for (cur.regm = 1; cur.regm < REGM_MAX; ++cur.regm) { 1189 for (cur.regm = 1; cur.regm < dsi.regm_max; ++cur.regm) {
903 unsigned long a, b; 1190 unsigned long a, b;
904 1191
905 a = 2 * cur.regm * (cur.clkin/1000); 1192 a = 2 * cur.regm * (cur.clkin/1000);
@@ -909,30 +1196,32 @@ retry:
909 if (cur.clkin4ddr > 1800 * 1000 * 1000) 1196 if (cur.clkin4ddr > 1800 * 1000 * 1000)
910 break; 1197 break;
911 1198
912 /* DSI1_PLL_FCLK(MHz) = DSIPHY(MHz) / regm3 < 173MHz */ 1199 /* dsi_pll_hsdiv_dispc_clk(MHz) =
913 for (cur.regm3 = 1; cur.regm3 < REGM3_MAX; 1200 * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */
914 ++cur.regm3) { 1201 for (cur.regm_dispc = 1; cur.regm_dispc < dsi.regm_dispc_max;
1202 ++cur.regm_dispc) {
915 struct dispc_clock_info cur_dispc; 1203 struct dispc_clock_info cur_dispc;
916 cur.dsi1_pll_fclk = cur.clkin4ddr / cur.regm3; 1204 cur.dsi_pll_hsdiv_dispc_clk =
1205 cur.clkin4ddr / cur.regm_dispc;
917 1206
918 /* this will narrow down the search a bit, 1207 /* this will narrow down the search a bit,
919 * but still give pixclocks below what was 1208 * but still give pixclocks below what was
920 * requested */ 1209 * requested */
921 if (cur.dsi1_pll_fclk < req_pck) 1210 if (cur.dsi_pll_hsdiv_dispc_clk < req_pck)
922 break; 1211 break;
923 1212
924 if (cur.dsi1_pll_fclk > DISPC_MAX_FCK) 1213 if (cur.dsi_pll_hsdiv_dispc_clk > max_dss_fck)
925 continue; 1214 continue;
926 1215
927 if (min_fck_per_pck && 1216 if (min_fck_per_pck &&
928 cur.dsi1_pll_fclk < 1217 cur.dsi_pll_hsdiv_dispc_clk <
929 req_pck * min_fck_per_pck) 1218 req_pck * min_fck_per_pck)
930 continue; 1219 continue;
931 1220
932 match = 1; 1221 match = 1;
933 1222
934 dispc_find_clk_divs(is_tft, req_pck, 1223 dispc_find_clk_divs(is_tft, req_pck,
935 cur.dsi1_pll_fclk, 1224 cur.dsi_pll_hsdiv_dispc_clk,
936 &cur_dispc); 1225 &cur_dispc);
937 1226
938 if (abs(cur_dispc.pck - req_pck) < 1227 if (abs(cur_dispc.pck - req_pck) <
@@ -961,9 +1250,9 @@ found:
961 return -EINVAL; 1250 return -EINVAL;
962 } 1251 }
963 1252
964 /* DSI2_PLL_FCLK (regm4) is not used */ 1253 /* dsi_pll_hsdiv_dsi_clk (regm_dsi) is not used */
965 best.regm4 = 0; 1254 best.regm_dsi = 0;
966 best.dsi2_pll_fclk = 0; 1255 best.dsi_pll_hsdiv_dsi_clk = 0;
967 1256
968 if (dsi_cinfo) 1257 if (dsi_cinfo)
969 *dsi_cinfo = best; 1258 *dsi_cinfo = best;
@@ -982,23 +1271,27 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
982 int r = 0; 1271 int r = 0;
983 u32 l; 1272 u32 l;
984 int f; 1273 int f;
1274 u8 regn_start, regn_end, regm_start, regm_end;
1275 u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
985 1276
986 DSSDBGF(); 1277 DSSDBGF();
987 1278
988 dsi.current_cinfo.fint = cinfo->fint; 1279 dsi.current_cinfo.fint = cinfo->fint;
989 dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr; 1280 dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr;
990 dsi.current_cinfo.dsi1_pll_fclk = cinfo->dsi1_pll_fclk; 1281 dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk =
991 dsi.current_cinfo.dsi2_pll_fclk = cinfo->dsi2_pll_fclk; 1282 cinfo->dsi_pll_hsdiv_dispc_clk;
1283 dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk =
1284 cinfo->dsi_pll_hsdiv_dsi_clk;
992 1285
993 dsi.current_cinfo.regn = cinfo->regn; 1286 dsi.current_cinfo.regn = cinfo->regn;
994 dsi.current_cinfo.regm = cinfo->regm; 1287 dsi.current_cinfo.regm = cinfo->regm;
995 dsi.current_cinfo.regm3 = cinfo->regm3; 1288 dsi.current_cinfo.regm_dispc = cinfo->regm_dispc;
996 dsi.current_cinfo.regm4 = cinfo->regm4; 1289 dsi.current_cinfo.regm_dsi = cinfo->regm_dsi;
997 1290
998 DSSDBG("DSI Fint %ld\n", cinfo->fint); 1291 DSSDBG("DSI Fint %ld\n", cinfo->fint);
999 1292
1000 DSSDBG("clkin (%s) rate %ld, highfreq %d\n", 1293 DSSDBG("clkin (%s) rate %ld, highfreq %d\n",
1001 cinfo->use_dss2_fck ? "dss2_fck" : "pclkfree", 1294 cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree",
1002 cinfo->clkin, 1295 cinfo->clkin,
1003 cinfo->highfreq); 1296 cinfo->highfreq);
1004 1297
@@ -1015,24 +1308,39 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1015 1308
1016 DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4); 1309 DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4);
1017 1310
1018 DSSDBG("regm3 = %d, dsi1_pll_fclk = %lu\n", 1311 DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc,
1019 cinfo->regm3, cinfo->dsi1_pll_fclk); 1312 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1020 DSSDBG("regm4 = %d, dsi2_pll_fclk = %lu\n", 1313 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1021 cinfo->regm4, cinfo->dsi2_pll_fclk); 1314 cinfo->dsi_pll_hsdiv_dispc_clk);
1315 DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi,
1316 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1317 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1318 cinfo->dsi_pll_hsdiv_dsi_clk);
1319
1320 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, &regn_start, &regn_end);
1321 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM, &regm_start, &regm_end);
1322 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DISPC, &regm_dispc_start,
1323 &regm_dispc_end);
1324 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, &regm_dsi_start,
1325 &regm_dsi_end);
1022 1326
1023 REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */ 1327 REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */
1024 1328
1025 l = dsi_read_reg(DSI_PLL_CONFIGURATION1); 1329 l = dsi_read_reg(DSI_PLL_CONFIGURATION1);
1026 l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ 1330 l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */
1027 l = FLD_MOD(l, cinfo->regn - 1, 7, 1); /* DSI_PLL_REGN */ 1331 /* DSI_PLL_REGN */
1028 l = FLD_MOD(l, cinfo->regm, 18, 8); /* DSI_PLL_REGM */ 1332 l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end);
1029 l = FLD_MOD(l, cinfo->regm3 > 0 ? cinfo->regm3 - 1 : 0, 1333 /* DSI_PLL_REGM */
1030 22, 19); /* DSI_CLOCK_DIV */ 1334 l = FLD_MOD(l, cinfo->regm, regm_start, regm_end);
1031 l = FLD_MOD(l, cinfo->regm4 > 0 ? cinfo->regm4 - 1 : 0, 1335 /* DSI_CLOCK_DIV */
1032 26, 23); /* DSIPROTO_CLOCK_DIV */ 1336 l = FLD_MOD(l, cinfo->regm_dispc > 0 ? cinfo->regm_dispc - 1 : 0,
1337 regm_dispc_start, regm_dispc_end);
1338 /* DSIPROTO_CLOCK_DIV */
1339 l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0,
1340 regm_dsi_start, regm_dsi_end);
1033 dsi_write_reg(DSI_PLL_CONFIGURATION1, l); 1341 dsi_write_reg(DSI_PLL_CONFIGURATION1, l);
1034 1342
1035 BUG_ON(cinfo->fint < 750000 || cinfo->fint > 2100000); 1343 BUG_ON(cinfo->fint < dsi.fint_min || cinfo->fint > dsi.fint_max);
1036 if (cinfo->fint < 1000000) 1344 if (cinfo->fint < 1000000)
1037 f = 0x3; 1345 f = 0x3;
1038 else if (cinfo->fint < 1250000) 1346 else if (cinfo->fint < 1250000)
@@ -1046,7 +1354,7 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1046 1354
1047 l = dsi_read_reg(DSI_PLL_CONFIGURATION2); 1355 l = dsi_read_reg(DSI_PLL_CONFIGURATION2);
1048 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ 1356 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */
1049 l = FLD_MOD(l, cinfo->use_dss2_fck ? 0 : 1, 1357 l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1,
1050 11, 11); /* DSI_PLL_CLKSEL */ 1358 11, 11); /* DSI_PLL_CLKSEL */
1051 l = FLD_MOD(l, cinfo->highfreq, 1359 l = FLD_MOD(l, cinfo->highfreq,
1052 12, 12); /* DSI_PLL_HIGHFREQ */ 1360 12, 12); /* DSI_PLL_HIGHFREQ */
@@ -1101,6 +1409,26 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
1101 1409
1102 DSSDBG("PLL init\n"); 1410 DSSDBG("PLL init\n");
1103 1411
1412#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
1413 /*
1414 * HACK: this is just a quick hack to get the USE_DSI_PLL
1415 * option working. USE_DSI_PLL is itself a big hack, and
1416 * should be removed.
1417 */
1418 if (dsi.vdds_dsi_reg == NULL) {
1419 struct regulator *vdds_dsi;
1420
1421 vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi");
1422
1423 if (IS_ERR(vdds_dsi)) {
1424 DSSERR("can't get VDDS_DSI regulator\n");
1425 return PTR_ERR(vdds_dsi);
1426 }
1427
1428 dsi.vdds_dsi_reg = vdds_dsi;
1429 }
1430#endif
1431
1104 enable_clocks(1); 1432 enable_clocks(1);
1105 dsi_enable_pll_clock(1); 1433 dsi_enable_pll_clock(1);
1106 1434
@@ -1162,6 +1490,10 @@ void dsi_dump_clocks(struct seq_file *s)
1162{ 1490{
1163 int clksel; 1491 int clksel;
1164 struct dsi_clock_info *cinfo = &dsi.current_cinfo; 1492 struct dsi_clock_info *cinfo = &dsi.current_cinfo;
1493 enum dss_clk_source dispc_clk_src, dsi_clk_src;
1494
1495 dispc_clk_src = dss_get_dispc_clk_source();
1496 dsi_clk_src = dss_get_dsi_clk_source();
1165 1497
1166 enable_clocks(1); 1498 enable_clocks(1);
1167 1499
@@ -1171,30 +1503,34 @@ void dsi_dump_clocks(struct seq_file *s)
1171 1503
1172 seq_printf(s, "dsi pll source = %s\n", 1504 seq_printf(s, "dsi pll source = %s\n",
1173 clksel == 0 ? 1505 clksel == 0 ?
1174 "dss2_alwon_fclk" : "pclkfree"); 1506 "dss_sys_clk" : "pclkfree");
1175 1507
1176 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); 1508 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn);
1177 1509
1178 seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n", 1510 seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n",
1179 cinfo->clkin4ddr, cinfo->regm); 1511 cinfo->clkin4ddr, cinfo->regm);
1180 1512
1181 seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n", 1513 seq_printf(s, "%s (%s)\t%-16luregm_dispc %u\t(%s)\n",
1182 cinfo->dsi1_pll_fclk, 1514 dss_get_generic_clk_source_name(dispc_clk_src),
1183 cinfo->regm3, 1515 dss_feat_get_clk_source_name(dispc_clk_src),
1184 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1516 cinfo->dsi_pll_hsdiv_dispc_clk,
1517 cinfo->regm_dispc,
1518 dispc_clk_src == DSS_CLK_SRC_FCK ?
1185 "off" : "on"); 1519 "off" : "on");
1186 1520
1187 seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n", 1521 seq_printf(s, "%s (%s)\t%-16luregm_dsi %u\t(%s)\n",
1188 cinfo->dsi2_pll_fclk, 1522 dss_get_generic_clk_source_name(dsi_clk_src),
1189 cinfo->regm4, 1523 dss_feat_get_clk_source_name(dsi_clk_src),
1190 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1524 cinfo->dsi_pll_hsdiv_dsi_clk,
1525 cinfo->regm_dsi,
1526 dsi_clk_src == DSS_CLK_SRC_FCK ?
1191 "off" : "on"); 1527 "off" : "on");
1192 1528
1193 seq_printf(s, "- DSI -\n"); 1529 seq_printf(s, "- DSI -\n");
1194 1530
1195 seq_printf(s, "dsi fclk source = %s\n", 1531 seq_printf(s, "dsi fclk source = %s (%s)\n",
1196 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1532 dss_get_generic_clk_source_name(dsi_clk_src),
1197 "dss1_alwon_fclk" : "dsi2_pll_fclk"); 1533 dss_feat_get_clk_source_name(dsi_clk_src));
1198 1534
1199 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); 1535 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate());
1200 1536
@@ -1306,7 +1642,7 @@ void dsi_dump_regs(struct seq_file *s)
1306{ 1642{
1307#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) 1643#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r))
1308 1644
1309 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 1645 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
1310 1646
1311 DUMPREG(DSI_REVISION); 1647 DUMPREG(DSI_REVISION);
1312 DUMPREG(DSI_SYSCONFIG); 1648 DUMPREG(DSI_SYSCONFIG);
@@ -1378,7 +1714,7 @@ void dsi_dump_regs(struct seq_file *s)
1378 DUMPREG(DSI_PLL_CONFIGURATION1); 1714 DUMPREG(DSI_PLL_CONFIGURATION1);
1379 DUMPREG(DSI_PLL_CONFIGURATION2); 1715 DUMPREG(DSI_PLL_CONFIGURATION2);
1380 1716
1381 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 1717 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
1382#undef DUMPREG 1718#undef DUMPREG
1383} 1719}
1384 1720
@@ -1622,20 +1958,6 @@ static int _dsi_reset(void)
1622 return _dsi_wait_reset(); 1958 return _dsi_wait_reset();
1623} 1959}
1624 1960
1625static void dsi_reset_tx_fifo(int channel)
1626{
1627 u32 mask;
1628 u32 l;
1629
1630 /* set fifosize of the channel to 0, then return the old size */
1631 l = dsi_read_reg(DSI_TX_FIFO_VC_SIZE);
1632
1633 mask = FLD_MASK((8 * channel) + 7, (8 * channel) + 4);
1634 dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l & ~mask);
1635
1636 dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l);
1637}
1638
1639static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2, 1961static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2,
1640 enum fifo_size size3, enum fifo_size size4) 1962 enum fifo_size size3, enum fifo_size size4)
1641{ 1963{
@@ -1753,8 +2075,6 @@ static void dsi_vc_initial_config(int channel)
1753 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ 2075 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
1754 2076
1755 dsi_write_reg(DSI_VC_CTRL(channel), r); 2077 dsi_write_reg(DSI_VC_CTRL(channel), r);
1756
1757 dsi.vc[channel].mode = DSI_VC_MODE_L4;
1758} 2078}
1759 2079
1760static int dsi_vc_config_l4(int channel) 2080static int dsi_vc_config_l4(int channel)
@@ -1922,33 +2242,44 @@ static int dsi_vc_send_bta(int channel)
1922 2242
1923int dsi_vc_send_bta_sync(int channel) 2243int dsi_vc_send_bta_sync(int channel)
1924{ 2244{
2245 DECLARE_COMPLETION_ONSTACK(completion);
1925 int r = 0; 2246 int r = 0;
1926 u32 err; 2247 u32 err;
1927 2248
1928 INIT_COMPLETION(dsi.bta_completion); 2249 r = dsi_register_isr_vc(channel, dsi_completion_handler,
2250 &completion, DSI_VC_IRQ_BTA);
2251 if (r)
2252 goto err0;
1929 2253
1930 dsi_vc_enable_bta_irq(channel); 2254 r = dsi_register_isr(dsi_completion_handler, &completion,
2255 DSI_IRQ_ERROR_MASK);
2256 if (r)
2257 goto err1;
1931 2258
1932 r = dsi_vc_send_bta(channel); 2259 r = dsi_vc_send_bta(channel);
1933 if (r) 2260 if (r)
1934 goto err; 2261 goto err2;
1935 2262
1936 if (wait_for_completion_timeout(&dsi.bta_completion, 2263 if (wait_for_completion_timeout(&completion,
1937 msecs_to_jiffies(500)) == 0) { 2264 msecs_to_jiffies(500)) == 0) {
1938 DSSERR("Failed to receive BTA\n"); 2265 DSSERR("Failed to receive BTA\n");
1939 r = -EIO; 2266 r = -EIO;
1940 goto err; 2267 goto err2;
1941 } 2268 }
1942 2269
1943 err = dsi_get_errors(); 2270 err = dsi_get_errors();
1944 if (err) { 2271 if (err) {
1945 DSSERR("Error while sending BTA: %x\n", err); 2272 DSSERR("Error while sending BTA: %x\n", err);
1946 r = -EIO; 2273 r = -EIO;
1947 goto err; 2274 goto err2;
1948 } 2275 }
1949err: 2276err2:
1950 dsi_vc_disable_bta_irq(channel); 2277 dsi_unregister_isr(dsi_completion_handler, &completion,
1951 2278 DSI_IRQ_ERROR_MASK);
2279err1:
2280 dsi_unregister_isr_vc(channel, dsi_completion_handler,
2281 &completion, DSI_VC_IRQ_BTA);
2282err0:
1952 return r; 2283 return r;
1953} 2284}
1954EXPORT_SYMBOL(dsi_vc_send_bta_sync); 2285EXPORT_SYMBOL(dsi_vc_send_bta_sync);
@@ -1961,7 +2292,7 @@ static inline void dsi_vc_write_long_header(int channel, u8 data_type,
1961 2292
1962 WARN_ON(!dsi_bus_is_locked()); 2293 WARN_ON(!dsi_bus_is_locked());
1963 2294
1964 data_id = data_type | channel << 6; 2295 data_id = data_type | dsi.vc[channel].vc_id << 6;
1965 2296
1966 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | 2297 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
1967 FLD_VAL(ecc, 31, 24); 2298 FLD_VAL(ecc, 31, 24);
@@ -2064,7 +2395,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
2064 return -EINVAL; 2395 return -EINVAL;
2065 } 2396 }
2066 2397
2067 data_id = data_type | channel << 6; 2398 data_id = data_type | dsi.vc[channel].vc_id << 6;
2068 2399
2069 r = (data_id << 0) | (data << 8) | (ecc << 24); 2400 r = (data_id << 0) | (data << 8) | (ecc << 24);
2070 2401
@@ -2762,19 +3093,20 @@ static void dsi_te_timeout(unsigned long arg)
2762} 3093}
2763#endif 3094#endif
2764 3095
3096static void dsi_framedone_bta_callback(void *data, u32 mask);
3097
2765static void dsi_handle_framedone(int error) 3098static void dsi_handle_framedone(int error)
2766{ 3099{
2767 const int channel = dsi.update_channel; 3100 const int channel = dsi.update_channel;
2768 3101
2769 cancel_delayed_work(&dsi.framedone_timeout_work); 3102 dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback,
3103 NULL, DSI_VC_IRQ_BTA);
2770 3104
2771 dsi_vc_disable_bta_irq(channel); 3105 cancel_delayed_work(&dsi.framedone_timeout_work);
2772 3106
2773 /* SIDLEMODE back to smart-idle */ 3107 /* SIDLEMODE back to smart-idle */
2774 dispc_enable_sidle(); 3108 dispc_enable_sidle();
2775 3109
2776 dsi.bta_callback = NULL;
2777
2778 if (dsi.te_enabled) { 3110 if (dsi.te_enabled) {
2779 /* enable LP_RX_TO again after the TE */ 3111 /* enable LP_RX_TO again after the TE */
2780 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ 3112 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
@@ -2808,7 +3140,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
2808 dsi_handle_framedone(-ETIMEDOUT); 3140 dsi_handle_framedone(-ETIMEDOUT);
2809} 3141}
2810 3142
2811static void dsi_framedone_bta_callback(void) 3143static void dsi_framedone_bta_callback(void *data, u32 mask)
2812{ 3144{
2813 dsi_handle_framedone(0); 3145 dsi_handle_framedone(0);
2814 3146
@@ -2848,15 +3180,19 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
2848 * asynchronously. 3180 * asynchronously.
2849 * */ 3181 * */
2850 3182
2851 dsi.bta_callback = dsi_framedone_bta_callback; 3183 r = dsi_register_isr_vc(channel, dsi_framedone_bta_callback,
2852 3184 NULL, DSI_VC_IRQ_BTA);
2853 barrier(); 3185 if (r) {
2854 3186 DSSERR("Failed to register BTA ISR\n");
2855 dsi_vc_enable_bta_irq(channel); 3187 dsi_handle_framedone(-EIO);
3188 return;
3189 }
2856 3190
2857 r = dsi_vc_send_bta(channel); 3191 r = dsi_vc_send_bta(channel);
2858 if (r) { 3192 if (r) {
2859 DSSERR("BTA after framedone failed\n"); 3193 DSSERR("BTA after framedone failed\n");
3194 dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback,
3195 NULL, DSI_VC_IRQ_BTA);
2860 dsi_handle_framedone(-EIO); 3196 dsi_handle_framedone(-EIO);
2861 } 3197 }
2862} 3198}
@@ -2984,12 +3320,12 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
2984 struct dsi_clock_info cinfo; 3320 struct dsi_clock_info cinfo;
2985 int r; 3321 int r;
2986 3322
2987 /* we always use DSS2_FCK as input clock */ 3323 /* we always use DSS_CLK_SYSCK as input clock */
2988 cinfo.use_dss2_fck = true; 3324 cinfo.use_sys_clk = true;
2989 cinfo.regn = dssdev->phy.dsi.div.regn; 3325 cinfo.regn = dssdev->phy.dsi.div.regn;
2990 cinfo.regm = dssdev->phy.dsi.div.regm; 3326 cinfo.regm = dssdev->phy.dsi.div.regm;
2991 cinfo.regm3 = dssdev->phy.dsi.div.regm3; 3327 cinfo.regm_dispc = dssdev->phy.dsi.div.regm_dispc;
2992 cinfo.regm4 = dssdev->phy.dsi.div.regm4; 3328 cinfo.regm_dsi = dssdev->phy.dsi.div.regm_dsi;
2993 r = dsi_calc_clock_rates(dssdev, &cinfo); 3329 r = dsi_calc_clock_rates(dssdev, &cinfo);
2994 if (r) { 3330 if (r) {
2995 DSSERR("Failed to calc dsi clocks\n"); 3331 DSSERR("Failed to calc dsi clocks\n");
@@ -3011,7 +3347,7 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
3011 int r; 3347 int r;
3012 unsigned long long fck; 3348 unsigned long long fck;
3013 3349
3014 fck = dsi_get_dsi1_pll_rate(); 3350 fck = dsi_get_pll_hsdiv_dispc_rate();
3015 3351
3016 dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div; 3352 dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div;
3017 dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div; 3353 dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div;
@@ -3045,8 +3381,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3045 if (r) 3381 if (r)
3046 goto err1; 3382 goto err1;
3047 3383
3048 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); 3384 dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC);
3049 dss_select_dsi_clk_source(DSS_SRC_DSI2_PLL_FCLK); 3385 dss_select_dsi_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI);
3050 3386
3051 DSSDBG("PLL OK\n"); 3387 DSSDBG("PLL OK\n");
3052 3388
@@ -3082,8 +3418,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3082err3: 3418err3:
3083 dsi_complexio_uninit(); 3419 dsi_complexio_uninit();
3084err2: 3420err2:
3085 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3421 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
3086 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3422 dss_select_dsi_clk_source(DSS_CLK_SRC_FCK);
3087err1: 3423err1:
3088 dsi_pll_uninit(); 3424 dsi_pll_uninit();
3089err0: 3425err0:
@@ -3099,8 +3435,8 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
3099 dsi_vc_enable(2, 0); 3435 dsi_vc_enable(2, 0);
3100 dsi_vc_enable(3, 0); 3436 dsi_vc_enable(3, 0);
3101 3437
3102 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3438 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
3103 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3439 dss_select_dsi_clk_source(DSS_CLK_SRC_FCK);
3104 dsi_complexio_uninit(); 3440 dsi_complexio_uninit();
3105 dsi_pll_uninit(); 3441 dsi_pll_uninit();
3106} 3442}
@@ -3220,29 +3556,107 @@ int dsi_init_display(struct omap_dss_device *dssdev)
3220 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | 3556 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
3221 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; 3557 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
3222 3558
3223 dsi.vc[0].dssdev = dssdev; 3559 if (dsi.vdds_dsi_reg == NULL) {
3224 dsi.vc[1].dssdev = dssdev; 3560 struct regulator *vdds_dsi;
3561
3562 vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi");
3563
3564 if (IS_ERR(vdds_dsi)) {
3565 DSSERR("can't get VDDS_DSI regulator\n");
3566 return PTR_ERR(vdds_dsi);
3567 }
3568
3569 dsi.vdds_dsi_reg = vdds_dsi;
3570 }
3225 3571
3226 return 0; 3572 return 0;
3227} 3573}
3228 3574
3229void dsi_wait_dsi1_pll_active(void) 3575int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
3576{
3577 int i;
3578
3579 for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) {
3580 if (!dsi.vc[i].dssdev) {
3581 dsi.vc[i].dssdev = dssdev;
3582 *channel = i;
3583 return 0;
3584 }
3585 }
3586
3587 DSSERR("cannot get VC for display %s", dssdev->name);
3588 return -ENOSPC;
3589}
3590EXPORT_SYMBOL(omap_dsi_request_vc);
3591
3592int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
3593{
3594 if (vc_id < 0 || vc_id > 3) {
3595 DSSERR("VC ID out of range\n");
3596 return -EINVAL;
3597 }
3598
3599 if (channel < 0 || channel > 3) {
3600 DSSERR("Virtual Channel out of range\n");
3601 return -EINVAL;
3602 }
3603
3604 if (dsi.vc[channel].dssdev != dssdev) {
3605 DSSERR("Virtual Channel not allocated to display %s\n",
3606 dssdev->name);
3607 return -EINVAL;
3608 }
3609
3610 dsi.vc[channel].vc_id = vc_id;
3611
3612 return 0;
3613}
3614EXPORT_SYMBOL(omap_dsi_set_vc_id);
3615
3616void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel)
3617{
3618 if ((channel >= 0 && channel <= 3) &&
3619 dsi.vc[channel].dssdev == dssdev) {
3620 dsi.vc[channel].dssdev = NULL;
3621 dsi.vc[channel].vc_id = 0;
3622 }
3623}
3624EXPORT_SYMBOL(omap_dsi_release_vc);
3625
3626void dsi_wait_pll_hsdiv_dispc_active(void)
3230{ 3627{
3231 if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1) 3628 if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1)
3232 DSSERR("DSI1 PLL clock not active\n"); 3629 DSSERR("%s (%s) not active\n",
3630 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
3631 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC));
3233} 3632}
3234 3633
3235void dsi_wait_dsi2_pll_active(void) 3634void dsi_wait_pll_hsdiv_dsi_active(void)
3236{ 3635{
3237 if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1) 3636 if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1)
3238 DSSERR("DSI2 PLL clock not active\n"); 3637 DSSERR("%s (%s) not active\n",
3638 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
3639 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI));
3640}
3641
3642static void dsi_calc_clock_param_ranges(void)
3643{
3644 dsi.regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN);
3645 dsi.regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM);
3646 dsi.regm_dispc_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC);
3647 dsi.regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI);
3648 dsi.fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT);
3649 dsi.fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT);
3650 dsi.lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
3239} 3651}
3240 3652
3241int dsi_init(struct platform_device *pdev) 3653static int dsi_init(struct platform_device *pdev)
3242{ 3654{
3243 u32 rev; 3655 u32 rev;
3244 int r; 3656 int r, i;
3657 struct resource *dsi_mem;
3245 3658
3659 spin_lock_init(&dsi.irq_lock);
3246 spin_lock_init(&dsi.errors_lock); 3660 spin_lock_init(&dsi.errors_lock);
3247 dsi.errors = 0; 3661 dsi.errors = 0;
3248 3662
@@ -3251,8 +3665,6 @@ int dsi_init(struct platform_device *pdev)
3251 dsi.irq_stats.last_reset = jiffies; 3665 dsi.irq_stats.last_reset = jiffies;
3252#endif 3666#endif
3253 3667
3254 init_completion(&dsi.bta_completion);
3255
3256 mutex_init(&dsi.lock); 3668 mutex_init(&dsi.lock);
3257 sema_init(&dsi.bus_lock, 1); 3669 sema_init(&dsi.bus_lock, 1);
3258 3670
@@ -3268,24 +3680,45 @@ int dsi_init(struct platform_device *pdev)
3268 dsi.te_timer.function = dsi_te_timeout; 3680 dsi.te_timer.function = dsi_te_timeout;
3269 dsi.te_timer.data = 0; 3681 dsi.te_timer.data = 0;
3270#endif 3682#endif
3271 dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS); 3683 dsi_mem = platform_get_resource(dsi.pdev, IORESOURCE_MEM, 0);
3684 if (!dsi_mem) {
3685 DSSERR("can't get IORESOURCE_MEM DSI\n");
3686 r = -EINVAL;
3687 goto err1;
3688 }
3689 dsi.base = ioremap(dsi_mem->start, resource_size(dsi_mem));
3272 if (!dsi.base) { 3690 if (!dsi.base) {
3273 DSSERR("can't ioremap DSI\n"); 3691 DSSERR("can't ioremap DSI\n");
3274 r = -ENOMEM; 3692 r = -ENOMEM;
3275 goto err1; 3693 goto err1;
3276 } 3694 }
3695 dsi.irq = platform_get_irq(dsi.pdev, 0);
3696 if (dsi.irq < 0) {
3697 DSSERR("platform_get_irq failed\n");
3698 r = -ENODEV;
3699 goto err2;
3700 }
3277 3701
3278 dsi.vdds_dsi_reg = dss_get_vdds_dsi(); 3702 r = request_irq(dsi.irq, omap_dsi_irq_handler, IRQF_SHARED,
3279 if (IS_ERR(dsi.vdds_dsi_reg)) { 3703 "OMAP DSI1", dsi.pdev);
3280 DSSERR("can't get VDDS_DSI regulator\n"); 3704 if (r < 0) {
3281 r = PTR_ERR(dsi.vdds_dsi_reg); 3705 DSSERR("request_irq failed\n");
3282 goto err2; 3706 goto err2;
3283 } 3707 }
3284 3708
3709 /* DSI VCs initialization */
3710 for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) {
3711 dsi.vc[i].mode = DSI_VC_MODE_L4;
3712 dsi.vc[i].dssdev = NULL;
3713 dsi.vc[i].vc_id = 0;
3714 }
3715
3716 dsi_calc_clock_param_ranges();
3717
3285 enable_clocks(1); 3718 enable_clocks(1);
3286 3719
3287 rev = dsi_read_reg(DSI_REVISION); 3720 rev = dsi_read_reg(DSI_REVISION);
3288 printk(KERN_INFO "OMAP DSI rev %d.%d\n", 3721 dev_dbg(&pdev->dev, "OMAP DSI rev %d.%d\n",
3289 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 3722 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3290 3723
3291 enable_clocks(0); 3724 enable_clocks(0);
@@ -3298,8 +3731,14 @@ err1:
3298 return r; 3731 return r;
3299} 3732}
3300 3733
3301void dsi_exit(void) 3734static void dsi_exit(void)
3302{ 3735{
3736 if (dsi.vdds_dsi_reg != NULL) {
3737 regulator_put(dsi.vdds_dsi_reg);
3738 dsi.vdds_dsi_reg = NULL;
3739 }
3740
3741 free_irq(dsi.irq, dsi.pdev);
3303 iounmap(dsi.base); 3742 iounmap(dsi.base);
3304 3743
3305 destroy_workqueue(dsi.workqueue); 3744 destroy_workqueue(dsi.workqueue);
@@ -3307,3 +3746,41 @@ void dsi_exit(void)
3307 DSSDBG("omap_dsi_exit\n"); 3746 DSSDBG("omap_dsi_exit\n");
3308} 3747}
3309 3748
3749/* DSI1 HW IP initialisation */
3750static int omap_dsi1hw_probe(struct platform_device *pdev)
3751{
3752 int r;
3753 dsi.pdev = pdev;
3754 r = dsi_init(pdev);
3755 if (r) {
3756 DSSERR("Failed to initialize DSI\n");
3757 goto err_dsi;
3758 }
3759err_dsi:
3760 return r;
3761}
3762
3763static int omap_dsi1hw_remove(struct platform_device *pdev)
3764{
3765 dsi_exit();
3766 return 0;
3767}
3768
3769static struct platform_driver omap_dsi1hw_driver = {
3770 .probe = omap_dsi1hw_probe,
3771 .remove = omap_dsi1hw_remove,
3772 .driver = {
3773 .name = "omapdss_dsi1",
3774 .owner = THIS_MODULE,
3775 },
3776};
3777
3778int dsi_init_platform_driver(void)
3779{
3780 return platform_driver_register(&omap_dsi1hw_driver);
3781}
3782
3783void dsi_uninit_platform_driver(void)
3784{
3785 return platform_driver_unregister(&omap_dsi1hw_driver);
3786}
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 77c3621c917..3f1fee63c67 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -26,14 +26,13 @@
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/err.h> 27#include <linux/err.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/interrupt.h>
30#include <linux/seq_file.h> 29#include <linux/seq_file.h>
31#include <linux/clk.h> 30#include <linux/clk.h>
32 31
33#include <plat/display.h> 32#include <plat/display.h>
33#include <plat/clock.h>
34#include "dss.h" 34#include "dss.h"
35 35#include "dss_features.h"
36#define DSS_BASE 0x48050000
37 36
38#define DSS_SZ_REGS SZ_512 37#define DSS_SZ_REGS SZ_512
39 38
@@ -59,9 +58,17 @@ struct dss_reg {
59 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end)) 58 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
60 59
61static struct { 60static struct {
61 struct platform_device *pdev;
62 void __iomem *base; 62 void __iomem *base;
63 int ctx_id;
63 64
64 struct clk *dpll4_m4_ck; 65 struct clk *dpll4_m4_ck;
66 struct clk *dss_ick;
67 struct clk *dss_fck;
68 struct clk *dss_sys_clk;
69 struct clk *dss_tv_fck;
70 struct clk *dss_video_fck;
71 unsigned num_clks_enabled;
65 72
66 unsigned long cache_req_pck; 73 unsigned long cache_req_pck;
67 unsigned long cache_prate; 74 unsigned long cache_prate;
@@ -70,10 +77,22 @@ static struct {
70 77
71 enum dss_clk_source dsi_clk_source; 78 enum dss_clk_source dsi_clk_source;
72 enum dss_clk_source dispc_clk_source; 79 enum dss_clk_source dispc_clk_source;
80 enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
73 81
74 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 82 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
75} dss; 83} dss;
76 84
85static const char * const dss_generic_clk_source_names[] = {
86 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC",
87 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI",
88 [DSS_CLK_SRC_FCK] = "DSS_FCK",
89};
90
91static void dss_clk_enable_all_no_ctx(void);
92static void dss_clk_disable_all_no_ctx(void);
93static void dss_clk_enable_no_ctx(enum dss_clock clks);
94static void dss_clk_disable_no_ctx(enum dss_clock clks);
95
77static int _omap_dss_wait_reset(void); 96static int _omap_dss_wait_reset(void);
78 97
79static inline void dss_write_reg(const struct dss_reg idx, u32 val) 98static inline void dss_write_reg(const struct dss_reg idx, u32 val)
@@ -99,10 +118,11 @@ void dss_save_context(void)
99 SR(SYSCONFIG); 118 SR(SYSCONFIG);
100 SR(CONTROL); 119 SR(CONTROL);
101 120
102#ifdef CONFIG_OMAP2_DSS_SDI 121 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
103 SR(SDI_CONTROL); 122 OMAP_DISPLAY_TYPE_SDI) {
104 SR(PLL_CONTROL); 123 SR(SDI_CONTROL);
105#endif 124 SR(PLL_CONTROL);
125 }
106} 126}
107 127
108void dss_restore_context(void) 128void dss_restore_context(void)
@@ -113,10 +133,11 @@ void dss_restore_context(void)
113 RR(SYSCONFIG); 133 RR(SYSCONFIG);
114 RR(CONTROL); 134 RR(CONTROL);
115 135
116#ifdef CONFIG_OMAP2_DSS_SDI 136 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
117 RR(SDI_CONTROL); 137 OMAP_DISPLAY_TYPE_SDI) {
118 RR(PLL_CONTROL); 138 RR(SDI_CONTROL);
119#endif 139 RR(PLL_CONTROL);
140 }
120} 141}
121 142
122#undef SR 143#undef SR
@@ -209,66 +230,96 @@ void dss_sdi_disable(void)
209 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ 230 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
210} 231}
211 232
233const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src)
234{
235 return dss_generic_clk_source_names[clk_src];
236}
237
212void dss_dump_clocks(struct seq_file *s) 238void dss_dump_clocks(struct seq_file *s)
213{ 239{
214 unsigned long dpll4_ck_rate; 240 unsigned long dpll4_ck_rate;
215 unsigned long dpll4_m4_ck_rate; 241 unsigned long dpll4_m4_ck_rate;
242 const char *fclk_name, *fclk_real_name;
243 unsigned long fclk_rate;
216 244
217 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 245 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
218
219 dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
220 dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
221 246
222 seq_printf(s, "- DSS -\n"); 247 seq_printf(s, "- DSS -\n");
223 248
224 seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); 249 fclk_name = dss_get_generic_clk_source_name(DSS_CLK_SRC_FCK);
250 fclk_real_name = dss_feat_get_clk_source_name(DSS_CLK_SRC_FCK);
251 fclk_rate = dss_clk_get_rate(DSS_CLK_FCK);
225 252
226 if (cpu_is_omap3630()) 253 if (dss.dpll4_m4_ck) {
227 seq_printf(s, "dss1_alwon_fclk = %lu / %lu = %lu\n", 254 dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
228 dpll4_ck_rate, 255 dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
229 dpll4_ck_rate / dpll4_m4_ck_rate, 256
230 dss_clk_get_rate(DSS_CLK_FCK1)); 257 seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
231 else
232 seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n",
233 dpll4_ck_rate,
234 dpll4_ck_rate / dpll4_m4_ck_rate,
235 dss_clk_get_rate(DSS_CLK_FCK1));
236 258
237 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 259 if (cpu_is_omap3630() || cpu_is_omap44xx())
260 seq_printf(s, "%s (%s) = %lu / %lu = %lu\n",
261 fclk_name, fclk_real_name,
262 dpll4_ck_rate,
263 dpll4_ck_rate / dpll4_m4_ck_rate,
264 fclk_rate);
265 else
266 seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
267 fclk_name, fclk_real_name,
268 dpll4_ck_rate,
269 dpll4_ck_rate / dpll4_m4_ck_rate,
270 fclk_rate);
271 } else {
272 seq_printf(s, "%s (%s) = %lu\n",
273 fclk_name, fclk_real_name,
274 fclk_rate);
275 }
276
277 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
238} 278}
239 279
240void dss_dump_regs(struct seq_file *s) 280void dss_dump_regs(struct seq_file *s)
241{ 281{
242#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) 282#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
243 283
244 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 284 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
245 285
246 DUMPREG(DSS_REVISION); 286 DUMPREG(DSS_REVISION);
247 DUMPREG(DSS_SYSCONFIG); 287 DUMPREG(DSS_SYSCONFIG);
248 DUMPREG(DSS_SYSSTATUS); 288 DUMPREG(DSS_SYSSTATUS);
249 DUMPREG(DSS_IRQSTATUS); 289 DUMPREG(DSS_IRQSTATUS);
250 DUMPREG(DSS_CONTROL); 290 DUMPREG(DSS_CONTROL);
251 DUMPREG(DSS_SDI_CONTROL);
252 DUMPREG(DSS_PLL_CONTROL);
253 DUMPREG(DSS_SDI_STATUS);
254 291
255 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 292 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
293 OMAP_DISPLAY_TYPE_SDI) {
294 DUMPREG(DSS_SDI_CONTROL);
295 DUMPREG(DSS_PLL_CONTROL);
296 DUMPREG(DSS_SDI_STATUS);
297 }
298
299 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
256#undef DUMPREG 300#undef DUMPREG
257} 301}
258 302
259void dss_select_dispc_clk_source(enum dss_clk_source clk_src) 303void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
260{ 304{
261 int b; 305 int b;
306 u8 start, end;
307
308 switch (clk_src) {
309 case DSS_CLK_SRC_FCK:
310 b = 0;
311 break;
312 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
313 b = 1;
314 dsi_wait_pll_hsdiv_dispc_active();
315 break;
316 default:
317 BUG();
318 }
262 319
263 BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK && 320 dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
264 clk_src != DSS_SRC_DSS1_ALWON_FCLK);
265
266 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
267
268 if (clk_src == DSS_SRC_DSI1_PLL_FCLK)
269 dsi_wait_dsi1_pll_active();
270 321
271 REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ 322 REG_FLD_MOD(DSS_CONTROL, b, start, end); /* DISPC_CLK_SWITCH */
272 323
273 dss.dispc_clk_source = clk_src; 324 dss.dispc_clk_source = clk_src;
274} 325}
@@ -277,19 +328,51 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
277{ 328{
278 int b; 329 int b;
279 330
280 BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK && 331 switch (clk_src) {
281 clk_src != DSS_SRC_DSS1_ALWON_FCLK); 332 case DSS_CLK_SRC_FCK:
282 333 b = 0;
283 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; 334 break;
284 335 case DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
285 if (clk_src == DSS_SRC_DSI2_PLL_FCLK) 336 b = 1;
286 dsi_wait_dsi2_pll_active(); 337 dsi_wait_pll_hsdiv_dsi_active();
338 break;
339 default:
340 BUG();
341 }
287 342
288 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ 343 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
289 344
290 dss.dsi_clk_source = clk_src; 345 dss.dsi_clk_source = clk_src;
291} 346}
292 347
348void dss_select_lcd_clk_source(enum omap_channel channel,
349 enum dss_clk_source clk_src)
350{
351 int b, ix, pos;
352
353 if (!dss_has_feature(FEAT_LCD_CLK_SRC))
354 return;
355
356 switch (clk_src) {
357 case DSS_CLK_SRC_FCK:
358 b = 0;
359 break;
360 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
361 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
362 b = 1;
363 dsi_wait_pll_hsdiv_dispc_active();
364 break;
365 default:
366 BUG();
367 }
368
369 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12;
370 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */
371
372 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
373 dss.lcd_clk_source[ix] = clk_src;
374}
375
293enum dss_clk_source dss_get_dispc_clk_source(void) 376enum dss_clk_source dss_get_dispc_clk_source(void)
294{ 377{
295 return dss.dispc_clk_source; 378 return dss.dispc_clk_source;
@@ -300,34 +383,52 @@ enum dss_clk_source dss_get_dsi_clk_source(void)
300 return dss.dsi_clk_source; 383 return dss.dsi_clk_source;
301} 384}
302 385
386enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
387{
388 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
389 return dss.lcd_clk_source[ix];
390}
391
303/* calculate clock rates using dividers in cinfo */ 392/* calculate clock rates using dividers in cinfo */
304int dss_calc_clock_rates(struct dss_clock_info *cinfo) 393int dss_calc_clock_rates(struct dss_clock_info *cinfo)
305{ 394{
306 unsigned long prate; 395 if (dss.dpll4_m4_ck) {
396 unsigned long prate;
397 u16 fck_div_max = 16;
307 398
308 if (cinfo->fck_div > (cpu_is_omap3630() ? 32 : 16) || 399 if (cpu_is_omap3630() || cpu_is_omap44xx())
309 cinfo->fck_div == 0) 400 fck_div_max = 32;
310 return -EINVAL; 401
402 if (cinfo->fck_div > fck_div_max || cinfo->fck_div == 0)
403 return -EINVAL;
311 404
312 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 405 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
313 406
314 cinfo->fck = prate / cinfo->fck_div; 407 cinfo->fck = prate / cinfo->fck_div;
408 } else {
409 if (cinfo->fck_div != 0)
410 return -EINVAL;
411 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
412 }
315 413
316 return 0; 414 return 0;
317} 415}
318 416
319int dss_set_clock_div(struct dss_clock_info *cinfo) 417int dss_set_clock_div(struct dss_clock_info *cinfo)
320{ 418{
321 unsigned long prate; 419 if (dss.dpll4_m4_ck) {
322 int r; 420 unsigned long prate;
421 int r;
323 422
324 if (cpu_is_omap34xx()) {
325 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 423 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
326 DSSDBG("dpll4_m4 = %ld\n", prate); 424 DSSDBG("dpll4_m4 = %ld\n", prate);
327 425
328 r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div); 426 r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div);
329 if (r) 427 if (r)
330 return r; 428 return r;
429 } else {
430 if (cinfo->fck_div != 0)
431 return -EINVAL;
331 } 432 }
332 433
333 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div); 434 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
@@ -337,12 +438,14 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
337 438
338int dss_get_clock_div(struct dss_clock_info *cinfo) 439int dss_get_clock_div(struct dss_clock_info *cinfo)
339{ 440{
340 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK1); 441 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
341 442
342 if (cpu_is_omap34xx()) { 443 if (dss.dpll4_m4_ck) {
343 unsigned long prate; 444 unsigned long prate;
445
344 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 446 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
345 if (cpu_is_omap3630()) 447
448 if (cpu_is_omap3630() || cpu_is_omap44xx())
346 cinfo->fck_div = prate / (cinfo->fck); 449 cinfo->fck_div = prate / (cinfo->fck);
347 else 450 else
348 cinfo->fck_div = prate / (cinfo->fck / 2); 451 cinfo->fck_div = prate / (cinfo->fck / 2);
@@ -355,7 +458,7 @@ int dss_get_clock_div(struct dss_clock_info *cinfo)
355 458
356unsigned long dss_get_dpll4_rate(void) 459unsigned long dss_get_dpll4_rate(void)
357{ 460{
358 if (cpu_is_omap34xx()) 461 if (dss.dpll4_m4_ck)
359 return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 462 return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
360 else 463 else
361 return 0; 464 return 0;
@@ -369,16 +472,18 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
369 struct dss_clock_info best_dss; 472 struct dss_clock_info best_dss;
370 struct dispc_clock_info best_dispc; 473 struct dispc_clock_info best_dispc;
371 474
372 unsigned long fck; 475 unsigned long fck, max_dss_fck;
373 476
374 u16 fck_div; 477 u16 fck_div, fck_div_max = 16;
375 478
376 int match = 0; 479 int match = 0;
377 int min_fck_per_pck; 480 int min_fck_per_pck;
378 481
379 prate = dss_get_dpll4_rate(); 482 prate = dss_get_dpll4_rate();
380 483
381 fck = dss_clk_get_rate(DSS_CLK_FCK1); 484 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
485
486 fck = dss_clk_get_rate(DSS_CLK_FCK);
382 if (req_pck == dss.cache_req_pck && 487 if (req_pck == dss.cache_req_pck &&
383 ((cpu_is_omap34xx() && prate == dss.cache_prate) || 488 ((cpu_is_omap34xx() && prate == dss.cache_prate) ||
384 dss.cache_dss_cinfo.fck == fck)) { 489 dss.cache_dss_cinfo.fck == fck)) {
@@ -391,7 +496,7 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
391 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 496 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
392 497
393 if (min_fck_per_pck && 498 if (min_fck_per_pck &&
394 req_pck * min_fck_per_pck > DISPC_MAX_FCK) { 499 req_pck * min_fck_per_pck > max_dss_fck) {
395 DSSERR("Requested pixel clock not possible with the current " 500 DSSERR("Requested pixel clock not possible with the current "
396 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " 501 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
397 "the constraint off.\n"); 502 "the constraint off.\n");
@@ -402,10 +507,10 @@ retry:
402 memset(&best_dss, 0, sizeof(best_dss)); 507 memset(&best_dss, 0, sizeof(best_dss));
403 memset(&best_dispc, 0, sizeof(best_dispc)); 508 memset(&best_dispc, 0, sizeof(best_dispc));
404 509
405 if (cpu_is_omap24xx()) { 510 if (dss.dpll4_m4_ck == NULL) {
406 struct dispc_clock_info cur_dispc; 511 struct dispc_clock_info cur_dispc;
407 /* XXX can we change the clock on omap2? */ 512 /* XXX can we change the clock on omap2? */
408 fck = dss_clk_get_rate(DSS_CLK_FCK1); 513 fck = dss_clk_get_rate(DSS_CLK_FCK);
409 fck_div = 1; 514 fck_div = 1;
410 515
411 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); 516 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
@@ -417,17 +522,19 @@ retry:
417 best_dispc = cur_dispc; 522 best_dispc = cur_dispc;
418 523
419 goto found; 524 goto found;
420 } else if (cpu_is_omap34xx()) { 525 } else {
421 for (fck_div = (cpu_is_omap3630() ? 32 : 16); 526 if (cpu_is_omap3630() || cpu_is_omap44xx())
422 fck_div > 0; --fck_div) { 527 fck_div_max = 32;
528
529 for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
423 struct dispc_clock_info cur_dispc; 530 struct dispc_clock_info cur_dispc;
424 531
425 if (cpu_is_omap3630()) 532 if (fck_div_max == 32)
426 fck = prate / fck_div; 533 fck = prate / fck_div;
427 else 534 else
428 fck = prate / fck_div * 2; 535 fck = prate / fck_div * 2;
429 536
430 if (fck > DISPC_MAX_FCK) 537 if (fck > max_dss_fck)
431 continue; 538 continue;
432 539
433 if (min_fck_per_pck && 540 if (min_fck_per_pck &&
@@ -450,8 +557,6 @@ retry:
450 goto found; 557 goto found;
451 } 558 }
452 } 559 }
453 } else {
454 BUG();
455 } 560 }
456 561
457found: 562found:
@@ -482,31 +587,6 @@ found:
482 return 0; 587 return 0;
483} 588}
484 589
485
486
487static irqreturn_t dss_irq_handler_omap2(int irq, void *arg)
488{
489 dispc_irq_handler();
490
491 return IRQ_HANDLED;
492}
493
494static irqreturn_t dss_irq_handler_omap3(int irq, void *arg)
495{
496 u32 irqstatus;
497
498 irqstatus = dss_read_reg(DSS_IRQSTATUS);
499
500 if (irqstatus & (1<<0)) /* DISPC_IRQ */
501 dispc_irq_handler();
502#ifdef CONFIG_OMAP2_DSS_DSI
503 if (irqstatus & (1<<1)) /* DSI_IRQ */
504 dsi_irq_handler();
505#endif
506
507 return IRQ_HANDLED;
508}
509
510static int _omap_dss_wait_reset(void) 590static int _omap_dss_wait_reset(void)
511{ 591{
512 int t = 0; 592 int t = 0;
@@ -549,34 +629,45 @@ void dss_set_dac_pwrdn_bgz(bool enable)
549 REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ 629 REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
550} 630}
551 631
552int dss_init(bool skip_init) 632void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi)
633{
634 REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */
635}
636
637static int dss_init(void)
553{ 638{
554 int r; 639 int r;
555 u32 rev; 640 u32 rev;
641 struct resource *dss_mem;
642 struct clk *dpll4_m4_ck;
556 643
557 dss.base = ioremap(DSS_BASE, DSS_SZ_REGS); 644 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
645 if (!dss_mem) {
646 DSSERR("can't get IORESOURCE_MEM DSS\n");
647 r = -EINVAL;
648 goto fail0;
649 }
650 dss.base = ioremap(dss_mem->start, resource_size(dss_mem));
558 if (!dss.base) { 651 if (!dss.base) {
559 DSSERR("can't ioremap DSS\n"); 652 DSSERR("can't ioremap DSS\n");
560 r = -ENOMEM; 653 r = -ENOMEM;
561 goto fail0; 654 goto fail0;
562 } 655 }
563 656
564 if (!skip_init) { 657 /* disable LCD and DIGIT output. This seems to fix the synclost
565 /* disable LCD and DIGIT output. This seems to fix the synclost 658 * problem that we get, if the bootloader starts the DSS and
566 * problem that we get, if the bootloader starts the DSS and 659 * the kernel resets it */
567 * the kernel resets it */ 660 omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
568 omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
569 661
570 /* We need to wait here a bit, otherwise we sometimes start to 662 /* We need to wait here a bit, otherwise we sometimes start to
571 * get synclost errors, and after that only power cycle will 663 * get synclost errors, and after that only power cycle will
572 * restore DSS functionality. I have no idea why this happens. 664 * restore DSS functionality. I have no idea why this happens.
573 * And we have to wait _before_ resetting the DSS, but after 665 * And we have to wait _before_ resetting the DSS, but after
574 * enabling clocks. 666 * enabling clocks.
575 */ 667 */
576 msleep(50); 668 msleep(50);
577 669
578 _omap_dss_reset(); 670 _omap_dss_reset();
579 }
580 671
581 /* autoidle */ 672 /* autoidle */
582 REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); 673 REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);
@@ -589,29 +680,30 @@ int dss_init(bool skip_init)
589 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ 680 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
590 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ 681 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
591#endif 682#endif
592
593 r = request_irq(INT_24XX_DSS_IRQ,
594 cpu_is_omap24xx()
595 ? dss_irq_handler_omap2
596 : dss_irq_handler_omap3,
597 0, "OMAP DSS", NULL);
598
599 if (r < 0) {
600 DSSERR("omap2 dss: request_irq failed\n");
601 goto fail1;
602 }
603
604 if (cpu_is_omap34xx()) { 683 if (cpu_is_omap34xx()) {
605 dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); 684 dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
606 if (IS_ERR(dss.dpll4_m4_ck)) { 685 if (IS_ERR(dpll4_m4_ck)) {
607 DSSERR("Failed to get dpll4_m4_ck\n"); 686 DSSERR("Failed to get dpll4_m4_ck\n");
608 r = PTR_ERR(dss.dpll4_m4_ck); 687 r = PTR_ERR(dpll4_m4_ck);
609 goto fail2; 688 goto fail1;
610 } 689 }
690 } else if (cpu_is_omap44xx()) {
691 dpll4_m4_ck = clk_get(NULL, "dpll_per_m5x2_ck");
692 if (IS_ERR(dpll4_m4_ck)) {
693 DSSERR("Failed to get dpll4_m4_ck\n");
694 r = PTR_ERR(dpll4_m4_ck);
695 goto fail1;
696 }
697 } else { /* omap24xx */
698 dpll4_m4_ck = NULL;
611 } 699 }
612 700
613 dss.dsi_clk_source = DSS_SRC_DSS1_ALWON_FCLK; 701 dss.dpll4_m4_ck = dpll4_m4_ck;
614 dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK; 702
703 dss.dsi_clk_source = DSS_CLK_SRC_FCK;
704 dss.dispc_clk_source = DSS_CLK_SRC_FCK;
705 dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
706 dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;
615 707
616 dss_save_context(); 708 dss_save_context();
617 709
@@ -621,21 +713,416 @@ int dss_init(bool skip_init)
621 713
622 return 0; 714 return 0;
623 715
624fail2:
625 free_irq(INT_24XX_DSS_IRQ, NULL);
626fail1: 716fail1:
627 iounmap(dss.base); 717 iounmap(dss.base);
628fail0: 718fail0:
629 return r; 719 return r;
630} 720}
631 721
632void dss_exit(void) 722static void dss_exit(void)
633{ 723{
634 if (cpu_is_omap34xx()) 724 if (dss.dpll4_m4_ck)
635 clk_put(dss.dpll4_m4_ck); 725 clk_put(dss.dpll4_m4_ck);
636 726
637 free_irq(INT_24XX_DSS_IRQ, NULL);
638
639 iounmap(dss.base); 727 iounmap(dss.base);
640} 728}
641 729
730/* CONTEXT */
731static int dss_get_ctx_id(void)
732{
733 struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
734 int r;
735
736 if (!pdata->board_data->get_last_off_on_transaction_id)
737 return 0;
738 r = pdata->board_data->get_last_off_on_transaction_id(&dss.pdev->dev);
739 if (r < 0) {
740 dev_err(&dss.pdev->dev, "getting transaction ID failed, "
741 "will force context restore\n");
742 r = -1;
743 }
744 return r;
745}
746
747int dss_need_ctx_restore(void)
748{
749 int id = dss_get_ctx_id();
750
751 if (id < 0 || id != dss.ctx_id) {
752 DSSDBG("ctx id %d -> id %d\n",
753 dss.ctx_id, id);
754 dss.ctx_id = id;
755 return 1;
756 } else {
757 return 0;
758 }
759}
760
761static void save_all_ctx(void)
762{
763 DSSDBG("save context\n");
764
765 dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
766
767 dss_save_context();
768 dispc_save_context();
769#ifdef CONFIG_OMAP2_DSS_DSI
770 dsi_save_context();
771#endif
772
773 dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
774}
775
776static void restore_all_ctx(void)
777{
778 DSSDBG("restore context\n");
779
780 dss_clk_enable_all_no_ctx();
781
782 dss_restore_context();
783 dispc_restore_context();
784#ifdef CONFIG_OMAP2_DSS_DSI
785 dsi_restore_context();
786#endif
787
788 dss_clk_disable_all_no_ctx();
789}
790
791static int dss_get_clock(struct clk **clock, const char *clk_name)
792{
793 struct clk *clk;
794
795 clk = clk_get(&dss.pdev->dev, clk_name);
796
797 if (IS_ERR(clk)) {
798 DSSERR("can't get clock %s", clk_name);
799 return PTR_ERR(clk);
800 }
801
802 *clock = clk;
803
804 DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
805
806 return 0;
807}
808
809static int dss_get_clocks(void)
810{
811 int r;
812 struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
813
814 dss.dss_ick = NULL;
815 dss.dss_fck = NULL;
816 dss.dss_sys_clk = NULL;
817 dss.dss_tv_fck = NULL;
818 dss.dss_video_fck = NULL;
819
820 r = dss_get_clock(&dss.dss_ick, "ick");
821 if (r)
822 goto err;
823
824 r = dss_get_clock(&dss.dss_fck, "fck");
825 if (r)
826 goto err;
827
828 if (!pdata->opt_clock_available) {
829 r = -ENODEV;
830 goto err;
831 }
832
833 if (pdata->opt_clock_available("sys_clk")) {
834 r = dss_get_clock(&dss.dss_sys_clk, "sys_clk");
835 if (r)
836 goto err;
837 }
838
839 if (pdata->opt_clock_available("tv_clk")) {
840 r = dss_get_clock(&dss.dss_tv_fck, "tv_clk");
841 if (r)
842 goto err;
843 }
844
845 if (pdata->opt_clock_available("video_clk")) {
846 r = dss_get_clock(&dss.dss_video_fck, "video_clk");
847 if (r)
848 goto err;
849 }
850
851 return 0;
852
853err:
854 if (dss.dss_ick)
855 clk_put(dss.dss_ick);
856 if (dss.dss_fck)
857 clk_put(dss.dss_fck);
858 if (dss.dss_sys_clk)
859 clk_put(dss.dss_sys_clk);
860 if (dss.dss_tv_fck)
861 clk_put(dss.dss_tv_fck);
862 if (dss.dss_video_fck)
863 clk_put(dss.dss_video_fck);
864
865 return r;
866}
867
868static void dss_put_clocks(void)
869{
870 if (dss.dss_video_fck)
871 clk_put(dss.dss_video_fck);
872 if (dss.dss_tv_fck)
873 clk_put(dss.dss_tv_fck);
874 if (dss.dss_sys_clk)
875 clk_put(dss.dss_sys_clk);
876 clk_put(dss.dss_fck);
877 clk_put(dss.dss_ick);
878}
879
880unsigned long dss_clk_get_rate(enum dss_clock clk)
881{
882 switch (clk) {
883 case DSS_CLK_ICK:
884 return clk_get_rate(dss.dss_ick);
885 case DSS_CLK_FCK:
886 return clk_get_rate(dss.dss_fck);
887 case DSS_CLK_SYSCK:
888 return clk_get_rate(dss.dss_sys_clk);
889 case DSS_CLK_TVFCK:
890 return clk_get_rate(dss.dss_tv_fck);
891 case DSS_CLK_VIDFCK:
892 return clk_get_rate(dss.dss_video_fck);
893 }
894
895 BUG();
896 return 0;
897}
898
899static unsigned count_clk_bits(enum dss_clock clks)
900{
901 unsigned num_clks = 0;
902
903 if (clks & DSS_CLK_ICK)
904 ++num_clks;
905 if (clks & DSS_CLK_FCK)
906 ++num_clks;
907 if (clks & DSS_CLK_SYSCK)
908 ++num_clks;
909 if (clks & DSS_CLK_TVFCK)
910 ++num_clks;
911 if (clks & DSS_CLK_VIDFCK)
912 ++num_clks;
913
914 return num_clks;
915}
916
917static void dss_clk_enable_no_ctx(enum dss_clock clks)
918{
919 unsigned num_clks = count_clk_bits(clks);
920
921 if (clks & DSS_CLK_ICK)
922 clk_enable(dss.dss_ick);
923 if (clks & DSS_CLK_FCK)
924 clk_enable(dss.dss_fck);
925 if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
926 clk_enable(dss.dss_sys_clk);
927 if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
928 clk_enable(dss.dss_tv_fck);
929 if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
930 clk_enable(dss.dss_video_fck);
931
932 dss.num_clks_enabled += num_clks;
933}
934
935void dss_clk_enable(enum dss_clock clks)
936{
937 bool check_ctx = dss.num_clks_enabled == 0;
938
939 dss_clk_enable_no_ctx(clks);
940
941 /*
942 * HACK: On omap4 the registers may not be accessible right after
943 * enabling the clocks. At some point this will be handled by
944 * pm_runtime, but for the time begin this should make things work.
945 */
946 if (cpu_is_omap44xx() && check_ctx)
947 udelay(10);
948
949 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
950 restore_all_ctx();
951}
952
953static void dss_clk_disable_no_ctx(enum dss_clock clks)
954{
955 unsigned num_clks = count_clk_bits(clks);
956
957 if (clks & DSS_CLK_ICK)
958 clk_disable(dss.dss_ick);
959 if (clks & DSS_CLK_FCK)
960 clk_disable(dss.dss_fck);
961 if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
962 clk_disable(dss.dss_sys_clk);
963 if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
964 clk_disable(dss.dss_tv_fck);
965 if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
966 clk_disable(dss.dss_video_fck);
967
968 dss.num_clks_enabled -= num_clks;
969}
970
971void dss_clk_disable(enum dss_clock clks)
972{
973 if (cpu_is_omap34xx()) {
974 unsigned num_clks = count_clk_bits(clks);
975
976 BUG_ON(dss.num_clks_enabled < num_clks);
977
978 if (dss.num_clks_enabled == num_clks)
979 save_all_ctx();
980 }
981
982 dss_clk_disable_no_ctx(clks);
983}
984
985static void dss_clk_enable_all_no_ctx(void)
986{
987 enum dss_clock clks;
988
989 clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
990 if (cpu_is_omap34xx())
991 clks |= DSS_CLK_VIDFCK;
992 dss_clk_enable_no_ctx(clks);
993}
994
995static void dss_clk_disable_all_no_ctx(void)
996{
997 enum dss_clock clks;
998
999 clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
1000 if (cpu_is_omap34xx())
1001 clks |= DSS_CLK_VIDFCK;
1002 dss_clk_disable_no_ctx(clks);
1003}
1004
1005#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
1006/* CLOCKS */
1007static void core_dump_clocks(struct seq_file *s)
1008{
1009 int i;
1010 struct clk *clocks[5] = {
1011 dss.dss_ick,
1012 dss.dss_fck,
1013 dss.dss_sys_clk,
1014 dss.dss_tv_fck,
1015 dss.dss_video_fck
1016 };
1017
1018 seq_printf(s, "- CORE -\n");
1019
1020 seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled);
1021
1022 for (i = 0; i < 5; i++) {
1023 if (!clocks[i])
1024 continue;
1025 seq_printf(s, "%-15s\t%lu\t%d\n",
1026 clocks[i]->name,
1027 clk_get_rate(clocks[i]),
1028 clocks[i]->usecount);
1029 }
1030}
1031#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
1032
1033/* DEBUGFS */
1034#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
1035void dss_debug_dump_clocks(struct seq_file *s)
1036{
1037 core_dump_clocks(s);
1038 dss_dump_clocks(s);
1039 dispc_dump_clocks(s);
1040#ifdef CONFIG_OMAP2_DSS_DSI
1041 dsi_dump_clocks(s);
1042#endif
1043}
1044#endif
1045
1046
1047/* DSS HW IP initialisation */
1048static int omap_dsshw_probe(struct platform_device *pdev)
1049{
1050 int r;
1051
1052 dss.pdev = pdev;
1053
1054 r = dss_get_clocks();
1055 if (r)
1056 goto err_clocks;
1057
1058 dss_clk_enable_all_no_ctx();
1059
1060 dss.ctx_id = dss_get_ctx_id();
1061 DSSDBG("initial ctx id %u\n", dss.ctx_id);
1062
1063 r = dss_init();
1064 if (r) {
1065 DSSERR("Failed to initialize DSS\n");
1066 goto err_dss;
1067 }
1068
1069 r = dpi_init();
1070 if (r) {
1071 DSSERR("Failed to initialize DPI\n");
1072 goto err_dpi;
1073 }
1074
1075 r = sdi_init();
1076 if (r) {
1077 DSSERR("Failed to initialize SDI\n");
1078 goto err_sdi;
1079 }
1080
1081 dss_clk_disable_all_no_ctx();
1082 return 0;
1083err_sdi:
1084 dpi_exit();
1085err_dpi:
1086 dss_exit();
1087err_dss:
1088 dss_clk_disable_all_no_ctx();
1089 dss_put_clocks();
1090err_clocks:
1091 return r;
1092}
1093
1094static int omap_dsshw_remove(struct platform_device *pdev)
1095{
1096
1097 dss_exit();
1098
1099 /*
1100 * As part of hwmod changes, DSS is not the only controller of dss
1101 * clocks; hwmod framework itself will also enable clocks during hwmod
1102 * init for dss, and autoidle is set in h/w for DSS. Hence, there's no
1103 * need to disable clocks if their usecounts > 1.
1104 */
1105 WARN_ON(dss.num_clks_enabled > 0);
1106
1107 dss_put_clocks();
1108 return 0;
1109}
1110
1111static struct platform_driver omap_dsshw_driver = {
1112 .probe = omap_dsshw_probe,
1113 .remove = omap_dsshw_remove,
1114 .driver = {
1115 .name = "omapdss_dss",
1116 .owner = THIS_MODULE,
1117 },
1118};
1119
1120int dss_init_platform_driver(void)
1121{
1122 return platform_driver_register(&omap_dsshw_driver);
1123}
1124
1125void dss_uninit_platform_driver(void)
1126{
1127 return platform_driver_unregister(&omap_dsshw_driver);
1128}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index b394951120a..c2f582bb19c 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -97,8 +97,6 @@ extern unsigned int dss_debug;
97#define FLD_MOD(orig, val, start, end) \ 97#define FLD_MOD(orig, val, start, end) \
98 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) 98 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
99 99
100#define DISPC_MAX_FCK 173000000
101
102enum omap_burst_size { 100enum omap_burst_size {
103 OMAP_DSS_BURST_4x32 = 0, 101 OMAP_DSS_BURST_4x32 = 0,
104 OMAP_DSS_BURST_8x32 = 1, 102 OMAP_DSS_BURST_8x32 = 1,
@@ -112,17 +110,25 @@ enum omap_parallel_interface_mode {
112}; 110};
113 111
114enum dss_clock { 112enum dss_clock {
115 DSS_CLK_ICK = 1 << 0, 113 DSS_CLK_ICK = 1 << 0, /* DSS_L3_ICLK and DSS_L4_ICLK */
116 DSS_CLK_FCK1 = 1 << 1, 114 DSS_CLK_FCK = 1 << 1, /* DSS1_ALWON_FCLK */
117 DSS_CLK_FCK2 = 1 << 2, 115 DSS_CLK_SYSCK = 1 << 2, /* DSS2_ALWON_FCLK */
118 DSS_CLK_54M = 1 << 3, 116 DSS_CLK_TVFCK = 1 << 3, /* DSS_TV_FCLK */
119 DSS_CLK_96M = 1 << 4, 117 DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/
120}; 118};
121 119
122enum dss_clk_source { 120enum dss_clk_source {
123 DSS_SRC_DSI1_PLL_FCLK, 121 DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* OMAP3: DSI1_PLL_FCLK
124 DSS_SRC_DSI2_PLL_FCLK, 122 * OMAP4: PLL1_CLK1 */
125 DSS_SRC_DSS1_ALWON_FCLK, 123 DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* OMAP3: DSI2_PLL_FCLK
124 * OMAP4: PLL1_CLK2 */
125 DSS_CLK_SRC_FCK, /* OMAP2/3: DSS1_ALWON_FCLK
126 * OMAP4: DSS_FCLK */
127};
128
129enum dss_hdmi_venc_clk_source_select {
130 DSS_VENC_TV_CLK = 0,
131 DSS_HDMI_M_PCLK = 1,
126}; 132};
127 133
128struct dss_clock_info { 134struct dss_clock_info {
@@ -148,36 +154,42 @@ struct dsi_clock_info {
148 unsigned long fint; 154 unsigned long fint;
149 unsigned long clkin4ddr; 155 unsigned long clkin4ddr;
150 unsigned long clkin; 156 unsigned long clkin;
151 unsigned long dsi1_pll_fclk; 157 unsigned long dsi_pll_hsdiv_dispc_clk; /* OMAP3: DSI1_PLL_CLK
152 unsigned long dsi2_pll_fclk; 158 * OMAP4: PLLx_CLK1 */
153 159 unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK
160 * OMAP4: PLLx_CLK2 */
154 unsigned long lp_clk; 161 unsigned long lp_clk;
155 162
156 /* dividers */ 163 /* dividers */
157 u16 regn; 164 u16 regn;
158 u16 regm; 165 u16 regm;
159 u16 regm3; 166 u16 regm_dispc; /* OMAP3: REGM3
160 u16 regm4; 167 * OMAP4: REGM4 */
161 168 u16 regm_dsi; /* OMAP3: REGM4
169 * OMAP4: REGM5 */
162 u16 lp_clk_div; 170 u16 lp_clk_div;
163 171
164 u8 highfreq; 172 u8 highfreq;
165 bool use_dss2_fck; 173 bool use_sys_clk;
174};
175
176/* HDMI PLL structure */
177struct hdmi_pll_info {
178 u16 regn;
179 u16 regm;
180 u32 regmf;
181 u16 regm2;
182 u16 regsd;
183 u16 dcofreq;
166}; 184};
167 185
168struct seq_file; 186struct seq_file;
169struct platform_device; 187struct platform_device;
170 188
171/* core */ 189/* core */
172void dss_clk_enable(enum dss_clock clks);
173void dss_clk_disable(enum dss_clock clks);
174unsigned long dss_clk_get_rate(enum dss_clock clk);
175int dss_need_ctx_restore(void);
176void dss_dump_clocks(struct seq_file *s);
177struct bus_type *dss_get_bus(void); 190struct bus_type *dss_get_bus(void);
178struct regulator *dss_get_vdds_dsi(void); 191struct regulator *dss_get_vdds_dsi(void);
179struct regulator *dss_get_vdds_sdi(void); 192struct regulator *dss_get_vdds_sdi(void);
180struct regulator *dss_get_vdda_dac(void);
181 193
182/* display */ 194/* display */
183int dss_suspend_all_devices(void); 195int dss_suspend_all_devices(void);
@@ -214,13 +226,23 @@ void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr);
214void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); 226void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
215 227
216/* DSS */ 228/* DSS */
217int dss_init(bool skip_init); 229int dss_init_platform_driver(void);
218void dss_exit(void); 230void dss_uninit_platform_driver(void);
219 231
232void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
220void dss_save_context(void); 233void dss_save_context(void);
221void dss_restore_context(void); 234void dss_restore_context(void);
235void dss_clk_enable(enum dss_clock clks);
236void dss_clk_disable(enum dss_clock clks);
237unsigned long dss_clk_get_rate(enum dss_clock clk);
238int dss_need_ctx_restore(void);
239const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src);
240void dss_dump_clocks(struct seq_file *s);
222 241
223void dss_dump_regs(struct seq_file *s); 242void dss_dump_regs(struct seq_file *s);
243#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
244void dss_debug_dump_clocks(struct seq_file *s);
245#endif
224 246
225void dss_sdi_init(u8 datapairs); 247void dss_sdi_init(u8 datapairs);
226int dss_sdi_enable(void); 248int dss_sdi_enable(void);
@@ -228,8 +250,11 @@ void dss_sdi_disable(void);
228 250
229void dss_select_dispc_clk_source(enum dss_clk_source clk_src); 251void dss_select_dispc_clk_source(enum dss_clk_source clk_src);
230void dss_select_dsi_clk_source(enum dss_clk_source clk_src); 252void dss_select_dsi_clk_source(enum dss_clk_source clk_src);
253void dss_select_lcd_clk_source(enum omap_channel channel,
254 enum dss_clk_source clk_src);
231enum dss_clk_source dss_get_dispc_clk_source(void); 255enum dss_clk_source dss_get_dispc_clk_source(void);
232enum dss_clk_source dss_get_dsi_clk_source(void); 256enum dss_clk_source dss_get_dsi_clk_source(void);
257enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
233 258
234void dss_set_venc_output(enum omap_dss_venc_type type); 259void dss_set_venc_output(enum omap_dss_venc_type type);
235void dss_set_dac_pwrdn_bgz(bool enable); 260void dss_set_dac_pwrdn_bgz(bool enable);
@@ -244,11 +269,11 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
244 269
245/* SDI */ 270/* SDI */
246#ifdef CONFIG_OMAP2_DSS_SDI 271#ifdef CONFIG_OMAP2_DSS_SDI
247int sdi_init(bool skip_init); 272int sdi_init(void);
248void sdi_exit(void); 273void sdi_exit(void);
249int sdi_init_display(struct omap_dss_device *display); 274int sdi_init_display(struct omap_dss_device *display);
250#else 275#else
251static inline int sdi_init(bool skip_init) 276static inline int sdi_init(void)
252{ 277{
253 return 0; 278 return 0;
254} 279}
@@ -259,8 +284,8 @@ static inline void sdi_exit(void)
259 284
260/* DSI */ 285/* DSI */
261#ifdef CONFIG_OMAP2_DSS_DSI 286#ifdef CONFIG_OMAP2_DSS_DSI
262int dsi_init(struct platform_device *pdev); 287int dsi_init_platform_driver(void);
263void dsi_exit(void); 288void dsi_uninit_platform_driver(void);
264 289
265void dsi_dump_clocks(struct seq_file *s); 290void dsi_dump_clocks(struct seq_file *s);
266void dsi_dump_irqs(struct seq_file *s); 291void dsi_dump_irqs(struct seq_file *s);
@@ -271,7 +296,7 @@ void dsi_restore_context(void);
271 296
272int dsi_init_display(struct omap_dss_device *display); 297int dsi_init_display(struct omap_dss_device *display);
273void dsi_irq_handler(void); 298void dsi_irq_handler(void);
274unsigned long dsi_get_dsi1_pll_rate(void); 299unsigned long dsi_get_pll_hsdiv_dispc_rate(void);
275int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo); 300int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo);
276int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, 301int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
277 struct dsi_clock_info *cinfo, 302 struct dsi_clock_info *cinfo,
@@ -282,31 +307,36 @@ void dsi_pll_uninit(void);
282void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 307void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
283 u32 fifo_size, enum omap_burst_size *burst_size, 308 u32 fifo_size, enum omap_burst_size *burst_size,
284 u32 *fifo_low, u32 *fifo_high); 309 u32 *fifo_low, u32 *fifo_high);
285void dsi_wait_dsi1_pll_active(void); 310void dsi_wait_pll_hsdiv_dispc_active(void);
286void dsi_wait_dsi2_pll_active(void); 311void dsi_wait_pll_hsdiv_dsi_active(void);
287#else 312#else
288static inline int dsi_init(struct platform_device *pdev) 313static inline int dsi_init_platform_driver(void)
289{ 314{
290 return 0; 315 return 0;
291} 316}
292static inline void dsi_exit(void) 317static inline void dsi_uninit_platform_driver(void)
293{ 318{
294} 319}
295static inline void dsi_wait_dsi1_pll_active(void) 320static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(void)
296{ 321{
322 WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
323 return 0;
297} 324}
298static inline void dsi_wait_dsi2_pll_active(void) 325static inline void dsi_wait_pll_hsdiv_dispc_active(void)
326{
327}
328static inline void dsi_wait_pll_hsdiv_dsi_active(void)
299{ 329{
300} 330}
301#endif 331#endif
302 332
303/* DPI */ 333/* DPI */
304#ifdef CONFIG_OMAP2_DSS_DPI 334#ifdef CONFIG_OMAP2_DSS_DPI
305int dpi_init(struct platform_device *pdev); 335int dpi_init(void);
306void dpi_exit(void); 336void dpi_exit(void);
307int dpi_init_display(struct omap_dss_device *dssdev); 337int dpi_init_display(struct omap_dss_device *dssdev);
308#else 338#else
309static inline int dpi_init(struct platform_device *pdev) 339static inline int dpi_init(void)
310{ 340{
311 return 0; 341 return 0;
312} 342}
@@ -316,8 +346,8 @@ static inline void dpi_exit(void)
316#endif 346#endif
317 347
318/* DISPC */ 348/* DISPC */
319int dispc_init(void); 349int dispc_init_platform_driver(void);
320void dispc_exit(void); 350void dispc_uninit_platform_driver(void);
321void dispc_dump_clocks(struct seq_file *s); 351void dispc_dump_clocks(struct seq_file *s);
322void dispc_dump_irqs(struct seq_file *s); 352void dispc_dump_irqs(struct seq_file *s);
323void dispc_dump_regs(struct seq_file *s); 353void dispc_dump_regs(struct seq_file *s);
@@ -350,6 +380,7 @@ void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height);
350void dispc_set_channel_out(enum omap_plane plane, 380void dispc_set_channel_out(enum omap_plane plane,
351 enum omap_channel channel_out); 381 enum omap_channel channel_out);
352 382
383void dispc_enable_gamma_table(bool enable);
353int dispc_setup_plane(enum omap_plane plane, 384int dispc_setup_plane(enum omap_plane plane,
354 u32 paddr, u16 screen_width, 385 u32 paddr, u16 screen_width,
355 u16 pos_x, u16 pos_y, 386 u16 pos_x, u16 pos_y,
@@ -409,24 +440,50 @@ int dispc_get_clock_div(enum omap_channel channel,
409 440
410/* VENC */ 441/* VENC */
411#ifdef CONFIG_OMAP2_DSS_VENC 442#ifdef CONFIG_OMAP2_DSS_VENC
412int venc_init(struct platform_device *pdev); 443int venc_init_platform_driver(void);
413void venc_exit(void); 444void venc_uninit_platform_driver(void);
414void venc_dump_regs(struct seq_file *s); 445void venc_dump_regs(struct seq_file *s);
415int venc_init_display(struct omap_dss_device *display); 446int venc_init_display(struct omap_dss_device *display);
416#else 447#else
417static inline int venc_init(struct platform_device *pdev) 448static inline int venc_init_platform_driver(void)
449{
450 return 0;
451}
452static inline void venc_uninit_platform_driver(void)
453{
454}
455#endif
456
457/* HDMI */
458#ifdef CONFIG_OMAP4_DSS_HDMI
459int hdmi_init_platform_driver(void);
460void hdmi_uninit_platform_driver(void);
461int hdmi_init_display(struct omap_dss_device *dssdev);
462#else
463static inline int hdmi_init_display(struct omap_dss_device *dssdev)
464{
465 return 0;
466}
467static inline int hdmi_init_platform_driver(void)
418{ 468{
419 return 0; 469 return 0;
420} 470}
421static inline void venc_exit(void) 471static inline void hdmi_uninit_platform_driver(void)
422{ 472{
423} 473}
424#endif 474#endif
475int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
476void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
477void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
478int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
479 struct omap_video_timings *timings);
480int hdmi_panel_init(void);
481void hdmi_panel_exit(void);
425 482
426/* RFBI */ 483/* RFBI */
427#ifdef CONFIG_OMAP2_DSS_RFBI 484#ifdef CONFIG_OMAP2_DSS_RFBI
428int rfbi_init(void); 485int rfbi_init_platform_driver(void);
429void rfbi_exit(void); 486void rfbi_uninit_platform_driver(void);
430void rfbi_dump_regs(struct seq_file *s); 487void rfbi_dump_regs(struct seq_file *s);
431 488
432int rfbi_configure(int rfbi_module, int bpp, int lines); 489int rfbi_configure(int rfbi_module, int bpp, int lines);
@@ -437,11 +494,11 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
437unsigned long rfbi_get_max_tx_rate(void); 494unsigned long rfbi_get_max_tx_rate(void);
438int rfbi_init_display(struct omap_dss_device *display); 495int rfbi_init_display(struct omap_dss_device *display);
439#else 496#else
440static inline int rfbi_init(void) 497static inline int rfbi_init_platform_driver(void)
441{ 498{
442 return 0; 499 return 0;
443} 500}
444static inline void rfbi_exit(void) 501static inline void rfbi_uninit_platform_driver(void)
445{ 502{
446} 503}
447#endif 504#endif
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index cf3ef696e14..aa1622241d0 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -25,14 +25,18 @@
25#include <plat/display.h> 25#include <plat/display.h>
26#include <plat/cpu.h> 26#include <plat/cpu.h>
27 27
28#include "dss.h"
28#include "dss_features.h" 29#include "dss_features.h"
29 30
30/* Defines a generic omap register field */ 31/* Defines a generic omap register field */
31struct dss_reg_field { 32struct dss_reg_field {
32 enum dss_feat_reg_field id;
33 u8 start, end; 33 u8 start, end;
34}; 34};
35 35
36struct dss_param_range {
37 int min, max;
38};
39
36struct omap_dss_features { 40struct omap_dss_features {
37 const struct dss_reg_field *reg_fields; 41 const struct dss_reg_field *reg_fields;
38 const int num_reg_fields; 42 const int num_reg_fields;
@@ -43,29 +47,68 @@ struct omap_dss_features {
43 const int num_ovls; 47 const int num_ovls;
44 const enum omap_display_type *supported_displays; 48 const enum omap_display_type *supported_displays;
45 const enum omap_color_mode *supported_color_modes; 49 const enum omap_color_mode *supported_color_modes;
50 const char * const *clksrc_names;
51 const struct dss_param_range *dss_params;
46}; 52};
47 53
48/* This struct is assigned to one of the below during initialization */ 54/* This struct is assigned to one of the below during initialization */
49static struct omap_dss_features *omap_current_dss_features; 55static struct omap_dss_features *omap_current_dss_features;
50 56
51static const struct dss_reg_field omap2_dss_reg_fields[] = { 57static const struct dss_reg_field omap2_dss_reg_fields[] = {
52 { FEAT_REG_FIRHINC, 11, 0 }, 58 [FEAT_REG_FIRHINC] = { 11, 0 },
53 { FEAT_REG_FIRVINC, 27, 16 }, 59 [FEAT_REG_FIRVINC] = { 27, 16 },
54 { FEAT_REG_FIFOLOWTHRESHOLD, 8, 0 }, 60 [FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 },
55 { FEAT_REG_FIFOHIGHTHRESHOLD, 24, 16 }, 61 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 },
56 { FEAT_REG_FIFOSIZE, 8, 0 }, 62 [FEAT_REG_FIFOSIZE] = { 8, 0 },
63 [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
64 [FEAT_REG_VERTICALACCU] = { 25, 16 },
65 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
66 [FEAT_REG_DSIPLL_REGN] = { 0, 0 },
67 [FEAT_REG_DSIPLL_REGM] = { 0, 0 },
68 [FEAT_REG_DSIPLL_REGM_DISPC] = { 0, 0 },
69 [FEAT_REG_DSIPLL_REGM_DSI] = { 0, 0 },
57}; 70};
58 71
59static const struct dss_reg_field omap3_dss_reg_fields[] = { 72static const struct dss_reg_field omap3_dss_reg_fields[] = {
60 { FEAT_REG_FIRHINC, 12, 0 }, 73 [FEAT_REG_FIRHINC] = { 12, 0 },
61 { FEAT_REG_FIRVINC, 28, 16 }, 74 [FEAT_REG_FIRVINC] = { 28, 16 },
62 { FEAT_REG_FIFOLOWTHRESHOLD, 11, 0 }, 75 [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
63 { FEAT_REG_FIFOHIGHTHRESHOLD, 27, 16 }, 76 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
64 { FEAT_REG_FIFOSIZE, 10, 0 }, 77 [FEAT_REG_FIFOSIZE] = { 10, 0 },
78 [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
79 [FEAT_REG_VERTICALACCU] = { 25, 16 },
80 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
81 [FEAT_REG_DSIPLL_REGN] = { 7, 1 },
82 [FEAT_REG_DSIPLL_REGM] = { 18, 8 },
83 [FEAT_REG_DSIPLL_REGM_DISPC] = { 22, 19 },
84 [FEAT_REG_DSIPLL_REGM_DSI] = { 26, 23 },
85};
86
87static const struct dss_reg_field omap4_dss_reg_fields[] = {
88 [FEAT_REG_FIRHINC] = { 12, 0 },
89 [FEAT_REG_FIRVINC] = { 28, 16 },
90 [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
91 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
92 [FEAT_REG_FIFOSIZE] = { 15, 0 },
93 [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
94 [FEAT_REG_VERTICALACCU] = { 26, 16 },
95 [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
96 [FEAT_REG_DSIPLL_REGN] = { 8, 1 },
97 [FEAT_REG_DSIPLL_REGM] = { 20, 9 },
98 [FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 },
99 [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
65}; 100};
66 101
67static const enum omap_display_type omap2_dss_supported_displays[] = { 102static const enum omap_display_type omap2_dss_supported_displays[] = {
68 /* OMAP_DSS_CHANNEL_LCD */ 103 /* OMAP_DSS_CHANNEL_LCD */
104 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
105
106 /* OMAP_DSS_CHANNEL_DIGIT */
107 OMAP_DISPLAY_TYPE_VENC,
108};
109
110static const enum omap_display_type omap3430_dss_supported_displays[] = {
111 /* OMAP_DSS_CHANNEL_LCD */
69 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 112 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
70 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI, 113 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI,
71 114
@@ -73,10 +116,10 @@ static const enum omap_display_type omap2_dss_supported_displays[] = {
73 OMAP_DISPLAY_TYPE_VENC, 116 OMAP_DISPLAY_TYPE_VENC,
74}; 117};
75 118
76static const enum omap_display_type omap3_dss_supported_displays[] = { 119static const enum omap_display_type omap3630_dss_supported_displays[] = {
77 /* OMAP_DSS_CHANNEL_LCD */ 120 /* OMAP_DSS_CHANNEL_LCD */
78 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 121 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
79 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI, 122 OMAP_DISPLAY_TYPE_DSI,
80 123
81 /* OMAP_DSS_CHANNEL_DIGIT */ 124 /* OMAP_DSS_CHANNEL_DIGIT */
82 OMAP_DISPLAY_TYPE_VENC, 125 OMAP_DISPLAY_TYPE_VENC,
@@ -87,7 +130,7 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
87 OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI, 130 OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI,
88 131
89 /* OMAP_DSS_CHANNEL_DIGIT */ 132 /* OMAP_DSS_CHANNEL_DIGIT */
90 OMAP_DISPLAY_TYPE_VENC, 133 OMAP_DISPLAY_TYPE_VENC | OMAP_DISPLAY_TYPE_HDMI,
91 134
92 /* OMAP_DSS_CHANNEL_LCD2 */ 135 /* OMAP_DSS_CHANNEL_LCD2 */
93 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | 136 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
@@ -134,6 +177,54 @@ static const enum omap_color_mode omap3_dss_supported_color_modes[] = {
134 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32, 177 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
135}; 178};
136 179
180static const char * const omap2_dss_clk_source_names[] = {
181 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A",
182 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A",
183 [DSS_CLK_SRC_FCK] = "DSS_FCLK1",
184};
185
186static const char * const omap3_dss_clk_source_names[] = {
187 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK",
188 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK",
189 [DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK",
190};
191
192static const char * const omap4_dss_clk_source_names[] = {
193 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1",
194 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2",
195 [DSS_CLK_SRC_FCK] = "DSS_FCLK",
196};
197
198static const struct dss_param_range omap2_dss_param_range[] = {
199 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
200 [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
201 [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
202 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 },
203 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 },
204 [FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
205 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
206};
207
208static const struct dss_param_range omap3_dss_param_range[] = {
209 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
210 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
211 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
212 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 },
213 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
214 [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
215 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
216};
217
218static const struct dss_param_range omap4_dss_param_range[] = {
219 [FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
220 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
221 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
222 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
223 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
224 [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
225 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
226};
227
137/* OMAP2 DSS Features */ 228/* OMAP2 DSS Features */
138static struct omap_dss_features omap2_dss_features = { 229static struct omap_dss_features omap2_dss_features = {
139 .reg_fields = omap2_dss_reg_fields, 230 .reg_fields = omap2_dss_reg_fields,
@@ -141,12 +232,15 @@ static struct omap_dss_features omap2_dss_features = {
141 232
142 .has_feature = 233 .has_feature =
143 FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL | 234 FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL |
144 FEAT_PCKFREEENABLE | FEAT_FUNCGATED, 235 FEAT_PCKFREEENABLE | FEAT_FUNCGATED |
236 FEAT_ROWREPEATENABLE | FEAT_RESIZECONF,
145 237
146 .num_mgrs = 2, 238 .num_mgrs = 2,
147 .num_ovls = 3, 239 .num_ovls = 3,
148 .supported_displays = omap2_dss_supported_displays, 240 .supported_displays = omap2_dss_supported_displays,
149 .supported_color_modes = omap2_dss_supported_color_modes, 241 .supported_color_modes = omap2_dss_supported_color_modes,
242 .clksrc_names = omap2_dss_clk_source_names,
243 .dss_params = omap2_dss_param_range,
150}; 244};
151 245
152/* OMAP3 DSS Features */ 246/* OMAP3 DSS Features */
@@ -157,12 +251,15 @@ static struct omap_dss_features omap3430_dss_features = {
157 .has_feature = 251 .has_feature =
158 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | 252 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
159 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 253 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
160 FEAT_FUNCGATED, 254 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
255 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF,
161 256
162 .num_mgrs = 2, 257 .num_mgrs = 2,
163 .num_ovls = 3, 258 .num_ovls = 3,
164 .supported_displays = omap3_dss_supported_displays, 259 .supported_displays = omap3430_dss_supported_displays,
165 .supported_color_modes = omap3_dss_supported_color_modes, 260 .supported_color_modes = omap3_dss_supported_color_modes,
261 .clksrc_names = omap3_dss_clk_source_names,
262 .dss_params = omap3_dss_param_range,
166}; 263};
167 264
168static struct omap_dss_features omap3630_dss_features = { 265static struct omap_dss_features omap3630_dss_features = {
@@ -172,27 +269,34 @@ static struct omap_dss_features omap3630_dss_features = {
172 .has_feature = 269 .has_feature =
173 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | 270 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
174 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 271 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
175 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED, 272 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
273 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
274 FEAT_RESIZECONF,
176 275
177 .num_mgrs = 2, 276 .num_mgrs = 2,
178 .num_ovls = 3, 277 .num_ovls = 3,
179 .supported_displays = omap3_dss_supported_displays, 278 .supported_displays = omap3630_dss_supported_displays,
180 .supported_color_modes = omap3_dss_supported_color_modes, 279 .supported_color_modes = omap3_dss_supported_color_modes,
280 .clksrc_names = omap3_dss_clk_source_names,
281 .dss_params = omap3_dss_param_range,
181}; 282};
182 283
183/* OMAP4 DSS Features */ 284/* OMAP4 DSS Features */
184static struct omap_dss_features omap4_dss_features = { 285static struct omap_dss_features omap4_dss_features = {
185 .reg_fields = omap3_dss_reg_fields, 286 .reg_fields = omap4_dss_reg_fields,
186 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 287 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
187 288
188 .has_feature = 289 .has_feature =
189 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA | 290 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
190 FEAT_MGR_LCD2, 291 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
292 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC,
191 293
192 .num_mgrs = 3, 294 .num_mgrs = 3,
193 .num_ovls = 3, 295 .num_ovls = 3,
194 .supported_displays = omap4_dss_supported_displays, 296 .supported_displays = omap4_dss_supported_displays,
195 .supported_color_modes = omap3_dss_supported_color_modes, 297 .supported_color_modes = omap3_dss_supported_color_modes,
298 .clksrc_names = omap4_dss_clk_source_names,
299 .dss_params = omap4_dss_param_range,
196}; 300};
197 301
198/* Functions returning values related to a DSS feature */ 302/* Functions returning values related to a DSS feature */
@@ -206,6 +310,16 @@ int dss_feat_get_num_ovls(void)
206 return omap_current_dss_features->num_ovls; 310 return omap_current_dss_features->num_ovls;
207} 311}
208 312
313unsigned long dss_feat_get_param_min(enum dss_range_param param)
314{
315 return omap_current_dss_features->dss_params[param].min;
316}
317
318unsigned long dss_feat_get_param_max(enum dss_range_param param)
319{
320 return omap_current_dss_features->dss_params[param].max;
321}
322
209enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel) 323enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel)
210{ 324{
211 return omap_current_dss_features->supported_displays[channel]; 325 return omap_current_dss_features->supported_displays[channel];
@@ -223,6 +337,11 @@ bool dss_feat_color_mode_supported(enum omap_plane plane,
223 color_mode; 337 color_mode;
224} 338}
225 339
340const char *dss_feat_get_clk_source_name(enum dss_clk_source id)
341{
342 return omap_current_dss_features->clksrc_names[id];
343}
344
226/* DSS has_feature check */ 345/* DSS has_feature check */
227bool dss_has_feature(enum dss_feat_id id) 346bool dss_has_feature(enum dss_feat_id id)
228{ 347{
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index b9c70be9258..12e9c4ef0de 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -22,6 +22,7 @@
22 22
23#define MAX_DSS_MANAGERS 3 23#define MAX_DSS_MANAGERS 3
24#define MAX_DSS_OVERLAYS 3 24#define MAX_DSS_OVERLAYS 3
25#define MAX_DSS_LCD_MANAGERS 2
25 26
26/* DSS has feature id */ 27/* DSS has feature id */
27enum dss_feat_id { 28enum dss_feat_id {
@@ -33,6 +34,12 @@ enum dss_feat_id {
33 FEAT_PCKFREEENABLE = 1 << 5, 34 FEAT_PCKFREEENABLE = 1 << 5,
34 FEAT_FUNCGATED = 1 << 6, 35 FEAT_FUNCGATED = 1 << 6,
35 FEAT_MGR_LCD2 = 1 << 7, 36 FEAT_MGR_LCD2 = 1 << 7,
37 FEAT_LINEBUFFERSPLIT = 1 << 8,
38 FEAT_ROWREPEATENABLE = 1 << 9,
39 FEAT_RESIZECONF = 1 << 10,
40 /* Independent core clk divider */
41 FEAT_CORE_CLK_DIV = 1 << 11,
42 FEAT_LCD_CLK_SRC = 1 << 12,
36}; 43};
37 44
38/* DSS register field id */ 45/* DSS register field id */
@@ -42,15 +49,35 @@ enum dss_feat_reg_field {
42 FEAT_REG_FIFOHIGHTHRESHOLD, 49 FEAT_REG_FIFOHIGHTHRESHOLD,
43 FEAT_REG_FIFOLOWTHRESHOLD, 50 FEAT_REG_FIFOLOWTHRESHOLD,
44 FEAT_REG_FIFOSIZE, 51 FEAT_REG_FIFOSIZE,
52 FEAT_REG_HORIZONTALACCU,
53 FEAT_REG_VERTICALACCU,
54 FEAT_REG_DISPC_CLK_SWITCH,
55 FEAT_REG_DSIPLL_REGN,
56 FEAT_REG_DSIPLL_REGM,
57 FEAT_REG_DSIPLL_REGM_DISPC,
58 FEAT_REG_DSIPLL_REGM_DSI,
59};
60
61enum dss_range_param {
62 FEAT_PARAM_DSS_FCK,
63 FEAT_PARAM_DSIPLL_REGN,
64 FEAT_PARAM_DSIPLL_REGM,
65 FEAT_PARAM_DSIPLL_REGM_DISPC,
66 FEAT_PARAM_DSIPLL_REGM_DSI,
67 FEAT_PARAM_DSIPLL_FINT,
68 FEAT_PARAM_DSIPLL_LPDIV,
45}; 69};
46 70
47/* DSS Feature Functions */ 71/* DSS Feature Functions */
48int dss_feat_get_num_mgrs(void); 72int dss_feat_get_num_mgrs(void);
49int dss_feat_get_num_ovls(void); 73int dss_feat_get_num_ovls(void);
74unsigned long dss_feat_get_param_min(enum dss_range_param param);
75unsigned long dss_feat_get_param_max(enum dss_range_param param);
50enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); 76enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
51enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); 77enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
52bool dss_feat_color_mode_supported(enum omap_plane plane, 78bool dss_feat_color_mode_supported(enum omap_plane plane,
53 enum omap_color_mode color_mode); 79 enum omap_color_mode color_mode);
80const char *dss_feat_get_clk_source_name(enum dss_clk_source id);
54 81
55bool dss_has_feature(enum dss_feat_id id); 82bool dss_has_feature(enum dss_feat_id id);
56void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); 83void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
new file mode 100644
index 00000000000..0d44f070ef3
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -0,0 +1,1332 @@
1/*
2 * hdmi.c
3 *
4 * HDMI interface DSS driver setting for TI's OMAP4 family of processor.
5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
6 * Authors: Yong Zhi
7 * Mythri pk <mythripk@ti.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 version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#define DSS_SUBSYS_NAME "HDMI"
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/err.h>
27#include <linux/io.h>
28#include <linux/interrupt.h>
29#include <linux/mutex.h>
30#include <linux/delay.h>
31#include <linux/string.h>
32#include <plat/display.h>
33
34#include "dss.h"
35#include "hdmi.h"
36
37static struct {
38 struct mutex lock;
39 struct omap_display_platform_data *pdata;
40 struct platform_device *pdev;
41 void __iomem *base_wp; /* HDMI wrapper */
42 int code;
43 int mode;
44 u8 edid[HDMI_EDID_MAX_LENGTH];
45 u8 edid_set;
46 bool custom_set;
47 struct hdmi_config cfg;
48} hdmi;
49
50/*
51 * Logic for the below structure :
52 * user enters the CEA or VESA timings by specifying the HDMI/DVI code.
53 * There is a correspondence between CEA/VESA timing and code, please
54 * refer to section 6.3 in HDMI 1.3 specification for timing code.
55 *
56 * In the below structure, cea_vesa_timings corresponds to all OMAP4
57 * supported CEA and VESA timing values.code_cea corresponds to the CEA
58 * code, It is used to get the timing from cea_vesa_timing array.Similarly
59 * with code_vesa. Code_index is used for back mapping, that is once EDID
60 * is read from the TV, EDID is parsed to find the timing values and then
61 * map it to corresponding CEA or VESA index.
62 */
63
64static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = {
65 { {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0},
66 { {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1},
67 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1},
68 { {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0},
69 { {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0},
70 { {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0},
71 { {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0},
72 { {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1},
73 { {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1},
74 { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1},
75 { {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0},
76 { {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0},
77 { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1},
78 { {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0},
79 { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1},
80 /* VESA From Here */
81 { {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0},
82 { {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1},
83 { {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1},
84 { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0},
85 { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0},
86 { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18}, 1, 1},
87 { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1},
88 { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1},
89 { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0},
90 { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0},
91 { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0},
92 { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0},
93 { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1},
94 { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1},
95 { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1},
96 { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1},
97 { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1},
98 { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1},
99 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}
100};
101
102/*
103 * This is a static mapping array which maps the timing values
104 * with corresponding CEA / VESA code
105 */
106static const int code_index[OMAP_HDMI_TIMINGS_NB] = {
107 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32,
108 /* <--15 CEA 17--> vesa*/
109 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A,
110 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B
111};
112
113/*
114 * This is reverse static mapping which maps the CEA / VESA code
115 * to the corresponding timing values
116 */
117static const int code_cea[39] = {
118 -1, 0, 3, 3, 2, 8, 5, 5, -1, -1,
119 -1, -1, -1, -1, -1, -1, 9, 10, 10, 1,
120 7, 6, 6, -1, -1, -1, -1, -1, -1, 11,
121 11, 12, 14, -1, -1, 13, 13, 4, 4
122};
123
124static const int code_vesa[85] = {
125 -1, -1, -1, -1, 15, -1, -1, -1, -1, 16,
126 -1, -1, -1, -1, 17, -1, 23, -1, -1, -1,
127 -1, -1, 29, 18, -1, -1, -1, 32, 19, -1,
128 -1, -1, 21, -1, -1, 22, -1, -1, -1, 20,
129 -1, 30, 24, -1, -1, -1, -1, 25, -1, -1,
130 -1, -1, -1, -1, -1, -1, -1, 31, 26, -1,
131 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
132 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
133 -1, 27, 28, -1, 33};
134
135static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
136
137static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val)
138{
139 __raw_writel(val, hdmi.base_wp + idx.idx);
140}
141
142static inline u32 hdmi_read_reg(const struct hdmi_reg idx)
143{
144 return __raw_readl(hdmi.base_wp + idx.idx);
145}
146
147static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
148 int b2, int b1, u32 val)
149{
150 u32 t = 0;
151 while (val != REG_GET(idx, b2, b1)) {
152 udelay(1);
153 if (t++ > 10000)
154 return !val;
155 }
156 return val;
157}
158
159int hdmi_init_display(struct omap_dss_device *dssdev)
160{
161 DSSDBG("init_display\n");
162
163 return 0;
164}
165
166static int hdmi_pll_init(enum hdmi_clk_refsel refsel, int dcofreq,
167 struct hdmi_pll_info *fmt, u16 sd)
168{
169 u32 r;
170
171 /* PLL start always use manual mode */
172 REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
173
174 r = hdmi_read_reg(PLLCTRL_CFG1);
175 r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
176 r = FLD_MOD(r, fmt->regn, 8, 1); /* CFG1_PLL_REGN */
177
178 hdmi_write_reg(PLLCTRL_CFG1, r);
179
180 r = hdmi_read_reg(PLLCTRL_CFG2);
181
182 r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
183 r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
184 r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
185
186 if (dcofreq) {
187 /* divider programming for frequency beyond 1000Mhz */
188 REG_FLD_MOD(PLLCTRL_CFG3, sd, 17, 10);
189 r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
190 } else {
191 r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
192 }
193
194 hdmi_write_reg(PLLCTRL_CFG2, r);
195
196 r = hdmi_read_reg(PLLCTRL_CFG4);
197 r = FLD_MOD(r, fmt->regm2, 24, 18);
198 r = FLD_MOD(r, fmt->regmf, 17, 0);
199
200 hdmi_write_reg(PLLCTRL_CFG4, r);
201
202 /* go now */
203 REG_FLD_MOD(PLLCTRL_PLL_GO, 0x1, 0, 0);
204
205 /* wait for bit change */
206 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_GO, 0, 0, 1) != 1) {
207 DSSERR("PLL GO bit not set\n");
208 return -ETIMEDOUT;
209 }
210
211 /* Wait till the lock bit is set in PLL status */
212 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
213 DSSWARN("cannot lock PLL\n");
214 DSSWARN("CFG1 0x%x\n",
215 hdmi_read_reg(PLLCTRL_CFG1));
216 DSSWARN("CFG2 0x%x\n",
217 hdmi_read_reg(PLLCTRL_CFG2));
218 DSSWARN("CFG4 0x%x\n",
219 hdmi_read_reg(PLLCTRL_CFG4));
220 return -ETIMEDOUT;
221 }
222
223 DSSDBG("PLL locked!\n");
224
225 return 0;
226}
227
228/* PHY_PWR_CMD */
229static int hdmi_set_phy_pwr(enum hdmi_phy_pwr val)
230{
231 /* Command for power control of HDMI PHY */
232 REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 7, 6);
233
234 /* Status of the power control of HDMI PHY */
235 if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
236 DSSERR("Failed to set PHY power mode to %d\n", val);
237 return -ETIMEDOUT;
238 }
239
240 return 0;
241}
242
243/* PLL_PWR_CMD */
244static int hdmi_set_pll_pwr(enum hdmi_pll_pwr val)
245{
246 /* Command for power control of HDMI PLL */
247 REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 3, 2);
248
249 /* wait till PHY_PWR_STATUS is set */
250 if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 1, 0, val) != val) {
251 DSSERR("Failed to set PHY_PWR_STATUS\n");
252 return -ETIMEDOUT;
253 }
254
255 return 0;
256}
257
258static int hdmi_pll_reset(void)
259{
260 /* SYSRESET controlled by power FSM */
261 REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
262
263 /* READ 0x0 reset is in progress */
264 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
265 DSSERR("Failed to sysreset PLL\n");
266 return -ETIMEDOUT;
267 }
268
269 return 0;
270}
271
272static int hdmi_phy_init(void)
273{
274 u16 r = 0;
275
276 r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_LDOON);
277 if (r)
278 return r;
279
280 r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_TXON);
281 if (r)
282 return r;
283
284 /*
285 * Read address 0 in order to get the SCP reset done completed
286 * Dummy access performed to make sure reset is done
287 */
288 hdmi_read_reg(HDMI_TXPHY_TX_CTRL);
289
290 /*
291 * Write to phy address 0 to configure the clock
292 * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
293 */
294 REG_FLD_MOD(HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
295
296 /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
297 hdmi_write_reg(HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
298
299 /* Setup max LDO voltage */
300 REG_FLD_MOD(HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
301
302 /* Write to phy address 3 to change the polarity control */
303 REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
304
305 return 0;
306}
307
308static int hdmi_wait_softreset(void)
309{
310 /* reset W1 */
311 REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0);
312
313 /* wait till SOFTRESET == 0 */
314 if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) {
315 DSSERR("sysconfig reset failed\n");
316 return -ETIMEDOUT;
317 }
318
319 return 0;
320}
321
322static int hdmi_pll_program(struct hdmi_pll_info *fmt)
323{
324 u16 r = 0;
325 enum hdmi_clk_refsel refsel;
326
327 /* wait for wrapper reset */
328 r = hdmi_wait_softreset();
329 if (r)
330 return r;
331
332 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
333 if (r)
334 return r;
335
336 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
337 if (r)
338 return r;
339
340 r = hdmi_pll_reset();
341 if (r)
342 return r;
343
344 refsel = HDMI_REFSEL_SYSCLK;
345
346 r = hdmi_pll_init(refsel, fmt->dcofreq, fmt, fmt->regsd);
347 if (r)
348 return r;
349
350 return 0;
351}
352
353static void hdmi_phy_off(void)
354{
355 hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF);
356}
357
358static int hdmi_core_ddc_edid(u8 *pedid, int ext)
359{
360 u32 i, j;
361 char checksum = 0;
362 u32 offset = 0;
363
364 /* Turn on CLK for DDC */
365 REG_FLD_MOD(HDMI_CORE_AV_DPD, 0x7, 2, 0);
366
367 /*
368 * SW HACK : Without the Delay DDC(i2c bus) reads 0 values /
369 * right shifted values( The behavior is not consistent and seen only
370 * with some TV's)
371 */
372 usleep_range(800, 1000);
373
374 if (!ext) {
375 /* Clk SCL Devices */
376 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0xA, 3, 0);
377
378 /* HDMI_CORE_DDC_STATUS_IN_PROG */
379 if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
380 4, 4, 0) != 0) {
381 DSSERR("Failed to program DDC\n");
382 return -ETIMEDOUT;
383 }
384
385 /* Clear FIFO */
386 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x9, 3, 0);
387
388 /* HDMI_CORE_DDC_STATUS_IN_PROG */
389 if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
390 4, 4, 0) != 0) {
391 DSSERR("Failed to program DDC\n");
392 return -ETIMEDOUT;
393 }
394
395 } else {
396 if (ext % 2 != 0)
397 offset = 0x80;
398 }
399
400 /* Load Segment Address Register */
401 REG_FLD_MOD(HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
402
403 /* Load Slave Address Register */
404 REG_FLD_MOD(HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
405
406 /* Load Offset Address Register */
407 REG_FLD_MOD(HDMI_CORE_DDC_OFFSET, offset, 7, 0);
408
409 /* Load Byte Count */
410 REG_FLD_MOD(HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
411 REG_FLD_MOD(HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
412
413 /* Set DDC_CMD */
414 if (ext)
415 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x4, 3, 0);
416 else
417 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x2, 3, 0);
418
419 /* HDMI_CORE_DDC_STATUS_BUS_LOW */
420 if (REG_GET(HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
421 DSSWARN("I2C Bus Low?\n");
422 return -EIO;
423 }
424 /* HDMI_CORE_DDC_STATUS_NO_ACK */
425 if (REG_GET(HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
426 DSSWARN("I2C No Ack\n");
427 return -EIO;
428 }
429
430 i = ext * 128;
431 j = 0;
432 while (((REG_GET(HDMI_CORE_DDC_STATUS, 4, 4) == 1) ||
433 (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0)) &&
434 j < 128) {
435
436 if (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0) {
437 /* FIFO not empty */
438 pedid[i++] = REG_GET(HDMI_CORE_DDC_DATA, 7, 0);
439 j++;
440 }
441 }
442
443 for (j = 0; j < 128; j++)
444 checksum += pedid[j];
445
446 if (checksum != 0) {
447 DSSERR("E-EDID checksum failed!!\n");
448 return -EIO;
449 }
450
451 return 0;
452}
453
454static int read_edid(u8 *pedid, u16 max_length)
455{
456 int r = 0, n = 0, i = 0;
457 int max_ext_blocks = (max_length / 128) - 1;
458
459 r = hdmi_core_ddc_edid(pedid, 0);
460 if (r) {
461 return r;
462 } else {
463 n = pedid[0x7e];
464
465 /*
466 * README: need to comply with max_length set by the caller.
467 * Better implementation should be to allocate necessary
468 * memory to store EDID according to nb_block field found
469 * in first block
470 */
471 if (n > max_ext_blocks)
472 n = max_ext_blocks;
473
474 for (i = 1; i <= n; i++) {
475 r = hdmi_core_ddc_edid(pedid, i);
476 if (r)
477 return r;
478 }
479 }
480 return 0;
481}
482
483static int get_timings_index(void)
484{
485 int code;
486
487 if (hdmi.mode == 0)
488 code = code_vesa[hdmi.code];
489 else
490 code = code_cea[hdmi.code];
491
492 if (code == -1) {
493 /* HDMI code 4 corresponds to 640 * 480 VGA */
494 hdmi.code = 4;
495 /* DVI mode 1 corresponds to HDMI 0 to DVI */
496 hdmi.mode = HDMI_DVI;
497
498 code = code_vesa[hdmi.code];
499 }
500 return code;
501}
502
503static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
504{
505 int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0;
506 int timing_vsync = 0, timing_hsync = 0;
507 struct omap_video_timings temp;
508 struct hdmi_cm cm = {-1};
509 DSSDBG("hdmi_get_code\n");
510
511 for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) {
512 temp = cea_vesa_timings[i].timings;
513 if ((temp.pixel_clock == timing->pixel_clock) &&
514 (temp.x_res == timing->x_res) &&
515 (temp.y_res == timing->y_res)) {
516
517 temp_hsync = temp.hfp + temp.hsw + temp.hbp;
518 timing_hsync = timing->hfp + timing->hsw + timing->hbp;
519 temp_vsync = temp.vfp + temp.vsw + temp.vbp;
520 timing_vsync = timing->vfp + timing->vsw + timing->vbp;
521
522 DSSDBG("temp_hsync = %d , temp_vsync = %d"
523 "timing_hsync = %d, timing_vsync = %d\n",
524 temp_hsync, temp_hsync,
525 timing_hsync, timing_vsync);
526
527 if ((temp_hsync == timing_hsync) &&
528 (temp_vsync == timing_vsync)) {
529 code = i;
530 cm.code = code_index[i];
531 if (code < 14)
532 cm.mode = HDMI_HDMI;
533 else
534 cm.mode = HDMI_DVI;
535 DSSDBG("Hdmi_code = %d mode = %d\n",
536 cm.code, cm.mode);
537 break;
538 }
539 }
540 }
541
542 return cm;
543}
544
545static void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid ,
546 struct omap_video_timings *timings)
547{
548 /* X and Y resolution */
549 timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) |
550 edid[current_descriptor_addrs + 2]);
551 timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) |
552 edid[current_descriptor_addrs + 5]);
553
554 timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) |
555 edid[current_descriptor_addrs]);
556
557 timings->pixel_clock = 10 * timings->pixel_clock;
558
559 /* HORIZONTAL FRONT PORCH */
560 timings->hfp = edid[current_descriptor_addrs + 8] |
561 ((edid[current_descriptor_addrs + 11] & 0xc0) << 2);
562 /* HORIZONTAL SYNC WIDTH */
563 timings->hsw = edid[current_descriptor_addrs + 9] |
564 ((edid[current_descriptor_addrs + 11] & 0x30) << 4);
565 /* HORIZONTAL BACK PORCH */
566 timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) |
567 edid[current_descriptor_addrs + 3]) -
568 (timings->hfp + timings->hsw);
569 /* VERTICAL FRONT PORCH */
570 timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) |
571 ((edid[current_descriptor_addrs + 11] & 0x0f) << 2);
572 /* VERTICAL SYNC WIDTH */
573 timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) |
574 ((edid[current_descriptor_addrs + 11] & 0x03) << 4);
575 /* VERTICAL BACK PORCH */
576 timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) |
577 edid[current_descriptor_addrs + 6]) -
578 (timings->vfp + timings->vsw);
579
580}
581
582/* Description : This function gets the resolution information from EDID */
583static void get_edid_timing_data(u8 *edid)
584{
585 u8 count;
586 u16 current_descriptor_addrs;
587 struct hdmi_cm cm;
588 struct omap_video_timings edid_timings;
589
590 /* seach block 0, there are 4 DTDs arranged in priority order */
591 for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) {
592 current_descriptor_addrs =
593 EDID_DESCRIPTOR_BLOCK0_ADDRESS +
594 count * EDID_TIMING_DESCRIPTOR_SIZE;
595 get_horz_vert_timing_info(current_descriptor_addrs,
596 edid, &edid_timings);
597 cm = hdmi_get_code(&edid_timings);
598 DSSDBG("Block0[%d] value matches code = %d , mode = %d\n",
599 count, cm.code, cm.mode);
600 if (cm.code == -1) {
601 continue;
602 } else {
603 hdmi.code = cm.code;
604 hdmi.mode = cm.mode;
605 DSSDBG("code = %d , mode = %d\n",
606 hdmi.code, hdmi.mode);
607 return;
608 }
609 }
610 if (edid[0x7e] != 0x00) {
611 for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR;
612 count++) {
613 current_descriptor_addrs =
614 EDID_DESCRIPTOR_BLOCK1_ADDRESS +
615 count * EDID_TIMING_DESCRIPTOR_SIZE;
616 get_horz_vert_timing_info(current_descriptor_addrs,
617 edid, &edid_timings);
618 cm = hdmi_get_code(&edid_timings);
619 DSSDBG("Block1[%d] value matches code = %d, mode = %d",
620 count, cm.code, cm.mode);
621 if (cm.code == -1) {
622 continue;
623 } else {
624 hdmi.code = cm.code;
625 hdmi.mode = cm.mode;
626 DSSDBG("code = %d , mode = %d\n",
627 hdmi.code, hdmi.mode);
628 return;
629 }
630 }
631 }
632
633 DSSINFO("no valid timing found , falling back to VGA\n");
634 hdmi.code = 4; /* setting default value of 640 480 VGA */
635 hdmi.mode = HDMI_DVI;
636}
637
638static void hdmi_read_edid(struct omap_video_timings *dp)
639{
640 int ret = 0, code;
641
642 memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH);
643
644 if (!hdmi.edid_set)
645 ret = read_edid(hdmi.edid, HDMI_EDID_MAX_LENGTH);
646
647 if (!ret) {
648 if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) {
649 /* search for timings of default resolution */
650 get_edid_timing_data(hdmi.edid);
651 hdmi.edid_set = true;
652 }
653 } else {
654 DSSWARN("failed to read E-EDID\n");
655 }
656
657 if (!hdmi.edid_set) {
658 DSSINFO("fallback to VGA\n");
659 hdmi.code = 4; /* setting default value of 640 480 VGA */
660 hdmi.mode = HDMI_DVI;
661 }
662
663 code = get_timings_index();
664
665 *dp = cea_vesa_timings[code].timings;
666}
667
668static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
669 struct hdmi_core_infoframe_avi *avi_cfg,
670 struct hdmi_core_packet_enable_repeat *repeat_cfg)
671{
672 DSSDBG("Enter hdmi_core_init\n");
673
674 /* video core */
675 video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
676 video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
677 video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
678 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
679 video_cfg->hdmi_dvi = HDMI_DVI;
680 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
681
682 /* info frame */
683 avi_cfg->db1_format = 0;
684 avi_cfg->db1_active_info = 0;
685 avi_cfg->db1_bar_info_dv = 0;
686 avi_cfg->db1_scan_info = 0;
687 avi_cfg->db2_colorimetry = 0;
688 avi_cfg->db2_aspect_ratio = 0;
689 avi_cfg->db2_active_fmt_ar = 0;
690 avi_cfg->db3_itc = 0;
691 avi_cfg->db3_ec = 0;
692 avi_cfg->db3_q_range = 0;
693 avi_cfg->db3_nup_scaling = 0;
694 avi_cfg->db4_videocode = 0;
695 avi_cfg->db5_pixel_repeat = 0;
696 avi_cfg->db6_7_line_eoftop = 0 ;
697 avi_cfg->db8_9_line_sofbottom = 0;
698 avi_cfg->db10_11_pixel_eofleft = 0;
699 avi_cfg->db12_13_pixel_sofright = 0;
700
701 /* packet enable and repeat */
702 repeat_cfg->audio_pkt = 0;
703 repeat_cfg->audio_pkt_repeat = 0;
704 repeat_cfg->avi_infoframe = 0;
705 repeat_cfg->avi_infoframe_repeat = 0;
706 repeat_cfg->gen_cntrl_pkt = 0;
707 repeat_cfg->gen_cntrl_pkt_repeat = 0;
708 repeat_cfg->generic_pkt = 0;
709 repeat_cfg->generic_pkt_repeat = 0;
710}
711
712static void hdmi_core_powerdown_disable(void)
713{
714 DSSDBG("Enter hdmi_core_powerdown_disable\n");
715 REG_FLD_MOD(HDMI_CORE_CTRL1, 0x0, 0, 0);
716}
717
718static void hdmi_core_swreset_release(void)
719{
720 DSSDBG("Enter hdmi_core_swreset_release\n");
721 REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x0, 0, 0);
722}
723
724static void hdmi_core_swreset_assert(void)
725{
726 DSSDBG("Enter hdmi_core_swreset_assert\n");
727 REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x1, 0, 0);
728}
729
730/* DSS_HDMI_CORE_VIDEO_CONFIG */
731static void hdmi_core_video_config(struct hdmi_core_video_config *cfg)
732{
733 u32 r = 0;
734
735 /* sys_ctrl1 default configuration not tunable */
736 r = hdmi_read_reg(HDMI_CORE_CTRL1);
737 r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
738 r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
739 r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
740 r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
741 hdmi_write_reg(HDMI_CORE_CTRL1, r);
742
743 REG_FLD_MOD(HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
744
745 /* Vid_Mode */
746 r = hdmi_read_reg(HDMI_CORE_SYS_VID_MODE);
747
748 /* dither truncation configuration */
749 if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
750 r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
751 r = FLD_MOD(r, 1, 5, 5);
752 } else {
753 r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
754 r = FLD_MOD(r, 0, 5, 5);
755 }
756 hdmi_write_reg(HDMI_CORE_SYS_VID_MODE, r);
757
758 /* HDMI_Ctrl */
759 r = hdmi_read_reg(HDMI_CORE_AV_HDMI_CTRL);
760 r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
761 r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
762 r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
763 hdmi_write_reg(HDMI_CORE_AV_HDMI_CTRL, r);
764
765 /* TMDS_CTRL */
766 REG_FLD_MOD(HDMI_CORE_SYS_TMDS_CTRL,
767 cfg->tclk_sel_clkmult, 6, 5);
768}
769
770static void hdmi_core_aux_infoframe_avi_config(
771 struct hdmi_core_infoframe_avi info_avi)
772{
773 u32 val;
774 char sum = 0, checksum = 0;
775
776 sum += 0x82 + 0x002 + 0x00D;
777 hdmi_write_reg(HDMI_CORE_AV_AVI_TYPE, 0x082);
778 hdmi_write_reg(HDMI_CORE_AV_AVI_VERS, 0x002);
779 hdmi_write_reg(HDMI_CORE_AV_AVI_LEN, 0x00D);
780
781 val = (info_avi.db1_format << 5) |
782 (info_avi.db1_active_info << 4) |
783 (info_avi.db1_bar_info_dv << 2) |
784 (info_avi.db1_scan_info);
785 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(0), val);
786 sum += val;
787
788 val = (info_avi.db2_colorimetry << 6) |
789 (info_avi.db2_aspect_ratio << 4) |
790 (info_avi.db2_active_fmt_ar);
791 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(1), val);
792 sum += val;
793
794 val = (info_avi.db3_itc << 7) |
795 (info_avi.db3_ec << 4) |
796 (info_avi.db3_q_range << 2) |
797 (info_avi.db3_nup_scaling);
798 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(2), val);
799 sum += val;
800
801 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(3), info_avi.db4_videocode);
802 sum += info_avi.db4_videocode;
803
804 val = info_avi.db5_pixel_repeat;
805 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(4), val);
806 sum += val;
807
808 val = info_avi.db6_7_line_eoftop & 0x00FF;
809 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(5), val);
810 sum += val;
811
812 val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
813 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(6), val);
814 sum += val;
815
816 val = info_avi.db8_9_line_sofbottom & 0x00FF;
817 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(7), val);
818 sum += val;
819
820 val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
821 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(8), val);
822 sum += val;
823
824 val = info_avi.db10_11_pixel_eofleft & 0x00FF;
825 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(9), val);
826 sum += val;
827
828 val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
829 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(10), val);
830 sum += val;
831
832 val = info_avi.db12_13_pixel_sofright & 0x00FF;
833 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(11), val);
834 sum += val;
835
836 val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
837 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(12), val);
838 sum += val;
839
840 checksum = 0x100 - sum;
841 hdmi_write_reg(HDMI_CORE_AV_AVI_CHSUM, checksum);
842}
843
844static void hdmi_core_av_packet_config(
845 struct hdmi_core_packet_enable_repeat repeat_cfg)
846{
847 /* enable/repeat the infoframe */
848 hdmi_write_reg(HDMI_CORE_AV_PB_CTRL1,
849 (repeat_cfg.audio_pkt << 5) |
850 (repeat_cfg.audio_pkt_repeat << 4) |
851 (repeat_cfg.avi_infoframe << 1) |
852 (repeat_cfg.avi_infoframe_repeat));
853
854 /* enable/repeat the packet */
855 hdmi_write_reg(HDMI_CORE_AV_PB_CTRL2,
856 (repeat_cfg.gen_cntrl_pkt << 3) |
857 (repeat_cfg.gen_cntrl_pkt_repeat << 2) |
858 (repeat_cfg.generic_pkt << 1) |
859 (repeat_cfg.generic_pkt_repeat));
860}
861
862static void hdmi_wp_init(struct omap_video_timings *timings,
863 struct hdmi_video_format *video_fmt,
864 struct hdmi_video_interface *video_int)
865{
866 DSSDBG("Enter hdmi_wp_init\n");
867
868 timings->hbp = 0;
869 timings->hfp = 0;
870 timings->hsw = 0;
871 timings->vbp = 0;
872 timings->vfp = 0;
873 timings->vsw = 0;
874
875 video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
876 video_fmt->y_res = 0;
877 video_fmt->x_res = 0;
878
879 video_int->vsp = 0;
880 video_int->hsp = 0;
881
882 video_int->interlacing = 0;
883 video_int->tm = 0; /* HDMI_TIMING_SLAVE */
884
885}
886
887static void hdmi_wp_video_start(bool start)
888{
889 REG_FLD_MOD(HDMI_WP_VIDEO_CFG, start, 31, 31);
890}
891
892static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
893 struct omap_video_timings *timings, struct hdmi_config *param)
894{
895 DSSDBG("Enter hdmi_wp_video_init_format\n");
896
897 video_fmt->y_res = param->timings.timings.y_res;
898 video_fmt->x_res = param->timings.timings.x_res;
899
900 timings->hbp = param->timings.timings.hbp;
901 timings->hfp = param->timings.timings.hfp;
902 timings->hsw = param->timings.timings.hsw;
903 timings->vbp = param->timings.timings.vbp;
904 timings->vfp = param->timings.timings.vfp;
905 timings->vsw = param->timings.timings.vsw;
906}
907
908static void hdmi_wp_video_config_format(
909 struct hdmi_video_format *video_fmt)
910{
911 u32 l = 0;
912
913 REG_FLD_MOD(HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8);
914
915 l |= FLD_VAL(video_fmt->y_res, 31, 16);
916 l |= FLD_VAL(video_fmt->x_res, 15, 0);
917 hdmi_write_reg(HDMI_WP_VIDEO_SIZE, l);
918}
919
920static void hdmi_wp_video_config_interface(
921 struct hdmi_video_interface *video_int)
922{
923 u32 r;
924 DSSDBG("Enter hdmi_wp_video_config_interface\n");
925
926 r = hdmi_read_reg(HDMI_WP_VIDEO_CFG);
927 r = FLD_MOD(r, video_int->vsp, 7, 7);
928 r = FLD_MOD(r, video_int->hsp, 6, 6);
929 r = FLD_MOD(r, video_int->interlacing, 3, 3);
930 r = FLD_MOD(r, video_int->tm, 1, 0);
931 hdmi_write_reg(HDMI_WP_VIDEO_CFG, r);
932}
933
934static void hdmi_wp_video_config_timing(
935 struct omap_video_timings *timings)
936{
937 u32 timing_h = 0;
938 u32 timing_v = 0;
939
940 DSSDBG("Enter hdmi_wp_video_config_timing\n");
941
942 timing_h |= FLD_VAL(timings->hbp, 31, 20);
943 timing_h |= FLD_VAL(timings->hfp, 19, 8);
944 timing_h |= FLD_VAL(timings->hsw, 7, 0);
945 hdmi_write_reg(HDMI_WP_VIDEO_TIMING_H, timing_h);
946
947 timing_v |= FLD_VAL(timings->vbp, 31, 20);
948 timing_v |= FLD_VAL(timings->vfp, 19, 8);
949 timing_v |= FLD_VAL(timings->vsw, 7, 0);
950 hdmi_write_reg(HDMI_WP_VIDEO_TIMING_V, timing_v);
951}
952
953static void hdmi_basic_configure(struct hdmi_config *cfg)
954{
955 /* HDMI */
956 struct omap_video_timings video_timing;
957 struct hdmi_video_format video_format;
958 struct hdmi_video_interface video_interface;
959 /* HDMI core */
960 struct hdmi_core_infoframe_avi avi_cfg;
961 struct hdmi_core_video_config v_core_cfg;
962 struct hdmi_core_packet_enable_repeat repeat_cfg;
963
964 hdmi_wp_init(&video_timing, &video_format,
965 &video_interface);
966
967 hdmi_core_init(&v_core_cfg,
968 &avi_cfg,
969 &repeat_cfg);
970
971 hdmi_wp_video_init_format(&video_format,
972 &video_timing, cfg);
973
974 hdmi_wp_video_config_timing(&video_timing);
975
976 /* video config */
977 video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
978
979 hdmi_wp_video_config_format(&video_format);
980
981 video_interface.vsp = cfg->timings.vsync_pol;
982 video_interface.hsp = cfg->timings.hsync_pol;
983 video_interface.interlacing = cfg->interlace;
984 video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
985
986 hdmi_wp_video_config_interface(&video_interface);
987
988 /*
989 * configure core video part
990 * set software reset in the core
991 */
992 hdmi_core_swreset_assert();
993
994 /* power down off */
995 hdmi_core_powerdown_disable();
996
997 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
998 v_core_cfg.hdmi_dvi = cfg->cm.mode;
999
1000 hdmi_core_video_config(&v_core_cfg);
1001
1002 /* release software reset in the core */
1003 hdmi_core_swreset_release();
1004
1005 /*
1006 * configure packet
1007 * info frame video see doc CEA861-D page 65
1008 */
1009 avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
1010 avi_cfg.db1_active_info =
1011 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
1012 avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
1013 avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
1014 avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
1015 avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
1016 avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
1017 avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
1018 avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
1019 avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
1020 avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
1021 avi_cfg.db4_videocode = cfg->cm.code;
1022 avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
1023 avi_cfg.db6_7_line_eoftop = 0;
1024 avi_cfg.db8_9_line_sofbottom = 0;
1025 avi_cfg.db10_11_pixel_eofleft = 0;
1026 avi_cfg.db12_13_pixel_sofright = 0;
1027
1028 hdmi_core_aux_infoframe_avi_config(avi_cfg);
1029
1030 /* enable/repeat the infoframe */
1031 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
1032 repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
1033 /* wakeup */
1034 repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
1035 repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
1036 hdmi_core_av_packet_config(repeat_cfg);
1037}
1038
1039static void update_hdmi_timings(struct hdmi_config *cfg,
1040 struct omap_video_timings *timings, int code)
1041{
1042 cfg->timings.timings.x_res = timings->x_res;
1043 cfg->timings.timings.y_res = timings->y_res;
1044 cfg->timings.timings.hbp = timings->hbp;
1045 cfg->timings.timings.hfp = timings->hfp;
1046 cfg->timings.timings.hsw = timings->hsw;
1047 cfg->timings.timings.vbp = timings->vbp;
1048 cfg->timings.timings.vfp = timings->vfp;
1049 cfg->timings.timings.vsw = timings->vsw;
1050 cfg->timings.timings.pixel_clock = timings->pixel_clock;
1051 cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol;
1052 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
1053}
1054
1055static void hdmi_compute_pll(unsigned long clkin, int phy,
1056 int n, struct hdmi_pll_info *pi)
1057{
1058 unsigned long refclk;
1059 u32 mf;
1060
1061 /*
1062 * Input clock is predivided by N + 1
1063 * out put of which is reference clk
1064 */
1065 refclk = clkin / (n + 1);
1066 pi->regn = n;
1067
1068 /*
1069 * multiplier is pixel_clk/ref_clk
1070 * Multiplying by 100 to avoid fractional part removal
1071 */
1072 pi->regm = (phy * 100/(refclk))/100;
1073 pi->regm2 = 1;
1074
1075 /*
1076 * fractional multiplier is remainder of the difference between
1077 * multiplier and actual phy(required pixel clock thus should be
1078 * multiplied by 2^18(262144) divided by the reference clock
1079 */
1080 mf = (phy - pi->regm * refclk) * 262144;
1081 pi->regmf = mf/(refclk);
1082
1083 /*
1084 * Dcofreq should be set to 1 if required pixel clock
1085 * is greater than 1000MHz
1086 */
1087 pi->dcofreq = phy > 1000 * 100;
1088 pi->regsd = ((pi->regm * clkin / 10) / ((n + 1) * 250) + 5) / 10;
1089
1090 DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
1091 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
1092}
1093
1094static void hdmi_enable_clocks(int enable)
1095{
1096 if (enable)
1097 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK |
1098 DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
1099 else
1100 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK |
1101 DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
1102}
1103
1104static int hdmi_power_on(struct omap_dss_device *dssdev)
1105{
1106 int r, code = 0;
1107 struct hdmi_pll_info pll_data;
1108 struct omap_video_timings *p;
1109 int clkin, n, phy;
1110
1111 hdmi_enable_clocks(1);
1112
1113 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
1114
1115 p = &dssdev->panel.timings;
1116
1117 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
1118 dssdev->panel.timings.x_res,
1119 dssdev->panel.timings.y_res);
1120
1121 if (!hdmi.custom_set) {
1122 DSSDBG("Read EDID as no EDID is not set on poweron\n");
1123 hdmi_read_edid(p);
1124 }
1125 code = get_timings_index();
1126 dssdev->panel.timings = cea_vesa_timings[code].timings;
1127 update_hdmi_timings(&hdmi.cfg, p, code);
1128
1129 clkin = 3840; /* 38.4 MHz */
1130 n = 15; /* this is a constant for our math */
1131 phy = p->pixel_clock;
1132
1133 hdmi_compute_pll(clkin, phy, n, &pll_data);
1134
1135 hdmi_wp_video_start(0);
1136
1137 /* config the PLL and PHY first */
1138 r = hdmi_pll_program(&pll_data);
1139 if (r) {
1140 DSSDBG("Failed to lock PLL\n");
1141 goto err;
1142 }
1143
1144 r = hdmi_phy_init();
1145 if (r) {
1146 DSSDBG("Failed to start PHY\n");
1147 goto err;
1148 }
1149
1150 hdmi.cfg.cm.mode = hdmi.mode;
1151 hdmi.cfg.cm.code = hdmi.code;
1152 hdmi_basic_configure(&hdmi.cfg);
1153
1154 /* Make selection of HDMI in DSS */
1155 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
1156
1157 /* Select the dispc clock source as PRCM clock, to ensure that it is not
1158 * DSI PLL source as the clock selected by DSI PLL might not be
1159 * sufficient for the resolution selected / that can be changed
1160 * dynamically by user. This can be moved to single location , say
1161 * Boardfile.
1162 */
1163 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
1164
1165 /* bypass TV gamma table */
1166 dispc_enable_gamma_table(0);
1167
1168 /* tv size */
1169 dispc_set_digit_size(dssdev->panel.timings.x_res,
1170 dssdev->panel.timings.y_res);
1171
1172 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1);
1173
1174 hdmi_wp_video_start(1);
1175
1176 return 0;
1177err:
1178 hdmi_enable_clocks(0);
1179 return -EIO;
1180}
1181
1182static void hdmi_power_off(struct omap_dss_device *dssdev)
1183{
1184 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
1185
1186 hdmi_wp_video_start(0);
1187 hdmi_phy_off();
1188 hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
1189 hdmi_enable_clocks(0);
1190
1191 hdmi.edid_set = 0;
1192}
1193
1194int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
1195 struct omap_video_timings *timings)
1196{
1197 struct hdmi_cm cm;
1198
1199 cm = hdmi_get_code(timings);
1200 if (cm.code == -1) {
1201 DSSERR("Invalid timing entered\n");
1202 return -EINVAL;
1203 }
1204
1205 return 0;
1206
1207}
1208
1209void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
1210{
1211 struct hdmi_cm cm;
1212
1213 hdmi.custom_set = 1;
1214 cm = hdmi_get_code(&dssdev->panel.timings);
1215 hdmi.code = cm.code;
1216 hdmi.mode = cm.mode;
1217 omapdss_hdmi_display_enable(dssdev);
1218 hdmi.custom_set = 0;
1219}
1220
1221int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
1222{
1223 int r = 0;
1224
1225 DSSDBG("ENTER hdmi_display_enable\n");
1226
1227 mutex_lock(&hdmi.lock);
1228
1229 r = omap_dss_start_device(dssdev);
1230 if (r) {
1231 DSSERR("failed to start device\n");
1232 goto err0;
1233 }
1234
1235 if (dssdev->platform_enable) {
1236 r = dssdev->platform_enable(dssdev);
1237 if (r) {
1238 DSSERR("failed to enable GPIO's\n");
1239 goto err1;
1240 }
1241 }
1242
1243 r = hdmi_power_on(dssdev);
1244 if (r) {
1245 DSSERR("failed to power on device\n");
1246 goto err2;
1247 }
1248
1249 mutex_unlock(&hdmi.lock);
1250 return 0;
1251
1252err2:
1253 if (dssdev->platform_disable)
1254 dssdev->platform_disable(dssdev);
1255err1:
1256 omap_dss_stop_device(dssdev);
1257err0:
1258 mutex_unlock(&hdmi.lock);
1259 return r;
1260}
1261
1262void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
1263{
1264 DSSDBG("Enter hdmi_display_disable\n");
1265
1266 mutex_lock(&hdmi.lock);
1267
1268 hdmi_power_off(dssdev);
1269
1270 if (dssdev->platform_disable)
1271 dssdev->platform_disable(dssdev);
1272
1273 omap_dss_stop_device(dssdev);
1274
1275 mutex_unlock(&hdmi.lock);
1276}
1277
1278/* HDMI HW IP initialisation */
1279static int omapdss_hdmihw_probe(struct platform_device *pdev)
1280{
1281 struct resource *hdmi_mem;
1282
1283 hdmi.pdata = pdev->dev.platform_data;
1284 hdmi.pdev = pdev;
1285
1286 mutex_init(&hdmi.lock);
1287
1288 hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
1289 if (!hdmi_mem) {
1290 DSSERR("can't get IORESOURCE_MEM HDMI\n");
1291 return -EINVAL;
1292 }
1293
1294 /* Base address taken from platform */
1295 hdmi.base_wp = ioremap(hdmi_mem->start, resource_size(hdmi_mem));
1296 if (!hdmi.base_wp) {
1297 DSSERR("can't ioremap WP\n");
1298 return -ENOMEM;
1299 }
1300
1301 hdmi_panel_init();
1302
1303 return 0;
1304}
1305
1306static int omapdss_hdmihw_remove(struct platform_device *pdev)
1307{
1308 hdmi_panel_exit();
1309
1310 iounmap(hdmi.base_wp);
1311
1312 return 0;
1313}
1314
1315static struct platform_driver omapdss_hdmihw_driver = {
1316 .probe = omapdss_hdmihw_probe,
1317 .remove = omapdss_hdmihw_remove,
1318 .driver = {
1319 .name = "omapdss_hdmi",
1320 .owner = THIS_MODULE,
1321 },
1322};
1323
1324int hdmi_init_platform_driver(void)
1325{
1326 return platform_driver_register(&omapdss_hdmihw_driver);
1327}
1328
1329void hdmi_uninit_platform_driver(void)
1330{
1331 return platform_driver_unregister(&omapdss_hdmihw_driver);
1332}
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
new file mode 100644
index 00000000000..9887ab96da3
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi.h
@@ -0,0 +1,415 @@
1/*
2 * hdmi.h
3 *
4 * HDMI driver definition for TI OMAP4 processors.
5 *
6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.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 version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef _OMAP4_DSS_HDMI_H_
22#define _OMAP4_DSS_HDMI_H_
23
24#include <linux/string.h>
25#include <plat/display.h>
26
27#define HDMI_WP 0x0
28#define HDMI_CORE_SYS 0x400
29#define HDMI_CORE_AV 0x900
30#define HDMI_PLLCTRL 0x200
31#define HDMI_PHY 0x300
32
33struct hdmi_reg { u16 idx; };
34
35#define HDMI_REG(idx) ((const struct hdmi_reg) { idx })
36
37/* HDMI Wrapper */
38#define HDMI_WP_REG(idx) HDMI_REG(HDMI_WP + idx)
39
40#define HDMI_WP_REVISION HDMI_WP_REG(0x0)
41#define HDMI_WP_SYSCONFIG HDMI_WP_REG(0x10)
42#define HDMI_WP_IRQSTATUS_RAW HDMI_WP_REG(0x24)
43#define HDMI_WP_IRQSTATUS HDMI_WP_REG(0x28)
44#define HDMI_WP_PWR_CTRL HDMI_WP_REG(0x40)
45#define HDMI_WP_IRQENABLE_SET HDMI_WP_REG(0x2C)
46#define HDMI_WP_VIDEO_CFG HDMI_WP_REG(0x50)
47#define HDMI_WP_VIDEO_SIZE HDMI_WP_REG(0x60)
48#define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68)
49#define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C)
50#define HDMI_WP_WP_CLK HDMI_WP_REG(0x70)
51
52/* HDMI IP Core System */
53#define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx)
54
55#define HDMI_CORE_SYS_VND_IDL HDMI_CORE_SYS_REG(0x0)
56#define HDMI_CORE_SYS_DEV_IDL HDMI_CORE_SYS_REG(0x8)
57#define HDMI_CORE_SYS_DEV_IDH HDMI_CORE_SYS_REG(0xC)
58#define HDMI_CORE_SYS_DEV_REV HDMI_CORE_SYS_REG(0x10)
59#define HDMI_CORE_SYS_SRST HDMI_CORE_SYS_REG(0x14)
60#define HDMI_CORE_CTRL1 HDMI_CORE_SYS_REG(0x20)
61#define HDMI_CORE_SYS_SYS_STAT HDMI_CORE_SYS_REG(0x24)
62#define HDMI_CORE_SYS_VID_ACEN HDMI_CORE_SYS_REG(0x124)
63#define HDMI_CORE_SYS_VID_MODE HDMI_CORE_SYS_REG(0x128)
64#define HDMI_CORE_SYS_INTR_STATE HDMI_CORE_SYS_REG(0x1C0)
65#define HDMI_CORE_SYS_INTR1 HDMI_CORE_SYS_REG(0x1C4)
66#define HDMI_CORE_SYS_INTR2 HDMI_CORE_SYS_REG(0x1C8)
67#define HDMI_CORE_SYS_INTR3 HDMI_CORE_SYS_REG(0x1CC)
68#define HDMI_CORE_SYS_INTR4 HDMI_CORE_SYS_REG(0x1D0)
69#define HDMI_CORE_SYS_UMASK1 HDMI_CORE_SYS_REG(0x1D4)
70#define HDMI_CORE_SYS_TMDS_CTRL HDMI_CORE_SYS_REG(0x208)
71#define HDMI_CORE_SYS_DE_DLY HDMI_CORE_SYS_REG(0xC8)
72#define HDMI_CORE_SYS_DE_CTRL HDMI_CORE_SYS_REG(0xCC)
73#define HDMI_CORE_SYS_DE_TOP HDMI_CORE_SYS_REG(0xD0)
74#define HDMI_CORE_SYS_DE_CNTL HDMI_CORE_SYS_REG(0xD8)
75#define HDMI_CORE_SYS_DE_CNTH HDMI_CORE_SYS_REG(0xDC)
76#define HDMI_CORE_SYS_DE_LINL HDMI_CORE_SYS_REG(0xE0)
77#define HDMI_CORE_SYS_DE_LINH_1 HDMI_CORE_SYS_REG(0xE4)
78#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1
79#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1
80#define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1
81#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1
82
83/* HDMI DDC E-DID */
84#define HDMI_CORE_DDC_CMD HDMI_CORE_SYS_REG(0x3CC)
85#define HDMI_CORE_DDC_STATUS HDMI_CORE_SYS_REG(0x3C8)
86#define HDMI_CORE_DDC_ADDR HDMI_CORE_SYS_REG(0x3B4)
87#define HDMI_CORE_DDC_OFFSET HDMI_CORE_SYS_REG(0x3BC)
88#define HDMI_CORE_DDC_COUNT1 HDMI_CORE_SYS_REG(0x3C0)
89#define HDMI_CORE_DDC_COUNT2 HDMI_CORE_SYS_REG(0x3C4)
90#define HDMI_CORE_DDC_DATA HDMI_CORE_SYS_REG(0x3D0)
91#define HDMI_CORE_DDC_SEGM HDMI_CORE_SYS_REG(0x3B8)
92
93/* HDMI IP Core Audio Video */
94#define HDMI_CORE_AV_REG(idx) HDMI_REG(HDMI_CORE_AV + idx)
95
96#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
97#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
98#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
99#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
100#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
101#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
102#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
103#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
104#define HDMI_CORE_AV_AVI_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x110)
105#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_CORE_AV_REG(15)
106#define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190)
107#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
108#define HDMI_CORE_AV_MPEG_DBYTE HDMI_CORE_AV_REG(0x290)
109#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
110#define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300)
111#define HDMI_CORE_AV_GEN_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
112#define HDMI_CORE_AV_GEN2_DBYTE HDMI_CORE_AV_REG(0x380)
113#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
114#define HDMI_CORE_AV_ACR_CTRL HDMI_CORE_AV_REG(0x4)
115#define HDMI_CORE_AV_FREQ_SVAL HDMI_CORE_AV_REG(0x8)
116#define HDMI_CORE_AV_N_SVAL1 HDMI_CORE_AV_REG(0xC)
117#define HDMI_CORE_AV_N_SVAL2 HDMI_CORE_AV_REG(0x10)
118#define HDMI_CORE_AV_N_SVAL3 HDMI_CORE_AV_REG(0x14)
119#define HDMI_CORE_AV_CTS_SVAL1 HDMI_CORE_AV_REG(0x18)
120#define HDMI_CORE_AV_CTS_SVAL2 HDMI_CORE_AV_REG(0x1C)
121#define HDMI_CORE_AV_CTS_SVAL3 HDMI_CORE_AV_REG(0x20)
122#define HDMI_CORE_AV_CTS_HVAL1 HDMI_CORE_AV_REG(0x24)
123#define HDMI_CORE_AV_CTS_HVAL2 HDMI_CORE_AV_REG(0x28)
124#define HDMI_CORE_AV_CTS_HVAL3 HDMI_CORE_AV_REG(0x2C)
125#define HDMI_CORE_AV_AUD_MODE HDMI_CORE_AV_REG(0x50)
126#define HDMI_CORE_AV_SPDIF_CTRL HDMI_CORE_AV_REG(0x54)
127#define HDMI_CORE_AV_HW_SPDIF_FS HDMI_CORE_AV_REG(0x60)
128#define HDMI_CORE_AV_SWAP_I2S HDMI_CORE_AV_REG(0x64)
129#define HDMI_CORE_AV_SPDIF_ERTH HDMI_CORE_AV_REG(0x6C)
130#define HDMI_CORE_AV_I2S_IN_MAP HDMI_CORE_AV_REG(0x70)
131#define HDMI_CORE_AV_I2S_IN_CTRL HDMI_CORE_AV_REG(0x74)
132#define HDMI_CORE_AV_I2S_CHST0 HDMI_CORE_AV_REG(0x78)
133#define HDMI_CORE_AV_I2S_CHST1 HDMI_CORE_AV_REG(0x7C)
134#define HDMI_CORE_AV_I2S_CHST2 HDMI_CORE_AV_REG(0x80)
135#define HDMI_CORE_AV_I2S_CHST4 HDMI_CORE_AV_REG(0x84)
136#define HDMI_CORE_AV_I2S_CHST5 HDMI_CORE_AV_REG(0x88)
137#define HDMI_CORE_AV_ASRC HDMI_CORE_AV_REG(0x8C)
138#define HDMI_CORE_AV_I2S_IN_LEN HDMI_CORE_AV_REG(0x90)
139#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
140#define HDMI_CORE_AV_AUDO_TXSTAT HDMI_CORE_AV_REG(0xC0)
141#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 HDMI_CORE_AV_REG(0xCC)
142#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 HDMI_CORE_AV_REG(0xD0)
143#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 HDMI_CORE_AV_REG(0xD4)
144#define HDMI_CORE_AV_TEST_TXCTRL HDMI_CORE_AV_REG(0xF0)
145#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
146#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
147#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
148#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
149#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
150#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
151#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
152#define HDMI_CORE_AV_SPD_TYPE HDMI_CORE_AV_REG(0x180)
153#define HDMI_CORE_AV_SPD_VERS HDMI_CORE_AV_REG(0x184)
154#define HDMI_CORE_AV_SPD_LEN HDMI_CORE_AV_REG(0x188)
155#define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C)
156#define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280)
157#define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284)
158#define HDMI_CORE_AV_MPEG_LEN HDMI_CORE_AV_REG(0x288)
159#define HDMI_CORE_AV_MPEG_CHSUM HDMI_CORE_AV_REG(0x28C)
160#define HDMI_CORE_AV_CP_BYTE1 HDMI_CORE_AV_REG(0x37C)
161#define HDMI_CORE_AV_CEC_ADDR_ID HDMI_CORE_AV_REG(0x3FC)
162#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4
163#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4
164#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4
165#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4
166
167/* PLL */
168#define HDMI_PLL_REG(idx) HDMI_REG(HDMI_PLLCTRL + idx)
169
170#define PLLCTRL_PLL_CONTROL HDMI_PLL_REG(0x0)
171#define PLLCTRL_PLL_STATUS HDMI_PLL_REG(0x4)
172#define PLLCTRL_PLL_GO HDMI_PLL_REG(0x8)
173#define PLLCTRL_CFG1 HDMI_PLL_REG(0xC)
174#define PLLCTRL_CFG2 HDMI_PLL_REG(0x10)
175#define PLLCTRL_CFG3 HDMI_PLL_REG(0x14)
176#define PLLCTRL_CFG4 HDMI_PLL_REG(0x20)
177
178/* HDMI PHY */
179#define HDMI_PHY_REG(idx) HDMI_REG(HDMI_PHY + idx)
180
181#define HDMI_TXPHY_TX_CTRL HDMI_PHY_REG(0x0)
182#define HDMI_TXPHY_DIGITAL_CTRL HDMI_PHY_REG(0x4)
183#define HDMI_TXPHY_POWER_CTRL HDMI_PHY_REG(0x8)
184#define HDMI_TXPHY_PAD_CFG_CTRL HDMI_PHY_REG(0xC)
185
186/* HDMI EDID Length */
187#define HDMI_EDID_MAX_LENGTH 256
188#define EDID_TIMING_DESCRIPTOR_SIZE 0x12
189#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36
190#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80
191#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
192#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
193
194#define OMAP_HDMI_TIMINGS_NB 34
195
196#define REG_FLD_MOD(idx, val, start, end) \
197 hdmi_write_reg(idx, FLD_MOD(hdmi_read_reg(idx), val, start, end))
198#define REG_GET(idx, start, end) \
199 FLD_GET(hdmi_read_reg(idx), start, end)
200
201/* HDMI timing structure */
202struct hdmi_timings {
203 struct omap_video_timings timings;
204 int vsync_pol;
205 int hsync_pol;
206};
207
208enum hdmi_phy_pwr {
209 HDMI_PHYPWRCMD_OFF = 0,
210 HDMI_PHYPWRCMD_LDOON = 1,
211 HDMI_PHYPWRCMD_TXON = 2
212};
213
214enum hdmi_pll_pwr {
215 HDMI_PLLPWRCMD_ALLOFF = 0,
216 HDMI_PLLPWRCMD_PLLONLY = 1,
217 HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
218 HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
219};
220
221enum hdmi_clk_refsel {
222 HDMI_REFSEL_PCLK = 0,
223 HDMI_REFSEL_REF1 = 1,
224 HDMI_REFSEL_REF2 = 2,
225 HDMI_REFSEL_SYSCLK = 3
226};
227
228enum hdmi_core_inputbus_width {
229 HDMI_INPUT_8BIT = 0,
230 HDMI_INPUT_10BIT = 1,
231 HDMI_INPUT_12BIT = 2
232};
233
234enum hdmi_core_dither_trunc {
235 HDMI_OUTPUTTRUNCATION_8BIT = 0,
236 HDMI_OUTPUTTRUNCATION_10BIT = 1,
237 HDMI_OUTPUTTRUNCATION_12BIT = 2,
238 HDMI_OUTPUTDITHER_8BIT = 3,
239 HDMI_OUTPUTDITHER_10BIT = 4,
240 HDMI_OUTPUTDITHER_12BIT = 5
241};
242
243enum hdmi_core_deepcolor_ed {
244 HDMI_DEEPCOLORPACKECTDISABLE = 0,
245 HDMI_DEEPCOLORPACKECTENABLE = 1
246};
247
248enum hdmi_core_packet_mode {
249 HDMI_PACKETMODERESERVEDVALUE = 0,
250 HDMI_PACKETMODE24BITPERPIXEL = 4,
251 HDMI_PACKETMODE30BITPERPIXEL = 5,
252 HDMI_PACKETMODE36BITPERPIXEL = 6,
253 HDMI_PACKETMODE48BITPERPIXEL = 7
254};
255
256enum hdmi_core_hdmi_dvi {
257 HDMI_DVI = 0,
258 HDMI_HDMI = 1
259};
260
261enum hdmi_core_tclkselclkmult {
262 HDMI_FPLL05IDCK = 0,
263 HDMI_FPLL10IDCK = 1,
264 HDMI_FPLL20IDCK = 2,
265 HDMI_FPLL40IDCK = 3
266};
267
268enum hdmi_core_packet_ctrl {
269 HDMI_PACKETENABLE = 1,
270 HDMI_PACKETDISABLE = 0,
271 HDMI_PACKETREPEATON = 1,
272 HDMI_PACKETREPEATOFF = 0
273};
274
275/* INFOFRAME_AVI_ definitions */
276enum hdmi_core_infoframe {
277 HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
278 HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
279 HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2,
280 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0,
281 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1,
282 HDMI_INFOFRAME_AVI_DB1B_NO = 0,
283 HDMI_INFOFRAME_AVI_DB1B_VERT = 1,
284 HDMI_INFOFRAME_AVI_DB1B_HORI = 2,
285 HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3,
286 HDMI_INFOFRAME_AVI_DB1S_0 = 0,
287 HDMI_INFOFRAME_AVI_DB1S_1 = 1,
288 HDMI_INFOFRAME_AVI_DB1S_2 = 2,
289 HDMI_INFOFRAME_AVI_DB2C_NO = 0,
290 HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1,
291 HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2,
292 HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3,
293 HDMI_INFOFRAME_AVI_DB2M_NO = 0,
294 HDMI_INFOFRAME_AVI_DB2M_43 = 1,
295 HDMI_INFOFRAME_AVI_DB2M_169 = 2,
296 HDMI_INFOFRAME_AVI_DB2R_SAME = 8,
297 HDMI_INFOFRAME_AVI_DB2R_43 = 9,
298 HDMI_INFOFRAME_AVI_DB2R_169 = 10,
299 HDMI_INFOFRAME_AVI_DB2R_149 = 11,
300 HDMI_INFOFRAME_AVI_DB3ITC_NO = 0,
301 HDMI_INFOFRAME_AVI_DB3ITC_YES = 1,
302 HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0,
303 HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1,
304 HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0,
305 HDMI_INFOFRAME_AVI_DB3Q_LR = 1,
306 HDMI_INFOFRAME_AVI_DB3Q_FR = 2,
307 HDMI_INFOFRAME_AVI_DB3SC_NO = 0,
308 HDMI_INFOFRAME_AVI_DB3SC_HORI = 1,
309 HDMI_INFOFRAME_AVI_DB3SC_VERT = 2,
310 HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3,
311 HDMI_INFOFRAME_AVI_DB5PR_NO = 0,
312 HDMI_INFOFRAME_AVI_DB5PR_2 = 1,
313 HDMI_INFOFRAME_AVI_DB5PR_3 = 2,
314 HDMI_INFOFRAME_AVI_DB5PR_4 = 3,
315 HDMI_INFOFRAME_AVI_DB5PR_5 = 4,
316 HDMI_INFOFRAME_AVI_DB5PR_6 = 5,
317 HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
318 HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
319 HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
320 HDMI_INFOFRAME_AVI_DB5PR_10 = 9
321};
322
323enum hdmi_packing_mode {
324 HDMI_PACK_10b_RGB_YUV444 = 0,
325 HDMI_PACK_24b_RGB_YUV444_YUV422 = 1,
326 HDMI_PACK_20b_YUV422 = 2,
327 HDMI_PACK_ALREADYPACKED = 7
328};
329
330struct hdmi_core_video_config {
331 enum hdmi_core_inputbus_width ip_bus_width;
332 enum hdmi_core_dither_trunc op_dither_truc;
333 enum hdmi_core_deepcolor_ed deep_color_pkt;
334 enum hdmi_core_packet_mode pkt_mode;
335 enum hdmi_core_hdmi_dvi hdmi_dvi;
336 enum hdmi_core_tclkselclkmult tclk_sel_clkmult;
337};
338
339/*
340 * Refer to section 8.2 in HDMI 1.3 specification for
341 * details about infoframe databytes
342 */
343struct hdmi_core_infoframe_avi {
344 u8 db1_format;
345 /* Y0, Y1 rgb,yCbCr */
346 u8 db1_active_info;
347 /* A0 Active information Present */
348 u8 db1_bar_info_dv;
349 /* B0, B1 Bar info data valid */
350 u8 db1_scan_info;
351 /* S0, S1 scan information */
352 u8 db2_colorimetry;
353 /* C0, C1 colorimetry */
354 u8 db2_aspect_ratio;
355 /* M0, M1 Aspect ratio (4:3, 16:9) */
356 u8 db2_active_fmt_ar;
357 /* R0...R3 Active format aspect ratio */
358 u8 db3_itc;
359 /* ITC IT content. */
360 u8 db3_ec;
361 /* EC0, EC1, EC2 Extended colorimetry */
362 u8 db3_q_range;
363 /* Q1, Q0 Quantization range */
364 u8 db3_nup_scaling;
365 /* SC1, SC0 Non-uniform picture scaling */
366 u8 db4_videocode;
367 /* VIC0..6 Video format identification */
368 u8 db5_pixel_repeat;
369 /* PR0..PR3 Pixel repetition factor */
370 u16 db6_7_line_eoftop;
371 /* Line number end of top bar */
372 u16 db8_9_line_sofbottom;
373 /* Line number start of bottom bar */
374 u16 db10_11_pixel_eofleft;
375 /* Pixel number end of left bar */
376 u16 db12_13_pixel_sofright;
377 /* Pixel number start of right bar */
378};
379
380struct hdmi_core_packet_enable_repeat {
381 u32 audio_pkt;
382 u32 audio_pkt_repeat;
383 u32 avi_infoframe;
384 u32 avi_infoframe_repeat;
385 u32 gen_cntrl_pkt;
386 u32 gen_cntrl_pkt_repeat;
387 u32 generic_pkt;
388 u32 generic_pkt_repeat;
389};
390
391struct hdmi_video_format {
392 enum hdmi_packing_mode packing_mode;
393 u32 y_res; /* Line per panel */
394 u32 x_res; /* pixel per line */
395};
396
397struct hdmi_video_interface {
398 int vsp; /* Vsync polarity */
399 int hsp; /* Hsync polarity */
400 int interlacing;
401 int tm; /* Timing mode */
402};
403
404struct hdmi_cm {
405 int code;
406 int mode;
407};
408
409struct hdmi_config {
410 struct hdmi_timings timings;
411 u16 interlace;
412 struct hdmi_cm cm;
413};
414
415#endif
diff --git a/drivers/video/omap2/dss/hdmi_omap4_panel.c b/drivers/video/omap2/dss/hdmi_omap4_panel.c
new file mode 100644
index 00000000000..ffb5de94131
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi_omap4_panel.c
@@ -0,0 +1,222 @@
1/*
2 * hdmi_omap4_panel.c
3 *
4 * HDMI library support functions for TI OMAP4 processors.
5 *
6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
7 * Authors: Mythri P k <mythripk@ti.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 version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <linux/kernel.h>
23#include <linux/err.h>
24#include <linux/io.h>
25#include <linux/mutex.h>
26#include <linux/module.h>
27#include <plat/display.h>
28
29#include "dss.h"
30
31static struct {
32 struct mutex hdmi_lock;
33} hdmi;
34
35
36static int hdmi_panel_probe(struct omap_dss_device *dssdev)
37{
38 DSSDBG("ENTER hdmi_panel_probe\n");
39
40 dssdev->panel.config = OMAP_DSS_LCD_TFT |
41 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS;
42
43 /*
44 * Initialize the timings to 640 * 480
45 * This is only for framebuffer update not for TV timing setting
46 * Setting TV timing will be done only on enable
47 */
48 dssdev->panel.timings.x_res = 640;
49 dssdev->panel.timings.y_res = 480;
50
51 DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
52 dssdev->panel.timings.x_res,
53 dssdev->panel.timings.y_res);
54 return 0;
55}
56
57static void hdmi_panel_remove(struct omap_dss_device *dssdev)
58{
59
60}
61
62static int hdmi_panel_enable(struct omap_dss_device *dssdev)
63{
64 int r = 0;
65 DSSDBG("ENTER hdmi_panel_enable\n");
66
67 mutex_lock(&hdmi.hdmi_lock);
68
69 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
70 r = -EINVAL;
71 goto err;
72 }
73
74 r = omapdss_hdmi_display_enable(dssdev);
75 if (r) {
76 DSSERR("failed to power on\n");
77 goto err;
78 }
79
80 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
81
82err:
83 mutex_unlock(&hdmi.hdmi_lock);
84
85 return r;
86}
87
88static void hdmi_panel_disable(struct omap_dss_device *dssdev)
89{
90 mutex_lock(&hdmi.hdmi_lock);
91
92 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
93 omapdss_hdmi_display_disable(dssdev);
94
95 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
96
97 mutex_unlock(&hdmi.hdmi_lock);
98}
99
100static int hdmi_panel_suspend(struct omap_dss_device *dssdev)
101{
102 int r = 0;
103
104 mutex_lock(&hdmi.hdmi_lock);
105
106 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
107 r = -EINVAL;
108 goto err;
109 }
110
111 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
112
113 omapdss_hdmi_display_disable(dssdev);
114
115err:
116 mutex_unlock(&hdmi.hdmi_lock);
117
118 return r;
119}
120
121static int hdmi_panel_resume(struct omap_dss_device *dssdev)
122{
123 int r = 0;
124
125 mutex_lock(&hdmi.hdmi_lock);
126
127 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
128 r = -EINVAL;
129 goto err;
130 }
131
132 r = omapdss_hdmi_display_enable(dssdev);
133 if (r) {
134 DSSERR("failed to power on\n");
135 goto err;
136 }
137
138 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
139
140err:
141 mutex_unlock(&hdmi.hdmi_lock);
142
143 return r;
144}
145
146static void hdmi_get_timings(struct omap_dss_device *dssdev,
147 struct omap_video_timings *timings)
148{
149 mutex_lock(&hdmi.hdmi_lock);
150
151 *timings = dssdev->panel.timings;
152
153 mutex_unlock(&hdmi.hdmi_lock);
154}
155
156static void hdmi_set_timings(struct omap_dss_device *dssdev,
157 struct omap_video_timings *timings)
158{
159 DSSDBG("hdmi_set_timings\n");
160
161 mutex_lock(&hdmi.hdmi_lock);
162
163 dssdev->panel.timings = *timings;
164
165 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
166 /* turn the hdmi off and on to get new timings to use */
167 omapdss_hdmi_display_disable(dssdev);
168 omapdss_hdmi_display_set_timing(dssdev);
169 }
170
171 mutex_unlock(&hdmi.hdmi_lock);
172}
173
174static int hdmi_check_timings(struct omap_dss_device *dssdev,
175 struct omap_video_timings *timings)
176{
177 int r = 0;
178
179 DSSDBG("hdmi_check_timings\n");
180
181 mutex_lock(&hdmi.hdmi_lock);
182
183 r = omapdss_hdmi_display_check_timing(dssdev, timings);
184 if (r) {
185 DSSERR("Timing cannot be applied\n");
186 goto err;
187 }
188err:
189 mutex_unlock(&hdmi.hdmi_lock);
190 return r;
191}
192
193static struct omap_dss_driver hdmi_driver = {
194 .probe = hdmi_panel_probe,
195 .remove = hdmi_panel_remove,
196 .enable = hdmi_panel_enable,
197 .disable = hdmi_panel_disable,
198 .suspend = hdmi_panel_suspend,
199 .resume = hdmi_panel_resume,
200 .get_timings = hdmi_get_timings,
201 .set_timings = hdmi_set_timings,
202 .check_timings = hdmi_check_timings,
203 .driver = {
204 .name = "hdmi_panel",
205 .owner = THIS_MODULE,
206 },
207};
208
209int hdmi_panel_init(void)
210{
211 mutex_init(&hdmi.hdmi_lock);
212
213 omap_dss_register_driver(&hdmi_driver);
214
215 return 0;
216}
217
218void hdmi_panel_exit(void)
219{
220 omap_dss_unregister_driver(&hdmi_driver);
221
222}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 172d4e69730..bcd37ec8695 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -515,6 +515,8 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
515 515
516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { 516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
517 irq = DISPC_IRQ_EVSYNC_ODD; 517 irq = DISPC_IRQ_EVSYNC_ODD;
518 } else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) {
519 irq = DISPC_IRQ_EVSYNC_EVEN;
518 } else { 520 } else {
519 if (mgr->id == OMAP_DSS_CHANNEL_LCD) 521 if (mgr->id == OMAP_DSS_CHANNEL_LCD)
520 irq = DISPC_IRQ_VSYNC; 522 irq = DISPC_IRQ_VSYNC;
@@ -536,7 +538,8 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
536 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 538 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
537 return 0; 539 return 0;
538 540
539 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 541 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
542 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
540 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 543 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
541 } else { 544 } else {
542 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 545 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
@@ -613,7 +616,8 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
613 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 616 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
614 return 0; 617 return 0;
615 618
616 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 619 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
620 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
617 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 621 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
618 } else { 622 } else {
619 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 623 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
@@ -1377,6 +1381,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1377 case OMAP_DISPLAY_TYPE_DBI: 1381 case OMAP_DISPLAY_TYPE_DBI:
1378 case OMAP_DISPLAY_TYPE_SDI: 1382 case OMAP_DISPLAY_TYPE_SDI:
1379 case OMAP_DISPLAY_TYPE_VENC: 1383 case OMAP_DISPLAY_TYPE_VENC:
1384 case OMAP_DISPLAY_TYPE_HDMI:
1380 default_get_overlay_fifo_thresholds(ovl->id, size, 1385 default_get_overlay_fifo_thresholds(ovl->id, size,
1381 &oc->burst_size, &oc->fifo_low, 1386 &oc->burst_size, &oc->fifo_low,
1382 &oc->fifo_high); 1387 &oc->fifo_high);
@@ -1394,7 +1399,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1394 } 1399 }
1395 1400
1396 r = 0; 1401 r = 0;
1397 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 1402 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
1398 if (!dss_cache.irq_enabled) { 1403 if (!dss_cache.irq_enabled) {
1399 u32 mask; 1404 u32 mask;
1400 1405
@@ -1407,7 +1412,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1407 dss_cache.irq_enabled = true; 1412 dss_cache.irq_enabled = true;
1408 } 1413 }
1409 configure_dispc(); 1414 configure_dispc();
1410 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 1415 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
1411 1416
1412 spin_unlock_irqrestore(&dss_cache.lock, flags); 1417 spin_unlock_irqrestore(&dss_cache.lock, flags);
1413 1418
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 456efef03c2..f1aca6d0401 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -490,7 +490,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
490 490
491 ovl->manager = mgr; 491 ovl->manager = mgr;
492 492
493 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 493 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
494 /* XXX: on manual update display, in auto update mode, a bug happens 494 /* XXX: on manual update display, in auto update mode, a bug happens
495 * here. When an overlay is first enabled on LCD, then it's disabled, 495 * here. When an overlay is first enabled on LCD, then it's disabled,
496 * and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT 496 * and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT
@@ -499,7 +499,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
499 * but I don't understand how or why. */ 499 * but I don't understand how or why. */
500 msleep(40); 500 msleep(40);
501 dispc_set_channel_out(ovl->id, mgr->id); 501 dispc_set_channel_out(ovl->id, mgr->id);
502 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 502 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
503 503
504 return 0; 504 return 0;
505} 505}
@@ -679,7 +679,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
679 lcd2_mgr->set_device(lcd2_mgr, dssdev); 679 lcd2_mgr->set_device(lcd2_mgr, dssdev);
680 mgr = lcd2_mgr; 680 mgr = lcd2_mgr;
681 } 681 }
682 } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) { 682 } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
683 && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
683 if (!lcd_mgr->device || force) { 684 if (!lcd_mgr->device || force) {
684 if (lcd_mgr->device) 685 if (lcd_mgr->device)
685 lcd_mgr->unset_device(lcd_mgr); 686 lcd_mgr->unset_device(lcd_mgr);
@@ -688,7 +689,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
688 } 689 }
689 } 690 }
690 691
691 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 692 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
693 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
692 if (!tv_mgr->device || force) { 694 if (!tv_mgr->device || force) {
693 if (tv_mgr->device) 695 if (tv_mgr->device)
694 tv_mgr->unset_device(tv_mgr); 696 tv_mgr->unset_device(tv_mgr);
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 10a2ffe0288..5ea17f49c61 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -36,8 +36,6 @@
36#include <plat/display.h> 36#include <plat/display.h>
37#include "dss.h" 37#include "dss.h"
38 38
39#define RFBI_BASE 0x48050800
40
41struct rfbi_reg { u16 idx; }; 39struct rfbi_reg { u16 idx; };
42 40
43#define RFBI_REG(idx) ((const struct rfbi_reg) { idx }) 41#define RFBI_REG(idx) ((const struct rfbi_reg) { idx })
@@ -100,6 +98,7 @@ static int rfbi_convert_timings(struct rfbi_timings *t);
100static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); 98static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
101 99
102static struct { 100static struct {
101 struct platform_device *pdev;
103 void __iomem *base; 102 void __iomem *base;
104 103
105 unsigned long l4_khz; 104 unsigned long l4_khz;
@@ -142,9 +141,9 @@ static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
142static void rfbi_enable_clocks(bool enable) 141static void rfbi_enable_clocks(bool enable)
143{ 142{
144 if (enable) 143 if (enable)
145 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 144 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
146 else 145 else
147 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 146 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
148} 147}
149 148
150void omap_rfbi_write_command(const void *buf, u32 len) 149void omap_rfbi_write_command(const void *buf, u32 len)
@@ -497,7 +496,7 @@ unsigned long rfbi_get_max_tx_rate(void)
497 }; 496 };
498 497
499 l4_rate = rfbi.l4_khz / 1000; 498 l4_rate = rfbi.l4_khz / 1000;
500 dss1_rate = dss_clk_get_rate(DSS_CLK_FCK1) / 1000000; 499 dss1_rate = dss_clk_get_rate(DSS_CLK_FCK) / 1000000;
501 500
502 for (i = 0; i < ARRAY_SIZE(ftab); i++) { 501 for (i = 0; i < ARRAY_SIZE(ftab); i++) {
503 /* Use a window instead of an exact match, to account 502 /* Use a window instead of an exact match, to account
@@ -922,7 +921,7 @@ void rfbi_dump_regs(struct seq_file *s)
922{ 921{
923#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) 922#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
924 923
925 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 924 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
926 925
927 DUMPREG(RFBI_REVISION); 926 DUMPREG(RFBI_REVISION);
928 DUMPREG(RFBI_SYSCONFIG); 927 DUMPREG(RFBI_SYSCONFIG);
@@ -953,54 +952,10 @@ void rfbi_dump_regs(struct seq_file *s)
953 DUMPREG(RFBI_VSYNC_WIDTH); 952 DUMPREG(RFBI_VSYNC_WIDTH);
954 DUMPREG(RFBI_HSYNC_WIDTH); 953 DUMPREG(RFBI_HSYNC_WIDTH);
955 954
956 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 955 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
957#undef DUMPREG 956#undef DUMPREG
958} 957}
959 958
960int rfbi_init(void)
961{
962 u32 rev;
963 u32 l;
964
965 spin_lock_init(&rfbi.cmd_lock);
966
967 init_completion(&rfbi.cmd_done);
968 atomic_set(&rfbi.cmd_fifo_full, 0);
969 atomic_set(&rfbi.cmd_pending, 0);
970
971 rfbi.base = ioremap(RFBI_BASE, SZ_256);
972 if (!rfbi.base) {
973 DSSERR("can't ioremap RFBI\n");
974 return -ENOMEM;
975 }
976
977 rfbi_enable_clocks(1);
978
979 msleep(10);
980
981 rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
982
983 /* Enable autoidle and smart-idle */
984 l = rfbi_read_reg(RFBI_SYSCONFIG);
985 l |= (1 << 0) | (2 << 3);
986 rfbi_write_reg(RFBI_SYSCONFIG, l);
987
988 rev = rfbi_read_reg(RFBI_REVISION);
989 printk(KERN_INFO "OMAP RFBI rev %d.%d\n",
990 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
991
992 rfbi_enable_clocks(0);
993
994 return 0;
995}
996
997void rfbi_exit(void)
998{
999 DSSDBG("rfbi_exit\n");
1000
1001 iounmap(rfbi.base);
1002}
1003
1004int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) 959int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
1005{ 960{
1006 int r; 961 int r;
@@ -1056,3 +1011,74 @@ int rfbi_init_display(struct omap_dss_device *dssdev)
1056 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 1011 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
1057 return 0; 1012 return 0;
1058} 1013}
1014
1015/* RFBI HW IP initialisation */
1016static int omap_rfbihw_probe(struct platform_device *pdev)
1017{
1018 u32 rev;
1019 u32 l;
1020 struct resource *rfbi_mem;
1021
1022 rfbi.pdev = pdev;
1023
1024 spin_lock_init(&rfbi.cmd_lock);
1025
1026 init_completion(&rfbi.cmd_done);
1027 atomic_set(&rfbi.cmd_fifo_full, 0);
1028 atomic_set(&rfbi.cmd_pending, 0);
1029
1030 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
1031 if (!rfbi_mem) {
1032 DSSERR("can't get IORESOURCE_MEM RFBI\n");
1033 return -EINVAL;
1034 }
1035 rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem));
1036 if (!rfbi.base) {
1037 DSSERR("can't ioremap RFBI\n");
1038 return -ENOMEM;
1039 }
1040
1041 rfbi_enable_clocks(1);
1042
1043 msleep(10);
1044
1045 rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
1046
1047 /* Enable autoidle and smart-idle */
1048 l = rfbi_read_reg(RFBI_SYSCONFIG);
1049 l |= (1 << 0) | (2 << 3);
1050 rfbi_write_reg(RFBI_SYSCONFIG, l);
1051
1052 rev = rfbi_read_reg(RFBI_REVISION);
1053 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
1054 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
1055
1056 rfbi_enable_clocks(0);
1057
1058 return 0;
1059}
1060
1061static int omap_rfbihw_remove(struct platform_device *pdev)
1062{
1063 iounmap(rfbi.base);
1064 return 0;
1065}
1066
1067static struct platform_driver omap_rfbihw_driver = {
1068 .probe = omap_rfbihw_probe,
1069 .remove = omap_rfbihw_remove,
1070 .driver = {
1071 .name = "omapdss_rfbi",
1072 .owner = THIS_MODULE,
1073 },
1074};
1075
1076int rfbi_init_platform_driver(void)
1077{
1078 return platform_driver_register(&omap_rfbihw_driver);
1079}
1080
1081void rfbi_uninit_platform_driver(void)
1082{
1083 return platform_driver_unregister(&omap_rfbihw_driver);
1084}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index b64adf7dfc8..54a53e64818 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -30,7 +30,6 @@
30#include "dss.h" 30#include "dss.h"
31 31
32static struct { 32static struct {
33 bool skip_init;
34 bool update_enabled; 33 bool update_enabled;
35 struct regulator *vdds_sdi_reg; 34 struct regulator *vdds_sdi_reg;
36} sdi; 35} sdi;
@@ -68,9 +67,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
68 if (r) 67 if (r)
69 goto err1; 68 goto err1;
70 69
71 /* In case of skip_init sdi_init has already enabled the clocks */ 70 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
72 if (!sdi.skip_init)
73 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
74 71
75 sdi_basic_init(dssdev); 72 sdi_basic_init(dssdev);
76 73
@@ -80,14 +77,8 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
80 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, 77 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
81 dssdev->panel.acbi, dssdev->panel.acb); 78 dssdev->panel.acbi, dssdev->panel.acb);
82 79
83 if (!sdi.skip_init) { 80 r = dss_calc_clock_div(1, t->pixel_clock * 1000,
84 r = dss_calc_clock_div(1, t->pixel_clock * 1000, 81 &dss_cinfo, &dispc_cinfo);
85 &dss_cinfo, &dispc_cinfo);
86 } else {
87 r = dss_get_clock_div(&dss_cinfo);
88 r = dispc_get_clock_div(dssdev->manager->id, &dispc_cinfo);
89 }
90
91 if (r) 82 if (r)
92 goto err2; 83 goto err2;
93 84
@@ -116,21 +107,17 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
116 if (r) 107 if (r)
117 goto err2; 108 goto err2;
118 109
119 if (!sdi.skip_init) { 110 dss_sdi_init(dssdev->phy.sdi.datapairs);
120 dss_sdi_init(dssdev->phy.sdi.datapairs); 111 r = dss_sdi_enable();
121 r = dss_sdi_enable(); 112 if (r)
122 if (r) 113 goto err1;
123 goto err1; 114 mdelay(2);
124 mdelay(2);
125 }
126 115
127 dssdev->manager->enable(dssdev->manager); 116 dssdev->manager->enable(dssdev->manager);
128 117
129 sdi.skip_init = 0;
130
131 return 0; 118 return 0;
132err2: 119err2:
133 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 120 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
134 regulator_disable(sdi.vdds_sdi_reg); 121 regulator_disable(sdi.vdds_sdi_reg);
135err1: 122err1:
136 omap_dss_stop_device(dssdev); 123 omap_dss_stop_device(dssdev);
@@ -145,7 +132,7 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
145 132
146 dss_sdi_disable(); 133 dss_sdi_disable();
147 134
148 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 135 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
149 136
150 regulator_disable(sdi.vdds_sdi_reg); 137 regulator_disable(sdi.vdds_sdi_reg);
151 138
@@ -157,25 +144,24 @@ int sdi_init_display(struct omap_dss_device *dssdev)
157{ 144{
158 DSSDBG("SDI init\n"); 145 DSSDBG("SDI init\n");
159 146
147 if (sdi.vdds_sdi_reg == NULL) {
148 struct regulator *vdds_sdi;
149
150 vdds_sdi = dss_get_vdds_sdi();
151
152 if (IS_ERR(vdds_sdi)) {
153 DSSERR("can't get VDDS_SDI regulator\n");
154 return PTR_ERR(vdds_sdi);
155 }
156
157 sdi.vdds_sdi_reg = vdds_sdi;
158 }
159
160 return 0; 160 return 0;
161} 161}
162 162
163int sdi_init(bool skip_init) 163int sdi_init(void)
164{ 164{
165 /* we store this for first display enable, then clear it */
166 sdi.skip_init = skip_init;
167
168 sdi.vdds_sdi_reg = dss_get_vdds_sdi();
169 if (IS_ERR(sdi.vdds_sdi_reg)) {
170 DSSERR("can't get VDDS_SDI regulator\n");
171 return PTR_ERR(sdi.vdds_sdi_reg);
172 }
173 /*
174 * Enable clocks already here, otherwise there would be a toggle
175 * of them until sdi_display_enable is called.
176 */
177 if (skip_init)
178 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
179 return 0; 165 return 0;
180} 166}
181 167
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index eff35050e28..8e35a5bae42 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -39,8 +39,6 @@
39 39
40#include "dss.h" 40#include "dss.h"
41 41
42#define VENC_BASE 0x48050C00
43
44/* Venc registers */ 42/* Venc registers */
45#define VENC_REV_ID 0x00 43#define VENC_REV_ID 0x00
46#define VENC_STATUS 0x04 44#define VENC_STATUS 0x04
@@ -289,6 +287,7 @@ const struct omap_video_timings omap_dss_ntsc_timings = {
289EXPORT_SYMBOL(omap_dss_ntsc_timings); 287EXPORT_SYMBOL(omap_dss_ntsc_timings);
290 288
291static struct { 289static struct {
290 struct platform_device *pdev;
292 void __iomem *base; 291 void __iomem *base;
293 struct mutex venc_lock; 292 struct mutex venc_lock;
294 u32 wss_data; 293 u32 wss_data;
@@ -381,11 +380,11 @@ static void venc_reset(void)
381static void venc_enable_clocks(int enable) 380static void venc_enable_clocks(int enable)
382{ 381{
383 if (enable) 382 if (enable)
384 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | 383 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
385 DSS_CLK_96M); 384 DSS_CLK_VIDFCK);
386 else 385 else
387 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | 386 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
388 DSS_CLK_96M); 387 DSS_CLK_VIDFCK);
389} 388}
390 389
391static const struct venc_config *venc_timings_to_config( 390static const struct venc_config *venc_timings_to_config(
@@ -641,50 +640,23 @@ static struct omap_dss_driver venc_driver = {
641}; 640};
642/* driver end */ 641/* driver end */
643 642
644 643int venc_init_display(struct omap_dss_device *dssdev)
645
646int venc_init(struct platform_device *pdev)
647{ 644{
648 u8 rev_id; 645 DSSDBG("init_display\n");
649 646
650 mutex_init(&venc.venc_lock); 647 if (venc.vdda_dac_reg == NULL) {
648 struct regulator *vdda_dac;
651 649
652 venc.wss_data = 0; 650 vdda_dac = regulator_get(&venc.pdev->dev, "vdda_dac");
653 651
654 venc.base = ioremap(VENC_BASE, SZ_1K); 652 if (IS_ERR(vdda_dac)) {
655 if (!venc.base) { 653 DSSERR("can't get VDDA_DAC regulator\n");
656 DSSERR("can't ioremap VENC\n"); 654 return PTR_ERR(vdda_dac);
657 return -ENOMEM; 655 }
658 }
659 656
660 venc.vdda_dac_reg = dss_get_vdda_dac(); 657 venc.vdda_dac_reg = vdda_dac;
661 if (IS_ERR(venc.vdda_dac_reg)) {
662 iounmap(venc.base);
663 DSSERR("can't get VDDA_DAC regulator\n");
664 return PTR_ERR(venc.vdda_dac_reg);
665 } 658 }
666 659
667 venc_enable_clocks(1);
668
669 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
670 printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
671
672 venc_enable_clocks(0);
673
674 return omap_dss_register_driver(&venc_driver);
675}
676
677void venc_exit(void)
678{
679 omap_dss_unregister_driver(&venc_driver);
680
681 iounmap(venc.base);
682}
683
684int venc_init_display(struct omap_dss_device *dssdev)
685{
686 DSSDBG("init_display\n");
687
688 return 0; 660 return 0;
689} 661}
690 662
@@ -740,3 +712,73 @@ void venc_dump_regs(struct seq_file *s)
740 712
741#undef DUMPREG 713#undef DUMPREG
742} 714}
715
716/* VENC HW IP initialisation */
717static int omap_venchw_probe(struct platform_device *pdev)
718{
719 u8 rev_id;
720 struct resource *venc_mem;
721
722 venc.pdev = pdev;
723
724 mutex_init(&venc.venc_lock);
725
726 venc.wss_data = 0;
727
728 venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
729 if (!venc_mem) {
730 DSSERR("can't get IORESOURCE_MEM VENC\n");
731 return -EINVAL;
732 }
733 venc.base = ioremap(venc_mem->start, resource_size(venc_mem));
734 if (!venc.base) {
735 DSSERR("can't ioremap VENC\n");
736 return -ENOMEM;
737 }
738
739 venc_enable_clocks(1);
740
741 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
742 dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id);
743
744 venc_enable_clocks(0);
745
746 return omap_dss_register_driver(&venc_driver);
747}
748
749static int omap_venchw_remove(struct platform_device *pdev)
750{
751 if (venc.vdda_dac_reg != NULL) {
752 regulator_put(venc.vdda_dac_reg);
753 venc.vdda_dac_reg = NULL;
754 }
755 omap_dss_unregister_driver(&venc_driver);
756
757 iounmap(venc.base);
758 return 0;
759}
760
761static struct platform_driver omap_venchw_driver = {
762 .probe = omap_venchw_probe,
763 .remove = omap_venchw_remove,
764 .driver = {
765 .name = "omapdss_venc",
766 .owner = THIS_MODULE,
767 },
768};
769
770int venc_init_platform_driver(void)
771{
772 if (cpu_is_omap44xx())
773 return 0;
774
775 return platform_driver_register(&omap_venchw_driver);
776}
777
778void venc_uninit_platform_driver(void)
779{
780 if (cpu_is_omap44xx())
781 return;
782
783 return platform_driver_unregister(&omap_venchw_driver);
784}
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
index 65149b22cf3..aa33386c81f 100644
--- a/drivers/video/omap2/omapfb/Kconfig
+++ b/drivers/video/omap2/omapfb/Kconfig
@@ -1,5 +1,5 @@
1menuconfig FB_OMAP2 1menuconfig FB_OMAP2
2 tristate "OMAP2/3 frame buffer support (EXPERIMENTAL)" 2 tristate "OMAP2+ frame buffer support (EXPERIMENTAL)"
3 depends on FB && OMAP2_DSS 3 depends on FB && OMAP2_DSS
4 4
5 select OMAP2_VRAM 5 select OMAP2_VRAM
@@ -8,10 +8,10 @@ menuconfig FB_OMAP2
8 select FB_CFB_COPYAREA 8 select FB_CFB_COPYAREA
9 select FB_CFB_IMAGEBLIT 9 select FB_CFB_IMAGEBLIT
10 help 10 help
11 Frame buffer driver for OMAP2/3 based boards. 11 Frame buffer driver for OMAP2+ based boards.
12 12
13config FB_OMAP2_DEBUG_SUPPORT 13config FB_OMAP2_DEBUG_SUPPORT
14 bool "Debug support for OMAP2/3 FB" 14 bool "Debug support for OMAP2+ FB"
15 default y 15 default y
16 depends on FB_OMAP2 16 depends on FB_OMAP2
17 help 17 help
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 4fdab8e9c49..505ec667204 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2090,7 +2090,7 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2090{ 2090{
2091 int r; 2091 int r;
2092 u8 bpp; 2092 u8 bpp;
2093 struct omap_video_timings timings; 2093 struct omap_video_timings timings, temp_timings;
2094 2094
2095 r = omapfb_mode_to_timings(mode_str, &timings, &bpp); 2095 r = omapfb_mode_to_timings(mode_str, &timings, &bpp);
2096 if (r) 2096 if (r)
@@ -2100,14 +2100,23 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2100 fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp; 2100 fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp;
2101 ++fbdev->num_bpp_overrides; 2101 ++fbdev->num_bpp_overrides;
2102 2102
2103 if (!display->driver->check_timings || !display->driver->set_timings) 2103 if (display->driver->check_timings) {
2104 return -EINVAL; 2104 r = display->driver->check_timings(display, &timings);
2105 if (r)
2106 return r;
2107 } else {
2108 /* If check_timings is not present compare xres and yres */
2109 if (display->driver->get_timings) {
2110 display->driver->get_timings(display, &temp_timings);
2105 2111
2106 r = display->driver->check_timings(display, &timings); 2112 if (temp_timings.x_res != timings.x_res ||
2107 if (r) 2113 temp_timings.y_res != timings.y_res)
2108 return r; 2114 return -EINVAL;
2115 }
2116 }
2109 2117
2110 display->driver->set_timings(display, &timings); 2118 if (display->driver->set_timings)
2119 display->driver->set_timings(display, &timings);
2111 2120
2112 return 0; 2121 return 0;
2113} 2122}
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 83ce9a04d87..6817d187d46 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -1340,6 +1340,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
1340 sfb->bus_clk = clk_get(dev, "lcd"); 1340 sfb->bus_clk = clk_get(dev, "lcd");
1341 if (IS_ERR(sfb->bus_clk)) { 1341 if (IS_ERR(sfb->bus_clk)) {
1342 dev_err(dev, "failed to get bus clock\n"); 1342 dev_err(dev, "failed to get bus clock\n");
1343 ret = PTR_ERR(sfb->bus_clk);
1343 goto err_sfb; 1344 goto err_sfb;
1344 } 1345 }
1345 1346
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 75738a92861..ddedad9cd06 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -64,6 +64,8 @@ static const struct svga_fb_format s3fb_formats[] = {
64 64
65static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3, 65static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3,
66 35000, 240000, 14318}; 66 35000, 240000, 14318};
67static const struct svga_pll s3_trio3d_pll = {3, 129, 3, 31, 0, 4,
68 230000, 460000, 14318};
67 69
68static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512}; 70static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512};
69 71
@@ -72,7 +74,8 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
72 "S3 Plato/PX", "S3 Aurora64VP", "S3 Virge", 74 "S3 Plato/PX", "S3 Aurora64VP", "S3 Virge",
73 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX", 75 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX",
74 "S3 Virge/GX2", "S3 Virge/GX2P", "S3 Virge/GX2P", 76 "S3 Virge/GX2", "S3 Virge/GX2P", "S3 Virge/GX2P",
75 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X"}; 77 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X",
78 "S3 Trio3D"};
76 79
77#define CHIP_UNKNOWN 0x00 80#define CHIP_UNKNOWN 0x00
78#define CHIP_732_TRIO32 0x01 81#define CHIP_732_TRIO32 0x01
@@ -93,6 +96,7 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
93#define CHIP_360_TRIO3D_1X 0x10 96#define CHIP_360_TRIO3D_1X 0x10
94#define CHIP_362_TRIO3D_2X 0x11 97#define CHIP_362_TRIO3D_2X 0x11
95#define CHIP_368_TRIO3D_2X 0x12 98#define CHIP_368_TRIO3D_2X 0x12
99#define CHIP_365_TRIO3D 0x13
96 100
97#define CHIP_XXX_TRIO 0x80 101#define CHIP_XXX_TRIO 0x80
98#define CHIP_XXX_TRIO64V2_DXGX 0x81 102#define CHIP_XXX_TRIO64V2_DXGX 0x81
@@ -119,9 +123,11 @@ static const struct vga_regset s3_v_sync_start_regs[] = {{0x10, 0, 7}, {0x07,
119static const struct vga_regset s3_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END}; 123static const struct vga_regset s3_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END};
120 124
121static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x5E, 6, 6}, VGA_REGSET_END}; 125static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x5E, 6, 6}, VGA_REGSET_END};
122static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x31, 4, 5}, {0x51, 0, 1}, VGA_REGSET_END}; 126static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x69, 0, 4}, VGA_REGSET_END};
123static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */ 127static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */
124 128
129static const struct vga_regset s3_dtpc_regs[] = {{0x3B, 0, 7}, {0x5D, 6, 6}, VGA_REGSET_END};
130
125static const struct svga_timing_regs s3_timing_regs = { 131static const struct svga_timing_regs s3_timing_regs = {
126 s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs, 132 s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs,
127 s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs, 133 s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs,
@@ -188,12 +194,19 @@ static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
188 } 194 }
189} 195}
190 196
197static void s3fb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
198{
199 struct s3fb_info *par = info->par;
200
201 svga_tilecursor(par->state.vgabase, info, cursor);
202}
203
191static struct fb_tile_ops s3fb_tile_ops = { 204static struct fb_tile_ops s3fb_tile_ops = {
192 .fb_settile = svga_settile, 205 .fb_settile = svga_settile,
193 .fb_tilecopy = svga_tilecopy, 206 .fb_tilecopy = svga_tilecopy,
194 .fb_tilefill = svga_tilefill, 207 .fb_tilefill = svga_tilefill,
195 .fb_tileblit = svga_tileblit, 208 .fb_tileblit = svga_tileblit,
196 .fb_tilecursor = svga_tilecursor, 209 .fb_tilecursor = s3fb_tilecursor,
197 .fb_get_tilemax = svga_get_tilemax, 210 .fb_get_tilemax = svga_get_tilemax,
198}; 211};
199 212
@@ -202,7 +215,7 @@ static struct fb_tile_ops s3fb_fast_tile_ops = {
202 .fb_tilecopy = svga_tilecopy, 215 .fb_tilecopy = svga_tilecopy,
203 .fb_tilefill = svga_tilefill, 216 .fb_tilefill = svga_tilefill,
204 .fb_tileblit = svga_tileblit, 217 .fb_tileblit = svga_tileblit,
205 .fb_tilecursor = svga_tilecursor, 218 .fb_tilecursor = s3fb_tilecursor,
206 .fb_get_tilemax = svga_get_tilemax, 219 .fb_get_tilemax = svga_get_tilemax,
207}; 220};
208 221
@@ -334,33 +347,34 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock)
334 u8 regval; 347 u8 regval;
335 int rv; 348 int rv;
336 349
337 rv = svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node); 350 rv = svga_compute_pll((par->chip == CHIP_365_TRIO3D) ? &s3_trio3d_pll : &s3_pll,
351 1000000000 / pixclock, &m, &n, &r, info->node);
338 if (rv < 0) { 352 if (rv < 0) {
339 printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node); 353 printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node);
340 return; 354 return;
341 } 355 }
342 356
343 /* Set VGA misc register */ 357 /* Set VGA misc register */
344 regval = vga_r(NULL, VGA_MIS_R); 358 regval = vga_r(par->state.vgabase, VGA_MIS_R);
345 vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 359 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
346 360
347 /* Set S3 clock registers */ 361 /* Set S3 clock registers */
348 if (par->chip == CHIP_360_TRIO3D_1X || 362 if (par->chip == CHIP_360_TRIO3D_1X ||
349 par->chip == CHIP_362_TRIO3D_2X || 363 par->chip == CHIP_362_TRIO3D_2X ||
350 par->chip == CHIP_368_TRIO3D_2X) { 364 par->chip == CHIP_368_TRIO3D_2X) {
351 vga_wseq(NULL, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */ 365 vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */
352 vga_wseq(NULL, 0x29, r >> 2); /* remaining highest bit of r */ 366 vga_wseq(par->state.vgabase, 0x29, r >> 2); /* remaining highest bit of r */
353 } else 367 } else
354 vga_wseq(NULL, 0x12, (n - 2) | (r << 5)); 368 vga_wseq(par->state.vgabase, 0x12, (n - 2) | (r << 5));
355 vga_wseq(NULL, 0x13, m - 2); 369 vga_wseq(par->state.vgabase, 0x13, m - 2);
356 370
357 udelay(1000); 371 udelay(1000);
358 372
359 /* Activate clock - write 0, 1, 0 to seq/15 bit 5 */ 373 /* Activate clock - write 0, 1, 0 to seq/15 bit 5 */
360 regval = vga_rseq (NULL, 0x15); /* | 0x80; */ 374 regval = vga_rseq (par->state.vgabase, 0x15); /* | 0x80; */
361 vga_wseq(NULL, 0x15, regval & ~(1<<5)); 375 vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5));
362 vga_wseq(NULL, 0x15, regval | (1<<5)); 376 vga_wseq(par->state.vgabase, 0x15, regval | (1<<5));
363 vga_wseq(NULL, 0x15, regval & ~(1<<5)); 377 vga_wseq(par->state.vgabase, 0x15, regval & ~(1<<5));
364} 378}
365 379
366 380
@@ -372,7 +386,10 @@ static int s3fb_open(struct fb_info *info, int user)
372 386
373 mutex_lock(&(par->open_lock)); 387 mutex_lock(&(par->open_lock));
374 if (par->ref_count == 0) { 388 if (par->ref_count == 0) {
389 void __iomem *vgabase = par->state.vgabase;
390
375 memset(&(par->state), 0, sizeof(struct vgastate)); 391 memset(&(par->state), 0, sizeof(struct vgastate));
392 par->state.vgabase = vgabase;
376 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 393 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
377 par->state.num_crtc = 0x70; 394 par->state.num_crtc = 0x70;
378 par->state.num_seq = 0x20; 395 par->state.num_seq = 0x20;
@@ -470,6 +487,7 @@ static int s3fb_set_par(struct fb_info *info)
470 struct s3fb_info *par = info->par; 487 struct s3fb_info *par = info->par;
471 u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes; 488 u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes;
472 u32 bpp = info->var.bits_per_pixel; 489 u32 bpp = info->var.bits_per_pixel;
490 u32 htotal, hsstart;
473 491
474 if (bpp != 0) { 492 if (bpp != 0) {
475 info->fix.ypanstep = 1; 493 info->fix.ypanstep = 1;
@@ -504,99 +522,112 @@ static int s3fb_set_par(struct fb_info *info)
504 info->var.activate = FB_ACTIVATE_NOW; 522 info->var.activate = FB_ACTIVATE_NOW;
505 523
506 /* Unlock registers */ 524 /* Unlock registers */
507 vga_wcrt(NULL, 0x38, 0x48); 525 vga_wcrt(par->state.vgabase, 0x38, 0x48);
508 vga_wcrt(NULL, 0x39, 0xA5); 526 vga_wcrt(par->state.vgabase, 0x39, 0xA5);
509 vga_wseq(NULL, 0x08, 0x06); 527 vga_wseq(par->state.vgabase, 0x08, 0x06);
510 svga_wcrt_mask(0x11, 0x00, 0x80); 528 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
511 529
512 /* Blank screen and turn off sync */ 530 /* Blank screen and turn off sync */
513 svga_wseq_mask(0x01, 0x20, 0x20); 531 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
514 svga_wcrt_mask(0x17, 0x00, 0x80); 532 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
515 533
516 /* Set default values */ 534 /* Set default values */
517 svga_set_default_gfx_regs(); 535 svga_set_default_gfx_regs(par->state.vgabase);
518 svga_set_default_atc_regs(); 536 svga_set_default_atc_regs(par->state.vgabase);
519 svga_set_default_seq_regs(); 537 svga_set_default_seq_regs(par->state.vgabase);
520 svga_set_default_crt_regs(); 538 svga_set_default_crt_regs(par->state.vgabase);
521 svga_wcrt_multi(s3_line_compare_regs, 0xFFFFFFFF); 539 svga_wcrt_multi(par->state.vgabase, s3_line_compare_regs, 0xFFFFFFFF);
522 svga_wcrt_multi(s3_start_address_regs, 0); 540 svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, 0);
523 541
524 /* S3 specific initialization */ 542 /* S3 specific initialization */
525 svga_wcrt_mask(0x58, 0x10, 0x10); /* enable linear framebuffer */ 543 svga_wcrt_mask(par->state.vgabase, 0x58, 0x10, 0x10); /* enable linear framebuffer */
526 svga_wcrt_mask(0x31, 0x08, 0x08); /* enable sequencer access to framebuffer above 256 kB */ 544 svga_wcrt_mask(par->state.vgabase, 0x31, 0x08, 0x08); /* enable sequencer access to framebuffer above 256 kB */
527 545
528/* svga_wcrt_mask(0x33, 0x08, 0x08); */ /* DDR ? */ 546/* svga_wcrt_mask(par->state.vgabase, 0x33, 0x08, 0x08); */ /* DDR ? */
529/* svga_wcrt_mask(0x43, 0x01, 0x01); */ /* DDR ? */ 547/* svga_wcrt_mask(par->state.vgabase, 0x43, 0x01, 0x01); */ /* DDR ? */
530 svga_wcrt_mask(0x33, 0x00, 0x08); /* no DDR ? */ 548 svga_wcrt_mask(par->state.vgabase, 0x33, 0x00, 0x08); /* no DDR ? */
531 svga_wcrt_mask(0x43, 0x00, 0x01); /* no DDR ? */ 549 svga_wcrt_mask(par->state.vgabase, 0x43, 0x00, 0x01); /* no DDR ? */
532 550
533 svga_wcrt_mask(0x5D, 0x00, 0x28); /* Clear strange HSlen bits */ 551 svga_wcrt_mask(par->state.vgabase, 0x5D, 0x00, 0x28); /* Clear strange HSlen bits */
534 552
535/* svga_wcrt_mask(0x58, 0x03, 0x03); */ 553/* svga_wcrt_mask(par->state.vgabase, 0x58, 0x03, 0x03); */
536 554
537/* svga_wcrt_mask(0x53, 0x12, 0x13); */ /* enable MMIO */ 555/* svga_wcrt_mask(par->state.vgabase, 0x53, 0x12, 0x13); */ /* enable MMIO */
538/* svga_wcrt_mask(0x40, 0x08, 0x08); */ /* enable write buffer */ 556/* svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08); */ /* enable write buffer */
539 557
540 558
541 /* Set the offset register */ 559 /* Set the offset register */
542 pr_debug("fb%d: offset register : %d\n", info->node, offset_value); 560 pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
543 svga_wcrt_multi(s3_offset_regs, offset_value); 561 svga_wcrt_multi(par->state.vgabase, s3_offset_regs, offset_value);
544 562
545 if (par->chip != CHIP_360_TRIO3D_1X && 563 if (par->chip != CHIP_360_TRIO3D_1X &&
546 par->chip != CHIP_362_TRIO3D_2X && 564 par->chip != CHIP_362_TRIO3D_2X &&
547 par->chip != CHIP_368_TRIO3D_2X) { 565 par->chip != CHIP_368_TRIO3D_2X) {
548 vga_wcrt(NULL, 0x54, 0x18); /* M parameter */ 566 vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */
549 vga_wcrt(NULL, 0x60, 0xff); /* N parameter */ 567 vga_wcrt(par->state.vgabase, 0x60, 0xff); /* N parameter */
550 vga_wcrt(NULL, 0x61, 0xff); /* L parameter */ 568 vga_wcrt(par->state.vgabase, 0x61, 0xff); /* L parameter */
551 vga_wcrt(NULL, 0x62, 0xff); /* L parameter */ 569 vga_wcrt(par->state.vgabase, 0x62, 0xff); /* L parameter */
552 } 570 }
553 571
554 vga_wcrt(NULL, 0x3A, 0x35); 572 vga_wcrt(par->state.vgabase, 0x3A, 0x35);
555 svga_wattr(0x33, 0x00); 573 svga_wattr(par->state.vgabase, 0x33, 0x00);
556 574
557 if (info->var.vmode & FB_VMODE_DOUBLE) 575 if (info->var.vmode & FB_VMODE_DOUBLE)
558 svga_wcrt_mask(0x09, 0x80, 0x80); 576 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
559 else 577 else
560 svga_wcrt_mask(0x09, 0x00, 0x80); 578 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
561 579
562 if (info->var.vmode & FB_VMODE_INTERLACED) 580 if (info->var.vmode & FB_VMODE_INTERLACED)
563 svga_wcrt_mask(0x42, 0x20, 0x20); 581 svga_wcrt_mask(par->state.vgabase, 0x42, 0x20, 0x20);
564 else 582 else
565 svga_wcrt_mask(0x42, 0x00, 0x20); 583 svga_wcrt_mask(par->state.vgabase, 0x42, 0x00, 0x20);
566 584
567 /* Disable hardware graphics cursor */ 585 /* Disable hardware graphics cursor */
568 svga_wcrt_mask(0x45, 0x00, 0x01); 586 svga_wcrt_mask(par->state.vgabase, 0x45, 0x00, 0x01);
569 /* Disable Streams engine */ 587 /* Disable Streams engine */
570 svga_wcrt_mask(0x67, 0x00, 0x0C); 588 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0x0C);
571 589
572 mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix)); 590 mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix));
573 591
574 /* S3 virge DX hack */ 592 /* S3 virge DX hack */
575 if (par->chip == CHIP_375_VIRGE_DX) { 593 if (par->chip == CHIP_375_VIRGE_DX) {
576 vga_wcrt(NULL, 0x86, 0x80); 594 vga_wcrt(par->state.vgabase, 0x86, 0x80);
577 vga_wcrt(NULL, 0x90, 0x00); 595 vga_wcrt(par->state.vgabase, 0x90, 0x00);
578 } 596 }
579 597
580 /* S3 virge VX hack */ 598 /* S3 virge VX hack */
581 if (par->chip == CHIP_988_VIRGE_VX) { 599 if (par->chip == CHIP_988_VIRGE_VX) {
582 vga_wcrt(NULL, 0x50, 0x00); 600 vga_wcrt(par->state.vgabase, 0x50, 0x00);
583 vga_wcrt(NULL, 0x67, 0x50); 601 vga_wcrt(par->state.vgabase, 0x67, 0x50);
584 602
585 vga_wcrt(NULL, 0x63, (mode <= 2) ? 0x90 : 0x09); 603 vga_wcrt(par->state.vgabase, 0x63, (mode <= 2) ? 0x90 : 0x09);
586 vga_wcrt(NULL, 0x66, 0x90); 604 vga_wcrt(par->state.vgabase, 0x66, 0x90);
587 } 605 }
588 606
589 if (par->chip == CHIP_360_TRIO3D_1X || 607 if (par->chip == CHIP_360_TRIO3D_1X ||
590 par->chip == CHIP_362_TRIO3D_2X || 608 par->chip == CHIP_362_TRIO3D_2X ||
591 par->chip == CHIP_368_TRIO3D_2X) { 609 par->chip == CHIP_368_TRIO3D_2X ||
610 par->chip == CHIP_365_TRIO3D ||
611 par->chip == CHIP_375_VIRGE_DX ||
612 par->chip == CHIP_385_VIRGE_GX) {
592 dbytes = info->var.xres * ((bpp+7)/8); 613 dbytes = info->var.xres * ((bpp+7)/8);
593 vga_wcrt(NULL, 0x91, (dbytes + 7) / 8); 614 vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8);
594 vga_wcrt(NULL, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80); 615 vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80);
595 616
596 vga_wcrt(NULL, 0x66, 0x81); 617 vga_wcrt(par->state.vgabase, 0x66, 0x81);
597 } 618 }
598 619
599 svga_wcrt_mask(0x31, 0x00, 0x40); 620 if (par->chip == CHIP_356_VIRGE_GX2 ||
621 par->chip == CHIP_357_VIRGE_GX2P ||
622 par->chip == CHIP_359_VIRGE_GX2P ||
623 par->chip == CHIP_360_TRIO3D_1X ||
624 par->chip == CHIP_362_TRIO3D_2X ||
625 par->chip == CHIP_368_TRIO3D_2X)
626 vga_wcrt(par->state.vgabase, 0x34, 0x00);
627 else /* enable Data Transfer Position Control (DTPC) */
628 vga_wcrt(par->state.vgabase, 0x34, 0x10);
629
630 svga_wcrt_mask(par->state.vgabase, 0x31, 0x00, 0x40);
600 multiplex = 0; 631 multiplex = 0;
601 hmul = 1; 632 hmul = 1;
602 633
@@ -604,51 +635,51 @@ static int s3fb_set_par(struct fb_info *info)
604 switch (mode) { 635 switch (mode) {
605 case 0: 636 case 0:
606 pr_debug("fb%d: text mode\n", info->node); 637 pr_debug("fb%d: text mode\n", info->node);
607 svga_set_textmode_vga_regs(); 638 svga_set_textmode_vga_regs(par->state.vgabase);
608 639
609 /* Set additional registers like in 8-bit mode */ 640 /* Set additional registers like in 8-bit mode */
610 svga_wcrt_mask(0x50, 0x00, 0x30); 641 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
611 svga_wcrt_mask(0x67, 0x00, 0xF0); 642 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
612 643
613 /* Disable enhanced mode */ 644 /* Disable enhanced mode */
614 svga_wcrt_mask(0x3A, 0x00, 0x30); 645 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
615 646
616 if (fasttext) { 647 if (fasttext) {
617 pr_debug("fb%d: high speed text mode set\n", info->node); 648 pr_debug("fb%d: high speed text mode set\n", info->node);
618 svga_wcrt_mask(0x31, 0x40, 0x40); 649 svga_wcrt_mask(par->state.vgabase, 0x31, 0x40, 0x40);
619 } 650 }
620 break; 651 break;
621 case 1: 652 case 1:
622 pr_debug("fb%d: 4 bit pseudocolor\n", info->node); 653 pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
623 vga_wgfx(NULL, VGA_GFX_MODE, 0x40); 654 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
624 655
625 /* Set additional registers like in 8-bit mode */ 656 /* Set additional registers like in 8-bit mode */
626 svga_wcrt_mask(0x50, 0x00, 0x30); 657 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
627 svga_wcrt_mask(0x67, 0x00, 0xF0); 658 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
628 659
629 /* disable enhanced mode */ 660 /* disable enhanced mode */
630 svga_wcrt_mask(0x3A, 0x00, 0x30); 661 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
631 break; 662 break;
632 case 2: 663 case 2:
633 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); 664 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
634 665
635 /* Set additional registers like in 8-bit mode */ 666 /* Set additional registers like in 8-bit mode */
636 svga_wcrt_mask(0x50, 0x00, 0x30); 667 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
637 svga_wcrt_mask(0x67, 0x00, 0xF0); 668 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
638 669
639 /* disable enhanced mode */ 670 /* disable enhanced mode */
640 svga_wcrt_mask(0x3A, 0x00, 0x30); 671 svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);
641 break; 672 break;
642 case 3: 673 case 3:
643 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 674 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
644 svga_wcrt_mask(0x50, 0x00, 0x30); 675 svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);
645 if (info->var.pixclock > 20000 || 676 if (info->var.pixclock > 20000 ||
646 par->chip == CHIP_360_TRIO3D_1X || 677 par->chip == CHIP_360_TRIO3D_1X ||
647 par->chip == CHIP_362_TRIO3D_2X || 678 par->chip == CHIP_362_TRIO3D_2X ||
648 par->chip == CHIP_368_TRIO3D_2X) 679 par->chip == CHIP_368_TRIO3D_2X)
649 svga_wcrt_mask(0x67, 0x00, 0xF0); 680 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
650 else { 681 else {
651 svga_wcrt_mask(0x67, 0x10, 0xF0); 682 svga_wcrt_mask(par->state.vgabase, 0x67, 0x10, 0xF0);
652 multiplex = 1; 683 multiplex = 1;
653 } 684 }
654 break; 685 break;
@@ -656,12 +687,21 @@ static int s3fb_set_par(struct fb_info *info)
656 pr_debug("fb%d: 5/5/5 truecolor\n", info->node); 687 pr_debug("fb%d: 5/5/5 truecolor\n", info->node);
657 if (par->chip == CHIP_988_VIRGE_VX) { 688 if (par->chip == CHIP_988_VIRGE_VX) {
658 if (info->var.pixclock > 20000) 689 if (info->var.pixclock > 20000)
659 svga_wcrt_mask(0x67, 0x20, 0xF0); 690 svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0);
660 else 691 else
661 svga_wcrt_mask(0x67, 0x30, 0xF0); 692 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
693 } else if (par->chip == CHIP_365_TRIO3D) {
694 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
695 if (info->var.pixclock > 8695) {
696 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
697 hmul = 2;
698 } else {
699 svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0);
700 multiplex = 1;
701 }
662 } else { 702 } else {
663 svga_wcrt_mask(0x50, 0x10, 0x30); 703 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
664 svga_wcrt_mask(0x67, 0x30, 0xF0); 704 svga_wcrt_mask(par->state.vgabase, 0x67, 0x30, 0xF0);
665 if (par->chip != CHIP_360_TRIO3D_1X && 705 if (par->chip != CHIP_360_TRIO3D_1X &&
666 par->chip != CHIP_362_TRIO3D_2X && 706 par->chip != CHIP_362_TRIO3D_2X &&
667 par->chip != CHIP_368_TRIO3D_2X) 707 par->chip != CHIP_368_TRIO3D_2X)
@@ -672,12 +712,21 @@ static int s3fb_set_par(struct fb_info *info)
672 pr_debug("fb%d: 5/6/5 truecolor\n", info->node); 712 pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
673 if (par->chip == CHIP_988_VIRGE_VX) { 713 if (par->chip == CHIP_988_VIRGE_VX) {
674 if (info->var.pixclock > 20000) 714 if (info->var.pixclock > 20000)
675 svga_wcrt_mask(0x67, 0x40, 0xF0); 715 svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0);
676 else 716 else
677 svga_wcrt_mask(0x67, 0x50, 0xF0); 717 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
718 } else if (par->chip == CHIP_365_TRIO3D) {
719 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
720 if (info->var.pixclock > 8695) {
721 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
722 hmul = 2;
723 } else {
724 svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0);
725 multiplex = 1;
726 }
678 } else { 727 } else {
679 svga_wcrt_mask(0x50, 0x10, 0x30); 728 svga_wcrt_mask(par->state.vgabase, 0x50, 0x10, 0x30);
680 svga_wcrt_mask(0x67, 0x50, 0xF0); 729 svga_wcrt_mask(par->state.vgabase, 0x67, 0x50, 0xF0);
681 if (par->chip != CHIP_360_TRIO3D_1X && 730 if (par->chip != CHIP_360_TRIO3D_1X &&
682 par->chip != CHIP_362_TRIO3D_2X && 731 par->chip != CHIP_362_TRIO3D_2X &&
683 par->chip != CHIP_368_TRIO3D_2X) 732 par->chip != CHIP_368_TRIO3D_2X)
@@ -687,12 +736,12 @@ static int s3fb_set_par(struct fb_info *info)
687 case 6: 736 case 6:
688 /* VIRGE VX case */ 737 /* VIRGE VX case */
689 pr_debug("fb%d: 8/8/8 truecolor\n", info->node); 738 pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
690 svga_wcrt_mask(0x67, 0xD0, 0xF0); 739 svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);
691 break; 740 break;
692 case 7: 741 case 7:
693 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node); 742 pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node);
694 svga_wcrt_mask(0x50, 0x30, 0x30); 743 svga_wcrt_mask(par->state.vgabase, 0x50, 0x30, 0x30);
695 svga_wcrt_mask(0x67, 0xD0, 0xF0); 744 svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);
696 break; 745 break;
697 default: 746 default:
698 printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node); 747 printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node);
@@ -700,25 +749,30 @@ static int s3fb_set_par(struct fb_info *info)
700 } 749 }
701 750
702 if (par->chip != CHIP_988_VIRGE_VX) { 751 if (par->chip != CHIP_988_VIRGE_VX) {
703 svga_wseq_mask(0x15, multiplex ? 0x10 : 0x00, 0x10); 752 svga_wseq_mask(par->state.vgabase, 0x15, multiplex ? 0x10 : 0x00, 0x10);
704 svga_wseq_mask(0x18, multiplex ? 0x80 : 0x00, 0x80); 753 svga_wseq_mask(par->state.vgabase, 0x18, multiplex ? 0x80 : 0x00, 0x80);
705 } 754 }
706 755
707 s3_set_pixclock(info, info->var.pixclock); 756 s3_set_pixclock(info, info->var.pixclock);
708 svga_set_timings(&s3_timing_regs, &(info->var), hmul, 1, 757 svga_set_timings(par->state.vgabase, &s3_timing_regs, &(info->var), hmul, 1,
709 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 758 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1,
710 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1, 759 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
711 hmul, info->node); 760 hmul, info->node);
712 761
713 /* Set interlaced mode start/end register */ 762 /* Set interlaced mode start/end register */
714 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len; 763 htotal = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
715 value = ((value * hmul) / 8) - 5; 764 htotal = ((htotal * hmul) / 8) - 5;
716 vga_wcrt(NULL, 0x3C, (value + 1) / 2); 765 vga_wcrt(par->state.vgabase, 0x3C, (htotal + 1) / 2);
766
767 /* Set Data Transfer Position */
768 hsstart = ((info->var.xres + info->var.right_margin) * hmul) / 8;
769 value = clamp((htotal + hsstart + 1) / 2, hsstart + 4, htotal + 1);
770 svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value);
717 771
718 memset_io(info->screen_base, 0x00, screen_size); 772 memset_io(info->screen_base, 0x00, screen_size);
719 /* Device and screen back on */ 773 /* Device and screen back on */
720 svga_wcrt_mask(0x17, 0x80, 0x80); 774 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
721 svga_wseq_mask(0x01, 0x00, 0x20); 775 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
722 776
723 return 0; 777 return 0;
724} 778}
@@ -788,31 +842,33 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
788 842
789static int s3fb_blank(int blank_mode, struct fb_info *info) 843static int s3fb_blank(int blank_mode, struct fb_info *info)
790{ 844{
845 struct s3fb_info *par = info->par;
846
791 switch (blank_mode) { 847 switch (blank_mode) {
792 case FB_BLANK_UNBLANK: 848 case FB_BLANK_UNBLANK:
793 pr_debug("fb%d: unblank\n", info->node); 849 pr_debug("fb%d: unblank\n", info->node);
794 svga_wcrt_mask(0x56, 0x00, 0x06); 850 svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
795 svga_wseq_mask(0x01, 0x00, 0x20); 851 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
796 break; 852 break;
797 case FB_BLANK_NORMAL: 853 case FB_BLANK_NORMAL:
798 pr_debug("fb%d: blank\n", info->node); 854 pr_debug("fb%d: blank\n", info->node);
799 svga_wcrt_mask(0x56, 0x00, 0x06); 855 svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);
800 svga_wseq_mask(0x01, 0x20, 0x20); 856 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
801 break; 857 break;
802 case FB_BLANK_HSYNC_SUSPEND: 858 case FB_BLANK_HSYNC_SUSPEND:
803 pr_debug("fb%d: hsync\n", info->node); 859 pr_debug("fb%d: hsync\n", info->node);
804 svga_wcrt_mask(0x56, 0x02, 0x06); 860 svga_wcrt_mask(par->state.vgabase, 0x56, 0x02, 0x06);
805 svga_wseq_mask(0x01, 0x20, 0x20); 861 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
806 break; 862 break;
807 case FB_BLANK_VSYNC_SUSPEND: 863 case FB_BLANK_VSYNC_SUSPEND:
808 pr_debug("fb%d: vsync\n", info->node); 864 pr_debug("fb%d: vsync\n", info->node);
809 svga_wcrt_mask(0x56, 0x04, 0x06); 865 svga_wcrt_mask(par->state.vgabase, 0x56, 0x04, 0x06);
810 svga_wseq_mask(0x01, 0x20, 0x20); 866 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
811 break; 867 break;
812 case FB_BLANK_POWERDOWN: 868 case FB_BLANK_POWERDOWN:
813 pr_debug("fb%d: sync down\n", info->node); 869 pr_debug("fb%d: sync down\n", info->node);
814 svga_wcrt_mask(0x56, 0x06, 0x06); 870 svga_wcrt_mask(par->state.vgabase, 0x56, 0x06, 0x06);
815 svga_wseq_mask(0x01, 0x20, 0x20); 871 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
816 break; 872 break;
817 } 873 }
818 874
@@ -822,8 +878,9 @@ static int s3fb_blank(int blank_mode, struct fb_info *info)
822 878
823/* Pan the display */ 879/* Pan the display */
824 880
825static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { 881static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
826 882{
883 struct s3fb_info *par = info->par;
827 unsigned int offset; 884 unsigned int offset;
828 885
829 /* Calculate the offset */ 886 /* Calculate the offset */
@@ -837,7 +894,7 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
837 } 894 }
838 895
839 /* Set the offset */ 896 /* Set the offset */
840 svga_wcrt_multi(s3_start_address_regs, offset); 897 svga_wcrt_multi(par->state.vgabase, s3_start_address_regs, offset);
841 898
842 return 0; 899 return 0;
843} 900}
@@ -863,12 +920,14 @@ static struct fb_ops s3fb_ops = {
863 920
864/* ------------------------------------------------------------------------- */ 921/* ------------------------------------------------------------------------- */
865 922
866static int __devinit s3_identification(int chip) 923static int __devinit s3_identification(struct s3fb_info *par)
867{ 924{
925 int chip = par->chip;
926
868 if (chip == CHIP_XXX_TRIO) { 927 if (chip == CHIP_XXX_TRIO) {
869 u8 cr30 = vga_rcrt(NULL, 0x30); 928 u8 cr30 = vga_rcrt(par->state.vgabase, 0x30);
870 u8 cr2e = vga_rcrt(NULL, 0x2e); 929 u8 cr2e = vga_rcrt(par->state.vgabase, 0x2e);
871 u8 cr2f = vga_rcrt(NULL, 0x2f); 930 u8 cr2f = vga_rcrt(par->state.vgabase, 0x2f);
872 931
873 if ((cr30 == 0xE0) || (cr30 == 0xE1)) { 932 if ((cr30 == 0xE0) || (cr30 == 0xE1)) {
874 if (cr2e == 0x10) 933 if (cr2e == 0x10)
@@ -883,7 +942,7 @@ static int __devinit s3_identification(int chip)
883 } 942 }
884 943
885 if (chip == CHIP_XXX_TRIO64V2_DXGX) { 944 if (chip == CHIP_XXX_TRIO64V2_DXGX) {
886 u8 cr6f = vga_rcrt(NULL, 0x6f); 945 u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f);
887 946
888 if (! (cr6f & 0x01)) 947 if (! (cr6f & 0x01))
889 return CHIP_775_TRIO64V2_DX; 948 return CHIP_775_TRIO64V2_DX;
@@ -892,7 +951,7 @@ static int __devinit s3_identification(int chip)
892 } 951 }
893 952
894 if (chip == CHIP_XXX_VIRGE_DXGX) { 953 if (chip == CHIP_XXX_VIRGE_DXGX) {
895 u8 cr6f = vga_rcrt(NULL, 0x6f); 954 u8 cr6f = vga_rcrt(par->state.vgabase, 0x6f);
896 955
897 if (! (cr6f & 0x01)) 956 if (! (cr6f & 0x01))
898 return CHIP_375_VIRGE_DX; 957 return CHIP_375_VIRGE_DX;
@@ -901,7 +960,7 @@ static int __devinit s3_identification(int chip)
901 } 960 }
902 961
903 if (chip == CHIP_36X_TRIO3D_1X_2X) { 962 if (chip == CHIP_36X_TRIO3D_1X_2X) {
904 switch (vga_rcrt(NULL, 0x2f)) { 963 switch (vga_rcrt(par->state.vgabase, 0x2f)) {
905 case 0x00: 964 case 0x00:
906 return CHIP_360_TRIO3D_1X; 965 return CHIP_360_TRIO3D_1X;
907 case 0x01: 966 case 0x01:
@@ -919,6 +978,8 @@ static int __devinit s3_identification(int chip)
919 978
920static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 979static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
921{ 980{
981 struct pci_bus_region bus_reg;
982 struct resource vga_res;
922 struct fb_info *info; 983 struct fb_info *info;
923 struct s3fb_info *par; 984 struct s3fb_info *par;
924 int rc; 985 int rc;
@@ -968,31 +1029,42 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
968 goto err_iomap; 1029 goto err_iomap;
969 } 1030 }
970 1031
1032 bus_reg.start = 0;
1033 bus_reg.end = 64 * 1024;
1034
1035 vga_res.flags = IORESOURCE_IO;
1036
1037 pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
1038
1039 par->state.vgabase = (void __iomem *) vga_res.start;
1040
971 /* Unlock regs */ 1041 /* Unlock regs */
972 cr38 = vga_rcrt(NULL, 0x38); 1042 cr38 = vga_rcrt(par->state.vgabase, 0x38);
973 cr39 = vga_rcrt(NULL, 0x39); 1043 cr39 = vga_rcrt(par->state.vgabase, 0x39);
974 vga_wseq(NULL, 0x08, 0x06); 1044 vga_wseq(par->state.vgabase, 0x08, 0x06);
975 vga_wcrt(NULL, 0x38, 0x48); 1045 vga_wcrt(par->state.vgabase, 0x38, 0x48);
976 vga_wcrt(NULL, 0x39, 0xA5); 1046 vga_wcrt(par->state.vgabase, 0x39, 0xA5);
977 1047
978 /* Identify chip type */ 1048 /* Identify chip type */
979 par->chip = id->driver_data & CHIP_MASK; 1049 par->chip = id->driver_data & CHIP_MASK;
980 par->rev = vga_rcrt(NULL, 0x2f); 1050 par->rev = vga_rcrt(par->state.vgabase, 0x2f);
981 if (par->chip & CHIP_UNDECIDED_FLAG) 1051 if (par->chip & CHIP_UNDECIDED_FLAG)
982 par->chip = s3_identification(par->chip); 1052 par->chip = s3_identification(par);
983 1053
984 /* Find how many physical memory there is on card */ 1054 /* Find how many physical memory there is on card */
985 /* 0x36 register is accessible even if other registers are locked */ 1055 /* 0x36 register is accessible even if other registers are locked */
986 regval = vga_rcrt(NULL, 0x36); 1056 regval = vga_rcrt(par->state.vgabase, 0x36);
987 if (par->chip == CHIP_360_TRIO3D_1X || 1057 if (par->chip == CHIP_360_TRIO3D_1X ||
988 par->chip == CHIP_362_TRIO3D_2X || 1058 par->chip == CHIP_362_TRIO3D_2X ||
989 par->chip == CHIP_368_TRIO3D_2X) { 1059 par->chip == CHIP_368_TRIO3D_2X ||
1060 par->chip == CHIP_365_TRIO3D) {
990 switch ((regval & 0xE0) >> 5) { 1061 switch ((regval & 0xE0) >> 5) {
991 case 0: /* 8MB -- only 4MB usable for display */ 1062 case 0: /* 8MB -- only 4MB usable for display */
992 case 1: /* 4MB with 32-bit bus */ 1063 case 1: /* 4MB with 32-bit bus */
993 case 2: /* 4MB */ 1064 case 2: /* 4MB */
994 info->screen_size = 4 << 20; 1065 info->screen_size = 4 << 20;
995 break; 1066 break;
1067 case 4: /* 2MB on 365 Trio3D */
996 case 6: /* 2MB */ 1068 case 6: /* 2MB */
997 info->screen_size = 2 << 20; 1069 info->screen_size = 2 << 20;
998 break; 1070 break;
@@ -1002,13 +1074,13 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1002 info->fix.smem_len = info->screen_size; 1074 info->fix.smem_len = info->screen_size;
1003 1075
1004 /* Find MCLK frequency */ 1076 /* Find MCLK frequency */
1005 regval = vga_rseq(NULL, 0x10); 1077 regval = vga_rseq(par->state.vgabase, 0x10);
1006 par->mclk_freq = ((vga_rseq(NULL, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2); 1078 par->mclk_freq = ((vga_rseq(par->state.vgabase, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2);
1007 par->mclk_freq = par->mclk_freq >> (regval >> 5); 1079 par->mclk_freq = par->mclk_freq >> (regval >> 5);
1008 1080
1009 /* Restore locks */ 1081 /* Restore locks */
1010 vga_wcrt(NULL, 0x38, cr38); 1082 vga_wcrt(par->state.vgabase, 0x38, cr38);
1011 vga_wcrt(NULL, 0x39, cr39); 1083 vga_wcrt(par->state.vgabase, 0x39, cr39);
1012 1084
1013 strcpy(info->fix.id, s3_names [par->chip]); 1085 strcpy(info->fix.id, s3_names [par->chip]);
1014 info->fix.mmio_start = 0; 1086 info->fix.mmio_start = 0;
@@ -1027,6 +1099,14 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1027 goto err_find_mode; 1099 goto err_find_mode;
1028 } 1100 }
1029 1101
1102 /* maximize virtual vertical size for fast scrolling */
1103 info->var.yres_virtual = info->fix.smem_len * 8 /
1104 (info->var.bits_per_pixel * info->var.xres_virtual);
1105 if (info->var.yres_virtual < info->var.yres) {
1106 dev_err(info->device, "virtual vertical size smaller than real\n");
1107 goto err_find_mode;
1108 }
1109
1030 rc = fb_alloc_cmap(&info->cmap, 256, 0); 1110 rc = fb_alloc_cmap(&info->cmap, 256, 0);
1031 if (rc < 0) { 1111 if (rc < 0) {
1032 dev_err(info->device, "cannot allocate colormap\n"); 1112 dev_err(info->device, "cannot allocate colormap\n");
@@ -1044,8 +1124,8 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1044 1124
1045 if (par->chip == CHIP_UNKNOWN) 1125 if (par->chip == CHIP_UNKNOWN)
1046 printk(KERN_INFO "fb%d: unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n", 1126 printk(KERN_INFO "fb%d: unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n",
1047 info->node, vga_rcrt(NULL, 0x2d), vga_rcrt(NULL, 0x2e), 1127 info->node, vga_rcrt(par->state.vgabase, 0x2d), vga_rcrt(par->state.vgabase, 0x2e),
1048 vga_rcrt(NULL, 0x2f), vga_rcrt(NULL, 0x30)); 1128 vga_rcrt(par->state.vgabase, 0x2f), vga_rcrt(par->state.vgabase, 0x30));
1049 1129
1050 /* Record a reference to the driver data */ 1130 /* Record a reference to the driver data */
1051 pci_set_drvdata(dev, info); 1131 pci_set_drvdata(dev, info);
@@ -1192,6 +1272,7 @@ static struct pci_device_id s3_devices[] __devinitdata = {
1192 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P}, 1272 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P},
1193 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P}, 1273 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P},
1194 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X}, 1274 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X},
1275 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D},
1195 1276
1196 {0, 0, 0, 0, 0, 0, 0} 1277 {0, 0, 0, 0, 0, 0, 0}
1197}; 1278};
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c
index bea38fce247..8fe19582c46 100644
--- a/drivers/video/sh7760fb.c
+++ b/drivers/video/sh7760fb.c
@@ -459,14 +459,14 @@ static int __devinit sh7760fb_probe(struct platform_device *pdev)
459 } 459 }
460 460
461 par->ioarea = request_mem_region(res->start, 461 par->ioarea = request_mem_region(res->start,
462 (res->end - res->start), pdev->name); 462 resource_size(res), pdev->name);
463 if (!par->ioarea) { 463 if (!par->ioarea) {
464 dev_err(&pdev->dev, "mmio area busy\n"); 464 dev_err(&pdev->dev, "mmio area busy\n");
465 ret = -EBUSY; 465 ret = -EBUSY;
466 goto out_fb; 466 goto out_fb;
467 } 467 }
468 468
469 par->base = ioremap_nocache(res->start, res->end - res->start + 1); 469 par->base = ioremap_nocache(res->start, resource_size(res));
470 if (!par->base) { 470 if (!par->base) {
471 dev_err(&pdev->dev, "cannot remap\n"); 471 dev_err(&pdev->dev, "cannot remap\n");
472 ret = -ENODEV; 472 ret = -ENODEV;
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index bf2629f83f4..757665bc500 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -1088,8 +1088,9 @@ static struct backlight_device *sh_mobile_lcdc_bl_probe(struct device *parent,
1088 1088
1089 bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch, 1089 bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch,
1090 &sh_mobile_lcdc_bl_ops, NULL); 1090 &sh_mobile_lcdc_bl_ops, NULL);
1091 if (!bl) { 1091 if (IS_ERR(bl)) {
1092 dev_err(parent, "unable to register backlight device\n"); 1092 dev_err(parent, "unable to register backlight device: %ld\n",
1093 PTR_ERR(bl));
1093 return NULL; 1094 return NULL;
1094 } 1095 }
1095 1096
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index eac7a01925f..1987f1b7212 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -495,6 +495,7 @@ struct sis_video_info {
495 unsigned int refresh_rate; 495 unsigned int refresh_rate;
496 496
497 unsigned int chip; 497 unsigned int chip;
498 unsigned int chip_real_id;
498 u8 revision_id; 499 u8 revision_id;
499 int sisvga_enabled; /* PCI device was enabled */ 500 int sisvga_enabled; /* PCI device was enabled */
500 501
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 2fb8c5a660f..75259845933 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4563,6 +4563,11 @@ sisfb_post_sis315330(struct pci_dev *pdev)
4563} 4563}
4564#endif 4564#endif
4565 4565
4566static inline int sisfb_xgi_is21(struct sis_video_info *ivideo)
4567{
4568 return ivideo->chip_real_id == XGI_21;
4569}
4570
4566static void __devinit 4571static void __devinit
4567sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay) 4572sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
4568{ 4573{
@@ -4627,11 +4632,11 @@ sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
4627 return 1; 4632 return 1;
4628} 4633}
4629 4634
4630static void __devinit 4635static int __devinit
4631sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) 4636sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
4632{ 4637{
4633 unsigned int buswidth, ranksize, channelab, mapsize; 4638 unsigned int buswidth, ranksize, channelab, mapsize;
4634 int i, j, k, l; 4639 int i, j, k, l, status;
4635 u8 reg, sr14; 4640 u8 reg, sr14;
4636 static const u8 dramsr13[12 * 5] = { 4641 static const u8 dramsr13[12 * 5] = {
4637 0x02, 0x0e, 0x0b, 0x80, 0x5d, 4642 0x02, 0x0e, 0x0b, 0x80, 0x5d,
@@ -4673,7 +4678,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
4673 SiS_SetReg(SISSR, 0x13, 0x35); 4678 SiS_SetReg(SISSR, 0x13, 0x35);
4674 SiS_SetReg(SISSR, 0x14, 0x41); 4679 SiS_SetReg(SISSR, 0x14, 0x41);
4675 /* TODO */ 4680 /* TODO */
4676 return; 4681 return -ENOMEM;
4677 } 4682 }
4678 4683
4679 /* Non-interleaving */ 4684 /* Non-interleaving */
@@ -4835,6 +4840,7 @@ bail_out:
4835 4840
4836 j = (ivideo->chip == XGI_20) ? 5 : 9; 4841 j = (ivideo->chip == XGI_20) ? 5 : 9;
4837 k = (ivideo->chip == XGI_20) ? 12 : 4; 4842 k = (ivideo->chip == XGI_20) ? 12 : 4;
4843 status = -EIO;
4838 4844
4839 for(i = 0; i < k; i++) { 4845 for(i = 0; i < k; i++) {
4840 4846
@@ -4868,11 +4874,15 @@ bail_out:
4868 SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0)); 4874 SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0));
4869 sisfb_post_xgi_delay(ivideo, 1); 4875 sisfb_post_xgi_delay(ivideo, 1);
4870 4876
4871 if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) 4877 if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) {
4878 status = 0;
4872 break; 4879 break;
4880 }
4873 } 4881 }
4874 4882
4875 iounmap(ivideo->video_vbase); 4883 iounmap(ivideo->video_vbase);
4884
4885 return status;
4876} 4886}
4877 4887
4878static void __devinit 4888static void __devinit
@@ -4931,6 +4941,175 @@ sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
4931 sisfb_post_xgi_delay(ivideo, 0x43); 4941 sisfb_post_xgi_delay(ivideo, 0x43);
4932} 4942}
4933 4943
4944static void __devinit
4945sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo, u8 regb)
4946{
4947 unsigned char *bios = ivideo->bios_abase;
4948 u8 v1;
4949
4950 SiS_SetReg(SISSR, 0x28, 0x64);
4951 SiS_SetReg(SISSR, 0x29, 0x63);
4952 sisfb_post_xgi_delay(ivideo, 15);
4953 SiS_SetReg(SISSR, 0x18, 0x00);
4954 SiS_SetReg(SISSR, 0x19, 0x20);
4955 SiS_SetReg(SISSR, 0x16, 0x00);
4956 SiS_SetReg(SISSR, 0x16, 0x80);
4957 SiS_SetReg(SISSR, 0x18, 0xc5);
4958 SiS_SetReg(SISSR, 0x19, 0x23);
4959 SiS_SetReg(SISSR, 0x16, 0x00);
4960 SiS_SetReg(SISSR, 0x16, 0x80);
4961 sisfb_post_xgi_delay(ivideo, 1);
4962 SiS_SetReg(SISCR, 0x97, 0x11);
4963 sisfb_post_xgi_setclocks(ivideo, regb);
4964 sisfb_post_xgi_delay(ivideo, 0x46);
4965 SiS_SetReg(SISSR, 0x18, 0xc5);
4966 SiS_SetReg(SISSR, 0x19, 0x23);
4967 SiS_SetReg(SISSR, 0x16, 0x00);
4968 SiS_SetReg(SISSR, 0x16, 0x80);
4969 sisfb_post_xgi_delay(ivideo, 1);
4970 SiS_SetReg(SISSR, 0x1b, 0x04);
4971 sisfb_post_xgi_delay(ivideo, 1);
4972 SiS_SetReg(SISSR, 0x1b, 0x00);
4973 sisfb_post_xgi_delay(ivideo, 1);
4974 v1 = 0x31;
4975 if (ivideo->haveXGIROM) {
4976 v1 = bios[0xf0];
4977 }
4978 SiS_SetReg(SISSR, 0x18, v1);
4979 SiS_SetReg(SISSR, 0x19, 0x06);
4980 SiS_SetReg(SISSR, 0x16, 0x04);
4981 SiS_SetReg(SISSR, 0x16, 0x84);
4982 sisfb_post_xgi_delay(ivideo, 1);
4983}
4984
4985static void __devinit
4986sisfb_post_xgi_ddr2_mrs_xg21(struct sis_video_info *ivideo)
4987{
4988 sisfb_post_xgi_setclocks(ivideo, 1);
4989
4990 SiS_SetReg(SISCR, 0x97, 0x11);
4991 sisfb_post_xgi_delay(ivideo, 0x46);
4992
4993 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS2 */
4994 SiS_SetReg(SISSR, 0x19, 0x80);
4995 SiS_SetReg(SISSR, 0x16, 0x05);
4996 SiS_SetReg(SISSR, 0x16, 0x85);
4997
4998 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS3 */
4999 SiS_SetReg(SISSR, 0x19, 0xc0);
5000 SiS_SetReg(SISSR, 0x16, 0x05);
5001 SiS_SetReg(SISSR, 0x16, 0x85);
5002
5003 SiS_SetReg(SISSR, 0x18, 0x00); /* EMRS1 */
5004 SiS_SetReg(SISSR, 0x19, 0x40);
5005 SiS_SetReg(SISSR, 0x16, 0x05);
5006 SiS_SetReg(SISSR, 0x16, 0x85);
5007
5008 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
5009 SiS_SetReg(SISSR, 0x19, 0x02);
5010 SiS_SetReg(SISSR, 0x16, 0x05);
5011 SiS_SetReg(SISSR, 0x16, 0x85);
5012 sisfb_post_xgi_delay(ivideo, 1);
5013
5014 SiS_SetReg(SISSR, 0x1b, 0x04);
5015 sisfb_post_xgi_delay(ivideo, 1);
5016
5017 SiS_SetReg(SISSR, 0x1b, 0x00);
5018 sisfb_post_xgi_delay(ivideo, 1);
5019
5020 SiS_SetReg(SISSR, 0x18, 0x42); /* MRS1 */
5021 SiS_SetReg(SISSR, 0x19, 0x00);
5022 SiS_SetReg(SISSR, 0x16, 0x05);
5023 SiS_SetReg(SISSR, 0x16, 0x85);
5024 sisfb_post_xgi_delay(ivideo, 1);
5025}
5026
5027static void __devinit
5028sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
5029{
5030 unsigned char *bios = ivideo->bios_abase;
5031 static const u8 cs158[8] = {
5032 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
5033 };
5034 static const u8 cs160[8] = {
5035 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
5036 };
5037 static const u8 cs168[8] = {
5038 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
5039 };
5040 u8 reg;
5041 u8 v1;
5042 u8 v2;
5043 u8 v3;
5044
5045 SiS_SetReg(SISCR, 0xb0, 0x80); /* DDR2 dual frequency mode */
5046 SiS_SetReg(SISCR, 0x82, 0x77);
5047 SiS_SetReg(SISCR, 0x86, 0x00);
5048 reg = SiS_GetReg(SISCR, 0x86);
5049 SiS_SetReg(SISCR, 0x86, 0x88);
5050 reg = SiS_GetReg(SISCR, 0x86);
5051 v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
5052 if (ivideo->haveXGIROM) {
5053 v1 = bios[regb + 0x168];
5054 v2 = bios[regb + 0x160];
5055 v3 = bios[regb + 0x158];
5056 }
5057 SiS_SetReg(SISCR, 0x86, v1);
5058 SiS_SetReg(SISCR, 0x82, 0x77);
5059 SiS_SetReg(SISCR, 0x85, 0x00);
5060 reg = SiS_GetReg(SISCR, 0x85);
5061 SiS_SetReg(SISCR, 0x85, 0x88);
5062 reg = SiS_GetReg(SISCR, 0x85);
5063 SiS_SetReg(SISCR, 0x85, v2);
5064 SiS_SetReg(SISCR, 0x82, v3);
5065 SiS_SetReg(SISCR, 0x98, 0x01);
5066 SiS_SetReg(SISCR, 0x9a, 0x02);
5067 if (sisfb_xgi_is21(ivideo))
5068 sisfb_post_xgi_ddr2_mrs_xg21(ivideo);
5069 else
5070 sisfb_post_xgi_ddr2_mrs_default(ivideo, regb);
5071}
5072
5073static u8 __devinit
5074sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
5075{
5076 unsigned char *bios = ivideo->bios_abase;
5077 u8 ramtype;
5078 u8 reg;
5079 u8 v1;
5080
5081 ramtype = 0x00; v1 = 0x10;
5082 if (ivideo->haveXGIROM) {
5083 ramtype = bios[0x62];
5084 v1 = bios[0x1d2];
5085 }
5086 if (!(ramtype & 0x80)) {
5087 if (sisfb_xgi_is21(ivideo)) {
5088 SiS_SetRegAND(SISCR, 0xb4, 0xfd); /* GPIO control */
5089 SiS_SetRegOR(SISCR, 0x4a, 0x80); /* GPIOH EN */
5090 reg = SiS_GetReg(SISCR, 0x48);
5091 SiS_SetRegOR(SISCR, 0xb4, 0x02);
5092 ramtype = reg & 0x01; /* GPIOH */
5093 } else if (ivideo->chip == XGI_20) {
5094 SiS_SetReg(SISCR, 0x97, v1);
5095 reg = SiS_GetReg(SISCR, 0x97);
5096 if (reg & 0x10) {
5097 ramtype = (reg & 0x01) << 1;
5098 }
5099 } else {
5100 reg = SiS_GetReg(SISSR, 0x39);
5101 ramtype = reg & 0x02;
5102 if (!(ramtype)) {
5103 reg = SiS_GetReg(SISSR, 0x3a);
5104 ramtype = (reg >> 1) & 0x01;
5105 }
5106 }
5107 }
5108 ramtype &= 0x07;
5109
5110 return ramtype;
5111}
5112
4934static int __devinit 5113static int __devinit
4935sisfb_post_xgi(struct pci_dev *pdev) 5114sisfb_post_xgi(struct pci_dev *pdev)
4936{ 5115{
@@ -5213,9 +5392,23 @@ sisfb_post_xgi(struct pci_dev *pdev)
5213 SiS_SetReg(SISCR, 0x77, v1); 5392 SiS_SetReg(SISCR, 0x77, v1);
5214 } 5393 }
5215 5394
5216 /* RAM type */ 5395 /* RAM type:
5217 5396 *
5218 regb = 0; /* ! */ 5397 * 0 == DDR1, 1 == DDR2, 2..7 == reserved?
5398 *
5399 * The code seems to written so that regb should equal ramtype,
5400 * however, so far it has been hardcoded to 0. Enable other values only
5401 * on XGI Z9, as it passes the POST, and add a warning for others.
5402 */
5403 ramtype = sisfb_post_xgi_ramtype(ivideo);
5404 if (!sisfb_xgi_is21(ivideo) && ramtype) {
5405 dev_warn(&pdev->dev,
5406 "RAM type something else than expected: %d\n",
5407 ramtype);
5408 regb = 0;
5409 } else {
5410 regb = ramtype;
5411 }
5219 5412
5220 v1 = 0xff; 5413 v1 = 0xff;
5221 if(ivideo->haveXGIROM) { 5414 if(ivideo->haveXGIROM) {
@@ -5367,7 +5560,10 @@ sisfb_post_xgi(struct pci_dev *pdev)
5367 } 5560 }
5368 } 5561 }
5369 5562
5370 SiS_SetReg(SISSR, 0x17, 0x00); 5563 if (regb == 1)
5564 SiS_SetReg(SISSR, 0x17, 0x80); /* DDR2 */
5565 else
5566 SiS_SetReg(SISSR, 0x17, 0x00); /* DDR1 */
5371 SiS_SetReg(SISSR, 0x1a, 0x87); 5567 SiS_SetReg(SISSR, 0x1a, 0x87);
5372 5568
5373 if(ivideo->chip == XGI_20) { 5569 if(ivideo->chip == XGI_20) {
@@ -5375,31 +5571,6 @@ sisfb_post_xgi(struct pci_dev *pdev)
5375 SiS_SetReg(SISSR, 0x1c, 0x00); 5571 SiS_SetReg(SISSR, 0x1c, 0x00);
5376 } 5572 }
5377 5573
5378 ramtype = 0x00; v1 = 0x10;
5379 if(ivideo->haveXGIROM) {
5380 ramtype = bios[0x62];
5381 v1 = bios[0x1d2];
5382 }
5383 if(!(ramtype & 0x80)) {
5384 if(ivideo->chip == XGI_20) {
5385 SiS_SetReg(SISCR, 0x97, v1);
5386 reg = SiS_GetReg(SISCR, 0x97);
5387 if(reg & 0x10) {
5388 ramtype = (reg & 0x01) << 1;
5389 }
5390 } else {
5391 reg = SiS_GetReg(SISSR, 0x39);
5392 ramtype = reg & 0x02;
5393 if(!(ramtype)) {
5394 reg = SiS_GetReg(SISSR, 0x3a);
5395 ramtype = (reg >> 1) & 0x01;
5396 }
5397 }
5398 }
5399 ramtype &= 0x07;
5400
5401 regb = 0; /* ! */
5402
5403 switch(ramtype) { 5574 switch(ramtype) {
5404 case 0: 5575 case 0:
5405 sisfb_post_xgi_setclocks(ivideo, regb); 5576 sisfb_post_xgi_setclocks(ivideo, regb);
@@ -5485,61 +5656,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
5485 SiS_SetReg(SISSR, 0x1b, 0x00); 5656 SiS_SetReg(SISSR, 0x1b, 0x00);
5486 break; 5657 break;
5487 case 1: 5658 case 1:
5488 SiS_SetReg(SISCR, 0x82, 0x77); 5659 sisfb_post_xgi_ddr2(ivideo, regb);
5489 SiS_SetReg(SISCR, 0x86, 0x00);
5490 reg = SiS_GetReg(SISCR, 0x86);
5491 SiS_SetReg(SISCR, 0x86, 0x88);
5492 reg = SiS_GetReg(SISCR, 0x86);
5493 v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
5494 if(ivideo->haveXGIROM) {
5495 v1 = bios[regb + 0x168];
5496 v2 = bios[regb + 0x160];
5497 v3 = bios[regb + 0x158];
5498 }
5499 SiS_SetReg(SISCR, 0x86, v1);
5500 SiS_SetReg(SISCR, 0x82, 0x77);
5501 SiS_SetReg(SISCR, 0x85, 0x00);
5502 reg = SiS_GetReg(SISCR, 0x85);
5503 SiS_SetReg(SISCR, 0x85, 0x88);
5504 reg = SiS_GetReg(SISCR, 0x85);
5505 SiS_SetReg(SISCR, 0x85, v2);
5506 SiS_SetReg(SISCR, 0x82, v3);
5507 SiS_SetReg(SISCR, 0x98, 0x01);
5508 SiS_SetReg(SISCR, 0x9a, 0x02);
5509
5510 SiS_SetReg(SISSR, 0x28, 0x64);
5511 SiS_SetReg(SISSR, 0x29, 0x63);
5512 sisfb_post_xgi_delay(ivideo, 15);
5513 SiS_SetReg(SISSR, 0x18, 0x00);
5514 SiS_SetReg(SISSR, 0x19, 0x20);
5515 SiS_SetReg(SISSR, 0x16, 0x00);
5516 SiS_SetReg(SISSR, 0x16, 0x80);
5517 SiS_SetReg(SISSR, 0x18, 0xc5);
5518 SiS_SetReg(SISSR, 0x19, 0x23);
5519 SiS_SetReg(SISSR, 0x16, 0x00);
5520 SiS_SetReg(SISSR, 0x16, 0x80);
5521 sisfb_post_xgi_delay(ivideo, 1);
5522 SiS_SetReg(SISCR, 0x97, 0x11);
5523 sisfb_post_xgi_setclocks(ivideo, regb);
5524 sisfb_post_xgi_delay(ivideo, 0x46);
5525 SiS_SetReg(SISSR, 0x18, 0xc5);
5526 SiS_SetReg(SISSR, 0x19, 0x23);
5527 SiS_SetReg(SISSR, 0x16, 0x00);
5528 SiS_SetReg(SISSR, 0x16, 0x80);
5529 sisfb_post_xgi_delay(ivideo, 1);
5530 SiS_SetReg(SISSR, 0x1b, 0x04);
5531 sisfb_post_xgi_delay(ivideo, 1);
5532 SiS_SetReg(SISSR, 0x1b, 0x00);
5533 sisfb_post_xgi_delay(ivideo, 1);
5534 v1 = 0x31;
5535 if(ivideo->haveXGIROM) {
5536 v1 = bios[0xf0];
5537 }
5538 SiS_SetReg(SISSR, 0x18, v1);
5539 SiS_SetReg(SISSR, 0x19, 0x06);
5540 SiS_SetReg(SISSR, 0x16, 0x04);
5541 SiS_SetReg(SISSR, 0x16, 0x84);
5542 sisfb_post_xgi_delay(ivideo, 1);
5543 break; 5660 break;
5544 default: 5661 default:
5545 sisfb_post_xgi_setclocks(ivideo, regb); 5662 sisfb_post_xgi_setclocks(ivideo, regb);
@@ -5648,6 +5765,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
5648 SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]); 5765 SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]);
5649 5766
5650 } else { 5767 } else {
5768 int err;
5651 5769
5652 /* Set default mode, don't clear screen */ 5770 /* Set default mode, don't clear screen */
5653 ivideo->SiS_Pr.SiS_UseOEM = false; 5771 ivideo->SiS_Pr.SiS_UseOEM = false;
@@ -5661,10 +5779,16 @@ sisfb_post_xgi(struct pci_dev *pdev)
5661 5779
5662 /* Disable read-cache */ 5780 /* Disable read-cache */
5663 SiS_SetRegAND(SISSR, 0x21, 0xdf); 5781 SiS_SetRegAND(SISSR, 0x21, 0xdf);
5664 sisfb_post_xgi_ramsize(ivideo); 5782 err = sisfb_post_xgi_ramsize(ivideo);
5665 /* Enable read-cache */ 5783 /* Enable read-cache */
5666 SiS_SetRegOR(SISSR, 0x21, 0x20); 5784 SiS_SetRegOR(SISSR, 0x21, 0x20);
5667 5785
5786 if (err) {
5787 dev_err(&pdev->dev,
5788 "%s: RAM size detection failed: %d\n",
5789 __func__, err);
5790 return 0;
5791 }
5668 } 5792 }
5669 5793
5670#if 0 5794#if 0
@@ -5777,6 +5901,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5777#endif 5901#endif
5778 5902
5779 ivideo->chip = chipinfo->chip; 5903 ivideo->chip = chipinfo->chip;
5904 ivideo->chip_real_id = chipinfo->chip;
5780 ivideo->sisvga_engine = chipinfo->vgaengine; 5905 ivideo->sisvga_engine = chipinfo->vgaengine;
5781 ivideo->hwcursor_size = chipinfo->hwcursor_size; 5906 ivideo->hwcursor_size = chipinfo->hwcursor_size;
5782 ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable; 5907 ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable;
@@ -6010,6 +6135,18 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
6010 sisfb_detect_custom_timing(ivideo); 6135 sisfb_detect_custom_timing(ivideo);
6011 } 6136 }
6012 6137
6138#ifdef CONFIG_FB_SIS_315
6139 if (ivideo->chip == XGI_20) {
6140 /* Check if our Z7 chip is actually Z9 */
6141 SiS_SetRegOR(SISCR, 0x4a, 0x40); /* GPIOG EN */
6142 reg = SiS_GetReg(SISCR, 0x48);
6143 if (reg & 0x02) { /* GPIOG */
6144 ivideo->chip_real_id = XGI_21;
6145 dev_info(&pdev->dev, "Z9 detected\n");
6146 }
6147 }
6148#endif
6149
6013 /* POST card in case this has not been done by the BIOS */ 6150 /* POST card in case this has not been done by the BIOS */
6014 if( (!ivideo->sisvga_enabled) 6151 if( (!ivideo->sisvga_enabled)
6015#if !defined(__i386__) && !defined(__x86_64__) 6152#if !defined(__i386__) && !defined(__x86_64__)
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
index 12c0dfaf251..e3f9976cfef 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/sis/vgatypes.h
@@ -87,6 +87,7 @@ typedef enum _SIS_CHIP_TYPE {
87 SIS_341, 87 SIS_341,
88 SIS_342, 88 SIS_342,
89 XGI_20 = 75, 89 XGI_20 = 75,
90 XGI_21,
90 XGI_40, 91 XGI_40,
91 MAX_SIS_CHIP 92 MAX_SIS_CHIP
92} SIS_CHIP_TYPE; 93} SIS_CHIP_TYPE;
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index bcb44a594eb..46d1a64fe80 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -41,6 +41,26 @@
41#include <linux/sm501.h> 41#include <linux/sm501.h>
42#include <linux/sm501-regs.h> 42#include <linux/sm501-regs.h>
43 43
44#include "edid.h"
45
46static char *fb_mode = "640x480-16@60";
47static unsigned long default_bpp = 16;
48
49static struct fb_videomode __devinitdata sm501_default_mode = {
50 .refresh = 60,
51 .xres = 640,
52 .yres = 480,
53 .pixclock = 20833,
54 .left_margin = 142,
55 .right_margin = 13,
56 .upper_margin = 21,
57 .lower_margin = 1,
58 .hsync_len = 69,
59 .vsync_len = 3,
60 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
61 .vmode = FB_VMODE_NONINTERLACED
62};
63
44#define NR_PALETTE 256 64#define NR_PALETTE 256
45 65
46enum sm501_controller { 66enum sm501_controller {
@@ -77,6 +97,7 @@ struct sm501fb_info {
77 void __iomem *regs2d; /* 2d remapped registers */ 97 void __iomem *regs2d; /* 2d remapped registers */
78 void __iomem *fbmem; /* remapped framebuffer */ 98 void __iomem *fbmem; /* remapped framebuffer */
79 size_t fbmem_len; /* length of remapped region */ 99 size_t fbmem_len; /* length of remapped region */
100 u8 *edid_data;
80}; 101};
81 102
82/* per-framebuffer private data */ 103/* per-framebuffer private data */
@@ -117,7 +138,7 @@ static inline int v_total(struct fb_var_screeninfo *var)
117 138
118static inline void sm501fb_sync_regs(struct sm501fb_info *info) 139static inline void sm501fb_sync_regs(struct sm501fb_info *info)
119{ 140{
120 readl(info->regs); 141 smc501_readl(info->regs);
121} 142}
122 143
123/* sm501_alloc_mem 144/* sm501_alloc_mem
@@ -262,7 +283,7 @@ static void sm501fb_setup_gamma(struct sm501fb_info *fbi,
262 283
263 /* set gamma values */ 284 /* set gamma values */
264 for (offset = 0; offset < 256 * 4; offset += 4) { 285 for (offset = 0; offset < 256 * 4; offset += 4) {
265 writel(value, fbi->regs + palette + offset); 286 smc501_writel(value, fbi->regs + palette + offset);
266 value += 0x010101; /* Advance RGB by 1,1,1.*/ 287 value += 0x010101; /* Advance RGB by 1,1,1.*/
267 } 288 }
268} 289}
@@ -476,7 +497,8 @@ static int sm501fb_set_par_common(struct fb_info *info,
476 497
477 /* set start of framebuffer to the screen */ 498 /* set start of framebuffer to the screen */
478 499
479 writel(par->screen.sm_addr | SM501_ADDR_FLIP, fbi->regs + head_addr); 500 smc501_writel(par->screen.sm_addr | SM501_ADDR_FLIP,
501 fbi->regs + head_addr);
480 502
481 /* program CRT clock */ 503 /* program CRT clock */
482 504
@@ -519,7 +541,7 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
519 reg = info->fix.line_length; 541 reg = info->fix.line_length;
520 reg |= ((var->xres * var->bits_per_pixel)/8) << 16; 542 reg |= ((var->xres * var->bits_per_pixel)/8) << 16;
521 543
522 writel(reg, fbi->regs + (par->head == HEAD_CRT ? 544 smc501_writel(reg, fbi->regs + (par->head == HEAD_CRT ?
523 SM501_DC_CRT_FB_OFFSET : SM501_DC_PANEL_FB_OFFSET)); 545 SM501_DC_CRT_FB_OFFSET : SM501_DC_PANEL_FB_OFFSET));
524 546
525 /* program horizontal total */ 547 /* program horizontal total */
@@ -527,27 +549,27 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
527 reg = (h_total(var) - 1) << 16; 549 reg = (h_total(var) - 1) << 16;
528 reg |= (var->xres - 1); 550 reg |= (var->xres - 1);
529 551
530 writel(reg, base + SM501_OFF_DC_H_TOT); 552 smc501_writel(reg, base + SM501_OFF_DC_H_TOT);
531 553
532 /* program horizontal sync */ 554 /* program horizontal sync */
533 555
534 reg = var->hsync_len << 16; 556 reg = var->hsync_len << 16;
535 reg |= var->xres + var->right_margin - 1; 557 reg |= var->xres + var->right_margin - 1;
536 558
537 writel(reg, base + SM501_OFF_DC_H_SYNC); 559 smc501_writel(reg, base + SM501_OFF_DC_H_SYNC);
538 560
539 /* program vertical total */ 561 /* program vertical total */
540 562
541 reg = (v_total(var) - 1) << 16; 563 reg = (v_total(var) - 1) << 16;
542 reg |= (var->yres - 1); 564 reg |= (var->yres - 1);
543 565
544 writel(reg, base + SM501_OFF_DC_V_TOT); 566 smc501_writel(reg, base + SM501_OFF_DC_V_TOT);
545 567
546 /* program vertical sync */ 568 /* program vertical sync */
547 reg = var->vsync_len << 16; 569 reg = var->vsync_len << 16;
548 reg |= var->yres + var->lower_margin - 1; 570 reg |= var->yres + var->lower_margin - 1;
549 571
550 writel(reg, base + SM501_OFF_DC_V_SYNC); 572 smc501_writel(reg, base + SM501_OFF_DC_V_SYNC);
551} 573}
552 574
553/* sm501fb_pan_crt 575/* sm501fb_pan_crt
@@ -566,15 +588,15 @@ static int sm501fb_pan_crt(struct fb_var_screeninfo *var,
566 588
567 xoffs = var->xoffset * bytes_pixel; 589 xoffs = var->xoffset * bytes_pixel;
568 590
569 reg = readl(fbi->regs + SM501_DC_CRT_CONTROL); 591 reg = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
570 592
571 reg &= ~SM501_DC_CRT_CONTROL_PIXEL_MASK; 593 reg &= ~SM501_DC_CRT_CONTROL_PIXEL_MASK;
572 reg |= ((xoffs & 15) / bytes_pixel) << 4; 594 reg |= ((xoffs & 15) / bytes_pixel) << 4;
573 writel(reg, fbi->regs + SM501_DC_CRT_CONTROL); 595 smc501_writel(reg, fbi->regs + SM501_DC_CRT_CONTROL);
574 596
575 reg = (par->screen.sm_addr + xoffs + 597 reg = (par->screen.sm_addr + xoffs +
576 var->yoffset * info->fix.line_length); 598 var->yoffset * info->fix.line_length);
577 writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR); 599 smc501_writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR);
578 600
579 sm501fb_sync_regs(fbi); 601 sm501fb_sync_regs(fbi);
580 return 0; 602 return 0;
@@ -593,10 +615,10 @@ static int sm501fb_pan_pnl(struct fb_var_screeninfo *var,
593 unsigned long reg; 615 unsigned long reg;
594 616
595 reg = var->xoffset | (var->xres_virtual << 16); 617 reg = var->xoffset | (var->xres_virtual << 16);
596 writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH); 618 smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH);
597 619
598 reg = var->yoffset | (var->yres_virtual << 16); 620 reg = var->yoffset | (var->yres_virtual << 16);
599 writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT); 621 smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT);
600 622
601 sm501fb_sync_regs(fbi); 623 sm501fb_sync_regs(fbi);
602 return 0; 624 return 0;
@@ -622,7 +644,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
622 /* enable CRT DAC - note 0 is on!*/ 644 /* enable CRT DAC - note 0 is on!*/
623 sm501_misc_control(fbi->dev->parent, 0, SM501_MISC_DAC_POWER); 645 sm501_misc_control(fbi->dev->parent, 0, SM501_MISC_DAC_POWER);
624 646
625 control = readl(fbi->regs + SM501_DC_CRT_CONTROL); 647 control = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
626 648
627 control &= (SM501_DC_CRT_CONTROL_PIXEL_MASK | 649 control &= (SM501_DC_CRT_CONTROL_PIXEL_MASK |
628 SM501_DC_CRT_CONTROL_GAMMA | 650 SM501_DC_CRT_CONTROL_GAMMA |
@@ -684,7 +706,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
684 out_update: 706 out_update:
685 dev_dbg(fbi->dev, "new control is %08lx\n", control); 707 dev_dbg(fbi->dev, "new control is %08lx\n", control);
686 708
687 writel(control, fbi->regs + SM501_DC_CRT_CONTROL); 709 smc501_writel(control, fbi->regs + SM501_DC_CRT_CONTROL);
688 sm501fb_sync_regs(fbi); 710 sm501fb_sync_regs(fbi);
689 711
690 return 0; 712 return 0;
@@ -696,18 +718,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
696 void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL; 718 void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL;
697 struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl; 719 struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl;
698 720
699 control = readl(ctrl_reg); 721 control = smc501_readl(ctrl_reg);
700 722
701 if (to && (control & SM501_DC_PANEL_CONTROL_VDD) == 0) { 723 if (to && (control & SM501_DC_PANEL_CONTROL_VDD) == 0) {
702 /* enable panel power */ 724 /* enable panel power */
703 725
704 control |= SM501_DC_PANEL_CONTROL_VDD; /* FPVDDEN */ 726 control |= SM501_DC_PANEL_CONTROL_VDD; /* FPVDDEN */
705 writel(control, ctrl_reg); 727 smc501_writel(control, ctrl_reg);
706 sm501fb_sync_regs(fbi); 728 sm501fb_sync_regs(fbi);
707 mdelay(10); 729 mdelay(10);
708 730
709 control |= SM501_DC_PANEL_CONTROL_DATA; /* DATA */ 731 control |= SM501_DC_PANEL_CONTROL_DATA; /* DATA */
710 writel(control, ctrl_reg); 732 smc501_writel(control, ctrl_reg);
711 sm501fb_sync_regs(fbi); 733 sm501fb_sync_regs(fbi);
712 mdelay(10); 734 mdelay(10);
713 735
@@ -719,7 +741,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
719 else 741 else
720 control |= SM501_DC_PANEL_CONTROL_BIAS; 742 control |= SM501_DC_PANEL_CONTROL_BIAS;
721 743
722 writel(control, ctrl_reg); 744 smc501_writel(control, ctrl_reg);
723 sm501fb_sync_regs(fbi); 745 sm501fb_sync_regs(fbi);
724 mdelay(10); 746 mdelay(10);
725 } 747 }
@@ -730,7 +752,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
730 else 752 else
731 control |= SM501_DC_PANEL_CONTROL_FPEN; 753 control |= SM501_DC_PANEL_CONTROL_FPEN;
732 754
733 writel(control, ctrl_reg); 755 smc501_writel(control, ctrl_reg);
734 sm501fb_sync_regs(fbi); 756 sm501fb_sync_regs(fbi);
735 mdelay(10); 757 mdelay(10);
736 } 758 }
@@ -742,7 +764,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
742 else 764 else
743 control &= ~SM501_DC_PANEL_CONTROL_FPEN; 765 control &= ~SM501_DC_PANEL_CONTROL_FPEN;
744 766
745 writel(control, ctrl_reg); 767 smc501_writel(control, ctrl_reg);
746 sm501fb_sync_regs(fbi); 768 sm501fb_sync_regs(fbi);
747 mdelay(10); 769 mdelay(10);
748 } 770 }
@@ -753,18 +775,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
753 else 775 else
754 control &= ~SM501_DC_PANEL_CONTROL_BIAS; 776 control &= ~SM501_DC_PANEL_CONTROL_BIAS;
755 777
756 writel(control, ctrl_reg); 778 smc501_writel(control, ctrl_reg);
757 sm501fb_sync_regs(fbi); 779 sm501fb_sync_regs(fbi);
758 mdelay(10); 780 mdelay(10);
759 } 781 }
760 782
761 control &= ~SM501_DC_PANEL_CONTROL_DATA; 783 control &= ~SM501_DC_PANEL_CONTROL_DATA;
762 writel(control, ctrl_reg); 784 smc501_writel(control, ctrl_reg);
763 sm501fb_sync_regs(fbi); 785 sm501fb_sync_regs(fbi);
764 mdelay(10); 786 mdelay(10);
765 787
766 control &= ~SM501_DC_PANEL_CONTROL_VDD; 788 control &= ~SM501_DC_PANEL_CONTROL_VDD;
767 writel(control, ctrl_reg); 789 smc501_writel(control, ctrl_reg);
768 sm501fb_sync_regs(fbi); 790 sm501fb_sync_regs(fbi);
769 mdelay(10); 791 mdelay(10);
770 } 792 }
@@ -799,7 +821,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
799 821
800 /* update control register */ 822 /* update control register */
801 823
802 control = readl(fbi->regs + SM501_DC_PANEL_CONTROL); 824 control = smc501_readl(fbi->regs + SM501_DC_PANEL_CONTROL);
803 control &= (SM501_DC_PANEL_CONTROL_GAMMA | 825 control &= (SM501_DC_PANEL_CONTROL_GAMMA |
804 SM501_DC_PANEL_CONTROL_VDD | 826 SM501_DC_PANEL_CONTROL_VDD |
805 SM501_DC_PANEL_CONTROL_DATA | 827 SM501_DC_PANEL_CONTROL_DATA |
@@ -833,16 +855,16 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
833 BUG(); 855 BUG();
834 } 856 }
835 857
836 writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL); 858 smc501_writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL);
837 859
838 /* panel plane top left and bottom right location */ 860 /* panel plane top left and bottom right location */
839 861
840 writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC); 862 smc501_writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC);
841 863
842 reg = var->xres - 1; 864 reg = var->xres - 1;
843 reg |= (var->yres - 1) << 16; 865 reg |= (var->yres - 1) << 16;
844 866
845 writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC); 867 smc501_writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC);
846 868
847 /* program panel control register */ 869 /* program panel control register */
848 870
@@ -855,7 +877,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
855 if ((var->sync & FB_SYNC_VERT_HIGH_ACT) == 0) 877 if ((var->sync & FB_SYNC_VERT_HIGH_ACT) == 0)
856 control |= SM501_DC_PANEL_CONTROL_VSP; 878 control |= SM501_DC_PANEL_CONTROL_VSP;
857 879
858 writel(control, fbi->regs + SM501_DC_PANEL_CONTROL); 880 smc501_writel(control, fbi->regs + SM501_DC_PANEL_CONTROL);
859 sm501fb_sync_regs(fbi); 881 sm501fb_sync_regs(fbi);
860 882
861 /* ensure the panel interface is not tristated at this point */ 883 /* ensure the panel interface is not tristated at this point */
@@ -924,7 +946,7 @@ static int sm501fb_setcolreg(unsigned regno,
924 val |= (green >> 8) << 8; 946 val |= (green >> 8) << 8;
925 val |= blue >> 8; 947 val |= blue >> 8;
926 948
927 writel(val, base + (regno * 4)); 949 smc501_writel(val, base + (regno * 4));
928 } 950 }
929 951
930 break; 952 break;
@@ -980,7 +1002,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
980 1002
981 dev_dbg(fbi->dev, "%s(mode=%d, %p)\n", __func__, blank_mode, info); 1003 dev_dbg(fbi->dev, "%s(mode=%d, %p)\n", __func__, blank_mode, info);
982 1004
983 ctrl = readl(fbi->regs + SM501_DC_CRT_CONTROL); 1005 ctrl = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
984 1006
985 switch (blank_mode) { 1007 switch (blank_mode) {
986 case FB_BLANK_POWERDOWN: 1008 case FB_BLANK_POWERDOWN:
@@ -1004,7 +1026,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
1004 1026
1005 } 1027 }
1006 1028
1007 writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL); 1029 smc501_writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL);
1008 sm501fb_sync_regs(fbi); 1030 sm501fb_sync_regs(fbi);
1009 1031
1010 return 0; 1032 return 0;
@@ -1041,12 +1063,14 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1041 if (cursor->image.depth > 1) 1063 if (cursor->image.depth > 1)
1042 return -EINVAL; 1064 return -EINVAL;
1043 1065
1044 hwc_addr = readl(base + SM501_OFF_HWC_ADDR); 1066 hwc_addr = smc501_readl(base + SM501_OFF_HWC_ADDR);
1045 1067
1046 if (cursor->enable) 1068 if (cursor->enable)
1047 writel(hwc_addr | SM501_HWC_EN, base + SM501_OFF_HWC_ADDR); 1069 smc501_writel(hwc_addr | SM501_HWC_EN,
1070 base + SM501_OFF_HWC_ADDR);
1048 else 1071 else
1049 writel(hwc_addr & ~SM501_HWC_EN, base + SM501_OFF_HWC_ADDR); 1072 smc501_writel(hwc_addr & ~SM501_HWC_EN,
1073 base + SM501_OFF_HWC_ADDR);
1050 1074
1051 /* set data */ 1075 /* set data */
1052 if (cursor->set & FB_CUR_SETPOS) { 1076 if (cursor->set & FB_CUR_SETPOS) {
@@ -1060,7 +1084,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1060 1084
1061 //y += cursor->image.height; 1085 //y += cursor->image.height;
1062 1086
1063 writel(x | (y << 16), base + SM501_OFF_HWC_LOC); 1087 smc501_writel(x | (y << 16), base + SM501_OFF_HWC_LOC);
1064 } 1088 }
1065 1089
1066 if (cursor->set & FB_CUR_SETCMAP) { 1090 if (cursor->set & FB_CUR_SETCMAP) {
@@ -1080,8 +1104,8 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1080 1104
1081 dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg); 1105 dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg);
1082 1106
1083 writel(bg, base + SM501_OFF_HWC_COLOR_1_2); 1107 smc501_writel(bg, base + SM501_OFF_HWC_COLOR_1_2);
1084 writel(fg, base + SM501_OFF_HWC_COLOR_3); 1108 smc501_writel(fg, base + SM501_OFF_HWC_COLOR_3);
1085 } 1109 }
1086 1110
1087 if (cursor->set & FB_CUR_SETSIZE || 1111 if (cursor->set & FB_CUR_SETSIZE ||
@@ -1102,7 +1126,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1102 __func__, cursor->image.width, cursor->image.height); 1126 __func__, cursor->image.width, cursor->image.height);
1103 1127
1104 for (op = 0; op < (64*64*2)/8; op+=4) 1128 for (op = 0; op < (64*64*2)/8; op+=4)
1105 writel(0x0, dst + op); 1129 smc501_writel(0x0, dst + op);
1106 1130
1107 for (y = 0; y < cursor->image.height; y++) { 1131 for (y = 0; y < cursor->image.height; y++) {
1108 for (x = 0; x < cursor->image.width; x++) { 1132 for (x = 0; x < cursor->image.width; x++) {
@@ -1141,7 +1165,7 @@ static ssize_t sm501fb_crtsrc_show(struct device *dev,
1141 struct sm501fb_info *info = dev_get_drvdata(dev); 1165 struct sm501fb_info *info = dev_get_drvdata(dev);
1142 unsigned long ctrl; 1166 unsigned long ctrl;
1143 1167
1144 ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 1168 ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
1145 ctrl &= SM501_DC_CRT_CONTROL_SEL; 1169 ctrl &= SM501_DC_CRT_CONTROL_SEL;
1146 1170
1147 return snprintf(buf, PAGE_SIZE, "%s\n", ctrl ? "crt" : "panel"); 1171 return snprintf(buf, PAGE_SIZE, "%s\n", ctrl ? "crt" : "panel");
@@ -1172,7 +1196,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
1172 1196
1173 dev_info(dev, "setting crt source to head %d\n", head); 1197 dev_info(dev, "setting crt source to head %d\n", head);
1174 1198
1175 ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 1199 ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
1176 1200
1177 if (head == HEAD_CRT) { 1201 if (head == HEAD_CRT) {
1178 ctrl |= SM501_DC_CRT_CONTROL_SEL; 1202 ctrl |= SM501_DC_CRT_CONTROL_SEL;
@@ -1184,7 +1208,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
1184 ctrl &= ~SM501_DC_CRT_CONTROL_TE; 1208 ctrl &= ~SM501_DC_CRT_CONTROL_TE;
1185 } 1209 }
1186 1210
1187 writel(ctrl, info->regs + SM501_DC_CRT_CONTROL); 1211 smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
1188 sm501fb_sync_regs(info); 1212 sm501fb_sync_regs(info);
1189 1213
1190 return len; 1214 return len;
@@ -1205,7 +1229,8 @@ static int sm501fb_show_regs(struct sm501fb_info *info, char *ptr,
1205 unsigned int reg; 1229 unsigned int reg;
1206 1230
1207 for (reg = start; reg < (len + start); reg += 4) 1231 for (reg = start; reg < (len + start); reg += 4)
1208 ptr += sprintf(ptr, "%08x = %08x\n", reg, readl(mem + reg)); 1232 ptr += sprintf(ptr, "%08x = %08x\n", reg,
1233 smc501_readl(mem + reg));
1209 1234
1210 return ptr - buf; 1235 return ptr - buf;
1211} 1236}
@@ -1257,7 +1282,7 @@ static int sm501fb_sync(struct fb_info *info)
1257 1282
1258 /* wait for the 2d engine to be ready */ 1283 /* wait for the 2d engine to be ready */
1259 while ((count > 0) && 1284 while ((count > 0) &&
1260 (readl(fbi->regs + SM501_SYSTEM_CONTROL) & 1285 (smc501_readl(fbi->regs + SM501_SYSTEM_CONTROL) &
1261 SM501_SYSCTRL_2D_ENGINE_STATUS) != 0) 1286 SM501_SYSCTRL_2D_ENGINE_STATUS) != 0)
1262 count--; 1287 count--;
1263 1288
@@ -1312,45 +1337,46 @@ static void sm501fb_copyarea(struct fb_info *info, const struct fb_copyarea *are
1312 return; 1337 return;
1313 1338
1314 /* set the base addresses */ 1339 /* set the base addresses */
1315 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE); 1340 smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
1316 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE); 1341 smc501_writel(par->screen.sm_addr,
1342 fbi->regs2d + SM501_2D_DESTINATION_BASE);
1317 1343
1318 /* set the window width */ 1344 /* set the window width */
1319 writel((info->var.xres << 16) | info->var.xres, 1345 smc501_writel((info->var.xres << 16) | info->var.xres,
1320 fbi->regs2d + SM501_2D_WINDOW_WIDTH); 1346 fbi->regs2d + SM501_2D_WINDOW_WIDTH);
1321 1347
1322 /* set window stride */ 1348 /* set window stride */
1323 writel((info->var.xres_virtual << 16) | info->var.xres_virtual, 1349 smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
1324 fbi->regs2d + SM501_2D_PITCH); 1350 fbi->regs2d + SM501_2D_PITCH);
1325 1351
1326 /* set data format */ 1352 /* set data format */
1327 switch (info->var.bits_per_pixel) { 1353 switch (info->var.bits_per_pixel) {
1328 case 8: 1354 case 8:
1329 writel(0, fbi->regs2d + SM501_2D_STRETCH); 1355 smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
1330 break; 1356 break;
1331 case 16: 1357 case 16:
1332 writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH); 1358 smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
1333 break; 1359 break;
1334 case 32: 1360 case 32:
1335 writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH); 1361 smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
1336 break; 1362 break;
1337 } 1363 }
1338 1364
1339 /* 2d compare mask */ 1365 /* 2d compare mask */
1340 writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK); 1366 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
1341 1367
1342 /* 2d mask */ 1368 /* 2d mask */
1343 writel(0xffffffff, fbi->regs2d + SM501_2D_MASK); 1369 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
1344 1370
1345 /* source and destination x y */ 1371 /* source and destination x y */
1346 writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE); 1372 smc501_writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE);
1347 writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION); 1373 smc501_writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION);
1348 1374
1349 /* w/h */ 1375 /* w/h */
1350 writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION); 1376 smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
1351 1377
1352 /* do area move */ 1378 /* do area move */
1353 writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL); 1379 smc501_writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL);
1354} 1380}
1355 1381
1356static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 1382static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
@@ -1372,47 +1398,49 @@ static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rec
1372 return; 1398 return;
1373 1399
1374 /* set the base addresses */ 1400 /* set the base addresses */
1375 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE); 1401 smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
1376 writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE); 1402 smc501_writel(par->screen.sm_addr,
1403 fbi->regs2d + SM501_2D_DESTINATION_BASE);
1377 1404
1378 /* set the window width */ 1405 /* set the window width */
1379 writel((info->var.xres << 16) | info->var.xres, 1406 smc501_writel((info->var.xres << 16) | info->var.xres,
1380 fbi->regs2d + SM501_2D_WINDOW_WIDTH); 1407 fbi->regs2d + SM501_2D_WINDOW_WIDTH);
1381 1408
1382 /* set window stride */ 1409 /* set window stride */
1383 writel((info->var.xres_virtual << 16) | info->var.xres_virtual, 1410 smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
1384 fbi->regs2d + SM501_2D_PITCH); 1411 fbi->regs2d + SM501_2D_PITCH);
1385 1412
1386 /* set data format */ 1413 /* set data format */
1387 switch (info->var.bits_per_pixel) { 1414 switch (info->var.bits_per_pixel) {
1388 case 8: 1415 case 8:
1389 writel(0, fbi->regs2d + SM501_2D_STRETCH); 1416 smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
1390 break; 1417 break;
1391 case 16: 1418 case 16:
1392 writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH); 1419 smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
1393 break; 1420 break;
1394 case 32: 1421 case 32:
1395 writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH); 1422 smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
1396 break; 1423 break;
1397 } 1424 }
1398 1425
1399 /* 2d compare mask */ 1426 /* 2d compare mask */
1400 writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK); 1427 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
1401 1428
1402 /* 2d mask */ 1429 /* 2d mask */
1403 writel(0xffffffff, fbi->regs2d + SM501_2D_MASK); 1430 smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
1404 1431
1405 /* colour */ 1432 /* colour */
1406 writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND); 1433 smc501_writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND);
1407 1434
1408 /* x y */ 1435 /* x y */
1409 writel((rect->dx << 16) | rect->dy, fbi->regs2d + SM501_2D_DESTINATION); 1436 smc501_writel((rect->dx << 16) | rect->dy,
1437 fbi->regs2d + SM501_2D_DESTINATION);
1410 1438
1411 /* w/h */ 1439 /* w/h */
1412 writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION); 1440 smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
1413 1441
1414 /* do rectangle fill */ 1442 /* do rectangle fill */
1415 writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL); 1443 smc501_writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL);
1416} 1444}
1417 1445
1418 1446
@@ -1470,11 +1498,12 @@ static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base)
1470 1498
1471 /* initialise the colour registers */ 1499 /* initialise the colour registers */
1472 1500
1473 writel(par->cursor.sm_addr, par->cursor_regs + SM501_OFF_HWC_ADDR); 1501 smc501_writel(par->cursor.sm_addr,
1502 par->cursor_regs + SM501_OFF_HWC_ADDR);
1474 1503
1475 writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC); 1504 smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC);
1476 writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2); 1505 smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2);
1477 writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3); 1506 smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3);
1478 sm501fb_sync_regs(info); 1507 sm501fb_sync_regs(info);
1479 1508
1480 return 0; 1509 return 0;
@@ -1581,7 +1610,7 @@ static int sm501fb_start(struct sm501fb_info *info,
1581 1610
1582 /* clear palette ram - undefined at power on */ 1611 /* clear palette ram - undefined at power on */
1583 for (k = 0; k < (256 * 3); k++) 1612 for (k = 0; k < (256 * 3); k++)
1584 writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4)); 1613 smc501_writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4));
1585 1614
1586 /* enable display controller */ 1615 /* enable display controller */
1587 sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1); 1616 sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1);
@@ -1649,20 +1678,20 @@ static int sm501fb_init_fb(struct fb_info *fb,
1649 switch (head) { 1678 switch (head) {
1650 case HEAD_CRT: 1679 case HEAD_CRT:
1651 pd = info->pdata->fb_crt; 1680 pd = info->pdata->fb_crt;
1652 ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 1681 ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
1653 enable = (ctrl & SM501_DC_CRT_CONTROL_ENABLE) ? 1 : 0; 1682 enable = (ctrl & SM501_DC_CRT_CONTROL_ENABLE) ? 1 : 0;
1654 1683
1655 /* ensure we set the correct source register */ 1684 /* ensure we set the correct source register */
1656 if (info->pdata->fb_route != SM501_FB_CRT_PANEL) { 1685 if (info->pdata->fb_route != SM501_FB_CRT_PANEL) {
1657 ctrl |= SM501_DC_CRT_CONTROL_SEL; 1686 ctrl |= SM501_DC_CRT_CONTROL_SEL;
1658 writel(ctrl, info->regs + SM501_DC_CRT_CONTROL); 1687 smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
1659 } 1688 }
1660 1689
1661 break; 1690 break;
1662 1691
1663 case HEAD_PANEL: 1692 case HEAD_PANEL:
1664 pd = info->pdata->fb_pnl; 1693 pd = info->pdata->fb_pnl;
1665 ctrl = readl(info->regs + SM501_DC_PANEL_CONTROL); 1694 ctrl = smc501_readl(info->regs + SM501_DC_PANEL_CONTROL);
1666 enable = (ctrl & SM501_DC_PANEL_CONTROL_EN) ? 1 : 0; 1695 enable = (ctrl & SM501_DC_PANEL_CONTROL_EN) ? 1 : 0;
1667 break; 1696 break;
1668 1697
@@ -1680,7 +1709,7 @@ static int sm501fb_init_fb(struct fb_info *fb,
1680 1709
1681 if (head == HEAD_CRT && info->pdata->fb_route == SM501_FB_CRT_PANEL) { 1710 if (head == HEAD_CRT && info->pdata->fb_route == SM501_FB_CRT_PANEL) {
1682 ctrl &= ~SM501_DC_CRT_CONTROL_SEL; 1711 ctrl &= ~SM501_DC_CRT_CONTROL_SEL;
1683 writel(ctrl, info->regs + SM501_DC_CRT_CONTROL); 1712 smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
1684 enable = 0; 1713 enable = 0;
1685 } 1714 }
1686 1715
@@ -1700,6 +1729,15 @@ static int sm501fb_init_fb(struct fb_info *fb,
1700 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | 1729 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
1701 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; 1730 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
1702 1731
1732#if defined(CONFIG_OF)
1733#ifdef __BIG_ENDIAN
1734 if (of_get_property(info->dev->parent->of_node, "little-endian", NULL))
1735 fb->flags |= FBINFO_FOREIGN_ENDIAN;
1736#else
1737 if (of_get_property(info->dev->parent->of_node, "big-endian", NULL))
1738 fb->flags |= FBINFO_FOREIGN_ENDIAN;
1739#endif
1740#endif
1703 /* fixed data */ 1741 /* fixed data */
1704 1742
1705 fb->fix.type = FB_TYPE_PACKED_PIXELS; 1743 fb->fix.type = FB_TYPE_PACKED_PIXELS;
@@ -1717,9 +1755,16 @@ static int sm501fb_init_fb(struct fb_info *fb,
1717 fb->var.vmode = FB_VMODE_NONINTERLACED; 1755 fb->var.vmode = FB_VMODE_NONINTERLACED;
1718 fb->var.bits_per_pixel = 16; 1756 fb->var.bits_per_pixel = 16;
1719 1757
1758 if (info->edid_data) {
1759 /* Now build modedb from EDID */
1760 fb_edid_to_monspecs(info->edid_data, &fb->monspecs);
1761 fb_videomode_to_modelist(fb->monspecs.modedb,
1762 fb->monspecs.modedb_len,
1763 &fb->modelist);
1764 }
1765
1720 if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) { 1766 if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) {
1721 /* TODO read the mode from the current display */ 1767 /* TODO read the mode from the current display */
1722
1723 } else { 1768 } else {
1724 if (pd->def_mode) { 1769 if (pd->def_mode) {
1725 dev_info(info->dev, "using supplied mode\n"); 1770 dev_info(info->dev, "using supplied mode\n");
@@ -1729,12 +1774,37 @@ static int sm501fb_init_fb(struct fb_info *fb,
1729 fb->var.xres_virtual = fb->var.xres; 1774 fb->var.xres_virtual = fb->var.xres;
1730 fb->var.yres_virtual = fb->var.yres; 1775 fb->var.yres_virtual = fb->var.yres;
1731 } else { 1776 } else {
1732 ret = fb_find_mode(&fb->var, fb, 1777 if (info->edid_data) {
1778 ret = fb_find_mode(&fb->var, fb, fb_mode,
1779 fb->monspecs.modedb,
1780 fb->monspecs.modedb_len,
1781 &sm501_default_mode, default_bpp);
1782 /* edid_data is no longer needed, free it */
1783 kfree(info->edid_data);
1784 } else {
1785 ret = fb_find_mode(&fb->var, fb,
1733 NULL, NULL, 0, NULL, 8); 1786 NULL, NULL, 0, NULL, 8);
1787 }
1734 1788
1735 if (ret == 0 || ret == 4) { 1789 switch (ret) {
1736 dev_err(info->dev, 1790 case 1:
1737 "failed to get initial mode\n"); 1791 dev_info(info->dev, "using mode specified in "
1792 "@mode\n");
1793 break;
1794 case 2:
1795 dev_info(info->dev, "using mode specified in "
1796 "@mode with ignored refresh rate\n");
1797 break;
1798 case 3:
1799 dev_info(info->dev, "using mode default "
1800 "mode\n");
1801 break;
1802 case 4:
1803 dev_info(info->dev, "using mode from list\n");
1804 break;
1805 default:
1806 dev_info(info->dev, "ret = %d\n", ret);
1807 dev_info(info->dev, "failed to find mode\n");
1738 return -EINVAL; 1808 return -EINVAL;
1739 } 1809 }
1740 } 1810 }
@@ -1875,8 +1945,32 @@ static int __devinit sm501fb_probe(struct platform_device *pdev)
1875 } 1945 }
1876 1946
1877 if (info->pdata == NULL) { 1947 if (info->pdata == NULL) {
1878 dev_info(dev, "using default configuration data\n"); 1948 int found = 0;
1949#if defined(CONFIG_OF)
1950 struct device_node *np = pdev->dev.parent->of_node;
1951 const u8 *prop;
1952 const char *cp;
1953 int len;
1954
1879 info->pdata = &sm501fb_def_pdata; 1955 info->pdata = &sm501fb_def_pdata;
1956 if (np) {
1957 /* Get EDID */
1958 cp = of_get_property(np, "mode", &len);
1959 if (cp)
1960 strcpy(fb_mode, cp);
1961 prop = of_get_property(np, "edid", &len);
1962 if (prop && len == EDID_LENGTH) {
1963 info->edid_data = kmemdup(prop, EDID_LENGTH,
1964 GFP_KERNEL);
1965 if (info->edid_data)
1966 found = 1;
1967 }
1968 }
1969#endif
1970 if (!found) {
1971 dev_info(dev, "using default configuration data\n");
1972 info->pdata = &sm501fb_def_pdata;
1973 }
1880 } 1974 }
1881 1975
1882 /* probe for the presence of each panel */ 1976 /* probe for the presence of each panel */
@@ -2085,7 +2179,7 @@ static int sm501fb_suspend(struct platform_device *pdev, pm_message_t state)
2085 struct sm501fb_info *info = platform_get_drvdata(pdev); 2179 struct sm501fb_info *info = platform_get_drvdata(pdev);
2086 2180
2087 /* store crt control to resume with */ 2181 /* store crt control to resume with */
2088 info->pm_crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 2182 info->pm_crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
2089 2183
2090 sm501fb_suspend_fb(info, HEAD_CRT); 2184 sm501fb_suspend_fb(info, HEAD_CRT);
2091 sm501fb_suspend_fb(info, HEAD_PANEL); 2185 sm501fb_suspend_fb(info, HEAD_PANEL);
@@ -2109,10 +2203,10 @@ static int sm501fb_resume(struct platform_device *pdev)
2109 2203
2110 /* restore the items we want to be saved for crt control */ 2204 /* restore the items we want to be saved for crt control */
2111 2205
2112 crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL); 2206 crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
2113 crt_ctrl &= ~SM501_CRT_CTRL_SAVE; 2207 crt_ctrl &= ~SM501_CRT_CTRL_SAVE;
2114 crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE; 2208 crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE;
2115 writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL); 2209 smc501_writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL);
2116 2210
2117 sm501fb_resume_fb(info, HEAD_CRT); 2211 sm501fb_resume_fb(info, HEAD_CRT);
2118 sm501fb_resume_fb(info, HEAD_PANEL); 2212 sm501fb_resume_fb(info, HEAD_PANEL);
@@ -2149,6 +2243,11 @@ static void __exit sm501fb_cleanup(void)
2149module_init(sm501fb_init); 2243module_init(sm501fb_init);
2150module_exit(sm501fb_cleanup); 2244module_exit(sm501fb_cleanup);
2151 2245
2246module_param_named(mode, fb_mode, charp, 0);
2247MODULE_PARM_DESC(mode,
2248 "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
2249module_param_named(bpp, default_bpp, ulong, 0);
2250MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode");
2152MODULE_AUTHOR("Ben Dooks, Vincent Sanders"); 2251MODULE_AUTHOR("Ben Dooks, Vincent Sanders");
2153MODULE_DESCRIPTION("SM501 Framebuffer driver"); 2252MODULE_DESCRIPTION("SM501 Framebuffer driver");
2154MODULE_LICENSE("GPL v2"); 2253MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/svgalib.c b/drivers/video/svgalib.c
index fdb45674e2f..33df9ec9179 100644
--- a/drivers/video/svgalib.c
+++ b/drivers/video/svgalib.c
@@ -20,12 +20,12 @@
20 20
21 21
22/* Write a CRT register value spread across multiple registers */ 22/* Write a CRT register value spread across multiple registers */
23void svga_wcrt_multi(const struct vga_regset *regset, u32 value) { 23void svga_wcrt_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
24 24{
25 u8 regval, bitval, bitnum; 25 u8 regval, bitval, bitnum;
26 26
27 while (regset->regnum != VGA_REGSET_END_VAL) { 27 while (regset->regnum != VGA_REGSET_END_VAL) {
28 regval = vga_rcrt(NULL, regset->regnum); 28 regval = vga_rcrt(regbase, regset->regnum);
29 bitnum = regset->lowbit; 29 bitnum = regset->lowbit;
30 while (bitnum <= regset->highbit) { 30 while (bitnum <= regset->highbit) {
31 bitval = 1 << bitnum; 31 bitval = 1 << bitnum;
@@ -34,18 +34,18 @@ void svga_wcrt_multi(const struct vga_regset *regset, u32 value) {
34 bitnum ++; 34 bitnum ++;
35 value = value >> 1; 35 value = value >> 1;
36 } 36 }
37 vga_wcrt(NULL, regset->regnum, regval); 37 vga_wcrt(regbase, regset->regnum, regval);
38 regset ++; 38 regset ++;
39 } 39 }
40} 40}
41 41
42/* Write a sequencer register value spread across multiple registers */ 42/* Write a sequencer register value spread across multiple registers */
43void svga_wseq_multi(const struct vga_regset *regset, u32 value) { 43void svga_wseq_multi(void __iomem *regbase, const struct vga_regset *regset, u32 value)
44 44{
45 u8 regval, bitval, bitnum; 45 u8 regval, bitval, bitnum;
46 46
47 while (regset->regnum != VGA_REGSET_END_VAL) { 47 while (regset->regnum != VGA_REGSET_END_VAL) {
48 regval = vga_rseq(NULL, regset->regnum); 48 regval = vga_rseq(regbase, regset->regnum);
49 bitnum = regset->lowbit; 49 bitnum = regset->lowbit;
50 while (bitnum <= regset->highbit) { 50 while (bitnum <= regset->highbit) {
51 bitval = 1 << bitnum; 51 bitval = 1 << bitnum;
@@ -54,7 +54,7 @@ void svga_wseq_multi(const struct vga_regset *regset, u32 value) {
54 bitnum ++; 54 bitnum ++;
55 value = value >> 1; 55 value = value >> 1;
56 } 56 }
57 vga_wseq(NULL, regset->regnum, regval); 57 vga_wseq(regbase, regset->regnum, regval);
58 regset ++; 58 regset ++;
59 } 59 }
60} 60}
@@ -75,95 +75,95 @@ static unsigned int svga_regset_size(const struct vga_regset *regset)
75 75
76 76
77/* Set graphics controller registers to sane values */ 77/* Set graphics controller registers to sane values */
78void svga_set_default_gfx_regs(void) 78void svga_set_default_gfx_regs(void __iomem *regbase)
79{ 79{
80 /* All standard GFX registers (GR00 - GR08) */ 80 /* All standard GFX registers (GR00 - GR08) */
81 vga_wgfx(NULL, VGA_GFX_SR_VALUE, 0x00); 81 vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0x00);
82 vga_wgfx(NULL, VGA_GFX_SR_ENABLE, 0x00); 82 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0x00);
83 vga_wgfx(NULL, VGA_GFX_COMPARE_VALUE, 0x00); 83 vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0x00);
84 vga_wgfx(NULL, VGA_GFX_DATA_ROTATE, 0x00); 84 vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0x00);
85 vga_wgfx(NULL, VGA_GFX_PLANE_READ, 0x00); 85 vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0x00);
86 vga_wgfx(NULL, VGA_GFX_MODE, 0x00); 86 vga_wgfx(regbase, VGA_GFX_MODE, 0x00);
87/* vga_wgfx(NULL, VGA_GFX_MODE, 0x20); */ 87/* vga_wgfx(regbase, VGA_GFX_MODE, 0x20); */
88/* vga_wgfx(NULL, VGA_GFX_MODE, 0x40); */ 88/* vga_wgfx(regbase, VGA_GFX_MODE, 0x40); */
89 vga_wgfx(NULL, VGA_GFX_MISC, 0x05); 89 vga_wgfx(regbase, VGA_GFX_MISC, 0x05);
90/* vga_wgfx(NULL, VGA_GFX_MISC, 0x01); */ 90/* vga_wgfx(regbase, VGA_GFX_MISC, 0x01); */
91 vga_wgfx(NULL, VGA_GFX_COMPARE_MASK, 0x0F); 91 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x0F);
92 vga_wgfx(NULL, VGA_GFX_BIT_MASK, 0xFF); 92 vga_wgfx(regbase, VGA_GFX_BIT_MASK, 0xFF);
93} 93}
94 94
95/* Set attribute controller registers to sane values */ 95/* Set attribute controller registers to sane values */
96void svga_set_default_atc_regs(void) 96void svga_set_default_atc_regs(void __iomem *regbase)
97{ 97{
98 u8 count; 98 u8 count;
99 99
100 vga_r(NULL, 0x3DA); 100 vga_r(regbase, 0x3DA);
101 vga_w(NULL, VGA_ATT_W, 0x00); 101 vga_w(regbase, VGA_ATT_W, 0x00);
102 102
103 /* All standard ATC registers (AR00 - AR14) */ 103 /* All standard ATC registers (AR00 - AR14) */
104 for (count = 0; count <= 0xF; count ++) 104 for (count = 0; count <= 0xF; count ++)
105 svga_wattr(count, count); 105 svga_wattr(regbase, count, count);
106 106
107 svga_wattr(VGA_ATC_MODE, 0x01); 107 svga_wattr(regbase, VGA_ATC_MODE, 0x01);
108/* svga_wattr(VGA_ATC_MODE, 0x41); */ 108/* svga_wattr(regbase, VGA_ATC_MODE, 0x41); */
109 svga_wattr(VGA_ATC_OVERSCAN, 0x00); 109 svga_wattr(regbase, VGA_ATC_OVERSCAN, 0x00);
110 svga_wattr(VGA_ATC_PLANE_ENABLE, 0x0F); 110 svga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 0x0F);
111 svga_wattr(VGA_ATC_PEL, 0x00); 111 svga_wattr(regbase, VGA_ATC_PEL, 0x00);
112 svga_wattr(VGA_ATC_COLOR_PAGE, 0x00); 112 svga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0x00);
113 113
114 vga_r(NULL, 0x3DA); 114 vga_r(regbase, 0x3DA);
115 vga_w(NULL, VGA_ATT_W, 0x20); 115 vga_w(regbase, VGA_ATT_W, 0x20);
116} 116}
117 117
118/* Set sequencer registers to sane values */ 118/* Set sequencer registers to sane values */
119void svga_set_default_seq_regs(void) 119void svga_set_default_seq_regs(void __iomem *regbase)
120{ 120{
121 /* Standard sequencer registers (SR01 - SR04), SR00 is not set */ 121 /* Standard sequencer registers (SR01 - SR04), SR00 is not set */
122 vga_wseq(NULL, VGA_SEQ_CLOCK_MODE, VGA_SR01_CHAR_CLK_8DOTS); 122 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, VGA_SR01_CHAR_CLK_8DOTS);
123 vga_wseq(NULL, VGA_SEQ_PLANE_WRITE, VGA_SR02_ALL_PLANES); 123 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, VGA_SR02_ALL_PLANES);
124 vga_wseq(NULL, VGA_SEQ_CHARACTER_MAP, 0x00); 124 vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
125/* vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE | VGA_SR04_CHN_4M); */ 125/* vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE | VGA_SR04_CHN_4M); */
126 vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE); 126 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE);
127} 127}
128 128
129/* Set CRTC registers to sane values */ 129/* Set CRTC registers to sane values */
130void svga_set_default_crt_regs(void) 130void svga_set_default_crt_regs(void __iomem *regbase)
131{ 131{
132 /* Standard CRT registers CR03 CR08 CR09 CR14 CR17 */ 132 /* Standard CRT registers CR03 CR08 CR09 CR14 CR17 */
133 svga_wcrt_mask(0x03, 0x80, 0x80); /* Enable vertical retrace EVRA */ 133 svga_wcrt_mask(regbase, 0x03, 0x80, 0x80); /* Enable vertical retrace EVRA */
134 vga_wcrt(NULL, VGA_CRTC_PRESET_ROW, 0); 134 vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
135 svga_wcrt_mask(VGA_CRTC_MAX_SCAN, 0, 0x1F); 135 svga_wcrt_mask(regbase, VGA_CRTC_MAX_SCAN, 0, 0x1F);
136 vga_wcrt(NULL, VGA_CRTC_UNDERLINE, 0); 136 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
137 vga_wcrt(NULL, VGA_CRTC_MODE, 0xE3); 137 vga_wcrt(regbase, VGA_CRTC_MODE, 0xE3);
138} 138}
139 139
140void svga_set_textmode_vga_regs(void) 140void svga_set_textmode_vga_regs(void __iomem *regbase)
141{ 141{
142 /* svga_wseq_mask(0x1, 0x00, 0x01); */ /* Switch 8/9 pixel per char */ 142 /* svga_wseq_mask(regbase, 0x1, 0x00, 0x01); */ /* Switch 8/9 pixel per char */
143 vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM); 143 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM);
144 vga_wseq(NULL, VGA_SEQ_PLANE_WRITE, 0x03); 144 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x03);
145 145
146 vga_wcrt(NULL, VGA_CRTC_MAX_SCAN, 0x0f); /* 0x4f */ 146 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, 0x0f); /* 0x4f */
147 vga_wcrt(NULL, VGA_CRTC_UNDERLINE, 0x1f); 147 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0x1f);
148 svga_wcrt_mask(VGA_CRTC_MODE, 0x23, 0x7f); 148 svga_wcrt_mask(regbase, VGA_CRTC_MODE, 0x23, 0x7f);
149 149
150 vga_wcrt(NULL, VGA_CRTC_CURSOR_START, 0x0d); 150 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0x0d);
151 vga_wcrt(NULL, VGA_CRTC_CURSOR_END, 0x0e); 151 vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 0x0e);
152 vga_wcrt(NULL, VGA_CRTC_CURSOR_HI, 0x00); 152 vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0x00);
153 vga_wcrt(NULL, VGA_CRTC_CURSOR_LO, 0x00); 153 vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0x00);
154 154
155 vga_wgfx(NULL, VGA_GFX_MODE, 0x10); /* Odd/even memory mode */ 155 vga_wgfx(regbase, VGA_GFX_MODE, 0x10); /* Odd/even memory mode */
156 vga_wgfx(NULL, VGA_GFX_MISC, 0x0E); /* Misc graphics register - text mode enable */ 156 vga_wgfx(regbase, VGA_GFX_MISC, 0x0E); /* Misc graphics register - text mode enable */
157 vga_wgfx(NULL, VGA_GFX_COMPARE_MASK, 0x00); 157 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 0x00);
158 158
159 vga_r(NULL, 0x3DA); 159 vga_r(regbase, 0x3DA);
160 vga_w(NULL, VGA_ATT_W, 0x00); 160 vga_w(regbase, VGA_ATT_W, 0x00);
161 161
162 svga_wattr(0x10, 0x0C); /* Attribute Mode Control Register - text mode, blinking and line graphics */ 162 svga_wattr(regbase, 0x10, 0x0C); /* Attribute Mode Control Register - text mode, blinking and line graphics */
163 svga_wattr(0x13, 0x08); /* Horizontal Pixel Panning Register */ 163 svga_wattr(regbase, 0x13, 0x08); /* Horizontal Pixel Panning Register */
164 164
165 vga_r(NULL, 0x3DA); 165 vga_r(regbase, 0x3DA);
166 vga_w(NULL, VGA_ATT_W, 0x20); 166 vga_w(regbase, VGA_ATT_W, 0x20);
167} 167}
168 168
169#if 0 169#if 0
@@ -299,7 +299,7 @@ void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit)
299} 299}
300 300
301/* Set cursor in text (tileblit) mode */ 301/* Set cursor in text (tileblit) mode */
302void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor) 302void svga_tilecursor(void __iomem *regbase, struct fb_info *info, struct fb_tilecursor *cursor)
303{ 303{
304 u8 cs = 0x0d; 304 u8 cs = 0x0d;
305 u8 ce = 0x0e; 305 u8 ce = 0x0e;
@@ -310,7 +310,7 @@ void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
310 if (! cursor -> mode) 310 if (! cursor -> mode)
311 return; 311 return;
312 312
313 svga_wcrt_mask(0x0A, 0x20, 0x20); /* disable cursor */ 313 svga_wcrt_mask(regbase, 0x0A, 0x20, 0x20); /* disable cursor */
314 314
315 if (cursor -> shape == FB_TILE_CURSOR_NONE) 315 if (cursor -> shape == FB_TILE_CURSOR_NONE)
316 return; 316 return;
@@ -334,11 +334,11 @@ void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
334 } 334 }
335 335
336 /* set cursor position */ 336 /* set cursor position */
337 vga_wcrt(NULL, 0x0E, pos >> 8); 337 vga_wcrt(regbase, 0x0E, pos >> 8);
338 vga_wcrt(NULL, 0x0F, pos & 0xFF); 338 vga_wcrt(regbase, 0x0F, pos & 0xFF);
339 339
340 vga_wcrt(NULL, 0x0B, ce); /* set cursor end */ 340 vga_wcrt(regbase, 0x0B, ce); /* set cursor end */
341 vga_wcrt(NULL, 0x0A, cs); /* set cursor start and enable it */ 341 vga_wcrt(regbase, 0x0A, cs); /* set cursor start and enable it */
342} 342}
343 343
344int svga_get_tilemax(struct fb_info *info) 344int svga_get_tilemax(struct fb_info *info)
@@ -507,8 +507,9 @@ int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screenin
507} 507}
508 508
509/* Set CRT timing registers */ 509/* Set CRT timing registers */
510void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, 510void svga_set_timings(void __iomem *regbase, const struct svga_timing_regs *tm,
511 u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node) 511 struct fb_var_screeninfo *var,
512 u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node)
512{ 513{
513 u8 regval; 514 u8 regval;
514 u32 value; 515 u32 value;
@@ -516,66 +517,66 @@ void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninf
516 value = var->xres + var->left_margin + var->right_margin + var->hsync_len; 517 value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
517 value = (value * hmul) / hdiv; 518 value = (value * hmul) / hdiv;
518 pr_debug("fb%d: horizontal total : %d\n", node, value); 519 pr_debug("fb%d: horizontal total : %d\n", node, value);
519 svga_wcrt_multi(tm->h_total_regs, (value / 8) - 5); 520 svga_wcrt_multi(regbase, tm->h_total_regs, (value / 8) - 5);
520 521
521 value = var->xres; 522 value = var->xres;
522 value = (value * hmul) / hdiv; 523 value = (value * hmul) / hdiv;
523 pr_debug("fb%d: horizontal display : %d\n", node, value); 524 pr_debug("fb%d: horizontal display : %d\n", node, value);
524 svga_wcrt_multi(tm->h_display_regs, (value / 8) - 1); 525 svga_wcrt_multi(regbase, tm->h_display_regs, (value / 8) - 1);
525 526
526 value = var->xres; 527 value = var->xres;
527 value = (value * hmul) / hdiv; 528 value = (value * hmul) / hdiv;
528 pr_debug("fb%d: horizontal blank start: %d\n", node, value); 529 pr_debug("fb%d: horizontal blank start: %d\n", node, value);
529 svga_wcrt_multi(tm->h_blank_start_regs, (value / 8) - 1 + hborder); 530 svga_wcrt_multi(regbase, tm->h_blank_start_regs, (value / 8) - 1 + hborder);
530 531
531 value = var->xres + var->left_margin + var->right_margin + var->hsync_len; 532 value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
532 value = (value * hmul) / hdiv; 533 value = (value * hmul) / hdiv;
533 pr_debug("fb%d: horizontal blank end : %d\n", node, value); 534 pr_debug("fb%d: horizontal blank end : %d\n", node, value);
534 svga_wcrt_multi(tm->h_blank_end_regs, (value / 8) - 1 - hborder); 535 svga_wcrt_multi(regbase, tm->h_blank_end_regs, (value / 8) - 1 - hborder);
535 536
536 value = var->xres + var->right_margin; 537 value = var->xres + var->right_margin;
537 value = (value * hmul) / hdiv; 538 value = (value * hmul) / hdiv;
538 pr_debug("fb%d: horizontal sync start : %d\n", node, value); 539 pr_debug("fb%d: horizontal sync start : %d\n", node, value);
539 svga_wcrt_multi(tm->h_sync_start_regs, (value / 8)); 540 svga_wcrt_multi(regbase, tm->h_sync_start_regs, (value / 8));
540 541
541 value = var->xres + var->right_margin + var->hsync_len; 542 value = var->xres + var->right_margin + var->hsync_len;
542 value = (value * hmul) / hdiv; 543 value = (value * hmul) / hdiv;
543 pr_debug("fb%d: horizontal sync end : %d\n", node, value); 544 pr_debug("fb%d: horizontal sync end : %d\n", node, value);
544 svga_wcrt_multi(tm->h_sync_end_regs, (value / 8)); 545 svga_wcrt_multi(regbase, tm->h_sync_end_regs, (value / 8));
545 546
546 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len; 547 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
547 value = (value * vmul) / vdiv; 548 value = (value * vmul) / vdiv;
548 pr_debug("fb%d: vertical total : %d\n", node, value); 549 pr_debug("fb%d: vertical total : %d\n", node, value);
549 svga_wcrt_multi(tm->v_total_regs, value - 2); 550 svga_wcrt_multi(regbase, tm->v_total_regs, value - 2);
550 551
551 value = var->yres; 552 value = var->yres;
552 value = (value * vmul) / vdiv; 553 value = (value * vmul) / vdiv;
553 pr_debug("fb%d: vertical display : %d\n", node, value); 554 pr_debug("fb%d: vertical display : %d\n", node, value);
554 svga_wcrt_multi(tm->v_display_regs, value - 1); 555 svga_wcrt_multi(regbase, tm->v_display_regs, value - 1);
555 556
556 value = var->yres; 557 value = var->yres;
557 value = (value * vmul) / vdiv; 558 value = (value * vmul) / vdiv;
558 pr_debug("fb%d: vertical blank start : %d\n", node, value); 559 pr_debug("fb%d: vertical blank start : %d\n", node, value);
559 svga_wcrt_multi(tm->v_blank_start_regs, value); 560 svga_wcrt_multi(regbase, tm->v_blank_start_regs, value);
560 561
561 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len; 562 value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
562 value = (value * vmul) / vdiv; 563 value = (value * vmul) / vdiv;
563 pr_debug("fb%d: vertical blank end : %d\n", node, value); 564 pr_debug("fb%d: vertical blank end : %d\n", node, value);
564 svga_wcrt_multi(tm->v_blank_end_regs, value - 2); 565 svga_wcrt_multi(regbase, tm->v_blank_end_regs, value - 2);
565 566
566 value = var->yres + var->lower_margin; 567 value = var->yres + var->lower_margin;
567 value = (value * vmul) / vdiv; 568 value = (value * vmul) / vdiv;
568 pr_debug("fb%d: vertical sync start : %d\n", node, value); 569 pr_debug("fb%d: vertical sync start : %d\n", node, value);
569 svga_wcrt_multi(tm->v_sync_start_regs, value); 570 svga_wcrt_multi(regbase, tm->v_sync_start_regs, value);
570 571
571 value = var->yres + var->lower_margin + var->vsync_len; 572 value = var->yres + var->lower_margin + var->vsync_len;
572 value = (value * vmul) / vdiv; 573 value = (value * vmul) / vdiv;
573 pr_debug("fb%d: vertical sync end : %d\n", node, value); 574 pr_debug("fb%d: vertical sync end : %d\n", node, value);
574 svga_wcrt_multi(tm->v_sync_end_regs, value); 575 svga_wcrt_multi(regbase, tm->v_sync_end_regs, value);
575 576
576 /* Set horizontal and vertical sync pulse polarity in misc register */ 577 /* Set horizontal and vertical sync pulse polarity in misc register */
577 578
578 regval = vga_r(NULL, VGA_MIS_R); 579 regval = vga_r(regbase, VGA_MIS_R);
579 if (var->sync & FB_SYNC_HOR_HIGH_ACT) { 580 if (var->sync & FB_SYNC_HOR_HIGH_ACT) {
580 pr_debug("fb%d: positive horizontal sync\n", node); 581 pr_debug("fb%d: positive horizontal sync\n", node);
581 regval = regval & ~0x80; 582 regval = regval & ~0x80;
@@ -590,7 +591,7 @@ void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninf
590 pr_debug("fb%d: negative vertical sync\n\n", node); 591 pr_debug("fb%d: negative vertical sync\n\n", node);
591 regval = regval | 0x40; 592 regval = regval | 0x40;
592 } 593 }
593 vga_w(NULL, VGA_MIS_W, regval); 594 vga_w(regbase, VGA_MIS_W, regval);
594} 595}
595 596
596 597
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 855b71993f6..07c66e94663 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -480,6 +480,7 @@ out_dealloc_cmap:
480 480
481out_unmap_regs: 481out_unmap_regs:
482 tcx_unmap_regs(op, info, par); 482 tcx_unmap_regs(op, info, par);
483 framebuffer_release(info);
483 484
484out_err: 485out_err:
485 return err; 486 return err;
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 5180a215d78..7f8472cc993 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -1552,8 +1552,7 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
1552 int rc; 1552 int rc;
1553 1553
1554 /* Find the largest power-of-two */ 1554 /* Find the largest power-of-two */
1555 while (temp_size & (temp_size - 1)) 1555 temp_size = roundup_pow_of_two(temp_size);
1556 temp_size &= (temp_size - 1);
1557 1556
1558 /* Try and find a power of two to add */ 1557 /* Try and find a power of two to add */
1559 do { 1558 do {
@@ -1566,6 +1565,28 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
1566#endif /* CONFIG_MTRR */ 1565#endif /* CONFIG_MTRR */
1567} 1566}
1568 1567
1568static void __devinit uvesafb_ioremap(struct fb_info *info)
1569{
1570#ifdef CONFIG_X86
1571 switch (mtrr) {
1572 case 1: /* uncachable */
1573 info->screen_base = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
1574 break;
1575 case 2: /* write-back */
1576 info->screen_base = ioremap_cache(info->fix.smem_start, info->fix.smem_len);
1577 break;
1578 case 3: /* write-combining */
1579 info->screen_base = ioremap_wc(info->fix.smem_start, info->fix.smem_len);
1580 break;
1581 case 4: /* write-through */
1582 default:
1583 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
1584 break;
1585 }
1586#else
1587 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
1588#endif /* CONFIG_X86 */
1589}
1569 1590
1570static ssize_t uvesafb_show_vbe_ver(struct device *dev, 1591static ssize_t uvesafb_show_vbe_ver(struct device *dev,
1571 struct device_attribute *attr, char *buf) 1592 struct device_attribute *attr, char *buf)
@@ -1736,15 +1757,22 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
1736 1757
1737 uvesafb_init_info(info, mode); 1758 uvesafb_init_info(info, mode);
1738 1759
1760 if (!request_region(0x3c0, 32, "uvesafb")) {
1761 printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
1762 err = -EIO;
1763 goto out_mode;
1764 }
1765
1739 if (!request_mem_region(info->fix.smem_start, info->fix.smem_len, 1766 if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,
1740 "uvesafb")) { 1767 "uvesafb")) {
1741 printk(KERN_ERR "uvesafb: cannot reserve video memory at " 1768 printk(KERN_ERR "uvesafb: cannot reserve video memory at "
1742 "0x%lx\n", info->fix.smem_start); 1769 "0x%lx\n", info->fix.smem_start);
1743 err = -EIO; 1770 err = -EIO;
1744 goto out_mode; 1771 goto out_reg;
1745 } 1772 }
1746 1773
1747 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); 1774 uvesafb_init_mtrr(info);
1775 uvesafb_ioremap(info);
1748 1776
1749 if (!info->screen_base) { 1777 if (!info->screen_base) {
1750 printk(KERN_ERR 1778 printk(KERN_ERR
@@ -1755,20 +1783,13 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
1755 goto out_mem; 1783 goto out_mem;
1756 } 1784 }
1757 1785
1758 if (!request_region(0x3c0, 32, "uvesafb")) {
1759 printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
1760 err = -EIO;
1761 goto out_unmap;
1762 }
1763
1764 uvesafb_init_mtrr(info);
1765 platform_set_drvdata(dev, info); 1786 platform_set_drvdata(dev, info);
1766 1787
1767 if (register_framebuffer(info) < 0) { 1788 if (register_framebuffer(info) < 0) {
1768 printk(KERN_ERR 1789 printk(KERN_ERR
1769 "uvesafb: failed to register framebuffer device\n"); 1790 "uvesafb: failed to register framebuffer device\n");
1770 err = -EINVAL; 1791 err = -EINVAL;
1771 goto out_reg; 1792 goto out_unmap;
1772 } 1793 }
1773 1794
1774 printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, " 1795 printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, "
@@ -1785,12 +1806,12 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
1785 1806
1786 return 0; 1807 return 0;
1787 1808
1788out_reg:
1789 release_region(0x3c0, 32);
1790out_unmap: 1809out_unmap:
1791 iounmap(info->screen_base); 1810 iounmap(info->screen_base);
1792out_mem: 1811out_mem:
1793 release_mem_region(info->fix.smem_start, info->fix.smem_len); 1812 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1813out_reg:
1814 release_region(0x3c0, 32);
1794out_mode: 1815out_mode:
1795 if (!list_empty(&info->modelist)) 1816 if (!list_empty(&info->modelist))
1796 fb_destroy_modelist(&info->modelist); 1817 fb_destroy_modelist(&info->modelist);
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index 931a567f9af..970e43d13f5 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -891,8 +891,7 @@ static int vmlfb_set_par(struct fb_info *info)
891 int ret; 891 int ret;
892 892
893 mutex_lock(&vml_mutex); 893 mutex_lock(&vml_mutex);
894 list_del(&vinfo->head); 894 list_move(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
895 list_add(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
896 ret = vmlfb_set_par_locked(vinfo); 895 ret = vmlfb_set_par_locked(vinfo);
897 896
898 mutex_unlock(&vml_mutex); 897 mutex_unlock(&vml_mutex);
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 6a069d04791..a99bbe86db1 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -303,19 +303,6 @@ static int __init vesafb_probe(struct platform_device *dev)
303 info->apertures->ranges[0].base = screen_info.lfb_base; 303 info->apertures->ranges[0].base = screen_info.lfb_base;
304 info->apertures->ranges[0].size = size_total; 304 info->apertures->ranges[0].size = size_total;
305 305
306 info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
307 if (!info->screen_base) {
308 printk(KERN_ERR
309 "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
310 vesafb_fix.smem_len, vesafb_fix.smem_start);
311 err = -EIO;
312 goto err;
313 }
314
315 printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, "
316 "using %dk, total %dk\n",
317 vesafb_fix.smem_start, info->screen_base,
318 size_remap/1024, size_total/1024);
319 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n", 306 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
320 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages); 307 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
321 308
@@ -438,8 +425,7 @@ static int __init vesafb_probe(struct platform_device *dev)
438 int rc; 425 int rc;
439 426
440 /* Find the largest power-of-two */ 427 /* Find the largest power-of-two */
441 while (temp_size & (temp_size - 1)) 428 temp_size = roundup_pow_of_two(temp_size);
442 temp_size &= (temp_size - 1);
443 429
444 /* Try and find a power of two to add */ 430 /* Try and find a power of two to add */
445 do { 431 do {
@@ -451,6 +437,34 @@ static int __init vesafb_probe(struct platform_device *dev)
451 } 437 }
452#endif 438#endif
453 439
440 switch (mtrr) {
441 case 1: /* uncachable */
442 info->screen_base = ioremap_nocache(vesafb_fix.smem_start, vesafb_fix.smem_len);
443 break;
444 case 2: /* write-back */
445 info->screen_base = ioremap_cache(vesafb_fix.smem_start, vesafb_fix.smem_len);
446 break;
447 case 3: /* write-combining */
448 info->screen_base = ioremap_wc(vesafb_fix.smem_start, vesafb_fix.smem_len);
449 break;
450 case 4: /* write-through */
451 default:
452 info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
453 break;
454 }
455 if (!info->screen_base) {
456 printk(KERN_ERR
457 "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
458 vesafb_fix.smem_len, vesafb_fix.smem_start);
459 err = -EIO;
460 goto err;
461 }
462
463 printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, "
464 "using %dk, total %dk\n",
465 vesafb_fix.smem_start, info->screen_base,
466 size_remap/1024, size_total/1024);
467
454 info->fbops = &vesafb_ops; 468 info->fbops = &vesafb_ops;
455 info->var = vesafb_defined; 469 info->var = vesafb_defined;
456 info->fix = vesafb_fix; 470 info->fix = vesafb_fix;
diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c
index a2965ab92cf..f9b3e3dc242 100644
--- a/drivers/video/vt8623fb.c
+++ b/drivers/video/vt8623fb.c
@@ -121,13 +121,19 @@ MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, d
121 121
122/* ------------------------------------------------------------------------- */ 122/* ------------------------------------------------------------------------- */
123 123
124static void vt8623fb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
125{
126 struct vt8623fb_info *par = info->par;
127
128 svga_tilecursor(par->state.vgabase, info, cursor);
129}
124 130
125static struct fb_tile_ops vt8623fb_tile_ops = { 131static struct fb_tile_ops vt8623fb_tile_ops = {
126 .fb_settile = svga_settile, 132 .fb_settile = svga_settile,
127 .fb_tilecopy = svga_tilecopy, 133 .fb_tilecopy = svga_tilecopy,
128 .fb_tilefill = svga_tilefill, 134 .fb_tilefill = svga_tilefill,
129 .fb_tileblit = svga_tileblit, 135 .fb_tileblit = svga_tileblit,
130 .fb_tilecursor = svga_tilecursor, 136 .fb_tilecursor = vt8623fb_tilecursor,
131 .fb_get_tilemax = svga_get_tilemax, 137 .fb_get_tilemax = svga_get_tilemax,
132}; 138};
133 139
@@ -253,6 +259,7 @@ static void vt8623fb_fillrect(struct fb_info *info, const struct fb_fillrect *re
253 259
254static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock) 260static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock)
255{ 261{
262 struct vt8623fb_info *par = info->par;
256 u16 m, n, r; 263 u16 m, n, r;
257 u8 regval; 264 u8 regval;
258 int rv; 265 int rv;
@@ -264,18 +271,18 @@ static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock)
264 } 271 }
265 272
266 /* Set VGA misc register */ 273 /* Set VGA misc register */
267 regval = vga_r(NULL, VGA_MIS_R); 274 regval = vga_r(par->state.vgabase, VGA_MIS_R);
268 vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 275 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
269 276
270 /* Set clock registers */ 277 /* Set clock registers */
271 vga_wseq(NULL, 0x46, (n | (r << 6))); 278 vga_wseq(par->state.vgabase, 0x46, (n | (r << 6)));
272 vga_wseq(NULL, 0x47, m); 279 vga_wseq(par->state.vgabase, 0x47, m);
273 280
274 udelay(1000); 281 udelay(1000);
275 282
276 /* PLL reset */ 283 /* PLL reset */
277 svga_wseq_mask(0x40, 0x02, 0x02); 284 svga_wseq_mask(par->state.vgabase, 0x40, 0x02, 0x02);
278 svga_wseq_mask(0x40, 0x00, 0x02); 285 svga_wseq_mask(par->state.vgabase, 0x40, 0x00, 0x02);
279} 286}
280 287
281 288
@@ -285,7 +292,10 @@ static int vt8623fb_open(struct fb_info *info, int user)
285 292
286 mutex_lock(&(par->open_lock)); 293 mutex_lock(&(par->open_lock));
287 if (par->ref_count == 0) { 294 if (par->ref_count == 0) {
295 void __iomem *vgabase = par->state.vgabase;
296
288 memset(&(par->state), 0, sizeof(struct vgastate)); 297 memset(&(par->state), 0, sizeof(struct vgastate));
298 par->state.vgabase = vgabase;
289 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 299 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
290 par->state.num_crtc = 0xA2; 300 par->state.num_crtc = 0xA2;
291 par->state.num_seq = 0x50; 301 par->state.num_seq = 0x50;
@@ -373,6 +383,7 @@ static int vt8623fb_check_var(struct fb_var_screeninfo *var, struct fb_info *inf
373static int vt8623fb_set_par(struct fb_info *info) 383static int vt8623fb_set_par(struct fb_info *info)
374{ 384{
375 u32 mode, offset_value, fetch_value, screen_size; 385 u32 mode, offset_value, fetch_value, screen_size;
386 struct vt8623fb_info *par = info->par;
376 u32 bpp = info->var.bits_per_pixel; 387 u32 bpp = info->var.bits_per_pixel;
377 388
378 if (bpp != 0) { 389 if (bpp != 0) {
@@ -414,82 +425,82 @@ static int vt8623fb_set_par(struct fb_info *info)
414 info->var.activate = FB_ACTIVATE_NOW; 425 info->var.activate = FB_ACTIVATE_NOW;
415 426
416 /* Unlock registers */ 427 /* Unlock registers */
417 svga_wseq_mask(0x10, 0x01, 0x01); 428 svga_wseq_mask(par->state.vgabase, 0x10, 0x01, 0x01);
418 svga_wcrt_mask(0x11, 0x00, 0x80); 429 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
419 svga_wcrt_mask(0x47, 0x00, 0x01); 430 svga_wcrt_mask(par->state.vgabase, 0x47, 0x00, 0x01);
420 431
421 /* Device, screen and sync off */ 432 /* Device, screen and sync off */
422 svga_wseq_mask(0x01, 0x20, 0x20); 433 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
423 svga_wcrt_mask(0x36, 0x30, 0x30); 434 svga_wcrt_mask(par->state.vgabase, 0x36, 0x30, 0x30);
424 svga_wcrt_mask(0x17, 0x00, 0x80); 435 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
425 436
426 /* Set default values */ 437 /* Set default values */
427 svga_set_default_gfx_regs(); 438 svga_set_default_gfx_regs(par->state.vgabase);
428 svga_set_default_atc_regs(); 439 svga_set_default_atc_regs(par->state.vgabase);
429 svga_set_default_seq_regs(); 440 svga_set_default_seq_regs(par->state.vgabase);
430 svga_set_default_crt_regs(); 441 svga_set_default_crt_regs(par->state.vgabase);
431 svga_wcrt_multi(vt8623_line_compare_regs, 0xFFFFFFFF); 442 svga_wcrt_multi(par->state.vgabase, vt8623_line_compare_regs, 0xFFFFFFFF);
432 svga_wcrt_multi(vt8623_start_address_regs, 0); 443 svga_wcrt_multi(par->state.vgabase, vt8623_start_address_regs, 0);
433 444
434 svga_wcrt_multi(vt8623_offset_regs, offset_value); 445 svga_wcrt_multi(par->state.vgabase, vt8623_offset_regs, offset_value);
435 svga_wseq_multi(vt8623_fetch_count_regs, fetch_value); 446 svga_wseq_multi(par->state.vgabase, vt8623_fetch_count_regs, fetch_value);
436 447
437 /* Clear H/V Skew */ 448 /* Clear H/V Skew */
438 svga_wcrt_mask(0x03, 0x00, 0x60); 449 svga_wcrt_mask(par->state.vgabase, 0x03, 0x00, 0x60);
439 svga_wcrt_mask(0x05, 0x00, 0x60); 450 svga_wcrt_mask(par->state.vgabase, 0x05, 0x00, 0x60);
440 451
441 if (info->var.vmode & FB_VMODE_DOUBLE) 452 if (info->var.vmode & FB_VMODE_DOUBLE)
442 svga_wcrt_mask(0x09, 0x80, 0x80); 453 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
443 else 454 else
444 svga_wcrt_mask(0x09, 0x00, 0x80); 455 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
445 456
446 svga_wseq_mask(0x1E, 0xF0, 0xF0); // DI/DVP bus 457 svga_wseq_mask(par->state.vgabase, 0x1E, 0xF0, 0xF0); // DI/DVP bus
447 svga_wseq_mask(0x2A, 0x0F, 0x0F); // DI/DVP bus 458 svga_wseq_mask(par->state.vgabase, 0x2A, 0x0F, 0x0F); // DI/DVP bus
448 svga_wseq_mask(0x16, 0x08, 0xBF); // FIFO read threshold 459 svga_wseq_mask(par->state.vgabase, 0x16, 0x08, 0xBF); // FIFO read threshold
449 vga_wseq(NULL, 0x17, 0x1F); // FIFO depth 460 vga_wseq(par->state.vgabase, 0x17, 0x1F); // FIFO depth
450 vga_wseq(NULL, 0x18, 0x4E); 461 vga_wseq(par->state.vgabase, 0x18, 0x4E);
451 svga_wseq_mask(0x1A, 0x08, 0x08); // enable MMIO ? 462 svga_wseq_mask(par->state.vgabase, 0x1A, 0x08, 0x08); // enable MMIO ?
452 463
453 vga_wcrt(NULL, 0x32, 0x00); 464 vga_wcrt(par->state.vgabase, 0x32, 0x00);
454 vga_wcrt(NULL, 0x34, 0x00); 465 vga_wcrt(par->state.vgabase, 0x34, 0x00);
455 vga_wcrt(NULL, 0x6A, 0x80); 466 vga_wcrt(par->state.vgabase, 0x6A, 0x80);
456 vga_wcrt(NULL, 0x6A, 0xC0); 467 vga_wcrt(par->state.vgabase, 0x6A, 0xC0);
457 468
458 vga_wgfx(NULL, 0x20, 0x00); 469 vga_wgfx(par->state.vgabase, 0x20, 0x00);
459 vga_wgfx(NULL, 0x21, 0x00); 470 vga_wgfx(par->state.vgabase, 0x21, 0x00);
460 vga_wgfx(NULL, 0x22, 0x00); 471 vga_wgfx(par->state.vgabase, 0x22, 0x00);
461 472
462 /* Set SR15 according to number of bits per pixel */ 473 /* Set SR15 according to number of bits per pixel */
463 mode = svga_match_format(vt8623fb_formats, &(info->var), &(info->fix)); 474 mode = svga_match_format(vt8623fb_formats, &(info->var), &(info->fix));
464 switch (mode) { 475 switch (mode) {
465 case 0: 476 case 0:
466 pr_debug("fb%d: text mode\n", info->node); 477 pr_debug("fb%d: text mode\n", info->node);
467 svga_set_textmode_vga_regs(); 478 svga_set_textmode_vga_regs(par->state.vgabase);
468 svga_wseq_mask(0x15, 0x00, 0xFE); 479 svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);
469 svga_wcrt_mask(0x11, 0x60, 0x70); 480 svga_wcrt_mask(par->state.vgabase, 0x11, 0x60, 0x70);
470 break; 481 break;
471 case 1: 482 case 1:
472 pr_debug("fb%d: 4 bit pseudocolor\n", info->node); 483 pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
473 vga_wgfx(NULL, VGA_GFX_MODE, 0x40); 484 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
474 svga_wseq_mask(0x15, 0x20, 0xFE); 485 svga_wseq_mask(par->state.vgabase, 0x15, 0x20, 0xFE);
475 svga_wcrt_mask(0x11, 0x00, 0x70); 486 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);
476 break; 487 break;
477 case 2: 488 case 2:
478 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); 489 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
479 svga_wseq_mask(0x15, 0x00, 0xFE); 490 svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);
480 svga_wcrt_mask(0x11, 0x00, 0x70); 491 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);
481 break; 492 break;
482 case 3: 493 case 3:
483 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 494 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
484 svga_wseq_mask(0x15, 0x22, 0xFE); 495 svga_wseq_mask(par->state.vgabase, 0x15, 0x22, 0xFE);
485 break; 496 break;
486 case 4: 497 case 4:
487 pr_debug("fb%d: 5/6/5 truecolor\n", info->node); 498 pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
488 svga_wseq_mask(0x15, 0xB6, 0xFE); 499 svga_wseq_mask(par->state.vgabase, 0x15, 0xB6, 0xFE);
489 break; 500 break;
490 case 5: 501 case 5:
491 pr_debug("fb%d: 8/8/8 truecolor\n", info->node); 502 pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
492 svga_wseq_mask(0x15, 0xAE, 0xFE); 503 svga_wseq_mask(par->state.vgabase, 0x15, 0xAE, 0xFE);
493 break; 504 break;
494 default: 505 default:
495 printk(KERN_ERR "vt8623fb: unsupported mode - bug\n"); 506 printk(KERN_ERR "vt8623fb: unsupported mode - bug\n");
@@ -497,16 +508,16 @@ static int vt8623fb_set_par(struct fb_info *info)
497 } 508 }
498 509
499 vt8623_set_pixclock(info, info->var.pixclock); 510 vt8623_set_pixclock(info, info->var.pixclock);
500 svga_set_timings(&vt8623_timing_regs, &(info->var), 1, 1, 511 svga_set_timings(par->state.vgabase, &vt8623_timing_regs, &(info->var), 1, 1,
501 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 1, 512 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 1,
502 1, info->node); 513 1, info->node);
503 514
504 memset_io(info->screen_base, 0x00, screen_size); 515 memset_io(info->screen_base, 0x00, screen_size);
505 516
506 /* Device and screen back on */ 517 /* Device and screen back on */
507 svga_wcrt_mask(0x17, 0x80, 0x80); 518 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
508 svga_wcrt_mask(0x36, 0x00, 0x30); 519 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
509 svga_wseq_mask(0x01, 0x00, 0x20); 520 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
510 521
511 return 0; 522 return 0;
512} 523}
@@ -569,31 +580,33 @@ static int vt8623fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
569 580
570static int vt8623fb_blank(int blank_mode, struct fb_info *info) 581static int vt8623fb_blank(int blank_mode, struct fb_info *info)
571{ 582{
583 struct vt8623fb_info *par = info->par;
584
572 switch (blank_mode) { 585 switch (blank_mode) {
573 case FB_BLANK_UNBLANK: 586 case FB_BLANK_UNBLANK:
574 pr_debug("fb%d: unblank\n", info->node); 587 pr_debug("fb%d: unblank\n", info->node);
575 svga_wcrt_mask(0x36, 0x00, 0x30); 588 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
576 svga_wseq_mask(0x01, 0x00, 0x20); 589 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
577 break; 590 break;
578 case FB_BLANK_NORMAL: 591 case FB_BLANK_NORMAL:
579 pr_debug("fb%d: blank\n", info->node); 592 pr_debug("fb%d: blank\n", info->node);
580 svga_wcrt_mask(0x36, 0x00, 0x30); 593 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
581 svga_wseq_mask(0x01, 0x20, 0x20); 594 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
582 break; 595 break;
583 case FB_BLANK_HSYNC_SUSPEND: 596 case FB_BLANK_HSYNC_SUSPEND:
584 pr_debug("fb%d: DPMS standby (hsync off)\n", info->node); 597 pr_debug("fb%d: DPMS standby (hsync off)\n", info->node);
585 svga_wcrt_mask(0x36, 0x10, 0x30); 598 svga_wcrt_mask(par->state.vgabase, 0x36, 0x10, 0x30);
586 svga_wseq_mask(0x01, 0x20, 0x20); 599 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
587 break; 600 break;
588 case FB_BLANK_VSYNC_SUSPEND: 601 case FB_BLANK_VSYNC_SUSPEND:
589 pr_debug("fb%d: DPMS suspend (vsync off)\n", info->node); 602 pr_debug("fb%d: DPMS suspend (vsync off)\n", info->node);
590 svga_wcrt_mask(0x36, 0x20, 0x30); 603 svga_wcrt_mask(par->state.vgabase, 0x36, 0x20, 0x30);
591 svga_wseq_mask(0x01, 0x20, 0x20); 604 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
592 break; 605 break;
593 case FB_BLANK_POWERDOWN: 606 case FB_BLANK_POWERDOWN:
594 pr_debug("fb%d: DPMS off (no sync)\n", info->node); 607 pr_debug("fb%d: DPMS off (no sync)\n", info->node);
595 svga_wcrt_mask(0x36, 0x30, 0x30); 608 svga_wcrt_mask(par->state.vgabase, 0x36, 0x30, 0x30);
596 svga_wseq_mask(0x01, 0x20, 0x20); 609 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
597 break; 610 break;
598 } 611 }
599 612
@@ -603,6 +616,7 @@ static int vt8623fb_blank(int blank_mode, struct fb_info *info)
603 616
604static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 617static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
605{ 618{
619 struct vt8623fb_info *par = info->par;
606 unsigned int offset; 620 unsigned int offset;
607 621
608 /* Calculate the offset */ 622 /* Calculate the offset */
@@ -616,7 +630,7 @@ static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *i
616 } 630 }
617 631
618 /* Set the offset */ 632 /* Set the offset */
619 svga_wcrt_multi(vt8623_start_address_regs, offset); 633 svga_wcrt_multi(par->state.vgabase, vt8623_start_address_regs, offset);
620 634
621 return 0; 635 return 0;
622} 636}
@@ -647,6 +661,8 @@ static struct fb_ops vt8623fb_ops = {
647 661
648static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 662static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
649{ 663{
664 struct pci_bus_region bus_reg;
665 struct resource vga_res;
650 struct fb_info *info; 666 struct fb_info *info;
651 struct vt8623fb_info *par; 667 struct vt8623fb_info *par;
652 unsigned int memsize1, memsize2; 668 unsigned int memsize1, memsize2;
@@ -705,9 +721,18 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi
705 goto err_iomap_2; 721 goto err_iomap_2;
706 } 722 }
707 723
724 bus_reg.start = 0;
725 bus_reg.end = 64 * 1024;
726
727 vga_res.flags = IORESOURCE_IO;
728
729 pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
730
731 par->state.vgabase = (void __iomem *) vga_res.start;
732
708 /* Find how many physical memory there is on card */ 733 /* Find how many physical memory there is on card */
709 memsize1 = (vga_rseq(NULL, 0x34) + 1) >> 1; 734 memsize1 = (vga_rseq(par->state.vgabase, 0x34) + 1) >> 1;
710 memsize2 = vga_rseq(NULL, 0x39) << 2; 735 memsize2 = vga_rseq(par->state.vgabase, 0x39) << 2;
711 736
712 if ((16 <= memsize1) && (memsize1 <= 64) && (memsize1 == memsize2)) 737 if ((16 <= memsize1) && (memsize1 <= 64) && (memsize1 == memsize2))
713 info->screen_size = memsize1 << 20; 738 info->screen_size = memsize1 << 20;