diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-06 16:35:12 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-06 16:35:12 -0500 |
| commit | 84b7290cca16c61a167c7e1912cd84a479852165 (patch) | |
| tree | 8ecdd0ac8519cf5f38032db0f87ee1640b488efa | |
| parent | 9858a38ea3a940762ae3028cce88f686d0e0c28b (diff) | |
| parent | 1928e87bcf185f56008d0746f887b691c1cb8c4a (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: (55 commits)
video: udlfb: Kill off special printk wrappers, use pr_fmt().
video: udlfb: Kill off some magic constants for EDID sizing.
video: udlfb: deifdefify (yes, that's a word).
fbdev: modedb: Add a new mode for 864x480 TAAL panels.
drivers/video/i810/i810-i2c.c: fix i2c bus handling
video: Fix the HGA framebuffer driver
drivers/video/carminefb.c: improve error handling
video: imxfb: Fix the maximum value for yres
fbdev: sh_mobile_lcdcfb: Enable 32 bpp and 24 bpp support
fbdev: sh_mipi_dsi: use platform provided register layout and values
ARM: mach-shmobile: specify sh7372 MIPI DSI register layout
fbdev: sh_mipi_dsi: support different register layouts
ARM: mach-shmobile: improve MIPI DSI clock configuration
fbdev: sh-mobile: implement MIPI DSI runtime PM support
sisfb: eliminate compiler warnings
sisfb: delete unused register I/O macros
sisfb: replace setSISIDXREG with SiS_SetRegANDOR
sisfb: replace andSISIDXREG with SiS_SetRegAND
sisfb: replace orSISIDXREG with SiS_SetRegOR
sisfb: replace outSISIDXREG with SiS_SetReg
...
46 files changed, 4820 insertions, 1101 deletions
diff --git a/drivers/staging/udlfb/udlfb.txt b/Documentation/fb/udlfb.txt index 7fdde2a02a27..7fdde2a02a27 100644 --- a/drivers/staging/udlfb/udlfb.txt +++ b/Documentation/fb/udlfb.txt | |||
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index d440e5f456ad..b1222dc43380 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
| @@ -501,7 +501,12 @@ static struct platform_device keysc_device = { | |||
| 501 | static struct resource mipidsi0_resources[] = { | 501 | static struct resource mipidsi0_resources[] = { |
| 502 | [0] = { | 502 | [0] = { |
| 503 | .start = 0xffc60000, | 503 | .start = 0xffc60000, |
| 504 | .end = 0xffc68fff, | 504 | .end = 0xffc63073, |
| 505 | .flags = IORESOURCE_MEM, | ||
| 506 | }, | ||
| 507 | [1] = { | ||
| 508 | .start = 0xffc68000, | ||
| 509 | .end = 0xffc680ef, | ||
| 505 | .flags = IORESOURCE_MEM, | 510 | .flags = IORESOURCE_MEM, |
| 506 | }, | 511 | }, |
| 507 | }; | 512 | }; |
| @@ -509,6 +514,7 @@ static struct resource mipidsi0_resources[] = { | |||
| 509 | static struct sh_mipi_dsi_info mipidsi0_info = { | 514 | static struct sh_mipi_dsi_info mipidsi0_info = { |
| 510 | .data_format = MIPI_RGB888, | 515 | .data_format = MIPI_RGB888, |
| 511 | .lcd_chan = &lcdc_info.ch[0], | 516 | .lcd_chan = &lcdc_info.ch[0], |
| 517 | .vsynw_offset = 17, | ||
| 512 | }; | 518 | }; |
| 513 | 519 | ||
| 514 | static struct platform_device mipidsi0_device = { | 520 | static struct platform_device mipidsi0_device = { |
| @@ -521,44 +527,6 @@ static struct platform_device mipidsi0_device = { | |||
| 521 | }, | 527 | }, |
| 522 | }; | 528 | }; |
| 523 | 529 | ||
| 524 | /* This function will disappear when we switch to (runtime) PM */ | ||
| 525 | static int __init ap4evb_init_display_clk(void) | ||
| 526 | { | ||
| 527 | struct clk *lcdc_clk; | ||
| 528 | struct clk *dsitx_clk; | ||
| 529 | int ret; | ||
| 530 | |||
| 531 | lcdc_clk = clk_get(&lcdc_device.dev, "sh_mobile_lcdc_fb.0"); | ||
| 532 | if (IS_ERR(lcdc_clk)) | ||
| 533 | return PTR_ERR(lcdc_clk); | ||
| 534 | |||
| 535 | dsitx_clk = clk_get(&mipidsi0_device.dev, "sh-mipi-dsi.0"); | ||
| 536 | if (IS_ERR(dsitx_clk)) { | ||
| 537 | ret = PTR_ERR(dsitx_clk); | ||
| 538 | goto eclkdsitxget; | ||
| 539 | } | ||
| 540 | |||
| 541 | ret = clk_enable(lcdc_clk); | ||
| 542 | if (ret < 0) | ||
| 543 | goto eclklcdcon; | ||
| 544 | |||
| 545 | ret = clk_enable(dsitx_clk); | ||
| 546 | if (ret < 0) | ||
| 547 | goto eclkdsitxon; | ||
| 548 | |||
| 549 | return 0; | ||
| 550 | |||
| 551 | eclkdsitxon: | ||
| 552 | clk_disable(lcdc_clk); | ||
| 553 | eclklcdcon: | ||
| 554 | clk_put(dsitx_clk); | ||
| 555 | eclkdsitxget: | ||
| 556 | clk_put(lcdc_clk); | ||
| 557 | |||
| 558 | return ret; | ||
| 559 | } | ||
| 560 | device_initcall(ap4evb_init_display_clk); | ||
| 561 | |||
| 562 | static struct platform_device *qhd_devices[] __initdata = { | 530 | static struct platform_device *qhd_devices[] __initdata = { |
| 563 | &mipidsi0_device, | 531 | &mipidsi0_device, |
| 564 | &keysc_device, | 532 | &keysc_device, |
| @@ -764,10 +732,15 @@ static struct platform_device lcdc1_device = { | |||
| 764 | }, | 732 | }, |
| 765 | }; | 733 | }; |
| 766 | 734 | ||
| 735 | static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq, | ||
| 736 | unsigned long *parent_freq); | ||
| 737 | |||
| 738 | |||
| 767 | static struct sh_mobile_hdmi_info hdmi_info = { | 739 | static struct sh_mobile_hdmi_info hdmi_info = { |
| 768 | .lcd_chan = &sh_mobile_lcdc1_info.ch[0], | 740 | .lcd_chan = &sh_mobile_lcdc1_info.ch[0], |
| 769 | .lcd_dev = &lcdc1_device.dev, | 741 | .lcd_dev = &lcdc1_device.dev, |
| 770 | .flags = HDMI_SND_SRC_SPDIF, | 742 | .flags = HDMI_SND_SRC_SPDIF, |
| 743 | .clk_optimize_parent = ap4evb_clk_optimize, | ||
| 771 | }; | 744 | }; |
| 772 | 745 | ||
| 773 | static struct resource hdmi_resources[] = { | 746 | static struct resource hdmi_resources[] = { |
| @@ -794,6 +767,25 @@ static struct platform_device hdmi_device = { | |||
| 794 | }, | 767 | }, |
| 795 | }; | 768 | }; |
| 796 | 769 | ||
| 770 | static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq, | ||
| 771 | unsigned long *parent_freq) | ||
| 772 | { | ||
| 773 | struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick"); | ||
| 774 | long error; | ||
| 775 | |||
| 776 | if (IS_ERR(hdmi_ick)) { | ||
| 777 | int ret = PTR_ERR(hdmi_ick); | ||
| 778 | pr_err("Cannot get HDMI ICK: %d\n", ret); | ||
| 779 | return ret; | ||
| 780 | } | ||
| 781 | |||
| 782 | error = clk_round_parent(hdmi_ick, target, best_freq, parent_freq, 1, 64); | ||
| 783 | |||
| 784 | clk_put(hdmi_ick); | ||
| 785 | |||
| 786 | return error; | ||
| 787 | } | ||
| 788 | |||
| 797 | static struct gpio_led ap4evb_leds[] = { | 789 | static struct gpio_led ap4evb_leds[] = { |
| 798 | { | 790 | { |
| 799 | .name = "led4", | 791 | .name = "led4", |
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 3aa026069435..66663adb21f8 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
| @@ -507,7 +507,7 @@ enum { MSTP001, | |||
| 507 | MSTP223, | 507 | MSTP223, |
| 508 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, | 508 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, |
| 509 | MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, | 509 | MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, |
| 510 | MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403, | 510 | MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403, |
| 511 | MSTP_NR }; | 511 | MSTP_NR }; |
| 512 | 512 | ||
| 513 | #define MSTP(_parent, _reg, _bit, _flags) \ | 513 | #define MSTP(_parent, _reg, _bit, _flags) \ |
| @@ -543,6 +543,7 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
| 543 | [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ | 543 | [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ |
| 544 | [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */ | 544 | [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */ |
| 545 | [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */ | 545 | [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */ |
| 546 | [MSTP423] = MSTP(&div4_clks[DIV4_B], SMSTPCR4, 23, 0), /* DSITX1 */ | ||
| 546 | [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */ | 547 | [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */ |
| 547 | [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */ | 548 | [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */ |
| 548 | [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */ | 549 | [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */ |
| @@ -596,9 +597,10 @@ static struct clk_lookup lookups[] = { | |||
| 596 | CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), | 597 | CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), |
| 597 | CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), | 598 | CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), |
| 598 | CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]), | 599 | CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]), |
| 599 | CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]), | 600 | CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]), |
| 600 | CLKDEV_CON_ID("dsi0p_clk", &div6_clks[DIV6_DSI0P]), | 601 | CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]), |
| 601 | CLKDEV_CON_ID("dsi1p_clk", &div6_clks[DIV6_DSI1P]), | 602 | CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]), |
| 603 | CLKDEV_ICK_ID("dsi1p_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]), | ||
| 602 | 604 | ||
| 603 | /* MSTP32 clocks */ | 605 | /* MSTP32 clocks */ |
| 604 | CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ | 606 | CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ |
| @@ -610,7 +612,7 @@ static struct clk_lookup lookups[] = { | |||
| 610 | CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */ | 612 | CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */ |
| 611 | CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */ | 613 | CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */ |
| 612 | CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */ | 614 | CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */ |
| 613 | CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ | 615 | CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */ |
| 614 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ | 616 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ |
| 615 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ | 617 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ |
| 616 | CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */ | 618 | CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */ |
| @@ -633,6 +635,7 @@ static struct clk_lookup lookups[] = { | |||
| 633 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ | 635 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ |
| 634 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ | 636 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ |
| 635 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */ | 637 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */ |
| 638 | CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */ | ||
| 636 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */ | 639 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */ |
| 637 | CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */ | 640 | CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */ |
| 638 | CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */ | 641 | CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */ |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 5eafdf435550..df31a7228079 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
| @@ -111,8 +111,6 @@ source "drivers/staging/vt6655/Kconfig" | |||
| 111 | 111 | ||
| 112 | source "drivers/staging/vt6656/Kconfig" | 112 | source "drivers/staging/vt6656/Kconfig" |
| 113 | 113 | ||
| 114 | source "drivers/staging/udlfb/Kconfig" | ||
| 115 | |||
| 116 | source "drivers/staging/hv/Kconfig" | 114 | source "drivers/staging/hv/Kconfig" |
| 117 | 115 | ||
| 118 | source "drivers/staging/vme/Kconfig" | 116 | source "drivers/staging/vme/Kconfig" |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index a97a955c094b..7a15c0c82b69 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
| @@ -38,7 +38,6 @@ obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/ | |||
| 38 | obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ | 38 | obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ |
| 39 | obj-$(CONFIG_VT6655) += vt6655/ | 39 | obj-$(CONFIG_VT6655) += vt6655/ |
| 40 | obj-$(CONFIG_VT6656) += vt6656/ | 40 | obj-$(CONFIG_VT6656) += vt6656/ |
| 41 | obj-$(CONFIG_FB_UDL) += udlfb/ | ||
| 42 | obj-$(CONFIG_HYPERV) += hv/ | 41 | obj-$(CONFIG_HYPERV) += hv/ |
| 43 | obj-$(CONFIG_VME_BUS) += vme/ | 42 | obj-$(CONFIG_VME_BUS) += vme/ |
| 44 | obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ | 43 | obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ |
diff --git a/drivers/staging/udlfb/Kconfig b/drivers/staging/udlfb/Kconfig deleted file mode 100644 index 65bd5db4ca56..000000000000 --- a/drivers/staging/udlfb/Kconfig +++ /dev/null | |||
| @@ -1,14 +0,0 @@ | |||
| 1 | config FB_UDL | ||
| 2 | tristate "Displaylink USB Framebuffer support" | ||
| 3 | depends on FB && USB | ||
| 4 | select FB_MODE_HELPERS | ||
| 5 | select FB_SYS_FILLRECT | ||
| 6 | select FB_SYS_COPYAREA | ||
| 7 | select FB_SYS_IMAGEBLIT | ||
| 8 | select FB_SYS_FOPS | ||
| 9 | select FB_DEFERRED_IO | ||
| 10 | ---help--- | ||
| 11 | This is a kernel framebuffer driver for DisplayLink USB devices. | ||
| 12 | Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and | ||
| 13 | mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices. | ||
| 14 | To compile as a module, choose M here: the module name is udlfb. | ||
diff --git a/drivers/staging/udlfb/Makefile b/drivers/staging/udlfb/Makefile deleted file mode 100644 index 30d9e675b10f..000000000000 --- a/drivers/staging/udlfb/Makefile +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | obj-$(CONFIG_FB_UDL) += udlfb.o | ||
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 27c1fb4b1e0d..9f36a29b10b4 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
| @@ -186,6 +186,14 @@ config FB_SYS_FOPS | |||
| 186 | depends on FB | 186 | depends on FB |
| 187 | default n | 187 | default n |
| 188 | 188 | ||
| 189 | config FB_WMT_GE_ROPS | ||
| 190 | tristate | ||
| 191 | depends on FB | ||
| 192 | default n | ||
| 193 | ---help--- | ||
| 194 | Include functions for accelerated rectangle filling and area | ||
| 195 | copying using WonderMedia Graphics Engine operations. | ||
| 196 | |||
| 189 | config FB_DEFERRED_IO | 197 | config FB_DEFERRED_IO |
| 190 | bool | 198 | bool |
| 191 | depends on FB | 199 | depends on FB |
| @@ -635,6 +643,72 @@ config FB_BFIN_LQ035Q1 | |||
| 635 | To compile this driver as a module, choose M here: the | 643 | To compile this driver as a module, choose M here: the |
| 636 | module will be called bfin-lq035q1-fb. | 644 | module will be called bfin-lq035q1-fb. |
| 637 | 645 | ||
| 646 | config FB_BF537_LQ035 | ||
| 647 | tristate "SHARP LQ035 TFT LCD (BF537 STAMP)" | ||
| 648 | depends on FB && (BF534 || BF536 || BF537) && I2C_BLACKFIN_TWI | ||
| 649 | select FB_CFB_FILLRECT | ||
| 650 | select FB_CFB_COPYAREA | ||
| 651 | select FB_CFB_IMAGEBLIT | ||
| 652 | select BFIN_GPTIMERS | ||
| 653 | help | ||
| 654 | This is the framebuffer device for a SHARP LQ035Q7DB03 TFT LCD | ||
| 655 | attached to a BF537. | ||
| 656 | |||
| 657 | To compile this driver as a module, choose M here: the | ||
| 658 | module will be called bf537-lq035. | ||
| 659 | |||
| 660 | config FB_BFIN_7393 | ||
| 661 | tristate "Blackfin ADV7393 Video encoder" | ||
| 662 | depends on FB && BLACKFIN | ||
| 663 | select I2C | ||
| 664 | select FB_CFB_FILLRECT | ||
| 665 | select FB_CFB_COPYAREA | ||
| 666 | select FB_CFB_IMAGEBLIT | ||
| 667 | help | ||
| 668 | This is the framebuffer device for a ADV7393 video encoder | ||
| 669 | attached to a Blackfin on the PPI port. | ||
| 670 | If your Blackfin board has a ADV7393 select Y. | ||
| 671 | |||
| 672 | To compile this driver as a module, choose M here: the | ||
| 673 | module will be called bfin_adv7393fb. | ||
| 674 | |||
| 675 | choice | ||
| 676 | prompt "Video mode support" | ||
| 677 | depends on FB_BFIN_7393 | ||
| 678 | default NTSC | ||
| 679 | |||
| 680 | config NTSC | ||
| 681 | bool 'NTSC 720x480' | ||
| 682 | |||
| 683 | config PAL | ||
| 684 | bool 'PAL 720x576' | ||
| 685 | |||
| 686 | config NTSC_640x480 | ||
| 687 | bool 'NTSC 640x480 (Experimental)' | ||
| 688 | |||
| 689 | config PAL_640x480 | ||
| 690 | bool 'PAL 640x480 (Experimental)' | ||
| 691 | |||
| 692 | config NTSC_YCBCR | ||
| 693 | bool 'NTSC 720x480 YCbCR input' | ||
| 694 | |||
| 695 | config PAL_YCBCR | ||
| 696 | bool 'PAL 720x576 YCbCR input' | ||
| 697 | |||
| 698 | endchoice | ||
| 699 | |||
| 700 | choice | ||
| 701 | prompt "Size of ADV7393 frame buffer memory Single/Double Size" | ||
| 702 | depends on (FB_BFIN_7393) | ||
| 703 | default ADV7393_1XMEM | ||
| 704 | |||
| 705 | config ADV7393_1XMEM | ||
| 706 | bool 'Single' | ||
| 707 | |||
| 708 | config ADV7393_2XMEM | ||
| 709 | bool 'Double' | ||
| 710 | endchoice | ||
| 711 | |||
| 638 | config FB_STI | 712 | config FB_STI |
| 639 | tristate "HP STI frame buffer device support" | 713 | tristate "HP STI frame buffer device support" |
| 640 | depends on FB && PARISC | 714 | depends on FB && PARISC |
| @@ -750,24 +824,14 @@ config FB_N411 | |||
| 750 | config FB_HGA | 824 | config FB_HGA |
| 751 | tristate "Hercules mono graphics support" | 825 | tristate "Hercules mono graphics support" |
| 752 | depends on FB && X86 | 826 | depends on FB && X86 |
| 753 | select FB_CFB_FILLRECT | ||
| 754 | select FB_CFB_COPYAREA | ||
| 755 | select FB_CFB_IMAGEBLIT | ||
| 756 | help | 827 | help |
| 757 | Say Y here if you have a Hercules mono graphics card. | 828 | Say Y here if you have a Hercules mono graphics card. |
| 758 | 829 | ||
| 759 | To compile this driver as a module, choose M here: the | 830 | To compile this driver as a module, choose M here: the |
| 760 | module will be called hgafb. | 831 | module will be called hgafb. |
| 761 | 832 | ||
| 762 | As this card technology is 15 years old, most people will answer N | 833 | As this card technology is at least 25 years old, |
| 763 | here. | 834 | most people will answer N here. |
| 764 | |||
| 765 | config FB_HGA_ACCEL | ||
| 766 | bool "Hercules mono Acceleration functions (EXPERIMENTAL)" | ||
| 767 | depends on FB_HGA && EXPERIMENTAL | ||
| 768 | ---help--- | ||
| 769 | This will compile the Hercules mono graphics with | ||
| 770 | acceleration functions. | ||
| 771 | 835 | ||
| 772 | config FB_SGIVW | 836 | config FB_SGIVW |
| 773 | tristate "SGI Visual Workstation framebuffer support" | 837 | tristate "SGI Visual Workstation framebuffer support" |
| @@ -1722,6 +1786,24 @@ config FB_AU1200 | |||
| 1722 | various panels and CRTs by passing in kernel cmd line option | 1786 | various panels and CRTs by passing in kernel cmd line option |
| 1723 | au1200fb:panel=<name>. | 1787 | au1200fb:panel=<name>. |
| 1724 | 1788 | ||
| 1789 | config FB_VT8500 | ||
| 1790 | bool "VT8500 LCD Driver" | ||
| 1791 | depends on (FB = y) && ARM && ARCH_VT8500 && VTWM_VERSION_VT8500 | ||
| 1792 | select FB_WMT_GE_ROPS | ||
| 1793 | select FB_SYS_IMAGEBLIT | ||
| 1794 | help | ||
| 1795 | This is the framebuffer driver for VIA VT8500 integrated LCD | ||
| 1796 | controller. | ||
| 1797 | |||
| 1798 | config FB_WM8505 | ||
| 1799 | bool "WM8505 frame buffer support" | ||
| 1800 | depends on (FB = y) && ARM && ARCH_VT8500 && VTWM_VERSION_WM8505 | ||
| 1801 | select FB_WMT_GE_ROPS | ||
| 1802 | select FB_SYS_IMAGEBLIT | ||
| 1803 | help | ||
| 1804 | This is the framebuffer driver for WonderMedia WM8505 | ||
| 1805 | integrated LCD controller. | ||
| 1806 | |||
| 1725 | source "drivers/video/geode/Kconfig" | 1807 | source "drivers/video/geode/Kconfig" |
| 1726 | 1808 | ||
| 1727 | config FB_HIT | 1809 | config FB_HIT |
| @@ -2034,6 +2116,20 @@ config FB_SM501 | |||
| 2034 | 2116 | ||
| 2035 | If unsure, say N. | 2117 | If unsure, say N. |
| 2036 | 2118 | ||
| 2119 | config FB_UDL | ||
| 2120 | tristate "Displaylink USB Framebuffer support" | ||
| 2121 | depends on FB && USB | ||
| 2122 | select FB_MODE_HELPERS | ||
| 2123 | select FB_SYS_FILLRECT | ||
| 2124 | select FB_SYS_COPYAREA | ||
| 2125 | select FB_SYS_IMAGEBLIT | ||
| 2126 | select FB_SYS_FOPS | ||
| 2127 | select FB_DEFERRED_IO | ||
| 2128 | ---help--- | ||
| 2129 | This is a kernel framebuffer driver for DisplayLink USB devices. | ||
| 2130 | Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and | ||
| 2131 | mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices. | ||
| 2132 | To compile as a module, choose M here: the module name is udlfb. | ||
| 2037 | 2133 | ||
| 2038 | config FB_PNX4008_DUM | 2134 | config FB_PNX4008_DUM |
| 2039 | tristate "Display Update Module support on Philips PNX4008 board" | 2135 | tristate "Display Update Module support on Philips PNX4008 board" |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 485e8ed1318c..f9de51c39ad7 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
| @@ -26,6 +26,7 @@ obj-$(CONFIG_FB_SVGALIB) += svgalib.o | |||
| 26 | obj-$(CONFIG_FB_MACMODES) += macmodes.o | 26 | obj-$(CONFIG_FB_MACMODES) += macmodes.o |
| 27 | obj-$(CONFIG_FB_DDC) += fb_ddc.o | 27 | obj-$(CONFIG_FB_DDC) += fb_ddc.o |
| 28 | obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o | 28 | obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o |
| 29 | obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o | ||
| 29 | 30 | ||
| 30 | # Hardware specific drivers go first | 31 | # Hardware specific drivers go first |
| 31 | obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o | 32 | obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o |
| @@ -104,6 +105,8 @@ obj-$(CONFIG_FB_W100) += w100fb.o | |||
| 104 | obj-$(CONFIG_FB_TMIO) += tmiofb.o | 105 | obj-$(CONFIG_FB_TMIO) += tmiofb.o |
| 105 | obj-$(CONFIG_FB_AU1100) += au1100fb.o | 106 | obj-$(CONFIG_FB_AU1100) += au1100fb.o |
| 106 | obj-$(CONFIG_FB_AU1200) += au1200fb.o | 107 | obj-$(CONFIG_FB_AU1200) += au1200fb.o |
| 108 | obj-$(CONFIG_FB_VT8500) += vt8500lcdfb.o | ||
| 109 | obj-$(CONFIG_FB_WM8505) += wm8505fb.o | ||
| 107 | obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o | 110 | obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o |
| 108 | obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o | 111 | obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o |
| 109 | obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o | 112 | obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o |
| @@ -122,6 +125,7 @@ obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/ | |||
| 122 | obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o | 125 | obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o |
| 123 | obj-$(CONFIG_FB_PS3) += ps3fb.o | 126 | obj-$(CONFIG_FB_PS3) += ps3fb.o |
| 124 | obj-$(CONFIG_FB_SM501) += sm501fb.o | 127 | obj-$(CONFIG_FB_SM501) += sm501fb.o |
| 128 | obj-$(CONFIG_FB_UDL) += udlfb.o | ||
| 125 | obj-$(CONFIG_FB_XILINX) += xilinxfb.o | 129 | obj-$(CONFIG_FB_XILINX) += xilinxfb.o |
| 126 | obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o | 130 | obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o |
| 127 | obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o | 131 | obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o |
| @@ -141,9 +145,11 @@ obj-$(CONFIG_FB_VESA) += vesafb.o | |||
| 141 | obj-$(CONFIG_FB_EFI) += efifb.o | 145 | obj-$(CONFIG_FB_EFI) += efifb.o |
| 142 | obj-$(CONFIG_FB_VGA16) += vga16fb.o | 146 | obj-$(CONFIG_FB_VGA16) += vga16fb.o |
| 143 | obj-$(CONFIG_FB_OF) += offb.o | 147 | obj-$(CONFIG_FB_OF) += offb.o |
| 148 | obj-$(CONFIG_FB_BF537_LQ035) += bf537-lq035.o | ||
| 144 | obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o | 149 | obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o |
| 145 | obj-$(CONFIG_FB_BFIN_LQ035Q1) += bfin-lq035q1-fb.o | 150 | obj-$(CONFIG_FB_BFIN_LQ035Q1) += bfin-lq035q1-fb.o |
| 146 | obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o | 151 | obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o |
| 152 | obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o | ||
| 147 | obj-$(CONFIG_FB_MX3) += mx3fb.o | 153 | obj-$(CONFIG_FB_MX3) += mx3fb.o |
| 148 | obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o | 154 | obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o |
| 149 | 155 | ||
diff --git a/drivers/video/bf537-lq035.c b/drivers/video/bf537-lq035.c new file mode 100644 index 000000000000..18c507874ff1 --- /dev/null +++ b/drivers/video/bf537-lq035.c | |||
| @@ -0,0 +1,914 @@ | |||
| 1 | /* | ||
| 2 | * Analog Devices Blackfin(BF537 STAMP) + SHARP TFT LCD. | ||
| 3 | * http://docs.blackfin.uclinux.org/doku.php?id=hw:cards:tft-lcd | ||
| 4 | * | ||
| 5 | * Copyright 2006-2010 Analog Devices Inc. | ||
| 6 | * Licensed under the GPL-2. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 10 | |||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/errno.h> | ||
| 14 | #include <linux/string.h> | ||
| 15 | #include <linux/mm.h> | ||
| 16 | #include <linux/delay.h> | ||
| 17 | #include <linux/fb.h> | ||
| 18 | #include <linux/ioport.h> | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/types.h> | ||
| 21 | #include <linux/gpio.h> | ||
| 22 | #include <linux/interrupt.h> | ||
| 23 | #include <linux/sched.h> | ||
| 24 | #include <linux/timer.h> | ||
| 25 | #include <linux/device.h> | ||
| 26 | #include <linux/backlight.h> | ||
| 27 | #include <linux/lcd.h> | ||
| 28 | #include <linux/i2c.h> | ||
| 29 | #include <linux/spinlock.h> | ||
| 30 | #include <linux/dma-mapping.h> | ||
| 31 | #include <linux/slab.h> | ||
| 32 | #include <linux/platform_device.h> | ||
| 33 | |||
| 34 | #include <asm/blackfin.h> | ||
| 35 | #include <asm/irq.h> | ||
| 36 | #include <asm/dpmc.h> | ||
| 37 | #include <asm/dma.h> | ||
| 38 | #include <asm/portmux.h> | ||
| 39 | |||
| 40 | #define NO_BL 1 | ||
| 41 | |||
| 42 | #define MAX_BRIGHENESS 95 | ||
| 43 | #define MIN_BRIGHENESS 5 | ||
| 44 | #define NBR_PALETTE 256 | ||
| 45 | |||
| 46 | static const unsigned short ppi_pins[] = { | ||
| 47 | P_PPI0_CLK, P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, | ||
| 48 | P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, | ||
| 49 | P_PPI0_D8, P_PPI0_D9, P_PPI0_D10, P_PPI0_D11, | ||
| 50 | P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15, 0 | ||
| 51 | }; | ||
| 52 | |||
| 53 | static unsigned char *fb_buffer; /* RGB Buffer */ | ||
| 54 | static unsigned long *dma_desc_table; | ||
| 55 | static int t_conf_done, lq035_open_cnt; | ||
| 56 | static DEFINE_SPINLOCK(bfin_lq035_lock); | ||
| 57 | |||
| 58 | static int landscape; | ||
| 59 | module_param(landscape, int, 0); | ||
| 60 | MODULE_PARM_DESC(landscape, | ||
| 61 | "LANDSCAPE use 320x240 instead of Native 240x320 Resolution"); | ||
| 62 | |||
| 63 | static int bgr; | ||
| 64 | module_param(bgr, int, 0); | ||
| 65 | MODULE_PARM_DESC(bgr, | ||
| 66 | "BGR use 16-bit BGR-565 instead of RGB-565"); | ||
| 67 | |||
| 68 | static int nocursor = 1; | ||
| 69 | module_param(nocursor, int, 0644); | ||
| 70 | MODULE_PARM_DESC(nocursor, "cursor enable/disable"); | ||
| 71 | |||
| 72 | static unsigned long current_brightness; /* backlight */ | ||
| 73 | |||
| 74 | /* AD5280 vcomm */ | ||
| 75 | static unsigned char vcomm_value = 150; | ||
| 76 | static struct i2c_client *ad5280_client; | ||
| 77 | |||
| 78 | static void set_vcomm(void) | ||
| 79 | { | ||
| 80 | int nr; | ||
| 81 | |||
| 82 | if (!ad5280_client) | ||
| 83 | return; | ||
| 84 | |||
| 85 | nr = i2c_smbus_write_byte_data(ad5280_client, 0x00, vcomm_value); | ||
| 86 | if (nr) | ||
| 87 | pr_err("i2c_smbus_write_byte_data fail: %d\n", nr); | ||
| 88 | } | ||
| 89 | |||
| 90 | static int __devinit ad5280_probe(struct i2c_client *client, | ||
| 91 | const struct i2c_device_id *id) | ||
| 92 | { | ||
| 93 | int ret; | ||
| 94 | if (!i2c_check_functionality(client->adapter, | ||
| 95 | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
| 96 | dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); | ||
| 97 | return -EIO; | ||
| 98 | } | ||
| 99 | |||
| 100 | ret = i2c_smbus_write_byte_data(client, 0x00, vcomm_value); | ||
| 101 | if (ret) { | ||
| 102 | dev_err(&client->dev, "write fail: %d\n", ret); | ||
| 103 | return ret; | ||
| 104 | } | ||
| 105 | |||
| 106 | ad5280_client = client; | ||
| 107 | |||
| 108 | return 0; | ||
| 109 | } | ||
| 110 | |||
| 111 | static int __devexit ad5280_remove(struct i2c_client *client) | ||
| 112 | { | ||
| 113 | ad5280_client = NULL; | ||
| 114 | return 0; | ||
| 115 | } | ||
| 116 | |||
| 117 | static const struct i2c_device_id ad5280_id[] = { | ||
| 118 | {"bf537-lq035-ad5280", 0}, | ||
| 119 | {} | ||
| 120 | }; | ||
| 121 | |||
| 122 | MODULE_DEVICE_TABLE(i2c, ad5280_id); | ||
| 123 | |||
| 124 | static struct i2c_driver ad5280_driver = { | ||
| 125 | .driver = { | ||
| 126 | .name = "bf537-lq035-ad5280", | ||
| 127 | }, | ||
| 128 | .probe = ad5280_probe, | ||
| 129 | .remove = __devexit_p(ad5280_remove), | ||
| 130 | .id_table = ad5280_id, | ||
| 131 | }; | ||
| 132 | |||
| 133 | #ifdef CONFIG_PNAV10 | ||
| 134 | #define MOD GPIO_PH13 | ||
| 135 | |||
| 136 | #define bfin_write_TIMER_LP_CONFIG bfin_write_TIMER0_CONFIG | ||
| 137 | #define bfin_write_TIMER_LP_WIDTH bfin_write_TIMER0_WIDTH | ||
| 138 | #define bfin_write_TIMER_LP_PERIOD bfin_write_TIMER0_PERIOD | ||
| 139 | #define bfin_read_TIMER_LP_COUNTER bfin_read_TIMER0_COUNTER | ||
| 140 | #define TIMDIS_LP TIMDIS0 | ||
| 141 | #define TIMEN_LP TIMEN0 | ||
| 142 | |||
| 143 | #define bfin_write_TIMER_SPS_CONFIG bfin_write_TIMER1_CONFIG | ||
| 144 | #define bfin_write_TIMER_SPS_WIDTH bfin_write_TIMER1_WIDTH | ||
| 145 | #define bfin_write_TIMER_SPS_PERIOD bfin_write_TIMER1_PERIOD | ||
| 146 | #define TIMDIS_SPS TIMDIS1 | ||
| 147 | #define TIMEN_SPS TIMEN1 | ||
| 148 | |||
| 149 | #define bfin_write_TIMER_SP_CONFIG bfin_write_TIMER5_CONFIG | ||
| 150 | #define bfin_write_TIMER_SP_WIDTH bfin_write_TIMER5_WIDTH | ||
| 151 | #define bfin_write_TIMER_SP_PERIOD bfin_write_TIMER5_PERIOD | ||
| 152 | #define TIMDIS_SP TIMDIS5 | ||
| 153 | #define TIMEN_SP TIMEN5 | ||
| 154 | |||
| 155 | #define bfin_write_TIMER_PS_CLS_CONFIG bfin_write_TIMER2_CONFIG | ||
| 156 | #define bfin_write_TIMER_PS_CLS_WIDTH bfin_write_TIMER2_WIDTH | ||
| 157 | #define bfin_write_TIMER_PS_CLS_PERIOD bfin_write_TIMER2_PERIOD | ||
| 158 | #define TIMDIS_PS_CLS TIMDIS2 | ||
| 159 | #define TIMEN_PS_CLS TIMEN2 | ||
| 160 | |||
| 161 | #define bfin_write_TIMER_REV_CONFIG bfin_write_TIMER3_CONFIG | ||
| 162 | #define bfin_write_TIMER_REV_WIDTH bfin_write_TIMER3_WIDTH | ||
| 163 | #define bfin_write_TIMER_REV_PERIOD bfin_write_TIMER3_PERIOD | ||
| 164 | #define TIMDIS_REV TIMDIS3 | ||
| 165 | #define TIMEN_REV TIMEN3 | ||
| 166 | #define bfin_read_TIMER_REV_COUNTER bfin_read_TIMER3_COUNTER | ||
| 167 | |||
| 168 | #define FREQ_PPI_CLK (5*1024*1024) /* PPI_CLK 5MHz */ | ||
| 169 | |||
| 170 | #define TIMERS {P_TMR0, P_TMR1, P_TMR2, P_TMR3, P_TMR5, 0} | ||
| 171 | |||
| 172 | #else | ||
| 173 | |||
| 174 | #define UD GPIO_PF13 /* Up / Down */ | ||
| 175 | #define MOD GPIO_PF10 | ||
| 176 | #define LBR GPIO_PF14 /* Left Right */ | ||
| 177 | |||
| 178 | #define bfin_write_TIMER_LP_CONFIG bfin_write_TIMER6_CONFIG | ||
| 179 | #define bfin_write_TIMER_LP_WIDTH bfin_write_TIMER6_WIDTH | ||
| 180 | #define bfin_write_TIMER_LP_PERIOD bfin_write_TIMER6_PERIOD | ||
| 181 | #define bfin_read_TIMER_LP_COUNTER bfin_read_TIMER6_COUNTER | ||
| 182 | #define TIMDIS_LP TIMDIS6 | ||
| 183 | #define TIMEN_LP TIMEN6 | ||
| 184 | |||
| 185 | #define bfin_write_TIMER_SPS_CONFIG bfin_write_TIMER1_CONFIG | ||
| 186 | #define bfin_write_TIMER_SPS_WIDTH bfin_write_TIMER1_WIDTH | ||
| 187 | #define bfin_write_TIMER_SPS_PERIOD bfin_write_TIMER1_PERIOD | ||
| 188 | #define TIMDIS_SPS TIMDIS1 | ||
| 189 | #define TIMEN_SPS TIMEN1 | ||
| 190 | |||
| 191 | #define bfin_write_TIMER_SP_CONFIG bfin_write_TIMER0_CONFIG | ||
| 192 | #define bfin_write_TIMER_SP_WIDTH bfin_write_TIMER0_WIDTH | ||
| 193 | #define bfin_write_TIMER_SP_PERIOD bfin_write_TIMER0_PERIOD | ||
| 194 | #define TIMDIS_SP TIMDIS0 | ||
| 195 | #define TIMEN_SP TIMEN0 | ||
| 196 | |||
| 197 | #define bfin_write_TIMER_PS_CLS_CONFIG bfin_write_TIMER7_CONFIG | ||
| 198 | #define bfin_write_TIMER_PS_CLS_WIDTH bfin_write_TIMER7_WIDTH | ||
| 199 | #define bfin_write_TIMER_PS_CLS_PERIOD bfin_write_TIMER7_PERIOD | ||
| 200 | #define TIMDIS_PS_CLS TIMDIS7 | ||
| 201 | #define TIMEN_PS_CLS TIMEN7 | ||
| 202 | |||
| 203 | #define bfin_write_TIMER_REV_CONFIG bfin_write_TIMER5_CONFIG | ||
| 204 | #define bfin_write_TIMER_REV_WIDTH bfin_write_TIMER5_WIDTH | ||
| 205 | #define bfin_write_TIMER_REV_PERIOD bfin_write_TIMER5_PERIOD | ||
| 206 | #define TIMDIS_REV TIMDIS5 | ||
| 207 | #define TIMEN_REV TIMEN5 | ||
| 208 | #define bfin_read_TIMER_REV_COUNTER bfin_read_TIMER5_COUNTER | ||
| 209 | |||
| 210 | #define FREQ_PPI_CLK (6*1000*1000) /* PPI_CLK 6MHz */ | ||
| 211 | #define TIMERS {P_TMR0, P_TMR1, P_TMR5, P_TMR6, P_TMR7, 0} | ||
| 212 | |||
| 213 | #endif | ||
| 214 | |||
| 215 | #define LCD_X_RES 240 /* Horizontal Resolution */ | ||
| 216 | #define LCD_Y_RES 320 /* Vertical Resolution */ | ||
| 217 | |||
| 218 | #define LCD_BBP 16 /* Bit Per Pixel */ | ||
| 219 | |||
| 220 | /* the LCD and the DMA start counting differently; | ||
| 221 | * since one starts at 0 and the other starts at 1, | ||
| 222 | * we have a difference of 1 between START_LINES | ||
| 223 | * and U_LINES. | ||
| 224 | */ | ||
| 225 | #define START_LINES 8 /* lines for field flyback or field blanking signal */ | ||
| 226 | #define U_LINES 9 /* number of undisplayed blanking lines */ | ||
| 227 | |||
| 228 | #define FRAMES_PER_SEC (60) | ||
| 229 | |||
| 230 | #define DCLKS_PER_FRAME (FREQ_PPI_CLK/FRAMES_PER_SEC) | ||
| 231 | #define DCLKS_PER_LINE (DCLKS_PER_FRAME/(LCD_Y_RES+U_LINES)) | ||
| 232 | |||
| 233 | #define PPI_CONFIG_VALUE (PORT_DIR|XFR_TYPE|DLEN_16|POLS) | ||
| 234 | #define PPI_DELAY_VALUE (0) | ||
| 235 | #define TIMER_CONFIG (PWM_OUT|PERIOD_CNT|TIN_SEL|CLK_SEL) | ||
| 236 | |||
| 237 | #define ACTIVE_VIDEO_MEM_OFFSET (LCD_X_RES*START_LINES*(LCD_BBP/8)) | ||
| 238 | #define ACTIVE_VIDEO_MEM_SIZE (LCD_Y_RES*LCD_X_RES*(LCD_BBP/8)) | ||
| 239 | #define TOTAL_VIDEO_MEM_SIZE ((LCD_Y_RES+U_LINES)*LCD_X_RES*(LCD_BBP/8)) | ||
| 240 | #define TOTAL_DMA_DESC_SIZE (2 * sizeof(u32) * (LCD_Y_RES + U_LINES)) | ||
| 241 | |||
| 242 | static void start_timers(void) /* CHECK with HW */ | ||
| 243 | { | ||
| 244 | unsigned long flags; | ||
| 245 | |||
| 246 | local_irq_save(flags); | ||
| 247 | |||
| 248 | bfin_write_TIMER_ENABLE(TIMEN_REV); | ||
| 249 | SSYNC(); | ||
| 250 | |||
| 251 | while (bfin_read_TIMER_REV_COUNTER() <= 11) | ||
| 252 | continue; | ||
| 253 | bfin_write_TIMER_ENABLE(TIMEN_LP); | ||
| 254 | SSYNC(); | ||
| 255 | |||
| 256 | while (bfin_read_TIMER_LP_COUNTER() < 3) | ||
| 257 | continue; | ||
| 258 | bfin_write_TIMER_ENABLE(TIMEN_SP|TIMEN_SPS|TIMEN_PS_CLS); | ||
| 259 | SSYNC(); | ||
| 260 | t_conf_done = 1; | ||
| 261 | local_irq_restore(flags); | ||
| 262 | } | ||
| 263 | |||
| 264 | static void config_timers(void) | ||
| 265 | { | ||
| 266 | /* Stop timers */ | ||
| 267 | bfin_write_TIMER_DISABLE(TIMDIS_SP|TIMDIS_SPS|TIMDIS_REV| | ||
| 268 | TIMDIS_LP|TIMDIS_PS_CLS); | ||
| 269 | SSYNC(); | ||
| 270 | |||
| 271 | /* LP, timer 6 */ | ||
| 272 | bfin_write_TIMER_LP_CONFIG(TIMER_CONFIG|PULSE_HI); | ||
| 273 | bfin_write_TIMER_LP_WIDTH(1); | ||
| 274 | |||
| 275 | bfin_write_TIMER_LP_PERIOD(DCLKS_PER_LINE); | ||
| 276 | SSYNC(); | ||
| 277 | |||
| 278 | /* SPS, timer 1 */ | ||
| 279 | bfin_write_TIMER_SPS_CONFIG(TIMER_CONFIG|PULSE_HI); | ||
| 280 | bfin_write_TIMER_SPS_WIDTH(DCLKS_PER_LINE*2); | ||
| 281 | bfin_write_TIMER_SPS_PERIOD((DCLKS_PER_LINE * (LCD_Y_RES+U_LINES))); | ||
| 282 | SSYNC(); | ||
| 283 | |||
| 284 | /* SP, timer 0 */ | ||
| 285 | bfin_write_TIMER_SP_CONFIG(TIMER_CONFIG|PULSE_HI); | ||
| 286 | bfin_write_TIMER_SP_WIDTH(1); | ||
| 287 | bfin_write_TIMER_SP_PERIOD(DCLKS_PER_LINE); | ||
| 288 | SSYNC(); | ||
| 289 | |||
| 290 | /* PS & CLS, timer 7 */ | ||
| 291 | bfin_write_TIMER_PS_CLS_CONFIG(TIMER_CONFIG); | ||
| 292 | bfin_write_TIMER_PS_CLS_WIDTH(LCD_X_RES + START_LINES); | ||
| 293 | bfin_write_TIMER_PS_CLS_PERIOD(DCLKS_PER_LINE); | ||
| 294 | |||
| 295 | SSYNC(); | ||
| 296 | |||
| 297 | #ifdef NO_BL | ||
| 298 | /* REV, timer 5 */ | ||
| 299 | bfin_write_TIMER_REV_CONFIG(TIMER_CONFIG|PULSE_HI); | ||
| 300 | |||
| 301 | bfin_write_TIMER_REV_WIDTH(DCLKS_PER_LINE); | ||
| 302 | bfin_write_TIMER_REV_PERIOD(DCLKS_PER_LINE*2); | ||
| 303 | |||
| 304 | SSYNC(); | ||
| 305 | #endif | ||
| 306 | } | ||
| 307 | |||
| 308 | static void config_ppi(void) | ||
| 309 | { | ||
| 310 | bfin_write_PPI_DELAY(PPI_DELAY_VALUE); | ||
| 311 | bfin_write_PPI_COUNT(LCD_X_RES-1); | ||
| 312 | /* 0x10 -> PORT_CFG -> 2 or 3 frame syncs */ | ||
| 313 | bfin_write_PPI_CONTROL((PPI_CONFIG_VALUE|0x10) & (~POLS)); | ||
| 314 | } | ||
| 315 | |||
| 316 | static int config_dma(void) | ||
| 317 | { | ||
| 318 | u32 i; | ||
| 319 | |||
| 320 | if (landscape) { | ||
| 321 | |||
| 322 | for (i = 0; i < U_LINES; ++i) { | ||
| 323 | /* blanking lines point to first line of fb_buffer */ | ||
| 324 | dma_desc_table[2*i] = (unsigned long)&dma_desc_table[2*i+2]; | ||
| 325 | dma_desc_table[2*i+1] = (unsigned long)fb_buffer; | ||
| 326 | } | ||
| 327 | |||
| 328 | for (i = U_LINES; i < U_LINES + LCD_Y_RES; ++i) { | ||
| 329 | /* visible lines */ | ||
| 330 | dma_desc_table[2*i] = (unsigned long)&dma_desc_table[2*i+2]; | ||
| 331 | dma_desc_table[2*i+1] = (unsigned long)fb_buffer + | ||
| 332 | (LCD_Y_RES+U_LINES-1-i)*2; | ||
| 333 | } | ||
| 334 | |||
| 335 | /* last descriptor points to first */ | ||
| 336 | dma_desc_table[2*(LCD_Y_RES+U_LINES-1)] = (unsigned long)&dma_desc_table[0]; | ||
| 337 | |||
| 338 | set_dma_x_count(CH_PPI, LCD_X_RES); | ||
| 339 | set_dma_x_modify(CH_PPI, LCD_Y_RES * (LCD_BBP / 8)); | ||
| 340 | set_dma_y_count(CH_PPI, 0); | ||
| 341 | set_dma_y_modify(CH_PPI, 0); | ||
| 342 | set_dma_next_desc_addr(CH_PPI, (void *)dma_desc_table[0]); | ||
| 343 | set_dma_config(CH_PPI, DMAFLOW_LARGE | NDSIZE_4 | WDSIZE_16); | ||
| 344 | |||
| 345 | } else { | ||
| 346 | |||
| 347 | set_dma_config(CH_PPI, set_bfin_dma_config(DIR_READ, | ||
| 348 | DMA_FLOW_AUTO, | ||
| 349 | INTR_DISABLE, | ||
| 350 | DIMENSION_2D, | ||
| 351 | DATA_SIZE_16, | ||
| 352 | DMA_NOSYNC_KEEP_DMA_BUF)); | ||
| 353 | set_dma_x_count(CH_PPI, LCD_X_RES); | ||
| 354 | set_dma_x_modify(CH_PPI, LCD_BBP / 8); | ||
| 355 | set_dma_y_count(CH_PPI, LCD_Y_RES+U_LINES); | ||
| 356 | set_dma_y_modify(CH_PPI, LCD_BBP / 8); | ||
| 357 | set_dma_start_addr(CH_PPI, (unsigned long) fb_buffer); | ||
| 358 | } | ||
| 359 | |||
| 360 | return 0; | ||
| 361 | } | ||
| 362 | |||
| 363 | static int __devinit request_ports(void) | ||
| 364 | { | ||
| 365 | u16 tmr_req[] = TIMERS; | ||
| 366 | |||
| 367 | /* | ||
| 368 | UD: PF13 | ||
| 369 | MOD: PF10 | ||
| 370 | LBR: PF14 | ||
| 371 | PPI_CLK: PF15 | ||
| 372 | */ | ||
| 373 | |||
| 374 | if (peripheral_request_list(ppi_pins, KBUILD_MODNAME)) { | ||
| 375 | pr_err("requesting PPI peripheral failed\n"); | ||
| 376 | return -EBUSY; | ||
| 377 | } | ||
| 378 | |||
| 379 | if (peripheral_request_list(tmr_req, KBUILD_MODNAME)) { | ||
| 380 | peripheral_free_list(ppi_pins); | ||
| 381 | pr_err("requesting timer peripheral failed\n"); | ||
| 382 | return -EBUSY; | ||
| 383 | } | ||
| 384 | |||
| 385 | #if (defined(UD) && defined(LBR)) | ||
| 386 | if (gpio_request(UD, KBUILD_MODNAME)) { | ||
| 387 | pr_err("requesting GPIO %d failed\n", UD); | ||
| 388 | return -EBUSY; | ||
| 389 | } | ||
| 390 | |||
| 391 | if (gpio_request(LBR, KBUILD_MODNAME)) { | ||
| 392 | pr_err("requesting GPIO %d failed\n", LBR); | ||
| 393 | gpio_free(UD); | ||
| 394 | return -EBUSY; | ||
| 395 | } | ||
| 396 | |||
| 397 | gpio_direction_output(UD, 0); | ||
| 398 | gpio_direction_output(LBR, 1); | ||
| 399 | |||
| 400 | #endif | ||
| 401 | |||
| 402 | if (gpio_request(MOD, KBUILD_MODNAME)) { | ||
| 403 | pr_err("requesting GPIO %d failed\n", MOD); | ||
| 404 | #if (defined(UD) && defined(LBR)) | ||
| 405 | gpio_free(LBR); | ||
| 406 | gpio_free(UD); | ||
| 407 | #endif | ||
| 408 | return -EBUSY; | ||
| 409 | } | ||
| 410 | |||
| 411 | gpio_direction_output(MOD, 1); | ||
| 412 | |||
| 413 | SSYNC(); | ||
| 414 | return 0; | ||
| 415 | } | ||
| 416 | |||
| 417 | static void free_ports(void) | ||
| 418 | { | ||
| 419 | u16 tmr_req[] = TIMERS; | ||
| 420 | |||
| 421 | peripheral_free_list(ppi_pins); | ||
| 422 | peripheral_free_list(tmr_req); | ||
| 423 | |||
| 424 | #if defined(UD) && defined(LBR) | ||
| 425 | gpio_free(LBR); | ||
| 426 | gpio_free(UD); | ||
| 427 | #endif | ||
| 428 | gpio_free(MOD); | ||
| 429 | } | ||
| 430 | |||
| 431 | static struct fb_info bfin_lq035_fb; | ||
| 432 | |||
| 433 | static struct fb_var_screeninfo bfin_lq035_fb_defined = { | ||
| 434 | .bits_per_pixel = LCD_BBP, | ||
| 435 | .activate = FB_ACTIVATE_TEST, | ||
| 436 | .xres = LCD_X_RES, /*default portrait mode RGB*/ | ||
| 437 | .yres = LCD_Y_RES, | ||
| 438 | .xres_virtual = LCD_X_RES, | ||
| 439 | .yres_virtual = LCD_Y_RES, | ||
| 440 | .height = -1, | ||
| 441 | .width = -1, | ||
| 442 | .left_margin = 0, | ||
| 443 | .right_margin = 0, | ||
| 444 | .upper_margin = 0, | ||
| 445 | .lower_margin = 0, | ||
| 446 | .red = {11, 5, 0}, | ||
| 447 | .green = {5, 6, 0}, | ||
| 448 | .blue = {0, 5, 0}, | ||
| 449 | .transp = {0, 0, 0}, | ||
| 450 | }; | ||
| 451 | |||
| 452 | static struct fb_fix_screeninfo bfin_lq035_fb_fix __devinitdata = { | ||
| 453 | .id = KBUILD_MODNAME, | ||
| 454 | .smem_len = ACTIVE_VIDEO_MEM_SIZE, | ||
| 455 | .type = FB_TYPE_PACKED_PIXELS, | ||
| 456 | .visual = FB_VISUAL_TRUECOLOR, | ||
| 457 | .xpanstep = 0, | ||
| 458 | .ypanstep = 0, | ||
| 459 | .line_length = LCD_X_RES*(LCD_BBP/8), | ||
| 460 | .accel = FB_ACCEL_NONE, | ||
| 461 | }; | ||
| 462 | |||
| 463 | |||
| 464 | static int bfin_lq035_fb_open(struct fb_info *info, int user) | ||
| 465 | { | ||
| 466 | unsigned long flags; | ||
| 467 | |||
| 468 | spin_lock_irqsave(&bfin_lq035_lock, flags); | ||
| 469 | lq035_open_cnt++; | ||
| 470 | spin_unlock_irqrestore(&bfin_lq035_lock, flags); | ||
| 471 | |||
| 472 | if (lq035_open_cnt <= 1) { | ||
| 473 | bfin_write_PPI_CONTROL(0); | ||
| 474 | SSYNC(); | ||
| 475 | |||
| 476 | set_vcomm(); | ||
| 477 | config_dma(); | ||
| 478 | config_ppi(); | ||
| 479 | |||
| 480 | /* start dma */ | ||
| 481 | enable_dma(CH_PPI); | ||
| 482 | SSYNC(); | ||
| 483 | bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() | PORT_EN); | ||
| 484 | SSYNC(); | ||
| 485 | |||
| 486 | if (!t_conf_done) { | ||
| 487 | config_timers(); | ||
| 488 | start_timers(); | ||
| 489 | } | ||
| 490 | /* gpio_set_value(MOD,1); */ | ||
| 491 | } | ||
| 492 | |||
| 493 | return 0; | ||
| 494 | } | ||
| 495 | |||
| 496 | static int bfin_lq035_fb_release(struct fb_info *info, int user) | ||
| 497 | { | ||
| 498 | unsigned long flags; | ||
| 499 | |||
| 500 | spin_lock_irqsave(&bfin_lq035_lock, flags); | ||
| 501 | lq035_open_cnt--; | ||
| 502 | spin_unlock_irqrestore(&bfin_lq035_lock, flags); | ||
| 503 | |||
| 504 | |||
| 505 | if (lq035_open_cnt <= 0) { | ||
| 506 | |||
| 507 | bfin_write_PPI_CONTROL(0); | ||
| 508 | SSYNC(); | ||
| 509 | |||
| 510 | disable_dma(CH_PPI); | ||
| 511 | } | ||
| 512 | |||
| 513 | return 0; | ||
| 514 | } | ||
| 515 | |||
| 516 | |||
| 517 | static int bfin_lq035_fb_check_var(struct fb_var_screeninfo *var, | ||
| 518 | struct fb_info *info) | ||
| 519 | { | ||
| 520 | switch (var->bits_per_pixel) { | ||
| 521 | case 16:/* DIRECTCOLOUR, 64k */ | ||
| 522 | var->red.offset = info->var.red.offset; | ||
| 523 | var->green.offset = info->var.green.offset; | ||
| 524 | var->blue.offset = info->var.blue.offset; | ||
| 525 | var->red.length = info->var.red.length; | ||
| 526 | var->green.length = info->var.green.length; | ||
| 527 | var->blue.length = info->var.blue.length; | ||
| 528 | var->transp.offset = 0; | ||
| 529 | var->transp.length = 0; | ||
| 530 | var->transp.msb_right = 0; | ||
| 531 | var->red.msb_right = 0; | ||
| 532 | var->green.msb_right = 0; | ||
| 533 | var->blue.msb_right = 0; | ||
| 534 | break; | ||
| 535 | default: | ||
| 536 | pr_debug("%s: depth not supported: %u BPP\n", __func__, | ||
| 537 | var->bits_per_pixel); | ||
| 538 | return -EINVAL; | ||
| 539 | } | ||
| 540 | |||
| 541 | if (info->var.xres != var->xres || | ||
| 542 | info->var.yres != var->yres || | ||
| 543 | info->var.xres_virtual != var->xres_virtual || | ||
| 544 | info->var.yres_virtual != var->yres_virtual) { | ||
| 545 | pr_debug("%s: Resolution not supported: X%u x Y%u\n", | ||
| 546 | __func__, var->xres, var->yres); | ||
| 547 | return -EINVAL; | ||
| 548 | } | ||
| 549 | |||
| 550 | /* | ||
| 551 | * Memory limit | ||
| 552 | */ | ||
| 553 | |||
| 554 | if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) { | ||
| 555 | pr_debug("%s: Memory Limit requested yres_virtual = %u\n", | ||
| 556 | __func__, var->yres_virtual); | ||
| 557 | return -ENOMEM; | ||
| 558 | } | ||
| 559 | |||
| 560 | return 0; | ||
| 561 | } | ||
| 562 | |||
| 563 | /* fb_rotate | ||
| 564 | * Rotate the display of this angle. This doesn't seems to be used by the core, | ||
| 565 | * but as our hardware supports it, so why not implementing it... | ||
| 566 | */ | ||
| 567 | static void bfin_lq035_fb_rotate(struct fb_info *fbi, int angle) | ||
| 568 | { | ||
| 569 | pr_debug("%s: %p %d", __func__, fbi, angle); | ||
| 570 | #if (defined(UD) && defined(LBR)) | ||
| 571 | switch (angle) { | ||
| 572 | |||
| 573 | case 180: | ||
| 574 | gpio_set_value(LBR, 0); | ||
| 575 | gpio_set_value(UD, 1); | ||
| 576 | break; | ||
| 577 | default: | ||
| 578 | gpio_set_value(LBR, 1); | ||
| 579 | gpio_set_value(UD, 0); | ||
| 580 | break; | ||
| 581 | } | ||
| 582 | #endif | ||
| 583 | } | ||
| 584 | |||
| 585 | static int bfin_lq035_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) | ||
| 586 | { | ||
| 587 | if (nocursor) | ||
| 588 | return 0; | ||
| 589 | else | ||
| 590 | return -EINVAL; /* just to force soft_cursor() call */ | ||
| 591 | } | ||
| 592 | |||
| 593 | static int bfin_lq035_fb_setcolreg(u_int regno, u_int red, u_int green, | ||
| 594 | u_int blue, u_int transp, | ||
| 595 | struct fb_info *info) | ||
| 596 | { | ||
| 597 | if (regno >= NBR_PALETTE) | ||
| 598 | return -EINVAL; | ||
| 599 | |||
| 600 | if (info->var.grayscale) | ||
| 601 | /* grayscale = 0.30*R + 0.59*G + 0.11*B */ | ||
| 602 | red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; | ||
| 603 | |||
| 604 | if (info->fix.visual == FB_VISUAL_TRUECOLOR) { | ||
| 605 | |||
| 606 | u32 value; | ||
| 607 | /* Place color in the pseudopalette */ | ||
| 608 | if (regno > 16) | ||
| 609 | return -EINVAL; | ||
| 610 | |||
| 611 | red >>= (16 - info->var.red.length); | ||
| 612 | green >>= (16 - info->var.green.length); | ||
| 613 | blue >>= (16 - info->var.blue.length); | ||
| 614 | |||
| 615 | value = (red << info->var.red.offset) | | ||
| 616 | (green << info->var.green.offset)| | ||
| 617 | (blue << info->var.blue.offset); | ||
| 618 | value &= 0xFFFF; | ||
| 619 | |||
| 620 | ((u32 *) (info->pseudo_palette))[regno] = value; | ||
| 621 | |||
| 622 | } | ||
| 623 | |||
| 624 | return 0; | ||
| 625 | } | ||
| 626 | |||
| 627 | static struct fb_ops bfin_lq035_fb_ops = { | ||
| 628 | .owner = THIS_MODULE, | ||
| 629 | .fb_open = bfin_lq035_fb_open, | ||
| 630 | .fb_release = bfin_lq035_fb_release, | ||
| 631 | .fb_check_var = bfin_lq035_fb_check_var, | ||
| 632 | .fb_rotate = bfin_lq035_fb_rotate, | ||
| 633 | .fb_fillrect = cfb_fillrect, | ||
| 634 | .fb_copyarea = cfb_copyarea, | ||
| 635 | .fb_imageblit = cfb_imageblit, | ||
| 636 | .fb_cursor = bfin_lq035_fb_cursor, | ||
| 637 | .fb_setcolreg = bfin_lq035_fb_setcolreg, | ||
| 638 | }; | ||
| 639 | |||
| 640 | static int bl_get_brightness(struct backlight_device *bd) | ||
| 641 | { | ||
| 642 | return current_brightness; | ||
| 643 | } | ||
| 644 | |||
| 645 | static const struct backlight_ops bfin_lq035fb_bl_ops = { | ||
| 646 | .get_brightness = bl_get_brightness, | ||
| 647 | }; | ||
| 648 | |||
| 649 | static struct backlight_device *bl_dev; | ||
| 650 | |||
| 651 | static int bfin_lcd_get_power(struct lcd_device *dev) | ||
| 652 | { | ||
| 653 | return 0; | ||
| 654 | } | ||
| 655 | |||
| 656 | static int bfin_lcd_set_power(struct lcd_device *dev, int power) | ||
| 657 | { | ||
| 658 | return 0; | ||
| 659 | } | ||
| 660 | |||
| 661 | static int bfin_lcd_get_contrast(struct lcd_device *dev) | ||
| 662 | { | ||
| 663 | return (int)vcomm_value; | ||
| 664 | } | ||
| 665 | |||
| 666 | static int bfin_lcd_set_contrast(struct lcd_device *dev, int contrast) | ||
| 667 | { | ||
| 668 | if (contrast > 255) | ||
| 669 | contrast = 255; | ||
| 670 | if (contrast < 0) | ||
| 671 | contrast = 0; | ||
| 672 | |||
| 673 | vcomm_value = (unsigned char)contrast; | ||
| 674 | set_vcomm(); | ||
| 675 | return 0; | ||
| 676 | } | ||
| 677 | |||
| 678 | static int bfin_lcd_check_fb(struct lcd_device *lcd, struct fb_info *fi) | ||
| 679 | { | ||
| 680 | if (!fi || (fi == &bfin_lq035_fb)) | ||
| 681 | return 1; | ||
| 682 | return 0; | ||
| 683 | } | ||
| 684 | |||
| 685 | static struct lcd_ops bfin_lcd_ops = { | ||
| 686 | .get_power = bfin_lcd_get_power, | ||
| 687 | .set_power = bfin_lcd_set_power, | ||
| 688 | .get_contrast = bfin_lcd_get_contrast, | ||
| 689 | .set_contrast = bfin_lcd_set_contrast, | ||
| 690 | .check_fb = bfin_lcd_check_fb, | ||
| 691 | }; | ||
| 692 | |||
| 693 | static struct lcd_device *lcd_dev; | ||
| 694 | |||
| 695 | static int __devinit bfin_lq035_probe(struct platform_device *pdev) | ||
| 696 | { | ||
| 697 | struct backlight_properties props; | ||
| 698 | dma_addr_t dma_handle; | ||
| 699 | |||
| 700 | if (request_dma(CH_PPI, KBUILD_MODNAME)) { | ||
| 701 | pr_err("couldn't request PPI DMA\n"); | ||
| 702 | return -EFAULT; | ||
| 703 | } | ||
| 704 | |||
| 705 | if (request_ports()) { | ||
| 706 | pr_err("couldn't request gpio port\n"); | ||
| 707 | free_dma(CH_PPI); | ||
| 708 | return -EFAULT; | ||
| 709 | } | ||
| 710 | |||
| 711 | fb_buffer = dma_alloc_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, | ||
| 712 | &dma_handle, GFP_KERNEL); | ||
| 713 | if (fb_buffer == NULL) { | ||
| 714 | pr_err("couldn't allocate dma buffer\n"); | ||
| 715 | free_dma(CH_PPI); | ||
| 716 | free_ports(); | ||
| 717 | return -ENOMEM; | ||
| 718 | } | ||
| 719 | |||
| 720 | if (L1_DATA_A_LENGTH) | ||
| 721 | dma_desc_table = l1_data_sram_zalloc(TOTAL_DMA_DESC_SIZE); | ||
| 722 | else | ||
| 723 | dma_desc_table = dma_alloc_coherent(NULL, TOTAL_DMA_DESC_SIZE, | ||
| 724 | &dma_handle, 0); | ||
| 725 | |||
| 726 | if (dma_desc_table == NULL) { | ||
| 727 | pr_err("couldn't allocate dma descriptor\n"); | ||
| 728 | free_dma(CH_PPI); | ||
| 729 | free_ports(); | ||
| 730 | dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0); | ||
| 731 | return -ENOMEM; | ||
| 732 | } | ||
| 733 | |||
| 734 | bfin_lq035_fb.screen_base = (void *)fb_buffer; | ||
| 735 | bfin_lq035_fb_fix.smem_start = (int)fb_buffer; | ||
| 736 | if (landscape) { | ||
| 737 | bfin_lq035_fb_defined.xres = LCD_Y_RES; | ||
| 738 | bfin_lq035_fb_defined.yres = LCD_X_RES; | ||
| 739 | bfin_lq035_fb_defined.xres_virtual = LCD_Y_RES; | ||
| 740 | bfin_lq035_fb_defined.yres_virtual = LCD_X_RES; | ||
| 741 | |||
| 742 | bfin_lq035_fb_fix.line_length = LCD_Y_RES*(LCD_BBP/8); | ||
| 743 | } else { | ||
| 744 | bfin_lq035_fb.screen_base += ACTIVE_VIDEO_MEM_OFFSET; | ||
| 745 | bfin_lq035_fb_fix.smem_start += ACTIVE_VIDEO_MEM_OFFSET; | ||
| 746 | } | ||
| 747 | |||
| 748 | bfin_lq035_fb_defined.green.msb_right = 0; | ||
| 749 | bfin_lq035_fb_defined.red.msb_right = 0; | ||
| 750 | bfin_lq035_fb_defined.blue.msb_right = 0; | ||
| 751 | bfin_lq035_fb_defined.green.offset = 5; | ||
| 752 | bfin_lq035_fb_defined.green.length = 6; | ||
| 753 | bfin_lq035_fb_defined.red.length = 5; | ||
| 754 | bfin_lq035_fb_defined.blue.length = 5; | ||
| 755 | |||
| 756 | if (bgr) { | ||
| 757 | bfin_lq035_fb_defined.red.offset = 0; | ||
| 758 | bfin_lq035_fb_defined.blue.offset = 11; | ||
| 759 | } else { | ||
| 760 | bfin_lq035_fb_defined.red.offset = 11; | ||
| 761 | bfin_lq035_fb_defined.blue.offset = 0; | ||
| 762 | } | ||
| 763 | |||
| 764 | bfin_lq035_fb.fbops = &bfin_lq035_fb_ops; | ||
| 765 | bfin_lq035_fb.var = bfin_lq035_fb_defined; | ||
| 766 | |||
| 767 | bfin_lq035_fb.fix = bfin_lq035_fb_fix; | ||
| 768 | bfin_lq035_fb.flags = FBINFO_DEFAULT; | ||
| 769 | |||
| 770 | |||
| 771 | bfin_lq035_fb.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL); | ||
| 772 | if (bfin_lq035_fb.pseudo_palette == NULL) { | ||
| 773 | pr_err("failed to allocate pseudo_palette\n"); | ||
| 774 | free_dma(CH_PPI); | ||
| 775 | free_ports(); | ||
| 776 | dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0); | ||
| 777 | return -ENOMEM; | ||
| 778 | } | ||
| 779 | |||
| 780 | if (fb_alloc_cmap(&bfin_lq035_fb.cmap, NBR_PALETTE, 0) < 0) { | ||
| 781 | pr_err("failed to allocate colormap (%d entries)\n", | ||
| 782 | NBR_PALETTE); | ||
| 783 | free_dma(CH_PPI); | ||
| 784 | free_ports(); | ||
| 785 | dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0); | ||
| 786 | kfree(bfin_lq035_fb.pseudo_palette); | ||
| 787 | return -EFAULT; | ||
| 788 | } | ||
| 789 | |||
| 790 | if (register_framebuffer(&bfin_lq035_fb) < 0) { | ||
| 791 | pr_err("unable to register framebuffer\n"); | ||
| 792 | free_dma(CH_PPI); | ||
| 793 | free_ports(); | ||
| 794 | dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0); | ||
| 795 | fb_buffer = NULL; | ||
| 796 | kfree(bfin_lq035_fb.pseudo_palette); | ||
| 797 | fb_dealloc_cmap(&bfin_lq035_fb.cmap); | ||
| 798 | return -EINVAL; | ||
| 799 | } | ||
| 800 | |||
| 801 | i2c_add_driver(&ad5280_driver); | ||
| 802 | |||
| 803 | memset(&props, 0, sizeof(props)); | ||
| 804 | props.max_brightness = MAX_BRIGHENESS; | ||
| 805 | bl_dev = backlight_device_register("bf537-bl", NULL, NULL, | ||
| 806 | &bfin_lq035fb_bl_ops, &props); | ||
| 807 | |||
| 808 | lcd_dev = lcd_device_register(KBUILD_MODNAME, &pdev->dev, NULL, | ||
| 809 | &bfin_lcd_ops); | ||
| 810 | lcd_dev->props.max_contrast = 255, | ||
| 811 | |||
| 812 | pr_info("initialized"); | ||
| 813 | |||
| 814 | return 0; | ||
| 815 | } | ||
| 816 | |||
| 817 | static int __devexit bfin_lq035_remove(struct platform_device *pdev) | ||
| 818 | { | ||
| 819 | if (fb_buffer != NULL) | ||
| 820 | dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0); | ||
| 821 | |||
| 822 | if (L1_DATA_A_LENGTH) | ||
| 823 | l1_data_sram_free(dma_desc_table); | ||
| 824 | else | ||
| 825 | dma_free_coherent(NULL, TOTAL_DMA_DESC_SIZE, NULL, 0); | ||
| 826 | |||
| 827 | bfin_write_TIMER_DISABLE(TIMEN_SP|TIMEN_SPS|TIMEN_PS_CLS| | ||
| 828 | TIMEN_LP|TIMEN_REV); | ||
| 829 | t_conf_done = 0; | ||
| 830 | |||
| 831 | free_dma(CH_PPI); | ||
| 832 | |||
| 833 | |||
| 834 | kfree(bfin_lq035_fb.pseudo_palette); | ||
| 835 | fb_dealloc_cmap(&bfin_lq035_fb.cmap); | ||
| 836 | |||
| 837 | |||
| 838 | lcd_device_unregister(lcd_dev); | ||
| 839 | backlight_device_unregister(bl_dev); | ||
| 840 | |||
| 841 | unregister_framebuffer(&bfin_lq035_fb); | ||
| 842 | i2c_del_driver(&ad5280_driver); | ||
| 843 | |||
| 844 | free_ports(); | ||
| 845 | |||
| 846 | pr_info("unregistered LCD driver\n"); | ||
| 847 | |||
| 848 | return 0; | ||
| 849 | } | ||
| 850 | |||
| 851 | #ifdef CONFIG_PM | ||
| 852 | static int bfin_lq035_suspend(struct platform_device *pdev, pm_message_t state) | ||
| 853 | { | ||
| 854 | if (lq035_open_cnt > 0) { | ||
| 855 | bfin_write_PPI_CONTROL(0); | ||
| 856 | SSYNC(); | ||
| 857 | disable_dma(CH_PPI); | ||
| 858 | } | ||
| 859 | |||
| 860 | return 0; | ||
| 861 | } | ||
| 862 | |||
| 863 | static int bfin_lq035_resume(struct platform_device *pdev) | ||
| 864 | { | ||
| 865 | if (lq035_open_cnt > 0) { | ||
| 866 | bfin_write_PPI_CONTROL(0); | ||
| 867 | SSYNC(); | ||
| 868 | |||
| 869 | config_dma(); | ||
| 870 | config_ppi(); | ||
| 871 | |||
| 872 | enable_dma(CH_PPI); | ||
| 873 | bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() | PORT_EN); | ||
| 874 | SSYNC(); | ||
| 875 | |||
| 876 | config_timers(); | ||
| 877 | start_timers(); | ||
| 878 | } else { | ||
| 879 | t_conf_done = 0; | ||
| 880 | } | ||
| 881 | |||
| 882 | return 0; | ||
| 883 | } | ||
| 884 | #else | ||
| 885 | # define bfin_lq035_suspend NULL | ||
| 886 | # define bfin_lq035_resume NULL | ||
| 887 | #endif | ||
| 888 | |||
| 889 | static struct platform_driver bfin_lq035_driver = { | ||
| 890 | .probe = bfin_lq035_probe, | ||
| 891 | .remove = __devexit_p(bfin_lq035_remove), | ||
| 892 | .suspend = bfin_lq035_suspend, | ||
| 893 | .resume = bfin_lq035_resume, | ||
| 894 | .driver = { | ||
| 895 | .name = KBUILD_MODNAME, | ||
| 896 | .owner = THIS_MODULE, | ||
| 897 | }, | ||
| 898 | }; | ||
| 899 | |||
| 900 | static int __init bfin_lq035_driver_init(void) | ||
| 901 | { | ||
| 902 | request_module("i2c-bfin-twi"); | ||
| 903 | return platform_driver_register(&bfin_lq035_driver); | ||
| 904 | } | ||
| 905 | module_init(bfin_lq035_driver_init); | ||
| 906 | |||
| 907 | static void __exit bfin_lq035_driver_cleanup(void) | ||
| 908 | { | ||
| 909 | platform_driver_unregister(&bfin_lq035_driver); | ||
| 910 | } | ||
| 911 | module_exit(bfin_lq035_driver_cleanup); | ||
| 912 | |||
| 913 | MODULE_DESCRIPTION("SHARP LQ035Q7DB03 TFT LCD Driver"); | ||
| 914 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/bfin_adv7393fb.c new file mode 100644 index 000000000000..8486f541156b --- /dev/null +++ b/drivers/video/bfin_adv7393fb.c | |||
| @@ -0,0 +1,832 @@ | |||
| 1 | /* | ||
| 2 | * Frame buffer driver for ADV7393/2 video encoder | ||
| 3 | * | ||
| 4 | * Copyright 2006-2009 Analog Devices Inc. | ||
| 5 | * Licensed under the GPL-2 or late. | ||
| 6 | */ | ||
| 7 | |||
| 8 | /* | ||
| 9 | * TODO: Remove Globals | ||
| 10 | * TODO: Code Cleanup | ||
| 11 | */ | ||
| 12 | |||
| 13 | #define pr_fmt(fmt) DRIVER_NAME ": " fmt | ||
| 14 | |||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/errno.h> | ||
| 18 | #include <linux/string.h> | ||
| 19 | #include <linux/mm.h> | ||
| 20 | #include <linux/tty.h> | ||
| 21 | #include <linux/slab.h> | ||
| 22 | #include <linux/delay.h> | ||
| 23 | #include <linux/fb.h> | ||
| 24 | #include <linux/ioport.h> | ||
| 25 | #include <linux/init.h> | ||
| 26 | #include <linux/types.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | #include <linux/sched.h> | ||
| 29 | #include <asm/blackfin.h> | ||
| 30 | #include <asm/irq.h> | ||
| 31 | #include <asm/dma.h> | ||
| 32 | #include <linux/uaccess.h> | ||
| 33 | #include <linux/gpio.h> | ||
| 34 | #include <asm/portmux.h> | ||
| 35 | |||
| 36 | #include <linux/dma-mapping.h> | ||
| 37 | #include <linux/proc_fs.h> | ||
| 38 | #include <linux/platform_device.h> | ||
| 39 | |||
| 40 | #include <linux/i2c.h> | ||
| 41 | #include <linux/i2c-dev.h> | ||
| 42 | |||
| 43 | #include "bfin_adv7393fb.h" | ||
| 44 | |||
| 45 | static int mode = VMODE; | ||
| 46 | static int mem = VMEM; | ||
| 47 | static int nocursor = 1; | ||
| 48 | |||
| 49 | static const unsigned short ppi_pins[] = { | ||
| 50 | P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, | ||
| 51 | P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, | ||
| 52 | P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, | ||
| 53 | P_PPI0_D8, P_PPI0_D9, P_PPI0_D10, P_PPI0_D11, | ||
| 54 | P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15, | ||
| 55 | 0 | ||
| 56 | }; | ||
| 57 | |||
| 58 | /* | ||
| 59 | * card parameters | ||
| 60 | */ | ||
| 61 | |||
| 62 | static struct bfin_adv7393_fb_par { | ||
| 63 | /* structure holding blackfin / adv7393 paramters when | ||
| 64 | screen is blanked */ | ||
| 65 | struct { | ||
| 66 | u8 Mode; /* ntsc/pal/? */ | ||
| 67 | } vga_state; | ||
| 68 | atomic_t ref_count; | ||
| 69 | } bfin_par; | ||
| 70 | |||
| 71 | /* --------------------------------------------------------------------- */ | ||
| 72 | |||
| 73 | static struct fb_var_screeninfo bfin_adv7393_fb_defined = { | ||
| 74 | .xres = 720, | ||
| 75 | .yres = 480, | ||
| 76 | .xres_virtual = 720, | ||
| 77 | .yres_virtual = 480, | ||
| 78 | .bits_per_pixel = 16, | ||
| 79 | .activate = FB_ACTIVATE_TEST, | ||
| 80 | .height = -1, | ||
| 81 | .width = -1, | ||
| 82 | .left_margin = 0, | ||
| 83 | .right_margin = 0, | ||
| 84 | .upper_margin = 0, | ||
| 85 | .lower_margin = 0, | ||
| 86 | .vmode = FB_VMODE_INTERLACED, | ||
| 87 | .red = {11, 5, 0}, | ||
| 88 | .green = {5, 6, 0}, | ||
| 89 | .blue = {0, 5, 0}, | ||
| 90 | .transp = {0, 0, 0}, | ||
| 91 | }; | ||
| 92 | |||
| 93 | static struct fb_fix_screeninfo bfin_adv7393_fb_fix __devinitdata = { | ||
| 94 | .id = "BFIN ADV7393", | ||
| 95 | .smem_len = 720 * 480 * 2, | ||
| 96 | .type = FB_TYPE_PACKED_PIXELS, | ||
| 97 | .visual = FB_VISUAL_TRUECOLOR, | ||
| 98 | .xpanstep = 0, | ||
| 99 | .ypanstep = 0, | ||
| 100 | .line_length = 720 * 2, | ||
| 101 | .accel = FB_ACCEL_NONE | ||
| 102 | }; | ||
| 103 | |||
| 104 | static struct fb_ops bfin_adv7393_fb_ops = { | ||
| 105 | .owner = THIS_MODULE, | ||
| 106 | .fb_open = bfin_adv7393_fb_open, | ||
| 107 | .fb_release = bfin_adv7393_fb_release, | ||
| 108 | .fb_check_var = bfin_adv7393_fb_check_var, | ||
| 109 | .fb_pan_display = bfin_adv7393_fb_pan_display, | ||
| 110 | .fb_blank = bfin_adv7393_fb_blank, | ||
| 111 | .fb_fillrect = cfb_fillrect, | ||
| 112 | .fb_copyarea = cfb_copyarea, | ||
| 113 | .fb_imageblit = cfb_imageblit, | ||
| 114 | .fb_cursor = bfin_adv7393_fb_cursor, | ||
| 115 | .fb_setcolreg = bfin_adv7393_fb_setcolreg, | ||
| 116 | }; | ||
| 117 | |||
| 118 | static int dma_desc_list(struct adv7393fb_device *fbdev, u16 arg) | ||
| 119 | { | ||
| 120 | if (arg == BUILD) { /* Build */ | ||
| 121 | fbdev->vb1 = l1_data_sram_zalloc(sizeof(struct dmasg)); | ||
| 122 | if (fbdev->vb1 == NULL) | ||
| 123 | goto error; | ||
| 124 | |||
| 125 | fbdev->av1 = l1_data_sram_zalloc(sizeof(struct dmasg)); | ||
| 126 | if (fbdev->av1 == NULL) | ||
| 127 | goto error; | ||
| 128 | |||
| 129 | fbdev->vb2 = l1_data_sram_zalloc(sizeof(struct dmasg)); | ||
| 130 | if (fbdev->vb2 == NULL) | ||
| 131 | goto error; | ||
| 132 | |||
| 133 | fbdev->av2 = l1_data_sram_zalloc(sizeof(struct dmasg)); | ||
| 134 | if (fbdev->av2 == NULL) | ||
| 135 | goto error; | ||
| 136 | |||
| 137 | /* Build linked DMA descriptor list */ | ||
| 138 | fbdev->vb1->next_desc_addr = fbdev->av1; | ||
| 139 | fbdev->av1->next_desc_addr = fbdev->vb2; | ||
| 140 | fbdev->vb2->next_desc_addr = fbdev->av2; | ||
| 141 | fbdev->av2->next_desc_addr = fbdev->vb1; | ||
| 142 | |||
| 143 | /* Save list head */ | ||
| 144 | fbdev->descriptor_list_head = fbdev->av2; | ||
| 145 | |||
| 146 | /* Vertical Blanking Field 1 */ | ||
| 147 | fbdev->vb1->start_addr = VB_DUMMY_MEMORY_SOURCE; | ||
| 148 | fbdev->vb1->cfg = DMA_CFG_VAL; | ||
| 149 | |||
| 150 | fbdev->vb1->x_count = | ||
| 151 | fbdev->modes[mode].xres + fbdev->modes[mode].boeft_blank; | ||
| 152 | |||
| 153 | fbdev->vb1->x_modify = 0; | ||
| 154 | fbdev->vb1->y_count = fbdev->modes[mode].vb1_lines; | ||
| 155 | fbdev->vb1->y_modify = 0; | ||
| 156 | |||
| 157 | /* Active Video Field 1 */ | ||
| 158 | |||
| 159 | fbdev->av1->start_addr = (unsigned long)fbdev->fb_mem; | ||
| 160 | fbdev->av1->cfg = DMA_CFG_VAL; | ||
| 161 | fbdev->av1->x_count = | ||
| 162 | fbdev->modes[mode].xres + fbdev->modes[mode].boeft_blank; | ||
| 163 | fbdev->av1->x_modify = fbdev->modes[mode].bpp / 8; | ||
| 164 | fbdev->av1->y_count = fbdev->modes[mode].a_lines; | ||
| 165 | fbdev->av1->y_modify = | ||
| 166 | (fbdev->modes[mode].xres - fbdev->modes[mode].boeft_blank + | ||
| 167 | 1) * (fbdev->modes[mode].bpp / 8); | ||
| 168 | |||
| 169 | /* Vertical Blanking Field 2 */ | ||
| 170 | |||
| 171 | fbdev->vb2->start_addr = VB_DUMMY_MEMORY_SOURCE; | ||
| 172 | fbdev->vb2->cfg = DMA_CFG_VAL; | ||
| 173 | fbdev->vb2->x_count = | ||
| 174 | fbdev->modes[mode].xres + fbdev->modes[mode].boeft_blank; | ||
| 175 | |||
| 176 | fbdev->vb2->x_modify = 0; | ||
| 177 | fbdev->vb2->y_count = fbdev->modes[mode].vb2_lines; | ||
| 178 | fbdev->vb2->y_modify = 0; | ||
| 179 | |||
| 180 | /* Active Video Field 2 */ | ||
| 181 | |||
| 182 | fbdev->av2->start_addr = | ||
| 183 | (unsigned long)fbdev->fb_mem + fbdev->line_len; | ||
| 184 | |||
| 185 | fbdev->av2->cfg = DMA_CFG_VAL; | ||
| 186 | |||
| 187 | fbdev->av2->x_count = | ||
| 188 | fbdev->modes[mode].xres + fbdev->modes[mode].boeft_blank; | ||
| 189 | |||
| 190 | fbdev->av2->x_modify = (fbdev->modes[mode].bpp / 8); | ||
| 191 | fbdev->av2->y_count = fbdev->modes[mode].a_lines; | ||
| 192 | |||
| 193 | fbdev->av2->y_modify = | ||
| 194 | (fbdev->modes[mode].xres - fbdev->modes[mode].boeft_blank + | ||
| 195 | 1) * (fbdev->modes[mode].bpp / 8); | ||
| 196 | |||
| 197 | return 1; | ||
| 198 | } | ||
| 199 | |||
| 200 | error: | ||
| 201 | l1_data_sram_free(fbdev->vb1); | ||
| 202 | l1_data_sram_free(fbdev->av1); | ||
| 203 | l1_data_sram_free(fbdev->vb2); | ||
| 204 | l1_data_sram_free(fbdev->av2); | ||
| 205 | |||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | static int bfin_config_dma(struct adv7393fb_device *fbdev) | ||
| 210 | { | ||
| 211 | BUG_ON(!(fbdev->fb_mem)); | ||
| 212 | |||
| 213 | set_dma_x_count(CH_PPI, fbdev->descriptor_list_head->x_count); | ||
| 214 | set_dma_x_modify(CH_PPI, fbdev->descriptor_list_head->x_modify); | ||
| 215 | set_dma_y_count(CH_PPI, fbdev->descriptor_list_head->y_count); | ||
| 216 | set_dma_y_modify(CH_PPI, fbdev->descriptor_list_head->y_modify); | ||
| 217 | set_dma_start_addr(CH_PPI, fbdev->descriptor_list_head->start_addr); | ||
| 218 | set_dma_next_desc_addr(CH_PPI, | ||
| 219 | fbdev->descriptor_list_head->next_desc_addr); | ||
| 220 | set_dma_config(CH_PPI, fbdev->descriptor_list_head->cfg); | ||
| 221 | |||
| 222 | return 1; | ||
| 223 | } | ||
| 224 | |||
| 225 | static void bfin_disable_dma(void) | ||
| 226 | { | ||
| 227 | bfin_write_DMA0_CONFIG(bfin_read_DMA0_CONFIG() & ~DMAEN); | ||
| 228 | } | ||
| 229 | |||
| 230 | static void bfin_config_ppi(struct adv7393fb_device *fbdev) | ||
| 231 | { | ||
| 232 | if (ANOMALY_05000183) { | ||
| 233 | bfin_write_TIMER2_CONFIG(WDTH_CAP); | ||
| 234 | bfin_write_TIMER_ENABLE(TIMEN2); | ||
| 235 | } | ||
| 236 | |||
| 237 | bfin_write_PPI_CONTROL(0x381E); | ||
| 238 | bfin_write_PPI_FRAME(fbdev->modes[mode].tot_lines); | ||
| 239 | bfin_write_PPI_COUNT(fbdev->modes[mode].xres + | ||
| 240 | fbdev->modes[mode].boeft_blank - 1); | ||
| 241 | bfin_write_PPI_DELAY(fbdev->modes[mode].aoeft_blank - 1); | ||
| 242 | } | ||
| 243 | |||
| 244 | static void bfin_enable_ppi(void) | ||
| 245 | { | ||
| 246 | bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() | PORT_EN); | ||
| 247 | } | ||
| 248 | |||
| 249 | static void bfin_disable_ppi(void) | ||
| 250 | { | ||
| 251 | bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() & ~PORT_EN); | ||
| 252 | } | ||
| 253 | |||
| 254 | static inline int adv7393_write(struct i2c_client *client, u8 reg, u8 value) | ||
| 255 | { | ||
| 256 | return i2c_smbus_write_byte_data(client, reg, value); | ||
| 257 | } | ||
| 258 | |||
| 259 | static inline int adv7393_read(struct i2c_client *client, u8 reg) | ||
| 260 | { | ||
| 261 | return i2c_smbus_read_byte_data(client, reg); | ||
| 262 | } | ||
| 263 | |||
| 264 | static int | ||
| 265 | adv7393_write_block(struct i2c_client *client, | ||
| 266 | const u8 *data, unsigned int len) | ||
| 267 | { | ||
| 268 | int ret = -1; | ||
| 269 | u8 reg; | ||
| 270 | |||
| 271 | while (len >= 2) { | ||
| 272 | reg = *data++; | ||
| 273 | ret = adv7393_write(client, reg, *data++); | ||
| 274 | if (ret < 0) | ||
| 275 | break; | ||
| 276 | len -= 2; | ||
| 277 | } | ||
| 278 | |||
| 279 | return ret; | ||
| 280 | } | ||
| 281 | |||
| 282 | static int adv7393_mode(struct i2c_client *client, u16 mode) | ||
| 283 | { | ||
| 284 | switch (mode) { | ||
| 285 | case POWER_ON: /* ADV7393 Sleep mode OFF */ | ||
| 286 | adv7393_write(client, 0x00, 0x1E); | ||
| 287 | break; | ||
| 288 | case POWER_DOWN: /* ADV7393 Sleep mode ON */ | ||
| 289 | adv7393_write(client, 0x00, 0x1F); | ||
| 290 | break; | ||
| 291 | case BLANK_OFF: /* Pixel Data Valid */ | ||
| 292 | adv7393_write(client, 0x82, 0xCB); | ||
| 293 | break; | ||
| 294 | case BLANK_ON: /* Pixel Data Invalid */ | ||
| 295 | adv7393_write(client, 0x82, 0x8B); | ||
| 296 | break; | ||
| 297 | default: | ||
| 298 | return -EINVAL; | ||
| 299 | break; | ||
| 300 | } | ||
| 301 | return 0; | ||
| 302 | } | ||
| 303 | |||
| 304 | static irqreturn_t ppi_irq_error(int irq, void *dev_id) | ||
| 305 | { | ||
| 306 | |||
| 307 | struct adv7393fb_device *fbdev = (struct adv7393fb_device *)dev_id; | ||
| 308 | |||
| 309 | u16 status = bfin_read_PPI_STATUS(); | ||
| 310 | |||
| 311 | pr_debug("%s: PPI Status = 0x%X\n", __func__, status); | ||
| 312 | |||
| 313 | if (status) { | ||
| 314 | bfin_disable_dma(); /* TODO: Check Sequence */ | ||
| 315 | bfin_disable_ppi(); | ||
| 316 | bfin_clear_PPI_STATUS(); | ||
| 317 | bfin_config_dma(fbdev); | ||
| 318 | bfin_enable_ppi(); | ||
| 319 | } | ||
| 320 | |||
| 321 | return IRQ_HANDLED; | ||
| 322 | |||
| 323 | } | ||
| 324 | |||
| 325 | static int proc_output(char *buf) | ||
| 326 | { | ||
| 327 | char *p = buf; | ||
| 328 | |||
| 329 | p += sprintf(p, | ||
| 330 | "Usage:\n" | ||
| 331 | "echo 0x[REG][Value] > adv7393\n" | ||
| 332 | "example: echo 0x1234 >adv7393\n" | ||
| 333 | "writes 0x34 into Register 0x12\n"); | ||
| 334 | |||
| 335 | return p - buf; | ||
| 336 | } | ||
| 337 | |||
| 338 | static int | ||
| 339 | adv7393_read_proc(char *page, char **start, off_t off, | ||
| 340 | int count, int *eof, void *data) | ||
| 341 | { | ||
| 342 | int len; | ||
| 343 | |||
| 344 | len = proc_output(page); | ||
| 345 | if (len <= off + count) | ||
| 346 | *eof = 1; | ||
| 347 | *start = page + off; | ||
| 348 | len -= off; | ||
| 349 | if (len > count) | ||
| 350 | len = count; | ||
| 351 | if (len < 0) | ||
| 352 | len = 0; | ||
| 353 | return len; | ||
| 354 | } | ||
| 355 | |||
| 356 | static int | ||
| 357 | adv7393_write_proc(struct file *file, const char __user * buffer, | ||
| 358 | unsigned long count, void *data) | ||
| 359 | { | ||
| 360 | struct adv7393fb_device *fbdev = data; | ||
| 361 | char line[8]; | ||
| 362 | unsigned int val; | ||
| 363 | int ret; | ||
| 364 | |||
| 365 | ret = copy_from_user(line, buffer, count); | ||
| 366 | if (ret) | ||
| 367 | return -EFAULT; | ||
| 368 | |||
| 369 | val = simple_strtoul(line, NULL, 0); | ||
| 370 | adv7393_write(fbdev->client, val >> 8, val & 0xff); | ||
| 371 | |||
| 372 | return count; | ||
| 373 | } | ||
| 374 | |||
| 375 | static int __devinit bfin_adv7393_fb_probe(struct i2c_client *client, | ||
| 376 | const struct i2c_device_id *id) | ||
| 377 | { | ||
| 378 | int ret = 0; | ||
| 379 | struct proc_dir_entry *entry; | ||
| 380 | int num_modes = ARRAY_SIZE(known_modes); | ||
| 381 | |||
| 382 | struct adv7393fb_device *fbdev = NULL; | ||
| 383 | |||
| 384 | if (mem > 2) { | ||
| 385 | dev_err(&client->dev, "mem out of allowed range [1;2]\n"); | ||
| 386 | return -EINVAL; | ||
| 387 | } | ||
| 388 | |||
| 389 | if (mode > num_modes) { | ||
| 390 | dev_err(&client->dev, "mode %d: not supported", mode); | ||
| 391 | return -EFAULT; | ||
| 392 | } | ||
| 393 | |||
| 394 | fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL); | ||
| 395 | if (!fbdev) { | ||
| 396 | dev_err(&client->dev, "failed to allocate device private record"); | ||
| 397 | return -ENOMEM; | ||
| 398 | } | ||
| 399 | |||
| 400 | i2c_set_clientdata(client, fbdev); | ||
| 401 | |||
| 402 | fbdev->modes = known_modes; | ||
| 403 | fbdev->client = client; | ||
| 404 | |||
| 405 | fbdev->fb_len = | ||
| 406 | mem * fbdev->modes[mode].xres * fbdev->modes[mode].xres * | ||
| 407 | (fbdev->modes[mode].bpp / 8); | ||
| 408 | |||
| 409 | fbdev->line_len = | ||
| 410 | fbdev->modes[mode].xres * (fbdev->modes[mode].bpp / 8); | ||
| 411 | |||
| 412 | /* Workaround "PPI Does Not Start Properly In Specific Mode" */ | ||
| 413 | if (ANOMALY_05000400) { | ||
| 414 | if (gpio_request(P_IDENT(P_PPI0_FS3), "PPI0_FS3")) { | ||
| 415 | dev_err(&client->dev, "PPI0_FS3 GPIO request failed\n"); | ||
| 416 | ret = -EBUSY; | ||
| 417 | goto out_8; | ||
| 418 | } | ||
| 419 | gpio_direction_output(P_IDENT(P_PPI0_FS3), 0); | ||
| 420 | } | ||
| 421 | |||
| 422 | if (peripheral_request_list(ppi_pins, DRIVER_NAME)) { | ||
| 423 | dev_err(&client->dev, "requesting PPI peripheral failed\n"); | ||
| 424 | ret = -EFAULT; | ||
| 425 | goto out_8; | ||
| 426 | } | ||
| 427 | |||
| 428 | fbdev->fb_mem = | ||
| 429 | dma_alloc_coherent(NULL, fbdev->fb_len, &fbdev->dma_handle, | ||
| 430 | GFP_KERNEL); | ||
| 431 | |||
| 432 | if (NULL == fbdev->fb_mem) { | ||
| 433 | dev_err(&client->dev, "couldn't allocate dma buffer (%d bytes)\n", | ||
| 434 | (u32) fbdev->fb_len); | ||
| 435 | ret = -ENOMEM; | ||
| 436 | goto out_7; | ||
| 437 | } | ||
| 438 | |||
| 439 | fbdev->info.screen_base = (void *)fbdev->fb_mem; | ||
| 440 | bfin_adv7393_fb_fix.smem_start = (int)fbdev->fb_mem; | ||
| 441 | |||
| 442 | bfin_adv7393_fb_fix.smem_len = fbdev->fb_len; | ||
| 443 | bfin_adv7393_fb_fix.line_length = fbdev->line_len; | ||
| 444 | |||
| 445 | if (mem > 1) | ||
| 446 | bfin_adv7393_fb_fix.ypanstep = 1; | ||
| 447 | |||
| 448 | bfin_adv7393_fb_defined.red.length = 5; | ||
| 449 | bfin_adv7393_fb_defined.green.length = 6; | ||
| 450 | bfin_adv7393_fb_defined.blue.length = 5; | ||
| 451 | |||
| 452 | bfin_adv7393_fb_defined.xres = fbdev->modes[mode].xres; | ||
| 453 | bfin_adv7393_fb_defined.yres = fbdev->modes[mode].yres; | ||
| 454 | bfin_adv7393_fb_defined.xres_virtual = fbdev->modes[mode].xres; | ||
| 455 | bfin_adv7393_fb_defined.yres_virtual = mem * fbdev->modes[mode].yres; | ||
| 456 | bfin_adv7393_fb_defined.bits_per_pixel = fbdev->modes[mode].bpp; | ||
| 457 | |||
| 458 | fbdev->info.fbops = &bfin_adv7393_fb_ops; | ||
| 459 | fbdev->info.var = bfin_adv7393_fb_defined; | ||
| 460 | fbdev->info.fix = bfin_adv7393_fb_fix; | ||
| 461 | fbdev->info.par = &bfin_par; | ||
| 462 | fbdev->info.flags = FBINFO_DEFAULT; | ||
| 463 | |||
| 464 | fbdev->info.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL); | ||
| 465 | if (!fbdev->info.pseudo_palette) { | ||
| 466 | dev_err(&client->dev, "failed to allocate pseudo_palette\n"); | ||
| 467 | ret = -ENOMEM; | ||
| 468 | goto out_6; | ||
| 469 | } | ||
| 470 | |||
| 471 | if (fb_alloc_cmap(&fbdev->info.cmap, BFIN_LCD_NBR_PALETTE_ENTRIES, 0) < 0) { | ||
| 472 | dev_err(&client->dev, "failed to allocate colormap (%d entries)\n", | ||
| 473 | BFIN_LCD_NBR_PALETTE_ENTRIES); | ||
| 474 | ret = -EFAULT; | ||
| 475 | goto out_5; | ||
| 476 | } | ||
| 477 | |||
| 478 | if (request_dma(CH_PPI, "BF5xx_PPI_DMA") < 0) { | ||
| 479 | dev_err(&client->dev, "unable to request PPI DMA\n"); | ||
| 480 | ret = -EFAULT; | ||
| 481 | goto out_4; | ||
| 482 | } | ||
| 483 | |||
| 484 | if (request_irq(IRQ_PPI_ERROR, ppi_irq_error, IRQF_DISABLED, | ||
| 485 | "PPI ERROR", fbdev) < 0) { | ||
| 486 | dev_err(&client->dev, "unable to request PPI ERROR IRQ\n"); | ||
| 487 | ret = -EFAULT; | ||
| 488 | goto out_3; | ||
| 489 | } | ||
| 490 | |||
| 491 | fbdev->open = 0; | ||
| 492 | |||
| 493 | ret = adv7393_write_block(client, fbdev->modes[mode].adv7393_i2c_initd, | ||
| 494 | fbdev->modes[mode].adv7393_i2c_initd_len); | ||
| 495 | |||
| 496 | if (ret) { | ||
| 497 | dev_err(&client->dev, "i2c attach: init error\n"); | ||
| 498 | goto out_1; | ||
| 499 | } | ||
| 500 | |||
| 501 | |||
| 502 | if (register_framebuffer(&fbdev->info) < 0) { | ||
| 503 | dev_err(&client->dev, "unable to register framebuffer\n"); | ||
| 504 | ret = -EFAULT; | ||
| 505 | goto out_1; | ||
| 506 | } | ||
| 507 | |||
| 508 | dev_info(&client->dev, "fb%d: %s frame buffer device\n", | ||
| 509 | fbdev->info.node, fbdev->info.fix.id); | ||
| 510 | dev_info(&client->dev, "fb memory address : 0x%p\n", fbdev->fb_mem); | ||
| 511 | |||
| 512 | entry = create_proc_entry("driver/adv7393", 0, NULL); | ||
| 513 | if (!entry) { | ||
| 514 | dev_err(&client->dev, "unable to create /proc entry\n"); | ||
| 515 | ret = -EFAULT; | ||
| 516 | goto out_0; | ||
| 517 | } | ||
| 518 | |||
| 519 | entry->read_proc = adv7393_read_proc; | ||
| 520 | entry->write_proc = adv7393_write_proc; | ||
| 521 | entry->data = fbdev; | ||
| 522 | |||
| 523 | return 0; | ||
| 524 | |||
| 525 | out_0: | ||
| 526 | unregister_framebuffer(&fbdev->info); | ||
| 527 | out_1: | ||
| 528 | free_irq(IRQ_PPI_ERROR, fbdev); | ||
| 529 | out_3: | ||
| 530 | free_dma(CH_PPI); | ||
| 531 | out_4: | ||
| 532 | dma_free_coherent(NULL, fbdev->fb_len, fbdev->fb_mem, | ||
| 533 | fbdev->dma_handle); | ||
| 534 | out_5: | ||
| 535 | fb_dealloc_cmap(&fbdev->info.cmap); | ||
| 536 | out_6: | ||
| 537 | kfree(fbdev->info.pseudo_palette); | ||
| 538 | out_7: | ||
| 539 | peripheral_free_list(ppi_pins); | ||
| 540 | out_8: | ||
| 541 | kfree(fbdev); | ||
| 542 | |||
| 543 | return ret; | ||
| 544 | } | ||
| 545 | |||
| 546 | static int bfin_adv7393_fb_open(struct fb_info *info, int user) | ||
| 547 | { | ||
| 548 | struct adv7393fb_device *fbdev = to_adv7393fb_device(info); | ||
| 549 | |||
| 550 | fbdev->info.screen_base = (void *)fbdev->fb_mem; | ||
| 551 | if (!fbdev->info.screen_base) { | ||
| 552 | dev_err(&fbdev->client->dev, "unable to map device\n"); | ||
| 553 | return -ENOMEM; | ||
| 554 | } | ||
| 555 | |||
| 556 | fbdev->open = 1; | ||
| 557 | dma_desc_list(fbdev, BUILD); | ||
| 558 | adv7393_mode(fbdev->client, BLANK_OFF); | ||
| 559 | bfin_config_ppi(fbdev); | ||
| 560 | bfin_config_dma(fbdev); | ||
| 561 | bfin_enable_ppi(); | ||
| 562 | |||
| 563 | return 0; | ||
| 564 | } | ||
| 565 | |||
| 566 | static int bfin_adv7393_fb_release(struct fb_info *info, int user) | ||
| 567 | { | ||
| 568 | struct adv7393fb_device *fbdev = to_adv7393fb_device(info); | ||
| 569 | |||
| 570 | adv7393_mode(fbdev->client, BLANK_ON); | ||
| 571 | bfin_disable_dma(); | ||
| 572 | bfin_disable_ppi(); | ||
| 573 | dma_desc_list(fbdev, DESTRUCT); | ||
| 574 | fbdev->open = 0; | ||
| 575 | return 0; | ||
| 576 | } | ||
| 577 | |||
| 578 | static int | ||
| 579 | bfin_adv7393_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | ||
| 580 | { | ||
| 581 | |||
| 582 | switch (var->bits_per_pixel) { | ||
| 583 | case 16:/* DIRECTCOLOUR, 64k */ | ||
| 584 | var->red.offset = info->var.red.offset; | ||
| 585 | var->green.offset = info->var.green.offset; | ||
| 586 | var->blue.offset = info->var.blue.offset; | ||
| 587 | var->red.length = info->var.red.length; | ||
| 588 | var->green.length = info->var.green.length; | ||
| 589 | var->blue.length = info->var.blue.length; | ||
| 590 | var->transp.offset = 0; | ||
| 591 | var->transp.length = 0; | ||
| 592 | var->transp.msb_right = 0; | ||
| 593 | var->red.msb_right = 0; | ||
| 594 | var->green.msb_right = 0; | ||
| 595 | var->blue.msb_right = 0; | ||
| 596 | break; | ||
| 597 | default: | ||
| 598 | pr_debug("%s: depth not supported: %u BPP\n", __func__, | ||
| 599 | var->bits_per_pixel); | ||
| 600 | return -EINVAL; | ||
| 601 | } | ||
| 602 | |||
| 603 | if (info->var.xres != var->xres || | ||
| 604 | info->var.yres != var->yres || | ||
| 605 | info->var.xres_virtual != var->xres_virtual || | ||
| 606 | info->var.yres_virtual != var->yres_virtual) { | ||
| 607 | pr_debug("%s: Resolution not supported: X%u x Y%u\n", | ||
| 608 | __func__, var->xres, var->yres); | ||
| 609 | return -EINVAL; | ||
| 610 | } | ||
| 611 | |||
| 612 | /* | ||
| 613 | * Memory limit | ||
| 614 | */ | ||
| 615 | |||
| 616 | if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) { | ||
| 617 | pr_debug("%s: Memory Limit requested yres_virtual = %u\n", | ||
| 618 | __func__, var->yres_virtual); | ||
| 619 | return -ENOMEM; | ||
| 620 | } | ||
| 621 | |||
| 622 | return 0; | ||
| 623 | } | ||
| 624 | |||
| 625 | static int | ||
| 626 | bfin_adv7393_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | ||
| 627 | { | ||
| 628 | int dy; | ||
| 629 | u32 dmaaddr; | ||
| 630 | struct adv7393fb_device *fbdev = to_adv7393fb_device(info); | ||
| 631 | |||
| 632 | if (!var || !info) | ||
| 633 | return -EINVAL; | ||
| 634 | |||
| 635 | if (var->xoffset - info->var.xoffset) { | ||
| 636 | /* No support for X panning for now! */ | ||
| 637 | return -EINVAL; | ||
| 638 | } | ||
| 639 | dy = var->yoffset - info->var.yoffset; | ||
| 640 | |||
| 641 | if (dy) { | ||
| 642 | pr_debug("%s: Panning screen of %d lines\n", __func__, dy); | ||
| 643 | |||
| 644 | dmaaddr = fbdev->av1->start_addr; | ||
| 645 | dmaaddr += (info->fix.line_length * dy); | ||
| 646 | /* TODO: Wait for current frame to finished */ | ||
| 647 | |||
| 648 | fbdev->av1->start_addr = (unsigned long)dmaaddr; | ||
| 649 | fbdev->av2->start_addr = (unsigned long)dmaaddr + fbdev->line_len; | ||
| 650 | } | ||
| 651 | |||
| 652 | return 0; | ||
| 653 | |||
| 654 | } | ||
| 655 | |||
| 656 | /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */ | ||
| 657 | static int bfin_adv7393_fb_blank(int blank, struct fb_info *info) | ||
| 658 | { | ||
| 659 | struct adv7393fb_device *fbdev = to_adv7393fb_device(info); | ||
| 660 | |||
| 661 | switch (blank) { | ||
| 662 | |||
| 663 | case VESA_NO_BLANKING: | ||
| 664 | /* Turn on panel */ | ||
| 665 | adv7393_mode(fbdev->client, BLANK_OFF); | ||
| 666 | break; | ||
| 667 | |||
| 668 | case VESA_VSYNC_SUSPEND: | ||
| 669 | case VESA_HSYNC_SUSPEND: | ||
| 670 | case VESA_POWERDOWN: | ||
| 671 | /* Turn off panel */ | ||
| 672 | adv7393_mode(fbdev->client, BLANK_ON); | ||
| 673 | break; | ||
| 674 | |||
| 675 | default: | ||
| 676 | return -EINVAL; | ||
| 677 | break; | ||
| 678 | } | ||
| 679 | return 0; | ||
| 680 | } | ||
| 681 | |||
| 682 | int bfin_adv7393_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) | ||
| 683 | { | ||
| 684 | if (nocursor) | ||
| 685 | return 0; | ||
| 686 | else | ||
| 687 | return -EINVAL; /* just to force soft_cursor() call */ | ||
| 688 | } | ||
| 689 | |||
| 690 | static int bfin_adv7393_fb_setcolreg(u_int regno, u_int red, u_int green, | ||
| 691 | u_int blue, u_int transp, | ||
| 692 | struct fb_info *info) | ||
| 693 | { | ||
| 694 | if (regno >= BFIN_LCD_NBR_PALETTE_ENTRIES) | ||
| 695 | return -EINVAL; | ||
| 696 | |||
| 697 | if (info->var.grayscale) | ||
| 698 | /* grayscale = 0.30*R + 0.59*G + 0.11*B */ | ||
| 699 | red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; | ||
| 700 | |||
| 701 | if (info->fix.visual == FB_VISUAL_TRUECOLOR) { | ||
| 702 | u32 value; | ||
| 703 | /* Place color in the pseudopalette */ | ||
| 704 | if (regno > 16) | ||
| 705 | return -EINVAL; | ||
| 706 | |||
| 707 | red >>= (16 - info->var.red.length); | ||
| 708 | green >>= (16 - info->var.green.length); | ||
| 709 | blue >>= (16 - info->var.blue.length); | ||
| 710 | |||
| 711 | value = (red << info->var.red.offset) | | ||
| 712 | (green << info->var.green.offset)| | ||
| 713 | (blue << info->var.blue.offset); | ||
| 714 | value &= 0xFFFF; | ||
| 715 | |||
| 716 | ((u32 *) (info->pseudo_palette))[regno] = value; | ||
| 717 | } | ||
| 718 | |||
| 719 | return 0; | ||
| 720 | } | ||
| 721 | |||
| 722 | static int __devexit bfin_adv7393_fb_remove(struct i2c_client *client) | ||
| 723 | { | ||
| 724 | struct adv7393fb_device *fbdev = i2c_get_clientdata(client); | ||
| 725 | |||
| 726 | adv7393_mode(client, POWER_DOWN); | ||
| 727 | |||
| 728 | if (fbdev->fb_mem) | ||
| 729 | dma_free_coherent(NULL, fbdev->fb_len, fbdev->fb_mem, fbdev->dma_handle); | ||
| 730 | free_dma(CH_PPI); | ||
| 731 | free_irq(IRQ_PPI_ERROR, fbdev); | ||
| 732 | unregister_framebuffer(&fbdev->info); | ||
| 733 | remove_proc_entry("driver/adv7393", NULL); | ||
| 734 | fb_dealloc_cmap(&fbdev->info.cmap); | ||
| 735 | kfree(fbdev->info.pseudo_palette); | ||
| 736 | |||
| 737 | if (ANOMALY_05000400) | ||
| 738 | gpio_free(P_IDENT(P_PPI0_FS3)); /* FS3 */ | ||
| 739 | peripheral_free_list(ppi_pins); | ||
| 740 | kfree(fbdev); | ||
| 741 | |||
| 742 | return 0; | ||
| 743 | } | ||
| 744 | |||
| 745 | #ifdef CONFIG_PM | ||
| 746 | static int bfin_adv7393_fb_suspend(struct device *dev) | ||
| 747 | { | ||
| 748 | struct adv7393fb_device *fbdev = dev_get_drvdata(dev); | ||
| 749 | |||
| 750 | if (fbdev->open) { | ||
| 751 | bfin_disable_dma(); | ||
| 752 | bfin_disable_ppi(); | ||
| 753 | dma_desc_list(fbdev, DESTRUCT); | ||
| 754 | } | ||
| 755 | adv7393_mode(fbdev->client, POWER_DOWN); | ||
| 756 | |||
| 757 | return 0; | ||
| 758 | } | ||
| 759 | |||
| 760 | static int bfin_adv7393_fb_resume(struct device *dev) | ||
| 761 | { | ||
| 762 | struct adv7393fb_device *fbdev = dev_get_drvdata(dev); | ||
| 763 | |||
| 764 | adv7393_mode(fbdev->client, POWER_ON); | ||
| 765 | |||
| 766 | if (fbdev->open) { | ||
| 767 | dma_desc_list(fbdev, BUILD); | ||
| 768 | bfin_config_ppi(fbdev); | ||
| 769 | bfin_config_dma(fbdev); | ||
| 770 | bfin_enable_ppi(); | ||
| 771 | } | ||
| 772 | |||
| 773 | return 0; | ||
| 774 | } | ||
| 775 | |||
| 776 | static const struct dev_pm_ops bfin_adv7393_dev_pm_ops = { | ||
| 777 | .suspend = bfin_adv7393_fb_suspend, | ||
| 778 | .resume = bfin_adv7393_fb_resume, | ||
| 779 | }; | ||
| 780 | #endif | ||
| 781 | |||
| 782 | static const struct i2c_device_id bfin_adv7393_id[] = { | ||
| 783 | {DRIVER_NAME, 0}, | ||
| 784 | {} | ||
| 785 | }; | ||
| 786 | |||
| 787 | MODULE_DEVICE_TABLE(i2c, bfin_adv7393_id); | ||
| 788 | |||
| 789 | static struct i2c_driver bfin_adv7393_fb_driver = { | ||
| 790 | .driver = { | ||
| 791 | .name = DRIVER_NAME, | ||
| 792 | #ifdef CONFIG_PM | ||
| 793 | .pm = &bfin_adv7393_dev_pm_ops, | ||
| 794 | #endif | ||
| 795 | }, | ||
| 796 | .probe = bfin_adv7393_fb_probe, | ||
| 797 | .remove = __devexit_p(bfin_adv7393_fb_remove), | ||
| 798 | .id_table = bfin_adv7393_id, | ||
| 799 | }; | ||
| 800 | |||
| 801 | static int __init bfin_adv7393_fb_driver_init(void) | ||
| 802 | { | ||
| 803 | #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) | ||
| 804 | request_module("i2c-bfin-twi"); | ||
| 805 | #else | ||
| 806 | request_module("i2c-gpio"); | ||
| 807 | #endif | ||
| 808 | |||
| 809 | return i2c_add_driver(&bfin_adv7393_fb_driver); | ||
| 810 | } | ||
| 811 | module_init(bfin_adv7393_fb_driver_init); | ||
| 812 | |||
| 813 | static void __exit bfin_adv7393_fb_driver_cleanup(void) | ||
| 814 | { | ||
| 815 | i2c_del_driver(&bfin_adv7393_fb_driver); | ||
| 816 | } | ||
| 817 | module_exit(bfin_adv7393_fb_driver_cleanup); | ||
| 818 | |||
| 819 | MODULE_LICENSE("GPL"); | ||
| 820 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
| 821 | MODULE_DESCRIPTION("Frame buffer driver for ADV7393/2 Video Encoder"); | ||
| 822 | |||
| 823 | module_param(mode, int, 0); | ||
| 824 | MODULE_PARM_DESC(mode, | ||
| 825 | "Video Mode (0=NTSC,1=PAL,2=NTSC 640x480,3=PAL 640x480,4=NTSC YCbCr input,5=PAL YCbCr input)"); | ||
| 826 | |||
| 827 | module_param(mem, int, 0); | ||
| 828 | MODULE_PARM_DESC(mem, | ||
| 829 | "Size of frame buffer memory 1=Single 2=Double Size (allows y-panning / frame stacking)"); | ||
| 830 | |||
| 831 | module_param(nocursor, int, 0644); | ||
| 832 | MODULE_PARM_DESC(nocursor, "cursor enable/disable"); | ||
diff --git a/drivers/video/bfin_adv7393fb.h b/drivers/video/bfin_adv7393fb.h new file mode 100644 index 000000000000..8c7f9e4fc6eb --- /dev/null +++ b/drivers/video/bfin_adv7393fb.h | |||
| @@ -0,0 +1,321 @@ | |||
| 1 | /* | ||
| 2 | * Frame buffer driver for ADV7393/2 video encoder | ||
| 3 | * | ||
| 4 | * Copyright 2006-2009 Analog Devices Inc. | ||
| 5 | * Licensed under the GPL-2 or late. | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef __BFIN_ADV7393FB_H__ | ||
| 9 | #define __BFIN_ADV7393FB_H__ | ||
| 10 | |||
| 11 | #define BFIN_LCD_NBR_PALETTE_ENTRIES 256 | ||
| 12 | |||
| 13 | #ifdef CONFIG_NTSC | ||
| 14 | # define VMODE 0 | ||
| 15 | #endif | ||
| 16 | #ifdef CONFIG_PAL | ||
| 17 | # define VMODE 1 | ||
| 18 | #endif | ||
| 19 | #ifdef CONFIG_NTSC_640x480 | ||
| 20 | # define VMODE 2 | ||
| 21 | #endif | ||
| 22 | #ifdef CONFIG_PAL_640x480 | ||
| 23 | # define VMODE 3 | ||
| 24 | #endif | ||
| 25 | #ifdef CONFIG_NTSC_YCBCR | ||
| 26 | # define VMODE 4 | ||
| 27 | #endif | ||
| 28 | #ifdef CONFIG_PAL_YCBCR | ||
| 29 | # define VMODE 5 | ||
| 30 | #endif | ||
| 31 | |||
| 32 | #ifndef VMODE | ||
| 33 | # define VMODE 1 | ||
| 34 | #endif | ||
| 35 | |||
| 36 | #ifdef CONFIG_ADV7393_2XMEM | ||
| 37 | # define VMEM 2 | ||
| 38 | #else | ||
| 39 | # define VMEM 1 | ||
| 40 | #endif | ||
| 41 | |||
| 42 | #if defined(CONFIG_BF537) || defined(CONFIG_BF536) || defined(CONFIG_BF534) | ||
| 43 | # define DMA_CFG_VAL 0x7935 /* Set Sync Bit */ | ||
| 44 | # define VB_DUMMY_MEMORY_SOURCE L1_DATA_B_START | ||
| 45 | #else | ||
| 46 | # define DMA_CFG_VAL 0x7915 | ||
| 47 | # define VB_DUMMY_MEMORY_SOURCE BOOT_ROM_START | ||
| 48 | #endif | ||
| 49 | |||
| 50 | enum { | ||
| 51 | DESTRUCT, | ||
| 52 | BUILD, | ||
| 53 | }; | ||
| 54 | |||
| 55 | enum { | ||
| 56 | POWER_ON, | ||
| 57 | POWER_DOWN, | ||
| 58 | BLANK_ON, | ||
| 59 | BLANK_OFF, | ||
| 60 | }; | ||
| 61 | |||
| 62 | #define DRIVER_NAME "bfin-adv7393" | ||
| 63 | |||
| 64 | struct adv7393fb_modes { | ||
| 65 | const s8 name[25]; /* Full name */ | ||
| 66 | u16 xres; /* Active Horizonzal Pixels */ | ||
| 67 | u16 yres; /* Active Vertical Pixels */ | ||
| 68 | u16 bpp; | ||
| 69 | u16 vmode; | ||
| 70 | u16 a_lines; /* Active Lines per Field */ | ||
| 71 | u16 vb1_lines; /* Vertical Blanking Field 1 Lines */ | ||
| 72 | u16 vb2_lines; /* Vertical Blanking Field 2 Lines */ | ||
| 73 | u16 tot_lines; /* Total Lines per Frame */ | ||
| 74 | u16 boeft_blank; /* Before Odd/Even Field Transition No. of Blank Pixels */ | ||
| 75 | u16 aoeft_blank; /* After Odd/Even Field Transition No. of Blank Pixels */ | ||
| 76 | const s8 *adv7393_i2c_initd; | ||
| 77 | u16 adv7393_i2c_initd_len; | ||
| 78 | }; | ||
| 79 | |||
| 80 | static const u8 init_NTSC_TESTPATTERN[] = { | ||
| 81 | 0x00, 0x1E, /* Power up all DACs and PLL */ | ||
| 82 | 0x01, 0x00, /* SD-Only Mode */ | ||
| 83 | 0x80, 0x10, /* SSAF Luma Filter Enabled, NTSC Mode */ | ||
| 84 | 0x82, 0xCB, /* Step control on, pixel data valid, pedestal on, PrPb SSAF on, CVBS/YC output */ | ||
| 85 | 0x84, 0x40, /* SD Color Bar Test Pattern Enabled, DAC 2 = Luma, DAC 3 = Chroma */ | ||
| 86 | }; | ||
| 87 | |||
| 88 | static const u8 init_NTSC[] = { | ||
| 89 | 0x00, 0x1E, /* Power up all DACs and PLL */ | ||
| 90 | 0xC3, 0x26, /* Program RGB->YCrCb Color Space convertion matrix */ | ||
| 91 | 0xC5, 0x12, /* Program RGB->YCrCb Color Space convertion matrix */ | ||
| 92 | 0xC2, 0x4A, /* Program RGB->YCrCb Color Space convertion matrix */ | ||
| 93 | 0xC6, 0x5E, /* Program RGB->YCrCb Color Space convertion matrix */ | ||
| 94 | 0xBD, 0x19, /* Program RGB->YCrCb Color Space convertion matrix */ | ||
| 95 | 0xBF, 0x42, /* Program RGB->YCrCb Color Space convertion matrix */ | ||
| 96 | 0x8C, 0x1F, /* NTSC Subcarrier Frequency */ | ||
| 97 | 0x8D, 0x7C, /* NTSC Subcarrier Frequency */ | ||
| 98 | 0x8E, 0xF0, /* NTSC Subcarrier Frequency */ | ||
| 99 | 0x8F, 0x21, /* NTSC Subcarrier Frequency */ | ||
| 100 | 0x01, 0x00, /* SD-Only Mode */ | ||
| 101 | 0x80, 0x30, /* SSAF Luma Filter Enabled, NTSC Mode */ | ||
| 102 | 0x82, 0x8B, /* Step control on, pixel data invalid, pedestal on, PrPb SSAF on, CVBS/YC output */ | ||
| 103 | 0x87, 0x80, /* SD Color Bar Test Pattern Enabled, DAC 2 = Luma, DAC 3 = Chroma */ | ||
| 104 | 0x86, 0x82, | ||
| 105 | 0x8B, 0x11, | ||
| 106 | 0x88, 0x20, | ||
| 107 | 0x8A, 0x0d, | ||
| 108 | }; | ||
| 109 | |||
| 110 | static const u8 init_PAL[] = { | ||
| 111 | 0x00, 0x1E, /* Power up all DACs and PLL */ | ||
| 112 | 0xC3, 0x26, /* Program RGB->YCrCb Color Space convertion matrix */ | ||
| 113 | 0xC5, 0x12, /* Program RGB->YCrCb Color Space convertion matrix */ | ||
| 114 | 0xC2, 0x4A, /* Program RGB->YCrCb Color Space convertion matrix */ | ||
| 115 | 0xC6, 0x5E, /* Program RGB->YCrCb Color Space convertion matrix */ | ||
| 116 | 0xBD, 0x19, /* Program RGB->YCrCb Color Space convertion matrix */ | ||
| 117 | 0xBF, 0x42, /* Program RGB->YCrCb Color Space convertion matrix */ | ||
| 118 | 0x8C, 0xCB, /* PAL Subcarrier Frequency */ | ||
| 119 | 0x8D, 0x8A, /* PAL Subcarrier Frequency */ | ||
| 120 | 0x8E, 0x09, /* PAL Subcarrier Frequency */ | ||
| 121 | 0x8F, 0x2A, /* PAL Subcarrier Frequency */ | ||
| 122 | 0x01, 0x00, /* SD-Only Mode */ | ||
| 123 | 0x80, 0x11, /* SSAF Luma Filter Enabled, PAL Mode */ | ||
| 124 | 0x82, 0x8B, /* Step control on, pixel data invalid, pedestal on, PrPb SSAF on, CVBS/YC output */ | ||
| 125 | 0x87, 0x80, /* SD Color Bar Test Pattern Enabled, DAC 2 = Luma, DAC 3 = Chroma */ | ||
| 126 | 0x86, 0x82, | ||
| 127 | 0x8B, 0x11, | ||
| 128 | 0x88, 0x20, | ||
| 129 | 0x8A, 0x0d, | ||
| 130 | }; | ||
| 131 | |||
| 132 | static const u8 init_NTSC_YCbCr[] = { | ||
| 133 | 0x00, 0x1E, /* Power up all DACs and PLL */ | ||
| 134 | 0x8C, 0x1F, /* NTSC Subcarrier Frequency */ | ||
| 135 | 0x8D, 0x7C, /* NTSC Subcarrier Frequency */ | ||
| 136 | 0x8E, 0xF0, /* NTSC Subcarrier Frequency */ | ||
| 137 | 0x8F, 0x21, /* NTSC Subcarrier Frequency */ | ||
| 138 | 0x01, 0x00, /* SD-Only Mode */ | ||
| 139 | 0x80, 0x30, /* SSAF Luma Filter Enabled, NTSC Mode */ | ||
| 140 | 0x82, 0x8B, /* Step control on, pixel data invalid, pedestal on, PrPb SSAF on, CVBS/YC output */ | ||
| 141 | 0x87, 0x00, /* DAC 2 = Luma, DAC 3 = Chroma */ | ||
| 142 | 0x86, 0x82, | ||
| 143 | 0x8B, 0x11, | ||
| 144 | 0x88, 0x08, | ||
| 145 | 0x8A, 0x0d, | ||
| 146 | }; | ||
| 147 | |||
| 148 | static const u8 init_PAL_YCbCr[] = { | ||
| 149 | 0x00, 0x1E, /* Power up all DACs and PLL */ | ||
| 150 | 0x8C, 0xCB, /* PAL Subcarrier Frequency */ | ||
| 151 | 0x8D, 0x8A, /* PAL Subcarrier Frequency */ | ||
| 152 | 0x8E, 0x09, /* PAL Subcarrier Frequency */ | ||
| 153 | 0x8F, 0x2A, /* PAL Subcarrier Frequency */ | ||
| 154 | 0x01, 0x00, /* SD-Only Mode */ | ||
| 155 | 0x80, 0x11, /* SSAF Luma Filter Enabled, PAL Mode */ | ||
| 156 | 0x82, 0x8B, /* Step control on, pixel data invalid, pedestal on, PrPb SSAF on, CVBS/YC output */ | ||
| 157 | 0x87, 0x00, /* DAC 2 = Luma, DAC 3 = Chroma */ | ||
| 158 | 0x86, 0x82, | ||
| 159 | 0x8B, 0x11, | ||
| 160 | 0x88, 0x08, | ||
| 161 | 0x8A, 0x0d, | ||
| 162 | }; | ||
| 163 | |||
| 164 | static struct adv7393fb_modes known_modes[] = { | ||
| 165 | /* NTSC 720x480 CRT */ | ||
| 166 | { | ||
| 167 | .name = "NTSC 720x480", | ||
| 168 | .xres = 720, | ||
| 169 | .yres = 480, | ||
| 170 | .bpp = 16, | ||
| 171 | .vmode = FB_VMODE_INTERLACED, | ||
| 172 | .a_lines = 240, | ||
| 173 | .vb1_lines = 22, | ||
| 174 | .vb2_lines = 23, | ||
| 175 | .tot_lines = 525, | ||
| 176 | .boeft_blank = 16, | ||
| 177 | .aoeft_blank = 122, | ||
| 178 | .adv7393_i2c_initd = init_NTSC, | ||
| 179 | .adv7393_i2c_initd_len = sizeof(init_NTSC) | ||
| 180 | }, | ||
| 181 | /* PAL 720x480 CRT */ | ||
| 182 | { | ||
| 183 | .name = "PAL 720x576", | ||
| 184 | .xres = 720, | ||
| 185 | .yres = 576, | ||
| 186 | .bpp = 16, | ||
| 187 | .vmode = FB_VMODE_INTERLACED, | ||
| 188 | .a_lines = 288, | ||
| 189 | .vb1_lines = 24, | ||
| 190 | .vb2_lines = 25, | ||
| 191 | .tot_lines = 625, | ||
| 192 | .boeft_blank = 12, | ||
| 193 | .aoeft_blank = 132, | ||
| 194 | .adv7393_i2c_initd = init_PAL, | ||
| 195 | .adv7393_i2c_initd_len = sizeof(init_PAL) | ||
| 196 | }, | ||
| 197 | /* NTSC 640x480 CRT Experimental */ | ||
| 198 | { | ||
| 199 | .name = "NTSC 640x480", | ||
| 200 | .xres = 640, | ||
| 201 | .yres = 480, | ||
| 202 | .bpp = 16, | ||
| 203 | .vmode = FB_VMODE_INTERLACED, | ||
| 204 | .a_lines = 240, | ||
| 205 | .vb1_lines = 22, | ||
| 206 | .vb2_lines = 23, | ||
| 207 | .tot_lines = 525, | ||
| 208 | .boeft_blank = 16 + 40, | ||
| 209 | .aoeft_blank = 122 + 40, | ||
| 210 | .adv7393_i2c_initd = init_NTSC, | ||
| 211 | .adv7393_i2c_initd_len = sizeof(init_NTSC) | ||
| 212 | }, | ||
| 213 | /* PAL 640x480 CRT Experimental */ | ||
| 214 | { | ||
| 215 | .name = "PAL 640x480", | ||
| 216 | .xres = 640, | ||
| 217 | .yres = 480, | ||
| 218 | .bpp = 16, | ||
| 219 | .vmode = FB_VMODE_INTERLACED, | ||
| 220 | .a_lines = 288 - 20, | ||
| 221 | .vb1_lines = 24 + 20, | ||
| 222 | .vb2_lines = 25 + 20, | ||
| 223 | .tot_lines = 625, | ||
| 224 | .boeft_blank = 12 + 40, | ||
| 225 | .aoeft_blank = 132 + 40, | ||
| 226 | .adv7393_i2c_initd = init_PAL, | ||
| 227 | .adv7393_i2c_initd_len = sizeof(init_PAL) | ||
| 228 | }, | ||
| 229 | /* NTSC 720x480 YCbCR */ | ||
| 230 | { | ||
| 231 | .name = "NTSC 720x480 YCbCR", | ||
| 232 | .xres = 720, | ||
| 233 | .yres = 480, | ||
| 234 | .bpp = 16, | ||
| 235 | .vmode = FB_VMODE_INTERLACED, | ||
| 236 | .a_lines = 240, | ||
| 237 | .vb1_lines = 22, | ||
| 238 | .vb2_lines = 23, | ||
| 239 | .tot_lines = 525, | ||
| 240 | .boeft_blank = 16, | ||
| 241 | .aoeft_blank = 122, | ||
| 242 | .adv7393_i2c_initd = init_NTSC_YCbCr, | ||
| 243 | .adv7393_i2c_initd_len = sizeof(init_NTSC_YCbCr) | ||
| 244 | }, | ||
| 245 | /* PAL 720x480 CRT */ | ||
| 246 | { | ||
| 247 | .name = "PAL 720x576 YCbCR", | ||
| 248 | .xres = 720, | ||
| 249 | .yres = 576, | ||
| 250 | .bpp = 16, | ||
| 251 | .vmode = FB_VMODE_INTERLACED, | ||
| 252 | .a_lines = 288, | ||
| 253 | .vb1_lines = 24, | ||
| 254 | .vb2_lines = 25, | ||
| 255 | .tot_lines = 625, | ||
| 256 | .boeft_blank = 12, | ||
| 257 | .aoeft_blank = 132, | ||
| 258 | .adv7393_i2c_initd = init_PAL_YCbCr, | ||
| 259 | .adv7393_i2c_initd_len = sizeof(init_PAL_YCbCr) | ||
| 260 | } | ||
| 261 | }; | ||
| 262 | |||
| 263 | struct adv7393fb_regs { | ||
| 264 | |||
| 265 | }; | ||
| 266 | |||
| 267 | struct adv7393fb_device { | ||
| 268 | struct fb_info info; /* FB driver info record */ | ||
| 269 | |||
| 270 | struct i2c_client *client; | ||
| 271 | |||
| 272 | struct dmasg *descriptor_list_head; | ||
| 273 | struct dmasg *vb1; | ||
| 274 | struct dmasg *av1; | ||
| 275 | struct dmasg *vb2; | ||
| 276 | struct dmasg *av2; | ||
| 277 | |||
| 278 | dma_addr_t dma_handle; | ||
| 279 | |||
| 280 | struct fb_info bfin_adv7393_fb; | ||
| 281 | |||
| 282 | struct adv7393fb_modes *modes; | ||
| 283 | |||
| 284 | struct adv7393fb_regs *regs; /* Registers memory map */ | ||
| 285 | size_t regs_len; | ||
| 286 | size_t fb_len; | ||
| 287 | size_t line_len; | ||
| 288 | u16 open; | ||
| 289 | u16 *fb_mem; /* RGB Buffer */ | ||
| 290 | |||
| 291 | }; | ||
| 292 | |||
| 293 | #define to_adv7393fb_device(_info) \ | ||
| 294 | (_info ? container_of(_info, struct adv7393fb_device, info) : NULL); | ||
| 295 | |||
| 296 | static int bfin_adv7393_fb_open(struct fb_info *info, int user); | ||
| 297 | static int bfin_adv7393_fb_release(struct fb_info *info, int user); | ||
| 298 | static int bfin_adv7393_fb_check_var(struct fb_var_screeninfo *var, | ||
| 299 | struct fb_info *info); | ||
| 300 | |||
| 301 | static int bfin_adv7393_fb_pan_display(struct fb_var_screeninfo *var, | ||
| 302 | struct fb_info *info); | ||
| 303 | |||
| 304 | static int bfin_adv7393_fb_blank(int blank, struct fb_info *info); | ||
| 305 | |||
| 306 | static void bfin_config_ppi(struct adv7393fb_device *fbdev); | ||
| 307 | static int bfin_config_dma(struct adv7393fb_device *fbdev); | ||
| 308 | static void bfin_disable_dma(void); | ||
| 309 | static void bfin_enable_ppi(void); | ||
| 310 | static void bfin_disable_ppi(void); | ||
| 311 | |||
| 312 | static inline int adv7393_write(struct i2c_client *client, u8 reg, u8 value); | ||
| 313 | static inline int adv7393_read(struct i2c_client *client, u8 reg); | ||
| 314 | static int adv7393_write_block(struct i2c_client *client, const u8 *data, | ||
| 315 | unsigned int len); | ||
| 316 | |||
| 317 | int bfin_adv7393_fb_cursor(struct fb_info *info, struct fb_cursor *cursor); | ||
| 318 | static int bfin_adv7393_fb_setcolreg(u_int, u_int, u_int, u_int, | ||
| 319 | u_int, struct fb_info *info); | ||
| 320 | |||
| 321 | #endif | ||
diff --git a/drivers/video/carminefb.c b/drivers/video/carminefb.c index 6b19136aa181..caaa27d4a46a 100644 --- a/drivers/video/carminefb.c +++ b/drivers/video/carminefb.c | |||
| @@ -654,7 +654,7 @@ static int __devinit carminefb_probe(struct pci_dev *dev, | |||
| 654 | printk(KERN_ERR "carminefb: Memory bar is only %d bytes, %d " | 654 | printk(KERN_ERR "carminefb: Memory bar is only %d bytes, %d " |
| 655 | "are required.", carminefb_fix.smem_len, | 655 | "are required.", carminefb_fix.smem_len, |
| 656 | CARMINE_TOTAL_DIPLAY_MEM); | 656 | CARMINE_TOTAL_DIPLAY_MEM); |
| 657 | goto err_free_reg_mmio; | 657 | goto err_unmap_vregs; |
| 658 | } | 658 | } |
| 659 | 659 | ||
| 660 | if (!request_mem_region(carminefb_fix.smem_start, | 660 | if (!request_mem_region(carminefb_fix.smem_start, |
| @@ -667,8 +667,6 @@ static int __devinit carminefb_probe(struct pci_dev *dev, | |||
| 667 | carminefb_fix.smem_len); | 667 | carminefb_fix.smem_len); |
| 668 | if (!hw->screen_mem) { | 668 | if (!hw->screen_mem) { |
| 669 | printk(KERN_ERR "carmine: Can't ioremap smem area.\n"); | 669 | printk(KERN_ERR "carmine: Can't ioremap smem area.\n"); |
| 670 | release_mem_region(carminefb_fix.smem_start, | ||
| 671 | carminefb_fix.smem_len); | ||
| 672 | goto err_reg_smem; | 670 | goto err_reg_smem; |
| 673 | } | 671 | } |
| 674 | 672 | ||
| @@ -710,7 +708,7 @@ err_deinit_hw: | |||
| 710 | err_unmap_screen: | 708 | err_unmap_screen: |
| 711 | iounmap(hw->screen_mem); | 709 | iounmap(hw->screen_mem); |
| 712 | err_reg_smem: | 710 | err_reg_smem: |
| 713 | release_mem_region(carminefb_fix.mmio_start, carminefb_fix.mmio_len); | 711 | release_mem_region(carminefb_fix.smem_start, carminefb_fix.smem_len); |
| 714 | err_unmap_vregs: | 712 | err_unmap_vregs: |
| 715 | iounmap(hw->v_regs); | 713 | iounmap(hw->v_regs); |
| 716 | err_free_reg_mmio: | 714 | err_free_reg_mmio: |
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 563a98b88e9b..4f57485f8c54 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c | |||
| @@ -973,6 +973,90 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) | |||
| 973 | DPRINTK("========================================\n"); | 973 | DPRINTK("========================================\n"); |
| 974 | } | 974 | } |
| 975 | 975 | ||
| 976 | /** | ||
| 977 | * fb_edid_add_monspecs() - add monitor video modes from E-EDID data | ||
| 978 | * @edid: 128 byte array with an E-EDID block | ||
| 979 | * @spacs: monitor specs to be extended | ||
| 980 | */ | ||
| 981 | void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) | ||
| 982 | { | ||
| 983 | unsigned char *block; | ||
| 984 | struct fb_videomode *m; | ||
| 985 | int num = 0, i; | ||
| 986 | u8 svd[64], edt[(128 - 4) / DETAILED_TIMING_DESCRIPTION_SIZE]; | ||
| 987 | u8 pos = 4, svd_n = 0; | ||
| 988 | |||
| 989 | if (!edid) | ||
| 990 | return; | ||
| 991 | |||
| 992 | if (!edid_checksum(edid)) | ||
| 993 | return; | ||
| 994 | |||
| 995 | if (edid[0] != 0x2 || | ||
| 996 | edid[2] < 4 || edid[2] > 128 - DETAILED_TIMING_DESCRIPTION_SIZE) | ||
| 997 | return; | ||
| 998 | |||
| 999 | DPRINTK(" Short Video Descriptors\n"); | ||
| 1000 | |||
| 1001 | while (pos < edid[2]) { | ||
| 1002 | u8 len = edid[pos] & 0x1f, type = (edid[pos] >> 5) & 7; | ||
| 1003 | pr_debug("Data block %u of %u bytes\n", type, len); | ||
| 1004 | if (type == 2) | ||
| 1005 | for (i = pos; i < pos + len; i++) { | ||
| 1006 | u8 idx = edid[pos + i] & 0x7f; | ||
| 1007 | svd[svd_n++] = idx; | ||
| 1008 | pr_debug("N%sative mode #%d\n", | ||
| 1009 | edid[pos + i] & 0x80 ? "" : "on-n", idx); | ||
| 1010 | } | ||
| 1011 | pos += len + 1; | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | block = edid + edid[2]; | ||
| 1015 | |||
| 1016 | DPRINTK(" Extended Detailed Timings\n"); | ||
| 1017 | |||
| 1018 | for (i = 0; i < (128 - edid[2]) / DETAILED_TIMING_DESCRIPTION_SIZE; | ||
| 1019 | i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) | ||
| 1020 | if (PIXEL_CLOCK) | ||
| 1021 | edt[num++] = block - edid; | ||
| 1022 | |||
| 1023 | /* Yikes, EDID data is totally useless */ | ||
| 1024 | if (!(num + svd_n)) | ||
| 1025 | return; | ||
| 1026 | |||
| 1027 | m = kzalloc((specs->modedb_len + num + svd_n) * | ||
| 1028 | sizeof(struct fb_videomode), GFP_KERNEL); | ||
| 1029 | |||
| 1030 | if (!m) | ||
| 1031 | return; | ||
| 1032 | |||
| 1033 | memcpy(m, specs->modedb, specs->modedb_len * sizeof(struct fb_videomode)); | ||
| 1034 | |||
| 1035 | for (i = specs->modedb_len; i < specs->modedb_len + num; i++) { | ||
| 1036 | get_detailed_timing(edid + edt[i - specs->modedb_len], &m[i]); | ||
| 1037 | if (i == specs->modedb_len) | ||
| 1038 | m[i].flag |= FB_MODE_IS_FIRST; | ||
| 1039 | pr_debug("Adding %ux%u@%u\n", m[i].xres, m[i].yres, m[i].refresh); | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | for (i = specs->modedb_len + num; i < specs->modedb_len + num + svd_n; i++) { | ||
| 1043 | int idx = svd[i - specs->modedb_len - num]; | ||
| 1044 | if (!idx || idx > 63) { | ||
| 1045 | pr_warning("Reserved SVD code %d\n", idx); | ||
| 1046 | } else if (idx > ARRAY_SIZE(cea_modes) || !cea_modes[idx].xres) { | ||
| 1047 | pr_warning("Unimplemented SVD code %d\n", idx); | ||
| 1048 | } else { | ||
| 1049 | memcpy(&m[i], cea_modes + idx, sizeof(m[i])); | ||
| 1050 | pr_debug("Adding SVD #%d: %ux%u@%u\n", idx, | ||
| 1051 | m[i].xres, m[i].yres, m[i].refresh); | ||
| 1052 | } | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | kfree(specs->modedb); | ||
| 1056 | specs->modedb = m; | ||
| 1057 | specs->modedb_len = specs->modedb_len + num + svd_n; | ||
| 1058 | } | ||
| 1059 | |||
| 976 | /* | 1060 | /* |
| 977 | * VESA Generalized Timing Formula (GTF) | 1061 | * VESA Generalized Timing Formula (GTF) |
| 978 | */ | 1062 | */ |
| @@ -1289,6 +1373,9 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) | |||
| 1289 | { | 1373 | { |
| 1290 | specs = NULL; | 1374 | specs = NULL; |
| 1291 | } | 1375 | } |
| 1376 | void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) | ||
| 1377 | { | ||
| 1378 | } | ||
| 1292 | void fb_destroy_modedb(struct fb_videomode *modedb) | 1379 | void fb_destroy_modedb(struct fb_videomode *modedb) |
| 1293 | { | 1380 | { |
| 1294 | } | 1381 | } |
| @@ -1396,6 +1483,7 @@ EXPORT_SYMBOL(fb_firmware_edid); | |||
| 1396 | 1483 | ||
| 1397 | EXPORT_SYMBOL(fb_parse_edid); | 1484 | EXPORT_SYMBOL(fb_parse_edid); |
| 1398 | EXPORT_SYMBOL(fb_edid_to_monspecs); | 1485 | EXPORT_SYMBOL(fb_edid_to_monspecs); |
| 1486 | EXPORT_SYMBOL(fb_edid_add_monspecs); | ||
| 1399 | EXPORT_SYMBOL(fb_get_mode); | 1487 | EXPORT_SYMBOL(fb_get_mode); |
| 1400 | EXPORT_SYMBOL(fb_validate_mode); | 1488 | EXPORT_SYMBOL(fb_validate_mode); |
| 1401 | EXPORT_SYMBOL(fb_destroy_modedb); | 1489 | EXPORT_SYMBOL(fb_destroy_modedb); |
diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c index af8f0f2cc782..4052718eefaa 100644 --- a/drivers/video/hgafb.c +++ b/drivers/video/hgafb.c | |||
| @@ -454,7 +454,6 @@ static int hgafb_blank(int blank_mode, struct fb_info *info) | |||
| 454 | /* | 454 | /* |
| 455 | * Accel functions | 455 | * Accel functions |
| 456 | */ | 456 | */ |
| 457 | #ifdef CONFIG_FB_HGA_ACCEL | ||
| 458 | static void hgafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 457 | static void hgafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) |
| 459 | { | 458 | { |
| 460 | u_int rows, y; | 459 | u_int rows, y; |
| @@ -466,7 +465,7 @@ static void hgafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
| 466 | dest = rowaddr(info, y) + (rect->dx >> 3); | 465 | dest = rowaddr(info, y) + (rect->dx >> 3); |
| 467 | switch (rect->rop) { | 466 | switch (rect->rop) { |
| 468 | case ROP_COPY: | 467 | case ROP_COPY: |
| 469 | //fb_memset(dest, rect->color, (rect->width >> 3)); | 468 | memset_io(dest, rect->color, (rect->width >> 3)); |
| 470 | break; | 469 | break; |
| 471 | case ROP_XOR: | 470 | case ROP_XOR: |
| 472 | fb_writeb(~(fb_readb(dest)), dest); | 471 | fb_writeb(~(fb_readb(dest)), dest); |
| @@ -488,7 +487,7 @@ static void hgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | |||
| 488 | for (rows = area->height; rows--; ) { | 487 | for (rows = area->height; rows--; ) { |
| 489 | src = rowaddr(info, y1) + (area->sx >> 3); | 488 | src = rowaddr(info, y1) + (area->sx >> 3); |
| 490 | dest = rowaddr(info, y2) + (area->dx >> 3); | 489 | dest = rowaddr(info, y2) + (area->dx >> 3); |
| 491 | //fb_memmove(dest, src, (area->width >> 3)); | 490 | memmove(dest, src, (area->width >> 3)); |
| 492 | y1++; | 491 | y1++; |
| 493 | y2++; | 492 | y2++; |
| 494 | } | 493 | } |
| @@ -499,7 +498,7 @@ static void hgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | |||
| 499 | for (rows = area->height; rows--;) { | 498 | for (rows = area->height; rows--;) { |
| 500 | src = rowaddr(info, y1) + (area->sx >> 3); | 499 | src = rowaddr(info, y1) + (area->sx >> 3); |
| 501 | dest = rowaddr(info, y2) + (area->dx >> 3); | 500 | dest = rowaddr(info, y2) + (area->dx >> 3); |
| 502 | //fb_memmove(dest, src, (area->width >> 3)); | 501 | memmove(dest, src, (area->width >> 3)); |
| 503 | y1--; | 502 | y1--; |
| 504 | y2--; | 503 | y2--; |
| 505 | } | 504 | } |
| @@ -511,20 +510,17 @@ static void hgafb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
| 511 | u8 __iomem *dest; | 510 | u8 __iomem *dest; |
| 512 | u8 *cdat = (u8 *) image->data; | 511 | u8 *cdat = (u8 *) image->data; |
| 513 | u_int rows, y = image->dy; | 512 | u_int rows, y = image->dy; |
| 513 | u_int x; | ||
| 514 | u8 d; | 514 | u8 d; |
| 515 | 515 | ||
| 516 | for (rows = image->height; rows--; y++) { | 516 | for (rows = image->height; rows--; y++) { |
| 517 | d = *cdat++; | 517 | for (x = 0; x < image->width; x+= 8) { |
| 518 | dest = rowaddr(info, y) + (image->dx >> 3); | 518 | d = *cdat++; |
| 519 | fb_writeb(d, dest); | 519 | dest = rowaddr(info, y) + ((image->dx + x)>> 3); |
| 520 | fb_writeb(d, dest); | ||
| 521 | } | ||
| 520 | } | 522 | } |
| 521 | } | 523 | } |
| 522 | #else /* !CONFIG_FB_HGA_ACCEL */ | ||
| 523 | #define hgafb_fillrect cfb_fillrect | ||
| 524 | #define hgafb_copyarea cfb_copyarea | ||
| 525 | #define hgafb_imageblit cfb_imageblit | ||
| 526 | #endif /* CONFIG_FB_HGA_ACCEL */ | ||
| 527 | |||
| 528 | 524 | ||
| 529 | static struct fb_ops hgafb_ops = { | 525 | static struct fb_ops hgafb_ops = { |
| 530 | .owner = THIS_MODULE, | 526 | .owner = THIS_MODULE, |
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c index cd2c728a809b..7db17d0d8a8c 100644 --- a/drivers/video/i810/i810-i2c.c +++ b/drivers/video/i810/i810-i2c.c | |||
| @@ -45,8 +45,10 @@ static void i810i2c_setscl(void *data, int state) | |||
| 45 | struct i810fb_par *par = chan->par; | 45 | struct i810fb_par *par = chan->par; |
| 46 | u8 __iomem *mmio = par->mmio_start_virtual; | 46 | u8 __iomem *mmio = par->mmio_start_virtual; |
| 47 | 47 | ||
| 48 | i810_writel(mmio, chan->ddc_base, (state ? SCL_VAL_OUT : 0) | SCL_DIR | | 48 | if (state) |
| 49 | SCL_DIR_MASK | SCL_VAL_MASK); | 49 | i810_writel(mmio, chan->ddc_base, SCL_DIR_MASK | SCL_VAL_MASK); |
| 50 | else | ||
| 51 | i810_writel(mmio, chan->ddc_base, SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK); | ||
| 50 | i810_readl(mmio, chan->ddc_base); /* flush posted write */ | 52 | i810_readl(mmio, chan->ddc_base); /* flush posted write */ |
| 51 | } | 53 | } |
| 52 | 54 | ||
| @@ -56,8 +58,10 @@ static void i810i2c_setsda(void *data, int state) | |||
| 56 | struct i810fb_par *par = chan->par; | 58 | struct i810fb_par *par = chan->par; |
| 57 | u8 __iomem *mmio = par->mmio_start_virtual; | 59 | u8 __iomem *mmio = par->mmio_start_virtual; |
| 58 | 60 | ||
| 59 | i810_writel(mmio, chan->ddc_base, (state ? SDA_VAL_OUT : 0) | SDA_DIR | | 61 | if (state) |
| 60 | SDA_DIR_MASK | SDA_VAL_MASK); | 62 | i810_writel(mmio, chan->ddc_base, SDA_DIR_MASK | SDA_VAL_MASK); |
| 63 | else | ||
| 64 | i810_writel(mmio, chan->ddc_base, SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK); | ||
| 61 | i810_readl(mmio, chan->ddc_base); /* flush posted write */ | 65 | i810_readl(mmio, chan->ddc_base); /* flush posted write */ |
| 62 | } | 66 | } |
| 63 | 67 | ||
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index de450c1fb869..d2bb365f09b3 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
| @@ -274,10 +274,61 @@ static const struct fb_videomode modedb[] = { | |||
| 274 | /* 800x520i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */ | 274 | /* 800x520i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */ |
| 275 | NULL, 50, 800, 520, 58823, 144, 64, 72, 28, 80, 5, | 275 | NULL, 50, 800, 520, 58823, 144, 64, 72, 28, 80, 5, |
| 276 | 0, FB_VMODE_INTERLACED | 276 | 0, FB_VMODE_INTERLACED |
| 277 | }, { | ||
| 278 | /* 864x480 @ 60 Hz, 35.15 kHz hsync */ | ||
| 279 | NULL, 60, 864, 480, 27777, 1, 1, 1, 1, 0, 0, | ||
| 280 | 0, FB_VMODE_NONINTERLACED | ||
| 277 | }, | 281 | }, |
| 278 | }; | 282 | }; |
| 279 | 283 | ||
| 280 | #ifdef CONFIG_FB_MODE_HELPERS | 284 | #ifdef CONFIG_FB_MODE_HELPERS |
| 285 | const struct fb_videomode cea_modes[64] = { | ||
| 286 | /* #1: 640x480p@59.94/60Hz */ | ||
| 287 | [1] = { | ||
| 288 | NULL, 60, 640, 480, 39722, 48, 16, 33, 10, 96, 2, 0, FB_VMODE_NONINTERLACED, 0, | ||
| 289 | }, | ||
| 290 | /* #3: 720x480p@59.94/60Hz */ | ||
| 291 | [3] = { | ||
| 292 | NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0, FB_VMODE_NONINTERLACED, 0, | ||
| 293 | }, | ||
| 294 | /* #5: 1920x1080i@59.94/60Hz */ | ||
| 295 | [5] = { | ||
| 296 | NULL, 60, 1920, 1080, 13763, 148, 88, 15, 2, 44, 5, | ||
| 297 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED, 0, | ||
| 298 | }, | ||
| 299 | /* #7: 720(1440)x480iH@59.94/60Hz */ | ||
| 300 | [7] = { | ||
| 301 | NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0, FB_VMODE_INTERLACED, 0, | ||
| 302 | }, | ||
| 303 | /* #9: 720(1440)x240pH@59.94/60Hz */ | ||
| 304 | [9] = { | ||
| 305 | NULL, 60, 1440, 240, 18554, 114, 38, 16, 4, 124, 3, 0, FB_VMODE_NONINTERLACED, 0, | ||
| 306 | }, | ||
| 307 | /* #18: 720x576pH@50Hz */ | ||
| 308 | [18] = { | ||
| 309 | NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0, FB_VMODE_NONINTERLACED, 0, | ||
| 310 | }, | ||
| 311 | /* #19: 1280x720p@50Hz */ | ||
| 312 | [19] = { | ||
| 313 | NULL, 50, 1280, 720, 13468, 220, 440, 20, 5, 40, 5, | ||
| 314 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0, | ||
| 315 | }, | ||
| 316 | /* #20: 1920x1080i@50Hz */ | ||
| 317 | [20] = { | ||
| 318 | NULL, 50, 1920, 1080, 13480, 148, 528, 15, 5, 528, 5, | ||
| 319 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED, 0, | ||
| 320 | }, | ||
| 321 | /* #32: 1920x1080p@23.98/24Hz */ | ||
| 322 | [32] = { | ||
| 323 | NULL, 24, 1920, 1080, 13468, 148, 638, 36, 4, 44, 5, | ||
| 324 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0, | ||
| 325 | }, | ||
| 326 | /* #35: (2880)x480p4x@59.94/60Hz */ | ||
| 327 | [35] = { | ||
| 328 | NULL, 60, 2880, 480, 9250, 240, 64, 30, 9, 248, 6, 0, FB_VMODE_NONINTERLACED, 0, | ||
| 329 | }, | ||
| 330 | }; | ||
| 331 | |||
| 281 | const struct fb_videomode vesa_modes[] = { | 332 | const struct fb_videomode vesa_modes[] = { |
| 282 | /* 0 640x350-85 VESA */ | 333 | /* 0 640x350-85 VESA */ |
| 283 | { NULL, 85, 640, 350, 31746, 96, 32, 60, 32, 64, 3, | 334 | { NULL, 85, 640, 350, 31746, 96, 32, 60, 32, 64, 3, |
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index ca0f6be9d12e..cb013919e9ce 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c | |||
| @@ -1474,8 +1474,7 @@ static int mx3fb_probe(struct platform_device *pdev) | |||
| 1474 | goto eremap; | 1474 | goto eremap; |
| 1475 | } | 1475 | } |
| 1476 | 1476 | ||
| 1477 | pr_debug("Remapped %x to %x at %p\n", sdc_reg->start, sdc_reg->end, | 1477 | pr_debug("Remapped %pR at %p\n", sdc_reg, mx3fb->reg_base); |
| 1478 | mx3fb->reg_base); | ||
| 1479 | 1478 | ||
| 1480 | /* IDMAC interface */ | 1479 | /* IDMAC interface */ |
| 1481 | dmaengine_get(); | 1480 | dmaengine_get(); |
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c index a6247fc081ab..28b1c6c3d8ac 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/s1d13xxxfb.c | |||
| @@ -410,28 +410,6 @@ s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | |||
| 410 | ************************************************************/ | 410 | ************************************************************/ |
| 411 | 411 | ||
| 412 | /** | 412 | /** |
| 413 | * bltbit_wait_bitset - waits for change in register value | ||
| 414 | * @info : framebuffer structure | ||
| 415 | * @bit : value expected in register | ||
| 416 | * @timeout : ... | ||
| 417 | * | ||
| 418 | * waits until value changes INTO bit | ||
| 419 | */ | ||
| 420 | static u8 | ||
| 421 | bltbit_wait_bitset(struct fb_info *info, u8 bit, int timeout) | ||
| 422 | { | ||
| 423 | while (!(s1d13xxxfb_readreg(info->par, S1DREG_BBLT_CTL0) & bit)) { | ||
| 424 | udelay(10); | ||
| 425 | if (!--timeout) { | ||
| 426 | dbg_blit("wait_bitset timeout\n"); | ||
| 427 | break; | ||
| 428 | } | ||
| 429 | } | ||
| 430 | |||
| 431 | return timeout; | ||
| 432 | } | ||
| 433 | |||
| 434 | /** | ||
| 435 | * bltbit_wait_bitclear - waits for change in register value | 413 | * bltbit_wait_bitclear - waits for change in register value |
| 436 | * @info : frambuffer structure | 414 | * @info : frambuffer structure |
| 437 | * @bit : value currently in register | 415 | * @bit : value currently in register |
| @@ -454,34 +432,6 @@ bltbit_wait_bitclear(struct fb_info *info, u8 bit, int timeout) | |||
| 454 | return timeout; | 432 | return timeout; |
| 455 | } | 433 | } |
| 456 | 434 | ||
| 457 | /** | ||
| 458 | * bltbit_fifo_status - checks the current status of the fifo | ||
| 459 | * @info : framebuffer structure | ||
| 460 | * | ||
| 461 | * returns number of free words in buffer | ||
| 462 | */ | ||
| 463 | static u8 | ||
| 464 | bltbit_fifo_status(struct fb_info *info) | ||
| 465 | { | ||
| 466 | u8 status; | ||
| 467 | |||
| 468 | status = s1d13xxxfb_readreg(info->par, S1DREG_BBLT_CTL0); | ||
| 469 | |||
| 470 | /* its empty so room for 16 words */ | ||
| 471 | if (status & BBLT_FIFO_EMPTY) | ||
| 472 | return 16; | ||
| 473 | |||
| 474 | /* its full so we dont want to add */ | ||
| 475 | if (status & BBLT_FIFO_FULL) | ||
| 476 | return 0; | ||
| 477 | |||
| 478 | /* its atleast half full but we can add one atleast */ | ||
| 479 | if (status & BBLT_FIFO_NOT_FULL) | ||
| 480 | return 1; | ||
| 481 | |||
| 482 | return 0; | ||
| 483 | } | ||
| 484 | |||
| 485 | /* | 435 | /* |
| 486 | * s1d13xxxfb_bitblt_copyarea - accelerated copyarea function | 436 | * s1d13xxxfb_bitblt_copyarea - accelerated copyarea function |
| 487 | * @info : framebuffer structure | 437 | * @info : framebuffer structure |
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index f9aca9d13d1b..83ce9a04d872 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
| 24 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
| 25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
| 26 | #include <linux/pm_runtime.h> | ||
| 26 | 27 | ||
| 27 | #include <mach/map.h> | 28 | #include <mach/map.h> |
| 28 | #include <plat/regs-fb-v4.h> | 29 | #include <plat/regs-fb-v4.h> |
| @@ -1013,8 +1014,30 @@ static int s3c_fb_ioctl(struct fb_info *info, unsigned int cmd, | |||
| 1013 | return ret; | 1014 | return ret; |
| 1014 | } | 1015 | } |
| 1015 | 1016 | ||
| 1017 | static int s3c_fb_open(struct fb_info *info, int user) | ||
| 1018 | { | ||
| 1019 | struct s3c_fb_win *win = info->par; | ||
| 1020 | struct s3c_fb *sfb = win->parent; | ||
| 1021 | |||
| 1022 | pm_runtime_get_sync(sfb->dev); | ||
| 1023 | |||
| 1024 | return 0; | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | static int s3c_fb_release(struct fb_info *info, int user) | ||
| 1028 | { | ||
| 1029 | struct s3c_fb_win *win = info->par; | ||
| 1030 | struct s3c_fb *sfb = win->parent; | ||
| 1031 | |||
| 1032 | pm_runtime_put_sync(sfb->dev); | ||
| 1033 | |||
| 1034 | return 0; | ||
| 1035 | } | ||
| 1036 | |||
| 1016 | static struct fb_ops s3c_fb_ops = { | 1037 | static struct fb_ops s3c_fb_ops = { |
| 1017 | .owner = THIS_MODULE, | 1038 | .owner = THIS_MODULE, |
| 1039 | .fb_open = s3c_fb_open, | ||
| 1040 | .fb_release = s3c_fb_release, | ||
| 1018 | .fb_check_var = s3c_fb_check_var, | 1041 | .fb_check_var = s3c_fb_check_var, |
| 1019 | .fb_set_par = s3c_fb_set_par, | 1042 | .fb_set_par = s3c_fb_set_par, |
| 1020 | .fb_blank = s3c_fb_blank, | 1043 | .fb_blank = s3c_fb_blank, |
| @@ -1322,6 +1345,8 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) | |||
| 1322 | 1345 | ||
| 1323 | clk_enable(sfb->bus_clk); | 1346 | clk_enable(sfb->bus_clk); |
| 1324 | 1347 | ||
| 1348 | pm_runtime_enable(sfb->dev); | ||
| 1349 | |||
| 1325 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1350 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1326 | if (!res) { | 1351 | if (!res) { |
| 1327 | dev_err(dev, "failed to find registers\n"); | 1352 | dev_err(dev, "failed to find registers\n"); |
| @@ -1360,6 +1385,9 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) | |||
| 1360 | 1385 | ||
| 1361 | dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs); | 1386 | dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs); |
| 1362 | 1387 | ||
| 1388 | platform_set_drvdata(pdev, sfb); | ||
| 1389 | pm_runtime_get_sync(sfb->dev); | ||
| 1390 | |||
| 1363 | /* setup gpio and output polarity controls */ | 1391 | /* setup gpio and output polarity controls */ |
| 1364 | 1392 | ||
| 1365 | pd->setup_gpio(); | 1393 | pd->setup_gpio(); |
| @@ -1400,6 +1428,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) | |||
| 1400 | } | 1428 | } |
| 1401 | 1429 | ||
| 1402 | platform_set_drvdata(pdev, sfb); | 1430 | platform_set_drvdata(pdev, sfb); |
| 1431 | pm_runtime_put_sync(sfb->dev); | ||
| 1403 | 1432 | ||
| 1404 | return 0; | 1433 | return 0; |
| 1405 | 1434 | ||
| @@ -1434,6 +1463,8 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev) | |||
| 1434 | struct s3c_fb *sfb = platform_get_drvdata(pdev); | 1463 | struct s3c_fb *sfb = platform_get_drvdata(pdev); |
| 1435 | int win; | 1464 | int win; |
| 1436 | 1465 | ||
| 1466 | pm_runtime_get_sync(sfb->dev); | ||
| 1467 | |||
| 1437 | for (win = 0; win < S3C_FB_MAX_WIN; win++) | 1468 | for (win = 0; win < S3C_FB_MAX_WIN; win++) |
| 1438 | if (sfb->windows[win]) | 1469 | if (sfb->windows[win]) |
| 1439 | s3c_fb_release_win(sfb, sfb->windows[win]); | 1470 | s3c_fb_release_win(sfb, sfb->windows[win]); |
| @@ -1450,12 +1481,74 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev) | |||
| 1450 | 1481 | ||
| 1451 | kfree(sfb); | 1482 | kfree(sfb); |
| 1452 | 1483 | ||
| 1484 | pm_runtime_put_sync(sfb->dev); | ||
| 1485 | pm_runtime_disable(sfb->dev); | ||
| 1486 | |||
| 1453 | return 0; | 1487 | return 0; |
| 1454 | } | 1488 | } |
| 1455 | 1489 | ||
| 1456 | #ifdef CONFIG_PM | 1490 | #ifdef CONFIG_PM |
| 1457 | static int s3c_fb_suspend(struct platform_device *pdev, pm_message_t state) | 1491 | static int s3c_fb_suspend(struct device *dev) |
| 1492 | { | ||
| 1493 | struct platform_device *pdev = to_platform_device(dev); | ||
| 1494 | struct s3c_fb *sfb = platform_get_drvdata(pdev); | ||
| 1495 | struct s3c_fb_win *win; | ||
| 1496 | int win_no; | ||
| 1497 | |||
| 1498 | for (win_no = S3C_FB_MAX_WIN - 1; win_no >= 0; win_no--) { | ||
| 1499 | win = sfb->windows[win_no]; | ||
| 1500 | if (!win) | ||
| 1501 | continue; | ||
| 1502 | |||
| 1503 | /* use the blank function to push into power-down */ | ||
| 1504 | s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo); | ||
| 1505 | } | ||
| 1506 | |||
| 1507 | clk_disable(sfb->bus_clk); | ||
| 1508 | return 0; | ||
| 1509 | } | ||
| 1510 | |||
| 1511 | static int s3c_fb_resume(struct device *dev) | ||
| 1512 | { | ||
| 1513 | struct platform_device *pdev = to_platform_device(dev); | ||
| 1514 | struct s3c_fb *sfb = platform_get_drvdata(pdev); | ||
| 1515 | struct s3c_fb_platdata *pd = sfb->pdata; | ||
| 1516 | struct s3c_fb_win *win; | ||
| 1517 | int win_no; | ||
| 1518 | |||
| 1519 | clk_enable(sfb->bus_clk); | ||
| 1520 | |||
| 1521 | /* setup registers */ | ||
| 1522 | writel(pd->vidcon1, sfb->regs + VIDCON1); | ||
| 1523 | |||
| 1524 | /* zero all windows before we do anything */ | ||
| 1525 | for (win_no = 0; win_no < sfb->variant.nr_windows; win_no++) | ||
| 1526 | s3c_fb_clear_win(sfb, win_no); | ||
| 1527 | |||
| 1528 | for (win_no = 0; win_no < sfb->variant.nr_windows - 1; win_no++) { | ||
| 1529 | void __iomem *regs = sfb->regs + sfb->variant.keycon; | ||
| 1530 | |||
| 1531 | regs += (win_no * 8); | ||
| 1532 | writel(0xffffff, regs + WKEYCON0); | ||
| 1533 | writel(0xffffff, regs + WKEYCON1); | ||
| 1534 | } | ||
| 1535 | |||
| 1536 | /* restore framebuffers */ | ||
| 1537 | for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) { | ||
| 1538 | win = sfb->windows[win_no]; | ||
| 1539 | if (!win) | ||
| 1540 | continue; | ||
| 1541 | |||
| 1542 | dev_dbg(&pdev->dev, "resuming window %d\n", win_no); | ||
| 1543 | s3c_fb_set_par(win->fbinfo); | ||
| 1544 | } | ||
| 1545 | |||
| 1546 | return 0; | ||
| 1547 | } | ||
| 1548 | |||
| 1549 | int s3c_fb_runtime_suspend(struct device *dev) | ||
| 1458 | { | 1550 | { |
| 1551 | struct platform_device *pdev = to_platform_device(dev); | ||
| 1459 | struct s3c_fb *sfb = platform_get_drvdata(pdev); | 1552 | struct s3c_fb *sfb = platform_get_drvdata(pdev); |
| 1460 | struct s3c_fb_win *win; | 1553 | struct s3c_fb_win *win; |
| 1461 | int win_no; | 1554 | int win_no; |
| @@ -1473,8 +1566,9 @@ static int s3c_fb_suspend(struct platform_device *pdev, pm_message_t state) | |||
| 1473 | return 0; | 1566 | return 0; |
| 1474 | } | 1567 | } |
| 1475 | 1568 | ||
| 1476 | static int s3c_fb_resume(struct platform_device *pdev) | 1569 | int s3c_fb_runtime_resume(struct device *dev) |
| 1477 | { | 1570 | { |
| 1571 | struct platform_device *pdev = to_platform_device(dev); | ||
| 1478 | struct s3c_fb *sfb = platform_get_drvdata(pdev); | 1572 | struct s3c_fb *sfb = platform_get_drvdata(pdev); |
| 1479 | struct s3c_fb_platdata *pd = sfb->pdata; | 1573 | struct s3c_fb_platdata *pd = sfb->pdata; |
| 1480 | struct s3c_fb_win *win; | 1574 | struct s3c_fb_win *win; |
| @@ -1509,9 +1603,12 @@ static int s3c_fb_resume(struct platform_device *pdev) | |||
| 1509 | 1603 | ||
| 1510 | return 0; | 1604 | return 0; |
| 1511 | } | 1605 | } |
| 1606 | |||
| 1512 | #else | 1607 | #else |
| 1513 | #define s3c_fb_suspend NULL | 1608 | #define s3c_fb_suspend NULL |
| 1514 | #define s3c_fb_resume NULL | 1609 | #define s3c_fb_resume NULL |
| 1610 | #define s3c_fb_runtime_suspend NULL | ||
| 1611 | #define s3c_fb_runtime_resume NULL | ||
| 1515 | #endif | 1612 | #endif |
| 1516 | 1613 | ||
| 1517 | 1614 | ||
| @@ -1710,15 +1807,21 @@ static struct platform_device_id s3c_fb_driver_ids[] = { | |||
| 1710 | }; | 1807 | }; |
| 1711 | MODULE_DEVICE_TABLE(platform, s3c_fb_driver_ids); | 1808 | MODULE_DEVICE_TABLE(platform, s3c_fb_driver_ids); |
| 1712 | 1809 | ||
| 1810 | static const struct dev_pm_ops s3cfb_pm_ops = { | ||
| 1811 | .suspend = s3c_fb_suspend, | ||
| 1812 | .resume = s3c_fb_resume, | ||
| 1813 | .runtime_suspend = s3c_fb_runtime_suspend, | ||
| 1814 | .runtime_resume = s3c_fb_runtime_resume, | ||
| 1815 | }; | ||
| 1816 | |||
| 1713 | static struct platform_driver s3c_fb_driver = { | 1817 | static struct platform_driver s3c_fb_driver = { |
| 1714 | .probe = s3c_fb_probe, | 1818 | .probe = s3c_fb_probe, |
| 1715 | .remove = __devexit_p(s3c_fb_remove), | 1819 | .remove = __devexit_p(s3c_fb_remove), |
| 1716 | .suspend = s3c_fb_suspend, | ||
| 1717 | .resume = s3c_fb_resume, | ||
| 1718 | .id_table = s3c_fb_driver_ids, | 1820 | .id_table = s3c_fb_driver_ids, |
| 1719 | .driver = { | 1821 | .driver = { |
| 1720 | .name = "s3c-fb", | 1822 | .name = "s3c-fb", |
| 1721 | .owner = THIS_MODULE, | 1823 | .owner = THIS_MODULE, |
| 1824 | .pm = &s3cfb_pm_ops, | ||
| 1722 | }, | 1825 | }, |
| 1723 | }; | 1826 | }; |
| 1724 | 1827 | ||
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index 3f3d431033ca..24640c8458ab 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
| 15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| 16 | #include <linux/pm_runtime.h> | ||
| 16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 17 | #include <linux/string.h> | 18 | #include <linux/string.h> |
| 18 | #include <linux/types.h> | 19 | #include <linux/types.h> |
| @@ -21,18 +22,40 @@ | |||
| 21 | #include <video/sh_mipi_dsi.h> | 22 | #include <video/sh_mipi_dsi.h> |
| 22 | #include <video/sh_mobile_lcdc.h> | 23 | #include <video/sh_mobile_lcdc.h> |
| 23 | 24 | ||
| 24 | #define CMTSRTCTR 0x80d0 | 25 | #define SYSCTRL 0x0000 |
| 25 | #define CMTSRTREQ 0x8070 | 26 | #define SYSCONF 0x0004 |
| 26 | 27 | #define TIMSET 0x0008 | |
| 28 | #define RESREQSET0 0x0018 | ||
| 29 | #define RESREQSET1 0x001c | ||
| 30 | #define HSTTOVSET 0x0020 | ||
| 31 | #define LPRTOVSET 0x0024 | ||
| 32 | #define TATOVSET 0x0028 | ||
| 33 | #define PRTOVSET 0x002c | ||
| 34 | #define DSICTRL 0x0030 | ||
| 27 | #define DSIINTE 0x0060 | 35 | #define DSIINTE 0x0060 |
| 36 | #define PHYCTRL 0x0070 | ||
| 37 | |||
| 38 | /* relative to linkbase */ | ||
| 39 | #define DTCTR 0x0000 | ||
| 40 | #define VMCTR1 0x0020 | ||
| 41 | #define VMCTR2 0x0024 | ||
| 42 | #define VMLEN1 0x0028 | ||
| 43 | #define CMTSRTREQ 0x0070 | ||
| 44 | #define CMTSRTCTR 0x00d0 | ||
| 28 | 45 | ||
| 29 | /* E.g., sh7372 has 2 MIPI-DSIs - one for each LCDC */ | 46 | /* E.g., sh7372 has 2 MIPI-DSIs - one for each LCDC */ |
| 30 | #define MAX_SH_MIPI_DSI 2 | 47 | #define MAX_SH_MIPI_DSI 2 |
| 31 | 48 | ||
| 32 | struct sh_mipi { | 49 | struct sh_mipi { |
| 33 | void __iomem *base; | 50 | void __iomem *base; |
| 51 | void __iomem *linkbase; | ||
| 34 | struct clk *dsit_clk; | 52 | struct clk *dsit_clk; |
| 35 | struct clk *dsip_clk; | 53 | struct clk *dsip_clk; |
| 54 | struct device *dev; | ||
| 55 | |||
| 56 | void *next_board_data; | ||
| 57 | void (*next_display_on)(void *board_data, struct fb_info *info); | ||
| 58 | void (*next_display_off)(void *board_data); | ||
| 36 | }; | 59 | }; |
| 37 | 60 | ||
| 38 | static struct sh_mipi *mipi_dsi[MAX_SH_MIPI_DSI]; | 61 | static struct sh_mipi *mipi_dsi[MAX_SH_MIPI_DSI]; |
| @@ -55,10 +78,10 @@ static int sh_mipi_send_short(struct sh_mipi *mipi, u8 dsi_cmd, | |||
| 55 | int cnt = 100; | 78 | int cnt = 100; |
| 56 | 79 | ||
| 57 | /* transmit a short packet to LCD panel */ | 80 | /* transmit a short packet to LCD panel */ |
| 58 | iowrite32(1 | data, mipi->base + 0x80d0); /* CMTSRTCTR */ | 81 | iowrite32(1 | data, mipi->linkbase + CMTSRTCTR); |
| 59 | iowrite32(1, mipi->base + 0x8070); /* CMTSRTREQ */ | 82 | iowrite32(1, mipi->linkbase + CMTSRTREQ); |
| 60 | 83 | ||
| 61 | while ((ioread32(mipi->base + 0x8070) & 1) && --cnt) | 84 | while ((ioread32(mipi->linkbase + CMTSRTREQ) & 1) && --cnt) |
| 62 | udelay(1); | 85 | udelay(1); |
| 63 | 86 | ||
| 64 | return cnt ? 0 : -ETIMEDOUT; | 87 | return cnt ? 0 : -ETIMEDOUT; |
| @@ -90,7 +113,7 @@ static void sh_mipi_dsi_enable(struct sh_mipi *mipi, bool enable) | |||
| 90 | * enable LCDC data tx, transition to LPS after completion of each HS | 113 | * enable LCDC data tx, transition to LPS after completion of each HS |
| 91 | * packet | 114 | * packet |
| 92 | */ | 115 | */ |
| 93 | iowrite32(0x00000002 | enable, mipi->base + 0x8000); /* DTCTR */ | 116 | iowrite32(0x00000002 | enable, mipi->linkbase + DTCTR); |
| 94 | } | 117 | } |
| 95 | 118 | ||
| 96 | static void sh_mipi_shutdown(struct platform_device *pdev) | 119 | static void sh_mipi_shutdown(struct platform_device *pdev) |
| @@ -104,14 +127,22 @@ static void mipi_display_on(void *arg, struct fb_info *info) | |||
| 104 | { | 127 | { |
| 105 | struct sh_mipi *mipi = arg; | 128 | struct sh_mipi *mipi = arg; |
| 106 | 129 | ||
| 130 | pm_runtime_get_sync(mipi->dev); | ||
| 107 | sh_mipi_dsi_enable(mipi, true); | 131 | sh_mipi_dsi_enable(mipi, true); |
| 132 | |||
| 133 | if (mipi->next_display_on) | ||
| 134 | mipi->next_display_on(mipi->next_board_data, info); | ||
| 108 | } | 135 | } |
| 109 | 136 | ||
| 110 | static void mipi_display_off(void *arg) | 137 | static void mipi_display_off(void *arg) |
| 111 | { | 138 | { |
| 112 | struct sh_mipi *mipi = arg; | 139 | struct sh_mipi *mipi = arg; |
| 113 | 140 | ||
| 141 | if (mipi->next_display_off) | ||
| 142 | mipi->next_display_off(mipi->next_board_data); | ||
| 143 | |||
| 114 | sh_mipi_dsi_enable(mipi, false); | 144 | sh_mipi_dsi_enable(mipi, false); |
| 145 | pm_runtime_put(mipi->dev); | ||
| 115 | } | 146 | } |
| 116 | 147 | ||
| 117 | static int __init sh_mipi_setup(struct sh_mipi *mipi, | 148 | static int __init sh_mipi_setup(struct sh_mipi *mipi, |
| @@ -119,8 +150,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, | |||
| 119 | { | 150 | { |
| 120 | void __iomem *base = mipi->base; | 151 | void __iomem *base = mipi->base; |
| 121 | struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan; | 152 | struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan; |
| 122 | u32 pctype, datatype, pixfmt; | 153 | u32 pctype, datatype, pixfmt, linelength, vmctr2 = 0x00e00000; |
| 123 | u32 linelength; | ||
| 124 | bool yuv; | 154 | bool yuv; |
| 125 | 155 | ||
| 126 | /* | 156 | /* |
| @@ -223,10 +253,10 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, | |||
| 223 | return -EINVAL; | 253 | return -EINVAL; |
| 224 | 254 | ||
| 225 | /* reset DSI link */ | 255 | /* reset DSI link */ |
| 226 | iowrite32(0x00000001, base); /* SYSCTRL */ | 256 | iowrite32(0x00000001, base + SYSCTRL); |
| 227 | /* Hold reset for 100 cycles of the slowest of bus, HS byte and LP clock */ | 257 | /* Hold reset for 100 cycles of the slowest of bus, HS byte and LP clock */ |
| 228 | udelay(50); | 258 | udelay(50); |
| 229 | iowrite32(0x00000000, base); /* SYSCTRL */ | 259 | iowrite32(0x00000000, base + SYSCTRL); |
| 230 | 260 | ||
| 231 | /* setup DSI link */ | 261 | /* setup DSI link */ |
| 232 | 262 | ||
| @@ -238,7 +268,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, | |||
| 238 | * ECC check enable | 268 | * ECC check enable |
| 239 | * additionally enable first two lanes | 269 | * additionally enable first two lanes |
| 240 | */ | 270 | */ |
| 241 | iowrite32(0x00003703, base + 0x04); /* SYSCONF */ | 271 | iowrite32(0x00003703, base + SYSCONF); |
| 242 | /* | 272 | /* |
| 243 | * T_wakeup = 0x7000 | 273 | * T_wakeup = 0x7000 |
| 244 | * T_hs-trail = 3 | 274 | * T_hs-trail = 3 |
| @@ -246,28 +276,28 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, | |||
| 246 | * T_clk-trail = 3 | 276 | * T_clk-trail = 3 |
| 247 | * T_clk-prepare = 2 | 277 | * T_clk-prepare = 2 |
| 248 | */ | 278 | */ |
| 249 | iowrite32(0x70003332, base + 0x08); /* TIMSET */ | 279 | iowrite32(0x70003332, base + TIMSET); |
| 250 | /* no responses requested */ | 280 | /* no responses requested */ |
| 251 | iowrite32(0x00000000, base + 0x18); /* RESREQSET0 */ | 281 | iowrite32(0x00000000, base + RESREQSET0); |
| 252 | /* request response to packets of type 0x28 */ | 282 | /* request response to packets of type 0x28 */ |
| 253 | iowrite32(0x00000100, base + 0x1c); /* RESREQSET1 */ | 283 | iowrite32(0x00000100, base + RESREQSET1); |
| 254 | /* High-speed transmission timeout, default 0xffffffff */ | 284 | /* High-speed transmission timeout, default 0xffffffff */ |
| 255 | iowrite32(0x0fffffff, base + 0x20); /* HSTTOVSET */ | 285 | iowrite32(0x0fffffff, base + HSTTOVSET); |
| 256 | /* LP reception timeout, default 0xffffffff */ | 286 | /* LP reception timeout, default 0xffffffff */ |
| 257 | iowrite32(0x0fffffff, base + 0x24); /* LPRTOVSET */ | 287 | iowrite32(0x0fffffff, base + LPRTOVSET); |
| 258 | /* Turn-around timeout, default 0xffffffff */ | 288 | /* Turn-around timeout, default 0xffffffff */ |
| 259 | iowrite32(0x0fffffff, base + 0x28); /* TATOVSET */ | 289 | iowrite32(0x0fffffff, base + TATOVSET); |
| 260 | /* Peripheral reset timeout, default 0xffffffff */ | 290 | /* Peripheral reset timeout, default 0xffffffff */ |
| 261 | iowrite32(0x0fffffff, base + 0x2c); /* PRTOVSET */ | 291 | iowrite32(0x0fffffff, base + PRTOVSET); |
| 262 | /* Enable timeout counters */ | 292 | /* Enable timeout counters */ |
| 263 | iowrite32(0x00000f00, base + 0x30); /* DSICTRL */ | 293 | iowrite32(0x00000f00, base + DSICTRL); |
| 264 | /* Interrupts not used, disable all */ | 294 | /* Interrupts not used, disable all */ |
| 265 | iowrite32(0, base + DSIINTE); | 295 | iowrite32(0, base + DSIINTE); |
| 266 | /* DSI-Tx bias on */ | 296 | /* DSI-Tx bias on */ |
| 267 | iowrite32(0x00000001, base + 0x70); /* PHYCTRL */ | 297 | iowrite32(0x00000001, base + PHYCTRL); |
| 268 | udelay(200); | 298 | udelay(200); |
| 269 | /* Deassert resets, power on, set multiplier */ | 299 | /* Deassert resets, power on, set multiplier */ |
| 270 | iowrite32(0x03070b01, base + 0x70); /* PHYCTRL */ | 300 | iowrite32(0x03070b01, base + PHYCTRL); |
| 271 | 301 | ||
| 272 | /* setup l-bridge */ | 302 | /* setup l-bridge */ |
| 273 | 303 | ||
| @@ -275,20 +305,28 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi, | |||
| 275 | * Enable transmission of all packets, | 305 | * Enable transmission of all packets, |
| 276 | * transmit LPS after each HS packet completion | 306 | * transmit LPS after each HS packet completion |
| 277 | */ | 307 | */ |
| 278 | iowrite32(0x00000006, base + 0x8000); /* DTCTR */ | 308 | iowrite32(0x00000006, mipi->linkbase + DTCTR); |
| 279 | /* VSYNC width = 2 (<< 17) */ | 309 | /* VSYNC width = 2 (<< 17) */ |
| 280 | iowrite32(0x00040000 | (pctype << 12) | datatype, base + 0x8020); /* VMCTR1 */ | 310 | iowrite32((ch->lcd_cfg[0].vsync_len << pdata->vsynw_offset) | |
| 311 | (pdata->clksrc << 16) | (pctype << 12) | datatype, | ||
| 312 | mipi->linkbase + VMCTR1); | ||
| 313 | |||
| 281 | /* | 314 | /* |
| 282 | * Non-burst mode with sync pulses: VSE and HSE are output, | 315 | * Non-burst mode with sync pulses: VSE and HSE are output, |
| 283 | * HSA period allowed, no commands in LP | 316 | * HSA period allowed, no commands in LP |
| 284 | */ | 317 | */ |
| 285 | iowrite32(0x00e00000, base + 0x8024); /* VMCTR2 */ | 318 | if (pdata->flags & SH_MIPI_DSI_HSABM) |
| 319 | vmctr2 |= 0x20; | ||
| 320 | if (pdata->flags & SH_MIPI_DSI_HSPBM) | ||
| 321 | vmctr2 |= 0x10; | ||
| 322 | iowrite32(vmctr2, mipi->linkbase + VMCTR2); | ||
| 323 | |||
| 286 | /* | 324 | /* |
| 287 | * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see | 325 | * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see |
| 288 | * sh_mobile_lcdc_info.ch[0].lcd_cfg[0].xres), HSALEN = 1 - default | 326 | * sh_mobile_lcdc_info.ch[0].lcd_cfg[0].xres), HSALEN = 1 - default |
| 289 | * (unused, since VMCTR2[HSABM] = 0) | 327 | * (unused if VMCTR2[HSABM] = 0) |
| 290 | */ | 328 | */ |
| 291 | iowrite32(1 | (linelength << 16), base + 0x8028); /* VMLEN1 */ | 329 | iowrite32(1 | (linelength << 16), mipi->linkbase + VMLEN1); |
| 292 | 330 | ||
| 293 | msleep(5); | 331 | msleep(5); |
| 294 | 332 | ||
| @@ -321,11 +359,12 @@ static int __init sh_mipi_probe(struct platform_device *pdev) | |||
| 321 | struct sh_mipi *mipi; | 359 | struct sh_mipi *mipi; |
| 322 | struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data; | 360 | struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data; |
| 323 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 361 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 362 | struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
| 324 | unsigned long rate, f_current; | 363 | unsigned long rate, f_current; |
| 325 | int idx = pdev->id, ret; | 364 | int idx = pdev->id, ret; |
| 326 | char dsip_clk[] = "dsi.p_clk"; | 365 | char dsip_clk[] = "dsi.p_clk"; |
| 327 | 366 | ||
| 328 | if (!res || idx >= ARRAY_SIZE(mipi_dsi) || !pdata) | 367 | if (!res || !res2 || idx >= ARRAY_SIZE(mipi_dsi) || !pdata) |
| 329 | return -ENODEV; | 368 | return -ENODEV; |
| 330 | 369 | ||
| 331 | mutex_lock(&array_lock); | 370 | mutex_lock(&array_lock); |
| @@ -356,6 +395,20 @@ static int __init sh_mipi_probe(struct platform_device *pdev) | |||
| 356 | goto emap; | 395 | goto emap; |
| 357 | } | 396 | } |
| 358 | 397 | ||
| 398 | if (!request_mem_region(res2->start, resource_size(res2), pdev->name)) { | ||
| 399 | dev_err(&pdev->dev, "MIPI register region 2 already claimed\n"); | ||
| 400 | ret = -EBUSY; | ||
| 401 | goto ereqreg2; | ||
| 402 | } | ||
| 403 | |||
| 404 | mipi->linkbase = ioremap(res2->start, resource_size(res2)); | ||
| 405 | if (!mipi->linkbase) { | ||
| 406 | ret = -ENOMEM; | ||
| 407 | goto emap2; | ||
| 408 | } | ||
| 409 | |||
| 410 | mipi->dev = &pdev->dev; | ||
| 411 | |||
| 359 | mipi->dsit_clk = clk_get(&pdev->dev, "dsit_clk"); | 412 | mipi->dsit_clk = clk_get(&pdev->dev, "dsit_clk"); |
| 360 | if (IS_ERR(mipi->dsit_clk)) { | 413 | if (IS_ERR(mipi->dsit_clk)) { |
| 361 | ret = PTR_ERR(mipi->dsit_clk); | 414 | ret = PTR_ERR(mipi->dsit_clk); |
| @@ -405,6 +458,9 @@ static int __init sh_mipi_probe(struct platform_device *pdev) | |||
| 405 | 458 | ||
| 406 | mipi_dsi[idx] = mipi; | 459 | mipi_dsi[idx] = mipi; |
| 407 | 460 | ||
| 461 | pm_runtime_enable(&pdev->dev); | ||
| 462 | pm_runtime_resume(&pdev->dev); | ||
| 463 | |||
| 408 | ret = sh_mipi_setup(mipi, pdata); | 464 | ret = sh_mipi_setup(mipi, pdata); |
| 409 | if (ret < 0) | 465 | if (ret < 0) |
| 410 | goto emipisetup; | 466 | goto emipisetup; |
| @@ -412,15 +468,22 @@ static int __init sh_mipi_probe(struct platform_device *pdev) | |||
| 412 | mutex_unlock(&array_lock); | 468 | mutex_unlock(&array_lock); |
| 413 | platform_set_drvdata(pdev, mipi); | 469 | platform_set_drvdata(pdev, mipi); |
| 414 | 470 | ||
| 471 | /* Save original LCDC callbacks */ | ||
| 472 | mipi->next_board_data = pdata->lcd_chan->board_cfg.board_data; | ||
| 473 | mipi->next_display_on = pdata->lcd_chan->board_cfg.display_on; | ||
| 474 | mipi->next_display_off = pdata->lcd_chan->board_cfg.display_off; | ||
| 475 | |||
| 415 | /* Set up LCDC callbacks */ | 476 | /* Set up LCDC callbacks */ |
| 416 | pdata->lcd_chan->board_cfg.board_data = mipi; | 477 | pdata->lcd_chan->board_cfg.board_data = mipi; |
| 417 | pdata->lcd_chan->board_cfg.display_on = mipi_display_on; | 478 | pdata->lcd_chan->board_cfg.display_on = mipi_display_on; |
| 418 | pdata->lcd_chan->board_cfg.display_off = mipi_display_off; | 479 | pdata->lcd_chan->board_cfg.display_off = mipi_display_off; |
| 480 | pdata->lcd_chan->board_cfg.owner = THIS_MODULE; | ||
| 419 | 481 | ||
| 420 | return 0; | 482 | return 0; |
| 421 | 483 | ||
| 422 | emipisetup: | 484 | emipisetup: |
| 423 | mipi_dsi[idx] = NULL; | 485 | mipi_dsi[idx] = NULL; |
| 486 | pm_runtime_disable(&pdev->dev); | ||
| 424 | clk_disable(mipi->dsip_clk); | 487 | clk_disable(mipi->dsip_clk); |
| 425 | eclkpon: | 488 | eclkpon: |
| 426 | clk_disable(mipi->dsit_clk); | 489 | clk_disable(mipi->dsit_clk); |
| @@ -431,6 +494,10 @@ eclkpget: | |||
| 431 | esettrate: | 494 | esettrate: |
| 432 | clk_put(mipi->dsit_clk); | 495 | clk_put(mipi->dsit_clk); |
| 433 | eclktget: | 496 | eclktget: |
| 497 | iounmap(mipi->linkbase); | ||
| 498 | emap2: | ||
| 499 | release_mem_region(res2->start, resource_size(res2)); | ||
| 500 | ereqreg2: | ||
| 434 | iounmap(mipi->base); | 501 | iounmap(mipi->base); |
| 435 | emap: | 502 | emap: |
| 436 | release_mem_region(res->start, resource_size(res)); | 503 | release_mem_region(res->start, resource_size(res)); |
| @@ -447,6 +514,7 @@ static int __exit sh_mipi_remove(struct platform_device *pdev) | |||
| 447 | { | 514 | { |
| 448 | struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data; | 515 | struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data; |
| 449 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 516 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 517 | struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
| 450 | struct sh_mipi *mipi = platform_get_drvdata(pdev); | 518 | struct sh_mipi *mipi = platform_get_drvdata(pdev); |
| 451 | int i, ret; | 519 | int i, ret; |
| 452 | 520 | ||
| @@ -467,14 +535,19 @@ static int __exit sh_mipi_remove(struct platform_device *pdev) | |||
| 467 | if (ret < 0) | 535 | if (ret < 0) |
| 468 | return ret; | 536 | return ret; |
| 469 | 537 | ||
| 538 | pdata->lcd_chan->board_cfg.owner = NULL; | ||
| 470 | pdata->lcd_chan->board_cfg.display_on = NULL; | 539 | pdata->lcd_chan->board_cfg.display_on = NULL; |
| 471 | pdata->lcd_chan->board_cfg.display_off = NULL; | 540 | pdata->lcd_chan->board_cfg.display_off = NULL; |
| 472 | pdata->lcd_chan->board_cfg.board_data = NULL; | 541 | pdata->lcd_chan->board_cfg.board_data = NULL; |
| 473 | 542 | ||
| 543 | pm_runtime_disable(&pdev->dev); | ||
| 474 | clk_disable(mipi->dsip_clk); | 544 | clk_disable(mipi->dsip_clk); |
| 475 | clk_disable(mipi->dsit_clk); | 545 | clk_disable(mipi->dsit_clk); |
| 476 | clk_put(mipi->dsit_clk); | 546 | clk_put(mipi->dsit_clk); |
| 477 | clk_put(mipi->dsip_clk); | 547 | clk_put(mipi->dsip_clk); |
| 548 | iounmap(mipi->linkbase); | ||
| 549 | if (res2) | ||
| 550 | release_mem_region(res2->start, resource_size(res2)); | ||
| 478 | iounmap(mipi->base); | 551 | iounmap(mipi->base); |
| 479 | if (res) | 552 | if (res) |
| 480 | release_mem_region(res->start, resource_size(res)); | 553 | release_mem_region(res->start, resource_size(res)); |
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c index fcda0e970113..8c59cc8c5a9c 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/sh_mobile_hdmi.c | |||
| @@ -209,7 +209,11 @@ enum hotplug_state { | |||
| 209 | struct sh_hdmi { | 209 | struct sh_hdmi { |
| 210 | void __iomem *base; | 210 | void __iomem *base; |
| 211 | enum hotplug_state hp_state; /* hot-plug status */ | 211 | enum hotplug_state hp_state; /* hot-plug status */ |
| 212 | bool preprogrammed_mode; /* use a pre-programmed VIC or the external mode */ | 212 | u8 preprogrammed_vic; /* use a pre-programmed VIC or |
| 213 | the external mode */ | ||
| 214 | u8 edid_block_addr; | ||
| 215 | u8 edid_segment_nr; | ||
| 216 | u8 edid_blocks; | ||
| 213 | struct clk *hdmi_clk; | 217 | struct clk *hdmi_clk; |
| 214 | struct device *dev; | 218 | struct device *dev; |
| 215 | struct fb_info *info; | 219 | struct fb_info *info; |
| @@ -342,7 +346,7 @@ static void sh_hdmi_external_video_param(struct sh_hdmi *hdmi) | |||
| 342 | hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION); | 346 | hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION); |
| 343 | 347 | ||
| 344 | /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for external mode */ | 348 | /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for external mode */ |
| 345 | if (!hdmi->preprogrammed_mode) | 349 | if (!hdmi->preprogrammed_vic) |
| 346 | hdmi_write(hdmi, sync | 1 | (voffset << 4), | 350 | hdmi_write(hdmi, sync | 1 | (voffset << 4), |
| 347 | HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS); | 351 | HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS); |
| 348 | } | 352 | } |
| @@ -466,7 +470,18 @@ static void sh_hdmi_audio_config(struct sh_hdmi *hdmi) | |||
| 466 | */ | 470 | */ |
| 467 | static void sh_hdmi_phy_config(struct sh_hdmi *hdmi) | 471 | static void sh_hdmi_phy_config(struct sh_hdmi *hdmi) |
| 468 | { | 472 | { |
| 469 | if (hdmi->var.yres > 480) { | 473 | if (hdmi->var.pixclock < 10000) { |
| 474 | /* for 1080p8bit 148MHz */ | ||
| 475 | hdmi_write(hdmi, 0x1d, HDMI_SLIPHDMIT_PARAM_SETTINGS_1); | ||
| 476 | hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2); | ||
| 477 | hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3); | ||
| 478 | hdmi_write(hdmi, 0x4c, HDMI_SLIPHDMIT_PARAM_SETTINGS_5); | ||
| 479 | hdmi_write(hdmi, 0x1e, HDMI_SLIPHDMIT_PARAM_SETTINGS_6); | ||
| 480 | hdmi_write(hdmi, 0x48, HDMI_SLIPHDMIT_PARAM_SETTINGS_7); | ||
| 481 | hdmi_write(hdmi, 0x0e, HDMI_SLIPHDMIT_PARAM_SETTINGS_8); | ||
| 482 | hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9); | ||
| 483 | hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10); | ||
| 484 | } else if (hdmi->var.pixclock < 30000) { | ||
| 470 | /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */ | 485 | /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */ |
| 471 | /* | 486 | /* |
| 472 | * [1:0] Speed_A | 487 | * [1:0] Speed_A |
| @@ -565,13 +580,11 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi) | |||
| 565 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB3); | 580 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB3); |
| 566 | 581 | ||
| 567 | /* | 582 | /* |
| 568 | * VIC = 1280 x 720p: ignored if external config is used | 583 | * VIC should be ignored if external config is used, so, we could just use 0, |
| 569 | * Send 2 for 720 x 480p, 16 for 1080p, ignored in external mode | 584 | * but play safe and use a valid value in any case just in case |
| 570 | */ | 585 | */ |
| 571 | if (hdmi->var.yres == 1080 && hdmi->var.xres == 1920) | 586 | if (hdmi->preprogrammed_vic) |
| 572 | vic = 16; | 587 | vic = hdmi->preprogrammed_vic; |
| 573 | else if (hdmi->var.yres == 480 && hdmi->var.xres == 720) | ||
| 574 | vic = 2; | ||
| 575 | else | 588 | else |
| 576 | vic = 4; | 589 | vic = 4; |
| 577 | hdmi_write(hdmi, vic, HDMI_CTRL_PKT_BUF_ACCESS_PB4); | 590 | hdmi_write(hdmi, vic, HDMI_CTRL_PKT_BUF_ACCESS_PB4); |
| @@ -685,11 +698,21 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi) | |||
| 685 | } | 698 | } |
| 686 | 699 | ||
| 687 | static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi, | 700 | static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi, |
| 688 | const struct fb_videomode *mode) | 701 | const struct fb_videomode *mode, |
| 702 | unsigned long *hdmi_rate, unsigned long *parent_rate) | ||
| 689 | { | 703 | { |
| 690 | long target = PICOS2KHZ(mode->pixclock) * 1000, | 704 | unsigned long target = PICOS2KHZ(mode->pixclock) * 1000, rate_error; |
| 691 | rate = clk_round_rate(hdmi->hdmi_clk, target); | 705 | struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; |
| 692 | unsigned long rate_error = rate > 0 ? abs(rate - target) : ULONG_MAX; | 706 | |
| 707 | *hdmi_rate = clk_round_rate(hdmi->hdmi_clk, target); | ||
| 708 | if ((long)*hdmi_rate < 0) | ||
| 709 | *hdmi_rate = clk_get_rate(hdmi->hdmi_clk); | ||
| 710 | |||
| 711 | rate_error = (long)*hdmi_rate > 0 ? abs(*hdmi_rate - target) : ULONG_MAX; | ||
| 712 | if (rate_error && pdata->clk_optimize_parent) | ||
| 713 | rate_error = pdata->clk_optimize_parent(target, hdmi_rate, parent_rate); | ||
| 714 | else if (clk_get_parent(hdmi->hdmi_clk)) | ||
| 715 | *parent_rate = clk_get_rate(clk_get_parent(hdmi->hdmi_clk)); | ||
| 693 | 716 | ||
| 694 | dev_dbg(hdmi->dev, "%u-%u-%u-%u x %u-%u-%u-%u\n", | 717 | dev_dbg(hdmi->dev, "%u-%u-%u-%u x %u-%u-%u-%u\n", |
| 695 | mode->left_margin, mode->xres, | 718 | mode->left_margin, mode->xres, |
| @@ -697,14 +720,15 @@ static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi, | |||
| 697 | mode->upper_margin, mode->yres, | 720 | mode->upper_margin, mode->yres, |
| 698 | mode->lower_margin, mode->vsync_len); | 721 | mode->lower_margin, mode->vsync_len); |
| 699 | 722 | ||
| 700 | dev_dbg(hdmi->dev, "\t@%lu(+/-%lu)Hz, e=%lu / 1000, r=%uHz\n", target, | 723 | dev_dbg(hdmi->dev, "\t@%lu(+/-%lu)Hz, e=%lu / 1000, r=%uHz, p=%luHz\n", target, |
| 701 | rate_error, rate_error ? 10000 / (10 * target / rate_error) : 0, | 724 | rate_error, rate_error ? 10000 / (10 * target / rate_error) : 0, |
| 702 | mode->refresh); | 725 | mode->refresh, *parent_rate); |
| 703 | 726 | ||
| 704 | return rate_error; | 727 | return rate_error; |
| 705 | } | 728 | } |
| 706 | 729 | ||
| 707 | static int sh_hdmi_read_edid(struct sh_hdmi *hdmi) | 730 | static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate, |
| 731 | unsigned long *parent_rate) | ||
| 708 | { | 732 | { |
| 709 | struct fb_var_screeninfo tmpvar; | 733 | struct fb_var_screeninfo tmpvar; |
| 710 | struct fb_var_screeninfo *var = &tmpvar; | 734 | struct fb_var_screeninfo *var = &tmpvar; |
| @@ -735,7 +759,38 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi) | |||
| 735 | printk(KERN_CONT "\n"); | 759 | printk(KERN_CONT "\n"); |
| 736 | #endif | 760 | #endif |
| 737 | 761 | ||
| 738 | fb_edid_to_monspecs(edid, &hdmi->monspec); | 762 | if (!hdmi->edid_blocks) { |
| 763 | fb_edid_to_monspecs(edid, &hdmi->monspec); | ||
| 764 | hdmi->edid_blocks = edid[126] + 1; | ||
| 765 | |||
| 766 | dev_dbg(hdmi->dev, "%d main modes, %d extension blocks\n", | ||
| 767 | hdmi->monspec.modedb_len, hdmi->edid_blocks - 1); | ||
| 768 | } else { | ||
| 769 | dev_dbg(hdmi->dev, "Extension %u detected, DTD start %u\n", | ||
| 770 | edid[0], edid[2]); | ||
| 771 | fb_edid_add_monspecs(edid, &hdmi->monspec); | ||
| 772 | } | ||
| 773 | |||
| 774 | if (hdmi->edid_blocks > hdmi->edid_segment_nr * 2 + | ||
| 775 | (hdmi->edid_block_addr >> 7) + 1) { | ||
| 776 | /* More blocks to read */ | ||
| 777 | if (hdmi->edid_block_addr) { | ||
| 778 | hdmi->edid_block_addr = 0; | ||
| 779 | hdmi->edid_segment_nr++; | ||
| 780 | } else { | ||
| 781 | hdmi->edid_block_addr = 0x80; | ||
| 782 | } | ||
| 783 | /* Set EDID word address */ | ||
| 784 | hdmi_write(hdmi, hdmi->edid_block_addr, HDMI_EDID_WORD_ADDRESS); | ||
| 785 | /* Enable EDID interrupt */ | ||
| 786 | hdmi_write(hdmi, 0xC6, HDMI_INTERRUPT_MASK_1); | ||
| 787 | /* Set EDID segment pointer - starts reading EDID */ | ||
| 788 | hdmi_write(hdmi, hdmi->edid_segment_nr, HDMI_EDID_SEGMENT_POINTER); | ||
| 789 | return -EAGAIN; | ||
| 790 | } | ||
| 791 | |||
| 792 | /* All E-EDID blocks ready */ | ||
| 793 | dev_dbg(hdmi->dev, "%d main and extended modes\n", hdmi->monspec.modedb_len); | ||
| 739 | 794 | ||
| 740 | fb_get_options("sh_mobile_lcdc", &forced); | 795 | fb_get_options("sh_mobile_lcdc", &forced); |
| 741 | if (forced && *forced) { | 796 | if (forced && *forced) { |
| @@ -754,11 +809,14 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi) | |||
| 754 | for (i = 0, mode = hdmi->monspec.modedb; | 809 | for (i = 0, mode = hdmi->monspec.modedb; |
| 755 | f_width && f_height && i < hdmi->monspec.modedb_len && !exact_match; | 810 | f_width && f_height && i < hdmi->monspec.modedb_len && !exact_match; |
| 756 | i++, mode++) { | 811 | i++, mode++) { |
| 757 | unsigned long rate_error = sh_hdmi_rate_error(hdmi, mode); | 812 | unsigned long rate_error; |
| 758 | 813 | ||
| 759 | /* No interest in unmatching modes */ | 814 | /* No interest in unmatching modes */ |
| 760 | if (f_width != mode->xres || f_height != mode->yres) | 815 | if (f_width != mode->xres || f_height != mode->yres) |
| 761 | continue; | 816 | continue; |
| 817 | |||
| 818 | rate_error = sh_hdmi_rate_error(hdmi, mode, hdmi_rate, parent_rate); | ||
| 819 | |||
| 762 | if (f_refresh == mode->refresh || (!f_refresh && !rate_error)) | 820 | if (f_refresh == mode->refresh || (!f_refresh && !rate_error)) |
| 763 | /* | 821 | /* |
| 764 | * Exact match if either the refresh rate matches or it | 822 | * Exact match if either the refresh rate matches or it |
| @@ -805,7 +863,7 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi) | |||
| 805 | 863 | ||
| 806 | if (modelist) { | 864 | if (modelist) { |
| 807 | found = &modelist->mode; | 865 | found = &modelist->mode; |
| 808 | found_rate_error = sh_hdmi_rate_error(hdmi, found); | 866 | found_rate_error = sh_hdmi_rate_error(hdmi, found, hdmi_rate, parent_rate); |
| 809 | } | 867 | } |
| 810 | } | 868 | } |
| 811 | 869 | ||
| @@ -813,16 +871,27 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi) | |||
| 813 | if (!found) | 871 | if (!found) |
| 814 | return -ENXIO; | 872 | return -ENXIO; |
| 815 | 873 | ||
| 816 | dev_info(hdmi->dev, "Using %s mode %ux%u@%uHz (%luHz), clock error %luHz\n", | 874 | if (found->xres == 640 && found->yres == 480 && found->refresh == 60) |
| 817 | modelist ? "default" : "EDID", found->xres, found->yres, | 875 | hdmi->preprogrammed_vic = 1; |
| 818 | found->refresh, PICOS2KHZ(found->pixclock) * 1000, found_rate_error); | 876 | else if (found->xres == 720 && found->yres == 480 && found->refresh == 60) |
| 819 | 877 | hdmi->preprogrammed_vic = 2; | |
| 820 | if ((found->xres == 720 && found->yres == 480) || | 878 | else if (found->xres == 720 && found->yres == 576 && found->refresh == 50) |
| 821 | (found->xres == 1280 && found->yres == 720) || | 879 | hdmi->preprogrammed_vic = 17; |
| 822 | (found->xres == 1920 && found->yres == 1080)) | 880 | else if (found->xres == 1280 && found->yres == 720 && found->refresh == 60) |
| 823 | hdmi->preprogrammed_mode = true; | 881 | hdmi->preprogrammed_vic = 4; |
| 882 | else if (found->xres == 1920 && found->yres == 1080 && found->refresh == 24) | ||
| 883 | hdmi->preprogrammed_vic = 32; | ||
| 884 | else if (found->xres == 1920 && found->yres == 1080 && found->refresh == 50) | ||
| 885 | hdmi->preprogrammed_vic = 31; | ||
| 886 | else if (found->xres == 1920 && found->yres == 1080 && found->refresh == 60) | ||
| 887 | hdmi->preprogrammed_vic = 16; | ||
| 824 | else | 888 | else |
| 825 | hdmi->preprogrammed_mode = false; | 889 | hdmi->preprogrammed_vic = 0; |
| 890 | |||
| 891 | dev_dbg(hdmi->dev, "Using %s %s mode %ux%u@%uHz (%luHz), clock error %luHz\n", | ||
| 892 | modelist ? "default" : "EDID", hdmi->preprogrammed_vic ? "VIC" : "external", | ||
| 893 | found->xres, found->yres, found->refresh, | ||
| 894 | PICOS2KHZ(found->pixclock) * 1000, found_rate_error); | ||
| 826 | 895 | ||
| 827 | fb_videomode_to_var(&hdmi->var, found); | 896 | fb_videomode_to_var(&hdmi->var, found); |
| 828 | sh_hdmi_external_video_param(hdmi); | 897 | sh_hdmi_external_video_param(hdmi); |
| @@ -871,32 +940,34 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id) | |||
| 871 | /* Check, if hot plug & MSENS pin status are both high */ | 940 | /* Check, if hot plug & MSENS pin status are both high */ |
| 872 | if ((msens & 0xC0) == 0xC0) { | 941 | if ((msens & 0xC0) == 0xC0) { |
| 873 | /* Display plug in */ | 942 | /* Display plug in */ |
| 943 | hdmi->edid_segment_nr = 0; | ||
| 944 | hdmi->edid_block_addr = 0; | ||
| 945 | hdmi->edid_blocks = 0; | ||
| 874 | hdmi->hp_state = HDMI_HOTPLUG_CONNECTED; | 946 | hdmi->hp_state = HDMI_HOTPLUG_CONNECTED; |
| 875 | 947 | ||
| 876 | /* Set EDID word address */ | 948 | /* Set EDID word address */ |
| 877 | hdmi_write(hdmi, 0x00, HDMI_EDID_WORD_ADDRESS); | 949 | hdmi_write(hdmi, 0x00, HDMI_EDID_WORD_ADDRESS); |
| 878 | /* Set EDID segment pointer */ | ||
| 879 | hdmi_write(hdmi, 0x00, HDMI_EDID_SEGMENT_POINTER); | ||
| 880 | /* Enable EDID interrupt */ | 950 | /* Enable EDID interrupt */ |
| 881 | hdmi_write(hdmi, 0xC6, HDMI_INTERRUPT_MASK_1); | 951 | hdmi_write(hdmi, 0xC6, HDMI_INTERRUPT_MASK_1); |
| 952 | /* Set EDID segment pointer - starts reading EDID */ | ||
| 953 | hdmi_write(hdmi, 0x00, HDMI_EDID_SEGMENT_POINTER); | ||
| 882 | } else if (!(status1 & 0x80)) { | 954 | } else if (!(status1 & 0x80)) { |
| 883 | /* Display unplug, beware multiple interrupts */ | 955 | /* Display unplug, beware multiple interrupts */ |
| 884 | if (hdmi->hp_state != HDMI_HOTPLUG_DISCONNECTED) | 956 | if (hdmi->hp_state != HDMI_HOTPLUG_DISCONNECTED) { |
| 957 | hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED; | ||
| 885 | schedule_delayed_work(&hdmi->edid_work, 0); | 958 | schedule_delayed_work(&hdmi->edid_work, 0); |
| 886 | 959 | } | |
| 887 | hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED; | ||
| 888 | /* display_off will switch back to mode_a */ | 960 | /* display_off will switch back to mode_a */ |
| 889 | } | 961 | } |
| 890 | } else if (status1 & 2) { | 962 | } else if (status1 & 2) { |
| 891 | /* EDID error interrupt: retry */ | 963 | /* EDID error interrupt: retry */ |
| 892 | /* Set EDID word address */ | 964 | /* Set EDID word address */ |
| 893 | hdmi_write(hdmi, 0x00, HDMI_EDID_WORD_ADDRESS); | 965 | hdmi_write(hdmi, hdmi->edid_block_addr, HDMI_EDID_WORD_ADDRESS); |
| 894 | /* Set EDID segment pointer */ | 966 | /* Set EDID segment pointer */ |
| 895 | hdmi_write(hdmi, 0x00, HDMI_EDID_SEGMENT_POINTER); | 967 | hdmi_write(hdmi, hdmi->edid_segment_nr, HDMI_EDID_SEGMENT_POINTER); |
| 896 | } else if (status1 & 4) { | 968 | } else if (status1 & 4) { |
| 897 | /* Disable EDID interrupt */ | 969 | /* Disable EDID interrupt */ |
| 898 | hdmi_write(hdmi, 0xC0, HDMI_INTERRUPT_MASK_1); | 970 | hdmi_write(hdmi, 0xC0, HDMI_INTERRUPT_MASK_1); |
| 899 | hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE; | ||
| 900 | schedule_delayed_work(&hdmi->edid_work, msecs_to_jiffies(10)); | 971 | schedule_delayed_work(&hdmi->edid_work, msecs_to_jiffies(10)); |
| 901 | } | 972 | } |
| 902 | 973 | ||
| @@ -979,39 +1050,37 @@ static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi) | |||
| 979 | 1050 | ||
| 980 | /** | 1051 | /** |
| 981 | * sh_hdmi_clk_configure() - set HDMI clock frequency and enable the clock | 1052 | * sh_hdmi_clk_configure() - set HDMI clock frequency and enable the clock |
| 982 | * @hdmi: driver context | 1053 | * @hdmi: driver context |
| 983 | * @pixclock: pixel clock period in picoseconds | 1054 | * @hdmi_rate: HDMI clock frequency in Hz |
| 984 | * return: configured positive rate if successful | 1055 | * @parent_rate: if != 0 - set parent clock rate for optimal precision |
| 985 | * 0 if couldn't set the rate, but managed to enable the clock | 1056 | * return: configured positive rate if successful |
| 986 | * negative error, if couldn't enable the clock | 1057 | * 0 if couldn't set the rate, but managed to enable the |
| 1058 | * clock, negative error, if couldn't enable the clock | ||
| 987 | */ | 1059 | */ |
| 988 | static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long pixclock) | 1060 | static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long hdmi_rate, |
| 1061 | unsigned long parent_rate) | ||
| 989 | { | 1062 | { |
| 990 | long rate; | ||
| 991 | int ret; | 1063 | int ret; |
| 992 | 1064 | ||
| 993 | rate = PICOS2KHZ(pixclock) * 1000; | 1065 | if (parent_rate && clk_get_parent(hdmi->hdmi_clk)) { |
| 994 | rate = clk_round_rate(hdmi->hdmi_clk, rate); | 1066 | ret = clk_set_rate(clk_get_parent(hdmi->hdmi_clk), parent_rate); |
| 995 | if (rate > 0) { | ||
| 996 | ret = clk_set_rate(hdmi->hdmi_clk, rate); | ||
| 997 | if (ret < 0) { | 1067 | if (ret < 0) { |
| 998 | dev_warn(hdmi->dev, "Cannot set rate %ld: %d\n", rate, ret); | 1068 | dev_warn(hdmi->dev, "Cannot set parent rate %ld: %d\n", parent_rate, ret); |
| 999 | rate = 0; | 1069 | hdmi_rate = clk_round_rate(hdmi->hdmi_clk, hdmi_rate); |
| 1000 | } else { | 1070 | } else { |
| 1001 | dev_dbg(hdmi->dev, "HDMI set frequency %lu\n", rate); | 1071 | dev_dbg(hdmi->dev, "HDMI set parent frequency %lu\n", parent_rate); |
| 1002 | } | 1072 | } |
| 1003 | } else { | ||
| 1004 | rate = 0; | ||
| 1005 | dev_warn(hdmi->dev, "Cannot get suitable rate: %ld\n", rate); | ||
| 1006 | } | 1073 | } |
| 1007 | 1074 | ||
| 1008 | ret = clk_enable(hdmi->hdmi_clk); | 1075 | ret = clk_set_rate(hdmi->hdmi_clk, hdmi_rate); |
| 1009 | if (ret < 0) { | 1076 | if (ret < 0) { |
| 1010 | dev_err(hdmi->dev, "Cannot enable clock: %d\n", ret); | 1077 | dev_warn(hdmi->dev, "Cannot set rate %ld: %d\n", hdmi_rate, ret); |
| 1011 | return ret; | 1078 | hdmi_rate = 0; |
| 1079 | } else { | ||
| 1080 | dev_dbg(hdmi->dev, "HDMI set frequency %lu\n", hdmi_rate); | ||
| 1012 | } | 1081 | } |
| 1013 | 1082 | ||
| 1014 | return rate; | 1083 | return hdmi_rate; |
| 1015 | } | 1084 | } |
| 1016 | 1085 | ||
| 1017 | /* Hotplug interrupt occurred, read EDID */ | 1086 | /* Hotplug interrupt occurred, read EDID */ |
| @@ -1030,17 +1099,20 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) | |||
| 1030 | 1099 | ||
| 1031 | mutex_lock(&hdmi->mutex); | 1100 | mutex_lock(&hdmi->mutex); |
| 1032 | 1101 | ||
| 1033 | if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) { | 1102 | if (hdmi->hp_state == HDMI_HOTPLUG_CONNECTED) { |
| 1103 | unsigned long parent_rate = 0, hdmi_rate; | ||
| 1104 | |||
| 1034 | /* A device has been plugged in */ | 1105 | /* A device has been plugged in */ |
| 1035 | pm_runtime_get_sync(hdmi->dev); | 1106 | pm_runtime_get_sync(hdmi->dev); |
| 1036 | 1107 | ||
| 1037 | ret = sh_hdmi_read_edid(hdmi); | 1108 | ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate); |
| 1038 | if (ret < 0) | 1109 | if (ret < 0) |
| 1039 | goto out; | 1110 | goto out; |
| 1040 | 1111 | ||
| 1112 | hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE; | ||
| 1113 | |||
| 1041 | /* Reconfigure the clock */ | 1114 | /* Reconfigure the clock */ |
| 1042 | clk_disable(hdmi->hdmi_clk); | 1115 | ret = sh_hdmi_clk_configure(hdmi, hdmi_rate, parent_rate); |
| 1043 | ret = sh_hdmi_clk_configure(hdmi, hdmi->var.pixclock); | ||
| 1044 | if (ret < 0) | 1116 | if (ret < 0) |
| 1045 | goto out; | 1117 | goto out; |
| 1046 | 1118 | ||
| @@ -1095,7 +1167,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) | |||
| 1095 | } | 1167 | } |
| 1096 | 1168 | ||
| 1097 | out: | 1169 | out: |
| 1098 | if (ret < 0) | 1170 | if (ret < 0 && ret != -EAGAIN) |
| 1099 | hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED; | 1171 | hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED; |
| 1100 | mutex_unlock(&hdmi->mutex); | 1172 | mutex_unlock(&hdmi->mutex); |
| 1101 | 1173 | ||
| @@ -1176,13 +1248,22 @@ static int __init sh_hdmi_probe(struct platform_device *pdev) | |||
| 1176 | goto egetclk; | 1248 | goto egetclk; |
| 1177 | } | 1249 | } |
| 1178 | 1250 | ||
| 1179 | /* Some arbitrary relaxed pixclock just to get things started */ | 1251 | /* An arbitrary relaxed pixclock just to get things started: from standard 480p */ |
| 1180 | rate = sh_hdmi_clk_configure(hdmi, 37037); | 1252 | rate = clk_round_rate(hdmi->hdmi_clk, PICOS2KHZ(37037)); |
| 1253 | if (rate > 0) | ||
| 1254 | rate = sh_hdmi_clk_configure(hdmi, rate, 0); | ||
| 1255 | |||
| 1181 | if (rate < 0) { | 1256 | if (rate < 0) { |
| 1182 | ret = rate; | 1257 | ret = rate; |
| 1183 | goto erate; | 1258 | goto erate; |
| 1184 | } | 1259 | } |
| 1185 | 1260 | ||
| 1261 | ret = clk_enable(hdmi->hdmi_clk); | ||
| 1262 | if (ret < 0) { | ||
| 1263 | dev_err(hdmi->dev, "Cannot enable clock: %d\n", ret); | ||
| 1264 | goto erate; | ||
| 1265 | } | ||
| 1266 | |||
| 1186 | dev_dbg(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate); | 1267 | dev_dbg(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate); |
| 1187 | 1268 | ||
| 1188 | if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) { | 1269 | if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) { |
| @@ -1200,10 +1281,6 @@ static int __init sh_hdmi_probe(struct platform_device *pdev) | |||
| 1200 | 1281 | ||
| 1201 | platform_set_drvdata(pdev, hdmi); | 1282 | platform_set_drvdata(pdev, hdmi); |
| 1202 | 1283 | ||
| 1203 | /* Product and revision IDs are 0 in sh-mobile version */ | ||
| 1204 | dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n", | ||
| 1205 | hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID)); | ||
| 1206 | |||
| 1207 | /* Set up LCDC callbacks */ | 1284 | /* Set up LCDC callbacks */ |
| 1208 | board_cfg = &pdata->lcd_chan->board_cfg; | 1285 | board_cfg = &pdata->lcd_chan->board_cfg; |
| 1209 | board_cfg->owner = THIS_MODULE; | 1286 | board_cfg->owner = THIS_MODULE; |
| @@ -1216,6 +1293,10 @@ static int __init sh_hdmi_probe(struct platform_device *pdev) | |||
| 1216 | pm_runtime_enable(&pdev->dev); | 1293 | pm_runtime_enable(&pdev->dev); |
| 1217 | pm_runtime_resume(&pdev->dev); | 1294 | pm_runtime_resume(&pdev->dev); |
| 1218 | 1295 | ||
| 1296 | /* Product and revision IDs are 0 in sh-mobile version */ | ||
| 1297 | dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n", | ||
| 1298 | hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID)); | ||
| 1299 | |||
| 1219 | ret = request_irq(irq, sh_hdmi_hotplug, 0, | 1300 | ret = request_irq(irq, sh_hdmi_hotplug, 0, |
| 1220 | dev_name(&pdev->dev), hdmi); | 1301 | dev_name(&pdev->dev), hdmi); |
| 1221 | if (ret < 0) { | 1302 | if (ret < 0) { |
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index c05326b61235..bd4840a8a6b7 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
| @@ -139,6 +139,7 @@ struct sh_mobile_lcdc_priv { | |||
| 139 | struct notifier_block notifier; | 139 | struct notifier_block notifier; |
| 140 | unsigned long saved_shared_regs[NR_SHARED_REGS]; | 140 | unsigned long saved_shared_regs[NR_SHARED_REGS]; |
| 141 | int started; | 141 | int started; |
| 142 | int forced_bpp; /* 2 channel LCDC must share bpp setting */ | ||
| 142 | }; | 143 | }; |
| 143 | 144 | ||
| 144 | static bool banked(int reg_nr) | 145 | static bool banked(int reg_nr) |
| @@ -461,13 +462,18 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
| 461 | struct sh_mobile_lcdc_chan *ch; | 462 | struct sh_mobile_lcdc_chan *ch; |
| 462 | struct sh_mobile_lcdc_board_cfg *board_cfg; | 463 | struct sh_mobile_lcdc_board_cfg *board_cfg; |
| 463 | unsigned long tmp; | 464 | unsigned long tmp; |
| 465 | int bpp = 0; | ||
| 464 | int k, m; | 466 | int k, m; |
| 465 | int ret = 0; | 467 | int ret = 0; |
| 466 | 468 | ||
| 467 | /* enable clocks before accessing the hardware */ | 469 | /* enable clocks before accessing the hardware */ |
| 468 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) | 470 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { |
| 469 | if (priv->ch[k].enabled) | 471 | if (priv->ch[k].enabled) { |
| 470 | sh_mobile_lcdc_clk_on(priv); | 472 | sh_mobile_lcdc_clk_on(priv); |
| 473 | if (!bpp) | ||
| 474 | bpp = priv->ch[k].info->var.bits_per_pixel; | ||
| 475 | } | ||
| 476 | } | ||
| 471 | 477 | ||
| 472 | /* reset */ | 478 | /* reset */ |
| 473 | lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET); | 479 | lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET); |
| @@ -535,7 +541,17 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
| 535 | } | 541 | } |
| 536 | 542 | ||
| 537 | /* word and long word swap */ | 543 | /* word and long word swap */ |
| 538 | lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6); | 544 | switch (bpp) { |
| 545 | case 16: | ||
| 546 | lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6); | ||
| 547 | break; | ||
| 548 | case 24: | ||
| 549 | lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 7); | ||
| 550 | break; | ||
| 551 | case 32: | ||
| 552 | lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 4); | ||
| 553 | break; | ||
| 554 | } | ||
| 539 | 555 | ||
| 540 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { | 556 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { |
| 541 | ch = &priv->ch[k]; | 557 | ch = &priv->ch[k]; |
| @@ -546,7 +562,16 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
| 546 | /* set bpp format in PKF[4:0] */ | 562 | /* set bpp format in PKF[4:0] */ |
| 547 | tmp = lcdc_read_chan(ch, LDDFR); | 563 | tmp = lcdc_read_chan(ch, LDDFR); |
| 548 | tmp &= ~0x0001001f; | 564 | tmp &= ~0x0001001f; |
| 549 | tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0; | 565 | switch (ch->info->var.bits_per_pixel) { |
| 566 | case 16: | ||
| 567 | tmp |= 0x03; | ||
| 568 | break; | ||
| 569 | case 24: | ||
| 570 | tmp |= 0x0b; | ||
| 571 | break; | ||
| 572 | case 32: | ||
| 573 | break; | ||
| 574 | } | ||
| 550 | lcdc_write_chan(ch, LDDFR, tmp); | 575 | lcdc_write_chan(ch, LDDFR, tmp); |
| 551 | 576 | ||
| 552 | /* point out our frame buffer */ | 577 | /* point out our frame buffer */ |
| @@ -913,15 +938,30 @@ static int sh_mobile_open(struct fb_info *info, int user) | |||
| 913 | static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 938 | static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
| 914 | { | 939 | { |
| 915 | struct sh_mobile_lcdc_chan *ch = info->par; | 940 | struct sh_mobile_lcdc_chan *ch = info->par; |
| 941 | struct sh_mobile_lcdc_priv *p = ch->lcdc; | ||
| 916 | 942 | ||
| 917 | if (var->xres > MAX_XRES || var->yres > MAX_YRES || | 943 | if (var->xres > MAX_XRES || var->yres > MAX_YRES || |
| 918 | var->xres * var->yres * (ch->cfg.bpp / 8) * 2 > info->fix.smem_len) { | 944 | var->xres * var->yres * (ch->cfg.bpp / 8) * 2 > info->fix.smem_len) { |
| 919 | dev_warn(info->dev, "Invalid info: %u-%u-%u-%u x %u-%u-%u-%u @ %ukHz!\n", | 945 | dev_warn(info->dev, "Invalid info: %u-%u-%u-%u x %u-%u-%u-%u @ %lukHz!\n", |
| 920 | var->left_margin, var->xres, var->right_margin, var->hsync_len, | 946 | var->left_margin, var->xres, var->right_margin, var->hsync_len, |
| 921 | var->upper_margin, var->yres, var->lower_margin, var->vsync_len, | 947 | var->upper_margin, var->yres, var->lower_margin, var->vsync_len, |
| 922 | PICOS2KHZ(var->pixclock)); | 948 | PICOS2KHZ(var->pixclock)); |
| 923 | return -EINVAL; | 949 | return -EINVAL; |
| 924 | } | 950 | } |
| 951 | |||
| 952 | /* only accept the forced_bpp for dual channel configurations */ | ||
| 953 | if (p->forced_bpp && p->forced_bpp != var->bits_per_pixel) | ||
| 954 | return -EINVAL; | ||
| 955 | |||
| 956 | switch (var->bits_per_pixel) { | ||
| 957 | case 16: /* PKF[4:0] = 00011 - RGB 565 */ | ||
| 958 | case 24: /* PKF[4:0] = 01011 - RGB 888 */ | ||
| 959 | case 32: /* PKF[4:0] = 00000 - RGBA 888 */ | ||
| 960 | break; | ||
| 961 | default: | ||
| 962 | return -EINVAL; | ||
| 963 | } | ||
| 964 | |||
| 925 | return 0; | 965 | return 0; |
| 926 | } | 966 | } |
| 927 | 967 | ||
| @@ -954,19 +994,27 @@ static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) | |||
| 954 | var->transp.length = 0; | 994 | var->transp.length = 0; |
| 955 | break; | 995 | break; |
| 956 | 996 | ||
| 957 | case 32: /* PKF[4:0] = 00000 - RGB 888 | 997 | case 24: /* PKF[4:0] = 01011 - RGB 888 */ |
| 958 | * sh7722 pdf says 00RRGGBB but reality is GGBB00RR | 998 | var->red.offset = 16; |
| 959 | * this may be because LDDDSR has word swap enabled.. | ||
| 960 | */ | ||
| 961 | var->red.offset = 0; | ||
| 962 | var->red.length = 8; | 999 | var->red.length = 8; |
| 963 | var->green.offset = 24; | 1000 | var->green.offset = 8; |
| 964 | var->green.length = 8; | 1001 | var->green.length = 8; |
| 965 | var->blue.offset = 16; | 1002 | var->blue.offset = 0; |
| 966 | var->blue.length = 8; | 1003 | var->blue.length = 8; |
| 967 | var->transp.offset = 0; | 1004 | var->transp.offset = 0; |
| 968 | var->transp.length = 0; | 1005 | var->transp.length = 0; |
| 969 | break; | 1006 | break; |
| 1007 | |||
| 1008 | case 32: /* PKF[4:0] = 00000 - RGBA 888 */ | ||
| 1009 | var->red.offset = 16; | ||
| 1010 | var->red.length = 8; | ||
| 1011 | var->green.offset = 8; | ||
| 1012 | var->green.length = 8; | ||
| 1013 | var->blue.offset = 0; | ||
| 1014 | var->blue.length = 8; | ||
| 1015 | var->transp.offset = 24; | ||
| 1016 | var->transp.length = 8; | ||
| 1017 | break; | ||
| 970 | default: | 1018 | default: |
| 971 | return -EINVAL; | 1019 | return -EINVAL; |
| 972 | } | 1020 | } |
| @@ -1170,6 +1218,10 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
| 1170 | goto err1; | 1218 | goto err1; |
| 1171 | } | 1219 | } |
| 1172 | 1220 | ||
| 1221 | /* for dual channel LCDC (MAIN + SUB) force shared bpp setting */ | ||
| 1222 | if (j == 2) | ||
| 1223 | priv->forced_bpp = pdata->ch[0].bpp; | ||
| 1224 | |||
| 1173 | priv->base = ioremap_nocache(res->start, resource_size(res)); | 1225 | priv->base = ioremap_nocache(res->start, resource_size(res)); |
| 1174 | if (!priv->base) | 1226 | if (!priv->base) |
| 1175 | goto err1; | 1227 | goto err1; |
diff --git a/drivers/video/sis/init.c b/drivers/video/sis/init.c index 31137adc8fba..66de832361cc 100644 --- a/drivers/video/sis/init.c +++ b/drivers/video/sis/init.c | |||
| @@ -56,10 +56,6 @@ | |||
| 56 | * Used by permission. | 56 | * Used by permission. |
| 57 | */ | 57 | */ |
| 58 | 58 | ||
| 59 | #ifdef HAVE_CONFIG_H | ||
| 60 | #include "config.h" | ||
| 61 | #endif | ||
| 62 | |||
| 63 | #include "init.h" | 59 | #include "init.h" |
| 64 | 60 | ||
| 65 | #ifdef CONFIG_FB_SIS_300 | 61 | #ifdef CONFIG_FB_SIS_300 |
| @@ -880,59 +876,59 @@ SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDispl | |||
| 880 | /*********************************************/ | 876 | /*********************************************/ |
| 881 | 877 | ||
| 882 | void | 878 | void |
| 883 | SiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data) | 879 | SiS_SetReg(SISIOADDRESS port, u8 index, u8 data) |
| 884 | { | 880 | { |
| 885 | outb((u8)index, port); | 881 | outb(index, port); |
| 886 | outb((u8)data, port + 1); | 882 | outb(data, port + 1); |
| 887 | } | 883 | } |
| 888 | 884 | ||
| 889 | void | 885 | void |
| 890 | SiS_SetRegByte(SISIOADDRESS port, unsigned short data) | 886 | SiS_SetRegByte(SISIOADDRESS port, u8 data) |
| 891 | { | 887 | { |
| 892 | outb((u8)data, port); | 888 | outb(data, port); |
| 893 | } | 889 | } |
| 894 | 890 | ||
| 895 | void | 891 | void |
| 896 | SiS_SetRegShort(SISIOADDRESS port, unsigned short data) | 892 | SiS_SetRegShort(SISIOADDRESS port, u16 data) |
| 897 | { | 893 | { |
| 898 | outw((u16)data, port); | 894 | outw(data, port); |
| 899 | } | 895 | } |
| 900 | 896 | ||
| 901 | void | 897 | void |
| 902 | SiS_SetRegLong(SISIOADDRESS port, unsigned int data) | 898 | SiS_SetRegLong(SISIOADDRESS port, u32 data) |
| 903 | { | 899 | { |
| 904 | outl((u32)data, port); | 900 | outl(data, port); |
| 905 | } | 901 | } |
| 906 | 902 | ||
| 907 | unsigned char | 903 | u8 |
| 908 | SiS_GetReg(SISIOADDRESS port, unsigned short index) | 904 | SiS_GetReg(SISIOADDRESS port, u8 index) |
| 909 | { | 905 | { |
| 910 | outb((u8)index, port); | 906 | outb(index, port); |
| 911 | return inb(port + 1); | 907 | return inb(port + 1); |
| 912 | } | 908 | } |
| 913 | 909 | ||
| 914 | unsigned char | 910 | u8 |
| 915 | SiS_GetRegByte(SISIOADDRESS port) | 911 | SiS_GetRegByte(SISIOADDRESS port) |
| 916 | { | 912 | { |
| 917 | return inb(port); | 913 | return inb(port); |
| 918 | } | 914 | } |
| 919 | 915 | ||
| 920 | unsigned short | 916 | u16 |
| 921 | SiS_GetRegShort(SISIOADDRESS port) | 917 | SiS_GetRegShort(SISIOADDRESS port) |
| 922 | { | 918 | { |
| 923 | return inw(port); | 919 | return inw(port); |
| 924 | } | 920 | } |
| 925 | 921 | ||
| 926 | unsigned int | 922 | u32 |
| 927 | SiS_GetRegLong(SISIOADDRESS port) | 923 | SiS_GetRegLong(SISIOADDRESS port) |
| 928 | { | 924 | { |
| 929 | return inl(port); | 925 | return inl(port); |
| 930 | } | 926 | } |
| 931 | 927 | ||
| 932 | void | 928 | void |
| 933 | SiS_SetRegANDOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND, unsigned short DataOR) | 929 | SiS_SetRegANDOR(SISIOADDRESS Port, u8 Index, u8 DataAND, u8 DataOR) |
| 934 | { | 930 | { |
| 935 | unsigned short temp; | 931 | u8 temp; |
| 936 | 932 | ||
| 937 | temp = SiS_GetReg(Port, Index); | 933 | temp = SiS_GetReg(Port, Index); |
| 938 | temp = (temp & (DataAND)) | DataOR; | 934 | temp = (temp & (DataAND)) | DataOR; |
| @@ -940,9 +936,9 @@ SiS_SetRegANDOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND, | |||
| 940 | } | 936 | } |
| 941 | 937 | ||
| 942 | void | 938 | void |
| 943 | SiS_SetRegAND(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND) | 939 | SiS_SetRegAND(SISIOADDRESS Port, u8 Index, u8 DataAND) |
| 944 | { | 940 | { |
| 945 | unsigned short temp; | 941 | u8 temp; |
| 946 | 942 | ||
| 947 | temp = SiS_GetReg(Port, Index); | 943 | temp = SiS_GetReg(Port, Index); |
| 948 | temp &= DataAND; | 944 | temp &= DataAND; |
| @@ -950,9 +946,9 @@ SiS_SetRegAND(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND) | |||
| 950 | } | 946 | } |
| 951 | 947 | ||
| 952 | void | 948 | void |
| 953 | SiS_SetRegOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataOR) | 949 | SiS_SetRegOR(SISIOADDRESS Port, u8 Index, u8 DataOR) |
| 954 | { | 950 | { |
| 955 | unsigned short temp; | 951 | u8 temp; |
| 956 | 952 | ||
| 957 | temp = SiS_GetReg(Port, Index); | 953 | temp = SiS_GetReg(Port, Index); |
| 958 | temp |= DataOR; | 954 | temp |= DataOR; |
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h index ee8ed3c203da..aff73842d877 100644 --- a/drivers/video/sis/init.h +++ b/drivers/video/sis/init.h | |||
| @@ -1516,19 +1516,6 @@ unsigned short SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDispla | |||
| 1516 | unsigned short SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, | 1516 | unsigned short SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, |
| 1517 | int VDisplay, int Depth, unsigned int VBFlags2); | 1517 | int VDisplay, int Depth, unsigned int VBFlags2); |
| 1518 | 1518 | ||
| 1519 | void SiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data); | ||
| 1520 | void SiS_SetRegByte(SISIOADDRESS port, unsigned short data); | ||
| 1521 | void SiS_SetRegShort(SISIOADDRESS port, unsigned short data); | ||
| 1522 | void SiS_SetRegLong(SISIOADDRESS port, unsigned int data); | ||
| 1523 | unsigned char SiS_GetReg(SISIOADDRESS port, unsigned short index); | ||
| 1524 | unsigned char SiS_GetRegByte(SISIOADDRESS port); | ||
| 1525 | unsigned short SiS_GetRegShort(SISIOADDRESS port); | ||
| 1526 | unsigned int SiS_GetRegLong(SISIOADDRESS port); | ||
| 1527 | void SiS_SetRegANDOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND, | ||
| 1528 | unsigned short DataOR); | ||
| 1529 | void SiS_SetRegAND(SISIOADDRESS Port,unsigned short Index, unsigned short DataAND); | ||
| 1530 | void SiS_SetRegOR(SISIOADDRESS Port,unsigned short Index, unsigned short DataOR); | ||
| 1531 | |||
| 1532 | void SiS_DisplayOn(struct SiS_Private *SiS_Pr); | 1519 | void SiS_DisplayOn(struct SiS_Private *SiS_Pr); |
| 1533 | void SiS_DisplayOff(struct SiS_Private *SiS_Pr); | 1520 | void SiS_DisplayOff(struct SiS_Private *SiS_Pr); |
| 1534 | void SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr); | 1521 | void SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr); |
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c index 9fa66fd4052a..a89e3cafd5ad 100644 --- a/drivers/video/sis/init301.c +++ b/drivers/video/sis/init301.c | |||
| @@ -57,10 +57,6 @@ | |||
| 57 | * | 57 | * |
| 58 | */ | 58 | */ |
| 59 | 59 | ||
| 60 | #ifdef HAVE_CONFIG_H | ||
| 61 | #include "config.h" | ||
| 62 | #endif | ||
| 63 | |||
| 64 | #if 1 | 60 | #if 1 |
| 65 | #define SET_EMI /* 302LV/ELV: Set EMI values */ | 61 | #define SET_EMI /* 302LV/ELV: Set EMI values */ |
| 66 | #endif | 62 | #endif |
| @@ -5856,7 +5852,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
| 5856 | temp = tempax & 0x00FF; | 5852 | temp = tempax & 0x00FF; |
| 5857 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp); | 5853 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp); |
| 5858 | temp = ((tempax & 0xFF00) >> 8) << 3; | 5854 | temp = ((tempax & 0xFF00) >> 8) << 3; |
| 5859 | SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp); | 5855 | SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp); |
| 5860 | 5856 | ||
| 5861 | tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */ | 5857 | tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */ |
| 5862 | if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || | 5858 | if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || |
| @@ -5870,7 +5866,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
| 5870 | temp = ((tempeax & 0xFF0000) >> 16) | 0x10; | 5866 | temp = ((tempeax & 0xFF0000) >> 16) | 0x10; |
| 5871 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp); | 5867 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp); |
| 5872 | temp = ((tempeax & 0x01000000) >> 24) << 7; | 5868 | temp = ((tempeax & 0x01000000) >> 24) << 7; |
| 5873 | SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp); | 5869 | SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp); |
| 5874 | 5870 | ||
| 5875 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03); | 5871 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03); |
| 5876 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50); | 5872 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50); |
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h index e1fd31d0fddf..2112d6d7feda 100644 --- a/drivers/video/sis/init301.h +++ b/drivers/video/sis/init301.h | |||
| @@ -428,17 +428,6 @@ static void SiS_OEM661Setting(struct SiS_Private *SiS_Pr, | |||
| 428 | static void SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short); | 428 | static void SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short); |
| 429 | #endif | 429 | #endif |
| 430 | 430 | ||
| 431 | extern void SiS_SetReg(SISIOADDRESS, unsigned short, unsigned short); | ||
| 432 | extern void SiS_SetRegByte(SISIOADDRESS, unsigned short); | ||
| 433 | extern void SiS_SetRegShort(SISIOADDRESS, unsigned short); | ||
| 434 | extern void SiS_SetRegLong(SISIOADDRESS, unsigned int); | ||
| 435 | extern unsigned char SiS_GetReg(SISIOADDRESS, unsigned short); | ||
| 436 | extern unsigned char SiS_GetRegByte(SISIOADDRESS); | ||
| 437 | extern unsigned short SiS_GetRegShort(SISIOADDRESS); | ||
| 438 | extern unsigned int SiS_GetRegLong(SISIOADDRESS); | ||
| 439 | extern void SiS_SetRegANDOR(SISIOADDRESS, unsigned short, unsigned short, unsigned short); | ||
| 440 | extern void SiS_SetRegOR(SISIOADDRESS, unsigned short, unsigned short); | ||
| 441 | extern void SiS_SetRegAND(SISIOADDRESS, unsigned short, unsigned short); | ||
| 442 | extern void SiS_DisplayOff(struct SiS_Private *SiS_Pr); | 431 | extern void SiS_DisplayOff(struct SiS_Private *SiS_Pr); |
| 443 | extern void SiS_DisplayOn(struct SiS_Private *SiS_Pr); | 432 | extern void SiS_DisplayOn(struct SiS_Private *SiS_Pr); |
| 444 | extern bool SiS_SearchModeID(struct SiS_Private *, unsigned short *, unsigned short *); | 433 | extern bool SiS_SearchModeID(struct SiS_Private *, unsigned short *, unsigned short *); |
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h index 80d89d37c414..eac7a01925f3 100644 --- a/drivers/video/sis/sis.h +++ b/drivers/video/sis/sis.h | |||
| @@ -307,58 +307,19 @@ | |||
| 307 | #define VB2_LCDOVER1600BRIDGE (VB2_307T | VB2_307LV) | 307 | #define VB2_LCDOVER1600BRIDGE (VB2_307T | VB2_307LV) |
| 308 | #define VB2_RAMDAC202MHZBRIDGE (VB2_301C | VB2_307T) | 308 | #define VB2_RAMDAC202MHZBRIDGE (VB2_301C | VB2_307T) |
| 309 | 309 | ||
| 310 | /* I/O port access macros */ | 310 | /* I/O port access functions */ |
| 311 | #define inSISREG(base) inb(base) | 311 | |
| 312 | 312 | void SiS_SetReg(SISIOADDRESS, u8, u8); | |
| 313 | #define outSISREG(base,val) outb(val,base) | 313 | void SiS_SetRegByte(SISIOADDRESS, u8); |
| 314 | 314 | void SiS_SetRegShort(SISIOADDRESS, u16); | |
| 315 | #define orSISREG(base,val) \ | 315 | void SiS_SetRegLong(SISIOADDRESS, u32); |
| 316 | do { \ | 316 | void SiS_SetRegANDOR(SISIOADDRESS, u8, u8, u8); |
| 317 | u8 __Temp = inSISREG(base); \ | 317 | void SiS_SetRegAND(SISIOADDRESS, u8, u8); |
| 318 | outSISREG(base, __Temp | (val));\ | 318 | void SiS_SetRegOR(SISIOADDRESS, u8, u8); |
| 319 | } while (0) | 319 | u8 SiS_GetReg(SISIOADDRESS, u8); |
| 320 | 320 | u8 SiS_GetRegByte(SISIOADDRESS); | |
| 321 | #define andSISREG(base,val) \ | 321 | u16 SiS_GetRegShort(SISIOADDRESS); |
| 322 | do { \ | 322 | u32 SiS_GetRegLong(SISIOADDRESS); |
| 323 | u8 __Temp = inSISREG(base); \ | ||
| 324 | outSISREG(base, __Temp & (val));\ | ||
| 325 | } while (0) | ||
| 326 | |||
| 327 | #define inSISIDXREG(base,idx,var) \ | ||
| 328 | do { \ | ||
| 329 | outSISREG(base, idx); \ | ||
| 330 | var = inSISREG((base)+1); \ | ||
| 331 | } while (0) | ||
| 332 | |||
| 333 | #define outSISIDXREG(base,idx,val) \ | ||
| 334 | do { \ | ||
| 335 | outSISREG(base, idx); \ | ||
| 336 | outSISREG((base)+1, val); \ | ||
| 337 | } while (0) | ||
| 338 | |||
| 339 | #define orSISIDXREG(base,idx,val) \ | ||
| 340 | do { \ | ||
| 341 | u8 __Temp; \ | ||
| 342 | outSISREG(base, idx); \ | ||
| 343 | __Temp = inSISREG((base)+1) | (val); \ | ||
| 344 | outSISREG((base)+1, __Temp); \ | ||
| 345 | } while (0) | ||
| 346 | |||
| 347 | #define andSISIDXREG(base,idx,and) \ | ||
| 348 | do { \ | ||
| 349 | u8 __Temp; \ | ||
| 350 | outSISREG(base, idx); \ | ||
| 351 | __Temp = inSISREG((base)+1) & (and); \ | ||
| 352 | outSISREG((base)+1, __Temp); \ | ||
| 353 | } while (0) | ||
| 354 | |||
| 355 | #define setSISIDXREG(base,idx,and,or) \ | ||
| 356 | do { \ | ||
| 357 | u8 __Temp; \ | ||
| 358 | outSISREG(base, idx); \ | ||
| 359 | __Temp = (inSISREG((base)+1) & (and)) | (or); \ | ||
| 360 | outSISREG((base)+1, __Temp); \ | ||
| 361 | } while (0) | ||
| 362 | 323 | ||
| 363 | /* MMIO access macros */ | 324 | /* MMIO access macros */ |
| 364 | #define MMIO_IN8(base, offset) readb((base+offset)) | 325 | #define MMIO_IN8(base, offset) readb((base+offset)) |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 7e3370f115b6..2fb8c5a660fb 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
| @@ -737,7 +737,7 @@ sisfb_bridgeisslave(struct sis_video_info *ivideo) | |||
| 737 | if(!(ivideo->vbflags2 & VB2_VIDEOBRIDGE)) | 737 | if(!(ivideo->vbflags2 & VB2_VIDEOBRIDGE)) |
| 738 | return false; | 738 | return false; |
| 739 | 739 | ||
| 740 | inSISIDXREG(SISPART1,0x00,P1_00); | 740 | P1_00 = SiS_GetReg(SISPART1, 0x00); |
| 741 | if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) || | 741 | if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) || |
| 742 | ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) { | 742 | ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) { |
| 743 | return true; | 743 | return true; |
| @@ -751,11 +751,11 @@ sisfballowretracecrt1(struct sis_video_info *ivideo) | |||
| 751 | { | 751 | { |
| 752 | u8 temp; | 752 | u8 temp; |
| 753 | 753 | ||
| 754 | inSISIDXREG(SISCR,0x17,temp); | 754 | temp = SiS_GetReg(SISCR, 0x17); |
| 755 | if(!(temp & 0x80)) | 755 | if(!(temp & 0x80)) |
| 756 | return false; | 756 | return false; |
| 757 | 757 | ||
| 758 | inSISIDXREG(SISSR,0x1f,temp); | 758 | temp = SiS_GetReg(SISSR, 0x1f); |
| 759 | if(temp & 0xc0) | 759 | if(temp & 0xc0) |
| 760 | return false; | 760 | return false; |
| 761 | 761 | ||
| @@ -768,7 +768,7 @@ sisfbcheckvretracecrt1(struct sis_video_info *ivideo) | |||
| 768 | if(!sisfballowretracecrt1(ivideo)) | 768 | if(!sisfballowretracecrt1(ivideo)) |
| 769 | return false; | 769 | return false; |
| 770 | 770 | ||
| 771 | if(inSISREG(SISINPSTAT) & 0x08) | 771 | if (SiS_GetRegByte(SISINPSTAT) & 0x08) |
| 772 | return true; | 772 | return true; |
| 773 | else | 773 | else |
| 774 | return false; | 774 | return false; |
| @@ -783,9 +783,9 @@ sisfbwaitretracecrt1(struct sis_video_info *ivideo) | |||
| 783 | return; | 783 | return; |
| 784 | 784 | ||
| 785 | watchdog = 65536; | 785 | watchdog = 65536; |
| 786 | while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog); | 786 | while ((!(SiS_GetRegByte(SISINPSTAT) & 0x08)) && --watchdog); |
| 787 | watchdog = 65536; | 787 | watchdog = 65536; |
| 788 | while((inSISREG(SISINPSTAT) & 0x08) && --watchdog); | 788 | while ((SiS_GetRegByte(SISINPSTAT) & 0x08) && --watchdog); |
| 789 | } | 789 | } |
| 790 | 790 | ||
| 791 | static bool | 791 | static bool |
| @@ -799,7 +799,7 @@ sisfbcheckvretracecrt2(struct sis_video_info *ivideo) | |||
| 799 | default: return false; | 799 | default: return false; |
| 800 | } | 800 | } |
| 801 | 801 | ||
| 802 | inSISIDXREG(SISPART1, reg, temp); | 802 | temp = SiS_GetReg(SISPART1, reg); |
| 803 | if(temp & 0x02) | 803 | if(temp & 0x02) |
| 804 | return true; | 804 | return true; |
| 805 | else | 805 | else |
| @@ -837,10 +837,10 @@ sisfb_setupvbblankflags(struct sis_video_info *ivideo, u32 *vcount, u32 *hcount) | |||
| 837 | default: | 837 | default: |
| 838 | case SIS_315_VGA: idx = 0x30; break; | 838 | case SIS_315_VGA: idx = 0x30; break; |
| 839 | } | 839 | } |
| 840 | inSISIDXREG(SISPART1,(idx+0),reg1); /* 30 */ | 840 | reg1 = SiS_GetReg(SISPART1, (idx+0)); /* 30 */ |
| 841 | inSISIDXREG(SISPART1,(idx+1),reg2); /* 31 */ | 841 | reg2 = SiS_GetReg(SISPART1, (idx+1)); /* 31 */ |
| 842 | inSISIDXREG(SISPART1,(idx+2),reg3); /* 32 */ | 842 | reg3 = SiS_GetReg(SISPART1, (idx+2)); /* 32 */ |
| 843 | inSISIDXREG(SISPART1,(idx+3),reg4); /* 33 */ | 843 | reg4 = SiS_GetReg(SISPART1, (idx+3)); /* 33 */ |
| 844 | if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING; | 844 | if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING; |
| 845 | if(reg1 & 0x02) ret |= FB_VBLANK_VSYNCING; | 845 | if(reg1 & 0x02) ret |= FB_VBLANK_VSYNCING; |
| 846 | if(reg4 & 0x80) ret |= FB_VBLANK_HBLANKING; | 846 | if(reg4 & 0x80) ret |= FB_VBLANK_HBLANKING; |
| @@ -853,13 +853,13 @@ sisfb_setupvbblankflags(struct sis_video_info *ivideo, u32 *vcount, u32 *hcount) | |||
| 853 | FB_VBLANK_HAVE_VBLANK | | 853 | FB_VBLANK_HAVE_VBLANK | |
| 854 | FB_VBLANK_HAVE_VCOUNT | | 854 | FB_VBLANK_HAVE_VCOUNT | |
| 855 | FB_VBLANK_HAVE_HCOUNT); | 855 | FB_VBLANK_HAVE_HCOUNT); |
| 856 | reg1 = inSISREG(SISINPSTAT); | 856 | reg1 = SiS_GetRegByte(SISINPSTAT); |
| 857 | if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING; | 857 | if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING; |
| 858 | if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING; | 858 | if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING; |
| 859 | inSISIDXREG(SISCR,0x20,reg1); | 859 | reg1 = SiS_GetReg(SISCR, 0x20); |
| 860 | inSISIDXREG(SISCR,0x1b,reg1); | 860 | reg1 = SiS_GetReg(SISCR, 0x1b); |
| 861 | inSISIDXREG(SISCR,0x1c,reg2); | 861 | reg2 = SiS_GetReg(SISCR, 0x1c); |
| 862 | inSISIDXREG(SISCR,0x1d,reg3); | 862 | reg3 = SiS_GetReg(SISCR, 0x1d); |
| 863 | (*vcount) = reg2 | ((reg3 & 0x07) << 8); | 863 | (*vcount) = reg2 | ((reg3 & 0x07) << 8); |
| 864 | (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3; | 864 | (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3; |
| 865 | } | 865 | } |
| @@ -930,12 +930,12 @@ sisfb_myblank(struct sis_video_info *ivideo, int blank) | |||
| 930 | (ivideo->sisfb_thismonitor.feature & 0xe0))) { | 930 | (ivideo->sisfb_thismonitor.feature & 0xe0))) { |
| 931 | 931 | ||
| 932 | if(ivideo->sisvga_engine == SIS_315_VGA) { | 932 | if(ivideo->sisvga_engine == SIS_315_VGA) { |
| 933 | setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63); | 933 | SiS_SetRegANDOR(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63); |
| 934 | } | 934 | } |
| 935 | 935 | ||
| 936 | if(!(sisfb_bridgeisslave(ivideo))) { | 936 | if(!(sisfb_bridgeisslave(ivideo))) { |
| 937 | setSISIDXREG(SISSR, 0x01, ~0x20, sr01); | 937 | SiS_SetRegANDOR(SISSR, 0x01, ~0x20, sr01); |
| 938 | setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f); | 938 | SiS_SetRegANDOR(SISSR, 0x1f, 0x3f, sr1f); |
| 939 | } | 939 | } |
| 940 | } | 940 | } |
| 941 | 941 | ||
| @@ -965,25 +965,25 @@ sisfb_myblank(struct sis_video_info *ivideo, int blank) | |||
| 965 | (ivideo->vbflags2 & (VB2_301|VB2_30xBDH|VB2_LVDS))) || | 965 | (ivideo->vbflags2 & (VB2_301|VB2_30xBDH|VB2_LVDS))) || |
| 966 | ((ivideo->sisvga_engine == SIS_315_VGA) && | 966 | ((ivideo->sisvga_engine == SIS_315_VGA) && |
| 967 | ((ivideo->vbflags2 & (VB2_LVDS | VB2_CHRONTEL)) == VB2_LVDS))) { | 967 | ((ivideo->vbflags2 & (VB2_LVDS | VB2_CHRONTEL)) == VB2_LVDS))) { |
| 968 | setSISIDXREG(SISSR, 0x11, ~0x0c, sr11); | 968 | SiS_SetRegANDOR(SISSR, 0x11, ~0x0c, sr11); |
| 969 | } | 969 | } |
| 970 | 970 | ||
| 971 | if(ivideo->sisvga_engine == SIS_300_VGA) { | 971 | if(ivideo->sisvga_engine == SIS_300_VGA) { |
| 972 | if((ivideo->vbflags2 & VB2_30xB) && | 972 | if((ivideo->vbflags2 & VB2_30xB) && |
| 973 | (!(ivideo->vbflags2 & VB2_30xBDH))) { | 973 | (!(ivideo->vbflags2 & VB2_30xBDH))) { |
| 974 | setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13); | 974 | SiS_SetRegANDOR(SISPART1, 0x13, 0x3f, p1_13); |
| 975 | } | 975 | } |
| 976 | } else if(ivideo->sisvga_engine == SIS_315_VGA) { | 976 | } else if(ivideo->sisvga_engine == SIS_315_VGA) { |
| 977 | if((ivideo->vbflags2 & VB2_30xB) && | 977 | if((ivideo->vbflags2 & VB2_30xB) && |
| 978 | (!(ivideo->vbflags2 & VB2_30xBDH))) { | 978 | (!(ivideo->vbflags2 & VB2_30xBDH))) { |
| 979 | setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0); | 979 | SiS_SetRegANDOR(SISPART2, 0x00, 0x1f, p2_0); |
| 980 | } | 980 | } |
| 981 | } | 981 | } |
| 982 | 982 | ||
| 983 | } else if(ivideo->currentvbflags & CRT2_VGA) { | 983 | } else if(ivideo->currentvbflags & CRT2_VGA) { |
| 984 | 984 | ||
| 985 | if(ivideo->vbflags2 & VB2_30xB) { | 985 | if(ivideo->vbflags2 & VB2_30xB) { |
| 986 | setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0); | 986 | SiS_SetRegANDOR(SISPART2, 0x00, 0x1f, p2_0); |
| 987 | } | 987 | } |
| 988 | 988 | ||
| 989 | } | 989 | } |
| @@ -1114,15 +1114,15 @@ sisfb_set_pitch(struct sis_video_info *ivideo) | |||
| 1114 | 1114 | ||
| 1115 | /* We need to set pitch for CRT1 if bridge is in slave mode, too */ | 1115 | /* We need to set pitch for CRT1 if bridge is in slave mode, too */ |
| 1116 | if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) { | 1116 | if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) { |
| 1117 | outSISIDXREG(SISCR,0x13,(HDisplay1 & 0xFF)); | 1117 | SiS_SetReg(SISCR, 0x13, (HDisplay1 & 0xFF)); |
| 1118 | setSISIDXREG(SISSR,0x0E,0xF0,(HDisplay1 >> 8)); | 1118 | SiS_SetRegANDOR(SISSR, 0x0E, 0xF0, (HDisplay1 >> 8)); |
| 1119 | } | 1119 | } |
| 1120 | 1120 | ||
| 1121 | /* We must not set the pitch for CRT2 if bridge is in slave mode */ | 1121 | /* We must not set the pitch for CRT2 if bridge is in slave mode */ |
| 1122 | if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) { | 1122 | if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) { |
| 1123 | orSISIDXREG(SISPART1,ivideo->CRT2_write_enable,0x01); | 1123 | SiS_SetRegOR(SISPART1, ivideo->CRT2_write_enable, 0x01); |
| 1124 | outSISIDXREG(SISPART1,0x07,(HDisplay2 & 0xFF)); | 1124 | SiS_SetReg(SISPART1, 0x07, (HDisplay2 & 0xFF)); |
| 1125 | setSISIDXREG(SISPART1,0x09,0xF0,(HDisplay2 >> 8)); | 1125 | SiS_SetRegANDOR(SISPART1, 0x09, 0xF0, (HDisplay2 >> 8)); |
| 1126 | } | 1126 | } |
| 1127 | } | 1127 | } |
| 1128 | 1128 | ||
| @@ -1167,7 +1167,7 @@ sisfb_set_mode(struct sis_video_info *ivideo, int clrscrn) | |||
| 1167 | /* >=2.6.12's fbcon clears the screen anyway */ | 1167 | /* >=2.6.12's fbcon clears the screen anyway */ |
| 1168 | modeno |= 0x80; | 1168 | modeno |= 0x80; |
| 1169 | 1169 | ||
| 1170 | outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD); | 1170 | SiS_SetReg(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD); |
| 1171 | 1171 | ||
| 1172 | sisfb_pre_setmode(ivideo); | 1172 | sisfb_pre_setmode(ivideo); |
| 1173 | 1173 | ||
| @@ -1176,7 +1176,7 @@ sisfb_set_mode(struct sis_video_info *ivideo, int clrscrn) | |||
| 1176 | return -EINVAL; | 1176 | return -EINVAL; |
| 1177 | } | 1177 | } |
| 1178 | 1178 | ||
| 1179 | outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD); | 1179 | SiS_SetReg(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD); |
| 1180 | 1180 | ||
| 1181 | sisfb_post_setmode(ivideo); | 1181 | sisfb_post_setmode(ivideo); |
| 1182 | 1182 | ||
| @@ -1308,13 +1308,13 @@ sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *in | |||
| 1308 | static void | 1308 | static void |
| 1309 | sisfb_set_base_CRT1(struct sis_video_info *ivideo, unsigned int base) | 1309 | sisfb_set_base_CRT1(struct sis_video_info *ivideo, unsigned int base) |
| 1310 | { | 1310 | { |
| 1311 | outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD); | 1311 | SiS_SetReg(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD); |
| 1312 | 1312 | ||
| 1313 | outSISIDXREG(SISCR, 0x0D, base & 0xFF); | 1313 | SiS_SetReg(SISCR, 0x0D, base & 0xFF); |
| 1314 | outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF); | 1314 | SiS_SetReg(SISCR, 0x0C, (base >> 8) & 0xFF); |
| 1315 | outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF); | 1315 | SiS_SetReg(SISSR, 0x0D, (base >> 16) & 0xFF); |
| 1316 | if(ivideo->sisvga_engine == SIS_315_VGA) { | 1316 | if(ivideo->sisvga_engine == SIS_315_VGA) { |
| 1317 | setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01); | 1317 | SiS_SetRegANDOR(SISSR, 0x37, 0xFE, (base >> 24) & 0x01); |
| 1318 | } | 1318 | } |
| 1319 | } | 1319 | } |
| 1320 | 1320 | ||
| @@ -1322,12 +1322,12 @@ static void | |||
| 1322 | sisfb_set_base_CRT2(struct sis_video_info *ivideo, unsigned int base) | 1322 | sisfb_set_base_CRT2(struct sis_video_info *ivideo, unsigned int base) |
| 1323 | { | 1323 | { |
| 1324 | if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { | 1324 | if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { |
| 1325 | orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01); | 1325 | SiS_SetRegOR(SISPART1, ivideo->CRT2_write_enable, 0x01); |
| 1326 | outSISIDXREG(SISPART1, 0x06, (base & 0xFF)); | 1326 | SiS_SetReg(SISPART1, 0x06, (base & 0xFF)); |
| 1327 | outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF)); | 1327 | SiS_SetReg(SISPART1, 0x05, ((base >> 8) & 0xFF)); |
| 1328 | outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF)); | 1328 | SiS_SetReg(SISPART1, 0x04, ((base >> 16) & 0xFF)); |
| 1329 | if(ivideo->sisvga_engine == SIS_315_VGA) { | 1329 | if(ivideo->sisvga_engine == SIS_315_VGA) { |
| 1330 | setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7); | 1330 | SiS_SetRegANDOR(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7); |
| 1331 | } | 1331 | } |
| 1332 | } | 1332 | } |
| 1333 | } | 1333 | } |
| @@ -1388,15 +1388,15 @@ sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, | |||
| 1388 | 1388 | ||
| 1389 | switch(info->var.bits_per_pixel) { | 1389 | switch(info->var.bits_per_pixel) { |
| 1390 | case 8: | 1390 | case 8: |
| 1391 | outSISREG(SISDACA, regno); | 1391 | SiS_SetRegByte(SISDACA, regno); |
| 1392 | outSISREG(SISDACD, (red >> 10)); | 1392 | SiS_SetRegByte(SISDACD, (red >> 10)); |
| 1393 | outSISREG(SISDACD, (green >> 10)); | 1393 | SiS_SetRegByte(SISDACD, (green >> 10)); |
| 1394 | outSISREG(SISDACD, (blue >> 10)); | 1394 | SiS_SetRegByte(SISDACD, (blue >> 10)); |
| 1395 | if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { | 1395 | if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) { |
| 1396 | outSISREG(SISDAC2A, regno); | 1396 | SiS_SetRegByte(SISDAC2A, regno); |
| 1397 | outSISREG(SISDAC2D, (red >> 8)); | 1397 | SiS_SetRegByte(SISDAC2D, (red >> 8)); |
| 1398 | outSISREG(SISDAC2D, (green >> 8)); | 1398 | SiS_SetRegByte(SISDAC2D, (green >> 8)); |
| 1399 | outSISREG(SISDAC2D, (blue >> 8)); | 1399 | SiS_SetRegByte(SISDAC2D, (blue >> 8)); |
| 1400 | } | 1400 | } |
| 1401 | break; | 1401 | break; |
| 1402 | case 16: | 1402 | case 16: |
| @@ -1961,7 +1961,7 @@ sisfb_get_dram_size(struct sis_video_info *ivideo) | |||
| 1961 | switch(ivideo->chip) { | 1961 | switch(ivideo->chip) { |
| 1962 | #ifdef CONFIG_FB_SIS_300 | 1962 | #ifdef CONFIG_FB_SIS_300 |
| 1963 | case SIS_300: | 1963 | case SIS_300: |
| 1964 | inSISIDXREG(SISSR, 0x14, reg); | 1964 | reg = SiS_GetReg(SISSR, 0x14); |
| 1965 | ivideo->video_size = ((reg & 0x3F) + 1) << 20; | 1965 | ivideo->video_size = ((reg & 0x3F) + 1) << 20; |
| 1966 | break; | 1966 | break; |
| 1967 | case SIS_540: | 1967 | case SIS_540: |
| @@ -1977,7 +1977,7 @@ sisfb_get_dram_size(struct sis_video_info *ivideo) | |||
| 1977 | case SIS_315H: | 1977 | case SIS_315H: |
| 1978 | case SIS_315PRO: | 1978 | case SIS_315PRO: |
| 1979 | case SIS_315: | 1979 | case SIS_315: |
| 1980 | inSISIDXREG(SISSR, 0x14, reg); | 1980 | reg = SiS_GetReg(SISSR, 0x14); |
| 1981 | ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; | 1981 | ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; |
| 1982 | switch((reg >> 2) & 0x03) { | 1982 | switch((reg >> 2) & 0x03) { |
| 1983 | case 0x01: | 1983 | case 0x01: |
| @@ -1989,31 +1989,31 @@ sisfb_get_dram_size(struct sis_video_info *ivideo) | |||
| 1989 | } | 1989 | } |
| 1990 | break; | 1990 | break; |
| 1991 | case SIS_330: | 1991 | case SIS_330: |
| 1992 | inSISIDXREG(SISSR, 0x14, reg); | 1992 | reg = SiS_GetReg(SISSR, 0x14); |
| 1993 | ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; | 1993 | ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; |
| 1994 | if(reg & 0x0c) ivideo->video_size <<= 1; | 1994 | if(reg & 0x0c) ivideo->video_size <<= 1; |
| 1995 | break; | 1995 | break; |
| 1996 | case SIS_550: | 1996 | case SIS_550: |
| 1997 | case SIS_650: | 1997 | case SIS_650: |
| 1998 | case SIS_740: | 1998 | case SIS_740: |
| 1999 | inSISIDXREG(SISSR, 0x14, reg); | 1999 | reg = SiS_GetReg(SISSR, 0x14); |
| 2000 | ivideo->video_size = (((reg & 0x3f) + 1) << 2) << 20; | 2000 | ivideo->video_size = (((reg & 0x3f) + 1) << 2) << 20; |
| 2001 | break; | 2001 | break; |
| 2002 | case SIS_661: | 2002 | case SIS_661: |
| 2003 | case SIS_741: | 2003 | case SIS_741: |
| 2004 | inSISIDXREG(SISCR, 0x79, reg); | 2004 | reg = SiS_GetReg(SISCR, 0x79); |
| 2005 | ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; | 2005 | ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; |
| 2006 | break; | 2006 | break; |
| 2007 | case SIS_660: | 2007 | case SIS_660: |
| 2008 | case SIS_760: | 2008 | case SIS_760: |
| 2009 | case SIS_761: | 2009 | case SIS_761: |
| 2010 | inSISIDXREG(SISCR, 0x79, reg); | 2010 | reg = SiS_GetReg(SISCR, 0x79); |
| 2011 | reg = (reg & 0xf0) >> 4; | 2011 | reg = (reg & 0xf0) >> 4; |
| 2012 | if(reg) { | 2012 | if(reg) { |
| 2013 | ivideo->video_size = (1 << reg) << 20; | 2013 | ivideo->video_size = (1 << reg) << 20; |
| 2014 | ivideo->UMAsize = ivideo->video_size; | 2014 | ivideo->UMAsize = ivideo->video_size; |
| 2015 | } | 2015 | } |
| 2016 | inSISIDXREG(SISCR, 0x78, reg); | 2016 | reg = SiS_GetReg(SISCR, 0x78); |
| 2017 | reg &= 0x30; | 2017 | reg &= 0x30; |
| 2018 | if(reg) { | 2018 | if(reg) { |
| 2019 | if(reg == 0x10) { | 2019 | if(reg == 0x10) { |
| @@ -2027,7 +2027,7 @@ sisfb_get_dram_size(struct sis_video_info *ivideo) | |||
| 2027 | case SIS_340: | 2027 | case SIS_340: |
| 2028 | case XGI_20: | 2028 | case XGI_20: |
| 2029 | case XGI_40: | 2029 | case XGI_40: |
| 2030 | inSISIDXREG(SISSR, 0x14, reg); | 2030 | reg = SiS_GetReg(SISSR, 0x14); |
| 2031 | ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; | 2031 | ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20; |
| 2032 | if(ivideo->chip != XGI_20) { | 2032 | if(ivideo->chip != XGI_20) { |
| 2033 | reg = (reg & 0x0c) >> 2; | 2033 | reg = (reg & 0x0c) >> 2; |
| @@ -2061,11 +2061,11 @@ sisfb_detect_VB_connect(struct sis_video_info *ivideo) | |||
| 2061 | 2061 | ||
| 2062 | #ifdef CONFIG_FB_SIS_300 | 2062 | #ifdef CONFIG_FB_SIS_300 |
| 2063 | if(ivideo->sisvga_engine == SIS_300_VGA) { | 2063 | if(ivideo->sisvga_engine == SIS_300_VGA) { |
| 2064 | inSISIDXREG(SISSR, 0x17, temp); | 2064 | temp = SiS_GetReg(SISSR, 0x17); |
| 2065 | if((temp & 0x0F) && (ivideo->chip != SIS_300)) { | 2065 | if((temp & 0x0F) && (ivideo->chip != SIS_300)) { |
| 2066 | /* PAL/NTSC is stored on SR16 on such machines */ | 2066 | /* PAL/NTSC is stored on SR16 on such machines */ |
| 2067 | if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN))) { | 2067 | if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN))) { |
| 2068 | inSISIDXREG(SISSR, 0x16, temp); | 2068 | temp = SiS_GetReg(SISSR, 0x16); |
| 2069 | if(temp & 0x20) | 2069 | if(temp & 0x20) |
| 2070 | ivideo->vbflags |= TV_PAL; | 2070 | ivideo->vbflags |= TV_PAL; |
| 2071 | else | 2071 | else |
| @@ -2075,7 +2075,7 @@ sisfb_detect_VB_connect(struct sis_video_info *ivideo) | |||
| 2075 | } | 2075 | } |
| 2076 | #endif | 2076 | #endif |
| 2077 | 2077 | ||
| 2078 | inSISIDXREG(SISCR, 0x32, cr32); | 2078 | cr32 = SiS_GetReg(SISCR, 0x32); |
| 2079 | 2079 | ||
| 2080 | if(cr32 & SIS_CRT1) { | 2080 | if(cr32 & SIS_CRT1) { |
| 2081 | ivideo->sisfb_crt1off = 0; | 2081 | ivideo->sisfb_crt1off = 0; |
| @@ -2151,15 +2151,15 @@ sisfb_detect_VB_connect(struct sis_video_info *ivideo) | |||
| 2151 | } | 2151 | } |
| 2152 | if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ))) { | 2152 | if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ))) { |
| 2153 | if(ivideo->sisvga_engine == SIS_300_VGA) { | 2153 | if(ivideo->sisvga_engine == SIS_300_VGA) { |
| 2154 | inSISIDXREG(SISSR, 0x38, temp); | 2154 | temp = SiS_GetReg(SISSR, 0x38); |
| 2155 | if(temp & 0x01) ivideo->vbflags |= TV_PAL; | 2155 | if(temp & 0x01) ivideo->vbflags |= TV_PAL; |
| 2156 | else ivideo->vbflags |= TV_NTSC; | 2156 | else ivideo->vbflags |= TV_NTSC; |
| 2157 | } else if((ivideo->chip <= SIS_315PRO) || (ivideo->chip >= SIS_330)) { | 2157 | } else if((ivideo->chip <= SIS_315PRO) || (ivideo->chip >= SIS_330)) { |
| 2158 | inSISIDXREG(SISSR, 0x38, temp); | 2158 | temp = SiS_GetReg(SISSR, 0x38); |
| 2159 | if(temp & 0x01) ivideo->vbflags |= TV_PAL; | 2159 | if(temp & 0x01) ivideo->vbflags |= TV_PAL; |
| 2160 | else ivideo->vbflags |= TV_NTSC; | 2160 | else ivideo->vbflags |= TV_NTSC; |
| 2161 | } else { | 2161 | } else { |
| 2162 | inSISIDXREG(SISCR, 0x79, temp); | 2162 | temp = SiS_GetReg(SISCR, 0x79); |
| 2163 | if(temp & 0x20) ivideo->vbflags |= TV_PAL; | 2163 | if(temp & 0x20) ivideo->vbflags |= TV_PAL; |
| 2164 | else ivideo->vbflags |= TV_NTSC; | 2164 | else ivideo->vbflags |= TV_NTSC; |
| 2165 | } | 2165 | } |
| @@ -2198,26 +2198,26 @@ sisfb_sense_crt1(struct sis_video_info *ivideo) | |||
| 2198 | u16 temp = 0xffff; | 2198 | u16 temp = 0xffff; |
| 2199 | int i; | 2199 | int i; |
| 2200 | 2200 | ||
| 2201 | inSISIDXREG(SISSR,0x1F,sr1F); | 2201 | sr1F = SiS_GetReg(SISSR, 0x1F); |
| 2202 | orSISIDXREG(SISSR,0x1F,0x04); | 2202 | SiS_SetRegOR(SISSR, 0x1F, 0x04); |
| 2203 | andSISIDXREG(SISSR,0x1F,0x3F); | 2203 | SiS_SetRegAND(SISSR, 0x1F, 0x3F); |
| 2204 | if(sr1F & 0xc0) mustwait = true; | 2204 | if(sr1F & 0xc0) mustwait = true; |
| 2205 | 2205 | ||
| 2206 | #ifdef CONFIG_FB_SIS_315 | 2206 | #ifdef CONFIG_FB_SIS_315 |
| 2207 | if(ivideo->sisvga_engine == SIS_315_VGA) { | 2207 | if(ivideo->sisvga_engine == SIS_315_VGA) { |
| 2208 | inSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,cr63); | 2208 | cr63 = SiS_GetReg(SISCR, ivideo->SiS_Pr.SiS_MyCR63); |
| 2209 | cr63 &= 0x40; | 2209 | cr63 &= 0x40; |
| 2210 | andSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF); | 2210 | SiS_SetRegAND(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xBF); |
| 2211 | } | 2211 | } |
| 2212 | #endif | 2212 | #endif |
| 2213 | 2213 | ||
| 2214 | inSISIDXREG(SISCR,0x17,cr17); | 2214 | cr17 = SiS_GetReg(SISCR, 0x17); |
| 2215 | cr17 &= 0x80; | 2215 | cr17 &= 0x80; |
| 2216 | if(!cr17) { | 2216 | if(!cr17) { |
| 2217 | orSISIDXREG(SISCR,0x17,0x80); | 2217 | SiS_SetRegOR(SISCR, 0x17, 0x80); |
| 2218 | mustwait = true; | 2218 | mustwait = true; |
| 2219 | outSISIDXREG(SISSR, 0x00, 0x01); | 2219 | SiS_SetReg(SISSR, 0x00, 0x01); |
| 2220 | outSISIDXREG(SISSR, 0x00, 0x03); | 2220 | SiS_SetReg(SISSR, 0x00, 0x03); |
| 2221 | } | 2221 | } |
| 2222 | 2222 | ||
| 2223 | if(mustwait) { | 2223 | if(mustwait) { |
| @@ -2226,18 +2226,18 @@ sisfb_sense_crt1(struct sis_video_info *ivideo) | |||
| 2226 | 2226 | ||
| 2227 | #ifdef CONFIG_FB_SIS_315 | 2227 | #ifdef CONFIG_FB_SIS_315 |
| 2228 | if(ivideo->chip >= SIS_330) { | 2228 | if(ivideo->chip >= SIS_330) { |
| 2229 | andSISIDXREG(SISCR,0x32,~0x20); | 2229 | SiS_SetRegAND(SISCR, 0x32, ~0x20); |
| 2230 | if(ivideo->chip >= SIS_340) { | 2230 | if(ivideo->chip >= SIS_340) { |
| 2231 | outSISIDXREG(SISCR, 0x57, 0x4a); | 2231 | SiS_SetReg(SISCR, 0x57, 0x4a); |
| 2232 | } else { | 2232 | } else { |
| 2233 | outSISIDXREG(SISCR, 0x57, 0x5f); | 2233 | SiS_SetReg(SISCR, 0x57, 0x5f); |
| 2234 | } | 2234 | } |
| 2235 | orSISIDXREG(SISCR, 0x53, 0x02); | 2235 | SiS_SetRegOR(SISCR, 0x53, 0x02); |
| 2236 | while((inSISREG(SISINPSTAT)) & 0x01) break; | 2236 | while ((SiS_GetRegByte(SISINPSTAT)) & 0x01) break; |
| 2237 | while(!((inSISREG(SISINPSTAT)) & 0x01)) break; | 2237 | while (!((SiS_GetRegByte(SISINPSTAT)) & 0x01)) break; |
| 2238 | if((inSISREG(SISMISCW)) & 0x10) temp = 1; | 2238 | if ((SiS_GetRegByte(SISMISCW)) & 0x10) temp = 1; |
| 2239 | andSISIDXREG(SISCR, 0x53, 0xfd); | 2239 | SiS_SetRegAND(SISCR, 0x53, 0xfd); |
| 2240 | andSISIDXREG(SISCR, 0x57, 0x00); | 2240 | SiS_SetRegAND(SISCR, 0x57, 0x00); |
| 2241 | } | 2241 | } |
| 2242 | #endif | 2242 | #endif |
| 2243 | 2243 | ||
| @@ -2254,18 +2254,18 @@ sisfb_sense_crt1(struct sis_video_info *ivideo) | |||
| 2254 | } | 2254 | } |
| 2255 | 2255 | ||
| 2256 | if((temp) && (temp != 0xffff)) { | 2256 | if((temp) && (temp != 0xffff)) { |
| 2257 | orSISIDXREG(SISCR,0x32,0x20); | 2257 | SiS_SetRegOR(SISCR, 0x32, 0x20); |
| 2258 | } | 2258 | } |
| 2259 | 2259 | ||
| 2260 | #ifdef CONFIG_FB_SIS_315 | 2260 | #ifdef CONFIG_FB_SIS_315 |
| 2261 | if(ivideo->sisvga_engine == SIS_315_VGA) { | 2261 | if(ivideo->sisvga_engine == SIS_315_VGA) { |
| 2262 | setSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF,cr63); | 2262 | SiS_SetRegANDOR(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xBF, cr63); |
| 2263 | } | 2263 | } |
| 2264 | #endif | 2264 | #endif |
| 2265 | 2265 | ||
| 2266 | setSISIDXREG(SISCR,0x17,0x7F,cr17); | 2266 | SiS_SetRegANDOR(SISCR, 0x17, 0x7F, cr17); |
| 2267 | 2267 | ||
| 2268 | outSISIDXREG(SISSR,0x1F,sr1F); | 2268 | SiS_SetReg(SISSR, 0x1F, sr1F); |
| 2269 | } | 2269 | } |
| 2270 | 2270 | ||
| 2271 | /* Determine and detect attached devices on SiS30x */ | 2271 | /* Determine and detect attached devices on SiS30x */ |
| @@ -2286,7 +2286,7 @@ SiS_SenseLCD(struct sis_video_info *ivideo) | |||
| 2286 | return; | 2286 | return; |
| 2287 | 2287 | ||
| 2288 | /* If LCD already set up by BIOS, skip it */ | 2288 | /* If LCD already set up by BIOS, skip it */ |
| 2289 | inSISIDXREG(SISCR, 0x32, reg); | 2289 | reg = SiS_GetReg(SISCR, 0x32); |
| 2290 | if(reg & 0x08) | 2290 | if(reg & 0x08) |
| 2291 | return; | 2291 | return; |
| 2292 | 2292 | ||
| @@ -2349,10 +2349,10 @@ SiS_SenseLCD(struct sis_video_info *ivideo) | |||
| 2349 | else | 2349 | else |
| 2350 | cr37 |= 0xc0; | 2350 | cr37 |= 0xc0; |
| 2351 | 2351 | ||
| 2352 | outSISIDXREG(SISCR, 0x36, paneltype); | 2352 | SiS_SetReg(SISCR, 0x36, paneltype); |
| 2353 | cr37 &= 0xf1; | 2353 | cr37 &= 0xf1; |
| 2354 | setSISIDXREG(SISCR, 0x37, 0x0c, cr37); | 2354 | SiS_SetRegANDOR(SISCR, 0x37, 0x0c, cr37); |
| 2355 | orSISIDXREG(SISCR, 0x32, 0x08); | 2355 | SiS_SetRegOR(SISCR, 0x32, 0x08); |
| 2356 | 2356 | ||
| 2357 | ivideo->SiS_Pr.PanelSelfDetected = true; | 2357 | ivideo->SiS_Pr.PanelSelfDetected = true; |
| 2358 | } | 2358 | } |
| @@ -2366,19 +2366,19 @@ SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test) | |||
| 2366 | result = 0; | 2366 | result = 0; |
| 2367 | for(i = 0; i < 3; i++) { | 2367 | for(i = 0; i < 3; i++) { |
| 2368 | mytest = test; | 2368 | mytest = test; |
| 2369 | outSISIDXREG(SISPART4,0x11,(type & 0x00ff)); | 2369 | SiS_SetReg(SISPART4, 0x11, (type & 0x00ff)); |
| 2370 | temp = (type >> 8) | (mytest & 0x00ff); | 2370 | temp = (type >> 8) | (mytest & 0x00ff); |
| 2371 | setSISIDXREG(SISPART4,0x10,0xe0,temp); | 2371 | SiS_SetRegANDOR(SISPART4, 0x10, 0xe0, temp); |
| 2372 | SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1500); | 2372 | SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1500); |
| 2373 | mytest >>= 8; | 2373 | mytest >>= 8; |
| 2374 | mytest &= 0x7f; | 2374 | mytest &= 0x7f; |
| 2375 | inSISIDXREG(SISPART4,0x03,temp); | 2375 | temp = SiS_GetReg(SISPART4, 0x03); |
| 2376 | temp ^= 0x0e; | 2376 | temp ^= 0x0e; |
| 2377 | temp &= mytest; | 2377 | temp &= mytest; |
| 2378 | if(temp == mytest) result++; | 2378 | if(temp == mytest) result++; |
| 2379 | #if 1 | 2379 | #if 1 |
| 2380 | outSISIDXREG(SISPART4,0x11,0x00); | 2380 | SiS_SetReg(SISPART4, 0x11, 0x00); |
| 2381 | andSISIDXREG(SISPART4,0x10,0xe0); | 2381 | SiS_SetRegAND(SISPART4, 0x10, 0xe0); |
| 2382 | SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1000); | 2382 | SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1000); |
| 2383 | #endif | 2383 | #endif |
| 2384 | } | 2384 | } |
| @@ -2400,7 +2400,7 @@ SiS_Sense30x(struct sis_video_info *ivideo) | |||
| 2400 | 2400 | ||
| 2401 | if(ivideo->vbflags2 & VB2_301) { | 2401 | if(ivideo->vbflags2 & VB2_301) { |
| 2402 | svhs = 0x00b9; cvbs = 0x00b3; vga2 = 0x00d1; | 2402 | svhs = 0x00b9; cvbs = 0x00b3; vga2 = 0x00d1; |
| 2403 | inSISIDXREG(SISPART4,0x01,myflag); | 2403 | myflag = SiS_GetReg(SISPART4, 0x01); |
| 2404 | if(myflag & 0x04) { | 2404 | if(myflag & 0x04) { |
| 2405 | svhs = 0x00dd; cvbs = 0x00ee; vga2 = 0x00fd; | 2405 | svhs = 0x00dd; cvbs = 0x00ee; vga2 = 0x00fd; |
| 2406 | } | 2406 | } |
| @@ -2430,7 +2430,7 @@ SiS_Sense30x(struct sis_video_info *ivideo) | |||
| 2430 | } | 2430 | } |
| 2431 | 2431 | ||
| 2432 | if(ivideo->chip == SIS_300) { | 2432 | if(ivideo->chip == SIS_300) { |
| 2433 | inSISIDXREG(SISSR,0x3b,myflag); | 2433 | myflag = SiS_GetReg(SISSR, 0x3b); |
| 2434 | if(!(myflag & 0x01)) vga2 = vga2_c = 0; | 2434 | if(!(myflag & 0x01)) vga2 = vga2_c = 0; |
| 2435 | } | 2435 | } |
| 2436 | 2436 | ||
| @@ -2438,93 +2438,93 @@ SiS_Sense30x(struct sis_video_info *ivideo) | |||
| 2438 | vga2 = vga2_c = 0; | 2438 | vga2 = vga2_c = 0; |
| 2439 | } | 2439 | } |
| 2440 | 2440 | ||
| 2441 | inSISIDXREG(SISSR,0x1e,backupSR_1e); | 2441 | backupSR_1e = SiS_GetReg(SISSR, 0x1e); |
| 2442 | orSISIDXREG(SISSR,0x1e,0x20); | 2442 | SiS_SetRegOR(SISSR, 0x1e, 0x20); |
| 2443 | 2443 | ||
| 2444 | inSISIDXREG(SISPART4,0x0d,backupP4_0d); | 2444 | backupP4_0d = SiS_GetReg(SISPART4, 0x0d); |
| 2445 | if(ivideo->vbflags2 & VB2_30xC) { | 2445 | if(ivideo->vbflags2 & VB2_30xC) { |
| 2446 | setSISIDXREG(SISPART4,0x0d,~0x07,0x01); | 2446 | SiS_SetRegANDOR(SISPART4, 0x0d, ~0x07, 0x01); |
| 2447 | } else { | 2447 | } else { |
| 2448 | orSISIDXREG(SISPART4,0x0d,0x04); | 2448 | SiS_SetRegOR(SISPART4, 0x0d, 0x04); |
| 2449 | } | 2449 | } |
| 2450 | SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000); | 2450 | SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000); |
| 2451 | 2451 | ||
| 2452 | inSISIDXREG(SISPART2,0x00,backupP2_00); | 2452 | backupP2_00 = SiS_GetReg(SISPART2, 0x00); |
| 2453 | outSISIDXREG(SISPART2,0x00,((backupP2_00 | 0x1c) & 0xfc)); | 2453 | SiS_SetReg(SISPART2, 0x00, ((backupP2_00 | 0x1c) & 0xfc)); |
| 2454 | 2454 | ||
| 2455 | inSISIDXREG(SISPART2,0x4d,backupP2_4d); | 2455 | backupP2_4d = SiS_GetReg(SISPART2, 0x4d); |
| 2456 | if(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE) { | 2456 | if(ivideo->vbflags2 & VB2_SISYPBPRBRIDGE) { |
| 2457 | outSISIDXREG(SISPART2,0x4d,(backupP2_4d & ~0x10)); | 2457 | SiS_SetReg(SISPART2, 0x4d, (backupP2_4d & ~0x10)); |
| 2458 | } | 2458 | } |
| 2459 | 2459 | ||
| 2460 | if(!(ivideo->vbflags2 & VB2_30xCLV)) { | 2460 | if(!(ivideo->vbflags2 & VB2_30xCLV)) { |
| 2461 | SISDoSense(ivideo, 0, 0); | 2461 | SISDoSense(ivideo, 0, 0); |
| 2462 | } | 2462 | } |
| 2463 | 2463 | ||
| 2464 | andSISIDXREG(SISCR, 0x32, ~0x14); | 2464 | SiS_SetRegAND(SISCR, 0x32, ~0x14); |
| 2465 | 2465 | ||
| 2466 | if(vga2_c || vga2) { | 2466 | if(vga2_c || vga2) { |
| 2467 | if(SISDoSense(ivideo, vga2, vga2_c)) { | 2467 | if(SISDoSense(ivideo, vga2, vga2_c)) { |
| 2468 | if(biosflag & 0x01) { | 2468 | if(biosflag & 0x01) { |
| 2469 | printk(KERN_INFO "%s %s SCART output\n", stdstr, tvstr); | 2469 | printk(KERN_INFO "%s %s SCART output\n", stdstr, tvstr); |
| 2470 | orSISIDXREG(SISCR, 0x32, 0x04); | 2470 | SiS_SetRegOR(SISCR, 0x32, 0x04); |
| 2471 | } else { | 2471 | } else { |
| 2472 | printk(KERN_INFO "%s secondary VGA connection\n", stdstr); | 2472 | printk(KERN_INFO "%s secondary VGA connection\n", stdstr); |
| 2473 | orSISIDXREG(SISCR, 0x32, 0x10); | 2473 | SiS_SetRegOR(SISCR, 0x32, 0x10); |
| 2474 | } | 2474 | } |
| 2475 | } | 2475 | } |
| 2476 | } | 2476 | } |
| 2477 | 2477 | ||
| 2478 | andSISIDXREG(SISCR, 0x32, 0x3f); | 2478 | SiS_SetRegAND(SISCR, 0x32, 0x3f); |
| 2479 | 2479 | ||
| 2480 | if(ivideo->vbflags2 & VB2_30xCLV) { | 2480 | if(ivideo->vbflags2 & VB2_30xCLV) { |
| 2481 | orSISIDXREG(SISPART4,0x0d,0x04); | 2481 | SiS_SetRegOR(SISPART4, 0x0d, 0x04); |
| 2482 | } | 2482 | } |
| 2483 | 2483 | ||
| 2484 | if((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) { | 2484 | if((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags2 & VB2_SISYPBPRBRIDGE)) { |
| 2485 | outSISIDXREG(SISPART2,0x4d,(backupP2_4d | 0x10)); | 2485 | SiS_SetReg(SISPART2, 0x4d, (backupP2_4d | 0x10)); |
| 2486 | SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000); | 2486 | SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000); |
| 2487 | if((result = SISDoSense(ivideo, svhs, 0x0604))) { | 2487 | if((result = SISDoSense(ivideo, svhs, 0x0604))) { |
| 2488 | if((result = SISDoSense(ivideo, cvbs, 0x0804))) { | 2488 | if((result = SISDoSense(ivideo, cvbs, 0x0804))) { |
| 2489 | printk(KERN_INFO "%s %s YPbPr component output\n", stdstr, tvstr); | 2489 | printk(KERN_INFO "%s %s YPbPr component output\n", stdstr, tvstr); |
| 2490 | orSISIDXREG(SISCR,0x32,0x80); | 2490 | SiS_SetRegOR(SISCR, 0x32, 0x80); |
| 2491 | } | 2491 | } |
| 2492 | } | 2492 | } |
| 2493 | outSISIDXREG(SISPART2,0x4d,backupP2_4d); | 2493 | SiS_SetReg(SISPART2, 0x4d, backupP2_4d); |
| 2494 | } | 2494 | } |
| 2495 | 2495 | ||
| 2496 | andSISIDXREG(SISCR, 0x32, ~0x03); | 2496 | SiS_SetRegAND(SISCR, 0x32, ~0x03); |
| 2497 | 2497 | ||
| 2498 | if(!(ivideo->vbflags & TV_YPBPR)) { | 2498 | if(!(ivideo->vbflags & TV_YPBPR)) { |
| 2499 | if((result = SISDoSense(ivideo, svhs, svhs_c))) { | 2499 | if((result = SISDoSense(ivideo, svhs, svhs_c))) { |
| 2500 | printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr); | 2500 | printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr); |
| 2501 | orSISIDXREG(SISCR, 0x32, 0x02); | 2501 | SiS_SetRegOR(SISCR, 0x32, 0x02); |
| 2502 | } | 2502 | } |
| 2503 | if((biosflag & 0x02) || (!result)) { | 2503 | if((biosflag & 0x02) || (!result)) { |
| 2504 | if(SISDoSense(ivideo, cvbs, cvbs_c)) { | 2504 | if(SISDoSense(ivideo, cvbs, cvbs_c)) { |
| 2505 | printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr); | 2505 | printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr); |
| 2506 | orSISIDXREG(SISCR, 0x32, 0x01); | 2506 | SiS_SetRegOR(SISCR, 0x32, 0x01); |
| 2507 | } | 2507 | } |
| 2508 | } | 2508 | } |
| 2509 | } | 2509 | } |
| 2510 | 2510 | ||
| 2511 | SISDoSense(ivideo, 0, 0); | 2511 | SISDoSense(ivideo, 0, 0); |
| 2512 | 2512 | ||
| 2513 | outSISIDXREG(SISPART2,0x00,backupP2_00); | 2513 | SiS_SetReg(SISPART2, 0x00, backupP2_00); |
| 2514 | outSISIDXREG(SISPART4,0x0d,backupP4_0d); | 2514 | SiS_SetReg(SISPART4, 0x0d, backupP4_0d); |
| 2515 | outSISIDXREG(SISSR,0x1e,backupSR_1e); | 2515 | SiS_SetReg(SISSR, 0x1e, backupSR_1e); |
| 2516 | 2516 | ||
| 2517 | if(ivideo->vbflags2 & VB2_30xCLV) { | 2517 | if(ivideo->vbflags2 & VB2_30xCLV) { |
| 2518 | inSISIDXREG(SISPART2,0x00,biosflag); | 2518 | biosflag = SiS_GetReg(SISPART2, 0x00); |
| 2519 | if(biosflag & 0x20) { | 2519 | if(biosflag & 0x20) { |
| 2520 | for(myflag = 2; myflag > 0; myflag--) { | 2520 | for(myflag = 2; myflag > 0; myflag--) { |
| 2521 | biosflag ^= 0x20; | 2521 | biosflag ^= 0x20; |
| 2522 | outSISIDXREG(SISPART2,0x00,biosflag); | 2522 | SiS_SetReg(SISPART2, 0x00, biosflag); |
| 2523 | } | 2523 | } |
| 2524 | } | 2524 | } |
| 2525 | } | 2525 | } |
| 2526 | 2526 | ||
| 2527 | outSISIDXREG(SISPART2,0x00,backupP2_00); | 2527 | SiS_SetReg(SISPART2, 0x00, backupP2_00); |
| 2528 | } | 2528 | } |
| 2529 | 2529 | ||
| 2530 | /* Determine and detect attached TV's on Chrontel */ | 2530 | /* Determine and detect attached TV's on Chrontel */ |
| @@ -2588,20 +2588,20 @@ SiS_SenseCh(struct sis_video_info *ivideo) | |||
| 2588 | if(temp1 == 0x02) { | 2588 | if(temp1 == 0x02) { |
| 2589 | printk(KERN_INFO "%s SVIDEO output\n", stdstr); | 2589 | printk(KERN_INFO "%s SVIDEO output\n", stdstr); |
| 2590 | ivideo->vbflags |= TV_SVIDEO; | 2590 | ivideo->vbflags |= TV_SVIDEO; |
| 2591 | orSISIDXREG(SISCR, 0x32, 0x02); | 2591 | SiS_SetRegOR(SISCR, 0x32, 0x02); |
| 2592 | andSISIDXREG(SISCR, 0x32, ~0x05); | 2592 | SiS_SetRegAND(SISCR, 0x32, ~0x05); |
| 2593 | } else if (temp1 == 0x01) { | 2593 | } else if (temp1 == 0x01) { |
| 2594 | printk(KERN_INFO "%s CVBS output\n", stdstr); | 2594 | printk(KERN_INFO "%s CVBS output\n", stdstr); |
| 2595 | ivideo->vbflags |= TV_AVIDEO; | 2595 | ivideo->vbflags |= TV_AVIDEO; |
| 2596 | orSISIDXREG(SISCR, 0x32, 0x01); | 2596 | SiS_SetRegOR(SISCR, 0x32, 0x01); |
| 2597 | andSISIDXREG(SISCR, 0x32, ~0x06); | 2597 | SiS_SetRegAND(SISCR, 0x32, ~0x06); |
| 2598 | } else { | 2598 | } else { |
| 2599 | SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8); | 2599 | SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8); |
| 2600 | andSISIDXREG(SISCR, 0x32, ~0x07); | 2600 | SiS_SetRegAND(SISCR, 0x32, ~0x07); |
| 2601 | } | 2601 | } |
| 2602 | } else if(temp1 == 0) { | 2602 | } else if(temp1 == 0) { |
| 2603 | SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8); | 2603 | SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x0e, 0x01, 0xF8); |
| 2604 | andSISIDXREG(SISCR, 0x32, ~0x07); | 2604 | SiS_SetRegAND(SISCR, 0x32, ~0x07); |
| 2605 | } | 2605 | } |
| 2606 | /* Set general purpose IO for Chrontel communication */ | 2606 | /* Set general purpose IO for Chrontel communication */ |
| 2607 | SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x00); | 2607 | SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x00); |
| @@ -2632,22 +2632,22 @@ SiS_SenseCh(struct sis_video_info *ivideo) | |||
| 2632 | case 0x01: | 2632 | case 0x01: |
| 2633 | printk(KERN_INFO "%s CVBS output\n", stdstr); | 2633 | printk(KERN_INFO "%s CVBS output\n", stdstr); |
| 2634 | ivideo->vbflags |= TV_AVIDEO; | 2634 | ivideo->vbflags |= TV_AVIDEO; |
| 2635 | orSISIDXREG(SISCR, 0x32, 0x01); | 2635 | SiS_SetRegOR(SISCR, 0x32, 0x01); |
| 2636 | andSISIDXREG(SISCR, 0x32, ~0x06); | 2636 | SiS_SetRegAND(SISCR, 0x32, ~0x06); |
| 2637 | break; | 2637 | break; |
| 2638 | case 0x02: | 2638 | case 0x02: |
| 2639 | printk(KERN_INFO "%s SVIDEO output\n", stdstr); | 2639 | printk(KERN_INFO "%s SVIDEO output\n", stdstr); |
| 2640 | ivideo->vbflags |= TV_SVIDEO; | 2640 | ivideo->vbflags |= TV_SVIDEO; |
| 2641 | orSISIDXREG(SISCR, 0x32, 0x02); | 2641 | SiS_SetRegOR(SISCR, 0x32, 0x02); |
| 2642 | andSISIDXREG(SISCR, 0x32, ~0x05); | 2642 | SiS_SetRegAND(SISCR, 0x32, ~0x05); |
| 2643 | break; | 2643 | break; |
| 2644 | case 0x04: | 2644 | case 0x04: |
| 2645 | printk(KERN_INFO "%s SCART output\n", stdstr); | 2645 | printk(KERN_INFO "%s SCART output\n", stdstr); |
| 2646 | orSISIDXREG(SISCR, 0x32, 0x04); | 2646 | SiS_SetRegOR(SISCR, 0x32, 0x04); |
| 2647 | andSISIDXREG(SISCR, 0x32, ~0x03); | 2647 | SiS_SetRegAND(SISCR, 0x32, ~0x03); |
| 2648 | break; | 2648 | break; |
| 2649 | default: | 2649 | default: |
| 2650 | andSISIDXREG(SISCR, 0x32, ~0x07); | 2650 | SiS_SetRegAND(SISCR, 0x32, ~0x07); |
| 2651 | } | 2651 | } |
| 2652 | #endif | 2652 | #endif |
| 2653 | } | 2653 | } |
| @@ -2665,10 +2665,10 @@ sisfb_get_VB_type(struct sis_video_info *ivideo) | |||
| 2665 | if(ivideo->chip == XGI_20) | 2665 | if(ivideo->chip == XGI_20) |
| 2666 | return; | 2666 | return; |
| 2667 | 2667 | ||
| 2668 | inSISIDXREG(SISPART4, 0x00, vb_chipid); | 2668 | vb_chipid = SiS_GetReg(SISPART4, 0x00); |
| 2669 | switch(vb_chipid) { | 2669 | switch(vb_chipid) { |
| 2670 | case 0x01: | 2670 | case 0x01: |
| 2671 | inSISIDXREG(SISPART4, 0x01, reg); | 2671 | reg = SiS_GetReg(SISPART4, 0x01); |
| 2672 | if(reg < 0xb0) { | 2672 | if(reg < 0xb0) { |
| 2673 | ivideo->vbflags |= VB_301; /* Deprecated */ | 2673 | ivideo->vbflags |= VB_301; /* Deprecated */ |
| 2674 | ivideo->vbflags2 |= VB2_301; | 2674 | ivideo->vbflags2 |= VB2_301; |
| @@ -2676,7 +2676,7 @@ sisfb_get_VB_type(struct sis_video_info *ivideo) | |||
| 2676 | } else if(reg < 0xc0) { | 2676 | } else if(reg < 0xc0) { |
| 2677 | ivideo->vbflags |= VB_301B; /* Deprecated */ | 2677 | ivideo->vbflags |= VB_301B; /* Deprecated */ |
| 2678 | ivideo->vbflags2 |= VB2_301B; | 2678 | ivideo->vbflags2 |= VB2_301B; |
| 2679 | inSISIDXREG(SISPART4,0x23,reg); | 2679 | reg = SiS_GetReg(SISPART4, 0x23); |
| 2680 | if(!(reg & 0x02)) { | 2680 | if(!(reg & 0x02)) { |
| 2681 | ivideo->vbflags |= VB_30xBDH; /* Deprecated */ | 2681 | ivideo->vbflags |= VB_30xBDH; /* Deprecated */ |
| 2682 | ivideo->vbflags2 |= VB2_30xBDH; | 2682 | ivideo->vbflags2 |= VB2_30xBDH; |
| @@ -2693,7 +2693,7 @@ sisfb_get_VB_type(struct sis_video_info *ivideo) | |||
| 2693 | ivideo->vbflags2 |= VB2_301LV; | 2693 | ivideo->vbflags2 |= VB2_301LV; |
| 2694 | printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr); | 2694 | printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr); |
| 2695 | } else if(reg <= 0xe1) { | 2695 | } else if(reg <= 0xe1) { |
| 2696 | inSISIDXREG(SISPART4,0x39,reg); | 2696 | reg = SiS_GetReg(SISPART4, 0x39); |
| 2697 | if(reg == 0xff) { | 2697 | if(reg == 0xff) { |
| 2698 | ivideo->vbflags |= VB_302LV; /* Deprecated */ | 2698 | ivideo->vbflags |= VB_302LV; /* Deprecated */ |
| 2699 | ivideo->vbflags2 |= VB2_302LV; | 2699 | ivideo->vbflags2 |= VB2_302LV; |
| @@ -2718,7 +2718,7 @@ sisfb_get_VB_type(struct sis_video_info *ivideo) | |||
| 2718 | } | 2718 | } |
| 2719 | 2719 | ||
| 2720 | if((!(ivideo->vbflags2 & VB2_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) { | 2720 | if((!(ivideo->vbflags2 & VB2_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) { |
| 2721 | inSISIDXREG(SISCR, 0x37, reg); | 2721 | reg = SiS_GetReg(SISCR, 0x37); |
| 2722 | reg &= SIS_EXTERNAL_CHIP_MASK; | 2722 | reg &= SIS_EXTERNAL_CHIP_MASK; |
| 2723 | reg >>= 1; | 2723 | reg >>= 1; |
| 2724 | if(ivideo->sisvga_engine == SIS_300_VGA) { | 2724 | if(ivideo->sisvga_engine == SIS_300_VGA) { |
| @@ -2759,7 +2759,7 @@ sisfb_get_VB_type(struct sis_video_info *ivideo) | |||
| 2759 | #endif | 2759 | #endif |
| 2760 | } else if(ivideo->chip >= SIS_661) { | 2760 | } else if(ivideo->chip >= SIS_661) { |
| 2761 | #ifdef CONFIG_FB_SIS_315 | 2761 | #ifdef CONFIG_FB_SIS_315 |
| 2762 | inSISIDXREG(SISCR, 0x38, reg); | 2762 | reg = SiS_GetReg(SISCR, 0x38); |
| 2763 | reg >>= 5; | 2763 | reg >>= 5; |
| 2764 | switch(reg) { | 2764 | switch(reg) { |
| 2765 | case 0x02: | 2765 | case 0x02: |
| @@ -2822,13 +2822,13 @@ sisfb_engine_init(struct sis_video_info *ivideo) | |||
| 2822 | 2822 | ||
| 2823 | tqueue_pos = (ivideo->video_size - ivideo->cmdQueueSize) / (64 * 1024); | 2823 | tqueue_pos = (ivideo->video_size - ivideo->cmdQueueSize) / (64 * 1024); |
| 2824 | 2824 | ||
| 2825 | inSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state); | 2825 | tq_state = SiS_GetReg(SISSR, IND_SIS_TURBOQUEUE_SET); |
| 2826 | tq_state |= 0xf0; | 2826 | tq_state |= 0xf0; |
| 2827 | tq_state &= 0xfc; | 2827 | tq_state &= 0xfc; |
| 2828 | tq_state |= (u8)(tqueue_pos >> 8); | 2828 | tq_state |= (u8)(tqueue_pos >> 8); |
| 2829 | outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state); | 2829 | SiS_SetReg(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state); |
| 2830 | 2830 | ||
| 2831 | outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff)); | 2831 | SiS_SetReg(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff)); |
| 2832 | 2832 | ||
| 2833 | ivideo->caps |= TURBO_QUEUE_CAP; | 2833 | ivideo->caps |= TURBO_QUEUE_CAP; |
| 2834 | } | 2834 | } |
| @@ -2865,8 +2865,8 @@ sisfb_engine_init(struct sis_video_info *ivideo) | |||
| 2865 | } | 2865 | } |
| 2866 | } | 2866 | } |
| 2867 | 2867 | ||
| 2868 | outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); | 2868 | SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); |
| 2869 | outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET); | 2869 | SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET); |
| 2870 | 2870 | ||
| 2871 | if((ivideo->chip >= XGI_40) && ivideo->modechanged) { | 2871 | if((ivideo->chip >= XGI_40) && ivideo->modechanged) { |
| 2872 | /* Must disable dual pipe on XGI_40. Can't do | 2872 | /* Must disable dual pipe on XGI_40. Can't do |
| @@ -2878,7 +2878,7 @@ sisfb_engine_init(struct sis_video_info *ivideo) | |||
| 2878 | 2878 | ||
| 2879 | MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, 0); | 2879 | MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, 0); |
| 2880 | 2880 | ||
| 2881 | outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, (temp | SIS_VRAM_CMDQUEUE_ENABLE)); | 2881 | SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, (temp | SIS_VRAM_CMDQUEUE_ENABLE)); |
| 2882 | 2882 | ||
| 2883 | tempq = MMIO_IN32(ivideo->mmio_vbase, Q_READ_PTR); | 2883 | tempq = MMIO_IN32(ivideo->mmio_vbase, Q_READ_PTR); |
| 2884 | MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, tempq); | 2884 | MMIO_OUT32(ivideo->mmio_vbase, Q_WRITE_PTR, tempq); |
| @@ -2895,7 +2895,7 @@ sisfb_engine_init(struct sis_video_info *ivideo) | |||
| 2895 | 2895 | ||
| 2896 | sisfb_syncaccel(ivideo); | 2896 | sisfb_syncaccel(ivideo); |
| 2897 | 2897 | ||
| 2898 | outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET); | 2898 | SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET); |
| 2899 | 2899 | ||
| 2900 | } | 2900 | } |
| 2901 | } | 2901 | } |
| @@ -2904,7 +2904,7 @@ sisfb_engine_init(struct sis_video_info *ivideo) | |||
| 2904 | MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq); | 2904 | MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq); |
| 2905 | 2905 | ||
| 2906 | temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR); | 2906 | temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR); |
| 2907 | outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp); | 2907 | SiS_SetReg(SISSR, IND_SIS_CMDQUEUE_SET, temp); |
| 2908 | 2908 | ||
| 2909 | tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize); | 2909 | tempq = (u32)(ivideo->video_size - ivideo->cmdQueueSize); |
| 2910 | MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq); | 2910 | MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq); |
| @@ -2922,7 +2922,7 @@ sisfb_detect_lcd_type(struct sis_video_info *ivideo) | |||
| 2922 | u8 reg; | 2922 | u8 reg; |
| 2923 | int i; | 2923 | int i; |
| 2924 | 2924 | ||
| 2925 | inSISIDXREG(SISCR, 0x36, reg); | 2925 | reg = SiS_GetReg(SISCR, 0x36); |
| 2926 | reg &= 0x0f; | 2926 | reg &= 0x0f; |
| 2927 | if(ivideo->sisvga_engine == SIS_300_VGA) { | 2927 | if(ivideo->sisvga_engine == SIS_300_VGA) { |
| 2928 | ivideo->CRT2LCDType = sis300paneltype[reg]; | 2928 | ivideo->CRT2LCDType = sis300paneltype[reg]; |
| @@ -2941,8 +2941,8 @@ sisfb_detect_lcd_type(struct sis_video_info *ivideo) | |||
| 2941 | if(ivideo->CRT2LCDType == LCD_UNKNOWN) { | 2941 | if(ivideo->CRT2LCDType == LCD_UNKNOWN) { |
| 2942 | /* For broken BIOSes: Assume 1024x768, RGB18 */ | 2942 | /* For broken BIOSes: Assume 1024x768, RGB18 */ |
| 2943 | ivideo->CRT2LCDType = LCD_1024x768; | 2943 | ivideo->CRT2LCDType = LCD_1024x768; |
| 2944 | setSISIDXREG(SISCR,0x36,0xf0,0x02); | 2944 | SiS_SetRegANDOR(SISCR, 0x36, 0xf0, 0x02); |
| 2945 | setSISIDXREG(SISCR,0x37,0xee,0x01); | 2945 | SiS_SetRegANDOR(SISCR, 0x37, 0xee, 0x01); |
| 2946 | printk(KERN_DEBUG "sisfb: Invalid panel ID (%02x), assuming 1024x768, RGB18\n", reg); | 2946 | printk(KERN_DEBUG "sisfb: Invalid panel ID (%02x), assuming 1024x768, RGB18\n", reg); |
| 2947 | } | 2947 | } |
| 2948 | 2948 | ||
| @@ -2980,10 +2980,10 @@ sisfb_save_pdc_emi(struct sis_video_info *ivideo) | |||
| 2980 | if(ivideo->sisvga_engine == SIS_300_VGA) { | 2980 | if(ivideo->sisvga_engine == SIS_300_VGA) { |
| 2981 | if(ivideo->vbflags2 & (VB2_LVDS | VB2_30xBDH)) { | 2981 | if(ivideo->vbflags2 & (VB2_LVDS | VB2_30xBDH)) { |
| 2982 | int tmp; | 2982 | int tmp; |
| 2983 | inSISIDXREG(SISCR,0x30,tmp); | 2983 | tmp = SiS_GetReg(SISCR, 0x30); |
| 2984 | if(tmp & 0x20) { | 2984 | if(tmp & 0x20) { |
| 2985 | /* Currently on LCD? If yes, read current pdc */ | 2985 | /* Currently on LCD? If yes, read current pdc */ |
| 2986 | inSISIDXREG(SISPART1,0x13,ivideo->detectedpdc); | 2986 | ivideo->detectedpdc = SiS_GetReg(SISPART1, 0x13); |
| 2987 | ivideo->detectedpdc &= 0x3c; | 2987 | ivideo->detectedpdc &= 0x3c; |
| 2988 | if(ivideo->SiS_Pr.PDC == -1) { | 2988 | if(ivideo->SiS_Pr.PDC == -1) { |
| 2989 | /* Let option override detection */ | 2989 | /* Let option override detection */ |
| @@ -3007,7 +3007,7 @@ sisfb_save_pdc_emi(struct sis_video_info *ivideo) | |||
| 3007 | /* Try to find about LCDA */ | 3007 | /* Try to find about LCDA */ |
| 3008 | if(ivideo->vbflags2 & VB2_SISLCDABRIDGE) { | 3008 | if(ivideo->vbflags2 & VB2_SISLCDABRIDGE) { |
| 3009 | int tmp; | 3009 | int tmp; |
| 3010 | inSISIDXREG(SISPART1,0x13,tmp); | 3010 | tmp = SiS_GetReg(SISPART1, 0x13); |
| 3011 | if(tmp & 0x04) { | 3011 | if(tmp & 0x04) { |
| 3012 | ivideo->SiS_Pr.SiS_UseLCDA = true; | 3012 | ivideo->SiS_Pr.SiS_UseLCDA = true; |
| 3013 | ivideo->detectedlcda = 0x03; | 3013 | ivideo->detectedlcda = 0x03; |
| @@ -3017,16 +3017,16 @@ sisfb_save_pdc_emi(struct sis_video_info *ivideo) | |||
| 3017 | /* Save PDC */ | 3017 | /* Save PDC */ |
| 3018 | if(ivideo->vbflags2 & VB2_SISLVDSBRIDGE) { | 3018 | if(ivideo->vbflags2 & VB2_SISLVDSBRIDGE) { |
| 3019 | int tmp; | 3019 | int tmp; |
| 3020 | inSISIDXREG(SISCR,0x30,tmp); | 3020 | tmp = SiS_GetReg(SISCR, 0x30); |
| 3021 | if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) { | 3021 | if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) { |
| 3022 | /* Currently on LCD? If yes, read current pdc */ | 3022 | /* Currently on LCD? If yes, read current pdc */ |
| 3023 | u8 pdc; | 3023 | u8 pdc; |
| 3024 | inSISIDXREG(SISPART1,0x2D,pdc); | 3024 | pdc = SiS_GetReg(SISPART1, 0x2D); |
| 3025 | ivideo->detectedpdc = (pdc & 0x0f) << 1; | 3025 | ivideo->detectedpdc = (pdc & 0x0f) << 1; |
| 3026 | ivideo->detectedpdca = (pdc & 0xf0) >> 3; | 3026 | ivideo->detectedpdca = (pdc & 0xf0) >> 3; |
| 3027 | inSISIDXREG(SISPART1,0x35,pdc); | 3027 | pdc = SiS_GetReg(SISPART1, 0x35); |
| 3028 | ivideo->detectedpdc |= ((pdc >> 7) & 0x01); | 3028 | ivideo->detectedpdc |= ((pdc >> 7) & 0x01); |
| 3029 | inSISIDXREG(SISPART1,0x20,pdc); | 3029 | pdc = SiS_GetReg(SISPART1, 0x20); |
| 3030 | ivideo->detectedpdca |= ((pdc >> 6) & 0x01); | 3030 | ivideo->detectedpdca |= ((pdc >> 6) & 0x01); |
| 3031 | if(ivideo->newrom) { | 3031 | if(ivideo->newrom) { |
| 3032 | /* New ROM invalidates other PDC resp. */ | 3032 | /* New ROM invalidates other PDC resp. */ |
| @@ -3060,10 +3060,10 @@ sisfb_save_pdc_emi(struct sis_video_info *ivideo) | |||
| 3060 | 3060 | ||
| 3061 | /* Save EMI */ | 3061 | /* Save EMI */ |
| 3062 | if(ivideo->vbflags2 & VB2_SISEMIBRIDGE) { | 3062 | if(ivideo->vbflags2 & VB2_SISEMIBRIDGE) { |
| 3063 | inSISIDXREG(SISPART4,0x30,ivideo->SiS_Pr.EMI_30); | 3063 | ivideo->SiS_Pr.EMI_30 = SiS_GetReg(SISPART4, 0x30); |
| 3064 | inSISIDXREG(SISPART4,0x31,ivideo->SiS_Pr.EMI_31); | 3064 | ivideo->SiS_Pr.EMI_31 = SiS_GetReg(SISPART4, 0x31); |
| 3065 | inSISIDXREG(SISPART4,0x32,ivideo->SiS_Pr.EMI_32); | 3065 | ivideo->SiS_Pr.EMI_32 = SiS_GetReg(SISPART4, 0x32); |
| 3066 | inSISIDXREG(SISPART4,0x33,ivideo->SiS_Pr.EMI_33); | 3066 | ivideo->SiS_Pr.EMI_33 = SiS_GetReg(SISPART4, 0x33); |
| 3067 | ivideo->SiS_Pr.HaveEMI = true; | 3067 | ivideo->SiS_Pr.HaveEMI = true; |
| 3068 | if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) { | 3068 | if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) { |
| 3069 | ivideo->SiS_Pr.HaveEMILCD = true; | 3069 | ivideo->SiS_Pr.HaveEMILCD = true; |
| @@ -3488,8 +3488,8 @@ sisfb_check_engine_and_sync(struct sis_video_info *ivideo) | |||
| 3488 | * ivideo->accel here, as this might have | 3488 | * ivideo->accel here, as this might have |
| 3489 | * been changed before this is called. | 3489 | * been changed before this is called. |
| 3490 | */ | 3490 | */ |
| 3491 | inSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, cr30); | 3491 | cr30 = SiS_GetReg(SISSR, IND_SIS_PCI_ADDRESS_SET); |
| 3492 | inSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, cr31); | 3492 | cr31 = SiS_GetReg(SISSR, IND_SIS_MODULE_ENABLE); |
| 3493 | /* MMIO and 2D/3D engine enabled? */ | 3493 | /* MMIO and 2D/3D engine enabled? */ |
| 3494 | if((cr30 & SIS_MEM_MAP_IO_ENABLE) && (cr31 & 0x42)) { | 3494 | if((cr30 & SIS_MEM_MAP_IO_ENABLE) && (cr31 & 0x42)) { |
| 3495 | #ifdef CONFIG_FB_SIS_300 | 3495 | #ifdef CONFIG_FB_SIS_300 |
| @@ -3507,7 +3507,7 @@ sisfb_check_engine_and_sync(struct sis_video_info *ivideo) | |||
| 3507 | * enabled, and that the queue | 3507 | * enabled, and that the queue |
| 3508 | * is not in the state of "reset" | 3508 | * is not in the state of "reset" |
| 3509 | */ | 3509 | */ |
| 3510 | inSISIDXREG(SISSR, 0x26, cr30); | 3510 | cr30 = SiS_GetReg(SISSR, 0x26); |
| 3511 | if((cr30 & 0xe0) && (!(cr30 & 0x01))) { | 3511 | if((cr30 & 0xe0) && (!(cr30 & 0x01))) { |
| 3512 | sisfb_syncaccel(ivideo); | 3512 | sisfb_syncaccel(ivideo); |
| 3513 | } | 3513 | } |
| @@ -3524,9 +3524,9 @@ sisfb_pre_setmode(struct sis_video_info *ivideo) | |||
| 3524 | 3524 | ||
| 3525 | ivideo->currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2); | 3525 | ivideo->currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2); |
| 3526 | 3526 | ||
| 3527 | outSISIDXREG(SISSR, 0x05, 0x86); | 3527 | SiS_SetReg(SISSR, 0x05, 0x86); |
| 3528 | 3528 | ||
| 3529 | inSISIDXREG(SISCR, 0x31, cr31); | 3529 | cr31 = SiS_GetReg(SISCR, 0x31); |
| 3530 | cr31 &= ~0x60; | 3530 | cr31 &= ~0x60; |
| 3531 | cr31 |= 0x04; | 3531 | cr31 |= 0x04; |
| 3532 | 3532 | ||
| @@ -3535,11 +3535,11 @@ sisfb_pre_setmode(struct sis_video_info *ivideo) | |||
| 3535 | #ifdef CONFIG_FB_SIS_315 | 3535 | #ifdef CONFIG_FB_SIS_315 |
| 3536 | if(ivideo->sisvga_engine == SIS_315_VGA) { | 3536 | if(ivideo->sisvga_engine == SIS_315_VGA) { |
| 3537 | if(ivideo->chip >= SIS_661) { | 3537 | if(ivideo->chip >= SIS_661) { |
| 3538 | inSISIDXREG(SISCR, 0x38, cr38); | 3538 | cr38 = SiS_GetReg(SISCR, 0x38); |
| 3539 | cr38 &= ~0x07; /* Clear LCDA/DualEdge and YPbPr bits */ | 3539 | cr38 &= ~0x07; /* Clear LCDA/DualEdge and YPbPr bits */ |
| 3540 | } else { | 3540 | } else { |
| 3541 | tvregnum = 0x38; | 3541 | tvregnum = 0x38; |
| 3542 | inSISIDXREG(SISCR, tvregnum, cr38); | 3542 | cr38 = SiS_GetReg(SISCR, tvregnum); |
| 3543 | cr38 &= ~0x3b; /* Clear LCDA/DualEdge and YPbPr bits */ | 3543 | cr38 &= ~0x3b; /* Clear LCDA/DualEdge and YPbPr bits */ |
| 3544 | } | 3544 | } |
| 3545 | } | 3545 | } |
| @@ -3547,7 +3547,7 @@ sisfb_pre_setmode(struct sis_video_info *ivideo) | |||
| 3547 | #ifdef CONFIG_FB_SIS_300 | 3547 | #ifdef CONFIG_FB_SIS_300 |
| 3548 | if(ivideo->sisvga_engine == SIS_300_VGA) { | 3548 | if(ivideo->sisvga_engine == SIS_300_VGA) { |
| 3549 | tvregnum = 0x35; | 3549 | tvregnum = 0x35; |
| 3550 | inSISIDXREG(SISCR, tvregnum, cr38); | 3550 | cr38 = SiS_GetReg(SISCR, tvregnum); |
| 3551 | } | 3551 | } |
| 3552 | #endif | 3552 | #endif |
| 3553 | 3553 | ||
| @@ -3654,20 +3654,20 @@ sisfb_pre_setmode(struct sis_video_info *ivideo) | |||
| 3654 | cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE); | 3654 | cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE); |
| 3655 | } | 3655 | } |
| 3656 | 3656 | ||
| 3657 | outSISIDXREG(SISCR, 0x30, cr30); | 3657 | SiS_SetReg(SISCR, 0x30, cr30); |
| 3658 | outSISIDXREG(SISCR, 0x33, cr33); | 3658 | SiS_SetReg(SISCR, 0x33, cr33); |
| 3659 | 3659 | ||
| 3660 | if(ivideo->chip >= SIS_661) { | 3660 | if(ivideo->chip >= SIS_661) { |
| 3661 | #ifdef CONFIG_FB_SIS_315 | 3661 | #ifdef CONFIG_FB_SIS_315 |
| 3662 | cr31 &= ~0x01; /* Clear PAL flag (now in CR35) */ | 3662 | cr31 &= ~0x01; /* Clear PAL flag (now in CR35) */ |
| 3663 | setSISIDXREG(SISCR, 0x35, ~0x10, cr35); /* Leave overscan bit alone */ | 3663 | SiS_SetRegANDOR(SISCR, 0x35, ~0x10, cr35); /* Leave overscan bit alone */ |
| 3664 | cr38 &= 0x07; /* Use only LCDA and HiVision/YPbPr bits */ | 3664 | cr38 &= 0x07; /* Use only LCDA and HiVision/YPbPr bits */ |
| 3665 | setSISIDXREG(SISCR, 0x38, 0xf8, cr38); | 3665 | SiS_SetRegANDOR(SISCR, 0x38, 0xf8, cr38); |
| 3666 | #endif | 3666 | #endif |
| 3667 | } else if(ivideo->chip != SIS_300) { | 3667 | } else if(ivideo->chip != SIS_300) { |
| 3668 | outSISIDXREG(SISCR, tvregnum, cr38); | 3668 | SiS_SetReg(SISCR, tvregnum, cr38); |
| 3669 | } | 3669 | } |
| 3670 | outSISIDXREG(SISCR, 0x31, cr31); | 3670 | SiS_SetReg(SISCR, 0x31, cr31); |
| 3671 | 3671 | ||
| 3672 | ivideo->SiS_Pr.SiS_UseOEM = ivideo->sisfb_useoem; | 3672 | ivideo->SiS_Pr.SiS_UseOEM = ivideo->sisfb_useoem; |
| 3673 | 3673 | ||
| @@ -3682,15 +3682,15 @@ sisfb_fixup_SR11(struct sis_video_info *ivideo) | |||
| 3682 | u8 tmpreg; | 3682 | u8 tmpreg; |
| 3683 | 3683 | ||
| 3684 | if(ivideo->chip >= SIS_661) { | 3684 | if(ivideo->chip >= SIS_661) { |
| 3685 | inSISIDXREG(SISSR,0x11,tmpreg); | 3685 | tmpreg = SiS_GetReg(SISSR, 0x11); |
| 3686 | if(tmpreg & 0x20) { | 3686 | if(tmpreg & 0x20) { |
| 3687 | inSISIDXREG(SISSR,0x3e,tmpreg); | 3687 | tmpreg = SiS_GetReg(SISSR, 0x3e); |
| 3688 | tmpreg = (tmpreg + 1) & 0xff; | 3688 | tmpreg = (tmpreg + 1) & 0xff; |
| 3689 | outSISIDXREG(SISSR,0x3e,tmpreg); | 3689 | SiS_SetReg(SISSR, 0x3e, tmpreg); |
| 3690 | inSISIDXREG(SISSR,0x11,tmpreg); | 3690 | tmpreg = SiS_GetReg(SISSR, 0x11); |
| 3691 | } | 3691 | } |
| 3692 | if(tmpreg & 0xf0) { | 3692 | if(tmpreg & 0xf0) { |
| 3693 | andSISIDXREG(SISSR,0x11,0x0f); | 3693 | SiS_SetRegAND(SISSR, 0x11, 0x0f); |
| 3694 | } | 3694 | } |
| 3695 | } | 3695 | } |
| 3696 | } | 3696 | } |
| @@ -3716,7 +3716,7 @@ sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val) | |||
| 3716 | case 1: | 3716 | case 1: |
| 3717 | x += val; | 3717 | x += val; |
| 3718 | if(x < 0) x = 0; | 3718 | if(x < 0) x = 0; |
| 3719 | outSISIDXREG(SISSR,0x05,0x86); | 3719 | SiS_SetReg(SISSR, 0x05, 0x86); |
| 3720 | SiS_SetCH700x(&ivideo->SiS_Pr, 0x0a, (x & 0xff)); | 3720 | SiS_SetCH700x(&ivideo->SiS_Pr, 0x0a, (x & 0xff)); |
| 3721 | SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((x & 0x0100) >> 7), 0xFD); | 3721 | SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((x & 0x0100) >> 7), 0xFD); |
| 3722 | break; | 3722 | break; |
| @@ -3745,11 +3745,11 @@ sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val) | |||
| 3745 | temp += (val * 2); | 3745 | temp += (val * 2); |
| 3746 | p2_43 = temp & 0xff; | 3746 | p2_43 = temp & 0xff; |
| 3747 | p2_42 = (temp & 0xf00) >> 4; | 3747 | p2_42 = (temp & 0xf00) >> 4; |
| 3748 | outSISIDXREG(SISPART2,0x1f,p2_1f); | 3748 | SiS_SetReg(SISPART2, 0x1f, p2_1f); |
| 3749 | setSISIDXREG(SISPART2,0x20,0x0F,p2_20); | 3749 | SiS_SetRegANDOR(SISPART2, 0x20, 0x0F, p2_20); |
| 3750 | setSISIDXREG(SISPART2,0x2b,0xF0,p2_2b); | 3750 | SiS_SetRegANDOR(SISPART2, 0x2b, 0xF0, p2_2b); |
| 3751 | setSISIDXREG(SISPART2,0x42,0x0F,p2_42); | 3751 | SiS_SetRegANDOR(SISPART2, 0x42, 0x0F, p2_42); |
| 3752 | outSISIDXREG(SISPART2,0x43,p2_43); | 3752 | SiS_SetReg(SISPART2, 0x43, p2_43); |
| 3753 | } | 3753 | } |
| 3754 | } | 3754 | } |
| 3755 | } | 3755 | } |
| @@ -3774,7 +3774,7 @@ sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val) | |||
| 3774 | case 1: | 3774 | case 1: |
| 3775 | y -= val; | 3775 | y -= val; |
| 3776 | if(y < 0) y = 0; | 3776 | if(y < 0) y = 0; |
| 3777 | outSISIDXREG(SISSR,0x05,0x86); | 3777 | SiS_SetReg(SISSR, 0x05, 0x86); |
| 3778 | SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b, (y & 0xff)); | 3778 | SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b, (y & 0xff)); |
| 3779 | SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((y & 0x0100) >> 8), 0xFE); | 3779 | SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x08, ((y & 0x0100) >> 8), 0xFE); |
| 3780 | break; | 3780 | break; |
| @@ -3798,8 +3798,8 @@ sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val) | |||
| 3798 | p2_02 += 2; | 3798 | p2_02 += 2; |
| 3799 | } | 3799 | } |
| 3800 | } | 3800 | } |
| 3801 | outSISIDXREG(SISPART2,0x01,p2_01); | 3801 | SiS_SetReg(SISPART2, 0x01, p2_01); |
| 3802 | outSISIDXREG(SISPART2,0x02,p2_02); | 3802 | SiS_SetReg(SISPART2, 0x02, p2_02); |
| 3803 | } | 3803 | } |
| 3804 | } | 3804 | } |
| 3805 | } | 3805 | } |
| @@ -3816,7 +3816,7 @@ sisfb_post_setmode(struct sis_video_info *ivideo) | |||
| 3816 | u8 reg1; | 3816 | u8 reg1; |
| 3817 | #endif | 3817 | #endif |
| 3818 | 3818 | ||
| 3819 | outSISIDXREG(SISSR, 0x05, 0x86); | 3819 | SiS_SetReg(SISSR, 0x05, 0x86); |
| 3820 | 3820 | ||
| 3821 | #ifdef CONFIG_FB_SIS_315 | 3821 | #ifdef CONFIG_FB_SIS_315 |
| 3822 | sisfb_fixup_SR11(ivideo); | 3822 | sisfb_fixup_SR11(ivideo); |
| @@ -3840,7 +3840,7 @@ sisfb_post_setmode(struct sis_video_info *ivideo) | |||
| 3840 | crt1isoff = false; | 3840 | crt1isoff = false; |
| 3841 | reg = 0x80; | 3841 | reg = 0x80; |
| 3842 | } | 3842 | } |
| 3843 | setSISIDXREG(SISCR, 0x17, 0x7f, reg); | 3843 | SiS_SetRegANDOR(SISCR, 0x17, 0x7f, reg); |
| 3844 | } | 3844 | } |
| 3845 | #endif | 3845 | #endif |
| 3846 | #ifdef CONFIG_FB_SIS_315 | 3846 | #ifdef CONFIG_FB_SIS_315 |
| @@ -3854,8 +3854,8 @@ sisfb_post_setmode(struct sis_video_info *ivideo) | |||
| 3854 | reg = 0x00; | 3854 | reg = 0x00; |
| 3855 | reg1 = 0x00; | 3855 | reg1 = 0x00; |
| 3856 | } | 3856 | } |
| 3857 | setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg); | 3857 | SiS_SetRegANDOR(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg); |
| 3858 | setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1); | 3858 | SiS_SetRegANDOR(SISSR, 0x1f, 0x3f, reg1); |
| 3859 | } | 3859 | } |
| 3860 | #endif | 3860 | #endif |
| 3861 | 3861 | ||
| @@ -3871,17 +3871,17 @@ sisfb_post_setmode(struct sis_video_info *ivideo) | |||
| 3871 | } | 3871 | } |
| 3872 | } | 3872 | } |
| 3873 | 3873 | ||
| 3874 | andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04); | 3874 | SiS_SetRegAND(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04); |
| 3875 | 3875 | ||
| 3876 | if(ivideo->currentvbflags & CRT2_TV) { | 3876 | if(ivideo->currentvbflags & CRT2_TV) { |
| 3877 | if(ivideo->vbflags2 & VB2_SISBRIDGE) { | 3877 | if(ivideo->vbflags2 & VB2_SISBRIDGE) { |
| 3878 | inSISIDXREG(SISPART2,0x1f,ivideo->p2_1f); | 3878 | ivideo->p2_1f = SiS_GetReg(SISPART2, 0x1f); |
| 3879 | inSISIDXREG(SISPART2,0x20,ivideo->p2_20); | 3879 | ivideo->p2_20 = SiS_GetReg(SISPART2, 0x20); |
| 3880 | inSISIDXREG(SISPART2,0x2b,ivideo->p2_2b); | 3880 | ivideo->p2_2b = SiS_GetReg(SISPART2, 0x2b); |
| 3881 | inSISIDXREG(SISPART2,0x42,ivideo->p2_42); | 3881 | ivideo->p2_42 = SiS_GetReg(SISPART2, 0x42); |
| 3882 | inSISIDXREG(SISPART2,0x43,ivideo->p2_43); | 3882 | ivideo->p2_43 = SiS_GetReg(SISPART2, 0x43); |
| 3883 | inSISIDXREG(SISPART2,0x01,ivideo->p2_01); | 3883 | ivideo->p2_01 = SiS_GetReg(SISPART2, 0x01); |
| 3884 | inSISIDXREG(SISPART2,0x02,ivideo->p2_02); | 3884 | ivideo->p2_02 = SiS_GetReg(SISPART2, 0x02); |
| 3885 | } else if(ivideo->vbflags2 & VB2_CHRONTEL) { | 3885 | } else if(ivideo->vbflags2 & VB2_CHRONTEL) { |
| 3886 | if(ivideo->chronteltype == 1) { | 3886 | if(ivideo->chronteltype == 1) { |
| 3887 | ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a); | 3887 | ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a); |
| @@ -4105,7 +4105,6 @@ sisfb_find_rom(struct pci_dev *pdev) | |||
| 4105 | struct sis_video_info *ivideo = pci_get_drvdata(pdev); | 4105 | struct sis_video_info *ivideo = pci_get_drvdata(pdev); |
| 4106 | void __iomem *rom_base; | 4106 | void __iomem *rom_base; |
| 4107 | unsigned char *myrombase = NULL; | 4107 | unsigned char *myrombase = NULL; |
| 4108 | u32 temp; | ||
| 4109 | size_t romsize; | 4108 | size_t romsize; |
| 4110 | 4109 | ||
| 4111 | /* First, try the official pci ROM functions (except | 4110 | /* First, try the official pci ROM functions (except |
| @@ -4132,26 +4131,29 @@ sisfb_find_rom(struct pci_dev *pdev) | |||
| 4132 | /* Otherwise do it the conventional way. */ | 4131 | /* Otherwise do it the conventional way. */ |
| 4133 | 4132 | ||
| 4134 | #if defined(__i386__) || defined(__x86_64__) | 4133 | #if defined(__i386__) || defined(__x86_64__) |
| 4134 | { | ||
| 4135 | u32 temp; | ||
| 4135 | 4136 | ||
| 4136 | for(temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) { | 4137 | for (temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) { |
| 4137 | 4138 | ||
| 4138 | rom_base = ioremap(temp, 65536); | 4139 | rom_base = ioremap(temp, 65536); |
| 4139 | if(!rom_base) | 4140 | if (!rom_base) |
| 4140 | continue; | 4141 | continue; |
| 4141 | 4142 | ||
| 4142 | if(!sisfb_check_rom(rom_base, ivideo)) { | 4143 | if (!sisfb_check_rom(rom_base, ivideo)) { |
| 4143 | iounmap(rom_base); | 4144 | iounmap(rom_base); |
| 4144 | continue; | 4145 | continue; |
| 4145 | } | 4146 | } |
| 4146 | 4147 | ||
| 4147 | if((myrombase = vmalloc(65536))) | 4148 | if ((myrombase = vmalloc(65536))) |
| 4148 | memcpy_fromio(myrombase, rom_base, 65536); | 4149 | memcpy_fromio(myrombase, rom_base, 65536); |
| 4149 | 4150 | ||
| 4150 | iounmap(rom_base); | 4151 | iounmap(rom_base); |
| 4151 | break; | 4152 | break; |
| 4152 | 4153 | ||
| 4153 | } | 4154 | } |
| 4154 | 4155 | ||
| 4156 | } | ||
| 4155 | #endif | 4157 | #endif |
| 4156 | 4158 | ||
| 4157 | return myrombase; | 4159 | return myrombase; |
| @@ -4192,10 +4194,10 @@ sisfb_post_300_buswidth(struct sis_video_info *ivideo) | |||
| 4192 | unsigned char reg; | 4194 | unsigned char reg; |
| 4193 | int i, j; | 4195 | int i, j; |
| 4194 | 4196 | ||
| 4195 | andSISIDXREG(SISSR, 0x15, 0xFB); | 4197 | SiS_SetRegAND(SISSR, 0x15, 0xFB); |
| 4196 | orSISIDXREG(SISSR, 0x15, 0x04); | 4198 | SiS_SetRegOR(SISSR, 0x15, 0x04); |
| 4197 | outSISIDXREG(SISSR, 0x13, 0x00); | 4199 | SiS_SetReg(SISSR, 0x13, 0x00); |
| 4198 | outSISIDXREG(SISSR, 0x14, 0xBF); | 4200 | SiS_SetReg(SISSR, 0x14, 0xBF); |
| 4199 | 4201 | ||
| 4200 | for(i = 0; i < 2; i++) { | 4202 | for(i = 0; i < 2; i++) { |
| 4201 | temp = 0x1234; | 4203 | temp = 0x1234; |
| @@ -4203,12 +4205,12 @@ sisfb_post_300_buswidth(struct sis_video_info *ivideo) | |||
| 4203 | writew(temp, FBAddress); | 4205 | writew(temp, FBAddress); |
| 4204 | if(readw(FBAddress) == temp) | 4206 | if(readw(FBAddress) == temp) |
| 4205 | break; | 4207 | break; |
| 4206 | orSISIDXREG(SISSR, 0x3c, 0x01); | 4208 | SiS_SetRegOR(SISSR, 0x3c, 0x01); |
| 4207 | inSISIDXREG(SISSR, 0x05, reg); | 4209 | reg = SiS_GetReg(SISSR, 0x05); |
| 4208 | inSISIDXREG(SISSR, 0x05, reg); | 4210 | reg = SiS_GetReg(SISSR, 0x05); |
| 4209 | andSISIDXREG(SISSR, 0x3c, 0xfe); | 4211 | SiS_SetRegAND(SISSR, 0x3c, 0xfe); |
| 4210 | inSISIDXREG(SISSR, 0x05, reg); | 4212 | reg = SiS_GetReg(SISSR, 0x05); |
| 4211 | inSISIDXREG(SISSR, 0x05, reg); | 4213 | reg = SiS_GetReg(SISSR, 0x05); |
| 4212 | temp++; | 4214 | temp++; |
| 4213 | } | 4215 | } |
| 4214 | } | 4216 | } |
| @@ -4218,7 +4220,7 @@ sisfb_post_300_buswidth(struct sis_video_info *ivideo) | |||
| 4218 | writel(0x89ABCDEFL, (FBAddress + 8)); | 4220 | writel(0x89ABCDEFL, (FBAddress + 8)); |
| 4219 | writel(0xCDEF0123L, (FBAddress + 12)); | 4221 | writel(0xCDEF0123L, (FBAddress + 12)); |
| 4220 | 4222 | ||
| 4221 | inSISIDXREG(SISSR, 0x3b, reg); | 4223 | reg = SiS_GetReg(SISSR, 0x3b); |
| 4222 | if(reg & 0x01) { | 4224 | if(reg & 0x01) { |
| 4223 | if(readl((FBAddress + 12)) == 0xCDEF0123L) | 4225 | if(readl((FBAddress + 12)) == 0xCDEF0123L) |
| 4224 | return 4; /* Channel A 128bit */ | 4226 | return 4; /* Channel A 128bit */ |
| @@ -4281,13 +4283,13 @@ sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration, int buswidth | |||
| 4281 | PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity; | 4283 | PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity; |
| 4282 | PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh; | 4284 | PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh; |
| 4283 | 4285 | ||
| 4284 | andSISIDXREG(SISSR, 0x15, 0xFB); /* Test */ | 4286 | SiS_SetRegAND(SISSR, 0x15, 0xFB); /* Test */ |
| 4285 | orSISIDXREG(SISSR, 0x15, 0x04); /* Test */ | 4287 | SiS_SetRegOR(SISSR, 0x15, 0x04); /* Test */ |
| 4286 | sr14 = (SiS_DRAMType[k][3] * buswidth) - 1; | 4288 | sr14 = (SiS_DRAMType[k][3] * buswidth) - 1; |
| 4287 | if(buswidth == 4) sr14 |= 0x80; | 4289 | if(buswidth == 4) sr14 |= 0x80; |
| 4288 | else if(buswidth == 2) sr14 |= 0x40; | 4290 | else if(buswidth == 2) sr14 |= 0x40; |
| 4289 | outSISIDXREG(SISSR, 0x13, SiS_DRAMType[k][4]); | 4291 | SiS_SetReg(SISSR, 0x13, SiS_DRAMType[k][4]); |
| 4290 | outSISIDXREG(SISSR, 0x14, sr14); | 4292 | SiS_SetReg(SISSR, 0x14, sr14); |
| 4291 | 4293 | ||
| 4292 | BankNumHigh <<= 16; | 4294 | BankNumHigh <<= 16; |
| 4293 | BankNumMid <<= 16; | 4295 | BankNumMid <<= 16; |
| @@ -4354,13 +4356,13 @@ sisfb_post_sis300(struct pci_dev *pdev) | |||
| 4354 | if(!ivideo->SiS_Pr.UseROM) | 4356 | if(!ivideo->SiS_Pr.UseROM) |
| 4355 | bios = NULL; | 4357 | bios = NULL; |
| 4356 | 4358 | ||
| 4357 | outSISIDXREG(SISSR, 0x05, 0x86); | 4359 | SiS_SetReg(SISSR, 0x05, 0x86); |
| 4358 | 4360 | ||
| 4359 | if(bios) { | 4361 | if(bios) { |
| 4360 | if(bios[0x52] & 0x80) { | 4362 | if(bios[0x52] & 0x80) { |
| 4361 | memtype = bios[0x52]; | 4363 | memtype = bios[0x52]; |
| 4362 | } else { | 4364 | } else { |
| 4363 | inSISIDXREG(SISSR, 0x3a, memtype); | 4365 | memtype = SiS_GetReg(SISSR, 0x3a); |
| 4364 | } | 4366 | } |
| 4365 | memtype &= 0x07; | 4367 | memtype &= 0x07; |
| 4366 | } | 4368 | } |
| @@ -4384,19 +4386,19 @@ sisfb_post_sis300(struct pci_dev *pdev) | |||
| 4384 | v6 = bios[rindex++]; | 4386 | v6 = bios[rindex++]; |
| 4385 | } | 4387 | } |
| 4386 | } | 4388 | } |
| 4387 | outSISIDXREG(SISSR, 0x28, v1); | 4389 | SiS_SetReg(SISSR, 0x28, v1); |
| 4388 | outSISIDXREG(SISSR, 0x29, v2); | 4390 | SiS_SetReg(SISSR, 0x29, v2); |
| 4389 | outSISIDXREG(SISSR, 0x2a, v3); | 4391 | SiS_SetReg(SISSR, 0x2a, v3); |
| 4390 | outSISIDXREG(SISSR, 0x2e, v4); | 4392 | SiS_SetReg(SISSR, 0x2e, v4); |
| 4391 | outSISIDXREG(SISSR, 0x2f, v5); | 4393 | SiS_SetReg(SISSR, 0x2f, v5); |
| 4392 | outSISIDXREG(SISSR, 0x30, v6); | 4394 | SiS_SetReg(SISSR, 0x30, v6); |
| 4393 | 4395 | ||
| 4394 | v1 = 0x10; | 4396 | v1 = 0x10; |
| 4395 | if(bios) | 4397 | if(bios) |
| 4396 | v1 = bios[0xa4]; | 4398 | v1 = bios[0xa4]; |
| 4397 | outSISIDXREG(SISSR, 0x07, v1); /* DAC speed */ | 4399 | SiS_SetReg(SISSR, 0x07, v1); /* DAC speed */ |
| 4398 | 4400 | ||
| 4399 | outSISIDXREG(SISSR, 0x11, 0x0f); /* DDC, power save */ | 4401 | SiS_SetReg(SISSR, 0x11, 0x0f); /* DDC, power save */ |
| 4400 | 4402 | ||
| 4401 | v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a; | 4403 | v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a; |
| 4402 | v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00; | 4404 | v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00; |
| @@ -4413,87 +4415,87 @@ sisfb_post_sis300(struct pci_dev *pdev) | |||
| 4413 | } | 4415 | } |
| 4414 | if(ivideo->revision_id >= 0x80) | 4416 | if(ivideo->revision_id >= 0x80) |
| 4415 | v3 &= 0xfd; | 4417 | v3 &= 0xfd; |
| 4416 | outSISIDXREG(SISSR, 0x15, v1); /* Ram type (assuming 0, BIOS 0xa5 step 8) */ | 4418 | SiS_SetReg(SISSR, 0x15, v1); /* Ram type (assuming 0, BIOS 0xa5 step 8) */ |
| 4417 | outSISIDXREG(SISSR, 0x16, v2); | 4419 | SiS_SetReg(SISSR, 0x16, v2); |
| 4418 | outSISIDXREG(SISSR, 0x17, v3); | 4420 | SiS_SetReg(SISSR, 0x17, v3); |
| 4419 | outSISIDXREG(SISSR, 0x18, v4); | 4421 | SiS_SetReg(SISSR, 0x18, v4); |
| 4420 | outSISIDXREG(SISSR, 0x19, v5); | 4422 | SiS_SetReg(SISSR, 0x19, v5); |
| 4421 | outSISIDXREG(SISSR, 0x1a, v6); | 4423 | SiS_SetReg(SISSR, 0x1a, v6); |
| 4422 | outSISIDXREG(SISSR, 0x1b, v7); | 4424 | SiS_SetReg(SISSR, 0x1b, v7); |
| 4423 | outSISIDXREG(SISSR, 0x1c, v8); /* ---- */ | 4425 | SiS_SetReg(SISSR, 0x1c, v8); /* ---- */ |
| 4424 | andSISIDXREG(SISSR, 0x15 ,0xfb); | 4426 | SiS_SetRegAND(SISSR, 0x15, 0xfb); |
| 4425 | orSISIDXREG(SISSR, 0x15, 0x04); | 4427 | SiS_SetRegOR(SISSR, 0x15, 0x04); |
| 4426 | if(bios) { | 4428 | if(bios) { |
| 4427 | if(bios[0x53] & 0x02) { | 4429 | if(bios[0x53] & 0x02) { |
| 4428 | orSISIDXREG(SISSR, 0x19, 0x20); | 4430 | SiS_SetRegOR(SISSR, 0x19, 0x20); |
| 4429 | } | 4431 | } |
| 4430 | } | 4432 | } |
| 4431 | v1 = 0x04; /* DAC pedestal (BIOS 0xe5) */ | 4433 | v1 = 0x04; /* DAC pedestal (BIOS 0xe5) */ |
| 4432 | if(ivideo->revision_id >= 0x80) | 4434 | if(ivideo->revision_id >= 0x80) |
| 4433 | v1 |= 0x01; | 4435 | v1 |= 0x01; |
| 4434 | outSISIDXREG(SISSR, 0x1f, v1); | 4436 | SiS_SetReg(SISSR, 0x1f, v1); |
| 4435 | outSISIDXREG(SISSR, 0x20, 0xa4); /* linear & relocated io & disable a0000 */ | 4437 | SiS_SetReg(SISSR, 0x20, 0xa4); /* linear & relocated io & disable a0000 */ |
| 4436 | v1 = 0xf6; v2 = 0x0d; v3 = 0x00; | 4438 | v1 = 0xf6; v2 = 0x0d; v3 = 0x00; |
| 4437 | if(bios) { | 4439 | if(bios) { |
| 4438 | v1 = bios[0xe8]; | 4440 | v1 = bios[0xe8]; |
| 4439 | v2 = bios[0xe9]; | 4441 | v2 = bios[0xe9]; |
| 4440 | v3 = bios[0xea]; | 4442 | v3 = bios[0xea]; |
| 4441 | } | 4443 | } |
| 4442 | outSISIDXREG(SISSR, 0x23, v1); | 4444 | SiS_SetReg(SISSR, 0x23, v1); |
| 4443 | outSISIDXREG(SISSR, 0x24, v2); | 4445 | SiS_SetReg(SISSR, 0x24, v2); |
| 4444 | outSISIDXREG(SISSR, 0x25, v3); | 4446 | SiS_SetReg(SISSR, 0x25, v3); |
| 4445 | outSISIDXREG(SISSR, 0x21, 0x84); | 4447 | SiS_SetReg(SISSR, 0x21, 0x84); |
| 4446 | outSISIDXREG(SISSR, 0x22, 0x00); | 4448 | SiS_SetReg(SISSR, 0x22, 0x00); |
| 4447 | outSISIDXREG(SISCR, 0x37, 0x00); | 4449 | SiS_SetReg(SISCR, 0x37, 0x00); |
| 4448 | orSISIDXREG(SISPART1, 0x24, 0x01); /* unlock crt2 */ | 4450 | SiS_SetRegOR(SISPART1, 0x24, 0x01); /* unlock crt2 */ |
| 4449 | outSISIDXREG(SISPART1, 0x00, 0x00); | 4451 | SiS_SetReg(SISPART1, 0x00, 0x00); |
| 4450 | v1 = 0x40; v2 = 0x11; | 4452 | v1 = 0x40; v2 = 0x11; |
| 4451 | if(bios) { | 4453 | if(bios) { |
| 4452 | v1 = bios[0xec]; | 4454 | v1 = bios[0xec]; |
| 4453 | v2 = bios[0xeb]; | 4455 | v2 = bios[0xeb]; |
| 4454 | } | 4456 | } |
| 4455 | outSISIDXREG(SISPART1, 0x02, v1); | 4457 | SiS_SetReg(SISPART1, 0x02, v1); |
| 4456 | 4458 | ||
| 4457 | if(ivideo->revision_id >= 0x80) | 4459 | if(ivideo->revision_id >= 0x80) |
| 4458 | v2 &= ~0x01; | 4460 | v2 &= ~0x01; |
| 4459 | 4461 | ||
| 4460 | inSISIDXREG(SISPART4, 0x00, reg); | 4462 | reg = SiS_GetReg(SISPART4, 0x00); |
| 4461 | if((reg == 1) || (reg == 2)) { | 4463 | if((reg == 1) || (reg == 2)) { |
| 4462 | outSISIDXREG(SISCR, 0x37, 0x02); | 4464 | SiS_SetReg(SISCR, 0x37, 0x02); |
| 4463 | outSISIDXREG(SISPART2, 0x00, 0x1c); | 4465 | SiS_SetReg(SISPART2, 0x00, 0x1c); |
| 4464 | v4 = 0x00; v5 = 0x00; v6 = 0x10; | 4466 | v4 = 0x00; v5 = 0x00; v6 = 0x10; |
| 4465 | if(ivideo->SiS_Pr.UseROM) { | 4467 | if(ivideo->SiS_Pr.UseROM) { |
| 4466 | v4 = bios[0xf5]; | 4468 | v4 = bios[0xf5]; |
| 4467 | v5 = bios[0xf6]; | 4469 | v5 = bios[0xf6]; |
| 4468 | v6 = bios[0xf7]; | 4470 | v6 = bios[0xf7]; |
| 4469 | } | 4471 | } |
| 4470 | outSISIDXREG(SISPART4, 0x0d, v4); | 4472 | SiS_SetReg(SISPART4, 0x0d, v4); |
| 4471 | outSISIDXREG(SISPART4, 0x0e, v5); | 4473 | SiS_SetReg(SISPART4, 0x0e, v5); |
| 4472 | outSISIDXREG(SISPART4, 0x10, v6); | 4474 | SiS_SetReg(SISPART4, 0x10, v6); |
| 4473 | outSISIDXREG(SISPART4, 0x0f, 0x3f); | 4475 | SiS_SetReg(SISPART4, 0x0f, 0x3f); |
| 4474 | inSISIDXREG(SISPART4, 0x01, reg); | 4476 | reg = SiS_GetReg(SISPART4, 0x01); |
| 4475 | if(reg >= 0xb0) { | 4477 | if(reg >= 0xb0) { |
| 4476 | inSISIDXREG(SISPART4, 0x23, reg); | 4478 | reg = SiS_GetReg(SISPART4, 0x23); |
| 4477 | reg &= 0x20; | 4479 | reg &= 0x20; |
| 4478 | reg <<= 1; | 4480 | reg <<= 1; |
| 4479 | outSISIDXREG(SISPART4, 0x23, reg); | 4481 | SiS_SetReg(SISPART4, 0x23, reg); |
| 4480 | } | 4482 | } |
| 4481 | } else { | 4483 | } else { |
| 4482 | v2 &= ~0x10; | 4484 | v2 &= ~0x10; |
| 4483 | } | 4485 | } |
| 4484 | outSISIDXREG(SISSR, 0x32, v2); | 4486 | SiS_SetReg(SISSR, 0x32, v2); |
| 4485 | 4487 | ||
| 4486 | andSISIDXREG(SISPART1, 0x24, 0xfe); /* Lock CRT2 */ | 4488 | SiS_SetRegAND(SISPART1, 0x24, 0xfe); /* Lock CRT2 */ |
| 4487 | 4489 | ||
| 4488 | inSISIDXREG(SISSR, 0x16, reg); | 4490 | reg = SiS_GetReg(SISSR, 0x16); |
| 4489 | reg &= 0xc3; | 4491 | reg &= 0xc3; |
| 4490 | outSISIDXREG(SISCR, 0x35, reg); | 4492 | SiS_SetReg(SISCR, 0x35, reg); |
| 4491 | outSISIDXREG(SISCR, 0x83, 0x00); | 4493 | SiS_SetReg(SISCR, 0x83, 0x00); |
| 4492 | #if !defined(__i386__) && !defined(__x86_64__) | 4494 | #if !defined(__i386__) && !defined(__x86_64__) |
| 4493 | if(sisfb_videoram) { | 4495 | if(sisfb_videoram) { |
| 4494 | outSISIDXREG(SISSR, 0x13, 0x28); /* ? */ | 4496 | SiS_SetReg(SISSR, 0x13, 0x28); /* ? */ |
| 4495 | reg = ((sisfb_videoram >> 10) - 1) | 0x40; | 4497 | reg = ((sisfb_videoram >> 10) - 1) | 0x40; |
| 4496 | outSISIDXREG(SISSR, 0x14, reg); | 4498 | SiS_SetReg(SISSR, 0x14, reg); |
| 4497 | } else { | 4499 | } else { |
| 4498 | #endif | 4500 | #endif |
| 4499 | /* Need to map max FB size for finding out about RAM size */ | 4501 | /* Need to map max FB size for finding out about RAM size */ |
| @@ -4506,8 +4508,8 @@ sisfb_post_sis300(struct pci_dev *pdev) | |||
| 4506 | } else { | 4508 | } else { |
| 4507 | printk(KERN_DEBUG | 4509 | printk(KERN_DEBUG |
| 4508 | "sisfb: Failed to map memory for size detection, assuming 8MB\n"); | 4510 | "sisfb: Failed to map memory for size detection, assuming 8MB\n"); |
| 4509 | outSISIDXREG(SISSR, 0x13, 0x28); /* ? */ | 4511 | SiS_SetReg(SISSR, 0x13, 0x28); /* ? */ |
| 4510 | outSISIDXREG(SISSR, 0x14, 0x47); /* 8MB, 64bit default */ | 4512 | SiS_SetReg(SISSR, 0x14, 0x47); /* 8MB, 64bit default */ |
| 4511 | } | 4513 | } |
| 4512 | #if !defined(__i386__) && !defined(__x86_64__) | 4514 | #if !defined(__i386__) && !defined(__x86_64__) |
| 4513 | } | 4515 | } |
| @@ -4516,7 +4518,7 @@ sisfb_post_sis300(struct pci_dev *pdev) | |||
| 4516 | v1 = bios[0xe6]; | 4518 | v1 = bios[0xe6]; |
| 4517 | v2 = bios[0xe7]; | 4519 | v2 = bios[0xe7]; |
| 4518 | } else { | 4520 | } else { |
| 4519 | inSISIDXREG(SISSR, 0x3a, reg); | 4521 | reg = SiS_GetReg(SISSR, 0x3a); |
| 4520 | if((reg & 0x30) == 0x30) { | 4522 | if((reg & 0x30) == 0x30) { |
| 4521 | v1 = 0x04; /* PCI */ | 4523 | v1 = 0x04; /* PCI */ |
| 4522 | v2 = 0x92; | 4524 | v2 = 0x92; |
| @@ -4525,8 +4527,8 @@ sisfb_post_sis300(struct pci_dev *pdev) | |||
| 4525 | v2 = 0xb2; | 4527 | v2 = 0xb2; |
| 4526 | } | 4528 | } |
| 4527 | } | 4529 | } |
| 4528 | outSISIDXREG(SISSR, 0x21, v1); | 4530 | SiS_SetReg(SISSR, 0x21, v1); |
| 4529 | outSISIDXREG(SISSR, 0x22, v2); | 4531 | SiS_SetReg(SISSR, 0x22, v2); |
| 4530 | 4532 | ||
| 4531 | /* Sense CRT1 */ | 4533 | /* Sense CRT1 */ |
| 4532 | sisfb_sense_crt1(ivideo); | 4534 | sisfb_sense_crt1(ivideo); |
| @@ -4539,13 +4541,13 @@ sisfb_post_sis300(struct pci_dev *pdev) | |||
| 4539 | ivideo->SiS_Pr.VideoMemorySize = 8 << 20; | 4541 | ivideo->SiS_Pr.VideoMemorySize = 8 << 20; |
| 4540 | SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80); | 4542 | SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80); |
| 4541 | 4543 | ||
| 4542 | outSISIDXREG(SISSR, 0x05, 0x86); | 4544 | SiS_SetReg(SISSR, 0x05, 0x86); |
| 4543 | 4545 | ||
| 4544 | /* Display off */ | 4546 | /* Display off */ |
| 4545 | orSISIDXREG(SISSR, 0x01, 0x20); | 4547 | SiS_SetRegOR(SISSR, 0x01, 0x20); |
| 4546 | 4548 | ||
| 4547 | /* Save mode number in CR34 */ | 4549 | /* Save mode number in CR34 */ |
| 4548 | outSISIDXREG(SISCR, 0x34, 0x2e); | 4550 | SiS_SetReg(SISCR, 0x34, 0x2e); |
| 4549 | 4551 | ||
| 4550 | /* Let everyone know what the current mode is */ | 4552 | /* Let everyone know what the current mode is */ |
| 4551 | ivideo->modeprechange = 0x2e; | 4553 | ivideo->modeprechange = 0x2e; |
| @@ -4568,7 +4570,7 @@ sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay) | |||
| 4568 | u8 reg; | 4570 | u8 reg; |
| 4569 | 4571 | ||
| 4570 | for(i = 0; i <= (delay * 10 * 36); i++) { | 4572 | for(i = 0; i <= (delay * 10 * 36); i++) { |
| 4571 | inSISIDXREG(SISSR, 0x05, reg); | 4573 | reg = SiS_GetReg(SISSR, 0x05); |
| 4572 | reg++; | 4574 | reg++; |
| 4573 | } | 4575 | } |
| 4574 | } | 4576 | } |
| @@ -4660,7 +4662,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) | |||
| 4660 | * - if running on non-x86, there usually is no VGA window | 4662 | * - if running on non-x86, there usually is no VGA window |
| 4661 | * at a0000. | 4663 | * at a0000. |
| 4662 | */ | 4664 | */ |
| 4663 | orSISIDXREG(SISSR, 0x20, (0x80 | 0x04)); | 4665 | SiS_SetRegOR(SISSR, 0x20, (0x80 | 0x04)); |
| 4664 | 4666 | ||
| 4665 | /* Need to map max FB size for finding out about RAM size */ | 4667 | /* Need to map max FB size for finding out about RAM size */ |
| 4666 | mapsize = ivideo->video_size; | 4668 | mapsize = ivideo->video_size; |
| @@ -4668,76 +4670,76 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) | |||
| 4668 | 4670 | ||
| 4669 | if(!ivideo->video_vbase) { | 4671 | if(!ivideo->video_vbase) { |
| 4670 | printk(KERN_ERR "sisfb: Unable to detect RAM size. Setting default.\n"); | 4672 | printk(KERN_ERR "sisfb: Unable to detect RAM size. Setting default.\n"); |
| 4671 | outSISIDXREG(SISSR, 0x13, 0x35); | 4673 | SiS_SetReg(SISSR, 0x13, 0x35); |
| 4672 | outSISIDXREG(SISSR, 0x14, 0x41); | 4674 | SiS_SetReg(SISSR, 0x14, 0x41); |
| 4673 | /* TODO */ | 4675 | /* TODO */ |
| 4674 | return; | 4676 | return; |
| 4675 | } | 4677 | } |
| 4676 | 4678 | ||
| 4677 | /* Non-interleaving */ | 4679 | /* Non-interleaving */ |
| 4678 | outSISIDXREG(SISSR, 0x15, 0x00); | 4680 | SiS_SetReg(SISSR, 0x15, 0x00); |
| 4679 | /* No tiling */ | 4681 | /* No tiling */ |
| 4680 | outSISIDXREG(SISSR, 0x1c, 0x00); | 4682 | SiS_SetReg(SISSR, 0x1c, 0x00); |
| 4681 | 4683 | ||
| 4682 | if(ivideo->chip == XGI_20) { | 4684 | if(ivideo->chip == XGI_20) { |
| 4683 | 4685 | ||
| 4684 | channelab = 1; | 4686 | channelab = 1; |
| 4685 | inSISIDXREG(SISCR, 0x97, reg); | 4687 | reg = SiS_GetReg(SISCR, 0x97); |
| 4686 | if(!(reg & 0x01)) { /* Single 32/16 */ | 4688 | if(!(reg & 0x01)) { /* Single 32/16 */ |
| 4687 | buswidth = 32; | 4689 | buswidth = 32; |
| 4688 | outSISIDXREG(SISSR, 0x13, 0xb1); | 4690 | SiS_SetReg(SISSR, 0x13, 0xb1); |
| 4689 | outSISIDXREG(SISSR, 0x14, 0x52); | 4691 | SiS_SetReg(SISSR, 0x14, 0x52); |
| 4690 | sisfb_post_xgi_delay(ivideo, 1); | 4692 | sisfb_post_xgi_delay(ivideo, 1); |
| 4691 | sr14 = 0x02; | 4693 | sr14 = 0x02; |
| 4692 | if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) | 4694 | if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) |
| 4693 | goto bail_out; | 4695 | goto bail_out; |
| 4694 | 4696 | ||
| 4695 | outSISIDXREG(SISSR, 0x13, 0x31); | 4697 | SiS_SetReg(SISSR, 0x13, 0x31); |
| 4696 | outSISIDXREG(SISSR, 0x14, 0x42); | 4698 | SiS_SetReg(SISSR, 0x14, 0x42); |
| 4697 | sisfb_post_xgi_delay(ivideo, 1); | 4699 | sisfb_post_xgi_delay(ivideo, 1); |
| 4698 | if(sisfb_post_xgi_rwtest(ivideo, 23, 23, mapsize)) | 4700 | if(sisfb_post_xgi_rwtest(ivideo, 23, 23, mapsize)) |
| 4699 | goto bail_out; | 4701 | goto bail_out; |
| 4700 | 4702 | ||
| 4701 | buswidth = 16; | 4703 | buswidth = 16; |
| 4702 | outSISIDXREG(SISSR, 0x13, 0xb1); | 4704 | SiS_SetReg(SISSR, 0x13, 0xb1); |
| 4703 | outSISIDXREG(SISSR, 0x14, 0x41); | 4705 | SiS_SetReg(SISSR, 0x14, 0x41); |
| 4704 | sisfb_post_xgi_delay(ivideo, 1); | 4706 | sisfb_post_xgi_delay(ivideo, 1); |
| 4705 | sr14 = 0x01; | 4707 | sr14 = 0x01; |
| 4706 | if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) | 4708 | if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) |
| 4707 | goto bail_out; | 4709 | goto bail_out; |
| 4708 | else | 4710 | else |
| 4709 | outSISIDXREG(SISSR, 0x13, 0x31); | 4711 | SiS_SetReg(SISSR, 0x13, 0x31); |
| 4710 | } else { /* Dual 16/8 */ | 4712 | } else { /* Dual 16/8 */ |
| 4711 | buswidth = 16; | 4713 | buswidth = 16; |
| 4712 | outSISIDXREG(SISSR, 0x13, 0xb1); | 4714 | SiS_SetReg(SISSR, 0x13, 0xb1); |
| 4713 | outSISIDXREG(SISSR, 0x14, 0x41); | 4715 | SiS_SetReg(SISSR, 0x14, 0x41); |
| 4714 | sisfb_post_xgi_delay(ivideo, 1); | 4716 | sisfb_post_xgi_delay(ivideo, 1); |
| 4715 | sr14 = 0x01; | 4717 | sr14 = 0x01; |
| 4716 | if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) | 4718 | if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) |
| 4717 | goto bail_out; | 4719 | goto bail_out; |
| 4718 | 4720 | ||
| 4719 | outSISIDXREG(SISSR, 0x13, 0x31); | 4721 | SiS_SetReg(SISSR, 0x13, 0x31); |
| 4720 | outSISIDXREG(SISSR, 0x14, 0x31); | 4722 | SiS_SetReg(SISSR, 0x14, 0x31); |
| 4721 | sisfb_post_xgi_delay(ivideo, 1); | 4723 | sisfb_post_xgi_delay(ivideo, 1); |
| 4722 | if(sisfb_post_xgi_rwtest(ivideo, 22, 22, mapsize)) | 4724 | if(sisfb_post_xgi_rwtest(ivideo, 22, 22, mapsize)) |
| 4723 | goto bail_out; | 4725 | goto bail_out; |
| 4724 | 4726 | ||
| 4725 | buswidth = 8; | 4727 | buswidth = 8; |
| 4726 | outSISIDXREG(SISSR, 0x13, 0xb1); | 4728 | SiS_SetReg(SISSR, 0x13, 0xb1); |
| 4727 | outSISIDXREG(SISSR, 0x14, 0x30); | 4729 | SiS_SetReg(SISSR, 0x14, 0x30); |
| 4728 | sisfb_post_xgi_delay(ivideo, 1); | 4730 | sisfb_post_xgi_delay(ivideo, 1); |
| 4729 | sr14 = 0x00; | 4731 | sr14 = 0x00; |
| 4730 | if(sisfb_post_xgi_rwtest(ivideo, 21, 22, mapsize)) | 4732 | if(sisfb_post_xgi_rwtest(ivideo, 21, 22, mapsize)) |
| 4731 | goto bail_out; | 4733 | goto bail_out; |
| 4732 | else | 4734 | else |
| 4733 | outSISIDXREG(SISSR, 0x13, 0x31); | 4735 | SiS_SetReg(SISSR, 0x13, 0x31); |
| 4734 | } | 4736 | } |
| 4735 | 4737 | ||
| 4736 | } else { /* XGI_40 */ | 4738 | } else { /* XGI_40 */ |
| 4737 | 4739 | ||
| 4738 | inSISIDXREG(SISCR, 0x97, reg); | 4740 | reg = SiS_GetReg(SISCR, 0x97); |
| 4739 | if(!(reg & 0x10)) { | 4741 | if(!(reg & 0x10)) { |
| 4740 | inSISIDXREG(SISSR, 0x39, reg); | 4742 | reg = SiS_GetReg(SISSR, 0x39); |
| 4741 | reg >>= 1; | 4743 | reg >>= 1; |
| 4742 | } | 4744 | } |
| 4743 | 4745 | ||
| @@ -4745,52 +4747,52 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) | |||
| 4745 | buswidth = 32; | 4747 | buswidth = 32; |
| 4746 | if(ivideo->revision_id == 2) { | 4748 | if(ivideo->revision_id == 2) { |
| 4747 | channelab = 2; | 4749 | channelab = 2; |
| 4748 | outSISIDXREG(SISSR, 0x13, 0xa1); | 4750 | SiS_SetReg(SISSR, 0x13, 0xa1); |
| 4749 | outSISIDXREG(SISSR, 0x14, 0x44); | 4751 | SiS_SetReg(SISSR, 0x14, 0x44); |
| 4750 | sr14 = 0x04; | 4752 | sr14 = 0x04; |
| 4751 | sisfb_post_xgi_delay(ivideo, 1); | 4753 | sisfb_post_xgi_delay(ivideo, 1); |
| 4752 | if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) | 4754 | if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) |
| 4753 | goto bail_out; | 4755 | goto bail_out; |
| 4754 | 4756 | ||
| 4755 | outSISIDXREG(SISSR, 0x13, 0x21); | 4757 | SiS_SetReg(SISSR, 0x13, 0x21); |
| 4756 | outSISIDXREG(SISSR, 0x14, 0x34); | 4758 | SiS_SetReg(SISSR, 0x14, 0x34); |
| 4757 | if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) | 4759 | if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) |
| 4758 | goto bail_out; | 4760 | goto bail_out; |
| 4759 | 4761 | ||
| 4760 | channelab = 1; | 4762 | channelab = 1; |
| 4761 | outSISIDXREG(SISSR, 0x13, 0xa1); | 4763 | SiS_SetReg(SISSR, 0x13, 0xa1); |
| 4762 | outSISIDXREG(SISSR, 0x14, 0x40); | 4764 | SiS_SetReg(SISSR, 0x14, 0x40); |
| 4763 | sr14 = 0x00; | 4765 | sr14 = 0x00; |
| 4764 | if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) | 4766 | if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize)) |
| 4765 | goto bail_out; | 4767 | goto bail_out; |
| 4766 | 4768 | ||
| 4767 | outSISIDXREG(SISSR, 0x13, 0x21); | 4769 | SiS_SetReg(SISSR, 0x13, 0x21); |
| 4768 | outSISIDXREG(SISSR, 0x14, 0x30); | 4770 | SiS_SetReg(SISSR, 0x14, 0x30); |
| 4769 | } else { | 4771 | } else { |
| 4770 | channelab = 3; | 4772 | channelab = 3; |
| 4771 | outSISIDXREG(SISSR, 0x13, 0xa1); | 4773 | SiS_SetReg(SISSR, 0x13, 0xa1); |
| 4772 | outSISIDXREG(SISSR, 0x14, 0x4c); | 4774 | SiS_SetReg(SISSR, 0x14, 0x4c); |
| 4773 | sr14 = 0x0c; | 4775 | sr14 = 0x0c; |
| 4774 | sisfb_post_xgi_delay(ivideo, 1); | 4776 | sisfb_post_xgi_delay(ivideo, 1); |
| 4775 | if(sisfb_post_xgi_rwtest(ivideo, 23, 25, mapsize)) | 4777 | if(sisfb_post_xgi_rwtest(ivideo, 23, 25, mapsize)) |
| 4776 | goto bail_out; | 4778 | goto bail_out; |
| 4777 | 4779 | ||
| 4778 | channelab = 2; | 4780 | channelab = 2; |
| 4779 | outSISIDXREG(SISSR, 0x14, 0x48); | 4781 | SiS_SetReg(SISSR, 0x14, 0x48); |
| 4780 | sisfb_post_xgi_delay(ivideo, 1); | 4782 | sisfb_post_xgi_delay(ivideo, 1); |
| 4781 | sr14 = 0x08; | 4783 | sr14 = 0x08; |
| 4782 | if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) | 4784 | if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) |
| 4783 | goto bail_out; | 4785 | goto bail_out; |
| 4784 | 4786 | ||
| 4785 | outSISIDXREG(SISSR, 0x13, 0x21); | 4787 | SiS_SetReg(SISSR, 0x13, 0x21); |
| 4786 | outSISIDXREG(SISSR, 0x14, 0x3c); | 4788 | SiS_SetReg(SISSR, 0x14, 0x3c); |
| 4787 | sr14 = 0x0c; | 4789 | sr14 = 0x0c; |
| 4788 | 4790 | ||
| 4789 | if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) { | 4791 | if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) { |
| 4790 | channelab = 3; | 4792 | channelab = 3; |
| 4791 | } else { | 4793 | } else { |
| 4792 | channelab = 2; | 4794 | channelab = 2; |
| 4793 | outSISIDXREG(SISSR, 0x14, 0x38); | 4795 | SiS_SetReg(SISSR, 0x14, 0x38); |
| 4794 | sr14 = 0x08; | 4796 | sr14 = 0x08; |
| 4795 | } | 4797 | } |
| 4796 | } | 4798 | } |
| @@ -4801,26 +4803,26 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) | |||
| 4801 | buswidth = 64; | 4803 | buswidth = 64; |
| 4802 | if(ivideo->revision_id == 2) { | 4804 | if(ivideo->revision_id == 2) { |
| 4803 | channelab = 1; | 4805 | channelab = 1; |
| 4804 | outSISIDXREG(SISSR, 0x13, 0xa1); | 4806 | SiS_SetReg(SISSR, 0x13, 0xa1); |
| 4805 | outSISIDXREG(SISSR, 0x14, 0x52); | 4807 | SiS_SetReg(SISSR, 0x14, 0x52); |
| 4806 | sisfb_post_xgi_delay(ivideo, 1); | 4808 | sisfb_post_xgi_delay(ivideo, 1); |
| 4807 | sr14 = 0x02; | 4809 | sr14 = 0x02; |
| 4808 | if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) | 4810 | if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) |
| 4809 | goto bail_out; | 4811 | goto bail_out; |
| 4810 | 4812 | ||
| 4811 | outSISIDXREG(SISSR, 0x13, 0x21); | 4813 | SiS_SetReg(SISSR, 0x13, 0x21); |
| 4812 | outSISIDXREG(SISSR, 0x14, 0x42); | 4814 | SiS_SetReg(SISSR, 0x14, 0x42); |
| 4813 | } else { | 4815 | } else { |
| 4814 | channelab = 2; | 4816 | channelab = 2; |
| 4815 | outSISIDXREG(SISSR, 0x13, 0xa1); | 4817 | SiS_SetReg(SISSR, 0x13, 0xa1); |
| 4816 | outSISIDXREG(SISSR, 0x14, 0x5a); | 4818 | SiS_SetReg(SISSR, 0x14, 0x5a); |
| 4817 | sisfb_post_xgi_delay(ivideo, 1); | 4819 | sisfb_post_xgi_delay(ivideo, 1); |
| 4818 | sr14 = 0x0a; | 4820 | sr14 = 0x0a; |
| 4819 | if(sisfb_post_xgi_rwtest(ivideo, 24, 25, mapsize)) | 4821 | if(sisfb_post_xgi_rwtest(ivideo, 24, 25, mapsize)) |
| 4820 | goto bail_out; | 4822 | goto bail_out; |
| 4821 | 4823 | ||
| 4822 | outSISIDXREG(SISSR, 0x13, 0x21); | 4824 | SiS_SetReg(SISSR, 0x13, 0x21); |
| 4823 | outSISIDXREG(SISSR, 0x14, 0x4a); | 4825 | SiS_SetReg(SISSR, 0x14, 0x4a); |
| 4824 | } | 4826 | } |
| 4825 | sisfb_post_xgi_delay(ivideo, 1); | 4827 | sisfb_post_xgi_delay(ivideo, 1); |
| 4826 | 4828 | ||
| @@ -4828,7 +4830,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo) | |||
| 4828 | } | 4830 | } |
| 4829 | 4831 | ||
| 4830 | bail_out: | 4832 | bail_out: |
| 4831 | setSISIDXREG(SISSR, 0x14, 0xf0, sr14); | 4833 | SiS_SetRegANDOR(SISSR, 0x14, 0xf0, sr14); |
| 4832 | sisfb_post_xgi_delay(ivideo, 1); | 4834 | sisfb_post_xgi_delay(ivideo, 1); |
| 4833 | 4835 | ||
| 4834 | j = (ivideo->chip == XGI_20) ? 5 : 9; | 4836 | j = (ivideo->chip == XGI_20) ? 5 : 9; |
| @@ -4838,13 +4840,13 @@ bail_out: | |||
| 4838 | 4840 | ||
| 4839 | reg = (ivideo->chip == XGI_20) ? | 4841 | reg = (ivideo->chip == XGI_20) ? |
| 4840 | dramsr13[(i * 5) + 4] : dramsr13_4[(i * 5) + 4]; | 4842 | dramsr13[(i * 5) + 4] : dramsr13_4[(i * 5) + 4]; |
| 4841 | setSISIDXREG(SISSR, 0x13, 0x80, reg); | 4843 | SiS_SetRegANDOR(SISSR, 0x13, 0x80, reg); |
| 4842 | sisfb_post_xgi_delay(ivideo, 50); | 4844 | sisfb_post_xgi_delay(ivideo, 50); |
| 4843 | 4845 | ||
| 4844 | ranksize = (ivideo->chip == XGI_20) ? | 4846 | ranksize = (ivideo->chip == XGI_20) ? |
| 4845 | dramsr13[(i * 5) + 3] : dramsr13_4[(i * 5) + 3]; | 4847 | dramsr13[(i * 5) + 3] : dramsr13_4[(i * 5) + 3]; |
| 4846 | 4848 | ||
| 4847 | inSISIDXREG(SISSR, 0x13, reg); | 4849 | reg = SiS_GetReg(SISSR, 0x13); |
| 4848 | if(reg & 0x80) ranksize <<= 1; | 4850 | if(reg & 0x80) ranksize <<= 1; |
| 4849 | 4851 | ||
| 4850 | if(ivideo->chip == XGI_20) { | 4852 | if(ivideo->chip == XGI_20) { |
| @@ -4863,7 +4865,7 @@ bail_out: | |||
| 4863 | 4865 | ||
| 4864 | if(!reg) continue; | 4866 | if(!reg) continue; |
| 4865 | 4867 | ||
| 4866 | setSISIDXREG(SISSR, 0x14, 0x0f, (reg & 0xf0)); | 4868 | SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0)); |
| 4867 | sisfb_post_xgi_delay(ivideo, 1); | 4869 | sisfb_post_xgi_delay(ivideo, 1); |
| 4868 | 4870 | ||
| 4869 | if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) | 4871 | if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) |
| @@ -4908,9 +4910,9 @@ sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb) | |||
| 4908 | v2 = ivideo->bios_abase[0x90 + index + 1]; | 4910 | v2 = ivideo->bios_abase[0x90 + index + 1]; |
| 4909 | v3 = ivideo->bios_abase[0x90 + index + 2]; | 4911 | v3 = ivideo->bios_abase[0x90 + index + 2]; |
| 4910 | } | 4912 | } |
| 4911 | outSISIDXREG(SISSR, 0x28, v1); | 4913 | SiS_SetReg(SISSR, 0x28, v1); |
| 4912 | outSISIDXREG(SISSR, 0x29, v2); | 4914 | SiS_SetReg(SISSR, 0x29, v2); |
| 4913 | outSISIDXREG(SISSR, 0x2a, v3); | 4915 | SiS_SetReg(SISSR, 0x2a, v3); |
| 4914 | sisfb_post_xgi_delay(ivideo, 0x43); | 4916 | sisfb_post_xgi_delay(ivideo, 0x43); |
| 4915 | sisfb_post_xgi_delay(ivideo, 0x43); | 4917 | sisfb_post_xgi_delay(ivideo, 0x43); |
| 4916 | sisfb_post_xgi_delay(ivideo, 0x43); | 4918 | sisfb_post_xgi_delay(ivideo, 0x43); |
| @@ -4921,9 +4923,9 @@ sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb) | |||
| 4921 | v2 = ivideo->bios_abase[0xb8 + index + 1]; | 4923 | v2 = ivideo->bios_abase[0xb8 + index + 1]; |
| 4922 | v3 = ivideo->bios_abase[0xb8 + index + 2]; | 4924 | v3 = ivideo->bios_abase[0xb8 + index + 2]; |
| 4923 | } | 4925 | } |
| 4924 | outSISIDXREG(SISSR, 0x2e, v1); | 4926 | SiS_SetReg(SISSR, 0x2e, v1); |
| 4925 | outSISIDXREG(SISSR, 0x2f, v2); | 4927 | SiS_SetReg(SISSR, 0x2f, v2); |
| 4926 | outSISIDXREG(SISSR, 0x30, v3); | 4928 | SiS_SetReg(SISSR, 0x30, v3); |
| 4927 | sisfb_post_xgi_delay(ivideo, 0x43); | 4929 | sisfb_post_xgi_delay(ivideo, 0x43); |
| 4928 | sisfb_post_xgi_delay(ivideo, 0x43); | 4930 | sisfb_post_xgi_delay(ivideo, 0x43); |
| 4929 | sisfb_post_xgi_delay(ivideo, 0x43); | 4931 | sisfb_post_xgi_delay(ivideo, 0x43); |
| @@ -4996,29 +4998,29 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 4996 | }; | 4998 | }; |
| 4997 | 4999 | ||
| 4998 | /* VGA enable */ | 5000 | /* VGA enable */ |
| 4999 | reg = inSISREG(SISVGAENABLE) | 0x01; | 5001 | reg = SiS_GetRegByte(SISVGAENABLE) | 0x01; |
| 5000 | outSISREG(SISVGAENABLE, reg); | 5002 | SiS_SetRegByte(SISVGAENABLE, reg); |
| 5001 | 5003 | ||
| 5002 | /* Misc */ | 5004 | /* Misc */ |
| 5003 | reg = inSISREG(SISMISCR) | 0x01; | 5005 | reg = SiS_GetRegByte(SISMISCR) | 0x01; |
| 5004 | outSISREG(SISMISCW, reg); | 5006 | SiS_SetRegByte(SISMISCW, reg); |
| 5005 | 5007 | ||
| 5006 | /* Unlock SR */ | 5008 | /* Unlock SR */ |
| 5007 | outSISIDXREG(SISSR, 0x05, 0x86); | 5009 | SiS_SetReg(SISSR, 0x05, 0x86); |
| 5008 | inSISIDXREG(SISSR, 0x05, reg); | 5010 | reg = SiS_GetReg(SISSR, 0x05); |
| 5009 | if(reg != 0xa1) | 5011 | if(reg != 0xa1) |
| 5010 | return 0; | 5012 | return 0; |
| 5011 | 5013 | ||
| 5012 | /* Clear some regs */ | 5014 | /* Clear some regs */ |
| 5013 | for(i = 0; i < 0x22; i++) { | 5015 | for(i = 0; i < 0x22; i++) { |
| 5014 | if(0x06 + i == 0x20) continue; | 5016 | if(0x06 + i == 0x20) continue; |
| 5015 | outSISIDXREG(SISSR, 0x06 + i, 0x00); | 5017 | SiS_SetReg(SISSR, 0x06 + i, 0x00); |
| 5016 | } | 5018 | } |
| 5017 | for(i = 0; i < 0x0b; i++) { | 5019 | for(i = 0; i < 0x0b; i++) { |
| 5018 | outSISIDXREG(SISSR, 0x31 + i, 0x00); | 5020 | SiS_SetReg(SISSR, 0x31 + i, 0x00); |
| 5019 | } | 5021 | } |
| 5020 | for(i = 0; i < 0x10; i++) { | 5022 | for(i = 0; i < 0x10; i++) { |
| 5021 | outSISIDXREG(SISCR, 0x30 + i, 0x00); | 5023 | SiS_SetReg(SISCR, 0x30 + i, 0x00); |
| 5022 | } | 5024 | } |
| 5023 | 5025 | ||
| 5024 | ptr = cs78; | 5026 | ptr = cs78; |
| @@ -5026,7 +5028,7 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5026 | ptr = (const u8 *)&bios[0x78]; | 5028 | ptr = (const u8 *)&bios[0x78]; |
| 5027 | } | 5029 | } |
| 5028 | for(i = 0; i < 3; i++) { | 5030 | for(i = 0; i < 3; i++) { |
| 5029 | outSISIDXREG(SISSR, 0x23 + i, ptr[i]); | 5031 | SiS_SetReg(SISSR, 0x23 + i, ptr[i]); |
| 5030 | } | 5032 | } |
| 5031 | 5033 | ||
| 5032 | ptr = cs76; | 5034 | ptr = cs76; |
| @@ -5034,7 +5036,7 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5034 | ptr = (const u8 *)&bios[0x76]; | 5036 | ptr = (const u8 *)&bios[0x76]; |
| 5035 | } | 5037 | } |
| 5036 | for(i = 0; i < 2; i++) { | 5038 | for(i = 0; i < 2; i++) { |
| 5037 | outSISIDXREG(SISSR, 0x21 + i, ptr[i]); | 5039 | SiS_SetReg(SISSR, 0x21 + i, ptr[i]); |
| 5038 | } | 5040 | } |
| 5039 | 5041 | ||
| 5040 | v1 = 0x18; v2 = 0x00; | 5042 | v1 = 0x18; v2 = 0x00; |
| @@ -5042,83 +5044,83 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5042 | v1 = bios[0x74]; | 5044 | v1 = bios[0x74]; |
| 5043 | v2 = bios[0x75]; | 5045 | v2 = bios[0x75]; |
| 5044 | } | 5046 | } |
| 5045 | outSISIDXREG(SISSR, 0x07, v1); | 5047 | SiS_SetReg(SISSR, 0x07, v1); |
| 5046 | outSISIDXREG(SISSR, 0x11, 0x0f); | 5048 | SiS_SetReg(SISSR, 0x11, 0x0f); |
| 5047 | outSISIDXREG(SISSR, 0x1f, v2); | 5049 | SiS_SetReg(SISSR, 0x1f, v2); |
| 5048 | /* PCI linear mode, RelIO enabled, A0000 decoding disabled */ | 5050 | /* PCI linear mode, RelIO enabled, A0000 decoding disabled */ |
| 5049 | outSISIDXREG(SISSR, 0x20, 0x80 | 0x20 | 0x04); | 5051 | SiS_SetReg(SISSR, 0x20, 0x80 | 0x20 | 0x04); |
| 5050 | outSISIDXREG(SISSR, 0x27, 0x74); | 5052 | SiS_SetReg(SISSR, 0x27, 0x74); |
| 5051 | 5053 | ||
| 5052 | ptr = cs7b; | 5054 | ptr = cs7b; |
| 5053 | if(ivideo->haveXGIROM) { | 5055 | if(ivideo->haveXGIROM) { |
| 5054 | ptr = (const u8 *)&bios[0x7b]; | 5056 | ptr = (const u8 *)&bios[0x7b]; |
| 5055 | } | 5057 | } |
| 5056 | for(i = 0; i < 3; i++) { | 5058 | for(i = 0; i < 3; i++) { |
| 5057 | outSISIDXREG(SISSR, 0x31 + i, ptr[i]); | 5059 | SiS_SetReg(SISSR, 0x31 + i, ptr[i]); |
| 5058 | } | 5060 | } |
| 5059 | 5061 | ||
| 5060 | if(ivideo->chip == XGI_40) { | 5062 | if(ivideo->chip == XGI_40) { |
| 5061 | if(ivideo->revision_id == 2) { | 5063 | if(ivideo->revision_id == 2) { |
| 5062 | setSISIDXREG(SISSR, 0x3b, 0x3f, 0xc0); | 5064 | SiS_SetRegANDOR(SISSR, 0x3b, 0x3f, 0xc0); |
| 5063 | } | 5065 | } |
| 5064 | outSISIDXREG(SISCR, 0x7d, 0xfe); | 5066 | SiS_SetReg(SISCR, 0x7d, 0xfe); |
| 5065 | outSISIDXREG(SISCR, 0x7e, 0x0f); | 5067 | SiS_SetReg(SISCR, 0x7e, 0x0f); |
| 5066 | } | 5068 | } |
| 5067 | if(ivideo->revision_id == 0) { /* 40 *and* 20? */ | 5069 | if(ivideo->revision_id == 0) { /* 40 *and* 20? */ |
| 5068 | andSISIDXREG(SISCR, 0x58, 0xd7); | 5070 | SiS_SetRegAND(SISCR, 0x58, 0xd7); |
| 5069 | inSISIDXREG(SISCR, 0xcb, reg); | 5071 | reg = SiS_GetReg(SISCR, 0xcb); |
| 5070 | if(reg & 0x20) { | 5072 | if(reg & 0x20) { |
| 5071 | setSISIDXREG(SISCR, 0x58, 0xd7, (reg & 0x10) ? 0x08 : 0x20); /* =0x28 Z7 ? */ | 5073 | SiS_SetRegANDOR(SISCR, 0x58, 0xd7, (reg & 0x10) ? 0x08 : 0x20); /* =0x28 Z7 ? */ |
| 5072 | } | 5074 | } |
| 5073 | } | 5075 | } |
| 5074 | 5076 | ||
| 5075 | reg = (ivideo->chip == XGI_40) ? 0x20 : 0x00; | 5077 | reg = (ivideo->chip == XGI_40) ? 0x20 : 0x00; |
| 5076 | setSISIDXREG(SISCR, 0x38, 0x1f, reg); | 5078 | SiS_SetRegANDOR(SISCR, 0x38, 0x1f, reg); |
| 5077 | 5079 | ||
| 5078 | if(ivideo->chip == XGI_20) { | 5080 | if(ivideo->chip == XGI_20) { |
| 5079 | outSISIDXREG(SISSR, 0x36, 0x70); | 5081 | SiS_SetReg(SISSR, 0x36, 0x70); |
| 5080 | } else { | 5082 | } else { |
| 5081 | outSISIDXREG(SISVID, 0x00, 0x86); | 5083 | SiS_SetReg(SISVID, 0x00, 0x86); |
| 5082 | outSISIDXREG(SISVID, 0x32, 0x00); | 5084 | SiS_SetReg(SISVID, 0x32, 0x00); |
| 5083 | outSISIDXREG(SISVID, 0x30, 0x00); | 5085 | SiS_SetReg(SISVID, 0x30, 0x00); |
| 5084 | outSISIDXREG(SISVID, 0x32, 0x01); | 5086 | SiS_SetReg(SISVID, 0x32, 0x01); |
| 5085 | outSISIDXREG(SISVID, 0x30, 0x00); | 5087 | SiS_SetReg(SISVID, 0x30, 0x00); |
| 5086 | andSISIDXREG(SISVID, 0x2f, 0xdf); | 5088 | SiS_SetRegAND(SISVID, 0x2f, 0xdf); |
| 5087 | andSISIDXREG(SISCAP, 0x00, 0x3f); | 5089 | SiS_SetRegAND(SISCAP, 0x00, 0x3f); |
| 5088 | 5090 | ||
| 5089 | outSISIDXREG(SISPART1, 0x2f, 0x01); | 5091 | SiS_SetReg(SISPART1, 0x2f, 0x01); |
| 5090 | outSISIDXREG(SISPART1, 0x00, 0x00); | 5092 | SiS_SetReg(SISPART1, 0x00, 0x00); |
| 5091 | outSISIDXREG(SISPART1, 0x02, bios[0x7e]); | 5093 | SiS_SetReg(SISPART1, 0x02, bios[0x7e]); |
| 5092 | outSISIDXREG(SISPART1, 0x2e, 0x08); | 5094 | SiS_SetReg(SISPART1, 0x2e, 0x08); |
| 5093 | andSISIDXREG(SISPART1, 0x35, 0x7f); | 5095 | SiS_SetRegAND(SISPART1, 0x35, 0x7f); |
| 5094 | andSISIDXREG(SISPART1, 0x50, 0xfe); | 5096 | SiS_SetRegAND(SISPART1, 0x50, 0xfe); |
| 5095 | 5097 | ||
| 5096 | inSISIDXREG(SISPART4, 0x00, reg); | 5098 | reg = SiS_GetReg(SISPART4, 0x00); |
| 5097 | if(reg == 1 || reg == 2) { | 5099 | if(reg == 1 || reg == 2) { |
| 5098 | outSISIDXREG(SISPART2, 0x00, 0x1c); | 5100 | SiS_SetReg(SISPART2, 0x00, 0x1c); |
| 5099 | outSISIDXREG(SISPART4, 0x0d, bios[0x7f]); | 5101 | SiS_SetReg(SISPART4, 0x0d, bios[0x7f]); |
| 5100 | outSISIDXREG(SISPART4, 0x0e, bios[0x80]); | 5102 | SiS_SetReg(SISPART4, 0x0e, bios[0x80]); |
| 5101 | outSISIDXREG(SISPART4, 0x10, bios[0x81]); | 5103 | SiS_SetReg(SISPART4, 0x10, bios[0x81]); |
| 5102 | andSISIDXREG(SISPART4, 0x0f, 0x3f); | 5104 | SiS_SetRegAND(SISPART4, 0x0f, 0x3f); |
| 5103 | 5105 | ||
| 5104 | inSISIDXREG(SISPART4, 0x01, reg); | 5106 | reg = SiS_GetReg(SISPART4, 0x01); |
| 5105 | if((reg & 0xf0) >= 0xb0) { | 5107 | if((reg & 0xf0) >= 0xb0) { |
| 5106 | inSISIDXREG(SISPART4, 0x23, reg); | 5108 | reg = SiS_GetReg(SISPART4, 0x23); |
| 5107 | if(reg & 0x20) reg |= 0x40; | 5109 | if(reg & 0x20) reg |= 0x40; |
| 5108 | outSISIDXREG(SISPART4, 0x23, reg); | 5110 | SiS_SetReg(SISPART4, 0x23, reg); |
| 5109 | reg = (reg & 0x20) ? 0x02 : 0x00; | 5111 | reg = (reg & 0x20) ? 0x02 : 0x00; |
| 5110 | setSISIDXREG(SISPART1, 0x1e, 0xfd, reg); | 5112 | SiS_SetRegANDOR(SISPART1, 0x1e, 0xfd, reg); |
| 5111 | } | 5113 | } |
| 5112 | } | 5114 | } |
| 5113 | 5115 | ||
| 5114 | v1 = bios[0x77]; | 5116 | v1 = bios[0x77]; |
| 5115 | 5117 | ||
| 5116 | inSISIDXREG(SISSR, 0x3b, reg); | 5118 | reg = SiS_GetReg(SISSR, 0x3b); |
| 5117 | if(reg & 0x02) { | 5119 | if(reg & 0x02) { |
| 5118 | inSISIDXREG(SISSR, 0x3a, reg); | 5120 | reg = SiS_GetReg(SISSR, 0x3a); |
| 5119 | v2 = (reg & 0x30) >> 3; | 5121 | v2 = (reg & 0x30) >> 3; |
| 5120 | if(!(v2 & 0x04)) v2 ^= 0x02; | 5122 | if(!(v2 & 0x04)) v2 ^= 0x02; |
| 5121 | inSISIDXREG(SISSR, 0x39, reg); | 5123 | reg = SiS_GetReg(SISSR, 0x39); |
| 5122 | if(reg & 0x80) v2 |= 0x80; | 5124 | if(reg & 0x80) v2 |= 0x80; |
| 5123 | v2 |= 0x01; | 5125 | v2 |= 0x01; |
| 5124 | 5126 | ||
| @@ -5151,36 +5153,36 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5151 | v2 |= 0x08; | 5153 | v2 |= 0x08; |
| 5152 | } | 5154 | } |
| 5153 | } | 5155 | } |
| 5154 | setSISIDXREG(SISCR, 0x5f, 0xf0, v2); | 5156 | SiS_SetRegANDOR(SISCR, 0x5f, 0xf0, v2); |
| 5155 | } | 5157 | } |
| 5156 | outSISIDXREG(SISSR, 0x22, v1); | 5158 | SiS_SetReg(SISSR, 0x22, v1); |
| 5157 | 5159 | ||
| 5158 | if(ivideo->revision_id == 2) { | 5160 | if(ivideo->revision_id == 2) { |
| 5159 | inSISIDXREG(SISSR, 0x3b, v1); | 5161 | v1 = SiS_GetReg(SISSR, 0x3b); |
| 5160 | inSISIDXREG(SISSR, 0x3a, v2); | 5162 | v2 = SiS_GetReg(SISSR, 0x3a); |
| 5161 | regd = bios[0x90 + 3] | (bios[0x90 + 4] << 8); | 5163 | regd = bios[0x90 + 3] | (bios[0x90 + 4] << 8); |
| 5162 | if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) ) | 5164 | if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) ) |
| 5163 | setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01); | 5165 | SiS_SetRegANDOR(SISCR, 0x5f, 0xf1, 0x01); |
| 5164 | 5166 | ||
| 5165 | if((mypdev = pci_get_device(0x10de, 0x01e0, NULL))) { | 5167 | if((mypdev = pci_get_device(0x10de, 0x01e0, NULL))) { |
| 5166 | /* TODO: set CR5f &0xf1 | 0x01 for version 6570 | 5168 | /* TODO: set CR5f &0xf1 | 0x01 for version 6570 |
| 5167 | * of nforce 2 ROM | 5169 | * of nforce 2 ROM |
| 5168 | */ | 5170 | */ |
| 5169 | if(0) | 5171 | if(0) |
| 5170 | setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01); | 5172 | SiS_SetRegANDOR(SISCR, 0x5f, 0xf1, 0x01); |
| 5171 | pci_dev_put(mypdev); | 5173 | pci_dev_put(mypdev); |
| 5172 | } | 5174 | } |
| 5173 | } | 5175 | } |
| 5174 | 5176 | ||
| 5175 | v1 = 0x30; | 5177 | v1 = 0x30; |
| 5176 | inSISIDXREG(SISSR, 0x3b, reg); | 5178 | reg = SiS_GetReg(SISSR, 0x3b); |
| 5177 | inSISIDXREG(SISCR, 0x5f, v2); | 5179 | v2 = SiS_GetReg(SISCR, 0x5f); |
| 5178 | if((!(reg & 0x02)) && (v2 & 0x0e)) | 5180 | if((!(reg & 0x02)) && (v2 & 0x0e)) |
| 5179 | v1 |= 0x08; | 5181 | v1 |= 0x08; |
| 5180 | outSISIDXREG(SISSR, 0x27, v1); | 5182 | SiS_SetReg(SISSR, 0x27, v1); |
| 5181 | 5183 | ||
| 5182 | if(bios[0x64] & 0x01) { | 5184 | if(bios[0x64] & 0x01) { |
| 5183 | setSISIDXREG(SISCR, 0x5f, 0xf0, bios[0x64]); | 5185 | SiS_SetRegANDOR(SISCR, 0x5f, 0xf0, bios[0x64]); |
| 5184 | } | 5186 | } |
| 5185 | 5187 | ||
| 5186 | v1 = bios[0x4f7]; | 5188 | v1 = bios[0x4f7]; |
| @@ -5188,27 +5190,27 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5188 | regd = (regd >> 20) & 0x0f; | 5190 | regd = (regd >> 20) & 0x0f; |
| 5189 | if(regd == 1) { | 5191 | if(regd == 1) { |
| 5190 | v1 &= 0xfc; | 5192 | v1 &= 0xfc; |
| 5191 | orSISIDXREG(SISCR, 0x5f, 0x08); | 5193 | SiS_SetRegOR(SISCR, 0x5f, 0x08); |
| 5192 | } | 5194 | } |
| 5193 | outSISIDXREG(SISCR, 0x48, v1); | 5195 | SiS_SetReg(SISCR, 0x48, v1); |
| 5194 | 5196 | ||
| 5195 | setSISIDXREG(SISCR, 0x47, 0x04, bios[0x4f6] & 0xfb); | 5197 | SiS_SetRegANDOR(SISCR, 0x47, 0x04, bios[0x4f6] & 0xfb); |
| 5196 | setSISIDXREG(SISCR, 0x49, 0xf0, bios[0x4f8] & 0x0f); | 5198 | SiS_SetRegANDOR(SISCR, 0x49, 0xf0, bios[0x4f8] & 0x0f); |
| 5197 | setSISIDXREG(SISCR, 0x4a, 0x60, bios[0x4f9] & 0x9f); | 5199 | SiS_SetRegANDOR(SISCR, 0x4a, 0x60, bios[0x4f9] & 0x9f); |
| 5198 | setSISIDXREG(SISCR, 0x4b, 0x08, bios[0x4fa] & 0xf7); | 5200 | SiS_SetRegANDOR(SISCR, 0x4b, 0x08, bios[0x4fa] & 0xf7); |
| 5199 | setSISIDXREG(SISCR, 0x4c, 0x80, bios[0x4fb] & 0x7f); | 5201 | SiS_SetRegANDOR(SISCR, 0x4c, 0x80, bios[0x4fb] & 0x7f); |
| 5200 | outSISIDXREG(SISCR, 0x70, bios[0x4fc]); | 5202 | SiS_SetReg(SISCR, 0x70, bios[0x4fc]); |
| 5201 | setSISIDXREG(SISCR, 0x71, 0xf0, bios[0x4fd] & 0x0f); | 5203 | SiS_SetRegANDOR(SISCR, 0x71, 0xf0, bios[0x4fd] & 0x0f); |
| 5202 | outSISIDXREG(SISCR, 0x74, 0xd0); | 5204 | SiS_SetReg(SISCR, 0x74, 0xd0); |
| 5203 | setSISIDXREG(SISCR, 0x74, 0xcf, bios[0x4fe] & 0x30); | 5205 | SiS_SetRegANDOR(SISCR, 0x74, 0xcf, bios[0x4fe] & 0x30); |
| 5204 | setSISIDXREG(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f); | 5206 | SiS_SetRegANDOR(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f); |
| 5205 | setSISIDXREG(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f); | 5207 | SiS_SetRegANDOR(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f); |
| 5206 | v1 = bios[0x501]; | 5208 | v1 = bios[0x501]; |
| 5207 | if((mypdev = pci_get_device(0x8086, 0x2530, NULL))) { | 5209 | if((mypdev = pci_get_device(0x8086, 0x2530, NULL))) { |
| 5208 | v1 = 0xf0; | 5210 | v1 = 0xf0; |
| 5209 | pci_dev_put(mypdev); | 5211 | pci_dev_put(mypdev); |
| 5210 | } | 5212 | } |
| 5211 | outSISIDXREG(SISCR, 0x77, v1); | 5213 | SiS_SetReg(SISCR, 0x77, v1); |
| 5212 | } | 5214 | } |
| 5213 | 5215 | ||
| 5214 | /* RAM type */ | 5216 | /* RAM type */ |
| @@ -5219,14 +5221,14 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5219 | if(ivideo->haveXGIROM) { | 5221 | if(ivideo->haveXGIROM) { |
| 5220 | v1 = bios[0x140 + regb]; | 5222 | v1 = bios[0x140 + regb]; |
| 5221 | } | 5223 | } |
| 5222 | outSISIDXREG(SISCR, 0x6d, v1); | 5224 | SiS_SetReg(SISCR, 0x6d, v1); |
| 5223 | 5225 | ||
| 5224 | ptr = cs128; | 5226 | ptr = cs128; |
| 5225 | if(ivideo->haveXGIROM) { | 5227 | if(ivideo->haveXGIROM) { |
| 5226 | ptr = (const u8 *)&bios[0x128]; | 5228 | ptr = (const u8 *)&bios[0x128]; |
| 5227 | } | 5229 | } |
| 5228 | for(i = 0, j = 0; i < 3; i++, j += 8) { | 5230 | for(i = 0, j = 0; i < 3; i++, j += 8) { |
| 5229 | outSISIDXREG(SISCR, 0x68 + i, ptr[j + regb]); | 5231 | SiS_SetReg(SISCR, 0x68 + i, ptr[j + regb]); |
| 5230 | } | 5232 | } |
| 5231 | 5233 | ||
| 5232 | ptr = cs31a; | 5234 | ptr = cs31a; |
| @@ -5250,14 +5252,14 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5250 | if(regd & 0x01) reg |= 0x04; | 5252 | if(regd & 0x01) reg |= 0x04; |
| 5251 | if(regd & 0x02) reg |= 0x08; | 5253 | if(regd & 0x02) reg |= 0x08; |
| 5252 | regd >>= 2; | 5254 | regd >>= 2; |
| 5253 | outSISIDXREG(SISCR, rega, reg); | 5255 | SiS_SetReg(SISCR, rega, reg); |
| 5254 | inSISIDXREG(SISCR, rega, reg); | 5256 | reg = SiS_GetReg(SISCR, rega); |
| 5255 | inSISIDXREG(SISCR, rega, reg); | 5257 | reg = SiS_GetReg(SISCR, rega); |
| 5256 | reg += 0x10; | 5258 | reg += 0x10; |
| 5257 | } | 5259 | } |
| 5258 | } | 5260 | } |
| 5259 | 5261 | ||
| 5260 | andSISIDXREG(SISCR, 0x6e, 0xfc); | 5262 | SiS_SetRegAND(SISCR, 0x6e, 0xfc); |
| 5261 | 5263 | ||
| 5262 | ptr = NULL; | 5264 | ptr = NULL; |
| 5263 | if(ivideo->haveXGIROM) { | 5265 | if(ivideo->haveXGIROM) { |
| @@ -5265,7 +5267,7 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5265 | ptr = (const u8 *)&bios[index]; | 5267 | ptr = (const u8 *)&bios[index]; |
| 5266 | } | 5268 | } |
| 5267 | for(i = 0; i < 4; i++) { | 5269 | for(i = 0; i < 4; i++) { |
| 5268 | setSISIDXREG(SISCR, 0x6e, 0xfc, i); | 5270 | SiS_SetRegANDOR(SISCR, 0x6e, 0xfc, i); |
| 5269 | reg = 0x00; | 5271 | reg = 0x00; |
| 5270 | for(j = 0; j < 2; j++) { | 5272 | for(j = 0; j < 2; j++) { |
| 5271 | regd = 0; | 5273 | regd = 0; |
| @@ -5279,9 +5281,9 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5279 | if(regd & 0x01) reg |= 0x01; | 5281 | if(regd & 0x01) reg |= 0x01; |
| 5280 | if(regd & 0x02) reg |= 0x02; | 5282 | if(regd & 0x02) reg |= 0x02; |
| 5281 | regd >>= 2; | 5283 | regd >>= 2; |
| 5282 | outSISIDXREG(SISCR, 0x6f, reg); | 5284 | SiS_SetReg(SISCR, 0x6f, reg); |
| 5283 | inSISIDXREG(SISCR, 0x6f, reg); | 5285 | reg = SiS_GetReg(SISCR, 0x6f); |
| 5284 | inSISIDXREG(SISCR, 0x6f, reg); | 5286 | reg = SiS_GetReg(SISCR, 0x6f); |
| 5285 | reg += 0x08; | 5287 | reg += 0x08; |
| 5286 | } | 5288 | } |
| 5287 | } | 5289 | } |
| @@ -5292,10 +5294,10 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5292 | ptr = (const u8 *)&bios[0x148]; | 5294 | ptr = (const u8 *)&bios[0x148]; |
| 5293 | } | 5295 | } |
| 5294 | for(i = 0, j = 0; i < 2; i++, j += 8) { | 5296 | for(i = 0, j = 0; i < 2; i++, j += 8) { |
| 5295 | outSISIDXREG(SISCR, 0x80 + i, ptr[j + regb]); | 5297 | SiS_SetReg(SISCR, 0x80 + i, ptr[j + regb]); |
| 5296 | } | 5298 | } |
| 5297 | 5299 | ||
| 5298 | andSISIDXREG(SISCR, 0x89, 0x8f); | 5300 | SiS_SetRegAND(SISCR, 0x89, 0x8f); |
| 5299 | 5301 | ||
| 5300 | ptr = cs45a; | 5302 | ptr = cs45a; |
| 5301 | if(ivideo->haveXGIROM) { | 5303 | if(ivideo->haveXGIROM) { |
| @@ -5309,9 +5311,9 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5309 | if(regd & 0x01) reg |= 0x01; | 5311 | if(regd & 0x01) reg |= 0x01; |
| 5310 | if(regd & 0x02) reg |= 0x02; | 5312 | if(regd & 0x02) reg |= 0x02; |
| 5311 | regd >>= 2; | 5313 | regd >>= 2; |
| 5312 | outSISIDXREG(SISCR, 0x89, reg); | 5314 | SiS_SetReg(SISCR, 0x89, reg); |
| 5313 | inSISIDXREG(SISCR, 0x89, reg); | 5315 | reg = SiS_GetReg(SISCR, 0x89); |
| 5314 | inSISIDXREG(SISCR, 0x89, reg); | 5316 | reg = SiS_GetReg(SISCR, 0x89); |
| 5315 | reg += 0x10; | 5317 | reg += 0x10; |
| 5316 | } | 5318 | } |
| 5317 | 5319 | ||
| @@ -5322,27 +5324,27 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5322 | v3 = bios[0x120 + regb]; | 5324 | v3 = bios[0x120 + regb]; |
| 5323 | v4 = bios[0x1ca]; | 5325 | v4 = bios[0x1ca]; |
| 5324 | } | 5326 | } |
| 5325 | outSISIDXREG(SISCR, 0x45, v1 & 0x0f); | 5327 | SiS_SetReg(SISCR, 0x45, v1 & 0x0f); |
| 5326 | outSISIDXREG(SISCR, 0x99, (v1 >> 4) & 0x07); | 5328 | SiS_SetReg(SISCR, 0x99, (v1 >> 4) & 0x07); |
| 5327 | orSISIDXREG(SISCR, 0x40, v1 & 0x80); | 5329 | SiS_SetRegOR(SISCR, 0x40, v1 & 0x80); |
| 5328 | outSISIDXREG(SISCR, 0x41, v2); | 5330 | SiS_SetReg(SISCR, 0x41, v2); |
| 5329 | 5331 | ||
| 5330 | ptr = cs170; | 5332 | ptr = cs170; |
| 5331 | if(ivideo->haveXGIROM) { | 5333 | if(ivideo->haveXGIROM) { |
| 5332 | ptr = (const u8 *)&bios[0x170]; | 5334 | ptr = (const u8 *)&bios[0x170]; |
| 5333 | } | 5335 | } |
| 5334 | for(i = 0, j = 0; i < 7; i++, j += 8) { | 5336 | for(i = 0, j = 0; i < 7; i++, j += 8) { |
| 5335 | outSISIDXREG(SISCR, 0x90 + i, ptr[j + regb]); | 5337 | SiS_SetReg(SISCR, 0x90 + i, ptr[j + regb]); |
| 5336 | } | 5338 | } |
| 5337 | 5339 | ||
| 5338 | outSISIDXREG(SISCR, 0x59, v3); | 5340 | SiS_SetReg(SISCR, 0x59, v3); |
| 5339 | 5341 | ||
| 5340 | ptr = cs1a8; | 5342 | ptr = cs1a8; |
| 5341 | if(ivideo->haveXGIROM) { | 5343 | if(ivideo->haveXGIROM) { |
| 5342 | ptr = (const u8 *)&bios[0x1a8]; | 5344 | ptr = (const u8 *)&bios[0x1a8]; |
| 5343 | } | 5345 | } |
| 5344 | for(i = 0, j = 0; i < 3; i++, j += 8) { | 5346 | for(i = 0, j = 0; i < 3; i++, j += 8) { |
| 5345 | outSISIDXREG(SISCR, 0xc3 + i, ptr[j + regb]); | 5347 | SiS_SetReg(SISCR, 0xc3 + i, ptr[j + regb]); |
| 5346 | } | 5348 | } |
| 5347 | 5349 | ||
| 5348 | ptr = cs100; | 5350 | ptr = cs100; |
| @@ -5350,27 +5352,27 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5350 | ptr = (const u8 *)&bios[0x100]; | 5352 | ptr = (const u8 *)&bios[0x100]; |
| 5351 | } | 5353 | } |
| 5352 | for(i = 0, j = 0; i < 2; i++, j += 8) { | 5354 | for(i = 0, j = 0; i < 2; i++, j += 8) { |
| 5353 | outSISIDXREG(SISCR, 0x8a + i, ptr[j + regb]); | 5355 | SiS_SetReg(SISCR, 0x8a + i, ptr[j + regb]); |
| 5354 | } | 5356 | } |
| 5355 | 5357 | ||
| 5356 | outSISIDXREG(SISCR, 0xcf, v4); | 5358 | SiS_SetReg(SISCR, 0xcf, v4); |
| 5357 | 5359 | ||
| 5358 | outSISIDXREG(SISCR, 0x83, 0x09); | 5360 | SiS_SetReg(SISCR, 0x83, 0x09); |
| 5359 | outSISIDXREG(SISCR, 0x87, 0x00); | 5361 | SiS_SetReg(SISCR, 0x87, 0x00); |
| 5360 | 5362 | ||
| 5361 | if(ivideo->chip == XGI_40) { | 5363 | if(ivideo->chip == XGI_40) { |
| 5362 | if( (ivideo->revision_id == 1) || | 5364 | if( (ivideo->revision_id == 1) || |
| 5363 | (ivideo->revision_id == 2) ) { | 5365 | (ivideo->revision_id == 2) ) { |
| 5364 | outSISIDXREG(SISCR, 0x8c, 0x87); | 5366 | SiS_SetReg(SISCR, 0x8c, 0x87); |
| 5365 | } | 5367 | } |
| 5366 | } | 5368 | } |
| 5367 | 5369 | ||
| 5368 | outSISIDXREG(SISSR, 0x17, 0x00); | 5370 | SiS_SetReg(SISSR, 0x17, 0x00); |
| 5369 | outSISIDXREG(SISSR, 0x1a, 0x87); | 5371 | SiS_SetReg(SISSR, 0x1a, 0x87); |
| 5370 | 5372 | ||
| 5371 | if(ivideo->chip == XGI_20) { | 5373 | if(ivideo->chip == XGI_20) { |
| 5372 | outSISIDXREG(SISSR, 0x15, 0x00); | 5374 | SiS_SetReg(SISSR, 0x15, 0x00); |
| 5373 | outSISIDXREG(SISSR, 0x1c, 0x00); | 5375 | SiS_SetReg(SISSR, 0x1c, 0x00); |
| 5374 | } | 5376 | } |
| 5375 | 5377 | ||
| 5376 | ramtype = 0x00; v1 = 0x10; | 5378 | ramtype = 0x00; v1 = 0x10; |
| @@ -5380,16 +5382,16 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5380 | } | 5382 | } |
| 5381 | if(!(ramtype & 0x80)) { | 5383 | if(!(ramtype & 0x80)) { |
| 5382 | if(ivideo->chip == XGI_20) { | 5384 | if(ivideo->chip == XGI_20) { |
| 5383 | outSISIDXREG(SISCR, 0x97, v1); | 5385 | SiS_SetReg(SISCR, 0x97, v1); |
| 5384 | inSISIDXREG(SISCR, 0x97, reg); | 5386 | reg = SiS_GetReg(SISCR, 0x97); |
| 5385 | if(reg & 0x10) { | 5387 | if(reg & 0x10) { |
| 5386 | ramtype = (reg & 0x01) << 1; | 5388 | ramtype = (reg & 0x01) << 1; |
| 5387 | } | 5389 | } |
| 5388 | } else { | 5390 | } else { |
| 5389 | inSISIDXREG(SISSR, 0x39, reg); | 5391 | reg = SiS_GetReg(SISSR, 0x39); |
| 5390 | ramtype = reg & 0x02; | 5392 | ramtype = reg & 0x02; |
| 5391 | if(!(ramtype)) { | 5393 | if(!(ramtype)) { |
| 5392 | inSISIDXREG(SISSR, 0x3a, reg); | 5394 | reg = SiS_GetReg(SISSR, 0x3a); |
| 5393 | ramtype = (reg >> 1) & 0x01; | 5395 | ramtype = (reg >> 1) & 0x01; |
| 5394 | } | 5396 | } |
| 5395 | } | 5397 | } |
| @@ -5410,55 +5412,55 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5410 | v2 = bios[regb + 0x160]; | 5412 | v2 = bios[regb + 0x160]; |
| 5411 | v3 = bios[regb + 0x168]; | 5413 | v3 = bios[regb + 0x168]; |
| 5412 | } | 5414 | } |
| 5413 | outSISIDXREG(SISCR, 0x82, v1); | 5415 | SiS_SetReg(SISCR, 0x82, v1); |
| 5414 | outSISIDXREG(SISCR, 0x85, v2); | 5416 | SiS_SetReg(SISCR, 0x85, v2); |
| 5415 | outSISIDXREG(SISCR, 0x86, v3); | 5417 | SiS_SetReg(SISCR, 0x86, v3); |
| 5416 | } else { | 5418 | } else { |
| 5417 | outSISIDXREG(SISCR, 0x82, 0x88); | 5419 | SiS_SetReg(SISCR, 0x82, 0x88); |
| 5418 | outSISIDXREG(SISCR, 0x86, 0x00); | 5420 | SiS_SetReg(SISCR, 0x86, 0x00); |
| 5419 | inSISIDXREG(SISCR, 0x86, reg); | 5421 | reg = SiS_GetReg(SISCR, 0x86); |
| 5420 | outSISIDXREG(SISCR, 0x86, 0x88); | 5422 | SiS_SetReg(SISCR, 0x86, 0x88); |
| 5421 | inSISIDXREG(SISCR, 0x86, reg); | 5423 | reg = SiS_GetReg(SISCR, 0x86); |
| 5422 | outSISIDXREG(SISCR, 0x86, bios[regb + 0x168]); | 5424 | SiS_SetReg(SISCR, 0x86, bios[regb + 0x168]); |
| 5423 | outSISIDXREG(SISCR, 0x82, 0x77); | 5425 | SiS_SetReg(SISCR, 0x82, 0x77); |
| 5424 | outSISIDXREG(SISCR, 0x85, 0x00); | 5426 | SiS_SetReg(SISCR, 0x85, 0x00); |
| 5425 | inSISIDXREG(SISCR, 0x85, reg); | 5427 | reg = SiS_GetReg(SISCR, 0x85); |
| 5426 | outSISIDXREG(SISCR, 0x85, 0x88); | 5428 | SiS_SetReg(SISCR, 0x85, 0x88); |
| 5427 | inSISIDXREG(SISCR, 0x85, reg); | 5429 | reg = SiS_GetReg(SISCR, 0x85); |
| 5428 | outSISIDXREG(SISCR, 0x85, bios[regb + 0x160]); | 5430 | SiS_SetReg(SISCR, 0x85, bios[regb + 0x160]); |
| 5429 | outSISIDXREG(SISCR, 0x82, bios[regb + 0x158]); | 5431 | SiS_SetReg(SISCR, 0x82, bios[regb + 0x158]); |
| 5430 | } | 5432 | } |
| 5431 | if(ivideo->chip == XGI_40) { | 5433 | if(ivideo->chip == XGI_40) { |
| 5432 | outSISIDXREG(SISCR, 0x97, 0x00); | 5434 | SiS_SetReg(SISCR, 0x97, 0x00); |
| 5433 | } | 5435 | } |
| 5434 | outSISIDXREG(SISCR, 0x98, 0x01); | 5436 | SiS_SetReg(SISCR, 0x98, 0x01); |
| 5435 | outSISIDXREG(SISCR, 0x9a, 0x02); | 5437 | SiS_SetReg(SISCR, 0x9a, 0x02); |
| 5436 | 5438 | ||
| 5437 | outSISIDXREG(SISSR, 0x18, 0x01); | 5439 | SiS_SetReg(SISSR, 0x18, 0x01); |
| 5438 | if((ivideo->chip == XGI_20) || | 5440 | if((ivideo->chip == XGI_20) || |
| 5439 | (ivideo->revision_id == 2)) { | 5441 | (ivideo->revision_id == 2)) { |
| 5440 | outSISIDXREG(SISSR, 0x19, 0x40); | 5442 | SiS_SetReg(SISSR, 0x19, 0x40); |
| 5441 | } else { | 5443 | } else { |
| 5442 | outSISIDXREG(SISSR, 0x19, 0x20); | 5444 | SiS_SetReg(SISSR, 0x19, 0x20); |
| 5443 | } | 5445 | } |
| 5444 | outSISIDXREG(SISSR, 0x16, 0x00); | 5446 | SiS_SetReg(SISSR, 0x16, 0x00); |
| 5445 | outSISIDXREG(SISSR, 0x16, 0x80); | 5447 | SiS_SetReg(SISSR, 0x16, 0x80); |
| 5446 | if((ivideo->chip == XGI_20) || (bios[0x1cb] != 0x0c)) { | 5448 | if((ivideo->chip == XGI_20) || (bios[0x1cb] != 0x0c)) { |
| 5447 | sisfb_post_xgi_delay(ivideo, 0x43); | 5449 | sisfb_post_xgi_delay(ivideo, 0x43); |
| 5448 | sisfb_post_xgi_delay(ivideo, 0x43); | 5450 | sisfb_post_xgi_delay(ivideo, 0x43); |
| 5449 | sisfb_post_xgi_delay(ivideo, 0x43); | 5451 | sisfb_post_xgi_delay(ivideo, 0x43); |
| 5450 | outSISIDXREG(SISSR, 0x18, 0x00); | 5452 | SiS_SetReg(SISSR, 0x18, 0x00); |
| 5451 | if((ivideo->chip == XGI_20) || | 5453 | if((ivideo->chip == XGI_20) || |
| 5452 | (ivideo->revision_id == 2)) { | 5454 | (ivideo->revision_id == 2)) { |
| 5453 | outSISIDXREG(SISSR, 0x19, 0x40); | 5455 | SiS_SetReg(SISSR, 0x19, 0x40); |
| 5454 | } else { | 5456 | } else { |
| 5455 | outSISIDXREG(SISSR, 0x19, 0x20); | 5457 | SiS_SetReg(SISSR, 0x19, 0x20); |
| 5456 | } | 5458 | } |
| 5457 | } else if((ivideo->chip == XGI_40) && (bios[0x1cb] == 0x0c)) { | 5459 | } else if((ivideo->chip == XGI_40) && (bios[0x1cb] == 0x0c)) { |
| 5458 | /* outSISIDXREG(SISSR, 0x16, 0x0c); */ /* ? */ | 5460 | /* SiS_SetReg(SISSR, 0x16, 0x0c); */ /* ? */ |
| 5459 | } | 5461 | } |
| 5460 | outSISIDXREG(SISSR, 0x16, 0x00); | 5462 | SiS_SetReg(SISSR, 0x16, 0x00); |
| 5461 | outSISIDXREG(SISSR, 0x16, 0x80); | 5463 | SiS_SetReg(SISSR, 0x16, 0x80); |
| 5462 | sisfb_post_xgi_delay(ivideo, 4); | 5464 | sisfb_post_xgi_delay(ivideo, 4); |
| 5463 | v1 = 0x31; v2 = 0x03; v3 = 0x83; v4 = 0x03; v5 = 0x83; | 5465 | v1 = 0x31; v2 = 0x03; v3 = 0x83; v4 = 0x03; v5 = 0x83; |
| 5464 | if(ivideo->haveXGIROM) { | 5466 | if(ivideo->haveXGIROM) { |
| @@ -5469,74 +5471,74 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5469 | v4 = bios[index + 2]; | 5471 | v4 = bios[index + 2]; |
| 5470 | v5 = bios[index + 3]; | 5472 | v5 = bios[index + 3]; |
| 5471 | } | 5473 | } |
| 5472 | outSISIDXREG(SISSR, 0x18, v1); | 5474 | SiS_SetReg(SISSR, 0x18, v1); |
| 5473 | outSISIDXREG(SISSR, 0x19, ((ivideo->chip == XGI_20) ? 0x02 : 0x01)); | 5475 | SiS_SetReg(SISSR, 0x19, ((ivideo->chip == XGI_20) ? 0x02 : 0x01)); |
| 5474 | outSISIDXREG(SISSR, 0x16, v2); | 5476 | SiS_SetReg(SISSR, 0x16, v2); |
| 5475 | outSISIDXREG(SISSR, 0x16, v3); | 5477 | SiS_SetReg(SISSR, 0x16, v3); |
| 5476 | sisfb_post_xgi_delay(ivideo, 0x43); | 5478 | sisfb_post_xgi_delay(ivideo, 0x43); |
| 5477 | outSISIDXREG(SISSR, 0x1b, 0x03); | 5479 | SiS_SetReg(SISSR, 0x1b, 0x03); |
| 5478 | sisfb_post_xgi_delay(ivideo, 0x22); | 5480 | sisfb_post_xgi_delay(ivideo, 0x22); |
| 5479 | outSISIDXREG(SISSR, 0x18, v1); | 5481 | SiS_SetReg(SISSR, 0x18, v1); |
| 5480 | outSISIDXREG(SISSR, 0x19, 0x00); | 5482 | SiS_SetReg(SISSR, 0x19, 0x00); |
| 5481 | outSISIDXREG(SISSR, 0x16, v4); | 5483 | SiS_SetReg(SISSR, 0x16, v4); |
| 5482 | outSISIDXREG(SISSR, 0x16, v5); | 5484 | SiS_SetReg(SISSR, 0x16, v5); |
| 5483 | outSISIDXREG(SISSR, 0x1b, 0x00); | 5485 | SiS_SetReg(SISSR, 0x1b, 0x00); |
| 5484 | break; | 5486 | break; |
| 5485 | case 1: | 5487 | case 1: |
| 5486 | outSISIDXREG(SISCR, 0x82, 0x77); | 5488 | SiS_SetReg(SISCR, 0x82, 0x77); |
| 5487 | outSISIDXREG(SISCR, 0x86, 0x00); | 5489 | SiS_SetReg(SISCR, 0x86, 0x00); |
| 5488 | inSISIDXREG(SISCR, 0x86, reg); | 5490 | reg = SiS_GetReg(SISCR, 0x86); |
| 5489 | outSISIDXREG(SISCR, 0x86, 0x88); | 5491 | SiS_SetReg(SISCR, 0x86, 0x88); |
| 5490 | inSISIDXREG(SISCR, 0x86, reg); | 5492 | reg = SiS_GetReg(SISCR, 0x86); |
| 5491 | v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb]; | 5493 | v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb]; |
| 5492 | if(ivideo->haveXGIROM) { | 5494 | if(ivideo->haveXGIROM) { |
| 5493 | v1 = bios[regb + 0x168]; | 5495 | v1 = bios[regb + 0x168]; |
| 5494 | v2 = bios[regb + 0x160]; | 5496 | v2 = bios[regb + 0x160]; |
| 5495 | v3 = bios[regb + 0x158]; | 5497 | v3 = bios[regb + 0x158]; |
| 5496 | } | 5498 | } |
| 5497 | outSISIDXREG(SISCR, 0x86, v1); | 5499 | SiS_SetReg(SISCR, 0x86, v1); |
| 5498 | outSISIDXREG(SISCR, 0x82, 0x77); | 5500 | SiS_SetReg(SISCR, 0x82, 0x77); |
| 5499 | outSISIDXREG(SISCR, 0x85, 0x00); | 5501 | SiS_SetReg(SISCR, 0x85, 0x00); |
| 5500 | inSISIDXREG(SISCR, 0x85, reg); | 5502 | reg = SiS_GetReg(SISCR, 0x85); |
| 5501 | outSISIDXREG(SISCR, 0x85, 0x88); | 5503 | SiS_SetReg(SISCR, 0x85, 0x88); |
| 5502 | inSISIDXREG(SISCR, 0x85, reg); | 5504 | reg = SiS_GetReg(SISCR, 0x85); |
| 5503 | outSISIDXREG(SISCR, 0x85, v2); | 5505 | SiS_SetReg(SISCR, 0x85, v2); |
| 5504 | outSISIDXREG(SISCR, 0x82, v3); | 5506 | SiS_SetReg(SISCR, 0x82, v3); |
| 5505 | outSISIDXREG(SISCR, 0x98, 0x01); | 5507 | SiS_SetReg(SISCR, 0x98, 0x01); |
| 5506 | outSISIDXREG(SISCR, 0x9a, 0x02); | 5508 | SiS_SetReg(SISCR, 0x9a, 0x02); |
| 5507 | 5509 | ||
| 5508 | outSISIDXREG(SISSR, 0x28, 0x64); | 5510 | SiS_SetReg(SISSR, 0x28, 0x64); |
| 5509 | outSISIDXREG(SISSR, 0x29, 0x63); | 5511 | SiS_SetReg(SISSR, 0x29, 0x63); |
| 5510 | sisfb_post_xgi_delay(ivideo, 15); | 5512 | sisfb_post_xgi_delay(ivideo, 15); |
| 5511 | outSISIDXREG(SISSR, 0x18, 0x00); | 5513 | SiS_SetReg(SISSR, 0x18, 0x00); |
| 5512 | outSISIDXREG(SISSR, 0x19, 0x20); | 5514 | SiS_SetReg(SISSR, 0x19, 0x20); |
| 5513 | outSISIDXREG(SISSR, 0x16, 0x00); | 5515 | SiS_SetReg(SISSR, 0x16, 0x00); |
| 5514 | outSISIDXREG(SISSR, 0x16, 0x80); | 5516 | SiS_SetReg(SISSR, 0x16, 0x80); |
| 5515 | outSISIDXREG(SISSR, 0x18, 0xc5); | 5517 | SiS_SetReg(SISSR, 0x18, 0xc5); |
| 5516 | outSISIDXREG(SISSR, 0x19, 0x23); | 5518 | SiS_SetReg(SISSR, 0x19, 0x23); |
| 5517 | outSISIDXREG(SISSR, 0x16, 0x00); | 5519 | SiS_SetReg(SISSR, 0x16, 0x00); |
| 5518 | outSISIDXREG(SISSR, 0x16, 0x80); | 5520 | SiS_SetReg(SISSR, 0x16, 0x80); |
| 5519 | sisfb_post_xgi_delay(ivideo, 1); | 5521 | sisfb_post_xgi_delay(ivideo, 1); |
| 5520 | outSISIDXREG(SISCR, 0x97,0x11); | 5522 | SiS_SetReg(SISCR, 0x97, 0x11); |
| 5521 | sisfb_post_xgi_setclocks(ivideo, regb); | 5523 | sisfb_post_xgi_setclocks(ivideo, regb); |
| 5522 | sisfb_post_xgi_delay(ivideo, 0x46); | 5524 | sisfb_post_xgi_delay(ivideo, 0x46); |
| 5523 | outSISIDXREG(SISSR, 0x18, 0xc5); | 5525 | SiS_SetReg(SISSR, 0x18, 0xc5); |
| 5524 | outSISIDXREG(SISSR, 0x19, 0x23); | 5526 | SiS_SetReg(SISSR, 0x19, 0x23); |
| 5525 | outSISIDXREG(SISSR, 0x16, 0x00); | 5527 | SiS_SetReg(SISSR, 0x16, 0x00); |
| 5526 | outSISIDXREG(SISSR, 0x16, 0x80); | 5528 | SiS_SetReg(SISSR, 0x16, 0x80); |
| 5527 | sisfb_post_xgi_delay(ivideo, 1); | 5529 | sisfb_post_xgi_delay(ivideo, 1); |
| 5528 | outSISIDXREG(SISSR, 0x1b, 0x04); | 5530 | SiS_SetReg(SISSR, 0x1b, 0x04); |
| 5529 | sisfb_post_xgi_delay(ivideo, 1); | 5531 | sisfb_post_xgi_delay(ivideo, 1); |
| 5530 | outSISIDXREG(SISSR, 0x1b, 0x00); | 5532 | SiS_SetReg(SISSR, 0x1b, 0x00); |
| 5531 | sisfb_post_xgi_delay(ivideo, 1); | 5533 | sisfb_post_xgi_delay(ivideo, 1); |
| 5532 | v1 = 0x31; | 5534 | v1 = 0x31; |
| 5533 | if(ivideo->haveXGIROM) { | 5535 | if(ivideo->haveXGIROM) { |
| 5534 | v1 = bios[0xf0]; | 5536 | v1 = bios[0xf0]; |
| 5535 | } | 5537 | } |
| 5536 | outSISIDXREG(SISSR, 0x18, v1); | 5538 | SiS_SetReg(SISSR, 0x18, v1); |
| 5537 | outSISIDXREG(SISSR, 0x19, 0x06); | 5539 | SiS_SetReg(SISSR, 0x19, 0x06); |
| 5538 | outSISIDXREG(SISSR, 0x16, 0x04); | 5540 | SiS_SetReg(SISSR, 0x16, 0x04); |
| 5539 | outSISIDXREG(SISSR, 0x16, 0x84); | 5541 | SiS_SetReg(SISSR, 0x16, 0x84); |
| 5540 | sisfb_post_xgi_delay(ivideo, 1); | 5542 | sisfb_post_xgi_delay(ivideo, 1); |
| 5541 | break; | 5543 | break; |
| 5542 | default: | 5544 | default: |
| @@ -5544,85 +5546,85 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5544 | if((ivideo->chip == XGI_40) && | 5546 | if((ivideo->chip == XGI_40) && |
| 5545 | ((ivideo->revision_id == 1) || | 5547 | ((ivideo->revision_id == 1) || |
| 5546 | (ivideo->revision_id == 2))) { | 5548 | (ivideo->revision_id == 2))) { |
| 5547 | outSISIDXREG(SISCR, 0x82, bios[regb + 0x158]); | 5549 | SiS_SetReg(SISCR, 0x82, bios[regb + 0x158]); |
| 5548 | outSISIDXREG(SISCR, 0x85, bios[regb + 0x160]); | 5550 | SiS_SetReg(SISCR, 0x85, bios[regb + 0x160]); |
| 5549 | outSISIDXREG(SISCR, 0x86, bios[regb + 0x168]); | 5551 | SiS_SetReg(SISCR, 0x86, bios[regb + 0x168]); |
| 5550 | } else { | 5552 | } else { |
| 5551 | outSISIDXREG(SISCR, 0x82, 0x88); | 5553 | SiS_SetReg(SISCR, 0x82, 0x88); |
| 5552 | outSISIDXREG(SISCR, 0x86, 0x00); | 5554 | SiS_SetReg(SISCR, 0x86, 0x00); |
| 5553 | inSISIDXREG(SISCR, 0x86, reg); | 5555 | reg = SiS_GetReg(SISCR, 0x86); |
| 5554 | outSISIDXREG(SISCR, 0x86, 0x88); | 5556 | SiS_SetReg(SISCR, 0x86, 0x88); |
| 5555 | outSISIDXREG(SISCR, 0x82, 0x77); | 5557 | SiS_SetReg(SISCR, 0x82, 0x77); |
| 5556 | outSISIDXREG(SISCR, 0x85, 0x00); | 5558 | SiS_SetReg(SISCR, 0x85, 0x00); |
| 5557 | inSISIDXREG(SISCR, 0x85, reg); | 5559 | reg = SiS_GetReg(SISCR, 0x85); |
| 5558 | outSISIDXREG(SISCR, 0x85, 0x88); | 5560 | SiS_SetReg(SISCR, 0x85, 0x88); |
| 5559 | inSISIDXREG(SISCR, 0x85, reg); | 5561 | reg = SiS_GetReg(SISCR, 0x85); |
| 5560 | v1 = cs160[regb]; v2 = cs158[regb]; | 5562 | v1 = cs160[regb]; v2 = cs158[regb]; |
| 5561 | if(ivideo->haveXGIROM) { | 5563 | if(ivideo->haveXGIROM) { |
| 5562 | v1 = bios[regb + 0x160]; | 5564 | v1 = bios[regb + 0x160]; |
| 5563 | v2 = bios[regb + 0x158]; | 5565 | v2 = bios[regb + 0x158]; |
| 5564 | } | 5566 | } |
| 5565 | outSISIDXREG(SISCR, 0x85, v1); | 5567 | SiS_SetReg(SISCR, 0x85, v1); |
| 5566 | outSISIDXREG(SISCR, 0x82, v2); | 5568 | SiS_SetReg(SISCR, 0x82, v2); |
| 5567 | } | 5569 | } |
| 5568 | if(ivideo->chip == XGI_40) { | 5570 | if(ivideo->chip == XGI_40) { |
| 5569 | outSISIDXREG(SISCR, 0x97, 0x11); | 5571 | SiS_SetReg(SISCR, 0x97, 0x11); |
| 5570 | } | 5572 | } |
| 5571 | if((ivideo->chip == XGI_40) && (ivideo->revision_id == 2)) { | 5573 | if((ivideo->chip == XGI_40) && (ivideo->revision_id == 2)) { |
| 5572 | outSISIDXREG(SISCR, 0x98, 0x01); | 5574 | SiS_SetReg(SISCR, 0x98, 0x01); |
| 5573 | } else { | 5575 | } else { |
| 5574 | outSISIDXREG(SISCR, 0x98, 0x03); | 5576 | SiS_SetReg(SISCR, 0x98, 0x03); |
| 5575 | } | 5577 | } |
| 5576 | outSISIDXREG(SISCR, 0x9a, 0x02); | 5578 | SiS_SetReg(SISCR, 0x9a, 0x02); |
| 5577 | 5579 | ||
| 5578 | if(ivideo->chip == XGI_40) { | 5580 | if(ivideo->chip == XGI_40) { |
| 5579 | outSISIDXREG(SISSR, 0x18, 0x01); | 5581 | SiS_SetReg(SISSR, 0x18, 0x01); |
| 5580 | } else { | 5582 | } else { |
| 5581 | outSISIDXREG(SISSR, 0x18, 0x00); | 5583 | SiS_SetReg(SISSR, 0x18, 0x00); |
| 5582 | } | 5584 | } |
| 5583 | outSISIDXREG(SISSR, 0x19, 0x40); | 5585 | SiS_SetReg(SISSR, 0x19, 0x40); |
| 5584 | outSISIDXREG(SISSR, 0x16, 0x00); | 5586 | SiS_SetReg(SISSR, 0x16, 0x00); |
| 5585 | outSISIDXREG(SISSR, 0x16, 0x80); | 5587 | SiS_SetReg(SISSR, 0x16, 0x80); |
| 5586 | if((ivideo->chip == XGI_40) && (bios[0x1cb] != 0x0c)) { | 5588 | if((ivideo->chip == XGI_40) && (bios[0x1cb] != 0x0c)) { |
| 5587 | sisfb_post_xgi_delay(ivideo, 0x43); | 5589 | sisfb_post_xgi_delay(ivideo, 0x43); |
| 5588 | sisfb_post_xgi_delay(ivideo, 0x43); | 5590 | sisfb_post_xgi_delay(ivideo, 0x43); |
| 5589 | sisfb_post_xgi_delay(ivideo, 0x43); | 5591 | sisfb_post_xgi_delay(ivideo, 0x43); |
| 5590 | outSISIDXREG(SISSR, 0x18, 0x00); | 5592 | SiS_SetReg(SISSR, 0x18, 0x00); |
| 5591 | outSISIDXREG(SISSR, 0x19, 0x40); | 5593 | SiS_SetReg(SISSR, 0x19, 0x40); |
| 5592 | outSISIDXREG(SISSR, 0x16, 0x00); | 5594 | SiS_SetReg(SISSR, 0x16, 0x00); |
| 5593 | outSISIDXREG(SISSR, 0x16, 0x80); | 5595 | SiS_SetReg(SISSR, 0x16, 0x80); |
| 5594 | } | 5596 | } |
| 5595 | sisfb_post_xgi_delay(ivideo, 4); | 5597 | sisfb_post_xgi_delay(ivideo, 4); |
| 5596 | v1 = 0x31; | 5598 | v1 = 0x31; |
| 5597 | if(ivideo->haveXGIROM) { | 5599 | if(ivideo->haveXGIROM) { |
| 5598 | v1 = bios[0xf0]; | 5600 | v1 = bios[0xf0]; |
| 5599 | } | 5601 | } |
| 5600 | outSISIDXREG(SISSR, 0x18, v1); | 5602 | SiS_SetReg(SISSR, 0x18, v1); |
| 5601 | outSISIDXREG(SISSR, 0x19, 0x01); | 5603 | SiS_SetReg(SISSR, 0x19, 0x01); |
| 5602 | if(ivideo->chip == XGI_40) { | 5604 | if(ivideo->chip == XGI_40) { |
| 5603 | outSISIDXREG(SISSR, 0x16, bios[0x53e]); | 5605 | SiS_SetReg(SISSR, 0x16, bios[0x53e]); |
| 5604 | outSISIDXREG(SISSR, 0x16, bios[0x53f]); | 5606 | SiS_SetReg(SISSR, 0x16, bios[0x53f]); |
| 5605 | } else { | 5607 | } else { |
| 5606 | outSISIDXREG(SISSR, 0x16, 0x05); | 5608 | SiS_SetReg(SISSR, 0x16, 0x05); |
| 5607 | outSISIDXREG(SISSR, 0x16, 0x85); | 5609 | SiS_SetReg(SISSR, 0x16, 0x85); |
| 5608 | } | 5610 | } |
| 5609 | sisfb_post_xgi_delay(ivideo, 0x43); | 5611 | sisfb_post_xgi_delay(ivideo, 0x43); |
| 5610 | if(ivideo->chip == XGI_40) { | 5612 | if(ivideo->chip == XGI_40) { |
| 5611 | outSISIDXREG(SISSR, 0x1b, 0x01); | 5613 | SiS_SetReg(SISSR, 0x1b, 0x01); |
| 5612 | } else { | 5614 | } else { |
| 5613 | outSISIDXREG(SISSR, 0x1b, 0x03); | 5615 | SiS_SetReg(SISSR, 0x1b, 0x03); |
| 5614 | } | 5616 | } |
| 5615 | sisfb_post_xgi_delay(ivideo, 0x22); | 5617 | sisfb_post_xgi_delay(ivideo, 0x22); |
| 5616 | outSISIDXREG(SISSR, 0x18, v1); | 5618 | SiS_SetReg(SISSR, 0x18, v1); |
| 5617 | outSISIDXREG(SISSR, 0x19, 0x00); | 5619 | SiS_SetReg(SISSR, 0x19, 0x00); |
| 5618 | if(ivideo->chip == XGI_40) { | 5620 | if(ivideo->chip == XGI_40) { |
| 5619 | outSISIDXREG(SISSR, 0x16, bios[0x540]); | 5621 | SiS_SetReg(SISSR, 0x16, bios[0x540]); |
| 5620 | outSISIDXREG(SISSR, 0x16, bios[0x541]); | 5622 | SiS_SetReg(SISSR, 0x16, bios[0x541]); |
| 5621 | } else { | 5623 | } else { |
| 5622 | outSISIDXREG(SISSR, 0x16, 0x05); | 5624 | SiS_SetReg(SISSR, 0x16, 0x05); |
| 5623 | outSISIDXREG(SISSR, 0x16, 0x85); | 5625 | SiS_SetReg(SISSR, 0x16, 0x85); |
| 5624 | } | 5626 | } |
| 5625 | outSISIDXREG(SISSR, 0x1b, 0x00); | 5627 | SiS_SetReg(SISSR, 0x1b, 0x00); |
| 5626 | } | 5628 | } |
| 5627 | 5629 | ||
| 5628 | regb = 0; /* ! */ | 5630 | regb = 0; /* ! */ |
| @@ -5630,7 +5632,7 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5630 | if(ivideo->haveXGIROM) { | 5632 | if(ivideo->haveXGIROM) { |
| 5631 | v1 = bios[0x110 + regb]; | 5633 | v1 = bios[0x110 + regb]; |
| 5632 | } | 5634 | } |
| 5633 | outSISIDXREG(SISSR, 0x1b, v1); | 5635 | SiS_SetReg(SISSR, 0x1b, v1); |
| 5634 | 5636 | ||
| 5635 | /* RAM size */ | 5637 | /* RAM size */ |
| 5636 | v1 = 0x00; v2 = 0x00; | 5638 | v1 = 0x00; v2 = 0x00; |
| @@ -5642,8 +5644,8 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5642 | regd = 1 << regb; | 5644 | regd = 1 << regb; |
| 5643 | if((v1 & 0x40) && (v2 & regd) && ivideo->haveXGIROM) { | 5645 | if((v1 & 0x40) && (v2 & regd) && ivideo->haveXGIROM) { |
| 5644 | 5646 | ||
| 5645 | outSISIDXREG(SISSR, 0x13, bios[regb + 0xe0]); | 5647 | SiS_SetReg(SISSR, 0x13, bios[regb + 0xe0]); |
| 5646 | outSISIDXREG(SISSR, 0x14, bios[regb + 0xe0 + 8]); | 5648 | SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]); |
| 5647 | 5649 | ||
| 5648 | } else { | 5650 | } else { |
| 5649 | 5651 | ||
| @@ -5655,24 +5657,24 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5655 | ivideo->SiS_Pr.VideoMemorySize = 8 << 20; | 5657 | ivideo->SiS_Pr.VideoMemorySize = 8 << 20; |
| 5656 | SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80); | 5658 | SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80); |
| 5657 | 5659 | ||
| 5658 | outSISIDXREG(SISSR, 0x05, 0x86); | 5660 | SiS_SetReg(SISSR, 0x05, 0x86); |
| 5659 | 5661 | ||
| 5660 | /* Disable read-cache */ | 5662 | /* Disable read-cache */ |
| 5661 | andSISIDXREG(SISSR, 0x21, 0xdf); | 5663 | SiS_SetRegAND(SISSR, 0x21, 0xdf); |
| 5662 | sisfb_post_xgi_ramsize(ivideo); | 5664 | sisfb_post_xgi_ramsize(ivideo); |
| 5663 | /* Enable read-cache */ | 5665 | /* Enable read-cache */ |
| 5664 | orSISIDXREG(SISSR, 0x21, 0x20); | 5666 | SiS_SetRegOR(SISSR, 0x21, 0x20); |
| 5665 | 5667 | ||
| 5666 | } | 5668 | } |
| 5667 | 5669 | ||
| 5668 | #if 0 | 5670 | #if 0 |
| 5669 | printk(KERN_DEBUG "-----------------\n"); | 5671 | printk(KERN_DEBUG "-----------------\n"); |
| 5670 | for(i = 0; i < 0xff; i++) { | 5672 | for(i = 0; i < 0xff; i++) { |
| 5671 | inSISIDXREG(SISCR, i, reg); | 5673 | reg = SiS_GetReg(SISCR, i); |
| 5672 | printk(KERN_DEBUG "CR%02x(%x) = 0x%02x\n", i, SISCR, reg); | 5674 | printk(KERN_DEBUG "CR%02x(%x) = 0x%02x\n", i, SISCR, reg); |
| 5673 | } | 5675 | } |
| 5674 | for(i = 0; i < 0x40; i++) { | 5676 | for(i = 0; i < 0x40; i++) { |
| 5675 | inSISIDXREG(SISSR, i, reg); | 5677 | reg = SiS_GetReg(SISSR, i); |
| 5676 | printk(KERN_DEBUG "SR%02x(%x) = 0x%02x\n", i, SISSR, reg); | 5678 | printk(KERN_DEBUG "SR%02x(%x) = 0x%02x\n", i, SISSR, reg); |
| 5677 | } | 5679 | } |
| 5678 | printk(KERN_DEBUG "-----------------\n"); | 5680 | printk(KERN_DEBUG "-----------------\n"); |
| @@ -5680,13 +5682,13 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5680 | 5682 | ||
| 5681 | /* Sense CRT1 */ | 5683 | /* Sense CRT1 */ |
| 5682 | if(ivideo->chip == XGI_20) { | 5684 | if(ivideo->chip == XGI_20) { |
| 5683 | orSISIDXREG(SISCR, 0x32, 0x20); | 5685 | SiS_SetRegOR(SISCR, 0x32, 0x20); |
| 5684 | } else { | 5686 | } else { |
| 5685 | inSISIDXREG(SISPART4, 0x00, reg); | 5687 | reg = SiS_GetReg(SISPART4, 0x00); |
| 5686 | if((reg == 1) || (reg == 2)) { | 5688 | if((reg == 1) || (reg == 2)) { |
| 5687 | sisfb_sense_crt1(ivideo); | 5689 | sisfb_sense_crt1(ivideo); |
| 5688 | } else { | 5690 | } else { |
| 5689 | orSISIDXREG(SISCR, 0x32, 0x20); | 5691 | SiS_SetRegOR(SISCR, 0x32, 0x20); |
| 5690 | } | 5692 | } |
| 5691 | } | 5693 | } |
| 5692 | 5694 | ||
| @@ -5697,20 +5699,20 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
| 5697 | ivideo->curFSTN = ivideo->curDSTN = 0; | 5699 | ivideo->curFSTN = ivideo->curDSTN = 0; |
| 5698 | SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80); | 5700 | SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80); |
| 5699 | 5701 | ||
| 5700 | outSISIDXREG(SISSR, 0x05, 0x86); | 5702 | SiS_SetReg(SISSR, 0x05, 0x86); |
| 5701 | 5703 | ||
| 5702 | /* Display off */ | 5704 | /* Display off */ |
| 5703 | orSISIDXREG(SISSR, 0x01, 0x20); | 5705 | SiS_SetRegOR(SISSR, 0x01, 0x20); |
| 5704 | 5706 | ||
| 5705 | /* Save mode number in CR34 */ | 5707 | /* Save mode number in CR34 */ |
| 5706 | outSISIDXREG(SISCR, 0x34, 0x2e); | 5708 | SiS_SetReg(SISCR, 0x34, 0x2e); |
| 5707 | 5709 | ||
| 5708 | /* Let everyone know what the current mode is */ | 5710 | /* Let everyone know what the current mode is */ |
| 5709 | ivideo->modeprechange = 0x2e; | 5711 | ivideo->modeprechange = 0x2e; |
| 5710 | 5712 | ||
| 5711 | if(ivideo->chip == XGI_40) { | 5713 | if(ivideo->chip == XGI_40) { |
| 5712 | inSISIDXREG(SISCR, 0xca, reg); | 5714 | reg = SiS_GetReg(SISCR, 0xca); |
| 5713 | inSISIDXREG(SISCR, 0xcc, v1); | 5715 | v1 = SiS_GetReg(SISCR, 0xcc); |
| 5714 | if((reg & 0x10) && (!(v1 & 0x04))) { | 5716 | if((reg & 0x10) && (!(v1 & 0x04))) { |
| 5715 | printk(KERN_ERR | 5717 | printk(KERN_ERR |
| 5716 | "sisfb: Please connect power to the card.\n"); | 5718 | "sisfb: Please connect power to the card.\n"); |
| @@ -5953,7 +5955,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 5953 | } | 5955 | } |
| 5954 | #endif | 5956 | #endif |
| 5955 | 5957 | ||
| 5956 | outSISIDXREG(SISSR, 0x05, 0x86); | 5958 | SiS_SetReg(SISSR, 0x05, 0x86); |
| 5957 | 5959 | ||
| 5958 | if( (!ivideo->sisvga_enabled) | 5960 | if( (!ivideo->sisvga_enabled) |
| 5959 | #if !defined(__i386__) && !defined(__x86_64__) | 5961 | #if !defined(__i386__) && !defined(__x86_64__) |
| @@ -5961,13 +5963,13 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 5961 | #endif | 5963 | #endif |
| 5962 | ) { | 5964 | ) { |
| 5963 | for(i = 0x30; i <= 0x3f; i++) { | 5965 | for(i = 0x30; i <= 0x3f; i++) { |
| 5964 | outSISIDXREG(SISCR, i, 0x00); | 5966 | SiS_SetReg(SISCR, i, 0x00); |
| 5965 | } | 5967 | } |
| 5966 | } | 5968 | } |
| 5967 | 5969 | ||
| 5968 | /* Find out about current video mode */ | 5970 | /* Find out about current video mode */ |
| 5969 | ivideo->modeprechange = 0x03; | 5971 | ivideo->modeprechange = 0x03; |
| 5970 | inSISIDXREG(SISCR, 0x34, reg); | 5972 | reg = SiS_GetReg(SISCR, 0x34); |
| 5971 | if(reg & 0x7f) { | 5973 | if(reg & 0x7f) { |
| 5972 | ivideo->modeprechange = reg & 0x7f; | 5974 | ivideo->modeprechange = reg & 0x7f; |
| 5973 | } else if(ivideo->sisvga_enabled) { | 5975 | } else if(ivideo->sisvga_enabled) { |
| @@ -6064,9 +6066,9 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 6064 | if((ivideo->sisfb_mode_idx < 0) || | 6066 | if((ivideo->sisfb_mode_idx < 0) || |
| 6065 | ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) { | 6067 | ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) { |
| 6066 | /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */ | 6068 | /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */ |
| 6067 | orSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE)); | 6069 | SiS_SetRegOR(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE)); |
| 6068 | /* Enable 2D accelerator engine */ | 6070 | /* Enable 2D accelerator engine */ |
| 6069 | orSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D); | 6071 | SiS_SetRegOR(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D); |
| 6070 | } | 6072 | } |
| 6071 | 6073 | ||
| 6072 | if(sisfb_pdc != 0xff) { | 6074 | if(sisfb_pdc != 0xff) { |
diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/video/udlfb.c index b7ac16005265..020589a6bf02 100644 --- a/drivers/staging/udlfb/udlfb.c +++ b/drivers/video/udlfb.c | |||
| @@ -16,6 +16,8 @@ | |||
| 16 | * from Florian Echtler, Henrik Bjerregaard Pedersen, and others. | 16 | * from Florian Echtler, Henrik Bjerregaard Pedersen, and others. |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 20 | |||
| 19 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 20 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
| 21 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| @@ -26,8 +28,8 @@ | |||
| 26 | #include <linux/vmalloc.h> | 28 | #include <linux/vmalloc.h> |
| 27 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 28 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
| 29 | 31 | #include <video/udlfb.h> | |
| 30 | #include "udlfb.h" | 32 | #include "edid.h" |
| 31 | 33 | ||
| 32 | static struct fb_fix_screeninfo dlfb_fix = { | 34 | static struct fb_fix_screeninfo dlfb_fix = { |
| 33 | .id = "udlfb", | 35 | .id = "udlfb", |
| @@ -40,9 +42,7 @@ static struct fb_fix_screeninfo dlfb_fix = { | |||
| 40 | }; | 42 | }; |
| 41 | 43 | ||
| 42 | static const u32 udlfb_info_flags = FBINFO_DEFAULT | FBINFO_READS_FAST | | 44 | static const u32 udlfb_info_flags = FBINFO_DEFAULT | FBINFO_READS_FAST | |
| 43 | #ifdef FBINFO_VIRTFB | ||
| 44 | FBINFO_VIRTFB | | 45 | FBINFO_VIRTFB | |
| 45 | #endif | ||
| 46 | FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_FILLRECT | | 46 | FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_FILLRECT | |
| 47 | FBINFO_HWACCEL_COPYAREA | FBINFO_MISC_ALWAYS_SETPAR; | 47 | FBINFO_HWACCEL_COPYAREA | FBINFO_MISC_ALWAYS_SETPAR; |
| 48 | 48 | ||
| @@ -293,7 +293,7 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma) | |||
| 293 | 293 | ||
| 294 | pos = (unsigned long)info->fix.smem_start + offset; | 294 | pos = (unsigned long)info->fix.smem_start + offset; |
| 295 | 295 | ||
| 296 | dl_notice("mmap() framebuffer addr:%lu size:%lu\n", | 296 | pr_notice("mmap() framebuffer addr:%lu size:%lu\n", |
| 297 | pos, size); | 297 | pos, size); |
| 298 | 298 | ||
| 299 | while (size > 0) { | 299 | while (size > 0) { |
| @@ -595,18 +595,6 @@ error: | |||
| 595 | return 0; | 595 | return 0; |
| 596 | } | 596 | } |
| 597 | 597 | ||
| 598 | static ssize_t dlfb_ops_read(struct fb_info *info, char __user *buf, | ||
| 599 | size_t count, loff_t *ppos) | ||
| 600 | { | ||
| 601 | ssize_t result = -ENOSYS; | ||
| 602 | |||
| 603 | #if defined CONFIG_FB_SYS_FOPS || defined CONFIG_FB_SYS_FOPS_MODULE | ||
| 604 | result = fb_sys_read(info, buf, count, ppos); | ||
| 605 | #endif | ||
| 606 | |||
| 607 | return result; | ||
| 608 | } | ||
| 609 | |||
| 610 | /* | 598 | /* |
| 611 | * Path triggered by usermode clients who write to filesystem | 599 | * Path triggered by usermode clients who write to filesystem |
| 612 | * e.g. cat filename > /dev/fb1 | 600 | * e.g. cat filename > /dev/fb1 |
| @@ -616,12 +604,10 @@ static ssize_t dlfb_ops_read(struct fb_info *info, char __user *buf, | |||
| 616 | static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf, | 604 | static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf, |
| 617 | size_t count, loff_t *ppos) | 605 | size_t count, loff_t *ppos) |
| 618 | { | 606 | { |
| 619 | ssize_t result = -ENOSYS; | 607 | ssize_t result; |
| 620 | struct dlfb_data *dev = info->par; | 608 | struct dlfb_data *dev = info->par; |
| 621 | u32 offset = (u32) *ppos; | 609 | u32 offset = (u32) *ppos; |
| 622 | 610 | ||
| 623 | #if defined CONFIG_FB_SYS_FOPS || defined CONFIG_FB_SYS_FOPS_MODULE | ||
| 624 | |||
| 625 | result = fb_sys_write(info, buf, count, ppos); | 611 | result = fb_sys_write(info, buf, count, ppos); |
| 626 | 612 | ||
| 627 | if (result > 0) { | 613 | if (result > 0) { |
| @@ -632,7 +618,6 @@ static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf, | |||
| 632 | dlfb_handle_damage(dev, 0, start, info->var.xres, | 618 | dlfb_handle_damage(dev, 0, start, info->var.xres, |
| 633 | lines, info->screen_base); | 619 | lines, info->screen_base); |
| 634 | } | 620 | } |
| 635 | #endif | ||
| 636 | 621 | ||
| 637 | return result; | 622 | return result; |
| 638 | } | 623 | } |
| @@ -644,14 +629,10 @@ static void dlfb_ops_copyarea(struct fb_info *info, | |||
| 644 | 629 | ||
| 645 | struct dlfb_data *dev = info->par; | 630 | struct dlfb_data *dev = info->par; |
| 646 | 631 | ||
| 647 | #if defined CONFIG_FB_SYS_COPYAREA || defined CONFIG_FB_SYS_COPYAREA_MODULE | ||
| 648 | |||
| 649 | sys_copyarea(info, area); | 632 | sys_copyarea(info, area); |
| 650 | 633 | ||
| 651 | dlfb_handle_damage(dev, area->dx, area->dy, | 634 | dlfb_handle_damage(dev, area->dx, area->dy, |
| 652 | area->width, area->height, info->screen_base); | 635 | area->width, area->height, info->screen_base); |
| 653 | #endif | ||
| 654 | |||
| 655 | } | 636 | } |
| 656 | 637 | ||
| 657 | static void dlfb_ops_imageblit(struct fb_info *info, | 638 | static void dlfb_ops_imageblit(struct fb_info *info, |
| @@ -659,15 +640,10 @@ static void dlfb_ops_imageblit(struct fb_info *info, | |||
| 659 | { | 640 | { |
| 660 | struct dlfb_data *dev = info->par; | 641 | struct dlfb_data *dev = info->par; |
| 661 | 642 | ||
| 662 | #if defined CONFIG_FB_SYS_IMAGEBLIT || defined CONFIG_FB_SYS_IMAGEBLIT_MODULE | ||
| 663 | |||
| 664 | sys_imageblit(info, image); | 643 | sys_imageblit(info, image); |
| 665 | 644 | ||
| 666 | dlfb_handle_damage(dev, image->dx, image->dy, | 645 | dlfb_handle_damage(dev, image->dx, image->dy, |
| 667 | image->width, image->height, info->screen_base); | 646 | image->width, image->height, info->screen_base); |
| 668 | |||
| 669 | #endif | ||
| 670 | |||
| 671 | } | 647 | } |
| 672 | 648 | ||
| 673 | static void dlfb_ops_fillrect(struct fb_info *info, | 649 | static void dlfb_ops_fillrect(struct fb_info *info, |
| @@ -675,17 +651,12 @@ static void dlfb_ops_fillrect(struct fb_info *info, | |||
| 675 | { | 651 | { |
| 676 | struct dlfb_data *dev = info->par; | 652 | struct dlfb_data *dev = info->par; |
| 677 | 653 | ||
| 678 | #if defined CONFIG_FB_SYS_FILLRECT || defined CONFIG_FB_SYS_FILLRECT_MODULE | ||
| 679 | |||
| 680 | sys_fillrect(info, rect); | 654 | sys_fillrect(info, rect); |
| 681 | 655 | ||
| 682 | dlfb_handle_damage(dev, rect->dx, rect->dy, rect->width, | 656 | dlfb_handle_damage(dev, rect->dx, rect->dy, rect->width, |
| 683 | rect->height, info->screen_base); | 657 | rect->height, info->screen_base); |
| 684 | #endif | ||
| 685 | |||
| 686 | } | 658 | } |
| 687 | 659 | ||
| 688 | #ifdef CONFIG_FB_DEFERRED_IO | ||
| 689 | /* | 660 | /* |
| 690 | * NOTE: fb_defio.c is holding info->fbdefio.mutex | 661 | * NOTE: fb_defio.c is holding info->fbdefio.mutex |
| 691 | * Touching ANY framebuffer memory that triggers a page fault | 662 | * Touching ANY framebuffer memory that triggers a page fault |
| @@ -747,8 +718,6 @@ error: | |||
| 747 | &dev->cpu_kcycles_used); | 718 | &dev->cpu_kcycles_used); |
| 748 | } | 719 | } |
| 749 | 720 | ||
| 750 | #endif | ||
| 751 | |||
| 752 | static int dlfb_get_edid(struct dlfb_data *dev, char *edid, int len) | 721 | static int dlfb_get_edid(struct dlfb_data *dev, char *edid, int len) |
| 753 | { | 722 | { |
| 754 | int i; | 723 | int i; |
| @@ -765,7 +734,7 @@ static int dlfb_get_edid(struct dlfb_data *dev, char *edid, int len) | |||
| 765 | (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2, | 734 | (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2, |
| 766 | HZ); | 735 | HZ); |
| 767 | if (ret < 1) { | 736 | if (ret < 1) { |
| 768 | dl_err("Read EDID byte %d failed err %x\n", i, ret); | 737 | pr_err("Read EDID byte %d failed err %x\n", i, ret); |
| 769 | i--; | 738 | i--; |
| 770 | break; | 739 | break; |
| 771 | } | 740 | } |
| @@ -881,7 +850,6 @@ static int dlfb_ops_open(struct fb_info *info, int user) | |||
| 881 | 850 | ||
| 882 | kref_get(&dev->kref); | 851 | kref_get(&dev->kref); |
| 883 | 852 | ||
| 884 | #ifdef CONFIG_FB_DEFERRED_IO | ||
| 885 | if (fb_defio && (info->fbdefio == NULL)) { | 853 | if (fb_defio && (info->fbdefio == NULL)) { |
| 886 | /* enable defio at last moment if not disabled by client */ | 854 | /* enable defio at last moment if not disabled by client */ |
| 887 | 855 | ||
| @@ -897,9 +865,8 @@ static int dlfb_ops_open(struct fb_info *info, int user) | |||
| 897 | info->fbdefio = fbdefio; | 865 | info->fbdefio = fbdefio; |
| 898 | fb_deferred_io_init(info); | 866 | fb_deferred_io_init(info); |
| 899 | } | 867 | } |
| 900 | #endif | ||
| 901 | 868 | ||
| 902 | dl_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n", | 869 | pr_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n", |
| 903 | info->node, user, info, dev->fb_count); | 870 | info->node, user, info, dev->fb_count); |
| 904 | 871 | ||
| 905 | return 0; | 872 | return 0; |
| @@ -923,7 +890,7 @@ static void dlfb_free(struct kref *kref) | |||
| 923 | 890 | ||
| 924 | kfree(dev->edid); | 891 | kfree(dev->edid); |
| 925 | 892 | ||
| 926 | dl_warn("freeing dlfb_data %p\n", dev); | 893 | pr_warn("freeing dlfb_data %p\n", dev); |
| 927 | 894 | ||
| 928 | kfree(dev); | 895 | kfree(dev); |
| 929 | } | 896 | } |
| @@ -959,7 +926,7 @@ static void dlfb_free_framebuffer_work(struct work_struct *work) | |||
| 959 | /* Assume info structure is freed after this point */ | 926 | /* Assume info structure is freed after this point */ |
| 960 | framebuffer_release(info); | 927 | framebuffer_release(info); |
| 961 | 928 | ||
| 962 | dl_warn("fb_info for /dev/fb%d has been freed\n", node); | 929 | pr_warn("fb_info for /dev/fb%d has been freed\n", node); |
| 963 | 930 | ||
| 964 | /* ref taken in probe() as part of registering framebfufer */ | 931 | /* ref taken in probe() as part of registering framebfufer */ |
| 965 | kref_put(&dev->kref, dlfb_free); | 932 | kref_put(&dev->kref, dlfb_free); |
| @@ -978,16 +945,14 @@ static int dlfb_ops_release(struct fb_info *info, int user) | |||
| 978 | if (dev->virtualized && (dev->fb_count == 0)) | 945 | if (dev->virtualized && (dev->fb_count == 0)) |
| 979 | schedule_delayed_work(&dev->free_framebuffer_work, HZ); | 946 | schedule_delayed_work(&dev->free_framebuffer_work, HZ); |
| 980 | 947 | ||
| 981 | #ifdef CONFIG_FB_DEFERRED_IO | ||
| 982 | if ((dev->fb_count == 0) && (info->fbdefio)) { | 948 | if ((dev->fb_count == 0) && (info->fbdefio)) { |
| 983 | fb_deferred_io_cleanup(info); | 949 | fb_deferred_io_cleanup(info); |
| 984 | kfree(info->fbdefio); | 950 | kfree(info->fbdefio); |
| 985 | info->fbdefio = NULL; | 951 | info->fbdefio = NULL; |
| 986 | info->fbops->fb_mmap = dlfb_ops_mmap; | 952 | info->fbops->fb_mmap = dlfb_ops_mmap; |
| 987 | } | 953 | } |
| 988 | #endif | ||
| 989 | 954 | ||
| 990 | dl_warn("released /dev/fb%d user=%d count=%d\n", | 955 | pr_warn("released /dev/fb%d user=%d count=%d\n", |
| 991 | info->node, user, dev->fb_count); | 956 | info->node, user, dev->fb_count); |
| 992 | 957 | ||
| 993 | kref_put(&dev->kref, dlfb_free); | 958 | kref_put(&dev->kref, dlfb_free); |
| @@ -1005,12 +970,12 @@ static int dlfb_is_valid_mode(struct fb_videomode *mode, | |||
| 1005 | struct dlfb_data *dev = info->par; | 970 | struct dlfb_data *dev = info->par; |
| 1006 | 971 | ||
| 1007 | if (mode->xres * mode->yres > dev->sku_pixel_limit) { | 972 | if (mode->xres * mode->yres > dev->sku_pixel_limit) { |
| 1008 | dl_warn("%dx%d beyond chip capabilities\n", | 973 | pr_warn("%dx%d beyond chip capabilities\n", |
| 1009 | mode->xres, mode->yres); | 974 | mode->xres, mode->yres); |
| 1010 | return 0; | 975 | return 0; |
| 1011 | } | 976 | } |
| 1012 | 977 | ||
| 1013 | dl_info("%dx%d valid mode\n", mode->xres, mode->yres); | 978 | pr_info("%dx%d valid mode\n", mode->xres, mode->yres); |
| 1014 | 979 | ||
| 1015 | return 1; | 980 | return 1; |
| 1016 | } | 981 | } |
| @@ -1054,7 +1019,7 @@ static int dlfb_ops_set_par(struct fb_info *info) | |||
| 1054 | u16 *pix_framebuffer; | 1019 | u16 *pix_framebuffer; |
| 1055 | int i; | 1020 | int i; |
| 1056 | 1021 | ||
| 1057 | dl_notice("set_par mode %dx%d\n", info->var.xres, info->var.yres); | 1022 | pr_notice("set_par mode %dx%d\n", info->var.xres, info->var.yres); |
| 1058 | 1023 | ||
| 1059 | result = dlfb_set_video_mode(dev, &info->var); | 1024 | result = dlfb_set_video_mode(dev, &info->var); |
| 1060 | 1025 | ||
| @@ -1104,7 +1069,7 @@ static int dlfb_ops_blank(int blank_mode, struct fb_info *info) | |||
| 1104 | 1069 | ||
| 1105 | static struct fb_ops dlfb_ops = { | 1070 | static struct fb_ops dlfb_ops = { |
| 1106 | .owner = THIS_MODULE, | 1071 | .owner = THIS_MODULE, |
| 1107 | .fb_read = dlfb_ops_read, | 1072 | .fb_read = fb_sys_read, |
| 1108 | .fb_write = dlfb_ops_write, | 1073 | .fb_write = dlfb_ops_write, |
| 1109 | .fb_setcolreg = dlfb_ops_setcolreg, | 1074 | .fb_setcolreg = dlfb_ops_setcolreg, |
| 1110 | .fb_fillrect = dlfb_ops_fillrect, | 1075 | .fb_fillrect = dlfb_ops_fillrect, |
| @@ -1133,7 +1098,7 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info) | |||
| 1133 | unsigned char *new_fb; | 1098 | unsigned char *new_fb; |
| 1134 | unsigned char *new_back; | 1099 | unsigned char *new_back; |
| 1135 | 1100 | ||
| 1136 | dl_warn("Reallocating framebuffer. Addresses will change!\n"); | 1101 | pr_warn("Reallocating framebuffer. Addresses will change!\n"); |
| 1137 | 1102 | ||
| 1138 | new_len = info->fix.line_length * info->var.yres; | 1103 | new_len = info->fix.line_length * info->var.yres; |
| 1139 | 1104 | ||
| @@ -1143,7 +1108,7 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info) | |||
| 1143 | */ | 1108 | */ |
| 1144 | new_fb = vmalloc(new_len); | 1109 | new_fb = vmalloc(new_len); |
| 1145 | if (!new_fb) { | 1110 | if (!new_fb) { |
| 1146 | dl_err("Virtual framebuffer alloc failed\n"); | 1111 | pr_err("Virtual framebuffer alloc failed\n"); |
| 1147 | goto error; | 1112 | goto error; |
| 1148 | } | 1113 | } |
| 1149 | 1114 | ||
| @@ -1165,7 +1130,7 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info) | |||
| 1165 | */ | 1130 | */ |
| 1166 | new_back = vmalloc(new_len); | 1131 | new_back = vmalloc(new_len); |
| 1167 | if (!new_back) | 1132 | if (!new_back) |
| 1168 | dl_info("No shadow/backing buffer allcoated\n"); | 1133 | pr_info("No shadow/backing buffer allcoated\n"); |
| 1169 | else { | 1134 | else { |
| 1170 | if (dev->backing_buffer) | 1135 | if (dev->backing_buffer) |
| 1171 | vfree(dev->backing_buffer); | 1136 | vfree(dev->backing_buffer); |
| @@ -1207,7 +1172,7 @@ static int dlfb_setup_modes(struct dlfb_data *dev, | |||
| 1207 | if (info->dev) /* only use mutex if info has been registered */ | 1172 | if (info->dev) /* only use mutex if info has been registered */ |
| 1208 | mutex_lock(&info->lock); | 1173 | mutex_lock(&info->lock); |
| 1209 | 1174 | ||
| 1210 | edid = kmalloc(MAX_EDID_SIZE, GFP_KERNEL); | 1175 | edid = kmalloc(EDID_LENGTH, GFP_KERNEL); |
| 1211 | if (!edid) { | 1176 | if (!edid) { |
| 1212 | result = -ENOMEM; | 1177 | result = -ENOMEM; |
| 1213 | goto error; | 1178 | goto error; |
| @@ -1223,9 +1188,9 @@ static int dlfb_setup_modes(struct dlfb_data *dev, | |||
| 1223 | */ | 1188 | */ |
| 1224 | while (tries--) { | 1189 | while (tries--) { |
| 1225 | 1190 | ||
| 1226 | i = dlfb_get_edid(dev, edid, MAX_EDID_SIZE); | 1191 | i = dlfb_get_edid(dev, edid, EDID_LENGTH); |
| 1227 | 1192 | ||
| 1228 | if (i >= MIN_EDID_SIZE) | 1193 | if (i >= EDID_LENGTH) |
| 1229 | fb_edid_to_monspecs(edid, &info->monspecs); | 1194 | fb_edid_to_monspecs(edid, &info->monspecs); |
| 1230 | 1195 | ||
| 1231 | if (info->monspecs.modedb_len > 0) { | 1196 | if (info->monspecs.modedb_len > 0) { |
| @@ -1238,24 +1203,24 @@ static int dlfb_setup_modes(struct dlfb_data *dev, | |||
| 1238 | /* If that fails, use a previously returned EDID if available */ | 1203 | /* If that fails, use a previously returned EDID if available */ |
| 1239 | if (info->monspecs.modedb_len == 0) { | 1204 | if (info->monspecs.modedb_len == 0) { |
| 1240 | 1205 | ||
| 1241 | dl_err("Unable to get valid EDID from device/display\n"); | 1206 | pr_err("Unable to get valid EDID from device/display\n"); |
| 1242 | 1207 | ||
| 1243 | if (dev->edid) { | 1208 | if (dev->edid) { |
| 1244 | fb_edid_to_monspecs(dev->edid, &info->monspecs); | 1209 | fb_edid_to_monspecs(dev->edid, &info->monspecs); |
| 1245 | if (info->monspecs.modedb_len > 0) | 1210 | if (info->monspecs.modedb_len > 0) |
| 1246 | dl_err("Using previously queried EDID\n"); | 1211 | pr_err("Using previously queried EDID\n"); |
| 1247 | } | 1212 | } |
| 1248 | } | 1213 | } |
| 1249 | 1214 | ||
| 1250 | /* If that fails, use the default EDID we were handed */ | 1215 | /* If that fails, use the default EDID we were handed */ |
| 1251 | if (info->monspecs.modedb_len == 0) { | 1216 | if (info->monspecs.modedb_len == 0) { |
| 1252 | if (default_edid_size >= MIN_EDID_SIZE) { | 1217 | if (default_edid_size >= EDID_LENGTH) { |
| 1253 | fb_edid_to_monspecs(default_edid, &info->monspecs); | 1218 | fb_edid_to_monspecs(default_edid, &info->monspecs); |
| 1254 | if (info->monspecs.modedb_len > 0) { | 1219 | if (info->monspecs.modedb_len > 0) { |
| 1255 | memcpy(edid, default_edid, default_edid_size); | 1220 | memcpy(edid, default_edid, default_edid_size); |
| 1256 | dev->edid = edid; | 1221 | dev->edid = edid; |
| 1257 | dev->edid_size = default_edid_size; | 1222 | dev->edid_size = default_edid_size; |
| 1258 | dl_err("Using default/backup EDID\n"); | 1223 | pr_err("Using default/backup EDID\n"); |
| 1259 | } | 1224 | } |
| 1260 | } | 1225 | } |
| 1261 | } | 1226 | } |
| @@ -1381,7 +1346,7 @@ static ssize_t edid_show( | |||
| 1381 | if (off + count > dev->edid_size) | 1346 | if (off + count > dev->edid_size) |
| 1382 | count = dev->edid_size - off; | 1347 | count = dev->edid_size - off; |
| 1383 | 1348 | ||
| 1384 | dl_info("sysfs edid copy %p to %p, %d bytes\n", | 1349 | pr_info("sysfs edid copy %p to %p, %d bytes\n", |
| 1385 | dev->edid, buf, (int) count); | 1350 | dev->edid, buf, (int) count); |
| 1386 | 1351 | ||
| 1387 | memcpy(buf, dev->edid, count); | 1352 | memcpy(buf, dev->edid, count); |
| @@ -1398,15 +1363,13 @@ static ssize_t edid_store( | |||
| 1398 | struct dlfb_data *dev = fb_info->par; | 1363 | struct dlfb_data *dev = fb_info->par; |
| 1399 | 1364 | ||
| 1400 | /* We only support write of entire EDID at once, no offset*/ | 1365 | /* We only support write of entire EDID at once, no offset*/ |
| 1401 | if ((src_size < MIN_EDID_SIZE) || | 1366 | if ((src_size != EDID_LENGTH) || (src_off != 0)) |
| 1402 | (src_size > MAX_EDID_SIZE) || | ||
| 1403 | (src_off != 0)) | ||
| 1404 | return 0; | 1367 | return 0; |
| 1405 | 1368 | ||
| 1406 | dlfb_setup_modes(dev, fb_info, src, src_size); | 1369 | dlfb_setup_modes(dev, fb_info, src, src_size); |
| 1407 | 1370 | ||
| 1408 | if (dev->edid && (memcmp(src, dev->edid, src_size) == 0)) { | 1371 | if (dev->edid && (memcmp(src, dev->edid, src_size) == 0)) { |
| 1409 | dl_info("sysfs written EDID is new default\n"); | 1372 | pr_info("sysfs written EDID is new default\n"); |
| 1410 | dlfb_ops_set_par(fb_info); | 1373 | dlfb_ops_set_par(fb_info); |
| 1411 | return src_size; | 1374 | return src_size; |
| 1412 | } else | 1375 | } else |
| @@ -1431,7 +1394,7 @@ static ssize_t metrics_reset_store(struct device *fbdev, | |||
| 1431 | static struct bin_attribute edid_attr = { | 1394 | static struct bin_attribute edid_attr = { |
| 1432 | .attr.name = "edid", | 1395 | .attr.name = "edid", |
| 1433 | .attr.mode = 0666, | 1396 | .attr.mode = 0666, |
| 1434 | .size = MAX_EDID_SIZE, | 1397 | .size = EDID_LENGTH, |
| 1435 | .read = edid_show, | 1398 | .read = edid_show, |
| 1436 | .write = edid_store | 1399 | .write = edid_store |
| 1437 | }; | 1400 | }; |
| @@ -1479,7 +1442,7 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev, | |||
| 1479 | total_len = usb_get_descriptor(usbdev, 0x5f, /* vendor specific */ | 1442 | total_len = usb_get_descriptor(usbdev, 0x5f, /* vendor specific */ |
| 1480 | 0, desc, MAX_VENDOR_DESCRIPTOR_SIZE); | 1443 | 0, desc, MAX_VENDOR_DESCRIPTOR_SIZE); |
| 1481 | if (total_len > 5) { | 1444 | if (total_len > 5) { |
| 1482 | dl_info("vendor descriptor length:%x data:%02x %02x %02x %02x" \ | 1445 | pr_info("vendor descriptor length:%x data:%02x %02x %02x %02x" \ |
| 1483 | "%02x %02x %02x %02x %02x %02x %02x\n", | 1446 | "%02x %02x %02x %02x %02x %02x %02x\n", |
| 1484 | total_len, desc[0], | 1447 | total_len, desc[0], |
| 1485 | desc[1], desc[2], desc[3], desc[4], desc[5], desc[6], | 1448 | desc[1], desc[2], desc[3], desc[4], desc[5], desc[6], |
| @@ -1508,7 +1471,7 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev, | |||
| 1508 | case 0x0200: { /* max_area */ | 1471 | case 0x0200: { /* max_area */ |
| 1509 | u32 max_area; | 1472 | u32 max_area; |
| 1510 | max_area = le32_to_cpu(*((u32 *)desc)); | 1473 | max_area = le32_to_cpu(*((u32 *)desc)); |
| 1511 | dl_warn("DL chip limited to %d pixel modes\n", | 1474 | pr_warn("DL chip limited to %d pixel modes\n", |
| 1512 | max_area); | 1475 | max_area); |
| 1513 | dev->sku_pixel_limit = max_area; | 1476 | dev->sku_pixel_limit = max_area; |
| 1514 | break; | 1477 | break; |
| @@ -1524,7 +1487,7 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev, | |||
| 1524 | 1487 | ||
| 1525 | unrecognized: | 1488 | unrecognized: |
| 1526 | /* allow udlfb to load for now even if firmware unrecognized */ | 1489 | /* allow udlfb to load for now even if firmware unrecognized */ |
| 1527 | dl_err("Unrecognized vendor firmware descriptor\n"); | 1490 | pr_err("Unrecognized vendor firmware descriptor\n"); |
| 1528 | 1491 | ||
| 1529 | success: | 1492 | success: |
| 1530 | kfree(buf); | 1493 | kfree(buf); |
| @@ -1557,24 +1520,24 @@ static int dlfb_usb_probe(struct usb_interface *interface, | |||
| 1557 | dev->gdev = &usbdev->dev; /* our generic struct device * */ | 1520 | dev->gdev = &usbdev->dev; /* our generic struct device * */ |
| 1558 | usb_set_intfdata(interface, dev); | 1521 | usb_set_intfdata(interface, dev); |
| 1559 | 1522 | ||
| 1560 | dl_info("%s %s - serial #%s\n", | 1523 | pr_info("%s %s - serial #%s\n", |
| 1561 | usbdev->manufacturer, usbdev->product, usbdev->serial); | 1524 | usbdev->manufacturer, usbdev->product, usbdev->serial); |
| 1562 | dl_info("vid_%04x&pid_%04x&rev_%04x driver's dlfb_data struct at %p\n", | 1525 | pr_info("vid_%04x&pid_%04x&rev_%04x driver's dlfb_data struct at %p\n", |
| 1563 | usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, | 1526 | usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, |
| 1564 | usbdev->descriptor.bcdDevice, dev); | 1527 | usbdev->descriptor.bcdDevice, dev); |
| 1565 | dl_info("console enable=%d\n", console); | 1528 | pr_info("console enable=%d\n", console); |
| 1566 | dl_info("fb_defio enable=%d\n", fb_defio); | 1529 | pr_info("fb_defio enable=%d\n", fb_defio); |
| 1567 | 1530 | ||
| 1568 | dev->sku_pixel_limit = 2048 * 1152; /* default to maximum */ | 1531 | dev->sku_pixel_limit = 2048 * 1152; /* default to maximum */ |
| 1569 | 1532 | ||
| 1570 | if (!dlfb_parse_vendor_descriptor(dev, usbdev)) { | 1533 | if (!dlfb_parse_vendor_descriptor(dev, usbdev)) { |
| 1571 | dl_err("firmware not recognized. Assume incompatible device\n"); | 1534 | pr_err("firmware not recognized. Assume incompatible device\n"); |
| 1572 | goto error; | 1535 | goto error; |
| 1573 | } | 1536 | } |
| 1574 | 1537 | ||
| 1575 | if (!dlfb_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) { | 1538 | if (!dlfb_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) { |
| 1576 | retval = -ENOMEM; | 1539 | retval = -ENOMEM; |
| 1577 | dl_err("dlfb_alloc_urb_list failed\n"); | 1540 | pr_err("dlfb_alloc_urb_list failed\n"); |
| 1578 | goto error; | 1541 | goto error; |
| 1579 | } | 1542 | } |
| 1580 | 1543 | ||
| @@ -1584,7 +1547,7 @@ static int dlfb_usb_probe(struct usb_interface *interface, | |||
| 1584 | info = framebuffer_alloc(0, &usbdev->dev); | 1547 | info = framebuffer_alloc(0, &usbdev->dev); |
| 1585 | if (!info) { | 1548 | if (!info) { |
| 1586 | retval = -ENOMEM; | 1549 | retval = -ENOMEM; |
| 1587 | dl_err("framebuffer_alloc failed\n"); | 1550 | pr_err("framebuffer_alloc failed\n"); |
| 1588 | goto error; | 1551 | goto error; |
| 1589 | } | 1552 | } |
| 1590 | 1553 | ||
| @@ -1595,7 +1558,7 @@ static int dlfb_usb_probe(struct usb_interface *interface, | |||
| 1595 | 1558 | ||
| 1596 | retval = fb_alloc_cmap(&info->cmap, 256, 0); | 1559 | retval = fb_alloc_cmap(&info->cmap, 256, 0); |
| 1597 | if (retval < 0) { | 1560 | if (retval < 0) { |
| 1598 | dl_err("fb_alloc_cmap failed %x\n", retval); | 1561 | pr_err("fb_alloc_cmap failed %x\n", retval); |
| 1599 | goto error; | 1562 | goto error; |
| 1600 | } | 1563 | } |
| 1601 | 1564 | ||
| @@ -1606,7 +1569,7 @@ static int dlfb_usb_probe(struct usb_interface *interface, | |||
| 1606 | 1569 | ||
| 1607 | retval = dlfb_setup_modes(dev, info, NULL, 0); | 1570 | retval = dlfb_setup_modes(dev, info, NULL, 0); |
| 1608 | if (retval != 0) { | 1571 | if (retval != 0) { |
| 1609 | dl_err("unable to find common mode for display and adapter\n"); | 1572 | pr_err("unable to find common mode for display and adapter\n"); |
| 1610 | goto error; | 1573 | goto error; |
| 1611 | } | 1574 | } |
| 1612 | 1575 | ||
| @@ -1620,7 +1583,7 @@ static int dlfb_usb_probe(struct usb_interface *interface, | |||
| 1620 | 1583 | ||
| 1621 | retval = register_framebuffer(info); | 1584 | retval = register_framebuffer(info); |
| 1622 | if (retval < 0) { | 1585 | if (retval < 0) { |
| 1623 | dl_err("register_framebuffer failed %d\n", retval); | 1586 | pr_err("register_framebuffer failed %d\n", retval); |
| 1624 | goto error; | 1587 | goto error; |
| 1625 | } | 1588 | } |
| 1626 | 1589 | ||
| @@ -1629,7 +1592,7 @@ static int dlfb_usb_probe(struct usb_interface *interface, | |||
| 1629 | 1592 | ||
| 1630 | device_create_bin_file(info->dev, &edid_attr); | 1593 | device_create_bin_file(info->dev, &edid_attr); |
| 1631 | 1594 | ||
| 1632 | dl_info("DisplayLink USB device /dev/fb%d attached. %dx%d resolution." | 1595 | pr_info("DisplayLink USB device /dev/fb%d attached. %dx%d resolution." |
| 1633 | " Using %dK framebuffer memory\n", info->node, | 1596 | " Using %dK framebuffer memory\n", info->node, |
| 1634 | info->var.xres, info->var.yres, | 1597 | info->var.xres, info->var.yres, |
| 1635 | ((dev->backing_buffer) ? | 1598 | ((dev->backing_buffer) ? |
| @@ -1673,7 +1636,7 @@ static void dlfb_usb_disconnect(struct usb_interface *interface) | |||
| 1673 | dev = usb_get_intfdata(interface); | 1636 | dev = usb_get_intfdata(interface); |
| 1674 | info = dev->info; | 1637 | info = dev->info; |
| 1675 | 1638 | ||
| 1676 | dl_info("USB disconnect starting\n"); | 1639 | pr_info("USB disconnect starting\n"); |
| 1677 | 1640 | ||
| 1678 | /* we virtualize until all fb clients release. Then we free */ | 1641 | /* we virtualize until all fb clients release. Then we free */ |
| 1679 | dev->virtualized = true; | 1642 | dev->virtualized = true; |
| @@ -1737,7 +1700,7 @@ static void dlfb_urb_completion(struct urb *urb) | |||
| 1737 | if (!(urb->status == -ENOENT || | 1700 | if (!(urb->status == -ENOENT || |
| 1738 | urb->status == -ECONNRESET || | 1701 | urb->status == -ECONNRESET || |
| 1739 | urb->status == -ESHUTDOWN)) { | 1702 | urb->status == -ESHUTDOWN)) { |
| 1740 | dl_err("%s - nonzero write bulk status received: %d\n", | 1703 | pr_err("%s - nonzero write bulk status received: %d\n", |
| 1741 | __func__, urb->status); | 1704 | __func__, urb->status); |
| 1742 | atomic_set(&dev->lost_pixels, 1); | 1705 | atomic_set(&dev->lost_pixels, 1); |
| 1743 | } | 1706 | } |
| @@ -1769,7 +1732,7 @@ static void dlfb_free_urb_list(struct dlfb_data *dev) | |||
| 1769 | int ret; | 1732 | int ret; |
| 1770 | unsigned long flags; | 1733 | unsigned long flags; |
| 1771 | 1734 | ||
| 1772 | dl_notice("Waiting for completes and freeing all render urbs\n"); | 1735 | pr_notice("Waiting for completes and freeing all render urbs\n"); |
| 1773 | 1736 | ||
| 1774 | /* keep waiting and freeing, until we've got 'em all */ | 1737 | /* keep waiting and freeing, until we've got 'em all */ |
| 1775 | while (count--) { | 1738 | while (count--) { |
| @@ -1848,7 +1811,7 @@ static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size) | |||
| 1848 | dev->urbs.count = i; | 1811 | dev->urbs.count = i; |
| 1849 | dev->urbs.available = i; | 1812 | dev->urbs.available = i; |
| 1850 | 1813 | ||
| 1851 | dl_notice("allocated %d %d byte urbs\n", i, (int) size); | 1814 | pr_notice("allocated %d %d byte urbs\n", i, (int) size); |
| 1852 | 1815 | ||
| 1853 | return i; | 1816 | return i; |
| 1854 | } | 1817 | } |
| @@ -1865,7 +1828,7 @@ static struct urb *dlfb_get_urb(struct dlfb_data *dev) | |||
| 1865 | ret = down_timeout(&dev->urbs.limit_sem, GET_URB_TIMEOUT); | 1828 | ret = down_timeout(&dev->urbs.limit_sem, GET_URB_TIMEOUT); |
| 1866 | if (ret) { | 1829 | if (ret) { |
| 1867 | atomic_set(&dev->lost_pixels, 1); | 1830 | atomic_set(&dev->lost_pixels, 1); |
| 1868 | dl_warn("wait for urb interrupted: %x available: %d\n", | 1831 | pr_warn("wait for urb interrupted: %x available: %d\n", |
| 1869 | ret, dev->urbs.available); | 1832 | ret, dev->urbs.available); |
| 1870 | goto error; | 1833 | goto error; |
| 1871 | } | 1834 | } |
| @@ -1897,7 +1860,7 @@ static int dlfb_submit_urb(struct dlfb_data *dev, struct urb *urb, size_t len) | |||
| 1897 | if (ret) { | 1860 | if (ret) { |
| 1898 | dlfb_urb_completion(urb); /* because no one else will */ | 1861 | dlfb_urb_completion(urb); /* because no one else will */ |
| 1899 | atomic_set(&dev->lost_pixels, 1); | 1862 | atomic_set(&dev->lost_pixels, 1); |
| 1900 | dl_err("usb_submit_urb error %x\n", ret); | 1863 | pr_err("usb_submit_urb error %x\n", ret); |
| 1901 | } | 1864 | } |
| 1902 | return ret; | 1865 | return ret; |
| 1903 | } | 1866 | } |
diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c index a3aa91709503..6723d6910cde 100644 --- a/drivers/video/via/via-core.c +++ b/drivers/video/via/via-core.c | |||
| @@ -15,6 +15,9 @@ | |||
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
| 17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 18 | #include <linux/list.h> | ||
| 19 | #include <linux/pm.h> | ||
| 20 | #include <asm/olpc.h> | ||
| 18 | 21 | ||
| 19 | /* | 22 | /* |
| 20 | * The default port config. | 23 | * The default port config. |
| @@ -29,6 +32,19 @@ static struct via_port_cfg adap_configs[] = { | |||
| 29 | }; | 32 | }; |
| 30 | 33 | ||
| 31 | /* | 34 | /* |
| 35 | * The OLPC XO-1.5 puts the camera power and reset lines onto | ||
| 36 | * GPIO 2C. | ||
| 37 | */ | ||
| 38 | static const struct via_port_cfg olpc_adap_configs[] = { | ||
| 39 | [VIA_PORT_26] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x26 }, | ||
| 40 | [VIA_PORT_31] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x31 }, | ||
| 41 | [VIA_PORT_25] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x25 }, | ||
| 42 | [VIA_PORT_2C] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x2c }, | ||
| 43 | [VIA_PORT_3D] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x3d }, | ||
| 44 | { 0, 0, 0, 0 } | ||
| 45 | }; | ||
| 46 | |||
| 47 | /* | ||
| 32 | * We currently only support one viafb device (will there ever be | 48 | * We currently only support one viafb device (will there ever be |
| 33 | * more than one?), so just declare it globally here. | 49 | * more than one?), so just declare it globally here. |
| 34 | */ | 50 | */ |
| @@ -575,6 +591,78 @@ static void via_teardown_subdevs(void) | |||
| 575 | } | 591 | } |
| 576 | } | 592 | } |
| 577 | 593 | ||
| 594 | /* | ||
| 595 | * Power management functions | ||
| 596 | */ | ||
| 597 | #ifdef CONFIG_PM | ||
| 598 | static LIST_HEAD(viafb_pm_hooks); | ||
| 599 | static DEFINE_MUTEX(viafb_pm_hooks_lock); | ||
| 600 | |||
| 601 | void viafb_pm_register(struct viafb_pm_hooks *hooks) | ||
| 602 | { | ||
| 603 | INIT_LIST_HEAD(&hooks->list); | ||
| 604 | |||
| 605 | mutex_lock(&viafb_pm_hooks_lock); | ||
| 606 | list_add_tail(&hooks->list, &viafb_pm_hooks); | ||
| 607 | mutex_unlock(&viafb_pm_hooks_lock); | ||
| 608 | } | ||
| 609 | EXPORT_SYMBOL_GPL(viafb_pm_register); | ||
| 610 | |||
| 611 | void viafb_pm_unregister(struct viafb_pm_hooks *hooks) | ||
| 612 | { | ||
| 613 | mutex_lock(&viafb_pm_hooks_lock); | ||
| 614 | list_del(&hooks->list); | ||
| 615 | mutex_unlock(&viafb_pm_hooks_lock); | ||
| 616 | } | ||
| 617 | EXPORT_SYMBOL_GPL(viafb_pm_unregister); | ||
| 618 | |||
| 619 | static int via_suspend(struct pci_dev *pdev, pm_message_t state) | ||
| 620 | { | ||
| 621 | struct viafb_pm_hooks *hooks; | ||
| 622 | |||
| 623 | if (state.event != PM_EVENT_SUSPEND) | ||
| 624 | return 0; | ||
| 625 | /* | ||
| 626 | * "I've occasionally hit a few drivers that caused suspend | ||
| 627 | * failures, and each and every time it was a driver bug, and | ||
| 628 | * the right thing to do was to just ignore the error and suspend | ||
| 629 | * anyway - returning an error code and trying to undo the suspend | ||
| 630 | * is not what anybody ever really wants, even if our model | ||
| 631 | *_allows_ for it." | ||
| 632 | * -- Linus Torvalds, Dec. 7, 2009 | ||
| 633 | */ | ||
| 634 | mutex_lock(&viafb_pm_hooks_lock); | ||
| 635 | list_for_each_entry_reverse(hooks, &viafb_pm_hooks, list) | ||
| 636 | hooks->suspend(hooks->private); | ||
| 637 | mutex_unlock(&viafb_pm_hooks_lock); | ||
| 638 | |||
| 639 | pci_save_state(pdev); | ||
| 640 | pci_disable_device(pdev); | ||
| 641 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
| 642 | return 0; | ||
| 643 | } | ||
| 644 | |||
| 645 | static int via_resume(struct pci_dev *pdev) | ||
| 646 | { | ||
| 647 | struct viafb_pm_hooks *hooks; | ||
| 648 | |||
| 649 | /* Get the bus side powered up */ | ||
| 650 | pci_set_power_state(pdev, PCI_D0); | ||
| 651 | pci_restore_state(pdev); | ||
| 652 | if (pci_enable_device(pdev)) | ||
| 653 | return 0; | ||
| 654 | |||
| 655 | pci_set_master(pdev); | ||
| 656 | |||
| 657 | /* Now bring back any subdevs */ | ||
| 658 | mutex_lock(&viafb_pm_hooks_lock); | ||
| 659 | list_for_each_entry(hooks, &viafb_pm_hooks, list) | ||
| 660 | hooks->resume(hooks->private); | ||
| 661 | mutex_unlock(&viafb_pm_hooks_lock); | ||
| 662 | |||
| 663 | return 0; | ||
| 664 | } | ||
| 665 | #endif /* CONFIG_PM */ | ||
| 578 | 666 | ||
| 579 | static int __devinit via_pci_probe(struct pci_dev *pdev, | 667 | static int __devinit via_pci_probe(struct pci_dev *pdev, |
| 580 | const struct pci_device_id *ent) | 668 | const struct pci_device_id *ent) |
| @@ -584,6 +672,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
| 584 | ret = pci_enable_device(pdev); | 672 | ret = pci_enable_device(pdev); |
| 585 | if (ret) | 673 | if (ret) |
| 586 | return ret; | 674 | return ret; |
| 675 | |||
| 587 | /* | 676 | /* |
| 588 | * Global device initialization. | 677 | * Global device initialization. |
| 589 | */ | 678 | */ |
| @@ -591,6 +680,9 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
| 591 | global_dev.pdev = pdev; | 680 | global_dev.pdev = pdev; |
| 592 | global_dev.chip_type = ent->driver_data; | 681 | global_dev.chip_type = ent->driver_data; |
| 593 | global_dev.port_cfg = adap_configs; | 682 | global_dev.port_cfg = adap_configs; |
| 683 | if (machine_is_olpc()) | ||
| 684 | global_dev.port_cfg = olpc_adap_configs; | ||
| 685 | |||
| 594 | spin_lock_init(&global_dev.reg_lock); | 686 | spin_lock_init(&global_dev.reg_lock); |
| 595 | ret = via_pci_setup_mmio(&global_dev); | 687 | ret = via_pci_setup_mmio(&global_dev); |
| 596 | if (ret) | 688 | if (ret) |
| @@ -663,8 +755,8 @@ static struct pci_driver via_driver = { | |||
| 663 | .probe = via_pci_probe, | 755 | .probe = via_pci_probe, |
| 664 | .remove = __devexit_p(via_pci_remove), | 756 | .remove = __devexit_p(via_pci_remove), |
| 665 | #ifdef CONFIG_PM | 757 | #ifdef CONFIG_PM |
| 666 | .suspend = viafb_suspend, | 758 | .suspend = via_suspend, |
| 667 | .resume = viafb_resume, | 759 | .resume = via_resume, |
| 668 | #endif | 760 | #endif |
| 669 | }; | 761 | }; |
| 670 | 762 | ||
diff --git a/drivers/video/via/via-gpio.c b/drivers/video/via/via-gpio.c index 39acb37e7a1d..c2a0a1cfd3b3 100644 --- a/drivers/video/via/via-gpio.c +++ b/drivers/video/via/via-gpio.c | |||
| @@ -172,6 +172,28 @@ static void viafb_gpio_disable(struct viafb_gpio *gpio) | |||
| 172 | via_write_reg_mask(VIASR, gpio->vg_port_index, 0, 0x02); | 172 | via_write_reg_mask(VIASR, gpio->vg_port_index, 0, 0x02); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | #ifdef CONFIG_PM | ||
| 176 | |||
| 177 | static int viafb_gpio_suspend(void *private) | ||
| 178 | { | ||
| 179 | return 0; | ||
| 180 | } | ||
| 181 | |||
| 182 | static int viafb_gpio_resume(void *private) | ||
| 183 | { | ||
| 184 | int i; | ||
| 185 | |||
| 186 | for (i = 0; i < gpio_config.gpio_chip.ngpio; i += 2) | ||
| 187 | viafb_gpio_enable(gpio_config.active_gpios[i]); | ||
| 188 | return 0; | ||
| 189 | } | ||
| 190 | |||
| 191 | static struct viafb_pm_hooks viafb_gpio_pm_hooks = { | ||
| 192 | .suspend = viafb_gpio_suspend, | ||
| 193 | .resume = viafb_gpio_resume | ||
| 194 | }; | ||
| 195 | #endif /* CONFIG_PM */ | ||
| 196 | |||
| 175 | /* | 197 | /* |
| 176 | * Look up a specific gpio and return the number it was assigned. | 198 | * Look up a specific gpio and return the number it was assigned. |
| 177 | */ | 199 | */ |
| @@ -236,6 +258,9 @@ static __devinit int viafb_gpio_probe(struct platform_device *platdev) | |||
| 236 | printk(KERN_ERR "viafb: failed to add gpios (%d)\n", ret); | 258 | printk(KERN_ERR "viafb: failed to add gpios (%d)\n", ret); |
| 237 | gpio_config.gpio_chip.ngpio = 0; | 259 | gpio_config.gpio_chip.ngpio = 0; |
| 238 | } | 260 | } |
| 261 | #ifdef CONFIG_PM | ||
| 262 | viafb_pm_register(&viafb_gpio_pm_hooks); | ||
| 263 | #endif | ||
| 239 | return ret; | 264 | return ret; |
| 240 | } | 265 | } |
| 241 | 266 | ||
| @@ -245,6 +270,10 @@ static int viafb_gpio_remove(struct platform_device *platdev) | |||
| 245 | unsigned long flags; | 270 | unsigned long flags; |
| 246 | int ret = 0, i; | 271 | int ret = 0, i; |
| 247 | 272 | ||
| 273 | #ifdef CONFIG_PM | ||
| 274 | viafb_pm_unregister(&viafb_gpio_pm_hooks); | ||
| 275 | #endif | ||
| 276 | |||
| 248 | /* | 277 | /* |
| 249 | * Get unregistered. | 278 | * Get unregistered. |
| 250 | */ | 279 | */ |
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index d298cfccd6fc..289edd519527 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
| @@ -1672,31 +1672,19 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres) | |||
| 1672 | 1672 | ||
| 1673 | 1673 | ||
| 1674 | #ifdef CONFIG_PM | 1674 | #ifdef CONFIG_PM |
| 1675 | int viafb_suspend(struct pci_dev *pdev, pm_message_t state) | 1675 | static int viafb_suspend(void *unused) |
| 1676 | { | 1676 | { |
| 1677 | if (state.event == PM_EVENT_SUSPEND) { | 1677 | acquire_console_sem(); |
| 1678 | acquire_console_sem(); | 1678 | fb_set_suspend(viafbinfo, 1); |
| 1679 | fb_set_suspend(viafbinfo, 1); | 1679 | viafb_sync(viafbinfo); |
| 1680 | 1680 | release_console_sem(); | |
| 1681 | viafb_sync(viafbinfo); | ||
| 1682 | |||
| 1683 | pci_save_state(pdev); | ||
| 1684 | pci_disable_device(pdev); | ||
| 1685 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
| 1686 | release_console_sem(); | ||
| 1687 | } | ||
| 1688 | 1681 | ||
| 1689 | return 0; | 1682 | return 0; |
| 1690 | } | 1683 | } |
| 1691 | 1684 | ||
| 1692 | int viafb_resume(struct pci_dev *pdev) | 1685 | static int viafb_resume(void *unused) |
| 1693 | { | 1686 | { |
| 1694 | acquire_console_sem(); | 1687 | acquire_console_sem(); |
| 1695 | pci_set_power_state(pdev, PCI_D0); | ||
| 1696 | pci_restore_state(pdev); | ||
| 1697 | if (pci_enable_device(pdev)) | ||
| 1698 | goto fail; | ||
| 1699 | pci_set_master(pdev); | ||
| 1700 | if (viaparinfo->shared->vdev->engine_mmio) | 1688 | if (viaparinfo->shared->vdev->engine_mmio) |
| 1701 | viafb_reset_engine(viaparinfo); | 1689 | viafb_reset_engine(viaparinfo); |
| 1702 | viafb_set_par(viafbinfo); | 1690 | viafb_set_par(viafbinfo); |
| @@ -1704,11 +1692,15 @@ int viafb_resume(struct pci_dev *pdev) | |||
| 1704 | viafb_set_par(viafbinfo1); | 1692 | viafb_set_par(viafbinfo1); |
| 1705 | fb_set_suspend(viafbinfo, 0); | 1693 | fb_set_suspend(viafbinfo, 0); |
| 1706 | 1694 | ||
| 1707 | fail: | ||
| 1708 | release_console_sem(); | 1695 | release_console_sem(); |
| 1709 | return 0; | 1696 | return 0; |
| 1710 | } | 1697 | } |
| 1711 | 1698 | ||
| 1699 | static struct viafb_pm_hooks viafb_fb_pm_hooks = { | ||
| 1700 | .suspend = viafb_suspend, | ||
| 1701 | .resume = viafb_resume | ||
| 1702 | }; | ||
| 1703 | |||
| 1712 | #endif | 1704 | #endif |
| 1713 | 1705 | ||
| 1714 | 1706 | ||
| @@ -1899,6 +1891,10 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev) | |||
| 1899 | 1891 | ||
| 1900 | viafb_init_proc(viaparinfo->shared); | 1892 | viafb_init_proc(viaparinfo->shared); |
| 1901 | viafb_init_dac(IGA2); | 1893 | viafb_init_dac(IGA2); |
| 1894 | |||
| 1895 | #ifdef CONFIG_PM | ||
| 1896 | viafb_pm_register(&viafb_fb_pm_hooks); | ||
| 1897 | #endif | ||
| 1902 | return 0; | 1898 | return 0; |
| 1903 | 1899 | ||
| 1904 | out_fb_unreg: | 1900 | out_fb_unreg: |
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 4960e3da6645..d66f963e930e 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h | |||
| @@ -108,6 +108,4 @@ void via_fb_pci_remove(struct pci_dev *pdev); | |||
| 108 | /* Temporary */ | 108 | /* Temporary */ |
| 109 | int viafb_init(void); | 109 | int viafb_init(void); |
| 110 | void viafb_exit(void); | 110 | void viafb_exit(void); |
| 111 | int viafb_suspend(struct pci_dev *pdev, pm_message_t state); | ||
| 112 | int viafb_resume(struct pci_dev *pdev); | ||
| 113 | #endif /* __VIAFBDEV_H__ */ | 111 | #endif /* __VIAFBDEV_H__ */ |
diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/vt8500lcdfb.c new file mode 100644 index 000000000000..7617f12e4fd7 --- /dev/null +++ b/drivers/video/vt8500lcdfb.c | |||
| @@ -0,0 +1,447 @@ | |||
| 1 | /* | ||
| 2 | * linux/drivers/video/vt8500lcdfb.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> | ||
| 5 | * | ||
| 6 | * Based on skeletonfb.c and pxafb.c | ||
| 7 | * | ||
| 8 | * This software is licensed under the terms of the GNU General Public | ||
| 9 | * License version 2, as published by the Free Software Foundation, and | ||
| 10 | * may be copied, distributed, and modified under those terms. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/errno.h> | ||
| 21 | #include <linux/string.h> | ||
| 22 | #include <linux/mm.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | #include <linux/delay.h> | ||
| 25 | #include <linux/fb.h> | ||
| 26 | #include <linux/init.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | #include <linux/io.h> | ||
| 29 | #include <linux/dma-mapping.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | #include <linux/wait.h> | ||
| 32 | |||
| 33 | #include <mach/vt8500fb.h> | ||
| 34 | |||
| 35 | #include "vt8500lcdfb.h" | ||
| 36 | #include "wmt_ge_rops.h" | ||
| 37 | |||
| 38 | #define to_vt8500lcd_info(__info) container_of(__info, \ | ||
| 39 | struct vt8500lcd_info, fb) | ||
| 40 | |||
| 41 | static int vt8500lcd_set_par(struct fb_info *info) | ||
| 42 | { | ||
| 43 | struct vt8500lcd_info *fbi = to_vt8500lcd_info(info); | ||
| 44 | int reg_bpp = 5; /* 16bpp */ | ||
| 45 | int i; | ||
| 46 | unsigned long control0; | ||
| 47 | |||
| 48 | if (!fbi) | ||
| 49 | return -EINVAL; | ||
| 50 | |||
| 51 | if (info->var.bits_per_pixel <= 8) { | ||
| 52 | /* palettized */ | ||
| 53 | info->var.red.offset = 0; | ||
| 54 | info->var.red.length = info->var.bits_per_pixel; | ||
| 55 | info->var.red.msb_right = 0; | ||
| 56 | |||
| 57 | info->var.green.offset = 0; | ||
| 58 | info->var.green.length = info->var.bits_per_pixel; | ||
| 59 | info->var.green.msb_right = 0; | ||
| 60 | |||
| 61 | info->var.blue.offset = 0; | ||
| 62 | info->var.blue.length = info->var.bits_per_pixel; | ||
| 63 | info->var.blue.msb_right = 0; | ||
| 64 | |||
| 65 | info->var.transp.offset = 0; | ||
| 66 | info->var.transp.length = 0; | ||
| 67 | info->var.transp.msb_right = 0; | ||
| 68 | |||
| 69 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; | ||
| 70 | info->fix.line_length = info->var.xres_virtual / | ||
| 71 | (8/info->var.bits_per_pixel); | ||
| 72 | } else { | ||
| 73 | /* non-palettized */ | ||
| 74 | info->var.transp.offset = 0; | ||
| 75 | info->var.transp.length = 0; | ||
| 76 | info->var.transp.msb_right = 0; | ||
| 77 | |||
| 78 | if (info->var.bits_per_pixel == 16) { | ||
| 79 | /* RGB565 */ | ||
| 80 | info->var.red.offset = 11; | ||
| 81 | info->var.red.length = 5; | ||
| 82 | info->var.red.msb_right = 0; | ||
| 83 | info->var.green.offset = 5; | ||
| 84 | info->var.green.length = 6; | ||
| 85 | info->var.green.msb_right = 0; | ||
| 86 | info->var.blue.offset = 0; | ||
| 87 | info->var.blue.length = 5; | ||
| 88 | info->var.blue.msb_right = 0; | ||
| 89 | } else { | ||
| 90 | /* Equal depths per channel */ | ||
| 91 | info->var.red.offset = info->var.bits_per_pixel | ||
| 92 | * 2 / 3; | ||
| 93 | info->var.red.length = info->var.bits_per_pixel / 3; | ||
| 94 | info->var.red.msb_right = 0; | ||
| 95 | info->var.green.offset = info->var.bits_per_pixel / 3; | ||
| 96 | info->var.green.length = info->var.bits_per_pixel / 3; | ||
| 97 | info->var.green.msb_right = 0; | ||
| 98 | info->var.blue.offset = 0; | ||
| 99 | info->var.blue.length = info->var.bits_per_pixel / 3; | ||
| 100 | info->var.blue.msb_right = 0; | ||
| 101 | } | ||
| 102 | |||
| 103 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
| 104 | info->fix.line_length = info->var.bits_per_pixel > 16 ? | ||
| 105 | info->var.xres_virtual << 2 : | ||
| 106 | info->var.xres_virtual << 1; | ||
| 107 | } | ||
| 108 | |||
| 109 | for (i = 0; i < 8; i++) { | ||
| 110 | if (bpp_values[i] == info->var.bits_per_pixel) { | ||
| 111 | reg_bpp = i; | ||
| 112 | continue; | ||
| 113 | } | ||
| 114 | } | ||
| 115 | |||
| 116 | control0 = readl(fbi->regbase) & ~0xf; | ||
| 117 | writel(0, fbi->regbase); | ||
| 118 | while (readl(fbi->regbase + 0x38) & 0x10) | ||
| 119 | /* wait */; | ||
| 120 | writel((((info->var.hsync_len - 1) & 0x3f) << 26) | ||
| 121 | | ((info->var.left_margin & 0xff) << 18) | ||
| 122 | | (((info->var.xres - 1) & 0x3ff) << 8) | ||
| 123 | | (info->var.right_margin & 0xff), fbi->regbase + 0x4); | ||
| 124 | writel((((info->var.vsync_len - 1) & 0x3f) << 26) | ||
| 125 | | ((info->var.upper_margin & 0xff) << 18) | ||
| 126 | | (((info->var.yres - 1) & 0x3ff) << 8) | ||
| 127 | | (info->var.lower_margin & 0xff), fbi->regbase + 0x8); | ||
| 128 | writel((((info->var.yres - 1) & 0x400) << 2) | ||
| 129 | | ((info->var.xres - 1) & 0x400), fbi->regbase + 0x10); | ||
| 130 | writel(0x80000000, fbi->regbase + 0x20); | ||
| 131 | writel(control0 | (reg_bpp << 1) | 0x100, fbi->regbase); | ||
| 132 | |||
| 133 | return 0; | ||
| 134 | } | ||
| 135 | |||
| 136 | static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf) | ||
| 137 | { | ||
| 138 | chan &= 0xffff; | ||
| 139 | chan >>= 16 - bf->length; | ||
| 140 | return chan << bf->offset; | ||
| 141 | } | ||
| 142 | |||
| 143 | static int vt8500lcd_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
| 144 | unsigned blue, unsigned transp, | ||
| 145 | struct fb_info *info) { | ||
| 146 | struct vt8500lcd_info *fbi = to_vt8500lcd_info(info); | ||
| 147 | int ret = 1; | ||
| 148 | unsigned int val; | ||
| 149 | if (regno >= 256) | ||
| 150 | return -EINVAL; | ||
| 151 | |||
| 152 | if (info->var.grayscale) | ||
| 153 | red = green = blue = | ||
| 154 | (19595 * red + 38470 * green + 7471 * blue) >> 16; | ||
| 155 | |||
| 156 | switch (fbi->fb.fix.visual) { | ||
| 157 | case FB_VISUAL_TRUECOLOR: | ||
| 158 | if (regno < 16) { | ||
| 159 | u32 *pal = fbi->fb.pseudo_palette; | ||
| 160 | |||
| 161 | val = chan_to_field(red, &fbi->fb.var.red); | ||
| 162 | val |= chan_to_field(green, &fbi->fb.var.green); | ||
| 163 | val |= chan_to_field(blue, &fbi->fb.var.blue); | ||
| 164 | |||
| 165 | pal[regno] = val; | ||
| 166 | ret = 0; | ||
| 167 | } | ||
| 168 | break; | ||
| 169 | |||
| 170 | case FB_VISUAL_STATIC_PSEUDOCOLOR: | ||
| 171 | case FB_VISUAL_PSEUDOCOLOR: | ||
| 172 | writew((red & 0xf800) | ||
| 173 | | ((green >> 5) & 0x7e0) | ||
| 174 | | ((blue >> 11) & 0x1f), | ||
| 175 | fbi->palette_cpu + sizeof(u16) * regno); | ||
| 176 | break; | ||
| 177 | } | ||
| 178 | |||
| 179 | return ret; | ||
| 180 | } | ||
| 181 | |||
| 182 | static int vt8500lcd_ioctl(struct fb_info *info, unsigned int cmd, | ||
| 183 | unsigned long arg) | ||
| 184 | { | ||
| 185 | int ret = 0; | ||
| 186 | struct vt8500lcd_info *fbi = to_vt8500lcd_info(info); | ||
| 187 | |||
| 188 | if (cmd == FBIO_WAITFORVSYNC) { | ||
| 189 | /* Unmask End of Frame interrupt */ | ||
| 190 | writel(0xffffffff ^ (1 << 3), fbi->regbase + 0x3c); | ||
| 191 | ret = wait_event_interruptible_timeout(fbi->wait, | ||
| 192 | readl(fbi->regbase + 0x38) & (1 << 3), HZ / 10); | ||
| 193 | /* Mask back to reduce unwanted interrupt traffic */ | ||
| 194 | writel(0xffffffff, fbi->regbase + 0x3c); | ||
| 195 | if (ret < 0) | ||
| 196 | return ret; | ||
| 197 | if (ret == 0) | ||
| 198 | return -ETIMEDOUT; | ||
| 199 | } | ||
| 200 | |||
| 201 | return ret; | ||
| 202 | } | ||
| 203 | |||
| 204 | static int vt8500lcd_pan_display(struct fb_var_screeninfo *var, | ||
| 205 | struct fb_info *info) | ||
| 206 | { | ||
| 207 | unsigned pixlen = info->fix.line_length / info->var.xres_virtual; | ||
| 208 | unsigned off = pixlen * var->xoffset | ||
| 209 | + info->fix.line_length * var->yoffset; | ||
| 210 | struct vt8500lcd_info *fbi = to_vt8500lcd_info(info); | ||
| 211 | |||
| 212 | writel((1 << 31) | ||
| 213 | | (((var->xres_virtual - var->xres) * pixlen / 4) << 20) | ||
| 214 | | (off >> 2), fbi->regbase + 0x20); | ||
| 215 | return 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | static struct fb_ops vt8500lcd_ops = { | ||
| 219 | .owner = THIS_MODULE, | ||
| 220 | .fb_set_par = vt8500lcd_set_par, | ||
| 221 | .fb_setcolreg = vt8500lcd_setcolreg, | ||
| 222 | .fb_fillrect = wmt_ge_fillrect, | ||
| 223 | .fb_copyarea = wmt_ge_copyarea, | ||
| 224 | .fb_imageblit = sys_imageblit, | ||
| 225 | .fb_sync = wmt_ge_sync, | ||
| 226 | .fb_ioctl = vt8500lcd_ioctl, | ||
| 227 | .fb_pan_display = vt8500lcd_pan_display, | ||
| 228 | }; | ||
| 229 | |||
| 230 | static irqreturn_t vt8500lcd_handle_irq(int irq, void *dev_id) | ||
| 231 | { | ||
| 232 | struct vt8500lcd_info *fbi = dev_id; | ||
| 233 | |||
| 234 | if (readl(fbi->regbase + 0x38) & (1 << 3)) | ||
| 235 | wake_up_interruptible(&fbi->wait); | ||
| 236 | |||
| 237 | writel(0xffffffff, fbi->regbase + 0x38); | ||
| 238 | return IRQ_HANDLED; | ||
| 239 | } | ||
| 240 | |||
| 241 | static int __devinit vt8500lcd_probe(struct platform_device *pdev) | ||
| 242 | { | ||
| 243 | struct vt8500lcd_info *fbi; | ||
| 244 | struct resource *res; | ||
| 245 | struct vt8500fb_platform_data *pdata = pdev->dev.platform_data; | ||
| 246 | void *addr; | ||
| 247 | int irq, ret; | ||
| 248 | |||
| 249 | ret = -ENOMEM; | ||
| 250 | fbi = NULL; | ||
| 251 | |||
| 252 | fbi = kzalloc(sizeof(struct vt8500lcd_info) + sizeof(u32) * 16, | ||
| 253 | GFP_KERNEL); | ||
| 254 | if (!fbi) { | ||
| 255 | dev_err(&pdev->dev, "Failed to initialize framebuffer device\n"); | ||
| 256 | ret = -ENOMEM; | ||
| 257 | goto failed; | ||
| 258 | } | ||
| 259 | |||
| 260 | strcpy(fbi->fb.fix.id, "VT8500 LCD"); | ||
| 261 | |||
| 262 | fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; | ||
| 263 | fbi->fb.fix.xpanstep = 0; | ||
| 264 | fbi->fb.fix.ypanstep = 1; | ||
| 265 | fbi->fb.fix.ywrapstep = 0; | ||
| 266 | fbi->fb.fix.accel = FB_ACCEL_NONE; | ||
| 267 | |||
| 268 | fbi->fb.var.nonstd = 0; | ||
| 269 | fbi->fb.var.activate = FB_ACTIVATE_NOW; | ||
| 270 | fbi->fb.var.height = -1; | ||
| 271 | fbi->fb.var.width = -1; | ||
| 272 | fbi->fb.var.vmode = FB_VMODE_NONINTERLACED; | ||
| 273 | |||
| 274 | fbi->fb.fbops = &vt8500lcd_ops; | ||
| 275 | fbi->fb.flags = FBINFO_DEFAULT | ||
| 276 | | FBINFO_HWACCEL_COPYAREA | ||
| 277 | | FBINFO_HWACCEL_FILLRECT | ||
| 278 | | FBINFO_HWACCEL_YPAN | ||
| 279 | | FBINFO_VIRTFB | ||
| 280 | | FBINFO_PARTIAL_PAN_OK; | ||
| 281 | fbi->fb.node = -1; | ||
| 282 | |||
| 283 | addr = fbi; | ||
| 284 | addr = addr + sizeof(struct vt8500lcd_info); | ||
| 285 | fbi->fb.pseudo_palette = addr; | ||
| 286 | |||
| 287 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 288 | if (res == NULL) { | ||
| 289 | dev_err(&pdev->dev, "no I/O memory resource defined\n"); | ||
| 290 | ret = -ENODEV; | ||
| 291 | goto failed_fbi; | ||
| 292 | } | ||
| 293 | |||
| 294 | res = request_mem_region(res->start, resource_size(res), "vt8500lcd"); | ||
| 295 | if (res == NULL) { | ||
| 296 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
| 297 | ret = -EBUSY; | ||
| 298 | goto failed_fbi; | ||
| 299 | } | ||
| 300 | |||
| 301 | fbi->regbase = ioremap(res->start, resource_size(res)); | ||
| 302 | if (fbi->regbase == NULL) { | ||
| 303 | dev_err(&pdev->dev, "failed to map I/O memory\n"); | ||
| 304 | ret = -EBUSY; | ||
| 305 | goto failed_free_res; | ||
| 306 | } | ||
| 307 | |||
| 308 | fbi->fb.fix.smem_start = pdata->video_mem_phys; | ||
| 309 | fbi->fb.fix.smem_len = pdata->video_mem_len; | ||
| 310 | fbi->fb.screen_base = pdata->video_mem_virt; | ||
| 311 | |||
| 312 | fbi->palette_size = PAGE_ALIGN(512); | ||
| 313 | fbi->palette_cpu = dma_alloc_coherent(&pdev->dev, | ||
| 314 | fbi->palette_size, | ||
| 315 | &fbi->palette_phys, | ||
| 316 | GFP_KERNEL); | ||
| 317 | if (fbi->palette_cpu == NULL) { | ||
| 318 | dev_err(&pdev->dev, "Failed to allocate palette buffer\n"); | ||
| 319 | ret = -ENOMEM; | ||
| 320 | goto failed_free_io; | ||
| 321 | } | ||
| 322 | |||
| 323 | irq = platform_get_irq(pdev, 0); | ||
| 324 | if (irq < 0) { | ||
| 325 | dev_err(&pdev->dev, "no IRQ defined\n"); | ||
| 326 | ret = -ENODEV; | ||
| 327 | goto failed_free_palette; | ||
| 328 | } | ||
| 329 | |||
| 330 | ret = request_irq(irq, vt8500lcd_handle_irq, IRQF_DISABLED, "LCD", fbi); | ||
| 331 | if (ret) { | ||
| 332 | dev_err(&pdev->dev, "request_irq failed: %d\n", ret); | ||
| 333 | ret = -EBUSY; | ||
| 334 | goto failed_free_palette; | ||
| 335 | } | ||
| 336 | |||
| 337 | init_waitqueue_head(&fbi->wait); | ||
| 338 | |||
| 339 | if (fb_alloc_cmap(&fbi->fb.cmap, 256, 0) < 0) { | ||
| 340 | dev_err(&pdev->dev, "Failed to allocate color map\n"); | ||
| 341 | ret = -ENOMEM; | ||
| 342 | goto failed_free_irq; | ||
| 343 | } | ||
| 344 | |||
| 345 | fb_videomode_to_var(&fbi->fb.var, &pdata->mode); | ||
| 346 | fbi->fb.var.bits_per_pixel = pdata->bpp; | ||
| 347 | fbi->fb.var.xres_virtual = pdata->xres_virtual; | ||
| 348 | fbi->fb.var.yres_virtual = pdata->yres_virtual; | ||
| 349 | |||
| 350 | ret = vt8500lcd_set_par(&fbi->fb); | ||
| 351 | if (ret) { | ||
| 352 | dev_err(&pdev->dev, "Failed to set parameters\n"); | ||
| 353 | goto failed_free_cmap; | ||
| 354 | } | ||
| 355 | |||
| 356 | writel(fbi->fb.fix.smem_start >> 22, fbi->regbase + 0x1c); | ||
| 357 | writel((fbi->palette_phys & 0xfffffe00) | 1, fbi->regbase + 0x18); | ||
| 358 | |||
| 359 | platform_set_drvdata(pdev, fbi); | ||
| 360 | |||
| 361 | ret = register_framebuffer(&fbi->fb); | ||
| 362 | if (ret < 0) { | ||
| 363 | dev_err(&pdev->dev, | ||
| 364 | "Failed to register framebuffer device: %d\n", ret); | ||
| 365 | goto failed_free_cmap; | ||
| 366 | } | ||
| 367 | |||
| 368 | /* | ||
| 369 | * Ok, now enable the LCD controller | ||
| 370 | */ | ||
| 371 | writel(readl(fbi->regbase) | 1, fbi->regbase); | ||
| 372 | |||
| 373 | return 0; | ||
| 374 | |||
| 375 | failed_free_cmap: | ||
| 376 | if (fbi->fb.cmap.len) | ||
| 377 | fb_dealloc_cmap(&fbi->fb.cmap); | ||
| 378 | failed_free_irq: | ||
| 379 | free_irq(irq, fbi); | ||
| 380 | failed_free_palette: | ||
| 381 | dma_free_coherent(&pdev->dev, fbi->palette_size, | ||
| 382 | fbi->palette_cpu, fbi->palette_phys); | ||
| 383 | failed_free_io: | ||
| 384 | iounmap(fbi->regbase); | ||
| 385 | failed_free_res: | ||
| 386 | release_mem_region(res->start, resource_size(res)); | ||
| 387 | failed_fbi: | ||
| 388 | platform_set_drvdata(pdev, NULL); | ||
| 389 | kfree(fbi); | ||
| 390 | failed: | ||
| 391 | return ret; | ||
| 392 | } | ||
| 393 | |||
| 394 | static int __devexit vt8500lcd_remove(struct platform_device *pdev) | ||
| 395 | { | ||
| 396 | struct vt8500lcd_info *fbi = platform_get_drvdata(pdev); | ||
| 397 | struct resource *res; | ||
| 398 | int irq; | ||
| 399 | |||
| 400 | unregister_framebuffer(&fbi->fb); | ||
| 401 | |||
| 402 | writel(0, fbi->regbase); | ||
| 403 | |||
| 404 | if (fbi->fb.cmap.len) | ||
| 405 | fb_dealloc_cmap(&fbi->fb.cmap); | ||
| 406 | |||
| 407 | irq = platform_get_irq(pdev, 0); | ||
| 408 | free_irq(irq, fbi); | ||
| 409 | |||
| 410 | dma_free_coherent(&pdev->dev, fbi->palette_size, | ||
| 411 | fbi->palette_cpu, fbi->palette_phys); | ||
| 412 | |||
| 413 | iounmap(fbi->regbase); | ||
| 414 | |||
| 415 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 416 | release_mem_region(res->start, resource_size(res)); | ||
| 417 | |||
| 418 | kfree(fbi); | ||
| 419 | |||
| 420 | return 0; | ||
| 421 | } | ||
| 422 | |||
| 423 | static struct platform_driver vt8500lcd_driver = { | ||
| 424 | .probe = vt8500lcd_probe, | ||
| 425 | .remove = __devexit_p(vt8500lcd_remove), | ||
| 426 | .driver = { | ||
| 427 | .owner = THIS_MODULE, | ||
| 428 | .name = "vt8500-lcd", | ||
| 429 | }, | ||
| 430 | }; | ||
| 431 | |||
| 432 | static int __init vt8500lcd_init(void) | ||
| 433 | { | ||
| 434 | return platform_driver_register(&vt8500lcd_driver); | ||
| 435 | } | ||
| 436 | |||
| 437 | static void __exit vt8500lcd_exit(void) | ||
| 438 | { | ||
| 439 | platform_driver_unregister(&vt8500lcd_driver); | ||
| 440 | } | ||
| 441 | |||
| 442 | module_init(vt8500lcd_init); | ||
| 443 | module_exit(vt8500lcd_exit); | ||
| 444 | |||
| 445 | MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>"); | ||
| 446 | MODULE_DESCRIPTION("LCD controller driver for VIA VT8500"); | ||
| 447 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/vt8500lcdfb.h b/drivers/video/vt8500lcdfb.h new file mode 100644 index 000000000000..36ca3ca09d83 --- /dev/null +++ b/drivers/video/vt8500lcdfb.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | /* | ||
| 2 | * linux/drivers/video/vt8500lcdfb.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | */ | ||
| 15 | |||
| 16 | struct vt8500lcd_info { | ||
| 17 | struct fb_info fb; | ||
| 18 | void __iomem *regbase; | ||
| 19 | void __iomem *palette_cpu; | ||
| 20 | dma_addr_t palette_phys; | ||
| 21 | size_t palette_size; | ||
| 22 | wait_queue_head_t wait; | ||
| 23 | }; | ||
| 24 | |||
| 25 | static int bpp_values[] = { | ||
| 26 | 1, | ||
| 27 | 2, | ||
| 28 | 4, | ||
| 29 | 8, | ||
| 30 | 12, | ||
| 31 | 16, | ||
| 32 | 18, | ||
| 33 | 24, | ||
| 34 | }; | ||
diff --git a/drivers/video/wm8505fb.c b/drivers/video/wm8505fb.c new file mode 100644 index 000000000000..96e34a569169 --- /dev/null +++ b/drivers/video/wm8505fb.c | |||
| @@ -0,0 +1,422 @@ | |||
| 1 | /* | ||
| 2 | * WonderMedia WM8505 Frame Buffer device driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Ed Spiridonov <edo.rus@gmail.com> | ||
| 5 | * Based on vt8500lcdfb.c | ||
| 6 | * | ||
| 7 | * This software is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2, as published by the Free Software Foundation, and | ||
| 9 | * may be copied, distributed, and modified under those terms. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/errno.h> | ||
| 20 | #include <linux/string.h> | ||
| 21 | #include <linux/mm.h> | ||
| 22 | #include <linux/slab.h> | ||
| 23 | #include <linux/delay.h> | ||
| 24 | #include <linux/fb.h> | ||
| 25 | #include <linux/init.h> | ||
| 26 | #include <linux/interrupt.h> | ||
| 27 | #include <linux/io.h> | ||
| 28 | #include <linux/dma-mapping.h> | ||
| 29 | #include <linux/platform_device.h> | ||
| 30 | #include <linux/wait.h> | ||
| 31 | |||
| 32 | #include <mach/vt8500fb.h> | ||
| 33 | |||
| 34 | #include "wm8505fb_regs.h" | ||
| 35 | #include "wmt_ge_rops.h" | ||
| 36 | |||
| 37 | #define DRIVER_NAME "wm8505-fb" | ||
| 38 | |||
| 39 | #define to_wm8505fb_info(__info) container_of(__info, \ | ||
| 40 | struct wm8505fb_info, fb) | ||
| 41 | struct wm8505fb_info { | ||
| 42 | struct fb_info fb; | ||
| 43 | void __iomem *regbase; | ||
| 44 | unsigned int contrast; | ||
| 45 | }; | ||
| 46 | |||
| 47 | |||
| 48 | static int wm8505fb_init_hw(struct fb_info *info) | ||
| 49 | { | ||
| 50 | struct wm8505fb_info *fbi = to_wm8505fb_info(info); | ||
| 51 | |||
| 52 | int i; | ||
| 53 | |||
| 54 | /* I know the purpose only of few registers, so clear unknown */ | ||
| 55 | for (i = 0; i < 0x200; i += 4) | ||
| 56 | writel(0, fbi->regbase + i); | ||
| 57 | |||
| 58 | /* Set frame buffer address */ | ||
| 59 | writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR); | ||
| 60 | writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR1); | ||
| 61 | |||
| 62 | /* Set in-memory picture format to RGB 32bpp */ | ||
| 63 | writel(0x1c, fbi->regbase + WMT_GOVR_COLORSPACE); | ||
| 64 | writel(1, fbi->regbase + WMT_GOVR_COLORSPACE1); | ||
| 65 | |||
| 66 | /* Virtual buffer size */ | ||
| 67 | writel(info->var.xres, fbi->regbase + WMT_GOVR_XRES); | ||
| 68 | writel(info->var.xres_virtual, fbi->regbase + WMT_GOVR_XRES_VIRTUAL); | ||
| 69 | |||
| 70 | /* black magic ;) */ | ||
| 71 | writel(0xf, fbi->regbase + WMT_GOVR_FHI); | ||
| 72 | writel(4, fbi->regbase + WMT_GOVR_DVO_SET); | ||
| 73 | writel(1, fbi->regbase + WMT_GOVR_MIF_ENABLE); | ||
| 74 | writel(1, fbi->regbase + WMT_GOVR_REG_UPDATE); | ||
| 75 | |||
| 76 | return 0; | ||
| 77 | } | ||
| 78 | |||
| 79 | static int wm8505fb_set_timing(struct fb_info *info) | ||
| 80 | { | ||
| 81 | struct wm8505fb_info *fbi = to_wm8505fb_info(info); | ||
| 82 | |||
| 83 | int h_start = info->var.left_margin; | ||
| 84 | int h_end = h_start + info->var.xres; | ||
| 85 | int h_all = h_end + info->var.right_margin; | ||
| 86 | int h_sync = info->var.hsync_len; | ||
| 87 | |||
| 88 | int v_start = info->var.upper_margin; | ||
| 89 | int v_end = v_start + info->var.yres; | ||
| 90 | int v_all = v_end + info->var.lower_margin; | ||
| 91 | int v_sync = info->var.vsync_len; | ||
| 92 | |||
| 93 | writel(0, fbi->regbase + WMT_GOVR_TG); | ||
| 94 | |||
| 95 | writel(h_start, fbi->regbase + WMT_GOVR_TIMING_H_START); | ||
| 96 | writel(h_end, fbi->regbase + WMT_GOVR_TIMING_H_END); | ||
| 97 | writel(h_all, fbi->regbase + WMT_GOVR_TIMING_H_ALL); | ||
| 98 | writel(h_sync, fbi->regbase + WMT_GOVR_TIMING_H_SYNC); | ||
| 99 | |||
| 100 | writel(v_start, fbi->regbase + WMT_GOVR_TIMING_V_START); | ||
| 101 | writel(v_end, fbi->regbase + WMT_GOVR_TIMING_V_END); | ||
| 102 | writel(v_all, fbi->regbase + WMT_GOVR_TIMING_V_ALL); | ||
| 103 | writel(v_sync, fbi->regbase + WMT_GOVR_TIMING_V_SYNC); | ||
| 104 | |||
| 105 | writel(1, fbi->regbase + WMT_GOVR_TG); | ||
| 106 | |||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | |||
| 111 | static int wm8505fb_set_par(struct fb_info *info) | ||
| 112 | { | ||
| 113 | struct wm8505fb_info *fbi = to_wm8505fb_info(info); | ||
| 114 | |||
| 115 | if (!fbi) | ||
| 116 | return -EINVAL; | ||
| 117 | |||
| 118 | if (info->var.bits_per_pixel == 32) { | ||
| 119 | info->var.red.offset = 16; | ||
| 120 | info->var.red.length = 8; | ||
| 121 | info->var.red.msb_right = 0; | ||
| 122 | info->var.green.offset = 8; | ||
| 123 | info->var.green.length = 8; | ||
| 124 | info->var.green.msb_right = 0; | ||
| 125 | info->var.blue.offset = 0; | ||
| 126 | info->var.blue.length = 8; | ||
| 127 | info->var.blue.msb_right = 0; | ||
| 128 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
| 129 | info->fix.line_length = info->var.xres_virtual << 2; | ||
| 130 | } | ||
| 131 | |||
| 132 | wm8505fb_set_timing(info); | ||
| 133 | |||
| 134 | writel(fbi->contrast<<16 | fbi->contrast<<8 | fbi->contrast, | ||
| 135 | fbi->regbase + WMT_GOVR_CONTRAST); | ||
| 136 | |||
| 137 | return 0; | ||
| 138 | } | ||
| 139 | |||
| 140 | static ssize_t contrast_show(struct device *dev, | ||
| 141 | struct device_attribute *attr, char *buf) | ||
| 142 | { | ||
| 143 | struct fb_info *info = dev_get_drvdata(dev); | ||
| 144 | struct wm8505fb_info *fbi = to_wm8505fb_info(info); | ||
| 145 | |||
| 146 | return sprintf(buf, "%d\n", fbi->contrast); | ||
| 147 | } | ||
| 148 | |||
| 149 | static ssize_t contrast_store(struct device *dev, | ||
| 150 | struct device_attribute *attr, | ||
| 151 | const char *buf, size_t count) | ||
| 152 | { | ||
| 153 | struct fb_info *info = dev_get_drvdata(dev); | ||
| 154 | struct wm8505fb_info *fbi = to_wm8505fb_info(info); | ||
| 155 | unsigned long tmp; | ||
| 156 | |||
| 157 | if (strict_strtoul(buf, 10, &tmp) || (tmp > 0xff)) | ||
| 158 | return -EINVAL; | ||
| 159 | fbi->contrast = tmp; | ||
| 160 | |||
| 161 | wm8505fb_set_par(info); | ||
| 162 | |||
| 163 | return count; | ||
| 164 | } | ||
| 165 | |||
| 166 | static DEVICE_ATTR(contrast, 0644, contrast_show, contrast_store); | ||
| 167 | |||
| 168 | static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf) | ||
| 169 | { | ||
| 170 | chan &= 0xffff; | ||
| 171 | chan >>= 16 - bf->length; | ||
| 172 | return chan << bf->offset; | ||
| 173 | } | ||
| 174 | |||
| 175 | static int wm8505fb_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
| 176 | unsigned blue, unsigned transp, | ||
| 177 | struct fb_info *info) { | ||
| 178 | struct wm8505fb_info *fbi = to_wm8505fb_info(info); | ||
| 179 | int ret = 1; | ||
| 180 | unsigned int val; | ||
| 181 | if (regno >= 256) | ||
| 182 | return -EINVAL; | ||
| 183 | |||
| 184 | if (info->var.grayscale) | ||
| 185 | red = green = blue = | ||
| 186 | (19595 * red + 38470 * green + 7471 * blue) >> 16; | ||
| 187 | |||
| 188 | switch (fbi->fb.fix.visual) { | ||
| 189 | case FB_VISUAL_TRUECOLOR: | ||
| 190 | if (regno < 16) { | ||
| 191 | u32 *pal = info->pseudo_palette; | ||
| 192 | |||
| 193 | val = chan_to_field(red, &fbi->fb.var.red); | ||
| 194 | val |= chan_to_field(green, &fbi->fb.var.green); | ||
| 195 | val |= chan_to_field(blue, &fbi->fb.var.blue); | ||
| 196 | |||
| 197 | pal[regno] = val; | ||
| 198 | ret = 0; | ||
| 199 | } | ||
| 200 | break; | ||
| 201 | } | ||
| 202 | |||
| 203 | return ret; | ||
| 204 | } | ||
| 205 | |||
| 206 | static int wm8505fb_pan_display(struct fb_var_screeninfo *var, | ||
| 207 | struct fb_info *info) | ||
| 208 | { | ||
| 209 | struct wm8505fb_info *fbi = to_wm8505fb_info(info); | ||
| 210 | |||
| 211 | writel(var->xoffset, fbi->regbase + WMT_GOVR_XPAN); | ||
| 212 | writel(var->yoffset, fbi->regbase + WMT_GOVR_YPAN); | ||
| 213 | return 0; | ||
| 214 | } | ||
| 215 | |||
| 216 | static int wm8505fb_blank(int blank, struct fb_info *info) | ||
| 217 | { | ||
| 218 | struct wm8505fb_info *fbi = to_wm8505fb_info(info); | ||
| 219 | |||
| 220 | switch (blank) { | ||
| 221 | case FB_BLANK_UNBLANK: | ||
| 222 | wm8505fb_set_timing(info); | ||
| 223 | break; | ||
| 224 | default: | ||
| 225 | writel(0, fbi->regbase + WMT_GOVR_TIMING_V_SYNC); | ||
| 226 | break; | ||
| 227 | } | ||
| 228 | |||
| 229 | return 0; | ||
| 230 | } | ||
| 231 | |||
| 232 | static struct fb_ops wm8505fb_ops = { | ||
| 233 | .owner = THIS_MODULE, | ||
| 234 | .fb_set_par = wm8505fb_set_par, | ||
| 235 | .fb_setcolreg = wm8505fb_setcolreg, | ||
| 236 | .fb_fillrect = wmt_ge_fillrect, | ||
| 237 | .fb_copyarea = wmt_ge_copyarea, | ||
| 238 | .fb_imageblit = sys_imageblit, | ||
| 239 | .fb_sync = wmt_ge_sync, | ||
| 240 | .fb_pan_display = wm8505fb_pan_display, | ||
| 241 | .fb_blank = wm8505fb_blank, | ||
| 242 | }; | ||
| 243 | |||
| 244 | static int __devinit wm8505fb_probe(struct platform_device *pdev) | ||
| 245 | { | ||
| 246 | struct wm8505fb_info *fbi; | ||
| 247 | struct resource *res; | ||
| 248 | void *addr; | ||
| 249 | struct vt8500fb_platform_data *pdata; | ||
| 250 | int ret; | ||
| 251 | |||
| 252 | pdata = pdev->dev.platform_data; | ||
| 253 | |||
| 254 | ret = -ENOMEM; | ||
| 255 | fbi = NULL; | ||
| 256 | |||
| 257 | fbi = kzalloc(sizeof(struct wm8505fb_info) + sizeof(u32) * 16, | ||
| 258 | GFP_KERNEL); | ||
| 259 | if (!fbi) { | ||
| 260 | dev_err(&pdev->dev, "Failed to initialize framebuffer device\n"); | ||
| 261 | ret = -ENOMEM; | ||
| 262 | goto failed; | ||
| 263 | } | ||
| 264 | |||
| 265 | strcpy(fbi->fb.fix.id, DRIVER_NAME); | ||
| 266 | |||
| 267 | fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; | ||
| 268 | fbi->fb.fix.xpanstep = 1; | ||
| 269 | fbi->fb.fix.ypanstep = 1; | ||
| 270 | fbi->fb.fix.ywrapstep = 0; | ||
| 271 | fbi->fb.fix.accel = FB_ACCEL_NONE; | ||
| 272 | |||
| 273 | fbi->fb.fbops = &wm8505fb_ops; | ||
| 274 | fbi->fb.flags = FBINFO_DEFAULT | ||
| 275 | | FBINFO_HWACCEL_COPYAREA | ||
| 276 | | FBINFO_HWACCEL_FILLRECT | ||
| 277 | | FBINFO_HWACCEL_XPAN | ||
| 278 | | FBINFO_HWACCEL_YPAN | ||
| 279 | | FBINFO_VIRTFB | ||
| 280 | | FBINFO_PARTIAL_PAN_OK; | ||
| 281 | fbi->fb.node = -1; | ||
| 282 | |||
| 283 | addr = fbi; | ||
| 284 | addr = addr + sizeof(struct wm8505fb_info); | ||
| 285 | fbi->fb.pseudo_palette = addr; | ||
| 286 | |||
| 287 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 288 | if (res == NULL) { | ||
| 289 | dev_err(&pdev->dev, "no I/O memory resource defined\n"); | ||
| 290 | ret = -ENODEV; | ||
| 291 | goto failed_fbi; | ||
| 292 | } | ||
| 293 | |||
| 294 | res = request_mem_region(res->start, resource_size(res), DRIVER_NAME); | ||
| 295 | if (res == NULL) { | ||
| 296 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
| 297 | ret = -EBUSY; | ||
| 298 | goto failed_fbi; | ||
| 299 | } | ||
| 300 | |||
| 301 | fbi->regbase = ioremap(res->start, resource_size(res)); | ||
| 302 | if (fbi->regbase == NULL) { | ||
| 303 | dev_err(&pdev->dev, "failed to map I/O memory\n"); | ||
| 304 | ret = -EBUSY; | ||
| 305 | goto failed_free_res; | ||
| 306 | } | ||
| 307 | |||
| 308 | fb_videomode_to_var(&fbi->fb.var, &pdata->mode); | ||
| 309 | |||
| 310 | fbi->fb.var.nonstd = 0; | ||
| 311 | fbi->fb.var.activate = FB_ACTIVATE_NOW; | ||
| 312 | |||
| 313 | fbi->fb.var.height = -1; | ||
| 314 | fbi->fb.var.width = -1; | ||
| 315 | fbi->fb.var.xres_virtual = pdata->xres_virtual; | ||
| 316 | fbi->fb.var.yres_virtual = pdata->yres_virtual; | ||
| 317 | fbi->fb.var.bits_per_pixel = pdata->bpp; | ||
| 318 | |||
| 319 | fbi->fb.fix.smem_start = pdata->video_mem_phys; | ||
| 320 | fbi->fb.fix.smem_len = pdata->video_mem_len; | ||
| 321 | fbi->fb.screen_base = pdata->video_mem_virt; | ||
| 322 | fbi->fb.screen_size = pdata->video_mem_len; | ||
| 323 | |||
| 324 | if (fb_alloc_cmap(&fbi->fb.cmap, 256, 0) < 0) { | ||
| 325 | dev_err(&pdev->dev, "Failed to allocate color map\n"); | ||
| 326 | ret = -ENOMEM; | ||
| 327 | goto failed_free_io; | ||
| 328 | } | ||
| 329 | |||
| 330 | wm8505fb_init_hw(&fbi->fb); | ||
| 331 | |||
| 332 | fbi->contrast = 0x80; | ||
| 333 | ret = wm8505fb_set_par(&fbi->fb); | ||
| 334 | if (ret) { | ||
| 335 | dev_err(&pdev->dev, "Failed to set parameters\n"); | ||
| 336 | goto failed_free_cmap; | ||
| 337 | } | ||
| 338 | |||
| 339 | platform_set_drvdata(pdev, fbi); | ||
| 340 | |||
| 341 | ret = register_framebuffer(&fbi->fb); | ||
| 342 | if (ret < 0) { | ||
| 343 | dev_err(&pdev->dev, | ||
| 344 | "Failed to register framebuffer device: %d\n", ret); | ||
| 345 | goto failed_free_cmap; | ||
| 346 | } | ||
| 347 | |||
| 348 | ret = device_create_file(&pdev->dev, &dev_attr_contrast); | ||
| 349 | if (ret < 0) { | ||
| 350 | printk(KERN_WARNING "fb%d: failed to register attributes (%d)\n", | ||
| 351 | fbi->fb.node, ret); | ||
| 352 | } | ||
| 353 | |||
| 354 | printk(KERN_INFO "fb%d: %s frame buffer at 0x%lx-0x%lx\n", | ||
| 355 | fbi->fb.node, fbi->fb.fix.id, fbi->fb.fix.smem_start, | ||
| 356 | fbi->fb.fix.smem_start + fbi->fb.fix.smem_len - 1); | ||
| 357 | |||
| 358 | return 0; | ||
| 359 | |||
| 360 | failed_free_cmap: | ||
| 361 | if (fbi->fb.cmap.len) | ||
| 362 | fb_dealloc_cmap(&fbi->fb.cmap); | ||
| 363 | failed_free_io: | ||
| 364 | iounmap(fbi->regbase); | ||
| 365 | failed_free_res: | ||
| 366 | release_mem_region(res->start, resource_size(res)); | ||
| 367 | failed_fbi: | ||
| 368 | platform_set_drvdata(pdev, NULL); | ||
| 369 | kfree(fbi); | ||
| 370 | failed: | ||
| 371 | return ret; | ||
| 372 | } | ||
| 373 | |||
| 374 | static int __devexit wm8505fb_remove(struct platform_device *pdev) | ||
| 375 | { | ||
| 376 | struct wm8505fb_info *fbi = platform_get_drvdata(pdev); | ||
| 377 | struct resource *res; | ||
| 378 | |||
| 379 | device_remove_file(&pdev->dev, &dev_attr_contrast); | ||
| 380 | |||
| 381 | unregister_framebuffer(&fbi->fb); | ||
| 382 | |||
| 383 | writel(0, fbi->regbase); | ||
| 384 | |||
| 385 | if (fbi->fb.cmap.len) | ||
| 386 | fb_dealloc_cmap(&fbi->fb.cmap); | ||
| 387 | |||
| 388 | iounmap(fbi->regbase); | ||
| 389 | |||
| 390 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 391 | release_mem_region(res->start, resource_size(res)); | ||
| 392 | |||
| 393 | kfree(fbi); | ||
| 394 | |||
| 395 | return 0; | ||
| 396 | } | ||
| 397 | |||
| 398 | static struct platform_driver wm8505fb_driver = { | ||
| 399 | .probe = wm8505fb_probe, | ||
| 400 | .remove = __devexit_p(wm8505fb_remove), | ||
| 401 | .driver = { | ||
| 402 | .owner = THIS_MODULE, | ||
| 403 | .name = DRIVER_NAME, | ||
| 404 | }, | ||
| 405 | }; | ||
| 406 | |||
| 407 | static int __init wm8505fb_init(void) | ||
| 408 | { | ||
| 409 | return platform_driver_register(&wm8505fb_driver); | ||
| 410 | } | ||
| 411 | |||
| 412 | static void __exit wm8505fb_exit(void) | ||
| 413 | { | ||
| 414 | platform_driver_unregister(&wm8505fb_driver); | ||
| 415 | } | ||
| 416 | |||
| 417 | module_init(wm8505fb_init); | ||
| 418 | module_exit(wm8505fb_exit); | ||
| 419 | |||
| 420 | MODULE_AUTHOR("Ed Spiridonov <edo.rus@gmail.com>"); | ||
| 421 | MODULE_DESCRIPTION("Framebuffer driver for WMT WM8505"); | ||
| 422 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/wm8505fb_regs.h b/drivers/video/wm8505fb_regs.h new file mode 100644 index 000000000000..4dd41668c6d1 --- /dev/null +++ b/drivers/video/wm8505fb_regs.h | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * GOVR registers list for WM8505 chips | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Ed Spiridonov <edo.rus@gmail.com> | ||
| 5 | * Based on VIA/WonderMedia wm8510-govrh-reg.h | ||
| 6 | * http://github.com/projectgus/kernel_wm8505/blob/wm8505_2.6.29/ | ||
| 7 | * drivers/video/wmt/register/wm8510/wm8510-govrh-reg.h | ||
| 8 | * | ||
| 9 | * This software is licensed under the terms of the GNU General Public | ||
| 10 | * License version 2, as published by the Free Software Foundation, and | ||
| 11 | * may be copied, distributed, and modified under those terms. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef _WM8505FB_REGS_H | ||
| 20 | #define _WM8505FB_REGS_H | ||
| 21 | |||
| 22 | /* | ||
| 23 | * Color space select register, default value 0x1c | ||
| 24 | * BIT0 GOVRH_DVO_YUV2RGB_ENABLE | ||
| 25 | * BIT1 GOVRH_VGA_YUV2RGB_ENABLE | ||
| 26 | * BIT2 GOVRH_RGB_MODE | ||
| 27 | * BIT3 GOVRH_DAC_CLKINV | ||
| 28 | * BIT4 GOVRH_BLANK_ZERO | ||
| 29 | */ | ||
| 30 | #define WMT_GOVR_COLORSPACE 0x1e4 | ||
| 31 | /* | ||
| 32 | * Another colorspace select register, default value 1 | ||
| 33 | * BIT0 GOVRH_DVO_RGB | ||
| 34 | * BIT1 GOVRH_DVO_YUV422 | ||
| 35 | */ | ||
| 36 | #define WMT_GOVR_COLORSPACE1 0x30 | ||
| 37 | |||
| 38 | #define WMT_GOVR_CONTRAST 0x1b8 | ||
| 39 | #define WMT_GOVR_BRGHTNESS 0x1bc /* incompatible with RGB? */ | ||
| 40 | |||
| 41 | /* Framubeffer address */ | ||
| 42 | #define WMT_GOVR_FBADDR 0x90 | ||
| 43 | #define WMT_GOVR_FBADDR1 0x94 /* UV offset in YUV mode */ | ||
| 44 | |||
| 45 | /* Offset of visible window */ | ||
| 46 | #define WMT_GOVR_XPAN 0xa4 | ||
| 47 | #define WMT_GOVR_YPAN 0xa0 | ||
| 48 | |||
| 49 | #define WMT_GOVR_XRES 0x98 | ||
| 50 | #define WMT_GOVR_XRES_VIRTUAL 0x9c | ||
| 51 | |||
| 52 | #define WMT_GOVR_MIF_ENABLE 0x80 | ||
| 53 | #define WMT_GOVR_FHI 0xa8 | ||
| 54 | #define WMT_GOVR_REG_UPDATE 0xe4 | ||
| 55 | |||
| 56 | /* | ||
| 57 | * BIT0 GOVRH_DVO_OUTWIDTH | ||
| 58 | * BIT1 GOVRH_DVO_SYNC_POLAR | ||
| 59 | * BIT2 GOVRH_DVO_ENABLE | ||
| 60 | */ | ||
| 61 | #define WMT_GOVR_DVO_SET 0x148 | ||
| 62 | |||
| 63 | /* Timing generator? */ | ||
| 64 | #define WMT_GOVR_TG 0x100 | ||
| 65 | |||
| 66 | /* Timings */ | ||
| 67 | #define WMT_GOVR_TIMING_H_ALL 0x108 | ||
| 68 | #define WMT_GOVR_TIMING_V_ALL 0x10c | ||
| 69 | #define WMT_GOVR_TIMING_V_START 0x110 | ||
| 70 | #define WMT_GOVR_TIMING_V_END 0x114 | ||
| 71 | #define WMT_GOVR_TIMING_H_START 0x118 | ||
| 72 | #define WMT_GOVR_TIMING_H_END 0x11c | ||
| 73 | #define WMT_GOVR_TIMING_V_SYNC 0x128 | ||
| 74 | #define WMT_GOVR_TIMING_H_SYNC 0x12c | ||
| 75 | |||
| 76 | #endif /* _WM8505FB_REGS_H */ | ||
diff --git a/drivers/video/wmt_ge_rops.c b/drivers/video/wmt_ge_rops.c new file mode 100644 index 000000000000..45832b7ef7d2 --- /dev/null +++ b/drivers/video/wmt_ge_rops.c | |||
| @@ -0,0 +1,186 @@ | |||
| 1 | /* | ||
| 2 | * linux/drivers/video/wmt_ge_rops.c | ||
| 3 | * | ||
| 4 | * Accelerators for raster operations using WonderMedia Graphics Engine | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> | ||
| 7 | * | ||
| 8 | * This software is licensed under the terms of the GNU General Public | ||
| 9 | * License version 2, as published by the Free Software Foundation, and | ||
| 10 | * may be copied, distributed, and modified under those terms. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/fb.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include "fb_draw.h" | ||
| 22 | |||
| 23 | #define GE_COMMAND_OFF 0x00 | ||
| 24 | #define GE_DEPTH_OFF 0x04 | ||
| 25 | #define GE_HIGHCOLOR_OFF 0x08 | ||
| 26 | #define GE_ROPCODE_OFF 0x14 | ||
| 27 | #define GE_FIRE_OFF 0x18 | ||
| 28 | #define GE_SRCBASE_OFF 0x20 | ||
| 29 | #define GE_SRCDISPW_OFF 0x24 | ||
| 30 | #define GE_SRCDISPH_OFF 0x28 | ||
| 31 | #define GE_SRCAREAX_OFF 0x2c | ||
| 32 | #define GE_SRCAREAY_OFF 0x30 | ||
| 33 | #define GE_SRCAREAW_OFF 0x34 | ||
| 34 | #define GE_SRCAREAH_OFF 0x38 | ||
| 35 | #define GE_DESTBASE_OFF 0x3c | ||
| 36 | #define GE_DESTDISPW_OFF 0x40 | ||
| 37 | #define GE_DESTDISPH_OFF 0x44 | ||
| 38 | #define GE_DESTAREAX_OFF 0x48 | ||
| 39 | #define GE_DESTAREAY_OFF 0x4c | ||
| 40 | #define GE_DESTAREAW_OFF 0x50 | ||
| 41 | #define GE_DESTAREAH_OFF 0x54 | ||
| 42 | #define GE_PAT0C_OFF 0x88 /* Pattern 0 color */ | ||
| 43 | #define GE_ENABLE_OFF 0xec | ||
| 44 | #define GE_INTEN_OFF 0xf0 | ||
| 45 | #define GE_STATUS_OFF 0xf8 | ||
| 46 | |||
| 47 | static void __iomem *regbase; | ||
| 48 | |||
| 49 | void wmt_ge_fillrect(struct fb_info *p, const struct fb_fillrect *rect) | ||
| 50 | { | ||
| 51 | unsigned long fg, pat; | ||
| 52 | |||
| 53 | if (p->state != FBINFO_STATE_RUNNING) | ||
| 54 | return; | ||
| 55 | |||
| 56 | if (p->fix.visual == FB_VISUAL_TRUECOLOR || | ||
| 57 | p->fix.visual == FB_VISUAL_DIRECTCOLOR) | ||
| 58 | fg = ((u32 *) (p->pseudo_palette))[rect->color]; | ||
| 59 | else | ||
| 60 | fg = rect->color; | ||
| 61 | |||
| 62 | pat = pixel_to_pat(p->var.bits_per_pixel, fg); | ||
| 63 | |||
| 64 | if (p->fbops->fb_sync) | ||
| 65 | p->fbops->fb_sync(p); | ||
| 66 | |||
| 67 | writel(p->var.bits_per_pixel == 32 ? 3 : | ||
| 68 | (p->var.bits_per_pixel == 8 ? 0 : 1), regbase + GE_DEPTH_OFF); | ||
| 69 | writel(p->var.bits_per_pixel == 15 ? 1 : 0, regbase + GE_HIGHCOLOR_OFF); | ||
| 70 | writel(p->fix.smem_start, regbase + GE_DESTBASE_OFF); | ||
| 71 | writel(p->var.xres_virtual - 1, regbase + GE_DESTDISPW_OFF); | ||
| 72 | writel(p->var.yres_virtual - 1, regbase + GE_DESTDISPH_OFF); | ||
| 73 | writel(rect->dx, regbase + GE_DESTAREAX_OFF); | ||
| 74 | writel(rect->dy, regbase + GE_DESTAREAY_OFF); | ||
| 75 | writel(rect->width - 1, regbase + GE_DESTAREAW_OFF); | ||
| 76 | writel(rect->height - 1, regbase + GE_DESTAREAH_OFF); | ||
| 77 | |||
| 78 | writel(pat, regbase + GE_PAT0C_OFF); | ||
| 79 | writel(1, regbase + GE_COMMAND_OFF); | ||
| 80 | writel(rect->rop == ROP_XOR ? 0x5a : 0xf0, regbase + GE_ROPCODE_OFF); | ||
| 81 | writel(1, regbase + GE_FIRE_OFF); | ||
| 82 | } | ||
| 83 | EXPORT_SYMBOL_GPL(wmt_ge_fillrect); | ||
| 84 | |||
| 85 | void wmt_ge_copyarea(struct fb_info *p, const struct fb_copyarea *area) | ||
| 86 | { | ||
| 87 | if (p->state != FBINFO_STATE_RUNNING) | ||
| 88 | return; | ||
| 89 | |||
| 90 | if (p->fbops->fb_sync) | ||
| 91 | p->fbops->fb_sync(p); | ||
| 92 | |||
| 93 | writel(p->var.bits_per_pixel > 16 ? 3 : | ||
| 94 | (p->var.bits_per_pixel > 8 ? 1 : 0), regbase + GE_DEPTH_OFF); | ||
| 95 | |||
| 96 | writel(p->fix.smem_start, regbase + GE_SRCBASE_OFF); | ||
| 97 | writel(p->var.xres_virtual - 1, regbase + GE_SRCDISPW_OFF); | ||
| 98 | writel(p->var.yres_virtual - 1, regbase + GE_SRCDISPH_OFF); | ||
| 99 | writel(area->sx, regbase + GE_SRCAREAX_OFF); | ||
| 100 | writel(area->sy, regbase + GE_SRCAREAY_OFF); | ||
| 101 | writel(area->width - 1, regbase + GE_SRCAREAW_OFF); | ||
| 102 | writel(area->height - 1, regbase + GE_SRCAREAH_OFF); | ||
| 103 | |||
| 104 | writel(p->fix.smem_start, regbase + GE_DESTBASE_OFF); | ||
| 105 | writel(p->var.xres_virtual - 1, regbase + GE_DESTDISPW_OFF); | ||
| 106 | writel(p->var.yres_virtual - 1, regbase + GE_DESTDISPH_OFF); | ||
| 107 | writel(area->dx, regbase + GE_DESTAREAX_OFF); | ||
| 108 | writel(area->dy, regbase + GE_DESTAREAY_OFF); | ||
| 109 | writel(area->width - 1, regbase + GE_DESTAREAW_OFF); | ||
| 110 | writel(area->height - 1, regbase + GE_DESTAREAH_OFF); | ||
| 111 | |||
| 112 | writel(0xcc, regbase + GE_ROPCODE_OFF); | ||
| 113 | writel(1, regbase + GE_COMMAND_OFF); | ||
| 114 | writel(1, regbase + GE_FIRE_OFF); | ||
| 115 | } | ||
| 116 | EXPORT_SYMBOL_GPL(wmt_ge_copyarea); | ||
| 117 | |||
| 118 | int wmt_ge_sync(struct fb_info *p) | ||
| 119 | { | ||
| 120 | int loops = 5000000; | ||
| 121 | while ((readl(regbase + GE_STATUS_OFF) & 4) && --loops) | ||
| 122 | cpu_relax(); | ||
| 123 | return loops > 0 ? 0 : -EBUSY; | ||
| 124 | } | ||
| 125 | EXPORT_SYMBOL_GPL(wmt_ge_sync); | ||
| 126 | |||
| 127 | static int __devinit wmt_ge_rops_probe(struct platform_device *pdev) | ||
| 128 | { | ||
| 129 | struct resource *res; | ||
| 130 | |||
| 131 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 132 | if (res == NULL) { | ||
| 133 | dev_err(&pdev->dev, "no I/O memory resource defined\n"); | ||
| 134 | return -ENODEV; | ||
| 135 | } | ||
| 136 | |||
| 137 | /* Only one ROP engine is presently supported. */ | ||
| 138 | if (unlikely(regbase)) { | ||
| 139 | WARN_ON(1); | ||
| 140 | return -EBUSY; | ||
| 141 | } | ||
| 142 | |||
| 143 | regbase = ioremap(res->start, resource_size(res)); | ||
| 144 | if (regbase == NULL) { | ||
| 145 | dev_err(&pdev->dev, "failed to map I/O memory\n"); | ||
| 146 | return -EBUSY; | ||
| 147 | } | ||
| 148 | |||
| 149 | writel(1, regbase + GE_ENABLE_OFF); | ||
| 150 | printk(KERN_INFO "Enabled support for WMT GE raster acceleration\n"); | ||
| 151 | |||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | static int __devexit wmt_ge_rops_remove(struct platform_device *pdev) | ||
| 156 | { | ||
| 157 | iounmap(regbase); | ||
| 158 | return 0; | ||
| 159 | } | ||
| 160 | |||
| 161 | static struct platform_driver wmt_ge_rops_driver = { | ||
| 162 | .probe = wmt_ge_rops_probe, | ||
| 163 | .remove = __devexit_p(wmt_ge_rops_remove), | ||
| 164 | .driver = { | ||
| 165 | .owner = THIS_MODULE, | ||
| 166 | .name = "wmt_ge_rops", | ||
| 167 | }, | ||
| 168 | }; | ||
| 169 | |||
| 170 | static int __init wmt_ge_rops_init(void) | ||
| 171 | { | ||
| 172 | return platform_driver_register(&wmt_ge_rops_driver); | ||
| 173 | } | ||
| 174 | |||
| 175 | static void __exit wmt_ge_rops_exit(void) | ||
| 176 | { | ||
| 177 | platform_driver_unregister(&wmt_ge_rops_driver); | ||
| 178 | } | ||
| 179 | |||
| 180 | module_init(wmt_ge_rops_init); | ||
| 181 | module_exit(wmt_ge_rops_exit); | ||
| 182 | |||
| 183 | MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com"); | ||
| 184 | MODULE_DESCRIPTION("Accelerators for raster operations using " | ||
| 185 | "WonderMedia Graphics Engine"); | ||
| 186 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/wmt_ge_rops.h b/drivers/video/wmt_ge_rops.h new file mode 100644 index 000000000000..87380751a443 --- /dev/null +++ b/drivers/video/wmt_ge_rops.h | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | extern void wmt_ge_fillrect(struct fb_info *info, | ||
| 2 | const struct fb_fillrect *rect); | ||
| 3 | extern void wmt_ge_copyarea(struct fb_info *info, | ||
| 4 | const struct fb_copyarea *area); | ||
| 5 | extern int wmt_ge_sync(struct fb_info *info); | ||
diff --git a/include/linux/fb.h b/include/linux/fb.h index d1631d37e9e0..68ba85a00c06 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h | |||
| @@ -1092,6 +1092,8 @@ extern int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var); | |||
| 1092 | extern const unsigned char *fb_firmware_edid(struct device *device); | 1092 | extern const unsigned char *fb_firmware_edid(struct device *device); |
| 1093 | extern void fb_edid_to_monspecs(unsigned char *edid, | 1093 | extern void fb_edid_to_monspecs(unsigned char *edid, |
| 1094 | struct fb_monspecs *specs); | 1094 | struct fb_monspecs *specs); |
| 1095 | extern void fb_edid_add_monspecs(unsigned char *edid, | ||
| 1096 | struct fb_monspecs *specs); | ||
| 1095 | extern void fb_destroy_modedb(struct fb_videomode *modedb); | 1097 | extern void fb_destroy_modedb(struct fb_videomode *modedb); |
| 1096 | extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb); | 1098 | extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb); |
| 1097 | extern unsigned char *fb_ddc_read(struct i2c_adapter *adapter); | 1099 | extern unsigned char *fb_ddc_read(struct i2c_adapter *adapter); |
| @@ -1150,6 +1152,7 @@ struct fb_videomode { | |||
| 1150 | 1152 | ||
| 1151 | extern const char *fb_mode_option; | 1153 | extern const char *fb_mode_option; |
| 1152 | extern const struct fb_videomode vesa_modes[]; | 1154 | extern const struct fb_videomode vesa_modes[]; |
| 1155 | extern const struct fb_videomode cea_modes[64]; | ||
| 1153 | 1156 | ||
| 1154 | struct fb_modelist { | 1157 | struct fb_modelist { |
| 1155 | struct list_head list; | 1158 | struct list_head list; |
diff --git a/include/linux/via-core.h b/include/linux/via-core.h index 38bffd8ccca5..9c21cdf3e3b3 100644 --- a/include/linux/via-core.h +++ b/include/linux/via-core.h | |||
| @@ -60,6 +60,21 @@ struct via_port_cfg { | |||
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | /* | 62 | /* |
| 63 | * Allow subdevs to register suspend/resume hooks. | ||
| 64 | */ | ||
| 65 | #ifdef CONFIG_PM | ||
| 66 | struct viafb_pm_hooks { | ||
| 67 | struct list_head list; | ||
| 68 | int (*suspend)(void *private); | ||
| 69 | int (*resume)(void *private); | ||
| 70 | void *private; | ||
| 71 | }; | ||
| 72 | |||
| 73 | void viafb_pm_register(struct viafb_pm_hooks *hooks); | ||
| 74 | void viafb_pm_unregister(struct viafb_pm_hooks *hooks); | ||
| 75 | #endif /* CONFIG_PM */ | ||
| 76 | |||
| 77 | /* | ||
| 63 | * This is the global viafb "device" containing stuff needed by | 78 | * This is the global viafb "device" containing stuff needed by |
| 64 | * all subdevs. | 79 | * all subdevs. |
| 65 | */ | 80 | */ |
diff --git a/include/video/s1d13xxxfb.h b/include/video/s1d13xxxfb.h index f0736cff2ca3..55f534491a3d 100644 --- a/include/video/s1d13xxxfb.h +++ b/include/video/s1d13xxxfb.h | |||
| @@ -136,12 +136,6 @@ | |||
| 136 | #define S1DREG_DELAYOFF 0xFFFE | 136 | #define S1DREG_DELAYOFF 0xFFFE |
| 137 | #define S1DREG_DELAYON 0xFFFF | 137 | #define S1DREG_DELAYON 0xFFFF |
| 138 | 138 | ||
| 139 | #define BBLT_FIFO_EMPTY 0x00 | ||
| 140 | #define BBLT_FIFO_NOT_EMPTY 0x40 | ||
| 141 | #define BBLT_FIFO_NOT_FULL 0x30 | ||
| 142 | #define BBLT_FIFO_HALF_FULL 0x20 | ||
| 143 | #define BBLT_FIFO_FULL 0x10 | ||
| 144 | |||
| 145 | #define BBLT_SOLID_FILL 0x0c | 139 | #define BBLT_SOLID_FILL 0x0c |
| 146 | 140 | ||
| 147 | 141 | ||
diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h index 18bca08f9f59..6cb95c977de9 100644 --- a/include/video/sh_mipi_dsi.h +++ b/include/video/sh_mipi_dsi.h | |||
| @@ -27,9 +27,15 @@ enum sh_mipi_dsi_data_fmt { | |||
| 27 | 27 | ||
| 28 | struct sh_mobile_lcdc_chan_cfg; | 28 | struct sh_mobile_lcdc_chan_cfg; |
| 29 | 29 | ||
| 30 | #define SH_MIPI_DSI_HSABM (1 << 0) | ||
| 31 | #define SH_MIPI_DSI_HSPBM (1 << 1) | ||
| 32 | |||
| 30 | struct sh_mipi_dsi_info { | 33 | struct sh_mipi_dsi_info { |
| 31 | enum sh_mipi_dsi_data_fmt data_format; | 34 | enum sh_mipi_dsi_data_fmt data_format; |
| 32 | struct sh_mobile_lcdc_chan_cfg *lcd_chan; | 35 | struct sh_mobile_lcdc_chan_cfg *lcd_chan; |
| 36 | unsigned long flags; | ||
| 37 | u32 clksrc; | ||
| 38 | unsigned int vsynw_offset; | ||
| 33 | }; | 39 | }; |
| 34 | 40 | ||
| 35 | #endif | 41 | #endif |
diff --git a/include/video/sh_mobile_hdmi.h b/include/video/sh_mobile_hdmi.h index 1e1aa54ab2e4..b56932927d0a 100644 --- a/include/video/sh_mobile_hdmi.h +++ b/include/video/sh_mobile_hdmi.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | struct sh_mobile_lcdc_chan_cfg; | 14 | struct sh_mobile_lcdc_chan_cfg; |
| 15 | struct device; | 15 | struct device; |
| 16 | struct clk; | ||
| 16 | 17 | ||
| 17 | /* | 18 | /* |
| 18 | * flags format | 19 | * flags format |
| @@ -33,6 +34,8 @@ struct sh_mobile_hdmi_info { | |||
| 33 | struct sh_mobile_lcdc_chan_cfg *lcd_chan; | 34 | struct sh_mobile_lcdc_chan_cfg *lcd_chan; |
| 34 | struct device *lcd_dev; | 35 | struct device *lcd_dev; |
| 35 | unsigned int flags; | 36 | unsigned int flags; |
| 37 | long (*clk_optimize_parent)(unsigned long target, unsigned long *best_freq, | ||
| 38 | unsigned long *parent_freq); | ||
| 36 | }; | 39 | }; |
| 37 | 40 | ||
| 38 | #endif | 41 | #endif |
diff --git a/drivers/staging/udlfb/udlfb.h b/include/video/udlfb.h index 6f9785e9d62e..69d485a4a026 100644 --- a/drivers/staging/udlfb/udlfb.h +++ b/include/video/udlfb.h | |||
| @@ -65,9 +65,6 @@ struct dlfb_data { | |||
| 65 | #define MAX_TRANSFER (PAGE_SIZE*16 - BULK_SIZE) | 65 | #define MAX_TRANSFER (PAGE_SIZE*16 - BULK_SIZE) |
| 66 | #define WRITES_IN_FLIGHT (4) | 66 | #define WRITES_IN_FLIGHT (4) |
| 67 | 67 | ||
| 68 | #define MIN_EDID_SIZE 128 | ||
| 69 | #define MAX_EDID_SIZE 128 | ||
| 70 | |||
| 71 | #define MAX_VENDOR_DESCRIPTOR_SIZE 256 | 68 | #define MAX_VENDOR_DESCRIPTOR_SIZE 256 |
| 72 | 69 | ||
| 73 | #define GET_URB_TIMEOUT HZ | 70 | #define GET_URB_TIMEOUT HZ |
| @@ -95,23 +92,4 @@ struct dlfb_data { | |||
| 95 | #define DL_ALIGN_UP(x, a) ALIGN(x, a) | 92 | #define DL_ALIGN_UP(x, a) ALIGN(x, a) |
| 96 | #define DL_ALIGN_DOWN(x, a) ALIGN(x-(a-1), a) | 93 | #define DL_ALIGN_DOWN(x, a) ALIGN(x-(a-1), a) |
| 97 | 94 | ||
| 98 | /* remove once this gets added to sysfs.h */ | ||
| 99 | #define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store) | ||
| 100 | |||
| 101 | /* | ||
| 102 | * udlfb is both a usb device, and a framebuffer device. | ||
| 103 | * They may exist at the same time, but during various stages | ||
| 104 | * inactivity, teardown, or "virtual" operation, only one or the | ||
| 105 | * other will exist (one will outlive the other). So we can't | ||
| 106 | * call the dev_*() macros, because we don't have a stable dev object. | ||
| 107 | */ | ||
| 108 | #define dl_err(format, arg...) \ | ||
| 109 | pr_err("udlfb: " format, ## arg) | ||
| 110 | #define dl_warn(format, arg...) \ | ||
| 111 | pr_warning("udlfb: " format, ## arg) | ||
| 112 | #define dl_notice(format, arg...) \ | ||
| 113 | pr_notice("udlfb: " format, ## arg) | ||
| 114 | #define dl_info(format, arg...) \ | ||
| 115 | pr_info("udlfb: " format, ## arg) | ||
| 116 | |||
| 117 | #endif | 95 | #endif |
