From bda2e699bfee84e1266f28da53a6debe432db96b Mon Sep 17 00:00:00 2001 From: root Date: Tue, 10 Jul 2012 09:41:13 +0800 Subject: [PATCH] New driver v4.0.6 [patch]New driver works for SM712/722/502/750/718/750LE. This is the first submission. Signed-off-by:Aaron Chen --- Makefile.am | 11 +- QA | 35 + README | 34 +- Release.txt | 381 +-- configure.ac | 81 +- man/Makefile.am | 64 +- src/CALLMAP | 22 + src/Imakefile | 116 + src/Makefile.am | 71 +- src/ddk502/502ddk_module.c | 43 + src/ddk502/Makefile.am | 38 + src/ddk502/ddk502_chip.c | 348 +++ src/ddk502/ddk502_chip.h | 127 + src/ddk502/ddk502_clock.c | 603 ++++ src/ddk502/ddk502_clock.h | 119 + src/ddk502/ddk502_ddkdebug.c | 241 ++ src/ddk502/ddk502_ddkdebug.h | 154 + src/ddk502/ddk502_display.c | 414 +++ src/ddk502/ddk502_display.h | 95 + src/ddk502/ddk502_hardware.c | 458 +++ src/ddk502/ddk502_hardware.h | 93 + src/ddk502/ddk502_help.c | 47 + src/ddk502/ddk502_help.h | 29 + src/ddk502/ddk502_linux.c | 407 +++ src/ddk502/ddk502_mode.c | 746 +++++ src/ddk502/ddk502_mode.h | 157 + src/ddk502/ddk502_os.c | 26 + src/ddk502/ddk502_os.h | 362 +++ src/ddk502/ddk502_power.c | 487 +++ src/ddk502/ddk502_power.h | 126 + src/ddk502/ddk502_regdc.h | 769 +++++ src/ddk502/ddk502_regdma.h | 69 + src/ddk502/ddk502_reggpio.h | 317 ++ src/ddk502/ddk502_regsc.h | 1233 ++++++++ src/ddk502/ddk502_regzv.h | 275 ++ src/ddk502/ddk502_swi2c.c | 551 ++++ src/ddk502/ddk502_swi2c.h | 39 + src/ddk502/ddk502_voyager.h | 94 + src/ddk502/version.h | 25 + src/ddk712/712ddk_module.c | 44 + src/ddk712/Makefile.am | 19 + src/ddk712/ddk712.h | 20 + src/ddk712/ddk712_chip.c | 163 + src/ddk712/ddk712_chip.h | 52 + src/ddk712/ddk712_help.c | 29 + src/ddk712/ddk712_help.h | 100 + src/ddk712/ddk712_mode.c | 260 ++ src/ddk712/ddk712_mode.h | 22 + src/ddk712/ddk712_reg.h | 14 + src/ddk712/version.h | 25 + src/ddk750/750ddk_module.c | 43 + src/ddk750/Makefile.am | 32 + src/ddk750/ddk750.h | 24 + src/ddk750/ddk750_chip.c | 657 ++++ src/ddk750/ddk750_chip.h | 84 + src/ddk750/ddk750_display.c | 350 +++ src/ddk750/ddk750_display.h | 177 ++ src/ddk750/ddk750_dvi.c | 98 + src/ddk750/ddk750_dvi.h | 67 + src/ddk750/ddk750_edid.c | 1940 ++++++++++++ src/ddk750/ddk750_edid.h | 1083 +++++++ src/ddk750/ddk750_help.c | 51 + src/ddk750/ddk750_help.h | 32 + src/ddk750/ddk750_hwi2c.c | 285 ++ src/ddk750/ddk750_hwi2c.h | 17 + src/ddk750/ddk750_mode.c | 219 ++ src/ddk750/ddk750_mode.h | 43 + src/ddk750/ddk750_power.c | 240 ++ src/ddk750/ddk750_power.h | 72 + src/ddk750/ddk750_reg.h | 2597 ++++++++++++++++ src/ddk750/ddk750_sii164.c | 423 +++ src/ddk750/ddk750_sii164.h | 170 + src/ddk750/ddk750_swi2c.c | 592 ++++ src/ddk750/ddk750_swi2c.h | 98 + src/ddk750/version.h | 25 + src/drv502/smi_502_crtc.c | 729 +++++ src/drv502/smi_502_driver.c | 813 +++++ src/drv502/smi_502_driver.h | 379 +++ src/drv502/smi_502_hw.c | 139 + src/drv502/smi_502_hw.h | 29 + src/drv502/smi_502_output.c | 486 +++ src/drv712/smi_712_crtc.c | 1540 +++++++++ src/drv712/smi_712_driver.c | 565 ++++ src/drv712/smi_712_driver.h | 98 + src/drv712/smi_712_hw.c | 558 ++++ src/drv712/smi_712_hw.h | 144 + src/drv712/smi_712_output.c | 698 +++++ src/drv750/smi_750_crtc.c | 699 +++++ src/drv750/smi_750_driver.c | 636 ++++ src/drv750/smi_750_driver.h | 64 + src/drv750/smi_750_hw.c | 237 ++ src/drv750/smi_750_hw.h | 54 + src/drv750/smi_750_output.c | 406 +++ src/drv750le/smi_750le_crtc.c | 331 ++ src/drv750le/smi_750le_driver.c | 652 ++++ src/drv750le/smi_750le_driver.h | 782 +++++ src/drv750le/smi_750le_hw.c | 140 + src/drv750le/smi_750le_hw.h | 46 + src/drv750le/smi_750le_output.c | 199 ++ src/smi_accel.c | 1556 +++++++++- src/smi_accel.h | 174 ++ src/smi_common.c | 11 + src/smi_common.h | 693 +++++ src/smi_crtc.c | 269 +- src/smi_crtc.h | 33 +- src/smi_dbg.h | 30 + src/smi_driver.c | 4047 ++++++++++++------------- src/smi_driver.h | 77 + src/smi_output.c | 197 +- src/smi_output.h | 44 + src/smi_ver.h | 21 + src/smi_video.c | 6561 ++++++++++++++++++++++++--------------- src/smi_video.h | 281 ++- src/version.h | 28 + 114 files changed, 38463 insertions(+), 5457 deletions(-) create mode 100644 QA mode change 100755 => 100644 autogen.sh create mode 100644 src/CALLMAP create mode 100644 src/Imakefile create mode 100644 src/ddk502/502ddk_module.c create mode 100644 src/ddk502/Makefile.am create mode 100644 src/ddk502/ddk502_chip.c create mode 100644 src/ddk502/ddk502_chip.h create mode 100644 src/ddk502/ddk502_clock.c create mode 100644 src/ddk502/ddk502_clock.h create mode 100644 src/ddk502/ddk502_ddkdebug.c create mode 100644 src/ddk502/ddk502_ddkdebug.h create mode 100644 src/ddk502/ddk502_display.c create mode 100644 src/ddk502/ddk502_display.h create mode 100644 src/ddk502/ddk502_hardware.c create mode 100644 src/ddk502/ddk502_hardware.h create mode 100644 src/ddk502/ddk502_help.c create mode 100644 src/ddk502/ddk502_help.h create mode 100644 src/ddk502/ddk502_linux.c create mode 100644 src/ddk502/ddk502_mode.c create mode 100644 src/ddk502/ddk502_mode.h create mode 100644 src/ddk502/ddk502_os.c create mode 100644 src/ddk502/ddk502_os.h create mode 100644 src/ddk502/ddk502_power.c create mode 100644 src/ddk502/ddk502_power.h create mode 100644 src/ddk502/ddk502_regdc.h create mode 100644 src/ddk502/ddk502_regdma.h create mode 100644 src/ddk502/ddk502_reggpio.h create mode 100644 src/ddk502/ddk502_regsc.h create mode 100644 src/ddk502/ddk502_regzv.h create mode 100644 src/ddk502/ddk502_swi2c.c create mode 100644 src/ddk502/ddk502_swi2c.h create mode 100644 src/ddk502/ddk502_voyager.h create mode 100644 src/ddk502/version.h create mode 100644 src/ddk712/712ddk_module.c create mode 100644 src/ddk712/Makefile.am create mode 100644 src/ddk712/ddk712.h create mode 100644 src/ddk712/ddk712_chip.c create mode 100644 src/ddk712/ddk712_chip.h create mode 100644 src/ddk712/ddk712_help.c create mode 100644 src/ddk712/ddk712_help.h create mode 100644 src/ddk712/ddk712_mode.c create mode 100644 src/ddk712/ddk712_mode.h create mode 100644 src/ddk712/ddk712_reg.h create mode 100644 src/ddk712/version.h create mode 100644 src/ddk750/750ddk_module.c create mode 100644 src/ddk750/Makefile.am create mode 100644 src/ddk750/ddk750.h create mode 100644 src/ddk750/ddk750_chip.c create mode 100644 src/ddk750/ddk750_chip.h create mode 100644 src/ddk750/ddk750_display.c create mode 100644 src/ddk750/ddk750_display.h create mode 100644 src/ddk750/ddk750_dvi.c create mode 100644 src/ddk750/ddk750_dvi.h create mode 100644 src/ddk750/ddk750_edid.c create mode 100644 src/ddk750/ddk750_edid.h create mode 100644 src/ddk750/ddk750_help.c create mode 100644 src/ddk750/ddk750_help.h create mode 100644 src/ddk750/ddk750_hwi2c.c create mode 100644 src/ddk750/ddk750_hwi2c.h create mode 100644 src/ddk750/ddk750_mode.c create mode 100644 src/ddk750/ddk750_mode.h create mode 100644 src/ddk750/ddk750_power.c create mode 100644 src/ddk750/ddk750_power.h create mode 100644 src/ddk750/ddk750_reg.h create mode 100644 src/ddk750/ddk750_sii164.c create mode 100644 src/ddk750/ddk750_sii164.h create mode 100644 src/ddk750/ddk750_swi2c.c create mode 100644 src/ddk750/ddk750_swi2c.h create mode 100644 src/ddk750/version.h create mode 100644 src/drv502/smi_502_crtc.c create mode 100644 src/drv502/smi_502_driver.c create mode 100644 src/drv502/smi_502_driver.h create mode 100644 src/drv502/smi_502_hw.c create mode 100644 src/drv502/smi_502_hw.h create mode 100644 src/drv502/smi_502_output.c create mode 100644 src/drv712/smi_712_crtc.c create mode 100644 src/drv712/smi_712_driver.c create mode 100644 src/drv712/smi_712_driver.h create mode 100644 src/drv712/smi_712_hw.c create mode 100644 src/drv712/smi_712_hw.h create mode 100644 src/drv712/smi_712_output.c create mode 100644 src/drv750/smi_750_crtc.c create mode 100644 src/drv750/smi_750_driver.c create mode 100644 src/drv750/smi_750_driver.h create mode 100644 src/drv750/smi_750_hw.c create mode 100644 src/drv750/smi_750_hw.h create mode 100644 src/drv750/smi_750_output.c create mode 100644 src/drv750le/smi_750le_crtc.c create mode 100644 src/drv750le/smi_750le_driver.c create mode 100644 src/drv750le/smi_750le_driver.h create mode 100644 src/drv750le/smi_750le_hw.c create mode 100644 src/drv750le/smi_750le_hw.h create mode 100644 src/drv750le/smi_750le_output.c create mode 100644 src/smi_accel.h create mode 100644 src/smi_common.c create mode 100644 src/smi_common.h create mode 100644 src/smi_dbg.h create mode 100644 src/smi_driver.h create mode 100644 src/smi_output.h create mode 100644 src/smi_ver.h create mode 100644 src/version.h diff --git a/Makefile.am b/Makefile.am index 1bb47d9..d79e354 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,17 +18,16 @@ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +AUTOMAKE_OPTIONS = foreign SUBDIRS = src man -MAINTAINERCLEANFILES = ChangeLog INSTALL -EXTRA_DIST = CALLMAP Release.txt +EXTRA_DIST = ChangeLog CALLMAP Release.txt -.PHONY: ChangeLog INSTALL +MAINTAINERCLEANFILES=ChangeLog -INSTALL: - $(INSTALL_CMD) +.PHONY: ChangeLog ChangeLog: $(CHANGELOG_CMD) -dist-hook: ChangeLog INSTALL +dist-hook: ChangeLog diff --git a/QA b/QA new file mode 100644 index 0000000..c5ac661 --- /dev/null +++ b/QA @@ -0,0 +1,35 @@ + +For QA +1. Please refer to sm750 linux xorg driver spec to do the test +2. there were four output combinations for dual view mode,and each need some modification on xorg.conf file + ------------------------------ + 1:Digital TFT(expansion) + CRT + ------------------------------ + Option "DualView" "TRUE" # or note this line directly + Option "XLCD" "1024" # or other value + Option "YLCD" "768" # or other value + Option "TFT_TYPE" "24" # or 18,36 + ------------------------------ + + ------------------------------ + 2:Digital TFT(fixed) + CRT + ------------------------------ + Option "DualView" "TRUE" # or note this line directly + Option "TFT_TYPE" "24" # or 18,36 + ------------------------------ + + ------------------------------ + 3:Digital TFT(fixed) + Digital TFT(fixed) + ------------------------------ + Option "DualView" "TRUE" # or note this line directly + Option "TFT_TYPE" "18" # only 18 is okay + ------------------------------ + + ------------------------------ + 4:Dual CRT (DVI + VGA) + ------------------------------ + Option "DualView" "TRUE" # or note this line directly + ------------------------------ + + + diff --git a/README b/README index a8840d8..2c6b8f5 100644 --- a/README +++ b/README @@ -1,25 +1,9 @@ -xf86-video-siliconmotion - Silicon Motion video driver for the Xorg X server - -All questions regarding this software should be directed at the -Xorg mailing list: - - http://lists.freedesktop.org/mailman/listinfo/xorg - -Please submit bug reports to the Xorg bugzilla: - - https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/siliconmotion - -The master development code repository can be found at: - - git://anongit.freedesktop.org/git/xorg/driver/xf86-video-siliconmotion - - http://cgit.freedesktop.org/xorg/driver/xf86-video-siliconmotion - -For patch submission instructions, see: - - http://www.x.org/wiki/Development/Documentation/SubmittingPatches - -For more information on the git code manager, see: - - http://wiki.x.org/wiki/GitPage - +I. Install Procedures: + + 1. run "sh ./autogen.sh" + 2. For 32bit OS: run "./configure -prefix=/usr" + For 64bit OS: run "./configure -libdir=/usr/lib64" + For disable xrandr functions: "./configure --disable-smirandr" + For enable xrandr functions: "./configure --enable-smirandr" or "./configure" + 3. make install + diff --git a/Release.txt b/Release.txt index 204dba7..636b40c 100644 --- a/Release.txt +++ b/Release.txt @@ -1,231 +1,194 @@ --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.1.0 - Alpha Release 1.3.1cz, 11/12/2001 ------------------------------------------------------------------------------- - -Extensions: - -- gamma correction for 24 bit true color mode. - -Known problems: - -- gamma correction does not work for 16 bit true color mode: - LoadPalette gets a gamma correction color table for 5:6:5 RGB, - whereas the SMI RAMDAC wants a 8:8:8 RGB color table. - -- gamma correction only implemented for the Lynx3DM - -- StopVideo don't work. The graphics controller continues to write - into the capture buffer - -Fixed bugs (or new bugs :) ): - -- in SMI_ScreenInit frame buffer size calculation for video changed. - - --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.1.0 - Alpha Release 1.3.0cz, 10/26/2001 + Silicon Motion Driver (Alcyone) For Xorg-server ------------------------------------------------------------------------------- -Fixed bugs: - -- XAA: clipping rectangle was clipped to visible screen, so offscreen - pixmaps could not been drawn at with accelerated drawing functions. - -Extensions: - -- smi_video: partly rewritten. - - Support for 7111 - - interlaced video via - - XF86Config Option "Interlaced" or - - attribute XV_INTERLACED - --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0.2 - Alpha Release 1.2.2, 02/14/2001 ------------------------------------------------------------------------------- - -Fixed bugs: - -- #920 - Color change/flash at 8bpp when switch back to desktop in rotation - mode. -- #932 - System hangs when enabling rotation in 24-bpp. -- #941 - Overlay disappear in the virtual desktop when move the window. -- #944 - Mouse pointer doesn't work properly in panning modes under rotation. -- #950 - Garbage appears on desktop when click the Basic/Metal for the Theme - Selector. -- #983 - Added ZoomOnLCD option. -- #1058 - Desktop changes color when panning in 24-bpp mode. -- #1069 - CRT is off after exit X on DSTN 800x600. -- #1074 - Screen broken occurs in X when enable Rotation on DSTN 800x600. - -Known problems: - -- When video is playing in panning mode, it is not correctly clipped when you - move the panning window. -- Sound breaks apart in Netscape when moving the window around. - + Version 4.0.6 6/21/2012 ------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0.2 - Alpha Release 1.2.1, 01/03/2001 --------------------------------------------------------------------------------- - -Fixed bugs: +Release Type: Full release + +Feature: + Support arch: x86 + Support chip: SM750 SM718 SM750LE SM712 SM722 SM502 + Support OS: Fedora 14/15, Ubuntu 10.10/11.04, 32bit/64bit. + Performance: No RandR / RandR + Dual view + Video + 2D + +Fixed Bug: +1. [32bits][U10][sm750le][RandR] startx failure. +2. [32bits][F15][sm750le][RandR] startx failure. +3. [sm718][NoRandR] driver crashed while use dual view. +4. [sm502]dual view error. +5. [sm712][No RandR] No dual view. +6. [32bits][F14][sm712][RandR] Noise on status lines after startx +7. [sm750le] RANDR works +8. [32-bit][F14][sm722][NoRandR]cant set mode after startx -- Severe corruption in 24-bpp across all chips. -- Disable hardware cursor on older BIOSes. --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0.2 - Alpha Release 1.2.0, 12/13/2000 --------------------------------------------------------------------------------- - -Fixed bugs: - -- When restoring from VESAFB graphics mode, the screen did not update with the - UseBIOS switch on. - --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0.1 - Alpha Release 1.1.9, 11/30/2000 --------------------------------------------------------------------------------- - -Fixed bugs: - -#581 - Need Linux driver to support zooming via ctrl+alt++ & ctrl+alt+-. -#670 - Screen broken occurs when switch back to the Xwindow during in Rotation - mode. -#671 - Very slow to pop up the Exit menu from X windows during in Rotation mode. -#672 - It doesn't redraw properly in X windows during in Rotation mode. -#689 - Screen broken when toggle between terminal and desktop during playing in - MPEG. -#705 - Linux CRT only 800x600 or 1024x768 there is no display. -#864 - Lockup when video is playing and switching to full-screen command shell. - --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0.1 - Alpha Release 1.1.8, 11/27/2000 --------------------------------------------------------------------------------- - -Fixed bugs: - -#640 - X windows shift to the right when start X or apply Rotation. - --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0.1 - Alpha Release 1.1.7, 11/17/2000 --------------------------------------------------------------------------------- - -Fixed bugs: - -#676 - Green color only shown in window when run Xlive in Linux. -#835 - Screen black after DPMS on. - - --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0.1 - Alpha Release 1.1.6, 11/03/2000 --------------------------------------------------------------------------------- - -Fixed bugs: - -#687 - Blue rectangle appears when video is clipped on thr right edge of screen. -#735 - When resume from sleep, X does not wake up. - --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0.1 - Alpha Release 1.1.5, 10/06/2000 --------------------------------------------------------------------------------- - -Fixed bugs: - -#578 - Don't check for CRT-only when validating modes. -#579 - Corrected DPI issue when DDC monitor is not attached. - --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0.1 - Alpha Release 1.1.4, 09/20/2000 --------------------------------------------------------------------------------- - -Fixed bugs: - -#521 - Screen corruption after return from X Server when vesafb is used. - --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0.1 - Alpha Release 1.1.3, 09/18/2000 --------------------------------------------------------------------------------- - -New features: - -- Added live video capture. - --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0.1 - Alpha Release 1.1.2, 09/14/2000 --------------------------------------------------------------------------------- - -Fixed bugs: - -#486 - Video scaling wrong on SM720. - --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0.1 - Alpha Release 1.1.1, 08/23/2000 --------------------------------------------------------------------------------- - -New features: - -- Added support for overlays. - --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0.1 - Alpha Release 1.1.0, 08/11/2000 --------------------------------------------------------------------------------- - -New features: +------------------------------------------------------------------------------- + Silicon Motion Driver (Alcyone) For Xorg-server +------------------------------------------------------------------------------- -- Added support for XFree86 4.0.1 server. This implies that support for the 4.0 - server has gone. Hence the change in the alpha version number from 1.0.x to - 1.1.x. +------------------------------------------------------------------------------- + Version 4.0.5 5/24/2012 +------------------------------------------------------------------------------- +Release Type: Full release + +Feature: + Support arch: x86 + Support chip: SM750 SM718 SM750LE SM712 SM722 SM502 + Support OS: Fedora 14 i386 + Performance: No RandR / RandR + Dual view + Video + 2D + +Bug: +1. Do not support 8-bits colour. +2. Mosaic appears on screen while using SM712(RandR). +3. Error in switching screen (SM750LE). +4. SM712/722 cannot play video. --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0 - Alpha Release 1.0.2, 08/02/2000 --------------------------------------------------------------------------------- +------------------------------------------------------------------------------- + Version 4.0.4 3/22/2012 +------------------------------------------------------------------------------- +Release Type: Formal release + +Feature: + Support arch: x86 + Support chip: lynx Express(750) + Support OS: Fedora 15 i386 + Performance: No RandR + Dual view + Multi card + 2D + + Fixed bugs: +6215:(SM750 multicard)On Fedora 15 i386, under high resolution(1024x768 and dual view at least), drag a icon to the view of the other card and then garbage will occur on the primary view(Screen 0). +6216:Xinerama)When the 2 views are the different resolution, enter xorg, then switch xorg to console, and return to xorg, garbage will occur on the primary screen(Screen 0). -#161, Corruption when moving windows with a wallpaper background. --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0 - Alpha Release 1.0.1, 07/27/2000 --------------------------------------------------------------------------------- -Fixed bugs: +------------------------------------------------------------------------------- + Version 3.0.9-08 11/24/2010 +------------------------------------------------------------------------------- +Feature: +1+,add support for EDID (both pnl and crt head) + +Misc: +1. Version number change: + A target product suffix is added to the version number. This suffix shows + the corresponding release is targeted on specific products. Currently the + suffix is a two-bit hex number which can be interpreted into eight-bit bin + number with every bit indicating a graphic product from SMI. The following + rule applies here: + + Bit 7 6 5 4 3 2 1 0 + SM712 SM722 SM502 SM107 SM750 SM718 TBD TBD + e.g. The suffix of the current release is 28 which can be converted to + 00101000. Thus this release for SM502 and SM750. +------------------------------------------------------------------------------- + Version 3.0.8 07/21/2010 +------------------------------------------------------------------------------- +Feature: +1+,add support for sm718 -#160, Mouse pointer sometimes in bad location. -#258, Temporary corruption starting X. +------------------------------------------------------------------------------- + Version 3.0.7 07/13/2010 +------------------------------------------------------------------------------- +Bug: +1-,#5461:csc video on 2nd screen,mass shown on 1st screen (larg resolution reduplicate) +2-,#5811:csc video under rotation status,you can see incorrect video --------------------------------------------------------------------------------- - Silicon Motion Driver for XFree86 4.0 - Alpha Release 1.0.0, 06/05/2000 --------------------------------------------------------------------------------- +------------------------------------------------------------------------------- + Version 3.0.6 06/08/2010 +------------------------------------------------------------------------------- +Feature: +Change Chip frequency from 300MHz to 290MHz -This is alpha version 1.0.0 of the Silicon Motion drivers for the XFree86 4.0 -server. See the README file for general information. +------------------------------------------------------------------------------- + Version 3.0.5 06/07/2010 +------------------------------------------------------------------------------- +Feature: +Change Chip frequency from 308MHz to 300MHz -This ALPHA version has the following known problems: +------------------------------------------------------------------------------- + Version 3.0.4 04/06/2010 +------------------------------------------------------------------------------- +Bug: +1-,#5450:sm750:black hand occur when play game +2-,#5460:sm750:DVI no signal bug +3-,#5469:sm750:also DVI problem +4-,sm712:different size of crt and pnl mode setting will cause crt width error +5-,#5614:sm712:not supported hsync showed to user +6-,#5612:sm712:some rotation option is not workable +7-,#5615:sm712:some timing of 712 pnl is not right +8-,#5418:sm712:hibernation failed in mode3 startup,please see READMD for detail + solution. +9-,#5456:Video screen has color noise when playing movie with CSC. +10-,#5457:When placing a window whose height is enough to cover video's height + on video window, if the window on upper layer is moved left, the + video's uncovered part will be found shaking. +11-,#5462:When moving video window which is playing in CSC across the screen + line and drag the window back to primary screen, the window is + found spilt to two part that the left part contiues playing and the + right part stops. +12-,#5468:When the video window is scaled down to smaller than 1/4 of the + original size, the video screen is duplication. +------------------------------------------------------------------------------- + Version 3.0.3 03/08/2010 +------------------------------------------------------------------------------- +Feature: +1+,sm712 crt channel DDC feature supported. +2-,no 1024x600 mode. -- During mode initialization, the screen shows temporary garbage. -- Image Transfers are disabled in the hardware for now. +Bug: +1-,sm712 panel video ripple issue +2+,found 1024x600 mode incorrect,disable it bynow. -This driver has been tested on the LynxEM+ 712 chip under 16-bit mode. Any other -mode might still show lock-ups and/or garbage. Please report any problems to -frido@siliconmotion.com. +------------------------------------------------------------------------------- + Version 3.0.2 02/22/2010 +------------------------------------------------------------------------------- +Features: + SM750: + 1. Hardware XV acceleration under all rotation circumstances and view + modes. + 2. Overlay video playback when using both dual view mode and single view + mode. + +Bug Fix: + SM750: + 1. CSC video pause problem when the viewport is rotated. + 2. Wrong video size when playing 1920x1080 movies. -Header: //Mercury/Projects/archives/XFree86/4.0/Release.txt-arc 1.33 13 Dec 2000 09:52:48 Frido $ +------------------------------------------------------------------------------- + Version 3.0.1 01/29/2010 +------------------------------------------------------------------------------- +Features: support sm712 + 1:Xaa 2d accelation + 2:Dual view + +Bug remaind: + #5263 750:Under rotation,CSC video will be paused + #5327 750:Abnormal video when playing 1920x1080 movie + #4900 750:There is aliasing when enlarging the video twice in windowed mode + #5337 750:there may be garbage with tooltip at the right-bottom of the window when playing video in CSC +Bug Fix: + #5328 750:Under dual-view mode,you can get another cloned cursor on another view -$XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/Release.txt,v 1.7 2001/12/20 21:35:37 eich Exp $ +------------------------------------------------------------------------------- + Version 1.2.0 12/25/2009 +------------------------------------------------------------------------------- +Features: + 1. Xrandr support (dynamic dual view, screen rotation and reflection). + 2. XAA 2D acceleration. + 3. Overlay video playback when using single view. + 4. CSC video playback. + 5. ARGB hardware cursor when using single view. + 6. DPMS support. + 7. Four output combination. + 8. 64bit OS compatible. diff --git a/autogen.sh b/autogen.sh old mode 100755 new mode 100644 diff --git a/configure.ac b/configure.ac index 7a80962..869870b 100644 --- a/configure.ac +++ b/configure.ac @@ -20,50 +20,64 @@ # # Process this file with autoconf to produce a configure script -# Initialize Autoconf -AC_PREREQ([2.60]) +AC_PREREQ(2.57) AC_INIT([xf86-video-siliconmotion], - [1.7.6], - [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/siliconmotion], - [xf86-video-siliconmotion]) + 1.8.0, + [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], + xf86-video-siliconmotion) -# Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS -m4_ifndef([XORG_MACROS_VERSION], - [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])]) -XORG_MACROS_VERSION(1.8) -XORG_DEFAULT_OPTIONS +# Require xorg-macros version 1.2 or newer for XORG_CWARNFLAGS and +# XORG_CHANGELOG macros +m4_ifndef([XORG_MACROS_VERSION], [AC_FATAL([must install xorg-macros 1.1.6 or later before running autoconf/autogen])]) +XORG_MACROS_VERSION(1.1.6) AC_CONFIG_SRCDIR([Makefile.am]) -AC_CONFIG_HEADERS([config.h]) +AM_CONFIG_HEADER([config.h]) AC_CONFIG_AUX_DIR(.) -# Initialize Automake -AM_INIT_AUTOMAKE([foreign dist-bzip2]) +AM_INIT_AUTOMAKE([dist-bzip2]) + AM_MAINTAINER_MODE -# Initialize libtool +# Checks for programs. AC_DISABLE_STATIC AC_PROG_LIBTOOL +AC_PROG_CC AH_TOP([#include "xorg-server.h"]) -# Define a configure option for an alternate module directory AC_ARG_WITH(xorg-module-dir, - AS_HELP_STRING([--with-xorg-module-dir=DIR], + AC_HELP_STRING([--with-xorg-module-dir=DIR], [Default xorg module directory [[default=$libdir/xorg/modules]]]), [moduledir="$withval"], [moduledir="$libdir/xorg/modules"]) -# Store the list of server defined optional extensions in REQUIRED_MODULES + + +# Checks for extensions +XORG_DRIVER_CHECK_EXT(RANDR, randrproto) + +AC_ARG_ENABLE([smirandr], + [AS_HELP_STRING([--enable-smirandr], + [enable X RandR feature for Silicon Motion (default=yes)])], + [enable_smirandr=$enableval], + [enable_smirandr=yes] + ) + +AS_IF([test "x$_EXT_CHECK" == "xno"], + [enable_smirandr=no],[]) + +AS_IF([test "x$enable_smirandr" != "xno"], + [AC_DEFINE([SMI_RANDR], [1], [Define SMI_RANDR to support X RandR])], + [AC_DEFINE([SMI_RANDR], [0], [Define SMI_RANDR to support X Randr])]) + +XORG_DRIVER_CHECK_EXT(RENDER, renderproto) XORG_DRIVER_CHECK_EXT(XV, videoproto) XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) -# Obtain compiler/linker options for the driver dependencies +# Checks for pkg-config packages PKG_CHECK_MODULES(XORG, [xorg-server >= 1.0.99.901 xproto fontsproto $REQUIRED_MODULES]) -PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1], - HAVE_XEXTPROTO_71="yes"; AC_DEFINE(HAVE_XEXTPROTO_71, 1, [xextproto 7.1 available]), - HAVE_XEXTPROTO_71="no") -AM_CONDITIONAL(HAVE_XEXTPROTO_71, [ test "$HAVE_XEXTPROTO_71" = "yes" ]) +sdkdir=$(pkg-config --variable=sdkdir xorg-server) # Checks for libraries. SAVE_CPPFLAGS="$CPPFLAGS" @@ -75,8 +89,12 @@ AC_CHECK_HEADER(xf86Modes.h, [XMODES=yes], [XMODES=no], [#include "xorg-server.h"]) CPPFLAGS="$SAVE_CPPFLAGS" +# Checks for header files. +AC_HEADER_STDC + if test "x$XSERVER_LIBPCIACCESS" = xyes; then PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0]) + XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS" fi AM_CONDITIONAL(XSERVER_LIBPCIACCESS, test "x$XSERVER_LIBPCIACCESS" = xyes) AM_CONDITIONAL(XMODES, test "x$XMODES" = xyes) @@ -85,14 +103,23 @@ if test "x$XMODES" = xyes; then AC_DEFINE(HAVE_XMODES, 1, [X server has new mode code]) fi +XORG_CWARNFLAGS +XORG_CFLAGS="$CWARNFLAGS $XORG_CFLAGS" +AC_SUBST([XORG_CFLAGS]) AC_SUBST([moduledir]) DRIVER_NAME=siliconmotion AC_SUBST([DRIVER_NAME]) -AC_CONFIG_FILES([ - Makefile - src/Makefile - man/Makefile +XORG_MANPAGE_SECTIONS +XORG_RELEASE_VERSION +XORG_CHANGELOG + +AC_OUTPUT([ + Makefile + src/Makefile + src/ddk712/Makefile + src/ddk750/Makefile + src/ddk502/Makefile + man/Makefile ]) -AC_OUTPUT diff --git a/man/Makefile.am b/man/Makefile.am index e1182ee..f0eb29b 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -1,25 +1,28 @@ # -# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice (including the next -# paragraph) shall be included in all copies or substantial portions of the -# Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. -# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation. +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the copyright holders shall +# not be used in advertising or otherwise to promote the sale, use or +# other dealings in this Software without prior written authorization +# from the copyright holders. +# drivermandir = $(DRIVER_MAN_DIR) @@ -31,10 +34,25 @@ EXTRA_DIST = @DRIVER_NAME@.man CLEANFILES = $(driverman_DATA) -# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__drivermansuffix__|$(DRIVER_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man .man.$(DRIVER_MAN_SUFFIX): - $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ + sed $(MAN_SUBSTS) < $< > $@ diff --git a/src/CALLMAP b/src/CALLMAP new file mode 100644 index 0000000..6410d18 --- /dev/null +++ b/src/CALLMAP @@ -0,0 +1,22 @@ +-- Only Once, calling order -- +ChipIdentify (SMIIdentify) +ChipProbe (SMIProbe) + Passive only, no ram determination, no writing + +-- For each ScrnInfoRec, still calling order -- +ChipPreInit (SMIPreInit) + Allows probing and mapping, hardware must remain unchanged + ChipGetRec + +ChipScreenInit + ChipMapMem + ChipSave + vgaHWSaveMMIO + ChipModeInit + vtSema=TRUE + ChipWriteMode + vgaHWRestoreMMIO + +Header: \\Mercury\Projects\archives\XFree86 4.0\CALLMAP.-arc 1.1 13 Jul 2000 18:16:58 Frido $ + +$XFree86$ diff --git a/src/Imakefile b/src/Imakefile new file mode 100644 index 0000000..1ad87c9 --- /dev/null +++ b/src/Imakefile @@ -0,0 +1,116 @@ +XCOMM Header: //Mercury/Projects/archives/XFree86/4.0/Imakefile.-arc 1.4 02 Aug 2000 13:17:16 Frido $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/Imakefile,v 1.2 2001/01/24 00:06:27 dawes Exp $ + +#define IHaveModules +#include + +SRCS = smi_driver.c swi2c.c smi750le_accel.c smi750le_driver.c \ + smi502_accel.c smi502_driver.c smi502_shadow.c smi502_video.c smi718_driver.c \ + smi750_driver.c + +OBJS = smi_driver.o swi2c.o smi750le_accel.o smi750le_driver.o \ + smi502_accel.o smi502_driver.o smi502_shadow.o smi502_video.o smi718_driver.o \ + smi750_driver.o + +DEFINES = -DPSZ=8 + +#if defined(XF86DriverSDK) +INCLUDES = -I. -I../../include +#else +INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \ + -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \ + -I$(XF86SRC)/xaa -I$(XF86SRC)/rac \ + -I$(XF86SRC)/vgahw -I$(XF86SRC)/fbdevhw \ + -I$(XF86SRC)/ramdac -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ + -I$(SERVERSRC)/Xext -I$(XF86SRC)/int10 \ + -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ + -I$(XF86SRC)/shadowfb -I$(EXTINCSRC) -I$(SERVERSRC)/fb \ + -I$(SERVERSRC)/render -I$(XF86SRC)/vbe -I$(SERVERSRC)/hw/xfree86 +#endif + +#if MakeHasPosixVariableSubstitutions +SubdirLibraryRule($(OBJS)) +#endif + +NormalAsmObjectRule() + +ModuleObjectRule() +ObjectModuleTarget(siliconmotion, $(OBJS)) + +InstallObjectModule(siliconmotion,$(MODULEDIR),drivers) + +#if !defined(XF86DriverSDK) +InstallModuleManPage(siliconmotion) +#endif + +DependTarget() + +InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/siliconmotion) + +InstallDriverSDKNonExecFile(smi_accel.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_accel.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_common.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_common.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_dbg.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_driver.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_driver.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_ver.h,$(DRIVERSDKDIR)/drivers/siliconmotion) + +InstallDriverSDKNonExecFile(smi_dac.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_dga.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_driver.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(swi2c.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_hwcurs.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(xf86PciInfo.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_version.h,$(DRIVERSDKDIR)/drivers/siliconmotion) + + +InstallDriverSDKNonExecFile(smi_750le.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(swi2c.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_pcirename.h,$(DRIVERSDKDIR)/drivers/siliconmotion) + + +InstallDriverSDKNonExecFile(smi502_accel.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi502_driver.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi502_shadow.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi502_video.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi502_hw.c,$(DRIVERSDKDIR)/drivers/siliconmotion) + +InstallDriverSDKNonExecFile(smi502_hw.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi502_video.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_502_driver.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(swi2c.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi750_accel.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi750_accel.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi750_driver.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi750_driver.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi750_video.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi750_hw.c,$(DRIVERSDKDIR)/drivers/siliconmotion) + +InstallDriverSDKNonExecFile(smi750_hw.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi750_video.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_750_driver.h,$(DRIVERSDKDIR)/drivers/siliconmotion) + + +InstallDriverSDKNonExecFile(smi_750_driver.h,$(DRIVERSDKDIR)/drivers/siliconmotion) + +InstallDriverSDKNonExecFile(smi_i2c.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_shadow.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_video.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(regsmi.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_video.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_chips.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_chips.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_501.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_501.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_712.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_712.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_720.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_720.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_730.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_730.c,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_820.h,$(DRIVERSDKDIR)/drivers/siliconmotion) +InstallDriverSDKNonExecFile(smi_820.c,$(DRIVERSDKDIR)/drivers/siliconmotion) + +InstallDriverSDKObjectModule(siliconmotion,$(DRIVERSDKMODULEDIR),drivers) diff --git a/src/Makefile.am b/src/Makefile.am index f3ee526..05ac15e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,35 +21,54 @@ # this is obnoxious: # -module lets us name the module exactly how we want # -avoid-version prevents gratuitous .0.0.0 version numbers on the end -# _ladir passes a dummy rpath to libtool so the thing will actually link +# +# +# -ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. - -AM_CFLAGS = $(XORG_CFLAGS) $(CWARNFLAGS) $(PCIACCESS_CFLAGS) - +AM_CFLAGS = @XORG_CFLAGS@ siliconmotion_drv_la_LTLIBRARIES = siliconmotion_drv.la siliconmotion_drv_la_LDFLAGS = -module -avoid-version siliconmotion_drv_ladir = @moduledir@/drivers +SUBDIRS = ddk750 ddk712 ddk502 + siliconmotion_drv_la_SOURCES = \ - regsmi.h \ - smi_501.c \ - smi_501.h \ - smi_accel.c \ - smi_xaa.c \ - smi_exa.c \ - smi_dac.c \ - smi_driver.c \ - smi.h \ - smi_i2c.c \ - smi_pcirename.h \ - smi_video.c \ - smi_video.h \ - smi_crtc.h \ - smi_crtc.c \ - smilynx_crtc.c \ - smi_output.c \ - smilynx_output.c \ - smilynx_hw.c \ - smilynx.h \ - smi501_crtc.c \ - smi501_output.c + smi_common.h \ + smi_dbg.h \ + smi.h \ + smi_output.c \ + smi_crtc.c \ + smi_ver.h \ + smi_accel.h \ + smi_driver.h \ + smi_video.h \ + smi_common.c \ + smi_driver.c \ + smi_accel.c \ + smi_video.c \ + ./drv750/smi_750_driver.h \ + ./drv750/smi_750_hw.h \ + ./drv750/smi_750_output.h \ + ./drv750/smi_750_crtc.h \ + ./drv502/smi_502_driver.h \ + ./drv502/smi_502_hw.h \ + ./drv750/smi_750_output.c \ + ./drv750/smi_750_crtc.c \ + ./drv750/smi_750_hw.c \ + ./drv750/smi_750_driver.c \ + ./drv750le/smi_750le_driver.h \ + ./drv750le/smi_750le_hw.h \ + ./drv750le/smi_750le_output.c \ + ./drv750le/smi_750le_crtc.c \ + ./drv750le/smi_750le_driver.c \ + ./drv750le/smi_750le_hw.c \ + ./drv712/smi_712_driver.h \ + ./drv712/smi_712_hw.h \ + ./drv712/smi_712_output.c \ + ./drv712/smi_712_crtc.c \ + ./drv712/smi_712_hw.c \ + ./drv712/smi_712_driver.c \ + ./drv502/smi_502_crtc.c \ + ./drv502/smi_502_output.c \ + ./drv502/smi_502_driver.c \ + ./drv502/smi_502_hw.c \ No newline at end of file diff --git a/src/ddk502/502ddk_module.c b/src/ddk502/502ddk_module.c new file mode 100644 index 0000000..ca8ba88 --- /dev/null +++ b/src/ddk502/502ddk_module.c @@ -0,0 +1,43 @@ +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86Module.h" +#if XORG_VERSION_CURRENT < 10706000 +#include "xf86Resources.h" +#endif +#include "./version.h" + +static MODULESETUPPROTO(smi502ddk_Setup); + +static XF86ModuleVersionInfo smi502ddkVersRec = + { + "smi502ddk", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + MAJOR_VERSION(LIBRARY_VERSION), + MINOR_VERSION(LIBRARY_VERSION), + 0, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_NONE, + { 0,0,0,0 } + }; + +_X_EXPORT XF86ModuleData smiddk502ModuleData = { + &smi502ddkVersRec, + smi502ddk_Setup, + NULL +}; + +static pointer +smi502ddk_Setup(pointer module, pointer opts, int *errmaj, int *errmin) { + return (pointer)1; +} + diff --git a/src/ddk502/Makefile.am b/src/ddk502/Makefile.am new file mode 100644 index 0000000..668fbf6 --- /dev/null +++ b/src/ddk502/Makefile.am @@ -0,0 +1,38 @@ +AM_CFLAGS = @XORG_CFLAGS@ +smiddk502_drv_la_LTLIBRARIES = smiddk502_drv.la +smiddk502_drv_la_LDFLAGS = -module -avoid-version -lpci +smiddk502_drv_ladir = @moduledir@/drivers + +smiddk502_drv_la_SOURCES = \ + ./ddk502_voyager.h \ + ./ddk502_chip.h \ + ./ddk502_display.h \ + ./ddk502_mode.h \ + ./ddk502_clock.h \ + ./ddk502_regsc.h \ + ./ddk502_regdc.h \ + ./ddk502_regzv.h \ + ./ddk502_regdma.h \ + ./ddk502_reggpio.h \ + ./ddk502_hardware.h \ + ./ddk502_power.h \ + ./ddk502_ddkdebug.h \ + ./ddk502_swi2c.h \ + ./ddk502_swi2c.c \ + ./ddk502_chip.c \ + ./ddk502_display.c \ + ./ddk502_power.c \ + ./ddk502_hardware.c \ + ./ddk502_clock.c \ + ./ddk502_ddkdebug.c \ + ./ddk502_mode.c \ + ./ddk502_os.c \ + ./ddk502_os.h \ + ./ddk502_linux.c \ + ./ddk502_help.c \ + ./ddk502_help.h \ + ./version.h \ + ./502ddk_module.c + + + diff --git a/src/ddk502/ddk502_chip.c b/src/ddk502/ddk502_chip.c new file mode 100644 index 0000000..a1f9101 --- /dev/null +++ b/src/ddk502/ddk502_chip.c @@ -0,0 +1,348 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* CHIP.C --- SMI DDK +* This file contains the source code for the mode table. +* +*******************************************************************/ +#include "ddk502_voyager.h" +#include "ddk502_hardware.h" +//#include "ddk502_power.h" +#include "ddk502_clock.h" +#include "ddk502_chip.h" +#include "ddk502_help.h" +#include "../smi_common.h" + +#define MB(x) (x*0x100000) /* Don't use this macro if x is fraction number */ + +static logical_chip_type_t gLogicalChipType = SM_UNKNOWN; + +/* + * This function returns frame buffer memory size in Byte units. + */ +//_X_EXPORT unsigned long getFrameBufSize() +_X_EXPORT int ddk502_getFrameBufSize() +{ + //unsigned long sizeSymbol, memSize; + unsigned long sizeSymbol; + int memSize; + + sizeSymbol = FIELD_GET(peekRegisterDWord(DRAM_CTRL), DRAM_CTRL, SIZE); + + switch(sizeSymbol) + { + /* Default is set to the lowest memory setting (requested by driver). */ + default: + case DRAM_CTRL_SIZE_2: memSize = MB(2); break; /* 2 Mega byte */ + case DRAM_CTRL_SIZE_4: memSize = MB(4); break; /* 4 Mega byte */ + case DRAM_CTRL_SIZE_8: memSize = MB(8); break; /* 8 Mega byte */ + case DRAM_CTRL_SIZE_16: memSize = MB(16); break; /* 16 Mega byte */ + case DRAM_CTRL_SIZE_32: memSize = MB(32); break; /* 32 Mega byte */ + case DRAM_CTRL_SIZE_64: memSize = MB(64); break; /* 64 Mega byte */ +#if 0 + default: memSize = MB(0); break; /* 0 Mege byte */ +#endif + } + + return memSize; +} + +/* + * This function gets the Frame buffer location. + * + * Return: + * 0 - Embedded + * 1 - External + */ +unsigned char getFrameBufLocation() +{ + /* Check if the memory is external memory */ + if (FIELD_GET(peekRegisterDWord(DRAM_CTRL), DRAM_CTRL, EMBEDDED) == DRAM_CTRL_EMBEDDED_DISABLE) + return 1; + + /* Embedded Memory */ + return 0; +} + +extern unsigned long revId502; +extern unsigned short devId502; + +/* + * This function returns the logical chip type defined in chip.h + * It is one of the following: SM501, SM502, SM107, SM718, SM 750 or + * SM_UNKNOWN. + */ +logical_chip_type_t getChipType() +{ + unsigned long physicalID, physicalRev, memSize; + logical_chip_type_t chip; +/* + physicalID = FIELD_GET(peekRegisterDWord(DEVICE_ID), DEVICE_ID, DEVICE_ID); + physicalRev = FIELD_GET(peekRegisterDWord(DEVICE_ID), DEVICE_ID, REVISION_ID); + memSize = ddk502_getFrameBufSize();*/ + physicalID = devId502;//either 0x718 or 0x750 + physicalRev = revId502; + + if (physicalID == 0x0501) + { + if (physicalRev == 0xC0) + {/* + if (memSize == MB(4)) + chip = SM107; + else*/ + chip = SM502; + } + else + { + chip = SM501; + } + } + else if (physicalID == 0x0718) + { + chip = SM718; + } + else if (physicalID == 0x750) + { + chip = SM750; + } + else + { + chip = SM_UNKNOWN; + } + + return chip; +} + +/* + * Return a char string name of the current chip. + * It's convenient for application need to display the chip name. + */ +char * getChipTypeString() +{ + char * chipName; + + switch(getChipType()) + { + case SM501: + chipName = "SM501"; + break; + case SM502: + chipName = "SM502"; + break; + case SM107: + chipName = "SM107"; + break; + case SM718: + chipName = "SM718"; + break; + case SM750: + chipName = "SM750"; + break; + default: + chipName = "Unknown"; + break; + } + + return chipName; +} + +/* + * Initialize a single chip and environment according to input parameters. + * + * Input: initchip_param_t structure. + * + * Return: 0 (or NO_ERROR) if successful. + * -1 if fail. + * + * Note: + * Caller needs to call the detectDevice and setCurrentDevice + * to set the device before calling this initChipParamEx. + */ +long initChipParamEx(initchip_param_t * pInitParam) +{ + unsigned long ulReg; + + /* Check if we know this chip */ + if ((gLogicalChipType = getChipType()) == SM_UNKNOWN) + return (-1); + + /* For SM107, local memory bank size has to change from hardware + default of 4 banks to 2 banks + */ + if (gLogicalChipType == SM107) + { + ulReg = peekRegisterDWord(DRAM_CTRL); + ulReg = FIELD_SET(ulReg, DRAM_CTRL, BANKS, 2); + + /* ulReg = FIELD_SET(ulReg, DRAM_CTRL, BLOCK_WRITE_PRECHARGE, 4); */ + /* ulReg = FIELD_SET(ulReg, DRAM_CTRL, WRITE_PRECHARGE, 1); */ + + pokeRegisterDWord(DRAM_CTRL, ulReg); + } + + /* Set power mode. + Check parameter validity first. + If calling function didn't set it up properly or set to some + weird value, always default to to 0. + */ + if (pInitParam->powerMode > 1) + pInitParam->powerMode = 0; + setPowerMode(pInitParam->powerMode); + + /* Set up memory clock. */ + setMemoryClock(pInitParam->memClock); + + /* Set up master clock */ + setMasterClock(pInitParam->masterClock); + + if (pInitParam->setAllEngOff == 1) + { + enable2DEngine(0); + + /* Disable Overlay, if a former application left it on */ + ulReg = peekRegisterDWord(VIDEO_DISPLAY_CTRL); + ulReg = FIELD_SET(ulReg, VIDEO_DISPLAY_CTRL, PLANE, DISABLE); + pokeRegisterDWord(VIDEO_DISPLAY_CTRL, ulReg); + + /* Disable video alpha, if a former application left it on */ + ulReg = peekRegisterDWord(VIDEO_ALPHA_DISPLAY_CTRL); + ulReg = FIELD_SET(ulReg, VIDEO_ALPHA_DISPLAY_CTRL, PLANE, DISABLE); + pokeRegisterDWord(VIDEO_ALPHA_DISPLAY_CTRL, ulReg); + + /* Disable alpha plane, if a former application left it on */ + ulReg = peekRegisterDWord(ALPHA_DISPLAY_CTRL); + ulReg = FIELD_SET(ulReg, ALPHA_DISPLAY_CTRL, PLANE, DISABLE); + pokeRegisterDWord(ALPHA_DISPLAY_CTRL, ulReg); + + /* Disable LCD hardware cursor, if a former application left it on */ + ulReg = peekRegisterDWord(PANEL_HWC_ADDRESS); + ulReg = FIELD_SET(ulReg, PANEL_HWC_ADDRESS, ENABLE, DISABLE); + pokeRegisterDWord(PANEL_HWC_ADDRESS, ulReg); + + /* Disable CRT hardware cursor, if a former application left it on */ + ulReg = peekRegisterDWord(CRT_HWC_ADDRESS); + ulReg = FIELD_SET(ulReg, CRT_HWC_ADDRESS, ENABLE, DISABLE); + pokeRegisterDWord(CRT_HWC_ADDRESS, ulReg); + + /* Disable ZV Port 0 */ + ulReg = peekRegisterDWord(ZV0_CAPTURE_CTRL); + ulReg = FIELD_SET(ulReg, ZV0_CAPTURE_CTRL, CAP, DISABLE); + pokeRegisterDWord(ZV0_CAPTURE_CTRL, ulReg); + + /* Disable ZV Port 1 */ + ulReg = peekRegisterDWord(ZV1_CAPTURE_CTRL); + ulReg = FIELD_SET(ulReg, ZV1_CAPTURE_CTRL, CAP, DISABLE); + pokeRegisterDWord(ZV1_CAPTURE_CTRL, ulReg); + + /* Disable ZV Port Power */ + enableZVPort(0); + + /* Disable both DMA Channel 0 and 1 */ + ulReg = peekRegisterDWord(DMA_ABORT_INTERRUPT); + ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_0, ABORT) | + FIELD_SET(0, DMA_ABORT_INTERRUPT, ABORT_1, ABORT); + pokeRegisterDWord(DMA_ABORT_INTERRUPT, ulReg); + } + else + { + enable2DEngine(1); + } + + /* We can add more initialization as needed. */ + + return 0; +} + +/* + * Initialize every chip and environment according to input parameters. + * + * Input: initchip_param_t structure. + * + * Return: 0 (or NO_ERROR) if successful. + * -1 if fail. + */ +long initChipParam(initchip_param_t * pInitParam) +{ + unsigned short deviceId; + unsigned char deviceIndex; + long prevDevice, result = 0; + + /* Check if any SMI VGX family chip exist and alive */ + deviceId = detectDevices(); + if (deviceId == 0) + return (-1); + + /* Save the currently set device. */ + prevDevice = getCurrentDevice(); + + /* Go through every device and do the initialization. */ + for (deviceIndex = 0; deviceIndex < (unsigned char)getNumOfDevices(); deviceIndex++) + { + /* Set the current adapter */ + setCurrentDevice(deviceIndex); + + /* Initialize a single chip. */ + if (initChipParamEx(pInitParam) != 0) + result = -1; + } + + /* Restore the previously set device. */ + setCurrentDevice(prevDevice); + + return result; +} + +/* + * Initialize a single chip with default parameters. + * + * Input: none. + * + * Return: 0 (or NO_ERROR) if successful. + * -1 if fail. + * + * Note: + * Caller needs to call the detectDevice and setCurrentDevice + * to set the device before calling this initChipEx. + */ +//long initChipEx() +_X_EXPORT long ddk502_initHw() +{ + initchip_param_t initParam; + + initParam.powerMode = 0; /* Default to power mode 0 */ + initParam.memClock = MEMORY_DEFAULT; /* Default memory clock to 144MHz */ + initParam.masterClock = MEMORY_DEFAULT/2; /* Default master clock to half of mem clock */ + initParam.setAllEngOff = 0; + + return(initChipParamEx(&initParam)); +} + +/* + * Initialize all available chips with default parameters. + * + * Input: none. + * + * Return: 0 (or NO_ERROR) if successful. + * -1 if fail. + * + * Note: + * This function initializes all the adapters at once. + * To initialize a selected adapters, please use initChipEx + */ +#if 0 +_X_EXPORT long ddk502_initHw() +{ + initchip_param_t initParam; + + initParam.powerMode = 0; /* Default to power mode 0 */ + initParam.memClock = MEMORY_DEFAULT; /* Default memory clock to 144MHz */ + initParam.masterClock = MEMORY_DEFAULT/2; /* Default master clock to half of mem clock */ + initParam.setAllEngOff = 1; + + return(initChipParam(&initParam)); +} +#endif diff --git a/src/ddk502/ddk502_chip.h b/src/ddk502/ddk502_chip.h new file mode 100644 index 0000000..9d1f696 --- /dev/null +++ b/src/ddk502/ddk502_chip.h @@ -0,0 +1,127 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* CHIP.H --- SMI DDK +* This file contains the source code for the mode table. +* +*******************************************************************/ +#ifndef _CHIP_H_ +#define _CHIP_H_ + +#define MEMORY_DEFAULT 144 + +/* This is all the chips recognized by this library */ +typedef enum _logical_chip_type_t +{ + SM_UNKNOWN, + SM501, + SM502, + SM107, + SM718, + SM750, +} +logical_chip_type_t; + + +/* input struct to initChipParam() function */ +typedef struct _initchip_param_t +{ + unsigned short powerMode; /* Use power mode 0 or 1 */ + unsigned short memClock; /* Speed of memory clock in MHz unit + 0 = keep the current clock setting + Others = the new memory clock + */ + unsigned short masterClock; /* Speed of master clock in MHz unit + 0 = keep the current clock setting + Others = the new master clock + */ + unsigned short setAllEngOff; /* 0 = leave all engine state untouched. + 1 = make sure they are off: 2D, Overlay, + video alpha, alpha, hardware cursors + */ + + /* More initialization parameter can be added if needed */ +} +initchip_param_t; + +/* + * This function returns frame buffer memory size in Byte units. + */ +//unsigned long getFrameBufSize(void); +int ddk502_getFrameBufSize(); + +/* + * This function gets the Frame buffer location. + */ +unsigned char getFrameBufLocation(); + +/* + * This function returns the logical chip type defined in chip.h + * It is one of the following: SM501, SM502, SM107, SM718, SM750 + * or SM_UNKNOWN. + */ +logical_chip_type_t getChipType(void); + +/* + * Return a char string name of the current chip. + * It's convenient for application need to display the chip name. + */ +char * getChipTypeString(void); + +/* + * Initialize a single chip and environment according to input parameters. + * + * Input: initchip_param_t structure. + * + * Return: 0 (or NO_ERROR) if successful. + * -1 if fail. + * + * Note: + * Caller needs to call the detectDevice and setCurrentDevice + * to set the device before calling this initChipParamEx. + */ +long initChipParamEx(initchip_param_t * pInitParam); + +/* + * Initialize every chip and environment according to input parameters. + * + * Input: initchip_param_t structure. + * + * Return: 0 (or NO_ERROR) if successful. + * -1 if fail. + */ +long initChipParam(initchip_param_t * pInitParam); + +/* + * Initialize a single chip with default parameters. + * + * Input: none. + * + * Return: 0 (or NO_ERROR) if successful. + * -1 if fail. + * + * Note: + * Caller needs to call the detectDevice and setCurrentDevice + * to set the device before calling this initChipEx. + */ +long initChipEx(); + +/* + * Initialize all available chips with default parameters. + * + * Input: none. + * + * Return: 0 (or NO_ERROR) if successful. + * -1 if fail. + * + * Note: + * This function initializes all the adapters at once. + * To initialize a selected adapters, please use initChipEx + */ +long ddk502_initHw(); + +#endif /* _CHIP_H_ */ diff --git a/src/ddk502/ddk502_clock.c b/src/ddk502/ddk502_clock.c new file mode 100644 index 0000000..eaf116e --- /dev/null +++ b/src/ddk502/ddk502_clock.c @@ -0,0 +1,603 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* CLOCK.C --- Voyager GX DDK +* This file contains source code for the Voyager Family PLL's +* +*******************************************************************/ +#include "ddk502_voyager.h" +#include "ddk502_hardware.h" +#include "ddk502_power.h" +#include "ddk502_clock.h" +#include "ddk502_help.h" + +/* Perform a rounded division. */ +long roundedDiv(long num, long denom) +{ + /* n / d + 1 / 2 = (2n + d) / 2d */ + return (2 * num + denom) / (2 * denom); +} + +/* Absolute differece between two numbers */ +unsigned long absDiff(unsigned long a, unsigned long b) +{ + if ( a >= b ) + return(a - b); + else + return(b - a); +} + +/* + * Given a requested output clock frequency, this function calculates the + * best M & N values for Programmable PLL. + * + * Note: + * 1) SM501 DON'T have programmable PLL at all. + * 2) The programmable PLL is for SM502 panel display only, while CRT display uses divider clock same as SM501. + * 3) SM502 can select between two inputs to the programmable PLL, either input + * can use this function to work out the M & N values. + * + * PLL mechanism: + * 1) The programmable PLL uses this formula to operate: requestClk = inputFreq * M / N . + * + * 2) It has a Divided by 2 feature at it's output because + * for some frequency, it is better to use (requestClk x 2) to work out the M & N values, + * and then divide them by 2 at output. + * + */ +unsigned long calcProgrammablePllCtrl( +unsigned long ulRequestClk, /* Required panel pixel clock in Hz unit */ +pll_value_t *pPLL /* Structure to hold the value to be set in PLL */ +) +{ + unsigned long M, N, diff, pllClk, i; + unsigned long bestDiff = 0xffffffff; /* biggest 32 bit unsigned number */ + + /* Sanity check */ + if (pPLL->inputFreq < MHz(5) || pPLL->inputFreq > MHz(100)) + { + /* Input clock frequency to PLL has not been set properly or out of range. + We have nothing to calculate. */ + return 0; + } + + /* Convert everything in Khz range in order to avoid calculation overflow */ + pPLL->inputFreq /= 1000; + ulRequestClk /= 1000; + + /* Try both ulRequestClk and (ulRequestClk x 2) to work out the best M & N values. */ + for (i=0; i<2; i++) + { + /* N must between 2 and 24, according to design */ + for (N=2; N<25; N++) + { + /* The formula for PLL is ulRequestClk = inputFreq * M / N . + For Voyager family, SMI reference design uses 24000000 Hz (or 24 Mhz) for inputFreq. + Depending on mode, requrestChk ranging from 25 Mhz to 110 Mhz. + In the following steps, we try to work out an M value given the others are known. + To avoid decimal calculation, we use 1000 as multiplier for up to 3 decimal places of accuracy. + */ + M = ulRequestClk * N * 1000 / pPLL->inputFreq; + M = roundedDiv(M, 1000); + + pllClk = pPLL->inputFreq * M / N; /* Calculate the actual clock for a given M & N */ + diff = absDiff(pllClk, ulRequestClk); /* How much are we different from the requirement */ + + if (diff < bestDiff) + { + bestDiff = diff; + + /* Store M and N values */ + pPLL->M = M; + pPLL->N = N; + pPLL->divBy2 = i; + } + } + + /* Try (ulRequestClk x 2) */ + ulRequestClk *= 2; + } + + /* Restore input frequency from Khz to hz unit */ + pPLL->inputFreq *= 1000; + + /* Return actual frequency that the PLL can set */ + return pPLL->divBy2 == 0 ? (pPLL->inputFreq * pPLL->M / pPLL->N) : (pPLL->inputFreq * pPLL->M / pPLL->N / 2); +} + +/* + * Given a requested clock, this function calculates the value of divider clock + * to be put in Power Mode Clock register (0x00003c of SM50x data book). + * + * Input: Pointer to a pll_value_t structure with the following fields set properly: + * 1) clockType + * 2) inputFreq + * + * Output: Fill up the empty fields of structure pll_value_t according to clockType. + * + * Note: + * 1) This is the only clock type for SM501. + * 2) SM502 panel timing can use programmable PLL. + * + */ +unsigned long calcDividerClock( +unsigned long ulRequestClk, /* Requested clock (pixel, memory or master) in Hz unit */ +pll_value_t *pPLL /* Structure to hold the value to be set in Power Mode Clock register */ +) +{ + unsigned long pll1, pll2, pllDiff, dividerClk, diff; + unsigned short divider, divider_limit, shift; + unsigned long best_diff = 0xffffffff; /* biggest 32 bit unsigned number */ + + /* Sanity check */ + if (pPLL->inputFreq < MHz(5) || pPLL->inputFreq > MHz(100)) + { + /* Input clock frequency to PLL has not been set properly or out of range. + We have nothing to calculate. */ + return 0; + } + + /* Convert everything in Khz range in order to avoid overflow */ + pPLL->inputFreq /= 1000; + ulRequestClk /= 1000; + + /* Input clock will pass through two PLL's. One PLL multiply the input frequency + by 12 and the other PLL multiply it by 14. + We need to choose the best fit (either x12 or x14) for the requested frequency. + Note that reference design uses 24 Mhz input clock. + Therefore, output of Pll 1 is 288 Mhz and Pll 2 is 336 Mhz in SMI demo board. + */ + pll1 = pPLL->inputFreq * 12; + pll2 = pPLL->inputFreq * 14; + pllDiff = pll2 - pll1; + + /* For panel clock, try divider 1, 3 and 5, while all others only have 1 and 3 */ + if ( pPLL->clockType == P1XCLK || pPLL->clockType == P2XCLK ) + divider_limit = 5; + else + divider_limit = 3; + + for(dividerClk = pll1; dividerClk <= pll2; dividerClk += pllDiff) + { + for(divider = 1; divider <= divider_limit; divider += 2) + { + /* Try all 8 shift values. */ + for(shift = 0; shift < 8; shift++) + { + /* Calculate difference with requested clock. */ + diff = absDiff((roundedDiv(dividerClk, divider << shift)), ulRequestClk); + + /* If the difference is less than the current, use it. */ + if(diff < best_diff) + { + /* Store best difference. */ + best_diff = diff; + + /* Store clock values. */ + pPLL->dividerClk = dividerClk; + pPLL->divider = divider; + pPLL->shift = shift; + } + } + } + } + + /* Restore frequency from Khz to hz unit */ + pPLL->dividerClk *= 1000; + pPLL->inputFreq *= 1000; + + /* Return actual frequency that the PLL can set */ + return pPLL->dividerClk / (pPLL->divider << pPLL->shift); +} + +/* + * This functions set up the proper values in the PLL structure. + * Input: Requested pixel clock. + * Output: Calculate the values to be put in divider clock or programmable PLL. + * Return: The actual clock that SM50x is able to set up. + * + */ +unsigned long calcPllValue(unsigned long ulPixelClock, pll_value_t *pPLL) +{ + /* Init PLL structure to know states */ + pPLL->dividerClk = 0; + pPLL->divider = 0; + pPLL->shift = 0; + pPLL->M = 0; + pPLL->N = 0; + pPLL->divBy2 = 0; + + if (pPLL->clockType == PANEL_PLL) + { + /* Use the programmable PLL as panel pixel clock (new for SM502) */ + return( calcProgrammablePllCtrl(ulPixelClock, pPLL)); + } + else if (pPLL->clockType == PANEL_PLL_2X) + { + /* Use the programmable PLL to calculate 2X clock for TV */ + return( calcProgrammablePllCtrl(ulPixelClock * 2, pPLL) / 2); + } + else if (pPLL->clockType == P2XCLK || pPLL->clockType == V2XCLK) + { + /* Use 2x clock in the divider clock (valid for both 501 and 502) */ + return( calcDividerClock(ulPixelClock * 2, pPLL) / 2); + } + else + { + /* MCLK, M1XCLK, PIXCLK and V1XCLK comes to here. */ + return( calcDividerClock(ulPixelClock, pPLL)); + } +} + +/* + * Set up the corresponding bit field of the Power Mode X Clock register. + * Note that this function only updates the affected bit fields. Others will be untouched. + * + * Input: Pointer to PLL structure with type and values set up properly. + * Usually, calcPllValue() function will be called before this to calculate the values first. + * + */ +unsigned long formatModeClockReg(pll_value_t *pPLL) +{ + unsigned long ulModeClockReg; + unsigned long ulModeClockField; + + ulModeClockReg = peekRegisterDWord(CURRENT_POWER_CLOCK); + + if (pPLL->clockType==PANEL_PLL) + { + /* If use programmable PLL, disable divider clock and + disable 2X clock. + */ + ulModeClockReg &= FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_DIS) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, SEL) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_SELECT) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_DIVIDER) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_SHIFT); + + ulModeClockField = + FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_DIS, 1X) + | FIELD_SET(0, CURRENT_POWER_CLOCK, SEL, PLL); + } + else if (pPLL->clockType==PANEL_PLL_2X) + { + /* If use programmable PLL x 2, disable divider clock. + */ + ulModeClockReg &= FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_DIS) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, SEL) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_SELECT) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_DIVIDER) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_SHIFT); + + ulModeClockField = + FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_DIS, NORMAL) + | FIELD_SET(0, CURRENT_POWER_CLOCK, SEL, PLL); + } + else if (pPLL->clockType==P2XCLK || pPLL->clockType==P1XCLK) + { + /* Use either 1X or 2X panel divider clock */ + ulModeClockReg &= FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_DIS) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, SEL) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_SELECT) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_DIVIDER) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_SHIFT); + + ulModeClockField = + FIELD_SET(0, CURRENT_POWER_CLOCK, SEL, PXCLK) + | (pPLL->clockType == P2XCLK + ? FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_DIS, NORMAL) + : FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_DIS, 1X)) + | (pPLL->dividerClk == (pPLL->inputFreq * 12) + ? FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_SELECT, 12X) + : FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_SELECT, 14X)) + | (pPLL->divider == 1 + ? FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_DIVIDER, 1) + : (pPLL->divider == 3 + ? FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_DIVIDER, 3) + : FIELD_SET(0, CURRENT_POWER_CLOCK, P2XCLK_DIVIDER, 5))) + | FIELD_VALUE(0, CURRENT_POWER_CLOCK, P2XCLK_SHIFT, pPLL->shift); + + } + else if (pPLL->clockType==V2XCLK || pPLL->clockType==V1XCLK) + { + /* Use either 1x or 2x CRT divider clock */ + ulModeClockReg &= FIELD_CLEAR(CURRENT_POWER_CLOCK, V2XCLK_DIS) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, V2XCLK_SELECT) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, V2XCLK_DIVIDER) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, V2XCLK_SHIFT); + + ulModeClockField = + (pPLL->clockType == V2XCLK + ? FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_DIS, NORMAL) + : FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_DIS, 1X)) + | (pPLL->dividerClk == (pPLL->inputFreq * 12) + ? FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_SELECT, 12X) + : FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_SELECT, 14X)) + | (pPLL->divider == 1 + ? FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_DIVIDER, 1) + : FIELD_SET(0, CURRENT_POWER_CLOCK, V2XCLK_DIVIDER, 3)) + | FIELD_VALUE(0, CURRENT_POWER_CLOCK, V2XCLK_SHIFT, pPLL->shift); + } + else if (pPLL->clockType==MCLK) + { + /* 1X Master Clock */ + ulModeClockReg &= FIELD_CLEAR(CURRENT_POWER_CLOCK, MCLK_SELECT) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, MCLK_DIVIDER) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, MCLK_SHIFT); + + ulModeClockField = + (pPLL->dividerClk == (pPLL->inputFreq * 12) + ? FIELD_SET(0, CURRENT_POWER_CLOCK, MCLK_SELECT, 12X) + : FIELD_SET(0, CURRENT_POWER_CLOCK, MCLK_SELECT, 14X)) + | (pPLL->divider == 1 + ? FIELD_SET(0, CURRENT_POWER_CLOCK, MCLK_DIVIDER, 1) + : FIELD_SET(0, CURRENT_POWER_CLOCK, MCLK_DIVIDER, 3)) + | FIELD_VALUE(0, CURRENT_POWER_CLOCK, MCLK_SHIFT, pPLL->shift); + } + else + { + /* 1X Memroy Clock */ + ulModeClockReg &= FIELD_CLEAR(CURRENT_POWER_CLOCK, M2XCLK_SELECT) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, M2XCLK_DIVIDER) + & FIELD_CLEAR(CURRENT_POWER_CLOCK, M2XCLK_SHIFT); + + ulModeClockField = + (pPLL->dividerClk == (pPLL->inputFreq * 12) + ? FIELD_SET(0, CURRENT_POWER_CLOCK, M2XCLK_SELECT, 12X) + : FIELD_SET(0, CURRENT_POWER_CLOCK, M2XCLK_SELECT, 14X)) + | (pPLL->divider == 1 + ? FIELD_SET(0, CURRENT_POWER_CLOCK, M2XCLK_DIVIDER, 1) + : FIELD_SET(0, CURRENT_POWER_CLOCK, M2XCLK_DIVIDER, 3)) + | FIELD_VALUE(0, CURRENT_POWER_CLOCK, M2XCLK_SHIFT, pPLL->shift); + } + + return(ulModeClockReg | ulModeClockField); +} + +/* + * Set up the corresponding bit field of the programmable PLL register. + * + * Input: Pointer to PLL structure with type and values set up properly. + * Usually, calcPllValue() function will be called before this to calculate the values first. + * + */ +unsigned long formatPllReg(pll_value_t *pPLL) +{ + unsigned long ulPllReg = 0; + + ulPllReg = + FIELD_SET(0, PROGRAMMABLE_PLL_CONTROL, TSTOE, DISABLE) + | FIELD_SET(0, PROGRAMMABLE_PLL_CONTROL, PON, ON) + | FIELD_SET(0, PROGRAMMABLE_PLL_CONTROL, SEL, CRYSTAL) + | FIELD_VALUE(0, PROGRAMMABLE_PLL_CONTROL, K, pPLL->divBy2) + | FIELD_VALUE(0, PROGRAMMABLE_PLL_CONTROL, N, pPLL->N) + | FIELD_VALUE(0, PROGRAMMABLE_PLL_CONTROL, M, pPLL->M); + + return(ulPllReg); +} + +/* + * This function set up the memory clock. + * + * Input: Frequency in MHz unit. + */ +void setMemoryClock(unsigned long megaHz) +{ + pll_value_t pll; + unsigned long ulFreq; + + /* Set up PLL structure */ + pll.inputFreq = DEFAULT_INPUT_CLOCK; + pll.clockType = M1XCLK; /* M1X is memory clock. */ + + ulFreq = MHz(megaHz); + + /* Do not modify the clock if it is not requested (ulFreq == 0) */ + if (ulFreq != 0) + { + calcPllValue(ulFreq, &pll); + setCurrentClock(formatModeClockReg(&pll)); + } +} + +/* + * This function set up the master clock (MCLK). + * + * Input: Frequency in MHz unit. + */ +void setMasterClock(unsigned long megaHz) +{ + pll_value_t pll; + unsigned long ulFreq; + + /* Set up PLL structure */ + pll.inputFreq = DEFAULT_INPUT_CLOCK; + pll.clockType = MCLK; + + ulFreq = MHz(megaHz); + + /* Do not modify the clock if it is not requested (ulFreq == 0) */ + if (ulFreq != 0) + { + calcPllValue(ulFreq, &pll); + setCurrentClock(formatModeClockReg(&pll)); + } +} + +/* + * This function get the Panel Pixel Clock value. + * + * Output: + * The Panel Pixel Clock value in whole number. + */ +unsigned long getPanelClock() +{ + unsigned long value, multiplier, divider, clockValue = 0; + + value = peekRegisterDWord(CURRENT_POWER_CLOCK); + + /* Calculate the multiplier */ + if (FIELD_GET(value, CURRENT_POWER_CLOCK, P2XCLK_DIS) == CURRENT_POWER_CLOCK_P2XCLK_DIS_NORMAL) + multiplier = 2; + else + multiplier = 1; + + /* Different calculation when using programmable PLL and using fixed PLL with frequency divider */ + if (FIELD_GET(value, CURRENT_POWER_CLOCK, SEL) == CURRENT_POWER_CLOCK_SEL_PLL) + { + /* Calculate the PLL value only when the PLL is enabled */ + value = peekRegisterDWord(PROGRAMMABLE_PLL_CONTROL); + if (FIELD_GET(value, PROGRAMMABLE_PLL_CONTROL, PON) == PROGRAMMABLE_PLL_CONTROL_PON_ON) + { + unsigned long mValue, nValue, kValue; + + mValue = FIELD_GET(value, PROGRAMMABLE_PLL_CONTROL, M); + nValue = FIELD_GET(value, PROGRAMMABLE_PLL_CONTROL, N); + if (FIELD_GET(value, PROGRAMMABLE_PLL_CONTROL, K) == PROGRAMMABLE_PLL_CONTROL_K_DISABLE) + kValue = 1; + else + kValue = 2; + + clockValue = (mValue * DEFAULT_INPUT_CLOCK) / (kValue * nValue); + } + } + else + { + /* Calculate the clock value based on the fixed frequency and frequency divider */ + if (FIELD_GET(value, CURRENT_POWER_CLOCK, P2XCLK_SELECT) == + CURRENT_POWER_CLOCK_P2XCLK_SELECT_12X) + clockValue = DEFAULT_INPUT_CLOCK * 12; + else + clockValue = DEFAULT_INPUT_CLOCK * 14; + + switch (FIELD_GET(value, CURRENT_POWER_CLOCK, P2XCLK_DIVIDER)) + { + case CURRENT_POWER_CLOCK_P2XCLK_DIVIDER_1: + divider = 1; + break; + case CURRENT_POWER_CLOCK_P2XCLK_DIVIDER_3: + divider = 3; + break; + case CURRENT_POWER_CLOCK_P2XCLK_DIVIDER_5: + divider = 5; + break; + } + + divider = divider << (FIELD_GET(value, CURRENT_POWER_CLOCK, P2XCLK_SHIFT)); + clockValue = clockValue / divider; + } + + return (clockValue * multiplier); +} + +/* + * This function get the CRT Pixel Clock value. + * + * Output: + * The CRT Pixel Clock value in whole number. + */ +unsigned long getCRTClock() +{ + unsigned long value, multiplier, divider, clockValue = 0; + + value = peekRegisterDWord(CURRENT_POWER_CLOCK); + + /* Calculate the multiplier */ + if (FIELD_GET(value, CURRENT_POWER_CLOCK, V2XCLK_DIS) == CURRENT_POWER_CLOCK_P2XCLK_DIS_NORMAL) + multiplier = 2; + else + multiplier = 1; + + /* Calculate the clock value based on the fixed frequency and frequency divider */ + if (FIELD_GET(value, CURRENT_POWER_CLOCK, V2XCLK_SELECT) == + CURRENT_POWER_CLOCK_V2XCLK_SELECT_12X) + clockValue = DEFAULT_INPUT_CLOCK * 12; + else + clockValue = DEFAULT_INPUT_CLOCK * 14; + + switch (FIELD_GET(value, CURRENT_POWER_CLOCK, V2XCLK_DIVIDER)) + { + case CURRENT_POWER_CLOCK_V2XCLK_DIVIDER_1: + divider = 1; + break; + case CURRENT_POWER_CLOCK_V2XCLK_DIVIDER_3: + divider = 3; + break; + } + + divider = divider << (FIELD_GET(value, CURRENT_POWER_CLOCK, V2XCLK_SHIFT)); + clockValue = clockValue / divider; + + return (clockValue * multiplier); +} + +/* + * This function gets the Master Clock value. + * + * Output: + * The Master Clock value in whole number. + */ +unsigned long getMasterClock() +{ + unsigned long value, divider, clockValue = 0; + + value = peekRegisterDWord(CURRENT_POWER_CLOCK); + + /* Calculate the clock value based on the fixed frequency and frequency divider */ + if (FIELD_GET(value, CURRENT_POWER_CLOCK, MCLK_SELECT) == CURRENT_POWER_CLOCK_MCLK_SELECT_12X) + clockValue = DEFAULT_INPUT_CLOCK * 12; + else + clockValue = DEFAULT_INPUT_CLOCK * 14; + + switch (FIELD_GET(value, CURRENT_POWER_CLOCK, MCLK_DIVIDER)) + { + case CURRENT_POWER_CLOCK_MCLK_DIVIDER_1: + divider = 1; + break; + case CURRENT_POWER_CLOCK_MCLK_DIVIDER_3: + divider = 3; + break; + } + + divider = divider << (FIELD_GET(value, CURRENT_POWER_CLOCK, MCLK_SHIFT)); + + return (clockValue / divider); +} + +/* + * This function gets the Memory Clock value. + * + * Output: + * The Memory Clock value in whole number. + */ +unsigned long getMemoryClock() +{ + unsigned long value, divider, clockValue = 0; + + value = peekRegisterDWord(CURRENT_POWER_CLOCK); + + /* Calculate the clock value based on the fixed frequency and frequency divider */ + if (FIELD_GET(value, CURRENT_POWER_CLOCK, M2XCLK_SELECT) == + CURRENT_POWER_CLOCK_M2XCLK_SELECT_12X) + clockValue = DEFAULT_INPUT_CLOCK * 12; + else + clockValue = DEFAULT_INPUT_CLOCK * 14; + + switch (FIELD_GET(value, CURRENT_POWER_CLOCK, M2XCLK_DIVIDER)) + { + case CURRENT_POWER_CLOCK_M2XCLK_DIVIDER_1: + divider = 1; + break; + case CURRENT_POWER_CLOCK_M2XCLK_DIVIDER_3: + divider = 3; + break; + } + + divider = divider << (FIELD_GET(value, CURRENT_POWER_CLOCK, M2XCLK_SHIFT)); + + return (clockValue / divider); +} diff --git a/src/ddk502/ddk502_clock.h b/src/ddk502/ddk502_clock.h new file mode 100644 index 0000000..6cf6fbc --- /dev/null +++ b/src/ddk502/ddk502_clock.h @@ -0,0 +1,119 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* CLOCK.H --- Voyager GX DDK +* +*******************************************************************/ +#ifndef _CLOCK_H_ +#define _CLOCK_H_ + +#define DEFAULT_INPUT_CLOCK 24000000 /* Default reference clock */ +#define MHz(x) (x*1000000) /* Don't use this macro if x is fraction number */ + +typedef enum _clock_type_t +{ + /* Divider clocks */ + P2XCLK, /* x2 panel divider clock */ + V2XCLK, /* x2 CRT divider clock */ + MCLK, /* x1 master clock */ + M1XCLK, /* x1 memory clock */ + + /* The following are for SM502 and later */ + P1XCLK, /* x1 panel divider clock */ + V1XCLK, /* x1 CRT divider clock */ + PANEL_PLL, /* Programmable panel pixel clock */ + PANEL_PLL_2X, /* For TV, 2X clock is needed */ +} +clock_type_t; + +typedef struct pll_value_t +{ + clock_type_t clockType; + unsigned long inputFreq; /* Input clock frequency to the PLL */ + + /* Use this for all clockType != PANEL_PLL */ + unsigned long dividerClk; /* either x12 or x14 of the input reference crystal */ + unsigned long divider; + unsigned long shift; + + /* Use this when clockType = PANEL_PLL */ + unsigned long M; + unsigned long N; + unsigned long divBy2; +} +pll_value_t; + +/* Perform a rounded division. */ +long roundedDiv(long num, long denom); + +/* Absolute differece between two numbers */ +unsigned long absDiff(unsigned long a, unsigned long b); + +/* + * This functions set up the proper values in the PLL structure. + */ +unsigned long calcPllValue(unsigned long ulPixelClock, pll_value_t *pPLL); + +/* + * Set up the corresponding bit field of the Power Mode X Clock register. + */ +unsigned long formatModeClockReg(pll_value_t *pPLL); + +/* + * Set up the corresponding bit field of the programmable PLL register. + */ +unsigned long formatPllReg(pll_value_t *pPLL); + +/* + * This function get the Panel Pixel Clock value. + * + * Output: + * The Panel Pixel Clock value in whole number. + */ +unsigned long getPanelClock(); + +/* + * This function get the CRT Pixel Clock value. + * + * Output: + * The CRT Pixel Clock value in whole number. + */ +unsigned long getCRTClock(); + +/* + * This function set up the memory clock. + * + * Input: Frequency in MHz unit. + */ +void setMemoryClock(unsigned long megaHz); + +/* + * This function set up the master clock (MCLK). + * + * Input: Frequency in MHz unit. + */ +void setMasterClock(unsigned long megaHz); + +/* + * getMasterClock + * This function gets the Master Clock value. + * + * Output: + * The Master Clock value in whole number. + */ +unsigned long getMasterClock(); + +/* + * getMemoryClock + * This function gets the Memory Clock value. + * + * Output: + * The Memory Clock value in whole number. + */ +unsigned long getMemoryClock(); + +#endif /*_CLOCK_H_*/ diff --git a/src/ddk502/ddk502_ddkdebug.c b/src/ddk502/ddk502_ddkdebug.c new file mode 100644 index 0000000..48d0a79 --- /dev/null +++ b/src/ddk502/ddk502_ddkdebug.c @@ -0,0 +1,241 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* ddkdebug.c --- DDK Debug Tool +* This file contains the source code for the SMI DDK Debugging. +* +*******************************************************************/ +#include +#include +#include +#include "ddk502_ddkdebug.h" +//#include "os.h" + +#ifdef DDKDEBUG + +/* COM Port index that is used for the debugging */ +#define DEBUG_COM_PORT_INDEX 0 + +/* Buffer length */ +#define BUFFER_LENGTH 1024 + +static ddk_debug_output_t gDebugOutput = DEBUG_OUTPUT_SCREEN; +static unsigned long gDebugLevelMask = 0; +static FILE *gFileHandle = (FILE *)0; +static short gCOMInit = 0; +static char gOutputFile[13] = "ddkdebug.log"; +static unsigned char gEnableDebugMessage; + +/* + * This function initializes the debug print out system. + * + * Input: + * debugOutput - Output where to print out the debug. It could be + * screen, file, or serial port. + * debugLevel - Debugging level + */ +void ddkDebugPrintInit(ddk_debug_output_t debugOutput, unsigned long debugLevelMask) +{ + gDebugOutput = debugOutput; + gDebugLevelMask = debugLevelMask; + gEnableDebugMessage = 1; + + /* Initialize the output media as necessary */ + switch (gDebugOutput) + { + default: + case DEBUG_OUTPUT_SCREEN: + /* Do nothing */ + break; + case DEBUG_OUTPUT_FILE: + /* Close the previous log file if opened */ + if (gFileHandle != (FILE *)0) + fclose(gFileHandle); + + /* Create a LOG file */ + gFileHandle = fopen((const char *)gOutputFile, "w"); + if (gFileHandle == NULL) + ddkDebugPrint(0, "Can not open log file\n"); + break; + case DEBUG_OUTPUT_SERIAL: + /* Open COM Port */ + if (comInit(DEBUG_COM_PORT_INDEX, + COM_9600, + DATA_SIZE_8, + PARITY_NONE, + STOP_BIT_1, + FLOW_CONTROL_NONE) == 0) + gCOMInit = 1; + else + ddkDebugPrint(0, "Can not open COM Port\n"); + break; + } +} + +/* + * This function specifies the new debug output file. + * + * Input: + * pDebugOutputFile - Debug output filename. + */ +void debugOutputFile(char *pDebugOutputFile) +{ + if (pDebugOutputFile != 0) + memcpy(gOutputFile, pDebugOutputFile, sizeof(gOutputFile)); +} + +/* + * This function enable or disable the debug message. + * + * Input: + * enableDebugMessage - Enable/disable the debug message + * 0 - Disable Debug Message + * 1 - Enable Debug Message + * + * Note: + * This function can be used to enable/disable the debug message + * at certain point of software, so that the debug messages, that + * are printed, are only the important ones. + */ +void ddkDebugEnable(unsigned char enableDebugMessage) +{ + gEnableDebugMessage = enableDebugMessage; +} + +/* + * This function prints out the formatted string. + * + * Input: + * debugLevel - The level of the debug of which the message is intended for. + * pszFormat - Format of the printed message + */ +void ddkDebugPrint(unsigned long debugLevel, const char* pszFormat, ...) +{ + static char pszPrintBuffer[BUFFER_LENGTH]; + unsigned long nWritten; + + /* Do not print any messages when this variable is flagged. */ + if (gEnableDebugMessage == 0) + return; + + /* Only process any ddkDebugPrint with the debugLevel less or equal the preset + debug Level during the init */ + if (((debugLevel & gDebugLevelMask) != 0) || (debugLevel == 0)) + { + /* Format the string */ + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + nWritten = (unsigned long) vsnprintf(pszPrintBuffer, BUFFER_LENGTH - 1, pszFormat, arg_ptr); + va_end(arg_ptr); + + /* Check for buffer overflow */ + if (nWritten == (unsigned long)(-1)) + { + ddkDebugPrint(0, "ddkDebugPrint(): BUFFER OVERFLOW DETECTED!!!\r\n" \ + "MAX STRING LENGTH = %d\n", BUFFER_LENGTH); + return; + } + + /* Print out the data */ + switch (gDebugOutput) + { + default: + case DEBUG_OUTPUT_SCREEN: + printf(pszPrintBuffer); + + /* + * Flush the stdout before the getch function. Otherwise the + * previous printf will not be displayed correctly sometimes. + */ + fflush(stdout); + break; + case DEBUG_OUTPUT_FILE: + /* Print out the message to the log file */ + if (gFileHandle != NULL) + { + fprintf(gFileHandle, pszPrintBuffer); + fflush(gFileHandle); + } + break; + case DEBUG_OUTPUT_SERIAL: + /* Send the data out to the COM Port */ + if (gCOMInit) + { +#if 1 + char *pString1, *pString2; + unsigned long length; + char linefeed = '\r'; + + length = 0; + pString1 = pszPrintBuffer; + while(nWritten) + { + /* Search for all '\n' and add '\r' so that the serial port can display correctly. */ + pString2 = strchr(pString1, '\n'); + if (pString2 != (char *)0) + { + length = pString2 - pString1 + 1; + + /* Check the previous character and the next character */ + if ((*(pString2 - 1) != '\r') && (*(pString2 + 1) != '\r')) + { + /* Write the buffer with the '\r' */ + comWrite(pString1, length); + comWrite(&linefeed, 1); + } + else + comWrite(pString1, length); + + /* Adjust the nWritten */ + nWritten -= length; + + /* Adjust the new string pointer */ + pString1 = pString2 + 1; + } + else + { + comWrite(pString1, nWritten); + nWritten = 0; + } + } +#else + comWrite(pszPrintBuffer, nWritten); +#endif + } + break; + } + } +} + +/* + * This function cleans up (such as closing the debug file, etc...) when + * exiting the debug module. + */ +void ddkDebugPrintExit() +{ + /* Clean up the debug print module */ + switch (gDebugOutput) + { + default: + case DEBUG_OUTPUT_SCREEN: + /* Do nothing */ + break; + case DEBUG_OUTPUT_FILE: + /* Close the log file */ + if (gFileHandle != (FILE *)0) + fclose(gFileHandle); + break; + case DEBUG_OUTPUT_SERIAL: + comClose(); + break; + } +} + +#endif + + + diff --git a/src/ddk502/ddk502_ddkdebug.h b/src/ddk502/ddk502_ddkdebug.h new file mode 100644 index 0000000..eb3b7bf --- /dev/null +++ b/src/ddk502/ddk502_ddkdebug.h @@ -0,0 +1,154 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* ddkdebug.h --- DDK Debug module +* This file contains the definitions for the SMI DDK debugging. +* +*******************************************************************/ +#ifndef _DDKDEBUG_H_ +#define _DDKDEBUG_H_ + +#ifdef DDKDEBUG + +/********************* + * Definition + *********************/ + +/* Debug Print Level definitions */ +/* Bit 16 ~ 31 are used by the library. Bit 0 ~ 15 can be used by application */ +#define ERROR_LEVEL 0x00010000 +#define WARNING_LEVEL 0x00020000 +#define INIT_LEVEL 0x00040000 +#define DISPLAY_LEVEL 0x00080000 +#define DMA_LEVEL 0x00100000 +#define DE_LEVEL 0x00200000 +#define CAPTURE_LEVEL 0x00400000 +#define SSP_LEVEL 0x00800000 +#define RESERVED8_LEVEL 0x01000000 +#define RESERVED9_LEVEL 0x02000000 +#define RESERVED10_LEVEL 0x04000000 +#define RESERVED11_LEVEL 0x08000000 +#define RESERVED12_LEVEL 0x10000000 +#define RESERVED13_LEVEL 0x20000000 +#define RESERVED14_LEVEL 0x40000000 +#define RESERVED15_LEVEL 0x80000000 + +#define SYSTEM_LEVEL_MASK 0xFFFF0000 +#define APPLICATION_LEVEL_MASK 0x0000FFFF + +/********************* + * Structure + *********************/ +typedef enum _ddk_debug_output_t +{ + DEBUG_OUTPUT_SCREEN = 0, + DEBUG_OUTPUT_FILE, + DEBUG_OUTPUT_SERIAL +} +ddk_debug_output_t; + +/********************* + * MACROS + *********************/ + +/* This function has to be called before calling other DEBUGPIRNT functions. */ +#define DDKDEBUGPRINTINIT(debugOutput, debugLevelMask) \ + ddkDebugPrintInit(debugOutput, debugLevelMask) + +/* This function has to be called before calling other DEBUGPIRNT functions. */ +#define DEBUGOUTPUTFILE(debugOutputFileName) \ + debugOutputFile(debugOutputFileName) + +/* This function enable or disable the debug message. + * Note: + * This function can be used to enable/disable the debug message + * at certain point of software, so that the debug messages, that + * are printed, are only the important ones. + */ +#define DDKDEBUGENABLE(arg) \ + ddkDebugEnable(arg) + +/* Calling the DDKDEBUGPRINT needs to have the arg to be enclosed with + two of open and close brackets. + Example: + DDKDEBUGPRINT(("Hello World: %s\n", pszString)); + */ +#define DDKDEBUGPRINT(arg) \ + ddkDebugPrint arg + +/* This function has to be called when exiting the application. + It is necessary to clean up the debug module. */ +#define DDKDEBUGPRINTEXIT() \ + ddkDebugPrintExit() + +/********************* + * Function prototype + *********************/ + +/* + * This function initializes the debug print out system. + * + * Input: + * debugOutput - Output where to print out the debug. It could be + * screen, file, or serial port. + * debugLevel - Debugging level + */ +void ddkDebugPrintInit(ddk_debug_output_t debugOutput, unsigned long debugLevelMask); + +/* + * This function specifies the new debug output file. + * + * Input: + * pDebugOutputFile - Debug output filename. + */ +void debugOutputFile(char *pDebugOutputFile); + +/* + * This function enable or disable the debug message. + * + * Input: + * enableDebugMessage - Enable/disable the debug message + * 0 - Disable Debug Message + * 1 - Enable Debug Message + * + * Note: + * This function can be used to enable/disable the debug message + * at certain point of software, so that the debug messages, that + * are printed, are only the important ones. + */ +void ddkDebugEnable(unsigned char enableDebugMessage); + +/* + * This function prints out the formatted string. + * + * Input: + * debugLevel - The level of the debug of which the message is intended for. + * pszFormat - Format of the printed message + */ +void ddkDebugPrint(unsigned long debugLevel, const char* pszFormat, ...); + +/* + * This function cleans up (such as closing the debug file, etc...) when + * exiting the debug module. + */ +void ddkDebugPrintExit(); + +#else + +/* + * If there is no DEBUG definition, then treat the macro as an empty macro. + * Therefore all the debug print will be stripped out. + */ +#define DDKDEBUGPRINTINIT(debugOutput, debugLevelMask) +#define DDKDEBUGENABLE(arg) +#define DDKDEBUGPRINT(arg) +#define DDKDEBUGPRINTEXIT() +#define DDKDEBUGOUTPUTFILE(debugOutputFileName) + +#endif + +#endif /* _DDKDEBUG_H_ */ diff --git a/src/ddk502/ddk502_display.c b/src/ddk502/ddk502_display.c new file mode 100644 index 0000000..e1145d6 --- /dev/null +++ b/src/ddk502/ddk502_display.c @@ -0,0 +1,414 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* DISPLAY.C --- Voyager GX SDK +* This file contains the source code for the panel and CRT functions. +* +*******************************************************************/ +#include "../smi_common.h" +#include "ddk502_voyager.h" +#include "ddk502_hardware.h" +#include "ddk502_display.h" +#include "ddk502_mode.h" +#include "ddk502_power.h" + +/* + * Use panel vertical sync as time delay function. + * Input: Number of vertical sync to wait. + */ +void panelWaitVerticalSync(unsigned long vsync_count) +{ + unsigned long status; + + /* Do not wait when the display control is already off. This will prevent + the software to wait forever. */ + if (FIELD_GET(peekRegisterDWord(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, TIMING) == + PANEL_DISPLAY_CTRL_TIMING_DISABLE) + { + return; + } + + while (vsync_count-- > 0) + { + /* Wait for end of vsync. */ + do + { + status = FIELD_GET(peekRegisterDWord(CMD_INTPR_STATUS), + CMD_INTPR_STATUS, + PANEL_SYNC); + } + while (status == CMD_INTPR_STATUS_PANEL_SYNC_ACTIVE); + + /* Wait for start of vsync. */ + do + { + status = FIELD_GET(peekRegisterDWord(CMD_INTPR_STATUS), + CMD_INTPR_STATUS, + PANEL_SYNC); + } + while (status == CMD_INTPR_STATUS_PANEL_SYNC_INACTIVE); + } +} + +/* + * Use crt vertical sync as time delay function. + * Input: Number of vertical sync to wait. + */ +void crtWaitVerticalSync(unsigned long vsync_count) +{ + unsigned long status; + + /* Do not wait when the display control is already off. This will prevent + the software to wait forever. */ + if (FIELD_GET(peekRegisterDWord(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, TIMING) == + CRT_DISPLAY_CTRL_TIMING_DISABLE) + { + return; + } + + while (vsync_count-- > 0) + { + /* Wait for end of vsync. */ + do + { + status = FIELD_GET(peekRegisterDWord(CMD_INTPR_STATUS), + CMD_INTPR_STATUS, + CRT_SYNC); + } + while (status == CMD_INTPR_STATUS_CRT_SYNC_ACTIVE); + + /* Wait for start of vsync. */ + do + { + status = FIELD_GET(peekRegisterDWord(CMD_INTPR_STATUS), + CMD_INTPR_STATUS, + CRT_SYNC); + } + while (status == CMD_INTPR_STATUS_CRT_SYNC_INACTIVE); + } +} + +/* + * Use vertical sync as time delay function. + * Input: + * dispControl - Display Control (either panel or crt) + * vsync_count - Number of vertical sync to wait. + * + * Note: + * This function is waiting for the next vertical sync. + */ +void waitNextVerticalSync(disp_control_t dispControl, unsigned long vsync_count) +{ + if (dispControl == CRT_CTRL) + crtWaitVerticalSync(vsync_count); + else + panelWaitVerticalSync(vsync_count); +} + +/* + * Use panel vertical sync line as time delay function. + * This function does not wait for the next VSync. Instead, it will wait + * until the current line reaches the Vertical Sync line. + * + * Input: display control (PANEL_CTRL or CRT_CTRL) + */ +void waitVSyncLine(disp_control_t dispControl) +{ + unsigned long value; + mode_parameter_t modeParam; + + /* Get the current mode parameter of the specific display control */ + modeParam = getCurrentModeParam(dispControl); + + do + { + if (dispControl == CRT_CTRL) + value = FIELD_GET(peekRegisterDWord(CRT_CURRENT_LINE), CRT_CURRENT_LINE, LINE) + 1; + else + value = FIELD_GET(peekRegisterDWord(PANEL_CURRENT_LINE), PANEL_CURRENT_LINE, LINE) + 1; + } + while (value < modeParam.vertical_sync_start); +} + +/* + * This functions uses software sequence to turn on/off the panel. + * + */ +_X_EXPORT void ddk502_swPanelPowerSequence(disp_state_t dispState, int vsync_delay) +{ + unsigned long panelControl = peekRegisterDWord(PANEL_DISPLAY_CTRL); + + if (dispState == DISP_ON) + { + /* Turn on FPVDDEN. */ + panelControl = FIELD_SET(panelControl, + PANEL_DISPLAY_CTRL, FPVDDEN, HIGH); + pokeRegisterDWord(PANEL_DISPLAY_CTRL, panelControl); + panelWaitVerticalSync(vsync_delay); + + /* Turn on FPDATA. */ + panelControl = FIELD_SET(panelControl, + PANEL_DISPLAY_CTRL, DATA, ENABLE); + pokeRegisterDWord(PANEL_DISPLAY_CTRL, panelControl); + panelWaitVerticalSync(vsync_delay); + + /* Turn on FPVBIAS. */ + panelControl = FIELD_SET(panelControl, + PANEL_DISPLAY_CTRL, VBIASEN, HIGH); + pokeRegisterDWord(PANEL_DISPLAY_CTRL, panelControl); + panelWaitVerticalSync(vsync_delay); + + /* Turn on FPEN. */ + panelControl = FIELD_SET(panelControl, + PANEL_DISPLAY_CTRL, FPEN, HIGH); + pokeRegisterDWord(PANEL_DISPLAY_CTRL, panelControl); + } + + else + { + /* Turn off FPEN. */ + panelControl = FIELD_SET(panelControl, + PANEL_DISPLAY_CTRL, FPEN, LOW); + pokeRegisterDWord(PANEL_DISPLAY_CTRL, panelControl); + panelWaitVerticalSync(vsync_delay); + + /* Turn off FPVBIASEN. */ + panelControl = FIELD_SET(panelControl, + PANEL_DISPLAY_CTRL, VBIASEN, LOW); + pokeRegisterDWord(PANEL_DISPLAY_CTRL, panelControl); + panelWaitVerticalSync(vsync_delay); + + /* Turn off FPDATA. */ + panelControl = FIELD_SET(panelControl, + PANEL_DISPLAY_CTRL, DATA, DISABLE); + pokeRegisterDWord(PANEL_DISPLAY_CTRL, panelControl); + panelWaitVerticalSync(vsync_delay); + + /* Turn off FPVDDEN. */ + panelControl = FIELD_SET(panelControl, + PANEL_DISPLAY_CTRL, FPVDDEN, LOW); + pokeRegisterDWord(PANEL_DISPLAY_CTRL, panelControl); + } +} + +/* + * This function turns on/off the DAC for CRT display control. + * Input: On or off + */ +void setDAC(disp_state_t state) +{ + if (state == DISP_ON) + { + pokeRegisterDWord(MISC_CTRL, FIELD_SET(peekRegisterDWord(MISC_CTRL), + MISC_CTRL, + DAC_POWER, + ENABLE)); + } + else + { + pokeRegisterDWord(MISC_CTRL, FIELD_SET(peekRegisterDWord(MISC_CTRL), + MISC_CTRL, + DAC_POWER, + DISABLE)); + } +} + +/* + * This function turns on/off the display control. + * Currently, it for CRT and Panel controls only. + * Input: Panel or CRT, or ... + * On or Off. + * + * This function manipulate the physical display channels + * and devices. + * + * Note: + * Turning on/off the timing and the plane requires programming sequence. + * The plane can not be changed without turning on the timing. However, + * changing the plane has no effect when the timing (clock) is off. Below, + * is the description of the timing and plane combination setting. + * + * +-----------+-----------+-----------------------------------------------+ + * | Timing | Plane | Description | + * +-----------+-----------+-----------------------------------------------+ + * | ON | OFF | no Display but clock is on (consume power) | + * | ON | ON | normal display | + * | OFF | OFF | no display and no clock (power down) | + * | OFF | ON | no display and no clock (same as power down) | + * +-----------+-----------+-----------------------------------------------+ + */ +void setDisplayControl(disp_control_t dispControl, disp_state_t dispState) +{ + unsigned long ulDisplayCtrlReg; + + if (dispControl == PANEL_CTRL) + { + ulDisplayCtrlReg = peekRegisterDWord(PANEL_DISPLAY_CTRL); + + /* Turn on/off the Panel display control */ + if (dispState == DISP_ON) + { + /* Timing should be enabled first before enabling the panel because changing at the + same time does not guarantee that the plane will also enabled or disabled. + */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, PANEL_DISPLAY_CTRL, TIMING, ENABLE); + pokeRegisterDWord(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, PANEL_DISPLAY_CTRL, PLANE, ENABLE); + } + else + { + /* When turning off, there is no rule on the programming sequence since whenever the + clock is off, then it does not matter whether the plane is enabled or disabled + */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, PANEL_DISPLAY_CTRL, PLANE, DISABLE); + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, PANEL_DISPLAY_CTRL, TIMING, DISABLE); + } + + pokeRegisterDWord(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + } + else /* CRT */ + { + ulDisplayCtrlReg = peekRegisterDWord(CRT_DISPLAY_CTRL); + + if (dispState == DISP_ON) + { + /* Timing should be enabled first before enabling the panel because changing at the + same time does not guarantee that the plane will also enabled or disabled. + */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, CRT_DISPLAY_CTRL, TIMING, ENABLE); + pokeRegisterDWord(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, CRT_DISPLAY_CTRL, PLANE, ENABLE); + } + else + { + /* When turning off, there is no rule on the programming sequence since whenever the + clock is off, then it does not matter whether the plane is enabled or disabled + */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, CRT_DISPLAY_CTRL, PLANE, DISABLE); + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, CRT_DISPLAY_CTRL, TIMING, DISABLE); + } + pokeRegisterDWord(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + } +} + +/* This function set the display path together with the HSync and VSync. */ +void setCRTPath(disp_control_t dispControl) +{ + unsigned long crtControl; + mode_parameter_t modeParam; + + /* Get the current mode parameter of the specific display control */ + modeParam = getCurrentModeParam(dispControl); + + crtControl = peekRegisterDWord(CRT_DISPLAY_CTRL); + + /* Adjust the VSync polarity */ + if (modeParam.vertical_sync_polarity == POS) + crtControl = FIELD_SET(crtControl, CRT_DISPLAY_CTRL, VSYNC_PHASE, ACTIVE_HIGH); + else + crtControl = FIELD_SET(crtControl, CRT_DISPLAY_CTRL, VSYNC_PHASE, ACTIVE_LOW); + + /* Adjust the HSync polarity */ + if (modeParam.horizontal_sync_polarity == POS) + crtControl = FIELD_SET(crtControl, CRT_DISPLAY_CTRL, HSYNC_PHASE, ACTIVE_HIGH); + else + crtControl = FIELD_SET(crtControl, CRT_DISPLAY_CTRL, HSYNC_PHASE, ACTIVE_LOW); + + /* Adjust the CRT Data path either to use Panel control or CRT control. */ + if (dispControl == PANEL_CTRL) + crtControl = FIELD_SET(crtControl, CRT_DISPLAY_CTRL, SELECT, PANEL); + else + crtControl = FIELD_SET(crtControl, CRT_DISPLAY_CTRL, SELECT, CRT); + + pokeRegisterDWord(CRT_DISPLAY_CTRL, crtControl); +} + +/* + * This function is an example showing how to set up + * PANEL only, CRT only , SIMUL or DUAL with the following functions: + * setDisplayControl() + * swPanelPowerSequence() + * setDAC() + * setDPMS() + * + * The output is called logical because it is independent of physical implementation. + * For example, CRT only mode is not using the internal CRT control. It uses the + * Panel Control with its output directed to CRT DAC. + */ +_X_EXPORT void setLogicalDispOutput(disp_output_t output) +{ + unsigned long ulReg; + + switch (output) + { + case NO_DISPLAY: + + /* In here, all the display device has to be turned off first before the + the display control. */ + ddk502_swPanelPowerSequence(DISP_OFF, 4); /* Turn off Panel */ + + setDAC(DISP_OFF); /* Turn off DAC */ + ddk502_setDPMS(DPMS_OFF); /* Turn off DPMS */ + + setDisplayControl(PANEL_CTRL, DISP_OFF); /* Turn off Panel Control */ + setDisplayControl(CRT_CTRL, DISP_OFF); /* Turn off CRT control */ + + break; + + case PANEL_ONLY: + setDisplayControl(PANEL_CTRL, DISP_ON); /* Turn on Panel Control */ + ddk502_swPanelPowerSequence(DISP_ON, 4); /* Turn on Panel */ + + setDisplayControl(CRT_CTRL, DISP_OFF); /* Turn off CRT control */ + setDAC(DISP_OFF); /* Turn off DAC */ + ddk502_setDPMS(DPMS_OFF); /* Turn off DPMS */ + + break; + + case CRT_ONLY: + setDisplayControl(PANEL_CTRL, DISP_ON); /* Turn on Panel Control */ + ddk502_swPanelPowerSequence(DISP_OFF, 4); /* Turn off Panel */ + + setDisplayControl(CRT_CTRL, DISP_OFF); /* Turn off CRT control */ + setDAC(DISP_ON); /* Turn on DAC */ + ddk502_setDPMS(DPMS_ON); /* Turn on DPMS to drive CRT */ + + /* Set up CRT control to use data from panel control */ + setCRTPath(PANEL_CTRL); + + break; + + case PANEL_CRT_SIMUL: /* Panel and CRT same content */ + setDisplayControl(PANEL_CTRL, DISP_ON); /* Turn on Panel Control */ + ddk502_swPanelPowerSequence(DISP_ON, 4); /* Turn on Panel */ + + setDisplayControl(CRT_CTRL, DISP_OFF); /* Turn off CRT control */ + setDAC(DISP_ON); /* Turn on DAC */ + ddk502_setDPMS(DPMS_ON); /* Turn on DPMS to drive CRT and TV */ + + /* Set up CRT control to use data from panel control */ + setCRTPath(PANEL_CTRL); + + break; + + case PANEL_CRT_DUAL: /* Panel and CRT different content */ + setDisplayControl(PANEL_CTRL, DISP_ON); /* Turn on panel control */ + ddk502_swPanelPowerSequence(DISP_ON, 4); /* Turn on Panel */ + + /* If previous state is SIMUL or CRT only, just be sure the + data direction bit of CRT channel is correct + */ + setCRTPath(CRT_CTRL); + + setDisplayControl(CRT_CTRL, DISP_ON); /* Turn on CRT control */ + setDAC(DISP_ON); /* Turn on DAC */ + ddk502_setDPMS(DPMS_ON); /* Turn on DPMS to drive CRT */ + break; + } +} diff --git a/src/ddk502/ddk502_display.h b/src/ddk502/ddk502_display.h new file mode 100644 index 0000000..60b4c20 --- /dev/null +++ b/src/ddk502/ddk502_display.h @@ -0,0 +1,95 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* DISPLAY.H --- Voyager GX SDK +* +*******************************************************************/ +#ifndef _DISPLAY_H_ +#define _DISPLAY_H_ + +#include "xf86Module.h" + +typedef enum _disp_control_t +{ + PANEL_CTRL = 0, + CRT_CTRL = 1, + /* Think of defining other display control here: Video, alpha, etc. */ +} +disp_control_t; + +typedef enum _disp_state_t +{ + DISP_OFF = 0, + DISP_ON = 1, +} +disp_state_t; + +typedef enum _disp_output_t +{ + NO_DISPLAY, /* All display off. */ + PANEL_ONLY, + CRT_ONLY, + PANEL_CRT_SIMUL, /* Both Panel and CRT displaying the same content. */ + PANEL_CRT_DUAL, /* Panel and CRT displaying different contents. */ +} +disp_output_t; + +/* + * This functions sets the CRT Path. + */ +void setCRTPath(disp_control_t dispControl); + +/* + * This functions uses software sequence to turn on/off the panel. + */ +void ddk502_swPanelPowerSequence(disp_state_t dispState, int vsync_delay); + +/* + * This function turns on/off the DAC for CRT display control. + * Input: On or off + */ +void setDAC(disp_state_t state); + +/* + * This function turns on/off the display control. + * Currently, it for CRT and Panel controls only. + * Input: Panel or CRT, or ... + * On or Off. + */ +void setDisplayControl(disp_control_t dispControl, disp_state_t dispState); + +/* + * This function is an example showing how to set up + * PANEL only, CRT only , SIMUL or DUAL with the following functions: + * setDisplayControl() + * swPanelPowerSequence() + * setDAC() + * setDPMS() + */ +_X_EXPORT void setLogicalDispOutput(disp_output_t output); + +/* + * Use vertical sync as time delay function. + * Input: + * dispControl - Display Control (PANEL_CTRL or CRT_CTRL) + * vsync_count - Number of vertical sync to wait. + * + * Note: + * This function is waiting for the next vertical sync. + */ +void waitNextVerticalSync(disp_control_t dispControl, unsigned long vsync_count); + +/* + * Use panel vertical sync line as time delay function. + * This function does not wait for the next VSync. Instead, it will wait + * until the current line reaches the Vertical Sync line. + * + * Input: display control (PANEL_CTRL or CRT_CTRL) + */ +void waitVSyncLine(disp_control_t dispControl); + +#endif /* _DISPLAY_H_ */ diff --git a/src/ddk502/ddk502_hardware.c b/src/ddk502/ddk502_hardware.c new file mode 100644 index 0000000..352d9d9 --- /dev/null +++ b/src/ddk502/ddk502_hardware.c @@ -0,0 +1,458 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* Hardware.c --- Voyager GX SDK +* This file contains the source code for the hardware. +* +*******************************************************************/ +//#include "ddk502_os.h" +#include "ddk502_hardware.h" + +#include "ddk502_ddkdebug.h" + +/* Table of all the device ID's supported by this library */ +static unsigned short gwDeviceIdTable[] = { +0x0501, +0}; + +/* Use Voyager PCI ID as default, but it may be changed by + detectDevice() if it is called */ +static unsigned short gwDeviceId = 0x0501; + +/* Total number of devices with the same ID in the system. + Use 1 as default. +*/ +static unsigned short gwNumOfDev = 1; + +/* Current device in use. + If there is only ONE device, it's always device 0. + If gwNumDev > 1, user need to set device 0, device 1, device 2, etc.. + The purpose is using it control multiple devices of the same ID, if any. +*/ +static unsigned short gwCurDev = 0; + +static unsigned char *frameBufBase[MAX_SMI_DEVICE] = {0, 0, 0, 0}; +static unsigned char *mmioBase[MAX_SMI_DEVICE] = {0, 0, 0, 0}; +static unsigned char *frameBufPhysicalBase[MAX_SMI_DEVICE] = {0, 0, 0, 0}; + +/* Get revision ID from the given Vendor ID, device ID, and device Number */ +unsigned char getRevisionId( + unsigned short vendorId, /* PCI vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum /* If more than one device in system, device number are ordered as 0, 1, 2,... */ +) +{ + return readPCIByte(vendorId, deviceId, deviceNum, 0x08); +} + +/* + * Detect if a specific device exist in the system. + * If exist, enable it on the PCI bus. + * Return: 0 if device found + * -1 if no device. + */ +long enableDevice( + unsigned short vendorId, /* PCI vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum /* If more than one device in system, device number are ordered as 0, 1, 2,... */ +) +{ + unsigned short value; + unsigned char control; + + /* Detect SMI device */ + value = readPCIWord(vendorId, deviceId, deviceNum, 0x00); + if (value != vendorId) + return -1; + + /* Enable the PCI device, if not yet enabled */ + control = readPCIByte(vendorId, deviceId, deviceNum, 0x04); + if ((control & 0x1E) != 0x1E) + writePCIByte(vendorId, deviceId, deviceNum, 0x04, control | 0x1E); + + return 0; +} + +/* + * Get a pointer to the base of Memory Mapped IO space. + * + * Return: A pointer to base of MMIO. + * NULL pointer if fail. + */ +void *getMmioBase( + unsigned short vendorId, /* PCI vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum /* If more than one device in system, device number are ordered as 0, 1, 2,... */ +) +{ + unsigned long physicalAddr; + + if (enableDevice(vendorId, deviceId, deviceNum) == -1) + return (void *)0; + + /* Get MMIO physical address */ + physicalAddr = readPCIDword(vendorId, deviceId, deviceNum, 0x14); + + DDKDEBUGPRINT((INIT_LEVEL, "Mmio Physical Addr: %08x\n", physicalAddr)); + if (physicalAddr == (-1)) + return (void *)0; + + /* Map it into the address space. */ + return mapPhysicalAddress((void*)physicalAddr, SM50X_PCI_ALLOC_MMIO_SIZE); + // return (x); +} + +/* + * Get a pointer to the base of physical video memory. This can be used for DMA transfer. + * In DOS, the physical and the logical address most likely are the same. + * Return: A pointer to base of physical video memory. + * NULL pointer if fail. + */ +void *getPhysicalMemoryBase( + unsigned short vendorId, /* PCI vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum /* If more than one device in system, device number are ordered as 0, 1, 2,... */ +) +{ + unsigned long physicalAddr; + + if (enableDevice(vendorId, deviceId, deviceNum) == -1) + return (void *)0; + + /* + * Access frame buffer through the PCI linear address. + */ + + /* Get frame buffer physical address */ + physicalAddr = readPCIDword(vendorId, deviceId, deviceNum, 0x10); + + /* + * In a memory bar (Frame buffer), bit 3 to bit 0 are used as the base + * address information, therefore, we should mask this out and set them + * to zero. + */ + physicalAddr &= ~0x0000000F; + + DDKDEBUGPRINT((INIT_LEVEL, "Memory Physical Addr: %08x\n", physicalAddr)); + if (physicalAddr == (-1)) + return (void *)0; + + return ((void *)physicalAddr); +} + +/* + * Get a pointer to the base of video memory (or frame buffer). + * + * Return: A pointer to base of video memory. + * NULL pointer if fail. + */ +void *getMemoryBase( + unsigned short vendorId, /* PCI vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum /* If more than one device in system, device number are ordered as 0, 1, 2,... */ +) +{ + void *physicalAddr; + + physicalAddr = getPhysicalMemoryBase(vendorId, deviceId, deviceNum); + if (physicalAddr == (void *)0) + return (void *)0; + + /* Map it into the address space */ + return (mapPhysicalAddress(physicalAddr, SM50X_PCI_ALLOC_MEMORY_SIZE)); +} + +/* + * Get the physical address of an offset location in frame buffer. + * In DOS, the physical and the logical address most likely are the same. + * Return: A valid address if success. + * NULL address if fail. + */ +void *getPhysicalAddress(unsigned long offset /* Offset from base of physical frame buffer */) +{ + if (frameBufPhysicalBase[gwCurDev] == (unsigned char *)0) + { + frameBufPhysicalBase[gwCurDev] = (unsigned char *)getPhysicalMemoryBase(SMI_PCI_VENDOR_ID, gwDeviceId, gwCurDev); + DDKDEBUGPRINT((INIT_LEVEL, "Device: %x, Memory Physical Base Addr: %08x\n", gwCurDev, frameBufPhysicalBase[gwCurDev])); + if (frameBufPhysicalBase[gwCurDev] == 0) + { + return((void *)0); + } + } + + return(frameBufPhysicalBase[gwCurDev] + offset); +} + +/* + * Get the logical address of an offset location in frame buffer. + * Return: A valid address if success. + * NULL address if fail. + */ +void *getAddress(unsigned long offset /*Offset from base of frame buffer*/) +{ + if (frameBufBase[gwCurDev] == (unsigned char *)0) + { + frameBufBase[gwCurDev] = (unsigned char *)getMemoryBase(SMI_PCI_VENDOR_ID, gwDeviceId, gwCurDev); + DDKDEBUGPRINT((INIT_LEVEL, "Device: %x, Memory Base Addr: %08x\n", gwCurDev, frameBufBase[gwCurDev])); + if (frameBufBase[gwCurDev] == 0) + { + return((void *)0); + } + } + + return(frameBufBase[gwCurDev] + offset); +} + +/* + * Get the logical address of an offset location in MMIO space. + * Return: A valid address if success. + * NULL address if fail. + */ +void *getMemoryMappedAddress(unsigned long offset /*Offset from base of MMIO*/) +{ + if (mmioBase[gwCurDev] == (unsigned char *)0) + { + mmioBase[gwCurDev] = (unsigned char *)getMmioBase(SMI_PCI_VENDOR_ID, gwDeviceId, gwCurDev); + if (mmioBase[gwCurDev] == 0) + { + return((void *)0); + } + } + + return(mmioBase[gwCurDev] + offset); +} + +/* + * Get the IRQ number of the current device. + */ +unsigned char getIRQ() +{ + return (readPCIByte(SMI_PCI_VENDOR_ID, gwDeviceId, gwCurDev, 0x3C)); +} + +/* + * This function detects what SMI chips is in the system. + * + * Return: A non-zero device ID if SMI chip is detected. + * Zero means NO SMI chip is detected. + */ +unsigned short detectDevices() +{ + unsigned char i, j; + + /* Clean up the MMIO and Frame Buffer structure first. + Otherwise, calling this function twice, will result in different gwDeviceID. + */ + for (i = 0; i < MAX_SMI_DEVICE; i++) + { + frameBufBase[i] = 0; + mmioBase[i] = 0; + frameBufPhysicalBase[i] = 0; + } + + /* Walk through the device ID table */ + for (i=0; gwDeviceIdTable[i] != 0; i++) + { + /* For a specific device, find out how many exist. + This library supports a max of 4 devices of the same ID. + */ + gwDeviceId = gwDeviceIdTable[i]; + gwNumOfDev = 0; + + for (j=0; j 0) break; + } + + gwCurDev = 0; /* Always defaults to device 0 after initialization */ + + /* Return the ID of detected device */ + return gwDeviceIdTable[i]; +} + +/* + * How many devices of the same ID are there. + */ +unsigned short getNumOfDevices() +{ + return gwNumOfDev; +} + +/* + * This function sets up the current accessible device, if more + * than one of the same ID exist in the system. + * + * Note: + * Single device application don't need to call this function. + * This function is to control multiple devices. + */ +long setCurrentDevice(unsigned short dev) +{ + /* Error check */ + if ( dev >= gwNumOfDev) + return -1; + + gwCurDev = dev; + return 0; +} + +/* + * This function gets the current accessible device index. + */ +unsigned short getCurrentDevice() +{ + return gwCurDev; +} + +unsigned char peekByte(unsigned long offset) +{ + void *pAddr; + + if ((pAddr = getAddress(offset)) == (void *)0) + return(0xFF); + + return *(volatile unsigned char *)(pAddr); +} + +unsigned short peekWord(unsigned long offset) +{ + void *pAddr; + + if ((pAddr = getAddress(offset)) == (void *)0) + return(0xFFFF); + + return *(volatile unsigned short *)(pAddr); +} + +unsigned long peekDWord(unsigned long offset) +{ +#if 0 + void *pAddr; + + if ((pAddr = getAddress(offset)) == (void *)0) + return(0xFFFFFFFF); + + return *(volatile unsigned long *)(pAddr); +#else + return ddk502_PEEK32(offset); +#endif +} + +void poke_4_Byte(unsigned long offset, unsigned char *buf) +{ + unsigned long tData; + void *pAddr; + + tData = ((unsigned long)buf[3]<<24) + ((unsigned long)buf[2]<<16) + ((unsigned int)buf[1]<<8) + buf[0]; + + if ((pAddr = getAddress(offset)) != (void *)0) + *(volatile unsigned long *)(pAddr) = tData; +} + +void pokeByte(unsigned long offset, unsigned char value) +{ + void *pAddr; + + if ((pAddr = getAddress(offset)) != (void *)0) + *(volatile unsigned char *)(pAddr) = value; +} + +void pokeWord(unsigned long offset, unsigned short value) +{ + void *pAddr; + + if ((pAddr = getAddress(offset)) != (void *)0) + *(volatile unsigned short *)(pAddr) = value; +} + +void pokeDWord(unsigned long offset, unsigned long value) +{ +#if 0 + void *pAddr; + + if ((pAddr = getAddress(offset)) != (void *)0) + *(volatile unsigned long *)(pAddr) = value; +#else + ddk502_POKE32(offset, value); + return; +#endif +} + +/* REGISTER SPACE */ + +unsigned char peekRegisterByte(unsigned long offset) +{ + void *pAddr; + + if ((pAddr = getMemoryMappedAddress(offset)) == (void *)0) + return (0xFF); + + return *(volatile unsigned char *)(pAddr); +} + +unsigned short peekRegisterWord(unsigned long offset) +{ + void *pAddr; + + if ((pAddr = getMemoryMappedAddress(offset)) == (void *)0) + return (0xFFFF); + + return *(volatile unsigned short *)(pAddr); +} + +unsigned long peekRegisterDWord(unsigned long offset) +{ +#if 0 + void *pAddr; + + if ((pAddr = getMemoryMappedAddress(offset)) == (void *)0) + return (0xFFFFFFFF); + + return *(volatile unsigned long *)(pAddr); +#else + return ddk502_PEEK32(offset); +#endif +} + +void pokeRegisterByte(unsigned long offset, unsigned char value) +{ + void *pAddr; + + if ((pAddr = getMemoryMappedAddress(offset)) != (void *)0) + *(volatile unsigned char *)(pAddr) = value; +} + +void pokeRegisterWord(unsigned long offset, unsigned short value) +{ + void *pAddr; + + if ((pAddr = getMemoryMappedAddress(offset)) != (void *)0) + *(volatile unsigned short *)(pAddr) = value; +} + +void pokeRegisterDWord(unsigned long offset, unsigned long value) +{ +#if 0 + void *pAddr; + + if ((pAddr = getMemoryMappedAddress(offset)) != (void *)0) + *(volatile unsigned long *)(pAddr) = value; +#else + return ddk502_POKE32(offset, value); +#endif +} diff --git a/src/ddk502/ddk502_hardware.h b/src/ddk502/ddk502_hardware.h new file mode 100644 index 0000000..eba0a9f --- /dev/null +++ b/src/ddk502/ddk502_hardware.h @@ -0,0 +1,93 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* HARDWARE.h --- Voyager GX SDK +* This file contains the definitions for the physical hardware. +* +*******************************************************************/ +#ifndef _HARDWARE_H_ +#define _HARDWARE_H_ + +/* Silicon Motion PCI vendor ID */ +#define SMI_PCI_VENDOR_ID 0x126F + +/* Maximum number of devices with the same ID supported by this library. */ +#define MAX_SMI_DEVICE 4 + +/* Size of the SM50X MMIO and memory */ +#define SM50X_PCI_ALLOC_MMIO_SIZE (2*1024*1024) +#define SM50X_PCI_ALLOC_MEMORY_SIZE (64*1024*1024) + +/* + * Get the physical address of an offset location in frame buffer. + * In DOS, the physical and the logical address most likely are the same. + * Return: A valid address if success. + * NULL address if fail. + */ +void *getPhysicalAddress(unsigned long offset /* Offset from base of physical frame buffer */); + +/* + * Get the logical address of an offset location in frame buffer. + * Return: A valid address if success. + * NULL address if fail. + */ +void *getAddress(unsigned long offset /*Offset from base of frame buffer*/); + +/* + * Get the logical address of an offset location in MMIO space. + * Return: A valid address if success. + * NULL address if fail. + */ +void *getMemoryMappedAddress(unsigned long offset /*Offset from base of MMIO*/); + +/* + * This function detects what SMI chips is in the system. + * + * Return: A non-zero device ID if SMI chip is detected. + * Zero means NO SMI chip is detected. + */ +unsigned short detectDevices(void); + +/* + * How many devices of the same ID are there. + */ +unsigned short getNumOfDevices(void); + +/* + * This function gets the IRQ line for the device in use + */ +unsigned char getIRQ(void); + +/* + * This function sets up the current accessible device, if more + * than one of the same ID exist in the system. + * + * Note: + * Single device application don't need to call this function. + * This function is to control multiple devices. + */ +long setCurrentDevice(unsigned short dev); +unsigned short getCurrentDevice(void); + +/* Video Memory read/write functions */ +unsigned char peekByte(unsigned long offset); +unsigned short peekWord(unsigned long offset); +unsigned long peekDWord(unsigned long offset); +void poke_4_Byte(unsigned long offset, unsigned char *buf); +void pokeByte(unsigned long offset, unsigned char value); +void pokeWord(unsigned long offset, unsigned short value); +void pokeDWord(unsigned long offset, unsigned long value); + +/* MMIO read/write functions */ +unsigned char peekRegisterByte(unsigned long offset); +unsigned short peekRegisterWord(unsigned long offset); +unsigned long peekRegisterDWord(unsigned long offset); +void pokeRegisterByte(unsigned long offset, unsigned char value); +void pokeRegisterWord(unsigned long offset, unsigned short value); +void pokeRegisterDWord(unsigned long offset, unsigned long value); + +#endif /* _HARDWARE_H_ */ diff --git a/src/ddk502/ddk502_help.c b/src/ddk502/ddk502_help.c new file mode 100644 index 0000000..c7bece6 --- /dev/null +++ b/src/ddk502/ddk502_help.c @@ -0,0 +1,47 @@ +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "compiler.h" + +#include "xf86Module.h" +#if XORG_VERSION_CURRENT < 10706000 +#include "xf86Resources.h" +#endif + +#include "ddk502_help.h" + +volatile unsigned char * mmio502 = NULL; +unsigned long revId502 = 0x0; +unsigned short devId502 = 0; + +volatile unsigned char * fb502 = NULL; + +_X_EXPORT unsigned long ddk502_PEEK32(addr) +{ + return MMIO_IN32(mmio502,addr); +} + +_X_EXPORT void ddk502_POKE32(addr,data) +{ + MMIO_OUT32(mmio502,(addr),(data)); +} +_X_EXPORT void ddk502_POKEfb32(addr,data) +{ + MMIO_OUT32(fb502,(addr),(data)); +} +/* after driver mapped io registers, use this function first */ +_X_EXPORT void ddk502_set_mmio(volatile unsigned char * addr,unsigned short devId,unsigned long revId) +{ + mmio502 = addr; + devId502= devId; + revId502 = revId; +} + +_X_EXPORT void ddk502_set_fb(volatile unsigned char * addr,unsigned short devId,char revId) +{ + +} diff --git a/src/ddk502/ddk502_help.h b/src/ddk502/ddk502_help.h new file mode 100644 index 0000000..7e003d8 --- /dev/null +++ b/src/ddk502/ddk502_help.h @@ -0,0 +1,29 @@ +#ifndef DDK502_HELP_H__ +#define DDK502_HELP_H__ +#include "ddk502_chip.h" +#include "../smi_common.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +//#include "compiler.h" + +#ifndef NULL +#define NULL 0 +#endif + + + +#define outb_p outb +#define inb_p inb + +_X_EXPORT unsigned long ddk502_PEEK32(addr) ; + +_X_EXPORT void ddk502_POKE32(addr,data); + +/* +_X_EXPORT void ddk750_set_mmio(volatile unsigned char * addr,unsigned short devId,char revId); +*/ + +#endif diff --git a/src/ddk502/ddk502_linux.c b/src/ddk502/ddk502_linux.c new file mode 100644 index 0000000..aac22ab --- /dev/null +++ b/src/ddk502/ddk502_linux.c @@ -0,0 +1,407 @@ +/******************************************************************* +* +* Copyright (c) 2008 by Silicon Motion, Inc. (SMI) +* +* LINUX.C --- VGX family DDK +* +* This file contains LINUX dependent codes, which works only +* with PCI boards in x86 systems. +* +* Don't use this file for other OS, non-x86 system, and non-PCI. +* +*******************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ddk502_voyager.h" +#include "ddk502_hardware.h" +////// +#include + +#include "ddk502_os.h" + +#include "ddk502_clock.h" +#include "ddk502_mode.h" + +#include + +#include "xf86_OSproc.h" +#include +#include +#include +#include "xf86i2c.h" + +/* Global variable to save all the SMI devices */ +static struct pci_dev *g_pCurrentDevice = (struct pci_dev *)0; +static struct pci_access *g_pAccess = (struct pci_access *)0; +static struct pci_filter g_filter; + +/* + * This function maps a physical address into logical address. + * Return: NULL address pointer if fail + * A Logical address pointer if success. + */ +void *mapPhysicalAddress( + void *phyAddr, /* 32 bit physical address */ + unsigned long size /* Memory size to be mapped */ +) +{ + unsigned long address; + int fileDescriptor; + + fileDescriptor = open("/dev/mem", O_RDWR); + if (fileDescriptor == -1) + return ((void *)0); + + address = (unsigned long) mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileDescriptor, (unsigned long)phyAddr); + + if ((void *) address == MAP_FAILED) + address = 0; + + close(fileDescriptor); + + return ((void *) address); +} + +/* + * This function unmaps a linear logical address obtained by mapPhysicalAddress. + * Return: + * 0 - Success + * -1 - Fail + */ +long unmapPhysicalAddress( + void *linearAddr, /* 32 bit linear address */ + unsigned long size +) +{ + return ((long)munmap(linearAddr, size)); +} + +/* Initialize the PCI */ +long initPCI( + unsigned short vendorId, + unsigned short deviceId, + unsigned short deviceNum +) +{ + unsigned short deviceIndex; + + if (g_pCurrentDevice != (struct pci_dev *)0) + return 0; + + /* Get the pci_access structure */ + g_pAccess = pci_alloc(); + + /* Initialize the PCI library */ + pci_init(g_pAccess); + + /* Set all options you want -- here we stick with the defaults */ + pci_filter_init(g_pAccess, &g_filter); + g_filter.vendor = vendorId; + g_filter.device = deviceId; + + /* Get the list of devices */ + pci_scan_bus(g_pAccess); + for(g_pCurrentDevice = g_pAccess->devices, deviceIndex = 0; + g_pCurrentDevice; + g_pCurrentDevice = g_pCurrentDevice->next) + { + if (pci_filter_match(&g_filter, g_pCurrentDevice)) + { + if (deviceIndex == deviceNum) + { + pci_fill_info(g_pCurrentDevice, PCI_FILL_IDENT | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES); + return 0; + } + + /* Increment the device index */ + deviceIndex++; + } + } + + return (-1); +} + +/* + * This function reads a DWord value from the PCI configuration space + * of a specific PCI device. + * + * Inputs are the Vendor and device ID of the device in question. + * Return: a DWord value. + */ +unsigned long readPCIDword( + unsigned short vendorId, /* PCI vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum, /* If more than one device in system, device number are ordered as 0, 1, 2,... */ + unsigned short offset /* Offset in configuration space to be read */ +) +{ + if (initPCI(vendorId, deviceId, deviceNum) == 0) + { + return ((unsigned long) pci_read_long(g_pCurrentDevice, offset)); + } + + return 0; +} + +/* + * This function reads a Word value from the PCI configuration space + * of a specific device. + * + * Inputs are the Vendor and device ID of the device in question. + * Return: a WORD value. + */ +unsigned short readPCIWord( + unsigned short vendorId, /* PCI vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum, /* If more than one device in system, device number are ordered as 0, 1, 2,... */ + unsigned short offset /* Offset in configuration space to be read */ +) +{ + if (initPCI(vendorId, deviceId, deviceNum) == 0) + { + return ((unsigned short) pci_read_word(g_pCurrentDevice, offset)); + } + + return 0; +} + +/* + * This function reads a byte value from the PCI configuration space + * of a specific device. + * + * Inputs are the Vendor and device ID of the device in question. + * Return: a BYTE value. + */ +unsigned char readPCIByte( + unsigned short vendorId, /* PCI Vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum, /* If more than one device in system, device number are ordered as 0, 1, 2,... */ + unsigned short offset /* Offset in configuration space to be read */ +) +{ + if (initPCI(vendorId, deviceId, deviceNum) == 0) + { + return ((unsigned char) pci_read_byte(g_pCurrentDevice, offset)); + } + + return 0; +} + +/* + * This function writes a byte value to the PCI configuration space + * of a specific device. + * + * Inputs are the Vendor and device ID of the device in question. + * Return: 0 = Success. + * -1 = Fail. + */ +long writePCIByte( + unsigned short vendorId, /* PCI vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum, /* If more than one device in system, device number are ordered as 0, 1, 2,... */ + unsigned short offset, /* Offset in configuration space to be written */ + unsigned char value /* To be written BYTE value */ +) +{ + if (initPCI(vendorId, deviceId, deviceNum) == 0) + return (pci_write_byte(g_pCurrentDevice, offset, value)); + + return (-1); +} + +/******************************************************************* + * Time related functions + * + * This implementation can be used for performance analysis or delay + * function. + *******************************************************************/ + +/* Tick count will be reset after midnight 24 hours. Therefore, when the tick count counter + reset, it means that it has passed the 24 hours boundary. + A Timer tick occurs every 1,193,180 / 65536 (= ~18.20648) times per second. + The maximum tick count is calculated as follows: (24*3600*1000/54.9254) = ~1573040 + */ +unsigned long getSystemTickCount() +{ + /* TODO: Check how to implement this in LINUX */ + return 0; +} + +/* Get current time in milliseconds. */ +unsigned long getCurrentTime() +{ + struct timeval currentTime; + unsigned long milliseconds = 0; + + if (gettimeofday(¤tTime, (struct timezone *)0) == 0) + milliseconds = (currentTime.tv_sec * 1000) + (currentTime.tv_usec / 1000); + + return milliseconds; +} + +/******************************************************************* + * Interrupt implementation support from the OS + * + * This implementation is used for handling the SM50x interrupt. + *******************************************************************/ +short enableTimerInterrupt( + unsigned char enable, + void (*pfnHandler)() +) +{ + struct itimerval tick; + + /* Initialize struct */ + memset((void *)&tick, 0, sizeof(tick)); + + if (enable != 0) + { + signal(SIGALRM, pfnHandler); + + /* Timeout to run function first time */ + tick.it_value.tv_sec = 0; /* sec */ + tick.it_value.tv_usec = 5880/*16666*/; /* micro sec. */ + + /* Interval time to run function */ + tick.it_interval.tv_sec = 0; + tick.it_interval.tv_usec = 5880/*16666*/; + } + + /* Set timer, ITIMER_REAL : real-time to decrease timer, send SIGALRM when timeout */ + if (setitimer(ITIMER_REAL, &tick, NULL)) + return (-1); + + return (0); +} + +/* + * Register an interrupt handler (ISR) to the interrupt vector table associated + * with the given irq number. + * + * Input: + * irqNumber - IRQ Number + * pfnHandler - Pointer to the ISR function + * + * Output: + * 0 - Success + * -1 - Fail + */ +short registerInterrupt( + unsigned char irqNumber, + void (*pfnHandler)() +) +{ + return enableTimerInterrupt(1, pfnHandler); +} + +/* + * Unregister an interrupt handler from the interrupt vector table + * + * Input: + * irqNumber - IRQ Number + */ +short unregisterInterrupt( + unsigned char irqNumber +) +{ + return enableTimerInterrupt(0, (void *)0); +} + +/* + * Signal the End Of Interrupt to the system and chain the interrupt + * if necessary. + * + * Input: + * irqNumber - IRQ Number + */ +void interruptEOI( + unsigned char irqNumber +) +{ +} + +/******************************************************************* + * CPU implementation support from the OS + * + * This implementation is used to detect CPU and manipulate its + * registers. + * It only applies to Pentium Pro. + *******************************************************************/ + +/* + * registerWCMemoryRange + * This function registers the memory range as the memory write combine type (burst) + * + * Input: + * phyAddr - Physical Memory Address to be registered as WC memory type + * size - The memory size to be registered. + * + * Output: + * 0 - Success + * -1 - Fail + * + * Note: + * 1. This code is only works in Intel Pentium Pro and above CPU. Previous CPU does not + * support Write Combine. + * 2. Not all systems have their MTRR enabled by default. I believe it depends on the + * either the system BIOS enable it or not during boot up. In most of ASUS motherboard, + * it seems that the system BIOS do a good job in setting up the MTRR when bootin up. + * However, in other motherboard, the MTRR seems to be disabled. In such case, it can + * be enabled in Ring 0 privilege. + */ +long registerWCMemoryRange( + void *phyAddr, /* 32 bit physical address */ + unsigned long size +) +{ + int fileDescriptor; + struct mtrr_sentry mtrrSentry; + + if ((fileDescriptor = open("/proc/mtrr", O_WRONLY, 0)) != (-1)) + { + mtrrSentry.base = (unsigned long)phyAddr; + mtrrSentry.size = size; + mtrrSentry.type = MTRR_TYPE_WRCOMB; + + if (ioctl(fileDescriptor, MTRRIOC_ADD_ENTRY, &mtrrSentry) != (-1)) + return (0); + } + + return (-1); +} + +/* + * This function unregisters the memory range WC type + */ +long unregisterWCMemoryRange( + void *phyAddr, /* 32 bit physical address */ + unsigned long size +) +{ + int fileDescriptor; + struct mtrr_sentry mtrrSentry; + + if ((fileDescriptor = open("/proc/mtrr", O_WRONLY, 0)) != (-1)) + { + mtrrSentry.base = (unsigned long)phyAddr; + mtrrSentry.size = size; + mtrrSentry.type = MTRR_TYPE_UNCACHABLE; + + if (ioctl(fileDescriptor, MTRRIOC_DEL_ENTRY, &mtrrSentry) != (-1)) + return (0); + } + + return (-1); +} + + diff --git a/src/ddk502/ddk502_mode.c b/src/ddk502/ddk502_mode.c new file mode 100644 index 0000000..c504aba --- /dev/null +++ b/src/ddk502/ddk502_mode.c @@ -0,0 +1,746 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* MODE.C --- SMI DDK +* This file contains the source code for the mode table. +* +*******************************************************************/ +#include "ddk502_voyager.h" +#include "ddk502_chip.h" +#include "ddk502_clock.h" +#include "ddk502_hardware.h" +#include "ddk502_mode.h" +#include "ddk502_power.h" +#include "ddk502_help.h" +#include "../smi_common.h" +/* + * Timing parameter for some popular modes. + * Note that this table is made according to standard VESA parameters for the + * popular modes. + */ +static mode_parameter_t gModeParamTable[] = +{ +/* 320 x 240 */ + { 352, 320, 335, 8, NEG, 265, 240, 254, 2, NEG, 5600000, 15909, 60, NEG}, + +/* 400 x 300 */ + { 528, 400, 420, 64, NEG, 314, 300, 301, 2, NEG, 9960000, 18864, 60, NEG}, + +/* 640 x 480 [4:3] */ + { 800, 640, 656, 96, NEG, 525, 480, 490, 2, NEG, 25175000, 31500, 60, NEG}, + { 840, 640, 680, 64, NEG, 500, 480, 481, 3, NEG, 31500000, 37500, 75, NEG}, + { 832, 640, 700, 56, NEG, 509, 480, 481, 3, NEG, 36000000, 43269, 85, NEG}, + +/* 720 x 480 [3:2] */ + { 889, 720, 738,108, POS, 525, 480, 490, 2, NEG, 28000000, 31496, 60, NEG}, + +/* 720 x 540 [4:3] */ + { 886, 720, 740, 96, POS, 576, 540, 545, 2, POS, 30600000, 34537, 60, NEG}, + +/* 800 x 480 [5:3] */ + { 973, 800, 822, 56, POS, 524, 480, 490, 2, NEG, 30600000, 31449, 60, NEG}, + +/* 800 x 600 [4:3] */ + {1062, 800, 840,128, POS, 628, 600, 601, 4, POS, 40000000, 37665, 60, NEG}, + {1056, 800, 816, 80, POS, 625, 600, 601, 3, POS, 49500000, 46875, 75, NEG}, + {1054, 800, 842, 64, POS, 625, 600, 601, 3, POS, 56000000, 53131, 85, NEG}, + +/* 960 x 720 [4:3] */ + {1245, 960, 992, 64, POS, 750, 720, 721, 3, POS, 56000000, 44980, 60, NEG}, + +/* 1024 x 600 [16:9] 1.7 */ + {1313,1024,1064,104, POS, 622, 600, 601, 3, POS, 49000000, 37319, 60, NEG}, + +/* 1024 x 768 [4:3] */ + {1340,1024,1060,136, NEG, 809, 768, 772, 6, NEG, 65000000, 48507, 60, NEG}, + {1337,1024,1072, 96, NEG, 808, 768, 780, 3, NEG, 81000000, 60583, 75, POS}, + {1376,1024,1070, 96, POS, 808, 768, 769, 3, POS, 94500000, 68677, 85, POS}, + +/* 1152 x 864 [4:3] */ + {1475,1152,1208, 96, NEG, 888, 864, 866, 3, NEG, 78600000, 53288, 60, POS}, + +/* 1280 x 720 [16:9] */ + {1664,1280,1336,136, POS, 746, 720, 721, 3, POS, 74481000, 44760, 60, POS}, + +/* 1280 x 768 [5:3] */ + {1678,1280,1350,136, POS, 795, 768, 769, 3, POS, 80000000, 47676, 60, POS}, + +/* 1280 x 800 [8:5] */ + {1650,1280,1344,136, NEG, 824, 800, 800, 3, NEG, 81600000, 49455, 60, POS}, + +/* 1280 x 960 [4:3] */ + {1618,1280,1330, 96, NEG, 977, 960, 960, 2, NEG, 94500000, 59259, 60, POS}, + +/* 1280 x 1024 [5:4] */ + {1626,1280,1332,112, POS,1046,1024,1024, 2, POS,102000000, 62731, 60, POS}, + +/* 1360 x 768 [16:9] */ + {1776,1360,1424,144, POS, 795, 768, 769, 3, POS, 84715000, 47700, 60, POS}, + +/* 1366 x 768 [16:9] */ + {1722,1366,1424,112, NEG, 784, 768, 769, 3, NEG, 81000000, 47038, 60, POS}, + +/* 1440 x 900 */ + {1904,1440,1520,152, NEG, 932, 900, 901, 3, POS,106470000, 55919, 60, POS}, + +/* 1440 x 960 [16:9] */ + {1920,1440,1528,152, POS, 994, 960, 961, 3, POS,114509000, 59640, 60, POS}, + +/* 1600 x 1200 [4:3] */ +/* Not supported yet. + {2160,1600,1724,112, NEG,1220,1200,1200, 2, NEG,158000000, 73148, 60, POS}, + */ + +/* End of table. */ + { 0, 0, 0, 0, NEG, 0, 0, 0, 0, NEG, 0, 0, 0, NEG}, +}; + +/* Local variable to store the current set mode. + Note: + The current set mode timing does not necessarily matching the mode parameter table. + Instead, the value is based on the actual values of the mode being set after + calculation and adjustment. + */ +static mode_parameter_t gPanelCurrentModeParam = { 0, 0, 0, 0, NEG, 0, 0, 0, 0, NEG, 0, 0, 0, NEG}; +static mode_parameter_t gCRTCurrentModeParam = { 0, 0, 0, 0, NEG, 0, 0, 0, 0, NEG, 0, 0, 0, NEG}; + +/* Flag to force 2x Display clock control */ +static unsigned char gForce2xDisplayClock = 0; + +/* + * Return a point to the gModeParamTable. + * Function in other files used this to get the mode table pointer. + */ +mode_parameter_t *getStockModeParamTable() +{ + return(gModeParamTable); +} + +/* + * Return the size of the Stock Mode Param Table + */ +unsigned long getStockModeParamTableSize() +{ + return (sizeof(gModeParamTable) / sizeof(mode_parameter_t) - 1); +} + +/* + * This function returns the current mode. + */ +mode_parameter_t getCurrentModeParam(disp_control_t dispCtrl) +{ + if (dispCtrl == PANEL_CTRL) + return gPanelCurrentModeParam; + else + return gCRTCurrentModeParam; +} + +/* + * This function sets the flag to force the display clock to use 2x. + * Each module that needs to use 2x has to enable it by setting to 1 and + * disable it by setting to 0. It is the caller module's responsibility + * to set it to 0 when they don't use the 2x clock anymore. + */ +void set2xDisplayClock(unsigned char ucForce2xDisplayClock) +{ + if (ucForce2xDisplayClock) + gForce2xDisplayClock++; + else + { + if (gForce2xDisplayClock) + gForce2xDisplayClock--; + } +} + +/* + * This function checks either the 2x Display Clock flag is enabled or not + */ +unsigned char get2xDisplayClock(void) +{ + return (gForce2xDisplayClock ? 1 : 0); +} + +/* This function get the Display Clock Multiplier */ +unsigned char getDisplayClkMultiplier(disp_control_t dispControl) +{ + unsigned long ulCurrentClock; + + ulCurrentClock = peekRegisterDWord(CURRENT_POWER_CLOCK); + if (dispControl == PANEL_CTRL) + { + if (FIELD_GET(ulCurrentClock, CURRENT_POWER_CLOCK, P2XCLK_DIS) == CURRENT_POWER_CLOCK_P2XCLK_DIS_1X) + return 1; + } + else + { + if (FIELD_GET(ulCurrentClock, CURRENT_POWER_CLOCK, V2XCLK_DIS) == CURRENT_POWER_CLOCK_V2XCLK_DIS_1X) + return 1; + } + + /* Default is 2 since SM501 chip */ + return 2; +} + +/* + * Locate in-stock parameter table for the requested mode. + * Success: return a pointer to the mode_parameter_t entry. + * Fail: a NULL pointer. + * + */ +mode_parameter_t *findVesaModeParam( +unsigned long width, +unsigned long height, +unsigned long refresh_rate) +{ + mode_parameter_t *mode_table = gModeParamTable; + + /* Walk the entire mode table. */ + while (mode_table->pixel_clock != 0) + { + if ((mode_table->horizontal_display_end == width) + && (mode_table->vertical_display_end == height) + && (mode_table->vertical_frequency == refresh_rate)) + { + return(mode_table); + } + mode_table++; /* Next entry */ + } + + /* No match, return NULL pointer */ + return((mode_parameter_t *)0); +} + +/* + * Convert the VESA timing into possible Voyager timing. + * If actual pixel clock is not equal to Vesa timing pixel clock. + * other parameter like horizontal total and sync have to be changed. + * + * Input: Pointer to a Vesa mode parameters. + * Pointer to a an empty mode parameter structure to be filled. + * Actual pixel clock generated by SMI hardware. + * + * Output: + * 1) Fill up input structure mode_parameter_t with possible timing for Voyager. + */ +long adjustVesaModeParam( +mode_parameter_t *pVesaMode, /* Pointer to Vesa mode parameter */ +mode_parameter_t *pMode, /* Pointer to Vogager mode parameter to be updated here */ +unsigned long ulPClk /* real pixel clock feasible by VGX */ +) +{ + unsigned long blank_width, sync_start, sync_width; + + /* Senity check */ + if ( pVesaMode == (mode_parameter_t *)0 || + pMode == (mode_parameter_t *)0 || + ulPClk == 0) + { + return -1; + } + + /* Copy VESA mode into Voyager mode. */ + *pMode = *pVesaMode; + + /* If VGX can generate the vesa reqiured pixel clock, nothing to change */ + if (ulPClk == pVesaMode->pixel_clock) return 0; + + pMode->pixel_clock = ulPClk; /* Update actual pixel clock into mode */ + + /* Calculate the sync percentages of the VESA mode. */ + blank_width = pVesaMode->horizontal_total - pVesaMode->horizontal_display_end; + sync_start = roundedDiv((pVesaMode->horizontal_sync_start - + pVesaMode->horizontal_display_end) * 100, blank_width); + sync_width = roundedDiv(pVesaMode->horizontal_sync_width * 100, blank_width); + + /* Calculate the horizontal total based on the actual pixel clock and VESA line frequency. */ + pMode->horizontal_total = roundedDiv(pMode->pixel_clock, + pVesaMode->horizontal_frequency); + + /* Calculate the sync start and width based on the VESA percentages. */ + blank_width = pMode->horizontal_total - pMode->horizontal_display_end; + pMode->horizontal_sync_start = pMode->horizontal_display_end + roundedDiv(blank_width * sync_start, 100); + pMode->horizontal_sync_width = roundedDiv(blank_width * sync_width, 100); + + /* Calculate the line and screen frequencies. */ + pMode->horizontal_frequency = roundedDiv(pMode->pixel_clock, + pMode->horizontal_total); + pMode->vertical_frequency = roundedDiv(pMode->horizontal_frequency, + pMode->vertical_total); + return 0; +} + +/* + * This function gets the display status + * + * Input: + * dispControl - display control of which display status to be retrieved. + * + * Output: + * 0 - Display is pending + * -1 - Display is not pending + */ +long isCurrentDisplayPending( + disp_control_t dispControl +) +{ + unsigned long value; + + /* Get the display status */ + if (dispControl == PANEL_CTRL) + { + if (FIELD_GET(peekRegisterDWord(PANEL_FB_ADDRESS), PANEL_FB_ADDRESS, STATUS) == PANEL_FB_ADDRESS_STATUS_PENDING) + return 0; + } + else if (dispControl == CRT_CTRL) + { + if (FIELD_GET(peekRegisterDWord(CRT_FB_ADDRESS), CRT_FB_ADDRESS, STATUS) == CRT_FB_ADDRESS_STATUS_PENDING) + return 0; + } + + return (-1); +} + +/* + * This function sets the display base address + * + * Input: + * dispControl - display control of which base address to be set. + * ulBaseAddress - Base Address value to be set. + */ +void setDisplayBaseAddress( + disp_control_t dispControl, + unsigned long ulBaseAddress +) +{ + if (dispControl == PANEL_CTRL) + { + /* Frame buffer base for this mode */ + pokeRegisterDWord(PANEL_FB_ADDRESS, + FIELD_SET(0, PANEL_FB_ADDRESS, STATUS, PENDING) + | FIELD_SET(0, PANEL_FB_ADDRESS, EXT, LOCAL) + | FIELD_VALUE(0, PANEL_FB_ADDRESS, ADDRESS, ulBaseAddress)); + } + else if (dispControl == CRT_CTRL) + { + /* Frame buffer base for this mode */ + pokeRegisterDWord(CRT_FB_ADDRESS, + FIELD_SET(0, CRT_FB_ADDRESS, STATUS, PENDING) + | FIELD_SET(0, CRT_FB_ADDRESS, EXT, LOCAL) + | FIELD_VALUE(0, CRT_FB_ADDRESS, ADDRESS, ulBaseAddress)); + } +} + +/* + * Program the hardware for a specific video mode + */ +void programModeRegisters( +mode_parameter_t *pModeParam, /* mode information about pixel clock, horizontal total, etc. */ +unsigned long ulBpp, /* Color depth for this mode */ +unsigned long ulBaseAddress, /* Offset in frame buffer */ +unsigned long ulPitch, /* Mode pitch value in byte: no of bytes between two lines. */ +pll_value_t *pPLL /* Pre-calculated values for the PLL */ +) +{ + unsigned long ulTmpValue, ulReg, ulReservedBits; + unsigned long palette_ram; + unsigned long offset; + + /* Enable display power gate */ + ulTmpValue = peekRegisterDWord(CURRENT_POWER_GATE); + ulTmpValue = FIELD_SET(ulTmpValue, CURRENT_POWER_GATE, DISPLAY, ENABLE); + ddk502_setCurrentGate(ulTmpValue); + + if (pPLL->clockType==V1XCLK || pPLL->clockType==V2XCLK) + { + /* CRT display */ + setCurrentClock(formatModeClockReg(pPLL)); + + /* Frame buffer base for this mode */ + setDisplayBaseAddress(CRT_CTRL, ulBaseAddress); + + /* Pitch value (Sometime, hardware people calls it Offset) */ + pokeRegisterDWord(CRT_FB_WIDTH, + FIELD_VALUE(0, CRT_FB_WIDTH, WIDTH, ulPitch) + | FIELD_VALUE(0, CRT_FB_WIDTH, OFFSET, ulPitch)); + + pokeRegisterDWord(CRT_HORIZONTAL_TOTAL, + FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) + | FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); + + pokeRegisterDWord(CRT_HORIZONTAL_SYNC, + FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) + | FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); + + pokeRegisterDWord(CRT_VERTICAL_TOTAL, + FIELD_VALUE(0, CRT_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) + | FIELD_VALUE(0, CRT_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); + + pokeRegisterDWord(CRT_VERTICAL_SYNC, + FIELD_VALUE(0, CRT_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) + | FIELD_VALUE(0, CRT_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); + + /* Set control register value */ + ulTmpValue = + (pModeParam->vertical_sync_polarity == POS + ? FIELD_SET(0, CRT_DISPLAY_CTRL, VSYNC_PHASE, ACTIVE_HIGH) + : FIELD_SET(0, CRT_DISPLAY_CTRL, VSYNC_PHASE, ACTIVE_LOW)) + | (pModeParam->horizontal_sync_polarity == POS + ? FIELD_SET(0, CRT_DISPLAY_CTRL, HSYNC_PHASE, ACTIVE_HIGH) + : FIELD_SET(0, CRT_DISPLAY_CTRL, HSYNC_PHASE, ACTIVE_LOW)) + | FIELD_SET(0, CRT_DISPLAY_CTRL, SELECT, CRT) + | FIELD_SET(0, CRT_DISPLAY_CTRL, TIMING, ENABLE) + | FIELD_SET(0, CRT_DISPLAY_CTRL, PLANE, ENABLE) + | (ulBpp == 8 + ? FIELD_SET(0, CRT_DISPLAY_CTRL, FORMAT, 8) + : (ulBpp == 16 + ? FIELD_SET(0, CRT_DISPLAY_CTRL, FORMAT, 16) + : FIELD_SET(0, CRT_DISPLAY_CTRL, FORMAT, 32))); + + ulReg = peekRegisterDWord(CRT_DISPLAY_CTRL) + & FIELD_CLEAR(CRT_DISPLAY_CTRL, VSYNC_PHASE) + & FIELD_CLEAR(CRT_DISPLAY_CTRL, HSYNC_PHASE) + & FIELD_CLEAR(CRT_DISPLAY_CTRL, SELECT) + & FIELD_CLEAR(CRT_DISPLAY_CTRL, TIMING) + & FIELD_CLEAR(CRT_DISPLAY_CTRL, PLANE) + & FIELD_CLEAR(CRT_DISPLAY_CTRL, FORMAT); + + pokeRegisterDWord(CRT_DISPLAY_CTRL, ulTmpValue | ulReg); + + /* Palette RAM. */ + palette_ram = CRT_PALETTE_RAM; + } + else + { + /* Panel display: PANEL_PLL, PANEL_PLL_2X, P1XCLK or P2XCLK */ + + setCurrentClock(formatModeClockReg(pPLL)); + + /* Program panel PLL, if applicable */ + if (pPLL->clockType==PANEL_PLL || pPLL->clockType==PANEL_PLL_2X) + pokeRegisterDWord(PROGRAMMABLE_PLL_CONTROL, formatPllReg(pPLL)); + + /* Frame buffer base for this mode */ + setDisplayBaseAddress(PANEL_CTRL, ulBaseAddress); + + /* Pitch value (Sometime, hardware people calls it Offset) */ + pokeRegisterDWord(PANEL_FB_WIDTH, FIELD_VALUE(0, PANEL_FB_WIDTH, WIDTH, ulPitch) | FIELD_VALUE(0, PANEL_FB_WIDTH, OFFSET, ulPitch)); + + pokeRegisterDWord(PANEL_WINDOW_WIDTH, FIELD_VALUE(0, PANEL_WINDOW_WIDTH, WIDTH, pModeParam->horizontal_display_end) | FIELD_VALUE(0, PANEL_WINDOW_WIDTH, X, 0)); + + pokeRegisterDWord(PANEL_WINDOW_HEIGHT, FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, HEIGHT, pModeParam->vertical_display_end) | FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, Y, 0)); + + pokeRegisterDWord(PANEL_PLANE_TL, FIELD_VALUE(0, PANEL_PLANE_TL, TOP, 0) | FIELD_VALUE(0, PANEL_PLANE_TL, LEFT, 0)); + + pokeRegisterDWord(PANEL_PLANE_BR, FIELD_VALUE(0, PANEL_PLANE_BR, BOTTOM, pModeParam->vertical_display_end - 1) | FIELD_VALUE(0, PANEL_PLANE_BR, RIGHT, pModeParam->horizontal_display_end - 1)); + + pokeRegisterDWord(PANEL_HORIZONTAL_TOTAL, FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) | FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); + + pokeRegisterDWord(PANEL_HORIZONTAL_SYNC, FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) | FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); + + pokeRegisterDWord(PANEL_VERTICAL_TOTAL, FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) | FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); + + pokeRegisterDWord(PANEL_VERTICAL_SYNC, FIELD_VALUE(0, PANEL_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) | FIELD_VALUE(0, PANEL_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); + + /* Set control register value */ + ulTmpValue = + (pModeParam->clock_phase_polarity == POS + ? FIELD_SET(0, PANEL_DISPLAY_CTRL, CLOCK_PHASE, ACTIVE_HIGH) + : FIELD_SET(0, PANEL_DISPLAY_CTRL, CLOCK_PHASE, ACTIVE_LOW)) + | (pModeParam->vertical_sync_polarity == POS + ? FIELD_SET(0, PANEL_DISPLAY_CTRL, VSYNC_PHASE, ACTIVE_HIGH) + : FIELD_SET(0, PANEL_DISPLAY_CTRL, VSYNC_PHASE, ACTIVE_LOW)) + | (pModeParam->horizontal_sync_polarity == POS + ? FIELD_SET(0, PANEL_DISPLAY_CTRL, HSYNC_PHASE, ACTIVE_HIGH) + : FIELD_SET(0, PANEL_DISPLAY_CTRL, HSYNC_PHASE, ACTIVE_LOW)) + | FIELD_SET(0, PANEL_DISPLAY_CTRL, TIMING, ENABLE) + | FIELD_SET(0, PANEL_DISPLAY_CTRL, PLANE, ENABLE) + | (ulBpp == 8 + ? FIELD_SET(0, PANEL_DISPLAY_CTRL, FORMAT, 8) + : (ulBpp == 16 + ? FIELD_SET(0, PANEL_DISPLAY_CTRL, FORMAT, 16) + : FIELD_SET(0, PANEL_DISPLAY_CTRL, FORMAT, 32))); + + /* Added some masks to mask out the reserved bits. + * Sometimes, the reserved bits are set/reset randomly when + * writing to the PANEL_DISPLAY_CTRL, therefore, the register + * reserved bits are needed to be masked out. RA 2008.01.02 + */ + ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | + FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE); + + ulReg = (peekRegisterDWord(PANEL_DISPLAY_CTRL) & ~ulReservedBits) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, CLOCK_PHASE) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, VSYNC_PHASE) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, HSYNC_PHASE) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, TIMING) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, VERTICAL_PAN) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, HORIZONTAL_PAN) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, PLANE) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, FORMAT); + + pokeRegisterDWord(PANEL_DISPLAY_CTRL, ulTmpValue | ulReg); + + /* May a hardware bug or just my test chip (not confirmed). + * PANEL_DISPLAY_CTRL register seems requiring few writes + * before a value can be succesfully written in. + * Added some masks to mask out the reserved bits. RA 2007.10.17 + */ + while((peekRegisterDWord(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulTmpValue|ulReg)) + { + pokeRegisterDWord(PANEL_DISPLAY_CTRL, ulTmpValue | ulReg); + } + + /* Palette RAM */ + palette_ram = PANEL_PALETTE_RAM; + } + + /* In case of 8-bpp, fill palette */ + if (ulBpp==8) + { + /* Start with RGB = 0,0,0. */ + unsigned char red = 0, green = 0, blue = 0; + unsigned long gray = 0; + for (offset = 0; offset < 256 * 4; offset += 4) + { + /* Store current RGB value. */ + pokeRegisterDWord(palette_ram + offset, gray + ? RGB((gray + 50) / 100, + (gray + 50) / 100, + (gray + 50) / 100) + : RGB(red, green, blue)); + + if (gray) + { + /* Walk through grays (40 in total). */ + gray += 654; + } + + else + { + /* Walk through colors (6 per base color). */ + if (blue != 255) + { + blue += 51; + } + else if (green != 255) + { + blue = 0; + green += 51; + } + else if (red != 255) + { + green = blue = 0; + red += 51; + } + else + { + gray = 1; + } + } + } + } + + /* For 16- and 32-bpp, fill palette with gamma values. */ + else + { + /* Start with RGB = 0,0,0. */ + ulTmpValue = 0x000000; + for (offset = 0; offset < 256 * 4; offset += 4) + { + pokeRegisterDWord(palette_ram + offset, ulTmpValue); + + /* Advance RGB by 1,1,1. */ + ulTmpValue += 0x010101; + } + } +} + +/* + * This function gets the available clock type + * + */ +clock_type_t getClockType(disp_control_t dispCtrl) +{ + clock_type_t clockType; + + switch(getChipType()) + { + case SM501: + { + clockType = (dispCtrl == PANEL_CTRL)? P2XCLK:V2XCLK; + } + break; + + case SM107: + case SM502: + { + clockType = (dispCtrl == PANEL_CTRL)? PANEL_PLL:V1XCLK; + } + break; + + default: + { + clockType = P1XCLK; + } + } + + /* For 2x Display clock, there are currently only 2 choices (P2XCLK or V2XCLK). + For future enhancement, we can use 2x on the PANEL_PLL. More code modification is + needed. + */ + if (gForce2xDisplayClock) + { + clockType = (dispCtrl == PANEL_CTRL)? P2XCLK:V2XCLK; + } + + return clockType; +} + +/* + * Input: + * 1) pLogicalMode contains information such as x, y resolution and bpp. + * 2) A user defined parameter table for the mode. + * + * This function calculate and programs the hardware to set up the + * requested mode. + * + * This function allows the use of user defined parameter table if + * predefined Vesa parameter table (gModeParamTable) does not fit. + * + * Return: 0 (or NO_ERROR) if mode can be set successfully. + * -1 if any set mode error. + */ +long setCustomMode(logicalMode_t *pLogicalMode, mode_parameter_t *pUserModeParam) +{ + mode_parameter_t pModeParam; /* physical parameters for the mode */ + pll_value_t pll; + unsigned long ulActualPixelClk, ulAddress, ulTemp; + + /* + * Minimum check on mode base address. + * At least it shouldn't be bigger than the size of frame buffer. + */ + if (ddk502_getFrameBufSize() <= pLogicalMode->baseAddress) + return -1; + + /* + * Set up PLL, a structure to hold the value to be set in clocks. + */ + pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */ + + /* Get the Clock Type */ + pll.clockType = getClockType(pLogicalMode->dispCtrl); + + /* + * Call calcPllValue() to fill up the other fields for PLL structure. + * Sometime, the chip cannot set up the exact clock required by User. + * Return value from calcPllValue() gives the actual possible pixel clock. + */ + ulActualPixelClk = calcPllValue(pUserModeParam->pixel_clock, &pll); + + /* + * Adjust Vesa mode parameter to feasible mode parameter for SMI hardware. + */ + if (adjustVesaModeParam(pUserModeParam, &pModeParam, ulActualPixelClk) != 0 ) + { + return -1; + } + + /* If calling function don't have a preferred pitch value, + work out a 16 byte aligned pitch value. + */ + if (pLogicalMode->pitch == 0) + { + /* + * Pitch value calculation in Bytes. + * Usually, it is (screen width) * (byte per pixel). + * However, there are cases that screen width is not 16 pixel aligned, which is + * a requirement for some OS and the hardware itself. + * For standard 4:3 resolutions: 320, 640., 800, 1024 and 1280, they are all + * 16 pixel aligned and pitch is simply (screen width) * (byte per pixel). + * + * However, 1366 resolution, for example, has to be adjusted for 16 pixel aligned. + */ + + ulTemp = (pLogicalMode->x + 15) & ~15; /* This calculation has no effect on 640, 800, 1024 and 1280. */ + pLogicalMode->pitch = ulTemp * (pLogicalMode->bpp / 8); + } +#if 0 + /* Clean the video memory to 0 */ + ulTemp = pLogicalMode->pitch * pLogicalMode->y; + for (ulAddress = 0; ulAddress < ulTemp; ulAddress+=4) + pokeDWord(pLogicalMode->baseAddress + ulAddress, 0); +#endif + /* Program the hardware to set up the mode. */ + programModeRegisters( + &pModeParam, + pLogicalMode->bpp, + pLogicalMode->baseAddress, + pLogicalMode->pitch, + &pll); + + /* Adjust window width for virtual mode, if applied */ + if (pLogicalMode->virtual == 1 && pLogicalMode->dispCtrl == PANEL_CTRL) + { + pokeRegisterDWord(PANEL_WINDOW_WIDTH, + FIELD_VALUE(0, PANEL_WINDOW_WIDTH, WIDTH, pLogicalMode->x) + | FIELD_VALUE(0, PANEL_WINDOW_WIDTH, X, 0)); + + pokeRegisterDWord(PANEL_WINDOW_HEIGHT, + FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, HEIGHT, pLogicalMode->y) + | FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, Y, 0)); + } + + /* Save the current mode */ + if (pLogicalMode->dispCtrl == PANEL_CTRL) + gPanelCurrentModeParam = pModeParam; + else + gCRTCurrentModeParam = pModeParam; + + //by ilena + pokeRegisterDWord(MISC_CTRL, FIELD_SET(peekRegisterDWord(MISC_CTRL), + MISC_CTRL, DAC_POWER, ENABLE)); + return(0); +} + +/* + * Input pLogicalMode contains information such as x, y resolution and bpp. + * Refer to MODE.h for the details. + * + * This function calculate and programs the hardware to set up the + * requested mode. + * + * Return: 0 (or NO_ERROR) if mode can be set successfully. + * -1 if any set mode error. + */ +_X_EXPORT long ddk502_setModeTiming(logicalMode_t *pLogicalMode) +{ + mode_parameter_t *pVesaModeParam; /* physical parameters for the mode */ + unsigned long modeX, modeY; + + if (pLogicalMode->virtual == 1 && pLogicalMode->dispCtrl == PANEL_CTRL) + { + /* Use panel size to set mode time */ + modeX = pLogicalMode->xLCD; + modeY = pLogicalMode->yLCD; + } + else + { + /* Use resolution to set mode time */ + modeX = pLogicalMode->x; + modeY = pLogicalMode->y; + } + + /* + * Check if we already have physical timing parameter for this mode. + */ + pVesaModeParam = (mode_parameter_t *)findVesaModeParam(modeX, modeY, pLogicalMode->hz); + if (pVesaModeParam == (mode_parameter_t *)0) + return -1; + + return(setCustomMode(pLogicalMode, pVesaModeParam)); +} diff --git a/src/ddk502/ddk502_mode.h b/src/ddk502/ddk502_mode.h new file mode 100644 index 0000000..6b20242 --- /dev/null +++ b/src/ddk502/ddk502_mode.h @@ -0,0 +1,157 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* MODE.H --- SMI DDK +* This file contains the definitions for the mode tables. +* +*******************************************************************/ +#ifndef _MODE_H_ +#define _MODE_H_ + +#include "ddk502_display.h" /* This file uses a definition in DISPLAY.H */ + +typedef enum _spolarity_t +{ + POS, /* positive */ + NEG, /* negative */ +} +spolarity_t; + +typedef struct _mode_parameter_t +{ + /* Horizontal timing. */ + unsigned long horizontal_total; + unsigned long horizontal_display_end; + unsigned long horizontal_sync_start; + unsigned long horizontal_sync_width; + spolarity_t horizontal_sync_polarity; + + /* Vertical timing. */ + unsigned long vertical_total; + unsigned long vertical_display_end; + unsigned long vertical_sync_start; + unsigned long vertical_sync_height; + spolarity_t vertical_sync_polarity; + + /* Refresh timing. */ + unsigned long pixel_clock; + unsigned long horizontal_frequency; + unsigned long vertical_frequency; + + /* Clock Phase. This clock phase only applies to Panel. */ + spolarity_t clock_phase_polarity; +} +mode_parameter_t; + +typedef struct _logicalMode_t +{ + long x; /* X resolution */ + long y; /* Y resolution */ + long bpp; /* Bits per pixel */ + long hz; /* Refresh rate */ + + long baseAddress; /* Offset from beginning of frame buffer. + It is used to control the starting location of a mode. + Calling function must initialize this field. + */ + + long pitch; /* Mode pitch in byte. + If initialized to 0, setMode function will set + up this field. + If not zero, setMode function will use this value. + */ + + disp_control_t dispCtrl; /* CRT or PANEL display control channel */ + + long virtual; /* 0 = off, 1 = on */ + + /* When virtual is off, xLCD and yLCD are not used bacause assuming + xLCD = x and yLCD = y. + + When virtual is on, xLCD != x and yLCD != y. + if xLCD and yLCD are smaller than x and y, then we have panning. + if xLCD are yLCD are bigger than x and y, we have wrap around. + */ + long xLCD; /* LCD width */ + long yLCD; /* LCD height */ + + void *userData; /* Not used now, for future only */ +} +logicalMode_t; + +/* + * This function sets the flag to force the clock to use 2x. + * Set it to 1 to force 2x clock. + */ +void set2xDisplayClock(unsigned char ucForce2xDisplayClock); + +/* This function gets the 2x Display Clock flag */ +unsigned char get2xDisplayClock(void); + +/* Get the display clock multiplier */ +unsigned char getDisplayClkMultiplier(disp_control_t dispControl); + +/* + * Return a point to the gModeParamTable. + * Function in other files used this to get the mode table pointer. + */ +mode_parameter_t *getStockModeParamTable(void); + +/* + * Return the size of the Stock Mode Param Table + */ +unsigned long getStockModeParamTableSize(); + +/* + * This function returns the current mode. + */ +mode_parameter_t getCurrentModeParam( + disp_control_t dispCtrl +); + +long setCustomMode( + logicalMode_t *pLogicalMode, + mode_parameter_t *pUserModeParam +); + +long ddk502_setModeTiming( + logicalMode_t *pLogicalMode +); + +mode_parameter_t *findVesaModeParam( + unsigned long width, + unsigned long height, + unsigned long refresh_rate +); + +/* + * This function sets the display base address + * + * Input: + * dispControl - display control of which base address to be set. + * ulBaseAddress - Base Address value to be set. + */ +void setDisplayBaseAddress( + disp_control_t dispControl, + unsigned long ulBaseAddress +); + +/* + * This function gets the display status + * + * Input: + * dispControl - display control of which display status to be retrieved. + * + * Output: + * 0 - Display is pending + * -1 - Display is not pending + */ +long isCurrentDisplayPending( + disp_control_t dispControl +); + +#endif /* _MODE_H_ */ diff --git a/src/ddk502/ddk502_os.c b/src/ddk502/ddk502_os.c new file mode 100644 index 0000000..ec25505 --- /dev/null +++ b/src/ddk502/ddk502_os.c @@ -0,0 +1,26 @@ +/******************************************************************* +* +* Copyright (c) 2008 by Silicon Motion, Inc. (SMI) +* +* OS.C --- VGX family DDK +* +* OS or platform dependent files are conditionally compiled here. +* +*******************************************************************/ +#include "ddk502_os.h" + +#if 0 +/* + * Use WATCOM DOS Extender compiler to implement the functions in OS.H + */ +#ifdef WDOSE +#include "ddk502_WATCOM.C" +#endif +#endif + +/* + * Use Linux compiler to implement the functions in OS.H + */ +#ifdef LINUX +#include "ddk502_linux.c" +#endif diff --git a/src/ddk502/ddk502_os.h b/src/ddk502/ddk502_os.h new file mode 100644 index 0000000..381e78f --- /dev/null +++ b/src/ddk502/ddk502_os.h @@ -0,0 +1,362 @@ +/******************************************************************* +* +* Copyright (c) 2008 by Silicon Motion, Inc. (SMI) +* +* OS.H --- VGX family DDK +* +* +*******************************************************************/ +#ifndef _OS_H_ +#define _OS_H_ + +typedef enum _intel_cpu_id_t +{ + INTEL_CPU_ID_8086_8088 = 0, + INTEL_CPU_ID_186_188, + INTEL_CPU_ID_286, + INTEL_CPU_ID_386, + INTEL_CPU_ID_486, + INTEL_CPU_ID_586 +} +intel_cpu_id_t; + +/* + * Important: + * How to implement the functions here is OS, bus and CPU dependent. + * Please refer to OS.C as an implementation example for WATCOM DOS extender. + * + * By keeping the same interface here, rest of the codes in this DDK are + * pretty much portable for different compilers. + */ + +/* + * This function reads a DWord value from the PCI configuration space + * of a specific PCI device. + * + * Inputs are the Vendor and device ID of the device in question. + * Return: a DWord value. + */ +unsigned long readPCIDword( + unsigned short vendorId, /* PCI vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum, /* If more than one device in system, device number are ordered as 0, 1, 2,... */ + unsigned short offset /* Offset in configuration space to be read */ +); + +/* + * This function writes a dword value to the PCI configuration space + * of a specific device. + * + * Inputs are the Vendor and device ID of the device in question. + * Return: 0 = Success. + * -1 = Fail. + */ +long writePCIDword( + unsigned short vendorId, /* PCI vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum, /* If more than one device in system, device number are ordered as 0, 1, 2,... */ + unsigned short offset, /* Offset in configuration space to be written */ + unsigned long value /* To be written BYTE value */ +); + +/* + * This function reads a Word value from the PCI configuration space + * of a specific device. + * + * Inputs are the Vendor and device ID of the device in question. + * Return: a WORD value. + */ +unsigned short readPCIWord( + unsigned short vendorId, /* PCI vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum, /* If more than one device in system, device number are ordered as 0, 1, 2,... */ + unsigned short offset /* Offset in configuration space to be read */ +); + +/* + * This function writes a word value to the PCI configuration space + * of a specific device. + * + * Inputs are the Vendor and device ID of the device in question. + * Return: 0 = Success. + * -1 = Fail. + */ +long writePCIWord( + unsigned short vendorId, /* PCI vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum, /* If more than one device in system, device number are ordered as 0, 1, 2,... */ + unsigned short offset, /* Offset in configuration space to be written */ + unsigned short value /* To be written BYTE value */ +); + +/* + * This function reads a byte value from the PCI configuration space + * of a specific device. + * + * Inputs are the Vendor and device ID of the device in question. + * Return: a BYTE value. + */ +unsigned char readPCIByte( + unsigned short vendorId, /* PCI Vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum, /* If more than one device in system, device number are ordered as 0, 1, 2,... */ + unsigned short offset /* Offset in configuration space to be read */ +); + +/* + * This function writes a byte value to the PCI configuration space + * of a specific device. + * + * Inputs are the Vendor and device ID of the device in question. + * Return: 0 = Success. + * -1 = Fail. + */ +long writePCIByte( + unsigned short vendorId, /* PCI vendor ID */ + unsigned short deviceId, /* PCI device ID */ + unsigned short deviceNum, /* If more than one device in system, device number are ordered as 0, 1, 2,... */ + unsigned short offset, /* Offset in configuration space to be written */ + unsigned char value /* To be written BYTE value */ +); + +/* + * This function maps a physical address into logical address. + * Return: NULL address pointer if fail + * A Logical address pointer if success. + */ +void *mapPhysicalAddress( + void *phyAddr, /* 32 bit physical address */ + unsigned long size /* Memory size to be mapped */ +); + +/* + * This function unmaps a linear logical address obtained by mapPhysicalAddress. + * Return: + * 0 - Success + * -1 - Fail + */ +long unmapPhysicalAddress( + void *linearAddr, /* 32 bit linear address */ + unsigned long size +); + +/******************************************************************* + * Time related functions + * + * This implementation can be used for performance analysis or delay + * function. + *******************************************************************/ + +/* Tick count will be reset after midnight 24 hours. Therefore, when the tick count counter + reset, it means that it has passed the 24 hours boundary. + A Timer tick occurs every 1,193,180 / 65536 (= ~18.20648) times per second. + The maximum tick count is calculated as follows: (24*3600*1000/54.9254) = ~1573040 + */ +#define MAX_TICKCOUNT 1573040 +unsigned long getSystemTickCount(); + +/* Get current time in milliseconds. */ +#define MAX_TIME_VALUE (24*3600*1000) +unsigned long getCurrentTime(); + +/******************************************************************* + * Interrupt implementation support from the OS + * + * This implementation is used for handling the interrupt. + *******************************************************************/ + +/* + * Register an interrupt handler (ISR) to the interrupt vector table associated + * with the given irq number. + * + * Input: + * irqNumber - IRQ Number + * pfnHandler - Pointer to the ISR function + * + * Output: + * 0 - Success + * -1 - Fail + */ +short registerInterrupt( + unsigned char irqNumber, +#ifdef WDOSE + void (interrupt far *pfnHandler)() +#else + void (*pfnHandler)() +#endif +); + +/* + * Unregister an interrupt handler from the interrupt vector table + * + * Input: + * irqNumber - IRQ Number + */ +short unregisterInterrupt( + unsigned char irqNumber +); + +/* + * Signal the End Of Interrupt to the system and chain the interrupt + * if necessary. + * + * Input: + * irqNumber - IRQ Number + */ +void interruptEOI( + unsigned char irqNumber +); + +/******************************************************************* + * Timer Interrupt implementation + * + * This implementation is used for handling the SM50x interrupt. + *******************************************************************/ + +/* + * Register an interrupt handler function to an interrupt status. + * The interrupt is happens every 55ms, or about 18.2 ticks per second. + */ +short registerTimerHandler( + void (*handler)(void), + unsigned long totalTicks /* Total number of ticks to wait */ +); + +/* + * Un-register a registered interrupt handler + */ +short unregisterTimerHandler( + void (*handler)(void) +); + +/******************************************************************* + * COM Port implementation + * + * This implementation is used by Debug module to send any + * debugging messages to other system through serial port. + *******************************************************************/ +typedef enum _baud_rate_t +{ + COM_2400 = 0, + COM_4800, + COM_9600, + COM_19200, + COM_38400, + COM_57600, + COM_115200 +} +baud_rate_t; + +typedef enum _data_size_t +{ + DATA_SIZE_8, + DATA_SIZE_7 +} +data_size_t; + +typedef enum _parity_t +{ + PARITY_NONE = 0, + PARITY_ODD, + PARITY_EVEN, + PARITY_SPACE +} +parity_t; + +typedef enum _stop_bit_t +{ + STOP_BIT_1, + STOP_BIT_2 +} +stop_bit_t; + +typedef enum _flow_ctrl_t +{ + FLOW_CONTROL_NONE = 0, + FLOW_CONTROL_HW, + FLOW_CONTROL_SW +} +flow_ctrl_t; + +/* + * Initialize the serial port. + * + * Parameters: + * comPortIndex - Serial Port Index + * baudRate - The communication speed to be set + * dataSize - Number of bits per characters + * parity - Error checking + * stopBit - Number of bits used as the end of each character + * flowCtrl - Serial port Flow Control (handshake) + * + * Returns: + * 0 - Success + * -1 - Fail + */ +long comInit( + unsigned char comPortIndex, + baud_rate_t baudRate, + data_size_t dataSize, + parity_t parity, + stop_bit_t stopBit, + flow_ctrl_t flowCtrl +); + +/* + * Send data out to through the serial port. + * + * Parameters: + * pszPrintBuffer - Pointer to a buffer which data to be sent out + * length - Number of characters to be sent out. + * + * Returns: + * Number of characters that are actually sent out. + */ +unsigned long comWrite( + char* pszPrintBuffer, + unsigned long length +); + +/* + * Close the serial communication port. + */ +void comClose(); + +/******************************************************************* + * CPU implementation support from the OS + * + * This implementation is used to supports Write Combine. + * It only applies to Pentium Pro. + *******************************************************************/ + +/* + * detectCPU + * This function detects the CPU ID + * + * Output: + * INTEL_CPU_ID_8086_8088 - 8086/8088 Intel CPU + * INTEL_CPU_ID_186_188 - 186 Intel CPU + * INTEL_CPU_ID_286 - 286 Intel CPU + * INTEL_CPU_ID_386 - 386 Intel CPU + * INTEL_CPU_ID_486 - 486 Intel CPU + * INTEL_CPU_ID_586 - 586 Intel CPU (Pentium) + */ +intel_cpu_id_t detectIntelCPU(); + +/* + * This function enable the write combine (burst) + */ +long registerWCMemoryRange( + void *phyAddr, /* 32 bit physical address */ + unsigned long size +); + +/* + * This function enable the write combine (burst) + */ +long unregisterWCMemoryRange( + void *phyAddr, /* 32 bit physical address */ + unsigned long size +); + +#endif /* _OS_H_ */ diff --git a/src/ddk502/ddk502_power.c b/src/ddk502/ddk502_power.c new file mode 100644 index 0000000..f9546e5 --- /dev/null +++ b/src/ddk502/ddk502_power.c @@ -0,0 +1,487 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* power.c --- Voyager GX SDK +* This file contains the source code for the power functions. +* +*******************************************************************/ +#include "ddk502_voyager.h" +#include "ddk502_hardware.h" +#include "ddk502_power.h" +#include "ddk502_help.h" + +/* Semaphore Counter for Bus Master Enable Bit */ +unsigned long g_ulBusMasterSemaphoreCounter[MAX_SMI_DEVICE] = { 0, 0, 0, 0}; +unsigned long g_ulPCISlaveBurstWriteSemaphoreCounter[MAX_SMI_DEVICE] = { 0, 0, 0, 0}; +unsigned long g_ulPCISlaveBurstReadSemaphoreCounter[MAX_SMI_DEVICE] = { 0, 0, 0, 0}; +unsigned long g_ulHostSemaphoreCounter[MAX_SMI_DEVICE] = { 0, 0, 0, 0}; + +/* Program new power mode */ +void setPower(unsigned long Gate, unsigned long Clock) +{ + unsigned long gate_reg, clock_reg; + unsigned long control_value; + + /* Get current power mode */ + control_value = FIELD_GET(peekRegisterDWord(POWER_MODE_CTRL), + POWER_MODE_CTRL, + MODE); + + /* Switch from mode 1 or sleep to mode 0 */ + gate_reg = POWER_MODE0_GATE; + clock_reg = POWER_MODE0_CLOCK; + control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, MODE0); + + /* Program new power mode */ + pokeRegisterDWord(gate_reg, Gate); + pokeRegisterDWord(clock_reg, Clock); + pokeRegisterDWord(POWER_MODE_CTRL, control_value); + + /* When returning from sleep, wait until finished */ + while (FIELD_GET(peekRegisterDWord(POWER_MODE_CTRL), POWER_MODE_CTRL, + SLEEP_STATUS) == POWER_MODE_CTRL_SLEEP_STATUS_ACTIVE) ; +} + +/* Set DPMS state */ +_X_EXPORT void ddk502_setDPMS(DPMS_t state) +{ + unsigned long value; + + value = peekRegisterDWord(SYSTEM_CTRL); + switch (state) + { + case DPMS_ON: + value = FIELD_SET(value, SYSTEM_CTRL, DPMS, VPHP); + break; + + case DPMS_STANDBY: + value = FIELD_SET(value, SYSTEM_CTRL, DPMS, VPHN); + break; + + case DPMS_SUSPEND: + value = FIELD_SET(value, SYSTEM_CTRL, DPMS, VNHP); + break; + + case DPMS_OFF: + value = FIELD_SET(value, SYSTEM_CTRL, DPMS, VNHN); + break; + } + + pokeRegisterDWord(SYSTEM_CTRL, value); +} + +/* + * This function gets the power mode, one of three modes: 0, 1 or Sleep. + * On hardware reset, power mode 0 is default. + */ +unsigned long getPowerMode() +{ + return (FIELD_GET(peekRegisterDWord(POWER_MODE_CTRL), POWER_MODE_CTRL, MODE)); +} + +/* + * SM50x can operate in one of three modes: 0, 1 or Sleep. + * On hardware reset, power mode 0 is default. + */ +void setPowerMode(unsigned long powerMode) +{ + unsigned long control_value = 0; + + switch (powerMode) + { + case POWER_MODE_CTRL_MODE_MODE0: + control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, MODE0); + break; + + case POWER_MODE_CTRL_MODE_MODE1: + control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, MODE1); + break; + + case POWER_MODE_CTRL_MODE_SLEEP: + control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, SLEEP); + break; + + default: + break; + } + + /* Program new power mode. */ + pokeRegisterDWord(POWER_MODE_CTRL, control_value); + + /* When returning from sleep, wait until finished. */ + while (FIELD_GET(peekRegisterDWord(POWER_MODE_CTRL), POWER_MODE_CTRL, + SLEEP_STATUS) == POWER_MODE_CTRL_SLEEP_STATUS_ACTIVE) ; +} + +_X_EXPORT void ddk502_setCurrentGate(unsigned long gate) +{ + unsigned long gate_reg, clock_reg; + unsigned long control_value = 0; + + /* Get current power mode. */ + control_value = FIELD_GET(peekRegisterDWord(POWER_MODE_CTRL), + POWER_MODE_CTRL, + MODE); + + switch (control_value) + { + case POWER_MODE_CTRL_MODE_MODE0: + gate_reg = POWER_MODE0_GATE; + break; + + case POWER_MODE_CTRL_MODE_MODE1: + gate_reg = POWER_MODE1_GATE; + break; + + case POWER_MODE_CTRL_MODE_SLEEP: + + default: + return; /* Nothing to set in sleep mode */ + } + pokeRegisterDWord(gate_reg, gate); +} + +void setCurrentClock(unsigned long clock) +{ + unsigned long clock_reg; + unsigned long control_value = 0; + + /* Get current power mode. */ + control_value = FIELD_GET(peekRegisterDWord(POWER_MODE_CTRL), + POWER_MODE_CTRL, + MODE); + + switch (control_value) + { + case POWER_MODE_CTRL_MODE_MODE0: + clock_reg = POWER_MODE0_CLOCK; + break; + + case POWER_MODE_CTRL_MODE_MODE1: + clock_reg = POWER_MODE1_CLOCK; + break; + + case POWER_MODE_CTRL_MODE_SLEEP: + default: + return; /* Nothing to set in sleep mode */ + } + pokeRegisterDWord(clock_reg, clock); +} + + +/* + * This function enable/disable Bus Master + */ +void enableBusMaster(unsigned long enable) +{ + unsigned long busMasterCounter, value; + + /* Enable Bus Master as necessary.*/ + busMasterCounter = g_ulBusMasterSemaphoreCounter[getCurrentDevice()]; + value = peekRegisterDWord(SYSTEM_CTRL); + + if (enable) + { + if (busMasterCounter == 0) + { + value = FIELD_SET(value, SYSTEM_CTRL, PCI_MASTER, START); +#if 1 /* Is it necessary to enable/disable the PCI Clock Run??? */ + value = FIELD_SET(value, SYSTEM_CTRL, PCI_CLOCK_RUN, ENABLE); +#endif + /*enableHost(1);*/ + pokeRegisterDWord(SYSTEM_CTRL, value); + } + + busMasterCounter++; + } + else + { + if (busMasterCounter > 0) + busMasterCounter--; + + if (busMasterCounter == 0) + { + value = FIELD_SET(value, SYSTEM_CTRL, PCI_MASTER, STOP); +#if 1 /* Is it necessary to enable/disable PCI Clock Run??? */ + value = FIELD_SET(value, SYSTEM_CTRL, PCI_CLOCK_RUN, DISABLE); +#endif + /*enableHost(0);*/ + pokeRegisterDWord(SYSTEM_CTRL, value); + } + } + + g_ulBusMasterSemaphoreCounter[getCurrentDevice()] = busMasterCounter; +} + +/* + * setPCIMasterBaseAddress + * This function set the PCI Master Base Address (used by bus master or DMA). + * + * Input: + * physicalSystemMemAddress - System physical memory address which PCI + * Master Base Address to be set to. + * + * Output: + * The memory address to be set in the register. + */ +unsigned long setPCIMasterBaseAddress( + unsigned long physicalSystemMemAddress +) +{ + unsigned long pciMasterBaseAddress; + + /* Set System Memory Address */ + pciMasterBaseAddress = FIELD_VALUE(0, PCI_MASTER_BASE, ADDRESS, physicalSystemMemAddress & 0xFFF00000); + pokeRegisterDWord(PCI_MASTER_BASE, pciMasterBaseAddress); + + /* Send back the remaining address */ + return (physicalSystemMemAddress - pciMasterBaseAddress); +} + +/* + * This function enable/disable PCI Slave Burst Write provided the CPU supports Write Combine. + * + * Input: + * enable - Enable/Disable the PCI Slave Burst Write (0 = disable, 1 = enable) + */ +void enablePCISlaveBurstWrite( + unsigned long enable +) +{ + unsigned long pciSlaveBurstWriteCounter, value; + + /* Enable PCI Slave Burst Write */ + pciSlaveBurstWriteCounter = g_ulPCISlaveBurstWriteSemaphoreCounter[getCurrentDevice()]; + value = peekRegisterDWord(SYSTEM_CTRL); + + if (enable != 0) + { + if (pciSlaveBurstWriteCounter == 0) + { + /* Enable PCI Slave Burst Write. */ + value = FIELD_SET(peekRegisterDWord(SYSTEM_CTRL), SYSTEM_CTRL, PCI_BURST, ENABLE); + pokeRegisterDWord(SYSTEM_CTRL, value); + } + + pciSlaveBurstWriteCounter++; + } + else + { + if (pciSlaveBurstWriteCounter > 0) + pciSlaveBurstWriteCounter--; + + if (pciSlaveBurstWriteCounter == 0) + { + /* Disable PCI Slave Burst Write */ + value = FIELD_SET(peekRegisterDWord(SYSTEM_CTRL), SYSTEM_CTRL, PCI_BURST, DISABLE); + pokeRegisterDWord(SYSTEM_CTRL, value); + } + } + + g_ulPCISlaveBurstWriteSemaphoreCounter[getCurrentDevice()] = pciSlaveBurstWriteCounter; +} + +/* + * This function enable/disable PCI Slave Burst Read provided the CPU supports it. + * + * Input: + * enable - Enable/Disable the PCI Slave Burst Read (0 = disable, 1 = enable) + * burstReadSize - Burst Read Size in 32-words (valid values are 1, 2, 4, and 8) + */ +void enablePCISlaveBurstRead( + unsigned long enable, + unsigned long burstReadSize +) +{ + unsigned long pciSlaveBurstReadCounter, value; + + /* Currently, only SM718 needs to enable the Bus Master enable bit. + The Bus Master in SM750 is enabled by default, without programming any bits. */ + pciSlaveBurstReadCounter = g_ulPCISlaveBurstReadSemaphoreCounter[getCurrentDevice()]; + value = peekRegisterDWord(SYSTEM_CTRL); + + if (enable != 0) + { + if (pciSlaveBurstReadCounter == 0) + { + value = peekRegisterDWord(SYSTEM_CTRL); + + /* Enable PCI Slave Burst Read. */ + value = FIELD_SET(value, SYSTEM_CTRL, PCI_BURST_READ, ENABLE); + + /* Set the Read Size */ + switch(burstReadSize) + { + case 1: + value = FIELD_SET(value, SYSTEM_CTRL, PCI_SLAVE_BURST_READ_SIZE, 1); + break; + case 2: + value = FIELD_SET(value, SYSTEM_CTRL, PCI_SLAVE_BURST_READ_SIZE, 2); + break; + case 4: + value = FIELD_SET(value, SYSTEM_CTRL, PCI_SLAVE_BURST_READ_SIZE, 4); + break; + default: + case 8: + value = FIELD_SET(value, SYSTEM_CTRL, PCI_SLAVE_BURST_READ_SIZE, 8); + break; + } + pokeRegisterDWord(SYSTEM_CTRL, value); + } + + pciSlaveBurstReadCounter++; + } + else + { + if (pciSlaveBurstReadCounter > 0) + pciSlaveBurstReadCounter--; + + if (pciSlaveBurstReadCounter == 0) + { + /* Disable PCI Slave Burst */ + value = FIELD_SET(peekRegisterDWord(SYSTEM_CTRL), SYSTEM_CTRL, PCI_BURST_READ, DISABLE); + pokeRegisterDWord(SYSTEM_CTRL, value); + } + } + + g_ulPCISlaveBurstReadSemaphoreCounter[getCurrentDevice()] = pciSlaveBurstReadCounter; +} + +/* + * This function enable/disable the 2D engine. + */ +void enable2DEngine(unsigned long enable) +{ + unsigned long gate; + + gate = peekRegisterDWord(CURRENT_POWER_GATE); + if (enable) + { + gate = FIELD_SET(gate, CURRENT_POWER_GATE, 2D, ENABLE); + gate = FIELD_SET(gate, CURRENT_POWER_GATE, CSC, ENABLE); + } + else + { + gate = FIELD_SET(gate, CURRENT_POWER_GATE, 2D, DISABLE); + gate = FIELD_SET(gate, CURRENT_POWER_GATE, CSC, DISABLE); + } + + ddk502_setCurrentGate(gate); +} + +/* + * This function enable/disable the ZV Port. + */ +void enableZVPort( + unsigned long enable +) +{ + unsigned long gate; + + /* Enable ZV Port Gate */ + gate = peekRegisterDWord(CURRENT_POWER_GATE); + if (enable) + { + gate = FIELD_SET(gate, CURRENT_POWER_GATE, ZVPORT, ENABLE); + gate = FIELD_SET(gate, CURRENT_POWER_GATE, GPIO_PWM_I2C, ENABLE); + } + else + { + /* Disable ZV Port Gate. There is no way to know whether the GPIO pins are being used + or not. Therefore, do not disable the GPIO gate. */ + gate = FIELD_SET(gate, CURRENT_POWER_GATE, ZVPORT, DISABLE); + } + + ddk502_setCurrentGate(gate); +} + +/* + * This function enable/disable the 8051 gate + */ +void enable8051( + unsigned long enable +) +{ + unsigned long gate; + + gate = peekRegisterDWord(CURRENT_POWER_GATE); + if (enable) + { + /* Enable 8051 Gate */ + gate = FIELD_SET(gate, CURRENT_POWER_GATE, 8051, ENABLE); + } + else + { + /* Disable 8051 Gate */ + gate = FIELD_SET(gate, CURRENT_POWER_GATE, 8051, DISABLE); + } + + ddk502_setCurrentGate(gate); +} + +/* + * This function enable/disable the AC97 or I2S gate + */ +void enableAC97_I2S( + unsigned long enable +) +{ + unsigned long gate; + + gate = peekRegisterDWord(CURRENT_POWER_GATE); + if (enable) + { + /* Enable AC97/I2S Gate */ + gate = FIELD_SET(gate, CURRENT_POWER_GATE, AC97_I2S, ENABLE); + } + else + { + /* Disable AC97/I2S Gate */ + gate = FIELD_SET(gate, CURRENT_POWER_GATE, AC97_I2S, DISABLE); + } + + ddk502_setCurrentGate(gate); +} + +/* + * This function enable/disable the Host Interface, Command Interpreter, and DMA Engine + */ +void enableHost(unsigned long enable) +{ + unsigned long hostCounter, gate; + + hostCounter = g_ulHostSemaphoreCounter[getCurrentDevice()]; + + gate = peekRegisterDWord(CURRENT_POWER_GATE); + if (enable) + { + if (hostCounter == 0) + gate = FIELD_SET(gate, CURRENT_POWER_GATE, HOST, ENABLE); + + hostCounter++; + } + else + { + if (hostCounter > 0) + hostCounter--; + + if (hostCounter == 0) + gate = FIELD_SET(gate, CURRENT_POWER_GATE, HOST, DISABLE); + } + ddk502_setCurrentGate(gate); + + g_ulHostSemaphoreCounter[getCurrentDevice()] = hostCounter; +} + +/* + * This function enable/disable the Host Interface, Command Interpreter, and DMA Engine + */ +void enableDMA(unsigned long enable) +{ + enableHost(enable); +} + diff --git a/src/ddk502/ddk502_power.h b/src/ddk502/ddk502_power.h new file mode 100644 index 0000000..943cc5a --- /dev/null +++ b/src/ddk502/ddk502_power.h @@ -0,0 +1,126 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* power.h --- Voyager GX SDK +* This file contains the definitions for the power functions. +* +*******************************************************************/ +#ifndef _POWER_H_ +#define _POWER_H_ + +typedef enum _DPMS_t +{ + DPMS_ON, + DPMS_STANDBY, + DPMS_SUSPEND, + DPMS_OFF +} +DPMS_t; + +/* + * This function sets the current power state + */ +void setPower(unsigned long Gate, unsigned long Clock); + +/* + * This function sets the DPMS state + */ +void ddk502_setDPMS(DPMS_t state); + +/* + * This function gets the current power mode + */ +unsigned long getPowerMode(); + +/* + * This function sets the current power mode + */ +void setPowerMode(unsigned long powerMode); + +/* + * This function sets current gate + */ +void ddk502_setCurrentGate(unsigned long gate); + +/* + * This function sets the current clock + */ +void setCurrentClock(unsigned long clock); + +/* + * This function enable/disable Bus Master + */ +void enableBusMaster(unsigned long enable); + +/* + * This function enable/disable PCI Slave Burst Write provided the CPU supports Write Combine. + * + * Input: + * enable - Enable/Disable the PCI Slave Burst Write (0 = disable, 1 = enable) + */ +void enablePCISlaveBurstWrite( + unsigned long enable +); + +/* + * This function enable/disable PCI Slave Burst Read provided the CPU supports it. + * + * Input: + * enable - Enable/Disable the PCI Slave Burst Read (0 = disable, 1 = enable) + * burstReadSize - Burst Read Size in 32-words (valid values are 1, 2, 4, and 8) + */ +void enablePCISlaveBurstRead( + unsigned long enable, + unsigned long burstReadSize +); + +/* + * setPCIMasterBaseAddress + * This function set the PCI Master Base Address (used by bus master or DMA). + * + * Input: + * physicalSystemMemAddress - System physical memory address which PCI + * Master Base Address to be set to. + * + * Output: + * The memory address to be set in the register. + */ +unsigned long setPCIMasterBaseAddress( + unsigned long physicalSystemMemAddress +); + +/* + * This function enable/disable the 2D engine. + */ +void enable2DEngine(unsigned long enable); + +/* + * This function enable/disable the ZV Port + */ +void enableZVPort(unsigned long enable); + +/* + * This function enable/disable the 8051 gate + */ +void enable8051(unsigned long enable); + +/* + * This function enable/disable the AC97 or I2S gate + */ +void enableAC97_I2S(unsigned long enable); + +/* + * This function enable/disable the Host Interface, Command Interpreter, and DMA Engine + */ +void enableHost(unsigned long enable); + +/* + * This function enable/disable the DMA Engine + */ +void enableDMA(unsigned long enable); + +#endif /* _POWER_H_ */ diff --git a/src/ddk502/ddk502_regdc.h b/src/ddk502/ddk502_regdc.h new file mode 100644 index 0000000..8d51b69 --- /dev/null +++ b/src/ddk502/ddk502_regdc.h @@ -0,0 +1,769 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* RegDC.h --- Voyager GX SDK +* This file contains the definitions for the Display Controller registers. +* +*******************************************************************/ +/* Panel Graphics Control */ + +#define PANEL_DISPLAY_CTRL 0x080000 +#define PANEL_DISPLAY_CTRL_RESERVED_1_MASK 31:28 +#define PANEL_DISPLAY_CTRL_RESERVED_1_MASK_DISABLE 0 +#define PANEL_DISPLAY_CTRL_RESERVED_1_MASK_ENABLE 0xF +#define PANEL_DISPLAY_CTRL_FPEN 27:27 +#define PANEL_DISPLAY_CTRL_FPEN_LOW 0 +#define PANEL_DISPLAY_CTRL_FPEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_VBIASEN 26:26 +#define PANEL_DISPLAY_CTRL_VBIASEN_LOW 0 +#define PANEL_DISPLAY_CTRL_VBIASEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_DATA 25:25 +#define PANEL_DISPLAY_CTRL_DATA_DISABLE 0 +#define PANEL_DISPLAY_CTRL_DATA_ENABLE 1 +#define PANEL_DISPLAY_CTRL_FPVDDEN 24:24 +#define PANEL_DISPLAY_CTRL_FPVDDEN_LOW 0 +#define PANEL_DISPLAY_CTRL_FPVDDEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_PATTERN 23:23 +#define PANEL_DISPLAY_CTRL_PATTERN_4 0 +#define PANEL_DISPLAY_CTRL_PATTERN_8 1 +#define PANEL_DISPLAY_CTRL_TFT 22:21 +#define PANEL_DISPLAY_CTRL_TFT_24 0 +#define PANEL_DISPLAY_CTRL_TFT_9 1 +#define PANEL_DISPLAY_CTRL_TFT_12 2 +#define PANEL_DISPLAY_CTRL_DITHER 20:20 +#define PANEL_DISPLAY_CTRL_DITHER_DISABLE 0 +#define PANEL_DISPLAY_CTRL_DITHER_ENABLE 1 +#define PANEL_DISPLAY_CTRL_LCD 19:18 +#define PANEL_DISPLAY_CTRL_LCD_TFT 0 +#define PANEL_DISPLAY_CTRL_LCD_STN_8 2 +#define PANEL_DISPLAY_CTRL_LCD_STN_12 3 +#define PANEL_DISPLAY_CTRL_FIFO 17:16 +#define PANEL_DISPLAY_CTRL_FIFO_1 0 +#define PANEL_DISPLAY_CTRL_FIFO_3 1 +#define PANEL_DISPLAY_CTRL_FIFO_7 2 +#define PANEL_DISPLAY_CTRL_FIFO_11 3 +#define PANEL_DISPLAY_CTRL_8BIT_TV 15:15 +#define PANEL_DISPLAY_CTRL_8BIT_TV_DISABLE 0 +#define PANEL_DISPLAY_CTRL_8BIT_TV_ENABLE 1 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE 14:14 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE 13:13 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE 12:12 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_RESERVED_2_MASK 11:11 +#define PANEL_DISPLAY_CTRL_RESERVED_2_MASK_DISABLE 0 +#define PANEL_DISPLAY_CTRL_RESERVED_2_MASK_ENABLE 1 +#define PANEL_DISPLAY_CTRL_CAPTURE_TIMING 10:10 +#define PANEL_DISPLAY_CTRL_CAPTURE_TIMING_DISABLE 0 +#define PANEL_DISPLAY_CTRL_CAPTURE_TIMING_ENABLE 1 +#define PANEL_DISPLAY_CTRL_COLOR_KEY 9:9 +#define PANEL_DISPLAY_CTRL_COLOR_KEY_DISABLE 0 +#define PANEL_DISPLAY_CTRL_COLOR_KEY_ENABLE 1 +#define PANEL_DISPLAY_CTRL_TIMING 8:8 +#define PANEL_DISPLAY_CTRL_TIMING_DISABLE 0 +#define PANEL_DISPLAY_CTRL_TIMING_ENABLE 1 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR 7:7 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR_DOWN 0 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR_UP 1 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN 6:6 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DISABLE 0 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_ENABLE 1 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR 5:5 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR_RIGHT 0 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR_LEFT 1 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN 4:4 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DISABLE 0 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_ENABLE 1 +#define PANEL_DISPLAY_CTRL_GAMMA 3:3 +#define PANEL_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define PANEL_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define PANEL_DISPLAY_CTRL_PLANE 2:2 +#define PANEL_DISPLAY_CTRL_PLANE_DISABLE 0 +#define PANEL_DISPLAY_CTRL_PLANE_ENABLE 1 +#define PANEL_DISPLAY_CTRL_FORMAT 1:0 +#define PANEL_DISPLAY_CTRL_FORMAT_8 0 +#define PANEL_DISPLAY_CTRL_FORMAT_16 1 +#define PANEL_DISPLAY_CTRL_FORMAT_32 2 + +#define PANEL_PAN_CTRL 0x080004 +#define PANEL_PAN_CTRL_VERTICAL_PAN 31:24 +#define PANEL_PAN_CTRL_VERTICAL_VSYNC 21:16 +#define PANEL_PAN_CTRL_HORIZONTAL_PAN 15:8 +#define PANEL_PAN_CTRL_HORIZONTAL_VSYNC 5:0 + +#define PANEL_COLOR_KEY 0x080008 +#define PANEL_COLOR_KEY_MASK 31:16 +#define PANEL_COLOR_KEY_VALUE 15:0 + +#define PANEL_FB_ADDRESS 0x08000C +#define PANEL_FB_ADDRESS_STATUS 31:31 +#define PANEL_FB_ADDRESS_STATUS_CURRENT 0 +#define PANEL_FB_ADDRESS_STATUS_PENDING 1 +#define PANEL_FB_ADDRESS_EXT 27:27 +#define PANEL_FB_ADDRESS_EXT_LOCAL 0 +#define PANEL_FB_ADDRESS_EXT_EXTERNAL 1 +#define PANEL_FB_ADDRESS_CS 26:26 +#define PANEL_FB_ADDRESS_CS_0 0 +#define PANEL_FB_ADDRESS_CS_1 1 +#define PANEL_FB_ADDRESS_ADDRESS 25:0 + +#define PANEL_FB_WIDTH 0x080010 +#define PANEL_FB_WIDTH_WIDTH 29:16 +#define PANEL_FB_WIDTH_OFFSET 13:0 + +#define PANEL_WINDOW_WIDTH 0x080014 +#define PANEL_WINDOW_WIDTH_WIDTH 27:16 +#define PANEL_WINDOW_WIDTH_X 11:0 + +#define PANEL_WINDOW_HEIGHT 0x080018 +#define PANEL_WINDOW_HEIGHT_HEIGHT 27:16 +#define PANEL_WINDOW_HEIGHT_Y 11:0 + +#define PANEL_PLANE_TL 0x08001C +#define PANEL_PLANE_TL_TOP 26:16 +#define PANEL_PLANE_TL_LEFT 10:0 + +#define PANEL_PLANE_BR 0x080020 +#define PANEL_PLANE_BR_BOTTOM 26:16 +#define PANEL_PLANE_BR_RIGHT 10:0 + +#define PANEL_HORIZONTAL_TOTAL 0x080024 +#define PANEL_HORIZONTAL_TOTAL_TOTAL 27:16 +#define PANEL_HORIZONTAL_TOTAL_DISPLAY_END 11:0 + +#define PANEL_HORIZONTAL_SYNC 0x080028 +#define PANEL_HORIZONTAL_SYNC_WIDTH 23:16 +#define PANEL_HORIZONTAL_SYNC_START 11:0 + +#define PANEL_VERTICAL_TOTAL 0x08002C +#define PANEL_VERTICAL_TOTAL_TOTAL 26:16 +#define PANEL_VERTICAL_TOTAL_DISPLAY_END 10:0 + +#define PANEL_VERTICAL_SYNC 0x080030 +#define PANEL_VERTICAL_SYNC_HEIGHT 21:16 +#define PANEL_VERTICAL_SYNC_START 10:0 + +#define PANEL_CURRENT_LINE 0x080034 +#define PANEL_CURRENT_LINE_LINE 10:0 + +/* Video Control */ + +#define VIDEO_DISPLAY_CTRL 0x080040 +#define VIDEO_DISPLAY_CTRL_FIFO 17:16 +#define VIDEO_DISPLAY_CTRL_FIFO_1 0 +#define VIDEO_DISPLAY_CTRL_FIFO_3 1 +#define VIDEO_DISPLAY_CTRL_FIFO_7 2 +#define VIDEO_DISPLAY_CTRL_FIFO_11 3 +#define VIDEO_DISPLAY_CTRL_BUFFER 15:15 +#define VIDEO_DISPLAY_CTRL_BUFFER_0 0 +#define VIDEO_DISPLAY_CTRL_BUFFER_1 1 +#define VIDEO_DISPLAY_CTRL_CAPTURE 14:14 +#define VIDEO_DISPLAY_CTRL_CAPTURE_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_CAPTURE_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER 13:13 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP 12:12 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE 11:11 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE_NORMAL 0 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE_HALF 1 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE 10:10 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE_NORMAL 0 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE_HALF 1 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE 9:9 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE_REPLICATE 0 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE_INTERPOLATE 1 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE 8:8 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE_REPLICATE 0 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE_INTERPOLATE 1 +#define VIDEO_DISPLAY_CTRL_PIXEL 7:4 +#define VIDEO_DISPLAY_CTRL_GAMMA 3:3 +#define VIDEO_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_PLANE 2:2 +#define VIDEO_DISPLAY_CTRL_PLANE_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_PLANE_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_FORMAT 1:0 +#define VIDEO_DISPLAY_CTRL_FORMAT_8 0 +#define VIDEO_DISPLAY_CTRL_FORMAT_16 1 +#define VIDEO_DISPLAY_CTRL_FORMAT_32 2 +#define VIDEO_DISPLAY_CTRL_FORMAT_YUV 3 + +#define VIDEO_FB_0_ADDRESS 0x080044 +#define VIDEO_FB_0_ADDRESS_STATUS 31:31 +#define VIDEO_FB_0_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_FB_0_ADDRESS_STATUS_PENDING 1 +#define VIDEO_FB_0_ADDRESS_EXT 27:27 +#define VIDEO_FB_0_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_0_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_0_ADDRESS_CS 26:26 +#define VIDEO_FB_0_ADDRESS_CS_0 0 +#define VIDEO_FB_0_ADDRESS_CS_1 1 +#define VIDEO_FB_0_ADDRESS_ADDRESS 25:0 + +#define VIDEO_FB_WIDTH 0x080048 +#define VIDEO_FB_WIDTH_WIDTH 29:16 +#define VIDEO_FB_WIDTH_OFFSET 13:0 + +#define VIDEO_FB_0_LAST_ADDRESS 0x08004C +#define VIDEO_FB_0_LAST_ADDRESS_EXT 27:27 +#define VIDEO_FB_0_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_0_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_0_LAST_ADDRESS_CS 26:26 +#define VIDEO_FB_0_LAST_ADDRESS_CS_0 0 +#define VIDEO_FB_0_LAST_ADDRESS_CS_1 1 +#define VIDEO_FB_0_LAST_ADDRESS_ADDRESS 25:0 + +#define VIDEO_PLANE_TL 0x080050 +#define VIDEO_PLANE_TL_TOP 26:16 +#define VIDEO_PLANE_TL_LEFT 13:0 + +#define VIDEO_PLANE_BR 0x080054 +#define VIDEO_PLANE_BR_BOTTOM 26:16 +#define VIDEO_PLANE_BR_RIGHT 13:0 + +#define VIDEO_SCALE 0x080058 +#define VIDEO_SCALE_VERTICAL_MODE 31:31 +#define VIDEO_SCALE_VERTICAL_MODE_EXPAND 0 +#define VIDEO_SCALE_VERTICAL_MODE_SHRINK 1 +#define VIDEO_SCALE_VERTICAL_SCALE 27:16 +#define VIDEO_SCALE_HORIZONTAL_MODE 15:15 +#define VIDEO_SCALE_HORIZONTAL_MODE_EXPAND 0 +#define VIDEO_SCALE_HORIZONTAL_MODE_SHRINK 1 +#define VIDEO_SCALE_HORIZONTAL_SCALE 11:0 + +#define VIDEO_INITIAL_SCALE 0x08005C +#define VIDEO_INITIAL_SCALE_FB_1 27:16 +#define VIDEO_INITIAL_SCALE_FB_0 11:0 + +#define VIDEO_YUV_CONSTANTS 0x080060 +#define VIDEO_YUV_CONSTANTS_Y 31:24 +#define VIDEO_YUV_CONSTANTS_R 23:16 +#define VIDEO_YUV_CONSTANTS_G 15:8 +#define VIDEO_YUV_CONSTANTS_B 7:0 + +#define VIDEO_FB_1_ADDRESS 0x080064 +#define VIDEO_FB_1_ADDRESS_STATUS 31:31 +#define VIDEO_FB_1_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_FB_1_ADDRESS_STATUS_PENDING 1 +#define VIDEO_FB_1_ADDRESS_EXT 27:27 +#define VIDEO_FB_1_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_1_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_1_ADDRESS_CS 26:26 +#define VIDEO_FB_1_ADDRESS_CS_0 0 +#define VIDEO_FB_1_ADDRESS_CS_1 1 +#define VIDEO_FB_1_ADDRESS_ADDRESS 25:0 + +#define VIDEO_FB_1_LAST_ADDRESS 0x080068 +#define VIDEO_FB_1_LAST_ADDRESS_EXT 27:27 +#define VIDEO_FB_1_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_1_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_1_LAST_ADDRESS_CS 26:26 +#define VIDEO_FB_1_LAST_ADDRESS_CS_0 0 +#define VIDEO_FB_1_LAST_ADDRESS_CS_1 1 +#define VIDEO_FB_1_LAST_ADDRESS_ADDRESS 25:0 + +/* Video Alpha Control */ + +#define VIDEO_ALPHA_DISPLAY_CTRL 0x080080 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT 28:28 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT_PER_PIXEL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT_ALPHA 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_ALPHA 27:24 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO 17:16 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_1 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_3 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_7 2 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_11 3 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE 11:11 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE_NORMAL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE_HALF 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE 10:10 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE_NORMAL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE_HALF 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE 9:9 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE_REPLICATE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE_INTERPOLATE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE 8:8 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE_REPLICATE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE_INTERPOLATE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_PIXEL 7:4 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY 3:3 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY_DISABLE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY_ENABLE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE 2:2 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_DISABLE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_ENABLE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT 1:0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_8 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_16 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4 2 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4_4_4 3 + +#define VIDEO_ALPHA_FB_ADDRESS 0x080084 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS 31:31 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS_PENDING 1 +#define VIDEO_ALPHA_FB_ADDRESS_EXT 27:27 +#define VIDEO_ALPHA_FB_ADDRESS_EXT_LOCAL 0 +#define VIDEO_ALPHA_FB_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_ALPHA_FB_ADDRESS_CS 26:26 +#define VIDEO_ALPHA_FB_ADDRESS_CS_0 0 +#define VIDEO_ALPHA_FB_ADDRESS_CS_1 1 +#define VIDEO_ALPHA_FB_ADDRESS_ADDRESS 25:0 + +#define VIDEO_ALPHA_FB_WIDTH 0x080088 +#define VIDEO_ALPHA_FB_WIDTH_WIDTH 29:16 +#define VIDEO_ALPHA_FB_WIDTH_OFFSET 13:0 + +#define VIDEO_ALPHA_FB_LAST_ADDRESS 0x08008C +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT 27:27 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_CS 26:26 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_CS_0 0 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_CS_1 1 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_ADDRESS 25:0 + +#define VIDEO_ALPHA_PLANE_TL 0x080090 +#define VIDEO_ALPHA_PLANE_TL_TOP 26:16 +#define VIDEO_ALPHA_PLANE_TL_LEFT 10:0 + +#define VIDEO_ALPHA_PLANE_BR 0x080094 +#define VIDEO_ALPHA_PLANE_BR_BOTTOM 26:16 +#define VIDEO_ALPHA_PLANE_BR_RIGHT 10:0 + +#define VIDEO_ALPHA_SCALE 0x080098 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE 31:31 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE_EXPAND 0 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE_SHRINK 1 +#define VIDEO_ALPHA_SCALE_VERTICAL_SCALE 27:16 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE 15:15 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE_EXPAND 0 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE_SHRINK 1 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_SCALE 11:0 + +#define VIDEO_ALPHA_INITIAL_SCALE 0x08009C +#define VIDEO_ALPHA_INITIAL_SCALE_FB 11:0 + +#define VIDEO_ALPHA_CHROMA_KEY 0x0800A0 +#define VIDEO_ALPHA_CHROMA_KEY_MASK 31:16 +#define VIDEO_ALPHA_CHROMA_KEY_VALUE 15:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_01 0x0800A4 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_23 0x0800A8 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_45 0x0800AC +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_67 0x0800B0 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_89 0x0800B4 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_AB 0x0800B8 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_CD 0x0800BC +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_EF 0x0800C0 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_BLUE 4:0 + +/* Panel Cursor Control */ + +#define PANEL_HWC_ADDRESS 0x0800F0 +#define PANEL_HWC_ADDRESS_ENABLE 31:31 +#define PANEL_HWC_ADDRESS_ENABLE_DISABLE 0 +#define PANEL_HWC_ADDRESS_ENABLE_ENABLE 1 +#define PANEL_HWC_ADDRESS_EXT 27:27 +#define PANEL_HWC_ADDRESS_EXT_LOCAL 0 +#define PANEL_HWC_ADDRESS_EXT_EXTERNAL 1 +#define PANEL_HWC_ADDRESS_CS 26:26 +#define PANEL_HWC_ADDRESS_CS_0 0 +#define PANEL_HWC_ADDRESS_CS_1 1 +#define PANEL_HWC_ADDRESS_ADDRESS 25:0 + +#define PANEL_HWC_LOCATION 0x0800F4 +#define PANEL_HWC_LOCATION_TOP 27:27 +#define PANEL_HWC_LOCATION_TOP_INSIDE 0 +#define PANEL_HWC_LOCATION_TOP_OUTSIDE 1 +#define PANEL_HWC_LOCATION_Y 26:16 +#define PANEL_HWC_LOCATION_LEFT 11:11 +#define PANEL_HWC_LOCATION_LEFT_INSIDE 0 +#define PANEL_HWC_LOCATION_LEFT_OUTSIDE 1 +#define PANEL_HWC_LOCATION_X 10:0 + +#define PANEL_HWC_COLOR_12 0x0800F8 +#define PANEL_HWC_COLOR_12_2_RGB565 31:16 +#define PANEL_HWC_COLOR_12_1_RGB565 15:0 + +#define PANEL_HWC_COLOR_3 0x0800FC +#define PANEL_HWC_COLOR_3_RGB565 15:0 + +/* Old Definitions +++ */ +#define PANEL_HWC_COLOR_01 0x0800F8 +#define PANEL_HWC_COLOR_01_1_RED 31:27 +#define PANEL_HWC_COLOR_01_1_GREEN 26:21 +#define PANEL_HWC_COLOR_01_1_BLUE 20:16 +#define PANEL_HWC_COLOR_01_0_RED 15:11 +#define PANEL_HWC_COLOR_01_0_GREEN 10:5 +#define PANEL_HWC_COLOR_01_0_BLUE 4:0 + +#define PANEL_HWC_COLOR_2 0x0800FC +#define PANEL_HWC_COLOR_2_RED 15:11 +#define PANEL_HWC_COLOR_2_GREEN 10:5 +#define PANEL_HWC_COLOR_2_BLUE 4:0 +/* Old Definitions --- */ + +/* Alpha Control */ + +#define ALPHA_DISPLAY_CTRL 0x080100 +#define ALPHA_DISPLAY_CTRL_SELECT 28:28 +#define ALPHA_DISPLAY_CTRL_SELECT_PER_PIXEL 0 +#define ALPHA_DISPLAY_CTRL_SELECT_ALPHA 1 +#define ALPHA_DISPLAY_CTRL_ALPHA 27:24 +#define ALPHA_DISPLAY_CTRL_FIFO 17:16 +#define ALPHA_DISPLAY_CTRL_FIFO_1 0 +#define ALPHA_DISPLAY_CTRL_FIFO_3 1 +#define ALPHA_DISPLAY_CTRL_FIFO_7 2 +#define ALPHA_DISPLAY_CTRL_FIFO_11 3 +#define ALPHA_DISPLAY_CTRL_PIXEL 7:4 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY 3:3 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY_DISABLE 0 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY_ENABLE 1 +#define ALPHA_DISPLAY_CTRL_PLANE 2:2 +#define ALPHA_DISPLAY_CTRL_PLANE_DISABLE 0 +#define ALPHA_DISPLAY_CTRL_PLANE_ENABLE 1 +#define ALPHA_DISPLAY_CTRL_FORMAT 1:0 +#define ALPHA_DISPLAY_CTRL_FORMAT_16 1 +#define ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4 2 +#define ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4_4_4 3 + +#define ALPHA_FB_ADDRESS 0x080104 +#define ALPHA_FB_ADDRESS_STATUS 31:31 +#define ALPHA_FB_ADDRESS_STATUS_CURRENT 0 +#define ALPHA_FB_ADDRESS_STATUS_PENDING 1 +#define ALPHA_FB_ADDRESS_EXT 27:27 +#define ALPHA_FB_ADDRESS_EXT_LOCAL 0 +#define ALPHA_FB_ADDRESS_EXT_EXTERNAL 1 +#define ALPHA_FB_ADDRESS_CS 26:26 +#define ALPHA_FB_ADDRESS_CS_0 0 +#define ALPHA_FB_ADDRESS_CS_1 1 +#define ALPHA_FB_ADDRESS_ADDRESS 25:0 + +#define ALPHA_FB_WIDTH 0x080108 +#define ALPHA_FB_WIDTH_WIDTH 29:16 +#define ALPHA_FB_WIDTH_OFFSET 13:0 + +#define ALPHA_PLANE_TL 0x08010C +#define ALPHA_PLANE_TL_TOP 26:16 +#define ALPHA_PLANE_TL_LEFT 10:0 + +#define ALPHA_PLANE_BR 0x080110 +#define ALPHA_PLANE_BR_BOTTOM 26:16 +#define ALPHA_PLANE_BR_RIGHT 10:0 + +#define ALPHA_CHROMA_KEY 0x080114 +#define ALPHA_CHROMA_KEY_MASK 31:16 +#define ALPHA_CHROMA_KEY_VALUE 15:0 + +#define ALPHA_COLOR_LOOKUP_01 0x080118 +#define ALPHA_COLOR_LOOKUP_01_1 31:16 +#define ALPHA_COLOR_LOOKUP_01_1_RED 31:27 +#define ALPHA_COLOR_LOOKUP_01_1_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_01_1_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_01_0 15:0 +#define ALPHA_COLOR_LOOKUP_01_0_RED 15:11 +#define ALPHA_COLOR_LOOKUP_01_0_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_01_0_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_23 0x08011C +#define ALPHA_COLOR_LOOKUP_23_3 31:16 +#define ALPHA_COLOR_LOOKUP_23_3_RED 31:27 +#define ALPHA_COLOR_LOOKUP_23_3_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_23_3_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_23_2 15:0 +#define ALPHA_COLOR_LOOKUP_23_2_RED 15:11 +#define ALPHA_COLOR_LOOKUP_23_2_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_23_2_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_45 0x080120 +#define ALPHA_COLOR_LOOKUP_45_5 31:16 +#define ALPHA_COLOR_LOOKUP_45_5_RED 31:27 +#define ALPHA_COLOR_LOOKUP_45_5_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_45_5_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_45_4 15:0 +#define ALPHA_COLOR_LOOKUP_45_4_RED 15:11 +#define ALPHA_COLOR_LOOKUP_45_4_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_45_4_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_67 0x080124 +#define ALPHA_COLOR_LOOKUP_67_7 31:16 +#define ALPHA_COLOR_LOOKUP_67_7_RED 31:27 +#define ALPHA_COLOR_LOOKUP_67_7_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_67_7_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_67_6 15:0 +#define ALPHA_COLOR_LOOKUP_67_6_RED 15:11 +#define ALPHA_COLOR_LOOKUP_67_6_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_67_6_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_89 0x080128 +#define ALPHA_COLOR_LOOKUP_89_9 31:16 +#define ALPHA_COLOR_LOOKUP_89_9_RED 31:27 +#define ALPHA_COLOR_LOOKUP_89_9_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_89_9_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_89_8 15:0 +#define ALPHA_COLOR_LOOKUP_89_8_RED 15:11 +#define ALPHA_COLOR_LOOKUP_89_8_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_89_8_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_AB 0x08012C +#define ALPHA_COLOR_LOOKUP_AB_B 31:16 +#define ALPHA_COLOR_LOOKUP_AB_B_RED 31:27 +#define ALPHA_COLOR_LOOKUP_AB_B_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_AB_B_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_AB_A 15:0 +#define ALPHA_COLOR_LOOKUP_AB_A_RED 15:11 +#define ALPHA_COLOR_LOOKUP_AB_A_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_AB_A_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_CD 0x080130 +#define ALPHA_COLOR_LOOKUP_CD_D 31:16 +#define ALPHA_COLOR_LOOKUP_CD_D_RED 31:27 +#define ALPHA_COLOR_LOOKUP_CD_D_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_CD_D_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_CD_C 15:0 +#define ALPHA_COLOR_LOOKUP_CD_C_RED 15:11 +#define ALPHA_COLOR_LOOKUP_CD_C_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_CD_C_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_EF 0x080134 +#define ALPHA_COLOR_LOOKUP_EF_F 31:16 +#define ALPHA_COLOR_LOOKUP_EF_F_RED 31:27 +#define ALPHA_COLOR_LOOKUP_EF_F_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_EF_F_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_EF_E 15:0 +#define ALPHA_COLOR_LOOKUP_EF_E_RED 15:11 +#define ALPHA_COLOR_LOOKUP_EF_E_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_EF_E_BLUE 4:0 + +/* CRT Graphics Control */ + +#define CRT_DISPLAY_CTRL 0x080200 +#define CRT_DISPLAY_CTRL_FIFO 17:16 +#define CRT_DISPLAY_CTRL_FIFO_1 0 +#define CRT_DISPLAY_CTRL_FIFO_3 1 +#define CRT_DISPLAY_CTRL_FIFO_7 2 +#define CRT_DISPLAY_CTRL_FIFO_11 3 +#define CRT_DISPLAY_CTRL_TV_PHASE 15:15 +#define CRT_DISPLAY_CTRL_TV_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_TV_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE 14:14 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE 13:13 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE 12:12 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_BLANK 10:10 +#define CRT_DISPLAY_CTRL_BLANK_OFF 0 +#define CRT_DISPLAY_CTRL_BLANK_ON 1 +#define CRT_DISPLAY_CTRL_SELECT 9:9 +#define CRT_DISPLAY_CTRL_SELECT_PANEL 0 +#define CRT_DISPLAY_CTRL_SELECT_CRT 1 +#define CRT_DISPLAY_CTRL_TIMING 8:8 +#define CRT_DISPLAY_CTRL_TIMING_DISABLE 0 +#define CRT_DISPLAY_CTRL_TIMING_ENABLE 1 +#define CRT_DISPLAY_CTRL_PIXEL 7:4 +#define CRT_DISPLAY_CTRL_GAMMA 3:3 +#define CRT_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define CRT_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define CRT_DISPLAY_CTRL_PLANE 2:2 +#define CRT_DISPLAY_CTRL_PLANE_DISABLE 0 +#define CRT_DISPLAY_CTRL_PLANE_ENABLE 1 +#define CRT_DISPLAY_CTRL_FORMAT 1:0 +#define CRT_DISPLAY_CTRL_FORMAT_8 0 +#define CRT_DISPLAY_CTRL_FORMAT_16 1 +#define CRT_DISPLAY_CTRL_FORMAT_32 2 + +#define CRT_FB_ADDRESS 0x080204 +#define CRT_FB_ADDRESS_STATUS 31:31 +#define CRT_FB_ADDRESS_STATUS_CURRENT 0 +#define CRT_FB_ADDRESS_STATUS_PENDING 1 +#define CRT_FB_ADDRESS_EXT 27:27 +#define CRT_FB_ADDRESS_EXT_LOCAL 0 +#define CRT_FB_ADDRESS_EXT_EXTERNAL 1 +#define CRT_FB_ADDRESS_CS 26:26 +#define CRT_FB_ADDRESS_CS_0 0 +#define CRT_FB_ADDRESS_CS_1 1 +#define CRT_FB_ADDRESS_ADDRESS 25:0 + +#define CRT_FB_WIDTH 0x080208 +#define CRT_FB_WIDTH_WIDTH 29:16 +#define CRT_FB_WIDTH_OFFSET 13:0 + +#define CRT_HORIZONTAL_TOTAL 0x08020C +#define CRT_HORIZONTAL_TOTAL_TOTAL 27:16 +#define CRT_HORIZONTAL_TOTAL_DISPLAY_END 11:0 + +#define CRT_HORIZONTAL_SYNC 0x080210 +#define CRT_HORIZONTAL_SYNC_WIDTH 23:16 +#define CRT_HORIZONTAL_SYNC_START 11:0 + +#define CRT_VERTICAL_TOTAL 0x080214 +#define CRT_VERTICAL_TOTAL_TOTAL 26:16 +#define CRT_VERTICAL_TOTAL_DISPLAY_END 10:0 + +#define CRT_VERTICAL_SYNC 0x080218 +#define CRT_VERTICAL_SYNC_HEIGHT 21:16 +#define CRT_VERTICAL_SYNC_START 10:0 + +#define CRT_SIGNATURE_ANALYZER 0x08021C +#define CRT_SIGNATURE_ANALYZER_STATUS 31:16 +#define CRT_SIGNATURE_ANALYZER_ENABLE 3:3 +#define CRT_SIGNATURE_ANALYZER_ENABLE_DISABLE 0 +#define CRT_SIGNATURE_ANALYZER_ENABLE_ENABLE 1 +#define CRT_SIGNATURE_ANALYZER_RESET 2:2 +#define CRT_SIGNATURE_ANALYZER_RESET_NORMAL 0 +#define CRT_SIGNATURE_ANALYZER_RESET_RESET 1 +#define CRT_SIGNATURE_ANALYZER_SOURCE 1:0 +#define CRT_SIGNATURE_ANALYZER_SOURCE_RED 0 +#define CRT_SIGNATURE_ANALYZER_SOURCE_GREEN 1 +#define CRT_SIGNATURE_ANALYZER_SOURCE_BLUE 2 + +#define CRT_CURRENT_LINE 0x080220 +#define CRT_CURRENT_LINE_LINE 10:0 + +#define CRT_MONITOR_DETECT 0x080224 +#define CRT_MONITOR_DETECT_ENABLE 24:24 +#define CRT_MONITOR_DETECT_ENABLE_DISABLE 0 +#define CRT_MONITOR_DETECT_ENABLE_ENABLE 1 +#define CRT_MONITOR_DETECT_RED 23:16 +#define CRT_MONITOR_DETECT_GREEN 15:8 +#define CRT_MONITOR_DETECT_BLUE 7:0 + +/* CRT Cursor Control */ + +#define CRT_HWC_ADDRESS 0x080230 +#define CRT_HWC_ADDRESS_ENABLE 31:31 +#define CRT_HWC_ADDRESS_ENABLE_DISABLE 0 +#define CRT_HWC_ADDRESS_ENABLE_ENABLE 1 +#define CRT_HWC_ADDRESS_EXT 27:27 +#define CRT_HWC_ADDRESS_EXT_LOCAL 0 +#define CRT_HWC_ADDRESS_EXT_EXTERNAL 1 +#define CRT_HWC_ADDRESS_CS 26:26 +#define CRT_HWC_ADDRESS_CS_0 0 +#define CRT_HWC_ADDRESS_CS_1 1 +#define CRT_HWC_ADDRESS_ADDRESS 25:0 + +#define CRT_HWC_LOCATION 0x080234 +#define CRT_HWC_LOCATION_TOP 27:27 +#define CRT_HWC_LOCATION_TOP_INSIDE 0 +#define CRT_HWC_LOCATION_TOP_OUTSIDE 1 +#define CRT_HWC_LOCATION_Y 26:16 +#define CRT_HWC_LOCATION_LEFT 11:11 +#define CRT_HWC_LOCATION_LEFT_INSIDE 0 +#define CRT_HWC_LOCATION_LEFT_OUTSIDE 1 +#define CRT_HWC_LOCATION_X 10:0 + +#define CRT_HWC_COLOR_12 0x080238 +#define CRT_HWC_COLOR_12_2_RGB565 31:16 +#define CRT_HWC_COLOR_12_1_RGB565 15:0 + +#define CRT_HWC_COLOR_3 0x08023C +#define CRT_HWC_COLOR_3_RGB565 15:0 + +/* Old Definitions +++ */ +#define CRT_HWC_COLOR_01 0x080238 +#define CRT_HWC_COLOR_01_1_RED 31:27 +#define CRT_HWC_COLOR_01_1_GREEN 26:21 +#define CRT_HWC_COLOR_01_1_BLUE 20:16 +#define CRT_HWC_COLOR_01_0_RED 15:11 +#define CRT_HWC_COLOR_01_0_GREEN 10:5 +#define CRT_HWC_COLOR_01_0_BLUE 4:0 + +#define CRT_HWC_COLOR_2 0x08023C +#define CRT_HWC_COLOR_2_RED 15:11 +#define CRT_HWC_COLOR_2_GREEN 10:5 +#define CRT_HWC_COLOR_2_BLUE 4:0 +/* Old Definitions --- */ + +/* Palette RAM */ + +#define CRT_PALETTE_RAM 0x080C00 +#define PANEL_PALETTE_RAM 0x080400 +#define VIDEO_PALETTE_RAM 0x080800 + diff --git a/src/ddk502/ddk502_regdma.h b/src/ddk502/ddk502_regdma.h new file mode 100644 index 0000000..e2073d7 --- /dev/null +++ b/src/ddk502/ddk502_regdma.h @@ -0,0 +1,69 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* RegDMA.h --- Voyager GX SDK +* This file contains the definitions for the DMA registers. +* +*******************************************************************/ +#define DMA_0_SDRAM 0x0D0000 +#define DMA_0_SDRAM_EXT 27:27 +#define DMA_0_SDRAM_EXT_LOCAL 0 +#define DMA_0_SDRAM_EXT_EXTERNAL 1 +#define DMA_0_SDRAM_CS 26:26 +#define DMA_0_SDRAM_CS_0 0 +#define DMA_0_SDRAM_CS_1 1 +#define DMA_0_SDRAM_ADDRESS 25:0 + +#define DMA_0_SRAM 0x0D0004 +#define DMA_0_SRAM_ADDRESS 15:0 + +#define DMA_0_SIZE_CONTROL 0x0D0008 +#define DMA_0_SIZE_CONTROL_STATUS 31:31 +#define DMA_0_SIZE_CONTROL_STATUS_IDLE 0 +#define DMA_0_SIZE_CONTROL_STATUS_ACTIVE 1 +#define DMA_0_SIZE_CONTROL_DIR 30:30 +#define DMA_0_SIZE_CONTROL_DIR_TO_SRAM 0 +#define DMA_0_SIZE_CONTROL_DIR_FROM_SRAM 1 +#define DMA_0_SIZE_CONTROL_SIZE 15:0 + +#define DMA_1_SOURCE 0x0D0010 +#define DMA_1_SOURCE_ADDRESS_EXT 27:27 +#define DMA_1_SOURCE_ADDRESS_EXT_LOCAL 0 +#define DMA_1_SOURCE_ADDRESS_EXT_EXTERNAL 1 +#define DMA_1_SOURCE_ADDRESS_CS 26:26 +#define DMA_1_SOURCE_ADDRESS_CS_0 0 +#define DMA_1_SOURCE_ADDRESS_CS_1 1 +#define DMA_1_SOURCE_ADDRESS 25:0 + +#define DMA_1_DESTINATION 0x0D0014 +#define DMA_1_DESTINATION_ADDRESS_EXT 27:27 +#define DMA_1_DESTINATION_ADDRESS_EXT_LOCAL 0 +#define DMA_1_DESTINATION_ADDRESS_EXT_EXTERNAL 1 +#define DMA_1_DESTINATION_ADDRESS_CS 26:26 +#define DMA_1_DESTINATION_ADDRESS_CS_0 0 +#define DMA_1_DESTINATION_ADDRESS_CS_1 1 +#define DMA_1_DESTINATION_ADDRESS 25:0 + +#define DMA_1_SIZE_CONTROL 0x0D0018 +#define DMA_1_SIZE_CONTROL_STATUS 31:31 +#define DMA_1_SIZE_CONTROL_STATUS_IDLE 0 +#define DMA_1_SIZE_CONTROL_STATUS_ACTIVE 1 +#define DMA_1_SIZE_CONTROL_SIZE 23:0 + +#define DMA_ABORT_INTERRUPT 0x0D0020 +#define DMA_ABORT_INTERRUPT_ABORT_1 5:5 +#define DMA_ABORT_INTERRUPT_ABORT_1_ENABLE 0 +#define DMA_ABORT_INTERRUPT_ABORT_1_ABORT 1 +#define DMA_ABORT_INTERRUPT_ABORT_0 4:4 +#define DMA_ABORT_INTERRUPT_ABORT_0_ENABLE 0 +#define DMA_ABORT_INTERRUPT_ABORT_0_ABORT 1 +#define DMA_ABORT_INTERRUPT_INT_1 1:1 +#define DMA_ABORT_INTERRUPT_INT_1_CLEAR 0 +#define DMA_ABORT_INTERRUPT_INT_1_FINISHED 1 +#define DMA_ABORT_INTERRUPT_INT_0 0:0 +#define DMA_ABORT_INTERRUPT_INT_0_CLEAR 0 +#define DMA_ABORT_INTERRUPT_INT_0_FINISHED 1 diff --git a/src/ddk502/ddk502_reggpio.h b/src/ddk502/ddk502_reggpio.h new file mode 100644 index 0000000..4afd2ae --- /dev/null +++ b/src/ddk502/ddk502_reggpio.h @@ -0,0 +1,317 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* RegGPIO.h --- Voyager GX SDK +* This file contains the definitions for the GPIO registers. +* +*******************************************************************/ +#define GPIO_DATA_LOW 0x010000 + +#define GPIO_DATA_HIGH 0x010004 +#define GPIO_DATA_HIGH_47 15:15 +#define GPIO_DATA_HIGH_46 14:14 + +#define GPIO_DATA_DIR_HIGH 0x01000C +#define GPIO_DATA_DIR_HIGH_47 15:15 +#define GPIO_DATA_DIR_HIGH_47_INPUT 0 +#define GPIO_DATA_DIR_HIGH_47_OUTPUT 1 +#define GPIO_DATA_DIR_HIGH_46 14:14 +#define GPIO_DATA_DIR_HIGH_46_INPUT 0 +#define GPIO_DATA_DIR_HIGH_46_OUTPUT 1 + +#define GPIO_DATA_DIRECTION_LOW 0x010008 +#define GPIO_DATA_DIRECTION_LOW_31 31:31 +#define GPIO_DATA_DIRECTION_LOW_31_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_31_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_30 30:30 +#define GPIO_DATA_DIRECTION_LOW_30_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_30_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_29 29:29 +#define GPIO_DATA_DIRECTION_LOW_29_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_29_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_28 28:28 +#define GPIO_DATA_DIRECTION_LOW_28_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_28_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_27 27:27 +#define GPIO_DATA_DIRECTION_LOW_27_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_27_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_26 26:26 +#define GPIO_DATA_DIRECTION_LOW_26_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_26_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_25 25:25 +#define GPIO_DATA_DIRECTION_LOW_25_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_25_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_24 24:24 +#define GPIO_DATA_DIRECTION_LOW_24_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_24_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_23 23:23 +#define GPIO_DATA_DIRECTION_LOW_23_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_23_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_22 22:22 +#define GPIO_DATA_DIRECTION_LOW_22_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_22_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_21 21:21 +#define GPIO_DATA_DIRECTION_LOW_21_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_21_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_20 20:20 +#define GPIO_DATA_DIRECTION_LOW_20_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_20_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_19 19:19 +#define GPIO_DATA_DIRECTION_LOW_19_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_19_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_18 18:18 +#define GPIO_DATA_DIRECTION_LOW_18_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_18_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_17 17:17 +#define GPIO_DATA_DIRECTION_LOW_17_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_17_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_16 16:16 +#define GPIO_DATA_DIRECTION_LOW_16_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_16_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_15 15:15 +#define GPIO_DATA_DIRECTION_LOW_15_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_15_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_14 14:14 +#define GPIO_DATA_DIRECTION_LOW_14_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_14_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_13 13:13 +#define GPIO_DATA_DIRECTION_LOW_13_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_13_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_12 12:12 +#define GPIO_DATA_DIRECTION_LOW_12_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_12_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_11 11:11 +#define GPIO_DATA_DIRECTION_LOW_11_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_11_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_10 10:10 +#define GPIO_DATA_DIRECTION_LOW_10_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_10_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_9 9:9 +#define GPIO_DATA_DIRECTION_LOW_9_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_9_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_8 8:8 +#define GPIO_DATA_DIRECTION_LOW_8_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_8_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_7 7:7 +#define GPIO_DATA_DIRECTION_LOW_7_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_7_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_6 6:6 +#define GPIO_DATA_DIRECTION_LOW_6_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_6_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_5 5:5 +#define GPIO_DATA_DIRECTION_LOW_5_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_5_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_4 4:4 +#define GPIO_DATA_DIRECTION_LOW_4_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_4_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_3 3:3 +#define GPIO_DATA_DIRECTION_LOW_3_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_3_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_2 2:2 +#define GPIO_DATA_DIRECTION_LOW_2_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_2_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_1 131 +#define GPIO_DATA_DIRECTION_LOW_1_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_1_OUTPUT 1 +#define GPIO_DATA_DIRECTION_LOW_0 0:0 +#define GPIO_DATA_DIRECTION_LOW_0_INPUT 0 +#define GPIO_DATA_DIRECTION_LOW_0_OUTPUT 1 + +#define GPIO_DATA_DIRECTION_HIGH 0x01000C +#define GPIO_DATA_DIRECTION_HIGH_63 31:31 +#define GPIO_DATA_DIRECTION_HIGH_63_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_63_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_62 30:30 +#define GPIO_DATA_DIRECTION_HIGH_62_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_62_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_61 29:29 +#define GPIO_DATA_DIRECTION_HIGH_61_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_61_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_60 28:28 +#define GPIO_DATA_DIRECTION_HIGH_60_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_60_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_59 27:27 +#define GPIO_DATA_DIRECTION_HIGH_59_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_59_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_58 26:26 +#define GPIO_DATA_DIRECTION_HIGH_58_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_58_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_57 25:25 +#define GPIO_DATA_DIRECTION_HIGH_57_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_57_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_56 24:24 +#define GPIO_DATA_DIRECTION_HIGH_56_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_56_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_55 23:23 +#define GPIO_DATA_DIRECTION_HIGH_55_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_55_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_54 22:22 +#define GPIO_DATA_DIRECTION_HIGH_54_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_54_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_53 21:21 +#define GPIO_DATA_DIRECTION_HIGH_53_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_53_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_52 20:20 +#define GPIO_DATA_DIRECTION_HIGH_52_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_52_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_51 19:19 +#define GPIO_DATA_DIRECTION_HIGH_51_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_51_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_50 18:18 +#define GPIO_DATA_DIRECTION_HIGH_50_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_50_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_49 17:17 +#define GPIO_DATA_DIRECTION_HIGH_49_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_49_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_48 16:16 +#define GPIO_DATA_DIRECTION_HIGH_48_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_48_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_47 15:15 +#define GPIO_DATA_DIRECTION_HIGH_47_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_47_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_46 14:14 +#define GPIO_DATA_DIRECTION_HIGH_46_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_46_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_45 13:13 +#define GPIO_DATA_DIRECTION_HIGH_45_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_45_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_44 12:12 +#define GPIO_DATA_DIRECTION_HIGH_44_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_44_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_43 11:11 +#define GPIO_DATA_DIRECTION_HIGH_43_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_43_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_42 10:10 +#define GPIO_DATA_DIRECTION_HIGH_42_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_42_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_41 9:9 +#define GPIO_DATA_DIRECTION_HIGH_41_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_41_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_40 8:8 +#define GPIO_DATA_DIRECTION_HIGH_40_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_40_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_39 7:7 +#define GPIO_DATA_DIRECTION_HIGH_39_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_39_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_38 6:6 +#define GPIO_DATA_DIRECTION_HIGH_38_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_38_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_37 5:5 +#define GPIO_DATA_DIRECTION_HIGH_37_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_37_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_36 4:4 +#define GPIO_DATA_DIRECTION_HIGH_36_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_36_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_35 3:3 +#define GPIO_DATA_DIRECTION_HIGH_35_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_35_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_34 2:2 +#define GPIO_DATA_DIRECTION_HIGH_34_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_34_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_33 1:1 +#define GPIO_DATA_DIRECTION_HIGH_33_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_33_OUTPUT 1 +#define GPIO_DATA_DIRECTION_HIGH_32 0:0 +#define GPIO_DATA_DIRECTION_HIGH_32_INPUT 0 +#define GPIO_DATA_DIRECTION_HIGH_32_OUTPUT 1 + +#define GPIO_INTERRUPT_SETUP 0x010010 +#define GPIO_INTERRUPT_SETUP_TRIGGER_54 22:22 +#define GPIO_INTERRUPT_SETUP_TRIGGER_54_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_54_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_53 21:21 +#define GPIO_INTERRUPT_SETUP_TRIGGER_53_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_53_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_52 20:20 +#define GPIO_INTERRUPT_SETUP_TRIGGER_52_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_52_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_51 19:19 +#define GPIO_INTERRUPT_SETUP_TRIGGER_51_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_51_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_50 18:18 +#define GPIO_INTERRUPT_SETUP_TRIGGER_50_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_50_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_49 17:17 +#define GPIO_INTERRUPT_SETUP_TRIGGER_49_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_49_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_48 16:16 +#define GPIO_INTERRUPT_SETUP_TRIGGER_48_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_48_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_54 14:14 +#define GPIO_INTERRUPT_SETUP_ACTIVE_54_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_54_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_53 13:13 +#define GPIO_INTERRUPT_SETUP_ACTIVE_53_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_53_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_52 12:12 +#define GPIO_INTERRUPT_SETUP_ACTIVE_52_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_52_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_51 11:11 +#define GPIO_INTERRUPT_SETUP_ACTIVE_51_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_51_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_50 10:10 +#define GPIO_INTERRUPT_SETUP_ACTIVE_50_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_50_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_49 9:9 +#define GPIO_INTERRUPT_SETUP_ACTIVE_49_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_49_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_48 8:8 +#define GPIO_INTERRUPT_SETUP_ACTIVE_48_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_48_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_54 6:6 +#define GPIO_INTERRUPT_SETUP_ENABLE_54_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_54_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_53 5:5 +#define GPIO_INTERRUPT_SETUP_ENABLE_53_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_53_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_52 4:4 +#define GPIO_INTERRUPT_SETUP_ENABLE_52_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_52_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_51 3:3 +#define GPIO_INTERRUPT_SETUP_ENABLE_51_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_51_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_50 2:2 +#define GPIO_INTERRUPT_SETUP_ENABLE_50_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_50_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_49 1:1 +#define GPIO_INTERRUPT_SETUP_ENABLE_49_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_49_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_48 0:0 +#define GPIO_INTERRUPT_SETUP_ENABLE_48_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_48_INTERRUPT 1 + +#define GPIO_INTERRUPT_STATUS 0x010014 +#define GPIO_INTERRUPT_STATUS_54 22:22 +#define GPIO_INTERRUPT_STATUS_54_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_54_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_54_RESET 1 +#define GPIO_INTERRUPT_STATUS_53 21:21 +#define GPIO_INTERRUPT_STATUS_53_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_53_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_53_RESET 1 +#define GPIO_INTERRUPT_STATUS_52 20:20 +#define GPIO_INTERRUPT_STATUS_52_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_52_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_52_RESET 1 +#define GPIO_INTERRUPT_STATUS_51 19:19 +#define GPIO_INTERRUPT_STATUS_51_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_51_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_51_RESET 1 +#define GPIO_INTERRUPT_STATUS_50 18:18 +#define GPIO_INTERRUPT_STATUS_50_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_50_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_50_RESET 1 +#define GPIO_INTERRUPT_STATUS_49 17:17 +#define GPIO_INTERRUPT_STATUS_49_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_49_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_49_RESET 1 +#define GPIO_INTERRUPT_STATUS_48 16:16 +#define GPIO_INTERRUPT_STATUS_48_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_48_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_48_RESET 1 + + diff --git a/src/ddk502/ddk502_regsc.h b/src/ddk502/ddk502_regsc.h new file mode 100644 index 0000000..11d6c4b --- /dev/null +++ b/src/ddk502/ddk502_regsc.h @@ -0,0 +1,1233 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* RegSC.h --- Voyager GX SDK +* This file contains the definitions for the System Configuration registers. +* +*******************************************************************/ +#define SYSTEM_CTRL 0x000000 +#define SYSTEM_CTRL_DPMS 31:30 +#define SYSTEM_CTRL_DPMS_VPHP 0 +#define SYSTEM_CTRL_DPMS_VPHN 1 +#define SYSTEM_CTRL_DPMS_VNHP 2 +#define SYSTEM_CTRL_DPMS_VNHN 3 +#define SYSTEM_CTRL_PCI_BURST 29:29 +#define SYSTEM_CTRL_PCI_BURST_DISABLE 0 +#define SYSTEM_CTRL_PCI_BURST_ENABLE 1 +#define SYSTEM_CTRL_CSC_STATUS 28:28 +#define SYSTEM_CTRL_CSC_STATUS_IDLE 0 +#define SYSTEM_CTRL_CSC_STATUS_BUSY 1 +#define SYSTEM_CTRL_PCI_MASTER 25:25 +#define SYSTEM_CTRL_PCI_MASTER_STOP 0 +#define SYSTEM_CTRL_PCI_MASTER_START 1 +#define SYSTEM_CTRL_LATENCY_TIMER 24:24 +#define SYSTEM_CTRL_LATENCY_TIMER_ENABLE 0 +#define SYSTEM_CTRL_LATENCY_TIMER_DISABLE 1 +#define SYSTEM_CTRL_PANEL_STATUS 23:23 +#define SYSTEM_CTRL_PANEL_STATUS_CURRENT 0 +#define SYSTEM_CTRL_PANEL_STATUS_PENDING 1 +#define SYSTEM_CTRL_VIDEO_STATUS 22:22 +#define SYSTEM_CTRL_VIDEO_STATUS_CURRENT 0 +#define SYSTEM_CTRL_VIDEO_STATUS_PENDING 1 +#define SYSTEM_CTRL_DE_FIFO 20:20 +#define SYSTEM_CTRL_DE_FIFO_NOT_EMPTY 0 +#define SYSTEM_CTRL_DE_FIFO_EMPTY 1 +#define SYSTEM_CTRL_DE_STATUS 19:19 +#define SYSTEM_CTRL_DE_STATUS_IDLE 0 +#define SYSTEM_CTRL_DE_STATUS_BUSY 1 +#define SYSTEM_CTRL_CRT_STATUS 17:17 +#define SYSTEM_CTRL_CRT_STATUS_CURRENT 0 +#define SYSTEM_CTRL_CRT_STATUS_PENDING 1 +#define SYSTEM_CTRL_ZVPORT 16:16 +#define SYSTEM_CTRL_ZVPORT_0 0 +#define SYSTEM_CTRL_ZVPORT_1 1 +#define SYSTEM_CTRL_PCI_BURST_READ 15:15 +#define SYSTEM_CTRL_PCI_BURST_READ_DISABLE 0 +#define SYSTEM_CTRL_PCI_BURST_READ_ENABLE 1 +#define SYSTEM_CTRL_DE_ABORT 13:12 +#define SYSTEM_CTRL_DE_ABORT_NORMAL 0 +#define SYSTEM_CTRL_DE_ABORT_2D_ABORT 3 +#define SYSTEM_CTRL_PCI_SUBSYS_LOCK 11:11 +#define SYSTEM_CTRL_PCI_SUBSYS_LOCK_DISABLE 0 +#define SYSTEM_CTRL_PCI_SUBSYS_LOCK_ENABLE 1 +#define SYSTEM_CTRL_PCI_RETRY 7:7 +#define SYSTEM_CTRL_PCI_RETRY_ENABLE 0 +#define SYSTEM_CTRL_PCI_RETRY_DISABLE 1 +#define SYSTEM_CTRL_PCI_CLOCK_RUN 6:6 +#define SYSTEM_CTRL_PCI_CLOCK_RUN_DISABLE 0 +#define SYSTEM_CTRL_PCI_CLOCK_RUN_ENABLE 1 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE 5:4 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_1 0 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_2 1 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_4 2 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_8 3 +#define SYSTEM_CTRL_CRT_TRISTATE 2:2 +#define SYSTEM_CTRL_CRT_TRISTATE_DISABLE 0 +#define SYSTEM_CTRL_CRT_TRISTATE_ENABLE 1 +#define SYSTEM_CTRL_INTMEM_TRISTATE 1:1 +#define SYSTEM_CTRL_INTMEM_TRISTATE_DISABLE 0 +#define SYSTEM_CTRL_INTMEM_TRISTATE_ENABLE 1 +#define SYSTEM_CTRL_PANEL_TRISTATE 0:0 +#define SYSTEM_CTRL_PANEL_TRISTATE_DISABLE 0 +#define SYSTEM_CTRL_PANEL_TRISTATE_ENABLE 1 + +#define MISC_CTRL 0x000004 +#define MISC_CTRL_PCI_PAD 31:30 +#define MISC_CTRL_PCI_PAD_24MA 0 +#define MISC_CTRL_PCI_PAD_12MA 1 +#define MISC_CTRL_PCI_PAD_8MA 2 +#define MISC_CTRL_48_SELECT 29:28 +#define MISC_CTRL_48_SELECT_CRYSTAL 0 +#define MISC_CTRL_48_SELECT_CPU_96 2 +#define MISC_CTRL_48_SELECT_CPU_48 3 +#define MISC_CTRL_UART1_SELECT 27:27 +#define MISC_CTRL_UART1_SELECT_UART 0 +#define MISC_CTRL_UART1_SELECT_SSP 1 +#define MISC_CTRL_8051_LATCH 26:26 +#define MISC_CTRL_8051_LATCH_DISABLE 0 +#define MISC_CTRL_8051_LATCH_ENABLE 1 +#define MISC_CTRL_FPDATA 25:25 +#define MISC_CTRL_FPDATA_18 0 +#define MISC_CTRL_FPDATA_24 1 +#define MISC_CTRL_CRYSTAL 24:24 +#define MISC_CTRL_CRYSTAL_24 0 +#define MISC_CTRL_CRYSTAL_12 1 +#define MISC_CTRL_DRAM_REFRESH 22:21 +#define MISC_CTRL_DRAM_REFRESH_8 0 +#define MISC_CTRL_DRAM_REFRESH_16 1 +#define MISC_CTRL_DRAM_REFRESH_32 2 +#define MISC_CTRL_DRAM_REFRESH_64 3 +#define MISC_CTRL_BUS_HOLD 20:18 +#define MISC_CTRL_BUS_HOLD_FIFO_EMPTY 0 +#define MISC_CTRL_BUS_HOLD_8 1 +#define MISC_CTRL_BUS_HOLD_16 2 +#define MISC_CTRL_BUS_HOLD_24 3 +#define MISC_CTRL_BUS_HOLD_32 4 +#define MISC_CTRL_HITACHI_READY 17:17 +#define MISC_CTRL_HITACHI_READY_NEGATIVE 0 +#define MISC_CTRL_HITACHI_READY_POSITIVE 1 +#define MISC_CTRL_INTERRUPT 16:16 +#define MISC_CTRL_INTERRUPT_NORMAL 0 +#define MISC_CTRL_INTERRUPT_INVERT 1 +#define MISC_CTRL_PLL_CLOCK_COUNT 15:15 +#define MISC_CTRL_PLL_CLOCK_COUNT_DISABLE 0 +#define MISC_CTRL_PLL_CLOCK_COUNT_ENABLE 1 +#define MISC_CTRL_DAC_BAND_GAP 14:13 +#define MISC_CTRL_DAC_POWER 12:12 +#define MISC_CTRL_DAC_POWER_ENABLE 0 +#define MISC_CTRL_DAC_POWER_DISABLE 1 +#define MISC_CTRL_USB_SLAVE_CONTROLLER 11:11 +#define MISC_CTRL_USB_SLAVE_CONTROLLER_CPU 0 +#define MISC_CTRL_USB_SLAVE_CONTROLLER_8051 1 +#define MISC_CTRL_BURST_LENGTH 10:10 +#define MISC_CTRL_BURST_LENGTH_8 0 +#define MISC_CTRL_BURST_LENGTH_1 1 +#define MISC_CTRL_USB_SELECT 9:9 +#define MISC_CTRL_USB_SELECT_MASTER 0 +#define MISC_CTRL_USB_SELECT_SLAVE 1 +#define MISC_CTRL_LOOPBACK 8:8 +#define MISC_CTRL_LOOPBACK_NORMAL 0 +#define MISC_CTRL_LOOPBACK_USB_HOST 1 +#define MISC_CTRL_CLOCK_DIVIDER_RESET 7:7 +#define MISC_CTRL_CLOCK_DIVIDER_RESET_ENABLE 0 +#define MISC_CTRL_CLOCK_DIVIDER_RESET_DISABLE 1 +#define MISC_CTRL_TEST_MODE 6:5 +#define MISC_CTRL_TEST_MODE_NORMAL 0 +#define MISC_CTRL_TEST_MODE_DEBUGGING 1 +#define MISC_CTRL_TEST_MODE_NAND 2 +#define MISC_CTRL_TEST_MODE_MEMORY 3 +#define MISC_CTRL_NEC_MMIO 4:4 +#define MISC_CTRL_NEC_MMIO_30 0 +#define MISC_CTRL_NEC_MMIO_62 1 +#define MISC_CTRL_CLOCK 3:3 +#define MISC_CTRL_CLOCK_PLL 0 +#define MISC_CTRL_CLOCK_TEST 1 +#define MISC_CTRL_HOST_BUS 2:0 +#define MISC_CTRL_HOST_BUS_HITACHI 0 +#define MISC_CTRL_HOST_BUS_PCI 1 +#define MISC_CTRL_HOST_BUS_XSCALE 2 +#define MISC_CTRL_HOST_BUS_STRONGARM 4 +#define MISC_CTRL_HOST_BUS_NEC 6 + +#define GPIO_MUX_LOW 0x000008 +#define GPIO_MUX_LOW_31 31:31 +#define GPIO_MUX_LOW_31_GPIO 0 +#define GPIO_MUX_LOW_31_PWM 1 +#define GPIO_MUX_LOW_30 30:30 +#define GPIO_MUX_LOW_30_GPIO 0 +#define GPIO_MUX_LOW_30_PWM 1 +#define GPIO_MUX_LOW_29 29:29 +#define GPIO_MUX_LOW_29_GPIO 0 +#define GPIO_MUX_LOW_29_PWM 1 +#define GPIO_MUX_LOW_28 28:28 +#define GPIO_MUX_LOW_28_GPIO 0 +#define GPIO_MUX_LOW_28_AC97_I2S 1 +#define GPIO_MUX_LOW_27 27:27 +#define GPIO_MUX_LOW_27_GPIO 0 +#define GPIO_MUX_LOW_27_AC97_I2S 1 +#define GPIO_MUX_LOW_26 26:26 +#define GPIO_MUX_LOW_26_GPIO 0 +#define GPIO_MUX_LOW_26_AC97_I2S 1 +#define GPIO_MUX_LOW_25 25:25 +#define GPIO_MUX_LOW_25_GPIO 0 +#define GPIO_MUX_LOW_25_AC97_I2S 1 +#define GPIO_MUX_LOW_24 24:24 +#define GPIO_MUX_LOW_24_GPIO 0 +#define GPIO_MUX_LOW_24_AC97 1 +#define GPIO_MUX_LOW_23 23:23 +#define GPIO_MUX_LOW_23_GPIO 0 +#define GPIO_MUX_LOW_23_ZVPORT 1 +#define GPIO_MUX_LOW_22 22:22 +#define GPIO_MUX_LOW_22_GPIO 0 +#define GPIO_MUX_LOW_22_ZVPORT 1 +#define GPIO_MUX_LOW_21 21:21 +#define GPIO_MUX_LOW_21_GPIO 0 +#define GPIO_MUX_LOW_21_ZVPORT 1 +#define GPIO_MUX_LOW_20 20:20 +#define GPIO_MUX_LOW_20_GPIO 0 +#define GPIO_MUX_LOW_20_ZVPORT 1 +#define GPIO_MUX_LOW_19 19:19 +#define GPIO_MUX_LOW_19_GPIO 0 +#define GPIO_MUX_LOW_19_ZVPORT 1 +#define GPIO_MUX_LOW_18 18:18 +#define GPIO_MUX_LOW_18_GPIO 0 +#define GPIO_MUX_LOW_18_ZVPORT 1 +#define GPIO_MUX_LOW_17 17:17 +#define GPIO_MUX_LOW_17_GPIO 0 +#define GPIO_MUX_LOW_17_ZVPORT 1 +#define GPIO_MUX_LOW_16 16:16 +#define GPIO_MUX_LOW_16_GPIO 0 +#define GPIO_MUX_LOW_16_ZVPORT 1 +#define GPIO_MUX_LOW_15 15:15 +#define GPIO_MUX_LOW_15_GPIO 0 +#define GPIO_MUX_LOW_15_8051 1 +#define GPIO_MUX_LOW_14 14:14 +#define GPIO_MUX_LOW_14_GPIO 0 +#define GPIO_MUX_LOW_14_8051 1 +#define GPIO_MUX_LOW_13 13:13 +#define GPIO_MUX_LOW_13_GPIO 0 +#define GPIO_MUX_LOW_13_8051 1 +#define GPIO_MUX_LOW_12 12:12 +#define GPIO_MUX_LOW_12_GPIO 0 +#define GPIO_MUX_LOW_12_8051 1 +#define GPIO_MUX_LOW_11 11:11 +#define GPIO_MUX_LOW_11_GPIO 0 +#define GPIO_MUX_LOW_11_8051 1 +#define GPIO_MUX_LOW_10 10:10 +#define GPIO_MUX_LOW_10_GPIO 0 +#define GPIO_MUX_LOW_10_8051 1 +#define GPIO_MUX_LOW_9 9:9 +#define GPIO_MUX_LOW_9_GPIO 0 +#define GPIO_MUX_LOW_9_8051 1 +#define GPIO_MUX_LOW_8 8:8 +#define GPIO_MUX_LOW_8_GPIO 0 +#define GPIO_MUX_LOW_8_8051 1 +#define GPIO_MUX_LOW_7 7:7 +#define GPIO_MUX_LOW_7_GPIO 0 +#define GPIO_MUX_LOW_7_8051 1 +#define GPIO_MUX_LOW_6 6:6 +#define GPIO_MUX_LOW_6_GPIO 0 +#define GPIO_MUX_LOW_6_8051 1 +#define GPIO_MUX_LOW_5 5:5 +#define GPIO_MUX_LOW_5_GPIO 0 +#define GPIO_MUX_LOW_5_8051 1 +#define GPIO_MUX_LOW_4 4:4 +#define GPIO_MUX_LOW_4_GPIO 0 +#define GPIO_MUX_LOW_4_8051 1 +#define GPIO_MUX_LOW_3 3:3 +#define GPIO_MUX_LOW_3_GPIO 0 +#define GPIO_MUX_LOW_3_8051 1 +#define GPIO_MUX_LOW_2 2:2 +#define GPIO_MUX_LOW_2_GPIO 0 +#define GPIO_MUX_LOW_2_8051 1 +#define GPIO_MUX_LOW_1 1:1 +#define GPIO_MUX_LOW_1_GPIO 0 +#define GPIO_MUX_LOW_1_8051 1 +#define GPIO_MUX_LOW_0 0:0 +#define GPIO_MUX_LOW_0_GPIO 0 +#define GPIO_MUX_LOW_0_8051 1 + +#define GPIO_MUX_HIGH 0x00000C +#define GPIO_MUX_HIGH_63 31:31 +#define GPIO_MUX_HIGH_63_GPIO 0 +#define GPIO_MUX_HIGH_63_CRT_ZVPORT_FPDATA 1 +#define GPIO_MUX_HIGH_62 30:30 +#define GPIO_MUX_HIGH_62_GPIO 0 +#define GPIO_MUX_HIGH_62_CRT_ZVPORT_FPDATA 1 +#define GPIO_MUX_HIGH_61 29:29 +#define GPIO_MUX_HIGH_61_GPIO 0 +#define GPIO_MUX_HIGH_61_CRT_ZVPORT_FPDATA 1 +#define GPIO_MUX_HIGH_60 28:28 +#define GPIO_MUX_HIGH_60_GPIO 0 +#define GPIO_MUX_HIGH_60_CRT_ZVPORT_FPDATA 1 +#define GPIO_MUX_HIGH_59 27:27 +#define GPIO_MUX_HIGH_59_GPIO 0 +#define GPIO_MUX_HIGH_59_CRT_ZVPORT_FPDATA 1 +#define GPIO_MUX_HIGH_58 26:26 +#define GPIO_MUX_HIGH_58_GPIO 0 +#define GPIO_MUX_HIGH_58_CRT_ZVPORT_FPDATA 1 +#define GPIO_MUX_HIGH_57 25:25 +#define GPIO_MUX_HIGH_57_GPIO 0 +#define GPIO_MUX_HIGH_57_CRT_ZVPORT 1 +#define GPIO_MUX_HIGH_56 24:24 +#define GPIO_MUX_HIGH_56_GPIO 0 +#define GPIO_MUX_HIGH_56_CRT_ZVPORT 1 +#define GPIO_MUX_HIGH_55 23:23 +#define GPIO_MUX_HIGH_55_GPIO 0 +#define GPIO_MUX_HIGH_55_CRT 1 +#define GPIO_MUX_HIGH_47 15:15 +#define GPIO_MUX_HIGH_47_GPIO 0 +#define GPIO_MUX_HIGH_47_I2C 1 +#define GPIO_MUX_HIGH_46 14:14 +#define GPIO_MUX_HIGH_46_GPIO 0 +#define GPIO_MUX_HIGH_46_I2C 1 +#define GPIO_MUX_HIGH_45 13:13 +#define GPIO_MUX_HIGH_45_GPIO 0 +#define GPIO_MUX_HIGH_45_SSP1 1 +#define GPIO_MUX_HIGH_44 12:12 +#define GPIO_MUX_HIGH_44_GPIO 0 +#define GPIO_MUX_HIGH_44_UART1_SSP1 1 +#define GPIO_MUX_HIGH_43 11:11 +#define GPIO_MUX_HIGH_43_GPIO 0 +#define GPIO_MUX_HIGH_43_UART1_SSP1 1 +#define GPIO_MUX_HIGH_42 10:10 +#define GPIO_MUX_HIGH_42_GPIO 0 +#define GPIO_MUX_HIGH_42_UART1_SSP1 1 +#define GPIO_MUX_HIGH_41 9:9 +#define GPIO_MUX_HIGH_41_GPIO 0 +#define GPIO_MUX_HIGH_41_UART1_SSP1 1 +#define GPIO_MUX_HIGH_40 8:8 +#define GPIO_MUX_HIGH_40_GPIO 0 +#define GPIO_MUX_HIGH_40_UART0 1 +#define GPIO_MUX_HIGH_39 7:7 +#define GPIO_MUX_HIGH_39_GPIO 0 +#define GPIO_MUX_HIGH_39_UART0 1 +#define GPIO_MUX_HIGH_38 6:6 +#define GPIO_MUX_HIGH_38_GPIO 0 +#define GPIO_MUX_HIGH_38_UART0 1 +#define GPIO_MUX_HIGH_37 5:5 +#define GPIO_MUX_HIGH_37_GPIO 0 +#define GPIO_MUX_HIGH_37_UART0 1 +#define GPIO_MUX_HIGH_36 4:4 +#define GPIO_MUX_HIGH_36_GPIO 0 +#define GPIO_MUX_HIGH_36_SSP0 1 +#define GPIO_MUX_HIGH_35 3:3 +#define GPIO_MUX_HIGH_35_GPIO 0 +#define GPIO_MUX_HIGH_35_SSP0 1 +#define GPIO_MUX_HIGH_34 2:2 +#define GPIO_MUX_HIGH_34_GPIO 0 +#define GPIO_MUX_HIGH_34_SSP0 1 +#define GPIO_MUX_HIGH_33 1:1 +#define GPIO_MUX_HIGH_33_GPIO 0 +#define GPIO_MUX_HIGH_33_SSP0 1 +#define GPIO_MUX_HIGH_32 0:0 +#define GPIO_MUX_HIGH_32_GPIO 0 +#define GPIO_MUX_HIGH_32_SSP0 1 + +#define DRAM_CTRL 0x000010 +#define DRAM_CTRL_EMBEDDED 31:31 +#define DRAM_CTRL_EMBEDDED_ENABLE 0 +#define DRAM_CTRL_EMBEDDED_DISABLE 1 +#define DRAM_CTRL_CPU_BURST 30:28 +#define DRAM_CTRL_CPU_BURST_1 0 +#define DRAM_CTRL_CPU_BURST_2 1 +#define DRAM_CTRL_CPU_BURST_4 2 +#define DRAM_CTRL_CPU_BURST_8 3 +#define DRAM_CTRL_CPU_CAS_LATENCY 27:27 +#define DRAM_CTRL_CPU_CAS_LATENCY_2 0 +#define DRAM_CTRL_CPU_CAS_LATENCY_3 1 +#define DRAM_CTRL_CPU_SIZE 26:24 +#define DRAM_CTRL_CPU_SIZE_2 0 +#define DRAM_CTRL_CPU_SIZE_4 1 +#define DRAM_CTRL_CPU_SIZE_64 4 +#define DRAM_CTRL_CPU_SIZE_32 5 +#define DRAM_CTRL_CPU_SIZE_16 6 +#define DRAM_CTRL_CPU_SIZE_8 7 +#define DRAM_CTRL_CPU_COLUMN_SIZE 23:22 +#define DRAM_CTRL_CPU_COLUMN_SIZE_1024 0 +#define DRAM_CTRL_CPU_COLUMN_SIZE_512 2 +#define DRAM_CTRL_CPU_COLUMN_SIZE_256 3 +#define DRAM_CTRL_CPU_ACTIVE_PRECHARGE 21:21 +#define DRAM_CTRL_CPU_ACTIVE_PRECHARGE_6 0 +#define DRAM_CTRL_CPU_ACTIVE_PRECHARGE_7 1 +#define DRAM_CTRL_CPU_RESET 20:20 +#define DRAM_CTRL_CPU_RESET_ENABLE 0 +#define DRAM_CTRL_CPU_RESET_DISABLE 1 +#define DRAM_CTRL_CPU_BANKS 19:19 +#define DRAM_CTRL_CPU_BANKS_2 1 //ilena: 0 in driver.h,why? +#define DRAM_CTRL_CPU_BANKS_4 0 //ilena: 1 in driver.h, why? +#define DRAM_CTRL_CPU_WRITE_PRECHARGE 18:18 +#define DRAM_CTRL_CPU_WRITE_PRECHARGE_2 0 +#define DRAM_CTRL_CPU_WRITE_PRECHARGE_1 1 +#define DRAM_CTRL_BLOCK_WRITE 17:17 +#define DRAM_CTRL_BLOCK_WRITE_DISABLE 0 +#define DRAM_CTRL_BLOCK_WRITE_ENABLE 1 +#define DRAM_CTRL_REFRESH_COMMAND 16:16 +#define DRAM_CTRL_REFRESH_COMMAND_10 0 +#define DRAM_CTRL_REFRESH_COMMAND_12 1 +#define DRAM_CTRL_SIZE 15:13 +#define DRAM_CTRL_SIZE_4 0 +#define DRAM_CTRL_SIZE_8 1 +#define DRAM_CTRL_SIZE_16 2 +#define DRAM_CTRL_SIZE_32 3 +#define DRAM_CTRL_SIZE_64 4 +#define DRAM_CTRL_SIZE_2 5 +#define DRAM_CTRL_COLUMN_SIZE 12:11 +#define DRAM_CTRL_COLUMN_SIZE_256 0 +#define DRAM_CTRL_COLUMN_SIZE_512 2 +#define DRAM_CTRL_COLUMN_SIZE_1024 3 +#define DRAM_CTRL_BLOCK_WRITE_TIME 10:10 +#define DRAM_CTRL_BLOCK_WRITE_TIME_1 0 +#define DRAM_CTRL_BLOCK_WRITE_TIME_2 1 +#define DRAM_CTRL_BLOCK_WRITE_PRECHARGE 9:9 +#define DRAM_CTRL_BLOCK_WRITE_PRECHARGE_4 0 +#define DRAM_CTRL_BLOCK_WRITE_PRECHARGE_1 1 +#define DRAM_CTRL_ACTIVE_PRECHARGE 8:8 +#define DRAM_CTRL_ACTIVE_PRECHARGE_6 0 +#define DRAM_CTRL_ACTIVE_PRECHARGE_7 1 +#define DRAM_CTRL_RESET 7:7 +#define DRAM_CTRL_RESET_ENABLE 0 +#define DRAM_CTRL_RESET_DISABLE 1 +#define DRAM_CTRL_REMAIN_ACTIVE 6:6 +#define DRAM_CTRL_REMAIN_ACTIVE_ENABLE 0 +#define DRAM_CTRL_REMAIN_ACTIVE_DISABLE 1 +#define DRAM_CTRL_BANKS 1:1 +#define DRAM_CTRL_BANKS_2 1 +#define DRAM_CTRL_BANKS_4 0 +#define DRAM_CTRL_WRITE_PRECHARGE 0:0 +#define DRAM_CTRL_WRITE_PRECHARGE_2 0 +#define DRAM_CTRL_WRITE_PRECHARGE_1 1 + +#define ARBITRATION_CTRL 0x000014 +#define ARBITRATION_CTRL_CPUMEM 29:29 +#define ARBITRATION_CTRL_CPUMEM_FIXED 0 +#define ARBITRATION_CTRL_CPUMEM_ROTATE 1 +#define ARBITRATION_CTRL_INTMEM 28:28 +#define ARBITRATION_CTRL_INTMEM_FIXED 0 +#define ARBITRATION_CTRL_INTMEM_ROTATE 1 +#define ARBITRATION_CTRL_USB 27:24 +#define ARBITRATION_CTRL_USB_OFF 0 +#define ARBITRATION_CTRL_USB_PRIORITY_1 1 +#define ARBITRATION_CTRL_USB_PRIORITY_2 2 +#define ARBITRATION_CTRL_USB_PRIORITY_3 3 +#define ARBITRATION_CTRL_USB_PRIORITY_4 4 +#define ARBITRATION_CTRL_USB_PRIORITY_5 5 +#define ARBITRATION_CTRL_USB_PRIORITY_6 6 +#define ARBITRATION_CTRL_USB_PRIORITY_7 7 +#define ARBITRATION_CTRL_PANEL 23:20 +#define ARBITRATION_CTRL_PANEL_OFF 0 +#define ARBITRATION_CTRL_PANEL_PRIORITY_1 1 +#define ARBITRATION_CTRL_PANEL_PRIORITY_2 2 +#define ARBITRATION_CTRL_PANEL_PRIORITY_3 3 +#define ARBITRATION_CTRL_PANEL_PRIORITY_4 4 +#define ARBITRATION_CTRL_PANEL_PRIORITY_5 5 +#define ARBITRATION_CTRL_PANEL_PRIORITY_6 6 +#define ARBITRATION_CTRL_PANEL_PRIORITY_7 7 +#define ARBITRATION_CTRL_ZVPORT 19:16 +#define ARBITRATION_CTRL_ZVPORT_OFF 0 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_1 1 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_2 2 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_3 3 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_4 4 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_5 5 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_6 6 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_7 7 +#define ARBITRATION_CTRL_CMD_INTPR 15:12 +#define ARBITRATION_CTRL_CMD_INTPR_OFF 0 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_1 1 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_2 2 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_3 3 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_4 4 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_5 5 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_6 6 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_7 7 +#define ARBITRATION_CTRL_DMA 11:8 +#define ARBITRATION_CTRL_DMA_OFF 0 +#define ARBITRATION_CTRL_DMA_PRIORITY_1 1 +#define ARBITRATION_CTRL_DMA_PRIORITY_2 2 +#define ARBITRATION_CTRL_DMA_PRIORITY_3 3 +#define ARBITRATION_CTRL_DMA_PRIORITY_4 4 +#define ARBITRATION_CTRL_DMA_PRIORITY_5 5 +#define ARBITRATION_CTRL_DMA_PRIORITY_6 6 +#define ARBITRATION_CTRL_DMA_PRIORITY_7 7 +#define ARBITRATION_CTRL_VIDEO 7:4 +#define ARBITRATION_CTRL_VIDEO_OFF 0 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_1 1 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_2 2 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_3 3 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_4 4 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_5 5 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_6 6 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_7 7 +#define ARBITRATION_CTRL_CRT 3:0 +#define ARBITRATION_CTRL_CRT_OFF 0 +#define ARBITRATION_CTRL_CRT_PRIORITY_1 1 +#define ARBITRATION_CTRL_CRT_PRIORITY_2 2 +#define ARBITRATION_CTRL_CRT_PRIORITY_3 3 +#define ARBITRATION_CTRL_CRT_PRIORITY_4 4 +#define ARBITRATION_CTRL_CRT_PRIORITY_5 5 +#define ARBITRATION_CTRL_CRT_PRIORITY_6 6 +#define ARBITRATION_CTRL_CRT_PRIORITY_7 7 + +#define CMD_INTPR_CTRL 0x000018 +#define CMD_INTPR_CTRL_STATUS 31:31 +#define CMD_INTPR_CTRL_STATUS_STOPPED 0 +#define CMD_INTPR_CTRL_STATUS_RUNNING 1 +#define CMD_INTPR_CTRL_EXT 27:27 +#define CMD_INTPR_CTRL_EXT_LOCAL 0 +#define CMD_INTPR_CTRL_EXT_EXTERNAL 1 +#define CMD_INTPR_CTRL_CS 26:26 +#define CMD_INTPR_CTRL_CS_0 0 +#define CMD_INTPR_CTRL_CS_1 1 +#define CMD_INTPR_CTRL_ADDRESS 25:0 + +#define CMD_INTPR_CONDITIONS 0x00001C + +#define CMD_INTPR_RETURN 0x000020 +#define CMD_INTPR_RETURN_EXT 27:27 +#define CMD_INTPR_RETURN_EXT_LOCAL 0 +#define CMD_INTPR_RETURN_EXT_EXTERNAL 1 +#define CMD_INTPR_RETURN_CS 26:26 +#define CMD_INTPR_RETURN_CS_0 0 +#define CMD_INTPR_RETURN_CS_1 1 +#define CMD_INTPR_RETURN_ADDRESS 25:0 + +#define CMD_INTPR_STATUS 0x000024 +#define CMD_INTPR_STATUS_2D_MEMORY_FIFO 20:20 +#define CMD_INTPR_STATUS_2D_MEMORY_FIFO_NOT_EMPTY 0 +#define CMD_INTPR_STATUS_2D_MEMORY_FIFO_EMPTY 1 +#define CMD_INTPR_STATUS_COMMAND_FIFO 19:19 +#define CMD_INTPR_STATUS_COMMAND_FIFO_NOT_EMPTY 0 +#define CMD_INTPR_STATUS_COMMAND_FIFO_EMPTY 1 +#define CMD_INTPR_STATUS_CSC_STATUS 18:18 +#define CMD_INTPR_STATUS_CSC_STATUS_IDLE 0 +#define CMD_INTPR_STATUS_CSC_STATUS_BUSY 1 +#define CMD_INTPR_STATUS_MEMORY_DMA 17:17 +#define CMD_INTPR_STATUS_MEMORY_DMA_IDLE 0 +#define CMD_INTPR_STATUS_MEMORY_DMA_BUSY 1 +#define CMD_INTPR_STATUS_CRT_STATUS 16:16 +#define CMD_INTPR_STATUS_CRT_STATUS_CURRENT 0 +#define CMD_INTPR_STATUS_CRT_STATUS_PENDING 1 +#define CMD_INTPR_STATUS_CURRENT_FIELD 15:15 +#define CMD_INTPR_STATUS_CURRENT_FIELD_ODD 0 +#define CMD_INTPR_STATUS_CURRENT_FIELD_EVEN 1 +#define CMD_INTPR_STATUS_VIDEO_STATUS 14:14 +#define CMD_INTPR_STATUS_VIDEO_STATUS_CURRENT 0 +#define CMD_INTPR_STATUS_VIDEO_STATUS_PENDING 1 +#define CMD_INTPR_STATUS_PANEL_STATUS 13:13 +#define CMD_INTPR_STATUS_PANEL_STATUS_CURRENT 0 +#define CMD_INTPR_STATUS_PANEL_STATUS_PENDING 1 +#define CMD_INTPR_STATUS_CRT_SYNC 12:12 +#define CMD_INTPR_STATUS_CRT_SYNC_INACTIVE 0 +#define CMD_INTPR_STATUS_CRT_SYNC_ACTIVE 1 +#define CMD_INTPR_STATUS_PANEL_SYNC 11:11 +#define CMD_INTPR_STATUS_PANEL_SYNC_INACTIVE 0 +#define CMD_INTPR_STATUS_PANEL_SYNC_ACTIVE 1 +#define CMD_INTPR_STATUS_2D_SETUP 2:2 +#define CMD_INTPR_STATUS_2D_SETUP_IDLE 0 +#define CMD_INTPR_STATUS_2D_SETUP_BUSY 1 +#define CMD_INTPR_STATUS_2D_FIFO 1:1 +#define CMD_INTPR_STATUS_2D_FIFO_NOT_EMPTY 0 +#define CMD_INTPR_STATUS_2D_FIFO_EMPTY 1 +#define CMD_INTPR_STATUS_2D_ENGINE 0:0 +#define CMD_INTPR_STATUS_2D_ENGINE_IDLE 0 +#define CMD_INTPR_STATUS_2D_ENGINE_BUSY 1 + +#define RAW_INT_STATUS 0x000028 +#define RAW_INT_STATUS_ZVPORT1 6:6 +#define RAW_INT_STATUS_ZVPORT1_INACTIVE 0 +#define RAW_INT_STATUS_ZVPORT1_ACTIVE 1 +#define RAW_INT_STATUS_ZVPORT1_CLEAR 1 +#define RAW_INT_STATUS_USB_SLAVE_PLUG_IN 5:5 +#define RAW_INT_STATUS_USB_SLAVE_PLUG_IN_INACTIVE 0 +#define RAW_INT_STATUS_USB_SLAVE_PLUG_IN_ACTIVE 1 +#define RAW_INT_STATUS_USB_SLAVE_PLUG_IN_CLEAR 1 +#define RAW_INT_STATUS_ZVPORT 4:4 +#define RAW_INT_STATUS_ZVPORT_INACTIVE 0 +#define RAW_INT_STATUS_ZVPORT_ACTIVE 1 +#define RAW_INT_STATUS_ZVPORT_CLEAR 1 +#define RAW_INT_STATUS_CRT_VSYNC 3:3 +#define RAW_INT_STATUS_CRT_VSYNC_INACTIVE 0 +#define RAW_INT_STATUS_CRT_VSYNC_ACTIVE 1 +#define RAW_INT_STATUS_CRT_VSYNC_CLEAR 1 +#define RAW_INT_STATUS_USB_SLAVE 2:2 +#define RAW_INT_STATUS_USB_SLAVE_INACTIVE 0 +#define RAW_INT_STATUS_USB_SLAVE_ACTIVE 1 +#define RAW_INT_STATUS_USB_SLAVE_CLEAR 1 +#define RAW_INT_STATUS_PANEL_VSYNC 1:1 +#define RAW_INT_STATUS_PANEL_VSYNC_INACTIVE 0 +#define RAW_INT_STATUS_PANEL_VSYNC_ACTIVE 1 +#define RAW_INT_STATUS_PANEL_VSYNC_CLEAR 1 +#define RAW_INT_STATUS_CMD_INTPR 0:0 +#define RAW_INT_STATUS_CMD_INTPR_INACTIVE 0 +#define RAW_INT_STATUS_CMD_INTPR_ACTIVE 1 +#define RAW_INT_STATUS_CMD_INTPR_CLEAR 1 + +#define INT_STATUS 0x00002C +#define INT_STATUS_USB_SLAVE_PLUG_IN 31:31 +#define INT_STATUS_USB_SLAVE_PLUG_IN_INACTIVE 0 +#define INT_STATUS_USB_SLAVE_PLUG_IN_ACTIVE 1 +#define INT_STATUS_GPIO54 30:30 +#define INT_STATUS_GPIO54_INACTIVE 0 +#define INT_STATUS_GPIO54_ACTIVE 1 +#define INT_STATUS_GPIO53 29:29 +#define INT_STATUS_GPIO53_INACTIVE 0 +#define INT_STATUS_GPIO53_ACTIVE 1 +#define INT_STATUS_GPIO52 28:28 +#define INT_STATUS_GPIO52_INACTIVE 0 +#define INT_STATUS_GPIO52_ACTIVE 1 +#define INT_STATUS_GPIO51 27:27 +#define INT_STATUS_GPIO51_INACTIVE 0 +#define INT_STATUS_GPIO51_ACTIVE 1 +#define INT_STATUS_GPIO50 26:26 +#define INT_STATUS_GPIO50_INACTIVE 0 +#define INT_STATUS_GPIO50_ACTIVE 1 +#define INT_STATUS_GPIO49 25:25 +#define INT_STATUS_GPIO49_INACTIVE 0 +#define INT_STATUS_GPIO49_ACTIVE 1 +#define INT_STATUS_GPIO48 24:24 +#define INT_STATUS_GPIO48_INACTIVE 0 +#define INT_STATUS_GPIO48_ACTIVE 1 +#define INT_STATUS_I2C 23:23 +#define INT_STATUS_I2C_INACTIVE 0 +#define INT_STATUS_I2C_ACTIVE 1 +#define INT_STATUS_PWM 22:22 +#define INT_STATUS_PWM_INACTIVE 0 +#define INT_STATUS_PWM_ACTIVE 1 +#define INT_STATUS_DMA 20:20 +#define INT_STATUS_DMA_INACTIVE 0 +#define INT_STATUS_DMA_ACTIVE 1 +#define INT_STATUS_PCI 19:19 +#define INT_STATUS_PCI_INACTIVE 0 +#define INT_STATUS_PCI_ACTIVE 1 +#define INT_STATUS_I2S 18:18 +#define INT_STATUS_I2S_INACTIVE 0 +#define INT_STATUS_I2S_ACTIVE 1 +#define INT_STATUS_AC97 17:17 +#define INT_STATUS_AC97_INACTIVE 0 +#define INT_STATUS_AC97_ACTIVE 1 +#define INT_STATUS_USB_SLAVE 16:16 +#define INT_STATUS_USB_SLAVE_INACTIVE 0 +#define INT_STATUS_USB_SLAVE_ACTIVE 1 +#define INT_STATUS_UART1 13:13 +#define INT_STATUS_UART1_INACTIVE 0 +#define INT_STATUS_UART1_ACTIVE 1 +#define INT_STATUS_UART0 12:12 +#define INT_STATUS_UART0_INACTIVE 0 +#define INT_STATUS_UART0_ACTIVE 1 +#define INT_STATUS_CRT_VSYNC 11:11 +#define INT_STATUS_CRT_VSYNC_INACTIVE 0 +#define INT_STATUS_CRT_VSYNC_ACTIVE 1 +#define INT_STATUS_8051 10:10 +#define INT_STATUS_8051_INACTIVE 0 +#define INT_STATUS_8051_ACTIVE 1 +#define INT_STATUS_SSP1 9:9 +#define INT_STATUS_SSP1_INACTIVE 0 +#define INT_STATUS_SSP1_ACTIVE 1 +#define INT_STATUS_SSP0 8:8 +#define INT_STATUS_SSP0_INACTIVE 0 +#define INT_STATUS_SSP0_ACTIVE 1 +#define INT_STATUS_USB_HOST 6:6 +#define INT_STATUS_USB_HOST_INACTIVE 0 +#define INT_STATUS_USB_HOST_ACTIVE 1 +#define INT_STATUS_ZVPORT1 4:4 +#define INT_STATUS_ZVPORT1_INACTIVE 0 +#define INT_STATUS_ZVPORT1_ACTIVE 1 +#define INT_STATUS_2D 3:3 +#define INT_STATUS_2D_INACTIVE 0 +#define INT_STATUS_2D_ACTIVE 1 +#define INT_STATUS_ZVPORT 2:2 +#define INT_STATUS_ZVPORT_INACTIVE 0 +#define INT_STATUS_ZVPORT_ACTIVE 1 +#define INT_STATUS_PANEL_VSYNC 1:1 +#define INT_STATUS_PANEL_VSYNC_INACTIVE 0 +#define INT_STATUS_PANEL_VSYNC_ACTIVE 1 +#define INT_STATUS_CMD_INTPR 0:0 +#define INT_STATUS_CMD_INTPR_INACTIVE 0 +#define INT_STATUS_CMD_INTPR_ACTIVE 1 + +#define INT_MASK 0x000030 +#define INT_MASK_USB_SLAVE_PLUG_IN 31:31 +#define INT_MASK_USB_SLAVE_PLUG_IN_DISABLE 0 +#define INT_MASK_USB_SLAVE_PLUG_IN_ENABLE 1 +#define INT_MASK_GPIO54 30:30 +#define INT_MASK_GPIO54_DISABLE 0 +#define INT_MASK_GPIO54_ENABLE 1 +#define INT_MASK_GPIO53 29:29 +#define INT_MASK_GPIO53_DISABLE 0 +#define INT_MASK_GPIO53_ENABLE 1 +#define INT_MASK_GPIO52 28:28 +#define INT_MASK_GPIO52_DISABLE 0 +#define INT_MASK_GPIO52_ENABLE 1 +#define INT_MASK_GPIO51 27:27 +#define INT_MASK_GPIO51_DISABLE 0 +#define INT_MASK_GPIO51_ENABLE 1 +#define INT_MASK_GPIO50 26:26 +#define INT_MASK_GPIO50_DISABLE 0 +#define INT_MASK_GPIO50_ENABLE 1 +#define INT_MASK_GPIO49 25:25 +#define INT_MASK_GPIO49_DISABLE 0 +#define INT_MASK_GPIO49_ENABLE 1 +#define INT_MASK_GPIO48 24:24 +#define INT_MASK_GPIO48_DISABLE 0 +#define INT_MASK_GPIO48_ENABLE 1 +#define INT_MASK_I2C 23:23 +#define INT_MASK_I2C_DISABLE 0 +#define INT_MASK_I2C_ENABLE 1 +#define INT_MASK_PWM 22:22 +#define INT_MASK_PWM_DISABLE 0 +#define INT_MASK_PWM_ENABLE 1 +#define INT_MASK_DMA 20:20 +#define INT_MASK_DMA_DISABLE 0 +#define INT_MASK_DMA_ENABLE 1 +#define INT_MASK_PCI 19:19 +#define INT_MASK_PCI_DISABLE 0 +#define INT_MASK_PCI_ENABLE 1 +#define INT_MASK_I2S 18:18 +#define INT_MASK_I2S_DISABLE 0 +#define INT_MASK_I2S_ENABLE 1 +#define INT_MASK_AC97 17:17 +#define INT_MASK_AC97_DISABLE 0 +#define INT_MASK_AC97_ENABLE 1 +#define INT_MASK_USB_SLAVE 16:16 +#define INT_MASK_USB_SLAVE_DISABLE 0 +#define INT_MASK_USB_SLAVE_ENABLE 1 +#define INT_MASK_UART1 13:13 +#define INT_MASK_UART1_DISABLE 0 +#define INT_MASK_UART1_ENABLE 1 +#define INT_MASK_UART0 12:12 +#define INT_MASK_UART0_DISABLE 0 +#define INT_MASK_UART0_ENABLE 1 +#define INT_MASK_CRT_VSYNC 11:11 +#define INT_MASK_CRT_VSYNC_DISABLE 0 +#define INT_MASK_CRT_VSYNC_ENABLE 1 +#define INT_MASK_8051 10:10 +#define INT_MASK_8051_DISABLE 0 +#define INT_MASK_8051_ENABLE 1 +#define INT_MASK_SSP1 9:9 +#define INT_MASK_SSP1_DISABLE 0 +#define INT_MASK_SSP1_ENABLE 1 +#define INT_MASK_SSP0 8:8 +#define INT_MASK_SSP0_DISABLE 0 +#define INT_MASK_SSP0_ENABLE 1 +#define INT_MASK_USB_HOST 6:6 +#define INT_MASK_USB_HOST_DISABLE 0 +#define INT_MASK_USB_HOST_ENABLE 1 +#define INT_MASK_ZV1 4:4 +#define INT_MASK_ZV1_DISABLE 0 +#define INT_MASK_ZV1_ENABLE 1 +#define INT_MASK_2D 3:3 +#define INT_MASK_2D_DISABLE 0 +#define INT_MASK_2D_ENABLE 1 +#define INT_MASK_ZVPORT 2:2 +#define INT_MASK_ZVPORT_DISABLE 0 +#define INT_MASK_ZVPORT_ENABLE 1 +#define INT_MASK_PANEL_VSYNC 1:1 +#define INT_MASK_PANEL_VSYNC_DISABLE 0 +#define INT_MASK_PANEL_VSYNC_ENABLE 1 +#define INT_MASK_CMD_INTPR 0:0 +#define INT_MASK_CMD_INTPR_DISABLE 0 +#define INT_MASK_CMD_INTPR_ENABLE 1 + +#define DEBUG_CTRL 0x000034 +#define DEBUG_CTRL_MODULE 7:5 +#define DEBUG_CTRL_PARTITION 4:0 +#define DEBUG_CTRL_PARTITION_HIF 0 +#define DEBUG_CTRL_PARTITION_CPUMEM 1 +#define DEBUG_CTRL_PARTITION_PCI 2 +#define DEBUG_CTRL_PARTITION_CMD_INTPR 3 +#define DEBUG_CTRL_PARTITION_DISPLAY 4 +#define DEBUG_CTRL_PARTITION_ZVPORT 5 +#define DEBUG_CTRL_PARTITION_2D 6 +#define DEBUG_CTRL_PARTITION_MIF 8 +#define DEBUG_CTRL_PARTITION_USB_HOST 10 +#define DEBUG_CTRL_PARTITION_SSP0 12 +#define DEBUG_CTRL_PARTITION_SSP1 13 +#define DEBUG_CTRL_PARTITION_UART0 19 +#define DEBUG_CTRL_PARTITION_UART1 20 +#define DEBUG_CTRL_PARTITION_I2C 21 +#define DEBUG_CTRL_PARTITION_8051 23 +#define DEBUG_CTRL_PARTITION_AC97 24 +#define DEBUG_CTRL_PARTITION_I2S 25 +#define DEBUG_CTRL_PARTITION_INTMEM 26 +#define DEBUG_CTRL_PARTITION_DMA 27 +#define DEBUG_CTRL_PARTITION_SIMULATION 28 + +#define CURRENT_POWER_GATE 0x000038 +#define CURRENT_POWER_GATE_AC97_I2S 18:18 +#define CURRENT_POWER_GATE_AC97_I2S_DISABLE 0 +#define CURRENT_POWER_GATE_AC97_I2S_ENABLE 1 +#define CURRENT_POWER_GATE_8051 17:17 +#define CURRENT_POWER_GATE_8051_DISABLE 0 +#define CURRENT_POWER_GATE_8051_ENABLE 1 +#define CURRENT_POWER_GATE_PLL 16:16 +#define CURRENT_POWER_GATE_PLL_DISABLE 0 +#define CURRENT_POWER_GATE_PLL_ENABLE 1 +#define CURRENT_POWER_GATE_OSCILLATOR 15:15 +#define CURRENT_POWER_GATE_OSCILLATOR_DISABLE 0 +#define CURRENT_POWER_GATE_OSCILLATOR_ENABLE 1 +#define CURRENT_POWER_GATE_PLL_RECOVERY 14:13 +#define CURRENT_POWER_GATE_PLL_RECOVERY_32 0 +#define CURRENT_POWER_GATE_PLL_RECOVERY_64 1 +#define CURRENT_POWER_GATE_PLL_RECOVERY_96 2 +#define CURRENT_POWER_GATE_PLL_RECOVERY_128 3 +#define CURRENT_POWER_GATE_USB_SLAVE 12:12 +#define CURRENT_POWER_GATE_USB_SLAVE_DISABLE 0 +#define CURRENT_POWER_GATE_USB_SLAVE_ENABLE 1 +#define CURRENT_POWER_GATE_USB_HOST 11:11 +#define CURRENT_POWER_GATE_USB_HOST_DISABLE 0 +#define CURRENT_POWER_GATE_USB_HOST_ENABLE 1 +#define CURRENT_POWER_GATE_SSP0_SSP1 10:10 +#define CURRENT_POWER_GATE_SSP0_SSP1_DISABLE 0 +#define CURRENT_POWER_GATE_SSP0_SSP1_ENABLE 1 +#define CURRENT_POWER_GATE_UART1 8:8 +#define CURRENT_POWER_GATE_UART1_DISABLE 0 +#define CURRENT_POWER_GATE_UART1_ENABLE 1 +#define CURRENT_POWER_GATE_UART0 7:7 +#define CURRENT_POWER_GATE_UART0_DISABLE 0 +#define CURRENT_POWER_GATE_UART0_ENABLE 1 +#define CURRENT_POWER_GATE_GPIO_PWM_I2C 6:6 +#define CURRENT_POWER_GATE_GPIO_PWM_I2C_DISABLE 0 +#define CURRENT_POWER_GATE_GPIO_PWM_I2C_ENABLE 1 +#define CURRENT_POWER_GATE_ZVPORT 5:5 +#define CURRENT_POWER_GATE_ZVPORT_DISABLE 0 +#define CURRENT_POWER_GATE_ZVPORT_ENABLE 1 +#define CURRENT_POWER_GATE_CSC 4:4 +#define CURRENT_POWER_GATE_CSC_DISABLE 0 +#define CURRENT_POWER_GATE_CSC_ENABLE 1 +#define CURRENT_POWER_GATE_2D 3:3 +#define CURRENT_POWER_GATE_2D_DISABLE 0 +#define CURRENT_POWER_GATE_2D_ENABLE 1 +#define CURRENT_POWER_GATE_DISPLAY 2:2 +#define CURRENT_POWER_GATE_DISPLAY_DISABLE 0 +#define CURRENT_POWER_GATE_DISPLAY_ENABLE 1 +#define CURRENT_POWER_GATE_INTMEM 1:1 +#define CURRENT_POWER_GATE_INTMEM_DISABLE 0 +#define CURRENT_POWER_GATE_INTMEM_ENABLE 1 +#define CURRENT_POWER_GATE_HOST 0:0 +#define CURRENT_POWER_GATE_HOST_DISABLE 0 +#define CURRENT_POWER_GATE_HOST_ENABLE 1 + +#define CURRENT_POWER_CLOCK 0x00003C + +#define CURRENT_POWER_CLOCK_DIS2XP 31:31 +#define CURRENT_POWER_CLOCK_DIS2XP_0 0 +#define CURRENT_POWER_CLOCK_DIS2XP_1 1 + +#define CURRENT_POWER_CLOCK_P2XCLK_DIS 31:31 +#define CURRENT_POWER_CLOCK_P2XCLK_DIS_NORMAL 0 +#define CURRENT_POWER_CLOCK_P2XCLK_DIS_1X 1 + +#define CURRENT_POWER_CLOCK_P2s 30:30 +#define CURRENT_POWER_CLOCK_P2s_HW 0 +#define CURRENT_POWER_CLOCK_P2s_SW 1 + +#define CURRENT_POWER_CLOCK_SEL 30:30 +#define CURRENT_POWER_CLOCK_SEL_PXCLK 0 +#define CURRENT_POWER_CLOCK_SEL_PLL 1 + +#define CURRENT_POWER_CLOCK_P2XCLK_SELECT 29:29 +#define CURRENT_POWER_CLOCK_P2XCLK_SELECT_288 0 +#define CURRENT_POWER_CLOCK_P2XCLK_SELECT_336 1 + +#define CURRENT_POWER_CLOCK_P2XCLK_SELECT_12X 0 +#define CURRENT_POWER_CLOCK_P2XCLK_SELECT_14X 1 + +#define CURRENT_POWER_CLOCK_P2XCLK_DIVIDER 28:27 +#define CURRENT_POWER_CLOCK_P2XCLK_DIVIDER_1 0 +#define CURRENT_POWER_CLOCK_P2XCLK_DIVIDER_3 1 +#define CURRENT_POWER_CLOCK_P2XCLK_DIVIDER_5 2 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT 26:24 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_0 0 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_1 1 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_2 2 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_3 3 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_4 4 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_5 5 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_6 6 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_7 7 + +#define CURRENT_POWER_CLOCK_V2XCLK_2X 21:21 + +#define CURRENT_POWER_CLOCK_V2XCLK_DIS 21:21 +#define CURRENT_POWER_CLOCK_V2XCLK_DIS_NORMAL 0 +#define CURRENT_POWER_CLOCK_V2XCLK_DIS_1X 1 + +#define CURRENT_POWER_CLOCK_V2XCLK_SELECT 20:20 +#define CURRENT_POWER_CLOCK_V2XCLK_SELECT_288 0 +#define CURRENT_POWER_CLOCK_V2XCLK_SELECT_336 1 +#define CURRENT_POWER_CLOCK_V2XCLK_SELECT_12X 0 +#define CURRENT_POWER_CLOCK_V2XCLK_SELECT_14X 1 +#define CURRENT_POWER_CLOCK_V2XCLK_DIVIDER 19:19 +#define CURRENT_POWER_CLOCK_V2XCLK_DIVIDER_1 0 +#define CURRENT_POWER_CLOCK_V2XCLK_DIVIDER_3 1 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT 18:16 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_0 0 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_1 1 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_2 2 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_3 3 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_4 4 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_5 5 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_6 6 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_7 7 +#define CURRENT_POWER_CLOCK_MCLK_SELECT 12:12 +#define CURRENT_POWER_CLOCK_MCLK_SELECT_288 0 +#define CURRENT_POWER_CLOCK_MCLK_SELECT_336 1 +#define CURRENT_POWER_CLOCK_MCLK_SELECT_12X 0 +#define CURRENT_POWER_CLOCK_MCLK_SELECT_14X 1 +#define CURRENT_POWER_CLOCK_MCLK_DIVIDER 11:11 +#define CURRENT_POWER_CLOCK_MCLK_DIVIDER_1 0 +#define CURRENT_POWER_CLOCK_MCLK_DIVIDER_3 1 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT 10:8 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_0 0 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_1 1 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_2 2 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_3 3 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_4 4 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_5 5 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_6 6 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_7 7 +#define CURRENT_POWER_CLOCK_M2XCLK_SELECT 4:4 +#define CURRENT_POWER_CLOCK_M2XCLK_SELECT_288 0 +#define CURRENT_POWER_CLOCK_M2XCLK_SELECT_336 1 +#define CURRENT_POWER_CLOCK_M2XCLK_SELECT_12X 0 +#define CURRENT_POWER_CLOCK_M2XCLK_SELECT_14X 1 +#define CURRENT_POWER_CLOCK_M2XCLK_DIVIDER 3:3 +#define CURRENT_POWER_CLOCK_M2XCLK_DIVIDER_1 0 +#define CURRENT_POWER_CLOCK_M2XCLK_DIVIDER_3 1 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT 2:0 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_0 0 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_1 1 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_2 2 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_3 3 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_4 4 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_5 5 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_6 6 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_7 7 + +#define POWER_MODE0_GATE 0x000040 +#define POWER_MODE0_GATE_AC97_I2S 18:18 +#define POWER_MODE0_GATE_AC97_I2S_DISABLE 0 +#define POWER_MODE0_GATE_AC97_I2S_ENABLE 1 +#define POWER_MODE0_GATE_8051 17:17 +#define POWER_MODE0_GATE_8051_DISABLE 0 +#define POWER_MODE0_GATE_8051_ENABLE 1 +#define POWER_MODE0_GATE_USB_SLAVE 12:12 +#define POWER_MODE0_GATE_USB_SLAVE_DISABLE 0 +#define POWER_MODE0_GATE_USB_SLAVE_ENABLE 1 +#define POWER_MODE0_GATE_USB_HOST 11:11 +#define POWER_MODE0_GATE_USB_HOST_DISABLE 0 +#define POWER_MODE0_GATE_USB_HOST_ENABLE 1 +#define POWER_MODE0_GATE_SSP0_SSP1 10:10 +#define POWER_MODE0_GATE_SSP0_SSP1_DISABLE 0 +#define POWER_MODE0_GATE_SSP0_SSP1_ENABLE 1 +#define POWER_MODE0_GATE_UART1 8:8 +#define POWER_MODE0_GATE_UART1_DISABLE 0 +#define POWER_MODE0_GATE_UART1_ENABLE 1 +#define POWER_MODE0_GATE_UART0 7:7 +#define POWER_MODE0_GATE_UART0_DISABLE 0 +#define POWER_MODE0_GATE_UART0_ENABLE 1 +#define POWER_MODE0_GATE_GPIO_PWM_I2C 6:6 +#define POWER_MODE0_GATE_GPIO_PWM_I2C_DISABLE 0 +#define POWER_MODE0_GATE_GPIO_PWM_I2C_ENABLE 1 +#define POWER_MODE0_GATE_ZVPORT 5:5 +#define POWER_MODE0_GATE_ZVPORT_DISABLE 0 +#define POWER_MODE0_GATE_ZVPORT_ENABLE 1 +#define POWER_MODE0_GATE_CSC 4:4 +#define POWER_MODE0_GATE_CSC_DISABLE 0 +#define POWER_MODE0_GATE_CSC_ENABLE 1 +#define POWER_MODE0_GATE_2D 3:3 +#define POWER_MODE0_GATE_2D_DISABLE 0 +#define POWER_MODE0_GATE_2D_ENABLE 1 +#define POWER_MODE0_GATE_DISPLAY 2:2 +#define POWER_MODE0_GATE_DISPLAY_DISABLE 0 +#define POWER_MODE0_GATE_DISPLAY_ENABLE 1 +#define POWER_MODE0_GATE_INTMEM 1:1 +#define POWER_MODE0_GATE_INTMEM_DISABLE 0 +#define POWER_MODE0_GATE_INTMEM_ENABLE 1 +#define POWER_MODE0_GATE_HOST 0:0 +#define POWER_MODE0_GATE_HOST_DISABLE 0 +#define POWER_MODE0_GATE_HOST_ENABLE 1 + +#define POWER_MODE0_CLOCK 0x000044 +#define POWER_MODE0_CLOCK_P2XCLK_DIS 31:31 +#define POWER_MODE0_CLOCK_P2XCLK_DIS_NORMAL 0 +#define POWER_MODE0_CLOCK_P2XCLK_DIS_1X 1 +#define POWER_MODE0_CLOCK_SEL 30:30 +#define POWER_MODE0_CLOCK_SEL_PXCLK 0 +#define POWER_MODE0_CLOCK_SEL_PLL 1 +#define POWER_MODE0_CLOCK_P2XCLK_SELECT 29:29 +#define POWER_MODE0_CLOCK_P2XCLK_SELECT_288 0 +#define POWER_MODE0_CLOCK_P2XCLK_SELECT_336 1 +#define POWER_MODE0_CLOCK_P2XCLK_SELECT_12X 0 +#define POWER_MODE0_CLOCK_P2XCLK_SELECT_14X 1 +#define POWER_MODE0_CLOCK_P2XCLK_DIVIDER 28:27 +#define POWER_MODE0_CLOCK_P2XCLK_DIVIDER_1 0 +#define POWER_MODE0_CLOCK_P2XCLK_DIVIDER_3 1 +#define POWER_MODE0_CLOCK_P2XCLK_DIVIDER_5 2 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT 26:24 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_0 0 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_1 1 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_2 2 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_3 3 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_4 4 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_5 5 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_6 6 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_7 7 +#define POWER_MODE0_CLOCK_V2XCLK_DIS 21:21 +#define POWER_MODE0_CLOCK_V2XCLK_DIS_NORMAL 0 +#define POWER_MODE0_CLOCK_V2XCLK_DIS_1X 1 +#define POWER_MODE0_CLOCK_V2XCLK_SELECT 20:20 +#define POWER_MODE0_CLOCK_V2XCLK_SELECT_288 0 +#define POWER_MODE0_CLOCK_V2XCLK_SELECT_336 1 +#define POWER_MODE0_CLOCK_V2XCLK_SELECT_12X 0 +#define POWER_MODE0_CLOCK_V2XCLK_SELECT_14X 1 +#define POWER_MODE0_CLOCK_V2XCLK_DIVIDER 19:19 +#define POWER_MODE0_CLOCK_V2XCLK_DIVIDER_1 0 +#define POWER_MODE0_CLOCK_V2XCLK_DIVIDER_3 1 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT 18:16 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_0 0 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_1 1 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_2 2 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_3 3 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_4 4 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_5 5 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_6 6 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_7 7 +#define POWER_MODE0_CLOCK_MCLK_SELECT 12:12 +#define POWER_MODE0_CLOCK_MCLK_SELECT_288 0 +#define POWER_MODE0_CLOCK_MCLK_SELECT_336 1 +#define POWER_MODE0_CLOCK_MCLK_SELECT_12X 0 +#define POWER_MODE0_CLOCK_MCLK_SELECT_14X 1 +#define POWER_MODE0_CLOCK_MCLK_DIVIDER 11:11 +#define POWER_MODE0_CLOCK_MCLK_DIVIDER_1 0 +#define POWER_MODE0_CLOCK_MCLK_DIVIDER_3 1 +#define POWER_MODE0_CLOCK_MCLK_SHIFT 10:8 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_0 0 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_1 1 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_2 2 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_3 3 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_4 4 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_5 5 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_6 6 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_7 7 +#define POWER_MODE0_CLOCK_M2XCLK_SELECT 4:4 +#define POWER_MODE0_CLOCK_M2XCLK_SELECT_288 0 +#define POWER_MODE0_CLOCK_M2XCLK_SELECT_336 1 +#define POWER_MODE0_CLOCK_M2XCLK_SELECT_12X 0 +#define POWER_MODE0_CLOCK_M2XCLK_SELECT_14X 1 +#define POWER_MODE0_CLOCK_M2XCLK_DIVIDER 3:3 +#define POWER_MODE0_CLOCK_M2XCLK_DIVIDER_1 0 +#define POWER_MODE0_CLOCK_M2XCLK_DIVIDER_3 1 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT 2:0 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_0 0 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_1 1 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_2 2 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_3 3 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_4 4 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_5 5 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_6 6 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_7 7 + +#define POWER_MODE1_GATE 0x000048 +#define POWER_MODE1_GATE_AC97_I2S 18:18 +#define POWER_MODE1_GATE_AC97_I2S_DISABLE 0 +#define POWER_MODE1_GATE_AC97_I2S_ENABLE 1 +#define POWER_MODE1_GATE_8051 17:17 +#define POWER_MODE1_GATE_8051_DISABLE 0 +#define POWER_MODE1_GATE_8051_ENABLE 1 +#define POWER_MODE1_GATE_USB_SLAVE 12:12 +#define POWER_MODE1_GATE_USB_SLAVE_DISABLE 0 +#define POWER_MODE1_GATE_USB_SLAVE_ENABLE 1 +#define POWER_MODE1_GATE_USB_HOST 11:11 +#define POWER_MODE1_GATE_USB_HOST_DISABLE 0 +#define POWER_MODE1_GATE_USB_HOST_ENABLE 1 +#define POWER_MODE1_GATE_SSP0_SSP1 10:10 +#define POWER_MODE1_GATE_SSP0_SSP1_DISABLE 0 +#define POWER_MODE1_GATE_SSP0_SSP1_ENABLE 1 +#define POWER_MODE1_GATE_UART1 8:8 +#define POWER_MODE1_GATE_UART1_DISABLE 0 +#define POWER_MODE1_GATE_UART1_ENABLE 1 +#define POWER_MODE1_GATE_UART0 7:7 +#define POWER_MODE1_GATE_UART0_DISABLE 0 +#define POWER_MODE1_GATE_UART0_ENABLE 1 +#define POWER_MODE1_GATE_GPIO_PWM_I2C 6:6 +#define POWER_MODE1_GATE_GPIO_PWM_I2C_DISABLE 0 +#define POWER_MODE1_GATE_GPIO_PWM_I2C_ENABLE 1 +#define POWER_MODE1_GATE_ZVPORT 5:5 +#define POWER_MODE1_GATE_ZVPORT_DISABLE 0 +#define POWER_MODE1_GATE_ZVPORT_ENABLE 1 +#define POWER_MODE1_GATE_CSC 4:4 +#define POWER_MODE1_GATE_CSC_DISABLE 0 +#define POWER_MODE1_GATE_CSC_ENABLE 1 +#define POWER_MODE1_GATE_2D 3:3 +#define POWER_MODE1_GATE_2D_DISABLE 0 +#define POWER_MODE1_GATE_2D_ENABLE 1 +#define POWER_MODE1_GATE_DISPLAY 2:2 +#define POWER_MODE1_GATE_DISPLAY_DISABLE 0 +#define POWER_MODE1_GATE_DISPLAY_ENABLE 1 +#define POWER_MODE1_GATE_INTMEM 1:1 +#define POWER_MODE1_GATE_INTMEM_DISABLE 0 +#define POWER_MODE1_GATE_INTMEM_ENABLE 1 +#define POWER_MODE1_GATE_HOST 0:0 +#define POWER_MODE1_GATE_HOST_DISABLE 0 +#define POWER_MODE1_GATE_HOST_ENABLE 1 + +#define POWER_MODE1_CLOCK 0x00004C +#define POWER_MODE1_CLOCK_P2XCLK_DIS 31:31 +#define POWER_MODE1_CLOCK_P2XCLK_DIS_NORMAL 0 +#define POWER_MODE1_CLOCK_P2XCLK_DIS_1X 1 +#define POWER_MODE1_CLOCK_SEL 30:30 +#define POWER_MODE1_CLOCK_SEL_PXCLK 0 +#define POWER_MODE1_CLOCK_SEL_PLL 1 +#define POWER_MODE1_CLOCK_P2XCLK_SELECT 29:29 +#define POWER_MODE1_CLOCK_P2XCLK_SELECT_288 0 +#define POWER_MODE1_CLOCK_P2XCLK_SELECT_336 1 +#define POWER_MODE1_CLOCK_P2XCLK_SELECT_12X 0 +#define POWER_MODE1_CLOCK_P2XCLK_SELECT_14X 1 +#define POWER_MODE1_CLOCK_P2XCLK_DIVIDER 28:27 +#define POWER_MODE1_CLOCK_P2XCLK_DIVIDER_1 0 +#define POWER_MODE1_CLOCK_P2XCLK_DIVIDER_3 1 +#define POWER_MODE1_CLOCK_P2XCLK_DIVIDER_5 2 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT 26:24 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_0 0 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_1 1 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_2 2 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_3 3 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_4 4 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_5 5 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_6 6 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_7 7 +#define POWER_MODE1_CLOCK_V2XCLK_DIS 21:21 +#define POWER_MODE1_CLOCK_V2XCLK_DIS_NORMAL 0 +#define POWER_MODE1_CLOCK_V2XCLK_DIS_1X 1 +#define POWER_MODE1_CLOCK_V2XCLK_SELECT 20:20 +#define POWER_MODE1_CLOCK_V2XCLK_SELECT_288 0 +#define POWER_MODE1_CLOCK_V2XCLK_SELECT_336 1 +#define POWER_MODE1_CLOCK_V2XCLK_SELECT_12X 0 +#define POWER_MODE1_CLOCK_V2XCLK_SELECT_14X 1 +#define POWER_MODE1_CLOCK_V2XCLK_DIVIDER 19:19 +#define POWER_MODE1_CLOCK_V2XCLK_DIVIDER_1 0 +#define POWER_MODE1_CLOCK_V2XCLK_DIVIDER_3 1 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT 18:16 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_0 0 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_1 1 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_2 2 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_3 3 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_4 4 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_5 5 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_6 6 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_7 7 +#define POWER_MODE1_CLOCK_MCLK_SELECT 12:12 +#define POWER_MODE1_CLOCK_MCLK_SELECT_288 0 +#define POWER_MODE1_CLOCK_MCLK_SELECT_336 1 +#define POWER_MODE1_CLOCK_MCLK_SELECT_12X 0 +#define POWER_MODE1_CLOCK_MCLK_SELECT_14X 1 +#define POWER_MODE1_CLOCK_MCLK_DIVIDER 11:11 +#define POWER_MODE1_CLOCK_MCLK_DIVIDER_1 0 +#define POWER_MODE1_CLOCK_MCLK_DIVIDER_3 1 +#define POWER_MODE1_CLOCK_MCLK_SHIFT 10:8 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_0 0 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_1 1 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_2 2 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_3 3 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_4 4 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_5 5 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_6 6 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_7 7 +#define POWER_MODE1_CLOCK_M2XCLK_SELECT 4:4 +#define POWER_MODE1_CLOCK_M2XCLK_SELECT_288 0 +#define POWER_MODE1_CLOCK_M2XCLK_SELECT_336 1 +#define POWER_MODE1_CLOCK_M2XCLK_SELECT_12X 0 +#define POWER_MODE1_CLOCK_M2XCLK_SELECT_14X 1 +#define POWER_MODE1_CLOCK_M2XCLK_DIVIDER 3:3 +#define POWER_MODE1_CLOCK_M2XCLK_DIVIDER_1 0 +#define POWER_MODE1_CLOCK_M2XCLK_DIVIDER_3 1 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT 2:0 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_0 0 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_1 1 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_2 2 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_3 3 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_4 4 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_5 5 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_6 6 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_7 7 + +#define POWER_SLEEP_GATE 0x000050 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK 22:19 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_4096 0 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_2048 1 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_1024 2 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_512 3 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_256 4 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_128 5 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_64 6 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_32 7 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_16 8 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_8 9 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_4 10 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_2 11 +#define POWER_SLEEP_GATE_PLL_RECOVERY 14:13 +#define POWER_SLEEP_GATE_PLL_RECOVERY_32 0 +#define POWER_SLEEP_GATE_PLL_RECOVERY_64 1 +#define POWER_SLEEP_GATE_PLL_RECOVERY_96 2 +#define POWER_SLEEP_GATE_PLL_RECOVERY_128 3 + +#define POWER_MODE_CTRL 0x000054 +#define POWER_MODE_CTRL_SLEEP_STATUS 2:2 +#define POWER_MODE_CTRL_SLEEP_STATUS_INACTIVE 0 +#define POWER_MODE_CTRL_SLEEP_STATUS_ACTIVE 1 +#define POWER_MODE_CTRL_MODE 1:0 +#define POWER_MODE_CTRL_MODE_MODE0 0 +#define POWER_MODE_CTRL_MODE_MODE1 1 +#define POWER_MODE_CTRL_MODE_SLEEP 2 + +#define PCI_MASTER_BASE 0x000058 +#define PCI_MASTER_BASE_ADDRESS 31:20 + +#define ENDIAN_CTRL 0x00005C +#define ENDIAN_CTRL_ENDIAN 0:0 +#define ENDIAN_CTRL_ENDIAN_LITTLE 0 +#define ENDIAN_CTRL_ENDIAN_BIG 1 + +#define DEVICE_ID 0x000060 +#define DEVICE_ID_DEVICE_ID 31:16 +#define DEVICE_ID_REVISION_ID 7:0 + +#define PLL_CLOCK_COUNT 0x000064 +#define PLL_CLOCK_COUNT_COUNTER 15:0 + +#define SYSTEM_DRAM_CTRL 0x000068 +#define SYSTEM_DRAM_CTRL_READ_DELAY 2:0 +#define SYSTEM_DRAM_CTRL_READ_DELAY_OFF 0 +#define SYSTEM_DRAM_CTRL_READ_DELAY_0_5NS 1 +#define SYSTEM_DRAM_CTRL_READ_DELAY_1NS 2 +#define SYSTEM_DRAM_CTRL_READ_DELAY_1_5NS 3 +#define SYSTEM_DRAM_CTRL_READ_DELAY_2NS 4 +#define SYSTEM_DRAM_CTRL_READ_DELAY_2_5NS 5 + +#define PROGRAMMABLE_PLL_CONTROL 0x000074 +#define PROGRAMMABLE_PLL_CONTROL_TSTOE 20:20 +#define PROGRAMMABLE_PLL_CONTROL_TSTOE_DISABLE 0 +#define PROGRAMMABLE_PLL_CONTROL_TSTOE_ENABLE 1 +#define PROGRAMMABLE_PLL_CONTROL_TST 19:18 +#define PROGRAMMABLE_PLL_CONTROL_TST_0 0 +#define PROGRAMMABLE_PLL_CONTROL_TST_1 1 +#define PROGRAMMABLE_PLL_CONTROL_TST_2 2 +#define PROGRAMMABLE_PLL_CONTROL_TST_3 3 +#define PROGRAMMABLE_PLL_CONTROL_PON 17:17 +#define PROGRAMMABLE_PLL_CONTROL_PON_OFF 0 +#define PROGRAMMABLE_PLL_CONTROL_PON_ON 1 +#define PROGRAMMABLE_PLL_CONTROL_SEL 16:16 +#define PROGRAMMABLE_PLL_CONTROL_SEL_CRYSTAL 0 +#define PROGRAMMABLE_PLL_CONTROL_SEL_TCLK 1 +#define PROGRAMMABLE_PLL_CONTROL_K 15:15 +#define PROGRAMMABLE_PLL_CONTROL_K_DISABLE 0 +#define PROGRAMMABLE_PLL_CONTROL_K_ENABLE 1 +#define PROGRAMMABLE_PLL_CONTROL_N 14:8 +#define PROGRAMMABLE_PLL_CONTROL_M 7:0 + diff --git a/src/ddk502/ddk502_regzv.h b/src/ddk502/ddk502_regzv.h new file mode 100644 index 0000000..4b98837 --- /dev/null +++ b/src/ddk502/ddk502_regzv.h @@ -0,0 +1,275 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* RegZV.h --- Voyager GX SDK +* This file contains the definitions for the ZV registers. +* +*******************************************************************/ + +/* ZV0 */ + +#define ZV0_CAPTURE_CTRL 0x090000 +#define ZV0_CAPTURE_CTRL_FIELD_INPUT 27:27 +#define ZV0_CAPTURE_CTRL_FIELD_INPUT_EVEN_FIELD 0 +#define ZV0_CAPTURE_CTRL_FIELD_INPUT_ODD_FIELD 0 +#define ZV0_CAPTURE_CTRL_SCAN 26:26 +#define ZV0_CAPTURE_CTRL_SCAN_PROGRESSIVE 0 +#define ZV0_CAPTURE_CTRL_SCAN_INTERLACE 1 +#define ZV0_CAPTURE_CTRL_CURRENT_BUFFER 25:25 +#define ZV0_CAPTURE_CTRL_CURRENT_BUFFER_0 0 +#define ZV0_CAPTURE_CTRL_CURRENT_BUFFER_1 1 +#define ZV0_CAPTURE_CTRL_VERTICAL_SYNC 24:24 +#define ZV0_CAPTURE_CTRL_VERTICAL_SYNC_INACTIVE 0 +#define ZV0_CAPTURE_CTRL_VERTICAL_SYNC_ACTIVE 1 +#define ZV0_CAPTURE_CTRL_ADJ 19:19 +#define ZV0_CAPTURE_CTRL_ADJ_NORMAL 0 +#define ZV0_CAPTURE_CTRL_ADJ_DELAY 1 +#define ZV0_CAPTURE_CTRL_HA 18:18 +#define ZV0_CAPTURE_CTRL_HA_DISABLE 0 +#define ZV0_CAPTURE_CTRL_HA_ENABLE 1 +#define ZV0_CAPTURE_CTRL_VSK 17:17 +#define ZV0_CAPTURE_CTRL_VSK_DISABLE 0 +#define ZV0_CAPTURE_CTRL_VSK_ENABLE 1 +#define ZV0_CAPTURE_CTRL_HSK 16:16 +#define ZV0_CAPTURE_CTRL_HSK_DISABLE 0 +#define ZV0_CAPTURE_CTRL_HSK_ENABLE 1 +#define ZV0_CAPTURE_CTRL_FD 15:15 +#define ZV0_CAPTURE_CTRL_FD_RISING 0 +#define ZV0_CAPTURE_CTRL_FD_FALLING 1 +#define ZV0_CAPTURE_CTRL_VP 14:14 +#define ZV0_CAPTURE_CTRL_VP_HIGH 0 +#define ZV0_CAPTURE_CTRL_VP_LOW 1 +#define ZV0_CAPTURE_CTRL_HP 13:13 +#define ZV0_CAPTURE_CTRL_HP_HIGH 0 +#define ZV0_CAPTURE_CTRL_HP_LOW 1 +#define ZV0_CAPTURE_CTRL_CP 12:12 +#define ZV0_CAPTURE_CTRL_CP_HIGH 0 +#define ZV0_CAPTURE_CTRL_CP_LOW 1 +#define ZV0_CAPTURE_CTRL_UVS 11:11 +#define ZV0_CAPTURE_CTRL_UVS_DISABLE 0 +#define ZV0_CAPTURE_CTRL_UVS_ENABLE 1 +#define ZV0_CAPTURE_CTRL_BS 10:10 +#define ZV0_CAPTURE_CTRL_BS_DISABLE 0 +#define ZV0_CAPTURE_CTRL_BS_ENABLE 1 +#define ZV0_CAPTURE_CTRL_CS 9:9 +#define ZV0_CAPTURE_CTRL_CS_16 0 +#define ZV0_CAPTURE_CTRL_CS_8 1 +#define ZV0_CAPTURE_CTRL_CF 8:8 +#define ZV0_CAPTURE_CTRL_CF_YUV 0 +#define ZV0_CAPTURE_CTRL_CF_RGB 1 +#define ZV0_CAPTURE_CTRL_FS 7:7 +#define ZV0_CAPTURE_CTRL_FS_DISABLE 0 +#define ZV0_CAPTURE_CTRL_FS_ENABLE 1 +#define ZV0_CAPTURE_CTRL_WEAVE 6:6 +#define ZV0_CAPTURE_CTRL_WEAVE_DISABLE 0 +#define ZV0_CAPTURE_CTRL_WEAVE_ENABLE 1 +#define ZV0_CAPTURE_CTRL_BOB 5:5 +#define ZV0_CAPTURE_CTRL_BOB_DISABLE 0 +#define ZV0_CAPTURE_CTRL_BOB_ENABLE 1 +#define ZV0_CAPTURE_CTRL_DB 4:4 +#define ZV0_CAPTURE_CTRL_DB_DISABLE 0 +#define ZV0_CAPTURE_CTRL_DB_ENABLE 1 +#define ZV0_CAPTURE_CTRL_CC 3:3 +#define ZV0_CAPTURE_CTRL_CC_CONTINUE 0 +#define ZV0_CAPTURE_CTRL_CC_CONDITION 1 +#define ZV0_CAPTURE_CTRL_RGB 2:2 +#define ZV0_CAPTURE_CTRL_RGB_DISABLE 0 +#define ZV0_CAPTURE_CTRL_RGB_ENABLE 1 +#define ZV0_CAPTURE_CTRL_656 1:1 +#define ZV0_CAPTURE_CTRL_656_DISABLE 0 +#define ZV0_CAPTURE_CTRL_656_ENABLE 1 +#define ZV0_CAPTURE_CTRL_CAP 0:0 +#define ZV0_CAPTURE_CTRL_CAP_DISABLE 0 +#define ZV0_CAPTURE_CTRL_CAP_ENABLE 1 + +#define ZV0_CAPTURE_CLIP 0x090004 +#define ZV0_CAPTURE_CLIP_YCLIP 25:16 +#define ZV0_CAPTURE_CLIP_XCLIP 9:0 + +#define ZV0_CAPTURE_SIZE 0x090008 +#define ZV0_CAPTURE_SIZE_HEIGHT 26:16 +#define ZV0_CAPTURE_SIZE_WIDTH 10:0 + +#define ZV0_CAPTURE_BUF0_ADDRESS 0x09000C +#define ZV0_CAPTURE_BUF0_ADDRESS_STATUS 31:31 +#define ZV0_CAPTURE_BUF0_ADDRESS_STATUS_CURRENT 0 +#define ZV0_CAPTURE_BUF0_ADDRESS_STATUS_PENDING 1 +#define ZV0_CAPTURE_BUF0_ADDRESS_EXT 27:27 +#define ZV0_CAPTURE_BUF0_ADDRESS_EXT_LOCAL 0 +#define ZV0_CAPTURE_BUF0_ADDRESS_EXT_EXTERNAL 1 +#define ZV0_CAPTURE_BUF0_ADDRESS_CS 26:26 +#define ZV0_CAPTURE_BUF0_ADDRESS_CS_0 0 +#define ZV0_CAPTURE_BUF0_ADDRESS_CS_1 1 +#define ZV0_CAPTURE_BUF0_ADDRESS_ADDRESS 25:0 + +#define ZV0_CAPTURE_BUF1_ADDRESS 0x090010 +#define ZV0_CAPTURE_BUF1_ADDRESS_STATUS 31:31 +#define ZV0_CAPTURE_BUF1_ADDRESS_STATUS_CURRENT 0 +#define ZV0_CAPTURE_BUF1_ADDRESS_STATUS_PENDING 1 +#define ZV0_CAPTURE_BUF1_ADDRESS_EXT 27:27 +#define ZV0_CAPTURE_BUF1_ADDRESS_EXT_LOCAL 0 +#define ZV0_CAPTURE_BUF1_ADDRESS_EXT_EXTERNAL 1 +#define ZV0_CAPTURE_BUF1_ADDRESS_CS 26:26 +#define ZV0_CAPTURE_BUF1_ADDRESS_CS_0 0 +#define ZV0_CAPTURE_BUF1_ADDRESS_CS_1 1 +#define ZV0_CAPTURE_BUF1_ADDRESS_ADDRESS 25:0 + +#define ZV0_CAPTURE_BUF_OFFSET 0x090014 +#define ZV0_CAPTURE_BUF_OFFSET_OFFSET 15:0 + +#define ZV0_CAPTURE_FIFO_CTRL 0x090018 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO 2:0 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_0 0 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_1 1 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_2 2 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_3 3 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_4 4 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_5 5 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_6 6 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_7 7 + +#define ZV0_CAPTURE_YRGB_CONST 0x09001C +#define ZV0_CAPTURE_YRGB_CONST_Y 31:24 +#define ZV0_CAPTURE_YRGB_CONST_R 23:16 +#define ZV0_CAPTURE_YRGB_CONST_G 15:8 +#define ZV0_CAPTURE_YRGB_CONST_B 7:0 + +#define ZV0_CAPTURE_LINE_COMP 0x090020 +#define ZV0_CAPTURE_LINE_COMP_LC 10:0 + +/* ZV1 */ + +#define ZV1_CAPTURE_CTRL 0x098000 +#define ZV1_CAPTURE_CTRL_FIELD_INPUT 27:27 +#define ZV1_CAPTURE_CTRL_FIELD_INPUT_EVEN_FIELD 0 +#define ZV1_CAPTURE_CTRL_FIELD_INPUT_ODD_FIELD 0 +#define ZV1_CAPTURE_CTRL_SCAN 26:26 +#define ZV1_CAPTURE_CTRL_SCAN_PROGRESSIVE 0 +#define ZV1_CAPTURE_CTRL_SCAN_INTERLACE 1 +#define ZV1_CAPTURE_CTRL_CURRENT_BUFFER 25:25 +#define ZV1_CAPTURE_CTRL_CURRENT_BUFFER_0 0 +#define ZV1_CAPTURE_CTRL_CURRENT_BUFFER_1 1 +#define ZV1_CAPTURE_CTRL_VERTICAL_SYNC 24:24 +#define ZV1_CAPTURE_CTRL_VERTICAL_SYNC_INACTIVE 0 +#define ZV1_CAPTURE_CTRL_VERTICAL_SYNC_ACTIVE 1 +#define ZV1_CAPTURE_CTRL_PANEL 20:20 +#define ZV1_CAPTURE_CTRL_PANEL_DISABLE 0 +#define ZV1_CAPTURE_CTRL_PANEL_ENABLE 1 +#define ZV1_CAPTURE_CTRL_ADJ 19:19 +#define ZV1_CAPTURE_CTRL_ADJ_NORMAL 0 +#define ZV1_CAPTURE_CTRL_ADJ_DELAY 1 +#define ZV1_CAPTURE_CTRL_HA 18:18 +#define ZV1_CAPTURE_CTRL_HA_DISABLE 0 +#define ZV1_CAPTURE_CTRL_HA_ENABLE 1 +#define ZV1_CAPTURE_CTRL_VSK 17:17 +#define ZV1_CAPTURE_CTRL_VSK_DISABLE 0 +#define ZV1_CAPTURE_CTRL_VSK_ENABLE 1 +#define ZV1_CAPTURE_CTRL_HSK 16:16 +#define ZV1_CAPTURE_CTRL_HSK_DISABLE 0 +#define ZV1_CAPTURE_CTRL_HSK_ENABLE 1 +#define ZV1_CAPTURE_CTRL_FD 15:15 +#define ZV1_CAPTURE_CTRL_FD_RISING 0 +#define ZV1_CAPTURE_CTRL_FD_FALLING 1 +#define ZV1_CAPTURE_CTRL_VP 14:14 +#define ZV1_CAPTURE_CTRL_VP_HIGH 0 +#define ZV1_CAPTURE_CTRL_VP_LOW 1 +#define ZV1_CAPTURE_CTRL_HP 13:13 +#define ZV1_CAPTURE_CTRL_HP_HIGH 0 +#define ZV1_CAPTURE_CTRL_HP_LOW 1 +#define ZV1_CAPTURE_CTRL_CP 12:12 +#define ZV1_CAPTURE_CTRL_CP_HIGH 0 +#define ZV1_CAPTURE_CTRL_CP_LOW 1 +#define ZV1_CAPTURE_CTRL_UVS 11:11 +#define ZV1_CAPTURE_CTRL_UVS_DISABLE 0 +#define ZV1_CAPTURE_CTRL_UVS_ENABLE 1 +#define ZV1_CAPTURE_CTRL_BS 10:10 +#define ZV1_CAPTURE_CTRL_BS_DISABLE 0 +#define ZV1_CAPTURE_CTRL_BS_ENABLE 1 +#define ZV1_CAPTURE_CTRL_CS 9:9 +#define ZV1_CAPTURE_CTRL_CS_16 0 +#define ZV1_CAPTURE_CTRL_CS_8 1 +#define ZV1_CAPTURE_CTRL_CF 8:8 +#define ZV1_CAPTURE_CTRL_CF_YUV 0 +#define ZV1_CAPTURE_CTRL_CF_RGB 1 +#define ZV1_CAPTURE_CTRL_FS 7:7 +#define ZV1_CAPTURE_CTRL_FS_DISABLE 0 +#define ZV1_CAPTURE_CTRL_FS_ENABLE 1 +#define ZV1_CAPTURE_CTRL_WEAVE 6:6 +#define ZV1_CAPTURE_CTRL_WEAVE_DISABLE 0 +#define ZV1_CAPTURE_CTRL_WEAVE_ENABLE 1 +#define ZV1_CAPTURE_CTRL_BOB 5:5 +#define ZV1_CAPTURE_CTRL_BOB_DISABLE 0 +#define ZV1_CAPTURE_CTRL_BOB_ENABLE 1 +#define ZV1_CAPTURE_CTRL_DB 4:4 +#define ZV1_CAPTURE_CTRL_DB_DISABLE 0 +#define ZV1_CAPTURE_CTRL_DB_ENABLE 1 +#define ZV1_CAPTURE_CTRL_CC 3:3 +#define ZV1_CAPTURE_CTRL_CC_CONTINUE 0 +#define ZV1_CAPTURE_CTRL_CC_CONDITION 1 +#define ZV1_CAPTURE_CTRL_RGB 2:2 +#define ZV1_CAPTURE_CTRL_RGB_DISABLE 0 +#define ZV1_CAPTURE_CTRL_RGB_ENABLE 1 +#define ZV1_CAPTURE_CTRL_656 1:1 +#define ZV1_CAPTURE_CTRL_656_DISABLE 0 +#define ZV1_CAPTURE_CTRL_656_ENABLE 1 +#define ZV1_CAPTURE_CTRL_CAP 0:0 +#define ZV1_CAPTURE_CTRL_CAP_DISABLE 0 +#define ZV1_CAPTURE_CTRL_CAP_ENABLE 1 + +#define ZV1_CAPTURE_CLIP 0x098004 +#define ZV1_CAPTURE_CLIP_YCLIP 25:16 +#define ZV1_CAPTURE_CLIP_XCLIP 9:0 + +#define ZV1_CAPTURE_SIZE 0x098008 +#define ZV1_CAPTURE_SIZE_HEIGHT 26:16 +#define ZV1_CAPTURE_SIZE_WIDTH 10:0 + +#define ZV1_CAPTURE_BUF0_ADDRESS 0x09800C +#define ZV1_CAPTURE_BUF0_ADDRESS_STATUS 31:31 +#define ZV1_CAPTURE_BUF0_ADDRESS_STATUS_CURRENT 0 +#define ZV1_CAPTURE_BUF0_ADDRESS_STATUS_PENDING 1 +#define ZV1_CAPTURE_BUF0_ADDRESS_EXT 27:27 +#define ZV1_CAPTURE_BUF0_ADDRESS_EXT_LOCAL 0 +#define ZV1_CAPTURE_BUF0_ADDRESS_EXT_EXTERNAL 1 +#define ZV1_CAPTURE_BUF0_ADDRESS_CS 26:26 +#define ZV1_CAPTURE_BUF0_ADDRESS_CS_0 0 +#define ZV1_CAPTURE_BUF0_ADDRESS_CS_1 1 +#define ZV1_CAPTURE_BUF0_ADDRESS_ADDRESS 25:0 + +#define ZV1_CAPTURE_BUF1_ADDRESS 0x098010 +#define ZV1_CAPTURE_BUF1_ADDRESS_STATUS 31:31 +#define ZV1_CAPTURE_BUF1_ADDRESS_STATUS_CURRENT 0 +#define ZV1_CAPTURE_BUF1_ADDRESS_STATUS_PENDING 1 +#define ZV1_CAPTURE_BUF1_ADDRESS_EXT 27:27 +#define ZV1_CAPTURE_BUF1_ADDRESS_EXT_LOCAL 0 +#define ZV1_CAPTURE_BUF1_ADDRESS_EXT_EXTERNAL 1 +#define ZV1_CAPTURE_BUF1_ADDRESS_CS 26:26 +#define ZV1_CAPTURE_BUF1_ADDRESS_CS_0 0 +#define ZV1_CAPTURE_BUF1_ADDRESS_CS_1 1 +#define ZV1_CAPTURE_BUF1_ADDRESS_ADDRESS 25:0 + +#define ZV1_CAPTURE_BUF_OFFSET 0x098014 +#define ZV1_CAPTURE_BUF_OFFSET_OFFSET 15:0 + +#define ZV1_CAPTURE_FIFO_CTRL 0x098018 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO 2:0 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_0 0 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_1 1 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_2 2 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_3 3 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_4 4 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_5 5 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_6 6 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_7 7 + +#define ZV1_CAPTURE_YRGB_CONST 0x09801C +#define ZV1_CAPTURE_YRGB_CONST_Y 31:24 +#define ZV1_CAPTURE_YRGB_CONST_R 23:16 +#define ZV1_CAPTURE_YRGB_CONST_G 15:8 +#define ZV1_CAPTURE_YRGB_CONST_B 7:0 + + diff --git a/src/ddk502/ddk502_swi2c.c b/src/ddk502/ddk502_swi2c.c new file mode 100644 index 0000000..5b53429 --- /dev/null +++ b/src/ddk502/ddk502_swi2c.c @@ -0,0 +1,551 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* I2C.c --- Voyager GX SDK +* This file contains the source code for SW I2C. +* +*******************************************************************/ +#include "../smi_common.h" +#include "ddk502_voyager.h" +#include "ddk502_hardware.h" +#include "ddk502_power.h" +#include "ddk502_swi2c.h" +#include "ddk502_help.h" +#include "ddk502_reggpio.h" + +/******************************************************************* + * I2C Software Master Driver: + * =========================== + * Each i2c cycle is split into 4 sections. Each of these section marks + * a point in time where the SCL or SDA may be changed. + * + * 1 Cycle == | Section I. | Section 2. | Section 3. | Section 4. | + * +-------------+-------------+-------------+-------------+ + * | SCL set LOW |SCL no change| SCL set HIGH|SCL no change| + * + * ____________ _____________ + * SCL == XXXX _____________ ____________ / + * + * I.e. the SCL may only be changed in section 1. and section 3. while + * the SDA may only be changed in section 2. and section 4. The table + * below gives the changes for these 2 lines in the varios sections. + * + * Section changes Table: + * ====================== + * blank = no change, L = set bit LOW, H = set bit HIGH + * + * | 1.| 2.| 3.| 4.| + * ---------------+---+---+---+---+ + * Tx Start SDA | | H | | L | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * Tx Stop SDA | | L | | H | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * Tx bit H SDA | | H | | | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * Tx bit L SDA | | L | | | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * + ******************************************************************/ + +/* GPIO pins used for this I2C. It ranges from 0 to 63. */ +static unsigned char g_i2cClockGPIO = DEFAULT_I2C_SCL; +static unsigned char g_i2cDataGPIO = DEFAULT_I2C_SDA; + +/* + * Below is the variable declaration for the GPIO pin register usage + * for the i2c Clock and i2c Data. + * + * Note: + * Notice that the GPIO usage for the i2c clock and i2c Data are + * separated. This is to make this code flexible enough when + * two separate GPIO pins for the clock and data are located + * in two different GPIO register set (worst case). + */ + +/* i2c Clock GPIO Register usage */ +static unsigned long g_i2cClkGPIOMuxReg = GPIO_MUX_HIGH; +static unsigned long g_i2cClkGPIODataReg = GPIO_DATA_HIGH; +static unsigned long g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION_HIGH; + +/* i2c Data GPIO Register usage */ +static unsigned long g_i2cDataGPIOMuxReg = GPIO_MUX_HIGH; +static unsigned long g_i2cDataGPIODataReg = GPIO_DATA_HIGH; +static unsigned long g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION_HIGH; + +/******************************************************************************* + swI2CWait + This function puts a delay between command + + Parameters: + None + + Return Value: + None + *******************************************************************************/ +static void swI2CWait(void) +{ + int i, Temp; + + for(i=0; i<600; i++) + { + Temp = i; + Temp += i; + } +} + +/******************************************************************************* + swI2CSCL + This function set/reset the SCL GPIO pin + + Parameters: + value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + + Return Value: + None + *******************************************************************************/ +static void swI2CSCL(unsigned char value) +{ + unsigned long ulGPIOData; + unsigned long ulGPIODirection; + + ulGPIODirection = peekRegisterDWord(g_i2cClkGPIODataDirReg); + if (value) /* High */ + { + /* Set direction as input. This will automatically pull the signal up. */ + ulGPIODirection &= ~(1 << g_i2cClockGPIO); + pokeRegisterDWord(g_i2cClkGPIODataDirReg, ulGPIODirection); + } + else /* Low */ + { + /* Set the signal down */ + ulGPIOData = peekRegisterDWord(g_i2cClkGPIODataReg); + ulGPIOData &= ~(1 << g_i2cClockGPIO); + pokeRegisterDWord(g_i2cClkGPIODataReg, ulGPIOData); + + /* Set direction as output */ + ulGPIODirection |= (1 << g_i2cClockGPIO); + pokeRegisterDWord(g_i2cClkGPIODataDirReg, ulGPIODirection); + } +} + +/******************************************************************************* + swI2CSDA + This function set/reset the SDA GPIO pin + + Parameters: + value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + + Return Value: + None + *******************************************************************************/ +static void swI2CSDA(unsigned char value) +{ + unsigned long ulGPIOData; + unsigned long ulGPIODirection; + + ulGPIODirection = peekRegisterDWord(g_i2cDataGPIODataDirReg); + if (value) /* High */ + { + /* Set direction as input. This will automatically pull the signal up. */ + ulGPIODirection &= ~(1 << g_i2cDataGPIO); + pokeRegisterDWord(g_i2cDataGPIODataDirReg, ulGPIODirection); + } + else /* Low */ + { + /* Set the signal down */ + ulGPIOData = peekRegisterDWord(g_i2cDataGPIODataReg); + ulGPIOData &= ~(1 << g_i2cDataGPIO); + pokeRegisterDWord(g_i2cDataGPIODataReg, ulGPIOData); + + /* Set direction as output */ + ulGPIODirection |= (1 << g_i2cDataGPIO); + pokeRegisterDWord(g_i2cDataGPIODataDirReg, ulGPIODirection); + } +} + +/******************************************************************************* + swI2CReadSDA + This function read the data from the SDA GPIO pin + + Parameters: + None + + Return Value: + The SDA data bit sent by the Slave + *******************************************************************************/ +static unsigned char swI2CReadSDA() +{ + unsigned long ulGPIODirection; + unsigned long ulGPIOData; + + /* Make sure that the direction is input (High) */ + ulGPIODirection = peekRegisterDWord(g_i2cDataGPIODataDirReg); + if ((ulGPIODirection & (1 << g_i2cDataGPIO)) != (~(1 << g_i2cDataGPIO))) + { + ulGPIODirection &= ~(1 << g_i2cDataGPIO); + pokeRegisterDWord(g_i2cDataGPIODataDirReg, ulGPIODirection); + } + + /* Now read the SDA line */ + ulGPIOData = peekRegisterDWord(g_i2cDataGPIODataReg); + if (ulGPIOData & (1 << g_i2cDataGPIO)) + return 1; + else + return 0; +} + +#pragma optimize( "", off ) + +/******************************************************************************* + swI2CAck + This function sends ACK signal + + Parameters: + None + + Return Value: + None + *******************************************************************************/ +static void swI2CAck(void) +{ + return; /* Single byte read is ok without it. */ +} + +/******************************************************************************* + swI2CStart + This function sends the start command to the slave device + + Parameters: + None + + Return Value: + None + *******************************************************************************/ +void swI2CStart(void) +{ + /* Start I2C */ + swI2CSDA(1); + swI2CSCL(1); + swI2CSDA(0); +} + +/******************************************************************************* + swI2CStop + This function sends the stop command to the slave device + + Parameters: + None + + Return value: + None + *******************************************************************************/ +void swI2CStop() +{ + /* Stop the I2C */ + swI2CSCL(1); + swI2CSDA(0); + swI2CSDA(1); +} + + +/******************************************************************************* + swI2CWriteByte + This function writes one byte to the slave device + + Parameters: + data - Data to be write to the slave device + + Return Value: + 0 - Fail to write byte + 1 - Success + *******************************************************************************/ +unsigned char swI2CWriteByte(unsigned char data) +{ + unsigned char value = data; + int i; + + /* Sending the data bit by bit */ + for (i=0; i<8; i++) + { + /* Set SCL to low */ + swI2CSCL(0); + + /* Send data bit */ + if ((value & 0x80) != 0) + swI2CSDA(1); + else + swI2CSDA(0); + + swI2CWait(); + + /* Toggle clk line to one */ + swI2CSCL(1); + + /* Shift byte to be sent */ + value = value << 1; + } + + /* Set the SCL Low and SDA High (prepare to get input) */ + swI2CSCL(0); + swI2CSDA(1); + + /* Set the SCL High for ack */ + swI2CWait(); + swI2CSCL(1); + + /* Read SDA, until SDA==0 */ + for(i=0; i<0xff; i++) + { + swI2CWait(); + swI2CWait(); + if (!swI2CReadSDA()) + break; + } + + /* Set the SCL Low and SDA High */ + swI2CSCL(0); + swI2CSDA(1); + + return (i<0xff); +} + +/******************************************************************************* + swI2CWriteByte + This function writes one byte to the slave device + + Parameters: + ack - Flag to indicate either to send the acknowledge + message to the slave device or not + + Return Value: + One byte data read from the Slave device + *******************************************************************************/ +unsigned char swI2CReadByte(unsigned char ack) +{ + int i; + unsigned char data = 0; + + for(i=7; i>=0; i--) + { + /* Set the SCL to Low and SDA to High (Input) */ + swI2CSCL(0); + swI2CSDA(1); + swI2CWait(); + + /* Set the SCL High */ + swI2CSCL(1); + swI2CWait(); + + /* Read data bits from SDA */ + data |= (swI2CReadSDA() << i); + } + + if (ack) + swI2CAck(); + + /* Set the SCL Low and SDA High */ + swI2CSCL(0); + swI2CSDA(1); + + return data; +} +#pragma optimize( "", on ) + + +/******************************************************************************* + ddk502_swI2CInit + This function initializes the i2c attributes and bus + + Parameters: + i2cClkGPIO - The GPIO pin to be used as i2c SCL + i2cDataGPIO - The GPIO pin to be used as i2c SDA + + Return Value: + 0 - Fail to initialize the i2c + 1 - Success + *******************************************************************************/ +_X_EXPORT unsigned char ddk502_swI2CInit(unsigned char i2cClkGPIO, unsigned char i2cDataGPIO) +{ + int i; + unsigned long value; + unsigned long gate; + + /* Return 0 if the GPIO pins to be used is out of range. The range is only from [0..63] */ + if ((i2cClkGPIO > 63) || (i2cDataGPIO > 63)) + return 0; + + /* Initialize the GPIO pin for the i2c Clock Register */ + if (i2cClkGPIO < 32) + { + g_i2cClkGPIOMuxReg = GPIO_MUX_LOW; + g_i2cClkGPIODataReg = GPIO_DATA_LOW; + g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION_LOW; + + /* Initialize the Clock GPIO Offset */ + g_i2cClockGPIO = i2cClkGPIO; + + } + else + { + g_i2cClkGPIOMuxReg = GPIO_MUX_HIGH; + g_i2cClkGPIODataReg = GPIO_DATA_HIGH; + g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION_HIGH; + + /* Initialize the Clock GPIO Offset */ + g_i2cClockGPIO = i2cClkGPIO - 32; + } + + /* Initialize the GPIO pin for the i2c Data Register */ + if (i2cDataGPIO < 32) + { + g_i2cDataGPIOMuxReg = GPIO_MUX_LOW; + g_i2cDataGPIODataReg = GPIO_DATA_LOW; + g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION_LOW; + + /* Initialize the Data GPIO Offset */ + g_i2cDataGPIO = i2cDataGPIO; + } + else + { + g_i2cDataGPIOMuxReg = GPIO_MUX_HIGH; + g_i2cDataGPIODataReg = GPIO_DATA_HIGH; + g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION_HIGH; + + /* Initialize the Data GPIO Offset */ + g_i2cDataGPIO = i2cDataGPIO - 32; + } + + /* Enable the GPIO pins for the i2c Clock and Data (GPIO MUX) */ + pokeRegisterDWord(g_i2cClkGPIOMuxReg, + peekRegisterDWord(g_i2cClkGPIOMuxReg) & ~(1 << g_i2cClockGPIO)); + pokeRegisterDWord(g_i2cDataGPIOMuxReg, + peekRegisterDWord(g_i2cDataGPIOMuxReg) & ~(1 << g_i2cDataGPIO)); + + /* Enable GPIO power */ + gate = peekRegisterDWord(CURRENT_POWER_GATE); + gate = FIELD_SET(gate, CURRENT_POWER_GATE, GPIO_PWM_I2C, ENABLE); + ddk502_setCurrentGate(gate); + + /* Clear the i2c lines. */ + for(i=0; i<9; i++) + swI2CStop(); + + return 1; +} +/******************************************************************************* + ddk502_swI2CReadReg + This function reads the slave device's register + + Parameters: + deviceAddress - i2c Slave device address which register + to be read from + registerIndex - Slave device's register to be read + + Return Value: + Register value + *******************************************************************************/ +_X_EXPORT unsigned char ddk502_swI2CReadReg(unsigned char deviceAddress, unsigned char registerIndex) +{ + unsigned char data; + + /* Send the Start signal */ + swI2CStart(); + + /* Send the device address */ + swI2CWriteByte(deviceAddress); + + /* Send the register index */ + swI2CWriteByte(registerIndex); + + /* Get the bus again and get the data from the device read address */ + swI2CStart(); + swI2CWriteByte(deviceAddress + 1); + data = swI2CReadByte(1); + + /* Stop swI2C and release the bus */ + swI2CStop(); + + return data; +} + +/******************************************************************************* + swI2CWriteReg + This function write a value to the slave device's register + + Parameters: + deviceAddress - i2c Slave device address which register + to be written + registerIndex - Slave device's register to be written + data - Data to be written to the register + + Return Value: + 0 - Fail + 1 - Success + *******************************************************************************/ +unsigned char swI2CWriteReg(unsigned char deviceAddress, unsigned char registerIndex, unsigned char data) +{ + unsigned char bReturn = 0; + + /* Send the Start signal */ + swI2CStart(); + + /* Send the device address and read the data. All should return success + in order for the writing processed to be successful + */ + if (swI2CWriteByte(deviceAddress) && + swI2CWriteByte(registerIndex) && + swI2CWriteByte(data)) + { + bReturn = 1; + } + + /* Stop i2c and release the bus */ + swI2CStop(); + + return bReturn; +} +int __wait(void) +{ + int i=0,j=0; + while(i++<1000){ + j+=i; + } + return j; +} + +_X_EXPORT void ddk502_I2CPutBits_panel(I2CBusPtr bus,int clock,int data) +{ + swI2CSCL(clock); + swI2CSDA(data); + __wait(); +} + +_X_EXPORT void ddk502_I2CGetBits_panel(I2CBusPtr bus,int* clock,int* data) +{ + *data = swI2CReadSDA(); + *clock = swI2CReadSCL(); + __wait(); +} + +_X_EXPORT void ddk502_I2CPutBits_crt(I2CBusPtr bus,int clock,int data) +{ + swI2CSCL(clock); + swI2CSDA(data); + __wait(); +} + +_X_EXPORT void ddk502_I2CGetBits_crt(I2CBusPtr bus,int* clock,int* data) +{ + *data = swI2CReadSDA(); + *clock = swI2CReadSCL(); + __wait(); +} + diff --git a/src/ddk502/ddk502_swi2c.h b/src/ddk502/ddk502_swi2c.h new file mode 100644 index 0000000..e0864c4 --- /dev/null +++ b/src/ddk502/ddk502_swi2c.h @@ -0,0 +1,39 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* I2C.H --- Voyager GX SDK +* This file contains the definitions for SW I2C. +* +*******************************************************************/ +#ifndef _SWI2C_H_ +#define _SWI2C_H_ + +/* Default i2c CLK and Data GPIO. These are the default i2c pins */ +#define DEFAULT_I2C_SCL 46 +#define DEFAULT_I2C_SDA 47 + +_X_EXPORT unsigned char ddk502_swI2CInit( + unsigned char i2cClkGPIO, + unsigned char i2cDataGPIO +); + +_X_EXPORT unsigned char ddk502_swI2CReadReg( + unsigned char deviceAddress, + unsigned char registerIndex +); + +unsigned char swI2CWriteReg( + unsigned char deviceAddress, + unsigned char registerIndex, + unsigned char data +); +_X_EXPORT void ddk750_I2CPutBits_panel(I2CBusPtr bus,int clock,int data); +_X_EXPORT void ddk750_I2CGetBits_panel(I2CBusPtr bus,int* clock,int* data); +_X_EXPORT void ddk750_I2CPutBits_crt(I2CBusPtr bus,int clock,int data); +_X_EXPORT void ddk750_I2CGetBits_crt(I2CBusPtr bus,int* clock,int* data); + +#endif /* _SWI2C_H_ */ diff --git a/src/ddk502/ddk502_voyager.h b/src/ddk502/ddk502_voyager.h new file mode 100644 index 0000000..84b37db --- /dev/null +++ b/src/ddk502/ddk502_voyager.h @@ -0,0 +1,94 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* Voyager.h --- Voyager GX SDK +* This file contains the difinitions for the main SDK. +* +*******************************************************************/ +#ifndef _VOYAGER_H_ +#define _VOYAGER_H_ + +#include "ddk502_regsc.h" +#include "ddk502_regdma.h" +#include "ddk502_regdc.h" +#include "ddk502_regzv.h" +#if 0 +#include "ddk502_reggpio.h" +#include "ddk502_regpwm.h" +#include "ddk502_regssp.h" + + +#include "ddk502_regde.h" +#include "ddk502_reg8051.h" +#include "ddk502_reguart.h" + +#include "ddk502_regi2s.h" +#include "ddk502_regi2c.h" +#endif + +/* Internal macros */ +#define _F_START(f) (0 ? f) +#define _F_END(f) (1 ? f) +#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f)) +#define _F_MASK(f) (((1 << _F_SIZE(f)) - 1) << _F_START(f)) +#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f)) +#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f)) + +/* Global macros */ +#define FIELD_GET(x, reg, field) \ +( \ + _F_NORMALIZE((x), reg ## _ ## field) \ +) + +#define FIELD_SET(x, reg, field, value) \ +( \ + (x & ~_F_MASK(reg ## _ ## field)) \ + | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \ +) + +#define FIELD_VALUE(x, reg, field, value) \ +( \ + (x & ~_F_MASK(reg ## _ ## field)) \ + | _F_DENORMALIZE(value, reg ## _ ## field) \ +) + +#define FIELD_CLEAR(reg, field) \ +( \ + ~ _F_MASK(reg ## _ ## field) \ +) + +/* FIELD MACROS */ +#define FIELD_START(field) (0 ? field) +#define FIELD_END(field) (1 ? field) +#define FIELD_SIZE(field) (1 + FIELD_END(field) - FIELD_START(field)) +#define FIELD_MASK(field) (((1 << (FIELD_SIZE(field)-1)) | ((1 << (FIELD_SIZE(field)-1)) - 1)) << FIELD_START(field)) +#define FIELD_NORMALIZE(reg, field) (((reg) & FIELD_MASK(field)) >> FIELD_START(field)) +#define FIELD_DENORMALIZE(field, value) (((value) << FIELD_START(field)) & FIELD_MASK(field)) +#define FIELD_INIT(reg, field, value) FIELD_DENORMALIZE(reg ## _ ## field, \ + reg ## _ ## field ## _ ## value) +#define FIELD_INIT_VAL(reg, field, value) \ + (FIELD_DENORMALIZE(reg ## _ ## field, value)) +#define FIELD_VAL_SET(x, r, f, v) x = x & ~FIELD_MASK(r ## _ ## f) \ + | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) + +#define RGB(r, g, b) \ +( \ + (unsigned long) (((r) << 16) | ((g) << 8) | (b)) \ +) + +#define RGB16(r, g, b) \ +( \ + (unsigned short) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 0xF8) >> 3)) \ +) + +#if 1 + #define PITCH(width, bpp) (((width + 15) & ~15) * (bpp) / 8) +#else + #define PITCH(width, bpp) (((width) * (bpp) / 8 + 15) & ~15) +#endif + +#endif /* _VOYAGER_H_ */ diff --git a/src/ddk502/version.h b/src/ddk502/version.h new file mode 100644 index 0000000..c9ddb9c --- /dev/null +++ b/src/ddk502/version.h @@ -0,0 +1,25 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* VERSION.H --- SMI DDK +* This file contains the source code for the mode table. +* +*******************************************************************/ +#ifndef _VERSION_H_ +#define _VERSION_H_ + +#define LIBRARY_VERSION 0x00000006 +#define MAJOR_VERSION(v) (v >> 16) +#define MINOR_VERSION(v) (v & 0x0000ffff) +#if XORG_VERSION_CURRENT < 10706000 +uint32_t getLibVersion(void) +{ + return(LIBRARY_VERSION); +} +#endif +#endif /* _VERSION_H_ */ + diff --git a/src/ddk712/712ddk_module.c b/src/ddk712/712ddk_module.c new file mode 100644 index 0000000..d56a102 --- /dev/null +++ b/src/ddk712/712ddk_module.c @@ -0,0 +1,44 @@ +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86Module.h" +#if XORG_VERSION_CURRENT < 10706000 +#include "xf86Resources.h" +#endif +#include "./version.h" + +static MODULESETUPPROTO(smi712ddk_Setup); + +static XF86ModuleVersionInfo smi712ddkVersRec = + { + "smi712ddk", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + MAJOR_VERSION(LIBRARY_VERSION), + MINOR_VERSION(LIBRARY_VERSION), + 0, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_NONE, + { 0,0,0,0 } + }; + +_X_EXPORT XF86ModuleData smiddk712ModuleData = { + &smi712ddkVersRec, + smi712ddk_Setup, + NULL +}; + +static pointer +smi712ddk_Setup(pointer module, pointer opts, int *errmaj, int *errmin) { + return (pointer)1; +} + + diff --git a/src/ddk712/Makefile.am b/src/ddk712/Makefile.am new file mode 100644 index 0000000..9ab0d55 --- /dev/null +++ b/src/ddk712/Makefile.am @@ -0,0 +1,19 @@ +AM_CFLAGS = @XORG_CFLAGS@ +smiddk712_drv_la_LTLIBRARIES = smiddk712_drv.la +smiddk712_drv_la_LDFLAGS = -module -avoid-version -lpci +smiddk712_drv_ladir = @moduledir@/drivers + +smiddk712_drv_la_SOURCES = \ + ./ddk712.h \ + ./ddk712_chip.h \ + ./ddk712_help.h \ + ./ddk712_mode.h \ + ./ddk712_reg.h \ + ./ddk712_chip.c \ + ./ddk712_help.c \ + ./ddk712_mode.c \ + ./712ddk_module.c \ + ./version.h + + + diff --git a/src/ddk712/ddk712.h b/src/ddk712/ddk712.h new file mode 100644 index 0000000..3fabd75 --- /dev/null +++ b/src/ddk712/ddk712.h @@ -0,0 +1,20 @@ +#ifndef DDK712_H__ +#define DDK712_H__ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* RegSC.h --- SM718 SDK +* This file contains the definitions for the System Configuration registers. +* +*******************************************************************/ +#include "ddk712_reg.h" +#include "ddk712_mode.h" +#include "ddk712_chip.h" +//#include "ddk712_display.h" +#include "ddk712_help.h" + +#endif diff --git a/src/ddk712/ddk712_chip.c b/src/ddk712/ddk712_chip.c new file mode 100644 index 0000000..f6b6312 --- /dev/null +++ b/src/ddk712/ddk712_chip.c @@ -0,0 +1,163 @@ +#include "ddk712_chip.h" +#include "ddk712_help.h" +/* Absolute differece between two numbers */ +unsigned long absDiff(unsigned long a, unsigned long b) +{ + if ( a >= b ) + return(a - b); + else + return(b - a); +} + +/* MCLK X mdr = INPUT X mnr */ +unsigned int ddk712_calcPllValue(unsigned int clock,int* o_mnr,int* o_mdr) +{ + int mdr,mnr; + unsigned int mxm; + unsigned int request,input; + unsigned int quo,rem; + unsigned int miniDiff,diff0; + + miniDiff = ~0; + /* clocl diveded b 1000 to prevent from overflow exception */ + request = clock /1000; + input = DEFAULT_INPUT_CLOCK / 1000; + + for(mdr=1;mdr<64;mdr++){ + mxm = request * mdr; + quo = mxm / input; + rem = mxm % input; + if((rem * 100 / input) > 500) + quo++; + mnr = quo; + + if(mnr < 256){ + diff0 = absDiff(calcMCLK(mnr,mdr),clock); + if(diff0 < miniDiff) + { + *o_mnr = mnr; + *o_mdr = mdr; + } + } + } + + return calcMCLK(*o_mnr,*o_mdr); +} + +_X_EXPORT void ddk712_hw_init(init_parm_712 * param) +{ + int mnr,mdr; + mnr = mdr = 1; + + /* for sm712 pci burst enabling + * either: + * open both burst write and read + * or + * open burst write and disable burst read + * nothing else + * */ + if(param->pci_burst == 2){ + /* burst write on and read off*/ + poke_scr(0x17,peek_scr(0x17)|0x20); + poke_scr(0x15,peek_scr(0x15)&~0x80); + }else if(param->pci_burst == 3){ + /* both burst read and write on*/ + poke_scr(0x17, peek_scr(0x17)|0x20); + poke_scr(0x15, peek_scr(0x15)|0x80); + }else{ + /* no pci burst */ + poke_scr(0x17,peek_scr(0x17) & ~0x20); + } + + /* use 3dx for crtc IO */ + poke8_io(0x3c2,peek8_io(0x3cc)|1); + + /* if memClock is 0,than use BIOS setting */ + if(param->memClock > 0){ + /* get approprite mnr,mdr for memory clock */ + ddk712_calcPllValue(param->memClock,&mnr,&mdr); + poke_ccr(0x6a,mnr&0xff); + poke_ccr(0x6b,mdr&0xff); + } + + if(param->devid == 0x720){ + /* for sm722,always set pdr21 bit 5 to 0*/ + poke_pdr(0x21,peek_pdr(0x21)&~0x20); + } + + /* Disable LCD framebuffer r/w operation */ + /* enable VPR power gate,VPR is used in frame buffer driver + * enable CPR power gate,and DPR power gate + * */ + poke_pdr(0x21,(peek_pdr(0x21)|0xB0)); + poke_pdr(0x21,(peek_pdr(0x21)|0x30)&0xf8); + /* if (pSmi->lcd == 2) // Panel is DSTN + mode->SR21 = 0x00;*/ + + /* Enable DAC defaultly */ + poke_pdr(0x21,peek_pdr(0x21)&0x7f); + + /* Select no displays */ + poke_pdr(0x31,(peek_pdr(0x31)&~0x07)); + + /* Disable virtual refresh */ + poke_pdr(0x31,(peek_pdr(0x31)&~0x80)); + + /* power down mode is standby mode, VCLK and MCLK divided by 4*/ + poke_pdr(0x20,(peek_pdr(0x20) & ~0xb0)|0x10); + + /* Disable horizontal expansion and auto centering */ + poke_fpr(0x32,peek_fpr(0x32)&~3); + + /* Disable verticle expansion/vertical centering/horizontal centering */ + poke_crt(0x9e,peek_crt(0x9e) & ~7); + poke_crt(0x17, peek_crt(0x17) | 0x80); + + /* use vclk1 */ + poke_ccr(0x68,0x54); + + /* Disable panel video */ + poke_fpr(0xa0,0); + poke_ccr(0x33,0); + poke_ccr(0x3a,0); + + /* memory control regsiter */ + poke_mcr(0x60,1); + + /* below mcr register should be set by BIOS/GPIO pin */ +#if 1 + /* memory bank set */ + poke_mcr(0x61,0); + + /* mcr6 should be set by onboard GPIO pin,but for internal memory 720 + * only ff is workable,while 0x3e for sm712 + * */ + if(param->devid == 0x720) + poke_mcr(0x62,0xff); + else + poke_mcr(0x62,0x3e); + + /* MCR 63 is not claimed on datasheet,but experiment shows that sm712 need it be 0x1a + * for stable timing */ + poke_mcr(0x63,0x1a); + +#endif + + if(param->lcd != LCD712_USE_JUMP){ + poke_fpr(0x30,(peek_fpr(0x30)&0xfe)|param->lcd); + /* set other related registers*/ + } + + if(param->lcd_color.tftColor != TFT_USE_JUMP){ +// printk("monk:param->lcd_color.tftColor = %d\n",param->lcd_color.tftColor); + poke_fpr(0x30,(peek_fpr(0x30)&0x8f)|(param->lcd_color.tftColor<<4)); +// printk("monk peek scr 0x30 = %02x\n",peek_fpr(0x30)); + /* set other related registers*/ + } + + if(param->lcd_color.dstnColor != DSTN_USE_JUMP){ + poke_fpr(0x30,(peek_fpr(0x30)&0x7f)|(param->lcd_color.dstnColor <<7)); + /* set other related registers*/ + } +} + diff --git a/src/ddk712/ddk712_chip.h b/src/ddk712/ddk712_chip.h new file mode 100644 index 0000000..00d6b3f --- /dev/null +++ b/src/ddk712/ddk712_chip.h @@ -0,0 +1,52 @@ +#ifndef DDK712_CHIP_H__ +#define DDK712_CHIP_H__ +#define DEFAULT_INPUT_CLOCK 14318181 /* Default reference clock */ + +enum LCD_TYPE{ + LCD712_USE_JUMP = -1, + LCD712_DSTN = 1, + LCD712_TFT = 0, +}; + +enum TFT_COLOR{ + TFT_USE_JUMP = -1, + TFT_9BIT = 0, + TFT_12BIT = 1, + TFT_18BIT = 2, + TFT_24BIT = 3, + TFT_12P12 = 4, + TFT_ANALOG = 5, + TFT_18P18 = 6, +}; + +enum DSTN_COLOR{ + DSTN_USE_JUMP = -1, + DSTN_16BIT = 0, + DSTN_24BIT = 1, +}; + +typedef struct _init_parm_712{ + int devid;/* sm712 sm722*/ + unsigned int memClock; + /* pci burst read,write enable bit*/ + int pci_burst;/* bit 0 stand for read and 1 for write*/ + /* lcd settings*/ + enum LCD_TYPE lcd; + struct { + enum TFT_COLOR tftColor; + enum DSTN_COLOR dstnColor; + }lcd_color; +}init_parm_712; + +static inline unsigned int calcMCLK(int mnr,int mdr) +{ + /* don't worry about overlflow + * 14.318181 mhz * 255 == 3.4 G */ + return DEFAULT_INPUT_CLOCK * mnr / mdr; +} + + +unsigned int ddk712_calcPllValue(unsigned int,int*,int*); +void ddk712_hw_init(init_parm_712*); + +#endif diff --git a/src/ddk712/ddk712_help.c b/src/ddk712/ddk712_help.c new file mode 100644 index 0000000..b7ce042 --- /dev/null +++ b/src/ddk712/ddk712_help.c @@ -0,0 +1,29 @@ +#include "ddk712_help.h" + +volatile unsigned char * mmio712 = NULL; +/* below offset used for sm712/sm722 */ +int io_offset712; +/* DPR and VPR memory mapped registers,treated as 32bit access */ +int dpr_offset712; +int vpr_offset712; +int dataPort_offset712; + +/* after driver mapped io registers, use this function first */ +_X_EXPORT void ddk712_set_mmio(volatile unsigned char * addr,int devid) +{ + mmio712 = addr; + if(devid == 0x712){ + /* sm712 register offset stuffs */ + io_offset712 = MB(3); + dpr_offset712 = KB(32); + vpr_offset712 = KB(48); + dataPort_offset712 = MB(1); + }else if(devid == 0x720){ + /* sm722 register offset stuffs */ + io_offset712 = KB(768); + dpr_offset712 = KB(0); + vpr_offset712 = KB(2); + dataPort_offset712 = MB(1); + } +} + diff --git a/src/ddk712/ddk712_help.h b/src/ddk712/ddk712_help.h new file mode 100644 index 0000000..fdc2884 --- /dev/null +++ b/src/ddk712/ddk712_help.h @@ -0,0 +1,100 @@ +#ifndef DDK712_HELP_H__ +#define DDK712_HELP_H__ +#include "../smi_common.h" +#include "ddk712_chip.h" +#include "compiler.h" +#ifndef USE_INTERNAL_REGISTER_ACCESS + + + +/* mmio712 start from framebuffer + 4mega bytes */ +extern volatile unsigned char * mmio712 ; +extern int io_offset712; +/* DPR and VPR memory mapped registers,treated as 32bit access */ +extern int dpr_offset712; +extern int vpr_offset712; +extern int dataPort_offset712; + +#define peek32(addr) MMIO_IN32(mmio712,addr) +#define poke32(addr,data) MMIO_OUT32(mmio712,(addr),(data)) + +#define peek8(addr) MMIO_IN8(mmio712,addr) +#define poke8(addr,data) MMIO_OUT8(mmio712,(addr),(data)) + +#define peek8_io(addr) peek8(addr+io_offset712) +#define poke8_io(addr,data) poke8(addr+io_offset712,data) + +static inline char peek_scr(int idx) +{ + poke8_io(0x3c4,idx); + return peek8_io(0x3c5); +} + +static inline void poke_scr(int idx,char val) +{ + poke8_io(0x3c4,idx); + poke8_io(0x3c5,val); +} + +static inline char peek_crt(int idx) +{ + poke8_io(0x3d4,idx); + return peek8_io(0x3d5); +} + +static inline void poke_crt(int idx,char val) +{ + poke8_io(0x3d4,idx); + poke8_io(0x3d5,val); +} + +/* below registers equal to sequence registers */ +#define peek_pdr(a) peek_scr(a) +#define peek_fpr(a) peek_scr(a) +#define peek_mcr(a) peek_scr(a) +#define peek_ccr(a) peek_scr(a) +#define peek_gpr(a) peek_scr(a) +#define peek_phr(a) peek_scr(a) +#define peek_pop(a) peek_scr(a) +#define peek_hcr(a) peek_scr(a) + +#define poke_pdr(a,b) poke_scr(a,b) +#define poke_fpr(a,b) poke_scr(a,b) +#define poke_mcr(a,b) poke_scr(a,b) +#define poke_ccr(a,b) poke_scr(a,b) +#define poke_gpr(a,b) poke_scr(a,b) +#define poke_phr(a,b) poke_scr(a,b) +#define poke_pop(a,b) poke_scr(a,b) +#define poke_hcr(a,b) poke_scr(a,b) + +/* below registers equal to crtc registers*/ +#define peek_svr(a) peek_crt(a) +#define poke_svr(a,b) poke_crt(a,b) + + +static inline unsigned int peek32_dpr(int index) +{ + return peek32(index + dpr_offset712); +} + +static inline void poke32_dpr(int index,unsigned int val) +{ + poke32(index + dpr_offset712,val); +} + +static inline unsigned int peek32_vpr(int index) +{ + return peek32(index + vpr_offset712); +} + +static inline void poke32_vpr(int index,unsigned int val) +{ + poke32(index + vpr_offset712,val); +} +#else +/* implement if you want use it*/ +#endif + +_X_EXPORT void ddk712_set_mmio(volatile unsigned char * addr,int devid); + +#endif diff --git a/src/ddk712/ddk712_mode.c b/src/ddk712/ddk712_mode.c new file mode 100644 index 0000000..fbc19bd --- /dev/null +++ b/src/ddk712/ddk712_mode.c @@ -0,0 +1,260 @@ +#include "ddk712_mode.h" +#include "ddk712_help.h" +#include "ddk712_reg.h" + +const SM712CrtTiming sm712_crt_modedb[] = { +/* 640x480 */ +{ + 640,480,60, + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, 0x07, 0x82, +}, +{ + 640,480,75, + 0x64, 0x4F, 0x00, 0x52, 0x1A, 0xF2, 0xDF, 0x00, + 0xE0, 0x03, 0x0F, 0xC0, 0x4F, 0xDF, 0x16, 0x85, +}, +{ + 640,480,85, + 0x63, 0x4F, 0x00, 0x57, 0x1E, 0xFB, 0xDF, 0x00, + 0xE0, 0x03, 0x0F, 0xC0, 0x4F, 0xDF, 0x88, 0x9B, +}, +/* 800x480 */ +{ + 800,480,60, + 0x6B, 0x63, 0x00, 0x69, 0x1B, 0xF2, 0xDF, 0x00, + 0xE2, 0xE4, 0x1F, 0xC0, 0x63, 0xDF, 0x2C, 0x17, +}, +{ + 800,480,75, + 0x6B, 0x63, 0x00, 0x69, 0x1B, 0xF2, 0xDF, 0x00, + 0xE2, 0xE4, 0x1F, 0xC0, 0x63, 0xDF, 0x2C, 0x17, +}, +{ + 800,480,85, + 0x6B, 0x63, 0x00, 0x69, 0x1B, 0xF2, 0xDF, 0x00, + 0xE2, 0xE4, 0x1F, 0xC0, 0x63, 0xDF, 0x2C, 0x17, +}, +/* 800x600 */ +{ + 800,600,60, + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, 0x1C, 0x85, +}, +{ + 800,600,75, + 0x7F, 0x63, 0x00, 0x66, 0x10, 0x6F, 0x57, 0x00, + 0x58, 0x0B, 0xE0, 0x20, 0x63, 0x57, 0x4C, 0x8B, +}, +{ + 800,600,85, + 0x7E, 0x63, 0x00, 0x68, 0x10, 0x75, 0x57, 0x00, + 0x58, 0x0B, 0xE0, 0x20, 0x63, 0x57, 0x37, 0x87, +}, +#if 0 +/* 1024x600 */ +{ + 1024,600,60, + 0xA3, 0x7F, 0x00, 0x82, 0x0B, 0x6F, 0x57, 0x00, + 0x5C, 0x0F, 0xE0, 0xE0, 0x7F, 0x57, 0x16, 0x07, +}, +#endif +/* 1024x768 */ + +{ + 1024,768,60, + 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, + 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, 0x52, 0x89, +}, +{ + 1024,768,75, + 0x9F, 0x7F, 0x00, 0x82, 0x0E, 0x1E, 0xFF, 0x00, + 0x00, 0x03, 0xE5, 0x20, 0x7F, 0xFF, 0x0B, 0x02, +}, +{ + 1024,768,85, + 0xA7, 0x7F, 0x00, 0x86, 0x12, 0x26, 0xFF, 0x00, + 0x00, 0x03, 0xE5, 0x20, 0x7F, 0xFF, 0x70, 0x11, +}, + +/* 1280x1024 */ +{ + 1280,1024,60, + 0xCE, 0x9F, 0x00, 0xA7, 0x15, 0x28, 0xFF, 0x00, + 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x53, 0x0B, +}, +{ + 1280,1024,75, + 0xCE, 0x9F, 0x00, 0xA2, 0x14, 0x28, 0xFF, 0x00, +// 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x13, 0x02, + 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x42, 0x07, +}, +{ + 1280,1024,85, + 0xD3, 0x9F, 0x00, 0xA8, 0x1C, 0x2E, 0xFF, 0x00, +// 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x16, 0x42, + 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x0b, 0x01, +}, + +}; + +const SM712PnlTiming sm712_pnl_modedb[] = { +#if 0 +{ + + 640,480,60, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0C, 0xDF, 0xE9, + 0x00, 0x03, 0x59, 0x00, 0x4F, 0xDF, 0x03, 0x02, +}, + +{ + 640,480,75, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0C, 0xDF, 0xE9, + 0x00, 0x03, 0x59, 0xC0, 0x4F, 0xDF, 0x16, 0x85, +}, +{ + 640,480,85, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0C, 0xDF, 0xE9, + 0x00, 0x03, 0x59, 0xC0, 0x4F, 0xDF, 0x88, 0x9B, +}, +#endif +{ + 800,480,60, + 0x02, 0x24, 0x7B, 0x63, 0x67, 0xF3, 0xDF, 0xE2, + 0x00, 0x03, 0x41, 0xC0, 0x63, 0xDF, 0x2C, 0x17, +}, +#if 0 +{ + 800,480,75, + 0x6B, 0x63, 0x00, 0x69, 0x1B, 0xF2, 0xDF, 0x00, + 0xE2, 0xE4, 0x1F, 0xC0, 0x63, 0xDF, 0x2C, 0x17, +}, +{ + 800,480,85, + 0x6B, 0x63, 0x00, 0x69, 0x1B, 0xF2, 0xDF, 0x00, + 0xE2, 0xE4, 0x1F, 0xC0, 0x63, 0xDF, 0x2C, 0x17, +}, +#endif +{ + 800,600,60, + 0x04, 0x48, 0x83, 0x63, 0x69, 0x73, 0x57, 0x58, + 0x00, 0x03, 0x7B, 0x20, 0x63, 0x57, 0x0E, 0x05, +}, +#if 0 +{ + 800,600,75, + 0x7F, 0x63, 0x00, 0x66, 0x10, 0x6F, 0x57, 0x00, + 0x58, 0x0B, 0xE0, 0x20, 0x63, 0x57, 0x4C, 0x8B, +}, +{ + 800,600,85, + 0x7E, 0x63, 0x00, 0x68, 0x10, 0x75, 0x57, 0x00, + 0x58, 0x0B, 0xE0, 0x20, 0x63, 0x57, 0x37, 0x87, +}, +#endif +#if 0 +{ + 1024,600,60, + 0x04, 0x48, 0x95, 0x7F, 0x86, 0x70, 0x57, 0x5B, + 0x00, 0x60, 0x1c, 0x22, 0x7F, 0x57, 0x16, 0x07, +}, +#endif +{ + 1024,768,60, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x25, 0xFF, 0x02, + 0x00, 0x62, 0x85, 0x20, 0x7F, 0xFF, 0x29, 0x09, +}, +#if 0 +{ + 1024,768,75, + 0x9F, 0x7F, 0x00, 0x82, 0x0E, 0x1E, 0xFF, 0x00, + 0x00, 0x03, 0xE5, 0x20, 0x7F, 0xFF, 0x0B, 0x02, +}, +{ + 1024,768,85, + 0xA7, 0x7F, 0x00, 0x86, 0x12, 0x26, 0xFF, 0x00, + 0x00, 0x03, 0xE5, 0x20, 0x7F, 0xFF, 0x70, 0x11, +}, +#endif +{ + 1280,1024,60, + 0x08, 0x8C, 0xD5, 0x9F, 0xAB, 0x26, 0xFF, 0x00, + 0x00, 0x03, 0x7E, 0x20, 0x9F, 0xFF, 0x53, 0x0B, +}, +#if 0 +{ + 1280,1024,75, + 0xCE, 0x9F, 0x00, 0xA2, 0x14, 0x28, 0xFF, 0x00, + 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x42, 0x07, +}, +{ + 1280,1024,85, + 0xD3, 0x9F, 0x00, 0xA8, 0x1C, 0x2E, 0xFF, 0x00, + 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x0b, 0x01, +}, +#endif +}; + +#define CNT_CRT sizeof(sm712_crt_modedb)/sizeof(sm712_crt_modedb[0]) +#define CNT_PNL sizeof(sm712_pnl_modedb)/sizeof(sm712_pnl_modedb[0]) + +_X_EXPORT void ddk712_setModeTiming(int channel,int x,int y,int hz) +{ + int i; + int index; + index = 0; + if(channel == 0){ + while(index < CNT_CRT){ + if(sm712_crt_modedb[index].h_res == x && + sm712_crt_modedb[index].v_res == y && + sm712_crt_modedb[index].vsync == hz) + break; + index++; + } + if(index == CNT_CRT){ + /* no mode found in table */ + return; + } + + /* program svr */ + for(i=0;i<14;i++){ + poke_svr(0x40+i,sm712_crt_modedb[index].svr[i]); + } + + /* work around crt */ + if(y>=1024){ + poke_crt(0x30,peek_crt(0x30)|9); + }else{ + poke_crt(0x30,peek_crt(0x30)&~9); + } + + /* programe ccr for pixel clock */ + poke_ccr(0x6c,sm712_crt_modedb[index].ccr[0]); + poke_ccr(0x6d,sm712_crt_modedb[index].ccr[1]); + + }else{ + while(index < CNT_PNL){ + if(sm712_pnl_modedb[index].h_res == x && + sm712_pnl_modedb[index].v_res == y && + sm712_pnl_modedb[index].vsync == hz) + break; + index++; + } + if(index == CNT_PNL){ + return; + } + + /* program FPR */ + for(i=0;i<8;i++){ + poke_fpr(0x50+i,sm712_pnl_modedb[index].fpr[i]); + } + + /* program fpr5a*/ + poke_fpr(0x5a,sm712_pnl_modedb[index].fpr[0xa]); + + /* program ccr for pixel clock*/ + poke_ccr(0x6e,sm712_pnl_modedb[index].ccr[0]); + poke_ccr(0x6f,sm712_pnl_modedb[index].ccr[1]); + + } +} diff --git a/src/ddk712/ddk712_mode.h b/src/ddk712/ddk712_mode.h new file mode 100644 index 0000000..b2db43e --- /dev/null +++ b/src/ddk712/ddk712_mode.h @@ -0,0 +1,22 @@ +#ifndef DDK712_MODE_H__ +#define DDK712_MODE_H__ + +typedef struct{ + unsigned short h_res; + unsigned short v_res; + char vsync; + char svr[14];/* shadow vga register :svr 40 => svr 4d*/ + char ccr[2];/* pixel pll:ccr6c,6d */ +}SM712CrtTiming; + +typedef struct{ + unsigned short h_res; + unsigned short v_res; + char vsync; + char fpr[14];/* fpr50 ==> fpr57,fpr5a*/ + char ccr[2];/* ccr6e.ccr6f*/ +}SM712PnlTiming; + + +void ddk712_setModeTiming(int channel,int x,int y,int hz); +#endif diff --git a/src/ddk712/ddk712_reg.h b/src/ddk712/ddk712_reg.h new file mode 100644 index 0000000..2c513c2 --- /dev/null +++ b/src/ddk712/ddk712_reg.h @@ -0,0 +1,14 @@ +#ifndef DDK712_REG_H__ +#define DDK712_REG_H__ + +#define MISC_GRAPH_VIDEO_CTRL 0 +#define MISC_GRAPH_VIDEO_CTRL_DATA_FORMAT 18:16 +#define MISC_GRAPH_VIDEO_CTRL_DATA_FORMAT_8 0 +#define MISC_GRAPH_VIDEO_CTRL_DATA_FORMAT_15 1 +#define MISC_GRAPH_VIDEO_CTRL_DATA_FORMAT_16 2 +#define MISC_GRAPH_VIDEO_CTRL_DATA_FORMAT_32 3 +#define MISC_GRAPH_VIDEO_CTRL_DATA_FORMAT_24 4 +#define MISC_GRAPH_VIDEO_CTRL_DATA_FORMAT_8P 5 + + +#endif diff --git a/src/ddk712/version.h b/src/ddk712/version.h new file mode 100644 index 0000000..c9ddb9c --- /dev/null +++ b/src/ddk712/version.h @@ -0,0 +1,25 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* VERSION.H --- SMI DDK +* This file contains the source code for the mode table. +* +*******************************************************************/ +#ifndef _VERSION_H_ +#define _VERSION_H_ + +#define LIBRARY_VERSION 0x00000006 +#define MAJOR_VERSION(v) (v >> 16) +#define MINOR_VERSION(v) (v & 0x0000ffff) +#if XORG_VERSION_CURRENT < 10706000 +uint32_t getLibVersion(void) +{ + return(LIBRARY_VERSION); +} +#endif +#endif /* _VERSION_H_ */ + diff --git a/src/ddk750/750ddk_module.c b/src/ddk750/750ddk_module.c new file mode 100644 index 0000000..7bd37f5 --- /dev/null +++ b/src/ddk750/750ddk_module.c @@ -0,0 +1,43 @@ +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86Module.h" +#if XORG_VERSION_CURRENT < 10706000 +#include "xf86Resources.h" +#endif +#include "./version.h" + +static MODULESETUPPROTO(smi750ddk_Setup); + +static XF86ModuleVersionInfo smi750ddkVersRec = + { + "smi750ddk", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + MAJOR_VERSION(LIBRARY_VERSION), + MINOR_VERSION(LIBRARY_VERSION), + 0, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_NONE, + { 0,0,0,0 } + }; + +_X_EXPORT XF86ModuleData smiddk750ModuleData = { + &smi750ddkVersRec, + smi750ddk_Setup, + NULL +}; + +static pointer +smi750ddk_Setup(pointer module, pointer opts, int *errmaj, int *errmin) { + return (pointer)1; +} + diff --git a/src/ddk750/Makefile.am b/src/ddk750/Makefile.am new file mode 100644 index 0000000..3c096e3 --- /dev/null +++ b/src/ddk750/Makefile.am @@ -0,0 +1,32 @@ +AM_CFLAGS = @XORG_CFLAGS@ +smiddk750_drv_la_LTLIBRARIES = smiddk750_drv.la +smiddk750_drv_la_LDFLAGS = -module -avoid-version +smiddk750_drv_ladir = @moduledir@/drivers + +smiddk750_drv_la_SOURCES = \ + ./ddk750.h \ + ./750ddk_module.c \ + ./ddk750_chip.h \ + ./version.h \ + ./ddk750_display.h \ + ./ddk750_dvi.h \ + ./ddk750_help.h \ + ./ddk750_hwi2c.h \ + ./ddk750_mode.h \ + ./ddk750_power.h \ + ./ddk750_reg.h \ + ./ddk750_sii164.h \ + ./ddk750_swi2c.h \ + ./ddk750_edid.h \ + ./ddk750_chip.c \ + ./ddk750_display.c \ + ./ddk750_dvi.c \ + ./ddk750_help.c \ + ./ddk750_hwi2c.c \ + ./ddk750_mode.c \ + ./ddk750_power.c \ + ./ddk750_sii164.c \ + ./ddk750_swi2c.c \ + ./ddk750_edid.c + + diff --git a/src/ddk750/ddk750.h b/src/ddk750/ddk750.h new file mode 100644 index 0000000..04ea14d --- /dev/null +++ b/src/ddk750/ddk750.h @@ -0,0 +1,24 @@ +#ifndef DDK750_H__ +#define DDK750_H__ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* RegSC.h --- SM718 SDK +* This file contains the definitions for the System Configuration registers. +* +*******************************************************************/ +#include "ddk750_reg.h" +#include "ddk750_mode.h" +#include "ddk750_chip.h" +#include "ddk750_display.h" +#include "ddk750_power.h" +#include "ddk750_help.h" +#ifdef USE_HW_I2C +#include "ddk750_hwi2c.h" +#endif +#include "ddk750_swi2c.h" +#endif diff --git a/src/ddk750/ddk750_chip.c b/src/ddk750/ddk750_chip.c new file mode 100644 index 0000000..d08de87 --- /dev/null +++ b/src/ddk750/ddk750_chip.c @@ -0,0 +1,657 @@ +#include "../smi_common.h" +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_chip.h" +#include "ddk750_power.h" +typedef struct _pllcalparam{ + unsigned char power;/* d : 0~ 6*/ + unsigned char pod; + unsigned char od; + unsigned char value;/* value of 2 power d (2^d) */ +} +pllcalparam; +/* Perform a rounded division. */ +long roundedDiv(long num, long denom) +{ + /* n / d + 1 / 2 = (2n + d) / 2d */ + return (2 * num + denom) / (2 * denom); +} + +/* Absolute differece between two numbers */ +unsigned long absDiff(unsigned long a, unsigned long b) +{ + if ( a >= b ) + return(a - b); + else + return(b - a); +} + +extern unsigned long revId750; +extern unsigned short devId750; + +logical_chip_type_t getChipType() +{ + unsigned short physicalID; + unsigned long physicalRev; + logical_chip_type_t chip; + + physicalID = devId750;//either 0x718 or 0x750 + physicalRev = revId750; + + if (physicalID == 0x718) + { + chip = SM718; + } + else if (physicalID == 0x750) + { + chip = SM750; + /* SM750 and SM750LE are different in their revision ID only. */ + if (physicalRev == SM750LE_REVISION_ID){ + chip = SM750LE; + } + } + else + { + chip = SM_UNKNOWN; + } + + return chip; +} + + +unsigned int twoToPowerOfx(unsigned long x) +{ + unsigned long i; + unsigned long result = 1; + + for (i=1; i<=x; i++) + result *= 2; + return result; +} + +unsigned int calcPLL(pll_value_t *pPLL) +{ + return (pPLL->inputFreq * pPLL->M / pPLL->N / twoToPowerOfx(pPLL->OD) / twoToPowerOfx(pPLL->POD)); +} + +unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL) +{ + unsigned int ulPllReg = 0; + + pPLL->inputFreq = DEFAULT_INPUT_CLOCK; + pPLL->clockType = clockType; + + switch (clockType) + { + case MXCLK_PLL: + ulPllReg = PEEK32(MXCLK_PLL_CTRL); + break; + case PRIMARY_PLL: + ulPllReg = PEEK32(PANEL_PLL_CTRL); + break; + case SECONDARY_PLL: + ulPllReg = PEEK32(CRT_PLL_CTRL); + break; + case VGA0_PLL: + ulPllReg = PEEK32(VGA_PLL0_CTRL); + break; + case VGA1_PLL: + ulPllReg = PEEK32(VGA_PLL1_CTRL); + break; + } + + pPLL->M = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, M); + pPLL->N = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, N); + pPLL->OD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, OD); + pPLL->POD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, POD); + + return calcPLL(pPLL); +} + + +unsigned int getChipClock() +{ + pll_value_t pll; +#if 1 + if(getChipType() == SM750LE) + return MHz(130); +#endif + + return getPllValue(MXCLK_PLL, &pll); +} + + +/* + * This function set up the main chip clock. + * + * Input: Frequency to be set. + */ +void setChipClock(unsigned int frequency) +{ + pll_value_t pll; + unsigned int ulActualMxClk; +#if 1 + /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */ + if (getChipType() == SM750LE) + return; +#endif + + if (frequency != 0) + { + /* + * Set up PLL, a structure to hold the value to be set in clocks. + */ + pll.inputFreq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */ + pll.clockType = MXCLK_PLL; + + /* + * Call calcPllValue() to fill up the other fields for PLL structure. + * Sometime, the chip cannot set up the exact clock required by User. + * Return value from calcPllValue() gives the actual possible clock. + */ + ulActualMxClk = calcPllValue(frequency, &pll); + + /* Master Clock Control: MXCLK_PLL */ + POKE32(MXCLK_PLL_CTRL, formatPllReg(&pll)); + } +} + + + +void setMemoryClock(unsigned int frequency) +{ + unsigned int ulReg, divisor; + #if 1 + /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */ + if (getChipType() == SM750LE) + return; +#endif + if (frequency != 0) + { + /* Set the frequency to the maximum frequency that the DDR Memory can take + which is 336MHz. */ + if (frequency > MHz(336)) + frequency = MHz(336); + + /* Calculate the divisor */ + divisor = (unsigned int) roundedDiv(getChipClock(), frequency); + + /* Set the corresponding divisor in the register. */ + ulReg = PEEK32(CURRENT_GATE); + switch(divisor) + { + default: + case 1: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, 336MHZ); + break; + case 2: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, 168MHZ); + break; + case 3: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, 112MHZ); + break; + case 4: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, M2XCLK, 84MHZ); + break; + } + + setCurrentGate(ulReg); + } +} + + +/* + * This function set up the master clock (MCLK). + * + * Input: Frequency to be set. + * + * NOTE: + * The maximum frequency the engine can run is 168MHz. + */ +void setMasterClock(unsigned int frequency) +{ + unsigned int ulReg, divisor; + #if 1 + /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */ + if (getChipType() == SM750LE) + return; +#endif + if (frequency != 0) + { + /* Set the frequency to the maximum frequency that the SM750 engine can + run, which is about 190 MHz. */ + if (frequency > MHz(190)) + frequency = MHz(190); + + /* Calculate the divisor */ + divisor = (unsigned int) roundedDiv(getChipClock(), frequency); + + /* Set the corresponding divisor in the register. */ + ulReg = PEEK32(CURRENT_GATE); + switch(divisor) + { + default: + case 3: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, 112MHZ); + break; + case 4: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, 84MHZ); + break; + case 6: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, 56MHZ); + break; + case 8: + ulReg = FIELD_SET(ulReg, CURRENT_GATE, MCLK, 42MHZ); + break; + } + + setCurrentGate(ulReg); + } +} + + +_X_EXPORT unsigned int ddk750_getVMSize() +{ + unsigned int reg; + unsigned int data; + + /* sm750le only use 64 mb memory*/ + if(getChipType() == SM750LE) + return MB(64); + + /* for 750,always use power mode0*/ + reg = PEEK32(MODE0_GATE); + reg = FIELD_SET(reg,MODE0_GATE,GPIO,ON); + POKE32(MODE0_GATE,reg); + + /* get frame buffer size from GPIO */ + reg = FIELD_GET(PEEK32(MISC_CTRL),MISC_CTRL,LOCALMEM_SIZE); + switch(reg){ + case MISC_CTRL_LOCALMEM_SIZE_8M: data = MB(8); break; /* 8 Mega byte */ + case MISC_CTRL_LOCALMEM_SIZE_16M: data = MB(16); break; /* 16 Mega byte */ + case MISC_CTRL_LOCALMEM_SIZE_32M: data = MB(32); break; /* 32 Mega byte */ + case MISC_CTRL_LOCALMEM_SIZE_64M: data = MB(64); break; /* 64 Mega byte */ + default: data = 0;break; + } + return data; + +} + +_X_EXPORT int ddk750_initHw(initchip_param_t * pInitParam) +{ + + unsigned int ulReg; +#if 0 + //move the code to map regiter function. + if(getChipType() == SM718){ + /* turn on big endian bit*/ + ulReg = PEEK32(0x74); + /* now consider register definition in a big endian pattern*/ + POKE32(0x74,ulReg|0x80000000); + } + +#endif + + + if (pInitParam->powerMode != 0 ) + pInitParam->powerMode = 0; + setPowerMode(pInitParam->powerMode); + + /* Enable display power gate & LOCALMEM power gate*/ + ulReg = PEEK32(CURRENT_GATE); + ulReg = FIELD_SET(ulReg, CURRENT_GATE, DISPLAY, ON); + ulReg = FIELD_SET(ulReg,CURRENT_GATE,LOCALMEM,ON); + setCurrentGate(ulReg); + + if(getChipType() != SM750LE){ + /* set panel pll and graphic mode via mmio_88 */ + ulReg = PEEK32(VGA_CONFIGURATION); + ulReg = FIELD_SET(ulReg,VGA_CONFIGURATION,PLL,PANEL); + ulReg = FIELD_SET(ulReg,VGA_CONFIGURATION,MODE,GRAPHIC); + POKE32(VGA_CONFIGURATION,ulReg); + }else{ +#if defined(__i386__) || defined( __x86_64__) + /* set graphic mode via IO method */ + outb_p(0x88,0x3d4); + outb_p(0x06,0x3d5); +#endif + } + + /* Set the Main Chip Clock */ + setChipClock(MHz((unsigned int)pInitParam->chipClock)); + + /* Set up memory clock. */ + setMemoryClock(MHz(pInitParam->memClock)); + + /* Set up master clock */ + setMasterClock(MHz(pInitParam->masterClock)); + + + /* Reset the memory controller. If the memory controller is not reset in SM750, + the system might hang when sw accesses the memory. + The memory should be resetted after changing the MXCLK. + */ + if (pInitParam->resetMemory == 1) + { + ulReg = PEEK32(MISC_CTRL); + ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, RESET); + POKE32(MISC_CTRL, ulReg); + + ulReg = FIELD_SET(ulReg, MISC_CTRL, LOCALMEM_RESET, NORMAL); + POKE32(MISC_CTRL, ulReg); + } + + if (pInitParam->setAllEngOff == 1) + { + enable2DEngine(0); + + /* Disable Overlay, if a former application left it on */ + ulReg = PEEK32(VIDEO_DISPLAY_CTRL); + ulReg = FIELD_SET(ulReg, VIDEO_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(VIDEO_DISPLAY_CTRL, ulReg); + + /* Disable video alpha, if a former application left it on */ + ulReg = PEEK32(VIDEO_ALPHA_DISPLAY_CTRL); + ulReg = FIELD_SET(ulReg, VIDEO_ALPHA_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(VIDEO_ALPHA_DISPLAY_CTRL, ulReg); + + /* Disable alpha plane, if a former application left it on */ + ulReg = PEEK32(ALPHA_DISPLAY_CTRL); + ulReg = FIELD_SET(ulReg, ALPHA_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(ALPHA_DISPLAY_CTRL, ulReg); + +#if 0 + /* Disable LCD hardware cursor, if a former application left it on */ + ulReg = PEEK32(PANEL_HWC_ADDRESS); + ulReg = FIELD_SET(ulReg, PANEL_HWC_ADDRESS, ENABLE, DISABLE); + POKE32(PANEL_HWC_ADDRESS, ulReg); + + /* Disable CRT hardware cursor, if a former application left it on */ + ulReg = PEEK32(CRT_HWC_ADDRESS); + ulReg = FIELD_SET(ulReg, CRT_HWC_ADDRESS, ENABLE, DISABLE); + POKE32(CRT_HWC_ADDRESS, ulReg); + + /* Disable ZV Port 0, if a former application left it on */ + ulReg = PEEK32(ZV0_CAPTURE_CTRL); + ulReg = FIELD_SET(ulReg, ZV0_CAPTURE_CTRL, CAP, DISABLE); + POKE32(ZV0_CAPTURE_CTRL, ulReg); + + /* Disable ZV Port 1, if a former application left it on */ + ulReg = PEEK32(ZV1_CAPTURE_CTRL); + ulReg = FIELD_SET(ulReg, ZV1_CAPTURE_CTRL, CAP, DISABLE); + POKE32(ZV1_CAPTURE_CTRL, ulReg); + + /* Disable ZV Port Power, if a former application left it on */ + enableZVPort(0); + /* Disable DMA Channel, if a former application left it on */ + ulReg = PEEK32(DMA_ABORT_INTERRUPT); + ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT); + POKE32(DMA_ABORT_INTERRUPT, ulReg); + + /* Disable i2c */ + enableI2C(0); +#endif + /* Disable DMA Channel, if a former application left it on */ + ulReg = PEEK32(DMA_ABORT_INTERRUPT); + ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT); + POKE32(DMA_ABORT_INTERRUPT, ulReg); + + /* Disable DMA Power, if a former application left it on */ + enableDMA(0); + } + + /* We can add more initialization as needed. */ + + return 0; +} + +#if 0 + +unsigned int absDiff(unsigned int a, unsigned int b) +{ + if ( a > b ) + return(a - b); + else + return(b - a); +} + +#endif +/* + monk liu @ 4/6/2011: + re-write the calculatePLL function of ddk750. + the original version function does not use some mathematics tricks and shortcut + when it doing the calculation of the best N,M,D combination + I think this version gives a little upgrade in speed + + 750 pll clock formular: + Request Clock = (Input Clock * M )/(N * X) + + Input Clock = 14318181 hz + X = 2 power D + D ={0,1,2,3,4,5,6} + M = {1,...,255} + N = {2,...,15} +*/ +unsigned int calcPllValue(unsigned int request_orig,pll_value_t *pll) +{ + /* used for primary and secondary channel pixel clock pll */ + static pllcalparam xparm_PIXEL[] = { + /* 2^0 = 1*/ {0,0,0,1}, + /* 2^ 1 =2*/ {1,0,1,2}, + /* 2^ 2 = 4*/ {2,0,2,4}, + {3,0,3,8}, + {4,1,3,16}, + {5,2,3,32}, + /* 2^6 = 64 */ {6,3,3,64}, + }; + + /* used for MXCLK (chip clock) */ + static pllcalparam xparm_MXCLK[] = { + /* 2^0 = 1*/ {0,0,0,1}, + /* 2^ 1 =2*/ {1,0,1,2}, + /* 2^ 2 = 4*/ {2,0,2,4}, + {3,0,3,8}, + }; + + /* as sm750 register definition, N located in 2,15 and M located in 1,255 */ + int N,M,X,d; + int xcnt; + int miniDiff; + unsigned int RN,quo,rem,fl_quo; + unsigned int input,request; + unsigned int tmpClock,ret; + pllcalparam * xparm; + +#if 1 + if (getChipType() == SM750LE) + { + /* SM750LE don't have prgrammable PLL and M/N values to work on. + Just return the requested clock. */ + return request_orig; + } +#endif + + ret = 0; + miniDiff = ~0; + request = request_orig / 1000; + input = pll->inputFreq / 1000; + + /* for MXCLK register , no POD provided, so need be treated differently */ + + if(pll->clockType != MXCLK_PLL){ + xparm = &xparm_PIXEL[0]; + xcnt = sizeof(xparm_PIXEL)/sizeof(xparm_PIXEL[0]); + }else{ + xparm = &xparm_MXCLK[0]; + xcnt = sizeof(xparm_MXCLK)/sizeof(xparm_MXCLK[0]); + } + + + for(N = 15;N>1;N--) + { + /* RN will not exceed maximum long if @request <= 285 MHZ (for 32bit cpu) */ + RN = N * request; + quo = RN / input; + rem = RN % input;/* rem always small than 14318181 */ + fl_quo = (rem * 10000 /input); + + for(d = xcnt - 1;d >= 0;d--){ + X = xparm[d].value; + M = quo*X; + M += fl_quo * X / 10000; + /* round step */ + M += (fl_quo*X % 10000)>5000?1:0; + if(M < 256 && M > 0) + { + unsigned int diff; + tmpClock = pll->inputFreq *M / N / X; + diff = absDiff(tmpClock,request_orig); + if(diff < miniDiff) + { + pll->M = M; + pll->N = N; + pll->OD = xparm[d].od; + pll->POD = xparm[d].pod; + miniDiff = diff; + ret = tmpClock; + } + } + } + } + + /*printk("Finally: pll->n[%lu],m[%lu],od[%lu],pod[%lu]\n",pll->N,pll->M,pll->OD,pll->POD);*/ + return ret; +} + +unsigned int calcPllValue2( +unsigned int ulRequestClk, /* Required pixel clock in Hz unit */ +pll_value_t *pPLL /* Structure to hold the value to be set in PLL */ +) +{ + unsigned int M, N, OD, POD = 0, diff, pllClk, odPower, podPower; + unsigned int bestDiff = 0xffffffff; /* biggest 32 bit unsigned number */ + unsigned int ret; + /* Init PLL structure to know states */ + pPLL->M = 0; + pPLL->N = 0; + pPLL->OD = 0; + pPLL->POD = 0; + + /* Sanity check: None at the moment */ + + /* Convert everything in Khz range in order to avoid calculation overflow */ + pPLL->inputFreq /= 1000; + ulRequestClk /= 1000; + +#ifndef VALIDATION_CHIP + /* The maximum of post divider is 8. */ + for (POD=0; POD<=3; POD++) +#endif + { + +#ifndef VALIDATION_CHIP + /* MXCLK_PLL does not have post divider. */ + if ((POD > 0) && (pPLL->clockType == MXCLK_PLL)) + break; +#endif + + /* Work out 2 to the power of POD */ + podPower = twoToPowerOfx(POD); + + /* OD has only 2 bits [15:14] and its value must between 0 to 3 */ + for (OD=0; OD<=3; OD++) + { + /* Work out 2 to the power of OD */ + odPower = twoToPowerOfx(OD); + +#ifdef VALIDATION_CHIP + if (odPower > 4) + podPower = 4; + else + podPower = odPower; +#endif + + /* N has 4 bits [11:8] and its value must between 2 and 15. + The N == 1 will behave differently --> Result is not correct. */ + for (N=2; N<=15; N++) + { + /* The formula for PLL is ulRequestClk = inputFreq * M / N / (2^OD) + In the following steps, we try to work out a best M value given the others are known. + To avoid decimal calculation, we use 1000 as multiplier for up to 3 decimal places of accuracy. + */ + M = ulRequestClk * N * odPower * 1000 / pPLL->inputFreq; + M = roundedDiv(M, 1000); + + /* M field has only 8 bits, reject value bigger than 8 bits */ + if (M < 256) + { + /* Calculate the actual clock for a given M & N */ + pllClk = pPLL->inputFreq * M / N / odPower / podPower; + + /* How much are we different from the requirement */ + diff = absDiff(pllClk, ulRequestClk); + + if (diff < bestDiff) + { + bestDiff = diff; + + /* Store M and N values */ + pPLL->M = M; + pPLL->N = N; + pPLL->OD = OD; + +#ifdef VALIDATION_CHIP + if (OD > 2) + POD = 2; + else + POD = OD; +#endif + + pPLL->POD = POD; + } + } + } + } + } + + /* Restore input frequency from Khz to hz unit */ +// pPLL->inputFreq *= 1000; + ulRequestClk *= 1000; + pPLL->inputFreq = DEFAULT_INPUT_CLOCK; /* Default reference clock */ + + /* Output debug information */ + //DDKDEBUGPRINT((DISPLAY_LEVEL, "calcPllValue: Requested Frequency = %d\n", ulRequestClk)); + //DDKDEBUGPRINT((DISPLAY_LEVEL, "calcPllValue: Input CLK = %dHz, M=%d, N=%d, OD=%d, POD=%d\n", pPLL->inputFreq, pPLL->M, pPLL->N, pPLL->OD, pPLL->POD)); + + /* Return actual frequency that the PLL can set */ + ret = calcPLL(pPLL); + return ret; +} + + + + + +unsigned int formatPllReg(pll_value_t *pPLL) +{ + unsigned int ulPllReg = 0; + + /* Note that all PLL's have the same format. Here, we just use Panel PLL parameter + to work out the bit fields in the register. + On returning a 32 bit number, the value can be applied to any PLL in the calling function. + */ + ulPllReg = + FIELD_SET( 0, PANEL_PLL_CTRL, BYPASS, OFF) + | FIELD_SET( 0, PANEL_PLL_CTRL, POWER, ON) + | FIELD_SET( 0, PANEL_PLL_CTRL, INPUT, OSC) +#ifndef VALIDATION_CHIP + | FIELD_VALUE(0, PANEL_PLL_CTRL, POD, pPLL->POD) +#endif + | FIELD_VALUE(0, PANEL_PLL_CTRL, OD, pPLL->OD) + | FIELD_VALUE(0, PANEL_PLL_CTRL, N, pPLL->N) + | FIELD_VALUE(0, PANEL_PLL_CTRL, M, pPLL->M); + + return(ulPllReg); +} + + diff --git a/src/ddk750/ddk750_chip.h b/src/ddk750/ddk750_chip.h new file mode 100644 index 0000000..7268b29 --- /dev/null +++ b/src/ddk750/ddk750_chip.h @@ -0,0 +1,84 @@ +#ifndef DDK750_CHIP_H__ +#define DDK750_CHIP_H__ +#define DEFAULT_INPUT_CLOCK 14318181 /* Default reference clock */ +#define SM750LE_REVISION_ID (unsigned long)0xfe + +#define MHz(x) (x*1000000) /* Don't use this macro if x is fraction number */ + +/* This is all the chips recognized by this library */ +typedef enum _logical_chip_type_t +{ + SM_UNKNOWN, + SM718, + SM750, + SM750LE, +} +logical_chip_type_t; + + +typedef enum _clock_type_t +{ + MXCLK_PLL, + PRIMARY_PLL, + SECONDARY_PLL, + VGA0_PLL, + VGA1_PLL, +} +clock_type_t; + +typedef struct _pll_value_t +{ + clock_type_t clockType; + unsigned long inputFreq; /* Input clock frequency to the PLL */ + + /* Use this when clockType = PANEL_PLL */ + unsigned long M; + unsigned long N; + unsigned long OD; + unsigned long POD; +} +pll_value_t; + +/* input struct to initChipParam() function */ +typedef struct _initchip_param_t +{ + unsigned short powerMode; /* Use power mode 0 or 1 */ + unsigned short chipClock; /* Speed of main chip clock in MHz unit + 0 = keep the current clock setting + Others = the new main chip clock + */ + unsigned short memClock; /* Speed of memory clock in MHz unit + 0 = keep the current clock setting + Others = the new memory clock + */ + unsigned short masterClock; /* Speed of master clock in MHz unit + 0 = keep the current clock setting + Others = the new master clock + */ + unsigned short setAllEngOff; /* 0 = leave all engine state untouched. + 1 = make sure they are off: 2D, Overlay, + video alpha, alpha, hardware cursors + */ + unsigned char resetMemory; /* 0 = Do not reset the memory controller + 1 = Reset the memory controller + */ + + /* More initialization parameter can be added if needed */ +} +initchip_param_t; + + +logical_chip_type_t getChipType(void); +unsigned int calcPllValue(unsigned int request,pll_value_t *pll); +unsigned int calcPllValue2(unsigned int,pll_value_t *); +unsigned int formatPllReg(pll_value_t *pPLL); +unsigned int ddk750_getVMSize(void); +int ddk750_initHw(initchip_param_t *); +unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL); +unsigned int getChipClock(void); +void setChipClock(unsigned int); +void setMemoryClock(unsigned int frequency); +void setMasterClock(unsigned int frequency); + + +#endif diff --git a/src/ddk750/ddk750_display.c b/src/ddk750/ddk750_display.c new file mode 100644 index 0000000..a5e2932 --- /dev/null +++ b/src/ddk750/ddk750_display.c @@ -0,0 +1,350 @@ +#include "../smi_common.h" +#include "ddk750_reg.h" +#include "ddk750_help.h" +#include "ddk750_power.h" +#include "ddk750_display.h" +#include "ddk750_dvi.h" + +#define primaryWaitVerticalSync(delay) waitNextVerticalSync(0,delay) + +static void setDisplayControl(int ctrl,int dispState) +{ + /* state != 0 means turn on both timing & plane en_bit */ + unsigned long ulDisplayCtrlReg, ulReservedBits; + int cnt; + + cnt = 0; + + /* Set the primary display control */ + if (!ctrl) + { + ulDisplayCtrlReg = PEEK32(PANEL_DISPLAY_CTRL); + /* Turn on/off the Panel display control */ + if (dispState) + { + /* Timing should be enabled first before enabling the plane + * because changing at the same time does not guarantee that + * the plane will also enabled or disabled. + */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + PANEL_DISPLAY_CTRL, TIMING, ENABLE); + POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + PANEL_DISPLAY_CTRL, PLANE, ENABLE); + + /* Added some masks to mask out the reserved bits. + * Sometimes, the reserved bits are set/reset randomly when + * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register + * reserved bits are needed to be masked out. + */ + ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | + FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | + FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE); + + /* Somehow the register value on the plane is not set + * until a few delay. Need to write + * and read it a couple times + */ + do + { + cnt++; + POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + } while((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != + (ulDisplayCtrlReg & ~ulReservedBits)); + /*printk("Set Panel Plane enbit:after tried %d times\n",cnt);*/ + } + else + { + /* When turning off, there is no rule on the programming + * sequence since whenever the clock is off, then it does not + * matter whether the plane is enabled or disabled. + * Note: Modifying the plane bit will take effect on the + * next vertical sync. Need to find out if it is necessary to + * wait for 1 vsync before modifying the timing enable bit. + * */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + PANEL_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + PANEL_DISPLAY_CTRL, TIMING, DISABLE); + POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); + } + + } + /* Set the secondary display control */ + else + { + ulDisplayCtrlReg = PEEK32(CRT_DISPLAY_CTRL); + + if (dispState) + { + /* Timing should be enabled first before enabling the plane because changing at the + same time does not guarantee that the plane will also enabled or disabled. + */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + CRT_DISPLAY_CTRL, TIMING, ENABLE); + POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + CRT_DISPLAY_CTRL, PLANE, ENABLE); + + /* Added some masks to mask out the reserved bits. + * Sometimes, the reserved bits are set/reset randomly when + * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register + * reserved bits are needed to be masked out. + */ + + ulReservedBits = FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | + FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | + FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE) | + FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_4_MASK, ENABLE); + + do + { + cnt++; + POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + } while((PEEK32(CRT_DISPLAY_CTRL) & ~ulReservedBits) != + (ulDisplayCtrlReg & ~ulReservedBits)); + /*printk("Set Crt Plane enbit:after tried %d times\n",cnt);*/ + } + else + { + /* When turning off, there is no rule on the programming + * sequence since whenever the clock is off, then it does not + * matter whether the plane is enabled or disabled. + * Note: Modifying the plane bit will take effect on the next + * vertical sync. Need to find out if it is necessary to + * wait for 1 vsync before modifying the timing enable bit. + */ + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + CRT_DISPLAY_CTRL, PLANE, DISABLE); + POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + + ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, + CRT_DISPLAY_CTRL, TIMING, DISABLE); + POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); + } + } +} + + +static void waitNextVerticalSync(int ctrl,int delay) +{ + unsigned int status; + if(!ctrl){ + /* primary controller */ + + /* Do not wait when the Primary PLL is off or display control is already off. + This will prevent the software to wait forever. */ + if ((FIELD_GET(PEEK32(PANEL_PLL_CTRL), PANEL_PLL_CTRL, POWER) == + PANEL_PLL_CTRL_POWER_OFF) || + (FIELD_GET(PEEK32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, TIMING) == + PANEL_DISPLAY_CTRL_TIMING_DISABLE)) + { + return; + } + + while (delay-- > 0) + { + /* Wait for end of vsync. */ + do + { + status = FIELD_GET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + PANEL_VSYNC); + } + while (status == SYSTEM_CTRL_PANEL_VSYNC_ACTIVE); + + /* Wait for start of vsync. */ + do + { + status = FIELD_GET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + PANEL_VSYNC); + } + while (status == SYSTEM_CTRL_PANEL_VSYNC_INACTIVE); + } + + }else{ + + /* Do not wait when the Primary PLL is off or display control is already off. + This will prevent the software to wait forever. */ + if ((FIELD_GET(PEEK32(CRT_PLL_CTRL), CRT_PLL_CTRL, POWER) == + CRT_PLL_CTRL_POWER_OFF) || + (FIELD_GET(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, TIMING) == + CRT_DISPLAY_CTRL_TIMING_DISABLE)) + { + return; + } + + while (delay-- > 0) + { + /* Wait for end of vsync. */ + do + { + status = FIELD_GET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + CRT_VSYNC); + } + while (status == SYSTEM_CTRL_CRT_VSYNC_ACTIVE); + + /* Wait for start of vsync. */ + do + { + status = FIELD_GET(PEEK32(SYSTEM_CTRL), + SYSTEM_CTRL, + CRT_VSYNC); + } + while (status == SYSTEM_CTRL_CRT_VSYNC_INACTIVE); + } + } +} + +static void swPanelPowerSequence_sm750le(int disp,int delay) +{ + unsigned int reg; + reg = PEEK32(DISPLAY_CONTROL_750LE); + if(disp) + reg |= 0xf; + else + reg &= ~0xf; + POKE32(DISPLAY_CONTROL_750LE,reg); +} + +_X_EXPORT void ddk750_swPanelPowerSequence(int disp,int delay) +{ + unsigned int reg; + + /* disp should be 1 to open sequence */ + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,FPVDDEN,disp); + POKE32(PANEL_DISPLAY_CTRL,reg); + primaryWaitVerticalSync(delay); + + + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,DATA,disp); + POKE32(PANEL_DISPLAY_CTRL,reg); + primaryWaitVerticalSync(delay); + + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,VBIASEN,disp); + POKE32(PANEL_DISPLAY_CTRL,reg); + primaryWaitVerticalSync(delay); + + + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,FPEN,disp); + POKE32(PANEL_DISPLAY_CTRL,reg); + primaryWaitVerticalSync(delay); + +} + +_X_EXPORT void ddk750_setLogicalDispOut(disp_output_t output) +{ + unsigned int reg; + if(output & PNL_2_USAGE){ + /* set panel path controller select */ + reg = PEEK32(PANEL_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,SELECT,(output & PNL_2_MASK)>>PNL_2_OFFSET); + POKE32(PANEL_DISPLAY_CTRL,reg); + } + + if(output & CRT_2_USAGE){ + /* set crt path controller select */ + reg = PEEK32(CRT_DISPLAY_CTRL); + reg = FIELD_VALUE(reg,CRT_DISPLAY_CTRL,SELECT,(output & CRT_2_MASK)>>CRT_2_OFFSET); + /*se blank off */ + reg = FIELD_SET(reg,CRT_DISPLAY_CTRL,BLANK,OFF);//i think that...it doesnot use for 750LE, ilena + POKE32(CRT_DISPLAY_CTRL,reg); + + } + + if(output & PRI_TP_USAGE){ + /* set primary timing and plane en_bit */ + setDisplayControl(0,(output&PRI_TP_MASK)>>PRI_TP_OFFSET); + } + + if(output & SEC_TP_USAGE){ + /* set secondary timing and plane en_bit*/ + setDisplayControl(1,(output&SEC_TP_MASK)>>SEC_TP_OFFSET); + } + + if(output & PNL_SEQ_USAGE){ + /* set panel sequence */ + ddk750_swPanelPowerSequence((output&PNL_SEQ_MASK)>>PNL_SEQ_OFFSET,4); + } + + if(output & DAC_USAGE) + setDAC((output & DAC_MASK)>>DAC_OFFSET); + + if(output & DISP_DDK_DPMS_USAGE) + ddk750_setDPMS((output & DISP_DDK_DPMS_MASK) >> DISP_DDK_DPMS_OFFSET); +} + + +_X_EXPORT int ddk750_initDVIDisp() +{ + /* Initialize DVI. If the dviInit fail and the VendorID or the DeviceID are + not zeroed, then set the failure flag. If it is zeroe, it might mean + that the system is in Dual CRT Monitor configuration. */ + + /* De-skew enabled with default 111b value. + This will fix some artifacts problem in some mode on board 2.2. + Somehow this fix does not affect board 2.1. + */ + if ((dviInit(1, /* Select Rising Edge */ + 1, /* Select 24-bit bus */ + 0, /* Select Single Edge clock */ + 1, /* Enable HSync as is */ + 1, /* Enable VSync as is */ + 1, /* Enable De-skew */ + 7, /* Set the de-skew setting to maximum setup */ + 1, /* Enable continuous Sync */ + 1, /* Enable PLL Filter */ + 4 /* Use the recommended value for PLL Filter value */ + ) != 0) && (dviGetVendorID() != 0x0000) && (dviGetDeviceID() != 0x0000)) + { + return (-1); + } + + /* TODO: Initialize other display component */ + + /* Success */ + return 0; + +} + +_X_EXPORT int setPanelType( + panel_type_t panelType +) +{ + int value; + + /* Set the panel type. */ + value=PEEK32(PANEL_DISPLAY_CTRL); + switch (panelType) + { + case TFT_18BIT: + value = FIELD_SET(value, PANEL_DISPLAY_CTRL, DUAL_DISPLAY, ENABLE); + value = FIELD_SET(value, PANEL_DISPLAY_CTRL, DOUBLE_PIXEL, DISABLE); + break; + case TFT_24BIT: + value = FIELD_SET(value, PANEL_DISPLAY_CTRL, DUAL_DISPLAY, DISABLE); + value = FIELD_SET(value, PANEL_DISPLAY_CTRL, DOUBLE_PIXEL, DISABLE); + break; + case TFT_36BIT: + value = FIELD_SET(value, PANEL_DISPLAY_CTRL, DUAL_DISPLAY, DISABLE); + value = FIELD_SET(value, PANEL_DISPLAY_CTRL, DOUBLE_PIXEL, ENABLE); + break; + default: + return (-1); + } + value=POKE32(PANEL_DISPLAY_CTRL,value); + + return 0; +} + + diff --git a/src/ddk750/ddk750_display.h b/src/ddk750/ddk750_display.h new file mode 100644 index 0000000..9a79fcf --- /dev/null +++ b/src/ddk750/ddk750_display.h @@ -0,0 +1,177 @@ +#ifndef DDK750_DISPLAY_H__ +#define DDK750_DISPLAY_H__ + +/* panel path select + 80000[29:28] +*/ + +#define PNL_2_OFFSET 0 +#define PNL_2_MASK (3 << PNL_2_OFFSET) +#define PNL_2_USAGE (PNL_2_MASK << 16) +#define PNL_2_PRI ((0 << PNL_2_OFFSET)|PNL_2_USAGE) +#define PNL_2_SEC ((2 << PNL_2_OFFSET)|PNL_2_USAGE) + + +/* primary timing & plane enable bit + 1: 80000[8] & 80000[2] on + 0: both off +*/ +#define PRI_TP_OFFSET 4 +#define PRI_TP_MASK (1 << PRI_TP_OFFSET) +#define PRI_TP_USAGE (PRI_TP_MASK << 16) +#define PRI_TP_ON ((0x1 << PRI_TP_OFFSET)|PRI_TP_USAGE) +#define PRI_TP_OFF ((0x0 << PRI_TP_OFFSET)|PRI_TP_USAGE) + + +/* panel sequency status + 80000[27:24] +*/ +#define PNL_SEQ_OFFSET 6 +#define PNL_SEQ_MASK (1 << PNL_SEQ_OFFSET) +#define PNL_SEQ_USAGE (PNL_SEQ_MASK << 16) +#define PNL_SEQ_ON ((1 << PNL_SEQ_OFFSET)|PNL_SEQ_USAGE) +#define PNL_SEQ_OFF ((0 << PNL_SEQ_OFFSET)|PNL_SEQ_USAGE) + +/* dual digital output + 80000[19] +*/ +#define DUAL_TFT_OFFSET 8 +#define DUAL_TFT_MASK (1 << DUAL_TFT_OFFSET) +#define DUAL_TFT_USAGE (DUAL_TFT_MASK << 16) +#define DUAL_TFT_ON ((1 << DUAL_TFT_OFFSET)|DUAL_TFT_USAGE) +#define DUAL_TFT_OFF ((0 << DUAL_TFT_OFFSET)|DUAL_TFT_USAGE) + +/* secondary timing & plane enable bit + 1:80200[8] & 80200[2] on + 0: both off +*/ +#define SEC_TP_OFFSET 5 +#define SEC_TP_MASK (1<< SEC_TP_OFFSET) +#define SEC_TP_USAGE (SEC_TP_MASK << 16) +#define SEC_TP_ON ((0x1 << SEC_TP_OFFSET)|SEC_TP_USAGE) +#define SEC_TP_OFF ((0x0 << SEC_TP_OFFSET)|SEC_TP_USAGE) + +/* crt path select + 80200[19:18] +*/ +#define CRT_2_OFFSET 2 +#define CRT_2_MASK (3 << CRT_2_OFFSET) +#define CRT_2_USAGE (CRT_2_MASK << 16) +#define CRT_2_PRI ((0x0 << CRT_2_OFFSET)|CRT_2_USAGE) +#define CRT_2_SEC ((0x2 << CRT_2_OFFSET)|CRT_2_USAGE) + + +/* DAC affect both DVI and DSUB + 4[20] +*/ +#define DAC_OFFSET 7 +#define DAC_MASK (1 << DAC_OFFSET) +#define DAC_USAGE (DAC_MASK << 16) +#define DAC_ON ((0x0<< DAC_OFFSET)|DAC_USAGE) +#define DAC_OFF ((0x1 << DAC_OFFSET)|DAC_USAGE) + +/* DPMS only affect D-SUB head + 0[31:30]*/ + +#define DISP_DDK_DPMS_OFFSET 9 +#define DISP_DDK_DPMS_MASK (3 << DISP_DDK_DPMS_OFFSET) +#define DISP_DDK_DPMS_USAGE (DISP_DDK_DPMS_MASK << 16) +#define DISP_DDK_DPMS_OFF ((3 << DISP_DDK_DPMS_OFFSET)|DISP_DDK_DPMS_USAGE) +#define DISP_DDK_DPMS_ON ((0 << DISP_DDK_DPMS_OFFSET)|DISP_DDK_DPMS_USAGE) + + + +/* + LCD1 means panel path TFT1 & panel path DVI (so enable DAC) + CRT means crt path DSUB +*/ +#if 0 +typedef enum _disp_output_t +{ + NO_DISPLAY = DPMS_OFF, + + LCD1_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON|DPMS_OFF|DAC_ON, + LCD1_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON|DPMS_OFF|DAC_ON, + + LCD2_PRI = CRT_2_PRI|PRI_TP_ON|DUAL_TFT_ON|DPMS_OFF, + LCD2_SEC = CRT_2_SEC|SEC_TP_ON|DUAL_TFT_ON|DPMS_OFF, + + DSUB_PRI = CRT_2_PRI|PRI_TP_ON|DAC_ON, + DSUB_SEC = CRT_2_SEC|SEC_TP_ON|DAC_ON, + + LCD1_DSUB_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON| + CRT_2_PRI|SEC_TP_OFF|DAC_ON, + + LCD1_DSUB_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON| + CRT_2_SEC|PRI_TP_OFF|DAC_ON, + + /* LCD1 show primary and DSUB show secondary */ + LCD1_DSUB_DUAL = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON| + CRT_2_SEC|SEC_TP_ON|DAC_ON, + + /* LCD1 show secondary and DSUB show primary */ + LCD1_DSUB_DUAL_SWAP = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON| + CRT_2_PRI|PRI_TP_ON|DAC_ON, + + LCD1_LCD2_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON| + CRT_2_PRI|SEC_TP_OFF|DPMS_OFF|DUAL_TFT_ON, + + LCD1_LCD2_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON| + CRT_2_SEC|PRI_TP_OFF|DPMS_OFF|DUAL_TFT_ON, + + LCD1_LCD2_DSUB_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON|DAC_ON| + CRT_2_PRI|SEC_TP_OFF|DPMS_ON|DUAL_TFT_ON, + + LCD1_LCD2_DSUB_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON|DAC_ON| + CRT_2_SEC|PRI_TP_OFF|DPMS_ON|DUAL_TFT_ON, + + +} +disp_output_t; +#else +typedef enum _disp_output_t{ + do_LCD1_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON|DAC_ON, + do_LCD1_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON|DAC_ON, +#if 0 + do_LCD2_PRI = CRT_2_PRI|PRI_TP_ON, + do_LCD2_SEC = CRT_2_SEC|SEC_TP_ON, +#else + do_LCD2_PRI = CRT_2_PRI|PRI_TP_ON|DUAL_TFT_ON, + do_LCD2_SEC = CRT_2_SEC|SEC_TP_ON|DUAL_TFT_ON, +#endif + /* + do_DSUB_PRI = CRT_2_PRI|PRI_TP_ON|DISP_DDK_DPMS_ON|DAC_ON, + do_DSUB_SEC = CRT_2_SEC|SEC_TP_ON|DISP_DDK_DPMS_ON|DAC_ON, + */ +#if 0 + do_CRT_PRI = CRT_2_PRI|PRI_TP_ON, + do_CRT_SEC = CRT_2_SEC|SEC_TP_ON, +#else + do_CRT_PRI = CRT_2_PRI|PRI_TP_ON|DISP_DDK_DPMS_ON|DAC_ON, + do_CRT_SEC = CRT_2_SEC|SEC_TP_ON|DISP_DDK_DPMS_ON|DAC_ON, +#endif +} +disp_output_t; +#endif + +typedef enum _panel_type_t +{ + TFT_9BIT=0, + TFT_12BIT, + TFT_18BIT, + TFT_24BIT, + TFT_36BIT +} +panel_type_t; + +typedef enum _disp_path_t +{ + PANEL_PATH = 0, + CRT_PATH = 1, +} +disp_path_t; + +void ddk750_setLogicalDispOut(disp_output_t); +int ddk750_initDVIDisp(void); + +#endif diff --git a/src/ddk750/ddk750_dvi.c b/src/ddk750/ddk750_dvi.c new file mode 100644 index 0000000..58aac6c --- /dev/null +++ b/src/ddk750/ddk750_dvi.c @@ -0,0 +1,98 @@ +#ifdef USE_DVICHIP +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_dvi.h" +#include "ddk750_sii164.h" + + +/* This global variable contains all the supported driver and its corresponding + function API. Please set the function pointer to NULL whenever the function + is not supported. */ +static dvi_ctrl_device_t g_dcftSupportedDviController[] = +{ +#ifdef DVI_CTRL_SII164 + { + .pfnInit = sii164InitChip, + .pfnGetVendorId = sii164GetVendorID, + .pfnGetDeviceId = sii164GetDeviceID, +#ifdef SII164_FULL_FUNCTIONS + .pfnResetChip = sii164ResetChip, + .pfnGetChipString = sii164GetChipString, + .pfnSetPower = sii164SetPower, + .pfnEnableHotPlugDetection = sii164EnableHotPlugDetection, + .pfnIsConnected = sii164IsConnected, + .pfnCheckInterrupt = sii164CheckInterrupt, + .pfnClearInterrupt = sii164ClearInterrupt, +#endif + }, +#endif +}; + + +int dviInit( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue + ) +{ + dvi_ctrl_device_t *pCurrentDviCtrl; + pCurrentDviCtrl = g_dcftSupportedDviController; + if(pCurrentDviCtrl->pfnInit != NULL) + { + return pCurrentDviCtrl->pfnInit(edgeSelect, busSelect, dualEdgeClkSelect, hsyncEnable, + vsyncEnable, deskewEnable, deskewSetting, continuousSyncEnable, + pllFilterEnable, pllFilterValue); + } + return -1;//error +} + + +/* + * dviGetVendorID + * This function gets the vendor ID of the DVI controller chip. + * + * Output: + * Vendor ID + */ +unsigned short dviGetVendorID() +{ + dvi_ctrl_device_t *pCurrentDviCtrl; + + //pCurrentDviCtrl = getDviCtrl(); + pCurrentDviCtrl = g_dcftSupportedDviController; + if (pCurrentDviCtrl != (dvi_ctrl_device_t *)0) + return pCurrentDviCtrl->pfnGetVendorId(); + + return 0x0000; +} + + +/* + * dviGetDeviceID + * This function gets the device ID of the DVI controller chip. + * + * Output: + * Device ID + */ +unsigned short dviGetDeviceID() +{ + dvi_ctrl_device_t *pCurrentDviCtrl; + +// pCurrentDviCtrl = getDviCtrl(); + pCurrentDviCtrl = g_dcftSupportedDviController; + if (pCurrentDviCtrl != (dvi_ctrl_device_t *)0) + return pCurrentDviCtrl->pfnGetDeviceId(); + + return 0x0000; +} + +#endif + + diff --git a/src/ddk750/ddk750_dvi.h b/src/ddk750/ddk750_dvi.h new file mode 100644 index 0000000..af014fb --- /dev/null +++ b/src/ddk750/ddk750_dvi.h @@ -0,0 +1,67 @@ +#ifndef DDK750_DVI_H__ +#define DDK750_DVI_H__ + +/* dvi chip stuffs structros */ + +typedef long (*PFN_DVICTRL_INIT)( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue); +typedef void (*PFN_DVICTRL_RESETCHIP)(void); +typedef char* (*PFN_DVICTRL_GETCHIPSTRING)(void); +typedef unsigned short (*PFN_DVICTRL_GETVENDORID)(void); +typedef unsigned short (*PFN_DVICTRL_GETDEVICEID)(void); +typedef void (*PFN_DVICTRL_SETPOWER)(unsigned char powerUp); +typedef void (*PFN_DVICTRL_HOTPLUGDETECTION)(unsigned char enableHotPlug); +typedef unsigned char (*PFN_DVICTRL_ISCONNECTED)(void); +typedef unsigned char (*PFN_DVICTRL_CHECKINTERRUPT)(void); +typedef void (*PFN_DVICTRL_CLEARINTERRUPT)(void); + + + +/* Structure to hold all the function pointer to the DVI Controller. */ +typedef struct _dvi_ctrl_device_t +{ + PFN_DVICTRL_INIT pfnInit; + PFN_DVICTRL_RESETCHIP pfnResetChip; + PFN_DVICTRL_GETCHIPSTRING pfnGetChipString; + PFN_DVICTRL_GETVENDORID pfnGetVendorId; + PFN_DVICTRL_GETDEVICEID pfnGetDeviceId; + PFN_DVICTRL_SETPOWER pfnSetPower; + PFN_DVICTRL_HOTPLUGDETECTION pfnEnableHotPlugDetection; + PFN_DVICTRL_ISCONNECTED pfnIsConnected; + PFN_DVICTRL_CHECKINTERRUPT pfnCheckInterrupt; + PFN_DVICTRL_CLEARINTERRUPT pfnClearInterrupt; +} dvi_ctrl_device_t; +#define DVI_CTRL_SII164 + + + +/* dvi functions prototype */ +int dviInit( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue +); + +unsigned short dviGetVendorID(void); +unsigned short dviGetDeviceID(void); + + + +#endif + diff --git a/src/ddk750/ddk750_edid.c b/src/ddk750/ddk750_edid.c new file mode 100644 index 0000000..142b1ad --- /dev/null +++ b/src/ddk750/ddk750_edid.c @@ -0,0 +1,1940 @@ +/******************************************************************* +* +* Copyright (c) 2009 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* edid.c --- SM750/SM718 DDK +* This file contains functions to interpret the EDID structure. +* +*******************************************************************/ +#include +#include "../smi_common.h" +#include "ddk750_edid.h" +#include "ddk750_hwi2c.h" +#include "ddk750_swi2c.h" + +/* Enable this one to print the VDIF timing when debug is enabled. */ +//#define ENABLE_DEBUG_PRINT_VDIF + +/**************************************************************** + * Configuration setting + ****************************************************************/ +/* I2C Address of each Monitor. Currently, there is only one i2c bus and + both display devices will responds to 0xA0 address with analog CRT as the first priority + The second version of evaluation board will separate the i2c bus, so that each i2c bus + corresponds to one display devices. + The new monitor devices (at least the tested DVI monitor) also corresponds to 0xA2, + which is temporarily used in this DDK. */ +#define EDID_DEVICE_I2C_ADDRESS 0xA0 + +/* GPIO used for the I2C on the PANEL_PATH size */ +#define EDID_PANEL_I2C_SCL DEFAULT_I2C_SCL +#define EDID_PANEL_I2C_SDA DEFAULT_I2C_SDA + +/* GPIO used for the I2C on the CRT_PATH size. + These GPIO pins only available in the Evaluation Board version 2.2. + Need to find out which pins are used for the CRT_PATH i2c. */ +#define EDID_CRT_I2C_SCL DEFAULT_I2C_SCL +#define EDID_CRT_I2C_SDA DEFAULT_I2C_SDA + +#define TOTAL_EDID_REGISTERS 128 + +typedef struct _est_timing_mode_t +{ + uint32_t x; /* Mode Width */ + uint32_t y; /* Mode Height */ + uint32_t hz; /* Refresh Rate */ + unsigned char source; /* Source: 0 - VESA + 1 - IBM + 2 - Apple + */ +} +est_timing_mode_t; + +/* These values only applies to EDID Version 1 */ +static est_timing_mode_t establishTiming[3][8] = +{ + /* Established Timing 1 */ + { + { 800, 600, 60, 0}, + { 800, 600, 56, 0}, + { 640, 480, 75, 0}, + { 640, 480, 72, 0}, + { 640, 480, 67, 2}, + { 640, 480, 60, 1}, + { 720, 400, 88, 1}, + { 720, 400, 70, 1}, + }, + { + {1280, 1024, 75, 0}, + {1024, 768, 75, 0}, + {1024, 768, 70, 0}, + {1024, 768, 60, 0}, + {1024, 768, 87, 1}, + { 832, 624, 75, 0}, + { 800, 600, 75, 0}, + { 800, 600, 72, 0}, + }, + { + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + {1152, 870, 75, 2}, + } +}; + +static void printVdif( + vdif_t *pVDIF +) +{ +#ifdef DDKDEBUG + +#ifndef ENABLE_DEBUG_PRINT_VDIF + DDKDEBUGENABLE(0); +#endif + + DDKDEBUGPRINT((DISPLAY_LEVEL, "pixelClock = %d\n", pVDIF->pixelClock)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "characterWidth = %d\n", pVDIF->characterWidth)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "scanType = %s\n", (pVDIF->scanType == VDIF_INTERLACED) ? "Interlaced" : "Progressive")); + + DDKDEBUGPRINT((DISPLAY_LEVEL, "horizontalFrequency = %d\n", pVDIF->horizontalFrequency)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "horizontalTotal = %d\n", pVDIF->horizontalTotal)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "horizontalActive = %d\n", pVDIF->horizontalActive)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "horizontalBlankStart = %d\n", pVDIF->horizontalBlankStart)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "horizontalBlankTime = %d\n", pVDIF->horizontalBlankTime)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "horizontalSyncStart = %d\n", pVDIF->horizontalSyncStart)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "horizontalRightBorder = %d\n", pVDIF->horizontalRightBorder)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "horizontalFrontPorch = %d\n", pVDIF->horizontalFrontPorch)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "horizontalSyncWidth = %d\n", pVDIF->horizontalSyncWidth)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "horizontalBackPorch = %d\n", pVDIF->horizontalBackPorch)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "horizontalLeftBorder = %d\n", pVDIF->horizontalLeftBorder)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "horizontalSyncPolarity = %s\n", + (pVDIF->horizontalSyncPolarity == VDIF_SYNC_NEGATIVE) ? "Negative" : "Positive")); + + DDKDEBUGPRINT((DISPLAY_LEVEL, "verticalFrequency = %d\n", pVDIF->verticalFrequency)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "verticalTotal = %d\n", pVDIF->verticalTotal)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "verticalActive = %d\n", pVDIF->verticalActive)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "verticalBlankStart = %d\n", pVDIF->verticalBlankStart)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "verticalBlankTime = %d\n", pVDIF->verticalBlankTime)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "verticalSyncStart = %d\n", pVDIF->verticalSyncStart)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "verticalBottomBorder = %d\n", pVDIF->verticalBottomBorder)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "verticalFrontPorch = %d\n", pVDIF->verticalFrontPorch)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "verticalSyncHeight = %d\n", pVDIF->verticalSyncHeight)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "verticalBackPorch = %d\n", pVDIF->verticalBackPorch)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "verticalTopBorder = %d\n", pVDIF->verticalTopBorder)); + DDKDEBUGPRINT((DISPLAY_LEVEL, "verticalSyncPolarity = %s\n", + (pVDIF->verticalSyncPolarity == VDIF_SYNC_NEGATIVE) ? "Negative" : "Positive")); + +#ifndef ENABLE_DEBUG_PRINT_VDIF + DDKDEBUGENABLE(1); +#endif +#endif +} + +/* + * edidGetVersion + * This function gets the EDID version + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pRevision - Revision of the EDIE (if exist) + * + * Output: + * Revision number of the given EDID buffer. + */ +unsigned char edidGetVersion( + unsigned char *pEDIDBuffer, + unsigned char *pRevision +) +{ + unsigned char version; + + if (pEDIDBuffer != (unsigned char *)0) + { + /* Check the header */ + if ((pEDIDBuffer[0] == 0x00) && (pEDIDBuffer[1] == 0xFF) && (pEDIDBuffer[2] == 0xFF) && + (pEDIDBuffer[3] == 0xFF) && (pEDIDBuffer[4] == 0xFF) && (pEDIDBuffer[5] == 0xFF) && + (pEDIDBuffer[6] == 0xFF) && (pEDIDBuffer[7] == 0x00)) + { + /* + * EDID Structure Version 1. + */ + + /* Read the version field from the buffer. It should be 1 */ + version = pEDIDBuffer[18]; + + if (version == 1) + { + /* Copy the revision first */ + if (pRevision != (unsigned char *)0) + *pRevision = pEDIDBuffer[19]; + + return version; + } + } + else + { + /* + * EDID Structure Version 2 + */ + + /* Read the version and revision field from the buffer. */ + version = pEDIDBuffer[0]; + + if ((version >> 4) == 2) + { + /* Copy the revision */ + if (pRevision != (unsigned char *)0) + *pRevision = version & 0x0F; + + return (version >> 4); + } + } + } + + return 0; +} + +/* + * edidGetProductInfo + * This function gets the vendor and product information. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor [in] + * pManufacturerName - Pointer to a 3 byte length variable to store the manufacturer name [out] + * pProductCode - Pointer to a variable to store the product code [out] + * pSerialNumber - Pointer to a variable to store the serial number [out] + * pWeekOfManufacture - Pointer to a variable to store the week of manufacture [out] + * pYearOfManufacture - Pointer to a variable to store the year of manufacture + * or model year (if WeekOfManufacture is 0xff) [out] + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetProductInfo( + unsigned char *pEDIDBuffer, + char *pManufacturerName, + unsigned short *pProductCode, + uint32_t *pSerialNumber, + unsigned char *pWeekOfManufacture, + unsigned short *pYearOfManufacture +) +{ + unsigned char version, revision; + unsigned short manufactureID; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + if (version == 1) + { + edid_version_1_t *pEDIDStructure; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + + if (pManufacturerName != (char *)0) + { + /* Swap the byte */ + manufactureID = (pEDIDStructure->manufacturerID >> 8) + (pEDIDStructure->manufacturerID << 8); + pManufacturerName[0] = ((manufactureID >> 10) & 0x001F) + 'A' - 1; + pManufacturerName[1] = ((manufactureID >> 5) & 0x001F) + 'A' - 1; + pManufacturerName[2] = (manufactureID & 0x001F) + 'A' - 1; + pManufacturerName[3] = '\0'; + } + + if (pProductCode != (unsigned short *)0) + *pProductCode = pEDIDStructure->productCode; + + /* Only EDID structure version 1.1 and 1.2 supports this. EDID 1.3 uses + detail timing descriptor to store the serial number in ASCII. */ + if (pSerialNumber != (uint32_t *)0) + *pSerialNumber = pEDIDStructure->serialNumber; + + /* + * Rev 1.3: - A value of 0 means that week of manufacture is not specified + * - A value in the range of 1 to 54 (0x01 - 0x36) means the week of manufacture + * - Any values greater than 54 is invalid. + * + * Rev 1.4: - A value of 0 means that week of manufacture is not specified + * - A value in the range of 1 to 54 (0x01 - 0x36) means the week of manufacture + * - A value of 0xFF means that Year of Manufacture contains the model year + * instead of year of Manufacture. + * - Other values means invalid + */ + if (pWeekOfManufacture != (unsigned char *)0) + *pWeekOfManufacture = pEDIDStructure->weekOfManufacture; + + /* The value must be greater than 3 and less than or equal to the current + year minus 1990. + A value of 3 or less would indicated that the display was manufactured + before the EDID standard was defined. + A value greater than (current year - 1990) would indicate that the display + has not yet been manufactured. + */ + if (pYearOfManufacture != (unsigned short *)0) + *pYearOfManufacture = (unsigned short) pEDIDStructure->yearOfManufacture + 1990; + + return 0; + } + + return (-1); +} + +/* + * edidCheckMonitorInputSignal + * This function checks whether the monitor is expected analog/digital + * input signal. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * 0 - Analog + * 1 - Digital + */ +unsigned char edidCheckMonitorInputSignal( + unsigned char *pEDIDBuffer +) +{ + unsigned char version; + unsigned short index; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, (unsigned char *)0); + + if (version == 1) + return (unsigned char)((edid_version_1_t *)pEDIDBuffer)->videoInputDefinition.analogSignal.inputSignal; + + return 0; +} + +/* + * edidGetAnalogSignalInfo + * This function gets the analog video input signal information + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pRefWhiteAboveBlank - Pointer to a variable to store the reference white above blank + * value. The value is in milliVolt. + * pSyncLevelBelowBlank - Pointer to a variable to store the Sync tip level below blank + * The value is also in milliVolt + * pBlank2BlackSetup - Pointer to a variable to store the Blank to black setup or + * pedestal per appropriate Signal Level Standard flag. + * 1 means that the display expect the setup. + * pSeparateSyncSupport - Pointer to a variable to store the flag to indicate that the + * monitor supports separate sync. + * pCompositeSyncSupport - Pointer to a variable to store a flag to indicate that the + * monitor supports composite sync. + * pSyncOnGreenSupport - Pointer to a variable to store a flag to indicate that + * the monitor supports sync on green video. + * pVSyncSerrationRequired - Pointer to a variable to store a flag to indicate that serration + * of the VSync pulse is required when composite sync or + * sync-on-green video is used. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetAnalogSignalInfo( + unsigned char *pEDIDBuffer, + unsigned short *pRefWhiteAboveBlank, + unsigned short *pSyncLevelBelowBlank, + unsigned char *pBlank2BlackSetup, + unsigned char *pSeparateSyncSupport, + unsigned char *pCompositeSyncSupport, + unsigned char *pSyncOnGreenSupport, + unsigned char *pVSyncSerrationRequired +) +{ + unsigned char version, revision; + unsigned short whiteReference, syncLevel; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + if (version == 1) + { + edid_version_1_t *pEDIDStructure; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + + /* Check if the input signal is analog */ + if (pEDIDStructure->videoInputDefinition.analogSignal.inputSignal != 0) + return (-1); + + switch (pEDIDStructure->videoInputDefinition.analogSignal.signalLevelStd) + { + case 0: + whiteReference = 700; + syncLevel = 300; + break; + case 1: + whiteReference = 714; + syncLevel = 286; + break; + case 2: + whiteReference = 1000; + syncLevel = 400; + break; + case 3: + whiteReference = 700; + syncLevel = 0; + break; + } + + if (pRefWhiteAboveBlank != (unsigned short *)0) + *pRefWhiteAboveBlank = whiteReference; + + if (pSyncLevelBelowBlank != (unsigned short *)0) + *pSyncLevelBelowBlank = syncLevel; + + if (pBlank2BlackSetup != (unsigned char *)0) + *pBlank2BlackSetup = (unsigned char) + pEDIDStructure->videoInputDefinition.analogSignal.blank2Black; + + if (pSeparateSyncSupport != (unsigned char *)0) + *pSeparateSyncSupport = (unsigned char) + pEDIDStructure->videoInputDefinition.analogSignal.separateSyncSupport; + + if (pCompositeSyncSupport != (unsigned char *)0) + *pCompositeSyncSupport = (unsigned char) + pEDIDStructure->videoInputDefinition.analogSignal.compositeSyncSupport; + + if (pSyncOnGreenSupport != (unsigned char *)0) + *pSyncOnGreenSupport = (unsigned char) + pEDIDStructure->videoInputDefinition.analogSignal.syncOnGreenSupport; + + if (pVSyncSerrationRequired != (unsigned char *)0) + *pVSyncSerrationRequired = (unsigned char) + pEDIDStructure->videoInputDefinition.analogSignal.vsyncSerration; + + return 0; + } + else + { + /* EDID Structure 2 */ + } + + return (-1); +} + +/* + * edidGetDigitalSignalInfo + * This function gets the digital video input signal information. + * Only applies to EDID 1.3 and above. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pDFP1xSupport - Pointer to a variable to store the flag to indicate that + * the mointor interface is signal compatible with VESA + * DFP 1.x TMDS CRGB, 1 pixel/clock, up to 8 bits / color + * MSB aligned, DE active high + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetDigitalSignalInfo( + unsigned char *pEDIDBuffer, + unsigned char *pDFP1xSupport +) +{ + unsigned char version, revision; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + if ((version == 1) && (revision == 3)) + { + edid_version_1_t *pEDIDStructure; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + + /* Check if the input signal is digital */ + if (pEDIDStructure->videoInputDefinition.digitalSignal.inputSignal != 1) + return (-1); + + if (pDFP1xSupport != (unsigned char *)0) + *pDFP1xSupport = pEDIDStructure->videoInputDefinition.digitalSignal.dfp1Support; + + return 0; + } + + return (-1); +} + +/* + * edidGetDisplaySize + * This function gets the display sizes in cm. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pMaxHorzImageSize - Pointer to a variable to store the maximum horizontal + * image size to the nearest centimeter. A value of 0 + * indicates that the size is indeterminate size. + * pMaxVertImageSize - Pointer to a variable to store the maximum vertical + * image size to the nearest centimeter. A value of 0 + * indicates that the size is indeterminate size. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetDisplaySize( + unsigned char *pEDIDBuffer, + unsigned char *pMaxHorzImageSize, + unsigned char *pMaxVertImageSize +) +{ + unsigned char version, revision; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + if (version == 1) + { + edid_version_1_t *pEDIDStructure; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + + if (pMaxHorzImageSize != (unsigned char *)0) + *pMaxHorzImageSize = pEDIDStructure->maxHorzImageSize; + + if (pMaxVertImageSize != (unsigned char *)0) + *pMaxVertImageSize = pEDIDStructure->maxVertImageSize; + + return 0; + } + + return (-1); +} + +#if 0 /* Use the edidGetWhitePoint to get the Gamma */ +/* + * edidGetGamma + * This function gets the Display Transfer Characteristic (Gamma). + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * Gamma value multiplied by 100. A value of 0xFFFF (-1) indicates that + * the gamma value is not defined. + */ +unsigned short edidGetGamma( + unsigned char *pEDIDBuffer +) +{ + unsigned char version; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, (unsigned char *)0); + + if (version == 1) + return (unsigned short)(((edid_version_1_t *)pEDIDBuffer)->displayTransferChar + 100); + + return (-1); +} +#endif + +/* + * edidGetPowerManagementSupport + * This function gets the monitor's power management support. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pStandBy - Pointer to a variable to store the flag to indicate that + * standby power mode is supported. + * pSuspend - Pointer to a variable to store the flag to indicate that + * suspend power mode is supported. + * pLowPower - Pointer to a variable to store the flag to indicate that + * the display consumes low power when it receives a timing + * signal that is outside its declared active operating range. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetPowerManagementSupport( + unsigned char *pEDIDBuffer, + unsigned char *pStandBy, + unsigned char *pSuspend, + unsigned char *pLowPower +) +{ + unsigned char version; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, (unsigned char *)0); + + if (version == 1) + { + edid_version_1_t *pEDIDStructure; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + + if (pStandBy != (unsigned char *)0) + *pStandBy = (unsigned char) pEDIDStructure->featureSupport.standbySupport; + + if (pSuspend != (unsigned char *)0) + *pSuspend = (unsigned char) pEDIDStructure->featureSupport.suspendSupport; + + if (pLowPower != (unsigned char *)0) + *pLowPower = (unsigned char) pEDIDStructure->featureSupport.lowPowerSupport; + + return 0; + } + + return (-1); +} + +/* + * edidGetDisplayType + * This function gets the display type. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * 0 - Monochrome / grayscale display + * 1 - RGB Color Display + * 2 - Non-RGB multicolor display, e.g. R/G/Y + * 3 - Undefined + */ +unsigned char edidGetDisplayType( + unsigned char *pEDIDBuffer +) +{ + unsigned char version; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, (unsigned char *)0); + + if (version == 1) + return (unsigned char)((edid_version_1_t *)pEDIDBuffer)->featureSupport.displayType; + + return (3); +} + +/* + * edidChecksRGBUsage + * This function checks if the display is using the sRGB standard default + * color space as its primary color space. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * 0 - Does not use sRGB as its primary color space + * 1 - Use sRGB as its primary color space + */ +unsigned char edidChecksRGBUsage( + unsigned char *pEDIDBuffer +) +{ + unsigned char version; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, (unsigned char *)0); + + if (version == 1) + return (unsigned char)((edid_version_1_t *)pEDIDBuffer)->featureSupport.sRGBSupport; + + return (0); +} + +/* + * edidIsPreferredTimingAvailable + * This function checks whether the preffered timing mode is available. + * Use of preferred timing mode is required by EDID structure version 1 + * Revision 3 and higher. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * 0 - Preferred Timing is not available + * 1 - Preferred Timing is available + */ +unsigned char edidIsPreferredTimingAvailable( + unsigned char *pEDIDBuffer +) +{ + unsigned char version; + + if (pEDIDBuffer != (unsigned char *)0) + { + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, (unsigned char *)0); + + if (version == 1) + return (unsigned char)((edid_version_1_t *)pEDIDBuffer)->featureSupport.preferredTiming; + } + + return (0); +} + +/* + * edidIsDefaultGTFSupported + * This function checks whether the display supports timings based on the + * GTF standard using default GTF parameter values. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * 0 - Default GTF is not supported + * 1 - Default GTF is supported + */ +unsigned char edidIsDefaultGTFSupported( + unsigned char *pEDIDBuffer +) +{ + unsigned char version, revision; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, (unsigned char *)0); + + if (version == 1) + return (unsigned char)((edid_version_1_t *)pEDIDBuffer)->featureSupport.defaultGTFSupport; + + return (0); +} + +/* + * edidCalculateChromaticValue + * This function calculates the chromatic value. + * + * Input: + * colorBinaryValue - Color Characteristic Binary Representation Value + * to be computed + * + * Output: + * The chromatic value times a 1000. + */ +static unsigned short edidCalculateChromaticValue( + unsigned short colorBinaryValue +) +{ + uint32_t index; + uint32_t result; + + result = 0; + for (index = 10; index > 0; index--) + { + /* Times 1000000 to make it accurate to the micro value. */ + result += roundedDiv((colorBinaryValue & 0x0001) * 1000000, twoToPowerOfx(index)); + colorBinaryValue >>= 1; + } + + /* Make it accurate to 1000 place */ + return ((unsigned short)roundedDiv(result, 1000)); +} + +/* + * edidGetColorCharacteristic + * This function gets the chromaticity and white point values expressed as + * an integer value which represents the actual value times 1000. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pRedX - Pointer to a variable to store the Red X values + * pRedY - Pointer to a variable to store the Red Y values + * pGreenX - Pointer to a variable to store the Green X values + * pGreenY - Pointer to a variable to store the Green Y values + * pBlueX - Pointer to a variable to store the Blue X values + * pBlueY - Pointer to a variable to store the Blue Y values + * + * Note: + * To get the White color characteristic, use the edidGetWhitePoint + */ +void edidGetColorCharacteristic( + unsigned char *pEDIDBuffer, + unsigned short *pRedX, + unsigned short *pRedY, + unsigned short *pGreenX, + unsigned short *pGreenY, + unsigned short *pBlueX, + unsigned short *pBlueY +) +{ + unsigned char version, revision; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, (unsigned char *)0); + + if (version == 1) + { + edid_version_1_t *pEDIDStructure; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + + if (pRedX != (unsigned short *)0) + { + *pRedX = edidCalculateChromaticValue(((unsigned short)pEDIDStructure->redX << 2) + + (unsigned short)pEDIDStructure->redGreenLowBits.redXLowBits); + } + + if (pRedY != (unsigned short *)0) + { + *pRedY = edidCalculateChromaticValue(((unsigned short)pEDIDStructure->redY << 2) + + (unsigned short)pEDIDStructure->redGreenLowBits.redYLowBits); + } + + if (pGreenX != (unsigned short *)0) + { + *pGreenX = edidCalculateChromaticValue(((unsigned short)pEDIDStructure->greenX << 2) + + (unsigned short)pEDIDStructure->redGreenLowBits.greenXLowBits); + } + + if (pGreenY != (unsigned short *)0) + { + *pGreenY = edidCalculateChromaticValue(((unsigned short)pEDIDStructure->greenY << 2) + + (unsigned short)pEDIDStructure->redGreenLowBits.greenYLowBits); + } + + if (pBlueX != (unsigned short *)0) + { + *pBlueX = edidCalculateChromaticValue(((unsigned short)pEDIDStructure->blueX << 2) + + (unsigned short)pEDIDStructure->blueWhiteLowBits.blueXLowBits); + } + + if (pBlueY != (unsigned short *)0) + { + *pBlueY = edidCalculateChromaticValue(((unsigned short)pEDIDStructure->blueY << 2) + + (unsigned short)pEDIDStructure->blueWhiteLowBits.blueYLowBits); + } + } +} + +/* + * edidGetWhitePoint + * This function gets the white point. + * To get the default white point, set the index to 0. For multiple white point, + * call this function multiple times to check if more than 1 white point is supported. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pWhitePointIndex - Pointer to a variable that contains the white point index + * to be retrieved. + * pWhiteX - Pointer to a variable to store the White X value + * pWhiteY - Pointer to a variable to store the White Y value + * pWhiteGamma - Pointer to a variable to store the White Gamma value + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetWhitePoint( + unsigned char *pEDIDBuffer, + unsigned char *pWhitePointIndex, + unsigned short *pWhiteX, + unsigned short *pWhiteY, + unsigned short *pWhiteGamma +) +{ + unsigned char version, revision, index, tableIndex; + + if (pWhitePointIndex == (unsigned char *)0) + return (-1); + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, (unsigned char *)0); + + if (version == 1) + { + edid_version_1_t *pEDIDStructure; + monitor_desc_t *pMonitorDescriptor; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + + /* Get the index to a temporary variable and increment the index for the + next loop. */ + index = *pWhitePointIndex; + (*pWhitePointIndex)++; + + if (index == 0) + { + if (pWhiteX != (unsigned short *)0) + { + *pWhiteX = edidCalculateChromaticValue(((unsigned short)pEDIDStructure->whiteX << 2) + + (unsigned short)pEDIDStructure->blueWhiteLowBits.whiteXLowBits); + } + + if (pWhiteY != (unsigned short *)0) + { + *pWhiteY = edidCalculateChromaticValue(((unsigned short)pEDIDStructure->whiteY << 2) + + (unsigned short)pEDIDStructure->blueWhiteLowBits.whiteYLowBits); + } + + if (pWhiteGamma != (unsigned short *)0) + *pWhiteGamma = pEDIDStructure->displayTransferChar + 100; + + return 0; + } + else + { + for (tableIndex = 0; tableIndex < 4; tableIndex++) + { + pMonitorDescriptor = &pEDIDStructure->miscInformation.monitorDesc[tableIndex]; + if ((pMonitorDescriptor->flag1 == 0) && (pMonitorDescriptor->flag2 == 0) && + (pMonitorDescriptor->dataTypeTag == 0xFB) && + (pMonitorDescriptor->descriptor.colorPoint.white[index-1].whitePointIndex != 0)) + { + if (pWhiteX != (unsigned short *)0) + { + *pWhiteX = edidCalculateChromaticValue(((unsigned short)pMonitorDescriptor->descriptor.colorPoint.white[index-1].whiteX << 2) + + (unsigned short)pMonitorDescriptor->descriptor.colorPoint.white[index-1].whiteLowBits.whiteXLowBits); + } + + if (pWhiteY != (unsigned short *)0) + { + *pWhiteY = edidCalculateChromaticValue(((unsigned short)pMonitorDescriptor->descriptor.colorPoint.white[index-1].whiteY << 2) + + (unsigned short)pMonitorDescriptor->descriptor.colorPoint.white[index-1].whiteLowBits.whiteYLowBits); + } + + if (pWhiteGamma != (unsigned short *)0) + *pWhiteGamma = pMonitorDescriptor->descriptor.colorPoint.white[index-1].gamma + 100; + + return 0; + } + } + } + } + + return (-1); +} + +/* + * edidCalculateChecksum + * This function adds all one-byte value of the EDID buffer. + * The total should be equal to 0x00 + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * Total of one-byte values. It should equal to 0x00. A value other than + * 0x00 indicates the EDID buffer is not valid. + */ +static unsigned char edidCalculateChecksum( + unsigned char *pEDIDBuffer +) +{ + unsigned char version, revision, checksum; + unsigned short index; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + checksum = 0; + if (version == 1) + { + for (index = 0; index < 128; index++) + checksum += pEDIDBuffer[index]; + } + + return checksum; +} + +/* + * edidGetExtension + * This function gets the number of (optional) EDID extension blocks to follow + * the given EDID buffer. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * Total number of EDID Extension to follow the given EDID buffer. + */ +unsigned char edidGetExtension( + unsigned char *pEDIDBuffer +) +{ + unsigned char version, revision; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + if (version == 1) + return ((edid_version_1_t *)pEDIDBuffer)->extFlag; + + return 0; +} + +#define EDID_TOTAL_RETRY_COUNTER 4 +/* + * edidReadMonitor + * This function reads the EDID structure from the attached monitor + * + * Input: + * displayPath - Display device which EDID to be read from. + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * bufferSize - The EDID Buffer size index (usually 128-bytes) + * edidExtNo - Extension Index of the EDID Structure to be read + * sclGpio - GPIO pin used as the I2C Clock (SCL) + * sdaGpio - GPIO pin used as the I2C Data (SDA) + * + * Output: + * 0 - Success + * -1 - Fail + */ +_X_EXPORT int32_t ddk750_edidReadMonitorEx( + disp_path_t displayPath, + unsigned char *pEDIDBuffer, + uint32_t bufferSize, + unsigned char edidExtNo, + unsigned char sclGpio, + unsigned char sdaGpio +) +{ + unsigned char value, retry, edidVersion, edidRevision; + unsigned char edidBuffer[256]; + uint32_t offset; + + /* Initialize the i2c bus */ +#if USE_HW_I2C == 1 + hwI2CInit(1);//use fast mode +#else + swI2CInit(sclGpio, sdaGpio); +#endif + for (retry = 0; retry < EDID_TOTAL_RETRY_COUNTER; retry++) + { + + /* Read the EDID from the monitor. */ + for (offset = 0; offset < TOTAL_EDID_REGISTERS; offset++) +#if USE_HW_I2C == 1 + edidBuffer[offset] = hwI2CReadReg(EDID_DEVICE_I2C_ADDRESS, (unsigned char)offset); +#else + edidBuffer[offset] = swI2CReadReg(EDID_DEVICE_I2C_ADDRESS, (unsigned char)offset); +#endif + /* Check if the EDID is valid. */ + edidVersion = edidGetVersion((unsigned char *)&edidBuffer, (unsigned char *)&edidRevision); + if (edidVersion != 0) + break; + } + + /* + * The monitor might not be DDC2B compliance. Therefore, need to use DDC1 protocol, + * which uses the Vertical Sync to clock in the EDID data. + * Currently this function return error. DDC1 protocol can be added later. + */ + if (retry == EDID_TOTAL_RETRY_COUNTER) + { + /* DDC1 uses the SDA line to transmit 9 bit data per byte. The last bit is + * only an acknowledge flag, which could be high or low. However, SCL line + * is not used. Instead the data is clock-in using vertical sync. + */ + return (-1); + } + + /* Copy the data to the given buffer */ + if (pEDIDBuffer != (unsigned char *)0) + { + for (offset = 0; offset < bufferSize; offset++) + pEDIDBuffer[offset] = edidBuffer[offset]; + } + +#if 0 /*def DDKDEBUG*/ + for (offset = 0; offset < TOTAL_EDID_REGISTERS; offset++) + { + if ((offset % 16) == 0) + { + if (offset != 0) + DDKDEBUGPRINT((0/*DISPLAY_LEVEL*/, "\n")); + DDKDEBUGPRINT((0/*DISPLAY_LEVEL*/, "%02x:\t", offset)); + } + DDKDEBUGPRINT((0/*DISPLAY_LEVEL*/, "%02x ", pEDIDBuffer[offset])); + } + DDKDEBUGPRINT((0/*DISPLAY_LEVEL*/, "\n")); +#endif + + return 0; +} + +/* + * edidReadMonitor + * This function reads the EDID structure from the attached monitor + * + * Input: + * displayPath - Display device which EDID to be read from. + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * bufferSize - The EDID Buffer size index (usually 128-bytes) + * edidExtNo - Extension Index of the EDID Structure to be read + * + * Output: + * 0 - Success + * -1 - Fail + */ +_X_EXPORT int32_t edidReadMonitor( + disp_path_t displayPath, + unsigned char *pEDIDBuffer, + uint32_t bufferSize, + unsigned char edidExtNo +) +{ + return ddk750_edidReadMonitorEx(displayPath, pEDIDBuffer, bufferSize, edidExtNo, DEFAULT_I2C_SCL, DEFAULT_I2C_SDA); +} + + +_X_EXPORT int32_t edidReadMonitorEx_software( + disp_path_t displayPath, + unsigned char *pEDIDBuffer, + uint32_t bufferSize, + unsigned char edidExtNo, + unsigned char sclGpio, + unsigned char sdaGpio +) +{ + unsigned char value, retry, edidVersion, edidRevision; + unsigned char edidBuffer[256]; + uint32_t offset; + + /* Initialize the i2c bus */ + swI2CInit(sclGpio, sdaGpio); + for (retry = 0; retry < EDID_TOTAL_RETRY_COUNTER; retry++) + { + + /* Read the EDID from the monitor. */ + for (offset = 0; offset < TOTAL_EDID_REGISTERS; offset++){ + edidBuffer[offset] = swI2CReadReg(EDID_DEVICE_I2C_ADDRESS, (unsigned char)offset); + } + + /* Check if the EDID is valid. */ + edidVersion = edidGetVersion((unsigned char *)&edidBuffer, (unsigned char *)&edidRevision); + if (edidVersion != 0) + break; + } + + /* + * The monitor might not be DDC2B compliance. Therefore, need to use DDC1 protocol, + * which uses the Vertical Sync to clock in the EDID data. + * Currently this function return error. DDC1 protocol can be added later. + */ + if (retry == EDID_TOTAL_RETRY_COUNTER) + { + /* DDC1 uses the SDA line to transmit 9 bit data per byte. The last bit is + * only an acknowledge flag, which could be high or low. However, SCL line + * is not used. Instead the data is clock-in using vertical sync. + */ + return (-1); + } + + /* Copy the data to the given buffer */ + if (pEDIDBuffer != (unsigned char *)0) + { + for (offset = 0; offset < bufferSize; offset++) + pEDIDBuffer[offset] = edidBuffer[offset]; + } + return 0; +} + + +/* + * edidGetEstablishedTiming + * This function gets the established timing list from the given EDID buffer, + * table, and timing index. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor (In) + * pEstTableIndex - Pointer to the Established Timing Table index (In/Out) + * pIndex - Pointer to the Establihsed Timing Index (In/Out) + * pWidth - Pointer to a variable that to store the horizontal active / width + * value of the retrieved timing (Out) + * pHeight - Pointer to a variable to store the vertical active / height + * value of the retrieved timing (Out) + * pRefreshRate - Pointer to a variable to store the vertical frequency value + * of the retrieved timing (out) + * pSource - Pointer to a variable to store the standard timing source: + * 0 - VESA + * 1 - IBM + * 2 - Apple + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetEstablishedTiming( + unsigned char *pEDIDBuffer, + /*unsigned char *pEstTableIndex,*/ + unsigned char *pIndex, + uint32_t *pWidth, + uint32_t *pHeight, + uint32_t *pRefreshRate, + unsigned char *pSource +) +{ + unsigned char version, revision; + unsigned char tableIndex, index; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + if (version == 1) + { + edid_version_1_t *pEDIDStructure; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + + while (1) + { + /* Get index */ + index = *pIndex; + + if (index > 16) + break; + + /* Search Established Table index 0 when the index is less than 8 */ + tableIndex = index / 8; + + /* Exit the function when it has reached the last table. */ + if (tableIndex > 2) + break; + + /* Increment the index value and update the index accordingly */ + (*pIndex)++; + index %= 8; + + /* Check */ + if ((pEDIDStructure->estTiming[tableIndex] & (1 << index)) != 0) + { + if (pWidth != (uint32_t *)0) + *pWidth = establishTiming[tableIndex][index].x; + + if (pHeight != (uint32_t *)0) + *pHeight = establishTiming[tableIndex][index].y; + + if (pRefreshRate != (uint32_t *)0) + *pRefreshRate = establishTiming[tableIndex][index].hz; + + if (pSource != (unsigned char *)0) + *pSource = establishTiming[tableIndex][index].source; + + /* Return success */ + return 0; + } + } + } + else + { + /* EDID Structure Version 2.0. */ + } + + return (-1); +} + +/* + * edidCalculateStdTiming + * This function calculates the width, height, and vertical frequency values + * from the given Standard Timing structure. This function only applies to + * EDID structure version 1. It will give the wrong result when used with + * EDID version 2. + * + * Input: + * pStdTiming - Pointer to a standard timing structure that contains the + * standard timing value to be calculated (In) + * edid1Revision - Revision of the EDID 1 (In) + * pWidth - Pointer to a variable that to store the horizontal active / width + * value of the retrieved timing (Out) + * pHeight - Pointer to a variable to store the vertical active / height + * value of the retrieved timing (Out) + * pRefreshRate - Pointer to a variable to store the vertical frequency value + * of the retrieved timing (out) + * + * Output: + * 0 - Success + * -1 - Fail + */ +static int32_t edidCalculateStdTiming( + standard_timing_t *pStdTiming, + unsigned char edid1Revision, + uint32_t *pWidth, + uint32_t *pHeight, + uint32_t *pRefreshRate +) +{ + uint32_t x, y; + + /* Calculate the standard timing into x and y mode dimension */ + if (pStdTiming->horzActive != 0x01) + { + /* Calculate the X and Y */ + x = (pStdTiming->horzActive + 31) * 8; + switch (pStdTiming->stdTimingInfo.aspectRatio) + { + case 0: + if (edid1Revision != 3) + y = x; /* 1:1 aspect ratio (prior revision 1.3) */ + else + y = x * 10 / 16; /* 16:10 aspect ratio (revision 1.3) */ + break; + case 1: + y = x * 3 / 4; /* 4:3 aspect ratio */ + break; + case 2: + y = x * 4 / 5; /* 5:4 aspect ratio */ + break; + case 3: + y = x * 9 / 16; /* 16:9 aspect ratio */ + break; + } + + if (pWidth != (uint32_t *)0) + *pWidth = x; + + if (pHeight != (uint32_t *)0) + *pHeight = y; + + if (pRefreshRate != (uint32_t *)0) + *pRefreshRate = pStdTiming->stdTimingInfo.refreshRate + 60; + + return 0; + } + + return (-1); +} + +/* + * edidGetStandardTiming + * This function gets the standard timing from the given EDID buffer and + * calculates the width, height, and vertical frequency from that timing. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pStdTimingIndex - Pointer to a standard timing index to be retrieved + * pWidth - Pointer to a variable that to store the horizontal active / width + * value of the retrieved timing (Out) + * pHeight - Pointer to a variable to store the vertical active / height + * value of the retrieved timing (Out) + * pRefreshRate - Pointer to a variable to store the vertical frequency value + * of the retrieved timing (out) + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetStandardTiming( + unsigned char *pEDIDBuffer, + unsigned char *pStdTimingIndex, + uint32_t *pWidth, + uint32_t *pHeight, + uint32_t *pRefreshRate +) +{ + unsigned char version, revision, timingIndex, tableIndex; + uint32_t x, y, aspectRatio; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + if (version == 1) + { + edid_version_1_t *pEDIDStructure; + monitor_desc_t *pMonitorDescriptor; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + + while (1) + { + /* There are only 8 standard timing entries */ + if (*pStdTimingIndex > 7) + break; + + /* Get the table index first before incrementing the index. */ + timingIndex = *pStdTimingIndex; + + /* Increment the standard timing index */ + (*pStdTimingIndex)++; + + if (timingIndex < 8) + { + /* + * Search the first Standard Timing Identifier table + */ + + /* Calculate the standard timing into x and y mode dimension */ + if (edidCalculateStdTiming(&pEDIDStructure->stdTiming[timingIndex], + revision, pWidth, pHeight, pRefreshRate) == 0) + { + return 0; + } + } + else + { + /* + * Search Standard Timing Identifier Table in the detailed Timing block. + */ + + /* + * Each Detailed Timing Identifier can contains 6 entries of Standard Timing + * Identifier. Based on this value, we can get the Detailed Timing Table Index + * that contains the requested standard timing. + */ + timingIndex = timingIndex - 8; + for (tableIndex = 0; tableIndex < 4; tableIndex++) + { + /* Get detailed info */ + pMonitorDescriptor = &pEDIDStructure->miscInformation.monitorDesc[tableIndex]; + if ((pMonitorDescriptor->flag1 == 0) && (pMonitorDescriptor->flag2 == 0) && + (pMonitorDescriptor->dataTypeTag == 0xFA)) + { + if (timingIndex >= 6) + { + timingIndex-=6; + continue; + } + else + { + if (edidCalculateStdTiming(&pMonitorDescriptor->descriptor.stdTimingExt.stdTiming[timingIndex], + revision, pWidth, pHeight, pRefreshRate) == 0) + { + return 0; + } + } + } + } + } + } + } + else + { + /* EDID Structure version 2 */ + } + + return (-1); +} + +/* + * edidGetDetailedTiming + * This function gets the detailed timing from the given EDID buffer. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pDetailedTimingIndex - Pointer to a detailed timing index to be retrieved + * pModeParameter - Pointer to a mode_parameter_t structure that will be + * filled with the detailed timing. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetDetailedTiming( + unsigned char *pEDIDBuffer, + unsigned char *pDetailedTimingIndex, + vdif_t *pVDIF +) +{ + unsigned char version, revision, tableIndex; + uint32_t x, y, aspectRatio; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + if (version == 1) + { + edid_version_1_t *pEDIDStructure; + detailed_timing_t *pDetailedTiming; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + + while (1) + { + if (*pDetailedTimingIndex > 3) + break; + + /* Get the Detail Timing entry index */ + tableIndex = *pDetailedTimingIndex; + + /* Increment the index */ + (*pDetailedTimingIndex)++; + + /* Get detailed info */ + pDetailedTiming = &pEDIDStructure->miscInformation.detailTiming[tableIndex]; + if ((pDetailedTiming->pixelClock != 0) && (pVDIF != (vdif_t *)0)) + { + /* Translate the Detail timing to VDIF format. */ + pVDIF->pixelClock = (uint32_t)pDetailedTiming->pixelClock * 10000; + pVDIF->characterWidth = 8; + pVDIF->scanType = (pDetailedTiming->flags.interlaced == 0) ? VDIF_NONINTERLACED : VDIF_INTERLACED; + + pVDIF->horizontalActive = + ((uint32_t)pDetailedTiming->horzActiveBlanking.horzActiveMSB << 8) + + (uint32_t)pDetailedTiming->horzActive; + pVDIF->horizontalBlankStart = pVDIF->horizontalActive; + pVDIF->horizontalBlankTime = + ((uint32_t)pDetailedTiming->horzActiveBlanking.horzBlankingMSB << 8) + + (uint32_t)pDetailedTiming->horzBlanking; + pVDIF->horizontalTotal = pVDIF->horizontalActive + pVDIF->horizontalBlankTime; + pVDIF->horizontalFrontPorch = + ((uint32_t)pDetailedTiming->syncAuxInfo.horzSyncOffset << 8) + + (uint32_t)pDetailedTiming->horzSyncOffset; + pVDIF->horizontalSyncStart = pVDIF->horizontalBlankStart + pVDIF->horizontalFrontPorch; + pVDIF->horizontalSyncWidth = + ((uint32_t)pDetailedTiming->syncAuxInfo.horzSyncWidth << 8) + + (uint32_t)pDetailedTiming->horzSyncPulseWidth; + pVDIF->horizontalBackPorch = + pVDIF->horizontalBlankTime - (pVDIF->horizontalFrontPorch + pVDIF->horizontalSyncWidth); + pVDIF->horizontalFrequency = roundedDiv(pVDIF->pixelClock, pVDIF->horizontalTotal); + pVDIF->horizontalLeftBorder = 0; + pVDIF->horizontalRightBorder = 0; + + pVDIF->verticalActive = + ((uint32_t)pDetailedTiming->vertActiveBlanking.vertActiveMSB << 8) + + (uint32_t)pDetailedTiming->vertActive; + pVDIF->verticalBlankStart = pVDIF->verticalActive; + pVDIF->verticalBlankTime = + ((uint32_t)pDetailedTiming->vertActiveBlanking.vertBlankingMSB << 8) + + (uint32_t)pDetailedTiming->vertBlanking; + pVDIF->verticalTotal = pVDIF->verticalActive + pVDIF->verticalBlankTime; + pVDIF->verticalFrontPorch = + ((uint32_t)pDetailedTiming->syncAuxInfo.vertSyncOffset << 8) + + (uint32_t)pDetailedTiming->verticalSyncInfo.syncOffset; + pVDIF->verticalSyncStart = pVDIF->verticalBlankStart + pVDIF->verticalFrontPorch; + pVDIF->verticalSyncHeight = + ((uint32_t)pDetailedTiming->syncAuxInfo.vertSyncWidth << 8) + + (uint32_t)pDetailedTiming->verticalSyncInfo.syncWidth; + pVDIF->verticalBackPorch = + pVDIF->verticalBlankTime - (pVDIF->verticalFrontPorch + pVDIF->verticalSyncHeight); + pVDIF->verticalFrequency = + roundedDiv(pVDIF->pixelClock, (pVDIF->horizontalTotal * pVDIF->verticalTotal)); + pVDIF->verticalTopBorder = 0; + pVDIF->verticalBottomBorder = 0; + + if (pDetailedTiming->flags.connectionType == 3) + { + pVDIF->verticalSyncPolarity = + (pDetailedTiming->flags.vertSyncFlag == 1) ? VDIF_SYNC_POSITIVE : VDIF_SYNC_NEGATIVE; + pVDIF->horizontalSyncPolarity = + (pDetailedTiming->flags.horzSyncFlag == 1) ? VDIF_SYNC_POSITIVE : VDIF_SYNC_NEGATIVE; + } + else + { + pVDIF->verticalSyncPolarity = VDIF_SYNC_NEGATIVE; + pVDIF->horizontalSyncPolarity = VDIF_SYNC_NEGATIVE; + } + + /* For debugging purpose. */ + printVdif(pVDIF); + + return 0; + } + } + } + + return (-1); +} + +/* + * edidGetMonitorSerialNumber + * This function gets the monitor serial number from the EDID structure. + * Only EDID version 1 and revision 1 or above supports this feature. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pMonitorSerialNumber - Pointer to a buffer to store the serial number + * retrieved from the EDID + * bufferSize - The size of the buffer to store the serial number. + * The maximum size required is 13 bytes. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetMonitorSerialNumber( + unsigned char *pEDIDBuffer, + char *pMonitorSerialNumber, + unsigned char bufferSize +) +{ + unsigned char version, revision, tableIndex, charIndex; + + /* If no pointer is given or the buffer size is set to 0, then return fail. */ + if ((pMonitorSerialNumber == (char *)0) || (bufferSize == 0)) + return (-1); + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + if ((version == 1) && (revision > 0)) + { + edid_version_1_t *pEDIDStructure; + monitor_desc_t *pMonitorDescriptor; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + for (tableIndex = 0; tableIndex < 4; tableIndex++) + { + pMonitorDescriptor = &pEDIDStructure->miscInformation.monitorDesc[tableIndex]; + if ((pMonitorDescriptor->flag1 == 0) && (pMonitorDescriptor->flag2 == 0) && + (pMonitorDescriptor->dataTypeTag == 0xFF)) + { + bufferSize = (bufferSize > 13) ? 13 : bufferSize; + for (charIndex = 0; charIndex < 13; charIndex++) + { + if (pMonitorDescriptor->descriptor.serialNo[charIndex] == 0x0A) + { + pMonitorSerialNumber[charIndex] = '\0'; + break; + } + + pMonitorSerialNumber[charIndex] = pMonitorDescriptor->descriptor.serialNo[charIndex]; + } + + return 0; + } + } + } + + /* Serial Number is not found. */ + return (-1); +} + +/* + * edidGetDataString + * This function gets the data string from the EDID + * Only EDID version 1 and revision 1 or above supports this feature. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pMonitorSerialNumber - Pointer to a buffer to store the data string + * retrieved from the EDID + * bufferSize - The size of the buffer to store the data string + * The maximum size required is 13 bytes. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetDataString( + unsigned char *pEDIDBuffer, + char *pDataString, + unsigned char bufferSize +) +{ + unsigned char version, revision, tableIndex, charIndex; + + /* If no pointer is given or the buffer size is set to 0, then return fail. */ + if ((pDataString == (char *)0) || (bufferSize == 0)) + return (-1); + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + if ((version == 1) && (revision > 0)) + { + edid_version_1_t *pEDIDStructure; + monitor_desc_t *pMonitorDescriptor; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + for (tableIndex = 0; tableIndex < 4; tableIndex++) + { + pMonitorDescriptor = &pEDIDStructure->miscInformation.monitorDesc[tableIndex]; + if ((pMonitorDescriptor->flag1 == 0) && (pMonitorDescriptor->flag2 == 0) && + (pMonitorDescriptor->dataTypeTag == 0xFE)) + { + bufferSize = (bufferSize > 13) ? 13 : bufferSize; + for (charIndex = 0; charIndex < 13; charIndex++) + { + if (pMonitorDescriptor->descriptor.dataString[charIndex] == 0x0A) + { + pDataString[charIndex] = '\0'; + break; + } + + pDataString[charIndex] = pMonitorDescriptor->descriptor.dataString[charIndex]; + } + + return 0; + } + } + } + + /* Data String is not found. */ + return (-1); +} + +/* + * edidGetMonitorRangeLimit + * This function gets the monitor range limits from the EDID structure. + * Only EDID version 1 revision 1 or above supports this feature. + * This is a required field in EDID Version 1.3 + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pMinVerticalRate - Pointer to a variable to store the Minimum Vertical Rate (Hz) + * pMaxVerticalRate - Pointer to a variable to store the Maximum Vertical Rate (Hz) + * pMinHorzFreq - Pointer to a variable to store the Minimum Horz. Freq (kHz) + * pMaxHorzFreq - Pointer to a variable to store the Maximum Horz. Freq (kHz) + * pMaxPixelClock - Pointer to a variable to store the Maximum Pixel Clock (Hz) + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetMonitorRangeLimit( + unsigned char *pEDIDBuffer, + unsigned char *pMinVerticalRate, + unsigned char *pMaxVerticalRate, + unsigned char *pMinHorzFreq, + unsigned char *pMaxHorzFreq, + uint32_t *pMaxPixelClock +) +{ + unsigned char version, revision, tableIndex, charIndex; + + if (pEDIDBuffer == (unsigned char *)0) + return (-1); + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + if ((version == 1) && (revision > 0)) + { + edid_version_1_t *pEDIDStructure; + monitor_desc_t *pMonitorDescriptor; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + + for (tableIndex = 0; tableIndex < 4; tableIndex++) + { + pMonitorDescriptor = &pEDIDStructure->miscInformation.monitorDesc[tableIndex]; + if ((pMonitorDescriptor->flag1 == 0) && (pMonitorDescriptor->flag2 == 0) && + (pMonitorDescriptor->dataTypeTag == 0xFD) && (pMonitorDescriptor->flag3 == 0)) + { + if (pMinVerticalRate != (unsigned char *)0) + *pMinVerticalRate = pMonitorDescriptor->descriptor.monitorRange.minVertRate; + + if (pMaxVerticalRate != (unsigned char *)0) + *pMaxVerticalRate = pMonitorDescriptor->descriptor.monitorRange.maxVertRate; + + if (pMinHorzFreq != (unsigned char *)0) + *pMinHorzFreq = pMonitorDescriptor->descriptor.monitorRange.minHorzFrequency; + + if (pMaxHorzFreq != (unsigned char *)0) + *pMaxHorzFreq = pMonitorDescriptor->descriptor.monitorRange.maxHorzFrequency; + + if (pMaxPixelClock != (uint32_t *)0) + *pMaxPixelClock = (uint32_t) pMonitorDescriptor->descriptor.monitorRange.maxPixelClock * 10 * 1000000; + + return 0; + } + } + } + + /* Data String is not found. */ + return (-1); +} + +/* + * edidGetSecondaryTimingSupport + * This function gets the secondary GTF timing support. + * Only EDID version 1 and revision 1 or above supports this feature. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pStartFrequency - Pointer to a variable to store the start frequency of + * the secondary GTF + * pOffset - Pointer to a variable to store the Offset (C) value of + * the secondary GTF + * pGradient - Pointer to a variable to store the Gradient (M) value of + * the secondary GTF + * pScalingFactor - Pointer to a variable to store the Scaling Factor (K) + * value of the secondary GTF + * pScalingFactorWeight - Pointer to a variable to store the Scaling Factore Weight (J) + * value of the secondary GTF + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetSecondaryTimingSupport( + unsigned char *pEDIDBuffer, + unsigned short *pStartFrequency, + unsigned char *pOffset, + unsigned short *pGradient, + unsigned char *pScalingFactor, + unsigned char *pScalingFactorWeight +) +{ + unsigned char version, revision, tableIndex, charIndex; + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + if ((version == 1) && (revision > 0) && (pEDIDBuffer != (unsigned char *)0)) + { + edid_version_1_t *pEDIDStructure; + monitor_desc_t *pMonitorDescriptor; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + for (tableIndex = 0; tableIndex < 4; tableIndex++) + { + pMonitorDescriptor = &pEDIDStructure->miscInformation.monitorDesc[tableIndex]; + if ((pMonitorDescriptor->flag1 == 0) && (pMonitorDescriptor->flag2 == 0) && + (pMonitorDescriptor->dataTypeTag == 0xFD) && + (pMonitorDescriptor->descriptor.monitorRange.secondaryTimingFlag == 0x02)) + { + if (pStartFrequency != (unsigned short *)0) + *pStartFrequency = (unsigned short) + pMonitorDescriptor->descriptor.monitorRange.secondaryTimingInfo.cmkjParam.startFrequency * 2 * 1000; + + if (pOffset != (unsigned char *)0) + *pOffset = pMonitorDescriptor->descriptor.monitorRange.secondaryTimingInfo.cmkjParam.cParam/2; + + if (pGradient != (unsigned short *)0) + *pGradient = pMonitorDescriptor->descriptor.monitorRange.secondaryTimingInfo.cmkjParam.mParam; + + if (pScalingFactor != (unsigned char *)0) + *pScalingFactor = pMonitorDescriptor->descriptor.monitorRange.secondaryTimingInfo.cmkjParam.kParam; + + if (pScalingFactorWeight != (unsigned char *)0) + *pScalingFactorWeight = pMonitorDescriptor->descriptor.monitorRange.secondaryTimingInfo.cmkjParam.jParam / 2; + + return 0; + } + } + } + + /* Data String is not found. */ + return (-1); +} + +/* + * edidGetMonitorName + * This function gets the monitor name from the EDID structure. + * This is a required field in EDID Version 1.3 + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pMonitorName - Pointer to a buffer to store the monitor name + * retrieved from the EDID + * bufferSize - The size of the buffer to store the monitor name + * The maximum size required is 13 bytes. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetMonitorName( + unsigned char *pEDIDBuffer, + char *pMonitorName, + unsigned char bufferSize +) +{ + unsigned char version, revision, tableIndex, charIndex; + + /* If no pointer is given or the buffer size is set to 0, then return fail. */ + if ((pMonitorName == (char *)0) || (bufferSize == 0)) + return (-1); + + /* Get EDID Version and revision */ + version = edidGetVersion(pEDIDBuffer, &revision); + + if (version == 1) + { + edid_version_1_t *pEDIDStructure; + monitor_desc_t *pMonitorDescriptor; + + /* EDID Structure Version 1. */ + pEDIDStructure = (edid_version_1_t *)pEDIDBuffer; + for (tableIndex = 0; tableIndex < 4; tableIndex++) + { + pMonitorDescriptor = &pEDIDStructure->miscInformation.monitorDesc[tableIndex]; + if ((pMonitorDescriptor->flag1 == 0) && (pMonitorDescriptor->flag2 == 0) && + (pMonitorDescriptor->dataTypeTag == 0xFC) && (pMonitorDescriptor->flag3 == 0)) + { + bufferSize = (bufferSize > 13) ? 13 : bufferSize; + for (charIndex = 0; charIndex < 13; charIndex++) + { + if (pMonitorDescriptor->descriptor.monitorName[charIndex] == 0x0A) + { + pMonitorName[charIndex] = '\0'; + break; + } + + pMonitorName[charIndex] = pMonitorDescriptor->descriptor.monitorName[charIndex]; + } + + return 0; + } + } + } + + /* Data String is not found. */ + return (-1); +} + +/* + * edidGetPreferredTiming + * This function gets the preferred/native timing of the monitor + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pWidth - Pointer to an uint32_t buffer to store the width + * of the preferred (native) timing. + * pHeight - Pointer to an uint32_t buffer to store the height + * of the preferred (native) timing. + * pVerticalFrequency - Pointer to an uint32_t buffer to store the refresh + * rate of the preferred (native) timing. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetPreferredTiming( + unsigned char *pEDIDBuffer, + uint32_t *pWidth, + uint32_t *pHeight, + uint32_t *pVerticalFrequency +) +{ + unsigned char index = 0; + vdif_t vdifBuffer; + +/* Disable this checking since some old monitor does have the Detailed Timing although the preferred timing flag is 0. */ +#if 0 + /* Check if preferred timing is available */ + if (edidIsPreferredTimingAvailable(pEDIDBuffer) == 1) +#endif + { + /* The preferred (native) timing is available, so get the timing. It is located + at the first index of detailed timing. + */ + if (edidGetDetailedTiming(pEDIDBuffer, &index, &vdifBuffer) == 0) + { + if (pWidth != (uint32_t *)0) + *pWidth = vdifBuffer.horizontalActive; + + if (pHeight != (uint32_t *)0) + *pHeight = vdifBuffer.verticalActive; + + if (pVerticalFrequency != (uint32_t *)0) + *pVerticalFrequency = vdifBuffer.verticalFrequency; + + return 0; + } + } + + return (-1); +} diff --git a/src/ddk750/ddk750_edid.h b/src/ddk750/ddk750_edid.h new file mode 100644 index 0000000..7be9303 --- /dev/null +++ b/src/ddk750/ddk750_edid.h @@ -0,0 +1,1083 @@ +/******************************************************************* +* +* Copyright (c) 2009 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* edid.h --- SMI DDK +* This file contains the EDID structure and function API to +* interpret the EDID +* +*******************************************************************/ +#ifndef _SMI_EDID_H_ +#define _SMI_EDID_H_ + + +#include "ddk750_display.h" + + + + + +/******************************************************************* +* The following contains the video display information format structure +* come from vdif.h --- SMI DDK +*******************************************************************/ + + +/* Sync polarity */ +typedef enum _vdif_sync_polarity_t +{ + VDIF_SYNC_NEGATIVE = 0, + VDIF_SYNC_POSITIVE +} vdif_sync_polarity_t; + +/* Scan type */ +typedef enum _vdif_scan_type_t +{ + VDIF_NONINTERLACED = 0, + VDIF_INTERLACED +} vdif_scan_type_t; + +/* Monitor Timing Information */ +typedef struct _video_display_information_format_t +{ + uint32_t pixelClock; + uint32_t characterWidth; + vdif_scan_type_t scanType; + + uint32_t horizontalFrequency; + vdif_sync_polarity_t horizontalSyncPolarity; + uint32_t horizontalTotal; + uint32_t horizontalActive; + uint32_t horizontalBlankStart; + uint32_t horizontalBlankTime; + uint32_t horizontalSyncStart; + uint32_t horizontalRightBorder; + uint32_t horizontalFrontPorch; + uint32_t horizontalSyncWidth; + uint32_t horizontalBackPorch; + uint32_t horizontalLeftBorder; + + uint32_t verticalFrequency; + vdif_sync_polarity_t verticalSyncPolarity; + uint32_t verticalTotal; + uint32_t verticalActive; + uint32_t verticalBlankStart; + uint32_t verticalBlankTime; + uint32_t verticalSyncStart; + uint32_t verticalBottomBorder; + uint32_t verticalFrontPorch; + uint32_t verticalSyncHeight; + uint32_t verticalBackPorch; + uint32_t verticalTopBorder; +} vdif_t; + +/* Set the alignment to 1-bit aligned. Otherwise, it can't get the EDID correctly. */ +#pragma pack(1) + +/* Standard Timing Structure */ +typedef struct _standard_timing_t +{ + unsigned char horzActive; /* (Horizontal active pixels / 8 ) - 31 */ + struct + { + unsigned char refreshRate:6; /* Refresh Rate (Hz) - 60; Range 60 --> 123 */ + unsigned char aspectRatio:2; /* Aspect Ratio: + Bit 7 Bit 6 Operation + 0 0 1:1 (prior Version 1.3) + 0 0 16:10 (Version 1.3) + 0 1 4:3 + 1 0 5:4 + 1 1 16:9 + */ + } stdTimingInfo; +} standard_timing_t; + +/* Detailed Timing Description Structure */ +typedef struct _detailed_timing_t +{ + unsigned short pixelClock; + unsigned char horzActive; + unsigned char horzBlanking; + struct + { + unsigned char horzBlankingMSB:4; + unsigned char horzActiveMSB:4; + } horzActiveBlanking; + unsigned char vertActive; + unsigned char vertBlanking; + struct + { + unsigned char vertBlankingMSB:4; + unsigned char vertActiveMSB:4; + } vertActiveBlanking; + unsigned char horzSyncOffset; + unsigned char horzSyncPulseWidth; + struct + { + unsigned char syncWidth:4; + unsigned char syncOffset:4; + } verticalSyncInfo; + struct + { + unsigned char vertSyncWidth:2; + unsigned char vertSyncOffset:2; + unsigned char horzSyncWidth:2; + unsigned char horzSyncOffset:2; + } syncAuxInfo; + unsigned char horzImageSize; + unsigned char vertImageSize; + struct + { + unsigned char vertImageSizeMSB:4; + unsigned char horzImageSizeMSB:4; + } horzVertImageSize; + unsigned char horzBorder; + unsigned char vertBorder; + struct + { + unsigned char interleaved:1; + unsigned char horzSyncFlag:1; + unsigned char vertSyncFlag:1; + unsigned char connectionType:2; + unsigned char stereo:2; + unsigned char interlaced:1; + } flags; +} detailed_timing_t; + +typedef struct _color_point_t +{ + unsigned char whitePointIndex; + struct + { + unsigned char whiteYLowBits:2; + unsigned char whiteXLowBits:2; + unsigned char reserved:4; + } whiteLowBits; + unsigned char whiteX; + unsigned char whiteY; + unsigned char gamma; +} color_point_t; + +typedef struct _monitor_desc_t +{ + unsigned short flag1; /* Flag = 0000h when block used as descriptor */ + unsigned char flag2; /* Flag = 00h when block used as descriptor */ + unsigned char dataTypeTag; /* Data type tag: + FFh: Monitor Serial Number - Stored as ASCII, + code page #437, <= 13bytes + FEh: ASCII String - Stored as ASCII, code + page #437, <= 13 bytes + FDh: Monitor range limits, binary coded + FCh: Monitor name, stored as ASCII, code page #437 + FBh: Descriptor contains additional color point data + FAh: Descriptor contains additional Standard Timing + Identifications + F9h-11h: Currently undefined + 10h: Dummy descriptor, used to indicate + that the descriptor space is unused + 0Fh-00h: Descriptor defined by manufacturer. + */ + unsigned char flag3; /* Flag = 00h when block used as descriptor */ + union + { + unsigned char serialNo[13]; + unsigned char dataString[13]; + struct + { + unsigned char minVertRate; + unsigned char maxVertRate; + unsigned char minHorzFrequency; + unsigned char maxHorzFrequency; + unsigned char maxPixelClock; /* Binary coded clock rate in MHz / 10 + Max Pixel Clock those are not a multiple of 10MHz + is rounded up to a multiple of 10MHz + */ + unsigned char secondaryTimingFlag; /* 00h = No secondary timing formula supported + (Support for default GTF indicated in feature byte) + 02h = Secondary GTF curve supported + All other = Reserved for future timing formula + definitions. + */ + union + { + unsigned char constantStr[7]; + struct + { + unsigned char reserved; + unsigned char startFrequency; + unsigned char cParam; + unsigned short mParam; + unsigned char kParam; + unsigned char jParam; + } cmkjParam; + } secondaryTimingInfo; + } monitorRange; + + unsigned char monitorName[13]; + struct + { + color_point_t white[2]; + unsigned char reserved[3]; /* Set to (0Ah, 20h, 20h)*/ + } colorPoint; + + struct + { + standard_timing_t stdTiming[6]; + unsigned char reserved; /* Set to 0Ah */ + } stdTimingExt; + + unsigned char manufactureSpecifics[13]; + } descriptor; +} +monitor_desc_t; + +/* EDID Structuve Version 1. Within version 1 itself, there are 4 revisions mentioned + below: + - EDID 1.0: The original 128-byte data format + - EDID 1.1: Added definitions for monitor descriptors as an alternate use of the space + originally reserved for detailed timings, as well as definitions for + previously unused fields. + - EDID 1.2: Added definitions to existing data fields. + - EDID 1.3: Added definitions for secondary GTF curve coefficients. This is the new + baseline for EDID data structures, which is recommended for all new monitor + designs. + */ +typedef struct _edid_version_1_t +{ + /* Header (8 bytes) */ + unsigned char header[8]; /* Header */ + + /* Vendor / Product ID (10 bytes) */ + unsigned short manufacturerID; /* Manufacture Identification */ + unsigned short productCode; /* Product code Identification */ + uint32_t serialNumber; /* Serial Number */ + unsigned char weekOfManufacture; /* Week of Manufacture */ + unsigned char yearOfManufacture; /* Year of Manufacture */ + + /* EDID Structure version / revision (2 bytes) */ + unsigned char version; /* EDID Structure Version no. */ + unsigned char revision; /* Revision Version no. */ + + /* Basic Display Parameters / Features (5 bytes) */ + union + { + struct + { + unsigned char vsyncSerration:1; + unsigned char syncOnGreenSupport:1; + unsigned char compositeSyncSupport:1; + unsigned char separateSyncSupport:1; + unsigned char blank2Black:1; + unsigned char signalLevelStd:2; + unsigned char inputSignal:1; /* Input Signal: Analog = 0, Digital = 1 */ + } analogSignal; + struct + { + unsigned char dfp1Support:1; + unsigned char reserved:6; + unsigned char inputSignal:1; /* Input Signal: Analog = 0, Digital = 1 */ + } digitalSignal; + } videoInputDefinition; /* Video Input Definition */ + + unsigned char maxHorzImageSize; /* Maximum Horizontal Image Size */ + unsigned char maxVertImageSize; /* Maximum Vertical Image Size */ + unsigned char displayTransferChar; /* Display Transfer Characteristic (Gamma) */ + struct + { + unsigned char defaultGTFSupport:1; /* Support timings based on the GTF standard using + default GTF parameters + */ + unsigned char preferredTiming:1; /* If set, the display's preferred timing mode is + indicated in the first detailed timing block. + */ + unsigned char sRGBSupport:1; /* If set, the display uses the sRGB standard + default color space as its primary color space + */ + unsigned char displayType:2; /* Display Type: + 00 - Monochrome / Grayscale display + 01 - RGB Color Display + 10 - Non-RGB multicolor display, e.g. R/G/Y + 11 - Undefined + */ + unsigned char lowPowerSupport:1; /* If set, the display consumes much less power when + it receives a timing signal outside its active + operating range. It will revert to normal if the + timing returns to the normal operating range. + */ + unsigned char suspendSupport:1; /* Support Suspend as defined in VESA DPMS spec. */ + unsigned char standbySupport:1; /* Support Standby as defined in VESA DPMS spec. */ + } featureSupport; /* Feature Support */ + + /* Color Characteristics (10 bytes) */ + struct + { + unsigned char greenYLowBits:2; + unsigned char greenXLowBits:2; + unsigned char redYLowBits:2; + unsigned char redXLowBits:2; + } redGreenLowBits; /* Red/Green Low Bits */ + struct + { + unsigned char whiteYLowBits:2; + unsigned char whiteXLowBits:2; + unsigned char blueYLowBits:2; + unsigned char blueXLowBits:2; + } blueWhiteLowBits; /* Blue/White Low Bits */ + unsigned char redX; /* Red-x bits 9-2 */ + unsigned char redY; /* Red-y bits 9-2 */ + unsigned char greenX; /* Green-x bits 9-2 */ + unsigned char greenY; /* Green-y bits 9-2 */ + unsigned char blueX; /* Blue-x bits 9-2 */ + unsigned char blueY; /* Blue-y bits 9-2 */ + unsigned char whiteX; /* White-x bits 9-2 */ + unsigned char whiteY; /* White-y bits 9-2 */ + + /* Established Timings (3 bytes) */ + unsigned char estTiming[3]; /* Established Timings */ + + /* Standard Timing Identification (16 bytes) */ + standard_timing_t stdTiming[8]; /* Standard Timings Identification */ + + /* Detailed Timing Descriptions (72 bytes) */ + union + { + detailed_timing_t detailTiming[4]; /* Detailed Timing Descriptor */ + monitor_desc_t monitorDesc[4]; /* Monitor descriptor */ + } miscInformation; + + /* Extension Flag (1 byte) */ + unsigned char extFlag; /* Number of (optional) 1280byte EDID + extension blocks to follow. + */ + + /* Checksum (1 byte) */ + unsigned char checksum; /* The 1-byte sum of all 128 bytes in + this EDID block shall equal zero. + */ +} +edid_version_1_t; + +#if 0 /* Temporary on hold. To be completed later. */ + +/* EDID Version 2.0. Not widely used. Usually defined for displays that follow + the original VESA Plug & Display (P&D) and Flat Panel Display Interface-2 (FPDI-2) + Standards + */ +typedef struct _edid_version_2_t +{ + /* + * EDID Structure Version/Revision (1 byte) + */ + unsigned char version:4; + unsigned char revision:4; + + /* + * Vendor / Product ID (7 bytes) + */ + unsigned short manufacturerID; /* ID Manufacturer Name */ + unsigned short productID; /* ID Product Code */ + unsigned char manufactureWeek; /* Week of Manufacture */ + unsigned short manufactureYear; /* Year of Manufacture */ + + /* + * Manufacturer/Product ID string (32 bytes) + */ + unsigned char productName; /* This string is compiresed of both manufacture name + and model name, which are separated using ASCII code 09h. + If the entire string is <32 bytes, then it is terminated + with ASCII code 0Ah and the field is padded with ASCII + code 20h + */ + + /* + * Serial number string (16 bytes) + */ + unsigned char serianNumber[16]; /* Serial number string. If <16 bytes then the string is + terminated with ASCII code 0Ah and the field padded + with ASCII code 20h + */ + + /* + * Unused/Reserved (8 bytes) + */ + unsigned char reserved[8]; + + /* + * Display Interface Parameters (15 bytes) + */ + unsigned char secondaryPhysicalIF:4; /* Look at defaultPhysicalIF description above. */ + unsigned char defaultPhysicalIF:4; /* Physical Connector Types. Consists of 2 fields. Bit 7-4 + indicates the connector for the default interface. If + a secondary interface is available, its connector is + indicated using bit 3-0. Both fields value description + is listed below: + 0 = None (Not valid for default connector) + 1 = BNC + 2 = 15 pin VGA + 3 = 13w3 + 4 = VESA EVC + 5 = VESA P&D-D + 6 = Micro-ribbon Connector (per the VESA P&D standard) + 7 = IEEE-1394 connector + 8 = VESA FPDI-2 + 9-E = Reserved + F = Non-standard connector + */ + unsigned char secondaryVideoIF:4; /* Look at the defaultVideoIF description above. */ + unsigned char defaultVideoIF:4; /* Video Interface Types. Consists of 2 fields. Bit 7-4 + defines the default video interface. Bit 3-0 defines + the secondary interface. Descriptions of the field is + listed below: + 0 = None (Not valid for default interface) + 1 = Analog + 2 = Analog w/ sampled pixel clock + 3 = TMDS (Transition Minimized Differential Signaling) + 4 = IEEE-1394-1995 + 5 = LVDS + 6 = Parallel + 7-F = Reserved + */ + unsigned char analogIFDataFormat[4]; /* Analog Interface Data Format */ + unsigned char digitalIFDataFormat[4]; /* Digital Interface Data Format */ + unsigned char secondaryColorEncodingIF:4; /* Secondary Color Encoding Interface */ + unsigned char defaultColorEncodingIF:4; /* Color Encoding default Interface */ + unsigned char primarySubChannel1:4; /* Supported bit-depth of sub-channel 1 ("Green") + of the Primary interface. */ + unsigned char primarySubChannel0:4; /* Supported bit-depth of sub-channel 0 ("Red") + of the Primary interface. */ + unsigned char primarySubChannel3:4; /* Supported bit-depth of sub-channel 3 of the + Primary interface. */ + unsigned char primarySubChannel2:4; /* Supported bit-depth of sub-channel 2 ("Blue") + of the Primary interface. */ + unsigned char secondarySubChannel1:4; /* Supported bit-depth of sub-channel 1 ("Green") + of the Secondary interface. */ + unsigned char secondarySubChannel0:4; /* Supported bit-depth of sub-channel 0 ("Red") + of the Secondary interface. */ + unsigned char secondarySubChannel3:4; /* Supported bit-depth of sub-channel 3 of the + Secondary interface. */ + unsigned char secondarySubChannel2:4; /* Supported bit-depth of sub-channel 2 ("Blue") + of the Secondary interface. */ + + /* + * Display Device Description (5 bytes) + */ + unsigned char displayType; /* Display technology type/subtype*/ + unsigned char displayCharacteristic; /* Major display characteristics. */ + unsigned char featureSupport[3]; /* Feature Support */ + + /* + * Display Response Time (2 bytes) + */ + unsigned char riseTimeResponse:4; /* Rise time response in seconds */ + unsigned char riseTimeExponent:4; /* Rise time exponent */ + unsigned char fallTimeResponse:4; /* Fall time response in seconds */ + unsigned char fallTimeExponent:4; /* Fall time exponent */ + + /* + * Color / Luminance Description (28 bytes) + */ + unsigned char whiteGamme; /* (Gamma x 100) - 100, [range 1.00 --> 3.55] */ + unsigned char redGamma; /* Color 0 ("red") Gamma (optional). Set to ffh if unused. */ + unsigned char greenGamma; /* Color 1 ("green") Gamma (optional). Set to ffh if unused. */ + unsigned char blueGamma; /* Color 2 ("blue") Gamma (optional). Set to ffh if unused. */ + unsigned short maxLuminance; /* Maximum LUminance (white) in units of cd/m^2*10 */ + unsigned char colorConfig; /* Standard RGB Model, adjustable Gamma and its offset */ + unsigned char offsetValue; /* Color Offset value */ + + /* Calorimetry and White Point(s) */ + unsigned char redGreenLowBits; /* Red / Green Low Bits */ +} +edid_version_2_t; + +#endif + +/* Restore alignment */ +#pragma pack() + +/************************************************************** + * Function Prototypes + **************************************************************/ + +/* + * edidGetVersion + * This function gets the EDID version + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pRevision - Revision of the EDIE (if exist) + * + * Output: + * Revision number of the given EDID buffer. + */ +unsigned char edidGetVersion( + unsigned char *pEDIDBuffer, + unsigned char *pRevision +); + +/* + * edidGetProductInfo + * This function gets the vendor and product information. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor [in] + * pManufacturerName - Pointer to a 3 byte length variable to store the manufacturer name [out] + * pProductCode - Pointer to a variable to store the product code [out] + * pSerialNumber - Pointer to a variable to store the serial number [out] + * pWeekOfManufacture - Pointer to a variable to store the week of manufacture [out] + * pYearOfManufacture - Pointer to a variable to store the year of manufacture + * or model year (if WeekOfManufacture is 0xff) [out] + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetProductInfo( + unsigned char *pEDIDBuffer, + char *pManufacturerName, + unsigned short *pProductCode, + uint32_t *pSerialNumber, + unsigned char *pWeekOfManufacture, + unsigned short *pYearOfManufacture +); + +/* + * edidCheckMonitorInputSignal + * This function checks whether the monitor is expected analog/digital + * input signal. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * 0 - Analog + * 1 - Digital + */ +unsigned char edidCheckMonitorInputSignal( + unsigned char *pEDIDBuffer +); + +/* + * edidGetAnalogSignalInfo + * This function gets the analog video input signal information + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pRefWhiteAboveBlank - Pointer to a variable to store the reference white above blank + * value. The value is in milliVolt. + * pSyncLevelBelowBlank - Pointer to a variable to store the Sync tip level below blank + * The value is also in milliVolt + * pBlank2BlackSetup - Pointer to a variable to store the Blank to black setup or + * pedestal per appropriate Signal Level Standard flag. + * 1 means that the display expect the setup. + * pSeparateSyncSupport - Pointer to a variable to store the flag to indicate that the + * monitor supports separate sync. + * pCompositeSyncSupport - Pointer to a variable to store a flag to indicate that the + * monitor supports composite sync. + * pSyncOnGreenSupport - Pointer to a variable to store a flag to indicate that + * the monitor supports sync on green video. + * pVSyncSerrationRequired - Pointer to a variable to store a flag to indicate that serration + * of the VSync pulse is required when composite sync or + * sync-on-green video is used. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetAnalogSignalInfo( + unsigned char *pEDIDBuffer, + unsigned short *pRefWhiteAboveBlank, + unsigned short *pSyncLevelBelowBlank, + unsigned char *pBlank2BlackSetup, + unsigned char *pSeparateSyncSupport, + unsigned char *pCompositeSyncSupport, + unsigned char *pSyncOnGreenSupport, + unsigned char *pVSyncSerrationRequired +); + +/* + * edidGetDigitalSignalInfo + * This function gets the digital video input signal information + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pDFP1xSupport - Pointer to a variable to store the flag to indicate that + * the mointor interface is signal compatible with VESA + * DFP 1.x TMDS CRGB, 1 pixel/clock, up to 8 bits / color + * MSB aligned, DE active high + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetDigitalSignalInfo( + unsigned char *pEDIDBuffer, + unsigned char *pDFP1xSupport +); + +/* + * edidGetDisplaySize + * This function gets the display sizes in cm. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pMaxHorzImageSize - Pointer to a variable to store the maximum horizontal + * image size to the nearest centimeter. A value of 0 + * indicates that the size is indeterminate size. + * pMaxVertImageSize - Pointer to a variable to store the maximum vertical + * image size to the nearest centimeter. A value of 0 + * indicates that the size is indeterminate size. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetDisplaySize( + unsigned char *pEDIDBuffer, + unsigned char *pMaxHorzImageSize, + unsigned char *pMaxVertImageSize +); + +/* + * edidGetPowerManagementSupport + * This function gets the monitor's power management support. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pStandBy - Pointer to a variable to store the flag to indicate that + * standby power mode is supported. + * pSuspend - Pointer to a variable to store the flag to indicate that + * suspend power mode is supported. + * pLowPower - Pointer to a variable to store the flag to indicate that + * the display consumes low power when it receives a timing + * signal that is outside its declared active operating range. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetPowerManagementSupport( + unsigned char *pEDIDBuffer, + unsigned char *pStandBy, + unsigned char *pSuspend, + unsigned char *pLowPower +); + +/* + * edidGetDisplayType + * This function gets the display type. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * 0 - Monochrome / grayscale display + * 1 - RGB Color Display + * 2 - Non-RGB multicolor display, e.g. R/G/Y + * 3 - Undefined + */ +unsigned char edidGetDisplayType( + unsigned char *pEDIDBuffer +); + +/* + * edidChecksRGBUsage + * This function checks if the display is using the sRGB standard default + * color space as its primary color space. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * 0 - Does not use sRGB as its primary color space + * 1 - Use sRGB as its primary color space + */ +unsigned char edidChecksRGBUsage( + unsigned char *pEDIDBuffer +); + +/* + * edidIsPreferredTimingAvailable + * This function checks whether the preffered timing mode is available. + * Use of preferred timing mode is required by EDID structure version 1 + * Revision 3 and higher. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * 0 - Preferred Timing is not available + * 1 - Preferred Timing is available + */ +unsigned char edidIsPreferredTimingAvailable( + unsigned char *pEDIDBuffer +); + +/* + * edidIsDefaultGTFSupported + * This function checks whether the display supports timings based on the + * GTF standard using default GTF parameter values. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * 0 - Default GTF is not supported + * 1 - Default GTF is supported + */ +unsigned char edidIsDefaultGTFSupported( + unsigned char *pEDIDBuffer +); + +/* + * edidGetColorCharacteristic + * This function gets the chromaticity and white point values expressed as + * an integer value which represents the actual value times 1000. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pRedX - Pointer to a variable to store the Red X values + * pRedY - Pointer to a variable to store the Red Y values + * pGreenX - Pointer to a variable to store the Green X values + * pGreenY - Pointer to a variable to store the Green Y values + * pBlueX - Pointer to a variable to store the Blue X values + * pBlueY - Pointer to a variable to store the Blue Y values + * + * Note: + * To get the White color characteristic, use the edidGetWhitePoint + */ +void edidGetColorCharacteristic( + unsigned char *pEDIDBuffer, + unsigned short *pRedX, + unsigned short *pRedY, + unsigned short *pGreenX, + unsigned short *pGreenY, + unsigned short *pBlueX, + unsigned short *pBlueY +); + +/* + * edidGetWhitePoint + * This function gets the white point. + * To get the default white point, set the index to 0. For multiple white point, + * call this function multiple times to check if more than 1 white point is supported. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pWhitePointIndex - Pointer to a variable that contains the white point index + * to be retrieved. + * pWhiteX - Pointer to a variable to store the White X value + * pWhiteY - Pointer to a variable to store the White Y value + * pWhiteGamma - Pointer to a variable to store the White Gamma value + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetWhitePoint( + unsigned char *pEDIDBuffer, + unsigned char *pWhitePointIndex, + unsigned short *pWhiteX, + unsigned short *pWhiteY, + unsigned short *pWhiteGamma +); + +/* + * edidGetExtension + * This function gets the number of (optional) EDID extension blocks to follow + * the given EDID buffer. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * + * Output: + * Total number of EDID Extension to follow the given EDID buffer. + */ +unsigned char edidGetExtension( + unsigned char *pEDIDBuffer +); + +/* + * edidReadMonitor + * This function reads the EDID structure from the attached monitor + * + * Input: + * displayPath - Display device which EDID to be read from. + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * bufferSize - The EDID Buffer size index (usually 128-bytes) + * edidExtNo - Extension Index of the EDID Structure to be read + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidReadMonitor( + disp_path_t displayPath, + unsigned char *pEDIDBuffer, + uint32_t bufferSize, + unsigned char edidExtNo +); + +/* + * edidReadMonitor + * This function reads the EDID structure from the attached monitor + * + * Input: + * displayPath - Display device which EDID to be read from. + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * bufferSize - The EDID Buffer size index (usually 128-bytes) + * edidExtNo - Extension Index of the EDID Structure to be read + * sclGpio - GPIO pin used as the I2C Clock (SCL) + * sdaGpio - GPIO pin used as the I2C Data (SDA) + * + * Output: + * 0 - Success + * -1 - Fail + */ +_X_EXPORT int32_t ddk750_edidReadMonitorEx( + disp_path_t displayPath, + unsigned char *pEDIDBuffer, + uint32_t bufferSize, + unsigned char edidExtNo, + unsigned char sclGpio, + unsigned char sdaGpio +); + +_X_EXPORT int32_t edidReadMonitorEx_software( + disp_path_t displayPath, + unsigned char *pEDIDBuffer, + uint32_t bufferSize, + unsigned char edidExtNo, + unsigned char sclGpio, + unsigned char sdaGpio +); + +/* + * edidGetEstablishedTiming + * This function gets the established timing list from the given EDID buffer, + * table, and timing index. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor (In) + * pEstTableIndex - Pointer to the Established Timing Table index (In/Out) + * pIndex - Pointer to the Establihsed Timing Index (In/Out) + * pWidth - Pointer to a variable that to store the horizontal active / width + * value of the retrieved timing (Out) + * pHeight - Pointer to a variable to store the vertical active / height + * value of the retrieved timing (Out) + * pRefreshRate - Pointer to a variable to store the vertical frequency value + * of the retrieved timing (out) + * pSource - Pointer to a variable to store the standard timing source: + * 0 - VESA + * 1 - IBM + * 2 - Apple + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetEstablishedTiming( + unsigned char *pEDIDBuffer, + /*unsigned char *pEstTableIndex,*/ + unsigned char *pIndex, + uint32_t *pWidth, + uint32_t *pHeight, + uint32_t *pRefreshRate, + unsigned char *pSource +); + +/* + * edidGetStandardTiming + * This function gets the standard timing from the given EDID buffer and + * calculates the width, height, and vertical frequency from that timing. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pStdTimingIndex - Pointer to a standard timing index to be retrieved + * pWidth - Pointer to a variable that to store the horizontal active / width + * value of the retrieved timing (Out) + * pHeight - Pointer to a variable to store the vertical active / height + * value of the retrieved timing (Out) + * pRefreshRate - Pointer to a variable to store the vertical frequency value + * of the retrieved timing (out) + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetStandardTiming( + unsigned char *pEDIDBuffer, + unsigned char *pStdTimingIndex, + uint32_t *pWidth, + uint32_t *pHeight, + uint32_t *pRefreshRate +); + +/* + * edidGetDetailedTiming + * This function gets the detailed timing from the given EDID buffer. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pDetailedTimingIndex - Pointer to a detailed timing index to be retrieved + * pModeParameter - Pointer to a mode_parameter_t structure that will be + * filled with the detailed timing. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetDetailedTiming( + unsigned char *pEDIDBuffer, + unsigned char *pDetailedTimingIndex, + vdif_t *pVDIF +); + +/* + * edidGetMonitorSerialNumber + * This function gets the monitor serial number from the EDID structure. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pMonitorSerialNumber - Pointer to a buffer to store the serial number + * retrieved from the EDID + * bufferSize - The size of the buffer to store the serial number. + * The maximum size required is 13 bytes. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetMonitorSerialNumber( + unsigned char *pEDIDBuffer, + char *pMonitorSerialNumber, + unsigned char bufferSize +); + +/* + * edidGetDataString + * This function gets the data string from the EDID structure. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pMonitorSerialNumber - Pointer to a buffer to store the data string + * retrieved from the EDID + * bufferSize - The size of the buffer to store the data string + * The maximum size required is 13 bytes. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetDataString( + unsigned char *pEDIDBuffer, + char *pDataString, + unsigned char bufferSize +); + +/* + * edidGetMonitorRangeLimit + * This function gets the monitor range limits from the EDID structure. + * Only EDID version 1 and revision 1 or above supports this feature. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pMinVerticalRate - Pointer to a variable to store the Minimum Vertical Rate (Hz) + * pMaxVerticalRate - Pointer to a variable to store the Maximum Vertical Rate (Hz) + * pMinHorzFreq - Pointer to a variable to store the Minimum Horz. Freq (kHz) + * pMaxHorzFreq - Pointer to a variable to store the Maximum Horz. Freq (kHz) + * pMaxPixelClock - Pointer to a variable to store the Maximum Pixel Clock (Hz) + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetMonitorRangeLimit( + unsigned char *pEDIDBuffer, + unsigned char *pMinVerticalRate, + unsigned char *pMaxVerticalRate, + unsigned char *pMinHorzFreq, + unsigned char *pMaxHorzFreq, + uint32_t *pMaxPixelClock +); + +/* + * edidGetSecondaryTimingSupport + * This function gets the secondary GTF timing support. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pStartFrequency - Pointer to a variable to store the start frequency of + * the secondary GTF + * pOffset - Pointer to a variable to store the Offset (C) value of + * the secondary GTF + * pGradient - Pointer to a variable to store the Gradient (M) value of + * the secondary GTF + * pScalingFactor - Pointer to a variable to store the Scaling Factor (K) + * value of the secondary GTF + * pScalingFactorWeight - Pointer to a variable to store the Scaling Factore Weight (J) + * value of the secondary GTF + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetSecondaryTimingSupport( + unsigned char *pEDIDBuffer, + unsigned short *pStartFrequency, + unsigned char *pOffset, + unsigned short *pGradient, + unsigned char *pScalingFactor, + unsigned char *pScalingFactorWeight +); + +/* + * edidGetMonitorName + * This function gets the monitor name from the EDID structure. + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pMonitorName - Pointer to a buffer to store the monitor name + * retrieved from the EDID + * bufferSize - The size of the buffer to store the monitor name + * The maximum size required is 13 bytes. + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetMonitorName( + unsigned char *pEDIDBuffer, + char *pMonitorName, + unsigned char bufferSize +); + +/* + * edidGetPreferredTiming + * This function gets the preferred/native timing of the monitor + * + * Input: + * pEDIDBuffer - Buffer that contains the EDID structure of the monitor + * pWidth - Pointer to an uint32_t buffer to store the width + * of the preferred (native) timing. + * pHeight - Pointer to an uint32_t buffer to store the height + * of the preferred (native) timing. + * pVerticalFrequency - Pointer to an uint32_t buffer to store the refresh + * rate of the preferred (native) timing. + * + * Output: + * 0 - Success + * -1 - Fail + */ +int32_t edidGetPreferredTiming( + unsigned char *pEDIDBuffer, + uint32_t *pWidth, + uint32_t *pHeight, + uint32_t *pVerticalFrequency +); + +#endif /* _EDID_H_ */ + + + diff --git a/src/ddk750/ddk750_help.c b/src/ddk750/ddk750_help.c new file mode 100644 index 0000000..1767f9f --- /dev/null +++ b/src/ddk750/ddk750_help.c @@ -0,0 +1,51 @@ +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "compiler.h" + +#include "xf86Module.h" +#if XORG_VERSION_CURRENT < 10706000 +#include "xf86Resources.h" +#endif + +#include "ddk750_help.h" + +volatile unsigned char * mmio750 = NULL; +unsigned long revId750 = 0; +unsigned short devId750 = 0; + +_X_EXPORT int PEEK32(addr) +{ + return MMIO_IN32(mmio750,addr); +} + +_X_EXPORT void POKE32(addr,data) +{ + MMIO_OUT32(mmio750,(addr),(data)); +} +_X_EXPORT int PEEK8(addr) +{ + return MMIO_IN8(mmio750,addr); +} + +_X_EXPORT void POKE8(addr,data) +{ + MMIO_OUT8(mmio750,(addr),(data)); +} + +/* after driver mapped io registers, use this function first */ +_X_EXPORT void ddk750_set_mmio(volatile unsigned char * addr,unsigned short devId,unsigned long revId) +{ + mmio750 = addr; + devId750 = devId; + revId750 = revId; + if(revId == 0xfe){ + /*printk("found sm750le\n");*/ + } +} + + diff --git a/src/ddk750/ddk750_help.h b/src/ddk750/ddk750_help.h new file mode 100644 index 0000000..9527682 --- /dev/null +++ b/src/ddk750/ddk750_help.h @@ -0,0 +1,32 @@ +#ifndef DDK750_HELP_H__ +#define DDK750_HELP_H__ +#include "ddk750_chip.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +//#include "compiler.h" + +#ifndef NULL +#define NULL 0 +#endif + + + +#define outb_p outb +#define inb_p inb + + + +/* DDK Interface +Ddk750_chip.c unsigned int ddk750_getVMSize() +Ddk750_chip.c int ddk750_initHw() +Ddk750_display.c void ddk750_setLogicalDispOut() +Ddk750_display.c int ddk750_initDVIDisp() +Ddk750_help.c void ddk750_set_mmio() +Ddk750_mode.c int ddk750_setModeTiming() +Ddk750_power.c void ddk750_setDPMS() +*/ + +#endif diff --git a/src/ddk750/ddk750_hwi2c.c b/src/ddk750/ddk750_hwi2c.c new file mode 100644 index 0000000..06e8fba --- /dev/null +++ b/src/ddk750/ddk750_hwi2c.c @@ -0,0 +1,285 @@ +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86Module.h" +#if XORG_VERSION_CURRENT < 10706000 +#include "xf86Resources.h" +#endif +#include "compiler.h" +#include "xf86i2c.h" +#include "../smi_common.h" +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_hwi2c.h" +#include "ddk750_power.h" + +#define MAX_HWI2C_FIFO 16 +#define HWI2C_WAIT_TIMEOUT 0xF0000 + +#ifdef USE_HW_I2C + +int hwI2CInit( + unsigned char busSpeedMode +) +{ + unsigned int value; + + /* Enable GPIO 30 & 31 as IIC clock & data */ + value = PEEK32(GPIO_MUX); + + value = FIELD_SET(value, GPIO_MUX, 30, I2C) | + FIELD_SET(0, GPIO_MUX, 31, I2C); + POKE32(GPIO_MUX, value); + + /* Enable Hardware I2C power. + TODO: Check if we need to enable GPIO power? + */ + enableI2C(1); + + /* Enable the I2C Controller and set the bus speed mode */ + value = PEEK8(I2C_CTRL); + if (busSpeedMode == 0) + value = FIELD_SET(value, I2C_CTRL, MODE, STANDARD); + else + value = FIELD_SET(value, I2C_CTRL, MODE, FAST); + value = FIELD_SET(value, I2C_CTRL, EN, ENABLE); + POKE8(I2C_CTRL, value); + + return 0; +} + + +void hwI2CClose(void) +{ + unsigned int value; + + /* Disable I2C controller */ + value = PEEK8(I2C_CTRL); + value = FIELD_SET(value, I2C_CTRL, EN, DISABLE); + POKE8(I2C_CTRL, value); + + /* Disable I2C Power */ + enableI2C(0); + + /* Set GPIO 30 & 31 back as GPIO pins */ + value = PEEK32(GPIO_MUX); + value = FIELD_SET(value, GPIO_MUX, 30, GPIO); + value = FIELD_SET(value, GPIO_MUX, 31, GPIO); + POKE32(GPIO_MUX, value); +} + + +long hwI2CWaitTXDone(void) +{ + unsigned int timeout; + + /* Wait until the transfer is completed. */ + timeout = HWI2C_WAIT_TIMEOUT; + while ((FIELD_GET(PEEK8(I2C_STATUS), I2C_STATUS, TX) != I2C_STATUS_TX_COMPLETED) && + (timeout != 0)) + timeout--; + + if (timeout == 0) + return (-1); + + return 0; +} + + + +/* + * This function writes data to the i2c slave device registers. + * + * Parameters: + * deviceAddress - i2c Slave device address + * length - Total number of bytes to be written to the device + * pBuffer - The buffer that contains the data to be written to the + * i2c device. + * + * Return Value: + * Total number of bytes those are actually written. + */ +unsigned int hwI2CWriteData( + unsigned char deviceAddress, + unsigned int length, + unsigned char *pBuffer +) +{ + unsigned char count, i; + unsigned int totalBytes = 0; + + /* Set the Device Address */ + POKE8(I2C_SLAVE_ADDRESS, deviceAddress & ~0x01); + + /* Write data. + * Note: + * Only 16 byte can be accessed per i2c start instruction. + */ + do + { + /* Reset I2C by writing 0 to I2C_RESET register to clear the previous status. */ + POKE8(I2C_RESET, 0); + + /* Set the number of bytes to be written */ + if (length < MAX_HWI2C_FIFO) + count = length - 1; + else + count = MAX_HWI2C_FIFO - 1; + POKE8(I2C_BYTE_COUNT, count); + + /* Move the data to the I2C data register */ + for (i = 0; i <= count; i++) + POKE8(I2C_DATA0 + i, *pBuffer++); + + /* Start the I2C */ + POKE8(I2C_CTRL, FIELD_SET(PEEK8(I2C_CTRL), I2C_CTRL, CTRL, START)); + + /* Wait until the transfer is completed. */ + if (hwI2CWaitTXDone() != 0) + break; + + /* Substract length */ + length -= (count + 1); + + /* Total byte written */ + totalBytes += (count + 1); + + } while (length > 0); + + return totalBytes; +} + + + + +/* + * This function reads data from the slave device and stores them + * in the given buffer + * + * Parameters: + * deviceAddress - i2c Slave device address + * length - Total number of bytes to be read + * pBuffer - Pointer to a buffer to be filled with the data read + * from the slave device. It has to be the same size as the + * length to make sure that it can keep all the data read. + * + * Return Value: + * Total number of actual bytes read from the slave device + */ +unsigned int hwI2CReadData( + unsigned char deviceAddress, + unsigned int length, + unsigned char *pBuffer +) +{ + unsigned char count, i; + unsigned int totalBytes = 0; + + /* Set the Device Address */ + POKE8(I2C_SLAVE_ADDRESS, deviceAddress | 0x01); + + /* Read data and save them to the buffer. + * Note: + * Only 16 byte can be accessed per i2c start instruction. + */ + do + { + /* Reset I2C by writing 0 to I2C_RESET register to clear all the status. */ + POKE8(I2C_RESET, 0); + + /* Set the number of bytes to be read */ + if (length <= MAX_HWI2C_FIFO) + count = length - 1; + else + count = MAX_HWI2C_FIFO - 1; + POKE8(I2C_BYTE_COUNT, count); + + /* Start the I2C */ + POKE8(I2C_CTRL, FIELD_SET(PEEK8(I2C_CTRL), I2C_CTRL, CTRL, START)); + + /* Wait until transaction done. */ + if (hwI2CWaitTXDone() != 0) + break; + + /* Save the data to the given buffer */ + for (i = 0; i <= count; i++) + *pBuffer++ = PEEK8(I2C_DATA0 + i); + + /* Substract length by 16 */ + length -= (count + 1); + + /* Number of bytes read. */ + totalBytes += (count + 1); + + } while (length > 0); + + return totalBytes; +} + + + + +/* + * This function reads the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be read from + * registerIndex - Slave device's register to be read + * + * Return Value: + * Register value + */ +unsigned char hwI2CReadReg( + unsigned char deviceAddress, + unsigned char registerIndex +) +{ + unsigned char value = (0xFF); + + if (hwI2CWriteData(deviceAddress, 1, ®isterIndex) == 1) + hwI2CReadData(deviceAddress, 1, &value); + + return value; +} + + + + + +/* + * This function writes a value to the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be written + * registerIndex - Slave device's register to be written + * data - Data to be written to the register + * + * Result: + * 0 - Success + * -1 - Fail + */ +int hwI2CWriteReg( + unsigned char deviceAddress, + unsigned char registerIndex, + unsigned char data +) +{ + unsigned char value[2]; + + value[0] = registerIndex; + value[1] = data; + if (hwI2CWriteData(deviceAddress, 2, value) == 2) + return 0; + + return (-1); +} + + +#endif diff --git a/src/ddk750/ddk750_hwi2c.h b/src/ddk750/ddk750_hwi2c.h new file mode 100644 index 0000000..ee514eb --- /dev/null +++ b/src/ddk750/ddk750_hwi2c.h @@ -0,0 +1,17 @@ +#ifndef DDK750_HWI2C_H__ +#define DDK750_HWI2C_H__ + +#define USE_HW_I2C 1 + +void ddk750_I2CPutBits_panel(I2CBusPtr bus,int clock,int data); +void ddk750_I2CGetBits_panel(I2CBusPtr bus,int* clock,int* data); +void ddk750_I2CPutBits_crt(I2CBusPtr bus,int clock,int data); +void ddk750_I2CGetBits_crt(I2CBusPtr bus,int* clock,int* data); + +/* hwi2c functions */ +int hwI2CInit(unsigned char busSpeedMode); +void hwI2CClose(void); + +unsigned char hwI2CReadReg(unsigned char deviceAddress,unsigned char registerIndex); +int hwI2CWriteReg(unsigned char deviceAddress,unsigned char registerIndex,unsigned char data); +#endif diff --git a/src/ddk750/ddk750_mode.c b/src/ddk750/ddk750_mode.c new file mode 100644 index 0000000..86b6e21 --- /dev/null +++ b/src/ddk750/ddk750_mode.c @@ -0,0 +1,219 @@ +#include "../smi_common.h" +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_mode.h" +#include "ddk750_chip.h" + +/* + SM750LE only: + This function takes care extra registers and bit fields required to set + up a mode in SM750LE + + Explanation about Display Control register: + HW only supports 7 predefined pixel clocks, and clock select is + in bit 29:27 of Display Control register. +*/ +static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, unsigned long dispControl) +{ + unsigned long x, y; + + x = pModeParam->horizontal_display_end; + y = pModeParam->vertical_display_end; + + /* SM750LE has to set up the top-left and bottom-right + registers as well. + Note that normal SM750/SM718 only use those two register for + auto-centering mode. + */ + POKE32(CRT_AUTO_CENTERING_TL, + FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, TOP, 0) + | FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, LEFT, 0)); + + POKE32(CRT_AUTO_CENTERING_BR, + FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, BOTTOM, y-1) + | FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, RIGHT, x-1)); + + /* Assume common fields in dispControl have been properly set before + calling this function. + This function only sets the extra fields in dispControl. + */ + + /* Clear bit 29:27 of display control register */ + dispControl &= FIELD_CLEAR(CRT_DISPLAY_CTRL, CLK); + + /* Set bit 29:27 of display control register for the right clock */ + /* Note that SM750LE only need to supported 7 resoluitons. */ + if ( x == 800 && y == 600 ) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL41); + else if (x == 1024 && y == 768) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL65); + else if (x == 1152 && y == 864) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80); + else if (x == 1280 && y == 768) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80); + else if (x == 1280 && y == 720) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL74); + else if (x == 1280 && y == 960) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108); + else if (x == 1280 && y == 1024) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108); + else /* default to VGA clock */ + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL25); + + /* Set bit 25:24 of display controller */ + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CRTSELECT, CRT); + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, RGBBIT, 24BIT); + + /* Set bit 14 of display controller */ + if( x == 800 && y == 600 ) + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLOCK_PHASE, ACTIVE_HIGH); + else + dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLOCK_PHASE, ACTIVE_LOW); + + POKE32(CRT_DISPLAY_CTRL, dispControl); + + return dispControl; +} + + + +/* only timing related registers will be programed */ +static int programModeRegisters(mode_parameter_t * pModeParam,pll_value_t * pll) +{ + int ret = 0; + int cnt = 0; + unsigned int ulTmpValue,ulReg; + if(pll->clockType == SECONDARY_PLL) + { + /* programe secondary pixel clock */ + POKE32(CRT_PLL_CTRL,formatPllReg(pll)); + POKE32(CRT_HORIZONTAL_TOTAL, + FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) + | FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); + + POKE32(CRT_HORIZONTAL_SYNC, + FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) + | FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); + + POKE32(CRT_VERTICAL_TOTAL, + FIELD_VALUE(0, CRT_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) + | FIELD_VALUE(0, CRT_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); + + POKE32(CRT_VERTICAL_SYNC, + FIELD_VALUE(0, CRT_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) + | FIELD_VALUE(0, CRT_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); + + ulTmpValue = FIELD_VALUE(0,CRT_DISPLAY_CTRL,VSYNC_PHASE,pModeParam->vertical_sync_polarity)| + FIELD_VALUE(0,CRT_DISPLAY_CTRL,HSYNC_PHASE,pModeParam->horizontal_sync_polarity)| + FIELD_SET(0,CRT_DISPLAY_CTRL,TIMING,ENABLE)| + FIELD_SET(0,CRT_DISPLAY_CTRL,PLANE,ENABLE); + + + if(getChipType() == SM750LE){ + displayControlAdjust_SM750LE(pModeParam,ulTmpValue); + }else{ + ulReg = PEEK32(CRT_DISPLAY_CTRL) + & FIELD_CLEAR(CRT_DISPLAY_CTRL,VSYNC_PHASE) + & FIELD_CLEAR(CRT_DISPLAY_CTRL,HSYNC_PHASE) + & FIELD_CLEAR(CRT_DISPLAY_CTRL,TIMING) + & FIELD_CLEAR(CRT_DISPLAY_CTRL,PLANE); + + POKE32(CRT_DISPLAY_CTRL,ulTmpValue|ulReg); + } + + } + else if(pll->clockType == PRIMARY_PLL) + { + unsigned int ulReservedBits; + POKE32(PANEL_PLL_CTRL,formatPllReg(pll)); + + + + POKE32(PANEL_PLANE_TL, + FIELD_VALUE(0, PANEL_PLANE_TL, TOP, 0) + | FIELD_VALUE(0, PANEL_PLANE_TL, LEFT, 0)); + + POKE32(PANEL_PLANE_BR, + FIELD_VALUE(0, PANEL_PLANE_BR, BOTTOM, pModeParam->vertical_display_end - 1) + | FIELD_VALUE(0, PANEL_PLANE_BR, RIGHT, pModeParam->horizontal_display_end - 1)); + + POKE32(PANEL_HORIZONTAL_TOTAL, + FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) + | FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); + + POKE32(PANEL_HORIZONTAL_SYNC, + FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) + | FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); + + POKE32(PANEL_VERTICAL_TOTAL, + FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) + | FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); + + POKE32(PANEL_VERTICAL_SYNC, + FIELD_VALUE(0, PANEL_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) + | FIELD_VALUE(0, PANEL_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); + + ulTmpValue = FIELD_VALUE(0,PANEL_DISPLAY_CTRL,VSYNC_PHASE,pModeParam->vertical_sync_polarity)| + FIELD_VALUE(0,PANEL_DISPLAY_CTRL,HSYNC_PHASE,pModeParam->horizontal_sync_polarity)| + FIELD_VALUE(0,PANEL_DISPLAY_CTRL,CLOCK_PHASE,pModeParam->clock_phase_polarity)| + FIELD_SET(0,PANEL_DISPLAY_CTRL,TIMING,ENABLE)| + FIELD_SET(0,PANEL_DISPLAY_CTRL,PLANE,ENABLE); + + ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | + FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | + FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE)| + FIELD_SET(0,PANEL_DISPLAY_CTRL,VSYNC,ACTIVE_LOW); + + ulReg = (PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, CLOCK_PHASE) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, VSYNC_PHASE) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, HSYNC_PHASE) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, TIMING) + & FIELD_CLEAR(PANEL_DISPLAY_CTRL, PLANE); + + POKE32(PANEL_WINDOW_WIDTH, + FIELD_VALUE(0,PANEL_WINDOW_WIDTH,WIDTH,pModeParam->horizontal_display_end - 1)| + FIELD_VALUE(0,PANEL_WINDOW_WIDTH,X,0)); + + POKE32(PANEL_WINDOW_HEIGHT, + FIELD_VALUE(0,PANEL_WINDOW_HEIGHT,HEIGHT,pModeParam->vertical_display_end - 1)| + FIELD_VALUE(0,PANEL_WINDOW_HEIGHT,Y,0)); + + /* May a hardware bug or just my test chip (not confirmed). + * PANEL_DISPLAY_CTRL register seems requiring few writes + * before a value can be succesfully written in. + * Added some masks to mask out the reserved bits. + * Note: This problem happens by design. The hardware will wait for the + * next vertical sync to turn on/off the plane. + */ + + POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg); +#if 1 + while((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulTmpValue|ulReg)) + { + cnt++; + if(cnt > 1000) + break; + POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg); + } +#endif + } + else{ + ret = -1; + } + return ret; +} + +_X_EXPORT int ddk750_setModeTiming(mode_parameter_t * parm,clock_type_t clock) +{ + pll_value_t pll; + unsigned int uiActualPixelClk; + pll.inputFreq = DEFAULT_INPUT_CLOCK;//how??? + pll.clockType = clock; + + uiActualPixelClk = calcPllValue(parm->pixel_clock,&pll); + programModeRegisters(parm,&pll); + return 0; +} + + diff --git a/src/ddk750/ddk750_mode.h b/src/ddk750/ddk750_mode.h new file mode 100644 index 0000000..261b280 --- /dev/null +++ b/src/ddk750/ddk750_mode.h @@ -0,0 +1,43 @@ +#ifndef DDK750_MODE_H__ +#define DDK750_MODE_H__ + +#include "ddk750_chip.h" + +typedef enum _spolarity_t +{ + POS = 0, /* positive */ + NEG, /* negative */ +} +spolarity_t; + + +typedef struct _mode_parameter_t +{ + /* Horizontal timing. */ + unsigned long horizontal_total; + unsigned long horizontal_display_end; + unsigned long horizontal_sync_start; + unsigned long horizontal_sync_width; + spolarity_t horizontal_sync_polarity; + + /* Vertical timing. */ + unsigned long vertical_total; + unsigned long vertical_display_end; + unsigned long vertical_sync_start; + unsigned long vertical_sync_height; + spolarity_t vertical_sync_polarity; + + /* Refresh timing. */ + unsigned long pixel_clock; + unsigned long horizontal_frequency; + unsigned long vertical_frequency; + + /* Clock Phase. This clock phase only applies to Panel. */ + spolarity_t clock_phase_polarity; +} +mode_parameter_t; + +int ddk750_setModeTiming(mode_parameter_t *,clock_type_t); + + +#endif diff --git a/src/ddk750/ddk750_power.c b/src/ddk750/ddk750_power.c new file mode 100644 index 0000000..bc8442e --- /dev/null +++ b/src/ddk750/ddk750_power.c @@ -0,0 +1,240 @@ +#include "../smi_common.h" +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_power.h" + +_X_EXPORT void ddk750_setDPMS(DPMS_t state) +{ + unsigned int value; + if(getChipType() == SM750LE){ + value = PEEK32(CRT_DISPLAY_CTRL); + POKE32(CRT_DISPLAY_CTRL,FIELD_VALUE(value,CRT_DISPLAY_CTRL,DPMS,state)); + }else{ + value = PEEK32(SYSTEM_CTRL); + value= FIELD_VALUE(value,SYSTEM_CTRL,DPMS,state); + POKE32(SYSTEM_CTRL, value); + } +} + +unsigned int getPowerMode() +{ + if(getChipType() == SM750LE) + return 0; + return (FIELD_GET(PEEK32(POWER_MODE_CTRL), POWER_MODE_CTRL, MODE)); +} + + +/* + * SM50x can operate in one of three modes: 0, 1 or Sleep. + * On hardware reset, power mode 0 is default. + */ +void setPowerMode(unsigned int powerMode) +{ + unsigned int control_value = 0; + + control_value = PEEK32(POWER_MODE_CTRL); + + if(getChipType() == SM750LE) + return; + + switch (powerMode) + { + case POWER_MODE_CTRL_MODE_MODE0: + control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, MODE0); + break; + + case POWER_MODE_CTRL_MODE_MODE1: + control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, MODE1); + break; + + case POWER_MODE_CTRL_MODE_SLEEP: + control_value = FIELD_SET(control_value, POWER_MODE_CTRL, MODE, SLEEP); + break; + + default: + break; + } + + /* Set up other fields in Power Control Register */ + if (powerMode == POWER_MODE_CTRL_MODE_SLEEP) + { + control_value = +#ifdef VALIDATION_CHIP + FIELD_SET( control_value, POWER_MODE_CTRL, 336CLK, OFF) | +#endif + FIELD_SET( control_value, POWER_MODE_CTRL, OSC_INPUT, OFF); + } + else + { + control_value = +#ifdef VALIDATION_CHIP + FIELD_SET( control_value, POWER_MODE_CTRL, 336CLK, ON) | +#endif + FIELD_SET( control_value, POWER_MODE_CTRL, OSC_INPUT, ON); + } + + /* Program new power mode. */ + POKE32(POWER_MODE_CTRL, control_value); +} + +void setCurrentGate(unsigned int gate) +{ + unsigned int gate_reg; + unsigned int mode; + + /* Get current power mode. */ + mode = getPowerMode(); + + switch (mode) + { + case POWER_MODE_CTRL_MODE_MODE0: + gate_reg = MODE0_GATE; + break; + + case POWER_MODE_CTRL_MODE_MODE1: + gate_reg = MODE1_GATE; + break; + + default: + gate_reg = MODE0_GATE; + break; + } + POKE32(gate_reg, gate); +} + + + +/* + * This function enable/disable the 2D engine. + */ +void enable2DEngine(unsigned int enable) +{ + uint32_t gate; + + gate = PEEK32(CURRENT_GATE); + if (enable) + { + gate = FIELD_SET(gate, CURRENT_GATE, DE, ON); + gate = FIELD_SET(gate, CURRENT_GATE, CSC, ON); + } + else + { + gate = FIELD_SET(gate, CURRENT_GATE, DE, OFF); + gate = FIELD_SET(gate, CURRENT_GATE, CSC, OFF); + } + + setCurrentGate(gate); +} + + +/* + * This function enable/disable the ZV Port. + */ +void enableZVPort(unsigned int enable) +{ + uint32_t gate; + + /* Enable ZV Port Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + { + gate = FIELD_SET(gate, CURRENT_GATE, ZVPORT, ON); +#if 1 + /* Using Software I2C */ + gate = FIELD_SET(gate, CURRENT_GATE, GPIO, ON); +#else + /* Using Hardware I2C */ + gate = FIELD_SET(gate, CURRENT_GATE, I2C, ON); +#endif + } + else + { + /* Disable ZV Port Gate. There is no way to know whether the GPIO pins are being used + or not. Therefore, do not disable the GPIO gate. */ + gate = FIELD_SET(gate, CURRENT_GATE, ZVPORT, OFF); + } + + setCurrentGate(gate); +} + + +void enableSSP(unsigned int enable) +{ + uint32_t gate; + + /* Enable SSP Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, SSP, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, SSP, OFF); + + setCurrentGate(gate); +} + +void enableDMA(unsigned int enable) +{ + uint32_t gate; + + /* Enable DMA Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, DMA, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, DMA, OFF); + + setCurrentGate(gate); +} + +/* + * This function enable/disable the GPIO Engine + */ +_X_EXPORT void enableGPIO(unsigned int enable) +{ + uint32_t gate; + + /* Enable GPIO Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, GPIO, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, GPIO, OFF); + + setCurrentGate(gate); +} + +/* + * This function enable/disable the PWM Engine + */ +void enablePWM(unsigned int enable) +{ + uint32_t gate; + + /* Enable PWM Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, PWM, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, PWM, OFF); + + setCurrentGate(gate); +} + +/* + * This function enable/disable the I2C Engine + */ +void enableI2C(unsigned int enable) +{ + uint32_t gate; + + /* Enable I2C Gate */ + gate = PEEK32(CURRENT_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_GATE, I2C, ON); + else + gate = FIELD_SET(gate, CURRENT_GATE, I2C, OFF); + + setCurrentGate(gate); +} + + diff --git a/src/ddk750/ddk750_power.h b/src/ddk750/ddk750_power.h new file mode 100644 index 0000000..6d32101 --- /dev/null +++ b/src/ddk750/ddk750_power.h @@ -0,0 +1,72 @@ +#ifndef DDK750_POWER_H__ +#define DDK750_POWER_H__ + +/* Power constants to use with setDPMS function. */ +typedef enum _DPMS_t +{ + DPMS_ON, + DPMS_STANDBY, + DPMS_SUSPEND, + DPMS_OFF +} +DPMS_t; + +#define setDAC(off) \ + { \ + POKE32(MISC_CTRL,FIELD_VALUE(PEEK32(MISC_CTRL), \ + MISC_CTRL, \ + DAC_POWER, \ + off)); \ + } + +void ddk750_setDPMS(DPMS_t); + +unsigned int getPowerMode(void); + +/* + * This function sets the current power mode + */ +void setPowerMode(unsigned int powerMode); + +/* + * This function sets current gate + */ +void setCurrentGate(unsigned int gate); + +/* + * This function enable/disable the 2D engine. + */ +void enable2DEngine(unsigned int enable); + +/* + * This function enable/disable the ZV Port + */ +void enableZVPort(unsigned int enable); + +/* + * This function enable/disable the DMA Engine + */ +void enableDMA(unsigned int enable); + +/* + * This function enable/disable the GPIO Engine + */ +void enableGPIO(unsigned int enable); + +/* + * This function enable/disable the PWM Engine + */ +void enablePWM(unsigned int enable); + +/* + * This function enable/disable the I2C Engine + */ +void enableI2C(unsigned int enable); + +/* + * This function enable/disable the SSP. + */ +void enableSSP(unsigned int enable); + + +#endif diff --git a/src/ddk750/ddk750_reg.h b/src/ddk750/ddk750_reg.h new file mode 100644 index 0000000..761892c --- /dev/null +++ b/src/ddk750/ddk750_reg.h @@ -0,0 +1,2597 @@ +#ifndef DDK750_REG_H__ +#define DDK750_REG_H__ + +/* New register for SM750LE */ +#define DE_STATE1 0x100054 +#define DE_STATE1_DE_ABORT 0:0 +#define DE_STATE1_DE_ABORT_OFF 0 +#define DE_STATE1_DE_ABORT_ON 1 + +#define DE_STATE2 0x100058 +#define DE_STATE2_DE_FIFO 3:3 +#define DE_STATE2_DE_FIFO_NOTEMPTY 0 +#define DE_STATE2_DE_FIFO_EMPTY 1 +#define DE_STATE2_DE_STATUS 2:2 +#define DE_STATE2_DE_STATUS_IDLE 0 +#define DE_STATE2_DE_STATUS_BUSY 1 +#define DE_STATE2_DE_MEM_FIFO 1:1 +#define DE_STATE2_DE_MEM_FIFO_NOTEMPTY 0 +#define DE_STATE2_DE_MEM_FIFO_EMPTY 1 +#define DE_STATE2_DE_RESERVED 0:0 + + + +#define SYSTEM_CTRL 0x000000 +#define SYSTEM_CTRL_DPMS 31:30 +#define SYSTEM_CTRL_DPMS_VPHP 0 +#define SYSTEM_CTRL_DPMS_VPHN 1 +#define SYSTEM_CTRL_DPMS_VNHP 2 +#define SYSTEM_CTRL_DPMS_VNHN 3 +#define SYSTEM_CTRL_PCI_BURST 29:29 +#define SYSTEM_CTRL_PCI_BURST_OFF 0 +#define SYSTEM_CTRL_PCI_BURST_ON 1 +#define SYSTEM_CTRL_PCI_MASTER 25:25 +#define SYSTEM_CTRL_PCI_MASTER_OFF 0 +#define SYSTEM_CTRL_PCI_MASTER_ON 1 +#define SYSTEM_CTRL_LATENCY_TIMER 24:24 +#define SYSTEM_CTRL_LATENCY_TIMER_ON 0 +#define SYSTEM_CTRL_LATENCY_TIMER_OFF 1 +#define SYSTEM_CTRL_DE_FIFO 23:23 +#define SYSTEM_CTRL_DE_FIFO_NOTEMPTY 0 +#define SYSTEM_CTRL_DE_FIFO_EMPTY 1 +#define SYSTEM_CTRL_DE_STATUS 22:22 +#define SYSTEM_CTRL_DE_STATUS_IDLE 0 +#define SYSTEM_CTRL_DE_STATUS_BUSY 1 +#define SYSTEM_CTRL_DE_MEM_FIFO 21:21 +#define SYSTEM_CTRL_DE_MEM_FIFO_NOTEMPTY 0 +#define SYSTEM_CTRL_DE_MEM_FIFO_EMPTY 1 +#define SYSTEM_CTRL_CSC_STATUS 20:20 +#define SYSTEM_CTRL_CSC_STATUS_IDLE 0 +#define SYSTEM_CTRL_CSC_STATUS_BUSY 1 +#define SYSTEM_CTRL_CRT_VSYNC 19:19 +#define SYSTEM_CTRL_CRT_VSYNC_INACTIVE 0 +#define SYSTEM_CTRL_CRT_VSYNC_ACTIVE 1 +#define SYSTEM_CTRL_PANEL_VSYNC 18:18 +#define SYSTEM_CTRL_PANEL_VSYNC_INACTIVE 0 +#define SYSTEM_CTRL_PANEL_VSYNC_ACTIVE 1 +#define SYSTEM_CTRL_CURRENT_BUFFER 17:17 +#define SYSTEM_CTRL_CURRENT_BUFFER_NORMAL 0 +#define SYSTEM_CTRL_CURRENT_BUFFER_FLIP_PENDING 1 +#define SYSTEM_CTRL_DMA_STATUS 16:16 +#define SYSTEM_CTRL_DMA_STATUS_IDLE 0 +#define SYSTEM_CTRL_DMA_STATUS_BUSY 1 +#define SYSTEM_CTRL_PCI_BURST_READ 15:15 +#define SYSTEM_CTRL_PCI_BURST_READ_OFF 0 +#define SYSTEM_CTRL_PCI_BURST_READ_ON 1 +#define SYSTEM_CTRL_DE_ABORT 13:13 +#define SYSTEM_CTRL_DE_ABORT_OFF 0 +#define SYSTEM_CTRL_DE_ABORT_ON 1 +#define SYSTEM_CTRL_PCI_SUBSYS_ID_LOCK 11:11 +#define SYSTEM_CTRL_PCI_SUBSYS_ID_LOCK_OFF 0 +#define SYSTEM_CTRL_PCI_SUBSYS_ID_LOCK_ON 1 +#define SYSTEM_CTRL_PCI_RETRY 7:7 +#define SYSTEM_CTRL_PCI_RETRY_ON 0 +#define SYSTEM_CTRL_PCI_RETRY_OFF 1 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE 5:4 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_1 0 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_2 1 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_4 2 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_8 3 +#define SYSTEM_CTRL_CRT_TRISTATE 3:3 +#define SYSTEM_CTRL_CRT_TRISTATE_OFF 0 +#define SYSTEM_CTRL_CRT_TRISTATE_ON 1 +#define SYSTEM_CTRL_PCIMEM_TRISTATE 2:2 +#define SYSTEM_CTRL_PCIMEM_TRISTATE_OFF 0 +#define SYSTEM_CTRL_PCIMEM_TRISTATE_ON 1 +#define SYSTEM_CTRL_LOCALMEM_TRISTATE 1:1 +#define SYSTEM_CTRL_LOCALMEM_TRISTATE_OFF 0 +#define SYSTEM_CTRL_LOCALMEM_TRISTATE_ON 1 +#define SYSTEM_CTRL_PANEL_TRISTATE 0:0 +#define SYSTEM_CTRL_PANEL_TRISTATE_OFF 0 +#define SYSTEM_CTRL_PANEL_TRISTATE_ON 1 + +#define MISC_CTRL 0x000004 +#define MISC_CTRL_DRAM_RERESH_COUNT 27:27 +#define MISC_CTRL_DRAM_RERESH_COUNT_1ROW 0 +#define MISC_CTRL_DRAM_RERESH_COUNT_3ROW 1 +#define MISC_CTRL_DRAM_REFRESH_TIME 26:25 +#define MISC_CTRL_DRAM_REFRESH_TIME_8 0 +#define MISC_CTRL_DRAM_REFRESH_TIME_16 1 +#define MISC_CTRL_DRAM_REFRESH_TIME_32 2 +#define MISC_CTRL_DRAM_REFRESH_TIME_64 3 +#define MISC_CTRL_INT_OUTPUT 24:24 +#define MISC_CTRL_INT_OUTPUT_NORMAL 0 +#define MISC_CTRL_INT_OUTPUT_INVERT 1 +#define MISC_CTRL_PLL_CLK_COUNT 23:23 +#define MISC_CTRL_PLL_CLK_COUNT_OFF 0 +#define MISC_CTRL_PLL_CLK_COUNT_ON 1 +#define MISC_CTRL_DAC_POWER 20:20 +#define MISC_CTRL_DAC_POWER_ON 0 +#define MISC_CTRL_DAC_POWER_OFF 1 +#define MISC_CTRL_CLK_SELECT 16:16 +#define MISC_CTRL_CLK_SELECT_OSC 0 +#define MISC_CTRL_CLK_SELECT_TESTCLK 1 +#define MISC_CTRL_DRAM_COLUMN_SIZE 15:14 +#define MISC_CTRL_DRAM_COLUMN_SIZE_256 0 +#define MISC_CTRL_DRAM_COLUMN_SIZE_512 1 +#define MISC_CTRL_DRAM_COLUMN_SIZE_1024 2 +#define MISC_CTRL_LOCALMEM_SIZE 13:12 +#define MISC_CTRL_LOCALMEM_SIZE_8M 3 +#define MISC_CTRL_LOCALMEM_SIZE_16M 0 +#define MISC_CTRL_LOCALMEM_SIZE_32M 1 +#define MISC_CTRL_LOCALMEM_SIZE_64M 2 +#define MISC_CTRL_DRAM_TWTR 11:11 +#define MISC_CTRL_DRAM_TWTR_2CLK 0 +#define MISC_CTRL_DRAM_TWTR_1CLK 1 +#define MISC_CTRL_DRAM_TWR 10:10 +#define MISC_CTRL_DRAM_TWR_3CLK 0 +#define MISC_CTRL_DRAM_TWR_2CLK 1 +#define MISC_CTRL_DRAM_TRP 9:9 +#define MISC_CTRL_DRAM_TRP_3CLK 0 +#define MISC_CTRL_DRAM_TRP_4CLK 1 +#define MISC_CTRL_DRAM_TRFC 8:8 +#define MISC_CTRL_DRAM_TRFC_12CLK 0 +#define MISC_CTRL_DRAM_TRFC_14CLK 1 +#define MISC_CTRL_DRAM_TRAS 7:7 +#define MISC_CTRL_DRAM_TRAS_7CLK 0 +#define MISC_CTRL_DRAM_TRAS_8CLK 1 +#define MISC_CTRL_LOCALMEM_RESET 6:6 +#define MISC_CTRL_LOCALMEM_RESET_RESET 0 +#define MISC_CTRL_LOCALMEM_RESET_NORMAL 1 +#define MISC_CTRL_LOCALMEM_STATE 5:5 +#define MISC_CTRL_LOCALMEM_STATE_ACTIVE 0 +#define MISC_CTRL_LOCALMEM_STATE_INACTIVE 1 +#define MISC_CTRL_CPU_CAS_LATENCY 4:4 +#define MISC_CTRL_CPU_CAS_LATENCY_2CLK 0 +#define MISC_CTRL_CPU_CAS_LATENCY_3CLK 1 +#define MISC_CTRL_DLL 3:3 +#define MISC_CTRL_DLL_ON 0 +#define MISC_CTRL_DLL_OFF 1 +#define MISC_CTRL_DRAM_OUTPUT 2:2 +#define MISC_CTRL_DRAM_OUTPUT_LOW 0 +#define MISC_CTRL_DRAM_OUTPUT_HIGH 1 +#define MISC_CTRL_LOCALMEM_BUS_SIZE 1:1 +#define MISC_CTRL_LOCALMEM_BUS_SIZE_32 0 +#define MISC_CTRL_LOCALMEM_BUS_SIZE_64 1 +#define MISC_CTRL_EMBEDDED_LOCALMEM 0:0 +#define MISC_CTRL_EMBEDDED_LOCALMEM_ON 0 +#define MISC_CTRL_EMBEDDED_LOCALMEM_OFF 1 + +#define GPIO_MUX 0x000008 +#define GPIO_MUX_31 31:31 +#define GPIO_MUX_31_GPIO 0 +#define GPIO_MUX_31_I2C 1 +#define GPIO_MUX_30 30:30 +#define GPIO_MUX_30_GPIO 0 +#define GPIO_MUX_30_I2C 1 +#define GPIO_MUX_29 29:29 +#define GPIO_MUX_29_GPIO 0 +#define GPIO_MUX_29_SSP1 1 +#define GPIO_MUX_28 28:28 +#define GPIO_MUX_28_GPIO 0 +#define GPIO_MUX_28_SSP1 1 +#define GPIO_MUX_27 27:27 +#define GPIO_MUX_27_GPIO 0 +#define GPIO_MUX_27_SSP1 1 +#define GPIO_MUX_26 26:26 +#define GPIO_MUX_26_GPIO 0 +#define GPIO_MUX_26_SSP1 1 +#define GPIO_MUX_25 25:25 +#define GPIO_MUX_25_GPIO 0 +#define GPIO_MUX_25_SSP1 1 +#define GPIO_MUX_24 24:24 +#define GPIO_MUX_24_GPIO 0 +#define GPIO_MUX_24_SSP0 1 +#define GPIO_MUX_23 23:23 +#define GPIO_MUX_23_GPIO 0 +#define GPIO_MUX_23_SSP0 1 +#define GPIO_MUX_22 22:22 +#define GPIO_MUX_22_GPIO 0 +#define GPIO_MUX_22_SSP0 1 +#define GPIO_MUX_21 21:21 +#define GPIO_MUX_21_GPIO 0 +#define GPIO_MUX_21_SSP0 1 +#define GPIO_MUX_20 20:20 +#define GPIO_MUX_20_GPIO 0 +#define GPIO_MUX_20_SSP0 1 +#define GPIO_MUX_19 19:19 +#define GPIO_MUX_19_GPIO 0 +#define GPIO_MUX_19_PWM 1 +#define GPIO_MUX_18 18:18 +#define GPIO_MUX_18_GPIO 0 +#define GPIO_MUX_18_PWM 1 +#define GPIO_MUX_17 17:17 +#define GPIO_MUX_17_GPIO 0 +#define GPIO_MUX_17_PWM 1 +#define GPIO_MUX_16 16:16 +#define GPIO_MUX_16_GPIO_ZVPORT 0 +#define GPIO_MUX_16_TEST_DATA 1 +#define GPIO_MUX_15 15:15 +#define GPIO_MUX_15_GPIO_ZVPORT 0 +#define GPIO_MUX_15_TEST_DATA 1 +#define GPIO_MUX_14 14:14 +#define GPIO_MUX_14_GPIO_ZVPORT 0 +#define GPIO_MUX_14_TEST_DATA 1 +#define GPIO_MUX_13 13:13 +#define GPIO_MUX_13_GPIO_ZVPORT 0 +#define GPIO_MUX_13_TEST_DATA 1 +#define GPIO_MUX_12 12:12 +#define GPIO_MUX_12_GPIO_ZVPORT 0 +#define GPIO_MUX_12_TEST_DATA 1 +#define GPIO_MUX_11 11:11 +#define GPIO_MUX_11_GPIO_ZVPORT 0 +#define GPIO_MUX_11_TEST_DATA 1 +#define GPIO_MUX_10 10:10 +#define GPIO_MUX_10_GPIO_ZVPORT 0 +#define GPIO_MUX_10_TEST_DATA 1 +#define GPIO_MUX_9 9:9 +#define GPIO_MUX_9_GPIO_ZVPORT 0 +#define GPIO_MUX_9_TEST_DATA 1 +#define GPIO_MUX_8 8:8 +#define GPIO_MUX_8_GPIO_ZVPORT 0 +#define GPIO_MUX_8_TEST_DATA 1 +#define GPIO_MUX_7 7:7 +#define GPIO_MUX_7_GPIO_ZVPORT 0 +#define GPIO_MUX_7_TEST_DATA 1 +#define GPIO_MUX_6 6:6 +#define GPIO_MUX_6_GPIO_ZVPORT 0 +#define GPIO_MUX_6_TEST_DATA 1 +#define GPIO_MUX_5 5:5 +#define GPIO_MUX_5_GPIO_ZVPORT 0 +#define GPIO_MUX_5_TEST_DATA 1 +#define GPIO_MUX_4 4:4 +#define GPIO_MUX_4_GPIO_ZVPORT 0 +#define GPIO_MUX_4_TEST_DATA 1 +#define GPIO_MUX_3 3:3 +#define GPIO_MUX_3_GPIO_ZVPORT 0 +#define GPIO_MUX_3_TEST_DATA 1 +#define GPIO_MUX_2 2:2 +#define GPIO_MUX_2_GPIO_ZVPORT 0 +#define GPIO_MUX_2_TEST_DATA 1 +#define GPIO_MUX_1 1:1 +#define GPIO_MUX_1_GPIO_ZVPORT 0 +#define GPIO_MUX_1_TEST_DATA 1 +#define GPIO_MUX_0 0:0 +#define GPIO_MUX_0_GPIO_ZVPORT 0 +#define GPIO_MUX_0_TEST_DATA 1 + +#define LOCALMEM_ARBITRATION 0x00000C +#define LOCALMEM_ARBITRATION_ROTATE 28:28 +#define LOCALMEM_ARBITRATION_ROTATE_OFF 0 +#define LOCALMEM_ARBITRATION_ROTATE_ON 1 +#define LOCALMEM_ARBITRATION_VGA 26:24 +#define LOCALMEM_ARBITRATION_VGA_OFF 0 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_VGA_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_DMA 22:20 +#define LOCALMEM_ARBITRATION_DMA_OFF 0 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_DMA_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_ZVPORT1 18:16 +#define LOCALMEM_ARBITRATION_ZVPORT1_OFF 0 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_ZVPORT1_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_ZVPORT0 14:12 +#define LOCALMEM_ARBITRATION_ZVPORT0_OFF 0 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_ZVPORT0_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_VIDEO 10:8 +#define LOCALMEM_ARBITRATION_VIDEO_OFF 0 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_VIDEO_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_PANEL 6:4 +#define LOCALMEM_ARBITRATION_PANEL_OFF 0 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_PANEL_PRIORITY_7 7 +#define LOCALMEM_ARBITRATION_CRT 2:0 +#define LOCALMEM_ARBITRATION_CRT_OFF 0 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_1 1 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_2 2 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_3 3 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_4 4 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_5 5 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_6 6 +#define LOCALMEM_ARBITRATION_CRT_PRIORITY_7 7 + +#define PCIMEM_ARBITRATION 0x000010 +#define PCIMEM_ARBITRATION_ROTATE 28:28 +#define PCIMEM_ARBITRATION_ROTATE_OFF 0 +#define PCIMEM_ARBITRATION_ROTATE_ON 1 +#define PCIMEM_ARBITRATION_VGA 26:24 +#define PCIMEM_ARBITRATION_VGA_OFF 0 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_VGA_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_DMA 22:20 +#define PCIMEM_ARBITRATION_DMA_OFF 0 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_DMA_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_ZVPORT1 18:16 +#define PCIMEM_ARBITRATION_ZVPORT1_OFF 0 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_ZVPORT1_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_ZVPORT0 14:12 +#define PCIMEM_ARBITRATION_ZVPORT0_OFF 0 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_ZVPORT0_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_VIDEO 10:8 +#define PCIMEM_ARBITRATION_VIDEO_OFF 0 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_VIDEO_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_PANEL 6:4 +#define PCIMEM_ARBITRATION_PANEL_OFF 0 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_PANEL_PRIORITY_7 7 +#define PCIMEM_ARBITRATION_CRT 2:0 +#define PCIMEM_ARBITRATION_CRT_OFF 0 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_1 1 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_2 2 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_3 3 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_4 4 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_5 5 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_6 6 +#define PCIMEM_ARBITRATION_CRT_PRIORITY_7 7 + +#define RAW_INT 0x000020 +#define RAW_INT_ZVPORT1_VSYNC 4:4 +#define RAW_INT_ZVPORT1_VSYNC_INACTIVE 0 +#define RAW_INT_ZVPORT1_VSYNC_ACTIVE 1 +#define RAW_INT_ZVPORT1_VSYNC_CLEAR 1 +#define RAW_INT_ZVPORT0_VSYNC 3:3 +#define RAW_INT_ZVPORT0_VSYNC_INACTIVE 0 +#define RAW_INT_ZVPORT0_VSYNC_ACTIVE 1 +#define RAW_INT_ZVPORT0_VSYNC_CLEAR 1 +#define RAW_INT_CRT_VSYNC 2:2 +#define RAW_INT_CRT_VSYNC_INACTIVE 0 +#define RAW_INT_CRT_VSYNC_ACTIVE 1 +#define RAW_INT_CRT_VSYNC_CLEAR 1 +#define RAW_INT_PANEL_VSYNC 1:1 +#define RAW_INT_PANEL_VSYNC_INACTIVE 0 +#define RAW_INT_PANEL_VSYNC_ACTIVE 1 +#define RAW_INT_PANEL_VSYNC_CLEAR 1 +#define RAW_INT_VGA_VSYNC 0:0 +#define RAW_INT_VGA_VSYNC_INACTIVE 0 +#define RAW_INT_VGA_VSYNC_ACTIVE 1 +#define RAW_INT_VGA_VSYNC_CLEAR 1 + +#define INT_STATUS 0x000024 +#define INT_STATUS_GPIO31 31:31 +#define INT_STATUS_GPIO31_INACTIVE 0 +#define INT_STATUS_GPIO31_ACTIVE 1 +#define INT_STATUS_GPIO30 30:30 +#define INT_STATUS_GPIO30_INACTIVE 0 +#define INT_STATUS_GPIO30_ACTIVE 1 +#define INT_STATUS_GPIO29 29:29 +#define INT_STATUS_GPIO29_INACTIVE 0 +#define INT_STATUS_GPIO29_ACTIVE 1 +#define INT_STATUS_GPIO28 28:28 +#define INT_STATUS_GPIO28_INACTIVE 0 +#define INT_STATUS_GPIO28_ACTIVE 1 +#define INT_STATUS_GPIO27 27:27 +#define INT_STATUS_GPIO27_INACTIVE 0 +#define INT_STATUS_GPIO27_ACTIVE 1 +#define INT_STATUS_GPIO26 26:26 +#define INT_STATUS_GPIO26_INACTIVE 0 +#define INT_STATUS_GPIO26_ACTIVE 1 +#define INT_STATUS_GPIO25 25:25 +#define INT_STATUS_GPIO25_INACTIVE 0 +#define INT_STATUS_GPIO25_ACTIVE 1 +#define INT_STATUS_I2C 12:12 +#define INT_STATUS_I2C_INACTIVE 0 +#define INT_STATUS_I2C_ACTIVE 1 +#define INT_STATUS_PWM 11:11 +#define INT_STATUS_PWM_INACTIVE 0 +#define INT_STATUS_PWM_ACTIVE 1 +#define INT_STATUS_DMA1 10:10 +#define INT_STATUS_DMA1_INACTIVE 0 +#define INT_STATUS_DMA1_ACTIVE 1 +#define INT_STATUS_DMA0 9:9 +#define INT_STATUS_DMA0_INACTIVE 0 +#define INT_STATUS_DMA0_ACTIVE 1 +#define INT_STATUS_PCI 8:8 +#define INT_STATUS_PCI_INACTIVE 0 +#define INT_STATUS_PCI_ACTIVE 1 +#define INT_STATUS_SSP1 7:7 +#define INT_STATUS_SSP1_INACTIVE 0 +#define INT_STATUS_SSP1_ACTIVE 1 +#define INT_STATUS_SSP0 6:6 +#define INT_STATUS_SSP0_INACTIVE 0 +#define INT_STATUS_SSP0_ACTIVE 1 +#define INT_STATUS_DE 5:5 +#define INT_STATUS_DE_INACTIVE 0 +#define INT_STATUS_DE_ACTIVE 1 +#define INT_STATUS_ZVPORT1_VSYNC 4:4 +#define INT_STATUS_ZVPORT1_VSYNC_INACTIVE 0 +#define INT_STATUS_ZVPORT1_VSYNC_ACTIVE 1 +#define INT_STATUS_ZVPORT0_VSYNC 3:3 +#define INT_STATUS_ZVPORT0_VSYNC_INACTIVE 0 +#define INT_STATUS_ZVPORT0_VSYNC_ACTIVE 1 +#define INT_STATUS_CRT_VSYNC 2:2 +#define INT_STATUS_CRT_VSYNC_INACTIVE 0 +#define INT_STATUS_CRT_VSYNC_ACTIVE 1 +#define INT_STATUS_PANEL_VSYNC 1:1 +#define INT_STATUS_PANEL_VSYNC_INACTIVE 0 +#define INT_STATUS_PANEL_VSYNC_ACTIVE 1 +#define INT_STATUS_VGA_VSYNC 0:0 +#define INT_STATUS_VGA_VSYNC_INACTIVE 0 +#define INT_STATUS_VGA_VSYNC_ACTIVE 1 + +#define INT_MASK 0x000028 +#define INT_MASK_GPIO31 31:31 +#define INT_MASK_GPIO31_DISABLE 0 +#define INT_MASK_GPIO31_ENABLE 1 +#define INT_MASK_GPIO30 30:30 +#define INT_MASK_GPIO30_DISABLE 0 +#define INT_MASK_GPIO30_ENABLE 1 +#define INT_MASK_GPIO29 29:29 +#define INT_MASK_GPIO29_DISABLE 0 +#define INT_MASK_GPIO29_ENABLE 1 +#define INT_MASK_GPIO28 28:28 +#define INT_MASK_GPIO28_DISABLE 0 +#define INT_MASK_GPIO28_ENABLE 1 +#define INT_MASK_GPIO27 27:27 +#define INT_MASK_GPIO27_DISABLE 0 +#define INT_MASK_GPIO27_ENABLE 1 +#define INT_MASK_GPIO26 26:26 +#define INT_MASK_GPIO26_DISABLE 0 +#define INT_MASK_GPIO26_ENABLE 1 +#define INT_MASK_GPIO25 25:25 +#define INT_MASK_GPIO25_DISABLE 0 +#define INT_MASK_GPIO25_ENABLE 1 +#define INT_MASK_I2C 12:12 +#define INT_MASK_I2C_DISABLE 0 +#define INT_MASK_I2C_ENABLE 1 +#define INT_MASK_PWM 11:11 +#define INT_MASK_PWM_DISABLE 0 +#define INT_MASK_PWM_ENABLE 1 +#define INT_MASK_DMA1 10:10 +#define INT_MASK_DMA1_DISABLE 0 +#define INT_MASK_DMA1_ENABLE 1 +#define INT_MASK_DMA 9:9 +#define INT_MASK_DMA_DISABLE 0 +#define INT_MASK_DMA_ENABLE 1 +#define INT_MASK_PCI 8:8 +#define INT_MASK_PCI_DISABLE 0 +#define INT_MASK_PCI_ENABLE 1 +#define INT_MASK_SSP1 7:7 +#define INT_MASK_SSP1_DISABLE 0 +#define INT_MASK_SSP1_ENABLE 1 +#define INT_MASK_SSP0 6:6 +#define INT_MASK_SSP0_DISABLE 0 +#define INT_MASK_SSP0_ENABLE 1 +#define INT_MASK_DE 5:5 +#define INT_MASK_DE_DISABLE 0 +#define INT_MASK_DE_ENABLE 1 +#define INT_MASK_ZVPORT1_VSYNC 4:4 +#define INT_MASK_ZVPORT1_VSYNC_DISABLE 0 +#define INT_MASK_ZVPORT1_VSYNC_ENABLE 1 +#define INT_MASK_ZVPORT0_VSYNC 3:3 +#define INT_MASK_ZVPORT0_VSYNC_DISABLE 0 +#define INT_MASK_ZVPORT0_VSYNC_ENABLE 1 +#define INT_MASK_CRT_VSYNC 2:2 +#define INT_MASK_CRT_VSYNC_DISABLE 0 +#define INT_MASK_CRT_VSYNC_ENABLE 1 +#define INT_MASK_PANEL_VSYNC 1:1 +#define INT_MASK_PANEL_VSYNC_DISABLE 0 +#define INT_MASK_PANEL_VSYNC_ENABLE 1 +#define INT_MASK_VGA_VSYNC 0:0 +#define INT_MASK_VGA_VSYNC_DISABLE 0 +#define INT_MASK_VGA_VSYNC_ENABLE 1 + +#define CURRENT_GATE 0x000040 +#define CURRENT_GATE_MCLK 15:14 +#define CURRENT_GATE_MCLK_112MHZ 0 +#define CURRENT_GATE_MCLK_84MHZ 1 +#define CURRENT_GATE_MCLK_56MHZ 2 +#define CURRENT_GATE_MCLK_42MHZ 3 +#define CURRENT_GATE_M2XCLK 13:12 +#define CURRENT_GATE_M2XCLK_336MHZ 0 +#define CURRENT_GATE_M2XCLK_168MHZ 1 +#define CURRENT_GATE_M2XCLK_112MHZ 2 +#define CURRENT_GATE_M2XCLK_84MHZ 3 +#define CURRENT_GATE_VGA 10:10 +#define CURRENT_GATE_VGA_OFF 0 +#define CURRENT_GATE_VGA_ON 1 +#define CURRENT_GATE_PWM 9:9 +#define CURRENT_GATE_PWM_OFF 0 +#define CURRENT_GATE_PWM_ON 1 +#define CURRENT_GATE_I2C 8:8 +#define CURRENT_GATE_I2C_OFF 0 +#define CURRENT_GATE_I2C_ON 1 +#define CURRENT_GATE_SSP 7:7 +#define CURRENT_GATE_SSP_OFF 0 +#define CURRENT_GATE_SSP_ON 1 +#define CURRENT_GATE_GPIO 6:6 +#define CURRENT_GATE_GPIO_OFF 0 +#define CURRENT_GATE_GPIO_ON 1 +#define CURRENT_GATE_ZVPORT 5:5 +#define CURRENT_GATE_ZVPORT_OFF 0 +#define CURRENT_GATE_ZVPORT_ON 1 +#define CURRENT_GATE_CSC 4:4 +#define CURRENT_GATE_CSC_OFF 0 +#define CURRENT_GATE_CSC_ON 1 +#define CURRENT_GATE_DE 3:3 +#define CURRENT_GATE_DE_OFF 0 +#define CURRENT_GATE_DE_ON 1 +#define CURRENT_GATE_DISPLAY 2:2 +#define CURRENT_GATE_DISPLAY_OFF 0 +#define CURRENT_GATE_DISPLAY_ON 1 +#define CURRENT_GATE_LOCALMEM 1:1 +#define CURRENT_GATE_LOCALMEM_OFF 0 +#define CURRENT_GATE_LOCALMEM_ON 1 +#define CURRENT_GATE_DMA 0:0 +#define CURRENT_GATE_DMA_OFF 0 +#define CURRENT_GATE_DMA_ON 1 + +#define MODE0_GATE 0x000044 +#define MODE0_GATE_MCLK 15:14 +#define MODE0_GATE_MCLK_112MHZ 0 +#define MODE0_GATE_MCLK_84MHZ 1 +#define MODE0_GATE_MCLK_56MHZ 2 +#define MODE0_GATE_MCLK_42MHZ 3 +#define MODE0_GATE_M2XCLK 13:12 +#define MODE0_GATE_M2XCLK_336MHZ 0 +#define MODE0_GATE_M2XCLK_168MHZ 1 +#define MODE0_GATE_M2XCLK_112MHZ 2 +#define MODE0_GATE_M2XCLK_84MHZ 3 +#define MODE0_GATE_VGA 10:10 +#define MODE0_GATE_VGA_OFF 0 +#define MODE0_GATE_VGA_ON 1 +#define MODE0_GATE_PWM 9:9 +#define MODE0_GATE_PWM_OFF 0 +#define MODE0_GATE_PWM_ON 1 +#define MODE0_GATE_I2C 8:8 +#define MODE0_GATE_I2C_OFF 0 +#define MODE0_GATE_I2C_ON 1 +#define MODE0_GATE_SSP 7:7 +#define MODE0_GATE_SSP_OFF 0 +#define MODE0_GATE_SSP_ON 1 +#define MODE0_GATE_GPIO 6:6 +#define MODE0_GATE_GPIO_OFF 0 +#define MODE0_GATE_GPIO_ON 1 +#define MODE0_GATE_ZVPORT 5:5 +#define MODE0_GATE_ZVPORT_OFF 0 +#define MODE0_GATE_ZVPORT_ON 1 +#define MODE0_GATE_CSC 4:4 +#define MODE0_GATE_CSC_OFF 0 +#define MODE0_GATE_CSC_ON 1 +#define MODE0_GATE_DE 3:3 +#define MODE0_GATE_DE_OFF 0 +#define MODE0_GATE_DE_ON 1 +#define MODE0_GATE_DISPLAY 2:2 +#define MODE0_GATE_DISPLAY_OFF 0 +#define MODE0_GATE_DISPLAY_ON 1 +#define MODE0_GATE_LOCALMEM 1:1 +#define MODE0_GATE_LOCALMEM_OFF 0 +#define MODE0_GATE_LOCALMEM_ON 1 +#define MODE0_GATE_DMA 0:0 +#define MODE0_GATE_DMA_OFF 0 +#define MODE0_GATE_DMA_ON 1 + +#define MODE1_GATE 0x000048 +#define MODE1_GATE_MCLK 15:14 +#define MODE1_GATE_MCLK_112MHZ 0 +#define MODE1_GATE_MCLK_84MHZ 1 +#define MODE1_GATE_MCLK_56MHZ 2 +#define MODE1_GATE_MCLK_42MHZ 3 +#define MODE1_GATE_M2XCLK 13:12 +#define MODE1_GATE_M2XCLK_336MHZ 0 +#define MODE1_GATE_M2XCLK_168MHZ 1 +#define MODE1_GATE_M2XCLK_112MHZ 2 +#define MODE1_GATE_M2XCLK_84MHZ 3 +#define MODE1_GATE_VGA 10:10 +#define MODE1_GATE_VGA_OFF 0 +#define MODE1_GATE_VGA_ON 1 +#define MODE1_GATE_PWM 9:9 +#define MODE1_GATE_PWM_OFF 0 +#define MODE1_GATE_PWM_ON 1 +#define MODE1_GATE_I2C 8:8 +#define MODE1_GATE_I2C_OFF 0 +#define MODE1_GATE_I2C_ON 1 +#define MODE1_GATE_SSP 7:7 +#define MODE1_GATE_SSP_OFF 0 +#define MODE1_GATE_SSP_ON 1 +#define MODE1_GATE_GPIO 6:6 +#define MODE1_GATE_GPIO_OFF 0 +#define MODE1_GATE_GPIO_ON 1 +#define MODE1_GATE_ZVPORT 5:5 +#define MODE1_GATE_ZVPORT_OFF 0 +#define MODE1_GATE_ZVPORT_ON 1 +#define MODE1_GATE_CSC 4:4 +#define MODE1_GATE_CSC_OFF 0 +#define MODE1_GATE_CSC_ON 1 +#define MODE1_GATE_DE 3:3 +#define MODE1_GATE_DE_OFF 0 +#define MODE1_GATE_DE_ON 1 +#define MODE1_GATE_DISPLAY 2:2 +#define MODE1_GATE_DISPLAY_OFF 0 +#define MODE1_GATE_DISPLAY_ON 1 +#define MODE1_GATE_LOCALMEM 1:1 +#define MODE1_GATE_LOCALMEM_OFF 0 +#define MODE1_GATE_LOCALMEM_ON 1 +#define MODE1_GATE_DMA 0:0 +#define MODE1_GATE_DMA_OFF 0 +#define MODE1_GATE_DMA_ON 1 + +#define POWER_MODE_CTRL 0x00004C +#define POWER_MODE_CTRL_336CLK 4:4 +#define POWER_MODE_CTRL_336CLK_OFF 0 +#define POWER_MODE_CTRL_336CLK_ON 1 +#define POWER_MODE_CTRL_OSC_INPUT 3:3 +#define POWER_MODE_CTRL_OSC_INPUT_OFF 0 +#define POWER_MODE_CTRL_OSC_INPUT_ON 1 +#define POWER_MODE_CTRL_ACPI 2:2 +#define POWER_MODE_CTRL_ACPI_OFF 0 +#define POWER_MODE_CTRL_ACPI_ON 1 +#define POWER_MODE_CTRL_MODE 1:0 +#define POWER_MODE_CTRL_MODE_MODE0 0 +#define POWER_MODE_CTRL_MODE_MODE1 1 +#define POWER_MODE_CTRL_MODE_SLEEP 2 + +#define PCI_MASTER_BASE 0x000050 +#define PCI_MASTER_BASE_ADDRESS 7:0 + +#define DEVICE_ID 0x000054 +#define DEVICE_ID_DEVICE_ID 31:16 +#define DEVICE_ID_REVISION_ID 7:0 + +#define PLL_CLK_COUNT 0x000058 +#define PLL_CLK_COUNT_COUNTER 15:0 + +#define PANEL_PLL_CTRL 0x00005C +#define PANEL_PLL_CTRL_BYPASS 18:18 +#define PANEL_PLL_CTRL_BYPASS_OFF 0 +#define PANEL_PLL_CTRL_BYPASS_ON 1 +#define PANEL_PLL_CTRL_POWER 17:17 +#define PANEL_PLL_CTRL_POWER_OFF 0 +#define PANEL_PLL_CTRL_POWER_ON 1 +#define PANEL_PLL_CTRL_INPUT 16:16 +#define PANEL_PLL_CTRL_INPUT_OSC 0 +#define PANEL_PLL_CTRL_INPUT_TESTCLK 1 +#ifdef VALIDATION_CHIP + #define PANEL_PLL_CTRL_OD 15:14 +#else + #define PANEL_PLL_CTRL_POD 15:14 + #define PANEL_PLL_CTRL_OD 13:12 +#endif +#define PANEL_PLL_CTRL_N 11:8 +#define PANEL_PLL_CTRL_M 7:0 + +#define CRT_PLL_CTRL 0x000060 +#define CRT_PLL_CTRL_BYPASS 18:18 +#define CRT_PLL_CTRL_BYPASS_OFF 0 +#define CRT_PLL_CTRL_BYPASS_ON 1 +#define CRT_PLL_CTRL_POWER 17:17 +#define CRT_PLL_CTRL_POWER_OFF 0 +#define CRT_PLL_CTRL_POWER_ON 1 +#define CRT_PLL_CTRL_INPUT 16:16 +#define CRT_PLL_CTRL_INPUT_OSC 0 +#define CRT_PLL_CTRL_INPUT_TESTCLK 1 +#ifdef VALIDATION_CHIP + #define CRT_PLL_CTRL_OD 15:14 +#else + #define CRT_PLL_CTRL_POD 15:14 + #define CRT_PLL_CTRL_OD 13:12 +#endif +#define CRT_PLL_CTRL_N 11:8 +#define CRT_PLL_CTRL_M 7:0 + +#define VGA_PLL0_CTRL 0x000064 +#define VGA_PLL0_CTRL_BYPASS 18:18 +#define VGA_PLL0_CTRL_BYPASS_OFF 0 +#define VGA_PLL0_CTRL_BYPASS_ON 1 +#define VGA_PLL0_CTRL_POWER 17:17 +#define VGA_PLL0_CTRL_POWER_OFF 0 +#define VGA_PLL0_CTRL_POWER_ON 1 +#define VGA_PLL0_CTRL_INPUT 16:16 +#define VGA_PLL0_CTRL_INPUT_OSC 0 +#define VGA_PLL0_CTRL_INPUT_TESTCLK 1 +#ifdef VALIDATION_CHIP + #define VGA_PLL0_CTRL_OD 15:14 +#else + #define VGA_PLL0_CTRL_POD 15:14 + #define VGA_PLL0_CTRL_OD 13:12 +#endif +#define VGA_PLL0_CTRL_N 11:8 +#define VGA_PLL0_CTRL_M 7:0 + +#define VGA_PLL1_CTRL 0x000068 +#define VGA_PLL1_CTRL_BYPASS 18:18 +#define VGA_PLL1_CTRL_BYPASS_OFF 0 +#define VGA_PLL1_CTRL_BYPASS_ON 1 +#define VGA_PLL1_CTRL_POWER 17:17 +#define VGA_PLL1_CTRL_POWER_OFF 0 +#define VGA_PLL1_CTRL_POWER_ON 1 +#define VGA_PLL1_CTRL_INPUT 16:16 +#define VGA_PLL1_CTRL_INPUT_OSC 0 +#define VGA_PLL1_CTRL_INPUT_TESTCLK 1 +#ifdef VALIDATION_CHIP + #define VGA_PLL1_CTRL_OD 15:14 +#else + #define VGA_PLL1_CTRL_POD 15:14 + #define VGA_PLL1_CTRL_OD 13:12 +#endif +#define VGA_PLL1_CTRL_N 11:8 +#define VGA_PLL1_CTRL_M 7:0 + +#define SCRATCH_DATA 0x00006c + +#define MXCLK_PLL_CTRL 0x000070 +#define MXCLK_PLL_CTRL_BYPASS 18:18 +#define MXCLK_PLL_CTRL_BYPASS_OFF 0 +#define MXCLK_PLL_CTRL_BYPASS_ON 1 +#define MXCLK_PLL_CTRL_POWER 17:17 +#define MXCLK_PLL_CTRL_POWER_OFF 0 +#define MXCLK_PLL_CTRL_POWER_ON 1 +#define MXCLK_PLL_CTRL_INPUT 16:16 +#define MXCLK_PLL_CTRL_INPUT_OSC 0 +#define MXCLK_PLL_CTRL_INPUT_TESTCLK 1 +#define MXCLK_PLL_CTRL_POD 15:14 +#define MXCLK_PLL_CTRL_OD 13:12 +#define MXCLK_PLL_CTRL_N 11:8 +#define MXCLK_PLL_CTRL_M 7:0 + +#define VGA_CONFIGURATION 0x000088 +#define VGA_CONFIGURATION_USER_DEFINE 5:4 +#define VGA_CONFIGURATION_PLL 2:2 +#define VGA_CONFIGURATION_PLL_VGA 0 +#define VGA_CONFIGURATION_PLL_PANEL 1 +#define VGA_CONFIGURATION_MODE 1:1 +#define VGA_CONFIGURATION_MODE_TEXT 0 +#define VGA_CONFIGURATION_MODE_GRAPHIC 1 + + +#define GPIO_DATA 0x010000 +#define GPIO_DATA_31 31:31 +#define GPIO_DATA_30 30:30 +#define GPIO_DATA_29 29:29 +#define GPIO_DATA_28 28:28 +#define GPIO_DATA_27 27:27 +#define GPIO_DATA_26 26:26 +#define GPIO_DATA_25 25:25 +#define GPIO_DATA_24 24:24 +#define GPIO_DATA_23 23:23 +#define GPIO_DATA_22 22:22 +#define GPIO_DATA_21 21:21 +#define GPIO_DATA_20 20:20 +#define GPIO_DATA_19 19:19 +#define GPIO_DATA_18 18:18 +#define GPIO_DATA_17 17:17 +#define GPIO_DATA_16 16:16 +#define GPIO_DATA_15 15:15 +#define GPIO_DATA_14 14:14 +#define GPIO_DATA_13 13:13 +#define GPIO_DATA_12 12:12 +#define GPIO_DATA_11 11:11 +#define GPIO_DATA_10 10:10 +#define GPIO_DATA_9 9:9 +#define GPIO_DATA_8 8:8 +#define GPIO_DATA_7 7:7 +#define GPIO_DATA_6 6:6 +#define GPIO_DATA_5 5:5 +#define GPIO_DATA_4 4:4 +#define GPIO_DATA_3 3:3 +#define GPIO_DATA_2 2:2 +#define GPIO_DATA_1 1:1 +#define GPIO_DATA_0 0:0 + +#define GPIO_DATA_DIRECTION 0x010004 +#define GPIO_DATA_DIRECTION_31 31:31 +#define GPIO_DATA_DIRECTION_31_INPUT 0 +#define GPIO_DATA_DIRECTION_31_OUTPUT 1 +#define GPIO_DATA_DIRECTION_30 30:30 +#define GPIO_DATA_DIRECTION_30_INPUT 0 +#define GPIO_DATA_DIRECTION_30_OUTPUT 1 +#define GPIO_DATA_DIRECTION_29 29:29 +#define GPIO_DATA_DIRECTION_29_INPUT 0 +#define GPIO_DATA_DIRECTION_29_OUTPUT 1 +#define GPIO_DATA_DIRECTION_28 28:28 +#define GPIO_DATA_DIRECTION_28_INPUT 0 +#define GPIO_DATA_DIRECTION_28_OUTPUT 1 +#define GPIO_DATA_DIRECTION_27 27:27 +#define GPIO_DATA_DIRECTION_27_INPUT 0 +#define GPIO_DATA_DIRECTION_27_OUTPUT 1 +#define GPIO_DATA_DIRECTION_26 26:26 +#define GPIO_DATA_DIRECTION_26_INPUT 0 +#define GPIO_DATA_DIRECTION_26_OUTPUT 1 +#define GPIO_DATA_DIRECTION_25 25:25 +#define GPIO_DATA_DIRECTION_25_INPUT 0 +#define GPIO_DATA_DIRECTION_25_OUTPUT 1 +#define GPIO_DATA_DIRECTION_24 24:24 +#define GPIO_DATA_DIRECTION_24_INPUT 0 +#define GPIO_DATA_DIRECTION_24_OUTPUT 1 +#define GPIO_DATA_DIRECTION_23 23:23 +#define GPIO_DATA_DIRECTION_23_INPUT 0 +#define GPIO_DATA_DIRECTION_23_OUTPUT 1 +#define GPIO_DATA_DIRECTION_22 22:22 +#define GPIO_DATA_DIRECTION_22_INPUT 0 +#define GPIO_DATA_DIRECTION_22_OUTPUT 1 +#define GPIO_DATA_DIRECTION_21 21:21 +#define GPIO_DATA_DIRECTION_21_INPUT 0 +#define GPIO_DATA_DIRECTION_21_OUTPUT 1 +#define GPIO_DATA_DIRECTION_20 20:20 +#define GPIO_DATA_DIRECTION_20_INPUT 0 +#define GPIO_DATA_DIRECTION_20_OUTPUT 1 +#define GPIO_DATA_DIRECTION_19 19:19 +#define GPIO_DATA_DIRECTION_19_INPUT 0 +#define GPIO_DATA_DIRECTION_19_OUTPUT 1 +#define GPIO_DATA_DIRECTION_18 18:18 +#define GPIO_DATA_DIRECTION_18_INPUT 0 +#define GPIO_DATA_DIRECTION_18_OUTPUT 1 +#define GPIO_DATA_DIRECTION_17 17:17 +#define GPIO_DATA_DIRECTION_17_INPUT 0 +#define GPIO_DATA_DIRECTION_17_OUTPUT 1 +#define GPIO_DATA_DIRECTION_16 16:16 +#define GPIO_DATA_DIRECTION_16_INPUT 0 +#define GPIO_DATA_DIRECTION_16_OUTPUT 1 +#define GPIO_DATA_DIRECTION_15 15:15 +#define GPIO_DATA_DIRECTION_15_INPUT 0 +#define GPIO_DATA_DIRECTION_15_OUTPUT 1 +#define GPIO_DATA_DIRECTION_14 14:14 +#define GPIO_DATA_DIRECTION_14_INPUT 0 +#define GPIO_DATA_DIRECTION_14_OUTPUT 1 +#define GPIO_DATA_DIRECTION_13 13:13 +#define GPIO_DATA_DIRECTION_13_INPUT 0 +#define GPIO_DATA_DIRECTION_13_OUTPUT 1 +#define GPIO_DATA_DIRECTION_12 12:12 +#define GPIO_DATA_DIRECTION_12_INPUT 0 +#define GPIO_DATA_DIRECTION_12_OUTPUT 1 +#define GPIO_DATA_DIRECTION_11 11:11 +#define GPIO_DATA_DIRECTION_11_INPUT 0 +#define GPIO_DATA_DIRECTION_11_OUTPUT 1 +#define GPIO_DATA_DIRECTION_10 10:10 +#define GPIO_DATA_DIRECTION_10_INPUT 0 +#define GPIO_DATA_DIRECTION_10_OUTPUT 1 +#define GPIO_DATA_DIRECTION_9 9:9 +#define GPIO_DATA_DIRECTION_9_INPUT 0 +#define GPIO_DATA_DIRECTION_9_OUTPUT 1 +#define GPIO_DATA_DIRECTION_8 8:8 +#define GPIO_DATA_DIRECTION_8_INPUT 0 +#define GPIO_DATA_DIRECTION_8_OUTPUT 1 +#define GPIO_DATA_DIRECTION_7 7:7 +#define GPIO_DATA_DIRECTION_7_INPUT 0 +#define GPIO_DATA_DIRECTION_7_OUTPUT 1 +#define GPIO_DATA_DIRECTION_6 6:6 +#define GPIO_DATA_DIRECTION_6_INPUT 0 +#define GPIO_DATA_DIRECTION_6_OUTPUT 1 +#define GPIO_DATA_DIRECTION_5 5:5 +#define GPIO_DATA_DIRECTION_5_INPUT 0 +#define GPIO_DATA_DIRECTION_5_OUTPUT 1 +#define GPIO_DATA_DIRECTION_4 4:4 +#define GPIO_DATA_DIRECTION_4_INPUT 0 +#define GPIO_DATA_DIRECTION_4_OUTPUT 1 +#define GPIO_DATA_DIRECTION_3 3:3 +#define GPIO_DATA_DIRECTION_3_INPUT 0 +#define GPIO_DATA_DIRECTION_3_OUTPUT 1 +#define GPIO_DATA_DIRECTION_2 2:2 +#define GPIO_DATA_DIRECTION_2_INPUT 0 +#define GPIO_DATA_DIRECTION_2_OUTPUT 1 +#define GPIO_DATA_DIRECTION_1 131 +#define GPIO_DATA_DIRECTION_1_INPUT 0 +#define GPIO_DATA_DIRECTION_1_OUTPUT 1 +#define GPIO_DATA_DIRECTION_0 0:0 +#define GPIO_DATA_DIRECTION_0_INPUT 0 +#define GPIO_DATA_DIRECTION_0_OUTPUT 1 + +#define GPIO_INTERRUPT_SETUP 0x010008 +#define GPIO_INTERRUPT_SETUP_TRIGGER_31 22:22 +#define GPIO_INTERRUPT_SETUP_TRIGGER_31_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_31_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_30 21:21 +#define GPIO_INTERRUPT_SETUP_TRIGGER_30_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_30_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_29 20:20 +#define GPIO_INTERRUPT_SETUP_TRIGGER_29_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_29_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_28 19:19 +#define GPIO_INTERRUPT_SETUP_TRIGGER_28_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_28_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_27 18:18 +#define GPIO_INTERRUPT_SETUP_TRIGGER_27_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_27_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_26 17:17 +#define GPIO_INTERRUPT_SETUP_TRIGGER_26_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_26_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_TRIGGER_25 16:16 +#define GPIO_INTERRUPT_SETUP_TRIGGER_25_EDGE 0 +#define GPIO_INTERRUPT_SETUP_TRIGGER_25_LEVEL 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_31 14:14 +#define GPIO_INTERRUPT_SETUP_ACTIVE_31_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_31_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_30 13:13 +#define GPIO_INTERRUPT_SETUP_ACTIVE_30_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_30_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_29 12:12 +#define GPIO_INTERRUPT_SETUP_ACTIVE_29_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_29_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_28 11:11 +#define GPIO_INTERRUPT_SETUP_ACTIVE_28_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_28_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_27 10:10 +#define GPIO_INTERRUPT_SETUP_ACTIVE_27_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_27_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_26 9:9 +#define GPIO_INTERRUPT_SETUP_ACTIVE_26_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_26_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ACTIVE_25 8:8 +#define GPIO_INTERRUPT_SETUP_ACTIVE_25_LOW 0 +#define GPIO_INTERRUPT_SETUP_ACTIVE_25_HIGH 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_31 6:6 +#define GPIO_INTERRUPT_SETUP_ENABLE_31_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_31_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_30 5:5 +#define GPIO_INTERRUPT_SETUP_ENABLE_30_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_30_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_29 4:4 +#define GPIO_INTERRUPT_SETUP_ENABLE_29_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_29_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_28 3:3 +#define GPIO_INTERRUPT_SETUP_ENABLE_28_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_28_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_27 2:2 +#define GPIO_INTERRUPT_SETUP_ENABLE_27_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_27_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_26 1:1 +#define GPIO_INTERRUPT_SETUP_ENABLE_26_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_26_INTERRUPT 1 +#define GPIO_INTERRUPT_SETUP_ENABLE_25 0:0 +#define GPIO_INTERRUPT_SETUP_ENABLE_25_GPIO 0 +#define GPIO_INTERRUPT_SETUP_ENABLE_25_INTERRUPT 1 + +#define GPIO_INTERRUPT_STATUS 0x01000C +#define GPIO_INTERRUPT_STATUS_31 22:22 +#define GPIO_INTERRUPT_STATUS_31_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_31_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_31_RESET 1 +#define GPIO_INTERRUPT_STATUS_30 21:21 +#define GPIO_INTERRUPT_STATUS_30_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_30_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_30_RESET 1 +#define GPIO_INTERRUPT_STATUS_29 20:20 +#define GPIO_INTERRUPT_STATUS_29_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_29_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_29_RESET 1 +#define GPIO_INTERRUPT_STATUS_28 19:19 +#define GPIO_INTERRUPT_STATUS_28_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_28_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_28_RESET 1 +#define GPIO_INTERRUPT_STATUS_27 18:18 +#define GPIO_INTERRUPT_STATUS_27_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_27_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_27_RESET 1 +#define GPIO_INTERRUPT_STATUS_26 17:17 +#define GPIO_INTERRUPT_STATUS_26_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_26_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_26_RESET 1 +#define GPIO_INTERRUPT_STATUS_25 16:16 +#define GPIO_INTERRUPT_STATUS_25_INACTIVE 0 +#define GPIO_INTERRUPT_STATUS_25_ACTIVE 1 +#define GPIO_INTERRUPT_STATUS_25_RESET 1 + + +#define PANEL_DISPLAY_CTRL 0x080000 +#define PANEL_DISPLAY_CTRL_RESERVED_1_MASK 31:30 +#define PANEL_DISPLAY_CTRL_RESERVED_1_MASK_DISABLE 0 +#define PANEL_DISPLAY_CTRL_RESERVED_1_MASK_ENABLE 3 +#define PANEL_DISPLAY_CTRL_SELECT 29:28 +#define PANEL_DISPLAY_CTRL_SELECT_PANEL 0 +#define PANEL_DISPLAY_CTRL_SELECT_VGA 1 +#define PANEL_DISPLAY_CTRL_SELECT_CRT 2 +#define PANEL_DISPLAY_CTRL_FPEN 27:27 +#define PANEL_DISPLAY_CTRL_FPEN_LOW 0 +#define PANEL_DISPLAY_CTRL_FPEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_VBIASEN 26:26 +#define PANEL_DISPLAY_CTRL_VBIASEN_LOW 0 +#define PANEL_DISPLAY_CTRL_VBIASEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_DATA 25:25 +#define PANEL_DISPLAY_CTRL_DATA_DISABLE 0 +#define PANEL_DISPLAY_CTRL_DATA_ENABLE 1 +#define PANEL_DISPLAY_CTRL_FPVDDEN 24:24 +#define PANEL_DISPLAY_CTRL_FPVDDEN_LOW 0 +#define PANEL_DISPLAY_CTRL_FPVDDEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_RESERVED_2_MASK 23:20 +#define PANEL_DISPLAY_CTRL_RESERVED_2_MASK_DISABLE 0 +#define PANEL_DISPLAY_CTRL_RESERVED_2_MASK_ENABLE 15 + +#define PANEL_DISPLAY_CTRL_TFT_DISP 19:18 +#define PANEL_DISPLAY_CTRL_TFT_DISP_24 0 +#define PANEL_DISPLAY_CTRL_TFT_DISP_36 1 +#define PANEL_DISPLAY_CTRL_TFT_DISP_18 2 + + +#define PANEL_DISPLAY_CTRL_DUAL_DISPLAY 19:19 +#define PANEL_DISPLAY_CTRL_DUAL_DISPLAY_DISABLE 0 +#define PANEL_DISPLAY_CTRL_DUAL_DISPLAY_ENABLE 1 +#define PANEL_DISPLAY_CTRL_DOUBLE_PIXEL 18:18 +#define PANEL_DISPLAY_CTRL_DOUBLE_PIXEL_DISABLE 0 +#define PANEL_DISPLAY_CTRL_DOUBLE_PIXEL_ENABLE 1 +#define PANEL_DISPLAY_CTRL_FIFO 17:16 +#define PANEL_DISPLAY_CTRL_FIFO_1 0 +#define PANEL_DISPLAY_CTRL_FIFO_3 1 +#define PANEL_DISPLAY_CTRL_FIFO_7 2 +#define PANEL_DISPLAY_CTRL_FIFO_11 3 +#define PANEL_DISPLAY_CTRL_RESERVED_3_MASK 15:15 +#define PANEL_DISPLAY_CTRL_RESERVED_3_MASK_DISABLE 0 +#define PANEL_DISPLAY_CTRL_RESERVED_3_MASK_ENABLE 1 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE 14:14 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE 13:13 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE 12:12 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_VSYNC 11:11 +#define PANEL_DISPLAY_CTRL_VSYNC_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_VSYNC_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_CAPTURE_TIMING 10:10 +#define PANEL_DISPLAY_CTRL_CAPTURE_TIMING_DISABLE 0 +#define PANEL_DISPLAY_CTRL_CAPTURE_TIMING_ENABLE 1 +#define PANEL_DISPLAY_CTRL_COLOR_KEY 9:9 +#define PANEL_DISPLAY_CTRL_COLOR_KEY_DISABLE 0 +#define PANEL_DISPLAY_CTRL_COLOR_KEY_ENABLE 1 +#define PANEL_DISPLAY_CTRL_TIMING 8:8 +#define PANEL_DISPLAY_CTRL_TIMING_DISABLE 0 +#define PANEL_DISPLAY_CTRL_TIMING_ENABLE 1 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR 7:7 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR_DOWN 0 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR_UP 1 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN 6:6 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DISABLE 0 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_ENABLE 1 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR 5:5 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR_RIGHT 0 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR_LEFT 1 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN 4:4 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DISABLE 0 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_ENABLE 1 +#define PANEL_DISPLAY_CTRL_GAMMA 3:3 +#define PANEL_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define PANEL_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define PANEL_DISPLAY_CTRL_PLANE 2:2 +#define PANEL_DISPLAY_CTRL_PLANE_DISABLE 0 +#define PANEL_DISPLAY_CTRL_PLANE_ENABLE 1 +#define PANEL_DISPLAY_CTRL_FORMAT 1:0 +#define PANEL_DISPLAY_CTRL_FORMAT_8 0 +#define PANEL_DISPLAY_CTRL_FORMAT_16 1 +#define PANEL_DISPLAY_CTRL_FORMAT_32 2 + +#define PANEL_PAN_CTRL 0x080004 +#define PANEL_PAN_CTRL_VERTICAL_PAN 31:24 +#define PANEL_PAN_CTRL_VERTICAL_VSYNC 21:16 +#define PANEL_PAN_CTRL_HORIZONTAL_PAN 15:8 +#define PANEL_PAN_CTRL_HORIZONTAL_VSYNC 5:0 + +#define PANEL_COLOR_KEY 0x080008 +#define PANEL_COLOR_KEY_MASK 31:16 +#define PANEL_COLOR_KEY_VALUE 15:0 + +#define PANEL_FB_ADDRESS 0x08000C +#define PANEL_FB_ADDRESS_STATUS 31:31 +#define PANEL_FB_ADDRESS_STATUS_CURRENT 0 +#define PANEL_FB_ADDRESS_STATUS_PENDING 1 +#define PANEL_FB_ADDRESS_EXT 27:27 +#define PANEL_FB_ADDRESS_EXT_LOCAL 0 +#define PANEL_FB_ADDRESS_EXT_EXTERNAL 1 +#define PANEL_FB_ADDRESS_ADDRESS 25:0 + +#define PANEL_FB_WIDTH 0x080010 +#define PANEL_FB_WIDTH_WIDTH 29:16 +#define PANEL_FB_WIDTH_OFFSET 13:0 + +#define PANEL_WINDOW_WIDTH 0x080014 +#define PANEL_WINDOW_WIDTH_WIDTH 27:16 +#define PANEL_WINDOW_WIDTH_X 11:0 + +#define PANEL_WINDOW_HEIGHT 0x080018 +#define PANEL_WINDOW_HEIGHT_HEIGHT 27:16 +#define PANEL_WINDOW_HEIGHT_Y 11:0 + +#define PANEL_PLANE_TL 0x08001C +#define PANEL_PLANE_TL_TOP 26:16 +#define PANEL_PLANE_TL_LEFT 10:0 + +#define PANEL_PLANE_BR 0x080020 +#define PANEL_PLANE_BR_BOTTOM 26:16 +#define PANEL_PLANE_BR_RIGHT 10:0 + +#define PANEL_HORIZONTAL_TOTAL 0x080024 +#define PANEL_HORIZONTAL_TOTAL_TOTAL 27:16 +#define PANEL_HORIZONTAL_TOTAL_DISPLAY_END 11:0 + +#define PANEL_HORIZONTAL_SYNC 0x080028 +#define PANEL_HORIZONTAL_SYNC_WIDTH 23:16 +#define PANEL_HORIZONTAL_SYNC_START 11:0 + +#define PANEL_VERTICAL_TOTAL 0x08002C +#define PANEL_VERTICAL_TOTAL_TOTAL 26:16 +#define PANEL_VERTICAL_TOTAL_DISPLAY_END 10:0 + +#define PANEL_VERTICAL_SYNC 0x080030 +#define PANEL_VERTICAL_SYNC_HEIGHT 21:16 +#define PANEL_VERTICAL_SYNC_START 10:0 + +#define PANEL_CURRENT_LINE 0x080034 +#define PANEL_CURRENT_LINE_LINE 10:0 + +/* Video Control */ + +#define VIDEO_DISPLAY_CTRL 0x080040 +#define VIDEO_DISPLAY_CTRL_LINE_BUFFER 18:18 +#define VIDEO_DISPLAY_CTRL_LINE_BUFFER_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_LINE_BUFFER_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_FIFO 17:16 +#define VIDEO_DISPLAY_CTRL_FIFO_1 0 +#define VIDEO_DISPLAY_CTRL_FIFO_3 1 +#define VIDEO_DISPLAY_CTRL_FIFO_7 2 +#define VIDEO_DISPLAY_CTRL_FIFO_11 3 +#define VIDEO_DISPLAY_CTRL_BUFFER 15:15 +#define VIDEO_DISPLAY_CTRL_BUFFER_0 0 +#define VIDEO_DISPLAY_CTRL_BUFFER_1 1 +#define VIDEO_DISPLAY_CTRL_CAPTURE 14:14 +#define VIDEO_DISPLAY_CTRL_CAPTURE_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_CAPTURE_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER 13:13 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP 12:12 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE 11:11 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE_NORMAL 0 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE_HALF 1 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE 10:10 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE_NORMAL 0 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE_HALF 1 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE 9:9 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE_REPLICATE 0 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE_INTERPOLATE 1 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE 8:8 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE_REPLICATE 0 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE_INTERPOLATE 1 +#define VIDEO_DISPLAY_CTRL_PIXEL 7:4 +#define VIDEO_DISPLAY_CTRL_GAMMA 3:3 +#define VIDEO_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_PLANE 2:2 +#define VIDEO_DISPLAY_CTRL_PLANE_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_PLANE_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_FORMAT 1:0 +#define VIDEO_DISPLAY_CTRL_FORMAT_8 0 +#define VIDEO_DISPLAY_CTRL_FORMAT_16 1 +#define VIDEO_DISPLAY_CTRL_FORMAT_32 2 +#define VIDEO_DISPLAY_CTRL_FORMAT_YUV 3 + +#define VIDEO_FB_0_ADDRESS 0x080044 +#define VIDEO_FB_0_ADDRESS_STATUS 31:31 +#define VIDEO_FB_0_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_FB_0_ADDRESS_STATUS_PENDING 1 +#define VIDEO_FB_0_ADDRESS_EXT 27:27 +#define VIDEO_FB_0_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_0_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_0_ADDRESS_ADDRESS 25:0 + +#define VIDEO_FB_WIDTH 0x080048 +#define VIDEO_FB_WIDTH_WIDTH 29:16 +#define VIDEO_FB_WIDTH_OFFSET 13:0 + +#define VIDEO_FB_0_LAST_ADDRESS 0x08004C +#define VIDEO_FB_0_LAST_ADDRESS_EXT 27:27 +#define VIDEO_FB_0_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_0_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_0_LAST_ADDRESS_ADDRESS 25:0 + +#define VIDEO_PLANE_TL 0x080050 +#define VIDEO_PLANE_TL_TOP 26:16 +#define VIDEO_PLANE_TL_LEFT 10:0 + +#define VIDEO_PLANE_BR 0x080054 +#define VIDEO_PLANE_BR_BOTTOM 26:16 +#define VIDEO_PLANE_BR_RIGHT 10:0 + +#define VIDEO_SCALE 0x080058 +#define VIDEO_SCALE_VERTICAL_MODE 31:31 +#define VIDEO_SCALE_VERTICAL_MODE_EXPAND 0 +#define VIDEO_SCALE_VERTICAL_MODE_SHRINK 1 +#define VIDEO_SCALE_VERTICAL_SCALE 27:16 +#define VIDEO_SCALE_HORIZONTAL_MODE 15:15 +#define VIDEO_SCALE_HORIZONTAL_MODE_EXPAND 0 +#define VIDEO_SCALE_HORIZONTAL_MODE_SHRINK 1 +#define VIDEO_SCALE_HORIZONTAL_SCALE 11:0 + +#define VIDEO_INITIAL_SCALE 0x08005C +#define VIDEO_INITIAL_SCALE_FB_1 27:16 +#define VIDEO_INITIAL_SCALE_FB_0 11:0 + +#define VIDEO_YUV_CONSTANTS 0x080060 +#define VIDEO_YUV_CONSTANTS_Y 31:24 +#define VIDEO_YUV_CONSTANTS_R 23:16 +#define VIDEO_YUV_CONSTANTS_G 15:8 +#define VIDEO_YUV_CONSTANTS_B 7:0 + +#define VIDEO_FB_1_ADDRESS 0x080064 +#define VIDEO_FB_1_ADDRESS_STATUS 31:31 +#define VIDEO_FB_1_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_FB_1_ADDRESS_STATUS_PENDING 1 +#define VIDEO_FB_1_ADDRESS_EXT 27:27 +#define VIDEO_FB_1_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_1_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_1_ADDRESS_ADDRESS 25:0 + +#define VIDEO_FB_1_LAST_ADDRESS 0x080068 +#define VIDEO_FB_1_LAST_ADDRESS_EXT 27:27 +#define VIDEO_FB_1_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_1_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_1_LAST_ADDRESS_ADDRESS 25:0 + +/* Video Alpha Control */ + +#define VIDEO_ALPHA_DISPLAY_CTRL 0x080080 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT 28:28 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT_PER_PIXEL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT_ALPHA 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_ALPHA 27:24 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO 17:16 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_1 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_3 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_7 2 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_11 3 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE 11:11 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE_NORMAL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE_HALF 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE 10:10 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE_NORMAL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE_HALF 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE 9:9 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE_REPLICATE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE_INTERPOLATE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE 8:8 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE_REPLICATE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE_INTERPOLATE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_PIXEL 7:4 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY 3:3 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY_DISABLE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY_ENABLE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE 2:2 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_DISABLE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_ENABLE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT 1:0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_8 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_16 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4 2 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4_4_4 3 + +#define VIDEO_ALPHA_FB_ADDRESS 0x080084 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS 31:31 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS_PENDING 1 +#define VIDEO_ALPHA_FB_ADDRESS_EXT 27:27 +#define VIDEO_ALPHA_FB_ADDRESS_EXT_LOCAL 0 +#define VIDEO_ALPHA_FB_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_ALPHA_FB_ADDRESS_ADDRESS 25:0 + +#define VIDEO_ALPHA_FB_WIDTH 0x080088 +#define VIDEO_ALPHA_FB_WIDTH_WIDTH 29:16 +#define VIDEO_ALPHA_FB_WIDTH_OFFSET 13:0 + +#define VIDEO_ALPHA_FB_LAST_ADDRESS 0x08008C +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT 27:27 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_ADDRESS 25:0 + +#define VIDEO_ALPHA_PLANE_TL 0x080090 +#define VIDEO_ALPHA_PLANE_TL_TOP 26:16 +#define VIDEO_ALPHA_PLANE_TL_LEFT 10:0 + +#define VIDEO_ALPHA_PLANE_BR 0x080094 +#define VIDEO_ALPHA_PLANE_BR_BOTTOM 26:16 +#define VIDEO_ALPHA_PLANE_BR_RIGHT 10:0 + +#define VIDEO_ALPHA_SCALE 0x080098 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE 31:31 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE_EXPAND 0 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE_SHRINK 1 +#define VIDEO_ALPHA_SCALE_VERTICAL_SCALE 27:16 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE 15:15 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE_EXPAND 0 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE_SHRINK 1 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_SCALE 11:0 + +#define VIDEO_ALPHA_INITIAL_SCALE 0x08009C +#define VIDEO_ALPHA_INITIAL_SCALE_VERTICAL 27:16 +#define VIDEO_ALPHA_INITIAL_SCALE_HORIZONTAL 11:0 + +#define VIDEO_ALPHA_CHROMA_KEY 0x0800A0 +#define VIDEO_ALPHA_CHROMA_KEY_MASK 31:16 +#define VIDEO_ALPHA_CHROMA_KEY_VALUE 15:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_01 0x0800A4 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_23 0x0800A8 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_45 0x0800AC +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_67 0x0800B0 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_89 0x0800B4 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_AB 0x0800B8 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_CD 0x0800BC +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_EF 0x0800C0 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F 31:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E 15:0 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_BLUE 4:0 + +/* Panel Cursor Control */ + +#define PANEL_HWC_ADDRESS 0x0800F0 +#define PANEL_HWC_ADDRESS_ENABLE 31:31 +#define PANEL_HWC_ADDRESS_ENABLE_DISABLE 0 +#define PANEL_HWC_ADDRESS_ENABLE_ENABLE 1 +#define PANEL_HWC_ADDRESS_EXT 27:27 +#define PANEL_HWC_ADDRESS_EXT_LOCAL 0 +#define PANEL_HWC_ADDRESS_EXT_EXTERNAL 1 +#define PANEL_HWC_ADDRESS_ADDRESS 25:0 + +#define PANEL_HWC_LOCATION 0x0800F4 +#define PANEL_HWC_LOCATION_TOP 27:27 +#define PANEL_HWC_LOCATION_TOP_INSIDE 0 +#define PANEL_HWC_LOCATION_TOP_OUTSIDE 1 +#define PANEL_HWC_LOCATION_Y 26:16 +#define PANEL_HWC_LOCATION_LEFT 11:11 +#define PANEL_HWC_LOCATION_LEFT_INSIDE 0 +#define PANEL_HWC_LOCATION_LEFT_OUTSIDE 1 +#define PANEL_HWC_LOCATION_X 10:0 + +#define PANEL_HWC_COLOR_12 0x0800F8 +#define PANEL_HWC_COLOR_12_2_RGB565 31:16 +#define PANEL_HWC_COLOR_12_1_RGB565 15:0 + +#define PANEL_HWC_COLOR_3 0x0800FC +#define PANEL_HWC_COLOR_3_RGB565 15:0 + +/* Old Definitions +++ */ +#define PANEL_HWC_COLOR_01 0x0800F8 +#define PANEL_HWC_COLOR_01_1_RED 31:27 +#define PANEL_HWC_COLOR_01_1_GREEN 26:21 +#define PANEL_HWC_COLOR_01_1_BLUE 20:16 +#define PANEL_HWC_COLOR_01_0_RED 15:11 +#define PANEL_HWC_COLOR_01_0_GREEN 10:5 +#define PANEL_HWC_COLOR_01_0_BLUE 4:0 + +#define PANEL_HWC_COLOR_2 0x0800FC +#define PANEL_HWC_COLOR_2_RED 15:11 +#define PANEL_HWC_COLOR_2_GREEN 10:5 +#define PANEL_HWC_COLOR_2_BLUE 4:0 +/* Old Definitions --- */ + +/* Alpha Control */ + +#define ALPHA_DISPLAY_CTRL 0x080100 +#define ALPHA_DISPLAY_CTRL_SELECT 28:28 +#define ALPHA_DISPLAY_CTRL_SELECT_PER_PIXEL 0 +#define ALPHA_DISPLAY_CTRL_SELECT_ALPHA 1 +#define ALPHA_DISPLAY_CTRL_ALPHA 27:24 +#define ALPHA_DISPLAY_CTRL_FIFO 17:16 +#define ALPHA_DISPLAY_CTRL_FIFO_1 0 +#define ALPHA_DISPLAY_CTRL_FIFO_3 1 +#define ALPHA_DISPLAY_CTRL_FIFO_7 2 +#define ALPHA_DISPLAY_CTRL_FIFO_11 3 +#define ALPHA_DISPLAY_CTRL_PIXEL 7:4 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY 3:3 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY_DISABLE 0 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY_ENABLE 1 +#define ALPHA_DISPLAY_CTRL_PLANE 2:2 +#define ALPHA_DISPLAY_CTRL_PLANE_DISABLE 0 +#define ALPHA_DISPLAY_CTRL_PLANE_ENABLE 1 +#define ALPHA_DISPLAY_CTRL_FORMAT 1:0 +#define ALPHA_DISPLAY_CTRL_FORMAT_16 1 +#define ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4 2 +#define ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4_4_4 3 + +#define ALPHA_FB_ADDRESS 0x080104 +#define ALPHA_FB_ADDRESS_STATUS 31:31 +#define ALPHA_FB_ADDRESS_STATUS_CURRENT 0 +#define ALPHA_FB_ADDRESS_STATUS_PENDING 1 +#define ALPHA_FB_ADDRESS_EXT 27:27 +#define ALPHA_FB_ADDRESS_EXT_LOCAL 0 +#define ALPHA_FB_ADDRESS_EXT_EXTERNAL 1 +#define ALPHA_FB_ADDRESS_ADDRESS 25:0 + +#define ALPHA_FB_WIDTH 0x080108 +#define ALPHA_FB_WIDTH_WIDTH 29:16 +#define ALPHA_FB_WIDTH_OFFSET 13:0 + +#define ALPHA_PLANE_TL 0x08010C +#define ALPHA_PLANE_TL_TOP 26:16 +#define ALPHA_PLANE_TL_LEFT 10:0 + +#define ALPHA_PLANE_BR 0x080110 +#define ALPHA_PLANE_BR_BOTTOM 26:16 +#define ALPHA_PLANE_BR_RIGHT 10:0 + +#define ALPHA_CHROMA_KEY 0x080114 +#define ALPHA_CHROMA_KEY_MASK 31:16 +#define ALPHA_CHROMA_KEY_VALUE 15:0 + +#define ALPHA_COLOR_LOOKUP_01 0x080118 +#define ALPHA_COLOR_LOOKUP_01_1 31:16 +#define ALPHA_COLOR_LOOKUP_01_1_RED 31:27 +#define ALPHA_COLOR_LOOKUP_01_1_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_01_1_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_01_0 15:0 +#define ALPHA_COLOR_LOOKUP_01_0_RED 15:11 +#define ALPHA_COLOR_LOOKUP_01_0_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_01_0_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_23 0x08011C +#define ALPHA_COLOR_LOOKUP_23_3 31:16 +#define ALPHA_COLOR_LOOKUP_23_3_RED 31:27 +#define ALPHA_COLOR_LOOKUP_23_3_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_23_3_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_23_2 15:0 +#define ALPHA_COLOR_LOOKUP_23_2_RED 15:11 +#define ALPHA_COLOR_LOOKUP_23_2_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_23_2_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_45 0x080120 +#define ALPHA_COLOR_LOOKUP_45_5 31:16 +#define ALPHA_COLOR_LOOKUP_45_5_RED 31:27 +#define ALPHA_COLOR_LOOKUP_45_5_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_45_5_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_45_4 15:0 +#define ALPHA_COLOR_LOOKUP_45_4_RED 15:11 +#define ALPHA_COLOR_LOOKUP_45_4_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_45_4_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_67 0x080124 +#define ALPHA_COLOR_LOOKUP_67_7 31:16 +#define ALPHA_COLOR_LOOKUP_67_7_RED 31:27 +#define ALPHA_COLOR_LOOKUP_67_7_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_67_7_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_67_6 15:0 +#define ALPHA_COLOR_LOOKUP_67_6_RED 15:11 +#define ALPHA_COLOR_LOOKUP_67_6_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_67_6_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_89 0x080128 +#define ALPHA_COLOR_LOOKUP_89_9 31:16 +#define ALPHA_COLOR_LOOKUP_89_9_RED 31:27 +#define ALPHA_COLOR_LOOKUP_89_9_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_89_9_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_89_8 15:0 +#define ALPHA_COLOR_LOOKUP_89_8_RED 15:11 +#define ALPHA_COLOR_LOOKUP_89_8_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_89_8_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_AB 0x08012C +#define ALPHA_COLOR_LOOKUP_AB_B 31:16 +#define ALPHA_COLOR_LOOKUP_AB_B_RED 31:27 +#define ALPHA_COLOR_LOOKUP_AB_B_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_AB_B_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_AB_A 15:0 +#define ALPHA_COLOR_LOOKUP_AB_A_RED 15:11 +#define ALPHA_COLOR_LOOKUP_AB_A_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_AB_A_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_CD 0x080130 +#define ALPHA_COLOR_LOOKUP_CD_D 31:16 +#define ALPHA_COLOR_LOOKUP_CD_D_RED 31:27 +#define ALPHA_COLOR_LOOKUP_CD_D_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_CD_D_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_CD_C 15:0 +#define ALPHA_COLOR_LOOKUP_CD_C_RED 15:11 +#define ALPHA_COLOR_LOOKUP_CD_C_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_CD_C_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_EF 0x080134 +#define ALPHA_COLOR_LOOKUP_EF_F 31:16 +#define ALPHA_COLOR_LOOKUP_EF_F_RED 31:27 +#define ALPHA_COLOR_LOOKUP_EF_F_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_EF_F_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_EF_E 15:0 +#define ALPHA_COLOR_LOOKUP_EF_E_RED 15:11 +#define ALPHA_COLOR_LOOKUP_EF_E_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_EF_E_BLUE 4:0 + +/* CRT Graphics Control */ + +#define CRT_DISPLAY_CTRL 0x080200 +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK 31:27 +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK_DISABLE 0 +#define CRT_DISPLAY_CTRL_RESERVED_1_MASK_ENABLE 0x1F + +/* SM750LE definition */ +#define CRT_DISPLAY_CTRL_DPMS 31:30 +#define CRT_DISPLAY_CTRL_DPMS_0 0 +#define CRT_DISPLAY_CTRL_DPMS_1 1 +#define CRT_DISPLAY_CTRL_DPMS_2 2 +#define CRT_DISPLAY_CTRL_DPMS_3 3 +#define CRT_DISPLAY_CTRL_CLK 29:27 +#define CRT_DISPLAY_CTRL_CLK_PLL25 0 +#define CRT_DISPLAY_CTRL_CLK_PLL41 1 +#define CRT_DISPLAY_CTRL_CLK_PLL62 2 +#define CRT_DISPLAY_CTRL_CLK_PLL65 3 +#define CRT_DISPLAY_CTRL_CLK_PLL74 4 +#define CRT_DISPLAY_CTRL_CLK_PLL80 5 +#define CRT_DISPLAY_CTRL_CLK_PLL108 6 +#define CRT_DISPLAY_CTRL_CLK_RESERVED 7 +#define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC 26:26 +#define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC_DISABLE 1 +#define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC_ENABLE 0 + + +#define CRT_DISPLAY_CTRL_RESERVED_2_MASK 25:24 +#define CRT_DISPLAY_CTRL_RESERVED_2_MASK_ENABLE 3 +#define CRT_DISPLAY_CTRL_RESERVED_2_MASK_DISABLE 0 + +/* SM750LE definition */ +#define CRT_DISPLAY_CTRL_CRTSELECT 25:25 +#define CRT_DISPLAY_CTRL_CRTSELECT_VGA 0 +#define CRT_DISPLAY_CTRL_CRTSELECT_CRT 1 +#define CRT_DISPLAY_CTRL_RGBBIT 24:24 +#define CRT_DISPLAY_CTRL_RGBBIT_24BIT 0 +#define CRT_DISPLAY_CTRL_RGBBIT_12BIT 1 + + +#define CRT_DISPLAY_CTRL_RESERVED_3_MASK 15:15 +#define CRT_DISPLAY_CTRL_RESERVED_3_MASK_DISABLE 0 +#define CRT_DISPLAY_CTRL_RESERVED_3_MASK_ENABLE 1 + +#define CRT_DISPLAY_CTRL_RESERVED_4_MASK 9:9 +#define CRT_DISPLAY_CTRL_RESERVED_4_MASK_DISABLE 0 +#define CRT_DISPLAY_CTRL_RESERVED_4_MASK_ENABLE 1 + +#ifndef VALIDATION_CHIP + #define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC 26:26 + #define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC_DISABLE 1 + #define CRT_DISPLAY_CTRL_SHIFT_VGA_DAC_ENABLE 0 + #define CRT_DISPLAY_CTRL_CENTERING 24:24 + #define CRT_DISPLAY_CTRL_CENTERING_DISABLE 0 + #define CRT_DISPLAY_CTRL_CENTERING_ENABLE 1 +#endif +#define CRT_DISPLAY_CTRL_LOCK_TIMING 23:23 +#define CRT_DISPLAY_CTRL_LOCK_TIMING_DISABLE 0 +#define CRT_DISPLAY_CTRL_LOCK_TIMING_ENABLE 1 +#define CRT_DISPLAY_CTRL_EXPANSION 22:22 +#define CRT_DISPLAY_CTRL_EXPANSION_DISABLE 0 +#define CRT_DISPLAY_CTRL_EXPANSION_ENABLE 1 +#define CRT_DISPLAY_CTRL_VERTICAL_MODE 21:21 +#define CRT_DISPLAY_CTRL_VERTICAL_MODE_REPLICATE 0 +#define CRT_DISPLAY_CTRL_VERTICAL_MODE_INTERPOLATE 1 +#define CRT_DISPLAY_CTRL_HORIZONTAL_MODE 20:20 +#define CRT_DISPLAY_CTRL_HORIZONTAL_MODE_REPLICATE 0 +#define CRT_DISPLAY_CTRL_HORIZONTAL_MODE_INTERPOLATE 1 +#define CRT_DISPLAY_CTRL_SELECT 19:18 +#define CRT_DISPLAY_CTRL_SELECT_PANEL 0 +#define CRT_DISPLAY_CTRL_SELECT_VGA 1 +#define CRT_DISPLAY_CTRL_SELECT_CRT 2 +#define CRT_DISPLAY_CTRL_FIFO 17:16 +#define CRT_DISPLAY_CTRL_FIFO_1 0 +#define CRT_DISPLAY_CTRL_FIFO_3 1 +#define CRT_DISPLAY_CTRL_FIFO_7 2 +#define CRT_DISPLAY_CTRL_FIFO_11 3 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE 14:14 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE 13:13 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE 12:12 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_BLANK 10:10 +#define CRT_DISPLAY_CTRL_BLANK_OFF 0 +#define CRT_DISPLAY_CTRL_BLANK_ON 1 +#define CRT_DISPLAY_CTRL_TIMING 8:8 +#define CRT_DISPLAY_CTRL_TIMING_DISABLE 0 +#define CRT_DISPLAY_CTRL_TIMING_ENABLE 1 +#define CRT_DISPLAY_CTRL_PIXEL 7:4 +#define CRT_DISPLAY_CTRL_GAMMA 3:3 +#define CRT_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define CRT_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define CRT_DISPLAY_CTRL_PLANE 2:2 +#define CRT_DISPLAY_CTRL_PLANE_DISABLE 0 +#define CRT_DISPLAY_CTRL_PLANE_ENABLE 1 +#define CRT_DISPLAY_CTRL_FORMAT 1:0 +#define CRT_DISPLAY_CTRL_FORMAT_8 0 +#define CRT_DISPLAY_CTRL_FORMAT_16 1 +#define CRT_DISPLAY_CTRL_FORMAT_32 2 +#define CRT_DISPLAY_CTRL_RESERVED_BITS_MASK 0xFF000200 + +#define CRT_FB_ADDRESS 0x080204 +#define CRT_FB_ADDRESS_STATUS 31:31 +#define CRT_FB_ADDRESS_STATUS_CURRENT 0 +#define CRT_FB_ADDRESS_STATUS_PENDING 1 +#define CRT_FB_ADDRESS_EXT 27:27 +#define CRT_FB_ADDRESS_EXT_LOCAL 0 +#define CRT_FB_ADDRESS_EXT_EXTERNAL 1 +#define CRT_FB_ADDRESS_ADDRESS 25:0 + +#define CRT_FB_WIDTH 0x080208 +#define CRT_FB_WIDTH_WIDTH 29:16 +#define CRT_FB_WIDTH_OFFSET 13:0 + +#define CRT_HORIZONTAL_TOTAL 0x08020C +#define CRT_HORIZONTAL_TOTAL_TOTAL 27:16 +#define CRT_HORIZONTAL_TOTAL_DISPLAY_END 11:0 + +#define CRT_HORIZONTAL_SYNC 0x080210 +#define CRT_HORIZONTAL_SYNC_WIDTH 23:16 +#define CRT_HORIZONTAL_SYNC_START 11:0 + +#define CRT_VERTICAL_TOTAL 0x080214 +#define CRT_VERTICAL_TOTAL_TOTAL 26:16 +#define CRT_VERTICAL_TOTAL_DISPLAY_END 10:0 + +#define CRT_VERTICAL_SYNC 0x080218 +#define CRT_VERTICAL_SYNC_HEIGHT 21:16 +#define CRT_VERTICAL_SYNC_START 10:0 + +#define CRT_SIGNATURE_ANALYZER 0x08021C +#define CRT_SIGNATURE_ANALYZER_STATUS 31:16 +#define CRT_SIGNATURE_ANALYZER_ENABLE 3:3 +#define CRT_SIGNATURE_ANALYZER_ENABLE_DISABLE 0 +#define CRT_SIGNATURE_ANALYZER_ENABLE_ENABLE 1 +#define CRT_SIGNATURE_ANALYZER_RESET 2:2 +#define CRT_SIGNATURE_ANALYZER_RESET_NORMAL 0 +#define CRT_SIGNATURE_ANALYZER_RESET_RESET 1 +#define CRT_SIGNATURE_ANALYZER_SOURCE 1:0 +#define CRT_SIGNATURE_ANALYZER_SOURCE_RED 0 +#define CRT_SIGNATURE_ANALYZER_SOURCE_GREEN 1 +#define CRT_SIGNATURE_ANALYZER_SOURCE_BLUE 2 + +#define CRT_CURRENT_LINE 0x080220 +#define CRT_CURRENT_LINE_LINE 10:0 + +#define CRT_MONITOR_DETECT 0x080224 +#define CRT_MONITOR_DETECT_VALUE 25:25 +#define CRT_MONITOR_DETECT_VALUE_DISABLE 0 +#define CRT_MONITOR_DETECT_VALUE_ENABLE 1 +#define CRT_MONITOR_DETECT_ENABLE 24:24 +#define CRT_MONITOR_DETECT_ENABLE_DISABLE 0 +#define CRT_MONITOR_DETECT_ENABLE_ENABLE 1 +#define CRT_MONITOR_DETECT_RED 23:16 +#define CRT_MONITOR_DETECT_GREEN 15:8 +#define CRT_MONITOR_DETECT_BLUE 7:0 + +#define CRT_SCALE 0x080228 +#define CRT_SCALE_VERTICAL_MODE 31:31 +#define CRT_SCALE_VERTICAL_MODE_EXPAND 0 +#define CRT_SCALE_VERTICAL_MODE_SHRINK 1 +#define CRT_SCALE_VERTICAL_SCALE 27:16 +#define CRT_SCALE_HORIZONTAL_MODE 15:15 +#define CRT_SCALE_HORIZONTAL_MODE_EXPAND 0 +#define CRT_SCALE_HORIZONTAL_MODE_SHRINK 1 +#define CRT_SCALE_HORIZONTAL_SCALE 11:0 + +/* CRT Cursor Control */ + +#define CRT_HWC_ADDRESS 0x080230 +#define CRT_HWC_ADDRESS_ENABLE 31:31 +#define CRT_HWC_ADDRESS_ENABLE_DISABLE 0 +#define CRT_HWC_ADDRESS_ENABLE_ENABLE 1 +#define CRT_HWC_ADDRESS_EXT 27:27 +#define CRT_HWC_ADDRESS_EXT_LOCAL 0 +#define CRT_HWC_ADDRESS_EXT_EXTERNAL 1 +#define CRT_HWC_ADDRESS_ADDRESS 25:0 + +#define CRT_HWC_LOCATION 0x080234 +#define CRT_HWC_LOCATION_TOP 27:27 +#define CRT_HWC_LOCATION_TOP_INSIDE 0 +#define CRT_HWC_LOCATION_TOP_OUTSIDE 1 +#define CRT_HWC_LOCATION_Y 26:16 +#define CRT_HWC_LOCATION_LEFT 11:11 +#define CRT_HWC_LOCATION_LEFT_INSIDE 0 +#define CRT_HWC_LOCATION_LEFT_OUTSIDE 1 +#define CRT_HWC_LOCATION_X 10:0 + +#define CRT_HWC_COLOR_12 0x080238 +#define CRT_HWC_COLOR_12_2_RGB565 31:16 +#define CRT_HWC_COLOR_12_1_RGB565 15:0 + +#define CRT_HWC_COLOR_3 0x08023C +#define CRT_HWC_COLOR_3_RGB565 15:0 + +/* Old Definitions +++. Need to be removed if no application use it. */ +#if 0 + #define CRT_HWC_COLOR_01 0x080238 + #define CRT_HWC_COLOR_01_1_RED 31:27 + #define CRT_HWC_COLOR_01_1_GREEN 26:21 + #define CRT_HWC_COLOR_01_1_BLUE 20:16 + #define CRT_HWC_COLOR_01_0_RED 15:11 + #define CRT_HWC_COLOR_01_0_GREEN 10:5 + #define CRT_HWC_COLOR_01_0_BLUE 4:0 + + #define CRT_HWC_COLOR_2 0x08023C + #define CRT_HWC_COLOR_2_RED 15:11 + #define CRT_HWC_COLOR_2_GREEN 10:5 + #define CRT_HWC_COLOR_2_BLUE 4:0 +#endif +/* Old Definitions --- */ + +/* This vertical expansion below start at 0x080240 ~ 0x080264 */ +#define CRT_VERTICAL_EXPANSION 0x080240 +#ifndef VALIDATION_CHIP + #define CRT_VERTICAL_CENTERING_VALUE 31:24 +#endif +#define CRT_VERTICAL_EXPANSION_COMPARE_VALUE 23:16 +#define CRT_VERTICAL_EXPANSION_LINE_BUFFER 15:12 +#define CRT_VERTICAL_EXPANSION_SCALE_FACTOR 11:0 + +/* This horizontal expansion below start at 0x080268 ~ 0x08027C */ +#define CRT_HORIZONTAL_EXPANSION 0x080268 +#ifndef VALIDATION_CHIP + #define CRT_HORIZONTAL_CENTERING_VALUE 31:24 +#endif +#define CRT_HORIZONTAL_EXPANSION_COMPARE_VALUE 23:16 +#define CRT_HORIZONTAL_EXPANSION_SCALE_FACTOR 11:0 + +#ifndef VALIDATION_CHIP + /* Auto Centering */ + #define CRT_AUTO_CENTERING_TL 0x080280 + #define CRT_AUTO_CENTERING_TL_TOP 26:16 + #define CRT_AUTO_CENTERING_TL_LEFT 10:0 + + #define CRT_AUTO_CENTERING_BR 0x080284 + #define CRT_AUTO_CENTERING_BR_BOTTOM 26:16 + #define CRT_AUTO_CENTERING_BR_RIGHT 10:0 +#endif + +/* sm750le new register to control panel output */ +#define DISPLAY_CONTROL_750LE 0x80288 +/* Palette RAM */ + +/* Panel Pallete register starts at 0x080400 ~ 0x0807FC */ +#define PANEL_PALETTE_RAM 0x080400 + +/* Panel Pallete register starts at 0x080C00 ~ 0x080FFC */ +#define CRT_PALETTE_RAM 0x080C00 + +/* 2D registers + * move their defination into general lynx_accel.h file + * because all smi graphic chip share the same drawing engine + * register format */ +#if 0 +#define DE_SOURCE 0x100000 +#define DE_SOURCE_WRAP 31:31 +#define DE_SOURCE_WRAP_DISABLE 0 +#define DE_SOURCE_WRAP_ENABLE 1 + +/* + * The following definitions are used in different setting + */ + +/* Use these definitions in XY addressing mode or linear addressing mode. */ +#define DE_SOURCE_X_K1 27:16 +#define DE_SOURCE_Y_K2 11:0 + +/* Use this definition in host write mode for mono. The Y_K2 is not used + in host write mode. */ +#define DE_SOURCE_X_K1_MONO 20:16 + +/* Use these definitions in Bresenham line drawing mode. */ +#define DE_SOURCE_X_K1_LINE 29:16 +#define DE_SOURCE_Y_K2_LINE 13:0 + +#define DE_DESTINATION 0x100004 +#define DE_DESTINATION_WRAP 31:31 +#define DE_DESTINATION_WRAP_DISABLE 0 +#define DE_DESTINATION_WRAP_ENABLE 1 +#if 1 + #define DE_DESTINATION_X 27:16 + #define DE_DESTINATION_Y 11:0 +#else + #define DE_DESTINATION_X 28:16 + #define DE_DESTINATION_Y 15:0 +#endif + +#define DE_DIMENSION 0x100008 +#define DE_DIMENSION_X 28:16 +#define DE_DIMENSION_Y_ET 15:0 + +#define DE_CONTROL 0x10000C +#define DE_CONTROL_STATUS 31:31 +#define DE_CONTROL_STATUS_STOP 0 +#define DE_CONTROL_STATUS_START 1 +#define DE_CONTROL_PATTERN 30:30 +#define DE_CONTROL_PATTERN_MONO 0 +#define DE_CONTROL_PATTERN_COLOR 1 +#define DE_CONTROL_UPDATE_DESTINATION_X 29:29 +#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0 +#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1 +#define DE_CONTROL_QUICK_START 28:28 +#define DE_CONTROL_QUICK_START_DISABLE 0 +#define DE_CONTROL_QUICK_START_ENABLE 1 +#define DE_CONTROL_DIRECTION 27:27 +#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0 +#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1 +#define DE_CONTROL_MAJOR 26:26 +#define DE_CONTROL_MAJOR_X 0 +#define DE_CONTROL_MAJOR_Y 1 +#define DE_CONTROL_STEP_X 25:25 +#define DE_CONTROL_STEP_X_POSITIVE 0 +#define DE_CONTROL_STEP_X_NEGATIVE 1 +#define DE_CONTROL_STEP_Y 24:24 +#define DE_CONTROL_STEP_Y_POSITIVE 0 +#define DE_CONTROL_STEP_Y_NEGATIVE 1 +#define DE_CONTROL_STRETCH 23:23 +#define DE_CONTROL_STRETCH_DISABLE 0 +#define DE_CONTROL_STRETCH_ENABLE 1 +#define DE_CONTROL_HOST 22:22 +#define DE_CONTROL_HOST_COLOR 0 +#define DE_CONTROL_HOST_MONO 1 +#define DE_CONTROL_LAST_PIXEL 21:21 +#define DE_CONTROL_LAST_PIXEL_OFF 0 +#define DE_CONTROL_LAST_PIXEL_ON 1 +#define DE_CONTROL_COMMAND 20:16 +#define DE_CONTROL_COMMAND_BITBLT 0 +#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1 +#define DE_CONTROL_COMMAND_DE_TILE 2 +#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3 +#define DE_CONTROL_COMMAND_ALPHA_BLEND 4 +#define DE_CONTROL_COMMAND_RLE_STRIP 5 +#define DE_CONTROL_COMMAND_SHORT_STROKE 6 +#define DE_CONTROL_COMMAND_LINE_DRAW 7 +#define DE_CONTROL_COMMAND_HOST_WRITE 8 +#define DE_CONTROL_COMMAND_HOST_READ 9 +#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10 +#define DE_CONTROL_COMMAND_ROTATE 11 +#define DE_CONTROL_COMMAND_FONT 12 +#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15 +#define DE_CONTROL_ROP_SELECT 15:15 +#define DE_CONTROL_ROP_SELECT_ROP3 0 +#define DE_CONTROL_ROP_SELECT_ROP2 1 +#define DE_CONTROL_ROP2_SOURCE 14:14 +#define DE_CONTROL_ROP2_SOURCE_BITMAP 0 +#define DE_CONTROL_ROP2_SOURCE_PATTERN 1 +#define DE_CONTROL_MONO_DATA 13:12 +#define DE_CONTROL_MONO_DATA_NOT_PACKED 0 +#define DE_CONTROL_MONO_DATA_8_PACKED 1 +#define DE_CONTROL_MONO_DATA_16_PACKED 2 +#define DE_CONTROL_MONO_DATA_32_PACKED 3 +#define DE_CONTROL_REPEAT_ROTATE 11:11 +#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0 +#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1 +#define DE_CONTROL_TRANSPARENCY_MATCH 10:10 +#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0 +#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1 +#define DE_CONTROL_TRANSPARENCY_SELECT 9:9 +#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0 +#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1 +#define DE_CONTROL_TRANSPARENCY 8:8 +#define DE_CONTROL_TRANSPARENCY_DISABLE 0 +#define DE_CONTROL_TRANSPARENCY_ENABLE 1 +#define DE_CONTROL_ROP 7:0 + +/* Pseudo fields. */ + +#define DE_CONTROL_SHORT_STROKE_DIR 27:24 +#define DE_CONTROL_SHORT_STROKE_DIR_225 0 +#define DE_CONTROL_SHORT_STROKE_DIR_135 1 +#define DE_CONTROL_SHORT_STROKE_DIR_315 2 +#define DE_CONTROL_SHORT_STROKE_DIR_45 3 +#define DE_CONTROL_SHORT_STROKE_DIR_270 4 +#define DE_CONTROL_SHORT_STROKE_DIR_90 5 +#define DE_CONTROL_SHORT_STROKE_DIR_180 8 +#define DE_CONTROL_SHORT_STROKE_DIR_0 10 +#define DE_CONTROL_ROTATION 25:24 +#define DE_CONTROL_ROTATION_0 0 +#define DE_CONTROL_ROTATION_270 1 +#define DE_CONTROL_ROTATION_90 2 +#define DE_CONTROL_ROTATION_180 3 + +#define DE_PITCH 0x100010 +#define DE_PITCH_DESTINATION 28:16 +#define DE_PITCH_SOURCE 12:0 + +#define DE_FOREGROUND 0x100014 +#define DE_FOREGROUND_COLOR 31:0 + +#define DE_BACKGROUND 0x100018 +#define DE_BACKGROUND_COLOR 31:0 + +#define DE_STRETCH_FORMAT 0x10001C +#define DE_STRETCH_FORMAT_PATTERN_XY 30:30 +#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0 +#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1 +#define DE_STRETCH_FORMAT_PATTERN_Y 29:27 +#define DE_STRETCH_FORMAT_PATTERN_X 25:23 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21:20 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2 +#define DE_STRETCH_FORMAT_ADDRESSING 19:16 +#define DE_STRETCH_FORMAT_ADDRESSING_XY 0 +#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15 +#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11:0 + +#define DE_COLOR_COMPARE 0x100020 +#define DE_COLOR_COMPARE_COLOR 23:0 + +#define DE_COLOR_COMPARE_MASK 0x100024 +#define DE_COLOR_COMPARE_MASK_MASKS 23:0 + +#define DE_MASKS 0x100028 +#define DE_MASKS_BYTE_MASK 31:16 +#define DE_MASKS_BIT_MASK 15:0 + +#define DE_CLIP_TL 0x10002C +#define DE_CLIP_TL_TOP 31:16 +#define DE_CLIP_TL_STATUS 13:13 +#define DE_CLIP_TL_STATUS_DISABLE 0 +#define DE_CLIP_TL_STATUS_ENABLE 1 +#define DE_CLIP_TL_INHIBIT 12:12 +#define DE_CLIP_TL_INHIBIT_OUTSIDE 0 +#define DE_CLIP_TL_INHIBIT_INSIDE 1 +#define DE_CLIP_TL_LEFT 11:0 + +#define DE_CLIP_BR 0x100030 +#define DE_CLIP_BR_BOTTOM 31:16 +#define DE_CLIP_BR_RIGHT 12:0 + +#define DE_MONO_PATTERN_LOW 0x100034 +#define DE_MONO_PATTERN_LOW_PATTERN 31:0 + +#define DE_MONO_PATTERN_HIGH 0x100038 +#define DE_MONO_PATTERN_HIGH_PATTERN 31:0 + +#define DE_WINDOW_WIDTH 0x10003C +#define DE_WINDOW_WIDTH_DESTINATION 28:16 +#define DE_WINDOW_WIDTH_SOURCE 12:0 + +#define DE_WINDOW_SOURCE_BASE 0x100040 +#define DE_WINDOW_SOURCE_BASE_EXT 27:27 +#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0 +#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1 +#define DE_WINDOW_SOURCE_BASE_CS 26:26 +#define DE_WINDOW_SOURCE_BASE_CS_0 0 +#define DE_WINDOW_SOURCE_BASE_CS_1 1 +#define DE_WINDOW_SOURCE_BASE_ADDRESS 25:0 + +#define DE_WINDOW_DESTINATION_BASE 0x100044 +#define DE_WINDOW_DESTINATION_BASE_EXT 27:27 +#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0 +#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1 +#define DE_WINDOW_DESTINATION_BASE_CS 26:26 +#define DE_WINDOW_DESTINATION_BASE_CS_0 0 +#define DE_WINDOW_DESTINATION_BASE_CS_1 1 +#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25:0 + +#define DE_ALPHA 0x100048 +#define DE_ALPHA_VALUE 7:0 + +#define DE_WRAP 0x10004C +#define DE_WRAP_X 31:16 +#define DE_WRAP_Y 15:0 + +#define DE_STATUS 0x100050 +#define DE_STATUS_CSC 1:1 +#define DE_STATUS_CSC_CLEAR 0 +#define DE_STATUS_CSC_NOT_ACTIVE 0 +#define DE_STATUS_CSC_ACTIVE 1 +#define DE_STATUS_2D 0:0 +#define DE_STATUS_2D_CLEAR 0 +#define DE_STATUS_2D_NOT_ACTIVE 0 +#define DE_STATUS_2D_ACTIVE 1 +#endif +/* Color Space Conversion registers. */ + +#define CSC_Y_SOURCE_BASE 0x1000C8 +#define CSC_Y_SOURCE_BASE_EXT 27:27 +#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_Y_SOURCE_BASE_CS 26:26 +#define CSC_Y_SOURCE_BASE_CS_0 0 +#define CSC_Y_SOURCE_BASE_CS_1 1 +#define CSC_Y_SOURCE_BASE_ADDRESS 25:0 + +#define CSC_CONSTANTS 0x1000CC +#define CSC_CONSTANTS_Y 31:24 +#define CSC_CONSTANTS_R 23:16 +#define CSC_CONSTANTS_G 15:8 +#define CSC_CONSTANTS_B 7:0 + +#define CSC_Y_SOURCE_X 0x1000D0 +#define CSC_Y_SOURCE_X_INTEGER 26:16 +#define CSC_Y_SOURCE_X_FRACTION 15:3 + +#define CSC_Y_SOURCE_Y 0x1000D4 +#define CSC_Y_SOURCE_Y_INTEGER 27:16 +#define CSC_Y_SOURCE_Y_FRACTION 15:3 + +#define CSC_U_SOURCE_BASE 0x1000D8 +#define CSC_U_SOURCE_BASE_EXT 27:27 +#define CSC_U_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_U_SOURCE_BASE_CS 26:26 +#define CSC_U_SOURCE_BASE_CS_0 0 +#define CSC_U_SOURCE_BASE_CS_1 1 +#define CSC_U_SOURCE_BASE_ADDRESS 25:0 + +#define CSC_V_SOURCE_BASE 0x1000DC +#define CSC_V_SOURCE_BASE_EXT 27:27 +#define CSC_V_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_V_SOURCE_BASE_CS 26:26 +#define CSC_V_SOURCE_BASE_CS_0 0 +#define CSC_V_SOURCE_BASE_CS_1 1 +#define CSC_V_SOURCE_BASE_ADDRESS 25:0 + +#define CSC_SOURCE_DIMENSION 0x1000E0 +#define CSC_SOURCE_DIMENSION_X 31:16 +#define CSC_SOURCE_DIMENSION_Y 15:0 + +#define CSC_SOURCE_PITCH 0x1000E4 +#define CSC_SOURCE_PITCH_Y 31:16 +#define CSC_SOURCE_PITCH_UV 15:0 + +#define CSC_DESTINATION 0x1000E8 +#define CSC_DESTINATION_WRAP 31:31 +#define CSC_DESTINATION_WRAP_DISABLE 0 +#define CSC_DESTINATION_WRAP_ENABLE 1 +#define CSC_DESTINATION_X 27:16 +#define CSC_DESTINATION_Y 11:0 + +#define CSC_DESTINATION_DIMENSION 0x1000EC +#define CSC_DESTINATION_DIMENSION_X 31:16 +#define CSC_DESTINATION_DIMENSION_Y 15:0 + +#define CSC_DESTINATION_PITCH 0x1000F0 +#define CSC_DESTINATION_PITCH_X 31:16 +#define CSC_DESTINATION_PITCH_Y 15:0 + +#define CSC_SCALE_FACTOR 0x1000F4 +#define CSC_SCALE_FACTOR_HORIZONTAL 31:16 +#define CSC_SCALE_FACTOR_VERTICAL 15:0 + +#define CSC_DESTINATION_BASE 0x1000F8 +#define CSC_DESTINATION_BASE_EXT 27:27 +#define CSC_DESTINATION_BASE_EXT_LOCAL 0 +#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1 +#define CSC_DESTINATION_BASE_CS 26:26 +#define CSC_DESTINATION_BASE_CS_0 0 +#define CSC_DESTINATION_BASE_CS_1 1 +#define CSC_DESTINATION_BASE_ADDRESS 25:0 + +#define CSC_CONTROL 0x1000FC +#define CSC_CONTROL_STATUS 31:31 +#define CSC_CONTROL_STATUS_STOP 0 +#define CSC_CONTROL_STATUS_START 1 +#define CSC_CONTROL_SOURCE_FORMAT 30:28 +#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0 +#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1 +#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2 +#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3 +#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4 +#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5 +#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6 +#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7 +#define CSC_CONTROL_DESTINATION_FORMAT 27:26 +#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0 +#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1 +#define CSC_CONTROL_HORIZONTAL_FILTER 25:25 +#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0 +#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1 +#define CSC_CONTROL_VERTICAL_FILTER 24:24 +#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0 +#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1 +#define CSC_CONTROL_BYTE_ORDER 23:23 +#define CSC_CONTROL_BYTE_ORDER_YUYV 0 +#define CSC_CONTROL_BYTE_ORDER_UYVY 1 + +#define DE_DATA_PORT 0x110000 + +#define I2C_BYTE_COUNT 0x010040 +#define I2C_BYTE_COUNT_COUNT 3:0 + +#define I2C_CTRL 0x010041 +#define I2C_CTRL_INT 4:4 +#define I2C_CTRL_INT_DISABLE 0 +#define I2C_CTRL_INT_ENABLE 1 +#define I2C_CTRL_DIR 3:3 +#define I2C_CTRL_DIR_WR 0 +#define I2C_CTRL_DIR_RD 1 +#define I2C_CTRL_CTRL 2:2 +#define I2C_CTRL_CTRL_STOP 0 +#define I2C_CTRL_CTRL_START 1 +#define I2C_CTRL_MODE 1:1 +#define I2C_CTRL_MODE_STANDARD 0 +#define I2C_CTRL_MODE_FAST 1 +#define I2C_CTRL_EN 0:0 +#define I2C_CTRL_EN_DISABLE 0 +#define I2C_CTRL_EN_ENABLE 1 + +#define I2C_STATUS 0x010042 +#define I2C_STATUS_TX 3:3 +#define I2C_STATUS_TX_PROGRESS 0 +#define I2C_STATUS_TX_COMPLETED 1 +#define I2C_TX_DONE 0x08 +#define I2C_STATUS_ERR 2:2 +#define I2C_STATUS_ERR_NORMAL 0 +#define I2C_STATUS_ERR_ERROR 1 +#define I2C_STATUS_ERR_CLEAR 0 +#define I2C_STATUS_ACK 1:1 +#define I2C_STATUS_ACK_RECEIVED 0 +#define I2C_STATUS_ACK_NOT 1 +#define I2C_STATUS_BSY 0:0 +#define I2C_STATUS_BSY_IDLE 0 +#define I2C_STATUS_BSY_BUSY 1 + +#define I2C_RESET 0x010042 +#define I2C_RESET_BUS_ERROR 2:2 +#define I2C_RESET_BUS_ERROR_CLEAR 0 + +#define I2C_SLAVE_ADDRESS 0x010043 +#define I2C_SLAVE_ADDRESS_ADDRESS 7:1 +#define I2C_SLAVE_ADDRESS_RW 0:0 +#define I2C_SLAVE_ADDRESS_RW_W 0 +#define I2C_SLAVE_ADDRESS_RW_R 1 + +#define I2C_DATA0 0x010044 +#define I2C_DATA1 0x010045 +#define I2C_DATA2 0x010046 +#define I2C_DATA3 0x010047 +#define I2C_DATA4 0x010048 +#define I2C_DATA5 0x010049 +#define I2C_DATA6 0x01004A +#define I2C_DATA7 0x01004B +#define I2C_DATA8 0x01004C +#define I2C_DATA9 0x01004D +#define I2C_DATA10 0x01004E +#define I2C_DATA11 0x01004F +#define I2C_DATA12 0x010050 +#define I2C_DATA13 0x010051 +#define I2C_DATA14 0x010052 +#define I2C_DATA15 0x010053 + + +#define ZV0_CAPTURE_CTRL 0x090000 +#define ZV0_CAPTURE_CTRL_FIELD_INPUT 27:27 +#define ZV0_CAPTURE_CTRL_FIELD_INPUT_EVEN_FIELD 0 +#define ZV0_CAPTURE_CTRL_FIELD_INPUT_ODD_FIELD 1 +#define ZV0_CAPTURE_CTRL_SCAN 26:26 +#define ZV0_CAPTURE_CTRL_SCAN_PROGRESSIVE 0 +#define ZV0_CAPTURE_CTRL_SCAN_INTERLACE 1 +#define ZV0_CAPTURE_CTRL_CURRENT_BUFFER 25:25 +#define ZV0_CAPTURE_CTRL_CURRENT_BUFFER_0 0 +#define ZV0_CAPTURE_CTRL_CURRENT_BUFFER_1 1 +#define ZV0_CAPTURE_CTRL_VERTICAL_SYNC 24:24 +#define ZV0_CAPTURE_CTRL_VERTICAL_SYNC_INACTIVE 0 +#define ZV0_CAPTURE_CTRL_VERTICAL_SYNC_ACTIVE 1 +#define ZV0_CAPTURE_CTRL_ADJ 19:19 +#define ZV0_CAPTURE_CTRL_ADJ_NORMAL 0 +#define ZV0_CAPTURE_CTRL_ADJ_DELAY 1 +#define ZV0_CAPTURE_CTRL_HA 18:18 +#define ZV0_CAPTURE_CTRL_HA_DISABLE 0 +#define ZV0_CAPTURE_CTRL_HA_ENABLE 1 +#define ZV0_CAPTURE_CTRL_VSK 17:17 +#define ZV0_CAPTURE_CTRL_VSK_DISABLE 0 +#define ZV0_CAPTURE_CTRL_VSK_ENABLE 1 +#define ZV0_CAPTURE_CTRL_HSK 16:16 +#define ZV0_CAPTURE_CTRL_HSK_DISABLE 0 +#define ZV0_CAPTURE_CTRL_HSK_ENABLE 1 +#define ZV0_CAPTURE_CTRL_FD 15:15 +#define ZV0_CAPTURE_CTRL_FD_RISING 0 +#define ZV0_CAPTURE_CTRL_FD_FALLING 1 +#define ZV0_CAPTURE_CTRL_VP 14:14 +#define ZV0_CAPTURE_CTRL_VP_HIGH 0 +#define ZV0_CAPTURE_CTRL_VP_LOW 1 +#define ZV0_CAPTURE_CTRL_HP 13:13 +#define ZV0_CAPTURE_CTRL_HP_HIGH 0 +#define ZV0_CAPTURE_CTRL_HP_LOW 1 +#define ZV0_CAPTURE_CTRL_CP 12:12 +#define ZV0_CAPTURE_CTRL_CP_HIGH 0 +#define ZV0_CAPTURE_CTRL_CP_LOW 1 +#define ZV0_CAPTURE_CTRL_UVS 11:11 +#define ZV0_CAPTURE_CTRL_UVS_DISABLE 0 +#define ZV0_CAPTURE_CTRL_UVS_ENABLE 1 +#define ZV0_CAPTURE_CTRL_BS 10:10 +#define ZV0_CAPTURE_CTRL_BS_DISABLE 0 +#define ZV0_CAPTURE_CTRL_BS_ENABLE 1 +#define ZV0_CAPTURE_CTRL_CS 9:9 +#define ZV0_CAPTURE_CTRL_CS_16 0 +#define ZV0_CAPTURE_CTRL_CS_8 1 +#define ZV0_CAPTURE_CTRL_CF 8:8 +#define ZV0_CAPTURE_CTRL_CF_YUV 0 +#define ZV0_CAPTURE_CTRL_CF_RGB 1 +#define ZV0_CAPTURE_CTRL_FS 7:7 +#define ZV0_CAPTURE_CTRL_FS_DISABLE 0 +#define ZV0_CAPTURE_CTRL_FS_ENABLE 1 +#define ZV0_CAPTURE_CTRL_WEAVE 6:6 +#define ZV0_CAPTURE_CTRL_WEAVE_DISABLE 0 +#define ZV0_CAPTURE_CTRL_WEAVE_ENABLE 1 +#define ZV0_CAPTURE_CTRL_BOB 5:5 +#define ZV0_CAPTURE_CTRL_BOB_DISABLE 0 +#define ZV0_CAPTURE_CTRL_BOB_ENABLE 1 +#define ZV0_CAPTURE_CTRL_DB 4:4 +#define ZV0_CAPTURE_CTRL_DB_DISABLE 0 +#define ZV0_CAPTURE_CTRL_DB_ENABLE 1 +#define ZV0_CAPTURE_CTRL_CC 3:3 +#define ZV0_CAPTURE_CTRL_CC_CONTINUE 0 +#define ZV0_CAPTURE_CTRL_CC_CONDITION 1 +#define ZV0_CAPTURE_CTRL_RGB 2:2 +#define ZV0_CAPTURE_CTRL_RGB_DISABLE 0 +#define ZV0_CAPTURE_CTRL_RGB_ENABLE 1 +#define ZV0_CAPTURE_CTRL_656 1:1 +#define ZV0_CAPTURE_CTRL_656_DISABLE 0 +#define ZV0_CAPTURE_CTRL_656_ENABLE 1 +#define ZV0_CAPTURE_CTRL_CAP 0:0 +#define ZV0_CAPTURE_CTRL_CAP_DISABLE 0 +#define ZV0_CAPTURE_CTRL_CAP_ENABLE 1 + +#define ZV0_CAPTURE_CLIP 0x090004 +#define ZV0_CAPTURE_CLIP_YCLIP_EVEN_FIELD 25:16 +#define ZV0_CAPTURE_CLIP_YCLIP 25:16 +#define ZV0_CAPTURE_CLIP_XCLIP 9:0 + +#define ZV0_CAPTURE_SIZE 0x090008 +#define ZV0_CAPTURE_SIZE_HEIGHT 26:16 +#define ZV0_CAPTURE_SIZE_WIDTH 10:0 + +#define ZV0_CAPTURE_BUF0_ADDRESS 0x09000C +#define ZV0_CAPTURE_BUF0_ADDRESS_STATUS 31:31 +#define ZV0_CAPTURE_BUF0_ADDRESS_STATUS_CURRENT 0 +#define ZV0_CAPTURE_BUF0_ADDRESS_STATUS_PENDING 1 +#define ZV0_CAPTURE_BUF0_ADDRESS_EXT 27:27 +#define ZV0_CAPTURE_BUF0_ADDRESS_EXT_LOCAL 0 +#define ZV0_CAPTURE_BUF0_ADDRESS_EXT_EXTERNAL 1 +#define ZV0_CAPTURE_BUF0_ADDRESS_CS 26:26 +#define ZV0_CAPTURE_BUF0_ADDRESS_CS_0 0 +#define ZV0_CAPTURE_BUF0_ADDRESS_CS_1 1 +#define ZV0_CAPTURE_BUF0_ADDRESS_ADDRESS 25:0 + +#define ZV0_CAPTURE_BUF1_ADDRESS 0x090010 +#define ZV0_CAPTURE_BUF1_ADDRESS_STATUS 31:31 +#define ZV0_CAPTURE_BUF1_ADDRESS_STATUS_CURRENT 0 +#define ZV0_CAPTURE_BUF1_ADDRESS_STATUS_PENDING 1 +#define ZV0_CAPTURE_BUF1_ADDRESS_EXT 27:27 +#define ZV0_CAPTURE_BUF1_ADDRESS_EXT_LOCAL 0 +#define ZV0_CAPTURE_BUF1_ADDRESS_EXT_EXTERNAL 1 +#define ZV0_CAPTURE_BUF1_ADDRESS_CS 26:26 +#define ZV0_CAPTURE_BUF1_ADDRESS_CS_0 0 +#define ZV0_CAPTURE_BUF1_ADDRESS_CS_1 1 +#define ZV0_CAPTURE_BUF1_ADDRESS_ADDRESS 25:0 + +#define ZV0_CAPTURE_BUF_OFFSET 0x090014 +#ifndef VALIDATION_CHIP + #define ZV0_CAPTURE_BUF_OFFSET_YCLIP_ODD_FIELD 25:16 +#endif +#define ZV0_CAPTURE_BUF_OFFSET_OFFSET 15:0 + +#define ZV0_CAPTURE_FIFO_CTRL 0x090018 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO 2:0 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_0 0 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_1 1 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_2 2 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_3 3 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_4 4 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_5 5 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_6 6 +#define ZV0_CAPTURE_FIFO_CTRL_FIFO_7 7 + +#define ZV0_CAPTURE_YRGB_CONST 0x09001C +#define ZV0_CAPTURE_YRGB_CONST_Y 31:24 +#define ZV0_CAPTURE_YRGB_CONST_R 23:16 +#define ZV0_CAPTURE_YRGB_CONST_G 15:8 +#define ZV0_CAPTURE_YRGB_CONST_B 7:0 + +#define ZV0_CAPTURE_LINE_COMP 0x090020 +#define ZV0_CAPTURE_LINE_COMP_LC 10:0 + +/* ZV1 */ + +#define ZV1_CAPTURE_CTRL 0x098000 +#define ZV1_CAPTURE_CTRL_FIELD_INPUT 27:27 +#define ZV1_CAPTURE_CTRL_FIELD_INPUT_EVEN_FIELD 0 +#define ZV1_CAPTURE_CTRL_FIELD_INPUT_ODD_FIELD 0 +#define ZV1_CAPTURE_CTRL_SCAN 26:26 +#define ZV1_CAPTURE_CTRL_SCAN_PROGRESSIVE 0 +#define ZV1_CAPTURE_CTRL_SCAN_INTERLACE 1 +#define ZV1_CAPTURE_CTRL_CURRENT_BUFFER 25:25 +#define ZV1_CAPTURE_CTRL_CURRENT_BUFFER_0 0 +#define ZV1_CAPTURE_CTRL_CURRENT_BUFFER_1 1 +#define ZV1_CAPTURE_CTRL_VERTICAL_SYNC 24:24 +#define ZV1_CAPTURE_CTRL_VERTICAL_SYNC_INACTIVE 0 +#define ZV1_CAPTURE_CTRL_VERTICAL_SYNC_ACTIVE 1 +#define ZV1_CAPTURE_CTRL_PANEL 20:20 +#define ZV1_CAPTURE_CTRL_PANEL_DISABLE 0 +#define ZV1_CAPTURE_CTRL_PANEL_ENABLE 1 +#define ZV1_CAPTURE_CTRL_ADJ 19:19 +#define ZV1_CAPTURE_CTRL_ADJ_NORMAL 0 +#define ZV1_CAPTURE_CTRL_ADJ_DELAY 1 +#define ZV1_CAPTURE_CTRL_HA 18:18 +#define ZV1_CAPTURE_CTRL_HA_DISABLE 0 +#define ZV1_CAPTURE_CTRL_HA_ENABLE 1 +#define ZV1_CAPTURE_CTRL_VSK 17:17 +#define ZV1_CAPTURE_CTRL_VSK_DISABLE 0 +#define ZV1_CAPTURE_CTRL_VSK_ENABLE 1 +#define ZV1_CAPTURE_CTRL_HSK 16:16 +#define ZV1_CAPTURE_CTRL_HSK_DISABLE 0 +#define ZV1_CAPTURE_CTRL_HSK_ENABLE 1 +#define ZV1_CAPTURE_CTRL_FD 15:15 +#define ZV1_CAPTURE_CTRL_FD_RISING 0 +#define ZV1_CAPTURE_CTRL_FD_FALLING 1 +#define ZV1_CAPTURE_CTRL_VP 14:14 +#define ZV1_CAPTURE_CTRL_VP_HIGH 0 +#define ZV1_CAPTURE_CTRL_VP_LOW 1 +#define ZV1_CAPTURE_CTRL_HP 13:13 +#define ZV1_CAPTURE_CTRL_HP_HIGH 0 +#define ZV1_CAPTURE_CTRL_HP_LOW 1 +#define ZV1_CAPTURE_CTRL_CP 12:12 +#define ZV1_CAPTURE_CTRL_CP_HIGH 0 +#define ZV1_CAPTURE_CTRL_CP_LOW 1 +#define ZV1_CAPTURE_CTRL_UVS 11:11 +#define ZV1_CAPTURE_CTRL_UVS_DISABLE 0 +#define ZV1_CAPTURE_CTRL_UVS_ENABLE 1 +#define ZV1_CAPTURE_CTRL_BS 10:10 +#define ZV1_CAPTURE_CTRL_BS_DISABLE 0 +#define ZV1_CAPTURE_CTRL_BS_ENABLE 1 +#define ZV1_CAPTURE_CTRL_CS 9:9 +#define ZV1_CAPTURE_CTRL_CS_16 0 +#define ZV1_CAPTURE_CTRL_CS_8 1 +#define ZV1_CAPTURE_CTRL_CF 8:8 +#define ZV1_CAPTURE_CTRL_CF_YUV 0 +#define ZV1_CAPTURE_CTRL_CF_RGB 1 +#define ZV1_CAPTURE_CTRL_FS 7:7 +#define ZV1_CAPTURE_CTRL_FS_DISABLE 0 +#define ZV1_CAPTURE_CTRL_FS_ENABLE 1 +#define ZV1_CAPTURE_CTRL_WEAVE 6:6 +#define ZV1_CAPTURE_CTRL_WEAVE_DISABLE 0 +#define ZV1_CAPTURE_CTRL_WEAVE_ENABLE 1 +#define ZV1_CAPTURE_CTRL_BOB 5:5 +#define ZV1_CAPTURE_CTRL_BOB_DISABLE 0 +#define ZV1_CAPTURE_CTRL_BOB_ENABLE 1 +#define ZV1_CAPTURE_CTRL_DB 4:4 +#define ZV1_CAPTURE_CTRL_DB_DISABLE 0 +#define ZV1_CAPTURE_CTRL_DB_ENABLE 1 +#define ZV1_CAPTURE_CTRL_CC 3:3 +#define ZV1_CAPTURE_CTRL_CC_CONTINUE 0 +#define ZV1_CAPTURE_CTRL_CC_CONDITION 1 +#define ZV1_CAPTURE_CTRL_RGB 2:2 +#define ZV1_CAPTURE_CTRL_RGB_DISABLE 0 +#define ZV1_CAPTURE_CTRL_RGB_ENABLE 1 +#define ZV1_CAPTURE_CTRL_656 1:1 +#define ZV1_CAPTURE_CTRL_656_DISABLE 0 +#define ZV1_CAPTURE_CTRL_656_ENABLE 1 +#define ZV1_CAPTURE_CTRL_CAP 0:0 +#define ZV1_CAPTURE_CTRL_CAP_DISABLE 0 +#define ZV1_CAPTURE_CTRL_CAP_ENABLE 1 + +#define ZV1_CAPTURE_CLIP 0x098004 +#define ZV1_CAPTURE_CLIP_YCLIP 25:16 +#define ZV1_CAPTURE_CLIP_XCLIP 9:0 + +#define ZV1_CAPTURE_SIZE 0x098008 +#define ZV1_CAPTURE_SIZE_HEIGHT 26:16 +#define ZV1_CAPTURE_SIZE_WIDTH 10:0 + +#define ZV1_CAPTURE_BUF0_ADDRESS 0x09800C +#define ZV1_CAPTURE_BUF0_ADDRESS_STATUS 31:31 +#define ZV1_CAPTURE_BUF0_ADDRESS_STATUS_CURRENT 0 +#define ZV1_CAPTURE_BUF0_ADDRESS_STATUS_PENDING 1 +#define ZV1_CAPTURE_BUF0_ADDRESS_EXT 27:27 +#define ZV1_CAPTURE_BUF0_ADDRESS_EXT_LOCAL 0 +#define ZV1_CAPTURE_BUF0_ADDRESS_EXT_EXTERNAL 1 +#define ZV1_CAPTURE_BUF0_ADDRESS_CS 26:26 +#define ZV1_CAPTURE_BUF0_ADDRESS_CS_0 0 +#define ZV1_CAPTURE_BUF0_ADDRESS_CS_1 1 +#define ZV1_CAPTURE_BUF0_ADDRESS_ADDRESS 25:0 + +#define ZV1_CAPTURE_BUF1_ADDRESS 0x098010 +#define ZV1_CAPTURE_BUF1_ADDRESS_STATUS 31:31 +#define ZV1_CAPTURE_BUF1_ADDRESS_STATUS_CURRENT 0 +#define ZV1_CAPTURE_BUF1_ADDRESS_STATUS_PENDING 1 +#define ZV1_CAPTURE_BUF1_ADDRESS_EXT 27:27 +#define ZV1_CAPTURE_BUF1_ADDRESS_EXT_LOCAL 0 +#define ZV1_CAPTURE_BUF1_ADDRESS_EXT_EXTERNAL 1 +#define ZV1_CAPTURE_BUF1_ADDRESS_CS 26:26 +#define ZV1_CAPTURE_BUF1_ADDRESS_CS_0 0 +#define ZV1_CAPTURE_BUF1_ADDRESS_CS_1 1 +#define ZV1_CAPTURE_BUF1_ADDRESS_ADDRESS 25:0 + +#define ZV1_CAPTURE_BUF_OFFSET 0x098014 +#define ZV1_CAPTURE_BUF_OFFSET_OFFSET 15:0 + +#define ZV1_CAPTURE_FIFO_CTRL 0x098018 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO 2:0 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_0 0 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_1 1 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_2 2 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_3 3 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_4 4 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_5 5 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_6 6 +#define ZV1_CAPTURE_FIFO_CTRL_FIFO_7 7 + +#define ZV1_CAPTURE_YRGB_CONST 0x09801C +#define ZV1_CAPTURE_YRGB_CONST_Y 31:24 +#define ZV1_CAPTURE_YRGB_CONST_R 23:16 +#define ZV1_CAPTURE_YRGB_CONST_G 15:8 +#define ZV1_CAPTURE_YRGB_CONST_B 7:0 + +#define DMA_1_SOURCE 0x0D0010 +#define DMA_1_SOURCE_ADDRESS_EXT 27:27 +#define DMA_1_SOURCE_ADDRESS_EXT_LOCAL 0 +#define DMA_1_SOURCE_ADDRESS_EXT_EXTERNAL 1 +#define DMA_1_SOURCE_ADDRESS_CS 26:26 +#define DMA_1_SOURCE_ADDRESS_CS_0 0 +#define DMA_1_SOURCE_ADDRESS_CS_1 1 +#define DMA_1_SOURCE_ADDRESS 25:0 + +#define DMA_1_DESTINATION 0x0D0014 +#define DMA_1_DESTINATION_ADDRESS_EXT 27:27 +#define DMA_1_DESTINATION_ADDRESS_EXT_LOCAL 0 +#define DMA_1_DESTINATION_ADDRESS_EXT_EXTERNAL 1 +#define DMA_1_DESTINATION_ADDRESS_CS 26:26 +#define DMA_1_DESTINATION_ADDRESS_CS_0 0 +#define DMA_1_DESTINATION_ADDRESS_CS_1 1 +#define DMA_1_DESTINATION_ADDRESS 25:0 + +#define DMA_1_SIZE_CONTROL 0x0D0018 +#define DMA_1_SIZE_CONTROL_STATUS 31:31 +#define DMA_1_SIZE_CONTROL_STATUS_IDLE 0 +#define DMA_1_SIZE_CONTROL_STATUS_ACTIVE 1 +#define DMA_1_SIZE_CONTROL_SIZE 23:0 + +#define DMA_ABORT_INTERRUPT 0x0D0020 +#define DMA_ABORT_INTERRUPT_ABORT_1 5:5 +#define DMA_ABORT_INTERRUPT_ABORT_1_ENABLE 0 +#define DMA_ABORT_INTERRUPT_ABORT_1_ABORT 1 +#define DMA_ABORT_INTERRUPT_ABORT_0 4:4 +#define DMA_ABORT_INTERRUPT_ABORT_0_ENABLE 0 +#define DMA_ABORT_INTERRUPT_ABORT_0_ABORT 1 +#define DMA_ABORT_INTERRUPT_INT_1 1:1 +#define DMA_ABORT_INTERRUPT_INT_1_CLEAR 0 +#define DMA_ABORT_INTERRUPT_INT_1_FINISHED 1 +#define DMA_ABORT_INTERRUPT_INT_0 0:0 +#define DMA_ABORT_INTERRUPT_INT_0_CLEAR 0 +#define DMA_ABORT_INTERRUPT_INT_0_FINISHED 1 + + + + + +/* Default i2c CLK and Data GPIO. These are the default i2c pins */ +#define DEFAULT_I2C_SCL 30 +#define DEFAULT_I2C_SDA 31 + + +#define GPIO_DATA_SM750LE 0x020018 +#define GPIO_DATA_SM750LE_1 1:1 +#define GPIO_DATA_SM750LE_0 0:0 + +#define GPIO_DATA_DIRECTION_SM750LE 0x02001C +#define GPIO_DATA_DIRECTION_SM750LE_1 1:1 +#define GPIO_DATA_DIRECTION_SM750LE_1_INPUT 0 +#define GPIO_DATA_DIRECTION_SM750LE_1_OUTPUT 1 +#define GPIO_DATA_DIRECTION_SM750LE_0 0:0 +#define GPIO_DATA_DIRECTION_SM750LE_0_INPUT 0 +#define GPIO_DATA_DIRECTION_SM750LE_0_OUTPUT 1 + + +#endif diff --git a/src/ddk750/ddk750_sii164.c b/src/ddk750/ddk750_sii164.c new file mode 100644 index 0000000..cb725aa --- /dev/null +++ b/src/ddk750/ddk750_sii164.c @@ -0,0 +1,423 @@ +#ifdef USE_DVICHIP + +#include "ddk750_sii164.h" +#include "ddk750_hwi2c.h" + +/* I2C Address of each SII164 chip */ +#define SII164_I2C_ADDRESS 0x70 + +/* Define this definition to use hardware i2c. */ +/*#define USE_HW_I2C*/ +#ifdef USE_HW_I2C + #define i2cWriteReg hwI2CWriteReg + #define i2cReadReg hwI2CReadReg +#else + #define i2cWriteReg swI2CWriteReg + #define i2cReadReg swI2CReadReg +#endif + +/* SII164 Vendor and Device ID */ +#define SII164_VENDOR_ID 0x0001 +#define SII164_DEVICE_ID 0x0006 + +#ifdef SII164_FULL_FUNCTIONS +/* Name of the DVI Controller chip */ +static char *gDviCtrlChipName = "Silicon Image SiI 164"; +#endif + +/* + * sii164GetVendorID + * This function gets the vendor ID of the DVI controller chip. + * + * Output: + * Vendor ID + */ +unsigned short sii164GetVendorID() +{ + unsigned short vendorID; + + vendorID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_HIGH) << 8) | + (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_LOW); + + return vendorID; +} + +/* + * sii164GetDeviceID + * This function gets the device ID of the DVI controller chip. + * + * Output: + * Device ID + */ +unsigned short sii164GetDeviceID() +{ + unsigned short deviceID; + + deviceID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_HIGH) << 8) | + (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_LOW); + + return deviceID; +} + + + +/* DVI.C will handle all SiI164 chip stuffs and try it best to make code minimal and useful */ + +/* + * sii164InitChip + * This function initialize and detect the DVI controller chip. + * + * Input: + * edgeSelect - Edge Select: + * 0 = Input data is falling edge latched (falling edge + * latched first in dual edge mode) + * 1 = Input data is rising edge latched (rising edge + * latched first in dual edge mode) + * busSelect - Input Bus Select: + * 0 = Input data bus is 12-bits wide + * 1 = Input data bus is 24-bits wide + * dualEdgeClkSelect - Dual Edge Clock Select + * 0 = Input data is single edge latched + * 1 = Input data is dual edge latched + * hsyncEnable - Horizontal Sync Enable: + * 0 = HSYNC input is transmitted as fixed LOW + * 1 = HSYNC input is transmitted as is + * vsyncEnable - Vertical Sync Enable: + * 0 = VSYNC input is transmitted as fixed LOW + * 1 = VSYNC input is transmitted as is + * deskewEnable - De-skewing Enable: + * 0 = De-skew disabled + * 1 = De-skew enabled + * deskewSetting - De-skewing Setting (increment of 260psec) + * 0 = 1 step --> minimum setup / maximum hold + * 1 = 2 step + * 2 = 3 step + * 3 = 4 step + * 4 = 5 step + * 5 = 6 step + * 6 = 7 step + * 7 = 8 step --> maximum setup / minimum hold + * continuousSyncEnable- SYNC Continuous: + * 0 = Disable + * 1 = Enable + * pllFilterEnable - PLL Filter Enable + * 0 = Disable PLL Filter + * 1 = Enable PLL Filter + * pllFilterValue - PLL Filter characteristics: + * 0~7 (recommended value is 4) + * + * Output: + * 0 - Success + * -1 - Fail. + */ +long sii164InitChip( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue +) +{ + //unsigned char ucRegIndex, ucRegValue; + //unsigned char ucDeviceAddress, + unsigned char config; + //unsigned long delayCount; + + /* Initialize the i2c bus */ +#ifdef USE_HW_I2C + /* Use fast mode. */ + hwI2CInit(1); +#else + swI2CInit(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA); +#endif + + /* Check if SII164 Chip exists */ + if ((sii164GetVendorID() == SII164_VENDOR_ID) && (sii164GetDeviceID() == SII164_DEVICE_ID)) + { + +#ifdef DDKDEBUG + //sii164PrintRegisterValues(); +#endif + /* + * Initialize SII164 controller chip. + */ + + /* Select the edge */ + if (edgeSelect == 0) + config = SII164_CONFIGURATION_LATCH_FALLING; + else + config = SII164_CONFIGURATION_LATCH_RISING; + + /* Select bus wide */ + if (busSelect == 0) + config |= SII164_CONFIGURATION_BUS_12BITS; + else + config |= SII164_CONFIGURATION_BUS_24BITS; + + /* Select Dual/Single Edge Clock */ + if (dualEdgeClkSelect == 0) + config |= SII164_CONFIGURATION_CLOCK_SINGLE; + else + config |= SII164_CONFIGURATION_CLOCK_DUAL; + + /* Select HSync Enable */ + if (hsyncEnable == 0) + config |= SII164_CONFIGURATION_HSYNC_FORCE_LOW; + else + config |= SII164_CONFIGURATION_HSYNC_AS_IS; + + /* Select VSync Enable */ + if (vsyncEnable == 0) + config |= SII164_CONFIGURATION_VSYNC_FORCE_LOW; + else + config |= SII164_CONFIGURATION_VSYNC_AS_IS; + + i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); + + /* De-skew enabled with default 111b value. + This will fix some artifacts problem in some mode on board 2.2. + Somehow this fix does not affect board 2.1. + */ + if (deskewEnable == 0) + config = SII164_DESKEW_DISABLE; + else + config = SII164_DESKEW_ENABLE; + + switch (deskewSetting) + { + case 0: + config |= SII164_DESKEW_1_STEP; + break; + case 1: + config |= SII164_DESKEW_2_STEP; + break; + case 2: + config |= SII164_DESKEW_3_STEP; + break; + case 3: + config |= SII164_DESKEW_4_STEP; + break; + case 4: + config |= SII164_DESKEW_5_STEP; + break; + case 5: + config |= SII164_DESKEW_6_STEP; + break; + case 6: + config |= SII164_DESKEW_7_STEP; + break; + case 7: + config |= SII164_DESKEW_8_STEP; + break; + } + i2cWriteReg(SII164_I2C_ADDRESS, SII164_DESKEW, config); + + /* Enable/Disable Continuous Sync. */ + if (continuousSyncEnable == 0) + config = SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE; + else + config = SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE; + + /* Enable/Disable PLL Filter */ + if (pllFilterEnable == 0) + config |= SII164_PLL_FILTER_DISABLE; + else + config |= SII164_PLL_FILTER_ENABLE; + + /* Set the PLL Filter value */ + config |= ((pllFilterValue & 0x07) << 1); + + i2cWriteReg(SII164_I2C_ADDRESS, SII164_PLL, config); + + /* Recover from Power Down and enable output. */ + config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION); + config |= SII164_CONFIGURATION_POWER_NORMAL; + i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); + +#ifdef DDKDEBUG + //sii164PrintRegisterValues(); +#endif + + return 0; + } + + /* Return -1 if initialization fails. */ + return (-1); +} + + + + + +/* below sii164 function is not neccessary */ + +#ifdef SII164_FULL_FUNCTIONS + +/* + * sii164ResetChip + * This function resets the DVI Controller Chip. + */ +void sii164ResetChip() +{ + /* Power down */ + sii164SetPower(0); + sii164SetPower(1); +} + + +/* + * sii164GetChipString + * This function returns a char string name of the current DVI Controller chip. + * It's convenient for application need to display the chip name. + */ +char *sii164GetChipString() +{ + return gDviCtrlChipName; +} + + +/* + * sii164SetPower + * This function sets the power configuration of the DVI Controller Chip. + * + * Input: + * powerUp - Flag to set the power down or up + */ +void sii164SetPower( + unsigned char powerUp +) +{ + unsigned char config; + + config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION); + if (powerUp == 1) + { + /* Power up the chip */ + config &= ~SII164_CONFIGURATION_POWER_MASK; + config |= SII164_CONFIGURATION_POWER_NORMAL; + i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); + } + else + { + /* Power down the chip */ + config &= ~SII164_CONFIGURATION_POWER_MASK; + config |= SII164_CONFIGURATION_POWER_DOWN; + i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config); + } +} + + +/* + * sii164SelectHotPlugDetectionMode + * This function selects the mode of the hot plug detection. + */ +static void sii164SelectHotPlugDetectionMode( + sii164_hot_plug_mode_t hotPlugMode +) +{ + unsigned char detectReg; + + detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & ~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG; + switch (hotPlugMode) + { + case SII164_HOTPLUG_DISABLE: + detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH; + break; + case SII164_HOTPLUG_USE_MDI: + detectReg &= ~SII164_DETECT_INTERRUPT_MASK; + detectReg |= SII164_DETECT_INTERRUPT_BY_HTPLG_PIN; + detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI; + break; + case SII164_HOTPLUG_USE_RSEN: + detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN; + break; + case SII164_HOTPLUG_USE_HTPLG: + detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG; + break; + } + + i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg); +} + +/* + * sii164EnableHotPlugDetection + * This function enables the Hot Plug detection. + * + * enableHotPlug - Enable (=1) / disable (=0) Hot Plug detection + */ +void sii164EnableHotPlugDetection( + unsigned char enableHotPlug +) +{ + unsigned char detectReg; + detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT); + + /* Depending on each DVI controller, need to enable the hot plug based on each + individual chip design. */ + if (enableHotPlug != 0) + sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI); + else + sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_DISABLE); +} + +/* + * sii164IsConnected + * Check if the DVI Monitor is connected. + * + * Output: + * 0 - Not Connected + * 1 - Connected + */ +unsigned char sii164IsConnected() +{ + unsigned char hotPlugValue; + + hotPlugValue = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_HOT_PLUG_STATUS_MASK; + if (hotPlugValue == SII164_DETECT_HOT_PLUG_STATUS_ON) + return 1; + else + return 0; +} + +/* + * sii164CheckInterrupt + * Checks if interrupt has occured. + * + * Output: + * 0 - No interrupt + * 1 - Interrupt occurs + */ +unsigned char sii164CheckInterrupt() +{ + unsigned char detectReg; + + detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_MONITOR_STATE_MASK; + if (detectReg == SII164_DETECT_MONITOR_STATE_CHANGE) + return 1; + else + return 0; +} + +/* + * sii164ClearInterrupt + * Clear the hot plug interrupt. + */ +void sii164ClearInterrupt() +{ + unsigned char detectReg; + + /* Clear the MDI interrupt */ + detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT); + i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg | SII164_DETECT_MONITOR_STATE_CLEAR); +} + +#endif + +#endif + + diff --git a/src/ddk750/ddk750_sii164.h b/src/ddk750/ddk750_sii164.h new file mode 100644 index 0000000..f66a266 --- /dev/null +++ b/src/ddk750/ddk750_sii164.h @@ -0,0 +1,170 @@ +#ifndef DDK750_SII164_H__ +#define DDK750_SII164_H__ + +/* Hot Plug detection mode structure */ +typedef enum _sii164_hot_plug_mode_t +{ + SII164_HOTPLUG_DISABLE = 0, /* Disable Hot Plug output bit (always high). */ + SII164_HOTPLUG_USE_MDI, /* Use Monitor Detect Interrupt bit. */ + SII164_HOTPLUG_USE_RSEN, /* Use Receiver Sense detect bit. */ + SII164_HOTPLUG_USE_HTPLG /* Use Hot Plug detect bit. */ +} sii164_hot_plug_mode_t; + + +/* Silicon Image SiI164 chip prototype */ +long sii164InitChip( + unsigned char edgeSelect, + unsigned char busSelect, + unsigned char dualEdgeClkSelect, + unsigned char hsyncEnable, + unsigned char vsyncEnable, + unsigned char deskewEnable, + unsigned char deskewSetting, + unsigned char continuousSyncEnable, + unsigned char pllFilterEnable, + unsigned char pllFilterValue +); + +unsigned short sii164GetVendorID(void); +unsigned short sii164GetDeviceID(void); + + +#ifdef SII164_FULL_FUNCTIONS +void sii164ResetChip(void); +char *sii164GetChipString(void); +void sii164SetPower(unsigned char powerUp); +void sii164EnableHotPlugDetection(unsigned char enableHotPlug); +unsigned char sii164IsConnected(void); +unsigned char sii164CheckInterrupt(void); +void sii164ClearInterrupt(void); +#endif +/* below register definination is used for Silicon Image SiI164 DVI controller chip */ +/* + * Vendor ID registers + */ +#define SII164_VENDOR_ID_LOW 0x00 +#define SII164_VENDOR_ID_HIGH 0x01 + +/* + * Device ID registers + */ +#define SII164_DEVICE_ID_LOW 0x02 +#define SII164_DEVICE_ID_HIGH 0x03 + +/* + * Device Revision + */ +#define SII164_DEVICE_REVISION 0x04 + +/* + * Frequency Limitation registers + */ +#define SII164_FREQUENCY_LIMIT_LOW 0x06 +#define SII164_FREQUENCY_LIMIT_HIGH 0x07 + +/* + * Power Down and Input Signal Configuration registers + */ +#define SII164_CONFIGURATION 0x08 + +/* Power down (PD) */ +#define SII164_CONFIGURATION_POWER_DOWN 0x00 +#define SII164_CONFIGURATION_POWER_NORMAL 0x01 +#define SII164_CONFIGURATION_POWER_MASK 0x01 + +/* Input Edge Latch Select (EDGE) */ +#define SII164_CONFIGURATION_LATCH_FALLING 0x00 +#define SII164_CONFIGURATION_LATCH_RISING 0x02 + +/* Bus Select (BSEL) */ +#define SII164_CONFIGURATION_BUS_12BITS 0x00 +#define SII164_CONFIGURATION_BUS_24BITS 0x04 + +/* Dual Edge Clock Select (DSEL) */ +#define SII164_CONFIGURATION_CLOCK_SINGLE 0x00 +#define SII164_CONFIGURATION_CLOCK_DUAL 0x08 + +/* Horizontal Sync Enable (HEN) */ +#define SII164_CONFIGURATION_HSYNC_FORCE_LOW 0x00 +#define SII164_CONFIGURATION_HSYNC_AS_IS 0x10 + +/* Vertical Sync Enable (VEN) */ +#define SII164_CONFIGURATION_VSYNC_FORCE_LOW 0x00 +#define SII164_CONFIGURATION_VSYNC_AS_IS 0x20 + +/* + * Detection registers + */ +#define SII164_DETECT 0x09 + +/* Monitor Detect Interrupt (MDI) */ +#define SII164_DETECT_MONITOR_STATE_CHANGE 0x00 +#define SII164_DETECT_MONITOR_STATE_NO_CHANGE 0x01 +#define SII164_DETECT_MONITOR_STATE_CLEAR 0x01 +#define SII164_DETECT_MONITOR_STATE_MASK 0x01 + +/* Hot Plug detect Input (HTPLG) */ +#define SII164_DETECT_HOT_PLUG_STATUS_OFF 0x00 +#define SII164_DETECT_HOT_PLUG_STATUS_ON 0x02 +#define SII164_DETECT_HOT_PLUG_STATUS_MASK 0x02 + +/* Receiver Sense (RSEN) */ +#define SII164_DETECT_RECEIVER_SENSE_NOT_DETECTED 0x00 +#define SII164_DETECT_RECEIVER_SENSE_DETECTED 0x04 + +/* Interrupt Generation Method (TSEL) */ +#define SII164_DETECT_INTERRUPT_BY_RSEN_PIN 0x00 +#define SII164_DETECT_INTERRUPT_BY_HTPLG_PIN 0x08 +#define SII164_DETECT_INTERRUPT_MASK 0x08 + +/* Monitor Sense Output (MSEN) */ +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH 0x00 +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI 0x10 +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN 0x20 +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG 0x30 +#define SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG 0x30 + +/* + * Skewing registers + */ +#define SII164_DESKEW 0x0A + +/* General Purpose Input (CTL[3:1]) */ +#define SII164_DESKEW_GENERAL_PURPOSE_INPUT_MASK 0x0E + +/* De-skewing Enable bit (DKEN) */ +#define SII164_DESKEW_DISABLE 0x00 +#define SII164_DESKEW_ENABLE 0x10 + +/* De-skewing Setting (DK[3:1])*/ +#define SII164_DESKEW_1_STEP 0x00 +#define SII164_DESKEW_2_STEP 0x20 +#define SII164_DESKEW_3_STEP 0x40 +#define SII164_DESKEW_4_STEP 0x60 +#define SII164_DESKEW_5_STEP 0x80 +#define SII164_DESKEW_6_STEP 0xA0 +#define SII164_DESKEW_7_STEP 0xC0 +#define SII164_DESKEW_8_STEP 0xE0 + +/* + * User Configuration Data registers (CFG 7:0) + */ +#define SII164_USER_CONFIGURATION 0x0B + +/* + * PLL registers + */ +#define SII164_PLL 0x0C + +/* PLL Filter Value (PLLF) */ +#define SII164_PLL_FILTER_VALUE_MASK 0x0E + +/* PLL Filter Enable (PFEN) */ +#define SII164_PLL_FILTER_DISABLE 0x00 +#define SII164_PLL_FILTER_ENABLE 0x01 + +/* Sync Continuous (SCNT) */ +#define SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE 0x00 +#define SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE 0x80 + +#endif diff --git a/src/ddk750/ddk750_swi2c.c b/src/ddk750/ddk750_swi2c.c new file mode 100644 index 0000000..7001349 --- /dev/null +++ b/src/ddk750/ddk750_swi2c.c @@ -0,0 +1,592 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* swi2c.c --- SM750/SM718 DDK +* This file contains the source code for I2C using software +* implementation. +* +*******************************************************************/ +#include "../smi_common.h" +#include "ddk750_help.h" +#include "ddk750_reg.h" +#include "ddk750_swi2c.h" +#include "ddk750_power.h" + + +/******************************************************************* + * I2C Software Master Driver: + * =========================== + * Each i2c cycle is split into 4 sections. Each of these section marks + * a point in time where the SCL or SDA may be changed. + * + * 1 Cycle == | Section I. | Section 2. | Section 3. | Section 4. | + * +-------------+-------------+-------------+-------------+ + * | SCL set LOW |SCL no change| SCL set HIGH|SCL no change| + * + * ____________ _____________ + * SCL == XXXX _____________ ____________ / + * + * I.e. the SCL may only be changed in section 1. and section 3. while + * the SDA may only be changed in section 2. and section 4. The table + * below gives the changes for these 2 lines in the varios sections. + * + * Section changes Table: + * ====================== + * blank = no change, L = set bit LOW, H = set bit HIGH + * + * | 1.| 2.| 3.| 4.| + * ---------------+---+---+---+---+ + * Tx Start SDA | | H | | L | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * Tx Stop SDA | | L | | H | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * Tx bit H SDA | | H | | | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * Tx bit L SDA | | L | | | + * SCL | L | | H | | + * ---------------+---+---+---+---+ + * + ******************************************************************/ + +/* GPIO pins used for this I2C. It ranges from 0 to 63. */ +static unsigned char g_i2cClockGPIO = DEFAULT_I2C_SCL; +static unsigned char g_i2cDataGPIO = DEFAULT_I2C_SDA; + +/* + * Below is the variable declaration for the GPIO pin register usage + * for the i2c Clock and i2c Data. + * + * Note: + * Notice that the GPIO usage for the i2c clock and i2c Data are + * separated. This is to make this code flexible enough when + * two separate GPIO pins for the clock and data are located + * in two different GPIO register set (worst case). + */ + +/* i2c Clock GPIO Register usage */ +static unsigned long g_i2cClkGPIOMuxReg = GPIO_MUX; +static unsigned long g_i2cClkGPIODataReg = GPIO_DATA; +static unsigned long g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION; + +/* i2c Data GPIO Register usage */ +static unsigned long g_i2cDataGPIOMuxReg = GPIO_MUX; +static unsigned long g_i2cDataGPIODataReg = GPIO_DATA; +static unsigned long g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION; + +#if 0 +static unsigned long SM750_IO_Base = 0; +_X_EXPORT void ddk750_setIOBase(unsigned long address) +{ + SM750_IO_Base = address; +} +#endif +/* + * This function puts a delay between command + */ +static void swI2CWait(void) +{ + /* find a bug: + * peekIO method works well before suspend/resume + * but after suspend, peekIO(0x3ce,0x61) & 0x10 + * always be non-zero,which makes the while loop + * never finish. + * use non-ultimate for loop below is safe + * */ +#if 0 + /* Change wait algorithm to use PCI bus clock, + it's more reliable than counter loop .. + write 0x61 to 0x3ce and read from 0x3cf + */ + while(inb(SM750_IO_Base + 0x61) & 0x10); +#else + int i, Temp; + + for(i=0; i<600; i++) + { + Temp = i; + Temp += i; + } +#endif +} + +/* + * This function set/reset the SCL GPIO pin + * + * Parameters: + * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + * + * Notes: + * When setting SCL to high, just set the GPIO as input where the pull up + * resistor will pull the signal up. Do not use software to pull up the + * signal because the i2c will fail when other device try to drive the + * signal due to SM50x will drive the signal to always high. + */ +void swI2CSCL(unsigned char value) +{ + uint32_t ulGPIOData; + uint32_t ulGPIODirection; + + ulGPIODirection = PEEK32(g_i2cClkGPIODataDirReg); + if (value) /* High */ + { + /* Set direction as input. This will automatically pull the signal up. */ + ulGPIODirection &= ~(1 << g_i2cClockGPIO); + POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection); + } + else /* Low */ + { + /* Set the signal down */ + ulGPIOData = PEEK32(g_i2cClkGPIODataReg); + ulGPIOData &= ~(1 << g_i2cClockGPIO); + POKE32(g_i2cClkGPIODataReg, ulGPIOData); + + /* Set direction as output */ + ulGPIODirection |= (1 << g_i2cClockGPIO); + POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection); + } +} + +/* + * This function set/reset the SDA GPIO pin + * + * Parameters: + * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + * + * Notes: + * When setting SCL to high, just set the GPIO as input where the pull up + * resistor will pull the signal up. Do not use software to pull up the + * signal because the i2c will fail when other device try to drive the + * signal due to SM50x will drive the signal to always high. + */ +void swI2CSDA(unsigned char value) +{ + uint32_t ulGPIOData; + uint32_t ulGPIODirection; + + ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg); + if (value) /* High */ + { + /* Set direction as input. This will automatically pull the signal up. */ + ulGPIODirection &= ~(1 << g_i2cDataGPIO); + POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection); + } + else /* Low */ + { + /* Set the signal down */ + ulGPIOData = PEEK32(g_i2cDataGPIODataReg); + ulGPIOData &= ~(1 << g_i2cDataGPIO); + POKE32(g_i2cDataGPIODataReg, ulGPIOData); + + /* Set direction as output */ + ulGPIODirection |= (1 << g_i2cDataGPIO); + POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection); + } +} +/* + * This function read the data from the SDA GPIO pin + * + * Return Value: + * The SDA data bit sent by the Slave + */ +static unsigned char swI2CReadSDA() +{ + uint32_t ulGPIODirection; + uint32_t ulGPIOData; + + /* Make sure that the direction is input (High) */ + ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg); + if ((ulGPIODirection & (1 << g_i2cDataGPIO)) != (~(1 << g_i2cDataGPIO))) + { + ulGPIODirection &= ~(1 << g_i2cDataGPIO); + POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection); + } + + /* Now read the SDA line */ + ulGPIOData = PEEK32(g_i2cDataGPIODataReg); + if (ulGPIOData & (1 << g_i2cDataGPIO)) + return 1; + else + return 0; +} + +static unsigned char swI2CReadSCL() +{ + uint32_t ulGPIODirection; + uint32_t ulGPIOData; + + /* Make sure that the direction is input (High) */ + ulGPIODirection = PEEK32(g_i2cClkGPIODataDirReg); + if ((ulGPIODirection & (1 << g_i2cClockGPIO)) != (~(1 << g_i2cClockGPIO))) + { + ulGPIODirection &= ~(1 << g_i2cClockGPIO); + POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection); + } + + /* Now read the SDA line */ + ulGPIOData = PEEK32(g_i2cClkGPIODataReg); + if (ulGPIOData & (1 << g_i2cClockGPIO)) + return 1; + else + return 0; +} + +#pragma optimize( "", off ) + +/* + * This function sends ACK signal + */ +static void swI2CAck(void) +{ + return; /* Single byte read is ok without it. */ +} + +/* + * This function sends the start command to the slave device + */ +void swI2CStart(void) +{ + /* Start I2C */ + swI2CSDA(1); + swI2CSCL(1); + swI2CSDA(0); +} + +/* + * This function sends the stop command to the slave device + */ +void swI2CStop() +{ + /* Stop the I2C */ + swI2CSCL(1); + swI2CSDA(0); + swI2CSDA(1); +} + +/* + * This function writes one byte to the slave device + * + * Parameters: + * data - Data to be write to the slave device + * + * Return Value: + * 0 - Success + * -1 - Fail to write byte + */ +long swI2CWriteByte(unsigned char data) +{ + unsigned char value = data; + int i; + + /* Sending the data bit by bit */ + for (i=0; i<8; i++) + { + /* Set SCL to low */ + swI2CSCL(0); + + /* Send data bit */ + if ((value & 0x80) != 0) + swI2CSDA(1); + else + swI2CSDA(0); + + swI2CWait(); + + /* Toggle clk line to one */ + swI2CSCL(1); + swI2CWait(); + + /* Shift byte to be sent */ + value = value << 1; + } + + /* Set the SCL Low and SDA High (prepare to get input) */ + swI2CSCL(0); + swI2CSDA(1); + + /* Set the SCL High for ack */ + swI2CWait(); + swI2CSCL(1); + swI2CWait(); + + /* Read SDA, until SDA==0 */ + for(i=0; i<0xff; i++) + { + if (!swI2CReadSDA()) + break; + + swI2CSCL(0); + swI2CWait(); + swI2CSCL(1); + swI2CWait(); + } + + /* Set the SCL Low and SDA High */ + swI2CSCL(0); + swI2CSDA(1); + + if (i<0xff) + return 0; + else + return (-1); +} + +/* + * This function reads one byte from the slave device + * + * Parameters: + * ack - Flag to indicate either to send the acknowledge + * message to the slave device or not + * + * Return Value: + * One byte data read from the Slave device + */ +unsigned char swI2CReadByte(unsigned char ack) +{ + int i; + unsigned char data = 0; + + for(i=7; i>=0; i--) + { + /* Set the SCL to Low and SDA to High (Input) */ + swI2CSCL(0); + swI2CSDA(1); + swI2CWait(); + + /* Set the SCL High */ + swI2CSCL(1); + swI2CWait(); + + /* Read data bits from SDA */ + data |= (swI2CReadSDA() << i); + } + + if (ack) + swI2CAck(); + + /* Set the SCL Low and SDA High */ + swI2CSCL(0); + swI2CSDA(1); + + return data; +} +#pragma optimize( "", on ) + +/* + * This function initializes GPIO port for SW I2C communication. + * + * Parameters: + * i2cClkGPIO - The GPIO pin to be used as i2c SCL + * i2cDataGPIO - The GPIO pin to be used as i2c SDA + * + * Return Value: + * -1 - Fail to initialize the i2c + * 0 - Success + */ +long swI2CInit_SM750LE( + unsigned char i2cClkGPIO, + unsigned char i2cDataGPIO +) +{ + int i; + + /* Initialize the GPIO pin for the i2c Clock Register */ + g_i2cClkGPIODataReg = GPIO_DATA_SM750LE; + g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE; + + /* Initialize the Clock GPIO Offset */ + g_i2cClockGPIO = i2cClkGPIO; + + /* Initialize the GPIO pin for the i2c Data Register */ + g_i2cDataGPIODataReg = GPIO_DATA_SM750LE; + g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE; + + /* Initialize the Data GPIO Offset */ + g_i2cDataGPIO = i2cDataGPIO; + + /* Note that SM750LE don't have GPIO MUX and power is always on */ + + /* Clear the i2c lines. */ + for(i=0; i<9; i++) + swI2CStop(); + + return 0; +} + +/* + * This function initializes the i2c attributes and bus + * + * Parameters: + * i2cClkGPIO - The GPIO pin to be used as i2c SCL + * i2cDataGPIO - The GPIO pin to be used as i2c SDA + * + * Return Value: + * -1 - Fail to initialize the i2c + * 0 - Success + */ +_X_EXPORT long swI2CInit( + unsigned char i2cClkGPIO, + unsigned char i2cDataGPIO +) +{ + int i; + + /* Return 0 if the GPIO pins to be used is out of range. The range is only from [0..63] */ + if ((i2cClkGPIO > 31) || (i2cDataGPIO > 31)) + return (-1); + + if (getChipType() == SM750LE) + return( swI2CInit_SM750LE(i2cClkGPIO, i2cDataGPIO) ); + + /* Initialize the GPIO pin for the i2c Clock Register */ + g_i2cClkGPIOMuxReg = GPIO_MUX; + g_i2cClkGPIODataReg = GPIO_DATA; + g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION; + + /* Initialize the Clock GPIO Offset */ + g_i2cClockGPIO = i2cClkGPIO; + + /* Initialize the GPIO pin for the i2c Data Register */ + g_i2cDataGPIOMuxReg = GPIO_MUX; + g_i2cDataGPIODataReg = GPIO_DATA; + g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION; + + /* Initialize the Data GPIO Offset */ + g_i2cDataGPIO = i2cDataGPIO; + + /* Enable the GPIO pins for the i2c Clock and Data (GPIO MUX) */ + POKE32(g_i2cClkGPIOMuxReg, + PEEK32(g_i2cClkGPIOMuxReg) & ~(1 << g_i2cClockGPIO)); + POKE32(g_i2cDataGPIOMuxReg, + PEEK32(g_i2cDataGPIOMuxReg) & ~(1 << g_i2cDataGPIO)); + + /* Enable GPIO power */ + enableGPIO(1); + + /* Clear the i2c lines. */ + for(i=0; i<9; i++) + swI2CStop(); + + return 0; +} + +/* + * This function reads the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be read from + * registerIndex - Slave device's register to be read + * + * Return Value: + * Register value + */ +unsigned char swI2CReadReg( + unsigned char deviceAddress, + unsigned char registerIndex +) +{ + unsigned char data; + + /* Send the Start signal */ + swI2CStart(); + + /* Send the device address */ + swI2CWriteByte(deviceAddress); + + /* Send the register index */ + swI2CWriteByte(registerIndex); + + /* Get the bus again and get the data from the device read address */ + swI2CStart(); + swI2CWriteByte(deviceAddress + 1); + data = swI2CReadByte(1); + + /* Stop swI2C and release the bus */ + swI2CStop(); + + return data; +} + +/* + * This function writes a value to the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be written + * registerIndex - Slave device's register to be written + * data - Data to be written to the register + * + * Result: + * 0 - Success + * -1 - Fail + */ +long swI2CWriteReg( + unsigned char deviceAddress, + unsigned char registerIndex, + unsigned char data +) +{ + long returnValue = 0; + + /* Send the Start signal */ + swI2CStart(); + + /* Send the device address and read the data. All should return success + in order for the writing processed to be successful + */ + if ((swI2CWriteByte(deviceAddress) != 0) || + (swI2CWriteByte(registerIndex) != 0) || + (swI2CWriteByte(data) != 0)) + { + returnValue = -1; + } + + /* Stop i2c and release the bus */ + swI2CStop(); + + return returnValue; +} +int __wait(void) +{ + int i=0,j=0; + while(i++<1000){ + j+=i; + } + return j; +} + +_X_EXPORT void ddk750_I2CPutBits_panel(I2CBusPtr bus,int clock,int data) +{ + swI2CSCL(clock); + swI2CSDA(data); + __wait(); +} + +_X_EXPORT void ddk750_I2CGetBits_panel(I2CBusPtr bus,int* clock,int* data) +{ + *data = swI2CReadSDA(); + *clock = swI2CReadSCL(); + __wait(); +} + +_X_EXPORT void ddk750_I2CPutBits_crt(I2CBusPtr bus,int clock,int data) +{ + swI2CSCL(clock); + swI2CSDA(data); + __wait(); +} + +_X_EXPORT void ddk750_I2CGetBits_crt(I2CBusPtr bus,int* clock,int* data) +{ + *data = swI2CReadSDA(); + *clock = swI2CReadSCL(); + __wait(); +} + diff --git a/src/ddk750/ddk750_swi2c.h b/src/ddk750/ddk750_swi2c.h new file mode 100644 index 0000000..9266dd6 --- /dev/null +++ b/src/ddk750/ddk750_swi2c.h @@ -0,0 +1,98 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* swi2c.h --- SM750/SM718 DDK +* This file contains the definitions for i2c using software +* implementation. +* +*******************************************************************/ +#ifndef _SWI2C_H_ +#define _SWI2C_H_ + +/* Default i2c CLK and Data GPIO. These are the default i2c pins */ +#define DEFAULT_I2C_SCL 30 +#define DEFAULT_I2C_SDA 31 + +/* + * This function initializes the i2c attributes and bus + * + * Parameters: + * i2cClkGPIO - The GPIO pin to be used as i2c SCL + * i2cDataGPIO - The GPIO pin to be used as i2c SDA + * + * Return Value: + * -1 - Fail to initialize the i2c + * 0 - Success + */ +long swI2CInit( + unsigned char i2cClkGPIO, + unsigned char i2cDataGPIO +); + +/* + * This function reads the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be read from + * registerIndex - Slave device's register to be read + * + * Return Value: + * Register value + */ +unsigned char swI2CReadReg( + unsigned char deviceAddress, + unsigned char registerIndex +); + +/* + * This function writes a value to the slave device's register + * + * Parameters: + * deviceAddress - i2c Slave device address which register + * to be written + * registerIndex - Slave device's register to be written + * data - Data to be written to the register + * + * Result: + * 0 - Success + * -1 - Fail + */ +long swI2CWriteReg( + unsigned char deviceAddress, + unsigned char registerIndex, + unsigned char data +); + +/* + * These two functions are used to toggle the data on the SCL and SDA I2C lines. + * The used of these two functions are not recommended unless it is necessary. + */ + +/* + * This function set/reset the SCL GPIO pin + * + * Parameters: + * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + */ +static void swI2CSCL(unsigned char value); + +/* + * This function set/reset the SDA GPIO pin + * + * Parameters: + * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) + */ +static void swI2CSDA(unsigned char value); +static unsigned char swI2CReadSCL(); +static unsigned char swI2CReadSDA(); +_X_EXPORT long swI2CInit(unsigned char i2cClkGPIO, unsigned char i2cDataGPIO); +_X_EXPORT void ddk750_I2CPutBits_panel(I2CBusPtr bus,int clock,int data); +_X_EXPORT void ddk750_I2CGetBits_panel(I2CBusPtr bus,int* clock,int* data); +_X_EXPORT void ddk750_I2CPutBits_crt(I2CBusPtr bus,int clock,int data); +_X_EXPORT void ddk750_I2CGetBits_crt(I2CBusPtr bus,int* clock,int* data); +#endif /* _SWI2C_H_ */ diff --git a/src/ddk750/version.h b/src/ddk750/version.h new file mode 100644 index 0000000..c9ddb9c --- /dev/null +++ b/src/ddk750/version.h @@ -0,0 +1,25 @@ +/******************************************************************* +* +* Copyright (c) 2007 by Silicon Motion, Inc. (SMI) +* +* All rights are reserved. Reproduction or in part is prohibited +* without the written consent of the copyright owner. +* +* VERSION.H --- SMI DDK +* This file contains the source code for the mode table. +* +*******************************************************************/ +#ifndef _VERSION_H_ +#define _VERSION_H_ + +#define LIBRARY_VERSION 0x00000006 +#define MAJOR_VERSION(v) (v >> 16) +#define MINOR_VERSION(v) (v & 0x0000ffff) +#if XORG_VERSION_CURRENT < 10706000 +uint32_t getLibVersion(void) +{ + return(LIBRARY_VERSION); +} +#endif +#endif /* _VERSION_H_ */ + diff --git a/src/drv502/smi_502_crtc.c b/src/drv502/smi_502_crtc.c new file mode 100644 index 0000000..997ae2a --- /dev/null +++ b/src/drv502/smi_502_crtc.c @@ -0,0 +1,729 @@ +/* + alphaEnableDisplay(1); + alphaEnableDisplay(1); + alphaEnableDisplay(1); + alphaEnableDisplay(1); + alphaEnableDisplay(1); + alphaEnableDisplay(1); + alphaEnableDisplay(1); + alphaEnableDisplay(1); + alphaEnableDisplay(1); + alphaEnableDisplay(1); + alphaEnableDisplay(1); +Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. +Copyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. +Copyright (C) 2008 Mandriva Linux. All Rights Reserved. +Copyright (C) 2008 Francisco Jerez. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- +NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of The XFree86 Project and +Silicon Motion shall not be used in advertising or otherwise to promote the +sale, use or other dealings in this Software without prior written +authorization from The XFree86 Project or Silicon Motion. +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "../smi_common.h" +#include "../smi_driver.h" +#include "../smi_dbg.h" +#include "../smi_crtc.h" +#include "../smi_output.h" +#include "smi_502_driver.h" +#include "ddk502/ddk502_regdc.h" +#include "ddk502/ddk502_display.h" +#include "ddk502/ddk502_help.h" + +#if SMI_RANDR + +static uint sm502g_HWCOffset[]={PANEL_HWC_ADDRESS,CRT_HWC_ADDRESS}; +static Bool sm502g_argb_saved = FALSE; + +#if 0 +static void SMI502init_argb_cursor(SMIPtr pSmi) +{ + if(!pSmi->entityPrivate->alphaOkay) + { + alphaInit(0,0,SMI501_MAX_CURSOR,SMI501_MAX_CURSOR, + pSmi->fb_argbCursorOffset,0,SMI501_MAX_CURSOR * 2, + ALPHA_FORMAT_ARGB_4444,0,0,0); + +//memset(pSmi->FBBase + pSmi->fbMapOffset+ pSmi->FBReserved, 0,(SMI501_CURSOR_SIZE + SMI502_ARGB_CURSOR_SIZE)*2); + pSmi->entityPrivate->alphaOkay = 1; + } +} + +#endif +/* + 502 Alpha layer is not flexiable as cursor layer + cursor layer can handle negetive position + alpha layer must do some stupid data copy to accomplish negetive potion effect ... + Monk @ 2009-12-31 +*/ + +static void SMI502_ARGB_SetCursorPosition(xf86CrtcPtr crtc, int x, int y) +{ + +#define ALPHA_BPP 2 +#define PITCH (SMI501_MAX_CURSOR * ALPHA_BPP) +//#define SMI501_ARGB_CURSOR_SIZE (SMI501_MAX_CURSOR * SMI501_MAX_CURSOR * 2) + + static Bool moved = FALSE; + int deltaX,deltaY; + int X,Y,v,h; + + uint reg1,reg2; + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMI502_Ptr pSmi502 = (SMI502_Ptr)pSmi; + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + deltaX = deltaY = 0; + + char * dst = pSmi->pFB + pSmi502->fb_argbCursorOffset; + char * src = pSmi->pFB + pSmi502->fb_argbCursorOffset - SMI501_ARGB_CURSOR_SIZE; + +#if 0 + XMSG("X = %d, Y = %d \n",x,y); +#endif + + if(x < 0){ + X = 0;deltaX = (-x) * ALPHA_BPP; + }else{ + X = x; + } + + if(y < 0){ + Y = 0;deltaY = (-y)*PITCH; + }else{ + Y = y; + } + + + alphaEnableDisplay(0); + + //POKE32(ALPHA_FB_WIDTH,FIELD_VALUE(PEEK32(ALPHA_FB_WIDTH),ALPHA_FB_WIDTH,WIDTH,PITCH - deltaX)); + + if(x < 0) + { + /* see if we need backup original cursor data first,copy ^dst ^ to ^src^ */ + if(!sm502g_argb_saved){ + memcpy(src,dst,SMI501_ARGB_CURSOR_SIZE); + sm502g_argb_saved = TRUE; + } + + /* only move alpha data could make it , because of alpha layer address 16 byte align requirement */ + for(v = deltaY;v < (SMI501_MAX_CURSOR * PITCH);v += PITCH) + { +#if 0 + for(h = 0;h<(PITCH - deltaX);h++) + *(dst + v + h) = *(src + v + deltaX + h); +#else + memcpy(dst+v,src+v+deltaX,PITCH-deltaX); +#endif + moved = TRUE; + } + } + else + { + if(moved == TRUE){ + /* need original cusor data come back */ + memcpy(dst,src,SMI501_ARGB_CURSOR_SIZE); + moved = FALSE; + } + } + + if(y < 0){ + ddk502_POKE32(ALPHA_FB_ADDRESS, + FIELD_VALUE(ddk502_PEEK32(ALPHA_FB_ADDRESS),ALPHA_FB_ADDRESS,ADDRESS,pSmi502->fb_argbCursorOffset + deltaY)); + }else{ + ddk502_POKE32(ALPHA_FB_ADDRESS, + FIELD_VALUE(ddk502_PEEK32(ALPHA_FB_ADDRESS),ALPHA_FB_ADDRESS,ADDRESS,pSmi502->fb_argbCursorOffset)); + } + + reg1 = (X & 0xffff)|(Y << 16); + reg2 = (x + SMI501_MAX_CURSOR - 1)|((y + SMI501_MAX_CURSOR - 1)<<16); + + ddk502_POKE32(ALPHA_PLANE_TL,reg1); + ddk502_POKE32(ALPHA_PLANE_BR,reg2); + alphaEnableDisplay(1); +// memset(pSmi->FBBase + pSmi->FBReserved,0xff,(SMI501_CURSOR_SIZE + SMI502_ARGB_CURSOR_SIZE)*2); +#undef PITCH + +} + +static void SMI502_ARGB_ShowCursor(xf86CrtcPtr crtc) +{ + alphaEnableDisplay(1); +// sm502_do_ARGB_showCursor(1); +} + + +static void SMI502_ARGB_HideCursor(xf86CrtcPtr crtc) +{ + alphaEnableDisplay(0); +// sm502_do_ARGB_showCursor(0); +} + +static void SMI502_ARGB_LOADARGB(xf86CrtcPtr crtc,CARD32* src) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMI502_Ptr pSmi502 = (SMI502_Ptr)pSmi; + uint add; + int i; + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + + //static uint cnt = 0; + //XERR("cnt = %08x \n",cnt++); + //ENTER(); + + + if(crtcPriv->controller!=0){ + return; + } + +// if(crtc->cursor_argb != TRUE) +// crtc->cursor_argb = TRUE; + + +#if 0 + /* copy cursor data to onscreen */ + { + char * fb = pSmi->FBBase; + int cnt,i,pitch; + cnt = SMI502_MAX_CURSOR * 4; + pitch = pScrn->displayWidth * pSmi->Bpp; + fb+=pitch/2; + for(i=0;irotation = %d:\n",crtc->rotation); + XMSG("crtc->desiredRotation = %d:\n",crtc->desiredRotation); + if(crtc->randr_crtc!=NULL) + XMSG("crtc->randr_crtc->rotation = %d:\n",crtc->randr_crtc->rotation); +#endif + + +#if 0 + for(i=0;i<(SMI501_ARGB_CURSOR_SIZE)/4;i+=4) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "MONK :src[%d] = %08x src[%d] = %08x, src[%d] = %08x, src[%d] = %08x\n", + i,src[i],i+1,src[i+1],i+2,src[i+2],i+3,src[i+3]); +#endif + uint argb; + unsigned short * addr = (unsigned short *)(pSmi->pFB + pSmi502->fb_argbCursorOffset); + //unsigned short * addr_bk = (unsigned short *)((unsigned long)addr - SMI502_ARGB_CURSOR_SIZE); +#if 1 + for(i=0;i> 16; + argb |= (src[i] & 0xf00000) >> 12; + argb |= (src[i] & 0xf000) >> 8; + argb |= (src[i] & 0xf0) >> 4; + addr[i] = (unsigned short)argb; + //addr_bk[i] = argb; + } + + add = pSmi502->fb_argbCursorOffset; + ddk502_POKE32(ALPHA_FB_ADDRESS,add); + + /* tell argb_set_position routine that cursor data updated ,need redraw backup data */ + sm502g_argb_saved = FALSE; +#endif + + //LEAVE(); +} + + +static void SMI502_SetCursorColors(xf86CrtcPtr crtc,int bg,int fg) +{ + //translate rgb888 color into rg 565 + //use hwc color 3 as bg and color 2 as fg + //X use 1 for fg and 0 for bg so set 502 hw color 2 with bg and color 3 with fg +#define RBIT 0xf80000 +#define GBIT 0xfc00 +#define BBIT 0xf8 +#define COLOR_24_16(X) (((X & RBIT) >> 8)|((X & GBIT) >> 5)|((X & BBIT) >>3)) + + + + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + uint regadd,regval; + uint hwcolor2,hwcolor3; + + ENTER(); + hwcolor2 = sm502g_HWCOffset[crtcPriv->controller] + 8; + hwcolor3 = sm502g_HWCOffset[crtcPriv->controller] + 0xc; + + //XMSG("bg = %08x,fg = %08x\n",bg,fg); + + regval = COLOR_24_16(bg)<<16; + ddk502_POKE32(hwcolor2,regval); + + regval = COLOR_24_16(fg); + ddk502_POKE32(hwcolor3,regval); + + LEAVE(); +#undef COLOR_24_16 +#undef RBIT +#undef GBIT +#undef BBIT + +} + +inline static void sm502_do_showCursor(SMIPtr pSmi,int channel,int onoff) +{ + uint regadd; + uint offset; + SMI502_Ptr pSmi502 = (SMI502_Ptr)pSmi; + ENTER(); + + regadd = sm502g_HWCOffset[channel]; + offset = (channel == 0)?pSmi502->fb_priCursorOffset:pSmi502->fb_secCursorOffset; + if(onoff) + ddk502_POKE32(regadd,offset|0x80000000); + else + ddk502_POKE32(regadd,0); + + LEAVE(); +} + + +/* + 502 cursor layer is smarter , it can handle negetive potion both for X and Y + just set outside bit and make potion multiplus -1 will reach it + Monk @ 2009-12-31 +*/ +static void SMI502_SetCursorPosition(xf86CrtcPtr crtc,int x,int y) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + uint regadd,regvalue; + + XMSG("Set %s position to %d,%d\n",crtcPriv->controller?"CRT":"PANEL",x,y); + + regadd = sm502g_HWCOffset[crtcPriv->controller] + 4; + regvalue = FIELD_VALUE(0,PANEL_HWC_LOCATION,TOP,y<0?1:0)| + FIELD_VALUE(0,PANEL_HWC_LOCATION,Y,y<0?-y:y)| + FIELD_VALUE(0,PANEL_HWC_LOCATION,LEFT,x<0?1:0)| + FIELD_VALUE(0,PANEL_HWC_LOCATION,X,x<0?-x:x); + + ddk502_POKE32(regadd,regvalue); +} + + +static void SMI502_CrtcShowCursor(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + sm502_do_showCursor(pSmi,crtcPriv->controller,1); +} + + +static void SMI502_CrtcHideCursor(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + sm502_do_showCursor(pSmi,crtcPriv->controller,0); +} + +static void SMI502_CrtcLoadCursorImage(xf86CrtcPtr crtc, CARD8* image) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMI502_Ptr pSmi502 = (SMI502_Ptr)pSmi; + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + uint regadd,regvalue; + + ENTER(); + + regadd = sm502g_HWCOffset[crtcPriv->controller]; + regvalue = (crtcPriv->controller == 0)?pSmi502->fb_priCursorOffset:pSmi502->fb_secCursorOffset; + ddk502_POKE32(regadd,regvalue); + memcpy(pSmi->pFB + regvalue,image,SMI501_CURSOR_SIZE); + + LEAVE(); +} + + + +#if 1 +static void +SMI502_CrtcAdjustFrame(xf86CrtcPtr crtc, int x, int y) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + ENTER(); + + CARD32 Base; + CARD32 Pitch; + CARD32 regval; + + XMSG("Davidprint crtc is crt = %d\n", crtcPriv->controller); + XMSG("Davidprintcrtc x is = %d\n", x); + XMSG("Davidprintcrtc y is = %d\n", y); + XMSG("Davidprintcrtc->rotatedData%d\n" , crtc->rotatedData); + XMSG("DavidprintpScrn->displayWidth%d\n", pScrn->displayWidth); + + + + Pitch = pScrn->displayWidth * pSmi->Bpp; + if(crtc->rotatedData){ + Base = (char*)crtc->rotatedData - (char*)pSmi->pFB; + Pitch = crtcPriv->shadow_pitch; + }else{ + Base = pSmi->FBOffset + (x + y * pScrn->displayWidth) * pSmi->Bpp; + } + //Base = 0; + XMSG("Base = %d\n" , Base); + XMSG( "Pitch = %d\n" , Pitch); + + + /* adjust base address and pitch */ + if(crtcPriv->controller == 0){ + WRITE_SCR(pHw,PANEL_FB_ADDRESS,Base); + regval = FIELD_VALUE(0,PANEL_FB_WIDTH,OFFSET,Pitch)| + FIELD_VALUE(0,PANEL_FB_WIDTH,WIDTH,Pitch); + WRITE_SCR(pHw,PANEL_FB_WIDTH,regval); + xf86DrvMsg(pScrn->scrnIndex,X_ERROR,": In %s\n",__func__); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Pitch: %x,%x \n",Pitch,regval); + }else{ + WRITE_SCR(pHw,CRT_FB_ADDRESS,Base); + regval = READ_SCR(pHw,CRT_FB_WIDTH); + regval = FIELD_VALUE(regval,CRT_FB_WIDTH,OFFSET,Pitch); + WRITE_SCR(pHw,CRT_FB_WIDTH,regval); + } + +#if 0 + if(crtc->rotatedData) + { + RRCrtcPtr rcrtc = crtc->randr_crtc; + xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"MONK : In %s",__func__); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : rotatedData != NULL \n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "crtc->desiredRotation= %d \n",crtc->desiredRotation); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "crtc->x,y == %d,%d \n",crtc->x,crtc->y); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "crtc->desiredX,desiredY == %d,%d \n", + crtc->desiredX,crtc->desiredY); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "crtc->randr_crtc->x,y == %d,%d \n",rcrtc->x,rcrtc->y); + } + +#endif + LEAVE(); +} +#else +static void +SMI502_CrtcAdjustFrame(xf86CrtcPtr crtc, int x, int y) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); + // MSOCRegPtr mode = pSmi->mode; + CARD32 Base; + + ENTER(); + + if(crtc->rotatedData) + Base = (char*)crtc->rotatedData - (char*)pSmi->FBBase; + else + Base = pSmi->FBOffset + (x + y * pScrn->displayWidth) * pSmi->Bpp; + + Base = (Base + 15) & ~15; + + if (crtc == crtcConf->crtc[0]) { + mode->panel_fb_address.f.address = Base >> 4; + mode->panel_fb_address.f.pending = 1; + WRITE_SCR(pSmi, PANEL_FB_ADDRESS, mode->panel_fb_address.value); + } + else { + mode->crt_display_ctl.f.pixel = ((x * pSmi->Bpp) & 15) / pSmi->Bpp; + WRITE_SCR(pSmi, CRT_DISPLAY_CTL, mode->crt_display_ctl.value); + mode->crt_fb_address.f.address = Base >> 4; + mode->crt_fb_address.f.mselect = 0; + mode->crt_fb_address.f.pending = 1; + WRITE_SCR(pSmi, CRT_FB_ADDRESS, mode->crt_fb_address.value); + } + + LEAVE(); +} +#endif + +static void +SMI502_CrtcModeSet(xf86CrtcPtr crtc, + DisplayModePtr xf86mode, + DisplayModePtr adjusted_mode, + int x, int y) +{ + ScrnInfoPtr pScrn; + SMIPtr pSmi; + SMICrtcPrivatePtr crtcPriv; + logicalMode_t Mode; + + ENTER(); + + pScrn = crtc->scrn; + pSmi = SMIPTR(pScrn); + crtcPriv = SMICRTC(crtc); + + pSmi->dispCtrl = PANEL; + if(crtcPriv->controller == 1) + pSmi->dispCtrl = CRT; + +#if 0 + Mode.dispCtrl = PANEL_CTRL; + Mode.xLCD = x; + Mode.yLCD = y; + Mode.pitch = 0; + Mode.baseAddress = 0; + Mode.virtual = 0; + Mode.userData = NULL; + if(crtcPriv->controller == 1) + { + Mode.dispCtrl = CRT_CTRL; + } + if(Mode.xLCD * Mode.yLCD != 0){ + /* expansion mode, only 60 hz is valid */ + Mode.hz = 60; + }else{ + /* no expansion */ + Mode.hz = (uint32_t)(((xf86mode->VRefresh!=0) ? xf86mode->VRefresh : adjusted_mode->VRefresh) + 0.5); + } + + Mode.x = xf86mode->HDisplay; + Mode.y = xf86mode->VDisplay; + Mode.bpp = pScrn->bitsPerPixel; + + if(crtc->desiredRotation && crtc->rotatedData) + Mode.baseAddress = ((FBLinearPtr)crtcPriv->shadowArea)->offset * pSmi->Bpp; + else + Mode.baseAddress = pSmi->FBOffset + (x + y * pScrn->displayWidth) * pSmi->Bpp; + + + + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : In %s \n",__func__); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : mode.dispCtrl = %d \n",Mode.dispCtrl); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : CRTC->desiredRotation= %d \n",crtc->desiredRotation); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : mode.LCD = %dx%d \n",Mode.xLCD,Mode.yLCD); + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : pScrn->virtual[X,Y] == %d,%d \n",pScrn->virtualX,pScrn->virtualY); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : pScrn->displayWidth == %d\n",pScrn->displayWidth); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : position x,y== %d,%d \n",x,y); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : Mode = [%d x %d]@%d hz\n",Mode.x,Mode.y,Mode.hz); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : xf86mode->VRefresh = %f\n",xf86mode->VRefresh); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : adjusted_mode->VRefresh = %f\n",adjusted_mode->VRefresh); +#endif + +#if 1 + /* if mode.hz == 71~76, we set it to 75 + if(Mode.hz > 70 && Mode.hz < 77) + Mode.hz = 75;*/ +#else + XMSG("member of DisplayModePtr \n"); + XMSG("DisplayModePtr->Clock = %d\n",xf86mode->Clock); + XMSG("DisplayModePtr->HSync = %f\n",xf86mode->HSync); + XMSG("DisplayModePtr->VRefresh = %f\n",xf86mode->VRefresh); + + + XMSG("DisplayModePtr->HDisplay = %d\n",xf86mode->HDisplay); + XMSG("DisplayModePtr->HSyncStart = %d\n",xf86mode->HSyncStart); + XMSG("DisplayModePtr->HSyncEnd = %d\n",xf86mode->HSyncEnd); + XMSG("DisplayModePtr->HTotal = %d\n",xf86mode->HTotal); + XMSG("DisplayModePtr->HSkew = %d\n",xf86mode->HSkew); + + XMSG("DisplayModePtr->VDisplay = %d\n",xf86mode->VDisplay); + XMSG("DisplayModePtr->VSyncStart = %d\n",xf86mode->VSyncStart); + XMSG("DisplayModePtr->VSyncEnd = %d\n",xf86mode->VSyncEnd); + XMSG("DisplayModePtr->VTotal = %d\n",xf86mode->VTotal); + XMSG("DisplayModePtr->VScan = %d\n",xf86mode->VScan); + +#ifndef SMI_EDID_ENTIRE + if(setMode(&Mode) == -1) + { + XMSG("Failed on setModeEx\n"); + /* the request mode can not be set by DDK ,directly set the mode */ + if(xorg_setMode(&Mode,adjusted_mode)) + { + XMSG("Failed on xorg_setMode\n"); + } + } +#else + if(Mode.xLCD && Mode.yLCD){ + /* expansion needed ,we use setModeEx */ + if(setMode(&Mode) == -1) + { + XERR("Opps,seems DDK setmode failed \n"); + if(xorg_setMode(&Mode,adjusted_mode)) + { + XMSG("Failed on xorg_setMode\n"); + } + } + + }else{ + /* common mode set requirment ,just use common routine */ + if(xorg_setMode(&Mode,adjusted_mode)) + XERR("Opps,seems xorg_setMode failed\n"); + } +#endif +#endif + pSmi->psSetMode(pScrn,xf86mode); + SMI502_CrtcAdjustFrame(crtc, x, y); + + + LEAVE(); +} + + +static Bool +SMI502_CrtcLock (xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + + ENTER(); + + /*deWaitForNotBusy();*/ + + LEAVE(FALSE); +} + + + +static void +SMI502_CrtcLoadLUT(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + + ENTER(); + + + LEAVE(); +} + + +/* + * Implementation + */ +static void +SMI502_CrtcVideoInit_lcd(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + ENTER(); + + + + LEAVE(); +} + + +Bool +SMI502_CrtcPreInit(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR(pScrn); + xf86CrtcPtr crtc; + xf86CrtcFuncsPtr crtcFuncs; + SMICrtcPrivatePtr crtcPriv; + SMIHWPtr pHw = pSmi->pHardware; + + ENTER(); + + int idx = 0; + int c = (pSmi->DualView?2:1); + Bool expansion = (pSmi->lcdWidth>0 && pSmi->lcdHeight> 0); + SMI_CrtcPreInit(pScrn); + while(idx < c) + { + crtcFuncs = NULL; + crtcPriv = NULL; + if(! SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv)) + LEAVE(FALSE); + + + crtcFuncs->mode_set = SMI502_CrtcModeSet; + crtcFuncs->lock = SMI502_CrtcLock; + + crtcPriv->adjust_frame = SMI502_CrtcAdjustFrame; + crtcPriv->video_init = SMI502_CrtcVideoInit_lcd; + crtcPriv->load_lut = SMI502_CrtcLoadLUT; + crtcPriv->index = idx; + +#if 0 + if(expansion && pSmi->DualView) + crtcPriv->controller = (idx+1)&1; + else if(expansion) + crtcPriv->controller = 1; + else + crtcPriv->controller = idx; +#else + if(expansion){ + /* if expansion enabled, than primary channel will be put into crtc_1 and secondary be crtc_0 + This limitation need be take care + */ + crtcPriv->controller = (idx+1)&1; + }else{ + crtcPriv->controller = idx; + } +#endif + + if(pSmi->ARGBCursor && pSmi->DualView) + { + crtcFuncs->set_cursor_position = SMI502_ARGB_SetCursorPosition; + crtcFuncs->show_cursor = SMI502_ARGB_ShowCursor; + crtcFuncs->hide_cursor = SMI502_ARGB_HideCursor; + crtcFuncs->load_cursor_argb = SMI502_ARGB_LOADARGB; + //init_argb_cursor(pSmi); + } + else if (pSmi->HwCursor) + { + crtcFuncs->set_cursor_colors = SMI502_SetCursorColors; + crtcFuncs->set_cursor_position = SMI502_SetCursorPosition; + crtcFuncs->show_cursor = SMI502_CrtcShowCursor; + crtcFuncs->hide_cursor = SMI502_CrtcHideCursor; + crtcFuncs->load_cursor_image = SMI502_CrtcLoadCursorImage; + } + + if (! (crtc = xf86CrtcCreate(pScrn, crtcFuncs))) + LEAVE(FALSE); + + crtc->driver_private = crtcPriv; + idx++; + } + + LEAVE(TRUE); +} + + +#endif /*#if SMI_RANDR*/ diff --git a/src/drv502/smi_502_driver.c b/src/drv502/smi_502_driver.c new file mode 100644 index 0000000..8e2d3b8 --- /dev/null +++ b/src/drv502/smi_502_driver.c @@ -0,0 +1,813 @@ +/* + Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. + Copyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- + NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of The XFree86 Project and + Silicon Motion shall not be used in advertising or otherwise to promote the + sale, use or other dealings in this Software without prior written + authorization from The XFree86 Project or Silicon Motion. + */ + + +#include "../smi_common.h" +#include "../smi_driver.h" +#include "smi_502_driver.h" +#include "smi_502_hw.h" +#include "../smi_dbg.h" +#include "ddk502/ddk502_regsc.h" +#include "ddk502/ddk502_chip.h" + +/* static functions */ +static Bool smi_setdepbpp_502(ScrnInfoPtr pScrn); +static Bool smi_set_dualhead_502(ScrnInfoPtr pScrn, SMI502_Ptr pSmi); +static Bool smi_setvideomem_502(int config, ScrnInfoPtr pScrn, SMI502_Ptr pSmi); +static mode_table_t * findMode_502 (mode_table_t * mode_table, INT width, + INT height, INT refresh_rate); + +static void SMI502_EnableVideo (ScrnInfoPtr pScrn); +static int SMI502_InternalScreenInit (int scrnIndex, ScreenPtr pScreen); +static void SMI502_EntityInit(int entityIndex,pointer private); + +void (*pfn_I2CPutBits_502[])(I2CBusPtr,int,int)= +{NULL,NULL}; + +void (*pfn_I2CGetBits_502[])(I2CBusPtr,int*,int*)= +{NULL,NULL}; + + + +/* Global Vars */ + +static const SMI502HWRec sm502_hwrec = { + .base = { + .pcDeepMap = sm502_pcDeepmap,/* actually,NULL value can be just ignored,gcc will know it*/ + .pcEntityInit = sm502_entityInit, + .pcEntityEnter = sm502_entityEnter, + .pcEntityLeave = sm502_entityLeave, + .pcCloseAllScreen = sm502_closeAllScreen, + .pcFBSize = sm502_totalFB, + .pcInitHardware = NULL, + }, + +}; + + +static const SMI502_Rec sm502_rec = { + .base = { + .minHeight = 128, + .psGetMapResult = sm502_getMapResult, + .psVgaPciInit = sm502_vgaAndpciInit, + .psHandleOptions = sm502_handleOptions, + .psValidMode = sm502_validMode, + .psSetMode = sm502_setMode, + .psAdjustFrame = sm502_adjustFrame, + .psLoadPalette = sm502_LoadPalette, + .psSetDisplay = sm502_setDisplay, + .psSaveText = sm502_saveText, + #if SMI_RANDR + .psCrtcPreInit = SMI502_CrtcPreInit, + .psOutputPreInit = SMI502_OutputPreInit, + .psI2CInit = sm502_I2CInit, + #endif + }, +}; + +SMIPtr sm502_genSMI(pointer priv,int entityIndex) +{ + SMIPtr pSmi; +#ifdef XSERVER_LIBPCIACCESS + struct pci_device * pPci; +#else + pciVideoPtr pPci; +#endif + + ENTER(); +#ifdef XSERVER_LIBPCIACCESS + pPci = xf86GetPciInfoForEntity(entityIndex); +#endif + + pSmi = (SMIPtr)XNFcalloc(sizeof(SMI502_Rec)); + memset(pSmi,0, sizeof(SMI502_Rec)); + if(pSmi == NULL) + return pSmi; + + memcpy(pSmi,&sm502_rec,sizeof(SMI502_Rec)); + /*This function is associated with screen + , but maybe two screen belongs to one entity (dualview)*/ + pSmi->pHardware = priv; + + /* if priv is NULL,means we need create a pHw + * below code can handle 2 screen per entity case + * but not work for 3+ screen per entity cases + * */ + if(!pSmi->pHardware) + { + /* + * Allocate an 'Chip'Rec, and hook it into pScrn->driverPrivate. + * pScrn->driverPrivate is initialised to NULL, so we can check if + * the allocation has already been done. + */ + SMI502HWPtr p502Hw; + p502Hw = pSmi->pHardware = (SMIHWPtr)XNFcalloc(sizeof(SMI502HWRec)); + if(pSmi->pHardware == NULL) + LEAVE(NULL); + memcpy(pSmi->pHardware,&sm502_hwrec,sizeof(SMI502HWRec)); + + p502Hw->pRegSave = xnfcalloc(sizeof(SMI502_RegRec),1); + if(p502Hw->pRegSave == NULL) + LEAVE(NULL); +#if 0 + p502Hw->fonts = xalloc(KB(64)); + if(p502Hw->fonts == NULL) + LEAVE(NULL); +#endif + + pSmi->pHardware->dual = 1; + pSmi->pHardware->primary_screen_rec = pSmi; + pSmi->screen = 0; + /////////////////////////// + //ilena:how???? copy from 750. not sure... + #ifdef XSERVER_LIBPCIACCESS + pSmi->pHardware->phyaddr_reg = pPci->regions[1].base_addr; + pSmi->pHardware->physize_reg = 0x200000; + pSmi->pHardware->phyaddr_mem = pPci->regions[0].base_addr; + //pSmi->pHardware->physize_mem = pPci->regions[0].size; + /*Get total video memory size from misc ccontrol register MMIO_base+0x0004 bit13 and bit12*/ + //pSmi->pHardware->physize_mem = ddk502_getFrameBufSize(); + + pSmi->pHardware->devId = pPci->device_id; + #else + pSmi->pHardware->phyaddr_reg = pPci->memBase[1]; + pSmi->pHardware->physize_reg = 0x200000; + pSmi->pHardware->phyaddr_mem = pPci->memBase[0]; + /*Get total video memory size from misc ccontrol register MMIO_base+0x0004 bit13 and bit12*/ + //pSmi->pHardware->physize_mem = pPci->size[0]; + //pSmi->pHardware->physize_mem = ddk502_getFrameBufSize(); + pSmi->pHardware->devId = pPci->device; + #endif + + #ifdef XSERVER_LIBPCIACCESS + pSmi->pHardware->revId = pPci->revision; + pSmi->pHardware->pPci = pPci; + #else + pSmi->pHardware->revId = pPci->chipRev; + pSmi->pHardware->pPci = pPci; + #endif + ///////////////////////// + }else{ + /* + * pSmi->pHardware is not NULL, which means current entity already + * mallocated a SMIHWPtr structure,so we are in dualview + * mode! + * */ + pSmi->pHardware->dual += 1;/*The total number of screen*/ + pSmi->screen = (pSmi->pHardware->dual)-1;/*The index of screen*/ + } + LEAVE(pSmi); +} +/* + * === FUNCTION ====================================================================== + * Name: sm502_pcDeepmap + * Description: + * ===================================================================================== + */ +void sm502_pcDeepmap(SMIHWPtr pHw) +{ + ENTER(); + + ddk502_set_mmio(pHw->pReg,pHw->devId,0xC0); + + SMI502HWPtr p502Hw = (SMI502HWPtr)pHw; + SMIPtr pSmi = HWPSMI(pHw); + ScrnInfoPtr pScrn = SMIPSI(pSmi); + pHw->DPRBase = pHw->pReg + 0x100000; + pHw->VPRBase = pHw->pReg + 0x000000; + pHw->CPRBase = pHw->pReg + 0x090000; + pHw->DCRBase = pHw->pReg + 0x080000; + pHw->SCRBase = pHw->pReg + 0x000000; + pHw->IOBase = 0; + pHw->DataPortBase = pHw->pReg + 0x110000; + pHw->DataPortSize = 0x10000; + LEAVE(TRUE); +} +void sm502_vgaAndpciInit(ScrnInfoPtr pScrn,int entityIndex) +{ + ENTER(); + + LEAVE(); + +} + +void sm502_entityInit(int entityIndex,pointer private) +{ + ENTER(); + + struct pci_device * pd; + EntityInfoPtr pEnt; + //ilena: sth have been moved to entityinit_common. + pd = xf86GetPciInfoForEntity(entityIndex); + pEnt = xf86GetEntityInfo (entityIndex); + pci_device_probe(pd);// this line only used for 502. + xfree(pEnt); + + ddk502_initHw(); + + LEAVE(); +} + +/* + * === FUNCTION ====================================================================== + * Name: sm502_entityEnter + * Description: save console's registers + * ===================================================================================== + */ +void sm502_entityEnter(int entIndex,pointer private) +{ + ENTER(); + ddk502_initHw(); + LEAVE(); +} + +/* + * === FUNCTION ====================================================================== + * Name: sm502_entityLeave + * Description: restore console's registers + * ===================================================================================== + */ +void sm502_entityLeave(int entIndex,pointer private) +{ + ENTER(); + + /* Restore the registers */ + //restore_reg_502((SMIHWPtr)private); + //save_reg_502((SMIHWPtr)private); + + LEAVE(); +} + +void sm502_saveText(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR (pScrn); + + ENTER(); + /* This functin called from entity init, + Of course, it is the primary screen */ + if(xf86IsPrimaryPci(pSmi->pHardware->pPci)) + { + /* Save the vga fonts */ + //sm750_saveFonts(pSmi->pHardware); + /* Save the registers */ + //save_reg_502(pSmi->pHardware); + } + LEAVE(); +} + +void sm502_getMapResult(ScrnInfoPtr pScrn) +{ + vgaHWPtr hwp; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + ENTER(); + + /* set video memory size */ + pSmi->videoRAMBytes = pHw->physize_mem / (pSmi->pHardware->dual); + pScrn->videoRam = (pSmi->videoRAMBytes)>>10;/* kbytes*/ + + /* set pScrn physica address*/ +#if 1 + pScrn->memPhysBase = pHw->phyaddr_mem; + pScrn->memPhysBase += (pSmi->screen) * pSmi->videoRAMBytes; +#else + pScrn->memPhysBase = 0; +#endif + + /* set OFFSET */// delete tmp by ilena + pScrn->fbOffset = pSmi->FBOffset = pScrn->memPhysBase - pHw->phyaddr_mem; + + /* monk:below is wrong,pScrn->memPhysBase should not pretend the + * physica address of video memory,but the offset of the videomemory + * of onscreen! So just set to 0 is okay ! + * */ + if (!pSmi->screen) + //pSmi->fbMapOffset = 0x0; + pSmi->FBOffset = 0x0; + else + //pSmi->fbMapOffset = pScrn->videoRam * 1024; + pSmi->FBOffset = pScrn->videoRam * 1024; + + /* set virtual address */ + pSmi->pFB = pHw->pMem; + pSmi->pFB += (pSmi->screen) * pSmi->videoRAMBytes; + + //pSmi->FBCursorOffset = pSmi->base.videoRAMBytes - 2048; + pSmi->FBReserved = pSmi->videoRAMBytes - 4096; + +#if 0 //ilena: why dont we use this? + if (pSmi->IsLCD) { + pSmi->lcd = 1; + } +#endif + + if (!pSmi->width) + pSmi->width = pScrn->displayWidth; + if (!pSmi->height) + pSmi->height = pScrn->virtualY; + //ilena:seems moved from modeInit + pSmi->Bpp = pScrn->bitsPerPixel / 8; + pSmi->Stride = (pSmi->width * pSmi->Bpp + 15) & ~15; +#if 0 + /* Mapping vga*/ + /* Assign hwp->MemBase & IOBase here */ + hwp = VGAHWPTR (pScrn); + //vgaHWGetIOBase(hwp); //vga fun was not init when no ioport platform + /* Map the VGA memory when the primary video */ + hwp->MapSize = 0x10000;// ilena: not sure about the size + if (!vgaHWMapMem (pScrn)) + { + LEAVE(FALSE); + } +#endif + + LEAVE(TRUE); + +} + +void sm502_handleOptions(ScrnInfoPtr pScrn) +{ + SMI502_Ptr pSmi; + pSmi = SMI502_PTR (pScrn); + MessageType from;// i'm not sure that we need this. + if (pScrn->depth == 8) + { + pScrn->rgbBits = 8; + } + #if 1 // maybe will use it in handleoption func. + /* + if no HWCursor option defined in xorg.conf ,then software cursor will + be used by default + */ + pSmi->hwcursor = FALSE; + if (xf86GetOptValBool (pSmi->base.Options, OPTION_HWCURSOR, &pSmi->hwcursor)){ + from = X_CONFIG; + } +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,5,1,0,0) + if(pScrn->scrnIndex != 0) + { + if(pScrn->depth != xf86Screens[0]->depth) + { + /* for X server 1.51+ , use ugly hardware cursor for + * none-primary screen or system will hang kind of X server bug + */ + pSmi->hwcursor = TRUE; + } + } +#endif + xf86DrvMsg (pScrn->scrnIndex, from, "Using %s Cursor\n", + pSmi->hwcursor ? "Hardware" : "Software"); + + if (xf86GetOptValInteger (pSmi->base.Options, OPTION_VIDEOKEY, &pSmi->videoKey)) + { + xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "Option: Video key set to " + "0x%08X\n", pSmi->videoKey); + } + else + { + /* should not use pScrn->offset now,because screenInit will + * modify their value,the videoKey will be set in ScreenInit after + * the pScrn->offset modified + * */ + } + + if (xf86ReturnOptValBool (pSmi->base.Options, OPTION_BYTESWAP, FALSE)) + { + pSmi->ByteSwap = TRUE; + xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "Option: ByteSwap enabled.\n"); + } + else + { + pSmi->ByteSwap = FALSE; + } +#endif + +} + +void sm502_adjustFrame(ScrnInfoPtr pScrn, int offset) +//void SMI502_AdjustFrame (int scrnIndex, int x, int y, int flags) +{ + return 0;// ilena:how to re-write it? +/* ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + SMI502_Ptr pSmi = SMI502_PTR (pScrn); + CARD32 Base; + + if (pSmi->ShowCache && y) + { + y += pScrn->virtualY - 1; + } + + xf86DrvMsg("", X_INFO, "pSmi->FBOffset is 0x%x, x is %d, y is %d\n", + pSmi->FBOffset, x, y); + Base = pSmi->FBOffset + (x + y * pScrn->displayWidth) * pSmi->Bpp; + + if (!pSmi->IsSecondary)//ilena: to dual + { + WRITE_DCR (pSmi, DCR0C, Base); + } + else + { + WRITE_DCR (pSmi, DCR204, Base); + }*/ +} + +void sm502_closeAllScreen(SMIHWPtr pHw) +{ + ENTER(); + SMI502HWPtr p502Hw = (SMI502HWPtr)pHw; + + if(p502Hw->pRegSave) + { + xf86Msg(X_INFO,"Close Screen Free saved reg\n"); + xfree(p502Hw->pRegSave); + p502Hw->pRegSave = NULL; + } +#if 0 + if(p502Hw->fonts) + { + xf86Msg(X_INFO,"Close Screen Free saved fonts\n"); + xfree(p502Hw->fonts); + p502Hw->fonts = NULL; + } +#endif + xfree(p502Hw); + LEAVE(); +} + +ModeStatus sm502_validMode(ScrnInfoPtr pScrn,DisplayModePtr pMode) +{ + ENTER(); + LEAVE (MODE_OK); +} + +void sm502_setMode(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + ENTER(); + SMIPtr pSmi = SMIPTR (pScrn); + unsigned int tmpData, tmpReg; + unsigned long dataLength; + logicalMode_t LogicalMode; + LogicalMode.x= mode->HDisplay; + LogicalMode.y =mode->VDisplay; + LogicalMode.bpp= pScrn->depth; + + LogicalMode.baseAddress = pSmi->FBOffset; + LogicalMode.pitch=(pSmi->width * pSmi->Bpp + 15) & ~15;/*Dont use pSmi->Stride, it had been changed in accel.c*/ + LogicalMode.virtual= 0; + LogicalMode.xLCD=pSmi->width; + LogicalMode.yLCD=pSmi->height; + +#if SMI_RANDR + if(pSmi->lcdWidth * pSmi->lcdHeight != 0){ + /* expansion mode, only 60 hz is valid */ + LogicalMode.hz = 60; + }else{ + /* no expansion */ + /*LogicalMode.hz = (uint32_t)(((mode->VRefresh!=0) ? mode->VRefresh : adjusted_mode->VRefresh) + 0.5); */ + /*Above sentence is more compatible, but hard code is a simple select + Because the adjusted_mode->VRefresh = 60.0038414 */ + LogicalMode.hz = 60; + } + if (pSmi->dispCtrl == PANEL) + { + LogicalMode.dispCtrl=PANEL_CTRL; + ddk502_setModeTiming(&LogicalMode); + tmpReg = DCR00; + } + else if (pSmi->dispCtrl == CRT) + { + LogicalMode.dispCtrl=CRT_CTRL; + ddk502_setModeTiming(&LogicalMode); + tmpReg = DCR200; + } +#else + if (!pSmi->screen) + { + LogicalMode.hz = 60; + LogicalMode.dispCtrl=PANEL_CTRL; + ddk502_setModeTiming(&LogicalMode); + tmpReg = DCR00; + } + else + { + LogicalMode.hz = (int) (mode->VRefresh + 0.5); + LogicalMode.dispCtrl=CRT_CTRL; + ddk502_setModeTiming(&LogicalMode); + tmpReg = DCR200; + } +#endif + /*ilena: open 2D engine CLOCK Control. enable it so that 2d could work*/ + unsigned long dwVal = ddk502_PEEK32(POWER_MODE0_GATE); + dwVal = FIELD_SET(dwVal, POWER_MODE0_GATE, 2D, ENABLE); + ddk502_POKE32(POWER_MODE0_GATE,dwVal); + + /* Jason 2010/09/21 + Set registers according to modeline sync polarity */ + SMIHWPtr pHw = pSmi->pHardware; + if (mode->Flags & V_PHSYNC) { + tmpData = READ_DCR(pHw, tmpReg); + WRITE_DCR(pHw, tmpReg, (tmpData & 0xFFFFEFFF)); + } + if (mode->Flags & V_NHSYNC){ + tmpData = READ_DCR(pHw, tmpReg); + WRITE_DCR(pHw, tmpReg, (tmpData | 0x00001000)); + } + if (mode->Flags & V_PVSYNC){ + tmpData = READ_DCR(pHw, tmpReg); + WRITE_DCR(pHw, tmpReg, (tmpData & 0xFFFFDFFF)); + } + if (mode->Flags & V_NVSYNC) { + tmpData = READ_DCR(pHw, tmpReg); + WRITE_DCR(pHw, tmpReg, (tmpData | 0x00002000)); + } + + LEAVE (); +} + +void sm502_setDisplay(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + int pitch; + int bpp = pScrn->bitsPerPixel; + SMIPtr pSmi = SMIPTR (pScrn); + + display_t channel; + +#if SMI_RANDR + if (pSmi->dispCtrl == PANEL) + channel = PANEL; + else if (pSmi->dispCtrl == CRT) + channel = CRT; +#else + if(pSmi->IsPrimary) + channel = PANEL; + else + channel = CRT; +#endif + /* + * Pitch value calculation in Bytes. + * Usually, it is (screen width) * (byte per pixel). + * However, there are cases that screen width is not 16 pixel aligned, which is + * a requirement for some OS and the hardware itself. + * For standard 4:3 resolutions: 320, 640, 800, 1024 and 1280, they are all + * 16 pixel aligned and pitch is simply (screen width) * (byte per pixel). + * + * However, 1366 resolution, for example, has to be adjusted for 16 pixel aligned. + */ + /* "+ 15) & ~15)" This calculation has no effect on 640, 800, 1024 and 1280. */ + pitch = ((pSmi->width+ 15) & ~15) * (bpp / 8); + + set_display_502(pSmi->pHardware, channel, bpp, pitch); +} + + +static int SMI502_InternalScreenInit (int scrnIndex, ScreenPtr pScreen) +{ +#if 0 + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SMI502_Ptr pSmi = SMI502_PTR (pScrn); + int width, height, displayWidth; + int bytesPerPixel = pScrn->bitsPerPixel / 8; + int xDpi, yDpi; + int ret; + + ENTER(); + + if (pSmi->rotate && pSmi->rotate != SMI_ROTATE_UD) + { + width = pScrn->virtualY; + height = pScrn->virtualX; + xDpi = pScrn->yDpi; + yDpi = pScrn->xDpi; + displayWidth = ((width * bytesPerPixel + 15) & ~15) / bytesPerPixel; + } + else + { + width = pScrn->virtualX; + height = pScrn->virtualY; + xDpi = pScrn->xDpi; + yDpi = pScrn->yDpi; + displayWidth = pScrn->displayWidth; + } + if (pSmi->shadowFB) + { + pSmi->ShadowWidth = width; + pSmi->ShadowHeight = height; + pSmi->ShadowWidthBytes = ((width + 15) & ~15) * bytesPerPixel; + if (bytesPerPixel == 3) + { + if(pSmi->rotate == SMI_ROTATE_CW || pSmi->rotate == SMI_ROTATE_CCW) + { + pSmi->ShadowPitch = ((height * 3) << 16) | + pSmi->ShadowWidthBytes; + } + else + { + pSmi->ShadowPitch = ((width * 3) << 16) | + pSmi->ShadowWidthBytes; + } + } + else + { + if(pSmi->rotate == SMI_ROTATE_CW || pSmi->rotate == SMI_ROTATE_CCW) + { + pSmi->ShadowPitch = (((height + 15) & ~15)<< 16) | + (pSmi->ShadowWidthBytes / bytesPerPixel); + } + else + { + pSmi->ShadowPitch = (((width + 15) & ~15)<< 16) | + (pSmi->ShadowWidthBytes / bytesPerPixel); + } + } + pSmi->saveBufferSize = pSmi->ShadowWidthBytes * pSmi->ShadowHeight; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "line %d: pSmi->FBReserved is 0x%x\n", + __LINE__, pSmi->base.FBReserved); + pSmi->base.FBReserved -= pSmi->saveBufferSize; + pSmi->base.FBReserved &= ~0x15; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "line %d: pSmi->FBReserved is 0x%x\n", + __LINE__, pSmi->base.FBReserved); + WRITE_VPR (pSmi, 0x0C, (pSmi->base.FBOffset = pSmi->base.FBReserved) >> 3); + xf86DrvMsg("", X_INFO, + "pSmi->SCRBase is 0x%x, DCRBase is 0x%x, \ + FBOffset is 0x%x\n", + pSmi->SCRBase, pSmi->DCRBase, pSmi->base.FBOffset); + if (!pSmi->base.screen) { + WRITE_DCR (pSmi, DCR0C, pSmi->base.FBOffset); + } else { + WRITE_DCR (pSmi, DCR204, pSmi->base.FBOffset); + } + pScrn->fbOffset = pSmi->base.FBOffset + pSmi->base.FBOffset;//fbMapoffset + xf86DrvMsg (pScrn->scrnIndex, X_INFO, "Shadow: width=%d height=%d " + "offset=0x%08X pitch=0x%08X\n", pSmi->ShadowWidth, + pSmi->ShadowHeight, pSmi->base.FBOffset, pSmi->ShadowPitch); + xf86DrvMsg("", X_INFO, + "line %d: Internalxxx: fbOffset = 0x%x\n", + __LINE__, pScrn->fbOffset); + } + else { + xf86DrvMsg("", X_INFO, "line %d: Internalxxx: fbOffset = 0x%x, \ + FBOffset is 0x%x\n", + __LINE__, pScrn->fbOffset, pSmi->base.FBOffset); + } + /* + * Call the framebuffer layer's ScreenInit function, and fill in other + * pScreen fields. + */ + DEBUG ("\tInitializing FB @ 0x%08X for %dx%d (%d)\n", + pSmi->base.pFB, width, height, displayWidth); + switch (pScrn->bitsPerPixel) + { + /* #ifdef USE_FB*/ + case 8: + case 16: + case 24: + case 32: + {// by ilena: i dont think it should be keeped + ret = fbScreenInit (pScreen, pSmi->base.pFB, width, height, xDpi, + yDpi, displayWidth, pScrn->bitsPerPixel); + } + break; + default: + xf86DrvMsg (scrnIndex, X_ERROR, "Internal error: invalid bpp (%d) " + "in SMI_InternalScreenInit\n", pScrn->bitsPerPixel); + LEAVE (FALSE); + } + if(pScrn->bitsPerPixel == 8) + { + /* Initialize Palette entries 0 and 1, they don't seem to get hit */ + if (!pSmi->base.screen) + { + WRITE_DCR (pSmi, DCR400 + 0, 0x00000000); /* CRT Palette */ + WRITE_DCR (pSmi, DCR400 + 4, 0x00FFFFFF); /* CRT Palette */ + } + else + { + WRITE_DCR (pSmi, DCR800 + 0, 0x00000000); /* Panel Palette */ + WRITE_DCR (pSmi, DCR800 + 4, 0x00FFFFFF); /* Panel Palette */ + } + } + LEAVE (ret); +#endif +} + +void sm502_LoadPalette (ScrnInfoPtr pScrn, int numColors, int *indicies, + LOCO * colors, VisualPtr pVisual) +{ + ENTER(); + SMIPtr pSmi = SMIPTR (pScrn); + SMIHWPtr pHw = pSmi->pHardware; + int i; + int iRGB; + + /* Enable both the CRT and LCD DAC RAM paths, + so both palettes are updated */ + for (i = 0; i < numColors; i++) + { + DEBUG ("pal[%d] = %d %d %d\n", indicies[i], + colors[indicies[i]].red, colors[indicies[i]].green, + colors[indicies[i]].blue); + + iRGB = (colors[indicies[i]].red << 16) | + (colors[indicies[i]].green << 8) | (colors[indicies[i]].blue); + + if (pSmi->screen) + { + /* CRT Palette */ + WRITE_DCR (pHw, DCR400 + (4 * (indicies[i])), iRGB); + } + else + /* Panel Palette */ + WRITE_DCR (pHw, DCR800 + (4 * (indicies[i])), iRGB); + } + LEAVE(); +} + +int sm502_totalFB(SMIHWPtr pHw) +{ + ENTER(); + + LEAVE( ddk502_getFrameBufSize()); +} +#if SMI_RANDR +void sm502_I2CInit(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + int cnt = pSmi->DualView?2:1; + int index; + I2CBusPtr ptr[2] = {NULL,NULL}; + static char * sm502_name[] = {"I2C Bus PanelPath","I2C Bus CrtPath"}; + ENTER(); + + pfn_I2CPutBits_502[0] = i2c_putbits_panel_502; + pfn_I2CPutBits_502[1] = i2c_putbits_crt_502; + pfn_I2CGetBits_502[0] = i2c_getbits_panel_502; + pfn_I2CGetBits_502[1] = i2c_getbits_crt_502; + + index= 0 ; + while(index < cnt) + { + if(ptr[index] == NULL ) + { + I2CBusPtr I2CPtr = xf86CreateI2CBusRec(); + if (I2CPtr == NULL) + return FALSE; + + I2CPtr->scrnIndex = pScrn->scrnIndex; + I2CPtr->BusName = sm502_name[index]; + I2CPtr->I2CPutBits = pfn_I2CPutBits_502[index]; + I2CPtr->I2CGetBits = pfn_I2CGetBits_502[index]; + + + I2CPtr->DriverPrivate.ptr = (void *)xalloc(sizeof(int)); + + if (!xf86I2CBusInit(I2CPtr)){ + xfree(I2CPtr->DriverPrivate.ptr); + xf86DestroyI2CBusRec(I2CPtr, TRUE, TRUE); + LEAVE(FALSE); + } + + ptr[index] = I2CPtr; + /* for sm712: 0 means CRT HEAD i2c bus + for sm750: 0 means PANEL HEAD i2c bus, + note that head is not pll + */ + *((int *)I2CPtr->DriverPrivate.ptr) = index; + } + index++; + } + + pSmi->I2C_primary = ptr[0]; + pSmi->I2C_secondary = ptr[1]; + + init_i2c_502(pHw); + + LEAVE(TRUE); +} +#endif diff --git a/src/drv502/smi_502_driver.h b/src/drv502/smi_502_driver.h new file mode 100644 index 0000000..8c97e71 --- /dev/null +++ b/src/drv502/smi_502_driver.h @@ -0,0 +1,379 @@ + +/* Header: //Mercury/Projects/archives/XFree86/4.0/smi.h-arc 1.51 29 Nov 2000 17:45:16 Frido $ */ + +/* + Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. + Copyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- + NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the XFree86 Project and + Silicon Motion shall not be used in advertising or otherwise to promote the + sale, use or other dealings in this Software without prior written + authorization from the XFree86 Project and Silicon Motion. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi.h,v 1.13 2003/04/23 21:51:44 tsi Exp $ */ + +#ifndef SMI_502_INC +#define SMI_502_INC +#include "../smi_common.h" +#include "smi_502_hw.h" +#include "ddk502/ddk502_mode.h" + +SMIPtr sm502_genSMI(pointer priv,int); + +#define REG_SYS_HEAD_502 0x0 +#define REG_SYS_TAIL_502 0x74 +#define REG_PNL_HEAD_502 0x80000 +#define REG_PNL_TAIL_502 0x80034 +#define REG_VID_HEAD_502 0x80040 +#define REG_VID_TAIL_502 0x80068 +#define REG_PCUR_HEAD_502 0x800f0 +#define REG_PCUR_TAIL_502 0x800fc +#define REG_CRT_HEAD_502 0x80200 +#define REG_CRT_TAIL_502 0x80224 +#define REG_CCUR_HEAD_502 0x80230 +#define REG_CCUR_TAIL_502 0x8023c + +/* Maximum hardware cursor dimensions */ +#define SMI501_MAX_CURSOR 64 +#define SMI501_CURSOR_SIZE 1024 + +#define SMI502_CURSOR_ALPHA_PLANE 0 +#if SMI502_CURSOR_ALPHA_PLANE +/* Stored in either 4:4:4:4 or 5:6:5 format */ +# define SMI501_ARGB_CURSOR_SIZE \ + (SMI501_MAX_CURSOR * SMI501_MAX_CURSOR * 2) +#else +#define SMI501_ARGB_CURSOR_SIZE 0 +#endif + +/* Driver data structure; this should contain all needed info for a mode */ +typedef struct +{ + Bool modeInit; + CARD16 mode; + + CARD32 System[(REG_SYS_TAIL_502 - REG_SYS_HEAD_502)/4+1]; //0x00 -- 0x74 + CARD32 PanelControl[(REG_PNL_TAIL_502 - REG_PNL_HEAD_502)/4 +1]; //0x80000 -- 0x80034 + CARD32 VIDEOControl[(REG_VID_TAIL_502 - REG_VID_HEAD_502)/4+1]; //0x80040 -- 0x80068 + CARD32 PanelCursorControl[(REG_PCUR_TAIL_502 - REG_PCUR_HEAD_502)/4+1]; + CARD32 CRTControl[(REG_CRT_TAIL_502 - REG_CRT_HEAD_502)/4 + 1]; //0x80200 -- 0x802284 + CARD32 CRTCursorControl[(REG_CCUR_TAIL_502 - REG_CCUR_HEAD_502)/4+1]; + + /* entity information */ + Bool DualHead; + ScrnInfoPtr pSecondaryScrn; + ScrnInfoPtr pPrimaryScrn; + int lastInstance; + + /* shared resource */ + int mmio_require; + volatile unsigned char * MMIOBase; /* Base of MMIO */ + int MapSize; /* how many mmio should map and unmap */ + int total_videoRam; /* memory count in bytes */ +}SMI502_RegRec,*SMI502_RegPtr; + + +typedef struct { + /* put common structure here */ + SMIHWRec base; + /* put chip dependent stuffs here*/ + SMI502_RegPtr pRegSave; + /* vga stuffs */ + //char * fonts; +}SMI502HWRec,*SMI502HWPtr; + + + +typedef struct { + /* we best put base in header of structure*/ + SMIRec base; + + /* chip dependent stuffs of this pSmi*/ + CARD32 AccelCmd; /* Value for DPR0C */ + + CARD32 ScissorsLeft; /* Left/top of current + scissors */ + CARD32 ScissorsRight; /* Right/bottom of current + scissors */ + Bool ClipTurnedOn; /* Clipping was turned on by + the previous command */ + xf86CursorInfoPtr CursorInfoRec; /* HW Cursor info */ + + /* XAA */ + int MapSize; /* Size of mapped memory */ + CARD8 * DPRBase; /* Base of DPR registers */ + CARD8 * VPRBase; /* Base of VPR registers */ + CARD8 * CPRBase; /* Base of CPR registers */ + CARD8 * DCRBase; /* Base of DCR registers - + for 0501 chipset */ + CARD8 * SCRBase; /* Base of SCR registers - + for 0501 chipset */ + CARD8 * DataPortBase; /* Base of data port */ + int DataPortSize; /* Size of data port */ + /* below resource should get directly from entity but no mmap */ + CARD8 * IOBase; /* Base of MMIO VGA ports */ +#if 0//by ilena, very closed to pFB..... + unsigned char * FBBase; /* Base of FB */ +#endif + unsigned char * MapBase; /* Base of mapped io */ + /*be monk*/ + + CARD32 FBCursorOffset; /* Cursor storage location */ + + Bool PrimaryVidMapped; /* Flag indicating if + vgaHWMapMem was used successfully for this screen */ +#if 0 //by ilena: be defined in clockRanges + int minClock; /* Mimimum clock */ + int maxClock; /* Maximum clock */ +#endif + //int MCLK; /* Memory Clock *///by ilena, seems used in base. + int GEResetCnt; /* Limit the number of errors + printed using a counter */ + Bool NoPCIRetry; /* Disable PCI retries */ + Bool hwcursor; /* hardware cursor enabled */ + Bool ShowCache; /* Debugging option */ + Bool edid_enable; + + XAAInfoRecPtr AccelInfoRec; /* XAA info Rec */ + + /* Panel information */ + Bool lcd; /* LCD active, 1=TFT, 2=DSTN */ + + I2CBusPtr I2C; /* Pointer into I2C module */ + I2CBusPtr I2C_primary; + I2CBusPtr I2C_secondary; + + /* Shadow frame buffer (rotation) */ + Bool shadowFB; /* Flag if shadow buffer is + used */ + Bool clone_mode; /* Flag if clone mode is + used */ + int rotate; /* Rotation flags */ + Bool RandRRotation; + int ShadowPitch; /* Pitch of shadow buffer */ + int ShadowWidthBytes; /* Width of shadow + buffer in bytes */ + int ShadowWidth; /* Width of shadow buffer in + pixels */ + int ShadowHeight; /* Height of shadow buffer in + pixels */ + CARD32 saveBufferSize; /* #670 - FB save buffer size */ + void * pSaveBuffer; /* #670 - FB save buffer */ + CARD32 savedFBOffset; /* #670 - Saved FBOffset value */ + CARD32 savedFBReserved; /* #670 - Saved + FBReserved value */ + CARD8 * paletteBuffer; /* #920 - Palette save buffer */ + /* Polylines - #671 */ + ValidateGCProcPtr ValidatePolylines; /* Org. + ValidatePolylines function */ + Bool polyLines; /* Our polylines patch is + active */ + void (*PointerMoved)(int index, int x, int y); + int videoKey; /* Video chroma key */ + Bool ByteSwap; /* Byte swap for ZV port */ + Bool interlaced; /* True: Interlaced Video */ + /* XvExtension */ + XF86VideoAdaptorPtr ptrAdaptor; /* Pointer to VideoAdapter + structure */ + void (*BlockHandler)(int i, pointer blockData, pointer pTimeout, + pointer pReadMask); + +#if 0// by ilena, closed to screen + Bool IsSecondary; /* second Screen */ + Bool IsPrimary; /* first Screen */ +#endif + Bool IsLCD; + Bool IsCRT; + /*For CSC Video*/ + Bool IsCSCVideo; + CARD32 fb_priCursorOffset; + CARD32 fb_secCursorOffset; + CARD32 fb_argbCursorOffset; +}SMI502_Rec,*SMI502_Ptr; + +void sm502_pcDeepmap(SMIHWPtr pHw); +void sm502_entityInit(int,pointer); +void sm502_entityEnter(int,pointer); +void sm502_entityLeave(int,pointer); +void sm502_getMapResult(ScrnInfoPtr); +void sm502_vgaAndpciInit(ScrnInfoPtr pScrn,int entityIndex); +void sm502_handleOptions(ScrnInfoPtr); +ModeStatus sm502_validMode(ScrnInfoPtr,DisplayModePtr); +void sm502_setMode(ScrnInfoPtr,DisplayModePtr); +void sm502_adjustFrame(ScrnInfoPtr,int); +void sm502_setDisplay(ScrnInfoPtr pScrn, DisplayModePtr mode); +void sm502_pcDeepmap(SMIHWPtr pHw); +void sm502_saveText(ScrnInfoPtr pScrn); +void sm502_LoadPalette (ScrnInfoPtr , int , int *, LOCO * , VisualPtr ); +void sm502_closeAllScreen(SMIHWPtr pHw); +int sm502_totalFB(); +extern int ddk502_getFrameBufSize(); +extern long ddk502_initHw(); +extern unsigned long ddk502_PEEK32(addr); +extern void ddk502_POKE32(addr,data); +extern void ddk502_POKEfb32(addr,data); +extern void ddk502_set_mmio(volatile unsigned char * addr,unsigned short devId,unsigned long revId); +extern void ddk502_set_fb(volatile unsigned char * addr,unsigned short devId,char revId); +extern long ddk502_setModeTiming(logicalMode_t *pLogicalMode); +extern Bool SMI502_CrtcPreInit(ScrnInfoPtr pScrn); +extern Bool SMI502_OutputPreInit(ScrnInfoPtr pScrn); +extern void setLogicalDispOutput(disp_output_t output); +void sm502_I2CInit(ScrnInfoPtr pScrn); + +#ifndef _SMI_FUNCS_ONLY +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,0,0,0) +#include +#else +#define DPMS_SERVER +#include +#endif + +/* Definitions Start*/ +#define VSYNCTIMEOUT 10000 +/* Definitions End*/ + +/* Macros Start*/ +#define SMI502_PTR(p) ((SMI502_Ptr)((p)->driverPrivate)) +/* Macros End*/ +#endif + +/* Function Prototypes Start*/ + +/* smi502_shadow.c */ +void SMI502_PointerMoved(int index, int x, int y); +void SMI502_RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); + +/* Function Prototypes End*/ + +#ifndef _SMI_FUNCS_ONLY +/* Registers Start */ + +#define CURRENT_POWER_CLOCK_P1XCLK 31:31 +#define CURRENT_POWER_CLOCK_P1XCLK_ENABLE 1 +#define CURRENT_POWER_CLOCK_P1XCLK_DISABLE 0 +#define CURRENT_POWER_CLOCK_PLLCLK_SELECT 30:30 +#define CURRENT_POWER_CLOCK_PLLCLK_SELECT_ENABLE 1 +#define CURRENT_POWER_CLOCK_PLLCLK_SELECT_DISABLE 0 +#define CURRENT_POWER_CLOCK_V1XCLK 21:21 +#define CURRENT_POWER_CLOCK_V1XCLK_ENABLE 1 +#define CURRENT_POWER_CLOCK_V1XCLK_DISABLE 0 +#define POWER_MODE0_CLOCK_PLL3_P1XCLK 31:31 +#define POWER_MODE0_CLOCK_PLL3_P1XCLK_ENABLE 1 +#define POWER_MODE0_CLOCK_PLL3_P1XCLK_DISABLE 0 +#define POWER_MODE0_CLOCK_PLL3 30:30 +#define POWER_MODE0_CLOCK_PLL3_ENABLE 0 +#define POWER_MODE0_CLOCK_PLL3_DISABLE 1 + +/* CRT Cursor Control */ + +#define CRT_PALETTE_RAM 0x080400 +#define PANEL_PALETTE_RAM 0x080800 +#define VIDEO_PALETTE_RAM 0x080C00 + +#define SYSTEM_PLL3_CLOCK 0x000074 +#define SYSTEM_PLL3_CLOCK_M 7:0 +#define SYSTEM_PLL3_CLOCK_N 14:8 +#define SYSTEM_PLL3_CLOCK_DIVIDE 15:15 +#define SYSTEM_PLL3_CLOCK_DIVIDE_1 0 +#define SYSTEM_PLL3_CLOCK_DIVIDE_2 1 +#define SYSTEM_PLL3_CLOCK_INPUT 16:16 +#define SYSTEM_PLL3_CLOCK_INPUT_CRYSTAL 0 +#define SYSTEM_PLL3_CLOCK_INPUT_TEST 1 +#define SYSTEM_PLL3_CLOCK_POWER 17:17 +#define SYSTEM_PLL3_CLOCK_POWER_OFF 0 +#define SYSTEM_PLL3_CLOCK_POWER_ON 1 + +#define CURRENT_POWER_PLLCLOCK 0x000074 +#define CURRENT_POWER_PLLCLOCK_TEST_OUTPUT 20:20 +#define CURRENT_POWER_PLLCLOCK_TEST_OUTPUT_ENABLE 1 +#define CURRENT_POWER_PLLCLOCK_TEST_OUTPUT_DISABLE 0 +#define CURRENT_POWER_PLLCLOCK_TESTMODE 19:18 +#define CURRENT_POWER_PLLCLOCK_TESTMODE_ENABLE 1 +#define CURRENT_POWER_PLLCLOCK_TESTMODE_DISABLE 0 +#define CURRENT_POWER_PLLCLOCK_POWER 17:17 +#define CURRENT_POWER_PLLCLOCK_POWER_DOWN 0 +#define CURRENT_POWER_PLLCLOCK_POWER_ON 1 +#define CURRENT_POWER_PLLCLOCK_INPUT_SELECT 16:16 +#define CURRENT_POWER_PLLCLOCK_INPUT_SELECT_TEST 1 +#define CURRENT_POWER_PLLCLOCK_INPUT_SELECT_CRYSTAL 0 +#define CURRENT_POWER_PLLCLOCK_DIVIDEBY2 15:15 +#define CURRENT_POWER_PLLCLOCK_DIVIDE_N 14:8 +#define CURRENT_POWER_PLLCLOCK_MULTIPLE_M 7:0 + +/* Registers End */ + +/* SM501 Video Alpha Control */ +#define DCR80 0x0080 +#define DCR84 0x0084 +#define DCR88 0x0088 +#define DCR8C 0x008C +#define DCR90 0x0090 +#define DCR94 0x0094 +#define DCR98 0x0098 +#define DCR9C 0x009C +#define DCRA0 0x00A0 +#define DCRA4 0x00A4 + +/* SM501 Panel Cursor Control */ +#define DCRF0 0x00F0 +#define DCRF4 0x00F4 +#define DCRF8 0x00F8 +#define DCRFC 0x00FC + +/* SM 501 Alpha Control */ +#define DCR100 0x0100 +#define DCR104 0x0104 +#define DCR108 0x0108 +#define DCR10C 0x010C +#define DCR110 0x0110 +#define DCR114 0x0114 +#define DCR118 0x0118 + +/* SM 501 CRT Graphics Control */ +#define DCR200 0x0200 +#define DCR200_CRT_BLANK 0x00000400 +#define DCR200_CRT_GRAPHICS_PLN_FMT 0x00000003 +#define CRT_GRAPHICS_PLN_FMT_8 0x00 +#define CRT_GRAPHICS_PLN_FMT_16 0x01 +#define CRT_GRAPHICS_PLN_FMT_32 0x10 +#define DCR204 0x0204 +#define DCR208 0x0208 +#define DCR20C 0x020C +#define DCR210 0x0210 +#define DCR214 0x0214 +#define DCR218 0x0218 +#define DCR21C 0x021C +#define DCR220 0x0220 +#define DCR224 0x0224 + +/* SM 501 CRT Cursor Control */ +#define DCR230 0x0230 +#define DCR234 0x0234 +#define DCR238 0x0238 +#define DCR23C 0x023C + +/* SM 501 Palette Ram */ +#define DCR400 0x0400 /* Panel */ +#define DCR800 0x0800 /* Video */ +#define DCRC00 0x0C00 /* CRT */ + + +#endif +#endif /* ----- #ifndef SMI_502_INC ----- */ \ No newline at end of file diff --git a/src/drv502/smi_502_hw.c b/src/drv502/smi_502_hw.c new file mode 100644 index 0000000..493a9be --- /dev/null +++ b/src/drv502/smi_502_hw.c @@ -0,0 +1,139 @@ +#include "ddk502/ddk502_power.h" +#include "ddk502/ddk502_regdc.h" +#include "ddk502/ddk502_regdma.h" +#include "ddk502/ddk502_regsc.h" +#include "ddk502/ddk502_regzv.h" +#include "../smi_common.h" +#include "../smi_driver.h" +#include "smi_502_driver.h" +#include "smi_502_hw.h" +#include "../smi_dbg.h" + + +void set_display_502(SMIHWPtr pHw, display_t channel, int bpp, int pitch) +{ + + int SetValue; + disp_output_t output; + SetValue = ddk502_PEEK32 (PANEL_DISPLAY_CTRL); + + if (channel == PANEL) + { + SetValue |= (bpp == 8? + FIELD_SET (0, PANEL_DISPLAY_CTRL, FORMAT, 8) + : (bpp == 16? + FIELD_SET (0, PANEL_DISPLAY_CTRL, FORMAT, 16) + : FIELD_SET (0, PANEL_DISPLAY_CTRL, FORMAT, 32))); + + SetValue |= (FIELD_SET (SetValue, CRT_DISPLAY_CTRL, SELECT, PANEL));//???why crt display ctrl>??? + ddk502_POKE32(PANEL_DISPLAY_CTRL, SetValue); + +#if SMI_RANDR == 0 + ddk502_POKE32 (PANEL_FB_WIDTH, + FIELD_VALUE (0, PANEL_FB_WIDTH, WIDTH, pitch) | + FIELD_VALUE (0, PANEL_FB_WIDTH, OFFSET, pitch)); +#endif + if(bpp == 8) + { + ddk502_POKE32(PANEL_PALETTE_RAM, 0x00000000); /* PANEL Palette */ + ddk502_POKE32(PANEL_PALETTE_RAM,+ 4, 0x00FFFFFF); /* PANEL Palette */ + } + if(pHw->dual ==1) + { + /* For mirror, vga and dvi use the primary channel data in common*/ + output = PANEL_ONLY ; + setLogicalDispOutput( output); + } + else{ + output = PANEL_CRT_DUAL; + setLogicalDispOutput( output); + } + } + else if (channel == CRT) + { + + SetValue |= (bpp == 8? + FIELD_SET (0, CRT_DISPLAY_CTRL, FORMAT, 8) + : (bpp == 16? + FIELD_SET (0, CRT_DISPLAY_CTRL, FORMAT, 16) + : FIELD_SET (0, CRT_DISPLAY_CTRL, FORMAT, 32))); + SetValue |= (FIELD_SET(SetValue,CRT_DISPLAY_CTRL,SELECT,CRT));//??ilena not sure + ddk502_POKE32(CRT_DISPLAY_CTRL, SetValue); + if(bpp == 8) + { + ddk502_POKE32(CRT_PALETTE_RAM, 0x00000000); /* CRT Palette */ + ddk502_POKE32(CRT_PALETTE_RAM,+ 4, 0x00FFFFFF); /* CRT Palette */ + } + } + +} + + +long wait_for_not_busy_502(SMIPtr pSmi) +{ + unsigned long i = 0x1000000; + while (i--) + { + unsigned long dwVal = ddk502_PEEK32(CMD_INTPR_STATUS);//PEEK_32(CMD_INTPR_STATUS); + if ((FIELD_GET(dwVal, CMD_INTPR_STATUS, 2D_ENGINE) == CMD_INTPR_STATUS_2D_ENGINE_IDLE) && + (FIELD_GET(dwVal, CMD_INTPR_STATUS, 2D_FIFO) == CMD_INTPR_STATUS_2D_FIFO_EMPTY) && + (FIELD_GET(dwVal, CMD_INTPR_STATUS, 2D_SETUP) == CMD_INTPR_STATUS_2D_SETUP_IDLE) && + (FIELD_GET(dwVal, CMD_INTPR_STATUS, CSC_STATUS) == CMD_INTPR_STATUS_CSC_STATUS_IDLE) && + (FIELD_GET(dwVal, CMD_INTPR_STATUS, 2D_MEMORY_FIFO) == CMD_INTPR_STATUS_2D_MEMORY_FIFO_EMPTY) && + (FIELD_GET(dwVal, CMD_INTPR_STATUS, COMMAND_FIFO) == CMD_INTPR_STATUS_COMMAND_FIFO_EMPTY)) + { + return 0; /* Return because engine idle */ + } + } + + return -1; /* Return because time out */ +} +static void enable_GPIO_502(uint32_t enable) +{ + uint32_t gate; + + /* Enable GPIO Gate */ + gate = ddk502_PEEK32(CURRENT_POWER_GATE); + if (enable) + gate = FIELD_SET(gate, CURRENT_POWER_GATE, GPIO_PWM_I2C, DISABLE); + else + gate = FIELD_SET(gate, CURRENT_POWER_GATE, GPIO_PWM_I2C, ENABLE); + + ddk502_setCurrentGate(gate); +} + +void init_i2c_502(SMIHWPtr pHw) +{ + /* set mux for the i2c scl/sda*/ + int val = ddk502_PEEK32(GPIO_MUX_HIGH); + val = FIELD_SET(val,GPIO_MUX_HIGH,63,GPIO); + val = FIELD_SET(val,GPIO_MUX_HIGH,62,GPIO); + val = FIELD_SET(val,GPIO_MUX_HIGH,46,GPIO); + val = FIELD_SET(val,GPIO_MUX_HIGH,47,GPIO); + ddk502_POKE32(GPIO_MUX_HIGH,val); + + enable_GPIO_502(1); + + /* enable GPIO gate*/ +} + +void i2c_putbits_panel_502(I2CBusPtr bus,int clock,int data) +{ + ddk502_I2CPutBits_panel(bus, clock, data); +} + +void i2c_putbits_crt_502(I2CBusPtr bus,int clock,int data) +{ + ddk502_I2CPutBits_crt(bus, clock, data); +} + +void i2c_getbits_panel_502(I2CBusPtr bus,int* clock,int* data) +{ + ddk502_I2CGetBits_panel(bus, clock, data); +} + +void i2c_getbits_crt_502(I2CBusPtr bus,int* clock,int* data) +{ + ddk502_I2CGetBits_crt(bus, clock, data); +} + diff --git a/src/drv502/smi_502_hw.h b/src/drv502/smi_502_hw.h new file mode 100644 index 0000000..5e36260 --- /dev/null +++ b/src/drv502/smi_502_hw.h @@ -0,0 +1,29 @@ +#ifndef SMI_502_HW_INC +#define SMI_502_HW_INC + + +//static VOID panelUseLCD (SMI502_Ptr pSmi, BOOL bEnable); +//static VOID panelUseCRT (SMI502_Ptr pSmi, BOOL bEnable); +//static void panel_wait_Vsync_502 (SMI502_Ptr pSmi, INT vsync_count); +//static VOID panel_power_sequence_502 (SMI502_Ptr pSmi, panel_state_t on_off, INT vsync_delay); +//static LONG find_clock_502 (SMI502_Ptr pSmi,LONG requested_clock, clock_select_t * clock, display_t display); +//static VOID set_DPMS_502 (SMI502_Ptr pSmi, DPMS_t state); +//static VOID set_power_502 (SMI502_Ptr pSmi, ULONG nGates, ULONG Clock, int control_value); + +void save_reg_502(SMIHWPtr pHw); +long wait_for_not_busy_502(SMIPtr); +void set_display_502(SMIHWPtr pHw, display_t channel, int bpp, int pitch); +void init_i2c_502(SMIHWPtr pHw); + +void i2c_putbits_panel_502(I2CBusPtr bus,int clock,int data); +void i2c_putbits_crt_502(I2CBusPtr bus,int clock,int data); +void i2c_getbits_panel_502(I2CBusPtr bus,int* clock,int* data); +void i2c_getbits_crt_502(I2CBusPtr bus,int* clock,int* data); + +extern void ddk502_I2CPutBits_panel(I2CBusPtr bus,int clock,int data); +extern void ddk502_I2CGetBits_panel(I2CBusPtr bus,int* clock,int* data); +extern void ddk502_I2CPutBits_crt(I2CBusPtr bus,int clock,int data); +extern void ddk502_I2CGetBits_crt(I2CBusPtr bus,int* clock,int* data); + +#endif /* ----- #ifndef SMI_502_HW_INC ----- */ + diff --git a/src/drv502/smi_502_output.c b/src/drv502/smi_502_output.c new file mode 100644 index 0000000..07e3878 --- /dev/null +++ b/src/drv502/smi_502_output.c @@ -0,0 +1,486 @@ +/* +Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. +Copyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. +Copyright (C) 2008 Mandriva Linux. All Rights Reserved. +Copyright (C) 2008 Francisco Jerez. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- +NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of The XFree86 Project and +Silicon Motion shall not be used in advertising or otherwise to promote the +sale, use or other dealings in this Software without prior written +authorization from The XFree86 Project or Silicon Motion. +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "../smi_common.h" +#include "../smi_driver.h" +#include "../smi_dbg.h" +#include "../smi_crtc.h" +#include "../smi_output.h" +#include "ddk502/ddk502_regdc.h" +#include "ddk502/ddk502_display.h" +#include "ddk502/ddk502_help.h" + + +#define EDID_DEVICE_I2C_ADDRESS_502 0xa0 +#define EDID_TOTAL_RETRY_COUNTER_502 4 +#define TOTAL_EDID_REGISTERS_502 128 +#define SM502_DEFAULT_I2C_SCL 46 +#define SM502_DEFAULT_I2C_SDA 47 + +void SMI502_OutputDPMS_PNL(xf86OutputPtr output, int dpms); +void SMI502_OutputDPMS_CRT(xf86OutputPtr output,int dpms); + + +#if SMI_RANDR + +char* sm502_outputName[]={"PNL","CRT"}; + + +static void (*pfn_sm502outputDPMS[])(xf86OutputPtr,int)= +{SMI502_OutputDPMS_PNL,SMI502_OutputDPMS_CRT}; + + +void +SMI502_OutputDPMS_PNL(xf86OutputPtr output, int dpms) +{ + ScrnInfoPtr pScrn = output->scrn; + int idx; + ENTER(); + + switch (dpms) + { + case DPMSModeOn: + idx = 0; + ddk502_swPanelPowerSequence(PANEL_ON,4); + break; + case DPMSModeStandby: + idx = 1; + break; + case DPMSModeSuspend: + idx = 2; + break; + case DPMSModeOff: + idx = 3; + ddk502_swPanelPowerSequence(PANEL_OFF,4); + break; + } + + DEBUG("Set PNL DPMS ==> %s \n",dpms_str[idx]); + LEAVE(); +} +void +SMI502_OutputDPMS_CRT(xf86OutputPtr output,int dpms) +{ + ScrnInfoPtr pScrn = output->scrn; + int idx; + ENTER(); + + switch (dpms) + { + case DPMSModeOn: + idx = 0; + ddk502_setDPMS(SMI_DPMS_ON); + break; + case DPMSModeStandby: + idx = 1; + ddk502_setDPMS(SMI_DPMS_STANDBY); + break; + case DPMSModeSuspend: + idx = 2; + ddk502_setDPMS(SMI_DPMS_SUSPEND); + break; + case DPMSModeOff: + idx = 3; + ddk502_setDPMS(SMI_DPMS_OFF); + break; + } + + DEBUG("Set CRT DPMS ==> %s \n",dpms_str[idx]); + LEAVE(); +} + + +/* return 0 if the mode can be found in DDK */ +unsigned char SM502_edidGetVersion( + unsigned char *pEDIDBuffer, + unsigned char *pRevision) +{ + unsigned char version; + + if (pEDIDBuffer != (unsigned char *)0) + { + /* Check the header */ + if ((pEDIDBuffer[0] == 0x00) && (pEDIDBuffer[1] == 0xFF) && (pEDIDBuffer[2] == 0xFF) && + (pEDIDBuffer[3] == 0xFF) && (pEDIDBuffer[4] == 0xFF) && (pEDIDBuffer[5] == 0xFF) && + (pEDIDBuffer[6] == 0xFF) && (pEDIDBuffer[7] == 0x00)) + { + /* + * EDID Structure Version 1. + */ + + /* Read the version field from the buffer. It should be 1 */ + version = pEDIDBuffer[18]; + + if (version == 1) + { + /* Copy the revision first */ + if (pRevision != (unsigned char *)0) + *pRevision = pEDIDBuffer[19]; + return version; + } + } + else + { + /* + * EDID Structure Version 2 + */ + + /* Read the version and revision field from the buffer. */ + version = pEDIDBuffer[0]; + + if ((version >> 4) == 2) + { + /* Copy the revision */ + if (pRevision != (unsigned char *)0) + *pRevision = version & 0x0F; + return (version >> 4); + } + } + } + return 0; +} + +int32_t SMI502_edidReadMonitorEx( + display_t displayPath, + unsigned char *pEDIDBuffer, + uint32_t bufferSize, + unsigned char edidExtNo, + unsigned char sclGpio, + unsigned char sdaGpio) +{ + unsigned char value, retry, edidVersion, edidRevision; + unsigned char edidBuffer[256]; + uint32_t offset; + + /* Initialize the i2c bus */ + ddk502_swI2CInit(sclGpio, sdaGpio); + for (retry = 0; retry < EDID_TOTAL_RETRY_COUNTER_502; retry++) + { + + /* Read the EDID from the monitor. */ + for (offset = 0; offset < TOTAL_EDID_REGISTERS_502; offset++) + edidBuffer[offset] = ddk502_swI2CReadReg(EDID_DEVICE_I2C_ADDRESS_502, (unsigned char)offset); + + /* Check if the EDID is valid. */ + edidVersion = SM502_edidGetVersion((unsigned char *)&edidBuffer, (unsigned char *)&edidRevision); + if (edidVersion != 0) + break; + } + + /* + * The monitor might not be DDC2B compliance. Therefore, need to use DDC1 protocol, + * which uses the Vertical Sync to clock in the EDID data. + * Currently this function return error. DDC1 protocol can be added later. + */ + if (retry == EDID_TOTAL_RETRY_COUNTER_502) + { + /* DDC1 uses the SDA line to transmit 9 bit data per byte. The last bit is + * only an acknowledge flag, which could be high or low. However, SCL line + * is not used. Instead the data is clock-in using vertical sync. + */ + return (-1); + } + + /* Copy the data to the given buffer */ + if (pEDIDBuffer != (unsigned char *)0) + { + for (offset = 0; offset < bufferSize; offset++) + pEDIDBuffer[offset] = edidBuffer[offset]; + } + return 0; +} +DisplayModePtr SMI502_OutputGetModes(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + xf86MonPtr pMon = NULL; + SMIOutputPrivatePtr priv = (SMIOutputPrivatePtr)output->driver_private; + I2CBusPtr bus; + char * EdidBuffer; + ENTER(); + LEAVE(NULL); + + EdidBuffer = xalloc(128); + + if(!EdidBuffer){ + XERR("not enough memory for allocating EDID buffer\n"); + LEAVE(NULL); + } + + XINF("i2c bus index == %d\n",priv->path); + + bus = (priv->path == PANEL ? NULL/*pSmi->I2C_primary*/:NULL); + + /* some thing weird: some times Xserver method to access EDID is okay while some times not + but use hardware i2c to access DVI EDID should be always okay + */ + + if(xf86LoaderCheckSymbol("xf86PrintEDID")) + { + if(bus) + { + pMon = xf86OutputGetEDID(output,bus); + if(pMon) + { + xf86PrintEDID(pMon); + xf86OutputSetEDID(output,pMon); + xfree(EdidBuffer); + LEAVE(xf86OutputGetEDIDModes(output)); + } +#if SMI_DEBUG == 1 + else{ + XERR("Seems monitor not found\n"); + } +#endif + } +#if SMI_DEBUG == 1 + else{ + XERR("Seems bus not found\n"); + } +#endif + } +#if SMI_DEBUG == 1 + else{ + XERR("should me be seen ?\n"); + } +#endif + + XINF("try DDK method\n"); + long returnValue; + if(priv->path != PANEL) + { + + returnValue = SMI502_edidReadMonitorEx(PANEL,EdidBuffer, 128, + 0, SM502_DEFAULT_I2C_SCL, SM502_DEFAULT_I2C_SDA); + if (returnValue == 0) + { + pMon = xf86InterpretEDID(pScrn->scrnIndex,EdidBuffer); + if(pMon){ + xf86OutputSetEDID(output,pMon); + XINF("Found monitor by DDK\n"); + xfree(EdidBuffer); + LEAVE(xf86OutputGetEDIDModes(output)); + }else{ + XERR("DDK cannot get monitor\n"); + } + } + else + { + XERR("DDK cannot detect EDID Version\n"); + } + } + else + { + /* + because 750ddk.so is loaded by siliconmotion_drv.so + so if one function of 750ddk.so is referenced as function pointer + it will be failed . + but calling the function is okay. + I suggest combine 750ddk.so into siliconmotion_drv.so + which is a must for function pointer passing method + + below code pass xorg_I2CUDelay address into edidRead + but X will exit with error when it be executed + while just calling xorg_I2CUDelay is okay + monk @ 10/20/2010 + */ + returnValue = -1 ; + //SMI502_edidReadMonitorEx(CRT_PATH,EdidBuffer,128,0, SM502_DEFAULT_I2C_SCL, SM502_DEFAULT_I2C_SDA); //502 do not support crt path edid + if (returnValue == 0) + { + pMon = xf86InterpretEDID(pScrn->scrnIndex, EdidBuffer); + if(pMon){ + xf86OutputSetEDID(output,pMon); + XINF("Found monitor by DDK\n"); + xfree(EdidBuffer); + LEAVE(xf86OutputGetEDIDModes(output)); + }else{ + XERR("DDK cannot get monitor\n"); + } + } + } + + XMSG("DDK seems no mode found\n"); + + xfree(EdidBuffer); + LEAVE(NULL); +} +Bool SMI502_LinkPathCrtcc(ScrnInfoPtr pScrn,display_t path,channel_t control) +{ + /* just select the contoller for the path and do nothing else */ + uint32_t ulreg; + ENTER(); + + DEBUG("%s path <== %s controller \n", + path==PANEL?"Panel":"Crt", + control==PRIMARY_CTRL?"Primary":"Secondary"); + + + if(path == PANEL) + { + } + else + { + ulreg = ddk502_PEEK32(CRT_DISPLAY_CTRL); + ulreg = FIELD_VALUE(ulreg,CRT_DISPLAY_CTRL,SELECT,control == PRIMARY_CTRL?0:1); + ddk502_POKE32(CRT_DISPLAY_CTRL,ulreg); + } + LEAVE(TRUE); +} +static void SMI502_OutputModeSet(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode) +{ + ScrnInfoPtr pScrn; + xf86CrtcPtr crtc; + SMIPtr pSmi; + SMIHWPtr pHw; + channel_t channel; + display_t path; + output_head_t head; + int okay; + + ENTER(); + pScrn = output->scrn; + pSmi = SMIPTR(pScrn); + pHw = pSmi->pHardware; + SMIOutputPrivatePtr priv = (SMIOutputPrivatePtr)output->driver_private; + + RROutputPtr rrop = output->randr_output; + + if((crtc = output->crtc) != NULL) + { + channel = ((SMICrtcPrivatePtr)crtc->driver_private)->controller; + path = priv->path; + head = priv->head; +#if 0 + if(pSmi->DualView == FALSE){ + SMI502_LinkPathCrtcc(pScrn,PANEL ,channel); + SMI502_LinkPathCrtcc(pScrn,CRT ,channel); + SMI_SetHead(pScrn,HEAD_DVI,PANEL_ON); + SMI_SetHead(pScrn,HEAD_VGA,PANEL_ON); + }else{ + SMI502_LinkPathCrtcc(pScrn,path ,channel); + SMI_SetHead(pScrn,head,DISP_ON); + if(channel != PRIMARY_CTRL) + setLogicalDispOutput(PANEL_CRT_DUAL); + } +#endif + } + else + { + XERR("Output->crtct == NULL !!\n"); + } + LEAVE(); +} + +Bool +SMI502_OutputPreInit(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi; + xf86OutputPtr output; + SMIOutputPrivatePtr outputPriv; + xf86OutputFuncsPtr outputFuncs; + SMIHWPtr pHw; + ENTER(); + + pSmi = SMIPTR(pScrn); + pHw = pSmi->pHardware; + int c = (pSmi->DualView?2:1); + int idx = 0; + Bool expansion = (pSmi->lcdWidth>0 && pSmi->lcdHeight>0); + + while(idx < c) + { + if(!SMI_OutputFuncsInit_base(&outputFuncs)) + LEAVE(FALSE); +// outputFuncs->mode_valid = SMI_OutputModeValid; + outputFuncs->mode_set = SMI502_OutputModeSet; + outputFuncs->dpms = pfn_sm502outputDPMS[idx]; + outputFuncs->get_modes = SMI502_OutputGetModes; + outputFuncs->detect = SMI_OutputDetect_PNL_CRT; + outputFuncs->mode_valid = SMI_OutputModeValid; + outputPriv = xnfcalloc(sizeof(SMIOutputPrivateRec),1); + outputPriv->index = idx; + outputPriv->path = idx; + + if(idx == 0) + { /* for output 0: it's always be Panel path */ + if(pSmi->TFTColor!= -1) + outputPriv->head = HEAD_TFT0; + else + outputPriv->head = HEAD_DVI; + } + else + { /* for output 1: it's always be Crt path */ + if(pSmi->TFTColor == SMI_TFT_18BIT) + outputPriv->head = HEAD_TFT1; + else + outputPriv->head = HEAD_VGA; + } + if (! (output = xf86OutputCreate(pScrn, outputFuncs, sm502_outputName[idx]))) + LEAVE(FALSE); + + output->driver_private = outputPriv; + if(idx == 0) + { + output->possible_crtcs = 1; + output->possible_clones = 1; + + } + else + { + output->possible_crtcs = pSmi->DualView?3:1; + output->possible_clones = 3; + + } + + if(outputPriv->path == 0 && expansion) + { + /* only link to crtc_1 [secondary channel] + but remember that if no expansion ,crtc_0 will be by default Primary channel + */ + output->possible_crtcs = 1;//note: Secondary controller will be ctrc 0 if expansion enabled + output->possible_clones = 0; + } + + if(outputPriv->path == 1 && expansion) + output->possible_clones = 1; + output->interlaceAllowed = FALSE; + output->doubleScanAllowed = FALSE; + XINF("output[%d]->possible_crtcs = %d \n",idx,output->possible_crtcs); + idx++; + } + + LEAVE(TRUE); +} + + +#endif /*#if SMI_RANDR*/ + diff --git a/src/drv712/smi_712_crtc.c b/src/drv712/smi_712_crtc.c new file mode 100644 index 0000000..fd57950 --- /dev/null +++ b/src/drv712/smi_712_crtc.c @@ -0,0 +1,1540 @@ +/* +Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. +Copyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. +Copyright (C) 2008 Francisco Jerez. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- +NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of The XFree86 Project and +Silicon Motion shall not be used in advertising or otherwise to promote the +sale, use or other dealings in this Software without prior written +authorization from The XFree86 Project or Silicon Motion. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "../smi_common.h" +#include "../smi_driver.h" +#include "../smi_video.h" +#include "../smi_dbg.h" +#include "../smi_crtc.h" +#include "../smi_output.h" +#include "smi_712_driver.h" +#include "ddk712/ddk712.h" +#include "smi_712_hw.h" +/* + below table is the timing value for sm712 + 0~13 will be set to SVR40 ~ SVR4D + 14~15 will be set to CCR6C and CCR6D +*/ +#if SMI_RANDR + +const SMI712CrtTiming g_sm712_ModeTable[] = { +/* 640x480 */ +{ + 640,480,60, + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, 0x07, 0x82, +}, +{ + 640,480,75, + 0x64, 0x4F, 0x00, 0x52, 0x1A, 0xF2, 0xDF, 0x00, + 0xE0, 0x03, 0x0F, 0xC0, 0x4F, 0xDF, 0x16, 0x85, +}, +{ + 640,480,85, + 0x63, 0x4F, 0x00, 0x57, 0x1E, 0xFB, 0xDF, 0x00, + 0xE0, 0x03, 0x0F, 0xC0, 0x4F, 0xDF, 0x88, 0x9B, +}, +/* 800x480 */ +{ + 800,480,60, + 0x6B, 0x63, 0x00, 0x69, 0x1B, 0xF2, 0xDF, 0x00, + 0xE2, 0xE4, 0x1F, 0xC0, 0x63, 0xDF, 0x2C, 0x17, +}, +{ + 800,480,75, + 0x6B, 0x63, 0x00, 0x69, 0x1B, 0xF2, 0xDF, 0x00, + 0xE2, 0xE4, 0x1F, 0xC0, 0x63, 0xDF, 0x2C, 0x17, +}, +{ + 800,480,85, + 0x6B, 0x63, 0x00, 0x69, 0x1B, 0xF2, 0xDF, 0x00, + 0xE2, 0xE4, 0x1F, 0xC0, 0x63, 0xDF, 0x2C, 0x17, +}, +/* 800x600 */ +{ + 800,600,60, + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, 0x1C, 0x85, +}, +{ + 800,600,75, + 0x7F, 0x63, 0x00, 0x66, 0x10, 0x6F, 0x57, 0x00, + 0x58, 0x0B, 0xE0, 0x20, 0x63, 0x57, 0x4C, 0x8B, +}, +{ + 800,600,85, + 0x7E, 0x63, 0x00, 0x68, 0x10, 0x75, 0x57, 0x00, + 0x58, 0x0B, 0xE0, 0x20, 0x63, 0x57, 0x37, 0x87, +}, +#if 0 +/* 1024x600 */ +{ + 1024,600,60, + 0xA3, 0x7F, 0x00, 0x82, 0x0B, 0x6F, 0x57, 0x00, + 0x5C, 0x0F, 0xE0, 0xE0, 0x7F, 0x57, 0x16, 0x07, +}, +#endif +/* 1024x768 */ + +{ + 1024,768,60, + 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, + 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, 0x52, 0x89, +}, +{ + 1024,768,75, + 0x9F, 0x7F, 0x00, 0x82, 0x0E, 0x1E, 0xFF, 0x00, + 0x00, 0x03, 0xE5, 0x20, 0x7F, 0xFF, 0x0B, 0x02, +}, +{ + 1024,768,85, + 0xA7, 0x7F, 0x00, 0x86, 0x12, 0x26, 0xFF, 0x00, + 0x00, 0x03, 0xE5, 0x20, 0x7F, 0xFF, 0x70, 0x11, +}, + +/* 1280x1024 */ +{ + 1280,1024,60, + 0xCE, 0x9F, 0x00, 0xA7, 0x15, 0x28, 0xFF, 0x00, + 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x53, 0x0B, +}, +{ + 1280,1024,75, + 0xCE, 0x9F, 0x00, 0xA2, 0x14, 0x28, 0xFF, 0x00, +// 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x13, 0x02, + 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x42, 0x07, +}, +{ + 1280,1024,85, + 0xD3, 0x9F, 0x00, 0xA8, 0x1C, 0x2E, 0xFF, 0x00, +// 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x16, 0x42, + 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x0b, 0x01, +}, + +}; + +const int g_sm712_mode_cnt = sizeof(g_sm712_ModeTable)/sizeof(g_sm712_ModeTable[0]); + + +/* below hard code is not correct, so disable none-60 hz incorrect timings */ +const SMI712PnlTiming g_sm712_ModeTable2[] = { +#if 0 +{ + + 640,480,60, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0C, 0xDF, 0xE9, + 0x00, 0x03, 0x59, 0x00, 0x4F, 0xDF, 0x03, 0x02, +}, + +{ + 640,480,75, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0C, 0xDF, 0xE9, + 0x00, 0x03, 0x59, 0xC0, 0x4F, 0xDF, 0x16, 0x85, +}, +{ + 640,480,85, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0C, 0xDF, 0xE9, + 0x00, 0x03, 0x59, 0xC0, 0x4F, 0xDF, 0x88, 0x9B, +}, +#endif +{ + 800,480,60, + 0x02, 0x24, 0x7B, 0x63, 0x67, 0xF3, 0xDF, 0xE2, + 0x00, 0x03, 0x41, 0xC0, 0x63, 0xDF, 0x2C, 0x17, +}, +#if 0 +{ + 800,480,75, + 0x6B, 0x63, 0x00, 0x69, 0x1B, 0xF2, 0xDF, 0x00, + 0xE2, 0xE4, 0x1F, 0xC0, 0x63, 0xDF, 0x2C, 0x17, +}, +{ + 800,480,85, + 0x6B, 0x63, 0x00, 0x69, 0x1B, 0xF2, 0xDF, 0x00, + 0xE2, 0xE4, 0x1F, 0xC0, 0x63, 0xDF, 0x2C, 0x17, +}, +#endif +{ + 800,600,60, + 0x04, 0x48, 0x83, 0x63, 0x69, 0x73, 0x57, 0x58, + 0x00, 0x03, 0x7B, 0x20, 0x63, 0x57, 0x0E, 0x05, +}, +#if 0 +{ + 800,600,75, + 0x7F, 0x63, 0x00, 0x66, 0x10, 0x6F, 0x57, 0x00, + 0x58, 0x0B, 0xE0, 0x20, 0x63, 0x57, 0x4C, 0x8B, +}, +{ + 800,600,85, + 0x7E, 0x63, 0x00, 0x68, 0x10, 0x75, 0x57, 0x00, + 0x58, 0x0B, 0xE0, 0x20, 0x63, 0x57, 0x37, 0x87, +}, +#endif +#if 0 +{ + 1024,600,60, + 0x04, 0x48, 0x95, 0x7F, 0x86, 0x70, 0x57, 0x5B, + 0x00, 0x60, 0x1c, 0x22, 0x7F, 0x57, 0x16, 0x07, +}, +#endif +{ + 1024,768,60, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x25, 0xFF, 0x02, + 0x00, 0x62, 0x85, 0x20, 0x7F, 0xFF, 0x29, 0x09, +}, +#if 0 +{ + 1024,768,75, + 0x9F, 0x7F, 0x00, 0x82, 0x0E, 0x1E, 0xFF, 0x00, + 0x00, 0x03, 0xE5, 0x20, 0x7F, 0xFF, 0x0B, 0x02, +}, +{ + 1024,768,85, + 0xA7, 0x7F, 0x00, 0x86, 0x12, 0x26, 0xFF, 0x00, + 0x00, 0x03, 0xE5, 0x20, 0x7F, 0xFF, 0x70, 0x11, +}, +#endif +{ + 1280,1024,60, + 0x08, 0x8C, 0xD5, 0x9F, 0xAB, 0x26, 0xFF, 0x00, + 0x00, 0x03, 0x7E, 0x20, 0x9F, 0xFF, 0x53, 0x0B, +}, +#if 0 +{ + 1280,1024,75, + 0xCE, 0x9F, 0x00, 0xA2, 0x14, 0x28, 0xFF, 0x00, + 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x42, 0x07, +}, +{ + 1280,1024,85, + 0xD3, 0x9F, 0x00, 0xA8, 0x1C, 0x2E, 0xFF, 0x00, + 0x00, 0x03, 0x4A, 0x20, 0x9F, 0xFF, 0x0b, 0x01, +}, +#endif +}; +#define BASE_FREQ 14.31818 /* MHz */ + +const int g_sm712_mode2_cnt = sizeof(g_sm712_ModeTable2)/sizeof(g_sm712_ModeTable2[0]); +void +SMI_CommonCalcClock(int scrnIndex, int32_t freq, int min_m, int min_n1, + int max_n1, int min_n2, int max_n2, int32_t freq_min, + int32_t freq_max, unsigned char *mdiv, unsigned char *ndiv) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + double div, diff, best_diff; + unsigned int m; + unsigned char n1, n2; + unsigned char best_n1 = 63, best_n2 = 3, best_m = 255; + + double ffreq = freq / 1000.0 / BASE_FREQ; + double ffreq_min = freq_min / 1000.0 / BASE_FREQ; + double ffreq_max = freq_max / 1000.0 / BASE_FREQ; + + if (ffreq < ffreq_min / (1 << max_n2)) { + xf86DrvMsg(scrnIndex,X_WARNING,"invalid frequency %1.3f MHz [freq >= %1.3f MHz]\n", + ffreq * BASE_FREQ, ffreq_min * BASE_FREQ / (1 << max_n2)); + ffreq = ffreq_min / (1 << max_n2); + } + if (ffreq > ffreq_max / (1 << min_n2)) { + xf86DrvMsg(scrnIndex,X_WARNING,"invalid frequency %1.3f MHz [freq <= %1.3f MHz]\n", + ffreq * BASE_FREQ, ffreq_max * BASE_FREQ / (1 << min_n2)); + ffreq = ffreq_max / (1 << min_n2); + } + + /* work out suitable timings */ + best_diff = ffreq; + + for (n2 = min_n2; n2 <= max_n2; n2++) { + for (n1 = min_n1; n1 <= max_n1; n1++) { + m = (int)(ffreq * n1 * (1 << n2) + 0.5); + if ( (m < min_m) || (m > 255) ) { + continue; + } + div = (double)(m) / (double)(n1); + if ( (div >= ffreq_min) && (div <= ffreq_max) ) { + diff = ffreq - div / (1 << n2); + if (diff < 0.0) { + diff = -diff; + } + if (diff < best_diff) { + best_diff = diff; + best_m = m; + best_n1 = n1; + best_n2 = n2; + } + } + } + } + + DEBUG("Clock parameters for %1.6f MHz: m=%d, n1=%d, n2=%d\n", + ((double)(best_m) / (double)(best_n1) / (1 << best_n2)) * BASE_FREQ, + best_m, best_n1, best_n2); + + if (SMI_LYNX_SERIES(pHw->Chipset)) { + /* Prefer post scalar enabled for even denominators */ + if (freq < 70000 && max_n2 > 0 && + best_n2 == 0 && best_n1 % 2 == 0){ + best_n1 >>= 1; + best_n2 = 1; + } + + *ndiv = best_n1 | + (best_n2 & 0x1) << 7 | + (best_n2 & 0x2) >> 1 <<6; + } else { + *ndiv = best_n1 | (best_n2 << 7); + + /* Enable second VCO */ + if (freq > 120000) + *ndiv |= 1 << 6; + } + + *mdiv = best_m; +} + + +static void SMILynx_CrtcVideoInit_crt(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + int pitch; + + ENTER(); + + switch (pScrn->bitsPerPixel) + { + case 8: + WRITE_VPR(pHw, VPR_00, 0x00000000); + break; + case 16: + WRITE_VPR(pHw, VPR_00, 0x00020000); + break; + case 24: + WRITE_VPR(pHw, VPR_00, 0x00040000); + break; + case 32: + WRITE_VPR(pHw, VPR_00, 0x00030000); + break; + } +#if 0 + pitch = (crtc->rotatedData? crtc->mode.HDisplay : pScrn->displayWidth) * pSmi->Bpp; + pitch = (pitch + 15) & ~15; + + WRITE_VPR(pSmi, 0x10, (crtc->mode.HDisplay * pSmi->Bpp) >> 3 << 16 | pitch >> 3); +#endif + + LEAVE(); +} + +static void SMILynx_CrtcVideoInit_lcd(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pSmi->pHardware; + SMI712RegPtr mode = p712Hw->pRegMode; + CARD16 fifo_readoffset,fifo_writeoffset; + + ENTER(); + + /* Set display depth */ + if (pScrn->bitsPerPixel > 8) + mode->SR31 |= 0x40; /* 16 bpp */ + else + mode->SR31 &= ~0x40; /* 8 bpp */ + + /* FIFO1/2 Read Offset*/ + fifo_readoffset = (crtc->rotatedData? crtc->mode.HDisplay : pScrn->displayWidth) * pSmi->Bpp; + fifo_readoffset = ((fifo_readoffset + 15) & ~15) >> 3; + + /* FIFO1 Read Offset */ + mode->SR44 = fifo_readoffset & 0x000000FF; + /* FIFO2 Read Offset */ + mode->SR4B = fifo_readoffset & 0x000000FF; + + if(pHw->Chipset == SMI_LYNX3DM){ + /* FIFO1/2 Read Offset overflow */ + mode->SR4C = (((fifo_readoffset & 0x00000300) >> 8) << 2) | + (((fifo_readoffset & 0x00000300) >> 8) << 6); + }else{ + /* FIFO1 Read Offset overflow */ + mode->SR45 = (mode->SR45 & 0x3F) | ((fifo_readoffset & 0x00000300) >> 8) << 6; + /* FIFO2 Read Offset overflow */ + mode->SR4C = (((fifo_readoffset & 0x00000300) >> 8) << 6); + } + + /* FIFO Write Offset */ + fifo_writeoffset = crtc->mode.HDisplay * pSmi->Bpp >> 3; + mode->SR48 = fifo_writeoffset & 0x000000FF; + mode->SR49 = (fifo_writeoffset & 0x00000300) >> 8; + + /* set FIFO levels */ + mode->SR4A = 0x41; + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, mode->SR31); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x44, mode->SR44); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45, mode->SR45); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x48, mode->SR48); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49, mode->SR49); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4A, mode->SR4A); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4B, mode->SR4B); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4C, mode->SR4C); + + LEAVE(); +} + +static void SMI712_CrtcAdjustFrame(xf86CrtcPtr crtc, int x, int y) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pSmi->pHardware; + SMI712RegPtr mode = p712Hw->pRegMode; + xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + CARD32 Base; + CARD32 Pitch,Width; + + ENTER(); + Pitch = (pScrn->displayWidth * pSmi->Bpp);//it == pixel unit divided with 8 + Width = (crtc->mode.HDisplay * pSmi->Bpp);//as caculated like pitch + + XERR("pScrn->displayWidth = %d\n",pScrn->displayWidth); + XERR("Pitch = %x Width = %x\n",Pitch,Width); + + if(crtc->rotatedData){ + Pitch = crtcPriv->shadow_pitch ; + Base = (char*)crtc->rotatedData - (char*)pSmi->pFB; + } + else + Base = pSmi->FBOffset + (x + y * pScrn->displayWidth) * pSmi->Bpp; + + + Base = (Base + 7) & ~7; + while ((Base % pSmi->Bpp) > 0) + Base -= 8; + Base >>= 3; + + Width>>=3; + Pitch>>=3; + + //if(pSmi->DualView && crtc == crtcConf->crtc[1]) + if(crtcPriv->controller && (pSmi->DualView)) + { + /* LCD channel pitch and base address */ + + /* FIFO1 read start address */ + mode->SR40 = Base & 0x000000FF; + mode->SR41 = (Base & 0x0000FF00) >> 8; + + /* FIFO2 read start address */ + mode->SR42 = Base & 0x000000FF; + mode->SR43 = (Base & 0x0000FF00) >> 8; + + /* FIFO1/2 read start address overflow */ + if(pHw->Chipset == SMI_LYNX3DM) + mode->SR45 = (Base & 0x000F0000) >> 16 | (Base & 0x000F0000) >> 16 << 4; + else + mode->SR45 = (mode->SR45 & 0xC0) | + (Base & 0x00070000) >> 16 | (Base & 0x00070000) >> 16 << 3; + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x40, mode->SR40); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x41, mode->SR41); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x42, mode->SR42); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x43, mode->SR43); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45, mode->SR45); + + /* Offset of LCD channel*/ + mode->SR45 = (mode->SR45 & 0x3f)|((Pitch & 0x300 ) >> 2); + VGAOUT8_INDEX_712(pHw,VGA_SEQ_INDEX,VGA_SEQ_DATA,0x44,Pitch & 0xff); + VGAOUT8_INDEX_712(pHw,VGA_SEQ_INDEX,VGA_SEQ_DATA,0x45,mode->SR45); + + } + else + { + /* CRT and single head */ + WRITE_VPR(pHw, 0x0C, Base); + WRITE_VPR(pHw, 0x10,(Width<<16)|(Pitch&0xffff)); + } + LEAVE(); +} + + +static void +SMILynx_CrtcAdjustFrame(xf86CrtcPtr crtc, int x, int y) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pSmi->pHardware; + SMI712RegPtr mode = p712Hw->pRegMode; + xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); + CARD32 Base; + CARD32 Pitch,Width; + + ENTER(); + Pitch = (pScrn->displayWidth * pSmi->Bpp) >> 3;//it == pixel unit divided with 8 + Width = (crtc->mode.HDisplay * pSmi->Bpp) >> 3;//as caculated like pitch + + if(crtc->rotatedData) + Base = (char*)crtc->rotatedData - (char*)pSmi->pFB; + else + Base = pSmi->FBOffset + (x + y * pScrn->displayWidth) * pSmi->Bpp; + + + if (SMI_LYNX3D_SERIES(pHw->Chipset) || SMI_COUGAR_SERIES(pHw->Chipset)) + { + Base = (Base + 15) & ~15; + while ((Base % pSmi->Bpp) > 0) { + Base -= 16; + } + } + else + { + Base = (Base + 7) & ~7; + while ((Base % pSmi->Bpp) > 0) + Base -= 8; + } + + Base >>= 3; + + if(SMI_COUGAR_SERIES(pHw->Chipset)) + { + WRITE_VPR(pHw, 0x0C, Base); + WRITE_FPR(pHw, FPR0C, Base); + } + else + { + if((pSmi->DualView) && crtc == crtcConf->crtc[1]) + { + /* LCD */ + + /* FIFO1 read start address */ + mode->SR40 = Base & 0x000000FF; + mode->SR41 = (Base & 0x0000FF00) >> 8; + + /* FIFO2 read start address */ + mode->SR42 = Base & 0x000000FF; + mode->SR43 = (Base & 0x0000FF00) >> 8; + + /* FIFO1/2 read start address overflow */ + if(pHw->Chipset == SMI_LYNX3DM) + mode->SR45 = (Base & 0x000F0000) >> 16 | (Base & 0x000F0000) >> 16 << 4; + else + mode->SR45 = (mode->SR45 & 0xC0) | + (Base & 0x00070000) >> 16 | (Base & 0x00070000) >> 16 << 3; + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x40, mode->SR40); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x41, mode->SR41); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x42, mode->SR42); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x43, mode->SR43); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45, mode->SR45); + } + else + { + /* CRT or single head */ + WRITE_VPR(pHw, 0x0C, Base); + WRITE_VPR(pHw, 0x10,(Pitch&0xffff)|(Width<<16)); + } + } + LEAVE(); +} + +static Bool +SMILynx_CrtcModeFixup(xf86CrtcPtr crtc, + DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + + ENTER(); + + + /* Adjust the pixel clock in case it is near one of the known + stable frequencies (KHz) */ + int stable_clocks[] = {46534,}; + int epsilon = 3000; + int i; + + for (i=0; i < sizeof(stable_clocks)/sizeof(int); i++) { + if ( abs(mode->Clock - stable_clocks[i]) < epsilon) { + adjusted_mode->Clock = stable_clocks[i]; + break; + } + + } + + LEAVE(TRUE); +} + +/* + for normal timing setting procedure, we can set mode with out the independence of VRefresh and HSync + But 712 CRT channel timing structor is too difficult and too hard to caculate (no document even) + Poorly,we just set the mode with hard code,routine below is strongly depend on the X res ,Y res and VRefresh +*/ +static void SMI712_ModeSet(xf86CrtcPtr crtc, + DisplayModePtr mode,DisplayModePtr mode_adj, + int x,int y) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + vgaHWPtr hwp = VGAHWPTR(pScrn); + SMICrtcPrivatePtr crtcPriv = crtc->driver_private; + SMI712CrtTiming * timing_crt = NULL; + SMI712PnlTiming * timing_pnl = NULL; + int VGA_CRT_INDEX = hwp->IOBase + VGA_CRTC_INDEX_OFFSET; + int VGA_CRT_DATA = hwp->IOBase + VGA_CRTC_DATA_OFFSET; + + unsigned char tmp;//used for CRTC30 + int index = 0; + int xres = mode_adj->HDisplay; + int yres = mode_adj->VDisplay; + float VRefresh = mode_adj->VRefresh + 0.5f; + float HSync = mode_adj->HSync; + + int item; + + ENTER(); + + + + XMSG("Set crtc[%d] ==> channel %d\n",crtcPriv->index,crtcPriv->controller); + XMSG("adjusted_mode:xres = %d,yres = %d,vsync = %f hsync = %f\n",xres,yres,VRefresh,HSync); + XMSG("mode:hsyncstart,hsyncend,htotal = %d,%d,%d\n", + mode_adj->HSyncStart,mode_adj->HSyncEnd,mode_adj->HTotal); + XMSG("mode:Vsyncstart,Vsyncend,Vtotal = %d,%d,%d\n", + mode_adj->VSyncStart,mode_adj->VSyncEnd,mode_adj->VTotal); + + /* find the mode */ + + if(crtcPriv->controller) + { + /* pnl channel */ + timing_pnl= g_sm712_ModeTable2; + item = g_sm712_mode2_cnt; + + /* find the pnl mode table */ + while(index < item){ + if(timing_pnl[index].h_res == xres && timing_pnl[index].v_res == yres && + timing_pnl[index].vsync == (unsigned short)VRefresh ) + break; + index++; + } + timing_pnl = timing_pnl + index; + } + else + { + /* crt channel */ + timing_crt = g_sm712_ModeTable; + item = g_sm712_mode_cnt; + + /* find the crt mode table */ + while(index < item){ + if(timing_crt[index].h_res == xres && timing_crt[index].v_res == yres && + timing_crt[index].vsync == (unsigned short)VRefresh ) + break; + index++; + } + timing_crt = timing_crt + index; + } + + if(index == item){ + /* seems no mode available */ + XERR("Mode [%dX%d@%fhz] is not valid for sm712!!!\n",xres,yres,VRefresh); + LEAVE(); + } + + XMSG("Okay,mode found:index = %d\n",index); + + /* program Timing registers */ + + if(crtcPriv->controller) + { + /* PANEL CHANNEL*/ + /* program FPR registers */ + for(index = 0;index < 8;index++) + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x50 + index, timing_pnl->FPR[index]); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x5A, timing_pnl->FPR[0xA]); + + /* program CCR */ + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E, timing_pnl->CCR[0]); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F, timing_pnl->CCR[1]); + } + else + { + /* CRT CHANNEL*/ + + /* program SVR registers */ + for(index = 0;index < 14;index++) + VGAOUT8_INDEX_712(pHw, VGA_CRT_INDEX, VGA_CRT_DATA, 0x40 + index, timing_crt->SVR[index]); + + /* program CRTC30 ,it's just a work around and seems dirty...*/ + + if(yres >= 1024 ){ + tmp = VGAIN8_INDEX_712(pHw,VGA_CRT_INDEX,VGA_CRT_DATA,0x30); + VGAOUT8_INDEX_712(pHw,VGA_CRT_INDEX,VGA_CRT_DATA,0x30,tmp|9); + }else{ + tmp = VGAIN8_INDEX_712(pHw,VGA_CRT_INDEX,VGA_CRT_DATA,0x30); + VGAOUT8_INDEX_712(pHw,VGA_CRT_INDEX,VGA_CRT_DATA,0x30,tmp&~9); + } + + /* program CCR */ + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C, timing_crt->CCR[0]); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D, timing_crt->CCR[1]); + } + pSmi->psSetMode(pScrn,mode); + /* program color depth */ + SMILynx_CrtcVideoInit_crt(crtc); + + /* program fb offset and pitch stuff ... */ + SMI712_CrtcAdjustFrame(crtc,x,y); + LEAVE(); + +} + + +static void SMILynx_CrtcModeSet_vga(xf86CrtcPtr crtc, + DisplayModePtr mode, + DisplayModePtr adjusted_mode, + int x, int y) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pSmi->pHardware; + SMI712RegPtr reg = p712Hw->pRegMode; + vgaHWPtr hwp = VGAHWPTR(pScrn); + int vgaIOBase = hwp->IOBase; + int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; + int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; + vgaRegPtr vganew = &hwp->ModeReg; + + ENTER(); + + /* Initialize Video Processor Registers */ + + SMICRTC(crtc)->video_init(crtc); + SMILynx_CrtcAdjustFrame(crtc, x,y); + + + /* Program the PLL */ + + /* calculate vclk1 */ + if (SMI_LYNX_SERIES(pHw->Chipset)) { + SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock, + 1, 1, 63, 0, 3, + pSmi->clockRanges->minClock, + pSmi->clockRanges->maxClock, + ®->SR6C, ®->SR6D); + } else { + SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock, + 1, 1, 63, 0, 1, + pSmi->clockRanges->minClock, + pSmi->clockRanges->maxClock, + ®->SR6C, ®->SR6D); + } + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C, reg->SR6C); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D, reg->SR6D); + + + /* Adjust mode timings */ + + if (!vgaHWInit(pScrn, mode)) { + LEAVE(); + } + + if ((mode->HDisplay == 640) && IS_OLDLYNX(pSmi)) { + vganew->MiscOutReg &= ~0x0C; + } else { + vganew->MiscOutReg |= 0x0C; + } + vganew->MiscOutReg |= 0x20; + + { + uint32_t HTotal=(mode->CrtcHTotal>>3)-5; + uint32_t HBlankEnd=(mode->CrtcHBlankEnd>>3)-1; + uint32_t VTotal=mode->CrtcVTotal-2; + uint32_t VDisplay=mode->CrtcVDisplay-1; + uint32_t VBlankStart=mode->CrtcVBlankStart-1; + uint32_t VBlankEnd=mode->CrtcVBlankEnd-1; + uint32_t VSyncStart=mode->CrtcVSyncStart; + + /* Fix HBlankEnd/VBlankEnd */ + if((mode->CrtcHBlankEnd >> 3) == (mode->CrtcHTotal >> 3)) HBlankEnd=0; + if(mode->CrtcVBlankEnd == mode->CrtcVTotal) VBlankEnd=0; + + vganew->CRTC[3] = (vganew->CRTC[3] & ~0x1F) | (HBlankEnd & 0x1F); + vganew->CRTC[5] = (vganew->CRTC[5] & ~0x80) | (HBlankEnd & 0x20) >> 5 << 7; + vganew->CRTC[22] = VBlankEnd & 0xFF; + + /* Write the overflow from several VGA registers */ + reg->CR30 = (VTotal & 0x400) >> 10 << 3 | + (VDisplay & 0x400) >> 10 << 2 | + (VBlankStart & 0x400) >> 10 << 1 | + (VSyncStart & 0x400) >> 10 << 0; + + if(pHw->Chipset == SMI_LYNX3DM) + reg->CR30 |= (HTotal & 0x100) >> 8 << 6; + + reg->CR33 = (HBlankEnd & 0xC0) >> 6 << 5 | (VBlankEnd & 0x300) >> 8 << 3; + } + + vgaHWRestore(pScrn, vganew, VGA_SR_MODE); + + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x30, reg->CR30); + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x33, reg->CR33); + + LEAVE(); +} + +static void +SMILynx_CrtcModeSet_crt(xf86CrtcPtr crtc, + DisplayModePtr mode, + DisplayModePtr adjusted_mode, + int x, int y) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pSmi->pHardware; + SMI712RegPtr reg = p712Hw->pRegMode; + vgaHWPtr hwp = VGAHWPTR(pScrn); + int vgaIOBase = hwp->IOBase; + int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; + int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; + int i; + + ENTER(); + + /* Initialize Video Processor Registers */ + + SMILynx_CrtcVideoInit_crt(crtc); + SMILynx_CrtcAdjustFrame(crtc, x,y); + + + /* Program the PLL */ + + /* calculate vclk1 */ + if (SMI_LYNX_SERIES(pHw->Chipset)) { + SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock, + 1, 1, 63, 0, 3, + pSmi->clockRanges->minClock, + pSmi->clockRanges->maxClock, + ®->SR6C, ®->SR6D); + } else { + SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock, + 1, 1, 63, 0, 1, + pSmi->clockRanges->minClock, + pSmi->clockRanges->maxClock, + ®->SR6C, ®->SR6D); + } + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C, reg->SR6C); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D, reg->SR6D); + + + /* Adjust mode timings */ + /* In virtual refresh mode, the CRT timings are controlled through + the shadow VGA registers */ + + { + uint32_t HTotal=(mode->CrtcHTotal>>3)-5; + uint32_t HDisplay=(mode->CrtcHDisplay>>3)-1; + uint32_t HBlankStart=(mode->CrtcHBlankStart>>3)-1; + uint32_t HBlankEnd=(mode->CrtcHBlankEnd>>3)-1; + uint32_t HSyncStart=mode->CrtcHSyncStart>>3; + uint32_t HSyncEnd=mode->CrtcHSyncEnd>>3; + uint32_t VTotal=mode->CrtcVTotal-2; + uint32_t VDisplay=mode->CrtcVDisplay-1; + uint32_t VBlankStart=mode->CrtcVBlankStart-1; + uint32_t VBlankEnd=mode->CrtcVBlankEnd-1; + uint32_t VSyncStart=mode->CrtcVSyncStart; + uint32_t VSyncEnd=mode->CrtcVSyncEnd; + + /* Fix HBlankEnd/VBlankEnd */ + if((mode->CrtcHBlankEnd >> 3) == (mode->CrtcHTotal >> 3)) HBlankEnd=0; + if(mode->CrtcVBlankEnd == mode->CrtcVTotal) VBlankEnd=0; + + reg->CR40 [0x0] = HTotal & 0xFF; + reg->CR40 [0x1] = HBlankStart & 0xFF; + reg->CR40 [0x2] = HBlankEnd & 0x1F; + reg->CR40 [0x3] = HSyncStart & 0xFF; + reg->CR40 [0x4] = (HBlankEnd & 0x20) >> 5 << 7 | + (HSyncEnd & 0x1F); + reg->CR40 [0x5] = VTotal & 0xFF; + reg->CR40 [0x6] = VBlankStart & 0xFF; + reg->CR40 [0x7] = VBlankEnd & 0xFF; + reg->CR40 [0x8] = VSyncStart & 0xFF; + reg->CR40 [0x9] = VSyncEnd & 0x0F; + reg->CR40 [0xA] = (VSyncStart & 0x200) >> 9 << 7 | + (VDisplay & 0x200) >> 9 << 6 | + (VTotal & 0x200) >> 9 << 5 | + (VBlankStart & 0x100) >> 8 << 3 | + (VSyncStart & 0x100) >> 8 << 2 | + (VDisplay & 0x100) >> 8 << 1 | + (VTotal & 0x100) >> 8 << 0; + reg->CR40 [0xB] = ((mode->Flags & V_NVSYNC)?1:0) << 7 | + ((mode->Flags & V_NHSYNC)?1:0) << 6 | + (VBlankStart & 0x200) >> 9 << 5; + reg->CR40 [0xC] = HDisplay & 0xFF; + reg->CR40 [0xD] = VDisplay & 0xFF; + + reg->CR30 = (VTotal & 0x400) >> 10 << 3 | + (VDisplay & 0x400) >> 10 << 2 | + (VBlankStart & 0x400) >> 10 << 1 | + (VSyncStart & 0x400) >> 10 << 0; + + if(pHw->Chipset == SMI_LYNX3DM) + reg->CR30 |= (HTotal & 0x100) >> 8 << 6; + + reg->CR33 = (HBlankEnd & 0xC0) >> 6 << 5 | (VBlankEnd & 0x300) >> 8 << 3; + + } + + /* Select primary set of shadow registers */ + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x9E, reg->CR90[0xE] & ~0x20); + + for(i=0; i <= 0xD; i++) + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x40 + i, reg->CR40[i]); + + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x30, reg->CR30); + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x33, reg->CR33); + + LEAVE(); +} + +static void +SMILynx_CrtcModeSet_lcd(xf86CrtcPtr crtc, + DisplayModePtr mode, + DisplayModePtr adjusted_mode, + int x, int y) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pSmi->pHardware; + SMI712RegPtr reg = p712Hw->pRegMode; + + ENTER(); + + /* Initialize the flat panel video processor */ + + SMILynx_CrtcVideoInit_lcd(crtc); + SMILynx_CrtcAdjustFrame(crtc,x,y); + + + /* Program the PLL */ + + /* calculate vclk2 */ + if (SMI_LYNX_SERIES(pHw->Chipset)) { + SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock, + 1, 1, 63, 0, 0, + pSmi->clockRanges->minClock, + pSmi->clockRanges->maxClock, + ®->SR6E, ®->SR6F); + } else { + SMI_CommonCalcClock(pScrn->scrnIndex, adjusted_mode->Clock, + 1, 1, 63, 0, 1, + pSmi->clockRanges->minClock, + pSmi->clockRanges->maxClock, + ®->SR6E, ®->SR6F); + } + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E, reg->SR6E); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F, reg->SR6F); + + + /* Adjust mode timings */ + { + uint32_t HTotal=(mode->CrtcHTotal>>3)-1; + uint32_t HDisplay=(mode->CrtcHDisplay>>3)-1; + uint32_t HSyncStart=(mode->CrtcHSyncStart>>3); + uint32_t HSyncWidth=((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) >> 3) - 1; + uint32_t VTotal=mode->CrtcVTotal-1; + uint32_t VDisplay=mode->CrtcVDisplay-1; + uint32_t VSyncStart=mode->CrtcVSyncStart-1; + uint32_t VSyncWidth=mode->CrtcVSyncEnd - mode->CrtcVSyncStart - 1; + + reg->SR50 = (VTotal & 0x700) >> 8 << 1 | + (HSyncStart & 0x100) >> 8 << 0; + reg->SR51 = (VSyncStart & 0x700) >> 8 << 5 | + (VDisplay & 0x700) >> 8 << 2 | + (HDisplay & 0x100) >> 8 << 1 | + (HTotal & 0x100) >> 8 << 0; + reg->SR52 = HTotal & 0xFF; + reg->SR53 = HDisplay & 0xFF; + reg->SR54 = HSyncStart & 0xFF; + reg->SR55 = VTotal & 0xFF; + reg->SR56 = VDisplay & 0xFF; + reg->SR57 = VSyncStart & 0xFF; + reg->SR5A = (HSyncWidth & 0x1F) << 3 | + (VSyncWidth & 0x07) << 0; + + /* XXX - Why is the polarity hardcoded here? */ + reg->SR32 &= ~0x18; + if (mode->HDisplay == 800) { + reg->SR32 |= 0x18; + } + if ((mode->HDisplay == 1024) && IS_OLDLYNX(pSmi)) { + reg->SR32 |= 0x18; + } + } + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32, reg->SR32); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x50, reg->SR50); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x51, reg->SR51); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x52, reg->SR52); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x53, reg->SR53); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x54, reg->SR54); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x55, reg->SR55); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x56, reg->SR56); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x57, reg->SR57); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x5A, reg->SR5A); + + LEAVE(); +} + +static void +SMILynx_CrtcModeSet_bios(xf86CrtcPtr crtc, + DisplayModePtr mode, + DisplayModePtr adjusted_mode, + int x, int y) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pSmi->pHardware; + SMI712RegPtr reg = p712Hw->pRegMode; + int i; + CARD8 tmp; + + ENTER(); + + /* Find the INT 10 mode number */ + { + static struct { + int x, y, bpp; + CARD16 mode; + } modeTable[] = + { + { 640, 480, 8, 0x50 }, + { 640, 480, 16, 0x52 }, + { 640, 480, 24, 0x53 }, + { 640, 480, 32, 0x54 }, + { 800, 480, 8, 0x4A }, + { 800, 480, 16, 0x4C }, + { 800, 480, 24, 0x4D }, + { 800, 600, 8, 0x55 }, + { 800, 600, 16, 0x57 }, + { 800, 600, 24, 0x58 }, + { 800, 600, 32, 0x59 }, + { 1024, 768, 8, 0x60 }, + { 1024, 768, 16, 0x62 }, + { 1024, 768, 24, 0x63 }, + { 1024, 768, 32, 0x64 }, + { 1280, 1024, 8, 0x65 }, + { 1280, 1024, 16, 0x67 }, + { 1280, 1024, 24, 0x68 }, + { 1280, 1024, 32, 0x69 }, + }; + + reg->mode = 0; + for (i = 0; i < sizeof(modeTable) / sizeof(modeTable[0]); i++) + { + if ((modeTable[i].x == mode->HDisplay) && + (modeTable[i].y == mode->VDisplay) && + (modeTable[i].bpp == pScrn->bitsPerPixel)) { + reg->mode = modeTable[i].mode; + break; + } + } + } + + if(!reg->mode){ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SMILynx_CrtcModeSet_bios: Not a known BIOS mode: " + "falling back to direct modesetting.\n"); + SMILynx_CrtcModeSet_vga(crtc,mode,adjusted_mode,x,y); + LEAVE(); + } + + pSmi->pInt10->num = 0x10; + pSmi->pInt10->ax = reg->mode | 0x80; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%02X\n", + reg->mode); + xf86ExecX86int10(pSmi->pInt10); + +#if 0 + pSmi->pInt10->num = 0x10; + pSmi->pInt10->ax = 0x5f03; + pSmi->pInt10->bx = 0x0; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%02X\n",reg->mode); + xf86ExecX86int10(pSmi->pInt10); +#endif + + + /* Enable linear mode. */ + outb(pHw->PIOBase + VGA_SEQ_INDEX, 0x18); + tmp = inb(pHw->PIOBase + VGA_SEQ_DATA); + outb(pHw->PIOBase + VGA_SEQ_DATA, tmp | 0x01); + + /* Enable DPR/VPR registers. */ + tmp = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, tmp & ~0x03); + + + /* Initialize Video Processor Registers */ + + SMICRTC(crtc)->video_init(crtc); + SMILynx_CrtcAdjustFrame(crtc, x,y); + + LEAVE(); +} + +static void +SMILynx_CrtcLoadLUT_crt(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pSmi->pHardware; + SMI712RegPtr mode = p712Hw->pRegMode; + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + int i; + + ENTER(); + + /* Write CRT RAM only */ + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX,VGA_SEQ_DATA,0x66,(mode->SR66 & ~0x30) | 0x20); + + for(i=0;i<256;i++){ + VGAOUT8_712(pHw, VGA_DAC_WRITE_ADDR, i); + VGAOUT8_712(pHw, VGA_DAC_DATA, crtcPriv->lut_r[i] >> 8); + VGAOUT8_712(pHw, VGA_DAC_DATA, crtcPriv->lut_g[i] >> 8); + VGAOUT8_712(pHw, VGA_DAC_DATA, crtcPriv->lut_b[i] >> 8); + } + + LEAVE(); +} + +static void +SMILynx_CrtcLoadLUT_lcd(xf86CrtcPtr crtc) +{ + ENTER(); + + /* XXX - Is it possible to load LCD LUT in Virtual Refresh mode? */ + + LEAVE(); +} + +static void +SMILynx_CrtcSetCursorColors_crt (xf86CrtcPtr crtc, int bg, int fg) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + CARD8 packedFG,packedBG; + + ENTER(); + + /* Pack the true color into 8 bit */ + packedFG = (fg & 0xE00000) >> 16 | + (fg & 0x00E000) >> 11 | + (fg & 0x0000C0) >> 6; + packedBG = (bg & 0xE00000) >> 16 | + (bg & 0x00E000) >> 11 | + (bg & 0x0000C0) >> 6; + + /* Program the colors */ + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x8C, packedFG); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x8D, packedBG); + + /* Program FPR copy when on the 730 */ + if (pHw->Chipset == SMI_COUGAR3DR) { + CARD32 fpr15c; + + fpr15c = READ_FPR(pHw, FPR15C) & FPR15C_MASK_HWCADDREN; + fpr15c |= packedFG; + fpr15c |= packedBG << 8; + WRITE_FPR(pHw, FPR15C, fpr15c); + } + + LEAVE(); +} + +static void +SMILynx_CrtcSetCursorPosition_crt (xf86CrtcPtr crtc, int x, int y) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + ENTER(); + + if (x >= 0) { + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x88, + x & 0xFF); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x89, + (x >> 8) & 0x07); + } + else { + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x88, + (-x) & (SMI712_MAX_CURSOR - 1)); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x89, + 0x08); + } + + if (y >= 0) { + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x8A, + y & 0xFF); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x8B, + (y >> 8) & 0x07); + } + else { + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x8A, + (-y) & (SMI712_MAX_CURSOR - 1)); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, + 0x8B, 0x08); + } + + /* Program FPR copy when on the 730 */ + if (pHw->Chipset == SMI_COUGAR3DR) { + CARD32 fpr158; + + if (x >= 0) + fpr158 = (x & FPR158_MASK_MAXBITS) << 16; + else + fpr158 = ((-x & FPR158_MASK_MAXBITS) | + FPR158_MASK_BOUNDARY) << 16; + + if (y >= 0) + fpr158 |= y & FPR158_MASK_MAXBITS; + else + fpr158 |= (-y & FPR158_MASK_MAXBITS) | FPR158_MASK_BOUNDARY; + + /* Program combined coordinates */ + WRITE_FPR(pHw, FPR158, fpr158); + } + + LEAVE(); +} + +static void +SMILynx_CrtcShowCursor_crt (xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + char tmp; + + ENTER(); + + /* Show cursor */ + tmp = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, tmp | 0x80); + + /* Program FPR copy when on the 730 */ + if (pHw->Chipset == SMI_COUGAR3DR) { + CARD32 fpr15c; + + /* turn on the top bit */ + fpr15c = READ_FPR(pHw, FPR15C); + fpr15c |= FPR15C_MASK_HWCENABLE; + WRITE_FPR(pHw, FPR15C, fpr15c); + } + + LEAVE(); +} + +static void +SMILynx_CrtcHideCursor_crt (xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + char tmp; + + ENTER(); + + /* Hide cursor */ + tmp = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, tmp & ~0x80); + + /* Program FPR copy when on the 730 */ + if (pHw->Chipset == SMI_COUGAR3DR) { + CARD32 fpr15c; + + /* turn off the top bit */ + fpr15c = READ_FPR(pHw, FPR15C); + fpr15c &= ~FPR15C_MASK_HWCENABLE; + WRITE_FPR(pHw, FPR15C, fpr15c); + } + + + LEAVE(); +} + +static void +SMILynx_CrtcLoadCursorImage_crt (xf86CrtcPtr crtc, CARD8 *image) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMI712Ptr pSmi712 = (SMI712Ptr)pSmi; + SMIHWPtr pHw = pSmi->pHardware; + CARD8 tmp; + int i; + CARD8* dst; + + ENTER(); + + /* Load storage location. */ + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x80, + pSmi712->FBCursorOffset / 2048); + tmp = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81) & 0x80; + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, + tmp | ((pSmi712->FBCursorOffset / 2048) >> 8)); + + /* Program FPR copy when on the 730 */ + if (pHw->Chipset == SMI_COUGAR3DR) { + CARD32 fpr15c; + + /* put address in upper word, and disable the cursor */ + fpr15c = READ_FPR(pHw, FPR15C) & FPR15C_MASK_HWCCOLORS; + fpr15c |= (pSmi712->FBCursorOffset / 2048) << 16; + WRITE_FPR(pHw, FPR15C, fpr15c); + } + + /* Copy cursor image to framebuffer storage */ + dst = pSmi->pFB + pSmi712->FBCursorOffset; + for(i=0; i < (SMI712_MAX_CURSOR * SMI712_MAX_CURSOR >> 2); i++){ + *(dst++) = image[i]; + if((i & 0x3) == 0x3) dst+=4; + } + + LEAVE(); +} + +static void +SMILynx_CrtcDPMS_crt(xf86CrtcPtr crtc, int mode) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pSmi->pHardware; + SMI712RegPtr reg = p712Hw->pRegMode; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + ENTER(); + + if(mode == DPMSModeOff) + reg->SR21 |= 0x88; /* Disable DAC and color palette RAM */ + else + reg->SR21 &= ~0x88; /* Enable DAC and color palette RAM */ + + /* Wait for vertical retrace */ + while (hwp->readST01(hwp) & 0x8) ; + while (!(hwp->readST01(hwp) & 0x8)) ; + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, reg->SR21); + + if(mode == DPMSModeOn){ + /* Reload the LUT */ + SMILynx_CrtcLoadLUT_crt(crtc); + } + + LEAVE(); +} + +static void +SMILynx_CrtcDPMS_lcd(xf86CrtcPtr crtc, int mode) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pSmi->pHardware; + SMI712RegPtr reg = p712Hw->pRegMode; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + ENTER(); + + if(mode == DPMSModeOff) + reg->SR31 &= ~0x80; /* Disable Virtual Refresh */ + else + reg->SR31 |= 0x80; /* Enable Virtual Refresh */ + + /* Wait for vertical retrace */ + while (hwp->readST01(hwp) & 0x8) ; + while (!(hwp->readST01(hwp) & 0x8)) ; + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, reg->SR31); + + LEAVE(); +} + +/* this routine only handle sm712 chips */ +Bool SMI712_CrtcPreInit(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR(pScrn); + xf86CrtcPtr crtc; + xf86CrtcFuncsPtr crtcFuncs; + SMICrtcPrivatePtr crtcPriv; + + ENTER(); + SMI_CrtcPreInit(pScrn); + /* the first crtc init: CRTC0==>CRT CHANNEL */ + SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv); +// if(!pSmi->useBIOS || pSmi->DualView) + if(1) + { + /* + CRTC0 [CRT channel ] can drive both outputs when virtual refresh is + disabled, and only the 1STCRT output with virtual refresh + enabled. + */ + crtcFuncs->dpms = SMILynx_CrtcDPMS_crt; + crtcFuncs->mode_set = SMI712_ModeSet; + } + else + { + crtcFuncs->mode_set = SMILynx_CrtcModeSet_bios; + } + //crtcFuncs->mode_fixup = SMILynx_CrtcModeFixup; + + crtcPriv->adjust_frame = SMI712_CrtcAdjustFrame; + crtcPriv->video_init = SMILynx_CrtcVideoInit_crt; + crtcPriv->load_lut = SMILynx_CrtcLoadLUT_crt; + crtcPriv->index = 0; //CRTC0 + crtcPriv->controller = 0; //CRT channel for sm712 + + if(! (crtc = xf86CrtcCreate(pScrn,crtcFuncs))) + LEAVE(FALSE); + crtc->driver_private = crtcPriv; + + /* the second crtc init:CRTC1==>LCD CHANNEL */ + + if(pSmi->DualView) + { + SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv); + /* no bios call for dual view */ + crtcFuncs->dpms = SMILynx_CrtcDPMS_lcd; + crtcFuncs->mode_set = SMI712_ModeSet; + + crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame; + crtcPriv->video_init = SMILynx_CrtcVideoInit_lcd; + crtcPriv->load_lut = SMILynx_CrtcLoadLUT_lcd; + crtcPriv->index = 1; //CRTC1 + crtcPriv->controller = 1; //LCD channel for sm712 + + if(! (crtc = xf86CrtcCreate(pScrn,crtcFuncs))) + LEAVE(FALSE); + crtc->driver_private = crtcPriv; + } + + LEAVE(TRUE); + +} + +Bool +SMILynx_CrtcPreInit(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR(pScrn); + xf86CrtcPtr crtc; + xf86CrtcFuncsPtr crtcFuncs; + SMICrtcPrivatePtr crtcPriv; + + ENTER(); + + { + /* CRTC0 can drive both outputs when virtual refresh is + disabled, and only the VGA output with virtual refresh + enabled. */ + SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv); + + /*if(pSmi->useBIOS) + { + crtcFuncs->mode_set = SMILynx_CrtcModeSet_bios; + } + else*/ + { + crtcFuncs->dpms = SMILynx_CrtcDPMS_crt; + + if(pSmi->DualView){ + /* The standard VGA CRTC registers get locked in virtual refresh mode. */ + crtcFuncs->mode_set = SMILynx_CrtcModeSet_crt; + }else{ + crtcFuncs->mode_set = SMILynx_CrtcModeSet_vga; + } + } + + crtcFuncs->mode_fixup = SMILynx_CrtcModeFixup; + crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame; + crtcPriv->video_init = SMILynx_CrtcVideoInit_crt; + crtcPriv->load_lut = SMILynx_CrtcLoadLUT_crt; + + if(0)/*(pSmi->HwCursor)*/{ + crtcFuncs->set_cursor_colors = SMILynx_CrtcSetCursorColors_crt; + crtcFuncs->set_cursor_position = SMILynx_CrtcSetCursorPosition_crt; + crtcFuncs->show_cursor = SMILynx_CrtcShowCursor_crt; + crtcFuncs->hide_cursor = SMILynx_CrtcHideCursor_crt; + crtcFuncs->load_cursor_image = SMILynx_CrtcLoadCursorImage_crt; + } + + if(! (crtc = xf86CrtcCreate(pScrn,crtcFuncs))) + LEAVE(FALSE); + crtc->driver_private = crtcPriv; + + if(pSmi->DualView) + { + /* CRTC1 drives LCD when enabled. */ + SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv); + crtcFuncs->mode_set = SMILynx_CrtcModeSet_lcd; + crtcFuncs->mode_fixup = SMILynx_CrtcModeFixup; + crtcFuncs->dpms = SMILynx_CrtcDPMS_lcd; + crtcPriv->adjust_frame = SMILynx_CrtcAdjustFrame; + crtcPriv->video_init = SMILynx_CrtcVideoInit_lcd; + crtcPriv->load_lut = SMILynx_CrtcLoadLUT_lcd; + + if(! (crtc = xf86CrtcCreate(pScrn,crtcFuncs))) + LEAVE(FALSE); + crtc->driver_private = crtcPriv; + } + } + + LEAVE(TRUE); +} + +#endif /*#if SMI_RANDR*/ + diff --git a/src/drv712/smi_712_driver.c b/src/drv712/smi_712_driver.c new file mode 100644 index 0000000..8b817e1 --- /dev/null +++ b/src/drv712/smi_712_driver.c @@ -0,0 +1,565 @@ +#include "../smi_common.h" +#include "../smi_driver.h" +#include "smi_712_driver.h" +#include "ddk712/ddk712_chip.h" + +static const SMI712HWRec sm712_hwrec = { + .base = { + .pcDeepMap = sm712_pcDeepmap,/* actually,NULL value can be just ignored,gcc will know it*/ + .pcEntityInit = sm712_entityInit, + .pcEntityEnter = sm712_entityEnter, + .pcEntityLeave = sm712_entityLeave, + .pcCloseAllScreen = sm712_closeAllScreen, + .pcFBSize = sm712_totalFB, + .pcInitHardware = sm712_hardwareInit, + }, + +}; + + +static const SMI712Rec sm712_rec = { + .base = { + .minHeight = 128, + .psGetMapResult = sm712_getMapResult, + .psVgaPciInit = sm712_vgaAndpciInit, + .psHandleOptions = sm712_handleOptions, + .psValidMode = sm712_validMode, + .psSetMode = sm712_setMode, + .psAdjustFrame = sm712_adjustFrame, + .psLoadPalette = sm712_LoadPalette, + .psSetDisplay = sm712_setDisplay, + .psSaveText = sm712_saveText, + #if SMI_RANDR + .psCrtcPreInit = SMI712_CrtcPreInit, + .psOutputPreInit = SMI712_OutputPreInit, + .psI2CInit = sm712_I2CInit, + #endif + }, +}; +SMIPtr sm712_genSMI(pointer priv,int entityIndex) +{ + SMIPtr pSmi; +#ifdef XSERVER_LIBPCIACCESS + struct pci_device * pPci; +#else + pciVideoPtr pPci; +#endif + + ENTER(); +#ifdef XSERVER_LIBPCIACCESS + /*what's the difference between 'pScrn->entityList[0]' and 'pEntInfo->index'??*/ + pPci = xf86GetPciInfoForEntity(entityIndex); +#endif + /* pSmi always need create for every screen*/ + pSmi = (SMIPtr)XNFcalloc(sizeof(SMI712Rec)); + memset(pSmi,0, sizeof(SMI712Rec)); + if(pSmi == NULL) + return pSmi; + memcpy(pSmi,&sm712_rec,sizeof(SMI712Rec)); + /*This function is associated with screen + , but maybe two screen belongs to one entity (dualview)*/ + pSmi->pHardware = priv; + + /* if priv is NULL,means we need create a pHw + * below code can handle 2 screen per entity case + * but not work for 3+ screen per entity cases + * */ + if(!pSmi->pHardware) + { + /* + * Allocate an 'Chip'Rec, and hook it into pScrn->driverPrivate. + * pScrn->driverPrivate is initialised to NULL, so we can check if + * the allocation has already been done. + */ + SMI712HWPtr p712Hw; + p712Hw = pSmi->pHardware = (SMIHWPtr)XNFcalloc(sizeof(SMI712HWRec)); + if(pSmi->pHardware == NULL) + LEAVE(NULL); + memcpy(pSmi->pHardware,&sm712_hwrec,sizeof(SMI712HWRec)); + p712Hw->pRegSave = xnfcalloc(sizeof(SMI712RegRec),1); + if(p712Hw->pRegSave == NULL) + LEAVE(NULL); + p712Hw->pRegMode = xnfcalloc(sizeof(SMI712RegRec),1); + if(p712Hw->pRegMode== NULL) + LEAVE(NULL); + + p712Hw->fonts = xalloc(KB(64)); + if(p712Hw->fonts == NULL) + LEAVE(NULL); + + pSmi->pHardware->dual = 1; + pSmi->pHardware->primary_screen_rec = pSmi; + pSmi->screen = 0; +#ifdef XSERVER_LIBPCIACCESS + pSmi->pHardware->devId = pPci->device_id; +#else + pSmi->pHardware->devId = pPci->device; +#endif + if(SMI_712 == pSmi->pHardware->devId) + { + /* Put what you already known into structure */ +#ifdef XSERVER_LIBPCIACCESS + pSmi->pHardware->phyaddr_reg = pPci->regions[0].base_addr + SM712_REG_OFFSET; + pSmi->pHardware->physize_reg = SM712_REG_SIZE; + pSmi->pHardware->phyaddr_mem = pPci->regions[0].base_addr; +#else + pSmi->pHardware->phyaddr_reg = pPci->memBase[0] + SM712_REG_OFFSET; + pSmi->pHardware->physize_reg = SM712_REG_SIZE; + pSmi->pHardware->phyaddr_mem = pPci->memBase[0] ; +#endif + } + else/*if(SMI_722 == pSmi->pHardware->devId)*/ + { + /* Put what you already known into structure */ +#ifdef XSERVER_LIBPCIACCESS + pSmi->pHardware->phyaddr_reg = pPci->regions[0].base_addr; + pSmi->pHardware->physize_reg = SM722_REG_SIZE; + pSmi->pHardware->phyaddr_mem = pPci->regions[0].base_addr + SM722_FB_OFFSET; +#else + pSmi->pHardware->phyaddr_reg = pPci->memBase[0]; + pSmi->pHardware->physize_reg = SM722_REG_SIZE; + pSmi->pHardware->phyaddr_mem = pPci->memBase[0] + SM722_FB_OFFSET; +#endif + } + +#ifdef XSERVER_LIBPCIACCESS + pSmi->pHardware->revId = pPci->revision; + pSmi->pHardware->pPci = pPci; +#endif + }else{ + /* + * pSmi->pHardware is not NULL, which means current entity already + * mallocated a SMIHWPtr structure,so we are in dualview + * mode! + * */ + pSmi->pHardware->dual += 1;/*The total number of screen*/ + pSmi->screen = (pSmi->pHardware->dual)-1;/*The index of screen*/ + } + + LEAVE(pSmi); +} + +void sm712_pcDeepmap(SMIHWPtr pHw) +{ + vgaHWPtr hwp; + SMI712HWPtr p712Hw = (SMI712HWPtr)pHw; + SMIPtr pSmi = HWPSMI(pHw); + ScrnInfoPtr pScrn = SMIPSI(pSmi); + ENTER(); + + ddk712_set_mmio(pHw->pReg,pHw->devId); + switch (pHw->devId) + { + case SMI_712: + pHw->DPRBase = pHw->pReg + 0x008000; + pHw->VPRBase = pHw->pReg + 0x00C000; + pHw->CPRBase = pHw->pReg + 0x00E000; + pHw->IOBase = pHw->pReg + 0x300000; + pHw->DataPortBase = pHw->pReg + 0x100000; + pHw->DataPortSize = 0x200000; + break; + case SMI_722: + pHw->DPRBase = pHw->pReg + 0x000000; + pHw->VPRBase = pHw->pReg + 0x000800; + pHw->CPRBase = pHw->pReg + 0x001000; + pHw->IOBase = pHw->pReg + 0x0C0000; + pHw->DataPortBase = pHw->pReg + 0x100000; + pHw->DataPortSize = 0x100000; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "SM712 chip ID error.\n"); + break; + } + pHw->DCRBase = 0; + pHw->SCRBase = 0; + LEAVE(TRUE); +} + +void sm712_vgaAndpciInit(ScrnInfoPtr pScrn,int entityIndex) +{ + ENTER(); + SMIPtr pSmi = SMIPTR (pScrn); + SMIHWPtr pHw = pSmi->pHardware; + enable_mmio_712(pScrn); + LEAVE(); +} +void sm712_hardwareInit(SMIHWPtr pHw) +{ + ENTER(); + init_parm_712 initParam; + SMIPtr pSmi = HWPSMI(pHw); + SMI712HWPtr p712Hw = (SMI712HWPtr)pHw; + SMI712RegPtr mode = p712Hw->pRegMode; + + initParam.devid = pHw->devId; + + if(pSmi->pci_burst) + initParam.pci_burst = 2; + else + initParam.pci_burst = 0; + + sm712_DetectMCLK(pSmi); + /*130 mhz is the maximum for sm712 BA version*/ + initParam.memClock = pSmi->MCLK; //130*1000000; + + initParam.lcd = LCD712_TFT; + /*In the current stage, it cant get the tft color*/ + initParam.lcd_color.tftColor = 0; + initParam.lcd_color.dstnColor = DSTN_USE_JUMP; + /* Disable DAC and LCD framebuffer r/w operation */ + /*add for mosaic of screen. by ilena*/ + mode->SR21 |= 0xB0; +#if 0 //use it later + if (pSmi->lcd == 2) /* Panel is DSTN */ + mode->SR21 = 0x00; +#endif + ddk712_hw_init(&initParam); + LEAVE(); +} + +void sm712_entityInit(int entIndex,pointer private) +{ + ENTER(); + SMIHWPtr pHw = (SMIHWPtr)private; + SMIPtr pSmi = HWPSMI(pHw); + ddk712_set_mmio(pHw->pReg,pHw->devId); + LEAVE(); +} + +void sm712_DetectMCLK(SMIPtr pSmi ) +{ + double real; + + pSmi->MCLK = 130*1000000;/*130 mhz is the maximum for sm712 BA version*/ + /* MCLK from user settings */ + if (xf86GetOptValFreq(pSmi->Options, OPTION_MCLK, OPTUNITS_MHZ, &real)) + { + if ((int)real <= 120) + pSmi->MCLK = (int)(real * 1000.0); + else + xf86Msg(X_INFO, "Memory Clock %1.3f MHz larger than limit of 120 MHz\n", real); + } + xf86Msg( X_INFO, "MCLK = %1.3f\n", pSmi->MCLK / 1000.0); +} + +/* + * === FUNCTION ====================================================================== + * Name: sm712_entityEnter + * Description: save console's registers + * ===================================================================================== + */ +void sm712_entityEnter(int entIndex,pointer private) +{ + ENTER(); + init_parm_712 initParam; + SMIHWPtr pHw = (SMIHWPtr)private; + SMIPtr pSmi = HWPSMI(pHw); + ScrnInfoPtr pScrn = SMIPSI(pSmi); + initParam.devid = pHw->devId; + + if(pSmi->pci_burst) + initParam.pci_burst = 2; + else + initParam.pci_burst = 1; + + sm712_DetectMCLK(pSmi ); + /*130 mhz is the maximum for sm712 BA version*/ + initParam.memClock = pSmi->MCLK; //130*1000000; + + initParam.lcd = LCD712_TFT; + /*In the current stage, it cant get the tft color*/ + initParam.lcd_color.tftColor = 0; + enable_mmio_712(pScrn); + ddk712_hw_init(&initParam); + LEAVE(); +} + +/* + * === FUNCTION ====================================================================== + * Name: sm712_entityLeave + * Description: restore console's registers + * ===================================================================================== + */ +void sm712_entityLeave(int entIndex,pointer private) +{ + SMIHWPtr pHw = (SMIHWPtr)private; + ScrnInfoPtr pScrn; + SMIPtr pSmi = HWPSMI(pHw); + pScrn = SMIPSI(pSmi); + ENTER(); + if(xf86IsPrimaryPci(pHw->pPci)) + { + /* Restore the registers */ + restore_reg_712((SMIHWPtr)private); + /* Restore the vga fonts */ + sm712_restoreFonts((SMIHWPtr)private); + + // vgaHWUnmapMem(pScrn); + disable_mmio_712(pScrn); + } + LEAVE(); +} +void sm712_saveText(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR (pScrn); + SMIHWPtr pHw = pSmi->pHardware; + ENTER(); + /* This functin called from entity init, + Of course, it is the primary device */ + if(xf86IsPrimaryPci(pSmi->pHardware->pPci)) + { + /* Save the vga fonts */ + sm712_saveFonts(pSmi->pHardware); + /* Save the registers */ + save_reg_712(pSmi->pHardware); + } + LEAVE(); +} + +void sm712_getMapResult(ScrnInfoPtr pScrn) +{ + ENTER(); + vgaHWPtr hwp; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pHw; + + /* set video memory size */ + pSmi->videoRAMBytes = pHw->physize_mem / (pSmi->pHardware->dual); + pScrn->videoRam = (pSmi->videoRAMBytes)>>10;/* kbytes*/ + + /* set pScrn physica address*/ + pScrn->memPhysBase = pHw->phyaddr_mem; + pScrn->memPhysBase += (pSmi->screen) * pSmi->videoRAMBytes; + + /* set OFFSET */ + pScrn->fbOffset = pSmi->FBOffset = pScrn->memPhysBase - pHw->phyaddr_mem; + + xf86Msg(X_INFO, "ilena: getMapResult, use screen[%d],rambytes[%x], offset[%x]\n", pSmi->screen, pSmi->videoRAMBytes,pSmi->FBOffset); + xf86Msg(X_INFO, "ilena: getMapResult, use pMem[%x]\n", pHw->pMem); + + + /* set virtual address */ + pSmi->pFB = pHw->pMem; + pSmi->pFB += (pSmi->screen) * pSmi->videoRAMBytes ; + xf86Msg(X_INFO, "ilena: getMapResult, use pFB[%x]\n", pSmi->pFB); + pSmi->FBReserved = pSmi->videoRAMBytes - 2048; + + if (!pSmi->width) + pSmi->width = pScrn->displayWidth; + if (!pSmi->height) + pSmi->height = pScrn->virtualY; + + pSmi->Bpp = pScrn->bitsPerPixel / 8; + pSmi->Stride = (pSmi->width * pSmi->Bpp + 15) & ~15; + /* set up the fifo reserved space */ + if (VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30) & 0x01) + { /* if DSTN panel selected */ + /* #1074 */ + CARD32 fifoOffset = 0; + fifoOffset |= VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, + 0x46) << 3; + fifoOffset |= VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, + 0x47) << 11; + fifoOffset |= (VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, + 0x49) & 0x1C) << 17; + pSmi->FBReserved = fifoOffset; /* PDR#1074 */ + } + else /* if TFT panel selected */ + { + /* sm712 only handle 4 mega video memory which means + hardware cursor is not suitable for this chip of new arch x server driver */ + pSmi->FBReserved = pSmi->videoRAMBytes; + } + //SMI_DisableVideo (pScrn); + if (pSmi->screen){ + vgaHWGetHWRec(pScrn); + } + hwp = VGAHWPTR (pScrn); + //vgaHWSetStdFuncs(hwp);//tmp by ilena + +if (!pSmi->screen) + { + if (pHw->IOBase != NULL) + vgaHWSetMmioFuncs(hwp, (char*)pHw->pReg, pHw->IOBase - (CARD8*)pHw->pReg); + + vgaHWGetIOBase(hwp);//tmp by ilena + + /* Map the VGA memory when the primary video */ + if (xf86IsPrimaryPci(pHw->pPci)) + { + hwp->MapSize = 0x10000; + if (!vgaHWMapMem(pScrn)) + LEAVE(FALSE); + } + /* vgaCRReg = vgaIOBase + VGA_CRTC_DATA_OFFSET; */ + pHw->PIOBase = hwp->PIOOffset; + } + LEAVE(); +} + +void sm712_handleOptions(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR(pScrn); + ENTER(); + + if (pScrn->depth == 8) + { + pScrn->rgbBits = 6;//why sm712/sm722 couldn't support 8bpp depth? + } + + LEAVE(); +} + +ModeStatus sm712_validMode(ScrnInfoPtr pScrn,DisplayModePtr pMode) +{ + ENTER(); + LEAVE(MODE_OK); +} + +void sm712_setMode(ScrnInfoPtr pScrn,DisplayModePtr pMode) +{ + SMIPtr pSmi = SMIPTR (pScrn); + SMIHWPtr pHw = pSmi->pHardware; + ENTER(); + save_dpr_address(pHw); + + int channel, width, height, hz; + channel = width = height = hz = 0; + if (pSmi->screen == 0)// i'm not sure. by ilena. + channel = 0; + else if (pSmi->screen == 1) + channel = 1; + width = pMode->HDisplay; + height = pMode->VDisplay, + hz = pMode->VRefresh; + + ddk712_setModeTiming(channel, width, height, hz); + LEAVE(); +} + +void sm712_setDisplay(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + ENTER(); + SMIPtr pSmi = SMIPTR (pScrn); + SMIHWPtr pHw = pSmi->pHardware; + display_t channel; + if(!pHw) + return; + if(!pSmi->screen) + channel = PANEL; + else + channel = CRT; + set_display_712(pHw, channel, pScrn, pSmi->FBOffset, mode->HDisplay, mode->VDisplay); + + LEAVE(); +} + +void sm712_adjustFrame(ScrnInfoPtr pScrn,int offset) +{ + ENTER(); + LEAVE(); +} + +void sm712_closeAllScreen(SMIHWPtr pHw) +{ + ENTER(); + LEAVE(); +} + +/* Save vga fonts */ +void sm712_saveFonts(SMIHWPtr pHw) +{ + SMI712HWPtr p712Hw = (SMI712HWPtr)pHw; + + ENTER(); + + /* leave if in graphic mode */ + //if(get_vga_mode_712(pHw) & 0x2) + + memcpy((char *)p712Hw->fonts,(char *)pHw->pMem + KB(0),KB(64)); + + /* not use legency method to access vga fonts , or multi-card will cry */ + + LEAVE(); +} + +void sm712_restoreFonts(SMIHWPtr pHw) +{ + SMI712HWPtr p712Hw = (SMI712HWPtr)pHw; + + ENTER(); + if(p712Hw->fonts) + memcpy((char *)pHw->pMem + KB(0),(char *)p712Hw->fonts,KB(64)); + + /* not use legency method or multi-card cries */ + + LEAVE(); +} +/* + 1. SM712 only support 2M/4M video buffer. + 2. Whatever the video buffer size, SM712 registers is always 4M + 2.2 and start from the video memory + 4M + 3. Video memory and registers is in a continuous space + +*/ +int sm712_totalFB(SMIHWPtr pHw) +{ + ENTER(); + unsigned int total_memory; + unsigned int *ptr; + char tmp; + int err; + + switch(pHw->devId) + { + case SMI_712: + total_memory = MB(4); + break; + case SMI_722: + total_memory = MB(8); + break; + default: + break; + } + LEAVE(total_memory); +} +void sm712_LoadPalette (ScrnInfoPtr pScrn, int numColors, + int *indicies, LOCO * colors, VisualPtr pVisual) +{ + ENTER(); + + SMIPtr pSmi = SMIPTR (pScrn); + int i; + int iRGB; + SMIHWPtr pHw = pSmi->pHardware; + + /* Enable both the CRT and LCD DAC RAM paths, so both palettes are updated */ + if (pHw->devId == SMI_LYNX3DM) + { + CARD8 ccr66; + + ccr66 = VGAIN8_INDEX_712 (pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, CCR66); + ccr66 &= 0x0f; + VGAOUT8_INDEX_712 (pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, CCR66, ccr66); + } + + for (i = 0; i < numColors; i++) + { + /* DEBUG ("pal[%d] = %d %d %d\n", indicies[i], + colors[indicies[i]].red, colors[indicies[i]].green, + colors[indicies[i]].blue);*/ + VGAOUT8_712 (pHw, VGA_DAC_WRITE_ADDR, indicies[i]); + VGAOUT8_712 (pHw, VGA_DAC_DATA, colors[indicies[i]].red); + VGAOUT8_712 (pHw, VGA_DAC_DATA, colors[indicies[i]].green); + VGAOUT8_712 (pHw, VGA_DAC_DATA, colors[indicies[i]].blue); + } + + LEAVE(); +} + +void sm712_I2CInit(ScrnInfoPtr pScrn) +{ + ENTER(); + LEAVE(); +} diff --git a/src/drv712/smi_712_driver.h b/src/drv712/smi_712_driver.h new file mode 100644 index 0000000..dcef4c1 --- /dev/null +++ b/src/drv712/smi_712_driver.h @@ -0,0 +1,98 @@ +#ifndef SMI_712_INC +#define SMI_712_INC + +#include "../smi_common.h" +#include "ddk712/ddk712_mode.h" +#include "ddk712/ddk712_chip.h" +#include "smi_712_hw.h" +#include "../smi_dbg.h" + +/* Maximum hardware cursor dimensions */ +#define SMI712_MAX_CURSOR 32 + +#define SM712_REG_OFFSET 0x400000 +#define SM712_REG_SIZE 0x400000 +#define SM722_FB_OFFSET 0x200000 +#define SM722_REG_SIZE 0x200000 + +typedef struct +{ + CARD16 h_res; + CARD16 v_res; + CARD16 vsync; //vertical refresh rate:only 60,75,85 is valid for sm712 + CARD8 SVR[14]; //shadow vga register:svr40==>svr4d + CARD8 CCR[2]; //clock control register: ccr6c ccr6d +}SMI712CrtTiming,*SMI712CrtTimingPtr; + +typedef struct +{ + CARD16 h_res; + CARD16 v_res; + CARD16 vsync; + CARD8 FPR[14]; //FPR50 => FPR57 + FPR 5A + CARD8 CCR[2]; //CCR6E && CCR6F +}SMI712PnlTiming,*SMI712PnlTimingPtr; + +typedef struct +{ + int x, y, bpp; + CARD16 mode; +}modeTable_t; + + + +typedef struct { + /* put common structure here */ + SMIHWRec base; + /* put chip dependent stuffs here*/ + SMI712RegPtr pRegSave; + /* */ + SMI712RegPtr pRegMode; + Bool ModeStructInit; /* Flag indicating ModeReg has been duped from console state */ + + /* vga stuffs */ + char * fonts; + CARD8 SR18Value; /* PDR#521: original SR18 + value */ + CARD8 SR21Value; /* PDR#521: original SR21 + value */ +}SMI712HWRec,*SMI712HWPtr; + +typedef struct { + /* we best put base in header of structure*/ + SMIRec base; + /* chip dependent stuffs of this pSmi*/ + int csc;/* use csc video or not */ + /* cursor offset for old lynx serials */ + CARD32 FBCursorOffset; /* Cursor storage location */ +}SMI712Rec,*SMI712Ptr; + + +SMIPtr sm712_genSMI(pointer priv,int); +void sm712_vgaAndpciInit(ScrnInfoPtr pScrn,int entityIndex); +void sm712_hardwareInit(SMIHWPtr pHw); +void sm712_entityInit(int,pointer); +void sm712_DetectMCLK(SMIPtr pSmi ); +void sm712_entityEnter(int,pointer); +void sm712_entityLeave(int,pointer); +void sm712_getMapResult(ScrnInfoPtr); +void sm712_handleOptions(ScrnInfoPtr); +ModeStatus sm712_validMode(ScrnInfoPtr,DisplayModePtr); +void sm712_LoadPalette (ScrnInfoPtr , int , int *, LOCO * , VisualPtr ); +void sm712_setMode(ScrnInfoPtr,DisplayModePtr); +void sm712_adjustFrame(ScrnInfoPtr,int); +void sm712_setDisplay(ScrnInfoPtr pScrn, DisplayModePtr mode); +void sm712_pcDeepmap(SMIHWPtr pHw); +void sm712_saveText(ScrnInfoPtr pScrn); +void sm712_saveFonts(SMIHWPtr pHw); +void sm712_restoreFonts(SMIHWPtr pHw); +void sm712_closeAllScreen(SMIHWPtr pHw); +int sm712_totalFB(SMIHWPtr pHw); + +extern void ddk712_set_mmio(volatile unsigned char * addr,int devid); +extern void ddk712_hw_init(init_parm_712 * param); +extern void ddk712_setModeTiming(int channel,int x,int y,int hz); +extern Bool SMI712_CrtcPreInit(ScrnInfoPtr pScrn); +extern Bool SMI712_OutputPreInit(ScrnInfoPtr pScrn); +void sm712_I2CInit(ScrnInfoPtr pScrn); +#endif /* ----- #ifndef SMI_712_INC -----*/ diff --git a/src/drv712/smi_712_hw.c b/src/drv712/smi_712_hw.c new file mode 100644 index 0000000..5e5a43a --- /dev/null +++ b/src/drv712/smi_712_hw.c @@ -0,0 +1,558 @@ +#include "smi_712_hw.h" +#include "smi_712_driver.h" + +static int saved_console_reg = -1; +__inline__ CARD8 +VGAIN8_INDEX_712(SMIHWPtr pHw, int indexPort, int dataPort, CARD8 index) +{ + if (0)//pSmi->IOBase) + { + MMIO_OUT8(pHw->IOBase, indexPort, index); + return(MMIO_IN8(pHw->IOBase, dataPort)); + } + else + { + outb(pHw->PIOBase + indexPort, index); + return(inb(pHw->PIOBase + dataPort)); + } +} +__inline__ void +VGAOUT8_INDEX_712(SMIHWPtr pHw, int indexPort, int dataPort, CARD8 index, CARD8 data) +{ + if (0)//pSmi->IOBase) + { + MMIO_OUT8(pHw->IOBase, indexPort, index); + MMIO_OUT8(pHw->IOBase, dataPort, data); + } + else + { + outb(pHw->PIOBase+ indexPort, index); + outb(pHw->PIOBase+ dataPort, data); + } +} + +__inline__ CARD8 +VGAIN8_712(SMIHWPtr pHw, int port) //ilena: need change for 718 +{ + if (0)//pSmi->IOBase) + { + return(MMIO_IN8(pHw->IOBase, port)); + } + else + { + return(inb(pHw->PIOBase + port)); + } +} + +__inline__ void +VGAOUT8_712(SMIHWPtr pHw, int port, CARD8 data) +{ + if (0)//pSmi->IOBase) + { + MMIO_OUT8(pHw->IOBase, port, data); + } + else + { + outb(pHw->PIOBase, data); + } +} +void enable_mmio_712(ScrnInfoPtr pScrn) +{ + CARD8 tmp; + ENTER(); + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pHw; + + vgaHWPtr hwp = VGAHWPTR(pScrn); + + vgaHWSetStdFuncs(hwp); + /* Enable linear mode */ + outb(pHw->PIOBase + VGA_SEQ_INDEX, SCR18); + tmp = inb(pHw->PIOBase + VGA_SEQ_DATA); + p712Hw->SR18Value = tmp; + /* !!To enable MMIO the following must be set prior to setting SCR18[0]: SCR17[1] = 1!! */ + /* Before enable the SCR18[0], all MMIO cant access*/ + /* So, enable the SCR18[0] by IO access first! */ + outb(pHw->PIOBase + VGA_SEQ_DATA, tmp | 0x11); + + /* Enable 2D/3D Engine and Video Processor */ + outb(pHw->PIOBase + VGA_SEQ_INDEX, PDR21); + tmp = inb(pHw->PIOBase + VGA_SEQ_DATA); + p712Hw->SR21Value = tmp; + outb(pHw->PIOBase + VGA_SEQ_DATA, tmp & ~0x03); + LEAVE(); +} + +void +disable_mmio_712(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR(pScrn); + SMI712HWPtr p712Hw = (SMI712HWPtr)(pSmi->pHardware); + SMIHWPtr pHw = pSmi->pHardware; + ENTER(); + + vgaHWPtr hwp = VGAHWPTR(pScrn); + + vgaHWSetStdFuncs(hwp); + + /* Disable 2D/3D Engine and Video Processor */ + outb(pHw->PIOBase + VGA_SEQ_INDEX, PDR21); + outb(pHw->PIOBase + VGA_SEQ_DATA, p712Hw->SR21Value); /* PDR#521 */ + + /* Disable linear mode */ + outb(pHw->PIOBase + VGA_SEQ_INDEX, SCR18); + outb(pHw->PIOBase + VGA_SEQ_DATA, p712Hw->SR18Value); /* PDR#521 */ + + LEAVE(); +} + +void set_display_712(SMIHWPtr pHw,display_t channel, ScrnInfoPtr pScrn, uint32_t offset, int x, int y) +{ + ENTER(); + SMI712HWPtr p712Hw = (SMI712HWPtr)pHw; + SMIPtr pSmi = SMIPTR(pScrn); + SMI712Ptr pSmi712 = (SMI712Ptr)pSmi; + SMI712RegPtr mode = p712Hw->pRegMode; + + CARD8 tmp; + CARD32 Pitch,Width; + CARD32 Base; + + + /* Scratch Pad Register 1 */ + tmp = 0; + tmp = VGAIN8_INDEX_712(pHw,VGA_SEQ_INDEX,VGA_SEQ_DATA,GPR70); + XERR("MONK,GET 3C4:70 == %02x\n",tmp); + tmp &= 0x0f; + tmp |= 0x50; + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, GPR70, tmp); + XERR("MONK,after set ,GET 3C4:70 == %02x\n",VGAIN8_INDEX_712(pHw,VGA_SEQ_INDEX,VGA_SEQ_DATA,GPR70)); + + tmp = 0; + Pitch = (pScrn->displayWidth * pSmi->Bpp); /* it == pixel unit divided with 8 */ + Width = (x * pSmi->Bpp); /* as caculated like pitch */ + + /* set the TFT color */ + tmp = VGAIN8_INDEX_712(pHw,VGA_SEQ_INDEX,VGA_SEQ_DATA,FPR30)&0x8f; + VGAOUT8_INDEX_712(pHw,VGA_SEQ_INDEX,VGA_SEQ_DATA,FPR30,tmp | (pSmi->TFTColor<<4)); + + switch (pScrn->bitsPerPixel) + { + case 8: + WRITE_VPR(pHw, 0x00, 0x00000000); + break; + case 16: + WRITE_VPR(pHw, 0x00, 0x00020000); + break; + case 24: + WRITE_VPR(pHw, 0x00, 0x00040000); + break; + case 32: + WRITE_VPR(pHw, 0x00, 0x00030000); + break; + } + + Base = offset + (pScrn->frameX0 + pScrn->frameY0* pScrn->displayWidth) * pSmi->Bpp; + if(pHw->devId == SMI_LYNX3DM) + { + Base = (Base + 15) & ~15; + while ((Base % pSmi->Bpp) > 0) + Base -= 16; + }else + { + Base = (Base + 7) & ~7; + while ((Base % pSmi->Bpp) > 0) + Base -= 8; + } + Base >>= 3; + Width >>= 3; + Pitch >>= 3; + + if((pHw->dual > 1)&&(channel == PANEL)) + { + /* LCD channel pitch and base address */ + CARD8 SR40,SR41,SR42,SR43,SR45; + XERR("LCD and CRT double head"); + /* FIFO1 read start address */ + SR40 = Base & 0x000000FF; + SR41 = (Base & 0x0000FF00) >> 8; + + /* FIFO2 read start address */ + SR42 = Base & 0x000000FF; + SR43 = (Base & 0x0000FF00) >> 8; + + /* FIFO1/2 read start address overflow */ + if(pHw->Chipset == SMI_LYNX3DM) + SR45 = (Base & 0x000F0000) >> 16 | (Base & 0x000F0000) >> 16 << 4; + else + SR45 = (SR45 & 0xC0) | + (Base & 0x00070000) >> 16 | (Base & 0x00070000) >> 16 << 3; + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, FPR40, SR40); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, FPR41, SR41); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, FPR42, SR42); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, FPR43, SR43); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, FPR45, SR45); + + /* Offset of LCD channel*/ + SR45 = (SR45 & 0x3f)|((Pitch & 0x300 ) >> 2); + VGAOUT8_INDEX_712(pHw,VGA_SEQ_INDEX,VGA_SEQ_DATA,FPR44,Pitch & 0xff); + VGAOUT8_INDEX_712(pHw,VGA_SEQ_INDEX,VGA_SEQ_DATA,FPR45,SR45); + + /* For create dual view mode, it will be clone without following statement */ + VGAOUT8_INDEX_712(pHw,VGA_SEQ_INDEX,VGA_SEQ_DATA,PDR21,0x20);/**/ + VGAOUT8_INDEX_712(pHw,VGA_SEQ_INDEX,VGA_SEQ_DATA,FPR31,0xc3);/*0xC0 for clone mode*/ + } + else if((channel == CRT)||(pHw->dual <= 1)) + { + /* CRT and single head */ + XERR("CRT and single head"); + WRITE_VPR(pHw, 0x0C, Base); + WRITE_VPR(pHw,0x10,(Width<<16)|(Pitch&0xffff)); + } + if(pHw->Chipset == SMI_LYNX3DM) + { + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, PDR22, 0x0); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, FPR31, 0x2); + } + LEAVE(); +} +int get_vga_mode_712(SMIHWPtr pHw) +{ + return 0; +// return peek32(0x88); +} + +void save_dpr_address(SMIHWPtr pHw) +{ + +} + +/* + * This function performs the inverse of the restore function: It saves all the + * standard and extended registers that we are going to modify to set up a video + * mode. + */ +void save_reg_712 (SMIHWPtr pHw) +{ + ENTER(); + ScrnInfoPtr pScrn; + SMIPtr pSmi = HWPSMI(pHw); + pScrn = SMIPSI(pSmi); + CARD8 tmp; + + vgaHWPtr hwp = VGAHWPTR (pScrn); + vgaRegPtr vgaSavePtr = &hwp->SavedReg; + SMI712HWPtr p712Hw = (SMI712HWPtr)pHw; + SMI712RegPtr save = p712Hw->pRegSave; + + vgaHWSetStdFuncs(hwp); + vgaHWGetIOBase(hwp); + + int i; + CARD32 offset; + int vgaIOBase = hwp->IOBase; + int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; + int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; + + /* Save the standard VGA registers */ + vgaHWSave(pScrn, vgaSavePtr, VGA_SR_ALL); + save->smiDACMask = VGAIN8_712(p712Hw, VGA_DAC_MASK); + VGAOUT8_712(pHw, VGA_DAC_READ_ADDR, 0); + for (i = 0; i < 256; i++) { + save->smiDacRegs[i][0] = VGAIN8_712(p712Hw, VGA_DAC_DATA); + save->smiDacRegs[i][1] = VGAIN8_712(p712Hw, VGA_DAC_DATA); + save->smiDacRegs[i][2] = VGAIN8_712(p712Hw, VGA_DAC_DATA); + } + + /* Save Fonts */ + for (i = 0, offset = 2; i < 8192; i++, offset += 8) + save->smiFont[i] = *((unsigned char *)(pSmi->pHardware->pMem) + offset); + + /* Now we save all the extended registers we need. */ + save->SR17 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17); + save->SR18 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18); + + save->SR20 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20); + save->SR21 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, PDR21); + save->SR22 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, PDR22); + save->SR23 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23); + save->SR24 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24); + + save->SR31 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, FPR31); + save->SR32 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, FPR32); + + save->SR66 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, CCR66); + save->SR68 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68); + save->SR69 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69); + save->SR6A = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A); + save->SR6B = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B); + save->SR6C = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C); + save->SR6D = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D); + + save->SR81 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81); + save->SRA0 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, FPRA0); + +#if 1 + //if (pSmi->DualView) + { + /* dualhead stuff */ + save->SR40 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x40); + save->SR41 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x41); + save->SR42 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x42); + save->SR43 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x43); + save->SR44 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x44); + save->SR45 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45); + save->SR48 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x48); + save->SR49 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49); + save->SR4A = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4A); + save->SR4B = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4B); + save->SR4C = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4C); + + save->SR50 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x50); + save->SR51 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x51); + save->SR52 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x52); + save->SR53 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x53); + save->SR54 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x54); + save->SR55 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x55); + save->SR56 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x56); + save->SR57 = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x57); + save->SR5A = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x5A); + + /* PLL2 stuff */ + save->SR6E = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E); + save->SR6F = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F); + } +#endif + /* note the judgement ,monk */ + { + /* Save common registers */ + save->CR30 = VGAIN8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x30); + save->CR3A = VGAIN8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x3A); + for (i = 0; i < 15; i++) { + save->CR90[i] = VGAIN8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x90 + i); + } + for (i = 0; i < 14; i++) { + save->CRA0[i] = VGAIN8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0xA0 + i); + } + + /* Save primary registers */ + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14] & ~0x20); + + save->CR33 = VGAIN8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x33); + for (i = 0; i < 14; i++) { + save->CR40[i] = VGAIN8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x40 + i); + } + save->CR9F = VGAIN8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x9F); + + /* Save secondary registers */ + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14] | 0x20); + save->CR33_2 = VGAIN8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x33); + for (i = 0; i < 14; i++) { + save->CR40_2[i] = VGAIN8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x40 + i); + } + save->CR9F_2 = VGAIN8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x9F); + + /* PDR#1069 */ + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14]); + } + + save->DPR10 = READ_DPR(pHw, 0x10); + save->DPR1C = READ_DPR(pHw, 0x1C); + save->DPR20 = READ_DPR(pHw, 0x20); + save->DPR24 = READ_DPR(pHw, 0x24); + save->DPR28 = READ_DPR(pHw, 0x28); + save->DPR2C = READ_DPR(pHw, 0x2C); + save->DPR30 = READ_DPR(pHw, 0x30); + save->DPR3C = READ_DPR(pHw, 0x3C); + save->DPR40 = READ_DPR(pHw, 0x40); + save->DPR44 = READ_DPR(pHw, 0x44); + + save->VPR00 = READ_VPR(pHw, 0x00); + save->VPR0C = READ_VPR(pHw, 0x0C); + save->VPR10 = READ_VPR(pHw, 0x10); + + save->CPR00 = READ_CPR(pHw, 0x00); + + vgaHWCopyReg(&hwp->ModeReg, vgaSavePtr); + + LEAVE(); +} + +/* + * This function is used to restore a video mode. It writes out all of the + * standard VGA and extended registers needed to setup a video mode. + */ +void restore_reg_712(SMIHWPtr pHw) +{ + ENTER(); + ScrnInfoPtr pScrn; + SMIPtr pSmi = HWPSMI(pHw); + pScrn = SMIPSI(pSmi); + + vgaHWPtr hwp = VGAHWPTR (pScrn); + vgaRegPtr vgaSavePtr = &hwp->SavedReg; + SMI712HWPtr p712Hw = (SMI712HWPtr)pHw; + SMI712RegPtr restore = p712Hw->pRegSave; + + int i; + CARD8 tmp; + CARD32 offset; + int vgaIOBase = hwp->IOBase; + int vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET; + int vgaCRData = vgaIOBase + VGA_CRTC_DATA_OFFSET; + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17, restore->SR17); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18, restore->SR18); + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20, restore->SR20); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, PDR21, restore->SR21); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, PDR22, restore->SR22); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23, restore->SR23); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24, restore->SR24); + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, FPR31, restore->SR31); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, FPR32, restore->SR32); + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, CCR66, restore->SR66); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68, restore->SR68); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69, restore->SR69); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A, restore->SR6A); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B, restore->SR6B); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C, restore->SR6C); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D, restore->SR6D); + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, restore->SR81); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0, restore->SRA0); + + { + /* Restore the standard VGA registers */ + vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_ALL); + + if (restore->smiDACMask) + { + VGAOUT8_712(pHw, VGA_DAC_MASK, restore->smiDACMask); + } + else + { + VGAOUT8_712(pHw, VGA_DAC_MASK, 0xFF); + } + VGAOUT8_712(pHw, VGA_DAC_WRITE_ADDR, 0); + for (i = 0; i < 256; i++) { + VGAOUT8_712(pHw, VGA_DAC_DATA, restore->smiDacRegs[i][0]); + VGAOUT8_712(pHw, VGA_DAC_DATA, restore->smiDacRegs[i][1]); + VGAOUT8_712(pHw, VGA_DAC_DATA, restore->smiDacRegs[i][2]); + } + for (i = 0, offset = 2; i < 8192; i++, offset += 8) { + *((unsigned char *)(pSmi->pHardware->pMem) + offset) = restore->smiFont[i]; + } + /* Restore secondary registers */ + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x9E, + restore->CR90[14] | 0x20); + + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x33, restore->CR33_2); + for (i = 0; i < 14; i++) { + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x40 + i, + restore->CR40_2[i]); + } + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x9F, restore->CR9F_2); + + /* Restore primary registers */ + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x9E, + restore->CR90[14] & ~0x20); + + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x33, restore->CR33); + for (i = 0; i < 14; i++) { + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x40 + i, + restore->CR40[i]); + } + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x9F, restore->CR9F); + + /* Restore common registers */ + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x30, restore->CR30); + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x3A, restore->CR3A); + + for (i = 0; i < 15; i++) + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0x90 + i, + restore->CR90[i]); + + for (i = 0; i < 14; i++) + VGAOUT8_INDEX_712(pHw, vgaCRIndex, vgaCRData, 0xA0 + i, + restore->CRA0[i]); + + // if (pSmi->DualView) { + { /* dualhead stuff */ + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x40, restore->SR40); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x41, restore->SR41); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x42, restore->SR42); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x43, restore->SR43); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x44, restore->SR44); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45, restore->SR45); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x48, restore->SR48); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49, restore->SR49); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4A, restore->SR4A); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4B, restore->SR4B); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4C, restore->SR4C); + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x50, restore->SR50); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x51, restore->SR51); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x52, restore->SR52); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x53, restore->SR53); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x54, restore->SR54); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x55, restore->SR55); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x56, restore->SR56); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x57, restore->SR57); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x5A, restore->SR5A); + + /* PLL2 stuff */ + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E, restore->SR6E); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F, restore->SR6F); + } + } + + /* Reset the graphics engine */ + WRITE_DPR(pHw, 0x10, restore->DPR10); + WRITE_DPR(pHw, 0x1C, restore->DPR1C); + WRITE_DPR(pHw, 0x20, restore->DPR20); + WRITE_DPR(pHw, 0x24, restore->DPR24); + WRITE_DPR(pHw, 0x28, restore->DPR28); + WRITE_DPR(pHw, 0x2C, restore->DPR2C); + WRITE_DPR(pHw, 0x30, restore->DPR30); + WRITE_DPR(pHw, 0x3C, restore->DPR3C); + WRITE_DPR(pHw, 0x40, restore->DPR40); + WRITE_DPR(pHw, 0x44, restore->DPR44); + + /* write video controller regs */ + WRITE_VPR(pHw, 0x00, restore->VPR00); + WRITE_VPR(pHw, 0x0C, restore->VPR0C); + WRITE_VPR(pHw, 0x10, restore->VPR10); + + WRITE_CPR(pHw, 0x00, restore->CPR00); + + vgaHWProtect(pScrn, FALSE); + + LEAVE(); +} + +void wait_for_not_busy_712(SMIPtr pSmi) +{ + ScrnInfoPtr pScrn; + pScrn = SMIPSI(pSmi); + SMIHWPtr pHw = pSmi->pHardware; + + do + { + int loop = MAXLOOP; + mem_barrier(); + + int status; + for (status = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX,VGA_SEQ_DATA, 0x16); + loop && (status & 0x18) != 0x10; + status = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX,VGA_SEQ_DATA, 0x16), loop--); + + if (loop <= 0) + SMI_GEReset(pScrn, 1, __LINE__, __FILE__); + }while (0); + +} diff --git a/src/drv712/smi_712_hw.h b/src/drv712/smi_712_hw.h new file mode 100644 index 0000000..f428b78 --- /dev/null +++ b/src/drv712/smi_712_hw.h @@ -0,0 +1,144 @@ +#ifndef SMI_712_HW_INC +#define SMI_712_HW_INC +#include "../smi_common.h" +#include "../smi_driver.h" +/********************/ +/* SMI712 REGISTERS */ +/********************/ +/*General Graphics Command Register 1*/ +#define SCR17 0x17 +/*System Control Registers*/ +#define SCR18 0x18 + +/*Power Down Control Registers*/ +#define PDR21 0x21 +#define PDR22 0x22 +/*Flat Panel Type Select*/ +#define FPR30 0x30 +/*Virtual Refresh and Auto Shut Down Control*/ +#define FPR31 0x31 +/*Dithering Engine Select, Polarity, and Expansion Control*/ +#define FPR32 0x32 +#define FPR33 0x33 +#define FPR35 0x35 +#define FPR36 0x36 +#define FPR37 0x37 +#define FPR38 0x38 +#define FPR39 0x39 +#define FPR3A 0x3a +#define FPR3B 0x3b +#define FPR40 0x40 +#define FPR41 0x41 +#define FPR42 0x42 +#define FPR43 0x43 +#define FPR44 0x44 +#define FPR45 0x45 +/*Panel M-Signal Control Register*/ +#define FPR59 0x59 +/*RAM LUT On/Off Control*/ +#define CCR66 0x66 +/*MCLK Numerator Register*/ +#define CCR6A 0x6A +/*MCLK Denominator Register*/ +#define CCR6B 0x6B +/*VCLK Numerator Register*/ +#define CCR6C 0x6C +/*VCLK Denominator Register*/ +#define CCR6D 0x6D +/*VCLK2 Numerator Register*/ +#define CCR6E 0x6E +/*VCLK2 Denominator Register*/ +#define CCR6F 0x6F +/*Scratch Pad Register 1*/ +#define GPR70 0x70 +/*Hardware Cursor Enable & PI/HWC Pattern Location High*/ +#define PHR81 0x81 + +/*DPR*/ +/*Source Row Pitch*/ +#define DPR_10 0x10 +/*Stretch Source Height Y*/ +#define DPR_1C 0x1C +/*Color Compare*/ +#define DPR_20 0x20 +/*Color Compare Masks*/ +#define DPR_24 0x24 +/*Bit Mask*/ +#define DPR_28 0x28 +/*Scissors Left and Control*/ +#define DPR_2C 0x2C +/*Scissors Right*/ +#define DPR_30 0x30 +/*XY Addressing Destination & Source Window Widths*/ +#define DPR_3C 0x3C +/*Source Base Address*/ +#define DPR_40 0x40 +/*Destination Base Address*/ +#define DPR_44 0x44 + +/*VPR*/ +/*Miscellaneous Graphics and Video Control*/ +#define VPR_00 0x00 +/*Data Source Start Address for Extended Graphics Modes*/ +#define VPR_0C 0x0C +/*Data Source Width and Offset for Extended Graphics Modes*/ +#define VPR_10 0x10 + +/*CPR*/ +/*Capture Port Control*/ +#define CPR_00 0x00 + +/*Panel HW Video Control*/ +#define FPRA0 0xA0 + +typedef struct +{ + Bool modeInit; + CARD16 mode; + + CARD8 CR66; + CARD8 SR17, SR18; + CARD8 SR20, SR21, SR22, SR23, SR24; + CARD8 SR30, SR31, SR32, SR34; + CARD8 SR40, SR41, SR42, SR43, SR44, SR45, SR48, SR49, SR4A, SR4B, SR4C; + CARD8 SR50, SR51, SR52, SR53, SR54, SR55, SR56, SR57, SR5A; + CARD8 SR66, SR68, SR69, SR6A, SR6B, SR6C, SR6D, SR6E, SR6F; + CARD8 SR81, SRA0; + + CARD8 CR30, CR33, CR33_2, CR3A; + CARD8 CR40[14], CR40_2[14]; + CARD8 CR90[15], CR9F, CR9F_2; + CARD8 CRA0[14]; + + CARD8 smiDACMask, smiDacRegs[256][3]; + CARD8 smiFont[8192]; + + CARD32 DPR10, DPR1C, DPR20, DPR24, DPR28, DPR2C, DPR30, DPR3C, DPR40, DPR44; + CARD32 VPR00, VPR0C, VPR10; + CARD32 CPR00; + CARD32 FPR00_, FPR0C_, FPR10_; + + /* entity information */ + Bool DualHead; + ScrnInfoPtr pSecondaryScrn; + ScrnInfoPtr pPrimaryScrn; + int lastInstance; + + /* shared resource */ + int mmio_require; + volatile unsigned char * MMIOBase; /* Base of MMIO */ + int MapSize; /* how many mmio should map and unmap */ + int total_videoRam; /* memory count in bytes */ + + /* vga stuffs */ + char * fonts; +} SMI712RegRec, *SMI712RegPtr; +CARD8 VGAIN8_INDEX_712(SMIHWPtr pHw, int indexPort, int dataPort, CARD8 index); +void VGAOUT8_INDEX_712(SMIHWPtr pHw, int indexPort, int dataPort, CARD8 index, CARD8 data); +CARD8 VGAIN8_712(SMIHWPtr pHw, int port); +void VGAOUT8_712(SMIHWPtr pHw, int port, CARD8 data); +void save_reg_712(SMIHWPtr); +void restore_reg_712(SMIHWPtr); +void save_dpr_address(SMIHWPtr); +void wait_for_not_busy_712(SMIPtr); +#endif /* ----- #ifndef SMI_712_HW_INC -----*/ diff --git a/src/drv712/smi_712_output.c b/src/drv712/smi_712_output.c new file mode 100644 index 0000000..197c5a8 --- /dev/null +++ b/src/drv712/smi_712_output.c @@ -0,0 +1,698 @@ +/* +Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. +Copyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. +Copyright (C) 2008 Francisco Jerez. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- +NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of The XFree86 Project and +Silicon Motion shall not be used in advertising or otherwise to promote the +sale, use or other dealings in this Software without prior written +authorization from The XFree86 Project or Silicon Motion. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "../smi_common.h" +#include "smi_driver.h" +#include "smi_dbg.h" +#include "smi_crtc.h" +#include "smi_output.h" +#include "smi_712_driver.h" +#include "ddk712/ddk712.h" +extern const SMI712CrtTiming g_sm712_ModeTable[]; +extern int g_sm712_mode_cnt; +extern const SMI712PnlTiming g_sm712_ModeTable2[]; +extern int g_sm712_mode2_cnt; + +#if SMI_RANDR + +static Bool CLOSE(unsigned short uv,float fv){ + unsigned short uv2; + uv2 = (unsigned short)fv; + if(uv - uv2 < 3 && uv - uv2 > -3) + return TRUE; + else + return FALSE; +} + +static void +SMILynx_OutputDPMS_crt(xf86OutputPtr output, int mode) +{ + ScrnInfoPtr pScrn = output->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pSmi->pHardware; + SMI712RegPtr reg = p712Hw->pRegMode; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + ENTER(); + + + + switch (mode) { + case DPMSModeOn: + reg->SR31 |= 0x02; /* Enable CRT display*/ + reg->SR22 = (reg->SR22 & ~0x30) | 0x00; /* Set DPMS state*/ + break; + case DPMSModeStandby: + reg->SR31 |= 0x02; /* Enable CRT display*/ + reg->SR22 = (reg->SR22 & ~0x30) | 0x10; /* Set DPMS state*/ + break; + case DPMSModeSuspend: + reg->SR31 |= 0x02; /* Enable CRT display*/ + reg->SR22 = (reg->SR22 & ~0x30) | 0x20; /* Set DPMS state*/ + break; + case DPMSModeOff: + reg->SR31 &= ~0x02; /* Disable CRT display*/ + reg->SR22 = (reg->SR22 & ~0x30) | 0x30; /* Set DPMS state*/ + break; + } + + /* Wait for vertical retrace */ + + //while (hwp->readST01(hwp) & 0x8) ; + //while (!(hwp->readST01(hwp) & 0x8)) ; + + /* Write the registers */ + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22, reg->SR22); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, reg->SR31); + + LEAVE(); + +} + +static void +SMILynx_OutputDPMS_lcd(xf86OutputPtr output, int mode) +{ + ScrnInfoPtr pScrn = output->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMI712HWPtr p712Hw = (SMI712HWPtr)pSmi->pHardware; + SMIHWPtr pHw = pSmi->pHardware; + SMI712RegPtr reg = p712Hw->pRegMode; + xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); + + ENTER(); + + switch (mode) { + case DPMSModeOn: + if((pSmi->DualView) && output->crtc == crtcConf->crtc[1]) + { + /* Virtual Refresh is enabled */ + reg->SR21 &= ~0x10; /* Enable LCD framebuffer read operation and DSTN dithering engine */ + } +#if 0/*There is no case that pSmi->lcd == 2*/ + else + { + if(pSmi->lcd == 2) + { + /* LCD is DSTN */ + + reg->SR21 &= ~0x10; /* Enable LCD framebuffer read operation and DSTN dithering engine */ + reg->SR21 &= ~0x20; /* Enable LCD framebuffer write operation */ + } + } +#endif + reg->SR31 |= 0x01; /* Enable LCD display*/ + break; + case DPMSModeStandby: + case DPMSModeSuspend: + case DPMSModeOff: + reg->SR21 |= 0x30; /* Disable LCD framebuffer r/w operation */ + reg->SR31 &= ~0x01; /* Disable LCD display*/ + break; + } + + /* Write the registers */ + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, reg->SR21); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, reg->SR31); + + LEAVE(); + + +} + +static void +SMILynx_OutputDPMS_bios(xf86OutputPtr output, int mode) +{ + ScrnInfoPtr pScrn = output->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + + ENTER(); + + pSmi->pInt10->ax = 0x4F10; + switch (mode) { + case DPMSModeOn: + pSmi->pInt10->bx = 0x0001; + break; + case DPMSModeStandby: + pSmi->pInt10->bx = 0x0101; + break; + case DPMSModeSuspend: + pSmi->pInt10->bx = 0x0201; + break; + case DPMSModeOff: + pSmi->pInt10->bx = 0x0401; + break; + } + pSmi->pInt10->cx = 0x0000; + pSmi->pInt10->num = 0x10; + xf86ExecX86int10(pSmi->pInt10); + + LEAVE(); +} + + +static unsigned int +SMILynx_ddc1Read(ScrnInfoPtr pScrn) +{ + register vgaHWPtr hwp = VGAHWPTR(pScrn); + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + unsigned int ret; + + ENTER(); + + while (hwp->readST01(hwp) & 0x8) ; + while (!(hwp->readST01(hwp) & 0x8)) ; + + ret = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72) & 0x08; + + LEAVE(ret); +} +static unsigned int +SMILynx_ddc1Read_pnl(ScrnInfoPtr pScrn) +{ + register vgaHWPtr hwp = VGAHWPTR(pScrn); + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + unsigned int ret; + + ENTER(); + + while (hwp->readST01(hwp) & 0x8) ; + while (!(hwp->readST01(hwp) & 0x8)) ; + + ret = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x73) & 0x08; + + LEAVE(ret); +} + + + +xf86MonPtr +SMILynx_ddc1(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + xf86MonPtr pMon; + unsigned char tmp; + + ENTER(); + + tmp = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72, tmp | 0x20); + + pMon = xf86PrintEDID(xf86DoEDID_DDC1(pScrn->scrnIndex, + vgaHWddc1SetSpeedWeak(), + SMILynx_ddc1Read)); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72, tmp); + + LEAVE(pMon); +} + + +xf86MonPtr +SMILynx_ddc1_pnl(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + xf86MonPtr pMon; + unsigned char tmp; + + ENTER(); + + tmp = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x73); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x73, tmp | 0x20); + + pMon = xf86PrintEDID(xf86DoEDID_DDC1(pScrn->scrnIndex, + vgaHWddc1SetSpeedWeak(), + SMILynx_ddc1Read_pnl)); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x73, tmp); + + LEAVE(pMon); +} + +static DisplayModePtr +SMILynx_OutputGetModes_crt(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + xf86MonPtr pMon = NULL; + + ENTER(); + + if(xf86LoaderCheckSymbol("xf86PrintEDID")){ /* Ensure the DDC module is loaded*/ + /* Try VBE */ + if(pSmi->pVbe){ + pMon = vbeDoEDID(pSmi->pVbe, NULL); + if ( pMon != NULL && + (pMon->rawData[0] == 0x00) && + (pMon->rawData[1] == 0xFF) && + (pMon->rawData[2] == 0xFF) && + (pMon->rawData[3] == 0xFF) && + (pMon->rawData[4] == 0xFF) && + (pMon->rawData[5] == 0xFF) && + (pMon->rawData[6] == 0xFF) && + (pMon->rawData[7] == 0x00)) { + xf86OutputSetEDID(output,pMon); + LEAVE(xf86OutputGetEDIDModes(output)); + } + } +#if 0 + /* Try DDC2 */ + if(pSmi->I2C_primary){ + pMon=xf86OutputGetEDID(output,pSmi->I2C_primary); + if(pMon){ + xf86OutputSetEDID(output,pMon); + LEAVE(xf86OutputGetEDIDModes(output)); + } + } +#endif + + /* Try DDC1 */ + pMon=SMILynx_ddc1(pScrn); + if(pMon){ + xf86OutputSetEDID(output,pMon); + LEAVE(xf86OutputGetEDIDModes(output)); + } + } + + LEAVE(NULL); +} + + + +static DisplayModePtr +SMILynx_OutputGetModes_pnl(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + xf86MonPtr pMon = NULL; + + ENTER(); + + + if(xf86LoaderCheckSymbol("xf86PrintEDID")){ /* Ensure the DDC module is loaded*/ +#if 1 + /* Try VBE */ + if(pSmi->pVbe){ + pMon = vbeDoEDID(pSmi->pVbe, NULL); + if ( pMon != NULL && + (pMon->rawData[0] == 0x00) && + (pMon->rawData[1] == 0xFF) && + (pMon->rawData[2] == 0xFF) && + (pMon->rawData[3] == 0xFF) && + (pMon->rawData[4] == 0xFF) && + (pMon->rawData[5] == 0xFF) && + (pMon->rawData[6] == 0xFF) && + (pMon->rawData[7] == 0x00)) { + xf86OutputSetEDID(output,pMon); + LEAVE(xf86OutputGetEDIDModes(output)); + } + } +#endif +#if 0 + /* Try DDC2 */ + if(pSmi->I2C_secondary){ + pMon=xf86OutputGetEDID(output,pSmi->I2C_secondary); + if(pMon){ + xf86OutputSetEDID(output,pMon); + LEAVE(xf86OutputGetEDIDModes(output)); + } + } +#endif + /* Try DDC1 */ + pMon=SMILynx_ddc1_pnl(pScrn); + if(pMon){ + xf86OutputSetEDID(output,pMon); + LEAVE(xf86OutputGetEDIDModes(output)); + } + } + + LEAVE(NULL); +} + + +static xf86OutputStatus +SMILynx_OutputDetect_crt(xf86OutputPtr output) +{ + SMIPtr pSmi = SMIPTR(output->scrn); + SMIHWPtr pHw = pSmi->pHardware; + SMI712HWPtr p712Hw = (SMI712HWPtr)pSmi->pHardware; + SMI712RegPtr mode = p712Hw->pRegMode; + vgaHWPtr hwp = VGAHWPTR(output->scrn); + CARD8 SR7D; + Bool status; + + ENTER(); + + SR7D = VGAIN8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x7D); + + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, mode->SR21 & ~0x88); /* Enable DAC and color palette RAM */ + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x7B, 0x40); /* "TV and RAMDAC Testing Power", Green component */ + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x7D, SR7D | 0x10); /* Enable monitor detect */ + + /* Wait for vertical retrace */ + while (!(hwp->readST01(hwp) & 0x8)) ; + while (hwp->readST01(hwp) & 0x8) ; + + status = VGAIN8_712(pHw, 0x3C2) & 0x10; + + /* Restore previous state */ + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, mode->SR21); + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x7D, SR7D); + + if(status) + LEAVE(XF86OutputStatusConnected); + else + LEAVE(XF86OutputStatusDisconnected); +} + +static int SMI712_OutputModeValid_PNL(xf86OutputPtr output, DisplayModePtr mode) +{ + int index,ret; + SMI712CrtTiming * timing; + ScrnInfoPtr pScrn = output->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + int xres = mode->HDisplay; + int yres = mode->VDisplay; + float VRefresh = mode->VRefresh; + float HSync = mode->HSync; + + ENTER(); + + if(HSync < 1.0f){ + HSync = mode->Clock/mode->HTotal; + HSync *= 1000; + HSync /= mode->VTotal; + //XERR("monk: hync == %f\n",HSync); + } + + index = 0; + timing = &g_sm712_ModeTable2[0]; + + if(pSmi->lcdWidth!= 0 && pSmi->lcdHeight!= 0) + { + if(xres == pSmi->lcdWidth&& yres == pSmi->lcdHeight) + LEAVE(MODE_OK); + else + ret = (MODE_CLOCK_RANGE); + + } + else if(xres*yres*pSmi->Bpp > ((pSmi->DualView)?pSmi->FBReserved/2:pSmi->FBReserved)) + { + ret = MODE_MEM; + } + else + { + ret = MODE_CLOCK_RANGE; + while(index < g_sm712_mode2_cnt) + { + if(timing[index].h_res == xres && + timing[index].v_res == yres && + CLOSE(timing[index].vsync,HSync)) + LEAVE(MODE_OK); + index++; + } + } + //XERR("Mode [%d,%d]@%f not supported by sm712 PNL\n",xres,yres,VRefresh); + LEAVE(ret); +} + +static int SMI712_OutputModeValid_CRT(xf86OutputPtr output, DisplayModePtr mode) +{ + int index,ret; + SMI712CrtTiming * timing; + ScrnInfoPtr pScrn = output->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + int xres = mode->HDisplay; + int yres = mode->VDisplay; + float VRefresh = mode->VRefresh; + float HSync = mode->HSync; + + ENTER(); + + //XERR("CHECK Mode [%d,%d]@%f 712 CRT\n",xres,yres,VRefresh); +#if 0 + if(xres == 640 && yres == 480) + { + XERR("HSync = %f,VRefresh = %f\n",HSync,VRefresh); + XERR("Clock = %d khz\n",mode->Clock); + XERR("htotal:%d,vtotal == %d\n",mode->HTotal,mode->VTotal); + } +#endif + if(HSync < 1.0f){ + HSync = mode->Clock/mode->HTotal; + HSync *= 1000; + HSync /= mode->VTotal; + //XERR("htotal:%d,vtotal == %d\n",mode->HTotal,mode->VTotal); + //XERR("hync == %f\n",HSync); + //XERR("\n"); + } + + + index = 0; + timing = &g_sm712_ModeTable[0]; + + if(xres*yres*pSmi->Bpp > ((pSmi->DualView)?pSmi->FBReserved/2:pSmi->FBReserved)) + { + ret = MODE_MEM; + } + else + { + ret = MODE_CLOCK_RANGE; + while(index < g_sm712_mode_cnt) + { + if(timing[index].h_res == xres && + timing[index].v_res == yres && + CLOSE(timing[index].vsync,HSync)) + LEAVE(MODE_OK); + index++; + } + } + + //XERR("Mode [%d,%d]@%f is not supported by sm712 CRT\n",xres,yres,VRefresh); + LEAVE(ret); +} + + +DisplayModePtr SMI712_OutputGetModes_pnl(xf86OutputPtr output) +{ + SMIPtr pSmi = SMIPTR(output->scrn); + + ENTER(); +#define X (pSmi->lcdWidth) +#define Y (pSmi->lcdHeight) + +#ifdef HAVE_XMODES +// XMSG("lcdWidth,lcdHeight = %d %d \n",X,Y); + if(X != 0 && Y != 0) + LEAVE(xf86CVTMode(X,Y,60.0f,FALSE,FALSE)); +#endif + LEAVE(NULL); +#undef X +#undef Y +} + + +void SMI712_OutputModeSet(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode) +{ + ScrnInfoPtr pScrn; + SMIOutputPrivatePtr outPriv; + SMIPtr pSmi; + SMIHWPtr pHw; + CARD8 tmp; + + ENTER(); + + + pScrn = output->scrn; + outPriv = SMIOUTPUT(output); + pSmi = SMIPTR(pScrn); + pHw = pSmi->pHardware; + + + if(!outPriv->path) + { /* sm712 CRT head */ + + } + else + { /* sm712 LCD head */ + tmp = VGAIN8_INDEX_712(pHw,VGA_SEQ_INDEX,VGA_SEQ_DATA,0x30); + //XERR("FPR30 = %x\n",tmp); + switch (pSmi->TFTColor) + { + case SMI_TFT_18BIT: + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30,(0x20|(tmp&0x8f))); + break; + case SMI_TFT_36BIT: + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30,(0x60|(tmp&0x8f))); + break; + case SMI_TFT_12BIT: + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30,(0x10|(tmp&0x8f))); + break; + case SMI_TFT_9BIT: + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30,(0x00|(tmp&0x8f))); + break; + + case -1: + case SMI_TFT_24BIT: + VGAOUT8_INDEX_712(pHw, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x30,(0x30|(tmp&0x8f))); + break; + } + } + pSmi->psSetDisplay(pScrn,pScrn->currentMode); + LEAVE(); +} + + +Bool SMI712_OutputFuncsInit_base(xf86OutputFuncsPtr* outputFuncs) +{ + ENTER(); + SMI_OutputFuncsInit_base(outputFuncs); + (*outputFuncs)->mode_valid = SMI_OutputModeValid; + (*outputFuncs)->mode_set = SMI712_OutputModeSet; + LEAVE(TRUE); +} + + +Bool SMI712_OutputPreInit(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR(pScrn); + xf86OutputPtr output; + xf86OutputFuncsPtr outputFuncs; + SMIOutputPrivatePtr outputPriv; + + ENTER(); + + + /* Output 0 is CRT */ + SMI712_OutputFuncsInit_base(&outputFuncs); + + /*if(pSmi->useBIOS) + outputFuncs->dpms = SMILynx_OutputDPMS_bios; + else*/ + outputFuncs->dpms = SMILynx_OutputDPMS_crt; + + outputFuncs->get_modes = SMILynx_OutputGetModes_crt; + outputFuncs->detect = SMI_OutputDetect_lcd; + outputFuncs->mode_valid = SMI712_OutputModeValid_CRT; + + if(! (output = xf86OutputCreate(pScrn,outputFuncs,"CRT"))) + LEAVE(FALSE); + + outputPriv = xnfcalloc(sizeof(SMIOutputPrivateRec),1); + outputPriv->index = 0; + outputPriv->path = 0;//CRT head for sm712 + + output->driver_private = outputPriv; + output->interlaceAllowed = FALSE; + output->doubleScanAllowed = FALSE; + output->possible_crtcs = 1; + /*output->possible_clones = 1 << 1;*/ + + if(pSmi->DualView){ + /* Output 1 is PNL */ + SMI712_OutputFuncsInit_base(&outputFuncs); + outputFuncs->dpms = SMILynx_OutputDPMS_lcd; + /*outputFuncs->get_modes = SMI712_OutputGetModes_pnl;*/ + outputFuncs->get_modes = SMILynx_OutputGetModes_pnl; + outputFuncs->detect = SMI_OutputDetect_lcd; + outputFuncs->mode_valid = SMI712_OutputModeValid_PNL; + + if(! (output = xf86OutputCreate(pScrn,outputFuncs,"PNL"))) + LEAVE(FALSE); + + outputPriv = xnfcalloc(sizeof(SMIOutputPrivateRec),1); + outputPriv->index = 1; + outputPriv->path = 1;//LCD head for sm712 + + output->driver_private = outputPriv; + output->interlaceAllowed = FALSE; + output->doubleScanAllowed = FALSE; + output->possible_crtcs = 2; + /*output->possible_clones = 1 << 1;*/ + } + LEAVE(TRUE); +} + + +Bool SMILynx_OutputPreInit(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR(pScrn); + xf86OutputPtr output; + xf86OutputFuncsPtr outputFuncs; + + ENTER(); + + /* Output 0 is LCD */ + SMI712_OutputFuncsInit_base(&outputFuncs); + + /*if(pSmi->useBIOS) + outputFuncs->dpms = SMILynx_OutputDPMS_bios; + else*/ + outputFuncs->dpms = SMILynx_OutputDPMS_lcd; + + outputFuncs->get_modes = SMI_OutputGetModes_native; + outputFuncs->detect = SMI_OutputDetect_lcd; + + if(! (output = xf86OutputCreate(pScrn,outputFuncs,"LVDS"))) + LEAVE(FALSE); + + output->interlaceAllowed = FALSE; + output->doubleScanAllowed = FALSE; + output->possible_crtcs = (1 << 0) | (1 << 1); + output->possible_clones = 1 << 1; + + if(pSmi->DualView){ + /* Output 1 is CRT */ + SMI712_OutputFuncsInit_base(&outputFuncs); + outputFuncs->dpms = SMILynx_OutputDPMS_crt; + outputFuncs->get_modes = SMILynx_OutputGetModes_crt; + + outputFuncs->detect = SMI_OutputDetect_lcd; + + if(! (output = xf86OutputCreate(pScrn,outputFuncs,"VGA"))) + LEAVE(FALSE); + + output->interlaceAllowed = FALSE; + output->doubleScanAllowed = FALSE; + + output->possible_crtcs = 1 << 0; + output->possible_clones = 1 << 0; + } + LEAVE(TRUE); +} + + + +#endif /*#if SMI_RANDR*/ diff --git a/src/drv750/smi_750_crtc.c b/src/drv750/smi_750_crtc.c new file mode 100644 index 0000000..d34485e --- /dev/null +++ b/src/drv750/smi_750_crtc.c @@ -0,0 +1,699 @@ +/* +Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. +Copyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. +Copyright (C) 2008 Mandriva Linux. All Rights Reserved. +Copyright (C) 2008 Francisco Jerez. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- +NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of The XFree86 Project and +Silicon Motion shall not be used in advertising or otherwise to promote the +sale, use or other dealings in this Software without prior written +authorization from The XFree86 Project or Silicon Motion. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "../smi_dbg.h" +#include "../smi_common.h" +#include "../smi_crtc.h" +#include "../ddk750/ddk750.h" +#include "../smi_accel.h" +#if SMI_RANDR + +static uint g_HWCOffset[]={PANEL_HWC_ADDRESS,CRT_HWC_ADDRESS}; +static Bool g_argb_saved = FALSE; + +#if 0 +static void init_argb_cursor(SMIPtr pSmi) +{ + if(!pSmi->entityPrivate->alphaOkay) + { + alphaInit(0,0,SMI750_MAX_CURSOR,SMI750_MAX_CURSOR, + pSmi->fb_argbCursorOffset,0,SMI750_MAX_CURSOR * 2, + ALPHA_FORMAT_ARGB_4444,0,0,0); + +//memset(pSmi->FBBase + pSmi->fbMapOffset+ pSmi->FBReserved, 0,(SMI501_CURSOR_SIZE + SMI750_ARGB_CURSOR_SIZE)*2); + pSmi->entityPrivate->alphaOkay = 1; + } +} + + +/* + 750 Alpha layer is not flexiable as cursor layer + cursor layer can handle negetive position + alpha layer must do some stupid data copy to accomplish negetive potion effect ... + Monk @ 2009-12-31 +*/ + +static void SMI750_ARGB_SetCursorPosition(xf86CrtcPtr crtc, int x, int y) +{ + +#define ALPHA_BPP 2 +#define PITCH (SMI750_MAX_CURSOR * ALPHA_BPP) + + static Bool moved = FALSE; + int deltaX,deltaY; + int X,Y,v,h; + + uint reg1,reg2; + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + deltaX = deltaY = 0; + + char * dst = pSmi->FBBase + pSmi->fbMapOffset + pSmi->fb_argbCursorOffset; + char * src = pSmi->FBBase + pSmi->fbMapOffset + pSmi->fb_argbCursorOffset - SMI750_ARGB_CURSOR_SIZE; + +#if 0 + XMSG("X = %d, Y = %d \n",x,y); +#endif + + if(x < 0){ + X = 0;deltaX = (-x) * ALPHA_BPP; + }else{ + X = x; + } + + if(y < 0){ + Y = 0;deltaY = (-y)*PITCH; + }else{ + Y = y; + } + + + alphaEnableDisplay(0); + + //POKE32(ALPHA_FB_WIDTH,FIELD_VALUE(PEEK32(ALPHA_FB_WIDTH),ALPHA_FB_WIDTH,WIDTH,PITCH - deltaX)); + + if(x < 0) + { + /* see if we need backup original cursor data first,copy ^dst ^ to ^src^ */ + if(!g_argb_saved){ + memcpy(src,dst,SMI750_ARGB_CURSOR_SIZE); + g_argb_saved = TRUE; + } + + /* only move alpha data could make it , because of alpha layer address 16 byte align requirement */ + for(v = deltaY;v < (SMI750_MAX_CURSOR * PITCH);v += PITCH) + { +#if 0 + for(h = 0;h<(PITCH - deltaX);h++) + *(dst + v + h) = *(src + v + deltaX + h); +#else + memcpy(dst+v,src+v+deltaX,PITCH-deltaX); +#endif + moved = TRUE; + } + } + else + { + if(moved == TRUE){ + /* need original cusor data come back */ + memcpy(dst,src,SMI750_ARGB_CURSOR_SIZE); + moved = FALSE; + } + } + + if(y < 0){ + POKE32(ALPHA_FB_ADDRESS, + FIELD_VALUE(PEEK32(ALPHA_FB_ADDRESS),ALPHA_FB_ADDRESS,ADDRESS,pSmi->fb_argbCursorOffset + deltaY)); + }else{ + POKE32(ALPHA_FB_ADDRESS, + FIELD_VALUE(PEEK32(ALPHA_FB_ADDRESS),ALPHA_FB_ADDRESS,ADDRESS,pSmi->fb_argbCursorOffset)); + } + + reg1 = (X & 0xffff)|(Y << 16); + reg2 = (x + SMI750_MAX_CURSOR - 1)|((y + SMI750_MAX_CURSOR - 1)<<16); + + POKE32(ALPHA_PLANE_TL,reg1); + POKE32(ALPHA_PLANE_BR,reg2); + alphaEnableDisplay(1); +// memset(pSmi->FBBase + pSmi->FBReserved,0xff,(SMI501_CURSOR_SIZE + SMI750_ARGB_CURSOR_SIZE)*2); +#undef PITCH + +} + +static void SMI750_ARGB_ShowCursor(xf86CrtcPtr crtc) +{ + alphaEnableDisplay(1); +// sm750_do_ARGB_showCursor(1); +} + + +static void SMI750_ARGB_HideCursor(xf86CrtcPtr crtc) +{ + alphaEnableDisplay(0); +// sm750_do_ARGB_showCursor(0); +} + +static void SMI750_ARGB_LOADARGB(xf86CrtcPtr crtc,CARD32* src) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + uint add; + int i; + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + + //static uint cnt = 0; + //XERR("cnt = %08x \n",cnt++); + //ENTER(); + + + if(crtcPriv->controller!=0){ + return; + } + +// if(crtc->cursor_argb != TRUE) +// crtc->cursor_argb = TRUE; + + +#if 0 + /* copy cursor data to onscreen */ + { + char * fb = pSmi->FBBase; + int cnt,i,pitch; + cnt = SMI750_MAX_CURSOR * 4; + pitch = pScrn->displayWidth * pSmi->Bpp; + fb+=pitch/2; + for(i=0;irotation = %d:\n",crtc->rotation); + XMSG("crtc->desiredRotation = %d:\n",crtc->desiredRotation); + if(crtc->randr_crtc!=NULL) + XMSG("crtc->randr_crtc->rotation = %d:\n",crtc->randr_crtc->rotation); +#endif + + +#if 0 + for(i=0;i<(SMI501_ARGB_CURSOR_SIZE)/4;i+=4) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "MONK :src[%d] = %08x src[%d] = %08x, src[%d] = %08x, src[%d] = %08x\n", + i,src[i],i+1,src[i+1],i+2,src[i+2],i+3,src[i+3]); +#endif + uint argb; + unsigned short * addr = (unsigned short *)(pSmi->FBBase + pSmi->fb_argbCursorOffset); + unsigned short * addr_bk = (unsigned short *)((unsigned long)addr - SMI750_ARGB_CURSOR_SIZE); +#if 1 + for(i=0;i> 16; + argb |= (src[i] & 0xf00000) >> 12; + argb |= (src[i] & 0xf000) >> 8; + argb |= (src[i] & 0xf0) >> 4; + addr[i] = (unsigned short)argb; + addr_bk[i] = argb; + } + + add = pSmi->fb_argbCursorOffset; + POKE32(ALPHA_FB_ADDRESS,add); + + /* tell argb_set_position routine that cursor data updated ,need redraw backup data */ + g_argb_saved = FALSE; +#endif + + //LEAVE(); +} + + +static void SMI750_SetCursorColors(xf86CrtcPtr crtc,int bg,int fg) +{ + //translate rgb888 color into rg 565 + //use hwc color 3 as bg and color 2 as fg + //X use 1 for fg and 0 for bg so set 750 hw color 2 with bg and color 3 with fg +#define RBIT 0xf80000 +#define GBIT 0xfc00 +#define BBIT 0xf8 +#define COLOR_24_16(X) (((X & RBIT) >> 8)|((X & GBIT) >> 5)|((X & BBIT) >>3)) + + + + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + uint regadd,regval; + uint hwcolor2,hwcolor3; + + ENTER(); + hwcolor2 = g_HWCOffset[crtcPriv->controller] + 8; + hwcolor3 = g_HWCOffset[crtcPriv->controller] + 0xc; + + //XMSG("bg = %08x,fg = %08x\n",bg,fg); + + regval = COLOR_24_16(bg)<<16; + POKE32(hwcolor2,regval); + + regval = COLOR_24_16(fg); + POKE32(hwcolor3,regval); + + LEAVE(); +#undef COLOR_24_16 +#undef RBIT +#undef GBIT +#undef BBIT + +} + +inline static void sm750_do_showCursor(SMIPtr pSmi,int channel,int onoff) +{ + uint regadd; + uint offset; + ENTER(); + + regadd = g_HWCOffset[channel]; + offset = (channel == 0)?pSmi->fb_priCursorOffset:pSmi->fb_secCursorOffset; + if(onoff) + POKE32(regadd,offset|0x80000000); + else + POKE32(regadd,0); + + LEAVE(); +} + + +/* + 750 cursor layer is smarter , it can handle negetive potion both for X and Y + just set outside bit and make potion multiplus -1 will reach it + Monk @ 2009-12-31 +*/ +static void SMI750_SetCursorPosition(xf86CrtcPtr crtc,int x,int y) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + uint regadd,regvalue; + + XMSG("Set %s position to %d,%d\n",crtcPriv->controller?"CRT":"PANEL",x,y); + + regadd = g_HWCOffset[crtcPriv->controller] + 4; + regvalue = FIELD_VALUE(0,PRIMARY_HWC_LOCATION,TOP,y<0?1:0)| + FIELD_VALUE(0,PRIMARY_HWC_LOCATION,Y,y<0?-y:y)| + FIELD_VALUE(0,PRIMARY_HWC_LOCATION,LEFT,x<0?1:0)| + FIELD_VALUE(0,PRIMARY_HWC_LOCATION,X,x<0?-x:x); + + POKE32(regadd,regvalue); +} + + +static void SMI750_CrtcShowCursor(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + sm750_do_showCursor(pSmi,crtcPriv->controller,1); +} + + +static void SMI750_CrtcHideCursor(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + sm750_do_showCursor(pSmi,crtcPriv->controller,0); +} + +static void SMI750_CrtcLoadCursorImage(xf86CrtcPtr crtc, CARD8* image) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + uint regadd,regvalue; + + ENTER(); + + regadd = g_HWCOffset[crtcPriv->controller]; + regvalue = (crtcPriv->controller == 0)?pSmi->fb_priCursorOffset:pSmi->fb_secCursorOffset; + POKE32(regadd,regvalue); + memcpy(pSmi->FBBase + regvalue,image,SMI501_CURSOR_SIZE); + + LEAVE(); +} +#endif + + +#if 1 +static void +SMI750_CrtcAdjustFrame(xf86CrtcPtr crtc, int x, int y) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + ENTER(); + + CARD32 Base; + CARD32 Pitch; + CARD32 regval; + + Pitch = pScrn->displayWidth * pSmi->Bpp; + xf86Msg(X_INFO,"Crtc Adjust Frame:Pitch: %x\n", Pitch); + + if(crtc->rotatedData){ + Base = (char*)crtc->rotatedData - (char*)pSmi->pFB; + Pitch = crtcPriv->shadow_pitch; + }else{ + Base = pSmi->FBOffset + (x + y * pScrn->displayWidth) * pSmi->Bpp; + } + + + + /* adjust base address and pitch */ + if(crtcPriv->controller == 0){ + WRITE_SCR(pHw,PANEL_FB_ADDRESS,Base); + regval = FIELD_VALUE(0,PANEL_FB_WIDTH,OFFSET,Pitch)| + FIELD_VALUE(0,PANEL_FB_WIDTH,WIDTH,Pitch); + WRITE_SCR(pHw,PANEL_FB_WIDTH,regval); + }else{ + WRITE_SCR(pHw,CRT_FB_ADDRESS,Base); + regval = READ_SCR(pHw,CRT_FB_WIDTH); + regval = FIELD_VALUE(regval,CRT_FB_WIDTH,OFFSET,Pitch); + WRITE_SCR(pHw,CRT_FB_WIDTH,regval); + } + +#if 0 + if(crtc->rotatedData) + { + RRCrtcPtr rcrtc = crtc->randr_crtc; + xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"MONK : In %s",__func__); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : rotatedData != NULL \n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "crtc->desiredRotation= %d \n",crtc->desiredRotation); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "crtc->x,y == %d,%d \n",crtc->x,crtc->y); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "crtc->desiredX,desiredY == %d,%d \n", + crtc->desiredX,crtc->desiredY); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "crtc->randr_crtc->x,y == %d,%d \n",rcrtc->x,rcrtc->y); + } + +#endif + LEAVE(); +} +#else +static void +SMI750_CrtcAdjustFrame(xf86CrtcPtr crtc, int x, int y) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); + // MSOCRegPtr mode = pSmi->mode; + CARD32 Base; + + ENTER(); + + if(crtc->rotatedData) + Base = (char*)crtc->rotatedData - (char*)pSmi->FBBase; + else + Base = pSmi->FBOffset + (x + y * pScrn->displayWidth) * pSmi->Bpp; + + Base = (Base + 15) & ~15; + + if (crtc == crtcConf->crtc[0]) { + mode->panel_fb_address.f.address = Base >> 4; + mode->panel_fb_address.f.pending = 1; + WRITE_SCR(pSmi, PANEL_FB_ADDRESS, mode->panel_fb_address.value); + } + else { + mode->crt_display_ctl.f.pixel = ((x * pSmi->Bpp) & 15) / pSmi->Bpp; + WRITE_SCR(pSmi, CRT_DISPLAY_CTL, mode->crt_display_ctl.value); + mode->crt_fb_address.f.address = Base >> 4; + mode->crt_fb_address.f.mselect = 0; + mode->crt_fb_address.f.pending = 1; + WRITE_SCR(pSmi, CRT_FB_ADDRESS, mode->crt_fb_address.value); + } + + LEAVE(); +} +#endif + + +static void +SMI750_CrtcModeSet(xf86CrtcPtr crtc, + DisplayModePtr xf86mode, + DisplayModePtr adjusted_mode, + int x, int y) +{ + ScrnInfoPtr pScrn; + SMIPtr pSmi; + SMICrtcPrivatePtr crtcPriv; + pScrn = crtc->scrn; + pSmi = SMIPTR(pScrn); + crtcPriv = SMICRTC(crtc); + + ENTER(); + + pSmi->dispCtrl = PANEL; + if(crtcPriv->controller == 1) + pSmi->dispCtrl = CRT; + +#if 0 + logicalMode_t Mode; + + + + pScrn = crtc->scrn; + pSmi = SMIPTR(pScrn); + crtcPriv = SMICRTC(crtc); +// pEntPriv = pSmi->entityPrivate; + + Mode.xLCD = Mode.yLCD = 0; + if(crtcPriv->controller == 1) + { + pSmi->dispCtrl = SECONDARY_CTRL; + Mode.xLCD = pSmi->lcdWidth; + Mode.yLCD = pSmi->lcdHeight; + } + + + if(Mode.xLCD * Mode.yLCD != 0){ + /* expansion mode, only 60 hz is valid */ + Mode.hz = 60; + }else{ + /* no expansion */ + Mode.hz = (uint32_t)(((xf86mode->VRefresh!=0) ? xf86mode->VRefresh : adjusted_mode->VRefresh) + 0.5); + } + + Mode.x = xf86mode->HDisplay; + Mode.y = xf86mode->VDisplay; + Mode.bpp = pScrn->bitsPerPixel; + + if(crtc->desiredRotation && crtc->rotatedData) + Mode.baseAddress = ((FBLinearPtr)crtcPriv->shadowArea)->offset * pSmi->Bpp; + else + Mode.baseAddress = pSmi->FBOffset ; +#endif +#if 0 + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : In %s \n",__func__); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : mode.dispCtrl = %d \n",Mode.dispCtrl); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : CRTC->desiredRotation= %d \n",crtc->desiredRotation); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : mode.LCD = %dx%d \n",Mode.xLCD,Mode.yLCD); + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : pScrn->virtual[X,Y] == %d,%d \n",pScrn->virtualX,pScrn->virtualY); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : pScrn->displayWidth == %d\n",pScrn->displayWidth); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : position x,y== %d,%d \n",x,y); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : Mode = [%d x %d]@%d hz\n",Mode.x,Mode.y,Mode.hz); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : xf86mode->VRefresh = %f\n",xf86mode->VRefresh); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MONK : adjusted_mode->VRefresh = %f\n",adjusted_mode->VRefresh); +#endif + +#if 0 + /* if mode.hz == 71~76, we set it to 75 */ + if(Mode.hz > 70 && Mode.hz < 77) + Mode.hz = 75; +#else + + /*XMSG("Mode.[x,y,hz] = [%d,%d,%d]\n",Mode.x,Mode.y,Mode.hz); + XMSG("member of DisplayModePtr \n"); + XMSG("DisplayModePtr->Clock = %d\n",xf86mode->Clock); + XMSG("DisplayModePtr->HSync = %f\n",xf86mode->HSync); + XMSG("DisplayModePtr->VRefresh = %f\n",xf86mode->VRefresh); + + + XMSG("DisplayModePtr->HDisplay = %d\n",xf86mode->HDisplay); + XMSG("DisplayModePtr->HSyncStart = %d\n",xf86mode->HSyncStart); + XMSG("DisplayModePtr->HSyncEnd = %d\n",xf86mode->HSyncEnd); + XMSG("DisplayModePtr->HTotal = %d\n",xf86mode->HTotal); + XMSG("DisplayModePtr->HSkew = %d\n",xf86mode->HSkew); + + XMSG("DisplayModePtr->VDisplay = %d\n",xf86mode->VDisplay); + XMSG("DisplayModePtr->VSyncStart = %d\n",xf86mode->VSyncStart); + XMSG("DisplayModePtr->VSyncEnd = %d\n",xf86mode->VSyncEnd); + XMSG("DisplayModePtr->VTotal = %d\n",xf86mode->VTotal); + XMSG("DisplayModePtr->VScan = %d\n",xf86mode->VScan);*/ + pSmi->psSetMode(pScrn,xf86mode); + pSmi->psSetDisplay(pScrn,pScrn->currentMode); +#if 0 +#ifndef SMI_EDID_ENTIRE +// if(setModeEx(&Mode) == -1) +if(sm750_setMode(&Mode) == -1) + { + XMSG("Failed on setModeEx\n"); + /* the request mode can not be set by DDK ,directly set the mode */ + if(xorg_setMode(&Mode,adjusted_mode)) +// { + XMSG("Failed on xorg_setMode\n"); + // } + } +#else + if(Mode.xLCD && Mode.yLCD){ + /* expansion needed ,we use setModeEx */ +// if(setModeEx(&Mode) == -1) + if(sm750_setMode(&Mode) == -1) + XERR("Opps,seems DDK setmode failed \n"); + + }else{ + /* common mode set requirment ,just use common routine */ + if(xorg_setMode(&Mode,adjusted_mode)) + // XERR("Opps,seems xorg_setMode failed\n"); + } +#endif +#endif +#endif + + SMI750_CrtcAdjustFrame(crtc, x, y); + + LEAVE(); +} + + +static Bool +SMI750_CrtcLock (xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + + ENTER(); + + // deWaitForNotBusy(); + + LEAVE(FALSE); +} + + + +static void +SMI750_CrtcLoadLUT(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); + + ENTER(); + + + LEAVE(); +} + + +/* + * Implementation + */ +static void +SMI750_CrtcVideoInit_lcd(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn=crtc->scrn; + SMIPtr pSmi = SMIPTR(pScrn); + ENTER(); + + + + LEAVE(); +} + + +Bool SMI750_CrtcPreInit(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR(pScrn); + xf86CrtcPtr crtc; + xf86CrtcFuncsPtr crtcFuncs; + SMICrtcPrivatePtr crtcPriv; + + ENTER(); + + int idx = 0; + int c = (pSmi->DualView?2:1); + Bool expansion = (pSmi->lcdWidth >0 && pSmi->lcdHeight > 0); + SMI_CrtcPreInit(pScrn); + while(idx < c) + { + crtcFuncs = NULL; + crtcPriv = NULL; + if(! SMI_CrtcFuncsInit_base(&crtcFuncs, &crtcPriv)) + LEAVE(FALSE); + + crtcFuncs->mode_set = SMI750_CrtcModeSet; + crtcFuncs->lock = SMI750_CrtcLock; + + crtcPriv->adjust_frame = SMI750_CrtcAdjustFrame; + crtcPriv->video_init = SMI750_CrtcVideoInit_lcd; + crtcPriv->load_lut = SMI750_CrtcLoadLUT; + crtcPriv->index = idx; + +#if 0 + if(expansion && pSmi->DualView) + crtcPriv->controller = (idx+1)&1; + else if(expansion) + crtcPriv->controller = 1; + else + crtcPriv->controller = idx; +#else + if(expansion){ + /* if expansion enabled, than primary channel will be put into crtc_1 and secondary be crtc_0 + This limitation need be take care + */ + crtcPriv->controller = (idx+1)&1; + }else{ + crtcPriv->controller = idx; + } +#endif +#if 0 + if(pSmi->ARGBCursor && !pSmi->DualView) + { + crtcFuncs->set_cursor_position = SMI750_ARGB_SetCursorPosition; + crtcFuncs->show_cursor = SMI750_ARGB_ShowCursor; + crtcFuncs->hide_cursor = SMI750_ARGB_HideCursor; + crtcFuncs->load_cursor_argb = SMI750_ARGB_LOADARGB; + //init_argb_cursor(pSmi); + } + else if (pSmi->HwCursor) + { + crtcFuncs->set_cursor_colors = SMI750_SetCursorColors; + crtcFuncs->set_cursor_position = SMI750_SetCursorPosition; + crtcFuncs->show_cursor = SMI750_CrtcShowCursor; + crtcFuncs->hide_cursor = SMI750_CrtcHideCursor; + crtcFuncs->load_cursor_image = SMI750_CrtcLoadCursorImage; + } +#endif + if (! (crtc = xf86CrtcCreate(pScrn, crtcFuncs))) + { LEAVE(FALSE); + + } + crtc->driver_private = crtcPriv; + idx++; + } + LEAVE(TRUE); +} + +#endif /*#if SMI_RANDR*/ diff --git a/src/drv750/smi_750_driver.c b/src/drv750/smi_750_driver.c new file mode 100644 index 0000000..d6fbae6 --- /dev/null +++ b/src/drv750/smi_750_driver.c @@ -0,0 +1,636 @@ +#include "../smi_common.h" +#include "../smi_driver.h" +#include "smi_750_driver.h" +#include "smi_750_hw.h" +#include "../smi_dbg.h" +#include "xf86Crtc.h" +#include "smi_crtc.h" +pll_value_t *pll_table; + +void (*pfn_I2CPutBits_750[])(I2CBusPtr,int,int)= +{NULL,NULL}; + +void (*pfn_I2CGetBits_750[])(I2CBusPtr,int*,int*)= +{NULL,NULL}; + +/*----------------------------------------------------------------------------- + * they are just static datas,don't pass their address to X + * you can put down the member data you want into these const + * variable and make a copy of them to use in driver + * or dualview and multicard case will shut your driver off + * + *-----------------------------------------------------------------------------*/ +static const SMI750HWRec sm750_hwrec = { + .base = { + .pcDeepMap = sm750_pcDeepmap,/* actually,NULL value can be just ignored,gcc will know it*/ + .pcEntityInit = sm750_entityInit, + .pcEntityEnter = sm750_entityEnter, + .pcEntityLeave = sm750_entityLeave, + .pcCloseAllScreen = sm750_closeAllScreen, + .pcFBSize = sm750_totalFB, + .pcInitHardware = NULL, + }, + +}; + + +static const SMI750Rec sm750_rec = { + .base = { + .minHeight = 128, + .psGetMapResult = sm750_getMapResult, + .psVgaPciInit = sm750_vgaAndpciInit, + .psHandleOptions = sm750_handleOptions, + .psValidMode = sm750_validMode, + .psSetMode = sm750_setMode, + .psAdjustFrame = sm750_adjustFrame, + .psLoadPalette = sm750_loadPalette, + .psSetDisplay = sm750_setDisplay, + .psSaveText = sm750_saveText, + #if SMI_RANDR + .psCrtcPreInit = SMI750_CrtcPreInit, + .psOutputPreInit = SMI750_OutputPreInit, + .psI2CInit = sm750_I2CInit, + #endif + }, +}; + + +/* + * === FUNCTION ====================================================================== + * Name: sm750_genSMI + * Description: build up the entire private date for sm750 video card and initialize them. + * malloc an SMIPtr (named pSmi) and SMIHWPtr(named pHw) if in need + * setting confirmed member of pSmi and pHw (such as physical address,etc..) + * hook all known function pointer to pSmi and pHw + * in a sentence, put everything associated with SM750 this stage can confirm into the two structure !!! + * ===================================================================================== + */ +SMIPtr sm750_genSMI(pointer priv,int entityIndex) +{ + SMIPtr pSmi; +#ifdef XSERVER_LIBPCIACCESS + struct pci_device * pPci; +#else + pciVideoPtr pPci; +#endif + + ENTER(); +#ifdef XSERVER_LIBPCIACCESS + /*what's the difference between 'pScrn->entityList[0]' and 'pEntInfo->index'??*/ + pPci = xf86GetPciInfoForEntity(entityIndex); +#endif + /* pSmi always need create for every screen*/ + pSmi = (SMIPtr)XNFcalloc(sizeof(SMI750Rec)); + memset(pSmi,0, sizeof(SMI750Rec)); + if(pSmi == NULL) + return pSmi; + memcpy(pSmi,&sm750_rec,sizeof(SMI750Rec)); + /*This function is associated with screen + , but maybe two screen belongs to one entity (dualview)*/ + pSmi->pHardware = priv; + + /* if priv is NULL,means we need create a pHw + * below code can handle 2 screen per entity case + * but not work for 3+ screen per entity cases + * */ + if(!pSmi->pHardware) + { + /* + * Allocate an 'Chip'Rec, and hook it into pScrn->driverPrivate. + * pScrn->driverPrivate is initialised to NULL, so we can check if + * the allocation has already been done. + */ + SMI750HWPtr p750Hw; + p750Hw = pSmi->pHardware = (SMIHWPtr)XNFcalloc(sizeof(SMI750HWRec)); + if(pSmi->pHardware == NULL) + LEAVE(NULL); + memcpy(pSmi->pHardware,&sm750_hwrec,sizeof(SMI750HWRec)); + p750Hw->pRegSave = xnfcalloc(sizeof(SMI750RegRec),1); + if(p750Hw->pRegSave == NULL) + LEAVE(NULL); + p750Hw->fonts = xalloc(KB(64)); + if(p750Hw->fonts == NULL) + LEAVE(NULL); + + pSmi->pHardware->dual = 1; + pSmi->pHardware->primary_screen_rec = pSmi; + pSmi->screen = 0; + + /* Put what you already known into structure */ + #ifdef XSERVER_LIBPCIACCESS + pSmi->pHardware->phyaddr_reg = pPci->regions[1].base_addr; + pSmi->pHardware->physize_reg = 0x200000; + pSmi->pHardware->phyaddr_mem = pPci->regions[0].base_addr; + /*Get total video memory size from misc ccontrol register MMIO_base+0x0004 bit13 and bit12 + pSmi->pHardware->physize_mem = get_total_fb()*/; + pSmi->pHardware->devId = pPci->device_id; + #else + pSmi->pHardware->phyaddr_reg = pPci->memBase[1]; + pSmi->pHardware->physize_reg = 0x200000; + pSmi->pHardware->phyaddr_mem = pPci->memBase[0]; + /*Get total video memory size from misc ccontrol register MMIO_base+0x0004 bit13 and bit12 + pSmi->pHardware->physize_mem = get_total_fb()*/; + pSmi->pHardware->devId = pPci->device; + #endif + + #ifdef XSERVER_LIBPCIACCESS + pSmi->pHardware->revId = pPci->revision; + pSmi->pHardware->pPci = pPci; + #else + //pSmi->pHardware->revId = pPci->chipRev; //ilena guess... + #endif + }else{ + /* + * pSmi->pHardware is not NULL, which means current entity already + * mallocated a SMIHWPtr structure,so we are in dualview + * mode! + * */ + pSmi->pHardware->dual += 1;/*The total number of screen*/ + pSmi->screen = (pSmi->pHardware->dual)-1;/*The index of screen*/ + } + + /*Assign the private function for SM750*/ + + LEAVE(pSmi); +} + +/* + * === FUNCTION ====================================================================== + * Name: sm750_pcDeepmap + * Description: + * ===================================================================================== + */ +void sm750_pcDeepmap(SMIHWPtr pHw) +{ + ENTER(); + SMI750HWPtr p750Hw = (SMI750HWPtr)pHw; + SMIPtr pSmi = HWPSMI(pHw); + ScrnInfoPtr pScrn = SMIPSI(pSmi); + + pHw->DPRBase = pHw->pReg + 0x100000; + pHw->VPRBase = pHw->pReg + 0x000000; + pHw->CPRBase = pHw->pReg + 0x090000; + pHw->DCRBase = pHw->pReg + 0x080000; + pHw->SCRBase = pHw->pReg + 0x000000; + pHw->IOBase = 0; + pHw->DataPortBase = pHw->pReg + 0x110000; + pHw->DataPortSize = 0x10000; + LEAVE(TRUE); +} + +void sm750_vgaAndpciInit(ScrnInfoPtr pScrn,int entityIndex) +{ + ENTER(); +#ifdef XSERVER_LIBPCIACCESS +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,0,0,0) + struct pci_device * pd; + pd = xf86GetPciInfoForEntity(entityIndex); + if(pd && !xf86IsEntityPrimary(entityIndex)){ + /* give up vga legency resource decodes for none-primary vga cards + Note: pci_device_vgaarb_*** function start be exist since libpciaccess v0.11.0 (ubuntu10.04). for v0.10.* and below (ubuntu9.10), + these function will throw you error when startx (but no error occured in compiling) + /* I cannot get libpciaccess version number, so use X server version is a work around */ + pci_device_vgaarb_set_target(pd); + pci_device_vgaarb_decodes(0); + /* monk: + Weird, with only above line, it not work. + it works well together with below line. + root cause: + + Libpciaccess will not use new decode flag passing to its immediate kernel sys call + but use original decode flag, and save new decode flag to its struct member after kernel sys call. + That's make kernel not sync with the latest request .Maybe it's a bug of libpciaccess + So I used a tricky method to fool around the libpciacess in order to make kernel vgaarb + consider this card already disclaimed for its vga legency resource decodings: + + Call again "pci_device_vgaarb_decodes" with meaningless decode flag but not the same as last one + it will make libpciaccess using last saved decode flag (it is 0) as the parameter for kernel sys call + */ + pci_device_vgaarb_decodes(0x10); + }else{ + xf86ErrorF("This should never happen!\n"); + LEAVE(); + } +#endif +#endif + +#ifdef XSERVER_LIBPCIACCESS + /*Enable pci device will open pci config space io/mem bits in theory ( according to kernel source code: pci-sysfs.c ) + Butter... seems 718 and 750 only be enabled for mem bits + */ + pci_device_enable(pd); +#else + /* TODO: how to enable pci device with out libpciaccess ? */ +#endif + LEAVE(); +} + +/* + * === FUNCTION ====================================================================== + * Name: sm750_entityInit + * Description: init hardware + * ===================================================================================== + */ +void sm750_entityInit(int entIndex,pointer private) +{ + initchip_param_t initParam; + SMIHWPtr pHw = (SMIHWPtr)private; + + ENTER(); + + initParam.powerMode = 0; /* Default to power mode 0 */ + initParam.chipClock = DEFAULT_MEMORY_CLK; + initParam.memClock = DEFAULT_MEMORY_CLK; /* Default memory clock to 144MHz */ + initParam.masterClock = initParam.chipClock/3; /* Default master clock to half of mem clock */ + initParam.setAllEngOff = 0; /* Using 2D now*/ + initParam.resetMemory = 1; + + ddk750_set_mmio(pHw->pReg,pHw->devId,0); + ddk750_initHw(&initParam); + + LEAVE(); +} + +/* + * === FUNCTION ====================================================================== + * Name: sm750_entityEnter + * Description: save console's registers + * ===================================================================================== + */ +void sm750_entityEnter(int entIndex,pointer private) +{ + ENTER(); + + sm750_entityInit(entIndex, private); + + LEAVE(); +} + +/* + * === FUNCTION ====================================================================== + * Name: sm750_entityLeave + * Description: restore console's registers + * ===================================================================================== + */ +void sm750_entityLeave(int entIndex,pointer private) +{ + SMIHWPtr pHw = (SMIHWPtr)private; + ENTER(); + if(xf86IsPrimaryPci(pHw->pPci)) + { + /* Restore the registers */ + restore_reg_750((SMIHWPtr)private); + /* Restore the vga fonts */ + sm750_restoreFonts((SMIHWPtr)private); + } + LEAVE(); +} +void sm750_saveText(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR (pScrn); + + ENTER(); + /* This functin called from entity init, + Of course, it is the primary device */ + if(xf86IsPrimaryPci(pSmi->pHardware->pPci)) + { + /* Save the vga fonts */ + sm750_saveFonts(pSmi->pHardware); + /* Save the registers */ + save_reg_750(pSmi->pHardware); + } + LEAVE(); +} +/* + * === FUNCTION ====================================================================== + * Name: sm750_getMapResult + * Description: calculate the frame buffer for the current screen + * ===================================================================================== + */ +void sm750_getMapResult(ScrnInfoPtr pScrn) +{ + vgaHWPtr hwp; + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + ENTER(); + + /* set video memory size */ + pSmi->videoRAMBytes = pHw->physize_mem / (pSmi->pHardware->dual); + pScrn->videoRam = (pSmi->videoRAMBytes)>>10;/* kbytes*/ + + /* set pScrn physica address*/ + pScrn->memPhysBase = pHw->phyaddr_mem; + pScrn->memPhysBase += (pSmi->screen) * pSmi->videoRAMBytes; + + /* set OFFSET */ + pScrn->fbOffset = pSmi->FBOffset = pScrn->memPhysBase - pHw->phyaddr_mem; + + /* set virtual address */ + pSmi->pFB = pHw->pMem; + pSmi->pFB += (pSmi->screen) * pSmi->videoRAMBytes; + + pSmi->FBReserved = pSmi->videoRAMBytes - 4096; + + if (!pSmi->width) + pSmi->width = pScrn->displayWidth; + if (!pSmi->height) + pSmi->height = pScrn->virtualY; + + pSmi->Bpp = pScrn->bitsPerPixel / 8; + pSmi->Stride = (pSmi->width * pSmi->Bpp + 15) & ~15; + + LEAVE(); +} + +void sm750_handleOptions(ScrnInfoPtr pScrn) +{ + ENTER(); + if (pScrn->depth == 8) + { + pScrn->rgbBits = 8; + } + LEAVE(); +} + +ModeStatus sm750_validMode(ScrnInfoPtr pScrn,DisplayModePtr pMode) +{ + ENTER(); + LEAVE(MODE_OK); +} + +void sm750_setMode(ScrnInfoPtr pScrn,DisplayModePtr pMode) +{ + SMIPtr pSmi = SMIPTR (pScrn); + SMIHWPtr pHw = pSmi->pHardware; + I2CBusPtr bus; + ENTER(); + + mode_parameter_t parm; + clock_type_t clock; + + if(pSmi->pci_burst && (pSmi->pHardware->pPci == SMI_718)) + enable_pci_burst_718(pHw); + +#if SMI_RANDR + if (pSmi->dispCtrl == PANEL) + clock = PRIMARY_PLL; + else if (pSmi->dispCtrl == CRT) + clock = SECONDARY_PLL; +#else + + if (pSmi->screen == 0) + clock = PRIMARY_PLL; + else if (pSmi->screen == 1) + clock = SECONDARY_PLL; +#endif + /* Horizontal timing. */ + parm.horizontal_total = pMode->HTotal; + parm.horizontal_display_end = pMode->HDisplay; + parm.horizontal_sync_start = pMode->HSyncStart; + parm.horizontal_sync_width = pMode->HSyncEnd - pMode->HSyncStart; + parm.horizontal_sync_polarity = (pMode->Flags & V_PHSYNC)?POS:NEG; + + /* Vertical timing. */ + parm.vertical_total = pMode->VTotal; + parm.vertical_display_end = pMode->VDisplay; + parm.vertical_sync_start = pMode->VSyncStart; + parm.vertical_sync_height = pMode->VSyncEnd - pMode->VSyncStart;; + parm.vertical_sync_polarity = (pMode->Flags & V_PVSYNC)?POS:NEG; + + /* Refresh timing. */ + parm.pixel_clock = pMode->Clock*1000; + parm.horizontal_frequency = roundDiv(parm.pixel_clock, + parm.horizontal_total); + parm.vertical_frequency = roundDiv(parm.horizontal_frequency, + parm.vertical_total); + + /* Clock Phase. This clock phase only applies to Panel. + parm.clock_phase_polarity = pMode->;*/ + xf86Msg(X_INFO,"Set Mode H: %x; V: %x; clock: %x\n", + parm.horizontal_total, parm.vertical_total, clock); + + ddk750_set_mmio(pHw->pReg,pHw->devId,0); + ddk750_setModeTiming(&parm, clock); + + LEAVE(); +} + +void sm750_setDisplay(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + int pitch; + int bpp = pScrn->bitsPerPixel; + SMIPtr pSmi = SMIPTR (pScrn); + SMIHWPtr pHw = pSmi->pHardware; + + ENTER(); + + display_t channel; +#if SMI_RANDR + if (pSmi->dispCtrl == PANEL) + channel = PANEL; + else if (pSmi->dispCtrl == CRT) + channel = CRT; +#else + if(pSmi->IsPrimary) + channel = PANEL; + else + channel = CRT; +#endif + /* + * Pitch value calculation in Bytes. + * Usually, it is (screen width) * (byte per pixel). + * However, there are cases that screen width is not 16 pixel aligned, which is + * a requirement for some OS and the hardware itself. + * For standard 4:3 resolutions: 320, 640, 800, 1024 and 1280, they are all + * 16 pixel aligned and pitch is simply (screen width) * (byte per pixel). + * + * However, 1366 resolution, for example, has to be adjusted for 16 pixel aligned. + */ + /* "+ 15) & ~15)" This calculation has no effect on 640, 800, 1024 and 1280. */ + pitch = ((pSmi->width + 15) & ~15) * (bpp / 8); + xf86Msg(X_INFO,"sm750 set Display:pitch: %x\n", pitch); + + set_display_750(pHw, channel, bpp, pitch, pSmi->FBOffset, mode->HDisplay, mode->HTotal); + LEAVE(); +} + +void sm750_adjustFrame(ScrnInfoPtr pScrn,int offset) +{ + ENTER(); + LEAVE(); +} + +void sm750_closeAllScreen(SMIHWPtr pHw) +{ + ENTER(); + SMI750HWPtr p750Hw; + p750Hw = (SMI750HWPtr)pHw; + + if(p750Hw->pRegSave) + { + xf86Msg(X_INFO,"Close Screen Free saved reg\n"); + xfree(p750Hw->pRegSave); + p750Hw->pRegSave = NULL; + } + + if(p750Hw->fonts) + { + xf86Msg(X_INFO,"Close Screen Free saved fonts\n"); + xfree(p750Hw->fonts); + p750Hw->fonts = NULL; + } + xfree(p750Hw); + LEAVE(); +} + +/* Save vga fonts */ +static void sm750_saveFonts(SMIHWPtr pHw) +{ + SMI750HWPtr p750Hw = (SMI750HWPtr)pHw; + + ENTER(); + + /* leave if in graphic mode */ + if(get_vga_mode_750(pHw) & 0x2) + LEAVE(); + + memcpy((char *)p750Hw->fonts,(char *)pHw->pMem + KB(0),KB(64)); + + /* not use legency method to access vga fonts , or multi-card will cry */ + + LEAVE(); +} + +static void sm750_restoreFonts(SMIHWPtr pHw) +{ + SMI750HWPtr p750Hw = (SMI750HWPtr)pHw; + + ENTER(); + + if(p750Hw->fonts) + memcpy((char *)pHw->pMem + KB(0),(char *)p750Hw->fonts,KB(64)); + + /* not use legency method or multi-card cries */ + + LEAVE(); +} + +int sm750_totalFB(SMIHWPtr pHw) +{ + unsigned int total_memory; + ENTER(); + + ddk750_set_mmio(pHw->pReg,pHw->devId,0); + total_memory = ddk750_getVMSize(); + + LEAVE(total_memory); +} + +void sm750_loadPalette (ScrnInfoPtr pScrn, int numColors, + int *indicies, LOCO * colors, VisualPtr pVisual) +{ + ENTER(); +#if SMI_RANDR + + xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); + int crtc_idx,i,j; + + if(pScrn->bitsPerPixel == 16){ + /* Expand the RGB 565 palette into the 256-elements LUT */ + + for(crtc_idx=0; crtc_idxnum_crtc; crtc_idx++){ + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtcConf->crtc[crtc_idx]); + + for(i=0; ilut_r[idx*8 + j] = colors[idx].red << 8; + crtcPriv->lut_b[idx*8 + j] = colors[idx].blue << 8; + } + } + + for(j=0; j<4; j++) + crtcPriv->lut_g[idx*4 + j] = colors[idx].green << 8; + } + + crtcPriv->load_lut(crtcConf->crtc[crtc_idx]); + } + }else{ + for(crtc_idx=0; crtc_idxnum_crtc; crtc_idx++){ + SMICrtcPrivatePtr crtcPriv = SMICRTC(crtcConf->crtc[crtc_idx]); + + for(i = 0; i < numColors; i++) { + int idx = indicies[i]; + + crtcPriv->lut_r[idx] = colors[idx].red << 8; + crtcPriv->lut_g[idx] = colors[idx].green << 8; + crtcPriv->lut_b[idx] = colors[idx].blue << 8; + } + + crtcPriv->load_lut(crtcConf->crtc[crtc_idx]); + } + } + +#endif + LEAVE(); +} + +#if SMI_RANDR +void sm750_I2CInit(ScrnInfoPtr pScrn) +{ + SMIPtr pSmi = SMIPTR(pScrn); + SMIHWPtr pHw = pSmi->pHardware; + int cnt = pSmi->DualView?2:1; + int index; + I2CBusPtr ptr[2] = {NULL,NULL}; + static char * sm750_name[] = {"I2C Bus PanelPath","I2C Bus CrtPath"}; + ENTER(); + + pfn_I2CPutBits_750[0] = i2c_putbits_panel_750; + pfn_I2CPutBits_750[1] = i2c_putbits_crt_750; + pfn_I2CGetBits_750[0] = i2c_getbits_panel_750; + pfn_I2CGetBits_750[1] = i2c_getbits_crt_750; + + index= 0 ; + while(index < cnt) + { + if(ptr[index] == NULL ) + { + I2CBusPtr I2CPtr = xf86CreateI2CBusRec(); + if (I2CPtr == NULL) + return FALSE; + + I2CPtr->scrnIndex = pScrn->scrnIndex; + I2CPtr->BusName = sm750_name[index]; + I2CPtr->I2CPutBits = pfn_I2CPutBits_750[index]; + I2CPtr->I2CGetBits = pfn_I2CGetBits_750[index]; + + + I2CPtr->DriverPrivate.ptr = (void *)xalloc(sizeof(int)); + + if (!xf86I2CBusInit(I2CPtr)){ + xfree(I2CPtr->DriverPrivate.ptr); + xf86DestroyI2CBusRec(I2CPtr, TRUE, TRUE); + LEAVE(FALSE); + } + + ptr[index] = I2CPtr; + /* for sm712: 0 means CRT HEAD i2c bus + for sm750: 0 means PANEL HEAD i2c bus, + note that head is not pll + */ + *((int *)I2CPtr->DriverPrivate.ptr) = index; + } + index++; + } + + pSmi->I2C_primary = ptr[0]; + pSmi->I2C_secondary = ptr[1]; + + init_i2c_750(pHw); + + LEAVE(TRUE); +} +#endif diff --git a/src/drv750/smi_750_driver.h b/src/drv750/smi_750_driver.h new file mode 100644 index 0000000..288611b --- /dev/null +++ b/src/drv750/smi_750_driver.h @@ -0,0 +1,64 @@ +#ifndef SMI_750_INC +#define SMI_750_INC + +#include "smi_750_hw.h" +#include "../ddk750/ddk750.h" +#include "../ddk750/ddk750_chip.h" +#include "../ddk750/ddk750_mode.h" + +#if VALIDATION_CHIP==1 +#else +#define VALIDATION_CHIP 1 +#endif + +#define PLL_INDEX_MAX 12 +#define DEFAULT_INPUT_CLOCK 14318181 + +typedef struct { + /* put common structure here */ + SMIHWRec base; + /* put chip dependent stuffs here*/ + SMI750RegPtr pRegSave; + /* vga stuffs */ + char * fonts; +}SMI750HWRec,*SMI750HWPtr; + +typedef struct { + /* we best put base in header of structure*/ + SMIRec base; + /* chip dependent stuffs of this pSmi*/ + int csc;/* use csc video or not */ +}SMI750Rec,*SMI750Ptr; + +SMIPtr sm750_genSMI(pointer priv,int); +void sm750_vgaAndpciInit(ScrnInfoPtr pScrn,int entityIndex); +void sm750_entityInit(int,pointer); +void sm750_entityEnter(int,pointer); +void sm750_entityLeave(int,pointer); +void sm750_getMapResult(ScrnInfoPtr); +void sm750_handleOptions(ScrnInfoPtr); +ModeStatus sm750_validMode(ScrnInfoPtr,DisplayModePtr); +void sm750_loadPalette (ScrnInfoPtr , int , int *, LOCO * , VisualPtr ); +void sm750_setMode(ScrnInfoPtr,DisplayModePtr); +void sm750_adjustFrame(ScrnInfoPtr,int); +void sm750_setDisplay(ScrnInfoPtr pScrn, DisplayModePtr mode); +void sm750_pcDeepmap(SMIHWPtr pHw); +void sm750_saveText(ScrnInfoPtr pScrn); +static void sm750_saveFonts(SMIHWPtr pHw); +static void sm750_restoreFonts(SMIHWPtr pHw); +void sm750_closeAllScreen(SMIHWPtr pHw); +int sm750_totalFB(SMIHWPtr pHw); + +extern unsigned int ddk750_getVMSize(); +extern int ddk750_initHw(initchip_param_t * pInitParam); +extern void ddk750_setLogicalDispOut(disp_output_t output); +extern int ddk750_initDVIDisp(); +extern int PEEK32(addr) ; +extern void POKE32(addr,data); +extern void ddk750_set_mmio(volatile unsigned char * addr,unsigned short devId,unsigned long revId); +extern int ddk750_setModeTiming(mode_parameter_t * parm,clock_type_t clock); +extern void ddk750_setDPMS(DPMS_t state); +extern Bool SMI750_CrtcPreInit(ScrnInfoPtr pScrn); +extern Bool SMI750_OutputPreInit(ScrnInfoPtr pScrn); +void sm750_I2CInit(ScrnInfoPtr pScrn); +#endif /* ----- #ifndef SMI_750_INC ----- */ diff --git a/src/drv750/smi_750_hw.c b/src/drv750/smi_750_hw.c new file mode 100644 index 0000000..2161055 --- /dev/null +++ b/src/drv750/smi_750_hw.c @@ -0,0 +1,237 @@ +#include "../smi_common.h" +#include "../smi_driver.h" +#include "../ddk750/ddk750.h" +#include "../ddk750/ddk750_display.h" +#include "../ddk750/ddk750_power.h" +#include "smi_750_hw.h" +#include "smi_750_driver.h" +#include "../smi_dbg.h" + +/* +IF THE FUNCTION WHOSE NAME POSTFIXED WITH 718, IT IS ONLY FOR SM718 +IF THE FUNCTION WHOSE NAME POSTFIXED WITH 750, IT IS FOR SM750 AND SM718 +IF THE FUNCTION WHOSE NAME POSTFIXED WITH 750o, IT IS ONLY FOR SM750 +*/ +/***************************** + For FB Display + *****************************/ +void enable_pci_burst_718(SMIHWPtr pHw) +{ + /* Enable PCI_BURST for SM718 */ + unsigned long tmp = PEEK32(SYSTEM_CTRL); + ddk750_set_mmio(pHw->pReg,pHw->devId,0); + POKE32(SYSTEM_CTRL, tmp | 0x20000000); +} + +/*Set the bpp and date channel and pitch for panel*/ +void set_display_750(SMIHWPtr pHw, display_t display, int bpp, int pitch, int ulBaseAddress,int HDisplay, int HTotal ) +{ + int SetValue; + disp_output_t output; + + ddk750_set_mmio(pHw->pReg,pHw->devId,0); + + if(display == PANEL){ + SetValue = PEEK32 (PANEL_DISPLAY_CTRL); + + SetValue = (bpp == 8 ? + FIELD_SET(SetValue, PANEL_DISPLAY_CTRL, FORMAT, 8) + : (bpp == 16 ? + FIELD_SET(SetValue, PANEL_DISPLAY_CTRL, FORMAT, 16) + : FIELD_SET(SetValue, PANEL_DISPLAY_CTRL, FORMAT, 32))); + + + POKE32(PANEL_DISPLAY_CTRL, SetValue); + + output = do_LCD1_PRI; + ddk750_setLogicalDispOut(output); + + if(pHw->dual==1) + { + /* For mirror, vga and dvi use the primary channel data in common*/ + output = do_LCD2_PRI; + ddk750_setLogicalDispOut(output); + } +#if SMI_RANDR == 0 + POKE32(PANEL_FB_ADDRESS, + FIELD_SET(0, PANEL_FB_ADDRESS, STATUS, PENDING) + | FIELD_SET(0, PANEL_FB_ADDRESS, EXT, LOCAL) + | FIELD_VALUE(0, PANEL_FB_ADDRESS, ADDRESS, ulBaseAddress)); + + + POKE32(PANEL_FB_WIDTH, + FIELD_VALUE(0, PANEL_FB_WIDTH, WIDTH, pitch) + | FIELD_VALUE(0, PANEL_FB_WIDTH, OFFSET, pitch)); + +#endif + } + else if (display == CRT){ + SetValue = PEEK32 (CRT_DISPLAY_CTRL); + + SetValue = (bpp == 8 ? + FIELD_SET(SetValue, CRT_DISPLAY_CTRL, FORMAT, 8) + : (bpp == 16 ? + FIELD_SET(SetValue, CRT_DISPLAY_CTRL, FORMAT, 16) + : FIELD_SET(SetValue, CRT_DISPLAY_CTRL, FORMAT, 32))); + + POKE32(CRT_DISPLAY_CTRL, SetValue); + + output = do_CRT_SEC;//do_LCD2_SEC; + ddk750_setLogicalDispOut(output); + + POKE32(CRT_FB_WIDTH, + FIELD_VALUE(0, CRT_FB_WIDTH, WIDTH,pitch) + | FIELD_VALUE(0, CRT_FB_WIDTH, OFFSET, pitch)); + + POKE32(CRT_FB_ADDRESS, + FIELD_SET(0, CRT_FB_ADDRESS, STATUS, PENDING) + | FIELD_SET(0, CRT_FB_ADDRESS, EXT, LOCAL) + | FIELD_VALUE(0, CRT_FB_ADDRESS, ADDRESS, ulBaseAddress));// adjust the right screen's FB. + + } +} + +void save_reg_750(SMIHWPtr pHw) +{ + int i, j; + SMI750HWPtr p750Hw = (SMI750HWPtr)pHw; + SMI750RegPtr save = p750Hw->pRegSave; + + ENTER(); + ddk750_set_mmio(pHw->pReg,pHw->devId,0); + + + /* save mmio */ + for (i = REG_SYS_HEAD, j = 0; i <= REG_SYS_TAIL; i += 4, j++){ + save->System[j] = PEEK32(i); + } + + for (i = REG_PNL_HEAD, j = 0; i <= REG_PNL_TAIL; i += 4, j++){ + save->PanelControl[j] = PEEK32(i); + } + + for (i = REG_CRT_HEAD, j = 0; i<=REG_CRT_TAIL; i+= 4, j++) { + save->CRTControl[j] = PEEK32(i); + } + + for(i=REG_PCUR_HEAD,j = 0;i<=REG_PCUR_TAIL;i+=4,j++){ + save->PriCursorControl[j] = PEEK32(i); + } + + for(i=REG_SCUR_HEAD,j = 0;i<=REG_SCUR_TAIL;i+=4,j++){ + save->SecCursorControl[j] = PEEK32(i); + } + + LEAVE(); +} + +void restore_reg_750(SMIHWPtr pHw) +{ + int i, j; + SMI750HWPtr p750Hw = (SMI750HWPtr)pHw; + SMI750RegPtr save = p750Hw->pRegSave; + + ENTER(); + ddk750_set_mmio(pHw->pReg,pHw->devId,0); + + /* restore mmio */ + for(i = REG_SYS_HEAD,j = 0 ;i<= REG_SYS_TAIL ;i+=4,j++) + { + POKE32(i,save->System[j]); + } + + for(i = REG_PNL_HEAD, j = 0 ;i<= REG_PNL_TAIL ;i+=4,j++) + { + POKE32(i,save->PanelControl[j]); + } + + for(i = REG_CRT_HEAD,j = 0 ;i<= REG_CRT_TAIL ;i+=4,j++) + { + POKE32(i,save->CRTControl[j]); + } + + for(i = REG_PCUR_HEAD,j = 0 ;i<= REG_PCUR_TAIL ;i+=4,j++) + { + POKE32(i,save->PriCursorControl[j]); + } + + + for(i = REG_SCUR_HEAD,j = 0 ;i<= REG_SCUR_TAIL ;i+=4,j++) + { + POKE32(i,save->SecCursorControl[j]); + } + + /* The followding is to restore fonts */ + + LEAVE(); +} + +int get_vga_mode_750(SMIHWPtr pHw) +{ + ddk750_set_mmio(pHw->pReg,pHw->devId,0); + return FIELD_GET(PEEK32(VGA_CONFIGURATION),VGA_CONFIGURATION,MODE); +} + +/***************************** + For Accelerate + *****************************/ + +void wait_for_not_busy_750(SMIPtr pSmi) +{ + SMIHWPtr pHw = pSmi->pHardware; + DWORD dwVal; + int i; + ddk750_set_mmio(pHw->pReg,pHw->devId,0); + + for (i = 0x1000000; i > 0; i--) + { + dwVal = PEEK32(SYSTEM_CTRL); + if ((FIELD_GET(dwVal, SYSTEM_CTRL, DE_STATUS) == SYSTEM_CTRL_DE_STATUS_IDLE) && + (FIELD_GET(dwVal, SYSTEM_CTRL, DE_FIFO) == SYSTEM_CTRL_DE_FIFO_EMPTY) && + (FIELD_GET(dwVal, SYSTEM_CTRL, CSC_STATUS) == SYSTEM_CTRL_CSC_STATUS_IDLE) && + (FIELD_GET(dwVal, SYSTEM_CTRL, DE_MEM_FIFO ) == SYSTEM_CTRL_DE_MEM_FIFO_EMPTY) && + TRUE + ) + { + break; + } + } +} + +void init_i2c_750(SMIHWPtr pHw) +{ + ddk750_set_mmio(pHw->pReg,pHw->devId,0); + /* set mux for the i2c scl/sda*/ + int val = PEEK32(GPIO_MUX); + + val = FIELD_SET(val,GPIO_MUX,31,GPIO); + val = FIELD_SET(val,GPIO_MUX,30,GPIO); + val = FIELD_SET(val,GPIO_MUX,18,GPIO); + val = FIELD_SET(val,GPIO_MUX,17,GPIO); + POKE32(GPIO_MUX,val); + + /* enable GPIO gate*/ + enableGPIO(1); +} + +void i2c_putbits_panel_750(I2CBusPtr bus,int clock,int data) +{ + ddk750_I2CPutBits_panel(bus, clock, data); +} + +void i2c_putbits_crt_750(I2CBusPtr bus,int clock,int data) +{ + ddk750_I2CPutBits_crt(bus, clock, data); +} + +void i2c_getbits_panel_750(I2CBusPtr bus,int* clock,int* data) +{ + ddk750_I2CGetBits_panel(bus, clock, data); +} + +void i2c_getbits_crt_750(I2CBusPtr bus,int* clock,int* data) +{ + ddk750_I2CGetBits_crt(bus, clock, data); +} + + diff --git a/src/drv750/smi_750_hw.h b/src/drv750/smi_750_hw.h new file mode 100644 index 0000000..1acc82c --- /dev/null +++ b/src/drv750/smi_750_hw.h @@ -0,0 +1,54 @@ +#ifndef SMI_750_HW_INC +#define SMI_750_HW_INC + +//simple save --wish to add the function to DDK +#define REG_SYS_HEAD 0x0 +#define REG_SYS_TAIL 0x88 +#define REG_PNL_HEAD 0x80000 +#define REG_PNL_TAIL 0x80034 +#define REG_CRT_HEAD 0x80200 +#define REG_CRT_TAIL 0x80228 +#define REG_ALPH_HEAD 0x80100 +#define REG_ALPH_TAIL 0x80114 +#define REG_PCUR_HEAD 0x800f0 +#define REG_PCUR_TAIL 0x800fc +#define REG_SCUR_HEAD 0x80230