diff --git a/packages/linux/patches/71_nouveau.diff b/packages/linux/patches/71_nouveau.diff new file mode 100644 index 0000000000..1102d90cbd --- /dev/null +++ b/packages/linux/patches/71_nouveau.diff @@ -0,0 +1,64199 @@ +diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig +index f831ea1..a2320ac 100644 +--- a/drivers/gpu/drm/Kconfig ++++ b/drivers/gpu/drm/Kconfig +@@ -154,3 +154,59 @@ config DRM_SAVAGE + help + Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister + chipset. If M is selected the module will be called savage. ++ ++config DRM_NOUVEAU ++ tristate "Nouveau (nVidia) cards" ++ depends on DRM ++ select DRM_KMS_HELPER ++ select DRM_TTM ++ select FB_CFB_FILLRECT ++ select FB_CFB_COPYAREA ++ select FB_CFB_IMAGEBLIT ++ select FB ++ select FRAMEBUFFER_CONSOLE if !EMBEDDED ++ select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT ++ help ++ Choose this option for open-source nVidia support. ++ ++config DRM_NOUVEAU_KMS ++ bool "Enable modesetting on nouveau by default" ++ depends on DRM_NOUVEAU ++ help ++ Choose this option if you want kernel modesetting enabled by default, ++ and you have a new enough userspace to support this. Running old ++ userspaces with this enabled will cause pain. ++ ++ NOTICE: if you plan on using the text based console outside of X, enable ++ FRAMEBUFFER_CONSOLE or else the console will be unusable. ++ ++config DRM_NOUVEAU_BACKLIGHT ++ bool "Support for backlight control" ++ depends on DRM_NOUVEAU ++ default y ++ help ++ Say Y here if you want to control the backlight of your display ++ (e.g. a laptop panel). ++ ++config DRM_NOUVEAU_DEBUG ++ bool "Build in Nouveau's debugfs support" ++ depends on DRM_NOUVEAU && DEBUG_FS ++ default y ++ help ++ Say Y here if you want Nouveau to output debugging information ++ via debugfs. ++ ++menu "I2C encoder or helper chips" ++ depends on DRM ++ ++config DRM_I2C_CH7006 ++ tristate "Chrontel ch7006 TV encoder" ++ default m if DRM_NOUVEAU ++ help ++ Support for Chrontel ch7006 and similar TV encoders, found ++ on some nVidia video cards. ++ ++ This driver is currently only useful if you're also using ++ the nouveau driver. ++ ++endmenu +diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile +index 3c8827a..d22e64b 100644 +--- a/drivers/gpu/drm/Makefile ++++ b/drivers/gpu/drm/Makefile +@@ -31,3 +31,5 @@ obj-$(CONFIG_DRM_I915) += i915/ + obj-$(CONFIG_DRM_SIS) += sis/ + obj-$(CONFIG_DRM_SAVAGE)+= savage/ + obj-$(CONFIG_DRM_VIA) +=via/ ++obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/ ++obj-y += i2c/ +diff --git a/drivers/gpu/drm/i2c/Makefile b/drivers/gpu/drm/i2c/Makefile +new file mode 100644 +index 0000000..6d2abaf +--- /dev/null ++++ b/drivers/gpu/drm/i2c/Makefile +@@ -0,0 +1,4 @@ ++ccflags-y := -Iinclude/drm ++ ++ch7006-y := ch7006_drv.o ch7006_mode.o ++obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o +diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c +new file mode 100644 +index 0000000..9422a74 +--- /dev/null ++++ b/drivers/gpu/drm/i2c/ch7006_drv.c +@@ -0,0 +1,531 @@ ++/* ++ * Copyright (C) 2009 Francisco Jerez. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "ch7006_priv.h" ++ ++/* DRM encoder functions */ ++ ++static void ch7006_encoder_set_config(struct drm_encoder *encoder, ++ void *params) ++{ ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ ++ priv->params = params; ++} ++ ++static void ch7006_encoder_destroy(struct drm_encoder *encoder) ++{ ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ ++ drm_property_destroy(encoder->dev, priv->scale_property); ++ ++ kfree(priv); ++ to_encoder_slave(encoder)->slave_priv = NULL; ++ ++ drm_i2c_encoder_destroy(encoder); ++} ++ ++static void ch7006_encoder_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct i2c_client *client = drm_i2c_encoder_get_client(encoder); ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ struct ch7006_state *state = &priv->state; ++ ++ ch7006_dbg(client, "\n"); ++ ++ if (mode == priv->last_dpms) ++ return; ++ priv->last_dpms = mode; ++ ++ ch7006_setup_power_state(encoder); ++ ++ ch7006_load_reg(client, state, CH7006_POWER); ++} ++ ++static void ch7006_encoder_save(struct drm_encoder *encoder) ++{ ++ struct i2c_client *client = drm_i2c_encoder_get_client(encoder); ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ ++ ch7006_dbg(client, "\n"); ++ ++ ch7006_state_save(client, &priv->saved_state); ++} ++ ++static void ch7006_encoder_restore(struct drm_encoder *encoder) ++{ ++ struct i2c_client *client = drm_i2c_encoder_get_client(encoder); ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ ++ ch7006_dbg(client, "\n"); ++ ++ ch7006_state_load(client, &priv->saved_state); ++} ++ ++static bool ch7006_encoder_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ ++ /* The ch7006 is painfully picky with the input timings so no ++ * custom modes for now... */ ++ ++ priv->mode = ch7006_lookup_mode(encoder, mode); ++ ++ return !!priv->mode; ++} ++ ++static int ch7006_encoder_mode_valid(struct drm_encoder *encoder, ++ struct drm_display_mode *mode) ++{ ++ if (ch7006_lookup_mode(encoder, mode)) ++ return MODE_OK; ++ else ++ return MODE_BAD; ++} ++ ++static void ch7006_encoder_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *drm_mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct i2c_client *client = drm_i2c_encoder_get_client(encoder); ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ struct ch7006_encoder_params *params = priv->params; ++ struct ch7006_state *state = &priv->state; ++ uint8_t *regs = state->regs; ++ struct ch7006_mode *mode = priv->mode; ++ struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm]; ++ int start_active; ++ ++ ch7006_dbg(client, "\n"); ++ ++ regs[CH7006_DISPMODE] = norm->dispmode | mode->dispmode; ++ regs[CH7006_BWIDTH] = 0; ++ regs[CH7006_INPUT_FORMAT] = bitf(CH7006_INPUT_FORMAT_FORMAT, ++ params->input_format); ++ ++ regs[CH7006_CLKMODE] = CH7006_CLKMODE_SUBC_LOCK ++ | bitf(CH7006_CLKMODE_XCM, params->xcm) ++ | bitf(CH7006_CLKMODE_PCM, params->pcm); ++ if (params->clock_mode) ++ regs[CH7006_CLKMODE] |= CH7006_CLKMODE_MASTER; ++ if (params->clock_edge) ++ regs[CH7006_CLKMODE] |= CH7006_CLKMODE_POS_EDGE; ++ ++ start_active = (drm_mode->htotal & ~0x7) - (drm_mode->hsync_start & ~0x7); ++ regs[CH7006_POV] = bitf(CH7006_POV_START_ACTIVE_8, start_active); ++ regs[CH7006_START_ACTIVE] = bitf(CH7006_START_ACTIVE_0, start_active); ++ ++ regs[CH7006_INPUT_SYNC] = 0; ++ if (params->sync_direction) ++ regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_OUTPUT; ++ if (params->sync_encoding) ++ regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_EMBEDDED; ++ if (drm_mode->flags & DRM_MODE_FLAG_PVSYNC) ++ regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_PVSYNC; ++ if (drm_mode->flags & DRM_MODE_FLAG_PHSYNC) ++ regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_PHSYNC; ++ ++ regs[CH7006_DETECT] = 0; ++ regs[CH7006_BCLKOUT] = 0; ++ ++ regs[CH7006_SUBC_INC3] = 0; ++ if (params->pout_level) ++ regs[CH7006_SUBC_INC3] |= CH7006_SUBC_INC3_POUT_3_3V; ++ ++ regs[CH7006_SUBC_INC4] = 0; ++ if (params->active_detect) ++ regs[CH7006_SUBC_INC4] |= CH7006_SUBC_INC4_DS_INPUT; ++ ++ regs[CH7006_PLL_CONTROL] = priv->saved_state.regs[CH7006_PLL_CONTROL]; ++ ++ ch7006_setup_levels(encoder); ++ ch7006_setup_subcarrier(encoder); ++ ch7006_setup_pll(encoder); ++ ch7006_setup_power_state(encoder); ++ ch7006_setup_properties(encoder); ++ ++ ch7006_state_load(client, state); ++} ++ ++static enum drm_connector_status ch7006_encoder_detect(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ struct i2c_client *client = drm_i2c_encoder_get_client(encoder); ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ struct ch7006_state *state = &priv->state; ++ int det; ++ ++ ch7006_dbg(client, "\n"); ++ ++ ch7006_save_reg(client, state, CH7006_DETECT); ++ ch7006_save_reg(client, state, CH7006_POWER); ++ ch7006_save_reg(client, state, CH7006_CLKMODE); ++ ++ ch7006_write(client, CH7006_POWER, CH7006_POWER_RESET | ++ bitfs(CH7006_POWER_LEVEL, NORMAL)); ++ ch7006_write(client, CH7006_CLKMODE, CH7006_CLKMODE_MASTER); ++ ++ ch7006_write(client, CH7006_DETECT, CH7006_DETECT_SENSE); ++ ++ ch7006_write(client, CH7006_DETECT, 0); ++ ++ det = ch7006_read(client, CH7006_DETECT); ++ ++ ch7006_load_reg(client, state, CH7006_CLKMODE); ++ ch7006_load_reg(client, state, CH7006_POWER); ++ ch7006_load_reg(client, state, CH7006_DETECT); ++ ++ if ((det & (CH7006_DETECT_SVIDEO_Y_TEST| ++ CH7006_DETECT_SVIDEO_C_TEST| ++ CH7006_DETECT_CVBS_TEST)) == 0) ++ priv->subconnector = DRM_MODE_SUBCONNECTOR_SCART; ++ else if ((det & (CH7006_DETECT_SVIDEO_Y_TEST| ++ CH7006_DETECT_SVIDEO_C_TEST)) == 0) ++ priv->subconnector = DRM_MODE_SUBCONNECTOR_SVIDEO; ++ else if ((det & CH7006_DETECT_CVBS_TEST) == 0) ++ priv->subconnector = DRM_MODE_SUBCONNECTOR_Composite; ++ else ++ priv->subconnector = DRM_MODE_SUBCONNECTOR_Unknown; ++ ++ drm_connector_property_set_value(connector, ++ encoder->dev->mode_config.tv_subconnector_property, ++ priv->subconnector); ++ ++ return priv->subconnector ? connector_status_connected : ++ connector_status_disconnected; ++} ++ ++static int ch7006_encoder_get_modes(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ struct ch7006_mode *mode; ++ int n = 0; ++ ++ for (mode = ch7006_modes; mode->mode.clock; mode++) { ++ if (~mode->valid_scales & 1<scale || ++ ~mode->valid_norms & 1<norm) ++ continue; ++ ++ drm_mode_probed_add(connector, ++ drm_mode_duplicate(encoder->dev, &mode->mode)); ++ ++ n++; ++ } ++ ++ return n; ++} ++ ++static int ch7006_encoder_create_resources(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ struct drm_device *dev = encoder->dev; ++ struct drm_mode_config *conf = &dev->mode_config; ++ ++ drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names); ++ ++ priv->scale_property = drm_property_create(dev, DRM_MODE_PROP_RANGE, ++ "scale", 2); ++ priv->scale_property->values[0] = 0; ++ priv->scale_property->values[1] = 2; ++ ++ drm_connector_attach_property(connector, conf->tv_select_subconnector_property, ++ priv->select_subconnector); ++ drm_connector_attach_property(connector, conf->tv_subconnector_property, ++ priv->subconnector); ++ drm_connector_attach_property(connector, conf->tv_left_margin_property, ++ priv->hmargin); ++ drm_connector_attach_property(connector, conf->tv_bottom_margin_property, ++ priv->vmargin); ++ drm_connector_attach_property(connector, conf->tv_mode_property, ++ priv->norm); ++ drm_connector_attach_property(connector, conf->tv_brightness_property, ++ priv->brightness); ++ drm_connector_attach_property(connector, conf->tv_contrast_property, ++ priv->contrast); ++ drm_connector_attach_property(connector, conf->tv_flicker_reduction_property, ++ priv->flicker); ++ drm_connector_attach_property(connector, priv->scale_property, ++ priv->scale); ++ ++ return 0; ++} ++ ++static int ch7006_encoder_set_property(struct drm_encoder *encoder, ++ struct drm_connector *connector, ++ struct drm_property *property, ++ uint64_t val) ++{ ++ struct i2c_client *client = drm_i2c_encoder_get_client(encoder); ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ struct ch7006_state *state = &priv->state; ++ struct drm_mode_config *conf = &encoder->dev->mode_config; ++ struct drm_crtc *crtc = encoder->crtc; ++ bool modes_changed = false; ++ ++ ch7006_dbg(client, "\n"); ++ ++ if (property == conf->tv_select_subconnector_property) { ++ priv->select_subconnector = val; ++ ++ ch7006_setup_power_state(encoder); ++ ++ ch7006_load_reg(client, state, CH7006_POWER); ++ ++ } else if (property == conf->tv_left_margin_property) { ++ priv->hmargin = val; ++ ++ ch7006_setup_properties(encoder); ++ ++ ch7006_load_reg(client, state, CH7006_POV); ++ ch7006_load_reg(client, state, CH7006_HPOS); ++ ++ } else if (property == conf->tv_bottom_margin_property) { ++ priv->vmargin = val; ++ ++ ch7006_setup_properties(encoder); ++ ++ ch7006_load_reg(client, state, CH7006_POV); ++ ch7006_load_reg(client, state, CH7006_VPOS); ++ ++ } else if (property == conf->tv_mode_property) { ++ if (connector->dpms != DRM_MODE_DPMS_OFF) ++ return -EINVAL; ++ ++ priv->norm = val; ++ ++ modes_changed = true; ++ ++ } else if (property == conf->tv_brightness_property) { ++ priv->brightness = val; ++ ++ ch7006_setup_levels(encoder); ++ ++ ch7006_load_reg(client, state, CH7006_BLACK_LEVEL); ++ ++ } else if (property == conf->tv_contrast_property) { ++ priv->contrast = val; ++ ++ ch7006_setup_properties(encoder); ++ ++ ch7006_load_reg(client, state, CH7006_CONTRAST); ++ ++ } else if (property == conf->tv_flicker_reduction_property) { ++ priv->flicker = val; ++ ++ ch7006_setup_properties(encoder); ++ ++ ch7006_load_reg(client, state, CH7006_FFILTER); ++ ++ } else if (property == priv->scale_property) { ++ if (connector->dpms != DRM_MODE_DPMS_OFF) ++ return -EINVAL; ++ ++ priv->scale = val; ++ ++ modes_changed = true; ++ ++ } else { ++ return -EINVAL; ++ } ++ ++ if (modes_changed) { ++ drm_helper_probe_single_connector_modes(connector, 0, 0); ++ ++ /* Disable the crtc to ensure a full modeset is ++ * performed whenever it's turned on again. */ ++ if (crtc) { ++ struct drm_mode_set modeset = { ++ .crtc = crtc, ++ }; ++ ++ crtc->funcs->set_config(&modeset); ++ } ++ } ++ ++ return 0; ++} ++ ++static struct drm_encoder_slave_funcs ch7006_encoder_funcs = { ++ .set_config = ch7006_encoder_set_config, ++ .destroy = ch7006_encoder_destroy, ++ .dpms = ch7006_encoder_dpms, ++ .save = ch7006_encoder_save, ++ .restore = ch7006_encoder_restore, ++ .mode_fixup = ch7006_encoder_mode_fixup, ++ .mode_valid = ch7006_encoder_mode_valid, ++ .mode_set = ch7006_encoder_mode_set, ++ .detect = ch7006_encoder_detect, ++ .get_modes = ch7006_encoder_get_modes, ++ .create_resources = ch7006_encoder_create_resources, ++ .set_property = ch7006_encoder_set_property, ++}; ++ ++ ++/* I2C driver functions */ ++ ++static int ch7006_probe(struct i2c_client *client, const struct i2c_device_id *id) ++{ ++ uint8_t addr = CH7006_VERSION_ID; ++ uint8_t val; ++ int ret; ++ ++ ch7006_dbg(client, "\n"); ++ ++ ret = i2c_master_send(client, &addr, sizeof(addr)); ++ if (ret < 0) ++ goto fail; ++ ++ ret = i2c_master_recv(client, &val, sizeof(val)); ++ if (ret < 0) ++ goto fail; ++ ++ ch7006_info(client, "Detected version ID: %x\n", val); ++ ++ return 0; ++ ++fail: ++ ch7006_err(client, "Error %d reading version ID\n", ret); ++ ++ return -ENODEV; ++} ++ ++static int ch7006_remove(struct i2c_client *client) ++{ ++ ch7006_dbg(client, "\n"); ++ ++ return 0; ++} ++ ++static int ch7006_encoder_init(struct i2c_client *client, ++ struct drm_device *dev, ++ struct drm_encoder_slave *encoder) ++{ ++ struct ch7006_priv *priv; ++ int i; ++ ++ ch7006_dbg(client, "\n"); ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ encoder->slave_priv = priv; ++ encoder->slave_funcs = &ch7006_encoder_funcs; ++ ++ priv->norm = TV_NORM_PAL; ++ priv->select_subconnector = DRM_MODE_SUBCONNECTOR_Automatic; ++ priv->subconnector = DRM_MODE_SUBCONNECTOR_Unknown; ++ priv->scale = 1; ++ priv->contrast = 50; ++ priv->brightness = 50; ++ priv->flicker = 50; ++ priv->hmargin = 50; ++ priv->vmargin = 50; ++ priv->last_dpms = -1; ++ ++ if (ch7006_tv_norm) { ++ for (i = 0; i < NUM_TV_NORMS; i++) { ++ if (!strcmp(ch7006_tv_norm_names[i], ch7006_tv_norm)) { ++ priv->norm = i; ++ break; ++ } ++ } ++ ++ if (i == NUM_TV_NORMS) ++ ch7006_err(client, "Invalid TV norm setting \"%s\".\n", ++ ch7006_tv_norm); ++ } ++ ++ if (ch7006_scale >= 0 && ch7006_scale <= 2) ++ priv->scale = ch7006_scale; ++ else ++ ch7006_err(client, "Invalid scale setting \"%d\".\n", ++ ch7006_scale); ++ ++ return 0; ++} ++ ++static struct i2c_device_id ch7006_ids[] = { ++ { "ch7006", 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, ch7006_ids); ++ ++static struct drm_i2c_encoder_driver ch7006_driver = { ++ .i2c_driver = { ++ .probe = ch7006_probe, ++ .remove = ch7006_remove, ++ ++ .driver = { ++ .name = "ch7006", ++ }, ++ ++ .id_table = ch7006_ids, ++ }, ++ ++ .encoder_init = ch7006_encoder_init, ++}; ++ ++ ++/* Module initialization */ ++ ++static int __init ch7006_init(void) ++{ ++ return drm_i2c_encoder_register(THIS_MODULE, &ch7006_driver); ++} ++ ++static void __exit ch7006_exit(void) ++{ ++ drm_i2c_encoder_unregister(&ch7006_driver); ++} ++ ++int ch7006_debug; ++module_param_named(debug, ch7006_debug, int, 0600); ++MODULE_PARM_DESC(debug, "Enable debug output."); ++ ++char *ch7006_tv_norm; ++module_param_named(tv_norm, ch7006_tv_norm, charp, 0600); ++MODULE_PARM_DESC(tv_norm, "Default TV norm.\n" ++ "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, PAL-60, NTSC-M, NTSC-J.\n" ++ "\t\tDefault: PAL"); ++ ++int ch7006_scale = 1; ++module_param_named(scale, ch7006_scale, int, 0600); ++MODULE_PARM_DESC(scale, "Default scale.\n" ++ "\t\tSupported: 0 -> Select video modes with a higher blanking ratio.\n" ++ "\t\t\t1 -> Select default video modes.\n" ++ "\t\t\t2 -> Select video modes with a lower blanking ratio."); ++ ++MODULE_AUTHOR("Francisco Jerez "); ++MODULE_DESCRIPTION("Chrontel ch7006 TV encoder driver"); ++MODULE_LICENSE("GPL and additional rights"); ++ ++module_init(ch7006_init); ++module_exit(ch7006_exit); +diff --git a/drivers/gpu/drm/i2c/ch7006_mode.c b/drivers/gpu/drm/i2c/ch7006_mode.c +new file mode 100644 +index 0000000..87f5445 +--- /dev/null ++++ b/drivers/gpu/drm/i2c/ch7006_mode.c +@@ -0,0 +1,473 @@ ++/* ++ * Copyright (C) 2009 Francisco Jerez. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "ch7006_priv.h" ++ ++char *ch7006_tv_norm_names[] = { ++ [TV_NORM_PAL] = "PAL", ++ [TV_NORM_PAL_M] = "PAL-M", ++ [TV_NORM_PAL_N] = "PAL-N", ++ [TV_NORM_PAL_NC] = "PAL-Nc", ++ [TV_NORM_PAL_60] = "PAL-60", ++ [TV_NORM_NTSC_M] = "NTSC-M", ++ [TV_NORM_NTSC_J] = "NTSC-J", ++}; ++ ++#define NTSC_LIKE_TIMINGS .vrefresh = 60 * fixed1/1.001, \ ++ .vdisplay = 480, \ ++ .vtotal = 525, \ ++ .hvirtual = 660 ++ ++#define PAL_LIKE_TIMINGS .vrefresh = 50 * fixed1, \ ++ .vdisplay = 576, \ ++ .vtotal = 625, \ ++ .hvirtual = 810 ++ ++struct ch7006_tv_norm_info ch7006_tv_norms[] = { ++ [TV_NORM_NTSC_M] = { ++ NTSC_LIKE_TIMINGS, ++ .black_level = 0.339 * fixed1, ++ .subc_freq = 3579545 * fixed1, ++ .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, NTSC), ++ .voffset = 0, ++ }, ++ [TV_NORM_NTSC_J] = { ++ NTSC_LIKE_TIMINGS, ++ .black_level = 0.286 * fixed1, ++ .subc_freq = 3579545 * fixed1, ++ .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, NTSC_J), ++ .voffset = 0, ++ }, ++ [TV_NORM_PAL] = { ++ PAL_LIKE_TIMINGS, ++ .black_level = 0.3 * fixed1, ++ .subc_freq = 4433618.75 * fixed1, ++ .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL), ++ .voffset = 0, ++ }, ++ [TV_NORM_PAL_M] = { ++ NTSC_LIKE_TIMINGS, ++ .black_level = 0.339 * fixed1, ++ .subc_freq = 3575611.433 * fixed1, ++ .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL_M), ++ .voffset = 16, ++ }, ++ ++ /* The following modes seem to work right but they're ++ * undocumented */ ++ ++ [TV_NORM_PAL_N] = { ++ PAL_LIKE_TIMINGS, ++ .black_level = 0.339 * fixed1, ++ .subc_freq = 4433618.75 * fixed1, ++ .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL), ++ .voffset = 0, ++ }, ++ [TV_NORM_PAL_NC] = { ++ PAL_LIKE_TIMINGS, ++ .black_level = 0.3 * fixed1, ++ .subc_freq = 3582056.25 * fixed1, ++ .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL), ++ .voffset = 0, ++ }, ++ [TV_NORM_PAL_60] = { ++ NTSC_LIKE_TIMINGS, ++ .black_level = 0.3 * fixed1, ++ .subc_freq = 4433618.75 * fixed1, ++ .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL_M), ++ .voffset = 16, ++ }, ++}; ++ ++#define __MODE(f, hd, vd, ht, vt, hsynp, vsynp, \ ++ subc, scale, scale_mask, norm_mask, e_hd, e_vd) { \ ++ .mode = { \ ++ .name = #hd "x" #vd, \ ++ .status = 0, \ ++ .type = DRM_MODE_TYPE_DRIVER, \ ++ .clock = f, \ ++ .hdisplay = hd, \ ++ .hsync_start = e_hd + 16, \ ++ .hsync_end = e_hd + 80, \ ++ .htotal = ht, \ ++ .hskew = 0, \ ++ .vdisplay = vd, \ ++ .vsync_start = vd + 10, \ ++ .vsync_end = vd + 26, \ ++ .vtotal = vt, \ ++ .vscan = 0, \ ++ .flags = DRM_MODE_FLAG_##hsynp##HSYNC | \ ++ DRM_MODE_FLAG_##vsynp##VSYNC, \ ++ .vrefresh = 0, \ ++ }, \ ++ .enc_hdisp = e_hd, \ ++ .enc_vdisp = e_vd, \ ++ .subc_coeff = subc * fixed1, \ ++ .dispmode = bitfs(CH7006_DISPMODE_SCALING_RATIO, scale) | \ ++ bitfs(CH7006_DISPMODE_INPUT_RES, e_hd##x##e_vd), \ ++ .valid_scales = scale_mask, \ ++ .valid_norms = norm_mask \ ++ } ++ ++#define MODE(f, hd, vd, ht, vt, hsynp, vsynp, \ ++ subc, scale, scale_mask, norm_mask) \ ++ __MODE(f, hd, vd, ht, vt, hsynp, vsynp, subc, scale, \ ++ scale_mask, norm_mask, hd, vd) ++ ++#define NTSC_LIKE (1 << TV_NORM_NTSC_M | 1 << TV_NORM_NTSC_J | \ ++ 1 << TV_NORM_PAL_M | 1 << TV_NORM_PAL_60) ++ ++#define PAL_LIKE (1 << TV_NORM_PAL | 1 << TV_NORM_PAL_N | 1 << TV_NORM_PAL_NC) ++ ++struct ch7006_mode ch7006_modes[] = { ++ MODE(21000, 512, 384, 840, 500, N, N, 181.797557582, 5_4, 0x6, PAL_LIKE), ++ MODE(26250, 512, 384, 840, 625, N, N, 145.438046066, 1_1, 0x1, PAL_LIKE), ++ MODE(20140, 512, 384, 800, 420, N, N, 213.257083791, 5_4, 0x4, NTSC_LIKE), ++ MODE(24671, 512, 384, 784, 525, N, N, 174.0874153, 1_1, 0x3, NTSC_LIKE), ++ MODE(28125, 720, 400, 1125, 500, N, N, 135.742176298, 5_4, 0x6, PAL_LIKE), ++ MODE(34875, 720, 400, 1116, 625, N, N, 109.469496898, 1_1, 0x1, PAL_LIKE), ++ MODE(23790, 720, 400, 945, 420, N, N, 160.475642016, 5_4, 0x4, NTSC_LIKE), ++ MODE(29455, 720, 400, 936, 525, N, N, 129.614941843, 1_1, 0x3, NTSC_LIKE), ++ MODE(25000, 640, 400, 1000, 500, N, N, 152.709948279, 5_4, 0x6, PAL_LIKE), ++ MODE(31500, 640, 400, 1008, 625, N, N, 121.198371646, 1_1, 0x1, PAL_LIKE), ++ MODE(21147, 640, 400, 840, 420, N, N, 180.535097338, 5_4, 0x4, NTSC_LIKE), ++ MODE(26434, 640, 400, 840, 525, N, N, 144.42807787, 1_1, 0x2, NTSC_LIKE), ++ MODE(30210, 640, 400, 840, 600, N, N, 126.374568276, 7_8, 0x1, NTSC_LIKE), ++ MODE(21000, 640, 480, 840, 500, N, N, 181.797557582, 5_4, 0x4, PAL_LIKE), ++ MODE(26250, 640, 480, 840, 625, N, N, 145.438046066, 1_1, 0x2, PAL_LIKE), ++ MODE(31500, 640, 480, 840, 750, N, N, 121.198371646, 5_6, 0x1, PAL_LIKE), ++ MODE(24671, 640, 480, 784, 525, N, N, 174.0874153, 1_1, 0x4, NTSC_LIKE), ++ MODE(28196, 640, 480, 784, 600, N, N, 152.326488422, 7_8, 0x2, NTSC_LIKE), ++ MODE(30210, 640, 480, 800, 630, N, N, 142.171389101, 5_6, 0x1, NTSC_LIKE), ++ __MODE(29500, 720, 576, 944, 625, P, P, 145.592111636, 1_1, 0x7, PAL_LIKE, 800, 600), ++ MODE(36000, 800, 600, 960, 750, P, P, 119.304647022, 5_6, 0x6, PAL_LIKE), ++ MODE(39000, 800, 600, 936, 836, P, P, 110.127366499, 3_4, 0x1, PAL_LIKE), ++ MODE(39273, 800, 600, 1040, 630, P, P, 145.816809399, 5_6, 0x4, NTSC_LIKE), ++ MODE(43636, 800, 600, 1040, 700, P, P, 131.235128487, 3_4, 0x2, NTSC_LIKE), ++ MODE(47832, 800, 600, 1064, 750, P, P, 119.723275165, 7_10, 0x1, NTSC_LIKE), ++ {} ++}; ++ ++struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder, ++ struct drm_display_mode *drm_mode) ++{ ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ struct ch7006_mode *mode; ++ ++ for (mode = ch7006_modes; mode->mode.clock; mode++) { ++ ++ if (~mode->valid_norms & 1<norm) ++ continue; ++ ++ if (mode->mode.hdisplay != drm_mode->hdisplay || ++ mode->mode.vdisplay != drm_mode->vdisplay || ++ mode->mode.vtotal != drm_mode->vtotal || ++ mode->mode.htotal != drm_mode->htotal || ++ mode->mode.clock != drm_mode->clock) ++ continue; ++ ++ return mode; ++ } ++ ++ return NULL; ++} ++ ++/* Some common HW state calculation code */ ++ ++void ch7006_setup_levels(struct drm_encoder *encoder) ++{ ++ struct i2c_client *client = drm_i2c_encoder_get_client(encoder); ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ uint8_t *regs = priv->state.regs; ++ struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm]; ++ int gain; ++ int black_level; ++ ++ /* Set DAC_GAIN if the voltage drop between white and black is ++ * high enough. */ ++ if (norm->black_level < 339*fixed1/1000) { ++ gain = 76; ++ ++ regs[CH7006_INPUT_FORMAT] |= CH7006_INPUT_FORMAT_DAC_GAIN; ++ } else { ++ gain = 71; ++ ++ regs[CH7006_INPUT_FORMAT] &= ~CH7006_INPUT_FORMAT_DAC_GAIN; ++ } ++ ++ black_level = round_fixed(norm->black_level*26625)/gain; ++ ++ /* Correct it with the specified brightness. */ ++ black_level = interpolate(90, black_level, 208, priv->brightness); ++ ++ regs[CH7006_BLACK_LEVEL] = bitf(CH7006_BLACK_LEVEL_0, black_level); ++ ++ ch7006_dbg(client, "black level: %d\n", black_level); ++} ++ ++void ch7006_setup_subcarrier(struct drm_encoder *encoder) ++{ ++ struct i2c_client *client = drm_i2c_encoder_get_client(encoder); ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ struct ch7006_state *state = &priv->state; ++ struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm]; ++ struct ch7006_mode *mode = priv->mode; ++ uint32_t subc_inc; ++ ++ subc_inc = round_fixed((mode->subc_coeff >> 8) ++ * (norm->subc_freq >> 24)); ++ ++ setbitf(state, CH7006_SUBC_INC0, 28, subc_inc); ++ setbitf(state, CH7006_SUBC_INC1, 24, subc_inc); ++ setbitf(state, CH7006_SUBC_INC2, 20, subc_inc); ++ setbitf(state, CH7006_SUBC_INC3, 16, subc_inc); ++ setbitf(state, CH7006_SUBC_INC4, 12, subc_inc); ++ setbitf(state, CH7006_SUBC_INC5, 8, subc_inc); ++ setbitf(state, CH7006_SUBC_INC6, 4, subc_inc); ++ setbitf(state, CH7006_SUBC_INC7, 0, subc_inc); ++ ++ ch7006_dbg(client, "subcarrier inc: %u\n", subc_inc); ++} ++ ++void ch7006_setup_pll(struct drm_encoder *encoder) ++{ ++ struct i2c_client *client = drm_i2c_encoder_get_client(encoder); ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ uint8_t *regs = priv->state.regs; ++ struct ch7006_mode *mode = priv->mode; ++ int n, best_n = 0; ++ int m, best_m = 0; ++ int freq, best_freq = 0; ++ ++ for (n = 0; n < CH7006_MAXN; n++) { ++ for (m = 0; m < CH7006_MAXM; m++) { ++ freq = CH7006_FREQ0*(n+2)/(m+2); ++ ++ if (abs(freq - mode->mode.clock) < ++ abs(best_freq - mode->mode.clock)) { ++ best_freq = freq; ++ best_n = n; ++ best_m = m; ++ } ++ } ++ } ++ ++ regs[CH7006_PLLOV] = bitf(CH7006_PLLOV_N_8, best_n) | ++ bitf(CH7006_PLLOV_M_8, best_m); ++ ++ regs[CH7006_PLLM] = bitf(CH7006_PLLM_0, best_m); ++ regs[CH7006_PLLN] = bitf(CH7006_PLLN_0, best_n); ++ ++ if (best_n < 108) ++ regs[CH7006_PLL_CONTROL] |= CH7006_PLL_CONTROL_CAPACITOR; ++ else ++ regs[CH7006_PLL_CONTROL] &= ~CH7006_PLL_CONTROL_CAPACITOR; ++ ++ ch7006_dbg(client, "n=%d m=%d f=%d c=%d\n", ++ best_n, best_m, best_freq, best_n < 108); ++} ++ ++void ch7006_setup_power_state(struct drm_encoder *encoder) ++{ ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ uint8_t *power = &priv->state.regs[CH7006_POWER]; ++ int subconnector; ++ ++ subconnector = priv->select_subconnector ? priv->select_subconnector : ++ priv->subconnector; ++ ++ *power = CH7006_POWER_RESET; ++ ++ if (priv->last_dpms == DRM_MODE_DPMS_ON) { ++ switch (subconnector) { ++ case DRM_MODE_SUBCONNECTOR_SVIDEO: ++ *power |= bitfs(CH7006_POWER_LEVEL, CVBS_OFF); ++ break; ++ case DRM_MODE_SUBCONNECTOR_Composite: ++ *power |= bitfs(CH7006_POWER_LEVEL, SVIDEO_OFF); ++ break; ++ case DRM_MODE_SUBCONNECTOR_SCART: ++ *power |= bitfs(CH7006_POWER_LEVEL, NORMAL) | ++ CH7006_POWER_SCART; ++ break; ++ } ++ ++ } else { ++ *power |= bitfs(CH7006_POWER_LEVEL, FULL_POWER_OFF); ++ } ++} ++ ++void ch7006_setup_properties(struct drm_encoder *encoder) ++{ ++ struct i2c_client *client = drm_i2c_encoder_get_client(encoder); ++ struct ch7006_priv *priv = to_ch7006_priv(encoder); ++ struct ch7006_state *state = &priv->state; ++ struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm]; ++ struct ch7006_mode *ch_mode = priv->mode; ++ struct drm_display_mode *mode = &ch_mode->mode; ++ uint8_t *regs = state->regs; ++ int flicker, contrast, hpos, vpos; ++ uint64_t scale, aspect; ++ ++ flicker = interpolate(0, 2, 3, priv->flicker); ++ regs[CH7006_FFILTER] = bitf(CH7006_FFILTER_TEXT, flicker) | ++ bitf(CH7006_FFILTER_LUMA, flicker) | ++ bitf(CH7006_FFILTER_CHROMA, 1); ++ ++ contrast = interpolate(0, 5, 7, priv->contrast); ++ regs[CH7006_CONTRAST] = bitf(CH7006_CONTRAST_0, contrast); ++ ++ scale = norm->vtotal*fixed1; ++ do_div(scale, mode->vtotal); ++ ++ aspect = ch_mode->enc_hdisp*fixed1; ++ do_div(aspect, ch_mode->enc_vdisp); ++ ++ hpos = round_fixed((norm->hvirtual * aspect - mode->hdisplay * scale) ++ * priv->hmargin * mode->vtotal) / norm->vtotal / 100 / 4; ++ ++ setbitf(state, CH7006_POV, HPOS_8, hpos); ++ setbitf(state, CH7006_HPOS, 0, hpos); ++ ++ vpos = max(0, norm->vdisplay - round_fixed(mode->vdisplay*scale) ++ + norm->voffset) * priv->vmargin / 100 / 2; ++ ++ setbitf(state, CH7006_POV, VPOS_8, vpos); ++ setbitf(state, CH7006_VPOS, 0, vpos); ++ ++ ch7006_dbg(client, "hpos: %d, vpos: %d\n", hpos, vpos); ++} ++ ++/* HW access functions */ ++ ++void ch7006_write(struct i2c_client *client, uint8_t addr, uint8_t val) ++{ ++ uint8_t buf[] = {addr, val}; ++ int ret; ++ ++ ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); ++ if (ret < 0) ++ ch7006_err(client, "Error %d writing to subaddress 0x%x\n", ++ ret, addr); ++} ++ ++uint8_t ch7006_read(struct i2c_client *client, uint8_t addr) ++{ ++ uint8_t val; ++ int ret; ++ ++ ret = i2c_master_send(client, &addr, sizeof(addr)); ++ if (ret < 0) ++ goto fail; ++ ++ ret = i2c_master_recv(client, &val, sizeof(val)); ++ if (ret < 0) ++ goto fail; ++ ++ return val; ++ ++fail: ++ ch7006_err(client, "Error %d reading from subaddress 0x%x\n", ++ ret, addr); ++ return 0; ++} ++ ++void ch7006_state_load(struct i2c_client *client, ++ struct ch7006_state *state) ++{ ++ ch7006_load_reg(client, state, CH7006_POWER); ++ ++ ch7006_load_reg(client, state, CH7006_DISPMODE); ++ ch7006_load_reg(client, state, CH7006_FFILTER); ++ ch7006_load_reg(client, state, CH7006_BWIDTH); ++ ch7006_load_reg(client, state, CH7006_INPUT_FORMAT); ++ ch7006_load_reg(client, state, CH7006_CLKMODE); ++ ch7006_load_reg(client, state, CH7006_START_ACTIVE); ++ ch7006_load_reg(client, state, CH7006_POV); ++ ch7006_load_reg(client, state, CH7006_BLACK_LEVEL); ++ ch7006_load_reg(client, state, CH7006_HPOS); ++ ch7006_load_reg(client, state, CH7006_VPOS); ++ ch7006_load_reg(client, state, CH7006_INPUT_SYNC); ++ ch7006_load_reg(client, state, CH7006_DETECT); ++ ch7006_load_reg(client, state, CH7006_CONTRAST); ++ ch7006_load_reg(client, state, CH7006_PLLOV); ++ ch7006_load_reg(client, state, CH7006_PLLM); ++ ch7006_load_reg(client, state, CH7006_PLLN); ++ ch7006_load_reg(client, state, CH7006_BCLKOUT); ++ ch7006_load_reg(client, state, CH7006_SUBC_INC0); ++ ch7006_load_reg(client, state, CH7006_SUBC_INC1); ++ ch7006_load_reg(client, state, CH7006_SUBC_INC2); ++ ch7006_load_reg(client, state, CH7006_SUBC_INC3); ++ ch7006_load_reg(client, state, CH7006_SUBC_INC4); ++ ch7006_load_reg(client, state, CH7006_SUBC_INC5); ++ ch7006_load_reg(client, state, CH7006_SUBC_INC6); ++ ch7006_load_reg(client, state, CH7006_SUBC_INC7); ++ ch7006_load_reg(client, state, CH7006_PLL_CONTROL); ++ ch7006_load_reg(client, state, CH7006_CALC_SUBC_INC0); ++ ++ /* I don't know what this is for, but otherwise I get no ++ * signal. ++ */ ++ ch7006_write(client, 0x3d, 0x0); ++} ++ ++void ch7006_state_save(struct i2c_client *client, ++ struct ch7006_state *state) ++{ ++ ch7006_save_reg(client, state, CH7006_POWER); ++ ++ ch7006_save_reg(client, state, CH7006_DISPMODE); ++ ch7006_save_reg(client, state, CH7006_FFILTER); ++ ch7006_save_reg(client, state, CH7006_BWIDTH); ++ ch7006_save_reg(client, state, CH7006_INPUT_FORMAT); ++ ch7006_save_reg(client, state, CH7006_CLKMODE); ++ ch7006_save_reg(client, state, CH7006_START_ACTIVE); ++ ch7006_save_reg(client, state, CH7006_POV); ++ ch7006_save_reg(client, state, CH7006_BLACK_LEVEL); ++ ch7006_save_reg(client, state, CH7006_HPOS); ++ ch7006_save_reg(client, state, CH7006_VPOS); ++ ch7006_save_reg(client, state, CH7006_INPUT_SYNC); ++ ch7006_save_reg(client, state, CH7006_DETECT); ++ ch7006_save_reg(client, state, CH7006_CONTRAST); ++ ch7006_save_reg(client, state, CH7006_PLLOV); ++ ch7006_save_reg(client, state, CH7006_PLLM); ++ ch7006_save_reg(client, state, CH7006_PLLN); ++ ch7006_save_reg(client, state, CH7006_BCLKOUT); ++ ch7006_save_reg(client, state, CH7006_SUBC_INC0); ++ ch7006_save_reg(client, state, CH7006_SUBC_INC1); ++ ch7006_save_reg(client, state, CH7006_SUBC_INC2); ++ ch7006_save_reg(client, state, CH7006_SUBC_INC3); ++ ch7006_save_reg(client, state, CH7006_SUBC_INC4); ++ ch7006_save_reg(client, state, CH7006_SUBC_INC5); ++ ch7006_save_reg(client, state, CH7006_SUBC_INC6); ++ ch7006_save_reg(client, state, CH7006_SUBC_INC7); ++ ch7006_save_reg(client, state, CH7006_PLL_CONTROL); ++ ch7006_save_reg(client, state, CH7006_CALC_SUBC_INC0); ++ ++ state->regs[CH7006_FFILTER] = (state->regs[CH7006_FFILTER] & 0xf0) | ++ (state->regs[CH7006_FFILTER] & 0x0c) >> 2 | ++ (state->regs[CH7006_FFILTER] & 0x03) << 2; ++} +diff --git a/drivers/gpu/drm/i2c/ch7006_priv.h b/drivers/gpu/drm/i2c/ch7006_priv.h +new file mode 100644 +index 0000000..b06d3d9 +--- /dev/null ++++ b/drivers/gpu/drm/i2c/ch7006_priv.h +@@ -0,0 +1,344 @@ ++/* ++ * Copyright (C) 2009 Francisco Jerez. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 __DRM_I2C_CH7006_PRIV_H__ ++#define __DRM_I2C_CH7006_PRIV_H__ ++ ++#include "drmP.h" ++#include "drm_crtc_helper.h" ++#include "drm_encoder_slave.h" ++#include "i2c/ch7006.h" ++ ++typedef int64_t fixed; ++#define fixed1 (1LL << 32) ++ ++enum ch7006_tv_norm { ++ TV_NORM_PAL, ++ TV_NORM_PAL_M, ++ TV_NORM_PAL_N, ++ TV_NORM_PAL_NC, ++ TV_NORM_PAL_60, ++ TV_NORM_NTSC_M, ++ TV_NORM_NTSC_J, ++ NUM_TV_NORMS ++}; ++ ++struct ch7006_tv_norm_info { ++ fixed vrefresh; ++ int vdisplay; ++ int vtotal; ++ int hvirtual; ++ ++ fixed subc_freq; ++ fixed black_level; ++ ++ uint32_t dispmode; ++ int voffset; ++}; ++ ++struct ch7006_mode { ++ struct drm_display_mode mode; ++ ++ int enc_hdisp; ++ int enc_vdisp; ++ ++ fixed subc_coeff; ++ uint32_t dispmode; ++ ++ uint32_t valid_scales; ++ uint32_t valid_norms; ++}; ++ ++struct ch7006_state { ++ uint8_t regs[0x26]; ++}; ++ ++struct ch7006_priv { ++ struct ch7006_encoder_params *params; ++ struct ch7006_mode *mode; ++ ++ struct ch7006_state state; ++ struct ch7006_state saved_state; ++ ++ struct drm_property *scale_property; ++ ++ int select_subconnector; ++ int subconnector; ++ int hmargin; ++ int vmargin; ++ enum ch7006_tv_norm norm; ++ int brightness; ++ int contrast; ++ int flicker; ++ int scale; ++ ++ int last_dpms; ++}; ++ ++#define to_ch7006_priv(x) \ ++ ((struct ch7006_priv *)to_encoder_slave(x)->slave_priv) ++ ++extern int ch7006_debug; ++extern char *ch7006_tv_norm; ++extern int ch7006_scale; ++ ++extern char *ch7006_tv_norm_names[]; ++extern struct ch7006_tv_norm_info ch7006_tv_norms[]; ++extern struct ch7006_mode ch7006_modes[]; ++ ++struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder, ++ struct drm_display_mode *drm_mode); ++ ++void ch7006_setup_levels(struct drm_encoder *encoder); ++void ch7006_setup_subcarrier(struct drm_encoder *encoder); ++void ch7006_setup_pll(struct drm_encoder *encoder); ++void ch7006_setup_power_state(struct drm_encoder *encoder); ++void ch7006_setup_properties(struct drm_encoder *encoder); ++ ++void ch7006_write(struct i2c_client *client, uint8_t addr, uint8_t val); ++uint8_t ch7006_read(struct i2c_client *client, uint8_t addr); ++ ++void ch7006_state_load(struct i2c_client *client, ++ struct ch7006_state *state); ++void ch7006_state_save(struct i2c_client *client, ++ struct ch7006_state *state); ++ ++/* Some helper macros */ ++ ++#define ch7006_dbg(client, format, ...) do { \ ++ if (ch7006_debug) \ ++ dev_printk(KERN_DEBUG, &client->dev, \ ++ "%s: " format, __func__, ## __VA_ARGS__); \ ++ } while (0) ++#define ch7006_info(client, format, ...) \ ++ dev_info(&client->dev, format, __VA_ARGS__) ++#define ch7006_err(client, format, ...) \ ++ dev_err(&client->dev, format, __VA_ARGS__) ++ ++#define __mask(src, bitfield) \ ++ (((2 << (1 ? bitfield)) - 1) & ~((1 << (0 ? bitfield)) - 1)) ++#define mask(bitfield) __mask(bitfield) ++ ++#define __bitf(src, bitfield, x) \ ++ (((x) >> (src) << (0 ? bitfield)) & __mask(src, bitfield)) ++#define bitf(bitfield, x) __bitf(bitfield, x) ++#define bitfs(bitfield, s) __bitf(bitfield, bitfield##_##s) ++#define setbitf(state, reg, bitfield, x) \ ++ state->regs[reg] = (state->regs[reg] & ~mask(reg##_##bitfield)) \ ++ | bitf(reg##_##bitfield, x) ++ ++#define __unbitf(src, bitfield, x) \ ++ ((x & __mask(src, bitfield)) >> (0 ? bitfield) << (src)) ++#define unbitf(bitfield, x) __unbitf(bitfield, x) ++ ++static inline int interpolate(int y0, int y1, int y2, int x) ++{ ++ return y1 + (x < 50 ? y1 - y0 : y2 - y1) * (x - 50) / 50; ++} ++ ++static inline int32_t round_fixed(fixed x) ++{ ++ return (x + fixed1/2) >> 32; ++} ++ ++#define ch7006_load_reg(client, state, reg) ch7006_write(client, reg, state->regs[reg]) ++#define ch7006_save_reg(client, state, reg) state->regs[reg] = ch7006_read(client, reg) ++ ++/* Fixed hardware specs */ ++ ++#define CH7006_FREQ0 14318 ++#define CH7006_MAXN 650 ++#define CH7006_MAXM 315 ++ ++/* Register definitions */ ++ ++#define CH7006_DISPMODE 0x00 ++#define CH7006_DISPMODE_INPUT_RES 0, 7:5 ++#define CH7006_DISPMODE_INPUT_RES_512x384 0x0 ++#define CH7006_DISPMODE_INPUT_RES_720x400 0x1 ++#define CH7006_DISPMODE_INPUT_RES_640x400 0x2 ++#define CH7006_DISPMODE_INPUT_RES_640x480 0x3 ++#define CH7006_DISPMODE_INPUT_RES_800x600 0x4 ++#define CH7006_DISPMODE_INPUT_RES_NATIVE 0x5 ++#define CH7006_DISPMODE_OUTPUT_STD 0, 4:3 ++#define CH7006_DISPMODE_OUTPUT_STD_PAL 0x0 ++#define CH7006_DISPMODE_OUTPUT_STD_NTSC 0x1 ++#define CH7006_DISPMODE_OUTPUT_STD_PAL_M 0x2 ++#define CH7006_DISPMODE_OUTPUT_STD_NTSC_J 0x3 ++#define CH7006_DISPMODE_SCALING_RATIO 0, 2:0 ++#define CH7006_DISPMODE_SCALING_RATIO_5_4 0x0 ++#define CH7006_DISPMODE_SCALING_RATIO_1_1 0x1 ++#define CH7006_DISPMODE_SCALING_RATIO_7_8 0x2 ++#define CH7006_DISPMODE_SCALING_RATIO_5_6 0x3 ++#define CH7006_DISPMODE_SCALING_RATIO_3_4 0x4 ++#define CH7006_DISPMODE_SCALING_RATIO_7_10 0x5 ++ ++#define CH7006_FFILTER 0x01 ++#define CH7006_FFILTER_TEXT 0, 5:4 ++#define CH7006_FFILTER_LUMA 0, 3:2 ++#define CH7006_FFILTER_CHROMA 0, 1:0 ++#define CH7006_FFILTER_CHROMA_NO_DCRAWL 0x3 ++ ++#define CH7006_BWIDTH 0x03 ++#define CH7006_BWIDTH_5L_FFILER (1 << 7) ++#define CH7006_BWIDTH_CVBS_NO_CHROMA (1 << 6) ++#define CH7006_BWIDTH_CHROMA 0, 5:4 ++#define CH7006_BWIDTH_SVIDEO_YPEAK (1 << 3) ++#define CH7006_BWIDTH_SVIDEO_LUMA 0, 2:1 ++#define CH7006_BWIDTH_CVBS_LUMA 0, 0:0 ++ ++#define CH7006_INPUT_FORMAT 0x04 ++#define CH7006_INPUT_FORMAT_DAC_GAIN (1 << 6) ++#define CH7006_INPUT_FORMAT_RGB_PASS_THROUGH (1 << 5) ++#define CH7006_INPUT_FORMAT_FORMAT 0, 3:0 ++#define CH7006_INPUT_FORMAT_FORMAT_RGB16 0x0 ++#define CH7006_INPUT_FORMAT_FORMAT_YCrCb24m16 0x1 ++#define CH7006_INPUT_FORMAT_FORMAT_RGB24m16 0x2 ++#define CH7006_INPUT_FORMAT_FORMAT_RGB15 0x3 ++#define CH7006_INPUT_FORMAT_FORMAT_RGB24m12C 0x4 ++#define CH7006_INPUT_FORMAT_FORMAT_RGB24m12I 0x5 ++#define CH7006_INPUT_FORMAT_FORMAT_RGB24m8 0x6 ++#define CH7006_INPUT_FORMAT_FORMAT_RGB16m8 0x7 ++#define CH7006_INPUT_FORMAT_FORMAT_RGB15m8 0x8 ++#define CH7006_INPUT_FORMAT_FORMAT_YCrCb24m8 0x9 ++ ++#define CH7006_CLKMODE 0x06 ++#define CH7006_CLKMODE_SUBC_LOCK (1 << 7) ++#define CH7006_CLKMODE_MASTER (1 << 6) ++#define CH7006_CLKMODE_POS_EDGE (1 << 4) ++#define CH7006_CLKMODE_XCM 0, 3:2 ++#define CH7006_CLKMODE_PCM 0, 1:0 ++ ++#define CH7006_START_ACTIVE 0x07 ++#define CH7006_START_ACTIVE_0 0, 7:0 ++ ++#define CH7006_POV 0x08 ++#define CH7006_POV_START_ACTIVE_8 8, 2:2 ++#define CH7006_POV_HPOS_8 8, 1:1 ++#define CH7006_POV_VPOS_8 8, 0:0 ++ ++#define CH7006_BLACK_LEVEL 0x09 ++#define CH7006_BLACK_LEVEL_0 0, 7:0 ++ ++#define CH7006_HPOS 0x0a ++#define CH7006_HPOS_0 0, 7:0 ++ ++#define CH7006_VPOS 0x0b ++#define CH7006_VPOS_0 0, 7:0 ++ ++#define CH7006_INPUT_SYNC 0x0d ++#define CH7006_INPUT_SYNC_EMBEDDED (1 << 3) ++#define CH7006_INPUT_SYNC_OUTPUT (1 << 2) ++#define CH7006_INPUT_SYNC_PVSYNC (1 << 1) ++#define CH7006_INPUT_SYNC_PHSYNC (1 << 0) ++ ++#define CH7006_POWER 0x0e ++#define CH7006_POWER_SCART (1 << 4) ++#define CH7006_POWER_RESET (1 << 3) ++#define CH7006_POWER_LEVEL 0, 2:0 ++#define CH7006_POWER_LEVEL_CVBS_OFF 0x0 ++#define CH7006_POWER_LEVEL_POWER_OFF 0x1 ++#define CH7006_POWER_LEVEL_SVIDEO_OFF 0x2 ++#define CH7006_POWER_LEVEL_NORMAL 0x3 ++#define CH7006_POWER_LEVEL_FULL_POWER_OFF 0x4 ++ ++#define CH7006_DETECT 0x10 ++#define CH7006_DETECT_SVIDEO_Y_TEST (1 << 3) ++#define CH7006_DETECT_SVIDEO_C_TEST (1 << 2) ++#define CH7006_DETECT_CVBS_TEST (1 << 1) ++#define CH7006_DETECT_SENSE (1 << 0) ++ ++#define CH7006_CONTRAST 0x11 ++#define CH7006_CONTRAST_0 0, 2:0 ++ ++#define CH7006_PLLOV 0x13 ++#define CH7006_PLLOV_N_8 8, 2:1 ++#define CH7006_PLLOV_M_8 8, 0:0 ++ ++#define CH7006_PLLM 0x14 ++#define CH7006_PLLM_0 0, 7:0 ++ ++#define CH7006_PLLN 0x15 ++#define CH7006_PLLN_0 0, 7:0 ++ ++#define CH7006_BCLKOUT 0x17 ++ ++#define CH7006_SUBC_INC0 0x18 ++#define CH7006_SUBC_INC0_28 28, 3:0 ++ ++#define CH7006_SUBC_INC1 0x19 ++#define CH7006_SUBC_INC1_24 24, 3:0 ++ ++#define CH7006_SUBC_INC2 0x1a ++#define CH7006_SUBC_INC2_20 20, 3:0 ++ ++#define CH7006_SUBC_INC3 0x1b ++#define CH7006_SUBC_INC3_GPIO1_VAL (1 << 7) ++#define CH7006_SUBC_INC3_GPIO0_VAL (1 << 6) ++#define CH7006_SUBC_INC3_POUT_3_3V (1 << 5) ++#define CH7006_SUBC_INC3_POUT_INV (1 << 4) ++#define CH7006_SUBC_INC3_16 16, 3:0 ++ ++#define CH7006_SUBC_INC4 0x1c ++#define CH7006_SUBC_INC4_GPIO1_IN (1 << 7) ++#define CH7006_SUBC_INC4_GPIO0_IN (1 << 6) ++#define CH7006_SUBC_INC4_DS_INPUT (1 << 4) ++#define CH7006_SUBC_INC4_12 12, 3:0 ++ ++#define CH7006_SUBC_INC5 0x1d ++#define CH7006_SUBC_INC5_8 8, 3:0 ++ ++#define CH7006_SUBC_INC6 0x1e ++#define CH7006_SUBC_INC6_4 4, 3:0 ++ ++#define CH7006_SUBC_INC7 0x1f ++#define CH7006_SUBC_INC7_0 0, 3:0 ++ ++#define CH7006_PLL_CONTROL 0x20 ++#define CH7006_PLL_CONTROL_CPI (1 << 5) ++#define CH7006_PLL_CONTROL_CAPACITOR (1 << 4) ++#define CH7006_PLL_CONTROL_7STAGES (1 << 3) ++#define CH7006_PLL_CONTROL_DIGITAL_5V (1 << 2) ++#define CH7006_PLL_CONTROL_ANALOG_5V (1 << 1) ++#define CH7006_PLL_CONTROL_MEMORY_5V (1 << 0) ++ ++#define CH7006_CALC_SUBC_INC0 0x21 ++#define CH7006_CALC_SUBC_INC0_24 24, 4:3 ++#define CH7006_CALC_SUBC_INC0_HYST 0, 2:1 ++#define CH7006_CALC_SUBC_INC0_AUTO (1 << 0) ++ ++#define CH7006_CALC_SUBC_INC1 0x22 ++#define CH7006_CALC_SUBC_INC1_16 16, 7:0 ++ ++#define CH7006_CALC_SUBC_INC2 0x23 ++#define CH7006_CALC_SUBC_INC2_8 8, 7:0 ++ ++#define CH7006_CALC_SUBC_INC3 0x24 ++#define CH7006_CALC_SUBC_INC3_0 0, 7:0 ++ ++#define CH7006_VERSION_ID 0x25 ++ ++#endif +diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile +new file mode 100644 +index 0000000..e12b4ff +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/Makefile +@@ -0,0 +1,29 @@ ++# ++# Makefile for the drm device driver. This driver provides support for the ++# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. ++ ++ccflags-y := -Iinclude/drm ++nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ ++ nouveau_object.o nouveau_irq.o nouveau_notifier.o \ ++ nouveau_sgdma.o nouveau_dma.o \ ++ nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ ++ nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ ++ nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ ++ nv04_timer.o \ ++ nv04_mc.o nv40_mc.o nv50_mc.o \ ++ nv04_fb.o nv10_fb.o nv40_fb.o \ ++ nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ ++ nv04_graph.o nv10_graph.o nv20_graph.o \ ++ nv40_graph.o nv50_graph.o \ ++ nv04_instmem.o nv50_instmem.o \ ++ nv50_crtc.o nv50_dac.o nv50_sor.o \ ++ nv50_cursor.o nv50_display.o nv50_fbcon.o \ ++ nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ ++ nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o ++ ++nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o ++nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o ++nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o ++nouveau-$(CONFIG_ACPI) += nouveau_acpi.o ++ ++obj-$(CONFIG_DRM_NOUVEAU)+= nouveau.o +diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c +new file mode 100644 +index 0000000..ec0f2f3 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c +@@ -0,0 +1,125 @@ ++#include ++#include ++#include ++#include ++ ++#include "drmP.h" ++#include "drm.h" ++#include "drm_sarea.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++#include "nv50_display.h" ++ ++#define NOUVEAU_DSM_SUPPORTED 0x00 ++#define NOUVEAU_DSM_SUPPORTED_FUNCTIONS 0x00 ++ ++#define NOUVEAU_DSM_ACTIVE 0x01 ++#define NOUVEAU_DSM_ACTIVE_QUERY 0x00 ++ ++#define NOUVEAU_DSM_LED 0x02 ++#define NOUVEAU_DSM_LED_STATE 0x00 ++#define NOUVEAU_DSM_LED_OFF 0x10 ++#define NOUVEAU_DSM_LED_STAMINA 0x11 ++#define NOUVEAU_DSM_LED_SPEED 0x12 ++ ++#define NOUVEAU_DSM_POWER 0x03 ++#define NOUVEAU_DSM_POWER_STATE 0x00 ++#define NOUVEAU_DSM_POWER_SPEED 0x01 ++#define NOUVEAU_DSM_POWER_STAMINA 0x02 ++ ++static int nouveau_dsm(struct drm_device *dev, int func, int arg, int *result) ++{ ++ static char muid[] = { ++ 0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D, ++ 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4, ++ }; ++ ++ struct pci_dev *pdev = dev->pdev; ++ struct acpi_handle *handle; ++ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; ++ struct acpi_object_list input; ++ union acpi_object params[4]; ++ union acpi_object *obj; ++ int err; ++ ++ handle = DEVICE_ACPI_HANDLE(&pdev->dev); ++ ++ if (!handle) ++ return -ENODEV; ++ ++ input.count = 4; ++ input.pointer = params; ++ params[0].type = ACPI_TYPE_BUFFER; ++ params[0].buffer.length = sizeof(muid); ++ params[0].buffer.pointer = (char *)muid; ++ params[1].type = ACPI_TYPE_INTEGER; ++ params[1].integer.value = 0x00000102; ++ params[2].type = ACPI_TYPE_INTEGER; ++ params[2].integer.value = func; ++ params[3].type = ACPI_TYPE_INTEGER; ++ params[3].integer.value = arg; ++ ++ err = acpi_evaluate_object(handle, "_DSM", &input, &output); ++ if (err) { ++ NV_ERROR(dev, "failed to evaluate _DSM: %d\n", err); ++ return err; ++ } ++ ++ obj = (union acpi_object *)output.pointer; ++ ++ if (obj->type == ACPI_TYPE_INTEGER) ++ if (obj->integer.value == 0x80000002) ++ return -ENODEV; ++ ++ if (obj->type == ACPI_TYPE_BUFFER) { ++ if (obj->buffer.length == 4 && result) { ++ *result = 0; ++ *result |= obj->buffer.pointer[0]; ++ *result |= (obj->buffer.pointer[1] << 8); ++ *result |= (obj->buffer.pointer[2] << 16); ++ *result |= (obj->buffer.pointer[3] << 24); ++ } ++ } ++ ++ kfree(output.pointer); ++ return 0; ++} ++ ++int nouveau_hybrid_setup(struct drm_device *dev) ++{ ++ int result; ++ ++ if (nouveau_dsm(dev, NOUVEAU_DSM_ACTIVE, NOUVEAU_DSM_ACTIVE_QUERY, ++ &result)) ++ return -ENODEV; ++ ++ NV_INFO(dev, "_DSM hardware status gave 0x%x\n", result); ++ ++ if (result & 0x1) { /* Stamina mode - disable the external GPU */ ++ nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_STAMINA, ++ NULL); ++ nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STAMINA, ++ NULL); ++ } else { /* Ensure that the external GPU is enabled */ ++ nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_SPEED, NULL); ++ nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_SPEED, ++ NULL); ++ } ++ ++ return 0; ++} ++ ++bool nouveau_dsm_probe(struct drm_device *dev) ++{ ++ int support = 0; ++ ++ if (nouveau_dsm(dev, NOUVEAU_DSM_SUPPORTED, ++ NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &support)) ++ return false; ++ ++ if (!support) ++ return false; ++ ++ return true; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c +new file mode 100644 +index 0000000..20564f8 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c +@@ -0,0 +1,155 @@ ++/* ++ * Copyright (C) 2009 Red Hat ++ * ++ * 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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. ++ * ++ */ ++ ++/* ++ * Authors: ++ * Matthew Garrett ++ * ++ * Register locations derived from NVClock by Roderick Colenbrander ++ */ ++ ++#include ++ ++#include "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++#include "nouveau_reg.h" ++ ++static int nv40_get_intensity(struct backlight_device *bd) ++{ ++ struct drm_device *dev = bl_get_data(bd); ++ int val = (nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK) ++ >> 16; ++ ++ return val; ++} ++ ++static int nv40_set_intensity(struct backlight_device *bd) ++{ ++ struct drm_device *dev = bl_get_data(bd); ++ int val = bd->props.brightness; ++ int reg = nv_rd32(dev, NV40_PMC_BACKLIGHT); ++ ++ nv_wr32(dev, NV40_PMC_BACKLIGHT, ++ (val << 16) | (reg & ~NV40_PMC_BACKLIGHT_MASK)); ++ ++ return 0; ++} ++ ++static struct backlight_ops nv40_bl_ops = { ++ .options = BL_CORE_SUSPENDRESUME, ++ .get_brightness = nv40_get_intensity, ++ .update_status = nv40_set_intensity, ++}; ++ ++static int nv50_get_intensity(struct backlight_device *bd) ++{ ++ struct drm_device *dev = bl_get_data(bd); ++ ++ return nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT); ++} ++ ++static int nv50_set_intensity(struct backlight_device *bd) ++{ ++ struct drm_device *dev = bl_get_data(bd); ++ int val = bd->props.brightness; ++ ++ nv_wr32(dev, NV50_PDISPLAY_SOR_BACKLIGHT, ++ val | NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE); ++ return 0; ++} ++ ++static struct backlight_ops nv50_bl_ops = { ++ .options = BL_CORE_SUSPENDRESUME, ++ .get_brightness = nv50_get_intensity, ++ .update_status = nv50_set_intensity, ++}; ++ ++static int nouveau_nv40_backlight_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct backlight_device *bd; ++ ++ if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK)) ++ return 0; ++ ++ bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev, ++ &nv40_bl_ops); ++ if (IS_ERR(bd)) ++ return PTR_ERR(bd); ++ ++ dev_priv->backlight = bd; ++ bd->props.max_brightness = 31; ++ bd->props.brightness = nv40_get_intensity(bd); ++ backlight_update_status(bd); ++ ++ return 0; ++} ++ ++static int nouveau_nv50_backlight_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct backlight_device *bd; ++ ++ if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT)) ++ return 0; ++ ++ bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev, ++ &nv50_bl_ops); ++ if (IS_ERR(bd)) ++ return PTR_ERR(bd); ++ ++ dev_priv->backlight = bd; ++ bd->props.max_brightness = 1025; ++ bd->props.brightness = nv50_get_intensity(bd); ++ backlight_update_status(bd); ++ return 0; ++} ++ ++int nouveau_backlight_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ switch (dev_priv->card_type) { ++ case NV_40: ++ return nouveau_nv40_backlight_init(dev); ++ case NV_50: ++ return nouveau_nv50_backlight_init(dev); ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++void nouveau_backlight_exit(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->backlight) { ++ backlight_device_unregister(dev_priv->backlight); ++ dev_priv->backlight = NULL; ++ } ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c +new file mode 100644 +index 0000000..ba946df +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_bios.c +@@ -0,0 +1,5734 @@ ++/* ++ * 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 "drmP.h" ++#define NV_DEBUG_NOTRACE ++#include "nouveau_drv.h" ++#include "nouveau_hw.h" ++ ++/* 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 LEGACY_I2C_TV 0x82 ++ ++#define EDID1_LEN 128 ++ ++#define BIOSLOG(sip, fmt, arg...) NV_DEBUG(sip->dev, fmt, ##arg) ++#define LOG_OLD_VALUE(x) ++ ++#define ROM16(x) le16_to_cpu(*(uint16_t *)&(x)) ++#define ROM32(x) le32_to_cpu(*(uint32_t *)&(x)) ++ ++struct init_exec { ++ bool execute; ++ bool repeat; ++}; ++ ++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(struct drm_device *dev, const uint8_t *data, const bool writeable) ++{ ++ if (!(data[0] == 0x55 && data[1] == 0xAA)) { ++ NV_TRACEWARN(dev, "... BIOS signature not found\n"); ++ return 0; ++ } ++ ++ if (nv_cksum(data, data[2] * 512)) { ++ NV_TRACEWARN(dev, "... BIOS checksum invalid\n"); ++ /* if a ro image is somewhat bad, it's probably all rubbish */ ++ return writeable ? 2 : 1; ++ } else ++ NV_TRACE(dev, "... appears to be valid\n"); ++ ++ return 3; ++} ++ ++static void load_vbios_prom(struct drm_device *dev, uint8_t *data) ++{ ++ uint32_t pci_nv_20, save_pci_nv_20; ++ int pcir_ptr; ++ int i; ++ ++ if (nv_arch(dev) >= NV_50) ++ pci_nv_20 = 0x88050; ++ else ++ pci_nv_20 = NV_PBUS_PCI_NV_20; ++ ++ /* enable ROM access */ ++ save_pci_nv_20 = nvReadMC(dev, pci_nv_20); ++ nvWriteMC(dev, pci_nv_20, ++ save_pci_nv_20 & ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED); ++ ++ /* bail if no rom signature */ ++ if (nv_rd08(dev, NV_PROM_OFFSET) != 0x55 || ++ nv_rd08(dev, NV_PROM_OFFSET + 1) != 0xaa) ++ goto out; ++ ++ /* additional check (see note below) - read PCI record header */ ++ pcir_ptr = nv_rd08(dev, NV_PROM_OFFSET + 0x18) | ++ nv_rd08(dev, NV_PROM_OFFSET + 0x19) << 8; ++ if (nv_rd08(dev, NV_PROM_OFFSET + pcir_ptr) != 'P' || ++ nv_rd08(dev, NV_PROM_OFFSET + pcir_ptr + 1) != 'C' || ++ nv_rd08(dev, NV_PROM_OFFSET + pcir_ptr + 2) != 'I' || ++ nv_rd08(dev, 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(dev, NV_PROM_OFFSET + i); ++ ++out: ++ /* disable ROM access */ ++ nvWriteMC(dev, pci_nv_20, ++ save_pci_nv_20 | NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED); ++} ++ ++static void load_vbios_pramin(struct drm_device *dev, uint8_t *data) ++{ ++ uint32_t old_bar0_pramin = 0; ++ int i; ++ ++ if (nv_arch(dev) >= NV_50) { ++ uint32_t vbios_vram = (nv_rd32(dev, 0x619f04) & ~0xff) << 8; ++ ++ if (!vbios_vram) ++ vbios_vram = (nv_rd32(dev, 0x1700) << 16) + 0xf0000; ++ ++ old_bar0_pramin = nv_rd32(dev, 0x1700); ++ nv_wr32(dev, 0x1700, vbios_vram >> 16); ++ } ++ ++ /* bail if no rom signature */ ++ if (nv_rd08(dev, NV_PRAMIN_OFFSET) != 0x55 || ++ nv_rd08(dev, NV_PRAMIN_OFFSET + 1) != 0xaa) ++ goto out; ++ ++ for (i = 0; i < NV_PROM_SIZE; i++) ++ data[i] = nv_rd08(dev, NV_PRAMIN_OFFSET + i); ++ ++out: ++ if (nv_arch(dev) >= NV_50) ++ nv_wr32(dev, 0x1700, old_bar0_pramin); ++} ++ ++static void load_vbios_pci(struct drm_device *dev, uint8_t *data) ++{ ++ void __iomem *rom = NULL; ++ size_t rom_len; ++ int ret; ++ ++ ret = pci_enable_rom(dev->pdev); ++ if (ret) ++ return; ++ ++ rom = pci_map_rom(dev->pdev, &rom_len); ++ if (!rom) ++ goto out; ++ memcpy_fromio(data, rom, rom_len); ++ pci_unmap_rom(dev->pdev, rom); ++ ++out: ++ pci_disable_rom(dev->pdev); ++} ++ ++struct methods { ++ const char desc[8]; ++ void (*loadbios)(struct drm_device *, uint8_t *); ++ const bool rw; ++ int score; ++}; ++ ++static struct methods nv04_methods[] = { ++ { "PROM", load_vbios_prom, false }, ++ { "PRAMIN", load_vbios_pramin, true }, ++ { "PCIROM", load_vbios_pci, true }, ++ { } ++}; ++ ++static struct methods nv50_methods[] = { ++ { "PRAMIN", load_vbios_pramin, true }, ++ { "PROM", load_vbios_prom, false }, ++ { "PCIROM", load_vbios_pci, true }, ++ { } ++}; ++ ++static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct methods *methods, *method; ++ int testscore = 3; ++ ++ if (nouveau_vbios) { ++ method = nv04_methods; ++ while (method->loadbios) { ++ if (!strcasecmp(nouveau_vbios, method->desc)) ++ break; ++ method++; ++ } ++ ++ if (method->loadbios) { ++ NV_INFO(dev, "Attempting to use BIOS image from %s\n", ++ method->desc); ++ ++ method->loadbios(dev, data); ++ if (score_vbios(dev, data, method->rw)) ++ return true; ++ } ++ ++ NV_ERROR(dev, "VBIOS source \'%s\' invalid\n", nouveau_vbios); ++ } ++ ++ if (dev_priv->card_type < NV_50) ++ methods = nv04_methods; ++ else ++ methods = nv50_methods; ++ ++ method = methods; ++ while (method->loadbios) { ++ NV_TRACE(dev, "Attempting to load BIOS image from %s\n", ++ method->desc); ++ data[0] = data[1] = 0; /* avoid reuse of previous image */ ++ method->loadbios(dev, data); ++ method->score = score_vbios(dev, data, method->rw); ++ if (method->score == testscore) ++ return true; ++ method++; ++ } ++ ++ while (--testscore > 0) { ++ method = methods; ++ while (method->loadbios) { ++ if (method->score == testscore) { ++ NV_TRACE(dev, "Using BIOS image from %s\n", ++ method->desc); ++ method->loadbios(dev, data); ++ return true; ++ } ++ method++; ++ } ++ } ++ ++ NV_ERROR(dev, "No valid BIOS image found\n"); ++ return false; ++} ++ ++struct init_tbl_entry { ++ char *name; ++ uint8_t id; ++ int length; ++ int length_offset; ++ int length_multiplier; ++ bool (*handler)(struct nvbios *, uint16_t, struct init_exec *); ++}; ++ ++struct bit_entry { ++ uint8_t id[2]; ++ uint16_t length; ++ uint16_t offset; ++}; ++ ++static int parse_init_table(struct nvbios *, unsigned int, struct init_exec *); ++ ++#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) ++{ ++#if 0 ++ sync(); ++ msleep(2); ++#endif ++} ++ ++static uint32_t ++munge_reg(struct nvbios *bios, uint32_t reg) ++{ ++ if (nv_arch(bios->dev) < NV_50) ++ return reg; ++ ++ if (!(reg & 0x40000000)) ++ return reg; ++ ++ BUG_ON(!bios->display.output); ++ ++ if (reg & 0x40000000) ++ reg += (ffs(bios->display.output->or) - 1) * 0x800; ++ ++ reg &= ~0x40000000; ++ return reg; ++} ++ ++static int ++valid_reg(struct nvbios *bios, uint32_t reg) ++{ ++ struct drm_nouveau_private *dev_priv = bios->dev->dev_private; ++ struct drm_device *dev = bios->dev; ++ ++ /* C51 has misaligned regs on purpose. Marvellous */ ++ if (reg & 0x2 || ++ (reg & 0x1 && dev_priv->VBIOS.pub.chip_version != 0x51)) ++ NV_ERROR(dev, "======= misaligned reg 0x%08X =======\n", reg); ++ ++ /* warn on C51 regs that haven't been verified accessible in tracing */ ++ if (reg & 0x1 && dev_priv->VBIOS.pub.chip_version == 0x51 && ++ reg != 0x130d && reg != 0x1311 && reg != 0x60081d) ++ NV_WARN(dev, "=== C51 misaligned reg 0x%08X not verified ===\n", ++ reg); ++ ++ if (reg >= (8*1024*1024)) { ++ NV_ERROR(dev, "=== reg 0x%08x out of mapped bounds ===\n", reg); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static bool ++valid_idx_port(struct nvbios *bios, uint16_t port) ++{ ++ struct drm_nouveau_private *dev_priv = bios->dev->dev_private; ++ struct drm_device *dev = bios->dev; ++ ++ /* ++ * 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 (dev_priv->card_type < NV_50) { ++ if (port == NV_CIO_CRX__COLOR) ++ return true; ++ if (port == NV_VIO_SRX) ++ return true; ++ } else { ++ if (port == NV_CIO_CRX__COLOR) ++ return true; ++ } ++ ++ NV_ERROR(dev, "========== unknown indexed io port 0x%04X ==========\n", ++ port); ++ ++ return false; ++} ++ ++static bool ++valid_port(struct nvbios *bios, uint16_t port) ++{ ++ struct drm_device *dev = bios->dev; ++ ++ /* ++ * 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(dev, "========== unknown io port 0x%04X ==========\n", port); ++ ++ return false; ++} ++ ++static uint32_t ++bios_rd32(struct nvbios *bios, uint32_t reg) ++{ ++ uint32_t data; ++ ++ reg = munge_reg(bios, reg); ++ if (!valid_reg(bios, 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(bios->dev, reg); ++ ++ BIOSLOG(bios, " Read: Reg: 0x%08X, Data: 0x%08X\n", reg, data); ++ ++ return data; ++} ++ ++static void ++bios_wr32(struct nvbios *bios, uint32_t reg, uint32_t data) ++{ ++ struct drm_nouveau_private *dev_priv = bios->dev->dev_private; ++ ++ reg = munge_reg(bios, reg); ++ if (!valid_reg(bios, reg)) ++ return; ++ ++ /* see note in bios_rd32 */ ++ if (reg & 0x1) ++ reg &= 0xfffffffe; ++ ++ LOG_OLD_VALUE(bios_rd32(bios, reg)); ++ BIOSLOG(bios, " Write: Reg: 0x%08X, Data: 0x%08X\n", reg, data); ++ ++ if (dev_priv->VBIOS.execute) { ++ still_alive(); ++ nv_wr32(bios->dev, reg, data); ++ } ++} ++ ++static uint8_t ++bios_idxprt_rd(struct nvbios *bios, uint16_t port, uint8_t index) ++{ ++ struct drm_nouveau_private *dev_priv = bios->dev->dev_private; ++ struct drm_device *dev = bios->dev; ++ uint8_t data; ++ ++ if (!valid_idx_port(bios, port)) ++ return 0; ++ ++ if (dev_priv->card_type < NV_50) { ++ if (port == NV_VIO_SRX) ++ data = NVReadVgaSeq(dev, bios->state.crtchead, index); ++ else /* assume NV_CIO_CRX__COLOR */ ++ data = NVReadVgaCrtc(dev, bios->state.crtchead, index); ++ } else { ++ uint32_t data32; ++ ++ data32 = bios_rd32(bios, NV50_PDISPLAY_VGACRTC(index & ~3)); ++ data = (data32 >> ((index & 3) << 3)) & 0xff; ++ } ++ ++ BIOSLOG(bios, " Indexed IO read: Port: 0x%04X, Index: 0x%02X, " ++ "Head: 0x%02X, Data: 0x%02X\n", ++ port, index, bios->state.crtchead, data); ++ return data; ++} ++ ++static void ++bios_idxprt_wr(struct nvbios *bios, uint16_t port, uint8_t index, uint8_t data) ++{ ++ struct drm_nouveau_private *dev_priv = bios->dev->dev_private; ++ struct drm_device *dev = bios->dev; ++ ++ if (!valid_idx_port(bios, port)) ++ return; ++ ++ /* ++ * The current head is maintained in the nvbios member state.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) ++ bios->state.crtchead = 0; ++ ++ LOG_OLD_VALUE(bios_idxprt_rd(bios, port, index)); ++ BIOSLOG(bios, " Indexed IO write: Port: 0x%04X, Index: 0x%02X, " ++ "Head: 0x%02X, Data: 0x%02X\n", ++ port, index, bios->state.crtchead, data); ++ ++ if (bios->execute && dev_priv->card_type < NV_50) { ++ still_alive(); ++ if (port == NV_VIO_SRX) ++ NVWriteVgaSeq(dev, bios->state.crtchead, index, data); ++ else /* assume NV_CIO_CRX__COLOR */ ++ NVWriteVgaCrtc(dev, bios->state.crtchead, index, data); ++ } else ++ if (bios->execute) { ++ uint32_t data32, shift = (index & 3) << 3; ++ ++ still_alive(); ++ ++ data32 = bios_rd32(bios, NV50_PDISPLAY_VGACRTC(index & ~3)); ++ data32 &= ~(0xff << shift); ++ data32 |= (data << shift); ++ bios_wr32(bios, NV50_PDISPLAY_VGACRTC(index & ~3), data32); ++ } ++ ++ if (port == NV_CIO_CRX__COLOR && ++ index == NV_CIO_CRE_44 && data == NV_CIO_CRE_44_HEADB) ++ bios->state.crtchead = 1; ++} ++ ++static uint8_t ++bios_port_rd(struct nvbios *bios, uint16_t port) ++{ ++ uint8_t data, head = bios->state.crtchead; ++ ++ if (!valid_port(bios, port)) ++ return 0; ++ ++ data = NVReadPRMVIO(bios->dev, head, NV_PRMVIO0_OFFSET + port); ++ ++ BIOSLOG(bios, " IO read: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n", ++ port, head, data); ++ ++ return data; ++} ++ ++static void ++bios_port_wr(struct nvbios *bios, uint16_t port, uint8_t data) ++{ ++ int head = bios->state.crtchead; ++ ++ if (!valid_port(bios, port)) ++ return; ++ ++ LOG_OLD_VALUE(bios_port_rd(bios, port)); ++ BIOSLOG(bios, " IO write: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n", ++ port, head, data); ++ ++ if (!bios->execute) ++ return; ++ ++ still_alive(); ++ NVWritePRMVIO(bios->dev, head, NV_PRMVIO0_OFFSET + port, data); ++} ++ ++static bool ++io_flag_condition_met(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(bios, "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(bios, crtcport, crtcindex); ++ ++ data = bios->data[flagarray + ((data & mask) >> shift)]; ++ data &= flagarraymask; ++ ++ BIOSLOG(bios, "0x%04X: Checking if 0x%02X equals 0x%02X\n", ++ offset, data, cmpval); ++ ++ return (data == cmpval); ++} ++ ++static bool ++bios_condition_met(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(bios, "0x%04X: Cond: 0x%02X, Reg: 0x%08X, Mask: 0x%08X\n", ++ offset, cond, reg, mask); ++ ++ data = bios_rd32(bios, reg) & mask; ++ ++ BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n", ++ offset, data, cmpval); ++ ++ return (data == cmpval); ++} ++ ++static bool ++io_condition_met(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(bios, io_port, port_index) & mask; ++ ++ BIOSLOG(bios, "0x%04X: Checking if 0x%02X equals 0x%02X\n", ++ offset, data, cmpval); ++ ++ return (data == cmpval); ++} ++ ++static int ++nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t reg0 = nv_rd32(dev, reg + 0); ++ uint32_t reg1 = nv_rd32(dev, reg + 4); ++ struct nouveau_pll_vals pll; ++ struct pll_lims pll_limits; ++ int ret; ++ ++ ret = get_pll_limits(dev, reg, &pll_limits); ++ if (ret) ++ return ret; ++ ++ clk = nouveau_calc_pll_mnp(dev, &pll_limits, clk, &pll); ++ if (!clk) ++ return -ERANGE; ++ ++ reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16); ++ reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1; ++ ++ if (dev_priv->VBIOS.execute) { ++ still_alive(); ++ nv_wr32(dev, reg + 4, reg1); ++ nv_wr32(dev, reg + 0, reg0); ++ } ++ ++ return 0; ++} ++ ++static int ++setPLL(struct nvbios *bios, uint32_t reg, uint32_t clk) ++{ ++ struct drm_device *dev = bios->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ /* clk in kHz */ ++ struct pll_lims pll_lim; ++ struct nouveau_pll_vals pllvals; ++ int ret; ++ ++ if (dev_priv->card_type >= NV_50) ++ return nv50_pll_set(dev, reg, clk); ++ ++ /* high regs (such as in the mac g5 table) are not -= 4 */ ++ ret = get_pll_limits(dev, reg > 0x405c ? reg : reg - 4, &pll_lim); ++ if (ret) ++ return ret; ++ ++ clk = nouveau_calc_pll_mnp(dev, &pll_lim, clk, &pllvals); ++ if (!clk) ++ return -ERANGE; ++ ++ if (bios->execute) { ++ still_alive(); ++ nouveau_hw_setpll(dev, reg, &pllvals); ++ } ++ ++ return 0; ++} ++ ++static int dcb_entry_idx_from_crtchead(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ ++ /* ++ * 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(dev, bios->state.crtchead, 0); ++ ++ if (dcb_entry > bios->bdcb.dcb.entries) { ++ NV_ERROR(dev, "CR58 doesn't have a valid DCB entry currently " ++ "(%02X)\n", dcb_entry); ++ dcb_entry = 0x7f; /* unused / invalid marker */ ++ } ++ ++ return dcb_entry; ++} ++ ++static struct nouveau_i2c_chan * ++init_i2c_device_find(struct drm_device *dev, int i2c_index) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct bios_parsed_dcb *bdcb = &dev_priv->VBIOS.bdcb; ++ ++ if (i2c_index == 0xff) { ++ /* note: dcb_entry_idx_from_crtchead needs pre-script set-up */ ++ int idx = dcb_entry_idx_from_crtchead(dev), 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; ++ ++ return nouveau_i2c_find(dev, i2c_index); ++} ++ ++static uint32_t get_tmds_index_reg(struct drm_device *dev, 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. ++ */ ++ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ 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 */ ++ dcb_entry = dcb_entry_idx_from_crtchead(dev); ++ if (dcb_entry == 0x7f) ++ return 0; ++ dacoffset = pramdac_offset[ ++ dev_priv->VBIOS.bdcb.dcb.entry[dcb_entry].or]; ++ if (mlv == 0x81) ++ dacoffset ^= 8; ++ return 0x6808b0 + dacoffset; ++ } else { ++ if (mlv > ARRAY_SIZE(pramdac_table)) { ++ NV_ERROR(dev, "Magic Lookup Value too big (%02X)\n", ++ mlv); ++ return 0; ++ } ++ return pramdac_table[mlv]; ++ } ++} ++ ++static bool ++init_io_restrict_prog(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios, "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(bios, crtcport, crtcindex) & mask) >> shift; ++ if (config > count) { ++ NV_ERROR(bios->dev, ++ "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(bios, "0x%04X: Writing config %02X\n", offset, config); ++ ++ bios_wr32(bios, reg, configval); ++ ++ return true; ++} ++ ++static bool ++init_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "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(bios, offset + 2, iexec); ++ ++ iexec->repeat = false; ++ ++ return true; ++} ++ ++static bool ++init_io_restrict_pll(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios, "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(bios, crtcport, crtcindex) & mask) >> shift; ++ if (config > count) { ++ NV_ERROR(bios->dev, ++ "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(bios, offset, io_flag_condition_idx)) { ++ BIOSLOG(bios, "0x%04X: Condition fulfilled -- " ++ "frequency doubled\n", offset); ++ freq *= 2; ++ } else ++ BIOSLOG(bios, "0x%04X: Condition not fulfilled -- " ++ "frequency unchanged\n", offset); ++ } ++ ++ BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %d0kHz\n", ++ offset, reg, config, freq); ++ ++ setPLL(bios, reg, freq * 10); ++ ++ return true; ++} ++ ++static bool ++init_end_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *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(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "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(bios, reg); ++ ++ if (shift < 0x80) ++ data >>= shift; ++ else ++ data <<= (0x100 - shift); ++ ++ data &= srcmask; ++ ++ crtcdata = bios_idxprt_rd(bios, crtcport, crtcindex) & mask; ++ crtcdata |= (uint8_t)data; ++ bios_idxprt_wr(bios, crtcport, crtcindex, crtcdata); ++ ++ return true; ++} ++ ++static bool ++init_not(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ++{ ++ /* ++ * INIT_NOT opcode: 0x38 ('8') ++ * ++ * offset (8 bit): opcode ++ * ++ * Invert the current execute / no-execute condition (i.e. "else") ++ */ ++ if (iexec->execute) ++ BIOSLOG(bios, "0x%04X: ------ Skipping following commands ------\n", offset); ++ else ++ BIOSLOG(bios, "0x%04X: ------ Executing following commands ------\n", offset); ++ ++ iexec->execute = !iexec->execute; ++ return true; ++} ++ ++static bool ++init_io_flag_condition(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios, offset, cond)) ++ BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); ++ else { ++ BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); ++ iexec->execute = false; ++ } ++ ++ return true; ++} ++ ++static bool ++init_idx_addr_latched(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios, "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(bios, "0x%04X: Address: 0x%02X, Data: 0x%02X\n", ++ offset, instaddress, instdata); ++ ++ bios_wr32(bios, datareg, instdata); ++ value = bios_rd32(bios, controlreg) & mask; ++ value |= data; ++ value |= instaddress; ++ bios_wr32(bios, controlreg, value); ++ } ++ ++ return true; ++} ++ ++static bool ++init_io_restrict_pll2(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios, "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(bios, crtcport, crtcindex) & mask) >> shift; ++ if (config > count) { ++ NV_ERROR(bios->dev, ++ "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(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %dkHz\n", ++ offset, reg, config, freq); ++ ++ setPLL(bios, reg, freq); ++ ++ return true; ++} ++ ++static bool ++init_pll2(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "0x%04X: Reg: 0x%04X, Freq: %dkHz\n", ++ offset, reg, freq); ++ ++ setPLL(bios, reg, freq); ++ return true; ++} ++ ++static bool ++init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *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]; ++ struct nouveau_i2c_chan *chan; ++ struct i2c_msg msg; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " ++ "Count: 0x%02X\n", ++ offset, i2c_index, i2c_address, count); ++ ++ chan = init_i2c_device_find(bios->dev, i2c_index); ++ if (!chan) ++ 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; ++ ++ msg.addr = i2c_address; ++ msg.flags = I2C_M_RD; ++ msg.len = 1; ++ msg.buf = &value; ++ if (i2c_transfer(&chan->adapter, &msg, 1) != 1) ++ return false; ++ ++ BIOSLOG(bios, "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) { ++ msg.addr = i2c_address; ++ msg.flags = 0; ++ msg.len = 1; ++ msg.buf = &value; ++ if (i2c_transfer(&chan->adapter, &msg, 1) != 1) ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++static bool ++init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *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]; ++ struct nouveau_i2c_chan *chan; ++ struct i2c_msg msg; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " ++ "Count: 0x%02X\n", ++ offset, i2c_index, i2c_address, count); ++ ++ chan = init_i2c_device_find(bios->dev, i2c_index); ++ if (!chan) ++ 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(bios, "0x%04X: I2CReg: 0x%02X, Data: 0x%02X\n", ++ offset, i2c_reg, data); ++ ++ if (bios->execute) { ++ msg.addr = i2c_address; ++ msg.flags = 0; ++ msg.len = 1; ++ msg.buf = &data; ++ if (i2c_transfer(&chan->adapter, &msg, 1) != 1) ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++static bool ++init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *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]; ++ struct nouveau_i2c_chan *chan; ++ struct i2c_msg msg; ++ uint8_t data[256]; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " ++ "Count: 0x%02X\n", ++ offset, i2c_index, i2c_address, count); ++ ++ chan = init_i2c_device_find(bios->dev, i2c_index); ++ if (!chan) ++ return false; ++ ++ for (i = 0; i < count; i++) { ++ data[i] = bios->data[offset + 4 + i]; ++ ++ BIOSLOG(bios, "0x%04X: Data: 0x%02X\n", offset, data[i]); ++ } ++ ++ if (bios->execute) { ++ msg.addr = i2c_address; ++ msg.flags = 0; ++ msg.len = count; ++ msg.buf = data; ++ if (i2c_transfer(&chan->adapter, &msg, 1) != 1) ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool ++init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "0x%04X: MagicLookupValue: 0x%02X, TMDSAddr: 0x%02X, " ++ "Mask: 0x%02X, Data: 0x%02X\n", ++ offset, mlv, tmdsaddr, mask, data); ++ ++ reg = get_tmds_index_reg(bios->dev, mlv); ++ if (!reg) ++ return false; ++ ++ bios_wr32(bios, reg, ++ tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); ++ value = (bios_rd32(bios, reg + 4) & mask) | data; ++ bios_wr32(bios, reg + 4, value); ++ bios_wr32(bios, reg, tmdsaddr); ++ ++ return true; ++} ++ ++static bool ++init_zm_tmds_group(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios, "0x%04X: MagicLookupValue: 0x%02X, Count: 0x%02X\n", ++ offset, mlv, count); ++ ++ reg = get_tmds_index_reg(bios->dev, mlv); ++ if (!reg) ++ 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(bios, reg + 4, tmdsdata); ++ bios_wr32(bios, reg, tmdsaddr); ++ } ++ ++ return true; ++} ++ ++static bool ++init_cr_idx_adr_latch(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios, "0x%04X: Index1: 0x%02X, Index2: 0x%02X, " ++ "BaseAddr: 0x%02X, Count: 0x%02X\n", ++ offset, crtcindex1, crtcindex2, baseaddr, count); ++ ++ oldaddr = bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, crtcindex1); ++ ++ for (i = 0; i < count; i++) { ++ bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex1, ++ baseaddr + i); ++ data = bios->data[offset + 5 + i]; ++ bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex2, data); ++ } ++ ++ bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex1, oldaddr); ++ ++ return true; ++} ++ ++static bool ++init_cr(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "0x%04X: Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", ++ offset, crtcindex, mask, data); ++ ++ value = bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, crtcindex) & mask; ++ value |= data; ++ bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, value); ++ ++ return true; ++} ++ ++static bool ++init_zm_cr(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, NV_CIO_CRX__COLOR, crtcindex, data); ++ ++ return true; ++} ++ ++static bool ++init_zm_cr_group(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, offset + 2 + 2 * i - 1, iexec); ++ ++ return true; ++} ++ ++static bool ++init_condition_time(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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; ++ unsigned cnt; ++ ++ if (!iexec->execute) ++ return true; ++ ++ if (retries > 100) ++ retries = 100; ++ ++ BIOSLOG(bios, "0x%04X: Condition: 0x%02X, Retries: 0x%02X\n", ++ offset, cond, retries); ++ ++ if (!bios->execute) /* avoid 2s delays when "faking" execution */ ++ retries = 1; ++ ++ for (cnt = 0; cnt < retries; cnt++) { ++ if (bios_condition_met(bios, offset, cond)) { ++ BIOSLOG(bios, "0x%04X: Condition met, continuing\n", ++ offset); ++ break; ++ } else { ++ BIOSLOG(bios, "0x%04X: " ++ "Condition not met, sleeping for 20ms\n", ++ offset); ++ msleep(20); ++ } ++ } ++ ++ if (!bios_condition_met(bios, offset, cond)) { ++ NV_WARN(bios->dev, ++ "0x%04X: Condition still not met after %dms, " ++ "skipping following opcodes\n", offset, 20 * retries); ++ iexec->execute = false; ++ } ++ ++ return true; ++} ++ ++static bool ++init_zm_reg_sequence(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios, "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(bios, reg, data); ++ } ++ ++ return true; ++} ++ ++static bool ++init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "0x%04X: Executing subroutine at 0x%04X\n", ++ offset, sub_offset); ++ ++ parse_init_table(bios, sub_offset, iexec); ++ ++ BIOSLOG(bios, "0x%04X: End of 0x%04X subroutine\n", offset, sub_offset); ++ ++ return true; ++} ++ ++static bool ++init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "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(bios, srcreg); ++ ++ if (shift < 0x80) ++ srcvalue >>= shift; ++ else ++ srcvalue <<= (0x100 - shift); ++ ++ srcvalue = (srcvalue & srcmask) ^ xor; ++ ++ dstvalue = bios_rd32(bios, dstreg) & dstmask; ++ ++ bios_wr32(bios, dstreg, dstvalue | srcvalue); ++ ++ return true; ++} ++ ++static bool ++init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, crtcport, crtcindex, data); ++ ++ return true; ++} ++ ++static bool ++init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *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 */ ++ ++ /* ++ * This appears to be a NOP on G8x chipsets, both io logs of the VBIOS ++ * and kmmio traces of the binary driver POSTing the card show nothing ++ * being done for this opcode. why is it still listed in the table?! ++ */ ++ ++ struct drm_nouveau_private *dev_priv = bios->dev->dev_private; ++ ++ if (dev_priv->card_type >= NV_50) ++ return true; ++ ++ /* ++ * On every card I've seen, this step gets done for us earlier in ++ * the init scripts ++ uint8_t crdata = bios_idxprt_rd(dev, NV_VIO_SRX, 0x01); ++ bios_idxprt_wr(dev, 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(bios, NV_PFB_REFCTRL, NV_PFB_REFCTRL_VALID_1); ++ ++ /* write back the saved configuration value */ ++ bios_wr32(bios, NV_PFB_CFG0, bios->state.saved_nv_pfb_cfg0); ++ ++ return true; ++} ++ ++static bool ++init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, NV_PBUS_PCI_NV_19); ++ bios_wr32(bios, NV_PBUS_PCI_NV_19, 0); ++ bios_wr32(bios, reg, value1); ++ ++ udelay(10); ++ ++ bios_wr32(bios, reg, value2); ++ bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19); ++ ++ pci_nv_20 = bios_rd32(bios, NV_PBUS_PCI_NV_20); ++ pci_nv_20 &= ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED; /* 0xfffffffe */ ++ bios_wr32(bios, NV_PBUS_PCI_NV_20, pci_nv_20); ++ ++ return true; ++} ++ ++static bool ++init_configure_mem(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios, 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(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd( ++ bios, 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(bios, reg, data); ++ } ++ ++ return true; ++} ++ ++static bool ++init_configure_clk(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios, 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(bios, NV_PRAMDAC_NVPLL_COEFF, clock); ++ ++ clock = ROM16(bios->data[meminitoffs + 2]) * 10; ++ if (bios->data[meminitoffs] & 1) /* DDR */ ++ clock *= 2; ++ setPLL(bios, NV_PRAMDAC_MPLL_COEFF, clock); ++ ++ return true; ++} ++ ++static bool ++init_configure_preinit(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios, NV_PEXTDEV_BOOT_0); ++ uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6)); ++ ++ if (bios->major_version > 2) ++ return false; ++ ++ bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, ++ NV_CIO_CRE_SCRATCH4__INDEX, cr3c); ++ ++ return true; ++} ++ ++static bool ++init_io(struct nvbios *bios, uint16_t offset, struct init_exec *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" ++ */ ++ ++ struct drm_nouveau_private *dev_priv = bios->dev->dev_private; ++ 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(bios, "0x%04X: Port: 0x%04X, Mask: 0x%02X, Data: 0x%02X\n", ++ offset, crtcport, mask, data); ++ ++ /* ++ * I have no idea what this does, but NVIDIA do this magic sequence ++ * in the places where this INIT_IO happens.. ++ */ ++ if (dev_priv->card_type >= NV_50 && crtcport == 0x3c3 && data == 1) { ++ int i; ++ ++ bios_wr32(bios, 0x614100, (bios_rd32( ++ bios, 0x614100) & 0x0fffffff) | 0x00800000); ++ ++ bios_wr32(bios, 0x00e18c, bios_rd32( ++ bios, 0x00e18c) | 0x00020000); ++ ++ bios_wr32(bios, 0x614900, (bios_rd32( ++ bios, 0x614900) & 0x0fffffff) | 0x00800000); ++ ++ bios_wr32(bios, 0x000200, bios_rd32( ++ bios, 0x000200) & ~0x40000000); ++ ++ mdelay(10); ++ ++ bios_wr32(bios, 0x00e18c, bios_rd32( ++ bios, 0x00e18c) & ~0x00020000); ++ ++ bios_wr32(bios, 0x000200, bios_rd32( ++ bios, 0x000200) | 0x40000000); ++ ++ bios_wr32(bios, 0x614100, 0x00800018); ++ bios_wr32(bios, 0x614900, 0x00800018); ++ ++ mdelay(10); ++ ++ bios_wr32(bios, 0x614100, 0x10000018); ++ bios_wr32(bios, 0x614900, 0x10000018); ++ ++ for (i = 0; i < 3; i++) ++ bios_wr32(bios, 0x614280 + (i*0x800), bios_rd32( ++ bios, 0x614280 + (i*0x800)) & 0xf0f0f0f0); ++ ++ for (i = 0; i < 2; i++) ++ bios_wr32(bios, 0x614300 + (i*0x800), bios_rd32( ++ bios, 0x614300 + (i*0x800)) & 0xfffff0f0); ++ ++ for (i = 0; i < 3; i++) ++ bios_wr32(bios, 0x614380 + (i*0x800), bios_rd32( ++ bios, 0x614380 + (i*0x800)) & 0xfffff0f0); ++ ++ for (i = 0; i < 2; i++) ++ bios_wr32(bios, 0x614200 + (i*0x800), bios_rd32( ++ bios, 0x614200 + (i*0x800)) & 0xfffffff0); ++ ++ for (i = 0; i < 2; i++) ++ bios_wr32(bios, 0x614108 + (i*0x800), bios_rd32( ++ bios, 0x614108 + (i*0x800)) & 0x0fffffff); ++ return true; ++ } ++ ++ bios_port_wr(bios, crtcport, (bios_port_rd(bios, crtcport) & mask) | ++ data); ++ return true; ++} ++ ++static bool ++init_sub(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "0x%04X: Calling script %d\n", offset, sub); ++ ++ parse_init_table(bios, ++ ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]), ++ iexec); ++ ++ BIOSLOG(bios, "0x%04X: End of script %d\n", offset, sub); ++ ++ return true; ++} ++ ++static bool ++init_ram_condition(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios, NV_PFB_BOOT_0) & mask; ++ ++ BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n", ++ offset, data, cmpval); ++ ++ if (data == cmpval) ++ BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); ++ else { ++ BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); ++ iexec->execute = false; ++ } ++ ++ return true; ++} ++ ++static bool ++init_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "0x%04X: Reg: 0x%08X, Mask: 0x%08X, Data: 0x%08X\n", ++ offset, reg, mask, data); ++ ++ bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | data); ++ ++ return true; ++} ++ ++static bool ++init_macro(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "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(bios, reg, data); ++ } ++ ++ return true; ++} ++ ++static bool ++init_done(struct nvbios *bios, uint16_t offset, struct init_exec *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(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "0x%04X: ---- Executing following commands ----\n", offset); ++ ++ return true; ++} ++ ++static bool ++init_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ++{ ++ /* ++ * INIT_TIME opcode: 0x74 ('t') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (16 bit): time ++ * ++ * Sleep for "time" microseconds. ++ */ ++ ++ unsigned time = ROM16(bios->data[offset + 1]); ++ ++ if (!iexec->execute) ++ return true; ++ ++ BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X microseconds\n", ++ offset, time); ++ ++ if (time < 1000) ++ udelay(time); ++ else ++ msleep((time + 900) / 1000); ++ ++ return true; ++} ++ ++static bool ++init_condition(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "0x%04X: Condition: 0x%02X\n", offset, cond); ++ ++ if (bios_condition_met(bios, offset, cond)) ++ BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); ++ else { ++ BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); ++ iexec->execute = false; ++ } ++ ++ return true; ++} ++ ++static bool ++init_io_condition(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "0x%04X: IO condition: 0x%02X\n", offset, cond); ++ ++ if (io_condition_met(bios, offset, cond)) ++ BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); ++ else { ++ BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); ++ iexec->execute = false; ++ } ++ ++ return true; ++} ++ ++static bool ++init_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " ++ "Data: 0x%02X\n", ++ offset, crtcport, crtcindex, mask, data); ++ ++ value = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) | data; ++ bios_idxprt_wr(bios, crtcport, crtcindex, value); ++ ++ return true; ++} ++ ++static bool ++init_pll(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", offset, reg, freq); ++ ++ setPLL(bios, reg, freq * 10); ++ ++ return true; ++} ++ ++static bool ++init_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *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; ++ ++ if (reg == 0x000200) ++ value |= 1; ++ ++ bios_wr32(bios, reg, value); ++ ++ return true; ++} ++ ++static bool ++init_ram_restrict_pll(struct nvbios *bios, uint16_t offset, ++ struct init_exec *iexec) ++{ ++ /* ++ * INIT_RAM_RESTRICT_PLL opcode: 0x87 ('') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (8 bit): PLL type ++ * offset + 2 (32 bit): frequency 0 ++ * ++ * Uses the RAMCFG strap of PEXTDEV_BOOT as an index into the table at ++ * ram_restrict_table_ptr. The value read from there is used to select ++ * a frequency from the table starting at 'frequency 0' to be ++ * programmed into the PLL corresponding to 'type'. ++ * ++ * The PLL limits table on cards using this opcode has a mapping of ++ * 'type' to the relevant registers. ++ */ ++ ++ struct drm_device *dev = bios->dev; ++ uint32_t strap = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) & 0x0000003c) >> 2; ++ uint8_t index = bios->data[bios->ram_restrict_tbl_ptr + strap]; ++ uint8_t type = bios->data[offset + 1]; ++ uint32_t freq = ROM32(bios->data[offset + 2 + (index * 4)]); ++ uint8_t *pll_limits = &bios->data[bios->pll_limit_tbl_ptr], *entry; ++ int i; ++ ++ if (!iexec->execute) ++ return true; ++ ++ if (!bios->pll_limit_tbl_ptr || (pll_limits[0] & 0xf0) != 0x30) { ++ NV_ERROR(dev, "PLL limits table not version 3.x\n"); ++ return true; /* deliberate, allow default clocks to remain */ ++ } ++ ++ entry = pll_limits + pll_limits[1]; ++ for (i = 0; i < pll_limits[3]; i++, entry += pll_limits[2]) { ++ if (entry[0] == type) { ++ uint32_t reg = ROM32(entry[3]); ++ ++ BIOSLOG(bios, "0x%04X: " ++ "Type %02x Reg 0x%08x Freq %dKHz\n", ++ offset, type, reg, freq); ++ ++ setPLL(bios, reg, freq); ++ return true; ++ } ++ } ++ ++ NV_ERROR(dev, "PLL type 0x%02x not found in PLL limits table", type); ++ return true; ++} ++ ++static bool ++init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ++{ ++ /* ++ * INIT_GPIO opcode: 0x8E ('') ++ * ++ * offset (8 bit): opcode ++ * ++ * Loop over all entries in the DCB GPIO table, and initialise ++ * each GPIO according to various values listed in each entry ++ */ ++ ++ const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; ++ const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; ++ const uint8_t *gpio_table = &bios->data[bios->bdcb.init8e_table_ptr]; ++ const uint8_t *gpio_entry; ++ int i; ++ ++ if (bios->bdcb.version != 0x40) { ++ NV_ERROR(bios->dev, "DCB table not version 4.0\n"); ++ return false; ++ } ++ ++ if (!bios->bdcb.init8e_table_ptr) { ++ NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n"); ++ return false; ++ } ++ ++ gpio_entry = gpio_table + gpio_table[1]; ++ for (i = 0; i < gpio_table[2]; i++, gpio_entry += gpio_table[3]) { ++ uint32_t entry = ROM32(gpio_entry[0]), r, s, v; ++ int line = (entry & 0x0000001f); ++ ++ BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, entry); ++ ++ if ((entry & 0x0000ff00) == 0x0000ff00) ++ continue; ++ ++ r = nv50_gpio_reg[line >> 3]; ++ s = (line & 0x07) << 2; ++ v = bios_rd32(bios, r) & ~(0x00000003 << s); ++ if (entry & 0x01000000) ++ v |= (((entry & 0x60000000) >> 29) ^ 2) << s; ++ else ++ v |= (((entry & 0x18000000) >> 27) ^ 2) << s; ++ bios_wr32(bios, r, v); ++ ++ r = nv50_gpio_ctl[line >> 4]; ++ s = (line & 0x0f); ++ v = bios_rd32(bios, r) & ~(0x00010001 << s); ++ switch ((entry & 0x06000000) >> 25) { ++ case 1: ++ v |= (0x00000001 << s); ++ break; ++ case 2: ++ v |= (0x00010000 << s); ++ break; ++ default: ++ break; ++ } ++ bios_wr32(bios, r, v); ++ } ++ ++ return true; ++} ++ ++/* hack to avoid moving the itbl_entry array before this function */ ++int init_ram_restrict_zm_reg_group_blocklen; ++ ++static bool ++init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios->dev, ++ "0x%04X: Zero block length - has the M table " ++ "been parsed?\n", offset); ++ return false; ++ } ++ ++ strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; ++ index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg]; ++ ++ BIOSLOG(bios, "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(bios, reg, data); ++ ++ reg += regincrement; ++ } ++ ++ return true; ++} ++ ++static bool ++init_copy_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *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(bios, dstreg, bios_rd32(bios, srcreg)); ++ ++ return true; ++} ++ ++static bool ++init_zm_reg_group_addr_latched(struct nvbios *bios, uint16_t offset, ++ struct init_exec *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(bios, reg, data); ++ } ++ ++ return true; ++} ++ ++static bool ++init_reserved(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ++{ ++ /* ++ * INIT_RESERVED opcode: 0x92 ('') ++ * ++ * offset (8 bit): opcode ++ * ++ * Seemingly does nothing ++ */ ++ ++ return true; ++} ++ ++static bool ++init_96(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ++{ ++ /* ++ * INIT_96 opcode: 0x96 ('') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): sreg ++ * offset + 5 (8 bit): sshift ++ * offset + 6 (8 bit): smask ++ * offset + 7 (8 bit): index ++ * offset + 8 (32 bit): reg ++ * offset + 12 (32 bit): mask ++ * offset + 16 (8 bit): shift ++ * ++ */ ++ ++ uint16_t xlatptr = bios->init96_tbl_ptr + (bios->data[offset + 7] * 2); ++ uint32_t reg = ROM32(bios->data[offset + 8]); ++ uint32_t mask = ROM32(bios->data[offset + 12]); ++ uint32_t val; ++ ++ val = bios_rd32(bios, ROM32(bios->data[offset + 1])); ++ if (bios->data[offset + 5] < 0x80) ++ val >>= bios->data[offset + 5]; ++ else ++ val <<= (0x100 - bios->data[offset + 5]); ++ val &= bios->data[offset + 6]; ++ ++ val = bios->data[ROM16(bios->data[xlatptr]) + val]; ++ val <<= bios->data[offset + 16]; ++ ++ if (!iexec->execute) ++ return true; ++ ++ bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | val); ++ return true; ++} ++ ++static bool ++init_97(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ++{ ++ /* ++ * INIT_97 opcode: 0x97 ('') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): register ++ * offset + 5 (32 bit): mask ++ * offset + 9 (32 bit): value ++ * ++ * Adds "value" to "register" preserving the fields specified ++ * by "mask" ++ */ ++ ++ uint32_t reg = ROM32(bios->data[offset + 1]); ++ uint32_t mask = ROM32(bios->data[offset + 5]); ++ uint32_t add = ROM32(bios->data[offset + 9]); ++ uint32_t val; ++ ++ val = bios_rd32(bios, reg); ++ val = (val & mask) | ((val + add) & ~mask); ++ ++ if (!iexec->execute) ++ return true; ++ ++ bios_wr32(bios, reg, val); ++ return true; ++} ++ ++static int ++nouveau_dp_auxch_rd(struct nouveau_i2c_chan *auxch, int cmd, int addr, ++ uint8_t buf[16], int len) ++{ ++ NV_ERROR(auxch->dev, "auxch_rd: stub!\n"); ++ return -ENODEV; ++} ++ ++static int ++nouveau_dp_auxch_wr(struct nouveau_i2c_chan *auxch, int cmd, int addr, ++ uint8_t buf[16], int len) ++{ ++ NV_ERROR(auxch->dev, "auxch_wr: stub!\n"); ++ return -ENODEV; ++} ++ ++static bool ++init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ++{ ++ /* ++ * INIT_AUXCH opcode: 0x98 ('') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): address ++ * offset + 5 (8 bit): count ++ * offset + 6 (8 bit): mask 0 ++ * offset + 7 (8 bit): data 0 ++ * ... ++ * ++ */ ++ ++ struct drm_device *dev = bios->dev; ++ struct nouveau_i2c_chan *auxch; ++ uint32_t addr = ROM32(bios->data[offset + 1]); ++ uint8_t len = bios->data[offset + 5]; ++ uint8_t buf[16]; ++ int ret, i; ++ ++ if (len > 16) { ++ NV_ERROR(dev, "INIT_AUXCH: >16 byte xfer unimplemented!\n"); ++ return false; ++ } ++ ++ if (!bios->display.output) { ++ NV_ERROR(dev, "INIT_AUXCH: no active output\n"); ++ return false; ++ } ++ ++ auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); ++ if (!auxch) { ++ NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n", ++ bios->display.output->i2c_index); ++ return false; ++ } ++ ++ if (!iexec->execute) ++ return true; ++ ++ ret = nouveau_dp_auxch_rd(auxch, 9, addr, buf, len); ++ if (ret) { ++ NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret); ++ return false; ++ } ++ ++ offset += 6; ++ for (i = 0; i < len; i++, offset += 2) { ++ buf[i] &= bios->data[offset + 0]; ++ buf[i] |= bios->data[offset + 1]; ++ } ++ ++ ret = nouveau_dp_auxch_wr(auxch, 8, addr, buf, len); ++ if (ret) { ++ NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret); ++ return false; ++ } ++ ++ return true; ++} ++ ++static bool ++init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ++{ ++ /* ++ * INIT_ZM_AUXCH opcode: 0x99 ('') ++ * ++ * offset (8 bit): opcode ++ * offset + 1 (32 bit): address ++ * offset + 5 (8 bit): count ++ * offset + 6 (8 bit): data 0 ++ * ... ++ * ++ */ ++ ++ struct drm_device *dev = bios->dev; ++ struct nouveau_i2c_chan *auxch; ++ uint32_t addr = ROM32(bios->data[offset + 1]); ++ uint8_t len = bios->data[offset + 5]; ++ int ret; ++ ++ if (len > 16) { ++ NV_ERROR(dev, "INIT_ZM_AUXCH: >16 byte xfer unimplemented!\n"); ++ return false; ++ } ++ ++ if (!bios->display.output) { ++ NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n"); ++ return false; ++ } ++ ++ auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); ++ if (!auxch) { ++ NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n", ++ bios->display.output->i2c_index); ++ return false; ++ } ++ ++ if (!iexec->execute) ++ return true; ++ ++ ret = nouveau_dp_auxch_wr(auxch, 8, addr, &bios->data[offset + 6], len); ++ if (ret) { ++ NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret); ++ return false; ++ } ++ ++ return true; ++} ++ ++static struct init_tbl_entry 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_RAM_RESTRICT_PLL's length is adjusted by the BIT M table */ ++ { "INIT_RAM_RESTRICT_PLL" , 0x87, 2 , 0 , 0 , init_ram_restrict_pll }, ++ { "INIT_GPIO" , 0x8E, 1 , 0 , 0 , init_gpio }, ++ /* 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 }, ++ { "INIT_96" , 0x96, 17 , 0 , 0 , init_96 }, ++ { "INIT_97" , 0x97, 13 , 0 , 0 , init_97 }, ++ { "INIT_AUXCH" , 0x98, 6 , 5 , 2 , init_auxch }, ++ { "INIT_ZM_AUXCH" , 0x99, 6 , 5 , 1 , init_zm_auxch }, ++ { NULL , 0 , 0 , 0 , 0 , NULL } ++}; ++ ++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(struct nvbios *bios, unsigned int offset, ++ struct init_exec *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(bios, "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)(bios, offset, iexec)) ++ break; ++ } else { ++ NV_ERROR(bios->dev, ++ "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(bios->dev, ++ "Offset 0x%04X greater than known bios image length. " ++ "Corrupt image?\n", offset); ++ if (count >= MAX_TABLE_OPS) ++ NV_WARN(bios->dev, ++ "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(struct nvbios *bios) ++{ ++ /* Loops and calls parse_init_table() for each present table. */ ++ ++ int i = 0; ++ uint16_t table; ++ struct init_exec iexec = {true, false}; ++ ++ if (bios->old_style_init) { ++ if (bios->init_script_tbls_ptr) ++ parse_init_table(bios, bios->init_script_tbls_ptr, &iexec); ++ if (bios->extra_init_script_tbl_ptr) ++ parse_init_table(bios, bios->extra_init_script_tbl_ptr, &iexec); ++ ++ return; ++ } ++ ++ while ((table = ROM16(bios->data[bios->init_script_tbls_ptr + i]))) { ++ NV_INFO(bios->dev, ++ "Parsing VBIOS init table %d at offset 0x%04X\n", ++ i / 2, table); ++ BIOSLOG(bios, "0x%04X: ------ Executing following commands ------\n", table); ++ ++ parse_init_table(bios, table, &iexec); ++ i += 2; ++ } ++} ++ ++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(struct drm_device *dev, uint16_t scriptptr, ++ struct dcb_entry *dcbent, int head, bool dl) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ struct init_exec iexec = {true, false}; ++ ++ NV_TRACE(dev, "0x%04X: Parsing digital output script table\n", ++ scriptptr); ++ bios_idxprt_wr(bios, 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(dev, head, 0, dcbent->index); ++ parse_init_table(bios, scriptptr, &iexec); ++ ++ nv04_dfp_bind_head(dev, dcbent, head, dl); ++} ++ ++static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->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(dev, scriptofs, dcbent, head, bios->fp.dual_link); ++ ++ if (script == LVDS_PANEL_OFF) { ++ /* off-on delay in ms */ ++ msleep(ROM16(bios->data[bios->fp.xlated_entry + 7])); ++ } ++#ifdef __powerpc__ ++ /* Powerbook specific quirks */ ++ if (script == LVDS_RESET && ((dev->pci_device & 0xffff) == 0x0179 || (dev->pci_device & 0xffff) == 0x0329)) ++ nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); ++ if ((dev->pci_device & 0xffff) == 0x0179 || (dev->pci_device & 0xffff) == 0x0189 || (dev->pci_device & 0xffff) == 0x0329) { ++ if (script == LVDS_PANEL_ON) { ++ bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) | (1 << 31)); ++ bios_wr32(bios, NV_PCRTC_GPIO_EXT, bios_rd32(bios, NV_PCRTC_GPIO_EXT) | 1); ++ } ++ if (script == LVDS_PANEL_OFF) { ++ bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) & ~(1 << 31)); ++ bios_wr32(bios, NV_PCRTC_GPIO_EXT, bios_rd32(bios, NV_PCRTC_GPIO_EXT) & ~3); ++ } ++ } ++#endif ++ ++ return 0; ++} ++ ++static int run_lvds_table(struct drm_device *dev, 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 drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->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(dev, "Pixel clock comparison table not found\n"); ++ return -ENOENT; ++ } ++ scriptptr = clkcmptable(bios, clktable, pxclk); ++ } ++ ++ if (!scriptptr) { ++ NV_ERROR(dev, "LVDS output init script not found\n"); ++ return -ENOENT; ++ } ++ run_digital_op_script(dev, scriptptr, dcbent, head, bios->fp.dual_link); ++ ++ return 0; ++} ++ ++int call_lvds_script(struct drm_device *dev, 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 ++ */ ++ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->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(dev, dcbent, head, LVDS_INIT, pxclk); ++ } ++ ++ if (script == LVDS_PANEL_ON && bios->fp.reset_after_pclk_change) ++ call_lvds_script(dev, dcbent, head, LVDS_RESET, pxclk); ++ if (script == LVDS_RESET && bios->fp.power_off_for_reset) ++ call_lvds_script(dev, dcbent, head, LVDS_PANEL_OFF, pxclk); ++ ++ NV_TRACE(dev, "Calling LVDS script %d:\n", script); ++ ++ /* don't let script change pll->head binding */ ++ sel_clk_binding = bios_rd32(bios, NV_PRAMDAC_SEL_CLK) & 0x50000; ++ ++ if (lvds_ver < 0x30) ++ ret = call_lvds_manufacturer_script(dev, dcbent, head, script); ++ else ++ ret = run_lvds_table(dev, dcbent, head, script, pxclk); ++ ++ bios->fp.last_script_invoc = (script << 1 | head); ++ ++ sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000; ++ NVWriteRAMDAC(dev, 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(dev, NV_PBUS_POWERCTRL_2, 0); ++ ++ return ret; ++} ++ ++struct lvdstableheader { ++ uint8_t lvds_ver, headerlen, recordlen; ++}; ++ ++static int parse_lvds_manufacturer_table_header(struct drm_device *dev, 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(dev, "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(dev, "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(dev, "LVDS table header not understood\n"); ++ return -EINVAL; ++ } ++ recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 2]; ++ break; ++ default: ++ NV_ERROR(dev, ++ "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(struct drm_device *dev, 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 ++ */ ++ ++ if (bios->major_version < 5 && bios->data[0x48] & 0x4) ++ return NVReadVgaCrtc5758(dev, 0, 0xf) & 0xf; ++ ++ if (nv_arch(dev) >= NV_50) ++ return (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 24) & 0xf; ++ else ++ return (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 16) & 0xf; ++} ++ ++static int parse_fp_mode_table(struct drm_device *dev, 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_ERROR(dev, "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(dev, ++ "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; ++ ++ ret = parse_lvds_manufacturer_table_header(dev, bios, <h); ++ if (ret) ++ 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(dev, "Pointer to flat panel xlat table invalid\n"); ++ return -EINVAL; ++ } ++ ++ fpstrapping = get_fp_strap(dev, bios); ++ ++ fpindex = bios->data[bios->fp.fpxlatetableptr + ++ fpstrapping * bios->fp.xlatwidth]; ++ ++ if (fpindex > fpentries) { ++ NV_ERROR(dev, "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(dev, "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(struct drm_device *dev, struct drm_display_mode *mode) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->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(struct drm_display_mode)); ++ /* ++ * 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->hsync_start = ROM16(mode_entry[17]) + 1; ++ mode->hsync_end = 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->vsync_start = ROM16(mode_entry[31]) + 1; ++ mode->vsync_end = ROM16(mode_entry[33]) + 1; ++ mode->vtotal = ROM16(mode_entry[35]) + 1; ++ mode->flags |= (mode_entry[37] & 0x10) ? ++ DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; ++ mode->flags |= (mode_entry[37] & 0x1) ? ++ DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; ++ /* ++ * bytes 38-39 relate to spread spectrum settings ++ * bytes 40-43 are something to do with PWM ++ */ ++ ++ mode->status = MODE_OK; ++ mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; ++ drm_mode_set_name(mode); ++ return bios->fp.mode_ptr; ++} ++ ++int nouveau_bios_parse_lvds_table(struct drm_device *dev, 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 drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ int fpstrapping = get_fp_strap(dev, bios), lvdsmanufacturerindex = 0; ++ struct lvdstableheader lth; ++ uint16_t lvdsofs; ++ int ret, chip_version = bios->pub.chip_version; ++ ++ ret = parse_lvds_manufacturer_table_header(dev, bios, <h); ++ if (ret) ++ 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(dev, "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(dev, ++ "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; ++ break; ++ case 0x40: ++ /* bios->fp.dual_link = bios->data[lvdsofs] & 1; */ ++ bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10; ++ break; ++ } ++ ++ /* 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 uint8_t * ++bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent, ++ uint16_t record, int record_len, int record_nr) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ uint32_t entry; ++ uint16_t table; ++ int i, v; ++ ++ for (i = 0; i < record_nr; i++, record += record_len) { ++ table = ROM16(bios->data[record]); ++ if (!table) ++ continue; ++ entry = ROM32(bios->data[table]); ++ ++ v = (entry & 0x000f0000) >> 16; ++ if (!(v & dcbent->or)) ++ continue; ++ ++ v = (entry & 0x000000f0) >> 4; ++ if (v != dcbent->location) ++ continue; ++ ++ v = (entry & 0x0000000f); ++ if (v != dcbent->type) ++ continue; ++ ++ return &bios->data[table]; ++ } ++ ++ return NULL; ++} ++ ++int ++nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, ++ uint32_t sub, 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 ++ */ ++ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct init_exec iexec = {true, false}; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ uint8_t *table = &bios->data[bios->display.script_table_ptr]; ++ uint8_t *otable = NULL; ++ uint16_t script; ++ int i = 0; ++ ++ if (!bios->display.script_table_ptr) { ++ NV_ERROR(dev, "No pointer to output script table\n"); ++ return 1; ++ } ++ ++ /* ++ * Nothing useful has been in any of the pre-2.0 tables I've seen, ++ * so until they are, we really don't need to care. ++ */ ++ if (table[0] < 0x20) ++ return 1; ++ ++ if (table[0] != 0x20 && table[0] != 0x21) { ++ NV_ERROR(dev, "Output script table version 0x%02x unknown\n", ++ table[0]); ++ return 1; ++ } ++ ++ /* ++ * 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. ++ */ ++ ++ NV_DEBUG(dev, "Searching for output entry for %d %d %d\n", ++ dcbent->type, dcbent->location, dcbent->or); ++ otable = bios_output_config_match(dev, dcbent, table[1] + ++ bios->display.script_table_ptr, ++ table[2], table[3]); ++ if (!otable) { ++ NV_ERROR(dev, "Couldn't find matching output script table\n"); ++ return 1; ++ } ++ ++ if (pxclk < -2 || pxclk > 0) { ++ /* Try to find matching script table entry */ ++ for (i = 0; i < otable[5]; i++) { ++ if (ROM16(otable[table[4] + i*6]) == sub) ++ break; ++ } ++ ++ if (i == otable[5]) { ++ NV_ERROR(dev, "Table 0x%04x not found for %d/%d, " ++ "using first\n", ++ sub, dcbent->type, dcbent->or); ++ i = 0; ++ } ++ } ++ ++ bios->display.output = dcbent; ++ ++ if (pxclk == 0) { ++ script = ROM16(otable[6]); ++ if (!script) { ++ NV_DEBUG(dev, "output script 0 not found\n"); ++ return 1; ++ } ++ ++ NV_TRACE(dev, "0x%04X: parsing output script 0\n", script); ++ parse_init_table(bios, script, &iexec); ++ } else ++ if (pxclk == -1) { ++ script = ROM16(otable[8]); ++ if (!script) { ++ NV_DEBUG(dev, "output script 1 not found\n"); ++ return 1; ++ } ++ ++ NV_TRACE(dev, "0x%04X: parsing output script 1\n", script); ++ parse_init_table(bios, script, &iexec); ++ } else ++ if (pxclk == -2) { ++ if (table[4] >= 12) ++ script = ROM16(otable[10]); ++ else ++ script = 0; ++ if (!script) { ++ NV_DEBUG(dev, "output script 2 not found\n"); ++ return 1; ++ } ++ ++ NV_TRACE(dev, "0x%04X: parsing output script 2\n", script); ++ parse_init_table(bios, script, &iexec); ++ } else ++ if (pxclk > 0) { ++ script = ROM16(otable[table[4] + i*6 + 2]); ++ if (script) ++ script = clkcmptable(bios, script, pxclk); ++ if (!script) { ++ NV_ERROR(dev, "clock script 0 not found\n"); ++ return 1; ++ } ++ ++ NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script); ++ parse_init_table(bios, script, &iexec); ++ } else ++ if (pxclk < 0) { ++ script = ROM16(otable[table[4] + i*6 + 4]); ++ if (script) ++ script = clkcmptable(bios, script, -pxclk); ++ if (!script) { ++ NV_DEBUG(dev, "clock script 1 not found\n"); ++ return 1; ++ } ++ ++ NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script); ++ parse_init_table(bios, script, &iexec); ++ } ++ ++ return 0; ++} ++ ++ ++int run_tmds_table(struct drm_device *dev, 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. ++ */ ++ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->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(dev, "Pixel clock comparison table not found\n"); ++ return -EINVAL; ++ } ++ ++ scriptptr = clkcmptable(bios, clktable, pxclk); ++ ++ if (!scriptptr) { ++ NV_ERROR(dev, "TMDS output init script not found\n"); ++ return -ENOENT; ++ } ++ ++ /* don't let script change pll->head binding */ ++ sel_clk_binding = bios_rd32(bios, NV_PRAMDAC_SEL_CLK) & 0x50000; ++ run_digital_op_script(dev, scriptptr, dcbent, head, pxclk >= 165000); ++ sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000; ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding); ++ ++ return 0; ++} ++ ++int get_pll_limits(struct drm_device *dev, 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. ++ */ ++ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->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(dev, "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 dev->twoHeads test */ ++ if (cv > 0x10 && cv != 0x15 && cv != 0x1a && cv != 0x20) ++ crystal_strap_mask |= 1 << 22; ++ crystal_straps = nvReadEXTDEV(dev, 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(dev, "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(dev, "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(bios, "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 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(dev, "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(dev, ++ "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(bios, 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(bios, 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(bios, "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(dev, "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(struct drm_device *dev, 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(dev, "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(struct drm_device *dev, struct nvbios *bios, struct bit_entry *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(dev, "Do not understand BIT A table\n"); ++ return -EINVAL; ++ } ++ ++ load_table_ptr = ROM16(bios->data[bitentry->offset]); ++ ++ if (load_table_ptr == 0x0) { ++ NV_ERROR(dev, "Pointer to BIT loadval table invalid\n"); ++ return -EINVAL; ++ } ++ ++ version = bios->data[load_table_ptr]; ++ ++ if (version != 0x10) { ++ NV_ERROR(dev, "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(dev, "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(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry) ++{ ++ /* ++ * offset + 8 (16 bits): PLL limits table pointer ++ * ++ * There's more in here, but that's unknown. ++ */ ++ ++ if (bitentry->length < 10) { ++ NV_ERROR(dev, "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(struct drm_device *dev, struct nvbios *bios, struct bit_entry *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(dev, "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(struct drm_device *dev, struct nvbios *bios, struct bit_entry *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(dev, "Do not understand init table\n"); ++ return -EINVAL; ++ } ++ ++ parse_script_table_pointers(bios, bitentry->offset); ++ ++ if (bitentry->length >= 16) ++ bios->some_script_ptr = ROM16(bios->data[bitentry->offset + 14]); ++ if (bitentry->length >= 18) ++ bios->init96_tbl_ptr = ROM16(bios->data[bitentry->offset + 16]); ++ ++ return 0; ++} ++ ++static int parse_bit_i_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *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(dev, "BIT i table too short for needed information\n"); ++ return -EINVAL; ++ } ++ ++ parse_bios_version(dev, 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(dev, "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, the second entry is a comparison value for ++ * TV load detection. ++ */ ++ ++ dacver = bios->data[daccmpoffset]; ++ dacheaderlen = bios->data[daccmpoffset + 1]; ++ ++ if (dacver != 0x00 && dacver != 0x10) { ++ NV_WARN(dev, "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]); ++ bios->pub.tvdactestval = ROM32(bios->data[daccmpoffset + dacheaderlen + 4]); ++ ++ return 0; ++} ++ ++static int parse_bit_lvds_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *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(dev, "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(struct drm_device *dev, struct nvbios *bios, struct bit_entry *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; ++ ++ /* adjust length of INIT_87 */ ++ for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != 0x87); i++); ++ itbl_entry[i].length += bios->data[bitentry->offset + 2] * 4; ++ ++ /* set up multiplier for INIT_RAM_RESTRICT_ZM_REG_GROUP */ ++ for (; 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(struct drm_device *dev, struct nvbios *bios, struct bit_entry *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 offset +7 is a pointer to a script, which I don't know how to ++ * run yet. ++ * At offset +9 is a pointer to another script, likewise ++ * 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, script1, script2; ++ ++ if (bitentry->length != 2) { ++ NV_ERROR(dev, "Do not understand BIT TMDS table\n"); ++ return -EINVAL; ++ } ++ ++ tmdstableptr = ROM16(bios->data[bitentry->offset]); ++ ++ if (tmdstableptr == 0x0) { ++ NV_ERROR(dev, "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(dev, ++ "TMDS table revision %d.%d not currently supported\n", ++ bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); ++ return -ENOSYS; ++ } ++ ++ /* ++ * These two scripts are odd: they don't seem to get run even when ++ * they are not stubbed. ++ */ ++ script1 = ROM16(bios->data[tmdstableptr + 7]); ++ script2 = ROM16(bios->data[tmdstableptr + 9]); ++ if (bios->data[script1] != 'q' || bios->data[script2] != 'q') ++ NV_WARN(dev, "TMDS table script pointers not stubbed\n"); ++ ++ 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(struct drm_device *dev, struct nvbios *bios, ++ struct bit_entry *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(dev, "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)(struct drm_device *, struct nvbios *, struct bit_entry *); ++}; ++ ++#define BIT_TABLE(id, funcid) ((struct bit_table){ id, parse_bit_##funcid##_tbl_entry }) ++ ++static int parse_bit_table(struct drm_device *dev, struct nvbios *bios, const uint16_t bitoffset, struct bit_table *table) ++{ ++ uint8_t maxentries = bios->data[bitoffset + 4]; ++ int i, offset; ++ struct bit_entry 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(dev, bios, &bitentry); ++ } ++ ++ NV_ERROR(dev, "BIT table '%c' not found\n", table->id); ++ ++ return -ENOSYS; ++} ++ ++static int parse_bit_structure(struct drm_device *dev, 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 ++ */ ++ ret = parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('i', i)); ++ if (ret) /* info? */ ++ return ret; ++ if (bios->major_version >= 0x60) /* g80+ */ ++ parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('A', A)); ++ ret = parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('C', C)); ++ if (ret) ++ return ret; ++ parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('D', display)); ++ ret = parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('I', init)); ++ if (ret) ++ return ret; ++ parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('M', M)); /* memory? */ ++ parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('L', lvds)); ++ parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('T', tmds)); ++ parse_bit_table(dev, bios, bitoffset, &BIT_TABLE('U', U)); ++ ++ return 0; ++} ++ ++static int parse_bmp_structure(struct drm_device *dev, 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(dev, "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(dev, "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(dev, "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(dev, 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]; ++ bios->bdcb.dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4]; ++ bios->bdcb.dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5]; ++ bios->bdcb.dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6]; ++ 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(struct drm_device *dev, 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(dev, ++ "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(dev, ++ "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(dev, "DCB I2C index too big (%d > %d)\n", ++ index, i2ctable[2]); ++ return -ENOENT; ++ } ++ if (i2ctable[headerlen + entry_len * index + 3] == 0xff) { ++ NV_ERROR(dev, "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(dev, "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 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) ++{ ++ struct dcb_entry *entry = new_dcb_entry(dcb); ++ ++ entry->type = 0; ++ entry->i2c_index = i2c; ++ entry->heads = heads; ++ entry->location = DCB_LOC_ON_CHIP; ++ /* "or" mostly unused in early gen crt modesetting, 0 is fine */ ++} ++ ++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); ++#endif ++} ++ ++static void fabricate_tv_output(struct parsed_dcb *dcb, bool twoHeads) ++{ ++ struct dcb_entry *entry = new_dcb_entry(dcb); ++ ++ entry->type = 1; ++ entry->i2c_index = LEGACY_I2C_TV; ++ entry->heads = twoHeads ? 3 : 1; ++ entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */ ++} ++ ++static bool ++parse_dcb20_entry(struct drm_device *dev, 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; ++ if (bdcb->version >= 0x40) ++ entry->connector = (conn >> 12) & 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(dev, "G80+ LVDS not initialized by driver; ignoring conf bits\n"); ++ break; ++ } ++ NV_ERROR(dev, "Unknown LVDS configuration bits, " ++ "please report\n"); ++ /* cause output setting to fail, so message is seen */ ++ bdcb->dcb.entries = 0; ++ return false; ++ } ++ break; ++ } ++ case OUTPUT_TV: ++ { ++ if (bdcb->version >= 0x30) ++ entry->tvconf.has_component_output = conf & (0x8 << 4); ++ else ++ entry->tvconf.has_component_output = 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(struct drm_device *dev, 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 && conn != 0xf2209004) { ++ NV_ERROR(dev, "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); ++ break; ++ case OUTPUT_TV: ++ entry->tvconf.has_component_output = false; ++ break; ++ } ++ ++ return true; ++} ++ ++static bool parse_dcb_entry(struct drm_device *dev, 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(dev, bdcb, conn, conf, entry); ++ else ++ ret = parse_dcb15_entry(dev, &bdcb->dcb, conn, conf, entry); ++ if (!ret) ++ return ret; ++ ++ read_dcb_i2c_entry(dev, bdcb->version, bdcb->i2c_table, ++ entry->i2c_index, &bdcb->dcb.i2c[entry->i2c_index]); ++ ++ return true; ++} ++ ++static ++void merge_like_dcb_entries(struct drm_device *dev, 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(dev, "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(struct drm_device *dev, 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) { ++ NV_WARN(dev, "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); ++ ++ if (nv04_tv_identify(dev, ++ bios->legacy.i2c_indices.tv) >= 0) ++ fabricate_tv_output(dcb, twoHeads); ++ ++ return 0; ++ } ++ ++ dcbtable = &bios->data[dcbptr]; ++ ++ /* get DCB version */ ++ bdcb->version = dcbtable[0]; ++ NV_TRACE(dev, "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(dev, "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(dev, "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(dev, "No useful information in BIOS output table; " ++ "adding all possible outputs\n"); ++ fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1); ++ ++ /* ++ * Attempt to detect TV before DVI because the test ++ * for the former is more accurate and it rules the ++ * latter out. ++ */ ++ if (nv04_tv_identify(dev, ++ bios->legacy.i2c_indices.tv) >= 0) ++ fabricate_tv_output(dcb, twoHeads); ++ ++ else if (bios->tmds.output0_script_ptr || ++ bios->tmds.output1_script_ptr) ++ fabricate_dvi_i_output(dcb, twoHeads); ++ ++ return 0; ++ } ++ ++ if (!i2ctabptr) ++ NV_WARN(dev, "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(dev, "Raw DCB entry %d: %08x %08x\n", ++ dcb->entries, connection, config); ++ ++ if (!parse_dcb_entry(dev, 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(dev, dcb); ++ ++ return dcb->entries ? 0 : -ENXIO; ++} ++ ++static void ++fixup_legacy_connector(struct nvbios *bios) ++{ ++ struct bios_parsed_dcb *bdcb = &bios->bdcb; ++ struct parsed_dcb *dcb = &bdcb->dcb; ++ int high = 0, i; ++ ++ /* ++ * DCB 3.0 also has the table in most cases, but there are some cards ++ * where the table is filled with stub entries, and the DCB entriy ++ * indices are all 0. We don't need the connector indices on pre-G80 ++ * chips (yet?) so limit the use to DCB 4.0 and above. ++ */ ++ if (bdcb->version >= 0x40) ++ return; ++ ++ /* ++ * No known connector info before v3.0, so make it up. the rule here ++ * is: anything on the same i2c bus is considered to be on the same ++ * connector. any output without an associated i2c bus is assigned ++ * its own unique connector index. ++ */ ++ for (i = 0; i < dcb->entries; i++) { ++ if (dcb->entry[i].i2c_index == 0xf) ++ continue; ++ ++ /* ++ * Ignore the I2C index for on-chip TV-out, as there ++ * are cards with bogus values (nv31m in bug 23212), ++ * and it's otherwise useless. ++ */ ++ if (dcb->entry[i].type == OUTPUT_TV && ++ dcb->entry[i].location == DCB_LOC_ON_CHIP) { ++ dcb->entry[i].i2c_index = 0xf; ++ continue; ++ } ++ ++ dcb->entry[i].connector = dcb->entry[i].i2c_index; ++ if (dcb->entry[i].connector > high) ++ high = dcb->entry[i].connector; ++ } ++ ++ for (i = 0; i < dcb->entries; i++) { ++ if (dcb->entry[i].i2c_index != 0xf) ++ continue; ++ ++ dcb->entry[i].connector = ++high; ++ } ++} ++ ++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; ++ if (dcb->entry[i].i2c_index == LEGACY_I2C_TV) ++ dcb->entry[i].i2c_index = bios->legacy.i2c_indices.tv; ++ } ++} ++ ++static int load_nv17_hwsq_ucode_entry(struct drm_device *dev, 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(dev, "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(dev, "Unknown HW sequencer entry size\n"); ++ return -EINVAL; ++ } ++ ++ NV_TRACE(dev, "Loading NV17 power sequencing microcode\n"); ++ ++ hwsq_entry_offset = hwsq_offset + 2 + entry * bytes_to_write; ++ ++ /* set sequencer control */ ++ bios_wr32(bios, 0x00001304, ROM32(bios->data[hwsq_entry_offset])); ++ bytes_to_write -= 4; ++ ++ /* write ucode */ ++ for (i = 0; i < bytes_to_write; i += 4) ++ bios_wr32(bios, 0x00001400 + i, ROM32(bios->data[hwsq_entry_offset + i + 4])); ++ ++ /* twiddle NV_PBUS_DEBUG_4 */ ++ bios_wr32(bios, NV_PBUS_DEBUG_4, bios_rd32(bios, NV_PBUS_DEBUG_4) | 0x18); ++ ++ return 0; ++} ++ ++static int load_nv17_hw_sequencer_ucode(struct drm_device *dev, ++ 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' }; ++ const int sz = sizeof(hwsq_signature); ++ int hwsq_offset; ++ ++ hwsq_offset = findstr(bios->data, bios->length, hwsq_signature, sz); ++ if (!hwsq_offset) ++ return 0; ++ ++ /* always use entry 0? */ ++ return load_nv17_hwsq_ucode_entry(dev, bios, hwsq_offset + sz, 0); ++} ++ ++uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ const uint8_t edid_sig[] = { ++ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; ++ uint16_t offset = 0; ++ uint16_t newoffset; ++ int searchlen = NV_PROM_SIZE; ++ ++ if (bios->fp.edid) ++ return bios->fp.edid; ++ ++ while (searchlen) { ++ newoffset = findstr(&bios->data[offset], searchlen, ++ edid_sig, 8); ++ if (!newoffset) ++ return NULL; ++ offset += newoffset; ++ if (!nv_cksum(&bios->data[offset], EDID1_LEN)) ++ break; ++ ++ searchlen -= offset; ++ offset++; ++ } ++ ++ NV_TRACE(dev, "Found EDID in BIOS\n"); ++ ++ return bios->fp.edid = &bios->data[offset]; ++} ++ ++void ++nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ struct init_exec iexec = { true, false }; ++ ++ parse_init_table(bios, table, &iexec); ++} ++ ++static bool NVInitVBIOS(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ ++ memset(bios, 0, sizeof(struct nvbios)); ++ bios->dev = dev; ++ ++ if (!NVShadowVBIOS(dev, bios->data)) ++ return false; ++ ++ bios->length = NV_PROM_SIZE; ++ return true; ++} ++ ++static int nouveau_parse_vbios_struct(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ const uint8_t bit_signature[] = { 0xff, 0xb8, 'B', 'I', 'T' }; ++ const uint8_t bmp_signature[] = { 0xff, 0x7f, 'N', 'V', 0x0 }; ++ int offset; ++ ++ offset = findstr(bios->data, bios->length, ++ bit_signature, sizeof(bit_signature)); ++ if (offset) { ++ NV_TRACE(dev, "BIT BIOS found\n"); ++ return parse_bit_structure(dev, bios, offset + 6); ++ } ++ ++ offset = findstr(bios->data, bios->length, ++ bmp_signature, sizeof(bmp_signature)); ++ if (offset) { ++ NV_TRACE(dev, "BMP BIOS found\n"); ++ return parse_bmp_structure(dev, bios, offset); ++ } ++ ++ NV_ERROR(dev, "No known BIOS signature found\n"); ++ return -ENODEV; ++} ++ ++int ++nouveau_run_vbios_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ int i, ret = 0; ++ ++ NVLockVgaCrtcs(dev, false); ++ if (nv_two_heads(dev)) ++ NVSetOwner(dev, bios->state.crtchead); ++ ++ if (bios->major_version < 5) /* BMP only */ ++ load_nv17_hw_sequencer_ucode(dev, bios); ++ ++ if (bios->execute) { ++ bios->fp.last_script_invoc = 0; ++ bios->fp.lvds_init_run = false; ++ } ++ ++ parse_init_tables(bios); ++ ++ /* ++ * Runs some additional script seen on G8x VBIOSen. The VBIOS' ++ * parser will run this right after the init tables, the binary ++ * driver appears to run it at some point later. ++ */ ++ if (bios->some_script_ptr) { ++ struct init_exec iexec = {true, false}; ++ ++ NV_INFO(dev, "Parsing VBIOS init table at offset 0x%04X\n", ++ bios->some_script_ptr); ++ parse_init_table(bios, bios->some_script_ptr, &iexec); ++ } ++ ++ if (dev_priv->card_type >= NV_50) { ++ for (i = 0; i < bios->bdcb.dcb.entries; i++) { ++ nouveau_bios_run_display_table(dev, ++ &bios->bdcb.dcb.entry[i], ++ 0, 0); ++ } ++ } ++ ++ NVLockVgaCrtcs(dev, true); ++ ++ return ret; ++} ++ ++static void ++nouveau_bios_i2c_devices_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ struct dcb_i2c_entry *entry; ++ int i; ++ ++ entry = &bios->bdcb.dcb.i2c[0]; ++ for (i = 0; i < DCB_MAX_NUM_I2C_ENTRIES; i++, entry++) ++ nouveau_i2c_fini(dev, entry); ++} ++ ++int ++nouveau_bios_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ uint32_t saved_nv_pextdev_boot_0; ++ bool was_locked; ++ int ret; ++ ++ dev_priv->vbios = &bios->pub; ++ ++ if (!NVInitVBIOS(dev)) ++ return -ENODEV; ++ ++ ret = nouveau_parse_vbios_struct(dev); ++ if (ret) ++ return ret; ++ ++ ret = parse_dcb_table(dev, bios, nv_two_heads(dev)); ++ if (ret) ++ return ret; ++ ++ fixup_legacy_i2c(bios); ++ fixup_legacy_connector(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(bios, NV_PEXTDEV_BOOT_0); ++ bios->state.saved_nv_pfb_cfg0 = bios_rd32(bios, NV_PFB_CFG0); ++ ++ /* init script execution disabled */ ++ bios->execute = false; ++ ++ /* ... unless card isn't POSTed already */ ++ if (dev_priv->card_type >= NV_10 && ++ NVReadVgaCrtc(dev, 0, 0x00) == 0 && ++ NVReadVgaCrtc(dev, 0, 0x1a) == 0) { ++ NV_INFO(dev, "Adaptor not initialised\n"); ++ if (dev_priv->card_type < NV_50) { ++ NV_ERROR(dev, "Unable to POST this chipset\n"); ++ return -ENODEV; ++ } ++ ++ NV_INFO(dev, "Running VBIOS init tables\n"); ++ bios->execute = true; ++ } ++ ++ bios_wr32(bios, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0); ++ ++ ret = nouveau_run_vbios_init(dev); ++ if (ret) { ++ dev_priv->vbios = NULL; ++ return ret; ++ } ++ ++ /* feature_byte on BMP is poor, but init always sets CR4B */ ++ was_locked = NVLockVgaCrtcs(dev, false); ++ if (bios->major_version < 5) ++ bios->is_mobile = NVReadVgaCrtc(dev, 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(dev, bios); ++ NVLockVgaCrtcs(dev, was_locked); ++ ++ /* allow subsequent scripts to execute */ ++ bios->execute = true; ++ ++ return 0; ++} ++ ++void ++nouveau_bios_takedown(struct drm_device *dev) ++{ ++ nouveau_bios_i2c_devices_takedown(dev); ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h +new file mode 100644 +index 0000000..1ffda97 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_bios.h +@@ -0,0 +1,236 @@ ++/* ++ * 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" ++#include "nouveau_i2c.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 connector; ++ 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; ++ struct { ++ bool has_component_output; ++ } tvconf; ++ }; ++ bool i2c_upper_default; ++}; ++ ++struct dcb_i2c_entry { ++ uint8_t port_type; ++ uint8_t read, write; ++ struct nouveau_i2c_chan *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 { ++ OUTPUT_ANALOG = 0, ++ OUTPUT_TV = 1, ++ OUTPUT_TMDS = 2, ++ OUTPUT_LVDS = 3, ++ OUTPUT_DP = 6, ++ OUTPUT_ANY = -1 ++}; ++ ++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; ++ uint32_t tvdactestval; ++ uint8_t digital_min_front_porch; ++ bool fp_no_ddc; ++}; ++ ++struct nvbios { ++ struct drm_device *dev; ++ 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; ++ ++ uint16_t some_script_ptr; /* BIT I + 14 */ ++ uint16_t init96_tbl_ptr; /* BIT I + 16 */ ++ ++ struct bios_parsed_dcb bdcb; ++ ++ struct { ++ int crtchead; ++ /* these need remembering across suspend */ ++ uint32_t saved_nv_pfb_cfg0; ++ } state; ++ ++ struct { ++ struct dcb_entry *output; ++ 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/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c +new file mode 100644 +index 0000000..8d1383a +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c +@@ -0,0 +1,663 @@ ++/* ++ * Copyright 2007 Dave Airlied ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. ++ */ ++/* ++ * Authors: Dave Airlied ++ * Ben Skeggs ++ * Jeremy Kolb ++ */ ++ ++#include "drmP.h" ++ ++#include "nouveau_drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++ ++static void ++nouveau_bo_del_ttm(struct ttm_buffer_object *bo) ++{ ++ struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); ++ struct nouveau_bo *nvbo = nouveau_bo(bo); ++ ++ ttm_bo_kunmap(&nvbo->kmap); ++ ++ if (unlikely(nvbo->gem)) ++ DRM_ERROR("bo %p still attached to GEM object\n", bo); ++ ++ spin_lock(&dev_priv->ttm.bo_list_lock); ++ list_del(&nvbo->head); ++ spin_unlock(&dev_priv->ttm.bo_list_lock); ++ kfree(nvbo); ++} ++ ++int ++nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, ++ int size, int align, uint32_t flags, uint32_t tile_mode, ++ uint32_t tile_flags, bool no_vm, bool mappable, ++ struct nouveau_bo **pnvbo) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_bo *nvbo; ++ int ret; ++ ++ nvbo = kzalloc(sizeof(struct nouveau_bo), GFP_KERNEL); ++ if (!nvbo) ++ return -ENOMEM; ++ INIT_LIST_HEAD(&nvbo->head); ++ INIT_LIST_HEAD(&nvbo->entry); ++ nvbo->mappable = mappable; ++ nvbo->no_vm = no_vm; ++ nvbo->tile_mode = tile_mode; ++ nvbo->tile_flags = tile_flags; ++ ++ if (!nvbo->mappable && (flags & TTM_PL_FLAG_VRAM)) ++ flags |= TTM_PL_FLAG_PRIV0; ++ ++ /* ++ * Some of the tile_flags have a periodic structure of N*4096 bytes, ++ * align to to that as well as the page size. Overallocate memory to ++ * avoid corruption of other buffer objects. ++ */ ++ switch (tile_flags) { ++ case 0x1800: ++ case 0x2800: ++ case 0x4800: ++ case 0x7a00: ++ if (dev_priv->chipset >= 0xA0) { ++ /* This is based on high end cards with 448 bits ++ * memory bus, could be different elsewhere.*/ ++ size += 6 * 28672; ++ /* 8 * 28672 is the actual alignment requirement, ++ * but we must also align to page size. */ ++ align = 2 * 8 * 28672; ++ } else if (dev_priv->chipset >= 0x90) { ++ size += 3 * 16384; ++ align = 12 * 16834; ++ } else { ++ size += 3 * 8192; ++ /* 12 * 8192 is the actual alignment requirement, ++ * but we must also align to page size. */ ++ align = 2 * 12 * 8192; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ align >>= PAGE_SHIFT; ++ ++ size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); ++ if (dev_priv->card_type == NV_50) { ++ size = (size + 65535) & ~65535; ++ if (align < (65536 / PAGE_SIZE)) ++ align = (65536 / PAGE_SIZE); ++ } ++ ++ nvbo->channel = chan; ++ ret = ttm_buffer_object_init(&dev_priv->ttm.bdev, &nvbo->bo, size, ++ ttm_bo_type_device, flags, align, ++ 0, false, NULL, size, nouveau_bo_del_ttm); ++ nvbo->channel = NULL; ++ if (ret) { ++ /* ttm will call nouveau_bo_del_ttm if it fails.. */ ++ return ret; ++ } ++ ++ spin_lock(&dev_priv->ttm.bo_list_lock); ++ list_add_tail(&nvbo->head, &dev_priv->ttm.bo_list); ++ spin_unlock(&dev_priv->ttm.bo_list_lock); ++ *pnvbo = nvbo; ++ return 0; ++} ++ ++int ++nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype) ++{ ++ struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); ++ struct ttm_buffer_object *bo = &nvbo->bo; ++ int ret; ++ ++ if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) { ++ NV_ERROR(nouveau_bdev(bo->bdev)->dev, ++ "bo %p pinned elsewhere: 0x%08x vs 0x%08x\n", bo, ++ 1 << bo->mem.mem_type, memtype); ++ return -EINVAL; ++ } ++ ++ if (nvbo->pin_refcnt++) ++ return 0; ++ ++ bo->proposed_placement &= ~TTM_PL_MASK_MEM; ++ bo->proposed_placement |= (memtype & TTM_PL_MASK_MEM); ++ bo->proposed_placement |= TTM_PL_FLAG_NO_EVICT; ++ ++ ret = ttm_bo_reserve(bo, false, false, false, 0); ++ if (ret) ++ goto out; ++ ++ ret = ttm_buffer_object_validate(bo, bo->proposed_placement, ++ false, false); ++ if (ret == 0) { ++ switch (bo->mem.mem_type) { ++ case TTM_PL_VRAM: ++ case TTM_PL_PRIV0: ++ dev_priv->fb_aper_free -= bo->mem.size; ++ break; ++ case TTM_PL_TT: ++ dev_priv->gart_info.aper_free -= bo->mem.size; ++ break; ++ default: ++ break; ++ } ++ } ++ ttm_bo_unreserve(bo); ++out: ++ if (unlikely(ret)) ++ nvbo->pin_refcnt--; ++ return ret; ++} ++ ++int ++nouveau_bo_unpin(struct nouveau_bo *nvbo) ++{ ++ struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); ++ struct ttm_buffer_object *bo = &nvbo->bo; ++ int ret; ++ ++ if (--nvbo->pin_refcnt) ++ return 0; ++ ++ bo->proposed_placement &= ~TTM_PL_FLAG_NO_EVICT; ++ ++ ret = ttm_bo_reserve(bo, false, false, false, 0); ++ if (ret) ++ return ret; ++ ++ ret = ttm_buffer_object_validate(bo, bo->proposed_placement, ++ false, false); ++ if (ret == 0) { ++ switch (bo->mem.mem_type) { ++ case TTM_PL_VRAM: ++ case TTM_PL_PRIV0: ++ dev_priv->fb_aper_free += bo->mem.size; ++ break; ++ case TTM_PL_TT: ++ dev_priv->gart_info.aper_free += bo->mem.size; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ ttm_bo_unreserve(bo); ++ return ret; ++} ++ ++int ++nouveau_bo_map(struct nouveau_bo *nvbo) ++{ ++ int ret; ++ ++ ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0); ++ if (ret) ++ return ret; ++ ++ ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.mem.num_pages, &nvbo->kmap); ++ ttm_bo_unreserve(&nvbo->bo); ++ return ret; ++} ++ ++void ++nouveau_bo_unmap(struct nouveau_bo *nvbo) ++{ ++ ttm_bo_kunmap(&nvbo->kmap); ++} ++ ++u16 ++nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index) ++{ ++ bool is_iomem; ++ u16 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem); ++ mem = &mem[index]; ++ if (is_iomem) ++ return ioread16_native((void __force __iomem *)mem); ++ else ++ return *mem; ++} ++ ++void ++nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val) ++{ ++ bool is_iomem; ++ u16 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem); ++ mem = &mem[index]; ++ if (is_iomem) ++ iowrite16_native(val, (void __force __iomem *)mem); ++ else ++ *mem = val; ++} ++ ++u32 ++nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index) ++{ ++ bool is_iomem; ++ u32 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem); ++ mem = &mem[index]; ++ if (is_iomem) ++ return ioread32_native((void __force __iomem *)mem); ++ else ++ return *mem; ++} ++ ++void ++nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val) ++{ ++ bool is_iomem; ++ u32 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem); ++ mem = &mem[index]; ++ if (is_iomem) ++ iowrite32_native(val, (void __force __iomem *)mem); ++ else ++ *mem = val; ++} ++ ++static struct ttm_backend * ++nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev) ++{ ++ struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev); ++ struct drm_device *dev = dev_priv->dev; ++ ++ switch (dev_priv->gart_info.type) { ++ case NOUVEAU_GART_AGP: ++ return ttm_agp_backend_init(bdev, dev->agp->bridge); ++ case NOUVEAU_GART_SGDMA: ++ return nouveau_sgdma_init_ttm(dev); ++ default: ++ NV_ERROR(dev, "Unknown GART type %d\n", ++ dev_priv->gart_info.type); ++ break; ++ } ++ ++ return NULL; ++} ++ ++static int ++nouveau_bo_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags) ++{ ++ /* We'll do this from user space. */ ++ return 0; ++} ++ ++static int ++nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, ++ struct ttm_mem_type_manager *man) ++{ ++ struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev); ++ struct drm_device *dev = dev_priv->dev; ++ ++ switch (type) { ++ case TTM_PL_SYSTEM: ++ man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; ++ man->available_caching = TTM_PL_MASK_CACHING; ++ man->default_caching = TTM_PL_FLAG_CACHED; ++ break; ++ case TTM_PL_VRAM: ++ man->flags = TTM_MEMTYPE_FLAG_FIXED | ++ TTM_MEMTYPE_FLAG_MAPPABLE | ++ TTM_MEMTYPE_FLAG_NEEDS_IOREMAP; ++ man->available_caching = TTM_PL_FLAG_UNCACHED | ++ TTM_PL_FLAG_WC; ++ man->default_caching = TTM_PL_FLAG_WC; ++ ++ man->io_addr = NULL; ++ man->io_offset = drm_get_resource_start(dev, 1); ++ man->io_size = drm_get_resource_len(dev, 1); ++ if (man->io_size > nouveau_mem_fb_amount(dev)) ++ man->io_size = nouveau_mem_fb_amount(dev); ++ ++ man->gpu_offset = dev_priv->vm_vram_base; ++ break; ++ case TTM_PL_PRIV0: /* Unmappable VRAM */ ++ man->flags = TTM_MEMTYPE_FLAG_CMA; ++ man->available_caching = ++ man->default_caching = 0; ++ break; ++ case TTM_PL_TT: ++ switch (dev_priv->gart_info.type) { ++ case NOUVEAU_GART_AGP: ++ man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | ++ TTM_MEMTYPE_FLAG_NEEDS_IOREMAP; ++ man->available_caching = TTM_PL_FLAG_UNCACHED; ++ man->default_caching = TTM_PL_FLAG_UNCACHED; ++ break; ++ case NOUVEAU_GART_SGDMA: ++ man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | ++ TTM_MEMTYPE_FLAG_CMA; ++ man->available_caching = TTM_PL_MASK_CACHING; ++ man->default_caching = TTM_PL_FLAG_CACHED; ++ break; ++ default: ++ NV_ERROR(dev, "Unknown GART type: %d\n", ++ dev_priv->gart_info.type); ++ return -EINVAL; ++ } ++ ++ man->io_offset = dev_priv->gart_info.aper_base; ++ man->io_size = dev_priv->gart_info.aper_size; ++ man->io_addr = NULL; ++ man->gpu_offset = dev_priv->vm_gart_base; ++ break; ++ default: ++ NV_ERROR(dev, "Unsupported memory type %u\n", (unsigned)type); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static uint32_t ++nouveau_bo_evict_flags(struct ttm_buffer_object *bo) ++{ ++ uint32_t placement = bo->mem.placement & ~TTM_PL_MASK_MEMTYPE; ++ ++ switch (bo->mem.mem_type) { ++ default: ++ return (placement & ~TTM_PL_MASK_CACHING) | ++ TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED; ++ } ++ ++ return 0; ++} ++ ++ ++/* GPU-assisted copy using NV_MEMORY_TO_MEMORY_FORMAT, can access ++ * TTM_PL_{VRAM,PRIV0,TT} directly. ++ */ ++static int ++nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, ++ struct nouveau_bo *nvbo, bool evict, bool no_wait, ++ struct ttm_mem_reg *new_mem) ++{ ++ struct nouveau_fence *fence = NULL; ++ int ret; ++ ++ ret = nouveau_fence_new(chan, &fence, true); ++ if (ret) ++ return ret; ++ ++ ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL, ++ evict, no_wait, new_mem); ++ nouveau_fence_unref((void *)&fence); ++ return ret; ++} ++ ++static inline uint32_t ++nouveau_bo_mem_ctxdma(struct nouveau_bo *nvbo, struct nouveau_channel *chan, ++ struct ttm_mem_reg *mem) ++{ ++ if (chan == nouveau_bdev(nvbo->bo.bdev)->channel) { ++ if (mem->mem_type == TTM_PL_TT) ++ return NvDmaGART; ++ return NvDmaVRAM; ++ } ++ ++ if (mem->mem_type == TTM_PL_TT) ++ return chan->gart_handle; ++ return chan->vram_handle; ++} ++ ++static int ++nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, int no_wait, ++ struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem) ++{ ++ struct nouveau_bo *nvbo = nouveau_bo(bo); ++ struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); ++ struct nouveau_channel *chan; ++ uint64_t src_offset, dst_offset; ++ uint32_t page_count; ++ int ret; ++ ++ chan = nvbo->channel; ++ if (!chan || nvbo->tile_flags || nvbo->no_vm) { ++ chan = dev_priv->channel; ++ if (!chan) ++ return -EINVAL; ++ } ++ ++ src_offset = old_mem->mm_node->start << PAGE_SHIFT; ++ dst_offset = new_mem->mm_node->start << PAGE_SHIFT; ++ if (chan != dev_priv->channel) { ++ if (old_mem->mem_type == TTM_PL_TT) ++ src_offset += dev_priv->vm_gart_base; ++ else ++ src_offset += dev_priv->vm_vram_base; ++ ++ if (new_mem->mem_type == TTM_PL_TT) ++ dst_offset += dev_priv->vm_gart_base; ++ else ++ dst_offset += dev_priv->vm_vram_base; ++ } ++ ++ ret = RING_SPACE(chan, 3); ++ if (ret) ++ return ret; ++ BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE, 2); ++ OUT_RING(chan, nouveau_bo_mem_ctxdma(nvbo, chan, old_mem)); ++ OUT_RING(chan, nouveau_bo_mem_ctxdma(nvbo, chan, new_mem)); ++ ++ if (dev_priv->card_type >= NV_50) { ++ ret = RING_SPACE(chan, 4); ++ if (ret) ++ return ret; ++ BEGIN_RING(chan, NvSubM2MF, 0x0200, 1); ++ OUT_RING(chan, 1); ++ BEGIN_RING(chan, NvSubM2MF, 0x021c, 1); ++ OUT_RING(chan, 1); ++ } ++ ++ page_count = new_mem->num_pages; ++ while (page_count) { ++ int line_count = (page_count > 2047) ? 2047 : page_count; ++ ++ if (dev_priv->card_type >= NV_50) { ++ ret = RING_SPACE(chan, 3); ++ if (ret) ++ return ret; ++ BEGIN_RING(chan, NvSubM2MF, 0x0238, 2); ++ OUT_RING(chan, upper_32_bits(src_offset)); ++ OUT_RING(chan, upper_32_bits(dst_offset)); ++ } ++ ret = RING_SPACE(chan, 11); ++ if (ret) ++ return ret; ++ BEGIN_RING(chan, NvSubM2MF, ++ NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); ++ OUT_RING(chan, lower_32_bits(src_offset)); ++ OUT_RING(chan, lower_32_bits(dst_offset)); ++ OUT_RING(chan, PAGE_SIZE); /* src_pitch */ ++ OUT_RING(chan, PAGE_SIZE); /* dst_pitch */ ++ OUT_RING(chan, PAGE_SIZE); /* line_length */ ++ OUT_RING(chan, line_count); ++ OUT_RING(chan, (1<<8)|(1<<0)); ++ OUT_RING(chan, 0); ++ BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1); ++ OUT_RING(chan, 0); ++ ++ page_count -= line_count; ++ src_offset += (PAGE_SIZE * line_count); ++ dst_offset += (PAGE_SIZE * line_count); ++ } ++ ++ return nouveau_bo_move_accel_cleanup(chan, nvbo, evict, no_wait, new_mem); ++} ++ ++static int ++nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, ++ bool no_wait, struct ttm_mem_reg *new_mem) ++{ ++ struct ttm_mem_reg tmp_mem; ++ int ret; ++ ++ tmp_mem = *new_mem; ++ tmp_mem.mm_node = NULL; ++ ret = ttm_bo_mem_space(bo, TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING, ++ &tmp_mem, intr, no_wait); ++ if (ret) ++ return ret; ++ ++ ret = ttm_tt_bind(bo->ttm, &tmp_mem); ++ if (ret) ++ goto out; ++ ++ ret = nouveau_bo_move_m2mf(bo, true, no_wait, &bo->mem, &tmp_mem); ++ if (ret) ++ goto out; ++ ++ ret = ttm_bo_move_ttm(bo, evict, no_wait, new_mem); ++out: ++ if (tmp_mem.mm_node) { ++ spin_lock(&bo->bdev->glob->lru_lock); ++ drm_mm_put_block(tmp_mem.mm_node); ++ spin_unlock(&bo->bdev->glob->lru_lock); ++ } ++ ++ return ret; ++} ++ ++static int ++nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, ++ bool no_wait, struct ttm_mem_reg *new_mem) ++{ ++ struct ttm_mem_reg tmp_mem; ++ int ret; ++ ++ tmp_mem = *new_mem; ++ tmp_mem.mm_node = NULL; ++ ret = ttm_bo_mem_space(bo, TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING, ++ &tmp_mem, intr, no_wait); ++ if (ret) ++ return ret; ++ ++ ret = ttm_bo_move_ttm(bo, evict, no_wait, &tmp_mem); ++ if (ret) ++ goto out; ++ ++ ret = nouveau_bo_move_m2mf(bo, true, no_wait, &bo->mem, new_mem); ++ if (ret) ++ goto out; ++ ++out: ++ if (tmp_mem.mm_node) { ++ spin_lock(&bo->bdev->glob->lru_lock); ++ drm_mm_put_block(tmp_mem.mm_node); ++ spin_unlock(&bo->bdev->glob->lru_lock); ++ } ++ ++ return ret; ++} ++ ++static int ++nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, ++ bool no_wait, struct ttm_mem_reg *new_mem) ++{ ++ struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); ++ struct nouveau_bo *nvbo = nouveau_bo(bo); ++ struct drm_device *dev = dev_priv->dev; ++ struct ttm_mem_reg *old_mem = &bo->mem; ++ int ret; ++ ++ if (dev_priv->card_type == NV_50 && ++ (new_mem->mem_type == TTM_PL_VRAM || ++ new_mem->mem_type == TTM_PL_PRIV0) && !nvbo->no_vm) { ++ uint64_t offset = new_mem->mm_node->start << PAGE_SHIFT; ++ ++ ret = nv50_mem_vm_bind_linear(dev, ++ offset + dev_priv->vm_vram_base, ++ new_mem->size, nvbo->tile_flags, ++ offset); ++ if (ret) ++ return ret; ++ } ++ ++ if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE) ++ return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); ++ ++ if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) { ++ BUG_ON(bo->mem.mm_node != NULL); ++ bo->mem = *new_mem; ++ new_mem->mm_node = NULL; ++ return 0; ++ } ++ ++ if (new_mem->mem_type == TTM_PL_SYSTEM) { ++ if (old_mem->mem_type == TTM_PL_SYSTEM) ++ return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); ++ if (nouveau_bo_move_flipd(bo, evict, intr, no_wait, new_mem)) ++ return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); ++ } else if (old_mem->mem_type == TTM_PL_SYSTEM) { ++ if (nouveau_bo_move_flips(bo, evict, intr, no_wait, new_mem)) ++ return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); ++ } else { ++ if (nouveau_bo_move_m2mf(bo, evict, no_wait, old_mem, new_mem)) ++ return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); ++ } ++ ++ return 0; ++} ++ ++static int ++nouveau_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp) ++{ ++ return 0; ++} ++ ++static uint32_t nouveau_mem_prios[] = { ++ TTM_PL_PRIV0, ++ TTM_PL_VRAM, ++ TTM_PL_TT, ++ TTM_PL_SYSTEM ++}; ++static uint32_t nouveau_busy_prios[] = { ++ TTM_PL_TT, ++ TTM_PL_PRIV0, ++ TTM_PL_VRAM, ++ TTM_PL_SYSTEM ++}; ++ ++struct ttm_bo_driver nouveau_bo_driver = { ++ .mem_type_prio = nouveau_mem_prios, ++ .mem_busy_prio = nouveau_busy_prios, ++ .num_mem_type_prio = ARRAY_SIZE(nouveau_mem_prios), ++ .num_mem_busy_prio = ARRAY_SIZE(nouveau_busy_prios), ++ .create_ttm_backend_entry = nouveau_bo_create_ttm_backend_entry, ++ .invalidate_caches = nouveau_bo_invalidate_caches, ++ .init_mem_type = nouveau_bo_init_mem_type, ++ .evict_flags = nouveau_bo_evict_flags, ++ .move = nouveau_bo_move, ++ .verify_access = nouveau_bo_verify_access, ++ .sync_obj_signaled = nouveau_fence_signalled, ++ .sync_obj_wait = nouveau_fence_wait, ++ .sync_obj_flush = nouveau_fence_flush, ++ .sync_obj_unref = nouveau_fence_unref, ++ .sync_obj_ref = nouveau_fence_ref, ++}; ++ +diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/nouveau_calc.c +new file mode 100644 +index 0000000..3f80db8 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_calc.c +@@ -0,0 +1,626 @@ ++/* ++ * 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 "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_hw.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, min_clwm; ++ 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--; ++ } ++ ++ /* This correction works around a slight snow effect ++ * when the TV and VGA outputs are enabled simultaneously. */ ++ min_clwm = 1024 - cbs + 128 * pclk_freq / 100000; ++ if (clwm < min_clwm) ++ clwm = min_clwm; ++ ++ /* 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; ++ } ++} ++ ++static void ++nv4_10UpdateArbitrationSettings(struct drm_device *dev, int VClk, int bpp, ++ int *burst, int *lwm) ++{ ++ struct nv_fifo_info fifo_data; ++ struct nv_sim_state sim_data; ++ int MClk = nouveau_hw_get_clock(dev, MPLL); ++ int NVClk = nouveau_hw_get_clock(dev, NVPLL); ++ uint32_t cfg1 = nvReadFB(dev, 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 ((dev->pci_device & 0xffff) == 0x01a0 /*CHIPSET_NFORCE*/ || ++ (dev->pci_device & 0xffff) == 0x01f0 /*CHIPSET_NFORCE2*/) { ++ uint32_t type; ++ ++ pci_read_config_dword(pci_get_bus_and_slot(0, 1), 0x7c, &type); ++ ++ sim_data.enable_video = false; ++ sim_data.memory_type = (type >> 12) & 1; ++ sim_data.memory_width = 64; ++ sim_data.mem_latency = 3; ++ sim_data.mem_page_miss = 10; ++ } else { ++ sim_data.enable_video = (nv_arch(dev) != NV_04); ++ sim_data.memory_type = nvReadFB(dev, NV_PFB_CFG0) & 0x1; ++ sim_data.memory_width = (nvReadEXTDEV(dev, 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 (nv_arch(dev) == NV_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; ++ } ++} ++ ++static 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(struct drm_device *dev, int vclk, int bpp, int *burst, int *lwm) ++{ ++ if (nv_arch(dev) < NV_30) ++ nv4_10UpdateArbitrationSettings(dev, vclk, bpp, burst, lwm); ++ else if ((dev->pci_device & 0xfff0) == 0x0240 /*CHIPSET_C51*/ || ++ (dev->pci_device & 0xfff0) == 0x03d0 /*CHIPSET_C512*/) { ++ *burst = 128; ++ *lwm = 0x0480; ++ } else ++ nv30UpdateArbitrationSettings(burst, lwm); ++} ++ ++static int ++getMNP_single(struct drm_device *dev, 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 ++ */ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int cv = dev_priv->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(struct drm_device *dev, 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 ++ */ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int chip_version = dev_priv->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(struct drm_device *dev, struct pll_lims *pll_lim, int clk, ++ struct nouveau_pll_vals *pv) ++{ ++ int outclk; ++ ++ if (!pll_lim->vco2.maxfreq) ++ outclk = getMNP_single(dev, pll_lim, clk, pv); ++ else ++ outclk = getMNP_double(dev, pll_lim, clk, pv); ++ ++ if (!outclk) ++ NV_ERROR(dev, "Could not find a compatible set of PLL values\n"); ++ ++ return outclk; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c +new file mode 100644 +index 0000000..9aaa972 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_channel.c +@@ -0,0 +1,468 @@ ++/* ++ * Copyright 2005-2006 Stephane Marchesin ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++#include "nouveau_dma.h" ++ ++static int ++nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_bo *pb = chan->pushbuf_bo; ++ struct nouveau_gpuobj *pushbuf = NULL; ++ uint32_t start = pb->bo.mem.mm_node->start << PAGE_SHIFT; ++ int ret; ++ ++ if (pb->bo.mem.mem_type == TTM_PL_TT) { ++ ret = nouveau_gpuobj_gart_dma_new(chan, 0, ++ dev_priv->gart_info.aper_size, ++ NV_DMA_ACCESS_RO, &pushbuf, ++ NULL); ++ chan->pushbuf_base = start; ++ } else ++ if (dev_priv->card_type != NV_04) { ++ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, ++ dev_priv->fb_available_size, ++ NV_DMA_ACCESS_RO, ++ NV_DMA_TARGET_VIDMEM, &pushbuf); ++ chan->pushbuf_base = start; ++ } else { ++ /* NV04 cmdbuf hack, from original ddx.. not sure of it's ++ * exact reason for existing :) PCI access to cmdbuf in ++ * VRAM. ++ */ ++ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, ++ drm_get_resource_start(dev, 1), ++ dev_priv->fb_available_size, ++ NV_DMA_ACCESS_RO, ++ NV_DMA_TARGET_PCI, &pushbuf); ++ chan->pushbuf_base = start; ++ } ++ ++ ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf); ++ if (ret) { ++ NV_ERROR(dev, "Error referencing pushbuf ctxdma: %d\n", ret); ++ if (pushbuf != dev_priv->gart_info.sg_ctxdma) ++ nouveau_gpuobj_del(dev, &pushbuf); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static struct nouveau_bo * ++nouveau_channel_user_pushbuf_alloc(struct drm_device *dev) ++{ ++ struct nouveau_bo *pushbuf = NULL; ++ int location, ret; ++ ++ if (nouveau_vram_pushbuf) ++ location = TTM_PL_FLAG_VRAM; ++ else ++ location = TTM_PL_FLAG_TT; ++ ++ ret = nouveau_bo_new(dev, NULL, 65536, 0, location, 0, 0x0000, false, ++ true, &pushbuf); ++ if (ret) { ++ NV_ERROR(dev, "error allocating DMA push buffer: %d\n", ret); ++ return NULL; ++ } ++ ++ ret = nouveau_bo_pin(pushbuf, location); ++ if (ret) { ++ NV_ERROR(dev, "error pinning DMA push buffer: %d\n", ret); ++ nouveau_bo_ref(NULL, &pushbuf); ++ return NULL; ++ } ++ ++ return pushbuf; ++} ++ ++/* allocates and initializes a fifo for user space consumption */ ++int ++nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, ++ struct drm_file *file_priv, ++ uint32_t vram_handle, uint32_t tt_handle) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; ++ struct nouveau_channel *chan; ++ int channel, user; ++ int ret; ++ ++ /* ++ * Alright, here is the full story ++ * Nvidia cards have multiple hw fifo contexts (praise them for that, ++ * no complicated crash-prone context switches) ++ * We allocate a new context for each app and let it write to it ++ * directly (woo, full userspace command submission !) ++ * When there are no more contexts, you lost ++ */ ++ for (channel = 0; channel < pfifo->channels; channel++) { ++ if (dev_priv->fifos[channel] == NULL) ++ break; ++ } ++ ++ /* no more fifos. you lost. */ ++ if (channel == pfifo->channels) ++ return -EINVAL; ++ ++ dev_priv->fifos[channel] = kzalloc(sizeof(struct nouveau_channel), ++ GFP_KERNEL); ++ if (!dev_priv->fifos[channel]) ++ return -ENOMEM; ++ dev_priv->fifo_alloc_count++; ++ chan = dev_priv->fifos[channel]; ++ INIT_LIST_HEAD(&chan->nvsw.vbl_wait); ++ INIT_LIST_HEAD(&chan->fence.pending); ++ chan->dev = dev; ++ chan->id = channel; ++ chan->file_priv = file_priv; ++ chan->vram_handle = vram_handle; ++ chan->gart_handle = tt_handle; ++ ++ NV_INFO(dev, "Allocating FIFO number %d\n", channel); ++ ++ /* Allocate DMA push buffer */ ++ chan->pushbuf_bo = nouveau_channel_user_pushbuf_alloc(dev); ++ if (!chan->pushbuf_bo) { ++ ret = -ENOMEM; ++ NV_ERROR(dev, "pushbuf %d\n", ret); ++ nouveau_channel_free(chan); ++ return ret; ++ } ++ ++ /* Locate channel's user control regs */ ++ if (dev_priv->card_type < NV_40) ++ user = NV03_USER(channel); ++ else ++ if (dev_priv->card_type < NV_50) ++ user = NV40_USER(channel); ++ else ++ user = NV50_USER(channel); ++ ++ chan->user = ioremap(pci_resource_start(dev->pdev, 0) + user, ++ PAGE_SIZE); ++ if (!chan->user) { ++ NV_ERROR(dev, "ioremap of regs failed.\n"); ++ nouveau_channel_free(chan); ++ return -ENOMEM; ++ } ++ chan->user_put = 0x40; ++ chan->user_get = 0x44; ++ ++ /* Allocate space for per-channel fixed notifier memory */ ++ ret = nouveau_notifier_init_channel(chan); ++ if (ret) { ++ NV_ERROR(dev, "ntfy %d\n", ret); ++ nouveau_channel_free(chan); ++ return ret; ++ } ++ ++ /* Setup channel's default objects */ ++ ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle); ++ if (ret) { ++ NV_ERROR(dev, "gpuobj %d\n", ret); ++ nouveau_channel_free(chan); ++ return ret; ++ } ++ ++ /* Create a dma object for the push buffer */ ++ ret = nouveau_channel_pushbuf_ctxdma_init(chan); ++ if (ret) { ++ NV_ERROR(dev, "pbctxdma %d\n", ret); ++ nouveau_channel_free(chan); ++ return ret; ++ } ++ ++ /* disable the fifo caches */ ++ pfifo->reassign(dev, false); ++ ++ /* Create a graphics context for new channel */ ++ ret = pgraph->create_context(chan); ++ if (ret) { ++ nouveau_channel_free(chan); ++ return ret; ++ } ++ ++ /* Construct inital RAMFC for new channel */ ++ ret = pfifo->create_context(chan); ++ if (ret) { ++ nouveau_channel_free(chan); ++ return ret; ++ } ++ ++ pfifo->reassign(dev, true); ++ ++ ret = nouveau_dma_init(chan); ++ if (!ret) ++ ret = nouveau_fence_init(chan); ++ if (ret) { ++ nouveau_channel_free(chan); ++ return ret; ++ } ++ ++ nouveau_debugfs_channel_init(chan); ++ ++ NV_INFO(dev, "%s: initialised FIFO %d\n", __func__, channel); ++ *chan_ret = chan; ++ return 0; ++} ++ ++int ++nouveau_channel_idle(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ uint32_t caches; ++ int idle; ++ ++ if (!chan) { ++ NV_ERROR(dev, "no channel...\n"); ++ return 1; ++ } ++ ++ caches = nv_rd32(dev, NV03_PFIFO_CACHES); ++ nv_wr32(dev, NV03_PFIFO_CACHES, caches & ~1); ++ ++ if (engine->fifo.channel_id(dev) != chan->id) { ++ struct nouveau_gpuobj *ramfc = ++ chan->ramfc ? chan->ramfc->gpuobj : NULL; ++ ++ if (!ramfc) { ++ NV_ERROR(dev, "No RAMFC for channel %d\n", chan->id); ++ return 1; ++ } ++ ++ engine->instmem.prepare_access(dev, false); ++ if (nv_ro32(dev, ramfc, 0) != nv_ro32(dev, ramfc, 1)) ++ idle = 0; ++ else ++ idle = 1; ++ engine->instmem.finish_access(dev); ++ } else { ++ idle = (nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET) == ++ nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); ++ } ++ ++ nv_wr32(dev, NV03_PFIFO_CACHES, caches); ++ return idle; ++} ++ ++/* stops a fifo */ ++void ++nouveau_channel_free(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; ++ unsigned long flags; ++ int ret; ++ ++ NV_INFO(dev, "%s: freeing fifo %d\n", __func__, chan->id); ++ ++ nouveau_debugfs_channel_fini(chan); ++ ++ /* Give outstanding push buffers a chance to complete */ ++ spin_lock_irqsave(&chan->fence.lock, flags); ++ nouveau_fence_update(chan); ++ spin_unlock_irqrestore(&chan->fence.lock, flags); ++ if (chan->fence.sequence != chan->fence.sequence_ack) { ++ struct nouveau_fence *fence = NULL; ++ ++ ret = nouveau_fence_new(chan, &fence, true); ++ if (ret == 0) { ++ ret = nouveau_fence_wait(fence, NULL, false, false); ++ nouveau_fence_unref((void *)&fence); ++ } ++ ++ if (ret) ++ NV_ERROR(dev, "Failed to idle channel %d.\n", chan->id); ++ } ++ ++ /* Ensure all outstanding fences are signaled. They should be if the ++ * above attempts at idling were OK, but if we failed this'll tell TTM ++ * we're done with the buffers. ++ */ ++ nouveau_fence_fini(chan); ++ ++ /* Ensure the channel is no longer active on the GPU */ ++ pfifo->reassign(dev, false); ++ ++ if (pgraph->channel(dev) == chan) { ++ pgraph->fifo_access(dev, false); ++ pgraph->unload_context(dev); ++ pgraph->fifo_access(dev, true); ++ } ++ pgraph->destroy_context(chan); ++ ++ if (pfifo->channel_id(dev) == chan->id) { ++ pfifo->disable(dev); ++ pfifo->unload_context(dev); ++ pfifo->enable(dev); ++ } ++ pfifo->destroy_context(chan); ++ ++ pfifo->reassign(dev, true); ++ ++ /* Release the channel's resources */ ++ nouveau_gpuobj_ref_del(dev, &chan->pushbuf); ++ if (chan->pushbuf_bo) { ++ nouveau_bo_unpin(chan->pushbuf_bo); ++ nouveau_bo_ref(NULL, &chan->pushbuf_bo); ++ } ++ nouveau_gpuobj_channel_takedown(chan); ++ nouveau_notifier_takedown_channel(chan); ++ if (chan->user) ++ iounmap(chan->user); ++ ++ dev_priv->fifos[chan->id] = NULL; ++ dev_priv->fifo_alloc_count--; ++ kfree(chan); ++} ++ ++/* cleans up all the fifos from file_priv */ ++void ++nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ int i; ++ ++ NV_DEBUG(dev, "clearing FIFO enables from file_priv\n"); ++ for (i = 0; i < engine->fifo.channels; i++) { ++ struct nouveau_channel *chan = dev_priv->fifos[i]; ++ ++ if (chan && chan->file_priv == file_priv) ++ nouveau_channel_free(chan); ++ } ++} ++ ++int ++nouveau_channel_owner(struct drm_device *dev, struct drm_file *file_priv, ++ int channel) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ ++ if (channel >= engine->fifo.channels) ++ return 0; ++ if (dev_priv->fifos[channel] == NULL) ++ return 0; ++ ++ return (dev_priv->fifos[channel]->file_priv == file_priv); ++} ++ ++/*********************************** ++ * ioctls wrapping the functions ++ ***********************************/ ++ ++static int ++nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_nouveau_channel_alloc *init = data; ++ struct nouveau_channel *chan; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ if (dev_priv->engine.graph.accel_blocked) ++ return -ENODEV; ++ ++ if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) ++ return -EINVAL; ++ ++ ret = nouveau_channel_alloc(dev, &chan, file_priv, ++ init->fb_ctxdma_handle, ++ init->tt_ctxdma_handle); ++ if (ret) ++ return ret; ++ init->channel = chan->id; ++ ++ init->subchan[0].handle = NvM2MF; ++ if (dev_priv->card_type < NV_50) ++ init->subchan[0].grclass = 0x0039; ++ else ++ init->subchan[0].grclass = 0x5039; ++ init->nr_subchan = 1; ++ ++ /* Named memory object area */ ++ ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem, ++ &init->notifier_handle); ++ if (ret) { ++ nouveau_channel_free(chan); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ++nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_channel_free *cfree = data; ++ struct nouveau_channel *chan; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan); ++ ++ nouveau_channel_free(chan); ++ return 0; ++} ++ ++/*********************************** ++ * finally, the ioctl table ++ ***********************************/ ++ ++struct drm_ioctl_desc nouveau_ioctls[] = { ++ DRM_IOCTL_DEF(DRM_NOUVEAU_CARD_INIT, nouveau_ioctl_card_init, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL, nouveau_gem_ioctl_pushbuf_call, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PIN, nouveau_gem_ioctl_pin, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_UNPIN, nouveau_gem_ioctl_unpin, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL2, nouveau_gem_ioctl_pushbuf_call2, DRM_AUTH), ++}; ++ ++int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); +diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c +new file mode 100644 +index 0000000..1e40ef0 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_connector.c +@@ -0,0 +1,811 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm_edid.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_reg.h" ++#include "nouveau_drv.h" ++#include "nouveau_encoder.h" ++#include "nouveau_crtc.h" ++#include "nouveau_connector.h" ++#include "nouveau_hw.h" ++ ++static inline struct drm_encoder_slave_funcs * ++get_slave_funcs(struct nouveau_encoder *enc) ++{ ++ return to_encoder_slave(to_drm_encoder(enc))->slave_funcs; ++} ++ ++static struct nouveau_encoder * ++find_encoder_by_type(struct drm_connector *connector, int type) ++{ ++ struct drm_device *dev = connector->dev; ++ struct nouveau_encoder *nv_encoder; ++ struct drm_mode_object *obj; ++ int i, id; ++ ++ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { ++ id = connector->encoder_ids[i]; ++ if (!id) ++ break; ++ ++ obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); ++ if (!obj) ++ continue; ++ nv_encoder = nouveau_encoder(obj_to_encoder(obj)); ++ ++ if (type == OUTPUT_ANY || nv_encoder->dcb->type == type) ++ return nv_encoder; ++ } ++ ++ return NULL; ++} ++ ++struct nouveau_connector * ++nouveau_encoder_connector_get(struct nouveau_encoder *encoder) ++{ ++ struct drm_device *dev = to_drm_encoder(encoder)->dev; ++ struct drm_connector *drm_connector; ++ ++ list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) { ++ if (drm_connector->encoder == to_drm_encoder(encoder)) ++ return nouveau_connector(drm_connector); ++ } ++ ++ return NULL; ++} ++ ++ ++static void ++nouveau_connector_destroy(struct drm_connector *drm_connector) ++{ ++ struct nouveau_connector *connector = nouveau_connector(drm_connector); ++ struct drm_device *dev = connector->base.dev; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (!connector) ++ return; ++ ++ drm_sysfs_connector_remove(drm_connector); ++ drm_connector_cleanup(drm_connector); ++ kfree(drm_connector); ++} ++ ++static void ++nouveau_connector_ddc_prepare(struct drm_connector *connector, int *flags) ++{ ++ struct drm_nouveau_private *dev_priv = connector->dev->dev_private; ++ ++ if (dev_priv->card_type >= NV_50) ++ return; ++ ++ *flags = 0; ++ if (NVLockVgaCrtcs(dev_priv->dev, false)) ++ *flags |= 1; ++ if (nv_heads_tied(dev_priv->dev)) ++ *flags |= 2; ++ ++ if (*flags & 2) ++ NVSetOwner(dev_priv->dev, 0); /* necessary? */ ++} ++ ++static void ++nouveau_connector_ddc_finish(struct drm_connector *connector, int flags) ++{ ++ struct drm_nouveau_private *dev_priv = connector->dev->dev_private; ++ ++ if (dev_priv->card_type >= NV_50) ++ return; ++ ++ if (flags & 2) ++ NVSetOwner(dev_priv->dev, 4); ++ if (flags & 1) ++ NVLockVgaCrtcs(dev_priv->dev, true); ++} ++ ++static struct nouveau_i2c_chan * ++nouveau_connector_ddc_detect(struct drm_connector *connector, ++ struct nouveau_encoder **pnv_encoder) ++{ ++ struct drm_device *dev = connector->dev; ++ uint8_t out_buf[] = { 0x0, 0x0}, buf[2]; ++ int ret, flags, i; ++ ++ struct i2c_msg msgs[] = { ++ { ++ .addr = 0x50, ++ .flags = 0, ++ .len = 1, ++ .buf = out_buf, ++ }, ++ { ++ .addr = 0x50, ++ .flags = I2C_M_RD, ++ .len = 1, ++ .buf = buf, ++ } ++ }; ++ ++ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { ++ struct nouveau_i2c_chan *i2c = NULL; ++ struct nouveau_encoder *nv_encoder; ++ struct drm_mode_object *obj; ++ int id; ++ ++ id = connector->encoder_ids[i]; ++ if (!id) ++ break; ++ ++ obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); ++ if (!obj) ++ continue; ++ nv_encoder = nouveau_encoder(obj_to_encoder(obj)); ++ ++ if (nv_encoder->dcb->i2c_index < 0xf) ++ i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); ++ if (!i2c) ++ continue; ++ ++ nouveau_connector_ddc_prepare(connector, &flags); ++ ret = i2c_transfer(&i2c->adapter, msgs, 2); ++ nouveau_connector_ddc_finish(connector, flags); ++ ++ if (ret == 2) { ++ *pnv_encoder = nv_encoder; ++ return i2c; ++ } ++ } ++ ++ return NULL; ++} ++ ++static void ++nouveau_connector_set_encoder(struct drm_connector *connector, ++ struct nouveau_encoder *nv_encoder) ++{ ++ struct nouveau_connector *nv_connector = nouveau_connector(connector); ++ struct drm_nouveau_private *dev_priv = connector->dev->dev_private; ++ struct drm_device *dev = connector->dev; ++ ++ if (nv_connector->detected_encoder == nv_encoder) ++ return; ++ nv_connector->detected_encoder = nv_encoder; ++ ++ if (nv_encoder->dcb->type == OUTPUT_LVDS || ++ nv_encoder->dcb->type == OUTPUT_TMDS) { ++ connector->doublescan_allowed = false; ++ connector->interlace_allowed = false; ++ } else { ++ connector->doublescan_allowed = true; ++ if (dev_priv->card_type == NV_20 || ++ (dev_priv->card_type == NV_10 && ++ (dev->pci_device & 0x0ff0) != 0x0100 && ++ (dev->pci_device & 0x0ff0) != 0x0150)) ++ /* HW is broken */ ++ connector->interlace_allowed = false; ++ else ++ connector->interlace_allowed = true; ++ } ++ ++ if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) { ++ drm_connector_property_set_value(connector, ++ dev->mode_config.dvi_i_subconnector_property, ++ nv_encoder->dcb->type == OUTPUT_TMDS ? ++ DRM_MODE_SUBCONNECTOR_DVID : ++ DRM_MODE_SUBCONNECTOR_DVIA); ++ } ++} ++ ++static enum drm_connector_status ++nouveau_connector_detect(struct drm_connector *connector) ++{ ++ struct drm_device *dev = connector->dev; ++ struct nouveau_connector *nv_connector = nouveau_connector(connector); ++ struct nouveau_encoder *nv_encoder = NULL; ++ struct nouveau_i2c_chan *i2c; ++ int type, flags; ++ ++ if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) ++ nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); ++ if (nv_encoder && nv_connector->native_mode) { ++ nouveau_connector_set_encoder(connector, nv_encoder); ++ return connector_status_connected; ++ } ++ ++ i2c = nouveau_connector_ddc_detect(connector, &nv_encoder); ++ if (i2c) { ++ nouveau_connector_ddc_prepare(connector, &flags); ++ nv_connector->edid = drm_get_edid(connector, &i2c->adapter); ++ nouveau_connector_ddc_finish(connector, flags); ++ drm_mode_connector_update_edid_property(connector, ++ nv_connector->edid); ++ if (!nv_connector->edid) { ++ NV_ERROR(dev, "DDC responded, but no EDID for %s\n", ++ drm_get_connector_name(connector)); ++ return connector_status_disconnected; ++ } else ++ if (nv_encoder->dcb->type == OUTPUT_DP) { ++ NV_ERROR(dev, "Detected DP connected, ignoring!\n"); ++ return connector_status_disconnected; ++ } ++ ++ /* Override encoder type for DVI-I based on whether EDID ++ * says the display is digital or analog, both use the ++ * same i2c channel so the value returned from ddc_detect ++ * isn't necessarily correct. ++ */ ++ if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) { ++ if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL) ++ type = OUTPUT_TMDS; ++ else ++ type = OUTPUT_ANALOG; ++ ++ nv_encoder = find_encoder_by_type(connector, type); ++ if (!nv_encoder) { ++ NV_ERROR(dev, "Detected %d encoder on %s, " ++ "but no object!\n", type, ++ drm_get_connector_name(connector)); ++ return connector_status_disconnected; ++ } ++ } ++ ++ nouveau_connector_set_encoder(connector, nv_encoder); ++ return connector_status_connected; ++ } ++ ++ nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG); ++ if (!nv_encoder) ++ nv_encoder = find_encoder_by_type(connector, OUTPUT_TV); ++ if (nv_encoder) { ++ struct drm_encoder *encoder = to_drm_encoder(nv_encoder); ++ struct drm_encoder_helper_funcs *helper = ++ encoder->helper_private; ++ ++ if (helper->detect(encoder, connector) == ++ connector_status_connected) { ++ nouveau_connector_set_encoder(connector, nv_encoder); ++ return connector_status_connected; ++ } ++ ++ } ++ ++ return connector_status_disconnected; ++} ++ ++static void ++nouveau_connector_force(struct drm_connector *connector) ++{ ++ struct drm_device *dev = connector->dev; ++ struct nouveau_encoder *nv_encoder; ++ int type; ++ ++ if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) { ++ if (connector->force == DRM_FORCE_ON_DIGITAL) ++ type = OUTPUT_TMDS; ++ else ++ type = OUTPUT_ANALOG; ++ } else ++ type = OUTPUT_ANY; ++ ++ nv_encoder = find_encoder_by_type(connector, type); ++ if (!nv_encoder) { ++ NV_ERROR(dev, "can't find encoder to force %s on!\n", ++ drm_get_connector_name(connector)); ++ connector->status = connector_status_disconnected; ++ return; ++ } ++ ++ nouveau_connector_set_encoder(connector, nv_encoder); ++} ++ ++static int ++nouveau_connector_set_property(struct drm_connector *connector, ++ struct drm_property *property, uint64_t value) ++{ ++ struct nouveau_connector *nv_connector = nouveau_connector(connector); ++ struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; ++ struct drm_device *dev = connector->dev; ++ int ret; ++ ++ /* Scaling mode */ ++ if (property == dev->mode_config.scaling_mode_property) { ++ struct nouveau_crtc *nv_crtc = NULL; ++ bool modeset = false; ++ ++ switch (value) { ++ case DRM_MODE_SCALE_NONE: ++ case DRM_MODE_SCALE_FULLSCREEN: ++ case DRM_MODE_SCALE_CENTER: ++ case DRM_MODE_SCALE_ASPECT: ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* LVDS always needs gpu scaling */ ++ if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS && ++ value == DRM_MODE_SCALE_NONE) ++ return -EINVAL; ++ ++ /* Changing between GPU and panel scaling requires a full ++ * modeset ++ */ ++ if ((nv_connector->scaling_mode == DRM_MODE_SCALE_NONE) || ++ (value == DRM_MODE_SCALE_NONE)) ++ modeset = true; ++ nv_connector->scaling_mode = value; ++ ++ if (connector->encoder && connector->encoder->crtc) ++ nv_crtc = nouveau_crtc(connector->encoder->crtc); ++ if (!nv_crtc) ++ return 0; ++ ++ if (modeset || !nv_crtc->set_scale) { ++ ret = drm_crtc_helper_set_mode(&nv_crtc->base, ++ &nv_crtc->base.mode, ++ nv_crtc->base.x, ++ nv_crtc->base.y, NULL); ++ if (!ret) ++ return -EINVAL; ++ } else { ++ ret = nv_crtc->set_scale(nv_crtc, value, true); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++ } ++ ++ /* Dithering */ ++ if (property == dev->mode_config.dithering_mode_property) { ++ struct nouveau_crtc *nv_crtc = NULL; ++ ++ if (value == DRM_MODE_DITHERING_ON) ++ nv_connector->use_dithering = true; ++ else ++ nv_connector->use_dithering = false; ++ ++ if (connector->encoder && connector->encoder->crtc) ++ nv_crtc = nouveau_crtc(connector->encoder->crtc); ++ ++ if (!nv_crtc || !nv_crtc->set_dither) ++ return 0; ++ ++ return nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, ++ true); ++ } ++ ++ if (nv_encoder && nv_encoder->dcb->type == OUTPUT_TV) ++ return get_slave_funcs(nv_encoder)-> ++ set_property(to_drm_encoder(nv_encoder), connector, property, value); ++ ++ return -EINVAL; ++} ++ ++static struct drm_display_mode * ++nouveau_connector_native_mode(struct nouveau_connector *connector) ++{ ++ struct drm_device *dev = connector->base.dev; ++ struct drm_display_mode *mode, *largest = NULL; ++ int high_w = 0, high_h = 0, high_v = 0; ++ ++ /* Use preferred mode if there is one.. */ ++ list_for_each_entry(mode, &connector->base.probed_modes, head) { ++ if (mode->type & DRM_MODE_TYPE_PREFERRED) { ++ NV_DEBUG(dev, "native mode from preferred\n"); ++ return drm_mode_duplicate(dev, mode); ++ } ++ } ++ ++ /* Otherwise, take the resolution with the largest width, then height, ++ * then vertical refresh ++ */ ++ list_for_each_entry(mode, &connector->base.probed_modes, head) { ++ if (mode->hdisplay < high_w) ++ continue; ++ ++ if (mode->hdisplay == high_w && mode->vdisplay < high_h) ++ continue; ++ ++ if (mode->hdisplay == high_w && mode->vdisplay == high_h && ++ mode->vrefresh < high_v) ++ continue; ++ ++ high_w = mode->hdisplay; ++ high_h = mode->vdisplay; ++ high_v = mode->vrefresh; ++ largest = mode; ++ } ++ ++ NV_DEBUG(dev, "native mode from largest: %dx%d@%d\n", ++ high_w, high_h, high_v); ++ return largest ? drm_mode_duplicate(dev, largest) : NULL; ++} ++ ++struct moderec { ++ int hdisplay; ++ int vdisplay; ++}; ++ ++static struct moderec scaler_modes[] = { ++ { 1920, 1200 }, ++ { 1920, 1080 }, ++ { 1680, 1050 }, ++ { 1600, 1200 }, ++ { 1400, 1050 }, ++ { 1280, 1024 }, ++ { 1280, 960 }, ++ { 1152, 864 }, ++ { 1024, 768 }, ++ { 800, 600 }, ++ { 720, 400 }, ++ { 640, 480 }, ++ { 640, 400 }, ++ { 640, 350 }, ++ {} ++}; ++ ++static int ++nouveau_connector_scaler_modes_add(struct drm_connector *connector) ++{ ++ struct nouveau_connector *nv_connector = nouveau_connector(connector); ++ struct drm_display_mode *native = nv_connector->native_mode, *m; ++ struct drm_device *dev = connector->dev; ++ struct moderec *mode = &scaler_modes[0]; ++ int modes = 0; ++ ++ if (!native) ++ return 0; ++ ++ while (mode->hdisplay) { ++ if (mode->hdisplay <= native->hdisplay && ++ mode->vdisplay <= native->vdisplay) { ++ m = drm_cvt_mode(dev, mode->hdisplay, mode->vdisplay, ++ drm_mode_vrefresh(native), false, ++ false, false); ++ if (!m) ++ continue; ++ ++ m->type |= DRM_MODE_TYPE_DRIVER; ++ ++ drm_mode_probed_add(connector, m); ++ modes++; ++ } ++ ++ mode++; ++ } ++ ++ return modes; ++} ++ ++static int ++nouveau_connector_get_modes(struct drm_connector *connector) ++{ ++ struct drm_device *dev = connector->dev; ++ struct nouveau_connector *nv_connector = nouveau_connector(connector); ++ struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; ++ int ret = 0; ++ ++ /* If we're not LVDS, destroy the previous native mode, the attached ++ * monitor could have changed. ++ */ ++ if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && ++ nv_connector->native_mode) { ++ drm_mode_destroy(dev, nv_connector->native_mode); ++ nv_connector->native_mode = NULL; ++ } ++ ++ if (nv_connector->edid) ++ ret = drm_add_edid_modes(connector, nv_connector->edid); ++ ++ /* Find the native mode if this is a digital panel, if we didn't ++ * find any modes through DDC previously add the native mode to ++ * the list of modes. ++ */ ++ if (!nv_connector->native_mode) ++ nv_connector->native_mode = ++ nouveau_connector_native_mode(nv_connector); ++ if (ret == 0 && nv_connector->native_mode) { ++ struct drm_display_mode *mode; ++ ++ mode = drm_mode_duplicate(dev, nv_connector->native_mode); ++ drm_mode_probed_add(connector, mode); ++ ret = 1; ++ } ++ ++ if (nv_encoder->dcb->type == OUTPUT_TV) ++ ret = get_slave_funcs(nv_encoder)-> ++ get_modes(to_drm_encoder(nv_encoder), connector); ++ ++ if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) ++ ret += nouveau_connector_scaler_modes_add(connector); ++ ++ return ret; ++} ++ ++static int ++nouveau_connector_mode_valid(struct drm_connector *connector, ++ struct drm_display_mode *mode) ++{ ++ struct drm_nouveau_private *dev_priv = connector->dev->dev_private; ++ struct nouveau_connector *nv_connector = nouveau_connector(connector); ++ struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; ++ unsigned min_clock = 25000, max_clock = min_clock; ++ ++ switch (nv_encoder->dcb->type) { ++ case OUTPUT_LVDS: ++ BUG_ON(!nv_connector->native_mode); ++ if (mode->hdisplay > nv_connector->native_mode->hdisplay || ++ mode->vdisplay > nv_connector->native_mode->vdisplay) ++ return MODE_PANEL; ++ ++ min_clock = 0; ++ max_clock = 400000; ++ break; ++ case OUTPUT_TMDS: ++ if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) || ++ (dev_priv->card_type < NV_50 && ++ !nv_encoder->dcb->duallink_possible)) ++ max_clock = 165000; ++ else ++ max_clock = 330000; ++ break; ++ case OUTPUT_ANALOG: ++ max_clock = nv_encoder->dcb->crtconf.maxfreq; ++ if (!max_clock) ++ max_clock = 350000; ++ break; ++ case OUTPUT_TV: ++ return get_slave_funcs(nv_encoder)-> ++ mode_valid(to_drm_encoder(nv_encoder), mode); ++ } ++ ++ if (mode->clock < min_clock) ++ return MODE_CLOCK_LOW; ++ ++ if (mode->clock > max_clock) ++ return MODE_CLOCK_HIGH; ++ ++ return MODE_OK; ++} ++ ++static struct drm_encoder * ++nouveau_connector_best_encoder(struct drm_connector *connector) ++{ ++ struct nouveau_connector *nv_connector = nouveau_connector(connector); ++ ++ if (nv_connector->detected_encoder) ++ return to_drm_encoder(nv_connector->detected_encoder); ++ ++ return NULL; ++} ++ ++static const struct drm_connector_helper_funcs ++nouveau_connector_helper_funcs = { ++ .get_modes = nouveau_connector_get_modes, ++ .mode_valid = nouveau_connector_mode_valid, ++ .best_encoder = nouveau_connector_best_encoder, ++}; ++ ++static const struct drm_connector_funcs ++nouveau_connector_funcs = { ++ .dpms = drm_helper_connector_dpms, ++ .save = NULL, ++ .restore = NULL, ++ .detect = nouveau_connector_detect, ++ .destroy = nouveau_connector_destroy, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .set_property = nouveau_connector_set_property, ++ .force = nouveau_connector_force ++}; ++ ++static int ++nouveau_connector_create_lvds(struct drm_device *dev, ++ struct drm_connector *connector) ++{ ++ struct nouveau_connector *nv_connector = nouveau_connector(connector); ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_i2c_chan *i2c = NULL; ++ struct nouveau_encoder *nv_encoder; ++ struct drm_display_mode native, *mode, *temp; ++ bool dummy, if_is_24bit = false; ++ int ret, flags; ++ ++ nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); ++ if (!nv_encoder) ++ return -ENODEV; ++ ++ ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &if_is_24bit); ++ if (ret) { ++ NV_ERROR(dev, "Error parsing LVDS table, disabling LVDS\n"); ++ return ret; ++ } ++ nv_connector->use_dithering = !if_is_24bit; ++ ++ /* Firstly try getting EDID over DDC, if allowed and I2C channel ++ * is available. ++ */ ++ if (!dev_priv->VBIOS.pub.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf) ++ i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); ++ ++ if (i2c) { ++ nouveau_connector_ddc_prepare(connector, &flags); ++ nv_connector->edid = drm_get_edid(connector, &i2c->adapter); ++ nouveau_connector_ddc_finish(connector, flags); ++ } ++ ++ /* If no EDID found above, and the VBIOS indicates a hardcoded ++ * modeline is avalilable for the panel, set it as the panel's ++ * native mode and exit. ++ */ ++ if (!nv_connector->edid && ++ nv_encoder->dcb->lvdsconf.use_straps_for_mode && ++ nouveau_bios_fp_mode(dev, &native)) { ++ nv_connector->native_mode = drm_mode_duplicate(dev, &native); ++ goto out; ++ } ++ ++ /* Still nothing, some VBIOS images have a hardcoded EDID block ++ * stored for the panel stored in them. ++ */ ++ if (!nv_connector->edid && !nv_connector->native_mode && ++ !dev_priv->VBIOS.pub.fp_no_ddc) { ++ nv_connector->edid = ++ (struct edid *)nouveau_bios_embedded_edid(dev); ++ } ++ ++ if (!nv_connector->edid) ++ goto out; ++ ++ /* We didn't find/use a panel mode from the VBIOS, so parse the EDID ++ * block and look for the preferred mode there. ++ */ ++ ret = drm_add_edid_modes(connector, nv_connector->edid); ++ if (ret == 0) ++ goto out; ++ nv_connector->detected_encoder = nv_encoder; ++ nv_connector->native_mode = nouveau_connector_native_mode(nv_connector); ++ list_for_each_entry_safe(mode, temp, &connector->probed_modes, head) ++ drm_mode_remove(connector, mode); ++ ++out: ++ if (!nv_connector->native_mode) { ++ NV_ERROR(dev, "LVDS present in DCB table, but couldn't " ++ "determine its native mode. Disabling.\n"); ++ return -ENODEV; ++ } ++ ++ drm_mode_connector_update_edid_property(connector, nv_connector->edid); ++ return 0; ++} ++ ++int ++nouveau_connector_create(struct drm_device *dev, int index, int type) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_connector *nv_connector = NULL; ++ struct drm_connector *connector; ++ struct drm_encoder *encoder; ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); ++ if (!nv_connector) ++ return -ENOMEM; ++ connector = &nv_connector->base; ++ ++ switch (type) { ++ case DRM_MODE_CONNECTOR_VGA: ++ NV_INFO(dev, "Detected a VGA connector\n"); ++ break; ++ case DRM_MODE_CONNECTOR_DVID: ++ NV_INFO(dev, "Detected a DVI-D connector\n"); ++ break; ++ case DRM_MODE_CONNECTOR_DVII: ++ NV_INFO(dev, "Detected a DVI-I connector\n"); ++ break; ++ case DRM_MODE_CONNECTOR_LVDS: ++ NV_INFO(dev, "Detected a LVDS connector\n"); ++ break; ++ case DRM_MODE_CONNECTOR_TV: ++ NV_INFO(dev, "Detected a TV connector\n"); ++ break; ++ case DRM_MODE_CONNECTOR_DisplayPort: ++ NV_INFO(dev, "Detected a DisplayPort connector\n"); ++ break; ++ default: ++ NV_ERROR(dev, "Unknown connector, this is not good.\n"); ++ break; ++ } ++ ++ /* defaults, will get overridden in detect() */ ++ connector->interlace_allowed = false; ++ connector->doublescan_allowed = false; ++ ++ drm_connector_init(dev, connector, &nouveau_connector_funcs, type); ++ drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); ++ ++ /* Init DVI-I specific properties */ ++ if (type == DRM_MODE_CONNECTOR_DVII) { ++ drm_mode_create_dvi_i_properties(dev); ++ drm_connector_attach_property(connector, dev->mode_config.dvi_i_subconnector_property, 0); ++ drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0); ++ } ++ ++ if (type != DRM_MODE_CONNECTOR_LVDS) ++ nv_connector->use_dithering = false; ++ ++ if (type == DRM_MODE_CONNECTOR_DVID || ++ type == DRM_MODE_CONNECTOR_DVII || ++ type == DRM_MODE_CONNECTOR_LVDS || ++ type == DRM_MODE_CONNECTOR_DisplayPort) { ++ nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; ++ ++ drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, ++ nv_connector->scaling_mode); ++ drm_connector_attach_property(connector, dev->mode_config.dithering_mode_property, ++ nv_connector->use_dithering ? DRM_MODE_DITHERING_ON ++ : DRM_MODE_DITHERING_OFF); ++ ++ } else { ++ nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; ++ ++ if (type == DRM_MODE_CONNECTOR_VGA && ++ dev_priv->card_type >= NV_50) { ++ drm_connector_attach_property(connector, ++ dev->mode_config.scaling_mode_property, ++ nv_connector->scaling_mode); ++ } ++ } ++ ++ /* attach encoders */ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ ++ if (nv_encoder->dcb->connector != index) ++ continue; ++ ++ if (get_slave_funcs(nv_encoder)) ++ get_slave_funcs(nv_encoder)->create_resources(encoder, connector); ++ ++ drm_mode_connector_attach_encoder(connector, encoder); ++ } ++ ++ drm_sysfs_connector_add(connector); ++ ++ if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { ++ ret = nouveau_connector_create_lvds(dev, connector); ++ if (ret) { ++ connector->funcs->destroy(connector); ++ return ret; ++ } ++ } ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h +new file mode 100644 +index 0000000..75dbe9b +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_connector.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drm_edid.h" ++#include "nouveau_i2c.h" ++ ++struct nouveau_connector { ++ struct drm_connector base; ++ ++ struct drm_display_mode *native_mode; ++ ++ int scaling_mode; ++ ++ bool use_dithering; ++ ++ struct nouveau_encoder *detected_encoder; ++ ++ struct edid *edid; ++}; ++ ++static inline struct nouveau_connector *nouveau_connector( ++ struct drm_connector *con) ++{ ++ return container_of(con, struct nouveau_connector, base); ++} ++ ++int nouveau_connector_create(struct drm_device *dev, int i2c_index, int type); ++ ++#endif /* __NOUVEAU_CONNECTOR_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h +new file mode 100644 +index 0000000..49fa7b2 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h +@@ -0,0 +1,95 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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__ ++ ++struct nouveau_crtc { ++ struct drm_crtc base; ++ ++ int index; ++ ++ struct drm_display_mode *mode; ++ ++ uint32_t dpms_saved_fp_control; ++ uint32_t fp_users; ++ int saturation; ++ int sharpness; ++ int last_dpms; ++ ++ struct { ++ int cpp; ++ bool blanked; ++ uint32_t offset; ++ uint32_t tile_flags; ++ } fb; ++ ++ struct { ++ struct nouveau_bo *nvbo; ++ bool visible; ++ uint32_t offset; ++ void (*set_offset)(struct nouveau_crtc *, uint32_t offset); ++ void (*set_pos)(struct nouveau_crtc *, int x, int y); ++ void (*hide)(struct nouveau_crtc *, bool update); ++ void (*show)(struct nouveau_crtc *, bool update); ++ } cursor; ++ ++ struct { ++ struct nouveau_bo *nvbo; ++ uint16_t r[256]; ++ uint16_t g[256]; ++ uint16_t b[256]; ++ int depth; ++ } lut; ++ ++ int (*set_dither)(struct nouveau_crtc *crtc, bool on, bool update); ++ int (*set_scale)(struct nouveau_crtc *crtc, int mode, bool update); ++}; ++ ++static inline struct nouveau_crtc *nouveau_crtc(struct drm_crtc *crtc) ++{ ++ return container_of(crtc, struct nouveau_crtc, base); ++} ++ ++static inline struct drm_crtc *to_drm_crtc(struct nouveau_crtc *crtc) ++{ ++ return &crtc->base; ++} ++ ++int nv50_crtc_create(struct drm_device *dev, int index); ++int nv50_cursor_init(struct nouveau_crtc *); ++void nv50_cursor_fini(struct nouveau_crtc *); ++int nv50_crtc_cursor_set(struct drm_crtc *drm_crtc, struct drm_file *file_priv, ++ uint32_t buffer_handle, uint32_t width, ++ uint32_t height); ++int nv50_crtc_cursor_move(struct drm_crtc *drm_crtc, int x, int y); ++ ++int nv04_cursor_init(struct nouveau_crtc *); ++ ++struct nouveau_connector * ++nouveau_crtc_connector_get(struct nouveau_crtc *crtc); ++ ++#endif /* __NOUVEAU_CRTC_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c +new file mode 100644 +index 0000000..d79db36 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c +@@ -0,0 +1,155 @@ ++/* ++ * Copyright (C) 2009 Red Hat ++ * ++ * 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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. ++ * ++ */ ++ ++/* ++ * Authors: ++ * Ben Skeggs ++ */ ++ ++#include ++ ++#include "drmP.h" ++#include "nouveau_drv.h" ++ ++static int ++nouveau_debugfs_channel_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct nouveau_channel *chan = node->info_ent->data; ++ ++ seq_printf(m, "channel id : %d\n", chan->id); ++ ++ seq_printf(m, "cpu fifo state:\n"); ++ seq_printf(m, " base: 0x%08x\n", chan->pushbuf_base); ++ seq_printf(m, " max: 0x%08x\n", chan->dma.max << 2); ++ seq_printf(m, " cur: 0x%08x\n", chan->dma.cur << 2); ++ seq_printf(m, " put: 0x%08x\n", chan->dma.put << 2); ++ seq_printf(m, " free: 0x%08x\n", chan->dma.free << 2); ++ ++ seq_printf(m, "gpu fifo state:\n"); ++ seq_printf(m, " get: 0x%08x\n", ++ nvchan_rd32(chan, chan->user_get)); ++ seq_printf(m, " put: 0x%08x\n", ++ nvchan_rd32(chan, chan->user_put)); ++ ++ seq_printf(m, "last fence : %d\n", chan->fence.sequence); ++ seq_printf(m, "last signalled: %d\n", chan->fence.sequence_ack); ++ return 0; ++} ++ ++int ++nouveau_debugfs_channel_init(struct nouveau_channel *chan) ++{ ++ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; ++ struct drm_minor *minor = chan->dev->primary; ++ int ret; ++ ++ if (!dev_priv->debugfs.channel_root) { ++ dev_priv->debugfs.channel_root = ++ debugfs_create_dir("channel", minor->debugfs_root); ++ if (!dev_priv->debugfs.channel_root) ++ return -ENOENT; ++ } ++ ++ snprintf(chan->debugfs.name, 32, "%d", chan->id); ++ chan->debugfs.info.name = chan->debugfs.name; ++ chan->debugfs.info.show = nouveau_debugfs_channel_info; ++ chan->debugfs.info.driver_features = 0; ++ chan->debugfs.info.data = chan; ++ ++ ret = drm_debugfs_create_files(&chan->debugfs.info, 1, ++ dev_priv->debugfs.channel_root, ++ chan->dev->primary); ++ if (ret == 0) ++ chan->debugfs.active = true; ++ return ret; ++} ++ ++void ++nouveau_debugfs_channel_fini(struct nouveau_channel *chan) ++{ ++ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; ++ ++ if (!chan->debugfs.active) ++ return; ++ ++ drm_debugfs_remove_files(&chan->debugfs.info, 1, chan->dev->primary); ++ chan->debugfs.active = false; ++ ++ if (chan == dev_priv->channel) { ++ debugfs_remove(dev_priv->debugfs.channel_root); ++ dev_priv->debugfs.channel_root = NULL; ++ } ++} ++ ++static int ++nouveau_debugfs_chipset_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_minor *minor = node->minor; ++ struct drm_device *dev = minor->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t ppci_0; ++ ++ ppci_0 = nv_rd32(dev, dev_priv->chipset >= 0x40 ? 0x88000 : 0x1800); ++ ++ seq_printf(m, "PMC_BOOT_0: 0x%08x\n", nv_rd32(dev, NV03_PMC_BOOT_0)); ++ seq_printf(m, "PCI ID : 0x%04x:0x%04x\n", ++ ppci_0 & 0xffff, ppci_0 >> 16); ++ return 0; ++} ++ ++static int ++nouveau_debugfs_memory_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_minor *minor = node->minor; ++ struct drm_device *dev = minor->dev; ++ ++ seq_printf(m, "VRAM total: %dKiB\n", ++ (int)(nouveau_mem_fb_amount(dev) >> 10)); ++ return 0; ++} ++ ++static struct drm_info_list nouveau_debugfs_list[] = { ++ { "chipset", nouveau_debugfs_chipset_info, 0, NULL }, ++ { "memory", nouveau_debugfs_memory_info, 0, NULL }, ++}; ++#define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list) ++ ++int ++nouveau_debugfs_init(struct drm_minor *minor) ++{ ++ drm_debugfs_create_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES, ++ minor->debugfs_root, minor); ++ return 0; ++} ++ ++void ++nouveau_debugfs_takedown(struct drm_minor *minor) ++{ ++ drm_debugfs_remove_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES, ++ minor); ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c +new file mode 100644 +index 0000000..dfc9439 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_display.c +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_drv.h" ++#include "nouveau_fb.h" ++#include "nouveau_fbcon.h" ++ ++static void ++nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) ++{ ++ struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); ++ struct drm_device *dev = drm_fb->dev; ++ ++ if (drm_fb->fbdev) ++ nouveau_fbcon_remove(dev, drm_fb); ++ ++ if (fb->nvbo) { ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(fb->nvbo->gem); ++ mutex_unlock(&dev->struct_mutex); ++ } ++ ++ drm_framebuffer_cleanup(drm_fb); ++ kfree(fb); ++} ++ ++static int ++nouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb, ++ struct drm_file *file_priv, ++ unsigned int *handle) ++{ ++ struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); ++ ++ return drm_gem_handle_create(file_priv, fb->nvbo->gem, handle); ++} ++ ++static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { ++ .destroy = nouveau_user_framebuffer_destroy, ++ .create_handle = nouveau_user_framebuffer_create_handle, ++}; ++ ++struct drm_framebuffer * ++nouveau_framebuffer_create(struct drm_device *dev, struct nouveau_bo *nvbo, ++ struct drm_mode_fb_cmd *mode_cmd) ++{ ++ struct nouveau_framebuffer *fb; ++ int ret; ++ ++ fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL); ++ if (!fb) ++ return NULL; ++ ++ ret = drm_framebuffer_init(dev, &fb->base, &nouveau_framebuffer_funcs); ++ if (ret) { ++ kfree(fb); ++ return NULL; ++ } ++ ++ drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd); ++ ++ fb->nvbo = nvbo; ++ return &fb->base; ++} ++ ++static struct drm_framebuffer * ++nouveau_user_framebuffer_create(struct drm_device *dev, ++ struct drm_file *file_priv, ++ struct drm_mode_fb_cmd *mode_cmd) ++{ ++ struct drm_framebuffer *fb; ++ struct drm_gem_object *gem; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); ++ if (!gem) ++ return NULL; ++ ++ fb = nouveau_framebuffer_create(dev, nouveau_gem_object(gem), mode_cmd); ++ if (!fb) { ++ drm_gem_object_unreference(gem); ++ return NULL; ++ } ++ ++ return fb; ++} ++ ++const struct drm_mode_config_funcs nouveau_mode_config_funcs = { ++ .fb_create = nouveau_user_framebuffer_create, ++ .fb_changed = nouveau_fbcon_probe, ++}; ++ +diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c +new file mode 100644 +index 0000000..7035536 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_dma.c +@@ -0,0 +1,206 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++ ++int ++nouveau_dma_init(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *m2mf = NULL; ++ int ret, i; ++ ++ /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */ ++ ret = nouveau_gpuobj_gr_new(chan, dev_priv->card_type < NV_50 ? ++ 0x0039 : 0x5039, &m2mf); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_gpuobj_ref_add(dev, chan, NvM2MF, m2mf, NULL); ++ if (ret) ++ return ret; ++ ++ /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ ++ ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy); ++ if (ret) ++ return ret; ++ ++ /* Map push buffer */ ++ ret = nouveau_bo_map(chan->pushbuf_bo); ++ if (ret) ++ return ret; ++ ++ /* Map M2MF notifier object - fbcon. */ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ ret = nouveau_bo_map(chan->notifier_bo); ++ if (ret) ++ return ret; ++ } ++ ++ /* Initialise DMA vars */ ++ chan->dma.max = (chan->pushbuf_bo->bo.mem.size >> 2) - 2; ++ chan->dma.put = 0; ++ chan->dma.cur = chan->dma.put; ++ chan->dma.free = chan->dma.max - chan->dma.cur; ++ ++ /* Insert NOPS for NOUVEAU_DMA_SKIPS */ ++ ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < NOUVEAU_DMA_SKIPS; i++) ++ OUT_RING(chan, 0); ++ ++ /* Initialise NV_MEMORY_TO_MEMORY_FORMAT */ ++ ret = RING_SPACE(chan, 4); ++ if (ret) ++ return ret; ++ BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1); ++ OUT_RING(chan, NvM2MF); ++ BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); ++ OUT_RING(chan, NvNotify0); ++ ++ /* Sit back and pray the channel works.. */ ++ FIRE_RING(chan); ++ ++ return 0; ++} ++ ++void ++OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords) ++{ ++ bool is_iomem; ++ u32 *mem = ttm_kmap_obj_virtual(&chan->pushbuf_bo->kmap, &is_iomem); ++ mem = &mem[chan->dma.cur]; ++ if (is_iomem) ++ memcpy_toio((void __force __iomem *)mem, data, nr_dwords * 4); ++ else ++ memcpy(mem, data, nr_dwords * 4); ++ chan->dma.cur += nr_dwords; ++} ++ ++static inline bool ++READ_GET(struct nouveau_channel *chan, uint32_t *get) ++{ ++ uint32_t val; ++ ++ val = nvchan_rd32(chan, chan->user_get); ++ if (val < chan->pushbuf_base || ++ val >= chan->pushbuf_base + chan->pushbuf_bo->bo.mem.size) { ++ /* meaningless to dma_wait() except to know whether the ++ * GPU has stalled or not ++ */ ++ *get = val; ++ return false; ++ } ++ ++ *get = (val - chan->pushbuf_base) >> 2; ++ return true; ++} ++ ++int ++nouveau_dma_wait(struct nouveau_channel *chan, int size) ++{ ++ uint32_t get, prev_get = 0, cnt = 0; ++ bool get_valid; ++ ++ while (chan->dma.free < size) { ++ /* reset counter as long as GET is still advancing, this is ++ * to avoid misdetecting a GPU lockup if the GPU happens to ++ * just be processing an operation that takes a long time ++ */ ++ get_valid = READ_GET(chan, &get); ++ if (get != prev_get) { ++ prev_get = get; ++ cnt = 0; ++ } ++ ++ if ((++cnt & 0xff) == 0) { ++ DRM_UDELAY(1); ++ if (cnt > 100000) ++ return -EBUSY; ++ } ++ ++ /* loop until we have a usable GET pointer. the value ++ * we read from the GPU may be outside the main ring if ++ * PFIFO is processing a buffer called from the main ring, ++ * discard these values until something sensible is seen. ++ * ++ * the other case we discard GET is while the GPU is fetching ++ * from the SKIPS area, so the code below doesn't have to deal ++ * with some fun corner cases. ++ */ ++ if (!get_valid || get < NOUVEAU_DMA_SKIPS) ++ continue; ++ ++ if (get <= chan->dma.cur) { ++ /* engine is fetching behind us, or is completely ++ * idle (GET == PUT) so we have free space up until ++ * the end of the push buffer ++ * ++ * we can only hit that path once per call due to ++ * looping back to the beginning of the push buffer, ++ * we'll hit the fetching-ahead-of-us path from that ++ * point on. ++ * ++ * the *one* exception to that rule is if we read ++ * GET==PUT, in which case the below conditional will ++ * always succeed and break us out of the wait loop. ++ */ ++ chan->dma.free = chan->dma.max - chan->dma.cur; ++ if (chan->dma.free >= size) ++ break; ++ ++ /* not enough space left at the end of the push buffer, ++ * instruct the GPU to jump back to the start right ++ * after processing the currently pending commands. ++ */ ++ OUT_RING(chan, chan->pushbuf_base | 0x20000000); ++ WRITE_PUT(NOUVEAU_DMA_SKIPS); ++ ++ /* we're now submitting commands at the start of ++ * the push buffer. ++ */ ++ chan->dma.cur = ++ chan->dma.put = NOUVEAU_DMA_SKIPS; ++ } ++ ++ /* engine fetching ahead of us, we have space up until the ++ * current GET pointer. the "- 1" is to ensure there's ++ * space left to emit a jump back to the beginning of the ++ * push buffer if we require it. we can never get GET == PUT ++ * here, so this is safe. ++ */ ++ chan->dma.free = get - chan->dma.cur - 1; ++ } ++ ++ return 0; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h +new file mode 100644 +index 0000000..04e85d8 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_dma.h +@@ -0,0 +1,157 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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_DMA_H__ ++#define __NOUVEAU_DMA_H__ ++ ++#ifndef NOUVEAU_DMA_DEBUG ++#define NOUVEAU_DMA_DEBUG 0 ++#endif ++ ++/* ++ * There's a hw race condition where you can't jump to your PUT offset, ++ * to avoid this we jump to offset + SKIPS and fill the difference with ++ * NOPs. ++ * ++ * xf86-video-nv configures the DMA fetch size to 32 bytes, and uses ++ * a SKIPS value of 8. Lets assume that the race condition is to do ++ * with writing into the fetch area, we configure a fetch size of 128 ++ * bytes so we need a larger SKIPS value. ++ */ ++#define NOUVEAU_DMA_SKIPS (128 / 4) ++ ++/* Hardcoded object assignments to subchannels (subchannel id). */ ++enum { ++ NvSubM2MF = 0, ++ NvSub2D = 1, ++ NvSubCtxSurf2D = 1, ++ NvSubGdiRect = 2, ++ NvSubImageBlit = 3 ++}; ++ ++/* Object handles. */ ++enum { ++ NvM2MF = 0x80000001, ++ NvDmaFB = 0x80000002, ++ NvDmaTT = 0x80000003, ++ NvDmaVRAM = 0x80000004, ++ NvDmaGART = 0x80000005, ++ NvNotify0 = 0x80000006, ++ Nv2D = 0x80000007, ++ NvCtxSurf2D = 0x80000008, ++ NvRop = 0x80000009, ++ NvImagePatt = 0x8000000a, ++ NvClipRect = 0x8000000b, ++ NvGdiRect = 0x8000000c, ++ NvImageBlit = 0x8000000d, ++ ++ /* G80+ display objects */ ++ NvEvoVRAM = 0x01000000, ++ NvEvoFB16 = 0x01000001, ++ NvEvoFB32 = 0x01000002 ++}; ++ ++#define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039 ++#define NV_MEMORY_TO_MEMORY_FORMAT_NAME 0x00000000 ++#define NV_MEMORY_TO_MEMORY_FORMAT_SET_REF 0x00000050 ++#define NV_MEMORY_TO_MEMORY_FORMAT_NOP 0x00000100 ++#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 ++#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE 0x00000000 ++#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE_LE_AWAKEN 0x00000001 ++#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY 0x00000180 ++#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE 0x00000184 ++#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c ++ ++#define NV50_MEMORY_TO_MEMORY_FORMAT 0x00005039 ++#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK200 0x00000200 ++#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK21C 0x0000021c ++#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH 0x00000238 ++#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH 0x0000023c ++ ++static __must_check inline int ++RING_SPACE(struct nouveau_channel *chan, int size) ++{ ++ if (chan->dma.free < size) { ++ int ret; ++ ++ ret = nouveau_dma_wait(chan, size); ++ if (ret) ++ return ret; ++ } ++ ++ chan->dma.free -= size; ++ return 0; ++} ++ ++static inline void ++OUT_RING(struct nouveau_channel *chan, int data) ++{ ++ if (NOUVEAU_DMA_DEBUG) { ++ NV_INFO(chan->dev, "Ch%d/0x%08x: 0x%08x\n", ++ chan->id, chan->dma.cur << 2, data); ++ } ++ ++ nouveau_bo_wr32(chan->pushbuf_bo, chan->dma.cur++, data); ++} ++ ++extern void ++OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords); ++ ++static inline void ++BEGIN_RING(struct nouveau_channel *chan, int subc, int mthd, int size) ++{ ++ OUT_RING(chan, (subc << 13) | (size << 18) | mthd); ++} ++ ++#define WRITE_PUT(val) do { \ ++ DRM_MEMORYBARRIER(); \ ++ nouveau_bo_rd32(chan->pushbuf_bo, 0); \ ++ nvchan_wr32(chan, chan->user_put, ((val) << 2) + chan->pushbuf_base); \ ++} while (0) ++ ++static inline void ++FIRE_RING(struct nouveau_channel *chan) ++{ ++ if (NOUVEAU_DMA_DEBUG) { ++ NV_INFO(chan->dev, "Ch%d/0x%08x: PUSH!\n", ++ chan->id, chan->dma.cur << 2); ++ } ++ ++ if (chan->dma.cur == chan->dma.put) ++ return; ++ chan->accel_done = true; ++ ++ WRITE_PUT(chan->dma.cur); ++ chan->dma.put = chan->dma.cur; ++} ++ ++static inline void ++WIND_RING(struct nouveau_channel *chan) ++{ ++ chan->dma.cur = chan->dma.put; ++} ++ ++#endif +diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c +new file mode 100644 +index 0000000..d8de3f6 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_drv.c +@@ -0,0 +1,413 @@ ++/* ++ * Copyright 2005 Stephane Marchesin. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 ++ ++#include "drmP.h" ++#include "drm.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_drv.h" ++#include "nouveau_hw.h" ++#include "nouveau_fb.h" ++#include "nouveau_fbcon.h" ++#include "nv50_display.h" ++ ++#include "drm_pciids.h" ++ ++MODULE_PARM_DESC(noagp, "Disable AGP"); ++int nouveau_noagp; ++module_param_named(noagp, nouveau_noagp, int, 0400); ++ ++MODULE_PARM_DESC(modeset, "Enable kernel modesetting"); ++static int nouveau_modeset = -1; /* kms */ ++module_param_named(modeset, nouveau_modeset, int, 0400); ++ ++MODULE_PARM_DESC(vbios, "Override default VBIOS location"); ++char *nouveau_vbios; ++module_param_named(vbios, nouveau_vbios, charp, 0400); ++ ++MODULE_PARM_DESC(vram_pushbuf, "Force DMA push buffers to be in VRAM"); ++int nouveau_vram_pushbuf; ++module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400); ++ ++MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM"); ++int nouveau_vram_notify; ++module_param_named(vram_notify, nouveau_vram_notify, int, 0400); ++ ++MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)"); ++int nouveau_duallink = 1; ++module_param_named(duallink, nouveau_duallink, int, 0400); ++ ++MODULE_PARM_DESC(uscript_lvds, "LVDS output script table ID (>=GeForce 8)"); ++int nouveau_uscript_lvds = -1; ++module_param_named(uscript_lvds, nouveau_uscript_lvds, int, 0400); ++ ++MODULE_PARM_DESC(uscript_tmds, "TMDS output script table ID (>=GeForce 8)"); ++int nouveau_uscript_tmds = -1; ++module_param_named(uscript_tmds, nouveau_uscript_tmds, int, 0400); ++ ++MODULE_PARM_DESC(tv, "Enable TV-out support (dev_private; ++ struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; ++ struct nouveau_channel *chan; ++ struct drm_crtc *crtc; ++ uint32_t fbdev_flags; ++ int ret, i; ++ ++ if (!drm_core_check_feature(dev, DRIVER_MODESET)) ++ return -ENODEV; ++ ++ if (pm_state.event == PM_EVENT_PRETHAW) ++ return 0; ++ ++ fbdev_flags = dev_priv->fbdev_info->flags; ++ dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED; ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct nouveau_framebuffer *nouveau_fb; ++ ++ nouveau_fb = nouveau_framebuffer(crtc->fb); ++ if (!nouveau_fb || !nouveau_fb->nvbo) ++ continue; ++ ++ nouveau_bo_unpin(nouveau_fb->nvbo); ++ } ++ ++ NV_INFO(dev, "Evicting buffers...\n"); ++ ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); ++ ++ NV_INFO(dev, "Idling channels...\n"); ++ for (i = 0; i < pfifo->channels; i++) { ++ struct nouveau_fence *fence = NULL; ++ ++ chan = dev_priv->fifos[i]; ++ if (!chan || (dev_priv->card_type >= NV_50 && ++ chan == dev_priv->fifos[0])) ++ continue; ++ ++ ret = nouveau_fence_new(chan, &fence, true); ++ if (ret == 0) { ++ ret = nouveau_fence_wait(fence, NULL, false, false); ++ nouveau_fence_unref((void *)&fence); ++ } ++ ++ if (ret) { ++ NV_ERROR(dev, "Failed to idle channel %d for suspend\n", ++ chan->id); ++ } ++ } ++ ++ pgraph->fifo_access(dev, false); ++ nouveau_wait_for_idle(dev); ++ pfifo->reassign(dev, false); ++ pfifo->disable(dev); ++ pfifo->unload_context(dev); ++ pgraph->unload_context(dev); ++ ++ NV_INFO(dev, "Suspending GPU objects...\n"); ++ ret = nouveau_gpuobj_suspend(dev); ++ if (ret) { ++ NV_ERROR(dev, "... failed: %d\n", ret); ++ goto out_abort; ++ } ++ ++ ret = pinstmem->suspend(dev); ++ if (ret) { ++ NV_ERROR(dev, "... failed: %d\n", ret); ++ nouveau_gpuobj_suspend_cleanup(dev); ++ goto out_abort; ++ } ++ ++ NV_INFO(dev, "And we're gone!\n"); ++ pci_save_state(pdev); ++ if (pm_state.event == PM_EVENT_SUSPEND) { ++ pci_disable_device(pdev); ++ pci_set_power_state(pdev, PCI_D3hot); ++ } ++ ++ acquire_console_sem(); ++ fb_set_suspend(dev_priv->fbdev_info, 1); ++ release_console_sem(); ++ dev_priv->fbdev_info->flags = fbdev_flags; ++ return 0; ++ ++out_abort: ++ NV_INFO(dev, "Re-enabling acceleration..\n"); ++ pfifo->enable(dev); ++ pfifo->reassign(dev, true); ++ pgraph->fifo_access(dev, true); ++ return ret; ++} ++ ++static int ++nouveau_pci_resume(struct pci_dev *pdev) ++{ ++ struct drm_device *dev = pci_get_drvdata(pdev); ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ struct drm_crtc *crtc; ++ uint32_t fbdev_flags; ++ int ret, i; ++ ++ if (!drm_core_check_feature(dev, DRIVER_MODESET)) ++ return -ENODEV; ++ ++ fbdev_flags = dev_priv->fbdev_info->flags; ++ dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED; ++ ++ NV_INFO(dev, "We're back, enabling device...\n"); ++ pci_set_power_state(pdev, PCI_D0); ++ pci_restore_state(pdev); ++ if (pci_enable_device(pdev)) ++ return -1; ++ pci_set_master(dev->pdev); ++ ++ NV_INFO(dev, "POSTing device...\n"); ++ ret = nouveau_run_vbios_init(dev); ++ if (ret) ++ return ret; ++ ++ if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) { ++ ret = nouveau_mem_init_agp(dev); ++ if (ret) { ++ NV_ERROR(dev, "error reinitialising AGP: %d\n", ret); ++ return ret; ++ } ++ } ++ ++ NV_INFO(dev, "Reinitialising engines...\n"); ++ engine->instmem.resume(dev); ++ engine->mc.init(dev); ++ engine->timer.init(dev); ++ engine->fb.init(dev); ++ engine->graph.init(dev); ++ engine->fifo.init(dev); ++ ++ NV_INFO(dev, "Restoring GPU objects...\n"); ++ nouveau_gpuobj_resume(dev); ++ ++ nouveau_irq_postinstall(dev); ++ ++ /* Re-write SKIPS, they'll have been lost over the suspend */ ++ if (nouveau_vram_pushbuf) { ++ struct nouveau_channel *chan; ++ int j; ++ ++ for (i = 0; i < dev_priv->engine.fifo.channels; i++) { ++ chan = dev_priv->fifos[i]; ++ if (!chan) ++ continue; ++ ++ for (j = 0; j < NOUVEAU_DMA_SKIPS; j++) ++ nouveau_bo_wr32(chan->pushbuf_bo, i, 0); ++ } ++ } ++ ++ NV_INFO(dev, "Restoring mode...\n"); ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct nouveau_framebuffer *nouveau_fb; ++ ++ nouveau_fb = nouveau_framebuffer(crtc->fb); ++ if (!nouveau_fb || !nouveau_fb->nvbo) ++ continue; ++ ++ nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM); ++ } ++ ++ if (dev_priv->card_type < NV_50) { ++ nv04_display_restore(dev); ++ NVLockVgaCrtcs(dev, false); ++ } else ++ nv50_display_init(dev); ++ ++ /* Force CLUT to get re-loaded during modeset */ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ ++ nv_crtc->lut.depth = 0; ++ } ++ ++ acquire_console_sem(); ++ fb_set_suspend(dev_priv->fbdev_info, 0); ++ release_console_sem(); ++ ++ nouveau_fbcon_zfill(dev); ++ ++ drm_helper_resume_force_mode(dev); ++ dev_priv->fbdev_info->flags = fbdev_flags; ++ return 0; ++} ++ ++static struct drm_driver driver = { ++ .driver_features = ++ DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | ++ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM, ++ .load = nouveau_load, ++ .firstopen = nouveau_firstopen, ++ .lastclose = nouveau_lastclose, ++ .unload = nouveau_unload, ++ .preclose = nouveau_preclose, ++#if defined(CONFIG_DRM_NOUVEAU_DEBUG) ++ .debugfs_init = nouveau_debugfs_init, ++ .debugfs_cleanup = nouveau_debugfs_takedown, ++#endif ++ .irq_preinstall = nouveau_irq_preinstall, ++ .irq_postinstall = nouveau_irq_postinstall, ++ .irq_uninstall = nouveau_irq_uninstall, ++ .irq_handler = nouveau_irq_handler, ++ .reclaim_buffers = drm_core_reclaim_buffers, ++ .get_map_ofs = drm_core_get_map_ofs, ++ .get_reg_ofs = drm_core_get_reg_ofs, ++ .ioctls = nouveau_ioctls, ++ .fops = { ++ .owner = THIS_MODULE, ++ .open = drm_open, ++ .release = drm_release, ++ .ioctl = drm_ioctl, ++ .mmap = nouveau_ttm_mmap, ++ .poll = drm_poll, ++ .fasync = drm_fasync, ++#if defined(CONFIG_COMPAT) ++ .compat_ioctl = nouveau_compat_ioctl, ++#endif ++ }, ++ .pci_driver = { ++ .name = DRIVER_NAME, ++ .id_table = pciidlist, ++ .probe = nouveau_pci_probe, ++ .remove = nouveau_pci_remove, ++ .suspend = nouveau_pci_suspend, ++ .resume = nouveau_pci_resume ++ }, ++ ++ .gem_init_object = nouveau_gem_object_new, ++ .gem_free_object = nouveau_gem_object_del, ++ ++ .name = DRIVER_NAME, ++ .desc = DRIVER_DESC, ++#ifdef GIT_REVISION ++ .date = GIT_REVISION, ++#else ++ .date = DRIVER_DATE, ++#endif ++ .major = DRIVER_MAJOR, ++ .minor = DRIVER_MINOR, ++ .patchlevel = DRIVER_PATCHLEVEL, ++}; ++ ++static int __init nouveau_init(void) ++{ ++ driver.num_ioctls = nouveau_max_ioctl; ++ ++ if (nouveau_modeset == -1) { ++#ifdef CONFIG_VGA_CONSOLE ++ if (vgacon_text_force()) ++ nouveau_modeset = 0; ++ else ++#endif ++#if defined(CONFIG_DRM_NOUVEAU_KMS) ++ nouveau_modeset = 1; ++#else ++ nouveau_modeset = 0; ++#endif ++ } ++ ++ if (nouveau_modeset == 1) ++ driver.driver_features |= DRIVER_MODESET; ++ ++ return drm_init(&driver); ++} ++ ++static void __exit nouveau_exit(void) ++{ ++ drm_exit(&driver); ++} ++ ++module_init(nouveau_init); ++module_exit(nouveau_exit); ++ ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_LICENSE("GPL and additional rights"); +diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h +new file mode 100644 +index 0000000..d16c843 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_drv.h +@@ -0,0 +1,1288 @@ ++/* ++ * Copyright 2005 Stephane Marchesin. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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_DRV_H__ ++#define __NOUVEAU_DRV_H__ ++ ++#define DRIVER_AUTHOR "Stephane Marchesin" ++#define DRIVER_EMAIL "dri-devel@lists.sourceforge.net" ++ ++#define DRIVER_NAME "nouveau" ++#define DRIVER_DESC "nVidia Riva/TNT/GeForce" ++#define DRIVER_DATE "20090420" ++ ++#define DRIVER_MAJOR 0 ++#define DRIVER_MINOR 0 ++#define DRIVER_PATCHLEVEL 15 ++ ++#define NOUVEAU_FAMILY 0x0000FFFF ++#define NOUVEAU_FLAGS 0xFFFF0000 ++ ++#include "ttm/ttm_bo_api.h" ++#include "ttm/ttm_bo_driver.h" ++#include "ttm/ttm_placement.h" ++#include "ttm/ttm_memory.h" ++#include "ttm/ttm_module.h" ++ ++struct nouveau_fpriv { ++ struct ttm_object_file *tfile; ++}; ++ ++#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) ++ ++#include "nouveau_drm.h" ++#include "nouveau_reg.h" ++#include "nouveau_bios.h" ++ ++#define MAX_NUM_DCB_ENTRIES 16 ++ ++#define NOUVEAU_MAX_CHANNEL_NR 128 ++ ++#define NV50_VM_MAX_VRAM (2*1024*1024*1024ULL) ++#define NV50_VM_BLOCK (512*1024*1024ULL) ++#define NV50_VM_VRAM_NR (NV50_VM_MAX_VRAM / NV50_VM_BLOCK) ++ ++struct nouveau_bo { ++ struct ttm_buffer_object bo; ++ struct ttm_bo_kmap_obj kmap; ++ struct list_head head; ++ ++ struct drm_file *reserved_by; ++ struct list_head entry; ++ ++ struct nouveau_channel *channel; ++ ++ bool mappable; ++ bool no_vm; ++ ++ uint32_t tile_mode; ++ uint32_t tile_flags; ++ ++ struct drm_gem_object *gem; ++ struct drm_file *cpu_filp; ++ int pin_refcnt; ++}; ++ ++static inline struct nouveau_bo * ++nouveau_bo(struct ttm_buffer_object *bo) ++{ ++ return container_of(bo, struct nouveau_bo, bo); ++} ++ ++static inline struct nouveau_bo * ++nouveau_gem_object(struct drm_gem_object *gem) ++{ ++ return gem ? gem->driver_private : NULL; ++} ++ ++/* TODO: submit equivalent to TTM generic API upstream? */ ++static inline void __iomem * ++nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo) ++{ ++ bool is_iomem; ++ void __iomem *ioptr = (void __force __iomem *)ttm_kmap_obj_virtual( ++ &nvbo->kmap, &is_iomem); ++ WARN_ON_ONCE(ioptr && !is_iomem); ++ return ioptr; ++} ++ ++struct mem_block { ++ struct mem_block *next; ++ struct mem_block *prev; ++ uint64_t start; ++ uint64_t size; ++ struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ ++}; ++ ++enum nouveau_flags { ++ NV_NFORCE = 0x10000000, ++ NV_NFORCE2 = 0x20000000 ++}; ++ ++#define NVOBJ_ENGINE_SW 0 ++#define NVOBJ_ENGINE_GR 1 ++#define NVOBJ_ENGINE_DISPLAY 2 ++#define NVOBJ_ENGINE_INT 0xdeadbeef ++ ++#define NVOBJ_FLAG_ALLOW_NO_REFS (1 << 0) ++#define NVOBJ_FLAG_ZERO_ALLOC (1 << 1) ++#define NVOBJ_FLAG_ZERO_FREE (1 << 2) ++#define NVOBJ_FLAG_FAKE (1 << 3) ++struct nouveau_gpuobj { ++ struct list_head list; ++ ++ struct nouveau_channel *im_channel; ++ struct mem_block *im_pramin; ++ struct nouveau_bo *im_backing; ++ uint32_t im_backing_start; ++ uint32_t *im_backing_suspend; ++ int im_bound; ++ ++ uint32_t flags; ++ int refcount; ++ ++ uint32_t engine; ++ uint32_t class; ++ ++ void (*dtor)(struct drm_device *, struct nouveau_gpuobj *); ++ void *priv; ++}; ++ ++struct nouveau_gpuobj_ref { ++ struct list_head list; ++ ++ struct nouveau_gpuobj *gpuobj; ++ uint32_t instance; ++ ++ struct nouveau_channel *channel; ++ int handle; ++}; ++ ++struct nouveau_channel { ++ struct drm_device *dev; ++ int id; ++ ++ /* owner of this fifo */ ++ struct drm_file *file_priv; ++ /* mapping of the fifo itself */ ++ struct drm_local_map *map; ++ ++ /* mapping of the regs controling the fifo */ ++ void __iomem *user; ++ uint32_t user_get; ++ uint32_t user_put; ++ ++ /* Fencing */ ++ struct { ++ /* lock protects the pending list only */ ++ spinlock_t lock; ++ struct list_head pending; ++ uint32_t sequence; ++ uint32_t sequence_ack; ++ uint32_t last_sequence_irq; ++ } fence; ++ ++ /* DMA push buffer */ ++ struct nouveau_gpuobj_ref *pushbuf; ++ struct nouveau_bo *pushbuf_bo; ++ uint32_t pushbuf_base; ++ ++ /* Notifier memory */ ++ struct nouveau_bo *notifier_bo; ++ struct mem_block *notifier_heap; ++ ++ /* PFIFO context */ ++ struct nouveau_gpuobj_ref *ramfc; ++ struct nouveau_gpuobj_ref *cache; ++ ++ /* PGRAPH context */ ++ /* XXX may be merge 2 pointers as private data ??? */ ++ struct nouveau_gpuobj_ref *ramin_grctx; ++ void *pgraph_ctx; ++ ++ /* NV50 VM */ ++ struct nouveau_gpuobj *vm_pd; ++ struct nouveau_gpuobj_ref *vm_gart_pt; ++ struct nouveau_gpuobj_ref *vm_vram_pt[NV50_VM_VRAM_NR]; ++ ++ /* Objects */ ++ struct nouveau_gpuobj_ref *ramin; /* Private instmem */ ++ struct mem_block *ramin_heap; /* Private PRAMIN heap */ ++ struct nouveau_gpuobj_ref *ramht; /* Hash table */ ++ struct list_head ramht_refs; /* Objects referenced by RAMHT */ ++ ++ /* GPU object info for stuff used in-kernel (mm_enabled) */ ++ uint32_t m2mf_ntfy; ++ uint32_t vram_handle; ++ uint32_t gart_handle; ++ bool accel_done; ++ ++ /* Push buffer state (only for drm's channel on !mm_enabled) */ ++ struct { ++ int max; ++ int free; ++ int cur; ++ int put; ++ /* access via pushbuf_bo */ ++ } dma; ++ ++ uint32_t sw_subchannel[8]; ++ ++ struct { ++ struct nouveau_gpuobj *vblsem; ++ uint32_t vblsem_offset; ++ uint32_t vblsem_rval; ++ struct list_head vbl_wait; ++ } nvsw; ++ ++ struct { ++ bool active; ++ char name[32]; ++ struct drm_info_list info; ++ } debugfs; ++}; ++ ++struct nouveau_instmem_engine { ++ void *priv; ++ ++ int (*init)(struct drm_device *dev); ++ void (*takedown)(struct drm_device *dev); ++ int (*suspend)(struct drm_device *dev); ++ void (*resume)(struct drm_device *dev); ++ ++ int (*populate)(struct drm_device *, struct nouveau_gpuobj *, ++ uint32_t *size); ++ void (*clear)(struct drm_device *, struct nouveau_gpuobj *); ++ int (*bind)(struct drm_device *, struct nouveau_gpuobj *); ++ int (*unbind)(struct drm_device *, struct nouveau_gpuobj *); ++ void (*prepare_access)(struct drm_device *, bool write); ++ void (*finish_access)(struct drm_device *); ++}; ++ ++struct nouveau_mc_engine { ++ int (*init)(struct drm_device *dev); ++ void (*takedown)(struct drm_device *dev); ++}; ++ ++struct nouveau_timer_engine { ++ int (*init)(struct drm_device *dev); ++ void (*takedown)(struct drm_device *dev); ++ uint64_t (*read)(struct drm_device *dev); ++}; ++ ++struct nouveau_fb_engine { ++ int (*init)(struct drm_device *dev); ++ void (*takedown)(struct drm_device *dev); ++}; ++ ++struct nouveau_fifo_engine { ++ void *priv; ++ ++ int channels; ++ ++ int (*init)(struct drm_device *); ++ void (*takedown)(struct drm_device *); ++ ++ void (*disable)(struct drm_device *); ++ void (*enable)(struct drm_device *); ++ bool (*reassign)(struct drm_device *, bool enable); ++ ++ int (*channel_id)(struct drm_device *); ++ ++ int (*create_context)(struct nouveau_channel *); ++ void (*destroy_context)(struct nouveau_channel *); ++ int (*load_context)(struct nouveau_channel *); ++ int (*unload_context)(struct drm_device *); ++}; ++ ++struct nouveau_pgraph_object_method { ++ int id; ++ int (*exec)(struct nouveau_channel *chan, int grclass, int mthd, ++ uint32_t data); ++}; ++ ++struct nouveau_pgraph_object_class { ++ int id; ++ bool software; ++ struct nouveau_pgraph_object_method *methods; ++}; ++ ++struct nouveau_pgraph_engine { ++ struct nouveau_pgraph_object_class *grclass; ++ bool accel_blocked; ++ ++ int (*init)(struct drm_device *); ++ void (*takedown)(struct drm_device *); ++ ++ void (*fifo_access)(struct drm_device *, bool); ++ ++ struct nouveau_channel *(*channel)(struct drm_device *); ++ int (*create_context)(struct nouveau_channel *); ++ void (*destroy_context)(struct nouveau_channel *); ++ int (*load_context)(struct nouveau_channel *); ++ int (*unload_context)(struct drm_device *); ++}; ++ ++struct nouveau_engine { ++ struct nouveau_instmem_engine instmem; ++ struct nouveau_mc_engine mc; ++ struct nouveau_timer_engine timer; ++ struct nouveau_fb_engine fb; ++ struct nouveau_pgraph_engine graph; ++ struct nouveau_fifo_engine fifo; ++}; ++ ++struct nouveau_pll_vals { ++ union { ++ struct { ++#ifdef __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; ++}; ++ ++enum nv04_fp_display_regs { ++ FP_DISPLAY_END, ++ FP_TOTAL, ++ FP_CRTC, ++ FP_SYNC_START, ++ FP_SYNC_END, ++ FP_VALID_START, ++ FP_VALID_END ++}; ++ ++struct nv04_crtc_reg { ++ unsigned char MiscOutReg; /* */ ++ uint8_t CRTC[0x9f]; ++ uint8_t CR58[0x10]; ++ uint8_t Sequencer[5]; ++ uint8_t Graphics[9]; ++ uint8_t Attribute[21]; ++ unsigned char DAC[768]; /* Internal Colorlookuptable */ ++ ++ /* 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 tv_setup; ++ uint32_t tv_vtotal; ++ uint32_t tv_vskew; ++ uint32_t tv_vsync_delay; ++ uint32_t tv_htotal; ++ uint32_t tv_hskew; ++ uint32_t tv_hsync_delay; ++ uint32_t tv_hsync_delay2; ++ 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 fp_margin_color; ++ uint32_t ramdac_8c0; ++ uint32_t ramdac_a20; ++ uint32_t ramdac_a24; ++ uint32_t ramdac_a34; ++ uint32_t ctv_regs[38]; ++}; ++ ++struct nv04_output_reg { ++ uint32_t output; ++ int head; ++}; ++ ++struct nv04_mode_state { ++ uint32_t bpp; ++ uint32_t width; ++ uint32_t height; ++ uint32_t interlace; ++ uint32_t repaint0; ++ uint32_t repaint1; ++ uint32_t screen; ++ uint32_t scale; ++ uint32_t dither; ++ uint32_t extra; ++ uint32_t fifo; ++ uint32_t pixel; ++ uint32_t horiz; ++ int arbitration0; ++ int arbitration1; ++ uint32_t pll; ++ uint32_t pllB; ++ uint32_t vpll; ++ uint32_t vpll2; ++ uint32_t vpllB; ++ uint32_t vpll2B; ++ uint32_t pllsel; ++ uint32_t sel_clk; ++ uint32_t general; ++ uint32_t crtcOwner; ++ uint32_t head; ++ uint32_t head2; ++ uint32_t cursorConfig; ++ uint32_t cursor0; ++ uint32_t cursor1; ++ uint32_t cursor2; ++ uint32_t timingH; ++ uint32_t timingV; ++ uint32_t displayV; ++ uint32_t crtcSync; ++ ++ struct nv04_crtc_reg crtc_reg[2]; ++}; ++ ++enum nouveau_card_type { ++ NV_UNKNOWN = 0, ++ NV_04 = 4, ++ NV_05 = 5, ++ NV_10 = 10, ++ NV_11 = 11, ++ NV_17 = 17, ++ NV_20 = 20, ++ NV_30 = 30, ++ NV_40 = 40, ++ NV_50 = 50, ++}; ++ ++struct drm_nouveau_private { ++ struct drm_device *dev; ++ enum { ++ NOUVEAU_CARD_INIT_DOWN, ++ NOUVEAU_CARD_INIT_DONE, ++ NOUVEAU_CARD_INIT_FAILED ++ } init_state; ++ ++ /* the card type, takes NV_* as values */ ++ enum nouveau_card_type card_type; ++ /* exact chipset, derived from NV_PMC_BOOT_0 */ ++ int chipset; ++ int flags; ++ ++ void __iomem *mmio; ++ void __iomem *ramin; ++ uint32_t ramin_size; ++ ++ struct work_struct irq_work; ++ struct list_head vbl_waiting; ++ ++ struct { ++ struct ttm_global_reference mem_global_ref; ++ struct ttm_bo_global_ref bo_global_ref; ++ struct ttm_bo_device bdev; ++ spinlock_t bo_list_lock; ++ struct list_head bo_list; ++ atomic_t validate_sequence; ++ } ttm; ++ ++ struct fb_info *fbdev_info; ++ ++ int fifo_alloc_count; ++ struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR]; ++ ++ struct nouveau_engine engine; ++ struct nouveau_channel *channel; ++ ++ /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ ++ struct nouveau_gpuobj *ramht; ++ uint32_t ramin_rsvd_vram; ++ uint32_t ramht_offset; ++ uint32_t ramht_size; ++ uint32_t ramht_bits; ++ uint32_t ramfc_offset; ++ uint32_t ramfc_size; ++ uint32_t ramro_offset; ++ uint32_t ramro_size; ++ ++ /* base physical adresses */ ++ uint64_t fb_phys; ++ uint64_t fb_available_size; ++ uint64_t fb_aper_free; ++ ++ struct { ++ enum { ++ NOUVEAU_GART_NONE = 0, ++ NOUVEAU_GART_AGP, ++ NOUVEAU_GART_SGDMA ++ } type; ++ uint64_t aper_base; ++ uint64_t aper_size; ++ uint64_t aper_free; ++ ++ struct nouveau_gpuobj *sg_ctxdma; ++ struct page *sg_dummy_page; ++ dma_addr_t sg_dummy_bus; ++ ++ /* nottm hack */ ++ struct drm_ttm_backend *sg_be; ++ unsigned long sg_handle; ++ } gart_info; ++ ++ /* G8x/G9x virtual address space */ ++ uint64_t vm_gart_base; ++ uint64_t vm_gart_size; ++ uint64_t vm_vram_base; ++ uint64_t vm_vram_size; ++ uint64_t vm_end; ++ struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; ++ int vm_vram_pt_nr; ++ ++ /* the mtrr covering the FB */ ++ int fb_mtrr; ++ ++ struct mem_block *ramin_heap; ++ ++ /* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */ ++ uint32_t ctx_table_size; ++ struct nouveau_gpuobj_ref *ctx_table; ++ ++ struct list_head gpuobj_list; ++ ++ struct nvbios VBIOS; ++ struct nouveau_bios_info *vbios; ++ ++ struct nv04_mode_state mode_reg; ++ struct nv04_mode_state saved_reg; ++ uint32_t saved_vga_font[4][16384]; ++ uint32_t crtc_owner; ++ uint32_t dac_users[4]; ++ ++ struct nouveau_suspend_resume { ++ uint32_t fifo_mode; ++ uint32_t graph_ctx_control; ++ uint32_t graph_state; ++ uint32_t *ramin_copy; ++ uint64_t ramin_size; ++ } susres; ++ ++ struct backlight_device *backlight; ++ bool acpi_dsm; ++ ++ struct nouveau_channel *evo; ++ ++ struct { ++ struct dentry *channel_root; ++ } debugfs; ++ ++ struct drm_gem_object *sfb_gem; ++}; ++ ++static inline struct drm_nouveau_private * ++nouveau_bdev(struct ttm_bo_device *bd) ++{ ++ return container_of(bd, struct drm_nouveau_private, ttm.bdev); ++} ++ ++static inline int ++nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo) ++{ ++ struct nouveau_bo *prev; ++ ++ if (!pnvbo) ++ return -EINVAL; ++ prev = *pnvbo; ++ ++ *pnvbo = ref ? nouveau_bo(ttm_bo_reference(&ref->bo)) : NULL; ++ if (prev) { ++ struct ttm_buffer_object *bo = &prev->bo; ++ ++ ttm_bo_unref(&bo); ++ } ++ ++ return 0; ++} ++ ++#define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do { \ ++ struct drm_nouveau_private *nv = dev->dev_private; \ ++ if (nv->init_state != NOUVEAU_CARD_INIT_DONE) { \ ++ NV_ERROR(dev, "called without init\n"); \ ++ return -EINVAL; \ ++ } \ ++} while (0) ++ ++#define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id, cl, ch) do { \ ++ struct drm_nouveau_private *nv = dev->dev_private; \ ++ if (!nouveau_channel_owner(dev, (cl), (id))) { \ ++ NV_ERROR(dev, "pid %d doesn't own channel %d\n", \ ++ DRM_CURRENTPID, (id)); \ ++ return -EPERM; \ ++ } \ ++ (ch) = nv->fifos[(id)]; \ ++} while (0) ++ ++/* nouveau_drv.c */ ++extern int nouveau_noagp; ++extern int nouveau_duallink; ++extern int nouveau_uscript_lvds; ++extern int nouveau_uscript_tmds; ++extern int nouveau_vram_pushbuf; ++extern int nouveau_vram_notify; ++extern int nouveau_fbpercrtc; ++extern int nouveau_tv; ++extern char *nouveau_tv_norm; ++extern int nouveau_reg_debug; ++extern char *nouveau_vbios; ++ ++/* nouveau_state.c */ ++extern void nouveau_preclose(struct drm_device *dev, struct drm_file *); ++extern int nouveau_load(struct drm_device *, unsigned long flags); ++extern int nouveau_firstopen(struct drm_device *); ++extern void nouveau_lastclose(struct drm_device *); ++extern int nouveau_unload(struct drm_device *); ++extern int nouveau_ioctl_getparam(struct drm_device *, void *data, ++ struct drm_file *); ++extern int nouveau_ioctl_setparam(struct drm_device *, void *data, ++ struct drm_file *); ++extern bool nouveau_wait_until(struct drm_device *, uint64_t timeout, ++ uint32_t reg, uint32_t mask, uint32_t val); ++extern bool nouveau_wait_for_idle(struct drm_device *); ++extern int nouveau_card_init(struct drm_device *); ++extern int nouveau_ioctl_card_init(struct drm_device *, void *data, ++ struct drm_file *); ++extern int nouveau_ioctl_suspend(struct drm_device *, void *data, ++ struct drm_file *); ++extern int nouveau_ioctl_resume(struct drm_device *, void *data, ++ struct drm_file *); ++ ++/* nouveau_mem.c */ ++extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start, ++ uint64_t size); ++extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *, ++ uint64_t size, int align2, ++ struct drm_file *, int tail); ++extern void nouveau_mem_takedown(struct mem_block **heap); ++extern void nouveau_mem_free_block(struct mem_block *); ++extern uint64_t nouveau_mem_fb_amount(struct drm_device *); ++extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap); ++extern int nouveau_mem_init(struct drm_device *); ++extern int nouveau_mem_init_agp(struct drm_device *); ++extern void nouveau_mem_close(struct drm_device *); ++extern int nv50_mem_vm_bind_linear(struct drm_device *, uint64_t virt, ++ uint32_t size, uint32_t flags, ++ uint64_t phys); ++extern void nv50_mem_vm_unbind(struct drm_device *, uint64_t virt, ++ uint32_t size); ++ ++/* nouveau_notifier.c */ ++extern int nouveau_notifier_init_channel(struct nouveau_channel *); ++extern void nouveau_notifier_takedown_channel(struct nouveau_channel *); ++extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, ++ int cout, uint32_t *offset); ++extern int nouveau_notifier_offset(struct nouveau_gpuobj *, uint32_t *); ++extern int nouveau_ioctl_notifier_alloc(struct drm_device *, void *data, ++ struct drm_file *); ++extern int nouveau_ioctl_notifier_free(struct drm_device *, void *data, ++ struct drm_file *); ++ ++/* nouveau_channel.c */ ++extern struct drm_ioctl_desc nouveau_ioctls[]; ++extern int nouveau_max_ioctl; ++extern void nouveau_channel_cleanup(struct drm_device *, struct drm_file *); ++extern int nouveau_channel_owner(struct drm_device *, struct drm_file *, ++ int channel); ++extern int nouveau_channel_alloc(struct drm_device *dev, ++ struct nouveau_channel **chan, ++ struct drm_file *file_priv, ++ uint32_t fb_ctxdma, uint32_t tt_ctxdma); ++extern void nouveau_channel_free(struct nouveau_channel *); ++extern int nouveau_channel_idle(struct nouveau_channel *chan); ++ ++/* nouveau_object.c */ ++extern int nouveau_gpuobj_early_init(struct drm_device *); ++extern int nouveau_gpuobj_init(struct drm_device *); ++extern void nouveau_gpuobj_takedown(struct drm_device *); ++extern void nouveau_gpuobj_late_takedown(struct drm_device *); ++extern int nouveau_gpuobj_suspend(struct drm_device *dev); ++extern void nouveau_gpuobj_suspend_cleanup(struct drm_device *dev); ++extern void nouveau_gpuobj_resume(struct drm_device *dev); ++extern int nouveau_gpuobj_channel_init(struct nouveau_channel *, ++ uint32_t vram_h, uint32_t tt_h); ++extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *); ++extern int nouveau_gpuobj_new(struct drm_device *, struct nouveau_channel *, ++ uint32_t size, int align, uint32_t flags, ++ struct nouveau_gpuobj **); ++extern int nouveau_gpuobj_del(struct drm_device *, struct nouveau_gpuobj **); ++extern int nouveau_gpuobj_ref_add(struct drm_device *, struct nouveau_channel *, ++ uint32_t handle, struct nouveau_gpuobj *, ++ struct nouveau_gpuobj_ref **); ++extern int nouveau_gpuobj_ref_del(struct drm_device *, ++ struct nouveau_gpuobj_ref **); ++extern int nouveau_gpuobj_ref_find(struct nouveau_channel *, uint32_t handle, ++ struct nouveau_gpuobj_ref **ref_ret); ++extern int nouveau_gpuobj_new_ref(struct drm_device *, ++ struct nouveau_channel *alloc_chan, ++ struct nouveau_channel *ref_chan, ++ uint32_t handle, uint32_t size, int align, ++ uint32_t flags, struct nouveau_gpuobj_ref **); ++extern int nouveau_gpuobj_new_fake(struct drm_device *, ++ uint32_t p_offset, uint32_t b_offset, ++ uint32_t size, uint32_t flags, ++ struct nouveau_gpuobj **, ++ struct nouveau_gpuobj_ref**); ++extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class, ++ uint64_t offset, uint64_t size, int access, ++ int target, struct nouveau_gpuobj **); ++extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *, ++ uint64_t offset, uint64_t size, ++ int access, struct nouveau_gpuobj **, ++ uint32_t *o_ret); ++extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, ++ struct nouveau_gpuobj **); ++extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, ++ struct drm_file *); ++extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, ++ struct drm_file *); ++ ++/* nouveau_irq.c */ ++extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); ++extern void nouveau_irq_preinstall(struct drm_device *); ++extern int nouveau_irq_postinstall(struct drm_device *); ++extern void nouveau_irq_uninstall(struct drm_device *); ++ ++/* nouveau_sgdma.c */ ++extern int nouveau_sgdma_init(struct drm_device *); ++extern void nouveau_sgdma_takedown(struct drm_device *); ++extern int nouveau_sgdma_get_page(struct drm_device *, uint32_t offset, ++ uint32_t *page); ++extern struct ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *); ++ ++/* nouveau_debugfs.c */ ++#if defined(CONFIG_DRM_NOUVEAU_DEBUG) ++extern int nouveau_debugfs_init(struct drm_minor *); ++extern void nouveau_debugfs_takedown(struct drm_minor *); ++extern int nouveau_debugfs_channel_init(struct nouveau_channel *); ++extern void nouveau_debugfs_channel_fini(struct nouveau_channel *); ++#else ++static inline int ++nouveau_debugfs_init(struct drm_minor *minor) ++{ ++ return 0; ++} ++ ++static inline void nouveau_debugfs_takedown(struct drm_minor *minor) ++{ ++} ++ ++static inline int ++nouveau_debugfs_channel_init(struct nouveau_channel *chan) ++{ ++ return 0; ++} ++ ++static inline void ++nouveau_debugfs_channel_fini(struct nouveau_channel *chan) ++{ ++} ++#endif ++ ++/* nouveau_dma.c */ ++extern int nouveau_dma_init(struct nouveau_channel *); ++extern int nouveau_dma_wait(struct nouveau_channel *, int size); ++ ++/* nouveau_acpi.c */ ++#ifdef CONFIG_ACPI ++extern int nouveau_hybrid_setup(struct drm_device *dev); ++extern bool nouveau_dsm_probe(struct drm_device *dev); ++#else ++static inline int nouveau_hybrid_setup(struct drm_device *dev) ++{ ++ return 0; ++} ++static inline bool nouveau_dsm_probe(struct drm_device *dev) ++{ ++ return false; ++} ++#endif ++ ++/* nouveau_backlight.c */ ++#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT ++extern int nouveau_backlight_init(struct drm_device *); ++extern void nouveau_backlight_exit(struct drm_device *); ++#else ++static inline int nouveau_backlight_init(struct drm_device *dev) ++{ ++ return 0; ++} ++ ++static inline void nouveau_backlight_exit(struct drm_device *dev) { } ++#endif ++ ++/* nouveau_bios.c */ ++extern int nouveau_bios_init(struct drm_device *); ++extern void nouveau_bios_takedown(struct drm_device *dev); ++extern int nouveau_run_vbios_init(struct drm_device *); ++extern void nouveau_bios_run_init_table(struct drm_device *, uint16_t table); ++extern int get_pll_limits(struct drm_device *, uint32_t limit_match, ++ struct pll_lims *); ++extern int nouveau_bios_run_display_table(struct drm_device *, ++ struct dcb_entry *, ++ uint32_t script, int pxclk); ++extern bool nouveau_bios_fp_mode(struct drm_device *, struct drm_display_mode *); ++extern uint8_t *nouveau_bios_embedded_edid(struct drm_device *); ++extern int nouveau_bios_parse_lvds_table(struct drm_device *, int pxclk, ++ bool *dl, bool *if_is_24bit); ++extern int run_tmds_table(struct drm_device *, struct dcb_entry *, ++ int head, int pxclk); ++extern int call_lvds_script(struct drm_device *, struct dcb_entry *, int head, ++ enum LVDS_script, int pxclk); ++ ++/* nouveau_ttm.c */ ++int nouveau_ttm_global_init(struct drm_nouveau_private *); ++void nouveau_ttm_global_release(struct drm_nouveau_private *); ++int nouveau_ttm_mmap(struct file *, struct vm_area_struct *); ++ ++/* nv04_fb.c */ ++extern int nv04_fb_init(struct drm_device *); ++extern void nv04_fb_takedown(struct drm_device *); ++ ++/* nv10_fb.c */ ++extern int nv10_fb_init(struct drm_device *); ++extern void nv10_fb_takedown(struct drm_device *); ++ ++/* nv40_fb.c */ ++extern int nv40_fb_init(struct drm_device *); ++extern void nv40_fb_takedown(struct drm_device *); ++ ++/* nv04_fifo.c */ ++extern int nv04_fifo_init(struct drm_device *); ++extern void nv04_fifo_disable(struct drm_device *); ++extern void nv04_fifo_enable(struct drm_device *); ++extern bool nv04_fifo_reassign(struct drm_device *, bool); ++extern int nv04_fifo_channel_id(struct drm_device *); ++extern int nv04_fifo_create_context(struct nouveau_channel *); ++extern void nv04_fifo_destroy_context(struct nouveau_channel *); ++extern int nv04_fifo_load_context(struct nouveau_channel *); ++extern int nv04_fifo_unload_context(struct drm_device *); ++ ++/* nv10_fifo.c */ ++extern int nv10_fifo_init(struct drm_device *); ++extern int nv10_fifo_channel_id(struct drm_device *); ++extern int nv10_fifo_create_context(struct nouveau_channel *); ++extern void nv10_fifo_destroy_context(struct nouveau_channel *); ++extern int nv10_fifo_load_context(struct nouveau_channel *); ++extern int nv10_fifo_unload_context(struct drm_device *); ++ ++/* nv40_fifo.c */ ++extern int nv40_fifo_init(struct drm_device *); ++extern int nv40_fifo_create_context(struct nouveau_channel *); ++extern void nv40_fifo_destroy_context(struct nouveau_channel *); ++extern int nv40_fifo_load_context(struct nouveau_channel *); ++extern int nv40_fifo_unload_context(struct drm_device *); ++ ++/* nv50_fifo.c */ ++extern int nv50_fifo_init(struct drm_device *); ++extern void nv50_fifo_takedown(struct drm_device *); ++extern int nv50_fifo_channel_id(struct drm_device *); ++extern int nv50_fifo_create_context(struct nouveau_channel *); ++extern void nv50_fifo_destroy_context(struct nouveau_channel *); ++extern int nv50_fifo_load_context(struct nouveau_channel *); ++extern int nv50_fifo_unload_context(struct drm_device *); ++ ++/* nv04_graph.c */ ++extern struct nouveau_pgraph_object_class nv04_graph_grclass[]; ++extern int nv04_graph_init(struct drm_device *); ++extern void nv04_graph_takedown(struct drm_device *); ++extern void nv04_graph_fifo_access(struct drm_device *, bool); ++extern struct nouveau_channel *nv04_graph_channel(struct drm_device *); ++extern int nv04_graph_create_context(struct nouveau_channel *); ++extern void nv04_graph_destroy_context(struct nouveau_channel *); ++extern int nv04_graph_load_context(struct nouveau_channel *); ++extern int nv04_graph_unload_context(struct drm_device *); ++extern void nv04_graph_context_switch(struct drm_device *); ++ ++/* nv10_graph.c */ ++extern struct nouveau_pgraph_object_class nv10_graph_grclass[]; ++extern int nv10_graph_init(struct drm_device *); ++extern void nv10_graph_takedown(struct drm_device *); ++extern struct nouveau_channel *nv10_graph_channel(struct drm_device *); ++extern int nv10_graph_create_context(struct nouveau_channel *); ++extern void nv10_graph_destroy_context(struct nouveau_channel *); ++extern int nv10_graph_load_context(struct nouveau_channel *); ++extern int nv10_graph_unload_context(struct drm_device *); ++extern void nv10_graph_context_switch(struct drm_device *); ++ ++/* nv20_graph.c */ ++extern struct nouveau_pgraph_object_class nv20_graph_grclass[]; ++extern struct nouveau_pgraph_object_class nv30_graph_grclass[]; ++extern int nv20_graph_create_context(struct nouveau_channel *); ++extern void nv20_graph_destroy_context(struct nouveau_channel *); ++extern int nv20_graph_load_context(struct nouveau_channel *); ++extern int nv20_graph_unload_context(struct drm_device *); ++extern int nv20_graph_init(struct drm_device *); ++extern void nv20_graph_takedown(struct drm_device *); ++extern int nv30_graph_init(struct drm_device *); ++ ++/* nv40_graph.c */ ++extern struct nouveau_pgraph_object_class nv40_graph_grclass[]; ++extern int nv40_graph_init(struct drm_device *); ++extern void nv40_graph_takedown(struct drm_device *); ++extern struct nouveau_channel *nv40_graph_channel(struct drm_device *); ++extern int nv40_graph_create_context(struct nouveau_channel *); ++extern void nv40_graph_destroy_context(struct nouveau_channel *); ++extern int nv40_graph_load_context(struct nouveau_channel *); ++extern int nv40_graph_unload_context(struct drm_device *); ++ ++/* nv50_graph.c */ ++extern struct nouveau_pgraph_object_class nv50_graph_grclass[]; ++extern int nv50_graph_init(struct drm_device *); ++extern void nv50_graph_takedown(struct drm_device *); ++extern void nv50_graph_fifo_access(struct drm_device *, bool); ++extern struct nouveau_channel *nv50_graph_channel(struct drm_device *); ++extern int nv50_graph_create_context(struct nouveau_channel *); ++extern void nv50_graph_destroy_context(struct nouveau_channel *); ++extern int nv50_graph_load_context(struct nouveau_channel *); ++extern int nv50_graph_unload_context(struct drm_device *); ++extern void nv50_graph_context_switch(struct drm_device *); ++ ++/* nv04_instmem.c */ ++extern int nv04_instmem_init(struct drm_device *); ++extern void nv04_instmem_takedown(struct drm_device *); ++extern int nv04_instmem_suspend(struct drm_device *); ++extern void nv04_instmem_resume(struct drm_device *); ++extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, ++ uint32_t *size); ++extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); ++extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); ++extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); ++extern void nv04_instmem_prepare_access(struct drm_device *, bool write); ++extern void nv04_instmem_finish_access(struct drm_device *); ++ ++/* nv50_instmem.c */ ++extern int nv50_instmem_init(struct drm_device *); ++extern void nv50_instmem_takedown(struct drm_device *); ++extern int nv50_instmem_suspend(struct drm_device *); ++extern void nv50_instmem_resume(struct drm_device *); ++extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, ++ uint32_t *size); ++extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); ++extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); ++extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); ++extern void nv50_instmem_prepare_access(struct drm_device *, bool write); ++extern void nv50_instmem_finish_access(struct drm_device *); ++ ++/* nv04_mc.c */ ++extern int nv04_mc_init(struct drm_device *); ++extern void nv04_mc_takedown(struct drm_device *); ++ ++/* nv40_mc.c */ ++extern int nv40_mc_init(struct drm_device *); ++extern void nv40_mc_takedown(struct drm_device *); ++ ++/* nv50_mc.c */ ++extern int nv50_mc_init(struct drm_device *); ++extern void nv50_mc_takedown(struct drm_device *); ++ ++/* nv04_timer.c */ ++extern int nv04_timer_init(struct drm_device *); ++extern uint64_t nv04_timer_read(struct drm_device *); ++extern void nv04_timer_takedown(struct drm_device *); ++ ++extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg); ++ ++/* nv04_dac.c */ ++extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry); ++extern enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, ++ struct drm_connector *connector); ++extern int nv04_dac_output_offset(struct drm_encoder *encoder); ++extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable); ++ ++/* nv04_dfp.c */ ++extern int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry); ++extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent); ++extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent, ++ int head, bool dl); ++extern void nv04_dfp_disable(struct drm_device *dev, int head); ++extern void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode); ++ ++/* nv04_tv.c */ ++extern int nv04_tv_identify(struct drm_device *dev, int i2c_index); ++extern int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry); ++ ++/* nv17_tv.c */ ++extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry); ++extern enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, ++ struct drm_connector *connector, ++ uint32_t pin_mask); ++ ++/* nv04_display.c */ ++extern int nv04_display_create(struct drm_device *); ++extern void nv04_display_destroy(struct drm_device *); ++extern void nv04_display_restore(struct drm_device *); ++ ++/* nv04_crtc.c */ ++extern int nv04_crtc_create(struct drm_device *, int index); ++ ++/* nouveau_bo.c */ ++extern struct ttm_bo_driver nouveau_bo_driver; ++extern int nouveau_bo_new(struct drm_device *, struct nouveau_channel *, ++ int size, int align, uint32_t flags, ++ uint32_t tile_mode, uint32_t tile_flags, ++ bool no_vm, bool mappable, struct nouveau_bo **); ++extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags); ++extern int nouveau_bo_unpin(struct nouveau_bo *); ++extern int nouveau_bo_map(struct nouveau_bo *); ++extern void nouveau_bo_unmap(struct nouveau_bo *); ++extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); ++extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); ++extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); ++extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); ++ ++/* nouveau_fence.c */ ++struct nouveau_fence; ++extern int nouveau_fence_init(struct nouveau_channel *); ++extern void nouveau_fence_fini(struct nouveau_channel *); ++extern void nouveau_fence_update(struct nouveau_channel *); ++extern int nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **, ++ bool emit); ++extern int nouveau_fence_emit(struct nouveau_fence *); ++struct nouveau_channel *nouveau_fence_channel(struct nouveau_fence *); ++extern bool nouveau_fence_signalled(void *obj, void *arg); ++extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr); ++extern int nouveau_fence_flush(void *obj, void *arg); ++extern void nouveau_fence_unref(void **obj); ++extern void *nouveau_fence_ref(void *obj); ++extern void nouveau_fence_handler(struct drm_device *dev, int channel); ++ ++/* nouveau_gem.c */ ++extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *, ++ int size, int align, uint32_t flags, ++ uint32_t tile_mode, uint32_t tile_flags, ++ bool no_vm, bool mappable, struct nouveau_bo **); ++extern int nouveau_gem_object_new(struct drm_gem_object *); ++extern void nouveau_gem_object_del(struct drm_gem_object *); ++extern int nouveau_gem_ioctl_new(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_pushbuf_call(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_pushbuf_call2(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_pin(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_unpin(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_tile(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_cpu_prep(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *, ++ struct drm_file *); ++extern int nouveau_gem_ioctl_info(struct drm_device *, void *, ++ struct drm_file *); ++ ++#ifndef ioread32_native ++#ifdef __BIG_ENDIAN ++#define ioread16_native ioread16be ++#define iowrite16_native iowrite16be ++#define ioread32_native ioread32be ++#define iowrite32_native iowrite32be ++#else /* def __BIG_ENDIAN */ ++#define ioread16_native ioread16 ++#define iowrite16_native iowrite16 ++#define ioread32_native ioread32 ++#define iowrite32_native iowrite32 ++#endif /* def __BIG_ENDIAN else */ ++#endif /* !ioread32_native */ ++ ++/* channel control reg access */ ++static inline u32 nvchan_rd32(struct nouveau_channel *chan, unsigned reg) ++{ ++ return ioread32_native(chan->user + reg); ++} ++ ++static inline void nvchan_wr32(struct nouveau_channel *chan, ++ unsigned reg, u32 val) ++{ ++ iowrite32_native(val, chan->user + reg); ++} ++ ++/* register access */ ++static inline u32 nv_rd32(struct drm_device *dev, unsigned reg) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ return ioread32_native(dev_priv->mmio + reg); ++} ++ ++static inline void nv_wr32(struct drm_device *dev, unsigned reg, u32 val) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ iowrite32_native(val, dev_priv->mmio + reg); ++} ++ ++static inline u8 nv_rd08(struct drm_device *dev, unsigned reg) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ return ioread8(dev_priv->mmio + reg); ++} ++ ++static inline void nv_wr08(struct drm_device *dev, unsigned reg, u8 val) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ iowrite8(val, dev_priv->mmio + reg); ++} ++ ++#define nv_wait(reg, mask, val) \ ++ nouveau_wait_until(dev, 2000000000ULL, (reg), (mask), (val)) ++ ++/* PRAMIN access */ ++static inline u32 nv_ri32(struct drm_device *dev, unsigned offset) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ return ioread32_native(dev_priv->ramin + offset); ++} ++ ++static inline void nv_wi32(struct drm_device *dev, unsigned offset, u32 val) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ iowrite32_native(val, dev_priv->ramin + offset); ++} ++ ++/* object access */ ++static inline u32 nv_ro32(struct drm_device *dev, struct nouveau_gpuobj *obj, ++ unsigned index) ++{ ++ return nv_ri32(dev, obj->im_pramin->start + index * 4); ++} ++ ++static inline void nv_wo32(struct drm_device *dev, struct nouveau_gpuobj *obj, ++ unsigned index, u32 val) ++{ ++ nv_wi32(dev, obj->im_pramin->start + index * 4, val); ++} ++ ++/* ++ * Logging ++ * Argument d is (struct drm_device *). ++ */ ++#define NV_PRINTK(level, d, fmt, arg...) \ ++ printk(level "[" DRM_NAME "] " DRIVER_NAME " %s: " fmt, \ ++ pci_name(d->pdev), ##arg) ++#ifndef NV_DEBUG_NOTRACE ++#define NV_DEBUG(d, fmt, arg...) do { \ ++ if (drm_debug) { \ ++ NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__, \ ++ __LINE__, ##arg); \ ++ } \ ++} while (0) ++#else ++#define NV_DEBUG(d, fmt, arg...) do { \ ++ if (drm_debug) \ ++ NV_PRINTK(KERN_DEBUG, d, fmt, ##arg); \ ++} while (0) ++#endif ++#define NV_ERROR(d, fmt, arg...) NV_PRINTK(KERN_ERR, d, fmt, ##arg) ++#define NV_INFO(d, fmt, arg...) NV_PRINTK(KERN_INFO, d, fmt, ##arg) ++#define NV_TRACEWARN(d, fmt, arg...) NV_PRINTK(KERN_NOTICE, d, fmt, ##arg) ++#define NV_TRACE(d, fmt, arg...) NV_PRINTK(KERN_INFO, d, fmt, ##arg) ++#define NV_WARN(d, fmt, arg...) NV_PRINTK(KERN_WARNING, d, fmt, ##arg) ++ ++/* nouveau_reg_debug bitmask */ ++enum { ++ NOUVEAU_REG_DEBUG_MC = 0x1, ++ NOUVEAU_REG_DEBUG_VIDEO = 0x2, ++ NOUVEAU_REG_DEBUG_FB = 0x4, ++ NOUVEAU_REG_DEBUG_EXTDEV = 0x8, ++ NOUVEAU_REG_DEBUG_CRTC = 0x10, ++ NOUVEAU_REG_DEBUG_RAMDAC = 0x20, ++ NOUVEAU_REG_DEBUG_VGACRTC = 0x40, ++ NOUVEAU_REG_DEBUG_RMVIO = 0x80, ++ NOUVEAU_REG_DEBUG_VGAATTR = 0x100, ++ NOUVEAU_REG_DEBUG_EVO = 0x200, ++}; ++ ++#define NV_REG_DEBUG(type, dev, fmt, arg...) do { \ ++ if (nouveau_reg_debug & NOUVEAU_REG_DEBUG_##type) \ ++ NV_PRINTK(KERN_DEBUG, dev, "%s: " fmt, __func__, ##arg); \ ++} while (0) ++ ++static inline enum nouveau_card_type ++nv_arch(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ switch (dev_priv->chipset & 0xf0) { ++ case 0x00: ++ return NV_04; ++ case 0x10: ++ return NV_10; ++ case 0x20: ++ return NV_20; ++ case 0x30: ++ return NV_30; ++ case 0x40: ++ case 0x60: ++ return NV_40; ++ case 0x50: ++ case 0x80: ++ case 0x90: ++ case 0xa0: ++ return NV_50; ++ default: ++ return NV_UNKNOWN; ++ } ++} ++ ++static inline bool ++nv_two_heads(struct drm_device *dev) ++{ ++ const int impl = dev->pci_device & 0x0ff0; ++ ++ if (nv_arch(dev) >= NV_10 && impl != 0x0100 && ++ impl != 0x0150 && impl != 0x01a0 && impl != 0x0200) ++ return true; ++ ++ return false; ++} ++ ++static inline bool ++nv_gf4_disp_arch(struct drm_device *dev) ++{ ++ return nv_two_heads(dev) && (dev->pci_device & 0x0ff0) != 0x0110; ++} ++ ++static inline bool ++nv_two_reg_pll(struct drm_device *dev) ++{ ++ const int impl = dev->pci_device & 0x0ff0; ++ ++ if (impl == 0x0310 || impl == 0x0340 || nv_arch(dev) >= NV_40) ++ return true; ++ return false; ++} ++ ++#define NV50_NVSW 0x0000506e ++#define NV50_NVSW_DMA_SEMAPHORE 0x00000060 ++#define NV50_NVSW_SEMAPHORE_OFFSET 0x00000064 ++#define NV50_NVSW_SEMAPHORE_ACQUIRE 0x00000068 ++#define NV50_NVSW_SEMAPHORE_RELEASE 0x0000006c ++#define NV50_NVSW_DMA_VBLSEM 0x0000018c ++#define NV50_NVSW_VBLSEM_OFFSET 0x00000400 ++#define NV50_NVSW_VBLSEM_RELEASE_VALUE 0x00000404 ++#define NV50_NVSW_VBLSEM_RELEASE 0x00000408 ++ ++#endif /* __NOUVEAU_DRV_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h +new file mode 100644 +index 0000000..ab823fc +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h +@@ -0,0 +1,66 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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_ENCODER_H__ ++#define __NOUVEAU_ENCODER_H__ ++ ++#include "drm_encoder_slave.h" ++#include "nouveau_drv.h" ++ ++#define NV_DPMS_CLEARED 0x80 ++ ++struct nouveau_encoder { ++ struct drm_encoder_slave base; ++ ++ struct dcb_entry *dcb; ++ int or; ++ ++ struct drm_display_mode mode; ++ int last_dpms; ++ ++ struct nv04_output_reg restore; ++ ++ void (*disconnect)(struct nouveau_encoder *encoder); ++}; ++ ++static inline struct nouveau_encoder *nouveau_encoder(struct drm_encoder *enc) ++{ ++ struct drm_encoder_slave *slave = to_encoder_slave(enc); ++ ++ return container_of(slave, struct nouveau_encoder, base); ++} ++ ++static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc) ++{ ++ return &enc->base.base; ++} ++ ++struct nouveau_connector * ++nouveau_encoder_connector_get(struct nouveau_encoder *encoder); ++int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry); ++int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry); ++ ++#endif /* __NOUVEAU_ENCODER_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_fb.h b/drivers/gpu/drm/nouveau/nouveau_fb.h +new file mode 100644 +index 0000000..4a3f31a +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_fb.h +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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_FB_H__ ++#define __NOUVEAU_FB_H__ ++ ++struct nouveau_framebuffer { ++ struct drm_framebuffer base; ++ struct nouveau_bo *nvbo; ++}; ++ ++static inline struct nouveau_framebuffer * ++nouveau_framebuffer(struct drm_framebuffer *fb) ++{ ++ return container_of(fb, struct nouveau_framebuffer, base); ++} ++ ++extern const struct drm_mode_config_funcs nouveau_mode_config_funcs; ++ ++struct drm_framebuffer * ++nouveau_framebuffer_create(struct drm_device *, struct nouveau_bo *, ++ struct drm_mode_fb_cmd *); ++ ++#endif /* __NOUVEAU_FB_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c +new file mode 100644 +index 0000000..36e8c5e +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c +@@ -0,0 +1,380 @@ ++/* ++ * Copyright © 2007 David Airlie ++ * ++ * 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. ++ * ++ * Authors: ++ * David Airlie ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "drmP.h" ++#include "drm.h" ++#include "drm_crtc.h" ++#include "drm_crtc_helper.h" ++#include "drm_fb_helper.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++#include "nouveau_crtc.h" ++#include "nouveau_fb.h" ++#include "nouveau_fbcon.h" ++#include "nouveau_dma.h" ++ ++static int ++nouveau_fbcon_sync(struct fb_info *info) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->channel; ++ int ret, i; ++ ++ if (!chan->accel_done || ++ info->state != FBINFO_STATE_RUNNING || ++ info->flags & FBINFO_HWACCEL_DISABLED) ++ return 0; ++ ++ if (RING_SPACE(chan, 4)) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ return 0; ++ } ++ ++ BEGIN_RING(chan, 0, 0x0104, 1); ++ OUT_RING(chan, 0); ++ BEGIN_RING(chan, 0, 0x0100, 1); ++ OUT_RING(chan, 0); ++ nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff); ++ FIRE_RING(chan); ++ ++ ret = -EBUSY; ++ for (i = 0; i < 100000; i++) { ++ if (!nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy + 3)) { ++ ret = 0; ++ break; ++ } ++ DRM_UDELAY(1); ++ } ++ ++ if (ret) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ return 0; ++ } ++ ++ chan->accel_done = false; ++ return 0; ++} ++ ++static struct fb_ops nouveau_fbcon_ops = { ++ .owner = THIS_MODULE, ++ .fb_check_var = drm_fb_helper_check_var, ++ .fb_set_par = drm_fb_helper_set_par, ++ .fb_setcolreg = drm_fb_helper_setcolreg, ++ .fb_fillrect = cfb_fillrect, ++ .fb_copyarea = cfb_copyarea, ++ .fb_imageblit = cfb_imageblit, ++ .fb_sync = nouveau_fbcon_sync, ++ .fb_pan_display = drm_fb_helper_pan_display, ++ .fb_blank = drm_fb_helper_blank, ++ .fb_setcmap = drm_fb_helper_setcmap, ++}; ++ ++static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, ++ u16 blue, int regno) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ ++ nv_crtc->lut.r[regno] = red; ++ nv_crtc->lut.g[regno] = green; ++ nv_crtc->lut.b[regno] = blue; ++} ++ ++static void nouveau_fbcon_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, ++ u16 *blue, int regno) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ ++ *red = nv_crtc->lut.r[regno]; ++ *green = nv_crtc->lut.g[regno]; ++ *blue = nv_crtc->lut.b[regno]; ++} ++ ++static struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = { ++ .gamma_set = nouveau_fbcon_gamma_set, ++ .gamma_get = nouveau_fbcon_gamma_get ++}; ++ ++#if defined(__i386__) || defined(__x86_64__) ++static bool ++nouveau_fbcon_has_vesafb_or_efifb(struct drm_device *dev) ++{ ++ struct pci_dev *pdev = dev->pdev; ++ int ramin; ++ ++ if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB && ++ screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) ++ return false; ++ ++ if (screen_info.lfb_base < pci_resource_start(pdev, 1)) ++ goto not_fb; ++ ++ if (screen_info.lfb_base + screen_info.lfb_size >= ++ pci_resource_start(pdev, 1) + pci_resource_len(pdev, 1)) ++ goto not_fb; ++ ++ return true; ++not_fb: ++ ramin = 2; ++ if (pci_resource_len(pdev, ramin) == 0) { ++ ramin = 3; ++ if (pci_resource_len(pdev, ramin) == 0) ++ return false; ++ } ++ ++ if (screen_info.lfb_base < pci_resource_start(pdev, ramin)) ++ return false; ++ ++ if (screen_info.lfb_base + screen_info.lfb_size >= ++ pci_resource_start(pdev, ramin) + pci_resource_len(pdev, ramin)) ++ return false; ++ ++ return true; ++} ++#endif ++ ++void ++nouveau_fbcon_zfill(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct fb_info *info = dev_priv->fbdev_info; ++ struct fb_fillrect rect; ++ ++ /* Clear the entire fbcon. The drm will program every connector ++ * with it's preferred mode. If the sizes differ, one display will ++ * quite likely have garbage around the console. ++ */ ++ rect.dx = rect.dy = 0; ++ rect.width = info->var.xres_virtual; ++ rect.height = info->var.yres_virtual; ++ rect.color = 0; ++ rect.rop = ROP_COPY; ++ info->fbops->fb_fillrect(info, &rect); ++} ++ ++static int ++nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width, ++ uint32_t fb_height, uint32_t surface_width, ++ uint32_t surface_height, uint32_t surface_depth, ++ uint32_t surface_bpp, struct drm_framebuffer **pfb) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct fb_info *info; ++ struct nouveau_fbcon_par *par; ++ struct drm_framebuffer *fb; ++ struct nouveau_framebuffer *nouveau_fb; ++ struct nouveau_bo *nvbo; ++ struct drm_mode_fb_cmd mode_cmd; ++ struct device *device = &dev->pdev->dev; ++ int size, ret; ++ ++ mode_cmd.width = surface_width; ++ mode_cmd.height = surface_height; ++ ++ mode_cmd.bpp = surface_bpp; ++ mode_cmd.pitch = mode_cmd.width * (mode_cmd.bpp >> 3); ++ mode_cmd.pitch = ALIGN(mode_cmd.pitch, 256); ++ mode_cmd.depth = surface_depth; ++ ++ size = mode_cmd.pitch * mode_cmd.height; ++ size = ALIGN(size, PAGE_SIZE); ++ ++ ret = nouveau_gem_new(dev, dev_priv->channel, size, 0, TTM_PL_FLAG_VRAM, ++ 0, 0x0000, false, true, &nvbo); ++ if (ret) { ++ NV_ERROR(dev, "failed to allocate framebuffer\n"); ++ goto out; ++ } ++ ++ ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM); ++ if (ret) { ++ NV_ERROR(dev, "failed to pin fb: %d\n", ret); ++ nouveau_bo_ref(NULL, &nvbo); ++ goto out; ++ } ++ ++ ret = nouveau_bo_map(nvbo); ++ if (ret) { ++ NV_ERROR(dev, "failed to map fb: %d\n", ret); ++ nouveau_bo_unpin(nvbo); ++ nouveau_bo_ref(NULL, &nvbo); ++ goto out; ++ } ++ ++ mutex_lock(&dev->struct_mutex); ++ ++ fb = nouveau_framebuffer_create(dev, nvbo, &mode_cmd); ++ if (!fb) { ++ ret = -ENOMEM; ++ NV_ERROR(dev, "failed to allocate fb.\n"); ++ goto out_unref; ++ } ++ ++ list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list); ++ ++ nouveau_fb = nouveau_framebuffer(fb); ++ *pfb = fb; ++ ++ info = framebuffer_alloc(sizeof(struct nouveau_fbcon_par), device); ++ if (!info) { ++ ret = -ENOMEM; ++ goto out_unref; ++ } ++ ++ par = info->par; ++ par->helper.funcs = &nouveau_fbcon_helper_funcs; ++ par->helper.dev = dev; ++ ret = drm_fb_helper_init_crtc_count(&par->helper, 2, 4); ++ if (ret) ++ goto out_unref; ++ dev_priv->fbdev_info = info; ++ ++ strcpy(info->fix.id, "nouveaufb"); ++ info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | ++ FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT; ++ info->fbops = &nouveau_fbcon_ops; ++ info->fix.smem_start = dev->mode_config.fb_base + nvbo->bo.offset - ++ dev_priv->vm_vram_base; ++ info->fix.smem_len = size; ++ ++ info->screen_base = nvbo_kmap_obj_iovirtual(nouveau_fb->nvbo); ++ info->screen_size = size; ++ ++ drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); ++ drm_fb_helper_fill_var(info, fb, fb_width, fb_height); ++ ++ /* FIXME: we really shouldn't expose mmio space at all */ ++ info->fix.mmio_start = pci_resource_start(dev->pdev, 1); ++ info->fix.mmio_len = pci_resource_len(dev->pdev, 1); ++ ++ /* Set aperture base/size for vesafb takeover */ ++#if defined(__i386__) || defined(__x86_64__) ++ if (nouveau_fbcon_has_vesafb_or_efifb(dev)) { ++ /* Some NVIDIA VBIOS' are stupid and decide to put the ++ * framebuffer in the middle of the PRAMIN BAR for ++ * whatever reason. We need to know the exact lfb_base ++ * to get vesafb kicked off, and the only reliable way ++ * we have left is to find out lfb_base the same way ++ * vesafb did. ++ */ ++ info->aperture_base = screen_info.lfb_base; ++ info->aperture_size = screen_info.lfb_size; ++ if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB) ++ info->aperture_size *= 65536; ++ } else ++#endif ++ { ++ info->aperture_base = info->fix.mmio_start; ++ info->aperture_size = info->fix.mmio_len; ++ } ++ ++ info->pixmap.size = 64*1024; ++ info->pixmap.buf_align = 8; ++ info->pixmap.access_align = 32; ++ info->pixmap.flags = FB_PIXMAP_SYSTEM; ++ info->pixmap.scan_align = 1; ++ ++ fb->fbdev = info; ++ ++ par->nouveau_fb = nouveau_fb; ++ par->dev = dev; ++ ++ switch (dev_priv->card_type) { ++ case NV_50: ++ nv50_fbcon_accel_init(info); ++ break; ++ default: ++ nv04_fbcon_accel_init(info); ++ break; ++ }; ++ ++ nouveau_fbcon_zfill(dev); ++ ++ /* To allow resizeing without swapping buffers */ ++ NV_INFO(dev, "allocated %dx%d fb: 0x%lx, bo %p\n", ++ nouveau_fb->base.width, ++ nouveau_fb->base.height, ++ nvbo->bo.offset, nvbo); ++ ++ mutex_unlock(&dev->struct_mutex); ++ return 0; ++ ++out_unref: ++ mutex_unlock(&dev->struct_mutex); ++out: ++ return ret; ++} ++ ++int ++nouveau_fbcon_probe(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ return drm_fb_helper_single_fb_probe(dev, 32, nouveau_fbcon_create); ++} ++ ++int ++nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb) ++{ ++ struct nouveau_framebuffer *nouveau_fb = nouveau_framebuffer(fb); ++ struct fb_info *info; ++ ++ if (!fb) ++ return -EINVAL; ++ ++ info = fb->fbdev; ++ if (info) { ++ struct nouveau_fbcon_par *par = info->par; ++ ++ unregister_framebuffer(info); ++ nouveau_bo_unmap(nouveau_fb->nvbo); ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(nouveau_fb->nvbo->gem); ++ nouveau_fb->nvbo = NULL; ++ mutex_unlock(&dev->struct_mutex); ++ if (par) ++ drm_fb_helper_free(&par->helper); ++ framebuffer_release(info); ++ } ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h +new file mode 100644 +index 0000000..8531140 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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_FBCON_H__ ++#define __NOUVEAU_FBCON_H__ ++ ++#include "drm_fb_helper.h" ++ ++struct nouveau_fbcon_par { ++ struct drm_fb_helper helper; ++ struct drm_device *dev; ++ struct nouveau_framebuffer *nouveau_fb; ++}; ++ ++int nouveau_fbcon_probe(struct drm_device *dev); ++int nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb); ++void nouveau_fbcon_restore(void); ++void nouveau_fbcon_zfill(struct drm_device *dev); ++ ++int nv04_fbcon_accel_init(struct fb_info *info); ++int nv50_fbcon_accel_init(struct fb_info *info); ++ ++#endif /* __NV50_FBCON_H__ */ ++ +diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c +new file mode 100644 +index 0000000..0cff7eb +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_fence.c +@@ -0,0 +1,262 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++ ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++ ++#define USE_REFCNT (dev_priv->card_type >= NV_10) ++ ++struct nouveau_fence { ++ struct nouveau_channel *channel; ++ struct kref refcount; ++ struct list_head entry; ++ ++ uint32_t sequence; ++ bool signalled; ++}; ++ ++static inline struct nouveau_fence * ++nouveau_fence(void *sync_obj) ++{ ++ return (struct nouveau_fence *)sync_obj; ++} ++ ++static void ++nouveau_fence_del(struct kref *ref) ++{ ++ struct nouveau_fence *fence = ++ container_of(ref, struct nouveau_fence, refcount); ++ ++ kfree(fence); ++} ++ ++void ++nouveau_fence_update(struct nouveau_channel *chan) ++{ ++ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; ++ struct list_head *entry, *tmp; ++ struct nouveau_fence *fence; ++ uint32_t sequence; ++ ++ if (USE_REFCNT) ++ sequence = nvchan_rd32(chan, 0x48); ++ else ++ sequence = chan->fence.last_sequence_irq; ++ ++ if (chan->fence.sequence_ack == sequence) ++ return; ++ chan->fence.sequence_ack = sequence; ++ ++ list_for_each_safe(entry, tmp, &chan->fence.pending) { ++ fence = list_entry(entry, struct nouveau_fence, entry); ++ ++ sequence = fence->sequence; ++ fence->signalled = true; ++ list_del(&fence->entry); ++ kref_put(&fence->refcount, nouveau_fence_del); ++ ++ if (sequence == chan->fence.sequence_ack) ++ break; ++ } ++} ++ ++int ++nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **pfence, ++ bool emit) ++{ ++ struct nouveau_fence *fence; ++ int ret = 0; ++ ++ fence = kzalloc(sizeof(*fence), GFP_KERNEL); ++ if (!fence) ++ return -ENOMEM; ++ kref_init(&fence->refcount); ++ fence->channel = chan; ++ ++ if (emit) ++ ret = nouveau_fence_emit(fence); ++ ++ if (ret) ++ nouveau_fence_unref((void *)&fence); ++ *pfence = fence; ++ return ret; ++} ++ ++struct nouveau_channel * ++nouveau_fence_channel(struct nouveau_fence *fence) ++{ ++ return fence ? fence->channel : NULL; ++} ++ ++int ++nouveau_fence_emit(struct nouveau_fence *fence) ++{ ++ struct drm_nouveau_private *dev_priv = fence->channel->dev->dev_private; ++ struct nouveau_channel *chan = fence->channel; ++ unsigned long flags; ++ int ret; ++ ++ ret = RING_SPACE(chan, 2); ++ if (ret) ++ return ret; ++ ++ if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) { ++ spin_lock_irqsave(&chan->fence.lock, flags); ++ nouveau_fence_update(chan); ++ spin_unlock_irqrestore(&chan->fence.lock, flags); ++ ++ BUG_ON(chan->fence.sequence == ++ chan->fence.sequence_ack - 1); ++ } ++ ++ fence->sequence = ++chan->fence.sequence; ++ ++ kref_get(&fence->refcount); ++ spin_lock_irqsave(&chan->fence.lock, flags); ++ list_add_tail(&fence->entry, &chan->fence.pending); ++ spin_unlock_irqrestore(&chan->fence.lock, flags); ++ ++ BEGIN_RING(chan, NvSubM2MF, USE_REFCNT ? 0x0050 : 0x0150, 1); ++ OUT_RING(chan, fence->sequence); ++ FIRE_RING(chan); ++ ++ return 0; ++} ++ ++void ++nouveau_fence_unref(void **sync_obj) ++{ ++ struct nouveau_fence *fence = nouveau_fence(*sync_obj); ++ ++ if (fence) ++ kref_put(&fence->refcount, nouveau_fence_del); ++ *sync_obj = NULL; ++} ++ ++void * ++nouveau_fence_ref(void *sync_obj) ++{ ++ struct nouveau_fence *fence = nouveau_fence(sync_obj); ++ ++ kref_get(&fence->refcount); ++ return sync_obj; ++} ++ ++bool ++nouveau_fence_signalled(void *sync_obj, void *sync_arg) ++{ ++ struct nouveau_fence *fence = nouveau_fence(sync_obj); ++ struct nouveau_channel *chan = fence->channel; ++ unsigned long flags; ++ ++ if (fence->signalled) ++ return true; ++ ++ spin_lock_irqsave(&chan->fence.lock, flags); ++ nouveau_fence_update(chan); ++ spin_unlock_irqrestore(&chan->fence.lock, flags); ++ return fence->signalled; ++} ++ ++int ++nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) ++{ ++ unsigned long timeout = jiffies + (3 * DRM_HZ); ++ int ret = 0; ++ ++ __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); ++ ++ while (1) { ++ if (nouveau_fence_signalled(sync_obj, sync_arg)) ++ break; ++ ++ if (time_after_eq(jiffies, timeout)) { ++ ret = -EBUSY; ++ break; ++ } ++ ++ if (lazy) ++ schedule_timeout(1); ++ ++ if (intr && signal_pending(current)) { ++ ret = -ERESTART; ++ break; ++ } ++ } ++ ++ __set_current_state(TASK_RUNNING); ++ ++ return ret; ++} ++ ++int ++nouveau_fence_flush(void *sync_obj, void *sync_arg) ++{ ++ return 0; ++} ++ ++void ++nouveau_fence_handler(struct drm_device *dev, int channel) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = NULL; ++ ++ if (channel >= 0 && channel < dev_priv->engine.fifo.channels) ++ chan = dev_priv->fifos[channel]; ++ ++ if (chan) { ++ spin_lock_irq(&chan->fence.lock); ++ nouveau_fence_update(chan); ++ spin_unlock_irq(&chan->fence.lock); ++ } ++} ++ ++int ++nouveau_fence_init(struct nouveau_channel *chan) ++{ ++ INIT_LIST_HEAD(&chan->fence.pending); ++ spin_lock_init(&chan->fence.lock); ++ return 0; ++} ++ ++void ++nouveau_fence_fini(struct nouveau_channel *chan) ++{ ++ struct list_head *entry, *tmp; ++ struct nouveau_fence *fence; ++ ++ list_for_each_safe(entry, tmp, &chan->fence.pending) { ++ fence = list_entry(entry, struct nouveau_fence, entry); ++ ++ fence->signalled = true; ++ list_del(&fence->entry); ++ kref_put(&fence->refcount, nouveau_fence_del); ++ } ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c +new file mode 100644 +index 0000000..b8c3664 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_gem.c +@@ -0,0 +1,981 @@ ++/* ++ * Copyright (C) 2008 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++ ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++#include "nouveau_dma.h" ++ ++#define nouveau_gem_pushbuf_sync(chan) 0 ++ ++int ++nouveau_gem_object_new(struct drm_gem_object *gem) ++{ ++ return 0; ++} ++ ++void ++nouveau_gem_object_del(struct drm_gem_object *gem) ++{ ++ struct nouveau_bo *nvbo = gem->driver_private; ++ struct ttm_buffer_object *bo = &nvbo->bo; ++ ++ if (!nvbo) ++ return; ++ nvbo->gem = NULL; ++ ++ if (unlikely(nvbo->cpu_filp)) ++ ttm_bo_synccpu_write_release(bo); ++ ++ if (unlikely(nvbo->pin_refcnt)) { ++ nvbo->pin_refcnt = 1; ++ nouveau_bo_unpin(nvbo); ++ } ++ ++ ttm_bo_unref(&bo); ++} ++ ++int ++nouveau_gem_new(struct drm_device *dev, struct nouveau_channel *chan, ++ int size, int align, uint32_t flags, uint32_t tile_mode, ++ uint32_t tile_flags, bool no_vm, bool mappable, ++ struct nouveau_bo **pnvbo) ++{ ++ struct nouveau_bo *nvbo; ++ int ret; ++ ++ ret = nouveau_bo_new(dev, chan, size, align, flags, tile_mode, ++ tile_flags, no_vm, mappable, pnvbo); ++ if (ret) ++ return ret; ++ nvbo = *pnvbo; ++ ++ nvbo->gem = drm_gem_object_alloc(dev, nvbo->bo.mem.size); ++ if (!nvbo->gem) { ++ nouveau_bo_ref(NULL, pnvbo); ++ return -ENOMEM; ++ } ++ ++ nvbo->bo.persistant_swap_storage = nvbo->gem->filp; ++ nvbo->gem->driver_private = nvbo; ++ return 0; ++} ++ ++static int ++nouveau_gem_info(struct drm_gem_object *gem, struct drm_nouveau_gem_info *rep) ++{ ++ struct nouveau_bo *nvbo = nouveau_gem_object(gem); ++ ++ if (nvbo->bo.mem.mem_type == TTM_PL_TT) ++ rep->domain = NOUVEAU_GEM_DOMAIN_GART; ++ else ++ rep->domain = NOUVEAU_GEM_DOMAIN_VRAM; ++ ++ rep->size = nvbo->bo.mem.num_pages << PAGE_SHIFT; ++ rep->offset = nvbo->bo.offset; ++ rep->map_handle = nvbo->mappable ? nvbo->bo.addr_space_offset : 0; ++ rep->tile_mode = nvbo->tile_mode; ++ rep->tile_flags = nvbo->tile_flags; ++ return 0; ++} ++ ++static bool ++nouveau_gem_tile_mode_valid(struct drm_device *dev, uint32_t tile_flags) { ++ switch (tile_flags) { ++ case 0x0000: ++ case 0x1800: ++ case 0x2800: ++ case 0x4800: ++ case 0x7000: ++ case 0x7400: ++ case 0x7a00: ++ case 0xe000: ++ break; ++ default: ++ NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags); ++ return false; ++ } ++ ++ return true; ++} ++ ++int ++nouveau_gem_ioctl_new(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_nouveau_gem_new *req = data; ++ struct nouveau_bo *nvbo = NULL; ++ struct nouveau_channel *chan = NULL; ++ uint32_t flags = 0; ++ int ret = 0; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL)) ++ dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping; ++ ++ if (req->channel_hint) { ++ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel_hint, ++ file_priv, chan); ++ } ++ ++ if (req->info.domain & NOUVEAU_GEM_DOMAIN_VRAM) ++ flags |= TTM_PL_FLAG_VRAM; ++ if (req->info.domain & NOUVEAU_GEM_DOMAIN_GART) ++ flags |= TTM_PL_FLAG_TT; ++ if (!flags || req->info.domain & NOUVEAU_GEM_DOMAIN_CPU) ++ flags |= TTM_PL_FLAG_SYSTEM; ++ ++ if (req->info.tile_mode > 4) { ++ NV_ERROR(dev, "bad tile mode: %d\n", req->info.tile_mode); ++ return -EINVAL; ++ } ++ ++ if (!nouveau_gem_tile_mode_valid(dev, req->info.tile_flags)) ++ return -EINVAL; ++ ++ ret = nouveau_gem_new(dev, chan, req->info.size, req->align, flags, ++ req->info.tile_mode, req->info.tile_flags, false, ++ (req->info.domain & NOUVEAU_GEM_DOMAIN_MAPPABLE), ++ &nvbo); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_gem_info(nvbo->gem, &req->info); ++ if (ret) ++ goto out; ++ ++ ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); ++out: ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_handle_unreference(nvbo->gem); ++ mutex_unlock(&dev->struct_mutex); ++ ++ if (ret) ++ drm_gem_object_unreference(nvbo->gem); ++ return ret; ++} ++ ++static int ++nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains, ++ uint32_t write_domains, uint32_t valid_domains) ++{ ++ struct nouveau_bo *nvbo = gem->driver_private; ++ struct ttm_buffer_object *bo = &nvbo->bo; ++ uint64_t flags; ++ ++ if (!valid_domains || (!read_domains && !write_domains)) ++ return -EINVAL; ++ ++ if (write_domains) { ++ if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && ++ (write_domains & NOUVEAU_GEM_DOMAIN_VRAM)) ++ flags = TTM_PL_FLAG_VRAM; ++ else ++ if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) && ++ (write_domains & NOUVEAU_GEM_DOMAIN_GART)) ++ flags = TTM_PL_FLAG_TT; ++ else ++ return -EINVAL; ++ } else { ++ if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && ++ (read_domains & NOUVEAU_GEM_DOMAIN_VRAM) && ++ (bo->mem.mem_type == TTM_PL_VRAM || ++ bo->mem.mem_type == TTM_PL_PRIV0)) ++ flags = TTM_PL_FLAG_VRAM; ++ else ++ if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) && ++ (read_domains & NOUVEAU_GEM_DOMAIN_GART) && ++ bo->mem.mem_type == TTM_PL_TT) ++ flags = TTM_PL_FLAG_TT; ++ else ++ if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && ++ (read_domains & NOUVEAU_GEM_DOMAIN_VRAM)) ++ flags = TTM_PL_FLAG_VRAM; ++ else ++ flags = TTM_PL_FLAG_TT; ++ } ++ ++ if ((flags & TTM_PL_FLAG_VRAM) && !nvbo->mappable) ++ flags |= TTM_PL_FLAG_PRIV0; ++ ++ bo->proposed_placement &= ~TTM_PL_MASK_MEM; ++ bo->proposed_placement |= flags; ++ return 0; ++} ++ ++static void ++nouveau_gem_pushbuf_backoff(struct list_head *list) ++{ ++ struct list_head *entry, *tmp; ++ struct nouveau_bo *nvbo; ++ ++ list_for_each_safe(entry, tmp, list) { ++ nvbo = list_entry(entry, struct nouveau_bo, entry); ++ ++ list_del(&nvbo->entry); ++ nvbo->reserved_by = NULL; ++ ttm_bo_unreserve(&nvbo->bo); ++ drm_gem_object_unreference(nvbo->gem); ++ } ++} ++ ++static void ++nouveau_gem_pushbuf_fence(struct list_head *list, struct nouveau_fence *fence) ++{ ++ struct list_head *entry, *tmp; ++ struct nouveau_fence *prev_fence; ++ struct nouveau_bo *nvbo; ++ ++ list_for_each_safe(entry, tmp, list) { ++ nvbo = list_entry(entry, struct nouveau_bo, entry); ++ ++ spin_lock(&nvbo->bo.lock); ++ prev_fence = nvbo->bo.sync_obj; ++ nvbo->bo.sync_obj = nouveau_fence_ref(fence); ++ spin_unlock(&nvbo->bo.lock); ++ ++ list_del(&nvbo->entry); ++ nvbo->reserved_by = NULL; ++ ttm_bo_unreserve(&nvbo->bo); ++ drm_gem_object_unreference(nvbo->gem); ++ ++ nouveau_fence_unref((void *)&prev_fence); ++ } ++} ++ ++static int ++nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, ++ struct drm_file *file_priv, ++ struct drm_nouveau_gem_pushbuf_bo *pbbo, ++ uint64_t user_buffers, int nr_buffers, ++ struct list_head *list, int *apply_relocs) ++{ ++ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_gem_pushbuf_bo *b; ++ struct drm_nouveau_gem_pushbuf_bo __user *user_pbbos = ++ (void __force __user *)(uintptr_t)user_buffers; ++ struct nouveau_fence *prev_fence; ++ struct nouveau_bo *nvbo; ++ struct list_head *entry, *tmp; ++ uint32_t sequence; ++ int ret = -EINVAL; ++ int i; ++ int trycnt = 0; ++ ++ if (nr_buffers == 0) ++ return 0; ++ ++ sequence = atomic_add_return(1, &dev_priv->ttm.validate_sequence); ++retry: ++ if (++trycnt > 100000) { ++ ret = -EINVAL; ++ NV_ERROR(dev, "%s failed and gave up.\n", __func__); ++ goto out_unref; ++ } ++ ++ for (i = 0, b = pbbo; i < nr_buffers; i++, b++) { ++ struct drm_gem_object *gem; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, b->handle); ++ if (!gem) { ++ NV_ERROR(dev, "Unknown handle 0x%08x\n", b->handle); ++ ret = -EINVAL; ++ goto out_unref; ++ } ++ nvbo = gem->driver_private; ++ ++ if (nvbo->reserved_by && nvbo->reserved_by == file_priv) { ++ NV_INFO(dev, "multiple instances of buffer %d on " ++ "validation list\n", b->handle); ++ ret = -EINVAL; ++ goto out_unref; ++ } ++ ++ ret = ttm_bo_reserve(&nvbo->bo, false, false, true, sequence); ++ if (ret) { ++ nouveau_gem_pushbuf_backoff(list); ++ if (ret == -EAGAIN) ++ ret = ttm_bo_wait_unreserved(&nvbo->bo, false); ++ drm_gem_object_unreference(gem); ++ if (ret) ++ goto out_unref; ++ goto retry; ++ } ++ ++ nvbo->reserved_by = file_priv; ++ list_add_tail(&nvbo->entry, list); ++ ++ if (unlikely(atomic_read(&nvbo->bo.cpu_writers) > 0)) { ++ nouveau_gem_pushbuf_backoff(list); ++ ++ if (nvbo->cpu_filp == file_priv) { ++ NV_ERROR(dev, "bo %p mapped by process trying " ++ "to validate it!\n", nvbo); ++ ret = -EINVAL; ++ goto out_unref; ++ } ++ ++ ret = ttm_bo_wait_cpu(&nvbo->bo, false); ++ if (ret == -ERESTART) ++ ret = -EAGAIN; ++ if (ret) ++ goto out_unref; ++ goto retry; ++ } ++ } ++ ++ b = pbbo; ++ list_for_each_safe(entry, tmp, list) { ++ nvbo = list_entry(entry, struct nouveau_bo, entry); ++ ++ prev_fence = nvbo->bo.sync_obj; ++ if (prev_fence && nouveau_fence_channel(prev_fence) != chan) { ++ spin_lock(&nvbo->bo.lock); ++ ret = ttm_bo_wait(&nvbo->bo, false, false, false); ++ spin_unlock(&nvbo->bo.lock); ++ if (ret) ++ goto out_unref; ++ } ++ ++ ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, ++ b->write_domains, ++ b->valid_domains); ++ if (ret) ++ goto out_unref; ++ ++ nvbo->channel = chan; ++ ret = ttm_buffer_object_validate(&nvbo->bo, ++ nvbo->bo.proposed_placement, ++ false, false); ++ nvbo->channel = NULL; ++ if (ret) ++ goto out_unref; ++ ++ if (nvbo->bo.offset == b->presumed_offset && ++ (((nvbo->bo.mem.mem_type == TTM_PL_VRAM || ++ nvbo->bo.mem.mem_type == TTM_PL_PRIV0) && ++ b->presumed_domain & NOUVEAU_GEM_DOMAIN_VRAM) || ++ (nvbo->bo.mem.mem_type == TTM_PL_TT && ++ b->presumed_domain & NOUVEAU_GEM_DOMAIN_GART))) { ++ b++; ++ user_pbbos++; ++ continue; ++ } ++ ++ if (nvbo->bo.mem.mem_type == TTM_PL_TT) ++ b->presumed_domain = NOUVEAU_GEM_DOMAIN_GART; ++ else ++ b->presumed_domain = NOUVEAU_GEM_DOMAIN_VRAM; ++ b->presumed_offset = nvbo->bo.offset; ++ b->presumed_ok = 0; ++ (*apply_relocs)++; ++ ++ if (DRM_COPY_TO_USER(user_pbbos, b, sizeof(*b))) { ++ ret = -EFAULT; ++ goto out_unref; ++ } ++ ++ b++; ++ user_pbbos++; ++ } ++ ++out_unref: ++ if (unlikely(ret)) ++ nouveau_gem_pushbuf_backoff(list); ++ ++ return ret; ++} ++ ++static inline void * ++u_memcpya(uint64_t user, unsigned nmemb, unsigned size) ++{ ++ void *mem; ++ void __user *userptr = (void __force __user *)(uintptr_t)user; ++ ++ mem = kmalloc(nmemb * size, GFP_KERNEL); ++ if (!mem) ++ return ERR_PTR(-ENOMEM); ++ ++ if (DRM_COPY_FROM_USER(mem, userptr, nmemb * size)) { ++ kfree(mem); ++ return ERR_PTR(-EFAULT); ++ } ++ ++ return mem; ++} ++ ++static int ++nouveau_gem_pushbuf_reloc_apply(struct nouveau_channel *chan, int nr_bo, ++ struct drm_nouveau_gem_pushbuf_bo *bo, ++ int nr_relocs, uint64_t ptr_relocs, ++ int nr_dwords, int first_dword, ++ uint32_t *pushbuf, bool is_iomem) ++{ ++ struct drm_nouveau_gem_pushbuf_reloc *reloc = NULL; ++ struct drm_device *dev = chan->dev; ++ int ret = 0, i; ++ ++ reloc = u_memcpya(ptr_relocs, nr_relocs, sizeof(*reloc)); ++ if (IS_ERR(reloc)) ++ return PTR_ERR(reloc); ++ ++ for (i = 0; i < nr_relocs; i++) { ++ struct drm_nouveau_gem_pushbuf_reloc *r = &reloc[i]; ++ struct drm_nouveau_gem_pushbuf_bo *b; ++ uint32_t data; ++ ++ if (r->bo_index >= nr_bo || r->reloc_index < first_dword || ++ r->reloc_index >= first_dword + nr_dwords) { ++ NV_ERROR(dev, "Bad relocation %d\n", i); ++ NV_ERROR(dev, " bo: %d max %d\n", r->bo_index, nr_bo); ++ NV_ERROR(dev, " id: %d max %d\n", r->reloc_index, nr_dwords); ++ ret = -EINVAL; ++ break; ++ } ++ ++ b = &bo[r->bo_index]; ++ if (b->presumed_ok) ++ continue; ++ ++ if (r->flags & NOUVEAU_GEM_RELOC_LOW) ++ data = b->presumed_offset + r->data; ++ else ++ if (r->flags & NOUVEAU_GEM_RELOC_HIGH) ++ data = (b->presumed_offset + r->data) >> 32; ++ else ++ data = r->data; ++ ++ if (r->flags & NOUVEAU_GEM_RELOC_OR) { ++ if (b->presumed_domain == NOUVEAU_GEM_DOMAIN_GART) ++ data |= r->tor; ++ else ++ data |= r->vor; ++ } ++ ++ if (is_iomem) ++ iowrite32_native(data, (void __force __iomem *) ++ &pushbuf[r->reloc_index]); ++ else ++ pushbuf[r->reloc_index] = data; ++ } ++ ++ kfree(reloc); ++ return ret; ++} ++ ++int ++nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gem_pushbuf *req = data; ++ struct drm_nouveau_gem_pushbuf_bo *bo = NULL; ++ struct nouveau_fence *fence = NULL; ++ struct nouveau_channel *chan; ++ struct list_head list; ++ uint32_t *pushbuf = NULL; ++ int ret = 0, do_reloc = 0, i; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan); ++ ++ if (req->nr_dwords >= chan->dma.max || ++ req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS || ++ req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS) { ++ NV_ERROR(dev, "Pushbuf config exceeds limits:\n"); ++ NV_ERROR(dev, " dwords : %d max %d\n", req->nr_dwords, ++ chan->dma.max - 1); ++ NV_ERROR(dev, " buffers: %d max %d\n", req->nr_buffers, ++ NOUVEAU_GEM_MAX_BUFFERS); ++ NV_ERROR(dev, " relocs : %d max %d\n", req->nr_relocs, ++ NOUVEAU_GEM_MAX_RELOCS); ++ return -EINVAL; ++ } ++ ++ pushbuf = u_memcpya(req->dwords, req->nr_dwords, sizeof(uint32_t)); ++ if (IS_ERR(pushbuf)) ++ return PTR_ERR(pushbuf); ++ ++ bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo)); ++ if (IS_ERR(bo)) { ++ kfree(pushbuf); ++ return PTR_ERR(bo); ++ } ++ ++ mutex_lock(&dev->struct_mutex); ++ ++ INIT_LIST_HEAD(&list); ++ ++ /* Validate buffer list */ ++ ret = nouveau_fence_new(chan, &fence, false); ++ if (ret) ++ goto out; ++ ++ ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, ++ req->nr_buffers, &list, &do_reloc); ++ if (ret) ++ goto out; ++ ++ /* Apply any relocations that are required */ ++ if (do_reloc) { ++ ret = nouveau_gem_pushbuf_reloc_apply(chan, req->nr_buffers, ++ bo, req->nr_relocs, ++ req->relocs, ++ req->nr_dwords, 0, ++ pushbuf, false); ++ if (ret) ++ goto out; ++ } ++ ++ /* Emit push buffer to the hw ++ */ ++ ret = RING_SPACE(chan, req->nr_dwords); ++ if (ret) ++ goto out; ++ ++ OUT_RINGp(chan, pushbuf, req->nr_dwords); ++ ++ ret = nouveau_fence_emit(fence); ++ if (ret) { ++ NV_ERROR(dev, "error fencing pushbuf: %d\n", ret); ++ WIND_RING(chan); ++ goto out; ++ } ++ ++ nouveau_gem_pushbuf_fence(&list, fence); ++ ++ if (nouveau_gem_pushbuf_sync(chan)) { ++ ret = nouveau_fence_wait(fence, NULL, false, false); ++ if (ret) { ++ for (i = 0; i < req->nr_dwords; i++) ++ NV_ERROR(dev, "0x%08x\n", pushbuf[i]); ++ NV_ERROR(dev, "^^ above push buffer is fail :(\n"); ++ } ++ } ++out: ++ if (unlikely(ret)) ++ nouveau_gem_pushbuf_backoff(&list); ++ nouveau_fence_unref((void *)&fence); ++ ++ mutex_unlock(&dev->struct_mutex); ++ ++ kfree(pushbuf); ++ kfree(bo); ++ return ret; ++} ++ ++#define PUSHBUF_CAL (dev_priv->card_type >= NV_20) ++ ++int ++nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_nouveau_gem_pushbuf_call *req = data; ++ struct drm_nouveau_gem_pushbuf_bo *bo = NULL; ++ struct nouveau_fence *fence = NULL; ++ struct nouveau_channel *chan; ++ struct drm_gem_object *gem; ++ struct nouveau_bo *pbbo; ++ struct list_head list; ++ int i, ret = 0, do_reloc = 0; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan); ++ ++ if (unlikely(req->handle == 0)) ++ goto out_next; ++ ++ if (req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS || ++ req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS) { ++ NV_ERROR(dev, "Pushbuf config exceeds limits:\n"); ++ NV_ERROR(dev, " buffers: %d max %d\n", req->nr_buffers, ++ NOUVEAU_GEM_MAX_BUFFERS); ++ NV_ERROR(dev, " relocs : %d max %d\n", req->nr_relocs, ++ NOUVEAU_GEM_MAX_RELOCS); ++ return -EINVAL; ++ } ++ ++ bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo)); ++ if (IS_ERR(bo)) ++ return PTR_ERR(bo); ++ ++ mutex_lock(&dev->struct_mutex); ++ ++ INIT_LIST_HEAD(&list); ++ ++ /* Validate buffer list */ ++ ret = nouveau_fence_new(chan, &fence, false); ++ if (ret) { ++ NV_ERROR(dev, "fence new\n"); ++ goto out; ++ } ++ ++ ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, ++ req->nr_buffers, &list, &do_reloc); ++ if (ret) { ++ NV_ERROR(dev, "validate: %d\n", ret); ++ goto out; ++ } ++ ++ /* Validate DMA push buffer */ ++ gem = drm_gem_object_lookup(dev, file_priv, req->handle); ++ if (!gem) { ++ NV_ERROR(dev, "Unknown pb handle 0x%08x\n", req->handle); ++ ret = -EINVAL; ++ goto out; ++ } ++ pbbo = nouveau_gem_object(gem); ++ ++ ret = ttm_bo_reserve(&pbbo->bo, false, false, true, ++ chan->fence.sequence); ++ if (ret) { ++ NV_ERROR(dev, "resv pb: %d\n", ret); ++ drm_gem_object_unreference(gem); ++ goto out; ++ } ++ ++ pbbo->bo.proposed_placement &= ~TTM_PL_MASK_MEM; ++ pbbo->bo.proposed_placement |= (1 << chan->pushbuf_bo->bo.mem.mem_type); ++ ret = ttm_buffer_object_validate(&pbbo->bo, pbbo->bo.proposed_placement, ++ false, false); ++ if (ret) { ++ NV_ERROR(dev, "validate pb: %d\n", ret); ++ ttm_bo_unreserve(&pbbo->bo); ++ drm_gem_object_unreference(gem); ++ goto out; ++ } ++ ++ list_add_tail(&pbbo->entry, &list); ++ ++ /* If presumed return address doesn't match, we need to map the ++ * push buffer and fix it.. ++ */ ++ if (!PUSHBUF_CAL) { ++ uint32_t retaddy; ++ ++ if (chan->dma.free < 4 + NOUVEAU_DMA_SKIPS) { ++ ret = nouveau_dma_wait(chan, 4 + NOUVEAU_DMA_SKIPS); ++ if (ret) { ++ NV_ERROR(dev, "jmp_space: %d\n", ret); ++ goto out; ++ } ++ } ++ ++ retaddy = chan->pushbuf_base + ((chan->dma.cur + 2) << 2); ++ retaddy |= 0x20000000; ++ if (retaddy != req->suffix0) { ++ req->suffix0 = retaddy; ++ do_reloc = 1; ++ } ++ } ++ ++ /* Apply any relocations that are required */ ++ if (do_reloc) { ++ void *pbvirt; ++ bool is_iomem; ++ ret = ttm_bo_kmap(&pbbo->bo, 0, pbbo->bo.mem.num_pages, ++ &pbbo->kmap); ++ if (ret) { ++ NV_ERROR(dev, "kmap pb: %d\n", ret); ++ goto out; ++ } ++ ++ pbvirt = ttm_kmap_obj_virtual(&pbbo->kmap, &is_iomem); ++ ret = nouveau_gem_pushbuf_reloc_apply(chan, req->nr_buffers, bo, ++ req->nr_relocs, ++ req->relocs, ++ req->nr_dwords, ++ req->offset / 4, ++ pbvirt, is_iomem); ++ ++ if (!PUSHBUF_CAL) { ++ nouveau_bo_wr32(pbbo, ++ req->offset / 4 + req->nr_dwords - 2, ++ req->suffix0); ++ } ++ ++ ttm_bo_kunmap(&pbbo->kmap); ++ if (ret) { ++ NV_ERROR(dev, "reloc apply: %d\n", ret); ++ goto out; ++ } ++ } ++ ++ if (PUSHBUF_CAL) { ++ ret = RING_SPACE(chan, 2); ++ if (ret) { ++ NV_ERROR(dev, "cal_space: %d\n", ret); ++ goto out; ++ } ++ OUT_RING(chan, ((pbbo->bo.mem.mm_node->start << PAGE_SHIFT) + ++ req->offset) | 2); ++ OUT_RING(chan, 0); ++ } else { ++ ret = RING_SPACE(chan, 2 + NOUVEAU_DMA_SKIPS); ++ if (ret) { ++ NV_ERROR(dev, "jmp_space: %d\n", ret); ++ goto out; ++ } ++ OUT_RING(chan, ((pbbo->bo.mem.mm_node->start << PAGE_SHIFT) + ++ req->offset) | 0x20000000); ++ OUT_RING(chan, 0); ++ ++ /* Space the jumps apart with NOPs. */ ++ for (i = 0; i < NOUVEAU_DMA_SKIPS; i++) ++ OUT_RING(chan, 0); ++ } ++ ++ ret = nouveau_fence_emit(fence); ++ if (ret) { ++ NV_ERROR(dev, "error fencing pushbuf: %d\n", ret); ++ WIND_RING(chan); ++ goto out; ++ } ++ ++ nouveau_gem_pushbuf_fence(&list, fence); ++ ++ FIRE_RING(chan); ++out: ++ if (unlikely(ret)) ++ nouveau_gem_pushbuf_backoff(&list); ++ nouveau_fence_unref((void *)&fence); ++ ++ mutex_unlock(&dev->struct_mutex); ++ ++ kfree(bo); ++ ++out_next: ++ if (PUSHBUF_CAL) { ++ req->suffix0 = 0x00020000; ++ req->suffix1 = 0x00000000; ++ } else { ++ req->suffix0 = 0x20000000 | ++ (chan->pushbuf_base + ((chan->dma.cur + 2) << 2)); ++ req->suffix1 = 0x00000000; ++ } ++ ++ return ret; ++} ++ ++int ++nouveau_gem_ioctl_pushbuf_call2(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_nouveau_gem_pushbuf_call *req = data; ++ ++ req->vram_available = dev_priv->fb_aper_free; ++ req->gart_available = dev_priv->gart_info.aper_free; ++ ++ return nouveau_gem_ioctl_pushbuf_call(dev, data, file_priv); ++} ++ ++static inline uint32_t ++domain_to_ttm(struct nouveau_bo *nvbo, uint32_t domain) ++{ ++ uint32_t flags = 0; ++ ++ if (domain & NOUVEAU_GEM_DOMAIN_VRAM) { ++ flags |= TTM_PL_FLAG_VRAM; ++ if (!nvbo->mappable) ++ flags |= TTM_PL_FLAG_PRIV0; ++ } ++ ++ if (domain & NOUVEAU_GEM_DOMAIN_GART) ++ flags |= TTM_PL_FLAG_TT; ++ ++ return flags; ++} ++ ++int ++nouveau_gem_ioctl_pin(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gem_pin *req = data; ++ struct drm_gem_object *gem; ++ struct nouveau_bo *nvbo; ++ int ret = 0; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ NV_ERROR(dev, "pin only allowed without kernel modesetting\n"); ++ return -EINVAL; ++ } ++ ++ if (!DRM_SUSER(DRM_CURPROC)) ++ return -EPERM; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, req->handle); ++ if (!gem) ++ return -EINVAL; ++ nvbo = nouveau_gem_object(gem); ++ ++ ret = nouveau_bo_pin(nvbo, domain_to_ttm(nvbo, req->domain)); ++ if (ret) ++ goto out; ++ ++ req->offset = nvbo->bo.offset; ++ if (nvbo->bo.mem.mem_type == TTM_PL_TT) ++ req->domain = NOUVEAU_GEM_DOMAIN_GART; ++ else ++ req->domain = NOUVEAU_GEM_DOMAIN_VRAM; ++ ++out: ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ ++ return ret; ++} ++ ++int ++nouveau_gem_ioctl_unpin(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gem_pin *req = data; ++ struct drm_gem_object *gem; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return -EINVAL; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, req->handle); ++ if (!gem) ++ return -EINVAL; ++ ++ ret = nouveau_bo_unpin(nouveau_gem_object(gem)); ++ ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ ++ return ret; ++} ++ ++int ++nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gem_cpu_prep *req = data; ++ struct drm_gem_object *gem; ++ struct nouveau_bo *nvbo; ++ bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT); ++ int ret = -EINVAL; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, req->handle); ++ if (!gem) ++ return ret; ++ nvbo = nouveau_gem_object(gem); ++ ++ if (nvbo->cpu_filp) { ++ if (nvbo->cpu_filp == file_priv) ++ goto out; ++ ++ ret = ttm_bo_wait_cpu(&nvbo->bo, no_wait); ++ if (ret == -ERESTART) ++ ret = -EAGAIN; ++ if (ret) ++ goto out; ++ } ++ ++ if (req->flags & NOUVEAU_GEM_CPU_PREP_NOBLOCK) { ++ ret = ttm_bo_wait(&nvbo->bo, false, false, no_wait); ++ } else { ++ ret = ttm_bo_synccpu_write_grab(&nvbo->bo, no_wait); ++ if (ret == -ERESTART) ++ ret = -EAGAIN; ++ else ++ if (ret == 0) ++ nvbo->cpu_filp = file_priv; ++ } ++ ++out: ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ return ret; ++} ++ ++int ++nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gem_cpu_prep *req = data; ++ struct drm_gem_object *gem; ++ struct nouveau_bo *nvbo; ++ int ret = -EINVAL; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, req->handle); ++ if (!gem) ++ return ret; ++ nvbo = nouveau_gem_object(gem); ++ ++ if (nvbo->cpu_filp != file_priv) ++ goto out; ++ nvbo->cpu_filp = NULL; ++ ++ ttm_bo_synccpu_write_release(&nvbo->bo); ++ ret = 0; ++ ++out: ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ return ret; ++} ++ ++int ++nouveau_gem_ioctl_info(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gem_info *req = data; ++ struct drm_gem_object *gem; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ gem = drm_gem_object_lookup(dev, file_priv, req->handle); ++ if (!gem) ++ return -EINVAL; ++ ++ ret = nouveau_gem_info(gem, req); ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ return ret; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c +new file mode 100644 +index 0000000..e78ee53 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_hw.c +@@ -0,0 +1,1078 @@ ++/* ++ * 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 "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_hw.h" ++ ++#define CHIPSET_NFORCE 0x01a0 ++#define CHIPSET_NFORCE2 0x01f0 ++ ++/* ++ * misc hw access wrappers/control functions ++ */ ++ ++void ++NVWriteVgaSeq(struct drm_device *dev, int head, uint8_t index, uint8_t value) ++{ ++ NVWritePRMVIO(dev, head, NV_PRMVIO_SRX, index); ++ NVWritePRMVIO(dev, head, NV_PRMVIO_SR, value); ++} ++ ++uint8_t ++NVReadVgaSeq(struct drm_device *dev, int head, uint8_t index) ++{ ++ NVWritePRMVIO(dev, head, NV_PRMVIO_SRX, index); ++ return NVReadPRMVIO(dev, head, NV_PRMVIO_SR); ++} ++ ++void ++NVWriteVgaGr(struct drm_device *dev, int head, uint8_t index, uint8_t value) ++{ ++ NVWritePRMVIO(dev, head, NV_PRMVIO_GRX, index); ++ NVWritePRMVIO(dev, head, NV_PRMVIO_GX, value); ++} ++ ++uint8_t ++NVReadVgaGr(struct drm_device *dev, int head, uint8_t index) ++{ ++ NVWritePRMVIO(dev, head, NV_PRMVIO_GRX, index); ++ return NVReadPRMVIO(dev, 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(struct drm_device *dev, int owner) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (owner == 1) ++ owner *= 3; ++ ++ if (dev_priv->chipset == 0x11) { ++ /* This might seem stupid, but the blob does it and ++ * omitting it often locks the system up. ++ */ ++ NVReadVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX); ++ NVReadVgaCrtc(dev, 1, NV_CIO_SR_LOCK_INDEX); ++ } ++ ++ /* CR44 is always changed on CRTC0 */ ++ NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_44, owner); ++ ++ if (dev_priv->chipset == 0x11) { /* set me harder */ ++ NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_2E, owner); ++ NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_2E, owner); ++ } ++} ++ ++void ++NVBlankScreen(struct drm_device *dev, int head, bool blank) ++{ ++ unsigned char seq1; ++ ++ if (nv_two_heads(dev)) ++ NVSetOwner(dev, head); ++ ++ seq1 = NVReadVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX); ++ ++ NVVgaSeqReset(dev, head, true); ++ if (blank) ++ NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20); ++ else ++ NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20); ++ NVVgaSeqReset(dev, 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(struct drm_device *dev, uint32_t reg, struct nouveau_pll_vals *pv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int chip_version = dev_priv->vbios->chip_version; ++ uint32_t oldpll = NVReadRAMDAC(dev, 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(dev, NV_PBUS_POWERCTRL_1); ++ nvWriteMC(dev, 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(dev, 0, reg, pv->log2P << 16 | (oldpll & 0xffff)); ++ else ++ /* downclock -- write new NM first */ ++ NVWriteRAMDAC(dev, 0, reg, (oldpll & 0xffff0000) | pv->NM1); ++ ++ if (chip_version < 0x17 && chip_version != 0x11) ++ /* wait a bit on older chips */ ++ msleep(64); ++ NVReadRAMDAC(dev, 0, reg); ++ ++ /* then write the other half as well */ ++ NVWriteRAMDAC(dev, 0, reg, pll); ++ ++ if (shift_powerctrl_1 >= 0) ++ nvWriteMC(dev, 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(struct drm_device *dev, uint32_t reg1, ++ struct nouveau_pll_vals *pv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int chip_version = dev_priv->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(dev, 0, reg1); ++ uint32_t oldpll2 = !nv3035 ? NVReadRAMDAC(dev, 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(dev, 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(dev, NV_PBUS_POWERCTRL_1); ++ nvWriteMC(dev, 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(dev, 0xc040); ++ if (shift_c040 != 14) ++ nvWriteMC(dev, 0xc040, savedc040 & ~(3 << shift_c040)); ++ } ++ ++ if (oldramdac580 != ramdac580) ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_580, ramdac580); ++ ++ if (!nv3035) ++ NVWriteRAMDAC(dev, 0, reg2, pll2); ++ NVWriteRAMDAC(dev, 0, reg1, pll1); ++ ++ if (shift_powerctrl_1 >= 0) ++ nvWriteMC(dev, NV_PBUS_POWERCTRL_1, saved_powerctrl_1); ++ if (chip_version >= 0x40) ++ nvWriteMC(dev, 0xc040, savedc040); ++} ++ ++static void ++setPLL_double_lowregs(struct drm_device *dev, 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 :) ++ */ ++ ++ uint32_t Preg = NMNMreg - 4; ++ bool mpll = Preg == 0x4020; ++ uint32_t oldPval = nvReadMC(dev, 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(dev, 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(dev, 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(dev, 0x4600); ++ nvWriteMC(dev, 0x4600, saved4600 | 8 << 28); ++ } ++ if (single_stage) ++ Pval |= mpll ? 1 << 12 : 1 << 8; ++ ++ nvWriteMC(dev, Preg, oldPval | 1 << 28); ++ nvWriteMC(dev, Preg, Pval & ~(4 << 28)); ++ if (mpll) { ++ Pval |= 8 << 20; ++ nvWriteMC(dev, 0x4020, Pval & ~(0xc << 28)); ++ nvWriteMC(dev, 0x4038, Pval & ~(0xc << 28)); ++ } ++ ++ savedc040 = nvReadMC(dev, 0xc040); ++ nvWriteMC(dev, 0xc040, savedc040 & maskc040); ++ ++ nvWriteMC(dev, NMNMreg, NMNM); ++ if (NMNMreg == 0x4024) ++ nvWriteMC(dev, 0x403c, NMNM); ++ ++ nvWriteMC(dev, Preg, Pval); ++ if (mpll) { ++ Pval &= ~(8 << 20); ++ nvWriteMC(dev, 0x4020, Pval); ++ nvWriteMC(dev, 0x4038, Pval); ++ nvWriteMC(dev, 0x4600, saved4600); ++ } ++ ++ nvWriteMC(dev, 0xc040, savedc040); ++ ++ if (mpll) { ++ nvWriteMC(dev, 0x4020, Pval & ~(1 << 28)); ++ nvWriteMC(dev, 0x4038, Pval & ~(1 << 28)); ++ } ++} ++ ++void ++nouveau_hw_setpll(struct drm_device *dev, uint32_t reg1, ++ struct nouveau_pll_vals *pv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int cv = dev_priv->vbios->chip_version; ++ ++ if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 || ++ cv >= 0x40) { ++ if (reg1 > 0x405c) ++ setPLL_double_highregs(dev, reg1, pv); ++ else ++ setPLL_double_lowregs(dev, reg1, pv); ++ } else ++ setPLL_single(dev, reg1, pv); ++} ++ ++/* ++ * PLL getting ++ */ ++ ++static void ++nouveau_hw_decode_pll(struct drm_device *dev, uint32_t reg1, uint32_t pll1, ++ uint32_t pll2, struct nouveau_pll_vals *pllvals) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ /* 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 (nv_two_reg_pll(dev) && pll2 & NV31_RAMDAC_ENABLE_VCO2) ++ pllvals->NM2 = pll2 & 0xffff; ++ else if (dev_priv->chipset == 0x30 || dev_priv->chipset == 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(struct drm_device *dev, enum pll_types plltype, ++ struct nouveau_pll_vals *pllvals) ++{ ++ 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 (nv_arch(dev) < NV_40) ++ reg1 = nv04_regs[plltype]; ++ else ++ reg1 = nv40_regs[plltype]; ++ ++ pll1 = nvReadMC(dev, reg1); ++ ++ if (reg1 <= 0x405c) ++ pll2 = nvReadMC(dev, reg1 + 4); ++ else if (nv_two_reg_pll(dev)) { ++ uint32_t reg2 = reg1 + (reg1 == NV_RAMDAC_VPLL2 ? 0x5c : 0x70); ++ ++ pll2 = nvReadMC(dev, reg2); ++ } ++ ++ if (nv_arch(dev) == 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) { ++ uint32_t ramdac580 = NVReadRAMDAC(dev, 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(dev, reg1, pll1, pll2, pllvals); ++ ++ ret = get_pll_limits(dev, plltype, &pll_lim); ++ if (ret) ++ 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(struct drm_device *dev, enum pll_types plltype) ++{ ++ struct nouveau_pll_vals pllvals; ++ ++ if (plltype == MPLL && (dev->pci_device & 0x0ff0) == CHIPSET_NFORCE) { ++ uint32_t mpllP; ++ ++ pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP); ++ if (!mpllP) ++ mpllP = 4; ++ ++ return 400000 / mpllP; ++ } else ++ if (plltype == MPLL && (dev->pci_device & 0xff0) == CHIPSET_NFORCE2) { ++ uint32_t clock; ++ ++ pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock); ++ return clock; ++ } ++ ++ nouveau_hw_get_pllvals(dev, plltype, &pllvals); ++ ++ return nouveau_hw_pllvals_to_clk(&pllvals); ++} ++ ++static void ++nouveau_hw_fix_bad_vpll(struct drm_device *dev, 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(dev, head ? VPLL2 : VPLL1, &pll_lim)) ++ return; ++ nouveau_hw_get_pllvals(dev, 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(dev, "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(dev, pllreg, &pv); ++} ++ ++/* ++ * vga font save/restore ++ */ ++ ++static void nouveau_vga_font_io(struct drm_device *dev, ++ void __iomem *iovram, ++ bool save, unsigned plane) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ unsigned i; ++ ++ NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 1 << plane); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, plane); ++ for (i = 0; i < 16384; i++) { ++ if (save) { ++ dev_priv->saved_vga_font[plane][i] = ++ ioread32_native(iovram + i * 4); ++ } else { ++ iowrite32_native(dev_priv->saved_vga_font[plane][i], ++ iovram + i * 4); ++ } ++ } ++} ++ ++void ++nouveau_hw_save_vga_fonts(struct drm_device *dev, bool save) ++{ ++ uint8_t misc, gr4, gr5, gr6, seq2, seq4; ++ bool graphicsmode; ++ unsigned plane; ++ void __iomem *iovram; ++ ++ if (nv_two_heads(dev)) ++ NVSetOwner(dev, 0); ++ ++ NVSetEnablePalette(dev, 0, true); ++ graphicsmode = NVReadVgaAttr(dev, 0, NV_CIO_AR_MODE_INDEX) & 1; ++ NVSetEnablePalette(dev, 0, false); ++ ++ if (graphicsmode) /* graphics mode => framebuffer => no need to save */ ++ return; ++ ++ NV_INFO(dev, "%sing VGA fonts\n", save ? "Sav" : "Restor"); ++ ++ /* map first 64KiB of VRAM, holds VGA fonts etc */ ++ iovram = ioremap(pci_resource_start(dev->pdev, 1), 65536); ++ if (!iovram) { ++ NV_ERROR(dev, "Failed to map VRAM, " ++ "cannot save/restore VGA fonts.\n"); ++ return; ++ } ++ ++ if (nv_two_heads(dev)) ++ NVBlankScreen(dev, 1, true); ++ NVBlankScreen(dev, 0, true); ++ ++ /* save control regs */ ++ misc = NVReadPRMVIO(dev, 0, NV_PRMVIO_MISC__READ); ++ seq2 = NVReadVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX); ++ seq4 = NVReadVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX); ++ gr4 = NVReadVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX); ++ gr5 = NVReadVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX); ++ gr6 = NVReadVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX); ++ ++ NVWritePRMVIO(dev, 0, NV_PRMVIO_MISC__WRITE, 0x67); ++ NVWriteVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX, 0x6); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX, 0x0); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX, 0x5); ++ ++ /* store font in planes 0..3 */ ++ for (plane = 0; plane < 4; plane++) ++ nouveau_vga_font_io(dev, iovram, save, plane); ++ ++ /* restore control regs */ ++ NVWritePRMVIO(dev, 0, NV_PRMVIO_MISC__WRITE, misc); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, gr4); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX, gr5); ++ NVWriteVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX, gr6); ++ NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, seq2); ++ NVWriteVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX, seq4); ++ ++ if (nv_two_heads(dev)) ++ NVBlankScreen(dev, 1, false); ++ NVBlankScreen(dev, 0, false); ++ ++ iounmap(iovram); ++} ++ ++/* ++ * mode state save/load ++ */ ++ ++static void ++rd_cio_state(struct drm_device *dev, int head, ++ struct nv04_crtc_reg *crtcstate, int index) ++{ ++ crtcstate->CRTC[index] = NVReadVgaCrtc(dev, head, index); ++} ++ ++static void ++wr_cio_state(struct drm_device *dev, int head, ++ struct nv04_crtc_reg *crtcstate, int index) ++{ ++ NVWriteVgaCrtc(dev, head, index, crtcstate->CRTC[index]); ++} ++ ++static void ++nv_save_state_ramdac(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv04_crtc_reg *regp = &state->crtc_reg[head]; ++ int i; ++ ++ if (nv_arch(dev) >= NV_10) ++ regp->nv10_cursync = NVReadRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC); ++ ++ nouveau_hw_get_pllvals(dev, head ? VPLL2 : VPLL1, ®p->pllvals); ++ state->pllsel = NVReadRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT); ++ if (nv_two_heads(dev)) ++ state->sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK); ++ if (dev_priv->chipset == 0x11) ++ regp->dither = NVReadRAMDAC(dev, head, NV_RAMDAC_DITHER_NV11); ++ ++ regp->ramdac_gen_ctrl = NVReadRAMDAC(dev, head, NV_PRAMDAC_GENERAL_CONTROL); ++ ++ if (nv_gf4_disp_arch(dev)) ++ regp->ramdac_630 = NVReadRAMDAC(dev, head, NV_PRAMDAC_630); ++ if (dev_priv->chipset >= 0x30) ++ regp->ramdac_634 = NVReadRAMDAC(dev, head, NV_PRAMDAC_634); ++ ++ regp->tv_setup = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP); ++ regp->tv_vtotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_VTOTAL); ++ regp->tv_vskew = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_VSKEW); ++ regp->tv_vsync_delay = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_VSYNC_DELAY); ++ regp->tv_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HTOTAL); ++ regp->tv_hskew = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HSKEW); ++ regp->tv_hsync_delay = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY); ++ regp->tv_hsync_delay2 = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY2); ++ ++ for (i = 0; i < 7; i++) { ++ uint32_t ramdac_reg = NV_PRAMDAC_FP_VDISPLAY_END + (i * 4); ++ regp->fp_vert_regs[i] = NVReadRAMDAC(dev, head, ramdac_reg); ++ regp->fp_horiz_regs[i] = NVReadRAMDAC(dev, head, ramdac_reg + 0x20); ++ } ++ ++ if (nv_gf4_disp_arch(dev)) { ++ regp->dither = NVReadRAMDAC(dev, head, NV_RAMDAC_FP_DITHER); ++ for (i = 0; i < 3; i++) { ++ regp->dither_regs[i] = NVReadRAMDAC(dev, head, NV_PRAMDAC_850 + i * 4); ++ regp->dither_regs[i + 3] = NVReadRAMDAC(dev, head, NV_PRAMDAC_85C + i * 4); ++ } ++ } ++ ++ regp->fp_control = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL); ++ regp->fp_debug_0 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_0); ++ if (!nv_gf4_disp_arch(dev) && head == 0) { ++ /* early chips don't allow access to PRAMDAC_TMDS_* without ++ * the head A FPCLK on (nv11 even locks up) */ ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_FP_DEBUG_0, regp->fp_debug_0 & ++ ~NV_PRAMDAC_FP_DEBUG_0_PWRDOWN_FPCLK); ++ } ++ regp->fp_debug_1 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1); ++ regp->fp_debug_2 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_2); ++ ++ regp->fp_margin_color = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_MARGIN_COLOR); ++ ++ if (nv_arch(dev) >= NV_30) ++ regp->ramdac_8c0 = NVReadRAMDAC(dev, head, NV_PRAMDAC_8C0); ++ ++ if (nv_arch(dev) == NV_40) { ++ regp->ramdac_a20 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A20); ++ regp->ramdac_a24 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A24); ++ regp->ramdac_a34 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A34); ++ ++ for (i = 0; i < 38; i++) ++ regp->ctv_regs[i] = NVReadRAMDAC(dev, head, ++ NV_PRAMDAC_CTV + 4*i); ++ } ++} ++ ++static void ++nv_load_state_ramdac(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv04_crtc_reg *regp = &state->crtc_reg[head]; ++ uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF; ++ int i; ++ ++ if (nv_arch(dev) >= NV_10) ++ NVWriteRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync); ++ ++ nouveau_hw_setpll(dev, pllreg, ®p->pllvals); ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel); ++ if (nv_two_heads(dev)) ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, state->sel_clk); ++ if (dev_priv->chipset == 0x11) ++ NVWriteRAMDAC(dev, head, NV_RAMDAC_DITHER_NV11, regp->dither); ++ ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_GENERAL_CONTROL, regp->ramdac_gen_ctrl); ++ ++ if (nv_gf4_disp_arch(dev)) ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_630, regp->ramdac_630); ++ if (dev_priv->chipset >= 0x30) ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_634, regp->ramdac_634); ++ ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP, regp->tv_setup); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_VTOTAL, regp->tv_vtotal); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_VSKEW, regp->tv_vskew); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_VSYNC_DELAY, regp->tv_vsync_delay); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HTOTAL, regp->tv_htotal); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HSKEW, regp->tv_hskew); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY, regp->tv_hsync_delay); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY2, regp->tv_hsync_delay2); ++ ++ for (i = 0; i < 7; i++) { ++ uint32_t ramdac_reg = NV_PRAMDAC_FP_VDISPLAY_END + (i * 4); ++ ++ NVWriteRAMDAC(dev, head, ramdac_reg, regp->fp_vert_regs[i]); ++ NVWriteRAMDAC(dev, head, ramdac_reg + 0x20, regp->fp_horiz_regs[i]); ++ } ++ ++ if (nv_gf4_disp_arch(dev)) { ++ NVWriteRAMDAC(dev, head, NV_RAMDAC_FP_DITHER, regp->dither); ++ for (i = 0; i < 3; i++) { ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_850 + i * 4, regp->dither_regs[i]); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_85C + i * 4, regp->dither_regs[i + 3]); ++ } ++ } ++ ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, regp->fp_control); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_0, regp->fp_debug_0); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1, regp->fp_debug_1); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_2, regp->fp_debug_2); ++ ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_MARGIN_COLOR, regp->fp_margin_color); ++ ++ if (nv_arch(dev) >= NV_30) ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_8C0, regp->ramdac_8c0); ++ ++ if (nv_arch(dev) == NV_40) { ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_A20, regp->ramdac_a20); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_A24, regp->ramdac_a24); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_A34, regp->ramdac_a34); ++ ++ for (i = 0; i < 38; i++) ++ NVWriteRAMDAC(dev, head, ++ NV_PRAMDAC_CTV + 4*i, regp->ctv_regs[i]); ++ } ++} ++ ++static void ++nv_save_state_vga(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct nv04_crtc_reg *regp = &state->crtc_reg[head]; ++ int i; ++ ++ regp->MiscOutReg = NVReadPRMVIO(dev, head, NV_PRMVIO_MISC__READ); ++ ++ for (i = 0; i < 25; i++) ++ rd_cio_state(dev, head, regp, i); ++ ++ NVSetEnablePalette(dev, head, true); ++ for (i = 0; i < 21; i++) ++ regp->Attribute[i] = NVReadVgaAttr(dev, head, i); ++ NVSetEnablePalette(dev, head, false); ++ ++ for (i = 0; i < 9; i++) ++ regp->Graphics[i] = NVReadVgaGr(dev, head, i); ++ ++ for (i = 0; i < 5; i++) ++ regp->Sequencer[i] = NVReadVgaSeq(dev, head, i); ++} ++ ++static void ++nv_load_state_vga(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct nv04_crtc_reg *regp = &state->crtc_reg[head]; ++ int i; ++ ++ NVWritePRMVIO(dev, head, NV_PRMVIO_MISC__WRITE, regp->MiscOutReg); ++ ++ for (i = 0; i < 5; i++) ++ NVWriteVgaSeq(dev, head, i, regp->Sequencer[i]); ++ ++ nv_lock_vga_crtc_base(dev, head, false); ++ for (i = 0; i < 25; i++) ++ wr_cio_state(dev, head, regp, i); ++ nv_lock_vga_crtc_base(dev, head, true); ++ ++ for (i = 0; i < 9; i++) ++ NVWriteVgaGr(dev, head, i, regp->Graphics[i]); ++ ++ NVSetEnablePalette(dev, head, true); ++ for (i = 0; i < 21; i++) ++ NVWriteVgaAttr(dev, head, i, regp->Attribute[i]); ++ NVSetEnablePalette(dev, head, false); ++} ++ ++static void ++nv_save_state_ext(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct nv04_crtc_reg *regp = &state->crtc_reg[head]; ++ int i; ++ ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_LCD__INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_RPC0_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_RPC1_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_LSR_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_PIXEL_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_HEB__INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX); ++ ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_21); ++ if (nv_arch(dev) >= NV_30) ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_47); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_49); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_ILACE__INDEX); ++ ++ if (nv_arch(dev) >= NV_10) { ++ regp->crtc_830 = NVReadCRTC(dev, head, NV_PCRTC_830); ++ regp->crtc_834 = NVReadCRTC(dev, head, NV_PCRTC_834); ++ ++ if (nv_arch(dev) >= NV_30) ++ regp->gpio_ext = NVReadCRTC(dev, head, NV_PCRTC_GPIO_EXT); ++ ++ if (nv_arch(dev) == NV_40) ++ regp->crtc_850 = NVReadCRTC(dev, head, NV_PCRTC_850); ++ ++ if (nv_two_heads(dev)) ++ regp->crtc_eng_ctrl = NVReadCRTC(dev, head, NV_PCRTC_ENGINE_CTRL); ++ regp->cursor_cfg = NVReadCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG); ++ } ++ ++ regp->crtc_cfg = NVReadCRTC(dev, head, NV_PCRTC_CONFIG); ++ ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH3__INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH4__INDEX); ++ if (nv_arch(dev) >= NV_10) { ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_EBR_INDEX); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_CSB); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_4B); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_TVOUT_LATENCY); ++ } ++ /* NV11 and NV20 don't have this, they stop at 0x52. */ ++ if (nv_gf4_disp_arch(dev)) { ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_53); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_54); ++ ++ for (i = 0; i < 0x10; i++) ++ regp->CR58[i] = NVReadVgaCrtc5758(dev, head, i); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_59); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_5B); ++ ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_85); ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_86); ++ } ++ ++ regp->fb_start = NVReadCRTC(dev, head, NV_PCRTC_START); ++} ++ ++static void ++nv_load_state_ext(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv04_crtc_reg *regp = &state->crtc_reg[head]; ++ uint32_t reg900; ++ int i; ++ ++ if (nv_arch(dev) >= NV_10) { ++ if (nv_two_heads(dev)) ++ /* 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(dev, head, NV_PCRTC_ENGINE_CTRL, regp->crtc_eng_ctrl); ++ ++ nvWriteVIDEO(dev, NV_PVIDEO_STOP, 1); ++ nvWriteVIDEO(dev, NV_PVIDEO_INTR_EN, 0); ++ nvWriteVIDEO(dev, NV_PVIDEO_OFFSET_BUFF(0), 0); ++ nvWriteVIDEO(dev, NV_PVIDEO_OFFSET_BUFF(1), 0); ++ nvWriteVIDEO(dev, NV_PVIDEO_LIMIT(0), dev_priv->fb_available_size - 1); ++ nvWriteVIDEO(dev, NV_PVIDEO_LIMIT(1), dev_priv->fb_available_size - 1); ++ nvWriteVIDEO(dev, NV_PVIDEO_UVPLANE_LIMIT(0), dev_priv->fb_available_size - 1); ++ nvWriteVIDEO(dev, NV_PVIDEO_UVPLANE_LIMIT(1), dev_priv->fb_available_size - 1); ++ nvWriteMC(dev, NV_PBUS_POWERCTRL_2, 0); ++ ++ NVWriteCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG, regp->cursor_cfg); ++ NVWriteCRTC(dev, head, NV_PCRTC_830, regp->crtc_830); ++ NVWriteCRTC(dev, head, NV_PCRTC_834, regp->crtc_834); ++ ++ if (nv_arch(dev) >= NV_30) ++ NVWriteCRTC(dev, head, NV_PCRTC_GPIO_EXT, regp->gpio_ext); ++ ++ if (nv_arch(dev) == NV_40) { ++ NVWriteCRTC(dev, head, NV_PCRTC_850, regp->crtc_850); ++ ++ reg900 = NVReadRAMDAC(dev, head, NV_PRAMDAC_900); ++ if (regp->crtc_cfg == NV_PCRTC_CONFIG_START_ADDRESS_HSYNC) ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_900, reg900 | 0x10000); ++ else ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_900, reg900 & ~0x10000); ++ } ++ } ++ ++ NVWriteCRTC(dev, head, NV_PCRTC_CONFIG, regp->crtc_cfg); ++ ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_RPC0_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_RPC1_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_LSR_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_PIXEL_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_LCD__INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_HEB__INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); ++ if (nv_arch(dev) >= NV_30) ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_47); ++ ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_49); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX); ++ if (nv_arch(dev) == NV_40) ++ nv_fix_nv40_hw_cursor(dev, head); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_ILACE__INDEX); ++ ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH3__INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH4__INDEX); ++ if (nv_arch(dev) >= NV_10) { ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_EBR_INDEX); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_CSB); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_4B); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_TVOUT_LATENCY); ++ } ++ /* NV11 and NV20 stop at 0x52. */ ++ if (nv_gf4_disp_arch(dev)) { ++ if (nv_arch(dev) == NV_10) { ++ /* Not waiting for vertical retrace before modifying ++ CRE_53/CRE_54 causes lockups. */ ++ nouveau_wait_until(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8); ++ nouveau_wait_until(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0); ++ } ++ ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_53); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_54); ++ ++ for (i = 0; i < 0x10; i++) ++ NVWriteVgaCrtc5758(dev, head, i, regp->CR58[i]); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_59); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_5B); ++ ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_85); ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_86); ++ } ++ ++ NVWriteCRTC(dev, head, NV_PCRTC_START, regp->fb_start); ++ ++ /* Setting 1 on this value gives you interrupts for every vblank period. */ ++ NVWriteCRTC(dev, head, NV_PCRTC_INTR_EN_0, 0); ++ NVWriteCRTC(dev, head, NV_PCRTC_INTR_0, NV_PCRTC_INTR_0_VBLANK); ++} ++ ++static void ++nv_save_state_palette(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ int head_offset = head * NV_PRMDIO_SIZE, i; ++ ++ nv_wr08(dev, NV_PRMDIO_PIXEL_MASK + head_offset, ++ NV_PRMDIO_PIXEL_MASK_MASK); ++ nv_wr08(dev, NV_PRMDIO_READ_MODE_ADDRESS + head_offset, 0x0); ++ ++ for (i = 0; i < 768; i++) { ++ state->crtc_reg[head].DAC[i] = nv_rd08(dev, ++ NV_PRMDIO_PALETTE_DATA + head_offset); ++ } ++ ++ NVSetEnablePalette(dev, head, false); ++} ++ ++void ++nouveau_hw_load_state_palette(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ int head_offset = head * NV_PRMDIO_SIZE, i; ++ ++ nv_wr08(dev, NV_PRMDIO_PIXEL_MASK + head_offset, ++ NV_PRMDIO_PIXEL_MASK_MASK); ++ nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS + head_offset, 0x0); ++ ++ for (i = 0; i < 768; i++) { ++ nv_wr08(dev, NV_PRMDIO_PALETTE_DATA + head_offset, ++ state->crtc_reg[head].DAC[i]); ++ } ++ ++ NVSetEnablePalette(dev, head, false); ++} ++ ++void nouveau_hw_save_state(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->chipset == 0x11) ++ /* NB: no attempt is made to restore the bad pll later on */ ++ nouveau_hw_fix_bad_vpll(dev, head); ++ nv_save_state_ramdac(dev, head, state); ++ nv_save_state_vga(dev, head, state); ++ nv_save_state_palette(dev, head, state); ++ nv_save_state_ext(dev, head, state); ++} ++ ++void nouveau_hw_load_state(struct drm_device *dev, int head, ++ struct nv04_mode_state *state) ++{ ++ NVVgaProtect(dev, head, true); ++ nv_load_state_ramdac(dev, head, state); ++ nv_load_state_ext(dev, head, state); ++ nouveau_hw_load_state_palette(dev, head, state); ++ nv_load_state_vga(dev, head, state); ++ NVVgaProtect(dev, head, false); ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.h b/drivers/gpu/drm/nouveau/nouveau_hw.h +new file mode 100644 +index 0000000..ff4993a +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_hw.h +@@ -0,0 +1,448 @@ ++/* ++ * 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__ ++ ++#include "drmP.h" ++#include "nouveau_drv.h" ++ ++#define MASK(field) ( \ ++ (0xffffffff >> (31 - ((1 ? field) - (0 ? field)))) << (0 ? field)) ++ ++#define XLATE(src, srclowbit, outfield) ( \ ++ (((src) >> (srclowbit)) << (0 ? outfield)) & MASK(outfield)) ++ ++void NVWriteVgaSeq(struct drm_device *, int head, uint8_t index, uint8_t value); ++uint8_t NVReadVgaSeq(struct drm_device *, int head, uint8_t index); ++void NVWriteVgaGr(struct drm_device *, int head, uint8_t index, uint8_t value); ++uint8_t NVReadVgaGr(struct drm_device *, int head, uint8_t index); ++void NVSetOwner(struct drm_device *, int owner); ++void NVBlankScreen(struct drm_device *, int head, bool blank); ++void nouveau_hw_setpll(struct drm_device *, uint32_t reg1, ++ struct nouveau_pll_vals *pv); ++int nouveau_hw_get_pllvals(struct drm_device *, 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(struct drm_device *, enum pll_types plltype); ++void nouveau_hw_save_vga_fonts(struct drm_device *, bool save); ++void nouveau_hw_save_state(struct drm_device *, int head, ++ struct nv04_mode_state *state); ++void nouveau_hw_load_state(struct drm_device *, int head, ++ struct nv04_mode_state *state); ++void nouveau_hw_load_state_palette(struct drm_device *, int head, ++ struct nv04_mode_state *state); ++ ++/* nouveau_calc.c */ ++extern void nouveau_calc_arb(struct drm_device *, int vclk, int bpp, ++ int *burst, int *lwm); ++extern int nouveau_calc_pll_mnp(struct drm_device *, struct pll_lims *pll_lim, ++ int clk, struct nouveau_pll_vals *pv); ++ ++static inline uint32_t ++nvReadMC(struct drm_device *dev, uint32_t reg) ++{ ++ uint32_t val = nv_rd32(dev, reg); ++ NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val); ++ return val; ++} ++ ++static inline void ++nvWriteMC(struct drm_device *dev, uint32_t reg, uint32_t val) ++{ ++ NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val); ++ nv_wr32(dev, reg, val); ++} ++ ++static inline uint32_t ++nvReadVIDEO(struct drm_device *dev, uint32_t reg) ++{ ++ uint32_t val = nv_rd32(dev, reg); ++ NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val); ++ return val; ++} ++ ++static inline void ++nvWriteVIDEO(struct drm_device *dev, uint32_t reg, uint32_t val) ++{ ++ NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val); ++ nv_wr32(dev, reg, val); ++} ++ ++static inline uint32_t ++nvReadFB(struct drm_device *dev, uint32_t reg) ++{ ++ uint32_t val = nv_rd32(dev, reg); ++ NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val); ++ return val; ++} ++ ++static inline void ++nvWriteFB(struct drm_device *dev, uint32_t reg, uint32_t val) ++{ ++ NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val); ++ nv_wr32(dev, reg, val); ++} ++ ++static inline uint32_t ++nvReadEXTDEV(struct drm_device *dev, uint32_t reg) ++{ ++ uint32_t val = nv_rd32(dev, reg); ++ NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val); ++ return val; ++} ++ ++static inline void ++nvWriteEXTDEV(struct drm_device *dev, uint32_t reg, uint32_t val) ++{ ++ NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val); ++ nv_wr32(dev, reg, val); ++} ++ ++static inline uint32_t NVReadCRTC(struct drm_device *dev, ++ int head, uint32_t reg) ++{ ++ uint32_t val; ++ if (head) ++ reg += NV_PCRTC0_SIZE; ++ val = nv_rd32(dev, reg); ++ NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val); ++ return val; ++} ++ ++static inline void NVWriteCRTC(struct drm_device *dev, ++ int head, uint32_t reg, uint32_t val) ++{ ++ if (head) ++ reg += NV_PCRTC0_SIZE; ++ NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val); ++ nv_wr32(dev, reg, val); ++} ++ ++static inline uint32_t NVReadRAMDAC(struct drm_device *dev, ++ int head, uint32_t reg) ++{ ++ uint32_t val; ++ if (head) ++ reg += NV_PRAMDAC0_SIZE; ++ val = nv_rd32(dev, reg); ++ NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n", ++ head, reg, val); ++ return val; ++} ++ ++static inline void NVWriteRAMDAC(struct drm_device *dev, ++ int head, uint32_t reg, uint32_t val) ++{ ++ if (head) ++ reg += NV_PRAMDAC0_SIZE; ++ NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n", ++ head, reg, val); ++ nv_wr32(dev, reg, val); ++} ++ ++static inline uint8_t nv_read_tmds(struct drm_device *dev, ++ int or, int dl, uint8_t address) ++{ ++ int ramdac = (or & OUTPUT_C) >> 2; ++ ++ NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, ++ NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | address); ++ return NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8); ++} ++ ++static inline void nv_write_tmds(struct drm_device *dev, ++ int or, int dl, uint8_t address, ++ uint8_t data) ++{ ++ int ramdac = (or & OUTPUT_C) >> 2; ++ ++ NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8, data); ++ NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, address); ++} ++ ++static inline void NVWriteVgaCrtc(struct drm_device *dev, ++ int head, uint8_t index, uint8_t value) ++{ ++ NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n", ++ head, index, value); ++ nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); ++ nv_wr08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value); ++} ++ ++static inline uint8_t NVReadVgaCrtc(struct drm_device *dev, ++ int head, uint8_t index) ++{ ++ uint8_t val; ++ nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); ++ val = nv_rd08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE); ++ NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n", ++ head, index, val); ++ return val; ++} ++ ++/* 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(struct drm_device *dev, int head, uint8_t index, uint8_t value) ++{ ++ NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index); ++ NVWriteVgaCrtc(dev, head, NV_CIO_CRE_58, value); ++} ++ ++static inline uint8_t NVReadVgaCrtc5758(struct drm_device *dev, int head, uint8_t index) ++{ ++ NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index); ++ return NVReadVgaCrtc(dev, head, NV_CIO_CRE_58); ++} ++ ++static inline uint8_t NVReadPRMVIO(struct drm_device *dev, ++ int head, uint32_t reg) ++{ ++ uint8_t val; ++ /* Only NV4x have two pvio ranges; other twoHeads cards MUST call ++ * NVSetOwner for the relevant head to be programmed */ ++ if (head && nv_arch(dev) == NV_40) ++ reg += NV_PRMVIO_SIZE; ++ ++ val = nv_rd08(dev, reg); ++ NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n", head, reg, val); ++ return val; ++} ++ ++static inline void NVWritePRMVIO(struct drm_device *dev, ++ 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 && nv_arch(dev) == NV_40) ++ reg += NV_PRMVIO_SIZE; ++ ++ NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n", ++ head, reg, value); ++ nv_wr08(dev, reg, value); ++} ++ ++static inline void NVSetEnablePalette(struct drm_device *dev, int head, bool enable) ++{ ++ nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); ++ nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, enable ? 0 : 0x20); ++} ++ ++static inline bool NVGetEnablePalette(struct drm_device *dev, int head) ++{ ++ nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); ++ return !(nv_rd08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) & 0x20); ++} ++ ++static inline void NVWriteVgaAttr(struct drm_device *dev, ++ int head, uint8_t index, uint8_t value) ++{ ++ if (NVGetEnablePalette(dev, head)) ++ index &= ~0x20; ++ else ++ index |= 0x20; ++ ++ nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); ++ NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n", ++ head, index, value); ++ nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index); ++ nv_wr08(dev, NV_PRMCIO_AR__WRITE + head * NV_PRMCIO_SIZE, value); ++} ++ ++static inline uint8_t NVReadVgaAttr(struct drm_device *dev, ++ int head, uint8_t index) ++{ ++ uint8_t val; ++ if (NVGetEnablePalette(dev, head)) ++ index &= ~0x20; ++ else ++ index |= 0x20; ++ ++ nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); ++ nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index); ++ val = nv_rd08(dev, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE); ++ NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n", ++ head, index, val); ++ return val; ++} ++ ++static inline void NVVgaSeqReset(struct drm_device *dev, int head, bool start) ++{ ++ NVWriteVgaSeq(dev, head, NV_VIO_SR_RESET_INDEX, start ? 0x1 : 0x3); ++} ++ ++static inline void NVVgaProtect(struct drm_device *dev, int head, bool protect) ++{ ++ uint8_t seq1 = NVReadVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX); ++ ++ if (protect) { ++ NVVgaSeqReset(dev, head, true); ++ NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20); ++ } else { ++ /* Reenable sequencer, then turn on screen */ ++ NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20); /* reenable display */ ++ NVVgaSeqReset(dev, head, false); ++ } ++ NVSetEnablePalette(dev, head, protect); ++} ++ ++static inline bool ++nv_heads_tied(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->chipset == 0x11) ++ return !!(nvReadMC(dev, NV_PBUS_DEBUG_1) & (1 << 28)); ++ ++ return NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44) & 0x4; ++} ++ ++/* makes cr0-7 on the specified head read-only */ ++static inline bool ++nv_lock_vga_crtc_base(struct drm_device *dev, int head, bool lock) ++{ ++ uint8_t cr11 = NVReadVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX); ++ bool waslocked = cr11 & 0x80; ++ ++ if (lock) ++ cr11 |= 0x80; ++ else ++ cr11 &= ~0x80; ++ NVWriteVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX, cr11); ++ ++ return waslocked; ++} ++ ++static inline void ++nv_lock_vga_crtc_shadow(struct drm_device *dev, 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(dev, head, NV_CIO_CRE_21) | 0xfa; ++ ++ NVWriteVgaCrtc(dev, head, NV_CIO_CRE_21, cr21); ++} ++ ++/* renders the extended crtc regs (cr19+) on all crtcs impervious: ++ * immutable and unreadable ++ */ ++static inline bool ++NVLockVgaCrtcs(struct drm_device *dev, bool lock) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ bool waslocked = !NVReadVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX); ++ ++ NVWriteVgaCrtc(dev, 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 (dev_priv->chipset == 0x11 && !nv_heads_tied(dev)) ++ NVWriteVgaCrtc(dev, 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(struct drm_device *dev) ++{ ++ return nv_arch(dev) >= NV_10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE; ++} ++ ++static inline void ++nv_fix_nv40_hw_cursor(struct drm_device *dev, 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 ++ */ ++ uint32_t curpos = NVReadRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS, curpos); ++} ++ ++static inline void ++nv_show_cursor(struct drm_device *dev, int head, bool show) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint8_t *curctl1 = ++ &dev_priv->mode_reg.crtc_reg[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(dev, head, NV_CIO_CRE_HCUR_ADDR1_INDEX, *curctl1); ++ ++ if (nv_arch(dev) == NV_40) ++ nv_fix_nv40_hw_cursor(dev, head); ++} ++ ++static inline uint32_t ++nv_pitch_align(struct drm_device *dev, uint32_t width, int bpp) ++{ ++ int mask; ++ ++ if (bpp == 15) ++ bpp = 16; ++ if (bpp == 24) ++ bpp = 8; ++ ++ /* Alignment requirements taken from the Haiku driver */ ++ if (nv_arch(dev) == NV_04) ++ mask = 128 / bpp - 1; ++ else ++ mask = 512 / bpp - 1; ++ ++ return (width + mask) & ~mask; ++} ++ ++#endif /* __NOUVEAU_HW_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c +new file mode 100644 +index 0000000..cca2b6c +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c +@@ -0,0 +1,257 @@ ++/* ++ * Copyright 2009 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. ++ * ++ * Authors: Ben Skeggs ++ */ ++ ++#include "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_i2c.h" ++#include "nouveau_hw.h" ++ ++static void ++nv04_i2c_setscl(void *data, int state) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ uint8_t val; ++ ++ val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xd0) | (state ? 0x20 : 0); ++ NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01); ++} ++ ++static void ++nv04_i2c_setsda(void *data, int state) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ uint8_t val; ++ ++ val = (NVReadVgaCrtc(dev, 0, i2c->wr) & 0xe0) | (state ? 0x10 : 0); ++ NVWriteVgaCrtc(dev, 0, i2c->wr, val | 0x01); ++} ++ ++static int ++nv04_i2c_getscl(void *data) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 4); ++} ++ ++static int ++nv04_i2c_getsda(void *data) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ return !!(NVReadVgaCrtc(dev, 0, i2c->rd) & 8); ++} ++ ++static void ++nv4e_i2c_setscl(void *data, int state) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ uint8_t val; ++ ++ val = (nv_rd32(dev, i2c->wr) & 0xd0) | (state ? 0x20 : 0); ++ nv_wr32(dev, i2c->wr, val | 0x01); ++} ++ ++static void ++nv4e_i2c_setsda(void *data, int state) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ uint8_t val; ++ ++ val = (nv_rd32(dev, i2c->wr) & 0xe0) | (state ? 0x10 : 0); ++ nv_wr32(dev, i2c->wr, val | 0x01); ++} ++ ++static int ++nv4e_i2c_getscl(void *data) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ return !!((nv_rd32(dev, i2c->rd) >> 16) & 4); ++} ++ ++static int ++nv4e_i2c_getsda(void *data) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ return !!((nv_rd32(dev, i2c->rd) >> 16) & 8); ++} ++ ++static int ++nv50_i2c_getscl(void *data) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ return !!(nv_rd32(dev, i2c->rd) & 1); ++} ++ ++ ++static int ++nv50_i2c_getsda(void *data) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ return !!(nv_rd32(dev, i2c->rd) & 2); ++} ++ ++static void ++nv50_i2c_setscl(void *data, int state) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ nv_wr32(dev, i2c->wr, 4 | (i2c->data ? 2 : 0) | (state ? 1 : 0)); ++} ++ ++static void ++nv50_i2c_setsda(void *data, int state) ++{ ++ struct nouveau_i2c_chan *i2c = data; ++ struct drm_device *dev = i2c->dev; ++ ++ nv_wr32(dev, i2c->wr, ++ (nv_rd32(dev, i2c->rd) & 1) | 4 | (state ? 2 : 0)); ++ i2c->data = state; ++} ++ ++static const uint32_t nv50_i2c_port[] = { ++ 0x00e138, 0x00e150, 0x00e168, 0x00e180, ++ 0x00e254, 0x00e274, 0x00e764, 0x00e780, ++ 0x00e79c, 0x00e7b8 ++}; ++#define NV50_I2C_PORTS ARRAY_SIZE(nv50_i2c_port) ++ ++int ++nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_i2c_chan *i2c; ++ int ret; ++ ++ if (entry->chan) ++ return -EEXIST; ++ ++ if (dev_priv->card_type == NV_50 && entry->read >= NV50_I2C_PORTS) { ++ NV_ERROR(dev, "unknown i2c port %d\n", entry->read); ++ return -EINVAL; ++ } ++ ++ i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); ++ if (i2c == NULL) ++ return -ENOMEM; ++ ++ snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), ++ "nouveau-%s-%d", pci_name(dev->pdev), index); ++ i2c->adapter.owner = THIS_MODULE; ++ i2c->adapter.algo_data = &i2c->algo; ++ i2c->adapter.dev.parent = &dev->pdev->dev; ++ i2c->dev = dev; ++ ++ switch (entry->port_type) { ++ case 0: ++ i2c->algo.setsda = nv04_i2c_setsda; ++ i2c->algo.setscl = nv04_i2c_setscl; ++ i2c->algo.getsda = nv04_i2c_getsda; ++ i2c->algo.getscl = nv04_i2c_getscl; ++ i2c->rd = entry->read; ++ i2c->wr = entry->write; ++ break; ++ case 4: ++ i2c->algo.setsda = nv4e_i2c_setsda; ++ i2c->algo.setscl = nv4e_i2c_setscl; ++ i2c->algo.getsda = nv4e_i2c_getsda; ++ i2c->algo.getscl = nv4e_i2c_getscl; ++ i2c->rd = 0x600800 + entry->read; ++ i2c->wr = 0x600800 + entry->write; ++ break; ++ case 5: ++ i2c->algo.setsda = nv50_i2c_setsda; ++ i2c->algo.setscl = nv50_i2c_setscl; ++ i2c->algo.getsda = nv50_i2c_getsda; ++ i2c->algo.getscl = nv50_i2c_getscl; ++ i2c->rd = nv50_i2c_port[entry->read]; ++ i2c->wr = i2c->rd; ++ break; ++ default: ++ NV_ERROR(dev, "DCB I2C port type %d unknown\n", ++ entry->port_type); ++ kfree(i2c); ++ return -EINVAL; ++ } ++ i2c->algo.udelay = 40; ++ i2c->algo.timeout = usecs_to_jiffies(5000); ++ i2c->algo.data = i2c; ++ ++ i2c_set_adapdata(&i2c->adapter, i2c); ++ ++ ret = i2c_bit_add_bus(&i2c->adapter); ++ if (ret) { ++ NV_ERROR(dev, "Failed to register i2c %d\n", index); ++ kfree(i2c); ++ return ret; ++ } ++ ++ entry->chan = i2c; ++ return 0; ++} ++ ++void ++nouveau_i2c_fini(struct drm_device *dev, struct dcb_i2c_entry *entry) ++{ ++ if (!entry->chan) ++ return; ++ ++ i2c_del_adapter(&entry->chan->adapter); ++ kfree(entry->chan); ++ entry->chan = NULL; ++} ++ ++struct nouveau_i2c_chan * ++nouveau_i2c_find(struct drm_device *dev, int index) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ ++ if (index > DCB_MAX_NUM_I2C_ENTRIES) ++ return NULL; ++ ++ if (!bios->bdcb.dcb.i2c[index].chan) { ++ if (nouveau_i2c_init(dev, &bios->bdcb.dcb.i2c[index], index)) ++ return NULL; ++ } ++ ++ return bios->bdcb.dcb.i2c[index].chan; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/nouveau_i2c.h +new file mode 100644 +index 0000000..13e099c +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_i2c.h +@@ -0,0 +1,45 @@ ++/* ++ * Copyright 2009 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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_I2C_H__ ++#define __NOUVEAU_I2C_H__ ++ ++#include ++#include ++#include ++ ++struct dcb_i2c_entry; ++ ++struct nouveau_i2c_chan { ++ struct drm_device *dev; ++ struct i2c_adapter adapter; ++ struct i2c_algo_bit_data algo; ++ unsigned rd; ++ unsigned wr; ++ unsigned data; ++}; ++ ++int nouveau_i2c_init(struct drm_device *, struct dcb_i2c_entry *, int index); ++void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *); ++struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index); ++ ++#endif /* __NOUVEAU_I2C_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nouveau_ioc32.c b/drivers/gpu/drm/nouveau/nouveau_ioc32.c +new file mode 100644 +index 0000000..a2c30f4 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_ioc32.c +@@ -0,0 +1,72 @@ ++/** ++ * \file mga_ioc32.c ++ * ++ * 32-bit ioctl compatibility routines for the MGA DRM. ++ * ++ * \author Dave Airlie with code from patches by Egbert Eich ++ * ++ * ++ * Copyright (C) Paul Mackerras 2005 ++ * Copyright (C) Egbert Eich 2003,2004 ++ * Copyright (C) Dave Airlie 2005 ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHOR 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 ++ ++#include "drmP.h" ++#include "drm.h" ++ ++#include "nouveau_drv.h" ++ ++/** ++ * Called whenever a 32-bit process running under a 64-bit kernel ++ * performs an ioctl on /dev/dri/card. ++ * ++ * \param filp file pointer. ++ * \param cmd command. ++ * \param arg user argument. ++ * \return zero on success or negative number on failure. ++ */ ++long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, ++ unsigned long arg) ++{ ++ unsigned int nr = DRM_IOCTL_NR(cmd); ++ drm_ioctl_compat_t *fn = NULL; ++ int ret; ++ ++ if (nr < DRM_COMMAND_BASE) ++ return drm_compat_ioctl(filp, cmd, arg); ++ ++#if 0 ++ if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) ++ fn = nouveau_compat_ioctls[nr - DRM_COMMAND_BASE]; ++#endif ++ lock_kernel(); /* XXX for now */ ++ if (fn != NULL) ++ ret = (*fn)(filp, cmd, arg); ++ else ++ ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); ++ unlock_kernel(); ++ ++ return ret; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c +new file mode 100644 +index 0000000..597007a +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_irq.c +@@ -0,0 +1,696 @@ ++/* ++ * Copyright (C) 2006 Ben Skeggs. ++ * ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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. ++ * ++ */ ++ ++/* ++ * Authors: ++ * Ben Skeggs ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_reg.h" ++ ++/* needed for hotplug irq */ ++#include "nouveau_connector.h" ++#include "nv50_display.h" ++ ++void ++nouveau_irq_preinstall(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ /* Master disable */ ++ nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); ++ ++ if (dev_priv->card_type == NV_50) { ++ INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); ++ INIT_LIST_HEAD(&dev_priv->vbl_waiting); ++ } ++} ++ ++int ++nouveau_irq_postinstall(struct drm_device *dev) ++{ ++ /* Master enable */ ++ nv_wr32(dev, NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE); ++ return 0; ++} ++ ++void ++nouveau_irq_uninstall(struct drm_device *dev) ++{ ++ /* Master disable */ ++ nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); ++} ++ ++static int ++nouveau_call_method(struct nouveau_channel *chan, int class, int mthd, int data) ++{ ++ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; ++ struct nouveau_pgraph_object_method *grm; ++ struct nouveau_pgraph_object_class *grc; ++ ++ grc = dev_priv->engine.graph.grclass; ++ while (grc->id) { ++ if (grc->id == class) ++ break; ++ grc++; ++ } ++ ++ if (grc->id != class || !grc->methods) ++ return -ENOENT; ++ ++ grm = grc->methods; ++ while (grm->id) { ++ if (grm->id == mthd) ++ return grm->exec(chan, class, mthd, data); ++ grm++; ++ } ++ ++ return -ENOENT; ++} ++ ++static bool ++nouveau_fifo_swmthd(struct nouveau_channel *chan, uint32_t addr, uint32_t data) ++{ ++ struct drm_device *dev = chan->dev; ++ const int subc = (addr >> 13) & 0x7; ++ const int mthd = addr & 0x1ffc; ++ ++ if (mthd == 0x0000) { ++ struct nouveau_gpuobj_ref *ref = NULL; ++ ++ if (nouveau_gpuobj_ref_find(chan, data, &ref)) ++ return false; ++ ++ if (ref->gpuobj->engine != NVOBJ_ENGINE_SW) ++ return false; ++ ++ chan->sw_subchannel[subc] = ref->gpuobj->class; ++ nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_rd32(dev, ++ NV04_PFIFO_CACHE1_ENGINE) & ~(0xf << subc * 4)); ++ return true; ++ } ++ ++ /* hw object */ ++ if (nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE) & (1 << (subc*4))) ++ return false; ++ ++ if (nouveau_call_method(chan, chan->sw_subchannel[subc], mthd, data)) ++ return false; ++ ++ return true; ++} ++ ++static void ++nouveau_fifo_irq_handler(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ uint32_t status, reassign; ++ int cnt = 0; ++ ++ reassign = nv_rd32(dev, NV03_PFIFO_CACHES) & 1; ++ while ((status = nv_rd32(dev, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) { ++ struct nouveau_channel *chan = NULL; ++ uint32_t chid, get; ++ ++ nv_wr32(dev, NV03_PFIFO_CACHES, 0); ++ ++ chid = engine->fifo.channel_id(dev); ++ if (chid >= 0 && chid < engine->fifo.channels) ++ chan = dev_priv->fifos[chid]; ++ get = nv_rd32(dev, NV03_PFIFO_CACHE1_GET); ++ ++ if (status & NV_PFIFO_INTR_CACHE_ERROR) { ++ uint32_t mthd, data; ++ int ptr; ++ ++ /* NV_PFIFO_CACHE1_GET actually goes to 0xffc before ++ * wrapping on my G80 chips, but CACHE1 isn't big ++ * enough for this much data.. Tests show that it ++ * wraps around to the start at GET=0x800.. No clue ++ * as to why.. ++ */ ++ ptr = (get & 0x7ff) >> 2; ++ ++ if (dev_priv->card_type < NV_40) { ++ mthd = nv_rd32(dev, ++ NV04_PFIFO_CACHE1_METHOD(ptr)); ++ data = nv_rd32(dev, ++ NV04_PFIFO_CACHE1_DATA(ptr)); ++ } else { ++ mthd = nv_rd32(dev, ++ NV40_PFIFO_CACHE1_METHOD(ptr)); ++ data = nv_rd32(dev, ++ NV40_PFIFO_CACHE1_DATA(ptr)); ++ } ++ ++ if (!chan || !nouveau_fifo_swmthd(chan, mthd, data)) { ++ NV_INFO(dev, "PFIFO_CACHE_ERROR - Ch %d/%d " ++ "Mthd 0x%04x Data 0x%08x\n", ++ chid, (mthd >> 13) & 7, mthd & 0x1ffc, ++ data); ++ } ++ ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0); ++ nv_wr32(dev, NV03_PFIFO_INTR_0, ++ NV_PFIFO_INTR_CACHE_ERROR); ++ ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, ++ nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) & ~1); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, ++ nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) | 1); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0); ++ ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, ++ nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH) | 1); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1); ++ ++ status &= ~NV_PFIFO_INTR_CACHE_ERROR; ++ } ++ ++ if (status & NV_PFIFO_INTR_DMA_PUSHER) { ++ NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d\n", chid); ++ ++ status &= ~NV_PFIFO_INTR_DMA_PUSHER; ++ nv_wr32(dev, NV03_PFIFO_INTR_0, ++ NV_PFIFO_INTR_DMA_PUSHER); ++ ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000); ++ if (nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT) != get) ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, ++ get + 4); ++ } ++ ++ if (status) { ++ NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n", ++ status, chid); ++ nv_wr32(dev, NV03_PFIFO_INTR_0, status); ++ status = 0; ++ } ++ ++ nv_wr32(dev, NV03_PFIFO_CACHES, reassign); ++ } ++ ++ if (status) { ++ NV_INFO(dev, "PFIFO still angry after %d spins, halt\n", cnt); ++ nv_wr32(dev, 0x2140, 0); ++ nv_wr32(dev, 0x140, 0); ++ } ++ ++ nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING); ++} ++ ++struct nouveau_bitfield_names { ++ uint32_t mask; ++ const char *name; ++}; ++ ++static struct nouveau_bitfield_names nstatus_names[] = ++{ ++ { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, ++ { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, ++ { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, ++ { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" } ++}; ++ ++static struct nouveau_bitfield_names nstatus_names_nv10[] = ++{ ++ { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, ++ { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, ++ { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, ++ { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" } ++}; ++ ++static struct nouveau_bitfield_names nsource_names[] = ++{ ++ { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" }, ++ { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" }, ++ { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" }, ++ { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" }, ++ { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" }, ++ { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" }, ++ { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" }, ++ { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" }, ++ { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" }, ++ { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" }, ++ { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" }, ++ { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" }, ++ { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" }, ++ { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" }, ++ { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" }, ++ { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" }, ++ { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" }, ++ { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" }, ++ { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" }, ++}; ++ ++static void ++nouveau_print_bitfield_names_(uint32_t value, ++ const struct nouveau_bitfield_names *namelist, ++ const int namelist_len) ++{ ++ /* ++ * Caller must have already printed the KERN_* log level for us. ++ * Also the caller is responsible for adding the newline. ++ */ ++ int i; ++ for (i = 0; i < namelist_len; ++i) { ++ uint32_t mask = namelist[i].mask; ++ if (value & mask) { ++ printk(" %s", namelist[i].name); ++ value &= ~mask; ++ } ++ } ++ if (value) ++ printk(" (unknown bits 0x%08x)", value); ++} ++#define nouveau_print_bitfield_names(val, namelist) \ ++ nouveau_print_bitfield_names_((val), (namelist), ARRAY_SIZE(namelist)) ++ ++ ++static int ++nouveau_graph_chid_from_grctx(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t inst; ++ int i; ++ ++ if (dev_priv->card_type < NV_40) ++ return dev_priv->engine.fifo.channels; ++ else ++ if (dev_priv->card_type < NV_50) { ++ inst = (nv_rd32(dev, 0x40032c) & 0xfffff) << 4; ++ ++ for (i = 0; i < dev_priv->engine.fifo.channels; i++) { ++ struct nouveau_channel *chan = dev_priv->fifos[i]; ++ ++ if (!chan || !chan->ramin_grctx) ++ continue; ++ ++ if (inst == chan->ramin_grctx->instance) ++ break; ++ } ++ } else { ++ inst = (nv_rd32(dev, 0x40032c) & 0xfffff) << 12; ++ ++ for (i = 0; i < dev_priv->engine.fifo.channels; i++) { ++ struct nouveau_channel *chan = dev_priv->fifos[i]; ++ ++ if (!chan || !chan->ramin) ++ continue; ++ ++ if (inst == chan->ramin->instance) ++ break; ++ } ++ } ++ ++ ++ return i; ++} ++ ++static int ++nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ int channel; ++ ++ if (dev_priv->card_type < NV_10) ++ channel = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0xf; ++ else ++ if (dev_priv->card_type < NV_40) ++ channel = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; ++ else ++ channel = nouveau_graph_chid_from_grctx(dev); ++ ++ if (channel >= engine->fifo.channels || !dev_priv->fifos[channel]) { ++ NV_ERROR(dev, "AIII, invalid/inactive channel id %d\n", channel); ++ return -EINVAL; ++ } ++ ++ *channel_ret = channel; ++ return 0; ++} ++ ++struct nouveau_pgraph_trap { ++ int channel; ++ int class; ++ int subc, mthd, size; ++ uint32_t data, data2; ++ uint32_t nsource, nstatus; ++}; ++ ++static void ++nouveau_graph_trap_info(struct drm_device *dev, ++ struct nouveau_pgraph_trap *trap) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t address; ++ ++ trap->nsource = trap->nstatus = 0; ++ if (dev_priv->card_type < NV_50) { ++ trap->nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); ++ trap->nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS); ++ } ++ ++ if (nouveau_graph_trapped_channel(dev, &trap->channel)) ++ trap->channel = -1; ++ address = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); ++ ++ trap->mthd = address & 0x1FFC; ++ trap->data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); ++ if (dev_priv->card_type < NV_10) { ++ trap->subc = (address >> 13) & 0x7; ++ } else { ++ trap->subc = (address >> 16) & 0x7; ++ trap->data2 = nv_rd32(dev, NV10_PGRAPH_TRAPPED_DATA_HIGH); ++ } ++ ++ if (dev_priv->card_type < NV_10) ++ trap->class = nv_rd32(dev, 0x400180 + trap->subc*4) & 0xFF; ++ else if (dev_priv->card_type < NV_40) ++ trap->class = nv_rd32(dev, 0x400160 + trap->subc*4) & 0xFFF; ++ else if (dev_priv->card_type < NV_50) ++ trap->class = nv_rd32(dev, 0x400160 + trap->subc*4) & 0xFFFF; ++ else ++ trap->class = nv_rd32(dev, 0x400814); ++} ++ ++static void ++nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id, ++ struct nouveau_pgraph_trap *trap) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t nsource = trap->nsource, nstatus = trap->nstatus; ++ ++ NV_INFO(dev, "%s - nSource:", id); ++ nouveau_print_bitfield_names(nsource, nsource_names); ++ printk(", nStatus:"); ++ if (dev_priv->card_type < NV_10) ++ nouveau_print_bitfield_names(nstatus, nstatus_names); ++ else ++ nouveau_print_bitfield_names(nstatus, nstatus_names_nv10); ++ printk("\n"); ++ ++ NV_INFO(dev, "%s - Ch %d/%d Class 0x%04x Mthd 0x%04x " ++ "Data 0x%08x:0x%08x\n", ++ id, trap->channel, trap->subc, ++ trap->class, trap->mthd, ++ trap->data2, trap->data); ++} ++ ++static int ++nouveau_pgraph_intr_swmthd(struct drm_device *dev, ++ struct nouveau_pgraph_trap *trap) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (trap->channel < 0 || ++ trap->channel >= dev_priv->engine.fifo.channels || ++ !dev_priv->fifos[trap->channel]) ++ return -ENODEV; ++ ++ return nouveau_call_method(dev_priv->fifos[trap->channel], ++ trap->class, trap->mthd, trap->data); ++} ++ ++static inline void ++nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource) ++{ ++ struct nouveau_pgraph_trap trap; ++ int unhandled = 0; ++ ++ nouveau_graph_trap_info(dev, &trap); ++ ++ if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { ++ if (nouveau_pgraph_intr_swmthd(dev, &trap)) ++ unhandled = 1; ++ } else { ++ unhandled = 1; ++ } ++ ++ if (unhandled) ++ nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY", &trap); ++} ++ ++static inline void ++nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource) ++{ ++ struct nouveau_pgraph_trap trap; ++ int unhandled = 0; ++ ++ nouveau_graph_trap_info(dev, &trap); ++ trap.nsource = nsource; ++ ++ if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { ++ if (nouveau_pgraph_intr_swmthd(dev, &trap)) ++ unhandled = 1; ++ } else { ++ unhandled = 1; ++ } ++ ++ if (unhandled) ++ nouveau_graph_dump_trap_info(dev, "PGRAPH_ERROR", &trap); ++} ++ ++static inline void ++nouveau_pgraph_intr_context_switch(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ uint32_t chid; ++ ++ chid = engine->fifo.channel_id(dev); ++ NV_DEBUG(dev, "PGRAPH context switch interrupt channel %x\n", chid); ++ ++ switch (dev_priv->card_type) { ++ case NV_04: ++ case NV_05: ++ nv04_graph_context_switch(dev); ++ break; ++ case NV_10: ++ case NV_11: ++ case NV_17: ++ nv10_graph_context_switch(dev); ++ break; ++ default: ++ NV_ERROR(dev, "Context switch not implemented\n"); ++ break; ++ } ++} ++ ++static void ++nouveau_pgraph_irq_handler(struct drm_device *dev) ++{ ++ uint32_t status; ++ ++ while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) { ++ uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); ++ ++ if (status & NV_PGRAPH_INTR_NOTIFY) { ++ nouveau_pgraph_intr_notify(dev, nsource); ++ ++ status &= ~NV_PGRAPH_INTR_NOTIFY; ++ nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_NOTIFY); ++ } ++ ++ if (status & NV_PGRAPH_INTR_ERROR) { ++ nouveau_pgraph_intr_error(dev, nsource); ++ ++ status &= ~NV_PGRAPH_INTR_ERROR; ++ nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_ERROR); ++ } ++ ++ if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) { ++ nouveau_pgraph_intr_context_switch(dev); ++ ++ status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; ++ nv_wr32(dev, NV03_PGRAPH_INTR, ++ NV_PGRAPH_INTR_CONTEXT_SWITCH); ++ } ++ ++ if (status) { ++ NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status); ++ nv_wr32(dev, NV03_PGRAPH_INTR, status); ++ } ++ ++ if ((nv_rd32(dev, NV04_PGRAPH_FIFO) & (1 << 0)) == 0) ++ nv_wr32(dev, NV04_PGRAPH_FIFO, 1); ++ } ++ ++ nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); ++} ++ ++static void ++nv50_pgraph_irq_handler(struct drm_device *dev) ++{ ++ uint32_t status, nsource; ++ ++ status = nv_rd32(dev, NV03_PGRAPH_INTR); ++ nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); ++ ++ if (status & 0x00000001) { ++ nouveau_pgraph_intr_notify(dev, nsource); ++ status &= ~0x00000001; ++ nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001); ++ } ++ ++ if (status & 0x00000010) { ++ nouveau_pgraph_intr_error(dev, nsource | ++ NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD); ++ ++ status &= ~0x00000010; ++ nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010); ++ } ++ ++ if (status & 0x00001000) { ++ nv_wr32(dev, 0x400500, 0x00000000); ++ nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); ++ nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev, ++ NV40_PGRAPH_INTR_EN) & ~NV_PGRAPH_INTR_CONTEXT_SWITCH); ++ nv_wr32(dev, 0x400500, 0x00010001); ++ ++ nv50_graph_context_switch(dev); ++ ++ status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; ++ } ++ ++ if (status & 0x00100000) { ++ nouveau_pgraph_intr_error(dev, nsource | ++ NV03_PGRAPH_NSOURCE_DATA_ERROR); ++ ++ status &= ~0x00100000; ++ nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000); ++ } ++ ++ if (status & 0x00200000) { ++ int r; ++ ++ nouveau_pgraph_intr_error(dev, nsource | ++ NV03_PGRAPH_NSOURCE_PROTECTION_ERROR); ++ ++ NV_ERROR(dev, "magic set 1:\n"); ++ for (r = 0x408900; r <= 0x408910; r += 4) ++ NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r)); ++ nv_wr32(dev, 0x408900, nv_rd32(dev, 0x408904) | 0xc0000000); ++ for (r = 0x408e08; r <= 0x408e24; r += 4) ++ NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r)); ++ nv_wr32(dev, 0x408e08, nv_rd32(dev, 0x408e08) | 0xc0000000); ++ ++ NV_ERROR(dev, "magic set 2:\n"); ++ for (r = 0x409900; r <= 0x409910; r += 4) ++ NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r)); ++ nv_wr32(dev, 0x409900, nv_rd32(dev, 0x409904) | 0xc0000000); ++ for (r = 0x409e08; r <= 0x409e24; r += 4) ++ NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r)); ++ nv_wr32(dev, 0x409e08, nv_rd32(dev, 0x409e08) | 0xc0000000); ++ ++ status &= ~0x00200000; ++ nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource); ++ nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000); ++ } ++ ++ if (status) { ++ NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status); ++ nv_wr32(dev, NV03_PGRAPH_INTR, status); ++ } ++ ++ { ++ const int isb = (1 << 16) | (1 << 0); ++ ++ if ((nv_rd32(dev, 0x400500) & isb) != isb) ++ nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | isb); ++ } ++ ++ nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); ++} ++ ++static void ++nouveau_crtc_irq_handler(struct drm_device *dev, int crtc) ++{ ++ if (crtc & 1) ++ nv_wr32(dev, NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK); ++ ++ if (crtc & 2) ++ nv_wr32(dev, NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK); ++} ++ ++irqreturn_t ++nouveau_irq_handler(DRM_IRQ_ARGS) ++{ ++ struct drm_device *dev = (struct drm_device *)arg; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t status, fbdev_flags = 0; ++ ++ status = nv_rd32(dev, NV03_PMC_INTR_0); ++ if (!status) ++ return IRQ_NONE; ++ ++ if (dev_priv->fbdev_info) { ++ fbdev_flags = dev_priv->fbdev_info->flags; ++ dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED; ++ } ++ ++ if (status & NV_PMC_INTR_0_PFIFO_PENDING) { ++ nouveau_fifo_irq_handler(dev); ++ status &= ~NV_PMC_INTR_0_PFIFO_PENDING; ++ } ++ ++ if (status & NV_PMC_INTR_0_PGRAPH_PENDING) { ++ if (dev_priv->card_type >= NV_50) ++ nv50_pgraph_irq_handler(dev); ++ else ++ nouveau_pgraph_irq_handler(dev); ++ ++ status &= ~NV_PMC_INTR_0_PGRAPH_PENDING; ++ } ++ ++ if (status & NV_PMC_INTR_0_CRTCn_PENDING) { ++ nouveau_crtc_irq_handler(dev, (status>>24)&3); ++ status &= ~NV_PMC_INTR_0_CRTCn_PENDING; ++ } ++ ++ if (status & (NV_PMC_INTR_0_NV50_DISPLAY_PENDING | ++ NV_PMC_INTR_0_NV50_I2C_PENDING)) { ++ nv50_display_irq_handler(dev); ++ status &= ~(NV_PMC_INTR_0_NV50_DISPLAY_PENDING | ++ NV_PMC_INTR_0_NV50_I2C_PENDING); ++ } ++ ++ if (status) ++ NV_ERROR(dev, "Unhandled PMC INTR status bits 0x%08x\n", status); ++ ++ if (dev_priv->fbdev_info) ++ dev_priv->fbdev_info->flags = fbdev_flags; ++ ++ return IRQ_HANDLED; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c +new file mode 100644 +index 0000000..4a6fde6 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_mem.c +@@ -0,0 +1,585 @@ ++/* ++ * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. ++ * Copyright 2005 Stephane Marchesin ++ * ++ * The Weather Channel (TM) funded Tungsten Graphics to develop the ++ * initial release of the Radeon 8500 driver under the XFree86 license. ++ * This notice must be preserved. ++ * ++ * 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 AND/OR THEIR SUPPLIERS 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. ++ * ++ * Authors: ++ * Keith Whitwell ++ */ ++ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "drm_sarea.h" ++#include "nouveau_drv.h" ++ ++static struct mem_block * ++split_block(struct mem_block *p, uint64_t start, uint64_t size, ++ struct drm_file *file_priv) ++{ ++ /* Maybe cut off the start of an existing block */ ++ if (start > p->start) { ++ struct mem_block *newblock = ++ kmalloc(sizeof(*newblock), GFP_KERNEL); ++ if (!newblock) ++ goto out; ++ newblock->start = start; ++ newblock->size = p->size - (start - p->start); ++ newblock->file_priv = NULL; ++ newblock->next = p->next; ++ newblock->prev = p; ++ p->next->prev = newblock; ++ p->next = newblock; ++ p->size -= newblock->size; ++ p = newblock; ++ } ++ ++ /* Maybe cut off the end of an existing block */ ++ if (size < p->size) { ++ struct mem_block *newblock = ++ kmalloc(sizeof(*newblock), GFP_KERNEL); ++ if (!newblock) ++ goto out; ++ newblock->start = start + size; ++ newblock->size = p->size - size; ++ newblock->file_priv = NULL; ++ newblock->next = p->next; ++ newblock->prev = p; ++ p->next->prev = newblock; ++ p->next = newblock; ++ p->size = size; ++ } ++ ++out: ++ /* Our block is in the middle */ ++ p->file_priv = file_priv; ++ return p; ++} ++ ++struct mem_block * ++nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size, ++ int align2, struct drm_file *file_priv, int tail) ++{ ++ struct mem_block *p; ++ uint64_t mask = (1 << align2) - 1; ++ ++ if (!heap) ++ return NULL; ++ ++ if (tail) { ++ list_for_each_prev(p, heap) { ++ uint64_t start = ((p->start + p->size) - size) & ~mask; ++ ++ if (p->file_priv == NULL && start >= p->start && ++ start + size <= p->start + p->size) ++ return split_block(p, start, size, file_priv); ++ } ++ } else { ++ list_for_each(p, heap) { ++ uint64_t start = (p->start + mask) & ~mask; ++ ++ if (p->file_priv == NULL && ++ start + size <= p->start + p->size) ++ return split_block(p, start, size, file_priv); ++ } ++ } ++ ++ return NULL; ++} ++ ++void nouveau_mem_free_block(struct mem_block *p) ++{ ++ p->file_priv = NULL; ++ ++ /* Assumes a single contiguous range. Needs a special file_priv in ++ * 'heap' to stop it being subsumed. ++ */ ++ if (p->next->file_priv == NULL) { ++ struct mem_block *q = p->next; ++ p->size += q->size; ++ p->next = q->next; ++ p->next->prev = p; ++ kfree(q); ++ } ++ ++ if (p->prev->file_priv == NULL) { ++ struct mem_block *q = p->prev; ++ q->size += p->size; ++ q->next = p->next; ++ q->next->prev = q; ++ kfree(p); ++ } ++} ++ ++/* Initialize. How to check for an uninitialized heap? ++ */ ++int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start, ++ uint64_t size) ++{ ++ struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL); ++ ++ if (!blocks) ++ return -ENOMEM; ++ ++ *heap = kmalloc(sizeof(**heap), GFP_KERNEL); ++ if (!*heap) { ++ kfree(blocks); ++ return -ENOMEM; ++ } ++ ++ blocks->start = start; ++ blocks->size = size; ++ blocks->file_priv = NULL; ++ blocks->next = blocks->prev = *heap; ++ ++ memset(*heap, 0, sizeof(**heap)); ++ (*heap)->file_priv = (struct drm_file *) -1; ++ (*heap)->next = (*heap)->prev = blocks; ++ return 0; ++} ++ ++/* ++ * Free all blocks associated with the releasing file_priv ++ */ ++void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap) ++{ ++ struct mem_block *p; ++ ++ if (!heap || !heap->next) ++ return; ++ ++ list_for_each(p, heap) { ++ if (p->file_priv == file_priv) ++ p->file_priv = NULL; ++ } ++ ++ /* Assumes a single contiguous range. Needs a special file_priv in ++ * 'heap' to stop it being subsumed. ++ */ ++ list_for_each(p, heap) { ++ while ((p->file_priv == NULL) && ++ (p->next->file_priv == NULL) && ++ (p->next != heap)) { ++ struct mem_block *q = p->next; ++ p->size += q->size; ++ p->next = q->next; ++ p->next->prev = p; ++ kfree(q); ++ } ++ } ++} ++ ++/* ++ * NV50 VM helpers ++ */ ++int ++nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, ++ uint32_t flags, uint64_t phys) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj **pgt; ++ unsigned psz, pfl, pages; ++ ++ if (virt >= dev_priv->vm_gart_base && ++ (virt + size) < (dev_priv->vm_gart_base + dev_priv->vm_gart_size)) { ++ psz = 12; ++ pgt = &dev_priv->gart_info.sg_ctxdma; ++ pfl = 0x21; ++ virt -= dev_priv->vm_gart_base; ++ } else ++ if (virt >= dev_priv->vm_vram_base && ++ (virt + size) < (dev_priv->vm_vram_base + dev_priv->vm_vram_size)) { ++ psz = 16; ++ pgt = dev_priv->vm_vram_pt; ++ pfl = 0x01; ++ virt -= dev_priv->vm_vram_base; ++ } else { ++ NV_ERROR(dev, "Invalid address: 0x%16llx-0x%16llx\n", ++ virt, virt + size - 1); ++ return -EINVAL; ++ } ++ ++ pages = size >> psz; ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ if (flags & 0x80000000) { ++ while (pages--) { ++ struct nouveau_gpuobj *pt = pgt[virt >> 29]; ++ unsigned pte = ((virt & 0x1fffffffULL) >> psz) << 1; ++ ++ nv_wo32(dev, pt, pte++, 0x00000000); ++ nv_wo32(dev, pt, pte++, 0x00000000); ++ ++ virt += (1 << psz); ++ } ++ } else { ++ while (pages--) { ++ struct nouveau_gpuobj *pt = pgt[virt >> 29]; ++ unsigned pte = ((virt & 0x1fffffffULL) >> psz) << 1; ++ unsigned offset_h = upper_32_bits(phys) & 0xff; ++ unsigned offset_l = lower_32_bits(phys); ++ ++ nv_wo32(dev, pt, pte++, offset_l | pfl); ++ nv_wo32(dev, pt, pte++, offset_h | flags); ++ ++ phys += (1 << psz); ++ virt += (1 << psz); ++ } ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv_wr32(dev, 0x100c80, 0x00050001); ++ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { ++ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); ++ NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); ++ return -EBUSY; ++ } ++ ++ nv_wr32(dev, 0x100c80, 0x00000001); ++ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { ++ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); ++ NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); ++ return -EBUSY; ++ } ++ ++ return 0; ++} ++ ++void ++nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) ++{ ++ nv50_mem_vm_bind_linear(dev, virt, size, 0x80000000, 0); ++} ++ ++/* ++ * Cleanup everything ++ */ ++void nouveau_mem_takedown(struct mem_block **heap) ++{ ++ struct mem_block *p; ++ ++ if (!*heap) ++ return; ++ ++ for (p = (*heap)->next; p != *heap;) { ++ struct mem_block *q = p; ++ p = p->next; ++ kfree(q); ++ } ++ ++ kfree(*heap); ++ *heap = NULL; ++} ++ ++void nouveau_mem_close(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->ttm.bdev.man[TTM_PL_PRIV0].has_type) ++ ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_PRIV0); ++ ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); ++ ++ ttm_bo_device_release(&dev_priv->ttm.bdev); ++ ++ nouveau_ttm_global_release(dev_priv); ++ ++ if (drm_core_has_AGP(dev) && dev->agp && ++ drm_core_check_feature(dev, DRIVER_MODESET)) { ++ struct drm_agp_mem *entry, *tempe; ++ ++ /* Remove AGP resources, but leave dev->agp ++ intact until drv_cleanup is called. */ ++ list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) { ++ if (entry->bound) ++ drm_unbind_agp(entry->memory); ++ drm_free_agp(entry->memory, entry->pages); ++ kfree(entry); ++ } ++ INIT_LIST_HEAD(&dev->agp->memory); ++ ++ if (dev->agp->acquired) ++ drm_agp_release(dev); ++ ++ dev->agp->acquired = 0; ++ dev->agp->enabled = 0; ++ } ++ ++ if (dev_priv->fb_mtrr) { ++ drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1), ++ drm_get_resource_len(dev, 1), DRM_MTRR_WC); ++ dev_priv->fb_mtrr = 0; ++ } ++} ++ ++/*XXX won't work on BSD because of pci_read_config_dword */ ++static uint32_t ++nouveau_mem_fb_amount_igp(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct pci_dev *bridge; ++ uint32_t mem; ++ ++ bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1)); ++ if (!bridge) { ++ NV_ERROR(dev, "no bridge device\n"); ++ return 0; ++ } ++ ++ if (dev_priv->flags&NV_NFORCE) { ++ pci_read_config_dword(bridge, 0x7C, &mem); ++ return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024; ++ } else ++ if (dev_priv->flags&NV_NFORCE2) { ++ pci_read_config_dword(bridge, 0x84, &mem); ++ return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024; ++ } ++ ++ NV_ERROR(dev, "impossible!\n"); ++ return 0; ++} ++ ++/* returns the amount of FB ram in bytes */ ++uint64_t nouveau_mem_fb_amount(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ switch (dev_priv->card_type) { ++ case NV_04: ++ case NV_05: { ++ uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0); ++ if (boot0 & 0x00000100) ++ return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024; ++ ++ switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) { ++ case NV04_BOOT_0_RAM_AMOUNT_32MB: ++ return 32 * 1024 * 1024; ++ case NV04_BOOT_0_RAM_AMOUNT_16MB: ++ return 16 * 1024 * 1024; ++ case NV04_BOOT_0_RAM_AMOUNT_8MB: ++ return 8 * 1024 * 1024; ++ case NV04_BOOT_0_RAM_AMOUNT_4MB: ++ return 4 * 1024 * 1024; ++ } ++ break; ++ } ++ case NV_10: ++ case NV_11: ++ case NV_17: ++ case NV_20: ++ case NV_30: ++ case NV_40: ++ case NV_50: ++ default: ++ if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) { ++ return nouveau_mem_fb_amount_igp(dev); ++ } else { ++ uint64_t mem; ++ mem = (nv_rd32(dev, NV04_FIFO_DATA) & ++ NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >> ++ NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT; ++ return mem * 1024 * 1024; ++ } ++ break; ++ } ++ ++ NV_ERROR(dev, ++ "Unable to detect video ram size. Please report your setup to " ++ DRIVER_EMAIL "\n"); ++ return 0; ++} ++ ++static void nouveau_mem_reset_agp(struct drm_device *dev) ++{ ++ uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable; ++ ++ saved_pci_nv_1 = nv_rd32(dev, NV04_PBUS_PCI_NV_1); ++ saved_pci_nv_19 = nv_rd32(dev, NV04_PBUS_PCI_NV_19); ++ ++ /* clear busmaster bit */ ++ nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4); ++ /* clear SBA and AGP bits */ ++ nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff); ++ ++ /* power cycle pgraph, if enabled */ ++ pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE); ++ if (pmc_enable & NV_PMC_ENABLE_PGRAPH) { ++ nv_wr32(dev, NV03_PMC_ENABLE, ++ pmc_enable & ~NV_PMC_ENABLE_PGRAPH); ++ nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | ++ NV_PMC_ENABLE_PGRAPH); ++ } ++ ++ /* and restore (gives effect of resetting AGP) */ ++ nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19); ++ nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1); ++} ++ ++int ++nouveau_mem_init_agp(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_agp_info info; ++ struct drm_agp_mode mode; ++ int ret; ++ ++ if (nouveau_noagp) ++ return 0; ++ ++ nouveau_mem_reset_agp(dev); ++ ++ if (!dev->agp->acquired) { ++ ret = drm_agp_acquire(dev); ++ if (ret) { ++ NV_ERROR(dev, "Unable to acquire AGP: %d\n", ret); ++ return ret; ++ } ++ } ++ ++ ret = drm_agp_info(dev, &info); ++ if (ret) { ++ NV_ERROR(dev, "Unable to get AGP info: %d\n", ret); ++ return ret; ++ } ++ ++ /* see agp.h for the AGPSTAT_* modes available */ ++ mode.mode = info.mode; ++ ret = drm_agp_enable(dev, mode); ++ if (ret) { ++ NV_ERROR(dev, "Unable to enable AGP: %d\n", ret); ++ return ret; ++ } ++ ++ dev_priv->gart_info.type = NOUVEAU_GART_AGP; ++ dev_priv->gart_info.aper_base = info.aperture_base; ++ dev_priv->gart_info.aper_size = info.aperture_size; ++ return 0; ++} ++ ++int ++nouveau_mem_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; ++ uint32_t vram_size, bar1_size, text_size; ++ int ret, dma_bits = 32; ++ ++ dev_priv->fb_phys = drm_get_resource_start(dev, 1); ++ dev_priv->gart_info.type = NOUVEAU_GART_NONE; ++ ++ if (dev_priv->card_type >= NV_50 && ++ pci_dma_supported(dev->pdev, DMA_BIT_MASK(40))) ++ dma_bits = 40; ++ ++ ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits)); ++ if (ret) { ++ NV_ERROR(dev, "Error setting DMA mask: %d\n", ret); ++ return ret; ++ } ++ ++ ret = nouveau_ttm_global_init(dev_priv); ++ if (ret) ++ return ret; ++ ++ ret = ttm_bo_device_init(&dev_priv->ttm.bdev, ++ dev_priv->ttm.bo_global_ref.ref.object, ++ &nouveau_bo_driver, DRM_FILE_PAGE_OFFSET, ++ dma_bits <= 32 ? true : false); ++ if (ret) { ++ NV_ERROR(dev, "Error initialising bo driver: %d\n", ret); ++ return ret; ++ } ++ ++ INIT_LIST_HEAD(&dev_priv->ttm.bo_list); ++ spin_lock_init(&dev_priv->ttm.bo_list_lock); ++ ++ dev_priv->fb_available_size = nouveau_mem_fb_amount(dev); ++ NV_INFO(dev, "%d MiB VRAM\n", (int)(dev_priv->fb_available_size >> 20)); ++ ++ /* remove reserved space at end of vram from available amount */ ++ dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram; ++ dev_priv->fb_aper_free = dev_priv->fb_available_size; ++ ++ /* non-mappable vram */ ++ vram_size = dev_priv->fb_available_size >> PAGE_SHIFT; ++ bar1_size = drm_get_resource_len(dev, 1) >> PAGE_SHIFT; ++ if (bar1_size < vram_size) { ++ if (dev_priv->card_type < NV_50) { ++ ret = ttm_bo_init_mm(bdev, TTM_PL_PRIV0, bar1_size, ++ vram_size - bar1_size); ++ if (ret) { ++ NV_ERROR(dev, "Failed PRIV0 mm init: %d\n", ++ ret); ++ return ret; ++ } ++ } ++ vram_size = bar1_size; ++ } ++ ++ /* remove reserved space at start of vram from available amount */ ++ dev_priv->fb_aper_free -= (256 * 1024); ++ text_size = (256 * 1024) >> PAGE_SHIFT; ++ vram_size -= text_size; ++ ++ /* mappable vram */ ++ ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM, text_size, vram_size); ++ if (ret) { ++ NV_ERROR(dev, "Failed VRAM mm init: %d\n", ret); ++ return ret; ++ } ++ ++ /* GART */ ++#if !defined(__powerpc__) && !defined(__ia64__) ++ if (drm_device_is_agp(dev) && dev->agp) { ++ ret = nouveau_mem_init_agp(dev); ++ if (ret) ++ NV_ERROR(dev, "Error initialising AGP: %d\n", ret); ++ } ++#endif ++ ++ if (dev_priv->gart_info.type == NOUVEAU_GART_NONE) { ++ ret = nouveau_sgdma_init(dev); ++ if (ret) { ++ NV_ERROR(dev, "Error initialising PCI(E): %d\n", ret); ++ return ret; ++ } ++ } ++ ++ NV_INFO(dev, "%d MiB GART (aperture)\n", ++ (int)(dev_priv->gart_info.aper_size >> 20)); ++ dev_priv->gart_info.aper_free = dev_priv->gart_info.aper_size; ++ ++ ret = ttm_bo_init_mm(bdev, TTM_PL_TT, 0, ++ dev_priv->gart_info.aper_size >> PAGE_SHIFT); ++ if (ret) { ++ NV_ERROR(dev, "Failed TT mm init: %d\n", ret); ++ return ret; ++ } ++ ++ dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1), ++ drm_get_resource_len(dev, 1), ++ DRM_MTRR_WC); ++ return 0; ++} ++ ++ +diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c +new file mode 100644 +index 0000000..6c66a34 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c +@@ -0,0 +1,196 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++int ++nouveau_notifier_init_channel(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct nouveau_bo *ntfy = NULL; ++ int ret; ++ ++ ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, nouveau_vram_notify ? ++ TTM_PL_FLAG_VRAM : TTM_PL_FLAG_TT, ++ 0, 0x0000, false, true, &ntfy); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_bo_pin(ntfy, TTM_PL_FLAG_VRAM); ++ if (ret) ++ goto out_err; ++ ++ ret = nouveau_bo_map(ntfy); ++ if (ret) ++ goto out_err; ++ ++ ret = nouveau_mem_init_heap(&chan->notifier_heap, 0, ntfy->bo.mem.size); ++ if (ret) ++ goto out_err; ++ ++ chan->notifier_bo = ntfy; ++out_err: ++ if (ret) { ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(ntfy->gem); ++ mutex_unlock(&dev->struct_mutex); ++ } ++ ++ return ret; ++} ++ ++void ++nouveau_notifier_takedown_channel(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ ++ if (!chan->notifier_bo) ++ return; ++ ++ nouveau_bo_unmap(chan->notifier_bo); ++ mutex_lock(&dev->struct_mutex); ++ nouveau_bo_unpin(chan->notifier_bo); ++ drm_gem_object_unreference(chan->notifier_bo->gem); ++ mutex_unlock(&dev->struct_mutex); ++ nouveau_mem_takedown(&chan->notifier_heap); ++} ++ ++static void ++nouveau_notifier_gpuobj_dtor(struct drm_device *dev, ++ struct nouveau_gpuobj *gpuobj) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ if (gpuobj->priv) ++ nouveau_mem_free_block(gpuobj->priv); ++} ++ ++int ++nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, ++ int size, uint32_t *b_offset) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *nobj = NULL; ++ struct mem_block *mem; ++ uint32_t offset; ++ int target, ret; ++ ++ if (!chan->notifier_heap) { ++ NV_ERROR(dev, "Channel %d doesn't have a notifier heap!\n", ++ chan->id); ++ return -EINVAL; ++ } ++ ++ mem = nouveau_mem_alloc_block(chan->notifier_heap, size, 0, ++ (struct drm_file *)-2, 0); ++ if (!mem) { ++ NV_ERROR(dev, "Channel %d notifier block full\n", chan->id); ++ return -ENOMEM; ++ } ++ ++ offset = chan->notifier_bo->bo.mem.mm_node->start << PAGE_SHIFT; ++ if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM) { ++ target = NV_DMA_TARGET_VIDMEM; ++ } else ++ if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_TT) { ++ if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA && ++ dev_priv->card_type < NV_50) { ++ ret = nouveau_sgdma_get_page(dev, offset, &offset); ++ if (ret) ++ return ret; ++ target = NV_DMA_TARGET_PCI; ++ } else { ++ target = NV_DMA_TARGET_AGP; ++ } ++ } else { ++ NV_ERROR(dev, "Bad DMA target, mem_type %d!\n", ++ chan->notifier_bo->bo.mem.mem_type); ++ return -EINVAL; ++ } ++ offset += mem->start; ++ ++ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset, ++ mem->size, NV_DMA_ACCESS_RW, target, ++ &nobj); ++ if (ret) { ++ nouveau_mem_free_block(mem); ++ NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret); ++ return ret; ++ } ++ nobj->dtor = nouveau_notifier_gpuobj_dtor; ++ nobj->priv = mem; ++ ++ ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL); ++ if (ret) { ++ nouveau_gpuobj_del(dev, &nobj); ++ nouveau_mem_free_block(mem); ++ NV_ERROR(dev, "Error referencing notifier ctxdma: %d\n", ret); ++ return ret; ++ } ++ ++ *b_offset = mem->start; ++ return 0; ++} ++ ++int ++nouveau_notifier_offset(struct nouveau_gpuobj *nobj, uint32_t *poffset) ++{ ++ if (!nobj || nobj->dtor != nouveau_notifier_gpuobj_dtor) ++ return -EINVAL; ++ ++ if (poffset) { ++ struct mem_block *mem = nobj->priv; ++ ++ if (*poffset >= mem->size) ++ return false; ++ ++ *poffset += mem->start; ++ } ++ ++ return 0; ++} ++ ++int ++nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_notifierobj_alloc *na = data; ++ struct nouveau_channel *chan; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan); ++ ++ ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset); ++ if (ret) ++ return ret; ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c +new file mode 100644 +index 0000000..93379bb +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_object.c +@@ -0,0 +1,1294 @@ ++/* ++ * Copyright (C) 2006 Ben Skeggs. ++ * ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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. ++ * ++ */ ++ ++/* ++ * Authors: ++ * Ben Skeggs ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++/* NVidia uses context objects to drive drawing operations. ++ ++ Context objects can be selected into 8 subchannels in the FIFO, ++ and then used via DMA command buffers. ++ ++ A context object is referenced by a user defined handle (CARD32). The HW ++ looks up graphics objects in a hash table in the instance RAM. ++ ++ An entry in the hash table consists of 2 CARD32. The first CARD32 contains ++ the handle, the second one a bitfield, that contains the address of the ++ object in instance RAM. ++ ++ The format of the second CARD32 seems to be: ++ ++ NV4 to NV30: ++ ++ 15: 0 instance_addr >> 4 ++ 17:16 engine (here uses 1 = graphics) ++ 28:24 channel id (here uses 0) ++ 31 valid (use 1) ++ ++ NV40: ++ ++ 15: 0 instance_addr >> 4 (maybe 19-0) ++ 21:20 engine (here uses 1 = graphics) ++ I'm unsure about the other bits, but using 0 seems to work. ++ ++ The key into the hash table depends on the object handle and channel id and ++ is given as: ++*/ ++static uint32_t ++nouveau_ramht_hash_handle(struct drm_device *dev, int channel, uint32_t handle) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t hash = 0; ++ int i; ++ ++ NV_DEBUG(dev, "ch%d handle=0x%08x\n", channel, handle); ++ ++ for (i = 32; i > 0; i -= dev_priv->ramht_bits) { ++ hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1)); ++ handle >>= dev_priv->ramht_bits; ++ } ++ ++ if (dev_priv->card_type < NV_50) ++ hash ^= channel << (dev_priv->ramht_bits - 4); ++ hash <<= 3; ++ ++ NV_DEBUG(dev, "hash=0x%08x\n", hash); ++ return hash; ++} ++ ++static int ++nouveau_ramht_entry_valid(struct drm_device *dev, struct nouveau_gpuobj *ramht, ++ uint32_t offset) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t ctx = nv_ro32(dev, ramht, (offset + 4)/4); ++ ++ if (dev_priv->card_type < NV_40) ++ return ((ctx & NV_RAMHT_CONTEXT_VALID) != 0); ++ return (ctx != 0); ++} ++ ++static int ++nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; ++ struct nouveau_channel *chan = ref->channel; ++ struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL; ++ uint32_t ctx, co, ho; ++ ++ if (!ramht) { ++ NV_ERROR(dev, "No hash table!\n"); ++ return -EINVAL; ++ } ++ ++ if (dev_priv->card_type < NV_40) { ++ ctx = NV_RAMHT_CONTEXT_VALID | (ref->instance >> 4) | ++ (chan->id << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) | ++ (ref->gpuobj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT); ++ } else ++ if (dev_priv->card_type < NV_50) { ++ ctx = (ref->instance >> 4) | ++ (chan->id << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) | ++ (ref->gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT); ++ } else { ++ if (ref->gpuobj->engine == NVOBJ_ENGINE_DISPLAY) { ++ ctx = (ref->instance << 10) | 2; ++ } else { ++ ctx = (ref->instance >> 4) | ++ ((ref->gpuobj->engine << ++ NV40_RAMHT_CONTEXT_ENGINE_SHIFT)); ++ } ++ } ++ ++ instmem->prepare_access(dev, true); ++ co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle); ++ do { ++ if (!nouveau_ramht_entry_valid(dev, ramht, co)) { ++ NV_DEBUG(dev, ++ "insert ch%d 0x%08x: h=0x%08x, c=0x%08x\n", ++ chan->id, co, ref->handle, ctx); ++ nv_wo32(dev, ramht, (co + 0)/4, ref->handle); ++ nv_wo32(dev, ramht, (co + 4)/4, ctx); ++ ++ list_add_tail(&ref->list, &chan->ramht_refs); ++ instmem->finish_access(dev); ++ return 0; ++ } ++ NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n", ++ chan->id, co, nv_ro32(dev, ramht, co/4)); ++ ++ co += 8; ++ if (co >= dev_priv->ramht_size) ++ co = 0; ++ } while (co != ho); ++ instmem->finish_access(dev); ++ ++ NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id); ++ return -ENOMEM; ++} ++ ++static void ++nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; ++ struct nouveau_channel *chan = ref->channel; ++ struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL; ++ uint32_t co, ho; ++ ++ if (!ramht) { ++ NV_ERROR(dev, "No hash table!\n"); ++ return; ++ } ++ ++ instmem->prepare_access(dev, true); ++ co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle); ++ do { ++ if (nouveau_ramht_entry_valid(dev, ramht, co) && ++ (ref->handle == nv_ro32(dev, ramht, (co/4)))) { ++ NV_DEBUG(dev, ++ "remove ch%d 0x%08x: h=0x%08x, c=0x%08x\n", ++ chan->id, co, ref->handle, ++ nv_ro32(dev, ramht, (co + 4))); ++ nv_wo32(dev, ramht, (co + 0)/4, 0x00000000); ++ nv_wo32(dev, ramht, (co + 4)/4, 0x00000000); ++ ++ list_del(&ref->list); ++ instmem->finish_access(dev); ++ return; ++ } ++ ++ co += 8; ++ if (co >= dev_priv->ramht_size) ++ co = 0; ++ } while (co != ho); ++ list_del(&ref->list); ++ instmem->finish_access(dev); ++ ++ NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n", ++ chan->id, ref->handle); ++} ++ ++int ++nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, ++ uint32_t size, int align, uint32_t flags, ++ struct nouveau_gpuobj **gpuobj_ret) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ struct nouveau_gpuobj *gpuobj; ++ struct mem_block *pramin = NULL; ++ int ret; ++ ++ NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n", ++ chan ? chan->id : -1, size, align, flags); ++ ++ if (!dev_priv || !gpuobj_ret || *gpuobj_ret != NULL) ++ return -EINVAL; ++ ++ gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); ++ if (!gpuobj) ++ return -ENOMEM; ++ NV_DEBUG(dev, "gpuobj %p\n", gpuobj); ++ gpuobj->flags = flags; ++ gpuobj->im_channel = chan; ++ ++ list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); ++ ++ /* Choose between global instmem heap, and per-channel private ++ * instmem heap. On ramin_heap) { ++ NV_DEBUG(dev, "private heap\n"); ++ pramin = chan->ramin_heap; ++ } else ++ if (dev_priv->card_type < NV_50) { ++ NV_DEBUG(dev, "global heap fallback\n"); ++ pramin = dev_priv->ramin_heap; ++ } ++ } else { ++ NV_DEBUG(dev, "global heap\n"); ++ pramin = dev_priv->ramin_heap; ++ } ++ ++ if (!pramin) { ++ NV_ERROR(dev, "No PRAMIN heap!\n"); ++ return -EINVAL; ++ } ++ ++ if (!chan) { ++ ret = engine->instmem.populate(dev, gpuobj, &size); ++ if (ret) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return ret; ++ } ++ } ++ ++ /* Allocate a chunk of the PRAMIN aperture */ ++ gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size, ++ drm_order(align), ++ (struct drm_file *)-2, 0); ++ if (!gpuobj->im_pramin) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return -ENOMEM; ++ } ++ ++ if (!chan) { ++ ret = engine->instmem.bind(dev, gpuobj); ++ if (ret) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return ret; ++ } ++ } ++ ++ if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { ++ int i; ++ ++ engine->instmem.prepare_access(dev, true); ++ for (i = 0; i < gpuobj->im_pramin->size; i += 4) ++ nv_wo32(dev, gpuobj, i/4, 0); ++ engine->instmem.finish_access(dev); ++ } ++ ++ *gpuobj_ret = gpuobj; ++ return 0; ++} ++ ++int ++nouveau_gpuobj_early_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ INIT_LIST_HEAD(&dev_priv->gpuobj_list); ++ ++ return 0; ++} ++ ++int ++nouveau_gpuobj_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (dev_priv->card_type < NV_50) { ++ ret = nouveau_gpuobj_new_fake(dev, ++ dev_priv->ramht_offset, ~0, dev_priv->ramht_size, ++ NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ALLOW_NO_REFS, ++ &dev_priv->ramht, NULL); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++void ++nouveau_gpuobj_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nouveau_gpuobj_del(dev, &dev_priv->ramht); ++} ++ ++void ++nouveau_gpuobj_late_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj = NULL; ++ struct list_head *entry, *tmp; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ list_for_each_safe(entry, tmp, &dev_priv->gpuobj_list) { ++ gpuobj = list_entry(entry, struct nouveau_gpuobj, list); ++ ++ NV_ERROR(dev, "gpuobj %p still exists at takedown, refs=%d\n", ++ gpuobj, gpuobj->refcount); ++ gpuobj->refcount = 0; ++ nouveau_gpuobj_del(dev, &gpuobj); ++ } ++} ++ ++int ++nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ struct nouveau_gpuobj *gpuobj; ++ int i; ++ ++ NV_DEBUG(dev, "gpuobj %p\n", pgpuobj ? *pgpuobj : NULL); ++ ++ if (!dev_priv || !pgpuobj || !(*pgpuobj)) ++ return -EINVAL; ++ gpuobj = *pgpuobj; ++ ++ if (gpuobj->refcount != 0) { ++ NV_ERROR(dev, "gpuobj refcount is %d\n", gpuobj->refcount); ++ return -EINVAL; ++ } ++ ++ if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) { ++ engine->instmem.prepare_access(dev, true); ++ for (i = 0; i < gpuobj->im_pramin->size; i += 4) ++ nv_wo32(dev, gpuobj, i/4, 0); ++ engine->instmem.finish_access(dev); ++ } ++ ++ if (gpuobj->dtor) ++ gpuobj->dtor(dev, gpuobj); ++ ++ if (gpuobj->im_backing && !(gpuobj->flags & NVOBJ_FLAG_FAKE)) ++ engine->instmem.clear(dev, gpuobj); ++ ++ if (gpuobj->im_pramin) { ++ if (gpuobj->flags & NVOBJ_FLAG_FAKE) ++ kfree(gpuobj->im_pramin); ++ else ++ nouveau_mem_free_block(gpuobj->im_pramin); ++ } ++ ++ list_del(&gpuobj->list); ++ ++ *pgpuobj = NULL; ++ kfree(gpuobj); ++ return 0; ++} ++ ++static int ++nouveau_gpuobj_instance_get(struct drm_device *dev, ++ struct nouveau_channel *chan, ++ struct nouveau_gpuobj *gpuobj, uint32_t *inst) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *cpramin; ++ ++ /* card_type < NV_50) { ++ *inst = gpuobj->im_pramin->start; ++ return 0; ++ } ++ ++ if (chan && gpuobj->im_channel != chan) { ++ NV_ERROR(dev, "Channel mismatch: obj %d, ref %d\n", ++ gpuobj->im_channel->id, chan->id); ++ return -EINVAL; ++ } ++ ++ /* NV50 channel-local instance */ ++ if (chan) { ++ cpramin = chan->ramin->gpuobj; ++ *inst = gpuobj->im_pramin->start - cpramin->im_pramin->start; ++ return 0; ++ } ++ ++ /* NV50 global (VRAM) instance */ ++ if (!gpuobj->im_channel) { ++ /* ...from global heap */ ++ if (!gpuobj->im_backing) { ++ NV_ERROR(dev, "AII, no VRAM backing gpuobj\n"); ++ return -EINVAL; ++ } ++ *inst = gpuobj->im_backing_start; ++ return 0; ++ } else { ++ /* ...from local heap */ ++ cpramin = gpuobj->im_channel->ramin->gpuobj; ++ *inst = cpramin->im_backing_start + ++ (gpuobj->im_pramin->start - cpramin->im_pramin->start); ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ ++int ++nouveau_gpuobj_ref_add(struct drm_device *dev, struct nouveau_channel *chan, ++ uint32_t handle, struct nouveau_gpuobj *gpuobj, ++ struct nouveau_gpuobj_ref **ref_ret) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj_ref *ref; ++ uint32_t instance; ++ int ret; ++ ++ NV_DEBUG(dev, "ch%d h=0x%08x gpuobj=%p\n", ++ chan ? chan->id : -1, handle, gpuobj); ++ ++ if (!dev_priv || !gpuobj || (ref_ret && *ref_ret != NULL)) ++ return -EINVAL; ++ ++ if (!chan && !ref_ret) ++ return -EINVAL; ++ ++ if (gpuobj->engine == NVOBJ_ENGINE_SW && !gpuobj->im_pramin) { ++ /* sw object */ ++ instance = 0x40; ++ } else { ++ ret = nouveau_gpuobj_instance_get(dev, chan, gpuobj, &instance); ++ if (ret) ++ return ret; ++ } ++ ++ ref = kzalloc(sizeof(*ref), GFP_KERNEL); ++ if (!ref) ++ return -ENOMEM; ++ INIT_LIST_HEAD(&ref->list); ++ ref->gpuobj = gpuobj; ++ ref->channel = chan; ++ ref->instance = instance; ++ ++ if (!ref_ret) { ++ ref->handle = handle; ++ ++ ret = nouveau_ramht_insert(dev, ref); ++ if (ret) { ++ kfree(ref); ++ return ret; ++ } ++ } else { ++ ref->handle = ~0; ++ *ref_ret = ref; ++ } ++ ++ ref->gpuobj->refcount++; ++ return 0; ++} ++ ++int nouveau_gpuobj_ref_del(struct drm_device *dev, struct nouveau_gpuobj_ref **pref) ++{ ++ struct nouveau_gpuobj_ref *ref; ++ ++ NV_DEBUG(dev, "ref %p\n", pref ? *pref : NULL); ++ ++ if (!dev || !pref || *pref == NULL) ++ return -EINVAL; ++ ref = *pref; ++ ++ if (ref->handle != ~0) ++ nouveau_ramht_remove(dev, ref); ++ ++ if (ref->gpuobj) { ++ ref->gpuobj->refcount--; ++ ++ if (ref->gpuobj->refcount == 0) { ++ if (!(ref->gpuobj->flags & NVOBJ_FLAG_ALLOW_NO_REFS)) ++ nouveau_gpuobj_del(dev, &ref->gpuobj); ++ } ++ } ++ ++ *pref = NULL; ++ kfree(ref); ++ return 0; ++} ++ ++int ++nouveau_gpuobj_new_ref(struct drm_device *dev, ++ struct nouveau_channel *oc, struct nouveau_channel *rc, ++ uint32_t handle, uint32_t size, int align, ++ uint32_t flags, struct nouveau_gpuobj_ref **ref) ++{ ++ struct nouveau_gpuobj *gpuobj = NULL; ++ int ret; ++ ++ ret = nouveau_gpuobj_new(dev, oc, size, align, flags, &gpuobj); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_gpuobj_ref_add(dev, rc, handle, gpuobj, ref); ++ if (ret) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int ++nouveau_gpuobj_ref_find(struct nouveau_channel *chan, uint32_t handle, ++ struct nouveau_gpuobj_ref **ref_ret) ++{ ++ struct nouveau_gpuobj_ref *ref; ++ struct list_head *entry, *tmp; ++ ++ list_for_each_safe(entry, tmp, &chan->ramht_refs) { ++ ref = list_entry(entry, struct nouveau_gpuobj_ref, list); ++ ++ if (ref->handle == handle) { ++ if (ref_ret) ++ *ref_ret = ref; ++ return 0; ++ } ++ } ++ ++ return -EINVAL; ++} ++ ++int ++nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset, ++ uint32_t b_offset, uint32_t size, ++ uint32_t flags, struct nouveau_gpuobj **pgpuobj, ++ struct nouveau_gpuobj_ref **pref) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj = NULL; ++ int i; ++ ++ NV_DEBUG(dev, ++ "p_offset=0x%08x b_offset=0x%08x size=0x%08x flags=0x%08x\n", ++ p_offset, b_offset, size, flags); ++ ++ gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); ++ if (!gpuobj) ++ return -ENOMEM; ++ NV_DEBUG(dev, "gpuobj %p\n", gpuobj); ++ gpuobj->im_channel = NULL; ++ gpuobj->flags = flags | NVOBJ_FLAG_FAKE; ++ ++ list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); ++ ++ if (p_offset != ~0) { ++ gpuobj->im_pramin = kzalloc(sizeof(struct mem_block), ++ GFP_KERNEL); ++ if (!gpuobj->im_pramin) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return -ENOMEM; ++ } ++ gpuobj->im_pramin->start = p_offset; ++ gpuobj->im_pramin->size = size; ++ } ++ ++ if (b_offset != ~0) { ++ gpuobj->im_backing = (struct nouveau_bo *)-1; ++ gpuobj->im_backing_start = b_offset; ++ } ++ ++ if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ for (i = 0; i < gpuobj->im_pramin->size; i += 4) ++ nv_wo32(dev, gpuobj, i/4, 0); ++ dev_priv->engine.instmem.finish_access(dev); ++ } ++ ++ if (pref) { ++ i = nouveau_gpuobj_ref_add(dev, NULL, 0, gpuobj, pref); ++ if (i) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return i; ++ } ++ } ++ ++ if (pgpuobj) ++ *pgpuobj = gpuobj; ++ return 0; ++} ++ ++ ++static uint32_t ++nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ /*XXX: dodgy hack for now */ ++ if (dev_priv->card_type >= NV_50) ++ return 24; ++ if (dev_priv->card_type >= NV_40) ++ return 32; ++ return 16; ++} ++ ++/* ++ DMA objects are used to reference a piece of memory in the ++ framebuffer, PCI or AGP address space. Each object is 16 bytes big ++ and looks as follows: ++ ++ entry[0] ++ 11:0 class (seems like I can always use 0 here) ++ 12 page table present? ++ 13 page entry linear? ++ 15:14 access: 0 rw, 1 ro, 2 wo ++ 17:16 target: 0 NV memory, 1 NV memory tiled, 2 PCI, 3 AGP ++ 31:20 dma adjust (bits 0-11 of the address) ++ entry[1] ++ dma limit (size of transfer) ++ entry[X] ++ 1 0 readonly, 1 readwrite ++ 31:12 dma frame address of the page (bits 12-31 of the address) ++ entry[N] ++ page table terminator, same value as the first pte, as does nvidia ++ rivatv uses 0xffffffff ++ ++ Non linear page tables need a list of frame addresses afterwards, ++ the rivatv project has some info on this. ++ ++ The method below creates a DMA object in instance RAM and returns a handle ++ to it that can be used to set up context objects. ++*/ ++int ++nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, ++ uint64_t offset, uint64_t size, int access, ++ int target, struct nouveau_gpuobj **gpuobj) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; ++ int ret; ++ ++ NV_DEBUG(dev, "ch%d class=0x%04x offset=0x%llx size=0x%llx\n", ++ chan->id, class, offset, size); ++ NV_DEBUG(dev, "access=%d target=%d\n", access, target); ++ ++ switch (target) { ++ case NV_DMA_TARGET_AGP: ++ offset += dev_priv->gart_info.aper_base; ++ break; ++ default: ++ break; ++ } ++ ++ ret = nouveau_gpuobj_new(dev, chan, ++ nouveau_gpuobj_class_instmem_size(dev, class), ++ 16, NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, gpuobj); ++ if (ret) { ++ NV_ERROR(dev, "Error creating gpuobj: %d\n", ret); ++ return ret; ++ } ++ ++ instmem->prepare_access(dev, true); ++ ++ if (dev_priv->card_type < NV_50) { ++ uint32_t frame, adjust, pte_flags = 0; ++ ++ if (access != NV_DMA_ACCESS_RO) ++ pte_flags |= (1<<1); ++ adjust = offset & 0x00000fff; ++ frame = offset & ~0x00000fff; ++ ++ nv_wo32(dev, *gpuobj, 0, ((1<<12) | (1<<13) | ++ (adjust << 20) | ++ (access << 14) | ++ (target << 16) | ++ class)); ++ nv_wo32(dev, *gpuobj, 1, size - 1); ++ nv_wo32(dev, *gpuobj, 2, frame | pte_flags); ++ nv_wo32(dev, *gpuobj, 3, frame | pte_flags); ++ } else { ++ uint64_t limit = offset + size - 1; ++ uint32_t flags0, flags5; ++ ++ if (target == NV_DMA_TARGET_VIDMEM) { ++ flags0 = 0x00190000; ++ flags5 = 0x00010000; ++ } else { ++ flags0 = 0x7fc00000; ++ flags5 = 0x00080000; ++ } ++ ++ nv_wo32(dev, *gpuobj, 0, flags0 | class); ++ nv_wo32(dev, *gpuobj, 1, lower_32_bits(limit)); ++ nv_wo32(dev, *gpuobj, 2, lower_32_bits(offset)); ++ nv_wo32(dev, *gpuobj, 3, ((upper_32_bits(limit) & 0xff) << 24) | ++ (upper_32_bits(offset) & 0xff)); ++ nv_wo32(dev, *gpuobj, 5, flags5); ++ } ++ ++ instmem->finish_access(dev); ++ ++ (*gpuobj)->engine = NVOBJ_ENGINE_SW; ++ (*gpuobj)->class = class; ++ return 0; ++} ++ ++int ++nouveau_gpuobj_gart_dma_new(struct nouveau_channel *chan, ++ uint64_t offset, uint64_t size, int access, ++ struct nouveau_gpuobj **gpuobj, ++ uint32_t *o_ret) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int ret; ++ ++ if (dev_priv->gart_info.type == NOUVEAU_GART_AGP || ++ (dev_priv->card_type >= NV_50 && ++ dev_priv->gart_info.type == NOUVEAU_GART_SGDMA)) { ++ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, ++ offset + dev_priv->vm_gart_base, ++ size, access, NV_DMA_TARGET_AGP, ++ gpuobj); ++ if (o_ret) ++ *o_ret = 0; ++ } else ++ if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) { ++ *gpuobj = dev_priv->gart_info.sg_ctxdma; ++ if (offset & ~0xffffffffULL) { ++ NV_ERROR(dev, "obj offset exceeds 32-bits\n"); ++ return -EINVAL; ++ } ++ if (o_ret) ++ *o_ret = (uint32_t)offset; ++ ret = (*gpuobj != NULL) ? 0 : -EINVAL; ++ } else { ++ NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type); ++ return -EINVAL; ++ } ++ ++ return ret; ++} ++ ++/* Context objects in the instance RAM have the following structure. ++ * On NV40 they are 32 byte long, on NV30 and smaller 16 bytes. ++ ++ NV4 - NV30: ++ ++ entry[0] ++ 11:0 class ++ 12 chroma key enable ++ 13 user clip enable ++ 14 swizzle enable ++ 17:15 patch config: ++ scrcopy_and, rop_and, blend_and, scrcopy, srccopy_pre, blend_pre ++ 18 synchronize enable ++ 19 endian: 1 big, 0 little ++ 21:20 dither mode ++ 23 single step enable ++ 24 patch status: 0 invalid, 1 valid ++ 25 context_surface 0: 1 valid ++ 26 context surface 1: 1 valid ++ 27 context pattern: 1 valid ++ 28 context rop: 1 valid ++ 29,30 context beta, beta4 ++ entry[1] ++ 7:0 mono format ++ 15:8 color format ++ 31:16 notify instance address ++ entry[2] ++ 15:0 dma 0 instance address ++ 31:16 dma 1 instance address ++ entry[3] ++ dma method traps ++ ++ NV40: ++ No idea what the exact format is. Here's what can be deducted: ++ ++ entry[0]: ++ 11:0 class (maybe uses more bits here?) ++ 17 user clip enable ++ 21:19 patch config ++ 25 patch status valid ? ++ entry[1]: ++ 15:0 DMA notifier (maybe 20:0) ++ entry[2]: ++ 15:0 DMA 0 instance (maybe 20:0) ++ 24 big endian ++ entry[3]: ++ 15:0 DMA 1 instance (maybe 20:0) ++ entry[4]: ++ entry[5]: ++ set to 0? ++*/ ++int ++nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, ++ struct nouveau_gpuobj **gpuobj) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int ret; ++ ++ NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class); ++ ++ ret = nouveau_gpuobj_new(dev, chan, ++ nouveau_gpuobj_class_instmem_size(dev, class), ++ 16, ++ NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, ++ gpuobj); ++ if (ret) { ++ NV_ERROR(dev, "Error creating gpuobj: %d\n", ret); ++ return ret; ++ } ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ if (dev_priv->card_type >= NV_50) { ++ nv_wo32(dev, *gpuobj, 0, class); ++ nv_wo32(dev, *gpuobj, 5, 0x00010000); ++ } else { ++ switch (class) { ++ case NV_CLASS_NULL: ++ nv_wo32(dev, *gpuobj, 0, 0x00001030); ++ nv_wo32(dev, *gpuobj, 1, 0xFFFFFFFF); ++ break; ++ default: ++ if (dev_priv->card_type >= NV_40) { ++ nv_wo32(dev, *gpuobj, 0, class); ++#ifdef __BIG_ENDIAN ++ nv_wo32(dev, *gpuobj, 2, 0x01000000); ++#endif ++ } else { ++#ifdef __BIG_ENDIAN ++ nv_wo32(dev, *gpuobj, 0, class | 0x00080000); ++#else ++ nv_wo32(dev, *gpuobj, 0, class); ++#endif ++ } ++ } ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ (*gpuobj)->engine = NVOBJ_ENGINE_GR; ++ (*gpuobj)->class = class; ++ return 0; ++} ++ ++static int ++nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, ++ struct nouveau_gpuobj **gpuobj_ret) ++{ ++ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; ++ struct nouveau_gpuobj *gpuobj; ++ ++ if (!chan || !gpuobj_ret || *gpuobj_ret != NULL) ++ return -EINVAL; ++ ++ gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); ++ if (!gpuobj) ++ return -ENOMEM; ++ gpuobj->engine = NVOBJ_ENGINE_SW; ++ gpuobj->class = class; ++ ++ list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); ++ *gpuobj_ret = gpuobj; ++ return 0; ++} ++ ++static int ++nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *pramin = NULL; ++ uint32_t size; ++ uint32_t base; ++ int ret; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ /* Base amount for object storage (4KiB enough?) */ ++ size = 0x1000; ++ base = 0; ++ ++ /* PGRAPH context */ ++ ++ if (dev_priv->card_type == NV_50) { ++ /* Various fixed table thingos */ ++ size += 0x1400; /* mostly unknown stuff */ ++ size += 0x4000; /* vm pd */ ++ base = 0x6000; ++ /* RAMHT, not sure about setting size yet, 32KiB to be safe */ ++ size += 0x8000; ++ /* RAMFC */ ++ size += 0x1000; ++ /* PGRAPH context */ ++ size += 0x70000; ++ } ++ ++ NV_DEBUG(dev, "ch%d PRAMIN size: 0x%08x bytes, base alloc=0x%08x\n", ++ chan->id, size, base); ++ ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0, ++ &chan->ramin); ++ if (ret) { ++ NV_ERROR(dev, "Error allocating channel PRAMIN: %d\n", ret); ++ return ret; ++ } ++ pramin = chan->ramin->gpuobj; ++ ++ ret = nouveau_mem_init_heap(&chan->ramin_heap, ++ pramin->im_pramin->start + base, size); ++ if (ret) { ++ NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret); ++ nouveau_gpuobj_ref_del(dev, &chan->ramin); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int ++nouveau_gpuobj_channel_init(struct nouveau_channel *chan, ++ uint32_t vram_h, uint32_t tt_h) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; ++ struct nouveau_gpuobj *vram = NULL, *tt = NULL; ++ int ret, i; ++ ++ INIT_LIST_HEAD(&chan->ramht_refs); ++ ++ NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); ++ ++ /* Reserve a block of PRAMIN for the channel ++ *XXX: maybe on card_type == NV_50) { ++ ret = nouveau_gpuobj_channel_init_pramin(chan); ++ if (ret) { ++ NV_ERROR(dev, "init pramin\n"); ++ return ret; ++ } ++ } ++ ++ /* NV50 VM ++ * - Allocate per-channel page-directory ++ * - Map GART and VRAM into the channel's address space at the ++ * locations determined during init. ++ */ ++ if (dev_priv->card_type >= NV_50) { ++ uint32_t vm_offset, pde; ++ ++ instmem->prepare_access(dev, true); ++ ++ vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200; ++ vm_offset += chan->ramin->gpuobj->im_pramin->start; ++ ++ ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000, ++ 0, &chan->vm_pd, NULL); ++ if (ret) { ++ instmem->finish_access(dev); ++ return ret; ++ } ++ for (i = 0; i < 0x4000; i += 8) { ++ nv_wo32(dev, chan->vm_pd, (i+0)/4, 0x00000000); ++ nv_wo32(dev, chan->vm_pd, (i+4)/4, 0xdeadcafe); ++ } ++ ++ pde = (dev_priv->vm_gart_base / (512*1024*1024)) * 2; ++ ret = nouveau_gpuobj_ref_add(dev, NULL, 0, ++ dev_priv->gart_info.sg_ctxdma, ++ &chan->vm_gart_pt); ++ if (ret) { ++ instmem->finish_access(dev); ++ return ret; ++ } ++ nv_wo32(dev, chan->vm_pd, pde++, ++ chan->vm_gart_pt->instance | 0x03); ++ nv_wo32(dev, chan->vm_pd, pde++, 0x00000000); ++ ++ pde = (dev_priv->vm_vram_base / (512*1024*1024)) * 2; ++ for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) { ++ ret = nouveau_gpuobj_ref_add(dev, NULL, 0, ++ dev_priv->vm_vram_pt[i], ++ &chan->vm_vram_pt[i]); ++ if (ret) { ++ instmem->finish_access(dev); ++ return ret; ++ } ++ ++ nv_wo32(dev, chan->vm_pd, pde++, ++ chan->vm_vram_pt[i]->instance | 0x61); ++ nv_wo32(dev, chan->vm_pd, pde++, 0x00000000); ++ } ++ ++ instmem->finish_access(dev); ++ } ++ ++ /* RAMHT */ ++ if (dev_priv->card_type < NV_50) { ++ ret = nouveau_gpuobj_ref_add(dev, NULL, 0, dev_priv->ramht, ++ &chan->ramht); ++ if (ret) ++ return ret; ++ } else { ++ ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, ++ 0x8000, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &chan->ramht); ++ if (ret) ++ return ret; ++ } ++ ++ /* VRAM ctxdma */ ++ if (dev_priv->card_type >= NV_50) { ++ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, ++ 0, dev_priv->vm_end, ++ NV_DMA_ACCESS_RW, ++ NV_DMA_TARGET_AGP, &vram); ++ if (ret) { ++ NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); ++ return ret; ++ } ++ } else { ++ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, ++ 0, dev_priv->fb_available_size, ++ NV_DMA_ACCESS_RW, ++ NV_DMA_TARGET_VIDMEM, &vram); ++ if (ret) { ++ NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); ++ return ret; ++ } ++ } ++ ++ ret = nouveau_gpuobj_ref_add(dev, chan, vram_h, vram, NULL); ++ if (ret) { ++ NV_ERROR(dev, "Error referencing VRAM ctxdma: %d\n", ret); ++ return ret; ++ } ++ ++ /* TT memory ctxdma */ ++ if (dev_priv->card_type >= NV_50) { ++ tt = vram; ++ } else ++ if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) { ++ ret = nouveau_gpuobj_gart_dma_new(chan, 0, ++ dev_priv->gart_info.aper_size, ++ NV_DMA_ACCESS_RW, &tt, NULL); ++ } else { ++ NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type); ++ ret = -EINVAL; ++ } ++ ++ if (ret) { ++ NV_ERROR(dev, "Error creating TT ctxdma: %d\n", ret); ++ return ret; ++ } ++ ++ ret = nouveau_gpuobj_ref_add(dev, chan, tt_h, tt, NULL); ++ if (ret) { ++ NV_ERROR(dev, "Error referencing TT ctxdma: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++void ++nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) ++{ ++ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; ++ struct drm_device *dev = chan->dev; ++ struct list_head *entry, *tmp; ++ struct nouveau_gpuobj_ref *ref; ++ int i; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ if (!chan->ramht_refs.next) ++ return; ++ ++ list_for_each_safe(entry, tmp, &chan->ramht_refs) { ++ ref = list_entry(entry, struct nouveau_gpuobj_ref, list); ++ ++ nouveau_gpuobj_ref_del(dev, &ref); ++ } ++ ++ nouveau_gpuobj_ref_del(dev, &chan->ramht); ++ ++ nouveau_gpuobj_del(dev, &chan->vm_pd); ++ nouveau_gpuobj_ref_del(dev, &chan->vm_gart_pt); ++ for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) ++ nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]); ++ ++ if (chan->ramin_heap) ++ nouveau_mem_takedown(&chan->ramin_heap); ++ if (chan->ramin) ++ nouveau_gpuobj_ref_del(dev, &chan->ramin); ++ ++} ++ ++int ++nouveau_gpuobj_suspend(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj; ++ int i; ++ ++ if (dev_priv->card_type < NV_50) { ++ dev_priv->susres.ramin_copy = vmalloc(dev_priv->ramin_rsvd_vram); ++ if (!dev_priv->susres.ramin_copy) ++ return -ENOMEM; ++ ++ for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4) ++ dev_priv->susres.ramin_copy[i/4] = nv_ri32(dev, i); ++ return 0; ++ } ++ ++ list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { ++ if (!gpuobj->im_backing || (gpuobj->flags & NVOBJ_FLAG_FAKE)) ++ continue; ++ ++ gpuobj->im_backing_suspend = vmalloc(gpuobj->im_pramin->size); ++ if (!gpuobj->im_backing_suspend) { ++ nouveau_gpuobj_resume(dev); ++ return -ENOMEM; ++ } ++ ++ dev_priv->engine.instmem.prepare_access(dev, false); ++ for (i = 0; i < gpuobj->im_pramin->size / 4; i++) ++ gpuobj->im_backing_suspend[i] = nv_ro32(dev, gpuobj, i); ++ dev_priv->engine.instmem.finish_access(dev); ++ } ++ ++ return 0; ++} ++ ++void ++nouveau_gpuobj_suspend_cleanup(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj; ++ ++ if (dev_priv->card_type < NV_50) { ++ vfree(dev_priv->susres.ramin_copy); ++ dev_priv->susres.ramin_copy = NULL; ++ return; ++ } ++ ++ list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { ++ if (!gpuobj->im_backing_suspend) ++ continue; ++ ++ vfree(gpuobj->im_backing_suspend); ++ gpuobj->im_backing_suspend = NULL; ++ } ++} ++ ++void ++nouveau_gpuobj_resume(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj; ++ int i; ++ ++ if (dev_priv->card_type < NV_50) { ++ for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4) ++ nv_wi32(dev, i, dev_priv->susres.ramin_copy[i/4]); ++ nouveau_gpuobj_suspend_cleanup(dev); ++ return; ++ } ++ ++ list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { ++ if (!gpuobj->im_backing_suspend) ++ continue; ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ for (i = 0; i < gpuobj->im_pramin->size / 4; i++) ++ nv_wo32(dev, gpuobj, i, gpuobj->im_backing_suspend[i]); ++ dev_priv->engine.instmem.finish_access(dev); ++ } ++ ++ nouveau_gpuobj_suspend_cleanup(dev); ++} ++ ++int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_nouveau_grobj_alloc *init = data; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; ++ struct nouveau_pgraph_object_class *grc; ++ struct nouveau_gpuobj *gr = NULL; ++ struct nouveau_channel *chan; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan); ++ ++ if (init->handle == ~0) ++ return -EINVAL; ++ ++ grc = pgraph->grclass; ++ while (grc->id) { ++ if (grc->id == init->class) ++ break; ++ grc++; ++ } ++ ++ if (!grc->id) { ++ NV_ERROR(dev, "Illegal object class: 0x%x\n", init->class); ++ return -EPERM; ++ } ++ ++ if (nouveau_gpuobj_ref_find(chan, init->handle, NULL) == 0) ++ return -EEXIST; ++ ++ if (!grc->software) ++ ret = nouveau_gpuobj_gr_new(chan, grc->id, &gr); ++ else ++ ret = nouveau_gpuobj_sw_new(chan, grc->id, &gr); ++ ++ if (ret) { ++ NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n", ++ ret, init->channel, init->handle); ++ return ret; ++ } ++ ++ ret = nouveau_gpuobj_ref_add(dev, chan, init->handle, gr, NULL); ++ if (ret) { ++ NV_ERROR(dev, "Error referencing object: %d (%d/0x%08x)\n", ++ ret, init->channel, init->handle); ++ nouveau_gpuobj_del(dev, &gr); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_gpuobj_free *objfree = data; ++ struct nouveau_gpuobj_ref *ref; ++ struct nouveau_channel *chan; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan); ++ ++ ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref); ++ if (ret) ++ return ret; ++ nouveau_gpuobj_ref_del(dev, &ref); ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h +new file mode 100644 +index 0000000..3a5f43a +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_reg.h +@@ -0,0 +1,788 @@ ++ ++ ++#define NV03_BOOT_0 0x00100000 ++# define NV03_BOOT_0_RAM_AMOUNT 0x00000003 ++# define NV03_BOOT_0_RAM_AMOUNT_8MB 0x00000000 ++# define NV03_BOOT_0_RAM_AMOUNT_2MB 0x00000001 ++# define NV03_BOOT_0_RAM_AMOUNT_4MB 0x00000002 ++# define NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM 0x00000003 ++# define NV04_BOOT_0_RAM_AMOUNT_32MB 0x00000000 ++# define NV04_BOOT_0_RAM_AMOUNT_4MB 0x00000001 ++# define NV04_BOOT_0_RAM_AMOUNT_8MB 0x00000002 ++# define NV04_BOOT_0_RAM_AMOUNT_16MB 0x00000003 ++ ++#define NV04_FIFO_DATA 0x0010020c ++# define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000 ++# define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20 ++ ++#define NV_RAMIN 0x00700000 ++ ++#define NV_RAMHT_HANDLE_OFFSET 0 ++#define NV_RAMHT_CONTEXT_OFFSET 4 ++# define NV_RAMHT_CONTEXT_VALID (1<<31) ++# define NV_RAMHT_CONTEXT_CHANNEL_SHIFT 24 ++# define NV_RAMHT_CONTEXT_ENGINE_SHIFT 16 ++# define NV_RAMHT_CONTEXT_ENGINE_SOFTWARE 0 ++# define NV_RAMHT_CONTEXT_ENGINE_GRAPHICS 1 ++# define NV_RAMHT_CONTEXT_INSTANCE_SHIFT 0 ++# define NV40_RAMHT_CONTEXT_CHANNEL_SHIFT 23 ++# define NV40_RAMHT_CONTEXT_ENGINE_SHIFT 20 ++# define NV40_RAMHT_CONTEXT_INSTANCE_SHIFT 0 ++ ++/* DMA object defines */ ++#define NV_DMA_ACCESS_RW 0 ++#define NV_DMA_ACCESS_RO 1 ++#define NV_DMA_ACCESS_WO 2 ++#define NV_DMA_TARGET_VIDMEM 0 ++#define NV_DMA_TARGET_PCI 2 ++#define NV_DMA_TARGET_AGP 3 ++/* The following is not a real value used by the card, it's changed by ++ * nouveau_object_dma_create */ ++#define NV_DMA_TARGET_PCI_NONLINEAR 8 ++ ++/* Some object classes we care about in the drm */ ++#define NV_CLASS_DMA_FROM_MEMORY 0x00000002 ++#define NV_CLASS_DMA_TO_MEMORY 0x00000003 ++#define NV_CLASS_NULL 0x00000030 ++#define NV_CLASS_DMA_IN_MEMORY 0x0000003D ++ ++#define NV03_USER(i) (0x00800000+(i*NV03_USER_SIZE)) ++#define NV03_USER__SIZE 16 ++#define NV10_USER__SIZE 32 ++#define NV03_USER_SIZE 0x00010000 ++#define NV03_USER_DMA_PUT(i) (0x00800040+(i*NV03_USER_SIZE)) ++#define NV03_USER_DMA_PUT__SIZE 16 ++#define NV10_USER_DMA_PUT__SIZE 32 ++#define NV03_USER_DMA_GET(i) (0x00800044+(i*NV03_USER_SIZE)) ++#define NV03_USER_DMA_GET__SIZE 16 ++#define NV10_USER_DMA_GET__SIZE 32 ++#define NV03_USER_REF_CNT(i) (0x00800048+(i*NV03_USER_SIZE)) ++#define NV03_USER_REF_CNT__SIZE 16 ++#define NV10_USER_REF_CNT__SIZE 32 ++ ++#define NV40_USER(i) (0x00c00000+(i*NV40_USER_SIZE)) ++#define NV40_USER_SIZE 0x00001000 ++#define NV40_USER_DMA_PUT(i) (0x00c00040+(i*NV40_USER_SIZE)) ++#define NV40_USER_DMA_PUT__SIZE 32 ++#define NV40_USER_DMA_GET(i) (0x00c00044+(i*NV40_USER_SIZE)) ++#define NV40_USER_DMA_GET__SIZE 32 ++#define NV40_USER_REF_CNT(i) (0x00c00048+(i*NV40_USER_SIZE)) ++#define NV40_USER_REF_CNT__SIZE 32 ++ ++#define NV50_USER(i) (0x00c00000+(i*NV50_USER_SIZE)) ++#define NV50_USER_SIZE 0x00002000 ++#define NV50_USER_DMA_PUT(i) (0x00c00040+(i*NV50_USER_SIZE)) ++#define NV50_USER_DMA_PUT__SIZE 128 ++#define NV50_USER_DMA_GET(i) (0x00c00044+(i*NV50_USER_SIZE)) ++#define NV50_USER_DMA_GET__SIZE 128 ++#define NV50_USER_REF_CNT(i) (0x00c00048+(i*NV50_USER_SIZE)) ++#define NV50_USER_REF_CNT__SIZE 128 ++ ++#define NV03_FIFO_SIZE 0x8000UL ++ ++#define NV03_PMC_BOOT_0 0x00000000 ++#define NV03_PMC_BOOT_1 0x00000004 ++#define NV03_PMC_INTR_0 0x00000100 ++# define NV_PMC_INTR_0_PFIFO_PENDING (1<<8) ++# define NV_PMC_INTR_0_PGRAPH_PENDING (1<<12) ++# define NV_PMC_INTR_0_NV50_I2C_PENDING (1<<21) ++# define NV_PMC_INTR_0_CRTC0_PENDING (1<<24) ++# define NV_PMC_INTR_0_CRTC1_PENDING (1<<25) ++# define NV_PMC_INTR_0_NV50_DISPLAY_PENDING (1<<26) ++# define NV_PMC_INTR_0_CRTCn_PENDING (3<<24) ++#define NV03_PMC_INTR_EN_0 0x00000140 ++# define NV_PMC_INTR_EN_0_MASTER_ENABLE (1<<0) ++#define NV03_PMC_ENABLE 0x00000200 ++# define NV_PMC_ENABLE_PFIFO (1<<8) ++# define NV_PMC_ENABLE_PGRAPH (1<<12) ++/* Disabling the below bit breaks newer (G7X only?) mobile chipsets, ++ * the card will hang early on in the X init process. ++ */ ++# define NV_PMC_ENABLE_UNK13 (1<<13) ++#define NV40_PMC_BACKLIGHT 0x000015f0 ++# define NV40_PMC_BACKLIGHT_MASK 0x001f0000 ++#define NV40_PMC_1700 0x00001700 ++#define NV40_PMC_1704 0x00001704 ++#define NV40_PMC_1708 0x00001708 ++#define NV40_PMC_170C 0x0000170C ++ ++/* probably PMC ? */ ++#define NV50_PUNK_BAR0_PRAMIN 0x00001700 ++#define NV50_PUNK_BAR_CFG_BASE 0x00001704 ++#define NV50_PUNK_BAR_CFG_BASE_VALID (1<<30) ++#define NV50_PUNK_BAR1_CTXDMA 0x00001708 ++#define NV50_PUNK_BAR1_CTXDMA_VALID (1<<31) ++#define NV50_PUNK_BAR3_CTXDMA 0x0000170C ++#define NV50_PUNK_BAR3_CTXDMA_VALID (1<<31) ++#define NV50_PUNK_UNK1710 0x00001710 ++ ++#define NV04_PBUS_PCI_NV_1 0x00001804 ++#define NV04_PBUS_PCI_NV_19 0x0000184C ++#define NV04_PBUS_PCI_NV_20 0x00001850 ++# define NV04_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED (0 << 0) ++# define NV04_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED (1 << 0) ++ ++#define NV04_PTIMER_INTR_0 0x00009100 ++#define NV04_PTIMER_INTR_EN_0 0x00009140 ++#define NV04_PTIMER_NUMERATOR 0x00009200 ++#define NV04_PTIMER_DENOMINATOR 0x00009210 ++#define NV04_PTIMER_TIME_0 0x00009400 ++#define NV04_PTIMER_TIME_1 0x00009410 ++#define NV04_PTIMER_ALARM_0 0x00009420 ++ ++#define NV04_PFB_CFG0 0x00100200 ++#define NV04_PFB_CFG1 0x00100204 ++#define NV40_PFB_020C 0x0010020C ++#define NV10_PFB_TILE(i) (0x00100240 + (i*16)) ++#define NV10_PFB_TILE__SIZE 8 ++#define NV10_PFB_TLIMIT(i) (0x00100244 + (i*16)) ++#define NV10_PFB_TSIZE(i) (0x00100248 + (i*16)) ++#define NV10_PFB_TSTATUS(i) (0x0010024C + (i*16)) ++#define NV10_PFB_CLOSE_PAGE2 0x0010033C ++#define NV40_PFB_TILE(i) (0x00100600 + (i*16)) ++#define NV40_PFB_TILE__SIZE_0 12 ++#define NV40_PFB_TILE__SIZE_1 15 ++#define NV40_PFB_TLIMIT(i) (0x00100604 + (i*16)) ++#define NV40_PFB_TSIZE(i) (0x00100608 + (i*16)) ++#define NV40_PFB_TSTATUS(i) (0x0010060C + (i*16)) ++#define NV40_PFB_UNK_800 0x00100800 ++ ++#define NV04_PGRAPH_DEBUG_0 0x00400080 ++#define NV04_PGRAPH_DEBUG_1 0x00400084 ++#define NV04_PGRAPH_DEBUG_2 0x00400088 ++#define NV04_PGRAPH_DEBUG_3 0x0040008c ++#define NV10_PGRAPH_DEBUG_4 0x00400090 ++#define NV03_PGRAPH_INTR 0x00400100 ++#define NV03_PGRAPH_NSTATUS 0x00400104 ++# define NV04_PGRAPH_NSTATUS_STATE_IN_USE (1<<11) ++# define NV04_PGRAPH_NSTATUS_INVALID_STATE (1<<12) ++# define NV04_PGRAPH_NSTATUS_BAD_ARGUMENT (1<<13) ++# define NV04_PGRAPH_NSTATUS_PROTECTION_FAULT (1<<14) ++# define NV10_PGRAPH_NSTATUS_STATE_IN_USE (1<<23) ++# define NV10_PGRAPH_NSTATUS_INVALID_STATE (1<<24) ++# define NV10_PGRAPH_NSTATUS_BAD_ARGUMENT (1<<25) ++# define NV10_PGRAPH_NSTATUS_PROTECTION_FAULT (1<<26) ++#define NV03_PGRAPH_NSOURCE 0x00400108 ++# define NV03_PGRAPH_NSOURCE_NOTIFICATION (1<<0) ++# define NV03_PGRAPH_NSOURCE_DATA_ERROR (1<<1) ++# define NV03_PGRAPH_NSOURCE_PROTECTION_ERROR (1<<2) ++# define NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION (1<<3) ++# define NV03_PGRAPH_NSOURCE_LIMIT_COLOR (1<<4) ++# define NV03_PGRAPH_NSOURCE_LIMIT_ZETA (1<<5) ++# define NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD (1<<6) ++# define NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION (1<<7) ++# define NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION (1<<8) ++# define NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION (1<<9) ++# define NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION (1<<10) ++# define NV03_PGRAPH_NSOURCE_STATE_INVALID (1<<11) ++# define NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY (1<<12) ++# define NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE (1<<13) ++# define NV03_PGRAPH_NSOURCE_METHOD_CNT (1<<14) ++# define NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION (1<<15) ++# define NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION (1<<16) ++# define NV03_PGRAPH_NSOURCE_DMA_WIDTH_A (1<<17) ++# define NV03_PGRAPH_NSOURCE_DMA_WIDTH_B (1<<18) ++#define NV03_PGRAPH_INTR_EN 0x00400140 ++#define NV40_PGRAPH_INTR_EN 0x0040013C ++# define NV_PGRAPH_INTR_NOTIFY (1<<0) ++# define NV_PGRAPH_INTR_MISSING_HW (1<<4) ++# define NV_PGRAPH_INTR_CONTEXT_SWITCH (1<<12) ++# define NV_PGRAPH_INTR_BUFFER_NOTIFY (1<<16) ++# define NV_PGRAPH_INTR_ERROR (1<<20) ++#define NV10_PGRAPH_CTX_CONTROL 0x00400144 ++#define NV10_PGRAPH_CTX_USER 0x00400148 ++#define NV10_PGRAPH_CTX_SWITCH1 0x0040014C ++#define NV10_PGRAPH_CTX_SWITCH2 0x00400150 ++#define NV10_PGRAPH_CTX_SWITCH3 0x00400154 ++#define NV10_PGRAPH_CTX_SWITCH4 0x00400158 ++#define NV10_PGRAPH_CTX_SWITCH5 0x0040015C ++#define NV04_PGRAPH_CTX_SWITCH1 0x00400160 ++#define NV10_PGRAPH_CTX_CACHE1 0x00400160 ++#define NV04_PGRAPH_CTX_SWITCH2 0x00400164 ++#define NV04_PGRAPH_CTX_SWITCH3 0x00400168 ++#define NV04_PGRAPH_CTX_SWITCH4 0x0040016C ++#define NV04_PGRAPH_CTX_CONTROL 0x00400170 ++#define NV04_PGRAPH_CTX_USER 0x00400174 ++#define NV04_PGRAPH_CTX_CACHE1 0x00400180 ++#define NV10_PGRAPH_CTX_CACHE2 0x00400180 ++#define NV03_PGRAPH_CTX_CONTROL 0x00400190 ++#define NV03_PGRAPH_CTX_USER 0x00400194 ++#define NV04_PGRAPH_CTX_CACHE2 0x004001A0 ++#define NV10_PGRAPH_CTX_CACHE3 0x004001A0 ++#define NV04_PGRAPH_CTX_CACHE3 0x004001C0 ++#define NV10_PGRAPH_CTX_CACHE4 0x004001C0 ++#define NV04_PGRAPH_CTX_CACHE4 0x004001E0 ++#define NV10_PGRAPH_CTX_CACHE5 0x004001E0 ++#define NV40_PGRAPH_CTXCTL_0304 0x00400304 ++#define NV40_PGRAPH_CTXCTL_0304_XFER_CTX 0x00000001 ++#define NV40_PGRAPH_CTXCTL_UCODE_STAT 0x00400308 ++#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_MASK 0xff000000 ++#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT 24 ++#define NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK 0x00ffffff ++#define NV40_PGRAPH_CTXCTL_0310 0x00400310 ++#define NV40_PGRAPH_CTXCTL_0310_XFER_SAVE 0x00000020 ++#define NV40_PGRAPH_CTXCTL_0310_XFER_LOAD 0x00000040 ++#define NV40_PGRAPH_CTXCTL_030C 0x0040030c ++#define NV40_PGRAPH_CTXCTL_UCODE_INDEX 0x00400324 ++#define NV40_PGRAPH_CTXCTL_UCODE_DATA 0x00400328 ++#define NV40_PGRAPH_CTXCTL_CUR 0x0040032c ++#define NV40_PGRAPH_CTXCTL_CUR_LOADED 0x01000000 ++#define NV40_PGRAPH_CTXCTL_CUR_INSTANCE 0x000FFFFF ++#define NV40_PGRAPH_CTXCTL_NEXT 0x00400330 ++#define NV40_PGRAPH_CTXCTL_NEXT_INSTANCE 0x000fffff ++#define NV50_PGRAPH_CTXCTL_CUR 0x0040032c ++#define NV50_PGRAPH_CTXCTL_CUR_LOADED 0x80000000 ++#define NV50_PGRAPH_CTXCTL_CUR_INSTANCE 0x00ffffff ++#define NV50_PGRAPH_CTXCTL_NEXT 0x00400330 ++#define NV50_PGRAPH_CTXCTL_NEXT_INSTANCE 0x00ffffff ++#define NV03_PGRAPH_ABS_X_RAM 0x00400400 ++#define NV03_PGRAPH_ABS_Y_RAM 0x00400480 ++#define NV03_PGRAPH_X_MISC 0x00400500 ++#define NV03_PGRAPH_Y_MISC 0x00400504 ++#define NV04_PGRAPH_VALID1 0x00400508 ++#define NV04_PGRAPH_SOURCE_COLOR 0x0040050C ++#define NV04_PGRAPH_MISC24_0 0x00400510 ++#define NV03_PGRAPH_XY_LOGIC_MISC0 0x00400514 ++#define NV03_PGRAPH_XY_LOGIC_MISC1 0x00400518 ++#define NV03_PGRAPH_XY_LOGIC_MISC2 0x0040051C ++#define NV03_PGRAPH_XY_LOGIC_MISC3 0x00400520 ++#define NV03_PGRAPH_CLIPX_0 0x00400524 ++#define NV03_PGRAPH_CLIPX_1 0x00400528 ++#define NV03_PGRAPH_CLIPY_0 0x0040052C ++#define NV03_PGRAPH_CLIPY_1 0x00400530 ++#define NV03_PGRAPH_ABS_ICLIP_XMAX 0x00400534 ++#define NV03_PGRAPH_ABS_ICLIP_YMAX 0x00400538 ++#define NV03_PGRAPH_ABS_UCLIP_XMIN 0x0040053C ++#define NV03_PGRAPH_ABS_UCLIP_YMIN 0x00400540 ++#define NV03_PGRAPH_ABS_UCLIP_XMAX 0x00400544 ++#define NV03_PGRAPH_ABS_UCLIP_YMAX 0x00400548 ++#define NV03_PGRAPH_ABS_UCLIPA_XMIN 0x00400560 ++#define NV03_PGRAPH_ABS_UCLIPA_YMIN 0x00400564 ++#define NV03_PGRAPH_ABS_UCLIPA_XMAX 0x00400568 ++#define NV03_PGRAPH_ABS_UCLIPA_YMAX 0x0040056C ++#define NV04_PGRAPH_MISC24_1 0x00400570 ++#define NV04_PGRAPH_MISC24_2 0x00400574 ++#define NV04_PGRAPH_VALID2 0x00400578 ++#define NV04_PGRAPH_PASSTHRU_0 0x0040057C ++#define NV04_PGRAPH_PASSTHRU_1 0x00400580 ++#define NV04_PGRAPH_PASSTHRU_2 0x00400584 ++#define NV10_PGRAPH_DIMX_TEXTURE 0x00400588 ++#define NV10_PGRAPH_WDIMX_TEXTURE 0x0040058C ++#define NV04_PGRAPH_COMBINE_0_ALPHA 0x00400590 ++#define NV04_PGRAPH_COMBINE_0_COLOR 0x00400594 ++#define NV04_PGRAPH_COMBINE_1_ALPHA 0x00400598 ++#define NV04_PGRAPH_COMBINE_1_COLOR 0x0040059C ++#define NV04_PGRAPH_FORMAT_0 0x004005A8 ++#define NV04_PGRAPH_FORMAT_1 0x004005AC ++#define NV04_PGRAPH_FILTER_0 0x004005B0 ++#define NV04_PGRAPH_FILTER_1 0x004005B4 ++#define NV03_PGRAPH_MONO_COLOR0 0x00400600 ++#define NV04_PGRAPH_ROP3 0x00400604 ++#define NV04_PGRAPH_BETA_AND 0x00400608 ++#define NV04_PGRAPH_BETA_PREMULT 0x0040060C ++#define NV04_PGRAPH_LIMIT_VIOL_PIX 0x00400610 ++#define NV04_PGRAPH_FORMATS 0x00400618 ++#define NV10_PGRAPH_DEBUG_2 0x00400620 ++#define NV04_PGRAPH_BOFFSET0 0x00400640 ++#define NV04_PGRAPH_BOFFSET1 0x00400644 ++#define NV04_PGRAPH_BOFFSET2 0x00400648 ++#define NV04_PGRAPH_BOFFSET3 0x0040064C ++#define NV04_PGRAPH_BOFFSET4 0x00400650 ++#define NV04_PGRAPH_BOFFSET5 0x00400654 ++#define NV04_PGRAPH_BBASE0 0x00400658 ++#define NV04_PGRAPH_BBASE1 0x0040065C ++#define NV04_PGRAPH_BBASE2 0x00400660 ++#define NV04_PGRAPH_BBASE3 0x00400664 ++#define NV04_PGRAPH_BBASE4 0x00400668 ++#define NV04_PGRAPH_BBASE5 0x0040066C ++#define NV04_PGRAPH_BPITCH0 0x00400670 ++#define NV04_PGRAPH_BPITCH1 0x00400674 ++#define NV04_PGRAPH_BPITCH2 0x00400678 ++#define NV04_PGRAPH_BPITCH3 0x0040067C ++#define NV04_PGRAPH_BPITCH4 0x00400680 ++#define NV04_PGRAPH_BLIMIT0 0x00400684 ++#define NV04_PGRAPH_BLIMIT1 0x00400688 ++#define NV04_PGRAPH_BLIMIT2 0x0040068C ++#define NV04_PGRAPH_BLIMIT3 0x00400690 ++#define NV04_PGRAPH_BLIMIT4 0x00400694 ++#define NV04_PGRAPH_BLIMIT5 0x00400698 ++#define NV04_PGRAPH_BSWIZZLE2 0x0040069C ++#define NV04_PGRAPH_BSWIZZLE5 0x004006A0 ++#define NV03_PGRAPH_STATUS 0x004006B0 ++#define NV04_PGRAPH_STATUS 0x00400700 ++#define NV04_PGRAPH_TRAPPED_ADDR 0x00400704 ++#define NV04_PGRAPH_TRAPPED_DATA 0x00400708 ++#define NV04_PGRAPH_SURFACE 0x0040070C ++#define NV10_PGRAPH_TRAPPED_DATA_HIGH 0x0040070C ++#define NV04_PGRAPH_STATE 0x00400710 ++#define NV10_PGRAPH_SURFACE 0x00400710 ++#define NV04_PGRAPH_NOTIFY 0x00400714 ++#define NV10_PGRAPH_STATE 0x00400714 ++#define NV10_PGRAPH_NOTIFY 0x00400718 ++ ++#define NV04_PGRAPH_FIFO 0x00400720 ++ ++#define NV04_PGRAPH_BPIXEL 0x00400724 ++#define NV10_PGRAPH_RDI_INDEX 0x00400750 ++#define NV04_PGRAPH_FFINTFC_ST2 0x00400754 ++#define NV10_PGRAPH_RDI_DATA 0x00400754 ++#define NV04_PGRAPH_DMA_PITCH 0x00400760 ++#define NV10_PGRAPH_FFINTFC_ST2 0x00400764 ++#define NV04_PGRAPH_DVD_COLORFMT 0x00400764 ++#define NV04_PGRAPH_SCALED_FORMAT 0x00400768 ++#define NV10_PGRAPH_DMA_PITCH 0x00400770 ++#define NV10_PGRAPH_DVD_COLORFMT 0x00400774 ++#define NV10_PGRAPH_SCALED_FORMAT 0x00400778 ++#define NV20_PGRAPH_CHANNEL_CTX_TABLE 0x00400780 ++#define NV20_PGRAPH_CHANNEL_CTX_POINTER 0x00400784 ++#define NV20_PGRAPH_CHANNEL_CTX_XFER 0x00400788 ++#define NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD 0x00000001 ++#define NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE 0x00000002 ++#define NV04_PGRAPH_PATT_COLOR0 0x00400800 ++#define NV04_PGRAPH_PATT_COLOR1 0x00400804 ++#define NV04_PGRAPH_PATTERN 0x00400808 ++#define NV04_PGRAPH_PATTERN_SHAPE 0x00400810 ++#define NV04_PGRAPH_CHROMA 0x00400814 ++#define NV04_PGRAPH_CONTROL0 0x00400818 ++#define NV04_PGRAPH_CONTROL1 0x0040081C ++#define NV04_PGRAPH_CONTROL2 0x00400820 ++#define NV04_PGRAPH_BLEND 0x00400824 ++#define NV04_PGRAPH_STORED_FMT 0x00400830 ++#define NV04_PGRAPH_PATT_COLORRAM 0x00400900 ++#define NV40_PGRAPH_TILE0(i) (0x00400900 + (i*16)) ++#define NV40_PGRAPH_TLIMIT0(i) (0x00400904 + (i*16)) ++#define NV40_PGRAPH_TSIZE0(i) (0x00400908 + (i*16)) ++#define NV40_PGRAPH_TSTATUS0(i) (0x0040090C + (i*16)) ++#define NV10_PGRAPH_TILE(i) (0x00400B00 + (i*16)) ++#define NV10_PGRAPH_TLIMIT(i) (0x00400B04 + (i*16)) ++#define NV10_PGRAPH_TSIZE(i) (0x00400B08 + (i*16)) ++#define NV10_PGRAPH_TSTATUS(i) (0x00400B0C + (i*16)) ++#define NV04_PGRAPH_U_RAM 0x00400D00 ++#define NV47_PGRAPH_TILE0(i) (0x00400D00 + (i*16)) ++#define NV47_PGRAPH_TLIMIT0(i) (0x00400D04 + (i*16)) ++#define NV47_PGRAPH_TSIZE0(i) (0x00400D08 + (i*16)) ++#define NV47_PGRAPH_TSTATUS0(i) (0x00400D0C + (i*16)) ++#define NV04_PGRAPH_V_RAM 0x00400D40 ++#define NV04_PGRAPH_W_RAM 0x00400D80 ++#define NV10_PGRAPH_COMBINER0_IN_ALPHA 0x00400E40 ++#define NV10_PGRAPH_COMBINER1_IN_ALPHA 0x00400E44 ++#define NV10_PGRAPH_COMBINER0_IN_RGB 0x00400E48 ++#define NV10_PGRAPH_COMBINER1_IN_RGB 0x00400E4C ++#define NV10_PGRAPH_COMBINER_COLOR0 0x00400E50 ++#define NV10_PGRAPH_COMBINER_COLOR1 0x00400E54 ++#define NV10_PGRAPH_COMBINER0_OUT_ALPHA 0x00400E58 ++#define NV10_PGRAPH_COMBINER1_OUT_ALPHA 0x00400E5C ++#define NV10_PGRAPH_COMBINER0_OUT_RGB 0x00400E60 ++#define NV10_PGRAPH_COMBINER1_OUT_RGB 0x00400E64 ++#define NV10_PGRAPH_COMBINER_FINAL0 0x00400E68 ++#define NV10_PGRAPH_COMBINER_FINAL1 0x00400E6C ++#define NV10_PGRAPH_WINDOWCLIP_HORIZONTAL 0x00400F00 ++#define NV10_PGRAPH_WINDOWCLIP_VERTICAL 0x00400F20 ++#define NV10_PGRAPH_XFMODE0 0x00400F40 ++#define NV10_PGRAPH_XFMODE1 0x00400F44 ++#define NV10_PGRAPH_GLOBALSTATE0 0x00400F48 ++#define NV10_PGRAPH_GLOBALSTATE1 0x00400F4C ++#define NV10_PGRAPH_PIPE_ADDRESS 0x00400F50 ++#define NV10_PGRAPH_PIPE_DATA 0x00400F54 ++#define NV04_PGRAPH_DMA_START_0 0x00401000 ++#define NV04_PGRAPH_DMA_START_1 0x00401004 ++#define NV04_PGRAPH_DMA_LENGTH 0x00401008 ++#define NV04_PGRAPH_DMA_MISC 0x0040100C ++#define NV04_PGRAPH_DMA_DATA_0 0x00401020 ++#define NV04_PGRAPH_DMA_DATA_1 0x00401024 ++#define NV04_PGRAPH_DMA_RM 0x00401030 ++#define NV04_PGRAPH_DMA_A_XLATE_INST 0x00401040 ++#define NV04_PGRAPH_DMA_A_CONTROL 0x00401044 ++#define NV04_PGRAPH_DMA_A_LIMIT 0x00401048 ++#define NV04_PGRAPH_DMA_A_TLB_PTE 0x0040104C ++#define NV04_PGRAPH_DMA_A_TLB_TAG 0x00401050 ++#define NV04_PGRAPH_DMA_A_ADJ_OFFSET 0x00401054 ++#define NV04_PGRAPH_DMA_A_OFFSET 0x00401058 ++#define NV04_PGRAPH_DMA_A_SIZE 0x0040105C ++#define NV04_PGRAPH_DMA_A_Y_SIZE 0x00401060 ++#define NV04_PGRAPH_DMA_B_XLATE_INST 0x00401080 ++#define NV04_PGRAPH_DMA_B_CONTROL 0x00401084 ++#define NV04_PGRAPH_DMA_B_LIMIT 0x00401088 ++#define NV04_PGRAPH_DMA_B_TLB_PTE 0x0040108C ++#define NV04_PGRAPH_DMA_B_TLB_TAG 0x00401090 ++#define NV04_PGRAPH_DMA_B_ADJ_OFFSET 0x00401094 ++#define NV04_PGRAPH_DMA_B_OFFSET 0x00401098 ++#define NV04_PGRAPH_DMA_B_SIZE 0x0040109C ++#define NV04_PGRAPH_DMA_B_Y_SIZE 0x004010A0 ++#define NV40_PGRAPH_TILE1(i) (0x00406900 + (i*16)) ++#define NV40_PGRAPH_TLIMIT1(i) (0x00406904 + (i*16)) ++#define NV40_PGRAPH_TSIZE1(i) (0x00406908 + (i*16)) ++#define NV40_PGRAPH_TSTATUS1(i) (0x0040690C + (i*16)) ++ ++ ++/* It's a guess that this works on NV03. Confirmed on NV04, though */ ++#define NV04_PFIFO_DELAY_0 0x00002040 ++#define NV04_PFIFO_DMA_TIMESLICE 0x00002044 ++#define NV04_PFIFO_NEXT_CHANNEL 0x00002050 ++#define NV03_PFIFO_INTR_0 0x00002100 ++#define NV03_PFIFO_INTR_EN_0 0x00002140 ++# define NV_PFIFO_INTR_CACHE_ERROR (1<<0) ++# define NV_PFIFO_INTR_RUNOUT (1<<4) ++# define NV_PFIFO_INTR_RUNOUT_OVERFLOW (1<<8) ++# define NV_PFIFO_INTR_DMA_PUSHER (1<<12) ++# define NV_PFIFO_INTR_DMA_PT (1<<16) ++# define NV_PFIFO_INTR_SEMAPHORE (1<<20) ++# define NV_PFIFO_INTR_ACQUIRE_TIMEOUT (1<<24) ++#define NV03_PFIFO_RAMHT 0x00002210 ++#define NV03_PFIFO_RAMFC 0x00002214 ++#define NV03_PFIFO_RAMRO 0x00002218 ++#define NV40_PFIFO_RAMFC 0x00002220 ++#define NV03_PFIFO_CACHES 0x00002500 ++#define NV04_PFIFO_MODE 0x00002504 ++#define NV04_PFIFO_DMA 0x00002508 ++#define NV04_PFIFO_SIZE 0x0000250c ++#define NV50_PFIFO_CTX_TABLE(c) (0x2600+(c)*4) ++#define NV50_PFIFO_CTX_TABLE__SIZE 128 ++#define NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED (1<<31) ++#define NV50_PFIFO_CTX_TABLE_UNK30_BAD (1<<30) ++#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80 0x0FFFFFFF ++#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84 0x00FFFFFF ++#define NV03_PFIFO_CACHE0_PUSH0 0x00003000 ++#define NV03_PFIFO_CACHE0_PULL0 0x00003040 ++#define NV04_PFIFO_CACHE0_PULL0 0x00003050 ++#define NV04_PFIFO_CACHE0_PULL1 0x00003054 ++#define NV03_PFIFO_CACHE1_PUSH0 0x00003200 ++#define NV03_PFIFO_CACHE1_PUSH1 0x00003204 ++#define NV03_PFIFO_CACHE1_PUSH1_DMA (1<<8) ++#define NV40_PFIFO_CACHE1_PUSH1_DMA (1<<16) ++#define NV03_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000000f ++#define NV10_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000001f ++#define NV50_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000007f ++#define NV03_PFIFO_CACHE1_PUT 0x00003210 ++#define NV04_PFIFO_CACHE1_DMA_PUSH 0x00003220 ++#define NV04_PFIFO_CACHE1_DMA_FETCH 0x00003224 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES 0x00000000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES 0x00000008 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES 0x00000010 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES 0x00000018 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES 0x00000020 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES 0x00000028 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES 0x00000030 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES 0x00000038 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES 0x00000040 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES 0x00000048 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES 0x00000050 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES 0x00000058 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES 0x00000060 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES 0x00000068 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES 0x00000070 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES 0x00000078 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES 0x00000080 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES 0x00000088 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES 0x00000090 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES 0x00000098 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES 0x000000A0 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES 0x000000A8 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES 0x000000B0 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES 0x000000B8 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES 0x000000C0 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES 0x000000C8 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES 0x000000D0 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES 0x000000D8 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES 0x000000E0 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES 0x000000E8 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES 0x000000F0 ++# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES 0x000000F8 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE 0x0000E000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES 0x00000000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES 0x00002000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES 0x00004000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES 0x00006000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES 0x00008000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES 0x0000A000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES 0x0000C000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES 0x0000E000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS 0x001F0000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_0 0x00000000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_1 0x00010000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_2 0x00020000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_3 0x00030000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 0x00040000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_5 0x00050000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_6 0x00060000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_7 0x00070000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 0x00080000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_9 0x00090000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_10 0x000A0000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_11 0x000B0000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_12 0x000C0000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_13 0x000D0000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_14 0x000E0000 ++# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15 0x000F0000 ++# define NV_PFIFO_CACHE1_ENDIAN 0x80000000 ++# define NV_PFIFO_CACHE1_LITTLE_ENDIAN 0x7FFFFFFF ++# define NV_PFIFO_CACHE1_BIG_ENDIAN 0x80000000 ++#define NV04_PFIFO_CACHE1_DMA_STATE 0x00003228 ++#define NV04_PFIFO_CACHE1_DMA_INSTANCE 0x0000322c ++#define NV04_PFIFO_CACHE1_DMA_CTL 0x00003230 ++#define NV04_PFIFO_CACHE1_DMA_PUT 0x00003240 ++#define NV04_PFIFO_CACHE1_DMA_GET 0x00003244 ++#define NV10_PFIFO_CACHE1_REF_CNT 0x00003248 ++#define NV10_PFIFO_CACHE1_DMA_SUBROUTINE 0x0000324C ++#define NV03_PFIFO_CACHE1_PULL0 0x00003240 ++#define NV04_PFIFO_CACHE1_PULL0 0x00003250 ++#define NV03_PFIFO_CACHE1_PULL1 0x00003250 ++#define NV04_PFIFO_CACHE1_PULL1 0x00003254 ++#define NV04_PFIFO_CACHE1_HASH 0x00003258 ++#define NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT 0x00003260 ++#define NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP 0x00003264 ++#define NV10_PFIFO_CACHE1_ACQUIRE_VALUE 0x00003268 ++#define NV10_PFIFO_CACHE1_SEMAPHORE 0x0000326C ++#define NV03_PFIFO_CACHE1_GET 0x00003270 ++#define NV04_PFIFO_CACHE1_ENGINE 0x00003280 ++#define NV04_PFIFO_CACHE1_DMA_DCOUNT 0x000032A0 ++#define NV40_PFIFO_GRCTX_INSTANCE 0x000032E0 ++#define NV40_PFIFO_UNK32E4 0x000032E4 ++#define NV04_PFIFO_CACHE1_METHOD(i) (0x00003800+(i*8)) ++#define NV04_PFIFO_CACHE1_DATA(i) (0x00003804+(i*8)) ++#define NV40_PFIFO_CACHE1_METHOD(i) (0x00090000+(i*8)) ++#define NV40_PFIFO_CACHE1_DATA(i) (0x00090004+(i*8)) ++ ++#define NV_CRTC0_INTSTAT 0x00600100 ++#define NV_CRTC0_INTEN 0x00600140 ++#define NV_CRTC1_INTSTAT 0x00602100 ++#define NV_CRTC1_INTEN 0x00602140 ++# define NV_CRTC_INTR_VBLANK (1<<0) ++ ++#define NV04_PRAMIN 0x00700000 ++ ++/* Fifo commands. These are not regs, neither masks */ ++#define NV03_FIFO_CMD_JUMP 0x20000000 ++#define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc ++#define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK)) ++ ++/* This is a partial import from rules-ng, a few things may be duplicated. ++ * Eventually we should completely import everything from rules-ng. ++ * For the moment check rules-ng for docs. ++ */ ++ ++#define NV50_PMC 0x00000000 ++#define NV50_PMC__LEN 0x1 ++#define NV50_PMC__ESIZE 0x2000 ++# define NV50_PMC_BOOT_0 0x00000000 ++# define NV50_PMC_BOOT_0_REVISION 0x000000ff ++# define NV50_PMC_BOOT_0_REVISION__SHIFT 0 ++# define NV50_PMC_BOOT_0_ARCH 0x0ff00000 ++# define NV50_PMC_BOOT_0_ARCH__SHIFT 20 ++# define NV50_PMC_INTR_0 0x00000100 ++# define NV50_PMC_INTR_0_PFIFO (1<<8) ++# define NV50_PMC_INTR_0_PGRAPH (1<<12) ++# define NV50_PMC_INTR_0_PTIMER (1<<20) ++# define NV50_PMC_INTR_0_HOTPLUG (1<<21) ++# define NV50_PMC_INTR_0_DISPLAY (1<<26) ++# define NV50_PMC_INTR_EN_0 0x00000140 ++# define NV50_PMC_INTR_EN_0_MASTER (1<<0) ++# define NV50_PMC_INTR_EN_0_MASTER_DISABLED (0<<0) ++# define NV50_PMC_INTR_EN_0_MASTER_ENABLED (1<<0) ++# define NV50_PMC_ENABLE 0x00000200 ++# define NV50_PMC_ENABLE_PFIFO (1<<8) ++# define NV50_PMC_ENABLE_PGRAPH (1<<12) ++ ++#define NV50_PCONNECTOR 0x0000e000 ++#define NV50_PCONNECTOR__LEN 0x1 ++#define NV50_PCONNECTOR__ESIZE 0x1000 ++# define NV50_PCONNECTOR_HOTPLUG_INTR 0x0000e050 ++# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C0 (1<<0) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C1 (1<<1) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C2 (1<<2) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C3 (1<<3) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C0 (1<<16) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C1 (1<<17) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C2 (1<<18) ++# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C3 (1<<19) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL 0x0000e054 ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C0 (1<<0) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C1 (1<<1) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C2 (1<<2) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C3 (1<<3) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C0 (1<<16) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C1 (1<<17) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C2 (1<<18) ++# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C3 (1<<19) ++# define NV50_PCONNECTOR_HOTPLUG_STATE 0x0000e104 ++# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C0 (1<<2) ++# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C1 (1<<6) ++# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C2 (1<<10) ++# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C3 (1<<14) ++# 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 ++ ++#define NV50_PBUS 0x00088000 ++#define NV50_PBUS__LEN 0x1 ++#define NV50_PBUS__ESIZE 0x1000 ++# define NV50_PBUS_PCI_ID 0x00088000 ++# define NV50_PBUS_PCI_ID_VENDOR_ID 0x0000ffff ++# define NV50_PBUS_PCI_ID_VENDOR_ID__SHIFT 0 ++# define NV50_PBUS_PCI_ID_DEVICE_ID 0xffff0000 ++# define NV50_PBUS_PCI_ID_DEVICE_ID__SHIFT 16 ++ ++#define NV50_PFB 0x00100000 ++#define NV50_PFB__LEN 0x1 ++#define NV50_PFB__ESIZE 0x1000 ++ ++#define NV50_PEXTDEV 0x00101000 ++#define NV50_PEXTDEV__LEN 0x1 ++#define NV50_PEXTDEV__ESIZE 0x1000 ++ ++#define NV50_PROM 0x00300000 ++#define NV50_PROM__LEN 0x1 ++#define NV50_PROM__ESIZE 0x10000 ++ ++#define NV50_PGRAPH 0x00400000 ++#define NV50_PGRAPH__LEN 0x1 ++#define NV50_PGRAPH__ESIZE 0x10000 ++ ++#define NV50_PDISPLAY 0x00610000 ++#define NV50_PDISPLAY_OBJECTS 0x00610010 ++#define NV50_PDISPLAY_INTR_0 0x00610020 ++#define NV50_PDISPLAY_INTR_1 0x00610024 ++#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC 0x0000000c ++#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_SHIFT 2 ++#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(n) (1 << ((n) + 2)) ++#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_0 0x00000004 ++#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1 0x00000008 ++#define NV50_PDISPLAY_INTR_1_CLK_UNK10 0x00000010 ++#define NV50_PDISPLAY_INTR_1_CLK_UNK20 0x00000020 ++#define NV50_PDISPLAY_INTR_1_CLK_UNK40 0x00000040 ++#define NV50_PDISPLAY_INTR_EN 0x0061002c ++#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC 0x0000000c ++#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(n) (1 << ((n) + 2)) ++#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_0 0x00000004 ++#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_1 0x00000008 ++#define NV50_PDISPLAY_INTR_EN_CLK_UNK10 0x00000010 ++#define NV50_PDISPLAY_INTR_EN_CLK_UNK20 0x00000020 ++#define NV50_PDISPLAY_INTR_EN_CLK_UNK40 0x00000040 ++#define NV50_PDISPLAY_UNK30_CTRL 0x00610030 ++#define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK0 0x00000200 ++#define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1 0x00000400 ++#define NV50_PDISPLAY_UNK30_CTRL_PENDING 0x80000000 ++#define NV50_PDISPLAY_TRAPPED_ADDR 0x00610080 ++#define NV50_PDISPLAY_TRAPPED_DATA 0x00610084 ++#define NV50_PDISPLAY_CHANNEL_STAT(i) ((i) * 0x10 + 0x00610200) ++#define NV50_PDISPLAY_CHANNEL_STAT_DMA 0x00000010 ++#define NV50_PDISPLAY_CHANNEL_STAT_DMA_DISABLED 0x00000000 ++#define NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED 0x00000010 ++#define NV50_PDISPLAY_CHANNEL_DMA_CB(i) ((i) * 0x10 + 0x00610204) ++#define NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION 0x00000002 ++#define NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_VRAM 0x00000000 ++#define NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_SYSTEM 0x00000002 ++#define NV50_PDISPLAY_CHANNEL_DMA_CB_VALID 0x00000001 ++#define NV50_PDISPLAY_CHANNEL_UNK2(i) ((i) * 0x10 + 0x00610208) ++#define NV50_PDISPLAY_CHANNEL_UNK3(i) ((i) * 0x10 + 0x0061020c) ++ ++#define NV50_PDISPLAY_CURSOR 0x00610270 ++#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i) ((i) * 0x10 + 0x00610270) ++#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON 0x00000001 ++#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS 0x00030000 ++#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE 0x00010000 ++ ++#define NV50_PDISPLAY_CTRL_STATE 0x00610300 ++#define NV50_PDISPLAY_CTRL_STATE_PENDING 0x80000000 ++#define NV50_PDISPLAY_CTRL_STATE_METHOD 0x00001ffc ++#define NV50_PDISPLAY_CTRL_STATE_ENABLE 0x00000001 ++#define NV50_PDISPLAY_CTRL_VAL 0x00610304 ++#define NV50_PDISPLAY_UNK_380 0x00610380 ++#define NV50_PDISPLAY_RAM_AMOUNT 0x00610384 ++#define NV50_PDISPLAY_UNK_388 0x00610388 ++#define NV50_PDISPLAY_UNK_38C 0x0061038c ++ ++#define NV50_PDISPLAY_CRTC_P(i, r) ((i) * 0x540 + NV50_PDISPLAY_CRTC_##r) ++#define NV50_PDISPLAY_CRTC_C(i, r) (4 + (i) * 0x540 + NV50_PDISPLAY_CRTC_##r) ++#define NV50_PDISPLAY_CRTC_UNK_0A18 /* mthd 0x0900 */ 0x00610a18 ++#define NV50_PDISPLAY_CRTC_CLUT_MODE 0x00610a24 ++#define NV50_PDISPLAY_CRTC_INTERLACE 0x00610a48 ++#define NV50_PDISPLAY_CRTC_SCALE_CTRL 0x00610a50 ++#define NV50_PDISPLAY_CRTC_CURSOR_CTRL 0x00610a58 ++#define NV50_PDISPLAY_CRTC_UNK0A78 /* mthd 0x0904 */ 0x00610a78 ++#define NV50_PDISPLAY_CRTC_UNK0AB8 0x00610ab8 ++#define NV50_PDISPLAY_CRTC_DEPTH 0x00610ac8 ++#define NV50_PDISPLAY_CRTC_CLOCK 0x00610ad0 ++#define NV50_PDISPLAY_CRTC_COLOR_CTRL 0x00610ae0 ++#define NV50_PDISPLAY_CRTC_SYNC_START_TO_BLANK_END 0x00610ae8 ++#define NV50_PDISPLAY_CRTC_MODE_UNK1 0x00610af0 ++#define NV50_PDISPLAY_CRTC_DISPLAY_TOTAL 0x00610af8 ++#define NV50_PDISPLAY_CRTC_SYNC_DURATION 0x00610b00 ++#define NV50_PDISPLAY_CRTC_MODE_UNK2 0x00610b08 ++#define NV50_PDISPLAY_CRTC_UNK_0B10 /* mthd 0x0828 */ 0x00610b10 ++#define NV50_PDISPLAY_CRTC_FB_SIZE 0x00610b18 ++#define NV50_PDISPLAY_CRTC_FB_PITCH 0x00610b20 ++#define NV50_PDISPLAY_CRTC_FB_PITCH_LINEAR 0x00100000 ++#define NV50_PDISPLAY_CRTC_FB_POS 0x00610b28 ++#define NV50_PDISPLAY_CRTC_SCALE_CENTER_OFFSET 0x00610b38 ++#define NV50_PDISPLAY_CRTC_REAL_RES 0x00610b40 ++#define NV50_PDISPLAY_CRTC_SCALE_RES1 0x00610b48 ++#define NV50_PDISPLAY_CRTC_SCALE_RES2 0x00610b50 ++ ++#define NV50_PDISPLAY_DAC_MODE_CTRL_P(i) (0x00610b58 + (i) * 0x8) ++#define NV50_PDISPLAY_DAC_MODE_CTRL_C(i) (0x00610b5c + (i) * 0x8) ++#define NV50_PDISPLAY_SOR_MODE_CTRL_P(i) (0x00610b70 + (i) * 0x8) ++#define NV50_PDISPLAY_SOR_MODE_CTRL_C(i) (0x00610b74 + (i) * 0x8) ++#define NV50_PDISPLAY_DAC_MODE_CTRL2_P(i) (0x00610bdc + (i) * 0x8) ++#define NV50_PDISPLAY_DAC_MODE_CTRL2_C(i) (0x00610be0 + (i) * 0x8) ++ ++#define NV90_PDISPLAY_SOR_MODE_CTRL_P(i) (0x00610794 + (i) * 0x8) ++#define NV90_PDISPLAY_SOR_MODE_CTRL_C(i) (0x00610798 + (i) * 0x8) ++#define NV90_PDISPLAY_DAC_MODE_CTRL_P(i) (0x00610b58 + (i) * 0x8) ++#define NV90_PDISPLAY_DAC_MODE_CTRL_C(i) (0x00610b5c + (i) * 0x8) ++#define NV90_PDISPLAY_DAC_MODE_CTRL2_P(i) (0x00610b80 + (i) * 0x8) ++#define NV90_PDISPLAY_DAC_MODE_CTRL2_C(i) (0x00610b84 + (i) * 0x8) ++ ++#define NV50_PDISPLAY_CRTC_CLK 0x00614000 ++#define NV50_PDISPLAY_CRTC_CLK_CTRL1(i) ((i) * 0x800 + 0x614100) ++#define NV50_PDISPLAY_CRTC_CLK_CTRL1_CONNECTED 0x00000600 ++#define NV50_PDISPLAY_CRTC_CLK_VPLL_A(i) ((i) * 0x800 + 0x614104) ++#define NV50_PDISPLAY_CRTC_CLK_VPLL_B(i) ((i) * 0x800 + 0x614108) ++#define NV50_PDISPLAY_CRTC_CLK_CTRL2(i) ((i) * 0x800 + 0x614200) ++ ++#define NV50_PDISPLAY_DAC_CLK 0x00614000 ++#define NV50_PDISPLAY_DAC_CLK_CTRL2(i) ((i) * 0x800 + 0x614280) ++ ++#define NV50_PDISPLAY_SOR_CLK 0x00614000 ++#define NV50_PDISPLAY_SOR_CLK_CTRL2(i) ((i) * 0x800 + 0x614300) ++ ++#define NV50_PDISPLAY_VGACRTC(r) ((r) + 0x619400) ++ ++#define NV50_PDISPLAY_DAC 0x0061a000 ++#define NV50_PDISPLAY_DAC_DPMS_CTRL(i) (0x0061a004 + (i) * 0x800) ++#define NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF 0x00000001 ++#define NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF 0x00000004 ++#define NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED 0x00000010 ++#define NV50_PDISPLAY_DAC_DPMS_CTRL_OFF 0x00000040 ++#define NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING 0x80000000 ++#define NV50_PDISPLAY_DAC_LOAD_CTRL(i) (0x0061a00c + (i) * 0x800) ++#define NV50_PDISPLAY_DAC_LOAD_CTRL_ACTIVE 0x00100000 ++#define NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT 0x38000000 ++#define NV50_PDISPLAY_DAC_LOAD_CTRL_DONE 0x80000000 ++#define NV50_PDISPLAY_DAC_CLK_CTRL1(i) (0x0061a010 + (i) * 0x800) ++#define NV50_PDISPLAY_DAC_CLK_CTRL1_CONNECTED 0x00000600 ++ ++#define NV50_PDISPLAY_SOR 0x0061c000 ++#define NV50_PDISPLAY_SOR_DPMS_CTRL(i) (0x0061c004 + (i) * 0x800) ++#define NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING 0x80000000 ++#define NV50_PDISPLAY_SOR_DPMS_CTRL_ON 0x00000001 ++#define NV50_PDISPLAY_SOR_CLK_CTRL1(i) (0x0061c008 + (i) * 0x800) ++#define NV50_PDISPLAY_SOR_CLK_CTRL1_CONNECTED 0x00000600 ++#define NV50_PDISPLAY_SOR_DPMS_STATE(i) (0x0061c030 + (i) * 0x800) ++#define NV50_PDISPLAY_SOR_DPMS_STATE_ACTIVE 0x00030000 ++#define NV50_PDISPLAY_SOR_DPMS_STATE_BLANKED 0x00080000 ++#define NV50_PDISPLAY_SOR_DPMS_STATE_WAIT 0x10000000 ++#define NV50_PDISPLAY_SOR_BACKLIGHT 0x0061c084 ++#define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000 ++#define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff ++ ++#define NV50_PDISPLAY_USER(i) ((i) * 0x1000 + 0x00640000) ++#define NV50_PDISPLAY_USER_PUT(i) ((i) * 0x1000 + 0x00640000) ++#define NV50_PDISPLAY_USER_GET(i) ((i) * 0x1000 + 0x00640004) ++ ++#define NV50_PDISPLAY_CURSOR_USER 0x00647000 ++#define NV50_PDISPLAY_CURSOR_USER_POS_CTRL(i) ((i) * 0x1000 + 0x00647080) ++#define NV50_PDISPLAY_CURSOR_USER_POS(i) ((i) * 0x1000 + 0x00647084) +diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c +new file mode 100644 +index 0000000..4c7f1e4 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c +@@ -0,0 +1,321 @@ ++#include "drmP.h" ++#include "nouveau_drv.h" ++#include ++ ++#define NV_CTXDMA_PAGE_SHIFT 12 ++#define NV_CTXDMA_PAGE_SIZE (1 << NV_CTXDMA_PAGE_SHIFT) ++#define NV_CTXDMA_PAGE_MASK (NV_CTXDMA_PAGE_SIZE - 1) ++ ++struct nouveau_sgdma_be { ++ struct ttm_backend backend; ++ struct drm_device *dev; ++ ++ dma_addr_t *pages; ++ unsigned nr_pages; ++ ++ unsigned pte_start; ++ bool bound; ++}; ++ ++static int ++nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages, ++ struct page **pages, struct page *dummy_read_page) ++{ ++ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; ++ struct drm_device *dev = nvbe->dev; ++ ++ NV_DEBUG(nvbe->dev, "num_pages = %ld\n", num_pages); ++ ++ if (nvbe->pages) ++ return -EINVAL; ++ ++ nvbe->pages = kmalloc(sizeof(dma_addr_t) * num_pages, GFP_KERNEL); ++ if (!nvbe->pages) ++ return -ENOMEM; ++ ++ nvbe->nr_pages = 0; ++ while (num_pages--) { ++ nvbe->pages[nvbe->nr_pages] = ++ pci_map_page(dev->pdev, pages[nvbe->nr_pages], 0, ++ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); ++ if (pci_dma_mapping_error(dev->pdev, ++ nvbe->pages[nvbe->nr_pages])) { ++ be->func->clear(be); ++ return -EFAULT; ++ } ++ ++ nvbe->nr_pages++; ++ } ++ ++ return 0; ++} ++ ++static void ++nouveau_sgdma_clear(struct ttm_backend *be) ++{ ++ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; ++ struct drm_device *dev = nvbe->dev; ++ ++ NV_DEBUG(nvbe->dev, "\n"); ++ ++ if (nvbe && nvbe->pages) { ++ if (nvbe->bound) ++ be->func->unbind(be); ++ ++ while (nvbe->nr_pages--) { ++ pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages], ++ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); ++ } ++ kfree(nvbe->pages); ++ nvbe->pages = NULL; ++ nvbe->nr_pages = 0; ++ } ++} ++ ++static inline unsigned ++nouveau_sgdma_pte(struct drm_device *dev, uint64_t offset) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ unsigned pte = (offset >> NV_CTXDMA_PAGE_SHIFT); ++ ++ if (dev_priv->card_type < NV_50) ++ return pte + 2; ++ ++ return pte << 1; ++} ++ ++static int ++nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) ++{ ++ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; ++ struct drm_device *dev = nvbe->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; ++ unsigned i, j, pte; ++ ++ NV_DEBUG(dev, "pg=0x%lx\n", mem->mm_node->start); ++ ++ dev_priv->engine.instmem.prepare_access(nvbe->dev, true); ++ pte = nouveau_sgdma_pte(nvbe->dev, mem->mm_node->start << PAGE_SHIFT); ++ nvbe->pte_start = pte; ++ for (i = 0; i < nvbe->nr_pages; i++) { ++ dma_addr_t dma_offset = nvbe->pages[i]; ++ uint32_t offset_l = lower_32_bits(dma_offset); ++ uint32_t offset_h = upper_32_bits(dma_offset); ++ ++ for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) { ++ if (dev_priv->card_type < NV_50) ++ nv_wo32(dev, gpuobj, pte++, offset_l | 3); ++ else { ++ nv_wo32(dev, gpuobj, pte++, offset_l | 0x21); ++ nv_wo32(dev, gpuobj, pte++, offset_h & 0xff); ++ } ++ ++ dma_offset += NV_CTXDMA_PAGE_SIZE; ++ } ++ } ++ dev_priv->engine.instmem.finish_access(nvbe->dev); ++ ++ if (dev_priv->card_type == NV_50) { ++ nv_wr32(dev, 0x100c80, 0x00050001); ++ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { ++ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); ++ NV_ERROR(dev, "0x100c80 = 0x%08x\n", ++ nv_rd32(dev, 0x100c80)); ++ return -EBUSY; ++ } ++ ++ nv_wr32(dev, 0x100c80, 0x00000001); ++ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { ++ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); ++ NV_ERROR(dev, "0x100c80 = 0x%08x\n", ++ nv_rd32(dev, 0x100c80)); ++ return -EBUSY; ++ } ++ } ++ ++ nvbe->bound = true; ++ return 0; ++} ++ ++static int ++nouveau_sgdma_unbind(struct ttm_backend *be) ++{ ++ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; ++ struct drm_device *dev = nvbe->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; ++ unsigned i, j, pte; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (!nvbe->bound) ++ return 0; ++ ++ dev_priv->engine.instmem.prepare_access(nvbe->dev, true); ++ pte = nvbe->pte_start; ++ for (i = 0; i < nvbe->nr_pages; i++) { ++ dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus; ++ ++ for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) { ++ if (dev_priv->card_type < NV_50) ++ nv_wo32(dev, gpuobj, pte++, dma_offset | 3); ++ else { ++ nv_wo32(dev, gpuobj, pte++, dma_offset | 0x21); ++ nv_wo32(dev, gpuobj, pte++, 0x00000000); ++ } ++ ++ dma_offset += NV_CTXDMA_PAGE_SIZE; ++ } ++ } ++ dev_priv->engine.instmem.finish_access(nvbe->dev); ++ ++ nvbe->bound = false; ++ return 0; ++} ++ ++static void ++nouveau_sgdma_destroy(struct ttm_backend *be) ++{ ++ struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; ++ ++ if (be) { ++ NV_DEBUG(nvbe->dev, "\n"); ++ ++ if (nvbe) { ++ if (nvbe->pages) ++ be->func->clear(be); ++ kfree(nvbe); ++ } ++ } ++} ++ ++static struct ttm_backend_func nouveau_sgdma_backend = { ++ .populate = nouveau_sgdma_populate, ++ .clear = nouveau_sgdma_clear, ++ .bind = nouveau_sgdma_bind, ++ .unbind = nouveau_sgdma_unbind, ++ .destroy = nouveau_sgdma_destroy ++}; ++ ++struct ttm_backend * ++nouveau_sgdma_init_ttm(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_sgdma_be *nvbe; ++ ++ if (!dev_priv->gart_info.sg_ctxdma) ++ return NULL; ++ ++ nvbe = kzalloc(sizeof(*nvbe), GFP_KERNEL); ++ if (!nvbe) ++ return NULL; ++ ++ nvbe->dev = dev; ++ ++ nvbe->backend.func = &nouveau_sgdma_backend; ++ ++ return &nvbe->backend; ++} ++ ++int ++nouveau_sgdma_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj = NULL; ++ uint32_t aper_size, obj_size; ++ int i, ret; ++ ++ if (dev_priv->card_type < NV_50) { ++ aper_size = (64 * 1024 * 1024); ++ obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4; ++ obj_size += 8; /* ctxdma header */ ++ } else { ++ /* 1 entire VM page table */ ++ aper_size = (512 * 1024 * 1024); ++ obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 8; ++ } ++ ++ ret = nouveau_gpuobj_new(dev, NULL, obj_size, 16, ++ NVOBJ_FLAG_ALLOW_NO_REFS | ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, &gpuobj); ++ if (ret) { ++ NV_ERROR(dev, "Error creating sgdma object: %d\n", ret); ++ return ret; ++ } ++ ++ dev_priv->gart_info.sg_dummy_page = ++ alloc_page(GFP_KERNEL|__GFP_DMA32); ++ set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags); ++ dev_priv->gart_info.sg_dummy_bus = ++ pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0, ++ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ if (dev_priv->card_type < NV_50) { ++ /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and ++ * confirmed to work on c51. Perhaps means NV_DMA_TARGET_PCIE ++ * on those cards? */ ++ nv_wo32(dev, gpuobj, 0, NV_CLASS_DMA_IN_MEMORY | ++ (1 << 12) /* PT present */ | ++ (0 << 13) /* PT *not* linear */ | ++ (NV_DMA_ACCESS_RW << 14) | ++ (NV_DMA_TARGET_PCI << 16)); ++ nv_wo32(dev, gpuobj, 1, aper_size - 1); ++ for (i = 2; i < 2 + (aper_size >> 12); i++) { ++ nv_wo32(dev, gpuobj, i, ++ dev_priv->gart_info.sg_dummy_bus | 3); ++ } ++ } else { ++ for (i = 0; i < obj_size; i += 8) { ++ nv_wo32(dev, gpuobj, (i+0)/4, ++ dev_priv->gart_info.sg_dummy_bus | 0x21); ++ nv_wo32(dev, gpuobj, (i+4)/4, 0); ++ } ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ dev_priv->gart_info.type = NOUVEAU_GART_SGDMA; ++ dev_priv->gart_info.aper_base = 0; ++ dev_priv->gart_info.aper_size = aper_size; ++ dev_priv->gart_info.sg_ctxdma = gpuobj; ++ return 0; ++} ++ ++void ++nouveau_sgdma_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->gart_info.sg_dummy_page) { ++ pci_unmap_page(dev->pdev, dev_priv->gart_info.sg_dummy_bus, ++ NV_CTXDMA_PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); ++ unlock_page(dev_priv->gart_info.sg_dummy_page); ++ __free_page(dev_priv->gart_info.sg_dummy_page); ++ dev_priv->gart_info.sg_dummy_page = NULL; ++ dev_priv->gart_info.sg_dummy_bus = 0; ++ } ++ ++ nouveau_gpuobj_del(dev, &dev_priv->gart_info.sg_ctxdma); ++} ++ ++int ++nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; ++ struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; ++ int pte; ++ ++ pte = (offset >> NV_CTXDMA_PAGE_SHIFT); ++ if (dev_priv->card_type < NV_50) { ++ instmem->prepare_access(dev, false); ++ *page = nv_ro32(dev, gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK; ++ instmem->finish_access(dev); ++ return 0; ++ } ++ ++ NV_ERROR(dev, "Unimplemented on NV50\n"); ++ return -EINVAL; ++} +diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c +new file mode 100644 +index 0000000..790630d +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_state.c +@@ -0,0 +1,872 @@ ++/* ++ * Copyright 2005 Stephane Marchesin ++ * Copyright 2008 Stuart Bennett ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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 ++ ++#include "drmP.h" ++#include "drm.h" ++#include "drm_sarea.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++#include "nv50_display.h" ++ ++static int nouveau_stub_init(struct drm_device *dev) { return 0; } ++static void nouveau_stub_takedown(struct drm_device *dev) {} ++ ++static int ++sfbhack_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_bo *nvbo = NULL; ++ uint32_t tile_flags = dev_priv->card_type == NV_50 ? 0x7000 : 0x0000; ++ int ret, size; ++ ++ if (dev_priv->sfb_gem) ++ return 0; ++ ++ size = nouveau_mem_fb_amount(dev); ++ if (size > drm_get_resource_len(dev, 1)) ++ size = drm_get_resource_len(dev, 1); ++ size >>= 1; ++ ++ ret = nouveau_gem_new(dev, dev_priv->channel, size, 0, TTM_PL_FLAG_VRAM, ++ 0, tile_flags, false, true, &nvbo); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM); ++ if (ret) { ++ nouveau_bo_ref(NULL, &nvbo); ++ return ret; ++ } ++ ++ dev_priv->sfb_gem = nvbo->gem; ++ return 0; ++} ++ ++static void ++sfbhack_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->sfb_gem) { ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(dev_priv->sfb_gem); ++ mutex_unlock(&dev->struct_mutex); ++ dev_priv->sfb_gem = NULL; ++ } ++} ++ ++static int nouveau_init_engine_ptrs(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ ++ switch (dev_priv->chipset & 0xf0) { ++ case 0x00: ++ engine->instmem.init = nv04_instmem_init; ++ engine->instmem.takedown = nv04_instmem_takedown; ++ engine->instmem.suspend = nv04_instmem_suspend; ++ engine->instmem.resume = nv04_instmem_resume; ++ engine->instmem.populate = nv04_instmem_populate; ++ engine->instmem.clear = nv04_instmem_clear; ++ engine->instmem.bind = nv04_instmem_bind; ++ engine->instmem.unbind = nv04_instmem_unbind; ++ engine->instmem.prepare_access = nv04_instmem_prepare_access; ++ engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->mc.init = nv04_mc_init; ++ engine->mc.takedown = nv04_mc_takedown; ++ engine->timer.init = nv04_timer_init; ++ engine->timer.read = nv04_timer_read; ++ engine->timer.takedown = nv04_timer_takedown; ++ engine->fb.init = nv04_fb_init; ++ engine->fb.takedown = nv04_fb_takedown; ++ engine->graph.grclass = nv04_graph_grclass; ++ engine->graph.init = nv04_graph_init; ++ engine->graph.takedown = nv04_graph_takedown; ++ engine->graph.fifo_access = nv04_graph_fifo_access; ++ engine->graph.channel = nv04_graph_channel; ++ engine->graph.create_context = nv04_graph_create_context; ++ engine->graph.destroy_context = nv04_graph_destroy_context; ++ engine->graph.load_context = nv04_graph_load_context; ++ engine->graph.unload_context = nv04_graph_unload_context; ++ engine->fifo.channels = 16; ++ engine->fifo.init = nv04_fifo_init; ++ engine->fifo.takedown = nouveau_stub_takedown; ++ engine->fifo.disable = nv04_fifo_disable; ++ engine->fifo.enable = nv04_fifo_enable; ++ engine->fifo.reassign = nv04_fifo_reassign; ++ engine->fifo.channel_id = nv04_fifo_channel_id; ++ engine->fifo.create_context = nv04_fifo_create_context; ++ engine->fifo.destroy_context = nv04_fifo_destroy_context; ++ engine->fifo.load_context = nv04_fifo_load_context; ++ engine->fifo.unload_context = nv04_fifo_unload_context; ++ break; ++ case 0x10: ++ engine->instmem.init = nv04_instmem_init; ++ engine->instmem.takedown = nv04_instmem_takedown; ++ engine->instmem.suspend = nv04_instmem_suspend; ++ engine->instmem.resume = nv04_instmem_resume; ++ engine->instmem.populate = nv04_instmem_populate; ++ engine->instmem.clear = nv04_instmem_clear; ++ engine->instmem.bind = nv04_instmem_bind; ++ engine->instmem.unbind = nv04_instmem_unbind; ++ engine->instmem.prepare_access = nv04_instmem_prepare_access; ++ engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->mc.init = nv04_mc_init; ++ engine->mc.takedown = nv04_mc_takedown; ++ engine->timer.init = nv04_timer_init; ++ engine->timer.read = nv04_timer_read; ++ engine->timer.takedown = nv04_timer_takedown; ++ engine->fb.init = nv10_fb_init; ++ engine->fb.takedown = nv10_fb_takedown; ++ engine->graph.grclass = nv10_graph_grclass; ++ engine->graph.init = nv10_graph_init; ++ engine->graph.takedown = nv10_graph_takedown; ++ engine->graph.channel = nv10_graph_channel; ++ engine->graph.create_context = nv10_graph_create_context; ++ engine->graph.destroy_context = nv10_graph_destroy_context; ++ engine->graph.fifo_access = nv04_graph_fifo_access; ++ engine->graph.load_context = nv10_graph_load_context; ++ engine->graph.unload_context = nv10_graph_unload_context; ++ engine->fifo.channels = 32; ++ engine->fifo.init = nv10_fifo_init; ++ engine->fifo.takedown = nouveau_stub_takedown; ++ engine->fifo.disable = nv04_fifo_disable; ++ engine->fifo.enable = nv04_fifo_enable; ++ engine->fifo.reassign = nv04_fifo_reassign; ++ engine->fifo.channel_id = nv10_fifo_channel_id; ++ engine->fifo.create_context = nv10_fifo_create_context; ++ engine->fifo.destroy_context = nv10_fifo_destroy_context; ++ engine->fifo.load_context = nv10_fifo_load_context; ++ engine->fifo.unload_context = nv10_fifo_unload_context; ++ break; ++ case 0x20: ++ engine->instmem.init = nv04_instmem_init; ++ engine->instmem.takedown = nv04_instmem_takedown; ++ engine->instmem.suspend = nv04_instmem_suspend; ++ engine->instmem.resume = nv04_instmem_resume; ++ engine->instmem.populate = nv04_instmem_populate; ++ engine->instmem.clear = nv04_instmem_clear; ++ engine->instmem.bind = nv04_instmem_bind; ++ engine->instmem.unbind = nv04_instmem_unbind; ++ engine->instmem.prepare_access = nv04_instmem_prepare_access; ++ engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->mc.init = nv04_mc_init; ++ engine->mc.takedown = nv04_mc_takedown; ++ engine->timer.init = nv04_timer_init; ++ engine->timer.read = nv04_timer_read; ++ engine->timer.takedown = nv04_timer_takedown; ++ engine->fb.init = nv10_fb_init; ++ engine->fb.takedown = nv10_fb_takedown; ++ engine->graph.grclass = nv20_graph_grclass; ++ engine->graph.init = nv20_graph_init; ++ engine->graph.takedown = nv20_graph_takedown; ++ engine->graph.channel = nv10_graph_channel; ++ engine->graph.create_context = nv20_graph_create_context; ++ engine->graph.destroy_context = nv20_graph_destroy_context; ++ engine->graph.fifo_access = nv04_graph_fifo_access; ++ engine->graph.load_context = nv20_graph_load_context; ++ engine->graph.unload_context = nv20_graph_unload_context; ++ engine->fifo.channels = 32; ++ engine->fifo.init = nv10_fifo_init; ++ engine->fifo.takedown = nouveau_stub_takedown; ++ engine->fifo.disable = nv04_fifo_disable; ++ engine->fifo.enable = nv04_fifo_enable; ++ engine->fifo.reassign = nv04_fifo_reassign; ++ engine->fifo.channel_id = nv10_fifo_channel_id; ++ engine->fifo.create_context = nv10_fifo_create_context; ++ engine->fifo.destroy_context = nv10_fifo_destroy_context; ++ engine->fifo.load_context = nv10_fifo_load_context; ++ engine->fifo.unload_context = nv10_fifo_unload_context; ++ break; ++ case 0x30: ++ engine->instmem.init = nv04_instmem_init; ++ engine->instmem.takedown = nv04_instmem_takedown; ++ engine->instmem.suspend = nv04_instmem_suspend; ++ engine->instmem.resume = nv04_instmem_resume; ++ engine->instmem.populate = nv04_instmem_populate; ++ engine->instmem.clear = nv04_instmem_clear; ++ engine->instmem.bind = nv04_instmem_bind; ++ engine->instmem.unbind = nv04_instmem_unbind; ++ engine->instmem.prepare_access = nv04_instmem_prepare_access; ++ engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->mc.init = nv04_mc_init; ++ engine->mc.takedown = nv04_mc_takedown; ++ engine->timer.init = nv04_timer_init; ++ engine->timer.read = nv04_timer_read; ++ engine->timer.takedown = nv04_timer_takedown; ++ engine->fb.init = nv10_fb_init; ++ engine->fb.takedown = nv10_fb_takedown; ++ engine->graph.grclass = nv30_graph_grclass; ++ engine->graph.init = nv30_graph_init; ++ engine->graph.takedown = nv20_graph_takedown; ++ engine->graph.fifo_access = nv04_graph_fifo_access; ++ engine->graph.channel = nv10_graph_channel; ++ engine->graph.create_context = nv20_graph_create_context; ++ engine->graph.destroy_context = nv20_graph_destroy_context; ++ engine->graph.load_context = nv20_graph_load_context; ++ engine->graph.unload_context = nv20_graph_unload_context; ++ engine->fifo.channels = 32; ++ engine->fifo.init = nv10_fifo_init; ++ engine->fifo.takedown = nouveau_stub_takedown; ++ engine->fifo.disable = nv04_fifo_disable; ++ engine->fifo.enable = nv04_fifo_enable; ++ engine->fifo.reassign = nv04_fifo_reassign; ++ engine->fifo.channel_id = nv10_fifo_channel_id; ++ engine->fifo.create_context = nv10_fifo_create_context; ++ engine->fifo.destroy_context = nv10_fifo_destroy_context; ++ engine->fifo.load_context = nv10_fifo_load_context; ++ engine->fifo.unload_context = nv10_fifo_unload_context; ++ break; ++ case 0x40: ++ case 0x60: ++ engine->instmem.init = nv04_instmem_init; ++ engine->instmem.takedown = nv04_instmem_takedown; ++ engine->instmem.suspend = nv04_instmem_suspend; ++ engine->instmem.resume = nv04_instmem_resume; ++ engine->instmem.populate = nv04_instmem_populate; ++ engine->instmem.clear = nv04_instmem_clear; ++ engine->instmem.bind = nv04_instmem_bind; ++ engine->instmem.unbind = nv04_instmem_unbind; ++ engine->instmem.prepare_access = nv04_instmem_prepare_access; ++ engine->instmem.finish_access = nv04_instmem_finish_access; ++ engine->mc.init = nv40_mc_init; ++ engine->mc.takedown = nv40_mc_takedown; ++ engine->timer.init = nv04_timer_init; ++ engine->timer.read = nv04_timer_read; ++ engine->timer.takedown = nv04_timer_takedown; ++ engine->fb.init = nv40_fb_init; ++ engine->fb.takedown = nv40_fb_takedown; ++ engine->graph.grclass = nv40_graph_grclass; ++ engine->graph.init = nv40_graph_init; ++ engine->graph.takedown = nv40_graph_takedown; ++ engine->graph.fifo_access = nv04_graph_fifo_access; ++ engine->graph.channel = nv40_graph_channel; ++ engine->graph.create_context = nv40_graph_create_context; ++ engine->graph.destroy_context = nv40_graph_destroy_context; ++ engine->graph.load_context = nv40_graph_load_context; ++ engine->graph.unload_context = nv40_graph_unload_context; ++ engine->fifo.channels = 32; ++ engine->fifo.init = nv40_fifo_init; ++ engine->fifo.takedown = nouveau_stub_takedown; ++ engine->fifo.disable = nv04_fifo_disable; ++ engine->fifo.enable = nv04_fifo_enable; ++ engine->fifo.reassign = nv04_fifo_reassign; ++ engine->fifo.channel_id = nv10_fifo_channel_id; ++ engine->fifo.create_context = nv40_fifo_create_context; ++ engine->fifo.destroy_context = nv40_fifo_destroy_context; ++ engine->fifo.load_context = nv40_fifo_load_context; ++ engine->fifo.unload_context = nv40_fifo_unload_context; ++ break; ++ case 0x50: ++ case 0x80: /* gotta love NVIDIA's consistency.. */ ++ case 0x90: ++ case 0xA0: ++ engine->instmem.init = nv50_instmem_init; ++ engine->instmem.takedown = nv50_instmem_takedown; ++ engine->instmem.suspend = nv50_instmem_suspend; ++ engine->instmem.resume = nv50_instmem_resume; ++ engine->instmem.populate = nv50_instmem_populate; ++ engine->instmem.clear = nv50_instmem_clear; ++ engine->instmem.bind = nv50_instmem_bind; ++ engine->instmem.unbind = nv50_instmem_unbind; ++ engine->instmem.prepare_access = nv50_instmem_prepare_access; ++ engine->instmem.finish_access = nv50_instmem_finish_access; ++ engine->mc.init = nv50_mc_init; ++ engine->mc.takedown = nv50_mc_takedown; ++ engine->timer.init = nv04_timer_init; ++ engine->timer.read = nv04_timer_read; ++ engine->timer.takedown = nv04_timer_takedown; ++ engine->fb.init = nouveau_stub_init; ++ engine->fb.takedown = nouveau_stub_takedown; ++ engine->graph.grclass = nv50_graph_grclass; ++ engine->graph.init = nv50_graph_init; ++ engine->graph.takedown = nv50_graph_takedown; ++ engine->graph.fifo_access = nv50_graph_fifo_access; ++ engine->graph.channel = nv50_graph_channel; ++ engine->graph.create_context = nv50_graph_create_context; ++ engine->graph.destroy_context = nv50_graph_destroy_context; ++ engine->graph.load_context = nv50_graph_load_context; ++ engine->graph.unload_context = nv50_graph_unload_context; ++ engine->fifo.channels = 128; ++ engine->fifo.init = nv50_fifo_init; ++ engine->fifo.takedown = nv50_fifo_takedown; ++ engine->fifo.disable = nv04_fifo_disable; ++ engine->fifo.enable = nv04_fifo_enable; ++ engine->fifo.reassign = nv04_fifo_reassign; ++ engine->fifo.channel_id = nv50_fifo_channel_id; ++ engine->fifo.create_context = nv50_fifo_create_context; ++ engine->fifo.destroy_context = nv50_fifo_destroy_context; ++ engine->fifo.load_context = nv50_fifo_load_context; ++ engine->fifo.unload_context = nv50_fifo_unload_context; ++ break; ++ default: ++ NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++int ++nouveau_card_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine; ++ struct nouveau_gpuobj *gpuobj; ++ int ret; ++ ++ NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); ++ ++ if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE) ++ return 0; ++ ++ /* Determine exact chipset we're running on */ ++ if (dev_priv->card_type < NV_10) ++ dev_priv->chipset = dev_priv->card_type; ++ else ++ dev_priv->chipset = ++ (nv_rd32(dev, NV03_PMC_BOOT_0) & 0x0ff00000) >> 20; ++ ++ /* Initialise internal driver API hooks */ ++ ret = nouveau_init_engine_ptrs(dev); ++ if (ret) ++ return ret; ++ engine = &dev_priv->engine; ++ dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; ++ ++ /* Parse BIOS tables / Run init tables if card not POSTed */ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ ret = nouveau_bios_init(dev); ++ if (ret) ++ return ret; ++ } ++ ++ ret = nouveau_gpuobj_early_init(dev); ++ if (ret) ++ return ret; ++ ++ /* Initialise instance memory, must happen before mem_init so we ++ * know exactly how much VRAM we're able to use for "normal" ++ * purposes. ++ */ ++ ret = engine->instmem.init(dev); ++ if (ret) ++ return ret; ++ ++ /* Setup the memory manager */ ++ ret = nouveau_mem_init(dev); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_gpuobj_init(dev); ++ if (ret) ++ return ret; ++ ++ /* PMC */ ++ ret = engine->mc.init(dev); ++ if (ret) ++ return ret; ++ ++ /* PTIMER */ ++ ret = engine->timer.init(dev); ++ if (ret) ++ return ret; ++ ++ /* PFB */ ++ ret = engine->fb.init(dev); ++ if (ret) ++ return ret; ++ ++ /* PGRAPH */ ++ ret = engine->graph.init(dev); ++ if (ret) ++ return ret; ++ ++ /* PFIFO */ ++ ret = engine->fifo.init(dev); ++ if (ret) ++ return ret; ++ ++ /* this call irq_preinstall, register irq handler and ++ * call irq_postinstall ++ */ ++ ret = drm_irq_install(dev); ++ if (ret) ++ return ret; ++ ++ ret = drm_vblank_init(dev, 0); ++ if (ret) ++ return ret; ++ ++ /* what about PVIDEO/PCRTC/PRAMDAC etc? */ ++ ++ ret = nouveau_channel_alloc(dev, &dev_priv->channel, ++ (struct drm_file *)-2, ++ NvDmaFB, NvDmaTT); ++ if (ret) ++ return ret; ++ ++ gpuobj = NULL; ++ ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, ++ 0, nouveau_mem_fb_amount(dev), ++ NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, ++ &gpuobj); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM, ++ gpuobj, NULL); ++ if (ret) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return ret; ++ } ++ ++ gpuobj = NULL; ++ ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0, ++ dev_priv->gart_info.aper_size, ++ NV_DMA_ACCESS_RW, &gpuobj, NULL); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART, ++ gpuobj, NULL); ++ if (ret) { ++ nouveau_gpuobj_del(dev, &gpuobj); ++ return ret; ++ } ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ if (dev_priv->card_type >= NV_50) { ++ ret = nv50_display_create(dev); ++ if (ret) ++ return ret; ++ } else { ++ ret = nv04_display_create(dev); ++ if (ret) ++ return ret; ++ } ++ } ++ ++ ret = nouveau_backlight_init(dev); ++ if (ret) ++ NV_ERROR(dev, "Error %d registering backlight\n", ret); ++ ++ dev_priv->init_state = NOUVEAU_CARD_INIT_DONE; ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ drm_helper_initial_config(dev); ++ ++ return 0; ++} ++ ++static void nouveau_card_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ ++ NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); ++ ++ if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) { ++ nouveau_backlight_exit(dev); ++ ++ if (dev_priv->channel) { ++ nouveau_channel_free(dev_priv->channel); ++ dev_priv->channel = NULL; ++ } ++ ++ engine->fifo.takedown(dev); ++ engine->graph.takedown(dev); ++ engine->fb.takedown(dev); ++ engine->timer.takedown(dev); ++ engine->mc.takedown(dev); ++ ++ mutex_lock(&dev->struct_mutex); ++ ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); ++ mutex_unlock(&dev->struct_mutex); ++ nouveau_sgdma_takedown(dev); ++ ++ nouveau_gpuobj_takedown(dev); ++ nouveau_mem_close(dev); ++ engine->instmem.takedown(dev); ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ drm_irq_uninstall(dev); ++ ++ nouveau_gpuobj_late_takedown(dev); ++ nouveau_bios_takedown(dev); ++ ++ dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN; ++ } ++} ++ ++/* here a client dies, release the stuff that was allocated for its ++ * file_priv */ ++void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv) ++{ ++ nouveau_channel_cleanup(dev, file_priv); ++} ++ ++/* first module load, setup the mmio/fb mapping */ ++/* KMS: we need mmio at load time, not when the first drm client opens. */ ++int nouveau_firstopen(struct drm_device *dev) ++{ ++ return 0; ++} ++ ++/* if we have an OF card, copy vbios to RAMIN */ ++static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev) ++{ ++#if defined(__powerpc__) ++ int size, i; ++ const uint32_t *bios; ++ struct device_node *dn = pci_device_to_OF_node(dev->pdev); ++ if (!dn) { ++ NV_INFO(dev, "Unable to get the OF node\n"); ++ return; ++ } ++ ++ bios = of_get_property(dn, "NVDA,BMP", &size); ++ if (bios) { ++ for (i = 0; i < size; i += 4) ++ nv_wi32(dev, i, bios[i/4]); ++ NV_INFO(dev, "OF bios successfully copied (%d bytes)\n", size); ++ } else { ++ NV_INFO(dev, "Unable to get the OF bios\n"); ++ } ++#endif ++} ++ ++int nouveau_load(struct drm_device *dev, unsigned long flags) ++{ ++ struct drm_nouveau_private *dev_priv; ++ uint32_t reg0; ++ uint8_t architecture = 0; ++ resource_size_t mmio_start_offs; ++ ++ dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); ++ if (!dev_priv) ++ return -ENOMEM; ++ dev->dev_private = dev_priv; ++ dev_priv->dev = dev; ++ ++ dev_priv->flags = flags & NOUVEAU_FLAGS; ++ dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN; ++ ++ NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", ++ dev->pci_vendor, dev->pci_device, dev->pdev->class); ++ ++ dev_priv->acpi_dsm = nouveau_dsm_probe(dev); ++ ++ if (dev_priv->acpi_dsm) ++ nouveau_hybrid_setup(dev); ++ ++ /* resource 0 is mmio regs */ ++ /* resource 1 is linear FB */ ++ /* resource 2 is RAMIN (mmio regs + 0x1000000) */ ++ /* resource 6 is bios */ ++ ++ /* map the mmio regs */ ++ mmio_start_offs = pci_resource_start(dev->pdev, 0); ++ dev_priv->mmio = ioremap(mmio_start_offs, 0x00800000); ++ if (!dev_priv->mmio) { ++ NV_ERROR(dev, "Unable to initialize the mmio mapping. " ++ "Please report your setup to " DRIVER_EMAIL "\n"); ++ return -EINVAL; ++ } ++ NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", ++ (unsigned long long)mmio_start_offs); ++ ++#ifdef __BIG_ENDIAN ++ /* Put the card in BE mode if it's not */ ++ if (nv_rd32(dev, NV03_PMC_BOOT_1)) ++ nv_wr32(dev, NV03_PMC_BOOT_1, 0x00000001); ++ ++ DRM_MEMORYBARRIER(); ++#endif ++ ++ /* Time to determine the card architecture */ ++ reg0 = nv_rd32(dev, NV03_PMC_BOOT_0); ++ ++ /* We're dealing with >=NV10 */ ++ if ((reg0 & 0x0f000000) > 0) { ++ /* Bit 27-20 contain the architecture in hex */ ++ architecture = (reg0 & 0xff00000) >> 20; ++ /* NV04 or NV05 */ ++ } else if ((reg0 & 0xff00fff0) == 0x20004000) { ++ architecture = 0x04; ++ } ++ ++ if (architecture >= 0x80) ++ dev_priv->card_type = NV_50; ++ else if (architecture >= 0x60) ++ dev_priv->card_type = NV_40; ++ else if (architecture >= 0x50) ++ dev_priv->card_type = NV_50; ++ else if (architecture >= 0x40) ++ dev_priv->card_type = NV_40; ++ else if (architecture >= 0x30) ++ dev_priv->card_type = NV_30; ++ else if (architecture >= 0x20) ++ dev_priv->card_type = NV_20; ++ else if (architecture >= 0x17) ++ dev_priv->card_type = NV_17; ++ else if (architecture >= 0x11) ++ dev_priv->card_type = NV_11; ++ else if (architecture >= 0x10) ++ dev_priv->card_type = NV_10; ++ else if (architecture >= 0x04) ++ dev_priv->card_type = NV_04; ++ else ++ dev_priv->card_type = NV_UNKNOWN; ++ ++ NV_INFO(dev, "Detected an NV%d generation card (0x%08x)\n", ++ dev_priv->card_type, reg0); ++ ++ if (dev_priv->card_type == NV_UNKNOWN) ++ return -EINVAL; ++ ++ /* map larger RAMIN aperture on NV40 cards */ ++ dev_priv->ramin = NULL; ++ if (dev_priv->card_type >= NV_40) { ++ int ramin_bar = 2; ++ if (pci_resource_len(dev->pdev, ramin_bar) == 0) ++ ramin_bar = 3; ++ ++ dev_priv->ramin_size = pci_resource_len(dev->pdev, ramin_bar); ++ dev_priv->ramin = ioremap( ++ pci_resource_start(dev->pdev, ramin_bar), ++ dev_priv->ramin_size); ++ if (!dev_priv->ramin) { ++ NV_ERROR(dev, "Failed to init RAMIN mapping, " ++ "limited instance memory available\n"); ++ } ++ } ++ ++ /* On older cards (or if the above failed), create a map covering ++ * the BAR0 PRAMIN aperture */ ++ if (!dev_priv->ramin) { ++ dev_priv->ramin_size = 1 * 1024 * 1024; ++ dev_priv->ramin = ioremap(mmio_start_offs + NV_RAMIN, ++ dev_priv->ramin_size); ++ if (!dev_priv->ramin) { ++ NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n"); ++ return -ENOMEM; ++ } ++ } ++ ++ nouveau_OF_copy_vbios_to_ramin(dev); ++ ++ /* Special flags */ ++ if (dev->pci_device == 0x01a0) ++ dev_priv->flags |= NV_NFORCE; ++ else if (dev->pci_device == 0x01f0) ++ dev_priv->flags |= NV_NFORCE2; ++ ++ /* For kernel modesetting, init card now and bring up fbcon */ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ int ret = nouveau_card_init(dev); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void nouveau_close(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ /* In the case of an error dev_priv may not be be allocated yet */ ++ if (dev_priv && dev_priv->card_type) ++ nouveau_card_takedown(dev); ++} ++ ++/* KMS: we need mmio at load time, not when the first drm client opens. */ ++void nouveau_lastclose(struct drm_device *dev) ++{ ++ sfbhack_takedown(dev); ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) ++ return; ++ ++ nouveau_close(dev); ++} ++ ++int nouveau_unload(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ if (dev_priv->card_type >= NV_50) ++ nv50_display_destroy(dev); ++ else ++ nv04_display_destroy(dev); ++ nouveau_close(dev); ++ } ++ ++ iounmap(dev_priv->mmio); ++ iounmap(dev_priv->ramin); ++ ++ kfree(dev_priv); ++ dev->dev_private = NULL; ++ return 0; ++} ++ ++int ++nouveau_ioctl_card_init(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ return nouveau_card_init(dev); ++} ++ ++int nouveau_ioctl_getparam(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_nouveau_getparam *getparam = data; ++ uint32_t sfb_handle; ++ int ret; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ switch (getparam->param) { ++ case NOUVEAU_GETPARAM_CHIPSET_ID: ++ getparam->value = dev_priv->chipset; ++ break; ++ case NOUVEAU_GETPARAM_PCI_VENDOR: ++ getparam->value = dev->pci_vendor; ++ break; ++ case NOUVEAU_GETPARAM_PCI_DEVICE: ++ getparam->value = dev->pci_device; ++ break; ++ case NOUVEAU_GETPARAM_BUS_TYPE: ++ if (drm_device_is_agp(dev)) ++ getparam->value = NV_AGP; ++ else if (drm_device_is_pcie(dev)) ++ getparam->value = NV_PCIE; ++ else ++ getparam->value = NV_PCI; ++ break; ++ case NOUVEAU_GETPARAM_FB_PHYSICAL: ++ getparam->value = dev_priv->fb_phys; ++ break; ++ case NOUVEAU_GETPARAM_AGP_PHYSICAL: ++ getparam->value = dev_priv->gart_info.aper_base; ++ break; ++ case NOUVEAU_GETPARAM_PCI_PHYSICAL: ++ if (dev->sg) { ++ getparam->value = (unsigned long)dev->sg->virtual; ++ } else { ++ NV_ERROR(dev, "Requested PCIGART address, " ++ "while no PCIGART was created\n"); ++ return -EINVAL; ++ } ++ break; ++ case NOUVEAU_GETPARAM_FB_SIZE: ++ getparam->value = dev_priv->fb_available_size; ++ break; ++ case NOUVEAU_GETPARAM_AGP_SIZE: ++ getparam->value = dev_priv->gart_info.aper_size; ++ break; ++ case NOUVEAU_GETPARAM_VM_VRAM_BASE: ++ getparam->value = dev_priv->vm_vram_base; ++ break; ++ case 0xdeadcafe00000001: /* NOUVEAU_GETPARAM_SHAREDFB_HANDLE */ ++ ret = sfbhack_init(dev); ++ if (ret) ++ return ret; ++ ++ ret = drm_gem_handle_create(file_priv, dev_priv->sfb_gem, ++ &sfb_handle); ++ if (ret) ++ return ret; ++ getparam->value = sfb_handle; ++ break; ++ case 0xdeadcafe00000002: /* NOUVEAU_GETPARAM_SHAREDFB_SIZE */ ++ ret = sfbhack_init(dev); ++ if (ret) ++ return ret; ++ ++ getparam->value = dev_priv->sfb_gem->size; ++ break; ++ case 0xdeadcafe00000003: /* NOUVEAU_GETPARAM_SCANOUT_TILEFLAGS */ ++ getparam->value = 1; ++ break; ++ default: ++ NV_ERROR(dev, "unknown parameter %lld\n", getparam->param); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++int ++nouveau_ioctl_setparam(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_nouveau_setparam *setparam = data; ++ ++ NOUVEAU_CHECK_INITIALISED_WITH_RETURN; ++ ++ switch (setparam->param) { ++ default: ++ NV_ERROR(dev, "unknown parameter %lld\n", setparam->param); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* Wait until (value(reg) & mask) == val, up until timeout has hit */ ++bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout, ++ uint32_t reg, uint32_t mask, uint32_t val) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; ++ uint64_t start = ptimer->read(dev); ++ ++ do { ++ if ((nv_rd32(dev, reg) & mask) == val) ++ return true; ++ } while (ptimer->read(dev) - start < timeout); ++ ++ return false; ++} ++ ++/* Waits for PGRAPH to go completely idle */ ++bool nouveau_wait_for_idle(struct drm_device *dev) ++{ ++ if (!nv_wait(NV04_PGRAPH_STATUS, 0xffffffff, 0x00000000)) { ++ NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n", ++ nv_rd32(dev, NV04_PGRAPH_STATUS)); ++ return false; ++ } ++ ++ return true; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c +new file mode 100644 +index 0000000..7818981 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c +@@ -0,0 +1,131 @@ ++/* ++ * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA, ++ * All Rights Reserved. ++ * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA, ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sub license, ++ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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 "drmP.h" ++ ++#include "nouveau_drv.h" ++ ++static struct vm_operations_struct nouveau_ttm_vm_ops; ++static struct vm_operations_struct *ttm_vm_ops; ++ ++static int ++nouveau_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ++{ ++ struct ttm_buffer_object *bo = vma->vm_private_data; ++ int ret; ++ ++ if (unlikely(bo == NULL)) ++ return VM_FAULT_NOPAGE; ++ ++ ret = ttm_vm_ops->fault(vma, vmf); ++ return ret; ++} ++ ++int ++nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma) ++{ ++ struct drm_file *file_priv = filp->private_data; ++ struct drm_nouveau_private *dev_priv = ++ file_priv->minor->dev->dev_private; ++ int ret; ++ ++ if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) ++ return drm_mmap(filp, vma); ++ ++ ret = ttm_bo_mmap(filp, vma, &dev_priv->ttm.bdev); ++ if (unlikely(ret != 0)) ++ return ret; ++ ++ if (unlikely(ttm_vm_ops == NULL)) { ++ ttm_vm_ops = vma->vm_ops; ++ nouveau_ttm_vm_ops = *ttm_vm_ops; ++ nouveau_ttm_vm_ops.fault = &nouveau_ttm_fault; ++ } ++ ++ vma->vm_ops = &nouveau_ttm_vm_ops; ++ return 0; ++} ++ ++static int ++nouveau_ttm_mem_global_init(struct ttm_global_reference *ref) ++{ ++ return ttm_mem_global_init(ref->object); ++} ++ ++static void ++nouveau_ttm_mem_global_release(struct ttm_global_reference *ref) ++{ ++ ttm_mem_global_release(ref->object); ++} ++ ++int ++nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv) ++{ ++ struct ttm_global_reference *global_ref; ++ int ret; ++ ++ global_ref = &dev_priv->ttm.mem_global_ref; ++ global_ref->global_type = TTM_GLOBAL_TTM_MEM; ++ global_ref->size = sizeof(struct ttm_mem_global); ++ global_ref->init = &nouveau_ttm_mem_global_init; ++ global_ref->release = &nouveau_ttm_mem_global_release; ++ ++ ret = ttm_global_item_ref(global_ref); ++ if (unlikely(ret != 0)) { ++ DRM_ERROR("Failed setting up TTM memory accounting\n"); ++ dev_priv->ttm.mem_global_ref.release = NULL; ++ return ret; ++ } ++ ++ dev_priv->ttm.bo_global_ref.mem_glob = global_ref->object; ++ global_ref = &dev_priv->ttm.bo_global_ref.ref; ++ global_ref->global_type = TTM_GLOBAL_TTM_BO; ++ global_ref->size = sizeof(struct ttm_bo_global); ++ global_ref->init = &ttm_bo_global_init; ++ global_ref->release = &ttm_bo_global_release; ++ ++ ret = ttm_global_item_ref(global_ref); ++ if (unlikely(ret != 0)) { ++ DRM_ERROR("Failed setting up TTM BO subsystem\n"); ++ ttm_global_item_unref(&dev_priv->ttm.mem_global_ref); ++ dev_priv->ttm.mem_global_ref.release = NULL; ++ return ret; ++ } ++ ++ return 0; ++} ++ ++void ++nouveau_ttm_global_release(struct drm_nouveau_private *dev_priv) ++{ ++ if (dev_priv->ttm.mem_global_ref.release == NULL) ++ return; ++ ++ ttm_global_item_unref(&dev_priv->ttm.bo_global_ref.ref); ++ ttm_global_item_unref(&dev_priv->ttm.mem_global_ref); ++ dev_priv->ttm.mem_global_ref.release = NULL; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c +new file mode 100644 +index 0000000..2ab9f30 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_crtc.c +@@ -0,0 +1,992 @@ ++/* ++ * 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 "drmP.h" ++#include "drm_crtc_helper.h" ++ ++#include "nouveau_drv.h" ++#include "nouveau_encoder.h" ++#include "nouveau_connector.h" ++#include "nouveau_crtc.h" ++#include "nouveau_fb.h" ++#include "nouveau_hw.h" ++#include "nvreg.h" ++ ++static int ++nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, ++ struct drm_framebuffer *old_fb); ++ ++static void ++crtc_wr_cio_state(struct drm_crtc *crtc, struct nv04_crtc_reg *crtcstate, int index) ++{ ++ NVWriteVgaCrtc(crtc->dev, nouveau_crtc(crtc)->index, index, ++ crtcstate->CRTC[index]); ++} ++ ++static void nv_crtc_set_digital_vibrance(struct drm_crtc *crtc, int level) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; ++ struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; ++ ++ regp->CRTC[NV_CIO_CRE_CSB] = nv_crtc->saturation = level; ++ if (nv_crtc->saturation && nv_gf4_disp_arch(crtc->dev)) { ++ regp->CRTC[NV_CIO_CRE_CSB] = 0x80; ++ regp->CRTC[NV_CIO_CRE_5B] = nv_crtc->saturation << 2; ++ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_5B); ++ } ++ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_CSB); ++} ++ ++static void nv_crtc_set_image_sharpening(struct drm_crtc *crtc, int level) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; ++ struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; ++ ++ nv_crtc->sharpness = level; ++ if (level < 0) /* blur is in hw range 0x3f -> 0x20 */ ++ level += 0x40; ++ regp->ramdac_634 = level; ++ NVWriteRAMDAC(crtc->dev, nv_crtc->index, NV_PRAMDAC_634, regp->ramdac_634); ++} ++ ++#define PLLSEL_VPLL1_MASK \ ++ (NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_VPLL \ ++ | NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2) ++#define PLLSEL_VPLL2_MASK \ ++ (NV_PRAMDAC_PLL_COEFF_SELECT_PLL_SOURCE_VPLL2 \ ++ | NV_PRAMDAC_PLL_COEFF_SELECT_VCLK2_RATIO_DB2) ++#define PLLSEL_TV_MASK \ ++ (NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1 \ ++ | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1 \ ++ | NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK2 \ ++ | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK2) ++ ++/* 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_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mode * mode, int dot_clock) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct nv04_mode_state *state = &dev_priv->mode_reg; ++ struct nv04_crtc_reg *regp = &state->crtc_reg[nv_crtc->index]; ++ struct drm_framebuffer *fb = crtc->fb; ++ struct nouveau_pll_vals *pv = ®p->pllvals; ++ struct pll_lims pll_lim; ++ int vclk, arb_burst, arb_fifo_lwm; ++ ++ if (get_pll_limits(dev, nv_crtc->index ? 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 (dev_priv->chipset > 0x40 && dot_clock <= (pll_lim.vco1.maxfreq / 2)) ++ memset(&pll_lim.vco2, 0, sizeof(pll_lim.vco2)); ++ ++ vclk = nouveau_calc_pll_mnp(dev, &pll_lim, dot_clock, pv); ++ if (!vclk) ++ return; ++ ++ state->pllsel &= PLLSEL_VPLL1_MASK | PLLSEL_VPLL2_MASK | PLLSEL_TV_MASK; ++ ++ /* The blob uses this always, so let's do the same */ ++ if (nv_arch(dev) == NV_40) ++ state->pllsel |= NV_PRAMDAC_PLL_COEFF_SELECT_USE_VPLL2_TRUE; ++ /* again nv40 and some nv43 act more like nv3x as described above */ ++ if (dev_priv->chipset < 0x41) ++ state->pllsel |= NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_MPLL | ++ NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_NVPLL; ++ state->pllsel |= nv_crtc->index ? PLLSEL_VPLL2_MASK : PLLSEL_VPLL1_MASK; ++ ++ if (pv->NM2) ++ NV_TRACE(dev, "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(dev, "vpll: n %d m %d log2p %d\n", ++ pv->N1, pv->M1, pv->log2P); ++ ++ nouveau_calc_arb(dev, vclk, fb->bits_per_pixel, &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 (nv_arch(dev) >= NV_30) ++ regp->CRTC[NV_CIO_CRE_47] = arb_fifo_lwm >> 8; ++ ++ nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset); ++} ++ ++static void ++nv_crtc_dpms(struct drm_crtc *crtc, int mode) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ unsigned char seq1 = 0, crtc17 = 0; ++ unsigned char crtc1A; ++ ++ NV_TRACE(dev, "Setting dpms mode %d on CRTC %d\n", mode, ++ nv_crtc->index); ++ ++ if (nv_crtc->last_dpms == mode) /* Don't do unnecesary mode changes. */ ++ return; ++ ++ nv_crtc->last_dpms = mode; ++ ++ if (nv_two_heads(dev)) ++ NVSetOwner(dev, nv_crtc->index); ++ ++ /* nv4ref indicates these two RPC1 bits inhibit h/v sync */ ++ crtc1A = NVReadVgaCrtc(dev, nv_crtc->index, ++ NV_CIO_CRE_RPC1_INDEX) & ~0xC0; ++ switch (mode) { ++ case DRM_MODE_DPMS_STANDBY: ++ /* Screen: Off; HSync: Off, VSync: On -- Not Supported */ ++ seq1 = 0x20; ++ crtc17 = 0x80; ++ crtc1A |= 0x80; ++ break; ++ case DRM_MODE_DPMS_SUSPEND: ++ /* Screen: Off; HSync: On, VSync: Off -- Not Supported */ ++ seq1 = 0x20; ++ crtc17 = 0x80; ++ crtc1A |= 0x40; ++ break; ++ case DRM_MODE_DPMS_OFF: ++ /* Screen: Off; HSync: Off, VSync: Off */ ++ seq1 = 0x20; ++ crtc17 = 0x00; ++ crtc1A |= 0xC0; ++ break; ++ case DRM_MODE_DPMS_ON: ++ default: ++ /* Screen: On; HSync: On, VSync: On */ ++ seq1 = 0x00; ++ crtc17 = 0x80; ++ break; ++ } ++ ++ NVVgaSeqReset(dev, nv_crtc->index, true); ++ /* Each head has it's own sequencer, so we can turn it off when we want */ ++ seq1 |= (NVReadVgaSeq(dev, nv_crtc->index, NV_VIO_SR_CLOCK_INDEX) & ~0x20); ++ NVWriteVgaSeq(dev, nv_crtc->index, NV_VIO_SR_CLOCK_INDEX, seq1); ++ crtc17 |= (NVReadVgaCrtc(dev, nv_crtc->index, NV_CIO_CR_MODE_INDEX) & ~0x80); ++ mdelay(10); ++ NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CR_MODE_INDEX, crtc17); ++ NVVgaSeqReset(dev, nv_crtc->index, false); ++ ++ NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A); ++} ++ ++static bool ++nv_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ return true; ++} ++ ++static void ++nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; ++ struct drm_framebuffer *fb = crtc->fb; ++ ++ /* Calculate our timings */ ++ int horizDisplay = (mode->crtc_hdisplay >> 3) - 1; ++ int horizStart = (mode->crtc_hsync_start >> 3) - 1; ++ int horizEnd = (mode->crtc_hsync_end >> 3) - 1; ++ int horizTotal = (mode->crtc_htotal >> 3) - 5; ++ int horizBlankStart = (mode->crtc_hdisplay >> 3) - 1; ++ int horizBlankEnd = (mode->crtc_htotal >> 3) - 1; ++ int vertDisplay = mode->crtc_vdisplay - 1; ++ int vertStart = mode->crtc_vsync_start - 1; ++ int vertEnd = mode->crtc_vsync_end - 1; ++ int vertTotal = mode->crtc_vtotal - 2; ++ int vertBlankStart = mode->crtc_vdisplay - 1; ++ int vertBlankEnd = mode->crtc_vtotal - 1; ++ ++ struct drm_encoder *encoder; ++ bool fp_output = false; ++ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ ++ if (encoder->crtc == crtc && ++ (nv_encoder->dcb->type == OUTPUT_LVDS || ++ nv_encoder->dcb->type == OUTPUT_TMDS)) ++ fp_output = true; ++ } ++ ++ if (fp_output) { ++ vertStart = vertTotal - 3; ++ vertEnd = vertTotal - 2; ++ vertBlankStart = vertStart; ++ horizStart = horizTotal - 5; ++ horizEnd = horizTotal - 2; ++ horizBlankEnd = horizTotal + 4; ++#if 0 ++ if (dev->overlayAdaptor && nv_arch(dev) >= NV_10) ++ /* This reportedly works around some video overlay bandwidth problems */ ++ horizTotal += 2; ++#endif ++ } ++ ++ if (mode->flags & DRM_MODE_FLAG_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 & (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC)) ++ && (mode->flags & (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC))) { ++ ++ regp->MiscOutReg = 0x23; ++ if (mode->flags & DRM_MODE_FLAG_NHSYNC) ++ regp->MiscOutReg |= 0x40; ++ if (mode->flags & DRM_MODE_FLAG_NVSYNC) ++ regp->MiscOutReg |= 0x80; ++ } else { ++ int vdisplay = mode->vdisplay; ++ if (mode->flags & DRM_MODE_FLAG_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->clock_index & 0x03) << 2; ++ ++ /* ++ * Time Sequencer ++ */ ++ regp->Sequencer[NV_VIO_SR_RESET_INDEX] = 0x00; ++ /* 0x20 disables the sequencer */ ++ if (mode->flags & DRM_MODE_FLAG_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 & DRM_MODE_FLAG_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] = fb->pitch / 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(fb->pitch / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8); ++ regp->CRTC[NV_CIO_CRE_RPC1_INDEX] = mode->crtc_hdisplay < 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 & DRM_MODE_FLAG_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(struct drm_crtc *crtc, struct drm_display_mode * mode) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; ++ struct nv04_crtc_reg *savep = &dev_priv->saved_reg.crtc_reg[nv_crtc->index]; ++ struct drm_encoder *encoder; ++ bool lvds_output = false, tmds_output = false, tv_output = false, ++ off_chip_digital = false; ++ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ bool digital = false; ++ ++ if (encoder->crtc != crtc) ++ continue; ++ ++ if (nv_encoder->dcb->type == OUTPUT_LVDS) ++ digital = lvds_output = true; ++ if (nv_encoder->dcb->type == OUTPUT_TV) ++ tv_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->index == 0) ++ regp->crtc_eng_ctrl |= NV_CRTC_FSEL_I2C; ++#if 0 ++ /* Set overlay to desired crtc. */ ++ if (dev->overlayAdaptor) { ++ NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(dev); ++ if (pPriv->overlayCRTC == nv_crtc->index) ++ regp->crtc_eng_ctrl |= NV_CRTC_FSEL_OVERLAY; ++ } ++#endif ++ ++ /* 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 (dev_priv->chipset >= 0x11) ++ regp->cursor_cfg |= NV_PCRTC_CURSOR_CONFIG_CUR_BPP_32; ++ if (mode->flags & DRM_MODE_FLAG_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->index == 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] = dev_priv->saved_reg.crtc_reg[0].CRTC[NV_CIO_CRE_TVOUT_LATENCY]; ++ if (!nv_crtc->index) ++ 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->crtc_vdisplay - 3; ++ regp->crtc_834 = mode->crtc_vdisplay - 1; ++ ++ if (nv_arch(dev) == NV_40) ++ /* This is what the blob does */ ++ regp->crtc_850 = NVReadCRTC(dev, 0, NV_PCRTC_850); ++ ++ if (nv_arch(dev) >= NV_30) ++ regp->gpio_ext = NVReadCRTC(dev, 0, NV_PCRTC_GPIO_EXT); ++ ++ regp->crtc_cfg = NV_PCRTC_CONFIG_START_ADDRESS_HSYNC; ++ ++ /* Some misc regs */ ++ if (nv_arch(dev) == NV_40) { ++ regp->CRTC[NV_CIO_CRE_85] = 0xFF; ++ regp->CRTC[NV_CIO_CRE_86] = 0x1; ++ } ++ ++ regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (crtc->fb->depth + 1) / 8; ++ /* Enable slaved mode (called MODE_TV in nv4ref.h) */ ++ if (lvds_output || tmds_output || tv_output) ++ regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (1 << 7); ++ ++ /* Generic PRAMDAC regs */ ++ ++ if (nv_arch(dev) >= NV_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 (crtc->fb->depth == 16) ++ regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; ++ if (dev_priv->chipset >= 0x11) ++ regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG; ++ ++ regp->ramdac_630 = 0; /* turn off green mode (tv test pattern?) */ ++ regp->tv_setup = 0; ++ ++ nv_crtc_set_image_sharpening(crtc, nv_crtc->sharpness); ++ ++ /* Some values the blob sets */ ++ regp->ramdac_8c0 = 0x100; ++ regp->ramdac_a20 = 0x0; ++ regp->ramdac_a24 = 0xfffff; ++ regp->ramdac_a34 = 0x1; ++} ++ ++/** ++ * 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 int ++nv_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode, ++ int x, int y, struct drm_framebuffer *old_fb) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ NV_DEBUG(dev, "CTRC mode on CRTC %d:\n", nv_crtc->index); ++ drm_mode_debug_printmodeline(adjusted_mode); ++ ++ /* unlock must come after turning off FP_TG_CONTROL in output_prepare */ ++ nv_lock_vga_crtc_shadow(dev, nv_crtc->index, -1); ++ ++ nv_crtc_mode_set_vga(crtc, adjusted_mode); ++ /* calculated in nv04_dfp_prepare, nv40 needs it written before calculating PLLs */ ++ if (nv_arch(dev) == NV_40) ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, dev_priv->mode_reg.sel_clk); ++ nv_crtc_mode_set_regs(crtc, adjusted_mode); ++ nv_crtc_calc_state_ext(crtc, mode, adjusted_mode->clock); ++ return 0; ++} ++ ++static void nv_crtc_save(struct drm_crtc *crtc) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; ++ struct nv04_mode_state *state = &dev_priv->mode_reg; ++ struct nv04_crtc_reg *crtc_state = &state->crtc_reg[nv_crtc->index]; ++ struct nv04_mode_state *saved = &dev_priv->saved_reg; ++ struct nv04_crtc_reg *crtc_saved = &saved->crtc_reg[nv_crtc->index]; ++ ++ if (nv_two_heads(crtc->dev)) ++ NVSetOwner(crtc->dev, nv_crtc->index); ++ ++ nouveau_hw_save_state(crtc->dev, nv_crtc->index, saved); ++ ++ /* init some state to saved value */ ++ state->sel_clk = saved->sel_clk & ~(0x5 << 16); ++ crtc_state->CRTC[NV_CIO_CRE_LCD__INDEX] = crtc_saved->CRTC[NV_CIO_CRE_LCD__INDEX]; ++ state->pllsel = saved->pllsel & ~(PLLSEL_VPLL1_MASK | PLLSEL_VPLL2_MASK | PLLSEL_TV_MASK); ++ crtc_state->gpio_ext = crtc_saved->gpio_ext; ++} ++ ++static void nv_crtc_restore(struct drm_crtc *crtc) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; ++ int head = nv_crtc->index; ++ uint8_t saved_cr21 = dev_priv->saved_reg.crtc_reg[head].CRTC[NV_CIO_CRE_21]; ++ ++ if (nv_two_heads(crtc->dev)) ++ NVSetOwner(crtc->dev, head); ++ ++ nouveau_hw_load_state(crtc->dev, head, &dev_priv->saved_reg); ++ nv_lock_vga_crtc_shadow(crtc->dev, head, saved_cr21); ++ ++ nv_crtc->last_dpms = NV_DPMS_CLEARED; ++} ++ ++static void nv_crtc_prepare(struct drm_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct drm_crtc_helper_funcs *funcs = crtc->helper_private; ++ ++ if (nv_two_heads(dev)) ++ NVSetOwner(dev, nv_crtc->index); ++ ++ funcs->dpms(crtc, DRM_MODE_DPMS_OFF); ++ ++ NVBlankScreen(dev, nv_crtc->index, true); ++ ++ /* Some more preperation. */ ++ NVWriteCRTC(dev, nv_crtc->index, NV_PCRTC_CONFIG, NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA); ++ if (nv_arch(dev) == NV_40) { ++ uint32_t reg900 = NVReadRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_900); ++ NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_900, reg900 & ~0x10000); ++ } ++} ++ ++static void nv_crtc_commit(struct drm_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_crtc_helper_funcs *funcs = crtc->helper_private; ++ struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ ++ nouveau_hw_load_state(dev, nv_crtc->index, &dev_priv->mode_reg); ++ nv04_crtc_mode_set_base(crtc, crtc->x, crtc->y, NULL); ++ ++#ifdef __BIG_ENDIAN ++ /* turn on LFB swapping */ ++ { ++ uint8_t tmp = NVReadVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RCR); ++ tmp |= MASK(NV_CIO_CRE_RCR_ENDIAN_BIG); ++ NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RCR, tmp); ++ } ++#endif ++ ++ funcs->dpms(crtc, DRM_MODE_DPMS_ON); ++} ++ ++static void nv_crtc_destroy(struct drm_crtc *crtc) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ ++ NV_DEBUG(crtc->dev, "\n"); ++ ++ if (!nv_crtc) ++ return; ++ ++ drm_crtc_cleanup(crtc); ++ ++ nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); ++ kfree(nv_crtc); ++} ++ ++static void ++nv_crtc_gamma_load(struct drm_crtc *crtc) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct drm_device *dev = nv_crtc->base.dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct rgb { uint8_t r, g, b; } __attribute__((packed)) *rgbs; ++ int i; ++ ++ rgbs = (struct rgb *)dev_priv->mode_reg.crtc_reg[nv_crtc->index].DAC; ++ for (i = 0; i < 256; i++) { ++ rgbs[i].r = nv_crtc->lut.r[i] >> 8; ++ rgbs[i].g = nv_crtc->lut.g[i] >> 8; ++ rgbs[i].b = nv_crtc->lut.b[i] >> 8; ++ } ++ ++ nouveau_hw_load_state_palette(dev, nv_crtc->index, &dev_priv->mode_reg); ++} ++ ++static void ++nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t size) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ int i; ++ ++ if (size != 256) ++ return; ++ ++ for (i = 0; i < 256; i++) { ++ nv_crtc->lut.r[i] = r[i]; ++ nv_crtc->lut.g[i] = g[i]; ++ nv_crtc->lut.b[i] = b[i]; ++ } ++ ++ /* We need to know the depth before we upload, but it's possible to ++ * get called before a framebuffer is bound. If this is the case, ++ * mark the lut values as dirty by setting depth==0, and it'll be ++ * uploaded on the first mode_set_base() ++ */ ++ if (!nv_crtc->base.fb) { ++ nv_crtc->lut.depth = 0; ++ return; ++ } ++ ++ nv_crtc_gamma_load(crtc); ++} ++ ++static int ++nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, ++ struct drm_framebuffer *old_fb) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; ++ struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; ++ struct drm_framebuffer *drm_fb = nv_crtc->base.fb; ++ struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); ++ int ret; ++ ++ ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM); ++ if (ret) ++ return ret; ++ ++ if (old_fb) { ++ struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb); ++ nouveau_bo_unpin(ofb->nvbo); ++ } ++ ++ nv_crtc->fb.offset = fb->nvbo->bo.offset; ++ ++ if (nv_crtc->lut.depth != drm_fb->depth) { ++ nv_crtc->lut.depth = drm_fb->depth; ++ nv_crtc_gamma_load(crtc); ++ } ++ ++ regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] &= ~3; ++ regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (crtc->fb->depth + 1) / 8; ++ regp->ramdac_gen_ctrl &= ~NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; ++ if (crtc->fb->depth == 16) ++ regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; ++ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_PIXEL_INDEX); ++ NVWriteRAMDAC(crtc->dev, nv_crtc->index, NV_PRAMDAC_GENERAL_CONTROL, ++ regp->ramdac_gen_ctrl); ++ ++ regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = drm_fb->pitch >> 3; ++ regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = ++ XLATE(drm_fb->pitch >> 3, 8, NV_CIO_CRE_RPC0_OFFSET_10_8); ++ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_RPC0_INDEX); ++ crtc_wr_cio_state(crtc, regp, NV_CIO_CR_OFFSET_INDEX); ++ ++ regp->fb_start = nv_crtc->fb.offset & ~3; ++ regp->fb_start += (y * drm_fb->pitch) + (x * drm_fb->bits_per_pixel / 8); ++ NVWriteCRTC(crtc->dev, nv_crtc->index, NV_PCRTC_START, regp->fb_start); ++ return 0; ++} ++ ++static void nv04_cursor_upload(struct drm_device *dev, struct nouveau_bo *src, ++ struct nouveau_bo *dst) ++{ ++ int width = nv_cursor_width(dev); ++ uint32_t pixel; ++ int i, j; ++ ++ for (i = 0; i < width; i++) { ++ for (j = 0; j < width; j++) { ++ pixel = nouveau_bo_rd32(src, i*64 + j); ++ ++ nouveau_bo_wr16(dst, i*width + j, (pixel & 0x80000000) >> 16 ++ | (pixel & 0xf80000) >> 9 ++ | (pixel & 0xf800) >> 6 ++ | (pixel & 0xf8) >> 3); ++ } ++ } ++} ++ ++static void nv11_cursor_upload(struct drm_device *dev, struct nouveau_bo *src, ++ struct nouveau_bo *dst) ++{ ++ uint32_t pixel; ++ int alpha, i; ++ ++ /* 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 < 64 * 64; i++) { ++ pixel = nouveau_bo_rd32(src, 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 = pixel >> 24; ++ if (alpha > 0 && alpha < 255) ++ pixel = (pixel & 0x00ffffff) | ((alpha + 1) << 24); ++ ++#ifdef __BIG_ENDIAN ++ { ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->chipset == 0x11) { ++ pixel = ((pixel & 0x000000ff) << 24) | ++ ((pixel & 0x0000ff00) << 8) | ++ ((pixel & 0x00ff0000) >> 8) | ++ ((pixel & 0xff000000) >> 24); ++ } ++ } ++#endif ++ ++ nouveau_bo_wr32(dst, i, pixel); ++ } ++} ++ ++static int ++nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, ++ uint32_t buffer_handle, uint32_t width, uint32_t height) ++{ ++ struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; ++ struct drm_device *dev = dev_priv->dev; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct nouveau_bo *cursor = NULL; ++ struct drm_gem_object *gem; ++ int ret = 0; ++ ++ if (width != 64 || height != 64) ++ return -EINVAL; ++ ++ if (!buffer_handle) { ++ nv_crtc->cursor.hide(nv_crtc, true); ++ return 0; ++ } ++ ++ gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); ++ if (!gem) ++ return -EINVAL; ++ cursor = nouveau_gem_object(gem); ++ ++ ret = nouveau_bo_map(cursor); ++ if (ret) ++ goto out; ++ ++ if (dev_priv->chipset >= 0x11) ++ nv11_cursor_upload(dev, cursor, nv_crtc->cursor.nvbo); ++ else ++ nv04_cursor_upload(dev, cursor, nv_crtc->cursor.nvbo); ++ ++ nouveau_bo_unmap(cursor); ++ nv_crtc->cursor.offset = nv_crtc->cursor.nvbo->bo.offset; ++ nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset); ++ nv_crtc->cursor.show(nv_crtc, true); ++out: ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ return ret; ++} ++ ++static int ++nv04_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ ++ nv_crtc->cursor.set_pos(nv_crtc, x, y); ++ return 0; ++} ++ ++static const struct drm_crtc_funcs nv04_crtc_funcs = { ++ .save = nv_crtc_save, ++ .restore = nv_crtc_restore, ++ .cursor_set = nv04_crtc_cursor_set, ++ .cursor_move = nv04_crtc_cursor_move, ++ .gamma_set = nv_crtc_gamma_set, ++ .set_config = drm_crtc_helper_set_config, ++ .destroy = nv_crtc_destroy, ++}; ++ ++static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = { ++ .dpms = nv_crtc_dpms, ++ .prepare = nv_crtc_prepare, ++ .commit = nv_crtc_commit, ++ .mode_fixup = nv_crtc_mode_fixup, ++ .mode_set = nv_crtc_mode_set, ++ .mode_set_base = nv04_crtc_mode_set_base, ++ .load_lut = nv_crtc_gamma_load, ++}; ++ ++int ++nv04_crtc_create(struct drm_device *dev, int crtc_num) ++{ ++ struct nouveau_crtc *nv_crtc; ++ int ret, i; ++ ++ nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL); ++ if (!nv_crtc) ++ return -ENOMEM; ++ ++ for (i = 0; i < 256; i++) { ++ nv_crtc->lut.r[i] = i << 8; ++ nv_crtc->lut.g[i] = i << 8; ++ nv_crtc->lut.b[i] = i << 8; ++ } ++ nv_crtc->lut.depth = 0; ++ ++ nv_crtc->index = crtc_num; ++ nv_crtc->last_dpms = NV_DPMS_CLEARED; ++ ++ drm_crtc_init(dev, &nv_crtc->base, &nv04_crtc_funcs); ++ drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs); ++ drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256); ++ ++ ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM, ++ 0, 0x0000, false, true, &nv_crtc->cursor.nvbo); ++ if (!ret) { ++ ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); ++ if (!ret) ++ ret = nouveau_bo_map(nv_crtc->cursor.nvbo); ++ if (ret) ++ nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); ++ } ++ ++ nv04_cursor_init(nv_crtc); ++ ++ return 0; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv04_cursor.c b/drivers/gpu/drm/nouveau/nv04_cursor.c +new file mode 100644 +index 0000000..fc9156e +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_cursor.c +@@ -0,0 +1,70 @@ ++#include "drmP.h" ++#include "drm_mode.h" ++#include "nouveau_reg.h" ++#include "nouveau_drv.h" ++#include "nouveau_crtc.h" ++#include "nouveau_hw.h" ++ ++static void ++nv04_cursor_show(struct nouveau_crtc *nv_crtc, bool update) ++{ ++ nv_show_cursor(nv_crtc->base.dev, nv_crtc->index, true); ++} ++ ++static void ++nv04_cursor_hide(struct nouveau_crtc *nv_crtc, bool update) ++{ ++ nv_show_cursor(nv_crtc->base.dev, nv_crtc->index, false); ++} ++ ++static void ++nv04_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y) ++{ ++ NVWriteRAMDAC(nv_crtc->base.dev, nv_crtc->index, ++ NV_PRAMDAC_CU_START_POS, ++ XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) | ++ XLATE(x, 0, NV_PRAMDAC_CU_START_POS_X)); ++} ++ ++static void ++crtc_wr_cio_state(struct drm_crtc *crtc, struct nv04_crtc_reg *crtcstate, int index) ++{ ++ NVWriteVgaCrtc(crtc->dev, nouveau_crtc(crtc)->index, index, ++ crtcstate->CRTC[index]); ++} ++ ++static void ++nv04_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset) ++{ ++ struct drm_device *dev = nv_crtc->base.dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; ++ struct drm_crtc *crtc = &nv_crtc->base; ++ ++ regp->CRTC[NV_CIO_CRE_HCUR_ADDR0_INDEX] = ++ MASK(NV_CIO_CRE_HCUR_ASI) | ++ XLATE(offset, 17, NV_CIO_CRE_HCUR_ADDR0_ADR); ++ regp->CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] = ++ XLATE(offset, 11, NV_CIO_CRE_HCUR_ADDR1_ADR); ++ if (crtc->mode.flags & DRM_MODE_FLAG_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] = offset >> 24; ++ ++ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); ++ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX); ++ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX); ++ if (nv_arch(dev) == NV_40) ++ nv_fix_nv40_hw_cursor(dev, nv_crtc->index); ++} ++ ++int ++nv04_cursor_init(struct nouveau_crtc *crtc) ++{ ++ crtc->cursor.set_offset = nv04_cursor_set_offset; ++ crtc->cursor.set_pos = nv04_cursor_set_pos; ++ crtc->cursor.hide = nv04_cursor_hide; ++ crtc->cursor.show = nv04_cursor_show; ++ return 0; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c +new file mode 100644 +index 0000000..587b6f5 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_dac.c +@@ -0,0 +1,529 @@ ++/* ++ * 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 "drmP.h" ++#include "drm_crtc_helper.h" ++ ++#include "nouveau_drv.h" ++#include "nouveau_encoder.h" ++#include "nouveau_connector.h" ++#include "nouveau_crtc.h" ++#include "nouveau_hw.h" ++#include "nvreg.h" ++ ++int nv04_dac_output_offset(struct drm_encoder *encoder) ++{ ++ struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; ++ int offset = 0; ++ ++ if (dcb->or & (8 | OUTPUT_C)) ++ offset += 0x68; ++ if (dcb->or & (8 | OUTPUT_B)) ++ offset += 0x2000; ++ ++ return offset; ++} ++ ++/* ++ * 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(struct drm_device *dev, 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 (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR, ++ 0x00000001, 0x00000000)) ++ return -EBUSY; ++ if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR, ++ 0x00000001, 0x00000001)) ++ return -EBUSY; ++ if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR, ++ 0x00000001, 0x00000000)) ++ return -EBUSY; ++ ++ udelay(100); ++ /* when level triggers, sense is _LO_ */ ++ sense_a = nv_rd08(dev, NV_PRMCIO_INP0) & 0x10; ++ ++ /* take another reading until it agrees with sense_a... */ ++ do { ++ udelay(100); ++ sense_b = nv_rd08(dev, NV_PRMCIO_INP0) & 0x10; ++ if (sense_a != sense_b) { ++ sense_b_prime = ++ nv_rd08(dev, 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 enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ struct drm_device *dev = encoder->dev; ++ 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 (nv_two_heads(dev)) ++ /* only implemented for head A for now */ ++ NVSetOwner(dev, 0); ++ ++ saved_seq1 = NVReadVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX); ++ NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20); ++ ++ saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL); ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL, ++ saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF); ++ ++ msleep(10); ++ ++ saved_pi = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX); ++ NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, ++ saved_pi & ~(0x80 | MASK(NV_CIO_CRE_PIXEL_FORMAT))); ++ saved_rpc1 = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX); ++ NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1 & ~0xc0); ++ ++ nv_wr08(dev, NV_PRMDIO_READ_MODE_ADDRESS, 0x0); ++ for (i = 0; i < 3; i++) ++ saved_palette0[i] = nv_rd08(dev, NV_PRMDIO_PALETTE_DATA); ++ saved_palette_mask = nv_rd08(dev, NV_PRMDIO_PIXEL_MASK); ++ nv_wr08(dev, NV_PRMDIO_PIXEL_MASK, 0); ++ ++ saved_rgen_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL); ++ NVWriteRAMDAC(dev, 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]; ++ ++ nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS, 0); ++ nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, 0); ++ nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, 0); ++ /* testing blue won't find monochrome monitors. I don't care */ ++ nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, blue); ++ ++ i = 0; ++ /* take sample pairs until both samples in the pair agree */ ++ do { ++ if (sample_load_twice(dev, 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: ++ nv_wr08(dev, NV_PRMDIO_PIXEL_MASK, saved_palette_mask); ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL, saved_rgen_ctrl); ++ nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS, 0); ++ for (i = 0; i < 3; i++) ++ nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, saved_palette0[i]); ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL, saved_rtest_ctrl); ++ NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi); ++ NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1); ++ NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1); ++ ++ if (blue == 0x18) { ++ NV_TRACE(dev, "Load detected on head A\n"); ++ return connector_status_connected; ++ } ++ ++ return connector_status_disconnected; ++} ++ ++enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; ++ uint32_t testval, regoffset = nv04_dac_output_offset(encoder); ++ uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, ++ saved_rtest_ctrl, temp, saved_gpio_ext = 0, routput; ++ int head, present = 0; ++ ++#define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) ++ if (dcb->type == OUTPUT_TV) { ++ testval = RGB_TEST_DATA(0xa0, 0xa0, 0xa0); ++ ++ if (dev_priv->vbios->tvdactestval) ++ testval = dev_priv->vbios->tvdactestval; ++ } else { ++ testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */ ++ ++ if (dev_priv->vbios->dactestval) ++ testval = dev_priv->vbios->dactestval; ++ } ++ ++ saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, ++ saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF); ++ ++ saved_powerctrl_2 = nvReadMC(dev, NV_PBUS_POWERCTRL_2); ++ ++ nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2 & 0xd7ffffff); ++ if (regoffset == 0x68) { ++ saved_powerctrl_4 = nvReadMC(dev, NV_PBUS_POWERCTRL_4); ++ nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf); ++ } ++ ++ if (dev_priv->chipset >= 0x34) { ++ saved_gpio_ext = NVReadCRTC(dev, 0, NV_PCRTC_GPIO_EXT); ++ ++ NVWriteCRTC(dev, 0, NV_PCRTC_GPIO_EXT, (saved_gpio_ext & ~(3 << 20)) | ++ (dcb->type == OUTPUT_TV ? (1 << 20) : 0)); ++ } ++ ++ msleep(4); ++ ++ saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); ++ head = (saved_routput & 0x100) >> 8; ++#if 0 ++ /* 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; ++#endif ++ /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */ ++ routput = (saved_routput & 0xfffffece) | head << 8; ++ ++ if (nv_arch(dev) >= NV_40) { ++ if (dcb->type == OUTPUT_TV) ++ routput |= 1 << 20; ++ else ++ routput &= ~(1 << 20); ++ } ++ ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, routput); ++ msleep(1); ++ ++ temp = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, temp | 1); ++ ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_TESTPOINT_DATA, ++ NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK | testval); ++ temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL, ++ temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED); ++ msleep(5); ++ ++ temp = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); ++ ++ if (dcb->type == OUTPUT_TV) ++ present = (nv17_tv_detect(encoder, connector, (temp >> 28) & 0xe) ++ == connector_status_connected); ++ else ++ present = temp & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI; ++ ++ temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL, ++ temp & ~NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_TESTPOINT_DATA, 0); ++ ++ /* bios does something more complex for restoring, but I think this is good enough */ ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, saved_routput); ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, saved_rtest_ctrl); ++ if (regoffset == 0x68) ++ nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4); ++ nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2); ++ ++ if (dev_priv->chipset >= 0x34) ++ NVWriteRAMDAC(dev, 0, NV_PCRTC_GPIO_EXT, saved_gpio_ext); ++ ++ if (present) { ++ NV_INFO(dev, "Load detected on output %c\n", '@' + ffs(dcb->or)); ++ return connector_status_connected; ++ } ++ ++ return connector_status_disconnected; ++} ++ ++ ++static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ return true; ++} ++ ++static void nv04_dac_prepare(struct drm_encoder *encoder) ++{ ++ struct drm_encoder_helper_funcs *helper = encoder->helper_private; ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int head = nouveau_crtc(encoder->crtc)->index; ++ struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg; ++ ++ helper->dpms(encoder, DRM_MODE_DPMS_OFF); ++ ++ nv04_dfp_disable(dev, head); ++ ++ /* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f) ++ * at LCD__INDEX which we don't alter ++ */ ++ if (!(crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX] & 0x44)) ++ crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX] = 0; ++} ++ ++ ++static void nv04_dac_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int head = nouveau_crtc(encoder->crtc)->index; ++ ++ NV_TRACE(dev, "%s called for encoder %d\n", __func__, ++ nv_encoder->dcb->index); ++ ++ if (nv_gf4_disp_arch(dev)) { ++ struct drm_encoder *rebind; ++ uint32_t dac_offset = nv04_dac_output_offset(encoder); ++ uint32_t otherdac; ++ ++ /* bit 16-19 are bits that are set on some G70 cards, ++ * but don't seem to have much effect */ ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset, ++ head << 8 | NV_PRAMDAC_DACCLK_SEL_DACCLK); ++ /* force any other vga encoders to bind to the other crtc */ ++ list_for_each_entry(rebind, &dev->mode_config.encoder_list, head) { ++ if (rebind == encoder ++ || nouveau_encoder(rebind)->dcb->type != OUTPUT_ANALOG) ++ continue; ++ ++ dac_offset = nv04_dac_output_offset(rebind); ++ otherdac = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset); ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset, ++ (otherdac & ~0x0100) | (head ^ 1) << 8); ++ } ++ } ++ ++ /* This could use refinement for flatpanels, but it should work this way */ ++ if (dev_priv->chipset < 0x44) ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0xf0000000); ++ else ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); ++} ++ ++static void nv04_dac_commit(struct drm_encoder *encoder) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_device *dev = encoder->dev; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); ++ struct drm_encoder_helper_funcs *helper = encoder->helper_private; ++ ++ helper->dpms(encoder, DRM_MODE_DPMS_ON); ++ ++ NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", ++ drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), ++ nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); ++} ++ ++void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; ++ ++ if (nv_gf4_disp_arch(dev)) { ++ uint32_t *dac_users = &dev_priv->dac_users[ffs(dcb->or) - 1]; ++ int dacclk_off = NV_PRAMDAC_DACCLK + nv04_dac_output_offset(encoder); ++ uint32_t dacclk = NVReadRAMDAC(dev, 0, dacclk_off); ++ ++ if (enable) { ++ *dac_users |= 1 << dcb->index; ++ NVWriteRAMDAC(dev, 0, dacclk_off, dacclk | NV_PRAMDAC_DACCLK_SEL_DACCLK); ++ ++ } else { ++ *dac_users &= ~(1 << dcb->index); ++ if (!*dac_users) ++ NVWriteRAMDAC(dev, 0, dacclk_off, ++ dacclk & ~NV_PRAMDAC_DACCLK_SEL_DACCLK); ++ } ++ } ++} ++ ++static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ ++ if (nv_encoder->last_dpms == mode) ++ return; ++ nv_encoder->last_dpms = mode; ++ ++ NV_INFO(dev, "Setting dpms mode %d on vga encoder (output %d)\n", ++ mode, nv_encoder->dcb->index); ++ ++ nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); ++} ++ ++static void nv04_dac_save(struct drm_encoder *encoder) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_device *dev = encoder->dev; ++ ++ if (nv_gf4_disp_arch(dev)) ++ nv_encoder->restore.output = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + ++ nv04_dac_output_offset(encoder)); ++} ++ ++static void nv04_dac_restore(struct drm_encoder *encoder) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_device *dev = encoder->dev; ++ ++ if (nv_gf4_disp_arch(dev)) ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + nv04_dac_output_offset(encoder), ++ nv_encoder->restore.output); ++ ++ nv_encoder->last_dpms = NV_DPMS_CLEARED; ++} ++ ++static void nv04_dac_destroy(struct drm_encoder *encoder) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ ++ NV_DEBUG(encoder->dev, "\n"); ++ ++ drm_encoder_cleanup(encoder); ++ kfree(nv_encoder); ++} ++ ++static const struct drm_encoder_helper_funcs nv04_dac_helper_funcs = { ++ .dpms = nv04_dac_dpms, ++ .save = nv04_dac_save, ++ .restore = nv04_dac_restore, ++ .mode_fixup = nv04_dac_mode_fixup, ++ .prepare = nv04_dac_prepare, ++ .commit = nv04_dac_commit, ++ .mode_set = nv04_dac_mode_set, ++ .detect = nv04_dac_detect ++}; ++ ++static const struct drm_encoder_helper_funcs nv17_dac_helper_funcs = { ++ .dpms = nv04_dac_dpms, ++ .save = nv04_dac_save, ++ .restore = nv04_dac_restore, ++ .mode_fixup = nv04_dac_mode_fixup, ++ .prepare = nv04_dac_prepare, ++ .commit = nv04_dac_commit, ++ .mode_set = nv04_dac_mode_set, ++ .detect = nv17_dac_detect ++}; ++ ++static const struct drm_encoder_funcs nv04_dac_funcs = { ++ .destroy = nv04_dac_destroy, ++}; ++ ++int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry) ++{ ++ const struct drm_encoder_helper_funcs *helper; ++ struct drm_encoder *encoder; ++ struct nouveau_encoder *nv_encoder = NULL; ++ ++ nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); ++ if (!nv_encoder) ++ return -ENOMEM; ++ ++ encoder = to_drm_encoder(nv_encoder); ++ ++ nv_encoder->dcb = entry; ++ nv_encoder->or = ffs(entry->or) - 1; ++ ++ if (nv_gf4_disp_arch(dev)) ++ helper = &nv17_dac_helper_funcs; ++ else ++ helper = &nv04_dac_helper_funcs; ++ ++ drm_encoder_init(dev, encoder, &nv04_dac_funcs, DRM_MODE_ENCODER_DAC); ++ drm_encoder_helper_add(encoder, helper); ++ ++ encoder->possible_crtcs = entry->heads; ++ encoder->possible_clones = 0; ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c +new file mode 100644 +index 0000000..e5b3333 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_dfp.c +@@ -0,0 +1,621 @@ ++/* ++ * 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 "drmP.h" ++#include "drm_crtc_helper.h" ++ ++#include "nouveau_drv.h" ++#include "nouveau_encoder.h" ++#include "nouveau_connector.h" ++#include "nouveau_crtc.h" ++#include "nouveau_hw.h" ++#include "nvreg.h" ++ ++#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 inline bool is_fpc_off(uint32_t fpc) ++{ ++ return ((fpc & (FP_TG_CONTROL_ON | FP_TG_CONTROL_OFF)) == ++ FP_TG_CONTROL_OFF); ++} ++ ++int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent) ++{ ++ /* 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 = (dcbent->or & OUTPUT_C) >> 2; ++ ++ NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL, ++ NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | 0x4); ++ return ((NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA) & 0x8) >> 3) ^ ramdac; ++} ++ ++void nv04_dfp_bind_head(struct drm_device *dev, 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(dev, dcbent->or, 0, 0x04, tmds04); ++ ++ if (dl) /* dual link */ ++ nv_write_tmds(dev, dcbent->or, 1, 0x04, tmds04 ^ 0x08); ++} ++ ++void nv04_dfp_disable(struct drm_device *dev, int head) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg; ++ ++ if (NVReadRAMDAC(dev, 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(dev, head, NV_PRAMDAC_FP_TG_CONTROL, ++ FP_TG_CONTROL_OFF); ++ msleep(50); ++ } ++ /* don't inadvertently turn it on when state written later */ ++ crtcstate[head].fp_control = FP_TG_CONTROL_OFF; ++} ++ ++void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_crtc *crtc; ++ struct nouveau_crtc *nv_crtc; ++ uint32_t *fpc; ++ ++ if (mode == DRM_MODE_DPMS_ON) { ++ nv_crtc = nouveau_crtc(encoder->crtc); ++ fpc = &dev_priv->mode_reg.crtc_reg[nv_crtc->index].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 << nouveau_encoder(encoder)->dcb->index; ++ NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_FP_TG_CONTROL, *fpc); ++ } else { ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ nv_crtc = nouveau_crtc(crtc); ++ fpc = &dev_priv->mode_reg.crtc_reg[nv_crtc->index].fp_control; ++ ++ nv_crtc->fp_users &= ~(1 << nouveau_encoder(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(dev, nv_crtc->index, ++ NV_PRAMDAC_FP_TG_CONTROL, *fpc); ++ } ++ } ++ } ++} ++ ++static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder); ++ ++ /* For internal panels and gpu scaling on DVI we need the native mode */ ++ if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) { ++ if (!nv_connector->native_mode) ++ return false; ++ nv_encoder->mode = *nv_connector->native_mode; ++ adjusted_mode->clock = nv_connector->native_mode->clock; ++ } else { ++ nv_encoder->mode = *adjusted_mode; ++ } ++ ++ return true; ++} ++ ++static void nv04_dfp_prepare_sel_clk(struct drm_device *dev, ++ struct nouveau_encoder *nv_encoder, int head) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv04_mode_state *state = &dev_priv->mode_reg; ++ 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 && dev_priv->saved_reg.sel_clk & 0xf0) { ++ int shift = (dev_priv->saved_reg.sel_clk & 0x50) ? 0 : 1; ++ ++ state->sel_clk &= ~0xf0; ++ state->sel_clk |= (head ? 0x40 : 0x10) << shift; ++ } ++} ++ ++static void nv04_dfp_prepare(struct drm_encoder *encoder) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_encoder_helper_funcs *helper = encoder->helper_private; ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int head = nouveau_crtc(encoder->crtc)->index; ++ struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg; ++ 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]; ++ ++ helper->dpms(encoder, DRM_MODE_DPMS_OFF); ++ ++ nv04_dfp_prepare_sel_clk(dev, 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 = 0x3; ++ ++ if (nv_two_heads(dev)) { ++ 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(dev, head ^ 1, ++ NV_CIO_CRE_LCD__INDEX, ++ *cr_lcd_oth); ++ } ++ } ++ } ++ } ++} ++ ++ ++static void nv04_dfp_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); ++ struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; ++ struct nv04_crtc_reg *savep = &dev_priv->saved_reg.crtc_reg[nv_crtc->index]; ++ struct nouveau_connector *nv_connector = nouveau_crtc_connector_get(nv_crtc); ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_display_mode *output_mode = &nv_encoder->mode; ++ uint32_t mode_ratio, panel_ratio; ++ ++ NV_DEBUG(dev, "Output mode on CRTC %d:\n", nv_crtc->index); ++ drm_mode_debug_printmodeline(output_mode); ++ ++ /* Initialize the FP registers in this CRTC. */ ++ regp->fp_horiz_regs[FP_DISPLAY_END] = output_mode->hdisplay - 1; ++ regp->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1; ++ if (!nv_gf4_disp_arch(dev) || ++ (output_mode->hsync_start - output_mode->hdisplay) >= ++ dev_priv->vbios->digital_min_front_porch) ++ regp->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay; ++ else ++ regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios->digital_min_front_porch - 1; ++ regp->fp_horiz_regs[FP_SYNC_START] = output_mode->hsync_start - 1; ++ regp->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1; ++ regp->fp_horiz_regs[FP_VALID_START] = output_mode->hskew; ++ regp->fp_horiz_regs[FP_VALID_END] = output_mode->hdisplay - 1; ++ ++ regp->fp_vert_regs[FP_DISPLAY_END] = output_mode->vdisplay - 1; ++ regp->fp_vert_regs[FP_TOTAL] = output_mode->vtotal - 1; ++ regp->fp_vert_regs[FP_CRTC] = output_mode->vtotal - 5 - 1; ++ regp->fp_vert_regs[FP_SYNC_START] = output_mode->vsync_start - 1; ++ regp->fp_vert_regs[FP_SYNC_END] = output_mode->vsync_end - 1; ++ regp->fp_vert_regs[FP_VALID_START] = 0; ++ regp->fp_vert_regs[FP_VALID_END] = output_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 (output_mode->flags & DRM_MODE_FLAG_PVSYNC) ++ regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS; ++ if (output_mode->flags & DRM_MODE_FLAG_PHSYNC) ++ regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS; ++ /* panel scaling first, as native would get set otherwise */ ++ if (nv_connector->scaling_mode == DRM_MODE_SCALE_NONE || ++ nv_connector->scaling_mode == DRM_MODE_SCALE_CENTER) /* panel handles it */ ++ regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_CENTER; ++ else if (adjusted_mode->hdisplay == output_mode->hdisplay && ++ adjusted_mode->vdisplay == output_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(dev, 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 && ++ output_mode->clock > 165000) ++ regp->fp_control |= (2 << 24); ++ if (nv_encoder->dcb->type == OUTPUT_LVDS) { ++ bool duallink, dummy; ++ ++ nouveau_bios_parse_lvds_table(dev, nv_connector->native_mode-> ++ clock, &duallink, &dummy); ++ if (duallink) ++ regp->fp_control |= (8 << 28); ++ } else ++ if (output_mode->clock > 165000) ++ 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) * adjusted_mode->hdisplay / adjusted_mode->vdisplay; ++ panel_ratio = (1 << 12) * output_mode->hdisplay / output_mode->vdisplay; ++ /* if ratios are equal, SCALE_ASPECT will automatically (and correctly) ++ * get treated the same as SCALE_FULLSCREEN */ ++ if (nv_connector->scaling_mode == DRM_MODE_SCALE_ASPECT && ++ mode_ratio != panel_ratio) { ++ uint32_t diff, scale; ++ bool divide_by_2 = nv_gf4_disp_arch(dev); ++ ++ 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) * adjusted_mode->vdisplay / output_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 = output_mode->hdisplay - ++ output_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) * adjusted_mode->hdisplay / output_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 = output_mode->vdisplay - ++ (1 << 12) * output_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_connector->use_dithering) { ++ if (dev_priv->chipset == 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 (dev_priv->chipset != 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; ++ } ++ ++ regp->fp_margin_color = 0; ++} ++ ++static void nv04_dfp_commit(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_encoder_helper_funcs *helper = encoder->helper_private; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct dcb_entry *dcbe = nv_encoder->dcb; ++ int head = nouveau_crtc(encoder->crtc)->index; ++ ++ NV_TRACE(dev, "%s called for encoder %d\n", __func__, nv_encoder->dcb->index); ++ ++ if (dcbe->type == OUTPUT_TMDS) ++ run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); ++ else if (dcbe->type == OUTPUT_LVDS) ++ call_lvds_script(dev, dcbe, head, LVDS_RESET, nv_encoder->mode.clock); ++ ++ /* update fp_control state for any changes made by scripts, ++ * so correct value is written at DPMS on */ ++ dev_priv->mode_reg.crtc_reg[head].fp_control = ++ NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL); ++ ++ /* This could use refinement for flatpanels, but it should work this way */ ++ if (dev_priv->chipset < 0x44) ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0xf0000000); ++ else ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); ++ ++ helper->dpms(encoder, DRM_MODE_DPMS_ON); ++ ++ NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", ++ drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), ++ nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); ++} ++ ++static inline bool is_powersaving_dpms(int mode) ++{ ++ return (mode != DRM_MODE_DPMS_ON); ++} ++ ++static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_crtc *crtc = encoder->crtc; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ bool was_powersaving = is_powersaving_dpms(nv_encoder->last_dpms); ++ ++ if (nv_encoder->last_dpms == mode) ++ return; ++ nv_encoder->last_dpms = mode; ++ ++ NV_INFO(dev, "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) { ++ struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder); ++ ++ /* when removing an output, crtc may not be set, but PANEL_OFF ++ * must still be run ++ */ ++ int head = crtc ? nouveau_crtc(crtc)->index : ++ nv04_dfp_get_bound_head(dev, nv_encoder->dcb); ++ ++ if (mode == DRM_MODE_DPMS_ON) { ++ if (!nv_connector->native_mode) { ++ NV_ERROR(dev, "Not turning on LVDS without native mode\n"); ++ return; ++ } ++ call_lvds_script(dev, nv_encoder->dcb, head, ++ LVDS_PANEL_ON, nv_connector->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(dev, nv_encoder->dcb, head, ++ LVDS_PANEL_OFF, 0); ++ } ++ ++ nv04_dfp_update_fp_control(encoder, mode); ++ ++ if (mode == DRM_MODE_DPMS_ON) ++ nv04_dfp_prepare_sel_clk(dev, nv_encoder, nouveau_crtc(crtc)->index); ++ else { ++ dev_priv->mode_reg.sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK); ++ dev_priv->mode_reg.sel_clk &= ~0xf0; ++ } ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, dev_priv->mode_reg.sel_clk); ++} ++ ++static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ ++ if (nv_encoder->last_dpms == mode) ++ return; ++ nv_encoder->last_dpms = mode; ++ ++ NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", ++ mode, nv_encoder->dcb->index); ++ ++ nv04_dfp_update_fp_control(encoder, mode); ++} ++ ++static void nv04_dfp_save(struct drm_encoder *encoder) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_device *dev = encoder->dev; ++ ++ if (nv_two_heads(dev)) ++ nv_encoder->restore.head = ++ nv04_dfp_get_bound_head(dev, nv_encoder->dcb); ++} ++ ++static void nv04_dfp_restore(struct drm_encoder *encoder) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int head = nv_encoder->restore.head; ++ ++ if (nv_encoder->dcb->type == OUTPUT_LVDS) { ++ struct drm_display_mode *native_mode = nouveau_encoder_connector_get(nv_encoder)->native_mode; ++ if (native_mode) ++ call_lvds_script(dev, nv_encoder->dcb, head, LVDS_PANEL_ON, ++ native_mode->clock); ++ else ++ NV_ERROR(dev, "Not restoring LVDS without native mode\n"); ++ ++ } else if (nv_encoder->dcb->type == OUTPUT_TMDS) { ++ int clock = nouveau_hw_pllvals_to_clk ++ (&dev_priv->saved_reg.crtc_reg[head].pllvals); ++ ++ run_tmds_table(dev, nv_encoder->dcb, head, clock); ++ } ++ ++ nv_encoder->last_dpms = NV_DPMS_CLEARED; ++} ++ ++static void nv04_dfp_destroy(struct drm_encoder *encoder) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ ++ NV_DEBUG(encoder->dev, "\n"); ++ ++ drm_encoder_cleanup(encoder); ++ kfree(nv_encoder); ++} ++ ++static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = { ++ .dpms = nv04_lvds_dpms, ++ .save = nv04_dfp_save, ++ .restore = nv04_dfp_restore, ++ .mode_fixup = nv04_dfp_mode_fixup, ++ .prepare = nv04_dfp_prepare, ++ .commit = nv04_dfp_commit, ++ .mode_set = nv04_dfp_mode_set, ++ .detect = NULL, ++}; ++ ++static const struct drm_encoder_helper_funcs nv04_tmds_helper_funcs = { ++ .dpms = nv04_tmds_dpms, ++ .save = nv04_dfp_save, ++ .restore = nv04_dfp_restore, ++ .mode_fixup = nv04_dfp_mode_fixup, ++ .prepare = nv04_dfp_prepare, ++ .commit = nv04_dfp_commit, ++ .mode_set = nv04_dfp_mode_set, ++ .detect = NULL, ++}; ++ ++static const struct drm_encoder_funcs nv04_dfp_funcs = { ++ .destroy = nv04_dfp_destroy, ++}; ++ ++int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry) ++{ ++ const struct drm_encoder_helper_funcs *helper; ++ struct drm_encoder *encoder; ++ struct nouveau_encoder *nv_encoder = NULL; ++ int type; ++ ++ switch (entry->type) { ++ case OUTPUT_TMDS: ++ type = DRM_MODE_ENCODER_TMDS; ++ helper = &nv04_tmds_helper_funcs; ++ break; ++ case OUTPUT_LVDS: ++ type = DRM_MODE_ENCODER_LVDS; ++ helper = &nv04_lvds_helper_funcs; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); ++ if (!nv_encoder) ++ return -ENOMEM; ++ ++ encoder = to_drm_encoder(nv_encoder); ++ ++ nv_encoder->dcb = entry; ++ nv_encoder->or = ffs(entry->or) - 1; ++ ++ drm_encoder_init(dev, encoder, &nv04_dfp_funcs, type); ++ drm_encoder_helper_add(encoder, helper); ++ ++ encoder->possible_crtcs = entry->heads; ++ encoder->possible_clones = 0; ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c +new file mode 100644 +index 0000000..2db7829 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_display.c +@@ -0,0 +1,293 @@ ++/* ++ * Copyright 2009 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. ++ * ++ * Author: Ben Skeggs ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "drm_crtc_helper.h" ++ ++#include "nouveau_drv.h" ++#include "nouveau_fb.h" ++#include "nouveau_hw.h" ++#include "nouveau_encoder.h" ++#include "nouveau_connector.h" ++ ++#define MULTIPLE_ENCODERS(e) (e & (e - 1)) ++ ++static void ++nv04_display_store_initial_head_owner(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->chipset != 0x11) { ++ dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44); ++ goto ownerknown; ++ } ++ ++ /* reading CR44 is broken on nv11, so we attempt to infer it */ ++ if (nvReadMC(dev, NV_PBUS_DEBUG_1) & (1 << 28)) /* heads tied, restore both */ ++ dev_priv->crtc_owner = 0x4; ++ else { ++ uint8_t slaved_on_A, slaved_on_B; ++ bool tvA = false; ++ bool tvB = false; ++ ++ NVLockVgaCrtcs(dev, false); ++ ++ slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) & ++ 0x80; ++ if (slaved_on_B) ++ tvB = !(NVReadVgaCrtc(dev, 1, NV_CIO_CRE_LCD__INDEX) & ++ MASK(NV_CIO_CRE_LCD_LCD_SELECT)); ++ ++ slaved_on_A = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX) & ++ 0x80; ++ if (slaved_on_A) ++ tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) & ++ MASK(NV_CIO_CRE_LCD_LCD_SELECT)); ++ ++ NVLockVgaCrtcs(dev, true); ++ ++ if (slaved_on_A && !tvA) ++ dev_priv->crtc_owner = 0x0; ++ else if (slaved_on_B && !tvB) ++ dev_priv->crtc_owner = 0x3; ++ else if (slaved_on_A) ++ dev_priv->crtc_owner = 0x0; ++ else if (slaved_on_B) ++ dev_priv->crtc_owner = 0x3; ++ else ++ dev_priv->crtc_owner = 0x0; ++ } ++ ++ownerknown: ++ NV_INFO(dev, "Initial CRTC_OWNER is %d\n", dev_priv->crtc_owner); ++ ++ /* 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(dev, 0); ++} ++ ++int ++nv04_display_create(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct parsed_dcb *dcb = dev_priv->vbios->dcb; ++ struct drm_encoder *encoder; ++ struct drm_crtc *crtc; ++ uint16_t connector[16] = { 0 }; ++ int i, ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (nv_two_heads(dev)) ++ nv04_display_store_initial_head_owner(dev); ++ ++ drm_mode_config_init(dev); ++ drm_mode_create_scaling_mode_property(dev); ++ drm_mode_create_dithering_property(dev); ++ ++ dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs; ++ ++ dev->mode_config.min_width = 0; ++ dev->mode_config.min_height = 0; ++ switch (dev_priv->card_type) { ++ case NV_04: ++ dev->mode_config.max_width = 2048; ++ dev->mode_config.max_height = 2048; ++ break; ++ default: ++ dev->mode_config.max_width = 4096; ++ dev->mode_config.max_height = 4096; ++ break; ++ } ++ ++ dev->mode_config.fb_base = dev_priv->fb_phys; ++ ++ nv04_crtc_create(dev, 0); ++ if (nv_two_heads(dev)) ++ nv04_crtc_create(dev, 1); ++ ++ for (i = 0; i < dcb->entries; i++) { ++ struct dcb_entry *dcbent = &dcb->entry[i]; ++ ++ switch (dcbent->type) { ++ case OUTPUT_ANALOG: ++ ret = nv04_dac_create(dev, dcbent); ++ break; ++ case OUTPUT_LVDS: ++ case OUTPUT_TMDS: ++ ret = nv04_dfp_create(dev, dcbent); ++ break; ++ case OUTPUT_TV: ++ if (!nouveau_tv) { ++ NV_INFO(dev, "Enable TV-Out with tv module option\n"); ++ continue; ++ } ++ ++ if (dcbent->location == DCB_LOC_ON_CHIP) ++ ret = nv17_tv_create(dev, dcbent); ++ else ++ ret = nv04_tv_create(dev, dcbent); ++ break; ++ default: ++ NV_WARN(dev, "DCB type %d not known\n", dcbent->type); ++ continue; ++ } ++ ++ if (ret) ++ continue; ++ ++ connector[dcbent->connector] |= (1 << dcbent->type); ++ } ++ ++ for (i = 0; i < dcb->entries; i++) { ++ struct dcb_entry *dcbent = &dcb->entry[i]; ++ uint16_t encoders; ++ int type; ++ ++ encoders = connector[dcbent->connector]; ++ if (!(encoders & (1 << dcbent->type))) ++ continue; ++ connector[dcbent->connector] = 0; ++ ++ switch (dcbent->type) { ++ case OUTPUT_ANALOG: ++ if (!MULTIPLE_ENCODERS(encoders)) ++ type = DRM_MODE_CONNECTOR_VGA; ++ else ++ type = DRM_MODE_CONNECTOR_DVII; ++ break; ++ case OUTPUT_TMDS: ++ if (!MULTIPLE_ENCODERS(encoders)) ++ type = DRM_MODE_CONNECTOR_DVID; ++ else ++ type = DRM_MODE_CONNECTOR_DVII; ++ break; ++ case OUTPUT_LVDS: ++ type = DRM_MODE_CONNECTOR_LVDS; ++#if 0 ++ /* don't create i2c adapter when lvds ddc not allowed */ ++ if (dcbent->lvdsconf.use_straps_for_mode || ++ dev_priv->vbios->fp_no_ddc) ++ i2c_index = 0xf; ++#endif ++ break; ++ case OUTPUT_TV: ++ type = DRM_MODE_CONNECTOR_TV; ++ break; ++ default: ++ type = DRM_MODE_CONNECTOR_Unknown; ++ continue; ++ } ++ ++ nouveau_connector_create(dev, dcbent->connector, type); ++ } ++ ++ /* Save previous state */ ++ NVLockVgaCrtcs(dev, false); ++ ++ nouveau_hw_save_vga_fonts(dev, 1); ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) ++ crtc->funcs->save(crtc); ++ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ struct drm_encoder_helper_funcs *func = encoder->helper_private; ++ ++ func->save(encoder); ++ } ++ ++ return 0; ++} ++ ++void ++nv04_display_destroy(struct drm_device *dev) ++{ ++ struct drm_encoder *encoder; ++ struct drm_crtc *crtc; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ /* Turn every CRTC off. */ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ++ struct drm_mode_set modeset = { ++ .crtc = crtc, ++ }; ++ ++ crtc->funcs->set_config(&modeset); ++ } ++ ++ /* Restore state */ ++ NVLockVgaCrtcs(dev, false); ++ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ struct drm_encoder_helper_funcs *func = encoder->helper_private; ++ ++ func->restore(encoder); ++ } ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) ++ crtc->funcs->restore(crtc); ++ ++ nouveau_hw_save_vga_fonts(dev, 0); ++ ++ drm_mode_config_cleanup(dev); ++} ++ ++void ++nv04_display_restore(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_encoder *encoder; ++ struct drm_crtc *crtc; ++ ++ NVLockVgaCrtcs(dev, false); ++ ++ /* meh.. modeset apparently doesn't setup all the regs and depends ++ * on pre-existing state, for now load the state of the card *before* ++ * nouveau was loaded, and then do a modeset. ++ * ++ * best thing to do probably is to make save/restore routines not ++ * save/restore "pre-load" state, but more general so we can save ++ * on suspend too. ++ */ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ struct drm_encoder_helper_funcs *func = encoder->helper_private; ++ ++ func->restore(encoder); ++ } ++ ++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) ++ crtc->funcs->restore(crtc); ++ ++ if (nv_two_heads(dev)) { ++ NV_INFO(dev, "Restoring CRTC_OWNER to %d.\n", ++ dev_priv->crtc_owner); ++ NVSetOwner(dev, dev_priv->crtc_owner); ++ } ++ ++ NVLockVgaCrtcs(dev, true); ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv04_fb.c b/drivers/gpu/drm/nouveau/nv04_fb.c +new file mode 100644 +index 0000000..638cf60 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_fb.c +@@ -0,0 +1,21 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++int ++nv04_fb_init(struct drm_device *dev) ++{ ++ /* This is what the DDX did for NV_ARCH_04, but a mmio-trace shows ++ * nvidia reading PFB_CFG_0, then writing back its original value. ++ * (which was 0x701114 in this case) ++ */ ++ ++ nv_wr32(dev, NV04_PFB_CFG0, 0x1114); ++ return 0; ++} ++ ++void ++nv04_fb_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c +new file mode 100644 +index 0000000..09a3107 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c +@@ -0,0 +1,316 @@ ++/* ++ * Copyright 2009 Ben Skeggs ++ * 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 (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 "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++#include "nouveau_fbcon.h" ++ ++static void ++nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->channel; ++ ++ if (info->state != FBINFO_STATE_RUNNING) ++ return; ++ ++ if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 4)) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ } ++ ++ if (info->flags & FBINFO_HWACCEL_DISABLED) { ++ cfb_copyarea(info, region); ++ return; ++ } ++ ++ BEGIN_RING(chan, NvSubImageBlit, 0x0300, 3); ++ OUT_RING(chan, (region->sy << 16) | region->sx); ++ OUT_RING(chan, (region->dy << 16) | region->dx); ++ OUT_RING(chan, (region->height << 16) | region->width); ++ FIRE_RING(chan); ++} ++ ++static void ++nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->channel; ++ uint32_t color = ((uint32_t *) info->pseudo_palette)[rect->color]; ++ ++ if (info->state != FBINFO_STATE_RUNNING) ++ return; ++ ++ if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 7)) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ } ++ ++ if (info->flags & FBINFO_HWACCEL_DISABLED) { ++ cfb_fillrect(info, rect); ++ return; ++ } ++ ++ BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1); ++ OUT_RING(chan, (rect->rop != ROP_COPY) ? 1 : 3); ++ BEGIN_RING(chan, NvSubGdiRect, 0x03fc, 1); ++ OUT_RING(chan, color); ++ BEGIN_RING(chan, NvSubGdiRect, 0x0400, 2); ++ OUT_RING(chan, (rect->dx << 16) | rect->dy); ++ OUT_RING(chan, (rect->width << 16) | rect->height); ++ FIRE_RING(chan); ++} ++ ++static void ++nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->channel; ++ uint32_t fg; ++ uint32_t bg; ++ uint32_t dsize; ++ uint32_t width; ++ uint32_t *data = (uint32_t *)image->data; ++ ++ if (info->state != FBINFO_STATE_RUNNING) ++ return; ++ ++ if (image->depth != 1) { ++ cfb_imageblit(info, image); ++ return; ++ } ++ ++ if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 8)) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ } ++ ++ if (info->flags & FBINFO_HWACCEL_DISABLED) { ++ cfb_imageblit(info, image); ++ return; ++ } ++ ++ width = (image->width + 31) & ~31; ++ dsize = (width * image->height) >> 5; ++ ++ if (info->fix.visual == FB_VISUAL_TRUECOLOR || ++ info->fix.visual == FB_VISUAL_DIRECTCOLOR) { ++ fg = ((uint32_t *) info->pseudo_palette)[image->fg_color]; ++ bg = ((uint32_t *) info->pseudo_palette)[image->bg_color]; ++ } else { ++ fg = image->fg_color; ++ bg = image->bg_color; ++ } ++ ++ BEGIN_RING(chan, NvSubGdiRect, 0x0be4, 7); ++ OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); ++ OUT_RING(chan, ((image->dy + image->height) << 16) | ++ ((image->dx + image->width) & 0xffff)); ++ OUT_RING(chan, bg); ++ OUT_RING(chan, fg); ++ OUT_RING(chan, (image->height << 16) | image->width); ++ OUT_RING(chan, (image->height << 16) | width); ++ OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); ++ ++ while (dsize) { ++ int iter_len = dsize > 128 ? 128 : dsize; ++ ++ if (RING_SPACE(chan, iter_len + 1)) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ cfb_imageblit(info, image); ++ return; ++ } ++ ++ BEGIN_RING(chan, NvSubGdiRect, 0x0c00, iter_len); ++ OUT_RINGp(chan, data, iter_len); ++ data += iter_len; ++ dsize -= iter_len; ++ } ++ ++ FIRE_RING(chan); ++} ++ ++static int ++nv04_fbcon_grobj_new(struct drm_device *dev, int class, uint32_t handle) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *obj = NULL; ++ int ret; ++ ++ ret = nouveau_gpuobj_gr_new(dev_priv->channel, class, &obj); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, handle, obj, NULL); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++int ++nv04_fbcon_accel_init(struct fb_info *info) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->channel; ++ int surface_fmt, pattern_fmt, rect_fmt; ++ int ret; ++ ++ switch (info->var.bits_per_pixel) { ++ case 8: ++ surface_fmt = 1; ++ pattern_fmt = 3; ++ rect_fmt = 3; ++ break; ++ case 16: ++ surface_fmt = 4; ++ pattern_fmt = 1; ++ rect_fmt = 1; ++ break; ++ case 32: ++ switch (info->var.transp.length) { ++ case 0: /* depth 24 */ ++ case 8: /* depth 32 */ ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ surface_fmt = 6; ++ pattern_fmt = 3; ++ rect_fmt = 3; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ ret = nv04_fbcon_grobj_new(dev, dev_priv->card_type >= NV_10 ? ++ 0x0062 : 0x0042, NvCtxSurf2D); ++ if (ret) ++ return ret; ++ ++ ret = nv04_fbcon_grobj_new(dev, 0x0019, NvClipRect); ++ if (ret) ++ return ret; ++ ++ ret = nv04_fbcon_grobj_new(dev, 0x0043, NvRop); ++ if (ret) ++ return ret; ++ ++ ret = nv04_fbcon_grobj_new(dev, 0x0044, NvImagePatt); ++ if (ret) ++ return ret; ++ ++ ret = nv04_fbcon_grobj_new(dev, 0x004a, NvGdiRect); ++ if (ret) ++ return ret; ++ ++ ret = nv04_fbcon_grobj_new(dev, dev_priv->card_type >= NV_10 ? ++ 0x009f : 0x005f, NvImageBlit); ++ if (ret) ++ return ret; ++ ++ if (RING_SPACE(chan, 49)) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ return 0; ++ } ++ ++ BEGIN_RING(chan, 1, 0x0000, 1); ++ OUT_RING(chan, NvCtxSurf2D); ++ BEGIN_RING(chan, 1, 0x0184, 2); ++ OUT_RING(chan, NvDmaFB); ++ OUT_RING(chan, NvDmaFB); ++ BEGIN_RING(chan, 1, 0x0300, 4); ++ OUT_RING(chan, surface_fmt); ++ OUT_RING(chan, info->fix.line_length | (info->fix.line_length << 16)); ++ OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base); ++ OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base); ++ ++ BEGIN_RING(chan, 1, 0x0000, 1); ++ OUT_RING(chan, NvRop); ++ BEGIN_RING(chan, 1, 0x0300, 1); ++ OUT_RING(chan, 0x55); ++ ++ BEGIN_RING(chan, 1, 0x0000, 1); ++ OUT_RING(chan, NvImagePatt); ++ BEGIN_RING(chan, 1, 0x0300, 8); ++ OUT_RING(chan, pattern_fmt); ++#ifdef __BIG_ENDIAN ++ OUT_RING(chan, 2); ++#else ++ OUT_RING(chan, 1); ++#endif ++ OUT_RING(chan, 0); ++ OUT_RING(chan, 1); ++ OUT_RING(chan, ~0); ++ OUT_RING(chan, ~0); ++ OUT_RING(chan, ~0); ++ OUT_RING(chan, ~0); ++ ++ BEGIN_RING(chan, 1, 0x0000, 1); ++ OUT_RING(chan, NvClipRect); ++ BEGIN_RING(chan, 1, 0x0300, 2); ++ OUT_RING(chan, 0); ++ OUT_RING(chan, (info->var.yres_virtual << 16) | info->var.xres_virtual); ++ ++ BEGIN_RING(chan, NvSubImageBlit, 0x0000, 1); ++ OUT_RING(chan, NvImageBlit); ++ BEGIN_RING(chan, NvSubImageBlit, 0x019c, 1); ++ OUT_RING(chan, NvCtxSurf2D); ++ BEGIN_RING(chan, NvSubImageBlit, 0x02fc, 1); ++ OUT_RING(chan, 3); ++ ++ BEGIN_RING(chan, NvSubGdiRect, 0x0000, 1); ++ OUT_RING(chan, NvGdiRect); ++ BEGIN_RING(chan, NvSubGdiRect, 0x0198, 1); ++ OUT_RING(chan, NvCtxSurf2D); ++ BEGIN_RING(chan, NvSubGdiRect, 0x0188, 2); ++ OUT_RING(chan, NvImagePatt); ++ OUT_RING(chan, NvRop); ++ BEGIN_RING(chan, NvSubGdiRect, 0x0304, 1); ++ OUT_RING(chan, 1); ++ BEGIN_RING(chan, NvSubGdiRect, 0x0300, 1); ++ OUT_RING(chan, rect_fmt); ++ BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1); ++ OUT_RING(chan, 3); ++ ++ FIRE_RING(chan); ++ ++ info->fbops->fb_fillrect = nv04_fbcon_fillrect; ++ info->fbops->fb_copyarea = nv04_fbcon_copyarea; ++ info->fbops->fb_imageblit = nv04_fbcon_imageblit; ++ return 0; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c +new file mode 100644 +index 0000000..0c3cd53 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_fifo.c +@@ -0,0 +1,271 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++#define NV04_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV04_RAMFC__SIZE)) ++#define NV04_RAMFC__SIZE 32 ++#define NV04_RAMFC_DMA_PUT 0x00 ++#define NV04_RAMFC_DMA_GET 0x04 ++#define NV04_RAMFC_DMA_INSTANCE 0x08 ++#define NV04_RAMFC_DMA_STATE 0x0C ++#define NV04_RAMFC_DMA_FETCH 0x10 ++#define NV04_RAMFC_ENGINE 0x14 ++#define NV04_RAMFC_PULL1_ENGINE 0x18 ++ ++#define RAMFC_WR(offset, val) nv_wo32(dev, chan->ramfc->gpuobj, \ ++ NV04_RAMFC_##offset/4, (val)) ++#define RAMFC_RD(offset) nv_ro32(dev, chan->ramfc->gpuobj, \ ++ NV04_RAMFC_##offset/4) ++ ++void ++nv04_fifo_disable(struct drm_device *dev) ++{ ++ uint32_t tmp; ++ ++ tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, tmp & ~1); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 0); ++ tmp = nv_rd32(dev, NV03_PFIFO_CACHE1_PULL1); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, tmp & ~1); ++} ++ ++void ++nv04_fifo_enable(struct drm_device *dev) ++{ ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 1); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1); ++} ++ ++bool ++nv04_fifo_reassign(struct drm_device *dev, bool enable) ++{ ++ uint32_t reassign = nv_rd32(dev, NV03_PFIFO_CACHES); ++ ++ nv_wr32(dev, NV03_PFIFO_CACHES, enable ? 1 : 0); ++ return (reassign == 1); ++} ++ ++int ++nv04_fifo_channel_id(struct drm_device *dev) ++{ ++ return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & ++ NV03_PFIFO_CACHE1_PUSH1_CHID_MASK; ++} ++ ++int ++nv04_fifo_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int ret; ++ ++ ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0, ++ NV04_RAMFC__SIZE, ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, ++ NULL, &chan->ramfc); ++ if (ret) ++ return ret; ++ ++ /* Setup initial state */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ RAMFC_WR(DMA_PUT, chan->pushbuf_base); ++ RAMFC_WR(DMA_GET, chan->pushbuf_base); ++ RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4); ++ RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | ++#ifdef __BIG_ENDIAN ++ NV_PFIFO_CACHE1_BIG_ENDIAN | ++#endif ++ 0)); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ /* enable the fifo dma operation */ ++ nv_wr32(dev, NV04_PFIFO_MODE, ++ nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); ++ return 0; ++} ++ ++void ++nv04_fifo_destroy_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ ++ nv_wr32(dev, NV04_PFIFO_MODE, ++ nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id)); ++ ++ nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++} ++ ++static void ++nv04_fifo_do_load_context(struct drm_device *dev, int chid) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t fc = NV04_RAMFC(chid), tmp; ++ ++ dev_priv->engine.instmem.prepare_access(dev, false); ++ ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); ++ tmp = nv_ri32(dev, fc + 8); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, tmp & 0xFFFF); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, tmp >> 16); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 12)); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, nv_ri32(dev, fc + 16)); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 20)); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 24)); ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); ++} ++ ++int ++nv04_fifo_load_context(struct nouveau_channel *chan) ++{ ++ uint32_t tmp; ++ ++ nv_wr32(chan->dev, NV03_PFIFO_CACHE1_PUSH1, ++ NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id); ++ nv04_fifo_do_load_context(chan->dev, chan->id); ++ nv_wr32(chan->dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1); ++ ++ /* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */ ++ tmp = nv_rd32(chan->dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31); ++ nv_wr32(chan->dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp); ++ ++ return 0; ++} ++ ++int ++nv04_fifo_unload_context(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; ++ struct nouveau_channel *chan = NULL; ++ uint32_t tmp; ++ int chid; ++ ++ chid = pfifo->channel_id(dev); ++ if (chid < 0 || chid >= dev_priv->engine.fifo.channels) ++ return 0; ++ ++ chan = dev_priv->fifos[chid]; ++ if (!chan) { ++ NV_ERROR(dev, "Inactive channel on PFIFO: %d\n", chid); ++ return -EINVAL; ++ } ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ RAMFC_WR(DMA_PUT, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); ++ RAMFC_WR(DMA_GET, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); ++ tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16; ++ tmp |= nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE); ++ RAMFC_WR(DMA_INSTANCE, tmp); ++ RAMFC_WR(DMA_STATE, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE)); ++ RAMFC_WR(DMA_FETCH, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH)); ++ RAMFC_WR(ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE)); ++ RAMFC_WR(PULL1_ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1)); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv04_fifo_do_load_context(dev, pfifo->channels - 1); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); ++ return 0; ++} ++ ++static void ++nv04_fifo_init_reset(struct drm_device *dev) ++{ ++ nv_wr32(dev, NV03_PMC_ENABLE, ++ nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO); ++ nv_wr32(dev, NV03_PMC_ENABLE, ++ nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PFIFO); ++ ++ nv_wr32(dev, 0x003224, 0x000f0078); ++ nv_wr32(dev, 0x002044, 0x0101ffff); ++ nv_wr32(dev, 0x002040, 0x000000ff); ++ nv_wr32(dev, 0x002500, 0x00000000); ++ nv_wr32(dev, 0x003000, 0x00000000); ++ nv_wr32(dev, 0x003050, 0x00000000); ++ nv_wr32(dev, 0x003200, 0x00000000); ++ nv_wr32(dev, 0x003250, 0x00000000); ++ nv_wr32(dev, 0x003220, 0x00000000); ++ ++ nv_wr32(dev, 0x003250, 0x00000000); ++ nv_wr32(dev, 0x003270, 0x00000000); ++ nv_wr32(dev, 0x003210, 0x00000000); ++} ++ ++static void ++nv04_fifo_init_ramxx(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | ++ ((dev_priv->ramht_bits - 9) << 16) | ++ (dev_priv->ramht_offset >> 8)); ++ nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8); ++ nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc_offset >> 8); ++} ++ ++static void ++nv04_fifo_init_intr(struct drm_device *dev) ++{ ++ nv_wr32(dev, 0x002100, 0xffffffff); ++ nv_wr32(dev, 0x002140, 0xffffffff); ++} ++ ++int ++nv04_fifo_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; ++ int i; ++ ++ nv04_fifo_init_reset(dev); ++ nv04_fifo_init_ramxx(dev); ++ ++ nv04_fifo_do_load_context(dev, pfifo->channels - 1); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); ++ ++ nv04_fifo_init_intr(dev); ++ pfifo->enable(dev); ++ ++ for (i = 0; i < dev_priv->engine.fifo.channels; i++) { ++ if (dev_priv->fifos[i]) { ++ uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE); ++ nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i)); ++ } ++ } ++ ++ return 0; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c +new file mode 100644 +index 0000000..396ee92 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_graph.c +@@ -0,0 +1,579 @@ ++/* ++ * Copyright 2007 Stephane Marchesin ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++#include "nouveau_drm.h" ++#include "nouveau_drv.h" ++ ++static uint32_t nv04_graph_ctx_regs[] = { ++ NV04_PGRAPH_CTX_SWITCH1, ++ NV04_PGRAPH_CTX_SWITCH2, ++ NV04_PGRAPH_CTX_SWITCH3, ++ NV04_PGRAPH_CTX_SWITCH4, ++ NV04_PGRAPH_CTX_CACHE1, ++ NV04_PGRAPH_CTX_CACHE2, ++ NV04_PGRAPH_CTX_CACHE3, ++ NV04_PGRAPH_CTX_CACHE4, ++ 0x00400184, ++ 0x004001a4, ++ 0x004001c4, ++ 0x004001e4, ++ 0x00400188, ++ 0x004001a8, ++ 0x004001c8, ++ 0x004001e8, ++ 0x0040018c, ++ 0x004001ac, ++ 0x004001cc, ++ 0x004001ec, ++ 0x00400190, ++ 0x004001b0, ++ 0x004001d0, ++ 0x004001f0, ++ 0x00400194, ++ 0x004001b4, ++ 0x004001d4, ++ 0x004001f4, ++ 0x00400198, ++ 0x004001b8, ++ 0x004001d8, ++ 0x004001f8, ++ 0x0040019c, ++ 0x004001bc, ++ 0x004001dc, ++ 0x004001fc, ++ 0x00400174, ++ NV04_PGRAPH_DMA_START_0, ++ NV04_PGRAPH_DMA_START_1, ++ NV04_PGRAPH_DMA_LENGTH, ++ NV04_PGRAPH_DMA_MISC, ++ NV04_PGRAPH_DMA_PITCH, ++ NV04_PGRAPH_BOFFSET0, ++ NV04_PGRAPH_BBASE0, ++ NV04_PGRAPH_BLIMIT0, ++ NV04_PGRAPH_BOFFSET1, ++ NV04_PGRAPH_BBASE1, ++ NV04_PGRAPH_BLIMIT1, ++ NV04_PGRAPH_BOFFSET2, ++ NV04_PGRAPH_BBASE2, ++ NV04_PGRAPH_BLIMIT2, ++ NV04_PGRAPH_BOFFSET3, ++ NV04_PGRAPH_BBASE3, ++ NV04_PGRAPH_BLIMIT3, ++ NV04_PGRAPH_BOFFSET4, ++ NV04_PGRAPH_BBASE4, ++ NV04_PGRAPH_BLIMIT4, ++ NV04_PGRAPH_BOFFSET5, ++ NV04_PGRAPH_BBASE5, ++ NV04_PGRAPH_BLIMIT5, ++ NV04_PGRAPH_BPITCH0, ++ NV04_PGRAPH_BPITCH1, ++ NV04_PGRAPH_BPITCH2, ++ NV04_PGRAPH_BPITCH3, ++ NV04_PGRAPH_BPITCH4, ++ NV04_PGRAPH_SURFACE, ++ NV04_PGRAPH_STATE, ++ NV04_PGRAPH_BSWIZZLE2, ++ NV04_PGRAPH_BSWIZZLE5, ++ NV04_PGRAPH_BPIXEL, ++ NV04_PGRAPH_NOTIFY, ++ NV04_PGRAPH_PATT_COLOR0, ++ NV04_PGRAPH_PATT_COLOR1, ++ NV04_PGRAPH_PATT_COLORRAM+0x00, ++ NV04_PGRAPH_PATT_COLORRAM+0x01, ++ NV04_PGRAPH_PATT_COLORRAM+0x02, ++ NV04_PGRAPH_PATT_COLORRAM+0x03, ++ NV04_PGRAPH_PATT_COLORRAM+0x04, ++ NV04_PGRAPH_PATT_COLORRAM+0x05, ++ NV04_PGRAPH_PATT_COLORRAM+0x06, ++ NV04_PGRAPH_PATT_COLORRAM+0x07, ++ NV04_PGRAPH_PATT_COLORRAM+0x08, ++ NV04_PGRAPH_PATT_COLORRAM+0x09, ++ NV04_PGRAPH_PATT_COLORRAM+0x0A, ++ NV04_PGRAPH_PATT_COLORRAM+0x0B, ++ NV04_PGRAPH_PATT_COLORRAM+0x0C, ++ NV04_PGRAPH_PATT_COLORRAM+0x0D, ++ NV04_PGRAPH_PATT_COLORRAM+0x0E, ++ NV04_PGRAPH_PATT_COLORRAM+0x0F, ++ NV04_PGRAPH_PATT_COLORRAM+0x10, ++ NV04_PGRAPH_PATT_COLORRAM+0x11, ++ NV04_PGRAPH_PATT_COLORRAM+0x12, ++ NV04_PGRAPH_PATT_COLORRAM+0x13, ++ NV04_PGRAPH_PATT_COLORRAM+0x14, ++ NV04_PGRAPH_PATT_COLORRAM+0x15, ++ NV04_PGRAPH_PATT_COLORRAM+0x16, ++ NV04_PGRAPH_PATT_COLORRAM+0x17, ++ NV04_PGRAPH_PATT_COLORRAM+0x18, ++ NV04_PGRAPH_PATT_COLORRAM+0x19, ++ NV04_PGRAPH_PATT_COLORRAM+0x1A, ++ NV04_PGRAPH_PATT_COLORRAM+0x1B, ++ NV04_PGRAPH_PATT_COLORRAM+0x1C, ++ NV04_PGRAPH_PATT_COLORRAM+0x1D, ++ NV04_PGRAPH_PATT_COLORRAM+0x1E, ++ NV04_PGRAPH_PATT_COLORRAM+0x1F, ++ NV04_PGRAPH_PATT_COLORRAM+0x20, ++ NV04_PGRAPH_PATT_COLORRAM+0x21, ++ NV04_PGRAPH_PATT_COLORRAM+0x22, ++ NV04_PGRAPH_PATT_COLORRAM+0x23, ++ NV04_PGRAPH_PATT_COLORRAM+0x24, ++ NV04_PGRAPH_PATT_COLORRAM+0x25, ++ NV04_PGRAPH_PATT_COLORRAM+0x26, ++ NV04_PGRAPH_PATT_COLORRAM+0x27, ++ NV04_PGRAPH_PATT_COLORRAM+0x28, ++ NV04_PGRAPH_PATT_COLORRAM+0x29, ++ NV04_PGRAPH_PATT_COLORRAM+0x2A, ++ NV04_PGRAPH_PATT_COLORRAM+0x2B, ++ NV04_PGRAPH_PATT_COLORRAM+0x2C, ++ NV04_PGRAPH_PATT_COLORRAM+0x2D, ++ NV04_PGRAPH_PATT_COLORRAM+0x2E, ++ NV04_PGRAPH_PATT_COLORRAM+0x2F, ++ NV04_PGRAPH_PATT_COLORRAM+0x30, ++ NV04_PGRAPH_PATT_COLORRAM+0x31, ++ NV04_PGRAPH_PATT_COLORRAM+0x32, ++ NV04_PGRAPH_PATT_COLORRAM+0x33, ++ NV04_PGRAPH_PATT_COLORRAM+0x34, ++ NV04_PGRAPH_PATT_COLORRAM+0x35, ++ NV04_PGRAPH_PATT_COLORRAM+0x36, ++ NV04_PGRAPH_PATT_COLORRAM+0x37, ++ NV04_PGRAPH_PATT_COLORRAM+0x38, ++ NV04_PGRAPH_PATT_COLORRAM+0x39, ++ NV04_PGRAPH_PATT_COLORRAM+0x3A, ++ NV04_PGRAPH_PATT_COLORRAM+0x3B, ++ NV04_PGRAPH_PATT_COLORRAM+0x3C, ++ NV04_PGRAPH_PATT_COLORRAM+0x3D, ++ NV04_PGRAPH_PATT_COLORRAM+0x3E, ++ NV04_PGRAPH_PATT_COLORRAM+0x3F, ++ NV04_PGRAPH_PATTERN, ++ 0x0040080c, ++ NV04_PGRAPH_PATTERN_SHAPE, ++ 0x00400600, ++ NV04_PGRAPH_ROP3, ++ NV04_PGRAPH_CHROMA, ++ NV04_PGRAPH_BETA_AND, ++ NV04_PGRAPH_BETA_PREMULT, ++ NV04_PGRAPH_CONTROL0, ++ NV04_PGRAPH_CONTROL1, ++ NV04_PGRAPH_CONTROL2, ++ NV04_PGRAPH_BLEND, ++ NV04_PGRAPH_STORED_FMT, ++ NV04_PGRAPH_SOURCE_COLOR, ++ 0x00400560, ++ 0x00400568, ++ 0x00400564, ++ 0x0040056c, ++ 0x00400400, ++ 0x00400480, ++ 0x00400404, ++ 0x00400484, ++ 0x00400408, ++ 0x00400488, ++ 0x0040040c, ++ 0x0040048c, ++ 0x00400410, ++ 0x00400490, ++ 0x00400414, ++ 0x00400494, ++ 0x00400418, ++ 0x00400498, ++ 0x0040041c, ++ 0x0040049c, ++ 0x00400420, ++ 0x004004a0, ++ 0x00400424, ++ 0x004004a4, ++ 0x00400428, ++ 0x004004a8, ++ 0x0040042c, ++ 0x004004ac, ++ 0x00400430, ++ 0x004004b0, ++ 0x00400434, ++ 0x004004b4, ++ 0x00400438, ++ 0x004004b8, ++ 0x0040043c, ++ 0x004004bc, ++ 0x00400440, ++ 0x004004c0, ++ 0x00400444, ++ 0x004004c4, ++ 0x00400448, ++ 0x004004c8, ++ 0x0040044c, ++ 0x004004cc, ++ 0x00400450, ++ 0x004004d0, ++ 0x00400454, ++ 0x004004d4, ++ 0x00400458, ++ 0x004004d8, ++ 0x0040045c, ++ 0x004004dc, ++ 0x00400460, ++ 0x004004e0, ++ 0x00400464, ++ 0x004004e4, ++ 0x00400468, ++ 0x004004e8, ++ 0x0040046c, ++ 0x004004ec, ++ 0x00400470, ++ 0x004004f0, ++ 0x00400474, ++ 0x004004f4, ++ 0x00400478, ++ 0x004004f8, ++ 0x0040047c, ++ 0x004004fc, ++ 0x0040053c, ++ 0x00400544, ++ 0x00400540, ++ 0x00400548, ++ 0x00400560, ++ 0x00400568, ++ 0x00400564, ++ 0x0040056c, ++ 0x00400534, ++ 0x00400538, ++ 0x00400514, ++ 0x00400518, ++ 0x0040051c, ++ 0x00400520, ++ 0x00400524, ++ 0x00400528, ++ 0x0040052c, ++ 0x00400530, ++ 0x00400d00, ++ 0x00400d40, ++ 0x00400d80, ++ 0x00400d04, ++ 0x00400d44, ++ 0x00400d84, ++ 0x00400d08, ++ 0x00400d48, ++ 0x00400d88, ++ 0x00400d0c, ++ 0x00400d4c, ++ 0x00400d8c, ++ 0x00400d10, ++ 0x00400d50, ++ 0x00400d90, ++ 0x00400d14, ++ 0x00400d54, ++ 0x00400d94, ++ 0x00400d18, ++ 0x00400d58, ++ 0x00400d98, ++ 0x00400d1c, ++ 0x00400d5c, ++ 0x00400d9c, ++ 0x00400d20, ++ 0x00400d60, ++ 0x00400da0, ++ 0x00400d24, ++ 0x00400d64, ++ 0x00400da4, ++ 0x00400d28, ++ 0x00400d68, ++ 0x00400da8, ++ 0x00400d2c, ++ 0x00400d6c, ++ 0x00400dac, ++ 0x00400d30, ++ 0x00400d70, ++ 0x00400db0, ++ 0x00400d34, ++ 0x00400d74, ++ 0x00400db4, ++ 0x00400d38, ++ 0x00400d78, ++ 0x00400db8, ++ 0x00400d3c, ++ 0x00400d7c, ++ 0x00400dbc, ++ 0x00400590, ++ 0x00400594, ++ 0x00400598, ++ 0x0040059c, ++ 0x004005a8, ++ 0x004005ac, ++ 0x004005b0, ++ 0x004005b4, ++ 0x004005c0, ++ 0x004005c4, ++ 0x004005c8, ++ 0x004005cc, ++ 0x004005d0, ++ 0x004005d4, ++ 0x004005d8, ++ 0x004005dc, ++ 0x004005e0, ++ NV04_PGRAPH_PASSTHRU_0, ++ NV04_PGRAPH_PASSTHRU_1, ++ NV04_PGRAPH_PASSTHRU_2, ++ NV04_PGRAPH_DVD_COLORFMT, ++ NV04_PGRAPH_SCALED_FORMAT, ++ NV04_PGRAPH_MISC24_0, ++ NV04_PGRAPH_MISC24_1, ++ NV04_PGRAPH_MISC24_2, ++ 0x00400500, ++ 0x00400504, ++ NV04_PGRAPH_VALID1, ++ NV04_PGRAPH_VALID2 ++ ++ ++}; ++ ++struct graph_state { ++ int nv04[ARRAY_SIZE(nv04_graph_ctx_regs)]; ++}; ++ ++struct nouveau_channel * ++nv04_graph_channel(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int chid = dev_priv->engine.fifo.channels; ++ ++ if (nv_rd32(dev, NV04_PGRAPH_CTX_CONTROL) & 0x00010000) ++ chid = nv_rd32(dev, NV04_PGRAPH_CTX_USER) >> 24; ++ ++ if (chid >= dev_priv->engine.fifo.channels) ++ return NULL; ++ ++ return dev_priv->fifos[chid]; ++} ++ ++void ++nv04_graph_context_switch(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; ++ struct nouveau_channel *chan = NULL; ++ int chid; ++ ++ pgraph->fifo_access(dev, false); ++ nouveau_wait_for_idle(dev); ++ ++ /* If previous context is valid, we need to save it */ ++ pgraph->unload_context(dev); ++ ++ /* Load context for next channel */ ++ chid = dev_priv->engine.fifo.channel_id(dev); ++ chan = dev_priv->fifos[chid]; ++ if (chan) ++ nv04_graph_load_context(chan); ++ ++ pgraph->fifo_access(dev, true); ++} ++ ++int nv04_graph_create_context(struct nouveau_channel *chan) ++{ ++ struct graph_state *pgraph_ctx; ++ NV_DEBUG(chan->dev, "nv04_graph_context_create %d\n", chan->id); ++ ++ chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), ++ GFP_KERNEL); ++ if (pgraph_ctx == NULL) ++ return -ENOMEM; ++ ++ /* dev_priv->fifos[channel].pgraph_ctx_user = channel << 24; */ ++ pgraph_ctx->nv04[0] = 0x0001ffff; ++ /* is it really needed ??? */ ++#if 0 ++ dev_priv->fifos[channel].pgraph_ctx[1] = ++ nv_rd32(dev, NV_PGRAPH_DEBUG_4); ++ dev_priv->fifos[channel].pgraph_ctx[2] = ++ nv_rd32(dev, 0x004006b0); ++#endif ++ return 0; ++} ++ ++void nv04_graph_destroy_context(struct nouveau_channel *chan) ++{ ++ struct graph_state *pgraph_ctx = chan->pgraph_ctx; ++ ++ kfree(pgraph_ctx); ++ chan->pgraph_ctx = NULL; ++} ++ ++int nv04_graph_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct graph_state *pgraph_ctx = chan->pgraph_ctx; ++ uint32_t tmp; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) ++ nv_wr32(dev, nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]); ++ ++ nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10010100); ++ nv_wr32(dev, NV04_PGRAPH_CTX_USER, chan->id << 24); ++ tmp = nv_rd32(dev, NV04_PGRAPH_FFINTFC_ST2); ++ nv_wr32(dev, NV04_PGRAPH_FFINTFC_ST2, tmp & 0x000fffff); ++ return 0; ++} ++ ++int ++nv04_graph_unload_context(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; ++ struct nouveau_channel *chan = NULL; ++ struct graph_state *ctx; ++ uint32_t tmp; ++ int i; ++ ++ chan = pgraph->channel(dev); ++ if (!chan) ++ return 0; ++ ctx = chan->pgraph_ctx; ++ ++ for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) ++ ctx->nv04[i] = nv_rd32(dev, nv04_graph_ctx_regs[i]); ++ ++ nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10000000); ++ tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff; ++ tmp |= (dev_priv->engine.fifo.channels - 1) << 24; ++ nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp); ++ return 0; ++} ++ ++int nv04_graph_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ++ ~NV_PMC_ENABLE_PGRAPH); ++ nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | ++ NV_PMC_ENABLE_PGRAPH); ++ ++ /* Enable PGRAPH interrupts */ ++ nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF); ++ nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); ++ ++ nv_wr32(dev, NV04_PGRAPH_VALID1, 0); ++ nv_wr32(dev, NV04_PGRAPH_VALID2, 0); ++ /*nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x000001FF); ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/ ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x1231c000); ++ /*1231C000 blob, 001 haiku*/ ++ //*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/ ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x72111100); ++ /*0x72111100 blob , 01 haiku*/ ++ /*nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/ ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f071); ++ /*haiku same*/ ++ ++ /*nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/ ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31); ++ /*haiku and blob 10d4*/ ++ ++ nv_wr32(dev, NV04_PGRAPH_STATE , 0xFFFFFFFF); ++ nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL , 0x10000100); ++ tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff; ++ tmp |= dev_priv->engine.fifo.channels << 24; ++ nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp); ++ ++ /* These don't belong here, they're part of a per-channel context */ ++ nv_wr32(dev, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000); ++ nv_wr32(dev, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF); ++ ++ return 0; ++} ++ ++void nv04_graph_takedown(struct drm_device *dev) ++{ ++} ++ ++void ++nv04_graph_fifo_access(struct drm_device *dev, bool enabled) ++{ ++ if (enabled) ++ nv_wr32(dev, NV04_PGRAPH_FIFO, ++ nv_rd32(dev, NV04_PGRAPH_FIFO) | 1); ++ else ++ nv_wr32(dev, NV04_PGRAPH_FIFO, ++ nv_rd32(dev, NV04_PGRAPH_FIFO) & ~1); ++} ++ ++static int ++nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass, ++ int mthd, uint32_t data) ++{ ++ chan->fence.last_sequence_irq = data; ++ nouveau_fence_handler(chan->dev, chan->id); ++ return 0; ++} ++ ++static int ++nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass, ++ int mthd, uint32_t data) ++{ ++ struct drm_device *dev = chan->dev; ++ uint32_t instance = nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff; ++ int subc = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7; ++ uint32_t tmp; ++ ++ tmp = nv_ri32(dev, instance); ++ tmp &= ~0x00038000; ++ tmp |= ((data & 7) << 15); ++ ++ nv_wi32(dev, instance, tmp); ++ nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp); ++ nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + subc, tmp); ++ return 0; ++} ++ ++static struct nouveau_pgraph_object_method nv04_graph_mthds_m2mf[] = { ++ { 0x0150, nv04_graph_mthd_set_ref }, ++ {} ++}; ++ ++static struct nouveau_pgraph_object_method nv04_graph_mthds_set_operation[] = { ++ { 0x02fc, nv04_graph_mthd_set_operation }, ++ {}, ++}; ++ ++struct nouveau_pgraph_object_class nv04_graph_grclass[] = { ++ { 0x0039, false, nv04_graph_mthds_m2mf }, ++ { 0x004a, false, nv04_graph_mthds_set_operation }, /* gdirect */ ++ { 0x005f, false, nv04_graph_mthds_set_operation }, /* imageblit */ ++ { 0x0061, false, nv04_graph_mthds_set_operation }, /* ifc */ ++ { 0x0077, false, nv04_graph_mthds_set_operation }, /* sifm */ ++ { 0x0030, false, NULL }, /* null */ ++ { 0x0042, false, NULL }, /* surf2d */ ++ { 0x0043, false, NULL }, /* rop */ ++ { 0x0012, false, NULL }, /* beta1 */ ++ { 0x0072, false, NULL }, /* beta4 */ ++ { 0x0019, false, NULL }, /* cliprect */ ++ { 0x0044, false, NULL }, /* pattern */ ++ { 0x0052, false, NULL }, /* swzsurf */ ++ { 0x0053, false, NULL }, /* surf3d */ ++ { 0x0054, false, NULL }, /* tex_tri */ ++ { 0x0055, false, NULL }, /* multitex_tri */ ++ {} ++}; ++ +diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c +new file mode 100644 +index 0000000..d87a426 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_instmem.c +@@ -0,0 +1,210 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++/* returns the size of fifo context */ ++static int ++nouveau_fifo_ctx_size(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (dev_priv->card_type >= NV_40) ++ return 128; ++ else ++ if (dev_priv->card_type >= NV_17) ++ return 64; ++ ++ return 32; ++} ++ ++static void ++nv04_instmem_determine_amount(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int i; ++ ++ /* Figure out how much instance memory we need */ ++ if (dev_priv->card_type >= NV_40) { ++ /* We'll want more instance memory than this on some NV4x cards. ++ * There's a 16MB aperture to play with that maps onto the end ++ * of vram. For now, only reserve a small piece until we know ++ * more about what each chipset requires. ++ */ ++ switch (dev_priv->chipset & 0xf0) { ++ case 0x40: ++ case 0x47: ++ case 0x49: ++ case 0x4b: ++ dev_priv->ramin_rsvd_vram = (2 * 1024 * 1024); ++ break; ++ default: ++ dev_priv->ramin_rsvd_vram = (1 * 1024 * 1024); ++ break; ++ } ++ } else { ++ /*XXX: what *are* the limits on ramin_rsvd_vram = (512 * 1024); ++ } ++ NV_DEBUG(dev, "RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram >> 10); ++ ++ /* Clear all of it, except the BIOS image that's in the first 64KiB */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ for (i = 64 * 1024; i < dev_priv->ramin_rsvd_vram; i += 4) ++ nv_wi32(dev, i, 0x00000000); ++ dev_priv->engine.instmem.finish_access(dev); ++} ++ ++static void ++nv04_instmem_configure_fixed_tables(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_engine *engine = &dev_priv->engine; ++ ++ /* FIFO hash table (RAMHT) ++ * use 4k hash table at RAMIN+0x10000 ++ * TODO: extend the hash table ++ */ ++ dev_priv->ramht_offset = 0x10000; ++ dev_priv->ramht_bits = 9; ++ dev_priv->ramht_size = (1 << dev_priv->ramht_bits); /* nr entries */ ++ dev_priv->ramht_size *= 8; /* 2 32-bit values per entry in RAMHT */ ++ NV_DEBUG(dev, "RAMHT offset=0x%x, size=%d\n", dev_priv->ramht_offset, ++ dev_priv->ramht_size); ++ ++ /* FIFO runout table (RAMRO) - 512k at 0x11200 */ ++ dev_priv->ramro_offset = 0x11200; ++ dev_priv->ramro_size = 512; ++ NV_DEBUG(dev, "RAMRO offset=0x%x, size=%d\n", dev_priv->ramro_offset, ++ dev_priv->ramro_size); ++ ++ /* FIFO context table (RAMFC) ++ * NV40 : Not sure exactly how to position RAMFC on some cards, ++ * 0x30002 seems to position it at RAMIN+0x20000 on these ++ * cards. RAMFC is 4kb (32 fifos, 128byte entries). ++ * Others: Position RAMFC at RAMIN+0x11400 ++ */ ++ dev_priv->ramfc_size = engine->fifo.channels * ++ nouveau_fifo_ctx_size(dev); ++ switch (dev_priv->card_type) { ++ case NV_40: ++ dev_priv->ramfc_offset = 0x20000; ++ break; ++ case NV_30: ++ case NV_20: ++ case NV_17: ++ case NV_11: ++ case NV_10: ++ case NV_04: ++ default: ++ dev_priv->ramfc_offset = 0x11400; ++ break; ++ } ++ NV_DEBUG(dev, "RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset, ++ dev_priv->ramfc_size); ++} ++ ++int nv04_instmem_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t offset; ++ int ret = 0; ++ ++ nv04_instmem_determine_amount(dev); ++ nv04_instmem_configure_fixed_tables(dev); ++ ++ /* Create a heap to manage RAMIN allocations, we don't allocate ++ * the space that was reserved for RAMHT/FC/RO. ++ */ ++ offset = dev_priv->ramfc_offset + dev_priv->ramfc_size; ++ ++ /* It appears RAMRO (or something?) is controlled by 0x2220/0x2230 ++ * on certain NV4x chipsets as well as RAMFC. When 0x2230 == 0 ++ * ("new style" control) the upper 16-bits of 0x2220 points at this ++ * other mysterious table that's clobbering important things. ++ * ++ * We're now pointing this at RAMIN+0x30000 to avoid RAMFC getting ++ * smashed to pieces on us, so reserve 0x30000-0x40000 too.. ++ */ ++ if (dev_priv->card_type >= NV_40) { ++ if (offset < 0x40000) ++ offset = 0x40000; ++ } ++ ++ ret = nouveau_mem_init_heap(&dev_priv->ramin_heap, ++ offset, dev_priv->ramin_rsvd_vram - offset); ++ if (ret) { ++ dev_priv->ramin_heap = NULL; ++ NV_ERROR(dev, "Failed to init RAMIN heap\n"); ++ } ++ ++ return ret; ++} ++ ++void ++nv04_instmem_takedown(struct drm_device *dev) ++{ ++} ++ ++int ++nv04_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, uint32_t *sz) ++{ ++ if (gpuobj->im_backing) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++void ++nv04_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (gpuobj && gpuobj->im_backing) { ++ if (gpuobj->im_bound) ++ dev_priv->engine.instmem.unbind(dev, gpuobj); ++ gpuobj->im_backing = NULL; ++ } ++} ++ ++int ++nv04_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ if (!gpuobj->im_pramin || gpuobj->im_bound) ++ return -EINVAL; ++ ++ gpuobj->im_bound = 1; ++ return 0; ++} ++ ++int ++nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ if (gpuobj->im_bound == 0) ++ return -EINVAL; ++ ++ gpuobj->im_bound = 0; ++ return 0; ++} ++ ++void ++nv04_instmem_prepare_access(struct drm_device *dev, bool write) ++{ ++} ++ ++void ++nv04_instmem_finish_access(struct drm_device *dev) ++{ ++} ++ ++int ++nv04_instmem_suspend(struct drm_device *dev) ++{ ++ return 0; ++} ++ ++void ++nv04_instmem_resume(struct drm_device *dev) ++{ ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv04_mc.c b/drivers/gpu/drm/nouveau/nv04_mc.c +new file mode 100644 +index 0000000..617ed1e +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_mc.c +@@ -0,0 +1,20 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++int ++nv04_mc_init(struct drm_device *dev) ++{ ++ /* Power up everything, resetting each individual unit will ++ * be done later if needed. ++ */ ++ ++ nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); ++ return 0; ++} ++ ++void ++nv04_mc_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv04_timer.c b/drivers/gpu/drm/nouveau/nv04_timer.c +new file mode 100644 +index 0000000..1d09ddd +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_timer.c +@@ -0,0 +1,51 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++int ++nv04_timer_init(struct drm_device *dev) ++{ ++ nv_wr32(dev, NV04_PTIMER_INTR_EN_0, 0x00000000); ++ nv_wr32(dev, NV04_PTIMER_INTR_0, 0xFFFFFFFF); ++ ++ /* Just use the pre-existing values when possible for now; these regs ++ * are not written in nv (driver writer missed a /4 on the address), and ++ * writing 8 and 3 to the correct regs breaks the timings on the LVDS ++ * hardware sequencing microcode. ++ * A correct solution (involving calculations with the GPU PLL) can ++ * be done when kernel modesetting lands ++ */ ++ if (!nv_rd32(dev, NV04_PTIMER_NUMERATOR) || ++ !nv_rd32(dev, NV04_PTIMER_DENOMINATOR)) { ++ nv_wr32(dev, NV04_PTIMER_NUMERATOR, 0x00000008); ++ nv_wr32(dev, NV04_PTIMER_DENOMINATOR, 0x00000003); ++ } ++ ++ return 0; ++} ++ ++uint64_t ++nv04_timer_read(struct drm_device *dev) ++{ ++ uint32_t low; ++ /* From kmmio dumps on nv28 this looks like how the blob does this. ++ * It reads the high dword twice, before and after. ++ * The only explanation seems to be that the 64-bit timer counter ++ * advances between high and low dword reads and may corrupt the ++ * result. Not confirmed. ++ */ ++ uint32_t high2 = nv_rd32(dev, NV04_PTIMER_TIME_1); ++ uint32_t high1; ++ do { ++ high1 = high2; ++ low = nv_rd32(dev, NV04_PTIMER_TIME_0); ++ high2 = nv_rd32(dev, NV04_PTIMER_TIME_1); ++ } while (high1 != high2); ++ return (((uint64_t)high2) << 32) | (uint64_t)low; ++} ++ ++void ++nv04_timer_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c +new file mode 100644 +index 0000000..9c63099 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv04_tv.c +@@ -0,0 +1,305 @@ ++/* ++ * Copyright (C) 2009 Francisco Jerez. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_encoder.h" ++#include "nouveau_connector.h" ++#include "nouveau_crtc.h" ++#include "nouveau_hw.h" ++#include "drm_crtc_helper.h" ++ ++#include "i2c/ch7006.h" ++ ++static struct { ++ struct i2c_board_info board_info; ++ struct drm_encoder_funcs funcs; ++ struct drm_encoder_helper_funcs hfuncs; ++ void *params; ++ ++} nv04_tv_encoder_info[] = { ++ { ++ .board_info = { I2C_BOARD_INFO("ch7006", 0x75) }, ++ .params = &(struct ch7006_encoder_params) { ++ CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER, ++ 0, 0, 0, ++ CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED, ++ CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC ++ }, ++ }, ++}; ++ ++static bool probe_i2c_addr(struct i2c_adapter *adapter, int addr) ++{ ++ struct i2c_msg msg = { ++ .addr = addr, ++ .len = 0, ++ }; ++ ++ return i2c_transfer(adapter, &msg, 1) == 1; ++} ++ ++int nv04_tv_identify(struct drm_device *dev, int i2c_index) ++{ ++ struct nouveau_i2c_chan *i2c; ++ bool was_locked; ++ int i, ret; ++ ++ NV_TRACE(dev, "Probing TV encoders on I2C bus: %d\n", i2c_index); ++ ++ i2c = nouveau_i2c_find(dev, i2c_index); ++ if (!i2c) ++ return -ENODEV; ++ ++ was_locked = NVLockVgaCrtcs(dev, false); ++ ++ for (i = 0; i < ARRAY_SIZE(nv04_tv_encoder_info); i++) { ++ if (probe_i2c_addr(&i2c->adapter, ++ nv04_tv_encoder_info[i].board_info.addr)) { ++ ret = i; ++ break; ++ } ++ } ++ ++ if (i < ARRAY_SIZE(nv04_tv_encoder_info)) { ++ NV_TRACE(dev, "Detected TV encoder: %s\n", ++ nv04_tv_encoder_info[i].board_info.type); ++ ++ } else { ++ NV_TRACE(dev, "No TV encoders found.\n"); ++ i = -ENODEV; ++ } ++ ++ NVLockVgaCrtcs(dev, was_locked); ++ return i; ++} ++ ++#define PLLSEL_TV_CRTC1_MASK \ ++ (NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1 \ ++ | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1) ++#define PLLSEL_TV_CRTC2_MASK \ ++ (NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK2 \ ++ | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK2) ++ ++static void nv04_tv_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv04_mode_state *state = &dev_priv->mode_reg; ++ uint8_t crtc1A; ++ ++ NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n", ++ mode, nv_encoder->dcb->index); ++ ++ state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK); ++ ++ if (mode == DRM_MODE_DPMS_ON) { ++ int head = nouveau_crtc(encoder->crtc)->index; ++ crtc1A = NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX); ++ ++ state->pllsel |= head ? PLLSEL_TV_CRTC2_MASK : ++ PLLSEL_TV_CRTC1_MASK; ++ ++ /* Inhibit hsync */ ++ crtc1A |= 0x80; ++ ++ NVWriteVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX, crtc1A); ++ } ++ ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel); ++ ++ to_encoder_slave(encoder)->slave_funcs->dpms(encoder, mode); ++} ++ ++static void nv04_tv_bind(struct drm_device *dev, int head, bool bind) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv04_crtc_reg *state = &dev_priv->mode_reg.crtc_reg[head]; ++ ++ state->tv_setup = 0; ++ ++ if (bind) { ++ state->CRTC[NV_CIO_CRE_LCD__INDEX] = 0; ++ state->CRTC[NV_CIO_CRE_49] |= 0x10; ++ } else { ++ state->CRTC[NV_CIO_CRE_49] &= ~0x10; ++ } ++ ++ NVWriteVgaCrtc(dev, head, NV_CIO_CRE_LCD__INDEX, ++ state->CRTC[NV_CIO_CRE_LCD__INDEX]); ++ NVWriteVgaCrtc(dev, head, NV_CIO_CRE_49, ++ state->CRTC[NV_CIO_CRE_49]); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP, ++ state->tv_setup); ++} ++ ++static void nv04_tv_prepare(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ int head = nouveau_crtc(encoder->crtc)->index; ++ struct drm_encoder_helper_funcs *helper = encoder->helper_private; ++ ++ helper->dpms(encoder, DRM_MODE_DPMS_OFF); ++ ++ nv04_dfp_disable(dev, head); ++ ++ if (nv_two_heads(dev)) ++ nv04_tv_bind(dev, head ^ 1, false); ++ ++ nv04_tv_bind(dev, head, true); ++} ++ ++static void nv04_tv_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); ++ struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; ++ ++ regp->tv_htotal = adjusted_mode->htotal; ++ regp->tv_vtotal = adjusted_mode->vtotal; ++ ++ /* These delay the TV signals with respect to the VGA port, ++ * they might be useful if we ever allow a CRTC to drive ++ * multiple outputs. ++ */ ++ regp->tv_hskew = 1; ++ regp->tv_hsync_delay = 1; ++ regp->tv_hsync_delay2 = 64; ++ regp->tv_vskew = 1; ++ regp->tv_vsync_delay = 1; ++ ++ to_encoder_slave(encoder)->slave_funcs->mode_set(encoder, mode, adjusted_mode); ++} ++ ++static void nv04_tv_commit(struct drm_encoder *encoder) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_device *dev = encoder->dev; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); ++ struct drm_encoder_helper_funcs *helper = encoder->helper_private; ++ ++ helper->dpms(encoder, DRM_MODE_DPMS_ON); ++ ++ NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", ++ drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, ++ '@' + ffs(nv_encoder->dcb->or)); ++} ++ ++static void nv04_tv_destroy(struct drm_encoder *encoder) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ ++ to_encoder_slave(encoder)->slave_funcs->destroy(encoder); ++ ++ drm_encoder_cleanup(encoder); ++ ++ kfree(nv_encoder); ++} ++ ++int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) ++{ ++ struct nouveau_encoder *nv_encoder; ++ struct drm_encoder *encoder; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct i2c_adapter *adap; ++ struct drm_encoder_funcs *funcs = NULL; ++ struct drm_encoder_helper_funcs *hfuncs = NULL; ++ struct drm_encoder_slave_funcs *sfuncs = NULL; ++ int i2c_index = entry->i2c_index; ++ int type, ret; ++ bool was_locked; ++ ++ /* Ensure that we can talk to this encoder */ ++ type = nv04_tv_identify(dev, i2c_index); ++ if (type < 0) ++ return type; ++ ++ /* Allocate the necessary memory */ ++ nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); ++ if (!nv_encoder) ++ return -ENOMEM; ++ ++ /* Initialize the common members */ ++ encoder = to_drm_encoder(nv_encoder); ++ ++ funcs = &nv04_tv_encoder_info[type].funcs; ++ hfuncs = &nv04_tv_encoder_info[type].hfuncs; ++ ++ drm_encoder_init(dev, encoder, funcs, DRM_MODE_ENCODER_TVDAC); ++ drm_encoder_helper_add(encoder, hfuncs); ++ ++ encoder->possible_crtcs = entry->heads; ++ encoder->possible_clones = 0; ++ ++ nv_encoder->dcb = entry; ++ nv_encoder->or = ffs(entry->or) - 1; ++ ++ /* Run the slave-specific initialization */ ++ adap = &dev_priv->vbios->dcb->i2c[i2c_index].chan->adapter; ++ ++ was_locked = NVLockVgaCrtcs(dev, false); ++ ++ ret = drm_i2c_encoder_init(encoder->dev, to_encoder_slave(encoder), adap, ++ &nv04_tv_encoder_info[type].board_info); ++ ++ NVLockVgaCrtcs(dev, was_locked); ++ ++ if (ret < 0) ++ goto fail; ++ ++ /* Fill the function pointers */ ++ sfuncs = to_encoder_slave(encoder)->slave_funcs; ++ ++ *funcs = (struct drm_encoder_funcs) { ++ .destroy = nv04_tv_destroy, ++ }; ++ ++ *hfuncs = (struct drm_encoder_helper_funcs) { ++ .dpms = nv04_tv_dpms, ++ .save = sfuncs->save, ++ .restore = sfuncs->restore, ++ .mode_fixup = sfuncs->mode_fixup, ++ .prepare = nv04_tv_prepare, ++ .commit = nv04_tv_commit, ++ .mode_set = nv04_tv_mode_set, ++ .detect = sfuncs->detect, ++ }; ++ ++ /* Set the slave encoder configuration */ ++ sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params); ++ ++ return 0; ++ ++fail: ++ drm_encoder_cleanup(encoder); ++ ++ kfree(nv_encoder); ++ return ret; ++} +diff --git a/drivers/gpu/drm/nouveau/nv10_fb.c b/drivers/gpu/drm/nouveau/nv10_fb.c +new file mode 100644 +index 0000000..79e2d10 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv10_fb.c +@@ -0,0 +1,24 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++int ++nv10_fb_init(struct drm_device *dev) ++{ ++ uint32_t fb_bar_size; ++ int i; ++ ++ fb_bar_size = drm_get_resource_len(dev, 0) - 1; ++ for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { ++ nv_wr32(dev, NV10_PFB_TILE(i), 0); ++ nv_wr32(dev, NV10_PFB_TLIMIT(i), fb_bar_size); ++ } ++ ++ return 0; ++} ++ ++void ++nv10_fb_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv10_fifo.c b/drivers/gpu/drm/nouveau/nv10_fifo.c +new file mode 100644 +index 0000000..877f00e +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv10_fifo.c +@@ -0,0 +1,260 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++#define NV10_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV10_RAMFC__SIZE)) ++#define NV10_RAMFC__SIZE ((dev_priv->chipset) >= 0x17 ? 64 : 32) ++ ++int ++nv10_fifo_channel_id(struct drm_device *dev) ++{ ++ return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & ++ NV10_PFIFO_CACHE1_PUSH1_CHID_MASK; ++} ++ ++int ++nv10_fifo_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; ++ struct drm_device *dev = chan->dev; ++ uint32_t fc = NV10_RAMFC(chan->id); ++ int ret; ++ ++ ret = nouveau_gpuobj_new_fake(dev, NV10_RAMFC(chan->id), ~0, ++ NV10_RAMFC__SIZE, NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, NULL, &chan->ramfc); ++ if (ret) ++ return ret; ++ ++ /* Fill entries that are seen filled in dumps of nvidia driver just ++ * after channel's is put into DMA mode ++ */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ nv_wi32(dev, fc + 0, chan->pushbuf_base); ++ nv_wi32(dev, fc + 4, chan->pushbuf_base); ++ nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4); ++ nv_wi32(dev, fc + 20, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | ++#ifdef __BIG_ENDIAN ++ NV_PFIFO_CACHE1_BIG_ENDIAN | ++#endif ++ 0); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ /* enable the fifo dma operation */ ++ nv_wr32(dev, NV04_PFIFO_MODE, ++ nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); ++ return 0; ++} ++ ++void ++nv10_fifo_destroy_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ ++ nv_wr32(dev, NV04_PFIFO_MODE, ++ nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id)); ++ ++ nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++} ++ ++static void ++nv10_fifo_do_load_context(struct drm_device *dev, int chid) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t fc = NV10_RAMFC(chid), tmp; ++ ++ dev_priv->engine.instmem.prepare_access(dev, false); ++ ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); ++ nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); ++ ++ tmp = nv_ri32(dev, fc + 12); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, tmp & 0xFFFF); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, tmp >> 16); ++ ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 16)); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, nv_ri32(dev, fc + 20)); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 24)); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 28)); ++ ++ if (dev_priv->chipset < 0x17) ++ goto out; ++ ++ nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE, nv_ri32(dev, fc + 32)); ++ tmp = nv_ri32(dev, fc + 36); ++ nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP, tmp); ++ nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT, nv_ri32(dev, fc + 40)); ++ nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, nv_ri32(dev, fc + 44)); ++ nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 48)); ++ ++out: ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); ++} ++ ++int ++nv10_fifo_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ uint32_t tmp; ++ ++ nv10_fifo_do_load_context(dev, chan->id); ++ ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, ++ NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1); ++ ++ /* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */ ++ tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp); ++ ++ return 0; ++} ++ ++int ++nv10_fifo_unload_context(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; ++ uint32_t fc, tmp; ++ int chid; ++ ++ chid = pfifo->channel_id(dev); ++ if (chid < 0 || chid >= dev_priv->engine.fifo.channels) ++ return 0; ++ fc = NV10_RAMFC(chid); ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ ++ nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); ++ nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); ++ nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); ++ tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE) & 0xFFFF; ++ tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16); ++ nv_wi32(dev, fc + 12, tmp); ++ nv_wi32(dev, fc + 16, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE)); ++ nv_wi32(dev, fc + 20, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH)); ++ nv_wi32(dev, fc + 24, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE)); ++ nv_wi32(dev, fc + 28, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1)); ++ ++ if (dev_priv->chipset < 0x17) ++ goto out; ++ ++ nv_wi32(dev, fc + 32, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); ++ tmp = nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP); ++ nv_wi32(dev, fc + 36, tmp); ++ nv_wi32(dev, fc + 40, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); ++ nv_wi32(dev, fc + 44, nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE)); ++ nv_wi32(dev, fc + 48, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); ++ ++out: ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv10_fifo_do_load_context(dev, pfifo->channels - 1); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); ++ return 0; ++} ++ ++static void ++nv10_fifo_init_reset(struct drm_device *dev) ++{ ++ nv_wr32(dev, NV03_PMC_ENABLE, ++ nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO); ++ nv_wr32(dev, NV03_PMC_ENABLE, ++ nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PFIFO); ++ ++ nv_wr32(dev, 0x003224, 0x000f0078); ++ nv_wr32(dev, 0x002044, 0x0101ffff); ++ nv_wr32(dev, 0x002040, 0x000000ff); ++ nv_wr32(dev, 0x002500, 0x00000000); ++ nv_wr32(dev, 0x003000, 0x00000000); ++ nv_wr32(dev, 0x003050, 0x00000000); ++ ++ nv_wr32(dev, 0x003258, 0x00000000); ++ nv_wr32(dev, 0x003210, 0x00000000); ++ nv_wr32(dev, 0x003270, 0x00000000); ++} ++ ++static void ++nv10_fifo_init_ramxx(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | ++ ((dev_priv->ramht_bits - 9) << 16) | ++ (dev_priv->ramht_offset >> 8)); ++ nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8); ++ ++ if (dev_priv->card_type > NV_11) { ++ nv_wr32(dev, NV03_PFIFO_RAMFC, (dev_priv->ramfc_offset >> 8) | ++ (1 << 16) /* 64 Bytes entry*/); ++ /* XXX nvidia blob set bit 18, 21,23 for nv20 & nv30 */ ++ } else { ++ nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc_offset >> 8); ++ } ++} ++ ++static void ++nv10_fifo_init_intr(struct drm_device *dev) ++{ ++ nv_wr32(dev, 0x002100, 0xffffffff); ++ nv_wr32(dev, 0x002140, 0xffffffff); ++} ++ ++int ++nv10_fifo_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; ++ int i; ++ ++ nv10_fifo_init_reset(dev); ++ nv10_fifo_init_ramxx(dev); ++ ++ nv10_fifo_do_load_context(dev, pfifo->channels - 1); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); ++ ++ nv10_fifo_init_intr(dev); ++ pfifo->enable(dev); ++ pfifo->reassign(dev, true); ++ ++ for (i = 0; i < dev_priv->engine.fifo.channels; i++) { ++ if (dev_priv->fifos[i]) { ++ uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE); ++ nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i)); ++ } ++ } ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c +new file mode 100644 +index 0000000..6bf6804 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv10_graph.c +@@ -0,0 +1,892 @@ ++/* ++ * Copyright 2007 Matthieu CASTET ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++#include "nouveau_drm.h" ++#include "nouveau_drv.h" ++ ++#define NV10_FIFO_NUMBER 32 ++ ++struct pipe_state { ++ uint32_t pipe_0x0000[0x040/4]; ++ uint32_t pipe_0x0040[0x010/4]; ++ uint32_t pipe_0x0200[0x0c0/4]; ++ uint32_t pipe_0x4400[0x080/4]; ++ uint32_t pipe_0x6400[0x3b0/4]; ++ uint32_t pipe_0x6800[0x2f0/4]; ++ uint32_t pipe_0x6c00[0x030/4]; ++ uint32_t pipe_0x7000[0x130/4]; ++ uint32_t pipe_0x7400[0x0c0/4]; ++ uint32_t pipe_0x7800[0x0c0/4]; ++}; ++ ++static int nv10_graph_ctx_regs[] = { ++ NV10_PGRAPH_CTX_SWITCH1, ++ NV10_PGRAPH_CTX_SWITCH2, ++ NV10_PGRAPH_CTX_SWITCH3, ++ NV10_PGRAPH_CTX_SWITCH4, ++ NV10_PGRAPH_CTX_SWITCH5, ++ NV10_PGRAPH_CTX_CACHE1, /* 8 values from 0x400160 to 0x40017c */ ++ NV10_PGRAPH_CTX_CACHE2, /* 8 values from 0x400180 to 0x40019c */ ++ NV10_PGRAPH_CTX_CACHE3, /* 8 values from 0x4001a0 to 0x4001bc */ ++ NV10_PGRAPH_CTX_CACHE4, /* 8 values from 0x4001c0 to 0x4001dc */ ++ NV10_PGRAPH_CTX_CACHE5, /* 8 values from 0x4001e0 to 0x4001fc */ ++ 0x00400164, ++ 0x00400184, ++ 0x004001a4, ++ 0x004001c4, ++ 0x004001e4, ++ 0x00400168, ++ 0x00400188, ++ 0x004001a8, ++ 0x004001c8, ++ 0x004001e8, ++ 0x0040016c, ++ 0x0040018c, ++ 0x004001ac, ++ 0x004001cc, ++ 0x004001ec, ++ 0x00400170, ++ 0x00400190, ++ 0x004001b0, ++ 0x004001d0, ++ 0x004001f0, ++ 0x00400174, ++ 0x00400194, ++ 0x004001b4, ++ 0x004001d4, ++ 0x004001f4, ++ 0x00400178, ++ 0x00400198, ++ 0x004001b8, ++ 0x004001d8, ++ 0x004001f8, ++ 0x0040017c, ++ 0x0040019c, ++ 0x004001bc, ++ 0x004001dc, ++ 0x004001fc, ++ NV10_PGRAPH_CTX_USER, ++ NV04_PGRAPH_DMA_START_0, ++ NV04_PGRAPH_DMA_START_1, ++ NV04_PGRAPH_DMA_LENGTH, ++ NV04_PGRAPH_DMA_MISC, ++ NV10_PGRAPH_DMA_PITCH, ++ NV04_PGRAPH_BOFFSET0, ++ NV04_PGRAPH_BBASE0, ++ NV04_PGRAPH_BLIMIT0, ++ NV04_PGRAPH_BOFFSET1, ++ NV04_PGRAPH_BBASE1, ++ NV04_PGRAPH_BLIMIT1, ++ NV04_PGRAPH_BOFFSET2, ++ NV04_PGRAPH_BBASE2, ++ NV04_PGRAPH_BLIMIT2, ++ NV04_PGRAPH_BOFFSET3, ++ NV04_PGRAPH_BBASE3, ++ NV04_PGRAPH_BLIMIT3, ++ NV04_PGRAPH_BOFFSET4, ++ NV04_PGRAPH_BBASE4, ++ NV04_PGRAPH_BLIMIT4, ++ NV04_PGRAPH_BOFFSET5, ++ NV04_PGRAPH_BBASE5, ++ NV04_PGRAPH_BLIMIT5, ++ NV04_PGRAPH_BPITCH0, ++ NV04_PGRAPH_BPITCH1, ++ NV04_PGRAPH_BPITCH2, ++ NV04_PGRAPH_BPITCH3, ++ NV04_PGRAPH_BPITCH4, ++ NV10_PGRAPH_SURFACE, ++ NV10_PGRAPH_STATE, ++ NV04_PGRAPH_BSWIZZLE2, ++ NV04_PGRAPH_BSWIZZLE5, ++ NV04_PGRAPH_BPIXEL, ++ NV10_PGRAPH_NOTIFY, ++ NV04_PGRAPH_PATT_COLOR0, ++ NV04_PGRAPH_PATT_COLOR1, ++ NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */ ++ 0x00400904, ++ 0x00400908, ++ 0x0040090c, ++ 0x00400910, ++ 0x00400914, ++ 0x00400918, ++ 0x0040091c, ++ 0x00400920, ++ 0x00400924, ++ 0x00400928, ++ 0x0040092c, ++ 0x00400930, ++ 0x00400934, ++ 0x00400938, ++ 0x0040093c, ++ 0x00400940, ++ 0x00400944, ++ 0x00400948, ++ 0x0040094c, ++ 0x00400950, ++ 0x00400954, ++ 0x00400958, ++ 0x0040095c, ++ 0x00400960, ++ 0x00400964, ++ 0x00400968, ++ 0x0040096c, ++ 0x00400970, ++ 0x00400974, ++ 0x00400978, ++ 0x0040097c, ++ 0x00400980, ++ 0x00400984, ++ 0x00400988, ++ 0x0040098c, ++ 0x00400990, ++ 0x00400994, ++ 0x00400998, ++ 0x0040099c, ++ 0x004009a0, ++ 0x004009a4, ++ 0x004009a8, ++ 0x004009ac, ++ 0x004009b0, ++ 0x004009b4, ++ 0x004009b8, ++ 0x004009bc, ++ 0x004009c0, ++ 0x004009c4, ++ 0x004009c8, ++ 0x004009cc, ++ 0x004009d0, ++ 0x004009d4, ++ 0x004009d8, ++ 0x004009dc, ++ 0x004009e0, ++ 0x004009e4, ++ 0x004009e8, ++ 0x004009ec, ++ 0x004009f0, ++ 0x004009f4, ++ 0x004009f8, ++ 0x004009fc, ++ NV04_PGRAPH_PATTERN, /* 2 values from 0x400808 to 0x40080c */ ++ 0x0040080c, ++ NV04_PGRAPH_PATTERN_SHAPE, ++ NV03_PGRAPH_MONO_COLOR0, ++ NV04_PGRAPH_ROP3, ++ NV04_PGRAPH_CHROMA, ++ NV04_PGRAPH_BETA_AND, ++ NV04_PGRAPH_BETA_PREMULT, ++ 0x00400e70, ++ 0x00400e74, ++ 0x00400e78, ++ 0x00400e7c, ++ 0x00400e80, ++ 0x00400e84, ++ 0x00400e88, ++ 0x00400e8c, ++ 0x00400ea0, ++ 0x00400ea4, ++ 0x00400ea8, ++ 0x00400e90, ++ 0x00400e94, ++ 0x00400e98, ++ 0x00400e9c, ++ NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00-0x400f1c */ ++ NV10_PGRAPH_WINDOWCLIP_VERTICAL, /* 8 values from 0x400f20-0x400f3c */ ++ 0x00400f04, ++ 0x00400f24, ++ 0x00400f08, ++ 0x00400f28, ++ 0x00400f0c, ++ 0x00400f2c, ++ 0x00400f10, ++ 0x00400f30, ++ 0x00400f14, ++ 0x00400f34, ++ 0x00400f18, ++ 0x00400f38, ++ 0x00400f1c, ++ 0x00400f3c, ++ NV10_PGRAPH_XFMODE0, ++ NV10_PGRAPH_XFMODE1, ++ NV10_PGRAPH_GLOBALSTATE0, ++ NV10_PGRAPH_GLOBALSTATE1, ++ NV04_PGRAPH_STORED_FMT, ++ NV04_PGRAPH_SOURCE_COLOR, ++ NV03_PGRAPH_ABS_X_RAM, /* 32 values from 0x400400 to 0x40047c */ ++ NV03_PGRAPH_ABS_Y_RAM, /* 32 values from 0x400480 to 0x4004fc */ ++ 0x00400404, ++ 0x00400484, ++ 0x00400408, ++ 0x00400488, ++ 0x0040040c, ++ 0x0040048c, ++ 0x00400410, ++ 0x00400490, ++ 0x00400414, ++ 0x00400494, ++ 0x00400418, ++ 0x00400498, ++ 0x0040041c, ++ 0x0040049c, ++ 0x00400420, ++ 0x004004a0, ++ 0x00400424, ++ 0x004004a4, ++ 0x00400428, ++ 0x004004a8, ++ 0x0040042c, ++ 0x004004ac, ++ 0x00400430, ++ 0x004004b0, ++ 0x00400434, ++ 0x004004b4, ++ 0x00400438, ++ 0x004004b8, ++ 0x0040043c, ++ 0x004004bc, ++ 0x00400440, ++ 0x004004c0, ++ 0x00400444, ++ 0x004004c4, ++ 0x00400448, ++ 0x004004c8, ++ 0x0040044c, ++ 0x004004cc, ++ 0x00400450, ++ 0x004004d0, ++ 0x00400454, ++ 0x004004d4, ++ 0x00400458, ++ 0x004004d8, ++ 0x0040045c, ++ 0x004004dc, ++ 0x00400460, ++ 0x004004e0, ++ 0x00400464, ++ 0x004004e4, ++ 0x00400468, ++ 0x004004e8, ++ 0x0040046c, ++ 0x004004ec, ++ 0x00400470, ++ 0x004004f0, ++ 0x00400474, ++ 0x004004f4, ++ 0x00400478, ++ 0x004004f8, ++ 0x0040047c, ++ 0x004004fc, ++ NV03_PGRAPH_ABS_UCLIP_XMIN, ++ NV03_PGRAPH_ABS_UCLIP_XMAX, ++ NV03_PGRAPH_ABS_UCLIP_YMIN, ++ NV03_PGRAPH_ABS_UCLIP_YMAX, ++ 0x00400550, ++ 0x00400558, ++ 0x00400554, ++ 0x0040055c, ++ NV03_PGRAPH_ABS_UCLIPA_XMIN, ++ NV03_PGRAPH_ABS_UCLIPA_XMAX, ++ NV03_PGRAPH_ABS_UCLIPA_YMIN, ++ NV03_PGRAPH_ABS_UCLIPA_YMAX, ++ NV03_PGRAPH_ABS_ICLIP_XMAX, ++ NV03_PGRAPH_ABS_ICLIP_YMAX, ++ NV03_PGRAPH_XY_LOGIC_MISC0, ++ NV03_PGRAPH_XY_LOGIC_MISC1, ++ NV03_PGRAPH_XY_LOGIC_MISC2, ++ NV03_PGRAPH_XY_LOGIC_MISC3, ++ NV03_PGRAPH_CLIPX_0, ++ NV03_PGRAPH_CLIPX_1, ++ NV03_PGRAPH_CLIPY_0, ++ NV03_PGRAPH_CLIPY_1, ++ NV10_PGRAPH_COMBINER0_IN_ALPHA, ++ NV10_PGRAPH_COMBINER1_IN_ALPHA, ++ NV10_PGRAPH_COMBINER0_IN_RGB, ++ NV10_PGRAPH_COMBINER1_IN_RGB, ++ NV10_PGRAPH_COMBINER_COLOR0, ++ NV10_PGRAPH_COMBINER_COLOR1, ++ NV10_PGRAPH_COMBINER0_OUT_ALPHA, ++ NV10_PGRAPH_COMBINER1_OUT_ALPHA, ++ NV10_PGRAPH_COMBINER0_OUT_RGB, ++ NV10_PGRAPH_COMBINER1_OUT_RGB, ++ NV10_PGRAPH_COMBINER_FINAL0, ++ NV10_PGRAPH_COMBINER_FINAL1, ++ 0x00400e00, ++ 0x00400e04, ++ 0x00400e08, ++ 0x00400e0c, ++ 0x00400e10, ++ 0x00400e14, ++ 0x00400e18, ++ 0x00400e1c, ++ 0x00400e20, ++ 0x00400e24, ++ 0x00400e28, ++ 0x00400e2c, ++ 0x00400e30, ++ 0x00400e34, ++ 0x00400e38, ++ 0x00400e3c, ++ NV04_PGRAPH_PASSTHRU_0, ++ NV04_PGRAPH_PASSTHRU_1, ++ NV04_PGRAPH_PASSTHRU_2, ++ NV10_PGRAPH_DIMX_TEXTURE, ++ NV10_PGRAPH_WDIMX_TEXTURE, ++ NV10_PGRAPH_DVD_COLORFMT, ++ NV10_PGRAPH_SCALED_FORMAT, ++ NV04_PGRAPH_MISC24_0, ++ NV04_PGRAPH_MISC24_1, ++ NV04_PGRAPH_MISC24_2, ++ NV03_PGRAPH_X_MISC, ++ NV03_PGRAPH_Y_MISC, ++ NV04_PGRAPH_VALID1, ++ NV04_PGRAPH_VALID2, ++}; ++ ++static int nv17_graph_ctx_regs[] = { ++ NV10_PGRAPH_DEBUG_4, ++ 0x004006b0, ++ 0x00400eac, ++ 0x00400eb0, ++ 0x00400eb4, ++ 0x00400eb8, ++ 0x00400ebc, ++ 0x00400ec0, ++ 0x00400ec4, ++ 0x00400ec8, ++ 0x00400ecc, ++ 0x00400ed0, ++ 0x00400ed4, ++ 0x00400ed8, ++ 0x00400edc, ++ 0x00400ee0, ++ 0x00400a00, ++ 0x00400a04, ++}; ++ ++struct graph_state { ++ int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)]; ++ int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)]; ++ struct pipe_state pipe_state; ++}; ++ ++static void nv10_graph_save_pipe(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct graph_state *pgraph_ctx = chan->pgraph_ctx; ++ struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; ++ int i; ++#define PIPE_SAVE(addr) \ ++ do { \ ++ nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \ ++ for (i = 0; i < ARRAY_SIZE(fifo_pipe_state->pipe_##addr); i++) \ ++ fifo_pipe_state->pipe_##addr[i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \ ++ } while (0) ++ ++ PIPE_SAVE(0x4400); ++ PIPE_SAVE(0x0200); ++ PIPE_SAVE(0x6400); ++ PIPE_SAVE(0x6800); ++ PIPE_SAVE(0x6c00); ++ PIPE_SAVE(0x7000); ++ PIPE_SAVE(0x7400); ++ PIPE_SAVE(0x7800); ++ PIPE_SAVE(0x0040); ++ PIPE_SAVE(0x0000); ++ ++#undef PIPE_SAVE ++} ++ ++static void nv10_graph_load_pipe(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct graph_state *pgraph_ctx = chan->pgraph_ctx; ++ struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; ++ int i; ++ uint32_t xfmode0, xfmode1; ++#define PIPE_RESTORE(addr) \ ++ do { \ ++ nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \ ++ for (i = 0; i < ARRAY_SIZE(fifo_pipe_state->pipe_##addr); i++) \ ++ nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, fifo_pipe_state->pipe_##addr[i]); \ ++ } while (0) ++ ++ ++ nouveau_wait_for_idle(dev); ++ /* XXX check haiku comments */ ++ xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0); ++ xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1); ++ nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000); ++ nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000); ++ nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0); ++ for (i = 0; i < 4; i++) ++ nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000); ++ for (i = 0; i < 4; i++) ++ nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000); ++ ++ nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0); ++ for (i = 0; i < 3; i++) ++ nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000); ++ ++ nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80); ++ for (i = 0; i < 3; i++) ++ nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000); ++ ++ nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); ++ nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008); ++ ++ ++ PIPE_RESTORE(0x0200); ++ nouveau_wait_for_idle(dev); ++ ++ /* restore XFMODE */ ++ nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0); ++ nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1); ++ PIPE_RESTORE(0x6400); ++ PIPE_RESTORE(0x6800); ++ PIPE_RESTORE(0x6c00); ++ PIPE_RESTORE(0x7000); ++ PIPE_RESTORE(0x7400); ++ PIPE_RESTORE(0x7800); ++ PIPE_RESTORE(0x4400); ++ PIPE_RESTORE(0x0000); ++ PIPE_RESTORE(0x0040); ++ nouveau_wait_for_idle(dev); ++ ++#undef PIPE_RESTORE ++} ++ ++static void nv10_graph_create_pipe(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct graph_state *pgraph_ctx = chan->pgraph_ctx; ++ struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; ++ uint32_t *fifo_pipe_state_addr; ++ int i; ++#define PIPE_INIT(addr) \ ++ do { \ ++ fifo_pipe_state_addr = fifo_pipe_state->pipe_##addr; \ ++ } while (0) ++#define PIPE_INIT_END(addr) \ ++ do { \ ++ uint32_t *__end_addr = fifo_pipe_state->pipe_##addr + \ ++ ARRAY_SIZE(fifo_pipe_state->pipe_##addr); \ ++ if (fifo_pipe_state_addr != __end_addr) \ ++ NV_ERROR(dev, "incomplete pipe init for 0x%x : %p/%p\n", \ ++ addr, fifo_pipe_state_addr, __end_addr); \ ++ } while (0) ++#define NV_WRITE_PIPE_INIT(value) *(fifo_pipe_state_addr++) = value ++ ++ PIPE_INIT(0x0200); ++ for (i = 0; i < 48; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x0200); ++ ++ PIPE_INIT(0x6400); ++ for (i = 0; i < 211; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ NV_WRITE_PIPE_INIT(0x40000000); ++ NV_WRITE_PIPE_INIT(0x40000000); ++ NV_WRITE_PIPE_INIT(0x40000000); ++ NV_WRITE_PIPE_INIT(0x40000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x3f000000); ++ NV_WRITE_PIPE_INIT(0x3f000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ PIPE_INIT_END(0x6400); ++ ++ PIPE_INIT(0x6800); ++ for (i = 0; i < 162; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x3f800000); ++ for (i = 0; i < 25; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x6800); ++ ++ PIPE_INIT(0x6c00); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0xbf800000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x6c00); ++ ++ PIPE_INIT(0x7000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x00000000); ++ NV_WRITE_PIPE_INIT(0x7149f2ca); ++ for (i = 0; i < 35; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x7000); ++ ++ PIPE_INIT(0x7400); ++ for (i = 0; i < 48; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x7400); ++ ++ PIPE_INIT(0x7800); ++ for (i = 0; i < 48; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x7800); ++ ++ PIPE_INIT(0x4400); ++ for (i = 0; i < 32; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x4400); ++ ++ PIPE_INIT(0x0000); ++ for (i = 0; i < 16; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x0000); ++ ++ PIPE_INIT(0x0040); ++ for (i = 0; i < 4; i++) ++ NV_WRITE_PIPE_INIT(0x00000000); ++ PIPE_INIT_END(0x0040); ++ ++#undef PIPE_INIT ++#undef PIPE_INIT_END ++#undef NV_WRITE_PIPE_INIT ++} ++ ++static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg) ++{ ++ int i; ++ for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) { ++ if (nv10_graph_ctx_regs[i] == reg) ++ return i; ++ } ++ NV_ERROR(dev, "unknow offset nv10_ctx_regs %d\n", reg); ++ return -1; ++} ++ ++static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg) ++{ ++ int i; ++ for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) { ++ if (nv17_graph_ctx_regs[i] == reg) ++ return i; ++ } ++ NV_ERROR(dev, "unknow offset nv17_ctx_regs %d\n", reg); ++ return -1; ++} ++ ++int nv10_graph_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct graph_state *pgraph_ctx = chan->pgraph_ctx; ++ uint32_t tmp; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) ++ nv_wr32(dev, nv10_graph_ctx_regs[i], pgraph_ctx->nv10[i]); ++ if (dev_priv->chipset >= 0x17) { ++ for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) ++ nv_wr32(dev, nv17_graph_ctx_regs[i], ++ pgraph_ctx->nv17[i]); ++ } ++ ++ nv10_graph_load_pipe(chan); ++ ++ nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100); ++ tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER); ++ nv_wr32(dev, NV10_PGRAPH_CTX_USER, (tmp & 0xffffff) | chan->id << 24); ++ tmp = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2); ++ nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, tmp & 0xcfffffff); ++ return 0; ++} ++ ++int ++nv10_graph_unload_context(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; ++ struct nouveau_channel *chan; ++ struct graph_state *ctx; ++ uint32_t tmp; ++ int i; ++ ++ chan = pgraph->channel(dev); ++ if (!chan) ++ return 0; ++ ctx = chan->pgraph_ctx; ++ ++ for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) ++ ctx->nv10[i] = nv_rd32(dev, nv10_graph_ctx_regs[i]); ++ ++ if (dev_priv->chipset >= 0x17) { ++ for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) ++ ctx->nv17[i] = nv_rd32(dev, nv17_graph_ctx_regs[i]); ++ } ++ ++ nv10_graph_save_pipe(chan); ++ ++ nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000); ++ tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff; ++ tmp |= (pfifo->channels - 1) << 24; ++ nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp); ++ return 0; ++} ++ ++void ++nv10_graph_context_switch(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; ++ struct nouveau_channel *chan = NULL; ++ int chid; ++ ++ pgraph->fifo_access(dev, false); ++ nouveau_wait_for_idle(dev); ++ ++ /* If previous context is valid, we need to save it */ ++ nv10_graph_unload_context(dev); ++ ++ /* Load context for next channel */ ++ chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; ++ chan = dev_priv->fifos[chid]; ++ if (chan) ++ nv10_graph_load_context(chan); ++ ++ pgraph->fifo_access(dev, true); ++} ++ ++#define NV_WRITE_CTX(reg, val) do { \ ++ int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \ ++ if (offset > 0) \ ++ pgraph_ctx->nv10[offset] = val; \ ++ } while (0) ++ ++#define NV17_WRITE_CTX(reg, val) do { \ ++ int offset = nv17_graph_ctx_regs_find_offset(dev, reg); \ ++ if (offset > 0) \ ++ pgraph_ctx->nv17[offset] = val; \ ++ } while (0) ++ ++struct nouveau_channel * ++nv10_graph_channel(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int chid = dev_priv->engine.fifo.channels; ++ ++ if (nv_rd32(dev, NV10_PGRAPH_CTX_CONTROL) & 0x00010000) ++ chid = nv_rd32(dev, NV10_PGRAPH_CTX_USER) >> 24; ++ ++ if (chid >= dev_priv->engine.fifo.channels) ++ return NULL; ++ ++ return dev_priv->fifos[chid]; ++} ++ ++int nv10_graph_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct graph_state *pgraph_ctx; ++ ++ NV_DEBUG(dev, "nv10_graph_context_create %d\n", chan->id); ++ ++ chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), ++ GFP_KERNEL); ++ if (pgraph_ctx == NULL) ++ return -ENOMEM; ++ ++ ++ NV_WRITE_CTX(0x00400e88, 0x08000000); ++ NV_WRITE_CTX(0x00400e9c, 0x4b7fffff); ++ NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff); ++ NV_WRITE_CTX(0x00400e10, 0x00001000); ++ NV_WRITE_CTX(0x00400e14, 0x00001000); ++ NV_WRITE_CTX(0x00400e30, 0x00080008); ++ NV_WRITE_CTX(0x00400e34, 0x00080008); ++ if (dev_priv->chipset >= 0x17) { ++ /* is it really needed ??? */ ++ NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4, ++ nv_rd32(dev, NV10_PGRAPH_DEBUG_4)); ++ NV17_WRITE_CTX(0x004006b0, nv_rd32(dev, 0x004006b0)); ++ NV17_WRITE_CTX(0x00400eac, 0x0fff0000); ++ NV17_WRITE_CTX(0x00400eb0, 0x0fff0000); ++ NV17_WRITE_CTX(0x00400ec0, 0x00000080); ++ NV17_WRITE_CTX(0x00400ed0, 0x00000080); ++ } ++ NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->id << 24); ++ ++ nv10_graph_create_pipe(chan); ++ return 0; ++} ++ ++void nv10_graph_destroy_context(struct nouveau_channel *chan) ++{ ++ struct graph_state *pgraph_ctx = chan->pgraph_ctx; ++ ++ kfree(pgraph_ctx); ++ chan->pgraph_ctx = NULL; ++} ++ ++int nv10_graph_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ int i; ++ ++ nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ++ ~NV_PMC_ENABLE_PGRAPH); ++ nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | ++ NV_PMC_ENABLE_PGRAPH); ++ ++ nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); ++ nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); ++ ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000); ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700); ++ /* nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */ ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x25f92ad9); ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0x55DE0830 | ++ (1<<29) | ++ (1<<31)); ++ if (dev_priv->chipset >= 0x17) { ++ nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000); ++ nv_wr32(dev, 0x004006b0, 0x40000020); ++ } else ++ nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000); ++ ++ /* copy tile info from PFB */ ++ for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { ++ nv_wr32(dev, NV10_PGRAPH_TILE(i), ++ nv_rd32(dev, NV10_PFB_TILE(i))); ++ nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), ++ nv_rd32(dev, NV10_PFB_TLIMIT(i))); ++ nv_wr32(dev, NV10_PGRAPH_TSIZE(i), ++ nv_rd32(dev, NV10_PFB_TSIZE(i))); ++ nv_wr32(dev, NV10_PGRAPH_TSTATUS(i), ++ nv_rd32(dev, NV10_PFB_TSTATUS(i))); ++ } ++ ++ nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH1, 0x00000000); ++ nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH2, 0x00000000); ++ nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH3, 0x00000000); ++ nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH4, 0x00000000); ++ nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); ++ ++ tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff; ++ tmp |= (dev_priv->engine.fifo.channels - 1) << 24; ++ nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp); ++ nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100); ++ nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, 0x08000000); ++ ++ return 0; ++} ++ ++void nv10_graph_takedown(struct drm_device *dev) ++{ ++} ++ ++struct nouveau_pgraph_object_class nv10_graph_grclass[] = { ++ { 0x0030, false, NULL }, /* null */ ++ { 0x0039, false, NULL }, /* m2mf */ ++ { 0x004a, false, NULL }, /* gdirect */ ++ { 0x005f, false, NULL }, /* imageblit */ ++ { 0x009f, false, NULL }, /* imageblit (nv12) */ ++ { 0x008a, false, NULL }, /* ifc */ ++ { 0x0089, false, NULL }, /* sifm */ ++ { 0x0062, false, NULL }, /* surf2d */ ++ { 0x0043, false, NULL }, /* rop */ ++ { 0x0012, false, NULL }, /* beta1 */ ++ { 0x0072, false, NULL }, /* beta4 */ ++ { 0x0019, false, NULL }, /* cliprect */ ++ { 0x0044, false, NULL }, /* pattern */ ++ { 0x0052, false, NULL }, /* swzsurf */ ++ { 0x0093, false, NULL }, /* surf3d */ ++ { 0x0094, false, NULL }, /* tex_tri */ ++ { 0x0095, false, NULL }, /* multitex_tri */ ++ { 0x0056, false, NULL }, /* celcius (nv10) */ ++ { 0x0096, false, NULL }, /* celcius (nv11) */ ++ { 0x0099, false, NULL }, /* celcius (nv17) */ ++ {} ++}; +diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c +new file mode 100644 +index 0000000..34f95c7 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv17_tv.c +@@ -0,0 +1,689 @@ ++/* ++ * Copyright (C) 2009 Francisco Jerez. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_drv.h" ++#include "nouveau_encoder.h" ++#include "nouveau_connector.h" ++#include "nouveau_crtc.h" ++#include "nouveau_hw.h" ++#include "nv17_tv.h" ++ ++enum drm_connector_status nv17_tv_detect(struct drm_encoder *encoder, ++ struct drm_connector *connector, ++ uint32_t pin_mask) ++{ ++ struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); ++ ++ tv_enc->pin_mask = pin_mask; ++ ++ switch (pin_mask) { ++ case 0x2: ++ case 0x4: ++ tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Composite; ++ break; ++ case 0xc: ++ tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SVIDEO; ++ break; ++ case 0xe: ++ if (nouveau_encoder(encoder)->dcb->tvconf.has_component_output) ++ tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Component; ++ else ++ tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SCART; ++ break; ++ default: ++ tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Unknown; ++ break; ++ } ++ ++ drm_connector_property_set_value(connector, ++ encoder->dev->mode_config.tv_subconnector_property, ++ tv_enc->subconnector); ++ ++ return tv_enc->subconnector ? connector_status_connected : ++ connector_status_disconnected; ++} ++ ++static const struct { ++ int hdisplay; ++ int vdisplay; ++} modes[] = { ++ { 640, 400 }, ++ { 640, 480 }, ++ { 720, 480 }, ++ { 720, 576 }, ++ { 800, 600 }, ++ { 1024, 768 }, ++ { 1280, 720 }, ++ { 1280, 1024 }, ++ { 1920, 1080 } ++}; ++ ++static int nv17_tv_get_modes(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); ++ struct drm_display_mode *mode; ++ struct drm_display_mode *output_mode; ++ int n = 0; ++ int i; ++ ++ if (tv_norm->kind != CTV_ENC_MODE) { ++ struct drm_display_mode *tv_mode; ++ ++ for (tv_mode = nv17_tv_modes; tv_mode->hdisplay; tv_mode++) { ++ mode = drm_mode_duplicate(encoder->dev, tv_mode); ++ ++ mode->clock = tv_norm->tv_enc_mode.vrefresh * ++ mode->htotal / 1000 * ++ mode->vtotal / 1000; ++ ++ if (mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ mode->clock *= 2; ++ ++ if (mode->hdisplay == tv_norm->tv_enc_mode.hdisplay && ++ mode->vdisplay == tv_norm->tv_enc_mode.vdisplay) ++ mode->type |= DRM_MODE_TYPE_PREFERRED; ++ ++ drm_mode_probed_add(connector, mode); ++ n++; ++ } ++ return n; ++ } ++ ++ /* tv_norm->kind == CTV_ENC_MODE */ ++ output_mode = &tv_norm->ctv_enc_mode.mode; ++ for (i = 0; i < ARRAY_SIZE(modes); i++) { ++ if (modes[i].hdisplay > output_mode->hdisplay || ++ modes[i].vdisplay > output_mode->vdisplay) ++ continue; ++ ++ if (modes[i].hdisplay == output_mode->hdisplay && ++ modes[i].vdisplay == output_mode->vdisplay) { ++ mode = drm_mode_duplicate(encoder->dev, output_mode); ++ mode->type |= DRM_MODE_TYPE_PREFERRED; ++ } else { ++ mode = drm_cvt_mode(encoder->dev, modes[i].hdisplay, ++ modes[i].vdisplay, 60, false, ++ output_mode->flags & DRM_MODE_FLAG_INTERLACE, ++ false); ++ } ++ ++ /* CVT modes are sometimes unsuitable... */ ++ if (output_mode->hdisplay <= 720 ++ || output_mode->hdisplay >= 1920) { ++ mode->htotal = output_mode->htotal; ++ mode->hsync_start = (mode->hdisplay + (mode->htotal ++ - mode->hdisplay) * 9 / 10) & ~7; ++ mode->hsync_end = mode->hsync_start + 8; ++ } ++ if (output_mode->vdisplay >= 1024) { ++ mode->vtotal = output_mode->vtotal; ++ mode->vsync_start = output_mode->vsync_start; ++ mode->vsync_end = output_mode->vsync_end; ++ } ++ ++ mode->type |= DRM_MODE_TYPE_DRIVER; ++ drm_mode_probed_add(connector, mode); ++ n++; ++ } ++ return n; ++} ++ ++static int nv17_tv_mode_valid(struct drm_encoder *encoder, ++ struct drm_display_mode *mode) ++{ ++ struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); ++ ++ if (tv_norm->kind == CTV_ENC_MODE) { ++ struct drm_display_mode *output_mode = ++ &tv_norm->ctv_enc_mode.mode; ++ ++ if (mode->clock > 400000) ++ return MODE_CLOCK_HIGH; ++ ++ if (mode->hdisplay > output_mode->hdisplay || ++ mode->vdisplay > output_mode->vdisplay) ++ return MODE_BAD; ++ ++ if ((mode->flags & DRM_MODE_FLAG_INTERLACE) != ++ (output_mode->flags & DRM_MODE_FLAG_INTERLACE)) ++ return MODE_NO_INTERLACE; ++ ++ if (mode->flags & DRM_MODE_FLAG_DBLSCAN) ++ return MODE_NO_DBLESCAN; ++ ++ } else { ++ const int vsync_tolerance = 600; ++ ++ if (mode->clock > 70000) ++ return MODE_CLOCK_HIGH; ++ ++ if (abs(drm_mode_vrefresh(mode) * 1000 - ++ tv_norm->tv_enc_mode.vrefresh) > vsync_tolerance) ++ return MODE_VSYNC; ++ ++ /* The encoder takes care of the actual interlacing */ ++ if (mode->flags & DRM_MODE_FLAG_INTERLACE) ++ return MODE_NO_INTERLACE; ++ } ++ ++ return MODE_OK; ++} ++ ++static bool nv17_tv_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); ++ ++ if (tv_norm->kind == CTV_ENC_MODE) ++ adjusted_mode->clock = tv_norm->ctv_enc_mode.mode.clock; ++ else ++ adjusted_mode->clock = 90000; ++ ++ return true; ++} ++ ++static void nv17_tv_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv17_tv_state *regs = &to_tv_enc(encoder)->state; ++ struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); ++ ++ if (nouveau_encoder(encoder)->last_dpms == mode) ++ return; ++ nouveau_encoder(encoder)->last_dpms = mode; ++ ++ NV_TRACE(dev, "Setting dpms mode %d on TV encoder (output %d)\n", ++ mode, nouveau_encoder(encoder)->dcb->index); ++ ++ regs->ptv_200 &= ~1; ++ ++ if (tv_norm->kind == CTV_ENC_MODE) { ++ nv04_dfp_update_fp_control(encoder, mode); ++ ++ } else { ++ nv04_dfp_update_fp_control(encoder, DRM_MODE_DPMS_OFF); ++ ++ if (mode == DRM_MODE_DPMS_ON) ++ regs->ptv_200 |= 1; ++ } ++ ++ nv_load_ptv(dev, regs, 200); ++ ++ if (dev_priv->chipset >= 0x34) { ++ uint32_t *gpio_ext = &dev_priv->mode_reg.crtc_reg[0].gpio_ext; ++ ++ *gpio_ext &= ~(3 << 20); ++ if (mode == DRM_MODE_DPMS_ON) ++ *gpio_ext |= 1 << 20; ++ ++ NVWriteCRTC(dev, 0, NV_PCRTC_GPIO_EXT, *gpio_ext); ++ } ++ ++ nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); ++} ++ ++static void nv17_tv_prepare(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_encoder_helper_funcs *helper = encoder->helper_private; ++ struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); ++ int head = nouveau_crtc(encoder->crtc)->index; ++ uint8_t *cr_lcd = &dev_priv->mode_reg.crtc_reg[head].CRTC[ ++ NV_CIO_CRE_LCD__INDEX]; ++ uint32_t dacclk_off = NV_PRAMDAC_DACCLK + ++ nv04_dac_output_offset(encoder); ++ uint32_t dacclk; ++ ++ helper->dpms(encoder, DRM_MODE_DPMS_OFF); ++ ++ nv04_dfp_disable(dev, head); ++ ++ /* Unbind any FP encoders from this head if we need the FP ++ * stuff enabled. */ ++ if (tv_norm->kind == CTV_ENC_MODE) { ++ struct drm_encoder *enc; ++ ++ list_for_each_entry(enc, &dev->mode_config.encoder_list, head) { ++ struct dcb_entry *dcb = nouveau_encoder(enc)->dcb; ++ ++ if ((dcb->type == OUTPUT_TMDS || ++ dcb->type == OUTPUT_LVDS) && ++ !enc->crtc && ++ nv04_dfp_get_bound_head(dev, dcb) == head) { ++ nv04_dfp_bind_head(dev, dcb, head ^ 1, ++ dev_priv->VBIOS.fp.dual_link); ++ } ++ } ++ ++ } ++ ++ /* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f) ++ * at LCD__INDEX which we don't alter ++ */ ++ if (!(*cr_lcd & 0x44)) { ++ if (tv_norm->kind == CTV_ENC_MODE) ++ *cr_lcd = 0x1 | (head ? 0x0 : 0x8); ++ else ++ *cr_lcd = 0; ++ } ++ ++ /* Set the DACCLK register */ ++ dacclk = (NVReadRAMDAC(dev, 0, dacclk_off) & ~0x30) | 0x1; ++ ++ if (nv_arch(dev) == NV_40) ++ dacclk |= 1 << 20; ++ ++ if (tv_norm->kind == CTV_ENC_MODE) { ++ dacclk |= 0x20; ++ ++ if (head) ++ dacclk |= 0x100; ++ else ++ dacclk &= ~0x100; ++ ++ } else { ++ dacclk |= 0x10; ++ ++ } ++ ++ NVWriteRAMDAC(dev, 0, dacclk_off, dacclk); ++} ++ ++static void nv17_tv_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *drm_mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int head = nouveau_crtc(encoder->crtc)->index; ++ struct nv04_crtc_reg *regs = &dev_priv->mode_reg.crtc_reg[head]; ++ struct nv17_tv_state *tv_regs = &to_tv_enc(encoder)->state; ++ struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); ++ int i; ++ ++ regs->CRTC[NV_CIO_CRE_53] = 0x40; /* FP_HTIMING */ ++ regs->CRTC[NV_CIO_CRE_54] = 0; /* FP_VTIMING */ ++ regs->ramdac_630 = 0x2; /* turn off green mode (tv test pattern?) */ ++ regs->tv_setup = 1; ++ regs->ramdac_8c0 = 0x0; ++ ++ if (tv_norm->kind == TV_ENC_MODE) { ++ tv_regs->ptv_200 = 0x13111100; ++ if (head) ++ tv_regs->ptv_200 |= 0x10; ++ ++ tv_regs->ptv_20c = 0x808010; ++ tv_regs->ptv_304 = 0x2d00000; ++ tv_regs->ptv_600 = 0x0; ++ tv_regs->ptv_60c = 0x0; ++ tv_regs->ptv_610 = 0x1e00000; ++ ++ if (tv_norm->tv_enc_mode.vdisplay == 576) { ++ tv_regs->ptv_508 = 0x1200000; ++ tv_regs->ptv_614 = 0x33; ++ ++ } else if (tv_norm->tv_enc_mode.vdisplay == 480) { ++ tv_regs->ptv_508 = 0xf00000; ++ tv_regs->ptv_614 = 0x13; ++ } ++ ++ if (nv_arch(dev) >= NV_30) { ++ tv_regs->ptv_500 = 0xe8e0; ++ tv_regs->ptv_504 = 0x1710; ++ tv_regs->ptv_604 = 0x0; ++ tv_regs->ptv_608 = 0x0; ++ } else { ++ if (tv_norm->tv_enc_mode.vdisplay == 576) { ++ tv_regs->ptv_604 = 0x20; ++ tv_regs->ptv_608 = 0x10; ++ tv_regs->ptv_500 = 0x19710; ++ tv_regs->ptv_504 = 0x68f0; ++ ++ } else if (tv_norm->tv_enc_mode.vdisplay == 480) { ++ tv_regs->ptv_604 = 0x10; ++ tv_regs->ptv_608 = 0x20; ++ tv_regs->ptv_500 = 0x4b90; ++ tv_regs->ptv_504 = 0x1b480; ++ } ++ } ++ ++ for (i = 0; i < 0x40; i++) ++ tv_regs->tv_enc[i] = tv_norm->tv_enc_mode.tv_enc[i]; ++ ++ } else { ++ struct drm_display_mode *output_mode = ++ &tv_norm->ctv_enc_mode.mode; ++ ++ /* The registers in PRAMDAC+0xc00 control some timings and CSC ++ * parameters for the CTV encoder (It's only used for "HD" TV ++ * modes, I don't think I have enough working to guess what ++ * they exactly mean...), it's probably connected at the ++ * output of the FP encoder, but it also needs the analog ++ * encoder in its OR enabled and routed to the head it's ++ * using. It's enabled with the DACCLK register, bits [5:4]. ++ */ ++ for (i = 0; i < 38; i++) ++ regs->ctv_regs[i] = tv_norm->ctv_enc_mode.ctv_regs[i]; ++ ++ regs->fp_horiz_regs[FP_DISPLAY_END] = output_mode->hdisplay - 1; ++ regs->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1; ++ regs->fp_horiz_regs[FP_SYNC_START] = ++ output_mode->hsync_start - 1; ++ regs->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1; ++ regs->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay + ++ max((output_mode->hdisplay-600)/40 - 1, 1); ++ ++ regs->fp_vert_regs[FP_DISPLAY_END] = output_mode->vdisplay - 1; ++ regs->fp_vert_regs[FP_TOTAL] = output_mode->vtotal - 1; ++ regs->fp_vert_regs[FP_SYNC_START] = ++ output_mode->vsync_start - 1; ++ regs->fp_vert_regs[FP_SYNC_END] = output_mode->vsync_end - 1; ++ regs->fp_vert_regs[FP_CRTC] = output_mode->vdisplay - 1; ++ ++ regs->fp_control = NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | ++ NV_PRAMDAC_FP_TG_CONTROL_READ_PROG | ++ NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12; ++ ++ if (output_mode->flags & DRM_MODE_FLAG_PVSYNC) ++ regs->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS; ++ if (output_mode->flags & DRM_MODE_FLAG_PHSYNC) ++ regs->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS; ++ ++ regs->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; ++ ++ regs->fp_debug_2 = 0; ++ ++ regs->fp_margin_color = 0x801080; ++ ++ } ++} ++ ++static void nv17_tv_commit(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_encoder_helper_funcs *helper = encoder->helper_private; ++ ++ if (get_tv_norm(encoder)->kind == TV_ENC_MODE) { ++ nv17_tv_update_rescaler(encoder); ++ nv17_tv_update_properties(encoder); ++ } else { ++ nv17_ctv_update_rescaler(encoder); ++ } ++ ++ nv17_tv_state_load(dev, &to_tv_enc(encoder)->state); ++ ++ /* This could use refinement for flatpanels, but it should work */ ++ if (dev_priv->chipset < 0x44) ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + ++ nv04_dac_output_offset(encoder), ++ 0xf0000000); ++ else ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + ++ nv04_dac_output_offset(encoder), ++ 0x00100000); ++ ++ helper->dpms(encoder, DRM_MODE_DPMS_ON); ++ ++ NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", ++ drm_get_connector_name( ++ &nouveau_encoder_connector_get(nv_encoder)->base), ++ nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); ++} ++ ++static void nv17_tv_save(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); ++ ++ nouveau_encoder(encoder)->restore.output = ++ NVReadRAMDAC(dev, 0, ++ NV_PRAMDAC_DACCLK + ++ nv04_dac_output_offset(encoder)); ++ ++ nv17_tv_state_save(dev, &tv_enc->saved_state); ++ ++ tv_enc->state.ptv_200 = tv_enc->saved_state.ptv_200; ++} ++ ++static void nv17_tv_restore(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ ++ NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + ++ nv04_dac_output_offset(encoder), ++ nouveau_encoder(encoder)->restore.output); ++ ++ nv17_tv_state_load(dev, &to_tv_enc(encoder)->saved_state); ++} ++ ++static int nv17_tv_create_resources(struct drm_encoder *encoder, ++ struct drm_connector *connector) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_mode_config *conf = &dev->mode_config; ++ struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); ++ struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; ++ int num_tv_norms = dcb->tvconf.has_component_output ? NUM_TV_NORMS : ++ NUM_LD_TV_NORMS; ++ int i; ++ ++ if (nouveau_tv_norm) { ++ for (i = 0; i < num_tv_norms; i++) { ++ if (!strcmp(nv17_tv_norm_names[i], nouveau_tv_norm)) { ++ tv_enc->tv_norm = i; ++ break; ++ } ++ } ++ ++ if (i == num_tv_norms) ++ NV_WARN(dev, "Invalid TV norm setting \"%s\"\n", ++ nouveau_tv_norm); ++ } ++ ++ drm_mode_create_tv_properties(dev, num_tv_norms, nv17_tv_norm_names); ++ ++ drm_connector_attach_property(connector, ++ conf->tv_select_subconnector_property, ++ tv_enc->select_subconnector); ++ drm_connector_attach_property(connector, ++ conf->tv_subconnector_property, ++ tv_enc->subconnector); ++ drm_connector_attach_property(connector, ++ conf->tv_mode_property, ++ tv_enc->tv_norm); ++ drm_connector_attach_property(connector, ++ conf->tv_flicker_reduction_property, ++ tv_enc->flicker); ++ drm_connector_attach_property(connector, ++ conf->tv_saturation_property, ++ tv_enc->saturation); ++ drm_connector_attach_property(connector, ++ conf->tv_hue_property, ++ tv_enc->hue); ++ drm_connector_attach_property(connector, ++ conf->tv_overscan_property, ++ tv_enc->overscan); ++ ++ return 0; ++} ++ ++static int nv17_tv_set_property(struct drm_encoder *encoder, ++ struct drm_connector *connector, ++ struct drm_property *property, ++ uint64_t val) ++{ ++ struct drm_mode_config *conf = &encoder->dev->mode_config; ++ struct drm_crtc *crtc = encoder->crtc; ++ struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); ++ struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); ++ bool modes_changed = false; ++ ++ if (property == conf->tv_overscan_property) { ++ tv_enc->overscan = val; ++ if (encoder->crtc) { ++ if (tv_norm->kind == CTV_ENC_MODE) ++ nv17_ctv_update_rescaler(encoder); ++ else ++ nv17_tv_update_rescaler(encoder); ++ } ++ ++ } else if (property == conf->tv_saturation_property) { ++ if (tv_norm->kind != TV_ENC_MODE) ++ return -EINVAL; ++ ++ tv_enc->saturation = val; ++ nv17_tv_update_properties(encoder); ++ ++ } else if (property == conf->tv_hue_property) { ++ if (tv_norm->kind != TV_ENC_MODE) ++ return -EINVAL; ++ ++ tv_enc->hue = val; ++ nv17_tv_update_properties(encoder); ++ ++ } else if (property == conf->tv_flicker_reduction_property) { ++ if (tv_norm->kind != TV_ENC_MODE) ++ return -EINVAL; ++ ++ tv_enc->flicker = val; ++ if (encoder->crtc) ++ nv17_tv_update_rescaler(encoder); ++ ++ } else if (property == conf->tv_mode_property) { ++ if (connector->dpms != DRM_MODE_DPMS_OFF) ++ return -EINVAL; ++ ++ tv_enc->tv_norm = val; ++ ++ modes_changed = true; ++ ++ } else if (property == conf->tv_select_subconnector_property) { ++ if (tv_norm->kind != TV_ENC_MODE) ++ return -EINVAL; ++ ++ tv_enc->select_subconnector = val; ++ nv17_tv_update_properties(encoder); ++ ++ } else { ++ return -EINVAL; ++ } ++ ++ if (modes_changed) { ++ drm_helper_probe_single_connector_modes(connector, 0, 0); ++ ++ /* Disable the crtc to ensure a full modeset is ++ * performed whenever it's turned on again. */ ++ if (crtc) { ++ struct drm_mode_set modeset = { ++ .crtc = crtc, ++ }; ++ ++ crtc->funcs->set_config(&modeset); ++ } ++ } ++ ++ return 0; ++} ++ ++static void nv17_tv_destroy(struct drm_encoder *encoder) ++{ ++ struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); ++ ++ NV_DEBUG(encoder->dev, "\n"); ++ ++ drm_encoder_cleanup(encoder); ++ kfree(tv_enc); ++} ++ ++static struct drm_encoder_helper_funcs nv17_tv_helper_funcs = { ++ .dpms = nv17_tv_dpms, ++ .save = nv17_tv_save, ++ .restore = nv17_tv_restore, ++ .mode_fixup = nv17_tv_mode_fixup, ++ .prepare = nv17_tv_prepare, ++ .commit = nv17_tv_commit, ++ .mode_set = nv17_tv_mode_set, ++ .detect = nv17_dac_detect, ++}; ++ ++static struct drm_encoder_slave_funcs nv17_tv_slave_funcs = { ++ .get_modes = nv17_tv_get_modes, ++ .mode_valid = nv17_tv_mode_valid, ++ .create_resources = nv17_tv_create_resources, ++ .set_property = nv17_tv_set_property, ++}; ++ ++static struct drm_encoder_funcs nv17_tv_funcs = { ++ .destroy = nv17_tv_destroy, ++}; ++ ++int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry) ++{ ++ struct drm_encoder *encoder; ++ struct nv17_tv_encoder *tv_enc = NULL; ++ ++ tv_enc = kzalloc(sizeof(*tv_enc), GFP_KERNEL); ++ if (!tv_enc) ++ return -ENOMEM; ++ ++ tv_enc->overscan = 50; ++ tv_enc->flicker = 50; ++ tv_enc->saturation = 50; ++ tv_enc->hue = 0; ++ tv_enc->tv_norm = TV_NORM_PAL; ++ tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Unknown; ++ tv_enc->select_subconnector = DRM_MODE_SUBCONNECTOR_Automatic; ++ tv_enc->pin_mask = 0; ++ ++ encoder = to_drm_encoder(&tv_enc->base); ++ ++ tv_enc->base.dcb = entry; ++ tv_enc->base.or = ffs(entry->or) - 1; ++ ++ drm_encoder_init(dev, encoder, &nv17_tv_funcs, DRM_MODE_ENCODER_TVDAC); ++ drm_encoder_helper_add(encoder, &nv17_tv_helper_funcs); ++ to_encoder_slave(encoder)->slave_funcs = &nv17_tv_slave_funcs; ++ ++ encoder->possible_crtcs = entry->heads; ++ encoder->possible_clones = 0; ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv17_tv.h b/drivers/gpu/drm/nouveau/nv17_tv.h +new file mode 100644 +index 0000000..c00977c +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv17_tv.h +@@ -0,0 +1,156 @@ ++/* ++ * Copyright (C) 2009 Francisco Jerez. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 __NV17_TV_H__ ++#define __NV17_TV_H__ ++ ++struct nv17_tv_state { ++ uint8_t tv_enc[0x40]; ++ ++ uint32_t hfilter[4][7]; ++ uint32_t hfilter2[4][7]; ++ uint32_t vfilter[4][7]; ++ ++ uint32_t ptv_200; ++ uint32_t ptv_204; ++ uint32_t ptv_208; ++ uint32_t ptv_20c; ++ uint32_t ptv_304; ++ uint32_t ptv_500; ++ uint32_t ptv_504; ++ uint32_t ptv_508; ++ uint32_t ptv_600; ++ uint32_t ptv_604; ++ uint32_t ptv_608; ++ uint32_t ptv_60c; ++ uint32_t ptv_610; ++ uint32_t ptv_614; ++}; ++ ++enum nv17_tv_norm{ ++ TV_NORM_PAL, ++ TV_NORM_PAL_M, ++ TV_NORM_PAL_N, ++ TV_NORM_PAL_NC, ++ TV_NORM_NTSC_M, ++ TV_NORM_NTSC_J, ++ NUM_LD_TV_NORMS, ++ TV_NORM_HD480I = NUM_LD_TV_NORMS, ++ TV_NORM_HD480P, ++ TV_NORM_HD576I, ++ TV_NORM_HD576P, ++ TV_NORM_HD720P, ++ TV_NORM_HD1080I, ++ NUM_TV_NORMS ++}; ++ ++struct nv17_tv_encoder { ++ struct nouveau_encoder base; ++ ++ struct nv17_tv_state state; ++ struct nv17_tv_state saved_state; ++ ++ int overscan; ++ int flicker; ++ int saturation; ++ int hue; ++ enum nv17_tv_norm tv_norm; ++ int subconnector; ++ int select_subconnector; ++ uint32_t pin_mask; ++}; ++#define to_tv_enc(x) container_of(nouveau_encoder(x), \ ++ struct nv17_tv_encoder, base) ++ ++extern char *nv17_tv_norm_names[NUM_TV_NORMS]; ++ ++extern struct nv17_tv_norm_params { ++ enum { ++ TV_ENC_MODE, ++ CTV_ENC_MODE, ++ } kind; ++ ++ union { ++ struct { ++ int hdisplay; ++ int vdisplay; ++ int vrefresh; /* mHz */ ++ ++ uint8_t tv_enc[0x40]; ++ } tv_enc_mode; ++ ++ struct { ++ struct drm_display_mode mode; ++ ++ uint32_t ctv_regs[38]; ++ } ctv_enc_mode; ++ }; ++ ++} nv17_tv_norms[NUM_TV_NORMS]; ++#define get_tv_norm(enc) (&nv17_tv_norms[to_tv_enc(enc)->tv_norm]) ++ ++extern struct drm_display_mode nv17_tv_modes[]; ++ ++static inline int interpolate(int y0, int y1, int y2, int x) ++{ ++ return y1 + (x < 50 ? y1 - y0 : y2 - y1) * (x - 50) / 50; ++} ++ ++void nv17_tv_state_save(struct drm_device *dev, struct nv17_tv_state *state); ++void nv17_tv_state_load(struct drm_device *dev, struct nv17_tv_state *state); ++void nv17_tv_update_properties(struct drm_encoder *encoder); ++void nv17_tv_update_rescaler(struct drm_encoder *encoder); ++void nv17_ctv_update_rescaler(struct drm_encoder *encoder); ++ ++/* TV hardware access functions */ ++ ++static inline void nv_write_ptv(struct drm_device *dev, uint32_t reg, uint32_t val) ++{ ++ nv_wr32(dev, reg, val); ++} ++ ++static inline uint32_t nv_read_ptv(struct drm_device *dev, uint32_t reg) ++{ ++ return nv_rd32(dev, reg); ++} ++ ++static inline void nv_write_tv_enc(struct drm_device *dev, uint8_t reg, uint8_t val) ++{ ++ nv_write_ptv(dev, NV_PTV_TV_INDEX, reg); ++ nv_write_ptv(dev, NV_PTV_TV_DATA, val); ++} ++ ++static inline uint8_t nv_read_tv_enc(struct drm_device *dev, uint8_t reg) ++{ ++ nv_write_ptv(dev, NV_PTV_TV_INDEX, reg); ++ return nv_read_ptv(dev, NV_PTV_TV_DATA); ++} ++ ++#define nv_load_ptv(dev, state, reg) nv_write_ptv(dev, NV_PTV_OFFSET + 0x##reg, state->ptv_##reg) ++#define nv_save_ptv(dev, state, reg) state->ptv_##reg = nv_read_ptv(dev, NV_PTV_OFFSET + 0x##reg) ++#define nv_load_tv_enc(dev, state, reg) nv_write_tv_enc(dev, 0x##reg, state->tv_enc[0x##reg]) ++ ++#endif +diff --git a/drivers/gpu/drm/nouveau/nv17_tv_modes.c b/drivers/gpu/drm/nouveau/nv17_tv_modes.c +new file mode 100644 +index 0000000..d64683d +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv17_tv_modes.c +@@ -0,0 +1,583 @@ ++/* ++ * Copyright (C) 2009 Francisco Jerez. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm_crtc_helper.h" ++#include "nouveau_drv.h" ++#include "nouveau_encoder.h" ++#include "nouveau_crtc.h" ++#include "nouveau_hw.h" ++#include "nv17_tv.h" ++ ++char *nv17_tv_norm_names[NUM_TV_NORMS] = { ++ [TV_NORM_PAL] = "PAL", ++ [TV_NORM_PAL_M] = "PAL-M", ++ [TV_NORM_PAL_N] = "PAL-N", ++ [TV_NORM_PAL_NC] = "PAL-Nc", ++ [TV_NORM_NTSC_M] = "NTSC-M", ++ [TV_NORM_NTSC_J] = "NTSC-J", ++ [TV_NORM_HD480I] = "hd480i", ++ [TV_NORM_HD480P] = "hd480p", ++ [TV_NORM_HD576I] = "hd576i", ++ [TV_NORM_HD576P] = "hd576p", ++ [TV_NORM_HD720P] = "hd720p", ++ [TV_NORM_HD1080I] = "hd1080i" ++}; ++ ++/* TV standard specific parameters */ ++ ++struct nv17_tv_norm_params nv17_tv_norms[NUM_TV_NORMS] = { ++ [TV_NORM_PAL] = { TV_ENC_MODE, { ++ .tv_enc_mode = { 720, 576, 50000, { ++ 0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18, ++ 0x7e, 0x40, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3, ++ 0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c, ++ 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3, ++ 0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5, ++ 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0, ++ 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b, ++ 0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0 ++ } } } }, ++ ++ [TV_NORM_PAL_M] = { TV_ENC_MODE, { ++ .tv_enc_mode = { 720, 480, 59940, { ++ 0x21, 0xe6, 0xef, 0xe3, 0x0, 0x0, 0xb, 0x18, ++ 0x7e, 0x44, 0x76, 0x32, 0x25, 0x0, 0x3c, 0x0, ++ 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83, ++ 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1, ++ 0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5, ++ 0x0, 0x18, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0, ++ 0x0, 0xb4, 0x0, 0x15, 0x40, 0x10, 0x0, 0x9c, ++ 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0 ++ } } } }, ++ ++ [TV_NORM_PAL_N] = { TV_ENC_MODE, { ++ .tv_enc_mode = { 720, 576, 50000, { ++ 0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18, ++ 0x7e, 0x40, 0x8a, 0x32, 0x25, 0x0, 0x3c, 0x0, ++ 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c, ++ 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1, ++ 0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5, ++ 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0, ++ 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b, ++ 0xbd, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0 ++ } } } }, ++ ++ [TV_NORM_PAL_NC] = { TV_ENC_MODE, { ++ .tv_enc_mode = { 720, 576, 50000, { ++ 0x21, 0xf6, 0x94, 0x46, 0x0, 0x0, 0xb, 0x18, ++ 0x7e, 0x44, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3, ++ 0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c, ++ 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3, ++ 0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5, ++ 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0, ++ 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b, ++ 0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0 ++ } } } }, ++ ++ [TV_NORM_NTSC_M] = { TV_ENC_MODE, { ++ .tv_enc_mode = { 720, 480, 59940, { ++ 0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18, ++ 0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x3c, 0x0, ++ 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83, ++ 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1, ++ 0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5, ++ 0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0, ++ 0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0x9c, ++ 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0 ++ } } } }, ++ ++ [TV_NORM_NTSC_J] = { TV_ENC_MODE, { ++ .tv_enc_mode = { 720, 480, 59940, { ++ 0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18, ++ 0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x32, 0x0, ++ 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83, ++ 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1, ++ 0xcf, 0x4, 0xcf, 0x1, 0x2, 0x0, 0xa, 0x5, ++ 0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0, ++ 0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0xa4, ++ 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0 ++ } } } }, ++ ++ [TV_NORM_HD480I] = { TV_ENC_MODE, { ++ .tv_enc_mode = { 720, 480, 59940, { ++ 0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18, ++ 0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x32, 0x0, ++ 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83, ++ 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1, ++ 0xcf, 0x4, 0xcf, 0x1, 0x2, 0x0, 0xa, 0x5, ++ 0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0, ++ 0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0xa4, ++ 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0 ++ } } } }, ++ ++ [TV_NORM_HD576I] = { TV_ENC_MODE, { ++ .tv_enc_mode = { 720, 576, 50000, { ++ 0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18, ++ 0x7e, 0x40, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3, ++ 0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c, ++ 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3, ++ 0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5, ++ 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0, ++ 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b, ++ 0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0 ++ } } } }, ++ ++ ++ [TV_NORM_HD480P] = { CTV_ENC_MODE, { ++ .ctv_enc_mode = { ++ .mode = { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, ++ 720, 735, 743, 858, 0, 480, 490, 494, 525, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ .ctv_regs = { 0x3540000, 0x0, 0x0, 0x314, ++ 0x354003a, 0x40000, 0x6f0344, 0x18100000, ++ 0x10160004, 0x10060005, 0x1006000c, 0x10060020, ++ 0x10060021, 0x140e0022, 0x10060202, 0x1802020a, ++ 0x1810020b, 0x10000fff, 0x10000fff, 0x10000fff, ++ 0x10000fff, 0x10000fff, 0x10000fff, 0x70, ++ 0x3ff0000, 0x57, 0x2e001e, 0x258012c, ++ 0xa0aa04ec, 0x30, 0x80960019, 0x12c0300, ++ 0x2019, 0x600, 0x32060019, 0x0, 0x0, 0x400 ++ } } } }, ++ ++ [TV_NORM_HD576P] = { CTV_ENC_MODE, { ++ .ctv_enc_mode = { ++ .mode = { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, ++ 720, 730, 738, 864, 0, 576, 581, 585, 625, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ .ctv_regs = { 0x3540000, 0x0, 0x0, 0x314, ++ 0x354003a, 0x40000, 0x6f0344, 0x18100000, ++ 0x10060001, 0x10060009, 0x10060026, 0x10060027, ++ 0x140e0028, 0x10060268, 0x1810026d, 0x10000fff, ++ 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, ++ 0x10000fff, 0x10000fff, 0x10000fff, 0x69, ++ 0x3ff0000, 0x57, 0x2e001e, 0x258012c, ++ 0xa0aa04ec, 0x30, 0x80960019, 0x12c0300, ++ 0x2019, 0x600, 0x32060019, 0x0, 0x0, 0x400 ++ } } } }, ++ ++ [TV_NORM_HD720P] = { CTV_ENC_MODE, { ++ .ctv_enc_mode = { ++ .mode = { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, ++ 1280, 1349, 1357, 1650, 0, 720, 725, 730, 750, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ .ctv_regs = { 0x1260394, 0x0, 0x0, 0x622, ++ 0x66b0021, 0x6004a, 0x1210626, 0x8170000, ++ 0x70004, 0x70016, 0x70017, 0x40f0018, ++ 0x702e8, 0x81702ed, 0xfff, 0xfff, ++ 0xfff, 0xfff, 0xfff, 0xfff, ++ 0xfff, 0xfff, 0xfff, 0x0, ++ 0x2e40001, 0x58, 0x2e001e, 0x258012c, ++ 0xa0aa04ec, 0x30, 0x810c0039, 0x12c0300, ++ 0xc0002039, 0x600, 0x32060039, 0x0, 0x0, 0x0 ++ } } } }, ++ ++ [TV_NORM_HD1080I] = { CTV_ENC_MODE, { ++ .ctv_enc_mode = { ++ .mode = { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, ++ 1920, 1961, 2049, 2200, 0, 1080, 1084, 1088, 1125, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC ++ | DRM_MODE_FLAG_INTERLACE) }, ++ .ctv_regs = { 0xac0420, 0x44c0478, 0x4a4, 0x4fc0868, ++ 0x8940028, 0x60054, 0xe80870, 0xbf70000, ++ 0xbc70004, 0x70005, 0x70012, 0x70013, ++ 0x40f0014, 0x70230, 0xbf70232, 0xbf70233, ++ 0x1c70237, 0x70238, 0x70244, 0x70245, ++ 0x40f0246, 0x70462, 0x1f70464, 0x0, ++ 0x2e40001, 0x58, 0x2e001e, 0x258012c, ++ 0xa0aa04ec, 0x30, 0x815f004c, 0x12c0300, ++ 0xc000204c, 0x600, 0x3206004c, 0x0, 0x0, 0x0 ++ } } } } ++}; ++ ++/* ++ * The following is some guesswork on how the TV encoder flicker ++ * filter/rescaler works: ++ * ++ * It seems to use some sort of resampling filter, it is controlled ++ * through the registers at NV_PTV_HFILTER and NV_PTV_VFILTER, they ++ * control the horizontal and vertical stage respectively, there is ++ * also NV_PTV_HFILTER2 the blob fills identically to NV_PTV_HFILTER, ++ * but they seem to do nothing. A rough guess might be that they could ++ * be used to independently control the filtering of each interlaced ++ * field, but I don't know how they are enabled. The whole filtering ++ * process seems to be disabled with bits 26:27 of PTV_200, but we ++ * aren't doing that. ++ * ++ * The layout of both register sets is the same: ++ * ++ * A: [BASE+0x18]...[BASE+0x0] [BASE+0x58]..[BASE+0x40] ++ * B: [BASE+0x34]...[BASE+0x1c] [BASE+0x74]..[BASE+0x5c] ++ * ++ * Each coefficient is stored in bits [31],[15:9] in two's complement ++ * format. They seem to be some kind of weights used in a low-pass ++ * filter. Both A and B coefficients are applied to the 14 nearest ++ * samples on each side (Listed from nearest to furthermost. They ++ * roughly cover 2 framebuffer pixels on each side). They are ++ * probably multiplied with some more hardwired weights before being ++ * used: B-coefficients are applied the same on both sides, ++ * A-coefficients are inverted before being applied to the opposite ++ * side. ++ * ++ * After all the hassle, I got the following formula by empirical ++ * means... ++ */ ++ ++#define calc_overscan(o) interpolate(0x100, 0xe1, 0xc1, o) ++ ++#define id1 (1LL << 8) ++#define id2 (1LL << 16) ++#define id3 (1LL << 24) ++#define id4 (1LL << 32) ++#define id5 (1LL << 48) ++ ++static struct filter_params{ ++ int64_t k1; ++ int64_t ki; ++ int64_t ki2; ++ int64_t ki3; ++ int64_t kr; ++ int64_t kir; ++ int64_t ki2r; ++ int64_t ki3r; ++ int64_t kf; ++ int64_t kif; ++ int64_t ki2f; ++ int64_t ki3f; ++ int64_t krf; ++ int64_t kirf; ++ int64_t ki2rf; ++ int64_t ki3rf; ++} fparams[2][4] = { ++ /* Horizontal filter parameters */ ++ { ++ {64.311690 * id5, -39.516924 * id5, 6.586143 * id5, 0.000002 * id5, ++ 0.051285 * id4, 26.168746 * id4, -4.361449 * id4, -0.000001 * id4, ++ 9.308169 * id3, 78.180965 * id3, -13.030158 * id3, -0.000001 * id3, ++ -8.801540 * id1, -46.572890 * id1, 7.762145 * id1, -0.000000 * id1}, ++ {-44.565569 * id5, -68.081246 * id5, 39.812074 * id5, -4.009316 * id5, ++ 29.832207 * id4, 50.047322 * id4, -25.380017 * id4, 2.546422 * id4, ++ 104.605622 * id3, 141.908641 * id3, -74.322319 * id3, 7.484316 * id3, ++ -37.081621 * id1, -90.397510 * id1, 42.784229 * id1, -4.289952 * id1}, ++ {-56.793244 * id5, 31.153584 * id5, -5.192247 * id5, -0.000003 * id5, ++ 33.541131 * id4, -34.149302 * id4, 5.691537 * id4, 0.000002 * id4, ++ 87.196610 * id3, -88.995169 * id3, 14.832456 * id3, 0.000012 * id3, ++ 17.288138 * id1, 71.864786 * id1, -11.977408 * id1, -0.000009 * id1}, ++ {51.787796 * id5, 21.211771 * id5, -18.993730 * id5, 1.853310 * id5, ++ -41.470726 * id4, -17.775823 * id4, 13.057821 * id4, -1.15823 * id4, ++ -154.235673 * id3, -44.878641 * id3, 40.656077 * id3, -3.695595 * id3, ++ 112.201065 * id1, 39.992155 * id1, -25.155714 * id1, 2.113984 * id1}, ++ }, ++ ++ /* Vertical filter parameters */ ++ { ++ {67.601979 * id5, 0.428319 * id5, -0.071318 * id5, -0.000012 * id5, ++ -3.402339 * id4, 0.000209 * id4, -0.000092 * id4, 0.000010 * id4, ++ -9.180996 * id3, 6.111270 * id3, -1.024457 * id3, 0.001043 * id3, ++ 6.060315 * id1, -0.017425 * id1, 0.007830 * id1, -0.000869 * id1}, ++ {6.755647 * id5, 5.841348 * id5, 1.469734 * id5, -0.149656 * id5, ++ 8.293120 * id4, -1.192888 * id4, -0.947652 * id4, 0.094507 * id4, ++ 37.526655 * id3, 10.257875 * id3, -10.823275 * id3, 1.081497 * id3, ++ -2.361928 * id1, -2.059432 * id1, 1.840671 * id1, -0.168100 * id1}, ++ {-14.780391 * id5, -16.042148 * id5, 2.673692 * id5, -0.000000 * id5, ++ 39.541978 * id4, 5.680053 * id4, -0.946676 * id4, 0.000000 * id4, ++ 152.994486 * id3, 12.625439 * id3, -2.119579 * id3, 0.002708 * id3, ++ -38.125089 * id1, -0.855880 * id1, 0.155359 * id1, -0.002245 * id1}, ++ {-27.476193 * id5, -1.454976 * id5, 1.286557 * id5, 0.025346 * id5, ++ 20.687300 * id4, 3.014003 * id4, -0.557786 * id4, -0.01311 * id4, ++ 60.008737 * id3, -0.738273 * id3, 5.408217 * id3, -0.796798 * id3, ++ -17.296835 * id1, 4.438577 * id1, -2.809420 * id1, 0.385491 * id1}, ++ } ++}; ++ ++static void tv_setup_filter(struct drm_encoder *encoder) ++{ ++ struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); ++ struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); ++ struct drm_display_mode *mode = &encoder->crtc->mode; ++ uint32_t (*filters[])[4][7] = {&tv_enc->state.hfilter, ++ &tv_enc->state.vfilter}; ++ int i, j, k; ++ int32_t overscan = calc_overscan(tv_enc->overscan); ++ int64_t flicker = (tv_enc->flicker - 50) * (id3 / 100); ++ uint64_t rs[] = {mode->hdisplay * id3, ++ mode->vdisplay * id3}; ++ ++ do_div(rs[0], overscan * tv_norm->tv_enc_mode.hdisplay); ++ do_div(rs[1], overscan * tv_norm->tv_enc_mode.vdisplay); ++ ++ for (k = 0; k < 2; k++) { ++ rs[k] = max((int64_t)rs[k], id2); ++ ++ for (j = 0; j < 4; j++) { ++ struct filter_params *p = &fparams[k][j]; ++ ++ for (i = 0; i < 7; i++) { ++ int64_t c = (p->k1 + p->ki*i + p->ki2*i*i + p->ki3*i*i*i) ++ + (p->kr + p->kir*i + p->ki2r*i*i + p->ki3r*i*i*i)*rs[k] ++ + (p->kf + p->kif*i + p->ki2f*i*i + p->ki3f*i*i*i)*flicker ++ + (p->krf + p->kirf*i + p->ki2rf*i*i + p->ki3rf*i*i*i)*flicker*rs[k]; ++ ++ (*filters[k])[j][i] = (c + id5/2) >> 39 & (0x1 << 31 | 0x7f << 9); ++ } ++ } ++ } ++} ++ ++/* Hardware state saving/restoring */ ++ ++static void tv_save_filter(struct drm_device *dev, uint32_t base, uint32_t regs[4][7]) ++{ ++ int i, j; ++ uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c }; ++ ++ for (i = 0; i < 4; i++) { ++ for (j = 0; j < 7; j++) ++ regs[i][j] = nv_read_ptv(dev, offsets[i]+4*j); ++ } ++} ++ ++static void tv_load_filter(struct drm_device *dev, uint32_t base, uint32_t regs[4][7]) ++{ ++ int i, j; ++ uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c }; ++ ++ for (i = 0; i < 4; i++) { ++ for (j = 0; j < 7; j++) ++ nv_write_ptv(dev, offsets[i]+4*j, regs[i][j]); ++ } ++} ++ ++void nv17_tv_state_save(struct drm_device *dev, struct nv17_tv_state *state) ++{ ++ int i; ++ ++ for (i = 0; i < 0x40; i++) ++ state->tv_enc[i] = nv_read_tv_enc(dev, i); ++ ++ tv_save_filter(dev, NV_PTV_HFILTER, state->hfilter); ++ tv_save_filter(dev, NV_PTV_HFILTER2, state->hfilter2); ++ tv_save_filter(dev, NV_PTV_VFILTER, state->vfilter); ++ ++ nv_save_ptv(dev, state, 200); ++ nv_save_ptv(dev, state, 204); ++ nv_save_ptv(dev, state, 208); ++ nv_save_ptv(dev, state, 20c); ++ nv_save_ptv(dev, state, 304); ++ nv_save_ptv(dev, state, 500); ++ nv_save_ptv(dev, state, 504); ++ nv_save_ptv(dev, state, 508); ++ nv_save_ptv(dev, state, 600); ++ nv_save_ptv(dev, state, 604); ++ nv_save_ptv(dev, state, 608); ++ nv_save_ptv(dev, state, 60c); ++ nv_save_ptv(dev, state, 610); ++ nv_save_ptv(dev, state, 614); ++} ++ ++void nv17_tv_state_load(struct drm_device *dev, struct nv17_tv_state *state) ++{ ++ int i; ++ ++ for (i = 0; i < 0x40; i++) ++ nv_write_tv_enc(dev, i, state->tv_enc[i]); ++ ++ tv_load_filter(dev, NV_PTV_HFILTER, state->hfilter); ++ tv_load_filter(dev, NV_PTV_HFILTER2, state->hfilter2); ++ tv_load_filter(dev, NV_PTV_VFILTER, state->vfilter); ++ ++ nv_load_ptv(dev, state, 200); ++ nv_load_ptv(dev, state, 204); ++ nv_load_ptv(dev, state, 208); ++ nv_load_ptv(dev, state, 20c); ++ nv_load_ptv(dev, state, 304); ++ nv_load_ptv(dev, state, 500); ++ nv_load_ptv(dev, state, 504); ++ nv_load_ptv(dev, state, 508); ++ nv_load_ptv(dev, state, 600); ++ nv_load_ptv(dev, state, 604); ++ nv_load_ptv(dev, state, 608); ++ nv_load_ptv(dev, state, 60c); ++ nv_load_ptv(dev, state, 610); ++ nv_load_ptv(dev, state, 614); ++ ++ /* This is required for some settings to kick in. */ ++ nv_write_tv_enc(dev, 0x3e, 1); ++ nv_write_tv_enc(dev, 0x3e, 0); ++} ++ ++/* Timings similar to the ones the blob sets */ ++ ++struct drm_display_mode nv17_tv_modes[] = { ++ { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 0, ++ 320, 344, 392, 560, 0, 200, 200, 202, 220, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC ++ | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) }, ++ { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 0, ++ 320, 344, 392, 560, 0, 240, 240, 246, 263, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC ++ | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) }, ++ { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 0, ++ 400, 432, 496, 640, 0, 300, 300, 303, 314, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC ++ | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) }, ++ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 0, ++ 640, 672, 768, 880, 0, 480, 480, 492, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 0, ++ 720, 752, 872, 960, 0, 480, 480, 493, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 0, ++ 720, 776, 856, 960, 0, 576, 576, 588, 597, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 0, ++ 800, 840, 920, 1040, 0, 600, 600, 604, 618, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 0, ++ 1024, 1064, 1200, 1344, 0, 768, 768, 777, 806, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ {} ++}; ++ ++void nv17_tv_update_properties(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); ++ struct nv17_tv_state *regs = &tv_enc->state; ++ struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); ++ int subconnector = tv_enc->select_subconnector ? ++ tv_enc->select_subconnector : ++ tv_enc->subconnector; ++ ++ switch (subconnector) { ++ case DRM_MODE_SUBCONNECTOR_Composite: ++ { ++ regs->ptv_204 = 0x2; ++ ++ /* The composite connector may be found on either pin. */ ++ if (tv_enc->pin_mask & 0x4) ++ regs->ptv_204 |= 0x010000; ++ else if (tv_enc->pin_mask & 0x2) ++ regs->ptv_204 |= 0x100000; ++ else ++ regs->ptv_204 |= 0x110000; ++ ++ regs->tv_enc[0x7] = 0x10; ++ break; ++ } ++ case DRM_MODE_SUBCONNECTOR_SVIDEO: ++ regs->ptv_204 = 0x11012; ++ regs->tv_enc[0x7] = 0x18; ++ break; ++ ++ case DRM_MODE_SUBCONNECTOR_Component: ++ regs->ptv_204 = 0x111333; ++ regs->tv_enc[0x7] = 0x14; ++ break; ++ ++ case DRM_MODE_SUBCONNECTOR_SCART: ++ regs->ptv_204 = 0x111012; ++ regs->tv_enc[0x7] = 0x18; ++ break; ++ } ++ ++ regs->tv_enc[0x20] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x20], 255, ++ tv_enc->saturation); ++ regs->tv_enc[0x22] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x22], 255, ++ tv_enc->saturation); ++ regs->tv_enc[0x25] = tv_enc->hue * 255 / 100; ++ ++ nv_load_ptv(dev, regs, 204); ++ nv_load_tv_enc(dev, regs, 7); ++ nv_load_tv_enc(dev, regs, 20); ++ nv_load_tv_enc(dev, regs, 22); ++ nv_load_tv_enc(dev, regs, 25); ++} ++ ++void nv17_tv_update_rescaler(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); ++ struct nv17_tv_state *regs = &tv_enc->state; ++ ++ regs->ptv_208 = 0x40 | (calc_overscan(tv_enc->overscan) << 8); ++ ++ tv_setup_filter(encoder); ++ ++ nv_load_ptv(dev, regs, 208); ++ tv_load_filter(dev, NV_PTV_HFILTER, regs->hfilter); ++ tv_load_filter(dev, NV_PTV_HFILTER2, regs->hfilter2); ++ tv_load_filter(dev, NV_PTV_VFILTER, regs->vfilter); ++} ++ ++void nv17_ctv_update_rescaler(struct drm_encoder *encoder) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); ++ int head = nouveau_crtc(encoder->crtc)->index; ++ struct nv04_crtc_reg *regs = &dev_priv->mode_reg.crtc_reg[head]; ++ struct drm_display_mode *crtc_mode = &encoder->crtc->mode; ++ struct drm_display_mode *output_mode = &get_tv_norm(encoder)->ctv_enc_mode.mode; ++ int overscan, hmargin, vmargin, hratio, vratio; ++ ++ /* The rescaler doesn't do the right thing for interlaced modes. */ ++ if (output_mode->flags & DRM_MODE_FLAG_INTERLACE) ++ overscan = 100; ++ else ++ overscan = tv_enc->overscan; ++ ++ hmargin = (output_mode->hdisplay - crtc_mode->hdisplay) / 2; ++ vmargin = (output_mode->vdisplay - crtc_mode->vdisplay) / 2; ++ ++ hmargin = interpolate(0, min(hmargin, output_mode->hdisplay/20), hmargin, ++ overscan); ++ vmargin = interpolate(0, min(vmargin, output_mode->vdisplay/20), vmargin, ++ overscan); ++ ++ hratio = crtc_mode->hdisplay * 0x800 / (output_mode->hdisplay - 2*hmargin); ++ vratio = crtc_mode->vdisplay * 0x800 / (output_mode->vdisplay - 2*vmargin) & ~3; ++ ++ regs->fp_horiz_regs[FP_VALID_START] = hmargin; ++ regs->fp_horiz_regs[FP_VALID_END] = output_mode->hdisplay - hmargin - 1; ++ regs->fp_vert_regs[FP_VALID_START] = vmargin; ++ regs->fp_vert_regs[FP_VALID_END] = output_mode->vdisplay - vmargin - 1; ++ ++ regs->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE | ++ XLATE(vratio, 0, NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE) | ++ NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE | ++ XLATE(hratio, 0, NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE); ++ ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HVALID_START, ++ regs->fp_horiz_regs[FP_VALID_START]); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HVALID_END, ++ regs->fp_horiz_regs[FP_VALID_END]); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_VVALID_START, ++ regs->fp_vert_regs[FP_VALID_START]); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_VVALID_END, ++ regs->fp_vert_regs[FP_VALID_END]); ++ NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1, regs->fp_debug_1); ++} +diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c +new file mode 100644 +index 0000000..eeadc14 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv20_graph.c +@@ -0,0 +1,778 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++/* ++ * NV20 ++ * ----- ++ * There are 3 families : ++ * NV20 is 0x10de:0x020* ++ * NV25/28 is 0x10de:0x025* / 0x10de:0x028* ++ * NV2A is 0x10de:0x02A0 ++ * ++ * NV30 ++ * ----- ++ * There are 3 families : ++ * NV30/31 is 0x10de:0x030* / 0x10de:0x031* ++ * NV34 is 0x10de:0x032* ++ * NV35/36 is 0x10de:0x033* / 0x10de:0x034* ++ * ++ * Not seen in the wild, no dumps (probably NV35) : ++ * NV37 is 0x10de:0x00fc, 0x10de:0x00fd ++ * NV38 is 0x10de:0x0333, 0x10de:0x00fe ++ * ++ */ ++ ++#define NV20_GRCTX_SIZE (3580*4) ++#define NV25_GRCTX_SIZE (3529*4) ++#define NV2A_GRCTX_SIZE (3500*4) ++ ++#define NV30_31_GRCTX_SIZE (24392) ++#define NV34_GRCTX_SIZE (18140) ++#define NV35_36_GRCTX_SIZE (22396) ++ ++static void ++nv20_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x033c/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x03a0/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x03a4/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x047c/4, 0x00000101); ++ nv_wo32(dev, ctx, 0x0490/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x04a8/4, 0x44400000); ++ for (i = 0x04d4; i <= 0x04e0; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00030303); ++ for (i = 0x04f4; i <= 0x0500; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080000); ++ for (i = 0x050c; i <= 0x0518; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x051c; i <= 0x0528; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x000105b8); ++ for (i = 0x052c; i <= 0x0538; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ for (i = 0x055c; i <= 0x0598; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x05a4/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x05fc/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0604/4, 0x00004000); ++ nv_wo32(dev, ctx, 0x0610/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0618/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x061c/4, 0x00010000); ++ for (i = 0x1c1c; i <= 0x248c; i += 16) { ++ nv_wo32(dev, ctx, (i + 0)/4, 0x10700ff9); ++ nv_wo32(dev, ctx, (i + 4)/4, 0x0436086c); ++ nv_wo32(dev, ctx, (i + 8)/4, 0x000c001b); ++ } ++ nv_wo32(dev, ctx, 0x281c/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x2830/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x285c/4, 0x40000000); ++ nv_wo32(dev, ctx, 0x2860/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x2864/4, 0x3f000000); ++ nv_wo32(dev, ctx, 0x286c/4, 0x40000000); ++ nv_wo32(dev, ctx, 0x2870/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x2878/4, 0xbf800000); ++ nv_wo32(dev, ctx, 0x2880/4, 0xbf800000); ++ nv_wo32(dev, ctx, 0x34a4/4, 0x000fe000); ++ nv_wo32(dev, ctx, 0x3530/4, 0x000003f8); ++ nv_wo32(dev, ctx, 0x3540/4, 0x002fe000); ++ for (i = 0x355c; i <= 0x3578; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x001c527c); ++} ++ ++static void ++nv25_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x035c/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x03c0/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x03c4/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x049c/4, 0x00000101); ++ nv_wo32(dev, ctx, 0x04b0/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x04c8/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x04cc/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x04d0/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x04e4/4, 0x44400000); ++ nv_wo32(dev, ctx, 0x04fc/4, 0x4b800000); ++ for (i = 0x0510; i <= 0x051c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00030303); ++ for (i = 0x0530; i <= 0x053c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080000); ++ for (i = 0x0548; i <= 0x0554; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x0558; i <= 0x0564; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x000105b8); ++ for (i = 0x0568; i <= 0x0574; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ for (i = 0x0598; i <= 0x05d4; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x05e0/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x0620/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x0624/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x0628/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x062c/4, 0xb0a09080); ++ nv_wo32(dev, ctx, 0x0630/4, 0xf0e0d0c0); ++ nv_wo32(dev, ctx, 0x0664/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x066c/4, 0x00004000); ++ nv_wo32(dev, ctx, 0x0678/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0680/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x0684/4, 0x00010000); ++ for (i = 0x1b04; i <= 0x2374; i += 16) { ++ nv_wo32(dev, ctx, (i + 0)/4, 0x10700ff9); ++ nv_wo32(dev, ctx, (i + 4)/4, 0x0436086c); ++ nv_wo32(dev, ctx, (i + 8)/4, 0x000c001b); ++ } ++ nv_wo32(dev, ctx, 0x2704/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x2718/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x2744/4, 0x40000000); ++ nv_wo32(dev, ctx, 0x2748/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x274c/4, 0x3f000000); ++ nv_wo32(dev, ctx, 0x2754/4, 0x40000000); ++ nv_wo32(dev, ctx, 0x2758/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x2760/4, 0xbf800000); ++ nv_wo32(dev, ctx, 0x2768/4, 0xbf800000); ++ nv_wo32(dev, ctx, 0x308c/4, 0x000fe000); ++ nv_wo32(dev, ctx, 0x3108/4, 0x000003f8); ++ nv_wo32(dev, ctx, 0x3468/4, 0x002fe000); ++ for (i = 0x3484; i <= 0x34a0; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x001c527c); ++} ++ ++static void ++nv2a_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x033c/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x03a0/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x03a4/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x047c/4, 0x00000101); ++ nv_wo32(dev, ctx, 0x0490/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x04a8/4, 0x44400000); ++ for (i = 0x04d4; i <= 0x04e0; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00030303); ++ for (i = 0x04f4; i <= 0x0500; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080000); ++ for (i = 0x050c; i <= 0x0518; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x051c; i <= 0x0528; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x000105b8); ++ for (i = 0x052c; i <= 0x0538; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ for (i = 0x055c; i <= 0x0598; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x05a4/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x05fc/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0604/4, 0x00004000); ++ nv_wo32(dev, ctx, 0x0610/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0618/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x061c/4, 0x00010000); ++ for (i = 0x1a9c; i <= 0x22fc; i += 16) { /*XXX: check!! */ ++ nv_wo32(dev, ctx, (i + 0)/4, 0x10700ff9); ++ nv_wo32(dev, ctx, (i + 4)/4, 0x0436086c); ++ nv_wo32(dev, ctx, (i + 8)/4, 0x000c001b); ++ } ++ nv_wo32(dev, ctx, 0x269c/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x26b0/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x26dc/4, 0x40000000); ++ nv_wo32(dev, ctx, 0x26e0/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x26e4/4, 0x3f000000); ++ nv_wo32(dev, ctx, 0x26ec/4, 0x40000000); ++ nv_wo32(dev, ctx, 0x26f0/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x26f8/4, 0xbf800000); ++ nv_wo32(dev, ctx, 0x2700/4, 0xbf800000); ++ nv_wo32(dev, ctx, 0x3024/4, 0x000fe000); ++ nv_wo32(dev, ctx, 0x30a0/4, 0x000003f8); ++ nv_wo32(dev, ctx, 0x33fc/4, 0x002fe000); ++ for (i = 0x341c; i <= 0x3438; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x001c527c); ++} ++ ++static void ++nv30_31_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x0410/4, 0x00000101); ++ nv_wo32(dev, ctx, 0x0424/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x0428/4, 0x00000060); ++ nv_wo32(dev, ctx, 0x0444/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x0448/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x044c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0460/4, 0x44400000); ++ nv_wo32(dev, ctx, 0x048c/4, 0xffff0000); ++ for (i = 0x04e0; i < 0x04e8; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x04ec/4, 0x00011100); ++ for (i = 0x0508; i < 0x0548; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x0550/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x058c/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x0590/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x0594/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x0598/4, 0xb8a89888); ++ nv_wo32(dev, ctx, 0x059c/4, 0xf8e8d8c8); ++ nv_wo32(dev, ctx, 0x05b0/4, 0xb0000000); ++ for (i = 0x0600; i < 0x0640; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00010588); ++ for (i = 0x0640; i < 0x0680; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00030303); ++ for (i = 0x06c0; i < 0x0700; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0008aae4); ++ for (i = 0x0700; i < 0x0740; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x0740; i < 0x0780; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(dev, ctx, 0x085c/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x0860/4, 0x00010000); ++ for (i = 0x0864; i < 0x0874; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00040004); ++ for (i = 0x1f18; i <= 0x3088 ; i += 16) { ++ nv_wo32(dev, ctx, i/4 + 0, 0x10700ff9); ++ nv_wo32(dev, ctx, i/4 + 1, 0x0436086c); ++ nv_wo32(dev, ctx, i/4 + 2, 0x000c001b); ++ } ++ for (i = 0x30b8; i < 0x30c8; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x344c/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x3808/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x381c/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x3848/4, 0x40000000); ++ nv_wo32(dev, ctx, 0x384c/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x3850/4, 0x3f000000); ++ nv_wo32(dev, ctx, 0x3858/4, 0x40000000); ++ nv_wo32(dev, ctx, 0x385c/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x3864/4, 0xbf800000); ++ nv_wo32(dev, ctx, 0x386c/4, 0xbf800000); ++} ++ ++static void ++nv34_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x040c/4, 0x01000101); ++ nv_wo32(dev, ctx, 0x0420/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x0424/4, 0x00000060); ++ nv_wo32(dev, ctx, 0x0440/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x0444/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x0448/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x045c/4, 0x44400000); ++ nv_wo32(dev, ctx, 0x0480/4, 0xffff0000); ++ for (i = 0x04d4; i < 0x04dc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x04e0/4, 0x00011100); ++ for (i = 0x04fc; i < 0x053c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x0544/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x057c/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x0580/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x0584/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x0588/4, 0xb8a89888); ++ nv_wo32(dev, ctx, 0x058c/4, 0xf8e8d8c8); ++ nv_wo32(dev, ctx, 0x05a0/4, 0xb0000000); ++ for (i = 0x05f0; i < 0x0630; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00010588); ++ for (i = 0x0630; i < 0x0670; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00030303); ++ for (i = 0x06b0; i < 0x06f0; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0008aae4); ++ for (i = 0x06f0; i < 0x0730; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x0730; i < 0x0770; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(dev, ctx, 0x0850/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x0854/4, 0x00010000); ++ for (i = 0x0858; i < 0x0868; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00040004); ++ for (i = 0x15ac; i <= 0x271c ; i += 16) { ++ nv_wo32(dev, ctx, i/4 + 0, 0x10700ff9); ++ nv_wo32(dev, ctx, i/4 + 1, 0x0436086c); ++ nv_wo32(dev, ctx, i/4 + 2, 0x000c001b); ++ } ++ for (i = 0x274c; i < 0x275c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x2ae0/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x2e9c/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x2eb0/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x2edc/4, 0x40000000); ++ nv_wo32(dev, ctx, 0x2ee0/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x2ee4/4, 0x3f000000); ++ nv_wo32(dev, ctx, 0x2eec/4, 0x40000000); ++ nv_wo32(dev, ctx, 0x2ef0/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x2ef8/4, 0xbf800000); ++ nv_wo32(dev, ctx, 0x2f00/4, 0xbf800000); ++} ++ ++static void ++nv35_36_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x040c/4, 0x00000101); ++ nv_wo32(dev, ctx, 0x0420/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x0424/4, 0x00000060); ++ nv_wo32(dev, ctx, 0x0440/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x0444/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x0448/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x045c/4, 0x44400000); ++ nv_wo32(dev, ctx, 0x0488/4, 0xffff0000); ++ for (i = 0x04dc; i < 0x04e4; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x04e8/4, 0x00011100); ++ for (i = 0x0504; i < 0x0544; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x054c/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x0588/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x058c/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x0590/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x0594/4, 0xb8a89888); ++ nv_wo32(dev, ctx, 0x0598/4, 0xf8e8d8c8); ++ nv_wo32(dev, ctx, 0x05ac/4, 0xb0000000); ++ for (i = 0x0604; i < 0x0644; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00010588); ++ for (i = 0x0644; i < 0x0684; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00030303); ++ for (i = 0x06c4; i < 0x0704; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0008aae4); ++ for (i = 0x0704; i < 0x0744; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x0744; i < 0x0784; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(dev, ctx, 0x0860/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x0864/4, 0x00010000); ++ for (i = 0x0868; i < 0x0878; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00040004); ++ for (i = 0x1f1c; i <= 0x308c ; i += 16) { ++ nv_wo32(dev, ctx, i/4 + 0, 0x10700ff9); ++ nv_wo32(dev, ctx, i/4 + 1, 0x0436086c); ++ nv_wo32(dev, ctx, i/4 + 2, 0x000c001b); ++ } ++ for (i = 0x30bc; i < 0x30cc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x3450/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x380c/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x3820/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x384c/4, 0x40000000); ++ nv_wo32(dev, ctx, 0x3850/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x3854/4, 0x3f000000); ++ nv_wo32(dev, ctx, 0x385c/4, 0x40000000); ++ nv_wo32(dev, ctx, 0x3860/4, 0x3f800000); ++ nv_wo32(dev, ctx, 0x3868/4, 0xbf800000); ++ nv_wo32(dev, ctx, 0x3870/4, 0xbf800000); ++} ++ ++int ++nv20_graph_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *); ++ unsigned int ctx_size; ++ unsigned int idoffs = 0x28/4; ++ int ret; ++ ++ switch (dev_priv->chipset) { ++ case 0x20: ++ ctx_size = NV20_GRCTX_SIZE; ++ ctx_init = nv20_graph_context_init; ++ idoffs = 0; ++ break; ++ case 0x25: ++ case 0x28: ++ ctx_size = NV25_GRCTX_SIZE; ++ ctx_init = nv25_graph_context_init; ++ break; ++ case 0x2a: ++ ctx_size = NV2A_GRCTX_SIZE; ++ ctx_init = nv2a_graph_context_init; ++ idoffs = 0; ++ break; ++ case 0x30: ++ case 0x31: ++ ctx_size = NV30_31_GRCTX_SIZE; ++ ctx_init = nv30_31_graph_context_init; ++ break; ++ case 0x34: ++ ctx_size = NV34_GRCTX_SIZE; ++ ctx_init = nv34_graph_context_init; ++ break; ++ case 0x35: ++ case 0x36: ++ ctx_size = NV35_36_GRCTX_SIZE; ++ ctx_init = nv35_36_graph_context_init; ++ break; ++ default: ++ ctx_size = 0; ++ ctx_init = nv35_36_graph_context_init; ++ NV_ERROR(dev, "Please contact the devs if you want your NV%x" ++ " card to work\n", dev_priv->chipset); ++ return -ENOSYS; ++ break; ++ } ++ ++ ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &chan->ramin_grctx); ++ if (ret) ++ return ret; ++ ++ /* Initialise default context values */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ ctx_init(dev, chan->ramin_grctx->gpuobj); ++ ++ /* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */ ++ nv_wo32(dev, chan->ramin_grctx->gpuobj, idoffs, ++ (chan->id << 24) | 0x1); /* CTX_USER */ ++ ++ nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, ++ chan->ramin_grctx->instance >> 4); ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ return 0; ++} ++ ++void ++nv20_graph_destroy_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (chan->ramin_grctx) ++ nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, 0); ++ dev_priv->engine.instmem.finish_access(dev); ++} ++ ++int ++nv20_graph_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ uint32_t inst; ++ ++ if (!chan->ramin_grctx) ++ return -EINVAL; ++ inst = chan->ramin_grctx->instance >> 4; ++ ++ nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); ++ nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER, ++ NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD); ++ nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100); ++ ++ nouveau_wait_for_idle(dev); ++ return 0; ++} ++ ++int ++nv20_graph_unload_context(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; ++ struct nouveau_channel *chan; ++ uint32_t inst, tmp; ++ ++ chan = pgraph->channel(dev); ++ if (!chan) ++ return 0; ++ inst = chan->ramin_grctx->instance >> 4; ++ ++ nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); ++ nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER, ++ NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE); ++ ++ nouveau_wait_for_idle(dev); ++ ++ nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000); ++ tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff; ++ tmp |= (pfifo->channels - 1) << 24; ++ nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp); ++ return 0; ++} ++ ++static void ++nv20_graph_rdi(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int i, writecount = 32; ++ uint32_t rdi_index = 0x2c80000; ++ ++ if (dev_priv->chipset == 0x20) { ++ rdi_index = 0x3d0000; ++ writecount = 15; ++ } ++ ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, rdi_index); ++ for (i = 0; i < writecount; i++) ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA, 0); ++ ++ nouveau_wait_for_idle(dev); ++} ++ ++int ++nv20_graph_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = ++ (struct drm_nouveau_private *)dev->dev_private; ++ uint32_t tmp, vramsz; ++ int ret, i; ++ ++ nv_wr32(dev, NV03_PMC_ENABLE, ++ nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); ++ nv_wr32(dev, NV03_PMC_ENABLE, ++ nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); ++ ++ if (!dev_priv->ctx_table) { ++ /* Create Context Pointer Table */ ++ dev_priv->ctx_table_size = 32 * 4; ++ ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, ++ dev_priv->ctx_table_size, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &dev_priv->ctx_table); ++ if (ret) ++ return ret; ++ } ++ ++ nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, ++ dev_priv->ctx_table->instance >> 4); ++ ++ nv20_graph_rdi(dev); ++ ++ nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); ++ nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); ++ ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000); ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700); ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xF3CE0475); /* 0x4 = auto ctx switch */ ++ nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000); ++ nv_wr32(dev, 0x40009C , 0x00000040); ++ ++ if (dev_priv->chipset >= 0x25) { ++ nv_wr32(dev, 0x400890, 0x00080000); ++ nv_wr32(dev, 0x400610, 0x304B1FB6); ++ nv_wr32(dev, 0x400B80, 0x18B82880); ++ nv_wr32(dev, 0x400B84, 0x44000000); ++ nv_wr32(dev, 0x400098, 0x40000080); ++ nv_wr32(dev, 0x400B88, 0x000000ff); ++ } else { ++ nv_wr32(dev, 0x400880, 0x00080000); /* 0x0008c7df */ ++ nv_wr32(dev, 0x400094, 0x00000005); ++ nv_wr32(dev, 0x400B80, 0x45CAA208); /* 0x45eae20e */ ++ nv_wr32(dev, 0x400B84, 0x24000000); ++ nv_wr32(dev, 0x400098, 0x00000040); ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E00038); ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030); ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E10038); ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030); ++ } ++ ++ /* copy tile info from PFB */ ++ for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { ++ nv_wr32(dev, 0x00400904 + i * 0x10, ++ nv_rd32(dev, NV10_PFB_TLIMIT(i))); ++ /* which is NV40_PGRAPH_TLIMIT0(i) ?? */ ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + i * 4); ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA, ++ nv_rd32(dev, NV10_PFB_TLIMIT(i))); ++ nv_wr32(dev, 0x00400908 + i * 0x10, ++ nv_rd32(dev, NV10_PFB_TSIZE(i))); ++ /* which is NV40_PGRAPH_TSIZE0(i) ?? */ ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + i * 4); ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA, ++ nv_rd32(dev, NV10_PFB_TSIZE(i))); ++ nv_wr32(dev, 0x00400900 + i * 0x10, ++ nv_rd32(dev, NV10_PFB_TILE(i))); ++ /* which is NV40_PGRAPH_TILE0(i) ?? */ ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + i * 4); ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA, ++ nv_rd32(dev, NV10_PFB_TILE(i))); ++ } ++ for (i = 0; i < 8; i++) { ++ nv_wr32(dev, 0x400980 + i * 4, nv_rd32(dev, 0x100300 + i * 4)); ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0090 + i * 4); ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA, ++ nv_rd32(dev, 0x100300 + i * 4)); ++ } ++ nv_wr32(dev, 0x4009a0, nv_rd32(dev, 0x100324)); ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA000C); ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA, nv_rd32(dev, 0x100324)); ++ ++ nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100); ++ nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); ++ ++ tmp = nv_rd32(dev, NV10_PGRAPH_SURFACE) & 0x0007ff00; ++ nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp); ++ tmp = nv_rd32(dev, NV10_PGRAPH_SURFACE) | 0x00020100; ++ nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp); ++ ++ /* begin RAM config */ ++ vramsz = drm_get_resource_len(dev, 0) - 1; ++ nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); ++ nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1)); ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000); ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA , nv_rd32(dev, NV04_PFB_CFG0)); ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0004); ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA , nv_rd32(dev, NV04_PFB_CFG1)); ++ nv_wr32(dev, 0x400820, 0); ++ nv_wr32(dev, 0x400824, 0); ++ nv_wr32(dev, 0x400864, vramsz - 1); ++ nv_wr32(dev, 0x400868, vramsz - 1); ++ ++ /* interesting.. the below overwrites some of the tile setup above.. */ ++ nv_wr32(dev, 0x400B20, 0x00000000); ++ nv_wr32(dev, 0x400B04, 0xFFFFFFFF); ++ ++ nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_XMIN, 0); ++ nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_YMIN, 0); ++ nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff); ++ nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff); ++ ++ return 0; ++} ++ ++void ++nv20_graph_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ nouveau_gpuobj_ref_del(dev, &dev_priv->ctx_table); ++} ++ ++int ++nv30_graph_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int ret, i; ++ ++ nv_wr32(dev, NV03_PMC_ENABLE, ++ nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); ++ nv_wr32(dev, NV03_PMC_ENABLE, ++ nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); ++ ++ if (!dev_priv->ctx_table) { ++ /* Create Context Pointer Table */ ++ dev_priv->ctx_table_size = 32 * 4; ++ ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, ++ dev_priv->ctx_table_size, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &dev_priv->ctx_table); ++ if (ret) ++ return ret; ++ } ++ ++ nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, ++ dev_priv->ctx_table->instance >> 4); ++ ++ nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); ++ nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); ++ ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000); ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x401287c0); ++ nv_wr32(dev, 0x400890, 0x01b463ff); ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf2de0475); ++ nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00008000); ++ nv_wr32(dev, NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04bdff6); ++ nv_wr32(dev, 0x400B80, 0x1003d888); ++ nv_wr32(dev, 0x400B84, 0x0c000000); ++ nv_wr32(dev, 0x400098, 0x00000000); ++ nv_wr32(dev, 0x40009C, 0x0005ad00); ++ nv_wr32(dev, 0x400B88, 0x62ff00ff); /* suspiciously like PGRAPH_DEBUG_2 */ ++ nv_wr32(dev, 0x4000a0, 0x00000000); ++ nv_wr32(dev, 0x4000a4, 0x00000008); ++ nv_wr32(dev, 0x4008a8, 0xb784a400); ++ nv_wr32(dev, 0x400ba0, 0x002f8685); ++ nv_wr32(dev, 0x400ba4, 0x00231f3f); ++ nv_wr32(dev, 0x4008a4, 0x40000020); ++ ++ if (dev_priv->chipset == 0x34) { ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0004); ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00200201); ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0008); ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000008); ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000); ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000032); ++ nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E00004); ++ nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000002); ++ } ++ ++ nv_wr32(dev, 0x4000c0, 0x00000016); ++ ++ /* copy tile info from PFB */ ++ for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { ++ nv_wr32(dev, 0x00400904 + i * 0x10, ++ nv_rd32(dev, NV10_PFB_TLIMIT(i))); ++ /* which is NV40_PGRAPH_TLIMIT0(i) ?? */ ++ nv_wr32(dev, 0x00400908 + i * 0x10, ++ nv_rd32(dev, NV10_PFB_TSIZE(i))); ++ /* which is NV40_PGRAPH_TSIZE0(i) ?? */ ++ nv_wr32(dev, 0x00400900 + i * 0x10, ++ nv_rd32(dev, NV10_PFB_TILE(i))); ++ /* which is NV40_PGRAPH_TILE0(i) ?? */ ++ } ++ ++ nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100); ++ nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); ++ nv_wr32(dev, 0x0040075c , 0x00000001); ++ ++ /* begin RAM config */ ++ /* vramsz = drm_get_resource_len(dev, 0) - 1; */ ++ nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); ++ nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1)); ++ if (dev_priv->chipset != 0x34) { ++ nv_wr32(dev, 0x400750, 0x00EA0000); ++ nv_wr32(dev, 0x400754, nv_rd32(dev, NV04_PFB_CFG0)); ++ nv_wr32(dev, 0x400750, 0x00EA0004); ++ nv_wr32(dev, 0x400754, nv_rd32(dev, NV04_PFB_CFG1)); ++ } ++ ++ return 0; ++} ++ ++struct nouveau_pgraph_object_class nv20_graph_grclass[] = { ++ { 0x0030, false, NULL }, /* null */ ++ { 0x0039, false, NULL }, /* m2mf */ ++ { 0x004a, false, NULL }, /* gdirect */ ++ { 0x009f, false, NULL }, /* imageblit (nv12) */ ++ { 0x008a, false, NULL }, /* ifc */ ++ { 0x0089, false, NULL }, /* sifm */ ++ { 0x0062, false, NULL }, /* surf2d */ ++ { 0x0043, false, NULL }, /* rop */ ++ { 0x0012, false, NULL }, /* beta1 */ ++ { 0x0072, false, NULL }, /* beta4 */ ++ { 0x0019, false, NULL }, /* cliprect */ ++ { 0x0044, false, NULL }, /* pattern */ ++ { 0x009e, false, NULL }, /* swzsurf */ ++ { 0x0096, false, NULL }, /* celcius */ ++ { 0x0097, false, NULL }, /* kelvin (nv20) */ ++ { 0x0597, false, NULL }, /* kelvin (nv25) */ ++ {} ++}; ++ ++struct nouveau_pgraph_object_class nv30_graph_grclass[] = { ++ { 0x0030, false, NULL }, /* null */ ++ { 0x0039, false, NULL }, /* m2mf */ ++ { 0x004a, false, NULL }, /* gdirect */ ++ { 0x009f, false, NULL }, /* imageblit (nv12) */ ++ { 0x008a, false, NULL }, /* ifc */ ++ { 0x0089, false, NULL }, /* sifm */ ++ { 0x0389, false, NULL }, /* sifm (nv30) */ ++ { 0x0062, false, NULL }, /* surf2d */ ++ { 0x0043, false, NULL }, /* rop */ ++ { 0x0012, false, NULL }, /* beta1 */ ++ { 0x0072, false, NULL }, /* beta4 */ ++ { 0x0019, false, NULL }, /* cliprect */ ++ { 0x0044, false, NULL }, /* pattern */ ++ { 0x039e, false, NULL }, /* swzsurf */ ++ { 0x0397, false, NULL }, /* rankine (nv30) */ ++ { 0x0497, false, NULL }, /* rankine (nv35) */ ++ { 0x0697, false, NULL }, /* rankine (nv34) */ ++ {} ++}; ++ +diff --git a/drivers/gpu/drm/nouveau/nv40_fb.c b/drivers/gpu/drm/nouveau/nv40_fb.c +new file mode 100644 +index 0000000..ca1d271 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv40_fb.c +@@ -0,0 +1,62 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++int ++nv40_fb_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t fb_bar_size, tmp; ++ int num_tiles; ++ int i; ++ ++ /* This is strictly a NV4x register (don't know about NV5x). */ ++ /* The blob sets these to all kinds of values, and they mess up our setup. */ ++ /* I got value 0x52802 instead. For some cards the blob even sets it back to 0x1. */ ++ /* Note: the blob doesn't read this value, so i'm pretty sure this is safe for all cards. */ ++ /* Any idea what this is? */ ++ nv_wr32(dev, NV40_PFB_UNK_800, 0x1); ++ ++ switch (dev_priv->chipset) { ++ case 0x40: ++ case 0x45: ++ tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2); ++ nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15)); ++ num_tiles = NV10_PFB_TILE__SIZE; ++ break; ++ case 0x46: /* G72 */ ++ case 0x47: /* G70 */ ++ case 0x49: /* G71 */ ++ case 0x4b: /* G73 */ ++ case 0x4c: /* C51 (G7X version) */ ++ num_tiles = NV40_PFB_TILE__SIZE_1; ++ break; ++ default: ++ num_tiles = NV40_PFB_TILE__SIZE_0; ++ break; ++ } ++ ++ fb_bar_size = drm_get_resource_len(dev, 0) - 1; ++ switch (dev_priv->chipset) { ++ case 0x40: ++ for (i = 0; i < num_tiles; i++) { ++ nv_wr32(dev, NV10_PFB_TILE(i), 0); ++ nv_wr32(dev, NV10_PFB_TLIMIT(i), fb_bar_size); ++ } ++ break; ++ default: ++ for (i = 0; i < num_tiles; i++) { ++ nv_wr32(dev, NV40_PFB_TILE(i), 0); ++ nv_wr32(dev, NV40_PFB_TLIMIT(i), fb_bar_size); ++ } ++ break; ++ } ++ ++ return 0; ++} ++ ++void ++nv40_fb_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c +new file mode 100644 +index 0000000..b4f19cc +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv40_fifo.c +@@ -0,0 +1,314 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++#define NV40_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV40_RAMFC__SIZE)) ++#define NV40_RAMFC__SIZE 128 ++ ++int ++nv40_fifo_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t fc = NV40_RAMFC(chan->id); ++ int ret; ++ ++ ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(chan->id), ~0, ++ NV40_RAMFC__SIZE, NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, NULL, &chan->ramfc); ++ if (ret) ++ return ret; ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ nv_wi32(dev, fc + 0, chan->pushbuf_base); ++ nv_wi32(dev, fc + 4, chan->pushbuf_base); ++ nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4); ++ nv_wi32(dev, fc + 24, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | ++ NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | ++#ifdef __BIG_ENDIAN ++ NV_PFIFO_CACHE1_BIG_ENDIAN | ++#endif ++ 0x30000000 /* no idea.. */); ++ nv_wi32(dev, fc + 56, chan->ramin_grctx->instance >> 4); ++ nv_wi32(dev, fc + 60, 0x0001FFFF); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ /* enable the fifo dma operation */ ++ nv_wr32(dev, NV04_PFIFO_MODE, ++ nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); ++ return 0; ++} ++ ++void ++nv40_fifo_destroy_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ ++ nv_wr32(dev, NV04_PFIFO_MODE, ++ nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id)); ++ ++ if (chan->ramfc) ++ nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++} ++ ++static void ++nv40_fifo_do_load_context(struct drm_device *dev, int chid) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t fc = NV40_RAMFC(chid), tmp, tmp2; ++ ++ dev_priv->engine.instmem.prepare_access(dev, false); ++ ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); ++ nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, nv_ri32(dev, fc + 12)); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, nv_ri32(dev, fc + 16)); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 20)); ++ ++ /* No idea what 0x2058 is.. */ ++ tmp = nv_ri32(dev, fc + 24); ++ tmp2 = nv_rd32(dev, 0x2058) & 0xFFF; ++ tmp2 |= (tmp & 0x30000000); ++ nv_wr32(dev, 0x2058, tmp2); ++ tmp &= ~0x30000000; ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, tmp); ++ ++ nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 28)); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 32)); ++ nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE, nv_ri32(dev, fc + 36)); ++ tmp = nv_ri32(dev, fc + 40); ++ nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP, tmp); ++ nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT, nv_ri32(dev, fc + 44)); ++ nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, nv_ri32(dev, fc + 48)); ++ nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 52)); ++ nv_wr32(dev, NV40_PFIFO_GRCTX_INSTANCE, nv_ri32(dev, fc + 56)); ++ ++ /* Don't clobber the TIMEOUT_ENABLED flag when restoring from RAMFC */ ++ tmp = nv_rd32(dev, NV04_PFIFO_DMA_TIMESLICE) & ~0x1FFFF; ++ tmp |= nv_ri32(dev, fc + 60) & 0x1FFFF; ++ nv_wr32(dev, NV04_PFIFO_DMA_TIMESLICE, tmp); ++ ++ nv_wr32(dev, 0x32e4, nv_ri32(dev, fc + 64)); ++ /* NVIDIA does this next line twice... */ ++ nv_wr32(dev, 0x32e8, nv_ri32(dev, fc + 68)); ++ nv_wr32(dev, 0x2088, nv_ri32(dev, fc + 76)); ++ nv_wr32(dev, 0x3300, nv_ri32(dev, fc + 80)); ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); ++} ++ ++int ++nv40_fifo_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ uint32_t tmp; ++ ++ nv40_fifo_do_load_context(dev, chan->id); ++ ++ /* Set channel active, and in DMA mode */ ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, ++ NV40_PFIFO_CACHE1_PUSH1_DMA | chan->id); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1); ++ ++ /* Reset DMA_CTL_AT_INFO to INVALID */ ++ tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31); ++ nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp); ++ ++ return 0; ++} ++ ++int ++nv40_fifo_unload_context(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; ++ uint32_t fc, tmp; ++ int chid; ++ ++ chid = pfifo->channel_id(dev); ++ if (chid < 0 || chid >= dev_priv->engine.fifo.channels) ++ return 0; ++ fc = NV40_RAMFC(chid); ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); ++ nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); ++ nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); ++ nv_wi32(dev, fc + 12, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE)); ++ nv_wi32(dev, fc + 16, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT)); ++ nv_wi32(dev, fc + 20, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE)); ++ tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH); ++ tmp |= nv_rd32(dev, 0x2058) & 0x30000000; ++ nv_wi32(dev, fc + 24, tmp); ++ nv_wi32(dev, fc + 28, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE)); ++ nv_wi32(dev, fc + 32, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1)); ++ nv_wi32(dev, fc + 36, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); ++ tmp = nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP); ++ nv_wi32(dev, fc + 40, tmp); ++ nv_wi32(dev, fc + 44, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); ++ nv_wi32(dev, fc + 48, nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE)); ++ /* NVIDIA read 0x3228 first, then write DMA_GET here.. maybe something ++ * more involved depending on the value of 0x3228? ++ */ ++ nv_wi32(dev, fc + 52, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); ++ nv_wi32(dev, fc + 56, nv_rd32(dev, NV40_PFIFO_GRCTX_INSTANCE)); ++ nv_wi32(dev, fc + 60, nv_rd32(dev, NV04_PFIFO_DMA_TIMESLICE) & 0x1ffff); ++ /* No idea what the below is for exactly, ripped from a mmio-trace */ ++ nv_wi32(dev, fc + 64, nv_rd32(dev, NV40_PFIFO_UNK32E4)); ++ /* NVIDIA do this next line twice.. bug? */ ++ nv_wi32(dev, fc + 68, nv_rd32(dev, 0x32e8)); ++ nv_wi32(dev, fc + 76, nv_rd32(dev, 0x2088)); ++ nv_wi32(dev, fc + 80, nv_rd32(dev, 0x3300)); ++#if 0 /* no real idea which is PUT/GET in UNK_48.. */ ++ tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_GET); ++ tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16); ++ nv_wi32(dev, fc + 72, tmp); ++#endif ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv40_fifo_do_load_context(dev, pfifo->channels - 1); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, ++ NV40_PFIFO_CACHE1_PUSH1_DMA | (pfifo->channels - 1)); ++ return 0; ++} ++ ++static void ++nv40_fifo_init_reset(struct drm_device *dev) ++{ ++ int i; ++ ++ nv_wr32(dev, NV03_PMC_ENABLE, ++ nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO); ++ nv_wr32(dev, NV03_PMC_ENABLE, ++ nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PFIFO); ++ ++ nv_wr32(dev, 0x003224, 0x000f0078); ++ nv_wr32(dev, 0x003210, 0x00000000); ++ nv_wr32(dev, 0x003270, 0x00000000); ++ nv_wr32(dev, 0x003240, 0x00000000); ++ nv_wr32(dev, 0x003244, 0x00000000); ++ nv_wr32(dev, 0x003258, 0x00000000); ++ nv_wr32(dev, 0x002504, 0x00000000); ++ for (i = 0; i < 16; i++) ++ nv_wr32(dev, 0x002510 + (i * 4), 0x00000000); ++ nv_wr32(dev, 0x00250c, 0x0000ffff); ++ nv_wr32(dev, 0x002048, 0x00000000); ++ nv_wr32(dev, 0x003228, 0x00000000); ++ nv_wr32(dev, 0x0032e8, 0x00000000); ++ nv_wr32(dev, 0x002410, 0x00000000); ++ nv_wr32(dev, 0x002420, 0x00000000); ++ nv_wr32(dev, 0x002058, 0x00000001); ++ nv_wr32(dev, 0x00221c, 0x00000000); ++ /* something with 0x2084, read/modify/write, no change */ ++ nv_wr32(dev, 0x002040, 0x000000ff); ++ nv_wr32(dev, 0x002500, 0x00000000); ++ nv_wr32(dev, 0x003200, 0x00000000); ++ ++ nv_wr32(dev, NV04_PFIFO_DMA_TIMESLICE, 0x2101ffff); ++} ++ ++static void ++nv40_fifo_init_ramxx(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | ++ ((dev_priv->ramht_bits - 9) << 16) | ++ (dev_priv->ramht_offset >> 8)); ++ nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8); ++ ++ switch (dev_priv->chipset) { ++ case 0x47: ++ case 0x49: ++ case 0x4b: ++ nv_wr32(dev, 0x2230, 1); ++ break; ++ default: ++ break; ++ } ++ ++ switch (dev_priv->chipset) { ++ case 0x40: ++ case 0x41: ++ case 0x42: ++ case 0x43: ++ case 0x45: ++ case 0x47: ++ case 0x48: ++ case 0x49: ++ case 0x4b: ++ nv_wr32(dev, NV40_PFIFO_RAMFC, 0x30002); ++ break; ++ default: ++ nv_wr32(dev, 0x2230, 0); ++ nv_wr32(dev, NV40_PFIFO_RAMFC, ++ ((nouveau_mem_fb_amount(dev) - 512 * 1024 + ++ dev_priv->ramfc_offset) >> 16) | (3 << 16)); ++ break; ++ } ++} ++ ++static void ++nv40_fifo_init_intr(struct drm_device *dev) ++{ ++ nv_wr32(dev, 0x002100, 0xffffffff); ++ nv_wr32(dev, 0x002140, 0xffffffff); ++} ++ ++int ++nv40_fifo_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; ++ int i; ++ ++ nv40_fifo_init_reset(dev); ++ nv40_fifo_init_ramxx(dev); ++ ++ nv40_fifo_do_load_context(dev, pfifo->channels - 1); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); ++ ++ nv40_fifo_init_intr(dev); ++ pfifo->enable(dev); ++ pfifo->reassign(dev, true); ++ ++ for (i = 0; i < dev_priv->engine.fifo.channels; i++) { ++ if (dev_priv->fifos[i]) { ++ uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE); ++ nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i)); ++ } ++ } ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c +new file mode 100644 +index 0000000..9b5e03a +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv40_graph.c +@@ -0,0 +1,2239 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++/*TODO: deciper what each offset in the context represents. The below ++ * contexts are taken from dumps just after the 3D object is ++ * created. ++ */ ++static void ++nv40_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ /* Always has the "instance address" of itself at offset 0 */ ++ nv_wo32(dev, ctx, 0x00000/4, ctx->im_pramin->start); ++ /* unknown */ ++ nv_wo32(dev, ctx, 0x00024/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00028/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00030/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0011c/4, 0x20010001); ++ nv_wo32(dev, ctx, 0x00120/4, 0x0f73ef00); ++ nv_wo32(dev, ctx, 0x00128/4, 0x02008821); ++ nv_wo32(dev, ctx, 0x0016c/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00170/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00174/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x0017c/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00180/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00184/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00188/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x0018c/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x0019c/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x001a0/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x001b0/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x001c0/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x001d0/4, 0x0b0b0b0c); ++ nv_wo32(dev, ctx, 0x00340/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x00350/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00354/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00358/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x0035c/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00388/4, 0x00000008); ++ nv_wo32(dev, ctx, 0x0039c/4, 0x00000010); ++ nv_wo32(dev, ctx, 0x00480/4, 0x00000100); ++ nv_wo32(dev, ctx, 0x00494/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00498/4, 0x00080060); ++ nv_wo32(dev, ctx, 0x004b4/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x004b8/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x004bc/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x004d0/4, 0x46400000); ++ nv_wo32(dev, ctx, 0x004ec/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x004f8/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x004fc/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00504/4, 0x00011100); ++ for (i = 0x00520; i <= 0x0055c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x00568/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x00594/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x00598/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x0059c/4, 0xb8a89888); ++ nv_wo32(dev, ctx, 0x005a0/4, 0xf8e8d8c8); ++ nv_wo32(dev, ctx, 0x005b4/4, 0x40100000); ++ nv_wo32(dev, ctx, 0x005cc/4, 0x00000004); ++ nv_wo32(dev, ctx, 0x005d8/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x0060c/4, 0x435185d6); ++ nv_wo32(dev, ctx, 0x00610/4, 0x2155b699); ++ nv_wo32(dev, ctx, 0x00614/4, 0xfedcba98); ++ nv_wo32(dev, ctx, 0x00618/4, 0x00000098); ++ nv_wo32(dev, ctx, 0x00628/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x0062c/4, 0x00ff7000); ++ nv_wo32(dev, ctx, 0x00630/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00640/4, 0x00ff0000); ++ nv_wo32(dev, ctx, 0x0067c/4, 0x00ffff00); ++ /* 0x680-0x6BC - NV30_TCL_PRIMITIVE_3D_TX_ADDRESS_UNIT(0-15) */ ++ /* 0x6C0-0x6FC - NV30_TCL_PRIMITIVE_3D_TX_FORMAT_UNIT(0-15) */ ++ for (i = 0x006C0; i <= 0x006fc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00018488); ++ /* 0x700-0x73C - NV30_TCL_PRIMITIVE_3D_TX_WRAP_UNIT(0-15) */ ++ for (i = 0x00700; i <= 0x0073c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00028202); ++ /* 0x740-0x77C - NV30_TCL_PRIMITIVE_3D_TX_ENABLE_UNIT(0-15) */ ++ /* 0x780-0x7BC - NV30_TCL_PRIMITIVE_3D_TX_SWIZZLE_UNIT(0-15) */ ++ for (i = 0x00780; i <= 0x007bc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0000aae4); ++ /* 0x7C0-0x7FC - NV30_TCL_PRIMITIVE_3D_TX_FILTER_UNIT(0-15) */ ++ for (i = 0x007c0; i <= 0x007fc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ /* 0x800-0x83C - NV30_TCL_PRIMITIVE_3D_TX_XY_DIM_UNIT(0-15) */ ++ for (i = 0x00800; i <= 0x0083c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ /* 0x840-0x87C - NV30_TCL_PRIMITIVE_3D_TX_UNK07_UNIT(0-15) */ ++ /* 0x880-0x8BC - NV30_TCL_PRIMITIVE_3D_TX_DEPTH_UNIT(0-15) */ ++ for (i = 0x00880; i <= 0x008bc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00100008); ++ /* unknown */ ++ for (i = 0x00910; i <= 0x0091c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0001bc80); ++ for (i = 0x00920; i <= 0x0092c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000202); ++ for (i = 0x00940; i <= 0x0094c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000008); ++ for (i = 0x00960; i <= 0x0096c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(dev, ctx, 0x00980/4, 0x00000002); ++ nv_wo32(dev, ctx, 0x009b4/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x009c0/4, 0x3e020200); ++ nv_wo32(dev, ctx, 0x009c4/4, 0x00ffffff); ++ nv_wo32(dev, ctx, 0x009c8/4, 0x60103f00); ++ nv_wo32(dev, ctx, 0x009d4/4, 0x00020000); ++ nv_wo32(dev, ctx, 0x00a08/4, 0x00008100); ++ nv_wo32(dev, ctx, 0x00aac/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00af0/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00af8/4, 0x80800001); ++ nv_wo32(dev, ctx, 0x00bcc/4, 0x00000005); ++ nv_wo32(dev, ctx, 0x00bf8/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00bfc/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c00/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c04/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c08/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c0c/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c44/4, 0x00000001); ++ for (i = 0x03008; i <= 0x03080; i += 8) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x05288; i <= 0x08570; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x08628; i <= 0x08e18; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x0bd28; i <= 0x0f010; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x0f0c8; i <= 0x0f8b8; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x127c8; i <= 0x15ab0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x15b68; i <= 0x16358; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x19268; i <= 0x1c550; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x1c608; i <= 0x1cdf8; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x1fd08; i <= 0x22ff0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x230a8; i <= 0x23898; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x267a8; i <= 0x29a90; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x29b48; i <= 0x2a338; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++} ++ ++static void ++nv41_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x00000/4, ctx->im_pramin->start); ++ nv_wo32(dev, ctx, 0x00000024/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00000028/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00000030/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0000011c/4, 0x20010001); ++ nv_wo32(dev, ctx, 0x00000120/4, 0x0f73ef00); ++ nv_wo32(dev, ctx, 0x00000128/4, 0x02008821); ++ for (i = 0x00000178; i <= 0x00000180; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00000188/4, 0x00000040); ++ for (i = 0x00000194; i <= 0x000001b0; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x000001d0/4, 0x0b0b0b0c); ++ nv_wo32(dev, ctx, 0x00000340/4, 0x00040000); ++ for (i = 0x00000350; i <= 0x0000035c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00000388/4, 0x00000008); ++ nv_wo32(dev, ctx, 0x0000039c/4, 0x00001010); ++ nv_wo32(dev, ctx, 0x000003cc/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x000003d0/4, 0x00080060); ++ nv_wo32(dev, ctx, 0x000003ec/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x000003f0/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x000003f4/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00000408/4, 0x46400000); ++ nv_wo32(dev, ctx, 0x00000418/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x00000424/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00000428/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00000430/4, 0x00011100); ++ for (i = 0x0000044c; i <= 0x00000488; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x00000494/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x000004bc/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x000004c0/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x000004c4/4, 0xb8a89888); ++ nv_wo32(dev, ctx, 0x000004c8/4, 0xf8e8d8c8); ++ nv_wo32(dev, ctx, 0x000004dc/4, 0x40100000); ++ nv_wo32(dev, ctx, 0x000004f8/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x0000052c/4, 0x435185d6); ++ nv_wo32(dev, ctx, 0x00000530/4, 0x2155b699); ++ nv_wo32(dev, ctx, 0x00000534/4, 0xfedcba98); ++ nv_wo32(dev, ctx, 0x00000538/4, 0x00000098); ++ nv_wo32(dev, ctx, 0x00000548/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x0000054c/4, 0x00ff7000); ++ nv_wo32(dev, ctx, 0x00000550/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00000560/4, 0x00ff0000); ++ nv_wo32(dev, ctx, 0x00000598/4, 0x00ffff00); ++ for (i = 0x000005dc; i <= 0x00000618; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00018488); ++ for (i = 0x0000061c; i <= 0x00000658; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00028202); ++ for (i = 0x0000069c; i <= 0x000006d8; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0000aae4); ++ for (i = 0x000006dc; i <= 0x00000718; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x0000071c; i <= 0x00000758; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ for (i = 0x0000079c; i <= 0x000007d8; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00100008); ++ for (i = 0x0000082c; i <= 0x00000838; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0001bc80); ++ for (i = 0x0000083c; i <= 0x00000848; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000202); ++ for (i = 0x0000085c; i <= 0x00000868; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000008); ++ for (i = 0x0000087c; i <= 0x00000888; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(dev, ctx, 0x0000089c/4, 0x00000002); ++ nv_wo32(dev, ctx, 0x000008d0/4, 0x00000021); ++ nv_wo32(dev, ctx, 0x000008d4/4, 0x030c30c3); ++ nv_wo32(dev, ctx, 0x000008e0/4, 0x3e020200); ++ nv_wo32(dev, ctx, 0x000008e4/4, 0x00ffffff); ++ nv_wo32(dev, ctx, 0x000008e8/4, 0x20103f00); ++ nv_wo32(dev, ctx, 0x000008f4/4, 0x00020000); ++ nv_wo32(dev, ctx, 0x0000092c/4, 0x00008100); ++ nv_wo32(dev, ctx, 0x000009b8/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x000009fc/4, 0x00001001); ++ nv_wo32(dev, ctx, 0x00000a04/4, 0x00000003); ++ nv_wo32(dev, ctx, 0x00000a08/4, 0x00888001); ++ nv_wo32(dev, ctx, 0x00000aac/4, 0x00000005); ++ nv_wo32(dev, ctx, 0x00000ab8/4, 0x0000ffff); ++ for (i = 0x00000ad4; i <= 0x00000ae4; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00000ae8/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00000b20/4, 0x00000001); ++ for (i = 0x00002ee8; i <= 0x00002f60; i += 8) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x00005168; i <= 0x00007358; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x00007368; i <= 0x00007758; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x0000a068; i <= 0x0000c258; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x0000c268; i <= 0x0000c658; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x0000ef68; i <= 0x00011158; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x00011168; i <= 0x00011558; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x00013e68; i <= 0x00016058; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x00016068; i <= 0x00016458; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++}; ++ ++static void ++nv43_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x00000/4, ctx->im_pramin->start); ++ nv_wo32(dev, ctx, 0x00024/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00028/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00030/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0011c/4, 0x20010001); ++ nv_wo32(dev, ctx, 0x00120/4, 0x0f73ef00); ++ nv_wo32(dev, ctx, 0x00128/4, 0x02008821); ++ nv_wo32(dev, ctx, 0x00178/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x0017c/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00180/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00188/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00194/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00198/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x0019c/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x001a0/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x001a4/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x001a8/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x001ac/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x001b0/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x001d0/4, 0x0b0b0b0c); ++ nv_wo32(dev, ctx, 0x00340/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x00350/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00354/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00358/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x0035c/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00388/4, 0x00000008); ++ nv_wo32(dev, ctx, 0x0039c/4, 0x00001010); ++ nv_wo32(dev, ctx, 0x003cc/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x003d0/4, 0x00080060); ++ nv_wo32(dev, ctx, 0x003ec/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x003f0/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x003f4/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00408/4, 0x46400000); ++ nv_wo32(dev, ctx, 0x00418/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x00424/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00428/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00430/4, 0x00011100); ++ for (i = 0x0044c; i <= 0x00488; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x00494/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x004bc/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x004c0/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x004c4/4, 0xb8a89888); ++ nv_wo32(dev, ctx, 0x004c8/4, 0xf8e8d8c8); ++ nv_wo32(dev, ctx, 0x004dc/4, 0x40100000); ++ nv_wo32(dev, ctx, 0x004f8/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x0052c/4, 0x435185d6); ++ nv_wo32(dev, ctx, 0x00530/4, 0x2155b699); ++ nv_wo32(dev, ctx, 0x00534/4, 0xfedcba98); ++ nv_wo32(dev, ctx, 0x00538/4, 0x00000098); ++ nv_wo32(dev, ctx, 0x00548/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x0054c/4, 0x00ff7000); ++ nv_wo32(dev, ctx, 0x00550/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00560/4, 0x00ff0000); ++ nv_wo32(dev, ctx, 0x00598/4, 0x00ffff00); ++ for (i = 0x005dc; i <= 0x00618; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00018488); ++ for (i = 0x0061c; i <= 0x00658; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00028202); ++ for (i = 0x0069c; i <= 0x006d8; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0000aae4); ++ for (i = 0x006dc; i <= 0x00718; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x0071c; i <= 0x00758; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ for (i = 0x0079c; i <= 0x007d8; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00100008); ++ for (i = 0x0082c; i <= 0x00838; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0001bc80); ++ for (i = 0x0083c; i <= 0x00848; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000202); ++ for (i = 0x0085c; i <= 0x00868; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000008); ++ for (i = 0x0087c; i <= 0x00888; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(dev, ctx, 0x0089c/4, 0x00000002); ++ nv_wo32(dev, ctx, 0x008d0/4, 0x00000021); ++ nv_wo32(dev, ctx, 0x008d4/4, 0x030c30c3); ++ nv_wo32(dev, ctx, 0x008e0/4, 0x3e020200); ++ nv_wo32(dev, ctx, 0x008e4/4, 0x00ffffff); ++ nv_wo32(dev, ctx, 0x008e8/4, 0x0c103f00); ++ nv_wo32(dev, ctx, 0x008f4/4, 0x00020000); ++ nv_wo32(dev, ctx, 0x0092c/4, 0x00008100); ++ nv_wo32(dev, ctx, 0x009b8/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x009fc/4, 0x00001001); ++ nv_wo32(dev, ctx, 0x00a04/4, 0x00000003); ++ nv_wo32(dev, ctx, 0x00a08/4, 0x00888001); ++ nv_wo32(dev, ctx, 0x00a8c/4, 0x00000005); ++ nv_wo32(dev, ctx, 0x00a98/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00ab4/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00ab8/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00abc/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00ac0/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00af8/4, 0x00000001); ++ for (i = 0x02ec0; i <= 0x02f38; i += 8) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x04c80; i <= 0x06e70; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x06e80; i <= 0x07270; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x096c0; i <= 0x0b8b0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x0b8c0; i <= 0x0bcb0; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x0e100; i <= 0x102f0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x10300; i <= 0x106f0; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++}; ++ ++static void ++nv46_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x00000/4, ctx->im_pramin->start); ++ nv_wo32(dev, ctx, 0x00040/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00044/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x0004c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00138/4, 0x20010001); ++ nv_wo32(dev, ctx, 0x0013c/4, 0x0f73ef00); ++ nv_wo32(dev, ctx, 0x00144/4, 0x02008821); ++ nv_wo32(dev, ctx, 0x00174/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00178/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0017c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00180/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00184/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00188/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0018c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00190/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00194/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00198/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x0019c/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x001a4/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x001ec/4, 0x0b0b0b0c); ++ nv_wo32(dev, ctx, 0x0035c/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x0036c/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00370/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00374/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00378/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x003a4/4, 0x00000008); ++ nv_wo32(dev, ctx, 0x003b8/4, 0x00003010); ++ nv_wo32(dev, ctx, 0x003dc/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x003e0/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x003e4/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x003e8/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x003ec/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x003f0/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x003f4/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x003f8/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x003fc/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00400/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00404/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00408/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x0040c/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00410/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00414/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00418/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x004b0/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x004b4/4, 0x00080060); ++ nv_wo32(dev, ctx, 0x004d0/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x004d4/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x004d8/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x004ec/4, 0x46400000); ++ nv_wo32(dev, ctx, 0x004fc/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x00500/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00504/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00508/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x0050c/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00510/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00514/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00518/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x0051c/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00520/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00524/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00528/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x0052c/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00530/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00534/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00538/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x0053c/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00550/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00554/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x0055c/4, 0x00011100); ++ for (i = 0x00578; i < 0x005b4; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005c0/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x005e8/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x005ec/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x005f0/4, 0xb8a89888); ++ nv_wo32(dev, ctx, 0x005f4/4, 0xf8e8d8c8); ++ nv_wo32(dev, ctx, 0x00608/4, 0x40100000); ++ nv_wo32(dev, ctx, 0x00624/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00658/4, 0x435185d6); ++ nv_wo32(dev, ctx, 0x0065c/4, 0x2155b699); ++ nv_wo32(dev, ctx, 0x00660/4, 0xfedcba98); ++ nv_wo32(dev, ctx, 0x00664/4, 0x00000098); ++ nv_wo32(dev, ctx, 0x00674/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00678/4, 0x00ff7000); ++ nv_wo32(dev, ctx, 0x0067c/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x0068c/4, 0x00ff0000); ++ nv_wo32(dev, ctx, 0x006c8/4, 0x00ffff00); ++ for (i = 0x0070c; i <= 0x00748; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00018488); ++ for (i = 0x0074c; i <= 0x00788; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00028202); ++ for (i = 0x007cc; i <= 0x00808; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0000aae4); ++ for (i = 0x0080c; i <= 0x00848; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x0084c; i <= 0x00888; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ for (i = 0x008cc; i <= 0x00908; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00100008); ++ for (i = 0x0095c; i <= 0x00968; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0001bc80); ++ for (i = 0x0096c; i <= 0x00978; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000202); ++ for (i = 0x0098c; i <= 0x00998; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000008); ++ for (i = 0x009ac; i <= 0x009b8; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(dev, ctx, 0x009cc/4, 0x00000002); ++ nv_wo32(dev, ctx, 0x00a00/4, 0x00000421); ++ nv_wo32(dev, ctx, 0x00a04/4, 0x030c30c3); ++ nv_wo32(dev, ctx, 0x00a08/4, 0x00011001); ++ nv_wo32(dev, ctx, 0x00a14/4, 0x3e020200); ++ nv_wo32(dev, ctx, 0x00a18/4, 0x00ffffff); ++ nv_wo32(dev, ctx, 0x00a1c/4, 0x0c103f00); ++ nv_wo32(dev, ctx, 0x00a28/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x00a60/4, 0x00008100); ++ nv_wo32(dev, ctx, 0x00aec/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00b30/4, 0x00001001); ++ nv_wo32(dev, ctx, 0x00b38/4, 0x00000003); ++ nv_wo32(dev, ctx, 0x00b3c/4, 0x00888001); ++ nv_wo32(dev, ctx, 0x00bc0/4, 0x00000005); ++ nv_wo32(dev, ctx, 0x00bcc/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00be8/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00bec/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00bf0/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00bf4/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00c2c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00c30/4, 0x08e00001); ++ nv_wo32(dev, ctx, 0x00c34/4, 0x000e3000); ++ for (i = 0x017f8; i <= 0x01870; i += 8) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x035b8; i <= 0x057a8; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x057b8; i <= 0x05ba8; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x07f38; i <= 0x0a128; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x0a138; i <= 0x0a528; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x0c8b8; i <= 0x0eaa8; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x0eab8; i <= 0x0eea8; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++} ++ ++/* This may only work on 7800 AGP cards, will include a warning */ ++static void ++nv47_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x00000000/4, ctx->im_pramin->start); ++ nv_wo32(dev, ctx, 0x00000024/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00000028/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00000030/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0000011c/4, 0x20010001); ++ nv_wo32(dev, ctx, 0x00000120/4, 0x0f73ef00); ++ nv_wo32(dev, ctx, 0x00000128/4, 0x02008821); ++ nv_wo32(dev, ctx, 0x00000178/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x0000017c/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00000180/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00000188/4, 0x00000040); ++ for (i = 0x00000194; i <= 0x000001b0; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x000001d0/4, 0x0b0b0b0c); ++ nv_wo32(dev, ctx, 0x00000340/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x00000350/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00000354/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00000358/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x0000035c/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00000388/4, 0x00000008); ++ nv_wo32(dev, ctx, 0x0000039c/4, 0x00001010); ++ for (i = 0x000003c0; i <= 0x000003fc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00000454/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00000458/4, 0x00080060); ++ nv_wo32(dev, ctx, 0x00000474/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x00000478/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x0000047c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00000490/4, 0x46400000); ++ nv_wo32(dev, ctx, 0x000004a0/4, 0xffff0000); ++ for (i = 0x000004a4; i <= 0x000004e0; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x000004f4/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x000004f8/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00000500/4, 0x00011100); ++ for (i = 0x0000051c; i <= 0x00000558; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x00000564/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x0000058c/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x00000590/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x00000594/4, 0xb8a89888); ++ nv_wo32(dev, ctx, 0x00000598/4, 0xf8e8d8c8); ++ nv_wo32(dev, ctx, 0x000005ac/4, 0x40100000); ++ nv_wo32(dev, ctx, 0x000005c8/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x000005fc/4, 0x435185d6); ++ nv_wo32(dev, ctx, 0x00000600/4, 0x2155b699); ++ nv_wo32(dev, ctx, 0x00000604/4, 0xfedcba98); ++ nv_wo32(dev, ctx, 0x00000608/4, 0x00000098); ++ nv_wo32(dev, ctx, 0x00000618/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x0000061c/4, 0x00ff7000); ++ nv_wo32(dev, ctx, 0x00000620/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00000630/4, 0x00ff0000); ++ nv_wo32(dev, ctx, 0x0000066c/4, 0x00ffff00); ++ for (i = 0x000006b0; i <= 0x000006ec; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00018488); ++ for (i = 0x000006f0; i <= 0x0000072c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00028202); ++ for (i = 0x00000770; i <= 0x000007ac; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0000aae4); ++ for (i = 0x000007b0; i <= 0x000007ec; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x000007f0; i <= 0x0000082c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ for (i = 0x00000870; i <= 0x000008ac; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00100008); ++ nv_wo32(dev, ctx, 0x00000900/4, 0x0001bc80); ++ nv_wo32(dev, ctx, 0x00000904/4, 0x0001bc80); ++ nv_wo32(dev, ctx, 0x00000908/4, 0x0001bc80); ++ nv_wo32(dev, ctx, 0x0000090c/4, 0x0001bc80); ++ nv_wo32(dev, ctx, 0x00000910/4, 0x00000202); ++ nv_wo32(dev, ctx, 0x00000914/4, 0x00000202); ++ nv_wo32(dev, ctx, 0x00000918/4, 0x00000202); ++ nv_wo32(dev, ctx, 0x0000091c/4, 0x00000202); ++ for (i = 0x00000930; i <= 0x0000095c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000008); ++ nv_wo32(dev, ctx, 0x00000970/4, 0x00000002); ++ nv_wo32(dev, ctx, 0x000009a4/4, 0x00000021); ++ nv_wo32(dev, ctx, 0x000009a8/4, 0x030c30c3); ++ nv_wo32(dev, ctx, 0x000009b4/4, 0x3e020200); ++ nv_wo32(dev, ctx, 0x000009b8/4, 0x00ffffff); ++ nv_wo32(dev, ctx, 0x000009bc/4, 0x40103f00); ++ nv_wo32(dev, ctx, 0x000009c8/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x00000a00/4, 0x00008100); ++ nv_wo32(dev, ctx, 0x00000a8c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00000ad0/4, 0x00001001); ++ nv_wo32(dev, ctx, 0x00000adc/4, 0x00000003); ++ nv_wo32(dev, ctx, 0x00000ae0/4, 0x00888001); ++ for (i = 0x00000b10; i <= 0x00000b8c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00000bb4/4, 0x00000005); ++ nv_wo32(dev, ctx, 0x00000bc0/4, 0x0000ffff); ++ for (i = 0x00000bdc; i <= 0x00000bf8; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00000bfc/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00000c34/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00000c38/4, 0x08e00001); ++ nv_wo32(dev, ctx, 0x00000c3c/4, 0x000e3000); ++ for (i = 0x00003000; i <= 0x00003078; i += 8) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x00004dc0; i <= 0x00006fb0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x00006fc0; i <= 0x000073b0; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x00009800; i <= 0x0000b9f0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x0000ba00; i <= 0x00010430; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x00010440; i <= 0x00010830; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x00012c80; i <= 0x00014e70; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x00014e80; i <= 0x00015270; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x000176c0; i <= 0x000198b0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x000198c0; i <= 0x00019cb0; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x0001c100; i <= 0x0001e2f0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x0001e300; i <= 0x0001e6f0; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++} ++ ++static void ++nv49_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x00000/4, ctx->im_pramin->start); ++ nv_wo32(dev, ctx, 0x00004/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x00008/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x0000c/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x00010/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x00014/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x00018/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x0001c/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x00020/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x000c4/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x000c8/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x000d0/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x001bc/4, 0x20010001); ++ nv_wo32(dev, ctx, 0x001c0/4, 0x0f73ef00); ++ nv_wo32(dev, ctx, 0x001c8/4, 0x02008821); ++ nv_wo32(dev, ctx, 0x00218/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x0021c/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00220/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00228/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00234/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00238/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x0023c/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00240/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00244/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00248/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x0024c/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00250/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00270/4, 0x0b0b0b0c); ++ nv_wo32(dev, ctx, 0x003e0/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x003f0/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x003f4/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x003f8/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x003fc/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00428/4, 0x00000008); ++ nv_wo32(dev, ctx, 0x0043c/4, 0x00001010); ++ nv_wo32(dev, ctx, 0x00460/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00464/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00468/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x0046c/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00470/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00474/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00478/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x0047c/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00480/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00484/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00488/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x0048c/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00490/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00494/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00498/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x0049c/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x004f4/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x004f8/4, 0x00080060); ++ nv_wo32(dev, ctx, 0x00514/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x00518/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x0051c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00530/4, 0x46400000); ++ nv_wo32(dev, ctx, 0x00540/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x00544/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00548/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x0054c/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00550/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00554/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00558/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x0055c/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00560/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00564/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00568/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x0056c/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00570/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00574/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00578/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x0057c/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00580/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00594/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00598/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x005a0/4, 0x00011100); ++ nv_wo32(dev, ctx, 0x005bc/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005c0/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005c4/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005c8/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005cc/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005d0/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005d4/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005d8/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005dc/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005e0/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005e4/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005e8/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005ec/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005f0/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005f4/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005f8/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x00604/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x0062c/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x00630/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x00634/4, 0xb8a89888); ++ nv_wo32(dev, ctx, 0x00638/4, 0xf8e8d8c8); ++ nv_wo32(dev, ctx, 0x0064c/4, 0x40100000); ++ nv_wo32(dev, ctx, 0x00668/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x0069c/4, 0x435185d6); ++ nv_wo32(dev, ctx, 0x006a0/4, 0x2155b699); ++ nv_wo32(dev, ctx, 0x006a4/4, 0xfedcba98); ++ nv_wo32(dev, ctx, 0x006a8/4, 0x00000098); ++ nv_wo32(dev, ctx, 0x006b8/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x006bc/4, 0x00ff7000); ++ nv_wo32(dev, ctx, 0x006c0/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x006d0/4, 0x00ff0000); ++ nv_wo32(dev, ctx, 0x0070c/4, 0x00ffff00); ++ for (i = 0x00750; i <= 0x0078c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00018488); ++ for (i = 0x00790; i <= 0x007cc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00028202); ++ for (i = 0x00810; i <= 0x0084c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0000aae4); ++ for (i = 0x00850; i <= 0x0088c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x00890; i <= 0x008cc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ for (i = 0x00910; i <= 0x0094c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00100008); ++ for (i = 0x009a0; i <= 0x009ac; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0001bc80); ++ for (i = 0x009b0; i <= 0x009bc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000202); ++ for (i = 0x009d0; i <= 0x009dc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000008); ++ for (i = 0x009f0; i <= 0x009fc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(dev, ctx, 0x00a10/4, 0x00000002); ++ nv_wo32(dev, ctx, 0x00a44/4, 0x00000421); ++ nv_wo32(dev, ctx, 0x00a48/4, 0x030c30c3); ++ nv_wo32(dev, ctx, 0x00a54/4, 0x3e020200); ++ nv_wo32(dev, ctx, 0x00a58/4, 0x00ffffff); ++ nv_wo32(dev, ctx, 0x00a5c/4, 0x20103f00); ++ nv_wo32(dev, ctx, 0x00a68/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x00aa0/4, 0x00008100); ++ nv_wo32(dev, ctx, 0x00b2c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00b70/4, 0x00001001); ++ nv_wo32(dev, ctx, 0x00b7c/4, 0x00000003); ++ nv_wo32(dev, ctx, 0x00b80/4, 0x00888001); ++ nv_wo32(dev, ctx, 0x00bb0/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bb4/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bb8/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bbc/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bc0/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bc4/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bc8/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bcc/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bd0/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bd4/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bd8/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bdc/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00be0/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00be4/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00be8/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bec/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bf0/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bf4/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bf8/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bfc/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c00/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c04/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c08/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c0c/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c10/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c14/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c18/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c1c/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c20/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c24/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c28/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c2c/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c54/4, 0x00000005); ++ nv_wo32(dev, ctx, 0x00c60/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00c7c/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c80/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c84/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c88/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c8c/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c90/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c94/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c98/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c9c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00cd4/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00cd8/4, 0x08e00001); ++ nv_wo32(dev, ctx, 0x00cdc/4, 0x000e3000); ++ for (i = 0x030a0; i <= 0x03118; i += 8) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x098a0; i <= 0x0ba90; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x0baa0; i <= 0x0be90; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x0e2e0; i <= 0x0fff0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x10008; i <= 0x104d0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x104e0; i <= 0x108d0; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x12d20; i <= 0x14f10; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x14f20; i <= 0x15310; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x17760; i <= 0x19950; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x19960; i <= 0x19d50; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x1c1a0; i <= 0x1e390; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x1e3a0; i <= 0x1e790; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x20be0; i <= 0x22dd0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x22de0; i <= 0x231d0; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++} ++ ++static void ++nv4a_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x00000/4, ctx->im_pramin->start); ++ nv_wo32(dev, ctx, 0x00024/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00028/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00030/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0011c/4, 0x20010001); ++ nv_wo32(dev, ctx, 0x00120/4, 0x0f73ef00); ++ nv_wo32(dev, ctx, 0x00128/4, 0x02008821); ++ nv_wo32(dev, ctx, 0x00158/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0015c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00160/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00164/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00168/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0016c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00170/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00174/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00178/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x0017c/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00180/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00188/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x001d0/4, 0x0b0b0b0c); ++ nv_wo32(dev, ctx, 0x00340/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x00350/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00354/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00358/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x0035c/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00388/4, 0x00000008); ++ nv_wo32(dev, ctx, 0x0039c/4, 0x00003010); ++ nv_wo32(dev, ctx, 0x003cc/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x003d0/4, 0x00080060); ++ nv_wo32(dev, ctx, 0x003ec/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x003f0/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x003f4/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00408/4, 0x46400000); ++ nv_wo32(dev, ctx, 0x00418/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x00424/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00428/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00430/4, 0x00011100); ++ for (i = 0x0044c; i <= 0x00488; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x00494/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x004bc/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x004c0/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x004c4/4, 0xb8a89888); ++ nv_wo32(dev, ctx, 0x004c8/4, 0xf8e8d8c8); ++ nv_wo32(dev, ctx, 0x004dc/4, 0x40100000); ++ nv_wo32(dev, ctx, 0x004f8/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x0052c/4, 0x435185d6); ++ nv_wo32(dev, ctx, 0x00530/4, 0x2155b699); ++ nv_wo32(dev, ctx, 0x00534/4, 0xfedcba98); ++ nv_wo32(dev, ctx, 0x00538/4, 0x00000098); ++ nv_wo32(dev, ctx, 0x00548/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x0054c/4, 0x00ff7000); ++ nv_wo32(dev, ctx, 0x00550/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x0055c/4, 0x00ff0000); ++ nv_wo32(dev, ctx, 0x00594/4, 0x00ffff00); ++ for (i = 0x005d8; i <= 0x00614; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00018488); ++ for (i = 0x00618; i <= 0x00654; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00028202); ++ for (i = 0x00698; i <= 0x006d4; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0000aae4); ++ for (i = 0x006d8; i <= 0x00714; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x00718; i <= 0x00754; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ for (i = 0x00798; i <= 0x007d4; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00100008); ++ for (i = 0x00828; i <= 0x00834; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0001bc80); ++ for (i = 0x00838; i <= 0x00844; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000202); ++ for (i = 0x00858; i <= 0x00864; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000008); ++ for (i = 0x00878; i <= 0x00884; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(dev, ctx, 0x00898/4, 0x00000002); ++ nv_wo32(dev, ctx, 0x008cc/4, 0x00000021); ++ nv_wo32(dev, ctx, 0x008d0/4, 0x030c30c3); ++ nv_wo32(dev, ctx, 0x008d4/4, 0x00011001); ++ nv_wo32(dev, ctx, 0x008e0/4, 0x3e020200); ++ nv_wo32(dev, ctx, 0x008e4/4, 0x00ffffff); ++ nv_wo32(dev, ctx, 0x008e8/4, 0x0c103f00); ++ nv_wo32(dev, ctx, 0x008f4/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x0092c/4, 0x00008100); ++ nv_wo32(dev, ctx, 0x009b8/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x009fc/4, 0x00001001); ++ nv_wo32(dev, ctx, 0x00a04/4, 0x00000003); ++ nv_wo32(dev, ctx, 0x00a08/4, 0x00888001); ++ nv_wo32(dev, ctx, 0x00a8c/4, 0x00000005); ++ nv_wo32(dev, ctx, 0x00a98/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00ab4/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00ab8/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00abc/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00ac0/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00af8/4, 0x00000001); ++ for (i = 0x016c0; i <= 0x01738; i += 8) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x03840; i <= 0x05670; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x05680; i <= 0x05a70; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x07e00; i <= 0x09ff0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x0a000; i <= 0x0a3f0; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x0c780; i <= 0x0e970; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x0e980; i <= 0x0ed70; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++} ++ ++static void ++nv4b_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x00000/4, ctx->im_pramin->start); ++ nv_wo32(dev, ctx, 0x00004/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x00008/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x0000c/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x00010/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x00014/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x00018/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x0001c/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x00020/4, 0x0000c040); ++ nv_wo32(dev, ctx, 0x000c4/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x000c8/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x000d0/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x001bc/4, 0x20010001); ++ nv_wo32(dev, ctx, 0x001c0/4, 0x0f73ef00); ++ nv_wo32(dev, ctx, 0x001c8/4, 0x02008821); ++ nv_wo32(dev, ctx, 0x00218/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x0021c/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00220/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00228/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00234/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00238/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x0023c/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00240/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00244/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00248/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x0024c/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00250/4, 0x80000000); ++ nv_wo32(dev, ctx, 0x00270/4, 0x0b0b0b0c); ++ nv_wo32(dev, ctx, 0x003e0/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x003f0/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x003f4/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x003f8/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x003fc/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00428/4, 0x00000008); ++ nv_wo32(dev, ctx, 0x0043c/4, 0x00001010); ++ nv_wo32(dev, ctx, 0x00460/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00464/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00468/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x0046c/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00470/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00474/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00478/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x0047c/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00480/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00484/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00488/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x0048c/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00490/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00494/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x00498/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x0049c/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x004f4/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x004f8/4, 0x00080060); ++ nv_wo32(dev, ctx, 0x00514/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x00518/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x0051c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00530/4, 0x46400000); ++ nv_wo32(dev, ctx, 0x00540/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x00544/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00548/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x0054c/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00550/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00554/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00558/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x0055c/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00560/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00564/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00568/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x0056c/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00570/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00574/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00578/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x0057c/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00580/4, 0x88888888); ++ nv_wo32(dev, ctx, 0x00594/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00598/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x005a0/4, 0x00011100); ++ nv_wo32(dev, ctx, 0x005bc/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005c0/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005c4/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005c8/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005cc/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005d0/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005d4/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005d8/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005dc/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005e0/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005e4/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005e8/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005ec/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005f0/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005f4/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x005f8/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x00604/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x0062c/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x00630/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x00634/4, 0xb8a89888); ++ nv_wo32(dev, ctx, 0x00638/4, 0xf8e8d8c8); ++ nv_wo32(dev, ctx, 0x0064c/4, 0x40100000); ++ nv_wo32(dev, ctx, 0x00668/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x0069c/4, 0x435185d6); ++ nv_wo32(dev, ctx, 0x006a0/4, 0x2155b699); ++ nv_wo32(dev, ctx, 0x006a4/4, 0xfedcba98); ++ nv_wo32(dev, ctx, 0x006a8/4, 0x00000098); ++ nv_wo32(dev, ctx, 0x006b8/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x006bc/4, 0x00ff7000); ++ nv_wo32(dev, ctx, 0x006c0/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x006d0/4, 0x00ff0000); ++ nv_wo32(dev, ctx, 0x0070c/4, 0x00ffff00); ++ for (i = 0x00750; i <= 0x0078c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00018488); ++ for (i = 0x00790; i <= 0x007cc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00028202); ++ for (i = 0x00810; i <= 0x0084c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0000aae4); ++ for (i = 0x00850; i <= 0x0088c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x00890; i <= 0x008cc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ for (i = 0x00910; i <= 0x0094c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00100008); ++ for (i = 0x009a0; i <= 0x009ac; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0001bc80); ++ for (i = 0x009b0; i <= 0x009bc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000202); ++ for (i = 0x009d0; i <= 0x009dc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000008); ++ for (i = 0x009f0; i <= 0x009fc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(dev, ctx, 0x00a10/4, 0x00000002); ++ nv_wo32(dev, ctx, 0x00a44/4, 0x00000421); ++ nv_wo32(dev, ctx, 0x00a48/4, 0x030c30c3); ++ nv_wo32(dev, ctx, 0x00a54/4, 0x3e020200); ++ nv_wo32(dev, ctx, 0x00a58/4, 0x00ffffff); ++ nv_wo32(dev, ctx, 0x00a5c/4, 0x20103f00); ++ nv_wo32(dev, ctx, 0x00a68/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x00aa0/4, 0x00008100); ++ nv_wo32(dev, ctx, 0x00b2c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00b70/4, 0x00001001); ++ nv_wo32(dev, ctx, 0x00b7c/4, 0x00000003); ++ nv_wo32(dev, ctx, 0x00b80/4, 0x00888001); ++ nv_wo32(dev, ctx, 0x00bb0/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bb4/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bb8/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bbc/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bc0/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bc4/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bc8/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bcc/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bd0/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bd4/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bd8/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bdc/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00be0/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00be4/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00be8/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bec/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bf0/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bf4/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bf8/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00bfc/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c00/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c04/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c08/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c0c/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c10/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c14/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c18/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c1c/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c20/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c24/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c28/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c2c/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00c54/4, 0x00000005); ++ nv_wo32(dev, ctx, 0x00c60/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00c7c/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c80/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c84/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c88/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c8c/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c90/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c94/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c98/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00c9c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00cd4/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00cd8/4, 0x08e00001); ++ nv_wo32(dev, ctx, 0x00cdc/4, 0x000e3000); ++ for (i = 0x030a0; i <= 0x03118; i += 8) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x098a0; i <= 0x0ba90; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x0baa0; i <= 0x0be90; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x0e2e0; i <= 0x0fff0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x10008; i <= 0x104d0; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x104e0; i <= 0x108d0; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x12d20; i <= 0x14f10; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x14f20; i <= 0x15310; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x17760; i <= 0x19950; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x19960; i <= 0x19d50; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++} ++ ++static void ++nv4c_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x00000/4, ctx->im_pramin->start); ++ nv_wo32(dev, ctx, 0x00024/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00028/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00030/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0011c/4, 0x20010001); ++ nv_wo32(dev, ctx, 0x00120/4, 0x0f73ef00); ++ nv_wo32(dev, ctx, 0x00128/4, 0x02008821); ++ nv_wo32(dev, ctx, 0x00158/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0015c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00160/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00164/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00168/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0016c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00170/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00174/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00178/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x0017c/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00180/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00188/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x001d0/4, 0x0b0b0b0c); ++ nv_wo32(dev, ctx, 0x00340/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x00350/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00354/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00358/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x0035c/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00388/4, 0x00000008); ++ nv_wo32(dev, ctx, 0x0039c/4, 0x00001010); ++ nv_wo32(dev, ctx, 0x003d0/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x003d4/4, 0x00080060); ++ nv_wo32(dev, ctx, 0x003f0/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x003f4/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x003f8/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0040c/4, 0x46400000); ++ nv_wo32(dev, ctx, 0x0041c/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x00428/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x0042c/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00434/4, 0x00011100); ++ for (i = 0x00450; i < 0x0048c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x00498/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x004c0/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x004c4/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x004c8/4, 0xb8a89888); ++ nv_wo32(dev, ctx, 0x004cc/4, 0xf8e8d8c8); ++ nv_wo32(dev, ctx, 0x004e0/4, 0x40100000); ++ nv_wo32(dev, ctx, 0x004fc/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00530/4, 0x435185d6); ++ nv_wo32(dev, ctx, 0x00534/4, 0x2155b699); ++ nv_wo32(dev, ctx, 0x00538/4, 0xfedcba98); ++ nv_wo32(dev, ctx, 0x0053c/4, 0x00000098); ++ nv_wo32(dev, ctx, 0x0054c/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x00550/4, 0x00ff7000); ++ nv_wo32(dev, ctx, 0x00554/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00564/4, 0x00ff0000); ++ nv_wo32(dev, ctx, 0x0059c/4, 0x00ffff00); ++ for (i = 0x005e0; i <= 0x0061c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00018488); ++ for (i = 0x00620; i <= 0x0065c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00028202); ++ for (i = 0x006a0; i <= 0x006dc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0000aae4); ++ for (i = 0x006e0; i <= 0x0071c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x00720; i <= 0x0075c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ for (i = 0x007a0; i <= 0x007dc; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00100008); ++ for (i = 0x00830; i <= 0x0083c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0001bc80); ++ for (i = 0x00840; i <= 0x0084c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000202); ++ for (i = 0x00860; i <= 0x0086c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000008); ++ for (i = 0x00880; i <= 0x0088c; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(dev, ctx, 0x008a0/4, 0x00000002); ++ nv_wo32(dev, ctx, 0x008d4/4, 0x00000020); ++ nv_wo32(dev, ctx, 0x008d8/4, 0x030c30c3); ++ nv_wo32(dev, ctx, 0x008dc/4, 0x00011001); ++ nv_wo32(dev, ctx, 0x008e8/4, 0x3e020200); ++ nv_wo32(dev, ctx, 0x008ec/4, 0x00ffffff); ++ nv_wo32(dev, ctx, 0x008f0/4, 0x0c103f00); ++ nv_wo32(dev, ctx, 0x008fc/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x00934/4, 0x00008100); ++ nv_wo32(dev, ctx, 0x009c0/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00a04/4, 0x00001001); ++ nv_wo32(dev, ctx, 0x00a0c/4, 0x00000003); ++ nv_wo32(dev, ctx, 0x00a10/4, 0x00888001); ++ nv_wo32(dev, ctx, 0x00a74/4, 0x00000005); ++ nv_wo32(dev, ctx, 0x00a80/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00a9c/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00aa0/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00ad8/4, 0x00000001); ++ for (i = 0x016a0; i < 0x01718; i += 8) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x03460; i < 0x05650; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x05660; i < 0x05a50; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++} ++ ++static void ++nv4e_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) ++{ ++ int i; ++ ++ nv_wo32(dev, ctx, 0x00000/4, ctx->im_pramin->start); ++ nv_wo32(dev, ctx, 0x00024/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00028/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00030/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0011c/4, 0x20010001); ++ nv_wo32(dev, ctx, 0x00120/4, 0x0f73ef00); ++ nv_wo32(dev, ctx, 0x00128/4, 0x02008821); ++ nv_wo32(dev, ctx, 0x00158/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0015c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00160/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00164/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00168/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x0016c/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00170/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00174/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00178/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x0017c/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00180/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x00188/4, 0x00000040); ++ nv_wo32(dev, ctx, 0x001d0/4, 0x0b0b0b0c); ++ nv_wo32(dev, ctx, 0x00340/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x00350/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00354/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00358/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x0035c/4, 0x55555555); ++ nv_wo32(dev, ctx, 0x00388/4, 0x00000008); ++ nv_wo32(dev, ctx, 0x0039c/4, 0x00001010); ++ nv_wo32(dev, ctx, 0x003cc/4, 0x00000111); ++ nv_wo32(dev, ctx, 0x003d0/4, 0x00080060); ++ nv_wo32(dev, ctx, 0x003ec/4, 0x00000080); ++ nv_wo32(dev, ctx, 0x003f0/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x003f4/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00408/4, 0x46400000); ++ nv_wo32(dev, ctx, 0x00418/4, 0xffff0000); ++ nv_wo32(dev, ctx, 0x00424/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00428/4, 0x0fff0000); ++ nv_wo32(dev, ctx, 0x00430/4, 0x00011100); ++ for (i = 0x0044c; i <= 0x00488; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x07ff0000); ++ nv_wo32(dev, ctx, 0x00494/4, 0x4b7fffff); ++ nv_wo32(dev, ctx, 0x004bc/4, 0x30201000); ++ nv_wo32(dev, ctx, 0x004c0/4, 0x70605040); ++ nv_wo32(dev, ctx, 0x004c4/4, 0xb8a89888); ++ nv_wo32(dev, ctx, 0x004c8/4, 0xf8e8d8c8); ++ nv_wo32(dev, ctx, 0x004dc/4, 0x40100000); ++ nv_wo32(dev, ctx, 0x004f8/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x0052c/4, 0x435185d6); ++ nv_wo32(dev, ctx, 0x00530/4, 0x2155b699); ++ nv_wo32(dev, ctx, 0x00534/4, 0xfedcba98); ++ nv_wo32(dev, ctx, 0x00538/4, 0x00000098); ++ nv_wo32(dev, ctx, 0x00548/4, 0xffffffff); ++ nv_wo32(dev, ctx, 0x0054c/4, 0x00ff7000); ++ nv_wo32(dev, ctx, 0x00550/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x0055c/4, 0x00ff0000); ++ nv_wo32(dev, ctx, 0x00594/4, 0x00ffff00); ++ for (i = 0x005d8; i <= 0x00614; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00018488); ++ for (i = 0x00618; i <= 0x00654; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00028202); ++ for (i = 0x00698; i <= 0x006d4; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0000aae4); ++ for (i = 0x006d8; i <= 0x00714; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x01012000); ++ for (i = 0x00718; i <= 0x00754; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ for (i = 0x00798; i <= 0x007d4; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00100008); ++ for (i = 0x00828; i <= 0x00834; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x0001bc80); ++ for (i = 0x00838; i <= 0x00844; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000202); ++ for (i = 0x00858; i <= 0x00864; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00000008); ++ for (i = 0x00878; i <= 0x00884; i += 4) ++ nv_wo32(dev, ctx, i/4, 0x00080008); ++ nv_wo32(dev, ctx, 0x00898/4, 0x00000002); ++ nv_wo32(dev, ctx, 0x008cc/4, 0x00000020); ++ nv_wo32(dev, ctx, 0x008d0/4, 0x030c30c3); ++ nv_wo32(dev, ctx, 0x008d4/4, 0x00011001); ++ nv_wo32(dev, ctx, 0x008e0/4, 0x3e020200); ++ nv_wo32(dev, ctx, 0x008e4/4, 0x00ffffff); ++ nv_wo32(dev, ctx, 0x008e8/4, 0x0c103f00); ++ nv_wo32(dev, ctx, 0x008f4/4, 0x00040000); ++ nv_wo32(dev, ctx, 0x0092c/4, 0x00008100); ++ nv_wo32(dev, ctx, 0x009b8/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x009fc/4, 0x00001001); ++ nv_wo32(dev, ctx, 0x00a04/4, 0x00000003); ++ nv_wo32(dev, ctx, 0x00a08/4, 0x00888001); ++ nv_wo32(dev, ctx, 0x00a6c/4, 0x00000005); ++ nv_wo32(dev, ctx, 0x00a78/4, 0x0000ffff); ++ nv_wo32(dev, ctx, 0x00a94/4, 0x00005555); ++ nv_wo32(dev, ctx, 0x00a98/4, 0x00000001); ++ nv_wo32(dev, ctx, 0x00aa4/4, 0x00000001); ++ for (i = 0x01668; i <= 0x016e0; i += 8) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++ for (i = 0x03428; i <= 0x05618; i += 24) ++ nv_wo32(dev, ctx, i/4, 0x00000001); ++ for (i = 0x05628; i <= 0x05a18; i += 16) ++ nv_wo32(dev, ctx, i/4, 0x3f800000); ++} ++ ++struct nouveau_channel * ++nv40_graph_channel(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t inst; ++ int i; ++ ++ inst = nv_rd32(dev, NV40_PGRAPH_CTXCTL_CUR); ++ if (!(inst & NV40_PGRAPH_CTXCTL_CUR_LOADED)) ++ return NULL; ++ inst = (inst & NV40_PGRAPH_CTXCTL_CUR_INSTANCE) << 4; ++ ++ for (i = 0; i < dev_priv->engine.fifo.channels; i++) { ++ struct nouveau_channel *chan = dev_priv->fifos[i]; ++ ++ if (chan && chan->ramin_grctx && ++ chan->ramin_grctx->instance == inst) ++ return chan; ++ } ++ ++ return NULL; ++} ++ ++int ++nv40_graph_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *); ++ int ret; ++ ++ /* These functions populate the graphics context with a whole heap ++ * of default state. All these functions are very similar, with ++ * a minimal amount of chipset-specific changes. However, as we're ++ * currently dependant on the context programs used by the NVIDIA ++ * binary driver these functions must match the layout expected by ++ * them. Hopefully at some point this will all change. ++ */ ++ switch (dev_priv->chipset) { ++ case 0x40: ++ ctx_init = nv40_graph_context_init; ++ break; ++ case 0x41: ++ case 0x42: ++ ctx_init = nv41_graph_context_init; ++ break; ++ case 0x43: ++ ctx_init = nv43_graph_context_init; ++ break; ++ case 0x46: ++ ctx_init = nv46_graph_context_init; ++ break; ++ case 0x47: ++ ctx_init = nv47_graph_context_init; ++ break; ++ case 0x49: ++ ctx_init = nv49_graph_context_init; ++ break; ++ case 0x44: ++ case 0x4a: ++ ctx_init = nv4a_graph_context_init; ++ break; ++ case 0x4b: ++ ctx_init = nv4b_graph_context_init; ++ break; ++ case 0x4c: ++ case 0x67: ++ ctx_init = nv4c_graph_context_init; ++ break; ++ case 0x4e: ++ ctx_init = nv4e_graph_context_init; ++ break; ++ default: ++ ctx_init = nv40_graph_context_init; ++ break; ++ } ++ ++ /* Allocate a 175KiB block of PRAMIN to store the context. This ++ * is massive overkill for a lot of chipsets, but it should be safe ++ * until we're able to implement this properly (will happen at more ++ * or less the same time we're able to write our own context programs. ++ */ ++ ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 175*1024, 16, ++ NVOBJ_FLAG_ZERO_ALLOC, ++ &chan->ramin_grctx); ++ if (ret) ++ return ret; ++ ++ /* Initialise default context values */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ ctx_init(dev, chan->ramin_grctx->gpuobj); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ return 0; ++} ++ ++void ++nv40_graph_destroy_context(struct nouveau_channel *chan) ++{ ++ nouveau_gpuobj_ref_del(chan->dev, &chan->ramin_grctx); ++} ++ ++static int ++nv40_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save) ++{ ++ uint32_t old_cp, tv = 1000, tmp; ++ int i; ++ ++ old_cp = nv_rd32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER); ++ nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); ++ ++ tmp = nv_rd32(dev, NV40_PGRAPH_CTXCTL_0310); ++ tmp |= save ? NV40_PGRAPH_CTXCTL_0310_XFER_SAVE : ++ NV40_PGRAPH_CTXCTL_0310_XFER_LOAD; ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_0310, tmp); ++ ++ tmp = nv_rd32(dev, NV40_PGRAPH_CTXCTL_0304); ++ tmp |= NV40_PGRAPH_CTXCTL_0304_XFER_CTX; ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_0304, tmp); ++ ++ nouveau_wait_for_idle(dev); ++ ++ for (i = 0; i < tv; i++) { ++ if (nv_rd32(dev, NV40_PGRAPH_CTXCTL_030C) == 0) ++ break; ++ } ++ ++ nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, old_cp); ++ ++ if (i == tv) { ++ uint32_t ucstat = nv_rd32(dev, NV40_PGRAPH_CTXCTL_UCODE_STAT); ++ NV_ERROR(dev, "Failed: Instance=0x%08x Save=%d\n", inst, save); ++ NV_ERROR(dev, "IP: 0x%02x, Opcode: 0x%08x\n", ++ ucstat >> NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT, ++ ucstat & NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK); ++ NV_ERROR(dev, "0x40030C = 0x%08x\n", ++ nv_rd32(dev, NV40_PGRAPH_CTXCTL_030C)); ++ return -EBUSY; ++ } ++ ++ return 0; ++} ++ ++/* Restore the context for a specific channel into PGRAPH */ ++int ++nv40_graph_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ uint32_t inst; ++ int ret; ++ ++ if (!chan->ramin_grctx) ++ return -EINVAL; ++ inst = chan->ramin_grctx->instance >> 4; ++ ++ ret = nv40_graph_transfer_context(dev, inst, 0); ++ if (ret) ++ return ret; ++ ++ /* 0x40032C, no idea of it's exact function. Could simply be a ++ * record of the currently active PGRAPH context. It's currently ++ * unknown as to what bit 24 does. The nv ddx has it set, so we will ++ * set it here too. ++ */ ++ nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, ++ (inst & NV40_PGRAPH_CTXCTL_CUR_INSTANCE) | ++ NV40_PGRAPH_CTXCTL_CUR_LOADED); ++ /* 0x32E0 records the instance address of the active FIFO's PGRAPH ++ * context. If at any time this doesn't match 0x40032C, you will ++ * recieve PGRAPH_INTR_CONTEXT_SWITCH ++ */ ++ nv_wr32(dev, NV40_PFIFO_GRCTX_INSTANCE, inst); ++ return 0; ++} ++ ++int ++nv40_graph_unload_context(struct drm_device *dev) ++{ ++ uint32_t inst; ++ int ret; ++ ++ inst = nv_rd32(dev, NV40_PGRAPH_CTXCTL_CUR); ++ if (!(inst & NV40_PGRAPH_CTXCTL_CUR_LOADED)) ++ return 0; ++ inst &= NV40_PGRAPH_CTXCTL_CUR_INSTANCE; ++ ++ ret = nv40_graph_transfer_context(dev, inst, 1); ++ ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, inst); ++ return ret; ++} ++ ++/* These blocks of "magic numbers" are actually a microcode that the GPU uses ++ * to control how graphics contexts get saved and restored between PRAMIN ++ * and PGRAPH during a context switch. We're currently using values seen ++ * in mmio-traces of the binary driver. ++ */ ++static uint32_t nv40_ctxprog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00408f65, 0x00409406, ++ 0x0040a268, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004014e6, 0x007000a0, 0x00401a84, 0x00700082, 0x00600001, 0x00500061, ++ 0x00600002, 0x00401b68, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00110205, 0x0011420a, 0x00114210, 0x00110216, ++ 0x0012421b, 0x00120270, 0x001242c0, 0x00200040, 0x00100280, 0x00128100, ++ 0x00128120, 0x00128143, 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, ++ 0x00110400, 0x00104d10, 0x00500060, 0x00403b87, 0x0060000d, 0x004076e6, ++ 0x002000f0, 0x0060000a, 0x00200045, 0x00100620, 0x00108668, 0x0011466b, ++ 0x00120682, 0x0011068b, 0x00168691, 0x0010c6ae, 0x001206b4, 0x0020002a, ++ 0x001006c4, 0x001246f0, 0x002000c0, 0x00100700, 0x0010c3d7, 0x001043e1, ++ 0x00500060, 0x00405600, 0x00405684, 0x00600003, 0x00500067, 0x00600008, ++ 0x00500060, 0x00700082, 0x0020026c, 0x0060000a, 0x00104800, 0x00104901, ++ 0x00120920, 0x00200035, 0x00100940, 0x00148a00, 0x00104a14, 0x00200038, ++ 0x00100b00, 0x00138d00, 0x00104e00, 0x0012d600, 0x00105c00, 0x00104f06, ++ 0x0020031a, 0x0060000a, 0x00300000, 0x00200680, 0x00406c00, 0x00200684, ++ 0x00800001, 0x00200b62, 0x0060000a, 0x0020a0b0, 0x0040728a, 0x00201b68, ++ 0x00800041, 0x00407684, 0x00203e60, 0x00800002, 0x00408700, 0x00600006, ++ 0x00700003, 0x004080e6, 0x00700080, 0x0020031a, 0x0060000a, 0x00200004, ++ 0x00800001, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a284, ++ 0x00700002, 0x00600004, 0x0040a268, 0x00700000, 0x00200000, 0x0060000a, ++ 0x00106002, 0x00700080, 0x00400a84, 0x00700002, 0x00400a68, 0x00500060, ++ 0x00600007, 0x00409388, 0x0060000f, 0x00000000, 0x00500060, 0x00200000, ++ 0x0060000a, 0x00700000, 0x00106001, 0x00700083, 0x00910880, 0x00901ffe, ++ 0x00940400, 0x00200020, 0x0060000b, 0x00500069, 0x0060000c, 0x00401b68, ++ 0x0040a406, 0x0040a505, 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ++ ~0 ++}; ++ ++static uint32_t nv41_ctxprog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00408f65, 0x00409306, ++ 0x0040a068, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, ++ 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, 0x00401826, 0x00401968, ++ 0x0060000d, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004020e6, 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, ++ 0x001046ec, 0x00500060, 0x00404087, 0x0060000d, 0x004079e6, 0x002000f1, ++ 0x0060000a, 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, 0x0011068b, ++ 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, ++ 0x00200020, 0x001006cc, 0x001046ed, 0x001246f0, 0x002000c0, 0x00100700, ++ 0x0010c3d7, 0x001043e1, 0x00500060, 0x00200233, 0x0060000a, 0x00104800, ++ 0x00108901, 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00148a00, ++ 0x00108a14, 0x00200020, 0x00100b00, 0x00134b2c, 0x0010cd00, 0x0010cd04, ++ 0x00114d08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, 0x00104f06, ++ 0x002002d2, 0x0060000a, 0x00300000, 0x00200680, 0x00407200, 0x00200684, ++ 0x00800001, 0x00200b1a, 0x0060000a, 0x00206380, 0x0040788a, 0x00201480, ++ 0x00800041, 0x00408900, 0x00600006, 0x004085e6, 0x00700080, 0x0020007a, ++ 0x0060000a, 0x00104280, 0x002002d2, 0x0060000a, 0x00200004, 0x00800001, ++ 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a068, 0x00700000, ++ 0x00200000, 0x0060000a, 0x00106002, 0x00700080, 0x00400a68, 0x00500060, ++ 0x00600007, 0x00409388, 0x0060000f, 0x00500060, 0x00200000, 0x0060000a, ++ 0x00700000, 0x00106001, 0x00910880, 0x00901ffe, 0x00940400, 0x00200020, ++ 0x0060000b, 0x00500069, 0x0060000c, 0x00402168, 0x0040a206, 0x0040a305, ++ 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 ++}; ++ ++static uint32_t nv43_ctxprog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409565, 0x00409a06, ++ 0x0040a868, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004014e6, 0x007000a0, 0x00401a84, 0x00700082, 0x00600001, 0x00500061, ++ 0x00600002, 0x00401b68, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, ++ 0x001046ec, 0x00500060, 0x00403a87, 0x0060000d, 0x00407ce6, 0x002000f1, ++ 0x0060000a, 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, 0x0011068b, ++ 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, ++ 0x00200020, 0x001006cc, 0x001046ed, 0x001246f0, 0x002000c0, 0x00100700, ++ 0x0010c3d7, 0x001043e1, 0x00500060, 0x00405800, 0x00405884, 0x00600003, ++ 0x00500067, 0x00600008, 0x00500060, 0x00700082, 0x00200233, 0x0060000a, ++ 0x00104800, 0x00108901, 0x00124920, 0x0020001f, 0x00100940, 0x00140965, ++ 0x00148a00, 0x00108a14, 0x00160b00, 0x00134b2c, 0x0010cd00, 0x0010cd04, ++ 0x0010cd08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, 0x00104f06, ++ 0x002002c8, 0x0060000a, 0x00300000, 0x00200680, 0x00407200, 0x00200684, ++ 0x00800001, 0x00200b10, 0x0060000a, 0x00203870, 0x0040788a, 0x00201350, ++ 0x00800041, 0x00407c84, 0x00201560, 0x00800002, 0x00408d00, 0x00600006, ++ 0x00700003, 0x004086e6, 0x00700080, 0x002002c8, 0x0060000a, 0x00200004, ++ 0x00800001, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a884, ++ 0x00700002, 0x00600004, 0x0040a868, 0x00700000, 0x00200000, 0x0060000a, ++ 0x00106002, 0x00700080, 0x00400a84, 0x00700002, 0x00400a68, 0x00500060, ++ 0x00600007, 0x00409988, 0x0060000f, 0x00000000, 0x00500060, 0x00200000, ++ 0x0060000a, 0x00700000, 0x00106001, 0x00700083, 0x00910880, 0x00901ffe, ++ 0x00940400, 0x00200020, 0x0060000b, 0x00500069, 0x0060000c, 0x00401b68, ++ 0x0040aa06, 0x0040ab05, 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ++ ~0 ++}; ++ ++static uint32_t nv44_ctxprog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409a65, 0x00409f06, ++ 0x0040ac68, 0x0040248f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, ++ 0x001041c6, 0x00104040, 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, ++ 0x00402320, 0x00402321, 0x00402322, 0x00402324, 0x00402326, 0x0040232b, ++ 0x001040c5, 0x00402328, 0x001040c5, 0x00402320, 0x00402468, 0x0060000d, ++ 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, 0x00402be6, ++ 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, 0x00110158, ++ 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, 0x001041c9, ++ 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, 0x001242c0, ++ 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, 0x0011415f, ++ 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, 0x001046ec, ++ 0x00500060, 0x00404b87, 0x0060000d, 0x004084e6, 0x002000f1, 0x0060000a, ++ 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, 0x0011068b, 0x00168691, ++ 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, 0x001646cc, ++ 0x001186e6, 0x001046ed, 0x001246f0, 0x002000c0, 0x00100700, 0x0010c3d7, ++ 0x001043e1, 0x00500060, 0x00200232, 0x0060000a, 0x00104800, 0x00108901, ++ 0x00104910, 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00148a00, ++ 0x00108a14, 0x00160b00, 0x00134b2c, 0x0010cd00, 0x0010cd04, 0x0010cd08, ++ 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, 0x00104f06, 0x002002c8, ++ 0x0060000a, 0x00300000, 0x00200080, 0x00407d00, 0x00200084, 0x00800001, ++ 0x00200510, 0x0060000a, 0x002037e0, 0x0040838a, 0x00201320, 0x00800029, ++ 0x00409400, 0x00600006, 0x004090e6, 0x00700080, 0x0020007a, 0x0060000a, ++ 0x00104280, 0x002002c8, 0x0060000a, 0x00200004, 0x00800001, 0x00700000, ++ 0x00200000, 0x0060000a, 0x00106002, 0x0040ac68, 0x00700000, 0x00200000, ++ 0x0060000a, 0x00106002, 0x00700080, 0x00400a68, 0x00500060, 0x00600007, ++ 0x00409e88, 0x0060000f, 0x00000000, 0x00500060, 0x00200000, 0x0060000a, ++ 0x00700000, 0x00106001, 0x00910880, 0x00901ffe, 0x01940000, 0x00200020, ++ 0x0060000b, 0x00500069, 0x0060000c, 0x00402c68, 0x0040ae06, 0x0040af05, ++ 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 ++}; ++ ++static uint32_t nv46_ctxprog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00408f65, 0x00409306, ++ 0x0040a068, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, ++ 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, 0x00401826, 0x00401968, ++ 0x0060000d, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004020e6, 0x007000a0, 0x00500060, 0x00200008, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, ++ 0x00500060, 0x00403f87, 0x0060000d, 0x004079e6, 0x002000f7, 0x0060000a, ++ 0x00200045, 0x00100620, 0x00104668, 0x0017466d, 0x0011068b, 0x00168691, ++ 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, 0x00200022, ++ 0x001006cc, 0x001246f0, 0x002000c0, 0x00100700, 0x0010c3d7, 0x001043e1, ++ 0x00500060, 0x0020027f, 0x0060000a, 0x00104800, 0x00108901, 0x00104910, ++ 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00148a00, 0x00108a14, ++ 0x00160b00, 0x00134b2c, 0x0010cd00, 0x0010cd04, 0x0010cd08, 0x00104d80, ++ 0x00104e00, 0x0012d600, 0x00105c00, 0x00104f06, 0x00105406, 0x00105709, ++ 0x00200316, 0x0060000a, 0x00300000, 0x00200080, 0x00407200, 0x00200084, ++ 0x00800001, 0x0020055e, 0x0060000a, 0x002037e0, 0x0040788a, 0x00201320, ++ 0x00800029, 0x00408900, 0x00600006, 0x004085e6, 0x00700080, 0x00200081, ++ 0x0060000a, 0x00104280, 0x00200316, 0x0060000a, 0x00200004, 0x00800001, ++ 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a068, 0x00700000, ++ 0x00200000, 0x0060000a, 0x00106002, 0x00700080, 0x00400a68, 0x00500060, ++ 0x00600007, 0x00409388, 0x0060000f, 0x00500060, 0x00200000, 0x0060000a, ++ 0x00700000, 0x00106001, 0x00910880, 0x00901ffe, 0x01940000, 0x00200020, ++ 0x0060000b, 0x00500069, 0x0060000c, 0x00402168, 0x0040a206, 0x0040a305, ++ 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 ++}; ++ ++static uint32_t nv47_ctxprog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409265, 0x00409606, ++ 0x0040a368, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, ++ 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, 0x00401826, 0x00401968, ++ 0x0060000d, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004020e6, 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d12, ++ 0x00500060, 0x00403f87, 0x0060000d, 0x00407ce6, 0x002000f0, 0x0060000a, ++ 0x00200020, 0x00100620, 0x00154650, 0x00104668, 0x0017466d, 0x0011068b, ++ 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, ++ 0x00200022, 0x001006cc, 0x001246f0, 0x002000c0, 0x00100700, 0x0010c3d7, ++ 0x001043e1, 0x00500060, 0x00200268, 0x0060000a, 0x00104800, 0x00108901, ++ 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00144a00, 0x00104a19, ++ 0x0010ca1c, 0x00110b00, 0x00200028, 0x00100b08, 0x00134c2e, 0x0010cd00, ++ 0x0010cd04, 0x00120d08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, ++ 0x00104f06, 0x00105406, 0x00105709, 0x00200318, 0x0060000a, 0x00300000, ++ 0x00200680, 0x00407500, 0x00200684, 0x00800001, 0x00200b60, 0x0060000a, ++ 0x00209540, 0x00407b8a, 0x00201350, 0x00800041, 0x00408c00, 0x00600006, ++ 0x004088e6, 0x00700080, 0x0020007a, 0x0060000a, 0x00104280, 0x00200318, ++ 0x0060000a, 0x00200004, 0x00800001, 0x00700000, 0x00200000, 0x0060000a, ++ 0x00106002, 0x0040a368, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, ++ 0x00700080, 0x00400a68, 0x00500060, 0x00600007, 0x00409688, 0x0060000f, ++ 0x00500060, 0x00200000, 0x0060000a, 0x00700000, 0x00106001, 0x0091a880, ++ 0x00901ffe, 0x10940000, 0x00200020, 0x0060000b, 0x00500069, 0x0060000c, ++ 0x00402168, 0x0040a506, 0x0040a605, 0x00600009, 0x00700005, 0x00700006, ++ 0x0060000e, ~0 ++}; ++ ++/* this is used for nv49 and nv4b */ ++static uint32_t nv49_4b_ctxprog[] = { ++ 0x00400564, 0x00400505, 0x00408165, 0x00408206, 0x00409e68, 0x00200020, ++ 0x0060000a, 0x00700080, 0x00104042, 0x00200020, 0x0060000a, 0x00700000, ++ 0x001040c5, 0x00400f26, 0x00401068, 0x0060000d, 0x0070008f, 0x0070000e, ++ 0x00408d68, 0x004015e6, 0x007000a0, 0x00700080, 0x0040180f, 0x00700000, ++ 0x00200029, 0x0060000a, 0x0011814d, 0x00110158, 0x00105401, 0x0020003a, ++ 0x00100051, 0x001040c5, 0x0010c1c4, 0x001041c9, 0x0010c1dc, 0x00150210, ++ 0x0012c225, 0x00108238, 0x0010823e, 0x001242c0, 0x00200040, 0x00100280, ++ 0x00128100, 0x00128120, 0x00128143, 0x0011415f, 0x0010815c, 0x0010c140, ++ 0x00104029, 0x00110400, 0x00104d12, 0x00500060, 0x004071e6, 0x00200118, ++ 0x0060000a, 0x00200020, 0x00100620, 0x00154650, 0x00104668, 0x0017466d, ++ 0x0011068b, 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, ++ 0x001146c6, 0x00200022, 0x001006cc, 0x001246f0, 0x002000c0, 0x00100700, ++ 0x0010c3d7, 0x001043e1, 0x00500060, 0x00200290, 0x0060000a, 0x00104800, ++ 0x00108901, 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00144a00, ++ 0x00104a19, 0x0010ca1c, 0x00110b00, 0x00200028, 0x00100b08, 0x00134c2e, ++ 0x0010cd00, 0x0010cd04, 0x00120d08, 0x00104d80, 0x00104e00, 0x0012d600, ++ 0x00105c00, 0x00104f06, 0x00105406, 0x00105709, 0x00200340, 0x0060000a, ++ 0x00300000, 0x00200680, 0x00406a0f, 0x00200684, 0x00800001, 0x00200b88, ++ 0x0060000a, 0x00209540, 0x0040708a, 0x00201350, 0x00800041, 0x00407c0f, ++ 0x00600006, 0x00407ce6, 0x00700080, 0x002000a2, 0x0060000a, 0x00104280, ++ 0x00200340, 0x0060000a, 0x00200004, 0x00800001, 0x0070008e, 0x00408d68, ++ 0x0040020f, 0x00600006, 0x00409e68, 0x00600007, 0x0070000f, 0x0070000e, ++ 0x00408d68, 0x0091a880, 0x00901ffe, 0x10940000, 0x00200020, 0x0060000b, ++ 0x00500069, 0x0060000c, 0x00401568, 0x00700000, 0x00200001, 0x0040910e, ++ 0x00200021, 0x0060000a, 0x00409b0d, 0x00104a40, 0x00104a50, 0x00104a60, ++ 0x00104a70, 0x00104a80, 0x00104a90, 0x00104aa0, 0x00104ab0, 0x00407e0e, ++ 0x0040130f, 0x00408568, 0x0040a006, 0x0040a105, 0x00600009, 0x00700005, ++ 0x00700006, 0x0060000e, ~0 ++}; ++ ++ ++static uint32_t nv4a_ctxprog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409965, 0x00409e06, ++ 0x0040ac68, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004014e6, 0x007000a0, 0x00401a84, 0x00700082, 0x00600001, 0x00500061, ++ 0x00600002, 0x00401b68, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, ++ 0x001046ec, 0x00500060, 0x00403a87, 0x0060000d, 0x00407de6, 0x002000f1, ++ 0x0060000a, 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, 0x0011068b, ++ 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, ++ 0x001646cc, 0x001186e6, 0x001046ed, 0x001246f0, 0x002000c0, 0x00100700, ++ 0x0010c3d7, 0x001043e1, 0x00500060, 0x00405800, 0x00405884, 0x00600003, ++ 0x00500067, 0x00600008, 0x00500060, 0x00700082, 0x00200232, 0x0060000a, ++ 0x00104800, 0x00108901, 0x00104910, 0x00124920, 0x0020001f, 0x00100940, ++ 0x00140965, 0x00148a00, 0x00108a14, 0x00160b00, 0x00134b2c, 0x0010cd00, ++ 0x0010cd04, 0x0010cd08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, ++ 0x00104f06, 0x002002c8, 0x0060000a, 0x00300000, 0x00200080, 0x00407300, ++ 0x00200084, 0x00800001, 0x00200510, 0x0060000a, 0x002037e0, 0x0040798a, ++ 0x00201320, 0x00800029, 0x00407d84, 0x00201560, 0x00800002, 0x00409100, ++ 0x00600006, 0x00700003, 0x00408ae6, 0x00700080, 0x0020007a, 0x0060000a, ++ 0x00104280, 0x002002c8, 0x0060000a, 0x00200004, 0x00800001, 0x00700000, ++ 0x00200000, 0x0060000a, 0x00106002, 0x0040ac84, 0x00700002, 0x00600004, ++ 0x0040ac68, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x00700080, ++ 0x00400a84, 0x00700002, 0x00400a68, 0x00500060, 0x00600007, 0x00409d88, ++ 0x0060000f, 0x00000000, 0x00500060, 0x00200000, 0x0060000a, 0x00700000, ++ 0x00106001, 0x00700083, 0x00910880, 0x00901ffe, 0x01940000, 0x00200020, ++ 0x0060000b, 0x00500069, 0x0060000c, 0x00401b68, 0x0040ae06, 0x0040af05, ++ 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 ++}; ++ ++static uint32_t nv4c_ctxprog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409065, 0x00409406, ++ 0x0040a168, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, ++ 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, 0x00401826, 0x00401968, ++ 0x0060000d, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004020e6, 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, ++ 0x0010427e, 0x001046ec, 0x00500060, 0x00404187, 0x0060000d, 0x00407ae6, ++ 0x002000f2, 0x0060000a, 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, ++ 0x0011068b, 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, ++ 0x001146c6, 0x00200020, 0x001006cc, 0x001046ed, 0x001246f0, 0x002000c0, ++ 0x00100700, 0x0010c3d7, 0x001043e1, 0x00500060, 0x00200234, 0x0060000a, ++ 0x00104800, 0x00108901, 0x00104910, 0x00124920, 0x0020001f, 0x00100940, ++ 0x00140965, 0x00148a00, 0x00108a14, 0x00140b00, 0x00134b2c, 0x0010cd00, ++ 0x0010cd04, 0x00104d08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, ++ 0x00104f06, 0x002002c0, 0x0060000a, 0x00300000, 0x00200080, 0x00407300, ++ 0x00200084, 0x00800001, 0x00200508, 0x0060000a, 0x00201320, 0x0040798a, ++ 0xfffffaf8, 0x00800029, 0x00408a00, 0x00600006, 0x004086e6, 0x00700080, ++ 0x0020007a, 0x0060000a, 0x00104280, 0x002002c0, 0x0060000a, 0x00200004, ++ 0x00800001, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a168, ++ 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x00700080, 0x00400a68, ++ 0x00500060, 0x00600007, 0x00409488, 0x0060000f, 0x00500060, 0x00200000, ++ 0x0060000a, 0x00700000, 0x00106001, 0x00910880, 0x00901ffe, 0x01940000, ++ 0x00200020, 0x0060000b, 0x00500069, 0x0060000c, 0x00402168, 0x0040a306, ++ 0x0040a405, 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 ++}; ++ ++static uint32_t nv4e_ctxprog[] = { ++ 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, ++ 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409565, 0x00409a06, ++ 0x0040a868, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, ++ 0x004014e6, 0x007000a0, 0x00401a84, 0x00700082, 0x00600001, 0x00500061, ++ 0x00600002, 0x00401b68, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, ++ 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, ++ 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, ++ 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, ++ 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, ++ 0x001046ec, 0x00500060, 0x00403a87, 0x0060000d, 0x00407ce6, 0x002000f1, ++ 0x0060000a, 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, 0x0011068b, ++ 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, ++ 0x001646cc, 0x001186e6, 0x001046ed, 0x001246f0, 0x002000c0, 0x00100700, ++ 0x0010c3d7, 0x001043e1, 0x00500060, 0x00405800, 0x00405884, 0x00600003, ++ 0x00500067, 0x00600008, 0x00500060, 0x00700082, 0x00200232, 0x0060000a, ++ 0x00104800, 0x00108901, 0x00104910, 0x00124920, 0x0020001f, 0x00100940, ++ 0x00140965, 0x00148a00, 0x00108a14, 0x00140b00, 0x00134b2c, 0x0010cd00, ++ 0x0010cd04, 0x00104d08, 0x00104d80, 0x00104e00, 0x00105c00, 0x00104f06, ++ 0x002002b2, 0x0060000a, 0x00300000, 0x00200080, 0x00407200, 0x00200084, ++ 0x00800001, 0x002004fa, 0x0060000a, 0x00201320, 0x0040788a, 0xfffffb06, ++ 0x00800029, 0x00407c84, 0x00200b20, 0x00800002, 0x00408d00, 0x00600006, ++ 0x00700003, 0x004086e6, 0x00700080, 0x002002b2, 0x0060000a, 0x00200004, ++ 0x00800001, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a884, ++ 0x00700002, 0x00600004, 0x0040a868, 0x00700000, 0x00200000, 0x0060000a, ++ 0x00106002, 0x00700080, 0x00400a84, 0x00700002, 0x00400a68, 0x00500060, ++ 0x00600007, 0x00409988, 0x0060000f, 0x00000000, 0x00500060, 0x00200000, ++ 0x0060000a, 0x00700000, 0x00106001, 0x00700083, 0x00910880, 0x00901ffe, ++ 0x01940000, 0x00200020, 0x0060000b, 0x00500069, 0x0060000c, 0x00401b68, ++ 0x0040aa06, 0x0040ab05, 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ++ ~0 ++}; ++ ++/* ++ * G70 0x47 ++ * G71 0x49 ++ * NV45 0x48 ++ * G72[M] 0x46 ++ * G73 0x4b ++ * C51_G7X 0x4c ++ * C51 0x4e ++ */ ++int ++nv40_graph_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = ++ (struct drm_nouveau_private *)dev->dev_private; ++ uint32_t *ctxprog = NULL; ++ uint32_t vramsz, tmp; ++ int i, j; ++ ++ nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ++ ~NV_PMC_ENABLE_PGRAPH); ++ nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | ++ NV_PMC_ENABLE_PGRAPH); ++ ++ switch (dev_priv->chipset) { ++ case 0x40: ++ ctxprog = nv40_ctxprog; ++ break; ++ case 0x41: ++ case 0x42: ++ ctxprog = nv41_ctxprog; ++ break; ++ case 0x43: ++ ctxprog = nv43_ctxprog; ++ break; ++ case 0x44: ++ ctxprog = nv44_ctxprog; ++ break; ++ case 0x46: ++ ctxprog = nv46_ctxprog; ++ break; ++ case 0x47: ++ ctxprog = nv47_ctxprog; ++ break; ++ case 0x49: ++ ctxprog = nv49_4b_ctxprog; ++ break; ++ case 0x4a: ++ ctxprog = nv4a_ctxprog; ++ break; ++ case 0x4b: ++ ctxprog = nv49_4b_ctxprog; ++ break; ++ case 0x4c: ++ case 0x67: ++ ctxprog = nv4c_ctxprog; ++ break; ++ case 0x4e: ++ ctxprog = nv4e_ctxprog; ++ break; ++ default: ++ NV_ERROR(dev, "Context program for 0x%02x unavailable\n", ++ dev_priv->chipset); ++ dev_priv->engine.graph.accel_blocked = true; ++ break; ++ } ++ ++ /* Load the context program onto the card */ ++ if (ctxprog) { ++ NV_DEBUG(dev, "Loading context program\n"); ++ ++ i = 0; ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); ++ while (ctxprog[i] != ~0) { ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, ctxprog[i]); ++ i++; ++ } ++ } ++ ++ /* No context present currently */ ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); ++ ++ nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); ++ nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xFFFFFFFF); ++ ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000); ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x401287c0); ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xe0de8055); ++ nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00008000); ++ nv_wr32(dev, NV04_PGRAPH_LIMIT_VIOL_PIX, 0x00be3c5f); ++ ++ nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100); ++ nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); ++ ++ j = nv_rd32(dev, 0x1540) & 0xff; ++ if (j) { ++ for (i = 0; !(j & 1); j >>= 1, i++) ++ ; ++ nv_wr32(dev, 0x405000, i); ++ } ++ ++ if (dev_priv->chipset == 0x40) { ++ nv_wr32(dev, 0x4009b0, 0x83280fff); ++ nv_wr32(dev, 0x4009b4, 0x000000a0); ++ } else { ++ nv_wr32(dev, 0x400820, 0x83280eff); ++ nv_wr32(dev, 0x400824, 0x000000a0); ++ } ++ ++ switch (dev_priv->chipset) { ++ case 0x40: ++ case 0x45: ++ nv_wr32(dev, 0x4009b8, 0x0078e366); ++ nv_wr32(dev, 0x4009bc, 0x0000014c); ++ break; ++ case 0x41: ++ case 0x42: /* pciid also 0x00Cx */ ++ /* case 0x0120: XXX (pciid) */ ++ nv_wr32(dev, 0x400828, 0x007596ff); ++ nv_wr32(dev, 0x40082c, 0x00000108); ++ break; ++ case 0x43: ++ nv_wr32(dev, 0x400828, 0x0072cb77); ++ nv_wr32(dev, 0x40082c, 0x00000108); ++ break; ++ case 0x44: ++ case 0x46: /* G72 */ ++ case 0x4a: ++ case 0x4c: /* G7x-based C51 */ ++ case 0x4e: ++ nv_wr32(dev, 0x400860, 0); ++ nv_wr32(dev, 0x400864, 0); ++ break; ++ case 0x47: /* G70 */ ++ case 0x49: /* G71 */ ++ case 0x4b: /* G73 */ ++ nv_wr32(dev, 0x400828, 0x07830610); ++ nv_wr32(dev, 0x40082c, 0x0000016A); ++ break; ++ default: ++ break; ++ } ++ ++ nv_wr32(dev, 0x400b38, 0x2ffff800); ++ nv_wr32(dev, 0x400b3c, 0x00006000); ++ ++ /* copy tile info from PFB */ ++ switch (dev_priv->chipset) { ++ case 0x40: /* vanilla NV40 */ ++ for (i = 0; i < NV10_PFB_TILE__SIZE; i++) { ++ tmp = nv_rd32(dev, NV10_PFB_TILE(i)); ++ nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp); ++ nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp); ++ tmp = nv_rd32(dev, NV10_PFB_TLIMIT(i)); ++ nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp); ++ nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp); ++ tmp = nv_rd32(dev, NV10_PFB_TSIZE(i)); ++ nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp); ++ nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp); ++ tmp = nv_rd32(dev, NV10_PFB_TSTATUS(i)); ++ nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp); ++ nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp); ++ } ++ break; ++ case 0x44: ++ case 0x4a: ++ case 0x4e: /* NV44-based cores don't have 0x406900? */ ++ for (i = 0; i < NV40_PFB_TILE__SIZE_0; i++) { ++ tmp = nv_rd32(dev, NV40_PFB_TILE(i)); ++ nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp); ++ tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i)); ++ nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp); ++ tmp = nv_rd32(dev, NV40_PFB_TSIZE(i)); ++ nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp); ++ tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i)); ++ nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp); ++ } ++ break; ++ case 0x46: ++ case 0x47: ++ case 0x49: ++ case 0x4b: /* G7X-based cores */ ++ for (i = 0; i < NV40_PFB_TILE__SIZE_1; i++) { ++ tmp = nv_rd32(dev, NV40_PFB_TILE(i)); ++ nv_wr32(dev, NV47_PGRAPH_TILE0(i), tmp); ++ nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp); ++ tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i)); ++ nv_wr32(dev, NV47_PGRAPH_TLIMIT0(i), tmp); ++ nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp); ++ tmp = nv_rd32(dev, NV40_PFB_TSIZE(i)); ++ nv_wr32(dev, NV47_PGRAPH_TSIZE0(i), tmp); ++ nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp); ++ tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i)); ++ nv_wr32(dev, NV47_PGRAPH_TSTATUS0(i), tmp); ++ nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp); ++ } ++ break; ++ default: /* everything else */ ++ for (i = 0; i < NV40_PFB_TILE__SIZE_0; i++) { ++ tmp = nv_rd32(dev, NV40_PFB_TILE(i)); ++ nv_wr32(dev, NV40_PGRAPH_TILE0(i), tmp); ++ nv_wr32(dev, NV40_PGRAPH_TILE1(i), tmp); ++ tmp = nv_rd32(dev, NV40_PFB_TLIMIT(i)); ++ nv_wr32(dev, NV40_PGRAPH_TLIMIT0(i), tmp); ++ nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tmp); ++ tmp = nv_rd32(dev, NV40_PFB_TSIZE(i)); ++ nv_wr32(dev, NV40_PGRAPH_TSIZE0(i), tmp); ++ nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tmp); ++ tmp = nv_rd32(dev, NV40_PFB_TSTATUS(i)); ++ nv_wr32(dev, NV40_PGRAPH_TSTATUS0(i), tmp); ++ nv_wr32(dev, NV40_PGRAPH_TSTATUS1(i), tmp); ++ } ++ break; ++ } ++ ++ /* begin RAM config */ ++ vramsz = drm_get_resource_len(dev, 0) - 1; ++ switch (dev_priv->chipset) { ++ case 0x40: ++ nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); ++ nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1)); ++ nv_wr32(dev, 0x4069A4, nv_rd32(dev, NV04_PFB_CFG0)); ++ nv_wr32(dev, 0x4069A8, nv_rd32(dev, NV04_PFB_CFG1)); ++ nv_wr32(dev, 0x400820, 0); ++ nv_wr32(dev, 0x400824, 0); ++ nv_wr32(dev, 0x400864, vramsz); ++ nv_wr32(dev, 0x400868, vramsz); ++ break; ++ default: ++ switch (dev_priv->chipset) { ++ case 0x46: ++ case 0x47: ++ case 0x49: ++ case 0x4b: ++ nv_wr32(dev, 0x400DF0, nv_rd32(dev, NV04_PFB_CFG0)); ++ nv_wr32(dev, 0x400DF4, nv_rd32(dev, NV04_PFB_CFG1)); ++ break; ++ default: ++ nv_wr32(dev, 0x4009F0, nv_rd32(dev, NV04_PFB_CFG0)); ++ nv_wr32(dev, 0x4009F4, nv_rd32(dev, NV04_PFB_CFG1)); ++ break; ++ } ++ nv_wr32(dev, 0x4069F0, nv_rd32(dev, NV04_PFB_CFG0)); ++ nv_wr32(dev, 0x4069F4, nv_rd32(dev, NV04_PFB_CFG1)); ++ nv_wr32(dev, 0x400840, 0); ++ nv_wr32(dev, 0x400844, 0); ++ nv_wr32(dev, 0x4008A0, vramsz); ++ nv_wr32(dev, 0x4008A4, vramsz); ++ break; ++ } ++ ++ return 0; ++} ++ ++void nv40_graph_takedown(struct drm_device *dev) ++{ ++} ++ ++struct nouveau_pgraph_object_class nv40_graph_grclass[] = { ++ { 0x0030, false, NULL }, /* null */ ++ { 0x0039, false, NULL }, /* m2mf */ ++ { 0x004a, false, NULL }, /* gdirect */ ++ { 0x009f, false, NULL }, /* imageblit (nv12) */ ++ { 0x008a, false, NULL }, /* ifc */ ++ { 0x0089, false, NULL }, /* sifm */ ++ { 0x3089, false, NULL }, /* sifm (nv40) */ ++ { 0x0062, false, NULL }, /* surf2d */ ++ { 0x0043, false, NULL }, /* rop */ ++ { 0x0012, false, NULL }, /* beta1 */ ++ { 0x0072, false, NULL }, /* beta4 */ ++ { 0x0019, false, NULL }, /* cliprect */ ++ { 0x0044, false, NULL }, /* pattern */ ++ { 0x309e, false, NULL }, /* swzsurf */ ++ { 0x4097, false, NULL }, /* curie (nv40) */ ++ { 0x4497, false, NULL }, /* curie (nv44) */ ++ {} ++}; ++ +diff --git a/drivers/gpu/drm/nouveau/nv40_mc.c b/drivers/gpu/drm/nouveau/nv40_mc.c +new file mode 100644 +index 0000000..2a3495e +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv40_mc.c +@@ -0,0 +1,38 @@ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++int ++nv40_mc_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t tmp; ++ ++ /* Power up everything, resetting each individual unit will ++ * be done later if needed. ++ */ ++ nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); ++ ++ switch (dev_priv->chipset) { ++ case 0x44: ++ case 0x46: /* G72 */ ++ case 0x4e: ++ case 0x4c: /* C51_G7X */ ++ tmp = nv_rd32(dev, NV40_PFB_020C); ++ nv_wr32(dev, NV40_PMC_1700, tmp); ++ nv_wr32(dev, NV40_PMC_1704, 0); ++ nv_wr32(dev, NV40_PMC_1708, 0); ++ nv_wr32(dev, NV40_PMC_170C, tmp); ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++void ++nv40_mc_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c +new file mode 100644 +index 0000000..768fb4f +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_crtc.c +@@ -0,0 +1,788 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm_mode.h" ++#include "drm_crtc_helper.h" ++ ++#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) ++#include "nouveau_reg.h" ++#include "nouveau_drv.h" ++#include "nouveau_hw.h" ++#include "nouveau_encoder.h" ++#include "nouveau_crtc.h" ++#include "nouveau_fb.h" ++#include "nouveau_connector.h" ++#include "nv50_display.h" ++ ++static void ++nv50_crtc_lut_load(struct drm_crtc *crtc) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo); ++ int i; ++ ++ NV_DEBUG(crtc->dev, "\n"); ++ ++ for (i = 0; i < 256; i++) { ++ writew(nv_crtc->lut.r[i] >> 2, lut + 8*i + 0); ++ writew(nv_crtc->lut.g[i] >> 2, lut + 8*i + 2); ++ writew(nv_crtc->lut.b[i] >> 2, lut + 8*i + 4); ++ } ++ ++ if (nv_crtc->lut.depth == 30) { ++ writew(nv_crtc->lut.r[i - 1] >> 2, lut + 8*i + 0); ++ writew(nv_crtc->lut.g[i - 1] >> 2, lut + 8*i + 2); ++ writew(nv_crtc->lut.b[i - 1] >> 2, lut + 8*i + 4); ++ } ++} ++ ++int ++nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked) ++{ ++ struct drm_device *dev = nv_crtc->base.dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *evo = dev_priv->evo; ++ int index = nv_crtc->index, ret; ++ ++ NV_DEBUG(dev, "index %d\n", nv_crtc->index); ++ NV_DEBUG(dev, "%s\n", blanked ? "blanked" : "unblanked"); ++ ++ if (blanked) { ++ nv_crtc->cursor.hide(nv_crtc, false); ++ ++ ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 7 : 5); ++ if (ret) { ++ NV_ERROR(dev, "no space while blanking crtc\n"); ++ return ret; ++ } ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2); ++ OUT_RING(evo, NV50_EVO_CRTC_CLUT_MODE_BLANK); ++ OUT_RING(evo, 0); ++ if (dev_priv->chipset != 0x50) { ++ BEGIN_RING(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1); ++ OUT_RING(evo, NV84_EVO_CRTC_CLUT_DMA_HANDLE_NONE); ++ } ++ ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1); ++ OUT_RING(evo, NV50_EVO_CRTC_FB_DMA_HANDLE_NONE); ++ } else { ++ nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset); ++ if (nv_crtc->cursor.visible) ++ nv_crtc->cursor.show(nv_crtc, false); ++ else ++ nv_crtc->cursor.hide(nv_crtc, false); ++ ++ ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 10 : 8); ++ if (ret) { ++ NV_ERROR(dev, "no space while unblanking crtc\n"); ++ return ret; ++ } ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2); ++ OUT_RING(evo, nv_crtc->lut.depth == 8 ? ++ NV50_EVO_CRTC_CLUT_MODE_OFF : ++ NV50_EVO_CRTC_CLUT_MODE_ON); ++ OUT_RING(evo, (nv_crtc->lut.nvbo->bo.mem.mm_node->start << ++ PAGE_SHIFT) >> 8); ++ if (dev_priv->chipset != 0x50) { ++ BEGIN_RING(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1); ++ OUT_RING(evo, NvEvoVRAM); ++ } ++ ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_OFFSET), 2); ++ OUT_RING(evo, nv_crtc->fb.offset >> 8); ++ OUT_RING(evo, 0); ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1); ++ if (dev_priv->chipset != 0x50) ++ if (nv_crtc->fb.tile_flags == 0x7a00) ++ OUT_RING(evo, NvEvoFB32); ++ else ++ if (nv_crtc->fb.tile_flags == 0x7000) ++ OUT_RING(evo, NvEvoFB16); ++ else ++ OUT_RING(evo, NvEvoVRAM); ++ else ++ OUT_RING(evo, NvEvoVRAM); ++ } ++ ++ nv_crtc->fb.blanked = blanked; ++ return 0; ++} ++ ++static int ++nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool on, bool update) ++{ ++ struct drm_device *dev = nv_crtc->base.dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *evo = dev_priv->evo; ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ ret = RING_SPACE(evo, 2 + (update ? 2 : 0)); ++ if (ret) { ++ NV_ERROR(dev, "no space while setting dither\n"); ++ return ret; ++ } ++ ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, DITHER_CTRL), 1); ++ if (on) ++ OUT_RING(evo, NV50_EVO_CRTC_DITHER_CTRL_ON); ++ else ++ OUT_RING(evo, NV50_EVO_CRTC_DITHER_CTRL_OFF); ++ ++ if (update) { ++ BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); ++ OUT_RING(evo, 0); ++ FIRE_RING(evo); ++ } ++ ++ return 0; ++} ++ ++struct nouveau_connector * ++nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc) ++{ ++ struct drm_device *dev = nv_crtc->base.dev; ++ struct drm_connector *connector; ++ struct drm_crtc *crtc = to_drm_crtc(nv_crtc); ++ ++ /* The safest approach is to find an encoder with the right crtc, that ++ * is also linked to a connector. */ ++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { ++ if (connector->encoder) ++ if (connector->encoder->crtc == crtc) ++ return nouveau_connector(connector); ++ } ++ ++ return NULL; ++} ++ ++static int ++nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update) ++{ ++ struct nouveau_connector *nv_connector = ++ nouveau_crtc_connector_get(nv_crtc); ++ struct drm_device *dev = nv_crtc->base.dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *evo = dev_priv->evo; ++ struct drm_display_mode *native_mode = NULL; ++ struct drm_display_mode *mode = &nv_crtc->base.mode; ++ uint32_t outX, outY, horiz, vert; ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ switch (scaling_mode) { ++ case DRM_MODE_SCALE_NONE: ++ break; ++ default: ++ if (!nv_connector || !nv_connector->native_mode) { ++ NV_ERROR(dev, "No native mode, forcing panel scaling\n"); ++ scaling_mode = DRM_MODE_SCALE_NONE; ++ } else { ++ native_mode = nv_connector->native_mode; ++ } ++ break; ++ } ++ ++ switch (scaling_mode) { ++ case DRM_MODE_SCALE_ASPECT: ++ horiz = (native_mode->hdisplay << 19) / mode->hdisplay; ++ vert = (native_mode->vdisplay << 19) / mode->vdisplay; ++ ++ if (vert > horiz) { ++ outX = (mode->hdisplay * horiz) >> 19; ++ outY = (mode->vdisplay * horiz) >> 19; ++ } else { ++ outX = (mode->hdisplay * vert) >> 19; ++ outY = (mode->vdisplay * vert) >> 19; ++ } ++ break; ++ case DRM_MODE_SCALE_FULLSCREEN: ++ outX = native_mode->hdisplay; ++ outY = native_mode->vdisplay; ++ break; ++ case DRM_MODE_SCALE_CENTER: ++ case DRM_MODE_SCALE_NONE: ++ default: ++ outX = mode->hdisplay; ++ outY = mode->vdisplay; ++ break; ++ } ++ ++ ret = RING_SPACE(evo, update ? 7 : 5); ++ if (ret) ++ return ret; ++ ++ /* Got a better name for SCALER_ACTIVE? */ ++ /* One day i've got to really figure out why this is needed. */ ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_CTRL), 1); ++ if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) || ++ (mode->flags & DRM_MODE_FLAG_INTERLACE) || ++ mode->hdisplay != outX || mode->vdisplay != outY) { ++ OUT_RING(evo, NV50_EVO_CRTC_SCALE_CTRL_ACTIVE); ++ } else { ++ OUT_RING(evo, NV50_EVO_CRTC_SCALE_CTRL_INACTIVE); ++ } ++ ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_RES1), 2); ++ OUT_RING(evo, outY << 16 | outX); ++ OUT_RING(evo, outY << 16 | outX); ++ ++ if (update) { ++ BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); ++ OUT_RING(evo, 0); ++ FIRE_RING(evo); ++ } ++ ++ return 0; ++} ++ ++int ++nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk) ++{ ++ uint32_t pll_reg = NV50_PDISPLAY_CRTC_CLK_CTRL1(head); ++ struct nouveau_pll_vals pll; ++ struct pll_lims limits; ++ uint32_t reg1, reg2; ++ int ret; ++ ++ ret = get_pll_limits(dev, pll_reg, &limits); ++ if (ret) ++ return ret; ++ ++ /*XXX: need a vbios image from one of these cards to look at ++ * rather than just guessing. P isn't log2P on these ++ * cards, it's uncertain at this stage what the PLL ++ * limits tables have to say about these chips. ++ * ++ * getPLL_single will need some modifications to calculate ++ * this properly too. ++ * ++ * for the moment, hacking up the PLL limits table with ++ * a log2 value matching nv's maximum. ++ */ ++ if (!limits.vco2.maxfreq) { ++ NV_ERROR(dev, "single-stage PLL, please report: %d!!\n", ++ limits.max_usable_log2p); ++ limits.max_usable_log2p = 6; ++ } ++ ++ ret = nouveau_calc_pll_mnp(dev, &limits, pclk, &pll); ++ if (ret <= 0) ++ return ret; ++ ++ if (limits.vco2.maxfreq) { ++ reg1 = nv_rd32(dev, pll_reg + 4) & 0xff00ff00; ++ reg2 = nv_rd32(dev, pll_reg + 8) & 0x8000ff00; ++ nv_wr32(dev, pll_reg, 0x10000611); ++ nv_wr32(dev, pll_reg + 4, reg1 | (pll.M1 << 16) | pll.N1); ++ nv_wr32(dev, pll_reg + 8, ++ reg2 | (pll.log2P << 28) | (pll.M2 << 16) | pll.N2); ++ } else { ++ reg1 = nv_rd32(dev, pll_reg + 4) & 0xffc00000; ++ nv_wr32(dev, pll_reg, 0x50000610); ++ nv_wr32(dev, pll_reg + 4, reg1 | ++ (((1<dev; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (!crtc) ++ return; ++ ++ drm_crtc_cleanup(&nv_crtc->base); ++ ++ nv50_cursor_fini(nv_crtc); ++ ++ nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo); ++ nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); ++ kfree(nv_crtc->mode); ++ kfree(nv_crtc); ++} ++ ++int ++nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, ++ uint32_t buffer_handle, uint32_t width, uint32_t height) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct nouveau_bo *cursor = NULL; ++ struct drm_gem_object *gem; ++ int ret = 0, i; ++ ++ if (width != 64 || height != 64) ++ return -EINVAL; ++ ++ if (!buffer_handle) { ++ nv_crtc->cursor.hide(nv_crtc, true); ++ return 0; ++ } ++ ++ gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); ++ if (!gem) ++ return -EINVAL; ++ cursor = nouveau_gem_object(gem); ++ ++ ret = nouveau_bo_map(cursor); ++ if (ret) ++ goto out; ++ ++ /* The simple will do for now. */ ++ for (i = 0; i < 64 * 64; i++) ++ nouveau_bo_wr32(nv_crtc->cursor.nvbo, i, nouveau_bo_rd32(cursor, i)); ++ ++ nouveau_bo_unmap(cursor); ++ ++ nv_crtc->cursor.offset = nv_crtc->cursor.nvbo->bo.offset; ++ nv_crtc->cursor.offset -= dev_priv->vm_vram_base; ++ nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset); ++ nv_crtc->cursor.show(nv_crtc, true); ++ ++out: ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(gem); ++ mutex_unlock(&dev->struct_mutex); ++ return ret; ++} ++ ++int ++nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ ++ nv_crtc->cursor.set_pos(nv_crtc, x, y); ++ return 0; ++} ++ ++static void ++nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, ++ uint32_t size) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ int i; ++ ++ if (size != 256) ++ return; ++ ++ for (i = 0; i < 256; i++) { ++ nv_crtc->lut.r[i] = r[i]; ++ nv_crtc->lut.g[i] = g[i]; ++ nv_crtc->lut.b[i] = b[i]; ++ } ++ ++ /* We need to know the depth before we upload, but it's possible to ++ * get called before a framebuffer is bound. If this is the case, ++ * mark the lut values as dirty by setting depth==0, and it'll be ++ * uploaded on the first mode_set_base() ++ */ ++ if (!nv_crtc->base.fb) { ++ nv_crtc->lut.depth = 0; ++ return; ++ } ++ ++ nv50_crtc_lut_load(crtc); ++} ++ ++static void ++nv50_crtc_save(struct drm_crtc *crtc) ++{ ++ NV_ERROR(crtc->dev, "!!\n"); ++} ++ ++static void ++nv50_crtc_restore(struct drm_crtc *crtc) ++{ ++ NV_ERROR(crtc->dev, "!!\n"); ++} ++ ++static const struct drm_crtc_funcs nv50_crtc_funcs = { ++ .save = nv50_crtc_save, ++ .restore = nv50_crtc_restore, ++ .cursor_set = nv50_crtc_cursor_set, ++ .cursor_move = nv50_crtc_cursor_move, ++ .gamma_set = nv50_crtc_gamma_set, ++ .set_config = drm_crtc_helper_set_config, ++ .destroy = nv50_crtc_destroy, ++}; ++ ++static void ++nv50_crtc_dpms(struct drm_crtc *crtc, int mode) ++{ ++} ++ ++static void ++nv50_crtc_prepare(struct drm_crtc *crtc) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ struct drm_encoder *encoder; ++ ++ NV_DEBUG(dev, "index %d\n", nv_crtc->index); ++ ++ /* Disconnect all unused encoders. */ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ ++ if (drm_helper_encoder_in_use(encoder)) ++ continue; ++ ++ nv_encoder->disconnect(nv_encoder); ++ } ++ ++ nv50_crtc_blank(nv_crtc, true); ++} ++ ++static void ++nv50_crtc_commit(struct drm_crtc *crtc) ++{ ++ struct drm_crtc *crtc2; ++ struct drm_device *dev = crtc->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *evo = dev_priv->evo; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ int ret; ++ ++ NV_DEBUG(dev, "index %d\n", nv_crtc->index); ++ ++ nv50_crtc_blank(nv_crtc, false); ++ ++ /* Explicitly blank all unused crtc's. */ ++ list_for_each_entry(crtc2, &dev->mode_config.crtc_list, head) { ++ if (!drm_helper_crtc_in_use(crtc2)) ++ nv50_crtc_blank(nouveau_crtc(crtc2), true); ++ } ++ ++ ret = RING_SPACE(evo, 2); ++ if (ret) { ++ NV_ERROR(dev, "no space while committing crtc\n"); ++ return; ++ } ++ BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); ++ OUT_RING(evo, 0); ++ FIRE_RING(evo); ++} ++ ++static bool ++nv50_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ return true; ++} ++ ++static int ++nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y, ++ struct drm_framebuffer *old_fb, bool update) ++{ ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct drm_device *dev = nv_crtc->base.dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *evo = dev_priv->evo; ++ struct drm_framebuffer *drm_fb = nv_crtc->base.fb; ++ struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); ++ int ret, format; ++ ++ NV_DEBUG(dev, "index %d\n", nv_crtc->index); ++ ++ switch (drm_fb->depth) { ++ case 8: ++ format = NV50_EVO_CRTC_FB_DEPTH_8; ++ break; ++ case 15: ++ format = NV50_EVO_CRTC_FB_DEPTH_15; ++ break; ++ case 16: ++ format = NV50_EVO_CRTC_FB_DEPTH_16; ++ break; ++ case 24: ++ case 32: ++ format = NV50_EVO_CRTC_FB_DEPTH_24; ++ break; ++ case 30: ++ format = NV50_EVO_CRTC_FB_DEPTH_30; ++ break; ++ default: ++ NV_ERROR(dev, "unknown depth %d\n", drm_fb->depth); ++ return -EINVAL; ++ } ++ ++ ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM); ++ if (ret) ++ return ret; ++ ++ if (old_fb) { ++ struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb); ++ nouveau_bo_unpin(ofb->nvbo); ++ } ++ ++ nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base; ++ nv_crtc->fb.tile_flags = fb->nvbo->tile_flags; ++ nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; ++ if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) { ++ ret = RING_SPACE(evo, 2); ++ if (ret) ++ return ret; ++ ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1); ++ if (nv_crtc->fb.tile_flags == 0x7a00) ++ OUT_RING(evo, NvEvoFB32); ++ else ++ if (nv_crtc->fb.tile_flags == 0x7000) ++ OUT_RING(evo, NvEvoFB16); ++ else ++ OUT_RING(evo, NvEvoVRAM); ++ } ++ ++ ret = RING_SPACE(evo, 12); ++ if (ret) ++ return ret; ++ ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5); ++ OUT_RING(evo, nv_crtc->fb.offset >> 8); ++ OUT_RING(evo, 0); ++ OUT_RING(evo, (drm_fb->height << 16) | drm_fb->width); ++ if (!nv_crtc->fb.tile_flags) { ++ OUT_RING(evo, drm_fb->pitch | (1 << 20)); ++ } else { ++ OUT_RING(evo, ((drm_fb->pitch / 4) << 4) | ++ fb->nvbo->tile_mode); ++ } ++ if (dev_priv->chipset == 0x50) ++ OUT_RING(evo, (fb->nvbo->tile_flags << 8) | format); ++ else ++ OUT_RING(evo, format); ++ ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1); ++ OUT_RING(evo, fb->base.depth == 8 ? ++ NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON); ++ ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1); ++ OUT_RING(evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR); ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1); ++ OUT_RING(evo, (y << 16) | x); ++ ++ if (nv_crtc->lut.depth != fb->base.depth) { ++ nv_crtc->lut.depth = fb->base.depth; ++ nv50_crtc_lut_load(crtc); ++ } ++ ++ if (update) { ++ ret = RING_SPACE(evo, 2); ++ if (ret) ++ return ret; ++ BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); ++ OUT_RING(evo, 0); ++ FIRE_RING(evo); ++ } ++ ++ return 0; ++} ++ ++static int ++nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode, int x, int y, ++ struct drm_framebuffer *old_fb) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *evo = dev_priv->evo; ++ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ++ struct nouveau_connector *nv_connector = NULL; ++ uint32_t hsync_dur, vsync_dur, hsync_start_to_end, vsync_start_to_end; ++ uint32_t hunk1, vunk1, vunk2a, vunk2b; ++ int ret; ++ ++ /* Find the connector attached to this CRTC */ ++ nv_connector = nouveau_crtc_connector_get(nv_crtc); ++ ++ *nv_crtc->mode = *adjusted_mode; ++ ++ NV_DEBUG(dev, "index %d\n", nv_crtc->index); ++ ++ hsync_dur = adjusted_mode->hsync_end - adjusted_mode->hsync_start; ++ vsync_dur = adjusted_mode->vsync_end - adjusted_mode->vsync_start; ++ hsync_start_to_end = adjusted_mode->htotal - adjusted_mode->hsync_start; ++ vsync_start_to_end = adjusted_mode->vtotal - adjusted_mode->vsync_start; ++ /* I can't give this a proper name, anyone else can? */ ++ hunk1 = adjusted_mode->htotal - ++ adjusted_mode->hsync_start + adjusted_mode->hdisplay; ++ vunk1 = adjusted_mode->vtotal - ++ adjusted_mode->vsync_start + adjusted_mode->vdisplay; ++ /* Another strange value, this time only for interlaced adjusted_modes. */ ++ vunk2a = 2 * adjusted_mode->vtotal - ++ adjusted_mode->vsync_start + adjusted_mode->vdisplay; ++ vunk2b = adjusted_mode->vtotal - ++ adjusted_mode->vsync_start + adjusted_mode->vtotal; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { ++ vsync_dur /= 2; ++ vsync_start_to_end /= 2; ++ vunk1 /= 2; ++ vunk2a /= 2; ++ vunk2b /= 2; ++ /* magic */ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) { ++ vsync_start_to_end -= 1; ++ vunk1 -= 1; ++ vunk2a -= 1; ++ vunk2b -= 1; ++ } ++ } ++ ++ ret = RING_SPACE(evo, 17); ++ if (ret) ++ return ret; ++ ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLOCK), 2); ++ OUT_RING(evo, adjusted_mode->clock | 0x800000); ++ OUT_RING(evo, (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ? 2 : 0); ++ ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, DISPLAY_START), 5); ++ OUT_RING(evo, 0); ++ OUT_RING(evo, (adjusted_mode->vtotal << 16) | adjusted_mode->htotal); ++ OUT_RING(evo, (vsync_dur - 1) << 16 | (hsync_dur - 1)); ++ OUT_RING(evo, (vsync_start_to_end - 1) << 16 | ++ (hsync_start_to_end - 1)); ++ OUT_RING(evo, (vunk1 - 1) << 16 | (hunk1 - 1)); ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, UNK0824), 1); ++ OUT_RING(evo, (vunk2b - 1) << 16 | (vunk2a - 1)); ++ } else { ++ OUT_RING(evo, 0); ++ OUT_RING(evo, 0); ++ } ++ ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, UNK082C), 1); ++ OUT_RING(evo, 0); ++ ++ /* This is the actual resolution of the mode. */ ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, REAL_RES), 1); ++ OUT_RING(evo, (mode->vdisplay << 16) | mode->hdisplay); ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_CENTER_OFFSET), 1); ++ OUT_RING(evo, NV50_EVO_CRTC_SCALE_CENTER_OFFSET_VAL(0, 0)); ++ ++ nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, false); ++ nv_crtc->set_scale(nv_crtc, nv_connector->scaling_mode, false); ++ ++ return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, false); ++} ++ ++static int ++nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, ++ struct drm_framebuffer *old_fb) ++{ ++ return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, true); ++} ++ ++static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = { ++ .dpms = nv50_crtc_dpms, ++ .prepare = nv50_crtc_prepare, ++ .commit = nv50_crtc_commit, ++ .mode_fixup = nv50_crtc_mode_fixup, ++ .mode_set = nv50_crtc_mode_set, ++ .mode_set_base = nv50_crtc_mode_set_base, ++ .load_lut = nv50_crtc_lut_load, ++}; ++ ++int ++nv50_crtc_create(struct drm_device *dev, int index) ++{ ++ struct nouveau_crtc *nv_crtc = NULL; ++ int ret, i; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL); ++ if (!nv_crtc) ++ return -ENOMEM; ++ ++ nv_crtc->mode = kzalloc(sizeof(*nv_crtc->mode), GFP_KERNEL); ++ if (!nv_crtc->mode) { ++ kfree(nv_crtc); ++ return -ENOMEM; ++ } ++ ++ /* Default CLUT parameters, will be activated on the hw upon ++ * first mode set. ++ */ ++ for (i = 0; i < 256; i++) { ++ nv_crtc->lut.r[i] = i << 8; ++ nv_crtc->lut.g[i] = i << 8; ++ nv_crtc->lut.b[i] = i << 8; ++ } ++ nv_crtc->lut.depth = 0; ++ ++ ret = nouveau_bo_new(dev, NULL, 4096, 0x100, TTM_PL_FLAG_VRAM, ++ 0, 0x0000, false, true, &nv_crtc->lut.nvbo); ++ if (!ret) { ++ ret = nouveau_bo_pin(nv_crtc->lut.nvbo, TTM_PL_FLAG_VRAM); ++ if (!ret) ++ ret = nouveau_bo_map(nv_crtc->lut.nvbo); ++ if (ret) ++ nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo); ++ } ++ ++ if (ret) { ++ kfree(nv_crtc->mode); ++ kfree(nv_crtc); ++ return ret; ++ } ++ ++ nv_crtc->index = index; ++ ++ /* set function pointers */ ++ nv_crtc->set_dither = nv50_crtc_set_dither; ++ nv_crtc->set_scale = nv50_crtc_set_scale; ++ ++ drm_crtc_init(dev, &nv_crtc->base, &nv50_crtc_funcs); ++ drm_crtc_helper_add(&nv_crtc->base, &nv50_crtc_helper_funcs); ++ drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256); ++ ++ ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM, ++ 0, 0x0000, false, true, &nv_crtc->cursor.nvbo); ++ if (!ret) { ++ ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); ++ if (!ret) ++ ret = nouveau_bo_map(nv_crtc->cursor.nvbo); ++ if (ret) ++ nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); ++ } ++ ++ nv50_cursor_init(nv_crtc); ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_cursor.c b/drivers/gpu/drm/nouveau/nv50_cursor.c +new file mode 100644 +index 0000000..aa7baad +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_cursor.c +@@ -0,0 +1,153 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm_mode.h" ++ ++#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) ++#include "nouveau_reg.h" ++#include "nouveau_drv.h" ++#include "nouveau_crtc.h" ++#include "nv50_display.h" ++ ++static void ++nv50_cursor_show(struct nouveau_crtc *crtc, bool update) ++{ ++ struct drm_nouveau_private *dev_priv = crtc->base.dev->dev_private; ++ struct nouveau_channel *evo = dev_priv->evo; ++ struct drm_device *dev = crtc->base.dev; ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ ret = RING_SPACE(evo, (dev_priv->chipset != 0x50 ? 4 : 2) + update * 2); ++ if (ret) { ++ NV_ERROR(dev, "no space while unhiding cursor\n"); ++ return; ++ } ++ ++ if (dev_priv->chipset != 0x50) { ++ BEGIN_RING(evo, 0, NV84_EVO_CRTC(crtc->index, CURSOR_DMA), 1); ++ OUT_RING(evo, NvEvoVRAM); ++ } ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(crtc->index, CURSOR_CTRL), 1); ++ OUT_RING(evo, NV50_EVO_CRTC_CURSOR_CTRL_SHOW); ++ ++ if (update) { ++ BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); ++ OUT_RING(evo, 0); ++ FIRE_RING(evo); ++ crtc->cursor.visible = true; ++ } ++} ++ ++static void ++nv50_cursor_hide(struct nouveau_crtc *crtc, bool update) ++{ ++ struct drm_nouveau_private *dev_priv = crtc->base.dev->dev_private; ++ struct nouveau_channel *evo = dev_priv->evo; ++ struct drm_device *dev = crtc->base.dev; ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ ret = RING_SPACE(evo, (dev_priv->chipset != 0x50 ? 4 : 2) + update * 2); ++ if (ret) { ++ NV_ERROR(dev, "no space while hiding cursor\n"); ++ return; ++ } ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(crtc->index, CURSOR_CTRL), 1); ++ OUT_RING(evo, NV50_EVO_CRTC_CURSOR_CTRL_HIDE); ++ if (dev_priv->chipset != 0x50) { ++ BEGIN_RING(evo, 0, NV84_EVO_CRTC(crtc->index, CURSOR_DMA), 1); ++ OUT_RING(evo, NV84_EVO_CRTC_CURSOR_DMA_HANDLE_NONE); ++ } ++ ++ if (update) { ++ BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); ++ OUT_RING(evo, 0); ++ FIRE_RING(evo); ++ crtc->cursor.visible = false; ++ } ++} ++ ++static void ++nv50_cursor_set_pos(struct nouveau_crtc *crtc, int x, int y) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ ++ nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS(crtc->index), ++ ((y & 0xFFFF) << 16) | (x & 0xFFFF)); ++ /* Needed to make the cursor move. */ ++ nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS_CTRL(crtc->index), 0); ++} ++ ++static void ++nv50_cursor_set_offset(struct nouveau_crtc *crtc, uint32_t offset) ++{ ++ struct drm_nouveau_private *dev_priv = crtc->base.dev->dev_private; ++ struct nouveau_channel *evo = dev_priv->evo; ++ struct drm_device *dev = crtc->base.dev; ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ ret = RING_SPACE(evo, 2); ++ if (ret) { ++ NV_ERROR(dev, "no space while setting cursor image\n"); ++ return; ++ } ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(crtc->index, CURSOR_OFFSET), 1); ++ OUT_RING(evo, offset >> 8); ++} ++ ++int ++nv50_cursor_init(struct nouveau_crtc *crtc) ++{ ++ crtc->cursor.set_offset = nv50_cursor_set_offset; ++ crtc->cursor.set_pos = nv50_cursor_set_pos; ++ crtc->cursor.hide = nv50_cursor_hide; ++ crtc->cursor.show = nv50_cursor_show; ++ return 0; ++} ++ ++void ++nv50_cursor_fini(struct nouveau_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->base.dev; ++ int idx = crtc->index; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0); ++ if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), ++ NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) { ++ NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n"); ++ NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n", ++ nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx))); ++ } ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c +new file mode 100644 +index 0000000..fb5838e +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_dac.c +@@ -0,0 +1,304 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm_crtc_helper.h" ++ ++#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) ++#include "nouveau_reg.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++#include "nouveau_encoder.h" ++#include "nouveau_connector.h" ++#include "nouveau_crtc.h" ++#include "nv50_display.h" ++ ++static void ++nv50_dac_disconnect(struct nouveau_encoder *nv_encoder) ++{ ++ struct drm_device *dev = to_drm_encoder(nv_encoder)->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *evo = dev_priv->evo; ++ int ret; ++ ++ NV_DEBUG(dev, "Disconnecting DAC %d\n", nv_encoder->or); ++ ++ ret = RING_SPACE(evo, 2); ++ if (ret) { ++ NV_ERROR(dev, "no space while disconnecting DAC\n"); ++ return; ++ } ++ BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1); ++ OUT_RING(evo, 0); ++} ++ ++static enum drm_connector_status ++nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ enum drm_connector_status status = connector_status_disconnected; ++ uint32_t dpms_state, load_pattern, load_state; ++ int or = nv_encoder->or; ++ ++ nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL1(or), 0x00000001); ++ dpms_state = nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)); ++ ++ nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), ++ 0x00150000 | NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); ++ if (!nv_wait(NV50_PDISPLAY_DAC_DPMS_CTRL(or), ++ NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) { ++ NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or); ++ NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or, ++ nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or))); ++ return status; ++ } ++ ++ /* Use bios provided value if possible. */ ++ if (dev_priv->vbios->dactestval) { ++ load_pattern = dev_priv->vbios->dactestval; ++ NV_DEBUG(dev, "Using bios provided load_pattern of %d\n", ++ load_pattern); ++ } else { ++ load_pattern = 340; ++ NV_DEBUG(dev, "Using default load_pattern of %d\n", ++ load_pattern); ++ } ++ ++ nv_wr32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or), ++ NV50_PDISPLAY_DAC_LOAD_CTRL_ACTIVE | load_pattern); ++ mdelay(45); /* give it some time to process */ ++ load_state = nv_rd32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or)); ++ ++ nv_wr32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or), 0); ++ nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), dpms_state | ++ NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); ++ ++ if ((load_state & NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) == ++ NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) ++ status = connector_status_connected; ++ ++ if (status == connector_status_connected) ++ NV_DEBUG(dev, "Load was detected on output with or %d\n", or); ++ else ++ NV_DEBUG(dev, "Load was not detected on output with or %d\n", or); ++ ++ return status; ++} ++ ++static void ++nv50_dac_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ uint32_t val; ++ int or = nv_encoder->or; ++ ++ NV_DEBUG(dev, "or %d mode %d\n", or, mode); ++ ++ /* wait for it to be done */ ++ if (!nv_wait(NV50_PDISPLAY_DAC_DPMS_CTRL(or), ++ NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) { ++ NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or); ++ NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or, ++ nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or))); ++ return; ++ } ++ ++ val = nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)) & ~0x7F; ++ ++ if (mode != DRM_MODE_DPMS_ON) ++ val |= NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED; ++ ++ switch (mode) { ++ case DRM_MODE_DPMS_STANDBY: ++ val |= NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF; ++ break; ++ case DRM_MODE_DPMS_SUSPEND: ++ val |= NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF; ++ break; ++ case DRM_MODE_DPMS_OFF: ++ val |= NV50_PDISPLAY_DAC_DPMS_CTRL_OFF; ++ val |= NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF; ++ val |= NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF; ++ break; ++ default: ++ break; ++ } ++ ++ nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), val | ++ NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); ++} ++ ++static void ++nv50_dac_save(struct drm_encoder *encoder) ++{ ++ NV_ERROR(encoder->dev, "!!\n"); ++} ++ ++static void ++nv50_dac_restore(struct drm_encoder *encoder) ++{ ++ NV_ERROR(encoder->dev, "!!\n"); ++} ++ ++static bool ++nv50_dac_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct nouveau_connector *connector; ++ ++ NV_DEBUG(encoder->dev, "or %d\n", nv_encoder->or); ++ ++ connector = nouveau_encoder_connector_get(nv_encoder); ++ if (!connector) { ++ NV_ERROR(encoder->dev, "Encoder has no connector\n"); ++ return false; ++ } ++ ++ if (connector->scaling_mode != DRM_MODE_SCALE_NONE && ++ connector->native_mode) { ++ int id = adjusted_mode->base.id; ++ *adjusted_mode = *connector->native_mode; ++ adjusted_mode->base.id = id; ++ } ++ ++ return true; ++} ++ ++static void ++nv50_dac_prepare(struct drm_encoder *encoder) ++{ ++} ++ ++static void ++nv50_dac_commit(struct drm_encoder *encoder) ++{ ++} ++ ++static void ++nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_device *dev = encoder->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *evo = dev_priv->evo; ++ struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc); ++ uint32_t mode_ctl = 0, mode_ctl2 = 0; ++ int ret; ++ ++ NV_DEBUG(dev, "or %d\n", nv_encoder->or); ++ ++ nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON); ++ ++ if (crtc->index == 1) ++ mode_ctl |= NV50_EVO_DAC_MODE_CTRL_CRTC1; ++ else ++ mode_ctl |= NV50_EVO_DAC_MODE_CTRL_CRTC0; ++ ++ /* Lacking a working tv-out, this is not a 100% sure. */ ++ if (nv_encoder->dcb->type == OUTPUT_ANALOG) ++ mode_ctl |= 0x40; ++ else ++ if (nv_encoder->dcb->type == OUTPUT_TV) ++ mode_ctl |= 0x100; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ++ mode_ctl2 |= NV50_EVO_DAC_MODE_CTRL2_NHSYNC; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ++ mode_ctl2 |= NV50_EVO_DAC_MODE_CTRL2_NVSYNC; ++ ++ ret = RING_SPACE(evo, 3); ++ if (ret) { ++ NV_ERROR(dev, "no space while connecting DAC\n"); ++ return; ++ } ++ BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2); ++ OUT_RING(evo, mode_ctl); ++ OUT_RING(evo, mode_ctl2); ++} ++ ++static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { ++ .dpms = nv50_dac_dpms, ++ .save = nv50_dac_save, ++ .restore = nv50_dac_restore, ++ .mode_fixup = nv50_dac_mode_fixup, ++ .prepare = nv50_dac_prepare, ++ .commit = nv50_dac_commit, ++ .mode_set = nv50_dac_mode_set, ++ .detect = nv50_dac_detect ++}; ++ ++static void ++nv50_dac_destroy(struct drm_encoder *encoder) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ ++ if (!encoder) ++ return; ++ ++ NV_DEBUG(encoder->dev, "\n"); ++ ++ drm_encoder_cleanup(encoder); ++ kfree(nv_encoder); ++} ++ ++static const struct drm_encoder_funcs nv50_dac_encoder_funcs = { ++ .destroy = nv50_dac_destroy, ++}; ++ ++int ++nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry) ++{ ++ struct nouveau_encoder *nv_encoder; ++ struct drm_encoder *encoder; ++ ++ NV_DEBUG(dev, "\n"); ++ NV_INFO(dev, "Detected a DAC output\n"); ++ ++ nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); ++ if (!nv_encoder) ++ return -ENOMEM; ++ encoder = to_drm_encoder(nv_encoder); ++ ++ nv_encoder->dcb = entry; ++ nv_encoder->or = ffs(entry->or) - 1; ++ ++ nv_encoder->disconnect = nv50_dac_disconnect; ++ ++ drm_encoder_init(dev, encoder, &nv50_dac_encoder_funcs, ++ DRM_MODE_ENCODER_DAC); ++ drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs); ++ ++ encoder->possible_crtcs = entry->heads; ++ encoder->possible_clones = 0; ++ return 0; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c +new file mode 100644 +index 0000000..c95efbc +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_display.c +@@ -0,0 +1,902 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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_display.h" ++#include "nouveau_crtc.h" ++#include "nouveau_encoder.h" ++#include "nouveau_connector.h" ++#include "nouveau_fb.h" ++#include "drm_crtc_helper.h" ++ ++static void ++nv50_evo_channel_del(struct nouveau_channel **pchan) ++{ ++ struct nouveau_channel *chan = *pchan; ++ ++ if (!chan) ++ return; ++ *pchan = NULL; ++ ++ nouveau_gpuobj_channel_takedown(chan); ++ nouveau_bo_ref(NULL, &chan->pushbuf_bo); ++ ++ if (chan->user) ++ iounmap(chan->user); ++ ++ kfree(chan); ++} ++ ++static int ++nv50_evo_dmaobj_new(struct nouveau_channel *evo, uint32_t class, uint32_t name, ++ uint32_t tile_flags, uint32_t magic_flags, ++ uint32_t offset, uint32_t limit) ++{ ++ struct drm_nouveau_private *dev_priv = evo->dev->dev_private; ++ struct drm_device *dev = evo->dev; ++ struct nouveau_gpuobj *obj = NULL; ++ int ret; ++ ++ ret = nouveau_gpuobj_new(dev, evo, 6*4, 32, 0, &obj); ++ if (ret) ++ return ret; ++ obj->engine = NVOBJ_ENGINE_DISPLAY; ++ ++ ret = nouveau_gpuobj_ref_add(dev, evo, name, obj, NULL); ++ if (ret) { ++ nouveau_gpuobj_del(dev, &obj); ++ return ret; ++ } ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ nv_wo32(dev, obj, 0, (tile_flags << 22) | (magic_flags << 16) | class); ++ nv_wo32(dev, obj, 1, limit); ++ nv_wo32(dev, obj, 2, offset); ++ nv_wo32(dev, obj, 3, 0x00000000); ++ nv_wo32(dev, obj, 4, 0x00000000); ++ nv_wo32(dev, obj, 5, 0x00010000); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ return 0; ++} ++ ++static int ++nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan; ++ int ret; ++ ++ chan = kzalloc(sizeof(struct nouveau_channel), GFP_KERNEL); ++ if (!chan) ++ return -ENOMEM; ++ *pchan = chan; ++ ++ chan->id = -1; ++ chan->dev = dev; ++ chan->user_get = 4; ++ chan->user_put = 0; ++ ++ INIT_LIST_HEAD(&chan->ramht_refs); ++ ++ ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 32768, 0x1000, ++ NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin); ++ if (ret) { ++ NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret); ++ nv50_evo_channel_del(pchan); ++ return ret; ++ } ++ ++ ret = nouveau_mem_init_heap(&chan->ramin_heap, chan->ramin->gpuobj-> ++ im_pramin->start, 32768); ++ if (ret) { ++ NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret); ++ nv50_evo_channel_del(pchan); ++ return ret; ++ } ++ ++ ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 4096, 16, ++ 0, &chan->ramht); ++ if (ret) { ++ NV_ERROR(dev, "Unable to allocate EVO RAMHT: %d\n", ret); ++ nv50_evo_channel_del(pchan); ++ return ret; ++ } ++ ++ if (dev_priv->chipset != 0x50) { ++ ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB16, 0x70, 0x19, ++ 0, 0xffffffff); ++ if (ret) { ++ nv50_evo_channel_del(pchan); ++ return ret; ++ } ++ ++ ++ ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB32, 0x7a, 0x19, ++ 0, 0xffffffff); ++ if (ret) { ++ nv50_evo_channel_del(pchan); ++ return ret; ++ } ++ } ++ ++ ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19, ++ 0, nouveau_mem_fb_amount(dev)); ++ if (ret) { ++ nv50_evo_channel_del(pchan); ++ return ret; ++ } ++ ++ ret = nouveau_bo_new(dev, NULL, 4096, 0, TTM_PL_FLAG_VRAM, 0, 0, ++ false, true, &chan->pushbuf_bo); ++ if (ret == 0) ++ ret = nouveau_bo_pin(chan->pushbuf_bo, TTM_PL_FLAG_VRAM); ++ if (ret) { ++ NV_ERROR(dev, "Error creating EVO DMA push buffer: %d\n", ret); ++ nv50_evo_channel_del(pchan); ++ return ret; ++ } ++ ++ ret = nouveau_bo_map(chan->pushbuf_bo); ++ if (ret) { ++ NV_ERROR(dev, "Error mapping EVO DMA push buffer: %d\n", ret); ++ nv50_evo_channel_del(pchan); ++ return ret; ++ } ++ ++ chan->user = ioremap(pci_resource_start(dev->pdev, 0) + ++ NV50_PDISPLAY_USER(0), PAGE_SIZE); ++ if (!chan->user) { ++ NV_ERROR(dev, "Error mapping EVO control regs.\n"); ++ nv50_evo_channel_del(pchan); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++int ++nv50_display_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; ++ struct nouveau_channel *evo = dev_priv->evo; ++ uint32_t val, ram_amount; ++ uint64_t start; ++ int ret, i; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(dev, 0x00610184, nv_rd32(dev, 0x00614004)); ++ /* ++ * I think the 0x006101XX range is some kind of main control area ++ * that enables things. ++ */ ++ /* CRTC? */ ++ nv_wr32(dev, 0x00610190 + 0 * 0x10, nv_rd32(dev, 0x00616100 + 0 * 0x800)); ++ nv_wr32(dev, 0x00610190 + 1 * 0x10, nv_rd32(dev, 0x00616100 + 1 * 0x800)); ++ nv_wr32(dev, 0x00610194 + 0 * 0x10, nv_rd32(dev, 0x00616104 + 0 * 0x800)); ++ nv_wr32(dev, 0x00610194 + 1 * 0x10, nv_rd32(dev, 0x00616104 + 1 * 0x800)); ++ nv_wr32(dev, 0x00610198 + 0 * 0x10, nv_rd32(dev, 0x00616108 + 0 * 0x800)); ++ nv_wr32(dev, 0x00610198 + 1 * 0x10, nv_rd32(dev, 0x00616108 + 1 * 0x800)); ++ nv_wr32(dev, 0x0061019c + 0 * 0x10, nv_rd32(dev, 0x0061610c + 0 * 0x800)); ++ nv_wr32(dev, 0x0061019c + 1 * 0x10, nv_rd32(dev, 0x0061610c + 1 * 0x800)); ++ /* DAC */ ++ nv_wr32(dev, 0x006101d0 + 0 * 0x4, nv_rd32(dev, 0x0061a000 + 0 * 0x800)); ++ nv_wr32(dev, 0x006101d0 + 1 * 0x4, nv_rd32(dev, 0x0061a000 + 1 * 0x800)); ++ nv_wr32(dev, 0x006101d0 + 2 * 0x4, nv_rd32(dev, 0x0061a000 + 2 * 0x800)); ++ /* SOR */ ++ nv_wr32(dev, 0x006101e0 + 0 * 0x4, nv_rd32(dev, 0x0061c000 + 0 * 0x800)); ++ nv_wr32(dev, 0x006101e0 + 1 * 0x4, nv_rd32(dev, 0x0061c000 + 1 * 0x800)); ++ nv_wr32(dev, 0x006101e0 + 2 * 0x4, nv_rd32(dev, 0x0061c000 + 2 * 0x800)); ++ nv_wr32(dev, 0x006101e0 + 3 * 0x4, nv_rd32(dev, 0x0061c000 + 3 * 0x800)); ++ /* Something not yet in use, tv-out maybe. */ ++ nv_wr32(dev, 0x006101f0 + 0 * 0x4, nv_rd32(dev, 0x0061e000 + 0 * 0x800)); ++ nv_wr32(dev, 0x006101f0 + 1 * 0x4, nv_rd32(dev, 0x0061e000 + 1 * 0x800)); ++ nv_wr32(dev, 0x006101f0 + 2 * 0x4, nv_rd32(dev, 0x0061e000 + 2 * 0x800)); ++ ++ for (i = 0; i < 3; i++) { ++ nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(i), 0x00550000 | ++ NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); ++ nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL1(i), 0x00000001); ++ } ++ ++ /* This used to be in crtc unblank, but seems out of place there. */ ++ nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0); ++ /* RAM is clamped to 256 MiB. */ ++ ram_amount = nouveau_mem_fb_amount(dev); ++ NV_DEBUG(dev, "ram_amount %d\n", ram_amount); ++ if (ram_amount > 256*1024*1024) ++ ram_amount = 256*1024*1024; ++ nv_wr32(dev, NV50_PDISPLAY_RAM_AMOUNT, ram_amount - 1); ++ nv_wr32(dev, NV50_PDISPLAY_UNK_388, 0x150000); ++ nv_wr32(dev, NV50_PDISPLAY_UNK_38C, 0); ++ ++ /* The precise purpose is unknown, i suspect it has something to do ++ * with text mode. ++ */ ++ if (nv_rd32(dev, NV50_PDISPLAY_INTR_1) & 0x100) { ++ nv_wr32(dev, NV50_PDISPLAY_INTR_1, 0x100); ++ nv_wr32(dev, 0x006194e8, nv_rd32(dev, 0x006194e8) & ~1); ++ if (!nv_wait(0x006194e8, 2, 0)) { ++ NV_ERROR(dev, "timeout: (0x6194e8 & 2) != 0\n"); ++ NV_ERROR(dev, "0x6194e8 = 0x%08x\n", ++ nv_rd32(dev, 0x6194e8)); ++ return -EBUSY; ++ } ++ } ++ ++ /* taken from nv bug #12637, attempts to un-wedge the hw if it's ++ * stuck in some unspecified state ++ */ ++ start = ptimer->read(dev); ++ nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x2b00); ++ while ((val = nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0))) & 0x1e0000) { ++ if ((val & 0x9f0000) == 0x20000) ++ nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), ++ val | 0x800000); ++ ++ if ((val & 0x3f0000) == 0x30000) ++ nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), ++ val | 0x200000); ++ ++ if (ptimer->read(dev) - start > 1000000000ULL) { ++ NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) != 0\n"); ++ NV_ERROR(dev, "0x610200 = 0x%08x\n", val); ++ return -EBUSY; ++ } ++ } ++ ++ nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, NV50_PDISPLAY_CTRL_STATE_ENABLE); ++ nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1000b03); ++ if (!nv_wait(NV50_PDISPLAY_CHANNEL_STAT(0), 0x40000000, 0x40000000)) { ++ NV_ERROR(dev, "timeout: (0x610200 & 0x40000000) == 0x40000000\n"); ++ NV_ERROR(dev, "0x610200 = 0x%08x\n", ++ nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0))); ++ return -EBUSY; ++ } ++ ++ for (i = 0; i < 2; i++) { ++ nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000); ++ if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), ++ NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) { ++ NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n"); ++ NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n", ++ nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i))); ++ return -EBUSY; ++ } ++ ++ nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), ++ NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON); ++ if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), ++ NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, ++ NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) { ++ NV_ERROR(dev, "timeout: " ++ "CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", i); ++ NV_ERROR(dev, "CURSOR_CTRL2(%d) = 0x%08x\n", i, ++ nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i))); ++ return -EBUSY; ++ } ++ } ++ ++ nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->instance >> 8) | 9); ++ ++ /* initialise fifo */ ++ nv_wr32(dev, NV50_PDISPLAY_CHANNEL_DMA_CB(0), ++ ((evo->pushbuf_bo->bo.mem.mm_node->start << PAGE_SHIFT) >> 8) | ++ NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_VRAM | ++ NV50_PDISPLAY_CHANNEL_DMA_CB_VALID); ++ nv_wr32(dev, NV50_PDISPLAY_CHANNEL_UNK2(0), 0x00010000); ++ nv_wr32(dev, NV50_PDISPLAY_CHANNEL_UNK3(0), 0x00000002); ++ if (!nv_wait(0x610200, 0x80000000, 0x00000000)) { ++ NV_ERROR(dev, "timeout: (0x610200 & 0x80000000) == 0\n"); ++ NV_ERROR(dev, "0x610200 = 0x%08x\n", nv_rd32(dev, 0x610200)); ++ return -EBUSY; ++ } ++ nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), ++ (nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0)) & ~0x00000003) | ++ NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED); ++ nv_wr32(dev, NV50_PDISPLAY_USER_PUT(0), 0); ++ nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x01000003 | ++ NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED); ++ nv_wr32(dev, 0x610300, nv_rd32(dev, 0x610300) & ~1); ++ ++ evo->dma.max = (4096/4) - 2; ++ evo->dma.put = 0; ++ evo->dma.cur = evo->dma.put; ++ evo->dma.free = evo->dma.max - evo->dma.cur; ++ ++ ret = RING_SPACE(evo, NOUVEAU_DMA_SKIPS); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < NOUVEAU_DMA_SKIPS; i++) ++ OUT_RING(evo, 0); ++ ++ ret = RING_SPACE(evo, 11); ++ if (ret) ++ return ret; ++ BEGIN_RING(evo, 0, NV50_EVO_UNK84, 2); ++ OUT_RING(evo, NV50_EVO_UNK84_NOTIFY_DISABLED); ++ OUT_RING(evo, NV50_EVO_DMA_NOTIFY_HANDLE_NONE); ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, FB_DMA), 1); ++ OUT_RING(evo, NV50_EVO_CRTC_FB_DMA_HANDLE_NONE); ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK0800), 1); ++ OUT_RING(evo, 0); ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, DISPLAY_START), 1); ++ OUT_RING(evo, 0); ++ BEGIN_RING(evo, 0, NV50_EVO_CRTC(0, UNK082C), 1); ++ OUT_RING(evo, 0); ++ FIRE_RING(evo); ++ if (!nv_wait(0x640004, 0xffffffff, evo->dma.put << 2)) ++ NV_ERROR(dev, "evo pushbuf stalled\n"); ++ ++ /* enable clock change interrupts. */ ++ nv_wr32(dev, 0x610028, 0x00010001); ++ nv_wr32(dev, NV50_PDISPLAY_INTR_EN, (NV50_PDISPLAY_INTR_EN_CLK_UNK10 | ++ NV50_PDISPLAY_INTR_EN_CLK_UNK20 | ++ NV50_PDISPLAY_INTR_EN_CLK_UNK40)); ++ ++ /* enable hotplug interrupts */ ++ nv_wr32(dev, NV50_PCONNECTOR_HOTPLUG_CTRL, 0x7FFF7FFF); ++ /* nv_wr32(dev, NV50_PCONNECTOR_HOTPLUG_INTR, 0x7FFF7FFF); */ ++ ++ ++ return 0; ++} ++ ++static int nv50_display_disable(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct drm_crtc *drm_crtc; ++ int ret, i; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) { ++ struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc); ++ ++ nv50_crtc_blank(crtc, true); ++ } ++ ++ ret = RING_SPACE(dev_priv->evo, 2); ++ if (ret == 0) { ++ BEGIN_RING(dev_priv->evo, 0, NV50_EVO_UPDATE, 1); ++ OUT_RING(dev_priv->evo, 0); ++ } ++ FIRE_RING(dev_priv->evo); ++ ++ /* Almost like ack'ing a vblank interrupt, maybe in the spirit of ++ * cleaning up? ++ */ ++ list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) { ++ struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc); ++ uint32_t mask = NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(crtc->index); ++ ++ if (!crtc->base.enabled) ++ continue; ++ ++ nv_wr32(dev, NV50_PDISPLAY_INTR_1, mask); ++ if (!nv_wait(NV50_PDISPLAY_INTR_1, mask, mask)) { ++ NV_ERROR(dev, "timeout: (0x610024 & 0x%08x) == " ++ "0x%08x\n", mask, mask); ++ NV_ERROR(dev, "0x610024 = 0x%08x\n", ++ nv_rd32(dev, NV50_PDISPLAY_INTR_1)); ++ } ++ } ++ ++ nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0); ++ nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, 0); ++ if (!nv_wait(NV50_PDISPLAY_CHANNEL_STAT(0), 0x1e0000, 0)) { ++ NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) == 0\n"); ++ NV_ERROR(dev, "0x610200 = 0x%08x\n", ++ nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0))); ++ } ++ ++ for (i = 0; i < 3; i++) { ++ if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_STATE(i), ++ NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) { ++ NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", i); ++ NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", i, ++ nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(i))); ++ } ++ } ++ ++ /* disable interrupts. */ ++ nv_wr32(dev, NV50_PDISPLAY_INTR_EN, 0x00000000); ++ ++ /* disable hotplug interrupts */ ++ nv_wr32(dev, NV50_PCONNECTOR_HOTPLUG_INTR, 0); ++ ++ return 0; ++} ++ ++int nv50_display_create(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct parsed_dcb *dcb = dev_priv->vbios->dcb; ++ uint32_t connector[16] = {}; ++ int ret, i; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ /* init basic kernel modesetting */ ++ drm_mode_config_init(dev); ++ ++ /* Initialise some optional connector properties. */ ++ drm_mode_create_scaling_mode_property(dev); ++ drm_mode_create_dithering_property(dev); ++ ++ dev->mode_config.min_width = 0; ++ dev->mode_config.min_height = 0; ++ ++ dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs; ++ ++ dev->mode_config.max_width = 8192; ++ dev->mode_config.max_height = 8192; ++ ++ dev->mode_config.fb_base = dev_priv->fb_phys; ++ ++ /* Create EVO channel */ ++ ret = nv50_evo_channel_new(dev, &dev_priv->evo); ++ if (ret) { ++ NV_ERROR(dev, "Error creating EVO channel: %d\n", ret); ++ return ret; ++ } ++ ++ /* Create CRTC objects */ ++ for (i = 0; i < 2; i++) ++ nv50_crtc_create(dev, i); ++ ++ /* We setup the encoders from the BIOS table */ ++ for (i = 0 ; i < dcb->entries; i++) { ++ struct dcb_entry *entry = &dcb->entry[i]; ++ ++ switch (entry->type) { ++ case OUTPUT_TMDS: ++ case OUTPUT_LVDS: ++ case OUTPUT_DP: ++ nv50_sor_create(dev, entry); ++ break; ++ case OUTPUT_ANALOG: ++ nv50_dac_create(dev, entry); ++ break; ++ default: ++ NV_WARN(dev, "DCB encoder %d unknown\n", entry->type); ++ continue; ++ } ++ ++ connector[entry->connector] |= (1 << entry->type); ++ } ++ ++ /* It appears that DCB 3.0+ VBIOS has a connector table, however, ++ * I'm not 100% certain how to decode it correctly yet so just ++ * look at what encoders are present on each connector index and ++ * attempt to derive the connector type from that. ++ */ ++ for (i = 0 ; i < dcb->entries; i++) { ++ struct dcb_entry *entry = &dcb->entry[i]; ++ uint16_t encoders; ++ int type; ++ ++ encoders = connector[entry->connector]; ++ if (!(encoders & (1 << entry->type))) ++ continue; ++ connector[entry->connector] = 0; ++ ++ if (encoders & (1 << OUTPUT_DP)) { ++ type = DRM_MODE_CONNECTOR_DisplayPort; ++ } else if (encoders & (1 << OUTPUT_TMDS)) { ++ if (encoders & (1 << OUTPUT_ANALOG)) ++ type = DRM_MODE_CONNECTOR_DVII; ++ else ++ type = DRM_MODE_CONNECTOR_DVID; ++ } else if (encoders & (1 << OUTPUT_ANALOG)) { ++ type = DRM_MODE_CONNECTOR_VGA; ++ } else if (encoders & (1 << OUTPUT_LVDS)) { ++ type = DRM_MODE_CONNECTOR_LVDS; ++ } else { ++ type = DRM_MODE_CONNECTOR_Unknown; ++ } ++ ++ if (type == DRM_MODE_CONNECTOR_Unknown) ++ continue; ++ ++ nouveau_connector_create(dev, entry->connector, type); ++ } ++ ++ ret = nv50_display_init(dev); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++int nv50_display_destroy(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ drm_mode_config_cleanup(dev); ++ ++ nv50_display_disable(dev); ++ nv50_evo_channel_del(&dev_priv->evo); ++ ++ return 0; ++} ++ ++static inline uint32_t ++nv50_display_mode_ctrl(struct drm_device *dev, bool sor, int or) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t mc; ++ ++ if (sor) { ++ if (dev_priv->chipset < 0x90 || ++ dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0) ++ mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(or)); ++ else ++ mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(or)); ++ } else { ++ mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(or)); ++ } ++ ++ return mc; ++} ++ ++static int ++nv50_display_irq_head(struct drm_device *dev, int *phead, ++ struct dcb_entry **pdcbent) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t unk30 = nv_rd32(dev, NV50_PDISPLAY_UNK30_CTRL); ++ uint32_t dac = 0, sor = 0; ++ int head, i, or; ++ ++ /* We're assuming that head 0 *or* head 1 will be active here, ++ * and not both. I'm not sure if the hw will even signal both ++ * ever, but it definitely shouldn't for us as we commit each ++ * CRTC separately, and submission will be blocked by the GPU ++ * until we handle each in turn. ++ */ ++ NV_DEBUG(dev, "0x610030: 0x%08x\n", unk30); ++ head = ffs((unk30 >> 9) & 3) - 1; ++ if (head < 0) { ++ NV_ERROR(dev, "no active heads: 0x%08x\n", ++ nv_rd32(dev, 0x610030)); ++ return -EINVAL; ++ } ++ ++ /* This assumes CRTCs are never bound to multiple encoders, which ++ * should be the case. ++ */ ++ for (i = 0; i < 3; i++) { ++ if (nv50_display_mode_ctrl(dev, false, i) & (1 << head)) ++ dac |= (1 << i); ++ } ++ ++ for (i = 0; i < 4; i++) { ++ if (nv50_display_mode_ctrl(dev, true, i) & (1 << head)) ++ sor |= (1 << i); ++ } ++ ++ NV_DEBUG(dev, "dac: 0x%08x, sor: 0x%08x\n", dac, sor); ++ ++ if (dac && sor) { ++ NV_ERROR(dev, "multiple encoders: 0x%08x 0x%08x\n", dac, sor); ++ return -1; ++ } else ++ if (dac) { ++ or = ffs(dac) - 1; ++ if (dac & ~(1 << or)) { ++ NV_ERROR(dev, "multiple DAC: 0x%08x\n", dac); ++ return -1; ++ } ++ } else ++ if (sor) { ++ or = ffs(sor) - 1; ++ if (sor & ~(1 << or)) { ++ NV_ERROR(dev, "multiple SOR: 0x%08x\n", sor); ++ return -1; ++ } ++ } else { ++ NV_ERROR(dev, "no encoders!\n"); ++ return -1; ++ } ++ ++ for (i = 0; i < dev_priv->vbios->dcb->entries; i++) { ++ struct dcb_entry *dcbent = &dev_priv->vbios->dcb->entry[i]; ++ ++ if (dac && (dcbent->type != OUTPUT_ANALOG && ++ dcbent->type != OUTPUT_TV)) ++ continue; ++ else ++ if (sor && (dcbent->type != OUTPUT_TMDS && ++ dcbent->type != OUTPUT_LVDS)) ++ continue; ++ ++ if (dcbent->or & (1 << or)) { ++ *phead = head; ++ *pdcbent = dcbent; ++ return 0; ++ } ++ } ++ ++ NV_ERROR(dev, "no DCB entry for %d %d\n", dac != 0, or); ++ return 0; ++} ++ ++static uint32_t ++nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent, ++ int pxclk) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvbios *bios = &dev_priv->VBIOS; ++ uint32_t mc, script = 0, or; ++ ++ or = ffs(dcbent->or) - 1; ++ mc = nv50_display_mode_ctrl(dev, dcbent->type != OUTPUT_ANALOG, or); ++ switch (dcbent->type) { ++ case OUTPUT_LVDS: ++ script = (mc >> 8) & 0xf; ++ if (pxclk >= bios->fp.duallink_transition_clk) ++ script |= 0x0100; ++ ++ if (nouveau_uscript_lvds >= 0) { ++ NV_INFO(dev, "override script 0x%04x with 0x%04x" ++ "for output LVDS-%d\n", script, ++ nouveau_uscript_lvds, or); ++ script = nouveau_uscript_lvds; ++ } ++ break; ++ case OUTPUT_TMDS: ++ script = (mc >> 8) & 0xf; ++ if (pxclk >= 165000) ++ script |= 0x0100; ++ ++ if (nouveau_uscript_tmds >= 0) { ++ NV_INFO(dev, "override script 0x%04x with 0x%04x" ++ "for output TMDS-%d\n", script, ++ nouveau_uscript_tmds, or); ++ script = nouveau_uscript_tmds; ++ } ++ break; ++ case OUTPUT_ANALOG: ++ script = 0xff; ++ break; ++ default: ++ NV_ERROR(dev, "modeset on unsupported output type!\n"); ++ break; ++ } ++ ++ return script; ++} ++ ++static void ++nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan; ++ struct list_head *entry, *tmp; ++ ++ list_for_each_safe(entry, tmp, &dev_priv->vbl_waiting) { ++ chan = list_entry(entry, struct nouveau_channel, nvsw.vbl_wait); ++ ++ nouveau_bo_wr32(chan->notifier_bo, chan->nvsw.vblsem_offset, ++ chan->nvsw.vblsem_rval); ++ list_del(&chan->nvsw.vbl_wait); ++ } ++} ++ ++static void ++nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr) ++{ ++ intr &= NV50_PDISPLAY_INTR_1_VBLANK_CRTC; ++ ++ if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_0) ++ nv50_display_vblank_crtc_handler(dev, 0); ++ ++ if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1) ++ nv50_display_vblank_crtc_handler(dev, 1); ++ ++ nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev, ++ NV50_PDISPLAY_INTR_EN) & ~intr); ++ nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr); ++} ++ ++static void ++nv50_display_unk10_handler(struct drm_device *dev) ++{ ++ struct dcb_entry *dcbent; ++ int head, ret; ++ ++ ret = nv50_display_irq_head(dev, &head, &dcbent); ++ if (ret) ++ goto ack; ++ ++ nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8); ++ ++ nouveau_bios_run_display_table(dev, dcbent, 0, -1); ++ ++ack: ++ nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10); ++ nv_wr32(dev, 0x610030, 0x80000000); ++} ++ ++static void ++nv50_display_unk20_handler(struct drm_device *dev) ++{ ++ struct dcb_entry *dcbent; ++ uint32_t tmp, pclk, script; ++ int head, or, ret; ++ ++ ret = nv50_display_irq_head(dev, &head, &dcbent); ++ if (ret) ++ goto ack; ++ or = ffs(dcbent->or) - 1; ++ pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff; ++ script = nv50_display_script_select(dev, dcbent, pclk); ++ ++ NV_DEBUG(dev, "head %d pxclk: %dKHz\n", head, pclk); ++ ++ nouveau_bios_run_display_table(dev, dcbent, 0, -2); ++ ++ nv50_crtc_set_clock(dev, head, pclk); ++ ++ nouveau_bios_run_display_table(dev, dcbent, script, pclk); ++ ++ tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head)); ++ tmp &= ~0x000000f; ++ nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head), tmp); ++ ++ if (dcbent->type != OUTPUT_ANALOG) { ++ tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or)); ++ tmp &= ~0x00000f0f; ++ if (script & 0x0100) ++ tmp |= 0x00000101; ++ nv_wr32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or), tmp); ++ } else { ++ nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0); ++ } ++ ++ack: ++ nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20); ++ nv_wr32(dev, 0x610030, 0x80000000); ++} ++ ++static void ++nv50_display_unk40_handler(struct drm_device *dev) ++{ ++ struct dcb_entry *dcbent; ++ int head, pclk, script, ret; ++ ++ ret = nv50_display_irq_head(dev, &head, &dcbent); ++ if (ret) ++ goto ack; ++ pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff; ++ script = nv50_display_script_select(dev, dcbent, pclk); ++ ++ nouveau_bios_run_display_table(dev, dcbent, script, -pclk); ++ ++ack: ++ nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40); ++ nv_wr32(dev, 0x610030, 0x80000000); ++ nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) | 8); ++} ++ ++void ++nv50_display_irq_handler_bh(struct work_struct *work) ++{ ++ struct drm_nouveau_private *dev_priv = ++ container_of(work, struct drm_nouveau_private, irq_work); ++ struct drm_device *dev = dev_priv->dev; ++ ++ for (;;) { ++ uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); ++ uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1); ++ ++ NV_DEBUG(dev, "PDISPLAY_INTR_BH 0x%08x 0x%08x\n", intr0, intr1); ++ ++ if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK10) ++ nv50_display_unk10_handler(dev); ++ else ++ if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK20) ++ nv50_display_unk20_handler(dev); ++ else ++ if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK40) ++ nv50_display_unk40_handler(dev); ++ else ++ break; ++ } ++ ++ nv_wr32(dev, NV03_PMC_INTR_EN_0, 1); ++} ++ ++static void ++nv50_display_error_handler(struct drm_device *dev) ++{ ++ uint32_t addr, data; ++ ++ nv_wr32(dev, NV50_PDISPLAY_INTR_0, 0x00010000); ++ addr = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_ADDR); ++ data = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_DATA); ++ ++ NV_ERROR(dev, "EvoCh %d Mthd 0x%04x Data 0x%08x (0x%04x 0x%02x)\n", ++ 0, addr & 0xffc, data, addr >> 16, (addr >> 12) & 0xf); ++ ++ nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000); ++} ++ ++void ++nv50_display_irq_handler(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t delayed = 0; ++ ++ while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { ++ uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); ++ uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1); ++ uint32_t clock; ++ ++ NV_DEBUG(dev, "PDISPLAY_INTR 0x%08x 0x%08x\n", intr0, intr1); ++ ++ if (!intr0 && !(intr1 & ~delayed)) ++ break; ++ ++ if (intr0 & 0x00010000) { ++ nv50_display_error_handler(dev); ++ intr0 &= ~0x00010000; ++ } ++ ++ if (intr1 & NV50_PDISPLAY_INTR_1_VBLANK_CRTC) { ++ nv50_display_vblank_handler(dev, intr1); ++ intr1 &= ~NV50_PDISPLAY_INTR_1_VBLANK_CRTC; ++ } ++ ++ clock = (intr1 & (NV50_PDISPLAY_INTR_1_CLK_UNK10 | ++ NV50_PDISPLAY_INTR_1_CLK_UNK20 | ++ NV50_PDISPLAY_INTR_1_CLK_UNK40)); ++ if (clock) { ++ nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); ++ if (!work_pending(&dev_priv->irq_work)) ++ schedule_work(&dev_priv->irq_work); ++ delayed |= clock; ++ intr1 &= ~clock; ++ } ++ ++ if (intr0) { ++ NV_ERROR(dev, "unknown PDISPLAY_INTR_0: 0x%08x\n", intr0); ++ nv_wr32(dev, NV50_PDISPLAY_INTR_0, intr0); ++ } ++ ++ if (intr1) { ++ NV_ERROR(dev, ++ "unknown PDISPLAY_INTR_1: 0x%08x\n", intr1); ++ nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr1); ++ } ++ } ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h +new file mode 100644 +index 0000000..3ae8d07 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_display.h +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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_DISPLAY_H__ ++#define __NV50_DISPLAY_H__ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++#include "nouveau_reg.h" ++#include "nouveau_crtc.h" ++#include "nv50_evo.h" ++ ++void nv50_display_irq_handler(struct drm_device *dev); ++void nv50_display_irq_handler_bh(struct work_struct *work); ++int nv50_display_init(struct drm_device *dev); ++int nv50_display_create(struct drm_device *dev); ++int nv50_display_destroy(struct drm_device *dev); ++int nv50_crtc_blank(struct nouveau_crtc *, bool blank); ++int nv50_crtc_set_clock(struct drm_device *, int head, int pclk); ++ ++#endif /* __NV50_DISPLAY_H__ */ +diff --git a/drivers/gpu/drm/nouveau/nv50_evo.h b/drivers/gpu/drm/nouveau/nv50_evo.h +new file mode 100644 +index 0000000..aae1334 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_evo.h +@@ -0,0 +1,113 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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. ++ * ++ */ ++ ++#define NV50_EVO_UPDATE 0x00000080 ++#define NV50_EVO_UNK84 0x00000084 ++#define NV50_EVO_UNK84_NOTIFY 0x40000000 ++#define NV50_EVO_UNK84_NOTIFY_DISABLED 0x00000000 ++#define NV50_EVO_UNK84_NOTIFY_ENABLED 0x40000000 ++#define NV50_EVO_DMA_NOTIFY 0x00000088 ++#define NV50_EVO_DMA_NOTIFY_HANDLE 0xffffffff ++#define NV50_EVO_DMA_NOTIFY_HANDLE_NONE 0x00000000 ++#define NV50_EVO_UNK8C 0x0000008C ++ ++#define NV50_EVO_DAC(n, r) ((n) * 0x80 + NV50_EVO_DAC_##r) ++#define NV50_EVO_DAC_MODE_CTRL 0x00000400 ++#define NV50_EVO_DAC_MODE_CTRL_CRTC0 0x00000001 ++#define NV50_EVO_DAC_MODE_CTRL_CRTC1 0x00000002 ++#define NV50_EVO_DAC_MODE_CTRL2 0x00000404 ++#define NV50_EVO_DAC_MODE_CTRL2_NHSYNC 0x00000001 ++#define NV50_EVO_DAC_MODE_CTRL2_NVSYNC 0x00000002 ++ ++#define NV50_EVO_SOR(n, r) ((n) * 0x40 + NV50_EVO_SOR_##r) ++#define NV50_EVO_SOR_MODE_CTRL 0x00000600 ++#define NV50_EVO_SOR_MODE_CTRL_CRTC0 0x00000001 ++#define NV50_EVO_SOR_MODE_CTRL_CRTC1 0x00000002 ++#define NV50_EVO_SOR_MODE_CTRL_TMDS 0x00000100 ++#define NV50_EVO_SOR_MODE_CTRL_TMDS_DUAL_LINK 0x00000400 ++#define NV50_EVO_SOR_MODE_CTRL_NHSYNC 0x00001000 ++#define NV50_EVO_SOR_MODE_CTRL_NVSYNC 0x00002000 ++ ++#define NV50_EVO_CRTC(n, r) ((n) * 0x400 + NV50_EVO_CRTC_##r) ++#define NV84_EVO_CRTC(n, r) ((n) * 0x400 + NV84_EVO_CRTC_##r) ++#define NV50_EVO_CRTC_UNK0800 0x00000800 ++#define NV50_EVO_CRTC_CLOCK 0x00000804 ++#define NV50_EVO_CRTC_INTERLACE 0x00000808 ++#define NV50_EVO_CRTC_DISPLAY_START 0x00000810 ++#define NV50_EVO_CRTC_DISPLAY_TOTAL 0x00000814 ++#define NV50_EVO_CRTC_SYNC_DURATION 0x00000818 ++#define NV50_EVO_CRTC_SYNC_START_TO_BLANK_END 0x0000081c ++#define NV50_EVO_CRTC_UNK0820 0x00000820 ++#define NV50_EVO_CRTC_UNK0824 0x00000824 ++#define NV50_EVO_CRTC_UNK082C 0x0000082c ++#define NV50_EVO_CRTC_CLUT_MODE 0x00000840 ++/* You can't have a palette in 8 bit mode (=OFF) */ ++#define NV50_EVO_CRTC_CLUT_MODE_BLANK 0x00000000 ++#define NV50_EVO_CRTC_CLUT_MODE_OFF 0x80000000 ++#define NV50_EVO_CRTC_CLUT_MODE_ON 0xC0000000 ++#define NV50_EVO_CRTC_CLUT_OFFSET 0x00000844 ++#define NV84_EVO_CRTC_CLUT_DMA 0x0000085C ++#define NV84_EVO_CRTC_CLUT_DMA_HANDLE 0xffffffff ++#define NV84_EVO_CRTC_CLUT_DMA_HANDLE_NONE 0x00000000 ++#define NV50_EVO_CRTC_FB_OFFSET 0x00000860 ++#define NV50_EVO_CRTC_FB_SIZE 0x00000868 ++#define NV50_EVO_CRTC_FB_CONFIG 0x0000086c ++#define NV50_EVO_CRTC_FB_CONFIG_MODE 0x00100000 ++#define NV50_EVO_CRTC_FB_CONFIG_MODE_TILE 0x00000000 ++#define NV50_EVO_CRTC_FB_CONFIG_MODE_PITCH 0x00100000 ++#define NV50_EVO_CRTC_FB_DEPTH 0x00000870 ++#define NV50_EVO_CRTC_FB_DEPTH_8 0x00001e00 ++#define NV50_EVO_CRTC_FB_DEPTH_15 0x0000e900 ++#define NV50_EVO_CRTC_FB_DEPTH_16 0x0000e800 ++#define NV50_EVO_CRTC_FB_DEPTH_24 0x0000cf00 ++#define NV50_EVO_CRTC_FB_DEPTH_30 0x0000d100 ++#define NV50_EVO_CRTC_FB_DMA 0x00000874 ++#define NV50_EVO_CRTC_FB_DMA_HANDLE 0xffffffff ++#define NV50_EVO_CRTC_FB_DMA_HANDLE_NONE 0x00000000 ++#define NV50_EVO_CRTC_CURSOR_CTRL 0x00000880 ++#define NV50_EVO_CRTC_CURSOR_CTRL_HIDE 0x05000000 ++#define NV50_EVO_CRTC_CURSOR_CTRL_SHOW 0x85000000 ++#define NV50_EVO_CRTC_CURSOR_OFFSET 0x00000884 ++#define NV84_EVO_CRTC_CURSOR_DMA 0x0000089c ++#define NV84_EVO_CRTC_CURSOR_DMA_HANDLE 0xffffffff ++#define NV84_EVO_CRTC_CURSOR_DMA_HANDLE_NONE 0x00000000 ++#define NV50_EVO_CRTC_DITHER_CTRL 0x000008a0 ++#define NV50_EVO_CRTC_DITHER_CTRL_OFF 0x00000000 ++#define NV50_EVO_CRTC_DITHER_CTRL_ON 0x00000011 ++#define NV50_EVO_CRTC_SCALE_CTRL 0x000008a4 ++#define NV50_EVO_CRTC_SCALE_CTRL_INACTIVE 0x00000000 ++#define NV50_EVO_CRTC_SCALE_CTRL_ACTIVE 0x00000009 ++#define NV50_EVO_CRTC_COLOR_CTRL 0x000008a8 ++#define NV50_EVO_CRTC_COLOR_CTRL_COLOR 0x00040000 ++#define NV50_EVO_CRTC_FB_POS 0x000008c0 ++#define NV50_EVO_CRTC_REAL_RES 0x000008c8 ++#define NV50_EVO_CRTC_SCALE_CENTER_OFFSET 0x000008d4 ++#define NV50_EVO_CRTC_SCALE_CENTER_OFFSET_VAL(x, y) \ ++ ((((unsigned)y << 16) & 0xFFFF0000) | (((unsigned)x) & 0x0000FFFF)) ++/* Both of these are needed, otherwise nothing happens. */ ++#define NV50_EVO_CRTC_SCALE_RES1 0x000008d8 ++#define NV50_EVO_CRTC_SCALE_RES2 0x000008dc ++ +diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c +new file mode 100644 +index 0000000..6bcc6d3 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c +@@ -0,0 +1,273 @@ ++#include "drmP.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++#include "nouveau_fbcon.h" ++ ++static void ++nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->channel; ++ ++ if (info->state != FBINFO_STATE_RUNNING) ++ return; ++ ++ if (!(info->flags & FBINFO_HWACCEL_DISABLED) && ++ RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11)) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ } ++ ++ if (info->flags & FBINFO_HWACCEL_DISABLED) { ++ cfb_fillrect(info, rect); ++ return; ++ } ++ ++ if (rect->rop != ROP_COPY) { ++ BEGIN_RING(chan, NvSub2D, 0x02ac, 1); ++ OUT_RING(chan, 1); ++ } ++ BEGIN_RING(chan, NvSub2D, 0x0588, 1); ++ OUT_RING(chan, rect->color); ++ BEGIN_RING(chan, NvSub2D, 0x0600, 4); ++ OUT_RING(chan, rect->dx); ++ OUT_RING(chan, rect->dy); ++ OUT_RING(chan, rect->dx + rect->width); ++ OUT_RING(chan, rect->dy + rect->height); ++ if (rect->rop != ROP_COPY) { ++ BEGIN_RING(chan, NvSub2D, 0x02ac, 1); ++ OUT_RING(chan, 3); ++ } ++ FIRE_RING(chan); ++} ++ ++static void ++nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->channel; ++ ++ if (info->state != FBINFO_STATE_RUNNING) ++ return; ++ ++ if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 12)) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ } ++ ++ if (info->flags & FBINFO_HWACCEL_DISABLED) { ++ cfb_copyarea(info, region); ++ return; ++ } ++ ++ BEGIN_RING(chan, NvSub2D, 0x0110, 1); ++ OUT_RING(chan, 0); ++ BEGIN_RING(chan, NvSub2D, 0x08b0, 4); ++ OUT_RING(chan, region->dx); ++ OUT_RING(chan, region->dy); ++ OUT_RING(chan, region->width); ++ OUT_RING(chan, region->height); ++ BEGIN_RING(chan, NvSub2D, 0x08d0, 4); ++ OUT_RING(chan, 0); ++ OUT_RING(chan, region->sx); ++ OUT_RING(chan, 0); ++ OUT_RING(chan, region->sy); ++ FIRE_RING(chan); ++} ++ ++static void ++nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->channel; ++ uint32_t width, dwords, *data = (uint32_t *)image->data; ++ uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); ++ uint32_t *palette = info->pseudo_palette; ++ ++ if (info->state != FBINFO_STATE_RUNNING) ++ return; ++ ++ if (image->depth != 1) { ++ cfb_imageblit(info, image); ++ return; ++ } ++ ++ if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 11)) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ } ++ ++ if (info->flags & FBINFO_HWACCEL_DISABLED) { ++ cfb_imageblit(info, image); ++ return; ++ } ++ ++ width = (image->width + 31) & ~31; ++ dwords = (width * image->height) >> 5; ++ ++ BEGIN_RING(chan, NvSub2D, 0x0814, 2); ++ if (info->fix.visual == FB_VISUAL_TRUECOLOR || ++ info->fix.visual == FB_VISUAL_DIRECTCOLOR) { ++ OUT_RING(chan, palette[image->bg_color] | mask); ++ OUT_RING(chan, palette[image->fg_color] | mask); ++ } else { ++ OUT_RING(chan, image->bg_color); ++ OUT_RING(chan, image->fg_color); ++ } ++ BEGIN_RING(chan, NvSub2D, 0x0838, 2); ++ OUT_RING(chan, image->width); ++ OUT_RING(chan, image->height); ++ BEGIN_RING(chan, NvSub2D, 0x0850, 4); ++ OUT_RING(chan, 0); ++ OUT_RING(chan, image->dx); ++ OUT_RING(chan, 0); ++ OUT_RING(chan, image->dy); ++ ++ while (dwords) { ++ int push = dwords > 2047 ? 2047 : dwords; ++ ++ if (RING_SPACE(chan, push + 1)) { ++ NV_ERROR(dev, ++ "GPU lockup - switching to software fbcon\n"); ++ info->flags |= FBINFO_HWACCEL_DISABLED; ++ cfb_imageblit(info, image); ++ return; ++ } ++ ++ dwords -= push; ++ ++ BEGIN_RING(chan, NvSub2D, 0x40000860, push); ++ OUT_RINGp(chan, data, push); ++ data += push; ++ } ++ ++ FIRE_RING(chan); ++} ++ ++int ++nv50_fbcon_accel_init(struct fb_info *info) ++{ ++ struct nouveau_fbcon_par *par = info->par; ++ struct drm_device *dev = par->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->channel; ++ struct nouveau_gpuobj *eng2d = NULL; ++ int ret, format; ++ ++ switch (info->var.bits_per_pixel) { ++ case 8: ++ format = 0xf3; ++ break; ++ case 15: ++ format = 0xf8; ++ break; ++ case 16: ++ format = 0xe8; ++ break; ++ case 32: ++ switch (info->var.transp.length) { ++ case 0: /* depth 24 */ ++ case 8: /* depth 32, just use 24.. */ ++ format = 0xe6; ++ break; ++ case 2: /* depth 30 */ ++ format = 0xd1; ++ break; ++ default: ++ return -EINVAL; ++ } ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ ret = nouveau_gpuobj_gr_new(dev_priv->channel, 0x502d, &eng2d); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, Nv2D, eng2d, NULL); ++ if (ret) ++ return ret; ++ ++ ret = RING_SPACE(chan, 59); ++ if (ret) { ++ NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); ++ return ret; ++ } ++ ++ BEGIN_RING(chan, NvSub2D, 0x0000, 1); ++ OUT_RING(chan, Nv2D); ++ BEGIN_RING(chan, NvSub2D, 0x0180, 4); ++ OUT_RING(chan, NvNotify0); ++ OUT_RING(chan, chan->vram_handle); ++ OUT_RING(chan, chan->vram_handle); ++ OUT_RING(chan, chan->vram_handle); ++ BEGIN_RING(chan, NvSub2D, 0x0290, 1); ++ OUT_RING(chan, 0); ++ BEGIN_RING(chan, NvSub2D, 0x0888, 1); ++ OUT_RING(chan, 1); ++ BEGIN_RING(chan, NvSub2D, 0x02ac, 1); ++ OUT_RING(chan, 3); ++ BEGIN_RING(chan, NvSub2D, 0x02a0, 1); ++ OUT_RING(chan, 0x55); ++ BEGIN_RING(chan, NvSub2D, 0x08c0, 4); ++ OUT_RING(chan, 0); ++ OUT_RING(chan, 1); ++ OUT_RING(chan, 0); ++ OUT_RING(chan, 1); ++ BEGIN_RING(chan, NvSub2D, 0x0580, 2); ++ OUT_RING(chan, 4); ++ OUT_RING(chan, format); ++ BEGIN_RING(chan, NvSub2D, 0x02e8, 2); ++ OUT_RING(chan, 2); ++ OUT_RING(chan, 1); ++ BEGIN_RING(chan, NvSub2D, 0x0804, 1); ++ OUT_RING(chan, format); ++ BEGIN_RING(chan, NvSub2D, 0x0800, 1); ++ OUT_RING(chan, 1); ++ BEGIN_RING(chan, NvSub2D, 0x0808, 3); ++ OUT_RING(chan, 0); ++ OUT_RING(chan, 0); ++ OUT_RING(chan, 0); ++ BEGIN_RING(chan, NvSub2D, 0x081c, 1); ++ OUT_RING(chan, 1); ++ BEGIN_RING(chan, NvSub2D, 0x0840, 4); ++ OUT_RING(chan, 0); ++ OUT_RING(chan, 1); ++ OUT_RING(chan, 0); ++ OUT_RING(chan, 1); ++ BEGIN_RING(chan, NvSub2D, 0x0200, 2); ++ OUT_RING(chan, format); ++ OUT_RING(chan, 1); ++ BEGIN_RING(chan, NvSub2D, 0x0214, 5); ++ OUT_RING(chan, info->fix.line_length); ++ OUT_RING(chan, info->var.xres_virtual); ++ OUT_RING(chan, info->var.yres_virtual); ++ OUT_RING(chan, 0); ++ OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys + ++ dev_priv->vm_vram_base); ++ BEGIN_RING(chan, NvSub2D, 0x0230, 2); ++ OUT_RING(chan, format); ++ OUT_RING(chan, 1); ++ BEGIN_RING(chan, NvSub2D, 0x0244, 5); ++ OUT_RING(chan, info->fix.line_length); ++ OUT_RING(chan, info->var.xres_virtual); ++ OUT_RING(chan, info->var.yres_virtual); ++ OUT_RING(chan, 0); ++ OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys + ++ dev_priv->vm_vram_base); ++ ++ info->fbops->fb_fillrect = nv50_fbcon_fillrect; ++ info->fbops->fb_copyarea = nv50_fbcon_copyarea; ++ info->fbops->fb_imageblit = nv50_fbcon_imageblit; ++ return 0; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c +new file mode 100644 +index 0000000..77ae1aa +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_fifo.c +@@ -0,0 +1,494 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++struct nv50_fifo_priv { ++ struct nouveau_gpuobj_ref *thingo[2]; ++ int cur_thingo; ++}; ++ ++#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) ++ ++static void ++nv50_fifo_init_thingo(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv; ++ struct nouveau_gpuobj_ref *cur; ++ int i, nr; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ cur = priv->thingo[priv->cur_thingo]; ++ priv->cur_thingo = !priv->cur_thingo; ++ ++ /* We never schedule channel 0 or 127 */ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ for (i = 1, nr = 0; i < 127; i++) { ++ if (dev_priv->fifos[i] && dev_priv->fifos[i]->ramfc) ++ nv_wo32(dev, cur->gpuobj, nr++, i); ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv_wr32(dev, 0x32f4, cur->instance >> 12); ++ nv_wr32(dev, 0x32ec, nr); ++ nv_wr32(dev, 0x2500, 0x101); ++} ++ ++static int ++nv50_fifo_channel_enable(struct drm_device *dev, int channel, bool nt) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->fifos[channel]; ++ uint32_t inst; ++ ++ NV_DEBUG(dev, "ch%d\n", channel); ++ ++ if (!chan->ramfc) ++ return -EINVAL; ++ ++ if (IS_G80) ++ inst = chan->ramfc->instance >> 12; ++ else ++ inst = chan->ramfc->instance >> 8; ++ nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), ++ inst | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED); ++ ++ if (!nt) ++ nv50_fifo_init_thingo(dev); ++ return 0; ++} ++ ++static void ++nv50_fifo_channel_disable(struct drm_device *dev, int channel, bool nt) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t inst; ++ ++ NV_DEBUG(dev, "ch%d, nt=%d\n", channel, nt); ++ ++ if (IS_G80) ++ inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80; ++ else ++ inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84; ++ nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst); ++ ++ if (!nt) ++ nv50_fifo_init_thingo(dev); ++} ++ ++static void ++nv50_fifo_init_reset(struct drm_device *dev) ++{ ++ uint32_t pmc_e = NV_PMC_ENABLE_PFIFO; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e); ++ nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | pmc_e); ++} ++ ++static void ++nv50_fifo_init_intr(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(dev, NV03_PFIFO_INTR_0, 0xFFFFFFFF); ++ nv_wr32(dev, NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF); ++} ++ ++static void ++nv50_fifo_init_context_table(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int i; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) { ++ if (dev_priv->fifos[i]) ++ nv50_fifo_channel_enable(dev, i, true); ++ else ++ nv50_fifo_channel_disable(dev, i, true); ++ } ++ ++ nv50_fifo_init_thingo(dev); ++} ++ ++static void ++nv50_fifo_init_regs__nv(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(dev, 0x250c, 0x6f3cfc34); ++} ++ ++static void ++nv50_fifo_init_regs(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(dev, 0x2500, 0); ++ nv_wr32(dev, 0x3250, 0); ++ nv_wr32(dev, 0x3220, 0); ++ nv_wr32(dev, 0x3204, 0); ++ nv_wr32(dev, 0x3210, 0); ++ nv_wr32(dev, 0x3270, 0); ++ ++ /* Enable dummy channels setup by nv50_instmem.c */ ++ nv50_fifo_channel_enable(dev, 0, true); ++ nv50_fifo_channel_enable(dev, 127, true); ++} ++ ++int ++nv50_fifo_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_fifo_priv *priv; ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ priv = dev_priv->engine.fifo.priv; ++ if (priv) { ++ priv->cur_thingo = !priv->cur_thingo; ++ goto just_reset; ++ } ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ dev_priv->engine.fifo.priv = priv; ++ ++ ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, ++ NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[0]); ++ if (ret) { ++ NV_ERROR(dev, "error creating thingo0: %d\n", ret); ++ return ret; ++ } ++ ++ ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000, ++ NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[1]); ++ if (ret) { ++ NV_ERROR(dev, "error creating thingo1: %d\n", ret); ++ return ret; ++ } ++ ++just_reset: ++ nv50_fifo_init_reset(dev); ++ nv50_fifo_init_intr(dev); ++ nv50_fifo_init_context_table(dev); ++ nv50_fifo_init_regs__nv(dev); ++ nv50_fifo_init_regs(dev); ++ dev_priv->engine.fifo.enable(dev); ++ dev_priv->engine.fifo.reassign(dev, true); ++ ++ return 0; ++} ++ ++void ++nv50_fifo_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (!priv) ++ return; ++ ++ nouveau_gpuobj_ref_del(dev, &priv->thingo[0]); ++ nouveau_gpuobj_ref_del(dev, &priv->thingo[1]); ++ ++ dev_priv->engine.fifo.priv = NULL; ++ kfree(priv); ++} ++ ++int ++nv50_fifo_channel_id(struct drm_device *dev) ++{ ++ return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & ++ NV50_PFIFO_CACHE1_PUSH1_CHID_MASK; ++} ++ ++int ++nv50_fifo_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *ramfc = NULL; ++ int ret; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ if (IS_G80) { ++ uint32_t ramin_poffset = chan->ramin->gpuobj->im_pramin->start; ++ uint32_t ramin_voffset = chan->ramin->gpuobj->im_backing_start; ++ ++ ret = nouveau_gpuobj_new_fake(dev, ramin_poffset, ramin_voffset, ++ 0x100, NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, &ramfc, ++ &chan->ramfc); ++ if (ret) ++ return ret; ++ ++ ret = nouveau_gpuobj_new_fake(dev, ramin_poffset + 0x0400, ++ ramin_voffset + 0x0400, 4096, ++ 0, NULL, &chan->cache); ++ if (ret) ++ return ret; ++ } else { ++ ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 0x100, 256, ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, ++ &chan->ramfc); ++ if (ret) ++ return ret; ++ ramfc = chan->ramfc->gpuobj; ++ ++ ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 4096, 256, ++ 0, &chan->cache); ++ if (ret) ++ return ret; ++ } ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ ++ nv_wo32(dev, ramfc, 0x08/4, chan->pushbuf_base); ++ nv_wo32(dev, ramfc, 0x10/4, chan->pushbuf_base); ++ nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4); ++ nv_wo32(dev, ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4)); ++ nv_wo32(dev, ramfc, 0x3c/4, 0x00086078); ++ nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff); ++ nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff); ++ nv_wo32(dev, ramfc, 0x40/4, 0x00000000); ++ nv_wo32(dev, ramfc, 0x7c/4, 0x30000001); ++ nv_wo32(dev, ramfc, 0x78/4, 0x00000000); ++ nv_wo32(dev, ramfc, 0x4c/4, 0xffffffff); ++ ++ if (!IS_G80) { ++ nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id); ++ nv_wo32(dev, chan->ramin->gpuobj, 1, ++ chan->ramfc->instance >> 8); ++ ++ nv_wo32(dev, ramfc, 0x88/4, chan->cache->instance >> 10); ++ nv_wo32(dev, ramfc, 0x98/4, chan->ramin->instance >> 12); ++ } ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ ret = nv50_fifo_channel_enable(dev, chan->id, false); ++ if (ret) { ++ NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret); ++ nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++void ++nv50_fifo_destroy_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++ nouveau_gpuobj_ref_del(dev, &chan->cache); ++ ++ nv50_fifo_channel_disable(dev, chan->id, false); ++ ++ /* Dummy channel, also used on ch 127 */ ++ if (chan->id == 0) ++ nv50_fifo_channel_disable(dev, 127, false); ++} ++ ++int ++nv50_fifo_load_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *ramfc = chan->ramfc->gpuobj; ++ struct nouveau_gpuobj *cache = chan->cache->gpuobj; ++ int ptr, cnt; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ dev_priv->engine.instmem.prepare_access(dev, false); ++ ++ nv_wr32(dev, 0x3330, nv_ro32(dev, ramfc, 0x00/4)); ++ nv_wr32(dev, 0x3334, nv_ro32(dev, ramfc, 0x04/4)); ++ nv_wr32(dev, 0x3240, nv_ro32(dev, ramfc, 0x08/4)); ++ nv_wr32(dev, 0x3320, nv_ro32(dev, ramfc, 0x0c/4)); ++ nv_wr32(dev, 0x3244, nv_ro32(dev, ramfc, 0x10/4)); ++ nv_wr32(dev, 0x3328, nv_ro32(dev, ramfc, 0x14/4)); ++ nv_wr32(dev, 0x3368, nv_ro32(dev, ramfc, 0x18/4)); ++ nv_wr32(dev, 0x336c, nv_ro32(dev, ramfc, 0x1c/4)); ++ nv_wr32(dev, 0x3370, nv_ro32(dev, ramfc, 0x20/4)); ++ nv_wr32(dev, 0x3374, nv_ro32(dev, ramfc, 0x24/4)); ++ nv_wr32(dev, 0x3378, nv_ro32(dev, ramfc, 0x28/4)); ++ nv_wr32(dev, 0x337c, nv_ro32(dev, ramfc, 0x2c/4)); ++ nv_wr32(dev, 0x3228, nv_ro32(dev, ramfc, 0x30/4)); ++ nv_wr32(dev, 0x3364, nv_ro32(dev, ramfc, 0x34/4)); ++ nv_wr32(dev, 0x32a0, nv_ro32(dev, ramfc, 0x38/4)); ++ nv_wr32(dev, 0x3224, nv_ro32(dev, ramfc, 0x3c/4)); ++ nv_wr32(dev, 0x324c, nv_ro32(dev, ramfc, 0x40/4)); ++ nv_wr32(dev, 0x2044, nv_ro32(dev, ramfc, 0x44/4)); ++ nv_wr32(dev, 0x322c, nv_ro32(dev, ramfc, 0x48/4)); ++ nv_wr32(dev, 0x3234, nv_ro32(dev, ramfc, 0x4c/4)); ++ nv_wr32(dev, 0x3340, nv_ro32(dev, ramfc, 0x50/4)); ++ nv_wr32(dev, 0x3344, nv_ro32(dev, ramfc, 0x54/4)); ++ nv_wr32(dev, 0x3280, nv_ro32(dev, ramfc, 0x58/4)); ++ nv_wr32(dev, 0x3254, nv_ro32(dev, ramfc, 0x5c/4)); ++ nv_wr32(dev, 0x3260, nv_ro32(dev, ramfc, 0x60/4)); ++ nv_wr32(dev, 0x3264, nv_ro32(dev, ramfc, 0x64/4)); ++ nv_wr32(dev, 0x3268, nv_ro32(dev, ramfc, 0x68/4)); ++ nv_wr32(dev, 0x326c, nv_ro32(dev, ramfc, 0x6c/4)); ++ nv_wr32(dev, 0x32e4, nv_ro32(dev, ramfc, 0x70/4)); ++ nv_wr32(dev, 0x3248, nv_ro32(dev, ramfc, 0x74/4)); ++ nv_wr32(dev, 0x2088, nv_ro32(dev, ramfc, 0x78/4)); ++ nv_wr32(dev, 0x2058, nv_ro32(dev, ramfc, 0x7c/4)); ++ nv_wr32(dev, 0x2210, nv_ro32(dev, ramfc, 0x80/4)); ++ ++ cnt = nv_ro32(dev, ramfc, 0x84/4); ++ for (ptr = 0; ptr < cnt; ptr++) { ++ nv_wr32(dev, NV40_PFIFO_CACHE1_METHOD(ptr), ++ nv_ro32(dev, cache, (ptr * 2) + 0)); ++ nv_wr32(dev, NV40_PFIFO_CACHE1_DATA(ptr), ++ nv_ro32(dev, cache, (ptr * 2) + 1)); ++ } ++ nv_wr32(dev, 0x3210, cnt << 2); ++ nv_wr32(dev, 0x3270, 0); ++ ++ /* guessing that all the 0x34xx regs aren't on NV50 */ ++ if (!IS_G80) { ++ nv_wr32(dev, 0x340c, nv_ro32(dev, ramfc, 0x88/4)); ++ nv_wr32(dev, 0x3400, nv_ro32(dev, ramfc, 0x8c/4)); ++ nv_wr32(dev, 0x3404, nv_ro32(dev, ramfc, 0x90/4)); ++ nv_wr32(dev, 0x3408, nv_ro32(dev, ramfc, 0x94/4)); ++ nv_wr32(dev, 0x3410, nv_ro32(dev, ramfc, 0x98/4)); ++ } ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16)); ++ return 0; ++} ++ ++int ++nv50_fifo_unload_context(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; ++ struct nouveau_gpuobj *ramfc, *cache; ++ struct nouveau_channel *chan = NULL; ++ int chid, get, put, ptr; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ chid = pfifo->channel_id(dev); ++ if (chid < 0 || chid >= dev_priv->engine.fifo.channels) ++ return 0; ++ ++ chan = dev_priv->fifos[chid]; ++ if (!chan) { ++ NV_ERROR(dev, "Inactive channel on PFIFO: %d\n", chid); ++ return -EINVAL; ++ } ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ramfc = chan->ramfc->gpuobj; ++ cache = chan->cache->gpuobj; ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ ++ nv_wo32(dev, ramfc, 0x00/4, nv_rd32(dev, 0x3330)); ++ nv_wo32(dev, ramfc, 0x04/4, nv_rd32(dev, 0x3334)); ++ nv_wo32(dev, ramfc, 0x08/4, nv_rd32(dev, 0x3240)); ++ nv_wo32(dev, ramfc, 0x0c/4, nv_rd32(dev, 0x3320)); ++ nv_wo32(dev, ramfc, 0x10/4, nv_rd32(dev, 0x3244)); ++ nv_wo32(dev, ramfc, 0x14/4, nv_rd32(dev, 0x3328)); ++ nv_wo32(dev, ramfc, 0x18/4, nv_rd32(dev, 0x3368)); ++ nv_wo32(dev, ramfc, 0x1c/4, nv_rd32(dev, 0x336c)); ++ nv_wo32(dev, ramfc, 0x20/4, nv_rd32(dev, 0x3370)); ++ nv_wo32(dev, ramfc, 0x24/4, nv_rd32(dev, 0x3374)); ++ nv_wo32(dev, ramfc, 0x28/4, nv_rd32(dev, 0x3378)); ++ nv_wo32(dev, ramfc, 0x2c/4, nv_rd32(dev, 0x337c)); ++ nv_wo32(dev, ramfc, 0x30/4, nv_rd32(dev, 0x3228)); ++ nv_wo32(dev, ramfc, 0x34/4, nv_rd32(dev, 0x3364)); ++ nv_wo32(dev, ramfc, 0x38/4, nv_rd32(dev, 0x32a0)); ++ nv_wo32(dev, ramfc, 0x3c/4, nv_rd32(dev, 0x3224)); ++ nv_wo32(dev, ramfc, 0x40/4, nv_rd32(dev, 0x324c)); ++ nv_wo32(dev, ramfc, 0x44/4, nv_rd32(dev, 0x2044)); ++ nv_wo32(dev, ramfc, 0x48/4, nv_rd32(dev, 0x322c)); ++ nv_wo32(dev, ramfc, 0x4c/4, nv_rd32(dev, 0x3234)); ++ nv_wo32(dev, ramfc, 0x50/4, nv_rd32(dev, 0x3340)); ++ nv_wo32(dev, ramfc, 0x54/4, nv_rd32(dev, 0x3344)); ++ nv_wo32(dev, ramfc, 0x58/4, nv_rd32(dev, 0x3280)); ++ nv_wo32(dev, ramfc, 0x5c/4, nv_rd32(dev, 0x3254)); ++ nv_wo32(dev, ramfc, 0x60/4, nv_rd32(dev, 0x3260)); ++ nv_wo32(dev, ramfc, 0x64/4, nv_rd32(dev, 0x3264)); ++ nv_wo32(dev, ramfc, 0x68/4, nv_rd32(dev, 0x3268)); ++ nv_wo32(dev, ramfc, 0x6c/4, nv_rd32(dev, 0x326c)); ++ nv_wo32(dev, ramfc, 0x70/4, nv_rd32(dev, 0x32e4)); ++ nv_wo32(dev, ramfc, 0x74/4, nv_rd32(dev, 0x3248)); ++ nv_wo32(dev, ramfc, 0x78/4, nv_rd32(dev, 0x2088)); ++ nv_wo32(dev, ramfc, 0x7c/4, nv_rd32(dev, 0x2058)); ++ nv_wo32(dev, ramfc, 0x80/4, nv_rd32(dev, 0x2210)); ++ ++ put = (nv_rd32(dev, NV03_PFIFO_CACHE1_PUT) & 0x7ff) >> 2; ++ get = (nv_rd32(dev, NV03_PFIFO_CACHE1_GET) & 0x7ff) >> 2; ++ ptr = 0; ++ while (put != get) { ++ nv_wo32(dev, cache, ptr++, ++ nv_rd32(dev, NV40_PFIFO_CACHE1_METHOD(get))); ++ nv_wo32(dev, cache, ptr++, ++ nv_rd32(dev, NV40_PFIFO_CACHE1_DATA(get))); ++ get = (get + 1) & 0x1ff; ++ } ++ ++ /* guessing that all the 0x34xx regs aren't on NV50 */ ++ if (!IS_G80) { ++ nv_wo32(dev, ramfc, 0x84/4, ptr >> 1); ++ nv_wo32(dev, ramfc, 0x88/4, nv_rd32(dev, 0x340c)); ++ nv_wo32(dev, ramfc, 0x8c/4, nv_rd32(dev, 0x3400)); ++ nv_wo32(dev, ramfc, 0x90/4, nv_rd32(dev, 0x3404)); ++ nv_wo32(dev, ramfc, 0x94/4, nv_rd32(dev, 0x3408)); ++ nv_wo32(dev, ramfc, 0x98/4, nv_rd32(dev, 0x3410)); ++ } ++ ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ /*XXX: probably reload ch127 (NULL) state back too */ ++ nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, 127); ++ return 0; ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c +new file mode 100644 +index 0000000..eef3ebd +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_graph.c +@@ -0,0 +1,479 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++#include "nv50_grctx.h" ++ ++#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) ++ ++static void ++nv50_graph_init_reset(struct drm_device *dev) ++{ ++ uint32_t pmc_e = NV_PMC_ENABLE_PGRAPH | (1 << 21); ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e); ++ nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | pmc_e); ++} ++ ++static void ++nv50_graph_init_intr(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(dev, NV03_PGRAPH_INTR, 0xffffffff); ++ nv_wr32(dev, 0x400138, 0xffffffff); ++ nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xffffffff); ++} ++ ++static void ++nv50_graph_init_regs__nv(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(dev, 0x400804, 0xc0000000); ++ nv_wr32(dev, 0x406800, 0xc0000000); ++ nv_wr32(dev, 0x400c04, 0xc0000000); ++ nv_wr32(dev, 0x401804, 0xc0000000); ++ nv_wr32(dev, 0x405018, 0xc0000000); ++ nv_wr32(dev, 0x402000, 0xc0000000); ++ ++ nv_wr32(dev, 0x400108, 0xffffffff); ++ ++ nv_wr32(dev, 0x400824, 0x00004000); ++ nv_wr32(dev, 0x400500, 0x00010001); ++} ++ ++static void ++nv50_graph_init_regs(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++ ++ nv_wr32(dev, NV04_PGRAPH_DEBUG_3, ++ (1 << 2) /* HW_CONTEXT_SWITCH_ENABLED */); ++ nv_wr32(dev, 0x402ca8, 0x800); ++} ++ ++static int ++nv50_graph_init_ctxctl(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t *voodoo = NULL; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ switch (dev_priv->chipset) { ++ case 0x50: ++ voodoo = nv50_ctxprog; ++ break; ++ case 0x84: ++ voodoo = nv84_ctxprog; ++ break; ++ case 0x86: ++ voodoo = nv86_ctxprog; ++ break; ++ case 0x92: ++ voodoo = nv92_ctxprog; ++ break; ++ case 0x94: ++ case 0x96: ++ voodoo = nv94_ctxprog; ++ break; ++ case 0x98: ++ voodoo = nv98_ctxprog; ++ break; ++ case 0xa0: ++ voodoo = nva0_ctxprog; ++ break; ++ case 0xa5: ++ voodoo = nva5_ctxprog; ++ break; ++ case 0xa8: ++ voodoo = nva8_ctxprog; ++ break; ++ case 0xaa: ++ voodoo = nvaa_ctxprog; ++ break; ++#if 0 /* block accel for now, it won't work */ ++ case 0xac: ++ voodoo = nvac_ctxprog; ++ break; ++#endif ++ default: ++ NV_ERROR(dev, "no ctxprog for chipset NV%02x\n", dev_priv->chipset); ++ dev_priv->engine.graph.accel_blocked = true; ++ break; ++ } ++ ++ if (voodoo) { ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); ++ while (*voodoo != ~0) { ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, *voodoo); ++ voodoo++; ++ } ++ } ++ ++ nv_wr32(dev, 0x400320, 4); ++ nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); ++ nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, 0); ++ ++ return 0; ++} ++ ++int ++nv50_graph_init(struct drm_device *dev) ++{ ++ int ret; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ nv50_graph_init_reset(dev); ++ nv50_graph_init_regs__nv(dev); ++ nv50_graph_init_regs(dev); ++ nv50_graph_init_intr(dev); ++ ++ ret = nv50_graph_init_ctxctl(dev); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++void ++nv50_graph_takedown(struct drm_device *dev) ++{ ++ NV_DEBUG(dev, "\n"); ++} ++ ++void ++nv50_graph_fifo_access(struct drm_device *dev, bool enabled) ++{ ++ const uint32_t mask = 0x00010001; ++ ++ if (enabled) ++ nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | mask); ++ else ++ nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) & ~mask); ++} ++ ++struct nouveau_channel * ++nv50_graph_channel(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ uint32_t inst; ++ int i; ++ ++ inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR); ++ if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED)) ++ return NULL; ++ inst = (inst & NV50_PGRAPH_CTXCTL_CUR_INSTANCE) << 12; ++ ++ for (i = 0; i < dev_priv->engine.fifo.channels; i++) { ++ struct nouveau_channel *chan = dev_priv->fifos[i]; ++ ++ if (chan && chan->ramin && chan->ramin->instance == inst) ++ return chan; ++ } ++ ++ return NULL; ++} ++ ++int ++nv50_graph_create_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; ++ struct nouveau_gpuobj *ctx; ++ uint32_t *ctxvals = NULL; ++ uint32_t grctx_size = 0x70000; ++ int hdr; ++ int ret; ++ int pos; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, grctx_size, 0x1000, ++ NVOBJ_FLAG_ZERO_ALLOC | ++ NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); ++ if (ret) ++ return ret; ++ ctx = chan->ramin_grctx->gpuobj; ++ ++ hdr = IS_G80 ? 0x200 : 0x20; ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002); ++ nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance + ++ grctx_size - 1); ++ nv_wo32(dev, ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance); ++ nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0); ++ nv_wo32(dev, ramin, (hdr + 0x10)/4, 0); ++ nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ switch (dev_priv->chipset) { ++ case 0x50: ++ ctxvals = nv50_ctxvals; ++ break; ++ case 0x84: ++ ctxvals = nv84_ctxvals; ++ break; ++ case 0x86: ++ ctxvals = nv86_ctxvals; ++ break; ++ case 0x92: ++ ctxvals = nv92_ctxvals; ++ break; ++ case 0x94: ++ ctxvals = nv94_ctxvals; ++ break; ++ case 0x96: ++ ctxvals = nv96_ctxvals; ++ break; ++ case 0x98: ++ ctxvals = nv98_ctxvals; ++ break; ++ case 0xa0: ++ ctxvals = nva0_ctxvals; ++ break; ++ case 0xa5: ++ ctxvals = nva5_ctxvals; ++ break; ++ case 0xa8: ++ ctxvals = nva8_ctxvals; ++ break; ++ case 0xaa: ++ ctxvals = nvaa_ctxvals; ++ break; ++#if 0 /* block accel for now, it won't work */ ++ case 0xac: ++ ctxvals = nvac_ctxvals; ++ break; ++#endif ++ default: ++ break; ++ } ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ ++ if (ctxvals) { ++ pos = 0; ++ while (*ctxvals) { ++ int cnt = *ctxvals++; ++ ++ while (cnt--) ++ nv_wo32(dev, ctx, pos++, *ctxvals); ++ ctxvals++; ++ } ++ } ++ ++ nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); ++ if ((dev_priv->chipset & 0xf0) == 0xa0) ++ nv_wo32(dev, ctx, 0x00004/4, 0x00000000); ++ else ++ nv_wo32(dev, ctx, 0x0011c/4, 0x00000000); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ return 0; ++} ++ ++void ++nv50_graph_destroy_context(struct nouveau_channel *chan) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ int i, hdr = IS_G80 ? 0x200 : 0x20; ++ ++ NV_DEBUG(dev, "ch%d\n", chan->id); ++ ++ if (!chan->ramin || !chan->ramin->gpuobj) ++ return; ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ for (i = hdr; i < hdr + 24; i += 4) ++ nv_wo32(dev, chan->ramin->gpuobj, i/4, 0); ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); ++} ++ ++static int ++nv50_graph_do_load_context(struct drm_device *dev, uint32_t inst) ++{ ++ uint32_t fifo = nv_rd32(dev, 0x400500); ++ ++ nv_wr32(dev, 0x400500, fifo & ~1); ++ nv_wr32(dev, 0x400784, inst); ++ nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x40); ++ nv_wr32(dev, 0x400320, nv_rd32(dev, 0x400320) | 0x11); ++ nv_wr32(dev, 0x400040, 0xffffffff); ++ (void)nv_rd32(dev, 0x400040); ++ nv_wr32(dev, 0x400040, 0x00000000); ++ nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 1); ++ ++ if (nouveau_wait_for_idle(dev)) ++ nv_wr32(dev, 0x40032c, inst | (1<<31)); ++ nv_wr32(dev, 0x400500, fifo); ++ ++ return 0; ++} ++ ++int ++nv50_graph_load_context(struct nouveau_channel *chan) ++{ ++ uint32_t inst = chan->ramin->instance >> 12; ++ ++ NV_DEBUG(chan->dev, "ch%d\n", chan->id); ++ return nv50_graph_do_load_context(chan->dev, inst); ++} ++ ++static int ++nv50_graph_do_save_context(struct drm_device *dev, uint32_t inst) ++{ ++ uint32_t fifo = nv_rd32(dev, 0x400500); ++ ++ nv_wr32(dev, 0x400500, fifo & ~1); ++ nv_wr32(dev, 0x400784, inst); ++ nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x20); ++ nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 0x01); ++ nouveau_wait_for_idle(dev); ++ ++ nv_wr32(dev, 0x400500, fifo); ++ return 0; ++} ++ ++int ++nv50_graph_unload_context(struct drm_device *dev) ++{ ++ uint32_t inst; ++ int ret; ++ ++ inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR); ++ if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED)) ++ return 0; ++ inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE; ++ ret = nv50_graph_do_save_context(dev, inst); ++ nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst); ++ return 0; ++} ++ ++void ++nv50_graph_context_switch(struct drm_device *dev) ++{ ++ uint32_t inst; ++ ++ nv50_graph_unload_context(dev); ++ ++ inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_NEXT); ++ inst &= NV50_PGRAPH_CTXCTL_NEXT_INSTANCE; ++ nv50_graph_do_load_context(dev, inst); ++ ++ nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev, ++ NV40_PGRAPH_INTR_EN) | NV_PGRAPH_INTR_CONTEXT_SWITCH); ++} ++ ++static int ++nv50_graph_nvsw_dma_vblsem(struct nouveau_channel *chan, int grclass, ++ int mthd, uint32_t data) ++{ ++ struct nouveau_gpuobj_ref *ref = NULL; ++ ++ if (nouveau_gpuobj_ref_find(chan, data, &ref)) ++ return -ENOENT; ++ ++ if (nouveau_notifier_offset(ref->gpuobj, NULL)) ++ return -EINVAL; ++ ++ chan->nvsw.vblsem = ref->gpuobj; ++ chan->nvsw.vblsem_offset = ~0; ++ return 0; ++} ++ ++static int ++nv50_graph_nvsw_vblsem_offset(struct nouveau_channel *chan, int grclass, ++ int mthd, uint32_t data) ++{ ++ if (nouveau_notifier_offset(chan->nvsw.vblsem, &data)) ++ return -ERANGE; ++ ++ chan->nvsw.vblsem_offset = data >> 2; ++ return 0; ++} ++ ++static int ++nv50_graph_nvsw_vblsem_release_val(struct nouveau_channel *chan, int grclass, ++ int mthd, uint32_t data) ++{ ++ chan->nvsw.vblsem_rval = data; ++ return 0; ++} ++ ++static int ++nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, int grclass, ++ int mthd, uint32_t data) ++{ ++ struct drm_device *dev = chan->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (!chan->nvsw.vblsem || chan->nvsw.vblsem_offset == ~0 || data > 1) ++ return -EINVAL; ++ ++ if (!(nv_rd32(dev, NV50_PDISPLAY_INTR_EN) & ++ NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data))) { ++ nv_wr32(dev, NV50_PDISPLAY_INTR_1, ++ NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(data)); ++ nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev, ++ NV50_PDISPLAY_INTR_EN) | ++ NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data)); ++ } ++ ++ list_add(&chan->nvsw.vbl_wait, &dev_priv->vbl_waiting); ++ return 0; ++} ++ ++static struct nouveau_pgraph_object_method nv50_graph_nvsw_methods[] = { ++ { 0x018c, nv50_graph_nvsw_dma_vblsem }, ++ { 0x0400, nv50_graph_nvsw_vblsem_offset }, ++ { 0x0404, nv50_graph_nvsw_vblsem_release_val }, ++ { 0x0408, nv50_graph_nvsw_vblsem_release }, ++ {} ++}; ++ ++struct nouveau_pgraph_object_class nv50_graph_grclass[] = { ++ { 0x506e, true, nv50_graph_nvsw_methods }, /* nvsw */ ++ { 0x0030, false, NULL }, /* null */ ++ { 0x5039, false, NULL }, /* m2mf */ ++ { 0x502d, false, NULL }, /* 2d */ ++ { 0x50c0, false, NULL }, /* compute */ ++ { 0x5097, false, NULL }, /* tesla (nv50) */ ++ { 0x8297, false, NULL }, /* tesla (nv80/nv90) */ ++ { 0x8397, false, NULL }, /* tesla (nva0) */ ++ { 0x8597, false, NULL }, /* tesla (nva8) */ ++ {} ++}; +diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.h b/drivers/gpu/drm/nouveau/nv50_grctx.h +new file mode 100644 +index 0000000..a5fd0e9 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_grctx.h +@@ -0,0 +1,26832 @@ ++#ifndef __NV50_GRCTX_H__ ++#define __NV50_GRCTX_H__ ++ ++static uint32_t nv50_ctxprog[] = { ++ 0x0070008e, 0x0070009c, 0x00200020, 0x00600008, 0x0050004c, 0x00400e89, ++ 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, 0x008000ff, ++ 0x00700009, 0x0041874d, 0x00401e44, 0x00401e05, 0x00401e0d, 0x00416306, ++ 0x00600005, 0x004015c5, 0x00600011, 0x00401c0b, 0x0090ffff, 0x0091ffff, ++ 0x00200020, 0x00600008, 0x0050004c, 0x00600009, 0x00416345, 0x00417e4d, ++ 0x0070009d, 0x004022cf, 0x0070009f, 0x0050009f, 0x00401fc0, 0x00200080, ++ 0x00600008, 0x00401f4f, 0x00401fc0, 0x004025cc, 0x00700081, 0x00200000, ++ 0x00600006, 0x00700000, 0x00111bfc, 0x00700083, 0x00300000, 0x00215900, ++ 0x00600007, 0x00c00b01, 0x0020001c, 0x00800001, 0x005000cb, 0x00c000ff, ++ 0x00700080, 0x00700083, 0x00200047, 0x00600006, 0x0011020a, 0x002005c0, ++ 0x00600007, 0x00300000, 0x00c000ff, 0x00c800ff, 0x00416e07, 0x00202627, ++ 0x008000ff, 0x0040458c, 0x005000cb, 0x00a0023f, 0x00200040, 0x00600006, ++ 0x0070000f, 0x00170202, 0x0011020a, 0x00200032, 0x0010020d, 0x001b0242, ++ 0x00120302, 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, ++ 0x001e0607, 0x00110700, 0x00110900, 0x00110902, 0x00110a00, 0x00160b02, ++ 0x00110b28, 0x00140b2b, 0x00110c01, 0x00111400, 0x00111405, 0x00111407, ++ 0x00111409, 0x0011140b, 0x002000ea, 0x00101500, 0x00406d0f, 0x00406d4b, ++ 0x00213700, 0x00600007, 0x00200440, 0x008800ff, 0x0070008f, 0x00406d8c, ++ 0x005000cb, 0x00000000, 0x001118f8, 0x0020002b, 0x00101a05, 0x00131c00, ++ 0x00111c04, 0x00141c20, 0x00111c25, 0x00131c40, 0x00111c44, 0x00141c60, ++ 0x00111c65, 0x00131c80, 0x00111c84, 0x00141ca0, 0x00111ca5, 0x00131cc0, ++ 0x00111cc4, 0x00141ce0, 0x00111ce5, 0x00131d00, 0x00111d04, 0x00141d20, ++ 0x00111d25, 0x00131d40, 0x00111d44, 0x00141d60, 0x00111d65, 0x00131f00, ++ 0x00191f40, 0x0040a7e0, 0x00200217, 0x00600006, 0x00200044, 0x00102080, ++ 0x001120c6, 0x001520c9, 0x001920d0, 0x00122100, 0x00122103, 0x00162200, ++ 0x00409f0f, 0x00409f4b, 0x00213700, 0x00600007, 0x00200440, 0x008800ff, ++ 0x0070008f, 0x00409f8c, 0x005000cb, 0x00000000, 0x00122207, 0x00112280, ++ 0x00112300, 0x00112302, 0x00122380, 0x0011238b, 0x00192394, 0x0040b9e1, ++ 0x00200285, 0x00600006, 0x00200044, 0x00102480, 0x001124c6, 0x001524c9, ++ 0x001924d0, 0x00122500, 0x00122503, 0x00162600, 0x00122607, 0x00112680, ++ 0x00112700, 0x00112702, 0x00122780, 0x0011278b, 0x00192794, 0x0040d5e2, ++ 0x002002f3, 0x00600006, 0x00200044, 0x00102880, 0x001128c6, 0x001528c9, ++ 0x0040c90f, 0x0040c94b, 0x00213700, 0x00600007, 0x00200440, 0x008800ff, ++ 0x0070008f, 0x0040c98c, 0x005000cb, 0x00000000, 0x001928d0, 0x00122900, ++ 0x00122903, 0x00162a00, 0x00122a07, 0x00112a80, 0x00112b00, 0x00112b02, ++ 0x00122b80, 0x00112b8b, 0x00192b94, 0x0040e7e3, 0x00200361, 0x00600006, ++ 0x00200044, 0x00102c80, 0x00112cc6, 0x00152cc9, 0x00192cd0, 0x00122d00, ++ 0x00122d03, 0x00162e00, 0x00122e07, 0x00112e80, 0x00112f00, 0x00112f02, ++ 0x00122f80, 0x00112f8b, 0x00192f94, 0x004103e4, 0x002003cf, 0x00600006, ++ 0x00200044, 0x00103080, 0x0040f50f, 0x0040f54b, 0x00213700, 0x00600007, ++ 0x00200440, 0x008800ff, 0x0070008f, 0x0040f58c, 0x005000cb, 0x00000000, ++ 0x001130c6, 0x001530c9, 0x001930d0, 0x00123100, 0x00123103, 0x00163200, ++ 0x00123207, 0x00113280, 0x00113300, 0x00113302, 0x00123380, 0x0011338b, ++ 0x00193394, 0x004115e5, 0x0020043d, 0x00600006, 0x00200044, 0x00103480, ++ 0x001134c6, 0x001534c9, 0x001934d0, 0x00123500, 0x00123503, 0x00163600, ++ 0x00123607, 0x00113680, 0x00113700, 0x00113702, 0x00123780, 0x0011378b, ++ 0x00193794, 0x004131e6, 0x002004ab, 0x00600006, 0x00200044, 0x00103880, ++ 0x0041230f, 0x0041234b, 0x00213700, 0x00600007, 0x00200440, 0x008800ff, ++ 0x0070008f, 0x0041238c, 0x005000cb, 0x00000000, 0x001138c6, 0x001538c9, ++ 0x001938d0, 0x00123900, 0x00123903, 0x00163a00, 0x00123a07, 0x00113a80, ++ 0x00113b00, 0x00113b02, 0x00123b80, 0x00113b8b, 0x00193b94, 0x004143e7, ++ 0x00200519, 0x00600006, 0x00200044, 0x00103c80, 0x00113cc6, 0x00153cc9, ++ 0x00193cd0, 0x00123d00, 0x00123d03, 0x00163e00, 0x00123e07, 0x00113e80, ++ 0x00113f00, 0x00113f02, 0x00123f80, 0x00113f8b, 0x00193f94, 0x00000000, ++ 0x00414a0f, 0x005000cb, 0x00213700, 0x00600007, 0x00200440, 0x008800ff, ++ 0x005000cb, 0x00414d87, 0x0060000a, 0x00000000, 0x00415c00, 0x007000a0, ++ 0x00700080, 0x002005c0, 0x00600007, 0x00200004, 0x00c000ff, 0x008000ff, ++ 0x005000cb, 0x00700000, 0x00200000, 0x00600006, 0x00111bfe, 0x00417e4d, ++ 0x00700000, 0x00200000, 0x00600006, 0x00111bfe, 0x00700080, 0x0070001d, ++ 0x0040114d, 0x00700081, 0x00600004, 0x0050004a, 0x00416888, 0x0060000b, ++ 0x00200000, 0x00600006, 0x00700000, 0x00417e0b, 0x00111bfd, 0x0040374d, ++ 0x00202627, 0x008000fd, 0x005000cb, 0x00c00002, 0x002005c0, 0x00600007, ++ 0x0020015f, 0x00800002, 0x005000cb, 0x00c01802, 0x002024c8, 0x00800002, ++ 0x005000cb, 0x0040434d, 0x0060000b, 0x00417c4d, 0x00700001, 0x00700003, ++ 0x00418206, 0x00418305, 0x0060000d, 0x00700005, 0x0070000d, 0x00700006, ++ 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ~0 ++}; ++ ++static uint32_t nv50_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0004, 0x00000000, ++ 0x0001, 0xff400040, ++ 0x0001, 0xfff00080, ++ 0x0001, 0xfff70090, ++ 0x0001, 0xffe806a8, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000e, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x0001fd87, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x0001005f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0001, 0x00000006, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00300080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000000a, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000026, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000f80, ++ 0x0011, 0x00000000, ++ 0x0001, 0x007f0080, ++ 0x000e, 0x00000000, ++ 0x0001, 0x007f0080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x1b74f820, ++ 0x0001, 0x89058001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x000000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x1b74f820, ++ 0x0001, 0x89058001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x000000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x1b74f820, ++ 0x0001, 0x89058001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x000000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x1b74f820, ++ 0x0001, 0x89058001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x000000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x1b74f820, ++ 0x0001, 0x89058001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x000000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x1b74f820, ++ 0x0001, 0x89058001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x000000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00010040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00010040, ++ 0x0001, 0x00000022, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00080000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x00000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00007070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x00007fff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0002, 0x00000003, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x0000001f, ++ 0x0002, 0x0000000f, ++ 0x0046, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00608080, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0055, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0049, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0040, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x03020100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0013, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0004, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0004, 0x00000003, ++ 0x0003, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0004, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x001c, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0099, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0061, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00003e60, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1905, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0032, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0077, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x0032, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0029, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0011, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x002a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0011, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0011, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0001, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0054, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x003c, 0x00000000, ++ 0x0004, 0x00003e60, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x002c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x001a, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0004, 0x000003ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x00ea, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0061, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x000a, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x001e, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000020, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00003e60, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x004c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00003e60, ++ 0x0002, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0019, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x2a712488, ++ 0x000c, 0x00000000, ++ 0x0004, 0x4085c000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x02800000, ++ 0x007c, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x30201000, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0004, 0x70605040, ++ 0x0004, 0x00000000, ++ 0x0004, 0xb8a89888, ++ 0x0004, 0x00000000, ++ 0x0004, 0xf8e8d8c8, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0004, 0x0000001a, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x00ac, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00608080, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x008a, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0079, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x03020100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0012, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x012a, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000003ff, ++ 0x2a17, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x2321, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x008c, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x005c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x002c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0064, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0054, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x003c, 0x00000000, ++ 0x0004, 0x00003e60, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x002c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x000003ff, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0154, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x003c, 0x00000000, ++ 0x0004, 0x00000020, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00003e60, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x004c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x00bc, 0x00000000, ++ 0x0004, 0x00003e60, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x2a712488, ++ 0x000c, 0x00000000, ++ 0x0004, 0x4085c000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x02800000, ++ 0x007c, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x30201000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x70605040, ++ 0x0004, 0x00000000, ++ 0x0004, 0xb8a89888, ++ 0x0004, 0x00000000, ++ 0x0004, 0xf8e8d8c8, ++ 0x000c, 0x00000000, ++ 0x0004, 0x0000001a, ++ 0x4c70, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0087, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000080, ++ 0x0008, 0x80007004, ++ 0x0008, 0x04000400, ++ 0x0008, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0010, 0x00001000, ++ 0x0008, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x0008, 0x00000002, ++ 0x0058, 0x00000000, ++ 0x0008, 0x00000080, ++ 0x0008, 0x80007004, ++ 0x0008, 0x04000400, ++ 0x0008, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0010, 0x00001000, ++ 0x0008, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x0008, 0x00000002, ++ 0x0050, 0x00000000, ++ 0x0008, 0x08100c12, ++ 0x0030, 0x00000000, ++ 0x0020, 0x0000ffff, ++ 0x0008, 0x00000001, ++ 0x0010, 0x00010001, ++ 0x0008, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0008, 0x08100c12, ++ 0x0008, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000002, ++ 0x0008, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0008, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0008, 0x00000002, ++ 0x0010, 0x00000001, ++ 0x0008, 0x00000002, ++ 0x0018, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x1d00, 0x00000000, ++ 0x0008, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nv84_ctxprog[] = { ++ 0x0070008e, 0x0070009c, 0x00200020, 0x00600008, 0x0050004c, 0x00400e89, ++ 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, 0x008000ff, ++ 0x00700009, 0x0041634d, 0x00402944, 0x00402905, 0x0040290d, 0x00413e06, ++ 0x00600005, 0x004015c5, 0x00600011, 0x0040270b, 0x004021c5, 0x00700000, ++ 0x00700081, 0x00600004, 0x0050004a, 0x00216f40, 0x00600007, 0x00c02801, ++ 0x0020002e, 0x00800001, 0x005000cb, 0x0090ffff, 0x0091ffff, 0x00200020, ++ 0x00600008, 0x0050004c, 0x00600009, 0x00413e45, 0x0041594d, 0x0070009d, ++ 0x00402dcf, 0x0070009f, 0x0050009f, 0x00402ac0, 0x00200200, 0x00600008, ++ 0x00402a4f, 0x00402ac0, 0x004030cc, 0x00700081, 0x00200000, 0x00600006, ++ 0x00700000, 0x00111bfc, 0x00700083, 0x00300000, 0x00216f40, 0x00600007, ++ 0x00c00b01, 0x0020001e, 0x00800001, 0x005000cb, 0x00c000ff, 0x00700080, ++ 0x00700083, 0x00200047, 0x00600006, 0x0011020a, 0x00200480, 0x00600007, ++ 0x00300000, 0x00c000ff, 0x00c800ff, 0x00414907, 0x00202916, 0x008000ff, ++ 0x0040508c, 0x005000cb, 0x00a0023f, 0x00200040, 0x00600006, 0x0070000f, ++ 0x00170202, 0x0011020a, 0x00200032, 0x0010020d, 0x001c0242, 0x00120302, ++ 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, 0x0020000f, ++ 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110a00, 0x00160b02, ++ 0x00120b28, 0x00140b2b, 0x00110c01, 0x00111400, 0x00111405, 0x00111407, ++ 0x00111409, 0x0011140b, 0x002000cb, 0x00101500, 0x0040790f, 0x0040794b, ++ 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x0070008f, 0x0040798c, ++ 0x005000cb, 0x00000000, 0x0020002b, 0x00101a05, 0x00131c00, 0x00121c04, ++ 0x00141c20, 0x00111c25, 0x00131c40, 0x00121c44, 0x00141c60, 0x00111c65, ++ 0x00131c80, 0x00121c84, 0x00141ca0, 0x00111ca5, 0x00131cc0, 0x00121cc4, ++ 0x00141ce0, 0x00111ce5, 0x00131f00, 0x00191f40, 0x0040a1e0, 0x002001ed, ++ 0x00600006, 0x00200044, 0x00102080, 0x001120c6, 0x001520c9, 0x001920d0, ++ 0x00122100, 0x00122103, 0x00162200, 0x00122207, 0x00112280, 0x00112300, ++ 0x00112302, 0x00122380, 0x0011238b, 0x00112394, 0x0011239c, 0x0040bee1, ++ 0x00200254, 0x00600006, 0x00200044, 0x00102480, 0x0040af0f, 0x0040af4b, ++ 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x0070008f, 0x0040af8c, ++ 0x005000cb, 0x00000000, 0x001124c6, 0x001524c9, 0x001924d0, 0x00122500, ++ 0x00122503, 0x00162600, 0x00122607, 0x00112680, 0x00112700, 0x00112702, ++ 0x00122780, 0x0011278b, 0x00112794, 0x0011279c, 0x0040d1e2, 0x002002bb, ++ 0x00600006, 0x00200044, 0x00102880, 0x001128c6, 0x001528c9, 0x001928d0, ++ 0x00122900, 0x00122903, 0x00162a00, 0x00122a07, 0x00112a80, 0x00112b00, ++ 0x00112b02, 0x00122b80, 0x00112b8b, 0x00112b94, 0x00112b9c, 0x0040eee3, ++ 0x00200322, 0x00600006, 0x00200044, 0x00102c80, 0x0040df0f, 0x0040df4b, ++ 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x0070008f, 0x0040df8c, ++ 0x005000cb, 0x00000000, 0x00112cc6, 0x00152cc9, 0x00192cd0, 0x00122d00, ++ 0x00122d03, 0x00162e00, 0x00122e07, 0x00112e80, 0x00112f00, 0x00112f02, ++ 0x00122f80, 0x00112f8b, 0x00112f94, 0x00112f9c, 0x004101e4, 0x00200389, ++ 0x00600006, 0x00200044, 0x00103080, 0x001130c6, 0x001530c9, 0x001930d0, ++ 0x00123100, 0x00123103, 0x00163200, 0x00123207, 0x00113280, 0x00113300, ++ 0x00113302, 0x00123380, 0x0011338b, 0x00113394, 0x0011339c, 0x00411ee5, ++ 0x002003f0, 0x00600006, 0x00200044, 0x00103480, 0x00410f0f, 0x00410f4b, ++ 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x0070008f, 0x00410f8c, ++ 0x005000cb, 0x00000000, 0x001134c6, 0x001534c9, 0x001934d0, 0x00123500, ++ 0x00123503, 0x00163600, 0x00123607, 0x00113680, 0x00113700, 0x00113702, ++ 0x00123780, 0x0011378b, 0x00113794, 0x0011379c, 0x00000000, 0x0041250f, ++ 0x005000cb, 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x005000cb, ++ 0x00412887, 0x0060000a, 0x00000000, 0x00413700, 0x007000a0, 0x00700080, ++ 0x00200480, 0x00600007, 0x00200004, 0x00c000ff, 0x008000ff, 0x005000cb, ++ 0x00700000, 0x00200000, 0x00600006, 0x00111bfe, 0x0041594d, 0x00700000, ++ 0x00200000, 0x00600006, 0x00111bfe, 0x00700080, 0x0070001d, 0x0040114d, ++ 0x00700081, 0x00600004, 0x0050004a, 0x00414388, 0x0060000b, 0x00200000, ++ 0x00600006, 0x00700000, 0x0041590b, 0x00111bfd, 0x0040424d, 0x00202916, ++ 0x008000fd, 0x005000cb, 0x00c00002, 0x00200480, 0x00600007, 0x00200160, ++ 0x00800002, 0x005000cb, 0x00c01802, 0x002027b6, 0x00800002, 0x005000cb, ++ 0x00404e4d, 0x0060000b, 0x0041574d, 0x00700001, 0x005000cf, 0x00700003, ++ 0x00415e06, 0x00415f05, 0x0060000d, 0x00700005, 0x0070000d, 0x00700006, ++ 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ~0 ++}; ++ ++static uint32_t nv84_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x044d00df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000e0080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000f80, ++ 0x0011, 0x00000000, ++ 0x0001, 0x007f0080, ++ 0x000e, 0x00000000, ++ 0x0001, 0x007f0080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00010040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00010040, ++ 0x0001, 0x00000022, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05100202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05100202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05100202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05100202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05100202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x00880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05100202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0038, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0014, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00608080, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0055, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0049, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0038, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0026, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0c04, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x2647, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0c78, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x001a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0077, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0035, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0029, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x002d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0041, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001d, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00dc, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000e, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000003, ++ 0x0049, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0019, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0045, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0019, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0097, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0035, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0061, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00608080, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00fd, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0035, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x4a17, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0291, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x008f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0157, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00bf, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0097, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x637b, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0067, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0001, 0x80007004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0001, 0x04000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0001, 0x00001000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0058, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0001, 0x80007004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0001, 0x04000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0001, 0x00001000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0050, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0006, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0030, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00010001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0006, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d10, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nv86_ctxprog[] = { ++ 0x0070008e, 0x0070009c, 0x00200020, 0x00600008, 0x0050004c, 0x00400e89, ++ 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, 0x008000ff, ++ 0x00700009, 0x0040dd4d, 0x00402944, 0x00402905, 0x0040290d, 0x0040b906, ++ 0x00600005, 0x004015c5, 0x00600011, 0x0040270b, 0x004021c5, 0x00700000, ++ 0x00700081, 0x00600004, 0x0050004a, 0x00216d80, 0x00600007, 0x00c02801, ++ 0x0020002e, 0x00800001, 0x005000cb, 0x0090ffff, 0x0091ffff, 0x00200020, ++ 0x00600008, 0x0050004c, 0x00600009, 0x0040b945, 0x0040d44d, 0x0070009d, ++ 0x00402dcf, 0x0070009f, 0x0050009f, 0x00402ac0, 0x00200200, 0x00600008, ++ 0x00402a4f, 0x00402ac0, 0x004030cc, 0x00700081, 0x00200000, 0x00600006, ++ 0x00700000, 0x00111bfc, 0x00700083, 0x00300000, 0x00216d80, 0x00600007, ++ 0x00c00b01, 0x0020001e, 0x00800001, 0x005000cb, 0x00c000ff, 0x00700080, ++ 0x00700083, 0x00200047, 0x00600006, 0x0011020a, 0x00200280, 0x00600007, ++ 0x00300000, 0x00c000ff, 0x00c800ff, 0x0040c407, 0x00202916, 0x008000ff, ++ 0x0040508c, 0x005000cb, 0x00a0023f, 0x00200040, 0x00600006, 0x0070000f, ++ 0x00170202, 0x0011020a, 0x00200032, 0x0010020d, 0x001c0242, 0x00120302, ++ 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, 0x0020000f, ++ 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110a00, 0x00160b02, ++ 0x00120b28, 0x00140b2b, 0x00110c01, 0x00111400, 0x00111405, 0x00111407, ++ 0x00111409, 0x0011140b, 0x002000cb, 0x00101500, 0x0040790f, 0x0040794b, ++ 0x00214b40, 0x00600007, 0x00200442, 0x008800ff, 0x0070008f, 0x0040798c, ++ 0x005000cb, 0x00000000, 0x0020002b, 0x00101a05, 0x00131c00, 0x00121c04, ++ 0x00141c20, 0x00111c25, 0x00131c40, 0x00121c44, 0x00141c60, 0x00111c65, ++ 0x00131f00, 0x00191f40, 0x004099e0, 0x002001d9, 0x00600006, 0x00200044, ++ 0x00102080, 0x001120c6, 0x001520c9, 0x001920d0, 0x00122100, 0x00122103, ++ 0x00162200, 0x00122207, 0x00112280, 0x00112300, 0x00112302, 0x00122380, ++ 0x0011238b, 0x00112394, 0x0011239c, 0x00000000, 0x0040a00f, 0x005000cb, ++ 0x00214b40, 0x00600007, 0x00200442, 0x008800ff, 0x005000cb, 0x0040a387, ++ 0x0060000a, 0x00000000, 0x0040b200, 0x007000a0, 0x00700080, 0x00200280, ++ 0x00600007, 0x00200004, 0x00c000ff, 0x008000ff, 0x005000cb, 0x00700000, ++ 0x00200000, 0x00600006, 0x00111bfe, 0x0040d44d, 0x00700000, 0x00200000, ++ 0x00600006, 0x00111bfe, 0x00700080, 0x0070001d, 0x0040114d, 0x00700081, ++ 0x00600004, 0x0050004a, 0x0040be88, 0x0060000b, 0x00200000, 0x00600006, ++ 0x00700000, 0x0040d40b, 0x00111bfd, 0x0040424d, 0x00202916, 0x008000fd, ++ 0x005000cb, 0x00c00002, 0x00200280, 0x00600007, 0x00200160, 0x00800002, ++ 0x005000cb, 0x00c01802, 0x002027b6, 0x00800002, 0x005000cb, 0x00404e4d, ++ 0x0060000b, 0x0040d24d, 0x00700001, 0x00700003, 0x0040d806, 0x0040d905, ++ 0x0060000d, 0x00700005, 0x0070000d, 0x00700006, 0x0070000b, 0x0070000e, ++ 0x0060000c, ~0 ++}; ++ ++static uint32_t nv86_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0031, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x044d00df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000f80, ++ 0x0011, 0x00000000, ++ 0x0001, 0x007f0080, ++ 0x000e, 0x00000000, ++ 0x0001, 0x007f0080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00010040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00010040, ++ 0x0001, 0x00000022, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x008c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x008c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0014, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00608080, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000d, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0089, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00b5, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0b84, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x2647, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0c78, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x005d, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0031, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x003d, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001d, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0041, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0025, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0009, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x003c, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0029, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x002d, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0009, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00c5, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0079, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0097, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x01c7, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x2a17, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x933d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0067, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0000 ++}; ++ ++static uint32_t nv92_ctxprog[] = { ++ 0x0070008E, 0x0070009C, 0x00200020, 0x00600008, 0x0050004C, 0x00400E89, ++ 0x00200000, 0x00600007, 0x00300000, 0x00C000FF, 0x00200000, 0x008000FF, ++ 0x00700009, 0x0041924D, 0x00402944, 0x00402905, 0x0040290D, 0x00416E06, ++ 0x00600005, 0x004015C5, 0x00600011, 0x0040270B, 0x004021C5, 0x00700000, ++ 0x00700081, 0x00600004, 0x0050004A, 0x00219600, 0x00600007, 0x00C02701, ++ 0x0020002E, 0x00800001, 0x005000CB, 0x0090FFFF, 0x0091FFFF, 0x00200020, ++ 0x00600008, 0x0050004C, 0x00600009, 0x00416E45, 0x0041894D, 0x0070009D, ++ 0x00402DCF, 0x0070009F, 0x0050009F, 0x00402AC0, 0x00200080, 0x00600008, ++ 0x00402A4F, 0x00402AC0, 0x004030CC, 0x00700081, 0x00200000, 0x00600006, ++ 0x00700000, 0x00111BFC, 0x00700083, 0x00300000, 0x00219600, 0x00600007, ++ 0x00C00A01, 0x0020001E, 0x00800001, 0x005000CB, 0x00C000FF, 0x00700080, ++ 0x00700083, 0x00200047, 0x00600006, 0x0011020A, 0x00200540, 0x00600007, ++ 0x00300000, 0x00C000FF, 0x00C800FF, 0x00417907, 0x00202DD2, 0x008000FF, ++ 0x0040508C, 0x005000CB, 0x00A0023F, 0x00200040, 0x00600006, 0x0070000F, ++ 0x00170202, 0x0011020A, 0x00200032, 0x0010020D, 0x001C0242, 0x00120302, ++ 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, 0x0020000F, ++ 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110A00, 0x00160B02, ++ 0x00120B28, 0x00140B2B, 0x00110C01, 0x00111400, 0x00111405, 0x00111407, ++ 0x00111409, 0x0011140B, 0x002000CB, 0x00101500, 0x0040790F, 0x0040794B, ++ 0x00217400, 0x00600007, 0x0020043E, 0x008800FF, 0x0070008F, 0x0040798C, ++ 0x005000CB, 0x00000000, 0x00141A05, 0x00131A0C, 0x00131C00, 0x00121C04, ++ 0x00141C20, 0x00111C25, 0x00131C40, 0x00121C44, 0x00141C60, 0x00111C65, ++ 0x00131C80, 0x00121C84, 0x00141CA0, 0x00111CA5, 0x00131CC0, 0x00121CC4, ++ 0x00141CE0, 0x00111CE5, 0x00131F00, 0x00191F40, 0x0040A1E0, 0x002001C9, ++ 0x00600006, 0x00200044, 0x00102080, 0x001120C6, 0x001520C9, 0x001920D0, ++ 0x00122100, 0x00122103, 0x00162200, 0x00122207, 0x00112280, 0x00112300, ++ 0x00112302, 0x00122380, 0x0011238B, 0x00112394, 0x0011239C, 0x0040BEE1, ++ 0x00200230, 0x00600006, 0x00200044, 0x00102480, 0x0040AF0F, 0x0040AF4B, ++ 0x00217400, 0x00600007, 0x0020043E, 0x008800FF, 0x0070008F, 0x0040AF8C, ++ 0x005000CB, 0x00000000, 0x001124C6, 0x001524C9, 0x001924D0, 0x00122500, ++ 0x00122503, 0x00162600, 0x00122607, 0x00112680, 0x00112700, 0x00112702, ++ 0x00122780, 0x0011278B, 0x00112794, 0x0011279C, 0x0040D1E2, 0x00200297, ++ 0x00600006, 0x00200044, 0x00102880, 0x001128C6, 0x001528C9, 0x001928D0, ++ 0x00122900, 0x00122903, 0x00162A00, 0x00122A07, 0x00112A80, 0x00112B00, ++ 0x00112B02, 0x00122B80, 0x00112B8B, 0x00112B94, 0x00112B9C, 0x0040EEE3, ++ 0x002002FE, 0x00600006, 0x00200044, 0x00102C80, 0x0040DF0F, 0x0040DF4B, ++ 0x00217400, 0x00600007, 0x0020043E, 0x008800FF, 0x0070008F, 0x0040DF8C, ++ 0x005000CB, 0x00000000, 0x00112CC6, 0x00152CC9, 0x00192CD0, 0x00122D00, ++ 0x00122D03, 0x00162E00, 0x00122E07, 0x00112E80, 0x00112F00, 0x00112F02, ++ 0x00122F80, 0x00112F8B, 0x00112F94, 0x00112F9C, 0x004101E4, 0x00200365, ++ 0x00600006, 0x00200044, 0x00103080, 0x001130C6, 0x001530C9, 0x001930D0, ++ 0x00123100, 0x00123103, 0x00163200, 0x00123207, 0x00113280, 0x00113300, ++ 0x00113302, 0x00123380, 0x0011338B, 0x00113394, 0x0011339C, 0x00411EE5, ++ 0x002003CC, 0x00600006, 0x00200044, 0x00103480, 0x00410F0F, 0x00410F4B, ++ 0x00217400, 0x00600007, 0x0020043E, 0x008800FF, 0x0070008F, 0x00410F8C, ++ 0x005000CB, 0x00000000, 0x001134C6, 0x001534C9, 0x001934D0, 0x00123500, ++ 0x00123503, 0x00163600, 0x00123607, 0x00113680, 0x00113700, 0x00113702, ++ 0x00123780, 0x0011378B, 0x00113794, 0x0011379C, 0x004131E6, 0x00200433, ++ 0x00600006, 0x00200044, 0x00103880, 0x001138C6, 0x001538C9, 0x001938D0, ++ 0x00123900, 0x00123903, 0x00163A00, 0x00123A07, 0x00113A80, 0x00113B00, ++ 0x00113B02, 0x00123B80, 0x00113B8B, 0x00113B94, 0x00113B9C, 0x00414EE7, ++ 0x0020049A, 0x00600006, 0x00200044, 0x00103C80, 0x00413F0F, 0x00413F4B, ++ 0x00217400, 0x00600007, 0x0020043E, 0x008800FF, 0x0070008F, 0x00413F8C, ++ 0x005000CB, 0x00000000, 0x00113CC6, 0x00153CC9, 0x00193CD0, 0x00123D00, ++ 0x00123D03, 0x00163E00, 0x00123E07, 0x00113E80, 0x00113F00, 0x00113F02, ++ 0x00123F80, 0x00113F8B, 0x00113F94, 0x00113F9C, 0x00000000, 0x0041550F, ++ 0x005000CB, 0x00217400, 0x00600007, 0x0020043E, 0x008800FF, 0x005000CB, ++ 0x00415887, 0x0060000A, 0x00000000, 0x00416700, 0x007000A0, 0x00700080, ++ 0x00200540, 0x00600007, 0x00200004, 0x00C000FF, 0x008000FF, 0x005000CB, ++ 0x00700000, 0x00200000, 0x00600006, 0x00111BFE, 0x0041894D, 0x00700000, ++ 0x00200000, 0x00600006, 0x00111BFE, 0x00700080, 0x0070001D, 0x0040114D, ++ 0x00700081, 0x00600004, 0x0050004A, 0x00417388, 0x0060000B, 0x00200000, ++ 0x00600006, 0x00700000, 0x0041890B, 0x00111BFD, 0x0040424D, 0x00202DD2, ++ 0x008000FD, 0x005000CB, 0x00C00002, 0x00200540, 0x00600007, 0x00200160, ++ 0x00800002, 0x005000CB, 0x00C01802, 0x00202C72, 0x00800002, 0x005000CB, ++ 0x00404E4D, 0x0060000B, 0x0041874D, 0x00700001, 0x00700003, 0x00418D06, ++ 0x00418E05, 0x0060000D, 0x00700005, 0x0070000D, 0x00700006, 0x0070000B, ++ 0x0070000E, 0x0070001C, 0x0060000C, ~0 ++}; ++ ++static uint32_t nv92_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0031, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x042500df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001f80, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000022, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x004e, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00608080, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0004, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0004, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0004, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0004, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000d, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0082, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x03020100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0013, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00b5, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0184, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x013a, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x2aed, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x001a, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x000a, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0069, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x000a, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0011, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0019, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001a, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0001, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0022, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0031, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0031, 0x00000000, ++ 0x0004, 0x001ffe67, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x002c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0004, 0x000007ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x00ff, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0039, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0009, 0x00000000, ++ 0x0004, 0x00000020, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x00000102, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0002, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0004, 0x001ffe67, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x004c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x0052, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0004, 0x001ffe67, ++ 0x001a, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0019, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x2a712488, ++ 0x000c, 0x00000000, ++ 0x0004, 0x4085c000, ++ 0x0002, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x02800000, ++ 0x0094, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x30201000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x70605040, ++ 0x0004, 0x00000000, ++ 0x0004, 0xb8a89888, ++ 0x0004, 0x00000000, ++ 0x0004, 0xf8e8d8c8, ++ 0x000c, 0x00000000, ++ 0x0004, 0x0000001a, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0042, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0051, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00608080, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x010a, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0011, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0004, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x03020100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0042, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x02c5, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x4749, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0281, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x008c, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x005c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x002c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0064, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x000000cf, ++ 0x0054, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x003c, 0x00000000, ++ 0x0004, 0x001ffe67, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x002c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x000007ff, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0154, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000008, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x003c, 0x00000000, ++ 0x0004, 0x00000020, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000003, ++ 0x0024, 0x00000000, ++ 0x0004, 0x001ffe67, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x004c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000400, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00001001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x003c, 0x00000000, ++ 0x0004, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000000f, ++ 0x00bc, 0x00000000, ++ 0x0004, 0x001ffe67, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000011, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x001c, 0x00000000, ++ 0x0004, 0x2a712488, ++ 0x000c, 0x00000000, ++ 0x0004, 0x4085c000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000040, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010100, ++ 0x0004, 0x00000000, ++ 0x0004, 0x02800000, ++ 0x0094, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x04e3bfdf, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0004, 0x00ffff00, ++ 0x0044, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x000c, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x30201000, ++ 0x0004, 0x00000000, ++ 0x0004, 0x70605040, ++ 0x0004, 0x00000000, ++ 0x0004, 0xb8a89888, ++ 0x0004, 0x00000000, ++ 0x0004, 0xf8e8d8c8, ++ 0x000c, 0x00000000, ++ 0x0004, 0x0000001a, ++ 0x8958, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0067, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0047, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000080, ++ 0x0008, 0x80007004, ++ 0x0008, 0x04000400, ++ 0x0008, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x0008, 0x00000002, ++ 0x0058, 0x00000000, ++ 0x0008, 0x00000080, ++ 0x0008, 0x80007004, ++ 0x0008, 0x04000400, ++ 0x0008, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x0008, 0x00000002, ++ 0x0050, 0x00000000, ++ 0x0008, 0x08100c12, ++ 0x0030, 0x00000000, ++ 0x0020, 0x0000ffff, ++ 0x0008, 0x00000001, ++ 0x0010, 0x00010001, ++ 0x0008, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0008, 0x08100c12, ++ 0x0008, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000002, ++ 0x0008, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0008, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0008, 0x00000002, ++ 0x0010, 0x00000001, ++ 0x0008, 0x00000002, ++ 0x0018, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000004, ++ 0x1d10, 0x00000000, ++ 0x0008, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0008, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nv96_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x042500df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001f80, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000022, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0029, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0013, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00608080, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0055, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0049, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0038, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0025, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000003, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0244, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x007a, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x2bed, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0010, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0077, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0097, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0037, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x007f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0137, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x00000005, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0046, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x00b0, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0137, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x018f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0037, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x01c7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x01c7, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x02e5, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1af3, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x008e, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x005e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0066, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0056, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000007ff, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0156, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x00000020, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0026, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x004e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x00be, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x2a712488, ++ 0x000e, 0x00000000, ++ 0x0002, 0x4085c000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x02800000, ++ 0x0096, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x30201000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x70605040, ++ 0x0006, 0x00000000, ++ 0x0002, 0xb8a89888, ++ 0x0006, 0x00000000, ++ 0x0002, 0xf8e8d8c8, ++ 0x000e, 0x00000000, ++ 0x0002, 0x0000001a, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x00ae, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00608080, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0126, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x1c5c, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x62a1, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x008e, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x005e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0066, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0056, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000007ff, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0156, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x00000020, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0026, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x004e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x00be, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x2a712488, ++ 0x000e, 0x00000000, ++ 0x0002, 0x4085c000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x02800000, ++ 0x0096, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x30201000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x70605040, ++ 0x0006, 0x00000000, ++ 0x0002, 0xb8a89888, ++ 0x0006, 0x00000000, ++ 0x0002, 0xf8e8d8c8, ++ 0x000e, 0x00000000, ++ 0x0002, 0x0000001a, ++ 0x295a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0067, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0047, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0058, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0050, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0030, 0x00000000, ++ 0x0003, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x0001fe21, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0003, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d18, 0x00000000, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nv98_ctxprog[] = { ++ 0x0070008e, 0x0070009c, 0x00200020, 0x00600008, 0x0050004c, 0x00400e89, ++ 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, 0x008000ff, ++ 0x00700009, 0x0040d94d, 0x00402944, 0x00402905, 0x0040290d, 0x0040b506, ++ 0x00600005, 0x004015c5, 0x00600011, 0x0040270b, 0x004021c5, 0x00700000, ++ 0x00700081, 0x00600004, 0x0050004a, 0x00216c40, 0x00600007, 0x00c02701, ++ 0x0020002e, 0x00800001, 0x005000cb, 0x0090ffff, 0x0091ffff, 0x00200020, ++ 0x00600008, 0x0050004c, 0x00600009, 0x0040b545, 0x0040d04d, 0x0070009d, ++ 0x00402dcf, 0x0070009f, 0x0050009f, 0x00402ac0, 0x00200080, 0x00600008, ++ 0x00402a4f, 0x00402ac0, 0x004030cc, 0x00700081, 0x00200000, 0x00600006, ++ 0x00700000, 0x00111bfc, 0x00700083, 0x00300000, 0x00216c40, 0x00600007, ++ 0x00c00a01, 0x0020001e, 0x00800001, 0x005000cb, 0x00c000ff, 0x00700080, ++ 0x00700083, 0x00200047, 0x00600006, 0x0011020a, 0x00200240, 0x00600007, ++ 0x00300000, 0x00c000ff, 0x00c800ff, 0x0040c007, 0x00202912, 0x008000ff, ++ 0x0040508c, 0x005000cb, 0x00a0023f, 0x00200040, 0x00600006, 0x0070000f, ++ 0x00170202, 0x0011020a, 0x00200032, 0x0010020d, 0x001c0242, 0x00120302, ++ 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, 0x0020000f, ++ 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110a00, 0x00160b02, ++ 0x00120b28, 0x00140b2b, 0x00110c01, 0x00111400, 0x00111405, 0x00111407, ++ 0x00111409, 0x0011140b, 0x002000cc, 0x00101500, 0x0040790f, 0x0040794b, ++ 0x00214b00, 0x00600007, 0x00200425, 0x008800ff, 0x0070008f, 0x0040798c, ++ 0x005000cb, 0x00000000, 0x00141a05, 0x00131a0c, 0x00131c00, 0x00121c04, ++ 0x00141c20, 0x00111c25, 0x00131f00, 0x00191f40, 0x004095e0, 0x002001ac, ++ 0x00600006, 0x00200044, 0x00102080, 0x001120c6, 0x001520c9, 0x001920d0, ++ 0x00122100, 0x00122103, 0x00162200, 0x00122207, 0x00112280, 0x00112300, ++ 0x00112302, 0x00122380, 0x0011238b, 0x00112394, 0x0011239c, 0x00000000, ++ 0x00409c0f, 0x005000cb, 0x00214b00, 0x00600007, 0x00200425, 0x008800ff, ++ 0x005000cb, 0x00409f87, 0x0060000a, 0x00000000, 0x0040ae00, 0x007000a0, ++ 0x00700080, 0x00200240, 0x00600007, 0x00200004, 0x00c000ff, 0x008000ff, ++ 0x005000cb, 0x00700000, 0x00200000, 0x00600006, 0x00111bfe, 0x0040d04d, ++ 0x00700000, 0x00200000, 0x00600006, 0x00111bfe, 0x00700080, 0x0070001d, ++ 0x0040114d, 0x00700081, 0x00600004, 0x0050004a, 0x0040ba88, 0x0060000b, ++ 0x00200000, 0x00600006, 0x00700000, 0x0040d00b, 0x00111bfd, 0x0040424d, ++ 0x00202912, 0x008000fd, 0x005000cb, 0x00c00002, 0x00200240, 0x00600007, ++ 0x00200160, 0x00800002, 0x005000cb, 0x00c01802, 0x002027b2, 0x00800002, ++ 0x005000cb, 0x00404e4d, 0x0060000b, 0x0040ce4d, 0x00700001, 0x00700003, ++ 0x0040d406, 0x0040d505, 0x0060000d, 0x00700005, 0x0070000d, 0x00700006, ++ 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ~0 ++}; ++ ++static uint32_t nv98_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x042500df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000f80, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00380040, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x118c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x003c, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0014, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00608080, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000d, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0089, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x03fd, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x02d7, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0e5e, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x2647, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0c98, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x005d, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0031, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x003d, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001d, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0041, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0025, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0009, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x003c, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0029, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x002d, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0009, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00c5, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0079, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0097, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x01c7, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x2a17, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x931d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0067, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0047, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0057, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0037, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x002f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0047, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1cff, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nva0_ctxprog[] = { ++ 0x0070009c, 0x00300000, 0x00452c09, 0x00402d09, 0x00412051, 0x00400a44, ++ 0x00400a05, 0x00400a0d, 0x0070008e, 0x0040124d, 0x0070009d, 0x00453b4d, ++ 0x00700097, 0x00453c21, 0x004446a1, 0x0044914d, 0x00449d4d, 0x0070001d, ++ 0x00401806, 0x00600005, 0x00444445, 0x0044308b, 0x00401845, 0x0040234d, ++ 0x00700081, 0x00401ccf, 0x0070009f, 0x0050009f, 0x0045174d, 0x00700017, ++ 0x0040230b, 0x0044984d, 0x00453d21, 0x004456a1, 0x007000a0, 0x00700001, ++ 0x00700003, 0x00402706, 0x00402805, 0x0060000d, 0x00700005, 0x0070000d, ++ 0x00700006, 0x00700002, 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ++ 0x00000000, 0x0090ffff, 0x0091ffff, 0x00450f4d, 0x00600009, 0x0048004d, ++ 0x00700096, 0x00403acf, 0x0070009f, 0x0050009f, 0x00412051, 0x004036c0, ++ 0x00200080, 0x00600008, 0x0040364f, 0x004036c0, 0x00403ecc, 0x00403651, ++ 0x00700016, 0x0048004d, 0x00600011, 0x0048004d, 0x0044364d, 0x0070008e, ++ 0x00700081, 0x00448b4d, 0x0044984d, 0x00700083, 0x00300000, 0x00217c80, ++ 0x00600007, 0x00c00a01, 0x00200022, 0x00800001, 0x005000cb, 0x00c000ff, ++ 0x00445e4d, 0x0048004d, 0x00450908, 0x00448e4d, 0x0044a64d, 0x00445e4d, ++ 0x00451d4d, 0x0044914d, 0x00449d4d, 0x0048004d, 0x00700083, 0x00453e4d, ++ 0x00a0023f, 0x00200040, 0x00600006, 0x0045374d, 0x0044a84d, 0x0020022b, ++ 0x0044ef60, 0x002002ba, 0x00300001, 0x0044ef61, 0x00200349, 0x00300002, ++ 0x0044ef62, 0x002003d8, 0x00300003, 0x0044ef63, 0x00200467, 0x00300004, ++ 0x0044ef64, 0x002004f6, 0x00300005, 0x0044ef65, 0x00200585, 0x00300006, ++ 0x0044ef66, 0x00200614, 0x00300007, 0x0044ef67, 0x002006a3, 0x00300008, ++ 0x0044ef68, 0x00200732, 0x00300009, 0x0044ef69, 0x00200800, 0x0038ffff, ++ 0x0045044d, 0x00300000, 0x005000cb, 0x0045564d, 0x005000cb, 0x00450b07, ++ 0x0048004d, 0x0044944d, 0x00111bfc, 0x0048004d, 0x0044944d, 0x00111bfd, ++ 0x0048004d, 0x0044944d, 0x00111bfe, 0x0048004d, 0x00200000, 0x00700000, ++ 0x00600006, 0x0048004d, 0x00200001, 0x00600006, 0x0045374d, 0x0011020a, ++ 0x0048004d, 0x00300000, 0x00c3ffff, 0x00200000, 0x00600007, 0x00700000, ++ 0x00200008, 0x008000ff, 0x005000cb, 0x0048004d, 0x00000000, 0x0048004d, ++ 0x00000000, 0x00170202, 0x00200032, 0x0010020d, 0x001e0242, 0x001102c0, ++ 0x00120302, 0x00150402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, ++ 0x00200013, 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110a00, ++ 0x00160b02, 0x00120b28, 0x00140b2b, 0x00110c01, 0x00110d01, 0x00111400, ++ 0x00111405, 0x00111407, 0x00111409, 0x0011140b, 0x002000d4, 0x00101500, ++ 0x00141a05, 0x00131a0c, 0x00131c00, 0x00131c04, 0x00141c20, 0x00131c25, ++ 0x00131c40, 0x00131c44, 0x00141c60, 0x00131c65, 0x00131c80, 0x00131c84, ++ 0x00141ca0, 0x00131ca5, 0x00131cc0, 0x00131cc4, 0x00141ce0, 0x00131ce5, ++ 0x00131d00, 0x00131d04, 0x00141d20, 0x00131d25, 0x00131d40, 0x00131d44, ++ 0x00141d60, 0x00131d65, 0x00131d80, 0x00131d84, 0x00141da0, 0x00131da5, ++ 0x00131dc0, 0x00131dc4, 0x00141de0, 0x00131de5, 0x00131f00, 0x00131f04, ++ 0x00111f08, 0x00111f0b, 0x00200015, 0x00101f40, 0x0048004d, 0x00600006, ++ 0x0045564d, 0x00112020, 0x00112022, 0x00200060, 0x00102040, 0x001520c0, ++ 0x001120c8, 0x001420ca, 0x001b20cf, 0x00122100, 0x00122103, 0x00162140, ++ 0x00122147, 0x00122153, 0x001121a0, 0x001221c0, 0x001121cb, 0x001121d4, ++ 0x001521d8, 0x0048004d, 0x00000000, 0x00700000, 0x00600006, 0x0045374d, ++ 0x0048004d, 0x0060000b, 0x0048004d, 0x0060000a, 0x0048004d, 0x0060000b, ++ 0x00410d4d, 0x00200020, 0x00600008, 0x0050004c, 0x0048004d, 0x002003e8, ++ 0x00600008, 0x0050004c, 0x0048004d, 0x00600004, 0x0050004a, 0x0048004d, ++ 0x00c000ff, 0x00c800ff, 0x0048004d, 0x00c000ff, 0x00c800ff, 0x0048004d, ++ 0x00700016, 0x0070008e, 0x00700082, 0x00500041, 0x0045134d, 0x00700095, ++ 0x005000d1, 0x00600016, 0x00500052, 0x00700002, 0x00700015, 0x0040284d, ++ 0x0070008e, 0x00450f4d, 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, ++ 0x00200000, 0x008000ff, 0x00700009, 0x0070000e, 0x0048004d, 0x00700080, ++ 0x00480017, 0x00700000, 0x0048004d, 0x0048004d, 0x0048004d, 0x0048004d, ++ 0x0070008e, 0x00450f4d, 0x00700083, 0x00451a4d, 0x0045474d, 0x0070000f, ++ 0x0041468c, 0x005000cb, 0x0048004d, 0x00200800, 0x00600007, 0x00454b87, ++ 0x0048004d, 0x00000000, 0x0020216c, 0x0045374d, 0x008000ff, 0x0048004d, ++ 0x00211380, 0x00600007, 0x00200d20, 0x0045374d, 0x008800ff, 0x0048004d, ++ 0x0048000f, 0x0048004b, 0x0045504d, 0x0070008f, 0x0048008c, 0x005000cb, ++ 0x0048004d, ~0 ++}; ++ ++static uint32_t nva0_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x0012, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x042500df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000800, ++ 0x0005, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x000e0080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000009, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001f80, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0007, 0x00000000, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000022, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00080c14, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000c, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000020, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x4085c000, ++ 0x0002, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0003, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0001, 0x00000040, ++ 0x0005, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x04000000, ++ 0x0001, 0x00000100, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0012, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x000c, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000c, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0002, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001c, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000b, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0x0000ffff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0001, 0x000007ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000ffff, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0002, 0x00000010, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0013, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000c, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001d, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x04000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x04000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0001, 0x000000cf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x002e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000015, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x04444480, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0034, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x000c, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x000c, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0058, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0003, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0038, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0013, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001c, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x002e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x003c, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0019, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x0000000f, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001d, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000080, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0058, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0030, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0xf8e8d8c8, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x006e, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x009e, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00df, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x02b4, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0011, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x008d, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0031, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0025, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0076, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x2a712488, ++ 0x000e, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x003e, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0019, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0038, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x002d, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0005, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x0000000f, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0055, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0031, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0050, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0056, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00d8, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x030e, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00c9, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x00df, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000d, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0025, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0035, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0039, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0025, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0015, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0060, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0008, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x002d, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x002e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x0000000f, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00bf, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0127, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x09a0, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0066, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0040, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0076, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0048, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0038, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x002e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x001ffe67, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x0000000f, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0021, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001d, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0036, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0015, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0001, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0001, 0x00000004, ++ 0x0001, 0x04000000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000052, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0071, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0005, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0009, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0015, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0025, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0081, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00b5, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x09a0, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x00df, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0076, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x00d8, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00bf, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0127, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x10a7, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x00df, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0157, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00bf, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0127, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x10a7, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x03c3, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x1a66, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x15c6, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0800, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x002d, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x000000c0, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0068, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x000000c0, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0068, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x000000c0, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0060, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0003, 0x0001fe21, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0003, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x0001fe21, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0003, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d18, 0x00000000, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0170, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x000000c0, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0068, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x000000c0, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0068, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x000000c0, ++ 0x0004, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0060, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0003, 0x0001fe21, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0003, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x0001fe21, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0003, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d18, 0x00000000, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0171, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x80007004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000c0, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001000, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x006e, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x80007004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000c0, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001000, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x006e, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x80007004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000c0, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001000, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0066, 0x00000000, ++ 0x0002, 0x08100c12, ++ 0x000e, 0x00000000, ++ 0x0002, 0x0001fe21, ++ 0x002e, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x0001fe21, ++ 0x002e, 0x00000000, ++ 0x0002, 0x08100c12, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0046, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x004e, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x1d1e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nva5_ctxprog[] = { ++ 0x0070009c, 0x00300000, 0x0044fb09, 0x00402d09, 0x0040ef51, 0x00400a44, ++ 0x00400a05, 0x00400a0d, 0x0070008e, 0x0040124d, 0x0070009d, 0x00450a4d, ++ 0x00700097, 0x00450b21, 0x004446a1, 0x0044794d, 0x0044854d, 0x0070001d, ++ 0x00401806, 0x00600005, 0x00444445, 0x0044308b, 0x00401845, 0x0040234d, ++ 0x00700081, 0x00401ccf, 0x0070009f, 0x0050009f, 0x0044e64d, 0x00700017, ++ 0x0040230b, 0x0044804d, 0x00450c21, 0x004456a1, 0x007000a0, 0x00700001, ++ 0x00700003, 0x00402706, 0x00402805, 0x0060000d, 0x00700005, 0x0070000d, ++ 0x00700006, 0x00700002, 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ++ 0x00000000, 0x0090ffff, 0x0091ffff, 0x0044de4d, 0x00600009, 0x0048004d, ++ 0x00700096, 0x00403acf, 0x0070009f, 0x0050009f, 0x0040ef51, 0x004036c0, ++ 0x00200080, 0x00600008, 0x0040364f, 0x004036c0, 0x00403ecc, 0x00403651, ++ 0x00700016, 0x0048004d, 0x00600011, 0x0048004d, 0x0044364d, 0x0070008e, ++ 0x00700081, 0x0044734d, 0x0044804d, 0x00700083, 0x00300000, 0x00215100, ++ 0x00600007, 0x00c00a01, 0x00200022, 0x00800001, 0x005000cb, 0x00c000ff, ++ 0x00445e4d, 0x0048004d, 0x0044d808, 0x0044764d, 0x00448e4d, 0x00445e4d, ++ 0x0044ec4d, 0x0044794d, 0x0044854d, 0x0048004d, 0x00700083, 0x00450d4d, ++ 0x00a0023f, 0x00200040, 0x00600006, 0x0045064d, 0x0044904d, 0x002001e7, ++ 0x0044c160, 0x00200278, 0x00300001, 0x0044c161, 0x00200340, 0x0038ffff, ++ 0x0044d64d, 0x00300000, 0x005000cb, 0x0045254d, 0x005000cb, 0x0044da07, ++ 0x0048004d, 0x00447c4d, 0x00111bfc, 0x0048004d, 0x00447c4d, 0x00111bfd, ++ 0x0048004d, 0x00447c4d, 0x00111bfe, 0x0048004d, 0x00200000, 0x00700000, ++ 0x00600006, 0x0048004d, 0x00200001, 0x00600006, 0x0045064d, 0x0011020a, ++ 0x0048004d, 0x00300000, 0x00c3ffff, 0x00200000, 0x00600007, 0x00700000, ++ 0x00200008, 0x008000ff, 0x005000cb, 0x0048004d, 0x00000000, 0x0048004d, ++ 0x00000000, 0x00170202, 0x00200032, 0x0010020d, 0x001e0242, 0x001102c0, ++ 0x001102c4, 0x001102c8, 0x00120302, 0x00150402, 0x00180500, 0x00130509, ++ 0x00150550, 0x00110605, 0x00200013, 0x00100607, 0x00110700, 0x00110900, ++ 0x00120902, 0x00110a00, 0x00160b02, 0x00120b28, 0x00140b2b, 0x00110c01, ++ 0x00110d01, 0x002000da, 0x00101200, 0x00111400, 0x00111405, 0x00111407, ++ 0x00111409, 0x0011140b, 0x00141a05, 0x00131a0c, 0x00131c00, 0x00131c04, ++ 0x00141c20, 0x00141c25, 0x00131c40, 0x00131c44, 0x00141c60, 0x00141c65, ++ 0x00131f00, 0x00131f04, 0x00111f08, 0x00111f0b, 0x00200015, 0x00101f40, ++ 0x0048004d, 0x00600006, 0x0045254d, 0x00112020, 0x00112022, 0x00200060, ++ 0x00102040, 0x001520c0, 0x001120c8, 0x001420ca, 0x001d20cf, 0x00122100, ++ 0x00122103, 0x00162140, 0x00122147, 0x00122153, 0x001121a0, 0x001221c0, ++ 0x001121cb, 0x001121d4, 0x001521d8, 0x0048004d, 0x00000000, 0x0048004d, ++ 0x0060000b, 0x0048004d, 0x0060000a, 0x0048004d, 0x0060000b, 0x0040dc4d, ++ 0x00200020, 0x00600008, 0x0050004c, 0x0048004d, 0x002003e8, 0x00600008, ++ 0x0050004c, 0x0048004d, 0x00600004, 0x0050004a, 0x0048004d, 0x00c000ff, ++ 0x00c800ff, 0x0048004d, 0x00c000ff, 0x00c800ff, 0x0048004d, 0x00700016, ++ 0x0070008e, 0x00700082, 0x00500041, 0x0044e24d, 0x00700095, 0x005000d1, ++ 0x00600016, 0x00500052, 0x00700002, 0x00700015, 0x0040284d, 0x0070008e, ++ 0x0044de4d, 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, ++ 0x008000ff, 0x00700009, 0x0070000e, 0x0048004d, 0x00700080, 0x00480017, ++ 0x00700000, 0x0048004d, 0x0048004d, 0x0048004d, 0x0048004d, 0x0070008e, ++ 0x0044de4d, 0x00700083, 0x0044e94d, 0x0045164d, 0x0070000f, 0x0041158c, ++ 0x005000cb, 0x0048004d, 0x00200340, 0x00600007, 0x00451a87, 0x0048004d, ++ 0x00000000, 0x00202072, 0x0045064d, 0x008000ff, 0x0048004d, 0x00210700, ++ 0x00600007, 0x0020093b, 0x0045064d, 0x008800ff, 0x0048004d, 0x0048000f, ++ 0x0048004b, 0x00451f4d, 0x0070008f, 0x0048008c, 0x005000cb, 0x0048004d, ++ ~0 ++}; ++ ++static uint32_t nva5_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0013, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0014, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x0012, 0x00000000, ++ 0x0002, 0x0001629d, ++ 0x0001, 0x0000fe0c, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00004000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x142500df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0002, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000009, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000e0080, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001f80, ++ 0x0001, 0x00000030, ++ 0x0004, 0x00000000, ++ 0x0001, 0x7b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x827c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x7b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000001ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x827c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0007, 0x00000000, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000022, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x05127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe007, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x6cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x310c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x05127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe007, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x6cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0001, 0x08100c12, ++ 0x0005, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x04000000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x000007ff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00080c14, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0015, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x003e, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000088, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x04444480, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0019, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x001d, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x2a712488, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x4085c000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00010100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x02800000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0030, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0038, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0026, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0018, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000300, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000020, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x003e, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00087e67, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000011, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0024, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0026, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000001a, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00f0, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0111, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1f35, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x007f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000c, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0127, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0127, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x035d, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x08ee, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0a9c, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x003f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x04cf, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0097, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0037, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x007f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x001d, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x008f, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0137, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x01e7, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x6cd9, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x003d, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x006f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x006f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0067, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x002f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0047, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d1f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0177, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x006f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x006f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0067, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x002f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0047, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d1f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nva8_ctxprog[] = { ++ 0x0070009c, 0x00300000, 0x0044f509, 0x00402d09, 0x0040e951, 0x00400a44, ++ 0x00400a05, 0x00400a0d, 0x0070008e, 0x0040124d, 0x0070009d, 0x0045044d, ++ 0x00700097, 0x00450521, 0x004447a1, 0x0044774d, 0x0044834d, 0x0070001d, ++ 0x00401806, 0x00600005, 0x00444545, 0x0044308b, 0x00401845, 0x0040234d, ++ 0x00700081, 0x00401ccf, 0x0070009f, 0x0050009f, 0x0044e04d, 0x00700017, ++ 0x0040230b, 0x00447e4d, 0x00450621, 0x004457a1, 0x007000a0, 0x00700001, ++ 0x00700003, 0x00402706, 0x00402805, 0x0060000d, 0x00700005, 0x0070000d, ++ 0x00700006, 0x00700002, 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ++ 0x00000000, 0x0090ffff, 0x0091ffff, 0x0044d84d, 0x00600009, 0x0048004d, ++ 0x00480019, 0x00700096, 0x00403bcf, 0x0070009f, 0x0050009f, 0x0040e951, ++ 0x004036c0, 0x00200080, 0x00600008, 0x0040364f, 0x004036c0, 0x00403fcc, ++ 0x00403651, 0x00700016, 0x0048004d, 0x00600011, 0x0048004d, 0x0044364d, ++ 0x0070008e, 0x00700081, 0x0044714d, 0x00447e4d, 0x00700083, 0x00300000, ++ 0x00212a80, 0x00600007, 0x00c00a01, 0x00200022, 0x00800001, 0x005000cb, ++ 0x00c000ff, 0x00445f4d, 0x0048004d, 0x0044d208, 0x0044744d, 0x00448c4d, ++ 0x00445f4d, 0x0044e64d, 0x0044774d, 0x0044834d, 0x0048004d, 0x00700083, ++ 0x0045074d, 0x00a0023f, 0x00200040, 0x00600006, 0x0045004d, 0x00448e4d, ++ 0x002001d9, 0x0044bb60, 0x00200280, 0x0038ffff, 0x0044d04d, 0x00300000, ++ 0x005000cb, 0x00451f4d, 0x005000cb, 0x0044d407, 0x0048004d, 0x00447a4d, ++ 0x00111bfc, 0x0048004d, 0x00447a4d, 0x00111bfd, 0x0048004d, 0x00447a4d, ++ 0x00111bfe, 0x0048004d, 0x00200000, 0x00700000, 0x00600006, 0x0048004d, ++ 0x00200001, 0x00600006, 0x0045004d, 0x0011020a, 0x0048004d, 0x00300000, ++ 0x00c3ffff, 0x00200000, 0x00600007, 0x00700000, 0x00200008, 0x008000ff, ++ 0x005000cb, 0x0048004d, 0x00000000, 0x0048004d, 0x00000000, 0x00170202, ++ 0x00200032, 0x0010020d, 0x001e0242, 0x001102c0, 0x001102c4, 0x001102c8, ++ 0x00120302, 0x00150402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, ++ 0x00200013, 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110a00, ++ 0x00160b02, 0x00120b28, 0x00140b2b, 0x00110c01, 0x00110d01, 0x002000da, ++ 0x00101200, 0x00111400, 0x00111405, 0x00111407, 0x00111409, 0x0011140b, ++ 0x00141a05, 0x00131a0c, 0x00131c00, 0x00131c04, 0x00141c20, 0x00141c25, ++ 0x00131f00, 0x00131f04, 0x00111f08, 0x00111f0b, 0x00200015, 0x00101f40, ++ 0x0048004d, 0x00600006, 0x00451f4d, 0x00112020, 0x00112022, 0x00200040, ++ 0x00102040, 0x001520c0, 0x001120c8, 0x001420ca, 0x001d20cf, 0x00122100, ++ 0x00122103, 0x00162140, 0x00122147, 0x00122153, 0x001121a0, 0x001221c0, ++ 0x001121cb, 0x001121d4, 0x001521d8, 0x0048004d, 0x00000000, 0x0048004d, ++ 0x0060000b, 0x0048004d, 0x0060000a, 0x0048004d, 0x0060000b, 0x0040d64d, ++ 0x00200020, 0x00600008, 0x0050004c, 0x0048004d, 0x002003e8, 0x00600008, ++ 0x0050004c, 0x0048004d, 0x00600004, 0x0050004a, 0x0048004d, 0x00c000ff, ++ 0x00c800ff, 0x0048004d, 0x00c000ff, 0x00c800ff, 0x0048004d, 0x00700016, ++ 0x0070008e, 0x00700082, 0x00500041, 0x0044dc4d, 0x00700095, 0x005000d1, ++ 0x00600016, 0x00500052, 0x00700002, 0x00700015, 0x0040284d, 0x0070008e, ++ 0x0044d84d, 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, ++ 0x008000ff, 0x00700009, 0x0070000e, 0x0048004d, 0x00700080, 0x00480017, ++ 0x00700000, 0x0048004d, 0x0048004d, 0x0048004d, 0x0048004d, 0x0070008e, ++ 0x0044d84d, 0x00700083, 0x0044e34d, 0x0045104d, 0x0070000f, 0x00410f8c, ++ 0x005000cb, 0x0048004d, 0x00200280, 0x00600007, 0x00451487, 0x0048004d, ++ 0x00000000, 0x00202072, 0x0045004d, 0x008000ff, 0x0048004d, 0x00210640, ++ 0x00600007, 0x00200487, 0x0045004d, 0x008800ff, 0x0048004d, 0x0048000f, ++ 0x0048004b, 0x0045194d, 0x0070008f, 0x0048008c, 0x005000cb, 0x0048004d, ++ ~0 ++}; ++ ++static uint32_t nva8_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0013, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0014, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x0012, 0x00000000, ++ 0x0002, 0x0001629d, ++ 0x0001, 0x0000fe0c, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00004000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x142500df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0002, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000009, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000e0080, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001f80, ++ 0x0001, 0x00000030, ++ 0x0004, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0007, 0x00000000, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000022, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x05127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe007, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x6cfff007, ++ 0x0001, 0x02bf7fff, ++ 0x003e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0001, 0x08100c12, ++ 0x0005, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x04000000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x000007ff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00080c14, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00001e00, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0011, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x003e, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000088, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x04444480, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0019, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0019, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x001d, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x2a712488, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x4085c000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00010100, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x02800000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x0000000f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0030, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x001c, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0022, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00087e67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002c, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0127, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0127, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0101, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1f45, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0632, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x113a, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x08f6, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0a94, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x003f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x036f, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0097, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0037, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x007f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x008f, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0137, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x01e7, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x6e39, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x003d, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x006f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0067, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x002f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0047, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d1f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nvaa_ctxprog[] = { ++ 0x0070009c, 0x00300000, 0x0044f109, 0x00402d09, 0x0040e551, 0x00400a44, ++ 0x00400a05, 0x00400a0d, 0x0070008e, 0x0040124d, 0x0070009d, 0x0045004d, ++ 0x00700097, 0x00450121, 0x004446a1, 0x0044764d, 0x0044824d, 0x0070001d, ++ 0x00401806, 0x00600005, 0x00444445, 0x0044308b, 0x00401845, 0x0040234d, ++ 0x00700081, 0x00401ccf, 0x0070009f, 0x0050009f, 0x0044dc4d, 0x00700017, ++ 0x0040230b, 0x00447d4d, 0x00450221, 0x004456a1, 0x007000a0, 0x00700001, ++ 0x00700003, 0x00402706, 0x00402805, 0x0060000d, 0x00700005, 0x0070000d, ++ 0x00700006, 0x00700002, 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ++ 0x00000000, 0x0090ffff, 0x0091ffff, 0x0044d44d, 0x00600009, 0x0048004d, ++ 0x00700096, 0x00403acf, 0x0070009f, 0x0050009f, 0x0040e551, 0x004036c0, ++ 0x00200080, 0x00600008, 0x0040364f, 0x004036c0, 0x00403ecc, 0x00403651, ++ 0x00700016, 0x0048004d, 0x00600011, 0x0048004d, 0x0044364d, 0x0070008e, ++ 0x00700081, 0x0044704d, 0x00447d4d, 0x00700083, 0x00300000, 0x00212740, ++ 0x00600007, 0x00c00b01, 0x00200022, 0x00800001, 0x005000cb, 0x00c000ff, ++ 0x00445e4d, 0x0048004d, 0x0044ce08, 0x0044734d, 0x00448b4d, 0x00445e4d, ++ 0x0044e24d, 0x0044764d, 0x0044824d, 0x0048004d, 0x00700083, 0x0045034d, ++ 0x00a0023f, 0x00200040, 0x00600006, 0x0044fc4d, 0x00448d4d, 0x002001d0, ++ 0x0044b860, 0x00200280, 0x0038ffff, 0x0044cc4d, 0x00300000, 0x005000cb, ++ 0x00451c4d, 0x005000cb, 0x0044d007, 0x0048004d, 0x0044794d, 0x00111bfc, ++ 0x0048004d, 0x0044794d, 0x00111bfd, 0x0048004d, 0x0044794d, 0x00111bfe, ++ 0x0048004d, 0x00200000, 0x00700000, 0x00600006, 0x0048004d, 0x00200001, ++ 0x00600006, 0x0044fc4d, 0x0011020a, 0x0048004d, 0x00300000, 0x00c3ffff, ++ 0x00200000, 0x00600007, 0x00700000, 0x00200008, 0x008000ff, 0x005000cb, ++ 0x0048004d, 0x00000000, 0x0048004d, 0x00000000, 0x00170202, 0x00200032, ++ 0x0010020d, 0x001e0242, 0x001102c0, 0x00120302, 0x00150402, 0x00180500, ++ 0x00130509, 0x00150550, 0x00110605, 0x00200013, 0x00100607, 0x00110700, ++ 0x00110900, 0x00120902, 0x00110a00, 0x00160b02, 0x00120b28, 0x00140b2b, ++ 0x00110c01, 0x00110d01, 0x00111400, 0x00111405, 0x00111407, 0x00111409, ++ 0x0011140b, 0x002000d4, 0x00101500, 0x00141a05, 0x00131a0c, 0x00131c00, ++ 0x00131c04, 0x00141c20, 0x00131c25, 0x00131f00, 0x00131f04, 0x00111f08, ++ 0x00111f0b, 0x00200015, 0x00101f40, 0x0048004d, 0x00600006, 0x00451c4d, ++ 0x00112020, 0x00112022, 0x00200085, 0x00102040, 0x001120c8, 0x001420ca, ++ 0x001b20cf, 0x00122100, 0x00122103, 0x00162140, 0x00122147, 0x00122153, ++ 0x001121a0, 0x001221c0, 0x001121cb, 0x001121d4, 0x001521d8, 0x0048004d, ++ 0x00000000, 0x0048004d, 0x0060000b, 0x0048004d, 0x0060000a, 0x0048004d, ++ 0x0060000b, 0x0040d24d, 0x00200020, 0x00600008, 0x0050004c, 0x0048004d, ++ 0x002003e8, 0x00600008, 0x0050004c, 0x0048004d, 0x00600004, 0x0050004a, ++ 0x0048004d, 0x00c000ff, 0x00c800ff, 0x0048004d, 0x00c000ff, 0x00c800ff, ++ 0x0048004d, 0x00700016, 0x0070008e, 0x00700082, 0x00500041, 0x0044d84d, ++ 0x00700095, 0x005000d1, 0x00600016, 0x00500052, 0x00700002, 0x00700015, ++ 0x0040284d, 0x0070008e, 0x0044d44d, 0x00200000, 0x00600007, 0x00300000, ++ 0x00c000ff, 0x00200000, 0x008000ff, 0x00700009, 0x0070000e, 0x0048004d, ++ 0x00700080, 0x00480017, 0x00700000, 0x0048004d, 0x0048004d, 0x0048004d, ++ 0x0048004d, 0x0070008e, 0x0044d44d, 0x00700083, 0x0044df4d, 0x00450c4d, ++ 0x0070000f, 0x00410b8c, 0x005000cb, 0x0048004d, 0x00200280, 0x00600007, ++ 0x00452307, 0x00451187, 0x0048004d, 0x00000000, 0x00202070, 0x0044fc4d, ++ 0x008000ff, 0x0048004d, 0x00210600, 0x00600007, 0x00200428, 0x0044fc4d, ++ 0x008800ff, 0x0048004d, 0x0048000f, 0x0048004b, 0x0045164d, 0x0070008f, ++ 0x0048008c, 0x005000cb, 0x0048004d, 0x00202070, 0x0044fc4d, 0x008000fd, ++ 0x005000cb, 0x00c00002, 0x00200280, 0x00600007, 0x00200161, 0x0044fc4d, ++ 0x00800002, 0x005000cb, 0x00c00002, 0x00201f0e, 0x0044fc4d, 0x00800002, ++ 0x005000cb, 0x0048004d, ~0 ++}; ++ ++static uint32_t nvaa_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x0012, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x042500df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000800, ++ 0x0005, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x000e0080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000009, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001f80, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0007, 0x00000000, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000022, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cf7f007, ++ 0x0001, 0x02bf7fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0001, 0x08100c12, ++ 0x0005, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x04000000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000d, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000d, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x000007ff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00080c14, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0020, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x003d, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x04000000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x04000000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000088, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000015, ++ 0x0001, 0x00000088, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x04444480, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0011, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0058, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0048, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x004c, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0084, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00d2, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00bf, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0127, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x03d1, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0c75, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x010a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x24f9, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0440, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x1383, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x032f, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0097, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0037, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x007f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0137, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x01e7, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x6ee1, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000d, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x005f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x002f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x002f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0047, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1cff, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nvac_ctxprog[] = { ++ 0x0070009c, 0x00300000, 0x0044f109, 0x00402d09, 0x0040e551, 0x00400a44, ++ 0x00400a05, 0x00400a0d, 0x0070008e, 0x0040124d, 0x0070009d, 0x0045004d, ++ 0x00700097, 0x00450121, 0x004446a1, 0x0044764d, 0x0044824d, 0x0070001d, ++ 0x00401806, 0x00600005, 0x00444445, 0x0044308b, 0x00401845, 0x0040234d, ++ 0x00700081, 0x00401ccf, 0x0070009f, 0x0050009f, 0x0044dc4d, 0x00700017, ++ 0x0040230b, 0x00447d4d, 0x00450221, 0x004456a1, 0x007000a0, 0x00700001, ++ 0x00700003, 0x00402706, 0x00402805, 0x0060000d, 0x00700005, 0x0070000d, ++ 0x00700006, 0x00700002, 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ++ 0x00000000, 0x0090ffff, 0x0091ffff, 0x0044d44d, 0x00600009, 0x0048004d, ++ 0x00700096, 0x00403acf, 0x0070009f, 0x0050009f, 0x0040e551, 0x004036c0, ++ 0x00200080, 0x00600008, 0x0040364f, 0x004036c0, 0x00403ecc, 0x00403651, ++ 0x00700016, 0x0048004d, 0x00600011, 0x0048004d, 0x0044364d, 0x0070008e, ++ 0x00700081, 0x0044704d, 0x00447d4d, 0x00700083, 0x00300000, 0x00212840, ++ 0x00600007, 0x00c00b01, 0x00200022, 0x00800001, 0x005000cb, 0x00c000ff, ++ 0x00445e4d, 0x0048004d, 0x0044ce08, 0x0044734d, 0x00448b4d, 0x00445e4d, ++ 0x0044e24d, 0x0044764d, 0x0044824d, 0x0048004d, 0x00700083, 0x0045034d, ++ 0x00a0023f, 0x00200040, 0x00600006, 0x0044fc4d, 0x00448d4d, 0x002001d0, ++ 0x0044b860, 0x00200280, 0x0038ffff, 0x0044cc4d, 0x00300000, 0x005000cb, ++ 0x00451c4d, 0x005000cb, 0x0044d007, 0x0048004d, 0x0044794d, 0x00111bfc, ++ 0x0048004d, 0x0044794d, 0x00111bfd, 0x0048004d, 0x0044794d, 0x00111bfe, ++ 0x0048004d, 0x00200000, 0x00700000, 0x00600006, 0x0048004d, 0x00200001, ++ 0x00600006, 0x0044fc4d, 0x0011020a, 0x0048004d, 0x00300000, 0x00c3ffff, ++ 0x00200000, 0x00600007, 0x00700000, 0x00200008, 0x008000ff, 0x005000cb, ++ 0x0048004d, 0x00000000, 0x0048004d, 0x00000000, 0x00170202, 0x00200032, ++ 0x0010020d, 0x001e0242, 0x001102c0, 0x00120302, 0x00150402, 0x00180500, ++ 0x00130509, 0x00150550, 0x00110605, 0x00200013, 0x00100607, 0x00110700, ++ 0x00110900, 0x00120902, 0x00110a00, 0x00160b02, 0x00120b28, 0x00140b2b, ++ 0x00110c01, 0x00110d01, 0x00111400, 0x00111405, 0x00111407, 0x00111409, ++ 0x0011140b, 0x002000d4, 0x00101500, 0x00141a05, 0x00131a0c, 0x00131c00, ++ 0x00131c04, 0x00141c20, 0x00131c25, 0x00131f00, 0x00131f04, 0x00111f08, ++ 0x00111f0b, 0x00200015, 0x00101f40, 0x0048004d, 0x00600006, 0x00451c4d, ++ 0x00112020, 0x00112022, 0x00200085, 0x00102040, 0x001120c8, 0x001420ca, ++ 0x001b20cf, 0x00122100, 0x00122103, 0x00162140, 0x00122147, 0x00122153, ++ 0x001121a0, 0x001221c0, 0x001121cb, 0x001121d4, 0x001521d8, 0x0048004d, ++ 0x00000000, 0x0048004d, 0x0060000b, 0x0048004d, 0x0060000a, 0x0048004d, ++ 0x0060000b, 0x0040d24d, 0x00200020, 0x00600008, 0x0050004c, 0x0048004d, ++ 0x002003e8, 0x00600008, 0x0050004c, 0x0048004d, 0x00600004, 0x0050004a, ++ 0x0048004d, 0x00c000ff, 0x00c800ff, 0x0048004d, 0x00c000ff, 0x00c800ff, ++ 0x0048004d, 0x00700016, 0x0070008e, 0x00700082, 0x00500041, 0x0044d84d, ++ 0x00700095, 0x005000d1, 0x00600016, 0x00500052, 0x00700002, 0x00700015, ++ 0x0040284d, 0x0070008e, 0x0044d44d, 0x00200000, 0x00600007, 0x00300000, ++ 0x00c000ff, 0x00200000, 0x008000ff, 0x00700009, 0x0070000e, 0x0048004d, ++ 0x00700080, 0x00480017, 0x00700000, 0x0048004d, 0x0048004d, 0x0048004d, ++ 0x0048004d, 0x0070008e, 0x0044d44d, 0x00700083, 0x0044df4d, 0x00450c4d, ++ 0x0070000f, 0x00410b8c, 0x005000cb, 0x0048004d, 0x00200280, 0x00600007, ++ 0x00452307, 0x00451187, 0x0048004d, 0x00000000, 0x00202070, 0x0044fc4d, ++ 0x008000ff, 0x0048004d, 0x00210600, 0x00600007, 0x00200448, 0x0044fc4d, ++ 0x008800ff, 0x0048004d, 0x0048000f, 0x0048004b, 0x0045164d, 0x0070008f, ++ 0x0048008c, 0x005000cb, 0x0048004d, 0x00202070, 0x0044fc4d, 0x008000fd, ++ 0x005000cb, 0x00c00002, 0x00200280, 0x00600007, 0x00200161, 0x0044fc4d, ++ 0x00800002, 0x005000cb, 0x00c00002, 0x00201f0e, 0x0044fc4d, 0x00800002, ++ 0x005000cb, 0x0048004d, ~0 ++}; ++ ++static uint32_t nvac_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x0012, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x0012, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x042500df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000800, ++ 0x0005, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x000e0080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000f0, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000009, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001f80, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0007, 0x00000000, ++ 0x0001, 0x003d0040, ++ 0x0001, 0x00000022, ++ 0x0011, 0x00000000, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x300c0000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x0000003e, ++ 0x0006, 0x00000000, ++ 0x0001, 0x01127070, ++ 0x0003, 0x00000000, ++ 0x0001, 0x07ffffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00008000, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x003fe006, ++ 0x0001, 0x003fe000, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0cfff007, ++ 0x0001, 0x02bf7fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0001, 0x08100c12, ++ 0x0005, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x04000000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000d, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000d, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x000007ff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x0000ffff, ++ 0x0001, 0x00080c14, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0014, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0020, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0018, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x003d, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x04000000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x04000000, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0020, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000088, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000015, ++ 0x0001, 0x00000088, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x04444480, ++ 0x0016, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0039, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0011, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0058, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x2a712488, ++ 0x000f, 0x00000000, ++ 0x0001, 0x4085c000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x02800000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0048, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x005f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x004c, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0084, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00d2, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0027, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000300, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00bf, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x005f, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x30201000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x70605040, ++ 0x0007, 0x00000000, ++ 0x0001, 0xb8a89888, ++ 0x0007, 0x00000000, ++ 0x0001, 0xf8e8d8c8, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0127, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x03020100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x03d1, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0c75, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x010a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x24f9, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0440, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x1383, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x036f, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0097, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0037, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x007f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0137, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x01e7, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x6ea1, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000d, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000c0, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001e00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x005f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x002f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x002f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0047, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d1f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0000 ++}; ++ ++static uint32_t nv94_ctxprog[] = { ++ 0x0070008e, 0x0070009c, 0x00200020, 0x00600008, 0x0050004c, 0x00400e89, ++ 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, 0x008000ff, ++ 0x00700009, 0x0041324d, 0x00402944, 0x00402905, 0x0040290d, 0x00410e06, ++ 0x00600005, 0x004015c5, 0x00600011, 0x0040270b, 0x004021c5, 0x00700000, ++ 0x00700081, 0x00600004, 0x0050004a, 0x00219440, 0x00600007, 0x00c02701, ++ 0x0020002e, 0x00800001, 0x005000cb, 0x0090ffff, 0x0091ffff, 0x00200020, ++ 0x00600008, 0x0050004c, 0x00600009, 0x00410e45, 0x0041294d, 0x0070009d, ++ 0x00402dcf, 0x0070009f, 0x0050009f, 0x00402ac0, 0x00200080, 0x00600008, ++ 0x00402a4f, 0x00402ac0, 0x004030cc, 0x00700081, 0x00200000, 0x00600006, ++ 0x00700000, 0x00111bfc, 0x00700083, 0x00300000, 0x00219440, 0x00600007, ++ 0x00c00a01, 0x0020001e, 0x00800001, 0x005000cb, 0x00c000ff, 0x00700080, ++ 0x00700083, 0x00200047, 0x00600006, 0x0011020a, 0x00200380, 0x00600007, ++ 0x00300000, 0x00c000ff, 0x00c800ff, 0x00411907, 0x00202dd2, 0x008000ff, ++ 0x0040508c, 0x005000cb, 0x00a0023f, 0x00200040, 0x00600006, 0x0070000f, ++ 0x00170202, 0x0011020a, 0x00200032, 0x0010020d, 0x001c0242, 0x00120302, ++ 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, 0x0020000f, ++ 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110a00, 0x00160b02, ++ 0x00120b28, 0x00140b2b, 0x00110c01, 0x00111400, 0x00111405, 0x00111407, ++ 0x00111409, 0x0011140b, 0x002000cc, 0x00101500, 0x0040790f, 0x0040794b, ++ 0x00217240, 0x00600007, 0x0020043f, 0x008800ff, 0x0070008f, 0x0040798c, ++ 0x005000cb, 0x00000000, 0x00141a05, 0x00131a0c, 0x00131c00, 0x00121c04, ++ 0x00141c20, 0x00111c25, 0x00131c40, 0x00121c44, 0x00141c60, 0x00111c65, ++ 0x00131c80, 0x00121c84, 0x00141ca0, 0x00111ca5, 0x00131cc0, 0x00121cc4, ++ 0x00141ce0, 0x00111ce5, 0x00131f00, 0x00191f40, 0x0040a1e0, 0x002001ca, ++ 0x00600006, 0x00200044, 0x00102080, 0x001120c6, 0x001520c9, 0x001920d0, ++ 0x00122100, 0x00122103, 0x00162200, 0x00122207, 0x00112280, 0x00112300, ++ 0x00112302, 0x00122380, 0x0011238b, 0x00112394, 0x0011239c, 0x0040bee1, ++ 0x00200231, 0x00600006, 0x00200044, 0x00102480, 0x0040af0f, 0x0040af4b, ++ 0x00217240, 0x00600007, 0x0020043f, 0x008800ff, 0x0070008f, 0x0040af8c, ++ 0x005000cb, 0x00000000, 0x001124c6, 0x001524c9, 0x001924d0, 0x00122500, ++ 0x00122503, 0x00162600, 0x00122607, 0x00112680, 0x00112700, 0x00112702, ++ 0x00122780, 0x0011278b, 0x00112794, 0x0011279c, 0x0040d1e2, 0x00200298, ++ 0x00600006, 0x00200044, 0x00102880, 0x001128c6, 0x001528c9, 0x001928d0, ++ 0x00122900, 0x00122903, 0x00162a00, 0x00122a07, 0x00112a80, 0x00112b00, ++ 0x00112b02, 0x00122b80, 0x00112b8b, 0x00112b94, 0x00112b9c, 0x0040eee3, ++ 0x002002ff, 0x00600006, 0x00200044, 0x00102c80, 0x0040df0f, 0x0040df4b, ++ 0x00217240, 0x00600007, 0x0020043f, 0x008800ff, 0x0070008f, 0x0040df8c, ++ 0x005000cb, 0x00000000, 0x00112cc6, 0x00152cc9, 0x00192cd0, 0x00122d00, ++ 0x00122d03, 0x00162e00, 0x00122e07, 0x00112e80, 0x00112f00, 0x00112f02, ++ 0x00122f80, 0x00112f8b, 0x00112f94, 0x00112f9c, 0x00000000, 0x0040f50f, ++ 0x005000cb, 0x00217240, 0x00600007, 0x0020043f, 0x008800ff, 0x005000cb, ++ 0x0040f887, 0x0060000a, 0x00000000, 0x00410700, 0x007000a0, 0x00700080, ++ 0x00200380, 0x00600007, 0x00200004, 0x00c000ff, 0x008000ff, 0x005000cb, ++ 0x00700000, 0x00200000, 0x00600006, 0x00111bfe, 0x0041294d, 0x00700000, ++ 0x00200000, 0x00600006, 0x00111bfe, 0x00700080, 0x0070001d, 0x0040114d, ++ 0x00700081, 0x00600004, 0x0050004a, 0x00411388, 0x0060000b, 0x00200000, ++ 0x00600006, 0x00700000, 0x0041290b, 0x00111bfd, 0x0040424d, 0x00202dd2, ++ 0x008000fd, 0x005000cb, 0x00c00002, 0x00200380, 0x00600007, 0x00200160, ++ 0x00800002, 0x005000cb, 0x00c01802, 0x00202c72, 0x00800002, 0x005000cb, ++ 0x00404e4d, 0x0060000b, 0x0041274d, 0x00700001, 0x00700003, 0x00412d06, ++ 0x00412e05, 0x0060000d, 0x00700005, 0x0070000d, 0x00700006, 0x0070000b, ++ 0x0070000e, 0x0070001c, 0x0060000c, ~0 ++}; ++ ++static uint32_t nv94_ctxvals[] = { ++ 0x0043, 0x00000000, ++ 0x0001, 0x00000030, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0028, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00001000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000fe0c, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x000a, 0x00000000, ++ 0x0001, 0x00000187, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001018, ++ 0x0001, 0x000000ff, ++ 0x000e, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x044d00df, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000600, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01000000, ++ 0x0001, 0x000000ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000400, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000080, ++ 0x0001, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0001, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000007, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000029, ++ 0x0001, 0x00000027, ++ 0x0001, 0x00000026, ++ 0x0001, 0x00000008, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000027, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000005, ++ 0x0001, 0x00000006, ++ 0x0001, 0x00000007, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000004, ++ 0x0001, 0x00000003, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000012, ++ 0x0001, 0x00000010, ++ 0x0001, 0x0000000c, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000004, ++ 0x0002, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0001, 0x00001fff, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0001, 0x00000014, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00000e00, ++ 0x0001, 0x00001000, ++ 0x0001, 0x00001e00, ++ 0x0001, 0x00000000, ++ 0x0005, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000200, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000070, ++ 0x0001, 0x00000080, ++ 0x0003, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001f80, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x3b74f821, ++ 0x0001, 0x89058001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0001, 0x0000001f, ++ 0x0001, 0x027c10fa, ++ 0x0001, 0x400000c0, ++ 0x0001, 0xb7892080, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000022, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00390040, ++ 0x0001, 0x00000022, ++ 0x0005, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0003, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0008, 0x00000000, ++ 0x0001, 0x01800000, ++ 0x0001, 0x00160000, ++ 0x0001, 0x01800000, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0003ffff, ++ 0x0001, 0x10880000, ++ 0x0008, 0x00000000, ++ 0x0001, 0x00010401, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000078, ++ 0x0001, 0x00000000, ++ 0x0001, 0x000000bf, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00001210, ++ 0x0001, 0x08000080, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00027070, ++ 0x0002, 0x00000000, ++ 0x0001, 0x03ffffff, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00120407, ++ 0x0001, 0x05091507, ++ 0x0001, 0x05010202, ++ 0x0001, 0x00030201, ++ 0x0006, 0x00000000, ++ 0x0001, 0x00000040, ++ 0x0001, 0x0d0c0b0a, ++ 0x0001, 0x00141210, ++ 0x0001, 0x000001f0, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000003, ++ 0x0002, 0x00000000, ++ 0x0001, 0x00039e00, ++ 0x0001, 0x00000100, ++ 0x0001, 0x00003800, ++ 0x0001, 0x00404040, ++ 0x0001, 0x0000ff0a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x0077f005, ++ 0x0001, 0x003f7fff, ++ 0x0029, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0013, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0021, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000020, ++ 0x0009, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0002, 0x00000004, ++ 0x0003, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00608080, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0018, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000b, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x0009, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0055, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0049, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0038, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0025, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000003, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0002, 0x00000004, ++ 0x0005, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0005, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000d, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000d, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x0001, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x031f, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0244, 0x00000000, ++ 0x0001, 0x00000021, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x007a, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x009f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x00cf, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0067, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x001ffe67, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x00af, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x2bed, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x00a7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000008, ++ 0x002f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x000000cf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000015, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04444480, ++ 0x01df, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000100, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0010, 0x00000000, ++ 0x0001, 0x003fffff, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00001fff, ++ 0x0077, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0037, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0097, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0037, 0x00000000, ++ 0x0001, 0x0000000f, ++ 0x003f, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x007f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000005, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0087, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0137, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0001, 0x00000005, ++ 0x0006, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0010, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0046, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x00b0, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0137, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000102, ++ 0x004f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x018f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0027, 0x00000000, ++ 0x0001, 0x00000804, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000007f, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0037, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x01c7, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x01c7, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000088, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x0017, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x001f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0147, 0x00000000, ++ 0x0001, 0x00000052, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000001a, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00ffff00, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x000f, 0x00000000, ++ 0x0001, 0x000007ff, ++ 0x02e5, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1af3, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x008e, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x005e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0066, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0056, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000007ff, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0156, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x00000020, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0026, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x004e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x00be, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x2a712488, ++ 0x000e, 0x00000000, ++ 0x0002, 0x4085c000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x02800000, ++ 0x0096, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x30201000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x70605040, ++ 0x0006, 0x00000000, ++ 0x0002, 0xb8a89888, ++ 0x0006, 0x00000000, ++ 0x0002, 0xf8e8d8c8, ++ 0x000e, 0x00000000, ++ 0x0002, 0x0000001a, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x00ae, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00608080, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0126, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000080, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x03020100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x1c5c, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000026, ++ 0x001f, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0127, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04e3bfdf, ++ 0x0017, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x62a1, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x008e, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x005e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000ffff, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0066, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x000000cf, ++ 0x0056, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x002e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x000007ff, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0156, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000008, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x003e, 0x00000000, ++ 0x0002, 0x00000020, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000003, ++ 0x0026, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000002, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x004e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000400, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000300, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00001001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x003e, 0x00000000, ++ 0x0002, 0x0fac6881, ++ 0x0006, 0x00000000, ++ 0x0002, 0x0000000f, ++ 0x00be, 0x00000000, ++ 0x0002, 0x001ffe67, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000011, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00000004, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0026, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x001e, 0x00000000, ++ 0x0002, 0x2a712488, ++ 0x000e, 0x00000000, ++ 0x0002, 0x4085c000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000040, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00010100, ++ 0x0006, 0x00000000, ++ 0x0002, 0x02800000, ++ 0x0096, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x04e3bfdf, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0006, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0016, 0x00000000, ++ 0x0002, 0x00ffff00, ++ 0x0046, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x000e, 0x00000000, ++ 0x0002, 0x00000001, ++ 0x0006, 0x00000000, ++ 0x0002, 0x30201000, ++ 0x0006, 0x00000000, ++ 0x0002, 0x70605040, ++ 0x0006, 0x00000000, ++ 0x0002, 0xb8a89888, ++ 0x0006, 0x00000000, ++ 0x0002, 0xf8e8d8c8, ++ 0x000e, 0x00000000, ++ 0x0002, 0x0000001a, ++ 0x295a, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0007, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x000f, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00080c14, ++ 0x0017, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000027, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x1e0f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x00b7, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0067, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x000f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x000f, 0x00000000, ++ 0x0001, 0x0000003f, ++ 0x0057, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x04000000, ++ 0x0047, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x001f, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x008f, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00001001, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0007, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0107, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x3f800000, ++ 0x0007, 0x00000000, ++ 0x0001, 0x00000010, ++ 0x0017, 0x00000000, ++ 0x0001, 0x00000003, ++ 0x0047, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0058, 0x00000000, ++ 0x0003, 0x00000080, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000080, ++ 0x0003, 0x80007004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x80007004, ++ 0x0003, 0x04000400, ++ 0x0004, 0x00000000, ++ 0x0001, 0x04000400, ++ 0x0003, 0x00001000, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00001000, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0010, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0050, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0030, 0x00000000, ++ 0x0003, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0004, 0x0000ffff, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0000ffff, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00010001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00010001, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x0001fe21, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0001fe21, ++ 0x0028, 0x00000000, ++ 0x0003, 0x08100c12, ++ 0x0004, 0x00000000, ++ 0x0001, 0x08100c12, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0040, 0x00000000, ++ 0x0003, 0x0fac6881, ++ 0x0004, 0x00000000, ++ 0x0001, 0x0fac6881, ++ 0x0020, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x0048, 0x00000000, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0003, 0x00000002, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000002, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0004, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000004, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000004, ++ 0x1d18, 0x00000000, ++ 0x0003, 0x00000011, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000011, ++ 0x0008, 0x00000000, ++ 0x0003, 0x00000001, ++ 0x0004, 0x00000000, ++ 0x0001, 0x00000001, ++ 0x0000 ++}; ++ ++#endif +diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c +new file mode 100644 +index 0000000..94400f7 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_instmem.c +@@ -0,0 +1,509 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++struct nv50_instmem_priv { ++ uint32_t save1700[5]; /* 0x1700->0x1710 */ ++ ++ struct nouveau_gpuobj_ref *pramin_pt; ++ struct nouveau_gpuobj_ref *pramin_bar; ++ struct nouveau_gpuobj_ref *fb_bar; ++ ++ bool last_access_wr; ++}; ++ ++#define NV50_INSTMEM_PAGE_SHIFT 12 ++#define NV50_INSTMEM_PAGE_SIZE (1 << NV50_INSTMEM_PAGE_SHIFT) ++#define NV50_INSTMEM_PT_SIZE(a) (((a) >> 12) << 3) ++ ++/*NOTE: - Assumes 0x1700 already covers the correct MiB of PRAMIN ++ */ ++#define BAR0_WI32(g, o, v) do { \ ++ uint32_t offset; \ ++ if ((g)->im_backing) { \ ++ offset = (g)->im_backing_start; \ ++ } else { \ ++ offset = chan->ramin->gpuobj->im_backing_start; \ ++ offset += (g)->im_pramin->start; \ ++ } \ ++ offset += (o); \ ++ nv_wr32(dev, NV_RAMIN + (offset & 0xfffff), (v)); \ ++} while (0) ++ ++int ++nv50_instmem_init(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan; ++ uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size; ++ struct nv50_instmem_priv *priv; ++ int ret, i; ++ uint32_t v, save_nv001700; ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ dev_priv->engine.instmem.priv = priv; ++ ++ /* Save state, will restore at takedown. */ ++ for (i = 0x1700; i <= 0x1710; i += 4) ++ priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i); ++ ++ /* Reserve the last MiB of VRAM, we should probably try to avoid ++ * setting up the below tables over the top of the VBIOS image at ++ * some point. ++ */ ++ dev_priv->ramin_rsvd_vram = 1 << 20; ++ c_offset = nouveau_mem_fb_amount(dev) - dev_priv->ramin_rsvd_vram; ++ c_size = 128 << 10; ++ c_vmpd = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200; ++ c_ramfc = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20; ++ c_base = c_vmpd + 0x4000; ++ pt_size = NV50_INSTMEM_PT_SIZE(dev_priv->ramin_size); ++ ++ NV_DEBUG(dev, " Rsvd VRAM base: 0x%08x\n", c_offset); ++ NV_DEBUG(dev, " VBIOS image: 0x%08x\n", ++ (nv_rd32(dev, 0x619f04) & ~0xff) << 8); ++ NV_DEBUG(dev, " Aperture size: %d MiB\n", dev_priv->ramin_size >> 20); ++ NV_DEBUG(dev, " PT size: %d KiB\n", pt_size >> 10); ++ ++ /* Determine VM layout, we need to do this first to make sure ++ * we allocate enough memory for all the page tables. ++ */ ++ dev_priv->vm_gart_base = roundup(NV50_VM_BLOCK, NV50_VM_BLOCK); ++ dev_priv->vm_gart_size = NV50_VM_BLOCK; ++ ++ dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size; ++ dev_priv->vm_vram_size = nouveau_mem_fb_amount(dev); ++ if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM) ++ dev_priv->vm_vram_size = NV50_VM_MAX_VRAM; ++ dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK); ++ dev_priv->vm_vram_pt_nr = dev_priv->vm_vram_size / NV50_VM_BLOCK; ++ ++ dev_priv->vm_end = dev_priv->vm_vram_base + dev_priv->vm_vram_size; ++ ++ NV_DEBUG(dev, "NV50VM: GART 0x%016llx-0x%016llx\n", ++ dev_priv->vm_gart_base, ++ dev_priv->vm_gart_base + dev_priv->vm_gart_size - 1); ++ NV_DEBUG(dev, "NV50VM: VRAM 0x%016llx-0x%016llx\n", ++ dev_priv->vm_vram_base, ++ dev_priv->vm_vram_base + dev_priv->vm_vram_size - 1); ++ ++ c_size += dev_priv->vm_vram_pt_nr * (NV50_VM_BLOCK / 65536 * 8); ++ ++ /* Map BAR0 PRAMIN aperture over the memory we want to use */ ++ save_nv001700 = nv_rd32(dev, NV50_PUNK_BAR0_PRAMIN); ++ nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, (c_offset >> 16)); ++ ++ /* Create a fake channel, and use it as our "dummy" channels 0/127. ++ * The main reason for creating a channel is so we can use the gpuobj ++ * code. However, it's probably worth noting that NVIDIA also setup ++ * their channels 0/127 with the same values they configure here. ++ * So, there may be some other reason for doing this. ++ * ++ * Have to create the entire channel manually, as the real channel ++ * creation code assumes we have PRAMIN access, and we don't until ++ * we're done here. ++ */ ++ chan = kzalloc(sizeof(*chan), GFP_KERNEL); ++ if (!chan) ++ return -ENOMEM; ++ chan->id = 0; ++ chan->dev = dev; ++ chan->file_priv = (struct drm_file *)-2; ++ dev_priv->fifos[0] = dev_priv->fifos[127] = chan; ++ ++ /* Channel's PRAMIN object + heap */ ++ ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, c_size, 0, ++ NULL, &chan->ramin); ++ if (ret) ++ return ret; ++ ++ if (nouveau_mem_init_heap(&chan->ramin_heap, c_base, c_size - c_base)) ++ return -ENOMEM; ++ ++ /* RAMFC + zero channel's PRAMIN up to start of VM pagedir */ ++ ret = nouveau_gpuobj_new_fake(dev, c_ramfc, c_offset + c_ramfc, ++ 0x4000, 0, NULL, &chan->ramfc); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < c_vmpd; i += 4) ++ BAR0_WI32(chan->ramin->gpuobj, i, 0); ++ ++ /* VM page directory */ ++ ret = nouveau_gpuobj_new_fake(dev, c_vmpd, c_offset + c_vmpd, ++ 0x4000, 0, &chan->vm_pd, NULL); ++ if (ret) ++ return ret; ++ for (i = 0; i < 0x4000; i += 8) { ++ BAR0_WI32(chan->vm_pd, i + 0x00, 0x00000000); ++ BAR0_WI32(chan->vm_pd, i + 0x04, 0x00000000); ++ } ++ ++ /* PRAMIN page table, cheat and map into VM at 0x0000000000. ++ * We map the entire fake channel into the start of the PRAMIN BAR ++ */ ++ ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pt_size, 0x1000, ++ 0, &priv->pramin_pt); ++ if (ret) ++ return ret; ++ ++ for (i = 0, v = c_offset; i < pt_size; i += 8, v += 0x1000) { ++ if (v < (c_offset + c_size)) ++ BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v | 1); ++ else ++ BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, 0x00000009); ++ BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000); ++ } ++ ++ BAR0_WI32(chan->vm_pd, 0x00, priv->pramin_pt->instance | 0x63); ++ BAR0_WI32(chan->vm_pd, 0x04, 0x00000000); ++ ++ /* VRAM page table(s), mapped into VM at +1GiB */ ++ for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) { ++ ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ++ NV50_VM_BLOCK/65536*8, 0, 0, ++ &chan->vm_vram_pt[i]); ++ if (ret) { ++ NV_ERROR(dev, "Error creating VRAM page tables: %d\n", ++ ret); ++ dev_priv->vm_vram_pt_nr = i; ++ return ret; ++ } ++ dev_priv->vm_vram_pt[i] = chan->vm_vram_pt[i]->gpuobj; ++ ++ for (v = 0; v < dev_priv->vm_vram_pt[i]->im_pramin->size; ++ v += 4) ++ BAR0_WI32(dev_priv->vm_vram_pt[i], v, 0); ++ ++ BAR0_WI32(chan->vm_pd, 0x10 + (i*8), ++ chan->vm_vram_pt[i]->instance | 0x61); ++ BAR0_WI32(chan->vm_pd, 0x14 + (i*8), 0); ++ } ++ ++ /* DMA object for PRAMIN BAR */ ++ ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 6*4, 16, 0, ++ &priv->pramin_bar); ++ if (ret) ++ return ret; ++ BAR0_WI32(priv->pramin_bar->gpuobj, 0x00, 0x7fc00000); ++ BAR0_WI32(priv->pramin_bar->gpuobj, 0x04, dev_priv->ramin_size - 1); ++ BAR0_WI32(priv->pramin_bar->gpuobj, 0x08, 0x00000000); ++ BAR0_WI32(priv->pramin_bar->gpuobj, 0x0c, 0x00000000); ++ BAR0_WI32(priv->pramin_bar->gpuobj, 0x10, 0x00000000); ++ BAR0_WI32(priv->pramin_bar->gpuobj, 0x14, 0x00000000); ++ ++ /* DMA object for FB BAR */ ++ ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 6*4, 16, 0, ++ &priv->fb_bar); ++ if (ret) ++ return ret; ++ BAR0_WI32(priv->fb_bar->gpuobj, 0x00, 0x7fc00000); ++ BAR0_WI32(priv->fb_bar->gpuobj, 0x04, 0x40000000 + ++ drm_get_resource_len(dev, 1) - 1); ++ BAR0_WI32(priv->fb_bar->gpuobj, 0x08, 0x40000000); ++ BAR0_WI32(priv->fb_bar->gpuobj, 0x0c, 0x00000000); ++ BAR0_WI32(priv->fb_bar->gpuobj, 0x10, 0x00000000); ++ BAR0_WI32(priv->fb_bar->gpuobj, 0x14, 0x00000000); ++ ++ /* Poke the relevant regs, and pray it works :) */ ++ nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12)); ++ nv_wr32(dev, NV50_PUNK_UNK1710, 0); ++ nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12) | ++ NV50_PUNK_BAR_CFG_BASE_VALID); ++ nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->fb_bar->instance >> 4) | ++ NV50_PUNK_BAR1_CTXDMA_VALID); ++ nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->instance >> 4) | ++ NV50_PUNK_BAR3_CTXDMA_VALID); ++ ++ for (i = 0; i < 8; i++) ++ nv_wr32(dev, 0x1900 + (i*4), 0); ++ ++ /* Assume that praying isn't enough, check that we can re-read the ++ * entire fake channel back from the PRAMIN BAR */ ++ dev_priv->engine.instmem.prepare_access(dev, false); ++ for (i = 0; i < c_size; i += 4) { ++ if (nv_rd32(dev, NV_RAMIN + i) != nv_ri32(dev, i)) { ++ NV_ERROR(dev, "Error reading back PRAMIN at 0x%08x\n", ++ i); ++ dev_priv->engine.instmem.finish_access(dev); ++ return -EINVAL; ++ } ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, save_nv001700); ++ ++ /* Global PRAMIN heap */ ++ if (nouveau_mem_init_heap(&dev_priv->ramin_heap, ++ c_size, dev_priv->ramin_size - c_size)) { ++ dev_priv->ramin_heap = NULL; ++ NV_ERROR(dev, "Failed to init RAMIN heap\n"); ++ } ++ ++ /*XXX: incorrect, but needed to make hash func "work" */ ++ dev_priv->ramht_offset = 0x10000; ++ dev_priv->ramht_bits = 9; ++ dev_priv->ramht_size = (1 << dev_priv->ramht_bits); ++ return 0; ++} ++ ++void ++nv50_instmem_takedown(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; ++ struct nouveau_channel *chan = dev_priv->fifos[0]; ++ int i; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ if (!priv) ++ return; ++ ++ /* Restore state from before init */ ++ for (i = 0x1700; i <= 0x1710; i += 4) ++ nv_wr32(dev, i, priv->save1700[(i - 0x1700) / 4]); ++ ++ nouveau_gpuobj_ref_del(dev, &priv->fb_bar); ++ nouveau_gpuobj_ref_del(dev, &priv->pramin_bar); ++ nouveau_gpuobj_ref_del(dev, &priv->pramin_pt); ++ ++ /* Destroy dummy channel */ ++ if (chan) { ++ for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) { ++ nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]); ++ dev_priv->vm_vram_pt[i] = NULL; ++ } ++ dev_priv->vm_vram_pt_nr = 0; ++ ++ nouveau_gpuobj_del(dev, &chan->vm_pd); ++ nouveau_gpuobj_ref_del(dev, &chan->ramfc); ++ nouveau_gpuobj_ref_del(dev, &chan->ramin); ++ nouveau_mem_takedown(&chan->ramin_heap); ++ ++ dev_priv->fifos[0] = dev_priv->fifos[127] = NULL; ++ kfree(chan); ++ } ++ ++ dev_priv->engine.instmem.priv = NULL; ++ kfree(priv); ++} ++ ++int ++nv50_instmem_suspend(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *chan = dev_priv->fifos[0]; ++ struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; ++ int i; ++ ++ ramin->im_backing_suspend = vmalloc(ramin->im_pramin->size); ++ if (!ramin->im_backing_suspend) ++ return -ENOMEM; ++ ++ for (i = 0; i < ramin->im_pramin->size; i += 4) ++ ramin->im_backing_suspend[i/4] = nv_ri32(dev, i); ++ return 0; ++} ++ ++void ++nv50_instmem_resume(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; ++ struct nouveau_channel *chan = dev_priv->fifos[0]; ++ struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; ++ int i; ++ ++ nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, (ramin->im_backing_start >> 16)); ++ for (i = 0; i < ramin->im_pramin->size; i += 4) ++ BAR0_WI32(ramin, i, ramin->im_backing_suspend[i/4]); ++ vfree(ramin->im_backing_suspend); ++ ramin->im_backing_suspend = NULL; ++ ++ /* Poke the relevant regs, and pray it works :) */ ++ nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12)); ++ nv_wr32(dev, NV50_PUNK_UNK1710, 0); ++ nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12) | ++ NV50_PUNK_BAR_CFG_BASE_VALID); ++ nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->fb_bar->instance >> 4) | ++ NV50_PUNK_BAR1_CTXDMA_VALID); ++ nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->instance >> 4) | ++ NV50_PUNK_BAR3_CTXDMA_VALID); ++ ++ for (i = 0; i < 8; i++) ++ nv_wr32(dev, 0x1900 + (i*4), 0); ++} ++ ++int ++nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, ++ uint32_t *sz) ++{ ++ int ret; ++ ++ if (gpuobj->im_backing) ++ return -EINVAL; ++ ++ *sz = (*sz + (NV50_INSTMEM_PAGE_SIZE-1)) & ~(NV50_INSTMEM_PAGE_SIZE-1); ++ if (*sz == 0) ++ return -EINVAL; ++ ++ ret = nouveau_bo_new(dev, NULL, *sz, 0, TTM_PL_FLAG_VRAM, 0, 0x0000, ++ true, false, &gpuobj->im_backing); ++ if (ret) { ++ NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret); ++ return ret; ++ } ++ ++ ret = nouveau_bo_pin(gpuobj->im_backing, TTM_PL_FLAG_VRAM); ++ if (ret) { ++ NV_ERROR(dev, "error pinning PRAMIN backing VRAM: %d\n", ret); ++ nouveau_bo_ref(NULL, &gpuobj->im_backing); ++ return ret; ++ } ++ ++ gpuobj->im_backing_start = gpuobj->im_backing->bo.mem.mm_node->start; ++ gpuobj->im_backing_start <<= PAGE_SHIFT; ++ ++ return 0; ++} ++ ++void ++nv50_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ ++ if (gpuobj && gpuobj->im_backing) { ++ if (gpuobj->im_bound) ++ dev_priv->engine.instmem.unbind(dev, gpuobj); ++ nouveau_bo_unpin(gpuobj->im_backing); ++ nouveau_bo_ref(NULL, &gpuobj->im_backing); ++ gpuobj->im_backing = NULL; ++ } ++} ++ ++int ++nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; ++ uint32_t pte, pte_end, vram; ++ ++ if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) ++ return -EINVAL; ++ ++ NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n", ++ gpuobj->im_pramin->start, gpuobj->im_pramin->size); ++ ++ pte = (gpuobj->im_pramin->start >> 12) << 3; ++ pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte; ++ vram = gpuobj->im_backing_start; ++ ++ NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n", ++ gpuobj->im_pramin->start, pte, pte_end); ++ NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start); ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ while (pte < pte_end) { ++ nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 0)/4, vram | 1); ++ nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000); ++ ++ pte += 8; ++ vram += NV50_INSTMEM_PAGE_SIZE; ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ nv_wr32(dev, 0x100c80, 0x00040001); ++ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { ++ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (1)\n"); ++ NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); ++ return -EBUSY; ++ } ++ ++ nv_wr32(dev, 0x100c80, 0x00060001); ++ if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { ++ NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); ++ NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); ++ return -EBUSY; ++ } ++ ++ gpuobj->im_bound = 1; ++ return 0; ++} ++ ++int ++nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; ++ uint32_t pte, pte_end; ++ ++ if (gpuobj->im_bound == 0) ++ return -EINVAL; ++ ++ pte = (gpuobj->im_pramin->start >> 12) << 3; ++ pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte; ++ ++ dev_priv->engine.instmem.prepare_access(dev, true); ++ while (pte < pte_end) { ++ nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 0)/4, 0x00000009); ++ nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000); ++ pte += 8; ++ } ++ dev_priv->engine.instmem.finish_access(dev); ++ ++ gpuobj->im_bound = 0; ++ return 0; ++} ++ ++void ++nv50_instmem_prepare_access(struct drm_device *dev, bool write) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; ++ ++ priv->last_access_wr = write; ++} ++ ++void ++nv50_instmem_finish_access(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; ++ ++ if (priv->last_access_wr) { ++ nv_wr32(dev, 0x070000, 0x00000001); ++ if (!nv_wait(0x070000, 0x00000001, 0x00000000)) ++ NV_ERROR(dev, "PRAMIN flush timeout\n"); ++ } ++} ++ +diff --git a/drivers/gpu/drm/nouveau/nv50_mc.c b/drivers/gpu/drm/nouveau/nv50_mc.c +new file mode 100644 +index 0000000..e0a9c3f +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_mc.c +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (C) 2007 Ben Skeggs. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm.h" ++#include "nouveau_drv.h" ++ ++int ++nv50_mc_init(struct drm_device *dev) ++{ ++ nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); ++ return 0; ++} ++ ++void nv50_mc_takedown(struct drm_device *dev) ++{ ++} +diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c +new file mode 100644 +index 0000000..d7fab7d +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nv50_sor.c +@@ -0,0 +1,265 @@ ++/* ++ * Copyright (C) 2008 Maarten Maathuis. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial ++ * portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ++ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "drmP.h" ++#include "drm_crtc_helper.h" ++ ++#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) ++#include "nouveau_reg.h" ++#include "nouveau_drv.h" ++#include "nouveau_dma.h" ++#include "nouveau_encoder.h" ++#include "nouveau_connector.h" ++#include "nouveau_crtc.h" ++#include "nv50_display.h" ++ ++static void ++nv50_sor_disconnect(struct nouveau_encoder *nv_encoder) ++{ ++ struct drm_device *dev = to_drm_encoder(nv_encoder)->dev; ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_channel *evo = dev_priv->evo; ++ int ret; ++ ++ NV_DEBUG(dev, "Disconnecting SOR %d\n", nv_encoder->or); ++ ++ ret = RING_SPACE(evo, 2); ++ if (ret) { ++ NV_ERROR(dev, "no space while disconnecting SOR\n"); ++ return; ++ } ++ BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); ++ OUT_RING(evo, 0); ++} ++ ++static void ++nv50_sor_dpms(struct drm_encoder *encoder, int mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ uint32_t val; ++ int or = nv_encoder->or; ++ ++ NV_DEBUG(dev, "or %d mode %d\n", or, mode); ++ ++ /* wait for it to be done */ ++ if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_CTRL(or), ++ NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING, 0)) { ++ NV_ERROR(dev, "timeout: SOR_DPMS_CTRL_PENDING(%d) == 0\n", or); ++ NV_ERROR(dev, "SOR_DPMS_CTRL(%d) = 0x%08x\n", or, ++ nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or))); ++ } ++ ++ val = nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or)); ++ ++ if (mode == DRM_MODE_DPMS_ON) ++ val |= NV50_PDISPLAY_SOR_DPMS_CTRL_ON; ++ else ++ val &= ~NV50_PDISPLAY_SOR_DPMS_CTRL_ON; ++ ++ nv_wr32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or), val | ++ NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING); ++ if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_STATE(or), ++ NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) { ++ NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", or); ++ NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", or, ++ nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or))); ++ } ++} ++ ++static void ++nv50_sor_save(struct drm_encoder *encoder) ++{ ++ NV_ERROR(encoder->dev, "!!\n"); ++} ++ ++static void ++nv50_sor_restore(struct drm_encoder *encoder) ++{ ++ NV_ERROR(encoder->dev, "!!\n"); ++} ++ ++static bool ++nv50_sor_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct nouveau_connector *connector; ++ ++ NV_DEBUG(encoder->dev, "or %d\n", nv_encoder->or); ++ ++ connector = nouveau_encoder_connector_get(nv_encoder); ++ if (!connector) { ++ NV_ERROR(encoder->dev, "Encoder has no connector\n"); ++ return false; ++ } ++ ++ if (connector->scaling_mode != DRM_MODE_SCALE_NONE && ++ connector->native_mode) { ++ int id = adjusted_mode->base.id; ++ *adjusted_mode = *connector->native_mode; ++ adjusted_mode->base.id = id; ++ } ++ ++ return true; ++} ++ ++static void ++nv50_sor_prepare(struct drm_encoder *encoder) ++{ ++} ++ ++static void ++nv50_sor_commit(struct drm_encoder *encoder) ++{ ++} ++ ++static void ++nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; ++ struct nouveau_channel *evo = dev_priv->evo; ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_device *dev = encoder->dev; ++ struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc); ++ uint32_t mode_ctl = 0; ++ int ret; ++ ++ NV_DEBUG(dev, "or %d\n", nv_encoder->or); ++ ++ nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON); ++ ++ switch (nv_encoder->dcb->type) { ++ case OUTPUT_TMDS: ++ mode_ctl |= NV50_EVO_SOR_MODE_CTRL_TMDS; ++ if (adjusted_mode->clock > 165000) ++ mode_ctl |= NV50_EVO_SOR_MODE_CTRL_TMDS_DUAL_LINK; ++ break; ++ default: ++ break; ++ } ++ ++ if (crtc->index == 1) ++ mode_ctl |= NV50_EVO_SOR_MODE_CTRL_CRTC1; ++ else ++ mode_ctl |= NV50_EVO_SOR_MODE_CTRL_CRTC0; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ++ mode_ctl |= NV50_EVO_SOR_MODE_CTRL_NHSYNC; ++ ++ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ++ mode_ctl |= NV50_EVO_SOR_MODE_CTRL_NVSYNC; ++ ++ ret = RING_SPACE(evo, 2); ++ if (ret) { ++ NV_ERROR(dev, "no space while connecting SOR\n"); ++ return; ++ } ++ BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); ++ OUT_RING(evo, mode_ctl); ++} ++ ++static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = { ++ .dpms = nv50_sor_dpms, ++ .save = nv50_sor_save, ++ .restore = nv50_sor_restore, ++ .mode_fixup = nv50_sor_mode_fixup, ++ .prepare = nv50_sor_prepare, ++ .commit = nv50_sor_commit, ++ .mode_set = nv50_sor_mode_set, ++ .detect = NULL ++}; ++ ++static void ++nv50_sor_destroy(struct drm_encoder *encoder) ++{ ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ ++ if (!encoder) ++ return; ++ ++ NV_DEBUG(encoder->dev, "\n"); ++ ++ drm_encoder_cleanup(encoder); ++ ++ kfree(nv_encoder); ++} ++ ++static const struct drm_encoder_funcs nv50_sor_encoder_funcs = { ++ .destroy = nv50_sor_destroy, ++}; ++ ++int ++nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) ++{ ++ struct nouveau_encoder *nv_encoder = NULL; ++ struct drm_encoder *encoder; ++ bool dum; ++ int type; ++ ++ NV_DEBUG(dev, "\n"); ++ ++ switch (entry->type) { ++ case OUTPUT_TMDS: ++ NV_INFO(dev, "Detected a TMDS output\n"); ++ type = DRM_MODE_ENCODER_TMDS; ++ break; ++ case OUTPUT_LVDS: ++ NV_INFO(dev, "Detected a LVDS output\n"); ++ type = DRM_MODE_ENCODER_LVDS; ++ ++ if (nouveau_bios_parse_lvds_table(dev, 0, &dum, &dum)) { ++ NV_ERROR(dev, "Failed parsing LVDS table\n"); ++ return -EINVAL; ++ } ++ break; ++ case OUTPUT_DP: ++ NV_INFO(dev, "Detected a DP output\n"); ++ type = DRM_MODE_ENCODER_TMDS; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); ++ if (!nv_encoder) ++ return -ENOMEM; ++ encoder = to_drm_encoder(nv_encoder); ++ ++ nv_encoder->dcb = entry; ++ nv_encoder->or = ffs(entry->or) - 1; ++ ++ nv_encoder->disconnect = nv50_sor_disconnect; ++ ++ drm_encoder_init(dev, encoder, &nv50_sor_encoder_funcs, type); ++ drm_encoder_helper_add(encoder, &nv50_sor_helper_funcs); ++ ++ encoder->possible_crtcs = entry->heads; ++ encoder->possible_clones = 0; ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nvreg.h b/drivers/gpu/drm/nouveau/nvreg.h +new file mode 100644 +index 0000000..5998c35 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nvreg.h +@@ -0,0 +1,535 @@ ++/* $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_PTV_OFFSET 0x0000D000 ++#define NV_PTV_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_PTV_TV_INDEX 0x0000d220 ++#define NV_PTV_TV_DATA 0x0000d224 ++#define NV_PTV_HFILTER 0x0000d310 ++#define NV_PTV_HFILTER2 0x0000d390 ++#define NV_PTV_VFILTER 0x0000d510 ++ ++#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_43 0x43 ++# 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_49 0x49 ++# 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_PRAMDAC_PLL_COEFF_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_PRAMDAC_PLL_COEFF_SELECT_PLL_SOURCE_VPLL2 (8 << 8) ++# define NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1 (1 << 16) ++# define NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1 (2 << 16) ++# define NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK2 (4 << 16) ++# define NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK2 (8 << 16) ++# define NV_PRAMDAC_PLL_COEFF_SELECT_TV_CLK_SOURCE_VIP (1 << 20) ++# define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2 (1 << 28) ++# define NV_PRAMDAC_PLL_COEFF_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_TV_SETUP 0x00680700 ++#define NV_PRAMDAC_TV_VTOTAL 0x00680720 ++#define NV_PRAMDAC_TV_VSKEW 0x00680724 ++#define NV_PRAMDAC_TV_VSYNC_DELAY 0x00680728 ++#define NV_PRAMDAC_TV_HTOTAL 0x0068072c ++#define NV_PRAMDAC_TV_HSKEW 0x00680730 ++#define NV_PRAMDAC_TV_HSYNC_DELAY 0x00680734 ++#define NV_PRAMDAC_TV_HSYNC_DELAY2 0x00680738 ++ ++#define NV_PRAMDAC_TV_SETUP 0x00680700 ++ ++#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_FP_MARGIN_COLOR 0x0068084c ++#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 ++ ++#define NV_PRAMDAC_8C0 0x006808c0 ++ ++/* Some kind of switch */ ++#define NV_PRAMDAC_900 0x00680900 ++#define NV_PRAMDAC_A20 0x00680A20 ++#define NV_PRAMDAC_A24 0x00680A24 ++#define NV_PRAMDAC_A34 0x00680A34 ++ ++#define NV_PRAMDAC_CTV 0x00680c00 ++ ++/* 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 +diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c +index 87c0625..863ac5e 100644 +--- a/drivers/gpu/drm/ttm/ttm_bo.c ++++ b/drivers/gpu/drm/ttm/ttm_bo.c +@@ -123,6 +123,7 @@ int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo, bool interruptible) + } + return 0; + } ++EXPORT_SYMBOL(ttm_bo_wait_unreserved); + + static void ttm_bo_add_to_lru(struct ttm_buffer_object *bo) + { +@@ -883,6 +884,7 @@ int ttm_bo_wait_cpu(struct ttm_buffer_object *bo, bool no_wait) + + return ret; + } ++EXPORT_SYMBOL(ttm_bo_wait_cpu); + + int ttm_bo_move_buffer(struct ttm_buffer_object *bo, + uint32_t proposed_placement, +@@ -1722,12 +1724,14 @@ int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait) + ttm_bo_unreserve(bo); + return ret; + } ++EXPORT_SYMBOL(ttm_bo_synccpu_write_grab); + + void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo) + { + if (atomic_dec_and_test(&bo->cpu_writers)) + wake_up_all(&bo->event_queue); + } ++EXPORT_SYMBOL(ttm_bo_synccpu_write_release); + + /** + * A buffer object shrink method that tries to swap out the first +diff --git a/include/drm/Kbuild b/include/drm/Kbuild +index b940fdf..cfa6af4 100644 +--- a/include/drm/Kbuild ++++ b/include/drm/Kbuild +@@ -8,3 +8,4 @@ unifdef-y += radeon_drm.h + unifdef-y += sis_drm.h + unifdef-y += savage_drm.h + unifdef-y += via_drm.h ++unifdef-y += nouveau_drm.h +diff --git a/include/drm/i2c/ch7006.h b/include/drm/i2c/ch7006.h +new file mode 100644 +index 0000000..8390b43 +--- /dev/null ++++ b/include/drm/i2c/ch7006.h +@@ -0,0 +1,86 @@ ++/* ++ * Copyright (C) 2009 Francisco Jerez. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sublicense, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 __DRM_I2C_CH7006_H__ ++#define __DRM_I2C_CH7006_H__ ++ ++/** ++ * struct ch7006_encoder_params ++ * ++ * Describes how the ch7006 is wired up with the GPU. It should be ++ * used as the @params parameter of its @set_config method. ++ * ++ * See "http://www.chrontel.com/pdf/7006.pdf" for their precise ++ * meaning. ++ */ ++struct ch7006_encoder_params { ++ enum { ++ CH7006_FORMAT_RGB16 = 0, ++ CH7006_FORMAT_YCrCb24m16, ++ CH7006_FORMAT_RGB24m16, ++ CH7006_FORMAT_RGB15, ++ CH7006_FORMAT_RGB24m12C, ++ CH7006_FORMAT_RGB24m12I, ++ CH7006_FORMAT_RGB24m8, ++ CH7006_FORMAT_RGB16m8, ++ CH7006_FORMAT_RGB15m8, ++ CH7006_FORMAT_YCrCb24m8, ++ } input_format; ++ ++ enum { ++ CH7006_CLOCK_SLAVE = 0, ++ CH7006_CLOCK_MASTER, ++ } clock_mode; ++ ++ enum { ++ CH7006_CLOCK_EDGE_NEG = 0, ++ CH7006_CLOCK_EDGE_POS, ++ } clock_edge; ++ ++ int xcm, pcm; ++ ++ enum { ++ CH7006_SYNC_SLAVE = 0, ++ CH7006_SYNC_MASTER, ++ } sync_direction; ++ ++ enum { ++ CH7006_SYNC_SEPARATED = 0, ++ CH7006_SYNC_EMBEDDED, ++ } sync_encoding; ++ ++ enum { ++ CH7006_POUT_1_8V = 0, ++ CH7006_POUT_3_3V, ++ } pout_level; ++ ++ enum { ++ CH7006_ACTIVE_HSYNC = 0, ++ CH7006_ACTIVE_DSTART, ++ } active_detect; ++}; ++ ++#endif +diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h +new file mode 100644 +index 0000000..1e67c44 +--- /dev/null ++++ b/include/drm/nouveau_drm.h +@@ -0,0 +1,220 @@ ++/* ++ * Copyright 2005 Stephane Marchesin. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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_DRM_H__ ++#define __NOUVEAU_DRM_H__ ++ ++#define NOUVEAU_DRM_HEADER_PATCHLEVEL 15 ++ ++struct drm_nouveau_channel_alloc { ++ uint32_t fb_ctxdma_handle; ++ uint32_t tt_ctxdma_handle; ++ ++ int channel; ++ ++ /* Notifier memory */ ++ uint32_t notifier_handle; ++ ++ /* DRM-enforced subchannel assignments */ ++ struct { ++ uint32_t handle; ++ uint32_t grclass; ++ } subchan[8]; ++ uint32_t nr_subchan; ++}; ++ ++struct drm_nouveau_channel_free { ++ int channel; ++}; ++ ++struct drm_nouveau_grobj_alloc { ++ int channel; ++ uint32_t handle; ++ int class; ++}; ++ ++struct drm_nouveau_notifierobj_alloc { ++ uint32_t channel; ++ uint32_t handle; ++ uint32_t size; ++ uint32_t offset; ++}; ++ ++struct drm_nouveau_gpuobj_free { ++ int channel; ++ uint32_t handle; ++}; ++ ++/* FIXME : maybe unify {GET,SET}PARAMs */ ++#define NOUVEAU_GETPARAM_PCI_VENDOR 3 ++#define NOUVEAU_GETPARAM_PCI_DEVICE 4 ++#define NOUVEAU_GETPARAM_BUS_TYPE 5 ++#define NOUVEAU_GETPARAM_FB_PHYSICAL 6 ++#define NOUVEAU_GETPARAM_AGP_PHYSICAL 7 ++#define NOUVEAU_GETPARAM_FB_SIZE 8 ++#define NOUVEAU_GETPARAM_AGP_SIZE 9 ++#define NOUVEAU_GETPARAM_PCI_PHYSICAL 10 ++#define NOUVEAU_GETPARAM_CHIPSET_ID 11 ++#define NOUVEAU_GETPARAM_VM_VRAM_BASE 12 ++struct drm_nouveau_getparam { ++ uint64_t param; ++ uint64_t value; ++}; ++ ++struct drm_nouveau_setparam { ++ uint64_t param; ++ uint64_t value; ++}; ++ ++#define NOUVEAU_GEM_DOMAIN_CPU (1 << 0) ++#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1) ++#define NOUVEAU_GEM_DOMAIN_GART (1 << 2) ++#define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3) ++ ++struct drm_nouveau_gem_info { ++ uint32_t handle; ++ uint32_t domain; ++ uint64_t size; ++ uint64_t offset; ++ uint64_t map_handle; ++ uint32_t tile_mode; ++ uint32_t tile_flags; ++}; ++ ++struct drm_nouveau_gem_new { ++ struct drm_nouveau_gem_info info; ++ uint32_t channel_hint; ++ uint32_t align; ++}; ++ ++struct drm_nouveau_gem_pushbuf_bo { ++ uint64_t user_priv; ++ uint32_t handle; ++ uint32_t read_domains; ++ uint32_t write_domains; ++ uint32_t valid_domains; ++ uint32_t presumed_ok; ++ uint32_t presumed_domain; ++ uint64_t presumed_offset; ++}; ++ ++#define NOUVEAU_GEM_RELOC_LOW (1 << 0) ++#define NOUVEAU_GEM_RELOC_HIGH (1 << 1) ++#define NOUVEAU_GEM_RELOC_OR (1 << 2) ++struct drm_nouveau_gem_pushbuf_reloc { ++ uint32_t bo_index; ++ uint32_t reloc_index; ++ uint32_t flags; ++ uint32_t data; ++ uint32_t vor; ++ uint32_t tor; ++}; ++ ++#define NOUVEAU_GEM_MAX_BUFFERS 1024 ++#define NOUVEAU_GEM_MAX_RELOCS 1024 ++ ++struct drm_nouveau_gem_pushbuf { ++ uint32_t channel; ++ uint32_t nr_dwords; ++ uint32_t nr_buffers; ++ uint32_t nr_relocs; ++ uint64_t dwords; ++ uint64_t buffers; ++ uint64_t relocs; ++}; ++ ++struct drm_nouveau_gem_pushbuf_call { ++ uint32_t channel; ++ uint32_t handle; ++ uint32_t offset; ++ uint32_t nr_buffers; ++ uint32_t nr_relocs; ++ uint32_t nr_dwords; ++ uint64_t buffers; ++ uint64_t relocs; ++ uint32_t suffix0; ++ uint32_t suffix1; ++ /* below only accessed for CALL2 */ ++ uint64_t vram_available; ++ uint64_t gart_available; ++}; ++ ++struct drm_nouveau_gem_pin { ++ uint32_t handle; ++ uint32_t domain; ++ uint64_t offset; ++}; ++ ++struct drm_nouveau_gem_unpin { ++ uint32_t handle; ++}; ++ ++#define NOUVEAU_GEM_CPU_PREP_NOWAIT 0x00000001 ++#define NOUVEAU_GEM_CPU_PREP_NOBLOCK 0x00000002 ++#define NOUVEAU_GEM_CPU_PREP_WRITE 0x00000004 ++struct drm_nouveau_gem_cpu_prep { ++ uint32_t handle; ++ uint32_t flags; ++}; ++ ++struct drm_nouveau_gem_cpu_fini { ++ uint32_t handle; ++}; ++ ++struct drm_nouveau_gem_tile { ++ uint32_t handle; ++ uint32_t offset; ++ uint32_t size; ++ uint32_t tile_mode; ++ uint32_t tile_flags; ++}; ++ ++enum nouveau_bus_type { ++ NV_AGP = 0, ++ NV_PCI = 1, ++ NV_PCIE = 2, ++}; ++ ++struct drm_nouveau_sarea { ++}; ++ ++#define DRM_NOUVEAU_CARD_INIT 0x00 ++#define DRM_NOUVEAU_GETPARAM 0x01 ++#define DRM_NOUVEAU_SETPARAM 0x02 ++#define DRM_NOUVEAU_CHANNEL_ALLOC 0x03 ++#define DRM_NOUVEAU_CHANNEL_FREE 0x04 ++#define DRM_NOUVEAU_GROBJ_ALLOC 0x05 ++#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x06 ++#define DRM_NOUVEAU_GPUOBJ_FREE 0x07 ++#define DRM_NOUVEAU_GEM_NEW 0x40 ++#define DRM_NOUVEAU_GEM_PUSHBUF 0x41 ++#define DRM_NOUVEAU_GEM_PUSHBUF_CALL 0x42 ++#define DRM_NOUVEAU_GEM_PIN 0x43 /* !KMS only */ ++#define DRM_NOUVEAU_GEM_UNPIN 0x44 /* !KMS only */ ++#define DRM_NOUVEAU_GEM_CPU_PREP 0x45 ++#define DRM_NOUVEAU_GEM_CPU_FINI 0x46 ++#define DRM_NOUVEAU_GEM_INFO 0x47 ++#define DRM_NOUVEAU_GEM_PUSHBUF_CALL2 0x48 ++ ++#endif /* __NOUVEAU_DRM_H__ */