diff options
author | Jordan Crouse <jordan.crouse@amd.com> | 2007-05-10 10:39:08 -0600 |
---|---|---|
committer | Jordan Crouse <jordan.crouse@amd.com> | 2007-05-10 10:39:08 -0600 |
commit | 217eeed3c1659cc9e0f13ba6932d1342c0255df4 (patch) | |
tree | 54e8ee9ebdb39200680af602048f9fbc749e1489 | |
parent | 6d1942fb5e9a1e37baae3ec8559f9567ddeb2f67 (diff) | |
parent | 022a106b38693d2d705e8c15ad84c18832fa2e8c (diff) |
Merge Geode GX and LX development from OLPC
Conflicts:
man/amd.man
44 files changed, 6584 insertions, 12343 deletions
diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index e69de29..0000000 --- a/ChangeLog +++ /dev/null diff --git a/Makefile.am b/Makefile.am index 7052905..16f4412 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,4 +19,4 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. AUTOMAKE_OPTIONS = foreign -SUBDIRS = src man +SUBDIRS = src @@ -1,878 +1,51 @@ -AMD Geode(TM) LX/GX Processor Xorg Display Driver - Release Notes -Version 04.00.00-01 -June 18, 2006 +AMD Geode GX and LX Xorg graphics Driver +May 9, 2007 +======================================== --------------------------------------------------------------------------------- -PRODUCT INFORMATION --------------------------------------------------------------------------------- -- This driver is the Xorg Display Driver for the AMD Geode(TM) Geode LX and - GX processors += Introduction = -This product is avaiable as a standalone patch comprising: - Graphics_LinuxXorg_Common_03.00.0101.patch - README.txt (this file) +This is the X graphics driver for the AMD Geode GX and LX processors. +The GX driver features XAA and EXA support for graphics acceleration, +and the LX driver supports EXA (including compositing). Both drivers +suppport dynamic rotation with XRandR, and Xv overlay support. -or as a tarball Graphics_LinuxXorg_Common_03.00.0101.tar.gz containing: - Graphics_LinuxXorg_Common_03.00.0101.patch - xorg.conf_lx - xorg.conf_gx - README.txt (this file) += Configuration options = -The patch adds the following documenation to the Xorg tree: -xc/programs/Xserver/hw/xfree86/drivers/amd/amd.man -xc/programs/Xserver/hw/xfree86/drivers/amd/gfx/release.txt (GX only) -xc/programs/Xserver/hw/xfree86/drivers/amd/panel/readme.txt (GX only) +You can specify the AMD driver in the normal fashion: -The following example files are provided in the tarball release only - xorg.conf_lx - xorg.conf_gx - -For bugs, patches, and info requests, please subscribe to: -info-linux@geode.amd.com - -To subscribe, send a blank message to: info-linux-subscribe@geode.amd.com - -Features --------- -The AMD Geode Linux Xorg driver implements Xorg XAA driver interface. -Through a hardware abstraction layer called Durango (GX) and Cimarron (LX), -the full accelerated functionality of the graphics processor is exposed to -the driver. - -The AMD Geode Xorg driver implements: - - - Xv video overlay extension support - - Geode hardware color-space conversion - - V4L2 overlay functionality (Geode LX processor only) - - Rotated graphical output - - DDC support - - DPMS support - - Common X.org patch support both Geode LX and GX processors - -Dependencies ------------- -This release depends on and includes the following subcomponents: - -Linux Build Tool - Base GeodeLinux Build System - Version 00.00.0021 -Linux Build Tool - AMD Embedded - Version 00.00.0022 -Linux Build Tool - Bitbake engine - Version 00.00.0011 -Linux Build Tool - Openembedded - Version 00.00.0008 - - -Functional Changes ------------------- -_____________________________________________________________________________ -Change: 78946 -_____________________________________________________________________________ -Add multiple BUILDCONFIG functionality to Tinderbox glue. - -_____________________________________________________________________________ -Change: 79682 -_____________________________________________________________________________ -Initial add of LinuxBIOSv2 source tree to Perforce. This code base matches -upstream SVN version 2296. Add P4MOD BOMs and Tinderbox configuration/linuxbios- -devel GeodeLinux targets. - -_____________________________________________________________________________ -Change: 81342 -_____________________________________________________________________________ -mplayer: enable qtx, opengl, libdvd, and alsa. xorg: enable Xft and Xinerama -icewm: configure and .bb patches for identifying correct X includes/libs - -_____________________________________________________________________________ -Change: 80914 -_____________________________________________________________________________ -Add a klocwork DISTRO and some task-*-klocwork meta files to define the -projects to build for klocwork. Move KWBUILD to the configuration file. Add -some klocwork report generation to klocwork.bbclass. - -_____________________________________________________________________________ -Change: 80794 -_____________________________________________________________________________ -klocwork.bbclass updates to support client/host and build renaming. Add a -draft nightly build script for klocwork builds. Only those .bb files with -KWBUILD=1 will be built here. Add COMPATIBLE_HOST for geode .bb files. -virtual/geode-aes must point to linux-geodelx with 2.6.16 now that this -is integrated. recent gcc-sdk-native changes were resulting in empty -packages. Revert and disable task-compilers from validation-image for -swval until this can be repaired. - -_____________________________________________________________________________ -Change: 79683 -_____________________________________________________________________________ -Release and devel .bb files for linuxbios pass build on morlock. - -_____________________________________________________________________________ -Change: 81340 -_____________________________________________________________________________ -Add libxinerama to xorg 6.8.1 config for icewm. xscreensaver depends upon intltool- -native. Use '/usr/bin/env perl' as intltool-* interpreter. - -_____________________________________________________________________________ -Change: 81186 -_____________________________________________________________________________ -Add geodelx-6.8.1 machine for norwich validation on 2.6.16+xorg6.8.1. Leave -geodelx machine at X11R7.0 because upgrade to X11R7.1 is imminent. Move x11 -clients from validation-image to task-xorg because the packages differ -between 6.8.1 and 7.0. Add p4 binaries to validation-image. Add icewm to -validation-image. - -_____________________________________________________________________________ -Change: 80319 -_____________________________________________________________________________ -* Cleanup X11R6.8.1 PROVIDERS for 'gentoo' builds. - * Created a new .bb file to correctly handle the 'gentoo'->other - branch of validationtests. - * ztv for 2.4.24 depends upon libxv as well - * Add 'Kernel Build Directory' to /etc/openembedded/version for gcov - builds so that GCOV_PREFIX environment variables may be used - effectively. - * disable ica-bin download error in amd/packages/ica because we have - this downloaded to the internal mirror morlock. - -_____________________________________________________________________________ -Change: 80637 -_____________________________________________________________________________ -add project/geodelx/unittest/ and configuration files - -_____________________________________________________________________________ -Change: 80373 -_____________________________________________________________________________ -libxft and libxrandr PROVIDERS for geodelx and dimsum are X11R7.0. configure -proxy variables in environment rather than command line for LSF builds. - -_____________________________________________________________________________ -Change: 79322 -_____________________________________________________________________________ -dimsum cleanup. - -_____________________________________________________________________________ -Change: 80630 -_____________________________________________________________________________ -Disable CCACHE for gcov builds so gcda files go to the correct location. - -_____________________________________________________________________________ -Change: 80370 -_____________________________________________________________________________ -Merge with OE snapshot from 2006/06/02: -http://eloi.amd.com/openembedded/oe/oe_20060602030001.tgz - -and Bitbake version 1.4.2: http://eloi.amd.com/openembedded/bitbake/bitbake- -1.4.2.tar.gz - -_____________________________________________________________________________ -Change: 80969 -_____________________________________________________________________________ -Propegate 80912 to local.rules for other images. Add x11perf, xclock, xvinfo, -rdesktop, and xpandmodes to validation-image. Add xvtest to amdtools RDEPENDS -so that it makes it to the image. - -_____________________________________________________________________________ -Change: 78809 -_____________________________________________________________________________ -Update task-compilers. This appears to build the 2.6.16 kernel OK (save -storage requirements for object files). Im adding this to the validation- -image for a quick build on LSF. Next, I will make this an optional package. - -_____________________________________________________________________________ -Change: 79843 -_____________________________________________________________________________ -Merge //drivers/buildroot/geodelinux/...@79818 and -//depot/tools/buildroot/geodelinux/...@51650. - -_____________________________________________________________________________ -Change: 79588 -_____________________________________________________________________________ -Merge //drivers/buildroot/geodelinux/...@79560 and -//depot/tools/buildroot/geodelinux/...@51580 - -_____________________________________________________________________________ -Change: 81291 -_____________________________________________________________________________ -Add serf for 2.6.11 to OE and Gentoo. - -_____________________________________________________________________________ -Change: 81312 -_____________________________________________________________________________ -intltool-native perl script use #/usr/bin/env perl interpreter. more validation- -tests postinst updates. Update PREFERRED_PROVIDERS for devel targets to -geode-v4l2lx-devel. Leave release at linux-geodelx until we have a release -to replace it with. - -_____________________________________________________________________________ -Change: 79362 -_____________________________________________________________________________ -PBz#8158: Add /etc/modules.autoload.d/kernel-2.6 file including lxv4l2 to -2.6.11, 2.6.15, and 2.6.16 Gentoo kernel builds. Add lxv4l2 to autoload list -for processing by kernel.bbclass for GeodeLinux kernel builds. Add /etc/udev/rules.d/10- -local.rules file for symlinking videox -> video0 at hotplug event for Gentoo. -Update /etc/udev/local.rules file for symlinking videox -> video0 at hotplug -event for GeodeLinux. - -_____________________________________________________________________________ -Change: 78909 -_____________________________________________________________________________ -Patches for $ 'cross' compile. Gentoo and Debian store 32bit libraries in -/lib32 and 64bit in /lib64. There are apparently two standards for this, but -I'm patching gcc to follow Gentoo/Debian multilib convention. This is still -giving a build failure in libstdc++-v3, however, pulling in multilib -libraries. - -_____________________________________________________________________________ -Change: 81109 -_____________________________________________________________________________ -Remove xterm from validation-image. Symlink rxvt -> xterm instead. Replace -eog with gqview in validation-image. Remove AMD_DRIVER_VERSION mangling from -klocwork.bbclass. Add defconfig for klocwork kernel build. - -_____________________________________________________________________________ -Change: 81004 -_____________________________________________________________________________ -Move to libtool 1.5.22. Appears to resolve some obscure cross-linking issues. -klocwork.bbclass - mipsel analysis was failing due to $ definition from -project name to build name. If AMD_DRIVER_VERSION is defined, prefix project -name with amd_, otherwise oe_ Add task kwinstall for installing report files. -Add .bb files for X11R7.0 75DPI fonts. Add font-bh-75dpi to task-xorg Add xf86-video- -vga to task-org as a fallback. Add xauth to validation-image Update default -xorg.conf. z4l has been renamed to ztv. Add Eye of Gnome image viewer to validation- -image. This depends upon *alot* of gnome, so it should be replaced or gnome -should take over matchbox as session manager. - -_____________________________________________________________________________ -Change: 80378 -_____________________________________________________________________________ -Mesa compiles using the correct compiler. Remove redundant files from glib- -2.0 packaging. More DEPENDS and site-packages.conf cleanup. Disable exclusive -bsub for now. gcov-tools listed twice in validation-image. - -_____________________________________________________________________________ -Change: 80372 -_____________________________________________________________________________ -syslinux was moved upstream. Add to site-packages.conf. - -_____________________________________________________________________________ -Change: 80359 -_____________________________________________________________________________ -Add matchbox and xterm to validation-image. Replaces xfce. Add ica-bin-9.0, -but this is broken until openmotif builds. - -_____________________________________________________________________________ -Change: 79975 -_____________________________________________________________________________ -Add perl and python to validation-image. record-play and pio_check use perl. -pixel-depth and i2cval use python. - -_____________________________________________________________________________ -Change: 79680 -_____________________________________________________________________________ -Move GeodeLinux to ldcperforce1. - -_____________________________________________________________________________ -Change: 78811 -_____________________________________________________________________________ -Disable task-compilers in validation-image by default. - -Unit Test ---------- -_____________________________________________________________________________ -Change: 81004 : Move to libtool 1.5.22. Appears to resolve some obscure cross -_____________________________________________________________________________ -HOST_ARCH definition. Move $PN - --------------------------------------------------------------------------------- -VALIDATION ENVIRONMENT --------------------------------------------------------------------------------- -Validated on AMD Geode(TM) Norwich Development Board - Rev 2 Rework H and -Rev 3 Rework E with: - -Processor: AMD Geode LX processor, silicon rev. C1 @ 433 MHz -Chipset: AMD Geode CS5536 companion device, silicon rev. B1 -PCI Bus Speed: 66 MHz -Memory: 256 MB PC3200 RAM -CRT: NEC MultiSync FP2141SB -Flat Panel: Samsung LTM213U3-L07 1600x1200 2-channel LVDS, -Keyboard/Mouse: PS/2 on Moray 1.1 - -BIOS: GeodeROM 1.06.06 -Operating System: Gentoo 2005.0 -Kernel: v2.6.11 -Kernel Patch: LX Kernel Patch v02.02.0100 -Graphics Driver: LX Xorg Graphics driver v03.00.0100 -Audio Driver: 5536 ALSA Audio driver v01.00.0500 -AES Driver: LX AES driver v02.01.0100 -AccessBus Driver: LX ACB Driver v01.00.0401 -Video4Linux2 Driver: LX Video4Linux2 driver v03.02.0100 -Other Software: N/A - --------------------------------------------------------------------------------- -INSTALLATION INSTRUCTIONS --------------------------------------------------------------------------------- -Acquire Xorg Tarball from the Xorg web site: -http://www.x.org/X11R6.8.1/ - -For more information on X.org: -http://xorg.freedesktop.org/wiki/ - -Acquire Graphics_LinuxXorg_Common_03.00.0100.patch - -Unpack Xorg Tarball -Patch the Source -Make Xorg -Construct Install -Apply Install image - -for example: - # tar -xzf X11R6.8.1-src.tar.gz - # cd xc - # patch -p1 < Graphics_LinuxXorg_Common_03.00.0100.patch - # cp config/cf/xorgsite.def config/cf/host.def - -Edit config/cf/host.def -uncomment the line: - -#define BuildSpecsDocs No - -Add the line (directly following the above line) - -#define InstallHardcopyDocs No - - # make World - # mkdir <install_path> - # make DESTDIR=<install_path> install install.man - # tar -C <install_path> -czf <path>/xorg-x11-geode.tgz . - move xorg-x11-geode.tgz to the target system - login as root on the target system and make path to tarball available - # tar -C / -xzpf <path>/xorg-x11-geode.tgz - # mv /etc/X11/xorg.conf /etc/X11/xorg.conf.orig - # cp <path>/xorg-<gx/lx>.conf /etc/X11/xorg.conf - - -++++++++++++++++++++++++++++++++++++++++++++++++++ -AMD Geode(TM) LX processor Xorg.conf Specification -++++++++++++++++++++++++++++++++++++++++++++++++++ - -Linux Xorg AMD GeodeLX Processor Configuration Specification - - -The AMD Geode driver supports an accelerated interface to the -hardware access layer for the graphical devices (cimarron library). -To operate this API with a widely, a set of operational customizations -were added to the xorg.conf configuration file. These specifications -for the most part are passed unmodified to cimarron. This document -only provides an overview of the customizations to the standard -configuration file definitions. - -The xorg configuration (xorg.conf) file usually exists in the system -configuration directory /etc/X11. The standard contents are documented -in the manual pages, and can typically be accessed using: -man XF86Config -The file is divided into "sections". The following information -illustrates the custom features added section by section. - - -1. Device section: - -The devices section specifies the graphics driver selection. Currently, -for the drivers that may be specified include: Section "Device" - Identifier "DevId" - Driver "vesa" - or - Driver "fbdev" - or - Driver "amd" -... -EndSection - -The "vesa" and "fbdev" selections are documented by the manual pages -man fbdev - or -man vesa -The "amd" driver has many selections that can be used to operate -the interface configuration. These selections follow: - - -2. Hardware Accelerations: - -This set of options are standard to the xorg "xaa" accelerations. -The presents of the option disables the named functionality. -Note that many accelerations depend on combinations with others, -and so disabling one may have a more pervasive effect. - - Option "XaaNoCPUToScreenColorExpandFill" - Option "XaaNoColor8x8PatternFillRect" - Option "XaaNoColor8x8PatternFillTrap" - Option "XaaNoDashedBresenhamLine" - Option "XaaNoDashedTwoPointLine" - Option "XaaNoImageWriteRect" - Option "XaaNoMono8x8PatternFillRect" - Option "XaaNoMono8x8PatternFillTrap" - Option "XaaNoOffscreenPixmaps" - Option "XaaNoPixmapCache" - Option "XaaNoScanlineCPUToScreenColorExpandFill" - Option "XaaNoScanlineImageWriteRect" - Option "XaaNoScreenToScreenColorExpandFill" - Option "XaaNoScreenToScreenCopy" - Option "XaaNoSolidBresenhamLine" - Option "XaaNoSolidFillRect" - Option "XaaNoSolidFillTrap" - Option "XaaNoSolidHorVertLine" - Option "XaaNoSolidTwoPointLine" - -Certain hardware accelerations may be armed or disarmed by using: - - Option "HWcursor" (default) -or - Option "SWcursor" - - Option "Compression" (default) -or - Option "No Compression" - - -Additionally, all accelerations may be armed or disarmed using: - - Option "Accel" (default) -or - Option "No Accel" - -This option enables/disables all rendering accelerations, HW/SW cursor, -and display compression. Certain accelerations may not be armed, even -though they are inferred by the configuration, if video memory is in -short supply. - - -3. Modes section: - -The configuration file included with the driver delivery contains an -optional "modes" section. This section asserts all of the standard -graphics/video mode configuration data. This set of modes is a subset -of the mode data in the cimarron library. Because these modes are -included, they are passed to the cimarron driver for validation. Be -aware that cimarron will select modes using a filtering function that -uses a constrained distance search. The mode in cimarron's definitions -that is "closest" to a mode defined - either builtin or user supplied - -will normally be used by cimarron. - -This filtering effect can be factored out by specifying: - - Option "CustomMode" - -This has the effect of causing the mode validation to pass any mode -in the mode pool, and allowing the selection of the specified mode -during mode switch. Unfortunately, because the interface specification -is not complete enough to support video modes. Only video modes that -exist in cimarron are possible when selecting a TVOUT mode. - - -4. More "Device" section Options: - -Since flat panels have fixed timing - that is, only one "real" mode - -the mode switch operation that normally might select a wide variety -of operational states must "adjust" the mode selection to fit the -fixed panel timing. To communicate that the mode selection is for -a flat panel, use: - Option "FlatPanel" -Note that the code expects that the flat panel will have been already -selected by the BIOS setup. Conflicts produce configuration errors. -The size adjustment usually involves scaling the source buffer -dimensions to the raster image size supported by the flat-panel. The -hardware supports this scaling operation transparently, and normally -no special considerations are needed. The hardware scaling is limited -to modes with horizontal aspects of less than 1024 pixels (buffer size -limitation for scaling/filtering). - -The display may be "rotated" in three ways, ClockWise, Upside-Down and -CounterClocwise using: - Option "Rotate" "CW" - Option "Rotate" "Invert" - Option "Rotate" "CCW" -This is accomplished using a "shadow" frame buffer, and using either -a hardware or software operation to transform the image to the -operational display buffer. - -Even though there is not strategic advantage, if you wish to use a -shadow frame buffer and display the unrotated image - this is specified -by using: - - Option "ShadowFB" - - -5. TVOUT video modes. - -In order to enable TVOUT mode selection, a TV known encoder -must be selected in the following way: - Option "TV_Encoder" "ADV7171" -or - Option "TV_Encoder" "SAA7127" -or - Option "TV_Encoder" "FS454" -or - Option "TV_Encoder" "ADV7300" -There is no default for the encoder. This selection is mandatory -to enable TVOUT modes. - -Most encoders support a variety of bus formats. Similarly, the -amd driver can select the bus data format from the following list: - Option "TV_Bus_Fmt" "disabled" - VOP output is disabled - Option "TV_Bus_Fmt" "vip1_1" - VIP 1.1 - Option "TV_Bus_Fmt" "ccir656" - CCIR 656 output - Option "TV_Bus_Fmt" "vip20_8bit" - 8-bit VIP 2.0 output - Option "TV_Bus_Fmt" "vip20_16bit" - 16-bit VIP 2.0 output - Option "TV_Bus_Fmt" "601_yuv_8bit" - 601 output, 8-bit YUV 4:2:2 - Option "TV_Bus_Fmt" "601_yuv_16bit" - 601 output, 16-bit YUV 4:2:2 - Option "TV_Bus_Fmt" "601_rgb_8_8_8" - 601 output, 24-bit RGB - Option "TV_Bus_Fmt" "601_yuv_4_4_4" - 601 output, YUV 4:4:4 -Note that the "601" modes may need sync signals for correct operation. -See the 601 flags below to operate these selections. - -Colorspace conversion requires a projective transformation to -perform downsampling for the implied transformation. The sampling -method may be specified by selecting from: - Option "TV_Conversion" "cosited" - Option "TV_Conversion" "interspersed" - Option "TV_Conversion" "alternating" - -The TV standard selected normally specifies a known frame buffer/ -TV mode geometry. However, it is quite common that TV output -devices may expect a blanked "overscan" area. The dx,dy marginal -widths for the overscan area can be specified using: - Option "TV_Overscan" "40:30" -Note that the TV standard geometry will be scaled (and filtered) to -downscale the source buffer to destination raster image. - -TVOUT operation may be conditioned with the following set of flags. -Some of these flags are not especially usable except to the kernel, -but are included for completeness. - -These "TV_Flags" identifiers are specified in a quoted comma -separated list from the following identifier set: - singlechipcompat - Enables SCx2xx compatibility mode.. - extendedsav - Enables extended SAV/EAV codes. - vbi - Use the task bit to indicate VBI data. - task - Set Task Bit to 1in VIP 2.0 mode. Default is 0. - swap_uv - Swap the U and V data prior to output. - swap_vbi - Swap the VBI bytes prior to output. -for example: - Option "TV_Flags" "swap_uv" -or - Option "TV_Flags" "extendedsav:swap_uv" - -These "TV_601_Flags" identifiers are specified in a quoted comma -separated list from the following identifier set: - inv_de_pol - Invert the polarity of display enable - inv_hs_pol - Invert the polarity of hsync - inv_vs_pol - Invert the polarity of vsync - vsync-4 - The VSync occurs 4 clocks earlier - vsync-2 - The VSync occurs 2 clocks earlier - vsync+0 - The VSync is not shifted at all - vsync+2 - The Vsync occurs 2 clocks later -for example: - Option "TV_601_Flags" "inv_vs_pol" - -These "TV_Vsync_Select" identifiers are specified in a quoted comma -separated list from the following identifier set: - disabled - VSync out disabled - vg - The VSync signal from the VG (video generator) - vg_inv - The VSync signal from the VG (inverted) - statreg17 - 1 written to VIP status bit 17 toggles vsync (0-1-0) - statreg17_inv - 1 written to VIP status bit 17 toggles vsync (1-0-1) -for example: - Option "TV_Vsync_Select" "disabled" - - -6. Screen section: - -The screen section selects among the other various sections for -sets of operational parameters and constraints. A typical -"Screen" section has the form: - -Section "Screen" - Identifier "ScreenId" - Device "Geode" - Monitor "MonitorId" - DefaultDepth 24 - - SubSection "Display" - Depth 24 - FbBpp 32 - Modes "1280x1024" "1024x768" "800x600" "640x480" "tv-ntsc" "tv-pal" - EndSubsection -... - + Identifier "AMD Geode" + Driver "amd" + Option "blah" "blah" + ... EndSection -In this example, the "Modes" selection of the display subsection specifies a -list of available modes. These modes are selectable using "Ctl-Alt-KpPlus" or -"Ctl-Alt-KpMinus" on most PC keyboards. It is also possible to select a mode -using the xrandr utility, as well as using the X library API. - -The DefaultDepth may be 24, 16 or 8. If the depth is 24, then the "FbBpp" line -is needed to specify the frame buffer format as 32 bits (hardware limitation). -If a custom mode is specified, care should be taken to be sure it does not -collide with a "builtin" mode, since the builtin mode will supersede. - -For a more complete functional description, review that the cimarron -reference and Geode LX processor functional specifications. - ------------------------------------------------------------------------------ -RELEASE HISTORY ------------------------------------------------------------------------------ -Version 04.00.0000 -April 30, 2006 - -Dependencies ------------- -This release depends on and includes the following subcomponents: - -Linux Build Tool - Base GeodeLinux Build System - Version 00.00.0015 -Linux Build Tool - AMD Embedded - Version 00.00.0016 -Linux Build Tool - Bitbake engine - Version 00.00.0010 -Linux Build Tool - Openembedded - Version 00.00.0006 - -Functional Changes ------------------- -_____________________________________________________________________________ -Change: 77478 -_____________________________________________________________________________ -Archive 2.6.11 kernel and kernel modules. - -_____________________________________________________________________________ -Change: 78502 -_____________________________________________________________________________ -Tinderbox script name and version must match .bb - -_____________________________________________________________________________ -Change: 78443 -_____________________________________________________________________________ -Changes to xorg_7.0 BOM did not take the first time. - -_____________________________________________________________________________ -Change: 78552 -_____________________________________________________________________________ -Rename norwich and norwich-2.6.11 machines to geodelx and geodelx-2.6.11. - -_____________________________________________________________________________ -Change: 78556 -_____________________________________________________________________________ -Move geodelx machine to X11R7.0. Prepend BBPATH with devel directory for -overriding local.conf without p4 edit. - -_____________________________________________________________________________ -Change: 78423 -_____________________________________________________________________________ - -_____________________________________________________________________________ -Change: 77505 -_____________________________________________________________________________ -More path and version updates after projects/norwich to -projects/geodelx rename. - -_____________________________________________________________________________ -Change: 78527 -_____________________________________________________________________________ -Don't let xorg try to identify the LinuxDistribution. - -_____________________________________________________________________________ -Change: 78561 -_____________________________________________________________________________ -Misc changes after geodelx and geodelx-2.6.11 X build testing. - -_____________________________________________________________________________ -Change: 78535 -_____________________________________________________________________________ -Move to tcltk 8.4.11 from upstream in attempts to squash this Tindebox -failure. - -_____________________________________________________________________________ -Change: 78108 -_____________________________________________________________________________ -First stab at dvb-image. Everything compiles, but I am worried about DRI -support in X, missing geode support in X, openGL support in qt-x11-free. -Also, directFB may be a better direction; it is currently disabled in this -mythtv build. - -_____________________________________________________________________________ -Change: 77965 -_____________________________________________________________________________ -Syncronize travis, sands, gcov, and simnow busybox configurations. Remove -grep and tar from travis-db1200-2.6 and validation-image images. These are -provided by busybox. Move IMAGE_ROOTFS_SIZE to the meta .bb files as this is -psp specific and not necessarily distro specific. - -_____________________________________________________________________________ -Change: 77612 -_____________________________________________________________________________ -Monotone OE Sync - -_____________________________________________________________________________ -Change: 77802 -_____________________________________________________________________________ -CVSDATE renamed to SRCDATE. - -_____________________________________________________________________________ -Change: 77847 -_____________________________________________________________________________ -Decrease the size on the etx2 partition. norwich/sands/conf/local.conf points -to norwich machine and not norwich-2.6.11. - -_____________________________________________________________________________ -Change: 77978 -_____________________________________________________________________________ -1. Update Norwich.conf and Samba.conf to 2.6.16 -2. Change version file: BBFile to BBFile2 and LinuxKernel to LinuxKernel2 - -_____________________________________________________________________________ -Change: 77947 -_____________________________________________________________________________ -Adding samba machine configuration file. The difference right now, from -existing norwich.conf is that this samba configures an X11R7 build. xserver-xorg-X11R7.0- -1.0.1 builds with this changelist but has not been tested. Additionally, the -AMD driver checked into Perforce has not yet been built here. - -================================================================================ -Version 03.00.0102 -April 10, 2006 - -Dependencies ------------- -This release depends on and includes the following subcomponents: - -Linux Build Tool - Base GeodeLinux Build System - Version 00.00.0013 -Linux Build Tool - AMD Embedded - Version 00.00.0014 -Linux Build Tool - Bitbake engine - Version 00.00.0009 -Linux Build Tool - Openembedded - Version 00.00.0006 - -Functional Changes ------------------- -_____________________________________________________________________________ -Change: 77441 -_____________________________________________________________________________ -Rename //drivers/projects/norwich to //drivers/projects/geodelx. This -change includes: - * Updates to P4MOD BOMs for 2.6.11 and 2.6.15 releases. - * Updates to GeodeLinux .bb files for 2.6.11 and 2.6.15 builds. - * P4MOD search path update. - -================================================================================ -Version: 03.00.0101, Release Notes -Release Date: December 19, 2005 - -Dependencies ------------- -- Built with xorg-x11-6.7.0 from Fedora Core 2 Source Updates -- Built with X11R6.8.1 from freedesktop.org - -- This driver has been tested with Linux Kernel 2.6.11 - using the Fedora Core 2 image environment - using the Gentoo 2005.0 image environment - -- To use the Xv adaptor interface - 1) create a "videox" link to the geodev4l2 video device in /dev - ln -s video0 /dev/videox - 2) uncomment the ' Load "z4l"' line in xorg.conf - -Functional Changes ------------------- -Issue #4027 - -Defects Corrected ------------------ -PBZ#6538 - X.org patch is incompletely licensed -PBZ#4027 - HWCursor/Rotation, cursor does not traverse entire resolution area -Description: -When using HWCursor, cursor can not traverse the entire visable area of *MOST* -(there are exceptions) rotated modes. The failures exist as edges which the -cursor can not travel to. Failing edges differ according to rotation. -Resolution: -Cursor "hotspot" error corrected. - -PBZ#4463 - 8 bpp, x11perf SWCRC --> HWCRC comparison fails paint8_03 ... -PBZ#4665 - LX Xorg Driver will not patch successfully if GX Xorg Pat... -PBZ#5025 - mode changes with xrandr, graphics distorted - -Known Errata ------------- -PBZ#4025 X - Rotations{90,270}, only lowest refresh rate pass mode validation -Description: -At 90 and 270 degree rotations, only the lowest supported refresh -rate can be entered. The rest of the refresh rates appear to fail mode -validation (xrandr does not see them as options, and I can not CTL->ALT->+/- -through the modes). This issue does not occur at 0 or 180 degree rotations. -Resolution: -This is an inherent weakness of the X mode switch -- where even a -full X R&R implementation would not fix this. -Steps to address will need to be: -(1) convert AMD rotation support to X R&R -(2) patch X to better handle X R&R -This may be addressed in a future version. - -PBZ#5993 - HWScaling mode hsync out of range error - -================================================================================ -Previous Version: 1.02.0900 -Release Date: 26 May 2005 - -Dependencies ------------- -- Built with xorg-x11-6.7.0 from Fedora Core 2 Source Updates -- Built with X11R6.8.1 from freedesktop.org - -- This driver has been tested with Linux Kernel 2.6.11 - using the Fedora Core 2 image environment - using the Gentoo 2004.3 image environment - -- To use the Xv adaptor interface - 1) create a "videox" link to the geodev4l2 video device in /dev - ln -s video0 /dev/videox - 2) uncomment the ' Load "z4l"' line in xorg.conf - +The following options may be added to the section: -Functional Changes ------------------- -- First release +== GX == -Defects Corrected ------------------ -- First release +SWCursor: Enable software cursors (essentially disabling HW cursor support) +NoCompression: Disable video bandwidth compression +NoAccel: Disable hardware assisted acceleration +AccelMethod: "EXA" (default) or "XAA" +Rotate: Select a orientation to start with - LEFT, INVERT, CCW +NoPanel: Disable panel support +OSMImageBuffers: Set the number of image buffers (XAA only) +OSMColorExpBuffers: Set the number of color expansion buffers (XAA only) +FBSize: Specify the size of the video space (in bytes) +PanelGeometry: Specify the geometry of the attached panel ("<width>x<height>") -Known Errata ------------- -Issue: +== LX == -PBZ#4025 X - Rotations{90,270}, only lowest refresh rate pass mode validation -Description: -At 90 and 270 degree rotations, only the lowest supported refresh -rate can be entered. The rest of the refresh rates appear to fail mode -validation (xrandr does not see them as options, and I can not -CTL->ALT->+/- through the modes). This issue does not occur at 0 or -180 degree rotations. -Resolution: -This is an inherent weakness of the X mode switch -- where even a full X R&R -implementation would not fix this. -Steps to address will need to be: -(1) convert AMD rotation support to X R&R -(2) patch X to better handle X R&R -This may be addressed in a future version. +SWCursor: Enable software cursors (essentially disabling HW cursor support) +NoCompression: Disable video bandwidth compression +NoAccel: Disable hardware assisted acceleration +Rotate: Select a orientation to start with - LEFT, INVERT, CCW +NoPanel: Disable panel support +ExaScratch: Specify the amount of extra EXA scratch buffer (in bytes) +FBSize: Specify the size of the video space (in bytes) +PanelGeometry: Specify the geometry of the attached panel ("<width>x<height>") -================================================================================ -Copyright ---------- -Copyright 2005 Advanced Micro Devices, Inc. All rights reserved. -The contents of this document are provided in connection with Advanced Micro -Devices, Inc. ("AMD") products. AMD makes no representations or warranties -with respect to the accuracy or completeness of the contents of this -publication and reserves the right to make changes to specifications and -product descriptions at any time without notice. No license, whether express, -implied, arising by estoppel or otherwise, to any intellectual property rights -is granted by this publication. Except as set forth in AMD's Standard Terms -and Conditions of Sale, AMD assumes no liability whatsoever, and disclaims any -express or implied warranty, relating to its products including, but not -limited to, the implied warranty of merchantability, fitness for a particular -purpose, or infringement of any intellectual property right. AMD's products -are not designed, intended, authorized or warranted for use as components in -systems intended for surgical implant into the body, or in other applications -intended to support or sustain life, or in any other application in which the -failure of AMD's product could create a situation where personal injury, -death, or severe property or environmental damage may occur. AMD reserves the -right to discontinue or make changes to its products at any time without notice. -Trademarks ----------- -AMD, the AMD Arrow logo, and combinations thereof, and Geode are trademarks -of Advanced Micro Devices, Inc. -Other product names used in this publication are for identification purposes -only and may be trademarks of their respective companies. -================================================================================ @@ -0,0 +1,19 @@ +General: + +* Add automagic probing of the fb driver (for memory size) +* Write the man page + +GX: + +* Fix the options so they are sane (i.e eliminate one of SWCursor or HWCursor) +* TV support +* Fix the rotate text strings (CCW?) +* Whitespace / indenting +* Don't crash when rotating when playing video + +LX: + +* Fix the options so they are sane +* TV support (VOP) +* Rotated video +* ARGB cursor diff --git a/configure.ac b/configure.ac index 92fabc3..93cc1ff 100644 --- a/configure.ac +++ b/configure.ac @@ -54,6 +54,12 @@ AC_ARG_ENABLE(geodegx-panel, [ ], [ AMD_CFLAGS="-DPNL_SUP $AMD_CFLAGS" ]) +AC_ARG_ENABLE(visibility, + AC_HELP_STRING([--enable-visibility], + [Enable GCC visibility optimizations]), + [ AMD_CFLAGS="$AMD_CFLAGS -fvisibility=hidden" ], + [ : ]) + # Checks for extensions XORG_DRIVER_CHECK_EXT(RANDR, randrproto) XORG_DRIVER_CHECK_EXT(RENDER, renderproto) diff --git a/man/Makefile.am b/man/Makefile.am deleted file mode 100644 index 9981874..0000000 --- a/man/Makefile.am +++ /dev/null @@ -1,59 +0,0 @@ -# $Id: Makefile.am,v 1.6 2005/12/06 22:48:36 kem Exp $ -# -# 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) - -driverman_PRE = @DRIVER_NAME@.man - -driverman_DATA = $(driverman_PRE:man=@DRIVER_MAN_SUFFIX@) - -EXTRA_DIST = @DRIVER_NAME@.man - -CLEANFILES = $(driverman_DATA) - -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): - sed $(MAN_SUBSTS) < $< > $@ diff --git a/man/amd.man b/man/amd.man deleted file mode 100644 index cff15e9..0000000 --- a/man/amd.man +++ /dev/null @@ -1,417 +0,0 @@ -.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/amd/amd.man,v 1.1 2002/12/10 15:12:23 alanh Exp $ -.\" shorthand for double quote that works everywhere. -.ds q \N'34' -.TH AMD __drivermansuffix__ __vendorversion__ -.SH NAME -amd \- Amd video driver \- lx options -.SH SYNOPSIS -.nf -.B "Section \*qDevice\*q" -.BI " Identifier \*q" devname \*q -.B " Driver \*qamd\*q" -\ \ ... -.B EndSection -.fi -.SH DESCRIPTION -.B amd -is an __xservername__ driver for Advanced Micro Devicess GEODE processor family. -It uses the CIMARRON kit provided by Advanced Micro Devices. -The driver is accelerated, and provides support for the following -framebuffer depths: 8, 16 and 24. -.SH SUPPORTED HARDWARE -The -.B amd -driver supports GeodeLX (5536 companion chip). -.SH CONFIGURATION DETAILS -Please refer to __xconfigfile__(__filemansuffix__) for general configuration -details. This section only covers configuration details specific to this -driver. -.PP -The driver will auto-detect the amount of video memory present. -If actual the amount of active video memory should be changed, -this may be specified with a -.B VideoRam -entry in the config file. The driver will attempt to allocate all -public/free reigons from the framebuffer memory, as allocated by the -kernel cimarron module. All private framebuffer reservations should -be made before starting X. Note that X attempts to open /dev/video# -devices during initialization, so that attached drivers may allocate -framebuffer memory before X reserves it. X will try to reserve -framebuffer memory using \*q/dev/cim\*q (char device node 10,156). -.PP -.B \*qDevice\*q -section. -.PP -The following driver -.B Options -are supported: -.TP -.BI "Option \*qHWCursor\*q" -.RS 0 -.BI "Option \*qSWCursor\*q" -.RS -Enable HW or SW cursor. -.br -Default: HW cursor. -.RE -.TP -.BI "Option \*qAccel\*q" -.RS 0 -.BI "Option \*qNoAccel\*q" -.RS -Disable or enable acceleration. -.br -Default: acceleration enabled. -.RE -.TP -.BI "Option \*qCompression\*q" -.RS 0 -.BI "Option \*qNoCompression\*q" -.RS -Disable or enable compression. -.br -Default: compression is enabled. -.RE -.TP -.BI "Option \*qShadowFB\*q" -.RS 0 -.BI "Option \*qNoShadowFB\*q" -.RS -Enable or disable use of the shadow framebuffer layer. -.br -Default: off. -.RE -.TP -.BI "Option \*qRotate\*q \*qCW\*q" -.RS 0 -.BI "Option \*qRotate\*q \*qInvert\*q" -.RS 0 -.BI "Option \*qRotate\*q \*qCCW\*q" -.RS -The display may be "rotated" in 3 ways, ClockWise, Upside-Down and -CounterClocwise using: -This is accomplished using a \*qshadow\*q framebuffer, and using either -a hardware or software operation to transform the image to the -operational display buffer. -.br -Default: no rotation. -.RE -.TP -.BI "Option \*qFPDestGeom\*q "\*qWxH\*q -This allows the configuration to override the bios probe of the -.B FlatPanel -output interface. -Since flat-panels have fixed timing - that is, only one \*qreal\*q mode - -the mode switch operation which normally might select a wide variety -of operational states must scale the mode selection to fit the -fixed panel timing. This option is used to communicate that the mode -selection is for a flat panel. When this option is used, the bios -probe is skipped and the specified geometry is used to derive timings. -.br -Default: bios. -.RE -.TP -.BI "Option \*qFPActiveGeom\*q "\*qWxH\*q -This allows the configuration of the active flatpanel display area. This -area must fit into the destination geometry area. The source (mode WxH) -geometry will be scaled to the active geometry, and centered in the -destination geometry of the -.B FlatPanel -output. -.br -Default: FPDestGeom. -.RE -.TP -.BI "Option \*qFlatPanel\*q" -.RS 0 -.BI "Option \*qNoFlatPanel\*q" -.RS -This allows the configuration to override the initialization probe -to enable or disable the -.B FlatPanel -output interface. -.br -Default: bios. -.RE -.TP -.BI "Option \*qCrtEnable\*q" -.RS 0 -.BI "Option \*qNoCrtEnable\*q" -.RS -This allows the configuration to override the initialization probe -to enable or disable the -.B CRT -output interface. -.br -Default: bios. -.RE -.TP -.BI "Option \*qOSMImageBuffers\*q \*q" integer \*q -This sets the number of scanline buffers to be allocated in offscreen -scanline memory for acceleration. This can take any value 0 will disable -the allocation. Disabled if cannot allocate requested scanline memory. -.br -Default: 20. -.TP -.BI "Option \*qOSMColorExpBuffers\*q \*q" integer \*q -This sets the number of scanline buffers to be allocated in offscreen -color expansiopn memory for acceleration. This can take any value 0 -will disable the allocation. Disabled if cannot allocate requested -scanline memory. -.br -Default: 20. -.PP -.BI "TVOUT Options" -.TP -TVOUT is operated when a tv encoder has been selected by using the -.B TV_Encoder -option describe below, and a tv mode name is selected as the active -display mode. The list of tv mode names are: -.RS - ModeName Geometry Std/Hi Encoders - tv-ntsc 720x480 Std adv7171 saa7127 adv7300 - pnl-ntsc 640x480 Std fs454 - pnl-8x6_ntsc 800x600 Std fs454 - pnl-10x7_ntsc 1024x768 Std fs454 - tv-pal 720x576 Std adv7171 saa7127 adv7300 - pnl-pal 640x480 Std fs454 - pnl-8x6_pal 800x600 Std fs454 - pnl-10x7_pal 1024x768 Std fs454 - tv-480p 720x480 Hi adv7300 - pnl-480p 720x480 Hi fs454 - tv-720p 1280x720 Hi adv7300 - pnl-720p 1280x720 Hi fs454 - tv-1080i 1920x1080 Hi adv7300 fs454 -.br -Default: none - manditory parameter -.RE -.TP -.BI "Option \*qTV_Encoder\*q "\*qencoder\*q -This option is manditory for TVOUT operation. It enables selection -of the subset -.B TVOUT -modes which are permitted for the designated encoder family. The -encoder must be one of: - adv7171 - modes for the adv7171 encoder - saa7127 - modes for the saa7127 encoder - fs454 - modes for the fs454 encoder - adv7300 - modes for the adv7300 encoder -.br -Default: none - manditory parameter -.TP -.BI "Option \*qTV_Bus_Fmt\*q "\*qformat\*q -This option is optional for TVOUT operation. It selects the bus -format of the -.B TVOUT -data. The format must be one of: - disabled - VOP output is disabled - vip1_1 - VIP 1.1 - ccir656 - CCIR 656 output - vip20_8bit - 8-bit VIP 2.0 output - vip20_16bit - 16-bit VIP 2.0 output - 601_yuv_8bit - 601 output, 8-bit YUV 4:2:2 - 601_yuv_16bit - 601 output, 16-bit YUV 4:2:2 - 601_rgb_8_8_8 - 601 output, 24-bit RGB - 601_yuv_4_4_4 - 601 output, YUV 4:4:4 -.br -Default: vip1_1 for Std modes, vip20_16bit for Hi modes -.TP -.BI "Option \*qTV_Conversion\*q "\*qconversion\*q -This option is optional for TVOUT operation. It selects the bus -color conversion sampling method of the -.B TVOUT -data. The conversion must be one of: -.br - cosited - color conversion cosited sampling - interspersed - color conversion interspersed sampling - alternating - color conversion alternating sampling -.br -Default: cosited -.TP -.BI "Option \*qTV_Overscan\*q "\*qX:Y\*q -This option is optional for TVOUT operation. It selects the image -overscale size in pixels. The output image is downscaled and padded -with a blanking region such that the resulting image contains a -left and right margin of X pixels, and a top and bottom margin of Y -pixels. -.br -Default: 0:0 -.TP -.BI "Option \*qTV_Flags\*q "\*qflags\*q -This option is optional for TVOUT operation. It selects standard -features of the -.B TVOUT -data. The flags may be a \*q:\*q seperated list of: -.br - disabled - VOP output is disabled - singlechipcompat - Enables SCx2xx compatibility mode.. - extendedsav - Enables extended SAV/EAV codes. - vbi - Use the task bit to indicate VBI data. - task - Set Task Bit to 1in VIP 2.0 mode. - swap_uv - Swap the U and V data prior to output. - swap_vbi - Swap the VBI bytes prior to output. -.br -Default: no active flags -.TP -.BI "Option \*qTV_601_Flags\*q "\*q601_flags\*q -This option is optional for TVOUT operation. It selects 601 -features of the -.B TVOUT -data. The 601_flags may be a \*q:\*q seperated list of: -.br - inv_de_pol - Invert the polarity of display enable - inv_hs_pol - Invert the polarity of hsync - inv_vs_pol - Invert the polarity of vsync - vsync-4 - The VSync occurs 4 clocks earlier - vsync-2 - The VSync occurs 2 clocks earlier - vsync+0 - The VSync is not shifted at all - vsync+2 - The Vsync occurs 2 clocks later -.br -Default: vsync+0 -.TP -.BI "Option \*qTV_Vsync_Select\*q "\*qsync_select\*q -This option is optional for TVOUT operation. It selects the source -for the -.B VIP -vsync output pin (not the -.B VOP -sync). This normally may be used to generate \*qgenlock\*q timing. -The sync_select may one of: -.br - disabled - VSync out disabled - vg - The VSync signal from the VG (video generator) - vg_inv - The VSync signal from the VG (inverted) - statreg17 - 1 written to VIP status[17] toggles vsync - statreg17_inv - 1 written to VIP status[17] toggles vsync -.br -Default: disabled -.SH NAME -amd \- Amd video driver \- gx options -.SH SYNOPSIS -.nf -.B "Section \*qDevice\*q" -.BI " Identifier \*q" devname \*q -.B " Driver \*qamd\*q" -\ \ ... -.B EndSection -.fi -.SH DESCRIPTION -.B amd -is an __xservername__ driver for Advanced Micro Devices GEODE processor family. -It uses the DURANGO kit provided by Advanced Micro Devices. -The driver is accelerated, and provides support for the following -framebuffer depths: 8, 16 and 24. -.SH SUPPORTED HARDWARE -The -.B amd -driver supports GXLV (5530 companion chip), SC1200, SC1400 and -GX (5535 companion chip). -.SH CONFIGURATION DETAILS -Please refer to __xconfigfile__(__filemansuffix__) for general configuration -details. This section only covers configuration details specific to this -driver. -.PP -The driver will auto-detect the amount of video memory present for all -chips. If the amount of memory is detected incorrectly, the actual amount -of video memory should be specified with a -.B VideoRam -entry in the config file -.B \*qDevice\*q -section. -.PP -The following driver -.B Options -are supported: -.TP -.BI "Option \*qSWCursor\*q \*q" boolean \*q -Enable or disable the SW cursor. -Default: off. -.TP -.BI "Option \*qHWCursor\*q \*q" boolean \*q -Enable or disable the HW cursor. -Default: on. -.TP -.BI "Option \*qNoAccel\*q \*q" boolean \*q -Disable or enable acceleration. -Default: acceleration is enabled. -.TP -.BI "Option \*qNoCompression\*q \*q" boolean \*q -Disable or enable compression. -Default: compression is enabled. -.TP -.BI "Option \*qShadowFB\*q \*q" boolean \*q -Enable or disable use of the shadow framebuffer layer. -Default: off. -.TP -.BI "Option \*qRotate\*q \*qCW\*q" -Rotate the display clockwise. This mode is unaccelerated, and uses -the Shadow Frame Buffer layer. -Default: no rotation. -.TP -.BI "Option \*qRotate\*q \*qCCW\*q" -Rotate the display counterclockwise. This mode is unaccelerated, and -uses the Shadow Frame Buffer layer. -Default: no rotation. -.TP -.BI "Option \*qFlatPanel\*q \*q" boolean \*q -This enables the FlatPanel display unit. The FlatPanel depends on the -BIOS to do the Pnale h/w initialization. -In GX based platforms with TFT part Flatpanel is enabled, and on CRT -part is disabled. -Default: off. -.TP -.BI "Option \*qOSMImageBuffers\*q \*q" integer \*q -This sets the number of scanline buffers to be allocated in offscreen -memory for acceleration. This can take any value 0 will disable the -allocation. Disabled if cannot alocate requested scanline memory. -Default: 20. -.TP -.BI "Option \*qColorKey\*q \*q" integer \*q -This sets the default pixel value for the YUV video overlay key. -Default: 0. -.PP -The following -.B Options -are supported only on SC1200 based platforms: -.TP -.BI "Option \*qTV\*q \*qPAL-768x576\*q" -Selects the PAL TV display mode 768x576 and the depth is forced to 16 bpp. -Default: no TV. -.TP -.BI "Option \*qTV\*q \*qPAL-720x576\*q" -Selects the PAL TV display mode 720x576 and the depth is forced to 16 bpp. -Default: no TV. -.TP -.BI "Option \*qTV\*q \*qNTSC-720x480\*q" -Selects the NTSC TV display mode 720x480 and the depth is forced to 16 bpp. -Default: no TV. -.TP -.BI "Option \*qTV\*q \*qNTSC-640x480\*q" -Selects the NTSC TV display mode 640x480 and the depth is forced to 16 bpp. -Default: no TV. -.TP -.BI "Option \*qTV_Output\*q \*qCOMPOSITE\*q" -The selected TV mode output is coded for Composite signal. -Default: no TV. -.TP -.BI "Option \*qTV_Output\*q \*qSVIDEO\*q" -The selected TV mode output is coded for SVIDEO signal. -Default: no TV. -.TP -.BI "Option \*qTV_Output\*q \*qYUV\*q" -The selected TV mode output is coded for YUV signal. -Default: no TV. -.TP -.BI "Option \*qTV_Output\*q \*qSCART\*q" -The selected TV mode output is coded for SCART signal. -Default: no TV. -.TP -.BI "Option \*qTVOverscan\*q \*xx:yy:ww:hh\*q" -This option will let only the viewable display area smaller to be able to -view on TV. The parameters xx: X-offset, yy: Y-offset, ww: Viewable width, -hh: Viewable height. -Default: no TV. -.SH "SEE ALSO" -__xservername__(1), __xconfigfile__(__filemansuffix__), xorgconfig(1), Xserver(1), X(__miscmansuffix__) -.SH AUTHOR -Author: William Morrow diff --git a/src/Makefile.am b/src/Makefile.am index db8c264..6ea5106 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,24 +39,31 @@ amd_drv_la_LDFLAGS = -module -avoid-version amd_drv_ladir = @moduledir@/drivers amd_drv_la_SOURCES = \ + amd.h \ + amd_blend.h \ + amd_fourcc.h \ + build_num.h \ + cim_dev.h \ amd_driver.c \ + amd_common.c \ + amd_msr.c \ amd_gx_driver.c\ amd_gx_accel.c \ amd_gx_cursor.c \ - amd_gx_dga.c \ amd_gx_video.c \ - amd_gx_shadow.c \ amd_gx_regacc.c \ - amd_gx_dcon.c \ + amd_gx_rotate.c \ + amd_gx_dcon.c \ + amd_gx_randr.c \ durango.c \ panel.c \ amd_lx_driver.c \ - amd_lx_accel.c \ amd_lx_cursor.c \ - amd_lx_dga.c \ amd_lx_video.c \ - amd_lx_shadow.c \ amd_lx_regacc.c \ + amd_lx_rotate.c \ + amd_lx_randr.c \ + amd_lx_exa.c \ cimarron.c EXTRA_DIST = \ @@ -78,7 +85,6 @@ EXTRA_DIST = \ \ gfx/disp_gu1.c \ gfx/disp_gu2.c \ - gfx/durango.c \ gfx/gfx_dcdr.c \ gfx/gfx_defs.h \ gfx/gfx_disp.c \ @@ -129,7 +135,10 @@ EXTRA_DIST = \ panel/pnl_bios.c \ panel/pnl_defs.h \ panel/pnl_init.c \ - panel/readme.txt + panel/readme.txt \ + \ + amd_gx_vga.c \ + amd_lx_vga.c ztv_drv_la_LTLIBRARIES = ztv_drv.la ztv_drv_la_LDFLAGS = -module -avoid-version diff --git a/src/amd.4.html b/src/amd.4.html deleted file mode 100644 index 89795bb..0000000 --- a/src/amd.4.html +++ /dev/null @@ -1,439 +0,0 @@ - -<!-- - $XFree86: xc/programs/Xserver/hw/xfree86/drivers/amd/amd.man,v 1.1 2002/12/10 15:12:23 alanh Exp $ - shorthand for double quote that works everywhere. - ---> -<!-- manual page source format generated by PolyglotMan v3.0.8+X.Org, --> -<!-- available at http://polyglotman.sourceforge.net/ --> - -<html> -<head> -<title>AMD(4) manual page</title> -</head> -<body bgcolor='#efefef' text='black' link='blue' vlink='#551A8B' alink='red'> -<a href='#toc'>Table of Contents</a><p> - -<h2><a name='sect0' href='#toc0'>Name</a></h2> -amd - Amd video driver - lx options -<h2><a name='sect1' href='#toc1'>Synopsis</a></h2> -<br> -<pre><b>Section "Device"</b> -<b> Identifier "</b><i>devname</i><b>"</b> -<b> Driver "amd"</b> - ... -<b>EndSection</b> -</pre> -<h2><a name='sect2' href='#toc2'>Description</a></h2> -<b>amd</b> is an XFree86 driver for Advanced Micro Devicess GEODE processor -family. It uses the CIMARRON kit provided by Advanced Micro Devices. The -driver is accelerated, and provides support for the following framebuffer -depths: 8, 16 and 24. -<h2><a name='sect3' href='#toc3'>Supported Hardware</a></h2> -The <b>amd</b> driver supports GeodeLX -(5536 companion chip). -<h2><a name='sect4' href='#toc4'>Configuration Details</a></h2> -Please refer to <a href='XF86Config.5.html'>XF86Config(5x)</a> - -for general configuration details. This section only covers configuration -details specific to this driver. <p> -The driver will auto-detect the amount of -video memory present. If actual the amount of active video memory should -be changed, this may be specified with a <b>VideoRam</b> entry in the config -file. The driver will attempt to allocate all public/free reigons from -the framebuffer memory, as allocated by the kernel cimarron module. All -private framebuffer reservations should be made before starting X. Note -that X attempts to open /dev/video# devices during initialization, so that -attached drivers may allocate framebuffer memory before X reserves it. -X will try to reserve framebuffer memory using "/dev/cim" (char device -node 10,156). <p> -<b>"Device"</b> section. <p> -The following driver <b>Options</b> are supported: - -<dl> - -<dt><b>Option "HWCursor"</b> </dt> -<dd><blockquote><b>Option "SWCursor"</b> <blockquote>Enable HW or SW cursor. <br> -Default: HW cursor. </dd> -</dl> -</blockquote> - -<dl> - -<dt><b>Option "Accel"</b> </dt> -<dd><blockquote><b>Option "NoAccel"</b> <blockquote>Disable or enable -acceleration. <br> -Default: acceleration enabled. </dd> -</dl> -</blockquote> - -<dl> - -<dt><b>Option "Compression"</b> </dt> -<dd><blockquote><b>Option "NoCompression"</b> -<blockquote>Disable or enable compression. <br> -Default: compression is enabled. </dd> -</dl> -</blockquote> - -<dl> - -<dt><b>Option "ShadowFB"</b> </dt> -<dd><blockquote><b>Option "NoShadowFB"</b> <blockquote>Enable -or disable use of the shadow framebuffer layer. <br> -Default: off. </dd> -</dl> -</blockquote> - -<dl> - -<dt><b>Option "Rotate" "CW"</b> </dt> -<dd><blockquote><b>Option "Rotate" "Invert"</b> <blockquote><b>Option "Rotate" -"CCW"</b> <blockquote>The display may be "rotated" in 3 ways, ClockWise, Upside-Down and -CounterClocwise using: This is accomplished using a "shadow" framebuffer, -and using either a hardware or software operation to transform the image -to the operational display buffer. <br> -Default: no rotation. </dd> -</dl> -</blockquote> - -<dl> - -<dt><b>Option "FPDestGeom" </b><i>"WxH"</i> </dt> -<dd>This allows the configuration -to override the bios probe of the <b>FlatPanel</b> output interface. Since flat-panels -have fixed timing - that is, only one "real" mode - the mode switch operation -which normally might select a wide variety of operational states must -scale the mode selection to fit the fixed panel timing. This option is -used to communicate that the mode selection is for a flat panel. When this -option is used, the bios probe is skipped and the specified geometry is -used to derive timings. <br> -Default: bios. </dd> -</dl> -</blockquote> - -<dl> - -<dt><b>Option "FPActiveGeom" </b><i>"WxH"</i> </dt> -<dd>This allows the configuration -of the active flatpanel display area. This area must fit into the destination -geometry area. The source (mode WxH) geometry will be scaled to the active -geometry, and centered in the destination geometry of the <b>FlatPanel</b> output. -<br> -Default: FPDestGeom. </dd> -</dl> -</blockquote> - -<dl> - -<dt><b>Option "FlatPanel"</b> </dt> -<dd><blockquote><b>Option "NoFlatPanel"</b> <blockquote>This allows -the configuration to override the initialization probe to enable or disable -the <b>FlatPanel</b> output interface. <br> -Default: bios. </dd> -</dl> -</blockquote> - -<dl> - -<dt><b>Option "CrtEnable"</b> </dt> -<dd><blockquote><b>Option "NoCrtEnable"</b> <blockquote>This allows the configuration -to override the initialization probe to enable or disable the <b>CRT</b> output -interface. <br> -Default: bios. </dd> -</dl> -</blockquote> - -<dl> - -<dt><b>Option "OSMImageBuffers" "</b><i>integer</i><b>"</b> </dt> -<dd>This sets the number of -scanline buffers to be allocated in offscreen scanline memory for acceleration. -This can take any value 0 will disable the allocation. Disabled if cannot -allocate requested scanline memory. <br> -Default: 20. </dd> - -<dt><b>Option "OSMColorExpBuffers" "</b><i>integer</i><b>"</b> </dt> -<dd>This sets the number -of scanline buffers to be allocated in offscreen color expansiopn memory -for acceleration. This can take any value 0 will disable the allocation. -Disabled if cannot allocate requested scanline memory. <br> -Default: 20. </dd> -</dl> -<p> -<b>TVOUT Options</b> -<dl> - -<dt>TVOUT is operated when a tv encoder has been -selected by using the </dt> -<dd><b>TV_Encoder</b> option describe below, and a tv mode -name is selected as the active display mode. The list of tv mode names -are: <blockquote> ModeName <tt> </tt> <tt> </tt> Geometry <tt> </tt> <tt> </tt> Std/Hi<tt> </tt> <tt> </tt> Encoders<br> - tv-ntsc <tt> </tt> <tt> </tt> 720x480 <tt> </tt> <tt> </tt> Std <tt> </tt> <tt> </tt> adv7171 saa7127 adv7300<br> - pnl-ntsc <tt> </tt> <tt> </tt> 640x480 <tt> </tt> <tt> </tt> Std <tt> </tt> <tt> </tt> fs454<br> - pnl-8x6_ntsc <tt> </tt> <tt> </tt> 800x600 <tt> </tt> <tt> </tt> Std <tt> </tt> <tt> </tt> fs454<br> - pnl-10x7_ntsc<tt> </tt> <tt> </tt> 1024x768 <tt> </tt> <tt> </tt> Std <tt> </tt> <tt> </tt> fs454<br> - tv-pal <tt> </tt> <tt> </tt> 720x576 <tt> </tt> <tt> </tt> Std <tt> </tt> <tt> </tt> adv7171 saa7127 adv7300<br> - pnl-pal <tt> </tt> <tt> </tt> 640x480 <tt> </tt> <tt> </tt> Std <tt> </tt> <tt> </tt> fs454<br> - pnl-8x6_pal <tt> </tt> <tt> </tt> 800x600 <tt> </tt> <tt> </tt> Std <tt> </tt> <tt> </tt> fs454<br> - pnl-10x7_pal <tt> </tt> <tt> </tt> 1024x768 <tt> </tt> <tt> </tt> Std <tt> </tt> <tt> </tt> fs454<br> - tv-480p <tt> </tt> <tt> </tt> 720x480 <tt> </tt> <tt> </tt> Hi <tt> </tt> <tt> </tt> adv7300<br> - pnl-480p <tt> </tt> <tt> </tt> 720x480 <tt> </tt> <tt> </tt> Hi <tt> </tt> <tt> </tt> fs454<br> - tv-720p <tt> </tt> <tt> </tt> 1280x720 <tt> </tt> <tt> </tt> Hi <tt> </tt> <tt> </tt> adv7300<br> - pnl-720p <tt> </tt> <tt> </tt> 1280x720 <tt> </tt> <tt> </tt> Hi <tt> </tt> <tt> </tt> fs454<br> - tv-1080i <tt> </tt> <tt> </tt> 1920x1080 <tt> </tt> <tt> </tt> Hi <tt> </tt> <tt> </tt> adv7300 fs454<br> - <br> -Default: none - </dd> -</dl> -manditory parameter </blockquote> - -<dl> - -<dt><b>Option "TV_Encoder" </b><i>"encoder"</i> </dt> -<dd>This option -is manditory for TVOUT operation. It enables selection of the subset <b>TVOUT</b> -modes which are permitted for the designated encoder family. The encoder -must be one of: adv7171 <tt> </tt> <tt> </tt> - modes for the adv7171 encoder<br> - saa7127 <tt> </tt> <tt> </tt> - modes for the saa7127 encoder<br> - fs454 <tt> </tt> <tt> </tt> - modes for the fs454 encoder<br> - adv7300 <tt> </tt> <tt> </tt> - modes for the adv7300 encoder<br> - <br> -Default: none - manditory parameter </dd> - -<dt><b>Option "TV_Bus_Fmt" </b><i>"format"</i> </dt> -<dd>This option -is optional for TVOUT operation. It selects the bus format of the <b>TVOUT</b> -data. The format must be one of: disabled <tt> </tt> <tt> </tt> - VOP output is disabled<br> - vip1_1 <tt> </tt> <tt> </tt> - VIP 1.1<br> - ccir656 <tt> </tt> <tt> </tt> - CCIR 656 output<br> - vip20_8bit <tt> </tt> <tt> </tt> - 8-bit VIP 2.0 output<br> - vip20_16bit <tt> </tt> <tt> </tt> - 16-bit VIP 2.0 output<br> - 601_yuv_8bit <tt> </tt> <tt> </tt> - 601 output, 8-bit YUV 4:2:2<br> - 601_yuv_16bit <tt> </tt> <tt> </tt> - 601 output, 16-bit YUV 4:2:2<br> - 601_rgb_8_8_8 <tt> </tt> <tt> </tt> - 601 output, 24-bit RGB<br> - 601_yuv_4_4_4 <tt> </tt> <tt> </tt> - 601 output, YUV 4:4:4<br> - <br> -Default: vip1_1 for Std modes, vip20_16bit for Hi modes </dd> - -<dt><b>Option "TV_Conversion" -</b><i>"conversion"</i> </dt> -<dd>This option is optional for TVOUT operation. It selects the -bus color conversion sampling method of the <b>TVOUT</b> data. The conversion -must be one of: <br> - cosited <tt> </tt> <tt> </tt> - color conversion cosited sampling<br> - interspersed <tt> </tt> <tt> </tt> - color conversion interspersed sampling<br> - alternating <tt> </tt> <tt> </tt> - color conversion alternating sampling<br> - <br> -Default: cosited </dd> - -<dt><b>Option "TV_Overscan" </b><i>"X:Y"</i> </dt> -<dd>This option is optional for -TVOUT operation. It selects the image overscale size in pixels. The output -image is downscaled and padded with a blanking region such that the resulting -image contains a left and right margin of X pixels, and a top and bottom -margin of Y pixels. <br> -Default: 0:0 </dd> - -<dt><b>Option "TV_Flags" </b><i>"flags"</i> </dt> -<dd>This option is optional for TVOUT -operation. It selects standard features of the <b>TVOUT</b> data. The flags may -be a ":" seperated list of: <br> - disabled <tt> </tt> <tt> </tt> - VOP output is disabled<br> - singlechipcompat<tt> </tt> <tt> </tt> - Enables SCx2xx compatibility mode..<br> - extendedsav <tt> </tt> <tt> </tt> - Enables extended SAV/EAV codes.<br> - vbi <tt> </tt> <tt> </tt> - Use the task bit to indicate VBI data.<br> - task <tt> </tt> <tt> </tt> - Set Task Bit to 1in VIP 2.0 mode.<br> - swap_uv <tt> </tt> <tt> </tt> - Swap the U and V data prior to output.<br> - swap_vbi <tt> </tt> <tt> </tt> - Swap the VBI bytes prior to output.<br> - <br> -Default: no active flags </dd> - -<dt><b>Option "TV_601_Flags" </b><i>"601_flags"</i> </dt> -<dd>This option -is optional for TVOUT operation. It selects 601 features of the <b>TVOUT</b> -data. The 601_flags may be a ":" seperated list of: <br> - inv_de_pol <tt> </tt> <tt> </tt> - Invert the polarity of display enable<br> - inv_hs_pol <tt> </tt> <tt> </tt> - Invert the polarity of hsync<br> - inv_vs_pol <tt> </tt> <tt> </tt> - Invert the polarity of vsync<br> - vsync-4 <tt> </tt> <tt> </tt> - The VSync occurs 4 clocks earlier<br> - vsync-2 <tt> </tt> <tt> </tt> - The VSync occurs 2 clocks earlier<br> - vsync+0 <tt> </tt> <tt> </tt> - The VSync is not shifted at all<br> - vsync+2 <tt> </tt> <tt> </tt> - The Vsync occurs 2 clocks later <br> - <br> -Default: vsync+0 </dd> - -<dt><b>Option "TV_Vsync_Select" </b><i>"sync_select"</i> </dt> -<dd>This option is -optional for TVOUT operation. It selects the source for the <b>VIP</b> vsync -output pin (not the <b>VOP</b> sync). This normally may be used to generate "genlock" -timing. The sync_select may one of: <br> - disabled <tt> </tt> <tt> </tt> - VSync out disabled<br> - vg <tt> </tt> <tt> </tt> - The VSync signal from the VG (video generator)<br> - vg_inv <tt> </tt> <tt> </tt> - The VSync signal from the VG (inverted)<br> - statreg17 <tt> </tt> <tt> </tt> - 1 written to VIP status[17] toggles vsync<br> - statreg17_inv<tt> </tt> <tt> </tt> - 1 written to VIP status[17] toggles vsync<br> - <br> -Default: </dd> -</dl> -disabled </blockquote> -</blockquote> -</blockquote> -</blockquote> -</blockquote> -</blockquote> - -<h2><a name='sect5' href='#toc5'>Name</a></h2> -amd - Amd video driver - gx options -<h2><a name='sect6' href='#toc6'>Synopsis</a></h2> -<br> -<pre><b>Section "Device"</b> -<b> Identifier "</b><i>devname</i><b>"</b> -<b> Driver "amd"</b> - ... -<b>EndSection</b> -</pre> -<h2><a name='sect7' href='#toc7'>Description</a></h2> -<b>amd</b> is an XFree86 driver for Advanced Micro Devices GEODE processor -family. It uses the DURANGO kit provided by Advanced Micro Devices. The driver -is accelerated, and provides support for the following framebuffer depths: -8, 16 and 24. -<h2><a name='sect8' href='#toc8'>Supported Hardware</a></h2> -The <b>amd</b> driver supports GXLV (5530 companion -chip), SC1200, SC1400 and GX (5535 companion chip). -<h2><a name='sect9' href='#toc9'>Configuration Details</a></h2> -Please -refer to <a href='XF86Config.5.html'>XF86Config(5x)</a> - for general configuration details. This section -only covers configuration details specific to this driver. <p> -The driver will -auto-detect the amount of video memory present for all chips. If the amount -of memory is detected incorrectly, the actual amount of video memory should -be specified with a <b>VideoRam</b> entry in the config file <b>"Device"</b> section. -<p> -The following driver <b>Options</b> are supported: -<dl> - -<dt><b>Option "SWCursor" "</b><i>boolean</i><b>"</b> -</dt> -<dd>Enable or disable the SW cursor. Default: off. </dd> - -<dt><b>Option "HWCursor" "</b><i>boolean</i><b>"</b> -</dt> -<dd>Enable or disable the HW cursor. Default: on. </dd> - -<dt><b>Option "NoAccel" "</b><i>boolean</i><b>"</b> -</dt> -<dd>Disable or enable acceleration. Default: acceleration is enabled. </dd> - -<dt><b>Option -"NoCompression" "</b><i>boolean</i><b>"</b> </dt> -<dd>Disable or enable compression. Default: compression -is enabled. </dd> - -<dt><b>Option "ShadowFB" "</b><i>boolean</i><b>"</b> </dt> -<dd>Enable or disable use of the shadow -framebuffer layer. Default: off. </dd> - -<dt><b>Option "Rotate" "CW"</b> </dt> -<dd>Rotate the display -clockwise. This mode is unaccelerated, and uses the Shadow Frame Buffer -layer. Default: no rotation. </dd> - -<dt><b>Option "Rotate" "CCW"</b> </dt> -<dd>Rotate the display counterclockwise. -This mode is unaccelerated, and uses the Shadow Frame Buffer layer. Default: -no rotation. </dd> - -<dt><b>Option "FlatPanel" "</b><i>boolean</i><b>"</b> </dt> -<dd>This enables the FlatPanel display -unit. The FlatPanel depends on the BIOS to do the Pnale h/w initialization. -In GX based platforms with TFT part Flatpanel is enabled, and on CRT part -is disabled. Default: off. </dd> - -<dt><b>Option "OSMImageBuffers" "</b><i>integer</i><b>"</b> </dt> -<dd>This sets the -number of scanline buffers to be allocated in offscreen memory for acceleration. -This can take any value 0 will disable the allocation. Disabled if cannot -alocate requested scanline memory. Default: 20. </dd> - -<dt><b>Option "ColorKey" "</b><i>integer</i><b>"</b> -</dt> -<dd>This sets the default pixel value for the YUV video overlay key. Default: -0. </dd> -</dl> -<p> -The following <b>Options</b> are supported only on SC1200 based platforms: - -<dl> - -<dt><b>Option "TV" "PAL-768x576"</b> </dt> -<dd>Selects the PAL TV display mode 768x576 and the -depth is forced to 16 bpp. Default: no TV. </dd> - -<dt><b>Option "TV" "PAL-720x576"</b> </dt> -<dd>Selects -the PAL TV display mode 720x576 and the depth is forced to 16 bpp. Default: -no TV. </dd> - -<dt><b>Option "TV" "NTSC-720x480"</b> </dt> -<dd>Selects the NTSC TV display mode 720x480 -and the depth is forced to 16 bpp. Default: no TV. </dd> - -<dt><b>Option "TV" "NTSC-640x480"</b> -</dt> -<dd>Selects the NTSC TV display mode 640x480 and the depth is forced to 16 -bpp. Default: no TV. </dd> - -<dt><b>Option "TV_Output" "COMPOSITE"</b> </dt> -<dd>The selected TV mode -output is coded for Composite signal. Default: no TV. </dd> - -<dt><b>Option "TV_Output" -"SVIDEO"</b> </dt> -<dd>The selected TV mode output is coded for SVIDEO signal. Default: -no TV. </dd> - -<dt><b>Option "TV_Output" "YUV"</b> </dt> -<dd>The selected TV mode output is coded for -YUV signal. Default: no TV. </dd> - -<dt><b>Option "TV_Output" "SCART"</b> </dt> -<dd>The selected TV mode -output is coded for SCART signal. Default: no TV. </dd> - -<dt><b>Option "TVOverscan" x:yy:ww:hh"</b> -</dt> -<dd>This option will let only the viewable display area smaller to be able -to view on TV. The parameters xx: X-offset, yy: Y-offset, ww: Viewable width, -hh: Viewable height. Default: no TV. </dd> -</dl> - -<h2><a name='sect10' href='#toc10'>See Also</a></h2> -<a href='XFree86.1.html'>XFree86(1)</a> -, <a href='XF86Config.5.html'>XF86Config(5x)</a> -, -<a href='xf86config.1.html'>xf86config(1)</a> -, <a href='Xserver.1.html'>Xserver(1)</a> -, <a href='X.7.html'>X(7)</a> - -<h2><a name='sect11' href='#toc11'>Author</a></h2> -Author: William Morrow <p> - -<hr><p> -<a name='toc'><b>Table of Contents</b></a><p> -<ul> -<li><a name='toc0' href='#sect0'>Name</a></li> -<li><a name='toc1' href='#sect1'>Synopsis</a></li> -<li><a name='toc2' href='#sect2'>Description</a></li> -<li><a name='toc3' href='#sect3'>Supported Hardware</a></li> -<li><a name='toc4' href='#sect4'>Configuration Details</a></li> -<li><a name='toc5' href='#sect5'>Name</a></li> -<li><a name='toc6' href='#sect6'>Synopsis</a></li> -<li><a name='toc7' href='#sect7'>Description</a></li> -<li><a name='toc8' href='#sect8'>Supported Hardware</a></li> -<li><a name='toc9' href='#sect9'>Configuration Details</a></li> -<li><a name='toc10' href='#sect10'>See Also</a></li> -<li><a name='toc11' href='#sect11'>Author</a></li> -</ul> -</body> -</html> @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. + /* + * (c) 2006 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -34,6 +34,7 @@ #include "vgaHW.h" #include "xf86int10.h" +#include <X11/extensions/randr.h> #include "xf86xv.h" @@ -230,54 +231,138 @@ typedef struct _VESARec } VESARec; -/* output enable types */ -#define LX_OT_CRT 0x0001 -#define LX_OT_FP 0x0002 -#define LX_OT_VOP 0x0004 -#define LX_OT_DRGB 0x0008 +#define OUTPUT_PANEL 0x01 +#define OUTPUT_CRT 0x02 +#define OUTPUT_TV 0x04 +#define OUTPUT_VOP 0x08 -typedef struct +typedef struct _geodeRec { - /* Private struct for the server */ - unsigned long cpu_version; - unsigned long cpu_revision; - unsigned long vid_version; - INIT_BASE_ADDRESSES InitBaseAddress; - - EntityInfoPtr pEnt; - ScreenBlockHandlerProcPtr BlockHandler; /* needed for video */ - int DetectedChipSet; - int Chipset; -#ifdef HAVE_LX - int cimFd; - unsigned long CmdBfrOffset; - unsigned long CmdBfrSize; - unsigned int EnabledOutput; - unsigned long FBTop; -#endif - unsigned long FBLinearAddr; - unsigned char *FBBase; - unsigned long FBAvail; - unsigned long FBOffset; - unsigned long FBSize; - unsigned long maxWidth, maxHeight; - unsigned int cpu_reg_size; - unsigned int gp_reg_size; - unsigned int vid_reg_size; -#ifdef HAVE_LX - unsigned int vg_reg_size; - unsigned int vip_reg_size; -#endif - int Pitch; /* display FB pitch */ - int AccelPitch; /* accel pitch (may be ShadowPitch) */ - Bool HWCursor; - Bool NoAccel; - Bool CustomMode; - Bool useVGA; - unsigned long VideoKey; - + /* Common */ + + int Output; /* Bitmask indicating the valid output options */ + + Bool HWCursor; + Bool NoAccel; + Bool useVGA; + Bool VGAActive; /* Flag indicating if LX VGA is active */ + Bool Compression; + Bool useEXA; + + int rotation; + int displayWidth; + Bool starting; + Bool tryCompression; + Bool tryHWCursor; + unsigned int shadowSize; + unsigned int shadowOffset; + + DisplayModePtr curMode; + VG_COMPRESSION_DATA CBData; + + unsigned long CursorStartOffset; + unsigned int CursorSize; + xf86CursorInfoPtr CursorInfo; + int CursorXHot; + int CursorYHot; + + /* Geometry information */ + unsigned int maxWidth; /* Maximum possible width of the screen */ + unsigned int maxHeight; /* Maximum possible height of the screen */ + + int Pitch; /* display FB pitch */ + + int displayPitch; /* The pitch ofthe visible area */ + int displayOffset; /* The offset of the visible area */ + int displaySize; /* The size of the visibile area */ + + int PanelX; + int PanelY; + + /* Framebuffer memory */ + + unsigned long FBLinearAddr; + unsigned char *FBBase; + unsigned int FBAvail; + unsigned int FBOffset; + unsigned int FBSize; + + /* Video information */ + int video_x; + int video_y; + short video_w; + short video_h; + short video_srcw; + short video_srch; + short video_dstw; + short video_dsth; + int video_id; + int video_offset; + ScrnInfoPtr video_scrnptr; + BOOL OverlayON; + int videoKey; + + /* EXA structures */ + + ExaDriverPtr pExa; + unsigned int exaBfrOffset; + unsigned int exaBfrSz; + + /* XAA structures */ + unsigned char **AccelImageWriteBuffers; + int NoOfImgBuffers; + unsigned char **AccelColorExpandBuffers; + int NoOfColorExpandLines; + XAAInfoRecPtr AccelInfoRec; + + /* Other structures */ + + EntityInfoPtr pEnt; + ScreenBlockHandlerProcPtr BlockHandler; /* needed for video */ + XF86VideoAdaptorPtr adaptor; + + /* State save structures */ + + gfx_vga_struct FBgfxVgaRegs; + TVTIMING FBtvtiming; + GFX_DISPLAYTIMING FBgfxdisplaytiming; + CIM_DISPLAYTIMING FBcimdisplaytiming; + + unsigned int FBTVActive; + unsigned int FBSupport; + unsigned long FBDisplayOffset; + unsigned long PrevDisplayOffset; + + VESARec *vesa; + + int FBCompressionEnable; + VG_COMPRESSION_DATA FBCBData; + VG_CURSOR_DATA FBCursor; + unsigned long FBCompressionOffset; + unsigned short FBCompressionPitch; + unsigned short FBCompressionSize; + + /* Save the Cursor offset of the FB */ + unsigned long FBCursorOffset; + unsigned char FBBIOSMode; + + /* Hooks */ + + void (*WritePixmap) (ScrnInfoPtr pScrni, int x, int y, int w, int h, + unsigned char *src, int srcwidth, int rop, + unsigned int planemask, int trans, int bpp, int depth); + + void (*PointerMoved) (int index, int x, int y); + CloseScreenProcPtr CloseScreen; + Bool (*CreateScreenResources)(ScreenPtr); + + /* LX only */ + + unsigned long CmdBfrOffset; + unsigned long CmdBfrSize; + +#ifdef HAVE_TVSUPPORT Bool TVSupport; -#ifdef HAVE_LX int tv_encoder; int tv_bus_fmt; int tv_flags; @@ -289,146 +374,25 @@ typedef struct int tv_vsync_select; int tvox, tvoy; - int FPBiosResX, FPBiosResY; - int FPGeomDstSet, FPGeomDstX, FPGeomDstY; - int FPGeomActSet, FPGeomActX, FPGeomActY; -#endif -#ifdef HAVE_GX TVPARAMS TvParam; int TVOx, TVOy, TVOw, TVOh; Bool TV_Overscan_On; - - Bool Panel; - Bool dconPanel; - - /* Flatpanel support from Bios */ - int FPBX; /* xres */ - int FPBY; /* yres */ - int FPBB; /* bpp */ - int FPBF; /* freq */ -#endif - - int Rotate; - void (*Rotation) (int x, int y, int w, int h, int *newX, int *newY); - void (*RBltXlat) (int x, int y, int w, int h, int *newX, int *newY); - -#ifdef HAVE_GX - void (*WritePixmap) (ScrnInfoPtr pScrni, int x, int y, int w, int h, - unsigned char *src, int srcwidth, int rop, - unsigned int planemask, int trans, int bpp, int depth); -#endif - - Bool ShadowFB; - unsigned char *ShadowPtr; - int ShadowSize; - int ShadowPitch; - int ShadowInFBMem; - - int orig_virtX; /* original */ - int orig_virtY; - int HDisplay; /* rotated */ - int VDisplay; - - void (*PointerMoved) (int index, int x, int y); - /* CloseScreen function. */ - CloseScreenProcPtr CloseScreen; - - Bool Compression; -#ifdef HAVE_LX - VG_COMPRESSION_DATA CBData; -#endif -#ifdef HAVE_GX - unsigned int CBOffset; - unsigned int CBPitch; - unsigned int CBSize; -#endif - unsigned long CursorStartOffset; - unsigned int CursorSize; - xf86CursorInfoPtr CursorInfo; - int CursorXHot; - int CursorYHot; - unsigned long OffscreenStartOffset; - unsigned int OffscreenSize; - - /***Image Write structures ***/ - - /* offset in video memory for ImageWrite Buffers */ - unsigned char **AccelImageWriteBuffers; - int NoOfImgBuffers; - unsigned char **AccelColorExpandBuffers; - int NoOfColorExpandLines; - -/*****************************************/ -/* Saved Console State */ -#ifdef HAVE_GX - gfx_vga_struct FBgfxVgaRegs; - TVTIMING FBtvtiming; - GFX_DISPLAYTIMING FBgfxdisplaytiming; -#endif -#ifdef HAVE_LX - CIM_DISPLAYTIMING FBcimdisplaytiming; -#endif - int FBVGAActive; - unsigned int FBTVActive; - unsigned int FBSupport; - unsigned long FBDisplayOffset; - unsigned long PrevDisplayOffset; - - VESARec *vesa; - - /* compression */ - int FBCompressionEnable; -#ifdef HAVE_LX - VG_COMPRESSION_DATA FBCBData; - VG_CURSOR_DATA FBCursor; -#endif -#ifdef HAVE_GX - unsigned long FBCompressionOffset; - unsigned short FBCompressionPitch; - unsigned short FBCompressionSize; - - /* Save the Cursor offset of the FB */ - unsigned long FBCursorOffset; -#endif - unsigned char FBBIOSMode; -/*****************************************/ - - XAAInfoRecPtr AccelInfoRec; - - DGAModePtr DGAModes; - int numDGAModes; - Bool DGAactive; - int DGAViewportStatus; -/*****************************************/ - int video_x; - int video_y; - short video_w; - short video_h; - short video_srcw; - short video_srch; - short video_dstw; - short video_dsth; - int video_id; - int video_offset; - ScrnInfoPtr video_scrnptr; - BOOL OverlayON; - - int videoKey; - XF86VideoAdaptorPtr adaptor; - Bool useEXA; -#if XF86EXA - ExaDriverPtr pExa; - unsigned int exaBfrOffset; - unsigned int exaBfrSz; - unsigned int cpySrcOffset; - int cpySrcPitch, cpySrcBpp; - int cpyDx, cpyDy; - unsigned int cmpSrcOffset; - int cmpSrcPitch, cmpSrcBpp; - unsigned int cmpSrcFmt, cmpDstFmt; - int cmpOp; #endif + + /* To be killed! */ + + int FBVGAActive; + unsigned int cpySrcOffset; + int cpySrcPitch, cpySrcBpp; + int cpyDx, cpyDy; + unsigned int cmpSrcOffset; + int cmpSrcPitch, cmpSrcBpp; + unsigned int cmpSrcFmt, cmpDstFmt; + int cmpOp; + + Bool Panel; + } GeodeRec, *GeodePtr; @@ -440,23 +404,16 @@ enum LX_OPTION_HW_CURSOR, LX_OPTION_NOCOMPRESSION, LX_OPTION_NOACCEL, - LX_OPTION_TV_ENCODER, - LX_OPTION_TV_BUS_FMT, - LX_OPTION_TV_FLAGS, - LX_OPTION_TV_601_FLAGS, - LX_OPTION_TV_VSYNC_SELECT, - LX_OPTION_TV_CONVERSION, + LX_OPTION_ACCEL_METHOD, + LX_OPTION_EXA_SCRATCH_BFRSZ, + LX_OPTION_TV_SUPPORT, + LX_OPTION_TV_OUTPUT, LX_OPTION_TV_OVERSCAN, - LX_OPTION_SHADOW_FB, LX_OPTION_ROTATE, - LX_OPTION_FLATPANEL, - LX_OPTION_CRTENABLE, + LX_OPTION_NOPANEL, LX_OPTION_COLOR_KEY, - LX_OPTION_OSM_IMG_BUFS, - LX_OPTION_OSM_CLR_BUFS, - LX_OPTION_CUSTOM_MODE, - LX_OPTION_FP_DEST_GEOM, - LX_OPTION_FP_ACTIVE_GEOM, + LX_OPTION_FBSIZE, + LX_OPTION_PANEL_GEOMETRY, LX_OPTION_DONT_PROGRAM } LX_GeodeOpts; @@ -474,19 +431,16 @@ enum GX_OPTION_TV_SUPPORT, GX_OPTION_TV_OUTPUT, GX_OPTION_TV_OVERSCAN, - GX_OPTION_SHADOW_FB, GX_OPTION_ROTATE, - GX_OPTION_FLATPANEL, + GX_OPTION_NOPANEL, GX_OPTION_FLATPANEL_INFO, GX_OPTION_FLATPANEL_IN_BIOS, GX_OPTION_COLOR_KEY, GX_OPTION_OSM, GX_OPTION_OSM_IMG_BUFS, GX_OPTION_OSM_CLR_BUFS, - GX_OPTION_CUSTOM_MODE, GX_OPTION_FBSIZE, - GX_OPTION_NOVGA, - GX_OPTION_DCONPANEL, + GX_OPTION_PANEL_GEOMETRY, GX_OPTION_DONT_PROGRAM } GX_GeodeOpts; @@ -498,5 +452,74 @@ GX_GeodeOpts; #define DCON_DEFAULT_YRES 900 #define DCON_DEFAULT_BPP 16 #define DCON_DEFAULT_REFRESH 50 +extern Bool gx_dcon_init(ScrnInfoPtr pScrni); + +/* amd_common.c */ + +void geode_memory_to_screen_blt(unsigned long, unsigned long, + unsigned long, unsigned long, long, long, int); +int GeodeGetRefreshRate(DisplayModePtr); +void GeodeCopyGreyscale(unsigned char *, unsigned char *, int, int, int, int); + +/* amd_gx_video.c */ + +int +GeodeQueryImageAttributes(ScrnInfoPtr, int id, unsigned short *w, + unsigned short *h, int *pitches, int *offsets); + + +Bool RegionsEqual(RegionPtr A, RegionPtr B); + +/* amd_gx_driver.c */ + +void GeodeProbeDDC(ScrnInfoPtr pScrni, int index); +xf86MonPtr GeodeDoDDC(ScrnInfoPtr pScrni, int index); +int GeodeGetFPGeometry(const char *str, int *width, int *height); +void GeodePointerMoved(int index, int x, int y); +void GeodeFreeScreen(int scrnIndex, int flags); +int GeodeCalculatePitchBytes(unsigned int width, unsigned int bpp); + +/* amd_msr.c */ +int GeodeReadMSR(unsigned long addr, unsigned long *lo, unsigned long *hi); +int GeodeWriteMSR(unsigned long addr, unsigned long lo, unsigned long hi); + +/* amd_gx_cursor.c */ +Bool GXHWCursorInit(ScreenPtr pScrn); +void GXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src); +void GXHideCursor(ScrnInfoPtr pScrni); +void GXShowCursor(ScrnInfoPtr pScrni); + +/* amd_gx_randr.c */ +Rotation GXGetRotation(ScreenPtr pScreen); +Bool GXRandRInit(ScreenPtr pScreen, int rotation); + +/* amd_gx_rotate.c */ +Bool GXRotate(ScrnInfoPtr pScrni, DisplayModePtr mode); + +/* amd_gx_accel.c */ +Bool GXAccelInit(ScreenPtr pScrn); + +/* amd_gx_video.c */ +void GXInitVideo(ScreenPtr pScrn); + +/* amd_lx_cursor.c */ +Bool LXHWCursorInit(ScreenPtr pScrn); +void LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src); +void LXHideCursor(ScrnInfoPtr pScrni); +void LXShowCursor(ScrnInfoPtr pScrni); + +/* amd_lx_randr.c */ +Rotation LXGetRotation(ScreenPtr pScreen); +Bool LXRandRInit(ScreenPtr pScreen, int rotation); + +/* amd_lx_rotate.c */ +Bool LXSetRotatePitch(ScrnInfoPtr pScrni); +Bool LXRotate(ScrnInfoPtr pScrni, DisplayModePtr mode); + +/* amd_lx_exa.c */ +Bool LXExaInit(ScreenPtr pScreen); + +/* amd_lx_video.c */ +void LXInitVideo(ScreenPtr pScrn); #endif /* _AMD_GEODE_H_ */ diff --git a/src/amd_blend.h b/src/amd_blend.h new file mode 100644 index 0000000..6748ec0 --- /dev/null +++ b/src/amd_blend.h @@ -0,0 +1,62 @@ +#ifndef AMD_BLEND_H_ +#define AMD_BLEND_H_ + +#define GEODEPTR_FROM_PIXMAP(x) \ + GEODEPTR(xf86Screens[(x)->drawable.pScreen->myNum]) +#define GEODEPTR_FROM_SCREEN(x) \ + GEODEPTR(xf86Screens[(x)->myNum]) +#define GEODEPTR_FROM_PICTURE(x) \ + GEODEPTR(xf86Screens[(x)->pDrawable->pScreen->myNum]) + +#define usesPasses(op) ((( \ + ( 1 << PictOpAtop ) | \ + ( 1 << PictOpAtopReverse ) | \ + ( 1 << PictOpXor ) | \ + 0 ) >> (op)) & 1) + +/* pass1 or pass2 */ +#define usesSrcAlpha(op) ((( \ + ( 1 << PictOpOver ) | \ + ( 1 << PictOpInReverse ) | \ + ( 1 << PictOpOutReverse ) | \ + ( 1 << PictOpAtop ) | \ + ( 1 << PictOpAtopReverse ) | \ + ( 1 << PictOpXor ) | \ + 0 ) >> (op)) & 1) + +/* pass1 or pass2 */ +#define usesDstAlpha(op) ((( \ + ( 1 << PictOpOverReverse ) | \ + ( 1 << PictOpIn ) | \ + ( 1 << PictOpOut ) | \ + ( 1 << PictOpAtop ) | \ + ( 1 << PictOpAtopReverse ) | \ + ( 1 << PictOpXor ) | \ + 0 ) >> (op)) & 1) + +/* non 2 pass ops */ +#define usesChanB0(op) ((( \ + ( 1 << PictOpOver ) | \ + ( 1 << PictOpOverReverse ) | \ + ( 1 << PictOpIn ) | \ + ( 1 << PictOpInReverse ) | \ + ( 1 << PictOpOut ) | \ + ( 1 << PictOpOutReverse ) | \ + ( 1 << PictOpAdd ) | \ + 0 ) >> (op)) & 1) + +/* pass 1 ops */ +#define usesChanB1(op) ((( \ + ( 1 << PictOpAtop ) | \ + ( 1 << PictOpAtopReverse ) | \ + ( 1 << PictOpXor ) | \ + 0 ) >> (op)) & 1) + +/* pass 2 ops */ +#define usesChanB2(op) ((( \ + ( 1 << PictOpAtop ) | \ + ( 1 << PictOpAtopReverse ) | \ + ( 1 << PictOpXor ) | \ + 0 ) >> (op)) & 1) + +#endif diff --git a/src/amd_common.c b/src/amd_common.c new file mode 100644 index 0000000..f7e0d73 --- /dev/null +++ b/src/amd_common.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2007 Advanced Micro Devices, Inc. + * + * 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, + * 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. + * + * Neither the name of the Advanced Micro Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + */ + +/* We want to share as much code between GX and LX as we possibly can for obvious reasons */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" + +#define move0(d,s,n) \ + __asm__ __volatile__( \ + " rep; movsl\n" \ + : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ + : "0" (n), "1" (s), "2" (d) \ + : "memory") + + + +#define move1(d,s,n) \ + __asm__ __volatile__( \ + " rep; movsl\n" \ + " movsb\n" \ + : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ + : "0" (n), "1" (s), "2" (d) \ + : "memory") + +#define move2(d,s,n) \ + __asm__ __volatile__( \ + " rep; movsl\n" \ + " movsw\n" \ + : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ + : "0" (n), "1" (s), "2" (d) \ + : "memory") + +#define move3(d,s,n) \ + __asm__ __volatile__( \ + " rep; movsl\n" \ + " movsw\n" \ + " movsb\n" \ + : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ + : "0" (n), "1" (s), "2" (d) \ + : "memory") + + +void +geode_memory_to_screen_blt(unsigned long src, unsigned long dst, + unsigned long sp, unsigned long dp, long w, long h, int bpp) +{ + int d0, d1, d2; + int n = w * (bpp >> 3); + int m = n >> 2; + + switch (n & 3) { + case 0: + while (--h >= 0) { + move0(dst, src, m); + src += sp; + dst += dp; + } + break; + case 1: + while (--h >= 0) { + move1(dst, src, m); + src += sp; + dst += dp; + } + break; + case 2: + while (--h >= 0) { + move2(dst, src, m); + src += sp; + dst += dp; + } + break; + case 3: + while (--h >= 0) { + move3(dst, src, m); + src += sp; + dst += dp; + } + break; + } +} + +/* I borrowed this function from the i830 driver - its much better + then what we had before +*/ + +int +GeodeGetRefreshRate(DisplayModePtr pMode) +{ + if (pMode->VRefresh) + return (int)(pMode->VRefresh + 0.5); + + return (int)(pMode->Clock * 1000.0 / pMode->HTotal / pMode->VTotal + 0.5); +} + +/* This is used by both GX and LX. It could be accelerated for LX, probably, but + that would involve a two pass blt, the first to copy the data, and the second + to copy the grey (using a pattern). That seems like a bit of work for a + very underused format - so we'll just use the slow version. +*/ + +void +GeodeCopyGreyscale(unsigned char *src, unsigned char *dst, + int dstPitch, int srcPitch, int h, int w) +{ + int i; + unsigned char *src2 = src; + unsigned char *dst2 = dst; + unsigned char *dst3; + unsigned char *src3; + + dstPitch <<= 1; + + while (h--) { + dst3 = dst2; + src3 = src2; + for (i = 0; i < w; i++) { + *dst3++ = *src3++; /* Copy Y data */ + *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ + } + + src3 = src2; + for (i = 0; i < w; i++) { + *dst3++ = *src3++; /* Copy Y data */ + *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ + } + + dst2 += dstPitch; + src2 += srcPitch; + } +} diff --git a/src/amd_driver.c b/src/amd_driver.c index 5f6c3d0..2a12b40 100644 --- a/src/amd_driver.c +++ b/src/amd_driver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Advanced Micro Devices, Inc. + * Copyright (c) 2006 Avanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -54,23 +54,7 @@ #define RC_MAX_DEPTH 24 -/* Frame buffer stuff */ -#if CFB -/* - * If using cfb, cfb.h is required. Select the others for the bpp values - * the driver supports. - */ -#define PSZ 8 /* needed for cfb.h */ -#include "cfb.h" -#undef PSZ -#include "cfb16.h" -#include "cfb24.h" -#include "cfb32.h" -#else #include "fb.h" -#endif - -#include "shadowfb.h" /* Machine independent stuff */ #include "mipointer.h" @@ -169,25 +153,19 @@ OptionInfoRec LX_GeodeOptions[] = { {LX_OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE}, {LX_OPTION_NOCOMPRESSION, "NoCompression", OPTV_BOOLEAN, {0}, FALSE}, {LX_OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, - {LX_OPTION_TV_ENCODER, "TV_Encoder", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_TV_BUS_FMT, "TV_Bus_Fmt", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_TV_FLAGS, "TV_Flags", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_TV_601_FLAGS, "TV_601_Flags", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_TV_VSYNC_SELECT, "TV_Vsync_Select", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_TV_CONVERSION, "TV_Conversion", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_TV_OVERSCAN, "TV_Overscan", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, + {LX_OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE}, + {LX_OPTION_TV_SUPPORT, "TV", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_TV_OUTPUT, "TV_Output", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_TV_OVERSCAN, "TVOverscan", OPTV_ANYSTR, {0}, FALSE}, {LX_OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_FLATPANEL, "FlatPanel", OPTV_BOOLEAN, {0}, FALSE}, - {LX_OPTION_CRTENABLE, "CrtEnable", OPTV_BOOLEAN, {0}, FALSE}, + {LX_OPTION_NOPANEL, "NoPanel", OPTV_BOOLEAN, {0}, FALSE}, {LX_OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE}, - {LX_OPTION_OSM_IMG_BUFS, "OSMImageBuffers", OPTV_INTEGER, {0}, FALSE}, - {LX_OPTION_OSM_CLR_BUFS, "OSMColorExpBuffers", OPTV_INTEGER, {0}, FALSE}, - {LX_OPTION_CUSTOM_MODE, "CustomMode", OPTV_BOOLEAN, {0}, FALSE}, - {LX_OPTION_FP_DEST_GEOM, "FPDestGeom", OPTV_ANYSTR, {0}, FALSE}, - {LX_OPTION_FP_ACTIVE_GEOM, "FPActiveGeom", OPTV_ANYSTR, {0}, FALSE}, + {LX_OPTION_EXA_SCRATCH_BFRSZ, "ExaScratch", OPTV_INTEGER, {0}, FALSE}, + {LX_OPTION_FBSIZE, "FBSize", OPTV_INTEGER, {0}, FALSE }, + {LX_OPTION_PANEL_GEOMETRY, "PanelGeometry", OPTV_STRING, {0}, FALSE }, {-1, NULL, OPTV_NONE, {0}, FALSE} }; + #endif #ifdef HAVE_GX @@ -202,16 +180,13 @@ OptionInfoRec GX_GeodeOptions[] = { {GX_OPTION_TV_SUPPORT, "TV", OPTV_ANYSTR, {0}, FALSE}, {GX_OPTION_TV_OUTPUT, "TV_Output", OPTV_ANYSTR, {0}, FALSE}, {GX_OPTION_TV_OVERSCAN, "TVOverscan", OPTV_ANYSTR, {0}, FALSE}, - {GX_OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, {GX_OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, - {GX_OPTION_FLATPANEL, "FlatPanel", OPTV_BOOLEAN, {0}, FALSE}, + {GX_OPTION_NOPANEL, "NoPanel", OPTV_BOOLEAN, {0}, FALSE}, {GX_OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE}, {GX_OPTION_OSM_IMG_BUFS, "OSMImageBuffers", OPTV_INTEGER, {0}, FALSE}, {GX_OPTION_OSM_CLR_BUFS, "OSMColorExpBuffers", OPTV_INTEGER, {0}, FALSE}, - {GX_OPTION_CUSTOM_MODE, "CustomMode", OPTV_BOOLEAN, {0}, FALSE}, {GX_OPTION_FBSIZE, "FBSize", OPTV_INTEGER, {0}, FALSE }, - {GX_OPTION_NOVGA, "NoVGA", OPTV_BOOLEAN, {0}, FALSE }, - {GX_OPTION_DCONPANEL, "DconPanel", OPTV_BOOLEAN, {0}, FALSE }, + {GX_OPTION_PANEL_GEOMETRY, "PanelGeometry", OPTV_STRING, {0}, FALSE }, {-1, NULL, OPTV_NONE, {0}, FALSE} }; #endif @@ -253,21 +228,11 @@ const char *amdInt10Symbols[] = { NULL }; -#if CFB -const char *amdCfbSymbols[] = { - "cfbScreenInit", - "cfb16ScreenInit", - "cfb24ScreenInit", - "cfb32ScreenInit", - NULL -}; -#else const char *amdFbSymbols[] = { "fbScreenInit", "fbPictureInit", NULL }; -#endif const char *amdXaaSymbols[] = { "XAADestroyInfoRec", @@ -293,11 +258,6 @@ const char *amdRamdacSymbols[] = { NULL }; -const char *amdShadowSymbols[] = { - "ShadowFBInit", - NULL -}; - #ifdef XFree86LOADER /* Module loader interface */ @@ -356,13 +316,8 @@ AmdSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) * module might refer to. */ LoaderRefSymLists(amdVgahwSymbols, amdVbeSymbols, -#if CFB - amdCfbSymbols, -#else - amdFbSymbols, -#endif - amdXaaSymbols, - amdInt10Symbols, amdRamdacSymbols, amdShadowSymbols, NULL); + amdFbSymbols, amdXaaSymbols, + amdInt10Symbols, amdRamdacSymbols, NULL); return (pointer) TRUE; } @@ -452,7 +407,7 @@ AmdProbe(DriverPtr drv, int flags) GDevPtr *devSections = NULL; int *usedChips = NULL; int i; - void (*drvr_setup) (ScrnInfoPtr pScrni); + void (*drvr_setup) (ScrnInfoPtr pScrni) = NULL; DEBUGMSG(1, (0, X_INFO, "AmdProbe: Probing for supported devices!\n")); /* @@ -507,12 +462,15 @@ AmdProbe(DriverPtr drv, int flags) break; #endif default: - return FALSE; + break; } break; } } xfree(pEnt); + if (drvr_setup == NULL) + return FALSE; + DEBUGMSG(1, (0, X_INFO, "AmdProbe: CPUDetected %d!\n", CPUDetected)); diff --git a/src/amd_fourcc.h b/src/amd_fourcc.h index 2fe6f9e..f34c2fb 100644 --- a/src/amd_fourcc.h +++ b/src/amd_fourcc.h @@ -87,4 +87,26 @@ XvTopToBottom \ } +/* Borrowed from Trident */ + +#define FOURCC_RGB565 0x36315652 +#define XVIMAGE_RGB565 \ + { \ + FOURCC_RGB565, \ + XvRGB,\ + LSBFirst,\ + {'R','V','1','6',\ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},\ + 16,\ + XvPacked,\ + 1,\ + 16, 0xF800, 0x07E0, 0x001F,\ + 0, 0, 0,\ + 0, 0, 0,\ + 0, 0, 0,\ + {'R','V','B',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},\ + XvTopToBottom\ + } + #endif diff --git a/src/amd_gx_accel.c b/src/amd_gx_accel.c index 20c79ef..84281f1 100644 --- a/src/amd_gx_accel.c +++ b/src/amd_gx_accel.c @@ -56,6 +56,10 @@ #include "gfx_defs.h" #include "gfx_regs.h" +/* Common macros for blend operations are here */ + +#include "amd_blend.h" + #undef ulong typedef unsigned long ulong; @@ -68,49 +72,8 @@ typedef unsigned short ushort; #undef uchar typedef unsigned char uchar; -#if DEBUGLVL>0 -extern FILE *zdfp; - -#if DEBUGTIM>0 -#ifdef NO_RDTSC -#define DBLOG(n,s...) \ - do { \ - if((DEBUGLVL)>=(n)) { \ - long secs,usecs; \ - getsecs(&secs,&usecs); \ - fprintf(zdfp,"%d,%d ",secs,usecs); \ - fprintf(zdfp,s); \ - } \ - } while(0) -#else /* ifdef No_RDTSC */ -#define tsc(n) __asm__ __volatile__ ( \ - " rdtsc" \ - : "=a" (((int*)(&(n)))[0]), "=d" (((int*)(&(n)))[1]) \ - : ) -#define DBLOG(n,s...) \ - do { \ - if((DEBUGLVL)>=(n)) { \ - long long t; \ - tsc(t); \ - fprintf(zdfp,"%lld ",t); \ - fprintf(zdfp,s); \ - } \ - } while(0) -#endif /* ifdef No_RDTSC */ -#else /* if DEBUFTIM */ -#define DBLOG(n,s...) \ - do { \ - if((DEBUGLVL)>=(n)) \ - fprintf(zdfp,s); \ - } while(0) -#endif /* if DEBUGTIM */ -#else /* if DEBUGLVL > 0 */ -#define DBLOG(n,s...) \ - do {} while(0) -#endif /* if DEBUGLVL > 0 */ - #define CALC_FBOFFSET(x, y) \ - (((ulong)(y) * gu2_pitch) + ((ulong)(x) << gu2_xshift)) + (((ulong)(y) * gu2_pitch + ((ulong)(x) << gu2_xshift))) #define FBADDR(x,y) \ ((unsigned char *)pGeode->FBBase + CALC_FBOFFSET(x, y)) @@ -133,6 +96,8 @@ unsigned int ACCEL_STRIDE; #define HOOK(fn) localRecPtr->fn = GX##fn +#define DLOG(l, fmt, args...) ErrorF(fmt, ##args) + /* static storage declarations */ typedef struct sGBltBox @@ -202,78 +167,6 @@ static int PDfn_SM[16] = { 0x26, 0xA6, 0x66, 0xE6, 0x2E, 0xAE, 0x6E, 0xEE }; -#define move0(d,s,n) \ - __asm__ __volatile__( \ - " rep; movsl\n" \ - : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ - : "0" (n), "1" (s), "2" (d) \ - : "memory") - -#define move1(d,s,n) \ - __asm__ __volatile__( \ - " rep; movsl\n" \ - " movsb\n" \ - : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ - : "0" (n), "1" (s), "2" (d) \ - : "memory") - -#define move2(d,s,n) \ - __asm__ __volatile__( \ - " rep; movsl\n" \ - " movsw\n" \ - : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ - : "0" (n), "1" (s), "2" (d) \ - : "memory") - -#define move3(d,s,n) \ - __asm__ __volatile__( \ - " rep; movsl\n" \ - " movsw\n" \ - " movsb\n" \ - : "=&c" (d0), "=&S" (d1), "=&D" (d2) \ - : "0" (n), "1" (s), "2" (d) \ - : "memory") - -static void -amd_memory_to_screen_blt(unsigned long src, unsigned long dst, - unsigned long sp, unsigned long dp, long w, long h, int bpp) -{ - int d0, d1, d2; - int n = w * (bpp >> 3); - int m = n >> 2; - - switch (n & 3) { - case 0: - while (--h >= 0) { - move0(dst, src, m); - src += sp; - dst += dp; - } - break; - case 1: - while (--h >= 0) { - move1(dst, src, m); - src += sp; - dst += dp; - } - break; - case 2: - while (--h >= 0) { - move2(dst, src, m); - src += sp; - dst += dp; - } - break; - case 3: - while (--h >= 0) { - move3(dst, src, m); - src += sp; - dst += dp; - } - break; - } -} - /*---------------------------------------------------------------------------- * GXAccelSync. * @@ -289,7 +182,7 @@ amd_memory_to_screen_blt(unsigned long src, unsigned long dst, void GXAccelSync(ScrnInfoPtr pScrni) { - DBLOG(3, "GXAccelSync()\n"); + //ErrorF("GXAccelSync()\n"); #ifndef OPT_ACCEL gfx_wait_until_idle(); #else @@ -318,7 +211,7 @@ static void GXSetupForSolidFill(ScrnInfoPtr pScrni, int color, int rop, unsigned int planemask) { - DBLOG(2, "GXSetupForSolidFill(%#x,%#x,%#x)\n", color, rop, planemask); + //ErrorF("GXSetupForSolidFill(%#x,%#x,%#x)\n", color, rop, planemask); rop &= 0x0F; #ifndef OPT_ACCEL gfx_set_solid_pattern(planemask); @@ -365,18 +258,18 @@ GXSetupForSolidFill(ScrnInfoPtr pScrni, static void GXSubsequentSolidFillRect(ScrnInfoPtr pScrni, int x, int y, int w, int h) { - DBLOG(2, "GXSubsequentSolidFillRect() at %d,%d %dx%d\n", x, y, w, h); + //ErrorF("GXSubsequentSolidFillRect() at %d,%d %dx%d\n", x, y, w, h); #ifndef OPT_ACCEL gfx_pattern_fill(x, y, w, h); #else { - unsigned int offset = CALC_FBOFFSET(x, y); - unsigned int size = (w << 16) | h; - - GU2_WAIT_PENDING; - WRITE_GP32(MGP_DST_OFFSET, offset); - WRITE_GP32(MGP_WID_HEIGHT, size); - WRITE_GP32(MGP_BLT_MODE, BLT_MODE); + unsigned int offset = CALC_FBOFFSET(x, y); + unsigned int size = (w << 16) | h; + + GU2_WAIT_PENDING; + WRITE_GP32(MGP_DST_OFFSET, offset); + WRITE_GP32(MGP_WID_HEIGHT, size); + WRITE_GP32(MGP_BLT_MODE, BLT_MODE); } #endif } @@ -412,16 +305,16 @@ GXSetupForColor8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, int rop, { GeodeRec *pGeode = GEODEPTR(pScrni); - DBLOG(2, "GXSetupForColor8x8PatternFill() pat %#x,%#x rop %#x %#x %#x\n", - patx, paty, rop, planemask, trans_color); + //ErrorF("GXSetupForColor8x8PatternFill() pat %#x,%#x rop %#x %#x %#x\n", + // patx, paty, rop, planemask, trans_color); rop &= 0x0F; gc8x8p = (unsigned long *)FBADDR(patx, paty); /* gfx_set_solid_pattern is needed to clear src/pat transparency */ gfx_set_solid_pattern(0); gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] : (gfx_set_solid_source(planemask), PDfn_SM[rop])); - gfx2_set_source_stride(pGeode->AccelPitch); - gfx2_set_destination_stride(pGeode->AccelPitch); + gfx2_set_source_stride(pGeode->Pitch); + gfx2_set_destination_stride(pGeode->Pitch); if (trans_color == -1) gfx2_set_source_transparency(0, 0); else @@ -453,9 +346,9 @@ static void GXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty, int x, int y, int w, int h) { - DBLOG(2, - "GXSubsequentColor8x8PatternFillRect() patxy %d,%d at %d,%d %dsx%d\n", - patx, paty, x, y, w, h); + //ErrorF( + // "GXSubsequentColor8x8PatternFillRect() patxy %d,%d at %d,%d %dsx%d\n", + // patx, paty, x, y, w, h); gfx2_set_pattern_origin(patx, paty); gfx2_color_pattern_fill(CALC_FBOFFSET(x, y), w, h, gc8x8p); } @@ -491,9 +384,9 @@ static void GXSetupForMono8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, int fg, int bg, int rop, uint planemask) { - DBLOG(2, - "GXSetupForMono8x8PatternFill() pat %#x,%#x fg %#x bg %#x %#x %#x\n", - patx, paty, fg, bg, rop, planemask); + //ErrorF( + //"GXSetupForMono8x8PatternFill() pat %#x,%#x fg %#x bg %#x %#x %#x\n", + //patx, paty, fg, bg, rop, planemask); rop &= 0x0F; #ifndef OPT_ACCEL gfx_set_mono_pattern(bg, fg, patx, paty, bg == -1 ? 1 : 0); @@ -545,9 +438,8 @@ static void GXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty, int x, int y, int w, int h) { - DBLOG(2, - "GXSubsequentMono8x8PatternFillRect() pat %#x,%#x at %d,%d %dx%d\n", - patx, paty, x, y, w, h); + DEBUGMSG(1, (0, X_INFO, "%s() pat %#x,%#x at %d,%d %dx%d\n", + __func__, patx, paty, x, y, w, h)); #ifndef OPT_ACCEL gfx_pattern_fill(x, y, w, h); #else @@ -588,8 +480,8 @@ static void GXSetupForScreenToScreenCopy(ScrnInfoPtr pScrni, int xdir, int ydir, int rop, uint planemask, int trans_color) { - DBLOG(2, "GXSetupForScreenToScreenCopy() xd%d yd%d rop %#x %#x %#x\n", - xdir, ydir, rop, planemask, trans_color); + DEBUGMSG(1, (0, X_INFO, "%s() xd%d yd%d rop %#x %#x %#x\n", + __func__, xdir, ydir, rop, planemask, trans_color)); rop &= 0x0F; #ifndef OPT_ACCEL { @@ -603,8 +495,8 @@ GXSetupForScreenToScreenCopy(ScrnInfoPtr pScrni, int xdir, int ydir, int rop, else gfx2_set_source_transparency(trans_color, ~0); gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); - gfx2_set_source_stride(pGeode->AccelPitch); - gfx2_set_destination_stride(pGeode->AccelPitch); + gfx2_set_source_stride(pGeode->Pitch); + gfx2_set_destination_stride(pGeode->Pitch); } #else { @@ -649,8 +541,8 @@ static void GXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrni, int x1, int y1, int x2, int y2, int w, int h) { - DBLOG(2, "GXSubsequentScreenToScreenCopy() from %d,%d to %d,%d %dx%d\n", - x1, y1, x2, y2, w, h); + DEBUGMSG(1, (0, X_INFO, "%s() from %d,%d to %d,%d %dx%d\n", + __func__, x1, y1, x2, y2, w, h)); #ifndef OPT_ACCEL { int flags = 0; @@ -678,7 +570,7 @@ GXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrni, blt_mode |= MGP_BM_NEG_XDIR; } if (y2 > y1) { - int n = (h - 1) * pGeode->AccelPitch; + int n = (h - 1) * pGeode->Pitch; src += n; dst += n; @@ -724,8 +616,8 @@ GXSetupForScanlineImageWrite(ScrnInfoPtr pScrni, int rop, uint planemask, { GeodeRec *pGeode = GEODEPTR(pScrni); - DBLOG(2, "GXSetupForScanlineImageWrite() rop %#x %#x %#x %d %d\n", - rop, planemask, trans_color, bpp, depth); + DEBUGMSG(1, (0, X_INFO, "%s() rop %#x %#x %#x %d %d\n", + __func__, rop, planemask, trans_color, bpp, depth)); rop &= 0x0F; /* transparency is a parameter to set_rop, but set...pattern clears * transparency */ @@ -735,8 +627,8 @@ GXSetupForScanlineImageWrite(ScrnInfoPtr pScrni, int rop, uint planemask, else gfx2_set_source_transparency(trans_color, ~0); gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); - gfx2_set_source_stride(pGeode->AccelPitch); - gfx2_set_destination_stride(pGeode->AccelPitch); + gfx2_set_source_stride(pGeode->Pitch); + gfx2_set_destination_stride(pGeode->Pitch); } /*---------------------------------------------------------------------------- @@ -758,8 +650,8 @@ static void GXSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrni, int x, int y, int w, int h, int skipleft) { - DBLOG(2, "GXSubsequentScanlineImageWriteRect() rop %d,%d %dx%d %d\n", x, - y, w, h, skipleft); + DEBUGMSG(1, (0, X_INFO, "%s() rop %d,%d %dx%d %d\n", + __func__, x, y, w, h, skipleft)); giwr.x = x; giwr.y = y; giwr.w = w; @@ -798,20 +690,20 @@ GXSubsequentImageWriteScanline(ScrnInfoPtr pScrni, int bufno) #endif #if GX_ONE_LINE_AT_A_TIME - DBLOG(3, "GXSubsequentImageWriteScanline() %d\n", bufno); + DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno)); #if !GX_USE_OFFSCRN_MEM offset = pGeode->AccelImageWriteBuffers[bufno] - pGeode->FBBase; gfx2_screen_to_screen_blt(offset, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w, 1, 0); #else /* if !GX_USE_OFFSCRN_MEM */ gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y), - giwr.w, 1, pGeode->AccelImageWriteBuffers[bufno], pGeode->AccelPitch); + giwr.w, 1, pGeode->AccelImageWriteBuffers[bufno], pGeode->Pitch); #endif /* if !GX_USE_OFFSCRN_MEM */ ++giwr.y; #else /* if GX_ONE_LINE_AT_A_TIME */ int blt_height; - DBLOG(3, "GXSubsequentImageWriteScanline() %d\n", bufno); + DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno)); if ((blt_height = pGeode->NoOfImgBuffers) > giwr.h) blt_height = giwr.h; @@ -825,7 +717,7 @@ GXSubsequentImageWriteScanline(ScrnInfoPtr pScrni, int bufno) #else /* if !GX_USE_OFFSCRN_MEM */ gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w, blt_height, pGeode->AccelImageWriteBuffers[0], - pGeode->AccelPitch); + pGeode->Pitch); #endif /* if !GX_USE_OFFSCRN_MEM */ giwr.h -= blt_height; giwr.y += blt_height; @@ -859,20 +751,19 @@ GXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni, GeodeRec *pGeode = GEODEPTR(pScrni); ulong srcpitch; - DBLOG(2, - "GXSetupForScanlineCPUToScreenColorExpandFill() fg %#x bg %#x " - "rop %#x %#x\n", fg, bg, rop, planemask); + DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n", + __func__, fg, bg, rop, planemask)); rop &= 0x0F; - srcpitch = ((pGeode->AccelPitch + 31) >> 5) << 2; + srcpitch = ((pGeode->Pitch + 31) >> 5) << 2; #ifndef OPT_ACCEL gfx_set_solid_pattern(planemask); gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0); gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); gfx2_set_source_stride(srcpitch); - gfx2_set_destination_stride(pGeode->AccelPitch); + gfx2_set_destination_stride(pGeode->Pitch); #else { - unsigned int stride = (srcpitch << 16) | pGeode->AccelPitch; + unsigned int stride = (srcpitch << 16) | pGeode->Pitch; unsigned int ROP = BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); if (bg == -1) @@ -910,9 +801,8 @@ static void GXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni, int x, int y, int w, int h, int skipleft) { - DBLOG(2, - "GXSubsequentScanlineCPUToScreenColorExpandFill() %d,%d %dx%d %d\n", - x, y, w, h, skipleft); + DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d\n", + __func__, x, y, w, h, skipleft)); gc2s.x = x; gc2s.y = y; gc2s.w = w; @@ -952,7 +842,7 @@ GXSubsequentColorExpandScanline(ScrnInfoPtr pScrni, int bufno) { GeodeRec *pGeode = GEODEPTR(pScrni); - DBLOG(3, "GXSubsequentColorExpandScanline() %d\n", bufno); + DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno)); #ifndef OPT_ACCEL { #if GX_ONE_LINE_AT_A_TIME @@ -971,7 +861,7 @@ GXSubsequentColorExpandScanline(ScrnInfoPtr pScrni, int bufno) return; /* convert from bits to dwords */ - srcpitch = ((pGeode->AccelPitch + 31) >> 5) << 2; + srcpitch = ((pGeode->Pitch + 31) >> 5) << 2; gfx2_mono_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(gc2s.x, gc2s.y), gc2s.w, blt_height, pGeode->AccelColorExpandBuffers[0], srcpitch); gc2s.h -= blt_height; @@ -1036,9 +926,8 @@ static void GXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, int fg, int bg, int rop, uint planemask) { - DBLOG(2, - "GXSetupForScreenToScreenColorExpandFill() fg %#x bg %#x " - "rop %#x %#x\n", fg, bg, rop, planemask); + DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n", + __func__, fg, bg, rop, planemask)); rop &= 0x0F; #ifndef OPT_ACCEL { @@ -1047,8 +936,8 @@ GXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, int fg, int bg, gfx_set_solid_pattern(planemask); gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0); gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); - gfx2_set_source_stride(pGeode->AccelPitch); - gfx2_set_destination_stride(pGeode->AccelPitch); + gfx2_set_source_stride(pGeode->Pitch); + gfx2_set_destination_stride(pGeode->Pitch); } #else { @@ -1090,9 +979,8 @@ static void GXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, int x, int y, int w, int h, int srcx, int srcy, int offset) { - DBLOG(2, - "GXSubsequentScreenToScreenColorExpandFill() %d,%d %dx%d %d,%d %d\n", - x, y, w, h, srcx, srcy, offset); + DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d,%d %d\n", + __func__, x, y, w, h, srcx, srcy, offset)); #ifndef OPT_ACCEL gfx2_mono_expand_blt(CALC_FBOFFSET(srcx, srcy), offset, 0, CALC_FBOFFSET(x, y), w, h, 0); @@ -1154,7 +1042,8 @@ static unsigned short vmode[] = { static void GXSetupForSolidLine(ScrnInfoPtr pScrni, int color, int rop, uint planemask) { - DBLOG(2, "GXSetupForSolidLine() %#x %#x %#x\n", color, rop, planemask); + DEBUGMSG(1, (0, X_INFO, "%s() %#x %#x %#x\n", + __func__, color, rop, planemask)); rop &= 0x0F; #ifndef OPT_ACCEL gfx_set_solid_pattern(color); @@ -1205,8 +1094,8 @@ GXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1, { long axial, diagn; - DBLOG(2, "GXSubsequentSolidBresenhamLine() %d,%d %d %d, %d %d, %d\n", - x1, y1, absmaj, absmin, err, len, octant); + DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d, %d %d, %d\n", + __func__, x1, y1, absmaj, absmin, err, len, octant)); if (len <= 0) return; axial = absmin; @@ -1252,8 +1141,8 @@ GXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0, long dx, dy, dmaj, dmin, octant, bias; long axial, diagn, err, len; - DBLOG(2, "GXSubsequentSolidTwoPointLine() %d,%d %d,%d, %#x\n", - x0, y0, x1, y1, flags); + DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d,%d, %#x\n", + __func__, x0, y0, x1, y1, flags)); if ((dx = x1 - x0) < 0) dx = -dx; @@ -1323,7 +1212,8 @@ static void GXSubsequentSolidHorVertLine(ScrnInfoPtr pScrni, int x, int y, int len, int dir) { - DBLOG(2, "GXSubsequentHorVertLine() %d,%d %d %d\n", x, y, len, dir); + DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d\n", + __func__, x, y, len, dir)); #ifndef OPT_ACCEL if (dir == DEGREES_0) gfx_pattern_fill(x, y, len, 1); @@ -1430,8 +1320,9 @@ GXSubsequentDashedBresenhamLine(ScrnInfoPtr pScrni, int trans = (gdln.bg == -1); unsigned long pat8x8[2]; - DEBUGMSG(0, (0, 0, "BLine %d, %d, %d, %d, %d, %d, %d\n", - x1, y1, absmaj, absmin, err, len, octant)); + //ErrorF("BLine %d, %d, %d, %d, %d, %d, %d\n" x1, y1, absmaj, absmin, + //err, len, octant); + i = phase >= 32 ? (phase -= 32, 1) : 0; n = 32 - phase; pat8x8[0] = @@ -1471,8 +1362,8 @@ GXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0, long dx, dy, dmaj, dmin, octant, bias; long axial, diagn, err, len, pat8x8[2]; - DBLOG(2, "GXSubsequentDashedTwoPointLine() %d,%d %d,%d, %#x %d\n", - x0, y0, x1, y1, flags, phase); + //ErrorF("GXSubsequentDashedTwoPointLine() %d,%d %d,%d, %#x %d\n", + // x0, y0, x1, y1, flags, phase); i = phase >= 32 ? (phase -= 32, 1) : 0; n = 32 - phase; @@ -1524,14 +1415,15 @@ GXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h, { GeodeRec *pGeode = GEODEPTR(pScrni); - DBLOG(2, "GXWritePixmap() %d,%d %dx%d, s%#x sp%d %#x %#x %#x %d %d\n", - x, y, w, h, src, srcwidth, rop, planemask, trans, bpp, depth); + //ErrorF("GXWritePixmap() %d,%d %dx%d, s%#x sp%d %#x %#x %#x %d %d\n", + // x, y, w, h, src, srcwidth, rop, planemask, trans, bpp, depth); + if (bpp == pScrni->bitsPerPixel) { rop &= 0x0F; if (rop == GXcopy && trans == -1) { gfx_wait_until_idle(); - amd_memory_to_screen_blt((unsigned long)src, - (unsigned long)FBADDR(x, y), srcwidth, pGeode->AccelPitch, w, + geode_memory_to_screen_blt((unsigned long)src, + (unsigned long)FBADDR(x, y), srcwidth, pGeode->Pitch, w, h, bpp); } else { gfx_set_solid_pattern(planemask); @@ -1552,12 +1444,6 @@ GXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h, #endif /* if GX_WRITE_PIXMAP_SUPPORT */ #if XF86EXA -#define GEODEPTR_FROM_PIXMAP(x) \ - GEODEPTR(xf86Screens[(x)->drawable.pScreen->myNum]) -#define GEODEPTR_FROM_SCREEN(x) \ - GEODEPTR(xf86Screens[(x)->myNum]) -#define GEODEPTR_FROM_PICTURE(x) \ - GEODEPTR(xf86Screens[(x)->pDrawable->pScreen->myNum]) static void amd_gx_exa_WaitMarker(ScreenPtr pScreen, int Marker) @@ -1580,7 +1466,7 @@ amd_gx_exa_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, dst += y * dst_pitch + x * (bpp >> 3); GU2_WAIT_BUSY; - amd_memory_to_screen_blt((unsigned long)src, (unsigned long)dst, + geode_memory_to_screen_blt((unsigned long)src, (unsigned long)dst, src_pitch, dst_pitch, w, h, bpp); return TRUE; } @@ -1595,7 +1481,7 @@ amd_gx_exa_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, src += y * src_pitch + x * (bpp >> 3); GU2_WAIT_BUSY; - amd_memory_to_screen_blt((unsigned long)src, (unsigned long)dst, + geode_memory_to_screen_blt((unsigned long)src, (unsigned long)dst, src_pitch, dst_pitch, w, h, bpp); return TRUE; } @@ -1605,10 +1491,12 @@ amd_gx_exa_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, static Bool amd_gx_exa_PrepareSolid(PixmapPtr pxMap, int alu, Pixel planemask, Pixel fg) { - DBLOG(2, "amd_gx_exa_PrepareSolid(%#x,%#x,%#x)\n", alu, planemask, fg); + int dstPitch = exaGetPixmapPitch(pxMap); unsigned int ROP = BPP | (planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]); + //ErrorF("amd_gx_exa_PrepareSolid(%#x,%#x,%#x)\n", alu, planemask, fg); + BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0; if (((ROP ^ (ROP >> 1)) & 0x55) != 0) BLT_MODE |= MGP_BM_DST_REQ; @@ -1623,12 +1511,13 @@ amd_gx_exa_PrepareSolid(PixmapPtr pxMap, int alu, Pixel planemask, Pixel fg) static void amd_gx_exa_Solid(PixmapPtr pxMap, int x1, int y1, int x2, int y2) { - DBLOG(2, "amd_gx_exa_Solid() at %d,%d %d,%d\n", x1, y1, x2, y2); int bpp = (pxMap->drawable.bitsPerPixel + 7) / 8; int pitch = exaGetPixmapPitch(pxMap); unsigned int offset = exaGetPixmapOffset(pxMap) + pitch * y1 + bpp * x1; unsigned int size = ((x2 - x1) << 16) | (y2 - y1); + //ErrorF("amd_gx_exa_Solid() at %d,%d %d,%d\n", x1, y1, x2, y2); + GU2_WAIT_PENDING; WRITE_GP32(MGP_DST_OFFSET, offset); WRITE_GP32(MGP_WID_HEIGHT, size); @@ -1641,11 +1530,12 @@ static Bool amd_gx_exa_PrepareCopy(PixmapPtr pxSrc, PixmapPtr pxDst, int dx, int dy, int alu, Pixel planemask) { - DBLOG(2, "amd_gx_exa_PrepareCopy() dx%d dy%d alu %#x %#x\n", - dx, dy, alu, planemask); GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); int dstPitch = exaGetPixmapPitch(pxDst); + //ErrorF("amd_gx_exa_PrepareCopy() dx%d dy%d alu %#x %#x\n", + // dx, dy, alu, planemask); + pGeode->cpySrcOffset = exaGetPixmapOffset(pxSrc); pGeode->cpySrcPitch = exaGetPixmapPitch(pxSrc); pGeode->cpySrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8; @@ -1668,8 +1558,6 @@ static void amd_gx_exa_Copy(PixmapPtr pxDst, int srcX, int srcY, int dstX, int dstY, int w, int h) { - DBLOG(2, "amd_gx_exa_Copy() from %d,%d to %d,%d %dx%d\n", srcX, srcY, - dstX, dstY, w, h); GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); int dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8; int dstPitch = exaGetPixmapPitch(pxDst); @@ -1681,6 +1569,9 @@ amd_gx_exa_Copy(PixmapPtr pxDst, int srcX, int srcY, int dstX, int dstY, unsigned int size = (w << 16) | h; unsigned int blt_mode = BLT_MODE; + //ErrorF("amd_gx_exa_Copy() from %d,%d to %d,%d %dx%d\n", srcX, srcY, + // dstX, dstY, w, h); + if (pGeode->cpyDx < 0) { srcOffset += w * pGeode->cpySrcBpp - 1; dstOffset += w * dstBpp - 1; @@ -1744,57 +1635,6 @@ unsigned int amd_gx_exa_alpha_ops[] = (SRC_DST | A1_B1a | a_C), 0, /* add (src*1 + dst*1) */ }; -#define usesPasses(op) ((( \ - ( 1 << PictOpAtop ) | \ - ( 1 << PictOpAtopReverse ) | \ - ( 1 << PictOpXor ) | \ - 0 ) >> (op)) & 1) - -/* pass1 or pass2 */ -#define usesSrcAlpha(op) ((( \ - ( 1 << PictOpOver ) | \ - ( 1 << PictOpInReverse ) | \ - ( 1 << PictOpOutReverse ) | \ - ( 1 << PictOpAtop ) | \ - ( 1 << PictOpAtopReverse ) | \ - ( 1 << PictOpXor ) | \ - 0 ) >> (op)) & 1) - -/* pass1 or pass2 */ -#define usesDstAlpha(op) ((( \ - ( 1 << PictOpOverReverse ) | \ - ( 1 << PictOpIn ) | \ - ( 1 << PictOpOut ) | \ - ( 1 << PictOpAtop ) | \ - ( 1 << PictOpAtopReverse ) | \ - ( 1 << PictOpXor ) | \ - 0 ) >> (op)) & 1) - -/* non 2 pass ops */ -#define usesChanB0(op) ((( \ - ( 1 << PictOpOver ) | \ - ( 1 << PictOpOverReverse ) | \ - ( 1 << PictOpIn ) | \ - ( 1 << PictOpInReverse ) | \ - ( 1 << PictOpOut ) | \ - ( 1 << PictOpOutReverse ) | \ - ( 1 << PictOpAdd ) | \ - 0 ) >> (op)) & 1) - -/* pass 1 ops */ -#define usesChanB1(op) ((( \ - ( 1 << PictOpAtop ) | \ - ( 1 << PictOpAtopReverse ) | \ - ( 1 << PictOpXor ) | \ - 0 ) >> (op)) & 1) - -/* pass 2 ops */ -#define usesChanB2(op) ((( \ - ( 1 << PictOpAtop ) | \ - ( 1 << PictOpAtopReverse ) | \ - ( 1 << PictOpXor ) | \ - 0 ) >> (op)) & 1) - typedef struct { int exa_fmt; @@ -1837,7 +1677,6 @@ static Bool amd_gx_exa_CheckComposite(int op, PicturePtr pSrc, PicturePtr pMsk, PicturePtr pDst) { - amd_gx_exa_fmt_t *sfp, *dfp; GeodeRec *pGeode = GEODEPTR_FROM_PICTURE(pDst); if (op > gxPictOpMAX) @@ -1863,10 +1702,11 @@ amd_gx_exa_PrepareComposite(int op, PicturePtr pSrc, PicturePtr pMsk, { int srcPitch; - DBLOG(2, "amd_gx_exa_PrepareComposite()\n"); GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); amd_gx_exa_fmt_t *sfp, *dfp; + //ErrorF("amd_gx_exa_PrepareComposite()\n"); + if ((sfp = amd_gx_exa_check_format(pSrc)) == NULL) return FALSE; if (sfp->alpha_bits == 0 && usesSrcAlpha(op)) @@ -1897,11 +1737,11 @@ amd_gx_exa_Composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, int op, current_line, max_lines, lines, pass, scratchPitch; unsigned int srcOffset, srcOfs, srcPitch, srcPch, srcBpp; unsigned int dstOffset, dstOfs, dstPitch, dstPch, dstBpp; - unsigned int sizes, strides, blt_mode, rop, pitch; + unsigned int sizes, strides, blt_mode, rop; GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); - DBLOG(2, "amd_gx_exa_Composite() from %d,%d to %d,%d %dx%d\n", - srcX, srcY, dstX, dstY, width, height); + //ErrorF("amd_gx_exa_Composite() from %d,%d to %d,%d %dx%d\n", + // srcX, srcY, dstX, dstY, width, height); op = pGeode->cmpOp; if (usesPasses(op)) { @@ -2030,9 +1870,12 @@ GXAccelInit(ScreenPtr pScrn) #endif gu2_xshift = pScrni->bitsPerPixel >> 4; - gu2_pitch = pGeode->AccelPitch; - switch (pGeode->AccelPitch) { + /* XXX - fixme - this will change - we'll need to update it */ + + gu2_pitch = pGeode->Pitch; + + switch (pGeode->Pitch) { case 1024: gu2_yshift = 10; break; @@ -2049,7 +1892,7 @@ GXAccelInit(ScreenPtr pScrn) #ifdef OPT_ACCEL - ACCEL_STRIDE = (pGeode->AccelPitch << 16) | pGeode->AccelPitch; + ACCEL_STRIDE = (pGeode->Pitch << 16) | pGeode->Pitch; switch (pScrni->bitsPerPixel) { case 16: BPP = MGP_RM_BPPFMT_565; @@ -2065,9 +1908,6 @@ GXAccelInit(ScreenPtr pScrn) #if XF86EXA if (pExa && pGeode->useEXA) { - - xf86DrvMsg(pScrni->scrnIndex, X_INFO, "Init EXA\n"); - pExa->exa_major = EXA_VERSION_MAJOR; pExa->exa_minor = EXA_VERSION_MINOR; diff --git a/src/amd_gx_cursor.c b/src/amd_gx_cursor.c index 3630482..b87d28d 100644 --- a/src/amd_gx_cursor.c +++ b/src/amd_gx_cursor.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2003-2005 Advanced Micro Devices, Inc. +/* Copyright (c) 2003-2006 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -42,12 +42,8 @@ #include "amd.h" /* Forward declarations of the functions */ -Bool GXHWCursorInit(ScreenPtr pScrn); static void GXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg); static void GXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y); -void GXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src); -void GXHideCursor(ScrnInfoPtr pScrni); -void GXShowCursor(ScrnInfoPtr pScrni); static Bool GXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs); extern void GXSetVideoPosition(int x, int y, int width, int height, short src_w, short src_h, short drw_w, @@ -140,11 +136,42 @@ GXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y) { static unsigned long panOffset = 0; GeodeRec *pGeode = GEODEPTR(pScrni); + int savex, savey; int newX, newY; - (*pGeode->Rotation) (x, y, pGeode->HDisplay, pGeode->VDisplay, &newX, - &newY); - (*pGeode->RBltXlat) (newX, newY, 32, 32, &newX, &newY); + /* Adjust xf86HWCursor messing about */ + + savex = x + pScrni->frameX0; + savey = y + pScrni->frameY0; + + switch(pGeode->rotation) { + default: + ErrorF("%s:%d invalid rotation %d\n", __func__, __LINE__, pGeode->rotation); + case RR_Rotate_0: + newX = savex; newY = savey; + break; + + case RR_Rotate_90: + newX = savey; + newY = pScrni->pScreen->width - savex; + break; + + case RR_Rotate_180: + newX = pScrni->pScreen->width - savex; + newY = pScrni->pScreen->height - savey; + break; + + case RR_Rotate_270: + newX = pScrni->pScreen->height - savey; + newY = savex; + break; + } + + newX += pScrni->frameX0; + newY += pScrni->frameY0; + + //ErrorF("Turned (%d,%d) into (%d,%d)\n", x,y,newX, newY); + if (newX < -31) newX = -31; if (newY < -31) @@ -204,7 +231,29 @@ GXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src) ++rowp; ++mskp; } - (*pGeode->Rotation) (x, y, 32, 32, &newX, &newY); + + switch(pGeode->rotation) { + default: + ErrorF("%s:%d invalid rotation %d\n", __func__, __LINE__, + pGeode->rotation); + case RR_Rotate_0: + newX = x; + newY = y; + break; + case RR_Rotate_90: + newX = y; + newY = 31 - x; + break; + case RR_Rotate_180: + newX = 31 - x; + newY = 31 - y; + break; + case RR_Rotate_270: + newX = 31 - y; + newY = x; + break; + } + i = 7 - i; n = 31 - newX; andMask[newY] |= (((mskb >> i) & 1) << n); @@ -281,10 +330,7 @@ static Bool GXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs) { ScrnInfoPtr pScrni = XF86SCRNINFO(pScrn); + GeodeRec *pGeode = GEODEPTR(pScrni); - if (pScrni->currentMode->Flags & V_DBLSCAN) - return FALSE; - return TRUE; + return pGeode->HWCursor; } - -/* End of File */ diff --git a/src/amd_gx_dcon.c b/src/amd_gx_dcon.c index 034f835..a3c5b2c 100644 --- a/src/amd_gx_dcon.c +++ b/src/amd_gx_dcon.c @@ -57,100 +57,122 @@ extern unsigned long gfx_gamma_ram_redcloud[]; embedded controller */ -static int eccmd(ScrnInfoPtr pScrni, unsigned char cmd) { - - unsigned char ret; - int i; - - ret = inb(0x6c); - - if (ret & 1) - ret = inb(0x68); - - /* Write the command */ - outb(0x6C, cmd); - - /* Wait for the 2 response */ - for(i = 0; i < 1000; i++) { - ret = inb(0x6C); - if ((ret & 3) == 1) - break; - } - - if (i == 100) { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "Error waiting for the EC command (%x)\n", ret); - ret = -1; - goto eread; - } +static int +eccmd(ScrnInfoPtr pScrni, unsigned char cmd) +{ + + unsigned char ret; + int i; - /* get the response */ + ret = inb(0x6c); + + if (ret & 1) ret = inb(0x68); - eread: - /* Clear the "ownership flag" */ - outb(0x6C, 0xFF); - return ret; + /* Write the command */ + outb(0x6C, cmd); + + /* Wait for the 2 response */ + for (i = 0; i < 1000; i++) { + ret = inb(0x6C); + if ((ret & 3) == 1) + break; + } + + if (i == 100) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Error waiting for the EC command (%x)\n", ret); + ret = -1; + goto eread; + } + + /* get the response */ + ret = inb(0x68); + + eread: + /* Clear the "ownership flag" */ + outb(0x6C, 0xFF); + return ret; } -static int boardrev(ScrnInfoPtr pScrni) { - int i, ret; +static int +boardrev(ScrnInfoPtr pScrni) +{ + int ret; - ret = eccmd(pScrni, 0x09); + ret = eccmd(pScrni, 0x09); - if (ret == -1) - return -1; + if (ret == -1) + return -1; - return ret == TESTA_REVISION ? REV_TESTA : REV_TESTB; + return ret == TESTA_REVISION ? REV_TESTA : REV_TESTB; } #define RTC_BASE_PORT 0x70 #define RTC_PORT(x) (RTC_BASE_PORT + (x)) -static inline char cmos_read(unsigned char addr) { - outb(RTC_PORT(0), addr); - return inb(RTC_PORT(1)); +static inline char +cmos_read(unsigned char addr) +{ + outb(RTC_PORT(0), addr); + return inb(RTC_PORT(1)); } -static inline void cmos_write(unsigned char val, unsigned char addr) { - outb(RTC_PORT(0), addr); - outb(RTC_PORT(1), val); -} - -static int dcon_avail(void) { - return cmos_read(440 / 8) & 1; +static inline void +cmos_write(unsigned char val, unsigned char addr) +{ + outb(RTC_PORT(0), addr); + outb(RTC_PORT(1), val); } -void gx_dcon_init(ScrnInfoPtr pScrni) { - - int rev = boardrev(pScrni); - int i; +static int +dcon_avail(void) +{ + return cmos_read(440 / 8) & 1; +} - if (rev == -1) { - xf86DrvMsg(pScrni->scrnIndex, X_DEFAULT, "This is not an OLPC board\n"); - return; - } - if (dcon_avail() == 0) { - xf86DrvMsg(pScrni->scrnIndex, X_DEFAULT, "No DCON is present\n"); - return; +Bool +gx_dcon_init(ScrnInfoPtr pScrni) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + int rev = boardrev(pScrni); + int i; + + if (rev == -1) { + xf86DrvMsg(pScrni->scrnIndex, X_DEFAULT, + "This is not an OLPC board\n"); + return FALSE; + } + if (dcon_avail() == 0) { + xf86DrvMsg(pScrni->scrnIndex, X_DEFAULT, "No DCON is present\n"); + return FALSE; + } + + xf86DrvMsg(pScrni->scrnIndex, X_DEFAULT, "OLPC board revision %s\n", + rev == REV_TESTB ? "testB" : "testA"); + xf86DrvMsg(pScrni->scrnIndex, X_DEFAULT, "DCON detected.\n"); + + /* Panel size setup */ + pGeode->PanelX = DCON_DEFAULT_XRES; + pGeode->PanelY = DCON_DEFAULT_YRES; + + /* FIXME: Mode setup should go here */ + /* FIXME: Controller setup should go here */ + + /* Update the Xv map on a rev-b board */ + + if (rev == REV_TESTB) { + for (i = 0; i < 256; i++) { + unsigned char r, g, b; + + r = (gfx_gamma_ram_redcloud[i] >> 16) & 0xFF; + g = (gfx_gamma_ram_redcloud[i] >> 8) & 0xFF; + b = gfx_gamma_ram_redcloud[i] & 0xFF; + + gfx_gamma_ram_redcloud[i] = + ((r >> 2) << 16) | ((g >> 1) << 8) | (b >> 2); } + } - xf86DrvMsg(pScrni->scrnIndex, X_DEFAULT, "OLPC board revision %s\n", rev == REV_TESTB ? "testB" : "testA"); - xf86DrvMsg(pScrni->scrnIndex, X_DEFAULT, "DCON detected.\n"); - - /* FIXME: Panel setup should go here */ - /* FIXME: Mode setup should go here */ - /* FIXME: Controller setup should go here */ - - /* Update the Xv map on a rev-b board */ - - if (rev == REV_TESTB) { - for(i = 0; i < 256; i++) { - unsigned char r, g, b; - r = (gfx_gamma_ram_redcloud[i] >> 16) & 0xFF; - g = (gfx_gamma_ram_redcloud[i] >> 8) & 0xFF; - b = gfx_gamma_ram_redcloud[i] & 0xFF; - - gfx_gamma_ram_redcloud[i] = ((r >> 2) << 16) | ((g >> 1) << 8) | (b >> 2); - } - } + return TRUE; } diff --git a/src/amd_gx_dga.c b/src/amd_gx_dga.c deleted file mode 100644 index 2212962..0000000 --- a/src/amd_gx_dga.c +++ /dev/null @@ -1,393 +0,0 @@ -/* Copyright (c) 2003-2005 Advanced Micro Devices, Inc. - * - * 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, - * 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. - * - * Neither the name of the Advanced Micro Devices, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * */ - -/* - * File contents: DGA(Direct Acess Graphics mode) is feature of XFree86 that - * allows the program to access directly to video memory on - * the graphics card.DGA supports the double flickering. This - * file has the functions to support the DGA modes. - * - * Project: Geode Xfree Frame buffer device driver. - * */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86.h" -#include "xf86_OSproc.h" -#include "xf86_ansic.h" -#include "xf86Pci.h" -#include "xf86PciInfo.h" -#include "xaa.h" -#include "xaalocal.h" -#include "amd.h" -#include "dgaproc.h" - -/* forward declarations */ -Bool GXDGAInit(ScreenPtr pScrn); -static Bool GX_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, - int *, int *, int *); -static void GX_CloseFramebuffer(ScrnInfoPtr pScrn); -static Bool GX_SetMode(ScrnInfoPtr, DGAModePtr); -static int GX_GetViewport(ScrnInfoPtr); -static void GX_SetViewport(ScrnInfoPtr, int, int, int); -static void GX_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); -static void GX_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); - -extern void GXAdjustFrame(int, int, int, int); -extern Bool GXSwitchMode(int, DisplayModePtr, int); -extern void GXAccelSync(ScrnInfoPtr pScrni); - -static DGAFunctionRec GXDGAFuncs = { - GX_OpenFramebuffer, - GX_CloseFramebuffer, - GX_SetMode, - GX_SetViewport, - GX_GetViewport, - GXAccelSync, - GX_FillRect, - GX_BlitRect, - NULL -}; - -/*---------------------------------------------------------------------------- - * GXDGAInit. - * - * Description :This function is used to intiallize the DGA modes and sets - * the viewport based on the screen mode. - * - * Parameters. - * pScreeen :Pointer to screen info structure. - * - * Returns :TRUE on success and FALSE on failure. - * - * Comments :This function prepares the DGA mode settings for - * other func reference. - * - *---------------------------------------------------------------------------- - */ - -Bool -GXDGAInit(ScreenPtr pScrn) -{ - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - GeodeRec *pGeode = GEODEPTR(pScrni); - DGAModePtr modes = NULL, newmodes = NULL, currentMode; - DisplayModePtr pMode, firstMode; - int Bpp = pScrni->bitsPerPixel >> 3; - int num = 0; - Bool oneMore; - - pMode = firstMode = pScrni->modes; - DEBUGMSG(0, (0, X_NONE, "GXDGAInit %d\n", Bpp)); - while (pMode) { - /* one record is allocated here */ - newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); - oneMore = FALSE; - if (!newmodes) { - xfree(modes); - return FALSE; - } - - modes = newmodes; - - SECOND_PASS: /* DGA mode flgas and viewport parametrs are set here. */ - currentMode = modes + num; - num++; - currentMode->mode = pMode; - currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; - currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; - if (pMode->Flags & V_DBLSCAN) - currentMode->flags |= DGA_DOUBLESCAN; - if (pMode->Flags & V_INTERLACE) - currentMode->flags |= DGA_INTERLACED; - currentMode->byteOrder = pScrni->imageByteOrder; - currentMode->depth = pScrni->depth; - currentMode->bitsPerPixel = pScrni->bitsPerPixel; - currentMode->red_mask = pScrni->mask.red; - currentMode->green_mask = pScrni->mask.green; - currentMode->blue_mask = pScrni->mask.blue; - currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; - currentMode->viewportWidth = pMode->HDisplay; - currentMode->viewportHeight = pMode->VDisplay; - currentMode->xViewportStep = 1; - currentMode->yViewportStep = 1; - currentMode->viewportFlags = DGA_FLIP_RETRACE; - currentMode->offset = 0; - currentMode->address = pGeode->FBBase; - if (oneMore) { /* first one is narrow width */ - currentMode->bytesPerScanline = - ((pMode->HDisplay * Bpp) + 3) & ~3L; - currentMode->imageWidth = pMode->HDisplay; - currentMode->imageHeight = pMode->VDisplay; - currentMode->pixmapWidth = currentMode->imageWidth; - currentMode->pixmapHeight = currentMode->imageHeight; - currentMode->maxViewportX = currentMode->imageWidth - - currentMode->viewportWidth; - /* this might need to get clamped to some maximum */ - currentMode->maxViewportY = currentMode->imageHeight - - currentMode->viewportHeight; - oneMore = FALSE; - goto SECOND_PASS; - } else { - currentMode->bytesPerScanline = - ((pScrni->displayWidth * Bpp) + 3) & ~3L; - currentMode->imageWidth = pScrni->displayWidth; - currentMode->imageHeight = pMode->VDisplay; - currentMode->pixmapWidth = currentMode->imageWidth; - currentMode->pixmapHeight = currentMode->imageHeight; - currentMode->maxViewportX = currentMode->imageWidth - - currentMode->viewportWidth; - /* this might need to get clamped to some maximum */ - currentMode->maxViewportY = currentMode->imageHeight - - currentMode->viewportHeight; - } - - pMode = pMode->next; - if (pMode == firstMode) - break; - } - pGeode->numDGAModes = num; - pGeode->DGAModes = modes; - return DGAInit(pScrn, &GXDGAFuncs, modes, num); -} - -/*---------------------------------------------------------------------------- - * GX_SetMode. - * - * Description :This function is sets into the DGA mode. - *. - * Parameters. - * pScreeen :Pointer to screen info structure. - * pMode :Points to the DGAmode ptr data - * - * Returns :TRUE on success and FALSE on failure. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ -static Bool -GX_SetMode(ScrnInfoPtr pScrni, DGAModePtr pMode) -{ - static int OldDisplayWidth[MAXSCREENS]; - int index = pScrni->pScreen->myNum; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DEBUGMSG(0, (0, X_NONE, "GX_SetMode\n")); - - if (!pMode) { - /* restore the original mode put the ScreenParameters back - */ - pScrni->displayWidth = OldDisplayWidth[index]; - DEBUGMSG(0, - (0, X_NONE, "GX_SetMode !pMode %d\n", pScrni->displayWidth)); - GXSwitchMode(index, pScrni->currentMode, 0); - pGeode->DGAactive = FALSE; - } else { - if (!pGeode->DGAactive) { /* save the old parameters */ - OldDisplayWidth[index] = pScrni->displayWidth; - pGeode->DGAactive = TRUE; - DEBUGMSG(0, - (0, X_NONE, "GX_SetMode pMode+ NA %d\n", - pScrni->displayWidth)); - } -#if defined(STB_X) - Gal_get_display_offset(&pGeode->PrevDisplayOffset); -#else - pGeode->PrevDisplayOffset = gfx_get_display_offset(); -#endif - pScrni->displayWidth = pMode->bytesPerScanline / - (pMode->bitsPerPixel >> 3); - DEBUGMSG(0, - (0, X_NONE, "GX_SetMode pMode+ %d\n", pScrni->displayWidth)); - GXSwitchMode(index, pMode->mode, 0); - } - /* enable/disable Compression */ - if (pGeode->Compression) { - GFX(set_compression_enable(!pGeode->DGAactive)); - } - - /* enable/disable cursor */ - if (pGeode->HWCursor) { - GFX(set_cursor_enable(!pGeode->DGAactive)); - } - - return TRUE; -} - -/*---------------------------------------------------------------------------- - * GX_GetViewPort. - * - * Description :This function is Gets the viewport window memory. - *. - * Parameters. - * pScrni :Pointer to screen info structure. - * - * Returns :returns the viewport status. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ -static int -GX_GetViewport(ScrnInfoPtr pScrni) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - return pGeode->DGAViewportStatus; -} - -/*---------------------------------------------------------------------------- - * GX_SetViewPort. - * - * Description :This function is Gets the viewport window memory. - * - * Parameters. - * pScrn :Pointer to screen info structure. - x :x-cordinate of viewport window - * y :y-codinate of the viewport window. - * flags :indicates the viewport to be flipped or not. - * - * Returns :returns the viewport status as zero. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ -static void -GX_SetViewport(ScrnInfoPtr pScrni, int x, int y, int flags) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - GXAdjustFrame(pScrni->pScreen->myNum, x, y, flags); - pGeode->DGAViewportStatus = 0; /*GXAdjustFrame loops until finished */ -} - -/*---------------------------------------------------------------------------- - * GX_FillRect. - * - * Description :This function is Gets the viewport window memory. - *. - * Parameters. - * pScrn :Pointer to screen info structure. - * x :x-cordinate of viewport window - * y :y-codinate of the viewport window. - * w :width of the rectangle - * h :height of the rectangle. - * color :color to be filled in rectangle. - * - * Returns :returns the viewport status as zero. - * - * Comments :This function is implemented by solidfill routines.. - *---------------------------------------------------------------------------- - */ -static void -GX_FillRect(ScrnInfoPtr pScrn, int x, int y, - int w, int h, unsigned long color) -{ - GeodeRec *pGeode = GEODEPTR(pScrn); - - if (pGeode->AccelInfoRec) { - (*pGeode->AccelInfoRec->SetupForSolidFill) (pScrn, color, GXcopy, ~0); - (*pGeode->AccelInfoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h); - SET_SYNC_FLAG(pGeode->AccelInfoRec); - } -} - -/*---------------------------------------------------------------------------- - * GX_BlitRect. - * - * Description :This function implementing Blit and it moves a - * Rectangular block of data from one location to other - * Location. - * - * Parameters. - * pScrni :Pointer to screen info structure. - * srcx :x-cordinate of the src rectangle - * srcy :y-codinate of src rectangle. - * w :width of the rectangle - * h :height of the rectangle. - * dstx :x-cordinate of the dst rectangle. - * dsty :y -coordinates of the dst rectangle. - * Returns :none. - * - * Comments :none - *---------------------------------------------------------------------------- - */ -static void -GX_BlitRect(ScrnInfoPtr pScrni, - int srcx, int srcy, int w, int h, int dstx, int dsty) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - if (pGeode->AccelInfoRec) { - int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; - int ydir = (srcy < dsty) ? -1 : 1; - - (*pGeode->AccelInfoRec->SetupForScreenToScreenCopy) - (pScrni, xdir, ydir, GXcopy, ~0, -1); - (*pGeode->AccelInfoRec->SubsequentScreenToScreenCopy) (pScrni, srcx, - srcy, dstx, dsty, w, h); - SET_SYNC_FLAG(pGeode->AccelInfoRec); - } -} - -/*---------------------------------------------------------------------------- - * GX_OpenFramebuffer. - * - * Description :This function open the framebuffer driver for DGA. - * - * Parameters. - * pScrni :Pointer to screen info structure. - * srcx :x-cordinate of the src rectangle - * srcy :y-codinate of src rectangle. - * w :width of the rectangle - * h :height of the rectangle. - * dstx :x-cordinate of the dst rectangle. - * dsty :y -coordinates of the dst rectangle. - * Returns :none. - * - * Comments :none - *---------------------------------------------------------------------------- - */ -static Bool -GX_OpenFramebuffer(ScrnInfoPtr pScrni, - char **name, unsigned char **mem, int *size, int *offset, int *flags) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - *name = NULL; /* no special device */ - *mem = (unsigned char *)pGeode->FBLinearAddr; - *size = pGeode->FBSize; - *offset = 0; - *flags = DGA_NEED_ROOT; - return TRUE; -} - -static void -GX_CloseFramebuffer(ScrnInfoPtr pScrni) -{ -} - -/* end of file */ diff --git a/src/amd_gx_driver.c b/src/amd_gx_driver.c index 5fc19f1..922dbb5 100644 --- a/src/amd_gx_driver.c +++ b/src/amd_gx_driver.c @@ -1,5 +1,9 @@ -/* Copyright (c) 2003-2005 Advanced Micro Devices, Inc. +/* Copyright (c) 2003-2006 Advanced Micro Devices, Inc. * + * Portioned modeled from xf86-video-intel/src/i830_driver.c + * Copyright 2001 VA Linux Systems Inc., Fremont, California. + * Copyright \ufffd 2002 by David Dawes + * 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 @@ -21,2540 +25,1555 @@ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. - * */ - -/* - * File Contents: This is the main module configures the interfacing with - * the X server. The individual modules will be loaded based - * upon the options selected from the XF86Config. This file - * also has modules for finding supported modes, turning on - * the modes based on options. - * - * Project: Geode Xfree Frame buffer device driver. - * */ + */ #ifdef HAVE_CONFIG_H #include "config.h" #endif -/* Includes that are used by all drivers */ +#include <stdio.h> + #include "xf86.h" #include "xf86_OSproc.h" -#include "xf86_ansic.h" -#include "xf86_libc.h" #include "xf86Resources.h" - -/* We may want inb() and outb() */ -#include "compiler.h" - -/* We may want to access the PCI config space */ -#include "xf86PciInfo.h" -#include "xf86Pci.h" - -/* Colormap handling stuff */ #include "xf86cmap.h" - -#define RC_MAX_DEPTH 24 +#include "compiler.h" +#include "mipointer.h" +#include "shadow.h" +#include <X11/extensions/randr.h> +#include "fb.h" +#include "miscstruct.h" +#include "micmap.h" +#include "vbe.h" +#include "fb.h" +#include "randrstr.h" #include "amd.h" #include "gfx_defs.h" #include "gfx_regs.h" #include "panel.h" -/* Frame buffer stuff */ -#if CFB -/* - * If using cfb, cfb.h is required. Select the others for the bpp values - * the driver supports. - */ -#define PSZ 8 /* needed for cfb.h */ -#include "cfb.h" -#undef PSZ -#include "cfb16.h" -#include "cfb24.h" -#include "cfb32.h" -#else -#include "fb.h" -#endif - -#include "shadowfb.h" - -/* Machine independent stuff */ -#include "mipointer.h" -#include "mibank.h" -#include "micmap.h" -/* All drivers implementing backing store need this */ -#include "mibstore.h" -#include "vgaHW.h" -#include "vbe.h" - -/* Check for some extensions */ -#ifdef XFreeXDGA -#define _XF86_DGA_SERVER_ -#include <X11/extensions/xf86dgastr.h> -#endif /* XFreeXDGA */ - -#ifdef DPMSExtension -#include "globals.h" -#include "opaque.h" -#define DPMS_SERVER -#include <X11/extensions/dpms.h> -#endif /* DPMSExtension */ - +/* Bring in VGA functions */ #include "amd_gx_vga.c" -extern SymTabRec GeodeChipsets[]; -extern OptionInfoRec GX_GeodeOptions[]; - -/* Forward definitions */ -static Bool GXPreInit(ScrnInfoPtr, int); -static Bool GXScreenInit(int, ScreenPtr, int, char **); -static Bool GXEnterVT(int, int); -static void GXLeaveVT(int, int); -static void GXFreeScreen(int, int); -void GXAdjustFrame(int, int, int, int); -Bool GXSwitchMode(int, DisplayModePtr, int); -static int GXValidMode(int, DisplayModePtr, Bool, int); -static void GXLoadPalette(ScrnInfoPtr pScrni, - int numColors, int *indizes, LOCO * colors, VisualPtr pVisual); -static Bool GXMapMem(ScrnInfoPtr); -static Bool GXUnmapMem(ScrnInfoPtr); -static void gx_set_DvLineSize(unsigned int pitch); - -extern Bool GXAccelInit(ScreenPtr pScrn); -extern Bool GXHWCursorInit(ScreenPtr pScrn); -extern void GXHideCursor(ScrnInfoPtr pScrni); -extern void GXShowCursor(ScrnInfoPtr pScrni); -extern void GXPointerMoved(int index, int x, int y); -extern void GXRotationInit(ScrnInfoPtr pScrni); -extern void GXShadowFBInit(ScreenPtr pScrn, GeodeRec *pGeode, int bytpp); -extern void GXInitVideo(ScreenPtr pScrn); -extern Bool GXDGAInit(ScreenPtr pScrn); -extern void GXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src); +#define GX_MIN_PITCH 1024 +#define GX_MAX_PITCH 8192 +#define GX_MAX_WIDTH 1600 +#define GX_MIN_HEIGHT 400 +#define GX_MAX_HEIGHT 1200 +#define GX_CB_PITCH 544 +#define GX_CB_SIZE 544 -unsigned char *XpressROMPtr; -unsigned long fb; +#define GX_CPU_REG_SIZE 0x4000 +#define GX_GP_REG_SIZE 0x4000 +#define GX_VID_REG_SIZE 0x4000 -/* Existing Processor Models */ -#define GX1 0x1 -#define GX 0x2 -#define GX_CRT 0x6 -#define GX_TFT 0xA +extern OptionInfoRec GX_GeodeOptions[]; -/* List of symbols from other modules that this module references.The purpose - * is that to avoid unresolved symbol warnings - */ extern const char *amdVgahwSymbols[]; extern const char *amdVbeSymbols[]; extern const char *amdInt10Symbols[]; - -#if CFB -extern const char *amdCfbSymbols[]; -#else extern const char *amdFbSymbols[]; -#endif extern const char *amdXaaSymbols[]; extern const char *amdExaSymbols[]; extern const char *amdRamdacSymbols[]; -extern const char *amdShadowSymbols[]; - -void GXSetupChipsetFPtr(ScrnInfoPtr pScrn); -GeodeRec *GXGetRec(ScrnInfoPtr pScrni); -void get_flatpanel_info(const char *options, int *W, int *H, - int *D, int *C, int *T); -void gx_clear_screen(ScrnInfoPtr pScrni, int width, int height, int bpp); -void gx_enable_dac_power(ScrnInfoPtr pScrni); -void gx_disable_dac_power(ScrnInfoPtr pScrni); - -#if DEBUGLVL>0 -FILE *zdfp = NULL; -#endif -void -GXSetupChipsetFPtr(ScrnInfoPtr pScrn) -{ -#if DEBUGLVL>0 - if (zdfp == NULL) { - zdfp = fopen("/tmp/xwin.log", "w"); -#if DEBUGTIM==0 - setbuf(zdfp, NULL); -#endif - } -#endif - DEBUGMSG(1, (0, X_INFO, "GXSetupChipsetFPtr!\n")); - pScrn->PreInit = GXPreInit; - pScrn->ScreenInit = GXScreenInit; - pScrn->SwitchMode = GXSwitchMode; - pScrn->AdjustFrame = GXAdjustFrame; - pScrn->EnterVT = GXEnterVT; - pScrn->LeaveVT = GXLeaveVT; - pScrn->FreeScreen = GXFreeScreen; - pScrn->ValidMode = GXValidMode; -} +unsigned char *XpressROMPtr; -/*---------------------------------------------------------------------------- - * GXGetRec. - * - * Description :This function allocates a GeodeRec and hooks into pScrni - * struct's driverPrivate member of ScreeenInfo structure. - * - * Parameters. - * pScrni :Pointer handle to the screenonfo structure. - * - * Returns :allocated pScrninfo structure. - * - * Comments :none - * - *---------------------------------------------------------------------------- - */ -GeodeRec * -GXGetRec(ScrnInfoPtr pScrni) +static inline void +gx_enable_dac_power(void) { - if (!pScrni->driverPrivate) { - GeodeRec *pGeode; - - pGeode = pScrni->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1); -#if INT10_SUPPORT - pGeode->vesa = xcalloc(sizeof(VESARec), 1); -#endif - } - return GEODEPTR(pScrni); + gfx_write_vid32(RCDF_VID_MISC, + gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH); } -/*---------------------------------------------------------------------------- - * GXFreeRec. - * - * Description :This function deallocates and disconnect the GeodeRec from - * the pScrni struct's driverPrivate member. - * - * Parameters. - * pScrni :Pointer handle to the screenonfo structure. - * - * Returns :none - * - * Comments :none - * - *---------------------------------------------------------------------------- - */ -static void -GXFreeRec(ScrnInfoPtr pScrni) +static inline void +gx_disable_dac_power(void) { - if (pScrni->driverPrivate == NULL) { - return; - } - xfree(pScrni->driverPrivate); - pScrni->driverPrivate = NULL; + gfx_write_vid32(RCDF_VID_MISC, + RCDF_DAC_POWER_DOWN | RCDF_ANALOG_POWER_DOWN | + (gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH)); } -/*---------------------------------------------------------------------------- - * GXSaveScreen. - * - * Description :This is todo the screen blanking - * - * Parameters. - * pScrn :Handle to ScreenPtr structure. - * mode :mode is used by vgaHWSaveScren to check blnak os on. - * - * Returns :TRUE on success and FALSE on failure. - * - * Comments :none - *---------------------------------------------------------------------------- - */ -static Bool -GXSaveScreen(ScreenPtr pScrn, int mode) -{ - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - GeodePtr pGeode = GEODEPTR(pScrni); - if (pGeode->useVGA && !pScrni->vtSema) - return vgaHWSaveScreen(pScrn, mode); - return TRUE; -} -/*---------------------------------------------------------------------------- - * get_flatpanel_info. - * - * Description: This gets the parameter values of the flatpanel attached. - * - * Parameters: - * options: Pointer to the display options. - * W: Pointer to the width of the panel - * H: Pointer to the height of the panel - * D: Pointer to the depth of the panel. - * C: Pointer to the color of the panel. - * T: Pointer to the type of the panel. - * - * Returns: none. - * - * Comments: none - *------------------------------------------------------------------------ - */ -void -get_flatpanel_info(const char *options, int *W, int *H, - int *D, int *C, int *T) -{ - char *pnl_opt; - - pnl_opt = strtok((char *)options, ":"); - *W = strtoul(pnl_opt, NULL, 0); - pnl_opt = strtok(NULL, ":"); - *H = strtoul(pnl_opt, NULL, 0); - pnl_opt = strtok(NULL, ":"); - *D = strtoul(pnl_opt, NULL, 0); - pnl_opt = strtok(NULL, ":"); - *C = strtoul(pnl_opt, NULL, 0); - pnl_opt = strtok(NULL, ":"); - *T = strtoul(pnl_opt, NULL, 0); - - *C = (*C) ? PNL_COLOR_PANEL : PNL_MONO_PANEL; - - switch (*T) { - case 0: - *T = PNL_SSTN; - break; - case 1: - *T = PNL_DSTN; - break; - case 2: - default: - *T = PNL_TFT; - break; - } - if ((*W != 640) && (*W != 800) && (*W != 1024)) - *W = 640; +static void +GXInitEXAMemory(ScrnInfoPtr pScrni, unsigned int *offset, unsigned int *avail) +{ + GeodePtr pGeode = GEODEPTR(pScrni); - if ((*H != 480) && (*H != 600) && (*H != 768)) - *H = 480; + if (pGeode->exaBfrSz > 0 && pGeode->exaBfrSz <= *avail) { + pGeode->exaBfrOffset = *offset; + *offset += pGeode->exaBfrOffset; + *avail -= pGeode->exaBfrOffset; + } } -static xf86MonPtr -GXProbeDDC(ScrnInfoPtr pScrni, int index) +static void +GXInitXAAMemory(ScrnInfoPtr pScrni, unsigned int *offset, unsigned int *avail) { - vbeInfoPtr pVbe; - xf86MonPtr ddc = NULL; + GeodePtr pGeode = GEODEPTR(pScrni); + unsigned int size, i, pitch; + + /* XXX - FIXME - What if we are out of room? Then what? */ + /* For now, we NULL them all out. */ + + if (pGeode->NoOfImgBuffers > 0) { + size = pGeode->displayPitch * pGeode->NoOfImgBuffers; + if (size <= *avail) { + for (i = 0; i < pGeode->NoOfImgBuffers; i++) { + pGeode->AccelImageWriteBuffers[i] = pGeode->FBBase + *offset; + *offset += pGeode->displayPitch; + *avail -= pGeode->displayPitch; + } + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for image write buffers.\n"); - if (xf86LoadSubModule(pScrni, "vbe")) { - pVbe = VBEInit(NULL, index); - ddc = vbeDoEDID(pVbe, NULL); - vbeFree(pVbe); + for (i = 0; i < pGeode->NoOfImgBuffers; i++) + pGeode->AccelImageWriteBuffers[i] = NULL; } - return ddc; -} + } -static void -GXDecodeDDC(ScrnInfoPtr pScrni, xf86MonPtr ddc) -{ - int i; - - DEBUGMSG(1, (0, X_INFO, - "Detected monitor DDC (%4s) id %d serno %d week %d year %d " - "nsects %d\n", - &ddc->vendor.name[0], ddc->vendor.prod_id, ddc->vendor.serial, - ddc->vendor.week, ddc->vendor.year, ddc->no_sections)); - for (i = 0; i < DET_TIMINGS; ++i) { - struct detailed_monitor_section *dp = &ddc->det_mon[i]; - - switch (dp->type) { - case DT: - { - struct detailed_timings *r = &dp->section.d_timings; - - DEBUGMSG(1, (0, X_INFO, " mon det timing %0.3f %dx%d\n", - r->clock / 1000000.0, r->h_active, r->v_active)); - DEBUGMSG(1, (0, X_INFO, - " mon border %d,%d laced %d stereo %d sync %d, misc" - " %d\n", - r->h_border, r->v_border, r->interlaced, r->stereo, - r->sync, r->misc)); - } - break; - case DS_SERIAL: - { - char *serial_no = (char *)&dp->section.serial[0]; - - DEBUGMSG(1, (0, X_INFO, " mon serial %13s\n", serial_no)); - } - break; - case DS_ASCII_STR: - { - char *ascii = (char *)&dp->section.ascii_data[0]; - - DEBUGMSG(1, (0, X_INFO, " mon ascii_str %13s\n", ascii)); - } - break; - case DS_NAME: - { - char *name = (char *)&dp->section.name[0]; - - DEBUGMSG(1, (0, X_INFO, " mon name %13s\n", name)); - } - break; - case DS_RANGES: - { - struct monitor_ranges *r = &dp->section.ranges; - - DEBUGMSG(1, (0, X_INFO, - " mon ranges v %d-%d h %d-%d clk %d\n", r->min_v, - r->max_v, r->min_h, r->max_h, r->max_clock)); - } - break; - case DS_WHITE_P: - { - struct whitePoints *wp = &dp->section.wp[0]; - - DEBUGMSG(1, (0, X_INFO, - " mon whitept %f,%f %f,%f idx %d,%d gamma %f,%f\n", - wp[1].white_x, wp[1].white_y, wp[2].white_x, - wp[2].white_y, wp[1].index, wp[2].index, - wp[1].white_gamma, wp[2].white_gamma)); - } - break; - case DS_STD_TIMINGS: - { - struct std_timings *t = &dp->section.std_t[0]; - - DEBUGMSG(1, (0, X_INFO, - " mon std_timing no size @rate, id\n")); - for (i = 0; i < 5; ++i) - DEBUGMSG(1, (0, X_INFO, - " %d %5dx%-5d @%-4d %d\n", i, - t[i].hsize, t[i].vsize, t[i].refresh, t[i].id)); - } - break; - } + if (pGeode->NoOfColorExpandLines > 0) { + pitch = ((pGeode->displayPitch + 31) >> 5) << 2; + size = pitch * pGeode->NoOfColorExpandLines; + + if (size <= *avail) { + for (i = 0; i < pGeode->NoOfColorExpandLines; i++) { + pGeode->AccelColorExpandBuffers[i] = pGeode->FBBase + *offset; + *offset += pitch; + *avail -= pitch; + } + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for color expansion buffers.\n"); + + for (i = 0; i < pGeode->NoOfImgBuffers; i++) + pGeode->AccelColorExpandBuffers[i] = NULL; } + } } -/*---------------------------------------------------------------------------- - * GXPreInit. - * - * Description :This function is called only once ate teh server startup - * - * Parameters. - * pScrni :Handle to ScreenPtr structure. - * flags :flags may be used to check the probeed one with config. - * - * Returns :TRUE on success and FALSE on failure. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ static Bool -GXPreInit(ScrnInfoPtr pScrni, int flags) +GXAllocateMemory(ScreenPtr pScrn, ScrnInfoPtr pScrni, int rotate) { - ClockRangePtr GeodeClockRange; - MessageType from; - int i = 0; - GeodeRec *pGeode; - char *mod = NULL; - xf86MonPtr ddc = NULL; - OptionInfoRec *GeodeOptions = &GX_GeodeOptions[0]; - -#if CFB - char *reqSymbol = NULL; -#endif /* CFB */ -#if INT10_SUPPORT - VESARec *pVesa; -#endif - unsigned int PitchInc = 0, minPitch = 0, maxPitch = 0; - unsigned int minHeight = 0, maxHeight = 0, maxWidth = 0; - unsigned int SupportFlags; - const char *s; - char **modes; - - /* - * Setup the ClockRanges, which describe what clock ranges are - * available, and what sort of modes they can be used for. - */ - GeodeClockRange = (ClockRangePtr) xnfcalloc(sizeof(ClockRange), 1); - GeodeClockRange->next = NULL; - GeodeClockRange->minClock = 25175; - GeodeClockRange->maxClock = 229500; - GeodeClockRange->clockIndex = -1; /* programmable */ - GeodeClockRange->interlaceAllowed = TRUE; - GeodeClockRange->doubleScanAllowed = FALSE; /* XXX check this */ - - DEBUGMSG(1, (0, X_INFO, "GXPreInit!\n")); - /* Allocate driver private structure */ - if (!(pGeode = GXGetRec(pScrni))) - return FALSE; - - if (pScrni->numEntities != 1) - return FALSE; - - pGeode->pEnt = xf86GetEntityInfo(pScrni->entityList[i]); - if (pGeode->pEnt->resources) - return FALSE; - pGeode->Chipset = pGeode->pEnt->chipset; - pScrni->chipset = (char *)xf86TokenToString(GeodeChipsets, - pGeode->pEnt->chipset); - - - /* DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, "PROBEDDC\n")); */ - - /* Note that we can't do this without VGA */ - - if (flags & PROBE_DETECT != 0) { - ConfiguredMonitor = GXProbeDDC(pScrni, pGeode->pEnt->index); - return TRUE; - } + GeodePtr pGeode = GEODEPTR(pScrni); - /* Hardware detection */ + unsigned int fboffset, fbavail; + unsigned int size; + unsigned int bytpp = (pScrni->bitsPerPixel + 7) / 8; + BOOL ret = TRUE; - pGeode->cpu_version = gfx_detect_cpu(); + if (pGeode->tryCompression) + pGeode->displayPitch = + GeodeCalculatePitchBytes(pScrni->virtualX, pScrni->bitsPerPixel); + else + pGeode->displayPitch = + ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3); - if ((pGeode->cpu_version & 0xFF) == GFX_CPU_REDCLOUD) { - int ret; - Q_WORD msrValue; - pGeode->DetectedChipSet = GX; + pGeode->Pitch = pGeode->displayPitch; + pGeode->displayWidth = pGeode->displayPitch / bytpp; + pScrni->displayWidth = pGeode->displayWidth; - /* See if this a CRT or TFT part */ + fbavail = pGeode->FBAvail - 0x4000; - ret = gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msrValue); + pGeode->displayOffset = fboffset = 0; + pGeode->displaySize = pScrni->virtualY * pGeode->displayPitch; - /* We depend heavily on the MSR working, so if it doesn't, there - * isn't much we can do but complain and move on - */ + fbavail -= pGeode->displaySize; + fboffset += pGeode->displaySize; - if (ret != 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, - "MSR read failed (ret=%d)\n", ret)); - } - - pGeode->DetectedChipSet = - ((msrValue.low & RCDF_CONFIG_FMT_MASK) == - RCDF_CONFIG_FMT_FP) ? GX_TFT : GX_CRT; - - } + if (pGeode->tryCompression) { + size = pScrni->virtualY * GX_CB_PITCH; - pGeode->vid_version = gfx_detect_video(); - pGeode->FBLinearAddr = gfx_get_frame_buffer_base(); + if (size <= fbavail) { + pGeode->CBData.compression_offset = fboffset; - /* update the max clock from the one system suports */ - GeodeClockRange->maxClock = gfx_get_max_supported_pixel_clock(); + fboffset += size; + fbavail -= size; + pGeode->Compression = TRUE; + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for compression\n"); + pGeode->Compression = FALSE; + } + } - /* Set Durango register pointers */ + if (pGeode->tryHWCursor) { + pGeode->CursorSize = 1024; - if (pGeode->DetectedChipSet & GX) { - pGeode->cpu_reg_size = 0x4000; - pGeode->gp_reg_size = 0x4000; - pGeode->vid_reg_size = 0x4000; + if (pGeode->CursorSize <= fbavail) { + pGeode->CursorStartOffset = fboffset; + fboffset += pGeode->CursorSize; + fbavail -= pGeode->CursorSize; + pGeode->HWCursor = TRUE; } else { - pGeode->cpu_reg_size = 0x9000; - pGeode->vid_reg_size = 0x1000; + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for the hardware cursor\n"); + pGeode->HWCursor = FALSE; } + } + if (!pGeode->NoAccel) { + if (pGeode->useEXA) + GXInitEXAMemory(pScrni, &fboffset, &fbavail); + else + GXInitXAAMemory(pScrni, &fboffset, &fbavail); + } - pGeode->FBVGAActive = 0; + pGeode->shadowSize = 0; - /* Fill in the monitor field */ - pScrni->monitor = pScrni->confScreen->monitor; + if (rotate != RR_Rotate_0) { + if (rotate & (RR_Rotate_90 | RR_Rotate_270)) + size = pGeode->displayPitch * pScrni->virtualX; + else + size = pGeode->displayPitch * pScrni->virtualY; - SupportFlags = Support24bppFb | Support32bppFb; + if (size <= fbavail) { + pGeode->shadowOffset = fboffset; + pGeode->shadowSize = size; - if (!xf86SetDepthBpp(pScrni, 8, 8, 8, SupportFlags)) { - return FALSE; + fboffset += size; + fbavail -= size; } else { - if (!((pScrni->depth == 8) || - (pScrni->depth == 16) || - (pScrni->depth == 24) || (pScrni->depth == 32))) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, - "Given depth (%d bpp) is not supported by this driver\n", - pScrni->depth)); - return FALSE; - } + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for the shadow framebuffer\n"); + ret = FALSE; } + } + + /* XAA always exists - we can't remove it on demand like we can with EXA. + So we assume the worse, and only give XAA enough offspace room to + account for any eventuality that RandR might throw at us. */ + + if (!pGeode->NoAccel) { + + if (pGeode->useEXA && pGeode->pExa) { + ExaDriverPtr pExa = pGeode->pExa; - /*This must happen after pScrni->display has been set - * * because xf86SetWeight references it. - */ - if (pScrni->depth > 8) { - - rgb BitsPerComponent = { 0, 0, 0 }; - rgb BitMask = { 0, 0, 0 }; - - if (pScrni->depth > 16) { - - BitsPerComponent.red = 8; - BitsPerComponent.green = 8; - BitsPerComponent.blue = 8; - - BitMask.red = 0xFF0000; - BitMask.green = 0x00FF00; - BitMask.blue = 0x0000FF; - } - if (!xf86SetWeight(pScrni, BitsPerComponent, BitMask)) { - return FALSE; - } else { - /* XXX Check if the returned weight is supported */ - } + pExa->offScreenBase = fboffset; + pExa->memorySize = fboffset + fbavail; } - xf86PrintDepthBpp(pScrni); + if (!pGeode->useEXA) { - if (!xf86SetDefaultVisual(pScrni, -1)) - return FALSE; + if (!xf86FBManagerRunning(pScrn)) { + + unsigned int offset = fboffset; + unsigned int avail = fbavail; + RegionRec OffscreenRegion; + BoxRec AvailBox; + + /* Assume the shadow FB exists even if it doesnt */ + + if (pGeode->shadowSize == 0) { + size = (pScrn->width * bytpp) * pScrni->virtualX; + offset += size; + avail -= size; + } - if (pScrni->depth > 1) { - Gamma zeros = { 0.0, 0.0, 0.0 }; + AvailBox.x1 = 0; + AvailBox.y1 = + (offset + pGeode->displayPitch - + 1) / pGeode->displayPitch; - if (!xf86SetGamma(pScrni, zeros)) { - return FALSE; - } + AvailBox.x2 = pGeode->displayWidth; + AvailBox.y2 = (offset + avail) / pGeode->displayPitch; + + if (AvailBox.y1 < AvailBox.y2) { + REGION_INIT(pScrn, &OffscreenRegion, &AvailBox, 2); + + if (!xf86InitFBManagerRegion(pScrn, &OffscreenRegion)) + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Memory manager initialization failed.\n"); + + REGION_UNINIT(pScrn, &OffscreenRegion); + } else + xf86DrvMsg(pScrni->scrnIndex, X_INFO, + "Cache disabled - no offscreen memory available.\n"); + } else + xf86DrvMsg(pScrni->scrnIndex, X_INFO, + "XAA offscreen memory has already been allocated.\n"); } + } + return ret; +} + +static Bool +GXSaveScreen(ScreenPtr pScrn, int mode) +{ + ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; + GeodePtr pGeode = GEODEPTR(pScrni); - /* We use a programmable clock */ - pScrni->progClock = TRUE; + if (pGeode->useVGA && !pScrni->vtSema) + return vgaHWSaveScreen(pScrn, mode); - xf86CollectOptions(pScrni, NULL); + return TRUE; +} - xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, - GeodeOptions); - pGeode->useVGA = TRUE; - if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOVGA, FALSE)) - pGeode->useVGA = FALSE; +/* Common function - used by the LX too */ - xf86DrvMsg(pScrni->scrnIndex, X_DEFAULT, - "useVGA=%d\n", pGeode->useVGA); - if (pGeode->useVGA) { -#if INT10_SUPPORT - if (!xf86LoadSubModule(pScrni, "int10")) - return FALSE; - xf86LoaderReqSymLists(amdInt10Symbols, NULL); +extern unsigned long gfx_gx2_scratch_base; - pVesa = pGeode->vesa; +static Bool +GXMapMem(ScrnInfoPtr pScrni) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + int index = pScrni->scrnIndex; - if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, - "Unable to initialize INT10 support\n")); - return FALSE; - } -#endif + pciVideoRec *pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); - if (!xf86LoadSubModule(pScrni, "vgahw")) - return FALSE; + gfx_virt_regptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_MMIO, + pci->memBase[2], pci->size[2]); - xf86LoaderReqSymLists(amdVgahwSymbols, NULL); + gfx_virt_gpptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_MMIO, + pci->memBase[1], pci->size[1]); - pGeode->FBAvail = gfx_get_frame_buffer_size(); - } - else { - if (!xf86GetOptValInteger(GeodeOptions, GX_OPTION_FBSIZE, - &(pGeode->FBAvail))) - pGeode->FBAvail = 0x800000; - } + gfx_virt_vidptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_MMIO, + pci->memBase[3], pci->size[3]); - if (!GXMapMem(pScrni)) - return FALSE; + gfx_virt_fbptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, + pci->memBase[0], pGeode->FBAvail); - pGeode->FBVGAActive = FALSE; + gfx_gx2_scratch_base = pGeode->FBAvail - 0x4000; - if (pGeode->useVGA) - pGeode->FBVGAActive = gu2_get_vga_active(); + XpressROMPtr = xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, 0xF0000, 0x10000); - /*Set the bits per RGB for 8bpp mode */ + pGeode->FBBase = gfx_virt_fbptr; - if (pScrni->depth == 8) - pScrni->rgbBits = 8; + if ((!gfx_virt_regptr) || (!gfx_virt_gpptr) || + (!gfx_virt_vidptr) || (!gfx_virt_fbptr)) + return FALSE; - from = X_DEFAULT; + if (!pGeode->NoAccel && pGeode->useEXA) + pGeode->pExa->memoryBase = pGeode->FBBase; - /* - * *The preferred method is to use the "hw cursor" option as a tri-state - * *option, with the default set above. - */ - pGeode->HWCursor = TRUE; + xf86DrvMsg(index, X_INFO, "Found Geode %x %p\n", + pGeode->FBAvail, pGeode->FBBase); - if (xf86GetOptValBool(GeodeOptions, GX_OPTION_HW_CURSOR, &pGeode->HWCursor)) { - from = X_CONFIG; - } - /* For compatibility, accept this too (as an override) */ - if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_SW_CURSOR, FALSE)) { - from = X_CONFIG; - pGeode->HWCursor = FALSE; - } + return TRUE; +} - pGeode->Compression = TRUE; - if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOCOMPRESSION, FALSE)) { - pGeode->Compression = FALSE; - } +/* Check to see if VGA exists - we map the space and look for a + signature - if it doesn't match exactly, then we assume no VGA. +*/ - pGeode->NoAccel = FALSE; - if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOACCEL, FALSE)) { - pGeode->NoAccel = TRUE; - } +static Bool +GXCheckVGA(ScrnInfoPtr pScrni) { - if (!xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_IMG_BUFS, - &(pGeode->NoOfImgBuffers))) - pGeode->NoOfImgBuffers = DEFAULT_IMG_LINE_BUFS; + const char *vgasig = "IBM VGA Compatible"; + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + int ret; - if (pGeode->NoOfImgBuffers <= 0) - pGeode->NoOfImgBuffers = 0; + if (!vgaHWMapMem(pScrni)) + return FALSE; - if (!xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_CLR_BUFS, - &(pGeode->NoOfColorExpandLines))) - pGeode->NoOfColorExpandLines = DEFAULT_CLR_LINE_BUFS; + ret = memcmp(pvgaHW->Base + 0x1E, vgasig, strlen(vgasig)); + vgaHWUnmapMem(pScrni); - if (pGeode->NoOfColorExpandLines <= 0) - pGeode->NoOfColorExpandLines = 0; + return ret ? FALSE : TRUE; +} +static Bool +GXPreInit(ScrnInfoPtr pScrni, int flags) +{ + GeodePtr pGeode; + ClockRangePtr GeodeClockRange; + OptionInfoRec *GeodeOptions = &GX_GeodeOptions[0]; + int ret; + QQ_WORD msrValue; + rgb defaultWeight = { 0, 0, 0 }; + int modecnt; + char *s, *panelgeo; -#ifdef XF86EXA - if (!xf86GetOptValInteger(GeodeOptions, GX_OPTION_EXA_SCRATCH_BFRSZ, - &(pGeode->exaBfrSz))) - pGeode->exaBfrSz = DEFAULT_EXA_SCRATCH_BFRSZ; + pGeode = pScrni->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1); - if (pGeode->exaBfrSz <= 0) - pGeode->exaBfrSz = 0; -#endif + if (pGeode == NULL) + return FALSE; - + /* Probe for VGA */ + pGeode->useVGA = FALSE; - pGeode->CustomMode = FALSE; - if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_CUSTOM_MODE, FALSE)) { - pGeode->CustomMode = TRUE; + if (xf86LoadSubModule(pScrni, "vgahw")) { + if (vgaHWGetHWRec(pScrni)) { + pGeode->useVGA = GXCheckVGA(pScrni); } + } - pGeode->Panel = FALSE; +#if INT10_SUPPORT + if (pGeode->useVGA) + pGeode->vesa = xcalloc(sizeof(VESARec), 1); +#endif - if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_FLATPANEL, FALSE)) { - pGeode->Panel = TRUE; - } + if (pScrni->numEntities != 1) + return FALSE; - if (pGeode->DetectedChipSet == GX_TFT) { - pGeode->Panel = TRUE; - } + pGeode->pEnt = xf86GetEntityInfo(pScrni->entityList[0]); - pGeode->dconPanel = FALSE; + if (pGeode->pEnt->resources) + return FALSE; - if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_DCONPANEL, FALSE)) { - pGeode->dconPanel = TRUE; - gx_dcon_init(); - } + /* ISSUE - this won't work without VGA, but its too early to know if we can use VGA or not */ - /* Force the Panel on if on a GX TFT part, no CRT support anyway */ + if (pGeode->useVGA && (flags & PROBE_DETECT)) { + GeodeProbeDDC(pScrni, pGeode->pEnt->index); + return TRUE; + } - if (pGeode->DetectedChipSet == GX_TFT) { - pGeode->Panel = TRUE; - } + gfx_msr_init(); - /* If on a CRT and Panel flag set, disable Panel */ - if ((pGeode->DetectedChipSet == GX_CRT) && (pGeode->Panel)) { - pGeode->dconPanel = FALSE; - pGeode->Panel = FALSE; - } + ret = gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msrValue); -#if defined(PNL_SUP) - /* If dconPanel is selected - then hard wire the settings */ - /* Otherwise, suck the timings out of the BIOS */ - - if (pGeode->dconPanel) { - pGeode->FPBX = DCON_DEFAULT_XRES; - pGeode->FPBY = DCON_DEFAULT_YRES; - pGeode->FPBB = DCON_DEFAULT_BPP; - pGeode->FPBF = DCON_DEFAULT_REFRESH; - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, "DCON!\n")); - } else if (pGeode->Panel) { - if ((pGeode->Panel = Pnl_IsPanelEnabledInBIOS())) - Pnl_GetPanelInfoFromBIOS(&pGeode->FPBX, &pGeode->FPBY, - &pGeode->FPBB, &pGeode->FPBF); - } + if (!ret) { + pGeode->Output = + ((msrValue.low & RCDF_CONFIG_FMT_MASK) == + RCDF_CONFIG_FMT_FP) ? OUTPUT_CRT : OUTPUT_PANEL; + } - if (pGeode->Panel) - Pnl_PowerUp(); - else - Pnl_PowerDown(); -#endif + /* Fill in the monitor information */ + pScrni->monitor = pScrni->confScreen->monitor; - pGeode->useEXA = FALSE; - from = X_DEFAULT; - if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ACCEL_METHOD))) { - if (!xf86NameCmp(s, "XAA")) { - from = X_CONFIG; - pGeode->useEXA = FALSE; -#if XF86EXA - } else if (!xf86NameCmp(s, "EXA")) { - from = X_CONFIG; - pGeode->useEXA = TRUE; -#endif - } else - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Unknown acceleration architecture - %s\n", s); - } + if (!xf86SetDepthBpp(pScrni, 8, 8, 8, Support24bppFb | Support32bppFb)) + return FALSE; - xf86DrvMsg(pScrni->scrnIndex, from, - "Using %s acceleration architecture\n", - pGeode->useEXA ? "EXA" : "XAA"); + switch (pScrni->depth) { + case 8: + pScrni->rgbBits = 8; + case 16: + case 24: + case 32: + break; + default: + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "The driver does not support %d as a depth.\n", pScrni->depth); + return FALSE; + } - pGeode->ShadowFB = FALSE; - if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_SHADOW_FB, FALSE)) { - pGeode->ShadowFB = TRUE; - pGeode->NoAccel = TRUE; - } + xf86PrintDepthBpp(pScrni); - pGeode->Rotate = 0; - if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ROTATE))) { + if (!xf86SetWeight(pScrni, defaultWeight, defaultWeight)) + return FALSE; - if (!xf86NameCmp(s, "CW")) - pGeode->Rotate = 1; - else if (!xf86NameCmp(s, "INVERT")) - pGeode->Rotate = 2; - else if (!xf86NameCmp(s, "CCW")) - pGeode->Rotate = 3; + if (!xf86SetDefaultVisual(pScrni, -1)) + return FALSE; + pScrni->progClock = TRUE; + xf86CollectOptions(pScrni, NULL); + xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, GeodeOptions); - if (pGeode->Rotate == 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "\"%s\" is not a valid value for Option \"Rotate\"\n", - s)); - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, - "Valid options are \"CW\", \"INVERT\" or \"CCW\"\n")); - } - } + /* Set up our various options that may get reversed as we go on */ - if (pGeode->Rotate == 1) - xf86DrvMsg(pScrni->scrnIndex, X_CONFIG, "Rotating screen clockwise\n"); - else if (pGeode->Rotate == 2) - xf86DrvMsg(pScrni->scrnIndex, X_CONFIG, "Rotating screen 180 degrees\n"); - else if (pGeode->Rotate == 3) - xf86DrvMsg(pScrni->scrnIndex, X_CONFIG, "Rotating screen 180 counter clockwise\n"); - - if (pGeode->Rotate != 0) { - xf86DrvMsg(pScrni->scrnIndex, X_CONFIG, "Option 'Rotate' will disable acceleration and enable shadow\n"); - pGeode->NoAccel = TRUE; - pGeode->ShadowFB = TRUE; - } + pGeode->FBVGAActive = FALSE; + pGeode->tryHWCursor = TRUE; + pGeode->tryCompression = TRUE; - /* XXX Init further private data here */ + pGeode->NoAccel = FALSE; + pGeode->useEXA = TRUE; - /* - * * This shouldn't happen because such problems should be caught in - * * GeodeProbe(), but check it just in case. - */ - if (pScrni->chipset == NULL) { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "ChipID 0x%04X is not recognised\n", pGeode->Chipset); - return FALSE; - } + pGeode->Panel = (pGeode->Output & OUTPUT_PANEL) ? TRUE : FALSE; - if (pGeode->Chipset < 0) { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "Chipset %s is not recognised\n", pScrni->chipset); - return FALSE; - } + pGeode->NoOfImgBuffers = DEFAULT_IMG_LINE_BUFS; + pGeode->NoOfColorExpandLines = DEFAULT_CLR_LINE_BUFS; + pGeode->exaBfrSz = DEFAULT_EXA_SCRATCH_BFRSZ; - if (pScrni->memPhysBase == 0) { - from = X_PROBED; - pScrni->memPhysBase = gfx_get_frame_buffer_base(); - } + xf86GetOptValBool(GeodeOptions, GX_OPTION_HW_CURSOR, + &pGeode->tryHWCursor); - pScrni->fbOffset = 0; + if (!xf86GetOptValInteger(GeodeOptions, GX_OPTION_FBSIZE, + &(pGeode->FBAvail))) + pGeode->FBAvail = 0; - if (pGeode->pEnt->device->videoRam == 0) { - from = X_PROBED; - pScrni->videoRam = pGeode->FBAvail / 1024; - } else { - pScrni->videoRam = pGeode->pEnt->device->videoRam; - from = X_CONFIG; - } + /* For compatability - allow SWCursor too */ - /* - * * xf86ValidateModes will check that the mode HTotal and VTotal values - * * don't exceed the chipset's limit if pScrni->maxHValue adn - * * pScrni->maxVValue are set. Since our GXValidMode() - * * already takes care of this, we don't worry about setting them here. - */ - /* Select valid modes from those available */ - - /* - * * min pitch 1024, max 2048 (Pixel count) - * * min height 480, max 1024 (Pixel count) - */ - - minPitch = 1024; - maxPitch = 8192; /* Can support upto 1600x1200 32Bpp */ - maxWidth = 1600; - minHeight = 400; - maxHeight = 1200; /* Can support upto 1600x1200 32Bpp */ - - - if (pGeode->Compression) { - if (pScrni->depth > 16) { - PitchInc = 4096; - } else if (pScrni->depth == 16) { - PitchInc = 2048; - } else { - PitchInc = 1024; - } - } - else { - /* When compression is off - use a linear pitch */ - if (pScrni->depth < 16) - PitchInc = 1600; - else if (pScrni->depth == 16) - PitchInc = 3200; - else - PitchInc = 6400; - } + if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_SW_CURSOR, FALSE)) + pGeode->tryHWCursor = FALSE; - PitchInc <<= 3; /* in bits */ + if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOCOMPRESSION, FALSE)) + pGeode->tryCompression = FALSE; - pGeode->maxWidth = maxWidth; - pGeode->maxHeight = maxHeight; + if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOACCEL, FALSE)) + pGeode->NoAccel = TRUE; - /* by default use what user sets in the XF86Config file */ - modes = pScrni->display->modes; + pGeode->rotation = RR_Rotate_0; + + if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ROTATE))) { + + if (!xf86NameCmp(s, "LEFT")) + pGeode->rotation = RR_Rotate_90; + else if (!xf86NameCmp(s, "INVERT")) + pGeode->rotation = RR_Rotate_180; + else if (!xf86NameCmp(s, "CCW")) + pGeode->rotation = RR_Rotate_270; + else + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Invalid rotation %s.\n", s); + } - if (ddc != NULL && pScrni->monitor != NULL - && pScrni->monitor->DDC == NULL) { - pScrni->monitor->DDC = ddc; - GXDecodeDDC(pScrni, ddc); - } + xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_IMG_BUFS, + &(pGeode->NoOfImgBuffers)); - i = xf86ValidateModes(pScrni, - pScrni->monitor->Modes, - modes, GeodeClockRange, - NULL, minPitch, maxPitch, - PitchInc, minHeight, maxHeight, - pScrni->display->virtualX, - pScrni->display->virtualY, pGeode->FBAvail, LOOKUP_BEST_REFRESH); - - if (i == -1) { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); - GXFreeRec(pScrni); - return FALSE; - } + if (pGeode->NoOfImgBuffers <= 0) + pGeode->NoOfImgBuffers = 0; - /* Prune the modes marked as invalid */ - xf86PruneDriverModes(pScrni); + xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_CLR_BUFS, + &(pGeode->NoOfColorExpandLines)); - if (i == 0 || pScrni->modes == NULL) { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); - GXFreeRec(pScrni); - return FALSE; - } + if (pGeode->NoOfColorExpandLines <= 0) + pGeode->NoOfColorExpandLines = 0; - xf86SetCrtcForModes(pScrni, 0); - - /* Set the current mode to the first in the list */ - pScrni->currentMode = pScrni->modes; - DEBUGMSG(1, (0, X_INFO, "GXPreInit(12)!\n")); - - /* Print the list of modes being used */ - xf86PrintModes(pScrni); - - /* Set the display resolution */ - xf86SetDpi(pScrni, 0, 0); - - /* Load bpp-specific modules */ - mod = NULL; - -#if CFB - /* Load bpp-specific modules */ - switch (pScrni->bitsPerPixel) { - case 8: - mod = "cfb"; - reqSymbol = "cfbScreenInit"; - break; - case 16: - mod = "cfb16"; - reqSymbol = "cfb16ScreenInit"; - break; - case 24: - mod = "cfb24"; - reqSymbol = "cfb24ScreenInit"; - break; - case 32: - mod = "cfb32"; - reqSymbol = "cfb32ScreenInit"; - break; - default: - return FALSE; - } + xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_CLR_BUFS, + &(pGeode->exaBfrSz)); - if (mod && xf86LoadSubModule(pScrni, mod) == NULL) { - GXFreeRec(pScrni); - return FALSE; - } + if (pGeode->exaBfrSz <= 0) + pGeode->exaBfrSz = 0; - xf86LoaderReqSymbols(reqSymbol, NULL); -#else - if (xf86LoadSubModule(pScrni, "fb") == NULL) { - GXFreeRec(pScrni); - return FALSE; - } + if (pGeode->Panel == TRUE) { + if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOPANEL, FALSE)) + pGeode->Panel = FALSE; + } - xf86LoaderReqSymLists(amdFbSymbols, NULL); -#endif + panelgeo = xf86GetOptValString(GeodeOptions, GX_OPTION_PANEL_GEOMETRY); - if (pGeode->NoAccel == FALSE) { - const char *module = "xaa"; - const char **symbols = &amdXaaSymbols[0]; + if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ACCEL_METHOD))) { + if (!xf86NameCmp(s, "XAA")) + pGeode->useEXA = FALSE; + else if (xf86NameCmp(s, "EXA")) + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Unknown accleration method %s. Defaulting to EXA.\n", s); + } -#if XF86EXA - if (pGeode->useEXA) { - module = "exa"; - symbols = &amdExaSymbols[0]; - } -#endif - if (!xf86LoadSubModule(pScrni, module)) { - GXFreeRec(pScrni); - return FALSE; - } + xf86DrvMsg(pScrni->scrnIndex, X_INFO, + "Using %s acceleration architecture\n", + pGeode->useEXA ? "EXA" : "XAA"); + + /* Set up the panel */ - xf86LoaderReqSymLists(symbols, NULL); + if (gx_dcon_init(pScrni)) { + pGeode->Panel = TRUE; + } else if (pGeode->Panel) { + if (panelgeo != NULL) { + if (GeodeGetFPGeometry(panelgeo, &pGeode->PanelX, &pGeode->PanelY)) + pGeode->Panel = FALSE; } +#ifdef PNL_SUP + else { + int b, f; - if (pGeode->HWCursor == TRUE) { - if (!xf86LoadSubModule(pScrni, "ramdac")) { - GXFreeRec(pScrni); - return FALSE; - } + /* The bitdepth and refresh isn't used anywhere else in the driver */ - xf86LoaderReqSymLists(amdRamdacSymbols, NULL); + if ((pGeode->Panel = Pnl_IsPanelEnabledInBIOS())) + Pnl_GetPanelInfoFromBIOS(&pGeode->PanelX, &pGeode->PanelY, &b, + &f); } +#endif + } - /* Load shadowfb if needed */ - if (pGeode->ShadowFB) { - if (!xf86LoadSubModule(pScrni, "shadowfb")) { - GXFreeRec(pScrni); - return FALSE; - } + /* Set up the VGA */ - xf86LoaderReqSymLists(amdShadowSymbols, NULL); - } + if (pGeode->useVGA) { +#if INT10_SUPPORT + VESARec *pVesa; + + if (!xf86LoadSubModule(pScrni, "int10")) + return FALSE; + xf86LoaderReqSymLists(amdInt10Symbols, NULL); - if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, - "xf86RegisterResources() found resource conflicts\n")); - GXFreeRec(pScrni); - return FALSE; + pVesa = pGeode->vesa; + + if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Unable to initialize 1NT10 support\n"); + pGeode->useVGA = FALSE; } +#endif - GXUnmapMem(pScrni); - return TRUE; -} + xf86LoaderReqSymLists(amdVgahwSymbols, NULL); + pGeode->FBVGAActive = gu2_get_vga_active(); + } -/*---------------------------------------------------------------------------- - * GXRestore. - * - * Description :This function restores the mode that was saved on server - entry - * Parameters. - * pScrni :Handle to ScreenPtr structure. - * Pmode :poits to screen mode - * - * Returns :none. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ -static void -GXRestore(ScrnInfoPtr pScrni) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); + if (pGeode->FBAvail == 0) + pGeode->FBAvail = gfx_get_frame_buffer_size(); - if (pGeode->useVGA && pGeode->FBVGAActive) { - vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + if (pScrni->memPhysBase == 0) + pScrni->memPhysBase = gfx_get_frame_buffer_base(); - vgaHWProtect(pScrni, TRUE); - vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); - vgaHWProtect(pScrni, FALSE); - } -} + pScrni->fbOffset = 0; -/*---------------------------------------------------------------------------- - * GXCalculatePitchBytes. - * - * Description :This function restores the mode that was saved on server - * - * Parameters. - * pScrni :Handle to ScreenPtr structure. - * Pmode :Points to screenmode - * - * Returns :none. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ -static int -GXCalculatePitchBytes(unsigned int width, unsigned int bpp) -{ - int lineDelta = width * (bpp >> 3); + if (pGeode->pEnt->device->videoRam == 0) + pScrni->videoRam = pGeode->FBAvail / 1024; + else + pScrni->videoRam = pGeode->pEnt->device->videoRam; - if (width < 640) { - /* low resolutions have both pixel and line doubling */ - DEBUGMSG(1, (0, X_PROBED, "lower resolution %d %d\n", - width, lineDelta)); - lineDelta <<= 1; - } - /* needed in Rotate mode when in accel is turned off */ - if (1) { /*!pGeode->NoAccel */ - if (lineDelta > 4096) - lineDelta = 8192; - else if (lineDelta > 2048) - lineDelta = 4096; - else if (lineDelta > 1024) - lineDelta = 2048; - else - lineDelta = 1024; - } + pGeode->maxWidth = GX_MAX_WIDTH; + pGeode->maxHeight = GX_MAX_HEIGHT; - DEBUGMSG(1, (0, X_PROBED, "pitch %d %d\n", width, lineDelta)); + GeodeClockRange = (ClockRangePtr) xnfcalloc(sizeof(ClockRange), 1); + GeodeClockRange->next = NULL; + GeodeClockRange->minClock = 25175; + GeodeClockRange->maxClock = 229500; + GeodeClockRange->clockIndex = -1; + GeodeClockRange->interlaceAllowed = TRUE; + GeodeClockRange->doubleScanAllowed = FALSE; - return lineDelta; -} + if (pGeode->useVGA) + pScrni->monitor->DDC = GeodeDoDDC(pScrni, pGeode->pEnt->index); + else + pScrni->monitor->DDC = NULL; -/*---------------------------------------------------------------------------- - * GXGetRefreshRate. - * - * Description :This function restores the mode that saved on server - * - * Parameters. - * Pmode :Pointer to the screen modes - * - * Returns :It returns the selected refresh rate. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ -static int -GXGetRefreshRate(DisplayModePtr pMode) -{ -#define THRESHOLD 2 - unsigned int i; - static int validRates[] = { 56, 60, 70, 72, 75, 85, 90, 100 }; /* Hz */ - unsigned long dotClock; - int refreshRate; - int selectedRate; + /* I'm still not 100% sure this uses the right values */ + + modecnt = xf86ValidateModes(pScrni, + pScrni->monitor->Modes, + pScrni->display->modes, + GeodeClockRange, + NULL, GX_MIN_PITCH, GX_MAX_PITCH, + 32, GX_MIN_HEIGHT, GX_MAX_HEIGHT, + pScrni->display->virtualX, + pScrni->display->virtualY, pGeode->FBAvail, LOOKUP_BEST_REFRESH); + + if (modecnt <= 0) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); + return FALSE; + } - dotClock = pMode->SynthClock * 1000; - refreshRate = dotClock / pMode->CrtcHTotal / pMode->CrtcVTotal; + xf86PruneDriverModes(pScrni); - if ((pMode->CrtcHTotal < 640) && (pMode->CrtcVTotal < 480)) - refreshRate >>= 2; /* double pixel and double scan */ + if (pScrni->modes == NULL) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); + return FALSE; + } - DEBUGMSG(1, (0, X_PROBED, "dotclock %lu %d\n", dotClock, refreshRate)); + xf86SetCrtcForModes(pScrni, 0); + pScrni->currentMode = pScrni->modes; - selectedRate = validRates[0]; + xf86PrintModes(pScrni); + xf86SetDpi(pScrni, 0, 0); - for (i = 0; i < (sizeof(validRates) / sizeof(validRates[0])); i++) { - if (validRates[i] < (refreshRate + THRESHOLD)) { - selectedRate = validRates[i]; - } + /* Load the modules we'll need */ + + if (xf86LoadSubModule(pScrni, "fb") == NULL) { + return FALSE; + } + + xf86LoaderReqSymLists(amdFbSymbols, NULL); + + if (pGeode->NoAccel == FALSE) { + const char *module = (pGeode->useEXA) ? "exa" : "xaa"; + const char **symbols = (pGeode->useEXA) ? + &amdExaSymbols[0] : &amdXaaSymbols[0]; + + if (!xf86LoadSubModule(pScrni, module)) { + return FALSE; } - return selectedRate; -} + xf86LoaderReqSymLists(symbols, NULL); + } -void -gx_clear_screen(ScrnInfoPtr pScrni, int width, int height, int bpp) -{ - /* no accels, mode is not yet set */ - GeodeRec *pGeode = GEODEPTR(pScrni); - unsigned long offset = gfx_get_display_offset(); - unsigned long pitch = gfx_get_display_pitch(); - unsigned long n = width * ((bpp + 7) >> 3); - - DEBUGMSG(1, (0, X_PROBED, "clear screen %lx %d %d %d %ld %ld\n", offset, - width, height, bpp, pitch, n)); - while (height > 0) { - memset(pGeode->FBBase + offset, 0, n); - offset += pitch; - --height; + if (pGeode->tryHWCursor == TRUE) { + if (!xf86LoadSubModule(pScrni, "ramdac")) { + return FALSE; } + + xf86LoaderReqSymLists(amdRamdacSymbols, NULL); + } + + if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Couldn't register the resources.\n"); + return FALSE; + } + + return TRUE; } -void -gx_clear_fb(ScrnInfoPtr pScrni) +static void +GXRestore(ScrnInfoPtr pScrni) { - GeodeRec *pGeode = GEODEPTR(pScrni); - unsigned char *fb = pGeode->FBBase + pGeode->FBOffset; + GeodeRec *pGeode = GEODEPTR(pScrni); - memset(fb, 0, pGeode->FBSize); - if (pGeode->ShadowPtr != NULL && pGeode->ShadowPtr != fb) - memset(pGeode->ShadowPtr, 0, pGeode->ShadowSize); + if (pGeode->useVGA && pGeode->FBVGAActive) { + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + + vgaHWProtect(pScrni, TRUE); + vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); + vgaHWProtect(pScrni, FALSE); + } } -void -gx_set_DvLineSize(unsigned int pitch) +static Bool +GXUnmapMem(ScrnInfoPtr pScrni) { - unsigned long temp, dv_size = MDC_DV_LINE_SIZE_1024; + GeodeRec *pGeode = GEODEPTR(pScrni); - if (pitch > 1024) { - dv_size = MDC_DV_LINE_SIZE_2048; - } - if (pitch > 2048) { - dv_size = MDC_DV_LINE_SIZE_4096; - } - if (pitch > 4096) { - dv_size = MDC_DV_LINE_SIZE_8192; - } + /* unmap all the memory map's */ - /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */ + xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_regptr, GX_CPU_REG_SIZE); + xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_gpptr, GX_GP_REG_SIZE); + xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_vidptr, GX_VID_REG_SIZE); + xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_fbptr, pGeode->FBAvail); + return TRUE; +} - temp = READ_REG32(MDC_DV_CTL); - WRITE_REG32(MDC_DV_CTL, (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size); +static void +GXSetDvLineSize(unsigned int pitch) +{ + unsigned long temp, dv_size = MDC_DV_LINE_SIZE_1024; + + if (pitch > 1024) { + dv_size = MDC_DV_LINE_SIZE_2048; + } + if (pitch > 2048) { + dv_size = MDC_DV_LINE_SIZE_4096; + } + if (pitch > 4096) { + dv_size = MDC_DV_LINE_SIZE_8192; + } + + /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */ + + temp = READ_REG32(MDC_DV_CTL); + WRITE_REG32(MDC_DV_CTL, (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size); } -/*---------------------------------------------------------------------------- - * GXSetMode. - * - * Description :This function sets parametrs for screen mode - * - * Parameters. - * pScrni :Pointer to the screenInfo structure. - * Pmode :Pointer to the screen modes - * - * Returns :TRUE on success and FALSE on Failure. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ +/* XXX - this is nothing like the original function - not sure exactly what the purpose is for this quite yet */ -static Bool -GXSetMode(ScrnInfoPtr pScrni, DisplayModePtr pMode) +static void +GXAdjustFrame(int scrnIndex, int x, int y, int flags) { - int flags; - static char *quals[4] = { - " +hsync +vsync", " -hsync +vsync", " +hsync -vsync", " -hsync -vsync" - }; - GeodeRec *pGeode = GEODEPTR(pScrni); - - gfx_wait_until_idle(); - /* disable video */ - gx_disable_dac_power(pScrni); - - /* unsigned int compOffset, compPitch, compSize; */ - DEBUGMSG(1, (0, X_INFO, "GXSetMode %p %p %p %p %p\n", - gfx_virt_regptr, gfx_virt_gpptr, - gfx_virt_spptr, gfx_virt_vidptr, gfx_virt_fbptr)); - - /* Set the VT semaphore */ - pScrni->vtSema = TRUE; - - /* The timing will be adjusted later */ - flags = 0; - if ((pMode->Flags & V_NHSYNC) != 0) - flags |= 1; - - if ((pMode->Flags & V_NVSYNC) != 0) - flags |= 2; - - DEBUGMSG(1, (0, X_PROBED, - "Setting mode %dx%d %0.3f %d %d %d %d %d %d %d %d%s\n", - pMode->CrtcHDisplay, pMode->CrtcVDisplay, - pMode->SynthClock / 1000.0, pMode->CrtcHDisplay, - pMode->CrtcHSyncStart, pMode->CrtcHSyncEnd, pMode->CrtcHTotal, - pMode->CrtcVDisplay, pMode->CrtcVSyncStart, pMode->CrtcVSyncEnd, - pMode->CrtcVTotal, quals[flags])); - DEBUGMSG(1, (0, X_INFO, "Set display mode: %dHz Pitch %d\n", - GXGetRefreshRate(pMode), pGeode->Pitch)); - - /* TV not selected */ - DEBUGMSG(1, (0, X_PROBED, "Setting Display for CRT or TFT\n")); - if (pGeode->CustomMode != 0) { - DEBUGMSG(1, (0, X_PROBED, "Setting Custom mode\n")); - GFX(set_display_timings(pScrni->bitsPerPixel, flags, - pMode->CrtcHDisplay, pMode->CrtcHBlankStart, - pMode->CrtcHSyncStart, pMode->CrtcHSyncEnd, - pMode->CrtcHBlankEnd, pMode->CrtcHTotal, - pMode->CrtcVDisplay, pMode->CrtcVBlankStart, - pMode->CrtcVSyncStart, pMode->CrtcVSyncEnd, - pMode->CrtcVBlankEnd, pMode->CrtcVTotal, - (int)((pMode->SynthClock / 1000.0) * 0x10000))); - } else if (pGeode->Panel != 0) { - DEBUGMSG(0, (0, X_PROBED, "Setting Display for TFT\n")); - DEBUGMSG(1, (0, X_PROBED, "Restore Panel %d %d %d %d %d\n", - pGeode->FPBX, pGeode->FPBY, - pMode->CrtcHDisplay, - pMode->CrtcVDisplay, pScrni->bitsPerPixel)); - - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "FP Bios %d\n", - pGeode->Panel)); - GFX(set_fixed_timings(pGeode->FPBX, pGeode->FPBY, - pMode->CrtcHDisplay, - pMode->CrtcVDisplay, pScrni->bitsPerPixel)); - } else { - /* display is crt */ - DEBUGMSG(1, (0, X_PROBED, - "Setting Display for CRT %dx%d-%d@%d\n", - pMode->CrtcHDisplay, pMode->CrtcVDisplay, - pScrni->bitsPerPixel, GXGetRefreshRate(pMode))); - GFX(set_display_mode(pMode->CrtcHDisplay, pMode->CrtcVDisplay, - pScrni->bitsPerPixel, GXGetRefreshRate(pMode))); - - /* adjust the pitch */ - } + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; + GeodeRec *pGeode = GEODEPTR(pScrni); + unsigned long offset; - /* enable crt */ - GFX(set_crt_enable(CRT_ENABLE)); - GFX(set_display_pitch(pGeode->Pitch)); - GFX(set_display_offset(0L)); - GFX(wait_vertical_blank()); - - DEBUGMSG(1, (0, X_PROBED, "Display mode set\n")); - /* enable compression if option selected */ - if (pGeode->Compression) { - DEBUGMSG(1, (0, X_PROBED, "Compression mode set %d\n", - pGeode->Compression)); - /* set the compression parameters,and it will be turned on later. */ - gx_set_DvLineSize(pGeode->Pitch); - - gfx_set_compression_offset(pGeode->CBOffset); - gfx_set_compression_pitch(pGeode->CBPitch); - gfx_set_compression_size(pGeode->CBSize); - - /* set the compression buffer, all parameters already set */ - gfx_set_compression_enable(1); - } - - if (pGeode->HWCursor) { - /* Load blank cursor */ - GXLoadCursorImage(pScrni, NULL); - GFX(set_cursor_position(pGeode->CursorStartOffset, 0, 0, 0, 0)); - GFX(set_cursor_enable(1)); - } else { - DEBUGMSG(1,(0, X_INFO, "GXRestore ... ")); - GXRestore(pScrni); - DEBUGMSG(1,(0, X_INFO, "done.\n")); - } - - DEBUGMSG(1, (0, X_INFO, "done.\n")); - /* Reenable the hardware cursor after the mode switch */ - if (pGeode->HWCursor == TRUE) { - DEBUGMSG(1, (0, X_INFO, "GXShowCursor ... ")); - GXShowCursor(pScrni); - DEBUGMSG(1, (0, X_INFO, "done.\n")); - } + offset = + pGeode->FBOffset + y * pGeode->Pitch + + x * (pScrni->bitsPerPixel >> 3); - if (!pGeode->Panel) - GFX(set_display_offset(pGeode->PrevDisplayOffset)); - - /* Restore the contents in the screen info */ - DEBUGMSG(1, (0, X_INFO, "After setting the mode\n")); - switch (pGeode->Rotate) { - case 1: - case 3: - pGeode->HDisplay = pMode->VDisplay; - pGeode->VDisplay = pMode->HDisplay; - break; - default: - pGeode->HDisplay = pMode->HDisplay; - pGeode->VDisplay = pMode->VDisplay; - break; - } - gx_enable_dac_power(pScrni); - return TRUE; + gfx_set_display_offset(offset); } -/*---------------------------------------------------------------------------- - * GXEnterGraphics. - * - * Description :This function will intiallize the displaytiming - structure for nextmode and switch to VGA mode. - * - * Parameters. - * pScrn :Screen information will be stored in this structure. - * pScrni :Pointer to the screenInfo structure. - * - * Returns :TRUE on success and FALSE on Failure. - * - * Comments :gfx_vga_mode_switch() will start and end the - * switching based on the arguments 0 or 1.soft_vga - * is disabled in this function. - *---------------------------------------------------------------------------- - */ static Bool -GXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) +GXSetVideoMode(ScrnInfoPtr pScrni, DisplayModePtr pMode) { - GeodeRec *pGeode = GEODEPTR(pScrni); - - gfx_wait_until_idle(); - - DEBUGMSG(1, (0, X_INFO, "GXEnterGraphics(1)!\n")); - - /* Save CRT State */ - pGeode->FBgfxdisplaytiming.dwDotClock = gfx_get_clock_frequency(); - pGeode->FBgfxdisplaytiming.wPitch = gfx_get_display_pitch(); - pGeode->FBgfxdisplaytiming.wBpp = gfx_get_display_bpp(); - pGeode->FBgfxdisplaytiming.wHTotal = gfx_get_htotal(); - pGeode->FBgfxdisplaytiming.wHActive = gfx_get_hactive(); - pGeode->FBgfxdisplaytiming.wHSyncStart = gfx_get_hsync_start(); - pGeode->FBgfxdisplaytiming.wHSyncEnd = gfx_get_hsync_end(); - pGeode->FBgfxdisplaytiming.wHBlankStart = gfx_get_hblank_start(); - pGeode->FBgfxdisplaytiming.wHBlankEnd = gfx_get_hblank_end(); - pGeode->FBgfxdisplaytiming.wVTotal = gfx_get_vtotal(); - pGeode->FBgfxdisplaytiming.wVActive = gfx_get_vactive(); - pGeode->FBgfxdisplaytiming.wVSyncStart = gfx_get_vsync_start(); - pGeode->FBgfxdisplaytiming.wVSyncEnd = gfx_get_vsync_end(); - pGeode->FBgfxdisplaytiming.wVBlankStart = gfx_get_vblank_start(); - pGeode->FBgfxdisplaytiming.wVBlankEnd = gfx_get_vblank_end(); - pGeode->FBgfxdisplaytiming.wPolarity = gfx_get_sync_polarities(); - - /* Save Display offset */ - pGeode->FBDisplayOffset = gfx_get_display_offset(); - - DEBUGMSG(1, (0, X_INFO, "GXEnterGraphics(2)!\n")); - - if (pGeode->useVGA) { - vgaHWPtr pvgaHW = VGAHWPTR(pScrni); - pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); - } - - /* Save the current Compression state */ - pGeode->FBCompressionEnable = gfx_get_compression_enable(); - pGeode->FBCompressionOffset = gfx_get_compression_offset(); - pGeode->FBCompressionPitch = gfx_get_compression_pitch(); - pGeode->FBCompressionSize = gfx_get_compression_size(); + GeodeRec *pGeode = GEODEPTR(pScrni); + int flags = 0; - /* Save Cursor offset */ - pGeode->FBCursorOffset = gfx_get_cursor_offset(); - -#if defined(PNL_SUP) - /* Save the Panel state */ - DEBUGMSG(1, (0, X_INFO, "GXEnterGraphics(3)!\n")); - Pnl_SavePanelState(); -#endif + pScrni->vtSema = TRUE; - /* only if comming from VGA */ - if (pGeode->useVGA && pGeode->FBVGAActive) { - unsigned short sequencer; - vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + gx_disable_dac_power(); - /* Map VGA aperture */ - if (!vgaHWMapMem(pScrni)) - return FALSE; + if (pMode->Flags & V_NHSYNC) + flags |= 1; + if (pMode->Flags & V_NVSYNC) + flags |= 2; - /* Unlock VGA registers */ - vgaHWUnlock(pvgaHW); + /* XXX Question - why even use set_display_mode at all - shouldn't the + * mode timings be the same that we advertise? */ - /* Save the current state and setup the current mode */ - vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); + /* Only use the panel mode for built in modes */ - /* DISABLE VGA SEQUENCER */ - /* This allows the VGA state machine to terminate. We must delay */ - /* such that there are no pending MBUS requests. */ + if ((pMode->type && pMode->type != M_T_USERDEF) && pGeode->Panel) { + GFX(set_fixed_timings(pGeode->PanelX, pGeode->PanelY, + pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pScrni->bitsPerPixel)); + } else { + if (pGeode->Panel) + GFX(set_panel_present(pGeode->PanelX, pGeode->PanelY, + pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pScrni->bitsPerPixel)); + + GFX(set_display_timings(pScrni->bitsPerPixel, flags, + pMode->CrtcHDisplay, pMode->CrtcHBlankStart, + pMode->CrtcHSyncStart, pMode->CrtcHSyncEnd, + pMode->CrtcHBlankEnd, pMode->CrtcHTotal, + pMode->CrtcVDisplay, pMode->CrtcVBlankStart, + pMode->CrtcVSyncStart, pMode->CrtcVSyncEnd, + pMode->CrtcVBlankEnd, pMode->CrtcVTotal, + (int)((pMode->SynthClock / 1000.0) * 0x10000))); + } + + GFX(set_crt_enable(CRT_ENABLE)); + GFX(set_display_pitch(pGeode->displayPitch)); + GFX(set_display_offset(0L)); + GFX(wait_vertical_blank()); + + if (pGeode->Compression) { + GXSetDvLineSize(pGeode->Pitch); + + gfx_set_compression_offset(pGeode->CBData.compression_offset); + gfx_set_compression_pitch(GX_CB_PITCH); + gfx_set_compression_size(GX_CB_SIZE); + + gfx_set_compression_enable(1); + } + + if (pGeode->HWCursor && !(pMode->Flags & V_DBLSCAN)) { + GXLoadCursorImage(pScrni, NULL); + GFX(set_cursor_position(pGeode->CursorStartOffset, 0, 0, 0, 0)); + GXShowCursor(pScrni); + } else { + GFX(set_cursor_enable(0)); + pGeode->HWCursor = FALSE; + } + + GXAdjustFrame(pScrni->scrnIndex, pScrni->frameX0, pScrni->frameY0, 0); + gx_enable_dac_power(); + + return TRUE; +} - gfx_outb(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_CLK_MODE); - sequencer = gfx_inb(MDC_SEQUENCER_DATA); - sequencer |= MDC_CLK_MODE_SCREEN_OFF; - gfx_outb(MDC_SEQUENCER_DATA, sequencer); +static Bool +GXSwitchMode(int index, DisplayModePtr pMode, int flags) +{ + ScrnInfoPtr pScrni = xf86Screens[index]; + GeodeRec *pGeode = GEODEPTR(pScrni); + int ret = TRUE; + int rotate; - gfx_delay_milliseconds(1); + /* Syn the engine and shutdown the DAC momentarily */ - /* BLANK THE VGA DISPLAY */ - gfx_outw(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_RESET); - sequencer = gfx_inb(MDC_SEQUENCER_DATA); - sequencer &= ~MDC_RESET_VGA_DISP_ENABLE; - gfx_outb(MDC_SEQUENCER_DATA, sequencer); + gfx_wait_until_idle(); - gfx_delay_milliseconds(1); - } + /* Set up the memory for the new mode */ + rotate = GXGetRotation(pScrni->pScreen); + ret = GXAllocateMemory(pScrni->pScreen, pScrni, rotate); - gx_clear_fb(pScrni); + if (ret) { + if (pGeode->curMode != pMode) + ret = GXSetVideoMode(pScrni, pMode); + } - if (!GXSetMode(pScrni, pScrni->currentMode)) { - return FALSE; - } + if (ret) + ret = GXRotate(pScrni, pMode); - gx_enable_dac_power(pScrni); - DEBUGMSG(1, (0, X_INFO, "GXEnterGraphics(4)!\n")); - return TRUE; -} + /* Go back the way it was */ -void -gx_enable_dac_power(ScrnInfoPtr pScrni) -{ - /* enable the DAC POWER */ - gfx_write_vid32(RCDF_VID_MISC, - gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH); -} + if (ret == FALSE) { + if (!GXSetVideoMode(pScrni, pGeode->curMode)) + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Could not restore the previous mode\n"); + } else + pGeode->curMode = pMode; -void -gx_disable_dac_power(ScrnInfoPtr pScrni) -{ - /* disable the DAC POWER */ - gfx_write_vid32(RCDF_VID_MISC, - RCDF_DAC_POWER_DOWN | RCDF_ANALOG_POWER_DOWN | - (gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH)); + return ret; } -/*---------------------------------------------------------------------------- - * GXLeaveGraphics: - * - * Description :This function will restore the displaymode parameters - * and switches the VGA mode - * - * Parameters. - * pScrn :Screen information will be stored in this structure. - * pScrni :Pointer to the screenInfo structure. - * - * Returns :none. - * - * Comments : gfx_vga_mode_switch() will start and end the switching - * based on the arguments 0 or 1.soft_vga is disabled in - * this function. - *---------------------------------------------------------------------------- - */ static void GXLeaveGraphics(ScrnInfoPtr pScrni) { - GeodeRec *pGeode = GEODEPTR(pScrni); - - gfx_wait_until_idle(); - - /* Restore VG registers */ - gfx_set_display_timings(pGeode->FBgfxdisplaytiming.wBpp, - pGeode->FBgfxdisplaytiming.wPolarity, - pGeode->FBgfxdisplaytiming.wHActive, - pGeode->FBgfxdisplaytiming.wHBlankStart, - pGeode->FBgfxdisplaytiming.wHSyncStart, - pGeode->FBgfxdisplaytiming.wHSyncEnd, - pGeode->FBgfxdisplaytiming.wHBlankEnd, - pGeode->FBgfxdisplaytiming.wHTotal, - pGeode->FBgfxdisplaytiming.wVActive, - pGeode->FBgfxdisplaytiming.wVBlankStart, - pGeode->FBgfxdisplaytiming.wVSyncStart, - pGeode->FBgfxdisplaytiming.wVSyncEnd, - pGeode->FBgfxdisplaytiming.wVBlankEnd, - pGeode->FBgfxdisplaytiming.wVTotal, - pGeode->FBgfxdisplaytiming.dwDotClock); - - gfx_set_compression_enable(0); - - /* Restore the previous Compression state */ - if (pGeode->FBCompressionEnable) { - gfx_set_compression_offset(pGeode->FBCompressionOffset); - gfx_set_compression_pitch(pGeode->FBCompressionPitch); - gfx_set_compression_size(pGeode->FBCompressionSize); - gfx_set_compression_enable(1); - } - - gfx_set_display_pitch(pGeode->FBgfxdisplaytiming.wPitch); - - gfx_set_display_offset(pGeode->FBDisplayOffset); - - /* Restore Cursor */ - gfx_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0); - - if (pGeode->useVGA) { + GeodeRec *pGeode = GEODEPTR(pScrni); + + gfx_wait_until_idle(); + + /* Restore VG registers */ + gfx_set_display_timings(pGeode->FBgfxdisplaytiming.wBpp, + pGeode->FBgfxdisplaytiming.wPolarity, + pGeode->FBgfxdisplaytiming.wHActive, + pGeode->FBgfxdisplaytiming.wHBlankStart, + pGeode->FBgfxdisplaytiming.wHSyncStart, + pGeode->FBgfxdisplaytiming.wHSyncEnd, + pGeode->FBgfxdisplaytiming.wHBlankEnd, + pGeode->FBgfxdisplaytiming.wHTotal, + pGeode->FBgfxdisplaytiming.wVActive, + pGeode->FBgfxdisplaytiming.wVBlankStart, + pGeode->FBgfxdisplaytiming.wVSyncStart, + pGeode->FBgfxdisplaytiming.wVSyncEnd, + pGeode->FBgfxdisplaytiming.wVBlankEnd, + pGeode->FBgfxdisplaytiming.wVTotal, + pGeode->FBgfxdisplaytiming.dwDotClock); + + gfx_set_compression_enable(0); + + /* Restore the previous Compression state */ + if (pGeode->FBCompressionEnable) { + gfx_set_compression_offset(pGeode->FBCompressionOffset); + gfx_set_compression_pitch(pGeode->FBCompressionPitch); + gfx_set_compression_size(pGeode->FBCompressionSize); + gfx_set_compression_enable(1); + } + + gfx_set_display_pitch(pGeode->FBgfxdisplaytiming.wPitch); + + gfx_set_display_offset(pGeode->FBDisplayOffset); + + /* Restore Cursor */ + gfx_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0); + + if (pGeode->useVGA) { pGeode->vesa->pInt->num = 0x10; pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode; pGeode->vesa->pInt->bx = 0; xf86ExecX86int10(pGeode->vesa->pInt); gfx_delay_milliseconds(3); - } + } - GXRestore(pScrni); + GXRestore(pScrni); - gx_enable_dac_power(pScrni); + gx_enable_dac_power(); } -/*---------------------------------------------------------------------------- - * GXCloseScreen. - * - * Description :This function will restore the original mode - * and also it unmap video memory - * - * Parameters. - * ScrnIndex :Screen index value of the screen will be closed. - * pScrn :Pointer to the screen structure. - * - * - * Returns :TRUE on success and FALSE on Failure. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ static Bool GXCloseScreen(int scrnIndex, ScreenPtr pScrn) { - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - GeodeRec *pGeode = GEODEPTR(pScrni); + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; + GeodeRec *pGeode = GEODEPTR(pScrni); - if (pGeode->ShadowPtr) - xfree(pGeode->ShadowPtr); + if (pScrni->vtSema) + GXLeaveGraphics(pScrni); - DEBUGMSG(0, (scrnIndex, X_PROBED, "GXCloseScreen %d\n", pScrni->vtSema)); - if (pScrni->vtSema) - GXLeaveGraphics(pScrni); + if (pGeode->AccelInfoRec) + XAADestroyInfoRec(pGeode->AccelInfoRec); - if (pGeode->AccelInfoRec) - XAADestroyInfoRec(pGeode->AccelInfoRec); + if (pGeode->AccelImageWriteBuffers) { + xfree(pGeode->AccelImageWriteBuffers[0]); + xfree(pGeode->AccelImageWriteBuffers); + pGeode->AccelImageWriteBuffers = NULL; + } - if (pGeode->AccelImageWriteBuffers) { -#if GX_USE_OFFSCRN_MEM - xfree(pGeode->AccelImageWriteBuffers[0]); -#endif - xfree(pGeode->AccelImageWriteBuffers); - pGeode->AccelImageWriteBuffers = NULL; - } + if (pGeode->AccelColorExpandBuffers) { + xfree(pGeode->AccelColorExpandBuffers); + pGeode->AccelColorExpandBuffers = NULL; + } - if (pGeode->AccelColorExpandBuffers) { - xfree(pGeode->AccelColorExpandBuffers); - pGeode->AccelColorExpandBuffers = NULL; - } + if (pGeode->pExa) { + exaDriverFini(pScrn); + xfree(pGeode->pExa); + pGeode->pExa = NULL; + } -#ifdef XF86EXA - if (pGeode->pExa) { - exaDriverFini(pScrn); - xfree(pGeode->pExa); - pGeode->pExa = NULL; - } + pScrni->vtSema = FALSE; + + GXUnmapMem(pScrni); + + + pScrni->PointerMoved = pGeode->PointerMoved; + pScrn->CloseScreen = pGeode->CloseScreen; + + if (pScrn->CloseScreen) + return (*pScrn->CloseScreen)(scrnIndex, pScrn); + + return TRUE; +} + +static Bool +GXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + + if (!GXMapMem(pScrni)) + return FALSE; + + gfx_wait_until_idle(); + + /* Save off the current state (should this be somewhere else)? */ + + pGeode->FBgfxdisplaytiming.dwDotClock = gfx_get_clock_frequency(); + pGeode->FBgfxdisplaytiming.wPitch = gfx_get_display_pitch(); + pGeode->FBgfxdisplaytiming.wBpp = gfx_get_display_bpp(); + pGeode->FBgfxdisplaytiming.wHTotal = gfx_get_htotal(); + pGeode->FBgfxdisplaytiming.wHActive = gfx_get_hactive(); + pGeode->FBgfxdisplaytiming.wHSyncStart = gfx_get_hsync_start(); + pGeode->FBgfxdisplaytiming.wHSyncEnd = gfx_get_hsync_end(); + pGeode->FBgfxdisplaytiming.wHBlankStart = gfx_get_hblank_start(); + pGeode->FBgfxdisplaytiming.wHBlankEnd = gfx_get_hblank_end(); + pGeode->FBgfxdisplaytiming.wVTotal = gfx_get_vtotal(); + pGeode->FBgfxdisplaytiming.wVActive = gfx_get_vactive(); + pGeode->FBgfxdisplaytiming.wVSyncStart = gfx_get_vsync_start(); + pGeode->FBgfxdisplaytiming.wVSyncEnd = gfx_get_vsync_end(); + pGeode->FBgfxdisplaytiming.wVBlankStart = gfx_get_vblank_start(); + pGeode->FBgfxdisplaytiming.wVBlankEnd = gfx_get_vblank_end(); + pGeode->FBgfxdisplaytiming.wPolarity = gfx_get_sync_polarities(); + + pGeode->FBDisplayOffset = gfx_get_display_offset(); + + if (pGeode->useVGA) { + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); + } + + pGeode->FBCompressionEnable = gfx_get_compression_enable(); + pGeode->FBCompressionOffset = gfx_get_compression_offset(); + pGeode->FBCompressionPitch = gfx_get_compression_pitch(); + pGeode->FBCompressionSize = gfx_get_compression_size(); + +#ifdef PNL_SUP + Pnl_SavePanelState(); #endif - pScrni->vtSema = FALSE; + /* Turn off the VGA */ - GXUnmapMem(pScrni); + if (pGeode->useVGA && pGeode->FBVGAActive) { + unsigned short sequencer; + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); - if (pGeode && (pScrn->CloseScreen = pGeode->CloseScreen)) { - pGeode->CloseScreen = NULL; - return ((*pScrn->CloseScreen) (scrnIndex, pScrn)); - } + /* Map VGA aperture */ + if (!vgaHWMapMem(pScrni)) + return FALSE; - return TRUE; + /* Unlock VGA registers */ + vgaHWUnlock(pvgaHW); + + /* Save the current state and setup the current mode */ + vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); + + /* DISABLE VGA SEQUENCER */ + /* This allows the VGA state machine to terminate. We must delay */ + /* such that there are no pending MBUS requests. */ + + gfx_outb(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_CLK_MODE); + sequencer = gfx_inb(MDC_SEQUENCER_DATA); + sequencer |= MDC_CLK_MODE_SCREEN_OFF; + gfx_outb(MDC_SEQUENCER_DATA, sequencer); + + gfx_delay_milliseconds(1); + + /* BLANK THE VGA DISPLAY */ + gfx_outw(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_RESET); + sequencer = gfx_inb(MDC_SEQUENCER_DATA); + sequencer &= ~MDC_RESET_VGA_DISP_ENABLE; + gfx_outb(MDC_SEQUENCER_DATA, sequencer); + + gfx_delay_milliseconds(1); + } + + /* Set up the memory */ + /* XXX - FIXME - when we alow inital rotation, it should be here */ + GXAllocateMemory(pScrn, pScrni, pGeode->rotation); + + /* Clear the framebuffer */ + memset(pGeode->FBBase + pGeode->displayOffset, 0, pGeode->displaySize); + + /* Set up the video mode */ + GXSetVideoMode(pScrni, pScrni->currentMode); + pGeode->curMode = pScrni->currentMode; + + return TRUE; +} + +static void +GXLoadPalette(ScrnInfoPtr pScrni, + int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) +{ + int i, index, color; + + for (i = 0; i < numColors; i++) { + index = indizes[i] & 0xFF; + color = (((unsigned long)(colors[index].red & 0xFF)) << 16) | + (((unsigned long)(colors[index].green & 0xFF)) << 8) | + ((unsigned long)(colors[index].blue & 0xFF)); + + GFX(set_display_palette_entry(index, color)); + } } #ifdef DPMSExtension static void GXPanelPower(int enable) { - unsigned long power = READ_VID32(RCDF_POWER_MANAGEMENT); + unsigned long power = READ_VID32(RCDF_POWER_MANAGEMENT); - if (enable != 0) - power |= RCDF_PM_PANEL_POWER_ON; - else - power &= ~RCDF_PM_PANEL_POWER_ON; + if (enable != 0) + power |= RCDF_PM_PANEL_POWER_ON; + else + power &= ~RCDF_PM_PANEL_POWER_ON; - WRITE_VID32(RCDF_POWER_MANAGEMENT, power); + WRITE_VID32(RCDF_POWER_MANAGEMENT, power); } -/*---------------------------------------------------------------------------- - * GXDPMSSet. - * - * Description :This function sets geode into Power Management - * Signalling mode. - * - * Parameters. - * pScrni :Pointer to screen info strucrure. - * mode :Specifies the power management mode. - * - * Returns :none. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ static void GXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags) { - GeodeRec *pGeode; + GeodeRec *pGeode; - pGeode = GEODEPTR(pScrni); + pGeode = GEODEPTR(pScrni); - DEBUGMSG(1, (0, X_INFO, "GXDPMSSet! %d %d\n", mode, flags)); + if (!pScrni->vtSema) + return; - /* Check if we are actively controlling the display */ - if (!pScrni->vtSema) { - ErrorF("GXDPMSSet called when we not controlling the VT!\n"); - return; - } - - switch (mode) { - case DPMSModeOn: - /* Screen: On; HSync: On; VSync: On */ - GFX(set_crt_enable(CRT_ENABLE)); + switch (mode) { + case DPMSModeOn: + /* Screen: On; HSync: On; VSync: On */ + GFX(set_crt_enable(CRT_ENABLE)); #if defined(PNL_SUP) - if (pGeode->Panel) { - Pnl_PowerUp(); - GXPanelPower(1); - } + if (pGeode->Panel) { + Pnl_PowerUp(); + GXPanelPower(1); + } #endif - break; + break; - case DPMSModeStandby: - /* Screen: Off; HSync: Off; VSync: On */ - GFX(set_crt_enable(CRT_STANDBY)); + case DPMSModeStandby: + /* Screen: Off; HSync: Off; VSync: On */ + GFX(set_crt_enable(CRT_STANDBY)); #if defined(PNL_SUP) - if (pGeode->Panel) { - Pnl_PowerDown(); - GXPanelPower(0); - } + if (pGeode->Panel) { + Pnl_PowerDown(); + GXPanelPower(0); + } #endif - break; + break; - case DPMSModeSuspend: - /* Screen: Off; HSync: On; VSync: Off */ - GFX(set_crt_enable(CRT_SUSPEND)); + case DPMSModeSuspend: + /* Screen: Off; HSync: On; VSync: Off */ + GFX(set_crt_enable(CRT_SUSPEND)); #if defined(PNL_SUP) - if (pGeode->Panel) { - Pnl_PowerDown(); - GXPanelPower(0); - } + if (pGeode->Panel) { + Pnl_PowerDown(); + GXPanelPower(0); + } #endif - break; + break; - case DPMSModeOff: - /* Screen: Off; HSync: Off; VSync: Off */ - GFX(set_crt_enable(CRT_DISABLE)); + case DPMSModeOff: + /* Screen: Off; HSync: Off; VSync: Off */ + GFX(set_crt_enable(CRT_DISABLE)); #if defined(PNL_SUP) - if (pGeode->Panel) { - Pnl_PowerDown(); - GXPanelPower(0); - } -#endif - break; + if (pGeode->Panel) { + Pnl_PowerDown(); + GXPanelPower(0); } +#endif + break; + } } #endif -/*---------------------------------------------------------------------------- - * GXScreenInit. - * - * Description :This function will be called at the each ofserver - * generation. - * - * Parameters. - * scrnIndex :Specfies the screenindex value during generation. - * pScrn :Pointer to screen info strucrure. - * argc :parameters for command line arguments count - * argv :command line arguments if any it is not used. - * - * Returns :none. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ static Bool -GXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) +GXCreateScreenResources(ScreenPtr pScreen) { - int i, l, bytpp, size, fbsize, fboffset, fbavail; - int pitch, displayWidth, virtualX, virtualY; - int HDisplay, VDisplay, maxHDisplay, maxVDisplay, maxX, maxY; - unsigned char *FBStart; - unsigned char **ap, *bp; - DisplayModePtr p; - GeodeRec *pGeode; - VisualPtr visual; - BoxRec AvailBox; - RegionRec OffscreenRegion; - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - Bool Inited = FALSE; - - pGeode = GXGetRec(pScrni); - - if (pGeode->useVGA) { - if (!vgaHWGetHWRec(pScrni)) - return FALSE; - if (!vgaHWMapMem(pScrni)) - return FALSE; + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); - vgaHWGetIOBase(VGAHWPTR(pScrni)); - } + pScreen->CreateScreenResources = pGeode->CreateScreenResources; + if (!(*pScreen->CreateScreenResources) (pScreen)) + return FALSE; - if (!GXMapMem(pScrni)) - return FALSE; + if (xf86LoaderCheckSymbol("GXRandRSetConfig") + && pGeode->rotation != RR_Rotate_0) { + Rotation(*GXRandRSetConfig) (ScreenPtr pScreen, Rotation rr, int rate, + RRScreenSizePtr pSize) = NULL; + RRScreenSize p; + Rotation requestedRotation = pGeode->rotation; - /* If compression is not turned on - adjust the pitch to be linear */ - if (pGeode->Compression) - pGeode->Pitch = GXCalculatePitchBytes(pScrni->virtualX, pScrni->bitsPerPixel); - else - pGeode->Pitch = ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3); + pGeode->rotation = RR_Rotate_0; - pGeode->AccelPitch = pGeode->Pitch; - bytpp = (pScrni->bitsPerPixel + 7) / 8; + /* Just setup enough for an initial rotate */ - /* start of framebuffer for accels */ - fboffset = 0; - /* 0x4000 for gfx_gu2_scratch_buffer */ - fbavail = pGeode->FBAvail - 0x4000; + p.width = pScreen->width; + p.height = pScreen->height; + p.mmWidth = pScreen->mmWidth; + p.mmHeight = pScreen->mmHeight; -#ifdef V4L2_VIDEO_BFR_SZ - fbavail -= V4L2_VIDEO_BFR_SZ; -#endif + GXRandRSetConfig = LoaderSymbol("GXRandRSetConfig"); + if (GXRandRSetConfig) { + pGeode->starting = TRUE; + (*GXRandRSetConfig) (pScreen, requestedRotation, 0, &p); + pGeode->starting = FALSE; + } + } - /* allocate display frame buffer at zero offset */ - fbsize = pScrni->virtualY * pGeode->Pitch; - pGeode->FBSize = fbsize; + return TRUE; +} - pGeode->CursorSize = 16 * 64; /* 64x64 */ - pGeode->CursorStartOffset = 0; +static Bool +GXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) +{ + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; + GeodeRec *pGeode = GEODEPTR(pScrni); + XF86ModReqInfo shadowReq; + int maj, min, ret, rotate; - DEBUGMSG(1, (scrnIndex, X_PROBED, "%d %d %d\n", - pScrni->virtualX, pScrni->bitsPerPixel, pGeode->Pitch)); + pGeode->starting = TRUE; - HDisplay = pScrni->currentMode->HDisplay; - VDisplay = pScrni->currentMode->VDisplay; - pGeode->orig_virtX = pScrni->virtualX; - pGeode->orig_virtY = pScrni->virtualY; + /* If we are using VGA then go ahead and map the memory */ - p = pScrni->modes; - maxHDisplay = p->HDisplay; - maxVDisplay = p->VDisplay; - while ((p = p->next) != pScrni->modes) { - if (maxHDisplay < p->HDisplay) - maxHDisplay = p->HDisplay; + if (pGeode->useVGA) { - if (maxVDisplay < p->VDisplay) - maxVDisplay = p->VDisplay; - } + if (!vgaHWMapMem(pScrni)) + return FALSE; - DEBUGMSG(1, (scrnIndex, X_PROBED, "maxHDisplay %d maxVDisplay %d\n", - maxHDisplay, maxVDisplay)); - - switch (pGeode->Rotate) { - case 1: - case 3: - pGeode->HDisplay = VDisplay; - pGeode->VDisplay = HDisplay; - virtualX = pScrni->virtualY; - virtualY = pScrni->virtualX; - maxX = maxVDisplay; - maxY = maxHDisplay; - break; - default: - pGeode->HDisplay = HDisplay; - pGeode->VDisplay = VDisplay; - virtualX = pScrni->virtualX; - virtualY = pScrni->virtualY; - maxX = maxHDisplay; - maxY = maxVDisplay; - break; + vgaHWGetIOBase(VGAHWPTR(pScrni)); + } + + if (!pGeode->NoAccel) { + + if (pGeode->useEXA) { + + if (!(pGeode->pExa = xnfcalloc(sizeof(ExaDriverRec), 1))) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Couldn't allocate the EXA structure.\n"); + pGeode->NoAccel = TRUE; + } else { + ExaDriverPtr pExa = pGeode->pExa; + + /* THis is set in GXAllocMem */ + pExa->memoryBase = 0; + + /* This is set in GXAllocateMemory */ + pExa->memorySize = 0; + + pExa->pixmapOffsetAlign = 32; + pExa->pixmapPitchAlign = 32; + pExa->flags = EXA_OFFSCREEN_PIXMAPS; + pExa->maxX = pGeode->maxWidth - 1; + pExa->maxY = pGeode->maxHeight - 1; + } + } else { + pGeode->AccelImageWriteBuffers = + xcalloc(sizeof(pGeode->AccelImageWriteBuffers[0]), + pGeode->NoOfImgBuffers); + pGeode->AccelColorExpandBuffers = + xcalloc(sizeof(pGeode->AccelColorExpandBuffers[0]), + pGeode->NoOfColorExpandLines); } + } - /* shadow may be first in FB, since accels render there */ - - pGeode->ShadowPtr = NULL; - if (pGeode->ShadowFB) { - if (!pGeode->PointerMoved) { - pGeode->PointerMoved = pScrni->PointerMoved; - pScrni->PointerMoved = GXPointerMoved; - } - - if (pGeode->ShadowPtr == NULL) { - pGeode->ShadowPitch = - BitmapBytePad(pScrni->bitsPerPixel * virtualX); - size = pGeode->ShadowPitch * virtualY; - pGeode->ShadowPtr = xalloc(size); - if (pGeode->ShadowPtr != NULL) { - pGeode->ShadowSize = size; - if (!pGeode->NoAccel) { - pGeode->NoAccel = TRUE; - pGeode->HWCursor = FALSE; - xf86DrvMsg(scrnIndex, X_ERROR, - "Shadow FB offscreen, All Accels disabled\n"); - } - - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Shadow FB, No offscreen Memory, disabled\n"); - pGeode->ShadowFB = FALSE; - pGeode->Rotate = 0; - pGeode->HDisplay = HDisplay; - pGeode->VDisplay = VDisplay; - virtualX = pScrni->virtualX; - virtualY = pScrni->virtualY; - } - } - } + /* XXX FIXME - Take down any of the structures on failure? */ - if (pGeode->ShadowPtr != NULL) { - displayWidth = pGeode->ShadowPitch / bytpp; - FBStart = pGeode->ShadowPtr; - DEBUGMSG(1, (0, X_PROBED, "Shadow %p \n", FBStart)); - } else { - displayWidth = pGeode->Pitch / bytpp; - FBStart = pGeode->FBBase; - DEBUGMSG(1, (0, X_PROBED, "FBStart %p \n", FBStart)); - } + if (!GXEnterGraphics(pScrn, pScrni)) + return FALSE; - DEBUGMSG(1, (0, X_PROBED, "FB display %X size %X \n", fboffset, fbsize)); - pGeode->FBOffset = fboffset; /* offset of display framebuffer */ - pScrni->fbOffset = fboffset; - fboffset += fbsize; - fbavail -= fbsize; - - if (pGeode->Compression) { /* Compression enabled */ - pGeode->CBPitch = 512 + 32; - pGeode->CBSize = 512 + 32; - size = maxY * pGeode->CBPitch; - DEBUGMSG(1, (0, X_PROBED, "CB %#x size %#x (%d*%d)\n", fboffset, size, - maxY, pGeode->CBPitch)); - if (size <= fbavail) { - pGeode->CBOffset = fboffset; - fboffset += size; - fbavail -= size; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Compression, No FB Memory, disabled\n"); - pGeode->Compression = FALSE; - } - } + miClearVisualTypes(); + + /* XXX Again - take down anything? */ - if (pGeode->HWCursor) { /* HWCursor enabled */ - size = pGeode->CursorSize; - if (size <= fbavail) { - pGeode->CursorStartOffset = fboffset; - fboffset += size; - fbavail -= size; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "HWCursor, No FB Memory, disabled\n"); - pGeode->HWCursor = FALSE; - } + if (pScrni->bitsPerPixel > 8) { + if (!miSetVisualTypes(pScrni->depth, + TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)) { + return FALSE; } -#if XF86EXA - if (!pGeode->NoAccel && pGeode->useEXA) { /* exa acceleration enabled */ - if (!(pGeode->pExa = xnfcalloc(sizeof(ExaDriverRec), 1))) { - xf86DrvMsg(scrnIndex, X_ERROR, - "No ExaDriverRec Memory, disabled\n"); - pGeode->NoAccel = TRUE; - } else { - if ((size = pGeode->exaBfrSz) > 0 && size <= fbavail) { - pGeode->exaBfrOffset = fboffset; - fboffset += size; - fbavail -= size; - } - } + } else { + if (!miSetVisualTypes(pScrni->depth, + miGetDefaultVisualMask(pScrni->depth), + pScrni->rgbBits, pScrni->defaultVisual)) { + return FALSE; } -#endif + } - if (!pGeode->NoAccel && !pGeode->useEXA) { /* xaa acceleration enabled */ - if (pGeode->NoOfImgBuffers > 0) { - pGeode->AccelImageWriteBuffers = NULL; - pitch = pGeode->AccelPitch; - size = pitch * pGeode->NoOfImgBuffers; -#if !GX_USE_OFFSCRN_MEM - if (size <= fbavail) { - bp = (unsigned char *)pGeode->FBBase + fboffset; - l = sizeof(pGeode->AccelImageWriteBuffers[0]) * - pGeode->NoOfImgBuffers; - ap = (unsigned char **)xalloc(l); - if (ap != NULL) { - for (i = 0; i < pGeode->NoOfImgBuffers; ++i) { - ap[i] = bp; - DEBUGMSG(1, (scrnIndex, X_PROBED, "img line %d %p\n", - i, ap[i])); - bp += pitch; - } - pGeode->AccelImageWriteBuffers = ap; - fboffset += size; - fbavail -= size; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Image Write, No Memory\n"); - } - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No FB Memory\n"); - } -#else - if ((bp = (unsigned char *)xalloc(size)) != NULL) { - ap = xalloc(sizeof(pGeode->AccelImageWriteBuffers[0]) * - pGeode->NoOfImgBuffers); - if (ap != NULL) { - for (i = 0; i < pGeode->NoOfImgBuffers; ++i) { - ap[i] = bp; - DEBUGMSG(1, (scrnIndex, X_PROBED, "img line %d %x\n", - i, ap[i])); - bp += pitch; - } - pGeode->AccelImageWriteBuffers = ap; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Image Write, No Memory\n"); - } - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Image Write, No offscreen Memory\n"); - } -#endif - if (pGeode->AccelImageWriteBuffers == NULL) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Accel Image Write disabled\n"); - pGeode->NoOfImgBuffers = 0; - } - } - - if (pGeode->NoOfColorExpandLines > 0) { - pGeode->AccelColorExpandBuffers = NULL; - pitch = ((pGeode->AccelPitch + 31) >> 5) << 2; - size = pitch * pGeode->NoOfColorExpandLines; - if (size <= fbavail) { - bp = (unsigned char *)pGeode->FBBase + fboffset; - l = sizeof(pGeode->AccelColorExpandBuffers[0]) * - pGeode->NoOfColorExpandLines; - ap = (unsigned char **)xalloc(l); - if (ap != NULL) { - for (i = 0; i < pGeode->NoOfColorExpandLines; ++i) { - ap[i] = bp; - DEBUGMSG(1, (scrnIndex, X_PROBED, "clr line %d %p\n", - i, ap[i])); - bp += pitch; - } - pGeode->AccelColorExpandBuffers = ap; - fboffset += size; - fbavail -= size; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Color Expansion, No Memory\n"); - } - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Color Expansion, No offscreen Memory\n"); - } - if (pGeode->AccelColorExpandBuffers == NULL) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Accel Color Expansion disabled\n"); - pGeode->NoOfColorExpandLines = 0; - } - } - } else { - pGeode->NoOfImgBuffers = 0; - pGeode->AccelImageWriteBuffers = NULL; - pGeode->NoOfColorExpandLines = 0; - pGeode->AccelColorExpandBuffers = NULL; - } + miSetPixmapDepths(); - /* Initialise graphics mode */ - if (!GXEnterGraphics(pScrn, pScrni)) - return FALSE; + /* Point at the visible area to start */ - pScrni->virtualX = virtualX; - pScrni->virtualY = virtualY; + ret = fbScreenInit(pScrn, pGeode->FBBase + pGeode->displayOffset, + pScrni->virtualX, pScrni->virtualY, + pScrni->xDpi, pScrni->yDpi, pGeode->displayWidth, + pScrni->bitsPerPixel); - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(1)!\n")); + if (!ret) + return FALSE; - /* Reset visual list */ - miClearVisualTypes(); - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(2)!\n")); + xf86SetBlackWhitePixels(pScrn); - /* Setup the visual we support */ - if (pScrni->bitsPerPixel > 8) { - DEBUGMSG(1, (scrnIndex, X_PROBED, - "miSetVisualTypes %d %X %X %X\n", - pScrni->depth, TrueColorMask, - pScrni->rgbBits, pScrni->defaultVisual)); + /* Set up the color ordering */ - if (!miSetVisualTypes(pScrni->depth, - TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)) { - return FALSE; - } - } else { - if (!miSetVisualTypes(pScrni->depth, - miGetDefaultVisualMask(pScrni->depth), - pScrni->rgbBits, pScrni->defaultVisual)) { - return FALSE; - } - } - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(3)!\n")); - - /* Set for RENDER extensions */ - miSetPixmapDepths(); - - /* Call the framebuffer layer's ScreenInit function, and fill in other - * * pScrn fields. - */ - switch (pScrni->bitsPerPixel) { -#if CFB - case 8: - Inited = cfbScreenInit(pScrn, FBStart, virtualX, virtualY, - pScrni->xDpi, pScrni->yDpi, displayWidth); - break; - case 16: - Inited = cfb16ScreenInit(pScrn, FBStart, virtualX, virtualY, - pScrni->xDpi, pScrni->yDpi, displayWidth); - break; - case 24: - case 32: - Inited = cfb32ScreenInit(pScrn, FBStart, virtualX, virtualY, - pScrni->xDpi, pScrni->yDpi, displayWidth); - break; -#else - case 8: - case 16: - case 24: - case 32: - Inited = fbScreenInit(pScrn, FBStart, virtualX, virtualY, - pScrni->xDpi, pScrni->yDpi, displayWidth, pScrni->bitsPerPixel); - break; -#endif - default: - xf86DrvMsg(scrnIndex, X_ERROR, - "Internal error: invalid bpp (%d) in ScreenInit\n", - pScrni->bitsPerPixel); - Inited = FALSE; - break; - } + if (pScrni->bitsPerPixel > 8) { + VisualPtr visual = pScrn->visuals + pScrn->numVisuals; - if (!Inited) - return FALSE; - - GXRotationInit(pScrni); - GXAdjustFrame(scrnIndex, pScrni->frameX0, pScrni->frameY0, 0); - - if (!pGeode->NoAccel) { - if (!pGeode->useEXA) { - AvailBox.x1 = 0; /* SET UP GRAPHICS MEMORY AVAILABLE FOR PIXMAP CACHE */ - AvailBox.y1 = - (fboffset + pGeode->AccelPitch - 1) / pGeode->AccelPitch; - AvailBox.x2 = displayWidth; - AvailBox.y2 = (fboffset + fbavail) / pGeode->AccelPitch; - - DEBUGMSG(1, (scrnIndex, X_PROBED, - "Memory manager initialized to (%d,%d) (%d,%d)\n", - AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2)); - - if (AvailBox.y1 < AvailBox.y2) { - xf86DrvMsg(scrnIndex, X_INFO, - "Initializing Memory manager to (%d,%d) (%d,%d)\n", - AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2); - REGION_INIT(pScrn, &OffscreenRegion, &AvailBox, 2); - if (!xf86InitFBManagerRegion(pScrn, &OffscreenRegion)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Memory manager initialization failed, Cache Diabled\n"); - } - REGION_UNINIT(pScrn, &OffscreenRegion); - } else { - xf86DrvMsg(scrnIndex, X_INFO, - "No Off Screen Memory, Cache Disabled (%d,%d) (%d,%d)\n", - AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2); - } - } -#if XF86EXA - else if (pGeode->pExa) { - ExaDriverPtr pExa = pGeode->pExa; - - pExa->memoryBase = pGeode->FBBase; - pExa->offScreenBase = fboffset; - pExa->memorySize = fboffset + fbavail; - pExa->pixmapOffsetAlign = 32; - pExa->pixmapPitchAlign = 32; - pExa->flags = EXA_OFFSCREEN_PIXMAPS; - pExa->maxX = pGeode->maxWidth - 1; - pExa->maxY = pGeode->maxHeight - 1; - } -#endif + while (--visual >= pScrn->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrni->offset.red; + visual->offsetGreen = pScrni->offset.green; + visual->offsetBlue = pScrni->offset.blue; + visual->redMask = pScrni->mask.red; + visual->greenMask = pScrni->mask.green; + visual->blueMask = pScrni->mask.blue; + } } + } - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(4)!\n")); - xf86SetBlackWhitePixels(pScrn); + /* Must follow the color ordering */ + fbPictureInit(pScrn, 0, 0); - if (!pGeode->ShadowFB) { - GXDGAInit(pScrn); - } + if (!pGeode->NoAccel) + GXAccelInit(pScrn); - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(5)!\n")); - if (pScrni->bitsPerPixel > 8) { - /* Fixup RGB ordering */ - visual = pScrn->visuals + pScrn->numVisuals; - while (--visual >= pScrn->visuals) { - if ((visual->class | DynamicClass) == DirectColor) { - visual->offsetRed = pScrni->offset.red; - visual->offsetGreen = pScrni->offset.green; - visual->offsetBlue = pScrni->offset.blue; - visual->redMask = pScrni->mask.red; - visual->greenMask = pScrni->mask.green; - visual->blueMask = pScrni->mask.blue; - } - } - } -#if CFB -#else - /* must be after RGB ordering fixed */ - fbPictureInit(pScrn, 0, 0); -#endif + miInitializeBackingStore(pScrn); + xf86SetBackingStore(pScrn); - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(6)!\n")); - if (!pGeode->NoAccel) { - GXAccelInit(pScrn); - } + /* Set up the soft cursor */ + miDCInitialize(pScrn, xf86GetPointerScreenFuncs()); - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(7)!\n")); - miInitializeBackingStore(pScrn); - xf86SetBackingStore(pScrn); - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(8)!\n")); - /* Initialise software cursor */ - miDCInitialize(pScrn, xf86GetPointerScreenFuncs()); - /* Initialize HW cursor layer. - * * Must follow software cursor initialization - */ - if (pGeode->HWCursor) { - if (!GXHWCursorInit(pScrn)) - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Hardware cursor initialization failed\n"); - } + /* Set up the HW cursor - must follow the soft cursor init */ - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(9)!\n")); - /* Setup default colourmap */ - if (!miCreateDefColormap(pScrn)) { - return FALSE; - } + if (pGeode->tryHWCursor) { + if (!GXHWCursorInit(pScrn)) + xf86DrvMsg(scrnIndex, X_ERROR, + "Hardware cursor initialization failed.\n"); + } - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(10)!\n")); - if (pScrni->bitsPerPixel == 8) { - /* Initialize colormap layer. - * * Must follow initialization of the default colormap - */ - if (!xf86HandleColormaps(pScrn, 256, 8, - GXLoadPalette, NULL, - CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { - return FALSE; - } - } + /* Set up the color map */ - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(11)!\n")); + if (!miCreateDefColormap(pScrn)) + return FALSE; - if (pGeode->ShadowFB) { - DEBUGMSG(1, (0, X_INFO, "Shadowed, Rotate=%d, NoAccel=%d\n", - pGeode->Rotate, pGeode->NoAccel)); - GXShadowFBInit(pScrn, pGeode, bytpp); + if (pScrni->bitsPerPixel == 8) { + /* Must follow initialization of the default colormap */ + + if (!xf86HandleColormaps(pScrn, 256, 8, + GXLoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { + return FALSE; } + } #ifdef DPMSExtension - xf86DPMSInit(pScrn, GXDPMSSet, 0); + xf86DPMSInit(pScrn, GXDPMSSet, 0); #endif - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(12)!\n")); - - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(13)!\n")); - GXInitVideo(pScrn); /* needed for video */ - /* Wrap the screen's CloseScreen vector and set its - * SaveScreen vector - */ - pGeode->CloseScreen = pScrn->CloseScreen; - pScrn->CloseScreen = GXCloseScreen; - - pScrn->SaveScreen = GXSaveScreen; - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(14)!\n")); - - /* Report any unused options */ - if (serverGeneration == 1) { - xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); - } - DEBUGMSG(1, (0, X_INFO, "GXScreenInit(15)!\n")); - return TRUE; -} + GXInitVideo(pScrn); -/*---------------------------------------------------------------------------- - * GXSwitchMode. - * - * Description :This function will switches the screen mode - * - * Parameters: - * scrnIndex :Specfies the screen index value. - * pMode :pointer to the mode structure. - * flags :may be used for status check?. - * - * Returns :Returns TRUE on success and FALSE on failure. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ -Bool -GXSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags) -{ - DEBUGMSG(1, (0, X_INFO, "GXSwitchMode!\n")); - return GXSetMode(xf86Screens[scrnIndex], pMode); + /* Set up RandR */ + + xf86DisableRandR(); /* We provide our own RandR goodness */ + + /* Try to set up the shadow FB for rotation */ + + memset(&shadowReq, 0, sizeof(shadowReq)); + shadowReq.majorversion = 1; + shadowReq.minorversion = 1; + + if (LoadSubModule(pScrni->module, "shadow", + NULL, NULL, NULL, &shadowReq, &maj, &min)) { + + rotate = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270; + shadowSetup(pScrn); + } else { + LoaderErrorMsg(NULL, "shadow", maj, min); + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Error loading shadow - rotation not available.\n"); + + if (pGeode->rotation != RR_Rotate_0) + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Reverting back to normal rotation.\n"); + + rotate = pGeode->rotation = RR_Rotate_0; + } + + GXRandRInit(pScrn, rotate); + + pGeode->PointerMoved = pScrni->PointerMoved; + pScrni->PointerMoved = GeodePointerMoved; + + pGeode->CreateScreenResources = pScrn->CreateScreenResources; + pScrn->CreateScreenResources = GXCreateScreenResources; + + pGeode->CloseScreen = pScrn->CloseScreen; + pScrn->CloseScreen = GXCloseScreen; + pScrn->SaveScreen = GXSaveScreen; + + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); + + pGeode->starting = FALSE; + + return TRUE; } -/*---------------------------------------------------------------------------- - * GXAdjustFrame. - * - * Description :This function is used to intiallize the start - * address of the memory. - * Parameters. - * scrnIndex :Specfies the screen index value. - * x :x co-ordinate value interms of pixels. - * y :y co-ordinate value interms of pixels. - * - * Returns :none. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ -void -GXAdjustFrame(int scrnIndex, int x, int y, int flags) +static int +GXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) { - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - - GeodeRec *pGeode = GEODEPTR(pScrni); - int newX, newY; - unsigned long offset; - - if (x + pGeode->HDisplay >= pScrni->virtualX) - x = pScrni->virtualX - pGeode->HDisplay; - - if (x < 0) - x = 0; - - if (y + pGeode->VDisplay >= pScrni->virtualY) - y = pScrni->virtualY - pGeode->VDisplay; - - if (y < 0) - y = 0; - - pScrni->frameX0 = x; - pScrni->frameY0 = y; - pScrni->frameX1 = x + pGeode->HDisplay - 1; - pScrni->frameY1 = y + pGeode->VDisplay - 1; - (*pGeode->Rotation) (x, y, pScrni->virtualX, pScrni->virtualY, &newX, - &newY); - (*pGeode->RBltXlat) (newX, newY, pGeode->HDisplay, pGeode->VDisplay, - &newX, &newY); - offset = - pGeode->FBOffset + newY * pGeode->Pitch + - newX * (pScrni->bitsPerPixel >> 3); - gfx_set_display_offset(offset); + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; + GeodeRec *pGeode = GEODEPTR(pScrni); + int p, ret; + + /* Not sure if this is an X bug or not - but on my current build, + * user defined modes pass a type of 0 */ + + if (pMode->type && pMode->type != M_T_USERDEF) { + + if (pGeode->Panel) { + if (pMode->CrtcHDisplay > pGeode->PanelX || + pMode->CrtcVDisplay > pGeode->PanelY || + gfx_is_panel_mode_supported(pGeode->PanelX, pGeode->PanelY, + pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pScrni->bitsPerPixel) < 0) { + + return MODE_BAD; + } + } + + ret = gfx_is_display_mode_supported(pMode->CrtcHDisplay, + pMode->CrtcVDisplay, + pScrni->bitsPerPixel, + GeodeGetRefreshRate(pMode)); + if (ret < 0) { + return MODE_BAD; + } + } + + if (pMode->Flags & V_INTERLACE) + return MODE_NO_INTERLACE; + + if (pGeode->tryCompression) + p = GeodeCalculatePitchBytes(pMode->CrtcHDisplay, pScrni->bitsPerPixel); + else + p = ((pMode->CrtcHDisplay + 3) & ~3) * (pScrni->bitsPerPixel >> 3); + + if (p * pMode->CrtcVDisplay > pGeode->FBAvail) + return MODE_MEM; + + return MODE_OK; } -/*---------------------------------------------------------------------------- - * GXEnterVT. - * - * Description :This is called when VT switching back to the X server - * - * Parameters. - * scrnIndex :Specfies the screen index value. - * flags :Not used inside the function. - * - * Returns :none. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ +/* XXX - Way more to do here */ + static Bool GXEnterVT(int scrnIndex, int flags) { - DEBUGMSG(1, (0, X_INFO, "GXEnterVT!\n")); - return GXEnterGraphics(NULL, xf86Screens[scrnIndex]); + return GXEnterGraphics(NULL, xf86Screens[scrnIndex]); } -/*---------------------------------------------------------------------------- - * GXLeaveVT. - * - * Description :This is called when VT switching X server text mode. - * - * Parameters. - * scrnIndex :Specfies the screen index value. - * flags :Not used inside the function. - * - * Returns :none. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ static void GXLeaveVT(int scrnIndex, int flags) { - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - GeodeRec *pGeode = GEODEPTR(pScrni); + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; + GeodeRec *pGeode = GEODEPTR(pScrni); - pGeode->PrevDisplayOffset = gfx_get_display_offset(); - DEBUGMSG(1, (0, X_INFO, "GXLeaveVT!\n")); - GXLeaveGraphics(xf86Screens[scrnIndex]); + pGeode->PrevDisplayOffset = gfx_get_display_offset(); + GXLeaveGraphics(xf86Screens[scrnIndex]); } -/*---------------------------------------------------------------------------- - * GXFreeScreen. - * - * Description :This is called to free any persistent data structures. - * - * Parameters. - * scrnIndex :Specfies the screen index value. - * flags :Not used inside the function. - * - * Returns :none. - * - * Comments :This will be called only when screen being deleted.. - *---------------------------------------------------------------------------- - */ -static void -GXFreeScreen(int scrnIndex, int flags) +void +GXSetupChipsetFPtr(ScrnInfoPtr pScrn) { - DEBUGMSG(1, (0, X_INFO, "GXFreeScreen!\n")); - if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) - vgaHWFreeHWRec(xf86Screens[scrnIndex]); - - GXFreeRec(xf86Screens[scrnIndex]); + pScrn->PreInit = GXPreInit; + pScrn->ScreenInit = GXScreenInit; + pScrn->SwitchMode = GXSwitchMode; + pScrn->AdjustFrame = GXAdjustFrame; + pScrn->EnterVT = GXEnterVT; + pScrn->LeaveVT = GXLeaveVT; + pScrn->FreeScreen = GeodeFreeScreen; + pScrn->ValidMode = GXValidMode; } -/*---------------------------------------------------------------------------- - * GXValidMode. - * - * Description :This function checks if a mode is suitable for selected - * chipset. - * Parameters. - * scrnIndex :Specfies the screen index value. - * pMode :Pointer to the screen mode structure.. - * verbose :not used for implementation. - * flags :not used for implementation - * - * Returns :MODE_OK if the specified mode is supported or - * MODE_NO_INTERLACE. - * Comments :none. - *---------------------------------------------------------------------------- - */ -static int -GXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) -{ - unsigned int total_memory_required; - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - int ret = -1; - unsigned int ptch; +/* ====== Common functions ====== + * These are all the common functions that we use for both GX and LX - They live here + * because most of them came along for the GX first, and then were adapted to the LX. + * We could move these to a common function, but there is no hurry + * ============================== */ - GeodeRec *pGeode = GEODEPTR(pScrni); - DEBUGMSG(1, (0, X_NONE, "GeodeValidateMode: %dx%d %d %d\n", - pMode->CrtcHDisplay, pMode->CrtcVDisplay, - pScrni->bitsPerPixel, GXGetRefreshRate(pMode))); - if (pGeode->CustomMode == 0) { +void +GeodePointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrni = xf86Screens[index]; + GeodeRec *pGeode = GEODEPTR(pScrni); + + int newX = x, newY = y; + + switch (pGeode->rotation) { + case RR_Rotate_0: + break; + case RR_Rotate_90: + newX = y; + newY = pScrni->pScreen->width - x - 1; + break; + case RR_Rotate_180: + newX = pScrni->pScreen->width - x - 1; + newY = pScrni->pScreen->height - y - 1; + break; + case RR_Rotate_270: + newX = pScrni->pScreen->height - y - 1; + newY = x; + break; + } + + (*pGeode->PointerMoved)(index, newX, newY); +} -#if defined(PNL_SUP) - if (pGeode->Panel != 0) { - DEBUGMSG(1, (0, X_NONE, "crtcH = %d, FPBX=%d, CrtcV=%d FPBY=%d\n", - pMode->CrtcHDisplay, pGeode->FPBX, - pMode->CrtcVDisplay, pGeode->FPBY)); - if (pMode->CrtcHDisplay > pGeode->FPBX || - pMode->CrtcVDisplay > pGeode->FPBY || - gfx_is_panel_mode_supported(pGeode->FPBX, pGeode->FPBY, - pMode->CrtcHDisplay, pMode->CrtcVDisplay, - pScrni->bitsPerPixel) < 0) - return MODE_NOMODE; - } -#endif /* PNL_SUP */ - - DEBUGMSG(1, (0, X_NONE, "CRT mode\n")); - if (pMode->Flags & V_INTERLACE) - return MODE_NO_INTERLACE; - - ret = gfx_is_display_mode_supported(pMode->CrtcHDisplay, - pMode->CrtcVDisplay, - pScrni->bitsPerPixel, GXGetRefreshRate(pMode)); - if (ret < 0) - return MODE_NOMODE; - } +void +GeodeProbeDDC(ScrnInfoPtr pScrni, int index) +{ + vbeInfoPtr pVbe; - if (pGeode->Compression) - ptch = GXCalculatePitchBytes(pMode->CrtcHDisplay, pScrni->bitsPerPixel); - else - ptch = ((pMode->CrtcHDisplay + 3) & ~3) * (pScrni->bitsPerPixel >> 3); + if (xf86LoadSubModule(pScrni, "vbe")) { + pVbe = VBEInit(NULL, index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } +} - total_memory_required = ptch * pMode->CrtcVDisplay; +xf86MonPtr +GeodeDoDDC(ScrnInfoPtr pScrni, int index) +{ + vbeInfoPtr pVbe; + xf86MonPtr info = NULL; + + if (xf86LoadSubModule(pScrni, "vbe") && + (pVbe = VBEInit(NULL, index))) { + xf86LoaderReqSymLists(amdVbeSymbols, NULL); + info = vbeDoEDID(pVbe, NULL); + xf86PrintEDID(info); + xf86SetDDCproperties(pScrni, info); + vbeFree(pVbe); + } else + xf86DrvMsg(pScrni->scrnIndex, X_INFO, + "We cannot do DDC without VBE.\n"); + + return info; +} - DEBUGMSG(1, (0, X_NONE, "Total Mem %X %lX\n", - total_memory_required, pGeode->FBAvail)); +int +GeodeGetFPGeometry(const char *str, int *width, int *height) +{ - if (total_memory_required > pGeode->FBAvail) - return MODE_MEM; + int ret = sscanf(str, "%dx%d", width, height); - return MODE_OK; + return (ret == 2) ? 0 : 1; } -/*---------------------------------------------------------------------------- - * GXLoadPalette. - * - * Description: This function sets the palette entry used for graphics - * data - * - * Parameters. - * pScrni: Points the screeninfo structure. - * numColors: Specifies the no of colors it supported. - * indizes: This is used get index value . - * LOCO: to be added. - * pVisual: to be added. - * - * Returns: MODE_OK if the specified mode is supported or - * MODE_NO_INTERLACE. - * - * Comments: none. - *---------------------------------------------------------------------------- - */ static void -GXLoadPalette(ScrnInfoPtr pScrni, - int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) +GeodeFreeRec(ScrnInfoPtr pScrni) { - int i, index, color; - - for (i = 0; i < numColors; i++) { - index = indizes[i] & 0xFF; - color = (((unsigned long)(colors[index].red & 0xFF)) << 16) | - (((unsigned long)(colors[index].green & 0xFF)) << 8) | - ((unsigned long)(colors[index].blue & 0xFF)); - DEBUGMSG(0, (0, X_NONE, "GXLoadPalette: %d %d %X\n", - numColors, index, color)); - - GFX(set_display_palette_entry(index, color)); - } + if (pScrni->driverPrivate != NULL) { + xfree(pScrni->driverPrivate); + pScrni->driverPrivate = NULL; + } } -static Bool -GXMapMem(ScrnInfoPtr pScrni) +void +GeodeFreeScreen(int scrnIndex, int flags) { - GeodeRec *pGeode = GEODEPTR(pScrni); + GeodeRec *pGeode = GEODEPTR(xf86Screens[scrnIndex]); - gfx_virt_regptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_MMIO, (unsigned int) - gfx_get_cpu_register_base(), pGeode->cpu_reg_size); - - if (pGeode->DetectedChipSet & GX) { - gfx_virt_gpptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_MMIO, (unsigned int) - gfx_get_graphics_register_base(), pGeode->gp_reg_size); - } else { - gfx_virt_spptr = gfx_virt_regptr; - } + if (pGeode == NULL) + return; - gfx_virt_vidptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_MMIO, (unsigned int) - gfx_get_vid_register_base(), pGeode->vid_reg_size); - - gfx_virt_fbptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_FRAMEBUFFER, pGeode->FBLinearAddr, pGeode->FBAvail); - - XpressROMPtr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_FRAMEBUFFER, 0xF0000, 0x10000); + if (pGeode->useVGA) { + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); + } - pGeode->FBBase = gfx_virt_fbptr; + GeodeFreeRec(xf86Screens[scrnIndex]); +} - DEBUGMSG(1, (0, X_NONE, "Set mode %p %p %p %p %p\n", - gfx_virt_regptr, - gfx_virt_gpptr, gfx_virt_spptr, gfx_virt_vidptr, gfx_virt_fbptr)); +int +GeodeCalculatePitchBytes(unsigned int width, unsigned int bpp) +{ - /* CHECK IF REGISTERS WERE MAPPED SUCCESSFULLY */ - if ((!gfx_virt_regptr) || - (!gfx_virt_gpptr) || (!gfx_virt_vidptr) || (!gfx_virt_fbptr)) { - DEBUGMSG(1, (0, X_NONE, "Could not map hardware registers.\n")); - return (FALSE); - } + int delta = width * (bpp >> 3); - DEBUGMSG(1, (0, X_NONE, "adapter info %lx %lx %lx %p\n", - pGeode->cpu_version, - pGeode->vid_version, - pGeode->FBAvail, pGeode->FBBase)); + /* Less then 640 has doubling enabled */ - return TRUE; -} + if (width < 640) + delta <<= 1; -/* - * Unmap the framebuffer and MMIO memory. - */ + /* Calculate the pitch (compression rquires a power of 2) */ -static Bool -GXUnmapMem(ScrnInfoPtr pScrni) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); + if (delta > 4096) + delta = 8192; + else if (delta > 2048) + delta = 4096; + else if (delta > 1024) + delta = 2048; + else + delta = 1024; - /* unmap all the memory map's */ - xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_regptr, pGeode->cpu_reg_size); - if (pGeode->DetectedChipSet & GX) { - xf86UnMapVidMem(pScrni->scrnIndex, - gfx_virt_gpptr, pGeode->gp_reg_size); - } - xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_vidptr, pGeode->vid_reg_size); - xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_fbptr, pGeode->FBAvail); - return TRUE; + return delta; } -/* End of file */ diff --git a/src/amd_gx_randr.c b/src/amd_gx_randr.c new file mode 100644 index 0000000..a4fa743 --- /dev/null +++ b/src/amd_gx_randr.c @@ -0,0 +1,331 @@ +/* Originally derived from the Intel example + * Copyright (C) 2002 Keith Packard, member of The XFree86 Project, Inc. + + * Copyright (c) 2006 Advanced Micro Devices, Inc. + * + * 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, + * 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. + * + * Neither the name of the Advanced Micro Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + */ + +#include "xf86.h" +#include "os.h" +#include "mibank.h" +#include "globals.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86DDC.h" +#include "mipointer.h" +#include "windowstr.h" +#include <X11/extensions/randr.h> +#include <randrstr.h> + +#include "amd.h" + +static int GXRandRIndex; +static int GXRandRGeneration; + +typedef struct _GXRandRInfo +{ + int virtualX; + int virtualY; + int mmWidth; + int mmHeight; + int maxX; + int maxY; + Rotation rotation; /* current mode */ + Rotation supported_rotations; /* driver supported */ +} XF86RandRInfoRec, *XF86RandRInfoPtr; + +#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) (p)->devPrivates[GXRandRIndex].ptr) + +static int +GXRandRModeRefresh(DisplayModePtr mode) +{ + if (mode->VRefresh) + return (int)(mode->VRefresh + 0.5); + else + return (int)(mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + + 0.5); +} + +static Bool +GXRandRGetInfo(ScreenPtr pScreen, Rotation * rotations) +{ + RRScreenSizePtr pSize; + ScrnInfoPtr pScrni = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr pRandr = XF86RANDRINFO(pScreen); + DisplayModePtr mode; + int refresh0 = 60; + int maxX = 0, maxY = 0; + + *rotations = pRandr->supported_rotations; + + if (pRandr->virtualX == -1 || pRandr->virtualY == -1) { + pRandr->virtualX = pScrni->virtualX; + pRandr->virtualY = pScrni->virtualY; + } + + for (mode = pScrni->modes;; mode = mode->next) { + int refresh = GXRandRModeRefresh(mode); + + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + if (maxX < mode->HDisplay) + maxX = mode->HDisplay; + if (maxY < mode->VDisplay) + maxY = mode->VDisplay; + } + + if (mode == pScrni->modes) + refresh0 = refresh; + + pSize = RRRegisterSize(pScreen, + mode->HDisplay, mode->VDisplay, + pRandr->mmWidth, pRandr->mmHeight); + if (!pSize) + return FALSE; + + RRRegisterRate(pScreen, pSize, refresh); + + if (mode == pScrni->currentMode && + mode->HDisplay == pScrni->virtualX + && mode->VDisplay == pScrni->virtualY) + RRSetCurrentConfig(pScreen, pRandr->rotation, refresh, pSize); + if (mode->next == pScrni->modes) + break; + } + + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + pRandr->maxX = maxX; + pRandr->maxY = maxY; + } + + if (pScrni->currentMode->HDisplay != pScrni->virtualX || + pScrni->currentMode->VDisplay != pScrni->virtualY) { + + mode = pScrni->modes; + pSize = RRRegisterSize(pScreen, + pRandr->virtualX, pRandr->virtualY, + pRandr->mmWidth, pRandr->mmHeight); + if (!pSize) + return FALSE; + + RRRegisterRate(pScreen, pSize, refresh0); + if (pScrni->virtualX == pRandr->virtualX && + pScrni->virtualY == pRandr->virtualY) { + RRSetCurrentConfig(pScreen, pRandr->rotation, refresh0, pSize); + } + } + + return TRUE; +} + +static Bool +GXRandRSetMode(ScreenPtr pScreen, + DisplayModePtr mode, Bool useVirtual, int mmWidth, int mmHeight) +{ + ScrnInfoPtr pScrni = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr pRandr = XF86RANDRINFO(pScreen); + + int oldWidth = pScreen->width; + int oldHeight = pScreen->height; + int oldmmWidth = pScreen->mmWidth; + int oldmmHeight = pScreen->mmHeight; + WindowPtr pRoot = WindowTable[pScreen->myNum]; + DisplayModePtr currentMode = NULL; + Bool ret = TRUE; + PixmapPtr pspix = NULL; + + if (pRoot) + (*pScrni->EnableDisableFBAccess) (pScreen->myNum, FALSE); + + if (useVirtual) { + pScrni->virtualX = pRandr->virtualX; + pScrni->virtualY = pRandr->virtualY; + } else { + pScrni->virtualX = mode->HDisplay; + pScrni->virtualY = mode->VDisplay; + } + + if (pRandr->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + pScreen->width = pScrni->virtualY; + pScreen->height = pScrni->virtualX; + pScreen->mmWidth = mmHeight; + pScreen->mmHeight = mmWidth; + } else { + pScreen->width = pScrni->virtualX; + pScreen->height = pScrni->virtualY; + pScreen->mmWidth = mmWidth; + pScreen->mmHeight = mmHeight; + } + + if (pScrni->currentMode == mode) { + currentMode = pScrni->currentMode; + pScrni->currentMode = NULL; + } + + if (!xf86SwitchMode(pScreen, mode)) { + ret = FALSE; + pScrni->virtualX = pScreen->width = oldWidth; + pScrni->virtualY = pScreen->height = oldHeight; + pScreen->mmWidth = oldmmWidth; + pScreen->mmHeight = oldmmHeight; + pScrni->currentMode = currentMode; + } + + /* + * Get the new Screen pixmap ptr as SwitchMode might have called + * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back... + * Unfortunately. + + */ + + pspix = (*pScreen->GetScreenPixmap) (pScreen); + if (pspix->devPrivate.ptr) + pScrni->pixmapPrivate = pspix->devPrivate; + + xf86ReconfigureLayout(); + + xf86SetViewport(pScreen, pScreen->width, pScreen->height); + xf86SetViewport(pScreen, 0, 0); + + if (pRoot) + (*pScrni->EnableDisableFBAccess) (pScreen->myNum, TRUE); + + return ret; +} + +Bool +GXRandRSetConfig(ScreenPtr pScreen, Rotation rotation, + int rate, RRScreenSizePtr pSize) +{ + ScrnInfoPtr pScrni = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr pRandr = XF86RANDRINFO(pScreen); + + DisplayModePtr mode; + int px, py; + Bool useVirtual = FALSE; + int maxX = 0, maxY = 0; + Rotation oldRotation = pRandr->rotation; + + pRandr->rotation = rotation; + + if (pRandr->virtualX == -1 || pRandr->virtualY == -1) { + pRandr->virtualX = pScrni->virtualX; + pRandr->virtualY = pScrni->virtualY; + } + + miPointerPosition(&px, &py); + + for (mode = pScrni->modes;; mode = mode->next) { + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + if (maxX < mode->HDisplay) + maxX = mode->HDisplay; + if (maxY < mode->VDisplay) + maxY = mode->VDisplay; + } + if (mode->HDisplay == pSize->width && + mode->VDisplay == pSize->height && + (rate == 0 || GXRandRModeRefresh(mode) == rate)) + break; + if (mode->next == pScrni->modes) { + if (pSize->width == pRandr->virtualX && + pSize->height == pRandr->virtualY) { + mode = pScrni->modes; + useVirtual = TRUE; + break; + } + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + pRandr->maxX = maxX; + pRandr->maxY = maxY; + } + return FALSE; + } + } + + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + pRandr->maxX = maxX; + pRandr->maxY = maxY; + } + + if (!GXRandRSetMode(pScreen, mode, useVirtual, pSize->mmWidth, + pSize->mmHeight)) { + pRandr->rotation = oldRotation; + return FALSE; + } + + if (pScreen == miPointerCurrentScreen()) { + px = (px >= pScreen->width ? (pScreen->width - 1) : px); + py = (py >= pScreen->height ? (pScreen->height - 1) : py); + + xf86SetViewport(pScreen, px, py); + + (*pScreen->SetCursorPosition) (pScreen, px, py, FALSE); + } + + return TRUE; +} + +Rotation +GXGetRotation(ScreenPtr pScreen) +{ + XF86RandRInfoPtr pRandr = XF86RANDRINFO(pScreen); + + return pRandr->rotation; +} + +Bool +GXRandRInit(ScreenPtr pScreen, int rotation) +{ + XF86RandRInfoPtr pRandr; + rrScrPrivPtr rp; + + if (GXRandRGeneration != serverGeneration) { + GXRandRIndex = AllocateScreenPrivateIndex(); + GXRandRGeneration = serverGeneration; + } + + pRandr = xcalloc(sizeof(XF86RandRInfoRec), 1); + if (pRandr == NULL) + return FALSE; + + if (!RRScreenInit(pScreen)) { + xfree(pRandr); + return FALSE; + } + + rp = rrGetScrPriv(pScreen); + rp->rrGetInfo = GXRandRGetInfo; + rp->rrSetConfig = GXRandRSetConfig; + + pRandr->virtualX = -1; + pRandr->virtualY = -1; + + pRandr->mmWidth = pScreen->mmWidth; + pRandr->mmHeight = pScreen->mmHeight; + + pRandr->rotation = RR_Rotate_0; + pRandr->supported_rotations = rotation; + pRandr->maxX = pRandr->maxY = 0; + + pScreen->devPrivates[GXRandRIndex].ptr = pRandr; + return TRUE; +} diff --git a/src/amd_gx_rotate.c b/src/amd_gx_rotate.c new file mode 100644 index 0000000..3e464ca --- /dev/null +++ b/src/amd_gx_rotate.c @@ -0,0 +1,190 @@ +/* Copyrightg (c) 2006 Advanced Micro Devices, Inc. + * + * 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, + * 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. + * + * Neither the name of the Advanced Micro Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "shadow.h" +#include "amd.h" + +static void * +GXWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, + CARD32 * size, void *closure) +{ + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + + *size = pGeode->displayPitch; + + return (pGeode->FBBase + pGeode->displayOffset) + + row * pGeode->displayPitch + offset; +} + +static void +GXUpdate(ScreenPtr pScreen, shadowBufPtr pBuf) +{ + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + int rotate = pGeode->rotation; + + switch (rotate) { + case RR_Rotate_90: + + if (pScrni->bitsPerPixel == 8) + shadowUpdateRotate8_90(pScreen, pBuf); + else if (pScrni->bitsPerPixel == 16) + shadowUpdateRotate16_90(pScreen, pBuf); + else + shadowUpdateRotate32_90(pScreen, pBuf); + + break; + + case RR_Rotate_180: + + if (pScrni->bitsPerPixel == 8) + shadowUpdateRotate8_180(pScreen, pBuf); + else if (pScrni->bitsPerPixel == 16) + shadowUpdateRotate16_180(pScreen, pBuf); + else + shadowUpdateRotate32_180(pScreen, pBuf); + + break; + + case RR_Rotate_270: + if (pScrni->bitsPerPixel == 8) + shadowUpdateRotate8_270(pScreen, pBuf); + else if (pScrni->bitsPerPixel == 16) + shadowUpdateRotate16_270(pScreen, pBuf); + else + shadowUpdateRotate32_270(pScreen, pBuf); + + break; + } +} + +Bool +GXRotate(ScrnInfoPtr pScrni, DisplayModePtr mode) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + Rotation curr = pGeode->rotation; + unsigned int curdw = pScrni->displayWidth; + PixmapPtr pPixmap; + BOOL ret; + + pPixmap = pScrni->pScreen->GetScreenPixmap(pScrni->pScreen); + pGeode->rotation = GXGetRotation(pScrni->pScreen); + + /* Leave if we have nothing to do */ + + if (pGeode->rotation == curr && pGeode->curMode == mode) { + return TRUE; + } + + shadowRemove(pScrni->pScreen, NULL); + + switch (pGeode->rotation) { + case RR_Rotate_0: + ErrorF("Rotate to 0 degrees\n"); + pScrni->displayWidth = pGeode->displayWidth; + pGeode->Pitch = pGeode->displayPitch; + break; + + case RR_Rotate_90: + ErrorF("Rotate to 90 degrees\n"); + pScrni->displayWidth = pScrni->pScreen->width; + break; + + case RR_Rotate_180: + ErrorF("Rotate to 180 degrees\n"); + pScrni->displayWidth = pGeode->displayWidth; + break; + + case RR_Rotate_270: + ErrorF("Rotate to 270 degrees\n"); + pScrni->displayWidth = pScrni->pScreen->width; + break; + } + + if (pGeode->rotation != RR_Rotate_0) { + + ret = + shadowAdd(pScrni->pScreen, pPixmap, GXUpdate, GXWindowLinear, + pGeode->rotation, NULL); + + /* XXX - FIXME - bail gracefully */ + + if (!ret) + ErrorF("shadowAdd failed\n"); + } + + if (pGeode->rotation == RR_Rotate_0) + pScrni->fbOffset = pGeode->displayOffset; + else + pScrni->fbOffset = pGeode->shadowOffset; + + pScrni->pScreen->ModifyPixmapHeader(pPixmap, + pScrni->pScreen->width, + pScrni->pScreen->height, + pScrni->pScreen->rootDepth, + pScrni->bitsPerPixel, + PixmapBytePad(pScrni->displayWidth, pScrni->pScreen->rootDepth), + (pointer) (pGeode->FBBase + pScrni->fbOffset)); + + /* Don't use XAA pixmap cache or offscreen pixmaps when rotated */ + + if (pGeode->AccelInfoRec) { + if (pGeode->rotation == RR_Rotate_0) { + pGeode->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE; + pGeode->AccelInfoRec->UsingPixmapCache = TRUE; + pGeode->AccelInfoRec->maxOffPixWidth = 0; + pGeode->AccelInfoRec->maxOffPixHeight = 0; + } + else { + pGeode->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER; + pGeode->AccelInfoRec->UsingPixmapCache = FALSE; + pGeode->AccelInfoRec->maxOffPixWidth = 1; + pGeode->AccelInfoRec->maxOffPixHeight = 1; + } + } + + return TRUE; + +error: + /* Restore the old rotation */ + pScrni->displayWidth = curdw; + + if (curr & (RR_Rotate_0 | RR_Rotate_180)) { + pScrni->pScreen->width = pScrni->virtualX; + pScrni->pScreen->height = pScrni->virtualY; + } else { + pScrni->pScreen->width = pScrni->virtualY; + pScrni->pScreen->height = pScrni->virtualX; + } + + pGeode->rotation = curr; + return FALSE; +} diff --git a/src/amd_gx_vga.c b/src/amd_gx_vga.c index 2fbe2de..b46675a 100644 --- a/src/amd_gx_vga.c +++ b/src/amd_gx_vga.c @@ -33,6 +33,9 @@ #include "config.h" #endif +#include <stdlib.h> +#include <string.h> + /* VGA STRUCTURE */ #define GU2_STD_CRTC_REGS 25 diff --git a/src/amd_gx_video.c b/src/amd_gx_video.c index c3c5344..9322da4 100644 --- a/src/amd_gx_video.c +++ b/src/amd_gx_video.c @@ -11,7 +11,7 @@ * 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, + * IMPDIs2IED, 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 @@ -40,6 +40,9 @@ #include "config.h" #endif +#include <stdlib.h> +#include <string.h> + #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Resources.h" @@ -89,7 +92,6 @@ GXSetVideoPosition() #else #define DBUF 1 -void GXInitVideo(ScreenPtr pScrn); void GXResetVideo(ScrnInfoPtr pScrni); static XF86VideoAdaptorPtr GXSetupImageVideo(ScreenPtr); static void GXInitOffscreenImages(ScreenPtr); @@ -101,8 +103,6 @@ static void GXQueryBestSize(ScrnInfoPtr, Bool, static int GXPutImage(ScrnInfoPtr, short, short, short, short, short, short, short, short, int, unsigned char *, short, short, Bool, RegionPtr, pointer, DrawablePtr pDraw); -static int GXQueryImageAttributes(ScrnInfoPtr, int, unsigned short *, - unsigned short *, int *, int *); static void GXBlockHandler(int, pointer, pointer, pointer); void GXSetVideoPosition(int x, int y, int width, int height, @@ -114,7 +114,7 @@ extern void GXAccelSync(ScrnInfoPtr pScrni); int DeltaX, DeltaY; unsigned long graphics_lut[256]; -unsigned long *lutptr = NULL; +static int lutflag = 0; #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) @@ -233,7 +233,7 @@ static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} }; -#define NUM_IMAGES 7 +#define NUM_IMAGES 8 static XF86ImageRec Images[NUM_IMAGES] = { XVIMAGE_UYVY, @@ -242,7 +242,8 @@ static XF86ImageRec Images[NUM_IMAGES] = { XVIMAGE_YVYU, XVIMAGE_Y800, XVIMAGE_I420, - XVIMAGE_YV12 + XVIMAGE_YV12, + XVIMAGE_RGB565 }; typedef struct @@ -401,7 +402,7 @@ GXSetupImageVideo(ScreenPtr pScrn) adapt->GetPortAttribute = GXGetPortAttribute; adapt->QueryBestSize = GXQueryBestSize; adapt->PutImage = GXPutImage; - adapt->QueryImageAttributes = GXQueryImageAttributes; + adapt->QueryImageAttributes = GeodeQueryImageAttributes; pPriv->filter = 0; pPriv->colorKey = pGeode->videoKey; @@ -468,13 +469,13 @@ GXStopVideo(ScrnInfoPtr pScrni, pointer data, Bool exit) /* If we have saved graphics LUT data - restore it */ /* Otherwise, turn bypass on */ - if (lutptr != NULL) - GFX(set_graphics_palette(lutptr)); - else + if (lutflag) + GFX(set_graphics_palette(graphics_lut)); + else GFX(set_video_palette_bypass(1)); - lutptr = NULL; - } + lutflag = 0; + } if (pPriv->area) { #ifdef XF86EXA @@ -621,37 +622,6 @@ GXQueryBestSize(ScrnInfoPtr pScrni, *p_w = 16384; } -static void -GXCopyGreyscale(unsigned char *src, - unsigned char *dst, int srcPitch, int dstPitch, int h, int w) -{ - int i; - unsigned char *src2 = src; - unsigned char *dst2 = dst; - unsigned char *dst3; - unsigned char *src3; - - dstPitch <<= 1; - - while (h--) { - dst3 = dst2; - src3 = src2; - for (i = 0; i < w; i++) { - *dst3++ = *src3++; /* Copy Y data */ - *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ - } - - src3 = src2; - for (i = 0; i < w; i++) { - *dst3++ = *src3++; /* Copy Y data */ - *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ - } - - dst2 += dstPitch; - src2 += srcPitch; - } -} - /*---------------------------------------------------------------------------- * GXCopyData420 * @@ -713,7 +683,6 @@ GXCopyData422(unsigned char *src, unsigned char *dst, static void GXVideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) { ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; - GeodeRec *pGeode = GEODEPTR(pScrni); GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); if (area == pPriv->area) @@ -726,20 +695,21 @@ GXAllocateMemory(ScrnInfoPtr pScrni, void **memp, int numlines) { ScreenPtr pScrn = screenInfo.screens[pScrni->scrnIndex]; GeodeRec *pGeode = GEODEPTR(pScrni); - long displayWidth = pGeode->AccelPitch / ((pScrni->bitsPerPixel + 7) / 8); + //long displayWidth = pGeode->Pitch / ((pScrni->bitsPerPixel + 7) / 8); + int size = numlines * pGeode->displayWidth; #if XF86EXA if (pGeode->useEXA) { ExaOffscreenArea *area = *memp; if (area != NULL) { - if (area->size >= (numlines * displayWidth)) + if (area->size >= size) return area->offset; exaOffscreenFree(pScrni->pScreen, area); } - area = exaOffscreenAlloc(pScrni->pScreen, numlines * displayWidth, 16, + area = exaOffscreenAlloc(pScrni->pScreen, size, 16, TRUE, GXVideoSave, NULL); *memp = area; @@ -756,13 +726,13 @@ GXAllocateMemory(ScrnInfoPtr pScrni, void **memp, int numlines) return (area->box.y1 * pGeode->Pitch); - if (xf86ResizeOffscreenArea(area, displayWidth, numlines)) + if (xf86ResizeOffscreenArea(area, pGeode->displayWidth, numlines)) return (area->box.y1 * pGeode->Pitch); xf86FreeOffscreenArea(area); } - new_area = xf86AllocateOffscreenArea(pScrn, displayWidth, + new_area = xf86AllocateOffscreenArea(pScrn, pGeode->displayWidth, numlines, 0, NULL, NULL, NULL); if (!new_area) { @@ -771,13 +741,13 @@ GXAllocateMemory(ScrnInfoPtr pScrni, void **memp, int numlines) xf86QueryLargestOffscreenArea(pScrn, &max_w, &max_h, 0, FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME); - if ((max_w < displayWidth) || (max_h < numlines)) { - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No room - how sad %x, %x, %x, %x\n", max_w, displayWidth, max_h, numlines); + if ((max_w < pGeode->displayWidth) || (max_h < numlines)) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No room - how sad %x, %x, %x, %x\n", max_w, pGeode->displayWidth, max_h, numlines); return 0; } xf86PurgeUnlockedOffscreenAreas(pScrn); - new_area = xf86AllocateOffscreenArea(pScrn, displayWidth, + new_area = xf86AllocateOffscreenArea(pScrn, pGeode->displayWidth, numlines, 0, NULL, NULL, NULL); } @@ -917,17 +887,19 @@ GXDisplayVideo(ScrnInfoPtr pScrni, * off */ - dcfg = gfx_read_vid32(DISPLAY_CONFIG); - misc = gfx_read_vid32(MISC); + + if (id != FOURCC_RGB565) { + dcfg = gfx_read_vid32(DISPLAY_CONFIG); + misc = gfx_read_vid32(MISC); + + lutflag = (!(misc & 1) && (dcfg & (1 << 21))); - if ((!(misc & 1)) && (!(dcfg & (1 << 21)))) { - /* xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "save graphics_lut\n"); */ + if (lutflag) get_gamma_ram(graphics_lut); - lutptr = graphics_lut; - } - /* Set the video gamma ram */ - GFX(set_video_palette(NULL)); + /* Set the video gamma ram */ + GFX(set_video_palette(NULL)); + } GFX(set_video_enable(1)); @@ -955,6 +927,11 @@ GXDisplayVideo(ScrnInfoPtr pScrni, GFX(set_video_format(VIDEO_FORMAT_YVYU)); GFX(set_video_size(width, height)); break; + case FOURCC_RGB565: + GFX(set_video_format(VIDEO_FORMAT_RGB)); + GFX(set_video_size(width, height)); + break; + } if (pGeode->Panel) { @@ -982,8 +959,9 @@ GXDisplayVideo(ScrnInfoPtr pScrni, src_h, drw_w, drw_h, id, offset, pScrni); } -#if REINIT -static Bool +/* Used by LX as well */ + +Bool RegionsEqual(RegionPtr A, RegionPtr B) { int *dataA, *dataB; @@ -1012,7 +990,6 @@ RegionsEqual(RegionPtr A, RegionPtr B) return TRUE; } -#endif /*---------------------------------------------------------------------------- * GXPutImage :This function writes a single frame of video into a @@ -1118,6 +1095,7 @@ GXPutImage(ScrnInfoPtr pScrni, case FOURCC_UYVY: case FOURCC_YUY2: case FOURCC_Y800: + case FOURCC_RGB565: default: dstPitch = ((width << 1) + 3) & ~3; srcPitch = (width << 1); @@ -1169,6 +1147,7 @@ GXPutImage(ScrnInfoPtr pScrni, case FOURCC_UYVY: case FOURCC_YUY2: case FOURCC_Y800: + case FOURCC_RGB565: default: left <<= 1; buf += (top * srcPitch) + left; @@ -1197,7 +1176,8 @@ GXPutImage(ScrnInfoPtr pScrni, #endif switch (id) { case FOURCC_Y800: - GXCopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels); + /* This is shared between LX and GX, so it lives in amd_common.c */ + GeodeCopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels); break; case FOURCC_YV12: case FOURCC_I420: @@ -1210,6 +1190,7 @@ GXPutImage(ScrnInfoPtr pScrni, break; case FOURCC_UYVY: case FOURCC_YUY2: + case FOURCC_RGB565: default: GXCopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels); break; @@ -1260,8 +1241,9 @@ GXPutImage(ScrnInfoPtr pScrni, * *---------------------------------------------------------------------------- */ -static int -GXQueryImageAttributes(ScrnInfoPtr pScrni, + +int +GeodeQueryImageAttributes(ScrnInfoPtr pScrni, int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets) { int size; @@ -1337,12 +1319,12 @@ GXBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) /* If we have saved graphics LUT data - restore it */ /* Otherwise, turn bypass on */ - if (lutptr != NULL) - GFX(set_graphics_palette(lutptr)); + if (lutflag) + GFX(set_graphics_palette(graphics_lut)); else - GFX(set_video_palette_bypass(1)); + GFX(set_video_palette_bypass(1)); - lutptr = NULL; + lutflag = 0; pPriv->videoStatus = FREE_TIMER; pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; diff --git a/src/amd_lx_accel.c b/src/amd_lx_accel.c deleted file mode 100644 index 3b65136..0000000 --- a/src/amd_lx_accel.c +++ /dev/null @@ -1,1559 +0,0 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. - * - * 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, - * 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. - * - * Neither the name of the Advanced Micro Devices, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - */ - -/* - * File Contents: This file is consists of main Xfree - * acceleration supported routines like solid fill used - * here. - * Project: Geode Xfree Frame buffer device driver. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* Xfree86 header files */ - -#include "vgaHW.h" -#include "xf86.h" -#include "xf86_ansic.h" -#include "xaalocal.h" -#include "xf86fbman.h" -#include "miline.h" -#include "xf86_libc.h" -#include "xaarop.h" -#include "amd.h" - -typedef unsigned char uchar; - -#if DEBUGLVL>0 -extern FILE *zdfp; - -#if DEBUGTIM>0 -#ifndef USE_RDTSC -#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) { long secs,usecs; \ - getsecs(&secs,&usecs); fprintf(zdfp,"%d,%d ",secs,usecs); \ - fprintf(zdfp,s); } } while(0) -#else -#define tsc(n) __asm__ __volatile__ ( \ - " rdtsc" \ - : "=a" (((int*)(&(n)))[0]), "=d" (((int*)(&(n)))[1]) \ - : ) -#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) { long long t; \ - tsc(t); fprintf(zdfp,"%lld ",t); \ - fprintf(zdfp,s); } } while(0) -#endif -#else -#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) fprintf(zdfp,s); } while(0) -#endif -#else -#define DBLOG(n,s...) do {} while(0) -#endif - -#define CALC_FBOFFSET(x, y) (((ulong)(y) << gu3_yshift) | \ - ((ulong)(x) << gu3_xshift)) - -#define OS_UDELAY 0 -#if OS_UDELAY > 0 -#define OS_USLEEP(usec) usleep(usec); -#else -#define OS_USLEEP(usec) -#endif - -#define HOOK(fn) localRecPtr->fn = LX##fn - -static int lx0 = -1, ly0 = -1; -static int lx1 = -1, ly1 = -1; -static int ROP; - -/* #define ENABLE_PREFETCH CIMGP_ENABLE_PREFETCH */ -#define ENABLE_PREFETCH 0 -#define BLTFLAGS_HAZARD CIMGP_BLTFLAGS_HAZARD - -/* specify dst bounding box, upper left/lower right */ -static int -lx_flags0(int x0, int y0, int x1, int y1) -{ - int n = ((ROP ^ (ROP >> 1)) & 0x55) == 0 || /* no dst */ - x0 >= lx1 || y0 >= ly1 || /* rght/below */ - x1 <= lx0 || y1 <= ly0 ? /* left/above */ - ENABLE_PREFETCH : BLTFLAGS_HAZARD; - - lx0 = x0; - ly0 = y0; - lx1 = x1; - ly1 = y1; - return n; -} - -/* specify dst bounding box, upper left/WxH */ -static int -lx_flags1(int x0, int y0, int w, int h) -{ - return lx_flags0(x0, y0, x0 + w, y0 + h); -} - -/* specify dst bounding box, two points */ -static int -lx_flags2(int x0, int y0, int x1, int y1) -{ - int n; - - if (x0 >= x1) { - n = x0; - x0 = x1 - 1; - x1 = n + 1; - } - if (y0 >= y1) { - n = y0; - y0 = y1 - 1; - y1 = n + 1; - } - - return lx_flags0(x0, y0, x1, y1); -} - -/* specify src/dst bounding box, upper left/WxH */ -static int -lx_flags3(int x0, int y0, int x1, int y1, int w, int h) -{ - int x2 = x1 + w, y2 = y1 + h; - - /* dst not hazzard and src not hazzard */ - int n = (((ROP ^ (ROP >> 1)) & 0x55) == 0 || - x1 >= lx1 || y1 >= ly1 || - x2 <= lx0 || y2 <= ly0) && - (((ROP ^ (ROP >> 2)) & 0x33) == 0 || - x0 >= lx1 || y0 >= ly1 || x0 + w <= lx0 || y0 + h <= ly0) - ? ENABLE_PREFETCH : BLTFLAGS_HAZARD; - - lx0 = x1; - ly0 = y1; - lx1 = x2; - ly1 = y2; - - return n; -} - -static void -lx_endpt(int x, int y, int len, int mag, int min, int err, int oct, int *px, - int *py) -{ - int u = len - 1; - int v = (u * min - err) / mag; - - switch (oct) { - default: - case 0: - x += u; - y += v; - break; - case 1: - x += v; - y += u; - break; - case 2: - x += u; - y -= v; - break; - case 3: - x += v; - y -= u; - break; - case 4: - x -= u; - y += v; - break; - case 5: - x -= v; - y += u; - break; - case 6: - x -= u; - y -= v; - break; - case 7: - x -= v; - y -= u; - break; - } - - *px = x; - *py = y; -} - -/* static storage declarations */ - -typedef struct sGBltBox -{ - ulong x, y; - ulong w, h; - ulong color; - int bpp, transparent; -} GBltBox; - -static GBltBox giwr; -static GBltBox gc2s; - -typedef struct sGDashLine -{ - ulong pat; - int len; - int fg; - int bg; -} GDashLine; - -static GDashLine gdln; - -static uint gu3_xshift = 1; -static uint gu3_yshift = 1; -static uint gu3_img_fmt = 0; - -#if !LX_USE_OFFSCRN_MEM -static uint ImgBufOffset; -#else -static uchar *ImgLnsBuffers; -#endif -static uchar *ClrLnsBuffers; -static XAAInfoRecPtr localRecPtr; - -static int lx_src_fmt[4] = { - CIMGP_SOURCE_FMT_8BPP_INDEXED, - CIMGP_SOURCE_FMT_0_5_6_5, - CIMGP_SOURCE_FMT_24BPP, - CIMGP_SOURCE_FMT_8_8_8_8 -}; - -/* pat 0xF0 */ -/* src 0xCC */ -/* dst 0xAA */ - -/* (src FUNC dst) */ - -static const int SDfn[16] = { - 0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE, - 0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF -}; - -/* ((src FUNC dst) AND pat-mask) OR (dst AND (NOT pat-mask)) */ - -static const int SDfn_PM[16] = { - 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, - 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA -}; - -/* (pat FUNC dst) */ - -static int PDfn[16] = { - 0x00, 0xA0, 0x50, 0xF0, 0x0A, 0xAA, 0x5A, 0xFA, - 0x05, 0xA5, 0x55, 0xF5, 0x0F, 0xAF, 0x5F, 0xFF -}; - -/* ((pat FUNC dst) AND src-mask) OR (dst AND (NOT src-mask)) */ - -static int PDfn_SM[16] = { - 0x22, 0xA2, 0x62, 0xE2, 0x2A, 0xAA, 0x6A, 0xEA, - 0x26, 0xA6, 0x66, 0xE6, 0x2E, 0xAE, 0x6E, 0xEE -}; - -/*---------------------------------------------------------------------------- - * LXAccelSync. - * - * Description :This function is called to synchronize with the graphics - * engine and it waits until the graphic engine is idle. - * This is required before allowing direct access to the - * framebuffer. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * - * Returns :none - *---------------------------------------------------------------------------*/ -void -LXAccelSync(ScrnInfoPtr pScrni) -{ - DBLOG(3, "LXAccelSync()\n"); - while (gp_test_blt_busy() != 0) { - OS_USLEEP(OS_UDELAY) - } -} - -#if LX_FILL_RECT_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForSolidFill. - * - * Description :The SetupFor and Subsequent SolidFill(Rect) provide - * filling rectangular areas of the screen with a - * foreground color. - * - * Parameters. - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * color int foreground fill color - * rop int unmapped raster op - * planemask uint -1 (fill) or pattern data - * - * Returns :none - *--------------------------------------------------------------------------*/ -static void -LXSetupForSolidFill(ScrnInfoPtr pScrni, int color, int rop, uint planemask) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, "LXSetupForSolidFill(%#x,%#x,%#x)\n", color, rop, planemask); - rop &= 0x0F; - gp_declare_blt(0); - if (planemask == ~0U) { /* fill with color */ - gp_set_raster_operation(ROP = SDfn[rop]); - } else { /* select rop that uses source data for planemask */ - gp_set_raster_operation(ROP = SDfn_PM[rop]); - gp_set_solid_pattern(planemask); - } - gp_set_solid_source(color); - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); -} - - /*---------------------------------------------------------------------------- - * LXSubsequentSolidFillRect. - * - * Description :see LXSetupForSolidFill. - * - * Parameters. - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x int destination x offset - * y int destination y offset - * w int fill area width (pixels) - * h int fill area height (pixels) - * - * Returns :none - * - * Sample application uses: - * - Window backgrounds. - * - pull down highlighting. - * - x11perf: rectangle tests (-rect500). - * - x11perf: fill trapezoid tests (-trap100). - * - x11perf: horizontal line segments (-hseg500). - *---------------------------------------------------------------------------*/ -static void -LXSubsequentSolidFillRect(ScrnInfoPtr pScrni, int x, int y, int w, int h) -{ - int flags; - - DBLOG(2, "LXSubsequentSolidFillRect() at %d,%d %dx%d\n", x, y, w, h); - flags = lx_flags1(x, y, w, h); - gp_declare_blt(flags); - gp_pattern_fill(CALC_FBOFFSET(x, y), w, h); -} - -/* LX_FILL_RECT_SUPPORT */ -#endif - -#if LX_CLREXP_8X8_PAT_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForColor8x8PatternFill - * - * Description :8x8 color pattern data is 64 pixels of full color data - * stored linearly in offscreen video memory. These patterns - * are useful as a substitute for 8x8 mono patterns when tiling, - * doing opaque stipples, or regular stipples. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * patx int x offset to pattern data - * paty int y offset to pattern data - * rop int unmapped raster operation - * planemask uint -1 (copy) or pattern data - * trans_color int -1 (copy) or transparent color (not enabled) - * trans color only supported on source channel - * or in monochrome pattern channel - * - * Returns :none. - * - *---------------------------------------------------------------------------*/ - -static void -LXSetupForColor8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, int rop, - uint planemask, int trans_color) -{ - unsigned long *pat_8x8; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, "LXSetupForColor8x8PatternFill() pat %#x,%#x rop %#x %#x %#x\n", - patx, paty, rop, planemask, trans_color); - pat_8x8 = (unsigned long *)(pGeode->FBBase + CALC_FBOFFSET(patx, paty)); - /* since the cache may be loaded by blt, we must wait here */ - LXAccelSync(pScrni); - gp_set_color_pattern(pat_8x8, gu3_img_fmt, 0, 0); - rop &= 0x0F; - gp_declare_blt(0); - if (planemask == ~0U) { /* fill with pattern */ - gp_set_raster_operation(ROP = PDfn[rop]); - } else { /* select rop that uses source data for planemask */ - gp_set_raster_operation(ROP = PDfn_SM[rop]); - gp_set_solid_source((ulong) planemask); - } - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); -} - -/*---------------------------------------------------------------------------- - * LXSubsequentColor8x8PatternFillRect - * - * Description :see LXSetupForColor8x8PatternFill. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * patx int pattern phase x offset - * paty int pattern phase y offset - * x int destination x offset - * y int destination y offset - * w int fill area width (pixels) - * h int fill area height (pixels) - * - * Returns :none - * - * Sample application uses: - * - Patterned desktops - * - x11perf: stippled rectangle tests (-srect500). - * - x11perf: opaque stippled rectangle tests (-osrect500). - *--------------------------------------------------------------------------*/ -static void -LXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty, - int x, int y, int w, int h) -{ - int flags; - - DBLOG(2, - "LXSubsequentColor8x8PatternFillRect() patxy %d,%d at %d,%d %dsx%d\n", - patx, paty, x, y, w, h); - flags = lx_flags1(x, y, w, h); - gp_declare_blt(flags); - gp_set_pattern_origin(patx, paty); - gp_pattern_fill(CALC_FBOFFSET(x, y), w, h); -} - -/* LX_CLREXP_8X8_PAT_SUPPORT */ -#endif - -#if LX_MONO_8X8_PAT_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForMono8x8PatternFill - * - * Description :8x8 mono pattern data is 64 bits of color expansion data - * with ones indicating the foreground color and zeros - * indicating the background color. These patterns are - * useful when tiling, doing opaque stipples, or regular - * stipples. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * patx int x offset to pattern data - * paty int y offset to pattern data - * fg int foreground color - * bg int -1 (transparent) or background color - * rop int unmapped raster operation - * planemask uint -1 (copy) or pattern data - * - * Returns :none. - * - * Comments :none. - * - *--------------------------------------------------------------------------*/ -static void -LXSetupForMono8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, - int fg, int bg, int rop, uint planemask) -{ - int trans; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, - "LXSetupForMono8x8PatternFill() pat %#x,%#x fg %#x bg %#x %#x %#x\n", - patx, paty, fg, bg, rop, planemask); - rop &= 0x0F; - gp_declare_blt(0); - if (planemask == ~0U) { /* fill with pattern */ - gp_set_raster_operation(ROP = PDfn[rop]); - } else { /* select rop that uses source data for planemask */ - gp_set_raster_operation(ROP = PDfn_SM[rop]); - gp_set_solid_source((ulong) planemask); - } - trans = bg == -1 ? 1 : 0; - gp_set_mono_pattern(bg, fg, patx, paty, trans, 0, 0); - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); -} - -/*---------------------------------------------------------------------------- - * LXSubsequentMono8x8PatternFillRect - * - * Description :see LXSetupForMono8x8PatternFill - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * patx int pattern phase x offset - * paty int pattern phase y offset - * x int destination x offset - * y int destination y offset - * w int fill area width (pixels) - * h int fill area height (pixels) - - * Returns :none - * - * Sample application uses: - * - Patterned desktops - * - x11perf: stippled rectangle tests (-srect500). - * - x11perf: opaque stippled rectangle tests (-osrect500). - *--------------------------------------------------------------------------*/ -static void -LXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty, - int x, int y, int w, int h) -{ - int flags; - - DBLOG(2, - "LXSubsequentMono8x8PatternFillRect() pat %#x,%#x at %d,%d %dx%d\n", - patx, paty, x, y, w, h); - flags = lx_flags1(x, y, w, h); - gp_declare_blt(flags); - gp_set_pattern_origin(patx, paty); - gp_pattern_fill(CALC_FBOFFSET(x, y), w, h); -} - -/* LX_MONO_8X8_PAT_SUPPORT */ -#endif - -#if LX_SCR2SCRCPY_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForScreenToScreenCopy - * - * Description :SetupFor and Subsequent ScreenToScreenCopy functions - * provide an interface for copying rectangular areas from - * video memory to video memory. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * xdir int x copy direction (up/dn) - * ydir int y copy direction (up/dn) - * rop int unmapped raster operation - * planemask uint -1 (copy) or pattern data - * trans_color int -1 (copy) or transparent color - * - * Returns :none - *---------------------------------------------------------------------------*/ -static void -LXSetupForScreenToScreenCopy(ScrnInfoPtr pScrni, int xdir, int ydir, int rop, - uint planemask, int trans_color) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, "LXSetupForScreenToScreenCopy() xd%d yd%d rop %#x %#x %#x\n", - xdir, ydir, rop, planemask, trans_color); - rop &= 0x0F; - gp_declare_blt(0); - if (planemask == ~0U) { - gp_set_raster_operation(ROP = SDfn[rop]); - } else { - gp_set_raster_operation(ROP = SDfn_PM[rop]); - gp_set_solid_pattern((ulong) planemask); - } - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); - gc2s.transparent = (trans_color == -1) ? 0 : 1; - gc2s.color = trans_color; -} - -/*---------------------------------------------------------------------------- - * LXSubsquentScreenToScreenCopy - * - * Description :see LXSetupForScreenToScreenCopy. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x1 int source x offset - * y1 int source y offset - * x2 int destination x offset - * y2 int destination y offset - * w int copy area width (pixels) - * h int copy area height (pixels) - * - * Returns :none - * - * Sample application uses (non-transparent): - * - Moving windows. - * - x11perf: scroll tests (-scroll500). - * - x11perf: copy from window to window (-copywinwin500). - *---------------------------------------------------------------------------*/ -static void -LXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrni, - int x1, int y1, int x2, int y2, int w, int h) -{ - int flags; - - DBLOG(2, "LXSubsequentScreenToScreenCopy() from %d,%d to %d,%d %dx%d\n", - x1, y1, x2, y2, w, h); - - flags = lx_flags3(x1, y1, x2, y2, w, h); - gp_declare_blt(flags); - - if (gc2s.transparent) { - gp_set_source_transparency(gc2s.color, ~0); - } - - flags = 0; - - if (x2 > x1) - flags |= 1; - if (y2 > y1) - flags |= 2; - - gp_screen_to_screen_blt(CALC_FBOFFSET(x2, y2), CALC_FBOFFSET(x1, y1), w, - h, flags); -} - -/* LX_SCR2SCRCPY_SUPPORT */ -#endif - -#if LX_SCANLINE_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForScanlineImageWrite - * - * Description :SetupFor/Subsequent ScanlineImageWrite and ImageWriteScanline - * transfer full color pixel data from system memory to video - * memory. This is useful for dealing with alignment issues and - * performing raster ops on the data. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * rop int unmapped raster operation - * planemask uint -1 (copy) or pattern data - * bpp int bits per pixel (unused) - * depth int color depth (unused) - * - * Returns :none - * - * x11perf -putimage10 - * x11perf -putimage100 - * x11perf -putimage500 -*---------------------------------------------------------------------------- -*/ -static void -LXSetupForScanlineImageWrite(ScrnInfoPtr pScrni, int rop, uint planemask, - int trans_color, int bpp, int depth) -{ - int Bpp = (bpp + 7) >> 3; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, "LXSetupForScanlineImageWrite() rop %#x %#x %#x %d %d\n", - rop, planemask, trans_color, bpp, depth); - rop &= 0x0F; - gp_set_source_format(lx_src_fmt[Bpp - 1]); - gp_declare_blt(0); - if (planemask == ~0U) { - gp_set_raster_operation(ROP = SDfn[rop]); - } else { - gp_set_raster_operation(ROP = SDfn_PM[rop]); - gp_set_solid_pattern(planemask); - } - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); - giwr.transparent = (trans_color == -1) ? 0 : 1; - giwr.color = trans_color; -} - -/*---------------------------------------------------------------------------- - * LXSubsequentScanlineImageWriteRect - * - * Description : see LXSetupForScanlineImageWrite. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x int destination x offset - * y int destination y offset - * w int copy area width (pixels) - * h int copy area height (pixels) - * skipleft int x margin (pixels) to skip (not enabled) - * - * Returns :none - *---------------------------------------------------------------------------*/ -static void -LXSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrni, - int x, int y, int w, int h, int skipleft) -{ - DBLOG(2, "LXSubsequentScanlineImageWriteRect() rop %d,%d %dx%d %d\n", x, - y, w, h, skipleft); - giwr.x = x; - giwr.y = y; - giwr.w = w; - giwr.h = h; - /* since the image buffer must be not busy (it may be busy from - * a previous ScanlineWriteImage), we must add a Sync here */ -#if !LX_USE_OFFSCRN_MEM - LXAccelSync(pScrni); -#endif -} - -/*---------------------------------------------------------------------------- - * LXSubsquentImageWriteScanline - * - * Description : see LXSetupForScanlineImageWrite. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * bufno int scanline number in write group - * - * Returns :none - * - * Sample application uses (non-transparent): - * - Moving windows. - * - x11perf: scroll tests (-scroll500). - * - x11perf: copy from window to window (-copywinwin500). - * - *---------------------------------------------------------------------------*/ -static void -LXSubsequentImageWriteScanline(ScrnInfoPtr pScrni, int bufno) -{ - GeodeRec *pGeode; - int blt_height = 0; - - DBLOG(3, "LXSubsequentImageWriteScanline() %d\n", bufno); - pGeode = GEODEPTR(pScrni); - - if ((blt_height = pGeode->NoOfImgBuffers) > giwr.h) - blt_height = giwr.h; - if (++bufno < blt_height) - return; - - gp_declare_blt(ENABLE_PREFETCH); - if (giwr.transparent) { - gp_set_source_transparency(giwr.color, ~0); - } -#if !LX_USE_OFFSCRN_MEM - gp_screen_to_screen_blt(CALC_FBOFFSET(giwr.x, giwr.y), ImgBufOffset, - giwr.w, blt_height, 0); - LXAccelSync(pScrni); -#else - gp_color_bitmap_to_screen_blt(CALC_FBOFFSET(giwr.x, giwr.y), 0, - giwr.w, blt_height, ImgLnsBuffers, pGeode->AccelPitch); -#endif - giwr.h -= blt_height; - giwr.y += blt_height; -} - -/* LX_SCANLINE_SUPPORT */ -#endif - -#if LX_CPU2SCREXP_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForScanlineCPUToScreenColorExpandFill - * - * Description :SetupFor/Subsequent CPUToScreenColorExpandFill and - * ColorExpandScanline routines provide an interface for - * doing expansion blits from source patterns stored in - * system memory. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * fg int foreground color - * bg int -1 (transparent) or background color - * rop int unmapped raster operation - * planemask uint -1 (copy) or pattern data - * - * Returns :none. - *---------------------------------------------------------------------------*/ - -static void -LXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni, - int fg, int bg, int rop, uint planemask) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, - "LXSetupForScanlineCPUToScreenColorExpandFill() " - "fg %#x bg %#x rop %#x %#x\n", fg, bg, rop, planemask); - rop &= 0x0F; - gp_declare_blt(0); - if (planemask == ~0U) { - gp_set_raster_operation(ROP = SDfn[rop]); - } else { - gp_set_raster_operation(ROP = SDfn_PM[rop]); - gp_set_solid_pattern(planemask); - } - gp_set_mono_source(bg, fg, (bg == -1)); - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); - gc2s.bpp = 1; - gc2s.transparent = 0; - gc2s.color = 0; -} - -/*---------------------------------------------------------------------------- - * LXSubsequentScanlineCPUToScreenColorExpandFill - * - * Description :see LXSetupForScanlineCPUToScreenColorExpandFill - * - * Parameters: - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x int destination x offset - * y int destination y offset - * w int fill area width (pixels) - * h int fill area height (pixels) - * - * Returns :none - * - *---------------------------------------------------------------------------*/ -static void -LXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni, - int x, int y, int w, int h, int skipleft) -{ - DBLOG(2, - "LXSubsequentScanlineCPUToScreenColorExpandFill() %d,%d %dx%d %d\n", - x, y, w, h, skipleft); - gc2s.x = x; - gc2s.y = y; - gc2s.w = w; - gc2s.h = h; -} - -/*---------------------------------------------------------------------------- - * LXSubsequentColorExpandScanline - * - * Description :see LXSetupForScanlineCPUToScreenColorExpandFill - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * bufno int scanline number in write group - * - * Returns :none -*---------------------------------------------------------------------------- -*/ -static void -LXSubsequentColorExpandScanline(ScrnInfoPtr pScrni, int bufno) -{ - GeodeRec *pGeode; - ulong srcpitch; - int blt_height = 0; - - DBLOG(3, "LXSubsequentColorExpandScanline() %d\n", bufno); - pGeode = GEODEPTR(pScrni); - - if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h) - blt_height = gc2s.h; - if (++bufno < blt_height) - return; - - gp_declare_blt(ENABLE_PREFETCH); - /* convert from bits to dwords */ - srcpitch = ((pGeode->AccelPitch + 31) >> 5) << 2; - gp_mono_bitmap_to_screen_blt(CALC_FBOFFSET(gc2s.x, gc2s.y), 0, gc2s.w, - blt_height, ClrLnsBuffers, srcpitch); - gc2s.h -= blt_height; - gc2s.y += blt_height; -} - -/* LX_CPU2SCREXP_SUPPORT */ -#endif - -#if LX_SCR2SCREXP_SUPPORT - -/*---------------------------------------------------------------------------- - * LXSetupForScreenToScreenColorExpandFill - * - * Description :SetupFor/Subsequent ScreenToScreenColorExpandFill and - * ColorExpandScanline routines provide an interface for - * doing expansion blits from source patterns stored in - * video memory. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * fg int foreground color - * bg int -1 (transparent) or background color - * rop int unmapped raster operation - * planemask uint -1 (copy) or pattern data - * - * Returns :none. - *---------------------------------------------------------------------------*/ - -static void -LXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, int fg, int bg, - int rop, uint planemask) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, - "LXSetupForScreenToScreenColorExpandFill() " - "fg %#x bg %#x rop %#x %#x\n", fg, bg, rop, planemask); - rop &= 0x0F; - gp_declare_blt(0); - if (planemask == ~0U) { - gp_set_raster_operation(ROP = SDfn[rop]); - } else { - gp_set_raster_operation(ROP = SDfn_PM[rop]); - gp_set_solid_pattern(planemask); - } - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_set_mono_source(bg, fg, (bg == -1)); - gp_write_parameters(); -} - -/*---------------------------------------------------------------------------- - * LXSubsequentScreenToScreenColorExpandFill - * - * Description :see LXSetupForScreenToScreenColorExpandFill - * - * Parameters: - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x int destination x offset - * y int destination y offset - * w int fill area width (pixels) - * h int fill area height (pixels) - * offset int initial x offset - * - * Returns :none - * - *---------------------------------------------------------------------------*/ -static void -LXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, - int x, int y, int w, int h, int srcx, int srcy, int offset) -{ - int flags; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, - "LXSubsequentScreenToScreenColorExpandFill() %d,%d %dx%d %d,%d %d\n", - x, y, w, h, srcx, srcy, offset); - flags = lx_flags3(srcx, srcy, x, y, w, h); - gp_declare_blt(flags); - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_mono_expand_blt(CALC_FBOFFSET(x, y), CALC_FBOFFSET(srcx, srcy), offset, - w, h, 0); -} - -/* LX_SCR2SCREXP_SUPPORT */ -#endif - -#define VM_X_MAJOR 0 -#define VM_Y_MAJOR 1 -#define VM_MAJOR_INC 2 -#define VM_MAJOR_DEC 0 -#define VM_MINOR_INC 4 -#define VM_MINOR_DEC 0 - -static ushort vmode[] = { - VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_INC, /* !XDECR !YDECR !YMAJOR */ - VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_INC, /* !XDECR !YDECR YMAJOR */ - VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC, /* !XDECR YDECR !YMAJOR */ - VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC, /* !XDECR YDECR YMAJOR */ - VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC, /* XDECR !YDECR !YMAJOR */ - VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC, /* XDECR !YDECR YMAJOR */ - VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC, /* XDECR YDECR !YMAJOR */ - VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC, /* XDECR YDECR YMAJOR */ -}; - -#define ABS(_val1, _val2) (((_val1) > (_val2)) ? \ - ((_val1)-(_val2)) : ((_val2) - (_val1))) - -#if LX_BRES_LINE_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForSolidLine - * - * Description :SetupForSolidLine and Subsequent HorVertLine TwoPointLine - * BresenhamLine provides an interface for drawing thin - * solid lines. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * color int foreground fill color - * rop int unmapped raster op - * planemask uint -1 (fill) or pattern data (not enabled) - * - * Returns :none -*---------------------------------------------------------------------------*/ -static void -LXSetupForSolidLine(ScrnInfoPtr pScrni, int color, int rop, uint planemask) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, "LXSetupForSolidLine() %#x %#x %#x\n", color, rop, planemask); - rop &= 0x0F; - gp_declare_vector(CIMGP_BLTFLAGS_HAZARD); - if (planemask == ~0U) { - gp_set_raster_operation(ROP = PDfn[rop]); - } else { - gp_set_raster_operation(ROP = PDfn_SM[rop]); - gp_set_solid_source(planemask); - } - gp_set_solid_pattern((ulong) color); - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); -} - -/*--------------------------------------------------------------------------- - * LXSubsequentSolidBresenhamLine - * - * Description :see LXSetupForSolidLine - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x1 int destination x offset - * y1 int destination y offset - * absmaj int Bresenman absolute major - * absmin int Bresenman absolute minor - * err int Bresenman initial error term - * len int length of the vector (pixels) - * octant int specifies sign and magnitude relationships - * used to determine axis of magor rendering - * and direction of vector progress. - * - * Returns :none - * - * - Window outlines on window move. - * - x11perf: line segments (-line500). - * - x11perf: line segments (-seg500). - *---------------------------------------------------------------------------*/ -static void -LXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1, - int absmaj, int absmin, int err, int len, int octant) -{ - int x2, y2, flags; - long axial, diagn; - - DBLOG(2, "LXSubsequentSolidBresenhamLine() %d,%d %d %d, %d %d, %d\n", - x1, y1, absmaj, absmin, err, len, octant); - if (len <= 0) - return; - lx_endpt(x1, y1, len, absmaj, absmin, err, octant, &x2, &y2); - flags = lx_flags2(x1, y1, x2 + 1, y2 + 1); - gp_declare_vector(flags); - axial = absmin; - err += axial; - diagn = absmin - absmaj; - gp_bresenham_line(CALC_FBOFFSET(x1, y1), len, err, axial, diagn, - vmode[octant]); -} - -/*--------------------------------------------------------------------------- - * LXSubsequentSolidTwoPointLine - * - * Description :see LXSetupForSolidLine - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x0 int destination x start offset - * y0 int destination y start offset - * x1 int destination x end offset - * y1 int destination y end offset - * flags int OMIT_LAST, dont draw last pixel (not used) - * - * Returns :none - *---------------------------------------------------------------------------*/ -static void -LXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0, - int x1, int y1, int flags) -{ - long dx, dy, dmaj, dmin, octant, bias; - long axial, diagn, err, len; - - DBLOG(2, "LXSubsequentSolidTwoPointLine() %d,%d %d,%d, %#x\n", - x0, y0, x1, y1, flags); - - if ((dx = x1 - x0) < 0) - dx = -dx; - if ((dy = y1 - y0) < 0) - dy = -dy; - - if (dy >= dx) { - dmaj = dy; - dmin = dx; - octant = YMAJOR; - } else { - dmaj = dx; - dmin = dy; - octant = 0; - } - len = dmaj; - if ((flags & OMIT_LAST) == 0) - ++len; - if (len <= 0) - return; - if (x1 < x0) - octant |= XDECREASING; - if (y1 < y0) - octant |= YDECREASING; - - flags = lx_flags2(x0, y0, x1 + 1, y1 + 1); - gp_declare_vector(flags); - axial = dmin << 1; - bias = miGetZeroLineBias(pScrni->pScreen); - err = axial - dmaj - ((bias >> octant) & 1); - diagn = (dmin - dmaj) << 1; - gp_bresenham_line(CALC_FBOFFSET(x0, y0), len, err, axial, diagn, - vmode[octant]); -} - -/*--------------------------------------------------------------------------- - * LXSubsequentSolidHorVertLine - * - * Description :see LXSetupForSolidLine - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x int destination x offset - * y int destination y offset - * len int length of the vector (pixels) - * dir int DEGREES_270 or DEGREES_0 line direction - * - * Sample application uses: - * - Window outlines on window move. - * - x11perf: line segments (-hseg500). - * - x11perf: line segments (-vseg500). - *--------------------------------------------------------------------------- - */ -static void -LXSubsequentSolidHorVertLine(ScrnInfoPtr pScrni, - int x, int y, int len, int dir) -{ - int flags, w, h; - - DBLOG(2, "LXSubsequentHorVertLine() %d,%d %d %d\n", x, y, len, dir); - gp_declare_blt(0); - if (dir == DEGREES_0) { - w = len; - h = 1; - } else { - w = 1; - h = len; - } - flags = lx_flags1(x, y, w, h); - gp_declare_blt(flags); - gp_pattern_fill(CALC_FBOFFSET(x, y), ((dir == DEGREES_0) ? len : 1), - ((dir == DEGREES_0) ? 1 : len)); -} - -/* LX_BRES_LINE_SUPPORT */ -#endif - -#if LX_DASH_LINE_SUPPORT -/*---------------------------------------------------------------------------- - * LXSetupForDashedLine - * - * Description :SetupForDashedLine and Subsequent TwoPointLine - * BresenhamLine provides an interface for drawing thin - * dashed lines. - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * fg int foreground fill color - * bg int -1 (transp) or background fill color - * rop int unmapped raster op - * planemask uint -1 (fill) or pattern data (not enabled) - * length int pattern length (bits) - * pattern uchar* dash pattern mask - * - * Returns :none -*---------------------------------------------------------------------------*/ -static void -LXSetupForDashedLine(ScrnInfoPtr pScrni, - int fg, int bg, int rop, uint planemask, int length, uchar * pattern) -{ - int n; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, - "LXSetupForDashedLine() " - "fg %#x bg %#x rop %#x pm %#x len %d, pat %#x\n", - fg, bg, rop, planemask, length, *(ulong *) pattern); - gdln.fg = fg; - gdln.bg = bg; - gdln.len = length; - n = (length + 7) / 8; - if (n > sizeof(gdln.pat)) - n = sizeof(gdln.pat); - memcpy(&gdln.pat, pattern, n); - rop &= 0x0F; - gp_declare_vector(CIMGP_BLTFLAGS_HAZARD); - if (planemask == ~0U) { - gp_set_raster_operation(ROP = PDfn[rop]); - } else { - gp_set_raster_operation(ROP = PDfn_SM[rop]); - gp_set_solid_source(planemask); - } - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - gp_write_parameters(); -} - -/*--------------------------------------------------------------------------- - * LXSubsequentDashedBresenhamLine - * - * Description :see LXSetupForDashedLine - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x1 int destination x offset - * y1 int destination y offset - * absmaj int Bresenman absolute major - * absmin int Bresenman absolute minor - * err int Bresenman initial error term - * len int length of the vector (pixels) - * octant int specifies sign and magnitude relationships - * used to determine axis of magor rendering - * and direction of vector progress. - * phase int initial pattern offset at x1,y1 - * - * Returns :none - *---------------------------------------------------------------------------*/ -static void -LXSubsequentDashedBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1, - int absmaj, int absmin, int err, int len, int octant, int phase) -{ - int x2, y2, flags; - long axial, diagn; - ulong pattern; - - DBLOG(2, "LXSubsequentDashedBresenhamLine() %d,%d %d %d, %d %d, %d %d\n", - x1, y1, absmaj, absmin, err, len, octant, phase); - if (len <= 0) - return; - pattern = gdln.pat; - if (phase > 0) { - int n = gdln.len - phase; - - pattern = ((pattern >> phase) & ((1UL << n) - 1)) | (pattern << n); - } - gp_set_vector_pattern(pattern, gdln.fg, gdln.len); - lx_endpt(x1, y1, len, absmaj, absmin, err, octant, &x2, &y2); - flags = lx_flags2(x1, y1, x2 + 1, y2 + 1); - gp_declare_vector(flags); - axial = absmin; - err += axial; - diagn = absmin - absmaj; - gp_bresenham_line(CALC_FBOFFSET(x1, y1), len, err, axial, diagn, - vmode[octant]); -} - -/*--------------------------------------------------------------------------- - * LXSubsequentDashedTwoPointLine - * - * Description :see LXSetupForDashedLine - * - * Arg Type Comment - * pScrni ScrnInfoPtr pointer to Screeen info - * x0 int destination x start offset - * y0 int destination y start offset - * x1 int destination x end offset - * y1 int destination y end offset - * flags int OMIT_LAST, dont draw last pixel (not used) - * phase int initial pattern offset at x1,y1 - * - * Returns :none - *---------------------------------------------------------------------------*/ -static void -LXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0, - int x1, int y1, int flags, int phase) -{ - ulong pattern; - long dx, dy, dmaj, dmin, octant, bias; - long axial, diagn, err, len; - - DBLOG(2, "LXSubsequentDashedTwoPointLine() %d,%d %d,%d, %#x %d\n", - x0, y0, x1, y1, flags, phase); - - if ((dx = x1 - x0) < 0) - dx = -dx; - if ((dy = y1 - y0) < 0) - dy = -dy; - if (dy >= dx) { - dmaj = dy; - dmin = dx; - octant = YMAJOR; - } else { - dmaj = dx; - dmin = dy; - octant = 0; - } - len = dmaj; - if ((flags & OMIT_LAST) == 0) - ++len; - if (len <= 0) - return; - if (x1 < x0) - octant |= XDECREASING; - if (y1 < y0) - octant |= YDECREASING; - - pattern = gdln.pat; - if (phase > 0) { - int n = gdln.len - phase; - - pattern = ((pattern >> phase) & ((1UL << n) - 1)) | (pattern << n); - } - gp_set_vector_pattern(pattern, gdln.fg, gdln.len); - flags = lx_flags2(x0, y0, x1 + 1, y1 + 1); - gp_declare_vector(flags); - - axial = dmin << 1; - bias = miGetZeroLineBias(pScrni->pScreen); - err = axial - dmaj - ((bias >> octant) & 1); - diagn = (dmin - dmaj) << 1; - gp_bresenham_line(CALC_FBOFFSET(x0, y0), len, err, axial, diagn, - vmode[octant]); -} - -/* LX_DASH_LINE_SUPPORT */ -#endif - -#if LX_WRITE_PIXMAP_SUPPORT -void -LXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h, - unsigned char *src, int srcwidth, int rop, - unsigned int planemask, int trans, int bpp, int depth) -{ - int flags, dx, dy; - int Bpp = (bpp + 7) >> 3; - unsigned long offset; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(2, "LXWritePixmap() %d,%d %dx%d, s%#x sp%d %#x %#x %#x %d %d\n", - x, y, w, h, src, srcwidth, rop, planemask, trans, bpp, depth); - - rop &= 0x0F; - gp_set_source_format(lx_src_fmt[Bpp - 1]); - /* must assign before lx_flags */ - ROP = planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]; - - if (src >= pGeode->FBBase && src < pGeode->FBBase + pGeode->FBSize) { - offset = src - pGeode->FBBase; - dx = (offset & ((1 << gu3_yshift) - 1)) >> Bpp; - dy = offset >> gu3_yshift; - flags = lx_flags3(x, y, dx, dy, w, h); - } else - flags = ENABLE_PREFETCH; - - gp_declare_blt(flags); - gp_set_raster_operation(ROP); - if (planemask != ~0U) - gp_set_solid_pattern(planemask); - gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch); - if (trans != -1) { - gp_set_source_transparency(trans, ~0); - } - - gp_color_bitmap_to_screen_blt(CALC_FBOFFSET(x, y), 0, w, h, src, - srcwidth); - SET_SYNC_FLAG(pGeode->AccelInfoRec); -} -#endif - -/*---------------------------------------------------------------------------- - * LXAccelInit. - * - * Description :Create and initialize XAAInfoRec structure. - * The XAAInfoRec structure contains many fields, most of - * which are primitive function pointers and flags. Each - * primitive will have two or more functions and a set of - * associated associated flags. These functions can be - * classified into two principle classes, the "SetupFor" - * and "Subsequent" functions. The "SetupFor" function tells - * the driver that the hardware should be initialized for - * a particular type of graphics operation. After the - * "SetupFor" function, one or more calls to the "Subsequent" - * function will be made to indicate that an instance of the - * particular primitive should be rendered by the hardware. - * - * Arg Type Comment - * pScrn ScreenPtr pointer to active Screen data - * - * Returns :TRUE on success and FALSE on Failure - * - * Comments :This function is called in LXScreenInit in - * amd_lx_driver.c to initialize acceleration. - *---------------------------------------------------------------------------*/ -Bool -LXAccelInit(ScreenPtr pScrn) -{ - GeodeRec *pGeode; - ScrnInfoPtr pScrni; - -#if DEBUGLVL>0 - if (zdfp == NULL) { - zdfp = fopen("/tmp/xwin.log", "w"); - setbuf(zdfp, NULL); - } -#endif - DBLOG(2, "LXAccelInit()\n"); - - pScrni = xf86Screens[pScrn->myNum]; - pGeode = GEODEPTR(pScrni); - - switch (pScrni->bitsPerPixel) { - case 8: - gu3_img_fmt = CIMGP_SOURCE_FMT_3_3_2; - break; - case 16: - gu3_img_fmt = CIMGP_SOURCE_FMT_0_5_6_5; - break; - case 32: - gu3_img_fmt = CIMGP_SOURCE_FMT_8_8_8_8; - break; - } - - gu3_xshift = pScrni->bitsPerPixel >> 4; - - switch (pGeode->AccelPitch) { - case 1024: - gu3_yshift = 10; - break; - case 2048: - gu3_yshift = 11; - break; - case 4096: - gu3_yshift = 12; - break; - case 8192: - gu3_yshift = 13; - break; - } - - /* Getting the pointer for acceleration Inforecord */ - pGeode->AccelInfoRec = localRecPtr = XAACreateInfoRec(); - - /* SET ACCELERATION FLAGS */ - localRecPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | - LINEAR_FRAMEBUFFER; - - /* HOOK SYNCRONIZARION ROUTINE */ - localRecPtr->Sync = LXAccelSync; - -#if LX_FILL_RECT_SUPPORT - /* HOOK FILLED RECTANGLES */ - HOOK(SetupForSolidFill); - HOOK(SubsequentSolidFillRect); - localRecPtr->SolidFillFlags = 0; -#endif - -#if LX_MONO_8X8_PAT_SUPPORT - /* HOOK 8x8 Mono EXPAND PATTERNS */ - HOOK(SetupForMono8x8PatternFill); - HOOK(SubsequentMono8x8PatternFillRect); - localRecPtr->Mono8x8PatternFillFlags = - BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | - HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_PROGRAMMED_ORIGIN; -#endif - -#if LX_CLREXP_8X8_PAT_SUPPORT - /* Color expansion */ - HOOK(SetupForColor8x8PatternFill); - HOOK(SubsequentColor8x8PatternFillRect); - localRecPtr->Color8x8PatternFillFlags = - BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | - NO_TRANSPARENCY | HARDWARE_PATTERN_PROGRAMMED_ORIGIN; -#endif - -#if LX_SCR2SCRCPY_SUPPORT - /* HOOK SCREEN TO SCREEN COPIES - * Set flag to only allow copy if transparency is enabled. - */ - HOOK(SetupForScreenToScreenCopy); - HOOK(SubsequentScreenToScreenCopy); - localRecPtr->ScreenToScreenCopyFlags = - BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; -#endif - -#if LX_BRES_LINE_SUPPORT - /* HOOK BRESENHAM SOLID LINES */ - localRecPtr->SolidLineFlags = NO_PLANEMASK; - HOOK(SetupForSolidLine); - HOOK(SubsequentSolidBresenhamLine); - HOOK(SubsequentSolidHorVertLine); - HOOK(SubsequentSolidTwoPointLine); - localRecPtr->SolidBresenhamLineErrorTermBits = 15; -#endif - -#if LX_DASH_LINE_SUPPORT - /* HOOK BRESENHAM DASHED LINES */ - localRecPtr->DashedLineFlags = NO_PLANEMASK | TRANSPARENCY_ONLY | - LINE_PATTERN_LSBFIRST_LSBJUSTIFIED | SCANLINE_PAD_DWORD; - HOOK(SetupForDashedLine); - HOOK(SubsequentDashedBresenhamLine); - HOOK(SubsequentDashedTwoPointLine); - localRecPtr->DashedBresenhamLineErrorTermBits = 15; - localRecPtr->DashPatternMaxLength = 32; -#endif - -#if LX_SCR2SCREXP_SUPPORT - /* Color expansion */ - HOOK(SetupForScreenToScreenColorExpandFill); - HOOK(SubsequentScreenToScreenColorExpandFill); - localRecPtr->ScreenToScreenColorExpandFillFlags = - BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; -#endif - - if (pGeode->AccelImageWriteBuffers) { -#if LX_SCANLINE_SUPPORT - localRecPtr->ScanlineImageWriteBuffers = - pGeode->AccelImageWriteBuffers; - localRecPtr->NumScanlineImageWriteBuffers = pGeode->NoOfImgBuffers; - HOOK(SetupForScanlineImageWrite); - HOOK(SubsequentScanlineImageWriteRect); - HOOK(SubsequentImageWriteScanline); - localRecPtr->ScanlineImageWriteFlags = - BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; -#endif -#if !LX_USE_OFFSCRN_MEM - ImgBufOffset = pGeode->AccelImageWriteBuffers[0] - pGeode->FBBase; -#else - ImgLnsBuffers = (uchar *) pGeode->AccelImageWriteBuffers[0]; -#endif - } else { - localRecPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES; - } - - if (pGeode->AccelColorExpandBuffers) { -#if LX_CPU2SCREXP_SUPPORT - /* Color expansion */ - localRecPtr->ScanlineColorExpandBuffers = - pGeode->AccelColorExpandBuffers; - localRecPtr->NumScanlineColorExpandBuffers = - pGeode->NoOfColorExpandLines; - HOOK(SetupForScanlineCPUToScreenColorExpandFill); - HOOK(SubsequentScanlineCPUToScreenColorExpandFill); - HOOK(SubsequentColorExpandScanline); - localRecPtr->ScanlineCPUToScreenColorExpandFillFlags = - BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; -#endif - ClrLnsBuffers = (uchar *) pGeode->AccelColorExpandBuffers[0]; - } -#if LX_WRITE_PIXMAP_SUPPORT - HOOK(WritePixmap); -#endif - - return (XAAInit(pScrn, localRecPtr)); -} - -/* END OF FILE */ diff --git a/src/amd_lx_cursor.c b/src/amd_lx_cursor.c index 5417d4b..61094b3 100644 --- a/src/amd_lx_cursor.c +++ b/src/amd_lx_cursor.c @@ -1,12 +1,11 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. +/* Copyright (c) 2003-2007 Advanced Micro Devices, Inc. * - * 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: + * 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. @@ -16,21 +15,13 @@ * 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. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. * * Neither the name of the Advanced Micro Devices, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. - */ - -/* - * File Contents: Xfree cursor implementation routines - * for geode HWcursor init.setting cursor color,image etc - * are done here. - * Project: Geode Xfree Frame buffer device driver. - * - */ + * */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -44,32 +35,13 @@ #include "amd.h" /* Forward declarations of the functions */ -Bool LXHWCursorInit(ScreenPtr pScrn); static void LXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg); static void LXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y); -void LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src); -void LXHideCursor(ScrnInfoPtr pScrni); -void LXShowCursor(ScrnInfoPtr pScrni); static Bool LXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs); extern void LXSetVideoPosition(int x, int y, int width, int height, short src_w, short src_h, short drw_w, - short drw_h, int id, int offset, ScrnInfoPtr pScrni); + short drw_h, int id, int offset, ScrnInfoPtr pScrn); -/*---------------------------------------------------------------------------- - * LXHWCursorInit. - * - * Description :This function sets the cursor information by probing the - * hardware. - * - * Parameters. - * pScrn :Screeen pointer structure. - * - * Returns :TRUE on success and FALSE on Failure - * - * Comments :Geode supports the hardware_cursor,no need to enable SW - * cursor. -*---------------------------------------------------------------------------- -*/ Bool LXHWCursorInit(ScreenPtr pScrn) { @@ -80,7 +52,7 @@ LXHWCursorInit(ScreenPtr pScrn) infoPtr = xf86CreateCursorInfoRec(); if (!infoPtr) return FALSE; - /* the geode structure is initialized with the cursor infoRec */ + /* the geode structure is intiallized with the cursor infoRec */ pGeode->CursorInfo = infoPtr; infoPtr->MaxWidth = 32; infoPtr->MaxHeight = 32; @@ -88,9 +60,7 @@ LXHWCursorInit(ScreenPtr pScrn) infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED; - /* cursor info ptr is initialized with the values obtained from - * cimarron calls - */ + infoPtr->SetCursorColors = LXSetCursorColors; infoPtr->SetCursorPosition = LXSetCursorPosition; infoPtr->LoadCursorImage = LXLoadCursorImage; @@ -101,90 +71,65 @@ LXHWCursorInit(ScreenPtr pScrn) return (xf86InitCursor(pScrn, infoPtr)); } -/*---------------------------------------------------------------------------- - * LXSetCursorColors. - * - * Description :This function sets the cursor foreground and background - * colors - * Parameters: - * pScrni: Screeen information pointer structure. - * bg: Specifies the color value of cursor background color. - * fg: Specifies the color value of cursor foreground color. - * Returns: none. - * - * Comments: The integer color value passed by this function is - * converted into * RGB value by the gfx_set_color routines. - *---------------------------------------------------------------------------- - */ static void LXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg) { - vg_set_mono_cursor_colors(bg, fg); + vg_set_mono_cursor_colors(bg, fg); } -/*---------------------------------------------------------------------------- - * LXSetCursorPosition. - * - * Description :This function sets the cursor co -ordinates and enable the - * cursor. - * - * Parameters: - * pScrni: Screeen information pointer structure. - * x: Specifies the x-cordinates of the cursor. - * y: Specifies the y co-ordinate of the cursor. - * Returns: none. - * - *---------------------------------------------------------------------------- - */ static void LXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y) { - static unsigned long panOffset = 0; GeodeRec *pGeode = GEODEPTR(pScrni); - VG_PANNING_COORDINATES panning; + int savex, savey; int newX, newY; + int hsx, hsy; + + /* Adjust xf86HWCursor messing about */ + + savex = x + pScrni->frameX0; + savey = y + pScrni->frameY0; + + switch(pGeode->rotation) { + default: + ErrorF("%s:%d invalid rotation %d\n", __func__, __LINE__, pGeode->rotation); + case RR_Rotate_0: + newX = savex; newY = savey; + hsx= 31; hsy = 31; + break; + + case RR_Rotate_270: + newX = savey; + newY = pScrni->pScreen->width - savex; + hsx= 31; hsy = 0; + break; + + case RR_Rotate_180: + newX = pScrni->pScreen->width - savex; + newY = pScrni->pScreen->height - savey; + hsx = 0; hsy = 0; + break; + + case RR_Rotate_90: + newX = pScrni->pScreen->height - savey; + newY = savex; + hsx= 0; hsy= 31; + break; + } - (*pGeode->Rotation) (x, y, pGeode->HDisplay, pGeode->VDisplay, &newX, - &newY); - (*pGeode->RBltXlat) (newX, newY, 32, 32, &newX, &newY); + newX -= pScrni->frameX0; + newY -= pScrni->frameY0; - if (newX < -31) - newX = -31; - if (newY < -31) - newY = -31; + { + VG_PANNING_COORDINATES panning; + vg_set_cursor_position(newX + hsx, newY + hsy, &panning); + } - vg_set_cursor_position(newX + 31, newY + 31, &panning); vg_set_cursor_enable(1); -#ifndef AMD_V4L2_VIDEO - if ((pGeode->OverlayON) && (pGeode->EnabledOutput & LX_OT_FP)) { - pGeode->PrevDisplayOffset = vg_get_display_offset(); - if (pGeode->PrevDisplayOffset != panOffset) { - LXSetVideoPosition(pGeode->video_x, pGeode->video_y, - pGeode->video_w, pGeode->video_h, - pGeode->video_srcw, pGeode->video_srch, - pGeode->video_dstw, pGeode->video_dsth, - pGeode->video_id, pGeode->video_offset, - pGeode->video_scrnptr); - panOffset = pGeode->PrevDisplayOffset; - } - } -#endif + /* FIXME: Adjust for video panning? */ } -/*---------------------------------------------------------------------------- - * LXLoadCursorImage - * - * Description :This function loads the 32x32 cursor pattern.The shape - * and color is set by AND and XOR masking of arrays of 32 - * DWORD. - * Parameters: - * pScrni: Screeen information pointer structure. - * src : Specifies cursor data. - * Returns : none - * - *---------------------------------------------------------------------------- -*/ void LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src) { @@ -207,7 +152,29 @@ LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src) ++rowp; ++mskp; } - (*pGeode->Rotation) (x, y, 32, 32, &newX, &newY); + + switch(pGeode->rotation) { + default: + ErrorF("%s:%d invalid rotation %d\n", __func__, __LINE__, + pGeode->rotation); + case RR_Rotate_0: + newX = x; + newY = y; + break; + case RR_Rotate_270: + newX = y; + newY = 31 - x; + break; + case RR_Rotate_180: + newX = 31 - x; + newY = 31 - y; + break; + case RR_Rotate_90: + newX = 31 - y; + newY = x; + break; + } + i = 7 - i; n = 31 - newX; andMask[newY] |= (((mskb >> i) & 1) << n); @@ -221,71 +188,26 @@ LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src) } } - vg_set_mono_cursor_shape32(pGeode->CursorStartOffset, &andMask[0], - &xorMask[0], 31, 31); + vg_set_mono_cursor_shape32(pGeode->CursorStartOffset,&andMask[0],&xorMask[0],31,31); } -/*---------------------------------------------------------------------------- - * LXHideCursor - * - * Description :This function will disable the cursor. - * - * Parameters: - * pScrni: Handles to the Screeen information pointer structure. - * - * Returns: none. - * - * Comments: gfx_set_cursor enable function is hardcoded to disable - * the cursor. - *---------------------------------------------------------------------------- - */ void LXHideCursor(ScrnInfoPtr pScrni) { vg_set_cursor_enable(0); } -/*---------------------------------------------------------------------------- - * LXShowCursor - * - * Description :This function will enable the cursor. - * - * Parameters: - * pScrni :Handles to the Screeen information pointer structure. - * - * Returns :none - * - * Comments :gfx_set_cursor enable function is hardcoded to enable the - * cursor - *---------------------------------------------------------------------------- -*/ void LXShowCursor(ScrnInfoPtr pScrni) { vg_set_cursor_enable(1); } -/*---------------------------------------------------------------------------- - * LXUseHwCursor. - * - * Description :This function will sets the hardware cursor flag in - * pscreen structure. - * - * Parameters. - * pScreen :Handles to the Screeen pointer structure. - * - * Returns :none - * - * Comments :none - * - *---------------------------------------------------------------------------- -*/ static Bool LXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs) { ScrnInfoPtr pScrni = XF86SCRNINFO(pScrn); + GeodeRec *pGeode = GEODEPTR(pScrni); - if (pScrni->currentMode->Flags & V_DBLSCAN) - return FALSE; - return TRUE; + return pGeode->HWCursor; } diff --git a/src/amd_lx_dga.c b/src/amd_lx_dga.c deleted file mode 100644 index 775d3f4..0000000 --- a/src/amd_lx_dga.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. - * - * 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, - * 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. - * - * Neither the name of the Advanced Micro Devices, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - */ - -/* - * File contents: DGA(Direct Acess Graphics mode) is feature of - * XFree86 that allows the program to access directly to video - * memory on the graphics card. DGA supports the double - * flickering. This file has the functions to support the DGA - * modes. - * - * Project: Geode Xfree Frame buffer device driver. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86.h" -#include "xf86_OSproc.h" -#include "xf86_ansic.h" -#include "xf86Pci.h" -#include "xf86PciInfo.h" -#include "xaa.h" -#include "xaalocal.h" -#include "amd.h" -#include "dgaproc.h" - -/* forward declarations */ -Bool LXDGAInit(ScreenPtr pScrn); -static Bool LX_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, - int *, int *, int *); -static void LX_CloseFramebuffer(ScrnInfoPtr pScrni); -static Bool LX_SetMode(ScrnInfoPtr, DGAModePtr); -static int LX_GetViewport(ScrnInfoPtr); -static void LX_SetViewport(ScrnInfoPtr, int, int, int); -static void LX_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); -static void LX_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); - -extern void LXAdjustFrame(int, int, int, int); -extern Bool LXSwitchMode(int, DisplayModePtr, int); -extern void LXAccelSync(ScrnInfoPtr pScrni); - -static DGAFunctionRec LXDGAFuncs = { - LX_OpenFramebuffer, - LX_CloseFramebuffer, - LX_SetMode, - LX_SetViewport, - LX_GetViewport, - LXAccelSync, - LX_FillRect, - LX_BlitRect, - NULL -}; - -/*---------------------------------------------------------------------------- - * LXDGAInit. - * - * Description :This function is used to initialize the DGA modes and sets - * the viewport based on the screen mode. - * Parameters. - * pScreeen :Pointer to screen info structure. - * - * Returns :TRUE on success and FALSE on failure. - * - * Comments :This function prepares the DGA mode settings for - * other func reference. - * -*---------------------------------------------------------------------------- -*/ -Bool -LXDGAInit(ScreenPtr pScrn) -{ - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - GeodeRec *pGeode = GEODEPTR(pScrni); - DGAModePtr modes = NULL, newmodes = NULL, currentMode; - DisplayModePtr pMode, firstMode; - int Bpp = pScrni->bitsPerPixel >> 3; - int num = 0; - Bool oneMore; - - pMode = firstMode = pScrni->modes; - DEBUGMSG(0, (0, X_NONE, "LXDGAInit %d\n", Bpp)); - while (pMode) { - /* one record is allocated here */ - newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); - oneMore = FALSE; - - if (!newmodes) { - xfree(modes); - return FALSE; - } - - modes = newmodes; - - SECOND_PASS: /* DGA mode flgas and viewport parametrs are set here. */ - currentMode = modes + num; - num++; - currentMode->mode = pMode; - currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; - currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; - if (pMode->Flags & V_DBLSCAN) - currentMode->flags |= DGA_DOUBLESCAN; - if (pMode->Flags & V_INTERLACE) - currentMode->flags |= DGA_INTERLACED; - currentMode->byteOrder = pScrni->imageByteOrder; - currentMode->depth = pScrni->depth; - currentMode->bitsPerPixel = pScrni->bitsPerPixel; - currentMode->red_mask = pScrni->mask.red; - currentMode->green_mask = pScrni->mask.green; - currentMode->blue_mask = pScrni->mask.blue; - currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; - currentMode->viewportWidth = pMode->HDisplay; - currentMode->viewportHeight = pMode->VDisplay; - currentMode->xViewportStep = 1; - currentMode->yViewportStep = 1; - currentMode->viewportFlags = DGA_FLIP_RETRACE; - currentMode->offset = 0; - currentMode->address = pGeode->FBBase; - if (oneMore) { /* first one is narrow width */ - currentMode->bytesPerScanline = - ((pMode->HDisplay * Bpp) + 3) & ~3L; - currentMode->imageWidth = pMode->HDisplay; - currentMode->imageHeight = pMode->VDisplay; - currentMode->pixmapWidth = currentMode->imageWidth; - currentMode->pixmapHeight = currentMode->imageHeight; - currentMode->maxViewportX = currentMode->imageWidth - - currentMode->viewportWidth; - /* this might need to get clamped to some maximum */ - currentMode->maxViewportY = currentMode->imageHeight - - currentMode->viewportHeight; - oneMore = FALSE; - goto SECOND_PASS; - } else { - currentMode->bytesPerScanline = - ((pScrni->displayWidth * Bpp) + 3) & ~3L; - currentMode->imageWidth = pScrni->displayWidth; - currentMode->imageHeight = pMode->VDisplay; - currentMode->pixmapWidth = currentMode->imageWidth; - currentMode->pixmapHeight = currentMode->imageHeight; - currentMode->maxViewportX = currentMode->imageWidth - - currentMode->viewportWidth; - /* this might need to get clamped to some maximum */ - currentMode->maxViewportY = currentMode->imageHeight - - currentMode->viewportHeight; - } - pMode = pMode->next; - if (pMode == firstMode) - break; - } - pGeode->numDGAModes = num; - pGeode->DGAModes = modes; - - return DGAInit(pScrn, &LXDGAFuncs, modes, num); -} - -/*---------------------------------------------------------------------------- - * LX_SetMode. - * - * Description :This function is sets into the DGA mode. - *. - * Parameters. - * pScreeen :Pointer to screen info structure. - * pMode :Points to the DGAmode ptr data - * Returns :TRUE on success and FALSE on failure. - * - * Comments :none. - * - * -*---------------------------------------------------------------------------- -*/ -static Bool -LX_SetMode(ScrnInfoPtr pScrni, DGAModePtr pMode) -{ - static int OldDisplayWidth[MAXSCREENS]; - int index = pScrni->pScreen->myNum; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DEBUGMSG(0, (0, X_NONE, "LX_SetMode\n")); - - if (!pMode) { - /* restore the original mode - * put the ScreenParameters back - */ - pScrni->displayWidth = OldDisplayWidth[index]; - DEBUGMSG(0, - (0, X_NONE, "LX_SetMode !pMode %d\n", pScrni->displayWidth)); - LXSwitchMode(index, pScrni->currentMode, 0); - pGeode->DGAactive = FALSE; - } else { - if (!pGeode->DGAactive) { /* save the old parameters */ - OldDisplayWidth[index] = pScrni->displayWidth; - pGeode->DGAactive = TRUE; - DEBUGMSG(0, (0, X_NONE, "LX_SetMode pMode+ NA %d\n", - pScrni->displayWidth)); - } - pGeode->PrevDisplayOffset = vg_get_display_offset(); - - pScrni->displayWidth = pMode->bytesPerScanline / - (pMode->bitsPerPixel >> 3); - DEBUGMSG(0, (0, X_NONE, - "LX_SetMode pMode+ %d\n", pScrni->displayWidth)); - LXSwitchMode(index, pMode->mode, 0); - } - /* enable/disable Compression */ - if (pGeode->Compression) { - vg_set_compression_enable(!pGeode->DGAactive); - } - - /* enable/disable cursor */ - if (pGeode->HWCursor) { - vg_set_cursor_enable(!pGeode->DGAactive); - } - - return TRUE; -} - -/*---------------------------------------------------------------------------- - * LX_GetViewPort. - * - * Description :This function is Gets the viewport window memory. - *. - * Parameters. - * pScrni :Pointer to screen info structure. - * - * Returns :returns the viewport status. - * - * Comments :none. - * - * -*---------------------------------------------------------------------------- -*/ -static int -LX_GetViewport(ScrnInfoPtr pScrni) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - return pGeode->DGAViewportStatus; -} - -/*---------------------------------------------------------------------------- - * LX_SetViewPort. - * - * Description :This function is Gets the viewport window memory. - * - * Parameters. - * pScrni :Pointer to screen info structure. - x :x-cordinate of viewport window - * y :y-codinate of the viewport window. - * flags :indicates the viewport to be flipped or not. - * Returns :returns the viewport status as zero. - * - * Comments :none. - * -*---------------------------------------------------------------------------- -*/ -static void -LX_SetViewport(ScrnInfoPtr pScrni, int x, int y, int flags) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - LXAdjustFrame(pScrni->pScreen->myNum, x, y, flags); - pGeode->DGAViewportStatus = 0; /* LXAdjustFrame loops until finished */ -} - -/*---------------------------------------------------------------------------- - * LX_FillRect. - * - * Description :This function is Gets the viewport window memory. - *. - * Parameters. - * pScrni :Pointer to screen info structure. - * x :x-cordinate of viewport window - * y :y-codinate of the viewport window. - * w :width of the rectangle - * h :height of the rectangle. - * color :color to be filled in rectangle. - * - * Returns :returns the viewport status as zero. - * - * Comments :This function is implemented by solidfill routines.. - * -*---------------------------------------------------------------------------- -*/ -static void -LX_FillRect(ScrnInfoPtr pScrni, int x, int y, - int w, int h, unsigned long color) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - if (pGeode->AccelInfoRec) { - (*pGeode->AccelInfoRec->SetupForSolidFill) (pScrni, color, GXcopy, - ~0); - (*pGeode->AccelInfoRec->SubsequentSolidFillRect) (pScrni, x, y, w, h); - SET_SYNC_FLAG(pGeode->AccelInfoRec); - } -} - -/*---------------------------------------------------------------------------- - * LX_BlitRect. - * - * Description :This function implementing Blit and it moves a - * Rectangular block of data from one location to other - * Location. - * - * Parameters. - * pScrni :Pointer to screen info structure. - * srcx :x-cordinate of the src rectangle - * srcy :y-codinate of src rectangle. - * w :width of the rectangle - * h :height of the rectangle. - * dstx :x-cordinate of the dst rectangle. - * dsty :y -coordinates of the dst rectangle. - * Returns :none. - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static void -LX_BlitRect(ScrnInfoPtr pScrni, - int srcx, int srcy, int w, int h, int dstx, int dsty) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - if (pGeode->AccelInfoRec) { - int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; - int ydir = (srcy < dsty) ? -1 : 1; - - (*pGeode->AccelInfoRec->SetupForScreenToScreenCopy) - (pScrni, xdir, ydir, GXcopy, ~0, -1); - (*pGeode->AccelInfoRec->SubsequentScreenToScreenCopy) - (pScrni, srcx, srcy, dstx, dsty, w, h); - SET_SYNC_FLAG(pGeode->AccelInfoRec); - } -} - -/*---------------------------------------------------------------------------- - * LX_OpenFramebuffer. - * - * Description :This function open the framebuffer driver for DGA. - * - * Parameters. - * pScrni :Pointer to screen info structure. - * srcx :x-cordinate of the src rectangle - * srcy :y-codinate of src rectangle. - * w :width of the rectangle - * h :height of the rectangle. - * dstx :x-cordinate of the dst rectangle. - * dsty :y -coordinates of the dst rectangle. - * Returns :none. - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static Bool -LX_OpenFramebuffer(ScrnInfoPtr pScrni, - char **name, unsigned char **mem, int *size, int *offset, int *flags) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - *name = NULL; /* no special device */ - *mem = (unsigned char *)pGeode->FBLinearAddr; - *size = pGeode->FBAvail; - *offset = 0; - *flags = DGA_NEED_ROOT; - - return TRUE; -} - -static void -LX_CloseFramebuffer(ScrnInfoPtr pScrni) -{ -} diff --git a/src/amd_lx_driver.c b/src/amd_lx_driver.c index 9a2146a..6f99e8f 100644 --- a/src/amd_lx_driver.c +++ b/src/amd_lx_driver.c @@ -1,12 +1,15 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. +/* Copyright (c) 2003-2007 Advanced Micro Devices, Inc. * - * 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: + * Portioned modeled from xf86-video-intel/src/i830_driver.c + * Copyright 2001 VA Linux Systems Inc., Fremont, California. + * Copyright \ufffd 2002 by David Dawes + + * 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. @@ -16,2201 +19,1112 @@ * 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. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. * * Neither the name of the Advanced Micro Devices, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. */ -/* - * File Contents: This is the main module configures the interfacing - * with the X server. The individual modules will be - * loaded based upon the options selected from the - * XF86Config. This file also has modules for finding - * supported modes, turning on the modes based on options. - * - * Project: Geode Xfree Frame buffer device driver. - * - */ +/* TODO: + TV out support + Detect panels better + Better VGA support + GX: cursor position needs to be correctly set + use CB data wrapper to save a variable + consolidate the saved timings + implement panning +*/ + +/* The effort to make things common: + define CmdBfrSize in the GX + add the output flag to GX +*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif -/* Includes that are used by all drivers */ +#include <stdio.h> +#include <string.h> + #include "xf86.h" #include "xf86_OSproc.h" -#include "xf86_ansic.h" -#include "xf86_libc.h" #include "xf86Resources.h" -#include "compiler.h" -#include "xf86PciInfo.h" -#include "xf86Pci.h" #include "xf86cmap.h" - -#define RC_MAX_DEPTH 24 - -#include "amd.h" -#include "cim_defs.h" -#include "cim_regs.h" -#include "cim_dev.h" - -/* Frame buffer stuff */ -#if CFB -/* - * If using cfb, cfb.h is required. Select the others for the bpp values - * the driver supports. - */ -#define PSZ 8 /* needed for cfb.h */ -#include "cfb.h" -#undef PSZ -#include "cfb16.h" -#include "cfb24.h" -#include "cfb32.h" -#else -#include "fb.h" -#endif - -#include "shadowfb.h" - -/* Machine independent stuff */ +#include "compiler.h" #include "mipointer.h" -#include "mibank.h" +#include <X11/extensions/randr.h> +#include "fb.h" +#include "miscstruct.h" #include "micmap.h" -#include "mibstore.h" -#include "vgaHW.h" #include "vbe.h" +#include "fb.h" +#include "randrstr.h" +#include "cim_defs.h" +#include "cim_regs.h" +#include "amd.h" +#include "shadow.h" -/* Check for some extensions */ -#ifdef XFreeXDGA -#define _XF86_DGA_SERVER_ -#include <X11/extensions/xf86dgastr.h> -#endif /* XFreeXDGA */ - -#ifdef DPMSExtension -#include "globals.h" -#include "opaque.h" -#define DPMS_SERVER -#include <X11/extensions/dpms.h> -#endif /* DPMSExtension */ - +/* Bring in VGA functions */ #include "amd_lx_vga.c" -extern SymTabRec GeodeChipsets[]; -extern OptionInfoRec LX_GeodeOptions[]; +/* Chipset types */ -/* Forward definitions */ -static Bool LXPreInit(ScrnInfoPtr, int); -static Bool LXScreenInit(int, ScreenPtr, int, char **); -static Bool LXEnterVT(int, int); -static void LXLeaveVT(int, int); -static void LXFreeScreen(int, int); -void LXAdjustFrame(int, int, int, int); -Bool LXSwitchMode(int, DisplayModePtr, int); -static int LXValidMode(int, DisplayModePtr, Bool, int); -static void LXLoadPalette(ScrnInfoPtr pScrni, - int numColors, int *indizes, LOCO * colors, VisualPtr pVisual); -static Bool LXMapMem(ScrnInfoPtr); -static Bool LXUnmapMem(ScrnInfoPtr); - -extern Bool LXAccelInit(ScreenPtr pScrn); -extern Bool LXHWCursorInit(ScreenPtr pScrn); -extern void LXHideCursor(ScrnInfoPtr pScrni); -extern void LXShowCursor(ScrnInfoPtr pScrni); -extern void LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src); -extern void LXPointerMoved(int index, int x, int y); -extern void LXRotationInit(ScrnInfoPtr pScrni); -extern void LXShadowFBInit(ScreenPtr pScrn, GeodeRec *pGeode, int bytpp); -extern void LXInitVideo(ScreenPtr pScrn); -extern Bool LXDGAInit(ScreenPtr pScrn); +#define LX_MIN_PITCH 1024 +#define LX_MAX_PITCH 8192 +#define LX_MAX_WIDTH 1940 +#define LX_MIN_HEIGHT 400 +#define LX_MAX_HEIGHT 1600 +#define LX_CB_PITCH 544 +#define LX_CB_SIZE 544 -unsigned char *XpressROMPtr; -unsigned long fb; +#define LX_GP_REG_SIZE 0x4000 +#define LX_VG_REG_SIZE 0x4000 +#define LX_VID_REG_SIZE 0x4000 +#define LX_VIP_REG_SIZE 0x4000 + +extern OptionInfoRec LX_GeodeOptions[]; extern const char *amdVgahwSymbols[]; extern const char *amdVbeSymbols[]; extern const char *amdInt10Symbols[]; - -#if CFB -extern const char *amdCfbSymbols[]; -#else extern const char *amdFbSymbols[]; -#endif -extern const char *amdXaaSymbols[]; +extern const char *amdExaSymbols[]; extern const char *amdRamdacSymbols[]; -extern const char *amdShadowSymbols[]; - -void LXSetupChipsetFPtr(ScrnInfoPtr pScrni); -GeodeRec *LXGetRec(ScrnInfoPtr pScrni); -void lx_clear_screen(ScrnInfoPtr pScrni, int width, int height, int bpp); -void lx_clear_fb(ScrnInfoPtr pScrni); -void lx_disable_dac_power(ScrnInfoPtr pScrni, int option); -void lx_enable_dac_power(ScrnInfoPtr pScrni, int option); -#if DEBUGLVL>0 -FILE *zdfp = NULL; -#endif +unsigned char *XpressROMPtr; /* Reference: Video Graphics Suite Specification: * VG Config Register (0x00) page 16 - * VG FP Register (0x02) page 18 */ - -#define LX_READ_VG(reg) \ - (outw(0xAC1C,0xFC53), outw(0xAC1C,0x0200|(reg)), inw(0xAC1E)) + * VG FP Register (0x02) page 18 + */ -/* panel resolutiosn decode of FP config reg */ +#define LX_READ_VG(reg) \ + (outw(0xAC1C,0xFC53), outw(0xAC1C,0x0200|(reg)), inw(0xAC1E)) -static struct sLXFpResolution +static inline void +lx_enable_dac_power(ScrnInfoPtr pScrni, int option) { - int xres, yres; -} lx_fp_resolution[] = { - { - 320, 240}, { - 640, 480}, { - 800, 600}, { - 1024, 768}, { - 1152, 864}, { - 1280, 1024}, { - 1600, 1200}, { - 0, 0} -}; - -/* Get the information from the BIOS regarding the panel */ + GeodeRec *pGeode = GEODEPTR(pScrni); -static int -lx_get_panel_info(int *xres, int *yres) + df_set_crt_enable(DF_CRT_ENABLE); + + /* Turn off the DAC if we don't need the CRT */ + + if (option && (!(pGeode->Output & OUTPUT_CRT))) { + unsigned int misc = READ_VID32(DF_VID_MISC); + misc |= DF_DAC_POWER_DOWN; + WRITE_VID32(DF_VID_MISC, misc); + } + + if (pGeode->Output & OUTPUT_PANEL) + df_set_panel_enable(1); +} + +static inline void +lx_disable_dac_power(ScrnInfoPtr pScrni, int option) { - unsigned short reg = LX_READ_VG(0x02); + GeodeRec *pGeode = GEODEPTR(pScrni); + + if (pGeode->Output & OUTPUT_PANEL) + df_set_panel_enable(0); - *xres = lx_fp_resolution[(reg >> 3) & 0x07].xres; - *yres = lx_fp_resolution[(reg >> 3) & 0x07].yres; + if (pGeode->Output & OUTPUT_CRT) { - return 0; + /* Wait for the panel to finish its procedure */ + + if (pGeode->Output & OUTPUT_PANEL) + while ((READ_VID32(DF_POWER_MANAGEMENT) & 2) == 0); + df_set_crt_enable(option); + } } static int -lx_panel_configured(void) +lx_get_panel(int *xres, int *yres) { - unsigned short reg = LX_READ_VG(0x00); - unsigned char ret = (reg >> 8) & 0x7; - - return (ret == 1) || (ret == 5) ? 1 : 0; + static struct { + int xres, yres; + } fpres[] = { + { 320, 240 }, { 640, 480 }, { 800, 600 }, { 1024, 768 }, + { 1152, 864 }, { 1280, 1024 }, { 1600, 1200 } }; + + unsigned short reg = LX_READ_VG(0x00); + unsigned char ret = (reg >> 8) & 0x07; + + if ((ret == 1 || ret == 5)) { + + reg = LX_READ_VG(0x02); + ret = (reg >> 3) & 0x07; + + /* 7 is a "reserved" value - if we get it, we can only assume that + a panel doesn't exist (or it hasn't been configured in the BIOS) + */ + + if (ret < 7) { + *xres = fpres[ret].xres; + *yres = fpres[ret].yres; + + return TRUE; + } + } + + return FALSE; } -void -LXSetupChipsetFPtr(ScrnInfoPtr pScrni) +static int +lx_set_custom_mode(GeodeRec *pGeode, DisplayModePtr pMode, int bpp) { -#if DEBUGLVL>0 - if (zdfp == NULL) { - zdfp = fopen("/tmp/xwin.log", "w"); - setbuf(zdfp, NULL); - } -#endif - DEBUGMSG(1, (0, X_INFO, "LXSetupChipsetFPtr!\n")); - pScrni->PreInit = LXPreInit; - pScrni->ScreenInit = LXScreenInit; - pScrni->SwitchMode = LXSwitchMode; - pScrni->AdjustFrame = LXAdjustFrame; - pScrni->EnterVT = LXEnterVT; - pScrni->LeaveVT = LXLeaveVT; - pScrni->FreeScreen = LXFreeScreen; - pScrni->ValidMode = LXValidMode; + VG_DISPLAY_MODE mode; + + memset(&mode, 0, sizeof(mode)); + + if (pMode->Flags & V_NHSYNC) + mode.flags |= VG_MODEFLAG_NEG_HSYNC; + if (pMode->Flags & V_NVSYNC) + mode.flags |= VG_MODEFLAG_NEG_VSYNC; + + mode.flags |= pGeode->Output & OUTPUT_CRT ? VG_MODEFLAG_CRT_AND_FP : 0; + + if (pGeode->Output & OUTPUT_PANEL) { + mode.panel_width = mode.mode_width = pGeode->PanelX; + mode.panel_height = mode.mode_height = pGeode->PanelY; + + mode.flags |= VG_MODEFLAG_PANELOUT; + mode.flags |= pGeode->Output & OUTPUT_CRT ? VG_MODEFLAG_CRT_AND_FP : 0; + } + else { + mode.mode_width = pMode->CrtcHDisplay; + mode.mode_height = pMode->CrtcVDisplay; + } + + mode.src_width = pMode->CrtcHDisplay; + mode.src_height = pMode->CrtcVDisplay; + + mode.hactive = pMode->CrtcHDisplay; + mode.hblankstart = pMode->CrtcHBlankStart; + mode.hsyncstart = pMode->CrtcHSyncStart; + mode.hsyncend = pMode->CrtcHSyncEnd; + mode.hblankend = pMode->CrtcHBlankEnd; + mode.htotal = pMode->CrtcHTotal; + + mode.vactive = pMode->CrtcVDisplay; + mode.vblankstart = pMode->CrtcVBlankStart; + mode.vsyncstart = pMode->CrtcVSyncStart; + mode.vsyncend = pMode->CrtcVSyncEnd; + mode.vblankend = pMode->CrtcVBlankEnd; + mode.vtotal = pMode->CrtcVTotal; + + mode.vactive_even = pMode->CrtcVDisplay; + mode.vblankstart_even = pMode->CrtcVBlankStart; + mode.vsyncstart_even = pMode->CrtcVSyncStart; + mode.vsyncend_even = pMode->CrtcVSyncEnd; + mode.vblankend_even = pMode->CrtcVBlankEnd; + mode.vtotal_even = pMode->CrtcVTotal; + + mode.frequency = (int)((pMode->SynthClock / 1000.0) * 0x10000); + + return vg_set_custom_mode(&mode, bpp); } -#ifdef AMD_V4L2_VIDEO -void -LXInitVideo(ScreenPtr pScrn) +static Bool +LXAllocateMemory(ScreenPtr pScrn, ScrnInfoPtr pScrni, int rotate) { - GeodeRec *pGeode; - int num_adaptors; - XF86VideoAdaptorPtr *adaptors; - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; + GeodePtr pGeode = GEODEPTR(pScrni); + + unsigned int fboffset, fbavail; + unsigned int size; + unsigned int bytpp = (pScrni->bitsPerPixel + 7) / 8; + Bool ret = TRUE; + + if (pGeode->tryCompression) + pGeode->displayPitch = + GeodeCalculatePitchBytes(pScrni->virtualX, pScrni->bitsPerPixel); + else + pGeode->displayPitch = + ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3); + + pGeode->displayWidth = pGeode->displayPitch / bytpp; + + + /* Sets pGeode->Pitch and pScrni->displayWidth based on the rotate settings */ + LXSetRotatePitch(pScrni); + + fbavail = pGeode->FBAvail - GP3_SCRATCH_BUFFER_SIZE; + + pGeode->displayOffset = fboffset = 0; + pGeode->displaySize = pScrni->virtualY * pGeode->displayPitch; + + fbavail -= pGeode->displaySize; + fboffset += pGeode->displaySize; + + if (pGeode->tryCompression) { + size = pScrni->virtualY * LX_CB_PITCH; + + if (size <= fbavail) { + pGeode->CBData.compression_offset = fboffset; + pGeode->CBData.size = LX_CB_PITCH; + pGeode->CBData.pitch = LX_CB_PITCH; + fboffset += size; + fbavail -= size; + + pGeode->Compression = TRUE; + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for compression\n"); + pGeode->Compression = FALSE; + } + } + + if (pGeode->tryHWCursor) { + pGeode->CursorSize = 1024; + + if (pGeode->CursorSize <= fbavail) { + pGeode->CursorStartOffset = fboffset; + fboffset += pGeode->CursorSize; + fbavail -= pGeode->CursorSize; + pGeode->HWCursor = TRUE; + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for the hardware cursor\n"); + pGeode->HWCursor = FALSE; + } + } + + /* Try to set up some EXA scratch memory for blending */ + + pGeode->exaBfrOffset = 0; - pGeode = GEODEPTR(pScrni); if (!pGeode->NoAccel) { - num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors); - if (num_adaptors > 0) - xf86XVScreenInit(pScrn, adaptors, num_adaptors); + if (pGeode->exaBfrSz > 0 && pGeode->exaBfrSz <= fbavail) { + pGeode->exaBfrOffset = fboffset; + fboffset += pGeode->exaBfrSz; + fbavail -= pGeode->exaBfrSz; + } } -} -#else -extern void LXInitVideo(ScreenPtr pScrn); -#endif -/*---------------------------------------------------------------------------- - * LXGetRec. - * - * Description :This function allocate an GeodeRec and hooked into - * pScrni str driverPrivate member of ScreeenInfo - * structure. - * Parameters. - * pScrni :Pointer handle to the screenonfo structure. - * - * Returns :allocated driver structure. - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -GeodeRec * -LXGetRec(ScrnInfoPtr pScrni) -{ - if (!pScrni->driverPrivate) { - GeodeRec *pGeode; + pGeode->shadowSize = 0; - pGeode = pScrni->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1); -#if INT10_SUPPORT - pGeode->vesa = xcalloc(sizeof(VESARec), 1); -#endif + if (rotate != RR_Rotate_0) { + if (rotate & (RR_Rotate_90 | RR_Rotate_270)) + size = pGeode->displayPitch * pScrni->virtualX; + else + size = pGeode->displayPitch * pScrni->virtualY; + + if (size <= fbavail) { + pGeode->shadowOffset = fboffset; + pGeode->shadowSize = size; + + fboffset += size; + fbavail -= size; + } else { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Not enough memory for the shadow framebuffer\n"); + ret = FALSE; + } } - return GEODEPTR(pScrni); -} + /* Adjust the available EXA offscreen space to account for the buffer */ -/*---------------------------------------------------------------------------- - * LXFreeRec. - * - * Description :This function deallocate an GeodeRec and freed from - * pScrni str driverPrivate member of ScreeenInfo - * structure. - * Parameters. - * pScrni :Pointer handle to the screenonfo structure. - * - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static void -LXFreeRec(ScrnInfoPtr pScrni) -{ - if (pScrni->driverPrivate == NULL) { - return; + if (!pGeode->NoAccel && pGeode->pExa) { + pGeode->pExa->offScreenBase = fboffset; + pGeode->pExa->memorySize = fboffset + fbavail; } - xfree(pScrni->driverPrivate); - pScrni->driverPrivate = NULL; + + return ret; } -/*---------------------------------------------------------------------------- - * LXSaveScreen. - * - * Description :This is to do the screen blanking - * - * Parameters. - * pScrn :Handle to ScreenPtr structure. - * mode :mode is used by vgaHWSaveScren to check blnak os on. - * - * Returns :TRUE on success and FALSE on failure. - * - * Comments :none -*---------------------------------------------------------------------------- -*/ static Bool LXSaveScreen(ScreenPtr pScrn, int mode) { ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; + GeodePtr pGeode = GEODEPTR(pScrni); - DEBUGMSG(0, (0, X_INFO, "LXSaveScreen!\n")); - - if (!pScrni->vtSema) - return vgaHWSaveScreen(pScrn, mode); + if (pGeode->useVGA && !pScrni->vtSema) + return vgaHWSaveScreen(pScrn, mode); return TRUE; } -static xf86MonPtr -LXProbeDDC(ScrnInfoPtr pScrni, int index) -{ - vbeInfoPtr pVbe; - xf86MonPtr ddc = NULL; - - if (xf86LoadSubModule(pScrni, "vbe")) { - pVbe = VBEInit(NULL, index); - ddc = vbeDoEDID(pVbe, NULL); - vbeFree(pVbe); - } - - return ddc; -} +/* This is an overly complex MSR read mechanism */ + +/* From Cimarron - the VSAII read/write methods - we use these as fallback */ + +#define LX_MSR_READ(adr,lo,hi) \ + __asm__ __volatile__( \ + " mov $0x0AC1C, %%edx\n" \ + " mov $0xFC530007, %%eax\n" \ + " out %%eax,%%dx\n" \ + " add $2,%%dl\n" \ + " in %%dx, %%ax" \ + : "=a" (lo), "=d" (hi) \ + : "c" (adr)) + +#define LX_MSR_WRITE(adr,high,low) \ + { int d0, d1, d2, d3, d4; \ + __asm__ __volatile__( \ + " push %%ebx\n" \ + " mov $0x0AC1C, %%edx\n" \ + " mov $0xFC530007, %%eax\n" \ + " out %%eax,%%dx\n" \ + " add $2,%%dl\n" \ + " mov %6, %%ebx\n" \ + " mov %7, %0\n" \ + " mov %5, %3\n" \ + " xor %2, %2\n" \ + " xor %1, %1\n" \ + " out %%ax, %%dx\n" \ + " pop %%ebx\n" \ + : "=a"(d0),"=&D"(d1),"=&S"(d2), \ + "=c"(d3),"=d"(d4) \ + : "1"(adr),"2"(high),"3"(low)); \ + } static void -LXDecodeDDC(ScrnInfoPtr pScrni, xf86MonPtr ddc) +LXReadMSR(unsigned long addr, unsigned long *lo, unsigned long *hi) { - int i; - - DEBUGMSG(1, (0, X_INFO, - "Detected monitor DDC (%4s) id %d serno %d week %d year %d " - "nsects %d\n", &ddc->vendor.name[0], ddc->vendor.prod_id, - ddc->vendor.serial, ddc->vendor.week, ddc->vendor.year, - ddc->no_sections)); - for (i = 0; i < DET_TIMINGS; ++i) { - struct detailed_monitor_section *dp = &ddc->det_mon[i]; - - switch (dp->type) { - case DT:{ - struct detailed_timings *r = &dp->section.d_timings; - - DEBUGMSG(1, (0, X_INFO, " mon det timing %0.3f %dx%d\n", - r->clock / 1000000.0, r->h_active, r->v_active)); - DEBUGMSG(1, (0, X_INFO, - " mon border %d,%d laced %d stereo %d sync %d, misc %d\n", - r->h_border, r->v_border, r->interlaced, r->stereo, - r->sync, r->misc)); - } - break; - - case DS_SERIAL:{ - char *serial_no = (char *)&dp->section.serial[0]; - - DEBUGMSG(1, (0, X_INFO, " mon serial %13s\n", serial_no)); - } - break; - - case DS_ASCII_STR:{ - char *ascii = (char *)&dp->section.ascii_data[0]; - - DEBUGMSG(1, (0, X_INFO, " mon ascii_str %13s\n", ascii)); - } - break; - - case DS_NAME:{ - char *name = (char *)&dp->section.name[0]; - - DEBUGMSG(1, (0, X_INFO, " mon name %13s\n", name)); - } break; - - case DS_RANGES:{ - struct monitor_ranges *r = &dp->section.ranges; - - DEBUGMSG(1, (0, X_INFO, - " mon ranges v %d-%d h %d-%d clk %d\n", r->min_v, - r->max_v, r->min_h, r->max_h, r->max_clock)); - } - break; - - case DS_WHITE_P:{ - struct whitePoints *wp = &dp->section.wp[0]; - - DEBUGMSG(1, (0, X_INFO, - " mon whitept %f,%f %f,%f idx %d,%d gamma %f,%f\n", - wp[1].white_x, wp[1].white_y, wp[2].white_x, - wp[2].white_y, wp[1].index, wp[2].index, - wp[1].white_gamma, wp[2].white_gamma)); - } - break; - - case DS_STD_TIMINGS:{ - struct std_timings *t = &dp->section.std_t[0]; - - DEBUGMSG(1, (0, X_INFO, - " mon std_timing no size @rate, id\n")); - for (i = 0; i < 5; ++i) - DEBUGMSG(1, (0, X_INFO, - " %d %5dx%-5d @%-4d %d\n", i, - t[i].hsize, t[i].vsize, t[i].refresh, t[i].id)); - } - break; - } - } + if (GeodeReadMSR(addr, lo, hi) == -1) { + unsigned int l, h; + + LX_MSR_READ(addr, l, h); + *lo = l; + *hi = h; + } } static void -LXFBAlloc(int fd, unsigned int offset, unsigned int size) +LXWriteMSR(unsigned long addr, unsigned long lo, unsigned long hi) { - cim_mem_req_t req; - - memset(&req, 0, sizeof(req)); - strcpy(&req.owner[0], "XFree86"); - sprintf(&req.name[0], "%08lx", offset); - req.flags = CIM_F_PUBLIC; - req.size = size; - ioctl(fd, CIM_RESERVE_MEM, &req); + if (GeodeWriteMSR(addr, lo, hi) == -1) + LX_MSR_WRITE(addr, lo, hi); } -/* check for "tv-" or "pnl-" in mode name, decode suffix */ -/* return -1 if mode name is not a known tv/pnl mode */ -static int -lx_tv_mode(DisplayModePtr pMode) + +static Bool +LXMapMem(ScrnInfoPtr pScrni) { - int tv_mode = -1; - char *bp, *cp; - - cp = pMode->name; - if ((*(bp = cp) == 't' && *++bp == 'v') || - (*(bp = cp) == 'p' && *++bp == 'n' && *++bp == 'l')) { - if (*++bp == '-') { - if (xf86NameCmp("ntsc", ++bp) == 0) - tv_mode = VG_TVMODE_NTSC; - else if (xf86NameCmp("pal", bp) == 0) - tv_mode = VG_TVMODE_PAL; - else if (xf86NameCmp("6x4_ntsc", bp) == 0) - tv_mode = VG_TVMODE_6X4_NTSC; - else if (xf86NameCmp("8x6_ntsc", bp) == 0) - tv_mode = VG_TVMODE_8X6_NTSC; - else if (xf86NameCmp("10x7_ntsc", bp) == 0) - tv_mode = VG_TVMODE_10X7_NTSC; - else if (xf86NameCmp("6x4_pal", bp) == 0) - tv_mode = VG_TVMODE_6X4_PAL; - else if (xf86NameCmp("8x6_pal", bp) == 0) - tv_mode = VG_TVMODE_8X6_PAL; - else if (xf86NameCmp("10x7_pal", bp) == 0) - tv_mode = VG_TVMODE_10X7_PAL; - else if (xf86NameCmp("480p", bp) == 0) - tv_mode = VG_TVMODE_480P; - else if (xf86NameCmp("720p", bp) == 0) - tv_mode = VG_TVMODE_720P; - else if (xf86NameCmp("1080i", bp) == 0) - tv_mode = VG_TVMODE_1080I; - } - } + GeodeRec *pGeode = GEODEPTR(pScrni); + int index = pScrni->scrnIndex; + unsigned long cmd_bfr_phys; + PCITAG tag; + + pciVideoRec *pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); + tag = pciTag(pci->bus, pci->device, pci->func); + + cim_gp_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_MMIO, + tag, pci->memBase[1], LX_GP_REG_SIZE); + + cim_vg_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_MMIO, + tag, pci->memBase[2], LX_VG_REG_SIZE); + + cim_vid_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_MMIO, + tag, pci->memBase[3], LX_VID_REG_SIZE); + + cim_vip_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_MMIO, + tag, pci->memBase[4], LX_VIP_REG_SIZE); + + cim_fb_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_FRAMEBUFFER, + tag, pci->memBase[0], pGeode->FBAvail + CIM_CMD_BFR_SZ); + + if (pScrni->memPhysBase == 0) + pScrni->memPhysBase = pci->memBase[0]; + + cmd_bfr_phys = pci->memBase[0] + pGeode->CmdBfrOffset; + cim_cmd_base_ptr = cim_fb_ptr + pGeode->CmdBfrOffset; + + if (!cim_gp_ptr || !cim_vg_ptr || !cim_vid_ptr || !cim_fb_ptr || + !cim_vip_ptr) + return FALSE; + + /* FIXME: Temporary */ + WRITE_GP32(GP3_BLT_STATUS, 0x690000); + + gp_set_frame_buffer_base(pci->memBase[0], pGeode->FBAvail); + gp_set_command_buffer_base(cmd_bfr_phys, 0, pGeode->CmdBfrSize); + + XpressROMPtr = xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, 0xF0000, 0x10000); + + pGeode->FBBase = cim_fb_ptr; + + if (!pGeode->NoAccel) + pGeode->pExa->memoryBase = pGeode->FBBase; + + xf86DrvMsg(index, X_INFO, "Geode LX video memory %x bytes at %p\n", + pGeode->FBAvail, pGeode->FBBase); - return tv_mode; + return TRUE; } -static int -lx_tv_mode_interlaced(int tv_mode) -{ - switch (tv_mode) { - case VG_TVMODE_NTSC: - case VG_TVMODE_PAL: - case VG_TVMODE_1080I: - return 1; - } +/* Check to see if VGA exists - we map the space and look for a + signature - if it doesn't match exactly, then we assume no VGA. +*/ + +static Bool +LXCheckVGA(ScrnInfoPtr pScrni) { - return 0; + char bfr[19]; + + const char *vgasig = "IBM VGA Compatible"; + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + int ret; + + if (!vgaHWMapMem(pScrni)) + return FALSE; + + ret = memcmp(pvgaHW->Base + 0x1E, vgasig, strlen(vgasig)); + memcpy(bfr, pvgaHW->Base + 0x1E, 18); + vgaHWUnmapMem(pScrni); + + bfr[18] = 0; + + return ret ? FALSE : TRUE; } -/*---------------------------------------------------------------------------- - * LXPreInit. - * - * Description :This function is called only once ate teh server startup - * - * Parameters. - * pScrni :Handle to ScreenPtr structure. - * options :may be used to check the probeed one with config. - * - * Returns :TRUE on success and FALSE on failure. - * - * Comments :none. - *---------------------------------------------------------------------------- - */ static Bool -LXPreInit(ScrnInfoPtr pScrni, int options) +LXPreInit(ScrnInfoPtr pScrni, int flags) { + GeodePtr pGeode; ClockRangePtr GeodeClockRange; - MessageType from; - int i = 0; - GeodeRec *pGeode; - char *mod = NULL; - xf86MonPtr ddc = NULL; - Q_WORD msrValue; - -#if CFB - char *reqSymbol = NULL; -#endif /* CFB */ - unsigned long offset, length, fb_top; - char dev_name[64], dev_owner[64]; - FILE *fp; - int fd; - -#if INT10_SUPPORT - VESARec *pVesa; -#endif - unsigned int PitchInc, minPitch, maxPitch; - unsigned int minHeight, maxHeight; - unsigned int flags, fmt, high, low; - int tv_encoder, tv_bus_fmt, tv_601_fmt; - int tv_conversion, tvox, tvoy, tv_flags; - int tv_601_flags, tv_vsync_shift, tv_vsync_select; - int tv_vsync_shift_count; - const char *s; - char **modes; OptionInfoRec *GeodeOptions = &LX_GeodeOptions[0]; + rgb defaultWeight = { 0, 0, 0 }; + int modecnt; + char *s, *panelgeo = NULL; - /* - * Setup the ClockRanges, which describe what clock ranges are - * available, and what sort of modes they can be used for. - */ - GeodeClockRange = (ClockRangePtr) xnfcalloc(sizeof(ClockRange), 1); - GeodeClockRange->next = NULL; - GeodeClockRange->minClock = 25175; - GeodeClockRange->maxClock = 341350; - GeodeClockRange->clockIndex = -1; /* programmable */ - GeodeClockRange->interlaceAllowed = TRUE; - GeodeClockRange->doubleScanAllowed = FALSE; /* XXX check this */ - - /* Select valid modes from those available */ - minPitch = 1024; - maxPitch = 8192; /* Can support upto 1920x1440 32Bpp */ - minHeight = 400; - maxHeight = 2048; /* Can support upto 1920x1440 32Bpp */ - /* need height >= maxWidth for rotate */ - - DEBUGMSG(1, (0, X_INFO, "LXPreInit!\n")); - /* Allocate driver private structure */ - if (!(pGeode = LXGetRec(pScrni))) - return FALSE; - - DEBUGMSG(1, (0, X_NONE, "pGeode = %p\n", (void *)pGeode)); - - /* This is the general case */ - for (i = 0; i < pScrni->numEntities; i++) { - pGeode->pEnt = xf86GetEntityInfo(pScrni->entityList[i]); - if (pGeode->pEnt->resources) - return FALSE; - pGeode->Chipset = pGeode->pEnt->chipset; - pScrni->chipset = (char *)xf86TokenToString(GeodeChipsets, - pGeode->pEnt->chipset); - } + pGeode = pScrni->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1); - if ((options & PROBE_DETECT) != 0) { - ConfiguredMonitor = LXProbeDDC(pScrni, pGeode->pEnt->index); - return TRUE; - } -#if INT10_SUPPORT - if (!xf86LoadSubModule(pScrni, "int10")) - return FALSE; - xf86LoaderReqSymLists(amdInt10Symbols, NULL); -#endif + if (pGeode == NULL) + return FALSE; - /* If the vgahw module would be needed it would be loaded here */ - if (!xf86LoadSubModule(pScrni, "vgahw")) { - return FALSE; - } - xf86LoaderReqSymLists(amdVgahwSymbols, NULL); - /* Do the cimarron hardware detection */ - init_detect_cpu(&pGeode->cpu_version, &pGeode->cpu_revision); + /* Probe for VGA */ + pGeode->useVGA = TRUE; + pGeode->VGAActive = FALSE; - /* find the base chipset core. Currently there can be only one - * chip active at any time. - */ - if ((pGeode->cpu_version & 0xFF) != CIM_CPU_GEODELX) { - ErrorF("Chipset not GEODELX !!!\n"); - return FALSE; - } - pGeode->DetectedChipSet = LX; - DEBUGMSG(1, (0, X_INFO, "Detected BaseChip (%d)\n", - pGeode->DetectedChipSet)); - - /* LX : Can have CRT or PANEL/TVO only */ - msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msrValue); - - fmt = (msrValue.low >> 3) & 0x07; - switch (fmt) { - case 4: - case 2: - case 0: - flags = LX_OT_CRT; - break; - case 1: - case 3: - case 5: - flags = LX_OT_FP; - if ((msrValue.low & 0x8000) != 0) - flags |= LX_OT_CRT; - break; - case 6: - flags = LX_OT_VOP; - break; - case 7: - flags = LX_OT_DRGB; - break; + if (xf86LoadSubModule(pScrni, "vgahw")) { + if (vgaHWGetHWRec(pScrni)) { + + pGeode->useVGA = LXCheckVGA(pScrni); + } } - /* currently supported formats */ - flags &= (LX_OT_FP | LX_OT_CRT | LX_OT_VOP); - /* can switch from crt/pnl vop, but not the other way */ - flags |= LX_OT_VOP; - pGeode->EnabledOutput = flags; + if (pGeode->useVGA) + pGeode->vesa = xcalloc(sizeof(VESARec), 1); - xf86DrvMsg(0, X_INFO, "AMD LX Output Formats -%sCRT,%sVOP,%sFP,%sDRGB\n", - ((flags & LX_OT_CRT) ? " " : " No "), - ((flags & LX_OT_VOP) ? " " : " No "), - ((flags & LX_OT_FP) ? " " : " No "), - ((flags & LX_OT_DRGB) ? " " : " No ")); + if (pScrni->numEntities != 1) + return FALSE; - pGeode->vid_version = CIM_CPU_GEODELX; - init_read_base_addresses(&(pGeode->InitBaseAddress)); + pGeode->pEnt = xf86GetEntityInfo(pScrni->entityList[0]); - pGeode->FBLinearAddr = pGeode->InitBaseAddress.framebuffer_base; - fb_top = pGeode->InitBaseAddress.framebuffer_size; + if (pGeode->pEnt->resources) + return FALSE; - if (pGeode->pEnt->device->videoRam == 0) { - from = X_PROBED; - pScrni->videoRam = fb_top / 1024; - } else { - pScrni->videoRam = pGeode->pEnt->device->videoRam; - from = X_CONFIG; - fb_top = pScrni->videoRam << 10; + if (pGeode->useVGA && (flags & PROBE_DETECT)) { + GeodeProbeDDC(pScrni, pGeode->pEnt->index); + return TRUE; } - DEBUGMSG(1, (pScrni->scrnIndex, from, "VideoRam: %lu kByte\n", - (unsigned long)pScrni->videoRam)); + cim_rdmsr = LXReadMSR; + cim_wrmsr = LXWriteMSR; - pGeode->CmdBfrOffset = 0; - pGeode->CmdBfrSize = 0; + /* Set up the Cimarron MSR tables */ + msr_init_table(); - /* - * Force modules to load now, to reserve fb mem for other drivers + /* By default, we support panel and CRT - the config file should + * disable the ones we don't want */ - pGeode->cimFd = open("/dev/cimarron", O_RDONLY); - if (pGeode->cimFd < 0) - pGeode->cimFd = open("/dev/cim", O_RDONLY); - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "/dev/cimarron: fd=%d\n", - pGeode->cimFd)); - if ((fd = open("/dev/video", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video0", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video1", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video2", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video3", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video/video0", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video/video1", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video/video2", O_RDONLY)) >= 0) - close(fd); - if ((fd = open("/dev/video/video3", O_RDONLY)) >= 0) - close(fd); - - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "open cim map\n")); - if ((fp = fopen("/proc/driver/cimarron/map", "r")) != NULL) { - low = 0; - high = fb_top; - - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "scan cim map\n")); - while (fscanf(fp, "%63s %63s %x %lx %lx\n", - &dev_owner[0], &dev_name[0], &flags, &offset, &length) == 5) { - if (offset < pGeode->FBLinearAddr) - continue; - offset -= pGeode->FBLinearAddr; - if ((flags & CIM_F_CMDBUF) != 0) { - pGeode->CmdBfrOffset = offset; - pGeode->CmdBfrSize = length; - } - if (offset >= fb_top) - continue; - if ((flags & CIM_F_PRIVATE) != 0) - if (offset < high) - high = offset; - if (offset + length >= fb_top) - length = fb_top - offset; - if ((flags & CIM_F_PUBLIC) != 0 || (flags & CIM_F_FREE) != 0) - if (offset + length > low) - low = offset + length; - } - fclose(fp); - fb_top = high < low ? high : low; - } + pGeode->Output = OUTPUT_PANEL | OUTPUT_CRT; - DEBUGMSG(1, (0, X_INFO, "fb_top = %08lx\n", fb_top)); - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, - "cmd bfr (map) %08lx/%08lx\n", pGeode->CmdBfrOffset, - pGeode->CmdBfrSize)); - - /* if cimarron module not reporting, use default buffer parameters */ - if (pGeode->CmdBfrSize == 0) { - if (fb_top < CIM_CMD_BFR_SZ) { - ErrorF("No memory for CMD_BFR !!!\n"); - return FALSE; - } - pGeode->CmdBfrSize = CIM_CMD_BFR_SZ; - fb_top -= pGeode->CmdBfrSize; - pGeode->CmdBfrOffset = fb_top; - } + /* Fill in the monitor information */ + pScrni->monitor = pScrni->confScreen->monitor; - if (pGeode->CmdBfrSize < CIM_CMD_BFR_MIN) { - ErrorF("Not enough memory for CMD_BFR !!!\n"); - return FALSE; - } - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, - "cmd bfr (actual) %08lx/%08lx\n", pGeode->CmdBfrOffset, - pGeode->CmdBfrSize)); - - /* now soak up all of the usable framebuffer memory */ - if (pGeode->cimFd >= 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "alloc cim map\n")); - for (;;) { - if ((fp = fopen("/proc/driver/cimarron/map", "r")) == NULL) - break; - low = fb_top; - high = 0; - while (fscanf(fp, "%63s %63s %x %lx %lx\n", - &dev_owner[0], &dev_name[0], &flags, &offset, - &length) == 5) { - if (offset < pGeode->FBLinearAddr) - continue; - offset -= pGeode->FBLinearAddr; - if (offset >= fb_top) - continue; - if ((flags & CIM_F_FREE) == 0) - continue; - if (low < offset) - continue; - low = offset; - if (offset + length > fb_top) - length = fb_top - offset; - high = length; - } - fclose(fp); - if (high == 0) - break; - LXFBAlloc(pGeode->cimFd, low, high); - } - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "check cim map\n")); - /* only shared memory allowed below fb_top */ - if ((fp = fopen("/proc/driver/cimarron/map", "r")) != NULL) { - low = 0; - while (fscanf(fp, "%63s %63s %x %lx %lx\n", - &dev_owner[0], &dev_name[0], &flags, &offset, - &length) == 5) { - if (offset < pGeode->FBLinearAddr) - continue; - offset -= pGeode->FBLinearAddr; - if (offset >= fb_top) - continue; - if ((flags & CIM_F_PUBLIC) == 0) { - low = 1; - break; - } - } - fclose(fp); - if (low != 0) { - ErrorF("Not able to claim free FB memory !!!\n"); - return FALSE; - } - } - } + if (!xf86SetDepthBpp(pScrni, 8, 8, 8, Support24bppFb | Support32bppFb)) + return FALSE; - pGeode->FBTop = fb_top; - if (fb_top < GP3_SCRATCH_BUFFER_SIZE) { - ErrorF("No available FB memory !!!\n"); - return FALSE; + switch (pScrni->depth) { + case 8: + pScrni->rgbBits = 8; + case 16: + case 24: + case 32: + break; + default: + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "The driver does not support %d as a depth.\n", pScrni->depth); + return FALSE; } - /* must remove cimarron scratch buffer from FB */ - pGeode->FBAvail = fb_top - GP3_SCRATCH_BUFFER_SIZE; - - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "FBAvail = %08lx\n", - pGeode->FBAvail)); - if (pGeode->DetectedChipSet & LX) { - pGeode->cpu_reg_size = 0x4000; - pGeode->gp_reg_size = 0x4000; - pGeode->vg_reg_size = 0x4000; - pGeode->vid_reg_size = 0x4000; - pGeode->vip_reg_size = 0x4000; - } else { - pGeode->cpu_reg_size = 0x9000; - pGeode->vid_reg_size = 0x1000; - } + xf86PrintDepthBpp(pScrni); - if (!LXMapMem(pScrni)) - return FALSE; + if (!xf86SetWeight(pScrni, defaultWeight, defaultWeight)) + return FALSE; - /* KFB will Knock off VGA */ - /* check if VGA is active */ - pGeode->FBVGAActive = gu3_get_vga_active(); + if (!xf86SetDefaultVisual(pScrni, -1)) + return FALSE; - DEBUGMSG(1, (0, X_PROBED, "VGA = %d\n", pGeode->FBVGAActive)); + pScrni->progClock = TRUE; + xf86CollectOptions(pScrni, NULL); + xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, GeodeOptions); - /* Fill in the monitor field */ - pScrni->monitor = pScrni->confScreen->monitor; - /* Determine depth, bpp, etc. */ - if (!xf86SetDepthBpp(pScrni, 8, 8, 8, Support24bppFb | Support32bppFb)) - return FALSE; - - if (!((pScrni->depth == 8) || (pScrni->depth == 16) || - (pScrni->depth == 24) || (pScrni->depth == 32))) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, - "Given depth (%d bpp) is not supported by this driver\n", - pScrni->depth)); - return FALSE; - } + /* Set up our various options that may get reversed as we go on */ - /* - * This must happen after pScrni->display has been set - * because xf86SetWeight references it. - */ - if (pScrni->depth > 8) { - /* The defaults are OK for us */ - rgb BitsPerComponent = { 0, 0, 0 }; - rgb BitMask = { 0, 0, 0 }; - - if (pScrni->depth > 16) { - /* we are operating in 24 bpp, Redcloud */ - BitsPerComponent.red = 8; - BitsPerComponent.green = 8; - BitsPerComponent.blue = 8; - - BitMask.red = 0xFF0000; - BitMask.green = 0x00FF00; - BitMask.blue = 0x0000FF; - } - if (xf86SetWeight(pScrni, BitsPerComponent, BitMask) == 0) - return FALSE; - } + pGeode->tryHWCursor = TRUE; + pGeode->tryCompression = TRUE; - xf86PrintDepthBpp(pScrni); + pGeode->NoAccel = FALSE; - if (!xf86SetDefaultVisual(pScrni, -1)) - return FALSE; + pGeode->NoOfImgBuffers = DEFAULT_IMG_LINE_BUFS; + pGeode->NoOfColorExpandLines = DEFAULT_CLR_LINE_BUFS; + pGeode->exaBfrSz = DEFAULT_EXA_SCRATCH_BFRSZ; - /* The new cmap layer needs this to be initialized */ - if (pScrni->depth > 1) { - Gamma zeros = { 0.0, 0.0, 0.0 }; + xf86GetOptValBool(GeodeOptions, LX_OPTION_HW_CURSOR, + &pGeode->tryHWCursor); - if (!xf86SetGamma(pScrni, zeros)) { - return FALSE; - } - } + if (!xf86GetOptValInteger(GeodeOptions, LX_OPTION_FBSIZE, + &(pGeode->FBAvail))) + pGeode->FBAvail = 0; - /* We use a programmable clock */ - pScrni->progClock = TRUE; + /* For compatability - allow SWCursor too */ - /* - * Collect all of the relevant option flags - * (fill in pScrni->options) - */ - xf86CollectOptions(pScrni, NULL); + if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_SW_CURSOR, FALSE)) + pGeode->tryHWCursor = FALSE; - /* Process the options */ - xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, GeodeOptions); + if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOCOMPRESSION, FALSE)) + pGeode->tryCompression = FALSE; -#if INT10_SUPPORT - pVesa = pGeode->vesa; - /* Initialize Vesa record */ + if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOACCEL, FALSE)) + pGeode->NoAccel = TRUE; - if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { - xf86DrvMsg(0, X_ERROR, "Int10 initialization failed.\n"); - return (FALSE); - } -#endif + pGeode->rotation = RR_Rotate_0; - if (pScrni->depth == 8) { - /* Default to 8 */ - pScrni->rgbBits = 8; - } - from = X_DEFAULT; - - pGeode->FPGeomDstSet = 0; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_FP_DEST_GEOM)) != NULL) { - char *sp; - int xres = strtoul(s, &sp, 0); - - if (sp != NULL && *sp == 'x') { - int yres = strtoul(sp + 1, &sp, 0); - - if (sp != NULL && *sp == 0) { - if (xres > 0 && xres <= maxPitch && - yres >= minHeight && yres <= maxHeight) { - pGeode->FPGeomDstSet = 1; - pGeode->FPGeomDstX = xres; - pGeode->FPGeomDstY = yres; - } else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FP_DEST_GEOM \"%dx%d\" out of range\n", xres, - yres)); - } - } - - if (pGeode->FPGeomDstSet == 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FP_DEST_GEOM \"%s\" not recognized\n", s)); - return FALSE; - } - pGeode->EnabledOutput |= LX_OT_FP; - } + if ((s = xf86GetOptValString(GeodeOptions, LX_OPTION_ROTATE))) { - pGeode->FPGeomActSet = 0; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_FP_ACTIVE_GEOM)) != NULL) { - char *sp; - int xres = strtoul(s, &sp, 0); - - if (sp != NULL && *sp == 'x') { - int yres = strtoul(sp + 1, &sp, 0); - - if (sp != NULL && *sp == 0) { - if (xres > 0 && xres <= maxPitch && - yres >= minHeight && yres <= maxHeight) { - pGeode->FPGeomActSet = 1; - pGeode->FPGeomActX = xres; - pGeode->FPGeomActY = yres; - } else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FP_ACTIVE_GEOM \"%s\" out of range\n", s)); - } - } - if (pGeode->FPGeomActSet == 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FP_ACTIVE_GEOM \"%s\" not recognized\n", s)); - return FALSE; - } - pGeode->EnabledOutput |= LX_OT_FP; + if (!xf86NameCmp(s, "LEFT")) + pGeode->rotation = RR_Rotate_90; + else if (!xf86NameCmp(s, "INVERT")) + pGeode->rotation = RR_Rotate_180; + else if (!xf86NameCmp(s, "CCW")) + pGeode->rotation = RR_Rotate_270; + else + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Invalid rotation %s.\n", s); } - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - if (pGeode->FPGeomDstSet == 0) { - if (lx_panel_configured() == 0) { - ErrorF("Panel configured and enabled but not configured " - "in BIOS !!!\n"); - return FALSE; - } - lx_get_panel_info(&pGeode->FPBiosResX, &pGeode->FPBiosResY); - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FP Bios panel configuation used\n")); - pGeode->FPGeomDstX = pGeode->FPBiosResX; - pGeode->FPGeomDstY = pGeode->FPBiosResY; - } - if (pGeode->FPGeomActSet == 0) { - pGeode->FPGeomActX = pGeode->FPGeomDstX; - pGeode->FPGeomActY = pGeode->FPGeomDstY; - } - if (pGeode->FPGeomActX > pGeode->FPGeomDstX || - pGeode->FPGeomActY > pGeode->FPGeomDstY) { - ErrorF("FP Geom params Active %dx%d bigger than Dest %dx%d\n", - pGeode->FPGeomActX, pGeode->FPGeomActY, - pGeode->FPGeomDstX, pGeode->FPGeomDstY); - return FALSE; - } - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FP Geom params Dest %dx%d, Active %dx%d\n", - pGeode->FPGeomDstX, pGeode->FPGeomDstY, - pGeode->FPGeomActX, pGeode->FPGeomActY)); - } + xf86GetOptValInteger(GeodeOptions, LX_OPTION_EXA_SCRATCH_BFRSZ, + &(pGeode->exaBfrSz)); + + if (pGeode->exaBfrSz <= 0) + pGeode->exaBfrSz = 0; - if (xf86IsOptionSet(GeodeOptions, LX_OPTION_FLATPANEL)) { - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_FLATPANEL, TRUE)) { - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FlatPanel Selected\n")); - } else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FlatPanel Selected, but not available - ignored\n")); - } else { - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "FlatPanel configured, but not enabled\n")); - pGeode->EnabledOutput &= ~LX_OT_FP; - } - } + if (pGeode->Output & OUTPUT_PANEL) { + if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOPANEL, FALSE)) + pGeode->Output &= ~OUTPUT_PANEL; } - /* - * The preferred method is to use the "hw cursor" option as a tri-state - * option, with the default set above. + panelgeo = xf86GetOptValString(GeodeOptions, LX_OPTION_PANEL_GEOMETRY); + + /* Get the panel information - if it is specified on the command line, + * then go with that - otherwise try to determine it by probing the + * BIOS - the BIOS may tell us that the panel doesn't exist, so the + * value of the output bitmask may change */ - pGeode->HWCursor = TRUE; - if (xf86GetOptValBool(GeodeOptions, LX_OPTION_HW_CURSOR, - &pGeode->HWCursor)) { - from = X_CONFIG; - } - /* For compatibility, accept this too (as an override) */ - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_SW_CURSOR, FALSE)) { - from = X_CONFIG; - pGeode->HWCursor = FALSE; - } - DEBUGMSG(1, (pScrni->scrnIndex, from, "Using %s cursor\n", - pGeode->HWCursor ? "HW" : "SW")); - pGeode->Compression = TRUE; - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOCOMPRESSION, FALSE)) { - pGeode->Compression = FALSE; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "NoCompression\n")); + if (pGeode->Output & OUTPUT_PANEL) { + if (panelgeo != NULL) + GeodeGetFPGeometry(panelgeo, &pGeode->PanelX, &pGeode->PanelY); + else { + Bool ret = lx_get_panel(&pGeode->PanelX, &pGeode->PanelY); + if (ret == FALSE) + pGeode->Output &= ~OUTPUT_PANEL; + } } - pGeode->NoAccel = FALSE; - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOACCEL, FALSE)) { - pGeode->NoAccel = TRUE; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "Acceleration disabled\n")); - } + xf86DrvMsg(pScrni->scrnIndex, X_INFO, "LX output options:\n"); + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " CRT: %s\n", + pGeode->Output & OUTPUT_CRT ? "YES" : "NO"); - if (!xf86GetOptValInteger(GeodeOptions, LX_OPTION_OSM_IMG_BUFS, - &(pGeode->NoOfImgBuffers))) - pGeode->NoOfImgBuffers = DEFAULT_IMG_LINE_BUFS; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "NoOfImgBuffers = %d\n", pGeode->NoOfImgBuffers)); - if (!xf86GetOptValInteger(GeodeOptions, LX_OPTION_OSM_CLR_BUFS, - &(pGeode->NoOfColorExpandLines))) - pGeode->NoOfColorExpandLines = DEFAULT_CLR_LINE_BUFS; - if (pGeode->NoOfColorExpandLines <= 0) - pGeode->NoOfColorExpandLines = 0; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "NoOfColorExpandLines = %d\n", pGeode->NoOfColorExpandLines)); - - pGeode->CustomMode = FALSE; - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_CUSTOM_MODE, FALSE)) { - pGeode->CustomMode = TRUE; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "Custom mode enabled\n")); - } + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " PANEL: %s\n", + pGeode->Output & OUTPUT_PANEL ? "YES" : "NO"); - if (xf86IsOptionSet(GeodeOptions, LX_OPTION_CRTENABLE)) { - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_CRTENABLE, TRUE)) { - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "CRT Output Selected\n")); - } else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "CRT Output Selected, but not available " - "- ignored\n")); - } else { - if ((pGeode->EnabledOutput & LX_OT_CRT) != 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "CRT output configured, but not enabled\n")); - pGeode->EnabledOutput &= ~LX_OT_CRT; - } - } - } + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " VGA: %s\n", + pGeode->useVGA ? "YES" : "NO"); - pGeode->TVSupport = FALSE; - if ((s = xf86GetOptValString(GeodeOptions, LX_OPTION_TV_ENCODER)) - != NULL) { - tv_encoder = -1; - if (xf86NameCmp(s, "ADV7171") == 0) - tv_encoder = VG_ENCODER_ADV7171; - else if (xf86NameCmp(s, "SAA7127") == 0) - tv_encoder = VG_ENCODER_SAA7127; - else if (xf86NameCmp(s, "FS454") == 0) - tv_encoder = VG_ENCODER_FS454; - else if (xf86NameCmp(s, "ADV7300") == 0) - tv_encoder = VG_ENCODER_ADV7300; - if (tv_encoder < 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP output configured, but no encoder specified, " - "VOP diabled\n")); - pGeode->EnabledOutput &= ~LX_OT_VOP; - } else - pGeode->TVSupport = TRUE; - pGeode->tv_encoder = tv_encoder; - } + /* Set up VGA */ + if (pGeode->useVGA) { + xf86LoaderReqSymLists(amdVgahwSymbols, NULL); - /* If TV Supported then check for TVO support */ - if (pGeode->TVSupport != FALSE) { - tv_bus_fmt = -1; - tv_601_fmt = -1; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_TV_BUS_FMT)) != NULL) { - if (xf86NameCmp(s, "disabled") == 0) - tv_bus_fmt = VOP_MODE_DISABLED; - else if (xf86NameCmp(s, "vip11") == 0) - tv_bus_fmt = VOP_MODE_VIP11; - else if (xf86NameCmp(s, "ccir656") == 0) - tv_bus_fmt = VOP_MODE_CCIR656; - else if (xf86NameCmp(s, "vip20_8bit") == 0) - tv_bus_fmt = VOP_MODE_VIP20_8BIT; - else if (xf86NameCmp(s, "vip20_16bit") == 0) - tv_bus_fmt = VOP_MODE_VIP20_16BIT; - else if (xf86NameCmp(s, "601_yuv_8bit") == 0) { - tv_601_fmt = VOP_601_YUV_8BIT; - tv_bus_fmt = VOP_MODE_601; - } else if (xf86NameCmp(s, "601_yuv_16bit") == 0) { - tv_601_fmt = VOP_601_YUV_16BIT; - tv_bus_fmt = VOP_MODE_601; - } else if (xf86NameCmp(s, "601_rgb_8_8_8") == 0) { - tv_601_fmt = VOP_601_RGB_8_8_8; - tv_bus_fmt = VOP_MODE_601; - } else if (xf86NameCmp(s, "601_yuv_4_4_4") == 0) { - tv_601_fmt = VOP_601_YUV_4_4_4; - tv_bus_fmt = VOP_MODE_601; - } - } - if (tv_bus_fmt < 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP output configured, but no bus format specified,\n" - "VOP bus format will depend on SD/HD mode\n")); - } - pGeode->tv_bus_fmt = tv_bus_fmt; - pGeode->tv_601_fmt = tv_601_fmt; - tv_flags = 0; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_TV_FLAGS)) != NULL) { - char *opt, *sp = strdup(s); - - if (sp != NULL) { - for (opt = strtok(sp, ":"); opt != NULL; - opt = strtok(NULL, ":")) { - if (xf86NameCmp(opt, "singlechipcompat") == 0) - tv_flags |= VOP_FLAG_SINGLECHIPCOMPAT; - else if (xf86NameCmp(opt, "extendedsav") == 0) - tv_flags |= VOP_FLAG_EXTENDEDSAV; - else if (xf86NameCmp(opt, "vbi") == 0) - tv_flags |= VOP_FLAG_VBI; - else if (xf86NameCmp(opt, "task") == 0) - tv_flags |= VOP_FLAG_TASK; - else if (xf86NameCmp(opt, "swap_uv") == 0) - tv_flags |= VOP_FLAG_SWAP_UV; - else if (xf86NameCmp(opt, "swap_vbi") == 0) - tv_flags |= VOP_FLAG_SWAP_VBI; - else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP flag \"%s\" not recognized\n", opt)); - } - free(sp); - } - } - tv_vsync_shift_count = 0; - tv_601_flags = 0; - tv_vsync_shift = VOP_VSYNC_NOSHIFT; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_TV_601_FLAGS)) != NULL) { - char *opt, *sp = strdup(s); - - if (sp != NULL) { - for (opt = strtok(sp, ":"); opt != NULL; - opt = strtok(NULL, ":")) { - if (xf86NameCmp(opt, "inv_de_pol") == 0) - tv_601_flags |= VOP_601_INVERT_DISPE; - else if (xf86NameCmp(opt, "inv_hs_pol") == 0) - tv_601_flags |= VOP_601_INVERT_HSYNC; - else if (xf86NameCmp(opt, "inv_vs_pol") == 0) - tv_601_flags |= VOP_601_INVERT_VSYNC; - else if (xf86NameCmp(opt, "vsync-4") == 0) - tv_vsync_shift = VOP_VSYNC_EARLIER_BY4; - else if (xf86NameCmp(opt, "vsync-2") == 0) - tv_vsync_shift = VOP_VSYNC_EARLIER_BY2; - else if (xf86NameCmp(opt, "vsync+0") == 0) - tv_vsync_shift = VOP_VSYNC_NOSHIFT; - else if (xf86NameCmp(opt, "vsync+2") == 0) { - tv_vsync_shift = VOP_VSYNC_LATER_BY_X; - tv_vsync_shift_count = 2; - } else if (xf86NameCmp(opt, "vsync+4") == 0) { - tv_vsync_shift = VOP_VSYNC_LATER_BY_X; - tv_vsync_shift_count = 4; - } else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP 601_flag \"%s\" not recognized\n", opt)); - } - free(sp); - } - } - tv_vsync_select = VOP_MB_SYNCSEL_DISABLED; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_TV_VSYNC_SELECT)) != NULL) { - char *opt, *sp = strdup(s); - - if (sp != NULL) { - for (opt = strtok(sp, ":"); opt != NULL; - opt = strtok(NULL, ":")) { - if (xf86NameCmp(opt, "disabled") == 0) - tv_vsync_select = VOP_MB_SYNCSEL_DISABLED; - else if (xf86NameCmp(opt, "vg") == 0) - tv_vsync_select = VOP_MB_SYNCSEL_VG; - else if (xf86NameCmp(opt, "vg_inv") == 0) - tv_vsync_select = VOP_MB_SYNCSEL_VG_INV; - else if (xf86NameCmp(opt, "statreg17") == 0) - tv_vsync_select = VOP_MB_SYNCSEL_STATREG17; - else if (xf86NameCmp(opt, "statreg17_inv") == 0) - tv_vsync_select = VOP_MB_SYNCSEL_STATREG17_INV; - else - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP vsync_select \"%s\" not " - "recognized\n", opt)); - } - free(sp); - } - } - pGeode->tv_flags = tv_flags; - pGeode->tv_601_flags = tv_601_flags; - pGeode->tv_vsync_shift = tv_vsync_shift; - pGeode->tv_vsync_shift_count = tv_vsync_shift_count; - pGeode->tv_vsync_select = tv_vsync_select; - tv_conversion = -1; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_TV_CONVERSION)) != NULL) { - if (xf86NameCmp(s, "cosited") == 0) - tv_conversion = VOP_422MODE_COSITED; - else if (xf86NameCmp(s, "interspersed") == 0) - tv_conversion = VOP_422MODE_INTERSPERSED; - else if (xf86NameCmp(s, "alternating") == 0) - tv_conversion = VOP_422MODE_ALTERNATING; - else { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP conversion \"%s\" not recognized\n", s)); - } - } - if (tv_conversion < 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP output configured, but no conversion specified,\n" - "VOP conversion will defaults to \"cosited\"\n")); - tv_conversion = VOP_422MODE_COSITED; - } - pGeode->tv_conversion = tv_conversion; - tvox = tvoy = 0; - if ((s = xf86GetOptValString(GeodeOptions, - LX_OPTION_TV_OVERSCAN)) != NULL) { - char *opt, *sp = strdup(s); - - if (sp != NULL) { - if ((opt = strtok(sp, ":")) != NULL) - tvox = strtol(opt, NULL, 0); - if ((opt = strtok(NULL, ":")) != NULL) - tvoy = strtol(opt, NULL, 0); - free(sp); - } - DEBUGMSG(1, (0, X_CONFIG, "TVO %d %d\n", tvox, tvoy)); - } - pGeode->tvox = tvox; - pGeode->tvoy = tvoy; - } else if ((pGeode->EnabledOutput & LX_OT_VOP) != 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "VOP output enabled, but not configured, VOP diabled\n")); - pGeode->EnabledOutput &= ~LX_OT_VOP; - } + VESARec *pVesa; + + if (!xf86LoadSubModule(pScrni, "int10")) + return FALSE; + + xf86LoaderReqSymLists(amdInt10Symbols, NULL); - if ((pGeode->EnabledOutput & LX_OT_CRT) != 0) { - ddc = LXProbeDDC(pScrni, pGeode->pEnt->index); + pVesa = pGeode->vesa; + + if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Unable to initialize 1NT10 support\n"); + pGeode->useVGA = FALSE; + } } - flags = pGeode->EnabledOutput; - xf86DrvMsg(0, X_INFO, "AMD LX Active Formats -%sCRT,%sVOP,%sFP,%sDRGB\n", - ((flags & LX_OT_CRT) ? " " : " No "), - ((flags & LX_OT_VOP) ? " " : " No "), - ((flags & LX_OT_FP) ? " " : " No "), - ((flags & LX_OT_DRGB) ? " " : " No ")); + /* Read the amount of framebuffer memory */ - if ((pGeode->EnabledOutput & (LX_OT_CRT | LX_OT_FP | LX_OT_VOP)) == 0) { - ErrorF("No output enabled !!!\n"); - return FALSE; - } + if (pGeode->FBAvail == 0) { + unsigned long value; + cim_outw(0xAC1C, 0xFC53); + cim_outw(0xAC1C, 0x0200); - pGeode->ShadowFB = FALSE; - if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_SHADOW_FB, FALSE)) { - pGeode->ShadowFB = TRUE; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "Using \"Shadow Framebuffer\"\n")); - } + value = (unsigned long)(cim_inw(0xAC1E)) & 0xFE; - pGeode->Rotate = 0; - if ((s = xf86GetOptValString(GeodeOptions, LX_OPTION_ROTATE))) { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "Rotating - %s\n", s)); - if (!xf86NameCmp(s, "CW")) { - pGeode->Rotate = 1; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "Rotating screen clockwise\n")); - } else if (!xf86NameCmp(s, "INVERT")) { - pGeode->Rotate = 2; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "Rotating screen inverted\n")); - } else if (!xf86NameCmp(s, "CCW")) { - pGeode->Rotate = 3; - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "Rotating screen counter clockwise\n")); - } - if (pGeode->Rotate != 0) { - pGeode->ShadowFB = TRUE; - } else { - DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, - "\"%s\" is not a valid value for Option \"Rotate\"\n", - s)); - DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, - "Valid options are \"CW\", \"INVERT\", or \"CCW\"\n")); - } + pGeode->FBAvail = value << 20; } - /* - * This shouldn't happen because such problems should be caught in - * GeodeProbe(), but check it just in case. - */ - if (pScrni->chipset == NULL) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, - "ChipID 0x%04X is not recognised\n", pGeode->Chipset)); - return FALSE; - } - if (pGeode->Chipset < 0) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, - "Chipset \"%s\" is not recognised\n", pScrni->chipset)); - return FALSE; - } - /* - * Init the screen with some values - */ - DEBUGMSG(1, (pScrni->scrnIndex, from, - "Video I/O registers at 0x%08lX\n", - (unsigned long)VGAHW_GET_IOBASE())); + pScrni->fbOffset = 0; - if (pScrni->memPhysBase == 0) { - from = X_PROBED; - pScrni->memPhysBase = pGeode->FBLinearAddr; + if (pGeode->pEnt->device->videoRam == 0) + pScrni->videoRam = pGeode->FBAvail / 1024; + else { + pScrni->videoRam = pGeode->pEnt->device->videoRam; + pGeode->FBAvail = pScrni->videoRam << 10; } - pScrni->fbOffset = 0; - DEBUGMSG(1, (pScrni->scrnIndex, from, - "Linear framebuffer at 0x%08lX\n", - (unsigned long)pScrni->memPhysBase)); + /* Carve out some memory for the command buffer */ - /* - * xf86ValidateModes will check that the mode HTotal and VTotal values - * don't exceed the chipset's limit if pScrni->maxHValue adn - * pScrni->maxVValue are set. Since our LXValidMode() - * already takes care of this, we don't worry about setting them here. - */ - if (pScrni->depth > 16) { - PitchInc = 4096; - } else if (pScrni->depth == 16) { - PitchInc = 2048; - } else { - PitchInc = 1024; - } - PitchInc <<= 3; /* in bits */ + pGeode->CmdBfrSize = CIM_CMD_BFR_SZ; + pGeode->FBAvail -= CIM_CMD_BFR_SZ; - /* by default use what user sets in the XF86Config file */ - modes = pScrni->display->modes; + pGeode->CmdBfrOffset = pGeode->FBAvail; + + pGeode->maxWidth = LX_MAX_WIDTH; + pGeode->maxHeight = LX_MAX_HEIGHT; - if (ddc != NULL && pScrni->monitor != NULL - && pScrni->monitor->DDC == NULL) { - pScrni->monitor->DDC = ddc; - LXDecodeDDC(pScrni, ddc); - } + GeodeClockRange = (ClockRangePtr) xnfcalloc(sizeof(ClockRange), 1); + GeodeClockRange->next = NULL; + GeodeClockRange->minClock = 25175; + GeodeClockRange->maxClock = 229500; + GeodeClockRange->clockIndex = -1; + GeodeClockRange->interlaceAllowed = TRUE; + GeodeClockRange->doubleScanAllowed = FALSE; + + if (pGeode->useVGA && (pGeode->Output & OUTPUT_CRT)) + pScrni->monitor->DDC = GeodeDoDDC(pScrni, pGeode->pEnt->index); + else + pScrni->monitor->DDC = NULL; + + /* I'm still not 100% sure this uses the right values */ + + modecnt = xf86ValidateModes(pScrni, + pScrni->monitor->Modes, + pScrni->display->modes, + GeodeClockRange, + NULL, LX_MIN_PITCH, LX_MAX_PITCH, + 32, LX_MIN_HEIGHT, LX_MAX_HEIGHT, + pScrni->display->virtualX, + pScrni->display->virtualY, pGeode->FBAvail, LOOKUP_BEST_REFRESH); - i = xf86ValidateModes(pScrni, pScrni->monitor->Modes, modes, - GeodeClockRange, NULL, minPitch, maxPitch, - PitchInc, minHeight, maxHeight, - pScrni->display->virtualX, - pScrni->display->virtualY, pGeode->FBAvail, LOOKUP_BEST_REFRESH); - - DEBUGMSG(1, (pScrni->scrnIndex, from, "xf86ValidateModes:%d %d %d %d\n", - i, pScrni->virtualX, pScrni->virtualY, pScrni->displayWidth)); - if (i == -1) { - LXFreeRec(pScrni); - return FALSE; + if (modecnt <= 0) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); + return FALSE; } - /* Prune the modes marked as invalid */ xf86PruneDriverModes(pScrni); - if (i == 0 || pScrni->modes == NULL) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, "No valid modes found\n")); - LXFreeRec(pScrni); - return FALSE; + if (pScrni->modes == NULL) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); + return FALSE; } xf86SetCrtcForModes(pScrni, 0); - - /* Set the current mode to the first in the list */ pScrni->currentMode = pScrni->modes; - /* Print the list of modes being used */ xf86PrintModes(pScrni); - - /* Set the display resolution */ xf86SetDpi(pScrni, 0, 0); - /* Load bpp-specific modules */ - mod = NULL; + /* Load the modules we'll need */ -#if CFB - /* Load bpp-specific modules */ - switch (pScrni->bitsPerPixel) { - case 8: - mod = "cfb"; - reqSymbol = "cfbScreenInit"; - break; - case 16: - mod = "cfb16"; - reqSymbol = "cfb16ScreenInit"; - break; - case 24: - mod = "cfb24"; - reqSymbol = "cfb24ScreenInit"; - break; - case 32: - mod = "cfb32"; - reqSymbol = "cfb32ScreenInit"; - break; - default: - return FALSE; - } - if (mod && xf86LoadSubModule(pScrni, mod) == NULL) { - LXFreeRec(pScrni); - return FALSE; - } - - xf86LoaderReqSymbols(reqSymbol, NULL); -#else if (xf86LoadSubModule(pScrni, "fb") == NULL) { - LXFreeRec(pScrni); - return FALSE; + return FALSE; } xf86LoaderReqSymLists(amdFbSymbols, NULL); -#endif - if (pGeode->NoAccel == FALSE) { - if (!xf86LoadSubModule(pScrni, "xaa")) { - LXFreeRec(pScrni); - return FALSE; - } - xf86LoaderReqSymLists(amdXaaSymbols, NULL); - } - if (pGeode->HWCursor == TRUE) { - if (!xf86LoadSubModule(pScrni, "ramdac")) { - LXFreeRec(pScrni); - return FALSE; - } - xf86LoaderReqSymLists(amdRamdacSymbols, NULL); + + if (!pGeode->NoAccel) { + if (!xf86LoadSubModule(pScrni, "exa")) + return FALSE; + + xf86LoaderReqSymLists(&amdExaSymbols[0], NULL); } - /* Load shadowfb if needed */ - if (pGeode->ShadowFB) { - if (!xf86LoadSubModule(pScrni, "shadowfb")) { - LXFreeRec(pScrni); - return FALSE; - } - xf86LoaderReqSymLists(amdShadowSymbols, NULL); + + if (pGeode->tryHWCursor == TRUE) { + if (!xf86LoadSubModule(pScrni, "ramdac")) { + return FALSE; + } + + xf86LoaderReqSymLists(amdRamdacSymbols, NULL); } + if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { - DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, - "xf86RegisterResources() found resource conflicts\n")); - LXFreeRec(pScrni); - return FALSE; + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Couldn't register the resources.\n"); + return FALSE; } - LXUnmapMem(pScrni); return TRUE; } -/*---------------------------------------------------------------------------- - * LXRestore. - * - * Description :This function restores the mode that was saved on server - entry - * Parameters. - * pScrni :Handle to ScreenPtr structure. - * Pmode :poits to screen mode - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ static void LXRestore(ScrnInfoPtr pScrni) { GeodeRec *pGeode = GEODEPTR(pScrni); - DEBUGMSG(0, (0, X_INFO, "LXRestore\n")); - - if (pGeode->FBVGAActive) { - vgaHWPtr pvgaHW = VGAHWPTR(pScrni); - - vgaHWProtect(pScrni, TRUE); - vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); - vgaHWProtect(pScrni, FALSE); - } -} - -/*---------------------------------------------------------------------------- - * LXCalculatePitchBytes. - * - * Description :This function restores the mode that was saved on server - * - * Parameters. - * pScrni :Handle to ScreenPtr structure. - * Pmode :Points to screenmode - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ -static int -LXCalculatePitchBytes(unsigned int width, unsigned int bpp) -{ - int lineDelta = width * (bpp >> 3); - - if (width < 640) { - /* low resolutions have both pixel and line doubling */ - DEBUGMSG(1, (0, X_PROBED, "lower resolution %d %d\n", - width, lineDelta)); - lineDelta <<= 1; - } - /* needed in Rotate mode when in accel is turned off */ - - if (lineDelta > 4096) - lineDelta = 8192; - else if (lineDelta > 2048) - lineDelta = 4096; - else if (lineDelta > 1024) - lineDelta = 2048; - else - lineDelta = 1024; - - DEBUGMSG(0, (0, X_INFO, "pitch %d %d\n", width, lineDelta)); - - return lineDelta; -} - -/*---------------------------------------------------------------------------- - * LXGetRefreshRate. - * - * Description :This function restores the mode that saved on server - * - * Parameters. - * Pmode :Pointer to the screen modes - * - * Returns :It returns the selected refresh rate. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ -static int -LXGetRefreshRate(DisplayModePtr pMode) -{ -#define THRESHOLD 2 - unsigned int i; - static int validRates[] = { 56, 60, 70, 72, 75, 85, 90, 100 }; /* Hz */ - unsigned long dotClock; - int refreshRate; - int selectedRate; - - dotClock = pMode->SynthClock * 1000; - refreshRate = dotClock / (pMode->CrtcHTotal * pMode->CrtcVTotal); - - if ((pMode->CrtcHTotal < 640) && (pMode->CrtcVTotal < 480)) - refreshRate >>= 2; /* double pixel and double scan */ - - DEBUGMSG(0, (0, X_INFO, "dotclock %lu %d\n", dotClock, refreshRate)); - - selectedRate = validRates[0]; + if (pGeode->useVGA) { + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); - for (i = 0; i < (sizeof(validRates) / sizeof(validRates[0])); i++) { - if (validRates[i] < (refreshRate + THRESHOLD)) { - selectedRate = validRates[i]; - } + vgaHWProtect(pScrni, TRUE); + vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); + vgaHWProtect(pScrni, FALSE); } - - return selectedRate; } -void -lx_clear_screen(ScrnInfoPtr pScrni, int width, int height, int bpp) +static Bool +LXUnmapMem(ScrnInfoPtr pScrni) { - /* no accels, mode is not yet set */ GeodeRec *pGeode = GEODEPTR(pScrni); - unsigned long offset = vg_get_display_offset(); - unsigned long pitch = vg_get_display_pitch(); - unsigned long n = width * ((bpp + 7) >> 3); - - DEBUGMSG(0, (0, X_INFO, "clear screen %lx %d %d %d %lu %lu\n", offset, - width, height, bpp, pitch, n)); - while (height > 0) { - memset(pGeode->FBBase + offset, 0, n); - offset += pitch; - --height; - } -} + + xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_gp_ptr, LX_GP_REG_SIZE); + xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vg_ptr, LX_VG_REG_SIZE); + xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vid_ptr, LX_VID_REG_SIZE); + xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vip_ptr, LX_VIP_REG_SIZE); -void -lx_clear_fb(ScrnInfoPtr pScrni) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - unsigned char *fb = pGeode->FBBase + pGeode->FBOffset; + xf86UnMapVidMem(pScrni->scrnIndex, cim_fb_ptr, pGeode->FBAvail); - memset(fb, 0, pGeode->FBSize); - if (pGeode->ShadowPtr != NULL && pGeode->ShadowPtr != fb) - memset(pGeode->ShadowPtr, 0, pGeode->ShadowSize); + return TRUE; } -static int -lx_set_tv_mode(ScrnInfoPtr pScrni, int tv_mode) +/* These should be correctly accounted for rotation */ + +static void +LXAdjustFrame(int scrnIndex, int x, int y, int flags) { - int ret, bpp, flags; - int tv_conversion, tv_bus_fmt, tv_flags; - int tv_601_fmt, tv_601_flags; - int tv_vsync_shift, tv_vsync_shift_count, tv_vsync_select; - unsigned long src_width, src_height; - char *bp, *cp, *dp; + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; GeodeRec *pGeode = GEODEPTR(pScrni); - VOPCONFIGURATIONBUFFER vopc; - - bpp = pScrni->bitsPerPixel; - if (bpp == 32) - bpp = 24; - flags = lx_tv_mode_interlaced(tv_mode) != 0 ? VG_MODEFLAG_INTERLACED : 0; - src_width = src_height = 0; - ret = vg_set_tv_mode(&src_width, &src_height, - pGeode->tv_encoder, tv_mode, bpp, flags, 0, 0); - DEBUGMSG(1, (0, X_INFO, - "Setting TV mode %lux%lu encoder=%d,bpp=%d,flags=%d,overscan " - "%d,%d\n", src_width, src_height, pGeode->tv_encoder, bpp, - flags, pGeode->tvox, pGeode->tvoy)); - ret = vg_set_tv_mode(&src_width, &src_height, - pGeode->tv_encoder, tv_mode, bpp, flags, pGeode->tvox, pGeode->tvoy); - - DEBUGMSG(1, (0, X_INFO, "Set TV mode ret=%d\n", ret)); - if (ret == 0) { - memset(&vopc, 0, sizeof(vopc)); - tv_flags = pGeode->tv_flags; - tv_bus_fmt = pGeode->tv_bus_fmt; - tv_601_fmt = pGeode->tv_601_fmt; - tv_601_flags = pGeode->tv_601_flags; - tv_vsync_shift = pGeode->tv_vsync_shift; - tv_vsync_shift_count = pGeode->tv_vsync_shift_count; - tv_vsync_select = pGeode->tv_vsync_select; - tv_conversion = pGeode->tv_conversion; - if (tv_bus_fmt < 0) { - dp = "defaults"; - switch (tv_mode) { - case VG_TVMODE_NTSC: - case VG_TVMODE_6X4_NTSC: - case VG_TVMODE_8X6_NTSC: - case VG_TVMODE_10X7_NTSC: - case VG_TVMODE_PAL: - case VG_TVMODE_6X4_PAL: - case VG_TVMODE_8X6_PAL: - case VG_TVMODE_10X7_PAL: - tv_bus_fmt = VOP_MODE_VIP11; - break; - default: - tv_bus_fmt = VOP_MODE_VIP20_16BIT; - break; - } - } else - dp = "set"; - switch (tv_bus_fmt) { - case VOP_MODE_VIP11: - bp = "vop11"; - break; - case VOP_MODE_CCIR656: - bp = "ccir656"; - break; - case VOP_MODE_VIP20_8BIT: - bp = "vip20_8bit"; - break; - case VOP_MODE_VIP20_16BIT: - bp = "vip20_16bit"; - break; - case VOP_MODE_601: - switch (tv_601_fmt) { - default: - tv_601_fmt = VOP_601_YUV_8BIT; - case VOP_601_YUV_8BIT: - bp = "601_yuv_8bit"; - break; - case VOP_601_YUV_16BIT: - bp = "601_yuv_16bit"; - break; - case VOP_601_RGB_8_8_8: - bp = "601_rgb_8_8_8"; - break; - case VOP_601_YUV_4_4_4: - bp = "601_yuv_4_4_4"; - break; - } - break; - default: - tv_bus_fmt = VOP_MODE_DISABLED; - case VOP_MODE_DISABLED: - bp = "disabled"; - break; - } - switch (tv_conversion) { - default: - tv_conversion = VOP_422MODE_COSITED; - case VOP_422MODE_COSITED: - cp = "cosited"; - break; - case VOP_422MODE_INTERSPERSED: - cp = "interspersed"; - break; - case VOP_422MODE_ALTERNATING: - cp = "alternating"; - break; - } - vopc.flags = tv_flags; - vopc.mode = tv_bus_fmt; - vopc.conversion_mode = tv_conversion; - vopc.vsync_out = tv_vsync_select; - vopc.vop601.flags = tv_601_flags; - vopc.vop601.vsync_shift = tv_vsync_shift; - vopc.vop601.vsync_shift_count = tv_vsync_shift_count; - vopc.vop601.output_mode = tv_601_fmt; - DEBUGMSG(1, (0, X_INFO, - "Set TV mode %s to %s, conv %s, flags %x\n", - dp, bp, cp, tv_flags)); - DEBUGMSG(1, (0, X_INFO, - "Set TV 601 mode %x flags %x vsync shift %x/%x\n", - tv_601_fmt, tv_601_flags, tv_vsync_shift, - tv_vsync_shift_count)); - vop_set_configuration(&vopc); - } - return ret; -} + unsigned long offset; + + /* XXX: Is pitch correct here? */ -static int -lx_set_custom_mode(unsigned long bpp, unsigned long flags, - unsigned long hactive, unsigned long hblankstart, - unsigned long hsyncstart, unsigned long hsyncend, - unsigned long hblankend, unsigned long htotal, - unsigned long vactive, unsigned long vblankstart, - unsigned long vsyncstart, unsigned long vsyncend, - unsigned long vblankend, unsigned long vtotal, unsigned long frequency) -{ - VG_DISPLAY_MODE mode; - - memset(&mode, 0, sizeof(mode)); - mode.flags = flags; - mode.src_width = hactive; - mode.src_height = vactive; - mode.mode_width = hactive; - mode.mode_height = vactive; - mode.hactive = hactive; - mode.hblankstart = hblankstart; - mode.hsyncstart = hsyncstart; - mode.hsyncend = hsyncend; - mode.hblankend = hblankend; - mode.htotal = htotal; - mode.vactive = vactive; - mode.vblankstart = vblankstart; - mode.vsyncstart = vsyncstart; - mode.vsyncend = vsyncend; - mode.vblankend = vblankend; - mode.vtotal = vtotal; - mode.vactive_even = vactive; - mode.vblankstart_even = vblankstart; - mode.vsyncstart_even = vsyncstart; - mode.vsyncend_even = vsyncend; - mode.vblankend_even = vblankend; - mode.vtotal_even = vtotal; - mode.frequency = frequency; - - return vg_set_custom_mode(&mode, bpp); + offset = pGeode->FBOffset + (y * pGeode->Pitch); + offset += x * (pScrni->bitsPerPixel >> 3); + + vg_set_display_offset(offset); } -/*---------------------------------------------------------------------------- - * LXSetMode. - * - * Description :This function sets parametrs for screen mode - * - * Parameters. - * pScrni :Pointer to the screenInfo structure. - * Pmode :Pointer to the screen modes - * - * Returns :TRUE on success and FALSE on Failure. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ - static Bool -LXSetMode(ScrnInfoPtr pScrni, DisplayModePtr pMode) +LXSetVideoMode(ScrnInfoPtr pScrni, DisplayModePtr pMode) { - int bpp, bppx, rate, video_enable, tv_mode, opath; - unsigned long flags, srcw, srch, actw, acth, dstw, dsth, video_flags; - GeodeRec *pGeode = GEODEPTR(pScrni); DF_VIDEO_SOURCE_PARAMS vs_odd, vs_even; + int flags = 0; + int video_enable; + unsigned long video_flags; - gp_wait_until_idle(); - /* disable video */ df_get_video_enable(&video_enable, &video_flags); + if (video_enable != 0) df_set_video_enable(0, 0); + df_get_video_source_configuration(&vs_odd, &vs_even); lx_disable_dac_power(pScrni, DF_CRT_DISABLE); + vg_set_compression_enable(0); - DEBUGMSG(1, (0, X_NONE, "LXSetMode! %p %p %p\n", - cim_gp_ptr, cim_vid_ptr, cim_fb_ptr)); - - /* Set the VT semaphore */ - pScrni->vtSema = TRUE; - - srcw = pMode->CrtcHDisplay; - srch = pMode->CrtcVDisplay; - bpp = pScrni->bitsPerPixel; - rate = LXGetRefreshRate(pMode); - /* otherwise color/chroma keying doesnt work */ - bppx = bpp == 32 ? 24 : bpp; - - /* The timing will be adjusted later */ - DEBUGMSG(1, (0, X_PROBED, - "Setting mode %dx%d %0.3f %d %d %d %d %d %d %d %d\n", - pMode->CrtcHDisplay, pMode->CrtcVDisplay, - pMode->SynthClock / 1000.0, pMode->CrtcHDisplay, - pMode->CrtcHSyncStart, pMode->CrtcHSyncEnd, pMode->CrtcHTotal, - pMode->CrtcVDisplay, pMode->CrtcVSyncStart, pMode->CrtcVSyncEnd, - pMode->CrtcVTotal)); - DEBUGMSG(1, (0, X_INFO, - "Set display mode: %lux%lu-%d (%dHz) Pitch %d/%d\n", srcw, srch, - bpp, rate, pGeode->Pitch, pGeode->AccelPitch)); - - opath = DF_DISPLAY_CRT; - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - if ((pGeode->EnabledOutput & LX_OT_CRT) != 0) - opath = DF_DISPLAY_CRT_FP; - else - opath = DF_DISPLAY_FP; - } - - if (pGeode->TVSupport && (tv_mode = lx_tv_mode(pMode)) >= 0) { - DEBUGMSG(1, (0, X_INFO, "Set TV mode %d\n", tv_mode)); - lx_set_tv_mode(pScrni, tv_mode); - opath = DF_DISPLAY_VOP; - } else if (pGeode->CustomMode != 0) { - DEBUGMSG(1, (0, X_PROBED, "Setting Custom mode\n")); - flags = 0; - if ((pMode->Flags & V_NHSYNC) != 0) - flags |= VG_MODEFLAG_NEG_HSYNC; - if ((pMode->Flags & V_NVSYNC) != 0) - flags |= VG_MODEFLAG_NEG_VSYNC; - lx_set_custom_mode(bppx, flags, pMode->CrtcHDisplay, - pMode->CrtcHBlankStart, pMode->CrtcHSyncStart, - pMode->CrtcHSyncEnd, pMode->CrtcHBlankEnd, - pMode->CrtcHTotal, pMode->CrtcVDisplay, - pMode->CrtcVBlankStart, pMode->CrtcVSyncStart, - pMode->CrtcVSyncEnd, pMode->CrtcVBlankEnd, - pMode->CrtcVTotal, (int)((pMode->SynthClock / 1000.0) * 0x10000)); - } else if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - /* display is fp */ - actw = pGeode->FPGeomActX; - dstw = pGeode->FPGeomDstX; - acth = pGeode->FPGeomActY; - dsth = pGeode->FPGeomDstY; - flags = (pGeode->EnabledOutput & LX_OT_CRT) != - 0 ? VG_MODEFLAG_CRT_AND_FP : 0; - /* cant do scaling if width > 1024 (hw bfr size limitation) */ - if (srcw > 1024) { - if (srcw != actw) - DEBUGMSG(1, (0, X_PROBED, - "FPGeomSrcX > 1024, scaling disabled\n")); - actw = srcw; - acth = srch; - vg_set_border_color(0); - } - DEBUGMSG(1, (0, X_PROBED, - "Setting Display for TFT %lux%lu %lux%lu %lux%lu %d\n", srcw, - srch, actw, acth, dstw, dsth, pScrni->bitsPerPixel)); - vg_set_panel_mode(srcw, srch, actw, acth, dstw, dsth, bppx, flags); - } else { - /* display is crt */ - DEBUGMSG(1, (0, X_PROBED, "Setting Display for CRT %lux%lu-%d@%d\n", - srcw, srch, bppx, LXGetRefreshRate(pMode))); - vg_set_display_mode(srcw, srch, srcw, srch, bppx, - LXGetRefreshRate(pMode), 0); - } - - df_set_output_path(opath); + if (!pMode->type || pMode->type == M_T_USERDEF) + lx_set_custom_mode(pGeode, pMode, pScrni->bitsPerPixel); + else { + if (pMode->Flags & V_NHSYNC) + flags |= VG_MODEFLAG_NEG_HSYNC; + if (pMode->Flags & V_NVSYNC) + flags |= VG_MODEFLAG_NEG_VSYNC; + + if (pGeode->Output & OUTPUT_PANEL) { + int activex = pGeode->PanelX; + int activey = pGeode->PanelY; + + flags = pGeode->Output & OUTPUT_CRT ? VG_MODEFLAG_CRT_AND_FP : 0; + + if (pMode->CrtcHDisplay > 1024 && + pMode->CrtcHDisplay != pGeode->PanelX) { + ErrorF("The source is greater then 1024 - scaling is disabled.\n"); + activex = pMode->CrtcHDisplay; + activey = pMode->CrtcVDisplay; + + vg_set_border_color(0); + } + + vg_set_panel_mode(pMode->CrtcHDisplay, pMode->CrtcVDisplay, + activex, activey, activex, activey, + pScrni->bitsPerPixel, flags); + } + else { + vg_set_display_mode(pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pMode->CrtcHDisplay, pMode->CrtcVDisplay, + pScrni->bitsPerPixel, GeodeGetRefreshRate(pMode), + 0); + } + } + + if (pGeode->Output & OUTPUT_PANEL) + df_set_output_path((pGeode->Output & OUTPUT_CRT) ? DF_DISPLAY_CRT_FP : DF_DISPLAY_FP); + else + df_set_output_path(DF_DISPLAY_CRT); + vg_set_display_pitch(pGeode->Pitch); gp_set_bpp(pScrni->bitsPerPixel); - - vg_set_display_offset(0L); + + vg_set_display_offset(0); vg_wait_vertical_blank(); - DEBUGMSG(1, (0, X_PROBED, "Display mode set\n")); - /* enable compression if option selected */ - if (pGeode->Compression != 0) { - DEBUGMSG(1, (0, X_PROBED, "Compression mode set %d\n", - pGeode->Compression)); - /* set the compression parameters,and it will be turned on later. */ - vg_configure_compression(&(pGeode->CBData)); - - /* set the compression buffer, all parameters already set */ - vg_set_compression_enable(1); + if (pGeode->Compression) { + vg_configure_compression(&(pGeode->CBData)); + vg_set_compression_enable(1); } - if (pGeode->HWCursor != 0) { - VG_PANNING_COORDINATES panning; + if (pGeode->HWCursor && !(pMode->Flags & V_DBLSCAN)) { + VG_PANNING_COORDINATES panning; - /* Load blank cursor */ - LXLoadCursorImage(pScrni, NULL); - vg_set_cursor_position(0, 0, &panning); - LXShowCursor(pScrni); + LXLoadCursorImage(pScrni, NULL); + vg_set_cursor_position(0, 0, &panning); + LXShowCursor(pScrni); + } else { + vg_set_cursor_enable(0); + pGeode->HWCursor = FALSE; } - DEBUGMSG(1, (0, X_INFO, "setting mode done.\n")); - - vg_set_display_offset(pGeode->PrevDisplayOffset); - - /* Restore the contents in the screen info */ - DEBUGMSG(1, (0, X_INFO, "After setting the mode\n")); - switch (pGeode->Rotate) { - case 1: - case 3: - pGeode->HDisplay = pMode->VDisplay; - pGeode->VDisplay = pMode->HDisplay; - break; - default: - pGeode->HDisplay = pMode->HDisplay; - pGeode->VDisplay = pMode->VDisplay; - break; - } + LXAdjustFrame(pScrni->scrnIndex, pScrni->frameX0, pScrni->frameY0, 0); df_configure_video_source(&vs_odd, &vs_even); + if (video_enable != 0) - df_set_video_enable(video_enable, video_flags); + df_set_video_enable(video_enable, video_flags); + lx_enable_dac_power(pScrni, 1); return TRUE; } -/*---------------------------------------------------------------------------- - * LXEnterGraphics. - * - * Description :This function will intiallize the displaytiming - structure for nextmode and switch to VGA mode. - * - * Parameters. - * pScrn :Screen information will be stored in this structure. - * pScrni :Pointer to the screenInfo structure. - * - * Returns :TRUE on success and FALSE on Failure. - * - * Comments :gfx_vga_mode_switch() will start and end the - * switching based on the arguments 0 or 1.soft_vga - * is disabled in this function. -*---------------------------------------------------------------------------- -*/ static Bool -LXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) +LXSwitchMode(int index, DisplayModePtr pMode, int flags) { - int bpp; - unsigned long cmd_bfr_phys; + ScrnInfoPtr pScrni = xf86Screens[index]; GeodeRec *pGeode = GEODEPTR(pScrni); - vgaHWPtr pvgaHW = VGAHWPTR(pScrni); - - DEBUGMSG(1, (0, X_INFO, "LXEnterGraphics.\n")); + int ret = TRUE; + int rotate; + /* Syn the engine and shutdown the DAC momentarily */ gp_wait_until_idle(); - cmd_bfr_phys = - pGeode->InitBaseAddress.framebuffer_base + pGeode->CmdBfrOffset; - cim_cmd_base_ptr = cim_fb_ptr + pGeode->CmdBfrOffset; - gp_set_frame_buffer_base(pGeode->InitBaseAddress.framebuffer_base, - pGeode->FBTop); - gp_set_command_buffer_base(cmd_bfr_phys, 0, pGeode->CmdBfrSize); - lx_disable_dac_power(pScrni, DF_CRT_DISABLE); - /* Save CRT State */ - vg_get_current_display_mode(&pGeode->FBcimdisplaytiming.vgDisplayMode, - &bpp); - - pGeode->FBcimdisplaytiming.wBpp = bpp; - pGeode->FBcimdisplaytiming.wPitch = vg_get_display_pitch(); - - /* Save Display offset */ - pGeode->FBDisplayOffset = vg_get_display_offset(); - pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); - DEBUGMSG(1, (0, X_INFO, "FBBIOSMode %d\n", pGeode->FBBIOSMode)); - - /* Save the current Compression state */ - pGeode->FBCompressionEnable = vg_get_compression_enable(); - - vg_get_compression_info(&(pGeode->FBCBData)); - - /* Save Cursor offset */ - vg_get_cursor_info(&pGeode->FBCursor); - - /* only if comming from VGA */ - if (pGeode->FBVGAActive) { - unsigned short sequencer; - vgaHWPtr pvgaHW = VGAHWPTR(pScrni); - - /* Map VGA aperture */ - if (!vgaHWMapMem(pScrni)) - return FALSE; - - /* Unlock VGA registers */ - vgaHWUnlock(pvgaHW); + /* Set up the memory for the new mode */ + rotate = LXGetRotation(pScrni->pScreen); + ret = LXAllocateMemory(pScrni->pScreen, pScrni, rotate); - /* Save the current state and setup the current mode */ - vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); - - /* DISABLE VGA SEQUENCER */ - /* This allows the VGA state machine to terminate. We must delay */ - /* such that there are no pending MBUS requests. */ - - cim_outb(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_CLK_MODE); - sequencer = cim_inb(DC3_SEQUENCER_DATA); - sequencer |= DC3_CLK_MODE_SCREEN_OFF; - cim_outb(DC3_SEQUENCER_DATA, sequencer); - - vg_delay_milliseconds(1); - - /* BLANK THE VGA DISPLAY */ - cim_outw(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_RESET); - sequencer = cim_inb(DC3_SEQUENCER_DATA); - sequencer &= ~DC3_RESET_VGA_DISP_ENABLE; - cim_outb(DC3_SEQUENCER_DATA, sequencer); - - vg_delay_milliseconds(1); + if (ret) { + if (pGeode->curMode != pMode) + ret = LXSetVideoMode(pScrni, pMode); } - lx_clear_fb(pScrni); + if (ret) + ret = LXRotate(pScrni, pMode); - if (!LXSetMode(pScrni, pScrni->currentMode)) { - return FALSE; - } - - lx_enable_dac_power(pScrni, 1); - return TRUE; -} + /* Go back the way it was */ -void -lx_disable_dac_power(ScrnInfoPtr pScrni, int option) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); + if (ret == FALSE) { + if (!LXSetVideoMode(pScrni, pGeode->curMode)) + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Could not restore the previous mode\n"); + } else + pGeode->curMode = pMode; - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) - df_set_panel_enable(0); - if ((pGeode->EnabledOutput & LX_OT_CRT) != 0) { - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) - /* wait for the panel to be fully powered off */ - while ((READ_VID32(DF_POWER_MANAGEMENT) & 2) == 0) ; - df_set_crt_enable(option); - } + return ret; } -void -lx_enable_dac_power(ScrnInfoPtr pScrni, int option) +static void +LXLeaveGraphics(ScrnInfoPtr pScrni) { - GeodeRec *pGeode = GEODEPTR(pScrni); - - df_set_crt_enable(DF_CRT_ENABLE); - if (option != 0 && (pGeode->EnabledOutput & LX_OT_CRT) == 0) { - unsigned int misc = READ_VID32(DF_VID_MISC); - - misc |= DF_DAC_POWER_DOWN; - WRITE_VID32(DF_VID_MISC, misc); - } - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) - df_set_panel_enable(1); + GeodeRec *pGeode = GEODEPTR(pScrni); + VG_PANNING_COORDINATES panning; + + gp_wait_until_idle(); + + lx_disable_dac_power(pScrni, DF_CRT_DISABLE); + + vg_set_custom_mode(&(pGeode->FBcimdisplaytiming.vgDisplayMode), + pGeode->FBcimdisplaytiming.wBpp); + + vg_set_compression_enable(0); + + /* Restore the previous Compression state */ + if (pGeode->FBCompressionEnable) { + vg_configure_compression(&(pGeode->FBCBData)); + vg_set_compression_enable(1); + } + + vg_set_display_pitch(pGeode->FBcimdisplaytiming.wPitch); + vg_set_display_offset(pGeode->FBDisplayOffset); + + /* Restore Cursor */ + vg_set_cursor_position(pGeode->FBCursor.cursor_x, + pGeode->FBCursor.cursor_y, &panning); + + + if (pGeode->useVGA && pGeode->VGAActive) { + pGeode->vesa->pInt->num = 0x10; + pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode; + pGeode->vesa->pInt->bx = 0; + xf86ExecX86int10(pGeode->vesa->pInt); + vg_delay_milliseconds(3); + } + + LXRestore(pScrni); + lx_enable_dac_power(pScrni, 1); + pScrni->vtSema = FALSE; } -/*---------------------------------------------------------------------------- - * LXLeaveGraphics: - * - * Description :This function will restore the displaymode parameters - * and switches the VGA mode - * - * Parameters. - * pScrni :Pointer to the screenInfo structure. - * - * Returns :none. -*---------------------------------------------------------------------------- -*/ -static void -LXLeaveGraphics(ScrnInfoPtr pScrni) +static Bool +LXCloseScreen(int scrnIndex, ScreenPtr pScrn) { + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; GeodeRec *pGeode = GEODEPTR(pScrni); - VG_PANNING_COORDINATES panning; - gp_wait_until_idle(); - - /* Restore VG registers */ - lx_disable_dac_power(pScrni, DF_CRT_DISABLE); - vg_set_custom_mode(&(pGeode->FBcimdisplaytiming.vgDisplayMode), - pGeode->FBcimdisplaytiming.wBpp); - - vg_set_compression_enable(0); + if (pScrni->vtSema) + LXLeaveGraphics(pScrni); - /* Restore the previous Compression state */ - if (pGeode->FBCompressionEnable) { - vg_configure_compression(&(pGeode->FBCBData)); - vg_set_compression_enable(1); + if (pGeode->pExa) { + exaDriverFini(pScrn); + xfree(pGeode->pExa); + pGeode->pExa = NULL; } - vg_set_display_pitch(pGeode->FBcimdisplaytiming.wPitch); - vg_set_display_offset(pGeode->FBDisplayOffset); + LXUnmapMem(pScrni); - /* Restore Cursor */ - vg_set_cursor_position(pGeode->FBCursor.cursor_x, - pGeode->FBCursor.cursor_y, &panning); + if (pGeode->useVGA) + vgaHWUnmapMem(pScrni); - /* For the moment, always do an int 10 */ + pScrni->PointerMoved = pGeode->PointerMoved; + pScrn->CloseScreen = pGeode->CloseScreen; -#if INT10_SUPPORT - pGeode->vesa->pInt->num = 0x10; - pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode; - pGeode->vesa->pInt->bx = 0; - xf86ExecX86int10(pGeode->vesa->pInt); -#endif - vg_delay_milliseconds(3); - LXRestore(pScrni); + if (pScrn->CloseScreen) + return (*pScrn->CloseScreen)(scrnIndex, pScrn); - lx_enable_dac_power(pScrni, 0); + return TRUE; } -/*---------------------------------------------------------------------------- - * LXCloseScreen. - * - * Description :This function will restore the original mode - * and also it unmap video memory - * - * Parameters. - * ScrnIndex :Screen index value of the screen will be closed. - * pScrn :Pointer to the screen structure. - * - * - * Returns :TRUE on success and FALSE on Failure. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ static Bool -LXCloseScreen(int scrnIndex, ScreenPtr pScrn) +LXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) { - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - GeodeRec *pGeode = GEODEPTR(pScrni); + int bpp; + GeodeRec *pGeode = GEODEPTR(pScrni); - if (pGeode->ShadowPtr && !pGeode->ShadowInFBMem) - xfree(pGeode->ShadowPtr); + if (!LXMapMem(pScrni)) + return FALSE; - DEBUGMSG(1, (scrnIndex, X_PROBED, "LXCloseScreen %d\n", pScrni->vtSema)); + pGeode->VGAActive = gu3_get_vga_active(); - if (pScrni->vtSema) - LXLeaveGraphics(pScrni); + gp_wait_until_idle(); + + //lx_disable_dac_power(pScrni, DF_CRT_DISABLE); + + vg_get_current_display_mode(&pGeode->FBcimdisplaytiming.vgDisplayMode, &bpp); + + //dump_previous(&pGeode->FBcimdisplaytiming.vgDisplayMode); - if (pGeode->AccelInfoRec) - XAADestroyInfoRec(pGeode->AccelInfoRec); + pGeode->FBcimdisplaytiming.wBpp = bpp; + pGeode->FBcimdisplaytiming.wPitch = vg_get_display_pitch(); - if (pGeode->AccelImageWriteBuffers) { -#if LX_USE_OFFSCRN_MEM - xfree(pGeode->AccelImageWriteBuffers[0]); -#endif - xfree(pGeode->AccelImageWriteBuffers); - pGeode->AccelImageWriteBuffers = NULL; - } + pGeode->FBDisplayOffset = vg_get_display_offset(); - if (pGeode->AccelColorExpandBuffers) { - xfree(pGeode->AccelColorExpandBuffers[0]); - xfree(pGeode->AccelColorExpandBuffers); - pGeode->AccelColorExpandBuffers = NULL; - } - pScrni->vtSema = FALSE; + if (pGeode->useVGA) { + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); + } + + pGeode->FBCompressionEnable = vg_get_compression_enable(); + vg_get_compression_info(&(pGeode->FBCBData)); + + /* Save Cursor offset */ + vg_get_cursor_info(&pGeode->FBCursor); + + /* Turn off the VGA */ + + if (pGeode->useVGA) { + unsigned short sequencer; + vgaHWPtr pvgaHW = VGAHWPTR(pScrni); + + /* Map VGA aperture */ + if (!vgaHWMapMem(pScrni)) + return FALSE; + + /* Unlock VGA registers */ + vgaHWUnlock(pvgaHW); + + /* Save the current state and setup the current mode */ + vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); + + /* DISABLE VGA SEQUENCER */ + /* This allows the VGA state machine to terminate. We must delay */ + /* such that there are no pending MBUS requests. */ + + cim_outb(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_CLK_MODE); + sequencer = cim_inb(DC3_SEQUENCER_DATA); + sequencer |= DC3_CLK_MODE_SCREEN_OFF; + cim_outb(DC3_SEQUENCER_DATA, sequencer); + + vg_delay_milliseconds(1); + + /* BLANK THE VGA DISPLAY */ + cim_outw(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_RESET); + sequencer = cim_inb(DC3_SEQUENCER_DATA); + sequencer &= ~DC3_RESET_VGA_DISP_ENABLE; + cim_outb(DC3_SEQUENCER_DATA, sequencer); + + vg_delay_milliseconds(1); + } + + /* Set up the memory */ + /* XXX - FIXME - when we alow inital rotation, it should be here */ + LXAllocateMemory(pScrn, pScrni, pGeode->rotation); + + /* Clear the framebuffer */ + memset(pGeode->FBBase + pGeode->displayOffset, 0, pGeode->displaySize); + + /* Set up the video mode */ + + LXSetVideoMode(pScrni, pScrni->currentMode); + pGeode->curMode = pScrni->currentMode; + pScrni->vtSema = TRUE; + + return TRUE; +} - LXUnmapMem(pScrni); +static void +LXLoadPalette(ScrnInfoPtr pScrni, + int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) +{ + int i, index, color; + + for (i = 0; i < numColors; i++) { + index = indizes[i] & 0xFF; + color = (((unsigned long)(colors[index].red & 0xFF)) << 16) | + (((unsigned long)(colors[index].green & 0xFF)) << 8) | + ((unsigned long)(colors[index].blue & 0xFF)); - if (pGeode && (pScrn->CloseScreen = pGeode->CloseScreen)) { - pGeode->CloseScreen = NULL; - return ((*pScrn->CloseScreen) (scrnIndex, pScrn)); + vg_set_display_palette_entry(index, color); } - return TRUE; } #ifdef DPMSExtension -/*---------------------------------------------------------------------------- - * LXDPMSSet. - * - * Description :This function sets geode into Power Management - * Signalling mode. - * - * Parameters. - * pScrni :Pointer to screen info strucrure. - * mode :Specifies the power management mode. - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ + static void LXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags) { @@ -2218,601 +1132,304 @@ LXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags) pGeode = GEODEPTR(pScrni); - DEBUGMSG(1, (0, X_INFO, "LXDPMSSet!\n")); + if (!pScrni->vtSema) + return; - /* Check if we are actively controlling the display */ - if (!pScrni->vtSema) { - ErrorF("LXDPMSSet called when we not controlling the VT!\n"); - return; - } switch (mode) { - case DPMSModeOn: /* Screen: On; HSync: On; VSync: On */ - lx_enable_dac_power(pScrni, 1); - break; + case DPMSModeOn: + lx_enable_dac_power(pScrni, 1); + break; - case DPMSModeStandby: /* Screen: Off; HSync: Off; VSync: On */ - lx_disable_dac_power(pScrni, DF_CRT_STANDBY); - break; + case DPMSModeStandby: + lx_disable_dac_power(pScrni, DF_CRT_STANDBY); + break; - case DPMSModeSuspend: /* Screen: Off; HSync: On; VSync: Off */ - lx_disable_dac_power(pScrni, DF_CRT_SUSPEND); - break; + case DPMSModeSuspend: + lx_disable_dac_power(pScrni, DF_CRT_SUSPEND); + break; - case DPMSModeOff: /* Screen: Off; HSync: Off; VSync: Off */ - lx_disable_dac_power(pScrni, DF_CRT_DISABLE); - break; + case DPMSModeOff: + lx_disable_dac_power(pScrni, DF_CRT_DISABLE); + break; } } + #endif -/*---------------------------------------------------------------------------- - * LXScreenInit. - * - * Description :This function will be called at the each ofserver - * generation. - * - * Parameters. - * scrnIndex :Specfies the screenindex value during generation. - * pScrn :Pointer to screen strucrure. - * argc :parameters for command line arguments count - * argv :command line arguments if any it is not used. - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ static Bool -LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) +LXCreateScreenResources(ScreenPtr pScreen) { - int i, bytpp, size, fbsize, fboffset, fbavail; - int pitch, displayWidth, virtualX, virtualY; - int HDisplay, VDisplay, maxHDisplay, maxVDisplay, maxX, maxY; - unsigned char *FBStart, **ap, *bp; - DisplayModePtr p; - GeodeRec *pGeode; - VisualPtr visual; - BoxRec AvailBox; - RegionRec OffscreenRegion; - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - Bool Inited = FALSE; - - DEBUGMSG(1, (0, X_INFO, "LXScreenInit!\n")); - /* Get driver private */ - pGeode = LXGetRec(pScrni); - DEBUGMSG(1, (0, X_INFO, "LXScreenInit(0)!\n")); - - /* - * Allocate a vgaHWRec - */ - - if (!vgaHWGetHWRec(pScrni)) - return FALSE; - if (!vgaHWMapMem(pScrni)) - return FALSE; - - vgaHWGetIOBase(VGAHWPTR(pScrni)); + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); - if (!LXMapMem(pScrni)) - return FALSE; + pScreen->CreateScreenResources = pGeode->CreateScreenResources; + if (!(*pScreen->CreateScreenResources) (pScreen)) + return FALSE; - pGeode->Pitch = LXCalculatePitchBytes(pScrni->virtualX, - pScrni->bitsPerPixel); - pGeode->AccelPitch = pGeode->Pitch; - bytpp = (pScrni->bitsPerPixel + 7) / 8; + if (xf86LoaderCheckSymbol("LXRandRSetConfig") + && pGeode->rotation != RR_Rotate_0) { + Rotation(*LXRandRSetConfig) (ScreenPtr pScreen, Rotation rr, int rate, + RRScreenSizePtr pSize) = NULL; + RRScreenSize p; + Rotation requestedRotation = pGeode->rotation; - /* start of framebuffer for accels */ - fboffset = 0; - fbavail = pGeode->FBAvail; + pGeode->rotation = RR_Rotate_0; - /* allocate display frame buffer at zero offset */ - fbsize = pScrni->virtualY * pGeode->Pitch; - pGeode->FBSize = fbsize; + /* Just setup enough for an initial rotate */ - pGeode->CursorSize = (HW_CURSOR_W * HW_CURSOR_H) / 8 * 2; - pGeode->CursorStartOffset = 0; + p.width = pScreen->width; + p.height = pScreen->height; + p.mmWidth = pScreen->mmWidth; + p.mmHeight = pScreen->mmHeight; - DEBUGMSG(1, (scrnIndex, X_PROBED, "%d %d %d\n", - pScrni->virtualX, pScrni->bitsPerPixel, pGeode->Pitch)); + LXRandRSetConfig = LoaderSymbol("LXRandRSetConfig"); + if (LXRandRSetConfig) { + pGeode->starting = TRUE; + (*LXRandRSetConfig) (pScreen, requestedRotation, 0, &p); + pGeode->starting = FALSE; + } + } - HDisplay = pScrni->currentMode->HDisplay; - VDisplay = pScrni->currentMode->VDisplay; - pGeode->orig_virtX = pScrni->virtualX; - pGeode->orig_virtY = pScrni->virtualY; + return TRUE; +} - p = pScrni->modes; - maxHDisplay = p->HDisplay; - maxVDisplay = p->VDisplay; - while ((p = p->next) != pScrni->modes) { - if (maxHDisplay < p->HDisplay) - maxHDisplay = p->HDisplay; - if (maxVDisplay < p->VDisplay) - maxVDisplay = p->VDisplay; - } - DEBUGMSG(1, (scrnIndex, X_PROBED, "maxHDisplay %d maxVDisplay %d\n", - maxHDisplay, maxVDisplay)); - - switch (pGeode->Rotate) { - case 1: - case 3: - pGeode->HDisplay = VDisplay; - pGeode->VDisplay = HDisplay; - virtualX = pScrni->virtualY; - virtualY = pScrni->virtualX; - maxX = maxVDisplay; - maxY = maxHDisplay; - break; - default: - pGeode->HDisplay = HDisplay; - pGeode->VDisplay = VDisplay; - virtualX = pScrni->virtualX; - virtualY = pScrni->virtualY; - maxX = maxHDisplay; - maxY = maxVDisplay; - break; - } +static Bool +LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) +{ + ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; + GeodeRec *pGeode = GEODEPTR(pScrni); + XF86ModReqInfo shadowReq; + int maj, min, ret, rotate; - /* shadow may be first in FB, since accels render there */ - - pGeode->ShadowPtr = NULL; - if (pGeode->ShadowFB) { - if (!pGeode->PointerMoved) { - pGeode->PointerMoved = pScrni->PointerMoved; - pScrni->PointerMoved = LXPointerMoved; - } - if (!pGeode->NoAccel) { - pGeode->ShadowPitch = - LXCalculatePitchBytes(virtualX, pScrni->bitsPerPixel); - size = pGeode->ShadowPitch * virtualY; - if (size <= fbavail - fbsize) { - pGeode->ShadowPtr = - (unsigned char *)pGeode->FBBase + fboffset; - pGeode->AccelPitch = pGeode->ShadowPitch; - pGeode->ShadowSize = size; - pGeode->ShadowInFBMem = TRUE; - fboffset += size; - fbavail -= size; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Shadow FB, No FB Memory, trying offscreen\n"); - } - } - if (pGeode->ShadowPtr == NULL) { - pGeode->ShadowPitch = - BitmapBytePad(pScrni->bitsPerPixel * virtualX); - size = pGeode->ShadowPitch * virtualY; - pGeode->ShadowPtr = xalloc(size); - if (pGeode->ShadowPtr != NULL) { - pGeode->ShadowSize = size; - pGeode->ShadowInFBMem = FALSE; - if (!pGeode->NoAccel) { - pGeode->NoAccel = TRUE; - pGeode->HWCursor = FALSE; - xf86DrvMsg(scrnIndex, X_ERROR, - "Shadow FB offscreen, All Accels disabled\n"); - } - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Shadow FB, No offscreen Memory, disabled\n"); - pGeode->ShadowFB = FALSE; - pGeode->Rotate = 0; - pGeode->HDisplay = HDisplay; - pGeode->VDisplay = VDisplay; - virtualX = pScrni->virtualX; - virtualY = pScrni->virtualY; - } - } - } + pGeode->starting = TRUE; - if (pGeode->ShadowPtr != NULL) { - displayWidth = pGeode->ShadowPitch / bytpp; - FBStart = pGeode->ShadowPtr; - DEBUGMSG(1, (0, X_PROBED, "Shadow %p \n", FBStart)); - } else { - displayWidth = pGeode->Pitch / bytpp; - FBStart = pGeode->FBBase; - DEBUGMSG(1, (0, X_PROBED, "FBStart %p \n", FBStart)); - } + /* If we are using VGA then go ahead and map the memory */ - DEBUGMSG(1, (0, X_PROBED, "FB display %X size %X \n", fboffset, fbsize)); - pGeode->FBOffset = fboffset; /* offset of display framebuffer */ - pScrni->fbOffset = fboffset; - fboffset += fbsize; - fbavail -= fbsize; - - if (pGeode->Compression) { /* Compression enabled */ - pGeode->CBData.size = 512 + 32; - pGeode->CBData.pitch = 512 + 32; - size = maxY * pGeode->CBData.pitch; - DEBUGMSG(1, (0, X_PROBED, "CB %#x size %#x (%d*%lu)\n", fboffset, - size, maxY, pGeode->CBData.pitch)); - if (size <= fbavail) { - pGeode->CBData.compression_offset = fboffset; - fboffset += size; - fbavail -= size; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Compression, No FB Memory, disabled\n"); - pGeode->Compression = FALSE; - } - } + if (pGeode->useVGA) { - if (pGeode->HWCursor) { /* HWCursor enabled */ - size = pGeode->CursorSize; - if (size <= fbavail) { - pGeode->CursorStartOffset = fboffset; - fboffset += size; - fbavail -= size; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "HWCursor, No FB Memory, disabled\n"); - pGeode->HWCursor = FALSE; - } - } + if (!vgaHWMapMem(pScrni)) + return FALSE; - if (!pGeode->NoAccel) { /* Acceleration enabled */ - if (pGeode->NoOfImgBuffers > 0) { - pGeode->AccelImageWriteBuffers = NULL; - pitch = pGeode->AccelPitch; - size = pitch * pGeode->NoOfImgBuffers; -#if !LX_USE_OFFSCRN_MEM - if (size <= fbavail) { - bp = (unsigned char *)pGeode->FBBase + fboffset; - ap = xalloc(sizeof(pGeode->AccelImageWriteBuffers[0]) * - pGeode->NoOfImgBuffers); - if (ap != NULL) { - for (i = 0; i < pGeode->NoOfImgBuffers; ++i) { - ap[i] = bp; - bp += pitch; - } - pGeode->AccelImageWriteBuffers = ap; - fboffset += size; - fbavail -= size; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Image Write, No Memory\n"); - } - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No FB Memory\n"); - } -#else - if ((bp = (unsigned char *)xalloc(size)) != NULL) { - ap = xalloc(sizeof(pGeode->AccelImageWriteBuffers[0]) * - pGeode->NoOfImgBuffers); - if (ap != NULL) { - for (i = 0; i < pGeode->NoOfImgBuffers; ++i) { - ap[i] = bp; - bp += pitch; - } - pGeode->AccelImageWriteBuffers = ap; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Image Write, No Memory\n"); - } - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Image Write, No offscreen Memory\n"); - } -#endif - if (pGeode->AccelImageWriteBuffers == NULL) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Accel Image Write disabled\n"); - pGeode->NoOfImgBuffers = 0; - } - } - - if (pGeode->NoOfColorExpandLines > 0) { - pGeode->AccelColorExpandBuffers = NULL; - pitch = ((pGeode->AccelPitch + 31) >> 5) << 2; - size = pitch * pGeode->NoOfColorExpandLines; - if ((bp = (unsigned char *)xalloc(size)) != NULL) { - ap = xalloc(sizeof(pGeode->AccelColorExpandBuffers[0]) * - pGeode->NoOfColorExpandLines); - if (ap != NULL) { - for (i = 0; i < pGeode->NoOfColorExpandLines; ++i) { - ap[i] = bp; - bp += pitch; - } - pGeode->AccelColorExpandBuffers = ap; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Color Expansion, No Memory\n"); - } - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Color Expansion, No offscreen Memory\n"); - } - if (pGeode->AccelColorExpandBuffers == NULL) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Accel Color Expansion disabled\n"); - pGeode->NoOfColorExpandLines = 0; - } - } - } else { - pGeode->NoOfImgBuffers = 0; - pGeode->AccelImageWriteBuffers = NULL; - pGeode->NoOfColorExpandLines = 0; - pGeode->AccelColorExpandBuffers = NULL; + vgaHWGetIOBase(VGAHWPTR(pScrni)); } + + if (!pGeode->NoAccel) { - /* Initialise graphics mode */ + pGeode->pExa = xnfcalloc(sizeof(ExaDriverRec), 1); + + if (pGeode->pExa) { + + /* THis is set in LXAllocMem */ + pGeode->pExa->memoryBase = 0; + + /* This is set in LXAllocateMemory */ + pGeode->pExa->memorySize = 0; + + pGeode->pExa->pixmapOffsetAlign = 32; + pGeode->pExa->pixmapPitchAlign = 32; + pGeode->pExa->flags = EXA_OFFSCREEN_PIXMAPS; + pGeode->pExa->maxX = pGeode->maxWidth - 1; + pGeode->pExa->maxY = pGeode->maxHeight - 1; + } + else { + xf86DrvMsg(scrnIndex, X_ERROR, "Couldn't allocate the EXA structure.\n"); + pGeode->NoAccel = TRUE; + } + } + + /* XXX FIXME - Take down any of the structures on failure? */ if (!LXEnterGraphics(pScrn, pScrni)) - return FALSE; + return FALSE; - pScrni->virtualX = virtualX; - pScrni->virtualY = virtualY; - - /* Reset visual list */ miClearVisualTypes(); - /* Setup the visual we support */ + /* XXX Again - take down anything? */ + if (pScrni->bitsPerPixel > 8) { - DEBUGMSG(1, (scrnIndex, X_PROBED, - "miSetVisualTypes %d %X %X %X\n", - pScrni->depth, - TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)); - - if (!miSetVisualTypes(pScrni->depth, - TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)) { - return FALSE; - } + if (!miSetVisualTypes(pScrni->depth, + TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)) { + return FALSE; + } } else { - if (!miSetVisualTypes(pScrni->depth, - miGetDefaultVisualMask(pScrni->depth), - pScrni->rgbBits, pScrni->defaultVisual)) { - return FALSE; - } + if (!miSetVisualTypes(pScrni->depth, + miGetDefaultVisualMask(pScrni->depth), + pScrni->rgbBits, pScrni->defaultVisual)) { + return FALSE; + } } - /* Set for RENDER extensions */ miSetPixmapDepths(); - /* Call the framebuffer layer's ScreenInit function, and fill in other - * pScrn fields. - */ - switch (pScrni->bitsPerPixel) { -#if CFB - case 8: - Inited = cfbScreenInit(pScrn, FBStart, virtualX, virtualY, - pScrni->xDpi, pScrni->yDpi, displayWidth); - break; - case 16: - Inited = cfb16ScreenInit(pScrn, FBStart, virtualX, virtualY, - pScrni->xDpi, pScrni->yDpi, displayWidth); - break; - case 24: - case 32: - Inited = cfb32ScreenInit(pScrn, FBStart, virtualX, virtualY, - pScrni->xDpi, pScrni->yDpi, displayWidth); - break; -#else - case 8: - case 16: - case 24: - case 32: - Inited = fbScreenInit(pScrn, FBStart, virtualX, virtualY, - pScrni->xDpi, pScrni->yDpi, displayWidth, pScrni->bitsPerPixel); - break; -#endif - default: - xf86DrvMsg(scrnIndex, X_ERROR, - "Internal error: invalid bpp (%d) in ScreenInit\n", - pScrni->bitsPerPixel); - Inited = FALSE; - break; - } + /* Point at the visible area to start */ - if (!Inited) - return FALSE; - - LXRotationInit(pScrni); - LXAdjustFrame(scrnIndex, pScrni->frameX0, pScrni->frameY0, 0); - - /* SET UP GRAPHICS MEMORY AVAILABLE FOR PIXMAP CACHE */ - AvailBox.x1 = 0; - AvailBox.y1 = (fboffset + pGeode->AccelPitch - 1) / pGeode->AccelPitch; - AvailBox.x2 = displayWidth; - AvailBox.y2 = (pGeode->FBAvail - pGeode->AccelPitch + 1) / - pGeode->AccelPitch; - - if (AvailBox.y1 < AvailBox.y2) { - xf86DrvMsg(scrnIndex, X_INFO, - "Initializing Memory manager to (%d,%d) (%d,%d)\n", - AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2); - REGION_INIT(pScrn, &OffscreenRegion, &AvailBox, 2); - if (!xf86InitFBManagerRegion(pScrn, &OffscreenRegion)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Memory manager initialization failed, Cache Diabled\n"); - } - REGION_UNINIT(pScrn, &OffscreenRegion); - } else { - xf86DrvMsg(scrnIndex, X_INFO, - "No Off Screen Memory, Cache Disabled (%d,%d) (%d,%d)\n", - AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2); - } + ret = fbScreenInit(pScrn, pGeode->FBBase + pGeode->displayOffset, + pScrni->virtualX, pScrni->virtualY, + pScrni->xDpi, pScrni->yDpi, pGeode->displayWidth, + pScrni->bitsPerPixel); - xf86SetBlackWhitePixels(pScrn); + if (!ret) + return FALSE; - if (!pGeode->ShadowFB) { - LXDGAInit(pScrn); - } + xf86SetBlackWhitePixels(pScrn); + /* Set up the color ordering */ if (pScrni->bitsPerPixel > 8) { - /* Fixup RGB ordering */ - visual = pScrn->visuals + pScrn->numVisuals; - while (--visual >= pScrn->visuals) { - if ((visual->class | DynamicClass) == DirectColor) { - visual->offsetRed = pScrni->offset.red; - visual->offsetGreen = pScrni->offset.green; - visual->offsetBlue = pScrni->offset.blue; - visual->redMask = pScrni->mask.red; - visual->greenMask = pScrni->mask.green; - visual->blueMask = pScrni->mask.blue; - } - } + VisualPtr visual = pScrn->visuals + pScrn->numVisuals; + + while (--visual >= pScrn->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrni->offset.red; + visual->offsetGreen = pScrni->offset.green; + visual->offsetBlue = pScrni->offset.blue; + visual->redMask = pScrni->mask.red; + visual->greenMask = pScrni->mask.green; + visual->blueMask = pScrni->mask.blue; + } + } } -#if CFB -#else - /* must be after RGB ordering fixed */ + + /* Must follow the color ordering */ fbPictureInit(pScrn, 0, 0); -#endif - if (!pGeode->NoAccel) { - LXAccelInit(pScrn); - } + if (!pGeode->NoAccel) + pGeode->NoAccel = LXExaInit(pScrn) ? FALSE : TRUE; + miInitializeBackingStore(pScrn); xf86SetBackingStore(pScrn); - /* Initialise software cursor */ + + /* Set up the soft cursor */ miDCInitialize(pScrn, xf86GetPointerScreenFuncs()); - /* Initialize HW cursor layer. - * Must follow software cursor initialization - */ - if (pGeode->HWCursor) { - if (!LXHWCursorInit(pScrn)) - xf86DrvMsg(pScrni->scrnIndex, X_ERROR, - "Hardware cursor initialization failed\n"); - } - /* Setup default colourmap */ - if (!miCreateDefColormap(pScrn)) { - return FALSE; + + /* Set up the HW cursor - must follow the soft cursor init */ + + if (pGeode->tryHWCursor) { + if (!LXHWCursorInit(pScrn)) + xf86DrvMsg(scrnIndex, X_ERROR, + "Hardware cursor initialization failed.\n"); } + + /* Set up the color map */ + + if (!miCreateDefColormap(pScrn)) + return FALSE; + if (pScrni->bitsPerPixel == 8) { - /* Initialize colormap layer. - * Must follow initialization of the default colormap - */ - if (!xf86HandleColormaps(pScrn, 256, 8, LXLoadPalette, NULL, - CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { - return FALSE; - } - } + /* Must follow initialization of the default colormap */ - if (pGeode->ShadowFB) { - DEBUGMSG(1, (0, X_INFO, "Shadowed, Rotate=%d, NoAccel=%d\n", - pGeode->Rotate, pGeode->NoAccel)); - LXShadowFBInit(pScrn, pGeode, bytpp); + if (!xf86HandleColormaps(pScrn, 256, 8, + LXLoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { + return FALSE; + } } #ifdef DPMSExtension xf86DPMSInit(pScrn, LXDPMSSet, 0); #endif - LXInitVideo(pScrn); /* needed for video */ - /* Wrap the screen's CloseScreen vector and set its - * SaveScreen vector - */ + LXInitVideo(pScrn); + + /* Set up RandR */ + /* We provide our own RandR goodness - disable the default */ + xf86DisableRandR(); + + memset(&shadowReq, 0, sizeof(shadowReq)); + shadowReq.majorversion = 1; + shadowReq.minorversion = 1; + + if (LoadSubModule(pScrni->module, "shadow", + NULL, NULL, NULL, &shadowReq, &maj, &min)) { + + rotate = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270; + shadowSetup(pScrn); + } else { + LoaderErrorMsg(NULL, "shadow", maj, min); + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Error loading shadow - rotation not available.\n"); + + if (pGeode->rotation != RR_Rotate_0) + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, + "Reverting back to normal rotation.\n"); + + rotate = pGeode->rotation = RR_Rotate_0; + } + + LXRandRInit(pScrn, rotate); + + pGeode->PointerMoved = pScrni->PointerMoved; + pScrni->PointerMoved = GeodePointerMoved; + pGeode->CreateScreenResources = pScrn->CreateScreenResources; + pScrn->CreateScreenResources = LXCreateScreenResources; + pGeode->CloseScreen = pScrn->CloseScreen; pScrn->CloseScreen = LXCloseScreen; - pScrn->SaveScreen = LXSaveScreen; - /* Report any unused options */ - if (serverGeneration == 1) { - xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); - } + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); - return TRUE; -} + pGeode->starting = FALSE; -/*---------------------------------------------------------------------------- - * LXSwitchMode. - * - * Description :This function will switches the screen mode - * - * Parameters: - * scrnIndex :Specfies the screen index value. - * pMode :pointer to the mode structure. - * flags :may be used for status check?. - * - * Returns :Returns TRUE on success and FALSE on failure. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ -Bool -LXSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags) -{ - DEBUGMSG(1, (0, X_INFO, "LXSwitchMode\n")); - return LXSetMode(xf86Screens[scrnIndex], pMode); + return TRUE; } -/*---------------------------------------------------------------------------- - * LXAdjustFrame. - * - * Description :This function is used to intiallize the start - * address of the memory. - * Parameters. - * scrnIndex :Specfies the screen index value. - * x :x co-ordinate value interms of pixels. - * y :y co-ordinate value interms of pixels. - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ -void -LXAdjustFrame(int scrnIndex, int x, int y, int flags) +static int +LXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) { ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; GeodeRec *pGeode = GEODEPTR(pScrni); - int newX, newY; - unsigned long offset; - - if (x + pGeode->HDisplay >= pScrni->virtualX) - x = pScrni->virtualX - pGeode->HDisplay; - if (x < 0) - x = 0; - if (y + pGeode->VDisplay >= pScrni->virtualY) - y = pScrni->virtualY - pGeode->VDisplay; - if (y < 0) - y = 0; - pScrni->frameX0 = x; - pScrni->frameY0 = y; - pScrni->frameX1 = x + pGeode->HDisplay - 1; - pScrni->frameY1 = y + pGeode->VDisplay - 1; - (*pGeode->Rotation) (x, y, pScrni->virtualX, pScrni->virtualY, &newX, - &newY); - (*pGeode->RBltXlat) (newX, newY, pGeode->HDisplay, pGeode->VDisplay, - &newX, &newY); - offset = pGeode->FBOffset + newY * pGeode->Pitch + - newX * (pScrni->bitsPerPixel >> 3); - vg_set_display_offset(offset); + int p, ret; + VG_QUERY_MODE vgQueryMode; + + memset(&vgQueryMode, 0, sizeof(vgQueryMode)); + + if (pMode->type && pMode->type != M_T_USERDEF) { + + if (pGeode->Output & OUTPUT_PANEL) { + + /* Can't scale this mode */ + + if ((pGeode->PanelY != pMode->CrtcHDisplay) && + pMode->CrtcHDisplay > 1024) + return MODE_NOMODE; + + vgQueryMode.panel_width = pGeode->PanelX; + vgQueryMode.panel_height = pGeode->PanelY; + + vgQueryMode.query_flags |= VG_QUERYFLAG_PANELWIDTH | VG_QUERYFLAG_PANELHEIGHT; + } + + vgQueryMode.active_width = pMode->CrtcHDisplay; + vgQueryMode.active_height = pMode->CrtcVDisplay; + vgQueryMode.bpp = pScrni->bitsPerPixel; + vgQueryMode.hz = GeodeGetRefreshRate(pMode); + vgQueryMode.query_flags |= VG_QUERYFLAG_REFRESH | VG_QUERYFLAG_BPP | + VG_QUERYFLAG_ACTIVEWIDTH | VG_QUERYFLAG_ACTIVEHEIGHT; + + ret = vg_get_display_mode_index(&vgQueryMode); + + if (ret < 0) + return MODE_BAD; + } + + if (pGeode->tryCompression) + p = GeodeCalculatePitchBytes(pMode->CrtcHDisplay, pScrni->bitsPerPixel); + else + p = ((pMode->CrtcHDisplay + 3) & ~3) * (pScrni->bitsPerPixel >> 3); + + if (p * pMode->CrtcVDisplay > pGeode->FBAvail) + return MODE_MEM; + + return MODE_OK; } -/*---------------------------------------------------------------------------- - * LXEnterVT. - * - * Description :This is called when VT switching back to the X server - * - * Parameters. - * scrnIndex :Specfies the screen index value. - * flags :Not used inside the function. - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ +/* XXX - Way more to do here */ + static Bool LXEnterVT(int scrnIndex, int flags) { - DEBUGMSG(1, (0, X_INFO, "LXEnterVT\n")); return LXEnterGraphics(NULL, xf86Screens[scrnIndex]); } -/*---------------------------------------------------------------------------- - * LXLeaveVT. - * - * Description :This is called when VT switching X server text mode. - * - * Parameters. - * scrnIndex :Specfies the screen index value. - * flags :Not used inside the function. - * - * Returns :none. - * - * Comments :none. -*---------------------------------------------------------------------------- -*/ static void LXLeaveVT(int scrnIndex, int flags) { @@ -2820,232 +1437,20 @@ LXLeaveVT(int scrnIndex, int flags) GeodeRec *pGeode = GEODEPTR(pScrni); pGeode->PrevDisplayOffset = vg_get_display_offset(); - DEBUGMSG(1, (0, X_INFO, "LXLeaveVT\n")); LXLeaveGraphics(xf86Screens[scrnIndex]); } -/*---------------------------------------------------------------------------- - * LXFreeScreen. - * - * Description :This is called to free any persistent data structures. - * - * Parameters. - * scrnIndex :Specfies the screen index value. - * flags :Not used inside the function. - * - * Returns :none. - * - * Comments :This will be called only when screen being deleted.. -*---------------------------------------------------------------------------- -*/ -static void -LXFreeScreen(int scrnIndex, int flags) -{ - DEBUGMSG(1, (0, X_INFO, "LXFreeScreen\n")); - if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) - vgaHWFreeHWRec(xf86Screens[scrnIndex]); - LXFreeRec(xf86Screens[scrnIndex]); -} - -/*---------------------------------------------------------------------------- - * LXValidMode. - * - * Description :This function checks if a mode is suitable for selected - * chipset. - * Parameters. - * scrnIndex :Specfies the screen index value. - * pMode :Pointer to the screen mode structure.. - * verbose :not used for implementation. - * flags :not used for implementation - * - * Returns :MODE_OK if the specified mode is supported or - * MODE_NO_INTERLACE. - * Comments :none. -*---------------------------------------------------------------------------- -*/ -static int -LXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) -{ - unsigned int total_memory_required; - ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; - int ret = -1; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DEBUGMSG(0, (0, X_NONE, "GeodeValidateMode: %dx%d %d %d\n", - pMode->CrtcHDisplay, pMode->CrtcVDisplay, - pScrni->bitsPerPixel, LXGetRefreshRate(pMode))); - if (pGeode->CustomMode == 0) { - int tv_mode; - VG_QUERY_MODE vgQueryMode; - unsigned long flags; - - if (pMode->Flags & V_INTERLACE) - return MODE_NO_INTERLACE; - - flags = VG_QUERYFLAG_REFRESH | VG_QUERYFLAG_BPP | - VG_QUERYFLAG_ACTIVEWIDTH | VG_QUERYFLAG_ACTIVEHEIGHT; - - if ((pGeode->EnabledOutput & LX_OT_FP) != 0) { - /* scaling required, but too big to scale */ - if (pGeode->FPGeomDstX != pMode->CrtcHDisplay - && pMode->CrtcHDisplay > 1024) - return MODE_NOMODE; - flags = VG_QUERYFLAG_PANELWIDTH | VG_QUERYFLAG_PANELHEIGHT | - VG_QUERYFLAG_PANEL; - vgQueryMode.panel_width = pGeode->FPGeomDstX; - vgQueryMode.panel_height = pGeode->FPGeomDstY; - } - - vgQueryMode.active_width = pMode->CrtcHDisplay; - vgQueryMode.active_height = pMode->CrtcVDisplay; - vgQueryMode.bpp = pScrni->bitsPerPixel; - vgQueryMode.hz = LXGetRefreshRate(pMode); - vgQueryMode.query_flags = VG_QUERYFLAG_REFRESH | VG_QUERYFLAG_BPP | - VG_QUERYFLAG_ACTIVEWIDTH | VG_QUERYFLAG_ACTIVEHEIGHT; - if ((tv_mode = lx_tv_mode(pMode)) >= 0) { - vgQueryMode.encoder = pGeode->tv_encoder; - vgQueryMode.tvmode = tv_mode; - vgQueryMode.query_flags |= - VG_QUERYFLAG_TVMODE | VG_QUERYFLAG_ENCODER; - vgQueryMode.query_flags &= ~VG_QUERYFLAG_REFRESH; - if (lx_tv_mode_interlaced(tv_mode) != 0) { - vgQueryMode.query_flags |= VG_QUERYFLAG_INTERLACED; - vgQueryMode.active_height /= 2; - } - } - ret = vg_get_display_mode_index(&vgQueryMode); - if (ret < 0) - return MODE_NOMODE; - } - - total_memory_required = LXCalculatePitchBytes(pMode->CrtcHDisplay, - pScrni->bitsPerPixel) * pMode->CrtcVDisplay; - - DEBUGMSG(0, (0, X_NONE, "Total Mem %x %lx\n", - total_memory_required, pGeode->FBAvail)); - - if (total_memory_required > pGeode->FBAvail) - return MODE_MEM; - - return MODE_OK; -} - -/*---------------------------------------------------------------------------- - * LXLoadPalette. - * - * Description :This function sets the palette entry used for graphics data - * - * Parameters. - * pScrni:Points the screeninfo structure. - * numColors:Specifies the no of colors it supported. - * indizes :This is used get index value . - * LOCO :to be added. - * pVisual :to be added. - * - * Returns :MODE_OK if the specified mode is supported or - * MODE_NO_INTERLACE. - * Comments :none. -*---------------------------------------------------------------------------- -*/ - -static void -LXLoadPalette(ScrnInfoPtr pScrni, - int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) -{ - int i, index, color; - - for (i = 0; i < numColors; i++) { - index = indizes[i] & 0xFF; - color = (((unsigned long)(colors[index].red & 0xFF)) << 16) | - (((unsigned long)(colors[index].green & 0xFF)) << 8) | - ((unsigned long)(colors[index].blue & 0xFF)); - vg_set_display_palette_entry(index, color); - } -} - -static Bool -LXMapMem(ScrnInfoPtr pScrni) +void +LXSetupChipsetFPtr(ScrnInfoPtr pScrn) { - unsigned long cmd_bfr_phys; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DEBUGMSG(1, (0, X_NONE, "LXMapMem\n")); - - cim_gp_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_MMIO, - pGeode->InitBaseAddress.gp_register_base, pGeode->gp_reg_size); - cim_vg_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_MMIO, - pGeode->InitBaseAddress.vg_register_base, pGeode->vg_reg_size); - cim_vid_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_MMIO, - pGeode->InitBaseAddress.df_register_base, pGeode->vid_reg_size); - cim_vip_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_MMIO, - pGeode->InitBaseAddress.vip_register_base, pGeode->vip_reg_size); - - cim_fb_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_FRAMEBUFFER, - pGeode->InitBaseAddress.framebuffer_base, - pGeode->InitBaseAddress.framebuffer_size); - - pGeode->FBBase = cim_fb_ptr; - - DEBUGMSG(1, (0, X_NONE, "cim ptrs %p %p %p %p %p\n", - cim_gp_ptr, cim_vg_ptr, cim_vid_ptr, cim_vip_ptr, cim_fb_ptr)); - - /* CHECK IF REGISTERS WERE MAPPED SUCCESSFULLY */ - if ((!cim_gp_ptr) || (!cim_vid_ptr) || (!cim_fb_ptr)) { - DEBUGMSG(1, (0, X_NONE, "Could not map hardware registers.\n")); - return (FALSE); - } - - cmd_bfr_phys = - pGeode->InitBaseAddress.framebuffer_base + pGeode->CmdBfrOffset; - cim_cmd_base_ptr = cim_fb_ptr + pGeode->CmdBfrOffset; - - /* - * Map the top of the frame buffer as the scratch buffer - * (GP3_SCRATCH_BUFFER_SIZE) - */ - gp_set_frame_buffer_base(pGeode->InitBaseAddress.framebuffer_base, - pGeode->FBTop); - gp_set_command_buffer_base(cmd_bfr_phys, 0, pGeode->CmdBfrSize); - DEBUGMSG(1, (0, X_NONE, "cim cmd %p %lx %lx %lx\n", - cim_cmd_base_ptr, pGeode->CmdBfrSize, cmd_bfr_phys, - pGeode->FBTop)); - - /* Map the XpressROM ptr to read what platform are we on */ - XpressROMPtr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, - VIDMEM_FRAMEBUFFER, 0xF0000, 0x10000); - - DEBUGMSG(1, (0, X_NONE, "adapter info %lx %lx %lx %lx %p, %p\n", - pGeode->cpu_version, - pGeode->vid_version, pGeode->FBLinearAddr, - pGeode->FBAvail, pGeode->FBBase, XpressROMPtr)); - - return TRUE; + pScrn->PreInit = LXPreInit; + pScrn->ScreenInit = LXScreenInit; + pScrn->SwitchMode = LXSwitchMode; + pScrn->AdjustFrame = LXAdjustFrame; + pScrn->EnterVT = LXEnterVT; + pScrn->LeaveVT = LXLeaveVT; + pScrn->FreeScreen = GeodeFreeScreen; + pScrn->ValidMode = LXValidMode; } -/* - * Unmap the framebuffer and MMIO memory. - */ -static Bool -LXUnmapMem(ScrnInfoPtr pScrni) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - DEBUGMSG(1, (0, X_NONE, "LXUnMapMem\n")); - - /* unmap all the memory map's */ - xf86UnMapVidMem(pScrni->scrnIndex, cim_gp_ptr, pGeode->gp_reg_size); - xf86UnMapVidMem(pScrni->scrnIndex, cim_vg_ptr, pGeode->vg_reg_size); - xf86UnMapVidMem(pScrni->scrnIndex, cim_vid_ptr, pGeode->vid_reg_size); - xf86UnMapVidMem(pScrni->scrnIndex, cim_vip_ptr, pGeode->vip_reg_size); - xf86UnMapVidMem(pScrni->scrnIndex, - cim_fb_ptr, pGeode->InitBaseAddress.framebuffer_size); - xf86UnMapVidMem(pScrni->scrnIndex, XpressROMPtr, 0x10000); - - return TRUE; -} diff --git a/src/amd_lx_exa.c b/src/amd_lx_exa.c new file mode 100644 index 0000000..4b25908 --- /dev/null +++ b/src/amd_lx_exa.c @@ -0,0 +1,1044 @@ +/* + * Copyright (c) 2007 Advanced Micro Devices, Inc. + * + * 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, + * 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. + * + * Neither the name of the Advanced Micro Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + */ + +/* TODO: + Support a8 as a source or destination? + convert !a8 or !a4 masks? + support multiple pass operations? +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "amd.h" +#include "cim_defs.h" +#include "cim_regs.h" + +#include "amd_blend.h" + +static const struct exa_format_t { + int exa; + int bpp; + int fmt; + int alphabits; +} lx_exa_formats[] = { + {PICT_a8r8g8b8, 32, CIMGP_SOURCE_FMT_8_8_8_8, 8 }, + {PICT_x8r8g8b8, 32, CIMGP_SOURCE_FMT_8_8_8_8, 0 }, + {PICT_x8b8g8r8, 32, CIMGP_SOURCE_FMT_32BPP_BGR, 0 }, + {PICT_a4r4g4b4, 16, CIMGP_SOURCE_FMT_4_4_4_4, 4 }, + {PICT_a1r5g5b5, 16, CIMGP_SOURCE_FMT_1_5_5_5, 1 }, + {PICT_r5g6b5, 16, CIMGP_SOURCE_FMT_0_5_6_5, 0 }, + {PICT_b5g6r5, 16, CIMGP_SOURCE_FMT_16BPP_BGR, 0 }, + {PICT_x1r5g5b5, 16, CIMGP_SOURCE_FMT_1_5_5_5, 0 }, + {PICT_x1b5g5r5, 16, CIMGP_SOURCE_FMT_15BPP_BGR, 0 }, + {PICT_r3g3b2, 8, CIMGP_SOURCE_FMT_3_3_2, 0 } +}; + +/* This is a chunk of memory we use for scratch space */ + +#define COMP_TYPE_MASK 0 +#define COMP_TYPE_ONEPASS 1 +#define COMP_TYPE_TWOPASS 3 + +static struct { + int type; + + unsigned int srcOffset; + unsigned int srcPitch; + unsigned int srcBpp; + unsigned int srcWidth, srcHeight; + PixmapPtr srcPixmap; + + int op; + int repeat; + unsigned int fourBpp; + unsigned int bufferOffset; + struct exa_format_t *srcFormat; + struct exa_format_t *dstFormat; +} exaScratch; + +static const int SDfn[16] = { + 0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE, + 0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF +}; + +static const int SDfn_PM[16] = { + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, + 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA +}; + +/* These functions check to see if we can safely prefetch the memory + * for the blt, or if we have to wait the previous blt to complete. + * One function is for the fill, and the other is for the copy because + * they have different requirements based on ROP + */ + +static int lx0 = -1, ly0 = -1, lx1 = -1, ly1 = -1; + +static int lx_fill_flags(int x0, int y0, int w, int h, int rop) +{ + int x1 = x0 + w, y1 = y0 + h; + int n = ((rop^(rop>>1))&0x55) == 0 || /* no dst */ + x0 >= lx1 || y0 >= ly1 || /* rght/below */ + x1 <= lx0 || y1 <= ly0 ? /* left/above */ + 0 : CIMGP_BLTFLAGS_HAZARD; + + lx0 = x0; + ly0 = y0; + lx1 = x1; + ly1 = y1; + + return n; +} + +static int lx_copy_flags(int x0, int y0, int x1, int y1, int w, int h, + int rop) +{ + int x2 = x1+w, y2 = y1+h; + + /* dst not hazzard and src not hazzard */ + int n = ( ((rop^(rop>>1))&0x55) == 0 || + x1 >= lx1 || y1 >= ly1 || + x2 <= lx0 || y2 <= ly0 ) && + ( ((rop^(rop>>2))&0x33) == 0 || + x0 >= lx1 || y0 >= ly1 || + x0+w <= lx0 || y0+h <= ly0 ) ? + 0 : CIMGP_BLTFLAGS_HAZARD; + + lx0 = x1; + ly0 = y1; + lx1 = x2; + ly1 = y2; + + return n; +} + +/* These are borrowed from the exa engine - they should be made global + and available to drivers, but until then.... +*/ + +/* exaGetPixelFromRGBA (exa_render.c) */ + +static Bool +_GetPixelFromRGBA(CARD32 *pixel, + CARD16 red, + CARD16 green, + CARD16 blue, + CARD16 alpha, + CARD32 format) +{ + int rbits, bbits, gbits, abits; + int rshift, bshift, gshift, ashift; + + *pixel = 0; + + if (!PICT_FORMAT_COLOR(format)) + return FALSE; + + rbits = PICT_FORMAT_R(format); + gbits = PICT_FORMAT_G(format); + bbits = PICT_FORMAT_B(format); + abits = PICT_FORMAT_A(format); + + if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { + bshift = 0; + gshift = bbits; + rshift = gshift + gbits; + ashift = rshift + rbits; + } else { /* PICT_TYPE_ABGR */ + rshift = 0; + gshift = rbits; + bshift = gshift + gbits; + ashift = bshift + bbits; + } + + *pixel |= ( blue >> (16 - bbits)) << bshift; + *pixel |= ( red >> (16 - rbits)) << rshift; + *pixel |= (green >> (16 - gbits)) << gshift; + *pixel |= (alpha >> (16 - abits)) << ashift; + + return TRUE; +} + +/* exaGetRGBAFromPixel (exa_render.c) */ + +static Bool +_GetRGBAFromPixel(CARD32 pixel, + CARD16 *red, + CARD16 *green, + CARD16 *blue, + CARD16 *alpha, + CARD32 format) +{ + int rbits, bbits, gbits, abits; + int rshift, bshift, gshift, ashift; + + if (!PICT_FORMAT_COLOR(format)) + return FALSE; + + rbits = PICT_FORMAT_R(format); + gbits = PICT_FORMAT_G(format); + bbits = PICT_FORMAT_B(format); + abits = PICT_FORMAT_A(format); + + if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { + bshift = 0; + gshift = bbits; + rshift = gshift + gbits; + ashift = rshift + rbits; + } else { /* PICT_TYPE_ABGR */ + rshift = 0; + gshift = rbits; + bshift = gshift + gbits; + ashift = bshift + bbits; + } + + *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits); + while (rbits < 16) { + *red |= *red >> rbits; + rbits <<= 1; + } + + *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits); + while (gbits < 16) { + *green |= *green >> gbits; + gbits <<= 1; + } + + *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits); + while (bbits < 16) { + *blue |= *blue >> bbits; + bbits <<= 1; + } + + if (abits) { + *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits); + while (abits < 16) { + *alpha |= *alpha >> abits; + abits <<= 1; + } + } else + *alpha = 0xffff; + + return TRUE; +} + +static unsigned int lx_get_source_color(PicturePtr pSrc, int x, int y, int dstFormat) +{ + FbBits *bits; + FbStride stride; + int bpp, xoff, yoff; + + CARD32 in, out; + CARD16 red, green, blue, alpha; + + fbGetDrawable (pSrc->pDrawable, bits, stride, bpp, xoff, yoff); + + bits += (y * stride) + (x * (bpp >> 3)); + + /* Read the source value */ + + switch(bpp) { + case 32: + case 24: + in = (CARD32) *((CARD32 *) bits); + break; + + case 16: + in = (CARD32) *((CARD16 *) bits); + break; + + case 8: + in = (CARD32) *((CARD8 *) bits); + break; + } + + _GetRGBAFromPixel(in, &red, &blue, &green, &alpha, pSrc->format); + _GetPixelFromRGBA(&out, red, blue, green, alpha, dstFormat); + + return out; +} + +static Bool +lx_prepare_solid(PixmapPtr pxMap, int alu, Pixel planemask, Pixel fg) +{ + int pitch = exaGetPixmapPitch(pxMap); + int op = (planemask == ~0U) ? SDfn[alu] : SDfn_PM[alu]; + + gp_declare_blt(0); + gp_set_bpp(pxMap->drawable.bitsPerPixel); + + gp_set_raster_operation(op); + + if (planemask != ~0U) + gp_set_solid_pattern(planemask); + + exaScratch.op = op; + + gp_set_solid_source(fg); + gp_set_strides(pitch, pitch); + gp_write_parameters(); + return TRUE; +} + +static void +lx_do_solid(PixmapPtr pxMap, int x1, int y1, int x2, int y2) +{ + int bpp = (pxMap->drawable.bitsPerPixel + 7) / 8; + int pitch = exaGetPixmapPitch(pxMap); + unsigned int offset = exaGetPixmapOffset(pxMap) + (pitch * y1) + (bpp * x1); + + gp_declare_blt(lx_fill_flags(x1, y1,x2-x1,y2-y1, exaScratch.op)); + gp_pattern_fill(offset, x2-x1, y2-y1); +} + +static Bool +lx_prepare_copy( PixmapPtr pxSrc, PixmapPtr pxDst, int dx, int dy, + int alu, Pixel planemask) +{ + int dpitch = exaGetPixmapPitch(pxDst); + int op = (planemask == ~0U) ? SDfn[alu] : SDfn_PM[alu]; + + gp_declare_blt(0); + gp_set_bpp(pxDst->drawable.bitsPerPixel); + + gp_set_raster_operation(op); + + if (planemask != ~0U) + gp_set_solid_pattern(planemask); + + exaScratch.srcOffset = exaGetPixmapOffset(pxSrc); + exaScratch.srcPitch = exaGetPixmapPitch(pxSrc); + exaScratch.srcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8; + + exaScratch.op = op; + + gp_set_strides(dpitch, exaScratch.srcPitch); + gp_write_parameters(); + return TRUE; +} + +static void +lx_do_copy(PixmapPtr pxDst, int srcX, int srcY, + int dstX, int dstY, int w, int h) +{ + int dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8; + int dstPitch = exaGetPixmapPitch(pxDst); + unsigned int srcOffset, dstOffset; + int flags = 0; + + gp_declare_blt(lx_copy_flags(srcX, srcY, dstX, dstY,w,h, exaScratch.op)); + + //gp_declare_blt(0); + + srcOffset = exaScratch.srcOffset + (exaScratch.srcPitch * srcY) + + (exaScratch.srcBpp) * srcX; + + dstOffset = exaGetPixmapOffset(pxDst) + (dstPitch * dstY) + + (dstBpp * dstX); + + flags = 0; + + if (dstX > srcX) + flags |= CIMGP_NEGXDIR; + + if (dstY > srcY) + flags |= CIMGP_NEGYDIR; + + gp_screen_to_screen_blt(dstOffset, srcOffset, w, h, flags); +} + +/* Composite operations + +These are the simplest - one pass operations - if there is no format or +mask, the we can make these happen pretty fast + + Operation Type Channel Alpha +PictOpClear 0 2 0 3 +PictOpSrc 0 3 0 3 +PictOpDst 0 3 1 3 +PictOpOver 2 0 0 3 +PictOpOverReverse 2 0 1 3 +PictOpIn 0 1 0 3 +PictOpInReverse 0 1 1 3 +PictOpOut 1 0 0 3 +PictOpOutReverse 1 0 1 3 +PictOpAdd 2 2 0 3 + +The following require multiple passes +PictOpAtop +PictOpXor +*/ + +struct blend_ops_t { + int operation; + int type; + int channel; +} lx_alpha_ops[] = { + /* PictOpClear */ + { CIMGP_ALPHA_TIMES_A, CIMGP_CONSTANT_ALPHA, CIMGP_CHANNEL_A_SOURCE }, { }, + /* PictOpSrc */ + { CIMGP_ALPHA_TIMES_A, CIMGP_ALPHA_EQUALS_ONE, CIMGP_CHANNEL_A_SOURCE }, { }, + /* PictOpDst */ + { CIMGP_ALPHA_TIMES_A, CIMGP_ALPHA_EQUALS_ONE, CIMGP_CHANNEL_A_DEST }, { }, + /* PictOpOver*/ + { CIMGP_A_PLUS_BETA_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE }, { }, + /* PictOpOverReverse */ + { CIMGP_A_PLUS_BETA_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_DEST }, { }, + /* PictOpIn */ + { CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_SOURCE }, { }, + /* PictOpInReverse */ + { CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_DEST }, { }, + /* PictOpOut */ + { CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE }, { }, + /* PictOpOutReverse */ + { CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_DEST }, { }, + /* SrcAtop */ + { CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_DEST }, + { CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE }, + /* SrcAtopReverse */ + { CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_SOURCE }, + { CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_DEST }, + /* Xor */ + { CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE }, + { CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE }, + /* PictOpAdd */ + { CIMGP_A_PLUS_BETA_B, CIMGP_CONSTANT_ALPHA, CIMGP_CHANNEL_A_SOURCE }, { } +}; + + +#define ARRAY_SIZE(a) (sizeof((a)) / (sizeof(*(a)))) + +static const struct exa_format_t *lx_get_format(PicturePtr p) +{ + int i; + unsigned int format = p->format; + + for(i = 0; i < ARRAY_SIZE(lx_exa_formats); i++) { + + if (lx_exa_formats[i].bpp < PICT_FORMAT_BPP(format)) + break; + else if (lx_exa_formats[i].bpp != PICT_FORMAT_BPP(format)) + continue; + + if (lx_exa_formats[i].exa == format) + return (&lx_exa_formats[i]); + } + +#if 0 + ErrorF("Couldn't match on format %x\n", format); + ErrorF("BPP = %d, type = %d, ARGB(%d,%d,%d,%d)n", + PICT_FORMAT_BPP(format), + PICT_FORMAT_TYPE(format), + PICT_FORMAT_A(format), + PICT_FORMAT_R(format), + PICT_FORMAT_G(format), + PICT_FORMAT_B(format)); +#endif + + return NULL; +} + +static Bool lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, + PicturePtr pDst) +{ + GeodeRec *pGeode = GEODEPTR_FROM_PICTURE(pDst); + + /* Check that the operation is supported */ + + if (op > PictOpAdd) + return FALSE; + + if (usesPasses(op)) { + if (pGeode->exaBfrOffset == 0 || !pMsk) + return FALSE; + } + + /* Check that the filter matches what we support */ + + switch(pSrc->filter) { + case PictFilterNearest: + case PictFilterFast: + case PictFilterGood: + case PictFilterBest: + break; + + default: + ErrorF("invalid filter %d\n", pSrc->filter); + return FALSE; + } + + /* We don't handle transforms */ + + if (pSrc->transform) + return FALSE; + + + /* XXX - I don't understand PICT_a8 enough - so I'm punting */ + + if (pSrc->format == PICT_a8 || pDst->format == PICT_a8) + return FALSE; + + return TRUE; +} + +static Bool lx_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMsk, + PicturePtr pDst, PixmapPtr pxSrc, PixmapPtr pxMsk, + PixmapPtr pxDst) +{ + GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); + const struct exa_format_t *srcFmt, *dstFmt; + + /* Get the formats for the source and destination */ + + if ((srcFmt = lx_get_format(pSrc)) == NULL) { + ErrorF("EXA: Invalid source format %x\n", pSrc->format); + return FALSE; + } + + if ((dstFmt = lx_get_format(pDst)) == NULL) { + ErrorF("EXA: Invalid destination format %x\n", pDst->format); + return FALSE; + } + + /* Make sure operations that need alpha bits have them */ + /* If a mask is enabled, the alpha will come from there */ + + if (!pMsk && (!srcFmt->alphabits && usesSrcAlpha(op))) { + ErrorF("EXA: Source needs alpha bits\n"); + return FALSE; + } + + if (!pMsk && (!dstFmt->alphabits && usesDstAlpha(op))) { + ErrorF("EXA: Dest needs alpha bits\n"); + return FALSE; + } + + /* FIXME: See a way around this! */ + + if (srcFmt->alphabits == 0 && dstFmt->alphabits != 0) + return FALSE; + + /* Set up the scratch buffer with the information we need */ + + exaScratch.srcFormat = (struct exa_format_t *) srcFmt; + exaScratch.dstFormat = (struct exa_format_t *) dstFmt; + exaScratch.op = op; + exaScratch.repeat = pSrc->repeat; + exaScratch.bufferOffset = pGeode->exaBfrOffset; + + + if (pMsk && op != PictOpClear) { + unsigned int srcColor; + struct blend_ops_t *opPtr = &lx_alpha_ops[op * 2]; + int direction = (opPtr->channel == CIMGP_CHANNEL_A_SOURCE) ? 0 : 1; + + /* We can only do masks with a 8bpp or a 4bpp mask */ + + if (pMsk->format != PICT_a8 && pMsk->format != PICT_a4) + return FALSE; + + /* Direction 0 indicates src->dst, 1 indiates dst->src */ + + if (((direction == 0) && (pxSrc->drawable.bitsPerPixel < 16)) || + ((direction == 1) && (pxDst->drawable.bitsPerPixel < 16))) { + ErrorF("Can't do mask blending with less then 16bpp\n"); + return FALSE; + } + + /* FIXME: What to do here? */ + + if (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1) + return FALSE; + + /* Save off the info we need (reuse the source values to save space) */ + + exaScratch.type = COMP_TYPE_MASK; + + exaScratch.srcOffset = exaGetPixmapOffset(pxMsk); + exaScratch.srcPitch = exaGetPixmapPitch(pxMsk); + exaScratch.srcBpp = (pxMsk->drawable.bitsPerPixel + 7) / 8; + + exaScratch.srcWidth = pMsk->pDrawable->width; + exaScratch.srcHeight = pMsk->pDrawable->height; + + /* Flag to indicate if this a 8BPP or a 4BPP mask */ + exaScratch.fourBpp = (pxMsk->drawable.bitsPerPixel == 4) ? 1 : 0; + + /* If the direction is reversed, then remember the source */ + + if (direction == 1) + exaScratch.srcPixmap = pxSrc; + + /* Extract the source color to use */ + + if (direction == 0) + srcColor = lx_get_source_color(pSrc, 0, 0, pDst->format); + else + srcColor = lx_get_source_color(pDst, 0, 0, pSrc->format); + + /* Build part of the blt now to save time later */ + + gp_declare_blt (0); + gp_set_solid_source (srcColor); + gp_write_parameters(); + } + else { + if (usesPasses(op)) + exaScratch.type = COMP_TYPE_TWOPASS; + else + exaScratch.type = COMP_TYPE_ONEPASS; + + exaScratch.srcOffset = exaGetPixmapOffset(pxSrc); + exaScratch.srcPitch = exaGetPixmapPitch(pxSrc); + exaScratch.srcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8; + + exaScratch.srcWidth = pSrc->pDrawable->width; + exaScratch.srcHeight = pSrc->pDrawable->height; + } + + return TRUE; +} + +int lx_get_bpp_from_format(int format) { + + switch(format) { + case CIMGP_SOURCE_FMT_8_8_8_8: + case CIMGP_SOURCE_FMT_32BPP_BGR: + return 32; + + case CIMGP_SOURCE_FMT_4_4_4_4: + return 12; + + case CIMGP_SOURCE_FMT_0_5_6_5: + case CIMGP_SOURCE_FMT_16BPP_BGR: + return 16; + + case CIMGP_SOURCE_FMT_1_5_5_5: + case CIMGP_SOURCE_FMT_15BPP_BGR: + return 15; + + case CIMGP_SOURCE_FMT_3_3_2: + return 8; + } + + return 0; +} + +/* BGR needs to be set in the source for it to take - so adjust the source + * to enable BGR if the two formats are different, and disable it if they + * are the same + */ + +static void lx_set_source_format(int srcFormat, int dstFormat) +{ + if (!(srcFormat & 0x10) && (dstFormat & 0x10)) + gp_set_source_format(srcFormat | 0x10); + else if ((srcFormat & 0x10) && (dstFormat & 0x10)) + gp_set_source_format(srcFormat & ~0x10); + else + gp_set_source_format(srcFormat); +} + +/* If we are converting colors and we need the channel A alpha, + * then use a special alpha type that preserves the alpha before + * converting the format + */ + +static inline int get_op_type(struct exa_format_t *src, + struct exa_format_t *dst, int type) +{ + return (type == CIMGP_CHANNEL_A_ALPHA && + src->alphabits != dst->alphabits) ? + CIMGP_CONVERTED_ALPHA : type; +} + +/* Note - this is the preferred onepass method. The other will remain + * ifdefed out until such time that we are sure its not needed + */ + +#if 1 + +static void +lx_composite_onepass(PixmapPtr pxDst, unsigned long dstOffset, + unsigned long srcOffset, int width, int height) +{ + struct blend_ops_t *opPtr; + int apply, type; + + opPtr = &lx_alpha_ops[exaScratch.op * 2]; + + apply = (exaScratch.dstFormat->alphabits != 0 && + exaScratch.srcFormat->alphabits != 0) ? + CIMGP_APPLY_BLEND_TO_ALL : CIMGP_APPLY_BLEND_TO_RGB; + + gp_declare_blt(0); + gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt)); + gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch); + + lx_set_source_format(exaScratch.srcFormat->fmt, exaScratch.dstFormat->fmt); + + type = get_op_type(exaScratch.srcFormat, exaScratch.dstFormat, opPtr->type); + + gp_set_alpha_operation(opPtr->operation, type, + opPtr->channel, apply, 0); + + gp_screen_to_screen_convert(dstOffset, srcOffset, width, height, 0); +} + +#else + +/* XXX - For now, we assume that the conversion will fit */ + +static void +lx_composite_onepass(PixmapPtr pxDst, unsigned long dstOffset, + unsigned long srcOffset, int width, int height) +{ + struct blend_ops_t *opPtr; + int apply, type; + int sbpp = lx_get_bpp_from_format(exaScratch.srcFormat->fmt); + + /* Copy the destination into the scratch buffer */ + + gp_declare_blt(0); + + gp_set_bpp(sbpp); + + gp_set_source_format(exaScratch.dstFormat->fmt); + + gp_set_raster_operation(0xCC); + gp_set_strides(exaScratch.srcPitch, exaGetPixmapPitch(pxDst)); + gp_screen_to_screen_convert(exaScratch.bufferOffset, dstOffset, width, + height, 0); + + /* Do the blend */ + + opPtr = &lx_alpha_ops[exaScratch.op * 2]; + apply = (exaScratch.srcFormat->alphabits == 0) ? + CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL; + + gp_declare_blt (0); + gp_set_bpp(sbpp); + + type = get_op_type(exaScratch.srcFormat, exaScrach.dstFormat, opPtr->type); + + gp_set_alpha_operation(opPtr->operation, type, opPtr->channel, + apply, 0); + + gp_set_strides(exaScratch.srcPitch, exaScratch.srcPitch); + gp_screen_to_screen_blt(exaScratch.bufferOffset, srcOffset, + width, height, 0); + + /* And copy back */ + + gp_declare_blt(0); + gp_set_bpp(pxDst->drawable.bitsPerPixel); + gp_set_source_format (exaScratch.srcFormat->fmt); + gp_set_raster_operation(0xCC); + gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch); + gp_screen_to_screen_convert(dstOffset, exaScratch.bufferOffset, + width, height, 0); +} + +#endif + +#if 0 + +lx_composite_convert(PixmapPtr pxDst, unsigned long dstOffset, + unsigned long srcOffset, int width, int height) +{ + /* Step 1 - copy the destination into the scratch buffer */ + + ErrorF("Convert\n"); + + gp_declare_blt(0); + gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt)); + + gp_set_raster_operation(0xCC); + gp_set_strides(exaGetPixmapPitch(pxDst), exaGetPixmapPitch(pxDst)); + + gp_screen_to_screen_blt(exaScratch.bufferOffset, dstOffset, width, height, 0); + + /* Step 2 - Do the original blend */ + + lx_composite_onepass(pxDst, exaScratch.bufferOffset, srcOffset, width, height); + + /* Step 3 - copy back and fixup the alpha */ + gp_declare_blt(0); + gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt)); + gp_set_strides(exaGetPixmapPitch(pxDst), exaGetPixmapPitch(pxDst)); + + /* FIXME: Does this alpha value need to be changed for the mode? */ + + gp_set_alpha_operation(CIMGP_ALPHA_TIMES_A, CIMGP_CONSTANT_ALPHA, + CIMGP_CHANNEL_A_SOURCE, CIMGP_APPLY_BLEND_TO_ALPHA, + 1); + + gp_screen_to_screen_blt(dstOffset, exaScratch.bufferOffset, width, height, 0); +} + +#endif + +/* This function handles the multipass blend functions */ + +static void +lx_composite_multipass(PixmapPtr pxDst, unsigned long dstOffset, unsigned long srcOffset, int width, int height) +{ + struct blend_ops_t *opPtr; + int sbpp = lx_get_bpp_from_format(exaScratch.srcFormat->fmt); + int apply, type; + + /* Wait until the GP is idle - this will ensure that the scratch buffer + * isn't occupied */ + + gp_wait_until_idle(); + + /* Copy the destination to the scratch buffer, and convert it to the + * source format */ + + gp_declare_blt(0); + + gp_set_bpp(sbpp); + gp_set_source_format(exaScratch.dstFormat->fmt); + gp_set_raster_operation(0xCC); + gp_set_strides(exaScratch.srcPitch, exaGetPixmapPitch(pxDst)); + gp_screen_to_screen_convert(exaScratch.bufferOffset, dstOffset, + width, height, 0); + + /* Do the first blend from the source to the scratch buffer */ + + gp_declare_blt(CIMGP_BLTFLAGS_HAZARD); + gp_set_bpp(sbpp); + gp_set_source_format(exaScratch.srcFormat->fmt); + gp_set_strides(exaScratch.srcPitch, exaScratch.srcPitch); + + opPtr = &lx_alpha_ops[exaScratch.op * 2]; + + apply = (exaScratch.srcFormat->alphabits == 0) ? + CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL; + + /* If we're destroying the source alpha bits, then make sure we + * use the alpha before the color conversion + */ + + gp_screen_to_screen_blt(exaScratch.bufferOffset, srcOffset, width, height, 0); + + /* Finally, do the second blend back to the destination */ + + opPtr = &lx_alpha_ops[(exaScratch.op * 2) + 1]; + + apply = (exaScratch.dstFormat->alphabits == 0) ? + CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL; + + gp_declare_blt(CIMGP_BLTFLAGS_HAZARD); + gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt)); + + lx_set_source_format(exaScratch.srcFormat->fmt, exaScratch.dstFormat->fmt); + + type = get_op_type(exaScratch.srcFormat, exaScratch.dstFormat, opPtr->type); + + gp_set_alpha_operation(opPtr->operation, type, opPtr->channel, + apply, 0); + + gp_screen_to_screen_convert(dstOffset, exaScratch.bufferOffset, + width, height, 0); +} + +static void +lx_do_composite_mask(PixmapPtr pxDst, unsigned long dstOffset, + unsigned int maskOffset, int width, int height) +{ + GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); + unsigned char *data = pGeode->FBBase + maskOffset; + + struct blend_ops_t *opPtr = &lx_alpha_ops[exaScratch.op * 2]; + + gp_declare_blt (0); + gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt)); + + gp_blend_mask_blt(dstOffset, 0, width, height, data, + exaScratch.srcPitch, opPtr->operation, + exaScratch.fourBpp); +} + +#define GetPixmapOffset(px, x, y) ( exaGetPixmapOffset((px)) + \ + (exaGetPixmapPitch((px)) * (y)) + \ + ((((px)->drawable.bitsPerPixel + 7) / 8) * (x)) ) + +static void +lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, + int maskY, int dstX, int dstY, int width, int height) { + + struct blend_ops_t *opPtr = &lx_alpha_ops[exaScratch.op * 2]; + + unsigned int dstOffset, srcOffset; + + unsigned int opX = dstX; + unsigned int opY = dstY; + unsigned int opWidth = width; + unsigned int opHeight = height; + + if (exaScratch.type == COMP_TYPE_MASK) + srcOffset = exaScratch.srcOffset + (maskY * exaScratch.srcPitch) + + (maskX * exaScratch.srcBpp); + else + srcOffset = exaScratch.srcOffset + (srcY * exaScratch.srcPitch) + + (srcX * exaScratch.srcBpp); + + /* Adjust the width / height of the operation the size of the source */ + + if (exaScratch.srcWidth < width) + opWidth = exaScratch.srcWidth; + + if (exaScratch.srcHeight < height) + opHeight = exaScratch.srcHeight; + + while(1) { + dstOffset = GetPixmapOffset(pxDst, opX, opY); + + switch(exaScratch.type) { + case COMP_TYPE_MASK: { + int direction = (opPtr->channel == CIMGP_CHANNEL_A_SOURCE) ? 0 : 1; + + if (direction == 1) { + dstOffset = GetPixmapOffset(exaScratch.srcPixmap, dstX,dstY); + lx_do_composite_mask(exaScratch.srcPixmap, dstOffset, srcOffset, + opWidth, opHeight); + } + else { + lx_do_composite_mask(pxDst, dstOffset, srcOffset, opWidth, opHeight); + } + } + break; + + case COMP_TYPE_ONEPASS: + lx_composite_onepass(pxDst, dstOffset, srcOffset, opWidth, opHeight); + break; + + case COMP_TYPE_TWOPASS: + lx_composite_multipass(pxDst, dstOffset, srcOffset, opWidth, opHeight); + break; + } + + if (!exaScratch.repeat) + break; + + opX += opWidth; + + if (opX >= dstX + width) { + opX = dstX; + opY += opHeight; + + if (opY >= dstY + height) + break; + } + + opWidth = ((dstX + width) - opX) > exaScratch.srcWidth ? + exaScratch.srcWidth : (dstX + width) - opX; + opHeight = ((dstY + height) - opY) > exaScratch.srcHeight ? + exaScratch.srcHeight : (dstY + height) - opY; + } +} + +static void lx_wait_marker(ScreenPtr PScreen, int marker) +{ + gp_wait_until_idle(); +} + +static void lx_done(PixmapPtr ptr) +{ +} + +static Bool lx_upload(PixmapPtr pDst, int x, int y, int w, int h, + char *src, int src_pitch) +{ + char *dst = pDst->devPrivate.ptr; + int dpitch = exaGetPixmapPitch(pDst); + int bpp = pDst->drawable.bitsPerPixel; + GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pDst); + unsigned long offset; + + dst += (y * dpitch) + (x * (bpp >> 3)); + + gp_declare_blt(0); + + gp_set_bpp(bpp); + gp_set_raster_operation(0xCC); + gp_set_strides(dpitch, src_pitch); + gp_set_solid_pattern(0); + + offset = ((unsigned long) dst) - ((unsigned long) pGeode->FBBase); + gp_color_bitmap_to_screen_blt(offset, 0, w, h, src, src_pitch); + return TRUE; +} + +static Bool lx_download(PixmapPtr pSrc, int x, int y, int w, int h, + char *dst, int dst_pitch) +{ + char *src = pSrc->devPrivate.ptr; + int spitch = exaGetPixmapPitch(pSrc); + int bpp = pSrc->drawable.bitsPerPixel; + + src += (y * spitch) + (x * (bpp >> 3)); + + geode_memory_to_screen_blt((unsigned long)src, (unsigned long)dst, + spitch, dst_pitch, w, h, bpp); + return TRUE; +} + + +Bool LXExaInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + ExaDriverPtr pExa = pGeode->pExa; + + pExa->exa_major = EXA_VERSION_MAJOR; + pExa->exa_minor = EXA_VERSION_MINOR; + + pExa->WaitMarker = lx_wait_marker; + + pExa->UploadToScreen = lx_upload; + pExa->DownloadFromScreen = lx_download; + + pExa->PrepareSolid = lx_prepare_solid; + pExa->Solid = lx_do_solid; + pExa->DoneSolid = lx_done; + + pExa->PrepareCopy = lx_prepare_copy; + pExa->Copy = lx_do_copy; + pExa->DoneCopy = lx_done; + + /* Composite */ + pExa->CheckComposite = lx_check_composite; + pExa->PrepareComposite = lx_prepare_composite; + pExa->Composite = lx_do_composite; + pExa->DoneComposite = lx_done; + + return exaDriverInit(pScreen, pGeode->pExa); +} diff --git a/src/amd_lx_randr.c b/src/amd_lx_randr.c new file mode 100644 index 0000000..e46ae20 --- /dev/null +++ b/src/amd_lx_randr.c @@ -0,0 +1,331 @@ +/* Originally derived from the Intel example + * Copyright (C) 2002 Keith Packard, member of The XFree86 Project, Inc. + + * Copyright (c) 2006 Advanced Micro Devices, Inc. + * + * 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, + * 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. + * + * Neither the name of the Advanced Micro Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + */ + +#include "xf86.h" +#include "os.h" +#include "mibank.h" +#include "globals.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86DDC.h" +#include "mipointer.h" +#include "windowstr.h" +#include <X11/extensions/randr.h> +#include <randrstr.h> + +#include "amd.h" + +static int LXRandRIndex; +static int LXRandRGeneration; + +typedef struct _LXRandRInfo +{ + int virtualX; + int virtualY; + int mmWidth; + int mmHeight; + int maxX; + int maxY; + Rotation rotation; /* current mode */ + Rotation supported_rotations; /* driver supported */ +} XF86RandRInfoRec, *XF86RandRInfoPtr; + +#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) (p)->devPrivates[LXRandRIndex].ptr) + +static int +LXRandRModeRefresh(DisplayModePtr mode) +{ + if (mode->VRefresh) + return (int)(mode->VRefresh + 0.5); + else + return (int)(mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + + 0.5); +} + +static Bool +LXRandRGetInfo(ScreenPtr pScreen, Rotation * rotations) +{ + RRScreenSizePtr pSize; + ScrnInfoPtr pScrni = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr pRandr = XF86RANDRINFO(pScreen); + DisplayModePtr mode; + int refresh0 = 60; + int maxX = 0, maxY = 0; + + *rotations = pRandr->supported_rotations; + + if (pRandr->virtualX == -1 || pRandr->virtualY == -1) { + pRandr->virtualX = pScrni->virtualX; + pRandr->virtualY = pScrni->virtualY; + } + + for (mode = pScrni->modes;; mode = mode->next) { + int refresh = LXRandRModeRefresh(mode); + + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + if (maxX < mode->HDisplay) + maxX = mode->HDisplay; + if (maxY < mode->VDisplay) + maxY = mode->VDisplay; + } + + if (mode == pScrni->modes) + refresh0 = refresh; + + pSize = RRRegisterSize(pScreen, + mode->HDisplay, mode->VDisplay, + pRandr->mmWidth, pRandr->mmHeight); + if (!pSize) + return FALSE; + + RRRegisterRate(pScreen, pSize, refresh); + + if (mode == pScrni->currentMode && + mode->HDisplay == pScrni->virtualX + && mode->VDisplay == pScrni->virtualY) + RRSetCurrentConfig(pScreen, pRandr->rotation, refresh, pSize); + if (mode->next == pScrni->modes) + break; + } + + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + pRandr->maxX = maxX; + pRandr->maxY = maxY; + } + + if (pScrni->currentMode->HDisplay != pScrni->virtualX || + pScrni->currentMode->VDisplay != pScrni->virtualY) { + + mode = pScrni->modes; + pSize = RRRegisterSize(pScreen, + pRandr->virtualX, pRandr->virtualY, + pRandr->mmWidth, pRandr->mmHeight); + if (!pSize) + return FALSE; + + RRRegisterRate(pScreen, pSize, refresh0); + if (pScrni->virtualX == pRandr->virtualX && + pScrni->virtualY == pRandr->virtualY) { + RRSetCurrentConfig(pScreen, pRandr->rotation, refresh0, pSize); + } + } + + return TRUE; +} + +static Bool +LXRandRSetMode(ScreenPtr pScreen, + DisplayModePtr mode, Bool useVirtual, int mmWidth, int mmHeight) +{ + ScrnInfoPtr pScrni = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr pRandr = XF86RANDRINFO(pScreen); + + int oldWidth = pScreen->width; + int oldHeight = pScreen->height; + int oldmmWidth = pScreen->mmWidth; + int oldmmHeight = pScreen->mmHeight; + WindowPtr pRoot = WindowTable[pScreen->myNum]; + DisplayModePtr currentMode = NULL; + Bool ret = TRUE; + PixmapPtr pspix = NULL; + + if (pRoot) + (*pScrni->EnableDisableFBAccess) (pScreen->myNum, FALSE); + + if (useVirtual) { + pScrni->virtualX = pRandr->virtualX; + pScrni->virtualY = pRandr->virtualY; + } else { + pScrni->virtualX = mode->HDisplay; + pScrni->virtualY = mode->VDisplay; + } + + if (pRandr->rotation & (RR_Rotate_90 | RR_Rotate_270)) { + pScreen->width = pScrni->virtualY; + pScreen->height = pScrni->virtualX; + pScreen->mmWidth = mmHeight; + pScreen->mmHeight = mmWidth; + } else { + pScreen->width = pScrni->virtualX; + pScreen->height = pScrni->virtualY; + pScreen->mmWidth = mmWidth; + pScreen->mmHeight = mmHeight; + } + + if (pScrni->currentMode == mode) { + currentMode = pScrni->currentMode; + pScrni->currentMode = NULL; + } + + if (!xf86SwitchMode(pScreen, mode)) { + ret = FALSE; + pScrni->virtualX = pScreen->width = oldWidth; + pScrni->virtualY = pScreen->height = oldHeight; + pScreen->mmWidth = oldmmWidth; + pScreen->mmHeight = oldmmHeight; + pScrni->currentMode = currentMode; + } + + /* + * Get the new Screen pixmap ptr as SwitchMode might have called + * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back... + * Unfortunately. + + */ + + pspix = (*pScreen->GetScreenPixmap) (pScreen); + if (pspix->devPrivate.ptr) + pScrni->pixmapPrivate = pspix->devPrivate; + + xf86ReconfigureLayout(); + + xf86SetViewport(pScreen, pScreen->width, pScreen->height); + xf86SetViewport(pScreen, 0, 0); + + if (pRoot) + (*pScrni->EnableDisableFBAccess) (pScreen->myNum, TRUE); + + return ret; +} + +Bool +LXRandRSetConfig(ScreenPtr pScreen, Rotation rotation, + int rate, RRScreenSizePtr pSize) +{ + ScrnInfoPtr pScrni = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr pRandr = XF86RANDRINFO(pScreen); + + DisplayModePtr mode; + int px, py; + Bool useVirtual = FALSE; + int maxX = 0, maxY = 0; + Rotation oldRotation = pRandr->rotation; + + pRandr->rotation = rotation; + + if (pRandr->virtualX == -1 || pRandr->virtualY == -1) { + pRandr->virtualX = pScrni->virtualX; + pRandr->virtualY = pScrni->virtualY; + } + + miPointerPosition(&px, &py); + + for (mode = pScrni->modes;; mode = mode->next) { + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + if (maxX < mode->HDisplay) + maxX = mode->HDisplay; + if (maxY < mode->VDisplay) + maxY = mode->VDisplay; + } + if (mode->HDisplay == pSize->width && + mode->VDisplay == pSize->height && + (rate == 0 || LXRandRModeRefresh(mode) == rate)) + break; + if (mode->next == pScrni->modes) { + if (pSize->width == pRandr->virtualX && + pSize->height == pRandr->virtualY) { + mode = pScrni->modes; + useVirtual = TRUE; + break; + } + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + pRandr->maxX = maxX; + pRandr->maxY = maxY; + } + return FALSE; + } + } + + if (pRandr->maxX == 0 || pRandr->maxY == 0) { + pRandr->maxX = maxX; + pRandr->maxY = maxY; + } + + if (!LXRandRSetMode(pScreen, mode, useVirtual, pSize->mmWidth, + pSize->mmHeight)) { + pRandr->rotation = oldRotation; + return FALSE; + } + + if (pScreen == miPointerCurrentScreen()) { + px = (px >= pScreen->width ? (pScreen->width - 1) : px); + py = (py >= pScreen->height ? (pScreen->height - 1) : py); + + xf86SetViewport(pScreen, px, py); + + (*pScreen->SetCursorPosition) (pScreen, px, py, FALSE); + } + + return TRUE; +} + +Rotation +LXGetRotation(ScreenPtr pScreen) +{ + XF86RandRInfoPtr pRandr = XF86RANDRINFO(pScreen); + + return pRandr ? pRandr->rotation : RR_Rotate_0; +} + +Bool +LXRandRInit(ScreenPtr pScreen, int rotation) +{ + XF86RandRInfoPtr pRandr; + rrScrPrivPtr rp; + + if (LXRandRGeneration != serverGeneration) { + LXRandRIndex = AllocateScreenPrivateIndex(); + LXRandRGeneration = serverGeneration; + } + + pRandr = xcalloc(sizeof(XF86RandRInfoRec), 1); + if (pRandr == NULL) + return FALSE; + + if (!RRScreenInit(pScreen)) { + xfree(pRandr); + return FALSE; + } + + rp = rrGetScrPriv(pScreen); + rp->rrGetInfo = LXRandRGetInfo; + rp->rrSetConfig = LXRandRSetConfig; + + pRandr->virtualX = -1; + pRandr->virtualY = -1; + + pRandr->mmWidth = pScreen->mmWidth; + pRandr->mmHeight = pScreen->mmHeight; + + pRandr->rotation = RR_Rotate_0; + pRandr->supported_rotations = rotation; + pRandr->maxX = pRandr->maxY = 0; + + pScreen->devPrivates[LXRandRIndex].ptr = pRandr; + return TRUE; +} diff --git a/src/amd_lx_rotate.c b/src/amd_lx_rotate.c new file mode 100644 index 0000000..cb28ec4 --- /dev/null +++ b/src/amd_lx_rotate.c @@ -0,0 +1,244 @@ +/* Copyrightg (c) 2007 Advanced Micro Devices, Inc. + * + * 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, + * 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. + * + * Neither the name of the Advanced Micro Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "shadow.h" +#include "amd.h" + +static void * +LXWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, + CARD32 * size, void *closure) +{ + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + + *size = pGeode->displayPitch; + + return (pGeode->FBBase + pGeode->displayOffset) + + row * pGeode->displayPitch + offset; +} + +void +LXUpdateFunc(ScreenPtr pScreen, shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage (pBuf); + + int nbox = REGION_NUM_RECTS (damage); + BoxPtr pbox = REGION_RECTS (damage); + int x, y, w, h, degrees; + FbStride shaStride; + FbBits *shaBits; + int shaBpp, dx, dy,dw, dh; + int shaXoff, shaYoff; + unsigned int srcOffset, dstOffset; + PixmapPtr pShadow = pBuf->pPixmap; + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + + fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, + shaYoff); + + /* Set up the blt */ + + gp_wait_until_idle(); + gp_declare_blt(0); + + gp_set_bpp(pScrni->bitsPerPixel); + + switch(shaBpp) { + case 8: + gp_set_source_format(CIMGP_SOURCE_FMT_3_3_2); + break; + + case 16: + gp_set_source_format(CIMGP_SOURCE_FMT_0_5_6_5); + break; + + case 24: + case 32: + gp_set_source_format(CIMGP_SOURCE_FMT_8_8_8_8); + break; + } + + gp_set_raster_operation(0xCC); + gp_write_parameters(); + + while(nbox--) { + x = pbox->x1; + y = pbox->y1; + w = (pbox->x2 - pbox->x1); + h = pbox->y2 - pbox->y1; + + srcOffset = ((unsigned long) shaBits) - ((unsigned long) pGeode->FBBase); + srcOffset += (y * pGeode->Pitch) + (x * (shaBpp >> 3)); + + switch(pGeode->rotation) { + case RR_Rotate_0: + dx = x; + dy = y; + dw = w; + dh = h; + degrees = 0; + break; + + case RR_Rotate_90: + dx = (pScrni->pScreen->height - 1) - (y + (h-1)); + dy = x; + dw = h; + dh = w; + degrees = 90; + break; + + case RR_Rotate_180: + dx = (pScrni->pScreen->width - 1) - (x + (w-1)); + dy = (pScrni->pScreen->height - 1) - (y + (h-1)); + dw = w; + dh = h; + + degrees = 180; + break; + + case RR_Rotate_270: + dy = (pScrni->pScreen->width - 1) - (x + (w-1)); + dx = y; + dw = h; + dh = w; + + degrees = 270; + break; + } + + dstOffset = pGeode->displayOffset + + (dy * pGeode->displayPitch) + (dx * (pScrni->bitsPerPixel >> 3)); + + gp_declare_blt(CIMGP_BLTFLAGS_HAZARD); + gp_set_strides(pGeode->displayPitch, pGeode->Pitch); + gp_rotate_blt(dstOffset, srcOffset, w, h, degrees); + pbox++; + } +} + +Bool LXSetRotatePitch(ScrnInfoPtr pScrni) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + + pScrni->displayWidth = pGeode->displayWidth; + + if (pGeode->Compression) + pGeode->Pitch = GeodeCalculatePitchBytes(pScrni->displayWidth, + pScrni->bitsPerPixel); + else + pGeode->Pitch = (pScrni->displayWidth * + (pScrni->bitsPerPixel >> 3)); + return TRUE; +} + +Bool +LXRotate(ScrnInfoPtr pScrni, DisplayModePtr mode) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + Rotation curr = pGeode->rotation; + unsigned int curdw = pScrni->displayWidth; + PixmapPtr pPixmap; + BOOL ret; + + pPixmap = pScrni->pScreen->GetScreenPixmap(pScrni->pScreen); + pGeode->rotation = LXGetRotation(pScrni->pScreen); + + /* Leave if we have nothing to do */ + + if (pGeode->rotation == curr && pGeode->curMode == mode) { + return TRUE; + } + + shadowRemove(pScrni->pScreen, NULL); + + LXSetRotatePitch(pScrni); + + if (pGeode->rotation != RR_Rotate_0) { + + + ret = shadowAdd(pScrni->pScreen, pPixmap, LXUpdateFunc, + LXWindowLinear, pGeode->rotation, NULL); + + /* XXX - FIXME - bail gracefully */ + + if (!ret) + ErrorF("shadowAdd failed\n"); + } + + if (pGeode->rotation == RR_Rotate_0) + pScrni->fbOffset = pGeode->displayOffset; + else + pScrni->fbOffset = pGeode->shadowOffset; + + vg_set_display_offset(pScrni->fbOffset); + + pScrni->pScreen->ModifyPixmapHeader(pPixmap, + pScrni->pScreen->width, + pScrni->pScreen->height, + pScrni->pScreen->rootDepth, + pScrni->bitsPerPixel, + PixmapBytePad(pScrni->displayWidth, pScrni->pScreen->rootDepth), + (pointer) (pGeode->FBBase + pScrni->fbOffset)); + + /* Don't use XAA pixmap cache or offscreen pixmaps when rotated */ + + if (pGeode->AccelInfoRec) { + if (pGeode->rotation == RR_Rotate_0) { + pGeode->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE; + pGeode->AccelInfoRec->UsingPixmapCache = TRUE; + pGeode->AccelInfoRec->maxOffPixWidth = 0; + pGeode->AccelInfoRec->maxOffPixHeight = 0; + } + else { + pGeode->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER; + pGeode->AccelInfoRec->UsingPixmapCache = FALSE; + pGeode->AccelInfoRec->maxOffPixWidth = 1; + pGeode->AccelInfoRec->maxOffPixHeight = 1; + } + } + + return TRUE; + +error: + /* Restore the old rotation */ + pScrni->displayWidth = curdw; + + if (curr & (RR_Rotate_0 | RR_Rotate_180)) { + pScrni->pScreen->width = pScrni->virtualX; + pScrni->pScreen->height = pScrni->virtualY; + } else { + pScrni->pScreen->width = pScrni->virtualY; + pScrni->pScreen->height = pScrni->virtualX; + } + + pGeode->rotation = curr; + return FALSE; +} diff --git a/src/amd_lx_shadow.c b/src/amd_lx_shadow.c deleted file mode 100644 index 8440c4e..0000000 --- a/src/amd_lx_shadow.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. - * - * 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, - * 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. - * - * Neither the name of the Advanced Micro Devices, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - */ - -/* - * File Contents: Direct graphics display routines are implemented and - * graphics rendering are all done in memory. - * - * Project: Geode Xfree Frame buffer device driver. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86.h" -#include "xf86_OSproc.h" -#include "xf86Resources.h" -#include "xf86_ansic.h" -#include "xf86PciInfo.h" -#include "xf86Pci.h" -#include "amd.h" -#include "shadowfb.h" -#include "servermd.h" - -#define CLIP(sip,bp,u1,v1,u2,v2) \ - u1 = bp->x1; v1 = bp->y1; \ - u2 = bp->x2; v2 = bp->y2; \ - if( u1 < 0 ) u1 = 0; \ - if( v1 < 0 ) v1 = 0; \ - if( u1 > sip->virtualX ) u1 = sip->virtualX; \ - if( v1 > sip->virtualY ) v1 = sip->virtualY; \ - if( u2 < 0 ) u2 = 0; \ - if( v2 < 0 ) v2 = 0; \ - if( u2 > sip->virtualX ) u2 = sip->virtualX; \ - if( v2 > sip->virtualY ) v2 = sip->virtualY; - -void LXAccelSync(ScrnInfoPtr pScrni); - -void -LXRotation0(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = x; - *newY = y; -} - -void -LXRotation1(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = (h - 1) - y; - *newY = x; -} - -void -LXRotation2(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = (w - 1) - x; - *newY = (h - 1) - y; -} - -void -LXRotation3(int x, int y, int w, int h, int *newX, int *newY) -{ - *newY = (w - 1) - x; - *newX = y; -} - -void -LXRBltXlat0(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = x; - *newY = y; -} - -void -LXRBltXlat1(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = x - (h - 1); - *newY = y; -} - -void -LXRBltXlat2(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = x - (w - 1); - *newY = y - (h - 1); -} - -void -LXRBltXlat3(int x, int y, int w, int h, int *newX, int *newY) -{ - *newX = x; - *newY = y - (w - 1); -} - -/*---------------------------------------------------------------------------- - * LXPointerMoved. - * - * Description :This function moves one screen memory from one area to other. - * - * Parameters. - * index :Pointer to screen index. - * x :Specifies the new x co-ordinates of new area. - * y :Specifies the new y co-ordinates of new area. - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -void -LXPointerMoved(int index, int x, int y) -{ - ScrnInfoPtr pScrni = xf86Screens[index]; - GeodeRec *pGeode = GEODEPTR(pScrni); - Bool frameChanged = FALSE; - - if (x < 0) - x = 0; - else if (x >= pScrni->virtualX) - x = pScrni->virtualX - 1; - - if (y < 0) - y = 0; - else if (y >= pScrni->virtualY) - y = pScrni->virtualY - 1; - - if (pScrni->frameX0 > x) { - pScrni->frameX0 = x; - pScrni->frameX1 = x + pGeode->HDisplay - 1; - frameChanged = TRUE; - } - - if (pScrni->frameX1 < x) { - pScrni->frameX1 = x + 1; - pScrni->frameX0 = x - pGeode->HDisplay + 1; - frameChanged = TRUE; - } - - if (pScrni->frameY0 > y) { - pScrni->frameY0 = y; - pScrni->frameY1 = y + pGeode->VDisplay - 1; - frameChanged = TRUE; - } - - if (pScrni->frameY1 < y) { - pScrni->frameY1 = y; - pScrni->frameY0 = y - pGeode->VDisplay + 1; - frameChanged = TRUE; - } - - if (frameChanged && pScrni->AdjustFrame != NULL) - pScrni->AdjustFrame(pScrni->scrnIndex, pScrni->frameX0, - pScrni->frameY0, 0); -} - -void -LXRefreshArea_Cpy(ScrnInfoPtr pScrni, int num, BoxPtr pbox) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - int x1, y1, x2, y2, width, height; - unsigned long src, dst; - int Bpp = pScrni->bitsPerPixel >> 3; - - gp_declare_blt(0); - gp_set_raster_operation(0xcc); /* copy dst=src */ - gp_write_parameters(); - for (; --num >= 0; ++pbox) { - CLIP(pScrni, pbox, x1, y1, x2, y2); - if ((width = x2 - x1) <= 0 || (height = y2 - y1) <= 0) - continue; - src = y1 * pGeode->ShadowPitch + x1 * Bpp; - dst = pGeode->FBOffset + y1 * pGeode->Pitch + x1 * Bpp; - gp_declare_blt(0); - gp_set_strides(pGeode->Pitch, pGeode->ShadowPitch); - gp_screen_to_screen_blt(dst, src, width, height, 0); - } -} - -/*---------------------------------------------------------------------------- - * LXRefreshArea8. - * - * Description :This function copies the memory to be displayed from the - * shadow pointer by 8bpp. - * Parameters. - * pScrni :Pointer to ScrnInfo structure. - * num :Specifies the num of squarebox area to be displayed. - * pbox :Points to square of memory to be displayed. - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ - -static int lx_shdw_fmt[4] = { - CIMGP_SOURCE_FMT_3_3_2, - CIMGP_SOURCE_FMT_0_5_6_5, - CIMGP_SOURCE_FMT_24BPP, - CIMGP_SOURCE_FMT_8_8_8_8 -}; - -void -LXRefreshArea_Blt(ScrnInfoPtr pScrni, int num, BoxPtr pbox) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - int width, height, x1, y1, x2, y2, newX, newY; - unsigned long src, dst; - int Bpp = pScrni->bitsPerPixel >> 3; - - gp_set_source_format(lx_shdw_fmt[Bpp - 1]); - gp_declare_blt(0); - gp_set_raster_operation(0xcc); /* copy dst=src */ - gp_write_parameters(); - for (; --num >= 0; ++pbox) { - CLIP(pScrni, pbox, x1, y1, x2, y2); - if ((width = x2 - x1) <= 0 || (height = y2 - y1) <= 0) - continue; - (*pGeode->Rotation) (x1, y1, pScrni->virtualX, pScrni->virtualY, - &newX, &newY); - (*pGeode->RBltXlat) (newX, newY, width, height, &newX, &newY); - src = y1 * pGeode->ShadowPitch + x1 * Bpp; - dst = pGeode->FBOffset + newY * pGeode->Pitch + newX * Bpp; - gp_declare_blt(0); - gp_set_strides(pGeode->Pitch, pGeode->ShadowPitch); - gp_rotate_blt(dst, src, width, height, pGeode->Rotate * 90); - } -} - -void -LXRefreshArea0_Cpu(ScrnInfoPtr pScrni, int num, BoxPtr pbox) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - int width, height, x1, y1, x2, y2; - unsigned char *src, *dst; - int Bpp = pScrni->bitsPerPixel >> 3; - - LXAccelSync(pScrni); - for (; --num >= 0; ++pbox) { - CLIP(pScrni, pbox, x1, y1, x2, y2); - if ((width = x2 - x1) <= 0 || (height = y2 - y1) <= 0) - continue; - src = pGeode->ShadowPtr + y1 * pGeode->ShadowPitch + x1 * Bpp; - dst = pGeode->FBBase + pGeode->FBOffset + y1 * pGeode->Pitch + x1 * - Bpp; - width *= Bpp; - while (--height >= 0) { - memcpy(dst, src, width); - dst += pGeode->Pitch; - src += pGeode->ShadowPitch; - } - } -} - -#define RefreshArea1_Cpu(nm,typ) \ -void LXRefreshArea1_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox) \ -{ \ - GeodeRec *pGeode = GEODEPTR(pScrni); \ - int l, width, height, x1, y1, x2, y2, newX, newY; \ - unsigned long src, dst, dp; \ - typ *sp; \ - LXAccelSync(pScrni); \ - for (; --num>=0; ++pbox) { \ - CLIP(pScrni,pbox,x1,y1,x2,y2); \ - if ((width=x2-x1) <=0 || (height=y2-y1) <= 0) continue; \ - src = y1*pGeode->ShadowPitch + x1*sizeof(typ); \ - newX = pScrni->virtualY-1 - y1; \ - newY = x1; \ - dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \ - while (--height >= 0) { \ - sp = (typ *)(pGeode->ShadowPtr + src); \ - dp = (unsigned long)(pGeode->FBBase + dst); \ - for (l=width; --l>=0;) { \ - *(typ *)dp = *sp++; \ - dp += pGeode->Pitch; \ - } \ - dst -= sizeof(typ); \ - src += pGeode->ShadowPitch; \ - } \ - } \ -} - -RefreshArea1_Cpu(8, unsigned char) -RefreshArea1_Cpu(16, unsigned short) -RefreshArea1_Cpu(32, unsigned int) -#define RefreshArea2_Cpu(nm,typ) \ -void LXRefreshArea2_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox) \ -{ \ - GeodeRec *pGeode = GEODEPTR(pScrni); \ - int l, width, height, x1, y1, x2, y2, newX, newY; \ - unsigned long src, dst, dp; \ - typ *sp; \ - LXAccelSync(pScrni); \ - for (; --num>=0; ++pbox) { \ - CLIP(pScrni,pbox,x1,y1,x2,y2); \ - if ((width=x2-x1) <=0 || (height=y2-y1) <= 0) continue; \ - src = y1*pGeode->ShadowPitch + x1*sizeof(typ); \ - newX = pScrni->virtualX-1 - x1; \ - newY = pScrni->virtualY-1 - y1; \ - dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \ - while (--height >= 0) { \ - sp = (typ *)(pGeode->ShadowPtr + src); \ - dp = (unsigned long)(pGeode->FBBase + dst); \ - for( l=width; --l>=0; ) { \ - *(typ *)dp = *sp++; \ - dp -= sizeof(typ); \ - } \ - src += pGeode->ShadowPitch; \ - dst -= pGeode->Pitch; \ - } \ - } \ -} -RefreshArea2_Cpu(8, unsigned char) -RefreshArea2_Cpu(16, unsigned short) -RefreshArea2_Cpu(32, unsigned int) -#define RefreshArea3_Cpu(nm,typ) \ -void LXRefreshArea3_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox) \ -{ \ - GeodeRec *pGeode = GEODEPTR(pScrni); \ - int l, width, height, x1, y1, x2, y2, newX, newY; \ - unsigned long src, dst, dp; \ - typ *sp; \ - LXAccelSync(pScrni); \ - for (; --num>=0; ++pbox) { \ - CLIP(pScrni,pbox,x1,y1,x2,y2); \ - if ((width=x2-x1) <=0 || (height=y2-y1) <= 0) continue; \ - src = y1*pGeode->ShadowPitch + x1*sizeof(typ); \ - newX = y1; \ - newY = pScrni->virtualX-1 - x1; \ - dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \ - while (--height >= 0) { \ - sp = (typ *)(pGeode->ShadowPtr + src); \ - dp = (unsigned long)(pGeode->FBBase + dst); \ - for( l=width; --l>=0; ) { \ - *(typ *)dp = *sp++; \ - dp -= pGeode->Pitch; \ - } \ - dst += sizeof(typ); \ - src += pGeode->ShadowPitch; \ - } \ - } \ -} -RefreshArea3_Cpu(8, unsigned char) -RefreshArea3_Cpu(16, unsigned short) -RefreshArea3_Cpu(32, unsigned int) - - void LXRotationInit(ScrnInfoPtr pScrni) -{ - GeodeRec *pGeode = GEODEPTR(pScrni); - - switch (pGeode->Rotate) { - case 1: - pGeode->Rotation = LXRotation1; - pGeode->RBltXlat = LXRBltXlat1; - break; - case 2: - pGeode->Rotation = LXRotation2; - pGeode->RBltXlat = LXRBltXlat2; - break; - case 3: - pGeode->Rotation = LXRotation3; - pGeode->RBltXlat = LXRBltXlat3; - break; - default: - pGeode->Rotation = LXRotation0; - pGeode->RBltXlat = LXRBltXlat0; - break; - } -} - -void -LXShadowFBInit(ScreenPtr pScrn, GeodeRec *pGeode, int bytpp) -{ - RefreshAreaFuncPtr refreshArea; - - if (pGeode->NoAccel || !pGeode->ShadowInFBMem || 0) { - switch (bytpp) { - case 2: - switch (pGeode->Rotate) { - case 1: - refreshArea = LXRefreshArea1_Cpu16; - break; - case 2: - refreshArea = LXRefreshArea2_Cpu16; - break; - case 3: - refreshArea = LXRefreshArea3_Cpu16; - break; - default: - refreshArea = LXRefreshArea0_Cpu; - break; - } - break; - case 4: - switch (pGeode->Rotate) { - case 1: - refreshArea = LXRefreshArea1_Cpu32; - break; - case 2: - refreshArea = LXRefreshArea2_Cpu32; - break; - case 3: - refreshArea = LXRefreshArea3_Cpu32; - break; - default: - refreshArea = LXRefreshArea0_Cpu; - break; - } - break; - default: - switch (pGeode->Rotate) { - case 1: - refreshArea = LXRefreshArea1_Cpu8; - break; - case 2: - refreshArea = LXRefreshArea2_Cpu8; - break; - case 3: - refreshArea = LXRefreshArea3_Cpu8; - break; - default: - refreshArea = LXRefreshArea0_Cpu; - break; - } - break; - } - } else { - refreshArea = pGeode->Rotate ? LXRefreshArea_Blt : LXRefreshArea_Cpy; - } - ShadowFBInit(pScrn, refreshArea); -} diff --git a/src/amd_lx_vga.c b/src/amd_lx_vga.c index 6351f3d..699ca21 100644 --- a/src/amd_lx_vga.c +++ b/src/amd_lx_vga.c @@ -25,7 +25,7 @@ */ /* - * This file contains routines to set modes using the VGA registers. + * This file contains routines to set modes using the VGA registers. * Since this file is for the first generation graphics unit, it interfaces * to SoftVGA registers. It works for both VSA1 and VSA2. */ @@ -38,8 +38,5 @@ int gu3_get_vga_active(void) { int data = READ_REG32(DC3_GENERAL_CFG); - - if (data & DC3_GCFG_VGAE) - return 1; - return 0; + return (data & DC3_GCFG_VGAE) ? 1 : 0; } diff --git a/src/amd_lx_video.c b/src/amd_lx_video.c index a0836b0..13129c0 100644 --- a/src/amd_lx_video.c +++ b/src/amd_lx_video.c @@ -1,12 +1,11 @@ -/* - * Copyright (c) 2006 Advanced Micro Devices, Inc. +/* Copyright (c) 2007 Advanced Micro Devices, Inc. * - * 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: + * 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. @@ -16,232 +15,82 @@ * 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. + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. * * Neither the name of the Advanced Micro Devices, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. */ -/* - * File Contents: This file consists of main Xfree video supported routines. - * - * Project: Geode Xfree Frame buffer device driver. - * - */ - -/* - * Fixes & Extensions to support Y800 greyscale modes - * Alan Hourihane <alanh@fairlite.demon.co.uk> - */ +/* TODO: + Add rotation + Add back in double buffering? + +*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#ifndef AMD_V4L2_VIDEO +#include <stdlib.h> +#include <string.h> + #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Resources.h" -#include "xf86_ansic.h" #include "compiler.h" #include "xf86PciInfo.h" #include "xf86Pci.h" #include "xf86fbman.h" #include "regionstr.h" +#include "dixstruct.h" #include "amd.h" -#include "Xv.h" -#include "xaa.h" -#include "xaalocal.h" -#include "dixstruct.h" +#include "xf86xv.h" +#include <X11/extensions/Xv.h> #include "fourcc.h" #include "amd_fourcc.h" -#if DEBUGLVL>0 -#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) fprintf(zdfp,s); } while(0) -#include "xf86_ansic.h" -extern FILE *zdfp; -#else -#define DBLOG(n,s...) do {} while(0) -#endif - -#define OFF_DELAY 200 /* milliseconds */ -#define FREE_DELAY 60000 - -#define OFF_TIMER 0x01 -#define FREE_TIMER 0x02 +#define OFF_DELAY 200 +#define FREE_DELAY 60000 +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 #define CLIENT_VIDEO_ON 0x04 - #define TIMER_MASK (OFF_TIMER | FREE_TIMER) -#define XV_PROFILE 0 -#define REINIT 1 - -#ifndef XvExtension -void -LXInitVideo(ScreenPtr pScrn) -{ -} - -void -LXResetVideo(ScrnInfoPtr pScrni) -{ -} - -void -LXSetVideoPosition(int x, int y, int width, int height, - short src_w, short src_h, short drw_w, - short drw_h, int id, int offset, ScrnInfoPtr pScrni) -{ -} -#else - -#define DBUF 1 -void LXInitVideo(ScreenPtr pScrn); -void LXResetVideo(ScrnInfoPtr pScrni); -static XF86VideoAdaptorPtr LXSetupImageVideo(ScreenPtr); -static void LXInitOffscreenImages(ScreenPtr); -static void LXStopVideo(ScrnInfoPtr, pointer, Bool); -static int LXSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); -static int LXGetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer); -static void LXQueryBestSize(ScrnInfoPtr, Bool, - short, short, short, short, unsigned int *, unsigned int *, pointer); -static int LXPutImage(ScrnInfoPtr, short, short, short, short, short, short, - short, short, int, unsigned char *, short, short, Bool, - RegionPtr, pointer); -static int LXQueryImageAttributes(ScrnInfoPtr, int, unsigned short *, - unsigned short *, int *, int *); - -static void LXBlockHandler(int, pointer, pointer, pointer); -void LXSetVideoPosition(int x, int y, int width, int height, - short src_w, short src_h, short drw_w, - short drw_h, int id, int offset, ScrnInfoPtr pScrni); - -extern void LXAccelSync(ScrnInfoPtr pScrni); #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) +#define ARRAY_SIZE(a) (sizeof((a)) / (sizeof(*(a)))) -static Atom xvColorKey, xvColorKeyMode, xvFilter; - -#if DBUF -static Atom xvDoubleBuffer; -#endif - -/*---------------------------------------------------------------------------- - * LXInitVideo - * - * Description: This is the initialization routine. It creates a new video - * adapter and calls LXSetupImageVideo to initialize it by - * filling XF86VideoAdaptorREc. Then it lists the existing - * adaptors and adds the new one to it. Finally the list of - * XF86VideoAdaptorPtr pointers are passed to the - * xf86XVScreenInit(). - * - * Parameters. - * ScreenPtr - * pScrn :Screen handler pointer having screen information. - * - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -void -LXInitVideo(ScreenPtr pScrn) -{ - GeodeRec *pGeode; - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - - DBLOG(1, "LXInitVideo()\n"); - - pGeode = GEODEPTR(pScrni); - - if (!pGeode->NoAccel) { - XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; - XF86VideoAdaptorPtr newAdaptor = NULL; - - int num_adaptors; - - newAdaptor = LXSetupImageVideo(pScrn); - LXInitOffscreenImages(pScrn); - - num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors); - - if (newAdaptor) { - if (!num_adaptors) { - num_adaptors = 1; - adaptors = &newAdaptor; - } else { - newAdaptors = /* need to free this someplace */ - xalloc((num_adaptors + - 1) * sizeof(XF86VideoAdaptorPtr *)); - if (newAdaptors) { - memcpy(newAdaptors, adaptors, num_adaptors * - sizeof(XF86VideoAdaptorPtr)); - newAdaptors[num_adaptors] = newAdaptor; - adaptors = newAdaptors; - num_adaptors++; - } - } - } - - if (num_adaptors) - xf86XVScreenInit(pScrn, adaptors, num_adaptors); - - if (newAdaptors) - xfree(newAdaptors); - } -} - -/* client libraries expect an encoding */ static XF86VideoEncodingRec DummyEncoding[1] = { - { - 0, - "XV_IMAGE", - 1024, 1024, - {1, 1} - } + { 0, "XV_IMAGE", 1024, 1024, {1, 1} } }; -#define NUM_FORMATS 4 - -static XF86VideoFormatRec Formats[NUM_FORMATS] = { - {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +static XF86VideoFormatRec Formats[] = { + {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} }; -#if DBUF -#define NUM_ATTRIBUTES 4 -#else -#define NUM_ATTRIBUTES 3 -#endif - -static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { -#if DBUF - {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, -#endif - {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, - {XvSettable | XvGettable, 0, 1, "XV_FILTER"}, - {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} +static XF86AttributeRec Attributes[] = { + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, 0, 1, "XV_FILTER"}, + {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} }; static XF86ImageRec Images[] = { - XVIMAGE_UYVY, - XVIMAGE_YUY2, - XVIMAGE_Y2YU, - XVIMAGE_YVYU, - XVIMAGE_Y800, - XVIMAGE_I420, - XVIMAGE_YV12 + XVIMAGE_UYVY, + XVIMAGE_YUY2, + XVIMAGE_Y2YU, + XVIMAGE_YVYU, + XVIMAGE_Y800, + XVIMAGE_I420, + XVIMAGE_YV12, + XVIMAGE_RGB565 }; -#define NUM_IMAGES (sizeof(Images)/sizeof(Images[0])); - typedef struct { - FBAreaPtr area; - FBLinearPtr linear; + void *area; + int offset; RegionRec clip; CARD32 filter; CARD32 colorKey; @@ -249,1116 +98,797 @@ typedef struct CARD32 videoStatus; Time offTime; Time freeTime; -#if DBUF - Bool doubleBuffer; - int currentBuffer; -#endif -} -GeodePortPrivRec, *GeodePortPrivPtr; +} GeodePortPrivRec, *GeodePortPrivPtr; #define GET_PORT_PRIVATE(pScrni) \ (GeodePortPrivRec *)((GEODEPTR(pScrni))->adaptor->pPortPrivates[0].ptr) -/*---------------------------------------------------------------------------- - * LXSetColorKey - * - * Description :This function reads the color key for the pallete and - * sets the video color key register. - * - * Parameters. - * ScreenInfoPtr - * pScrni :Screen pointer having screen information. - * pPriv :Video port private data - * - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static INT32 -LXSetColorkey(ScrnInfoPtr pScrni, GeodePortPrivRec * pPriv) +static void +LXCopyFromSys(GeodeRec *pGeode, unsigned char *src, unsigned int dst, + int dstPitch, int srcPitch, int h, int w) { - int red, green, blue; - unsigned long key; - - switch (pScrni->depth) { - case 8: - vg_get_display_palette_entry(pPriv->colorKey & 0xFF, &key); - red = ((key >> 16) & 0xFF); - green = ((key >> 8) & 0xFF); - blue = (key & 0xFF); - break; - case 16: - red = (pPriv->colorKey & pScrni->mask.red) >> - pScrni->offset.red << (8 - pScrni->weight.red); - green = (pPriv->colorKey & pScrni->mask.green) >> - pScrni->offset.green << (8 - pScrni->weight.green); - blue = (pPriv->colorKey & pScrni->mask.blue) >> - pScrni->offset.blue << (8 - pScrni->weight.blue); - break; - default: - /* for > 16 bpp we send in the mask in xf86SetWeight. This - * function is providing the offset by 1 more. So we take - * this as a special case and subtract 1 for > 16 - */ - red = (pPriv->colorKey & pScrni->mask.red) >> - (pScrni->offset.red - 1) << (8 - pScrni->weight.red); - green = (pPriv->colorKey & pScrni->mask.green) >> - (pScrni->offset.green - 1) << (8 - pScrni->weight.green); - blue = (pPriv->colorKey & pScrni->mask.blue) >> - (pScrni->offset.blue - 1) << (8 - pScrni->weight.blue); - break; - } - - DBLOG(1, "LXSetColorkey() %08x %d\n", blue | (green << 8) | (red << 16), - pPriv->colorKeyMode); - if (pPriv->colorKeyMode != 0) - df_set_video_color_key((blue | (green << 8) | (red << 16)), - 0xFFFFFF, 1); - else - df_set_video_color_key(0, 0, 1); - REGION_EMPTY(pScrni->pScreen, &pPriv->clip); - - return 0; + gp_declare_blt(0); + gp_set_bpp(16); + + gp_set_raster_operation(0xCC); + gp_set_strides(dstPitch, srcPitch); + gp_set_solid_pattern(0); + + gp_color_bitmap_to_screen_blt(dst, 0, w, h, src, srcPitch); } -/*---------------------------------------------------------------------------- - * LXResetVideo - * - * Description : This function resets the video - * - * Parameters. - * ScreenInfoPtr - * pScrni :Screen pointer having screen information. - * - * Returns :None - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ - -void -LXResetVideo(ScrnInfoPtr pScrni) +static void +LXVideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) { - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(1, "LXResetVideo()\n"); - - if (!pGeode->NoAccel) { - GeodePortPrivRec *pPriv = pGeode->adaptor->pPortPrivates[0].ptr; - - LXAccelSync(pScrni); - df_set_video_palette(NULL); - LXSetColorkey(pScrni, pPriv); - } + ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; + + GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); + + if (area == pPriv->area) + pPriv->area = NULL; } -/*---------------------------------------------------------------------------- - * LXSetupImageVideo - * - * Description : This function allocates space for a Videoadaptor and initializes - * the XF86VideoAdaptorPtr record. - * - * Parameters. - * ScreenPtr - * pScrn :Screen handler pointer having screen information. - * - * Returns :XF86VideoAdaptorPtr :- pointer to the initialized video adaptor record. - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static XF86VideoAdaptorPtr -LXSetupImageVideo(ScreenPtr pScrn) +static unsigned int +LXAllocateVidMem(ScrnInfoPtr pScrni, void **memp, int size) { - ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; - GeodeRec *pGeode = GEODEPTR(pScrni); - XF86VideoAdaptorPtr adapt; - GeodePortPrivRec *pPriv; - - DBLOG(1, "LXSetupImageVideo()\n"); - - if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + - sizeof(GeodePortPrivRec) + sizeof(DevUnion)))) - return NULL; - - adapt->type = XvWindowMask | XvInputMask | XvImageMask; - adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; - adapt->name = "Advanced Micro Devices"; - adapt->nEncodings = 1; - adapt->pEncodings = DummyEncoding; - adapt->nFormats = NUM_FORMATS; - adapt->pFormats = Formats; - adapt->nPorts = 1; - adapt->pPortPrivates = (DevUnion *) (&adapt[1]); - pPriv = (GeodePortPrivRec *) (&adapt->pPortPrivates[1]); - adapt->pPortPrivates[0].ptr = (pointer) (pPriv); - adapt->pAttributes = Attributes; - adapt->nImages = NUM_IMAGES; - adapt->nAttributes = NUM_ATTRIBUTES; - adapt->pImages = Images; - adapt->PutVideo = NULL; - adapt->PutStill = NULL; - adapt->GetVideo = NULL; - adapt->GetStill = NULL; - adapt->StopVideo = LXStopVideo; - adapt->SetPortAttribute = LXSetPortAttribute; - adapt->GetPortAttribute = LXGetPortAttribute; - adapt->QueryBestSize = LXQueryBestSize; - adapt->PutImage = LXPutImage; - adapt->QueryImageAttributes = LXQueryImageAttributes; - - pPriv->filter = 0; - pPriv->colorKey = pGeode->videoKey; - pPriv->colorKeyMode = 0; - pPriv->videoStatus = 0; -#if DBUF - pPriv->doubleBuffer = TRUE; - pPriv->currentBuffer = 0; /* init to first buffer */ -#endif - - /* gotta uninit this someplace */ -#if defined(REGION_NULL) - REGION_NULL(pScrn, &pPriv->clip); -#else - REGION_INIT(pScrn, &pPriv->clip, NullBox, 0); -#endif - - pGeode->adaptor = adapt; - - pGeode->BlockHandler = pScrn->BlockHandler; - pScrn->BlockHandler = LXBlockHandler; - - xvColorKey = MAKE_ATOM("XV_COLORKEY"); - xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE"); - xvFilter = MAKE_ATOM("XV_FILTER"); -#if DBUF - xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); -#endif - - LXResetVideo(pScrni); - - return adapt; + ExaOffscreenArea *area = *memp; + + if (area != NULL) { + if (area->size >= size) + return area->offset; + + exaOffscreenFree(pScrni->pScreen, area); + } + + area = exaOffscreenAlloc(pScrni->pScreen, size, 16, TRUE, + LXVideoSave, NULL); + + *memp = area; + return (area == NULL) ? 0 : area->offset; } -/*---------------------------------------------------------------------------- - * LXStopVideo - * - * Description :This function is used to stop input and output video - * - * Parameters. - * pScrni :Screen handler pointer having screen information. - * data :Pointer to the video port's private data - * exit :Flag indicating whether the offscreen areas used for video - * to be deallocated or not. - * Returns :none - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ static void -LXStopVideo(ScrnInfoPtr pScrni, pointer data, Bool exit) +LXSetColorkey(ScrnInfoPtr pScrni, GeodePortPrivRec * pPriv) { - GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; - GeodeRec *pGeode = GEODEPTR(pScrni); - - DBLOG(1, "LXStopVideo()\n"); - - REGION_EMPTY(pScrni->pScreen, &pPriv->clip); - - LXAccelSync(pScrni); - if (exit) { - if (pPriv->videoStatus & CLIENT_VIDEO_ON) { - df_set_video_enable(0, 0); - } - if (pPriv->area) { - xf86FreeOffscreenArea(pPriv->area); - pPriv->area = NULL; - } - pPriv->videoStatus = 0; - pGeode->OverlayON = FALSE; - } else { - if (pPriv->videoStatus & CLIENT_VIDEO_ON) { - pPriv->videoStatus |= OFF_TIMER; - pPriv->offTime = currentTime.milliseconds + OFF_DELAY; - } - } + int red, green, blue; + unsigned long key; + + switch (pScrni->depth) { + case 8: + vg_get_display_palette_entry(pPriv->colorKey & 0xFF, &key); + red = ((key >> 16) & 0xFF); + green = ((key >> 8) & 0xFF); + blue = (key & 0xFF); + break; + case 16: + red = (pPriv->colorKey & pScrni->mask.red) >> + pScrni->offset.red << (8 - pScrni->weight.red); + green = (pPriv->colorKey & pScrni->mask.green) >> + pScrni->offset.green << (8 - pScrni->weight.green); + blue = (pPriv->colorKey & pScrni->mask.blue) >> + pScrni->offset.blue << (8 - pScrni->weight.blue); + break; + default: + /* for > 16 bpp we send in the mask in xf86SetWeight. This + * function is providing the offset by 1 more. So we take + * this as a special case and subtract 1 for > 16 + */ + + red = (pPriv->colorKey & pScrni->mask.red) >> + (pScrni->offset.red - 1) << (8 - pScrni->weight.red); + green = (pPriv->colorKey & pScrni->mask.green) >> + (pScrni->offset.green - 1) << (8 - pScrni->weight.green); + blue = (pPriv->colorKey & pScrni->mask.blue) >> + (pScrni->offset.blue - 1) << (8 - pScrni->weight.blue); + break; + } + + df_set_video_color_key((blue | (green << 8) | (red << 16)), + 0xFFFFFF, (pPriv->colorKeyMode == 0)); + + REGION_EMPTY(pScrni->pScreen, &pPriv->clip); } -/*---------------------------------------------------------------------------- - * LXSetPortAttribute - * - * Description :This function is used to set the attributes of a port like colorkeymode, - * double buffer support and filter. - * - * Parameters. - * pScrni :Screen handler pointer having screen information. - * data :Pointer to the video port's private data - * attribute :The port attribute to be set - * value :Value of the attribute to be set. - * - * Returns :Sucess if the attribute is supported, else BadMatch - * - * Comments :none - * -*---------------------------------------------------------------------------- +/* A structure full of the scratch information that originates in the copy routines, + but is needed for the video display - maybe we should figure out a way to attach + this to structures? I hate to put it in pGeode since it will increase the size of + the structure, and possibly cause us cache issues. */ -static int -LXSetPortAttribute(ScrnInfoPtr pScrni, - Atom attribute, INT32 value, pointer data) -{ - GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; - DBLOG(1, "LXSetPortAttribute(%d,%#x)\n", attribute, value); +struct { + unsigned int dstOffset; + unsigned int dstPitch; + unsigned int UVPitch; + unsigned int UDstOffset; + unsigned int VDstOffset; +} videoScratch; - LXAccelSync(pScrni); - if (attribute == xvColorKey) { - pPriv->colorKey = value; - LXSetColorkey(pScrni, pPriv); - } -#if DBUF - else if (attribute == xvDoubleBuffer) { - if ((value < 0) || (value > 1)) - return BadValue; - pPriv->doubleBuffer = value; - } -#endif - else if (attribute == xvColorKeyMode) { - pPriv->colorKeyMode = value; - LXSetColorkey(pScrni, pPriv); - } else if (attribute == xvFilter) { - if ((value < 0) || (value > 1)) - return BadValue; - pPriv->filter = value; - } else - return BadMatch; +/* Copy planar YUV data */ - return Success; +static Bool +LXCopyPlanar(ScrnInfoPtr pScrni, int id, unsigned char *buf, + short x1, short y1, short x2, short y2, + int width, int height, pointer data) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + + unsigned int YSrcPitch, YDstPitch; + unsigned int UVSrcPitch, UVDstPitch; + unsigned int YSrcOffset, YDstOffset; + unsigned int USrcOffset, UDstOffset; + unsigned int VSrcOffset, VDstOffset; + + unsigned int size, lines, top, left, pixels; + + YSrcPitch = (width + 3) & ~3; + YDstPitch = (width + 31) & ~31; + + UVSrcPitch = ((width >> 1) + 3) & ~3; + UVDstPitch = ((width >> 1) + 15) & ~15; + + if (id != FOURCC_I420) { + VSrcOffset = YSrcPitch * height; + USrcOffset = VSrcOffset + (UVSrcPitch * (height >> 1)); + + VDstOffset = YDstPitch * height; + UDstOffset = VDstOffset + (UVDstPitch * (height >> 1)); + } + else { + USrcOffset = YSrcPitch * height; + VSrcOffset = USrcOffset + (UVSrcPitch * (height >> 1)); + + UDstOffset = YDstPitch * height; + VDstOffset = UDstOffset + (UVDstPitch * (height >> 1)); + } + + size = YDstPitch * height; + size += UVDstPitch * height; + + pPriv->offset = LXAllocateVidMem(pScrni, &pPriv->area, size); + + if (pPriv->offset == 0) { + ErrorF("Error allocating an offscreen region.\n"); + return FALSE; + } + + /* The top of the source region we want to copy */ + top = y1 & ~1; + + /* The left hand side of the source region, aligned on a word */ + left = x1 & ~1; + + /* Number of bytes to copy, also word aligned */ + pixels = ((x2 + 1) & ~1) - left; + + /* Calculate the source offset */ + YSrcOffset = (top * YSrcPitch) + left; + USrcOffset += ((top >> 1) * UVSrcPitch) + (left >> 1); + VSrcOffset += ((top >> 1) * UVSrcPitch) + (left >> 1); + + /* Calculate the destination offset */ + YDstOffset = (top * YDstPitch) + left; + UDstOffset += ((top >> 1) * UVDstPitch) + (left >> 1); + VDstOffset += ((top >> 1) * UVDstPitch) + (left >> 1); + + lines = ((y2 + 1) & ~1) - top; + + /* Copy Y */ + + LXCopyFromSys(pGeode, buf + YSrcOffset, pPriv->offset + YDstOffset, + YDstPitch, YSrcPitch, lines, pixels); + + /* Copy U + V at the same time */ + + LXCopyFromSys(pGeode, buf + USrcOffset, pPriv->offset + UDstOffset, + UVDstPitch, UVSrcPitch, lines, pixels >> 1); + + /* Copy V */ + + //LXCopyFromSys(pGeode, buf + VSrcOffset, pPriv->offset + VDstOffset, + //UVDstPitch, UVSrcPitch, lines >> 1, pixels >> 1); + + videoScratch.dstOffset = pPriv->offset + YDstOffset; + videoScratch.dstPitch = YDstPitch; + videoScratch.UVPitch = UVDstPitch; + videoScratch.UDstOffset = pPriv->offset + UDstOffset; + videoScratch.VDstOffset = pPriv->offset + VDstOffset; + + return TRUE; } -/*---------------------------------------------------------------------------- - * LXGetPortAttribute - * - * Description :This function is used to get the attributes of a port like hue, - * saturation,brightness or contrast. - * - * Parameters. - * pScrni :Screen handler pointer having screen information. - * data :Pointer to the video port's private data - * attribute :The port attribute to be read - * value :Pointer to the value of the attribute to be read. - * - * Returns :Sucess if the attribute is supported, else BadMatch - * - * Comments :none - * -*---------------------------------------------------------------------------- -*/ -static int -LXGetPortAttribute(ScrnInfoPtr pScrni, - Atom attribute, INT32 * value, pointer data) +static Bool +LXCopyPacked(ScrnInfoPtr pScrni, int id, unsigned char *buf, + short x1, short y1, short x2, short y2, + int width, int height, pointer data) { - GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; - - DBLOG(1, "LXGetPortAttribute(%d)\n", attribute); - - if (attribute == xvColorKey) { - *value = pPriv->colorKey; - } -#if DBUF - else if (attribute == xvDoubleBuffer) { - *value = (pPriv->doubleBuffer) ? 1 : 0; - } -#endif - else if (attribute == xvColorKeyMode) { - *value = pPriv->colorKeyMode; - } else if (attribute == xvFilter) { - *value = pPriv->filter; - } else - return BadMatch; - - return Success; + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + GeodeRec *pGeode = GEODEPTR(pScrni); + unsigned int dstPitch, srcPitch; + unsigned int srcOffset, dstOffset; + unsigned int lines, top, left, pixels; + + dstPitch = ((width << 1) + 3) & ~3; + srcPitch = (width << 1); + + lines = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch; + + pPriv->offset = LXAllocateVidMem(pScrni, &pPriv->area, height * dstPitch); + + if (pPriv->offset == 0) { + ErrorF("Error while allocating an offscreen region.\n"); + return FALSE; + } + + /* The top of the source region we want to copy */ + top = y1; + + /* The left hand side of the source region, aligned on a word */ + left = x1 & ~1; + + /* Number of bytes to copy, also word aligned */ + pixels = ((x2 + 1) & ~1) - left; + + /* Adjust the incoming buffer */ + srcOffset = (top * srcPitch) + left; + + /* Calculate the destination offset */ + dstOffset = pPriv->offset + (top * dstPitch) + left; + + /* Make the copy happen */ + + if (id == FOURCC_Y800) { + + /* Use the shared (unaccelerated) greyscale copy - you could probably + accelerate it using a 2 pass blit and patterns, but it doesn't really + seem worth it + */ + + GeodeCopyGreyscale(buf + srcOffset, pGeode->FBBase + dstOffset, srcPitch, dstPitch, + height, pixels >> 1); + } + else + LXCopyFromSys(pGeode, buf + srcOffset, dstOffset, dstPitch, srcPitch, height, pixels); + + videoScratch.dstOffset = dstOffset; + videoScratch.dstPitch = dstPitch; + + return TRUE; } -/*---------------------------------------------------------------------------- - * LXQueryBestSize - * - * Description : - * This function provides a way to query what the destination dimensions - * would end up being if they were to request that an area vid_w by vid_h - * from the video stream be scaled to rectangle of drw_w by drw_h on - * the screen. - * - * Parameters. - * ScreenInfoPtr - * pScrni :Screen handler pointer having screen information. - * data :Pointer to the video port's private data - * vid_w,vid_h :Width and height of the video data. - * drw_w,drw_h :Width and height of the scaled rectangle. - * p_w,p_h :Width and height of the destination rectangle. - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ -static void -LXQueryBestSize(ScrnInfoPtr pScrni, Bool motion, short vid_w, short vid_h, - short drw_w, short drw_h, unsigned int *p_w, - unsigned int *p_h, pointer data) +void +LXDisplayVideo(ScrnInfoPtr pScrni, int id, short width, short height, + BoxPtr dstBox, short srcW, short srcH, short drawW, short drawH) { - *p_w = drw_w; - *p_h = drw_h; - - if (*p_w > 16384) - *p_w = 16384; - - DBLOG(1, "LXQueryBestSize(%d, src %dx%d scl %dx%d dst %dx%d)\n", motion, - vid_w, vid_h, drw_w, drw_h, *p_w, *p_h); + long ystart, xend, yend; + unsigned long lines = 0; + unsigned long yExtra, uvExtra = 0; + DF_VIDEO_POSITION vidPos; + DF_VIDEO_SOURCE_PARAMS vSrcParams; + + gp_wait_until_idle(); + + switch(id) { + case FOURCC_UYVY: + vSrcParams.video_format = DF_VIDFMT_UYVY; + break; + + case FOURCC_Y800: + case FOURCC_YV12: + case FOURCC_I420: + vSrcParams.video_format = DF_VIDFMT_Y0Y1Y2Y3; + break; + case FOURCC_YUY2: + vSrcParams.video_format = DF_VIDFMT_YUYV; + break; + case FOURCC_Y2YU: + vSrcParams.video_format = DF_VIDFMT_Y2YU; + break; + case FOURCC_YVYU: + vSrcParams.video_format = DF_VIDFMT_YVYU; + break; + case FOURCC_RGB565: + vSrcParams.video_format = DF_VIDFMT_RGB; + break; + } + + vSrcParams.width = width; + vSrcParams.height = height; + vSrcParams.y_pitch = videoScratch.dstPitch; + vSrcParams.uv_pitch = videoScratch.UVPitch; + + /* Set up scaling */ + df_set_video_filter_coefficients(NULL, 1); + + if ((drawW >= srcW) && (drawH >= srcH)) + df_set_video_scale(width, height, drawW, drawH, + DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); + else if (drawW < srcW) + df_set_video_scale(drawW, height, drawW, drawH, + DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); + else if (drawH < srcH) + df_set_video_scale(width, drawH, drawW, drawH, + DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); + + /* Figure out clipping */ + + xend = dstBox->x2; + yend = dstBox->y2; + + if (dstBox->y1 < 0) { + if (srcH < drawH) + lines = ((-dstBox->y1) * srcH) / drawH; + else + lines = (-dstBox->y1); + + ystart = 0; + drawH += dstBox->y1; + } + else { + ystart = dstBox->y1; + lines = 0; + } + + yExtra = lines * videoScratch.dstPitch; + uvExtra = (lines >> 1) * videoScratch.UVPitch; + + memset(&vidPos, 0, sizeof(vidPos)); + + vidPos.x = dstBox->x1; + vidPos.y = ystart; + vidPos.width = xend - dstBox->x1; + vidPos.height = yend - ystart; + + df_set_video_position(&vidPos); + + vSrcParams.y_offset = videoScratch.dstOffset + yExtra; + + switch(id) { + case FOURCC_Y800: + case FOURCC_I420: + case FOURCC_YV12: + vSrcParams.u_offset = videoScratch.UDstOffset + uvExtra; + vSrcParams.v_offset = videoScratch.VDstOffset + uvExtra; + break; + + default: + vSrcParams.u_offset = vSrcParams.v_offset = 0; + break; + } + + vSrcParams.flags = DF_SOURCEFLAG_IMPLICITSCALING; + df_configure_video_source(&vSrcParams, &vSrcParams); + df_set_video_enable(1, 0); } -static void -LXCopyGreyscale(unsigned char *src, unsigned char *dst, int srcp, int dstp, - int h, int w) +static int +LXPutImage(ScrnInfoPtr pScrni, + short srcX, short srcY, short drawX, short drawY, + short srcW, short srcH, short drawW, short drawH, + int id, unsigned char *buf, + short width, short height, Bool sync, RegionPtr clipBoxes, + pointer data, DrawablePtr pDraw) { - int i; - unsigned char *src2 = src; - unsigned char *dst2 = dst; - unsigned char *dst3; - unsigned char *src3; - - dstp <<= 1; - - while (h--) { - dst3 = dst2; - src3 = src2; - for (i = 0; i < w; i++) { - *dst3++ = *src3++; /* Copy Y data */ - *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ - } - src3 = src2; - for (i = 0; i < w; i++) { - *dst3++ = *src3++; /* Copy Y data */ - *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */ - } - dst2 += dstp; - src2 += srcp; + GeodeRec *pGeode = GEODEPTR(pScrni); + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + INT32 x1,x2,y1,y2; + BoxRec dstBox; + + if (srcW <= 0 || srcH <= 0) { + ErrorF("Nothing to draw!\n"); + return Success; + } + + if (drawW <= 0 || drawH <=0) { + ErrorF("Nothing to show!\n"); + return Success; + } + + if (drawW > 16384) + drawW = 16384; + + x1 = srcX; + x2 = srcX + srcW; + y1 = srcY; + y2 = srcY + srcH; + + dstBox.x1 = drawX; + dstBox.x2 = drawX + drawW; + dstBox.y1 = drawY; + dstBox.y2 = drawY + drawH; + + dstBox.x1 -= pScrni->frameX0; + dstBox.x2 -= pScrni->frameX0; + dstBox.y1 -= pScrni->frameY0; + dstBox.y2 -= pScrni->frameY0; + + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + LXCopyPlanar(pScrni, id, buf, x1, y1, x2, y2, width, height, data); + break; + + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_Y800: + case FOURCC_RGB565: + LXCopyPacked(pScrni, id, buf, x1, y1, x2, y2, width, height, data); + break; + } + + if (!RegionsEqual(&pPriv->clip, clipBoxes)) { + REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); + + if (pPriv->colorKeyMode == 0) { + xf86XVFillKeyHelper(pScrni->pScreen, pPriv->colorKey, clipBoxes); } + + LXDisplayVideo(pScrni, id, width, height, &dstBox, + srcW, srcH, drawW, drawH); + } + + pPriv->videoStatus = CLIENT_VIDEO_ON; + pGeode->OverlayON = TRUE; + + return Success; } -/*---------------------------------------------------------------------------- - * LXCopyData420 - * - * Description : Copies data from src to destination - * - * Parameters. - * src : pointer to the source data - * dst : pointer to destination data - * srcp : pitch of the srcdata - * dstp : pitch of the destination data - * h & w : height and width of source data - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ - static void -LXCopyData420(unsigned char *src, unsigned char *dst, int srcp, int dstp, - int h, int w) +LXQueryBestSize(ScrnInfoPtr pScrni, Bool motion, + short vidW, short vidH, short drawW, short drawH, + unsigned int *retW, unsigned int *retH, pointer data) { - while (h--) { - memcpy(dst, src, w); - src += srcp; - dst += dstp; - } + *retW = drawW > 16384 ? 16384 : drawW; + *retH = drawH; } - -/*---------------------------------------------------------------------------- - * LXCopyData422 - * - * Description : Copies data from src to destination - * - * Parameters. - * src : pointer to the source data - * dst : pointer to destination data - * srcp : pitch of the srcdata - * dstp : pitch of the destination data - * h & w : height and width of source data - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ - -static void -LXCopyData422(unsigned char *src, unsigned char *dst, - int srcp, int dstp, int h, int w) + +static Atom xvColorKey, xvColorKeyMode, xvFilter; + +static int +LXGetPortAttribute(ScrnInfoPtr pScrni, + Atom attribute, INT32 * value, pointer data) { - w <<= 1; - while (h--) { - memcpy(dst, src, w); - src += srcp; - dst += dstp; - } + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + + if (attribute == xvColorKey) + *value = pPriv->colorKey; + else if (attribute == xvColorKeyMode) + *value = pPriv->colorKeyMode; + else if (attribute == xvFilter) + *value = pPriv->filter; + else + return BadMatch; + + return Success; } -static FBAreaPtr -LXAllocateMemory(ScrnInfoPtr pScrni, FBAreaPtr area, int numlines) +static int +LXSetPortAttribute(ScrnInfoPtr pScrni, + Atom attribute, INT32 value, pointer data) { - ScreenPtr pScrn = screenInfo.screens[pScrni->scrnIndex]; - FBAreaPtr new_area; + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + + gp_wait_until_idle(); + + if (attribute == xvColorKey) { + pPriv->colorKey = value; + LXSetColorkey(pScrni, pPriv); + } + else if (attribute == xvColorKeyMode) { + pPriv->colorKeyMode = value; + LXSetColorkey(pScrni, pPriv); + } + else if (attribute == xvFilter) { + if ((value < 0) || (value > 1)) + return BadValue; + pPriv->filter = value; + } + else + return BadMatch; + + return Success; +} - if (area) { - if ((area->box.y2 - area->box.y1) >= numlines) - return area; +void +LXStopVideo(ScrnInfoPtr pScrni, pointer data, Bool exit) +{ + GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; + GeodeRec *pGeode = GEODEPTR(pScrni); - if (xf86ResizeOffscreenArea(area, pScrni->displayWidth, numlines)) - return area; + REGION_EMPTY(pScrni->pScreen, &pPriv->clip); + gp_wait_until_idle(); - xf86FreeOffscreenArea(area); + if (exit) { + if (pPriv->videoStatus & CLIENT_VIDEO_ON) { + df_set_video_enable(0,0); + df_set_video_palette(NULL); } - new_area = xf86AllocateOffscreenArea(pScrn, pScrni->displayWidth, - numlines, 0, NULL, NULL, NULL); - - if (!new_area) { - int max_w, max_h; - - xf86QueryLargestOffscreenArea(pScrn, &max_w, &max_h, 0, - FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME); + if (pPriv->area) + exaOffscreenFree(pScrni->pScreen, pPriv->area); - if ((max_w < pScrni->displayWidth) || (max_h < numlines)) - return NULL; + pPriv->videoStatus = 0; - xf86PurgeUnlockedOffscreenAreas(pScrn); - new_area = xf86AllocateOffscreenArea(pScrn, pScrni->displayWidth, - numlines, 0, NULL, NULL, NULL); + /* Eh? */ + pGeode->OverlayON = FALSE; + } + else { + if (pPriv->videoStatus & CLIENT_VIDEO_ON) { + pPriv->videoStatus |= OFF_TIMER; + pPriv->offTime = currentTime.milliseconds + OFF_DELAY; } - - return new_area; + } } - -static BoxRec dstBox; -static int srcPitch = 0, srcPitch2 = 0, dstPitch = 0, dstPitch2 = 0; -static INT32 Bx1, Bx2, By1, By2; -static int top, left, npixels, nlines; -static int offset, s1offset = 0, s2offset = 0, s3offset = 0; -static unsigned char *dst_start; -static int d2offset = 0, d3offset = 0; - -static DF_VIDEO_SOURCE_PARAMS vSrcParams; - + void -LXSetVideoPosition(int x, int y, int width, int height, - short src_w, short src_h, short drw_w, short drw_h, - int id, int offset, ScrnInfoPtr pScrni) +LXResetVideo(ScrnInfoPtr pScrni) { - long ystart, xend, yend; - unsigned long lines = 0; - unsigned long y_extra, uv_extra = 0; - DF_VIDEO_POSITION vidPos; - - DBLOG(1, "LXSetVideoPosition(%d,%d %dx%d, src %dx%d, dst %dx%d, id %d, " - "ofs %d)\n", x, y, width, height, src_w, src_h, drw_w, drw_h, - id, offset); - - xend = x + drw_w; - yend = y + drw_h; - - /* TOP CLIPPING */ - - if (y < 0) { - if (src_h < drw_h) - lines = (-y) * src_h / drw_h; - else - lines = (-y); - ystart = 0; - drw_h += y; - y_extra = lines * dstPitch; - uv_extra = (lines >> 1) * (dstPitch2); - } else { - ystart = y; - lines = 0; - y_extra = 0; - } - - memset(&vidPos, 0, sizeof(vidPos)); - vidPos.x = x; - vidPos.y = ystart; - vidPos.width = xend - x; - vidPos.height = yend - ystart; - - DBLOG(1, "video_pos %d,%d %dx%d\n", vidPos.x, vidPos.y, vidPos.width, - vidPos.height); - df_set_video_position(&vidPos); - - vSrcParams.y_offset = offset + y_extra; - if ((id == FOURCC_Y800) || (id == FOURCC_I420) || (id == FOURCC_YV12)) { - vSrcParams.u_offset = offset + d3offset + uv_extra; - vSrcParams.v_offset = offset + d2offset + uv_extra; - } else { - vSrcParams.u_offset = vSrcParams.v_offset = 0; - } - vSrcParams.flags = DF_SOURCEFLAG_IMPLICITSCALING; - - DBLOG(1, "video_format %#x yofs %#x uofs %#x vofs %#x yp %d uvp %d wh " - "%dx%d flg %#x\n", vSrcParams.video_format, vSrcParams.y_offset, - vSrcParams.u_offset, vSrcParams.v_offset, vSrcParams.y_pitch, - vSrcParams.uv_pitch, vSrcParams.width, vSrcParams.height, - vSrcParams.flags); + GeodeRec *pGeode = GEODEPTR(pScrni); - df_configure_video_source(&vSrcParams, &vSrcParams); -} + if (!pGeode->NoAccel) { + GeodePortPrivRec *pPriv = pGeode->adaptor->pPortPrivates[0].ptr; -/*---------------------------------------------------------------------------- - * LXDisplayVideo - * - * Description : This function sets up the video registers for playing video - * It sets up the video format,width, height & position of the - * video window ,video offsets( y,u,v) and video pitches(y,u,v) - * Parameters. - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ + gp_wait_until_idle(); + df_set_video_palette(NULL); -static void -LXDisplayVideo(ScrnInfoPtr pScrni, int id, int offset, short width, - short height, int pitch, int x1, int y1, int x2, int y2, - BoxPtr dstBox, short src_w, short src_h, short drw_w, short drw_h) -{ - DBLOG(1, "LXDisplayVideo(id %d, ofs %d, %dx%d, p %d, %d,%d, %d,%d, src " - "%dx%d dst %dx%d)\n", id, offset, width, height, pitch, x1, y1, - x2, y2, src_w, src_h, drw_w, drw_h); - - LXAccelSync(pScrni); - - switch (id) { - case FOURCC_UYVY: - vSrcParams.video_format = DF_VIDFMT_UYVY; - break; - case FOURCC_Y800: - case FOURCC_YV12: - case FOURCC_I420: - vSrcParams.video_format = DF_VIDFMT_Y0Y1Y2Y3; - break; - case FOURCC_YUY2: - vSrcParams.video_format = DF_VIDFMT_YUYV; - break; - case FOURCC_Y2YU: - vSrcParams.video_format = DF_VIDFMT_Y2YU; - break; - case FOURCC_YVYU: - vSrcParams.video_format = DF_VIDFMT_YVYU; - break; + LXSetColorkey(pScrni, pPriv); } - - vSrcParams.width = width; - vSrcParams.height = height; - vSrcParams.y_pitch = dstPitch; - vSrcParams.uv_pitch = dstPitch2; - - df_set_video_filter_coefficients(NULL, 1); - if ((drw_w >= src_w) && (drw_h >= src_h)) - df_set_video_scale(width, height, drw_w, drw_h, - DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); - else if (drw_w < src_w) - df_set_video_scale(drw_w, height, drw_w, drw_h, - DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); - else if (drw_h < src_h) - df_set_video_scale(width, drw_h, drw_w, drw_h, - DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY); - - LXSetVideoPosition(dstBox->x1, dstBox->y1, width, height, src_w, - src_h, drw_w, drw_h, id, offset, pScrni); - - df_set_video_enable(1, 0); } -#if REINIT -static Bool -RegionsEqual(RegionPtr A, RegionPtr B) +static void +LXVidBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) { - int *dataA, *dataB; - int num; - - num = REGION_NUM_RECTS(A); - if (num != REGION_NUM_RECTS(B)) { - return FALSE; - } - - if ((A->extents.x1 != B->extents.x1) || - (A->extents.x2 != B->extents.x2) || - (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2)) - return FALSE; + ScreenPtr pScrn = screenInfo.screens[i]; + ScrnInfoPtr pScrni = xf86Screens[i]; + GeodeRec *pGeode = GEODEPTR(pScrni); + GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); - dataA = (int *)REGION_RECTS(A); - dataB = (int *)REGION_RECTS(B); + pScrn->BlockHandler = pGeode->BlockHandler; + (*pScrn->BlockHandler) (i, blockData, pTimeout, pReadmask); + pScrn->BlockHandler = LXVidBlockHandler; - while (num--) { - if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) - return FALSE; - dataA += 2; - dataB += 2; + if (pPriv->videoStatus & TIMER_MASK) { + Time now = currentTime.milliseconds; + + if (pPriv->videoStatus & OFF_TIMER) { + gp_wait_until_idle(); + + if (pPriv->offTime < now) { + df_set_video_enable(0, 0); + pPriv->videoStatus = FREE_TIMER; + pPriv->freeTime = now + FREE_DELAY; + } + } + else { + if (pPriv->freeTime < now) { + if (pPriv->area) { + exaOffscreenFree(pScrni->pScreen, pPriv->area); + pPriv->area = NULL; + } + + pPriv->videoStatus = 0; + } + } } - - return TRUE; } -#endif - -/*---------------------------------------------------------------------------- - * LXPutImage : - * This function writes a single frame of video into a drawable. - * The position and size of the source rectangle is specified by src_x,src_y, - * src_w and src_h. This data is stored in a system memory buffer at buf. - * The position and size of the destination rectangle is specified by drw_x, - * drw_y,drw_w,drw_h.The data is in the format indicated by the image - * descriptor and represents a source of size width by height. If sync is - * TRUE the driver should not return from this function until it is through - * reading the data from buf. Returning when sync is TRUE indicates that - * it is safe for the data at buf to be replaced,freed, or modified. - * - * Description : - * Parameters. - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ -static int -LXPutImage(ScrnInfoPtr pScrni, short src_x, short src_y, short drw_x, - short drw_y, short src_w, short src_h, short drw_w, short drw_h, - int id, unsigned char *buf, short width, short height, Bool sync, - RegionPtr clipBoxes, pointer data) +static XF86VideoAdaptorPtr +LXSetupImageVideo(ScreenPtr pScrn) { - GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; - GeodeRec *pGeode = GEODEPTR(pScrni); - int new_h; - -#if REINIT - BOOL ReInitVideo = FALSE; - static BOOL DoReinitAgain = 0; -#endif - -#if XV_PROFILE - long oldtime, newtime; - - UpdateCurrentTime(); - oldtime = currentTime.milliseconds; -#endif - DBLOG(1, "LXPutImage(src %d,%d %dx%d dst %d,%d %dx%d, id %d %dx%d sync " - "%d)\n", src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, - id, width, height, sync); - -#if REINIT - /* update cliplist */ - if (!RegionsEqual(&pPriv->clip, clipBoxes)) { - ReInitVideo = TRUE; - } - - if (DoReinitAgain) - ReInitVideo = TRUE; - - if (ReInitVideo) { - DBLOG(1, "Regional Not Equal - Init\n"); -#endif - DoReinitAgain = ~DoReinitAgain; - if (drw_w > 16384) - drw_w = 16384; - - /* Clip */ - Bx1 = src_x; - Bx2 = src_x + src_w; - By1 = src_y; - By2 = src_y + src_h; - - if ((Bx1 >= Bx2) || (By1 >= By2)) - return Success; - - dstBox.x1 = drw_x; - dstBox.x2 = drw_x + drw_w; - dstBox.y1 = drw_y; - dstBox.y2 = drw_y + drw_h; - - dstBox.x1 -= pScrni->frameX0; - dstBox.x2 -= pScrni->frameX0; - dstBox.y1 -= pScrni->frameY0; - dstBox.y2 -= pScrni->frameY0; - - switch (id) { - case FOURCC_YV12: - case FOURCC_I420: - srcPitch = (width + 3) & ~3; /* of luma */ - dstPitch = (width + 31) & ~31; - - s2offset = srcPitch * height; - d2offset = dstPitch * height; - - srcPitch2 = ((width >> 1) + 3) & ~3; - dstPitch2 = ((width >> 1) + 15) & ~15; - - s3offset = (srcPitch2 * (height >> 1)) + s2offset; - d3offset = (dstPitch2 * (height >> 1)) + d2offset; - - new_h = dstPitch * height; /* Y */ - new_h += (dstPitch2 * height); /* U+V */ - new_h += pGeode->Pitch - 1; - new_h /= pGeode->Pitch; - break; - - case FOURCC_UYVY: - case FOURCC_YUY2: - case FOURCC_Y800: - default: - dstPitch = ((width << 1) + 3) & ~3; - srcPitch = (width << 1); - new_h = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch; - break; - } - -#if DBUF - if (pPriv->doubleBuffer) - new_h <<= 1; -#endif - - if (!(pPriv->area = LXAllocateMemory(pScrni, pPriv->area, new_h))) - return BadAlloc; - - /* copy data */ - top = By1; - left = Bx1 & ~1; - npixels = ((Bx2 + 1) & ~1) - left; - - switch (id) { - case FOURCC_YV12: - case FOURCC_I420:{ - int tmp; - - top &= ~1; - offset = (pPriv->area->box.y1 * pGeode->Pitch) + - (top * dstPitch); - -#if DBUF - if (pPriv->doubleBuffer && pPriv->currentBuffer) - offset += (new_h >> 1) * pGeode->Pitch; -#endif - - dst_start = pGeode->FBBase + offset + left; - tmp = ((top >> 1) * srcPitch2) + (left >> 1); - s2offset += tmp; - s3offset += tmp; - if (id == FOURCC_I420) { - tmp = s2offset; - s2offset = s3offset; - s3offset = tmp; - } - nlines = ((By2 + 1) & ~1) - top; - } - break; - - case FOURCC_UYVY: - case FOURCC_YUY2: - case FOURCC_Y800: - default: - left <<= 1; - buf += (top * srcPitch) + left; - nlines = By2 - top; - offset = (pPriv->area->box.y1 * pGeode->Pitch) + (top * dstPitch); -#if DBUF - if (pPriv->doubleBuffer && pPriv->currentBuffer) - offset += (new_h >> 1) * pGeode->Pitch; -#endif + ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; + GeodeRec *pGeode = GEODEPTR(pScrni); + XF86VideoAdaptorPtr adapt; + GeodePortPrivRec *pPriv; + + adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(GeodePortPrivRec) + sizeof(DevUnion)); + + if (adapt == NULL) { + ErrorF("Couldn't create the rec\n"); + return NULL; + } + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + + adapt->name = "AMD Geode LX"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = ARRAY_SIZE(Formats); + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion *) (&adapt[1]); + pPriv = (GeodePortPrivRec *) (&adapt->pPortPrivates[1]); + adapt->pPortPrivates[0].ptr = (pointer) (pPriv); + adapt->pAttributes = Attributes; + adapt->nImages = ARRAY_SIZE(Images); + adapt->nAttributes = ARRAY_SIZE(Attributes); + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo= LXStopVideo; + adapt->SetPortAttribute = LXSetPortAttribute; + adapt->GetPortAttribute = LXGetPortAttribute; + adapt->QueryBestSize = LXQueryBestSize; + adapt->PutImage =LXPutImage; + + /* Use the common function */ + adapt->QueryImageAttributes = GeodeQueryImageAttributes; + + pPriv->filter = 0; + pPriv->colorKey = pGeode->videoKey; + pPriv->colorKeyMode = 0; + pPriv->videoStatus = 0; + + REGION_NULL(pScrn, &pPriv->clip); + + pGeode->adaptor = adapt; + + pGeode->BlockHandler = pScrn->BlockHandler; + pScrn->BlockHandler = LXVidBlockHandler; + + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE"); + xvFilter = MAKE_ATOM("XV_FILTER"); + + LXResetVideo(pScrni); + + return adapt; +} - dst_start = pGeode->FBBase + offset + left; - break; - } - s1offset = (top * srcPitch) + left; - -#if REINIT - /* update cliplist */ - REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); - if (pPriv->colorKeyMode == 0) { - /* draw these */ - XAAFillSolidRects(pScrni, pPriv->colorKey, GXcopy, ~0, - REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes)); - } - LXDisplayVideo(pScrni, id, offset, width, height, dstPitch, - Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); - } -#endif +/* Offscreen surface allocation */ - switch (id) { - case FOURCC_Y800: - LXCopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels); - break; - case FOURCC_YV12: - case FOURCC_I420: - LXCopyData420(buf + s1offset, dst_start, srcPitch, dstPitch, nlines, - npixels); - LXCopyData420(buf + s2offset, dst_start + d2offset, srcPitch2, - dstPitch2, nlines >> 1, npixels >> 1); - LXCopyData420(buf + s3offset, dst_start + d3offset, srcPitch2, - dstPitch2, nlines >> 1, npixels >> 1); - break; - case FOURCC_UYVY: - case FOURCC_YUY2: - default: - LXCopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels); - break; - } -#if !REINIT - /* update cliplist */ - REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); - if (pPriv->colorKeyMode == 0) { - /* draw these */ - XAAFillSolidRects(pScrni, pPriv->colorKey, GXcopy, ~0, - REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes)); - } - LXDisplayVideo(pScrni, id, offset, width, height, dstPitch, - Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); -#endif +struct OffscreenPrivRec +{ + void * area; + int offset; + Bool isOn; +}; -#if XV_PROFILE - UpdateCurrentTime(); - newtime = currentTime.milliseconds; - DBLOG(1, "PI %d\n", newtime - oldtime); -#endif +static int +LXDisplaySurface(XF86SurfacePtr surface, + short srcX, short srcY, short drawX, short drawY, + short srcW, short srcH, short drawW, short drawH, + RegionPtr clipBoxes) +{ + struct OffscreenPrivRec *pPriv = + (struct OffscreenPrivRec *) surface->devPrivate.ptr; -#if DBUF - pPriv->currentBuffer ^= 1; -#endif + ScrnInfoPtr pScrni = surface->pScrn; + GeodePortPrivRec *portPriv = GET_PORT_PRIVATE(pScrni); + + BoxRec dstBox; - pPriv->videoStatus = CLIENT_VIDEO_ON; - pGeode->OverlayON = TRUE; + dstBox.x1 = drawX; + dstBox.x2 = drawX + drawW; + dstBox.y1 = drawY; + dstBox.y2 = drawY + drawH; + if ((drawW <= 0) | (drawH <=0)) return Success; -} -/*---------------------------------------------------------------------------- - * LXQueryImageAttributes - * - * Description :This function is called to let the driver specify how data - * for a particular image of size width by height should be - * stored. - * - * Parameters. - * pScrni :Screen handler pointer having screen information. - * id :Id for the video format - * width :width of the image (can be modified by the driver) - * height :height of the image (can be modified by the driver) - * Returns : Size of the memory required for storing this image - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ -static int -LXQueryImageAttributes(ScrnInfoPtr pScrni, int id, unsigned short *w, - unsigned short *h, int *pitches, int *offsets) -{ - int size; - int tmp; - - if (*w > 1024) - *w = 1024; - if (*h > 1024) - *h = 1024; - - *w = (*w + 1) & ~1; - if (offsets) - offsets[0] = 0; - - switch (id) { - case FOURCC_YV12: - case FOURCC_I420: - *h = (*h + 1) & ~1; - size = (*w + 3) & ~3; - if (pitches) - pitches[0] = size; - size *= *h; - if (offsets) - offsets[1] = size; - tmp = ((*w >> 1) + 3) & ~3; - if (pitches) - pitches[1] = pitches[2] = tmp; - tmp *= (*h >> 1); - size += tmp; - if (offsets) - offsets[2] = size; - size += tmp; - break; - case FOURCC_UYVY: - case FOURCC_YUY2: - case FOURCC_Y800: - default: - size = *w << 1; - if (pitches) - pitches[0] = size; - size *= *h; - break; - } + /* Is this still valid? */ - DBLOG(1, "LXQueryImageAttributes(%d)= %d, %dx%d %d/%d/%d %d/%d/%d\n", - id, size, *w, *h, pitches[0], pitches[1], pitches[2], offsets[0], - offsets[1], offsets[2]); + dstBox.x1 -= pScrni->frameX0; + dstBox.x2 -= pScrni->frameX0; + dstBox.y1 -= pScrni->frameY0; + dstBox.y2 -= pScrni->frameY0; - return size; -} - -static void -LXBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) -{ - ScreenPtr pScrn = screenInfo.screens[i]; - ScrnInfoPtr pScrni = xf86Screens[i]; - GeodeRec *pGeode = GEODEPTR(pScrni); - GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); + xf86XVFillKeyHelper(pScrni->pScreen, portPriv->colorKey, clipBoxes); - pScrn->BlockHandler = pGeode->BlockHandler; - (*pScrn->BlockHandler) (i, blockData, pTimeout, pReadmask); - pScrn->BlockHandler = LXBlockHandler; + videoScratch.dstOffset = surface->offsets[0]; + videoScratch.dstPitch = surface->pitches[0]; - if (pPriv->videoStatus & TIMER_MASK) { - DBLOG(1, "LXBlockHandler(%d)\n", i); - LXAccelSync(pScrni); - UpdateCurrentTime(); - if (pPriv->videoStatus & OFF_TIMER) { - if (pPriv->offTime < currentTime.milliseconds) { - df_set_video_enable(0, 0); - pPriv->videoStatus = FREE_TIMER; - pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; - } - } else { /* FREE_TIMER */ - if (pPriv->freeTime < currentTime.milliseconds) { - if (pPriv->area) { - xf86FreeOffscreenArea(pPriv->area); - pPriv->area = NULL; - } - pPriv->videoStatus = 0; - } - } - } -} + LXDisplayVideo(pScrni, surface->id, surface->width, surface->height, + &dstBox, srcW, srcH, drawW, drawH); -/****************** Offscreen stuff ***************/ + pPriv->isOn = TRUE; + + if (portPriv->videoStatus & CLIENT_VIDEO_ON) { + REGION_EMPTY(pScrni->pScreen, &portPriv->clip); + UpdateCurrentTime(); + portPriv->videoStatus = FREE_TIMER; + portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; + } -typedef struct -{ - FBAreaPtr area; - FBLinearPtr linear; - Bool isOn; + return Success; } -OffscreenPrivRec, *OffscreenPrivPtr; - -/*---------------------------------------------------------------------------- - * LXAllocateSurface - * - * Description :This function allocates an area of w by h in the offscreen - * Parameters. - * pScrni :Screen handler pointer having screen information. - * - * Returns :None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ -static int +static int LXAllocateSurface(ScrnInfoPtr pScrni, int id, unsigned short w, - unsigned short h, XF86SurfacePtr surface) + unsigned short h, XF86SurfacePtr surface) { - FBAreaPtr area; - int pitch, fbpitch, numlines; - OffscreenPrivRec *pPriv; + GeodeRec *pGeode = GEODEPTR(pScrni); + void * area = NULL; + int pitch, lines; + unsigned offset; + struct OffscreenPrivRec *pPriv; - DBLOG(1, "LXAllocateSurface(id %d, %dx%d)\n", id, w, h); + if (w > 1024 || h > 1024) + return BadAlloc; - if ((w > 1024) || (h > 1024)) - return BadAlloc; + /* The width needs to be word aligned */ + w = (w + 1) & ~1; - w = (w + 1) & ~1; - pitch = ((w << 1) + 15) & ~15; - fbpitch = pScrni->bitsPerPixel * pScrni->displayWidth >> 3; - numlines = ((pitch * h) + fbpitch - 1) / fbpitch; + pitch = ((w << 1) + 15) & ~15; + lines = ((pitch * h) + (pGeode->Pitch - 1)) / pGeode->Pitch; + + offset = LXAllocateVidMem(pScrni, &area, lines); - if (!(area = LXAllocateMemory(pScrni, NULL, numlines))) - return BadAlloc; + if (offset == 0) { + ErrorF("Error while allocating an offscreen region.\n"); + return BadAlloc; + } - surface->width = w; - surface->height = h; + surface->width = w; + surface->height = h; + + surface->pitches = xalloc(sizeof(int)); - if (!(surface->pitches = xalloc(sizeof(int)))) - return BadAlloc; - if (!(surface->offsets = xalloc(sizeof(int)))) { - xfree(surface->pitches); - return BadAlloc; - } - if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { - xfree(surface->pitches); - xfree(surface->offsets); - return BadAlloc; - } + surface->offsets = xalloc(sizeof(int)); + + pPriv = xalloc(sizeof(struct OffscreenPrivRec)); + if (pPriv && surface->pitches && surface->offsets) { + pPriv->area = area; + pPriv->offset = offset; + pPriv->isOn = FALSE; - + surface->pScrn = pScrni; surface->id = id; surface->pitches[0] = pitch; - surface->offsets[0] = area->box.y1 * fbpitch; + surface->offsets[0] = offset; surface->devPrivate.ptr = (pointer) pPriv; - + return Success; + } + + if (surface->offsets) + xfree(surface->offsets); + + if (surface->pitches) + xfree(surface->pitches); + + if (area) + exaOffscreenFree(pScrni->pScreen, area); + + return BadAlloc; } static int -LXStopSurface(XF86SurfacePtr surface) +LXStopSurface(XF86SurfacePtr surface) { - OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; + struct OffscreenPrivRec *pPriv = (struct OffscreenPrivRec *) + surface->devPrivate.ptr; - DBLOG(1, "LXStopSurface()\n"); - - if (pPriv->isOn) { - pPriv->isOn = FALSE; - } - - return Success; + pPriv->isOn = FALSE; + return Success; } static int LXFreeSurface(XF86SurfacePtr surface) { - OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; - - DBLOG(1, "LXFreeSurface()\n"); + struct OffscreenPrivRec *pPriv = (struct OffscreenPrivRec *) + surface->devPrivate.ptr; + ScrnInfoPtr pScrni = surface->pScrn; - if (pPriv->isOn) - LXStopSurface(surface); + if (pPriv->isOn) + LXStopSurface(surface); - xf86FreeOffscreenArea(pPriv->area); - xfree(surface->pitches); - xfree(surface->offsets); - xfree(surface->devPrivate.ptr); + if (pPriv->area) + exaOffscreenFree(pScrni->pScreen, pPriv->area); - return Success; + xfree(surface->pitches); + xfree(surface->offsets); + xfree(surface->devPrivate.ptr); + + return Success; } static int @@ -1375,98 +905,78 @@ LXSetSurfaceAttribute(ScrnInfoPtr pScrni, Atom attribute, INT32 value) (pointer) (GET_PORT_PRIVATE(pScrni))); } -static int -LXDisplaySurface(XF86SurfacePtr surface, short src_x, short src_y, - short drw_x, short drw_y, short src_w, short src_h, - short drw_w, short drw_h, RegionPtr clipBoxes) -{ - OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; - ScrnInfoPtr pScrni = surface->pScrn; - GeodePortPrivRec *portPriv = GET_PORT_PRIVATE(pScrni); - INT32 x1, y1, x2, y2; - BoxRec dstBox; - - DBLOG(1, "LXDisplaySurface(src %d,%d %dx%d, dst %d,%d %dx%d)\n", - src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h); - - DEBUGMSG(0, (0, X_NONE, "DisplaySuface\n")); - x1 = src_x; - x2 = src_x + src_w; - y1 = src_y; - y2 = src_y + src_h; - - dstBox.x1 = drw_x; - dstBox.x2 = drw_x + drw_w; - dstBox.y1 = drw_y; - dstBox.y2 = drw_y + drw_h; - - if ((x1 >= x2) || (y1 >= y2)) - return Success; - - dstBox.x1 -= pScrni->frameX0; - dstBox.x2 -= pScrni->frameX0; - dstBox.y1 -= pScrni->frameY0; - dstBox.y2 -= pScrni->frameY0; - - xf86XVFillKeyHelper(pScrni->pScreen, portPriv->colorKey, clipBoxes); - - LXDisplayVideo(pScrni, surface->id, surface->offsets[0], - surface->width, surface->height, surface->pitches[0], - x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); - - pPriv->isOn = TRUE; - if (portPriv->videoStatus & CLIENT_VIDEO_ON) { - REGION_EMPTY(pScrni->pScreen, &portPriv->clip); - UpdateCurrentTime(); - portPriv->videoStatus = FREE_TIMER; - portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; - } - - return Success; -} -/*---------------------------------------------------------------------------- - * LXInitOffscreenImages - * - * Description :This function sets up the offscreen memory management.It fills - * in the XF86OffscreenImagePtr structure with functions to handle - * offscreen memory operations. - * - * Parameters. - * pScrn :Screen handler pointer having screen information. - * - * Returns : None - * - * Comments :None - * -*---------------------------------------------------------------------------- -*/ static void -LXInitOffscreenImages(ScreenPtr pScrn) +LXInitOffscreenImages(ScreenPtr pScrn) { - XF86OffscreenImagePtr offscreenImages; - - DBLOG(1, "LXInitOffscreenImages()\n"); - - /* need to free this someplace */ - if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) - return; - - offscreenImages[0].image = &Images[0]; - offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; - offscreenImages[0].alloc_surface = LXAllocateSurface; - offscreenImages[0].free_surface = LXFreeSurface; - offscreenImages[0].display = LXDisplaySurface; - offscreenImages[0].stop = LXStopSurface; - offscreenImages[0].setAttribute = LXSetSurfaceAttribute; - offscreenImages[0].getAttribute = LXGetSurfaceAttribute; - offscreenImages[0].max_width = 1024; - offscreenImages[0].max_height = 1024; - offscreenImages[0].num_attributes = NUM_ATTRIBUTES; - offscreenImages[0].attributes = Attributes; - - xf86XVRegisterOffscreenImages(pScrn, offscreenImages, 1); + XF86OffscreenImagePtr offscreenImages; + + /* need to free this someplace */ + if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) + return; + + offscreenImages[0].image = &Images[0]; + offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + offscreenImages[0].alloc_surface = LXAllocateSurface; + offscreenImages[0].free_surface = LXFreeSurface; + offscreenImages[0].display = LXDisplaySurface; + offscreenImages[0].stop = LXStopSurface; + offscreenImages[0].setAttribute = LXSetSurfaceAttribute; + offscreenImages[0].getAttribute = LXGetSurfaceAttribute; + offscreenImages[0].max_width = 1024; + offscreenImages[0].max_height = 1024; + offscreenImages[0].num_attributes = ARRAY_SIZE(Attributes); + offscreenImages[0].attributes = Attributes; + + xf86XVRegisterOffscreenImages(pScrn, offscreenImages, 1); +} + +void +LXInitVideo(ScreenPtr pScrn) +{ + GeodeRec *pGeode; + ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + int num_adaptors; + + pGeode = GEODEPTR(pScrni); + + if (pGeode->NoAccel) { + ErrorF("Cannot run Xv without accelerations!\n"); + return; + } + + if (!(newAdaptor = LXSetupImageVideo(pScrn))) { + ErrorF("Error while setting up the adaptor.\n"); + return; + } + + LXInitOffscreenImages(pScrn); + + num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors); + + if (!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + newAdaptors = + xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *)); + + if (newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + else + ErrorF("Memory error while setting up the adaptor\n"); + } + + if (num_adaptors) + xf86XVScreenInit(pScrn, adaptors, num_adaptors); + + if (newAdaptors) + xfree(newAdaptors); } - -#endif /* !XvExtension */ -#endif /* !AMD_V4L2_VIDEO */ diff --git a/src/amd_msr.c b/src/amd_msr.c new file mode 100644 index 0000000..12b9f73 --- /dev/null +++ b/src/amd_msr.c @@ -0,0 +1,65 @@ +#define _LARGEFILE64_SOURCE +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/errno.h> +#include "os.h" + +static int _msr_open(void) +{ + static int msrfd = 0; + + if (msrfd == 0) { + msrfd = open("/dev/cpu/0/msr", O_RDWR); + if (msrfd == -1) + ErrorF("Unable to open /dev/cpu/0/msr: %d\n", errno); + } + + return msrfd; +} + +int GeodeReadMSR(unsigned long addr, unsigned long *lo, unsigned long *hi) +{ + unsigned int data[2]; + int fd = _msr_open(); + int ret; + + if (fd == -1) + return -1; + + ret = lseek64(fd, (off64_t) addr, SEEK_SET); + + if (ret == -1) + return -1; + + ret = read(fd, (void *) data, sizeof(data)); + + if (ret != 8) + return -1; + + *hi = data[1]; + *lo = data[0]; + + return 0; +} + +int GeodeWriteMSR(unsigned long addr, unsigned long lo, unsigned long hi) +{ + unsigned int data[2]; + int fd = _msr_open(); + + if (fd == -1) + return - 1; + + if (lseek64(fd, (off64_t) addr, SEEK_SET) == -1) + return -1; + + data[0] = lo; + data[1] = hi; + + if (write(fd, (void *) data, 8) != 8) + return -1; + + return 0; +} diff --git a/src/cim/cim_defs.h b/src/cim/cim_defs.h index 176bdb4..eea2f49 100644 --- a/src/cim/cim_defs.h +++ b/src/cim/cim_defs.h @@ -282,6 +282,33 @@ wrmsr(addr, val1, val2); \ } +#elif CIMARRON_MSR_HOOKS + + +#define MSR_READ(msr_reg, device_add, data64_ptr) \ +{ \ + unsigned long addr, val1, val2; \ + \ + addr = device_add | msr_reg; \ + if (cim_rdmsr) { \ + cim_rdmsr (addr, &val1, &val2); \ + \ + ((Q_WORD *)(data64_ptr))->high = val2; \ + ((Q_WORD *)(data64_ptr))->low = val1; \ + } \ +} + +#define MSR_WRITE(msr_reg, device_add, data64_ptr) \ +{ \ + unsigned long addr, val1, val2; \ + \ + val2 = ((Q_WORD *)(data64_ptr))->high; \ + val1 = ((Q_WORD *)(data64_ptr))->low; \ + \ + addr = (device_add & 0xFFFF0000) | (unsigned long)msr_reg; \ + if (cim_wrmsr) \ + cim_wrmsr(addr, val1, val2); \ +} #endif #endif /* #ifdef CIMARRON_INCLUDE_MSR_MACROS */ @@ -728,4 +755,7 @@ cim_outb(unsigned short port, unsigned char data) #endif /* CIMARRON_INCLUDE_IO_MACROS */ +extern void (*cim_rdmsr)(unsigned long, unsigned long *, unsigned long *); +extern void (*cim_wrmsr)(unsigned long, unsigned long, unsigned long); + #endif diff --git a/src/cim/cim_defs.h.rej b/src/cim/cim_defs.h.rej deleted file mode 100644 index 3d892c6..0000000 --- a/src/cim/cim_defs.h.rej +++ /dev/null @@ -1,45 +0,0 @@ -*************** -*** 208,227 **** - *-----------------------------------------------------------------*/ - - #define MSR_WRITE(msr,adr,val) \ -- { int d0, d1, d2, d3, d4; \ - __asm__ __volatile__( \ - " mov $0x0AC1C, %%edx\n" \ - " mov $0xFC530007, %%eax\n" \ - " out %%eax,%%dx\n" \ - " add $2,%%dl\n" \ -- " mov %5, %4\n" \ -- " mov 0(%6), %1\n" \ -- " mov 4(%6), %0\n" \ -- " xor %3, %3\n" \ - " xor %2, %2\n" \ -- " out %%ax, %%dx" \ -- : "=a" (d0), "=b" (d1), "=&D" (d2), "=&S" (d3), "=c" (d4) \ -- : "2" (msr | adr), "3" (val)); \ - } - - #elif CIMARRON_MSR_KERNEL_ROUTINE ---- 208,229 ---- - *-----------------------------------------------------------------*/ - - #define MSR_WRITE(msr,adr,val) \ -+ { int d0, d1, d2, d3; \ - __asm__ __volatile__( \ -+ " push %%ebx\n" \ - " mov $0x0AC1C, %%edx\n" \ - " mov $0xFC530007, %%eax\n" \ - " out %%eax,%%dx\n" \ - " add $2,%%dl\n" \ -+ " mov %4, %3\n" \ -+ " mov 0(%5), %%ebx\n" \ -+ " mov 4(%5), %0\n" \ - " xor %2, %2\n" \ -+ " xor %1, %1\n" \ -+ " out %%ax, %%dx\n" \ -+ " pop %%ebx\n" \ -+ : "=a" (d0), "=&D" (d1), "=&S" (d2), "=c" (d3) \ -+ : "1" (msr | adr), "2" (val)); \ - } - - #elif CIMARRON_MSR_KERNEL_ROUTINE diff --git a/src/cim/cim_gp.c b/src/cim/cim_gp.c index fc105c9..04c901e 100644 --- a/src/cim/cim_gp.c +++ b/src/cim/cim_gp.c @@ -1151,6 +1151,7 @@ gp_screen_to_screen_blt(unsigned long dstoffset, unsigned long srcoffset, gp3_cmd_current = gp3_cmd_next; } + /*--------------------------------------------------------------------------- * gp_screen_to_screen_convert * @@ -3390,3 +3391,192 @@ gp_restore_state(GP_SAVE_RESTORE * gp_state) gp_set_command_buffer_base(gp_state->cmd_base, gp_state->cmd_top, gp_state->cmd_bottom); } + +/* This is identical to gp_antialiased_text, except we support all one + pass alpha operations similar to gp_set_alpha_operation */ + + +void +gp_blend_mask_blt(unsigned long dstoffset, unsigned long srcx, + unsigned long width, unsigned long height, + unsigned char *data, long stride, int operation, + int fourbpp) +{ + unsigned long indent, temp; + unsigned long total_dwords, size_dwords; + unsigned long dword_count, byte_count; + unsigned long size = ((width << 16) | height); + unsigned long ch3_offset, srcoffset; + unsigned long base, depth_flag; + + base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) | + (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK); + + /* ENABLE ALL RELEVANT REGISTERS */ + /* We override the raster mode register to force the */ + /* correct alpha blend */ + + gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE | + GP3_BLT_HDR_DST_OFF_ENABLE | + GP3_BLT_HDR_WIDHI_ENABLE | + GP3_BLT_HDR_CH3_OFF_ENABLE | + GP3_BLT_HDR_CH3_STR_ENABLE | + GP3_BLT_HDR_CH3_WIDHI_ENABLE | + GP3_BLT_HDR_BASE_OFFSET_ENABLE | GP3_BLT_HDR_BLT_MODE_ENABLE; + + /* CALCULATIONS BASED ON ALPHA DEPTH */ + /* Although most antialiased text is 4BPP, the hardware supports */ + /* a full 8BPP. Either case is supported by this routine. */ + + if (fourbpp) { + depth_flag = GP3_CH3_SRC_4BPP_ALPHA; + indent = (srcx >> 1); + srcoffset = (indent & ~3L); + indent &= 3; + ch3_offset = indent | ((srcx & 1) << 25); + + temp = ((width + (srcx & 1) + 1) >> 1) + indent; + } else { + depth_flag = GP3_CH3_SRC_8BPP_ALPHA; + indent = srcx; + srcoffset = (indent & ~3L); + indent &= 3; + ch3_offset = indent; + + temp = width + indent; + } + + total_dwords = (temp + 3) >> 2; + size_dwords = (total_dwords << 2) + 8; + dword_count = (temp >> 2); + byte_count = (temp & 3); + + /* SET RASTER MODE REGISTER */ + /* Alpha blending will only apply to RGB when no alpha component is present. */ + /* As 8BPP is not supported for this routine, the only alpha-less mode is */ + /* 5:6:5. */ + + if (gp3_bpp == GP3_RM_BPPFMT_565) { + WRITE_COMMAND32(GP3_BLT_RASTER_MODE, + gp3_bpp | + GP3_RM_ALPHA_TO_RGB | + GP3_RM_ALPHA_A_PLUS_BETA_B | GP3_RM_SELECT_ALPHA_CHAN_3); + } else { + WRITE_COMMAND32(GP3_BLT_RASTER_MODE, + gp3_bpp | + GP3_RM_ALPHA_ALL | + ((unsigned long) operation << 20) | GP3_RM_SELECT_ALPHA_CHAN_3); + } + + /* WRITE ALL REMAINING REGISTERS */ + + WRITE_COMMAND32(GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF)); + WRITE_COMMAND32(GP3_BLT_CH3_OFFSET, ch3_offset); + WRITE_COMMAND32(GP3_BLT_WID_HEIGHT, size); + WRITE_COMMAND32(GP3_BLT_CH3_WIDHI, size); + WRITE_COMMAND32(GP3_BLT_BASE_OFFSET, base); + WRITE_COMMAND32(GP3_BLT_CH3_MODE_STR, GP3_CH3_C3EN | + GP3_CH3_HST_SRC_ENABLE | + depth_flag | ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20)); + WRITE_COMMAND32(GP3_BLT_MODE, gp3_blt_mode | GP3_BM_DST_REQ); + + /* START THE BLT */ + + WRITE_COMMAND32(GP3_BLT_CMD_HEADER, gp3_cmd_header); + WRITE_GP32(GP3_CMD_WRITE, gp3_cmd_next); + gp3_cmd_current = gp3_cmd_next; + + /* WRITE DATA LINE BY LINE + * Each line will be created as a separate command buffer entry to allow + * line-by-line wrapping and to allow simultaneous rendering by the HW. + */ + + if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE && + (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72)) { + /* UPDATE THE COMMAND POINTER */ + + cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current; + + /* CHECK IF A WRAP WILL BE NEEDED */ + + gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8; + + if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE) { + gp3_cmd_next = gp3_cmd_top; + + GP3_WAIT_WRAP(temp); + WRITE_COMMAND32(0, + GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP | + GP3_DATA_LOAD_HDR_ENABLE); + } else { + GP3_WAIT_PRIMITIVE(temp); + WRITE_COMMAND32(0, + GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE); + } + + /* WRITE DWORD COUNT */ + + WRITE_COMMAND32(4, + GP3_CH3_HOST_SOURCE_TYPE | (total_dwords * height)); + + while (height--) { + /* WRITE DATA */ + + WRITE_COMMAND_STRING32(8, data, srcoffset, dword_count); + WRITE_COMMAND_STRING8(8 + (dword_count << 2), data, + srcoffset + (dword_count << 2), byte_count); + + srcoffset += stride; + cim_cmd_ptr += total_dwords << 2; + } + + WRITE_GP32(GP3_CMD_WRITE, gp3_cmd_next); + gp3_cmd_current = gp3_cmd_next; + } else { + while (height--) { + /* UPDATE THE COMMAND POINTER + * The WRITE_COMMANDXX macros use a pointer to the current buffer + * space. This is created by adding gp3_cmd_current to the base + * pointer. + */ + + cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current; + + /* CHECK IF A WRAP WILL BE NEEDED */ + + gp3_cmd_next = gp3_cmd_current + size_dwords; + if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE) { + gp3_cmd_next = gp3_cmd_top; + + /* WAIT FOR HARDWARE */ + + GP3_WAIT_WRAP(temp); + WRITE_COMMAND32(0, + GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP | + GP3_DATA_LOAD_HDR_ENABLE); + } else { + /* WAIT FOR AVAILABLE SPACE */ + + GP3_WAIT_PRIMITIVE(temp); + WRITE_COMMAND32(0, + GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE); + } + + /* WRITE DWORD COUNT */ + + WRITE_COMMAND32(4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords); + + /* WRITE DATA */ + + WRITE_COMMAND_STRING32(8, data, srcoffset, dword_count); + WRITE_COMMAND_STRING8(8 + (dword_count << 2), data, + srcoffset + (dword_count << 2), byte_count); + + /* UPDATE POINTERS */ + + srcoffset += stride; + WRITE_GP32(GP3_CMD_WRITE, gp3_cmd_next); + gp3_cmd_current = gp3_cmd_next; + } + } +} diff --git a/src/cim/cim_msr.c b/src/cim/cim_msr.c index 9e46a87..4a6b72d 100644 --- a/src/cim/cim_msr.c +++ b/src/cim/cim_msr.c @@ -50,7 +50,7 @@ GEODELINK_NODE msr_dev_lookup[MSR_DEVICE_EMPTY]; int msr_init_table(void) { - Q_WORD msr_value; + Q_WORD msr_value = {0, 0}; unsigned int i, j; int return_value = CIM_STATUS_OK; @@ -157,7 +157,7 @@ msr_create_geodelink_table(GEODELINK_NODE * gliu_nodes) int glcp_count = 0; int usb_count = 0; int mpci_count = 0; - Q_WORD msr_value; + Q_WORD msr_value = {0, 0}; /* ALL THREE GLIUS ARE IN ONE ARRAY */ /* Entries 0-7 contain the port information for GLIU0, entries */ diff --git a/src/cim/cim_rtns.h b/src/cim/cim_rtns.h index ce149cd..6fecb4b 100644 --- a/src/cim/cim_rtns.h +++ b/src/cim/cim_rtns.h @@ -125,7 +125,10 @@ extern "C" void gp_antialiased_text(unsigned long dstoffset, unsigned long srcx, unsigned long width, unsigned long height, unsigned char *data, long stride, int fourbpp); - void gp_masked_blt(unsigned long dstoffset, unsigned long width, + void gp_blend_mask_blt(unsigned long dstoffset, unsigned long srcx, + unsigned long width, unsigned long height, unsigned char *data, + long stride, int operation, int fourbpp); + void gp_masked_blt(unsigned long dstoffset, unsigned long width, unsigned long height, unsigned long mono_srcx, unsigned long color_srcx, unsigned char *mono_mask, unsigned char *color_data, long mono_pitch, long color_pitch); diff --git a/src/cimarron.c b/src/cimarron.c index 76d8615..65df4d2 100644 --- a/src/cimarron.c +++ b/src/cimarron.c @@ -130,8 +130,9 @@ #define CIMARRON_INCLUDE_MSR_MACROS #define CIMARRON_MSR_DIRECT_ASM 0 #define CIMARRON_MSR_VSA_IO 0 -#define CIMARRON_MSR_ABSTRACTED_ASM 1 +#define CIMARRON_MSR_ABSTRACTED_ASM 0 #define CIMARRON_MSR_KERNEL_ROUTINE 0 +#define CIMARRON_MSR_HOOKS 1 #define CIMARRON_INCLUDE_IO_MACROS #define CIMARRON_IO_DIRECT_ACCESS 0 @@ -173,6 +174,14 @@ unsigned char *cim_vid_ptr = (unsigned char *)0; unsigned char *cim_vip_ptr = (unsigned char *)0; unsigned char *cim_vg_ptr = (unsigned char *)0; +/* Define hooks for reading and writing MSRs - this is a major hack + * to share the MSR code with the GX code */ + +#ifdef CIMARRON_MSR_HOOKS +void (*cim_rdmsr)(unsigned long, unsigned long *, unsigned long *); +void (*cim_wrmsr)(unsigned long, unsigned long, unsigned long); +#endif + /*----------------------------------------------------------------------*/ /* INCLUDE RELEVANT CIMARRON HEADERS */ /*----------------------------------------------------------------------*/ diff --git a/src/durango.c b/src/durango.c index 9fcfa6f..77ba16a 100644 --- a/src/durango.c +++ b/src/durango.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2003-2005 Advanced Micro Devices, Inc. +/* Copyright (c) 2003-2006 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -23,159 +23,71 @@ * software without specific prior written permission. * */ -/* - * This is the main file used to add Durango graphics support to a software - * project. The main reason to have a single file include the other files - * is that it centralizes the location of the compiler options. This file - * should be tuned for a specific implementation, and then modified as needed - * for new Durango releases. The releases.txt file indicates any updates to - * this main file, such as a new definition for a new hardware platform. - * - * In other words, this file should be copied from the Durango source files - * once when a software project starts, and then maintained as necessary. - * It should not be recopied with new versions of Durango unless the - * developer is willing to tune the file again for the specific project. - * */ +/* The previous version of this file was way more complex then it should have + been - remove the unnessesary #defines and routines, and concentrate on + Linux for now. +*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif -/* COMPILER OPTIONS - * These compiler options specify how the Durango routines are compiled - * for the different hardware platforms. For best performance, a driver - * would build for a specific platform. The "dynamic" switches are set - * by diagnostic applications such as Darwin that will run on a variety - * of platforms and use the appropriate code at runtime. Each component - * may be separately dynamic, so that a driver has the option of being - * tuned for a specific 2D accelerator, but will still run with a variety - * of chipsets. - */ - -#define GFX_DISPLAY_DYNAMIC 0 /* runtime selection */ -#define GFX_DISPLAY_GU1 0 /* 1st generation display controller */ -#define GFX_DISPLAY_GU2 1 /* 2nd generation display controller */ -#define GFX_DISPLAY_GU3 0 /* 3nd generation display controller */ - -#define GFX_INIT_DYNAMIC 0 /* runtime selection */ -#define GFX_INIT_GU1 0 /* Geode family */ -#define GFX_INIT_GU2 1 /* Redcloud */ -#define GFX_INIT_GU3 0 /* Castle */ - -#define GFX_MSR_DYNAMIC 1 /* runtime selection */ -#define GFX_MSR_REDCLOUD 1 /* Redcloud */ - -#define GFX_2DACCEL_DYNAMIC 0 /* runtime selection */ -#define GFX_2DACCEL_GU1 0 /* 1st generation 2D accelerator */ -#define GFX_2DACCEL_GU2 1 /* 2nd generation 2D accelerator */ - -#define GFX_VIDEO_DYNAMIC 0 /* runtime selection */ -#define GFX_VIDEO_CS5530 0 /* support for CS5530 */ -#define GFX_VIDEO_SC1200 0 /* support for SC1200 */ -#define GFX_VIDEO_REDCLOUD 1 /* support for Redcloud */ -#define GFX_VIDEO_CASTLE 0 /* support for Castle */ - -#define GFX_VIP_DYNAMIC 0 /* runtime selection */ -#define GFX_VIP_SC1200 0 /* support for SC1200 */ - -#define GFX_DECODER_DYNAMIC 0 /* runtime selection */ -#define GFX_DECODER_SAA7114 0 /* Philips SAA7114 decoder */ - -#define GFX_TV_DYNAMIC 0 /* runtime selection */ -#define GFX_TV_FS451 0 /* Focus Enhancements FS450 */ -#define GFX_TV_SC1200 0 /* SC1200 integrated TV encoder */ - -#define GFX_I2C_DYNAMIC 0 /* runtime selection */ -#define GFX_I2C_ACCESS 0 /* support for ACCESS.BUS */ -#define GFX_I2C_GPIO 0 /* support for CS5530 GPIOs */ - -#define GFX_VGA_DYNAMIC 0 /* runtime selection */ -#define GFX_VGA_GU1 0 /* 1st generation graphics unit */ - -#define FB4MB 1 /* Set to use 4Mb video ram for - * Pyramid */ - -#define GFX_NO_IO_IN_WAIT_MACROS 1 /* Set to remove I/O accesses in GP - * bit testing */ - -/* ROUTINES TO READ VALUES - * These are routines used by Darwin or other diagnostics to read the - * current state of the hardware. Display drivers or embedded applications - * can reduce the size of the Durango code by not including these routines. - */ -#define GFX_READ_ROUTINES 1 /* add routines to read values */ - -/* HEADER FILE FOR DURANGO ROUTINE DEFINITIONS - * Needed since some of the Durango routines call other Durango routines. - * Also defines the size of chipset array (GFX_CSPTR_SIZE). - */ -#include "gfx_rtns.h" /* routine definitions */ -#include "gfx_priv.h" +#define _LARGEFILE64_SOURCE -/* VARIABLES USED FOR RUNTIME SELECTION - * If part of the graphics subsystem is declared as dynamic, then the - * following variables are used to specify which platform has been detected. - * The variables are set in the "gfx_detect_cpu" routine. The values should - * be bit flags to allow masks to be used to check for multiple platforms. - */ +#include <unistd.h> +#include <errno.h> +#include <xf86_ansic.h> +#include <compiler.h> -#if GFX_DISPLAY_DYNAMIC -int gfx_display_type = 0; -#endif +/* Compiler options */ -#if GFX_INIT_DYNAMIC -int gfx_init_type = 0; -#endif -#if GFX_MSR_DYNAMIC -int gfx_msr_type = 0; -#endif +#define GFX_DISPLAY_GU1 0 /* 1st generation display controller */ +#define GFX_DISPLAY_GU2 1 /* 2nd generation display controller */ -#if GFX_2DACCEL_DYNAMIC -int gfx_2daccel_type = 0; -#endif +#define GFX_INIT_DYNAMIC 0 /* runtime selection */ +#define GFX_INIT_GU1 0 /* SC1200/GX1 */ +#define GFX_INIT_GU2 1 /* GX */ -#if GFX_VIDEO_DYNAMIC -int gfx_video_type = 0; -#endif +#define GFX_MSR_DYNAMIC 0 /* runtime selection */ +#define GFX_MSR_REDCLOUD 1 /* GX */ -#if GFX_VIP_DYNAMIC -int gfx_vip_type = 0; -#endif +#define GFX_2DACCEL_DYNAMIC 0 /* runtime selection */ +#define GFX_2DACCEL_GU1 0 /* 1st generation 2D accelerator */ +#define GFX_2DACCEL_GU2 1 /* 2nd generation 2D accelerator */ -#if GFX_DECODER_DYNAMIC -int gfx_decoder_type = 0; -#endif +#define GFX_VIDEO_DYNAMIC 0 /* runtime selection */ +#define GFX_VIDEO_CS5530 0 /* support for CS5530 */ +#define GFX_VIDEO_SC1200 0 /* support for SC1200 */ +#define GFX_VIDEO_REDCLOUD 1 /* support for GX */ -#if GFX_TV_DYNAMIC -int gfx_tv_type = 0; -#endif +#define GFX_VIP_DYNAMIC 0 /* runtime selection */ +#define GFX_VIP_SC1200 0 /* support for SC1200 */ -#if GFX_I2C_DYNAMIC -int gfx_i2c_type = 0; -#endif +#define GFX_DECODER_DYNAMIC 0 /* runtime selection */ +#define GFX_DECODER_SAA7114 0 /* Philips SAA7114 decoder */ -#if GFX_VGA_DYNAMIC -int gfx_vga_type = 0; -#endif +#define GFX_TV_DYNAMIC 0 /* runtime selection */ +#define GFX_TV_FS451 0 /* Focus Enhancements FS450 */ +#define GFX_TV_SC1200 0 /* SC1200 integrated TV encoder */ + +#define GFX_I2C_DYNAMIC 0 /* runtime selection */ +#define GFX_I2C_ACCESS 0 /* support for ACCESS.BUS */ +#define GFX_I2C_GPIO 0 /* support for CS5530 GPIOs */ -/* DEFINE POINTERS TO MEMORY MAPPED REGIONS - * These pointers are used by the Durango routines to access the hardware. - * The variables must be set by the project's initialization code after - * mapping the regions in the appropriate manner. - */ - -/* DEFINE VIRTUAL ADDRESSES */ -/* Note: These addresses define the starting base expected by all */ -/* Durango offsets. Under an OS that requires these pointers */ -/* to be mapped to linear addresses (i.e Windows), it may not */ -/* be possible to keep these base offsets. In these cases, */ -/* the addresses are modified to point to the beginning of the */ -/* relevant memory region and the access macros are adjusted */ -/* to subtract the offset from the default base. For example, */ -/* the register pointer could be moved to be 0x40008000, while */ -/* the WRITE_REG* macros are modified to subtract 0x8000 from */ -/* the offset. */ +#define GFX_VGA_DYNAMIC 0 /* runtime selection */ +#define GFX_VGA_GU1 0 /* 1st generation graphics unit */ + +#define FB4MB 1 /* Set to use 4Mb vid ram for Pyramid */ + +#define GFX_NO_IO_IN_WAIT_MACROS 1 /* Set to remove I/O accesses in GP + bit testing */ +#define GFX_READ_ROUTINES 1 + +#include "gfx_rtns.h" +#include "gfx_priv.h" +#include "gfx_regs.h" +#include "gfx_defs.h" unsigned char *gfx_virt_regptr = (unsigned char *)0x40000000; unsigned char *gfx_virt_fbptr = (unsigned char *)0x40800000; @@ -184,31 +96,11 @@ unsigned char *gfx_virt_vipptr = (unsigned char *)0x40015000; unsigned char *gfx_virt_spptr = (unsigned char *)0x40000000; unsigned char *gfx_virt_gpptr = (unsigned char *)0x40000000; -/* DEFINE PHYSICAL ADDRESSES */ - unsigned char *gfx_phys_regptr = (unsigned char *)0x40000000; unsigned char *gfx_phys_fbptr = (unsigned char *)0x40800000; unsigned char *gfx_phys_vidptr = (unsigned char *)0x40010000; unsigned char *gfx_phys_vipptr = (unsigned char *)0x40015000; -/* HEADER FILE FOR GRAPHICS REGISTER DEFINITIONS - * This contains only constant definitions, so it should be able to be - * included in any software project as is. - */ -#include "gfx_regs.h" /* graphics register definitions */ - -/* HEADER FILE FOR REGISTER ACCESS MACROS - * This file contains the definitions of the WRITE_REG32 and similar macros - * used by the Durango routines to access the hardware. The file assumes - * that the environment can handle 32-bit pointer access. If this is not - * the case, or if there are special requirements, then this header file - * should not be included and the project must define the macros itself. - * (A project may define WRITE_REG32 to call a routine, for example). - */ -#include "gfx_defs.h" /* register access macros */ -#include <xf86_ansic.h> -#include <compiler.h> - #define INB(port) inb(port) #define INW(port) inw(port) #define IND(port) inl(port) @@ -216,55 +108,45 @@ unsigned char *gfx_phys_vipptr = (unsigned char *)0x40015000; #define OUTW(port,data) outw(port, data) #define OUTD(port,data) outl(port, data) -unsigned char gfx_inb(unsigned short port); -unsigned short gfx_inw(unsigned short port); -unsigned long gfx_ind(unsigned short port); -void gfx_outb(unsigned short port, unsigned char data); -void gfx_outw(unsigned short port, unsigned short data); -void gfx_outd(unsigned short port, unsigned long data); - -unsigned char +inline unsigned char gfx_inb(unsigned short port) { return inb(port); } -unsigned short +inline unsigned short gfx_inw(unsigned short port) { return inw(port); } -unsigned long +inline unsigned long gfx_ind(unsigned short port) { return inl(port); } -void +inline void gfx_outb(unsigned short port, unsigned char data) { outb(port, data); } -void +inline void gfx_outw(unsigned short port, unsigned short data) { outw(port, data); } -void +inline void gfx_outd(unsigned short port, unsigned long data) { outl(port, data); } -/*----------------------------------------------------------------- - * gfx_msr_asm_read - * Read the contents of a 64 bit MSR into address pointers - *-----------------------------------------------------------------*/ +/* These routines use VSA to read the MSRs - these are a second resort to the Linux MSR method */ -#define gfx_msr_asm_read(msr,adr,high,low) \ +#define vsa_msr_read(msr,adr,high,low) \ __asm__ __volatile__( \ " mov $0x0AC1C, %%edx\n" \ " mov $0xFC530007, %%eax\n" \ @@ -274,12 +156,8 @@ gfx_outd(unsigned short port, unsigned long data) : "=a" (*(low)), "=d" (*(high)) \ : "c" (msr | adr)) -/*----------------------------------------------------------------- - * gfx_msr_asm_write - * Write the contents of address pointers to a MSR. - *-----------------------------------------------------------------*/ -#define gfx_msr_asm_write(msr,adr,high,low) \ +#define vsa_msr_write(msr,adr,high,low) \ { int d0, d1, d2, d3, d4; \ __asm__ __volatile__( \ " push %%ebx\n" \ @@ -299,61 +177,50 @@ gfx_outd(unsigned short port, unsigned long data) : "1"(msr | adr),"2"(*(high)),"3"(*(low))); \ } -/* INITIALIZATION ROUTINES - * These routines are used during the initialization of the driver to - * perform such tasks as detecting the type of CPU and video hardware. - * The routines require the use of IO, so the above IO routines need - * to be implemented before the initialization routines will work - * properly. - */ +extern int GeodeWriteMSR(unsigned long, unsigned long, unsigned long); +extern int GeodeReadMSR(unsigned long, unsigned long *, unsigned long *); -#include "gfx_init.c" +void gfx_msr_asm_write(unsigned short reg, unsigned long addr, +unsigned long *hi, unsigned long *lo) +{ + static int msr_method = 0; -/* INCLUDE MSR ACCESS ROUTINES */ + if (msr_method == 0) { + if (!GeodeWriteMSR(addr | reg, *lo, *hi)) + return; -#include "gfx_msr.c" + msr_method = 1; + } + + /* This is the fallback VSA method - not preferred */ + vsa_msr_write(reg, addr, hi, lo); +} -/* INCLUDE GRAPHICS ENGINE ROUTINES - * These routines are used to program the 2D graphics accelerator. If - * the project does not use graphics acceleration (direct frame buffer - * access only), then this file does not need to be included. - */ -#include "gfx_rndr.c" /* graphics engine routines */ - -/* INCLUDE DISPLAY CONTROLLER ROUTINES - * These routines are used if the display mode is set directly. If the - * project uses VGA registers to set a display mode, then these files - * do not need to be included. - */ -#include "gfx_mode.h" /* display mode tables */ -#include "gfx_disp.c" /* display controller routines */ - -/* INCLUDE VIDEO OVERLAY ROUTINES - * These routines control the video overlay hardware. - */ -#include "gfx_vid.c" /* video overlay routines */ - -/* VIDEO PORT AND VIDEO DECODER ROUTINES - * These routines rely on the I2C routines. - */ -#include "gfx_vip.c" /* video port routines */ -#include "gfx_dcdr.c" /* video decoder routines */ - -/* I2C BUS ACCESS ROUTINES - * These routines are used by the video decoder and possibly an - * external TV encoer. - */ -#include "gfx_i2c.c" /* I2C bus access routines */ - -/* TV ENCODER ROUTINES - * This file does not need to be included if the system does not - * support TV output. - */ -#include "gfx_tv.c" /* TV encoder routines */ - -/* VGA ROUTINES - * This file is used if setting display modes using VGA registers. - */ -#include "gfx_vga.c" /* VGA routines */ - -/* END OF FILE */ +void gfx_msr_asm_read(unsigned short reg, unsigned long addr, +unsigned long *hi, unsigned long *lo) +{ + static int msr_method = 0; + + if (msr_method == 0) { + if (!GeodeReadMSR(addr | reg, lo, hi)) + return; + + ErrorF("Unable to read the MSR - reverting to the VSA method.\n"); + msr_method = 1; + } + + /* This is the fallback VSA method - not preferred */ + vsa_msr_read(reg, addr, hi, lo); +} + +#include "gfx_init.c" +#include "gfx_msr.c" +#include "gfx_rndr.c" +#include "gfx_mode.h" +#include "gfx_disp.c" +#include "gfx_vid.c" +#include "gfx_vip.c" +#include "gfx_dcdr.c" +#include "gfx_i2c.c" +#include "gfx_tv.c" +#include "gfx_vga.c" diff --git a/src/gfx/durango.c b/src/gfx/durango.c deleted file mode 100644 index 5f96ff1..0000000 --- a/src/gfx/durango.c +++ /dev/null @@ -1,484 +0,0 @@ -/* Copyright (c) 2005 Advanced Micro Devices, Inc. - * - * 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, - * 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. - * - * Neither the name of the Advanced Micro Devices, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * */ - -/* - * This is the main file used to add Durango graphics support to a software - * project. The main reason to have a single file include the other files - * is that it centralizes the location of the compiler options. This file - * should be tuned for a specific implementation, and then modified as needed - * for new Durango releases. The releases.txt file indicates any updates to - * this main file, such as a new definition for a new hardware platform. - * - * In other words, this file should be copied from the Durango source files - * once when a software project starts, and then maintained as necessary. - * It should not be recopied with new versions of Durango unless the - * developer is willing to tune the file again for the specific project. - * */ - -/* COMPILER OPTIONS - * These compiler options specify how the Durango routines are compiled - * for the different hardware platforms. For best performance, a driver - * would build for a specific platform. The "dynamic" switches are set - * by diagnostic applications such as Darwin that will run on a variety - * of platforms and use the appropriate code at runtime. Each component - * may be separately dynamic, so that a driver has the option of being - * tuned for a specific 2D accelerator, but will still run with a variety - * of chipsets. - */ - -#define GFX_DISPLAY_DYNAMIC 1 /* runtime selection */ -#define GFX_DISPLAY_GU1 1 /* 1st generation display controller */ -#define GFX_DISPLAY_GU2 1 /* 2nd generation display controller */ - -#define GFX_INIT_DYNAMIC 1 /* runtime selection */ -#define GFX_INIT_GU1 1 /* Geode family */ -#define GFX_INIT_GU2 1 /* Redcloud */ -#define GFX_MSR_DYNAMIC 1 /* runtime selection */ -#define GFX_MSR_REDCLOUD 1 /* Redcloud */ - -#define GFX_2DACCEL_DYNAMIC 1 /* runtime selection */ -#define GFX_2DACCEL_GU1 1 /* 1st generation 2D accelerator */ -#define GFX_2DACCEL_GU2 1 /* 2nd generation 2D accelerator */ - -#define GFX_VIDEO_DYNAMIC 1 /* runtime selection */ -#define GFX_VIDEO_CS5530 1 /* support for CS5530 */ -#define GFX_VIDEO_SC1200 1 /* support for SC1200 */ -#define GFX_VIDEO_REDCLOUD 1 /* support for Redcloud */ - -#define GFX_VIP_DYNAMIC 1 /* runtime selection */ -#define GFX_VIP_SC1200 1 /* support for SC1200 */ - -#define GFX_DECODER_DYNAMIC 1 /* runtime selection */ -#define GFX_DECODER_SAA7114 1 /* Philips SAA7114 decoder */ - -#define GFX_TV_DYNAMIC 1 /* runtime selection */ -#define GFX_TV_FS451 1 /* Focus Enhancements FS450 */ -#define GFX_TV_SC1200 1 /* SC1200 integrated TV encoder */ - -#define GFX_I2C_DYNAMIC 1 /* runtime selection */ -#define GFX_I2C_ACCESS 1 /* support for ACCESS.BUS */ -#define GFX_I2C_GPIO 1 /* support for CS5530 GPIOs */ - -#define GFX_VGA_DYNAMIC 1 /* runtime selection */ -#define GFX_VGA_GU1 1 /* 1st generation graphics unit */ - -#define FB4MB 1 /* Set to use 4Mb video ram for Pyramid */ - -#define GFX_NO_IO_IN_WAIT_MACROS 0 /* Set to remove I/O accesses in GP - * bit testing */ - -/* ROUTINES TO READ VALUES - * These are routines used by Darwin or other diagnostics to read the - * current state of the hardware. Display drivers or embedded applications - * can reduce the size of the Durango code by not including these routines. - */ -#define GFX_READ_ROUTINES 1 /* add routines to read values */ - -/* VARIABLES USED FOR RUNTIME SELECTION - * If part of the graphics subsystem is declared as dynamic, then the - * following variables are used to specify which platform has been detected. - * The variables are set in the "gfx_detect_cpu" routine. The values should - * be bit flags to allow masks to be used to check for multiple platforms. - */ - -#if GFX_DISPLAY_DYNAMIC -int gfx_display_type = 0; -#endif - -#if GFX_INIT_DYNAMIC -int gfx_init_type = 0; -#endif - -#if GFX_MSR_DYNAMIC -int gfx_msr_type = 0; -#endif - -#if GFX_2DACCEL_DYNAMIC -int gfx_2daccel_type = 0; -#endif - -#if GFX_VIDEO_DYNAMIC -int gfx_video_type = 0; -#endif - -#if GFX_VIP_DYNAMIC -int gfx_vip_type = 0; -#endif - -#if GFX_DECODER_DYNAMIC -int gfx_decoder_type = 0; -#endif - -#if GFX_TV_DYNAMIC -int gfx_tv_type = 0; -#endif - -#if GFX_I2C_DYNAMIC -int gfx_i2c_type = 0; -#endif - -#if GFX_VGA_DYNAMIC -int gfx_vga_type = 0; -#endif - -/* HEADER FILE FOR DURANGO ROUTINE DEFINITIONS - * Needed since some of the Durango routines call other Durango routines. - * Also defines the size of chipset array (GFX_CSPTR_SIZE). - */ -#include "gfx_rtns.h" /* routine definitions */ - -/* INCLUDE PROTOTYPES FOR PRIVATE ROUTINES */ - -#include "gfx_priv.h" - -/* DEFINE POINTERS TO MEMORY MAPPED REGIONS - * These pointers are used by the Durango routines to access the hardware. - * The variables must be set by the project's initialization code after - * mapping the regions in the appropriate manner. - */ - -/* DEFINE VIRTUAL ADDRESSES */ -/* Note: These addresses define the starting base expected by all */ -/* Durango offsets. Under an OS that requires these pointers */ -/* to be mapped to linear addresses (i.e Windows), it may not */ -/* be possible to keep these base offsets. In these cases, */ -/* the addresses are modified to point to the beginning of the */ -/* relevant memory region and the access macros are adjusted */ -/* to subtract the offset from the default base. For example, */ -/* the register pointer could be moved to be 0x40008000, while */ -/* the WRITE_REG* macros are modified to subtract 0x8000 from */ -/* the offset. */ - -unsigned char *gfx_virt_regptr = (unsigned char *)0x40000000; -unsigned char *gfx_virt_fbptr = (unsigned char *)0x40800000; -unsigned char *gfx_virt_vidptr = (unsigned char *)0x40010000; -unsigned char *gfx_virt_vipptr = (unsigned char *)0x40015000; -unsigned char *gfx_virt_spptr = (unsigned char *)0x40000000; -unsigned char *gfx_virt_gpptr = (unsigned char *)0x40000000; - -/* DEFINE PHYSICAL ADDRESSES */ - -unsigned char *gfx_phys_regptr = (unsigned char *)0x40000000; -unsigned char *gfx_phys_fbptr = (unsigned char *)0x40800000; -unsigned char *gfx_phys_vidptr = (unsigned char *)0x40010000; -unsigned char *gfx_phys_vipptr = (unsigned char *)0x40015000; - -/* HEADER FILE FOR GRAPHICS REGISTER DEFINITIONS - * This contains only constant definitions, so it should be able to be - * included in any software project as is. - */ -#include "gfx_regs.h" /* graphics register definitions */ - -/* HEADER FILE FOR REGISTER ACCESS MACROS - * This file contains the definitions of the WRITE_REG32 and similar macros - * used by the Durango routines to access the hardware. The file assumes - * that the environment can handle 32-bit pointer access. If this is not - * the case, or if there are special requirements, then this header file - * should not be included and the project must define the macros itself. - * (A project may define WRITE_REG32 to call a routine, for example). - */ -#include "gfx_defs.h" /* register access macros */ - -/* IO MACROS AND ROUTINES - * These macros must be defined before the initialization or I2C - * routines will work properly. - */ - -#if defined(OS_WIN32) /* For Windows */ - -/* VSA II CALL */ - -void -gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr, - unsigned long *ptrHigh, unsigned long *ptrLow) -{ - unsigned long temp1, temp2; - - _asm { - mov dx, 0x0AC1C - mov eax, 0x0FC530007 - out dx, eax add dl, 2 mov ecx, msrAddr mov cx, msrReg in ax, dx; - EDX:EAX will contain MSR contents.mov temp1, edx mov temp2, eax} - - *ptrHigh = temp1; - *ptrLow = temp2; -} - -void -gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr, - unsigned long *ptrHigh, unsigned long *ptrLow) -{ - unsigned long temp1 = *ptrHigh; - unsigned long temp2 = *ptrLow; - - _asm { - - mov dx, 0x0AC1C - mov eax, 0x0FC530007 out dx, eax add dl, 2 mov ecx, msrAddr; - ECX contains msrAddr | msrReg mov cx, msrReg; - mov ebx, temp1; - - <OR_mask_hi > mov eax, temp2; - <OR_mask_hi > mov esi, 0; - <AND_mask_hi > mov edi, 0; - <AND_mask_lo > out dx, ax; - MSR is written at this point} -} - -unsigned char -gfx_inb(unsigned short port) -{ - unsigned char data; - - _asm { - pushf mov dx, port in al, dx mov data, al popf} - return (data); -} - -unsigned short -gfx_inw(unsigned short port) -{ - unsigned short data; - - _asm { - pushf mov dx, port in ax, dx mov data, ax popf} - return (data); -} - -unsigned long -gfx_ind(unsigned short port) -{ - unsigned long data; - - _asm { - pushf mov dx, port in eax, dx mov data, eax popf} - return (data); -} - -void -gfx_outb(unsigned short port, unsigned char data) -{ - _asm { - pushf mov al, data mov dx, port out dx, al popf} -} - -void -gfx_outw(unsigned short port, unsigned short data) -{ - _asm { - pushf mov ax, data mov dx, port out dx, ax popf} -} - -void -gfx_outd(unsigned short port, unsigned long data) -{ - _asm { - pushf mov eax, data mov dx, port out dx, eax popf} -} - -#elif defined(OS_VXWORKS) || defined (OS_LINUX) /* VxWorks and Linux */ - -#if defined(OS_LINUX) -#include "asm/msr.h" -#endif - -void -gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr, - unsigned long *ptrHigh, unsigned long *ptrLow) -{ - unsigned long addr, val1, val2; - - addr = msrAddr | (unsigned long)msrReg; - rdmsr(addr, val1, val2); - - *ptrHigh = val2; - *ptrLow = val1; -} - -void -gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr, - unsigned long *ptrHigh, unsigned long *ptrLow) -{ - unsigned long addr, val1, val2; - - val2 = *ptrHigh; - val1 = *ptrLow; - - addr = (msrAddr & 0xFFFF0000) | (unsigned long)msrReg; - wrmsr(addr, val1, val2); -} - -unsigned char -gfx_inb(unsigned short port) -{ - unsigned char value; - __asm__ volatile ("inb %1,%0":"=a" (value):"d"(port)); - - return value; -} - -unsigned short -gfx_inw(unsigned short port) -{ - unsigned short value; - __asm__ volatile ("in %1,%0":"=a" (value):"d"(port)); - - return value; -} - -unsigned long -gfx_ind(unsigned short port) -{ - unsigned long value; - __asm__ volatile ("inl %1,%0":"=a" (value):"d"(port)); - - return value; -} - -void -gfx_outb(unsigned short port, unsigned char data) -{ - __asm__ volatile ("outb %0,%1"::"a" (data), "d"(port)); -} - -void -gfx_outw(unsigned short port, unsigned short data) -{ - __asm__ volatile ("out %0,%1"::"a" (data), "d"(port)); -} - -void -gfx_outd(unsigned short port, unsigned long data) -{ - __asm__ volatile ("outl %0,%1"::"a" (data), "d"(port)); -} - -#else /* else nothing */ - -unsigned char -gfx_inb(unsigned short port) -{ - /* ADD OS SPECIFIC IMPLEMENTATION */ - return (0); -} - -unsigned short -gfx_inw(unsigned short port) -{ - /* ADD OS SPECIFIC IMPLEMENTATION */ - return (0); -} - -unsigned long -gfx_ind(unsigned short port) -{ - /* ADD OS SPECIFIC IMPLEMENTATION */ - return (0); -} - -void -gfx_outb(unsigned short port, unsigned char data) -{ - /* ADD OS SPECIFIC IMPLEMENTATION */ -} - -void -gfx_outw(unsigned short port, unsigned short data) -{ - /* ADD OS SPECIFIC IMPLEMENTATION */ -} - -void -gfx_outd(unsigned short port, unsigned long data) -{ - /* ADD OS SPECIFIC IMPLEMENTATION */ -} -#endif - -#define INB(port) gfx_inb(port) -#define INW(port) gfx_inw(port) -#define IND(port) gfx_ind(port) -#define OUTB(port, data) gfx_outb(port, data) -#define OUTW(port, data) gfx_outw(port, data) -#define OUTD(port, data) gfx_outd(port, data) - -/* INITIALIZATION ROUTINES - * These routines are used during the initialization of the driver to - * perform such tasks as detecting the type of CPU and video hardware. - * The routines require the use of IO, so the above IO routines need - * to be implemented before the initialization routines will work - * properly. - */ - -#include "gfx_init.c" - -/* INCLUDE MSR ACCESS ROUTINES */ - -#include "gfx_msr.c" - -/* INCLUDE GRAPHICS ENGINE ROUTINES - * These routines are used to program the 2D graphics accelerator. If - * the project does not use graphics acceleration (direct frame buffer - * access only), then this file does not need to be included. - */ -#include "gfx_rndr.c" /* graphics engine routines */ - -/* INCLUDE DISPLAY CONTROLLER ROUTINES - * These routines are used if the display mode is set directly. If the - * project uses VGA registers to set a display mode, then these files - * do not need to be included. - */ -#include "gfx_mode.h" /* display mode tables */ -#include "gfx_disp.c" /* display controller routines */ - -/* INCLUDE VIDEO OVERLAY ROUTINES - * These routines control the video overlay hardware. - */ -#include "gfx_vid.c" /* video overlay routines */ - -/* VIDEO PORT AND VIDEO DECODER ROUTINES - * These routines rely on the I2C routines. - */ -#include "gfx_vip.c" /* video port routines */ -#include "gfx_dcdr.c" /* video decoder routines */ - -/* I2C BUS ACCESS ROUTINES - * These routines are used by the video decoder and possibly an - * external TV encoer. - */ -#include "gfx_i2c.c" /* I2C bus access routines */ - -/* TV ENCODER ROUTINES - * This file does not need to be included if the system does not - * support TV output. - */ -#include "gfx_tv.c" /* TV encoder routines */ - -/* VGA ROUTINES - * This file is used if setting display modes using VGA registers. - */ -#include "gfx_vga.c" /* VGA routines */ - -/* END OF FILE */ diff --git a/src/gfx/msr_rdcl.c b/src/gfx/msr_rdcl.c index 8c927a4..548e8a4 100644 --- a/src/gfx/msr_rdcl.c +++ b/src/gfx/msr_rdcl.c @@ -628,5 +628,6 @@ gfx_msr_write(unsigned int device, unsigned int msrRegister, return msrDev[device].Present; } + return NOT_KNOWN; } diff --git a/src/gfx/vid_rdcl.c b/src/gfx/vid_rdcl.c index 06e1925..7c98d2d 100644 --- a/src/gfx/vid_rdcl.c +++ b/src/gfx/vid_rdcl.c @@ -221,10 +221,17 @@ gfx_set_display_control(int sync_polarities) /* SET APPROPRIATE SYNC POLARITIES */ + if (PanelEnable) { + unsigned int pt2 = READ_VID32(0x408); + + pt2 &= ~((1 << 22) | (1 << 23)); + WRITE_VID32(0x408, pt2); + } + if (sync_polarities & 0x1) - dcfg |= RCDF_DCFG_CRT_HSYNC_POL; - if (sync_polarities & 0x2) - dcfg |= RCDF_DCFG_CRT_VSYNC_POL; + dcfg |= RCDF_DCFG_CRT_HSYNC_POL; + if (sync_polarities & 0x2) + dcfg |= RCDF_DCFG_CRT_VSYNC_POL; WRITE_VID32(RCDF_DISPLAY_CONFIG, dcfg); |