summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-01-06 14:58:15 +1000
committerBen Skeggs <bskeggs@redhat.com>2010-01-11 09:46:23 +1000
commit17485c234ff191cee3dd19e3dd693a80b024e189 (patch)
treee69ec488f0ec8b186d4e8a39eecc0ee7b8e64308
parent061cb284b93612848296599759b915a4d66b6d01 (diff)
Initial pass at removal of non-KMS support.
It's likely there's a lot more that can be cleaned up/removed as a result of this, we can handle that as we come across it. Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Signed-off-by: Francisco Jerez <currojerez@riseup.net> Acked-by: Maarten Maathuis <madman2003@gmail.com>
-rw-r--r--configure.ac27
-rw-r--r--src/Makefile.am25
-rw-r--r--src/drmmode_display.c57
-rw-r--r--src/nouveau_bios.h224
-rw-r--r--src/nouveau_calc.c617
-rw-r--r--src/nouveau_connector.h65
-rw-r--r--src/nouveau_crtc.h91
-rw-r--r--src/nouveau_exa.c6
-rw-r--r--src/nouveau_hw.c1031
-rw-r--r--src/nouveau_hw.h352
-rw-r--r--src/nouveau_modeset.h31
-rw-r--r--src/nouveau_ms.h159
-rw-r--r--src/nouveau_output.h69
-rw-r--r--src/nouveau_xv.c39
-rw-r--r--src/nv04_xv_blit.c8
-rw-r--r--src/nv04_xv_ovl.c6
-rw-r--r--src/nv10_exa.c12
-rw-r--r--src/nv10_xv_ovl.c12
-rw-r--r--src/nv30_exa.c2
-rw-r--r--src/nv30_xv_tex.c5
-rw-r--r--src/nv40_exa.c3
-rw-r--r--src/nv40_xv_tex.c5
-rw-r--r--src/nv50_connector.c123
-rw-r--r--src/nv50_crtc.c535
-rw-r--r--src/nv50_cursor.c77
-rw-r--r--src/nv50_dac.c225
-rw-r--r--src/nv50_display.c150
-rw-r--r--src/nv50_output.c236
-rw-r--r--src/nv50_randr.c899
-rw-r--r--src/nv50_randr.h41
-rw-r--r--src/nv50_sor.c216
-rw-r--r--src/nv50reg.h449
-rw-r--r--src/nv_accel_common.c4
-rw-r--r--src/nv_bios.c4810
-rw-r--r--src/nv_const.h8
-rw-r--r--src/nv_crtc.c1095
-rw-r--r--src/nv_cursor.c216
-rw-r--r--src/nv_dma.c1
-rw-r--r--src/nv_driver.c539
-rw-r--r--src/nv_i2c.c158
-rw-r--r--src/nv_include.h3
-rw-r--r--src/nv_output.c1293
-rw-r--r--src/nv_proto.h102
-rw-r--r--src/nv_setup.c207
-rw-r--r--src/nv_type.h124
-rw-r--r--src/nvreg.h503
46 files changed, 176 insertions, 14684 deletions
diff --git a/configure.ac b/configure.ac
index e917c01..201bfc6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,3 +24,3 @@ AC_PREREQ(2.57)
AC_INIT([xf86-video-nouveau],
- 0.0.10,
+ 0.0.15,
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
@@ -29,9 +29,9 @@ AC_INIT([xf86-video-nouveau],
AC_DEFINE_UNQUOTED([NV_MAJOR_VERSION],
- [$(echo $PACKAGE_VERSION | sed -e 's/^\([[0-9]]\)\.[[0-9]]\.[[0-9]]/\1/')],
+ [$(echo $PACKAGE_VERSION | sed -e 's/^\([[0-9]]*\)\.[[0-9]]*\.[[0-9]]*/\1/')],
[Major version])
AC_DEFINE_UNQUOTED([NV_MINOR_VERSION],
- [$(echo $PACKAGE_VERSION | sed -e 's/^[[0-9]]\.\([[0-9]]\)\.[[0-9]]/\1/')],
+ [$(echo $PACKAGE_VERSION | sed -e 's/^[[0-9]]*\.\([[0-9]]*\)\.[[0-9]]*/\1/')],
[Minor version])
AC_DEFINE_UNQUOTED([NV_PATCHLEVEL],
- [$(echo $PACKAGE_VERSION | sed -e 's/^[[0-9]]\.[[0-9]]\.\([[0-9]]\)/\1/')],
+ [$(echo $PACKAGE_VERSION | sed -e 's/^[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)/\1/')],
[Patch version])
@@ -98,21 +98,2 @@ CFLAGS="$CFLAGS $XORG_CFLAGS"
-AC_MSG_CHECKING(for DRM modesetting)
-AC_ARG_WITH(
- kms,
- [ --with-kms=yes,no compile with drm modesetting support (default: auto)],
- kms="$withval",
- kms="yes")
-AC_MSG_RESULT($kms)
-
-if test "x$kms" = xyes; then
- AC_CHECK_HEADER([xf86drmMode.h],[kms=yes],[kms=no],
- [#include <stdint.h>
- #include <stdlib.h> ]
- )
-fi
-
-if test "x$kms" = xyes; then
- AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting])
-fi
-
AC_SUBST([CFLAGS])
diff --git a/src/Makefile.am b/src/Makefile.am
index 3bd4b8c..2142330 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -31,7 +31,3 @@ nouveau_drv_ladir = @moduledir@/drivers
nouveau_drv_la_SOURCES = \
- nouveau_bios.h \
- nouveau_calc.c \
- nouveau_hw.c nouveau_hw.h \
nouveau_local.h \
- nouveau_ms.h \
nouveau_exa.c nouveau_xv.c nouveau_dri2.c \
@@ -39,5 +35,3 @@ nouveau_drv_la_SOURCES = \
nv_accel_common.c \
- nv_bios.c \
nv_const.h \
- nv_cursor.c \
nv_dma.c \
@@ -51,9 +45,4 @@ nouveau_drv_la_SOURCES = \
nv_proto.h \
- nvreg.h \
- nv_setup.c \
nv_shadow.c \
nv_type.h \
- nv_crtc.c \
- nv_output.c \
- nv_i2c.c \
nv04_exa.c \
@@ -70,19 +59,5 @@ nouveau_drv_la_SOURCES = \
nv50_accel.c nv50_accel.h \
- nv50_cursor.c \
- nv50_crtc.c \
- nv50_dac.c \
- nv50_display.c \
nv50_exa.c \
- nv50_output.c \
- nv50_sor.c \
- nv50_randr.c \
- nv50_randr.h \
- nv50_connector.c \
nv50_xv.c \
nv50_texture.h \
- nv50reg.h \
- nouveau_crtc.h \
- nouveau_output.h \
- nouveau_connector.h \
- nouveau_modeset.h \
drmmode_display.c \
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index e37e7c1..0c8b4a0 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -35,3 +35,2 @@
-#ifdef XF86DRM_MODE
#include "nv_include.h"
@@ -370,2 +369,48 @@ done:
+#define SOURCE_MASK_INTERLEAVE 32
+#define TRANSPARENT_PIXEL 0
+
+/*
+ * Convert a source/mask bitmap cursor to an ARGB cursor, clipping or
+ * padding as necessary. source/mask are assumed to be alternated each
+ * SOURCE_MASK_INTERLEAVE bits.
+ */
+void
+nv_cursor_convert_cursor(uint32_t *src, void *dst, int src_stride, int dst_stride,
+ int bpp, uint32_t fg, uint32_t bg)
+{
+ int width = min(src_stride, dst_stride);
+ uint32_t b, m, pxval;
+ int i, j, k;
+
+ for (i = 0; i < width; i++) {
+ for (j = 0; j < width / SOURCE_MASK_INTERLEAVE; j++) {
+ int src_off = i*src_stride/SOURCE_MASK_INTERLEAVE + j;
+ int dst_off = i*dst_stride + j*SOURCE_MASK_INTERLEAVE;
+
+ b = src[2*src_off];
+ m = src[2*src_off + 1];
+
+ for (k = 0; k < SOURCE_MASK_INTERLEAVE; k++) {
+ pxval = TRANSPARENT_PIXEL;
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ if (m & 0x80000000)
+ pxval = (b & 0x80000000) ? fg : bg;
+ b <<= 1;
+ m <<= 1;
+#else
+ if (m & 1)
+ pxval = (b & 1) ? fg : bg;
+ b >>= 1;
+ m >>= 1;
+#endif
+ if (bpp == 32)
+ ((uint32_t *)dst)[dst_off + k] = pxval;
+ else
+ ((uint16_t *)dst)[dst_off + k] = pxval;
+ }
+ }
+ }
+}
+
static void
@@ -432,3 +477,2 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
-
static void
@@ -1198,5 +1242,2 @@ drmmode_is_rotate_pixmap(PixmapPtr ppix, struct nouveau_bo **bo)
- if (!NVPTR(pScrn)->kms_enable)
- return FALSE;
-
for (i = 0; i < config->num_crtc; i++) {
@@ -1239,5 +1280,2 @@ drmmode_remove_fb(ScrnInfoPtr pScrn)
- if (!NVPTR(pScrn)->kms_enable)
- return;
-
if (config)
@@ -1262,3 +1300,3 @@ drmmode_cursor_init(ScreenPtr pScreen)
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
- (pNv->alphaCursor ? HARDWARE_CURSOR_ARGB : 0) |
+ (pNv->NVArch >= 0x11 ? HARDWARE_CURSOR_ARGB : 0) |
HARDWARE_CURSOR_UPDATE_UNHIDDEN;
@@ -1268,2 +1306 @@ drmmode_cursor_init(ScreenPtr pScreen)
-#endif
diff --git a/src/nouveau_bios.h b/src/nouveau_bios.h
deleted file mode 100644
index 125862e..0000000
--- a/src/nouveau_bios.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright 2007-2008 Nouveau Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __NOUVEAU_BIOS_H__
-#define __NOUVEAU_BIOS_H__
-
-#include "nvreg.h"
-
-#define DCB_MAX_NUM_ENTRIES 16
-#define DCB_MAX_NUM_I2C_ENTRIES 16
-
-#define DCB_LOC_ON_CHIP 0
-
-struct dcb_entry {
- int index; /* may not be raw dcb index if merging has happened */
- uint8_t type;
- uint8_t i2c_index;
- uint8_t heads;
- uint8_t bus;
- uint8_t location;
- uint8_t or;
- bool duallink_possible;
- union {
- struct {
- int maxfreq;
- } crtconf;
- struct {
- bool use_straps_for_mode;
- bool use_power_scripts;
- } lvdsconf;
- };
- bool i2c_upper_default;
-};
-
-struct dcb_i2c_entry {
- uint8_t port_type;
- uint8_t read, write;
- I2CBusPtr chan;
-};
-
-struct parsed_dcb {
- int entries;
- struct dcb_entry entry[DCB_MAX_NUM_ENTRIES];
- struct dcb_i2c_entry i2c[DCB_MAX_NUM_I2C_ENTRIES];
-};
-
-struct bios_parsed_dcb {
- uint8_t version;
-
- struct parsed_dcb dcb;
-
- uint16_t init8e_table_ptr;
- uint8_t *i2c_table;
- uint8_t i2c_default_indices;
-};
-
-enum nouveau_encoder_type
-{
- /* 0-3 match DCB types */
- OUTPUT_NONE = 4,
- OUTPUT_ANALOG = 0,
- OUTPUT_TMDS = 2,
- OUTPUT_LVDS = 3,
- OUTPUT_TV = 1,
- OUTPUT_ANY = 5,
-};
-
-#define IS_DFP(t) (t == OUTPUT_LVDS || t == OUTPUT_TMDS)
-
-enum nouveau_or {
- OUTPUT_A = (1 << 0),
- OUTPUT_B = (1 << 1),
- OUTPUT_C = (1 << 2)
-};
-
-enum LVDS_script {
- /* Order *does* matter here */
- LVDS_INIT = 1,
- LVDS_RESET,
- LVDS_BACKLIGHT_ON,
- LVDS_BACKLIGHT_OFF,
- LVDS_PANEL_ON,
- LVDS_PANEL_OFF
-};
-
-/* changing these requires matching changes to reg tables in nv_get_clock */
-#define MAX_PLL_TYPES 4
-enum pll_types {
- NVPLL,
- MPLL,
- VPLL1,
- VPLL2
-};
-
-struct pll_lims {
- struct {
- int minfreq;
- int maxfreq;
- int min_inputfreq;
- int max_inputfreq;
-
- uint8_t min_m;
- uint8_t max_m;
- uint8_t min_n;
- uint8_t max_n;
- } vco1, vco2;
-
- uint8_t max_log2p;
- /*
- * for most pre nv50 cards setting a log2P of 7 (the common max_log2p
- * value) is no different to 6 (at least for vplls) so allowing the MNP
- * calc to use 7 causes the generated clock to be out by a factor of 2.
- * however, max_log2p cannot be fixed-up during parsing as the
- * unmodified max_log2p value is still needed for setting mplls, hence
- * an additional max_usable_log2p member
- */
- uint8_t max_usable_log2p;
- uint8_t log2p_bias;
- int refclk;
-};
-
-struct nouveau_bios_info {
- struct parsed_dcb *dcb;
-
- uint8_t chip_version;
-
- uint32_t dactestval;
- uint8_t digital_min_front_porch;
- bool fp_no_ddc;
-};
-
-struct nvbios {
- struct nouveau_bios_info pub;
-
- uint8_t data[NV_PROM_SIZE];
- unsigned int length;
- bool execute;
-
- uint8_t major_version;
- uint8_t feature_byte;
- bool is_mobile;
-
- uint32_t fmaxvco, fminvco;
-
- bool old_style_init;
- uint16_t init_script_tbls_ptr;
- uint16_t extra_init_script_tbl_ptr;
- uint16_t macro_index_tbl_ptr;
- uint16_t macro_tbl_ptr;
- uint16_t condition_tbl_ptr;
- uint16_t io_condition_tbl_ptr;
- uint16_t io_flag_condition_tbl_ptr;
- uint16_t init_function_tbl_ptr;
-
- uint16_t pll_limit_tbl_ptr;
- uint16_t ram_restrict_tbl_ptr;
-
- struct bios_parsed_dcb bdcb;
-
- struct {
- int head;
- uint16_t script_table_ptr;
- } display;
-
- struct {
- uint16_t fptablepointer; /* also used by tmds */
- uint16_t fpxlatetableptr;
- int xlatwidth;
- uint16_t lvdsmanufacturerpointer;
- uint16_t fpxlatemanufacturertableptr;
- uint16_t mode_ptr;
- uint16_t xlated_entry;
- bool power_off_for_reset;
- bool reset_after_pclk_change;
- bool dual_link;
- bool link_c_increment;
- bool BITbit1;
- int duallink_transition_clk;
- uint8_t *edid;
-
- /* will need resetting after suspend */
- int last_script_invoc;
- bool lvds_init_run;
- } fp;
-
- struct {
- uint16_t output0_script_ptr;
- uint16_t output1_script_ptr;
- } tmds;
-
- struct {
- uint16_t mem_init_tbl_ptr;
- uint16_t sdr_seq_tbl_ptr;
- uint16_t ddr_seq_tbl_ptr;
-
- struct {
- uint8_t crt, tv, panel;
- } i2c_indices;
-
- uint16_t lvds_single_a_script_ptr;
- } legacy;
-};
-
-#endif
diff --git a/src/nouveau_calc.c b/src/nouveau_calc.c
deleted file mode 100644
index f12486c..0000000
--- a/src/nouveau_calc.c
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * Copyright 1993-2003 NVIDIA, Corporation
- * Copyright 2007-2009 Stuart Bennett
- *
- * 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 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.
- */
-
-#include "nv_include.h"
-
-/****************************************************************************\
-* *
-* The video arbitration routines calculate some "magic" numbers. Fixes *
-* the snow seen when accessing the framebuffer without it. *
-* It just works (I hope). *
-* *
-\****************************************************************************/
-
-struct nv_fifo_info {
- int graphics_lwm;
- int video_lwm;
- int graphics_burst_size;
- int video_burst_size;
- bool valid;
-};
-
-struct nv_sim_state {
- int pclk_khz;
- int mclk_khz;
- int nvclk_khz;
- int pix_bpp;
- bool enable_mp;
- bool enable_video;
- int mem_page_miss;
- int mem_latency;
- int memory_type;
- int memory_width;
-};
-
-static void nv4CalcArbitration(struct nv_fifo_info *fifo, struct nv_sim_state *arb)
-{
- int pagemiss, cas, width, video_enable, bpp;
- int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
- int found, mclk_extra, mclk_loop, cbs, m1, p1;
- int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
- int us_m, us_n, us_p, video_drain_rate, crtc_drain_rate;
- int vpm_us, us_video, vlwm, video_fill_us, cpm_us, us_crt, clwm;
-
- pclk_freq = arb->pclk_khz;
- mclk_freq = arb->mclk_khz;
- nvclk_freq = arb->nvclk_khz;
- pagemiss = arb->mem_page_miss;
- cas = arb->mem_latency;
- width = arb->memory_width >> 6;
- video_enable = arb->enable_video;
- bpp = arb->pix_bpp;
- mp_enable = arb->enable_mp;
- clwm = 0;
- vlwm = 0;
- cbs = 128;
- pclks = 2;
- nvclks = 2;
- nvclks += 2;
- nvclks += 1;
- mclks = 5;
- mclks += 3;
- mclks += 1;
- mclks += cas;
- mclks += 1;
- mclks += 1;
- mclks += 1;
- mclks += 1;
- mclk_extra = 3;
- nvclks += 2;
- nvclks += 1;
- nvclks += 1;
- nvclks += 1;
- if (mp_enable)
- mclks += 4;
- nvclks += 0;
- pclks += 0;
- found = 0;
- vbs = 0;
- while (found != 1) {
- fifo->valid = true;
- found = 1;
- mclk_loop = mclks + mclk_extra;
- us_m = mclk_loop * 1000 * 1000 / mclk_freq;
- us_n = nvclks * 1000 * 1000 / nvclk_freq;
- us_p = nvclks * 1000 * 1000 / pclk_freq;
- if (video_enable) {
- video_drain_rate = pclk_freq * 2;
- crtc_drain_rate = pclk_freq * bpp / 8;
- vpagemiss = 2;
- vpagemiss += 1;
- crtpagemiss = 2;
- vpm_us = vpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
- if (nvclk_freq * 2 > mclk_freq * width)
- video_fill_us = cbs * 1000 * 1000 / 16 / nvclk_freq;
- else
- video_fill_us = cbs * 1000 * 1000 / (8 * width) / mclk_freq;
- us_video = vpm_us + us_m + us_n + us_p + video_fill_us;
- vlwm = us_video * video_drain_rate / (1000 * 1000);
- vlwm++;
- vbs = 128;
- if (vlwm > 128)
- vbs = 64;
- if (vlwm > (256 - 64))
- vbs = 32;
- if (nvclk_freq * 2 > mclk_freq * width)
- video_fill_us = vbs * 1000 * 1000 / 16 / nvclk_freq;
- else
- video_fill_us = vbs * 1000 * 1000 / (8 * width) / mclk_freq;
- cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
- us_crt = us_video + video_fill_us + cpm_us + us_m + us_n + us_p;
- clwm = us_crt * crtc_drain_rate / (1000 * 1000);
- clwm++;
- } else {
- crtc_drain_rate = pclk_freq * bpp / 8;
- crtpagemiss = 2;
- crtpagemiss += 1;
- cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
- us_crt = cpm_us + us_m + us_n + us_p;
- clwm = us_crt * crtc_drain_rate / (1000 * 1000);
- clwm++;
- }
- m1 = clwm + cbs - 512;
- p1 = m1 * pclk_freq / mclk_freq;
- p1 = p1 * bpp / 8;
- if ((p1 < m1 && m1 > 0) ||
- (video_enable && (clwm > 511 || vlwm > 255)) ||
- (!video_enable && clwm > 519)) {
- fifo->valid = false;
- found = !mclk_extra;
- mclk_extra--;
- }
- if (clwm < 384)
- clwm = 384;
- if (vlwm < 128)
- vlwm = 128;
- fifo->graphics_lwm = clwm;
- fifo->graphics_burst_size = 128;
- fifo->video_lwm = vlwm + 15;
- fifo->video_burst_size = vbs;
- }
-}
-
-static void nv10CalcArbitration(struct nv_fifo_info *fifo, struct nv_sim_state *arb)
-{
- int pagemiss, width, video_enable, bpp;
- int nvclks, mclks, pclks, vpagemiss, crtpagemiss;
- int nvclk_fill;
- int found, mclk_extra, mclk_loop, cbs, m1;
- int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
- int us_m, us_m_min, us_n, us_p, crtc_drain_rate;
- int vus_m;
- int vpm_us, us_video, cpm_us, us_crt, clwm;
- int clwm_rnd_down;
- int m2us, us_pipe_min, p1clk, p2;
- int min_mclk_extra;
- int us_min_mclk_extra;
-
- pclk_freq = arb->pclk_khz; /* freq in KHz */
- mclk_freq = arb->mclk_khz;
- nvclk_freq = arb->nvclk_khz;
- pagemiss = arb->mem_page_miss;
- width = arb->memory_width / 64;
- video_enable = arb->enable_video;
- bpp = arb->pix_bpp;
- mp_enable = arb->enable_mp;
- clwm = 0;
- cbs = 512;
- pclks = 4; /* lwm detect. */
- nvclks = 3; /* lwm -> sync. */
- nvclks += 2; /* fbi bus cycles (1 req + 1 busy) */
- mclks = 1; /* 2 edge sync. may be very close to edge so just put one. */
- mclks += 1; /* arb_hp_req */
- mclks += 5; /* ap_hp_req tiling pipeline */
- mclks += 2; /* tc_req latency fifo */
- mclks += 2; /* fb_cas_n_ memory request to fbio block */
- mclks += 7; /* sm_d_rdv data returned from fbio block */
-
- /* fb.rd.d.Put_gc need to accumulate 256 bits for read */
- if (arb->memory_type == 0) {
- if (arb->memory_width == 64) /* 64 bit bus */
- mclks += 4;
- else
- mclks += 2;
- } else if (arb->memory_width == 64) /* 64 bit bus */
- mclks += 2;
- else
- mclks += 1;
-
- if (!video_enable && arb->memory_width == 128) {
- mclk_extra = (bpp == 32) ? 31 : 42; /* Margin of error */
- min_mclk_extra = 17;
- } else {
- mclk_extra = (bpp == 32) ? 8 : 4; /* Margin of error */
- /* mclk_extra = 4; *//* Margin of error */
- min_mclk_extra = 18;
- }
-
- nvclks += 1; /* 2 edge sync. may be very close to edge so just put one. */
- nvclks += 1; /* fbi_d_rdv_n */
- nvclks += 1; /* Fbi_d_rdata */
- nvclks += 1; /* crtfifo load */
-
- if (mp_enable)
- mclks += 4; /* Mp can get in with a burst of 8. */
- /* Extra clocks determined by heuristics */
-
- nvclks += 0;
- pclks += 0;
- found = 0;
- while (found != 1) {
- fifo->valid = true;
- found = 1;
- mclk_loop = mclks + mclk_extra;
- us_m = mclk_loop * 1000 * 1000 / mclk_freq; /* Mclk latency in us */
- us_m_min = mclks * 1000 * 1000 / mclk_freq; /* Minimum Mclk latency in us */
- us_min_mclk_extra = min_mclk_extra * 1000 * 1000 / mclk_freq;
- us_n = nvclks * 1000 * 1000 / nvclk_freq; /* nvclk latency in us */
- us_p = pclks * 1000 * 1000 / pclk_freq; /* nvclk latency in us */
- us_pipe_min = us_m_min + us_n + us_p;
-
- vus_m = mclk_loop * 1000 * 1000 / mclk_freq; /* Mclk latency in us */
-
- if (video_enable) {
- crtc_drain_rate = pclk_freq * bpp / 8; /* MB/s */
-
- vpagemiss = 1; /* self generating page miss */
- vpagemiss += 1; /* One higher priority before */
-
- crtpagemiss = 2; /* self generating page miss */
- if (mp_enable)
- crtpagemiss += 1; /* if MA0 conflict */
-
- vpm_us = vpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
-
- us_video = vpm_us + vus_m; /* Video has separate read return path */
-
- cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
- us_crt = us_video /* Wait for video */
- + cpm_us /* CRT Page miss */
- + us_m + us_n + us_p; /* other latency */
-
- clwm = us_crt * crtc_drain_rate / (1000 * 1000);
- clwm++; /* fixed point <= float_point - 1. Fixes that */
- } else {
- crtc_drain_rate = pclk_freq * bpp / 8; /* bpp * pclk/8 */
-
- crtpagemiss = 1; /* self generating page miss */
- crtpagemiss += 1; /* MA0 page miss */
- if (mp_enable)
- crtpagemiss += 1; /* if MA0 conflict */
- cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq;
- us_crt = cpm_us + us_m + us_n + us_p;
- clwm = us_crt * crtc_drain_rate / (1000 * 1000);
- clwm++; /* fixed point <= float_point - 1. Fixes that */
-
- /* Finally, a heuristic check when width == 64 bits */
- if (width == 1) {
- nvclk_fill = nvclk_freq * 8;
- if (crtc_drain_rate * 100 >= nvclk_fill * 102)
- clwm = 0xfff; /* Large number to fail */
- else if (crtc_drain_rate * 100 >= nvclk_fill * 98) {
- clwm = 1024;
- cbs = 512;
- }
- }
- }
-
- /*
- * Overfill check:
- */
-
- clwm_rnd_down = (clwm / 8) * 8;
- if (clwm_rnd_down < clwm)
- clwm += 8;
-
- m1 = clwm + cbs - 1024; /* Amount of overfill */
- m2us = us_pipe_min + us_min_mclk_extra;
-
- /* pclk cycles to drain */
- p1clk = m2us * pclk_freq / (1000 * 1000);
- p2 = p1clk * bpp / 8; /* bytes drained. */
-
- if (p2 < m1 && m1 > 0) {
- fifo->valid = false;
- found = 0;
- if (min_mclk_extra == 0) {
- if (cbs <= 32)
- found = 1; /* Can't adjust anymore! */
- else
- cbs = cbs / 2; /* reduce the burst size */
- } else
- min_mclk_extra--;
- } else if (clwm > 1023) { /* Have some margin */
- fifo->valid = false;
- found = 0;
- if (min_mclk_extra == 0)
- found = 1; /* Can't adjust anymore! */
- else
- min_mclk_extra--;
- }
-
- if (clwm < (1024 - cbs + 8))
- clwm = 1024 - cbs + 8;
- /* printf("CRT LWM: prog: 0x%x, bs: 256\n", clwm); */
- fifo->graphics_lwm = clwm;
- fifo->graphics_burst_size = cbs;
-
- fifo->video_lwm = 1024;
- fifo->video_burst_size = 512;
- }
-}
-
-void nv4_10UpdateArbitrationSettings(ScrnInfoPtr pScrn, int VClk, int bpp, int *burst, int *lwm)
-{
- NVPtr pNv = NVPTR(pScrn);
- struct nv_fifo_info fifo_data;
- struct nv_sim_state sim_data;
- int MClk = nouveau_hw_get_clock(pScrn, MPLL);
- int NVClk = nouveau_hw_get_clock(pScrn, NVPLL);
- uint32_t cfg1 = nvReadFB(pNv, NV_PFB_CFG1);
-
- sim_data.pclk_khz = VClk;
- sim_data.mclk_khz = MClk;
- sim_data.nvclk_khz = NVClk;
- sim_data.pix_bpp = bpp;
- sim_data.enable_mp = false;
- if ((pNv->Chipset & 0xffff) == CHIPSET_NFORCE ||
- (pNv->Chipset & 0xffff) == CHIPSET_NFORCE2) {
- struct pci_device *dev = pci_device_find_by_slot(0, 0, 0, 1);
- uint32_t data;
-
- pci_device_cfg_read_u32(dev, &data, 0x7c);
-
- sim_data.enable_video = false;
- sim_data.memory_type = (data >> 12) & 1;
- sim_data.memory_width = 64;
- sim_data.mem_latency = 3;
- sim_data.mem_page_miss = 10;
- } else {
- sim_data.enable_video = (pNv->Architecture != NV_ARCH_04);
- sim_data.memory_type = nvReadFB(pNv, NV_PFB_CFG0) & 0x1;
- sim_data.memory_width = (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64;
- sim_data.mem_latency = cfg1 & 0xf;
- sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1);
- }
-
- if (pNv->Architecture == NV_ARCH_04)
- nv4CalcArbitration(&fifo_data, &sim_data);
- else
- nv10CalcArbitration(&fifo_data, &sim_data);
-
- if (fifo_data.valid) {
- int b = fifo_data.graphics_burst_size >> 4;
- *burst = 0;
- while (b >>= 1)
- (*burst)++;
- *lwm = fifo_data.graphics_lwm >> 3;
- }
-}
-
-void nv30UpdateArbitrationSettings(int *burst, int *lwm)
-{
- unsigned int fifo_size, burst_size, graphics_lwm;
-
- fifo_size = 2048;
- burst_size = 512;
- graphics_lwm = fifo_size - burst_size;
-
- *burst = 0;
- burst_size >>= 5;
- while (burst_size >>= 1)
- (*burst)++;
- *lwm = graphics_lwm >> 3;
-}
-
-void
-nouveau_calc_arb(ScrnInfoPtr pScrn, int vclk, int bpp, int *burst, int *lwm)
-{
- NVPtr pNv = NVPTR(pScrn);
-
- if (pNv->Architecture < NV_ARCH_30)
- nv4_10UpdateArbitrationSettings(pScrn, vclk, bpp, burst, lwm);
- else if ((pNv->Chipset & 0xfff0) == CHIPSET_C51 ||
- (pNv->Chipset & 0xfff0) == CHIPSET_C512) {
- *burst = 128;
- *lwm = 0x0480;
- } else
- nv30UpdateArbitrationSettings(burst, lwm);
-}
-
-static int getMNP_single(ScrnInfoPtr pScrn, struct pll_lims *pll_lim, int clk,
- struct nouveau_pll_vals *bestpv)
-{
- /* Find M, N and P for a single stage PLL
- *
- * Note that some bioses (NV3x) have lookup tables of precomputed MNP
- * values, but we're too lazy to use those atm
- *
- * "clk" parameter in kHz
- * returns calculated clock
- */
-
- int cv = NVPTR(pScrn)->vbios->chip_version;
- int minvco = pll_lim->vco1.minfreq, maxvco = pll_lim->vco1.maxfreq;
- int minM = pll_lim->vco1.min_m, maxM = pll_lim->vco1.max_m;
- int minN = pll_lim->vco1.min_n, maxN = pll_lim->vco1.max_n;
- int minU = pll_lim->vco1.min_inputfreq, maxU = pll_lim->vco1.max_inputfreq;
- int maxlog2P = pll_lim->max_usable_log2p;
- int crystal = pll_lim->refclk;
- int M, N, log2P, P;
- int clkP, calcclk;
- int delta, bestdelta = INT_MAX;
- int bestclk = 0;
-
- /* this division verified for nv20, nv18, nv28 (Haiku), and nv34 */
- /* possibly correlated with introduction of 27MHz crystal */
- if (cv < 0x17 || cv == 0x1a || cv == 0x20) {
- if (clk > 250000)
- maxM = 6;
- if (clk > 340000)
- maxM = 2;
- } else if (cv < 0x40) {
- if (clk > 150000)
- maxM = 6;
- if (clk > 200000)
- maxM = 4;
- if (clk > 340000)
- maxM = 2;
- }
-
- if ((clk << maxlog2P) < minvco) {
- minvco = clk << maxlog2P;
- maxvco = minvco * 2;
- }
- if (clk + clk/200 > maxvco) /* +0.5% */
- maxvco = clk + clk/200;
-
- /* NV34 goes maxlog2P->0, NV20 goes 0->maxlog2P */
- for (log2P = 0; log2P <= maxlog2P; log2P++) {
- P = 1 << log2P;
- clkP = clk * P;
-
- if (clkP < minvco)
- continue;
- if (clkP > maxvco)
- return bestclk;
-
- for (M = minM; M <= maxM; M++) {
- if (crystal/M < minU)
- return bestclk;
- if (crystal/M > maxU)
- continue;
-
- /* add crystal/2 to round better */
- N = (clkP * M + crystal/2) / crystal;
-
- if (N < minN)
- continue;
- if (N > maxN)
- break;
-
- /* more rounding additions */
- calcclk = ((N * crystal + P/2) / P + M/2) / M;
- delta = abs(calcclk - clk);
- /* we do an exhaustive search rather than terminating
- * on an optimality condition...
- */
- if (delta < bestdelta) {
- bestdelta = delta;
- bestclk = calcclk;
- bestpv->N1 = N;
- bestpv->M1 = M;
- bestpv->log2P = log2P;
- if (delta == 0) /* except this one */
- return bestclk;
- }
- }
- }
-
- return bestclk;
-}
-
-static int getMNP_double(ScrnInfoPtr pScrn, struct pll_lims *pll_lim, int clk,
- struct nouveau_pll_vals *bestpv)
-{
- /* Find M, N and P for a two stage PLL
- *
- * Note that some bioses (NV30+) have lookup tables of precomputed MNP
- * values, but we're too lazy to use those atm
- *
- * "clk" parameter in kHz
- * returns calculated clock
- */
-
- int chip_version = NVPTR(pScrn)->vbios->chip_version;
- int minvco1 = pll_lim->vco1.minfreq, maxvco1 = pll_lim->vco1.maxfreq;
- int minvco2 = pll_lim->vco2.minfreq, maxvco2 = pll_lim->vco2.maxfreq;
- int minU1 = pll_lim->vco1.min_inputfreq, minU2 = pll_lim->vco2.min_inputfreq;
- int maxU1 = pll_lim->vco1.max_inputfreq, maxU2 = pll_lim->vco2.max_inputfreq;
- int minM1 = pll_lim->vco1.min_m, maxM1 = pll_lim->vco1.max_m;
- int minN1 = pll_lim->vco1.min_n, maxN1 = pll_lim->vco1.max_n;
- int minM2 = pll_lim->vco2.min_m, maxM2 = pll_lim->vco2.max_m;
- int minN2 = pll_lim->vco2.min_n, maxN2 = pll_lim->vco2.max_n;
- int maxlog2P = pll_lim->max_usable_log2p;
- int crystal = pll_lim->refclk;
- bool fixedgain2 = (minM2 == maxM2 && minN2 == maxN2);
- int M1, N1, M2, N2, log2P;
- int clkP, calcclk1, calcclk2, calcclkout;
- int delta, bestdelta = INT_MAX;
- int bestclk = 0;
-
- int vco2 = (maxvco2 - maxvco2/200) / 2;
- for (log2P = 0; clk && log2P < maxlog2P && clk <= (vco2 >> log2P); log2P++)
- ;
- clkP = clk << log2P;
-
- if (maxvco2 < clk + clk/200) /* +0.5% */
- maxvco2 = clk + clk/200;
-
- for (M1 = minM1; M1 <= maxM1; M1++) {
- if (crystal/M1 < minU1)
- return bestclk;
- if (crystal/M1 > maxU1)
- continue;
-
- for (N1 = minN1; N1 <= maxN1; N1++) {
- calcclk1 = crystal * N1 / M1;
- if (calcclk1 < minvco1)
- continue;
- if (calcclk1 > maxvco1)
- break;
-
- for (M2 = minM2; M2 <= maxM2; M2++) {
- if (calcclk1/M2 < minU2)
- break;
- if (calcclk1/M2 > maxU2)
- continue;
-
- /* add calcclk1/2 to round better */
- N2 = (clkP * M2 + calcclk1/2) / calcclk1;
- if (N2 < minN2)
- continue;
- if (N2 > maxN2)
- break;
-
- if (!fixedgain2) {
- if (chip_version < 0x60)
- if (N2/M2 < 4 || N2/M2 > 10)
- continue;
-
- calcclk2 = calcclk1 * N2 / M2;
- if (calcclk2 < minvco2)
- break;
- if (calcclk2 > maxvco2)
- continue;
- } else
- calcclk2 = calcclk1;
-
- calcclkout = calcclk2 >> log2P;
- delta = abs(calcclkout - clk);
- /* we do an exhaustive search rather than terminating
- * on an optimality condition...
- */
- if (delta < bestdelta) {
- bestdelta = delta;
- bestclk = calcclkout;
- bestpv->N1 = N1;
- bestpv->M1 = M1;
- bestpv->N2 = N2;
- bestpv->M2 = M2;
- bestpv->log2P = log2P;
- if (delta == 0) /* except this one */
- return bestclk;
- }
- }
- }
- }
-
- return bestclk;
-}
-
-int nouveau_calc_pll_mnp(ScrnInfoPtr pScrn, struct pll_lims *pll_lim, int clk,
- struct nouveau_pll_vals *pv)
-{
- int outclk;
-
- if (!pll_lim->vco2.maxfreq)
- outclk = getMNP_single(pScrn, pll_lim, clk, pv);
- else
- outclk = getMNP_double(pScrn, pll_lim, clk, pv);
-
- if (!outclk)
- NV_ERROR(pScrn,
- "Could not find a compatible set of PLL values\n");
-
- return outclk;
-}
diff --git a/src/nouveau_connector.h b/src/nouveau_connector.h
deleted file mode 100644
index 5d2c8af..0000000
--- a/src/nouveau_connector.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2008 Maarten Maathuis
- *
- * 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 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.
- */
-
-#ifndef __NOUVEAU_CONNECTOR_H_
-#define __NOUVEAU_CONNECTOR_H_
-
-#include "nv_include.h"
-#include "nouveau_modeset.h"
-#include "nouveau_crtc.h"
-#include "nouveau_output.h"
-
-/* I have yet to find specific information on connectors, so it's all derived from outputs. */
-typedef enum {
- CONNECTOR_NONE = 4,
- CONNECTOR_VGA = 0,
- CONNECTOR_DVI = 1,
- CONNECTOR_TV = 2,
- CONNECTOR_PANEL = 3
-} NVConnectorType;
-
-#define MAX_OUTPUTS_PER_CONNECTOR 2
-
-typedef struct nouveauConnector {
- ScrnInfoPtr scrn;
- int index;
-
- char *name;
- Bool active;
-
- NVConnectorType type;
-
- I2CBusPtr pDDCBus;
- int i2c_index;
-
- /* For load detect amongst other things. */
- nouveauOutputPtr outputs[MAX_OUTPUTS_PER_CONNECTOR];
- int connected_output;
-
- Bool hotplug_detected; /* better name? */
- /* Function pointers. */
- Bool (*HotplugDetect) (nouveauConnectorPtr connector);
- xf86MonPtr (*DDCDetect) (nouveauConnectorPtr connector);
- DisplayModePtr (*GetDDCModes) (nouveauConnectorPtr connector);
-} nouveauConnectorRec;
-
-#endif /* __NOUVEAU_CONNECTOR_H_ */
diff --git a/src/nouveau_crtc.h b/src/nouveau_crtc.h
deleted file mode 100644
index 45d0eee..0000000
--- a/src/nouveau_crtc.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2008 Maarten Maathuis
- *
- * 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 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.
- */
-
-#ifndef __NOUVEAU_CRTC_H_
-#define __NOUVEAU_CRTC_H_
-
-#include "nv_include.h"
-#include "nouveau_modeset.h"
-
-typedef struct nouveauCrtc {
- ScrnInfoPtr scrn;
-
- char *name;
- uint8_t index;
- Bool active;
- Bool blanked;
-
- /* Scanout area. */
- struct nouveau_bo * front_buffer;
- uint32_t fb_pitch;
- uint32_t x; /* relative to the frontbuffer */
- uint32_t y;
-
- /* Gamma */
- struct nouveau_bo *lut;
- struct {
- uint16_t red;
- uint16_t green;
- uint16_t blue;
- uint16_t unused;
- } lut_values[256];
- bool lut_values_valid;
-
- /* Options and some state. */
- Bool modeset_lock;
- Bool dithering;
- Bool cursor_visible;
- Bool use_native_mode;
- int scale_mode;
- int pixel_clock;
-
- /* Mode info. */
- DisplayModePtr cur_mode;
- DisplayModePtr native_mode;
- DisplayModePtr mode_list;
-
- /* Function pointers. */
- Bool (*ModeValid) (nouveauCrtcPtr crtc, DisplayModePtr mode);
- void (*ModeSet) (nouveauCrtcPtr crtc, DisplayModePtr mode);
- void (*SetPixelClock) (nouveauCrtcPtr crtc, int clock);
- void (*SetClockMode) (nouveauCrtcPtr crtc, int clock); /* maybe another name? */
-
- void (*SetFB) (nouveauCrtcPtr crtc, struct nouveau_bo * buffer);
- void (*SetFBOffset) (nouveauCrtcPtr crtc, uint32_t x, uint32_t y);
-
- void (*Blank) (nouveauCrtcPtr crtc, Bool blanked);
- void (*SetDither) (nouveauCrtcPtr crtc);
-
- void (*SetScaleMode) (nouveauCrtcPtr crtc, int scale);
-
- void (*ShowCursor) (nouveauCrtcPtr crtc, Bool forced_lock);
- void (*HideCursor) (nouveauCrtcPtr crtc, Bool forced_lock);
- void (*SetCursorPosition) (nouveauCrtcPtr crtc, int x, int y);
- void (*LoadCursor) (nouveauCrtcPtr crtc, Bool argb, uint32_t *src);
-
- void (*GammaSet) (nouveauCrtcPtr crtc, uint16_t *red, uint16_t *green, uint16_t *blue, int size);
-
- void (*Save) (nouveauCrtcPtr crtc);
- void (*Load) (nouveauCrtcPtr crtc);
-} nouveauCrtcRec;
-
-#endif /* __NOUVEAU_CRTC_H_ */
diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c
index 5707add..d8c2d45 100644
--- a/src/nouveau_exa.c
+++ b/src/nouveau_exa.c
@@ -726,8 +726,2 @@ nouveau_exa_init(ScreenPtr pScreen)
return FALSE;
- else
- /* EXA init catches this, but only for xserver >= 1.4 */
- if (pNv->VRAMPhysicalSize / 2 < NOUVEAU_ALIGN(pScrn->virtualX, 64) * NOUVEAU_ALIGN(pScrn->virtualY, 64) * (pScrn->bitsPerPixel >> 3)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "The virtual screen size's resolution is too big for the video RAM framebuffer at this colour depth.\n");
- return FALSE;
- }
diff --git a/src/nouveau_hw.c b/src/nouveau_hw.c
deleted file mode 100644
index ff36407..0000000
--- a/src/nouveau_hw.c
+++ /dev/null
@@ -1,1031 +0,0 @@
-/*
- * Copyright 2006 Dave Airlie
- * Copyright 2007 Maarten Maathuis
- * Copyright 2007-2009 Stuart Bennett
- *
- * 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 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.
- */
-
-#include "nv_include.h"
-
-/*
- * misc hw access wrappers/control functions
- */
-
-void NVWriteVgaSeq(NVPtr pNv, int head, uint8_t index, uint8_t value)
-{
- NVWritePRMVIO(pNv, head, NV_PRMVIO_SRX, index);
- NVWritePRMVIO(pNv, head, NV_PRMVIO_SR, value);
-}
-
-uint8_t NVReadVgaSeq(NVPtr pNv, int head, uint8_t index)
-{
- NVWritePRMVIO(pNv, head, NV_PRMVIO_SRX, index);
- return NVReadPRMVIO(pNv, head, NV_PRMVIO_SR);
-}
-
-void NVWriteVgaGr(NVPtr pNv, int head, uint8_t index, uint8_t value)
-{
- NVWritePRMVIO(pNv, head, NV_PRMVIO_GRX, index);
- NVWritePRMVIO(pNv, head, NV_PRMVIO_GX, value);
-}
-
-uint8_t NVReadVgaGr(NVPtr pNv, int head, uint8_t index)
-{
- NVWritePRMVIO(pNv, head, NV_PRMVIO_GRX, index);
- return NVReadPRMVIO(pNv, head, NV_PRMVIO_GX);
-}
-
-/* CR44 takes values 0 (head A), 3 (head B) and 4 (heads tied)
- * it affects only the 8 bit vga io regs, which we access using mmio at
- * 0xc{0,2}3c*, 0x60{1,3}3*, and 0x68{1,3}3d*
- * in general, the set value of cr44 does not matter: reg access works as
- * expected and values can be set for the appropriate head by using a 0x2000
- * offset as required
- * however:
- * a) pre nv40, the head B range of PRMVIO regs at 0xc23c* was not exposed and
- * cr44 must be set to 0 or 3 for accessing values on the correct head
- * through the common 0xc03c* addresses
- * b) in tied mode (4) head B is programmed to the values set on head A, and
- * access using the head B addresses can have strange results, ergo we leave
- * tied mode in init once we know to what cr44 should be restored on exit
- *
- * the owner parameter is slightly abused:
- * 0 and 1 are treated as head values and so the set value is (owner * 3)
- * other values are treated as literal values to set
- */
-void NVSetOwner(NVPtr pNv, int owner)
-{
- if (owner == 1)
- owner *= 3;
- /* CR44 is always changed on CRTC0 */
- NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_44, owner);
- if (pNv->NVArch == 0x11) { /* set me harder */
- NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_2E, owner);
- NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_2E, owner);
- }
-}
-
-/*
- * on nv11 this may not be reliable
- * returned value is suitable for directly programming back into cr44
- */
-int nouveau_hw_get_current_head(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- int cr44;
-
- if (pNv->NVArch != 0x11)
- return NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_44);
-
- /* reading CR44 is broken on nv11, so we attempt to infer it */
- if (nvReadMC(pNv, NV_PBUS_DEBUG_1) & (1 << 28)) /* heads tied, restore both */
- cr44 = 0x4;
- else {
- bool slaved_on_A, tvA = false;
- bool slaved_on_B, tvB = false;
- bool waslocked;
-
- waslocked = NVLockVgaCrtcs(pNv, false);
-
- slaved_on_A = NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_PIXEL_INDEX) & 0x80;
- if (slaved_on_A)
- tvA = !(NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_LCD__INDEX) & MASK(NV_CIO_CRE_LCD_LCD_SELECT));
-
- slaved_on_B = NVReadVgaCrtc(pNv, 1, NV_CIO_CRE_PIXEL_INDEX) & 0x80;
- if (slaved_on_B)
- tvB = !(NVReadVgaCrtc(pNv, 1, NV_CIO_CRE_LCD__INDEX) & MASK(NV_CIO_CRE_LCD_LCD_SELECT));
-
- if (waslocked)
- NVLockVgaCrtcs(pNv, true);
-
- if (slaved_on_A && !tvA)
- cr44 = 0x0;
- else if (slaved_on_B && !tvB)
- cr44 = 0x3;
- else if (slaved_on_A)
- cr44 = 0x0;
- else if (slaved_on_B)
- cr44 = 0x3;
- else
- cr44 = 0x0;
- }
-
- return cr44;
-}
-
-void NVBlankScreen(NVPtr pNv, int head, bool blank)
-{
- unsigned char seq1;
-
- if (pNv->twoHeads)
- NVSetOwner(pNv, head);
-
- seq1 = NVReadVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX);
-
- NVVgaSeqReset(pNv, head, true);
- if (blank)
- NVWriteVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20);
- else
- NVWriteVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20);
- NVVgaSeqReset(pNv, head, false);
-}
-
-/*
- * PLL setting
- */
-
-static int powerctrl_1_shift(int chip_version, int reg)
-{
- int shift = -4;
-
- if (chip_version < 0x17 || chip_version == 0x1a || chip_version == 0x20)
- return shift;
-
- switch (reg) {
- case NV_RAMDAC_VPLL2:
- shift += 4;
- case NV_PRAMDAC_VPLL_COEFF:
- shift += 4;
- case NV_PRAMDAC_MPLL_COEFF:
- shift += 4;
- case NV_PRAMDAC_NVPLL_COEFF:
- shift += 4;
- }
-
- /*
- * the shift for vpll regs is only used for nv3x chips with a single
- * stage pll
- */
- if (shift > 4 && (chip_version < 0x32 || chip_version == 0x35 ||
- chip_version == 0x36 || chip_version >= 0x40))
- shift = -4;
-
- return shift;
-}
-
-static void setPLL_single(ScrnInfoPtr pScrn, uint32_t reg,
- struct nouveau_pll_vals *pv)
-{
- NVPtr pNv = NVPTR(pScrn);
- int chip_version = pNv->vbios->chip_version;
- uint32_t oldpll = NVReadRAMDAC(pNv, 0, reg);
- int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
- uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
- uint32_t saved_powerctrl_1 = 0;
- int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg);
-
- if (oldpll == pll)
- return; /* already set */
-
- if (shift_powerctrl_1 >= 0) {
- saved_powerctrl_1 = nvReadMC(pNv, NV_PBUS_POWERCTRL_1);
- nvWriteMC(pNv, NV_PBUS_POWERCTRL_1,
- (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
- 1 << shift_powerctrl_1);
- }
-
- if (oldM && pv->M1 && (oldN / oldM < pv->N1 / pv->M1))
- /* upclock -- write new post divider first */
- NVWriteRAMDAC(pNv, 0, reg, pv->log2P << 16 | (oldpll & 0xffff));
- else
- /* downclock -- write new NM first */
- NVWriteRAMDAC(pNv, 0, reg, (oldpll & 0xffff0000) | pv->NM1);
-
- if (chip_version < 0x17 && chip_version != 0x11)
- /* wait a bit on older chips */
- usleep(64000);
- NVReadRAMDAC(pNv, 0, reg);
-
- /* then write the other half as well */
- NVWriteRAMDAC(pNv, 0, reg, pll);
-
- if (shift_powerctrl_1 >= 0)
- nvWriteMC(pNv, NV_PBUS_POWERCTRL_1, saved_powerctrl_1);
-}
-
-static uint32_t new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580)
-{
- bool head_a = (reg1 == NV_PRAMDAC_VPLL_COEFF);
-
- if (ss) /* single stage pll mode */
- ramdac580 |= head_a ? NV_RAMDAC_580_VPLL1_ACTIVE :
- NV_RAMDAC_580_VPLL2_ACTIVE;
- else
- ramdac580 &= head_a ? ~NV_RAMDAC_580_VPLL1_ACTIVE :
- ~NV_RAMDAC_580_VPLL2_ACTIVE;
-
- return ramdac580;
-}
-
-static void setPLL_double_highregs(ScrnInfoPtr pScrn, uint32_t reg1,
- struct nouveau_pll_vals *pv)
-{
- NVPtr pNv = NVPTR(pScrn);
- int chip_version = pNv->vbios->chip_version;
- bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
- uint32_t reg2 = reg1 + ((reg1 == NV_RAMDAC_VPLL2) ? 0x5c : 0x70);
- uint32_t oldpll1 = NVReadRAMDAC(pNv, 0, reg1);
- uint32_t oldpll2 = !nv3035 ? NVReadRAMDAC(pNv, 0, reg2) : 0;
- uint32_t pll1 = (oldpll1 & 0xfff80000) | pv->log2P << 16 | pv->NM1;
- uint32_t pll2 = (oldpll2 & 0x7fff0000) | 1 << 31 | pv->NM2;
- uint32_t oldramdac580 = 0, ramdac580 = 0;
- bool single_stage = !pv->NM2 || pv->N2 == pv->M2; /* nv41+ only */
- uint32_t saved_powerctrl_1 = 0, savedc040 = 0;
- int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg1);
-
- /* model specific additions to generic pll1 and pll2 set up above */
- if (nv3035) {
- pll1 = (pll1 & 0xfcc7ffff) | (pv->N2 & 0x18) << 21 |
- (pv->N2 & 0x7) << 19 | 8 << 4 | (pv->M2 & 7) << 4;
- pll2 = 0;
- }
- if (chip_version > 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) { /* !nv40 */
- oldramdac580 = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_580);
- ramdac580 = new_ramdac580(reg1, single_stage, oldramdac580);
- if (oldramdac580 != ramdac580)
- oldpll1 = ~0; /* force mismatch */
- if (single_stage)
- /* magic value used by nvidia in single stage mode */
- pll2 |= 0x011f;
- }
- if (chip_version > 0x70)
- /* magic bits set by the blob (but not the bios) on g71-73 */
- pll1 = (pll1 & 0x7fffffff) | (single_stage ? 0x4 : 0xc) << 28;
-
- if (oldpll1 == pll1 && oldpll2 == pll2)
- return; /* already set */
-
- if (shift_powerctrl_1 >= 0) {
- saved_powerctrl_1 = nvReadMC(pNv, NV_PBUS_POWERCTRL_1);
- nvWriteMC(pNv, NV_PBUS_POWERCTRL_1,
- (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
- 1 << shift_powerctrl_1);
- }
-
- if (chip_version >= 0x40) {
- int shift_c040 = 14;
-
- switch (reg1) {
- case NV_PRAMDAC_MPLL_COEFF:
- shift_c040 += 2;
- case NV_PRAMDAC_NVPLL_COEFF:
- shift_c040 += 2;
- case NV_RAMDAC_VPLL2:
- shift_c040 += 2;
- case NV_PRAMDAC_VPLL_COEFF:
- shift_c040 += 2;
- }
-
- savedc040 = nvReadMC(pNv, 0xc040);
- if (shift_c040 != 14)
- nvWriteMC(pNv, 0xc040, savedc040 & ~(3 << shift_c040));
- }
-
- if (oldramdac580 != ramdac580)
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_580, ramdac580);
-
- if (!nv3035)
- NVWriteRAMDAC(pNv, 0, reg2, pll2);
- NVWriteRAMDAC(pNv, 0, reg1, pll1);
-
- if (shift_powerctrl_1 >= 0)
- nvWriteMC(pNv, NV_PBUS_POWERCTRL_1, saved_powerctrl_1);
- if (chip_version >= 0x40)
- nvWriteMC(pNv, 0xc040, savedc040);
-}
-
-static void setPLL_double_lowregs(ScrnInfoPtr pScrn, uint32_t NMNMreg,
- struct nouveau_pll_vals *pv)
-{
- /* When setting PLLs, there is a merry game of disabling and enabling
- * various bits of hardware during the process. This function is a
- * synthesis of six nv4x traces, nearly each card doing a subtly
- * different thing. With luck all the necessary bits for each card are
- * combined herein. Without luck it deviates from each card's formula
- * so as to not work on any :)
- */
-
- NVPtr pNv = NVPTR(pScrn);
- uint32_t Preg = NMNMreg - 4;
- bool mpll = Preg == 0x4020;
- uint32_t oldPval = nvReadMC(pNv, Preg);
- uint32_t NMNM = pv->NM2 << 16 | pv->NM1;
- uint32_t Pval = (oldPval & (mpll ? ~(0x11 << 16) : ~(1 << 16))) |
- 0xc << 28 | pv->log2P << 16;
- uint32_t saved4600 = 0;
- /* some cards have different maskc040s */
- uint32_t maskc040 = ~(3 << 14), savedc040;
- bool single_stage = !pv->NM2 || pv->N2 == pv->M2;
-
- if (nvReadMC(pNv, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval)
- return;
-
- if (Preg == 0x4000)
- maskc040 = ~0x333;
- if (Preg == 0x4058)
- maskc040 = ~(0xc << 24);
-
- if (mpll) {
- struct pll_lims pll_lim;
- uint8_t Pval2;
-
- if (get_pll_limits(pScrn, Preg, &pll_lim))
- return;
-
- Pval2 = pv->log2P + pll_lim.log2p_bias;
- if (Pval2 > pll_lim.max_log2p)
- Pval2 = pll_lim.max_log2p;
- Pval |= 1 << 28 | Pval2 << 20;
-
- saved4600 = nvReadMC(pNv, 0x4600);
- nvWriteMC(pNv, 0x4600, saved4600 | 8 << 28);
- }
- if (single_stage)
- Pval |= mpll ? 1 << 12 : 1 << 8;
-
- nvWriteMC(pNv, Preg, oldPval | 1 << 28);
- nvWriteMC(pNv, Preg, Pval & ~(4 << 28));
- if (mpll) {
- Pval |= 8 << 20;
- nvWriteMC(pNv, 0x4020, Pval & ~(0xc << 28));
- nvWriteMC(pNv, 0x4038, Pval & ~(0xc << 28));
- }
-
- savedc040 = nvReadMC(pNv, 0xc040);
- nvWriteMC(pNv, 0xc040, savedc040 & maskc040);
-
- nvWriteMC(pNv, NMNMreg, NMNM);
- if (NMNMreg == 0x4024)
- nvWriteMC(pNv, 0x403c, NMNM);
-
- nvWriteMC(pNv, Preg, Pval);
- if (mpll) {
- Pval &= ~(8 << 20);
- nvWriteMC(pNv, 0x4020, Pval);
- nvWriteMC(pNv, 0x4038, Pval);
- nvWriteMC(pNv, 0x4600, saved4600);
- }
-
- nvWriteMC(pNv, 0xc040, savedc040);
-
- if (mpll) {
- nvWriteMC(pNv, 0x4020, Pval & ~(1 << 28));
- nvWriteMC(pNv, 0x4038, Pval & ~(1 << 28));
- }
-}
-
-void nouveau_hw_setpll(ScrnInfoPtr pScrn, uint32_t reg1,
- struct nouveau_pll_vals *pv)
-{
- int cv = NVPTR(pScrn)->vbios->chip_version;
-
- if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
- cv >= 0x40) {
- if (reg1 > 0x405c)
- setPLL_double_highregs(pScrn, reg1, pv);
- else
- setPLL_double_lowregs(pScrn, reg1, pv);
- } else
- setPLL_single(pScrn, reg1, pv);
-}
-
-/*
- * PLL getting
- */
-
-static void nouveau_hw_decode_pll(NVPtr pNv, uint32_t reg1,
- uint32_t pll1, uint32_t pll2,
- struct nouveau_pll_vals *pllvals)
-{
- /* to force parsing as single stage (i.e. nv40 vplls) pass pll2 as 0 */
-
- /* log2P is & 0x7 as never more than 7, and nv30/35 only uses 3 bits */
- pllvals->log2P = (pll1 >> 16) & 0x7;
- pllvals->N2 = pllvals->M2 = 1;
-
- if (reg1 <= 0x405c) {
- pllvals->NM1 = pll2 & 0xffff;
- /* single stage NVPLL and VPLLs use 1 << 8, MPLL uses 1 << 12 */
- if (!(pll1 & 0x1100))
- pllvals->NM2 = pll2 >> 16;
- } else {
- pllvals->NM1 = pll1 & 0xffff;
- if (pNv->two_reg_pll && pll2 & NV31_RAMDAC_ENABLE_VCO2)
- pllvals->NM2 = pll2 & 0xffff;
- else if (pNv->NVArch == 0x30 || pNv->NVArch == 0x35) {
- pllvals->M1 &= 0xf; /* only 4 bits */
- if (pll1 & NV30_RAMDAC_ENABLE_VCO2) {
- pllvals->M2 = (pll1 >> 4) & 0x7;
- pllvals->N2 = ((pll1 >> 21) & 0x18) |
- ((pll1 >> 19) & 0x7);
- }
- }
- }
-}
-
-int nouveau_hw_get_pllvals(ScrnInfoPtr pScrn, enum pll_types plltype,
- struct nouveau_pll_vals *pllvals)
-{
- NVPtr pNv = NVPTR(pScrn);
- const uint32_t nv04_regs[MAX_PLL_TYPES] = { NV_PRAMDAC_NVPLL_COEFF,
- NV_PRAMDAC_MPLL_COEFF,
- NV_PRAMDAC_VPLL_COEFF,
- NV_RAMDAC_VPLL2 };
- const uint32_t nv40_regs[MAX_PLL_TYPES] = { 0x4000,
- 0x4020,
- NV_PRAMDAC_VPLL_COEFF,
- NV_RAMDAC_VPLL2 };
- uint32_t reg1, pll1, pll2 = 0;
- struct pll_lims pll_lim;
- int ret;
-
- if (pNv->Architecture < NV_ARCH_40)
- reg1 = nv04_regs[plltype];
- else
- reg1 = nv40_regs[plltype];
-
- pll1 = nvReadMC(pNv, reg1);
-
- if (reg1 <= 0x405c)
- pll2 = nvReadMC(pNv, reg1 + 4);
- else if (pNv->two_reg_pll) {
- uint32_t reg2 = reg1 + (reg1 == NV_RAMDAC_VPLL2 ? 0x5c : 0x70);
-
- pll2 = nvReadMC(pNv, reg2);
- }
-
- if (pNv->Architecture == 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) {
- uint32_t ramdac580 = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_580);
-
- /* check whether vpll has been forced into single stage mode */
- if (reg1 == NV_PRAMDAC_VPLL_COEFF) {
- if (ramdac580 & NV_RAMDAC_580_VPLL1_ACTIVE)
- pll2 = 0;
- } else
- if (ramdac580 & NV_RAMDAC_580_VPLL2_ACTIVE)
- pll2 = 0;
- }
-
- nouveau_hw_decode_pll(pNv, reg1, pll1, pll2, pllvals);
-
- if ((ret = get_pll_limits(pScrn, plltype, &pll_lim)))
- return ret;
-
- pllvals->refclk = pll_lim.refclk;
-
- return 0;
-}
-
-int nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pv)
-{
- /* Avoid divide by zero if called at an inappropriate time */
- if (!pv->M1 || !pv->M2)
- return 0;
-
- return (pv->N1 * pv->N2 * pv->refclk / (pv->M1 * pv->M2) >> pv->log2P);
-}
-
-int nouveau_hw_get_clock(ScrnInfoPtr pScrn, enum pll_types plltype)
-{
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_pll_vals pllvals;
-
- if (plltype == MPLL && (pNv->Chipset & 0x0ff0) == CHIPSET_NFORCE) {
- struct pci_device *dev = pci_device_find_by_slot(0, 0, 0, 3);
- uint32_t mpllP;
-
- pci_device_cfg_read_u32(dev, &mpllP, 0x6c);
- mpllP = (mpllP >> 8) & 0xf;
-
- if (!mpllP)
- mpllP = 4;
- return 400000 / mpllP;
- } else
- if (plltype == MPLL && (pNv->Chipset & 0xff0) == CHIPSET_NFORCE2) {
- struct pci_device *dev = pci_device_find_by_slot(0, 0, 0, 5);
- uint32_t data;
-
- pci_device_cfg_read_u32(dev, &data, 0x4c);
-
- return data / 1000;
- }
-
- nouveau_hw_get_pllvals(pScrn, plltype, &pllvals);
-
- return nouveau_hw_pllvals_to_clk(&pllvals);
-}
-
-static void nouveau_hw_fix_bad_vpll(ScrnInfoPtr pScrn, int head)
-{
- /* the vpll on an unused head can come up with a random value, way
- * beyond the pll limits. for some reason this causes the chip to
- * lock up when reading the dac palette regs, so set a valid pll here
- * when such a condition detected. only seen on nv11 to date
- */
-
- struct pll_lims pll_lim;
- struct nouveau_pll_vals pv;
- uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF;
-
- if (get_pll_limits(pScrn, head ? VPLL2 : VPLL1, &pll_lim))
- return;
- nouveau_hw_get_pllvals(pScrn, head ? VPLL2 : VPLL1, &pv);
-
- if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m &&
- pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n &&
- pv.log2P <= pll_lim.max_log2p)
- return;
-
- NV_WARN(pScrn, "VPLL %d outwith limits, attempting to fix\n", head + 1);
-
- /* set lowest clock within static limits */
- pv.M1 = pll_lim.vco1.max_m;
- pv.N1 = pll_lim.vco1.min_n;
- pv.log2P = pll_lim.max_usable_log2p;
- nouveau_hw_setpll(pScrn, pllreg, &pv);
-}
-
-/*
- * vga font save/restore
- */
-
-void nouveau_hw_save_vga_fonts(ScrnInfoPtr pScrn, bool save)
-{
- NVPtr pNv = NVPTR(pScrn);
- bool graphicsmode;
- uint8_t misc, gr4, gr5, gr6, seq2, seq4;
- int i;
-
- if (pNv->twoHeads)
- NVSetOwner(pNv, 0);
-
- NVSetEnablePalette(pNv, 0, true);
- graphicsmode = NVReadVgaAttr(pNv, 0, NV_CIO_AR_MODE_INDEX) & 1;
- NVSetEnablePalette(pNv, 0, false);
-
- if (graphicsmode) /* graphics mode => framebuffer => no need to save */
- return;
-
- NV_TRACE(pScrn, "%sing VGA fonts\n", save ? "Sav" : "Restor");
- if (pNv->twoHeads)
- NVBlankScreen(pNv, 1, true);
- NVBlankScreen(pNv, 0, true);
-
- /* save control regs */
- misc = NVReadPRMVIO(pNv, 0, NV_PRMVIO_MISC__READ);
- seq2 = NVReadVgaSeq(pNv, 0, NV_VIO_SR_PLANE_MASK_INDEX);
- seq4 = NVReadVgaSeq(pNv, 0, NV_VIO_SR_MEM_MODE_INDEX);
- gr4 = NVReadVgaGr(pNv, 0, NV_VIO_GX_READ_MAP_INDEX);
- gr5 = NVReadVgaGr(pNv, 0, NV_VIO_GX_MODE_INDEX);
- gr6 = NVReadVgaGr(pNv, 0, NV_VIO_GX_MISC_INDEX);
-
- NVWritePRMVIO(pNv, 0, NV_PRMVIO_MISC__WRITE, 0x67);
- NVWriteVgaSeq(pNv, 0, NV_VIO_SR_MEM_MODE_INDEX, 0x6);
- NVWriteVgaGr(pNv, 0, NV_VIO_GX_MODE_INDEX, 0x0);
- NVWriteVgaGr(pNv, 0, NV_VIO_GX_MISC_INDEX, 0x5);
-
- /* store font in plane 0 */
- NVWriteVgaSeq(pNv, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x1);
- NVWriteVgaGr(pNv, 0, NV_VIO_GX_READ_MAP_INDEX, 0x0);
- for (i = 0; i < 16384; i++)
- if (save)
- pNv->saved_vga_font[0][i] = MMIO_IN32(pNv->FB_BAR, i * 4);
- else
- MMIO_OUT32(pNv->FB_BAR, i * 4, pNv->saved_vga_font[0][i]);
-
- /* store font in plane 1 */
- NVWriteVgaSeq(pNv, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x2);
- NVWriteVgaGr(pNv, 0, NV_VIO_GX_READ_MAP_INDEX, 0x1);
- for (i = 0; i < 16384; i++)
- if (save)
- pNv->saved_vga_font[1][i] = MMIO_IN32(pNv->FB_BAR, i * 4);
- else
- MMIO_OUT32(pNv->FB_BAR, i * 4, pNv->saved_vga_font[1][i]);
-
- /* store font in plane 2 */
- NVWriteVgaSeq(pNv, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x4);
- NVWriteVgaGr(pNv, 0, NV_VIO_GX_READ_MAP_INDEX, 0x2);
- for (i = 0; i < 16384; i++)
- if (save)
- pNv->saved_vga_font[2][i] = MMIO_IN32(pNv->FB_BAR, i * 4);
- else
- MMIO_OUT32(pNv->FB_BAR, i * 4, pNv->saved_vga_font[2][i]);
-
- /* store font in plane 3 */
- NVWriteVgaSeq(pNv, 0, NV_VIO_SR_PLANE_MASK_INDEX, 0x8);
- NVWriteVgaGr(pNv, 0, NV_VIO_GX_READ_MAP_INDEX, 0x3);
- for (i = 0; i < 16384; i++)
- if (save)
- pNv->saved_vga_font[3][i] = MMIO_IN32(pNv->FB_BAR, i * 4);
- else
- MMIO_OUT32(pNv->FB_BAR, i * 4, pNv->saved_vga_font[3][i]);
-
- /* restore control regs */
- NVWritePRMVIO(pNv, 0, NV_PRMVIO_MISC__WRITE, misc);
- NVWriteVgaGr(pNv, 0, NV_VIO_GX_READ_MAP_INDEX, gr4);
- NVWriteVgaGr(pNv, 0, NV_VIO_GX_MODE_INDEX, gr5);
- NVWriteVgaGr(pNv, 0, NV_VIO_GX_MISC_INDEX, gr6);
- NVWriteVgaSeq(pNv, 0, NV_VIO_SR_PLANE_MASK_INDEX, seq2);
- NVWriteVgaSeq(pNv, 0, NV_VIO_SR_MEM_MODE_INDEX, seq4);
-
- if (pNv->twoHeads)
- NVBlankScreen(pNv, 1, false);
- NVBlankScreen(pNv, 0, false);
-}
-
-/*
- * mode state save/load
- */
-
-static void rd_cio_state(NVPtr pNv, int head,
- struct nouveau_crtc_state *crtcstate, int index)
-{
- crtcstate->CRTC[index] = NVReadVgaCrtc(pNv, head, index);
-}
-
-static void wr_cio_state(NVPtr pNv, int head,
- struct nouveau_crtc_state *crtcstate, int index)
-{
- NVWriteVgaCrtc(pNv, head, index, crtcstate->CRTC[index]);
-}
-
-static void
-nv_save_state_ramdac(ScrnInfoPtr pScrn, int head, struct nouveau_mode_state *state)
-{
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_crtc_state *regp = &state->head[head];
- int i;
-
- if (pNv->Architecture >= NV_ARCH_10)
- regp->nv10_cursync = NVReadRAMDAC(pNv, head, NV_RAMDAC_NV10_CURSYNC);
-
- nouveau_hw_get_pllvals(pScrn, head ? VPLL2 : VPLL1, &regp->pllvals);
- state->pllsel = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_PLL_COEFF_SELECT);
- if (pNv->twoHeads)
- state->sel_clk = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_SEL_CLK);
- if (pNv->NVArch == 0x11)
- regp->dither = NVReadRAMDAC(pNv, head, NV_RAMDAC_DITHER_NV11);
-
- regp->ramdac_gen_ctrl = NVReadRAMDAC(pNv, head, NV_PRAMDAC_GENERAL_CONTROL);
-
- if (pNv->gf4_disp_arch)
- regp->ramdac_630 = NVReadRAMDAC(pNv, head, NV_PRAMDAC_630);
- if (pNv->NVArch >= 0x30)
- regp->ramdac_634 = NVReadRAMDAC(pNv, head, NV_PRAMDAC_634);
-
- for (i = 0; i < 7; i++) {
- uint32_t ramdac_reg = NV_PRAMDAC_FP_VDISPLAY_END + (i * 4);
-
- regp->fp_vert_regs[i] = NVReadRAMDAC(pNv, head, ramdac_reg);
- regp->fp_horiz_regs[i] = NVReadRAMDAC(pNv, head, ramdac_reg + 0x20);
- }
-
- if (pNv->gf4_disp_arch) {
- regp->dither = NVReadRAMDAC(pNv, head, NV_RAMDAC_FP_DITHER);
- for (i = 0; i < 3; i++) {
- regp->dither_regs[i] = NVReadRAMDAC(pNv, head, NV_PRAMDAC_850 + i * 4);
- regp->dither_regs[i + 3] = NVReadRAMDAC(pNv, head, NV_PRAMDAC_85C + i * 4);
- }
- }
-
- regp->fp_control = NVReadRAMDAC(pNv, head, NV_PRAMDAC_FP_TG_CONTROL);
- regp->fp_debug_0 = NVReadRAMDAC(pNv, head, NV_PRAMDAC_FP_DEBUG_0);
- if (!pNv->gf4_disp_arch && head == 0)
- /* early chips don't allow access to PRAMDAC_TMDS_* without
- * the head A FPCLK on (nv11 even locks up) */
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_FP_DEBUG_0, regp->fp_debug_0 &
- ~NV_PRAMDAC_FP_DEBUG_0_PWRDOWN_FPCLK);
- regp->fp_debug_1 = NVReadRAMDAC(pNv, head, NV_PRAMDAC_FP_DEBUG_1);
- regp->fp_debug_2 = NVReadRAMDAC(pNv, head, NV_PRAMDAC_FP_DEBUG_2);
-
- if (pNv->Architecture == NV_ARCH_40) {
- regp->ramdac_a20 = NVReadRAMDAC(pNv, head, NV_PRAMDAC_A20);
- regp->ramdac_a24 = NVReadRAMDAC(pNv, head, NV_PRAMDAC_A24);
- regp->ramdac_a34 = NVReadRAMDAC(pNv, head, NV_PRAMDAC_A34);
- }
-}
-
-static void nv_load_state_ramdac(ScrnInfoPtr pScrn, int head, struct nouveau_mode_state *state)
-{
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_crtc_state *regp = &state->head[head];
- uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF;
- int i;
-
- if (pNv->Architecture >= NV_ARCH_10)
- NVWriteRAMDAC(pNv, head, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync);
-
- nouveau_hw_setpll(pScrn, pllreg, &regp->pllvals);
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel);
- if (pNv->twoHeads)
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_SEL_CLK, state->sel_clk);
- if (pNv->NVArch == 0x11)
- NVWriteRAMDAC(pNv, head, NV_RAMDAC_DITHER_NV11, regp->dither);
-
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_GENERAL_CONTROL, regp->ramdac_gen_ctrl);
-
- if (pNv->gf4_disp_arch)
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_630, regp->ramdac_630);
- if (pNv->NVArch >= 0x30)
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_634, regp->ramdac_634);
-
- for (i = 0; i < 7; i++) {
- uint32_t ramdac_reg = NV_PRAMDAC_FP_VDISPLAY_END + (i * 4);
-
- NVWriteRAMDAC(pNv, head, ramdac_reg, regp->fp_vert_regs[i]);
- NVWriteRAMDAC(pNv, head, ramdac_reg + 0x20, regp->fp_horiz_regs[i]);
- }
-
- if (pNv->gf4_disp_arch) {
- NVWriteRAMDAC(pNv, head, NV_RAMDAC_FP_DITHER, regp->dither);
- for (i = 0; i < 3; i++) {
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_850 + i * 4, regp->dither_regs[i]);
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_85C + i * 4, regp->dither_regs[i + 3]);
- }
- }
-
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_FP_TG_CONTROL, regp->fp_control);
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_FP_DEBUG_0, regp->fp_debug_0);
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_FP_DEBUG_1, regp->fp_debug_1);
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_FP_DEBUG_2, regp->fp_debug_2);
-
- if (pNv->Architecture == NV_ARCH_40) {
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_A20, regp->ramdac_a20);
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_A24, regp->ramdac_a24);
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_A34, regp->ramdac_a34);
- }
-}
-
-static void
-nv_save_state_vga(NVPtr pNv, int head, struct nouveau_mode_state *state)
-{
- struct nouveau_crtc_state *regp = &state->head[head];
- int i;
-
- regp->MiscOutReg = NVReadPRMVIO(pNv, head, NV_PRMVIO_MISC__READ);
-
- for (i = 0; i < 25; i++)
- rd_cio_state(pNv, head, regp, i);
-
- NVSetEnablePalette(pNv, head, true);
- for (i = 0; i < 21; i++)
- regp->Attribute[i] = NVReadVgaAttr(pNv, head, i);
- NVSetEnablePalette(pNv, head, false);
-
- for (i = 0; i < 9; i++)
- regp->Graphics[i] = NVReadVgaGr(pNv, head, i);
-
- for (i = 0; i < 5; i++)
- regp->Sequencer[i] = NVReadVgaSeq(pNv, head, i);
-}
-
-static void nv_load_state_vga(NVPtr pNv, int head, struct nouveau_mode_state *state)
-{
- struct nouveau_crtc_state *regp = &state->head[head];
- int i;
-
- NVWritePRMVIO(pNv, head, NV_PRMVIO_MISC__WRITE, regp->MiscOutReg);
-
- for (i = 0; i < 5; i++)
- NVWriteVgaSeq(pNv, head, i, regp->Sequencer[i]);
-
- nv_lock_vga_crtc_base(pNv, head, false);
- for (i = 0; i < 25; i++)
- wr_cio_state(pNv, head, regp, i);
- nv_lock_vga_crtc_base(pNv, head, true);
-
- for (i = 0; i < 9; i++)
- NVWriteVgaGr(pNv, head, i, regp->Graphics[i]);
-
- NVSetEnablePalette(pNv, head, true);
- for (i = 0; i < 21; i++)
- NVWriteVgaAttr(pNv, head, i, regp->Attribute[i]);
- NVSetEnablePalette(pNv, head, false);
-}
-
-static void
-nv_save_state_ext(NVPtr pNv, int head, struct nouveau_mode_state *state)
-{
- struct nouveau_crtc_state *regp = &state->head[head];
- int i;
-
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_LCD__INDEX);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_RPC0_INDEX);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_RPC1_INDEX);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_LSR_INDEX);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_PIXEL_INDEX);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_HEB__INDEX);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_ENH_INDEX);
-
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_FF_INDEX);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_FFLWM__INDEX);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_21);
- if (pNv->Architecture >= NV_ARCH_30)
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_47);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_ILACE__INDEX);
-
- if (pNv->Architecture >= NV_ARCH_10) {
- regp->crtc_830 = NVReadCRTC(pNv, head, NV_PCRTC_830);
- regp->crtc_834 = NVReadCRTC(pNv, head, NV_PCRTC_834);
- if (pNv->Architecture == NV_ARCH_40) {
- regp->crtc_850 = NVReadCRTC(pNv, head, NV_PCRTC_850);
- regp->gpio_ext = NVReadCRTC(pNv, head, NV_PCRTC_GPIO_EXT);
- }
- if (pNv->twoHeads)
- regp->crtc_eng_ctrl = NVReadCRTC(pNv, head, NV_PCRTC_ENGINE_CTRL);
- regp->cursor_cfg = NVReadCRTC(pNv, head, NV_PCRTC_CURSOR_CONFIG);
- }
-
- regp->crtc_cfg = NVReadCRTC(pNv, head, NV_PCRTC_CONFIG);
-
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_SCRATCH3__INDEX);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_SCRATCH4__INDEX);
- if (pNv->Architecture >= NV_ARCH_10) {
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_EBR_INDEX);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_CSB);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_4B);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_TVOUT_LATENCY);
- }
- if (pNv->gf4_disp_arch) {
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_53);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_54);
-
- for (i = 0; i < 0x10; i++)
- regp->CR58[i] = NVReadVgaCrtc5758(pNv, head, i);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_59);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_5B);
-
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_85);
- rd_cio_state(pNv, head, regp, NV_CIO_CRE_86);
- }
-
- regp->fb_start = NVReadCRTC(pNv, head, NV_PCRTC_START);
-}
-
-static void nv_load_state_ext(NVPtr pNv, int head, struct nouveau_mode_state *state)
-{
- struct nouveau_crtc_state *regp = &state->head[head];
- int i;
-
- if (pNv->Architecture >= NV_ARCH_10) {
- if (pNv->twoHeads)
- /* setting ENGINE_CTRL (EC) *must* come before
- * CIO_CRE_LCD, as writing CRE_LCD sets bits 16 & 17 in
- * EC that should not be overwritten by writing stale EC
- */
- NVWriteCRTC(pNv, head, NV_PCRTC_ENGINE_CTRL, regp->crtc_eng_ctrl);
-
- nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1);
- nvWriteVIDEO(pNv, NV_PVIDEO_INTR_EN, 0);
- nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(0), 0);
- nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(1), 0);
- nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(0), pNv->VRAMPhysicalSize - 1);
- nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(1), pNv->VRAMPhysicalSize - 1);
- nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_LIMIT(0), pNv->VRAMPhysicalSize - 1);
- nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_LIMIT(1), pNv->VRAMPhysicalSize - 1);
- nvWriteMC(pNv, NV_PBUS_POWERCTRL_2, 0);
-
- NVWriteCRTC(pNv, head, NV_PCRTC_CURSOR_CONFIG, regp->cursor_cfg);
- NVWriteCRTC(pNv, head, NV_PCRTC_830, regp->crtc_830);
- NVWriteCRTC(pNv, head, NV_PCRTC_834, regp->crtc_834);
- if (pNv->Architecture == NV_ARCH_40) {
- NVWriteCRTC(pNv, head, NV_PCRTC_850, regp->crtc_850);
- NVWriteCRTC(pNv, head, NV_PCRTC_GPIO_EXT, regp->gpio_ext);
- }
-
- if (pNv->Architecture == NV_ARCH_40) {
- uint32_t reg900 = NVReadRAMDAC(pNv, head, NV_PRAMDAC_900);
- if (regp->crtc_cfg == NV_PCRTC_CONFIG_START_ADDRESS_HSYNC)
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_900, reg900 | 0x10000);
- else
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_900, reg900 & ~0x10000);
- }
- }
-
- NVWriteCRTC(pNv, head, NV_PCRTC_CONFIG, regp->crtc_cfg);
-
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_RPC0_INDEX);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_RPC1_INDEX);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_LSR_INDEX);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_PIXEL_INDEX);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_LCD__INDEX);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_HEB__INDEX);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_ENH_INDEX);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_FF_INDEX);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_FFLWM__INDEX);
- if (pNv->Architecture >= NV_ARCH_30)
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_47);
-
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX);
- if (pNv->Architecture == NV_ARCH_40)
- nv_fix_nv40_hw_cursor(pNv, head);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_ILACE__INDEX);
-
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_SCRATCH3__INDEX);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_SCRATCH4__INDEX);
- if (pNv->Architecture >= NV_ARCH_10) {
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_EBR_INDEX);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_CSB);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_4B);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_TVOUT_LATENCY);
- }
- if (pNv->gf4_disp_arch) {
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_53);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_54);
-
- for (i = 0; i < 0x10; i++)
- NVWriteVgaCrtc5758(pNv, head, i, regp->CR58[i]);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_59);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_5B);
-
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_85);
- wr_cio_state(pNv, head, regp, NV_CIO_CRE_86);
- }
-
- NVWriteCRTC(pNv, head, NV_PCRTC_START, regp->fb_start);
-
- /* Setting 1 on this value gives you interrupts for every vblank period. */
- NVWriteCRTC(pNv, head, NV_PCRTC_INTR_EN_0, 0);
- NVWriteCRTC(pNv, head, NV_PCRTC_INTR_0, NV_PCRTC_INTR_0_VBLANK);
-}
-
-static void
-nv_save_state_palette(NVPtr pNv, int head, struct nouveau_mode_state *state)
-{
- int head_offset = head * NV_PRMDIO_SIZE, i;
-
- VGA_WR08(pNv->REGS, NV_PRMDIO_PIXEL_MASK + head_offset, NV_PRMDIO_PIXEL_MASK_MASK);
- VGA_WR08(pNv->REGS, NV_PRMDIO_READ_MODE_ADDRESS + head_offset, 0x0);
-
- for (i = 0; i < 768; i++) {
- state->head[head].DAC[i] = NV_RD08(pNv->REGS, NV_PRMDIO_PALETTE_DATA + head_offset);
- DDXMMIOH("nv_save_state_palette: head %d reg 0x%04x data 0x%02x\n", head, NV_PRMDIO_PALETTE_DATA + head_offset, state->head[head].DAC[i]);
- }
-
- NVSetEnablePalette(pNv, head, false);
-}
-
-void nouveau_hw_load_state_palette(NVPtr pNv, int head,
- struct nouveau_mode_state *state)
-{
- int head_offset = head * NV_PRMDIO_SIZE, i;
-
- VGA_WR08(pNv->REGS, NV_PRMDIO_PIXEL_MASK + head_offset, NV_PRMDIO_PIXEL_MASK_MASK);
- VGA_WR08(pNv->REGS, NV_PRMDIO_WRITE_MODE_ADDRESS + head_offset, 0x0);
-
- for (i = 0; i < 768; i++) {
- DDXMMIOH("nouveau_mode_state_load_palette: head %d reg 0x%04x data 0x%02x\n", head, NV_PRMDIO_PALETTE_DATA + head_offset, state->head[head].DAC[i]);
- NV_WR08(pNv->REGS, NV_PRMDIO_PALETTE_DATA + head_offset, state->head[head].DAC[i]);
- }
-
- NVSetEnablePalette(pNv, head, false);
-}
-
-void nouveau_hw_save_state(ScrnInfoPtr pScrn, int head,
- struct nouveau_mode_state *state)
-{
- NVPtr pNv = NVPTR(pScrn);
-
- if (pNv->NVArch == 0x11)
- /* NB: no attempt is made to restore the bad pll later on */
- nouveau_hw_fix_bad_vpll(pScrn, head);
- nv_save_state_ramdac(pScrn, head, state);
- nv_save_state_vga(pNv, head, state);
- nv_save_state_palette(pNv, head, state);
- nv_save_state_ext(pNv, head, state);
-}
-
-void nouveau_hw_load_state(ScrnInfoPtr pScrn, int head,
- struct nouveau_mode_state *state)
-{
- NVPtr pNv = NVPTR(pScrn);
-
- NVVgaProtect(pNv, head, true);
- nv_load_state_ramdac(pScrn, head, state);
- nv_load_state_ext(pNv, head, state);
- nouveau_hw_load_state_palette(pNv, head, state);
- nv_load_state_vga(pNv, head, state);
- NVVgaProtect(pNv, head, false);
-}
diff --git a/src/nouveau_hw.h b/src/nouveau_hw.h
deleted file mode 100644
index aa2a3b4..0000000
--- a/src/nouveau_hw.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright 2008 Stuart Bennett
- *
- * 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 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.
- */
-
-#ifndef __NOUVEAU_HW_H__
-#define __NOUVEAU_HW_H__
-
-#define MASK(field) ((0xffffffff >> (31 - ((1?field) - (0?field)))) << (0?field))
-#define XLATE(src, srclowbit, outfield) ((((src) >> (srclowbit)) << (0?outfield)) & MASK(outfield))
-
-#define nvReadMC(pNv, reg) DDXMMIOW("nvReadMC: reg %08x val %08x\n", reg, (uint32_t)MMIO_IN32(pNv->REGS, reg))
-#define nvWriteMC(pNv, reg, val) MMIO_OUT32(pNv->REGS, reg, DDXMMIOW("nvWriteMC: reg %08x val %08x\n", reg, val))
-
-#define nvReadVIDEO(pNv, reg) DDXMMIOW("nvReadVIDEO: reg %08x val %08x\n", reg, (uint32_t)MMIO_IN32(pNv->REGS, reg))
-#define nvWriteVIDEO(pNv, reg, val) MMIO_OUT32(pNv->REGS, reg, DDXMMIOW("nvWriteVIDEO: reg %08x val %08x\n", reg, val))
-
-#define nvReadFB(pNv, reg) DDXMMIOW("nvReadFB: reg %08x val %08x\n", reg, (uint32_t)MMIO_IN32(pNv->REGS, reg))
-#define nvWriteFB(pNv, reg, val) MMIO_OUT32(pNv->REGS, reg, DDXMMIOW("nvWriteFB: reg %08x val %08x\n", reg, val))
-
-#define nvReadEXTDEV(pNv, reg) DDXMMIOW("nvReadEXTDEV: reg %08x val %08x\n", reg, (uint32_t)MMIO_IN32(pNv->REGS, reg))
-#define nvWriteEXTDEV(pNv, reg, val) MMIO_OUT32(pNv->REGS, reg, DDXMMIOW("nvWriteEXTDEV: reg %08x val %08x\n", reg, val))
-
-static inline uint32_t NVRead(NVPtr pNv, uint32_t reg)
-{
- DDXMMIOW("NVRead: reg %08x val %08x\n", reg, (uint32_t)NV_RD32(pNv->REGS, reg));
- return NV_RD32(pNv->REGS, reg);
-}
-
-static inline void NVWrite(NVPtr pNv, uint32_t reg, uint32_t val)
-{
- DDXMMIOW("NVWrite: reg %08x val %08x\n", reg, NV_WR32(pNv->REGS, reg, val));
-}
-
-static inline uint32_t NVReadCRTC(NVPtr pNv, int head, uint32_t reg)
-{
- if (head)
- reg += NV_PCRTC0_SIZE;
- DDXMMIOH("NVReadCRTC: head %d reg %08x val %08x\n", head, reg, (uint32_t)NV_RD32(pNv->REGS, reg));
- return NV_RD32(pNv->REGS, reg);
-}
-
-static inline void NVWriteCRTC(NVPtr pNv, int head, uint32_t reg, uint32_t val)
-{
- if (head)
- reg += NV_PCRTC0_SIZE;
- DDXMMIOH("NVWriteCRTC: head %d reg %08x val %08x\n", head, reg, val);
- NV_WR32(pNv->REGS, reg, val);
-}
-
-static inline uint32_t NVReadRAMDAC(NVPtr pNv, int head, uint32_t reg)
-{
- if (head)
- reg += NV_PRAMDAC0_SIZE;
- DDXMMIOH("NVReadRamdac: head %d reg %08x val %08x\n", head, reg, (uint32_t)NV_RD32(pNv->REGS, reg));
- return NV_RD32(pNv->REGS, reg);
-}
-
-static inline void
-NVWriteRAMDAC(NVPtr pNv, int head, uint32_t reg, uint32_t val)
-{
- if (head)
- reg += NV_PRAMDAC0_SIZE;
- DDXMMIOH("NVWriteRamdac: head %d reg %08x val %08x\n", head, reg, val);
- NV_WR32(pNv->REGS, reg, val);
-}
-
-static inline uint8_t nv_read_tmds(NVPtr pNv, int or, int dl, uint8_t address)
-{
- int ramdac = (or & OUTPUT_C) >> 2;
-
- NVWriteRAMDAC(pNv, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8,
- NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | address);
- return NVReadRAMDAC(pNv, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8);
-}
-
-static inline void
-nv_write_tmds(NVPtr pNv, int or, int dl, uint8_t address, uint8_t data)
-{
- int ramdac = (or & OUTPUT_C) >> 2;
-
- NVWriteRAMDAC(pNv, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8, data);
- NVWriteRAMDAC(pNv, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, address);
-}
-
-static inline void
-NVWriteVgaCrtc(NVPtr pNv, int head, uint8_t index, uint8_t value)
-{
- DDXMMIOH("NVWriteVgaCrtc: head %d index 0x%02x data 0x%02x\n", head, index, value);
- NV_WR08(pNv->REGS, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
- NV_WR08(pNv->REGS, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value);
-}
-
-static inline uint8_t NVReadVgaCrtc(NVPtr pNv, int head, uint8_t index)
-{
- NV_WR08(pNv->REGS, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index);
- DDXMMIOH("NVReadVgaCrtc: head %d index 0x%02x data 0x%02x\n", head, index, NV_RD08(pNv->REGS, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE));
- return NV_RD08(pNv->REGS, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE);
-}
-
-/* CR57 and CR58 are a fun pair of regs. CR57 provides an index (0-0xf) for CR58
- * I suspect they in fact do nothing, but are merely a way to carry useful
- * per-head variables around
- *
- * Known uses:
- * CR57 CR58
- * 0x00 index to the appropriate dcb entry (or 7f for inactive)
- * 0x02 dcb entry's "or" value (or 00 for inactive)
- * 0x03 bit0 set for dual link (LVDS, possibly elsewhere too)
- * 0x08 or 0x09 pxclk in MHz
- * 0x0f laptop panel info - low nibble for PEXTDEV_BOOT_0 strap
- * high nibble for xlat strap value
- */
-
-static inline void
-NVWriteVgaCrtc5758(NVPtr pNv, int head, uint8_t index, uint8_t value)
-{
- NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_57, index);
- NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_58, value);
-}
-
-static inline uint8_t NVReadVgaCrtc5758(NVPtr pNv, int head, uint8_t index)
-{
- NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_57, index);
- return NVReadVgaCrtc(pNv, head, NV_CIO_CRE_58);
-}
-
-static inline uint8_t NVReadPRMVIO(NVPtr pNv, int head, uint32_t reg)
-{
- /* Only NV4x have two pvio ranges; other twoHeads cards MUST call
- * NVSetOwner for the relevant head to be programmed */
- if (head && pNv->Architecture == NV_ARCH_40)
- reg += NV_PRMVIO_SIZE;
-
- DDXMMIOH("NVReadPRMVIO: head %d reg %08x val %02x\n", head, reg, NV_RD08(pNv->REGS, reg));
- return NV_RD08(pNv->REGS, reg);
-}
-
-static inline void
-NVWritePRMVIO(NVPtr pNv, int head, uint32_t reg, uint8_t value)
-{
- /* Only NV4x have two pvio ranges; other twoHeads cards MUST call
- * NVSetOwner for the relevant head to be programmed */
- if (head && pNv->Architecture == NV_ARCH_40)
- reg += NV_PRMVIO_SIZE;
-
- DDXMMIOH("NVWritePRMVIO: head %d reg %08x val %02x\n", head, reg, value);
- NV_WR08(pNv->REGS, reg, value);
-}
-
-static inline void NVSetEnablePalette(NVPtr pNv, int head, bool enable)
-{
- VGA_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
- VGA_WR08(pNv->REGS, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE,
- enable ? 0 : 0x20);
-}
-
-static inline bool NVGetEnablePalette(NVPtr pNv, int head)
-{
- VGA_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
- return !(VGA_RD08(pNv->REGS, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) &
- 0x20);
-}
-
-static inline void NVWriteVgaAttr(NVPtr pNv, int head, uint8_t index, uint8_t value)
-{
- if (NVGetEnablePalette(pNv, head))
- index &= ~0x20;
- else
- index |= 0x20;
-
- NV_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
- DDXMMIOH("NVWriteVgaAttr: head %d index 0x%02x data 0x%02x\n", head, index, value);
- NV_WR08(pNv->REGS, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
- NV_WR08(pNv->REGS, NV_PRMCIO_AR__WRITE + head * NV_PRMCIO_SIZE, value);
-}
-
-static inline uint8_t NVReadVgaAttr(NVPtr pNv, int head, uint8_t index)
-{
- if (NVGetEnablePalette(pNv, head))
- index &= ~0x20;
- else
- index |= 0x20;
-
- NV_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE);
- NV_WR08(pNv->REGS, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index);
- DDXMMIOH("NVReadVgaAttr: head %d index 0x%02x data 0x%02x\n", head, index, NV_RD08(pNv->REGS, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE));
- return NV_RD08(pNv->REGS, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE);
-}
-
-static inline void NVVgaSeqReset(NVPtr pNv, int head, bool start)
-{
- NVWriteVgaSeq(pNv, head, NV_VIO_SR_RESET_INDEX, start ? 0x1 : 0x3);
-}
-
-static inline void NVVgaProtect(NVPtr pNv, int head, bool protect)
-{
- uint8_t seq1 = NVReadVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX);
-
- if (protect) {
- NVVgaSeqReset(pNv, head, true);
- NVWriteVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20);
- } else {
- /* Reenable sequencer, then turn on screen */
- NVWriteVgaSeq(pNv, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20); /* reenable display */
- NVVgaSeqReset(pNv, head, false);
- }
- NVSetEnablePalette(pNv, head, protect);
-}
-
-static inline bool nv_heads_tied(NVPtr pNv)
-{
- if (pNv->NVArch == 0x11)
- return !!(nvReadMC(pNv, NV_PBUS_DEBUG_1) & (1 << 28));
-
- return (NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_44) & 0x4);
-}
-
-/* makes cr0-7 on the specified head read-only */
-static inline bool nv_lock_vga_crtc_base(NVPtr pNv, int head, bool lock)
-{
- uint8_t cr11 = NVReadVgaCrtc(pNv, head, NV_CIO_CR_VRE_INDEX);
- bool waslocked = cr11 & 0x80;
-
- if (lock)
- cr11 |= 0x80;
- else
- cr11 &= ~0x80;
- NVWriteVgaCrtc(pNv, head, NV_CIO_CR_VRE_INDEX, cr11);
-
- return waslocked;
-}
-
-static inline void nv_lock_vga_crtc_shadow(NVPtr pNv, int head, int lock)
-{
- /* shadow lock: connects 0x60?3d? regs to "real" 0x3d? regs
- * bit7: unlocks HDT, HBS, HBE, HRS, HRE, HEB
- * bit6: seems to have some effect on CR09 (double scan, VBS_9)
- * bit5: unlocks HDE
- * bit4: unlocks VDE
- * bit3: unlocks VDT, OVL, VRS, ?VRE?, VBS, VBE, LSR, EBR
- * bit2: same as bit 1 of 0x60?804
- * bit0: same as bit 0 of 0x60?804
- */
-
- uint8_t cr21 = lock;
-
- if (lock < 0)
- /* 0xfa is generic "unlock all" mask */
- cr21 = NVReadVgaCrtc(pNv, head, NV_CIO_CRE_21) | 0xfa;
-
- NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_21, cr21);
-}
-
-/* renders the extended crtc regs (cr19+) on all crtcs impervious:
- * immutable and unreadable
- */
-static inline bool NVLockVgaCrtcs(NVPtr pNv, bool lock)
-{
- bool waslocked = !NVReadVgaCrtc(pNv, 0, NV_CIO_SR_LOCK_INDEX);
-
- NVWriteVgaCrtc(pNv, 0, NV_CIO_SR_LOCK_INDEX,
- lock ? NV_CIO_SR_LOCK_VALUE : NV_CIO_SR_UNLOCK_RW_VALUE);
- /* NV11 has independently lockable extended crtcs, except when tied */
- if (pNv->NVArch == 0x11 && !nv_heads_tied(pNv))
- NVWriteVgaCrtc(pNv, 1, NV_CIO_SR_LOCK_INDEX,
- lock ? NV_CIO_SR_LOCK_VALUE :
- NV_CIO_SR_UNLOCK_RW_VALUE);
-
- return waslocked;
-}
-
-/* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */
-#define NV04_CURSOR_SIZE 32
-/* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */
-#define NV10_CURSOR_SIZE 64
-
-static inline int nv_cursor_width(NVPtr pNv)
-{
- return pNv->NVArch >= 0x10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
-}
-
-static inline int nv_cursor_pixels(NVPtr pNv)
-{
- int width = nv_cursor_width(pNv);
-
- return width * width;
-}
-
-static inline void nv_fix_nv40_hw_cursor(NVPtr pNv, int head)
-{
- /* on some nv40 (such as the "true" (in the NV_PFB_BOOT_0 sense) nv40,
- * the gf6800gt) a hardware bug requires a write to PRAMDAC_CURSOR_POS
- * for changes to the CRTC CURCTL regs to take effect, whether changing
- * the pixmap location, or just showing/hiding the cursor
- */
- volatile uint32_t curpos = NVReadRAMDAC(pNv, head,
- NV_PRAMDAC_CU_START_POS);
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_CU_START_POS, curpos);
-}
-
-static inline void nv_show_cursor(NVPtr pNv, int head, bool show)
-{
- uint8_t *curctl1 =
- &pNv->set_state.head[head].CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX];
-
- if (show)
- *curctl1 |= MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE);
- else
- *curctl1 &= ~MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE);
- NVWriteVgaCrtc(pNv, head, NV_CIO_CRE_HCUR_ADDR1_INDEX, *curctl1);
-
- if (pNv->Architecture == NV_ARCH_40)
- nv_fix_nv40_hw_cursor(pNv, head);
-}
-
-static inline uint32_t nv_pitch_align(NVPtr pNv, uint32_t width, int bpp)
-{
- int mask;
-
- if (bpp == 15)
- bpp = 16;
- if (bpp == 24 || bpp == 30)
- bpp = 8;
-
- /* Alignment requirements taken from the Haiku driver */
- if (pNv->Architecture == NV_ARCH_04)
- mask = 128 / bpp - 1;
- else
- mask = 512 / bpp - 1;
-
- return (width + mask) & ~mask;
-}
-
-#endif /* __NOUVEAU_HW_H__ */
diff --git a/src/nouveau_modeset.h b/src/nouveau_modeset.h
deleted file mode 100644
index defc699..0000000
--- a/src/nouveau_modeset.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2008 Maarten Maathuis
- *
- * 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 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.
- */
-
-#ifndef __NOUVEAU_MODESET_H_
-#define __NOUVEAU_MODESET_H_
-
-/* Forward declarations. */
-typedef struct nouveauCrtc *nouveauCrtcPtr;
-typedef struct nouveauConnector *nouveauConnectorPtr;
-typedef struct nouveauOutput *nouveauOutputPtr;
-
-#endif /* __NOUVEAU_MODESET_H_ */
diff --git a/src/nouveau_ms.h b/src/nouveau_ms.h
deleted file mode 100644
index c613be3..0000000
--- a/src/nouveau_ms.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2006 Dave Airlie
- * Copyright 2007 Maarten Maathuis
- * Copyright 2007-2009 Stuart Bennett
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __NOUVEAU_MS_H__
-#define __NOUVEAU_MS_H__
-
-//#define NOUVEAU_DEBUG
-#ifdef NOUVEAU_DEBUG
-#define NV_DEBUG(d, fmt, arg...) xf86DrvMsg(d->scrnIndex, X_INFO, fmt, ##arg)
-#else
-#define NV_DEBUG(d, fmt, arg...)
-#endif
-#define NV_ERROR(d, fmt, arg...) xf86DrvMsg(d->scrnIndex, X_ERROR, fmt, ##arg)
-#define NV_INFO(d, fmt, arg...) xf86DrvMsg(d->scrnIndex, X_PROBED, fmt, ##arg)
-#define NV_TRACEWARN(d, fmt, arg...) xf86DrvMsg(d->scrnIndex, X_NOTICE, fmt, ##arg)
-#define NV_TRACE(d, fmt, arg...) xf86DrvMsg(d->scrnIndex, X_INFO, fmt, ##arg)
-#define NV_WARN(d, fmt, arg...) xf86DrvMsg(d->scrnIndex, X_WARNING, fmt, ##arg)
-
-#define NV_DPMS_CLEARED 0x80
-
-enum scaling_modes {
- SCALE_PANEL,
- SCALE_FULLSCREEN,
- SCALE_ASPECT,
- SCALE_NOSCALE,
- SCALE_INVALID
-};
-
-struct nouveau_pll_vals {
- union {
- struct {
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- uint8_t N1, M1, N2, M2;
-#else
- uint8_t M1, N1, M2, N2;
-#endif
- };
- struct {
- uint16_t NM1, NM2;
- } __attribute__((packed));
- };
- int log2P;
-
- int refclk;
-};
-
-struct nouveau_crtc_state {
- uint8_t MiscOutReg;
- uint8_t CRTC[0x9f];
- uint8_t CR58[0x10];
- uint8_t Sequencer[5];
- uint8_t Graphics[9];
- uint8_t Attribute[21];
- uint8_t DAC[768];
-
- /* PCRTC regs */
- uint32_t fb_start;
- uint32_t crtc_cfg;
- uint32_t cursor_cfg;
- uint32_t gpio_ext;
- uint32_t crtc_830;
- uint32_t crtc_834;
- uint32_t crtc_850;
- uint32_t crtc_eng_ctrl;
-
- /* PRAMDAC regs */
- uint32_t nv10_cursync;
- struct nouveau_pll_vals pllvals;
- uint32_t ramdac_gen_ctrl;
- uint32_t ramdac_630;
- uint32_t ramdac_634;
- uint32_t fp_horiz_regs[7];
- uint32_t fp_vert_regs[7];
- uint32_t dither;
- uint32_t fp_control;
- uint32_t dither_regs[6];
- uint32_t fp_debug_0;
- uint32_t fp_debug_1;
- uint32_t fp_debug_2;
- uint32_t ramdac_a20;
- uint32_t ramdac_a24;
- uint32_t ramdac_a34;
-};
-
-struct nouveau_encoder_state {
- uint32_t output;
- int head;
-};
-
-struct nouveau_mode_state
-{
- uint32_t pllsel;
- uint32_t sel_clk;
-
- struct nouveau_crtc_state head[2];
-};
-
-struct nouveau_crtc {
- int head;
- uint8_t last_dpms;
- int fp_users;
- uint32_t dpms_saved_fp_control;
- int saturation, sharpness;
-
- /* convenient pointer to pNv->set_state.head[head_nr] */
- struct nouveau_crtc_state *state;
-
- uint32_t cursor_fg, cursor_bg;
-
- struct nouveau_bo *bo;
- ExaOffscreenArea *shadow;
- unsigned shadow_pitch;
-};
-
-struct nouveau_encoder {
- uint8_t last_dpms;
- struct dcb_entry *dcb;
- DisplayModePtr native_mode;
- uint8_t scaling_mode;
- bool dithering;
- bool dual_link;
- struct nouveau_encoder_state restore;
-};
-
-struct nouveau_connector {
- xf86MonPtr edid;
- I2CBusPtr pDDCBus;
- uint16_t possible_encoders;
- struct nouveau_encoder *detected_encoder;
- struct nouveau_encoder *nv_encoder;
-};
-
-#define to_nouveau_connector(x) ((struct nouveau_connector *)(x)->driver_private)
-#define to_nouveau_crtc(x) ((struct nouveau_crtc *)(x)->driver_private)
-#define to_nouveau_encoder(x) ((struct nouveau_connector *)(x)->driver_private)->nv_encoder
-
-#endif /* __NOUVEAU_MS_H__ */
diff --git a/src/nouveau_output.h b/src/nouveau_output.h
deleted file mode 100644
index e2e873d..0000000
--- a/src/nouveau_output.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2008 Maarten Maathuis
- *
- * 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 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.
- */
-
-#ifndef __NOUVEAU_OUTPUT_H_
-#define __NOUVEAU_OUTPUT_H_
-
-#include "nv_include.h"
-#include "nouveau_modeset.h"
-#include "nouveau_crtc.h"
-#include "nouveau_connector.h"
-
-typedef struct nouveauOutput {
- ScrnInfoPtr scrn;
-
- char *name;
- Bool active;
- nouveauOutputPtr next;
-
- nouveauCrtcPtr crtc;
- nouveauConnectorPtr connector; /* the one that is currently in use, not all possibilities. */
-
- /* This can change in rare circumstances, when an output resource is shared. */
- struct dcb_entry *dcb;
- int type;
- uint8_t allowed_crtc; /* bit0: crtc0, bit1: crtc1 */
- int scale_mode;
- Bool dithering;
-
- /* Mode stuff. */
- DisplayModePtr native_mode;
-
- /* Function pointers. */
- int (*ModeValid) (nouveauOutputPtr output, DisplayModePtr mode);
- void (*ModeSet) (nouveauOutputPtr output, DisplayModePtr mode);
- void (*SetClockMode) (nouveauOutputPtr output, int clock); /* maybe another name? */
-
- /* This will handle the case where output resources are shared. */
- int (*Sense) (nouveauOutputPtr output); /* this is not for ddc or load detect, and will often just return a fixed type. */
- Bool (*Detect) (nouveauOutputPtr output); /* everything that isn't hotplug detect or ddc */
-
- void (*SetPowerMode) (nouveauOutputPtr output, int mode);
-
- /* Get the last associated crtc of the output. */
- nouveauCrtcPtr (*GetCurrentCrtc) (nouveauOutputPtr output);
-
- void (*Save) (nouveauOutputPtr output);
- void (*Load) (nouveauOutputPtr output);
-} nouveauOutputRec;
-
-#endif /* __NOUVEAU_OUTPUT_H_ */
diff --git a/src/nouveau_xv.c b/src/nouveau_xv.c
index ee72848..cb950e4 100644
--- a/src/nouveau_xv.c
+++ b/src/nouveau_xv.c
@@ -287,3 +287,3 @@ NVFreeOverlayMemory(ScrnInfoPtr pScrn)
NVFreePortMemory(pScrn, pPriv);
-
+#if NVOVL_SUPPORT
/* "power cycle" the overlay */
@@ -293,2 +293,3 @@ NVFreeOverlayMemory(ScrnInfoPtr pScrn)
(nvReadMC(pNv, NV_PMC_ENABLE) | 0x10000000));
+#endif
}
@@ -807,2 +808,3 @@ NV_set_action_flags(ScrnInfoPtr pScrn, DrawablePtr pDraw, NVPortPrivPtr pPriv,
+#ifdef NVOVL_SUPPORT
if (USING_OVERLAY) {
@@ -847,2 +849,3 @@ NV_set_action_flags(ScrnInfoPtr pScrn, DrawablePtr pDraw, NVPortPrivPtr pPriv,
}
+#endif
@@ -993,2 +996,3 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x,
offset = 0;
+#ifdef NVOVL_SUPPORT
if (pPriv->doubleBuffer) {
@@ -1006,2 +1010,3 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x,
}
+#endif
@@ -1603,3 +1608,3 @@ NVSetupBlitVideo (ScreenPtr pScreen)
- if(pNv->WaitVSyncPossible) {
+ if (pNv->NVArch >= 0x11) {
adapt->pAttributes = NVBlitAttributes;
@@ -1630,3 +1635,3 @@ NVSetupBlitVideo (ScreenPtr pScreen)
pPriv->doubleBuffer = FALSE;
- pPriv->SyncToVBlank = pNv->WaitVSyncPossible;
+ pPriv->SyncToVBlank = (pNv->NVArch >= 0x11);
@@ -1773,3 +1778,3 @@ NVChipsetHasOverlay(NVPtr pNv)
case NV_ARCH_40:
- if ((pNv->Chipset & 0xfff0) == CHIPSET_NV40)
+ if (pNv->NVArch == 0x40)
return TRUE;
@@ -1800,3 +1805,3 @@ NVSetupOverlayVideo(ScreenPtr pScreen)
- if (pNv->kms_enable || !NVChipsetHasOverlay(pNv))
+ if (1 /*pNv->kms_enable*/ || !NVChipsetHasOverlay(pNv))
return NULL;
@@ -1870,10 +1875,4 @@ NV30SetupTexturedVideo (ScreenPtr pScreen, Bool bicubic)
- if (pNv->WaitVSyncPossible) {
- adapt->pAttributes = NVTexturedAttributes;
- adapt->nAttributes = NUM_TEXTURED_ATTRIBUTES;
- } else {
- adapt->pAttributes = NULL;
- adapt->nAttributes = 0;
- }
-
+ adapt->pAttributes = NVTexturedAttributes;
+ adapt->nAttributes = NUM_TEXTURED_ATTRIBUTES;
adapt->pImages = NV30TexturedImages;
@@ -1897,3 +1896,3 @@ NV30SetupTexturedVideo (ScreenPtr pScreen, Bool bicubic)
pPriv->doubleBuffer = FALSE;
- pPriv->SyncToVBlank = pNv->WaitVSyncPossible;
+ pPriv->SyncToVBlank = TRUE;
@@ -1957,10 +1956,4 @@ NV40SetupTexturedVideo (ScreenPtr pScreen, Bool bicubic)
- if(pNv->WaitVSyncPossible) {
- adapt->pAttributes = NVTexturedAttributes;
- adapt->nAttributes = NUM_TEXTURED_ATTRIBUTES;
- } else {
- adapt->pAttributes = NULL;
- adapt->nAttributes = 0;
- }
-
+ adapt->pAttributes = NVTexturedAttributes;
+ adapt->nAttributes = NUM_TEXTURED_ATTRIBUTES;
adapt->pImages = NV40TexturedImages;
@@ -1984,3 +1977,3 @@ NV40SetupTexturedVideo (ScreenPtr pScreen, Bool bicubic)
pPriv->doubleBuffer = FALSE;
- pPriv->SyncToVBlank = pNv->WaitVSyncPossible;
+ pPriv->SyncToVBlank = TRUE;
diff --git a/src/nv04_xv_blit.c b/src/nv04_xv_blit.c
index 990817c..c1451e3 100644
--- a/src/nv04_xv_blit.c
+++ b/src/nv04_xv_blit.c
@@ -38,2 +38,4 @@
+#define VSYNC_POSSIBLE (pNv->NVArch >= 0x11)
+
extern Atom xvSetDefaults, xvSyncToVBlank;
@@ -141,3 +143,3 @@ NVPutBlitImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int src_offset,
- if(pNv->BlendingPossible) {
+ if ((pNv->Chipset & 0xffff) > CHIPSET_NV04) {
BEGIN_RING(chan, sifm,
@@ -216,3 +218,3 @@ NVSetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
- if ((attribute == xvSyncToVBlank) && pNv->WaitVSyncPossible) {
+ if ((attribute == xvSyncToVBlank) && VSYNC_POSSIBLE) {
if ((value < 0) || (value > 1))
@@ -222,3 +224,3 @@ NVSetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
if (attribute == xvSetDefaults) {
- pPriv->SyncToVBlank = pNv->WaitVSyncPossible;
+ pPriv->SyncToVBlank = VSYNC_POSSIBLE;
} else
diff --git a/src/nv04_xv_ovl.c b/src/nv04_xv_ovl.c
index b24379a..a729193 100644
--- a/src/nv04_xv_ovl.c
+++ b/src/nv04_xv_ovl.c
@@ -45,5 +45,6 @@ NV04PutOverlayImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int offset,
{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
NVPtr pNv = NVPTR(pScrn);
NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
+#if NVOVL_SUPPORT
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
xf86CrtcPtr crtc = xf86_config->crtc[pPriv->overlayCRTC];
@@ -105,2 +106,3 @@ NV04PutOverlayImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int offset,
nvWriteVIDEO(pNv, NV_PVIDEO_SU_STATE, (nvReadVIDEO(pNv, NV_PVIDEO_SU_STATE) ^ (1 << 16)));
+#endif
@@ -185,2 +187,3 @@ NV04StopOverlay (ScrnInfoPtr pScrn)
{
+#ifdef NVOVL_SUPPORT
NVPtr pNv = NVPTR(pScrn);
@@ -191,2 +194,3 @@ NV04StopOverlay (ScrnInfoPtr pScrn)
nvWriteVIDEO(pNv, NV_PVIDEO_RM_STATE, 0);
+#endif
}
diff --git a/src/nv10_exa.c b/src/nv10_exa.c
index a3425a8..d74b052 100644
--- a/src/nv10_exa.c
+++ b/src/nv10_exa.c
@@ -727,14 +727,14 @@ NVAccelInitNV10TCL(ScrnInfoPtr pScrn)
struct nouveau_grobj *celsius;
- uint32_t class = 0, chipset;
+ uint32_t class = 0;
int i;
- chipset = (nvReadMC(pNv, NV_PMC_BOOT_0) >> 20) & 0xff;
- if (((chipset & 0xf0) != NV_ARCH_10) && ((chipset & 0xf0) != NV_ARCH_20))
+ if (((pNv->NVArch & 0xf0) != NV_ARCH_10) &&
+ ((pNv->NVArch & 0xf0) != NV_ARCH_20))
return FALSE;
- if (chipset >= 0x20 || chipset == 0x1a)
+ if (pNv->NVArch >= 0x20 || pNv->NVArch == 0x1a)
class = NV11TCL;
- else if (chipset >= 0x17)
+ else if (pNv->NVArch >= 0x17)
class = NV17TCL;
- else if (chipset >= 0x11)
+ else if (pNv->NVArch >= 0x11)
class = NV11TCL;
diff --git a/src/nv10_xv_ovl.c b/src/nv10_xv_ovl.c
index 66f7399..ce50b26 100644
--- a/src/nv10_xv_ovl.c
+++ b/src/nv10_xv_ovl.c
@@ -70,2 +70,3 @@ NV10PutOverlayImage(ScrnInfoPtr pScrn,
NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
+#ifdef NVOVL_SUPPORT
int buffer = pPriv->currentBuffer;
@@ -127,2 +128,3 @@ NV10PutOverlayImage(ScrnInfoPtr pScrn,
nvWriteVIDEO(pNv, NV_PVIDEO_BUFFER, buffer ? 0x10 : 0x1);
+#endif
@@ -150,3 +152,2 @@ NV10SetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
- NVPtr pNv = NVPTR(pScrn);
@@ -195,3 +196,6 @@ NV10SetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
} else
+#ifdef NVOVL_SUPPORT
if ( attribute == xvOnCRTCNb) {
+ NVPtr pNv = NVPTR(pScrn);
+
if ((value < 0) || (value > 1))
@@ -204,2 +208,3 @@ NV10SetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
} else
+#endif
return BadMatch;
@@ -257,4 +262,6 @@ NV10StopOverlay (ScrnInfoPtr pScrn)
{
+#ifdef NVOVL_SUPPORT
NVPtr pNv = NVPTR(pScrn);
nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1);
+#endif
}
@@ -283,2 +290,3 @@ NV10WriteOverlayParameters (ScrnInfoPtr pScrn)
+#ifdef NVOVL_SUPPORT
nvWriteVIDEO(pNv, NV_PVIDEO_LUMINANCE(0), (pPriv->brightness << 16) |
@@ -292,3 +300,3 @@ NV10WriteOverlayParameters (ScrnInfoPtr pScrn)
nvWriteVIDEO(pNv, NV_PVIDEO_COLOR_KEY, pPriv->colorKey);
-
+#endif
}
diff --git a/src/nv30_exa.c b/src/nv30_exa.c
index 6350828..a50a6eb 100644
--- a/src/nv30_exa.c
+++ b/src/nv30_exa.c
@@ -681,3 +681,3 @@ NVAccelInitNV30TCL(ScrnInfoPtr pScrn)
- chipset = (nvReadMC(pNv, NV_PMC_BOOT_0) >> 20) & 0xff;
+ chipset = pNv->NVArch;
if ((chipset & 0xf0) != NV_ARCH_30)
diff --git a/src/nv30_xv_tex.c b/src/nv30_xv_tex.c
index 2d90e8b..1ecc7b7 100644
--- a/src/nv30_xv_tex.c
+++ b/src/nv30_xv_tex.c
@@ -432,5 +432,4 @@ NV30SetTexturePortAttribute(ScrnInfoPtr pScrn, Atom attribute,
NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
- NVPtr pNv = NVPTR(pScrn);
- if ((attribute == xvSyncToVBlank) && pNv->WaitVSyncPossible) {
+ if (attribute == xvSyncToVBlank) {
if ((value < 0) || (value > 1))
@@ -440,3 +439,3 @@ NV30SetTexturePortAttribute(ScrnInfoPtr pScrn, Atom attribute,
if (attribute == xvSetDefaults) {
- pPriv->SyncToVBlank = pNv->WaitVSyncPossible;
+ pPriv->SyncToVBlank = TRUE;
} else
diff --git a/src/nv40_exa.c b/src/nv40_exa.c
index 03efce4..2b36f2d 100644
--- a/src/nv40_exa.c
+++ b/src/nv40_exa.c
@@ -614,4 +614,3 @@ NVAccelInitNV40TCL(ScrnInfoPtr pScrn)
- chipset = (nvReadMC(pNv, NV_PMC_BOOT_0) >> 20) & 0xff;
-
+ chipset = pNv->NVArch;
if ( (chipset & 0xf0) == NV_ARCH_40) {
diff --git a/src/nv40_xv_tex.c b/src/nv40_xv_tex.c
index 463b178..7679019 100644
--- a/src/nv40_xv_tex.c
+++ b/src/nv40_xv_tex.c
@@ -409,5 +409,4 @@ NV40SetTexturePortAttribute(ScrnInfoPtr pScrn, Atom attribute,
NVPortPrivPtr pPriv = (NVPortPrivPtr)data;
- NVPtr pNv = NVPTR(pScrn);
- if ((attribute == xvSyncToVBlank) && pNv->WaitVSyncPossible) {
+ if (attribute == xvSyncToVBlank) {
if ((value < 0) || (value > 1))
@@ -417,3 +416,3 @@ NV40SetTexturePortAttribute(ScrnInfoPtr pScrn, Atom attribute,
if (attribute == xvSetDefaults) {
- pPriv->SyncToVBlank = pNv->WaitVSyncPossible;
+ pPriv->SyncToVBlank = TRUE;
} else
diff --git a/src/nv50_connector.c b/src/nv50_connector.c
deleted file mode 100644
index f7d6133..0000000
--- a/src/nv50_connector.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright 2008 Maarten Maathuis
- *
- * 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 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.
- */
-
-#include "nouveau_modeset.h"
-#include "nouveau_crtc.h"
-#include "nouveau_output.h"
-#include "nouveau_connector.h"
-
-static xf86MonPtr
-NV50ConnectorGetEDID(nouveauConnectorPtr connector)
-{
- ScrnInfoPtr pScrn = connector->scrn;
- xf86MonPtr mon = NULL;
-
-#ifdef EDID_COMPLETE_RAWDATA
- mon = xf86DoEEDID(pScrn->scrnIndex, connector->pDDCBus, TRUE);
-#else
- mon = xf86DoEDID_DDC2(pScrn->scrnIndex, connector->pDDCBus);
-#endif
-
- if (mon)
- xf86DDCApplyQuirks(pScrn->scrnIndex, mon);
-
- return mon;
-}
-
-static xf86MonPtr
-NV50ConnectorDDCDetect(nouveauConnectorPtr connector)
-{
- ScrnInfoPtr pScrn = connector->scrn;
- xf86MonPtr ddc_mon;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50ConnectorDDCDetect is called.\n");
-
- if (!connector->pDDCBus)
- return FALSE;
-
- ddc_mon = NV50ConnectorGetEDID(connector);
-
- return ddc_mon;
-}
-
-static DisplayModePtr
-NV50ConnectorGetDDCModes(nouveauConnectorPtr connector)
-{
- ScrnInfoPtr pScrn = connector->scrn;
- xf86MonPtr ddc_mon;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50ConnectorGetDDCModes is called.\n");
-
- if (!connector->pDDCBus)
- return FALSE;
-
- ddc_mon = NV50ConnectorGetEDID(connector);
- if (!ddc_mon)
- return NULL;
-
- return xf86DDCGetModes(pScrn->scrnIndex, ddc_mon);
-}
-
-void
-NV50ConnectorInit(ScrnInfoPtr pScrn)
-{
- int i;
- NVPtr pNv = NVPTR(pScrn);
-
- /* Maybe a bit overdone, because often only 3 or 4 connectors are present. */
- for (i = 0; i < DCB_MAX_NUM_I2C_ENTRIES; i++) {
- nouveauConnectorPtr connector = xnfcalloc(sizeof(nouveauConnectorRec), 1);
- connector->scrn = pScrn;
- connector->index = i;
-
- char connector_name[20];
- sprintf(connector_name, "Connector-%d", i);
- connector->name = xstrdup(connector_name);
-
- /* Function pointers. */
- connector->DDCDetect = NV50ConnectorDDCDetect;
- connector->GetDDCModes = NV50ConnectorGetDDCModes;
- connector->HotplugDetect = NULL;
-
- pNv->connector[i] = connector;
- }
-}
-
-void
-NV50ConnectorDestroy(ScrnInfoPtr pScrn)
-{
- int i;
- NVPtr pNv = NVPTR(pScrn);
-
- /* Maybe a bit overdone, because often only 3 or 4 connectors are present. */
- for (i = 0; i < DCB_MAX_NUM_I2C_ENTRIES; i++) {
- nouveauConnectorPtr connector = pNv->connector[i];
-
- if (!connector)
- continue;
-
- xfree(connector->name);
- xfree(connector);
- pNv->connector[i] = NULL;
- }
-}
-
diff --git a/src/nv50_crtc.c b/src/nv50_crtc.c
deleted file mode 100644
index aa85cee..0000000
--- a/src/nv50_crtc.c
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * Copyright 2007 NVIDIA, Corporation
- * Copyright 2008 Maarten Maathuis
- *
- * 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 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.
- */
-
-#include "nouveau_modeset.h"
-#include "nouveau_crtc.h"
-#include "nouveau_output.h"
-#include "nouveau_connector.h"
-
-/* Check if the card wants us to update the any of the video clocks.
- * Maybe it would be enough to check only after method 0x80? */
-static void
-NV50CheckWriteVClk(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- int t_start = GetTimeInMillis();
-
- while (NVRead(pNv, NV50_DISPLAY_CTRL_STATE) & NV50_DISPLAY_CTRL_STATE_PENDING) {
- /* An educated guess. */
- const uint32_t supervisor = NVRead(pNv, NV50_DISPLAY_SUPERVISOR);
-
- if ((GetTimeInMillis() - t_start) > 5000) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "NV50CheckWriteVClk() timed out.\n");
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "A reboot is probably required now.\n");
- break;
- }
-
- /* Simply acknowledge it, maybe we should do more? */
- if (supervisor & NV50_DISPLAY_SUPERVISOR_CRTCn) {
- NVWrite(pNv, NV50_DISPLAY_SUPERVISOR, supervisor & NV50_DISPLAY_SUPERVISOR_CRTCn);
- }
-
- if (supervisor & NV50_DISPLAY_SUPERVISOR_CLK_MASK) {
- if (supervisor & NV50_DISPLAY_SUPERVISOR_CLK_UPDATE) {
- const uint32_t clockvar = NVRead(pNv, NV50_DISPLAY_UNK30_CTRL);
- int i;
-
- for(i = 0; i < 2; i++) {
- nouveauCrtcPtr crtc = pNv->crtc[i];
- uint32_t mask = 0;
-
- if (crtc->index == 1)
- mask = NV50_DISPLAY_UNK30_CTRL_UPDATE_VCLK1;
- else
- mask = NV50_DISPLAY_UNK30_CTRL_UPDATE_VCLK0;
-
- if (clockvar & mask)
- crtc->SetPixelClock(crtc, crtc->pixel_clock);
- /* Always do something if the supervisor wants a clock change. */
- /* This is needed because you get a deadlock if you don't kick the NV50_CRTC0_CLK_CTRL2 register. */
- if (crtc->modeset_lock) {
- crtc->SetClockMode(crtc, crtc->pixel_clock);
-
- nouveauOutputPtr output;
- for (output = pNv->output; output != NULL; output = output->next) {
- if (output->crtc == crtc)
- output->SetClockMode(output, crtc->pixel_clock);
- }
- }
- }
- }
-
- NVWrite(pNv, NV50_DISPLAY_SUPERVISOR, 1 << (ffs(supervisor & NV50_DISPLAY_SUPERVISOR_CLK_MASK) - 1));
- NVWrite(pNv, NV50_DISPLAY_UNK30_CTRL, NV50_DISPLAY_UNK30_CTRL_PENDING);
- }
- }
-}
-
-void NV50DisplayCommand(ScrnInfoPtr pScrn, uint32_t addr, uint32_t value)
-{
- DDXMMIOH("NV50DisplayCommand: head %d addr 0x%X value 0x%X\n", 0, addr, value);
- NVPtr pNv = NVPTR(pScrn);
- NVWrite(pNv, NV50_DISPLAY_CTRL_VAL, value);
- NVWrite(pNv, NV50_DISPLAY_CTRL_STATE, addr | 0x10000 | NV50_DISPLAY_CTRL_STATE_ENABLE | NV50_DISPLAY_CTRL_STATE_PENDING);
- NV50CheckWriteVClk(pScrn);
-}
-
-void NV50CrtcCommand(nouveauCrtcPtr crtc, uint32_t addr, uint32_t value)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
-
- /* This head dependent offset is only for crtc commands. */
- NV50DisplayCommand(pScrn, addr + 0x400 * crtc->index, value);
-}
-
-static Bool
-NV50CrtcModeValid(nouveauCrtcPtr crtc, DisplayModePtr mode)
-{
- return TRUE;
-}
-
-static void
-NV50CrtcModeSet(nouveauCrtcPtr crtc, DisplayModePtr mode)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50CrtcModeSet is called for %s.\n", crtc->index ? "CRTC1" : "CRTC0");
-
- /* Anyone know a more appropriate name? */
- DisplayModePtr desired_mode = crtc->use_native_mode ? crtc->native_mode : mode;
-
- /* Save the pixel clock for posterity. */
- crtc->pixel_clock = desired_mode->Clock;
- crtc->cur_mode = mode;
-
- uint32_t hsync_dur = desired_mode->CrtcHSyncEnd - desired_mode->CrtcHSyncStart;
- uint32_t vsync_dur = desired_mode->CrtcVSyncEnd - desired_mode->CrtcVSyncStart;
- uint32_t hsync_start_to_end = desired_mode->CrtcHBlankEnd - desired_mode->CrtcHSyncStart;
- uint32_t vsync_start_to_end = desired_mode->CrtcVBlankEnd - desired_mode->CrtcVSyncStart;
- /* I can't give this a proper name, anyone else can? */
- uint32_t hunk1 = desired_mode->CrtcHTotal - desired_mode->CrtcHSyncStart + desired_mode->CrtcHBlankStart;
- uint32_t vunk1 = desired_mode->CrtcVTotal - desired_mode->CrtcVSyncStart + desired_mode->CrtcVBlankStart;
- /* Another strange value, this time only for interlaced modes. */
- uint32_t vunk2a = 2*desired_mode->CrtcVTotal - desired_mode->CrtcVSyncStart + desired_mode->CrtcVBlankStart;
- uint32_t vunk2b = desired_mode->CrtcVTotal - desired_mode->CrtcVSyncStart + desired_mode->CrtcVBlankEnd;
-
- if (desired_mode->Flags & V_INTERLACE) {
- vsync_dur /= 2;
- vsync_start_to_end /= 2;
- vunk1 /= 2;
- vunk2a /= 2;
- vunk2b /= 2;
- /* magic */
- if (desired_mode->Flags & V_DBLSCAN) {
- vsync_start_to_end -= 1;
- vunk1 -= 1;
- vunk2a -= 1;
- vunk2b -= 1;
- }
- }
-
- /* NV50CrtcCommand includes head offset */
- /* This is the native mode when DFP && !SCALE_PANEL */
- NV50CrtcCommand(crtc, NV50_CRTC0_CLOCK, desired_mode->Clock | 0x800000);
- NV50CrtcCommand(crtc, NV50_CRTC0_INTERLACE, (desired_mode->Flags & V_INTERLACE) ? 2 : 0);
- NV50CrtcCommand(crtc, NV50_CRTC0_DISPLAY_START, 0);
- NV50CrtcCommand(crtc, NV50_CRTC0_UNK82C, 0);
- NV50CrtcCommand(crtc, NV50_CRTC0_DISPLAY_TOTAL, desired_mode->CrtcVTotal << 16 | desired_mode->CrtcHTotal);
- NV50CrtcCommand(crtc, NV50_CRTC0_SYNC_DURATION, (vsync_dur - 1) << 16 | (hsync_dur - 1));
- NV50CrtcCommand(crtc, NV50_CRTC0_SYNC_START_TO_BLANK_END, (vsync_start_to_end - 1) << 16 | (hsync_start_to_end - 1));
- NV50CrtcCommand(crtc, NV50_CRTC0_MODE_UNK1, (vunk1 - 1) << 16 | (hunk1 - 1));
- if (desired_mode->Flags & V_INTERLACE) {
- NV50CrtcCommand(crtc, NV50_CRTC0_MODE_UNK2, (vunk2b - 1) << 16 | (vunk2a - 1));
- }
- NV50CrtcCommand(crtc, NV50_CRTC0_FB_SIZE, pScrn->virtualY << 16 | pScrn->virtualX);
-
- /* Maybe move this calculation elsewhere? */
- crtc->fb_pitch = pScrn->displayWidth * (pScrn->bitsPerPixel / 8);
- NV50CrtcCommand(crtc, NV50_CRTC0_FB_PITCH, crtc->fb_pitch | 0x100000);
-
- switch (pScrn->depth) {
- case 8:
- NV50CrtcCommand(crtc, NV50_CRTC0_DEPTH, NV50_CRTC0_DEPTH_8BPP);
- break;
- case 15:
- NV50CrtcCommand(crtc, NV50_CRTC0_DEPTH, NV50_CRTC0_DEPTH_15BPP);
- break;
- case 16:
- NV50CrtcCommand(crtc, NV50_CRTC0_DEPTH, NV50_CRTC0_DEPTH_16BPP);
- break;
- case 24:
- NV50CrtcCommand(crtc, NV50_CRTC0_DEPTH, NV50_CRTC0_DEPTH_24BPP);
- break;
- }
- crtc->SetDither(crtc);
- NV50CrtcCommand(crtc, NV50_CRTC0_COLOR_CTRL, NV50_CRTC_COLOR_CTRL_MODE_COLOR);
- NV50CrtcCommand(crtc, NV50_CRTC0_FB_POS, (crtc->y << 16) | (crtc->x));
- /* This is the actual resolution of the mode. */
- NV50CrtcCommand(crtc, NV50_CRTC0_REAL_RES, (mode->VDisplay << 16) | mode->HDisplay);
- NV50CrtcCommand(crtc, NV50_CRTC0_SCALE_CENTER_OFFSET, NV50_CRTC_SCALE_CENTER_OFFSET_VAL(0,0));
-
- /* Maybe move this as well? */
- crtc->Blank(crtc, FALSE);
-}
-
-static void
-NV50CrtcSetPixelClock(nouveauCrtcPtr crtc, int clock)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50CrtcSetPixelClock is called for %s.\n", crtc->index ? "CRTC1" : "CRTC0");
-
- NVPtr pNv = NVPTR(pScrn);
-
- /* I don't know why exactly, but these were in my table. */
- uint32_t pll_reg = crtc->index ? NV50_CRTC1_CLK_CTRL1 : NV50_CRTC0_CLK_CTRL1;
- struct pll_lims pll_lim;
- struct nouveau_pll_vals pllvals;
-
- get_pll_limits(pScrn, pll_reg, &pll_lim);
-
- /* NV5x hardware doesn't seem to support a single vco mode, otherwise the blob is hiding it well. */
- if (!nouveau_calc_pll_mnp(pScrn, &pll_lim, clock, &pllvals))
- return;
-
- uint32_t reg1 = NVRead(pNv, pll_reg + 4);
- uint32_t reg2 = NVRead(pNv, pll_reg + 8);
-
- /* bit0: The blob (and bios) seem to have this on (almost) always.
- * I'm hoping this (experiment) will fix my image stability issues.
- */
- NVWrite(pNv, NV50_CRTC0_CLK_CTRL1 + crtc->index * 0x800, NV50_CRTC_CLK_CTRL1_CONNECTED | 0x10000011);
-
- /* Eventually we should learn ourselves what all the bits should be. */
- reg1 &= 0xff00ff00;
- reg2 &= 0x8000ff00;
-
- reg1 |= (pllvals.M1 << 16) | pllvals.N1;
- reg2 |= (pllvals.log2P << 28) | (pllvals.M2 << 16) | pllvals.N2;
-
- NVWrite(pNv, pll_reg + 4, reg1);
- NVWrite(pNv, pll_reg + 8, reg2);
-}
-
-static void
-NV50CrtcSetClockMode(nouveauCrtcPtr crtc, int clock)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50CrtcSetClockMode is called for %s.\n", crtc->index ? "CRTC1" : "CRTC0");
-
- NVPtr pNv = NVPTR(pScrn);
-
- /* There seem to be a few indicator bits, which are similar to the SOR_CTRL bits. */
- NVWrite(pNv, NV50_CRTC0_CLK_CTRL2 + crtc->index * 0x800, 0);
-}
-
-static void
-NV50CrtcSetFB(nouveauCrtcPtr crtc, struct nouveau_bo * buffer)
-{
- if (crtc->front_buffer)
- nouveau_bo_unpin(crtc->front_buffer);
-
- /* For the moment the actual hardware settings stays in ModeSet(). */
- nouveau_bo_pin(buffer, NOUVEAU_BO_VRAM);
- crtc->front_buffer = buffer;
-}
-
-static void
-NV50CrtcSetFBOffset(nouveauCrtcPtr crtc, uint32_t x, uint32_t y)
-{
- crtc->x = x;
- crtc->y = y;
-
- NV50CrtcCommand(crtc, NV50_CRTC0_FB_POS, (crtc->y << 16) | (crtc->x));
-}
-
-static void
-NV50CrtcBlank(nouveauCrtcPtr crtc, Bool blanked)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50CrtcBlank is called (%s) for %s.\n", blanked ? "blanked" : "unblanked", crtc->index ? "CRTC1" : "CRTC0");
-
- NVPtr pNv = NVPTR(pScrn);
-
- if (blanked) {
- crtc->HideCursor(crtc, TRUE);
-
- NV50CrtcCommand(crtc, NV50_CRTC0_CLUT_MODE, NV50_CRTC0_CLUT_MODE_BLANK);
- NV50CrtcCommand(crtc, NV50_CRTC0_CLUT_OFFSET, 0);
- if (pNv->NVArch != 0x50)
- NV50CrtcCommand(crtc, NV84_CRTC0_BLANK_UNK1, NV84_CRTC0_BLANK_UNK1_BLANK);
- NV50CrtcCommand(crtc, NV50_CRTC0_BLANK_CTRL, NV50_CRTC0_BLANK_CTRL_BLANK);
- if (pNv->NVArch != 0x50)
- NV50CrtcCommand(crtc, NV84_CRTC0_BLANK_UNK2, NV84_CRTC0_BLANK_UNK2_BLANK);
- } else {
- struct nouveau_device *dev = crtc->front_buffer->device;
- uint32_t fb = crtc->front_buffer->offset - dev->vm_vram_base;
- uint32_t clut = crtc->lut->offset - dev->vm_vram_base;
- uint32_t cursor;
-
- if (crtc->index)
- cursor = pNv->Cursor2->offset - dev->vm_vram_base;
- else
- cursor = pNv->Cursor->offset - dev->vm_vram_base;
-
- NV50CrtcCommand(crtc, NV50_CRTC0_FB_OFFSET, fb >> 8);
- NV50CrtcCommand(crtc, 0x864, 0);
- NVWrite(pNv, NV50_DISPLAY_UNK_380, 0);
- /* RAM is clamped to 256 MiB. */
- NVWrite(pNv, NV50_DISPLAY_RAM_AMOUNT, pNv->RamAmountKBytes * 1024 - 1);
- NVWrite(pNv, NV50_DISPLAY_UNK_388, 0x150000);
- NVWrite(pNv, NV50_DISPLAY_UNK_38C, 0);
- NV50CrtcCommand(crtc, NV50_CRTC0_CURSOR_OFFSET, cursor >> 8);
- if(pNv->NVArch != 0x50)
- NV50CrtcCommand(crtc, NV84_CRTC0_BLANK_UNK2, NV84_CRTC0_BLANK_UNK2_UNBLANK);
-
- if (crtc->cursor_visible)
- crtc->ShowCursor(crtc, TRUE);
-
- NV50CrtcCommand(crtc, NV50_CRTC0_CLUT_MODE,
- pScrn->depth == 8 ? NV50_CRTC0_CLUT_MODE_OFF : NV50_CRTC0_CLUT_MODE_ON);
- /* Each CRTC has it's own CLUT. */
- NV50CrtcCommand(crtc, NV50_CRTC0_CLUT_OFFSET, clut >> 8);
- if (pNv->NVArch != 0x50)
- NV50CrtcCommand(crtc, NV84_CRTC0_BLANK_UNK1, NV84_CRTC0_BLANK_UNK1_UNBLANK);
- NV50CrtcCommand(crtc, NV50_CRTC0_BLANK_CTRL, NV50_CRTC0_BLANK_CTRL_UNBLANK);
- }
-
- crtc->blanked = blanked;
-}
-
-static void
-NV50CrtcSetDither(nouveauCrtcPtr crtc)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50CrtcSetDither is called (%s).\n", !crtc->modeset_lock ? "update" : "no update");
-
- NV50CrtcCommand(crtc, NV50_CRTC0_DITHERING_CTRL, crtc->dithering ?
- NV50_CRTC0_DITHERING_CTRL_ON : NV50_CRTC0_DITHERING_CTRL_OFF);
-
- if (!crtc->modeset_lock)
- NV50DisplayCommand(pScrn, NV50_UPDATE_DISPLAY, 0);
-}
-
-static void
-ComputeAspectScale(DisplayModePtr mode, DisplayModePtr adjusted_mode, int *outX, int *outY)
-{
- float scaleX, scaleY, scale;
-
- scaleX = adjusted_mode->HDisplay / (float)mode->HDisplay;
- scaleY = adjusted_mode->VDisplay / (float)mode->VDisplay;
-
- if (scaleX > scaleY)
- scale = scaleY;
- else
- scale = scaleX;
-
- *outX = mode->HDisplay * scale;
- *outY = mode->VDisplay * scale;
-}
-
-static void
-NV50CrtcSetScaleMode(nouveauCrtcPtr crtc, int scale)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50CrtcSetScale is called with mode %d for %s.\n", scale, crtc->index ? "CRTC1" : "CRTC0");
-
- uint32_t scale_val = 0;
- int outX = 0, outY = 0;
-
- switch(scale) {
- case SCALE_ASPECT:
- ComputeAspectScale(crtc->cur_mode, crtc->native_mode, &outX, &outY);
- break;
- case SCALE_FULLSCREEN:
- outX = crtc->native_mode->HDisplay;
- outY = crtc->native_mode->VDisplay;
- break;
- case SCALE_NOSCALE:
- case SCALE_PANEL:
- default:
- outX = crtc->cur_mode->HDisplay;
- outY = crtc->cur_mode->VDisplay;
- break;
- }
-
- /* Got a better name for SCALER_ACTIVE? */
- if ((crtc->cur_mode->Flags & V_DBLSCAN) || (crtc->cur_mode->Flags & V_INTERLACE) ||
- crtc->cur_mode->HDisplay != outX || crtc->cur_mode->VDisplay != outY) {
- scale_val = NV50_CRTC0_SCALE_CTRL_SCALER_ACTIVE;
- } else {
- scale_val = NV50_CRTC0_SCALE_CTRL_SCALER_INACTIVE;
- }
-
- NV50CrtcCommand(crtc, NV50_CRTC0_SCALE_CTRL, scale_val);
- NV50CrtcCommand(crtc, NV50_CRTC0_SCALE_RES1, outY << 16 | outX);
- NV50CrtcCommand(crtc, NV50_CRTC0_SCALE_RES2, outY << 16 | outX);
-}
-
-/*
- * Cursor stuff.
- */
-
-static void
-NV50CrtcShowCursor(nouveauCrtcPtr crtc, Bool forced_lock)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- //xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50CrtcShowCursor is called for %s.\n", crtc->index ? "CRTC1" : "CRTC0");
-
- if (!crtc->modeset_lock)
- crtc->cursor_visible = TRUE;
-
- NV50CrtcCommand(crtc, NV50_CRTC0_CURSOR_CTRL, NV50_CRTC0_CURSOR_CTRL_SHOW);
-
- /* Calling this during modeset will lock things up. */
- if (!crtc->modeset_lock && !forced_lock)
- NV50DisplayCommand(pScrn, NV50_UPDATE_DISPLAY, 0);
-}
-
-static void
-NV50CrtcHideCursor(nouveauCrtcPtr crtc, Bool forced_lock)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- //xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50CrtcHideCursor is called for %s.\n", crtc->index ? "CRTC1" : "CRTC0");
-
- if (!crtc->modeset_lock)
- crtc->cursor_visible = FALSE;
-
- NV50CrtcCommand(crtc, NV50_CRTC0_CURSOR_CTRL, NV50_CRTC0_CURSOR_CTRL_HIDE);
-
- /* Calling this during modeset will lock things up. */
- if (!crtc->modeset_lock && !forced_lock)
- NV50DisplayCommand(pScrn, NV50_UPDATE_DISPLAY, 0);
-}
-
-static void
-NV50CrtcSetCursorPosition(nouveauCrtcPtr crtc, int x, int y)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NVPtr pNv = NVPTR(pScrn);
- NVWrite(pNv, NV50_CRTC0_CURSOR_POS + crtc->index * 0x1000, (y & 0xFFFF) << 16 | (x & 0xFFFF));
-
- /* This is needed to allow the cursor to move. */
- NVWrite(pNv, NV50_CRTC0_CURSOR_POS_CTRL + crtc->index * 0x1000, 0);
-}
-
-static void
-NV50CrtcLoadCursor(nouveauCrtcPtr crtc, Bool argb, uint32_t *src)
-{
- NVPtr pNv = NVPTR(crtc->scrn);
- struct nouveau_bo *cursor = NULL;
-
- if (!argb) /* FIXME */
- return;
-
- nouveau_bo_ref(crtc->index ? pNv->Cursor2 : pNv->Cursor, &cursor);
- nouveau_bo_map(cursor, NOUVEAU_BO_WR);
- /* Assume cursor is 64x64 */
- memcpy(cursor->map, src, 64 * 64 * 4);
- nouveau_bo_unmap(cursor);
-}
-
-/*
- * Gamma stuff.
- */
-
-/*
- * The indices are a bit strange, but i'll assume it's correct (taken from nv).
- * The LUT resolution seems to be 14 bits on NV50 as opposed to the 8 bits of previous hardware.
- */
-static void
-NV50CrtcGammaSet(nouveauCrtcPtr crtc, uint16_t *red, uint16_t *green, uint16_t *blue, int size)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- uint32_t i;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50CrtcGammaSet is called for %s.\n", crtc->index ? "CRTC1" : "CRTC0");
-
- for (i = 0; i < 256; i++) {
- crtc->lut_values[i].red = red[i] >> 2;
- crtc->lut_values[i].green = green[i] >> 2;
- crtc->lut_values[i].blue = blue[i] >> 2;
- }
-
- crtc->lut_values_valid = true;
-
- /* This is pre-init, we don't have access to the lut bo now. */
- if (!crtc->lut)
- return;
-
- nouveau_bo_map(crtc->lut, NOUVEAU_BO_WR);
- memcpy(crtc->lut->map, crtc->lut_values, 4*256*sizeof(uint16_t));
- nouveau_bo_unmap(crtc->lut);
-}
-
-void
-NV50CrtcInit(ScrnInfoPtr pScrn)
-{
- int i;
- NVPtr pNv = NVPTR(pScrn);
-
- for (i=0; i < 2; i++) {
- nouveauCrtcPtr crtc = xnfcalloc(sizeof(nouveauCrtcRec), 1);
- crtc->scrn = pScrn;
- crtc->index = i;
-
- /* Function pointers. */
- crtc->ModeValid = NV50CrtcModeValid;
- crtc->ModeSet = NV50CrtcModeSet;
- crtc->SetPixelClock = NV50CrtcSetPixelClock;
- crtc->SetClockMode = NV50CrtcSetClockMode;
-
- crtc->SetFB = NV50CrtcSetFB;
- crtc->SetFBOffset = NV50CrtcSetFBOffset;
-
- crtc->Blank = NV50CrtcBlank;
- crtc->SetDither = NV50CrtcSetDither;
-
- crtc->SetScaleMode = NV50CrtcSetScaleMode;
-
- crtc->ShowCursor = NV50CrtcShowCursor;
- crtc->HideCursor = NV50CrtcHideCursor;
- crtc->SetCursorPosition = NV50CrtcSetCursorPosition;
- crtc->LoadCursor = NV50CrtcLoadCursor;
-
- crtc->GammaSet = NV50CrtcGammaSet;
-
- pNv->crtc[i] = crtc;
- }
-}
-
-void
-NV50CrtcDestroy(ScrnInfoPtr pScrn)
-{
- int i;
- NVPtr pNv = NVPTR(pScrn);
-
- for (i=0; i < 2; i++) {
- nouveauCrtcPtr crtc = pNv->crtc[i];
-
- if (!crtc)
- continue;
-
- xfree(crtc->name);
- xfree(crtc);
- pNv->crtc[i] = NULL;
- }
-}
diff --git a/src/nv50_cursor.c b/src/nv50_cursor.c
deleted file mode 100644
index 11c37cf..0000000
--- a/src/nv50_cursor.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2007 NVIDIA, Corporation
- * Copyright (c) 2008 Maarten Maathuis
- *
- * 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.
- */
-
-#include <string.h>
-
-#include <cursorstr.h>
-
-#include "nv_include.h"
-
-Bool NV50CursorAcquire(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- int i;
-
- if (!pNv->HWCursor) return TRUE;
-
- /* Initialize the cursor on each head */
- for (i = 0; i < 2; i++) {
- nouveauCrtcPtr crtc = pNv->crtc[i];
- const int headOff = 0x10 * crtc->index;
-
- NVWrite(pNv, NV50_CRTC0_CURSOR_CTRL2 + headOff, 0x2000);
- while (NVRead(pNv, NV50_CRTC0_CURSOR_CTRL2 + headOff) & NV50_CRTC_CURSOR_CTRL2_STATUS_MASK);
-
- NVWrite(pNv, NV50_CRTC0_CURSOR_CTRL2 + headOff, NV50_CRTC_CURSOR_CTRL2_ON);
- while ((NVRead(pNv, NV50_CRTC0_CURSOR_CTRL2 + headOff) & NV50_CRTC_CURSOR_CTRL2_STATUS_MASK) != NV50_CRTC_CURSOR_CTRL2_STATUS_ACTIVE);
- }
-
- return TRUE;
-}
-
-void NV50CursorRelease(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- int i;
-
- if (!pNv->HWCursor) return;
-
- /* Release the cursor on each head */
- for (i = 0; i < 2; i++) {
- nouveauCrtcPtr crtc = pNv->crtc[i];
- const int headOff = 0x10 * crtc->index;
-
- NVWrite(pNv, NV50_CRTC0_CURSOR_CTRL2 + headOff, NV50_CRTC_CURSOR_CTRL2_OFF);
- while (NVRead(pNv, NV50_CRTC0_CURSOR_CTRL2 + headOff) & NV50_CRTC_CURSOR_CTRL2_STATUS_MASK);
- }
-}
-
-Bool NV50CursorInit(ScreenPtr pScreen)
-{
- return xf86_cursors_init(pScreen, 64, 64,
- HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
- HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
- HARDWARE_CURSOR_ARGB);
-}
-
diff --git a/src/nv50_dac.c b/src/nv50_dac.c
deleted file mode 100644
index 9ec5eef..0000000
--- a/src/nv50_dac.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright 2007 NVIDIA, Corporation
- * Copyright 2008 Maarten Maathuis
- *
- * 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 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.
- */
-
-#include "nouveau_modeset.h"
-#include "nouveau_crtc.h"
-#include "nouveau_output.h"
-#include "nouveau_connector.h"
-
-static int
-NV50DacModeValid(nouveauOutputPtr output, DisplayModePtr mode)
-{
- if (mode->Clock > 400000)
- return MODE_CLOCK_HIGH;
-
- if (mode->Clock < 25000)
- return MODE_CLOCK_LOW;
-
- return MODE_OK;
-}
-
-static void
-NV50DacModeSet(nouveauOutputPtr output, DisplayModePtr mode)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50DacModeSet is called.\n");
-
- const int dacOff = 0x80 * NV50OrOffset(output);
- uint32_t mode_ctl = NV50_DAC_MODE_CTRL_OFF;
- uint32_t mode_ctl2 = 0;
-
- if (!mode) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disconnecting DAC.\n");
- NV50DisplayCommand(pScrn, NV50_DAC0_MODE_CTRL + dacOff, mode_ctl);
- return;
- }
-
- /* Anyone know a more appropriate name? */
- DisplayModePtr desired_mode = output->crtc->use_native_mode ? output->crtc->native_mode : mode;
-
- if (output->crtc) {
- if (output->crtc->index == 1)
- mode_ctl |= NV50_DAC_MODE_CTRL_CRTC1;
- else
- mode_ctl |= NV50_DAC_MODE_CTRL_CRTC0;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Warning, output has no crtc.\n");
- return;
- }
-
- if (output->type == OUTPUT_ANALOG) {
- /* What is this? */
- mode_ctl |= 0x40;
- } else if (output->type == OUTPUT_TV) {
- mode_ctl |= 0x100;
- }
-
- if (desired_mode->Flags & V_NHSYNC)
- mode_ctl2 |= NV50_DAC_MODE_CTRL2_NHSYNC;
-
- if (desired_mode->Flags & V_NVSYNC)
- mode_ctl2 |= NV50_DAC_MODE_CTRL2_NVSYNC;
-
- // This wouldn't be necessary, but the server is stupid and calls
- // nv50_dac_dpms after the output is disconnected, even though the hardware
- // turns it off automatically.
- output->SetPowerMode(output, DPMSModeOn);
-
- NV50DisplayCommand(pScrn, NV50_DAC0_MODE_CTRL + dacOff, mode_ctl);
-
- NV50DisplayCommand(pScrn, NV50_DAC0_MODE_CTRL2 + dacOff, mode_ctl2);
-
- output->crtc->SetScaleMode(output->crtc, output->scale_mode);
-}
-
-static void
-NV50DacSetClockMode(nouveauOutputPtr output, int clock)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50DacSetClockMode is called.\n");
-
- NVPtr pNv = NVPTR(pScrn);
- NVWrite(pNv, NV50_DAC0_CLK_CTRL2 + NV50OrOffset(output) * 0x800, 0);
-}
-
-static int
-NV50DacSense(nouveauOutputPtr output)
-{
- switch (output->type) {
- case OUTPUT_ANALOG:
- case OUTPUT_TV:
- return output->type;
- default:
- return OUTPUT_NONE;
- }
-}
-
-static Bool
-NV50DacDetect (nouveauOutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- NVPtr pNv = NVPTR(pScrn);
- const int scrnIndex = pScrn->scrnIndex;
- int sigstate;
- uint32_t load, dactestval, tmp;
-
- NVWrite(pNv, NV50_DAC0_CLK_CTRL1 + NV50OrOffset(output) * 0x800, 0x00000001);
- tmp = NVRead(pNv, NV50_DAC0_DPMS_CTRL + NV50OrOffset(output) * 0x800);
-
- NVWrite(pNv, NV50_DAC0_DPMS_CTRL + NV50OrOffset(output) * 0x800, NV50_DAC_DPMS_CTRL_DEFAULT_STATE | NV50_DAC_DPMS_CTRL_PENDING);
- while (NVRead(pNv, NV50_DAC0_DPMS_CTRL + NV50OrOffset(output) * 0x800) & NV50_DAC_DPMS_CTRL_PENDING);
-
- dactestval = 340;
- if (pNv->vbios->dactestval) {
- dactestval = pNv->vbios->dactestval;
- xf86DrvMsg(scrnIndex, X_INFO, "Using bios provided load value of %d\n", dactestval);
- } else {
- xf86DrvMsg(scrnIndex, X_INFO, "Using default load value of %d\n", dactestval);
- }
-
- NVWrite(pNv, NV50_DAC0_LOAD_CTRL + NV50OrOffset(output) * 0x800, dactestval | NV50_DAC_LOAD_CTRL_ACTIVE);
- /* Why is this needed, load detect is almost instantanious and seemingly reliable for me. */
- sigstate = xf86BlockSIGIO();
- usleep(45000);
- xf86UnblockSIGIO(sigstate);
- load = NVRead(pNv, NV50_DAC0_LOAD_CTRL + NV50OrOffset(output) * 0x800);
- NVWrite(pNv, NV50_DAC0_LOAD_CTRL + NV50OrOffset(output) * 0x800, 0);
- NVWrite(pNv, NV50_DAC0_DPMS_CTRL + NV50OrOffset(output) * 0x800, NV50_DAC_DPMS_CTRL_PENDING | tmp);
-
- // Use this DAC if all three channels show load.
- if ((load & NV50_DAC_LOAD_CTRL_PRESENT) == NV50_DAC_LOAD_CTRL_PRESENT) {
- xf86DrvMsg(scrnIndex, X_PROBED, "Load present on DAC-%i\n", NV50OrOffset(output));
- return TRUE;
- }
-
- xf86DrvMsg(scrnIndex, X_PROBED, "No Load present on DAC-%i\n", NV50OrOffset(output));
- return FALSE;
-}
-
-static void
-NV50DacSetPowerMode(nouveauOutputPtr output, int mode)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50DacSetPowerMode is called with mode %d.\n", mode);
-
- uint32_t tmp;
- NVPtr pNv = NVPTR(pScrn);
-
- /*
- * DPMSModeOn everything on
- * DPMSModeStandby hsync disabled, vsync enabled
- * DPMSModeSuspend hsync enabled, vsync disabled
- * DPMSModeOff sync disabled
- */
- while(NVRead(pNv, NV50_DAC0_DPMS_CTRL + NV50OrOffset(output) * 0x800) & NV50_DAC_DPMS_CTRL_PENDING);
-
- tmp = NVRead(pNv, NV50_DAC0_DPMS_CTRL + NV50OrOffset(output) * 0x800);
- tmp &= ~0x7f;
- tmp |= NV50_DAC_DPMS_CTRL_PENDING;
-
- if (mode == DPMSModeStandby || mode == DPMSModeOff)
- tmp |= NV50_DAC_DPMS_CTRL_HSYNC_OFF;
- if (mode == DPMSModeSuspend || mode == DPMSModeOff)
- tmp |= NV50_DAC_DPMS_CTRL_VSYNC_OFF;
- if (mode != DPMSModeOn)
- tmp |= NV50_DAC_DPMS_CTRL_BLANKED;
- if (mode == DPMSModeOff)
- tmp |= NV50_DAC_DPMS_CTRL_OFF;
-
- NVWrite(pNv, NV50_DAC0_DPMS_CTRL + NV50OrOffset(output) * 0x800, tmp);
-}
-
-static nouveauCrtcPtr
-NV50DacGetCurrentCrtc(nouveauOutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50DacGetCurrentCrtc is called.\n");
-
- NVPtr pNv = NVPTR(pScrn);
- uint32_t mode_ctrl = NVRead(pNv, NV50_DAC0_MODE_CTRL_VAL + NV50OrOffset(output) * 0x8);
-
- /*
- * MODE_CTRL values only contain one instance of crtc0 and of crtc1.
- * This is because we disconnect outputs upon modeset.
- * Crtc might be off even if we get a positive return.
- * But we are still associated with that crtc.
- */
- if (mode_ctrl & NV50_DAC_MODE_CTRL_CRTC0)
- return pNv->crtc[0];
- else if (mode_ctrl & NV50_DAC_MODE_CTRL_CRTC1)
- return pNv->crtc[1];
-
- return NULL;
-}
-
-void
-NV50DacSetFunctionPointers(nouveauOutputPtr output)
-{
- output->ModeValid = NV50DacModeValid;
- output->ModeSet = NV50DacModeSet;
- output->SetClockMode = NV50DacSetClockMode;
- output->Sense = NV50DacSense;
- output->Detect = NV50DacDetect;
- output->SetPowerMode = NV50DacSetPowerMode;
- output->GetCurrentCrtc = NV50DacGetCurrentCrtc;
-}
diff --git a/src/nv50_display.c b/src/nv50_display.c
deleted file mode 100644
index 9dcdbd1..0000000
--- a/src/nv50_display.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2007 NVIDIA, Corporation
- * Copyright (c) 2008 Maarten Maathuis
- *
- * 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.
- */
-
-#include <float.h>
-#include <math.h>
-#include <strings.h>
-#include <unistd.h>
-
-#include "nv_include.h"
-
-Bool
-NV50DispPreInit(ScrnInfoPtr pScrn)
-{
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50DispPreInit is called.\n");
-
- NVPtr pNv = NVPTR(pScrn);
- /*
- * I get the strange feeling that the 0x006101XX range is some kind of master modesetting control.
- * Maybe this what triggers it to be enabled.
- */
- NVWrite(pNv, 0x00610184, NVRead(pNv, 0x00614004));
- /* CRTC related? */
- NVWrite(pNv, 0x00610190 + 0 * 0x10, NVRead(pNv, 0x00616100 + 0 * 0x800));
- NVWrite(pNv, 0x00610190 + 1 * 0x10, NVRead(pNv, 0x00616100 + 1 * 0x800));
- NVWrite(pNv, 0x00610194 + 0 * 0x10, NVRead(pNv, 0x00616104 + 0 * 0x800));
- NVWrite(pNv, 0x00610194 + 1 * 0x10, NVRead(pNv, 0x00616104 + 1 * 0x800));
- NVWrite(pNv, 0x00610198 + 0 * 0x10, NVRead(pNv, 0x00616108 + 0 * 0x800));
- NVWrite(pNv, 0x00610198 + 1 * 0x10, NVRead(pNv, 0x00616108 + 1 * 0x800));
- NVWrite(pNv, 0x0061019c + 0 * 0x10, NVRead(pNv, 0x0061610c + 0 * 0x800));
- NVWrite(pNv, 0x0061019c + 1 * 0x10, NVRead(pNv, 0x0061610c + 1 * 0x800));
- NVWrite(pNv, 0x006101d0 + DAC0 * 0x4, NVRead(pNv, 0x0061a000 + DAC0 * 0x800));
- NVWrite(pNv, 0x006101d0 + DAC1 * 0x4, NVRead(pNv, 0x0061a000 + DAC1 * 0x800));
- NVWrite(pNv, 0x006101d0 + DAC2 * 0x4, NVRead(pNv, 0x0061a000 + DAC2 * 0x800));
- NVWrite(pNv, 0x006101e0 + SOR0 * 0x4, NVRead(pNv, 0x0061c000 + SOR0 * 0x800));
- NVWrite(pNv, 0x006101e0 + SOR1 * 0x4, NVRead(pNv, 0x0061c000 + SOR1 * 0x800));
- NVWrite(pNv, 0x006101e0 + SOR2 * 0x4, NVRead(pNv, 0x0061c000 + SOR2 * 0x800));
- /* Maybe TV-out related, or something more generic? */
- /* These are not in nv, so it must be something nv does not use. */
- NVWrite(pNv, 0x006101f0 + 0 * 0x4, NVRead(pNv, 0x0061e000 + 0 * 0x800));
- NVWrite(pNv, 0x006101f0 + 1 * 0x4, NVRead(pNv, 0x0061e000 + 1 * 0x800));
- NVWrite(pNv, 0x006101f0 + 2 * 0x4, NVRead(pNv, 0x0061e000 + 2 * 0x800));
- /* 0x00150000 seems to be the default state on many cards. why the extra bit is needed on some is unknown. */
- NVWrite(pNv, NV50_DAC0_DPMS_CTRL, 0x00400000 | NV50_DAC_DPMS_CTRL_DEFAULT_STATE | NV50_DAC_DPMS_CTRL_PENDING);
- NVWrite(pNv, NV50_DAC0_CLK_CTRL1, 0x00000001);
- NVWrite(pNv, NV50_DAC1_DPMS_CTRL, 0x00400000 | NV50_DAC_DPMS_CTRL_DEFAULT_STATE | NV50_DAC_DPMS_CTRL_PENDING);
- NVWrite(pNv, NV50_DAC1_CLK_CTRL1, 0x00000001);
- NVWrite(pNv, NV50_DAC2_DPMS_CTRL, 0x00400000 | NV50_DAC_DPMS_CTRL_DEFAULT_STATE | NV50_DAC_DPMS_CTRL_PENDING);
- NVWrite(pNv, NV50_DAC2_CLK_CTRL1, 0x00000001);
-
- return TRUE;
-}
-
-Bool
-NV50DispInit(ScrnInfoPtr pScrn)
-{
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50DispInit is called.\n");
-
- NVPtr pNv = NVPTR(pScrn);
- uint32_t val;
- if (NVRead(pNv, NV50_DISPLAY_SUPERVISOR) & 0x100) {
- NVWrite(pNv, NV50_DISPLAY_SUPERVISOR, 0x100);
- NVWrite(pNv, 0x006194e8, NVRead(pNv, 0x006194e8) & ~1);
- while (NVRead(pNv, 0x006194e8) & 2);
- }
-
- NVWrite(pNv, NV50_DISPLAY_UNK200_CTRL, 0x2b00);
- /* A bugfix (#12637) from the nv driver, to unlock the driver if it's left in a poor state */
- do {
- val = NVRead(pNv, NV50_DISPLAY_UNK200_CTRL);
- if ((val & 0x9f0000) == 0x20000)
- NVWrite(pNv, NV50_DISPLAY_UNK200_CTRL, val | 0x800000);
-
- if ((val & 0x3f0000) == 0x30000)
- NVWrite(pNv, NV50_DISPLAY_UNK200_CTRL, val | 0x200000);
- } while ((val & 0x1e0000) != 0);
- NVWrite(pNv, NV50_DISPLAY_CTRL_STATE, NV50_DISPLAY_CTRL_STATE_ENABLE);
- NVWrite(pNv, NV50_DISPLAY_UNK200_CTRL, 0x1000b03);
- while (!(NVRead(pNv, NV50_DISPLAY_UNK200_CTRL) & 0x40000000));
-
- NV50DisplayCommand(pScrn, NV50_UNK84, 0);
- NV50DisplayCommand(pScrn, NV50_UNK88, 0);
- /* The GetLVDSNativeMode() function is proof that more than crtc0 is used by the bios. */
- NV50DisplayCommand(pScrn, NV50_CRTC0_BLANK_CTRL, NV50_CRTC0_BLANK_CTRL_BLANK);
- NV50DisplayCommand(pScrn, NV50_CRTC0_UNK800, 0);
- NV50DisplayCommand(pScrn, NV50_CRTC0_DISPLAY_START, 0);
- NV50DisplayCommand(pScrn, NV50_CRTC0_UNK82C, 0);
-
- return TRUE;
-}
-
-void
-NV50DispShutdown(ScrnInfoPtr pScrn)
-{
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50DispShutdown is called.\n");
- NVPtr pNv = NVPTR(pScrn);
- int i;
-
- for(i = 0; i < 2; i++) {
- nouveauCrtcPtr crtc = pNv->crtc[i];
-
- crtc->Blank(crtc, TRUE);
- }
-
- NV50DisplayCommand(pScrn, NV50_UPDATE_DISPLAY, 0);
-
- for(i = 0; i < 2; i++) {
- nouveauCrtcPtr crtc = pNv->crtc[i];
-
- /* This is like acknowledging a vblank, maybe this is in the spirit of cleaning up? */
- /* The blob doesn't do it quite this way, it seems to do 0x30C as init and end. */
- /* It doesn't wait for a non-zero value either. */
- if (crtc->active) {
- uint32_t mask = 0;
- if (crtc->index == 1)
- mask = NV50_DISPLAY_SUPERVISOR_CRTC1;
- else
- mask = NV50_DISPLAY_SUPERVISOR_CRTC0;
-
- NVWrite(pNv, NV50_DISPLAY_SUPERVISOR, mask);
- while(!(NVRead(pNv, NV50_DISPLAY_SUPERVISOR) & mask));
- }
- }
-
- NVWrite(pNv, NV50_DISPLAY_UNK200_CTRL, 0x0);
- NVWrite(pNv, NV50_DISPLAY_CTRL_STATE, NV50_DISPLAY_CTRL_STATE_DISABLE);
- while ((NVRead(pNv, NV50_DISPLAY_UNK200_CTRL) & 0x1e0000) != 0);
- while ((NVRead(pNv, NV50_SOR0_DPMS_STATE) & NV50_SOR_DPMS_STATE_WAIT));
- while ((NVRead(pNv, NV50_SOR1_DPMS_STATE) & NV50_SOR_DPMS_STATE_WAIT));
-}
diff --git a/src/nv50_output.c b/src/nv50_output.c
deleted file mode 100644
index c806748..0000000
--- a/src/nv50_output.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2007 NVIDIA, Corporation
- * Copyright (c) 2008 Maarten Maathuis
- *
- * 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.
- */
-
-#include <string.h>
-
-#include "nv_include.h"
-
-#include <xf86DDC.h>
-
-#include "nouveau_crtc.h"
-#include "nouveau_output.h"
-#include "nouveau_connector.h"
-
-int
-NV50OrOffset(nouveauOutputPtr output)
-{
- return ffs(output->dcb->or) - 1;
-}
-
-static void
-NV50OutputInit(ScrnInfoPtr pScrn, struct dcb_entry *dcbent)
-{
- NVPtr pNv = NVPTR(pScrn);
- nouveauConnectorPtr connector = pNv->connector[dcbent->i2c_index];
- nouveauOutputPtr output = NULL;
- char name[20];
- int i;
-
- switch (dcbent->type) {
- case OUTPUT_LVDS:
- case OUTPUT_TMDS:
- sprintf(name, "SOR-%d", ffs(dcbent->or) - 1);
- break;
- case OUTPUT_ANALOG:
- sprintf(name, "DAC-%d", ffs(dcbent->or) - 1);
- break;
- default:
- return;
- }
-
- output = xnfcalloc(sizeof(nouveauOutputRec), 1);
- output->name = xstrdup(name);
- output->dcb = dcbent;
- output->type = dcbent->type;
- output->scrn = pScrn;
-
- /* Put the output in the connector's list of outputs. */
- for (i = 0; i < MAX_OUTPUTS_PER_CONNECTOR; i++) {
- if (connector->outputs[i])
- continue;
- connector->outputs[i] = output;
-
- break;
- }
-
- /* Put ourselves in the main output list. */
- if (!pNv->output) {
- pNv->output = output;
- } else {
- nouveauOutputPtr output_link = pNv->output;
- if (output_link->next) {
- do {
- output_link = output_link->next;
- } while (output_link->next);
- }
- output_link->next = output;
- }
-
- /* Output property for tmds and lvds. */
- output->dithering = (pNv->FPDither || output->type == OUTPUT_LVDS);
-
- if (output->type == OUTPUT_LVDS || output->type == OUTPUT_TMDS) {
- if (pNv->FpScale) /* GPU Scaling */
- output->scale_mode = SCALE_ASPECT;
- else if (output->type == OUTPUT_LVDS)
- output->scale_mode = SCALE_NOSCALE;
- else
- output->scale_mode = SCALE_PANEL;
-
- if (xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE)) {
- output->scale_mode = nv_scaling_mode_lookup(xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE), -1);
- if (output->scale_mode == SCALE_INVALID)
- output->scale_mode = SCALE_ASPECT; /* default */
- }
- }
-
- /* NV5x scaling hardware seems to work fine for analog too. */
- if (output->type == OUTPUT_ANALOG) {
- output->scale_mode = SCALE_PANEL;
-
- if (xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE)) {
- output->scale_mode = nv_scaling_mode_lookup(xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE), -1);
- if (output->scale_mode == SCALE_INVALID)
- output->scale_mode = SCALE_PANEL; /* default */
- }
- }
-
- /* Usually 3, which means both crtc's. */
- output->allowed_crtc = output->dcb->heads;
-
- if (output->type == OUTPUT_TMDS) {
- NVWrite(pNv, NV50_SOR0_UNK00C + NV50OrOffset(output) * 0x800, 0x03010700);
- NVWrite(pNv, NV50_SOR0_UNK010 + NV50OrOffset(output) * 0x800, 0x0000152f);
- NVWrite(pNv, NV50_SOR0_UNK014 + NV50OrOffset(output) * 0x800, 0x00000000);
- NVWrite(pNv, NV50_SOR0_UNK018 + NV50OrOffset(output) * 0x800, 0x00245af8);
- }
-
-#if 0
- if (output->type == OUTPUT_LVDS) {
- /* now fpindex should be known, so reread the table here. */
- /* not that we do a lot with the information. */
- parse_lvds_manufacturer_table(pScrn, 0);
- }
-#endif
-
- /* This needs to be handled in the same way as pre-NV5x on the long run. */
- //if (output->type == OUTPUT_LVDS)
- // pNv->vbios->fp.native_mode = GetLVDSNativeMode(pScrn);
-
- /* Function pointers. */
- if (output->type == OUTPUT_TMDS || output->type == OUTPUT_LVDS) {
- NV50SorSetFunctionPointers(output);
- } else if (output->type == OUTPUT_ANALOG || output->type == OUTPUT_TV) {
- NV50DacSetFunctionPointers(output);
- }
-}
-
-#define MULTIPLE_ENCODERS(e) ((e) & ((e) - 1))
-void
-NV50OutputSetup(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- struct parsed_dcb *dcb = pNv->vbios->dcb;
- int lvds = 0, dvi_i = 0, dvi_d = 0, vga = 0;
- uint16_t connector[16] = {};
- char name[20];
- int i;
-
- for (i = 0; i < dcb->entries; i++) {
- struct dcb_entry *dcbent = &dcb->entry[i];
-
- switch (dcbent->type) {
- case OUTPUT_ANALOG:
- case OUTPUT_TMDS:
- case OUTPUT_LVDS:
- break;
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "DCB encoder type %d not known\n",
- dcbent->type);
- continue;
- }
-
- connector[dcbent->i2c_index] |= (1 << i);
- NV50OutputInit(pScrn, dcbent);
- }
-
- for (i = 0; i < dcb->entries; i++) {
- struct dcb_entry *dcbent = &dcb->entry[i];
- nouveauConnectorPtr c = pNv->connector[dcbent->i2c_index];
- uint16_t encoders;
-
- encoders = connector[dcbent->i2c_index];
- connector[dcbent->i2c_index] = 0;
-
- if (!encoders)
- continue;
-
- switch (dcbent->type) {
- case OUTPUT_ANALOG:
- if (!MULTIPLE_ENCODERS(encoders))
- sprintf(name, "VGA-%d", vga++);
- else
- sprintf(name, "DVI-I-%d", dvi_i++);
- break;
- case OUTPUT_TMDS:
- if (!MULTIPLE_ENCODERS(encoders))
- sprintf(name, "DVI-D-%d", dvi_d++);
- else
- sprintf(name, "DVI-I-%d", dvi_i++);
- break;
- case OUTPUT_LVDS:
- sprintf(name, "LVDS-%d", lvds++);
- break;
- default:
- continue;
- }
-
- if (dcbent->i2c_index != 0xf) {
- NV_I2CInit(pScrn, &pNv->pI2CBus[dcbent->i2c_index],
- &dcb->i2c[dcbent->i2c_index],
- xstrdup(name));
- }
-
- xfree(c->name);
- c->name = xstrdup(name);
- c->i2c_index = dcbent->i2c_index;
- c->pDDCBus = pNv->pI2CBus[dcbent->i2c_index];
- }
-}
-
-void
-NV50OutputDestroy(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- nouveauOutputPtr output, next;
-
- for (output = pNv->output; output != NULL; output = next) {
- next = output->next;
- xfree(output->name);
- xfree(output);
- }
-
- pNv->output = NULL;
-}
diff --git a/src/nv50_randr.c b/src/nv50_randr.c
deleted file mode 100644
index b163fda..0000000
--- a/src/nv50_randr.c
+++ /dev/null
@@ -1,899 +0,0 @@
-/*
- * Copyright 2008 Maarten Maathuis
- *
- * 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 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.
- */
-
-#include "nv50_randr.h"
-#include "X11/Xatom.h"
-
-/*
- * A randr-1.2 wrapper around the NV50 driver.
- */
-
-/*
- * CRTC stuff.
- */
-
-static void
-nv50_crtc_dpms(xf86CrtcPtr crtc, int mode)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_crtc_dpms is called with mode %d for %s.\n", mode, nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- switch (mode) {
- case DPMSModeOn:
- nv_crtc->crtc->active = TRUE;
- break;
- case DPMSModeSuspend:
- case DPMSModeStandby:
- case DPMSModeOff:
- default:
- nv_crtc->crtc->active = FALSE;
- break;
- }
-}
-
-static Bool
-nv50_crtc_lock(xf86CrtcPtr crtc)
-{
- return FALSE;
-}
-
-static Bool
-nv50_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
- DisplayModePtr adjusted_mode)
-{
- return TRUE;
-}
-
-static void
-nv50_crtc_prepare(xf86CrtcPtr crtc)
-{
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- ScrnInfoPtr pScrn = crtc->scrn;
- NVPtr pNv = NVPTR(pScrn);
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- nouveauOutputPtr output;
- int i;
-
- /* Rewire internal stucts to match randr-1.2... yet again.. */
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- NV50OutputPrivatePtr nv50_output = output->driver_private;
- nouveauOutputPtr nv_output = nv50_output->output;
-
- if (output->crtc) {
- NV50CrtcPrivatePtr nv50_crtc =
- output->crtc->driver_private;
- nv_output->crtc = nv50_crtc->crtc;
- } else {
- nv_output->crtc = NULL;
- }
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "nv50_crtc_prepare is called for %s.\n",
- nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- nv_crtc->crtc->active = TRUE;
- nv_crtc->crtc->modeset_lock = TRUE;
-
- /* Detach any unused outputs. */
- for (output = pNv->output; output != NULL; output = output->next) {
- if (!output->crtc)
- output->ModeSet(output, NULL);
- }
-}
-
-static void
-nv50_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
- DisplayModePtr adjusted_mode, int x, int y)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- struct nouveau_bo *bo;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "nv50_crtc_mode_set is called for %s.\n",
- nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- NVPtr pNv = NVPTR(pScrn);
-
- bo = pNv->scanout;
- if (crtc->rotatedData) {
- bo = nv_crtc->shadow;
- x = 0;
- y = 0;
- }
-
- nv_crtc->crtc->SetFB(nv_crtc->crtc, bo);
- nv_crtc->crtc->SetFBOffset(nv_crtc->crtc, x, y);
- nv_crtc->crtc->ModeSet(nv_crtc->crtc, mode);
-}
-
-static void
-nv50_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, int size)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_crtc_gamma_set is called for %s.\n", nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- nv_crtc->crtc->GammaSet(nv_crtc->crtc, (uint16_t *) red, (uint16_t *) green, (uint16_t *) blue, size);
-}
-
-static void
-nv50_crtc_commit(xf86CrtcPtr crtc)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_crtc_commit is called for %s.\n", nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- NVPtr pNv = NVPTR(pScrn);
-
- /* Let's detect any outputs and connectors that have gone inactive. */
- uint8_t crtc_active_mask = 0;
- int i, j;
- nouveauOutputPtr output;
-
- for (i = 0; i < DCB_MAX_NUM_I2C_ENTRIES; i++) {
- Bool connector_active = FALSE;
- for (j = 0; j < MAX_OUTPUTS_PER_CONNECTOR; j++) {
- output = pNv->connector[i]->outputs[j];
- if (output) {
- if (output->crtc) {
- crtc_active_mask |= 1 << output->crtc->index;
- connector_active = TRUE;
- } else {
- output->active = FALSE;
- }
- }
- }
-
- pNv->connector[i]->active = connector_active;
- }
-
- /* Blank any crtc's that are inactive. */
- if (!(crtc_active_mask & (1 << 0)))
- pNv->crtc[0]->Blank(pNv->crtc[0], TRUE);
-
- if (!(crtc_active_mask & (1 << 1)))
- pNv->crtc[1]->Blank(pNv->crtc[1], TRUE);
-
- xf86_reload_cursors(pScrn->pScreen);
-
- NV50DisplayCommand(pScrn, NV50_UPDATE_DISPLAY, 0);
-
- nv_crtc->crtc->modeset_lock = FALSE;
-}
-
-/*
- * Cursor CRTC stuff.
- */
-
-static void
-nv50_crtc_show_cursor(xf86CrtcPtr crtc)
-{
- //ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- //xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_crtc_show_cursor is called for %s.\n", nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- if (!nv_crtc->crtc->blanked)
- nv_crtc->crtc->ShowCursor(nv_crtc->crtc, FALSE);
-}
-
-static void
-nv50_crtc_hide_cursor(xf86CrtcPtr crtc)
-{
- //ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- //xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_crtc_hide_cursor is called for %s.\n", nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- nv_crtc->crtc->HideCursor(nv_crtc->crtc, FALSE);
-}
-
-static void
-nv50_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
-{
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
-
- nv_crtc->crtc->SetCursorPosition(nv_crtc->crtc, x, y);
-}
-
-static void
-nv50_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *src)
-{
- //ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- //xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_crtc_load_cursor_argb is called for %s.\n", nv_crtc->crtc->index ? "CRTC1" : "CRTC0");
-
- nv_crtc->crtc->LoadCursor(nv_crtc->crtc, TRUE, (uint32_t *) src);
-}
-
-static void *
-nv50_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- NVPtr pNv = NVPTR(pScrn);
- int size, pitch;
-
- ErrorF("nv50_crtc_shadow_allocate\n");
-
- pitch = pScrn->displayWidth * (pScrn->bitsPerPixel/8);
- size = pitch * height;
-
- if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_MAP, 64, size, &nv_crtc->shadow)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate memory for shadow buffer!\n");
- return NULL;
- }
-
- if (nv_crtc->shadow && nouveau_bo_map(nv_crtc->shadow, NOUVEAU_BO_RDWR)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to map shadow buffer.\n");
- return NULL;
- }
-
- pNv->shadow[nv_crtc->crtc->index] = nv_crtc->shadow;
-
- return nv_crtc->shadow->map;
-}
-
-static PixmapPtr
-nv50_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- uint32_t pitch;
- PixmapPtr rotate_pixmap;
-
- ErrorF("nv50_crtc_shadow_create\n");
-
- if (!data)
- data = crtc->funcs->shadow_allocate (crtc, width, height);
-
- pitch = pScrn->displayWidth * (pScrn->bitsPerPixel/8);
-
- rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
- width, height,
- pScrn->depth,
- pScrn->bitsPerPixel,
- pitch,
- data);
-
- if (rotate_pixmap == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Couldn't allocate shadow pixmap for rotated CRTC\n");
- }
-
- return rotate_pixmap;
-}
-
-static void
-nv50_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- NVPtr pNv = NVPTR(pScrn);
- ScreenPtr pScreen = pScrn->pScreen;
-
- ErrorF("nv50_crtc_shadow_destroy\n");
-
- if (rotate_pixmap)
- pScreen->DestroyPixmap(rotate_pixmap);
-
- if (nv_crtc->shadow)
- nouveau_bo_ref(NULL, &nv_crtc->shadow);
-
- nv_crtc->shadow = NULL;
- /* for easy acces by exa */
- pNv->shadow[nv_crtc->crtc->index] = NULL;
-}
-
-#if XF86_CRTC_VERSION >= 2
-static void
-nv50_crtc_set_origin(xf86CrtcPtr crtc, int x, int y)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
- nouveauCrtcPtr nvcrtc = nv_crtc->crtc; /* sigh.. */
- NVPtr pNv = NVPTR(pScrn);
- uint32_t fb;
-
- nvcrtc->SetFB(nvcrtc, pNv->scanout);
- nvcrtc->SetFBOffset(nvcrtc, x, y);
- nvcrtc->fb_pitch = pScrn->displayWidth * (pScrn->bitsPerPixel >> 3);
- fb = nvcrtc->front_buffer->offset - pNv->dev->vm_vram_base;
-
- NV50CrtcCommand(nvcrtc, NV50_CRTC0_FB_OFFSET, fb >> 8);
- NV50CrtcCommand(nvcrtc, NV50_CRTC0_FB_PITCH, nvcrtc->fb_pitch | (1<<20));
- NV50CrtcCommand(nvcrtc, NV50_CRTC0_FB_SIZE, (pScrn->virtualY << 16) |
- pScrn->virtualX);
-
- NV50DisplayCommand(pScrn, NV50_UPDATE_DISPLAY, 0);
-}
-#endif
-
-static void
-nv50_crtc_destroy(xf86CrtcPtr crtc)
-{
- xfree(crtc->driver_private);
-}
-
-static const xf86CrtcFuncsRec nv50_crtc_funcs = {
- .dpms = nv50_crtc_dpms,
- .save = NULL,
- .restore = NULL,
- .lock = nv50_crtc_lock,
- .unlock = NULL,
- .mode_fixup = nv50_crtc_mode_fixup,
- .prepare = nv50_crtc_prepare,
- .mode_set = nv50_crtc_mode_set,
- .gamma_set = nv50_crtc_gamma_set,
- .commit = nv50_crtc_commit,
- .shadow_create = nv50_crtc_shadow_create,
- .shadow_allocate = nv50_crtc_shadow_allocate,
- .shadow_destroy = nv50_crtc_shadow_destroy,
- .set_cursor_position = nv50_crtc_set_cursor_position,
- .show_cursor = nv50_crtc_show_cursor,
- .hide_cursor = nv50_crtc_hide_cursor,
- .load_cursor_argb = nv50_crtc_load_cursor_argb,
- .destroy = nv50_crtc_destroy,
-#if XF86_CRTC_VERSION >= 2
- .set_origin = nv50_crtc_set_origin,
-#endif
-};
-
-void
-nv50_crtc_init(ScrnInfoPtr pScrn, int crtc_num)
-{
- NVPtr pNv = NVPTR(pScrn);
- xf86CrtcPtr crtc;
- NV50CrtcPrivatePtr nv_crtc;
-
- crtc = xf86CrtcCreate(pScrn, &nv50_crtc_funcs);
- if (crtc == NULL)
- return;
-
- nv_crtc = xnfcalloc (sizeof (NV50CrtcPrivateRec), 1);
- nv_crtc->crtc = pNv->crtc[crtc_num];
-
- crtc->driver_private = nv_crtc;
-}
-
-
-/*
- * "Output" stuff.
- */
-
-static void
-nv50_output_dpms(xf86OutputPtr output, int mode)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_dpms is called with mode %d.\n", mode);
-
- NVPtr pNv = NVPTR(pScrn);
- NV50OutputPrivatePtr nv_output = output->driver_private;
-
- /* Keep the crtc wiring consistent with randr-1.2 */
- if (output->crtc) {
- NV50CrtcPrivatePtr nv_crtc = output->crtc->driver_private;
- nv_output->output->crtc = nv_crtc->crtc;
- } else {
- nv_output->output->crtc = NULL;
- }
-
- /* Our crtc's map 1:1 onto randr-1.2 crtc's. */
- switch (mode) {
- case DPMSModeOn:
- nv_output->output->active = TRUE;
- break;
- case DPMSModeSuspend:
- case DPMSModeStandby:
- case DPMSModeOff:
- default:
- nv_output->output->active = FALSE;
- break;
- }
-
- /* Set dpms on all outputs for ths connector, just to be safe. */
- nouveauConnectorPtr connector =
- pNv->connector[nv_output->output->dcb->i2c_index];
- int i;
- for (i = 0; i < MAX_OUTPUTS_PER_CONNECTOR; i++) {
- if (connector->outputs[i])
- connector->outputs[i]->SetPowerMode(connector->outputs[i], mode);
- }
-}
-
-static int
-nv50_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_mode_valid is called.\n");
-
- NV50OutputPrivatePtr nv_output = output->driver_private;
-
- return nv_output->output->ModeValid(nv_output->output, mode);
-}
-
-static Bool
-nv50_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
-{
- return TRUE;
-}
-
-static void
-nv50_output_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_mode_set is called.\n");
-
- NV50OutputPrivatePtr nv_output = output->driver_private;
-
- nv_output->output->ModeSet(nv_output->output, mode);
-}
-
-static xf86OutputStatus
-nv50_output_detect(xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_detect is called.\n");
-
- NVPtr pNv = NVPTR(pScrn);
- NV50OutputPrivatePtr nv_output = output->driver_private;
- nouveauConnectorPtr connector =
- pNv->connector[nv_output->output->dcb->i2c_index];
-
- if (!connector)
- return XF86OutputStatusDisconnected;
-
- Bool detect_present = FALSE;
- Bool detect_digital = FALSE;
- xf86MonPtr ddc_mon = connector->DDCDetect(connector);
- int i;
-
- if (!ddc_mon) {
- for (i = 0; i < MAX_OUTPUTS_PER_CONNECTOR; i++) {
- if (connector->outputs[i] && connector->outputs[i]->Detect) {
- detect_present = connector->outputs[i]->Detect(connector->outputs[i]);
- if (detect_present) {
- if (connector->outputs[i]->type == OUTPUT_TMDS || connector->outputs[i]->type == OUTPUT_LVDS)
- detect_digital = TRUE;
- break;
- }
- }
- }
- }
-
- /* HACK: assume that a connector only holds output in the case of a tv-out */
- if (nv_output->output->type == OUTPUT_TV)
- return XF86OutputStatusUnknown;
-
- /*
- * We abuse randr-1.2 outputs as connector, so here we have to determine what actual output is connected to the connector.
- */
- if (ddc_mon || detect_present) {
- Bool is_digital = FALSE;
- Bool found = FALSE;
- nouveauCrtcPtr crtc_backup = nv_output->output->crtc;
- nv_output->output->crtc = NULL;
- nv_output->output->connector = NULL;
-
- if (ddc_mon)
- is_digital = ddc_mon->features.input_type;
- else
- is_digital = detect_digital;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected a %s output on %s\n", is_digital ? "Digital" : "Analog", connector->name);
-
- for (i = 0; i < MAX_OUTPUTS_PER_CONNECTOR; i++) {
- if (!is_digital && (connector->outputs[i]->type == OUTPUT_ANALOG || connector->outputs[i]->type == OUTPUT_TV)) {
- found = TRUE;
- } else if (is_digital && (connector->outputs[i]->type == OUTPUT_TMDS || connector->outputs[i]->type == OUTPUT_LVDS)) {
- found = TRUE;
- }
- if (found) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found a suitable output, index %d\n", i);
- connector->connected_output = i;
- connector->outputs[i]->connector = connector;
- connector->outputs[i]->crtc = crtc_backup;
- nv_output->output = connector->outputs[i];
- break;
- }
- }
- }
-
- if (ddc_mon || detect_present) {
- free(ddc_mon);
- return XF86OutputStatusConnected;
- } else {
- return XF86OutputStatusDisconnected;
- }
-}
-
-static DisplayModePtr
-nv50_output_get_modes(xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_detect is called.\n");
-
- NVPtr pNv = NVPTR(pScrn);
- NV50OutputPrivatePtr nv_output = output->driver_private;
- nouveauConnectorPtr connector =
- pNv->connector[nv_output->output->dcb->i2c_index];
-
- xf86MonPtr ddc_mon = connector->DDCDetect(connector);
-
- xf86OutputSetEDID(output, ddc_mon);
-
- DisplayModePtr ddc_modes = connector->GetDDCModes(connector);
- DisplayModePtr default_modes = NULL;
-
- xf86DeleteMode(&nv_output->output->native_mode, nv_output->output->native_mode);
- nv_output->output->native_mode = NULL;
- if (nv_output->output->crtc)
- nv_output->output->crtc->native_mode = NULL;
-
- /* typically only LVDS will hit this code path. */
- if (!ddc_modes) {
- DisplayModeRec mode = {};
-
- if (nv_output->output->type == OUTPUT_LVDS &&
- nouveau_bios_fp_mode(pScrn, &mode)) {
- mode.status = MODE_OK;
- mode.type = M_T_DRIVER | M_T_PREFERRED;
- xf86SetModeDefaultName(&mode);
-
- ddc_modes = xf86DuplicateMode(&mode);
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "LVDS: Using a bios mode, which should work, if it doesn't please report.\n");
- }
- }
-
- if (!ddc_modes && nv_output->output->type == OUTPUT_LVDS) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "LVDS and no modes found, bailing out.\n");
- return NULL;
- }
-
- /* NV5x hardware can also do scaling on analog connections. */
- if (ddc_modes) {
- /* Use the first preferred mode as native mode. */
- DisplayModePtr mode;
-
- /* Find the preferred mode. */
- for (mode = ddc_modes; mode != NULL; mode = mode->next) {
- if (mode->type & M_T_PREFERRED) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "%s: preferred mode is %s\n",
- output->name, mode->name);
- break;
- }
- }
-
- /* TODO: Scaling needs a native mode, maybe fail in a better way. */
- if (!mode) {
- mode = ddc_modes;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "%s: no preferred mode found, using %s\n",
- output->name, mode->name);
- }
-
- nv_output->output->native_mode = xf86DuplicateMode(mode);
- }
-
- /* No ddc means no native mode, so make one up to avoid crashes. */
- if (!nv_output->output->native_mode)
- nv_output->output->native_mode = xf86CVTMode(1024, 768, 60.0, FALSE, FALSE);
-
- xf86SetModeCrtc(nv_output->output->native_mode, 0);
-
- if (nv_output->output->crtc)
- nv_output->output->crtc->native_mode = nv_output->output->native_mode;
-
- if (nv_output->output->type == OUTPUT_LVDS &&
- (!ddc_mon ||!GTF_SUPPORTED(ddc_mon->features.msc))) {
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,6,99,1,0)
- default_modes = xf86GetDefaultModes(output->interlaceAllowed,
- output->doubleScanAllowed);
-#else
- default_modes = xf86GetDefaultModes();
-#endif
- }
-
- xf86ModesAdd(ddc_modes, default_modes);
- return ddc_modes;
-}
-
-static void
-nv50_output_destroy(xf86OutputPtr output)
-{
- NV50OutputPrivatePtr nv_output = output->driver_private;
-
- xf86DeleteMode(&nv_output->output->native_mode, nv_output->output->native_mode);
-
- xfree(output->driver_private);
- output->driver_private = NULL;
-}
-
-void
-nv50_output_prepare(xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_prepare is called.\n");
-
- NV50OutputPrivatePtr nv_output = output->driver_private;
- NV50CrtcPrivatePtr nv_crtc = output->crtc->driver_private;
-
- /* Set the real crtc now. */
- nv_output->output->crtc = nv_crtc->crtc;
-
- /* Transfer some output properties to the crtc for easy access. */
- nv_output->output->crtc->scale_mode = nv_output->output->scale_mode;
- nv_output->output->crtc->dithering = nv_output->output->dithering;
- nv_output->output->crtc->native_mode = nv_output->output->native_mode;
-
- if (nv_output->output->scale_mode != SCALE_PANEL)
- nv_output->output->crtc->use_native_mode = TRUE;
- else
- nv_output->output->crtc->use_native_mode = FALSE;
-}
-
-static void
-nv50_output_commit(xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_commit is called.\n");
-}
-
-#ifdef RANDR_GET_CRTC_INTERFACE
-static xf86CrtcPtr
-nv50_output_get_crtc(xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv50_output_get_crtc is called.\n");
-
- NV50OutputPrivatePtr nv_output = output->driver_private;
- nouveauCrtcPtr crtc = nv_output->output->GetCurrentCrtc(nv_output->output);
-
- /*
- * Match the internal crtc to the public crtc.
- * Note that GetCurrentCrtc() retrieves hardware state.
- * Otherwise we could have just used output->crtc.
- */
- if (crtc) {
- int i;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- for (i = 0; i < xf86_config->num_crtc; i++) {
- NV50CrtcPrivatePtr nv_crtc = xf86_config->crtc[i]->driver_private;
- if (nv_crtc->crtc == crtc)
- return xf86_config->crtc[i];
- }
- }
-
- return NULL;
-}
-#endif /* RANDR_GET_CRTC_INTERFACE */
-
-/*
- * Output properties.
- */
-
-/*
- * Several scaling modes exist, let the user choose.
- */
-#define SCALING_MODE_NAME "SCALING_MODE"
-static const struct {
- char *name;
- enum scaling_modes mode;
-} scaling_mode[] = {
- { "panel", SCALE_PANEL },
- { "fullscreen", SCALE_FULLSCREEN },
- { "aspect", SCALE_ASPECT },
- { "noscale", SCALE_NOSCALE },
- { NULL, SCALE_INVALID}
-};
-static Atom scaling_mode_atom;
-
-#define DITHERING_MODE_NAME "DITHERING"
-static Atom dithering_atom;
-
-int
-nv_scaling_mode_lookup(char *name, int size)
-{
- int i;
-
- /* for when name is zero terminated */
- if (size < 0)
- size = strlen(name);
-
- for (i = 0; scaling_mode[i].name; i++)
- /* We're getting non-terminated strings */
- if (strlen(scaling_mode[i].name) >= size &&
- !strncasecmp(name, scaling_mode[i].name, size))
- break;
-
- return scaling_mode[i].mode;
-}
-
-void
-nv50_output_create_resources(xf86OutputPtr output)
-{
- NV50OutputPrivatePtr nv_output = output->driver_private;
- ScrnInfoPtr pScrn = output->scrn;
- INT32 dithering_range[2] = { 0, 1 };
- int error, i;
-
- /*
- * Setup scaling mode property.
- */
- scaling_mode_atom = MakeAtom(SCALING_MODE_NAME, sizeof(SCALING_MODE_NAME) - 1, TRUE);
-
- error = RRConfigureOutputProperty(output->randr_output,
- scaling_mode_atom, TRUE, FALSE, FALSE,
- 0, NULL);
-
- if (error != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "RRConfigureOutputProperty error, %d\n", error);
- }
-
- char *existing_scale_name = NULL;
- for (i = 0; scaling_mode[i].name; i++)
- if (scaling_mode[i].mode == nv_output->output->scale_mode)
- existing_scale_name = scaling_mode[i].name;
-
- error = RRChangeOutputProperty(output->randr_output, scaling_mode_atom,
- XA_STRING, 8, PropModeReplace,
- strlen(existing_scale_name),
- existing_scale_name, FALSE, TRUE);
-
- if (error != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to set scaling mode, %d\n", error);
- }
-
- if (nv_output->output->type == OUTPUT_TMDS || nv_output->output->type == OUTPUT_LVDS) {
- /*
- * Setup dithering property.
- */
- dithering_atom = MakeAtom(DITHERING_MODE_NAME, sizeof(DITHERING_MODE_NAME) - 1, TRUE);
-
- error = RRConfigureOutputProperty(output->randr_output,
- dithering_atom, TRUE, TRUE, FALSE,
- 2, dithering_range);
-
- if (error != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "RRConfigureOutputProperty error, %d\n", error);
- }
-
- error = RRChangeOutputProperty(output->randr_output, dithering_atom,
- XA_INTEGER, 32, PropModeReplace, 1, &nv_output->output->dithering,
- FALSE, TRUE);
-
- if (error != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to set dithering mode, %d\n", error);
- }
- }
-}
-
-Bool
-nv50_output_set_property(xf86OutputPtr output, Atom property,
- RRPropertyValuePtr value)
-{
- NV50OutputPrivatePtr nv_output = output->driver_private;
-
- if (property == scaling_mode_atom) {
- int32_t ret;
- char *name = NULL;
-
- if (value->type != XA_STRING || value->format != 8)
- return FALSE;
-
- name = (char *) value->data;
-
- /* Match a string to a scaling mode */
- ret = nv_scaling_mode_lookup(name, value->size);
- if (ret == SCALE_INVALID)
- return FALSE;
-
- /* LVDS must always use gpu scaling. */
- if (ret == SCALE_PANEL && nv_output->output->type == OUTPUT_LVDS)
- return FALSE;
-
- nv_output->output->scale_mode = ret;
- if (nv_output->output->crtc) /* normally prepare sets all these things for the crtc. */
- nv_output->output->crtc->scale_mode = ret;
- return TRUE;
- } else if (property == dithering_atom) {
- if (value->type != XA_INTEGER || value->format != 32)
- return FALSE;
-
- int32_t val = *(int32_t *) value->data;
-
- if (val < 0 || val > 1)
- return FALSE;
-
- nv_output->output->dithering = val;
- if (nv_output->output->crtc) /* normally prepare sets all these things for the crtc. */
- nv_output->output->crtc->dithering = val;
- return TRUE;
- }
-
- return TRUE;
-}
-
-static const xf86OutputFuncsRec nv50_output_funcs = {
- .dpms = nv50_output_dpms,
- .save = NULL,
- .restore = NULL,
- .mode_valid = nv50_output_mode_valid,
- .mode_fixup = nv50_output_mode_fixup,
- .mode_set = nv50_output_mode_set,
- .detect = nv50_output_detect,
- .get_modes = nv50_output_get_modes,
- .destroy = nv50_output_destroy,
- .prepare = nv50_output_prepare,
- .commit = nv50_output_commit,
-#ifdef RANDR_GET_CRTC_INTERFACE
- .get_crtc = nv50_output_get_crtc,
-#endif /*RANDR_GET_CRTC_INTERFACE */
- .create_resources = nv50_output_create_resources,
- .set_property = nv50_output_set_property,
-};
-
-void
-nv50_output_create(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- xf86OutputPtr output;
- NV50OutputPrivatePtr nv_output;
- int i;
-
- /* this is a 1:1 hookup of the connectors. */
- for (i = 0; i < DCB_MAX_NUM_I2C_ENTRIES; i++) {
- if (!(pNv->connector[i]->outputs[0]))
- continue; /* An empty connector is not useful. */
-
- if (!(output = xf86OutputCreate(pScrn, &nv50_output_funcs, pNv->connector[i]->name)))
- return;
-
- if (!(nv_output = xnfcalloc(sizeof(NV50OutputPrivateRec), 1)))
- return;
-
- output->driver_private = nv_output;
-
- nv_output->output = pNv->connector[i]->outputs[0]; /* initially just wire up the first output available. */
-
- output->possible_crtcs = nv_output->output->allowed_crtc;
- output->possible_clones = 0;
-
- if (nv_output->output->type == OUTPUT_TMDS || nv_output->output->type == OUTPUT_LVDS) {
- output->doubleScanAllowed = false;
- output->interlaceAllowed = false;
- } else {
- output->doubleScanAllowed = true;
- output->interlaceAllowed = true;
- }
- }
-}
diff --git a/src/nv50_randr.h b/src/nv50_randr.h
deleted file mode 100644
index d71087a..0000000
--- a/src/nv50_randr.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2008 Maarten Maathuis
- *
- * 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 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.
- */
-
-#ifndef __NV50_RANDR_H_
-#define __NV50_RANDR_H_
-
-#include "nouveau_modeset.h"
-#include "nouveau_crtc.h"
-#include "nouveau_output.h"
-#include "nouveau_connector.h"
-
-typedef struct NV50CrtcPrivate {
- int head;
- nouveauCrtcPtr crtc;
- struct nouveau_bo *shadow;
-} NV50CrtcPrivateRec, *NV50CrtcPrivatePtr;
-
-typedef struct NV50OutputPrivate {
- nouveauOutputPtr output;
-} NV50OutputPrivateRec, *NV50OutputPrivatePtr;
-
-#endif /* __NV50_RANDR_H_ */
diff --git a/src/nv50_sor.c b/src/nv50_sor.c
deleted file mode 100644
index ea18e77..0000000
--- a/src/nv50_sor.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright 2007 NVIDIA, Corporation
- * Copyright 2008 Maarten Maathuis
- *
- * 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 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.
- */
-
-#include "nouveau_modeset.h"
-#include "nouveau_crtc.h"
-#include "nouveau_output.h"
-#include "nouveau_connector.h"
-
-static int
-NV50SorModeValid(nouveauOutputPtr output, DisplayModePtr mode)
-{
- int high_limit;
-
- if (output->type == OUTPUT_LVDS)
- high_limit = 400000;
- else
- high_limit = 165000; /* no dual link dvi until we figure it out completely */
-
- if (mode->Clock > high_limit)
- return MODE_CLOCK_HIGH;
-
- if (mode->Clock < 25000)
- return MODE_CLOCK_LOW;
-
- if (mode->Flags & V_DBLSCAN)
- return MODE_NO_DBLESCAN;
-
- if (mode->HDisplay > output->native_mode->HDisplay || mode->VDisplay > output->native_mode->VDisplay)
- return MODE_PANEL;
-
- return MODE_OK;
-}
-
-static void
-NV50SorModeSet(nouveauOutputPtr output, DisplayModePtr mode)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50SorModeSet is called.\n");
-
- const int sorOff = 0x40 * NV50OrOffset(output);
- uint32_t mode_ctl = NV50_SOR_MODE_CTRL_OFF;
-
- if (!mode) {
- /* Disconnect the SOR */
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disconnecting SOR.\n");
- NV50DisplayCommand(pScrn, NV50_SOR0_MODE_CTRL + sorOff, mode_ctl);
- return;
- }
-
- /* Anyone know a more appropriate name? */
- DisplayModePtr desired_mode = output->crtc->use_native_mode ? output->crtc->native_mode : mode;
-
- if (output->type == OUTPUT_LVDS) {
- mode_ctl |= NV50_SOR_MODE_CTRL_LVDS;
- } else {
- mode_ctl |= NV50_SOR_MODE_CTRL_TMDS;
- if (desired_mode->Clock > 165000)
- mode_ctl |= NV50_SOR_MODE_CTRL_TMDS_DUAL_LINK;
- }
-
- if (output->crtc) {
- if (output->crtc->index == 1)
- mode_ctl |= NV50_SOR_MODE_CTRL_CRTC1;
- else
- mode_ctl |= NV50_SOR_MODE_CTRL_CRTC0;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Warning, output has no crtc.\n");
- return;
- }
-
- if (desired_mode->Flags & V_NHSYNC)
- mode_ctl |= NV50_SOR_MODE_CTRL_NHSYNC;
-
- if (desired_mode->Flags & V_NVSYNC)
- mode_ctl |= NV50_SOR_MODE_CTRL_NVSYNC;
-
- // This wouldn't be necessary, but the server is stupid and calls
- // nv50_sor_dpms after the output is disconnected, even though the hardware
- // turns it off automatically.
- output->SetPowerMode(output, DPMSModeOn);
-
- NV50DisplayCommand(pScrn, NV50_SOR0_MODE_CTRL + sorOff, mode_ctl);
-
- output->crtc->SetScaleMode(output->crtc, output->scale_mode);
-}
-
-static void
-NV50SorSetClockMode(nouveauOutputPtr output, int clock)
-{
- ScrnInfoPtr pScrn = output->scrn;
- NVPtr pNv = NVPTR(pScrn);
- const int limit = output->dcb->type == OUTPUT_LVDS ? 112000 : 165000;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "NV50SorSetClockMode is called.\n");
-
-#if 0
- ret = nouveau_bios_run_display_table(pScrn, output->dcb, clock);
- if (ret)
- NV_WARN(pScrn, "failed to run output script, may hang!\n");
-#else
- /* just to keep the original behaviour until we can reliably run
- * the output scripts...
- */
- if (output->dcb->type == OUTPUT_LVDS)
- return;
-#endif
-
- /* 0x70000 was a late addition to nv, mentioned as fixing tmds
- * initialisation on certain gpu's. */
- /* I presume it's some kind of clock setting, but what precisely i
- * do not know.
- */
- NVWrite(pNv, NV50_SOR0_CLK_CTRL2 + NV50OrOffset(output) * 0x800,
- 0x70000 | ((clock > limit) ? 0x101 : 0));
-}
-
-static int
-NV50SorSense(nouveauOutputPtr output)
-{
- switch (output->type) {
- case OUTPUT_TMDS:
- case OUTPUT_LVDS:
- return output->type;
- default:
- return OUTPUT_NONE;
- }
-}
-
-static void
-NV50SorSetPowerMode(nouveauOutputPtr output, int mode)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50SorSetPowerMode is called with mode %d.\n", mode);
-
- NVPtr pNv = NVPTR(pScrn);
- uint32_t tmp;
-
- while ((NVRead(pNv, NV50_SOR0_DPMS_CTRL + NV50OrOffset(output) * 0x800) & NV50_SOR_DPMS_CTRL_PENDING));
-
- tmp = NVRead(pNv, NV50_SOR0_DPMS_CTRL + NV50OrOffset(output) * 0x800);
- tmp |= NV50_SOR_DPMS_CTRL_PENDING;
-
- if (mode == DPMSModeOn)
- tmp |= NV50_SOR_DPMS_CTRL_MODE_ON;
- else
- tmp &= ~NV50_SOR_DPMS_CTRL_MODE_ON;
-
- NVWrite(pNv, NV50_SOR0_DPMS_CTRL + NV50OrOffset(output) * 0x800, tmp);
- while ((NVRead(pNv, NV50_SOR0_DPMS_STATE + NV50OrOffset(output) * 0x800) & NV50_SOR_DPMS_STATE_WAIT));
-}
-
-static Bool
-NV50SorDetect(nouveauOutputPtr output)
-{
- if (output->type == OUTPUT_LVDS) /* assume connected */
- return TRUE;
-
- return FALSE;
-}
-
-static nouveauCrtcPtr
-NV50SorGetCurrentCrtc(nouveauOutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV50SorGetCurrentCrtc is called.\n");
-
- NVPtr pNv = NVPTR(pScrn);
- uint32_t mode_ctrl = NVRead(pNv, NV50_SOR0_MODE_CTRL_VAL + NV50OrOffset(output) * 0x8);
-
- /*
- * MODE_CTRL values only contain one instance of crtc0 and of crtc1.
- * This is because we disconnect outputs upon modeset.
- * Crtc might be off even if we get a positive return.
- * But we are still associated with that crtc.
- */
- if (mode_ctrl & NV50_SOR_MODE_CTRL_CRTC0)
- return pNv->crtc[0];
- else if (mode_ctrl & NV50_SOR_MODE_CTRL_CRTC1)
- return pNv->crtc[1];
-
- return NULL;
-}
-
-void
-NV50SorSetFunctionPointers(nouveauOutputPtr output)
-{
- output->ModeValid = NV50SorModeValid;
- output->ModeSet = NV50SorModeSet;
- output->SetClockMode = NV50SorSetClockMode;
- output->Sense = NV50SorSense;
- output->Detect = NV50SorDetect;
- output->SetPowerMode = NV50SorSetPowerMode;
- output->GetCurrentCrtc = NV50SorGetCurrentCrtc;
-}
-
diff --git a/src/nv50reg.h b/src/nv50reg.h
deleted file mode 100644
index 4e21220..0000000
--- a/src/nv50reg.h
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright 2007 Maarten Maathuis
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __NV50REG_H_
-#define __NV50REG_H_
-
-/* Bit 28 also does something, although i don't know what. */
-#define NV50_CONNECTOR_HOTPLUG_INTR 0x0000E050
- #define NV50_CONNECTOR_HOTPLUG_INTR_PLUG_I2C0 (1 << 0)
- #define NV50_CONNECTOR_HOTPLUG_INTR_PLUG_I2C1 (2 << 0)
- #define NV50_CONNECTOR_HOTPLUG_INTR_UNPLUG_I2C0 (1 << 16)
- #define NV50_CONNECTOR_HOTPLUG_INTR_UNPLUG_I2C1 (2 << 16)
-
-/* Writing 0x7FFF7FFF seems to be the way to acknowledge an interrupt. */
-/* There is also bit 7 and bit 23, but i also don't know what they do. */
-#define NV50_CONNECTOR_HOTPLUG_CTRL 0x0000E054
- #define NV50_CONNECTOR_HOTPLUG_CTRL_PLUG_I2C0 (1 << 0)
- #define NV50_CONNECTOR_HOTPLUG_CTRL_PLUG_I2C1 (2 << 0)
- #define NV50_CONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C0 (1 << 16)
- #define NV50_CONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C1 (2 << 16)
-
-/* This works for DVI->VGA adapters as well, providing the adapter supports it. */
-/* It's unknown if bits exist for i2c port > 1. */
-/* Renamed to avoid confusion with other instances of CONNECTED. */
-#define NV50_CONNECTOR_HOTPLUG_STATE 0x0000E104
- #define NV50_CONNECTOR_HOTPLUG_STATE_I2C0_DETECT_PIN (1 << 2)
- #define NV50_CONNECTOR_HOTPLUG_STATE_I2C1_DETECT_PIN (1 << 6)
-
-#define NV50_PCONNECTOR_I2C_PORT_0 0x0000e138
-#define NV50_PCONNECTOR_I2C_PORT_1 0x0000e150
-#define NV50_PCONNECTOR_I2C_PORT_2 0x0000e168
-#define NV50_PCONNECTOR_I2C_PORT_3 0x0000e180
-#define NV50_PCONNECTOR_I2C_PORT_4 0x0000e240
-#define NV50_PCONNECTOR_I2C_PORT_5 0x0000e258
-
-/* 0x00610024 is the state register to read, all it's bits also exist in 0x0061002C in the form of interrupt switches. */
-#define NV50_DISPLAY_SUPERVISOR 0x00610024
- #define NV50_DISPLAY_SUPERVISOR_CRTC0 (1 << 2)
- #define NV50_DISPLAY_SUPERVISOR_CRTC1 (2 << 2)
- #define NV50_DISPLAY_SUPERVISOR_CRTCn (3 << 2)
- #define NV50_DISPLAY_SUPERVISOR_CLK_MASK (7 << 4)
- #define NV50_DISPLAY_SUPERVISOR_CLK_UPDATE (2 << 4)
-
-/* Two vblank interrupts arrive per blanking period, it could be rise and fall, i do not know. */
-/* If a vblank interrupt arrives, check NV50_DISPLAY_SUPERVISOR, it will show for which crtc (or both) it is. */
-/* Note that one crtc bit will always show, maybe it's updated when a vblank occurs? */
-/* Once modesetting goes into the kernel, we can ditch NV50CheckWriteVClk() and do it with interrupts. */
-/* Up until then, realise that most interrupts are not handled properly yet (and will stall your machine). */
-/* Bit 8 and 9 also exist for sure, but their purpose is unknown. */
-#define NV50_DISPLAY_SUPERVISOR_INTR 0x0061002C
- #define NV50_DISPLAY_INTR_VBLANK_CRTC0 (1 << 2)
- #define NV50_DISPLAY_INTR_VBLANK_CRTC1 (1 << 3)
- #define NV50_DISPLAY_INTR_UNK1 (1 << 4)
- #define NV50_DISPLAY_INTR_CLK_UPDATE (2 << 4)
- #define NV50_DISPLAY_INTR_UNK4 (4 << 4)
-
-#define NV50_DISPLAY_UNK30_CTRL 0x00610030
- #define NV50_DISPLAY_UNK30_CTRL_UPDATE_VCLK0 (1 << 9)
- #define NV50_DISPLAY_UNK30_CTRL_UPDATE_VCLK1 (1 << 10)
- #define NV50_DISPLAY_UNK30_CTRL_PENDING (1 << 31)
-
-#define NV50_DISPLAY_UNK50_CTRL 0x00610050
- #define NV50_DISPLAY_UNK50_CTRL_CRTC0_ACTIVE (2 << 0)
- #define NV50_DISPLAY_UNK50_CTRL_CRTC0_MASK (3 << 0)
- #define NV50_DISPLAY_UNK50_CTRL_CRTC1_ACTIVE (2 << 8)
- #define NV50_DISPLAY_UNK50_CTRL_CRTC1_MASK (3 << 8)
-
-/* I really don't know what this does, except that it's only revelant at start. */
-#define NV50_DISPLAY_UNK200_CTRL 0x00610200
-
-/* bit3 always activates itself, and bit 4 is some kind of switch. */
-#define NV50_CRTC0_CURSOR_CTRL2 0x00610270
- #define NV50_CRTC_CURSOR_CTRL2_ON (1 << 0)
- #define NV50_CRTC_CURSOR_CTRL2_OFF (0 << 0)
- #define NV50_CRTC_CURSOR_CTRL2_STATUS_MASK (3 << 16)
- #define NV50_CRTC_CURSOR_CTRL2_STATUS_ACTIVE (1 << 16)
-#define NV50_CRTC1_CURSOR_CTRL2 0x00610280
-
-#define NV50_DISPLAY_CTRL_STATE 0x00610300
- #define NV50_DISPLAY_CTRL_STATE_DISABLE (0 << 0)
- #define NV50_DISPLAY_CTRL_STATE_ENABLE (1 << 0)
- #define NV50_DISPLAY_CTRL_STATE_PENDING (1 << 31)
-#define NV50_DISPLAY_CTRL_VAL 0x00610304
-
-#define NV50_DISPLAY_UNK_380 0x00610380
-/* Clamped to 256 MiB */
-#define NV50_DISPLAY_RAM_AMOUNT 0x00610384
-#define NV50_DISPLAY_UNK_388 0x00610388
-#define NV50_DISPLAY_UNK_38C 0x0061038C
-
-/* The registers in this range are normally accessed through display commands, with an offset of 0x540 for crtc1. */
-/* They also seem duplicated into the next register as well. */
-#define NV50_CRTC0_CLUT_MODE_VAL 0x00610A24
-#define NV50_CRTC0_SCALE_CTRL_VAL 0x00610A50
-#define NV50_CRTC0_CURSOR_CTRL_VAL 0x00610A58
-#define NV50_CRTC0_DEPTH_VAL 0x00610AC8
-#define NV50_CRTC0_CLOCK_VAL 0x00610AD0
-#define NV50_CRTC0_COLOR_CTRL_VAL 0x00610AE0
-#define NV50_CRTC0_SYNC_START_TO_BLANK_END_VAL 0x00610AE8
-#define NV50_CRTC0_MODE_UNK1_VAL 0x00610AF0
-#define NV50_CRTC0_DISPLAY_TOTAL_VAL 0x00610AF8
-#define NV50_CRTC0_SYNC_DURATION_VAL 0x00610B00
-/* For some reason this displayed the maximum framebuffer size for crtc0/dfp. */
-/* It was correct for crtc1/afp. */
-#define NV50_CRTC0_FB_SIZE_VAL 0x00610B18
-#define NV50_CRTC0_FB_PITCH_VAL 0x00610B20
-#define NV50_CRTC0_FB_POS_VAL 0x00610B28
-#define NV50_CRTC0_SCALE_CENTER_OFFSET_VAL 0x00610B38
-#define NV50_CRTC0_REAL_RES_VAL 0x00610B40
-/* I can't be 100% about the order of these two, as setting them differently locks up the card. */
-#define NV50_CRTC0_SCALE_RES1_VAL 0x00610B48
-#define NV50_CRTC0_SCALE_RES2_VAL 0x00610B50
-
-/* Some registers are based on extrapolation. */
-#define NV50_DAC0_MODE_CTRL_VAL 0x00610B58
-#define NV50_DAC1_MODE_CTRL_VAL 0x00610B60
-#define NV50_DAC2_MODE_CTRL_VAL 0x00610B68
-#define NV50_SOR0_MODE_CTRL_VAL 0x00610B70
-#define NV50_SOR1_MODE_CTRL_VAL 0x00610B78
-#define NV50_SOR2_MODE_CTRL_VAL 0x00610B80
-
-#define NV50_DAC0_MODE_CTRL2_VAL 0x00610BDC
-#define NV50_DAC1_MODE_CTRL2_VAL 0x00610BE4
-#define NV50_DAC2_MODE_CTRL2_VAL 0x00610BEC
-
-#define NV50_CRTC1_CLUT_MODE_VAL 0x00610F64
-#define NV50_CRTC1_SCALE_CTRL_VAL 0x00610F90
-#define NV50_CRTC1_CURSOR_CTRL_VAL 0x00610F98
-#define NV50_CRTC1_DEPTH_VAL 0x00611008
-#define NV50_CRTC1_CLOCK_VAL 0x00611010
-#define NV50_CRTC1_COLOR_CTRL_VAL 0x00611020
-#define NV50_CRTC1_SYNC_START_TO_BLANK_END_VAL 0x00611028
-#define NV50_CRTC1_MODE_UNK1_VAL 0x00611030
-#define NV50_CRTC1_DISPLAY_TOTAL_VAL 0x00611038
-#define NV50_CRTC1_SYNC_DURATION_VAL 0x00611040
-#define NV50_CRTC1_FB_SIZE_VAL 0x00611058
-#define NV50_CRTC1_FB_PITCH_VAL 0x00611060
-#define NV50_CRTC1_FB_POS_VAL 0x00611068
-#define NV50_CRTC1_SCALE_CENTER_OFFSET_VAL 0x00611078
-#define NV50_CRTC1_REAL_RES_VAL 0x00611080
-/* I can't be 100% about the order of these two, as setting them differently locks up the card. */
-#define NV50_CRTC1_SCALE_RES1_VAL 0x00611088
-#define NV50_CRTC1_SCALE_RES2_VAL 0x00611090
-
-/* These CLK_CTRL names are a bit of a guess, i do have my reasons though. */
-/* These connected indicators exist for crtc, dac and sor. */
-#define NV50_CRTC0_CLK_CTRL1 0x00614100
- #define NV50_CRTC_CLK_CTRL1_CONNECTED (3 << 9)
-/* These are probably redrirected from 0x4000 range (very similar regs to nv40, maybe different order) */
-#define NV50_CRTC0_VPLL_A 0x00614104
-#define NV50_CRTC0_VPLL_B 0x00614108
-#define NV50_CRTC0_CLK_CTRL2 0x00614200
-
-/* These control some special modes, like dual link dvi, maybe they need another name? */
-#define NV50_DAC0_CLK_CTRL2 0x00614280
-#define NV50_SOR0_CLK_CTRL2 0x00614300
-
-#define NV50_CRTC1_CLK_CTRL1 0x00614900
-#define NV50_CRTC1_VPLL_A 0x00614904
-#define NV50_CRTC1_VPLL_B 0x00614908
-#define NV50_CRTC1_CLK_CTRL2 0x00614A00
-
-#define NV50_DAC1_CLK_CTRL2 0x00614A80
-#define NV50_SOR1_CLK_CTRL2 0x00614B00
-
-#define NV50_DAC2_CLK_CTRL2 0x00615280
-#define NV50_SOR2_CLK_CTRL2 0x00615300
-
-#define NV50_DAC0_DPMS_CTRL 0x0061A004
- #define NV50_DAC_DPMS_CTRL_HSYNC_OFF (1 << 0)
- #define NV50_DAC_DPMS_CTRL_VSYNC_OFF (1 << 2)
- #define NV50_DAC_DPMS_CTRL_BLANKED (1 << 4)
- #define NV50_DAC_DPMS_CTRL_OFF (1 << 6)
- /* Some cards also use bit 22, why exactly is unknown. */
- /* It seems that 1, 4 and 5 are present at bit0. bit4. bit16, bit20. */
- /* No idea what the symmetry means precisely. */
- #define NV50_DAC_DPMS_CTRL_DEFAULT_STATE (21 << 16)
- #define NV50_DAC_DPMS_CTRL_PENDING (1 << 31)
-#define NV50_DAC0_LOAD_CTRL 0x0061A00C
- #define NV50_DAC_LOAD_CTRL_ACTIVE (1 << 20)
- #define NV50_DAC_LOAD_CTRL_PRESENT (7 << 27)
- /* this a bit of a guess, as load detect is very fast */
- #define NV50_DAC_LOAD_CTRL_DONE (1 << 31)
-/* These connected indicators exist for crtc, dac and sor. */
-/* The upper 4 bits seem to be some kind indicator. */
-/* The purpose of bit 1 is unknown, maybe some kind of reset? */
-#define NV50_DAC0_CLK_CTRL1 0x0061A010
- #define NV50_DAC_CLK_CTRL1_CONNECTED (3 << 9)
-#define NV50_DAC1_DPMS_CTRL 0x0061A804
-#define NV50_DAC1_LOAD_CTRL 0x0061A80C
-#define NV50_DAC1_CLK_CTRL1 0x0061A810
-#define NV50_DAC2_DPMS_CTRL 0x0061B004
-#define NV50_DAC2_LOAD_CTRL 0x0061B00C
-#define NV50_DAC2_CLK_CTRL1 0x0061B010
-
-/* both SOR_DPMS and DAC_DPMS have a bit28, whose purpose is unknown atm. */
-#define NV50_SOR0_DPMS_CTRL 0x0061C004
- #define NV50_SOR_DPMS_CTRL_MODE_ON (1 << 0)
- #define NV50_SOR_DPMS_CTRL_PENDING (1 << 31)
-/* These connected indicators exist for crtc, dac and sor. */
-/* I don't know what bit27 does, it doesn't seem extremely important. */
-#define NV50_SOR0_CLK_CTRL1 0x0061C008
- #define NV50_SOR_CLK_CTRL1_CONNECTED (3 << 9)
-/* Seems to be a default state, nothing that can RE'd in great detail. */
-#define NV50_SOR0_UNK00C 0x0061C00C
-#define NV50_SOR0_UNK010 0x0061C010
-#define NV50_SOR0_UNK014 0x0061C014
-#define NV50_SOR0_UNK018 0x0061C018
-
-#define NV50_SOR0_DPMS_STATE 0x0061C030
- #define NV50_SOR_DPMS_STATE_ACTIVE (3 << 16) /* this does not show if DAC is active */
- #define NV50_SOR_DPMS_STATE_BLANKED (8 << 16)
- #define NV50_SOR_DPMS_STATE_WAIT (1 << 28)
-
-#define NV50_SOR1_DPMS_CTRL 0x0061C804
-#define NV50_SOR1_CLK_CTRL1 0x0061C808
-/* Seems to be a default state, nothing that can RE'd in any great detail. */
-#define NV50_SOR1_UNK00C 0x0061C80C
-#define NV50_SOR1_UNK010 0x0061C810
-#define NV50_SOR1_UNK014 0x0061C814
-#define NV50_SOR1_UNK018 0x0061C818
-
-#define NV50_SOR1_DPMS_STATE 0x0061C830
-
-#define NV50_SOR2_DPMS_CTRL 0x0061D004
-#define NV50_SOR2_CLK_CTRL1 0x0061D008
-/* Seems to be a default state, nothing that can RE'd in any great detail. */
-#define NV50_SOR2_UNK00C 0x0061D00C
-#define NV50_SOR2_UNK010 0x0061D010
-#define NV50_SOR2_UNK014 0x0061D014
-#define NV50_SOR2_UNK018 0x0061D018
-
-#define NV50_SOR2_DPMS_STATE 0x0061D030
-
-/* A few things seem to exist in the 0x0064XXXX range, but not much. */
-/* Each of these corresponds to a range in 0x006102XX. */
-/* The blob writes zero to these regs. */
-/* 0x00610200-0x0061020C, 0x00610200 seems special from all the rest. */
-#define NV50_UNK_640000 0x00640000
-/* 0x00610210-0x0061021C */
-#define NV50_UNK_641000 0x00641000
-/* 0x00610220-0x0061022C */
-/* Seems tv-out related somehow, the other two show up always. */
-#define NV50_UNK_642000 0x00642000
-/* 0x00610230-0x0061023C and 0x00610240-0x0061024C seem to be similar. */
-/* I think the correlation goes for all 0x0064X000, up to and including 6. */
-
-/* Write 0 to process the new position, seem to be write only registers. */
-#define NV50_CRTC0_CURSOR_POS_CTRL 0x00647080
-#define NV50_CRTC0_CURSOR_POS 0x00647084
-#define NV50_CRTC1_CURSOR_POS_CTRL 0x00648080
-#define NV50_CRTC1_CURSOR_POS 0x00648084
-
-/* These things below are so called "commands" */
-#define NV50_UPDATE_DISPLAY 0x80
-#define NV50_UNK84 0x84
-#define NV50_UNK88 0x88
-
-#define NV50_DAC0_MODE_CTRL 0x400
- #define NV50_DAC_MODE_CTRL_OFF (0 << 0)
- #define NV50_DAC_MODE_CTRL_CRTC0 (1 << 0)
- #define NV50_DAC_MODE_CTRL_CRTC1 (1 << 1)
-#define NV50_DAC1_MODE_CTRL 0x480
-#define NV50_DAC2_MODE_CTRL 0x500
-
-#define NV50_DAC0_MODE_CTRL2 0x404
- #define NV50_DAC_MODE_CTRL2_NHSYNC (1 << 0)
- #define NV50_DAC_MODE_CTRL2_NVSYNC (2 << 0)
-#define NV50_DAC1_MODE_CTRL2 0x484
-#define NV50_DAC2_MODE_CTRL2 0x504
-
-#define NV50_SOR0_MODE_CTRL 0x600
- #define NV50_SOR_MODE_CTRL_OFF (0 << 0)
- #define NV50_SOR_MODE_CTRL_CRTC0 (1 << 0)
- #define NV50_SOR_MODE_CTRL_CRTC1 (1 << 1)
- #define NV50_SOR_MODE_CTRL_LVDS (0 << 8)
- #define NV50_SOR_MODE_CTRL_TMDS (1 << 8)
- #define NV50_SOR_MODE_CTRL_TMDS_DUAL_LINK (4 << 8)
- #define NV50_SOR_MODE_CTRL_NHSYNC (1 << 12)
- #define NV50_SOR_MODE_CTRL_NVSYNC (2 << 12)
-#define NV50_SOR1_MODE_CTRL 0x640
-#define NV50_SOR2_MODE_CTRL 0x680
-
-#define NV50_CRTC0_UNK800 0x800
-#define NV50_CRTC0_CLOCK 0x804
-#define NV50_CRTC0_INTERLACE 0x808
-
-/* 0x810 is a reasonable guess, nothing more. */
-#define NV50_CRTC0_DISPLAY_START 0x810
-#define NV50_CRTC0_DISPLAY_TOTAL 0x814
-#define NV50_CRTC0_SYNC_DURATION 0x818
-#define NV50_CRTC0_SYNC_START_TO_BLANK_END 0x81C
-#define NV50_CRTC0_MODE_UNK1 0x820
-#define NV50_CRTC0_MODE_UNK2 0x824
-
-#define NV50_CRTC0_UNK82C 0x82C
-
-/* You can't have a palette in 8 bit mode (=OFF) */
-#define NV50_CRTC0_CLUT_MODE 0x840
- #define NV50_CRTC0_CLUT_MODE_BLANK 0x00000000
- #define NV50_CRTC0_CLUT_MODE_OFF 0x80000000
- #define NV50_CRTC0_CLUT_MODE_ON 0xC0000000
-#define NV50_CRTC0_CLUT_OFFSET 0x844
-
-/* Anyone know what part of the chip is triggered here precisely? */
-#define NV84_CRTC0_BLANK_UNK1 0x85C
- #define NV84_CRTC0_BLANK_UNK1_BLANK 0x0
- #define NV84_CRTC0_BLANK_UNK1_UNBLANK 0x1
-
-#define NV50_CRTC0_FB_OFFSET 0x860
-
-#define NV50_CRTC0_FB_SIZE 0x868
-#define NV50_CRTC0_FB_PITCH 0x86C
-
-#define NV50_CRTC0_DEPTH 0x870
- #define NV50_CRTC0_DEPTH_8BPP 0x1E00
- #define NV50_CRTC0_DEPTH_15BPP 0xE900
- #define NV50_CRTC0_DEPTH_16BPP 0xE800
- #define NV50_CRTC0_DEPTH_24BPP 0xCF00
-
-/* I'm openminded to better interpretations. */
-/* This is an educated guess. */
-/* NV50 has RAMDAC and TMDS offchip, so it's unlikely to be that. */
-#define NV50_CRTC0_BLANK_CTRL 0x874
- #define NV50_CRTC0_BLANK_CTRL_BLANK 0x0
- #define NV50_CRTC0_BLANK_CTRL_UNBLANK 0x1
-
-#define NV50_CRTC0_CURSOR_CTRL 0x880
- #define NV50_CRTC0_CURSOR_CTRL_SHOW 0x85000000
- #define NV50_CRTC0_CURSOR_CTRL_HIDE 0x05000000
-
-#define NV50_CRTC0_CURSOR_OFFSET 0x884
-
-/* Anyone know what part of the chip is triggered here precisely? */
-#define NV84_CRTC0_BLANK_UNK2 0x89C
- #define NV84_CRTC0_BLANK_UNK2_BLANK 0x0
- #define NV84_CRTC0_BLANK_UNK2_UNBLANK 0x1
-
-#define NV50_CRTC0_DITHERING_CTRL 0x8A0
- #define NV50_CRTC0_DITHERING_CTRL_ON 0x11
- #define NV50_CRTC0_DITHERING_CTRL_OFF 0x0
-
-#define NV50_CRTC0_SCALE_CTRL 0x8A4
- #define NV50_CRTC0_SCALE_CTRL_SCALER_INACTIVE (0 << 0)
- /* It doesn't seem to be needed, hence i wonder what it does precisely. */
- #define NV50_CRTC0_SCALE_CTRL_SCALER_ACTIVE (9 << 0)
-#define NV50_CRTC0_COLOR_CTRL 0x8A8
- #define NV50_CRTC_COLOR_CTRL_MODE_COLOR (4 << 16)
-
-#define NV50_CRTC0_FB_POS 0x8C0
-#define NV50_CRTC0_REAL_RES 0x8C8
-
-/* Added a macro, because the signed stuff can cause you problems very quickly. */
-#define NV50_CRTC0_SCALE_CENTER_OFFSET 0x8D4
- #define NV50_CRTC_SCALE_CENTER_OFFSET_VAL(x, y) ((((unsigned)y << 16) & 0xFFFF0000) | (((unsigned)x) & 0x0000FFFF))
-/* Both of these are needed, otherwise nothing happens. */
-#define NV50_CRTC0_SCALE_RES1 0x8D8
-#define NV50_CRTC0_SCALE_RES2 0x8DC
-
-#define NV50_CRTC1_UNK800 0xC00
-#define NV50_CRTC1_CLOCK 0xC04
-#define NV50_CRTC1_INTERLACE 0xC08
-
-/* 0xC10 is a reasonable guess, nothing more. */
-#define NV50_CRTC1_DISPLAY_START 0xC10
-#define NV50_CRTC1_DISPLAY_TOTAL 0xC14
-#define NV50_CRTC1_SYNC_DURATION 0xC18
-#define NV50_CRTC1_SYNC_START_TO_BLANK_END 0xC1C
-#define NV50_CRTC1_MODE_UNK1 0xC20
-#define NV50_CRTC1_MODE_UNK2 0xC24
-
-#define NV50_CRTC1_CLUT_MODE 0xC40
- #define NV50_CRTC1_CLUT_MODE_BLANK 0x00000000
- #define NV50_CRTC1_CLUT_MODE_OFF 0x80000000
- #define NV50_CRTC1_CLUT_MODE_ON 0xC0000000
-#define NV50_CRTC1_CLUT_OFFSET 0xC44
-
-/* Anyone know what part of the chip is triggered here precisely? */
-#define NV84_CRTC1_BLANK_UNK1 0xC5C
- #define NV84_CRTC1_BLANK_UNK1_BLANK 0x0
- #define NV84_CRTC1_BLANK_UNK1_UNBLANK 0x1
-
-#define NV50_CRTC1_FB_OFFSET 0xC60
-
-#define NV50_CRTC1_FB_SIZE 0xC68
-#define NV50_CRTC1_FB_PITCH 0xC6C
-
-#define NV50_CRTC1_DEPTH 0xC70
- #define NV50_CRTC1_DEPTH_8BPP 0x1E00
- #define NV50_CRTC1_DEPTH_15BPP 0xE900
- #define NV50_CRTC1_DEPTH_16BPP 0xE800
- #define NV50_CRTC1_DEPTH_24BPP 0xCF00
-
-/* I'm openminded to better interpretations. */
-#define NV50_CRTC1_BLANK_CTRL 0xC74
- #define NV50_CRTC1_BLANK_CTRL_BLANK 0x0
- #define NV50_CRTC1_BLANK_CTRL_UNBLANK 0x1
-
-#define NV50_CRTC1_CURSOR_CTRL 0xC80
- #define NV50_CRTC1_CURSOR_CTRL_SHOW 0x85000000
- #define NV50_CRTC1_CURSOR_CTRL_HIDE 0x05000000
-
-#define NV50_CRTC1_CURSOR_OFFSET 0xC84
-
-/* Anyone know what part of the chip is triggered here precisely? */
-#define NV84_CRTC1_BLANK_UNK2 0xC9C
- #define NV84_CRTC1_BLANK_UNK2_BLANK 0x0
- #define NV84_CRTC1_BLANK_UNK2_UNBLANK 0x1
-
-#define NV50_CRTC1_DITHERING_CTRL 0xCA0
- #define NV50_CRTC1_DITHERING_CTRL_ON 0x11
- #define NV50_CRTC1_DITHERING_CTRL_OFF 0x0
-
-#define NV50_CRTC1_SCALE_CTRL 0xCA4
-#define NV50_CRTC1_COLOR_CTRL 0xCA8
-
-#define NV50_CRTC1_FB_POS 0xCC0
-#define NV50_CRTC1_REAL_RES 0xCC8
-
-#define NV50_CRTC1_SCALE_CENTER_OFFSET 0xCD4
-/* Both of these are needed, otherwise nothing happens. */
-#define NV50_CRTC1_SCALE_RES1 0xCD8
-#define NV50_CRTC1_SCALE_RES2 0xCDC
-
-/* misc stuff */
-#define NV50_I2C_START 0x7
-#define NV50_I2C_STOP 0x3
-
-#endif /* __NV50REG_H_ */
diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c
index 05fdeb9..4ddb89e 100644
--- a/src/nv_accel_common.c
+++ b/src/nv_accel_common.c
@@ -263,3 +263,3 @@ NVAccelInitImageBlit(ScrnInfoPtr pScrn)
- class = (pNv->WaitVSyncPossible) ? NV12_IMAGE_BLIT : NV04_IMAGE_BLIT;
+ class = (pNv->NVArch > 0x11) ? NV12_IMAGE_BLIT : NV04_IMAGE_BLIT;
@@ -285,3 +285,3 @@ NVAccelInitImageBlit(ScrnInfoPtr pScrn)
- if (pNv->WaitVSyncPossible) {
+ if (blit->grclass == NV12_IMAGE_BLIT) {
BEGIN_RING(chan, blit, 0x0120, 3);
diff --git a/src/nv_bios.c b/src/nv_bios.c
deleted file mode 100644
index 218bf7d..0000000
--- a/src/nv_bios.c
+++ /dev/null
@@ -1,4810 +0,0 @@
-/*
- * Copyright 2005-2006 Erik Waling
- * Copyright 2006 Stephane Marchesin
- * Copyright 2007-2009 Stuart Bennett
- *
- * 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 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.
- */
-
-#include "nv_include.h"
-
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-#define bswap_16 bswap16
-#define bswap_32 bswap32
-#else
-#include <byteswap.h>
-#endif
-
-/* these defines are made up */
-#define NV_CIO_CRE_44_HEADA 0x0
-#define NV_CIO_CRE_44_HEADB 0x3
-#define FEATURE_MOBILE 0x10 /* also FEATURE_QUADRO for BMP */
-#define LEGACY_I2C_CRT 0x80
-#define LEGACY_I2C_PANEL 0x81
-
-#define BIOSLOG(sip, fmt, arg...) NV_DEBUG(sip, fmt, ##arg)
-#define LOG_OLD_VALUE(x) //x
-
-#define BIOS_USLEEP(n) usleep(n)
-
-#define ROM16(x) le16_to_cpu(*(uint16_t *)&(x))
-#define ROM32(x) le32_to_cpu(*(uint32_t *)&(x))
-
-static int crtchead = 0;
-
-/* this will need remembering across a suspend */
-static uint32_t saved_nv_pfb_cfg0;
-
-typedef struct {
- bool execute;
- bool repeat;
-} init_exec_t;
-
-static inline uint16_t le16_to_cpu(const uint16_t x)
-{
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- return bswap_16(x);
-#else
- return x;
-#endif
-}
-
-static inline uint32_t le32_to_cpu(const uint32_t x)
-{
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- return bswap_32(x);
-#else
- return x;
-#endif
-}
-
-static bool nv_cksum(const uint8_t *data, unsigned int length)
-{
- /* there's a few checksums in the BIOS, so here's a generic checking function */
- int i;
- uint8_t sum = 0;
-
- for (i = 0; i < length; i++)
- sum += data[i];
-
- if (sum)
- return true;
-
- return false;
-}
-
-static int
-score_vbios(ScrnInfoPtr pScrn, const uint8_t *data, const bool writeable)
-{
- if (!(data[0] == 0x55 && data[1] == 0xAA)) {
- NV_TRACEWARN(pScrn, "... BIOS signature not found\n");
- return 0;
- }
-
- if (nv_cksum(data, data[2] * 512)) {
- NV_TRACEWARN(pScrn, "... BIOS checksum invalid\n");
- /* if a ro image is somewhat bad, it's probably all rubbish */
- return writeable ? 2 : 1;
- } else
- NV_TRACE(pScrn, "... appears to be valid\n");
-
- return 3;
-}
-
-static void load_vbios_prom(NVPtr pNv, uint8_t *data)
-{
- uint32_t pci_nv_20, save_pci_nv_20;
- int pcir_ptr;
- int i;
-
- if (pNv->Architecture >= NV_ARCH_50)
- pci_nv_20 = 0x88050;
- else
- pci_nv_20 = NV_PBUS_PCI_NV_20;
-
- /* enable ROM access */
- save_pci_nv_20 = nvReadMC(pNv, pci_nv_20);
- nvWriteMC(pNv, pci_nv_20,
- save_pci_nv_20 & ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED);
-
- /* bail if no rom signature */
- if (NV_RD08(pNv->REGS, NV_PROM_OFFSET) != 0x55 ||
- NV_RD08(pNv->REGS, NV_PROM_OFFSET + 1) != 0xaa)
- goto out;
-
- /* additional check (see note below) - read PCI record header */
- pcir_ptr = NV_RD08(pNv->REGS, NV_PROM_OFFSET + 0x18) |
- NV_RD08(pNv->REGS, NV_PROM_OFFSET + 0x19) << 8;
- if (NV_RD08(pNv->REGS, NV_PROM_OFFSET + pcir_ptr) != 'P' ||
- NV_RD08(pNv->REGS, NV_PROM_OFFSET + pcir_ptr + 1) != 'C' ||
- NV_RD08(pNv->REGS, NV_PROM_OFFSET + pcir_ptr + 2) != 'I' ||
- NV_RD08(pNv->REGS, NV_PROM_OFFSET + pcir_ptr + 3) != 'R')
- goto out;
-
- /* on some 6600GT/6800LE prom reads are messed up. nvclock alleges a
- * a good read may be obtained by waiting or re-reading (cargocult: 5x)
- * each byte. we'll hope pramin has something usable instead
- */
- for (i = 0; i < NV_PROM_SIZE; i++)
- data[i] = NV_RD08(pNv->REGS, NV_PROM_OFFSET + i);
-
-out:
- /* disable ROM access */
- nvWriteMC(pNv, pci_nv_20,
- save_pci_nv_20 | NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED);
-}
-
-static void load_vbios_pramin(NVPtr pNv, uint8_t *data)
-{
- uint32_t old_bar0_pramin = 0;
- int i;
-
- if (pNv->Architecture >= NV_ARCH_50) {
- uint32_t vbios_vram = (NV_RD32(pNv->REGS, 0x619f04) & ~0xff) << 8;
-
- if (!vbios_vram)
- vbios_vram = (NV_RD32(pNv->REGS, 0x1700) << 16) + 0xf0000;
-
- old_bar0_pramin = NV_RD32(pNv->REGS, 0x1700);
- NV_WR32(pNv->REGS, 0x1700, vbios_vram >> 16);
- }
-
- /* bail if no rom signature */
- if (NV_RD08(pNv->REGS, NV_PRAMIN_OFFSET) != 0x55 ||
- NV_RD08(pNv->REGS, NV_PRAMIN_OFFSET + 1) != 0xaa)
- goto out;
-
- for (i = 0; i < NV_PROM_SIZE; i++)
- data[i] = NV_RD08(pNv->REGS, NV_PRAMIN_OFFSET + i);
-
-out:
- if (pNv->Architecture >= NV_ARCH_50)
- NV_WR32(pNv->REGS, 0x1700, old_bar0_pramin);
-}
-
-static void load_vbios_pci(NVPtr pNv, uint8_t *data)
-{
- pci_device_read_rom(pNv->PciInfo, data);
-}
-
-struct methods {
- const char desc[8];
- void (*loadbios)(NVPtr, uint8_t *);
- const bool rw;
- int score;
-};
-
-static struct methods nv04_methods[] = {
- { "PROM", load_vbios_prom, false },
- { "PRAMIN", load_vbios_pramin, true },
- { "PCI ROM", load_vbios_pci, true },
- { }
-};
-
-static struct methods nv50_methods[] = {
- { "PRAMIN", load_vbios_pramin, true },
- { "PROM", load_vbios_prom, false },
- { "PCI ROM", load_vbios_pci, true },
- { }
-};
-
-static bool NVShadowVBIOS(ScrnInfoPtr pScrn, uint8_t *data)
-{
- NVPtr pNv = NVPTR(pScrn);
- struct methods *methods, *method;
- int testscore = 3;
-
- if (pNv->Architecture < NV_ARCH_50)
- methods = nv04_methods;
- else
- methods = nv50_methods;
-
- method = methods;
- while (method->loadbios) {
- NV_TRACE(pScrn, "Attempting to load BIOS image from %s\n",
- method->desc);
- data[0] = data[1] = 0; /* avoid reuse of previous image */
- method->loadbios(pNv, data);
- method->score = score_vbios(pScrn, data, method->rw);
- if (method->score == testscore)
- return true;
- method++;
- }
-
- while (--testscore > 0) {
- method = methods;
- while (method->loadbios) {
- if (method->score == testscore) {
- NV_TRACE(pScrn, "Using BIOS image from %s\n",
- method->desc);
- method->loadbios(pNv, data);
- return true;
- }
- method++;
- }
- }
-
- NV_ERROR(pScrn, "No valid BIOS image found\n");
- return false;
-}
-
-typedef struct {
- char* name;
- uint8_t id;
- int length;
- int length_offset;
- int length_multiplier;
- bool (*handler)(ScrnInfoPtr pScrn, struct nvbios *, uint16_t, init_exec_t *);
-} init_tbl_entry_t;
-
-typedef struct {
- uint8_t id[2];
- uint16_t length;
- uint16_t offset;
-} bit_entry_t;
-
-static int parse_init_table(ScrnInfoPtr pScrn, struct nvbios *bios, unsigned int offset, init_exec_t *iexec);
-
-#define MACRO_INDEX_SIZE 2
-#define MACRO_SIZE 8
-#define CONDITION_SIZE 12
-#define IO_FLAG_CONDITION_SIZE 9
-#define IO_CONDITION_SIZE 5
-#define MEM_INIT_SIZE 66
-
-static void still_alive(void)
-{
-// sync();
-// BIOS_USLEEP(2000);
-}
-
-static uint32_t
-munge_reg(ScrnInfoPtr pScrn, uint32_t reg)
-{
- NVPtr pNv = NVPTR(pScrn);
-
- if (pNv->Architecture < NV_ARCH_50)
- return reg;
-
- if (reg & 0x40000000)
- reg += pNv->VBIOS.display.head * 0x800;
-
- reg &= ~(0x40000000);
- return reg;
-}
-
-static int valid_reg(ScrnInfoPtr pScrn, uint32_t reg)
-{
- NVPtr pNv = NVPTR(pScrn);
-
- /* C51 has misaligned regs on purpose. Marvellous */
- if (reg & 0x2 || (reg & 0x1 && pNv->VBIOS.pub.chip_version != 0x51)) {
- NV_ERROR(pScrn, "========== misaligned reg 0x%08X ==========\n",
- reg);
- return 0;
- }
- /* warn on C51 regs that haven't been verified accessible in mmiotracing */
- if (reg & 0x1 && pNv->VBIOS.pub.chip_version == 0x51 &&
- reg != 0x130d && reg != 0x1311 && reg != 0x60081d)
- NV_WARN(pScrn, "=== C51 misaligned reg 0x%08X not verified ===\n",
- reg);
-
- #define WITHIN(x,y,z) ((x>=y)&&(x<=y+z))
- if (WITHIN(reg,NV_PMC_OFFSET,NV_PMC_SIZE))
- return 1;
- if (WITHIN(reg,NV_PBUS_OFFSET,NV_PBUS_SIZE))
- return 1;
- if (WITHIN(reg,NV_PFIFO_OFFSET,NV_PFIFO_SIZE))
- return 1;
- /* maybe a little large, but it will do for the moment. */
- if (pNv->Architecture == NV_ARCH_50 && WITHIN(reg, 0x1000, 0xEFFF))
- return 1;
- if (pNv->VBIOS.pub.chip_version >= 0x30 && WITHIN(reg,0x4000,0x600))
- return 1;
- if (pNv->VBIOS.pub.chip_version >= 0x40 && WITHIN(reg,0xc000,0x48))
- return 1;
- if (pNv->VBIOS.pub.chip_version >= 0x17 && reg == 0x0000d204)
- return 1;
- if (pNv->VBIOS.pub.chip_version >= 0x40) {
- if (reg == 0x00011014 || reg == 0x00020328)
- return 1;
- if (WITHIN(reg,0x88000,NV_PBUS_SIZE)) /* new PBUS */
- return 1;
- }
- if (pNv->Architecture == NV_ARCH_50) {
- /* No clue what they do, but because they are outside normal
- * ranges we' better list them seperately. */
- if (reg == 0x00020018 || reg == 0x0002004C ||
- reg == 0x00020060 || reg == 0x00021218 ||
- reg == 0x0002130C || reg == 0x00089008 ||
- reg == 0x00089028)
- return 1;
- }
- if (WITHIN(reg,NV_PFB_OFFSET,NV_PFB_SIZE))
- return 1;
- if (WITHIN(reg,NV_PEXTDEV_OFFSET,NV_PEXTDEV_SIZE))
- return 1;
- if (WITHIN(reg,NV_PCRTC0_OFFSET,NV_PCRTC0_SIZE * 2))
- return 1;
- if (pNv->Architecture == NV_ARCH_50 &&
- WITHIN(reg, NV50_DISPLAY_OFFSET, NV50_DISPLAY_SIZE))
- return 1;
- if (WITHIN(reg,NV_PRAMDAC0_OFFSET,NV_PRAMDAC0_SIZE * 2))
- return 1;
- if (pNv->VBIOS.pub.chip_version >= 0x17 && reg == 0x0070fff0)
- return 1;
- if (pNv->VBIOS.pub.chip_version == 0x51 && WITHIN(reg,NV_PRAMIN_OFFSET,NV_PRAMIN_SIZE))
- return 1;
- #undef WITHIN
-
- NV_ERROR(pScrn, "========== unknown reg 0x%08X ==========\n", reg);
-
- return 0;
-}
-
-static bool valid_idx_port(ScrnInfoPtr pScrn, uint16_t port)
-{
- /* if adding more ports here, the read/write functions below will need
- * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is
- * used for the port in question
- */
- if (port == NV_CIO_CRX__COLOR)
- return true;
- if (port == NV_VIO_SRX)
- return true;
-
- NV_ERROR(pScrn, "========== unknown indexed io port 0x%04X ==========\n",
- port);
-
- return false;
-}
-
-static bool valid_port(ScrnInfoPtr pScrn, uint16_t port)
-{
- /* if adding more ports here, the read/write functions below will need
- * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is
- * used for the port in question
- */
- if (port == NV_VIO_VSE2)
- return true;
-
- NV_ERROR(pScrn, "========== unknown io port 0x%04X ==========\n", port);
-
- return false;
-}
-
-static uint32_t bios_rd32(ScrnInfoPtr pScrn, uint32_t reg)
-{
- NVPtr pNv = NVPTR(pScrn);
- uint32_t data;
-
- reg = munge_reg(pScrn, reg);
- if (!valid_reg(pScrn, reg))
- return 0;
-
- /* C51 sometimes uses regs with bit0 set in the address. For these
- * cases there should exist a translation in a BIOS table to an IO
- * port address which the BIOS uses for accessing the reg
- *
- * These only seem to appear for the power control regs to a flat panel,
- * and the GPIO regs at 0x60081*. In C51 mmio traces the normal regs
- * for 0x1308 and 0x1310 are used - hence the mask below. An S3
- * suspend-resume mmio trace from a C51 will be required to see if this
- * is true for the power microcode in 0x14.., or whether the direct IO
- * port access method is needed
- */
- if (reg & 0x1)
- reg &= ~0x1;
-
- data = NV_RD32(pNv->REGS, reg);
-
- BIOSLOG(pScrn, " Read: Reg: 0x%08X, Data: 0x%08X\n", reg, data);
-
- return data;
-}
-
-static void bios_wr32(ScrnInfoPtr pScrn, uint32_t reg, uint32_t data)
-{
- NVPtr pNv = NVPTR(pScrn);
-
- reg = munge_reg(pScrn, reg);
- if (!valid_reg(pScrn, reg))
- return;
-
- /* see note in bios_rd32 */
- if (reg & 0x1)
- reg &= 0xfffffffe;
-
- LOG_OLD_VALUE(bios_rd32(pScrn, reg));
- BIOSLOG(pScrn, " Write: Reg: 0x%08X, Data: 0x%08X\n", reg, data);
-
- if (pNv->VBIOS.execute) {
- still_alive();
- NV_WR32(pNv->REGS, reg, data);
- }
-}
-
-static uint8_t bios_idxprt_rd(ScrnInfoPtr pScrn, uint16_t port, uint8_t index)
-{
- NVPtr pNv = NVPTR(pScrn);
- uint8_t data;
-
- if (!valid_idx_port(pScrn, port))
- return 0;
-
- if (port == NV_VIO_SRX)
- data = NVReadVgaSeq(pNv, crtchead, index);
- else /* assume NV_CIO_CRX__COLOR */
- data = NVReadVgaCrtc(pNv, crtchead, index);
-
- BIOSLOG(pScrn, " Indexed IO read: Port: 0x%04X, Index: 0x%02X, Head: 0x%02X, Data: 0x%02X\n",
- port, index, crtchead, data);
-
- return data;
-}
-
-static void bios_idxprt_wr(ScrnInfoPtr pScrn, uint16_t port, uint8_t index, uint8_t data)
-{
- NVPtr pNv = NVPTR(pScrn);
-
- if (!valid_idx_port(pScrn, port))
- return;
-
- /* The current head is maintained in a file scope variable crtchead.
- * We trap changes to CR44 and update the head variable and hence the
- * register set written.
- * As CR44 only exists on CRTC0, we update crtchead to head0 in advance
- * of the write, and to head1 after the write
- */
- if (port == NV_CIO_CRX__COLOR && index == NV_CIO_CRE_44 && data != NV_CIO_CRE_44_HEADB)
- crtchead = 0;
-
- LOG_OLD_VALUE(bios_idxprt_rd(pScrn, port, index));
- BIOSLOG(pScrn, " Indexed IO write: Port: 0x%04X, Index: 0x%02X, Head: 0x%02X, Data: 0x%02X\n",
- port, index, crtchead, data);
-
- if (pNv->VBIOS.execute) {
- still_alive();
- if (port == NV_VIO_SRX)
- NVWriteVgaSeq(pNv, crtchead, index, data);
- else /* assume NV_CIO_CRX__COLOR */
- NVWriteVgaCrtc(pNv, crtchead, index, data);
- }
-
- if (port == NV_CIO_CRX__COLOR && index == NV_CIO_CRE_44 && data == NV_CIO_CRE_44_HEADB)
- crtchead = 1;
-}
-
-static uint8_t bios_port_rd(ScrnInfoPtr pScrn, uint16_t port)
-{
- NVPtr pNv = NVPTR(pScrn);
- uint8_t data;
-
- if (!valid_port(pScrn, port))
- return 0;
-
- data = NVReadPRMVIO(pNv, crtchead, NV_PRMVIO0_OFFSET + port);
-
- BIOSLOG(pScrn, " IO read: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n",
- port, crtchead, data);
-
- return data;
-}
-
-static void bios_port_wr(ScrnInfoPtr pScrn, uint16_t port, uint8_t data)
-{
- NVPtr pNv = NVPTR(pScrn);
-
- if (!valid_port(pScrn, port))
- return;
-
- LOG_OLD_VALUE(bios_port_rd(pScrn, port));
- BIOSLOG(pScrn, " IO write: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n",
- port, crtchead, data);
-
- if (pNv->VBIOS.execute) {
- still_alive();
- NVWritePRMVIO(pNv, crtchead, NV_PRMVIO0_OFFSET + port, data);
- }
-}
-
-static bool io_flag_condition_met(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, uint8_t cond)
-{
- /* The IO flag condition entry has 2 bytes for the CRTC port; 1 byte
- * for the CRTC index; 1 byte for the mask to apply to the value
- * retrieved from the CRTC; 1 byte for the shift right to apply to the
- * masked CRTC value; 2 bytes for the offset to the flag array, to
- * which the shifted value is added; 1 byte for the mask applied to the
- * value read from the flag array; and 1 byte for the value to compare
- * against the masked byte from the flag table.
- */
-
- uint16_t condptr = bios->io_flag_condition_tbl_ptr + cond * IO_FLAG_CONDITION_SIZE;
- uint16_t crtcport = ROM16(bios->data[condptr]);
- uint8_t crtcindex = bios->data[condptr + 2];
- uint8_t mask = bios->data[condptr + 3];
- uint8_t shift = bios->data[condptr + 4];
- uint16_t flagarray = ROM16(bios->data[condptr + 5]);
- uint8_t flagarraymask = bios->data[condptr + 7];
- uint8_t cmpval = bios->data[condptr + 8];
- uint8_t data;
-
- BIOSLOG(pScrn, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, Shift: 0x%02X, FlagArray: 0x%04X, FAMask: 0x%02X, Cmpval: 0x%02X\n",
- offset, crtcport, crtcindex, mask, shift, flagarray, flagarraymask, cmpval);
-
- data = bios_idxprt_rd(pScrn, crtcport, crtcindex);
-
- data = bios->data[flagarray + ((data & mask) >> shift)];
- data &= flagarraymask;
-
- BIOSLOG(pScrn, "0x%04X: Checking if 0x%02X equals 0x%02X\n", offset, data, cmpval);
-
- return (data == cmpval);
-}
-
-static bool bios_condition_met(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, uint8_t cond)
-{
- /* The condition table entry has 4 bytes for the address of the
- * register to check, 4 bytes for a mask to apply to the register and
- * 4 for a test comparison value
- */
-
- uint16_t condptr = bios->condition_tbl_ptr + cond * CONDITION_SIZE;
- uint32_t reg = ROM32(bios->data[condptr]);
- uint32_t mask = ROM32(bios->data[condptr + 4]);
- uint32_t cmpval = ROM32(bios->data[condptr + 8]);
- uint32_t data;
-
- BIOSLOG(pScrn, "0x%04X: Cond: 0x%02X, Reg: 0x%08X, Mask: 0x%08X\n",
- offset, cond, reg, mask);
-
- data = bios_rd32(pScrn, reg) & mask;
-
- BIOSLOG(pScrn, "0x%04X: Checking if 0x%08X equals 0x%08X\n",
- offset, data, cmpval);
-
- return (data == cmpval);
-}
-
-static bool io_condition_met(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, uint8_t cond)
-{
- /* The IO condition entry has 2 bytes for the IO port address; 1 byte
- * for the index to write to io_port; 1 byte for the mask to apply to
- * the byte read from io_port+1; and 1 byte for the value to compare
- * against the masked byte.
- */
-
- uint16_t condptr = bios->io_condition_tbl_ptr + cond * IO_CONDITION_SIZE;
- uint16_t io_port = ROM16(bios->data[condptr]);
- uint8_t port_index = bios->data[condptr + 2];
- uint8_t mask = bios->data[condptr + 3];
- uint8_t cmpval = bios->data[condptr + 4];
-
- uint8_t data = bios_idxprt_rd(pScrn, io_port, port_index) & mask;
-
- BIOSLOG(pScrn, "0x%04X: Checking if 0x%02X equals 0x%02X\n",
- offset, data, cmpval);
-
- return (data == cmpval);
-}
-
-static int setPLL(ScrnInfoPtr pScrn, struct nvbios *bios, uint32_t reg, uint32_t clk)
-{
- /* clk in kHz */
- struct pll_lims pll_lim;
- int ret;
- struct nouveau_pll_vals pllvals;
-
- /* high regs (such as in the mac g5 table) are not -= 4 */
- if ((ret = get_pll_limits(pScrn, reg > 0x405c ? reg : reg - 4, &pll_lim)))
- return ret;
-
- if (!(clk = nouveau_calc_pll_mnp(pScrn, &pll_lim, clk, &pllvals)))
- return -ERANGE;
-
- if (bios->execute) {
- still_alive();
- nouveau_hw_setpll(pScrn, reg, &pllvals);
- }
-
- return 0;
-}
-
-static int dcb_entry_idx_from_crtchead(ScrnInfoPtr pScrn)
-{
- /* for the results of this function to be correct, CR44 must have been
- * set (using bios_idxprt_wr to set crtchead), CR58 set for CR57 = 0,
- * and the DCB table parsed, before the script calling the function is
- * run. run_digital_op_script is example of how to do such setup
- */
-
- uint8_t dcb_entry = NVReadVgaCrtc5758(NVPTR(pScrn), crtchead, 0);
-
- if (dcb_entry > NVPTR(pScrn)->VBIOS.bdcb.dcb.entries) {
- NV_ERROR(pScrn, "CR58 doesn't have a valid DCB entry currently "
- "(%02X)\n", dcb_entry);
- dcb_entry = 0x7f; /* unused / invalid marker */
- }
-
- return dcb_entry;
-}
-
-static int init_dcb_i2c_entry(ScrnInfoPtr pScrn, struct nvbios *bios, int index);
-
-static int
-create_i2c_device(ScrnInfoPtr pScrn, struct nvbios *bios, int i2c_index, int address, I2CDevRec *i2cdev)
-{
- struct bios_parsed_dcb *bdcb = &bios->bdcb;
- int ret;
-
- if (i2c_index == 0xff) {
- /* note: dcb_entry_idx_from_crtchead needs pre-script set-up */
- int idx = dcb_entry_idx_from_crtchead(pScrn), shift = 0;
- int default_indices = bdcb->i2c_default_indices;
-
- if (idx != 0x7f && bdcb->dcb.entry[idx].i2c_upper_default)
- shift = 4;
-
- i2c_index = (default_indices >> shift) & 0xf;
- }
- if (i2c_index == 0x80) /* g80+ */
- i2c_index = bdcb->i2c_default_indices & 0xf;
-
- if ((ret = init_dcb_i2c_entry(pScrn, bios, i2c_index)))
- return ret;
-
- memset(i2cdev, 0, sizeof(I2CDevRec));
- i2cdev->DevName = "init script device";
- i2cdev->pI2CBus = bdcb->dcb.i2c[i2c_index].chan;
- i2cdev->SlaveAddr = address;
- if (!xf86I2CDevInit(i2cdev)) {
- NV_ERROR(pScrn, "Couldn't add I2C device\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static uint32_t get_tmds_index_reg(ScrnInfoPtr pScrn, uint8_t mlv)
-{
- /* For mlv < 0x80, it is an index into a table of TMDS base addresses
- * For mlv == 0x80 use the "or" value of the dcb_entry indexed by CR58 for CR57 = 0
- * to index a table of offsets to the basic 0x6808b0 address
- * For mlv == 0x81 use the "or" value of the dcb_entry indexed by CR58 for CR57 = 0
- * to index a table of offsets to the basic 0x6808b0 address, and then flip the offset by 8
- */
-
- NVPtr pNv = NVPTR(pScrn);
- const int pramdac_offset[13] = {0, 0, 0x8, 0, 0x2000, 0, 0, 0, 0x2008, 0, 0, 0, 0x2000};
- const uint32_t pramdac_table[4] = {0x6808b0, 0x6808b8, 0x6828b0, 0x6828b8};
-
- if (mlv >= 0x80) {
- int dcb_entry, dacoffset;
-
- /* note: dcb_entry_idx_from_crtchead needs pre-script set-up */
- if ((dcb_entry = dcb_entry_idx_from_crtchead(pScrn)) == 0x7f)
- return 0;
- dacoffset = pramdac_offset[pNv->VBIOS.bdcb.dcb.entry[dcb_entry].or];
- if (mlv == 0x81)
- dacoffset ^= 8;
- return (0x6808b0 + dacoffset);
- } else {
- if (mlv > (sizeof(pramdac_table) / sizeof(uint32_t))) {
- NV_ERROR(pScrn, "Magic Lookup Value too big (%02X)\n", mlv);
- return 0;
- }
- return pramdac_table[mlv];
- }
-}
-
-static bool init_io_restrict_prog(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_IO_RESTRICT_PROG opcode: 0x32 ('2')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): CRTC port
- * offset + 3 (8 bit): CRTC index
- * offset + 4 (8 bit): mask
- * offset + 5 (8 bit): shift
- * offset + 6 (8 bit): count
- * offset + 7 (32 bit): register
- * offset + 11 (32 bit): configuration 1
- * ...
- *
- * Starting at offset + 11 there are "count" 32 bit values.
- * To find out which value to use read index "CRTC index" on "CRTC port",
- * AND this value with "mask" and then bit shift right "shift" bits.
- * Read the appropriate value using this index and write to "register"
- */
-
- uint16_t crtcport = ROM16(bios->data[offset + 1]);
- uint8_t crtcindex = bios->data[offset + 3];
- uint8_t mask = bios->data[offset + 4];
- uint8_t shift = bios->data[offset + 5];
- uint8_t count = bios->data[offset + 6];
- uint32_t reg = ROM32(bios->data[offset + 7]);
- uint8_t config;
- uint32_t configval;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n",
- offset, crtcport, crtcindex, mask, shift, count, reg);
-
- config = (bios_idxprt_rd(pScrn, crtcport, crtcindex) & mask) >> shift;
- if (config > count) {
- NV_ERROR(pScrn,
- "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
- offset, config, count);
- return false;
- }
-
- configval = ROM32(bios->data[offset + 11 + config * 4]);
-
- BIOSLOG(pScrn, "0x%04X: Writing config %02X\n", offset, config);
-
- bios_wr32(pScrn, reg, configval);
-
- return true;
-}
-
-static bool init_repeat(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_REPEAT opcode: 0x33 ('3')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): count
- *
- * Execute script following this opcode up to INIT_REPEAT_END
- * "count" times
- */
-
- uint8_t count = bios->data[offset + 1];
- uint8_t i;
-
- /* no iexec->execute check by design */
-
- BIOSLOG(pScrn, "0x%04X: Repeating following segment %d times\n", offset, count);
-
- iexec->repeat = true;
-
- /* count - 1, as the script block will execute once when we leave this
- * opcode -- this is compatible with bios behaviour as:
- * a) the block is always executed at least once, even if count == 0
- * b) the bios interpreter skips to the op following INIT_END_REPEAT,
- * while we don't
- */
- for (i = 0; i < count - 1; i++)
- parse_init_table(pScrn, bios, offset + 2, iexec);
-
- iexec->repeat = false;
-
- return true;
-}
-
-static bool init_io_restrict_pll(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_IO_RESTRICT_PLL opcode: 0x34 ('4')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): CRTC port
- * offset + 3 (8 bit): CRTC index
- * offset + 4 (8 bit): mask
- * offset + 5 (8 bit): shift
- * offset + 6 (8 bit): IO flag condition index
- * offset + 7 (8 bit): count
- * offset + 8 (32 bit): register
- * offset + 12 (16 bit): frequency 1
- * ...
- *
- * Starting at offset + 12 there are "count" 16 bit frequencies (10kHz).
- * Set PLL register "register" to coefficients for frequency n,
- * selected by reading index "CRTC index" of "CRTC port" ANDed with
- * "mask" and shifted right by "shift". If "IO flag condition index" > 0,
- * and condition met, double frequency before setting it.
- */
-
- uint16_t crtcport = ROM16(bios->data[offset + 1]);
- uint8_t crtcindex = bios->data[offset + 3];
- uint8_t mask = bios->data[offset + 4];
- uint8_t shift = bios->data[offset + 5];
- int8_t io_flag_condition_idx = bios->data[offset + 6];
- uint8_t count = bios->data[offset + 7];
- uint32_t reg = ROM32(bios->data[offset + 8]);
- uint8_t config;
- uint16_t freq;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, Shift: 0x%02X, IO Flag Condition: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n",
- offset, crtcport, crtcindex, mask, shift, io_flag_condition_idx, count, reg);
-
- config = (bios_idxprt_rd(pScrn, crtcport, crtcindex) & mask) >> shift;
- if (config > count) {
- NV_ERROR(pScrn,
- "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
- offset, config, count);
- return false;
- }
-
- freq = ROM16(bios->data[offset + 12 + config * 2]);
-
- if (io_flag_condition_idx > 0) {
- if (io_flag_condition_met(pScrn, bios, offset, io_flag_condition_idx)) {
- BIOSLOG(pScrn, "0x%04X: Condition fulfilled -- frequency doubled\n", offset);
- freq *= 2;
- } else
- BIOSLOG(pScrn, "0x%04X: Condition not fulfilled -- frequency unchanged\n", offset);
- }
-
- BIOSLOG(pScrn, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %d0kHz\n",
- offset, reg, config, freq);
-
- setPLL(pScrn, bios, reg, freq * 10);
-
- return true;
-}
-
-static bool init_end_repeat(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_END_REPEAT opcode: 0x36 ('6')
- *
- * offset (8 bit): opcode
- *
- * Marks the end of the block for INIT_REPEAT to repeat
- */
-
- /* no iexec->execute check by design */
-
- /* iexec->repeat flag necessary to go past INIT_END_REPEAT opcode when
- * we're not in repeat mode
- */
- if (iexec->repeat)
- return false;
-
- return true;
-}
-
-static bool init_copy(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_COPY opcode: 0x37 ('7')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): register
- * offset + 5 (8 bit): shift
- * offset + 6 (8 bit): srcmask
- * offset + 7 (16 bit): CRTC port
- * offset + 9 (8 bit): CRTC index
- * offset + 10 (8 bit): mask
- *
- * Read index "CRTC index" on "CRTC port", AND with "mask", OR with
- * (REGVAL("register") >> "shift" & "srcmask") and write-back to CRTC port
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint8_t shift = bios->data[offset + 5];
- uint8_t srcmask = bios->data[offset + 6];
- uint16_t crtcport = ROM16(bios->data[offset + 7]);
- uint8_t crtcindex = bios->data[offset + 9];
- uint8_t mask = bios->data[offset + 10];
- uint32_t data;
- uint8_t crtcdata;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Reg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%02X, Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X\n",
- offset, reg, shift, srcmask, crtcport, crtcindex, mask);
-
- data = bios_rd32(pScrn, reg);
-
- if (shift < 0x80)
- data >>= shift;
- else
- data <<= (0x100 - shift);
-
- data &= srcmask;
-
- crtcdata = (bios_idxprt_rd(pScrn, crtcport, crtcindex) & mask) | (uint8_t)data;
- bios_idxprt_wr(pScrn, crtcport, crtcindex, crtcdata);
-
- return true;
-}
-
-static bool init_not(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_NOT opcode: 0x38 ('8')
- *
- * offset (8 bit): opcode
- *
- * Invert the current execute / no-execute condition (i.e. "else")
- */
- if (iexec->execute)
- BIOSLOG(pScrn, "0x%04X: ------ Skipping following commands ------\n", offset);
- else
- BIOSLOG(pScrn, "0x%04X: ------ Executing following commands ------\n", offset);
-
- iexec->execute = !iexec->execute;
- return true;
-}
-
-static bool init_io_flag_condition(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_IO_FLAG_CONDITION opcode: 0x39 ('9')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): condition number
- *
- * Check condition "condition number" in the IO flag condition table.
- * If condition not met skip subsequent opcodes until condition is
- * inverted (INIT_NOT), or we hit INIT_RESUME
- */
-
- uint8_t cond = bios->data[offset + 1];
-
- if (!iexec->execute)
- return true;
-
- if (io_flag_condition_met(pScrn, bios, offset, cond))
- BIOSLOG(pScrn, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
- else {
- BIOSLOG(pScrn, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
- iexec->execute = false;
- }
-
- return true;
-}
-
-static bool init_idx_addr_latched(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_INDEX_ADDRESS_LATCHED opcode: 0x49 ('I')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): control register
- * offset + 5 (32 bit): data register
- * offset + 9 (32 bit): mask
- * offset + 13 (32 bit): data
- * offset + 17 (8 bit): count
- * offset + 18 (8 bit): address 1
- * offset + 19 (8 bit): data 1
- * ...
- *
- * For each of "count" address and data pairs, write "data n" to "data register",
- * read the current value of "control register", and write it back once ANDed
- * with "mask", ORed with "data", and ORed with "address n"
- */
-
- uint32_t controlreg = ROM32(bios->data[offset + 1]);
- uint32_t datareg = ROM32(bios->data[offset + 5]);
- uint32_t mask = ROM32(bios->data[offset + 9]);
- uint32_t data = ROM32(bios->data[offset + 13]);
- uint8_t count = bios->data[offset + 17];
- uint32_t value;
- int i;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: ControlReg: 0x%08X, DataReg: 0x%08X, Mask: 0x%08X, Data: 0x%08X, Count: 0x%02X\n",
- offset, controlreg, datareg, mask, data, count);
-
- for (i = 0; i < count; i++) {
- uint8_t instaddress = bios->data[offset + 18 + i * 2];
- uint8_t instdata = bios->data[offset + 19 + i * 2];
-
- BIOSLOG(pScrn, "0x%04X: Address: 0x%02X, Data: 0x%02X\n", offset, instaddress, instdata);
-
- bios_wr32(pScrn, datareg, instdata);
- value = (bios_rd32(pScrn, controlreg) & mask) | data | instaddress;
- bios_wr32(pScrn, controlreg, value);
- }
-
- return true;
-}
-
-static bool init_io_restrict_pll2(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_IO_RESTRICT_PLL2 opcode: 0x4A ('J')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): CRTC port
- * offset + 3 (8 bit): CRTC index
- * offset + 4 (8 bit): mask
- * offset + 5 (8 bit): shift
- * offset + 6 (8 bit): count
- * offset + 7 (32 bit): register
- * offset + 11 (32 bit): frequency 1
- * ...
- *
- * Starting at offset + 11 there are "count" 32 bit frequencies (kHz).
- * Set PLL register "register" to coefficients for frequency n,
- * selected by reading index "CRTC index" of "CRTC port" ANDed with
- * "mask" and shifted right by "shift".
- */
-
- uint16_t crtcport = ROM16(bios->data[offset + 1]);
- uint8_t crtcindex = bios->data[offset + 3];
- uint8_t mask = bios->data[offset + 4];
- uint8_t shift = bios->data[offset + 5];
- uint8_t count = bios->data[offset + 6];
- uint32_t reg = ROM32(bios->data[offset + 7]);
- uint8_t config;
- uint32_t freq;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n",
- offset, crtcport, crtcindex, mask, shift, count, reg);
-
- if (!reg)
- return true;
-
- config = (bios_idxprt_rd(pScrn, crtcport, crtcindex) & mask) >> shift;
- if (config > count) {
- NV_ERROR(pScrn,
- "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
- offset, config, count);
- return false;
- }
-
- freq = ROM32(bios->data[offset + 11 + config * 4]);
-
- BIOSLOG(pScrn, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %dkHz\n",
- offset, reg, config, freq);
-
- setPLL(pScrn, bios, reg, freq);
-
- return true;
-}
-
-static bool init_pll2(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_PLL2 opcode: 0x4B ('K')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): register
- * offset + 5 (32 bit): freq
- *
- * Set PLL register "register" to coefficients for frequency "freq"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint32_t freq = ROM32(bios->data[offset + 5]);
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Reg: 0x%04X, Freq: %dkHz\n",
- offset, reg, freq);
-
- setPLL(pScrn, bios, reg, freq);
-
- return true;
-}
-
-static bool init_i2c_byte(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_I2C_BYTE opcode: 0x4C ('L')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): DCB I2C table entry index
- * offset + 2 (8 bit): I2C slave address
- * offset + 3 (8 bit): count
- * offset + 4 (8 bit): I2C register 1
- * offset + 5 (8 bit): mask 1
- * offset + 6 (8 bit): data 1
- * ...
- *
- * For each of "count" registers given by "I2C register n" on the device
- * addressed by "I2C slave address" on the I2C bus given by
- * "DCB I2C table entry index", read the register, AND the result with
- * "mask n" and OR it with "data n" before writing it back to the device
- */
-
- uint8_t i2c_index = bios->data[offset + 1];
- uint8_t i2c_address = bios->data[offset + 2];
- uint8_t count = bios->data[offset + 3];
- I2CDevRec i2cdev;
- int i;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, Count: 0x%02X\n",
- offset, i2c_index, i2c_address, count);
-
- if (create_i2c_device(pScrn, bios, i2c_index, i2c_address, &i2cdev))
- return false;
-
- for (i = 0; i < count; i++) {
- uint8_t i2c_reg = bios->data[offset + 4 + i * 3];
- uint8_t mask = bios->data[offset + 5 + i * 3];
- uint8_t data = bios->data[offset + 6 + i * 3];
- uint8_t value;
-
- xf86I2CReadByte(&i2cdev, i2c_reg, &value);
-
- BIOSLOG(pScrn, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n",
- offset, i2c_reg, value, mask, data);
-
- value = (value & mask) | data;
-
- if (bios->execute)
- xf86I2CWriteByte(&i2cdev, i2c_reg, value);
- }
-
- xf86DestroyI2CDevRec(&i2cdev, FALSE);
-
- return true;
-}
-
-static bool init_zm_i2c_byte(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_ZM_I2C_BYTE opcode: 0x4D ('M')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): DCB I2C table entry index
- * offset + 2 (8 bit): I2C slave address
- * offset + 3 (8 bit): count
- * offset + 4 (8 bit): I2C register 1
- * offset + 5 (8 bit): data 1
- * ...
- *
- * For each of "count" registers given by "I2C register n" on the device
- * addressed by "I2C slave address" on the I2C bus given by
- * "DCB I2C table entry index", set the register to "data n"
- */
-
- uint8_t i2c_index = bios->data[offset + 1];
- uint8_t i2c_address = bios->data[offset + 2];
- uint8_t count = bios->data[offset + 3];
- I2CDevRec i2cdev;
- int i;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, Count: 0x%02X\n",
- offset, i2c_index, i2c_address, count);
-
- if (create_i2c_device(pScrn, bios, i2c_index, i2c_address, &i2cdev))
- return false;
-
- for (i = 0; i < count; i++) {
- uint8_t i2c_reg = bios->data[offset + 4 + i * 2];
- uint8_t data = bios->data[offset + 5 + i * 2];
-
- BIOSLOG(pScrn, "0x%04X: I2CReg: 0x%02X, Data: 0x%02X\n",
- offset, i2c_reg, data);
-
- if (bios->execute)
- if (!xf86I2CWriteByte(&i2cdev, i2c_reg, data))
- break;
- }
-
- xf86DestroyI2CDevRec(&i2cdev, FALSE);
-
- return true;
-}
-
-static bool init_zm_i2c(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_ZM_I2C opcode: 0x4E ('N')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): DCB I2C table entry index
- * offset + 2 (8 bit): I2C slave address
- * offset + 3 (8 bit): count
- * offset + 4 (8 bit): data 1
- * ...
- *
- * Send "count" bytes ("data n") to the device addressed by "I2C slave
- * address" on the I2C bus given by "DCB I2C table entry index"
- */
-
- uint8_t i2c_index = bios->data[offset + 1];
- uint8_t i2c_address = bios->data[offset + 2];
- uint8_t count = bios->data[offset + 3];
- I2CDevRec i2cdev;
- uint8_t data[256]; /* 256 is max "count" could specify */
- int i;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, Count: 0x%02X\n",
- offset, i2c_index, i2c_address, count);
-
- if (create_i2c_device(pScrn, bios, i2c_index, i2c_address, &i2cdev))
- return false;
-
- for (i = 0; i < count; i++) {
- data[i] = bios->data[offset + 4 + i];
-
- BIOSLOG(pScrn, "0x%04X: Data: 0x%02X\n", offset, data[i]);
- }
-
- if (bios->execute)
- xf86I2CWrite(&i2cdev, data, count);
-
- xf86DestroyI2CDevRec(&i2cdev, FALSE);
-
- return true;
-}
-
-static bool init_tmds(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_TMDS opcode: 0x4F ('O') (non-canon name)
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): magic lookup value
- * offset + 2 (8 bit): TMDS address
- * offset + 3 (8 bit): mask
- * offset + 4 (8 bit): data
- *
- * Read the data reg for TMDS address "TMDS address", AND it with mask
- * and OR it with data, then write it back
- * "magic lookup value" determines which TMDS base address register is used --
- * see get_tmds_index_reg()
- */
-
- uint8_t mlv = bios->data[offset + 1];
- uint32_t tmdsaddr = bios->data[offset + 2];
- uint8_t mask = bios->data[offset + 3];
- uint8_t data = bios->data[offset + 4];
- uint32_t reg, value;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: MagicLookupValue: 0x%02X, TMDSAddr: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n",
- offset, mlv, tmdsaddr, mask, data);
-
- if (!(reg = get_tmds_index_reg(pScrn, mlv)))
- return false;
-
- bios_wr32(pScrn, reg, tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
- value = (bios_rd32(pScrn, reg + 4) & mask) | data;
- bios_wr32(pScrn, reg + 4, value);
- bios_wr32(pScrn, reg, tmdsaddr);
-
- return true;
-}
-
-static bool init_zm_tmds_group(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_ZM_TMDS_GROUP opcode: 0x50 ('P') (non-canon name)
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): magic lookup value
- * offset + 2 (8 bit): count
- * offset + 3 (8 bit): addr 1
- * offset + 4 (8 bit): data 1
- * ...
- *
- * For each of "count" TMDS address and data pairs write "data n" to "addr n"
- * "magic lookup value" determines which TMDS base address register is used --
- * see get_tmds_index_reg()
- */
-
- uint8_t mlv = bios->data[offset + 1];
- uint8_t count = bios->data[offset + 2];
- uint32_t reg;
- int i;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: MagicLookupValue: 0x%02X, Count: 0x%02X\n",
- offset, mlv, count);
-
- if (!(reg = get_tmds_index_reg(pScrn, mlv)))
- return false;
-
- for (i = 0; i < count; i++) {
- uint8_t tmdsaddr = bios->data[offset + 3 + i * 2];
- uint8_t tmdsdata = bios->data[offset + 4 + i * 2];
-
- bios_wr32(pScrn, reg + 4, tmdsdata);
- bios_wr32(pScrn, reg, tmdsaddr);
- }
-
- return true;
-}
-
-static bool init_cr_idx_adr_latch(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_CR_INDEX_ADDRESS_LATCHED opcode: 0x51 ('Q')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): CRTC index1
- * offset + 2 (8 bit): CRTC index2
- * offset + 3 (8 bit): baseaddr
- * offset + 4 (8 bit): count
- * offset + 5 (8 bit): data 1
- * ...
- *
- * For each of "count" address and data pairs, write "baseaddr + n" to
- * "CRTC index1" and "data n" to "CRTC index2"
- * Once complete, restore initial value read from "CRTC index1"
- */
- uint8_t crtcindex1 = bios->data[offset + 1];
- uint8_t crtcindex2 = bios->data[offset + 2];
- uint8_t baseaddr = bios->data[offset + 3];
- uint8_t count = bios->data[offset + 4];
- uint8_t oldaddr, data;
- int i;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Index1: 0x%02X, Index2: 0x%02X, BaseAddr: 0x%02X, Count: 0x%02X\n",
- offset, crtcindex1, crtcindex2, baseaddr, count);
-
- oldaddr = bios_idxprt_rd(pScrn, NV_CIO_CRX__COLOR, crtcindex1);
-
- for (i = 0; i < count; i++) {
- bios_idxprt_wr(pScrn, NV_CIO_CRX__COLOR, crtcindex1, baseaddr + i);
-
- data = bios->data[offset + 5 + i];
- bios_idxprt_wr(pScrn, NV_CIO_CRX__COLOR, crtcindex2, data);
- }
-
- bios_idxprt_wr(pScrn, NV_CIO_CRX__COLOR, crtcindex1, oldaddr);
-
- return true;
-}
-
-static bool init_cr(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_CR opcode: 0x52 ('R')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): CRTC index
- * offset + 2 (8 bit): mask
- * offset + 3 (8 bit): data
- *
- * Assign the value of at "CRTC index" ANDed with mask and ORed with data
- * back to "CRTC index"
- */
-
- uint8_t crtcindex = bios->data[offset + 1];
- uint8_t mask = bios->data[offset + 2];
- uint8_t data = bios->data[offset + 3];
- uint8_t value;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n",
- offset, crtcindex, mask, data);
-
- value = (bios_idxprt_rd(pScrn, NV_CIO_CRX__COLOR, crtcindex) & mask) | data;
- bios_idxprt_wr(pScrn, NV_CIO_CRX__COLOR, crtcindex, value);
-
- return true;
-}
-
-static bool init_zm_cr(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_ZM_CR opcode: 0x53 ('S')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): CRTC index
- * offset + 2 (8 bit): value
- *
- * Assign "value" to CRTC register with index "CRTC index".
- */
-
- uint8_t crtcindex = ROM32(bios->data[offset + 1]);
- uint8_t data = bios->data[offset + 2];
-
- if (!iexec->execute)
- return true;
-
- bios_idxprt_wr(pScrn, NV_CIO_CRX__COLOR, crtcindex, data);
-
- return true;
-}
-
-static bool init_zm_cr_group(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_ZM_CR_GROUP opcode: 0x54 ('T')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): count
- * offset + 2 (8 bit): CRTC index 1
- * offset + 3 (8 bit): value 1
- * ...
- *
- * For "count", assign "value n" to CRTC register with index "CRTC index n".
- */
-
- uint8_t count = bios->data[offset + 1];
- int i;
-
- if (!iexec->execute)
- return true;
-
- for (i = 0; i < count; i++)
- init_zm_cr(pScrn, bios, offset + 2 + 2 * i - 1, iexec);
-
- return true;
-}
-
-static bool init_condition_time(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_CONDITION_TIME opcode: 0x56 ('V')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): condition number
- * offset + 2 (8 bit): retries / 50
- *
- * Check condition "condition number" in the condition table.
- * Bios code then sleeps for 2ms if the condition is not met, and
- * repeats up to "retries" times, but on one C51 this has proved
- * insufficient. In mmiotraces the driver sleeps for 20ms, so we do
- * this, and bail after "retries" times, or 2s, whichever is less.
- * If still not met after retries, clear execution flag for this table.
- */
-
- uint8_t cond = bios->data[offset + 1];
- uint16_t retries = bios->data[offset + 2] * 50;
-
- if (!iexec->execute)
- return true;
-
- if (retries > 100)
- retries = 100;
-
- BIOSLOG(pScrn, "0x%04X: Condition: 0x%02X, Retries: 0x%02X\n", offset, cond, retries);
-
- for (; retries > 0; retries--)
- if (bios_condition_met(pScrn, bios, offset, cond)) {
- BIOSLOG(pScrn, "0x%04X: Condition met, continuing\n", offset);
- break;
- } else {
- BIOSLOG(pScrn, "0x%04X: Condition not met, sleeping for 20ms\n", offset);
- BIOS_USLEEP(20000);
- }
-
- if (!bios_condition_met(pScrn, bios, offset, cond)) {
- NV_WARN(pScrn, "0x%04X: Condition still not met after %dms, "
- "skiping following opcodes\n", offset, 20 * retries);
- iexec->execute = false;
- }
-
- return true;
-}
-
-static bool init_zm_reg_sequence(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_ZM_REG_SEQUENCE opcode: 0x58 ('X')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): base register
- * offset + 5 (8 bit): count
- * offset + 6 (32 bit): value 1
- * ...
- *
- * Starting at offset + 6 there are "count" 32 bit values.
- * For "count" iterations set "base register" + 4 * current_iteration
- * to "value current_iteration"
- */
-
- uint32_t basereg = ROM32(bios->data[offset + 1]);
- uint32_t count = bios->data[offset + 5];
- int i;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: BaseReg: 0x%08X, Count: 0x%02X\n", offset, basereg, count);
-
- for (i = 0; i < count; i++) {
- uint32_t reg = basereg + i * 4;
- uint32_t data = ROM32(bios->data[offset + 6 + i * 4]);
-
- bios_wr32(pScrn, reg, data);
- }
-
- return true;
-}
-
-static bool init_sub_direct(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_SUB_DIRECT opcode: 0x5B ('[')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): subroutine offset (in bios)
- *
- * Calls a subroutine that will execute commands until INIT_DONE
- * is found.
- */
-
- uint16_t sub_offset = ROM16(bios->data[offset + 1]);
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Executing subroutine at 0x%04X\n", offset, sub_offset);
-
- parse_init_table(pScrn, bios, sub_offset, iexec);
-
- BIOSLOG(pScrn, "0x%04X: End of 0x%04X subroutine\n", offset, sub_offset);
-
- return true;
-}
-
-static bool init_copy_nv_reg(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_COPY_NV_REG opcode: 0x5F ('_')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): src reg
- * offset + 5 (8 bit): shift
- * offset + 6 (32 bit): src mask
- * offset + 10 (32 bit): xor
- * offset + 14 (32 bit): dst reg
- * offset + 18 (32 bit): dst mask
- *
- * Shift REGVAL("src reg") right by (signed) "shift", AND result with
- * "src mask", then XOR with "xor". Write this OR'd with
- * (REGVAL("dst reg") AND'd with "dst mask") to "dst reg"
- */
-
- uint32_t srcreg = *((uint32_t *)(&bios->data[offset + 1]));
- uint8_t shift = bios->data[offset + 5];
- uint32_t srcmask = *((uint32_t *)(&bios->data[offset + 6]));
- uint32_t xor = *((uint32_t *)(&bios->data[offset + 10]));
- uint32_t dstreg = *((uint32_t *)(&bios->data[offset + 14]));
- uint32_t dstmask = *((uint32_t *)(&bios->data[offset + 18]));
- uint32_t srcvalue, dstvalue;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: SrcReg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%08X, Xor: 0x%08X, DstReg: 0x%08X, DstMask: 0x%08X\n",
- offset, srcreg, shift, srcmask, xor, dstreg, dstmask);
-
- srcvalue = bios_rd32(pScrn, srcreg);
-
- if (shift < 0x80)
- srcvalue >>= shift;
- else
- srcvalue <<= (0x100 - shift);
-
- srcvalue = (srcvalue & srcmask) ^ xor;
-
- dstvalue = bios_rd32(pScrn, dstreg) & dstmask;
-
- bios_wr32(pScrn, dstreg, dstvalue | srcvalue);
-
- return true;
-}
-
-static bool init_zm_index_io(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_ZM_INDEX_IO opcode: 0x62 ('b')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): CRTC port
- * offset + 3 (8 bit): CRTC index
- * offset + 4 (8 bit): data
- *
- * Write "data" to index "CRTC index" of "CRTC port"
- */
- uint16_t crtcport = ROM16(bios->data[offset + 1]);
- uint8_t crtcindex = bios->data[offset + 3];
- uint8_t data = bios->data[offset + 4];
-
- if (!iexec->execute)
- return true;
-
- bios_idxprt_wr(pScrn, crtcport, crtcindex, data);
-
- return true;
-}
-
-static bool init_compute_mem(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_COMPUTE_MEM opcode: 0x63 ('c')
- *
- * offset (8 bit): opcode
- *
- * This opcode is meant to set NV_PFB_CFG0 (0x100200) appropriately so
- * that the hardware can correctly calculate how much VRAM it has
- * (and subsequently report that value in NV_PFB_CSTATUS (0x10020C))
- *
- * The implementation of this opcode in general consists of two parts:
- * 1) determination of the memory bus width
- * 2) determination of how many of the card's RAM pads have ICs attached
- *
- * 1) is done by a cunning combination of writes to offsets 0x1c and
- * 0x3c in the framebuffer, and seeing whether the written values are
- * read back correctly. This then affects bits 4-7 of NV_PFB_CFG0
- *
- * 2) is done by a cunning combination of writes to an offset slightly
- * less than the maximum memory reported by NV_PFB_CSTATUS, then seeing
- * if the test pattern can be read back. This then affects bits 12-15 of
- * NV_PFB_CFG0
- *
- * In this context a "cunning combination" may include multiple reads
- * and writes to varying locations, often alternating the test pattern
- * and 0, doubtless to make sure buffers are filled, residual charges
- * on tracks are removed etc.
- *
- * Unfortunately, the "cunning combination"s mentioned above, and the
- * changes to the bits in NV_PFB_CFG0 differ with nearly every bios
- * trace I have.
- *
- * Therefore, we cheat and assume the value of NV_PFB_CFG0 with which
- * we started was correct, and use that instead
- */
-
- /* no iexec->execute check by design */
-
- /* on every card I've seen, this step gets done for us earlier in the init scripts
- uint8_t crdata = bios_idxprt_rd(pScrn, NV_VIO_SRX, 0x01);
- bios_idxprt_wr(pScrn, NV_VIO_SRX, 0x01, crdata | 0x20);
- */
-
- /* this also has probably been done in the scripts, but an mmio trace of
- * s3 resume shows nvidia doing it anyway (unlike the NV_VIO_SRX write)
- */
- bios_wr32(pScrn, NV_PFB_REFCTRL, NV_PFB_REFCTRL_VALID_1);
-
- /* write back the saved configuration value */
- bios_wr32(pScrn, NV_PFB_CFG0, saved_nv_pfb_cfg0);
-
- return true;
-}
-
-static bool init_reset(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_RESET opcode: 0x65 ('e')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): register
- * offset + 5 (32 bit): value1
- * offset + 9 (32 bit): value2
- *
- * Assign "value1" to "register", then assign "value2" to "register"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint32_t value1 = ROM32(bios->data[offset + 5]);
- uint32_t value2 = ROM32(bios->data[offset + 9]);
- uint32_t pci_nv_19, pci_nv_20;
-
- /* no iexec->execute check by design */
-
- pci_nv_19 = bios_rd32(pScrn, NV_PBUS_PCI_NV_19);
- bios_wr32(pScrn, NV_PBUS_PCI_NV_19, 0);
- bios_wr32(pScrn, reg, value1);
-
- BIOS_USLEEP(10);
-
- bios_wr32(pScrn, reg, value2);
- bios_wr32(pScrn, NV_PBUS_PCI_NV_19, pci_nv_19);
-
- pci_nv_20 = bios_rd32(pScrn, NV_PBUS_PCI_NV_20);
- pci_nv_20 &= ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED; /* 0xfffffffe */
- bios_wr32(pScrn, NV_PBUS_PCI_NV_20, pci_nv_20);
-
- return true;
-}
-
-static bool init_configure_mem(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_CONFIGURE_MEM opcode: 0x66 ('f')
- *
- * offset (8 bit): opcode
- *
- * Equivalent to INIT_DONE on bios version 3 or greater.
- * For early bios versions, sets up the memory registers, using values
- * taken from the memory init table
- */
-
- /* no iexec->execute check by design */
-
- uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (bios_idxprt_rd(pScrn, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX) >> 4);
- uint16_t seqtbloffs = bios->legacy.sdr_seq_tbl_ptr, meminitdata = meminitoffs + 6;
- uint32_t reg, data;
-
- if (bios->major_version > 2)
- return false;
-
- bios_idxprt_wr(pScrn, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX,
- bios_idxprt_rd(pScrn, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20);
-
- if (bios->data[meminitoffs] & 1)
- seqtbloffs = bios->legacy.ddr_seq_tbl_ptr;
-
- for (reg = ROM32(bios->data[seqtbloffs]);
- reg != 0xffffffff;
- reg = ROM32(bios->data[seqtbloffs += 4])) {
-
- switch (reg) {
- case NV_PFB_PRE:
- data = NV_PFB_PRE_CMD_PRECHARGE;
- break;
- case NV_PFB_PAD:
- data = NV_PFB_PAD_CKE_NORMAL;
- break;
- case NV_PFB_REF:
- data = NV_PFB_REF_CMD_REFRESH;
- break;
- default:
- data = ROM32(bios->data[meminitdata]);
- meminitdata += 4;
- if (data == 0xffffffff)
- continue;
- }
-
- bios_wr32(pScrn, reg, data);
- }
-
- return true;
-}
-
-static bool init_configure_clk(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_CONFIGURE_CLK opcode: 0x67 ('g')
- *
- * offset (8 bit): opcode
- *
- * Equivalent to INIT_DONE on bios version 3 or greater.
- * For early bios versions, sets up the NVClk and MClk PLLs, using
- * values taken from the memory init table
- */
-
- /* no iexec->execute check by design */
-
- uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (bios_idxprt_rd(pScrn, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX) >> 4);
- int clock;
-
- if (bios->major_version > 2)
- return false;
-
- clock = ROM16(bios->data[meminitoffs + 4]) * 10;
- setPLL(pScrn, bios, NV_PRAMDAC_NVPLL_COEFF, clock);
-
- clock = ROM16(bios->data[meminitoffs + 2]) * 10;
- if (bios->data[meminitoffs] & 1) /* DDR */
- clock *= 2;
- setPLL(pScrn, bios, NV_PRAMDAC_MPLL_COEFF, clock);
-
- return true;
-}
-
-static bool init_configure_preinit(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_CONFIGURE_PREINIT opcode: 0x68 ('h')
- *
- * offset (8 bit): opcode
- *
- * Equivalent to INIT_DONE on bios version 3 or greater.
- * For early bios versions, does early init, loading ram and crystal
- * configuration from straps into CR3C
- */
-
- /* no iexec->execute check by design */
-
- uint32_t straps = bios_rd32(pScrn, NV_PEXTDEV_BOOT_0);
- uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6));
-
- if (bios->major_version > 2)
- return false;
-
- bios_idxprt_wr(pScrn, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX, cr3c);
-
- return true;
-}
-
-static bool init_io(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_IO opcode: 0x69 ('i')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): CRTC port
- * offset + 3 (8 bit): mask
- * offset + 4 (8 bit): data
- *
- * Assign ((IOVAL("crtc port") & "mask") | "data") to "crtc port"
- */
-
- uint16_t crtcport = ROM16(bios->data[offset + 1]);
- uint8_t mask = bios->data[offset + 3];
- uint8_t data = bios->data[offset + 4];
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Port: 0x%04X, Mask: 0x%02X, Data: 0x%02X\n",
- offset, crtcport, mask, data);
-
- bios_port_wr(pScrn, crtcport, (bios_port_rd(pScrn, crtcport) & mask) | data);
-
- return true;
-}
-
-static bool init_sub(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_SUB opcode: 0x6B ('k')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): script number
- *
- * Execute script number "script number", as a subroutine
- */
-
- uint8_t sub = bios->data[offset + 1];
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Calling script %d\n", offset, sub);
-
- parse_init_table(pScrn, bios,
- ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]),
- iexec);
-
- BIOSLOG(pScrn, "0x%04X: End of script %d\n", offset, sub);
-
- return true;
-}
-
-static bool init_ram_condition(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_RAM_CONDITION opcode: 0x6D ('m')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): mask
- * offset + 2 (8 bit): cmpval
- *
- * Test if (NV_PFB_BOOT_0 & "mask") equals "cmpval".
- * If condition not met skip subsequent opcodes until condition is
- * inverted (INIT_NOT), or we hit INIT_RESUME
- */
-
- uint8_t mask = bios->data[offset + 1];
- uint8_t cmpval = bios->data[offset + 2];
- uint8_t data;
-
- if (!iexec->execute)
- return true;
-
- data = bios_rd32(pScrn, NV_PFB_BOOT_0) & mask;
-
- BIOSLOG(pScrn, "0x%04X: Checking if 0x%08X equals 0x%08X\n", offset, data, cmpval);
-
- if (data == cmpval)
- BIOSLOG(pScrn, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
- else {
- BIOSLOG(pScrn, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
- iexec->execute = false;
- }
-
- return true;
-}
-
-static bool init_nv_reg(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_NV_REG opcode: 0x6E ('n')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): register
- * offset + 5 (32 bit): mask
- * offset + 9 (32 bit): data
- *
- * Assign ((REGVAL("register") & "mask") | "data") to "register"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint32_t mask = ROM32(bios->data[offset + 5]);
- uint32_t data = ROM32(bios->data[offset + 9]);
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Reg: 0x%08X, Mask: 0x%08X, Data: 0x%08X\n", offset, reg, mask, data);
-
- bios_wr32(pScrn, reg, (bios_rd32(pScrn, reg) & mask) | data);
-
- return true;
-}
-
-static bool init_macro(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_MACRO opcode: 0x6F ('o')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): macro number
- *
- * Look up macro index "macro number" in the macro index table.
- * The macro index table entry has 1 byte for the index in the macro table,
- * and 1 byte for the number of times to repeat the macro.
- * The macro table entry has 4 bytes for the register address and
- * 4 bytes for the value to write to that register
- */
-
- uint8_t macro_index_tbl_idx = bios->data[offset + 1];
- uint16_t tmp = bios->macro_index_tbl_ptr + (macro_index_tbl_idx * MACRO_INDEX_SIZE);
- uint8_t macro_tbl_idx = bios->data[tmp];
- uint8_t count = bios->data[tmp + 1];
- uint32_t reg, data;
- int i;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Macro: 0x%02X, MacroTableIndex: 0x%02X, Count: 0x%02X\n",
- offset, macro_index_tbl_idx, macro_tbl_idx, count);
-
- for (i = 0; i < count; i++) {
- uint16_t macroentryptr = bios->macro_tbl_ptr + (macro_tbl_idx + i) * MACRO_SIZE;
-
- reg = ROM32(bios->data[macroentryptr]);
- data = ROM32(bios->data[macroentryptr + 4]);
-
- bios_wr32(pScrn, reg, data);
- }
-
- return true;
-}
-
-static bool init_done(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_DONE opcode: 0x71 ('q')
- *
- * offset (8 bit): opcode
- *
- * End the current script
- */
-
- /* mild retval abuse to stop parsing this table */
- return false;
-}
-
-static bool init_resume(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_RESUME opcode: 0x72 ('r')
- *
- * offset (8 bit): opcode
- *
- * End the current execute / no-execute condition
- */
-
- if (iexec->execute)
- return true;
-
- iexec->execute = true;
- BIOSLOG(pScrn, "0x%04X: ---- Executing following commands ----\n", offset);
-
- return true;
-}
-
-static bool init_time(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_TIME opcode: 0x74 ('t')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): time
- *
- * Sleep for "time" microseconds.
- */
-
- uint16_t time = ROM16(bios->data[offset + 1]);
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Sleeping for 0x%04X microseconds\n", offset, time);
-
- BIOS_USLEEP(time);
-
- return true;
-}
-
-static bool init_condition(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_CONDITION opcode: 0x75 ('u')
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): condition number
- *
- * Check condition "condition number" in the condition table.
- * If condition not met skip subsequent opcodes until condition is
- * inverted (INIT_NOT), or we hit INIT_RESUME
- */
-
- uint8_t cond = bios->data[offset + 1];
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Condition: 0x%02X\n", offset, cond);
-
- if (bios_condition_met(pScrn, bios, offset, cond))
- BIOSLOG(pScrn, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
- else {
- BIOSLOG(pScrn, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
- iexec->execute = false;
- }
-
- return true;
-}
-
-static bool init_io_condition(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_IO_CONDITION opcode: 0x76
- *
- * offset (8 bit): opcode
- * offset + 1 (8 bit): condition number
- *
- * Check condition "condition number" in the io condition table.
- * If condition not met skip subsequent opcodes until condition is
- * inverted (INIT_NOT), or we hit INIT_RESUME
- */
-
- uint8_t cond = bios->data[offset + 1];
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: IO condition: 0x%02X\n", offset, cond);
-
- if (io_condition_met(pScrn, bios, offset, cond))
- BIOSLOG(pScrn, "0x%04X: Condition fulfilled -- continuing to execute\n", offset);
- else {
- BIOSLOG(pScrn, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset);
- iexec->execute = false;
- }
-
- return true;
-}
-
-static bool init_index_io(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_INDEX_IO opcode: 0x78 ('x')
- *
- * offset (8 bit): opcode
- * offset + 1 (16 bit): CRTC port
- * offset + 3 (8 bit): CRTC index
- * offset + 4 (8 bit): mask
- * offset + 5 (8 bit): data
- *
- * Read value at index "CRTC index" on "CRTC port", AND with "mask", OR with "data", write-back
- */
-
- uint16_t crtcport = ROM16(bios->data[offset + 1]);
- uint8_t crtcindex = bios->data[offset + 3];
- uint8_t mask = bios->data[offset + 4];
- uint8_t data = bios->data[offset + 5];
- uint8_t value;
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n",
- offset, crtcport, crtcindex, mask, data);
-
- value = (bios_idxprt_rd(pScrn, crtcport, crtcindex) & mask) | data;
- bios_idxprt_wr(pScrn, crtcport, crtcindex, value);
-
- return true;
-}
-
-static bool init_pll(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_PLL opcode: 0x79 ('y')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): register
- * offset + 5 (16 bit): freq
- *
- * Set PLL register "register" to coefficients for frequency (10kHz) "freq"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint16_t freq = ROM16(bios->data[offset + 5]);
-
- if (!iexec->execute)
- return true;
-
- BIOSLOG(pScrn, "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", offset, reg, freq);
-
- setPLL(pScrn, bios, reg, freq * 10);
-
- return true;
-}
-
-static bool init_zm_reg(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_ZM_REG opcode: 0x7A ('z')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): register
- * offset + 5 (32 bit): value
- *
- * Assign "value" to "register"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint32_t value = ROM32(bios->data[offset + 5]);
-
- if (!iexec->execute)
- return true;
-
- bios_wr32(pScrn, reg, value);
-
- return true;
-}
-
-static bool init_8e(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_8E opcode: 0x8E ('')
- *
- * offset (8 bit): opcode
- *
- * The purpose of this opcode is unclear (being for nv50 cards), and
- * the literal functionality can be seen in the code below.
- *
- * A brief synopsis is that for each entry in a table pointed to by the
- * DCB table header, depending on the settings of various bits, various
- * other bits in registers 0xe100, 0xe104, and 0xe108, are set or
- * cleared.
- */
-
- uint8_t headerlen = bios->data[bios->bdcb.init8e_table_ptr + 1];
- uint8_t entries = bios->data[bios->bdcb.init8e_table_ptr + 2];
- uint8_t recordlen = bios->data[bios->bdcb.init8e_table_ptr + 3];
- int i;
-
- if (bios->bdcb.version != 0x40) {
- NV_ERROR(pScrn, "DCB table not version 4.0\n");
- return false;
- }
- if (!bios->bdcb.init8e_table_ptr) {
- NV_WARN(pScrn, "Invalid pointer to INIT_8E table\n");
- return false;
- }
-
- for (i = 0; i < entries; i++) {
- uint32_t entry = ROM32(bios->data[bios->bdcb.init8e_table_ptr + headerlen + recordlen * i]);
- int shift = (entry & 0x1f) * 4;
- uint32_t mask;
- uint32_t reg = 0xe104;
- uint32_t data;
-
- if ((entry & 0xff00) == 0xff00)
- continue;
-
- if (shift >= 32) {
- reg += 4;
- shift -= 32;
- }
- shift %= 32;
-
- mask = ~(3 << shift);
- if (entry & (1 << 24))
- data = (entry >> 21);
- else
- data = (entry >> 19);
- data = ((data & 3) ^ 2) << shift;
-
- BIOSLOG(pScrn, "0x%04X: Entry: 0x%08X, Reg: 0x%08X, Shift: 0x%02X, Mask: 0x%08X, Data: 0x%08X\n",
- offset, entry, reg, shift, mask, data);
-
- bios_wr32(pScrn, reg, (bios_rd32(pScrn, reg) & mask) | data);
-
- reg = 0xe100;
- shift = entry & 0x1f;
-
- mask = ~(1 << 16 | 1);
- mask = mask << shift | mask >> (32 - shift);
- data = 0;
- if ((entry & (3 << 25)) == (1 << 25))
- data |= 1;
- if ((entry & (3 << 25)) == (2 << 25))
- data |= 0x10000;
- data <<= shift;
-
- BIOSLOG(pScrn, "0x%04X: Entry: 0x%08X, Reg: 0x%08X, Shift: 0x%02X, Mask: 0x%08X, Data: 0x%08X\n",
- offset, entry, reg, shift, mask, data);
-
- bios_wr32(pScrn, reg, (bios_rd32(pScrn, reg) & mask) | data);
- }
-
- return true;
-}
-
-/* hack to avoid moving the itbl_entry array before this function */
-int init_ram_restrict_zm_reg_group_blocklen = 0;
-
-static bool init_ram_restrict_zm_reg_group(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_RAM_RESTRICT_ZM_REG_GROUP opcode: 0x8F ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): reg
- * offset + 5 (8 bit): regincrement
- * offset + 6 (8 bit): count
- * offset + 7 (32 bit): value 1,1
- * ...
- *
- * Use the RAMCFG strap of PEXTDEV_BOOT as an index into the table at
- * ram_restrict_table_ptr. The value read from here is 'n', and
- * "value 1,n" gets written to "reg". This repeats "count" times and on
- * each iteration 'm', "reg" increases by "regincrement" and
- * "value m,n" is used. The extent of n is limited by a number read
- * from the 'M' BIT table, herein called "blocklen"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint8_t regincrement = bios->data[offset + 5];
- uint8_t count = bios->data[offset + 6];
- uint32_t strap_ramcfg, data;
- uint16_t blocklen;
- uint8_t index;
- int i;
-
- /* previously set by 'M' BIT table */
- blocklen = init_ram_restrict_zm_reg_group_blocklen;
-
- if (!iexec->execute)
- return true;
-
- if (!blocklen) {
- NV_ERROR(pScrn, "0x%04X: Zero block length - has the M table "
- "been parsed?\n", offset);
- return false;
- }
-
- strap_ramcfg = (bios_rd32(pScrn, NV_PEXTDEV_BOOT_0) >> 2) & 0xf;
- index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg];
-
- BIOSLOG(pScrn, "0x%04X: Reg: 0x%08X, RegIncrement: 0x%02X, Count: 0x%02X, StrapRamCfg: 0x%02X, Index: 0x%02X\n",
- offset, reg, regincrement, count, strap_ramcfg, index);
-
- for (i = 0; i < count; i++) {
- data = ROM32(bios->data[offset + 7 + index * 4 + blocklen * i]);
-
- bios_wr32(pScrn, reg, data);
-
- reg += regincrement;
- }
-
- return true;
-}
-
-static bool init_copy_zm_reg(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_COPY_ZM_REG opcode: 0x90 ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): src reg
- * offset + 5 (32 bit): dst reg
- *
- * Put contents of "src reg" into "dst reg"
- */
-
- uint32_t srcreg = ROM32(bios->data[offset + 1]);
- uint32_t dstreg = ROM32(bios->data[offset + 5]);
-
- if (!iexec->execute)
- return true;
-
- bios_wr32(pScrn, dstreg, bios_rd32(pScrn, srcreg));
-
- return true;
-}
-
-static bool init_zm_reg_group_addr_latched(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_ZM_REG_GROUP_ADDRESS_LATCHED opcode: 0x91 ('')
- *
- * offset (8 bit): opcode
- * offset + 1 (32 bit): dst reg
- * offset + 5 (8 bit): count
- * offset + 6 (32 bit): data 1
- * ...
- *
- * For each of "count" values write "data n" to "dst reg"
- */
-
- uint32_t reg = ROM32(bios->data[offset + 1]);
- uint8_t count = bios->data[offset + 5];
- int i;
-
- if (!iexec->execute)
- return true;
-
- for (i = 0; i < count; i++) {
- uint32_t data = ROM32(bios->data[offset + 6 + 4 * i]);
- bios_wr32(pScrn, reg, data);
- }
-
- return true;
-}
-
-static bool init_reserved(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset, init_exec_t *iexec)
-{
- /* INIT_RESERVED opcode: 0x92 ('')
- *
- * offset (8 bit): opcode
- *
- * Seemingly does nothing
- */
-
- return true;
-}
-
-static init_tbl_entry_t itbl_entry[] = {
- /* command name , id , length , offset , mult , command handler */
- /* INIT_PROG (0x31, 15, 10, 4) removed due to no example of use */
- { "INIT_IO_RESTRICT_PROG" , 0x32, 11 , 6 , 4 , init_io_restrict_prog },
- { "INIT_REPEAT" , 0x33, 2 , 0 , 0 , init_repeat },
- { "INIT_IO_RESTRICT_PLL" , 0x34, 12 , 7 , 2 , init_io_restrict_pll },
- { "INIT_END_REPEAT" , 0x36, 1 , 0 , 0 , init_end_repeat },
- { "INIT_COPY" , 0x37, 11 , 0 , 0 , init_copy },
- { "INIT_NOT" , 0x38, 1 , 0 , 0 , init_not },
- { "INIT_IO_FLAG_CONDITION" , 0x39, 2 , 0 , 0 , init_io_flag_condition },
- { "INIT_INDEX_ADDRESS_LATCHED" , 0x49, 18 , 17 , 2 , init_idx_addr_latched },
- { "INIT_IO_RESTRICT_PLL2" , 0x4A, 11 , 6 , 4 , init_io_restrict_pll2 },
- { "INIT_PLL2" , 0x4B, 9 , 0 , 0 , init_pll2 },
- { "INIT_I2C_BYTE" , 0x4C, 4 , 3 , 3 , init_i2c_byte },
- { "INIT_ZM_I2C_BYTE" , 0x4D, 4 , 3 , 2 , init_zm_i2c_byte },
- { "INIT_ZM_I2C" , 0x4E, 4 , 3 , 1 , init_zm_i2c },
- { "INIT_TMDS" , 0x4F, 5 , 0 , 0 , init_tmds },
- { "INIT_ZM_TMDS_GROUP" , 0x50, 3 , 2 , 2 , init_zm_tmds_group },
- { "INIT_CR_INDEX_ADDRESS_LATCHED" , 0x51, 5 , 4 , 1 , init_cr_idx_adr_latch },
- { "INIT_CR" , 0x52, 4 , 0 , 0 , init_cr },
- { "INIT_ZM_CR" , 0x53, 3 , 0 , 0 , init_zm_cr },
- { "INIT_ZM_CR_GROUP" , 0x54, 2 , 1 , 2 , init_zm_cr_group },
- { "INIT_CONDITION_TIME" , 0x56, 3 , 0 , 0 , init_condition_time },
- { "INIT_ZM_REG_SEQUENCE" , 0x58, 6 , 5 , 4 , init_zm_reg_sequence },
- /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */
- { "INIT_SUB_DIRECT" , 0x5B, 3 , 0 , 0 , init_sub_direct },
- { "INIT_COPY_NV_REG" , 0x5F, 22 , 0 , 0 , init_copy_nv_reg },
- { "INIT_ZM_INDEX_IO" , 0x62, 5 , 0 , 0 , init_zm_index_io },
- { "INIT_COMPUTE_MEM" , 0x63, 1 , 0 , 0 , init_compute_mem },
- { "INIT_RESET" , 0x65, 13 , 0 , 0 , init_reset },
- { "INIT_CONFIGURE_MEM" , 0x66, 1 , 0 , 0 , init_configure_mem },
- { "INIT_CONFIGURE_CLK" , 0x67, 1 , 0 , 0 , init_configure_clk },
- { "INIT_CONFIGURE_PREINIT" , 0x68, 1 , 0 , 0 , init_configure_preinit },
- { "INIT_IO" , 0x69, 5 , 0 , 0 , init_io },
- { "INIT_SUB" , 0x6B, 2 , 0 , 0 , init_sub },
- { "INIT_RAM_CONDITION" , 0x6D, 3 , 0 , 0 , init_ram_condition },
- { "INIT_NV_REG" , 0x6E, 13 , 0 , 0 , init_nv_reg },
- { "INIT_MACRO" , 0x6F, 2 , 0 , 0 , init_macro },
- { "INIT_DONE" , 0x71, 1 , 0 , 0 , init_done },
- { "INIT_RESUME" , 0x72, 1 , 0 , 0 , init_resume },
- /* INIT_RAM_CONDITION2 (0x73, 9, 0, 0) removed due to no example of use */
- { "INIT_TIME" , 0x74, 3 , 0 , 0 , init_time },
- { "INIT_CONDITION" , 0x75, 2 , 0 , 0 , init_condition },
- { "INIT_IO_CONDITION" , 0x76, 2 , 0 , 0 , init_io_condition },
- { "INIT_INDEX_IO" , 0x78, 6 , 0 , 0 , init_index_io },
- { "INIT_PLL" , 0x79, 7 , 0 , 0 , init_pll },
- { "INIT_ZM_REG" , 0x7A, 9 , 0 , 0 , init_zm_reg },
- { "INIT_8E" , 0x8E, 1 , 0 , 0 , init_8e },
- /* INIT_RAM_RESTRICT_ZM_REG_GROUP's mult is loaded by M table in BIT */
- { "INIT_RAM_RESTRICT_ZM_REG_GROUP" , 0x8F, 7 , 6 , 0 , init_ram_restrict_zm_reg_group },
- { "INIT_COPY_ZM_REG" , 0x90, 9 , 0 , 0 , init_copy_zm_reg },
- { "INIT_ZM_REG_GROUP_ADDRESS_LATCHED" , 0x91, 6 , 5 , 4 , init_zm_reg_group_addr_latched },
- { "INIT_RESERVED" , 0x92, 1 , 0 , 0 , init_reserved },
- { 0 , 0 , 0 , 0 , 0 , 0 }
-};
-
-static unsigned int get_init_table_entry_length(struct nvbios *bios, unsigned int offset, int i)
-{
- /* Calculates the length of a given init table entry. */
- return itbl_entry[i].length + bios->data[offset + itbl_entry[i].length_offset]*itbl_entry[i].length_multiplier;
-}
-
-#define MAX_TABLE_OPS 1000
-
-static int parse_init_table(ScrnInfoPtr pScrn, struct nvbios *bios, unsigned int offset, init_exec_t *iexec)
-{
- /* Parses all commands in an init table.
- *
- * We start out executing all commands found in the init table. Some
- * opcodes may change the status of iexec->execute to SKIP, which will
- * cause the following opcodes to perform no operation until the value
- * is changed back to EXECUTE.
- */
-
- int count = 0, i;
- uint8_t id;
-
- /* Loop until INIT_DONE causes us to break out of the loop
- * (or until offset > bios length just in case... )
- * (and no more than MAX_TABLE_OPS iterations, just in case... ) */
- while ((offset < bios->length) && (count++ < MAX_TABLE_OPS)) {
- id = bios->data[offset];
-
- /* Find matching id in itbl_entry */
- for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != id); i++)
- ;
-
- if (itbl_entry[i].name) {
- BIOSLOG(pScrn, "0x%04X: [ (0x%02X) - %s ]\n",
- offset, itbl_entry[i].id, itbl_entry[i].name);
-
- /* execute eventual command handler */
- if (itbl_entry[i].handler)
- if (!(*itbl_entry[i].handler)(pScrn, bios, offset, iexec))
- break;
- } else {
- NV_ERROR(pScrn, "0x%04X: Init table command not found: "
- "0x%02X\n", offset, id);
- return -ENOENT;
- }
-
- /* Add the offset of the current command including all data
- * of that command. The offset will then be pointing on the
- * next op code.
- */
- offset += get_init_table_entry_length(bios, offset, i);
- }
-
- if (offset >= bios->length)
- NV_WARN(pScrn,
- "Offset 0x%04X greater than known bios image length. "
- "Corrupt image?\n", offset);
- if (count >= MAX_TABLE_OPS)
- NV_WARN(pScrn, "More than %d opcodes to a table is unlikely, "
- "is the bios image corrupt?\n", MAX_TABLE_OPS);
-
- return 0;
-}
-
-static void parse_init_tables(ScrnInfoPtr pScrn, struct nvbios *bios)
-{
- /* Loops and calls parse_init_table() for each present table. */
-
- int i = 0;
- uint16_t table;
- init_exec_t iexec = {true, false};
-
- if (bios->old_style_init) {
- if (bios->init_script_tbls_ptr)
- parse_init_table(pScrn, bios, bios->init_script_tbls_ptr, &iexec);
- if (bios->extra_init_script_tbl_ptr)
- parse_init_table(pScrn, bios, bios->extra_init_script_tbl_ptr, &iexec);
-
- return;
- }
-
- while ((table = ROM16(bios->data[bios->init_script_tbls_ptr + i]))) {
- NV_INFO(pScrn, "Parsing VBIOS init table %d at offset 0x%04X\n",
- i / 2, table);
- BIOSLOG(pScrn, "0x%04X: ------ Executing following commands ------\n", table);
-
- parse_init_table(pScrn, bios, table, &iexec);
- i += 2;
- }
-}
-
-static void link_head_and_output(NVPtr pNv, struct dcb_entry *dcbent, int head, bool dl)
-{
- /* The BIOS scripts don't do this for us, sadly
- * Luckily we do know the values ;-)
- *
- * head < 0 indicates we wish to force a setting with the overrideval
- * (for VT restore etc.)
- */
-
- int ramdac = (dcbent->or & OUTPUT_C) >> 2;
- uint8_t tmds04 = 0x80;
-
- if (head != ramdac)
- tmds04 = 0x88;
-
- if (dcbent->type == OUTPUT_LVDS)
- tmds04 |= 0x01;
-
- nv_write_tmds(pNv, dcbent->or, 0, 0x04, tmds04);
-
- if (dl) /* dual link */
- nv_write_tmds(pNv, dcbent->or, 1, 0x04, tmds04 ^ 0x08);
-}
-
-static uint16_t clkcmptable(struct nvbios *bios, uint16_t clktable, int pxclk)
-{
- int compare_record_len, i = 0;
- uint16_t compareclk, scriptptr = 0;
-
- if (bios->major_version < 5) /* pre BIT */
- compare_record_len = 3;
- else
- compare_record_len = 4;
-
- do {
- compareclk = ROM16(bios->data[clktable + compare_record_len * i]);
- if (pxclk >= compareclk * 10) {
- if (bios->major_version < 5) {
- uint8_t tmdssub = bios->data[clktable + 2 + compare_record_len * i];
- scriptptr = ROM16(bios->data[bios->init_script_tbls_ptr + tmdssub * 2]);
- } else
- scriptptr = ROM16(bios->data[clktable + 2 + compare_record_len * i]);
- break;
- }
- i++;
- } while (compareclk);
-
- return scriptptr;
-}
-
-static void run_digital_op_script(ScrnInfoPtr pScrn, uint16_t scriptptr, struct dcb_entry *dcbent, int head, bool dl)
-{
- struct nvbios *bios = &NVPTR(pScrn)->VBIOS;
- init_exec_t iexec = {true, false};
-
- NV_TRACE(pScrn, "0x%04X: Parsing digital output script table\n",
- scriptptr);
- bios_idxprt_wr(pScrn, NV_CIO_CRX__COLOR, NV_CIO_CRE_44,
- head ? NV_CIO_CRE_44_HEADB : NV_CIO_CRE_44_HEADA);
- /* note: if dcb entries have been merged, index may be misleading */
- NVWriteVgaCrtc5758(NVPTR(pScrn), head, 0, dcbent->index);
- parse_init_table(pScrn, bios, scriptptr, &iexec);
-
- link_head_and_output(NVPTR(pScrn), dcbent, head, dl);
-}
-
-static int call_lvds_manufacturer_script(ScrnInfoPtr pScrn, struct dcb_entry *dcbent, int head, enum LVDS_script script)
-{
- NVPtr pNv = NVPTR(pScrn);
- struct nvbios *bios = &pNv->VBIOS;
- uint8_t sub = bios->data[bios->fp.xlated_entry + script] + (bios->fp.link_c_increment && dcbent->or & OUTPUT_C ? 1 : 0);
- uint16_t scriptofs = ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]);
-
- if (!bios->fp.xlated_entry || !sub || !scriptofs)
- return -EINVAL;
-
- run_digital_op_script(pScrn, scriptofs, dcbent, head, bios->fp.dual_link);
-
- if (script == LVDS_PANEL_OFF)
- /* off-on delay in ms */
- BIOS_USLEEP(ROM16(bios->data[bios->fp.xlated_entry + 7]));
-#ifdef __powerpc__
- /* Powerbook specific quirks */
- if (script == LVDS_RESET && ((pNv->Chipset & 0xffff) == 0x0179 || (pNv->Chipset & 0xffff) == 0x0329))
- nv_write_tmds(pNv, dcbent->or, 0, 0x02, 0x72);
- if ((pNv->Chipset & 0xffff) == 0x0179 || (pNv->Chipset & 0xffff) == 0x0189 || (pNv->Chipset & 0xffff) == 0x0329) {
- if (script == LVDS_PANEL_ON) {
- bios_wr32(pScrn, NV_PBUS_DEBUG_DUALHEAD_CTL, bios_rd32(pScrn, NV_PBUS_DEBUG_DUALHEAD_CTL) | (1 << 31));
- bios_wr32(pScrn, NV_PCRTC_GPIO_EXT, bios_rd32(pScrn, NV_PCRTC_GPIO_EXT) | 1);
- }
- if (script == LVDS_PANEL_OFF) {
- bios_wr32(pScrn, NV_PBUS_DEBUG_DUALHEAD_CTL, bios_rd32(pScrn, NV_PBUS_DEBUG_DUALHEAD_CTL) & ~(1 << 31));
- bios_wr32(pScrn, NV_PCRTC_GPIO_EXT, bios_rd32(pScrn, NV_PCRTC_GPIO_EXT) & ~3);
- }
- }
-#endif
-
- return 0;
-}
-
-static int run_lvds_table(ScrnInfoPtr pScrn, struct dcb_entry *dcbent, int head, enum LVDS_script script, int pxclk)
-{
- /* The BIT LVDS table's header has the information to setup the
- * necessary registers. Following the standard 4 byte header are:
- * A bitmask byte and a dual-link transition pxclk value for use in
- * selecting the init script when not using straps; 4 script pointers
- * for panel power, selected by output and on/off; and 8 table pointers
- * for panel init, the needed one determined by output, and bits in the
- * conf byte. These tables are similar to the TMDS tables, consisting
- * of a list of pxclks and script pointers.
- */
-
- struct nvbios *bios = &NVPTR(pScrn)->VBIOS;
- unsigned int outputset = (dcbent->or == 4) ? 1 : 0;
- uint16_t scriptptr = 0, clktable;
- uint8_t clktableptr = 0;
-
- /* for now we assume version 3.0 table - g80 support will need some changes */
-
- switch (script) {
- case LVDS_INIT:
- return -ENOSYS;
- case LVDS_BACKLIGHT_ON:
- case LVDS_PANEL_ON:
- scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 7 + outputset * 2]);
- break;
- case LVDS_BACKLIGHT_OFF:
- case LVDS_PANEL_OFF:
- scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]);
- break;
- case LVDS_RESET:
- if (dcbent->lvdsconf.use_straps_for_mode) {
- if (bios->fp.dual_link)
- clktableptr += 2;
- if (bios->fp.BITbit1)
- clktableptr++;
- } else {
- /* using EDID */
- uint8_t fallback = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
- int fallbackcmpval = (dcbent->or == 4) ? 4 : 1;
-
- if (bios->fp.dual_link) {
- clktableptr += 2;
- fallbackcmpval *= 2;
- }
- if (fallbackcmpval & fallback)
- clktableptr++;
- }
-
- /* adding outputset * 8 may not be correct */
- clktable = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 15 + clktableptr * 2 + outputset * 8]);
- if (!clktable) {
- NV_ERROR(pScrn, "Pixel clock comparison table not found\n");
- return -ENOENT;
- }
- scriptptr = clkcmptable(bios, clktable, pxclk);
- }
-
- if (!scriptptr) {
- NV_ERROR(pScrn, "LVDS output init script not found\n");
- return -ENOENT;
- }
- run_digital_op_script(pScrn, scriptptr, dcbent, head, bios->fp.dual_link);
-
- return 0;
-}
-
-int call_lvds_script(ScrnInfoPtr pScrn, struct dcb_entry *dcbent, int head, enum LVDS_script script, int pxclk)
-{
- /* LVDS operations are multiplexed in an effort to present a single API
- * which works with two vastly differing underlying structures.
- * This acts as the demux
- */
-
- NVPtr pNv = NVPTR(pScrn);
- struct nvbios *bios = &pNv->VBIOS;
- uint8_t lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer];
- uint32_t sel_clk_binding, sel_clk;
- int ret;
-
- if (bios->fp.last_script_invoc == (script << 1 | head) || !lvds_ver ||
- (lvds_ver >= 0x30 && script == LVDS_INIT))
- return 0;
-
- if (!bios->fp.lvds_init_run) {
- bios->fp.lvds_init_run = true;
- call_lvds_script(pScrn, dcbent, head, LVDS_INIT, pxclk);
- }
-
- if (script == LVDS_PANEL_ON && bios->fp.reset_after_pclk_change)
- call_lvds_script(pScrn, dcbent, head, LVDS_RESET, pxclk);
- if (script == LVDS_RESET && bios->fp.power_off_for_reset)
- call_lvds_script(pScrn, dcbent, head, LVDS_PANEL_OFF, pxclk);
-
- NV_TRACE(pScrn, "Calling LVDS script %d:\n", script);
-
- /* don't let script change pll->head binding */
- sel_clk_binding = bios_rd32(pScrn, NV_PRAMDAC_SEL_CLK) & 0x50000;
-
- if (lvds_ver < 0x30)
- ret = call_lvds_manufacturer_script(pScrn, dcbent, head, script);
- else
- ret = run_lvds_table(pScrn, dcbent, head, script, pxclk);
-
- bios->fp.last_script_invoc = (script << 1 | head);
-
- sel_clk = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000;
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding);
- /* some scripts set a value in NV_PBUS_POWERCTRL_2 and break video overlay */
- nvWriteMC(pNv, NV_PBUS_POWERCTRL_2, 0);
-
- return ret;
-}
-
-struct lvdstableheader {
- uint8_t lvds_ver, headerlen, recordlen;
-};
-
-static int parse_lvds_manufacturer_table_header(ScrnInfoPtr pScrn, struct nvbios *bios, struct lvdstableheader *lth)
-{
- /* BMP version (0xa) LVDS table has a simple header of version and
- * record length. The BIT LVDS table has the typical BIT table header:
- * version byte, header length byte, record length byte, and a byte for
- * the maximum number of records that can be held in the table */
-
- uint8_t lvds_ver, headerlen, recordlen;
-
- memset(lth, 0, sizeof(struct lvdstableheader));
-
- if (bios->fp.lvdsmanufacturerpointer == 0x0) {
- NV_ERROR(pScrn, "Pointer to LVDS manufacturer table invalid\n");
- return -EINVAL;
- }
-
- lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer];
-
- switch (lvds_ver) {
- case 0x0a: /* pre NV40 */
- headerlen = 2;
- recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1];
- break;
- case 0x30: /* NV4x */
- headerlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1];
- if (headerlen < 0x1f) {
- NV_ERROR(pScrn, "LVDS table header not understood\n");
- return -EINVAL;
- }
- recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 2];
- break;
- case 0x40: /* G80/G90 */
- headerlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1];
- if (headerlen < 0x7) {
- NV_ERROR(pScrn, "LVDS table header not understood\n");
- return -EINVAL;
- }
- recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 2];
- break;
- default:
- NV_ERROR(pScrn,
- "LVDS table revision %d.%d not currently supported\n",
- lvds_ver >> 4, lvds_ver & 0xf);
- return -ENOSYS;
- }
-
- lth->lvds_ver = lvds_ver;
- lth->headerlen = headerlen;
- lth->recordlen = recordlen;
-
- return 0;
-}
-
-static int get_fp_strap(ScrnInfoPtr pScrn, struct nvbios *bios)
-{
- /* the fp strap is normally dictated by the "User Strap" in
- * PEXTDEV_BOOT_0[20:16], but on BMP cards when bit 2 of the
- * Internal_Flags struct at 0x48 is set, the user strap gets overriden
- * by the PCI subsystem ID during POST, but not before the previous user
- * strap has been committed to CR58 for CR57=0xf on head A, which may be
- * read and used instead
- */
- NVPtr pNv = NVPTR(pScrn);
-
- if (bios->major_version < 5 && bios->data[0x48] & 0x4)
- return (NVReadVgaCrtc5758(NVPTR(pScrn), 0, 0xf) & 0xf);
-
- if (pNv->Architecture >= NV_ARCH_50)
- return ((bios_rd32(pScrn, NV_PEXTDEV_BOOT_0) >> 24) & 0xf);
- else
- return ((bios_rd32(pScrn, NV_PEXTDEV_BOOT_0) >> 16) & 0xf);
-}
-
-static int parse_fp_mode_table(ScrnInfoPtr pScrn, struct nvbios *bios)
-{
- uint8_t *fptable;
- uint8_t fptable_ver, headerlen = 0, recordlen, fpentries = 0xf, fpindex;
- int ret, ofs, fpstrapping;
- struct lvdstableheader lth;
-
- if (bios->fp.fptablepointer == 0x0) {
- /* Apple cards don't have the fp table; the laptops use DDC */
- /* The table is also missing on some x86 IGPs */
-#ifndef __powerpc__
- NV_WARN(pScrn, "Pointer to flat panel table invalid\n");
-#endif
- bios->pub.digital_min_front_porch = 0x4b;
- return 0;
- }
-
- fptable = &bios->data[bios->fp.fptablepointer];
- fptable_ver = fptable[0];
-
- switch (fptable_ver) {
- /* BMP version 0x5.0x11 BIOSen have version 1 like tables, but no version field,
- * and miss one of the spread spectrum/PWM bytes.
- * This could affect early GF2Go parts (not seen any appropriate ROMs though).
- * Here we assume that a version of 0x05 matches this case (combining with a
- * BMP version check would be better), as the common case for the panel type
- * field is 0x0005, and that is in fact what we are reading the first byte of. */
- case 0x05: /* some NV10, 11, 15, 16 */
- recordlen = 42;
- ofs = -1;
- break;
- case 0x10: /* some NV15/16, and NV11+ */
- recordlen = 44;
- ofs = 0;
- break;
- case 0x20: /* NV40+ */
- headerlen = fptable[1];
- recordlen = fptable[2];
- fpentries = fptable[3];
- /* fptable[4] is the minimum RAMDAC_FP_HCRTC->RAMDAC_FP_HSYNC_START gap */
- bios->pub.digital_min_front_porch = fptable[4];
- ofs = -7;
- break;
- default:
- NV_ERROR(pScrn,
- "FP table revision %d.%d not currently supported\n",
- fptable_ver >> 4, fptable_ver & 0xf);
- return -ENOSYS;
- }
-
- if (!bios->is_mobile) /* !mobile only needs digital_min_front_porch */
- return 0;
-
- if ((ret = parse_lvds_manufacturer_table_header(pScrn, bios, &lth)))
- return ret;
-
- if (lth.lvds_ver == 0x30 || lth.lvds_ver == 0x40) {
- bios->fp.fpxlatetableptr = bios->fp.lvdsmanufacturerpointer + lth.headerlen + 1;
- bios->fp.xlatwidth = lth.recordlen;
- }
- if (bios->fp.fpxlatetableptr == 0x0) {
- NV_ERROR(pScrn, "Pointer to flat panel xlat table invalid\n");
- return -EINVAL;
- }
-
- fpstrapping = get_fp_strap(pScrn, bios);
-
- fpindex = bios->data[bios->fp.fpxlatetableptr + fpstrapping * bios->fp.xlatwidth];
-
- if (fpindex > fpentries) {
- NV_ERROR(pScrn, "Bad flat panel table index\n");
- return -ENOENT;
- }
-
- /* nv4x cards need both a strap value and fpindex of 0xf to use DDC */
- if (lth.lvds_ver > 0x10)
- bios->pub.fp_no_ddc = fpstrapping != 0xf || fpindex != 0xf;
-
- /* if either the strap or xlated fpindex value are 0xf there is no
- * panel using a strap-derived bios mode present. this condition
- * includes, but is different from, the DDC panel indicator above
- */
- if (fpstrapping == 0xf || fpindex == 0xf)
- return 0;
-
- bios->fp.mode_ptr = bios->fp.fptablepointer + headerlen +
- recordlen * fpindex + ofs;
-
- NV_TRACE(pScrn, "BIOS FP mode: %dx%d (%dkHz pixel clock)\n",
- ROM16(bios->data[bios->fp.mode_ptr + 11]) + 1,
- ROM16(bios->data[bios->fp.mode_ptr + 25]) + 1,
- ROM16(bios->data[bios->fp.mode_ptr + 7]) * 10);
-
- return 0;
-}
-
-bool nouveau_bios_fp_mode(ScrnInfoPtr pScrn, DisplayModeRec *mode)
-{
- struct nvbios *bios = &NVPTR(pScrn)->VBIOS;
- uint8_t *mode_entry = &bios->data[bios->fp.mode_ptr];
-
- if (!mode) /* just checking whether we can produce a mode */
- return bios->fp.mode_ptr;
-
- memset(mode, 0, sizeof(DisplayModeRec));
- /* for version 1.0 (version in byte 0):
- * bytes 1-2 are "panel type", including bits on whether Colour/mono,
- * single/dual link, and type (TFT etc.)
- * bytes 3-6 are bits per colour in RGBX */
- mode->Clock = ROM16(mode_entry[7]) * 10;
- /* bytes 9-10 is HActive */
- mode->HDisplay = ROM16(mode_entry[11]) + 1;
- /* bytes 13-14 is HValid Start
- * bytes 15-16 is HValid End */
- mode->HSyncStart = ROM16(mode_entry[17]) + 1;
- mode->HSyncEnd = ROM16(mode_entry[19]) + 1;
- mode->HTotal = ROM16(mode_entry[21]) + 1;
- /* bytes 23-24, 27-30 similarly, but vertical */
- mode->VDisplay = ROM16(mode_entry[25]) + 1;
- mode->VSyncStart = ROM16(mode_entry[31]) + 1;
- mode->VSyncEnd = ROM16(mode_entry[33]) + 1;
- mode->VTotal = ROM16(mode_entry[35]) + 1;
- mode->Flags |= (mode_entry[37] & 0x10) ? V_PHSYNC : V_NHSYNC;
- mode->Flags |= (mode_entry[37] & 0x1) ? V_PVSYNC : V_NVSYNC;
- /* bytes 38-39 relate to spread spectrum settings
- * bytes 40-43 are something to do with PWM */
-
- return bios->fp.mode_ptr;
-}
-
-int nouveau_bios_parse_lvds_table(ScrnInfoPtr pScrn, int pxclk, bool *dl, bool *if_is_24bit)
-{
- /* The LVDS table header is (mostly) described in
- * parse_lvds_manufacturer_table_header(): the BIT header additionally
- * contains the dual-link transition pxclk (in 10s kHz), at byte 5 - if
- * straps are not being used for the panel, this specifies the frequency
- * at which modes should be set up in the dual link style.
- *
- * Following the header, the BMP (ver 0xa) table has several records,
- * indexed by a seperate xlat table, indexed in turn by the fp strap in
- * EXTDEV_BOOT. Each record had a config byte, followed by 6 script
- * numbers for use by INIT_SUB which controlled panel init and power,
- * and finally a dword of ms to sleep between power off and on
- * operations.
- *
- * In the BIT versions, the table following the header serves as an
- * integrated config and xlat table: the records in the table are
- * indexed by the FP strap nibble in EXTDEV_BOOT, and each record has
- * two bytes - the first as a config byte, the second for indexing the
- * fp mode table pointed to by the BIT 'D' table
- *
- * DDC is not used until after card init, so selecting the correct table
- * entry and setting the dual link flag for EDID equipped panels,
- * requiring tests against the native-mode pixel clock, cannot be done
- * until later, when this function should be called with non-zero pxclk
- */
-
- struct nvbios *bios = &NVPTR(pScrn)->VBIOS;
- int fpstrapping = get_fp_strap(pScrn, bios), lvdsmanufacturerindex = 0;
- struct lvdstableheader lth;
- uint16_t lvdsofs;
- int ret, chip_version = bios->pub.chip_version;
-
- if ((ret = parse_lvds_manufacturer_table_header(pScrn, bios, &lth)))
- return ret;
-
- switch (lth.lvds_ver) {
- case 0x0a: /* pre NV40 */
- lvdsmanufacturerindex = bios->data[bios->fp.fpxlatemanufacturertableptr + fpstrapping];
-
- /* we're done if this isn't the EDID panel case */
- if (!pxclk)
- break;
-
- if (chip_version < 0x25) {
- /* nv17 behaviour */
- /* it seems the old style lvds script pointer is reused
- * to select 18/24 bit colour depth for EDID panels */
- lvdsmanufacturerindex = (bios->legacy.lvds_single_a_script_ptr & 1) ? 2 : 0;
- if (pxclk >= bios->fp.duallink_transition_clk)
- lvdsmanufacturerindex++;
- } else if (chip_version < 0x30) {
- /* nv28 behaviour (off-chip encoder) */
- /* nv28 does a complex dance of first using byte 121 of
- * the EDID to choose the lvdsmanufacturerindex, then
- * later attempting to match the EDID manufacturer and
- * product IDs in a table (signature 'pidt' (panel id
- * table?)), setting an lvdsmanufacturerindex of 0 and
- * an fp strap of the match index (or 0xf if none)
- */
- lvdsmanufacturerindex = 0;
- } else {
- /* nv31, nv34 behaviour */
- lvdsmanufacturerindex = 0;
- if (pxclk >= bios->fp.duallink_transition_clk)
- lvdsmanufacturerindex = 2;
- if (pxclk >= 140000)
- lvdsmanufacturerindex = 3;
- }
-
- /* nvidia set the high nibble of (cr57=f, cr58) to
- * lvdsmanufacturerindex in this case; we don't */
- break;
- case 0x30: /* NV4x */
- case 0x40: /* G80/G90 */
- lvdsmanufacturerindex = fpstrapping;
- break;
- default:
- NV_ERROR(pScrn, "LVDS table revision not currently supported\n");
- return -ENOSYS;
- }
-
- lvdsofs = bios->fp.xlated_entry = bios->fp.lvdsmanufacturerpointer + lth.headerlen + lth.recordlen * lvdsmanufacturerindex;
- switch (lth.lvds_ver) {
- case 0x0a:
- bios->fp.power_off_for_reset = bios->data[lvdsofs] & 1;
- bios->fp.reset_after_pclk_change = bios->data[lvdsofs] & 2;
- bios->fp.dual_link = bios->data[lvdsofs] & 4;
- bios->fp.link_c_increment = bios->data[lvdsofs] & 8;
- *if_is_24bit = bios->data[lvdsofs] & 16;
- break;
- case 0x30:
- /* My money would be on there being a 24 bit interface bit in this table,
- * but I have no example of a laptop bios with a 24 bit panel to confirm that.
- * Hence we shout loudly if any bit other than bit 0 is set (I've not even
- * seen bit 1)
- */
- if (bios->data[lvdsofs] > 1)
- NV_ERROR(pScrn,
- "You have a very unusual laptop display; please report it\n");
- /* no sign of the "power off for reset" or "reset for panel on" bits, but it's safer to assume we should */
- bios->fp.power_off_for_reset = true;
- bios->fp.reset_after_pclk_change = true;
- /* it's ok lvdsofs is wrong for nv4x edid case; dual_link is
- * over-written, and BITbit1 isn't used */
- bios->fp.dual_link = bios->data[lvdsofs] & 1;
- bios->fp.BITbit1 = bios->data[lvdsofs] & 2;
- bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
-#if 0 // currently unused
- break;
- case 0x40:
- /* fairly sure, but not 100% */
- bios->fp.dual_link = bios->data[lvdsofs] & 1;
- bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
- break;
-#endif
- }
-
- /* set dual_link flag for EDID case */
- if (pxclk && (chip_version < 0x25 || chip_version > 0x28))
- bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk);
-
- *dl = bios->fp.dual_link;
-
- return 0;
-}
-
-static int
-find_script_pointers(ScrnInfoPtr pScrn, uint8_t *table, uint16_t *script0,
- uint16_t *script1, uint16_t headerlen, int pxclk)
-{
- /* The output script tables describing a particular output type
- * look as follows:
- *
- * offset + 0 (32 bits): output this table matches (hash of DCB)
- * offset + 4 ( 8 bits): unknown
- * offset + 5 ( 8 bits): number of configurations
- * offset + 6 (16 bits): pointer to some script
- * offset + 8 (16 bits): pointer to some script
- *
- * headerlen == 10
- * offset + 10 : configuration 0
- *
- * headerlen == 12
- * offset + 10 : pointer to some script
- * offset + 12 : configuration 0
- *
- * Each config entry is as follows:
- *
- * offset + 0 (16 bits): unknown, assumed to be a match value
- * offset + 2 (16 bits): pointer to script table (clock set?)
- * offset + 4 (16 bits): pointer to script table (reset?)
- *
- * There doesn't appear to be a count value to say how many
- * entries exist in each script table, instead, a 0 value in
- * the first 16-bit word seems to indicate both the end of the
- * list and the default entry. The second 16-bit word in the
- * script tables is a pointer to the script to execute.
- */
-
- struct nvbios *bios = &NVPTR(pScrn)->VBIOS;
- int i, cmpval = 0x0100;
-
- *script0 = *script1 = 0;
- for (i = 0; i < table[5]; i++) {
- uint16_t offset;
-
- if (ROM16(table[headerlen + i*6 + 0]) != cmpval)
- continue;
-
- offset = ROM16(table[headerlen + i*6 + 2]);
- if (offset)
- *script0 = clkcmptable(bios, offset, pxclk);
-
- if (!*script0)
- NV_WARN(pScrn, "script0 missing!\n");
-
- offset = ROM16(table[headerlen + i*6 + 4]);
- if (offset)
- *script1 = clkcmptable(bios, offset, pxclk);
-
- return 0;
- }
-
- NV_ERROR(pScrn, "couldn't find suitable output scripts\n");
- return 1;
-}
-
-int
-nouveau_bios_run_display_table(ScrnInfoPtr pScrn, struct dcb_entry *dcbent,
- int pxclk)
-{
- /* The display script table is located by the BIT 'U' table.
- *
- * It contains an array of pointers to various tables describing
- * a particular output type. The first 32-bits of the output
- * tables contains similar information to a DCB entry, and is
- * used to decide whether that particular table is suitable for
- * the output you want to access.
- *
- * The "record header length" field here seems to indicate the
- * offset of the first configuration entry in the output tables.
- * This is 10 on most cards I've seen, but 12 has been witnessed
- * on DP cards, and there's another script pointer within the
- * header.
- *
- * offset + 0 ( 8 bits): version
- * offset + 1 ( 8 bits): header length
- * offset + 2 ( 8 bits): record length
- * offset + 3 ( 8 bits): number of records
- * offset + 4 ( 8 bits): record header length
- * offset + 5 (16 bits): pointer to first output script table
- */
-
- NVPtr pNv = NVPTR(pScrn);
- init_exec_t iexec = {true, false};
- struct nvbios *bios = &pNv->VBIOS;
- uint8_t *table = &bios->data[bios->display.script_table_ptr];
- uint8_t *entry, *otable = NULL;
- uint16_t script0, script1;
- int i;
- bool run_scripts = false;
-
- if (!bios->display.script_table_ptr) {
- NV_ERROR(pScrn, "No pointer to output script table\n");
- return 1;
- }
-
- if (table[0] != 0x20) {
- NV_ERROR(pScrn, "Output script table version 0x%02x unknown\n", table[0]);
- return 1;
- }
-
- NV_DEBUG(pScrn, "Searching for output entry for %d %d %d\n",
- dcbent->type, dcbent->location, dcbent->or);
- entry = table + table[1];
- for (i = 0; i < table[3]; i++, entry += table[2]) {
- uint32_t match;
-
- if (ROM16(entry[0]) == 0)
- continue;
- otable = &bios->data[ROM16(entry[0])];
- match = ROM32(otable[0]);
-
- NV_DEBUG(pScrn, " %d: 0x%08x\n", i, match);
- if ((((match & 0x000f0000) >> 16) & dcbent->or) &&
- ((match & 0x0000000f) >> 0) == dcbent->type &&
- ((match & 0x000000f0) >> 4) == dcbent->location)
- break;
- }
-
- if (i == table[3]) {
- NV_ERROR(pScrn, "Couldn't find matching output script table\n");
- return 1;
- }
-
- if (find_script_pointers(pScrn, otable, &script0, &script1, table[4], pxclk))
- return 1;
- bios->display.head = ffs(dcbent->or) - 1;
-
- if (script0) {
- NV_TRACE(pScrn, "0x%04X: Parsing output Script0\n", script0);
- if (run_scripts)
- parse_init_table(pScrn, bios, script0, &iexec);
- }
-
- if (script1) {
- NV_TRACE(pScrn, "0x%04X: Parsing output Script1\n", script1);
- if (run_scripts)
- parse_init_table(pScrn, bios, script1, &iexec);
- }
-
- return run_scripts ? 0 : 1;
-}
-
-int run_tmds_table(ScrnInfoPtr pScrn, struct dcb_entry *dcbent, int head, int pxclk)
-{
- /* the pxclk parameter is in kHz
- *
- * This runs the TMDS regs setting code found on BIT bios cards
- *
- * For ffs(or) == 1 use the first table, for ffs(or) == 2 and
- * ffs(or) == 3, use the second.
- */
-
- NVPtr pNv = NVPTR(pScrn);
- struct nvbios *bios = &pNv->VBIOS;
- int cv = bios->pub.chip_version;
- uint16_t clktable = 0, scriptptr;
- uint32_t sel_clk_binding, sel_clk;
-
- /* pre-nv17 off-chip tmds uses scripts, post nv17 doesn't */
- if (cv >= 0x17 && cv != 0x1a && cv != 0x20 &&
- dcbent->location != DCB_LOC_ON_CHIP)
- return 0;
-
- switch (ffs(dcbent->or)) {
- case 1:
- clktable = bios->tmds.output0_script_ptr;
- break;
- case 2:
- case 3:
- clktable = bios->tmds.output1_script_ptr;
- break;
- }
-
- if (!clktable) {
- NV_ERROR(pScrn, "Pixel clock comparison table not found\n");
- return -EINVAL;
- }
-
- scriptptr = clkcmptable(bios, clktable, pxclk);
-
- if (!scriptptr) {
- NV_ERROR(pScrn, "TMDS output init script not found\n");
- return -ENOENT;
- }
-
- /* don't let script change pll->head binding */
- sel_clk_binding = bios_rd32(pScrn, NV_PRAMDAC_SEL_CLK) & 0x50000;
- run_digital_op_script(pScrn, scriptptr, dcbent, head, pxclk >= 165000);
- sel_clk = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000;
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding);
-
- return 0;
-}
-
-int get_pll_limits(ScrnInfoPtr pScrn, uint32_t limit_match, struct pll_lims *pll_lim)
-{
- /* PLL limits table
- *
- * Version 0x10: NV30, NV31
- * One byte header (version), one record of 24 bytes
- * Version 0x11: NV36 - Not implemented
- * Seems to have same record style as 0x10, but 3 records rather than 1
- * Version 0x20: Found on Geforce 6 cards
- * Trivial 4 byte BIT header. 31 (0x1f) byte record length
- * Version 0x21: Found on Geforce 7, 8 and some Geforce 6 cards
- * 5 byte header, fifth byte of unknown purpose. 35 (0x23) byte record
- * length in general, some (integrated) have an extra configuration byte
- * Version 0x30: Found on Geforce 8, separates the register mapping
- * from the limits tables.
- */
-
- NVPtr pNv = NVPTR(pScrn);
- struct nvbios *bios = &pNv->VBIOS;
- int cv = bios->pub.chip_version, pllindex = 0;
- uint8_t pll_lim_ver = 0, headerlen = 0, recordlen = 0, entries = 0;
- uint32_t crystal_strap_mask, crystal_straps;
-
- if (!bios->pll_limit_tbl_ptr) {
- if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
- cv >= 0x40) {
- NV_ERROR(pScrn, "Pointer to PLL limits table invalid\n");
- return -EINVAL;
- }
- } else
- pll_lim_ver = bios->data[bios->pll_limit_tbl_ptr];
-
- crystal_strap_mask = 1 << 6;
- /* open coded pNv->twoHeads test */
- if (cv > 0x10 && cv != 0x15 && cv != 0x1a && cv != 0x20)
- crystal_strap_mask |= 1 << 22;
- crystal_straps = nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & crystal_strap_mask;
-
- switch (pll_lim_ver) {
- /* we use version 0 to indicate a pre limit table bios (single stage pll)
- * and load the hard coded limits instead */
- case 0:
- break;
- case 0x10:
- case 0x11: /* strictly v0x11 has 3 entries, but the last two don't seem to get used */
- headerlen = 1;
- recordlen = 0x18;
- entries = 1;
- pllindex = 0;
- break;
- case 0x20:
- case 0x21:
- case 0x30:
- headerlen = bios->data[bios->pll_limit_tbl_ptr + 1];
- recordlen = bios->data[bios->pll_limit_tbl_ptr + 2];
- entries = bios->data[bios->pll_limit_tbl_ptr + 3];
- break;
- default:
- NV_ERROR(pScrn, "PLL limits table revision 0x%X not currently "
- "supported\n", pll_lim_ver);
- return -ENOSYS;
- }
-
- /* initialize all members to zero */
- memset(pll_lim, 0, sizeof(struct pll_lims));
-
- if (pll_lim_ver == 0x10 || pll_lim_ver == 0x11) {
- uint8_t *pll_rec = &bios->data[bios->pll_limit_tbl_ptr + headerlen + recordlen * pllindex];
-
- pll_lim->vco1.minfreq = ROM32(pll_rec[0]);
- pll_lim->vco1.maxfreq = ROM32(pll_rec[4]);
- pll_lim->vco2.minfreq = ROM32(pll_rec[8]);
- pll_lim->vco2.maxfreq = ROM32(pll_rec[12]);
- pll_lim->vco1.min_inputfreq = ROM32(pll_rec[16]);
- pll_lim->vco2.min_inputfreq = ROM32(pll_rec[20]);
- pll_lim->vco1.max_inputfreq = pll_lim->vco2.max_inputfreq = INT_MAX;
-
- /* these values taken from nv30/31/36 */
- pll_lim->vco1.min_n = 0x1;
- if (cv == 0x36)
- pll_lim->vco1.min_n = 0x5;
- pll_lim->vco1.max_n = 0xff;
- pll_lim->vco1.min_m = 0x1;
- pll_lim->vco1.max_m = 0xd;
- pll_lim->vco2.min_n = 0x4;
- /* on nv30, 31, 36 (i.e. all cards with two stage PLLs with this
- * table version (apart from nv35)), N2 is compared to
- * maxN2 (0x46) and 10 * maxM2 (0x4), so set maxN2 to 0x28 and
- * save a comparison
- */
- pll_lim->vco2.max_n = 0x28;
- if (cv == 0x30 || cv == 0x35)
- /* only 5 bits available for N2 on nv30/35 */
- pll_lim->vco2.max_n = 0x1f;
- pll_lim->vco2.min_m = 0x1;
- pll_lim->vco2.max_m = 0x4;
- pll_lim->max_log2p = 0x7;
- pll_lim->max_usable_log2p = 0x6;
- } else if (pll_lim_ver == 0x20 || pll_lim_ver == 0x21) {
- uint16_t plloffs = bios->pll_limit_tbl_ptr + headerlen;
- uint32_t reg = 0; /* default match */
- uint8_t *pll_rec;
- int i;
-
- /* first entry is default match, if nothing better. warn if reg field nonzero */
- if (ROM32(bios->data[plloffs]))
- NV_WARN(pScrn, "Default PLL limit entry has non-zero "
- "register field\n");
-
- if (limit_match > MAX_PLL_TYPES)
- /* we've been passed a reg as the match */
- reg = limit_match;
- else /* limit match is a pll type */
- for (i = 1; i < entries && !reg; i++) {
- uint32_t cmpreg = ROM32(bios->data[plloffs + recordlen * i]);
-
- if (limit_match == NVPLL &&
- (cmpreg == NV_PRAMDAC_NVPLL_COEFF || cmpreg == 0x4000))
- reg = cmpreg;
- if (limit_match == MPLL &&
- (cmpreg == NV_PRAMDAC_MPLL_COEFF || cmpreg == 0x4020))
- reg = cmpreg;
- if (limit_match == VPLL1 &&
- (cmpreg == NV_PRAMDAC_VPLL_COEFF || cmpreg == 0x4010))
- reg = cmpreg;
- if (limit_match == VPLL2 &&
- (cmpreg == NV_RAMDAC_VPLL2 || cmpreg == 0x4018))
- reg = cmpreg;
- }
-
- for (i = 1; i < entries; i++)
- if (ROM32(bios->data[plloffs + recordlen * i]) == reg) {
- pllindex = i;
- break;
- }
-
- pll_rec = &bios->data[plloffs + recordlen * pllindex];
-
- BIOSLOG(pScrn, "Loading PLL limits for reg 0x%08x\n", pllindex ? reg : 0);
-
- /* frequencies are stored in tables in MHz, kHz are more useful, so we convert */
-
- /* What output frequencies can each VCO generate? */
- pll_lim->vco1.minfreq = ROM16(pll_rec[4]) * 1000;
- pll_lim->vco1.maxfreq = ROM16(pll_rec[6]) * 1000;
- pll_lim->vco2.minfreq = ROM16(pll_rec[8]) * 1000;
- pll_lim->vco2.maxfreq = ROM16(pll_rec[10]) * 1000;
-
- /* What input frequencies do they accept (past the m-divider)? */
- pll_lim->vco1.min_inputfreq = ROM16(pll_rec[12]) * 1000;
- pll_lim->vco2.min_inputfreq = ROM16(pll_rec[14]) * 1000;
- pll_lim->vco1.max_inputfreq = ROM16(pll_rec[16]) * 1000;
- pll_lim->vco2.max_inputfreq = ROM16(pll_rec[18]) * 1000;
-
- /* What values are accepted as multiplier and divider? */
- pll_lim->vco1.min_n = pll_rec[20];
- pll_lim->vco1.max_n = pll_rec[21];
- pll_lim->vco1.min_m = pll_rec[22];
- pll_lim->vco1.max_m = pll_rec[23];
- pll_lim->vco2.min_n = pll_rec[24];
- pll_lim->vco2.max_n = pll_rec[25];
- pll_lim->vco2.min_m = pll_rec[26];
- pll_lim->vco2.max_m = pll_rec[27];
-
- pll_lim->max_usable_log2p = pll_lim->max_log2p = pll_rec[29];
- if (pll_lim->max_log2p > 0x7)
- /* pll decoding in nv_hw.c assumes never > 7 */
- NV_WARN(pScrn, "Max log2 P value greater than 7 (%d)\n",
- pll_lim->max_log2p);
- if (cv < 0x60)
- pll_lim->max_usable_log2p = 0x6;
- pll_lim->log2p_bias = pll_rec[30];
-
- if (recordlen > 0x22)
- pll_lim->refclk = ROM32(pll_rec[31]);
-
- if (recordlen > 0x23 && pll_rec[35])
- NV_WARN(pScrn,
- "Bits set in PLL configuration byte (%x)\n",
- pll_rec[35]);
-
- /* C51 special not seen elsewhere */
- if (cv == 0x51 && !pll_lim->refclk) {
- uint32_t sel_clk = bios_rd32(pScrn, NV_PRAMDAC_SEL_CLK);
-
- if (((limit_match == NV_PRAMDAC_VPLL_COEFF || limit_match == VPLL1) && sel_clk & 0x20) ||
- ((limit_match == NV_RAMDAC_VPLL2 || limit_match == VPLL2) && sel_clk & 0x80)) {
- if (bios_idxprt_rd(pScrn, NV_CIO_CRX__COLOR, NV_CIO_CRE_CHIP_ID_INDEX) < 0xa3)
- pll_lim->refclk = 200000;
- else
- pll_lim->refclk = 25000;
- }
- }
- } else if (pll_lim_ver) { /* ver 0x30 */
- uint8_t *entry = &bios->data[bios->pll_limit_tbl_ptr + headerlen];
- uint8_t *record = NULL;
- int i;
-
- BIOSLOG(pScrn, "Loading PLL limits for register 0x%08x\n",
- limit_match);
-
- for (i = 0; i < entries; i++, entry += recordlen) {
- if (ROM32(entry[3]) == limit_match) {
- record = &bios->data[ROM16(entry[1])];
- break;
- }
- }
-
- if (!record) {
- NV_ERROR(pScrn, "Register 0x%08x not found in PLL "
- "limits table", limit_match);
- return -ENOENT;
- }
-
- pll_lim->vco1.minfreq = ROM16(record[0]) * 1000;
- pll_lim->vco1.maxfreq = ROM16(record[2]) * 1000;
- pll_lim->vco2.minfreq = ROM16(record[4]) * 1000;
- pll_lim->vco2.maxfreq = ROM16(record[6]) * 1000;
- pll_lim->vco1.min_inputfreq = ROM16(record[8]) * 1000;
- pll_lim->vco2.min_inputfreq = ROM16(record[10]) * 1000;
- pll_lim->vco1.max_inputfreq = ROM16(record[12]) * 1000;
- pll_lim->vco2.max_inputfreq = ROM16(record[14]) * 1000;
- pll_lim->vco1.min_n = record[16];
- pll_lim->vco1.max_n = record[17];
- pll_lim->vco1.min_m = record[18];
- pll_lim->vco1.max_m = record[19];
- pll_lim->vco2.min_n = record[20];
- pll_lim->vco2.max_n = record[21];
- pll_lim->vco2.min_m = record[22];
- pll_lim->vco2.max_m = record[23];
- pll_lim->max_usable_log2p = pll_lim->max_log2p = record[25];
- pll_lim->log2p_bias = record[27];
- pll_lim->refclk = ROM32(record[28]);
- }
-
- /* By now any valid limit table ought to have set a max frequency for
- * vco1, so if it's zero it's either a pre limit table bios, or one
- * with an empty limit table (seen on nv18)
- */
- if (!pll_lim->vco1.maxfreq) {
- pll_lim->vco1.minfreq = bios->fminvco;
- pll_lim->vco1.maxfreq = bios->fmaxvco;
- pll_lim->vco1.min_inputfreq = 0;
- pll_lim->vco1.max_inputfreq = INT_MAX;
- pll_lim->vco1.min_n = 0x1;
- pll_lim->vco1.max_n = 0xff;
- pll_lim->vco1.min_m = 0x1;
- if (crystal_straps == 0) {
- /* nv05 does this, nv11 doesn't, nv10 unknown */
- if (cv < 0x11)
- pll_lim->vco1.min_m = 0x7;
- pll_lim->vco1.max_m = 0xd;
- } else {
- if (cv < 0x11)
- pll_lim->vco1.min_m = 0x8;
- pll_lim->vco1.max_m = 0xe;
- }
- if (cv < 0x17 || cv == 0x1a || cv == 0x20)
- pll_lim->max_log2p = 4;
- else
- pll_lim->max_log2p = 5;
- pll_lim->max_usable_log2p = pll_lim->max_log2p;
- }
-
- if (!pll_lim->refclk)
- switch (crystal_straps) {
- case 0:
- pll_lim->refclk = 13500;
- break;
- case (1 << 6):
- pll_lim->refclk = 14318;
- break;
- case (1 << 22):
- pll_lim->refclk = 27000;
- break;
- case (1 << 22 | 1 << 6):
- pll_lim->refclk = 25000;
- break;
- }
-
-#if 0 /* for easy debugging */
- ErrorF("pll.vco1.minfreq: %d\n", pll_lim->vco1.minfreq);
- ErrorF("pll.vco1.maxfreq: %d\n", pll_lim->vco1.maxfreq);
- ErrorF("pll.vco2.minfreq: %d\n", pll_lim->vco2.minfreq);
- ErrorF("pll.vco2.maxfreq: %d\n", pll_lim->vco2.maxfreq);
-
- ErrorF("pll.vco1.min_inputfreq: %d\n", pll_lim->vco1.min_inputfreq);
- ErrorF("pll.vco1.max_inputfreq: %d\n", pll_lim->vco1.max_inputfreq);
- ErrorF("pll.vco2.min_inputfreq: %d\n", pll_lim->vco2.min_inputfreq);
- ErrorF("pll.vco2.max_inputfreq: %d\n", pll_lim->vco2.max_inputfreq);
-
- ErrorF("pll.vco1.min_n: %d\n", pll_lim->vco1.min_n);
- ErrorF("pll.vco1.max_n: %d\n", pll_lim->vco1.max_n);
- ErrorF("pll.vco1.min_m: %d\n", pll_lim->vco1.min_m);
- ErrorF("pll.vco1.max_m: %d\n", pll_lim->vco1.max_m);
- ErrorF("pll.vco2.min_n: %d\n", pll_lim->vco2.min_n);
- ErrorF("pll.vco2.max_n: %d\n", pll_lim->vco2.max_n);
- ErrorF("pll.vco2.min_m: %d\n", pll_lim->vco2.min_m);
- ErrorF("pll.vco2.max_m: %d\n", pll_lim->vco2.max_m);
-
- ErrorF("pll.max_log2p: %d\n", pll_lim->max_log2p);
- ErrorF("pll.log2p_bias: %d\n", pll_lim->log2p_bias);
-
- ErrorF("pll.refclk: %d\n", pll_lim->refclk);
-#endif
-
- return 0;
-}
-
-static void parse_bios_version(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t offset)
-{
- /* offset + 0 (8 bits): Micro version
- * offset + 1 (8 bits): Minor version
- * offset + 2 (8 bits): Chip version
- * offset + 3 (8 bits): Major version
- */
-
- bios->major_version = bios->data[offset + 3];
- bios->pub.chip_version = bios->data[offset + 2];
- NV_TRACE(pScrn, "Bios version %02x.%02x.%02x.%02x\n",
- bios->data[offset + 3], bios->data[offset + 2],
- bios->data[offset + 1], bios->data[offset]);
-}
-
-static void parse_script_table_pointers(struct nvbios *bios, uint16_t offset)
-{
- /* Parses the init table segment for pointers used in script execution.
- *
- * offset + 0 (16 bits): init script tables pointer
- * offset + 2 (16 bits): macro index table pointer
- * offset + 4 (16 bits): macro table pointer
- * offset + 6 (16 bits): condition table pointer
- * offset + 8 (16 bits): io condition table pointer
- * offset + 10 (16 bits): io flag condition table pointer
- * offset + 12 (16 bits): init function table pointer
- */
-
- bios->init_script_tbls_ptr = ROM16(bios->data[offset]);
- bios->macro_index_tbl_ptr = ROM16(bios->data[offset + 2]);
- bios->macro_tbl_ptr = ROM16(bios->data[offset + 4]);
- bios->condition_tbl_ptr = ROM16(bios->data[offset + 6]);
- bios->io_condition_tbl_ptr = ROM16(bios->data[offset + 8]);
- bios->io_flag_condition_tbl_ptr = ROM16(bios->data[offset + 10]);
- bios->init_function_tbl_ptr = ROM16(bios->data[offset + 12]);
-}
-
-static int parse_bit_A_tbl_entry(ScrnInfoPtr pScrn, struct nvbios *bios, bit_entry_t *bitentry)
-{
- /* Parses the load detect values for g80 cards.
- *
- * offset + 0 (16 bits): loadval table pointer
- */
-
- uint16_t load_table_ptr;
- uint8_t version, headerlen, entrylen, num_entries;
-
- if (bitentry->length != 3) {
- NV_ERROR(pScrn, "Do not understand BIT A table\n");
- return -EINVAL;
- }
-
- load_table_ptr = ROM16(bios->data[bitentry->offset]);
-
- if (load_table_ptr == 0x0) {
- NV_ERROR(pScrn, "Pointer to BIT loadval table invalid\n");
- return -EINVAL;
- }
-
- version = bios->data[load_table_ptr];
-
- if (version != 0x10) {
- NV_ERROR(pScrn, "BIT loadval table version %d.%d not supported\n",
- version >> 4, version & 0xF);
- return -ENOSYS;
- }
-
- headerlen = bios->data[load_table_ptr + 1];
- entrylen = bios->data[load_table_ptr + 2];
- num_entries = bios->data[load_table_ptr + 3];
-
- if (headerlen != 4 || entrylen != 4 || num_entries != 2) {
- NV_ERROR(pScrn, "Do not understand BIT loadval table\n");
- return -EINVAL;
- }
-
- /* First entry is normal dac, 2nd tv-out perhaps? */
- bios->pub.dactestval = ROM32(bios->data[load_table_ptr + headerlen]) & 0x3ff;
-
- return 0;
-}
-
-static int parse_bit_C_tbl_entry(ScrnInfoPtr pScrn, struct nvbios *bios, bit_entry_t *bitentry)
-{
- /* offset + 8 (16 bits): PLL limits table pointer
- *
- * There's more in here, but that's unknown.
- */
-
- if (bitentry->length < 10) {
- NV_ERROR(pScrn, "Do not understand BIT C table\n");
- return -EINVAL;
- }
-
- bios->pll_limit_tbl_ptr = ROM16(bios->data[bitentry->offset + 8]);
-
- return 0;
-}
-
-static int parse_bit_display_tbl_entry(ScrnInfoPtr pScrn, struct nvbios *bios, bit_entry_t *bitentry)
-{
- /* Parses the flat panel table segment that the bit entry points to.
- * Starting at bitentry->offset:
- *
- * offset + 0 (16 bits): ??? table pointer - seems to have 18 byte records beginning with a freq
- * offset + 2 (16 bits): mode table pointer
- */
-
- if (bitentry->length != 4) {
- NV_ERROR(pScrn, "Do not understand BIT display table\n");
- return -EINVAL;
- }
-
- bios->fp.fptablepointer = ROM16(bios->data[bitentry->offset + 2]);
-
- return 0;
-}
-
-static int parse_bit_init_tbl_entry(ScrnInfoPtr pScrn, struct nvbios *bios, bit_entry_t *bitentry)
-{
- /* Parses the init table segment that the bit entry points to.
- *
- * See parse_script_table_pointers for layout
- */
-
- if (bitentry->length < 14) {
- NV_ERROR(pScrn, "Do not understand init table\n");
- return -EINVAL;
- }
-
- parse_script_table_pointers(bios, bitentry->offset);
-
- return 0;
-}
-
-static int parse_bit_i_tbl_entry(ScrnInfoPtr pScrn, struct nvbios *bios, bit_entry_t *bitentry)
-{
- /* BIT 'i' (info?) table
- *
- * offset + 0 (32 bits): BIOS version dword (as in B table)
- * offset + 5 (8 bits): BIOS feature byte (same as for BMP?)
- * offset + 13 (16 bits): pointer to table containing DAC load detection comparison values
- *
- * There's other things in the table, purpose unknown
- */
-
- uint16_t daccmpoffset;
- uint8_t dacver, dacheaderlen;
-
- if (bitentry->length < 6) {
- NV_ERROR(pScrn, "BIT i table too short for needed information\n");
- return -EINVAL;
- }
-
- parse_bios_version(pScrn, bios, bitentry->offset);
-
- /* bit 4 seems to indicate a mobile bios (doesn't suffer from BMP's
- * Quadro identity crisis), other bits possibly as for BMP feature byte
- */
- bios->feature_byte = bios->data[bitentry->offset + 5];
- bios->is_mobile = bios->feature_byte & FEATURE_MOBILE;
-
- if (bitentry->length < 15) {
- NV_WARN(pScrn, "BIT i table not long enough for DAC load "
- "detection comparison table\n");
- return -EINVAL;
- }
-
- daccmpoffset = ROM16(bios->data[bitentry->offset + 13]);
-
- /* doesn't exist on g80 */
- if (!daccmpoffset)
- return 0;
-
- /* The first value in the table, following the header, is the comparison value
- * Purpose of subsequent values unknown -- TV load detection?
- */
-
- dacver = bios->data[daccmpoffset];
- dacheaderlen = bios->data[daccmpoffset + 1];
-
- if (dacver != 0x00 && dacver != 0x10) {
- NV_WARN(pScrn, "DAC load detection comparison table version "
- "%d.%d not known\n", dacver >> 4, dacver & 0xf);
- return -ENOSYS;
- }
-
- bios->pub.dactestval = ROM32(bios->data[daccmpoffset + dacheaderlen]);
-
- return 0;
-}
-
-static int parse_bit_lvds_tbl_entry(ScrnInfoPtr pScrn, struct nvbios *bios, bit_entry_t *bitentry)
-{
- /* Parses the LVDS table segment that the bit entry points to.
- * Starting at bitentry->offset:
- *
- * offset + 0 (16 bits): LVDS strap xlate table pointer
- */
-
- if (bitentry->length != 2) {
- NV_ERROR(pScrn, "Do not understand BIT LVDS table\n");
- return -EINVAL;
- }
-
- /* no idea if it's still called the LVDS manufacturer table, but the concept's close enough */
- bios->fp.lvdsmanufacturerpointer = ROM16(bios->data[bitentry->offset]);
-
- return 0;
-}
-
-static int parse_bit_M_tbl_entry(ScrnInfoPtr pScrn, struct nvbios *bios, bit_entry_t *bitentry)
-{
- /* offset + 2 (8 bits): number of options in an INIT_RAM_RESTRICT_ZM_REG_GROUP opcode option set
- * offset + 3 (16 bits): pointer to strap xlate table for RAM restrict option selection
- *
- * There's a bunch of bits in this table other than the RAM restrict
- * stuff that we don't use - their use currently unknown
- */
-
- int i;
-
- /* Older bios versions don't have a sufficiently long table for what we want */
- if (bitentry->length < 0x5)
- return 0;
-
- /* set up multiplier for INIT_RAM_RESTRICT_ZM_REG_GROUP */
- for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != 0x8f); i++)
- ;
- itbl_entry[i].length_multiplier = bios->data[bitentry->offset + 2] * 4;
- init_ram_restrict_zm_reg_group_blocklen = itbl_entry[i].length_multiplier;
-
- bios->ram_restrict_tbl_ptr = ROM16(bios->data[bitentry->offset + 3]);
-
- return 0;
-}
-
-static int parse_bit_tmds_tbl_entry(ScrnInfoPtr pScrn, struct nvbios *bios, bit_entry_t *bitentry)
-{
- /* Parses the pointer to the TMDS table
- *
- * Starting at bitentry->offset:
- *
- * offset + 0 (16 bits): TMDS table pointer
- *
- * The TMDS table is typically found just before the DCB table, with a
- * characteristic signature of 0x11,0x13 (1.1 being version, 0x13 being
- * length?)
- *
- * At offsets +7 and +9 are pointers to scripts, which (when not
- * stubbed) seem to be called from the main init tables at POST
- * Offset +11 has a pointer to a table where the first word is a pxclk
- * frequency and the second word a pointer to a script, which should be
- * run if the comparison pxclk frequency is less than the pxclk desired.
- * This repeats for decreasing comparison frequencies
- * Offset +13 has a pointer to a similar table
- * The selection of table (and possibly +7/+9 script) is dictated by
- * "or" from the DCB.
- */
-
- uint16_t tmdstableptr;
-
- if (bitentry->length != 2) {
- NV_ERROR(pScrn, "Do not understand BIT TMDS table\n");
- return -EINVAL;
- }
-
- tmdstableptr = ROM16(bios->data[bitentry->offset]);
-
- if (tmdstableptr == 0x0) {
- NV_ERROR(pScrn, "Pointer to TMDS table invalid\n");
- return -EINVAL;
- }
-
- /* nv50+ has v2.0, but we don't parse it atm */
- if (bios->data[tmdstableptr] != 0x11) {
- NV_WARN(pScrn,
- "TMDS table revision %d.%d not currently supported\n",
- bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf);
- return -ENOSYS;
- }
-
- bios->tmds.output0_script_ptr = ROM16(bios->data[tmdstableptr + 11]);
- bios->tmds.output1_script_ptr = ROM16(bios->data[tmdstableptr + 13]);
-
- return 0;
-}
-
-static int
-parse_bit_U_tbl_entry(ScrnInfoPtr pScrn, struct nvbios *bios,
- bit_entry_t *bitentry)
-{
- /* Parses the pointer to the G80 output script tables
- *
- * Starting at bitentry->offset:
- *
- * offset + 0 (16 bits): output script table pointer
- */
-
- uint16_t outputscripttableptr;
-
- if (bitentry->length != 3) {
- NV_ERROR(pScrn, "Do not understand BIT U table\n");
- return -EINVAL;
- }
-
- outputscripttableptr = ROM16(bios->data[bitentry->offset]);
- bios->display.script_table_ptr = outputscripttableptr;
- return 0;
-}
-
-struct bit_table {
- const char id;
- int (* const parse_fn)(ScrnInfoPtr, struct nvbios *, bit_entry_t *);
-};
-
-#define BIT_TABLE(id, funcid) ((struct bit_table){ id, parse_bit_##funcid##_tbl_entry })
-
-static int parse_bit_table(ScrnInfoPtr pScrn, struct nvbios *bios, const uint16_t bitoffset, struct bit_table *table)
-{
- uint8_t maxentries = bios->data[bitoffset + 4];
- int i, offset;
- bit_entry_t bitentry;
-
- for (i = 0, offset = bitoffset + 6; i < maxentries; i++, offset += 6) {
- bitentry.id[0] = bios->data[offset];
-
- if (bitentry.id[0] != table->id)
- continue;
-
- bitentry.id[1] = bios->data[offset + 1];
- bitentry.length = ROM16(bios->data[offset + 2]);
- bitentry.offset = ROM16(bios->data[offset + 4]);
-
- return table->parse_fn(pScrn, bios, &bitentry);
- }
-
- NV_ERROR(pScrn, "BIT table '%c' not found\n", table->id);
-
- return -ENOSYS;
-}
-
-static int parse_bit_structure(ScrnInfoPtr pScrn, struct nvbios *bios, const uint16_t bitoffset)
-{
- int ret;
-
- /* the only restriction on parsing order currently is having 'i' first
- * for use of bios->*_version or bios->feature_byte while parsing;
- * functions shouldn't be actually *doing* anything apart from pulling
- * data from the image into the bios struct, thus no interdependencies
- */
- if ((ret = parse_bit_table(pScrn, bios, bitoffset, &BIT_TABLE('i', i)))) /* info? */
- return ret;
- if (bios->major_version >= 0x60) /* g80+ */
- parse_bit_table(pScrn, bios, bitoffset, &BIT_TABLE('A', A));
- if ((ret = parse_bit_table(pScrn, bios, bitoffset, &BIT_TABLE('C', C))))
- return ret;
- parse_bit_table(pScrn, bios, bitoffset, &BIT_TABLE('D', display));
- if ((ret = parse_bit_table(pScrn, bios, bitoffset, &BIT_TABLE('I', init))))
- return ret;
- parse_bit_table(pScrn, bios, bitoffset, &BIT_TABLE('M', M)); /* memory? */
- parse_bit_table(pScrn, bios, bitoffset, &BIT_TABLE('L', lvds));
- parse_bit_table(pScrn, bios, bitoffset, &BIT_TABLE('T', tmds));
- parse_bit_table(pScrn, bios, bitoffset, &BIT_TABLE('U', U));
-
- return 0;
-}
-
-static int parse_bmp_structure(ScrnInfoPtr pScrn, struct nvbios *bios, unsigned int offset)
-{
- /* Parses the BMP structure for useful things, but does not act on them
- *
- * offset + 5: BMP major version
- * offset + 6: BMP minor version
- * offset + 9: BMP feature byte
- * offset + 10: BCD encoded BIOS version
- *
- * offset + 18: init script table pointer (for bios versions < 5.10h)
- * offset + 20: extra init script table pointer (for bios versions < 5.10h)
- *
- * offset + 24: memory init table pointer (used on early bios versions)
- * offset + 26: SDR memory sequencing setup data table
- * offset + 28: DDR memory sequencing setup data table
- *
- * offset + 54: index of I2C CRTC pair to use for CRT output
- * offset + 55: index of I2C CRTC pair to use for TV output
- * offset + 56: index of I2C CRTC pair to use for flat panel output
- * offset + 58: write CRTC index for I2C pair 0
- * offset + 59: read CRTC index for I2C pair 0
- * offset + 60: write CRTC index for I2C pair 1
- * offset + 61: read CRTC index for I2C pair 1
- *
- * offset + 67: maximum internal PLL frequency (single stage PLL)
- * offset + 71: minimum internal PLL frequency (single stage PLL)
- *
- * offset + 75: script table pointers, as described in parse_script_table_pointers
- *
- * offset + 89: TMDS single link output A table pointer
- * offset + 91: TMDS single link output B table pointer
- * offset + 95: LVDS single link output A table pointer
- * offset + 105: flat panel timings table pointer
- * offset + 107: flat panel strapping translation table pointer
- * offset + 117: LVDS manufacturer panel config table pointer
- * offset + 119: LVDS manufacturer strapping translation table pointer
- *
- * offset + 142: PLL limits table pointer
- *
- * offset + 156: minimum pixel clock for LVDS dual link
- */
-
- uint8_t *bmp = &bios->data[offset], bmp_version_major, bmp_version_minor;
- uint16_t bmplength;
- uint16_t legacy_scripts_offset, legacy_i2c_offset;
-
- /* load needed defaults in case we can't parse this info */
- bios->bdcb.dcb.i2c[0].write = NV_CIO_CRE_DDC_WR__INDEX;
- bios->bdcb.dcb.i2c[0].read = NV_CIO_CRE_DDC_STATUS__INDEX;
- bios->bdcb.dcb.i2c[1].write = NV_CIO_CRE_DDC0_WR__INDEX;
- bios->bdcb.dcb.i2c[1].read = NV_CIO_CRE_DDC0_STATUS__INDEX;
- bios->pub.digital_min_front_porch = 0x4b;
- bios->fmaxvco = 256000;
- bios->fminvco = 128000;
- bios->fp.duallink_transition_clk = 90000;
-
- bmp_version_major = bmp[5];
- bmp_version_minor = bmp[6];
-
- NV_TRACE(pScrn, "BMP version %d.%d\n",
- bmp_version_major, bmp_version_minor);
-
- /* Make sure that 0x36 is blank and can't be mistaken for a DCB pointer on early versions */
- if (bmp_version_major < 5)
- *(uint16_t *)&bios->data[0x36] = 0;
-
- /* Seems that the minor version was 1 for all major versions prior to 5 */
- /* Version 6 could theoretically exist, but I suspect BIT happened instead */
- if ((bmp_version_major < 5 && bmp_version_minor != 1) || bmp_version_major > 5) {
- NV_ERROR(pScrn, "You have an unsupported BMP version. "
- "Please send in your bios\n");
- return -ENOSYS;
- }
-
- if (bmp_version_major == 0) /* nothing that's currently useful in this version */
- return 0;
- else if (bmp_version_major == 1)
- bmplength = 44; /* exact for 1.01 */
- else if (bmp_version_major == 2)
- bmplength = 48; /* exact for 2.01 */
- else if (bmp_version_major == 3)
- bmplength = 54; /* guessed - mem init tables added in this version */
- else if (bmp_version_major == 4 || bmp_version_minor < 0x1) /* don't know if 5.0 exists... */
- bmplength = 62; /* guessed - BMP I2C indices added in version 4*/
- else if (bmp_version_minor < 0x6)
- bmplength = 67; /* exact for 5.01 */
- else if (bmp_version_minor < 0x10)
- bmplength = 75; /* exact for 5.06 */
- else if (bmp_version_minor == 0x10)
- bmplength = 89; /* exact for 5.10h */
- else if (bmp_version_minor < 0x14)
- bmplength = 118; /* exact for 5.11h */
- else if (bmp_version_minor < 0x24) /* not sure of version where pll limits came in;
- * certainly exist by 0x24 though */
- /* length not exact: this is long enough to get lvds members */
- bmplength = 123;
- else if (bmp_version_minor < 0x27)
- /* length not exact: this is long enough to get pll limit member */
- bmplength = 144;
- else
- /* length not exact: this is long enough to get dual link transition clock */
- bmplength = 158;
-
- /* checksum */
- if (nv_cksum(bmp, 8)) {
- NV_ERROR(pScrn, "Bad BMP checksum\n");
- return -EINVAL;
- }
-
- /* bit 4 seems to indicate either a mobile bios or a quadro card --
- * mobile behaviour consistent (nv11+), quadro only seen nv18gl-nv36gl
- * (not nv10gl), bit 5 that the flat panel tables are present, and
- * bit 6 a tv bios */
- bios->feature_byte = bmp[9];
-
- parse_bios_version(pScrn, bios, offset + 10);
-
- if (bmp_version_major < 5 || bmp_version_minor < 0x10)
- bios->old_style_init = true;
- legacy_scripts_offset = 18;
- if (bmp_version_major < 2)
- legacy_scripts_offset -= 4;
- bios->init_script_tbls_ptr = ROM16(bmp[legacy_scripts_offset]);
- bios->extra_init_script_tbl_ptr = ROM16(bmp[legacy_scripts_offset + 2]);
-
- if (bmp_version_major > 2) { /* appears in BMP 3 */
- bios->legacy.mem_init_tbl_ptr = ROM16(bmp[24]);
- bios->legacy.sdr_seq_tbl_ptr = ROM16(bmp[26]);
- bios->legacy.ddr_seq_tbl_ptr = ROM16(bmp[28]);
- }
-
- legacy_i2c_offset = 0x48; /* BMP version 2 & 3 */
- if (bmplength > 61)
- legacy_i2c_offset = offset + 54;
- bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset];
- bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1];
- bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2];
- /* don't overwrite defaults with zero (mac braindamage) */
- if (bios->data[legacy_i2c_offset + 4])
- bios->bdcb.dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4];
- if (bios->data[legacy_i2c_offset + 5])
- bios->bdcb.dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5];
- if (bios->data[legacy_i2c_offset + 6])
- bios->bdcb.dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6];
- if (bios->data[legacy_i2c_offset + 7])
- bios->bdcb.dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7];
-
- if (bmplength > 74) {
- bios->fmaxvco = ROM32(bmp[67]);
- bios->fminvco = ROM32(bmp[71]);
- }
- if (bmplength > 88)
- parse_script_table_pointers(bios, offset + 75);
- if (bmplength > 94) {
- bios->tmds.output0_script_ptr = ROM16(bmp[89]);
- bios->tmds.output1_script_ptr = ROM16(bmp[91]);
- /* never observed in use with lvds scripts, but is reused for
- * 18/24 bit panel interface default for EDID equipped panels
- * (if_is_24bit not set directly to avoid any oscillation) */
- bios->legacy.lvds_single_a_script_ptr = ROM16(bmp[95]);
- }
- if (bmplength > 108) {
- bios->fp.fptablepointer = ROM16(bmp[105]);
- bios->fp.fpxlatetableptr = ROM16(bmp[107]);
- bios->fp.xlatwidth = 1;
- }
- if (bmplength > 120) {
- bios->fp.lvdsmanufacturerpointer = ROM16(bmp[117]);
- bios->fp.fpxlatemanufacturertableptr = ROM16(bmp[119]);
- }
- if (bmplength > 143)
- bios->pll_limit_tbl_ptr = ROM16(bmp[142]);
-
- if (bmplength > 157)
- bios->fp.duallink_transition_clk = ROM16(bmp[156]) * 10;
-
- return 0;
-}
-
-static uint16_t findstr(uint8_t *data, int n, const uint8_t *str, int len)
-{
- int i, j;
-
- for (i = 0; i <= (n - len); i++) {
- for (j = 0; j < len; j++)
- if (data[i + j] != str[j])
- break;
- if (j == len)
- return i;
- }
-
- return 0;
-}
-
-static int
-read_dcb_i2c_entry(ScrnInfoPtr pScrn, int dcb_version, uint8_t *i2ctable, int index, struct dcb_i2c_entry *i2c)
-{
- uint8_t dcb_i2c_ver = dcb_version, headerlen = 0, entry_len = 4;
- int i2c_entries = DCB_MAX_NUM_I2C_ENTRIES;
- int recordoffset = 0, rdofs = 1, wrofs = 0;
- uint8_t port_type = 0;
-
- if (!i2ctable)
- return -EINVAL;
-
- if (dcb_version >= 0x30) {
- if (i2ctable[0] != dcb_version) /* necessary? */
- NV_WARN(pScrn,
- "DCB I2C table version mismatch (%02X vs %02X)\n",
- i2ctable[0], dcb_version);
- dcb_i2c_ver = i2ctable[0];
- headerlen = i2ctable[1];
- if (i2ctable[2] <= DCB_MAX_NUM_I2C_ENTRIES)
- i2c_entries = i2ctable[2];
- else
- NV_WARN(pScrn,
- "DCB I2C table has more entries than indexable "
- "(%d entries, max index 15)\n", i2ctable[2]);
- entry_len = i2ctable[3];
- /* [4] is i2c_default_indices, read in parse_dcb_table() */
- }
- /* it's your own fault if you call this function on a DCB 1.1 BIOS --
- * the test below is for DCB 1.2
- */
- if (dcb_version < 0x14) {
- recordoffset = 2;
- rdofs = 0;
- wrofs = 1;
- }
-
- if (index == 0xf)
- return 0;
- if (index > i2c_entries) {
- NV_ERROR(pScrn, "DCB I2C index too big (%d > %d)\n",
- index, i2ctable[2]);
- return -ENOENT;
- }
- if (i2ctable[headerlen + entry_len * index + 3] == 0xff) {
- NV_ERROR(pScrn, "DCB I2C entry invalid\n");
- return -EINVAL;
- }
-
- if (dcb_i2c_ver >= 0x30) {
- port_type = i2ctable[headerlen + recordoffset + 3 + entry_len * index];
-
- /* fixup for chips using same address offset for read and write */
- if (port_type == 4) /* seen on C51 */
- rdofs = wrofs = 1;
- if (port_type == 5) /* G80+ */
- rdofs = wrofs = 0;
- }
- if (dcb_i2c_ver >= 0x40 && port_type != 5)
- NV_WARN(pScrn, "DCB I2C table has port type %d\n", port_type);
-
- i2c->port_type = port_type;
- i2c->read = i2ctable[headerlen + recordoffset + rdofs + entry_len * index];
- i2c->write = i2ctable[headerlen + recordoffset + wrofs + entry_len * index];
-
- return 0;
-}
-
-static int init_dcb_i2c_entry(ScrnInfoPtr pScrn, struct nvbios *bios, int index)
-{
- struct dcb_i2c_entry *i2c = &bios->bdcb.dcb.i2c[index];
- int ret;
- char adaptorname[11];
-
- if (i2c->chan)
- return 0;
-
- if (bios->bdcb.version < 0x15) {
- NV_ERROR(pScrn, "DCB table not version 1.5 or greater\n");
- return -ENOSYS;
- }
- if (!bios->bdcb.i2c_table) {
- NV_ERROR(pScrn, "No parsed DCB I2C port table\n");
- return -EINVAL;
- }
-
- if ((ret = read_dcb_i2c_entry(pScrn, bios->bdcb.version, bios->bdcb.i2c_table, index, i2c)))
- return ret;
-
- snprintf(adaptorname, 11, "DCB-I2C-%d", index);
-
- return NV_I2CInit(pScrn, &i2c->chan, i2c, xstrdup(adaptorname));
-}
-
-static struct dcb_entry * new_dcb_entry(struct parsed_dcb *dcb)
-{
- struct dcb_entry *entry = &dcb->entry[dcb->entries];
-
- memset(entry, 0, sizeof (struct dcb_entry));
- entry->index = dcb->entries++;
-
- return entry;
-}
-
-static void
-fabricate_vga_output(struct parsed_dcb *dcb, int i2c, int heads, int or)
-{
- struct dcb_entry *entry = new_dcb_entry(dcb);
-
- entry->type = 0;
- entry->i2c_index = i2c;
- entry->heads = heads;
- entry->location = DCB_LOC_ON_CHIP;
- /* setting "or" to 0 for early gen crt modesetting is fine (unused) */
- entry->or = or;
-}
-
-static void fabricate_dvi_i_output(struct parsed_dcb *dcb, bool twoHeads)
-{
- struct dcb_entry *entry = new_dcb_entry(dcb);
-
- entry->type = 2;
- entry->i2c_index = LEGACY_I2C_PANEL;
- entry->heads = twoHeads ? 3 : 1;
- entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */
- entry->or = 1; /* means |0x10 gets set on CRE_LCD__INDEX */
- entry->duallink_possible = false; /* SiI164 and co. are single link */
-
-#if 0
- /* for dvi-a either crtc probably works, but my card appears to only
- * support dvi-d. "nvidia" still attempts to program it for dvi-a,
- * doing the full fp output setup (program 0x6808.. fp dimension regs,
- * setting 0x680848 to 0x10000111 to enable, maybe setting 0x680880);
- * the monitor picks up the mode res ok and lights up, but no pixel
- * data appears, so the board manufacturer probably connected up the
- * sync lines, but missed the video traces / components
- *
- * with this introduction, dvi-a left as an exercise for the reader.
- */
- fabricate_vga_output(dcb, LEGACY_I2C_PANEL, entry->heads, 0);
-#endif
-}
-
-static bool
-parse_dcb20_entry(ScrnInfoPtr pScrn, struct bios_parsed_dcb *bdcb,
- uint32_t conn, uint32_t conf, struct dcb_entry *entry)
-{
- entry->type = conn & 0xf;
- entry->i2c_index = (conn >> 4) & 0xf;
- entry->heads = (conn >> 8) & 0xf;
- entry->bus = (conn >> 16) & 0xf;
- entry->location = (conn >> 20) & 0x3;
- entry->or = (conn >> 24) & 0xf;
- /* Normal entries consist of a single bit, but dual link has the
- * next most significant bit set too
- */
- entry->duallink_possible =
- ((1 << (ffs(entry->or) - 1)) * 3 == entry->or);
-
- switch (entry->type) {
- case OUTPUT_ANALOG:
- /* although the rest of a CRT conf dword is usually
- * zeros, mac biosen have stuff there so we must mask
- */
- entry->crtconf.maxfreq = (bdcb->version < 0x30) ?
- (conf & 0xffff) * 10 :
- (conf & 0xff) * 10000;
- break;
- case OUTPUT_LVDS:
- {
- uint32_t mask;
- if (conf & 0x1)
- entry->lvdsconf.use_straps_for_mode = true;
- if (bdcb->version < 0x22) {
- mask = ~0xd;
- /* the laptop in bug 14567 lies and claims to not use
- * straps when it does, so assume all DCB 2.0 laptops
- * use straps, until a broken EDID using one is produced
- */
- entry->lvdsconf.use_straps_for_mode = true;
- /* both 0x4 and 0x8 show up in v2.0 tables; assume they
- * mean the same thing (probably wrong, but might work)
- */
- if (conf & 0x4 || conf & 0x8)
- entry->lvdsconf.use_power_scripts = true;
- } else {
- mask = ~0x5;
- if (conf & 0x4)
- entry->lvdsconf.use_power_scripts = true;
- }
- if (conf & mask) {
- /* I'm bored of getting this reported; left as a reminder for someone to fix it */
- if (bdcb->version >= 0x40) {
- NV_WARN(pScrn, "G80+ LVDS not initialized by driver; ignoring conf bits\n");
- break;
- }
- NV_ERROR(pScrn, "Unknown LVDS configuration bits, "
- "please report\n");
- /* cause output setting to fail, so message is seen */
- bdcb->dcb.entries = 0;
- return false;
- }
- break;
- }
- case 0xe:
- /* weird g80 mobile type that "nv" treats as a terminator */
- bdcb->dcb.entries--;
- return false;
- }
- /* unsure what DCB version introduces this, 3.0? */
- if (conf & 0x100000)
- entry->i2c_upper_default = true;
-
- return true;
-}
-
-static bool
-parse_dcb15_entry(ScrnInfoPtr pScrn, struct parsed_dcb *dcb,
- uint32_t conn, uint32_t conf, struct dcb_entry *entry)
-{
- if (conn != 0xf0003f00 && conn != 0xf2247f10 &&
- conn != 0xf2204001 && conn != 0xf2204301 && conn != 0xf2204311 && conn != 0xf2208001 && conn != 0xf2244001 && conn != 0xf2244301 && conn != 0xf2244311 && conn != 0xf4204011 && conn != 0xf4208011 && conn != 0xf4248011 &&
- conn != 0xf2045ff2 &&
- conn != 0xf2045f14 && conn != 0xf207df14 && conn != 0xf2205004) {
- NV_ERROR(pScrn, "Unknown DCB 1.5 entry, please report\n");
-
- /* cause output setting to fail for !TV, so message is seen */
- if ((conn & 0xf) != 0x1)
- dcb->entries = 0;
-
- return false;
- }
- /* most of the below is a "best guess" atm */
- entry->type = conn & 0xf;
- if (entry->type == 2)
- /* another way of specifying straps based lvds... */
- entry->type = OUTPUT_LVDS;
- if (entry->type == 4) { /* digital */
- if (conn & 0x10)
- entry->type = OUTPUT_LVDS;
- else
- entry->type = OUTPUT_TMDS;
- }
- /* what's in bits 5-13? could be some encoder maker thing, in tv case */
- entry->i2c_index = (conn >> 14) & 0xf;
- /* raw heads field is in range 0-1, so move to 1-2 */
- entry->heads = ((conn >> 18) & 0x7) + 1;
- entry->location = (conn >> 21) & 0xf;
- /* unused: entry->bus = (conn >> 25) & 0x7; */
- /* set or to be same as heads -- hopefully safe enough */
- entry->or = entry->heads;
- entry->duallink_possible = false;
-
- switch (entry->type) {
- case OUTPUT_ANALOG:
- entry->crtconf.maxfreq = (conf & 0xffff) * 10;
- break;
- case OUTPUT_LVDS:
- /* this is probably buried in conn's unknown bits */
- /* this will upset EDID-ful models, if they exist */
- entry->lvdsconf.use_straps_for_mode = true;
- entry->lvdsconf.use_power_scripts = true;
- break;
- case OUTPUT_TMDS:
- /* invent a DVI-A output, by copying the fields of the DVI-D
- * output; reported to work by math_b on an NV20(!) */
- fabricate_vga_output(dcb, entry->i2c_index, entry->heads, 0);
- }
-
- return true;
-}
-
-static bool parse_dcb_entry(ScrnInfoPtr pScrn, struct bios_parsed_dcb *bdcb,
- uint32_t conn, uint32_t conf)
-{
- struct dcb_entry *entry = new_dcb_entry(&bdcb->dcb);
- bool ret;
-
- if (bdcb->version >= 0x20)
- ret = parse_dcb20_entry(pScrn, bdcb, conn, conf, entry);
- else
- ret = parse_dcb15_entry(pScrn, &bdcb->dcb, conn, conf, entry);
- if (!ret)
- return ret;
-
- read_dcb_i2c_entry(pScrn, bdcb->version, bdcb->i2c_table,
- entry->i2c_index, &bdcb->dcb.i2c[entry->i2c_index]);
-
- return true;
-}
-
-void merge_like_dcb_entries(ScrnInfoPtr pScrn, struct parsed_dcb *dcb)
-{
- /* DCB v2.0 lists each output combination separately.
- * Here we merge compatible entries to have fewer outputs, with more options
- */
-
- int i, newentries = 0;
-
- for (i = 0; i < dcb->entries; i++) {
- struct dcb_entry *ient = &dcb->entry[i];
- int j;
-
- for (j = i + 1; j < dcb->entries; j++) {
- struct dcb_entry *jent = &dcb->entry[j];
-
- if (jent->type == 100) /* already merged entry */
- continue;
-
- /* merge heads field when all other fields the same */
- if (jent->i2c_index == ient->i2c_index &&
- jent->type == ient->type &&
- jent->location == ient->location &&
- jent->or == ient->or) {
- NV_TRACE(pScrn, "Merging DCB entries %d and %d\n",
- i, j);
- ient->heads |= jent->heads;
- jent->type = 100; /* dummy value */
- }
- }
- }
-
- /* Compact entries merged into others out of dcb */
- for (i = 0; i < dcb->entries; i++) {
- if (dcb->entry[i].type == 100)
- continue;
-
- if (newentries != i) {
- dcb->entry[newentries] = dcb->entry[i];
- dcb->entry[newentries].index = newentries;
- }
- newentries++;
- }
-
- dcb->entries = newentries;
-}
-
-static int parse_dcb_table(ScrnInfoPtr pScrn, struct nvbios *bios, bool twoHeads)
-{
- struct bios_parsed_dcb *bdcb = &bios->bdcb;
- struct parsed_dcb *dcb;
- uint16_t dcbptr, i2ctabptr = 0;
- uint8_t *dcbtable;
- uint8_t headerlen = 0x4, entries = DCB_MAX_NUM_ENTRIES;
- bool configblock = true;
- int recordlength = 8, confofs = 4;
- int i;
-
- dcb = bios->pub.dcb = &bdcb->dcb;
- dcb->entries = 0;
-
- /* get the offset from 0x36 */
- dcbptr = ROM16(bios->data[0x36]);
-
- if (dcbptr == 0x0) {
-#ifdef __powerpc__
- if ((NVPTR(pScrn)->Chipset & 0xffff) == 0x0172) {
- /* retarded PowerMac G4 has DVI and ADC (#21273) */
- NV_WARN(pScrn, "Working around missing output tables\n");
- /* this is the dvi-a */
- fabricate_vga_output(dcb, LEGACY_I2C_PANEL, 0x3, 2);
- return 0;
- }
-#endif
- NV_WARN(pScrn, "No output data (DCB) found in BIOS, "
- "assuming a CRT output exists\n");
- /* this situation likely means a really old card, pre DCB */
- fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1, 0);
- return 0;
- }
-
- dcbtable = &bios->data[dcbptr];
-
- /* get DCB version */
- bdcb->version = dcbtable[0];
- NV_TRACE(pScrn, "Found Display Configuration Block version %d.%d\n",
- bdcb->version >> 4, bdcb->version & 0xf);
-
- if (bdcb->version >= 0x20) { /* NV17+ */
- uint32_t sig;
-
- if (bdcb->version >= 0x30) { /* NV40+ */
- headerlen = dcbtable[1];
- entries = dcbtable[2];
- recordlength = dcbtable[3];
- i2ctabptr = ROM16(dcbtable[4]);
- sig = ROM32(dcbtable[6]);
- if (bdcb->version == 0x40) /* G80 */
- bdcb->init8e_table_ptr =
- ROM16(dcbtable[10]);
- } else {
- i2ctabptr = ROM16(dcbtable[2]);
- sig = ROM32(dcbtable[4]);
- headerlen = 8;
- }
-
- if (sig != 0x4edcbdcb) {
- NV_ERROR(pScrn, "Bad Display Configuration Block "
- "signature (%08X)\n", sig);
- return -EINVAL;
- }
- } else if (bdcb->version >= 0x15) { /* some NV11 and NV20 */
- char sig[8] = { 0 };
-
- strncpy(sig, (char *)&dcbtable[-7], 7);
- i2ctabptr = ROM16(dcbtable[2]);
- recordlength = 10;
- confofs = 6;
-
- if (strcmp(sig, "DEV_REC")) {
- NV_ERROR(pScrn, "Bad Display Configuration Block "
- "signature (%s)\n", sig);
- return -EINVAL;
- }
- } else {
- /* v1.4 (some NV15/16, NV11+) seems the same as v1.5, but always
- * has the same single (crt) entry, even when tv-out present, so
- * the conclusion is this version cannot really be used.
- * v1.2 tables (some NV6/10, and NV15+) normally have the same
- * 5 entries, which are not specific to the card and so no use.
- * v1.2 does have an I2C table that read_dcb_i2c_table can
- * handle, but cards exist (nv11 in #14821) with a bad i2c table
- * pointer, so use the indices parsed in parse_bmp_structure.
- * v1.1 (NV5+, maybe some NV4) is entirely unhelpful
- */
- NV_TRACEWARN(pScrn, "No useful information in BIOS output table; "
- "adding all possible outputs\n");
- fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1, 0);
- if (bios->tmds.output0_script_ptr ||
- bios->tmds.output1_script_ptr)
- fabricate_dvi_i_output(dcb, twoHeads);
- return 0;
- }
-
- if (!i2ctabptr)
- NV_WARN(pScrn, "No pointer to DCB I2C port table\n");
- else {
- bdcb->i2c_table = &bios->data[i2ctabptr];
- if (bdcb->version >= 0x30)
- bdcb->i2c_default_indices = bdcb->i2c_table[4];
- }
-
- if (entries > DCB_MAX_NUM_ENTRIES)
- entries = DCB_MAX_NUM_ENTRIES;
-
- for (i = 0; i < entries; i++) {
- uint32_t connection, config = 0;
-
- connection = ROM32(dcbtable[headerlen + recordlength * i]);
- if (configblock)
- config = ROM32(dcbtable[headerlen + confofs + recordlength * i]);
-
- /* Should we allow discontinuous DCBs? Certainly DCB I2C tables can be discontinuous */
- if ((connection & 0x0000000f) == 0x0000000f) /* end of records */
- break;
- if (connection == 0x00000000) /* seen on an NV11 with DCB v1.5 */
- break;
-
- NV_TRACEWARN(pScrn, "Raw DCB entry %d: %08x %08x\n",
- dcb->entries, connection, config);
-
- if (!parse_dcb_entry(pScrn, bdcb, connection, config))
- break;
- }
-
- /* apart for v2.1+ not being known for requiring merging, this
- * guarantees dcbent->index is the index of the entry in the rom image
- */
- if (bdcb->version < 0x21)
- merge_like_dcb_entries(pScrn, dcb);
-
- return (dcb->entries ? 0 : -ENXIO);
-}
-
-static void fixup_legacy_i2c(struct nvbios *bios)
-{
- struct parsed_dcb *dcb = &bios->bdcb.dcb;
- int i;
-
- for (i = 0; i < dcb->entries; i++) {
- if (dcb->entry[i].i2c_index == LEGACY_I2C_CRT)
- dcb->entry[i].i2c_index = bios->legacy.i2c_indices.crt;
- if (dcb->entry[i].i2c_index == LEGACY_I2C_PANEL)
- dcb->entry[i].i2c_index = bios->legacy.i2c_indices.panel;
- }
-}
-
-static int load_nv17_hwsq_ucode_entry(ScrnInfoPtr pScrn, struct nvbios *bios, uint16_t hwsq_offset, int entry)
-{
- /* The header following the "HWSQ" signature has the number of entries,
- * and the entry size
- *
- * An entry consists of a dword to write to the sequencer control reg
- * (0x00001304), followed by the ucode bytes, written sequentially,
- * starting at reg 0x00001400
- */
-
- uint8_t bytes_to_write;
- uint16_t hwsq_entry_offset;
- int i;
-
- if (bios->data[hwsq_offset] <= entry) {
- NV_ERROR(pScrn, "Too few entries in HW sequencer table for "
- "requested entry\n");
- return -ENOENT;
- }
-
- bytes_to_write = bios->data[hwsq_offset + 1];
-
- if (bytes_to_write != 36) {
- NV_ERROR(pScrn, "Unknown HW sequencer entry size\n");
- return -EINVAL;
- }
-
- NV_TRACE(pScrn, "Loading NV17 power sequencing microcode\n");
-
- hwsq_entry_offset = hwsq_offset + 2 + entry * bytes_to_write;
-
- /* set sequencer control */
- bios_wr32(pScrn, 0x00001304, ROM32(bios->data[hwsq_entry_offset]));
- bytes_to_write -= 4;
-
- /* write ucode */
- for (i = 0; i < bytes_to_write; i += 4)
- bios_wr32(pScrn, 0x00001400 + i, ROM32(bios->data[hwsq_entry_offset + i + 4]));
-
- /* twiddle NV_PBUS_DEBUG_4 */
- bios_wr32(pScrn, NV_PBUS_DEBUG_4, bios_rd32(pScrn, NV_PBUS_DEBUG_4) | 0x18);
-
- return 0;
-}
-
-static int load_nv17_hw_sequencer_ucode(ScrnInfoPtr pScrn, struct nvbios *bios)
-{
- /* BMP based cards, from NV17, need a microcode loading to correctly
- * control the GPIO etc for LVDS panels
- *
- * BIT based cards seem to do this directly in the init scripts
- *
- * The microcode entries are found by the "HWSQ" signature.
- */
-
- const uint8_t hwsq_signature[] = { 'H', 'W', 'S', 'Q' };
- int hwsq_offset;
-
- if (!(hwsq_offset = findstr(bios->data, bios->length, hwsq_signature,
- sizeof(hwsq_signature))))
- return 0;
-
- /* always use entry 0? */
- return load_nv17_hwsq_ucode_entry(pScrn, bios,
- hwsq_offset + sizeof(hwsq_signature), 0);
-}
-
-uint8_t * nouveau_bios_embedded_edid(ScrnInfoPtr pScrn)
-{
- struct nvbios *bios = &NVPTR(pScrn)->VBIOS;
- const uint8_t edid_sig[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
- uint16_t offset = 0, newoffset;
- int searchlen = NV_PROM_SIZE;
-
- if (bios->fp.edid)
- return bios->fp.edid;
-
- while (searchlen) {
- if (!(newoffset = findstr(&bios->data[offset], searchlen, edid_sig, 8)))
- return NULL;
- offset += newoffset;
- if (!nv_cksum(&bios->data[offset], EDID1_LEN))
- break;
-
- searchlen -= offset;
- offset++;
- }
-
- NV_TRACE(pScrn, "Found EDID in BIOS\n");
-
- return (bios->fp.edid = &bios->data[offset]);
-}
-
-bool NVInitVBIOS(ScrnInfoPtr pScrn)
-{
- struct nvbios *bios = &NVPTR(pScrn)->VBIOS;
-
- memset(bios, 0, sizeof(struct nvbios));
-
- if (!NVShadowVBIOS(pScrn, bios->data))
- return false;
-
- bios->length = bios->data[2] * 512;
- if (bios->length > NV_PROM_SIZE)
- bios->length = NV_PROM_SIZE;
-
- return true;
-}
-
-int nouveau_parse_vbios_struct(ScrnInfoPtr pScrn)
-{
- struct nvbios *bios = &NVPTR(pScrn)->VBIOS;
- const uint8_t bit_signature[] = { 0xff, 0xb8, 'B', 'I', 'T' };
- const uint8_t bmp_signature[] = { 0xff, 0x7f, 'N', 'V', 0x0 };
- int offset;
-
- if ((offset = findstr(bios->data, bios->length, bit_signature, sizeof(bit_signature)))) {
- NV_TRACE(pScrn, "BIT BIOS found\n");
- return parse_bit_structure(pScrn, bios, offset + 6);
- }
- if ((offset = findstr(bios->data, bios->length, bmp_signature, sizeof(bmp_signature)))) {
- NV_TRACE(pScrn, "BMP BIOS found\n");
- return parse_bmp_structure(pScrn, bios, offset);
- }
-
- NV_ERROR(pScrn, "No known BIOS signature found\n");
-
- return -ENODEV;
-}
-
-int nouveau_run_vbios_init(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- struct nvbios *bios = &pNv->VBIOS;
- int ret = 0;
-
- NVLockVgaCrtcs(pNv, false);
- if (pNv->twoHeads)
- NVSetOwner(pNv, crtchead);
-
- if (bios->major_version < 5) /* BMP only */
- load_nv17_hw_sequencer_ucode(pScrn, bios);
-
- parse_init_tables(pScrn, bios);
-
- if (bios->major_version < 5)
- /* feature_byte on BMP is poor, but init always sets CR4B */
- bios->is_mobile = NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_4B) & 0x40;
-
- /* all BIT systems need p_f_m_t for digital_min_front_porch */
- if (bios->is_mobile || bios->major_version >= 5)
- ret = parse_fp_mode_table(pScrn, bios);
-
- NVLockVgaCrtcs(pNv, true);
-
- return ret;
-}
-
-int NVParseBios(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- struct nvbios *bios = &pNv->VBIOS;
- uint32_t saved_nv_pextdev_boot_0;
- int ret;
-
- if (!NVInitVBIOS(pScrn))
- return -ENODEV;
- if ((ret = nouveau_parse_vbios_struct(pScrn)))
- return ret;
- if ((ret = parse_dcb_table(pScrn, bios, pNv->twoHeads)))
- return ret;
- fixup_legacy_i2c(bios);
-
- if (!bios->major_version) /* we don't run version 0 bios */
- return 0;
-
- /* these will need remembering across a suspend */
- saved_nv_pextdev_boot_0 = bios_rd32(pScrn, NV_PEXTDEV_BOOT_0);
- saved_nv_pfb_cfg0 = bios_rd32(pScrn, NV_PFB_CFG0);
-
- /* init script execution disabled */
- bios->execute = false;
-
- bios_wr32(pScrn, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0);
-
- pNv->vbios = &bios->pub;
-
- if ((ret = nouveau_run_vbios_init(pScrn))) {
- pNv->vbios = NULL;
- return ret;
- }
-
- /* allow subsequent scripts to execute */
- bios->execute = true;
-
- return 0;
-}
diff --git a/src/nv_const.h b/src/nv_const.h
index 3217af6..767344c 100644
--- a/src/nv_const.h
+++ b/src/nv_const.h
@@ -15,7 +15,2 @@ typedef enum {
OPTION_VIDEO_KEY,
- OPTION_FP_DITHER,
- OPTION_FP_SCALE,
- OPTION_CMDBUF_LOCATION,
- OPTION_CMDBUF_SIZE,
- OPTION_SCALING_MODE,
OPTION_EXA_PIXMAPS
@@ -30,5 +25,2 @@ static const OptionInfoRec NVOptions[] = {
{ OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE },
- { OPTION_FP_DITHER, "FPDither", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_FP_SCALE, "FPScale", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_SCALING_MODE, "ScalingMode", OPTV_STRING, {0}, FALSE },
{ OPTION_EXA_PIXMAPS, "EXAPixmaps", OPTV_BOOLEAN, {0}, FALSE },
diff --git a/src/nv_crtc.c b/src/nv_crtc.c
deleted file mode 100644
index 9708741..0000000
--- a/src/nv_crtc.c
+++ /dev/null
@@ -1,1095 +0,0 @@
-/*
- * Copyright 1993-2003 NVIDIA, Corporation
- * Copyright 2006 Dave Airlie
- * Copyright 2007 Maarten Maathuis
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include "nv_include.h"
-
-static void crtc_wr_cio_state(xf86CrtcPtr crtc, int index)
-{
- NVWriteVgaCrtc(NVPTR(crtc->scrn), to_nouveau_crtc(crtc)->head, index,
- to_nouveau_crtc(crtc)->state->CRTC[index]);
-}
-
-void nv_crtc_set_digital_vibrance(xf86CrtcPtr crtc, int level)
-{
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- struct nouveau_crtc_state *regp = nv_crtc->state;
- NVPtr pNv = NVPTR(crtc->scrn);
-
- regp->CRTC[NV_CIO_CRE_CSB] = nv_crtc->saturation = level;
- if (nv_crtc->saturation && pNv->gf4_disp_arch) {
- regp->CRTC[NV_CIO_CRE_CSB] = 0x80;
- regp->CRTC[NV_CIO_CRE_5B] = nv_crtc->saturation << 2;
- crtc_wr_cio_state(crtc, NV_CIO_CRE_5B);
- }
- crtc_wr_cio_state(crtc, NV_CIO_CRE_CSB);
-}
-
-void nv_crtc_set_image_sharpening(xf86CrtcPtr crtc, int level)
-{
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- struct nouveau_crtc_state *regp = nv_crtc->state;
- NVPtr pNv = NVPTR(crtc->scrn);
-
- nv_crtc->sharpness = level;
- if (level < 0) /* blur is in hw range 0x3f -> 0x20 */
- level += 0x40;
- regp->ramdac_634 = level;
- NVWriteRAMDAC(pNv, nv_crtc->head, NV_PRAMDAC_634, regp->ramdac_634);
-}
-
-/* NV4x 0x40.. pll notes:
- * gpu pll: 0x4000 + 0x4004
- * ?gpu? pll: 0x4008 + 0x400c
- * vpll1: 0x4010 + 0x4014
- * vpll2: 0x4018 + 0x401c
- * mpll: 0x4020 + 0x4024
- * mpll: 0x4038 + 0x403c
- *
- * the first register of each pair has some unknown details:
- * bits 0-7: redirected values from elsewhere? (similar to PLL_SETUP_CONTROL?)
- * bits 20-23: (mpll) something to do with post divider?
- * bits 28-31: related to single stage mode? (bit 8/12)
- */
-
-static void nv_crtc_cursor_set(xf86CrtcPtr crtc)
-{
- NVPtr pNv = NVPTR(crtc->scrn);
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- struct nouveau_crtc_state *regp = nv_crtc->state;
- uint32_t cursor_start = nv_crtc->head ? pNv->Cursor2->offset :
- pNv->Cursor->offset;
-
- regp->CRTC[NV_CIO_CRE_HCUR_ADDR0_INDEX] = MASK(NV_CIO_CRE_HCUR_ASI) |
- XLATE(cursor_start, 17,
- NV_CIO_CRE_HCUR_ADDR0_ADR);
- regp->CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] = XLATE(cursor_start, 11,
- NV_CIO_CRE_HCUR_ADDR1_ADR);
- if (crtc->mode.Flags & V_DBLSCAN)
- regp->CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] |= MASK(NV_CIO_CRE_HCUR_ADDR1_CUR_DBL);
- regp->CRTC[NV_CIO_CRE_HCUR_ADDR2_INDEX] = cursor_start >> 24;
-
- crtc_wr_cio_state(crtc, NV_CIO_CRE_HCUR_ADDR0_INDEX);
- crtc_wr_cio_state(crtc, NV_CIO_CRE_HCUR_ADDR1_INDEX);
- crtc_wr_cio_state(crtc, NV_CIO_CRE_HCUR_ADDR2_INDEX);
- if (pNv->Architecture == NV_ARCH_40)
- nv_fix_nv40_hw_cursor(pNv, nv_crtc->head);
-}
-
-static void nv_crtc_calc_state_ext(xf86CrtcPtr crtc, DisplayModePtr mode, int dot_clock)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- struct nouveau_mode_state *state = &pNv->set_state;
- struct nouveau_crtc_state *regp = &state->head[nv_crtc->head];
- struct nouveau_pll_vals *pv = &regp->pllvals;
- struct pll_lims pll_lim;
- int vclk, arb_burst, arb_fifo_lwm;
-
- if (get_pll_limits(pScrn, nv_crtc->head ? VPLL2 : VPLL1, &pll_lim))
- return;
-
- /* NM2 == 0 is used to determine single stage mode on two stage plls */
- pv->NM2 = 0;
-
- /* for newer nv4x the blob uses only the first stage of the vpll below a
- * certain clock. for a certain nv4b this is 150MHz. since the max
- * output frequency of the first stage for this card is 300MHz, it is
- * assumed the threshold is given by vco1 maxfreq/2
- */
- /* for early nv4x, specifically nv40 and *some* nv43 (devids 0 and 6,
- * not 8, others unknown), the blob always uses both plls. no problem
- * has yet been observed in allowing the use a single stage pll on all
- * nv43 however. the behaviour of single stage use is untested on nv40
- */
- if (pNv->NVArch > 0x40 && dot_clock <= (pll_lim.vco1.maxfreq / 2))
- memset(&pll_lim.vco2, 0, sizeof(pll_lim.vco2));
-
- if (!(vclk = nouveau_calc_pll_mnp(pScrn, &pll_lim, dot_clock, pv)))
- return;
-
- /* The blob uses this always, so let's do the same */
- if (pNv->Architecture == NV_ARCH_40)
- state->pllsel |= NV_RAMDAC_PLL_SELECT_USE_VPLL2_TRUE;
- /* again nv40 and some nv43 act more like nv3x as described above */
- if (pNv->NVArch < 0x41)
- state->pllsel |= NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_MPLL |
- NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_NVPLL;
- state->pllsel |= (nv_crtc->head ? NV_RAMDAC_PLL_SELECT_PLL_SOURCE_VPLL2 |
- NV_RAMDAC_PLL_SELECT_VCLK2_RATIO_DB2 :
- NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_VPLL |
- NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2);
-
- if (pv->NM2)
- NV_TRACE(pScrn, "vpll: n1 %d n2 %d m1 %d m2 %d log2p %d\n",
- pv->N1, pv->N2, pv->M1, pv->M2, pv->log2P);
- else
- NV_TRACE(pScrn, "vpll: n %d m %d log2p %d\n",
- pv->N1, pv->M1, pv->log2P);
-
- nouveau_calc_arb(pScrn, vclk, pScrn->bitsPerPixel, &arb_burst, &arb_fifo_lwm);
-
- regp->CRTC[NV_CIO_CRE_FF_INDEX] = arb_burst;
- regp->CRTC[NV_CIO_CRE_FFLWM__INDEX] = arb_fifo_lwm & 0xff;
- if (pNv->Architecture >= NV_ARCH_30)
- regp->CRTC[NV_CIO_CRE_47] = arb_fifo_lwm >> 8;
-
- nv_crtc_cursor_set(crtc);
-}
-
-static void
-nv_crtc_dpms(xf86CrtcPtr crtc, int mode)
-{
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- ScrnInfoPtr pScrn = crtc->scrn;
- NVPtr pNv = NVPTR(pScrn);
- unsigned char seq1 = 0, crtc17 = 0;
- unsigned char crtc1A;
-
- NV_TRACE(pScrn, "Setting dpms mode %d on CRTC %d\n", mode, nv_crtc->head);
-
- if (nv_crtc->last_dpms == mode) /* Don't do unnecesary mode changes. */
- return;
-
- nv_crtc->last_dpms = mode;
-
- if (pNv->twoHeads)
- NVSetOwner(pNv, nv_crtc->head);
-
- /* nv4ref indicates these two RPC1 bits inhibit h/v sync */
- crtc1A = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_RPC1_INDEX) & ~0xC0;
- switch(mode) {
- case DPMSModeStandby:
- /* Screen: Off; HSync: Off, VSync: On -- Not Supported */
- seq1 = 0x20;
- crtc17 = 0x80;
- crtc1A |= 0x80;
- break;
- case DPMSModeSuspend:
- /* Screen: Off; HSync: On, VSync: Off -- Not Supported */
- seq1 = 0x20;
- crtc17 = 0x80;
- crtc1A |= 0x40;
- break;
- case DPMSModeOff:
- /* Screen: Off; HSync: Off, VSync: Off */
- seq1 = 0x20;
- crtc17 = 0x00;
- crtc1A |= 0xC0;
- break;
- case DPMSModeOn:
- default:
- /* Screen: On; HSync: On, VSync: On */
- seq1 = 0x00;
- crtc17 = 0x80;
- break;
- }
-
- NVVgaSeqReset(pNv, nv_crtc->head, true);
- /* Each head has it's own sequencer, so we can turn it off when we want */
- seq1 |= (NVReadVgaSeq(pNv, nv_crtc->head, NV_VIO_SR_CLOCK_INDEX) & ~0x20);
- NVWriteVgaSeq(pNv, nv_crtc->head, NV_VIO_SR_CLOCK_INDEX, seq1);
- crtc17 |= (NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CR_MODE_INDEX) & ~0x80);
- usleep(10000);
- NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CR_MODE_INDEX, crtc17);
- NVVgaSeqReset(pNv, nv_crtc->head, false);
-
- NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_RPC1_INDEX, crtc1A);
-}
-
-static Bool
-nv_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
- DisplayModePtr adjusted_mode)
-{
- return TRUE;
-}
-
-static void
-nv_crtc_mode_set_vga(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjusted_mode)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- struct nouveau_crtc_state *regp = nv_crtc->state;
-
- /* Calculate our timings */
- int horizDisplay = (mode->CrtcHDisplay >> 3) - 1;
- int horizStart = (mode->CrtcHSyncStart >> 3) - 1;
- int horizEnd = (mode->CrtcHSyncEnd >> 3) - 1;
- int horizTotal = (mode->CrtcHTotal >> 3) - 5;
- int horizBlankStart = (mode->CrtcHDisplay >> 3) - 1;
- int horizBlankEnd = (mode->CrtcHTotal >> 3) - 1;
- int vertDisplay = mode->CrtcVDisplay - 1;
- int vertStart = mode->CrtcVSyncStart - 1;
- int vertEnd = mode->CrtcVSyncEnd - 1;
- int vertTotal = mode->CrtcVTotal - 2;
- int vertBlankStart = mode->CrtcVDisplay - 1;
- int vertBlankEnd = mode->CrtcVTotal - 1;
-
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- bool fp_output = false;
- int i;
-
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
-
- if (output->crtc == crtc && IS_DFP(nv_encoder->dcb->type))
- fp_output = true;
- }
-
- if (fp_output) {
- vertStart = vertTotal - 3;
- vertEnd = vertTotal - 2;
- vertBlankStart = vertStart;
- horizStart = horizTotal - 5;
- horizEnd = horizTotal - 2;
- horizBlankEnd = horizTotal + 4;
- if (pNv->overlayAdaptor && pNv->Architecture >= NV_ARCH_10)
- /* This reportedly works around some video overlay bandwidth problems */
- horizTotal += 2;
- }
-
- if (mode->Flags & V_INTERLACE)
- vertTotal |= 1;
-
-#if 0
- ErrorF("horizDisplay: 0x%X \n", horizDisplay);
- ErrorF("horizStart: 0x%X \n", horizStart);
- ErrorF("horizEnd: 0x%X \n", horizEnd);
- ErrorF("horizTotal: 0x%X \n", horizTotal);
- ErrorF("horizBlankStart: 0x%X \n", horizBlankStart);
- ErrorF("horizBlankEnd: 0x%X \n", horizBlankEnd);
- ErrorF("vertDisplay: 0x%X \n", vertDisplay);
- ErrorF("vertStart: 0x%X \n", vertStart);
- ErrorF("vertEnd: 0x%X \n", vertEnd);
- ErrorF("vertTotal: 0x%X \n", vertTotal);
- ErrorF("vertBlankStart: 0x%X \n", vertBlankStart);
- ErrorF("vertBlankEnd: 0x%X \n", vertBlankEnd);
-#endif
-
- /*
- * compute correct Hsync & Vsync polarity
- */
- if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
- && (mode->Flags & (V_PVSYNC | V_NVSYNC))) {
-
- regp->MiscOutReg = 0x23;
- if (mode->Flags & V_NHSYNC) regp->MiscOutReg |= 0x40;
- if (mode->Flags & V_NVSYNC) regp->MiscOutReg |= 0x80;
- } else {
- int VDisplay = mode->VDisplay;
- if (mode->Flags & V_DBLSCAN)
- VDisplay *= 2;
- if (mode->VScan > 1)
- VDisplay *= mode->VScan;
- if (VDisplay < 400)
- regp->MiscOutReg = 0xA3; /* +hsync -vsync */
- else if (VDisplay < 480)
- regp->MiscOutReg = 0x63; /* -hsync +vsync */
- else if (VDisplay < 768)
- regp->MiscOutReg = 0xE3; /* -hsync -vsync */
- else
- regp->MiscOutReg = 0x23; /* +hsync +vsync */
- }
-
- regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2;
-
- /*
- * Time Sequencer
- */
- regp->Sequencer[NV_VIO_SR_RESET_INDEX] = 0x00;
- /* 0x20 disables the sequencer */
- if (mode->Flags & V_CLKDIV2)
- regp->Sequencer[NV_VIO_SR_CLOCK_INDEX] = 0x29;
- else
- regp->Sequencer[NV_VIO_SR_CLOCK_INDEX] = 0x21;
- regp->Sequencer[NV_VIO_SR_PLANE_MASK_INDEX] = 0x0F;
- regp->Sequencer[NV_VIO_SR_CHAR_MAP_INDEX] = 0x00;
- regp->Sequencer[NV_VIO_SR_MEM_MODE_INDEX] = 0x0E;
-
- /*
- * CRTC
- */
- regp->CRTC[NV_CIO_CR_HDT_INDEX] = horizTotal;
- regp->CRTC[NV_CIO_CR_HDE_INDEX] = horizDisplay;
- regp->CRTC[NV_CIO_CR_HBS_INDEX] = horizBlankStart;
- regp->CRTC[NV_CIO_CR_HBE_INDEX] = (1 << 7) |
- XLATE(horizBlankEnd, 0, NV_CIO_CR_HBE_4_0);
- regp->CRTC[NV_CIO_CR_HRS_INDEX] = horizStart;
- regp->CRTC[NV_CIO_CR_HRE_INDEX] = XLATE(horizBlankEnd, 5, NV_CIO_CR_HRE_HBE_5) |
- XLATE(horizEnd, 0, NV_CIO_CR_HRE_4_0);
- regp->CRTC[NV_CIO_CR_VDT_INDEX] = vertTotal;
- regp->CRTC[NV_CIO_CR_OVL_INDEX] = XLATE(vertStart, 9, NV_CIO_CR_OVL_VRS_9) |
- XLATE(vertDisplay, 9, NV_CIO_CR_OVL_VDE_9) |
- XLATE(vertTotal, 9, NV_CIO_CR_OVL_VDT_9) |
- (1 << 4) |
- XLATE(vertBlankStart, 8, NV_CIO_CR_OVL_VBS_8) |
- XLATE(vertStart, 8, NV_CIO_CR_OVL_VRS_8) |
- XLATE(vertDisplay, 8, NV_CIO_CR_OVL_VDE_8) |
- XLATE(vertTotal, 8, NV_CIO_CR_OVL_VDT_8);
- regp->CRTC[NV_CIO_CR_RSAL_INDEX] = 0x00;
- regp->CRTC[NV_CIO_CR_CELL_HT_INDEX] = ((mode->Flags & V_DBLSCAN) ? MASK(NV_CIO_CR_CELL_HT_SCANDBL) : 0) |
- 1 << 6 |
- XLATE(vertBlankStart, 9, NV_CIO_CR_CELL_HT_VBS_9);
- regp->CRTC[NV_CIO_CR_CURS_ST_INDEX] = 0x00;
- regp->CRTC[NV_CIO_CR_CURS_END_INDEX] = 0x00;
- regp->CRTC[NV_CIO_CR_SA_HI_INDEX] = 0x00;
- regp->CRTC[NV_CIO_CR_SA_LO_INDEX] = 0x00;
- regp->CRTC[NV_CIO_CR_TCOFF_HI_INDEX] = 0x00;
- regp->CRTC[NV_CIO_CR_TCOFF_LO_INDEX] = 0x00;
- regp->CRTC[NV_CIO_CR_VRS_INDEX] = vertStart;
- regp->CRTC[NV_CIO_CR_VRE_INDEX] = 1 << 5 | XLATE(vertEnd, 0, NV_CIO_CR_VRE_3_0);
- regp->CRTC[NV_CIO_CR_VDE_INDEX] = vertDisplay;
- /* framebuffer can be larger than crtc scanout area. */
- regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = pScrn->displayWidth / 8 * pScrn->bitsPerPixel / 8;
- regp->CRTC[NV_CIO_CR_ULINE_INDEX] = 0x00;
- regp->CRTC[NV_CIO_CR_VBS_INDEX] = vertBlankStart;
- regp->CRTC[NV_CIO_CR_VBE_INDEX] = vertBlankEnd;
- regp->CRTC[NV_CIO_CR_MODE_INDEX] = 0x43;
- regp->CRTC[NV_CIO_CR_LCOMP_INDEX] = 0xff;
-
- /*
- * Some extended CRTC registers (they are not saved with the rest of the vga regs).
- */
-
- /* framebuffer can be larger than crtc scanout area. */
- regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = XLATE(pScrn->displayWidth / 8 * pScrn->bitsPerPixel / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
- regp->CRTC[NV_CIO_CRE_RPC1_INDEX] = mode->CrtcHDisplay < 1280 ?
- MASK(NV_CIO_CRE_RPC1_LARGE) : 0x00;
- regp->CRTC[NV_CIO_CRE_LSR_INDEX] = XLATE(horizBlankEnd, 6, NV_CIO_CRE_LSR_HBE_6) |
- XLATE(vertBlankStart, 10, NV_CIO_CRE_LSR_VBS_10) |
- XLATE(vertStart, 10, NV_CIO_CRE_LSR_VRS_10) |
- XLATE(vertDisplay, 10, NV_CIO_CRE_LSR_VDE_10) |
- XLATE(vertTotal, 10, NV_CIO_CRE_LSR_VDT_10);
- regp->CRTC[NV_CIO_CRE_HEB__INDEX] = XLATE(horizStart, 8, NV_CIO_CRE_HEB_HRS_8) |
- XLATE(horizBlankStart, 8, NV_CIO_CRE_HEB_HBS_8) |
- XLATE(horizDisplay, 8, NV_CIO_CRE_HEB_HDE_8) |
- XLATE(horizTotal, 8, NV_CIO_CRE_HEB_HDT_8);
- regp->CRTC[NV_CIO_CRE_EBR_INDEX] = XLATE(vertBlankStart, 11, NV_CIO_CRE_EBR_VBS_11) |
- XLATE(vertStart, 11, NV_CIO_CRE_EBR_VRS_11) |
- XLATE(vertDisplay, 11, NV_CIO_CRE_EBR_VDE_11) |
- XLATE(vertTotal, 11, NV_CIO_CRE_EBR_VDT_11);
-
- if (mode->Flags & V_INTERLACE) {
- horizTotal = (horizTotal >> 1) & ~1;
- regp->CRTC[NV_CIO_CRE_ILACE__INDEX] = horizTotal;
- regp->CRTC[NV_CIO_CRE_HEB__INDEX] |= XLATE(horizTotal, 8, NV_CIO_CRE_HEB_ILC_8);
- } else
- regp->CRTC[NV_CIO_CRE_ILACE__INDEX] = 0xff; /* interlace off */
-
- /*
- * Graphics Display Controller
- */
- regp->Graphics[NV_VIO_GX_SR_INDEX] = 0x00;
- regp->Graphics[NV_VIO_GX_SREN_INDEX] = 0x00;
- regp->Graphics[NV_VIO_GX_CCOMP_INDEX] = 0x00;
- regp->Graphics[NV_VIO_GX_ROP_INDEX] = 0x00;
- regp->Graphics[NV_VIO_GX_READ_MAP_INDEX] = 0x00;
- regp->Graphics[NV_VIO_GX_MODE_INDEX] = 0x40; /* 256 color mode */
- regp->Graphics[NV_VIO_GX_MISC_INDEX] = 0x05; /* map 64k mem + graphic mode */
- regp->Graphics[NV_VIO_GX_DONT_CARE_INDEX] = 0x0F;
- regp->Graphics[NV_VIO_GX_BIT_MASK_INDEX] = 0xFF;
-
- regp->Attribute[0] = 0x00; /* standard colormap translation */
- regp->Attribute[1] = 0x01;
- regp->Attribute[2] = 0x02;
- regp->Attribute[3] = 0x03;
- regp->Attribute[4] = 0x04;
- regp->Attribute[5] = 0x05;
- regp->Attribute[6] = 0x06;
- regp->Attribute[7] = 0x07;
- regp->Attribute[8] = 0x08;
- regp->Attribute[9] = 0x09;
- regp->Attribute[10] = 0x0A;
- regp->Attribute[11] = 0x0B;
- regp->Attribute[12] = 0x0C;
- regp->Attribute[13] = 0x0D;
- regp->Attribute[14] = 0x0E;
- regp->Attribute[15] = 0x0F;
- regp->Attribute[NV_CIO_AR_MODE_INDEX] = 0x01; /* Enable graphic mode */
- /* Non-vga */
- regp->Attribute[NV_CIO_AR_OSCAN_INDEX] = 0x00;
- regp->Attribute[NV_CIO_AR_PLANE_INDEX] = 0x0F; /* enable all color planes */
- regp->Attribute[NV_CIO_AR_HPP_INDEX] = 0x00;
- regp->Attribute[NV_CIO_AR_CSEL_INDEX] = 0x00;
-}
-
-/**
- * Sets up registers for the given mode/adjusted_mode pair.
- *
- * The clocks, CRTCs and outputs attached to this CRTC must be off.
- *
- * This shouldn't enable any clocks, CRTCs, or outputs, but they should
- * be easily turned on/off after this.
- */
-static void
-nv_crtc_mode_set_regs(xf86CrtcPtr crtc, DisplayModePtr mode)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- struct nouveau_crtc_state *regp = nv_crtc->state;
- struct nouveau_crtc_state *savep = &pNv->saved_regs.head[nv_crtc->head];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- bool lvds_output = false, tmds_output = false, off_chip_digital = false;
- int i;
-
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
- bool digital = false;
-
- if (output->crtc != crtc || !nv_encoder)
- continue;
-
- if (nv_encoder->dcb->type == OUTPUT_LVDS)
- digital = lvds_output = true;
- if (nv_encoder->dcb->type == OUTPUT_TMDS)
- digital = tmds_output = true;
- if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP && digital)
- off_chip_digital = true;
- }
-
- /* Registers not directly related to the (s)vga mode */
-
- /* What is the meaning of this register? */
- /* A few popular values are 0x18, 0x1c, 0x38, 0x3c */
- regp->CRTC[NV_CIO_CRE_ENH_INDEX] = savep->CRTC[NV_CIO_CRE_ENH_INDEX] & ~(1<<5);
-
- regp->crtc_eng_ctrl = 0;
- /* Except for rare conditions I2C is enabled on the primary crtc */
- if (nv_crtc->head == 0)
- regp->crtc_eng_ctrl |= NV_CRTC_FSEL_I2C;
- /* Set overlay to desired crtc. */
- if (pNv->overlayAdaptor) {
- NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv);
- if (pPriv->overlayCRTC == nv_crtc->head)
- regp->crtc_eng_ctrl |= NV_CRTC_FSEL_OVERLAY;
- }
-
- /* ADDRESS_SPACE_PNVM is the same as setting HCUR_ASI */
- regp->cursor_cfg = NV_PCRTC_CURSOR_CONFIG_CUR_LINES_64 |
- NV_PCRTC_CURSOR_CONFIG_CUR_PIXELS_64 |
- NV_PCRTC_CURSOR_CONFIG_ADDRESS_SPACE_PNVM;
- if (pNv->alphaCursor)
- regp->cursor_cfg |= NV_PCRTC_CURSOR_CONFIG_CUR_BPP_32;
- if (mode->Flags & V_DBLSCAN)
- regp->cursor_cfg |= NV_PCRTC_CURSOR_CONFIG_DOUBLE_SCAN_ENABLE;
-
- /* Unblock some timings */
- regp->CRTC[NV_CIO_CRE_53] = 0;
- regp->CRTC[NV_CIO_CRE_54] = 0;
-
- /* 0x00 is disabled, 0x11 is lvds, 0x22 crt and 0x88 tmds */
- if (lvds_output)
- regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x11;
- else if (tmds_output)
- regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x88;
- else
- regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x22;
-
- /* These values seem to vary */
- /* This register seems to be used by the bios to make certain decisions on some G70 cards? */
- regp->CRTC[NV_CIO_CRE_SCRATCH4__INDEX] = savep->CRTC[NV_CIO_CRE_SCRATCH4__INDEX];
-
- nv_crtc_set_digital_vibrance(crtc, nv_crtc->saturation);
-
- /* probably a scratch reg, but kept for cargo-cult purposes:
- * bit0: crtc0?, head A
- * bit6: lvds, head A
- * bit7: (only in X), head A
- */
- if (nv_crtc->head == 0)
- regp->CRTC[NV_CIO_CRE_4B] = savep->CRTC[NV_CIO_CRE_4B] | 0x80;
-
- /* The blob seems to take the current value from crtc 0, add 4 to that
- * and reuse the old value for crtc 1 */
- regp->CRTC[NV_CIO_CRE_TVOUT_LATENCY] = pNv->saved_regs.head[0].CRTC[NV_CIO_CRE_TVOUT_LATENCY];
- if (!nv_crtc->head)
- regp->CRTC[NV_CIO_CRE_TVOUT_LATENCY] += 4;
-
- /* the blob sometimes sets |= 0x10 (which is the same as setting |=
- * 1 << 30 on 0x60.830), for no apparent reason */
- regp->CRTC[NV_CIO_CRE_59] = off_chip_digital;
-
- regp->crtc_830 = mode->CrtcVDisplay - 3;
- regp->crtc_834 = mode->CrtcVDisplay - 1;
-
- if (pNv->Architecture == NV_ARCH_40)
- /* This is what the blob does */
- regp->crtc_850 = NVReadCRTC(pNv, 0, NV_PCRTC_850);
-
- if (pNv->Architecture == NV_ARCH_40)
- regp->gpio_ext = NVReadCRTC(pNv, 0, NV_PCRTC_GPIO_EXT);
-
- regp->crtc_cfg = NV_PCRTC_CONFIG_START_ADDRESS_HSYNC;
-
- /* Some misc regs */
- if (pNv->Architecture == NV_ARCH_40) {
- regp->CRTC[NV_CIO_CRE_85] = 0xFF;
- regp->CRTC[NV_CIO_CRE_86] = 0x1;
- }
-
- regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (pScrn->depth + 1) / 8;
- /* Enable slaved mode (called MODE_TV in nv4ref.h) */
- if (lvds_output || tmds_output)
- regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (1 << 7);
-
- /* Generic PRAMDAC regs */
-
- if (pNv->Architecture >= NV_ARCH_10)
- /* Only bit that bios and blob set. */
- regp->nv10_cursync = (1 << 25);
-
- regp->ramdac_gen_ctrl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS |
- NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL |
- NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON;
- if (pScrn->depth == 16)
- regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL;
- if (pNv->alphaCursor)
- regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG;
-
- regp->ramdac_630 = 0; /* turn off green mode (tv test pattern?) */
-
- nv_crtc_set_image_sharpening(crtc, nv_crtc->sharpness);
-
- /* Some values the blob sets */
- regp->ramdac_a20 = 0x0;
- regp->ramdac_a24 = 0xfffff;
- regp->ramdac_a34 = 0x1;
-}
-
-enum fp_display_regs {
- FP_DISPLAY_END,
- FP_TOTAL,
- FP_CRTC,
- FP_SYNC_START,
- FP_SYNC_END,
- FP_VALID_START,
- FP_VALID_END
-};
-
-/* this could be set in nv_output, but would require some rework of load/save */
-static void
-nv_crtc_mode_set_fp_regs(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjusted_mode)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- struct nouveau_crtc_state *regp = nv_crtc->state;
- struct nouveau_crtc_state *savep = &pNv->saved_regs.head[nv_crtc->head];
- struct nouveau_encoder *nv_encoder = NULL;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- uint32_t mode_ratio, panel_ratio;
- int i;
-
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- struct nouveau_encoder *tmp_nve = to_nouveau_encoder(output);
-
- if (output->crtc != crtc)
- continue;
-
- if (IS_DFP(tmp_nve->dcb->type)) {
- /* assumes a maximum of one fp output per crtc */
- nv_encoder = tmp_nve;
- break;
- }
- }
- if (!nv_encoder)
- return;
-
- regp->fp_horiz_regs[FP_DISPLAY_END] = adjusted_mode->HDisplay - 1;
- regp->fp_horiz_regs[FP_TOTAL] = adjusted_mode->HTotal - 1;
- if (!pNv->gf4_disp_arch ||
- (adjusted_mode->HSyncStart - adjusted_mode->HDisplay) >=
- pNv->vbios->digital_min_front_porch)
- regp->fp_horiz_regs[FP_CRTC] = adjusted_mode->HDisplay;
- else
- regp->fp_horiz_regs[FP_CRTC] = adjusted_mode->HSyncStart - pNv->vbios->digital_min_front_porch - 1;
- regp->fp_horiz_regs[FP_SYNC_START] = adjusted_mode->HSyncStart - 1;
- regp->fp_horiz_regs[FP_SYNC_END] = adjusted_mode->HSyncEnd - 1;
- regp->fp_horiz_regs[FP_VALID_START] = adjusted_mode->HSkew;
- regp->fp_horiz_regs[FP_VALID_END] = adjusted_mode->HDisplay - 1;
-
- regp->fp_vert_regs[FP_DISPLAY_END] = adjusted_mode->VDisplay - 1;
- regp->fp_vert_regs[FP_TOTAL] = adjusted_mode->VTotal - 1;
- regp->fp_vert_regs[FP_CRTC] = adjusted_mode->VTotal - 5 - 1;
- regp->fp_vert_regs[FP_SYNC_START] = adjusted_mode->VSyncStart - 1;
- regp->fp_vert_regs[FP_SYNC_END] = adjusted_mode->VSyncEnd - 1;
- regp->fp_vert_regs[FP_VALID_START] = 0;
- regp->fp_vert_regs[FP_VALID_END] = adjusted_mode->VDisplay - 1;
-
- /* bit26: a bit seen on some g7x, no as yet discernable purpose */
- regp->fp_control = NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS |
- (savep->fp_control & (1 << 26 | NV_PRAMDAC_FP_TG_CONTROL_READ_PROG));
- /* Deal with vsync/hsync polarity */
- /* LVDS screens do set this, but modes with +ve syncs are very rare */
- if (adjusted_mode->Flags & V_PVSYNC)
- regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS;
- if (adjusted_mode->Flags & V_PHSYNC)
- regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS;
- /* panel scaling first, as native would get set otherwise */
- if (nv_encoder->scaling_mode == SCALE_PANEL ||
- nv_encoder->scaling_mode == SCALE_NOSCALE) /* panel handles it */
- regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_CENTER;
- else if (mode->HDisplay == adjusted_mode->HDisplay &&
- mode->VDisplay == adjusted_mode->VDisplay) /* native mode */
- regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_NATIVE;
- else /* gpu needs to scale */
- regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_SCALE;
- if (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT)
- regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12;
- if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP &&
- adjusted_mode->Clock > 165000)
- regp->fp_control |= (2 << 24);
- if (nv_encoder->dual_link)
- regp->fp_control |= (8 << 28);
-
- regp->fp_debug_0 = NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND |
- NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND |
- NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR |
- NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR |
- NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED |
- NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE |
- NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE;
-
- /* We want automatic scaling */
- regp->fp_debug_1 = 0;
- /* This can override HTOTAL and VTOTAL */
- regp->fp_debug_2 = 0;
-
- /* Use 20.12 fixed point format to avoid floats */
- mode_ratio = (1 << 12) * mode->HDisplay / mode->VDisplay;
- panel_ratio = (1 << 12) * adjusted_mode->HDisplay / adjusted_mode->VDisplay;
- /* if ratios are equal, SCALE_ASPECT will automatically (and correctly)
- * get treated the same as SCALE_FULLSCREEN */
- if (nv_encoder->scaling_mode == SCALE_ASPECT && mode_ratio != panel_ratio) {
- uint32_t diff, scale;
- bool divide_by_2 = pNv->gf4_disp_arch;
-
- if (mode_ratio < panel_ratio) {
- /* vertical needs to expand to glass size (automatic)
- * horizontal needs to be scaled at vertical scale factor
- * to maintain aspect */
-
- scale = (1 << 12) * mode->VDisplay / adjusted_mode->VDisplay;
- regp->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE |
- XLATE(scale, divide_by_2, NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE);
-
- /* restrict area of screen used, horizontally */
- diff = adjusted_mode->HDisplay -
- adjusted_mode->VDisplay * mode_ratio / (1 << 12);
- regp->fp_horiz_regs[FP_VALID_START] += diff / 2;
- regp->fp_horiz_regs[FP_VALID_END] -= diff / 2;
- }
-
- if (mode_ratio > panel_ratio) {
- /* horizontal needs to expand to glass size (automatic)
- * vertical needs to be scaled at horizontal scale factor
- * to maintain aspect */
-
- scale = (1 << 12) * mode->HDisplay / adjusted_mode->HDisplay;
- regp->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE |
- XLATE(scale, divide_by_2, NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE);
-
- /* restrict area of screen used, vertically */
- diff = adjusted_mode->VDisplay -
- (1 << 12) * adjusted_mode->HDisplay / mode_ratio;
- regp->fp_vert_regs[FP_VALID_START] += diff / 2;
- regp->fp_vert_regs[FP_VALID_END] -= diff / 2;
- }
- }
-
- /* Output property. */
- if (nv_encoder && nv_encoder->dithering) {
- if (pNv->NVArch == 0x11)
- regp->dither = savep->dither | 0x00010000;
- else {
- int i;
- regp->dither = savep->dither | 0x00000001;
- for (i = 0; i < 3; i++) {
- regp->dither_regs[i] = 0xe4e4e4e4;
- regp->dither_regs[i + 3] = 0x44444444;
- }
- }
- } else {
- if (pNv->NVArch != 0x11) {
- /* reset them */
- int i;
- for (i = 0; i < 3; i++) {
- regp->dither_regs[i] = savep->dither_regs[i];
- regp->dither_regs[i + 3] = savep->dither_regs[i + 3];
- }
- }
- regp->dither = savep->dither;
- }
-}
-
-/**
- * Sets up registers for the given mode/adjusted_mode pair.
- *
- * The clocks, CRTCs and outputs attached to this CRTC must be off.
- *
- * This shouldn't enable any clocks, CRTCs, or outputs, but they should
- * be easily turned on/off after this.
- */
-static void
-nv_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
- DisplayModePtr adjusted_mode,
- int x, int y)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- NVPtr pNv = NVPTR(pScrn);
-
- NV_TRACE(pScrn, "CTRC mode on CRTC %d:\n", nv_crtc->head);
- xf86PrintModeline(pScrn->scrnIndex, mode);
- NV_TRACE(pScrn, "Output mode on CRTC %d:\n", nv_crtc->head);
- xf86PrintModeline(pScrn->scrnIndex, adjusted_mode);
-
- /* unlock must come after turning off FP_TG_CONTROL in output_prepare */
- nv_lock_vga_crtc_shadow(pNv, nv_crtc->head, -1);
-
- nv_crtc_mode_set_vga(crtc, mode, adjusted_mode);
- /* calculated in output_prepare, nv40 needs it written before calculating PLLs */
- if (pNv->Architecture == NV_ARCH_40)
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_SEL_CLK, pNv->set_state.sel_clk);
- nv_crtc_mode_set_regs(crtc, mode);
- nv_crtc_mode_set_fp_regs(crtc, mode, adjusted_mode);
- nv_crtc_calc_state_ext(crtc, mode, adjusted_mode->Clock);
-
- nouveau_hw_load_state(pScrn, nv_crtc->head, &pNv->set_state);
-
- NVCrtcSetBase(crtc, x, y);
-
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- /* turn on LFB swapping */
- {
- uint8_t tmp = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_RCR);
- tmp |= MASK(NV_CIO_CRE_RCR_ENDIAN_BIG);
- NVWriteVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_RCR, tmp);
- }
-#endif
-}
-
-static void nv_crtc_save(xf86CrtcPtr crtc)
-{
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- NVPtr pNv = NVPTR(crtc->scrn);
-
- if (pNv->twoHeads)
- NVSetOwner(pNv, nv_crtc->head);
-
- nouveau_hw_save_state(crtc->scrn, nv_crtc->head, &pNv->saved_regs);
-
- /* init some state to saved value */
- pNv->set_state.sel_clk = pNv->saved_regs.sel_clk & ~(0x5 << 16);
- nv_crtc->state->CRTC[NV_CIO_CRE_LCD__INDEX] = pNv->saved_regs.head[nv_crtc->head].CRTC[NV_CIO_CRE_LCD__INDEX];
-}
-
-static void nv_crtc_restore(xf86CrtcPtr crtc)
-{
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- NVPtr pNv = NVPTR(crtc->scrn);
- int head = nv_crtc->head;
- uint8_t saved_cr21 = pNv->saved_regs.head[head].CRTC[NV_CIO_CRE_21];
-
- if (pNv->twoHeads)
- NVSetOwner(pNv, head);
-
- nouveau_hw_load_state(crtc->scrn, head, &pNv->saved_regs);
- nv_lock_vga_crtc_shadow(pNv, head, saved_cr21);
-
- nv_crtc->last_dpms = NV_DPMS_CLEARED;
-}
-
-static void nv_crtc_prepare(xf86CrtcPtr crtc)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
-
- if (pNv->twoHeads)
- NVSetOwner(pNv, nv_crtc->head);
-
- crtc->funcs->dpms(crtc, DPMSModeOff);
-
- /* Sync the engine before adjust mode */
- if (pNv->EXADriverPtr) {
- exaMarkSync(pScrn->pScreen);
- exaWaitSync(pScrn->pScreen);
- }
-
- NVBlankScreen(pNv, nv_crtc->head, true);
-
- /* Some more preperation. */
- NVWriteCRTC(pNv, nv_crtc->head, NV_PCRTC_CONFIG, NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA);
- if (pNv->Architecture == NV_ARCH_40) {
- uint32_t reg900 = NVReadRAMDAC(pNv, nv_crtc->head, NV_PRAMDAC_900);
- NVWriteRAMDAC(pNv, nv_crtc->head, NV_PRAMDAC_900, reg900 & ~0x10000);
- }
-}
-
-static void nv_crtc_commit(xf86CrtcPtr crtc)
-{
- crtc->funcs->dpms (crtc, DPMSModeOn);
-
- if (crtc->scrn->pScreen != NULL) {
- NVPtr pNv = NVPTR(crtc->scrn);
-
- xf86_reload_cursors (crtc->scrn->pScreen);
- if (!pNv->alphaCursor) {
- /* this works round the fact that xf86_reload_cursors
- * will quite happily show the hw cursor when it knows
- * the hardware can't do alpha, and the current cursor
- * has an alpha channel
- */
- xf86ForceHWCursor(crtc->scrn->pScreen, 1);
- xf86ForceHWCursor(crtc->scrn->pScreen, 0);
- }
- }
-}
-
-static void nv_crtc_destroy(xf86CrtcPtr crtc)
-{
- xfree(to_nouveau_crtc(crtc));
-}
-
-static Bool nv_crtc_lock(xf86CrtcPtr crtc)
-{
- return FALSE;
-}
-
-static void nv_crtc_unlock(xf86CrtcPtr crtc)
-{
-}
-
-static void
-nv_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
- int size)
-{
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- NVPtr pNv = NVPTR(crtc->scrn);
- struct rgb { uint8_t r, g, b; } __attribute__((packed)) *rgbs;
- int i;
-
- rgbs = (struct rgb *)nv_crtc->state->DAC;
-
- for (i = 0; i < 256; i++) {
- rgbs[i].r = red[i] >> 8;
- rgbs[i].g = green[i] >> 8;
- rgbs[i].b = blue[i] >> 8;
- }
-
- nouveau_hw_load_state_palette(pNv, nv_crtc->head, &pNv->set_state);
-}
-
-/**
- * Allocates memory for a locked-in-framebuffer shadow of the given
- * width and height for this CRTC's rotated shadow framebuffer.
- */
-
-static void *
-nv_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
-{
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- ScrnInfoPtr pScrn = crtc->scrn;
- ScreenPtr pScreen = pScrn->pScreen;
- NVPtr pNv = NVPTR(pScrn);
- void *offset;
- int size, align = 64;
-
- nv_crtc->shadow_pitch = pScrn->displayWidth * (pScrn->bitsPerPixel/8);
- size = nv_crtc->shadow_pitch * height;
-
- assert(nv_crtc->shadow == NULL);
- if (!pScreen) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Can't allocate shadow memory for rotated CRTC at server regeneration\n");
- return NULL;
- }
- nv_crtc->shadow = exaOffscreenAlloc(pScreen, size, align, TRUE, NULL, NULL);
- if (nv_crtc->shadow == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Couldn't allocate shadow memory for rotated CRTC.\n");
- return NULL;
- }
- offset = pNv->offscreen_map + nv_crtc->shadow->offset;
-
- return offset;
-}
-
-/**
- * Creates a pixmap for this CRTC's rotated shadow framebuffer.
- */
-static PixmapPtr
-nv_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
-{
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- ScrnInfoPtr pScrn = crtc->scrn;
- PixmapPtr rotate_pixmap;
-
- if (!data)
- data = crtc->funcs->shadow_allocate (crtc, width, height);
-
- rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen, width, height,
- pScrn->depth,
- pScrn->bitsPerPixel,
- nv_crtc->shadow_pitch, data);
- if (rotate_pixmap == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Couldn't allocate shadow pixmap for rotated CRTC\n");
- }
-
- return rotate_pixmap;
-}
-
-static void
-nv_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- ScreenPtr pScreen = pScrn->pScreen;
-
- if (rotate_pixmap) { /* This should also unmap the buffer object if relevant. */
- pScreen->DestroyPixmap(rotate_pixmap);
- }
-
- if (data && nv_crtc->shadow)
- exaOffscreenFree(pScreen, nv_crtc->shadow);
-
- nv_crtc->shadow = NULL;
-}
-
-static const xf86CrtcFuncsRec nv_crtc_funcs = {
- .dpms = nv_crtc_dpms,
- .save = nv_crtc_save,
- .restore = nv_crtc_restore,
- .mode_fixup = nv_crtc_mode_fixup,
- .mode_set = nv_crtc_mode_set,
- .prepare = nv_crtc_prepare,
- .commit = nv_crtc_commit,
- .destroy = nv_crtc_destroy,
- .lock = nv_crtc_lock,
- .unlock = nv_crtc_unlock,
- .set_cursor_colors = nv_crtc_set_cursor_colors,
- .set_cursor_position = nv_crtc_set_cursor_position,
- .show_cursor = nv_crtc_show_cursor,
- .hide_cursor = nv_crtc_hide_cursor,
- .load_cursor_image = nv_crtc_load_cursor_image,
- .load_cursor_argb = nv_crtc_load_cursor_argb,
- .gamma_set = nv_crtc_gamma_set,
- .shadow_create = nv_crtc_shadow_create,
- .shadow_allocate = nv_crtc_shadow_allocate,
- .shadow_destroy = nv_crtc_shadow_destroy,
-#ifdef RANDR_13_INTERFACE
- .set_origin = NVCrtcSetBase,
-#endif
-};
-
-void
-nv_crtc_init(ScrnInfoPtr pScrn, int crtc_num)
-{
- NVPtr pNv = NVPTR(pScrn);
- static xf86CrtcFuncsRec crtcfuncs;
- xf86CrtcPtr crtc;
- struct nouveau_crtc *nv_crtc;
- int i;
-
- crtcfuncs = nv_crtc_funcs;
-
- if (!pNv->alphaCursor)
- crtcfuncs.load_cursor_argb = NULL;
- if (pNv->NoAccel) {
- crtcfuncs.shadow_create = NULL;
- crtcfuncs.shadow_allocate = NULL;
- crtcfuncs.shadow_destroy = NULL;
- }
-
- if (!(crtc = xf86CrtcCreate(pScrn, &crtcfuncs)))
- return;
-
- if (!(nv_crtc = xcalloc(1, sizeof (struct nouveau_crtc)))) {
- xf86CrtcDestroy(crtc);
- return;
- }
-
- nv_crtc->head = crtc_num;
- nv_crtc->last_dpms = NV_DPMS_CLEARED;
- nv_crtc->state = &pNv->set_state.head[crtc_num];
-
- crtc->driver_private = nv_crtc;
-
- /* Initialise the default LUT table. */
- for (i = 0; i < 256; i++) {
- nv_crtc->state->DAC[i*3] = i;
- nv_crtc->state->DAC[(i*3)+1] = i;
- nv_crtc->state->DAC[(i*3)+2] = i;
- }
-}
-
-void NVCrtcSetBase(xf86CrtcPtr crtc, int x, int y)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- struct nouveau_crtc_state *regp = nv_crtc->state;
- struct nouveau_bo *bo;
- uint32_t start, pitch;
-
- bo = pNv->scanout;
- pitch = pScrn->displayWidth * (pScrn->bitsPerPixel / 8);
- if (crtc->rotatedData != NULL) {
- pitch = nv_crtc->shadow_pitch;
- bo = pNv->offscreen;
- x = 0;
- y = 0;
- }
-
- if (nv_crtc->bo)
- nouveau_bo_unpin(nv_crtc->bo);
- nouveau_bo_pin(bo, NOUVEAU_BO_VRAM);
- nv_crtc->bo = bo;
-
- start = nv_crtc->bo->offset;
- start += (y * pScrn->displayWidth + x) * pScrn->bitsPerPixel / 8;
- if (crtc->rotatedData != NULL)
- start += nv_crtc->shadow->offset;
-
- regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = pitch >> 3;
- regp->CRTC[NV_CIO_CRE_RPC0_INDEX] =
- XLATE(pitch >> 3, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
- crtc_wr_cio_state(crtc, NV_CIO_CRE_RPC0_INDEX);
- crtc_wr_cio_state(crtc, NV_CIO_CR_OFFSET_INDEX);
-
- start &= ~3;
- nv_crtc->state->fb_start = start;
- NVWriteCRTC(pNv, nv_crtc->head, NV_PCRTC_START, start);
-
- crtc->x = x;
- crtc->y = y;
-}
diff --git a/src/nv_cursor.c b/src/nv_cursor.c
deleted file mode 100644
index 3df1539..0000000
--- a/src/nv_cursor.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright 2003 NVIDIA, Corporation
- * Copyright 2007 Maarten Maathuis
- * Copyright 2009 Stuart Bennett
- *
- * 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 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.
- */
-
-#include "nv_include.h"
-
-#define TO_ARGB1555(c) (0x8000 | /* Mask bit */ \
- ((c & 0xf80000) >> 9 ) | /* Red */ \
- ((c & 0xf800) >> 6 ) | /* Green */ \
- ((c & 0xf8) >> 3 )) /* Blue */
-#define TO_ARGB8888(c) (0xff000000 | c)
-
-#define SOURCE_MASK_INTERLEAVE 32
-#define TRANSPARENT_PIXEL 0
-
-/*
- * Convert a source/mask bitmap cursor to an ARGB cursor, clipping or
- * padding as necessary. source/mask are assumed to be alternated each
- * SOURCE_MASK_INTERLEAVE bits.
- */
-void
-nv_cursor_convert_cursor(uint32_t *src, void *dst, int src_stride, int dst_stride,
- int bpp, uint32_t fg, uint32_t bg)
-{
- int width = min(src_stride, dst_stride);
- uint32_t b, m, pxval;
- int i, j, k;
-
- for (i = 0; i < width; i++) {
- for (j = 0; j < width / SOURCE_MASK_INTERLEAVE; j++) {
- int src_off = i*src_stride/SOURCE_MASK_INTERLEAVE + j;
- int dst_off = i*dst_stride + j*SOURCE_MASK_INTERLEAVE;
-
- b = src[2*src_off];
- m = src[2*src_off + 1];
-
- for (k = 0; k < SOURCE_MASK_INTERLEAVE; k++) {
- pxval = TRANSPARENT_PIXEL;
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- if (m & 0x80000000)
- pxval = (b & 0x80000000) ? fg : bg;
- b <<= 1;
- m <<= 1;
-#else
- if (m & 1)
- pxval = (b & 1) ? fg : bg;
- b >>= 1;
- m >>= 1;
-#endif
- if (bpp == 32)
- ((uint32_t *)dst)[dst_off + k] = pxval;
- else
- ((uint16_t *)dst)[dst_off + k] = pxval;
- }
- }
- }
-}
-
-static void nv_cursor_transform_cursor(NVPtr pNv, struct nouveau_crtc *nv_crtc)
-{
- uint16_t *tmp;
- struct nouveau_bo *cursor = NULL;
- int px = nv_cursor_pixels(pNv);
- int width = nv_cursor_width(pNv);
-
- if (!(tmp = xcalloc(px, 4)))
- return;
-
- /* convert to colour cursor */
- nv_cursor_convert_cursor(pNv->curImage, tmp, width, width,
- pNv->alphaCursor ? 32 : 16, nv_crtc->cursor_fg,
- nv_crtc->cursor_bg);
-
- nouveau_bo_ref(nv_crtc->head ? pNv->Cursor2 : pNv->Cursor, &cursor);
- nouveau_bo_map(cursor, NOUVEAU_BO_WR);
-
- memcpy(cursor->map, tmp, px * 4);
-
- nouveau_bo_unmap(cursor);
- nouveau_bo_ref(NULL, &cursor);
-
- xfree(tmp);
-}
-
-void nv_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
-{
- NVPtr pNv = NVPTR(crtc->scrn);
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- uint32_t fore, back;
-
- if (pNv->alphaCursor) {
- fore = TO_ARGB8888(fg);
- back = TO_ARGB8888(bg);
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
- fore = lswapl(fore);
- back = lswapl(back);
- }
-#endif
- } else {
- fore = TO_ARGB1555(fg);
- back = TO_ARGB1555(bg);
- }
-
- if (nv_crtc->cursor_fg != fore || nv_crtc->cursor_bg != back) {
- nv_crtc->cursor_fg = fore;
- nv_crtc->cursor_bg = back;
- nv_cursor_transform_cursor(pNv, nv_crtc);
- }
-}
-
-void nv_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *image)
-{
- NVPtr pNv = NVPTR(crtc->scrn);
-
- /* save copy of image for colour changes */
- memcpy(pNv->curImage, image, nv_cursor_pixels(pNv) / 4);
-
- nv_cursor_transform_cursor(pNv, to_nouveau_crtc(crtc));
-}
-
-void nv_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
-{
- NVPtr pNv = NVPTR(crtc->scrn);
- int head = to_nouveau_crtc(crtc)->head, i, alpha;
- struct nouveau_bo *cursor = NULL;
- uint32_t *dst, *src = (uint32_t *)image, tmp;
-
- nouveau_bo_ref(head ? pNv->Cursor2 : pNv->Cursor, &cursor);
- nouveau_bo_map(cursor, NOUVEAU_BO_WR);
- dst = cursor->map;
-
- /* nv11+ supports premultiplied (PM), or non-premultiplied (NPM) alpha
- * cursors (though NPM in combination with fp dithering may not work on
- * nv11, from "nv" driver history)
- * NPM mode needs NV_PCRTC_CURSOR_CONFIG_ALPHA_BLEND set and is what the
- * blob uses, however we get given PM cursors so we use PM mode
- */
- for (i = 0; i < nv_cursor_pixels(pNv); i++) {
- /* hw gets unhappy if alpha <= rgb values. for a PM image "less
- * than" shouldn't happen; fix "equal to" case by adding one to
- * alpha channel (slightly inaccurate, but so is attempting to
- * get back to NPM images, due to limits of integer precision)
- */
- alpha = (*src >> 24);
- if (!alpha || alpha == 0xff)
- /* alpha == max(r,g,b) works ok for 0x0 and 0xff */
- tmp = *src;
- else
- tmp = ((alpha + 1) << 24) | (*src & 0xffffff);
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- if (pNv->NVArch == 0x11)
- tmp = lswapl(tmp);
-#endif
- *dst++ = tmp;
- src++;
- }
-
- nouveau_bo_unmap(cursor);
- nouveau_bo_ref(NULL, &cursor);
-}
-
-void nv_crtc_show_cursor(xf86CrtcPtr crtc)
-{
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
-
- nv_show_cursor(NVPTR(crtc->scrn), nv_crtc->head, true);
-}
-
-void nv_crtc_hide_cursor(xf86CrtcPtr crtc)
-{
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
-
- nv_show_cursor(NVPTR(crtc->scrn), nv_crtc->head, false);
-}
-
-void nv_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
-{
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- NVPtr pNv = NVPTR(crtc->scrn);
-
- NVWriteRAMDAC(pNv, nv_crtc->head, NV_PRAMDAC_CU_START_POS,
- XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) |
- XLATE(x, 0, NV_PRAMDAC_CU_START_POS_X));
-}
-
-Bool NVCursorInitRandr12(ScreenPtr pScreen)
-{
- NVPtr pNv = NVPTR(xf86Screens[pScreen->myNum]);
- int width = nv_cursor_width(pNv);
- int flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
- HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
- (pNv->alphaCursor ? HARDWARE_CURSOR_ARGB : 0);
-
- return xf86_cursors_init(pScreen, width, width, flags);
-}
diff --git a/src/nv_dma.c b/src/nv_dma.c
index ed51b9f..c3d7639 100644
--- a/src/nv_dma.c
+++ b/src/nv_dma.c
@@ -25,3 +25,2 @@
#include "nv_include.h"
-#include "nvreg.h"
diff --git a/src/nv_driver.c b/src/nv_driver.c
index a0656af..4f39eb5 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -29,5 +29,3 @@
#include "xf86drm.h"
-#ifdef XF86DRM_MODE
#include "xf86drmMode.h"
-#endif
@@ -57,4 +55,2 @@ static Bool NVMapMem(ScrnInfoPtr pScrn);
static Bool NVUnmapMem(ScrnInfoPtr pScrn);
-static void NVSave(ScrnInfoPtr pScrn);
-static void NVRestore(ScrnInfoPtr pScrn);
@@ -325,46 +321,4 @@ NVAdjustFrame(int scrnIndex, int x, int y, int flags)
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- NVPtr pNv = NVPTR(pScrn);
-
- if (pNv->kms_enable) {
- drmmode_adjust_frame(pScrn, x, y, flags);
- } else {
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- xf86CrtcPtr crtc = config->output[config->compat_output]->crtc;
-
- if (crtc && crtc->enabled)
- NVCrtcSetBase(crtc, x, y);
- }
-}
-static Bool
-NV50AcquireDisplay(ScrnInfoPtr pScrn)
-{
- if (!NV50DispInit(pScrn))
- return FALSE;
- if (!NV50CursorAcquire(pScrn))
- return FALSE;
-
- return TRUE;
-}
-
-static Bool
-NV50ReleaseDisplay(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
-
- NV50CursorRelease(pScrn);
- NV50DispShutdown(pScrn);
-
- if (pNv->pInt10 && pNv->Int10Mode) {
- xf86Int10InfoPtr pInt10 = pNv->pInt10;
-
- pInt10->num = 0x10;
- pInt10->ax = 0x4f02;
- pInt10->bx = pNv->Int10Mode | 0x8000;
- pInt10->cx =
- pInt10->dx = 0;
- xf86ExecX86int10(pInt10);
- }
-
- return TRUE;
+ drmmode_adjust_frame(pScrn, x, y, flags);
}
@@ -395,19 +349,2 @@ NVEnterVT(int scrnIndex, int flags)
- if (!pNv->kms_enable) {
- /* Save current state, VGA fonts etc */
- NVSave(pScrn);
-
- /* Clear the framebuffer, we don't want to see garbage
- * on-screen up until X decides to draw something
- */
- nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR);
- memset(pNv->scanout->map, 0, pNv->scanout->size);
- nouveau_bo_unmap(pNv->scanout);
-
- if (pNv->Architecture == NV_ARCH_50) {
- if (!NV50AcquireDisplay(pScrn))
- return FALSE;
- }
- }
-
pNv->allow_dpms = FALSE;
@@ -445,9 +382,2 @@ NVLeaveVT(int scrnIndex, int flags)
ErrorF("Error dropping master: %d\n", ret);
-
- if (!pNv->kms_enable) {
- if (pNv->Architecture < NV_ARCH_50)
- NVRestore(pScrn);
- else
- NV50ReleaseDisplay(pScrn);
- }
}
@@ -579,12 +509,2 @@ NVFreeScreen(int scrnIndex, int flags)
- if (pNv->Architecture == NV_ARCH_50 && !pNv->kms_enable) {
- NV50ConnectorDestroy(pScrn);
- NV50OutputDestroy(pScrn);
- NV50CrtcDestroy(pScrn);
- }
-
- /* Free this here and not in CloseScreen, as it's needed after the first server generation. */
- if (pNv->pInt10)
- xf86FreeInt10(pNv->pInt10);
-
xfree(pScrn->driverPrivate);
@@ -593,79 +513,2 @@ NVFreeScreen(int scrnIndex, int flags)
-static Bool
-nouveau_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- ScreenPtr screen = screenInfo.screens[scrn->scrnIndex];
- NVPtr pNv = NVPTR(scrn);
- uint32_t pitch, old_width, old_height, old_pitch;
- struct nouveau_bo *old_bo = NULL;
- uint32_t tile_mode = 0, tile_flags = 0, ah = height;
- PixmapPtr ppix = screen->GetScreenPixmap(screen);
- int ret, i;
-
- ErrorF("resize called %d %d\n", width, height);
-
- if (scrn->virtualX == width && scrn->virtualY == height)
- return TRUE;
-
- pitch = nv_pitch_align(pNv, width, scrn->depth);
- pitch *= (scrn->bitsPerPixel >> 3);
-
- old_width = scrn->virtualX;
- old_height = scrn->virtualY;
- old_pitch = scrn->displayWidth;
- nouveau_bo_ref(pNv->scanout, &old_bo);
- nouveau_bo_ref(NULL, &pNv->scanout);
-
- scrn->virtualX = width;
- scrn->virtualY = height;
- scrn->displayWidth = pitch / (scrn->bitsPerPixel >> 3);
-
- ret = nouveau_bo_new_tile(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP,
- 0, pitch * ah, tile_mode, tile_flags,
- &pNv->scanout);
- if (ret)
- goto fail;
-
- if (pNv->ShadowPtr) {
- xfree(pNv->ShadowPtr);
- pNv->ShadowPitch = pitch;
- pNv->ShadowPtr = xalloc(pNv->ShadowPitch * height);
- }
-
- nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR);
- screen->ModifyPixmapHeader(ppix, width, height, -1, -1, pitch,
- (!pNv->NoAccel || pNv->ShadowFB) ?
- pNv->ShadowPtr : pNv->scanout->map);
- scrn->pixmapPrivate.ptr = ppix->devPrivate.ptr;
- nouveau_bo_unmap(pNv->scanout);
-
- for (i = 0; i < xf86_config->num_crtc; i++) {
- xf86CrtcPtr crtc = xf86_config->crtc[i];
-
- if (!crtc->enabled)
- continue;
-
- xf86CrtcSetMode(crtc, &crtc->mode, crtc->rotation,
- crtc->x, crtc->y);
- }
-
- nouveau_bo_ref(NULL, &old_bo);
-
- NVDRIFinishScreenInit(scrn, true);
- return TRUE;
-
- fail:
- nouveau_bo_ref(old_bo, &pNv->scanout);
- scrn->virtualX = old_width;
- scrn->virtualY = old_height;
- scrn->displayWidth = old_pitch;
-
- return FALSE;
-}
-
-static const xf86CrtcConfigFuncsRec nv_xf86crtc_config_funcs = {
- nouveau_xf86crtc_resize
-};
-
#define NVPreInitFail(fmt, args...) do { \
@@ -738,10 +581,10 @@ NVPreInitDRM(ScrnInfoPtr pScrn)
*/
-#ifdef XF86DRM_MODE
- pNv->kms_enable = !drmCheckModesettingSupported(bus_id);
-#endif
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "[drm] kernel modesetting %s\n", pNv->kms_enable ?
- "in use" : "not available");
-
+ if (drmCheckModesettingSupported(bus_id)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] kernel modesetting not available\n");
+ xfree(bus_id);
+ return FALSE;
+ }
xfree(bus_id);
+
return TRUE;
@@ -854,10 +697,2 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
- /* Initialize the card through int10 interface if needed */
- if (xf86LoadSubModule(pScrn, "int10")) {
-#if !defined(__alpha__) && !defined(__powerpc__)
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n");
- pNv->pInt10 = xf86InitInt10(pNv->pEnt->index);
-#endif
- }
-
/* Initialise the kernel module */
@@ -866,19 +701,2 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
- /* Save current console video mode */
- if (pNv->Architecture >= NV_ARCH_50 && pNv->pInt10 && !pNv->kms_enable) {
- const xf86Int10InfoPtr pInt10 = pNv->pInt10;
-
- pInt10->num = 0x10;
- pInt10->ax = 0x4f03;
- pInt10->bx =
- pInt10->cx =
- pInt10->dx = 0;
- xf86ExecX86int10(pInt10);
- pNv->Int10Mode = pInt10->bx & 0x3fff;
-
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "VESA-HACK: Console VGA mode is 0x%x\n",
- pNv->Int10Mode);
- }
-
/* Set pScrn->monitor */
@@ -901,4 +719,4 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
/* OK on NV50 KMS */
- if (!pNv->kms_enable || pNv->Architecture != NV_ARCH_50)
- NVPreInitFail("Depth 30 supported on G80+KMS only\n");
+ if (pNv->Architecture != NV_ARCH_50)
+ NVPreInitFail("Depth 30 supported on G80 only\n");
break;
@@ -980,9 +798,2 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
- pNv->FpScale = TRUE;
-
- if (xf86GetOptValBool(pNv->Options, OPTION_FP_SCALE, &pNv->FpScale)) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Flat panel scaling %s\n",
- pNv->FpScale ? "on" : "off");
- }
-
if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) {
@@ -1002,12 +813,6 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
xf86ReturnOptValBool(pNv->Options, OPTION_EXA_PIXMAPS, TRUE)) {
- if (pNv->kms_enable) {
- pNv->exa_driver_pixmaps = TRUE;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "EXAPixmaps support requires KMS\n");
- }
+ pNv->exa_driver_pixmaps = TRUE;
}
- if (!pNv->NoAccel && pNv->kms_enable &&
- pNv->Architecture >= NV_ARCH_50) {
+ if (!pNv->NoAccel && pNv->Architecture >= NV_ARCH_50) {
pNv->wfb_enabled = TRUE;
@@ -1026,109 +831,6 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
- pNv->FPDither = FALSE;
- if (xf86GetOptValBool(pNv->Options, OPTION_FP_DITHER, &(pNv->FPDither)))
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "enabling flat panel dither\n");
-
- if (pNv->pEnt->device->MemBase != 0) {
- /* Require that the config file value matches one of the PCI values. */
- if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->MemBase)) {
- NVPreInitFail(
- "MemBase 0x%08lX doesn't match any PCI base register.\n",
- pNv->pEnt->device->MemBase);
- }
- pNv->VRAMPhysical = pNv->pEnt->device->MemBase;
- from = X_CONFIG;
- } else {
- if (pNv->PciInfo->regions[1].base_addr != 0) {
- pNv->VRAMPhysical = pNv->PciInfo->regions[1].base_addr & 0xff800000;
- from = X_PROBED;
- } else {
- NVPreInitFail("No valid FB address in PCI config space\n");
- return FALSE;
- }
- }
- xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
- (unsigned long)pNv->VRAMPhysical);
-
- if (pNv->pEnt->device->IOBase != 0) {
- /* Require that the config file value matches one of the PCI values. */
- if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->IOBase)) {
- NVPreInitFail("IOBase 0x%08lX doesn't match any PCI base register.\n",
- pNv->pEnt->device->IOBase);
- }
- pNv->IOAddress = pNv->pEnt->device->IOBase;
- from = X_CONFIG;
- } else {
- if (pNv->PciInfo->regions[0].base_addr != 0) {
- pNv->IOAddress = pNv->PciInfo->regions[0].base_addr & 0xffffc000;
- from = X_PROBED;
- } else {
- NVPreInitFail("No valid MMIO address in PCI config space\n");
- }
- }
- xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
- (unsigned long)pNv->IOAddress);
-
-#ifdef XF86DRM_MODE
- if (pNv->kms_enable){
- ret = drmmode_pre_init(pScrn, nouveau_device(pNv->dev)->fd,
- pScrn->bitsPerPixel >> 3);
- if (ret == FALSE)
- NVPreInitFail("Kernel modesetting failed to initialize\n");
- } else
-#endif
- {
- int max_width, max_height;
-
- if (pNv->Architecture < NV_ARCH_10) {
- max_width = (pScrn->bitsPerPixel > 16) ? 2032 : 2048;
- max_height = 2048;
- } else if (pNv->Architecture < NV_ARCH_50) {
- max_width = (pScrn->bitsPerPixel > 16) ? 4080 : 4096;
- max_height = 4096;
- } else {
- max_width = (pScrn->bitsPerPixel > 16) ? 8176 : 8192;
- max_height = 8192;
- }
-
- /* Allocate an xf86CrtcConfig */
- xf86CrtcConfigInit(pScrn, &nv_xf86crtc_config_funcs);
- xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height);
- }
-
- NVCommonSetup(pScrn);
-
- if (!pNv->kms_enable) {
- if (pNv->Architecture == NV_ARCH_50)
- if (!NV50DispPreInit(pScrn))
- NVPreInitFail("\n");
-
- /* This is the internal system, not the randr-1.2 ones. */
- if (pNv->Architecture == NV_ARCH_50) {
- NV50CrtcInit(pScrn);
- NV50ConnectorInit(pScrn);
- NV50OutputSetup(pScrn);
- }
-
- for (i = 0; i <= pNv->twoHeads; i++) {
- if (pNv->Architecture == NV_ARCH_50)
- nv50_crtc_init(pScrn, i);
- else
- nv_crtc_init(pScrn, i);
- }
-
- if (pNv->Architecture < NV_ARCH_50) {
- NVLockVgaCrtcs(pNv, false);
- NvSetupOutputs(pScrn);
- } else
- nv50_output_create(pScrn); /* create randr-1.2 "outputs". */
-
- if (!xf86InitialConfiguration(pScrn, TRUE))
- NVPreInitFail("No valid modes.\n");
- }
-
- pScrn->videoRam = pNv->RamAmountKBytes;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kBytes\n",
- pScrn->videoRam);
-
- pNv->VRAMPhysicalSize = pScrn->videoRam * 1024;
+ ret = drmmode_pre_init(pScrn, nouveau_device(pNv->dev)->fd,
+ pScrn->bitsPerPixel >> 3);
+ if (ret == FALSE)
+ NVPreInitFail("Kernel modesetting failed to initialize\n");
@@ -1189,2 +891,3 @@ NVMapMem(ScrnInfoPtr pScrn)
NVPtr pNv = NVPTR(pScrn);
+ struct nouveau_device *dev = pNv->dev;
uint64_t res;
@@ -1193,8 +896,4 @@ NVMapMem(ScrnInfoPtr pScrn)
- nouveau_device_get_param(pNv->dev, NOUVEAU_GETPARAM_FB_SIZE, &res);
- pNv->VRAMSize=res;
- nouveau_device_get_param(pNv->dev, NOUVEAU_GETPARAM_FB_PHYSICAL, &res);
+ nouveau_device_get_param(dev, NOUVEAU_GETPARAM_FB_PHYSICAL, &res);
pNv->VRAMPhysical=res;
- nouveau_device_get_param(pNv->dev, NOUVEAU_GETPARAM_AGP_SIZE, &res);
- pNv->AGPSize=res;
@@ -1209,3 +908,3 @@ NVMapMem(ScrnInfoPtr pScrn)
- ret = nouveau_bo_new_tile(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP,
+ ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP,
0, size, tile_mode, tile_flags,
@@ -1222,6 +921,6 @@ NVMapMem(ScrnInfoPtr pScrn)
if (pNv->NoAccel)
- goto skip_offscreen_gart;
+ return TRUE;
if (!pNv->exa_driver_pixmaps) {
- size = (pNv->VRAMPhysicalSize / 2) - size;
+ size = (dev->vm_vram_size / 2) - size;
@@ -1232,3 +931,3 @@ NVMapMem(ScrnInfoPtr pScrn)
- ret = nouveau_bo_new_tile(pNv->dev, NOUVEAU_BO_VRAM |
+ ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM |
NOUVEAU_BO_MAP, 0, size, tile_mode,
@@ -1250,18 +949,12 @@ NVMapMem(ScrnInfoPtr pScrn)
- if (pNv->AGPSize) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "AGPGART: %dMiB available\n",
- (unsigned int)(pNv->AGPSize >> 20));
- if (pNv->AGPSize > (16*1024*1024))
- size = 16*1024*1024;
- else
- /* always leave 512kb for other things like the fifos */
- size = pNv->AGPSize - 512*1024;
- } else {
- size = (4 << 20) - (1 << 18) ;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "GART: PCI DMA - using %dKiB\n", size >> 10);
- }
- if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: %dMiB available\n",
+ (unsigned int)(dev->vm_gart_size >> 20));
+ if (dev->vm_gart_size > (16 * 1024 * 1024))
+ size = 16 * 1024 * 1024;
+ else
+ /* always leave 512kb for other things like the fifos */
+ size = dev->vm_gart_size - 512*1024;
+
+ if (nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
0, size, &pNv->GART)) {
@@ -1276,52 +969,2 @@ NVMapMem(ScrnInfoPtr pScrn)
-skip_offscreen_gart:
- /* We don't need to allocate cursors / lut here if we're using
- * kernel modesetting
- **/
- if (pNv->kms_enable)
- return TRUE;
-
- if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN |
- NOUVEAU_BO_MAP, 0, 64 * 64 * 4, &pNv->Cursor)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate memory for hardware cursor\n");
- return FALSE;
- }
-
- if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN |
- NOUVEAU_BO_MAP, 0, 64 * 64 * 4, &pNv->Cursor2)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate memory for hardware cursor\n");
- return FALSE;
- }
-
- /* This is not the ideal solution, but significant changes are needed
- * otherwise. Ideally you do this once upon preinit, but drm is
- * closed between screen inits.
- */
- if (pNv->Architecture == NV_ARCH_50) {
- int i;
-
- for(i = 0; i < 2; i++) {
- nouveauCrtcPtr crtc = pNv->crtc[i];
-
- if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_PIN |
- NOUVEAU_BO_MAP, 0, 0x1000,
- &crtc->lut)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate memory for lut %d\n", i);
- return FALSE;
- }
-
- /* Copy the last known values. */
- if (crtc->lut_values_valid) {
- nouveau_bo_map(crtc->lut, NOUVEAU_BO_WR);
- memcpy(crtc->lut->map, crtc->lut_values,
- 4 * 256 * sizeof(uint16_t));
- nouveau_bo_unmap(crtc->lut);
- }
- }
- }
-
return TRUE;
@@ -1338,11 +981,4 @@ NVUnmapMem(ScrnInfoPtr pScrn)
- if (!pNv->dev) {
- pci_device_unmap_range(pNv->PciInfo, pNv->VRAMMap,
- pNv->PciInfo->regions[1].size);
- }
+ drmmode_remove_fb(pScrn);
-#ifdef XF86DRM_MODE
- if (pNv->kms_enable)
- drmmode_remove_fb(pScrn);
-#endif
nouveau_bo_ref(NULL, &pNv->scanout);
@@ -1350,16 +986,2 @@ NVUnmapMem(ScrnInfoPtr pScrn)
nouveau_bo_ref(NULL, &pNv->GART);
- nouveau_bo_ref(NULL, &pNv->Cursor);
- nouveau_bo_ref(NULL, &pNv->Cursor2);
-
- /* Again not the most ideal way. */
- if (pNv->Architecture == NV_ARCH_50 && !pNv->kms_enable) {
- int i;
-
- for(i = 0; i < 2; i++) {
- nouveauCrtcPtr crtc = pNv->crtc[i];
-
- nouveau_bo_ref(NULL, &crtc->lut);
- }
- }
-
return TRUE;
@@ -1367,34 +989,2 @@ NVUnmapMem(ScrnInfoPtr pScrn)
-
-/*
- * Restore the initial (text) mode.
- */
-static void
-NVRestore(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
-
- NVLockVgaCrtcs(pNv, false);
-
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int i;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Restoring encoders\n");
- for (i = 0; i < pNv->vbios->dcb->entries; i++)
- nv_encoder_restore(pScrn, &pNv->encoders[i]);
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Restoring crtcs\n");
- for (i = 0; i < xf86_config->num_crtc; i++)
- xf86_config->crtc[i]->funcs->restore(xf86_config->crtc[i]);
-
- nouveau_hw_save_vga_fonts(pScrn, 0);
-
- if (pNv->twoHeads) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Restoring CRTC_OWNER to %d.\n", pNv->vtOWNER);
- NVSetOwner(pNv, pNv->vtOWNER);
- }
-
- NVLockVgaCrtcs(pNv, true);
-}
-
static void
@@ -1506,5 +1096,2 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
- if (!pNv->kms_enable)
- NVSave(pScrn);
-
/*
@@ -1603,10 +1190,4 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
- if (!pNv->NoAccel) {
- if (!nouveau_exa_init(pScreen))
- return FALSE;
- } else if (pNv->VRAMPhysicalSize / 2 < NOUVEAU_ALIGN(pScrn->virtualX, 64) * NOUVEAU_ALIGN(pScrn->virtualY, 64) * (pScrn->bitsPerPixel >> 3)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "The virtual screen size's resolution is too big for the video RAM framebuffer at this colour depth.\n");
+ if (!pNv->NoAccel && !nouveau_exa_init(pScreen))
return FALSE;
- }
-
@@ -1634,13 +1215,6 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (pNv->HWCursor) {
- if (pNv->kms_enable)
- ret = drmmode_cursor_init(pScreen);
- else
- if (pNv->Architecture < NV_ARCH_50)
- ret = NVCursorInitRandr12(pScreen);
- else
- ret = NV50CursorInit(pScreen);
-
+ ret = drmmode_cursor_init(pScreen);
if (ret != TRUE) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Hardware cursor initialization failed\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
pNv->HWCursor = FALSE;
@@ -1667,4 +1241,3 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pScrn->pScreen = pScreen;
- if (pNv->kms_enable)
- drmmode_fbcon_copy(pScrn);
+ drmmode_fbcon_copy(pScrn);
@@ -1707,18 +1280,2 @@ NVSaveScreen(ScreenPtr pScreen, int mode)
{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- NVPtr pNv = NVPTR(pScrn);
- bool on = xf86IsUnblank(mode);
- int i;
-
- if (pScrn->vtSema && pNv->Architecture < NV_ARCH_50) {
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-
- for (i = 0; i < xf86_config->num_crtc; i++) {
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(xf86_config->crtc[i]);
-
- if (xf86_config->crtc[i]->enabled)
- NVBlankScreen(pNv, nv_crtc->head, !on);
- }
- }
-
return TRUE;
@@ -1726,23 +1283 @@ NVSaveScreen(ScreenPtr pScreen, int mode)
-static void
-NVSave(ScrnInfoPtr pScrn)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- NVPtr pNv = NVPTR(pScrn);
- int i;
-
- if (pNv->Architecture == NV_ARCH_50)
- return;
-
- NVLockVgaCrtcs(pNv, false);
-
- nouveau_hw_save_vga_fonts(pScrn, 1);
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Saving crtcs\n");
- for (i = 0; i < xf86_config->num_crtc; i++)
- xf86_config->crtc[i]->funcs->save(xf86_config->crtc[i]);
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Saving encoders\n");
- for (i = 0; i < pNv->vbios->dcb->entries; i++)
- nv_encoder_save(pScrn, &pNv->encoders[i]);
-}
diff --git a/src/nv_i2c.c b/src/nv_i2c.c
deleted file mode 100644
index e8b2e29..0000000
--- a/src/nv_i2c.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2006 Stephane Marchesin
- * Copyright 2007 Maarten Maathuis
- *
- * 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 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.
- */
-
-#include "nv_include.h"
-
-/*
- * DDC1 support only requires DDC_SDA_MASK,
- * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK
- */
-#define DDC_SDA_READ_MASK (1 << 3)
-#define DDC_SCL_READ_MASK (1 << 2)
-#define DDC_SDA_WRITE_MASK (1 << 4)
-#define DDC_SCL_WRITE_MASK (1 << 5)
-
-static void
-NVI2CGetBits(I2CBusPtr b, int *clock, int *data)
-{
- NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
- struct dcb_i2c_entry *dcb_i2c = b->DriverPrivate.ptr;
- unsigned char val;
-
- /* Get the result. */
- /* Doing this on head 0 seems fine. */
- if (dcb_i2c->port_type == 4) /* C51 */
- val = NVReadCRTC(pNv, 0, 0x600800 + dcb_i2c->read) >> 16;
- else
- val = NVReadVgaCrtc(pNv, 0, dcb_i2c->read);
-
- *clock = (val & DDC_SCL_READ_MASK) != 0;
- *data = (val & DDC_SDA_READ_MASK) != 0;
-}
-
-static void
-NVI2CPutBits(I2CBusPtr b, int clock, int data)
-{
- NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
- struct dcb_i2c_entry *dcb_i2c = b->DriverPrivate.ptr;
- uint32_t val;
-
- /* Doing this on head 0 seems fine. */
- if (dcb_i2c->port_type == 4) /* C51 */
- val = NVReadCRTC(pNv, 0, 0x600800 + dcb_i2c->write);
- else
- val = NVReadVgaCrtc(pNv, 0, dcb_i2c->write);
-
- val = (val & ~0xf) | 1;
-
- if (clock)
- val |= DDC_SCL_WRITE_MASK;
- else
- val &= ~DDC_SCL_WRITE_MASK;
-
- if (data)
- val |= DDC_SDA_WRITE_MASK;
- else
- val &= ~DDC_SDA_WRITE_MASK;
-
- /* Doing this on head 0 seems fine. */
- if (dcb_i2c->port_type == 4) /* C51 */
- NVWriteCRTC(pNv, 0, 0x600800 + dcb_i2c->write, val);
- else
- NVWriteVgaCrtc(pNv, 0, dcb_i2c->write, val);
-}
-
-static uint32_t NV50_GetI2CPort(ScrnInfoPtr pScrn, int index)
-{
- NVPtr pNv = NVPTR(pScrn);
-
- if (index <= 3)
- return 0xe138 + (index * 24);
-
- /* I have my doubts that this is 100% correct everywhere,
- * but this is the best guess based on the data we have.
- */
- if (pNv->NVArch >= 0x90) /* 0x90, 0xA0 */
- return 0xe1d4 + (index * 32);
- return 0xe1e0 + (index * 24);
-}
-
-static void NV50_I2CPutBits(I2CBusPtr b, int clock, int data)
-{
- NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
- struct dcb_i2c_entry *dcb_i2c = b->DriverPrivate.ptr;
-
- NVWrite(pNv, NV50_GetI2CPort(xf86Screens[b->scrnIndex], dcb_i2c->write), (4 | clock | data << 1));
-}
-
-static void NV50_I2CGetBits(I2CBusPtr b, int *clock, int *data)
-{
- NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
- struct dcb_i2c_entry *dcb_i2c = b->DriverPrivate.ptr;
- unsigned char val;
-
- val = NVRead(pNv, NV50_GetI2CPort(xf86Screens[b->scrnIndex], dcb_i2c->read));
- *clock = !!(val & 1);
- *data = !!(val & 2);
-}
-
-int
-NV_I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, struct dcb_i2c_entry *dcb_i2c, char *name)
-{
- I2CBusPtr pI2CBus;
-
- if (dcb_i2c->chan)
- goto initialized;
-
- if (!(pI2CBus = xf86CreateI2CBusRec()))
- return -ENOMEM;
-
- pI2CBus->BusName = name;
- pI2CBus->scrnIndex = pScrn->scrnIndex;
- if (dcb_i2c->port_type == 5) { /* NV50 */
- pI2CBus->I2CPutBits = NV50_I2CPutBits;
- pI2CBus->I2CGetBits = NV50_I2CGetBits;
- /* Could this be used for the rest as well? */
- pI2CBus->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */
- pI2CBus->StartTimeout = 550;
- pI2CBus->BitTimeout = 40;
- pI2CBus->ByteTimeout = 40;
- pI2CBus->AcknTimeout = 40;
- } else {
- pI2CBus->I2CPutBits = NVI2CPutBits;
- pI2CBus->I2CGetBits = NVI2CGetBits;
- pI2CBus->AcknTimeout = 5;
- }
- pI2CBus->DriverPrivate.ptr = dcb_i2c;
-
- if (!xf86I2CBusInit(pI2CBus))
- return -EINVAL;
-
- dcb_i2c->chan = pI2CBus;
-
-initialized:
- *bus_ptr = dcb_i2c->chan;
-
- return 0;
-}
-
diff --git a/src/nv_include.h b/src/nv_include.h
index 03e8c6a..f17cf8b 100644
--- a/src/nv_include.h
+++ b/src/nv_include.h
@@ -73,3 +73,2 @@
#include "nv_proto.h"
-#include "nouveau_hw.h"
#include "nv_dma.h"
@@ -77,4 +76,2 @@
#include "nouveau_class.h"
-#include "nvreg.h"
-#include "nv50reg.h"
#include "sarea.h"
diff --git a/src/nv_output.c b/src/nv_output.c
deleted file mode 100644
index 2573702..0000000
--- a/src/nv_output.c
+++ /dev/null
@@ -1,1293 +0,0 @@
-/*
- * Copyright 2003 NVIDIA, Corporation
- * Copyright 2006 Dave Airlie
- * Copyright 2007 Maarten Maathuis
- * Copyright 2007-2009 Stuart Bennett
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <X11/Xatom.h>
-#include <X11/Xos.h> /* X_GETTIMEOFDAY */
-#include "nv_include.h"
-
-#define MULTIPLE_ENCODERS(e) (e & (e - 1))
-#define FOR_EACH_ENCODER_IN_CONNECTOR(i, c, e) for (i = 0; i < pNv->vbios->dcb->entries; i++) \
- if (c->possible_encoders & (1 << i) && \
- (e = &pNv->encoders[i]))
-
-static int nv_output_ramdac_offset(struct nouveau_encoder *nv_encoder)
-{
- int offset = 0;
-
- if (nv_encoder->dcb->or & (8 | OUTPUT_C))
- offset += 0x68;
- if (nv_encoder->dcb->or & (8 | OUTPUT_B))
- offset += 0x2000;
-
- return offset;
-}
-
-static int nv_get_digital_bound_head(NVPtr pNv, int or)
-{
- /* special case of nv_read_tmds to find crtc associated with an output.
- * this does not give a correct answer for off-chip dvi, but there's no
- * use for such an answer anyway
- */
- int ramdac = (or & OUTPUT_C) >> 2;
-
- NVWriteRAMDAC(pNv, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL,
- NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | 0x4);
- return (((NVReadRAMDAC(pNv, ramdac, NV_PRAMDAC_FP_TMDS_DATA) & 0x8) >> 3) ^ ramdac);
-}
-
-#define WAIT_FOR(cond, timeout_us) __extension__ ({ \
- struct timeval begin, cur; \
- long d_secs, d_usecs, diff = 0; \
- \
- X_GETTIMEOFDAY(&begin); \
- while (!(cond) && diff < timeout_us) { \
- X_GETTIMEOFDAY(&cur); \
- d_secs = cur.tv_sec - begin.tv_sec; \
- d_usecs = cur.tv_usec - begin.tv_usec; \
- diff = d_secs * 1000000 + d_usecs; \
- }; \
- diff >= timeout_us ? -EAGAIN : 0; \
-})
-
-/*
- * arbitrary limit to number of sense oscillations tolerated in one sample
- * period (observed to be at least 13 in "nvidia")
- */
-#define MAX_HBLANK_OSC 20
-
-/*
- * arbitrary limit to number of conflicting sample pairs to tolerate at a
- * voltage step (observed to be at least 5 in "nvidia")
- */
-#define MAX_SAMPLE_PAIRS 10
-
-static int sample_load_twice(NVPtr pNv, bool sense[2])
-{
- int i;
-
- for (i = 0; i < 2; i++) {
- bool sense_a, sense_b, sense_b_prime;
- int j = 0;
-
- /*
- * wait for bit 0 clear -- out of hblank -- (say reg value 0x4),
- * then wait for transition 0x4->0x5->0x4: enter hblank, leave
- * hblank again
- * use a 10ms timeout (guards against crtc being inactive, in
- * which case blank state would never change)
- */
- if (WAIT_FOR(!(VGA_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR) & 1), 10000))
- return -EWOULDBLOCK;
- if (WAIT_FOR(VGA_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR) & 1, 10000))
- return -EWOULDBLOCK;
- if (WAIT_FOR(!(VGA_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR) & 1), 10000))
- return -EWOULDBLOCK;
-
- WAIT_FOR(0, 100); /* faster than usleep(100) */
- /* when level triggers, sense is _LO_ */
- sense_a = VGA_RD08(pNv->REGS, NV_PRMCIO_INP0) & 0x10;
-
- /* take another reading until it agrees with sense_a... */
- do {
- WAIT_FOR(0, 100);
- sense_b = VGA_RD08(pNv->REGS, NV_PRMCIO_INP0) & 0x10;
- if (sense_a != sense_b) {
- sense_b_prime = VGA_RD08(pNv->REGS, NV_PRMCIO_INP0) & 0x10;
- if (sense_b == sense_b_prime) {
- /* ... unless two consecutive subsequent
- * samples agree; sense_a is replaced */
- sense_a = sense_b;
- /* force mis-match so we loop */
- sense_b = !sense_a;
- }
- }
- } while ((sense_a != sense_b) && ++j < MAX_HBLANK_OSC);
-
- if (j == MAX_HBLANK_OSC)
- /* with so much oscillation, default to sense:LO */
- sense[i] = false;
- else
- sense[i] = sense_a;
- }
-
- return 0;
-}
-
-static bool nv_legacy_load_detect(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- uint8_t saved_seq1, saved_pi, saved_rpc1;
- uint8_t saved_palette0[3], saved_palette_mask;
- uint32_t saved_rtest_ctrl, saved_rgen_ctrl;
- int i;
- uint8_t blue;
- bool sense = true;
-
- /*
- * for this detection to work, there needs to be a mode set up on the
- * CRTC. this is presumed to be the case
- */
-
- if (pNv->twoHeads)
- /* only implemented for head A for now */
- NVSetOwner(pNv, 0);
-
- saved_seq1 = NVReadVgaSeq(pNv, 0, NV_VIO_SR_CLOCK_INDEX);
- NVWriteVgaSeq(pNv, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20);
-
- saved_rtest_ctrl = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL);
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL,
- saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF);
-
- usleep(10000);
-
- saved_pi = NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_PIXEL_INDEX);
- NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_PIXEL_INDEX,
- saved_pi & ~(0x80 | MASK(NV_CIO_CRE_PIXEL_FORMAT)));
- saved_rpc1 = NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_RPC1_INDEX);
- NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1 & ~0xc0);
-
- VGA_WR08(pNv->REGS, NV_PRMDIO_READ_MODE_ADDRESS, 0x0);
- for (i = 0; i < 3; i++)
- saved_palette0[i] = NV_RD08(pNv->REGS, NV_PRMDIO_PALETTE_DATA);
- saved_palette_mask = NV_RD08(pNv->REGS, NV_PRMDIO_PIXEL_MASK);
- VGA_WR08(pNv->REGS, NV_PRMDIO_PIXEL_MASK, 0);
-
- saved_rgen_ctrl = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_GENERAL_CONTROL);
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_GENERAL_CONTROL,
- (saved_rgen_ctrl & ~(NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS |
- NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM)) |
- NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON);
-
- blue = 8; /* start of test range */
-
- do {
- bool sense_pair[2];
-
- VGA_WR08(pNv->REGS, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
- NV_WR08(pNv->REGS, NV_PRMDIO_PALETTE_DATA, 0);
- NV_WR08(pNv->REGS, NV_PRMDIO_PALETTE_DATA, 0);
- /* testing blue won't find monochrome monitors. I don't care */
- NV_WR08(pNv->REGS, NV_PRMDIO_PALETTE_DATA, blue);
-
- i = 0;
- /* take sample pairs until both samples in the pair agree */
- do {
- if (sample_load_twice(pNv, sense_pair))
- goto out;
- } while ((sense_pair[0] != sense_pair[1]) &&
- ++i < MAX_SAMPLE_PAIRS);
-
- if (i == MAX_SAMPLE_PAIRS)
- /* too much oscillation defaults to LO */
- sense = false;
- else
- sense = sense_pair[0];
-
- /*
- * if sense goes LO before blue ramps to 0x18, monitor is not connected.
- * ergo, if blue gets to 0x18, monitor must be connected
- */
- } while (++blue < 0x18 && sense);
-
-out:
- VGA_WR08(pNv->REGS, NV_PRMDIO_PIXEL_MASK, saved_palette_mask);
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_GENERAL_CONTROL, saved_rgen_ctrl);
- VGA_WR08(pNv->REGS, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
- for (i = 0; i < 3; i++)
- NV_WR08(pNv->REGS, NV_PRMDIO_PALETTE_DATA, saved_palette0[i]);
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL, saved_rtest_ctrl);
- NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi);
- NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1);
- NVWriteVgaSeq(pNv, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1);
-
- if (blue == 0x18) {
- NV_TRACE(pScrn, "Load detected on head A\n");
- return true;
- }
-
- return false;
-}
-
-static bool
-nv_nv17_load_detect(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder)
-{
- NVPtr pNv = NVPTR(pScrn);
- uint32_t testval, regoffset = nv_output_ramdac_offset(nv_encoder);
- uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, saved_rtest_ctrl, temp;
- int head, present = 0;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-
-#define RGB_TEST_DATA(r,g,b) (r << 0 | g << 10 | b << 20)
- testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */
- if (pNv->vbios->dactestval)
- testval = pNv->vbios->dactestval;
-
- saved_rtest_ctrl = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL + regoffset,
- saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF);
-
- saved_powerctrl_2 = nvReadMC(pNv, NV_PBUS_POWERCTRL_2);
-
- nvWriteMC(pNv, NV_PBUS_POWERCTRL_2, saved_powerctrl_2 & 0xd7ffffff);
- if (regoffset == 0x68) {
- saved_powerctrl_4 = nvReadMC(pNv, NV_PBUS_POWERCTRL_4);
- nvWriteMC(pNv, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf);
- }
-
- usleep(4000);
-
- saved_routput = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset);
- head = (saved_routput & 0x100) >> 8;
- /* if there's a spare crtc, using it will minimise flicker for the case
- * where the in-use crtc is in use by an off-chip tmds encoder */
- if (xf86_config->crtc[head]->enabled && !xf86_config->crtc[head ^ 1]->enabled)
- head ^= 1;
- /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset,
- (saved_routput & 0xfffffece) | head << 8);
- usleep(1000);
-
- temp = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset);
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset, temp | 1);
-
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_TESTPOINT_DATA,
- NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK | testval);
- temp = NVReadRAMDAC(pNv, head, NV_PRAMDAC_TEST_CONTROL);
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_TEST_CONTROL,
- temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED);
- usleep(1000);
-
- present = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL + regoffset) &
- NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI;
-
- temp = NVReadRAMDAC(pNv, head, NV_PRAMDAC_TEST_CONTROL);
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_TEST_CONTROL,
- temp & ~NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED);
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_TESTPOINT_DATA, 0);
-
- /* bios does something more complex for restoring, but I think this is good enough */
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset, saved_routput);
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, saved_rtest_ctrl);
- if (regoffset == 0x68)
- nvWriteMC(pNv, NV_PBUS_POWERCTRL_4, saved_powerctrl_4);
- nvWriteMC(pNv, NV_PBUS_POWERCTRL_2, saved_powerctrl_2);
-
- if (present) {
- NV_TRACE(pScrn, "Load detected on output %c\n",
- '@' + ffs(nv_encoder->dcb->or));
- return true;
- }
-
- return false;
-}
-
-static void
-update_output_fields(xf86OutputPtr output, struct nouveau_encoder *det_encoder)
-{
- struct nouveau_connector *nv_connector = to_nouveau_connector(output);
- NVPtr pNv = NVPTR(output->scrn);
-
- if (nv_connector->detected_encoder == det_encoder)
- return;
-
- nv_connector->detected_encoder = det_encoder;
- output->possible_crtcs = det_encoder->dcb->heads;
- if (IS_DFP(det_encoder->dcb->type)) {
- output->doubleScanAllowed = false;
- output->interlaceAllowed = false;
- } else {
- output->doubleScanAllowed = true;
- if (pNv->Architecture == NV_ARCH_20 ||
- (pNv->Architecture == NV_ARCH_10 &&
- (pNv->Chipset & 0x0ff0) != CHIPSET_NV10 &&
- (pNv->Chipset & 0x0ff0) != CHIPSET_NV15))
- /* HW is broken */
- output->interlaceAllowed = false;
- else
- output->interlaceAllowed = true;
- }
-}
-
-static bool edid_sink_connected(xf86OutputPtr output)
-{
- struct nouveau_connector *nv_connector = to_nouveau_connector(output);
- NVPtr pNv = NVPTR(output->scrn);
- bool waslocked = NVLockVgaCrtcs(pNv, false);
- bool wastied = nv_heads_tied(pNv);
-
- if (wastied)
- NVSetOwner(pNv, 0); /* necessary? */
-
- nv_connector->edid = xf86OutputGetEDID(output, nv_connector->pDDCBus);
-
- if (wastied)
- NVSetOwner(pNv, 0x4);
- if (waslocked)
- NVLockVgaCrtcs(pNv, true);
-
- return !!nv_connector->edid;
-}
-
-static xf86OutputStatus
-nv_output_detect(xf86OutputPtr output)
-{
- struct nouveau_connector *nv_connector = to_nouveau_connector(output);
- ScrnInfoPtr pScrn = output->scrn;
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_encoder *det_encoder;
- xf86OutputStatus ret = XF86OutputStatusDisconnected;
-
- struct nouveau_encoder *find_encoder_by_type(enum nouveau_encoder_type type)
- {
- int i;
- for (i = 0; i < pNv->vbios->dcb->entries; i++)
- if (nv_connector->possible_encoders & (1 << i) &&
- (type == OUTPUT_ANY || pNv->encoders[i].dcb->type == type))
- return &pNv->encoders[i];
- return NULL;
- }
-
- /* if an LVDS output was ever connected it remains so */
- if (nv_connector->detected_encoder &&
- nv_connector->detected_encoder->dcb->type == OUTPUT_LVDS)
- return XF86OutputStatusConnected;
-
- if (nv_connector->pDDCBus && edid_sink_connected(output)) {
- if (MULTIPLE_ENCODERS(nv_connector->possible_encoders)) {
- if (nv_connector->edid->features.input_type)
- det_encoder = find_encoder_by_type(OUTPUT_TMDS);
- else
- det_encoder = find_encoder_by_type(OUTPUT_ANALOG);
- } else
- det_encoder = find_encoder_by_type(OUTPUT_ANY);
- ret = XF86OutputStatusConnected;
- } else if ((det_encoder = find_encoder_by_type(OUTPUT_ANALOG))) {
- /* bind encoder if enabled in xorg.conf */
- if (output->conf_monitor &&
- xf86CheckBoolOption(output->conf_monitor->mon_option_lst,
- "Enable", FALSE))
- ret = XF86OutputStatusConnected;
- else if (pNv->gf4_disp_arch) {
- if (nv_nv17_load_detect(pScrn, det_encoder))
- ret = XF86OutputStatusConnected;
- } else
- if (nv_legacy_load_detect(pScrn))
- ret = XF86OutputStatusConnected;
- } else if ((det_encoder = find_encoder_by_type(OUTPUT_LVDS))) {
- if (det_encoder->dcb->lvdsconf.use_straps_for_mode) {
- if (nouveau_bios_fp_mode(pScrn, NULL))
- ret = XF86OutputStatusConnected;
- } else if (!pNv->vbios->fp_no_ddc &&
- nouveau_bios_embedded_edid(pScrn)) {
- nv_connector->edid = xf86InterpretEDID(pScrn->scrnIndex,
- nouveau_bios_embedded_edid(pScrn));
- ret = XF86OutputStatusConnected;
- }
- }
-
- if (ret != XF86OutputStatusDisconnected)
- update_output_fields(output, det_encoder);
-
- return ret;
-}
-
-static DisplayModePtr
-get_native_mode_from_edid(xf86OutputPtr output, DisplayModePtr edid_modes)
-{
- struct nouveau_connector *nv_connector = to_nouveau_connector(output);
- struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
- int max_h_active = 0, max_v_active = 0;
- int i;
- DisplayModePtr mode;
-
- for (i = 0; i < DET_TIMINGS; i++) {
- struct detailed_timings *dt =
- &nv_connector->edid->det_mon[i].section.d_timings;
-
- if (nv_connector->edid->det_mon[i].type != DT)
- continue;
- /* Selecting only based on width ok? */
- if (dt->h_active > max_h_active) {
- max_h_active = dt->h_active;
- max_v_active = dt->v_active;
- }
- }
- if (!max_h_active || !max_v_active) /* clearly a joke EDID */
- for (i = 0; i < STD_TIMINGS; i++) {
- struct std_timings *st =
- &nv_connector->edid->timings2[i];
-
- if (st->hsize > max_h_active) {
- max_h_active = st->hsize;
- max_v_active = st->vsize;
- }
- }
- if (!max_h_active || !max_v_active) {
- NV_ERROR(output->scrn, "EDID too broken to find native mode\n");
- return NULL;
- }
-
- if (nv_encoder->native_mode) {
- xfree(nv_encoder->native_mode);
- nv_encoder->native_mode = NULL;
- }
-
- for (mode = edid_modes; mode != NULL; mode = mode->next) {
- if (mode->HDisplay == max_h_active &&
- mode->VDisplay == max_v_active) {
- /* Take the preferred mode when it exists. */
- if (mode->type & M_T_PREFERRED) {
- nv_encoder->native_mode = xf86DuplicateMode(mode);
- break;
- }
- /* Find the highest refresh mode otherwise. */
- if (!nv_encoder->native_mode ||
- (mode->VRefresh > nv_encoder->native_mode->VRefresh)) {
- if (nv_encoder->native_mode)
- xfree(nv_encoder->native_mode);
- mode->type |= M_T_PREFERRED;
- nv_encoder->native_mode = xf86DuplicateMode(mode);
- }
- }
- }
-
- return nv_encoder->native_mode;
-}
-
-static DisplayModePtr
-nv_output_get_edid_modes(xf86OutputPtr output)
-{
- struct nouveau_connector *nv_connector = to_nouveau_connector(output);
- struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
- DisplayModePtr edid_modes;
-
- if (IS_DFP(nv_encoder->dcb->type) &&
- nv_encoder->scaling_mode != SCALE_PANEL)
- /* the digital scaler is not limited to modes given in the EDID,
- * so enable the GTF bit in order that the xserver thinks
- * continuous timing is available and adds the standard modes
- */
- nv_connector->edid->features.msc |= 1;
-
- xf86OutputSetEDID(output, nv_connector->edid);
- if (!(edid_modes = xf86OutputGetEDIDModes(output)))
- return edid_modes;
-
- if (IS_DFP(nv_encoder->dcb->type))
- if (!get_native_mode_from_edid(output, edid_modes))
- return NULL;
- if (nv_encoder->dcb->type == OUTPUT_TMDS)
- nv_encoder->dual_link = nv_encoder->native_mode->Clock >= 165000;
-
- return edid_modes;
-}
-
-static DisplayModePtr
-nv_lvds_output_get_modes(xf86OutputPtr output)
-{
- struct nouveau_connector *nv_connector = to_nouveau_connector(output);
- struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
- ScrnInfoPtr pScrn = output->scrn;
- DisplayModeRec mode, *ret_mode = NULL;
- int clock = 0; /* needs to be zero for straps case */
- bool dl, if_is_24bit = false;
-
- /* panels only have one mode, and it doesn't change */
- if (nv_encoder->native_mode)
- return xf86DuplicateMode(nv_encoder->native_mode);
-
- if (nv_encoder->dcb->lvdsconf.use_straps_for_mode) {
- if (!nouveau_bios_fp_mode(pScrn, &mode))
- return NULL;
-
- mode.status = MODE_OK;
- mode.type = M_T_DRIVER | M_T_PREFERRED;
- xf86SetModeDefaultName(&mode);
-
- nv_encoder->native_mode = xf86DuplicateMode(&mode);
- ret_mode = xf86DuplicateMode(&mode);
- } else
- if ((ret_mode = nv_output_get_edid_modes(output)))
- clock = nv_encoder->native_mode->Clock;
-
- if (nouveau_bios_parse_lvds_table(pScrn, clock, &dl, &if_is_24bit)) {
- if (nv_encoder->native_mode) {
- xfree(nv_encoder->native_mode);
- nv_encoder->native_mode = NULL;
- }
- return NULL;
- }
-
- /* because of the pre-existing native mode exit above, this will only
- * get run at startup (and before create_resources is called in
- * mode_fixup), so subsequent user dither settings are not overridden
- */
- nv_encoder->dithering |= !if_is_24bit;
- nv_encoder->dual_link = dl;
-
- return ret_mode;
-}
-
-static int nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
-{
- struct nouveau_encoder *nv_encoder = to_nouveau_connector(output)->detected_encoder;
-
- /* mode_valid can be called by someone doing addmode on an output
- * which is disconnected and so without an encoder; avoid crashing
- */
- if (!nv_encoder)
- return MODE_ERROR;
-
- if (!output->doubleScanAllowed && mode->Flags & V_DBLSCAN)
- return MODE_NO_DBLESCAN;
- if (!output->interlaceAllowed && mode->Flags & V_INTERLACE)
- return MODE_NO_INTERLACE;
-
- if (nv_encoder->dcb->type == OUTPUT_ANALOG) {
- if (nv_encoder->dcb->crtconf.maxfreq) {
- if (mode->Clock > nv_encoder->dcb->crtconf.maxfreq)
- return MODE_CLOCK_HIGH;
- } else
- if (mode->Clock > 350000)
- return MODE_CLOCK_HIGH;
- }
- /* must have a native mode for fp (except in panel scaling case) */
- if (IS_DFP(nv_encoder->dcb->type) && !nv_encoder->native_mode &&
- nv_encoder->scaling_mode != SCALE_PANEL)
- return MODE_NOCLOCK;
- if (IS_DFP(nv_encoder->dcb->type) && nv_encoder->native_mode)
- /* No modes > panel's native res */
- if (mode->HDisplay > nv_encoder->native_mode->HDisplay ||
- mode->VDisplay > nv_encoder->native_mode->VDisplay)
- return MODE_PANEL;
- if (nv_encoder->dcb->type == OUTPUT_TMDS) {
- if (nv_encoder->dcb->duallink_possible) {
- if (mode->Clock > 330000) /* 2x165 MHz */
- return MODE_CLOCK_HIGH;
- } else
- if (mode->Clock > 165000) /* 165 MHz */
- return MODE_CLOCK_HIGH;
- }
-
- return MODE_OK;
-}
-
-static void
-nv_output_destroy(xf86OutputPtr output)
-{
- struct nouveau_connector *nv_connector = to_nouveau_connector(output);
- struct nouveau_encoder *nv_encoder;
- NVPtr pNv = NVPTR(output->scrn);
- int i;
-
- if (!nv_connector)
- return;
-
- if (nv_connector->edid)
- xfree(nv_connector->edid);
- FOR_EACH_ENCODER_IN_CONNECTOR(i, nv_connector, nv_encoder)
- if (nv_encoder->native_mode)
- xfree(nv_encoder->native_mode);
- xfree(nv_connector);
-}
-
-static char * get_current_scaling_name(enum scaling_modes mode)
-{
- static const struct {
- char *name;
- enum scaling_modes mode;
- } scaling_mode[] = {
- { "panel", SCALE_PANEL },
- { "fullscreen", SCALE_FULLSCREEN },
- { "aspect", SCALE_ASPECT },
- { "noscale", SCALE_NOSCALE },
- { NULL, SCALE_INVALID }
- };
- int i;
-
- for (i = 0; scaling_mode[i].name; i++)
- if (scaling_mode[i].mode == mode)
- return scaling_mode[i].name;
-
- return NULL;
-}
-
-static int nv_output_create_prop(xf86OutputPtr output, char *name, Atom *atom,
- INT32 *rangevals, INT32 cur_val, char *cur_str, Bool do_mode_set)
-{
- int ret = -ENOMEM;
- Bool range = rangevals ? TRUE : FALSE;
-
- if ((*atom = MakeAtom(name, strlen(name), TRUE)) == BAD_RESOURCE)
- goto fail;
- if (RRQueryOutputProperty(output->randr_output, *atom))
- return 0; /* already exists */
- if ((ret = RRConfigureOutputProperty(output->randr_output, *atom,
- do_mode_set, range, FALSE, range ? 2 : 0, rangevals)))
- goto fail;
- if (range)
- ret = RRChangeOutputProperty(output->randr_output, *atom, XA_INTEGER, 32,
- PropModeReplace, 1, &cur_val, FALSE, do_mode_set);
- else
- ret = RRChangeOutputProperty(output->randr_output, *atom, XA_STRING, 8,
- PropModeReplace, strlen(cur_str), cur_str,
- FALSE, do_mode_set);
-
-fail:
- if (ret)
- xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
- "Creation of %s property failed: %d\n", name, ret);
-
- return ret;
-}
-
-static Atom dithering_atom, scaling_mode_atom;
-static Atom dv_atom, sharpness_atom;
-
-static void nv_output_create_resources(xf86OutputPtr output)
-{
- struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
- NVPtr pNv = NVPTR(output->scrn);
-
- /* may be called before encoder is picked, resources will be created
- * by update_output_fields()
- */
- if (!nv_encoder)
- return;
-
- if (IS_DFP(nv_encoder->dcb->type)) {
- nv_output_create_prop(output, "DITHERING", &dithering_atom,
- (INT32 []){ 0, 1 }, nv_encoder->dithering, NULL, TRUE);
- nv_output_create_prop(output, "SCALING_MODE", &scaling_mode_atom,
- NULL, 0, get_current_scaling_name(nv_encoder->scaling_mode), TRUE);
- }
- if (pNv->NVArch >= 0x11 && output->crtc) {
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(output->crtc);
- INT32 dv_range[2] = { 0, !pNv->gf4_disp_arch ? 3 : 63 };
- /* unsure of correct condition here: blur works on my nv34, but not on my nv31 */
- INT32 is_range[2] = { pNv->NVArch > 0x31 ? -32 : 0, 31 };
-
- nv_output_create_prop(output, "DIGITAL_VIBRANCE", &dv_atom,
- dv_range, nv_crtc->saturation, NULL, FALSE);
- if (pNv->NVArch >= 0x30)
- nv_output_create_prop(output, "IMAGE_SHARPENING", &sharpness_atom,
- is_range, nv_crtc->sharpness, NULL, FALSE);
- }
-}
-
-static Bool
-nv_output_set_property(xf86OutputPtr output, Atom property,
- RRPropertyValuePtr value)
-{
- struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
- NVPtr pNv = NVPTR(output->scrn);
-
- if (property == scaling_mode_atom) {
- char *name = (char *) value->data;
- int32_t val;
-
- if (value->type != XA_STRING || value->format != 8)
- return FALSE;
-
- /* Match a string to a scaling mode */
- val = nv_scaling_mode_lookup(name, value->size);
- if (val == SCALE_INVALID)
- return FALSE;
-
- /* LVDS must always use gpu scaling. */
- if (val == SCALE_PANEL && nv_encoder->dcb->type == OUTPUT_LVDS)
- return FALSE;
-
- nv_encoder->scaling_mode = val;
- } else if (property == dithering_atom) {
- int32_t val = *(int32_t *) value->data;
-
- if (value->type != XA_INTEGER || value->format != 32)
- return FALSE;
-
- if (val < 0 || val > 1)
- return FALSE;
-
- nv_encoder->dithering = val;
- } else if (property == dv_atom || property == sharpness_atom) {
- int32_t val = *(int32_t *) value->data;
-
- if (value->type != XA_INTEGER || value->format != 32)
- return FALSE;
-
- if (!output->crtc)
- return FALSE;
-
- if (property == dv_atom) {
- if (val < 0 || val > (!pNv->gf4_disp_arch ? 3 : 63))
- return FALSE;
-
- nv_crtc_set_digital_vibrance(output->crtc, val);
- } else {
- if (val < (pNv->NVArch > 0x31 ? -32 : 0) || val > 31)
- return FALSE;
-
- nv_crtc_set_image_sharpening(output->crtc, val);
- }
- }
-
- return TRUE;
-}
-
-static Bool
-nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
- DisplayModePtr adjusted_mode)
-{
- struct nouveau_connector *nv_connector = to_nouveau_connector(output);
-
- if (nv_connector->nv_encoder != nv_connector->detected_encoder) {
- nv_connector->nv_encoder = nv_connector->detected_encoder;
- if (output->randr_output) {
- RRDeleteOutputProperty(output->randr_output, dithering_atom);
- RRDeleteOutputProperty(output->randr_output, scaling_mode_atom);
- output->funcs->create_resources(output);
- }
- }
-
- struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
-
- /* For internal panels and gpu scaling on DVI we need the native mode */
- if (IS_DFP(nv_encoder->dcb->type) &&
- nv_encoder->scaling_mode != SCALE_PANEL) {
- adjusted_mode->HDisplay = nv_encoder->native_mode->HDisplay;
- adjusted_mode->HSkew = nv_encoder->native_mode->HSkew;
- adjusted_mode->HSyncStart = nv_encoder->native_mode->HSyncStart;
- adjusted_mode->HSyncEnd = nv_encoder->native_mode->HSyncEnd;
- adjusted_mode->HTotal = nv_encoder->native_mode->HTotal;
- adjusted_mode->VDisplay = nv_encoder->native_mode->VDisplay;
- adjusted_mode->VScan = nv_encoder->native_mode->VScan;
- adjusted_mode->VSyncStart = nv_encoder->native_mode->VSyncStart;
- adjusted_mode->VSyncEnd = nv_encoder->native_mode->VSyncEnd;
- adjusted_mode->VTotal = nv_encoder->native_mode->VTotal;
- adjusted_mode->Clock = nv_encoder->native_mode->Clock;
- adjusted_mode->Flags = nv_encoder->native_mode->Flags;
-
- xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
- }
-
- return TRUE;
-}
-
-static void nv_digital_output_prepare_sel_clk(NVPtr pNv, struct nouveau_encoder *nv_encoder, int head)
-{
- struct nouveau_mode_state *state = &pNv->set_state;
- uint32_t bits1618 = nv_encoder->dcb->or & OUTPUT_A ? 0x10000 : 0x40000;
-
- if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP)
- return;
-
- /* SEL_CLK is only used on the primary ramdac
- * It toggles spread spectrum PLL output and sets the bindings of PLLs
- * to heads on digital outputs
- */
- if (head)
- state->sel_clk |= bits1618;
- else
- state->sel_clk &= ~bits1618;
-
- /* nv30:
- * bit 0 NVClk spread spectrum on/off
- * bit 2 MemClk spread spectrum on/off
- * bit 4 PixClk1 spread spectrum on/off toggle
- * bit 6 PixClk2 spread spectrum on/off toggle
- *
- * nv40 (observations from bios behaviour and mmio traces):
- * bits 4&6 as for nv30
- * bits 5&7 head dependent as for bits 4&6, but do not appear with 4&6;
- * maybe a different spread mode
- * bits 8&10 seen on dual-link dvi outputs, purpose unknown (set by POST scripts)
- * The logic behind turning spread spectrum on/off in the first place,
- * and which bit-pair to use, is unclear on nv40 (for earlier cards, the fp table
- * entry has the necessary info)
- */
- if (nv_encoder->dcb->type == OUTPUT_LVDS && pNv->saved_regs.sel_clk & 0xf0) {
- int shift = (pNv->saved_regs.sel_clk & 0x50) ? 0 : 1;
-
- state->sel_clk &= ~0xf0;
- state->sel_clk |= (head ? 0x40 : 0x10) << shift;
- }
-}
-
-#define FP_TG_CONTROL_ON (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | \
- NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | \
- NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS)
-#define FP_TG_CONTROL_OFF (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_DISABLE | \
- NV_PRAMDAC_FP_TG_CONTROL_HSYNC_DISABLE | \
- NV_PRAMDAC_FP_TG_CONTROL_VSYNC_DISABLE)
-
-static bool is_fpc_off(uint32_t fpc)
-{
- return ((fpc & (FP_TG_CONTROL_ON | FP_TG_CONTROL_OFF)) ==
- FP_TG_CONTROL_OFF);
-}
-
-static void
-nv_output_prepare(xf86OutputPtr output)
-{
- struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
- NVPtr pNv = NVPTR(output->scrn);
- int head = to_nouveau_crtc(output->crtc)->head;
- struct nouveau_crtc_state *crtcstate = pNv->set_state.head;
- uint8_t *cr_lcd = &crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX];
- uint8_t *cr_lcd_oth = &crtcstate[head ^ 1].CRTC[NV_CIO_CRE_LCD__INDEX];
-
- output->funcs->dpms(output, DPMSModeOff);
-
- if (nv_encoder->dcb->type == OUTPUT_ANALOG) {
- if (NVReadRAMDAC(pNv, head, NV_PRAMDAC_FP_TG_CONTROL) &
- FP_TG_CONTROL_ON) {
- /* digital remnants must be cleaned before new crtc
- * values programmed. delay is time for the vga stuff
- * to realise it's in control again
- */
- NVWriteRAMDAC(pNv, head, NV_PRAMDAC_FP_TG_CONTROL,
- FP_TG_CONTROL_OFF);
- usleep(50000);
- }
- /* don't inadvertently turn it on when state written later */
- crtcstate[head].fp_control = FP_TG_CONTROL_OFF;
- }
-
- /* calculate some output specific CRTC regs now, so that they can be
- * written in nv_crtc_set_mode
- */
-
- if (IS_DFP(nv_encoder->dcb->type))
- nv_digital_output_prepare_sel_clk(pNv, nv_encoder, head);
-
- /* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f)
- * at LCD__INDEX which we don't alter
- */
- if (!(*cr_lcd & 0x44)) {
- *cr_lcd = IS_DFP(nv_encoder->dcb->type) ? 0x3 : 0x0;
- if (IS_DFP(nv_encoder->dcb->type) && pNv->twoHeads) {
- if (nv_encoder->dcb->location == DCB_LOC_ON_CHIP)
- *cr_lcd |= head ? 0x0 : 0x8;
- else {
- *cr_lcd |= (nv_encoder->dcb->or << 4) & 0x30;
- if (nv_encoder->dcb->type == OUTPUT_LVDS)
- *cr_lcd |= 0x30;
- if ((*cr_lcd & 0x30) == (*cr_lcd_oth & 0x30)) {
- /* avoid being connected to both crtcs */
- *cr_lcd_oth &= ~0x30;
- NVWriteVgaCrtc(pNv, head ^ 1,
- NV_CIO_CRE_LCD__INDEX,
- *cr_lcd_oth);
- }
- }
- }
- }
-}
-
-static void
-nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
-{
- struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
- ScrnInfoPtr pScrn = output->scrn;
- NVPtr pNv = NVPTR(pScrn);
- struct dcb_entry *dcbe = nv_encoder->dcb;
- int head = to_nouveau_crtc(output->crtc)->head;
-
- NV_TRACE(pScrn, "%s called for encoder %d\n", __func__, dcbe->index);
-
- if (pNv->gf4_disp_arch && dcbe->type == OUTPUT_ANALOG) {
- uint32_t dac_offset = nv_output_ramdac_offset(nv_encoder);
- uint32_t otherdac;
- int i;
-
- /* bit 16-19 are bits that are set on some G70 cards,
- * but don't seem to have much effect */
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + dac_offset,
- head << 8 | NV_PRAMDAC_DACCLK_SEL_DACCLK);
- /* force any other vga encoders to bind to the other crtc */
- for (i = 0; i < pNv->vbios->dcb->entries; i++)
- if (i != dcbe->index && pNv->encoders[i].dcb &&
- pNv->encoders[i].dcb->type == OUTPUT_ANALOG) {
- dac_offset = nv_output_ramdac_offset(&pNv->encoders[i]);
- otherdac = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + dac_offset);
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + dac_offset,
- (otherdac & ~0x100) | (head ^ 1) << 8);
- }
- }
- if (dcbe->type == OUTPUT_TMDS)
- run_tmds_table(pScrn, dcbe, head, adjusted_mode->Clock);
- else if (dcbe->type == OUTPUT_LVDS)
- call_lvds_script(pScrn, dcbe, head, LVDS_RESET, adjusted_mode->Clock);
- if (IS_DFP(dcbe->type))
- /* update fp_control state for any changes made by scripts,
- * so correct value is written at DPMS on */
- pNv->set_state.head[head].fp_control =
- NVReadRAMDAC(pNv, head, NV_PRAMDAC_FP_TG_CONTROL);
-
- /* This could use refinement for flatpanels, but it should work this way */
- if (pNv->NVArch < 0x44)
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL + nv_output_ramdac_offset(nv_encoder), 0xf0000000);
- else
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL + nv_output_ramdac_offset(nv_encoder), 0x00100000);
-}
-
-static void
-nv_output_commit(xf86OutputPtr output)
-{
- struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
- ScrnInfoPtr pScrn = output->scrn;
- struct nouveau_crtc *nv_crtc = to_nouveau_crtc(output->crtc);
-
- output->funcs->dpms(output, DPMSModeOn);
-
- NV_TRACE(pScrn, "Output %s is running on CRTC %d using output %c\n",
- output->name, nv_crtc->head, '@' + ffs(nv_encoder->dcb->or));
-}
-
-static void dpms_update_fp_control(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode)
-{
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_crtc *nv_crtc;
- uint32_t *fpc;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int i;
-
- if (mode == DPMSModeOn) {
- nv_crtc = to_nouveau_crtc(crtc);
- fpc = &nv_crtc->state->fp_control;
-
- if (is_fpc_off(*fpc))
- /* using saved value is ok, as (is_digital && dpms_on &&
- * fp_control==OFF) is (at present) *only* true when
- * fpc's most recent change was by below "off" code
- */
- *fpc = nv_crtc->dpms_saved_fp_control;
-
- nv_crtc->fp_users |= 1 << nv_encoder->dcb->index;
- NVWriteRAMDAC(pNv, nv_crtc->head, NV_PRAMDAC_FP_TG_CONTROL, *fpc);
- } else
- for (i = 0; i < xf86_config->num_crtc; i++) {
- nv_crtc = to_nouveau_crtc(xf86_config->crtc[i]);
- fpc = &nv_crtc->state->fp_control;
-
- nv_crtc->fp_users &= ~(1 << nv_encoder->dcb->index);
- if (!is_fpc_off(*fpc) && !nv_crtc->fp_users) {
- nv_crtc->dpms_saved_fp_control = *fpc;
- /* cut the FP output */
- *fpc &= ~FP_TG_CONTROL_ON;
- *fpc |= FP_TG_CONTROL_OFF;
- NVWriteRAMDAC(pNv, nv_crtc->head,
- NV_PRAMDAC_FP_TG_CONTROL, *fpc);
- }
- }
-}
-
-static bool is_powersaving_dpms(int mode)
-{
- return (mode == DPMSModeStandby || mode == DPMSModeSuspend ||
- mode == DPMSModeOff);
-}
-
-static void
-lvds_encoder_dpms(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode)
-{
- NVPtr pNv = NVPTR(pScrn);
- bool was_powersaving = is_powersaving_dpms(nv_encoder->last_dpms);
-
- if (nv_encoder->last_dpms == mode)
- return;
- nv_encoder->last_dpms = mode;
-
- NV_TRACE(pScrn, "Setting dpms mode %d on lvds encoder (output %d)\n",
- mode, nv_encoder->dcb->index);
-
- if (was_powersaving && is_powersaving_dpms(mode))
- return;
-
- if (nv_encoder->dcb->lvdsconf.use_power_scripts) {
- /* when removing an output, crtc may not be set, but PANEL_OFF
- * must still be run
- */
- int head = crtc ? to_nouveau_crtc(crtc)->head :
- nv_get_digital_bound_head(pNv, nv_encoder->dcb->or);
-
- if (mode == DPMSModeOn)
- call_lvds_script(pScrn, nv_encoder->dcb, head,
- LVDS_PANEL_ON, nv_encoder->native_mode->Clock);
- else
- /* pxclk of 0 is fine for PANEL_OFF, and for a
- * disconnected LVDS encoder there is no native_mode
- */
- call_lvds_script(pScrn, nv_encoder->dcb, head,
- LVDS_PANEL_OFF, 0);
- }
-
- dpms_update_fp_control(pScrn, nv_encoder, crtc, mode);
-
- if (mode == DPMSModeOn)
- nv_digital_output_prepare_sel_clk(pNv, nv_encoder, to_nouveau_crtc(crtc)->head);
- else {
- pNv->set_state.sel_clk = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_SEL_CLK);
- pNv->set_state.sel_clk &= ~0xf0;
- }
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_SEL_CLK, pNv->set_state.sel_clk);
-}
-
-static void
-vga_encoder_dpms(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode)
-{
- NVPtr pNv = NVPTR(pScrn);
-
- if (nv_encoder->last_dpms == mode)
- return;
- nv_encoder->last_dpms = mode;
-
- NV_TRACE(pScrn, "Setting dpms mode %d on vga encoder (output %d)\n",
- mode, nv_encoder->dcb->index);
-
- if (pNv->gf4_disp_arch) {
- uint32_t outputval = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + nv_output_ramdac_offset(nv_encoder));
-
- if (mode == DPMSModeOff)
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + nv_output_ramdac_offset(nv_encoder),
- outputval & ~NV_PRAMDAC_DACCLK_SEL_DACCLK);
- else if (mode == DPMSModeOn)
- NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + nv_output_ramdac_offset(nv_encoder),
- outputval | NV_PRAMDAC_DACCLK_SEL_DACCLK);
- }
-}
-
-static void
-tmds_encoder_dpms(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode)
-{
- if (nv_encoder->last_dpms == mode)
- return;
- nv_encoder->last_dpms = mode;
-
- NV_TRACE(pScrn, "Setting dpms mode %d on tmds encoder (output %d)\n",
- mode, nv_encoder->dcb->index);
-
- dpms_update_fp_control(pScrn, nv_encoder, crtc, mode);
-}
-
-static void nv_output_dpms(xf86OutputPtr output, int mode)
-{
- struct nouveau_connector *nv_connector = to_nouveau_connector(output);
- struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
- ScrnInfoPtr pScrn = output->scrn;
- xf86CrtcPtr crtc = output->crtc;
- NVPtr pNv = NVPTR(pScrn);
- int i;
- void (* const encoder_dpms[4])(ScrnInfoPtr, struct nouveau_encoder *, xf86CrtcPtr, int) =
- /* index matches DCB type */
- { vga_encoder_dpms, NULL, tmds_encoder_dpms, lvds_encoder_dpms };
-
- struct nouveau_encoder *nv_encoder_i;
- FOR_EACH_ENCODER_IN_CONNECTOR(i, nv_connector, nv_encoder_i)
- if (nv_encoder_i != nv_encoder)
- encoder_dpms[nv_encoder_i->dcb->type](pScrn, nv_encoder_i, crtc, DPMSModeOff);
-
- if (nv_encoder) /* may be called before encoder is picked, but iteration above solves it */
- encoder_dpms[nv_encoder->dcb->type](pScrn, nv_encoder, crtc, mode);
-}
-
-void nv_encoder_save(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder)
-{
- NVPtr pNv = NVPTR(pScrn);
-
- if (!nv_encoder->dcb) /* uninitialised encoder */
- return;
-
- if (pNv->gf4_disp_arch && nv_encoder->dcb->type == OUTPUT_ANALOG)
- nv_encoder->restore.output =
- NVReadRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK +
- nv_output_ramdac_offset(nv_encoder));
- if (pNv->twoHeads && IS_DFP(nv_encoder->dcb->type))
- nv_encoder->restore.head =
- nv_get_digital_bound_head(pNv, nv_encoder->dcb->or);
-}
-
-void nv_encoder_restore(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder)
-{
- NVPtr pNv = NVPTR(pScrn);
- int head = nv_encoder->restore.head;
-
- if (!nv_encoder->dcb) /* uninitialised encoder */
- return;
-
- if (pNv->gf4_disp_arch && nv_encoder->dcb->type == OUTPUT_ANALOG)
- NVWriteRAMDAC(pNv, 0,
- NV_PRAMDAC_DACCLK + nv_output_ramdac_offset(nv_encoder),
- nv_encoder->restore.output);
- if (nv_encoder->dcb->type == OUTPUT_LVDS)
- call_lvds_script(pScrn, nv_encoder->dcb, head, LVDS_PANEL_ON,
- nv_encoder->native_mode->Clock);
- if (nv_encoder->dcb->type == OUTPUT_TMDS) {
- int clock = nouveau_hw_pllvals_to_clk
- (&pNv->saved_regs.head[head].pllvals);
-
- run_tmds_table(pScrn, nv_encoder->dcb, head, clock);
- }
-
- nv_encoder->last_dpms = NV_DPMS_CLEARED;
-}
-
-static const xf86OutputFuncsRec nv_output_funcs = {
- .dpms = nv_output_dpms,
- .mode_valid = nv_output_mode_valid,
- .mode_fixup = nv_output_mode_fixup,
- .mode_set = nv_output_mode_set,
- .detect = nv_output_detect,
- .get_modes = nv_output_get_edid_modes,
- .destroy = nv_output_destroy,
- .prepare = nv_output_prepare,
- .commit = nv_output_commit,
- .create_resources = nv_output_create_resources,
- .set_property = nv_output_set_property,
-};
-
-static const xf86OutputFuncsRec nv_lvds_output_funcs = {
- .dpms = nv_output_dpms,
- .mode_valid = nv_output_mode_valid,
- .mode_fixup = nv_output_mode_fixup,
- .mode_set = nv_output_mode_set,
- .detect = nv_output_detect,
- .get_modes = nv_lvds_output_get_modes,
- .destroy = nv_output_destroy,
- .prepare = nv_output_prepare,
- .commit = nv_output_commit,
- .create_resources = nv_output_create_resources,
- .set_property = nv_output_set_property,
-};
-
-static void
-nv_add_encoder(ScrnInfoPtr pScrn, struct dcb_entry *dcbent)
-{
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_encoder *nv_encoder = &pNv->encoders[dcbent->index];
-
- nv_encoder->dcb = dcbent;
- nv_encoder->last_dpms = NV_DPMS_CLEARED;
- nv_encoder->dithering = pNv->FPDither;
- if (pNv->FpScale && pNv->gf4_disp_arch) /* GPU Scaling */
- nv_encoder->scaling_mode = SCALE_ASPECT;
- else if (nv_encoder->dcb->type == OUTPUT_LVDS)
- nv_encoder->scaling_mode = SCALE_NOSCALE;
- else
- nv_encoder->scaling_mode = SCALE_PANEL;
- if (xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE)) {
- nv_encoder->scaling_mode = nv_scaling_mode_lookup(xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE), -1);
- if (nv_encoder->scaling_mode == SCALE_INVALID)
- nv_encoder->scaling_mode = SCALE_ASPECT; /* default */
- }
-}
-
-static void
-nv_add_connector(ScrnInfoPtr pScrn, int i2c_index, int encoders, const xf86OutputFuncsRec *output_funcs, char *outputname)
-{
- NVPtr pNv = NVPTR(pScrn);
- xf86OutputPtr output;
- struct nouveau_connector *nv_connector;
-
- if (!(output = xf86OutputCreate(pScrn, output_funcs, outputname)))
- return;
- if (!(nv_connector = xcalloc(1, sizeof (struct nouveau_connector)))) {
- xf86OutputDestroy(output);
- return;
- }
-
- output->driver_private = nv_connector;
-
- if (i2c_index < 0xf)
- NV_I2CInit(pScrn, &nv_connector->pDDCBus, &pNv->vbios->dcb->i2c[i2c_index], xstrdup(outputname));
- nv_connector->possible_encoders = encoders;
-}
-
-void NvSetupOutputs(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- struct parsed_dcb *dcb = pNv->vbios->dcb;
- uint16_t connectors[0x10] = { 0 };
- int i, vga_count = 0, dvid_count = 0, dvii_count = 0, lvds_count = 0;
-
- if (!(pNv->encoders = xcalloc(dcb->entries, sizeof (struct nouveau_encoder))))
- return;
-
- for (i = 0; i < dcb->entries; i++) {
- struct dcb_entry *dcbent = &dcb->entry[i];
-
- if (dcbent->type == OUTPUT_TV)
- continue;
- if (dcbent->type > 3) {
- NV_WARN(pScrn, "DCB type %d not known\n", dcbent->type);
- continue;
- }
-
- connectors[dcbent->i2c_index] |= 1 << i;
-
- nv_add_encoder(pScrn, dcbent);
- }
-
- for (i = 0; i < dcb->entries; i++) {
- struct dcb_entry *dcbent = &dcb->entry[i];
- int i2c_index = dcbent->i2c_index;
- uint16_t encoders = connectors[i2c_index];
- char outputname[20];
- xf86OutputFuncsRec const *funcs = &nv_output_funcs;
-
- if (!encoders)
- continue;
-
- switch (dcbent->type) {
- case OUTPUT_ANALOG:
- if (!MULTIPLE_ENCODERS(encoders))
- sprintf(outputname, "VGA-%d", vga_count++);
- else
- sprintf(outputname, "DVI-I-%d", dvii_count++);
- break;
- case OUTPUT_TMDS:
- if (!MULTIPLE_ENCODERS(encoders))
- sprintf(outputname, "DVI-D-%d", dvid_count++);
- else
- sprintf(outputname, "DVI-I-%d", dvii_count++);
- break;
- case OUTPUT_LVDS:
- sprintf(outputname, "LVDS-%d", lvds_count++);
- funcs = &nv_lvds_output_funcs;
- /* don't create i2c adapter when lvds ddc not allowed */
- if (dcbent->lvdsconf.use_straps_for_mode ||
- pNv->vbios->fp_no_ddc)
- i2c_index = 0xf;
- break;
- default:
- continue;
- }
-
- nv_add_connector(pScrn, i2c_index, encoders, funcs, outputname);
- connectors[i2c_index] = 0; /* avoid connectors being added multiply */
- }
-}
diff --git a/src/nv_proto.h b/src/nv_proto.h
index ee1c8f2..733ee0a 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -11,7 +11,2 @@ void drmmode_fbcon_copy(ScrnInfoPtr pScrn);
-/* in nouveau_calc.c */
-void nouveau_calc_arb(ScrnInfoPtr pScrn, int vclk, int bpp, int *burst, int *lwm);
-int nouveau_calc_pll_mnp(ScrnInfoPtr pScrn, struct pll_lims *pll_lim, int clk,
- struct nouveau_pll_vals *pv);
-
/* in nv_accel_common.c */
@@ -40,17 +35,2 @@ unsigned int nv_window_belongs_to_crtc(ScrnInfoPtr, int, int, int, int);
-/* in nv_setup.c */
-void RivaEnterLeave(ScrnInfoPtr pScrn, Bool enter);
-void NVCommonSetup(ScrnInfoPtr pScrn);
-
-/* in nv_cursor.c */
-Bool NVCursorInitRandr12(ScreenPtr pScreen);
-void nv_crtc_show_cursor(xf86CrtcPtr crtc);
-void nv_crtc_hide_cursor(xf86CrtcPtr crtc);
-void nv_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y);
-void nv_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg);
-void nv_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *image);
-void nv_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image);
-void nv_cursor_convert_cursor(uint32_t *src, void *dst, int src_stride,
- int dst_stride, int bpp, uint32_t fg, uint32_t bg);
-
/* in nv_dma.c */
@@ -74,48 +54,2 @@ void NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
-/* in nv_bios.c */
-int NVParseBios(ScrnInfoPtr pScrn);
-int call_lvds_script(ScrnInfoPtr pScrn, struct dcb_entry *dcbent, int head, enum LVDS_script script, int pxclk);
-bool nouveau_bios_fp_mode(ScrnInfoPtr pScrn, DisplayModeRec *mode);
-int nouveau_bios_parse_lvds_table(ScrnInfoPtr pScrn, int pxclk, bool *dl, bool *if_is_24bit);
-int run_tmds_table(ScrnInfoPtr pScrn, struct dcb_entry *dcbent, int head, int pxclk);
-int get_pll_limits(ScrnInfoPtr pScrn, uint32_t limit_match, struct pll_lims *pll_lim);
-uint8_t * nouveau_bios_embedded_edid(ScrnInfoPtr pScrn);
-int nouveau_bios_run_display_table(ScrnInfoPtr, struct dcb_entry *, int pxclk);
-
-/* nv_crtc.c */
-void nv_crtc_set_digital_vibrance(xf86CrtcPtr crtc, int level);
-void nv_crtc_set_image_sharpening(xf86CrtcPtr crtc, int level);
-void NVCrtcSetBase(xf86CrtcPtr crtc, int x, int y);
-void nv_crtc_init(ScrnInfoPtr pScrn, int crtc_num);
-
-/* nv_output.c */
-void nv_encoder_restore(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder);
-void nv_encoder_save(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder);
-void NvSetupOutputs(ScrnInfoPtr pScrn);
-
-/* nouveau_hw.c */
-void NVWriteVgaSeq(NVPtr pNv, int head, uint8_t index, uint8_t value);
-uint8_t NVReadVgaSeq(NVPtr pNv, int head, uint8_t index);
-void NVWriteVgaGr(NVPtr pNv, int head, uint8_t index, uint8_t value);
-uint8_t NVReadVgaGr(NVPtr pNv, int head, uint8_t index);
-void NVSetOwner(NVPtr pNv, int owner);
-int nouveau_hw_get_current_head(ScrnInfoPtr pScrn);
-void NVBlankScreen(NVPtr pNv, int head, bool blank);
-void nouveau_hw_setpll(ScrnInfoPtr pScrn, uint32_t reg1,
- struct nouveau_pll_vals *pv);
-int nouveau_hw_get_pllvals(ScrnInfoPtr pScrn, enum pll_types plltype,
- struct nouveau_pll_vals *pllvals);
-int nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pllvals);
-int nouveau_hw_get_clock(ScrnInfoPtr pScrn, enum pll_types plltype);
-void nouveau_hw_save_vga_fonts(ScrnInfoPtr pScrn, bool save);
-void nouveau_hw_save_state(ScrnInfoPtr pScrn, int head,
- struct nouveau_mode_state *state);
-void nouveau_hw_load_state(ScrnInfoPtr pScrn, int head,
- struct nouveau_mode_state *state);
-void nouveau_hw_load_state_palette(NVPtr pNv, int head,
- struct nouveau_mode_state *state);
-
-/* in nv_i2c.c */
-int NV_I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, struct dcb_i2c_entry *dcb_i2c, char *name);
-
/* in nv04_video_overlay.c */
@@ -215,38 +149,2 @@ Bool NV50EXAUploadSIFC(const char *src, int src_pitch,
-/* in nv50_display.c */
-Bool NV50DispPreInit(ScrnInfoPtr);
-Bool NV50DispInit(ScrnInfoPtr);
-void NV50DispShutdown(ScrnInfoPtr);
-
-/* in nv50_cursor.c */
-Bool NV50CursorInit(ScreenPtr);
-Bool NV50CursorAcquire(ScrnInfoPtr);
-void NV50CursorRelease(ScrnInfoPtr);
-
-/* in nv50_crtc.c */
-void NV50DisplayCommand(ScrnInfoPtr pScrn, uint32_t addr, uint32_t value);
-void NV50CrtcCommand(nouveauCrtcPtr crtc, uint32_t addr, uint32_t value);
-void NV50CrtcInit(ScrnInfoPtr pScrn);
-void NV50CrtcDestroy(ScrnInfoPtr pScrn);
-
-/* in nv50_output.c */
-int NV50OrOffset(nouveauOutputPtr output);
-void NV50OutputSetup(ScrnInfoPtr pScrn);
-void NV50OutputDestroy(ScrnInfoPtr pScrn);
-
-/* nv50_dac.c */
-void NV50DacSetFunctionPointers(nouveauOutputPtr output);
-
-/* nv50_sor.c */
-void NV50SorSetFunctionPointers(nouveauOutputPtr output);
-
-/* nv50_connector.c */
-void NV50ConnectorInit(ScrnInfoPtr pScrn);
-void NV50ConnectorDestroy(ScrnInfoPtr pScrn);
-
-/* nv50_randr.c */
-void nv50_crtc_init(ScrnInfoPtr pScrn, int crtc_num);
-void nv50_output_create(ScrnInfoPtr pScrn);
-int nv_scaling_mode_lookup(char *name, int size);
-
/* nv50_xv.c */
diff --git a/src/nv_setup.c b/src/nv_setup.c
deleted file mode 100644
index f0478ca..0000000
--- a/src/nv_setup.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright 2003 NVIDIA, Corporation
- *
- * 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 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.
- */
-
-#include "nv_include.h"
-
-static void nv4GetConfig (NVPtr pNv)
-{
- uint32_t reg_FB0 = nvReadFB(pNv, NV_PFB_BOOT_0);
-
- if (reg_FB0 & 0x00000100)
- pNv->RamAmountKBytes = ((reg_FB0 >> 12) & 0x0F) * 1024 * 2 + 1024 * 2;
- else
- switch (reg_FB0 & 0x00000003) {
- case 0:
- pNv->RamAmountKBytes = 1024 * 32;
- break;
- case 1:
- pNv->RamAmountKBytes = 1024 * 4;
- break;
- case 2:
- pNv->RamAmountKBytes = 1024 * 8;
- break;
- case 3:
- default:
- pNv->RamAmountKBytes = 1024 * 16;
- break;
- }
-}
-
-static void nv10GetConfig(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- uint32_t implementation = pNv->Chipset & 0x0ff0;
- struct pci_device *dev = NULL;
- uint32_t data;
-
- if (implementation == CHIPSET_NFORCE ||
- implementation == CHIPSET_NFORCE2) {
- dev = pci_device_find_by_slot(0, 0, 0, 1);
- if (!dev) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "couldn't find bridge device\n");
- return;
- }
- }
-
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- if (!(nvReadMC(pNv, 0x0004) & 0x01000001))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Card is in big endian mode, something is very wrong !\n");
-#endif
-
- if (implementation == CHIPSET_NFORCE) {
- pci_device_cfg_read_u32(dev, &data, 0x7c);
- pNv->RamAmountKBytes = (((data >> 6) & 31) + 1) * 1024;
- } else if (implementation == CHIPSET_NFORCE2) {
- pci_device_cfg_read_u32(dev, &data, 0x84);
- pNv->RamAmountKBytes = (((data >> 4) & 127) + 1) * 1024;
- } else {
- pNv->RamAmountKBytes =
- (nvReadFB(pNv, NV_PFB_CSTATUS) & 0xFFF00000) >> 10;
- }
-
- if (pNv->RamAmountKBytes > 256*1024)
- pNv->RamAmountKBytes = 256*1024;
-}
-
-void
-NVCommonSetup(ScrnInfoPtr pScrn)
-{
- NVPtr pNv = NVPTR(pScrn);
- uint16_t implementation = pNv->Chipset & 0x0ff0;
-
- /* 0x01000000 is the size */
- pci_device_map_range(pNv->PciInfo, pNv->IOAddress, 0x01000000, PCI_DEV_MAP_FLAG_WRITABLE, (void *)&pNv->REGS);
- pci_device_map_range(pNv->PciInfo, pNv->VRAMPhysical, 0x10000, PCI_DEV_MAP_FLAG_WRITABLE, (void *)&pNv->FB_BAR);
-
- pNv->alphaCursor = (pNv->NVArch >= 0x11);
-
- pNv->twoHeads = (pNv->Architecture >= NV_ARCH_10) &&
- (implementation != CHIPSET_NV10) &&
- (implementation != CHIPSET_NV15) &&
- (implementation != CHIPSET_NFORCE) &&
- (implementation != CHIPSET_NV20);
-
- pNv->gf4_disp_arch = pNv->twoHeads && implementation != CHIPSET_NV11;
-
- /* nv30 and nv35 have two stage PLLs, but use only one register; they are dealt with separately */
- pNv->two_reg_pll = (implementation == CHIPSET_NV31) ||
- (implementation == CHIPSET_NV36) ||
- (pNv->Architecture >= NV_ARCH_40);
-
- pNv->WaitVSyncPossible = (pNv->Architecture >= NV_ARCH_10) &&
- (implementation != CHIPSET_NV10);
-
- pNv->BlendingPossible = ((pNv->Chipset & 0xffff) > CHIPSET_NV04);
-
- /* look for known laptop chips */
- /* FIXME still probably missing some ids (for randr12, pre-nv40 mobile should be auto-detected) */
- switch(pNv->Chipset & 0xffff) {
- case 0x0098:
- case 0x0099:
- case 0x00C8:
- case 0x00C9:
- case 0x00CC:
- case 0x0112:
- case 0x0144:
- case 0x0146:
- case 0x0148:
- case 0x0149:
- case 0x0160:
- case 0x0164:
- case 0x0166:
- case 0x0167:
- case 0x0168:
- case 0x0169:
- case 0x016B:
- case 0x016C:
- case 0x016D:
- case 0x0174:
- case 0x0175:
- case 0x0176:
- case 0x0177:
- case 0x0179:
- case 0x017C:
- case 0x017D:
- case 0x0186:
- case 0x0187:
- case 0x018D:
- case 0x01D6:
- case 0x01D7:
- case 0x01D8:
- case 0x0228:
- case 0x0244:
- case 0x0286:
- case 0x028C:
- case 0x0297:
- case 0x0298:
- case 0x0299:
- case 0x0316:
- case 0x0317:
- case 0x031A:
- case 0x031B:
- case 0x031C:
- case 0x031D:
- case 0x031E:
- case 0x031F:
- case 0x0324:
- case 0x0325:
- case 0x0328:
- case 0x0329:
- case 0x032C:
- case 0x032D:
- case 0x0347:
- case 0x0348:
- case 0x0349:
- case 0x034B:
- case 0x034C:
- case 0x0397:
- case 0x0398:
- case 0x039B:
- pNv->Mobile = TRUE;
- break;
- default:
- break;
- }
-
- if (pNv->twoHeads) {
- pNv->vtOWNER = nouveau_hw_get_current_head(pScrn);
-
- NV_TRACE(pScrn, "Initial CRTC_OWNER is %d\n", pNv->vtOWNER);
-
- /* we need to ensure the heads are not tied henceforth, or
- * reading any 8 bit reg on head B will fail.
- * setting a single arbitrary head solves that */
- NVSetOwner(pNv, 0);
- }
-
- /* Parse the bios to initialize the card */
- if (!pNv->kms_enable)
- NVParseBios(pScrn);
-
- if (pNv->Architecture == NV_ARCH_04)
- nv4GetConfig(pNv);
- else
- nv10GetConfig(pScrn);
-}
-
diff --git a/src/nv_type.h b/src/nv_type.h
index 6face1f..510ec11 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -19,10 +19,2 @@
-#include "nouveau_bios.h"
-
-#include "nouveau_ms.h"
-
-#include "nouveau_crtc.h"
-#include "nouveau_connector.h"
-#include "nouveau_output.h"
-
#define NV_ARCH_03 0x03
@@ -71,27 +63,5 @@
-
-#undef SetBit /* some input related header also includes a macro called SetBit, which gives a lot of warnings. */
-#define BITMASK(t,b) (((unsigned)(1U << (((t)-(b)+1)))-1) << (b))
-#define MASKEXPAND(mask) BITMASK(1?mask,0?mask)
-#define SetBF(mask,value) ((value) << (0?mask))
-#define GetBF(var,mask) (((unsigned)((var) & MASKEXPAND(mask))) >> (0?mask) )
-#define SetBitField(value,from,to) SetBF(to, GetBF(value,from))
-#define SetBit(n) (1<<(n))
-#define Set8Bits(value) ((value)&0xff)
-
/* NV50 */
-typedef enum ORNum {
- DAC0 = 0,
- DAC1 = 1,
- DAC2 = 2,
- SOR0 = 0,
- SOR1 = 1,
- SOR2 = 2,
-} ORNum;
-
typedef struct _NVRec *NVPtr;
typedef struct _NVRec {
- struct nouveau_mode_state saved_regs;
- struct nouveau_mode_state set_state;
- uint32_t saved_vga_font[4][16384];
uint32_t Architecture;
@@ -102,3 +72,2 @@ typedef struct _NVRec {
Bool Primary;
- CARD32 IOAddress;
@@ -106,10 +75,2 @@ typedef struct _NVRec {
unsigned long VRAMPhysical;
- /* Size of VRAM BAR */
- unsigned long VRAMPhysicalSize;
- /* Accesible VRAM size (by the GPU) */
- unsigned long VRAMSize;
- /* Mapped VRAM BAR */
- void * VRAMMap;
- /* Accessible AGP size */
- unsigned long AGPSize;
@@ -119,13 +80,6 @@ typedef struct _NVRec {
void * offscreen_map;
- //struct nouveau_bo * FB_old; /* for KMS */
- struct nouveau_bo * shadow[2]; /* for easy acces by exa */
- struct nouveau_bo * Cursor;
- struct nouveau_bo * Cursor2;
struct nouveau_bo * GART;
- struct nvbios VBIOS;
- struct nouveau_bios_info *vbios;
Bool NoAccel;
Bool HWCursor;
- Bool FpScale;
Bool ShadowFB;
@@ -133,8 +87,3 @@ typedef struct _NVRec {
int ShadowPitch;
- uint32_t RamAmountKBytes;
- volatile CARD32 *REGS;
- volatile CARD32 *FB_BAR;
-
- uint8_t cur_head;
ExaDriverPtr EXADriverPtr;
@@ -148,7 +97,4 @@ typedef struct _NVRec {
/* Cursor */
- uint32_t curImage[256];
- /* I2C / DDC */
- xf86Int10InfoPtr pInt10;
- unsigned Int10Mode;
- void (*VideoTimerCallback)(ScrnInfoPtr, Time);
+ uint32_t curImage[256];
+ void (*VideoTimerCallback)(ScrnInfoPtr, Time);
XF86VideoAdaptorPtr overlayAdaptor;
@@ -157,10 +103,3 @@ typedef struct _NVRec {
int videoKey;
- Bool FPDither;
- int Mobile;
- int vtOWNER;
OptionInfoPtr Options;
- bool alphaCursor;
- bool twoHeads;
- bool gf4_disp_arch;
- bool two_reg_pll;
@@ -170,4 +109,2 @@ typedef struct _NVRec {
- Bool WaitVSyncPossible;
- Bool BlendingPossible;
DRIInfoPtr pDRIInfo;
@@ -176,16 +113,4 @@ typedef struct _NVRec {
- Bool kms_enable;
-
- I2CBusPtr pI2CBus[DCB_MAX_NUM_I2C_ENTRIES];
- struct nouveau_encoder *encoders;
-
-#ifdef XF86DRM_MODE
void *drmmode; /* for KMS */
Bool allow_dpms;
-#endif
-
- nouveauCrtcPtr crtc[2];
- nouveauOutputPtr output; /* this a linked list. */
- /* Assume a connector can exist for each i2c bus. */
- nouveauConnectorPtr connector[DCB_MAX_NUM_I2C_ENTRIES];
@@ -230,11 +155,2 @@ typedef struct _NVRec {
-#define nvReadCurVGA(pNv, reg) NVReadVgaCrtc(pNv, pNv->cur_head, reg)
-#define nvWriteCurVGA(pNv, reg, val) NVWriteVgaCrtc(pNv, pNv->cur_head, reg, val)
-
-#define nvReadCurRAMDAC(pNv, reg) NVReadRAMDAC(pNv, pNv->cur_head, reg)
-#define nvWriteCurRAMDAC(pNv, reg, val) NVWriteRAMDAC(pNv, pNv->cur_head, reg, val)
-
-#define nvReadCurCRTC(pNv, reg) NVReadCRTC(pNv, pNv->cur_head, reg)
-#define nvWriteCurCRTC(pNv, reg, val) NVWriteCRTC(pNv, pNv->cur_head, reg, val)
-
typedef struct _NVPortPrivRec {
@@ -331,2 +247,38 @@ nouveau_pixmap_offset(PixmapPtr ppix)
+static inline uint32_t
+ nv_pitch_align(NVPtr pNv, uint32_t width, int bpp)
+{
+ int mask;
+
+ if (bpp == 15)
+ bpp = 16;
+ if (bpp == 24 || bpp == 30)
+ bpp = 8;
+
+ /* Alignment requirements taken from the Haiku driver */
+ if (pNv->Architecture == NV_ARCH_04)
+ mask = 128 / bpp - 1;
+ else
+ mask = 512 / bpp - 1;
+
+ return (width + mask) & ~mask;
+}
+
+/* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */
+#define NV04_CURSOR_SIZE 32
+/* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */
+#define NV10_CURSOR_SIZE 64
+
+static inline int nv_cursor_width(NVPtr pNv)
+{
+ return pNv->NVArch >= 0x10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
+}
+
+static inline int nv_cursor_pixels(NVPtr pNv)
+{
+ int width = nv_cursor_width(pNv);
+
+ return width * width;
+}
+
#endif /* __NV_STRUCT_H__ */
diff --git a/src/nvreg.h b/src/nvreg.h
deleted file mode 100644
index 060e243..0000000
--- a/src/nvreg.h
+++ /dev/null
@@ -1,503 +0,0 @@
-/* $XConsortium: nvreg.h /main/2 1996/10/28 05:13:41 kaleb $ */
-/*
- * Copyright 1996-1997 David J. McKay
- *
- * 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
- * DAVID J. MCKAY 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.
- */
-
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nvreg.h,v 1.6 2002/01/25 21:56:06 tsi Exp $ */
-
-#ifndef __NVREG_H_
-#define __NVREG_H_
-
-#define NV_PMC_OFFSET 0x00000000
-#define NV_PMC_SIZE 0x00001000
-
-#define NV_PBUS_OFFSET 0x00001000
-#define NV_PBUS_SIZE 0x00001000
-
-#define NV_PFIFO_OFFSET 0x00002000
-#define NV_PFIFO_SIZE 0x00002000
-
-#define NV_HDIAG_OFFSET 0x00005000
-#define NV_HDIAG_SIZE 0x00001000
-
-#define NV_PRAM_OFFSET 0x00006000
-#define NV_PRAM_SIZE 0x00001000
-
-#define NV_PVIDEO_OFFSET 0x00008000
-#define NV_PVIDEO_SIZE 0x00001000
-
-#define NV_PTIMER_OFFSET 0x00009000
-#define NV_PTIMER_SIZE 0x00001000
-
-#define NV_PPM_OFFSET 0x0000A000
-#define NV_PPM_SIZE 0x00001000
-
-#define NV_PRMVGA_OFFSET 0x000A0000
-#define NV_PRMVGA_SIZE 0x00020000
-
-#define NV_PRMVIO0_OFFSET 0x000C0000
-#define NV_PRMVIO_SIZE 0x00002000
-#define NV_PRMVIO1_OFFSET 0x000C2000
-
-#define NV_PFB_OFFSET 0x00100000
-#define NV_PFB_SIZE 0x00001000
-
-#define NV_PEXTDEV_OFFSET 0x00101000
-#define NV_PEXTDEV_SIZE 0x00001000
-
-#define NV_PME_OFFSET 0x00200000
-#define NV_PME_SIZE 0x00001000
-
-#define NV_PROM_OFFSET 0x00300000
-#define NV_PROM_SIZE 0x00010000
-
-#define NV_PGRAPH_OFFSET 0x00400000
-#define NV_PGRAPH_SIZE 0x00010000
-
-#define NV_PCRTC0_OFFSET 0x00600000
-#define NV_PCRTC0_SIZE 0x00002000 /* empirical */
-
-#define NV_PRMCIO0_OFFSET 0x00601000
-#define NV_PRMCIO_SIZE 0x00002000
-#define NV_PRMCIO1_OFFSET 0x00603000
-
-#define NV50_DISPLAY_OFFSET 0x00610000
-#define NV50_DISPLAY_SIZE 0x0000FFFF
-
-#define NV_PRAMDAC0_OFFSET 0x00680000
-#define NV_PRAMDAC0_SIZE 0x00002000
-
-#define NV_PRMDIO0_OFFSET 0x00681000
-#define NV_PRMDIO_SIZE 0x00002000
-#define NV_PRMDIO1_OFFSET 0x00683000
-
-#define NV_PRAMIN_OFFSET 0x00700000
-#define NV_PRAMIN_SIZE 0x00100000
-
-#define NV_FIFO_OFFSET 0x00800000
-#define NV_FIFO_SIZE 0x00800000
-
-#define NV_PMC_BOOT_0 0x00000000
-#define NV_PMC_ENABLE 0x00000200
-
-#define NV_VIO_VSE2 0x000003c3
-#define NV_VIO_SRX 0x000003c4
-
-#define NV_CIO_CRX__COLOR 0x000003d4
-#define NV_CIO_CR__COLOR 0x000003d5
-
-#define NV_PBUS_DEBUG_1 0x00001084
-#define NV_PBUS_DEBUG_4 0x00001098
-#define NV_PBUS_DEBUG_DUALHEAD_CTL 0x000010f0
-#define NV_PBUS_POWERCTRL_1 0x00001584
-#define NV_PBUS_POWERCTRL_2 0x00001588
-#define NV_PBUS_POWERCTRL_4 0x00001590
-#define NV_PBUS_PCI_NV_19 0x0000184C
-#define NV_PBUS_PCI_NV_20 0x00001850
-# define NV_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED (0 << 0)
-# define NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED (1 << 0)
-
-#define NV_PFIFO_RAMHT 0x00002210
-
-#define NV_PRMVIO_MISC__WRITE 0x000c03c2
-#define NV_PRMVIO_SRX 0x000c03c4
-#define NV_PRMVIO_SR 0x000c03c5
-# define NV_VIO_SR_RESET_INDEX 0x00
-# define NV_VIO_SR_CLOCK_INDEX 0x01
-# define NV_VIO_SR_PLANE_MASK_INDEX 0x02
-# define NV_VIO_SR_CHAR_MAP_INDEX 0x03
-# define NV_VIO_SR_MEM_MODE_INDEX 0x04
-#define NV_PRMVIO_MISC__READ 0x000c03cc
-#define NV_PRMVIO_GRX 0x000c03ce
-#define NV_PRMVIO_GX 0x000c03cf
-# define NV_VIO_GX_SR_INDEX 0x00
-# define NV_VIO_GX_SREN_INDEX 0x01
-# define NV_VIO_GX_CCOMP_INDEX 0x02
-# define NV_VIO_GX_ROP_INDEX 0x03
-# define NV_VIO_GX_READ_MAP_INDEX 0x04
-# define NV_VIO_GX_MODE_INDEX 0x05
-# define NV_VIO_GX_MISC_INDEX 0x06
-# define NV_VIO_GX_DONT_CARE_INDEX 0x07
-# define NV_VIO_GX_BIT_MASK_INDEX 0x08
-
-#define NV_PFB_BOOT_0 0x00100000
-#define NV_PFB_CFG0 0x00100200
-#define NV_PFB_CFG1 0x00100204
-#define NV_PFB_CSTATUS 0x0010020C
-#define NV_PFB_REFCTRL 0x00100210
-# define NV_PFB_REFCTRL_VALID_1 (1 << 31)
-#define NV_PFB_PAD 0x0010021C
-# define NV_PFB_PAD_CKE_NORMAL (1 << 0)
-#define NV_PFB_TILE_NV10 0x00100240
-#define NV_PFB_TILE_SIZE_NV10 0x00100244
-#define NV_PFB_REF 0x001002D0
-# define NV_PFB_REF_CMD_REFRESH (1 << 0)
-#define NV_PFB_PRE 0x001002D4
-# define NV_PFB_PRE_CMD_PRECHARGE (1 << 0)
-#define NV_PFB_CLOSE_PAGE2 0x0010033C
-#define NV_PFB_TILE_NV40 0x00100600
-#define NV_PFB_TILE_SIZE_NV40 0x00100604
-
-#define NV_PEXTDEV_BOOT_0 0x00101000
-# define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT (8 << 12)
-#define NV_PEXTDEV_BOOT_3 0x0010100c
-
-#define NV_PCRTC_INTR_0 0x00600100
-# define NV_PCRTC_INTR_0_VBLANK (1 << 0)
-#define NV_PCRTC_INTR_EN_0 0x00600140
-#define NV_PCRTC_START 0x00600800
-#define NV_PCRTC_CONFIG 0x00600804
-# define NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA (1 << 0)
-# define NV_PCRTC_CONFIG_START_ADDRESS_HSYNC (2 << 0)
-#define NV_PCRTC_CURSOR_CONFIG 0x00600810
-# define NV_PCRTC_CURSOR_CONFIG_ENABLE_ENABLE (1 << 0)
-# define NV_PCRTC_CURSOR_CONFIG_DOUBLE_SCAN_ENABLE (1 << 4)
-# define NV_PCRTC_CURSOR_CONFIG_ADDRESS_SPACE_PNVM (1 << 8)
-# define NV_PCRTC_CURSOR_CONFIG_CUR_BPP_32 (1 << 12)
-# define NV_PCRTC_CURSOR_CONFIG_CUR_PIXELS_64 (1 << 16)
-# define NV_PCRTC_CURSOR_CONFIG_CUR_LINES_32 (2 << 24)
-# define NV_PCRTC_CURSOR_CONFIG_CUR_LINES_64 (4 << 24)
-# define NV_PCRTC_CURSOR_CONFIG_CUR_BLEND_ALPHA (1 << 28)
-
-/* note: PCRTC_GPIO is not available on nv10, and in fact aliases 0x600810 */
-#define NV_PCRTC_GPIO 0x00600818
-#define NV_PCRTC_GPIO_EXT 0x0060081c
-#define NV_PCRTC_830 0x00600830
-#define NV_PCRTC_834 0x00600834
-#define NV_PCRTC_850 0x00600850
-#define NV_PCRTC_ENGINE_CTRL 0x00600860
-# define NV_CRTC_FSEL_I2C (1 << 4)
-# define NV_CRTC_FSEL_OVERLAY (1 << 12)
-
-#define NV_PRMCIO_ARX 0x006013c0
-#define NV_PRMCIO_AR__WRITE 0x006013c0
-#define NV_PRMCIO_AR__READ 0x006013c1
-# define NV_CIO_AR_MODE_INDEX 0x10
-# define NV_CIO_AR_OSCAN_INDEX 0x11
-# define NV_CIO_AR_PLANE_INDEX 0x12
-# define NV_CIO_AR_HPP_INDEX 0x13
-# define NV_CIO_AR_CSEL_INDEX 0x14
-#define NV_PRMCIO_INP0 0x006013c2
-#define NV_PRMCIO_CRX__COLOR 0x006013d4
-#define NV_PRMCIO_CR__COLOR 0x006013d5
- /* Standard VGA CRTC registers */
-# define NV_CIO_CR_HDT_INDEX 0x00 /* horizontal display total */
-# define NV_CIO_CR_HDE_INDEX 0x01 /* horizontal display end */
-# define NV_CIO_CR_HBS_INDEX 0x02 /* horizontal blanking start */
-# define NV_CIO_CR_HBE_INDEX 0x03 /* horizontal blanking end */
-# define NV_CIO_CR_HBE_4_0 4:0
-# define NV_CIO_CR_HRS_INDEX 0x04 /* horizontal retrace start */
-# define NV_CIO_CR_HRE_INDEX 0x05 /* horizontal retrace end */
-# define NV_CIO_CR_HRE_4_0 4:0
-# define NV_CIO_CR_HRE_HBE_5 7:7
-# define NV_CIO_CR_VDT_INDEX 0x06 /* vertical display total */
-# define NV_CIO_CR_OVL_INDEX 0x07 /* overflow bits */
-# define NV_CIO_CR_OVL_VDT_8 0:0
-# define NV_CIO_CR_OVL_VDE_8 1:1
-# define NV_CIO_CR_OVL_VRS_8 2:2
-# define NV_CIO_CR_OVL_VBS_8 3:3
-# define NV_CIO_CR_OVL_VDT_9 5:5
-# define NV_CIO_CR_OVL_VDE_9 6:6
-# define NV_CIO_CR_OVL_VRS_9 7:7
-# define NV_CIO_CR_RSAL_INDEX 0x08 /* normally "preset row scan" */
-# define NV_CIO_CR_CELL_HT_INDEX 0x09 /* cell height?! normally "max scan line" */
-# define NV_CIO_CR_CELL_HT_VBS_9 5:5
-# define NV_CIO_CR_CELL_HT_SCANDBL 7:7
-# define NV_CIO_CR_CURS_ST_INDEX 0x0a /* cursor start */
-# define NV_CIO_CR_CURS_END_INDEX 0x0b /* cursor end */
-# define NV_CIO_CR_SA_HI_INDEX 0x0c /* screen start address high */
-# define NV_CIO_CR_SA_LO_INDEX 0x0d /* screen start address low */
-# define NV_CIO_CR_TCOFF_HI_INDEX 0x0e /* cursor offset high */
-# define NV_CIO_CR_TCOFF_LO_INDEX 0x0f /* cursor offset low */
-# define NV_CIO_CR_VRS_INDEX 0x10 /* vertical retrace start */
-# define NV_CIO_CR_VRE_INDEX 0x11 /* vertical retrace end */
-# define NV_CIO_CR_VRE_3_0 3:0
-# define NV_CIO_CR_VDE_INDEX 0x12 /* vertical display end */
-# define NV_CIO_CR_OFFSET_INDEX 0x13 /* sets screen pitch */
-# define NV_CIO_CR_ULINE_INDEX 0x14 /* underline location */
-# define NV_CIO_CR_VBS_INDEX 0x15 /* vertical blank start */
-# define NV_CIO_CR_VBE_INDEX 0x16 /* vertical blank end */
-# define NV_CIO_CR_MODE_INDEX 0x17 /* crtc mode control */
-# define NV_CIO_CR_LCOMP_INDEX 0x18 /* line compare */
- /* Extended VGA CRTC registers */
-# define NV_CIO_CRE_RPC0_INDEX 0x19 /* repaint control 0 */
-# define NV_CIO_CRE_RPC0_OFFSET_10_8 7:5
-# define NV_CIO_CRE_RPC1_INDEX 0x1a /* repaint control 1 */
-# define NV_CIO_CRE_RPC1_LARGE 2:2
-# define NV_CIO_CRE_FF_INDEX 0x1b /* fifo control */
-# define NV_CIO_CRE_ENH_INDEX 0x1c /* enhanced? */
-# define NV_CIO_SR_LOCK_INDEX 0x1f /* crtc lock */
-# define NV_CIO_SR_UNLOCK_RW_VALUE 0x57
-# define NV_CIO_SR_LOCK_VALUE 0x99
-# define NV_CIO_CRE_FFLWM__INDEX 0x20 /* fifo low water mark */
-# define NV_CIO_CRE_21 0x21 /* vga shadow crtc lock */
-# define NV_CIO_CRE_LSR_INDEX 0x25 /* ? */
-# define NV_CIO_CRE_LSR_VDT_10 0:0
-# define NV_CIO_CRE_LSR_VDE_10 1:1
-# define NV_CIO_CRE_LSR_VRS_10 2:2
-# define NV_CIO_CRE_LSR_VBS_10 3:3
-# define NV_CIO_CRE_LSR_HBE_6 4:4
-# define NV_CIO_CR_ARX_INDEX 0x26 /* attribute index -- ro copy of 0x60.3c0 */
-# define NV_CIO_CRE_CHIP_ID_INDEX 0x27 /* chip revision */
-# define NV_CIO_CRE_PIXEL_INDEX 0x28
-# define NV_CIO_CRE_PIXEL_FORMAT 1:0
-# define NV_CIO_CRE_HEB__INDEX 0x2d /* horizontal extra bits? */
-# define NV_CIO_CRE_HEB_HDT_8 0:0
-# define NV_CIO_CRE_HEB_HDE_8 1:1
-# define NV_CIO_CRE_HEB_HBS_8 2:2
-# define NV_CIO_CRE_HEB_HRS_8 3:3
-# define NV_CIO_CRE_HEB_ILC_8 4:4
-# define NV_CIO_CRE_2E 0x2e /* some scratch or dummy reg to force writes to sink in */
-# define NV_CIO_CRE_HCUR_ADDR2_INDEX 0x2f /* cursor */
-# define NV_CIO_CRE_HCUR_ADDR0_INDEX 0x30 /* pixmap */
-# define NV_CIO_CRE_HCUR_ADDR0_ADR 6:0
-# define NV_CIO_CRE_HCUR_ASI 7:7
-# define NV_CIO_CRE_HCUR_ADDR1_INDEX 0x31 /* address */
-# define NV_CIO_CRE_HCUR_ADDR1_ENABLE 0:0
-# define NV_CIO_CRE_HCUR_ADDR1_CUR_DBL 1:1
-# define NV_CIO_CRE_HCUR_ADDR1_ADR 7:2
-# define NV_CIO_CRE_LCD__INDEX 0x33
-# define NV_CIO_CRE_LCD_LCD_SELECT 0:0
-# define NV_CIO_CRE_DDC0_STATUS__INDEX 0x36
-# define NV_CIO_CRE_DDC0_WR__INDEX 0x37
-# define NV_CIO_CRE_ILACE__INDEX 0x39 /* interlace */
-# define NV_CIO_CRE_SCRATCH3__INDEX 0x3b
-# define NV_CIO_CRE_SCRATCH4__INDEX 0x3c
-# define NV_CIO_CRE_DDC_STATUS__INDEX 0x3e
-# define NV_CIO_CRE_DDC_WR__INDEX 0x3f
-# define NV_CIO_CRE_EBR_INDEX 0x41 /* extra bits ? (vertical) */
-# define NV_CIO_CRE_EBR_VDT_11 0:0
-# define NV_CIO_CRE_EBR_VDE_11 2:2
-# define NV_CIO_CRE_EBR_VRS_11 4:4
-# define NV_CIO_CRE_EBR_VBS_11 6:6
-# define NV_CIO_CRE_44 0x44 /* head control */
-# define NV_CIO_CRE_CSB 0x45 /* colour saturation boost */
-# define NV_CIO_CRE_RCR 0x46
-# define NV_CIO_CRE_RCR_ENDIAN_BIG 7:7
-# define NV_CIO_CRE_47 0x47 /* extended fifo lwm, used on nv30+ */
-# define NV_CIO_CRE_4B 0x4b /* given patterns in 0x[2-3][a-c] regs, probably scratch 6 */
-# define NV_CIO_CRE_TVOUT_LATENCY 0x52
-# define NV_CIO_CRE_53 0x53 /* `fp_htiming' according to Haiku */
-# define NV_CIO_CRE_54 0x54 /* `fp_vtiming' according to Haiku */
-# define NV_CIO_CRE_57 0x57 /* index reg for cr58 */
-# define NV_CIO_CRE_58 0x58 /* data reg for cr57 */
-# define NV_CIO_CRE_59 0x59 /* related to on/off-chip-ness of digital outputs */
-# define NV_CIO_CRE_5B 0x5B /* newer colour saturation reg */
-# define NV_CIO_CRE_85 0x85
-# define NV_CIO_CRE_86 0x86
-#define NV_PRMCIO_INP0__COLOR 0x006013da
-
-#define NV_PRAMDAC_CU_START_POS 0x00680300
-# define NV_PRAMDAC_CU_START_POS_X 15:0
-# define NV_PRAMDAC_CU_START_POS_Y 31:16
-#define NV_RAMDAC_NV10_CURSYNC 0x00680404
-
-#define NV_PRAMDAC_NVPLL_COEFF 0x00680500
-#define NV_PRAMDAC_MPLL_COEFF 0x00680504
-#define NV_PRAMDAC_VPLL_COEFF 0x00680508
-# define NV30_RAMDAC_ENABLE_VCO2 (8 << 4)
-
-#define NV_PRAMDAC_PLL_COEFF_SELECT 0x0068050c
-# define NV_RAMDAC_PLL_SELECT_USE_VPLL2_TRUE (4 << 0)
-# define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_MPLL (1 << 8)
-# define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_VPLL (2 << 8)
-# define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_NVPLL (4 << 8)
-# define NV_RAMDAC_PLL_SELECT_PLL_SOURCE_VPLL2 (8 << 8)
-# define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2 (1 << 28)
-# define NV_RAMDAC_PLL_SELECT_VCLK2_RATIO_DB2 (2 << 28)
-
-#define NV_PRAMDAC_PLL_SETUP_CONTROL 0x00680510
-#define NV_RAMDAC_VPLL2 0x00680520
-#define NV_PRAMDAC_SEL_CLK 0x00680524
-#define NV_RAMDAC_DITHER_NV11 0x00680528
-#define NV_PRAMDAC_DACCLK 0x0068052c
-# define NV_PRAMDAC_DACCLK_SEL_DACCLK (1 << 0)
-
-#define NV_RAMDAC_NVPLL_B 0x00680570
-#define NV_RAMDAC_MPLL_B 0x00680574
-#define NV_RAMDAC_VPLL_B 0x00680578
-#define NV_RAMDAC_VPLL2_B 0x0068057c
-# define NV31_RAMDAC_ENABLE_VCO2 (8 << 28)
-#define NV_PRAMDAC_580 0x00680580
-# define NV_RAMDAC_580_VPLL1_ACTIVE (1 << 8)
-# define NV_RAMDAC_580_VPLL2_ACTIVE (1 << 28)
-
-#define NV_PRAMDAC_GENERAL_CONTROL 0x00680600
-# define NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON (3 << 4)
-# define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL (1 << 8)
-# define NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL (1 << 12)
-# define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM (2 << 16)
-# define NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS (1 << 20)
-# define NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG (2 << 28)
-#define NV_PRAMDAC_TEST_CONTROL 0x00680608
-# define NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED (1 << 12)
-# define NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF (1 << 16)
-# define NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI (1 << 28)
-#define NV_PRAMDAC_TESTPOINT_DATA 0x00680610
-# define NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK (8 << 28)
-#define NV_PRAMDAC_630 0x00680630
-#define NV_PRAMDAC_634 0x00680634
-
-#define NV_PRAMDAC_FP_VDISPLAY_END 0x00680800
-#define NV_PRAMDAC_FP_VTOTAL 0x00680804
-#define NV_PRAMDAC_FP_VCRTC 0x00680808
-#define NV_PRAMDAC_FP_VSYNC_START 0x0068080c
-#define NV_PRAMDAC_FP_VSYNC_END 0x00680810
-#define NV_PRAMDAC_FP_VVALID_START 0x00680814
-#define NV_PRAMDAC_FP_VVALID_END 0x00680818
-#define NV_PRAMDAC_FP_HDISPLAY_END 0x00680820
-#define NV_PRAMDAC_FP_HTOTAL 0x00680824
-#define NV_PRAMDAC_FP_HCRTC 0x00680828
-#define NV_PRAMDAC_FP_HSYNC_START 0x0068082c
-#define NV_PRAMDAC_FP_HSYNC_END 0x00680830
-#define NV_PRAMDAC_FP_HVALID_START 0x00680834
-#define NV_PRAMDAC_FP_HVALID_END 0x00680838
-
-#define NV_RAMDAC_FP_DITHER 0x0068083c
-#define NV_PRAMDAC_FP_TG_CONTROL 0x00680848
-# define NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS (1 << 0)
-# define NV_PRAMDAC_FP_TG_CONTROL_VSYNC_DISABLE (2 << 0)
-# define NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS (1 << 4)
-# define NV_PRAMDAC_FP_TG_CONTROL_HSYNC_DISABLE (2 << 4)
-# define NV_PRAMDAC_FP_TG_CONTROL_MODE_SCALE (0 << 8)
-# define NV_PRAMDAC_FP_TG_CONTROL_MODE_CENTER (1 << 8)
-# define NV_PRAMDAC_FP_TG_CONTROL_MODE_NATIVE (2 << 8)
-# define NV_PRAMDAC_FP_TG_CONTROL_READ_PROG (1 << 20)
-# define NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12 (1 << 24)
-# define NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS (1 << 28)
-# define NV_PRAMDAC_FP_TG_CONTROL_DISPEN_DISABLE (2 << 28)
-#define NV_PRAMDAC_850 0x00680850
-#define NV_PRAMDAC_85C 0x0068085c
-#define NV_PRAMDAC_FP_DEBUG_0 0x00680880
-# define NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE (1 << 0)
-# define NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE (1 << 4)
-/* This doesn't seem to be essential for tmds, but still often set */
-# define NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED (8 << 4)
-# define NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR (1 << 8)
-# define NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR (1 << 12)
-# define NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND (1 << 20)
-# define NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND (1 << 24)
-# define NV_PRAMDAC_FP_DEBUG_0_PWRDOWN_FPCLK (1 << 28)
-#define NV_PRAMDAC_FP_DEBUG_1 0x00680884
-# define NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE 11:0
-# define NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE (1 << 12)
-# define NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE 27:16
-# define NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE (1 << 28)
-#define NV_PRAMDAC_FP_DEBUG_2 0x00680888
-#define NV_PRAMDAC_FP_DEBUG_3 0x0068088C
-
-/* see NV_PRAMDAC_INDIR_TMDS in rules.xml */
-#define NV_PRAMDAC_FP_TMDS_CONTROL 0x006808b0
-# define NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE (1 << 16)
-#define NV_PRAMDAC_FP_TMDS_DATA 0x006808b4
-
-/* Some kind of switch */
-#define NV_PRAMDAC_900 0x00680900
-#define NV_PRAMDAC_A20 0x00680A20
-#define NV_PRAMDAC_A24 0x00680A24
-#define NV_PRAMDAC_A34 0x00680A34
-
-/* names fabricated from NV_USER_DAC info */
-#define NV_PRMDIO_PIXEL_MASK 0x006813c6
-# define NV_PRMDIO_PIXEL_MASK_MASK 0xff
-#define NV_PRMDIO_READ_MODE_ADDRESS 0x006813c7
-#define NV_PRMDIO_WRITE_MODE_ADDRESS 0x006813c8
-#define NV_PRMDIO_PALETTE_DATA 0x006813c9
-
-#define NV_PGRAPH_DEBUG_0 0x00400080
-#define NV_PGRAPH_DEBUG_1 0x00400084
-#define NV_PGRAPH_DEBUG_2_NV04 0x00400088
-#define NV_PGRAPH_DEBUG_2 0x00400620
-#define NV_PGRAPH_DEBUG_3 0x0040008c
-#define NV_PGRAPH_DEBUG_4 0x00400090
-#define NV_PGRAPH_INTR 0x00400100
-#define NV_PGRAPH_INTR_EN 0x00400140
-#define NV_PGRAPH_CTX_CONTROL 0x00400144
-#define NV_PGRAPH_CTX_CONTROL_NV04 0x00400170
-#define NV_PGRAPH_ABS_UCLIP_XMIN 0x0040053C
-#define NV_PGRAPH_ABS_UCLIP_YMIN 0x00400540
-#define NV_PGRAPH_ABS_UCLIP_XMAX 0x00400544
-#define NV_PGRAPH_ABS_UCLIP_YMAX 0x00400548
-#define NV_PGRAPH_BETA_AND 0x00400608
-#define NV_PGRAPH_LIMIT_VIOL_PIX 0x00400610
-#define NV_PGRAPH_BOFFSET0 0x00400640
-#define NV_PGRAPH_BOFFSET1 0x00400644
-#define NV_PGRAPH_BOFFSET2 0x00400648
-#define NV_PGRAPH_BLIMIT0 0x00400684
-#define NV_PGRAPH_BLIMIT1 0x00400688
-#define NV_PGRAPH_BLIMIT2 0x0040068c
-#define NV_PGRAPH_STATUS 0x00400700
-#define NV_PGRAPH_SURFACE 0x00400710
-#define NV_PGRAPH_STATE 0x00400714
-#define NV_PGRAPH_FIFO 0x00400720
-#define NV_PGRAPH_PATTERN_SHAPE 0x00400810
-#define NV_PGRAPH_TILE 0x00400b00
-
-#define NV_PVIDEO_INTR_EN 0x00008140
-#define NV_PVIDEO_BUFFER 0x00008700
-#define NV_PVIDEO_STOP 0x00008704
-#define NV_PVIDEO_UVPLANE_BASE(buff) (0x00008800+(buff)*4)
-#define NV_PVIDEO_UVPLANE_LIMIT(buff) (0x00008808+(buff)*4)
-#define NV_PVIDEO_UVPLANE_OFFSET_BUFF(buff) (0x00008820+(buff)*4)
-#define NV_PVIDEO_BASE(buff) (0x00008900+(buff)*4)
-#define NV_PVIDEO_LIMIT(buff) (0x00008908+(buff)*4)
-#define NV_PVIDEO_LUMINANCE(buff) (0x00008910+(buff)*4)
-#define NV_PVIDEO_CHROMINANCE(buff) (0x00008918+(buff)*4)
-#define NV_PVIDEO_OFFSET_BUFF(buff) (0x00008920+(buff)*4)
-#define NV_PVIDEO_SIZE_IN(buff) (0x00008928+(buff)*4)
-#define NV_PVIDEO_POINT_IN(buff) (0x00008930+(buff)*4)
-#define NV_PVIDEO_DS_DX(buff) (0x00008938+(buff)*4)
-#define NV_PVIDEO_DT_DY(buff) (0x00008940+(buff)*4)
-#define NV_PVIDEO_POINT_OUT(buff) (0x00008948+(buff)*4)
-#define NV_PVIDEO_SIZE_OUT(buff) (0x00008950+(buff)*4)
-#define NV_PVIDEO_FORMAT(buff) (0x00008958+(buff)*4)
-# define NV_PVIDEO_FORMAT_PLANAR (1 << 0)
-# define NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8 (1 << 16)
-# define NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY (1 << 20)
-# define NV_PVIDEO_FORMAT_MATRIX_ITURBT709 (1 << 24)
-#define NV_PVIDEO_COLOR_KEY 0x00008B00
-
-/* NV04 overlay defines from VIDIX & Haiku */
-#define NV_PVIDEO_INTR_EN_0 0x00680140
-#define NV_PVIDEO_STEP_SIZE 0x00680200
-#define NV_PVIDEO_CONTROL_Y 0x00680204
-#define NV_PVIDEO_CONTROL_X 0x00680208
-#define NV_PVIDEO_BUFF0_START_ADDRESS 0x0068020c
-#define NV_PVIDEO_BUFF0_PITCH_LENGTH 0x00680214
-#define NV_PVIDEO_BUFF0_OFFSET 0x0068021c
-#define NV_PVIDEO_BUFF1_START_ADDRESS 0x00680210
-#define NV_PVIDEO_BUFF1_PITCH_LENGTH 0x00680218
-#define NV_PVIDEO_BUFF1_OFFSET 0x00680220
-#define NV_PVIDEO_OE_STATE 0x00680224
-#define NV_PVIDEO_SU_STATE 0x00680228
-#define NV_PVIDEO_RM_STATE 0x0068022c
-#define NV_PVIDEO_WINDOW_START 0x00680230
-#define NV_PVIDEO_WINDOW_SIZE 0x00680234
-#define NV_PVIDEO_FIFO_THRES_SIZE 0x00680238
-#define NV_PVIDEO_FIFO_BURST_LENGTH 0x0068023c
-#define NV_PVIDEO_KEY 0x00680240
-#define NV_PVIDEO_OVERLAY 0x00680244
-#define NV_PVIDEO_RED_CSC_OFFSET 0x00680280
-#define NV_PVIDEO_GREEN_CSC_OFFSET 0x00680284
-#define NV_PVIDEO_BLUE_CSC_OFFSET 0x00680288
-#define NV_PVIDEO_CSC_ADJUST 0x0068028c
-
-#endif