From 49b6ccd3b71b863346cfccd3407b93440308bcdc Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Wed, 11 May 2011 13:05:40 +0200 Subject: [PATCH] linux: update to linux-2.6.39-rc7 Signed-off-by: Stephan Raue --- packages/linux/meta | 2 +- ...rc6-056_mceusb_add_DELL_receiver-0.1.patch | 12 - ...c6-110-drm_nouveau_upstream-20110509.patch | 9012 ----------------- ...> linux-2.6.39-rc7-000_crosscompile.patch} | 0 ...ux-2.6.39-rc7-002_bash_only_feature.patch} | 0 ...linux-2.6.39-rc7-003-no_dev_console.patch} | 0 ...c7-004_lower_undefined_mode_timeout.patch} | 0 ...2.6.39-rc7-005_kconfig_no_timestamp.patch} | 0 ...=> linux-2.6.39-rc7-006_enable_utf8.patch} | 0 ...linux-2.6.39-rc7-007_die_floppy_die.patch} | 0 ...08-hda_intel_prealloc_4mb_dmabuffer.patch} | 0 ...09_disable_i8042_check_on_apple_mac.patch} | 0 ...39-rc7-041-add_rtl8192se_driver-0.2.patch} | 0 ...6.39-rc7-050_add_appleir_usb_driver.patch} | 0 ....39-rc7-052-aureal_remote_quirk-0.1.patch} | 0 ...i-remote_all_keys_and_keychange-0.1.patch} | 0 ...n-cir-only-warn-about-unknown-chips.patch} | 0 ...enable-CIR-on-w83667hg-chip-variant.patch} | 0 ...2.6.39-rc7-057_ite-resume-debug-0.1.patch} | 0 ...r-make-IR-receive-work-after-resume.patch} | 0 ...ioneer_DVR-216D_failed_xfermode-0.1.patch} | 0 ...rc7-071-silence_i915_agp-module-0.1.patch} | 0 ...map4_pandaboard_fix_dvi_support-0.1.patch} | 0 ...x-2.6.39-rc7-716_mm-zero_swappiness.patch} | 0 24 files changed, 1 insertion(+), 9025 deletions(-) delete mode 100644 packages/linux/patches/linux-2.6.39-rc6-056_mceusb_add_DELL_receiver-0.1.patch delete mode 100644 packages/linux/patches/linux-2.6.39-rc6-110-drm_nouveau_upstream-20110509.patch rename packages/linux/patches/{linux-2.6.39-rc6-000_crosscompile.patch => linux-2.6.39-rc7-000_crosscompile.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-002_bash_only_feature.patch => linux-2.6.39-rc7-002_bash_only_feature.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-003-no_dev_console.patch => linux-2.6.39-rc7-003-no_dev_console.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-004_lower_undefined_mode_timeout.patch => linux-2.6.39-rc7-004_lower_undefined_mode_timeout.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-005_kconfig_no_timestamp.patch => linux-2.6.39-rc7-005_kconfig_no_timestamp.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-006_enable_utf8.patch => linux-2.6.39-rc7-006_enable_utf8.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-007_die_floppy_die.patch => linux-2.6.39-rc7-007_die_floppy_die.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-008-hda_intel_prealloc_4mb_dmabuffer.patch => linux-2.6.39-rc7-008-hda_intel_prealloc_4mb_dmabuffer.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-009_disable_i8042_check_on_apple_mac.patch => linux-2.6.39-rc7-009_disable_i8042_check_on_apple_mac.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-041-add_rtl8192se_driver-0.2.patch => linux-2.6.39-rc7-041-add_rtl8192se_driver-0.2.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-050_add_appleir_usb_driver.patch => linux-2.6.39-rc7-050_add_appleir_usb_driver.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-052-aureal_remote_quirk-0.1.patch => linux-2.6.39-rc7-052-aureal_remote_quirk-0.1.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-053_ati-remote_all_keys_and_keychange-0.1.patch => linux-2.6.39-rc7-053_ati-remote_all_keys_and_keychange-0.1.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-054_nuvoton-cir-only-warn-about-unknown-chips.patch => linux-2.6.39-rc7-054_nuvoton-cir-only-warn-about-unknown-chips.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-055_nuvoton-cir-enable-CIR-on-w83667hg-chip-variant.patch => linux-2.6.39-rc7-055_nuvoton-cir-enable-CIR-on-w83667hg-chip-variant.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-057_ite-resume-debug-0.1.patch => linux-2.6.39-rc7-057_ite-resume-debug-0.1.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-057_media-ite-cir-make-IR-receive-work-after-resume.patch => linux-2.6.39-rc7-057_media-ite-cir-make-IR-receive-work-after-resume.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-062-Pioneer_DVR-216D_failed_xfermode-0.1.patch => linux-2.6.39-rc7-062-Pioneer_DVR-216D_failed_xfermode-0.1.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-071-silence_i915_agp-module-0.1.patch => linux-2.6.39-rc7-071-silence_i915_agp-module-0.1.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-322-omap4_pandaboard_fix_dvi_support-0.1.patch => linux-2.6.39-rc7-322-omap4_pandaboard_fix_dvi_support-0.1.patch} (100%) rename packages/linux/patches/{linux-2.6.39-rc6-716_mm-zero_swappiness.patch => linux-2.6.39-rc7-716_mm-zero_swappiness.patch} (100%) diff --git a/packages/linux/meta b/packages/linux/meta index 284ef7f368..30509cc23f 100644 --- a/packages/linux/meta +++ b/packages/linux/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="linux" -PKG_VERSION="2.6.39-rc6" +PKG_VERSION="2.6.39-rc7" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/linux/patches/linux-2.6.39-rc6-056_mceusb_add_DELL_receiver-0.1.patch b/packages/linux/patches/linux-2.6.39-rc6-056_mceusb_add_DELL_receiver-0.1.patch deleted file mode 100644 index c632320aba..0000000000 --- a/packages/linux/patches/linux-2.6.39-rc6-056_mceusb_add_DELL_receiver-0.1.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Naur linux-2.6.39-rc5/drivers/media/rc/mceusb.c linux-2.6.39-rc5.patch/drivers/media/rc/mceusb.c ---- linux-2.6.39-rc5/drivers/media/rc/mceusb.c 2011-04-27 05:48:50.000000000 +0200 -+++ linux-2.6.39-rc5.patch/drivers/media/rc/mceusb.c 2011-04-29 18:10:32.361073307 +0200 -@@ -220,6 +220,8 @@ - { USB_DEVICE(VENDOR_PHILIPS, 0x206c) }, - /* Philips/Spinel plus IR transceiver for ASUS */ - { USB_DEVICE(VENDOR_PHILIPS, 0x2088) }, -+ /* Philips RC6 Transceiver, Dell branded */ -+ { USB_DEVICE(VENDOR_PHILIPS, 0x2093) }, - /* Realtek MCE IR Receiver and card reader */ - { USB_DEVICE(VENDOR_REALTEK, 0x0161), - .driver_info = MULTIFUNCTION }, diff --git a/packages/linux/patches/linux-2.6.39-rc6-110-drm_nouveau_upstream-20110509.patch b/packages/linux/patches/linux-2.6.39-rc6-110-drm_nouveau_upstream-20110509.patch deleted file mode 100644 index 2572644720..0000000000 --- a/packages/linux/patches/linux-2.6.39-rc6-110-drm_nouveau_upstream-20110509.patch +++ /dev/null @@ -1,9012 +0,0 @@ -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/Makefile linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/Makefile ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/Makefile 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/Makefile 2011-05-09 00:36:22.000000000 +0200 -@@ -20,6 +20,8 @@ - nv40_graph.o nv50_graph.o nvc0_graph.o \ - nv40_grctx.o nv50_grctx.o nvc0_grctx.o \ - nv84_crypt.o \ -+ nva3_copy.o nvc0_copy.o \ -+ nv40_mpeg.o nv50_mpeg.o \ - nv04_instmem.o nv50_instmem.o nvc0_instmem.o \ - nv50_evo.o nv50_crtc.o nv50_dac.o nv50_sor.o \ - nv50_cursor.o nv50_display.o \ -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_bios.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_bios.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_bios.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_bios.c 2011-05-09 00:36:22.000000000 +0200 -@@ -5049,11 +5049,7 @@ - pll_lim->vco1.max_n = record[11]; - pll_lim->min_p = record[12]; - pll_lim->max_p = record[13]; -- /* where did this go to?? */ -- if ((entry[0] & 0xf0) == 0x80) -- pll_lim->refclk = 27000; -- else -- pll_lim->refclk = 100000; -+ pll_lim->refclk = ROM16(entry[9]) * 1000; - } - - /* -@@ -6035,6 +6031,7 @@ - case DCB_CONNECTOR_DVI_I: - case DCB_CONNECTOR_DVI_D: - case DCB_CONNECTOR_LVDS: -+ case DCB_CONNECTOR_LVDS_SPWG: - case DCB_CONNECTOR_DP: - case DCB_CONNECTOR_eDP: - case DCB_CONNECTOR_HDMI_0: -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_bios.h linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_bios.h ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_bios.h 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_bios.h 2011-05-09 00:36:22.000000000 +0200 -@@ -82,6 +82,7 @@ - DCB_CONNECTOR_DVI_I = 0x30, - DCB_CONNECTOR_DVI_D = 0x31, - DCB_CONNECTOR_LVDS = 0x40, -+ DCB_CONNECTOR_LVDS_SPWG = 0x41, - DCB_CONNECTOR_DP = 0x46, - DCB_CONNECTOR_eDP = 0x47, - DCB_CONNECTOR_HDMI_0 = 0x60, -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_channel.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_channel.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_channel.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_channel.c 2011-05-09 00:36:22.000000000 +0200 -@@ -268,9 +268,8 @@ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; -- struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; - unsigned long flags; -+ int i; - - /* decrement the refcount, and we're done if there's still refs */ - if (likely(!atomic_dec_and_test(&chan->users))) { -@@ -294,19 +293,12 @@ - /* boot it off the hardware */ - pfifo->reassign(dev, false); - -- /* We want to give pgraph a chance to idle and get rid of all -- * potential errors. We need to do this without the context -- * switch lock held, otherwise the irq handler is unable to -- * process them. -- */ -- if (pgraph->channel(dev) == chan) -- nouveau_wait_for_idle(dev); -- - /* destroy the engine specific contexts */ - pfifo->destroy_context(chan); -- pgraph->destroy_context(chan); -- if (pcrypt->destroy_context) -- pcrypt->destroy_context(chan); -+ for (i = 0; i < NVOBJ_ENGINE_NR; i++) { -+ if (chan->engctx[i]) -+ dev_priv->eng[i]->context_del(chan, i); -+ } - - pfifo->reassign(dev, true); - -@@ -414,7 +406,7 @@ - struct nouveau_channel *chan; - int ret; - -- if (dev_priv->engine.graph.accel_blocked) -+ if (!dev_priv->eng[NVOBJ_ENGINE_GR]) - return -ENODEV; - - if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_connector.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_connector.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_connector.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_connector.c 2011-05-09 00:36:22.000000000 +0200 -@@ -442,7 +442,7 @@ - } - - /* LVDS always needs gpu scaling */ -- if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS && -+ if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS && - value == DRM_MODE_SCALE_NONE) - return -EINVAL; - -@@ -650,6 +650,7 @@ - ret = get_slave_funcs(encoder)->get_modes(encoder, connector); - - if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS || -+ nv_connector->dcb->type == DCB_CONNECTOR_LVDS_SPWG || - nv_connector->dcb->type == DCB_CONNECTOR_eDP) - ret += nouveau_connector_scaler_modes_add(connector); - -@@ -810,6 +811,7 @@ - type = DRM_MODE_CONNECTOR_HDMIA; - break; - case DCB_CONNECTOR_LVDS: -+ case DCB_CONNECTOR_LVDS_SPWG: - type = DRM_MODE_CONNECTOR_LVDS; - funcs = &nouveau_connector_funcs_lvds; - break; -@@ -838,7 +840,7 @@ - drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); - - /* Check if we need dithering enabled */ -- if (dcb->type == DCB_CONNECTOR_LVDS) { -+ if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { - bool dummy, is_24bit = false; - - ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &is_24bit); -@@ -883,7 +885,7 @@ - nv_connector->use_dithering ? - DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF); - -- if (dcb->type != DCB_CONNECTOR_LVDS) { -+ if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS) { - if (dev_priv->card_type >= NV_50) - connector->polled = DRM_CONNECTOR_POLL_HPD; - else -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_display.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_display.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_display.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_display.c 2011-05-09 00:36:22.000000000 +0200 -@@ -276,7 +276,7 @@ - struct nouveau_fence *fence; - int ret; - -- if (dev_priv->engine.graph.accel_blocked) -+ if (!dev_priv->channel) - return -ENODEV; - - s = kzalloc(sizeof(*s), GFP_KERNEL); -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_drv.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_drv.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_drv.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_drv.c 2011-05-09 00:36:22.000000000 +0200 -@@ -162,11 +162,10 @@ - struct drm_device *dev = pci_get_drvdata(pdev); - struct drm_nouveau_private *dev_priv = dev->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; -- int ret, i; -+ int ret, i, e; - - if (pm_state.event == PM_EVENT_PRETHAW) - return 0; -@@ -206,12 +205,17 @@ - nouveau_channel_idle(chan); - } - -- 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); -+ -+ for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) { -+ if (dev_priv->eng[e]) { -+ ret = dev_priv->eng[e]->fini(dev, e); -+ if (ret) -+ goto out_abort; -+ } -+ } - - ret = pinstmem->suspend(dev); - if (ret) { -@@ -242,9 +246,12 @@ - - out_abort: - NV_INFO(dev, "Re-enabling acceleration..\n"); -+ for (e = e + 1; e < NVOBJ_ENGINE_NR; e++) { -+ if (dev_priv->eng[e]) -+ dev_priv->eng[e]->init(dev, e); -+ } - pfifo->enable(dev); - pfifo->reassign(dev, true); -- pgraph->fifo_access(dev, true); - return ret; - } - -@@ -299,8 +306,10 @@ - engine->mc.init(dev); - engine->timer.init(dev); - engine->fb.init(dev); -- engine->graph.init(dev); -- engine->crypt.init(dev); -+ for (i = 0; i < NVOBJ_ENGINE_NR; i++) { -+ if (dev_priv->eng[i]) -+ dev_priv->eng[i]->init(dev, i); -+ } - engine->fifo.init(dev); - - nouveau_irq_postinstall(dev); -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_drv.h linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_drv.h ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_drv.h 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_drv.h 2011-05-09 00:36:22.000000000 +0200 -@@ -150,13 +150,12 @@ - - #define NVOBJ_ENGINE_SW 0 - #define NVOBJ_ENGINE_GR 1 --#define NVOBJ_ENGINE_PPP 2 --#define NVOBJ_ENGINE_COPY 3 --#define NVOBJ_ENGINE_VP 4 --#define NVOBJ_ENGINE_CRYPT 5 --#define NVOBJ_ENGINE_BSP 6 --#define NVOBJ_ENGINE_DISPLAY 0xcafe0001 --#define NVOBJ_ENGINE_INT 0xdeadbeef -+#define NVOBJ_ENGINE_CRYPT 2 -+#define NVOBJ_ENGINE_COPY0 3 -+#define NVOBJ_ENGINE_COPY1 4 -+#define NVOBJ_ENGINE_MPEG 5 -+#define NVOBJ_ENGINE_DISPLAY 15 -+#define NVOBJ_ENGINE_NR 16 - - #define NVOBJ_FLAG_DONT_MAP (1 << 0) - #define NVOBJ_FLAG_ZERO_ALLOC (1 << 1) -@@ -245,11 +244,8 @@ - struct nouveau_gpuobj *cache; - void *fifo_priv; - -- /* PGRAPH context */ -- /* XXX may be merge 2 pointers as private data ??? */ -- struct nouveau_gpuobj *ramin_grctx; -- struct nouveau_gpuobj *crypt_ctx; -- void *pgraph_ctx; -+ /* Execution engine contexts */ -+ void *engctx[NVOBJ_ENGINE_NR]; - - /* NV50 VM */ - struct nouveau_vm *vm; -@@ -298,6 +294,18 @@ - } debugfs; - }; - -+struct nouveau_exec_engine { -+ void (*destroy)(struct drm_device *, int engine); -+ int (*init)(struct drm_device *, int engine); -+ int (*fini)(struct drm_device *, int engine); -+ int (*context_new)(struct nouveau_channel *, int engine); -+ void (*context_del)(struct nouveau_channel *, int engine); -+ int (*object_new)(struct nouveau_channel *, int engine, -+ u32 handle, u16 class); -+ void (*set_tile_region)(struct drm_device *dev, int i); -+ void (*tlb_flush)(struct drm_device *, int engine); -+}; -+ - struct nouveau_instmem_engine { - void *priv; - -@@ -364,30 +372,6 @@ - void (*tlb_flush)(struct drm_device *dev); - }; - --struct nouveau_pgraph_engine { -- bool accel_blocked; -- bool registered; -- int grctx_size; -- void *priv; -- -- /* NV2x/NV3x context table (0x400780) */ -- struct nouveau_gpuobj *ctx_table; -- -- 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 *); -- void (*tlb_flush)(struct drm_device *dev); -- -- void (*set_tile_region)(struct drm_device *dev, int i); --}; -- - struct nouveau_display_engine { - void *priv; - int (*early_init)(struct drm_device *); -@@ -426,6 +410,19 @@ - int nr_level; - }; - -+struct nouveau_pm_memtiming { -+ int id; -+ u32 reg_100220; -+ u32 reg_100224; -+ u32 reg_100228; -+ u32 reg_10022c; -+ u32 reg_100230; -+ u32 reg_100234; -+ u32 reg_100238; -+ u32 reg_10023c; -+ u32 reg_100240; -+}; -+ - #define NOUVEAU_PM_MAX_LEVEL 8 - struct nouveau_pm_level { - struct device_attribute dev_attr; -@@ -436,11 +433,13 @@ - u32 memory; - u32 shader; - u32 unk05; -+ u32 unk0a; - - u8 voltage; - u8 fanspeed; - - u16 memscript; -+ struct nouveau_pm_memtiming *timing; - }; - - struct nouveau_pm_temp_sensor_constants { -@@ -457,17 +456,6 @@ - s16 fan_boost; - }; - --struct nouveau_pm_memtiming { -- u32 reg_100220; -- u32 reg_100224; -- u32 reg_100228; -- u32 reg_10022c; -- u32 reg_100230; -- u32 reg_100234; -- u32 reg_100238; -- u32 reg_10023c; --}; -- - struct nouveau_pm_memtimings { - bool supported; - struct nouveau_pm_memtiming *timing; -@@ -499,16 +487,6 @@ - int (*temp_get)(struct drm_device *); - }; - --struct nouveau_crypt_engine { -- bool registered; -- -- int (*init)(struct drm_device *); -- void (*takedown)(struct drm_device *); -- int (*create_context)(struct nouveau_channel *); -- void (*destroy_context)(struct nouveau_channel *); -- void (*tlb_flush)(struct drm_device *dev); --}; -- - struct nouveau_vram_engine { - int (*init)(struct drm_device *); - int (*get)(struct drm_device *, u64, u32 align, u32 size_nc, -@@ -523,12 +501,10 @@ - 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_display_engine display; - struct nouveau_gpio_engine gpio; - struct nouveau_pm_engine pm; -- struct nouveau_crypt_engine crypt; - struct nouveau_vram_engine vram; - }; - -@@ -637,6 +613,7 @@ - enum nouveau_card_type card_type; - /* exact chipset, derived from NV_PMC_BOOT_0 */ - int chipset; -+ int stepping; - int flags; - - void __iomem *mmio; -@@ -647,6 +624,7 @@ - u32 ramin_base; - bool ramin_available; - struct drm_mm ramin_heap; -+ struct nouveau_exec_engine *eng[NVOBJ_ENGINE_NR]; - struct list_head gpuobj_list; - struct list_head classes; - -@@ -745,10 +723,6 @@ - uint32_t crtc_owner; - uint32_t dac_users[4]; - -- struct nouveau_suspend_resume { -- uint32_t *ramin_copy; -- } susres; -- - struct backlight_device *backlight; - - struct { -@@ -757,8 +731,6 @@ - - struct nouveau_fbdev *nfbdev; - struct apertures_struct *apertures; -- -- bool powered_down; - }; - - static inline struct drm_nouveau_private * -@@ -883,17 +855,27 @@ - extern void nouveau_channel_idle(struct nouveau_channel *chan); - - /* nouveau_object.c */ --#define NVOBJ_CLASS(d,c,e) do { \ -+#define NVOBJ_ENGINE_ADD(d, e, p) do { \ -+ struct drm_nouveau_private *dev_priv = (d)->dev_private; \ -+ dev_priv->eng[NVOBJ_ENGINE_##e] = (p); \ -+} while (0) -+ -+#define NVOBJ_ENGINE_DEL(d, e) do { \ -+ struct drm_nouveau_private *dev_priv = (d)->dev_private; \ -+ dev_priv->eng[NVOBJ_ENGINE_##e] = NULL; \ -+} while (0) -+ -+#define NVOBJ_CLASS(d, c, e) do { \ - int ret = nouveau_gpuobj_class_new((d), (c), NVOBJ_ENGINE_##e); \ - if (ret) \ - return ret; \ --} while(0) -+} while (0) - --#define NVOBJ_MTHD(d,c,m,e) do { \ -+#define NVOBJ_MTHD(d, c, m, e) do { \ - int ret = nouveau_gpuobj_mthd_new((d), (c), (m), (e)); \ - if (ret) \ - return ret; \ --} while(0) -+} while (0) - - extern int nouveau_gpuobj_early_init(struct drm_device *); - extern int nouveau_gpuobj_init(struct drm_device *); -@@ -903,7 +885,7 @@ - extern int nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng); - extern int nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd, - int (*exec)(struct nouveau_channel *, -- u32 class, u32 mthd, u32 data)); -+ u32 class, u32 mthd, u32 data)); - extern int nouveau_gpuobj_mthd_call(struct nouveau_channel *, u32, u32, u32); - extern int nouveau_gpuobj_mthd_call2(struct drm_device *, int, u32, u32, u32); - extern int nouveau_gpuobj_channel_init(struct nouveau_channel *, -@@ -1137,81 +1119,50 @@ - extern int nvc0_fifo_unload_context(struct drm_device *); - - /* nv04_graph.c */ --extern int nv04_graph_init(struct drm_device *); --extern void nv04_graph_takedown(struct drm_device *); -+extern int nv04_graph_create(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 int nv04_graph_object_new(struct nouveau_channel *, int, u32, u16); - extern int nv04_graph_mthd_page_flip(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data); - extern struct nouveau_bitfield nv04_graph_nsource[]; - - /* nv10_graph.c */ --extern int nv10_graph_init(struct drm_device *); --extern void nv10_graph_takedown(struct drm_device *); -+extern int nv10_graph_create(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_set_tile_region(struct drm_device *dev, int i); - extern struct nouveau_bitfield nv10_graph_intr[]; - extern struct nouveau_bitfield nv10_graph_nstatus[]; - - /* nv20_graph.c */ --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 *); --extern void nv20_graph_set_tile_region(struct drm_device *dev, int i); -+extern int nv20_graph_create(struct drm_device *); - - /* nv40_graph.c */ --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 *); -+extern int nv40_graph_create(struct drm_device *); - extern void nv40_grctx_init(struct nouveau_grctx *); --extern void nv40_graph_set_tile_region(struct drm_device *dev, int i); - - /* nv50_graph.c */ --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 int nv50_graph_create(struct drm_device *); - extern int nv50_grctx_init(struct nouveau_grctx *); --extern void nv50_graph_tlb_flush(struct drm_device *dev); --extern void nv84_graph_tlb_flush(struct drm_device *dev); - extern struct nouveau_enum nv50_data_error_names[]; -+extern int nv50_graph_isr_chid(struct drm_device *dev, u64 inst); - - /* nvc0_graph.c */ --extern int nvc0_graph_init(struct drm_device *); --extern void nvc0_graph_takedown(struct drm_device *); --extern void nvc0_graph_fifo_access(struct drm_device *, bool); --extern struct nouveau_channel *nvc0_graph_channel(struct drm_device *); --extern int nvc0_graph_create_context(struct nouveau_channel *); --extern void nvc0_graph_destroy_context(struct nouveau_channel *); --extern int nvc0_graph_load_context(struct nouveau_channel *); --extern int nvc0_graph_unload_context(struct drm_device *); -+extern int nvc0_graph_create(struct drm_device *); -+extern int nvc0_graph_isr_chid(struct drm_device *dev, u64 inst); - - /* nv84_crypt.c */ --extern int nv84_crypt_init(struct drm_device *dev); --extern void nv84_crypt_fini(struct drm_device *dev); --extern int nv84_crypt_create_context(struct nouveau_channel *); --extern void nv84_crypt_destroy_context(struct nouveau_channel *); --extern void nv84_crypt_tlb_flush(struct drm_device *dev); -+extern int nv84_crypt_create(struct drm_device *); -+ -+/* nva3_copy.c */ -+extern int nva3_copy_create(struct drm_device *dev); -+ -+/* nvc0_copy.c */ -+extern int nvc0_copy_create(struct drm_device *dev, int engine); -+ -+/* nv40_mpeg.c */ -+extern int nv40_mpeg_create(struct drm_device *dev); -+ -+/* nv50_mpeg.c */ -+extern int nv50_mpeg_create(struct drm_device *dev); - - /* nv04_instmem.c */ - extern int nv04_instmem_init(struct drm_device *); -@@ -1402,8 +1353,8 @@ - /* nv50_calc. */ - int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk, - int *N1, int *M1, int *N2, int *M2, int *P); --int nv50_calc_pll2(struct drm_device *, struct pll_lims *, -- int clk, int *N, int *fN, int *M, int *P); -+int nva3_calc_pll(struct drm_device *, struct pll_lims *, -+ int clk, int *N, int *fN, int *M, int *P); - - #ifndef ioread32_native - #ifdef __BIG_ENDIAN -@@ -1579,6 +1530,13 @@ - dev->pdev->subsystem_device == sub_device; - } - -+static inline void * -+nv_engine(struct drm_device *dev, int engine) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ return (void *)dev_priv->eng[engine]; -+} -+ - /* returns 1 if device is one of the nv4x using the 0x4497 object class, - * helpful to determine a number of other hardware features - */ -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_grctx.h linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_grctx.h ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_grctx.h 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_grctx.h 2011-05-09 00:36:22.000000000 +0200 -@@ -87,10 +87,10 @@ - cp_out(ctx, CP_BRA | (mod << 18) | ip | flag | - (state ? 0 : CP_BRA_IF_CLEAR)); - } --#define cp_bra(c,f,s,n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n) -+#define cp_bra(c, f, s, n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n) - #ifdef CP_BRA_MOD --#define cp_cal(c,f,s,n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n) --#define cp_ret(c,f,s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0) -+#define cp_cal(c, f, s, n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n) -+#define cp_ret(c, f, s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0) - #endif - - static inline void -@@ -98,14 +98,14 @@ - { - cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0)); - } --#define cp_wait(c,f,s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s) -+#define cp_wait(c, f, s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s) - - static inline void - _cp_set(struct nouveau_grctx *ctx, int flag, int state) - { - cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0)); - } --#define cp_set(c,f,s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s) -+#define cp_set(c, f, s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s) - - static inline void - cp_pos(struct nouveau_grctx *ctx, int offset) -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_mem.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_mem.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_mem.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_mem.c 2011-05-09 00:36:22.000000000 +0200 -@@ -51,8 +51,7 @@ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; -- int i = tile - dev_priv->tile.reg; -+ int i = tile - dev_priv->tile.reg, j; - unsigned long save; - - nouveau_fence_unref(&tile->fence); -@@ -70,7 +69,10 @@ - nouveau_wait_for_idle(dev); - - pfb->set_tile_region(dev, i); -- pgraph->set_tile_region(dev, i); -+ for (j = 0; j < NVOBJ_ENGINE_NR; j++) { -+ if (dev_priv->eng[j] && dev_priv->eng[j]->set_tile_region) -+ dev_priv->eng[j]->set_tile_region(dev, i); -+ } - - pfifo->cache_pull(dev, true); - pfifo->reassign(dev, true); -@@ -152,8 +154,6 @@ - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - -- nouveau_bo_ref(NULL, &dev_priv->vga_ram); -- - ttm_bo_device_release(&dev_priv->ttm.bdev); - - nouveau_ttm_global_release(dev_priv); -@@ -597,10 +597,10 @@ - if (!memtimings->timing) - return; - -- /* Get "some number" from the timing reg for NV_40 -+ /* Get "some number" from the timing reg for NV_40 and NV_50 - * Used in calculations later */ -- if(dev_priv->card_type == NV_40) { -- magic_number = (nv_rd32(dev,0x100228) & 0x0f000000) >> 24; -+ if (dev_priv->card_type >= NV_40 && dev_priv->chipset < 0x98) { -+ magic_number = (nv_rd32(dev, 0x100228) & 0x0f000000) >> 24; - } - - entry = mem + mem[1]; -@@ -643,51 +643,68 @@ - /* XXX: I don't trust the -1's and +1's... they must come - * from somewhere! */ - timing->reg_100224 = (tUNK_0 + tUNK_19 + 1 + magic_number) << 24 | -- tUNK_18 << 16 | -+ max(tUNK_18, (u8) 1) << 16 | - (tUNK_1 + tUNK_19 + 1 + magic_number) << 8; -- if(dev_priv->chipset == 0xa8) { -+ if (dev_priv->chipset == 0xa8) { - timing->reg_100224 |= (tUNK_2 - 1); - } else { - timing->reg_100224 |= (tUNK_2 + 2 - magic_number); - } - - timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10); -- if(dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa) { -+ if (dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa) - timing->reg_100228 |= (tUNK_19 - 1) << 24; -- } -+ else -+ timing->reg_100228 |= magic_number << 24; - -- if(dev_priv->card_type == NV_40) { -+ if (dev_priv->card_type == NV_40) { - /* NV40: don't know what the rest of the regs are.. - * And don't need to know either */ -- timing->reg_100228 |= 0x20200000 | magic_number << 24; -- } else if(dev_priv->card_type >= NV_50) { -- /* XXX: reg_10022c */ -- timing->reg_10022c = tUNK_2 - 1; -+ timing->reg_100228 |= 0x20200000; -+ } else if (dev_priv->card_type >= NV_50) { -+ if (dev_priv->chipset < 0x98 || -+ (dev_priv->chipset == 0x98 && -+ dev_priv->stepping <= 0xa1)) { -+ timing->reg_10022c = (0x14 + tUNK_2) << 24 | -+ 0x16 << 16 | -+ (tUNK_2 - 1) << 8 | -+ (tUNK_2 - 1); -+ } else { -+ /* XXX: reg_10022c for recentish cards */ -+ timing->reg_10022c = tUNK_2 - 1; -+ } - - timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 | - tUNK_13 << 8 | tUNK_13); - - timing->reg_100234 = (tRAS << 24 | tRC); -- timing->reg_100234 += max(tUNK_10,tUNK_11) << 16; -+ timing->reg_100234 += max(tUNK_10, tUNK_11) << 16; - -- if(dev_priv->chipset < 0xa3) { -+ if (dev_priv->chipset < 0x98 || -+ (dev_priv->chipset == 0x98 && -+ dev_priv->stepping <= 0xa1)) { - timing->reg_100234 |= (tUNK_2 + 2) << 8; - } else { - /* XXX: +6? */ - timing->reg_100234 |= (tUNK_19 + 6) << 8; - } - -- /* XXX; reg_100238, reg_10023c -- * reg_100238: 0x00?????? -- * reg_10023c: 0x!!??0202 for NV50+ cards (empirical evidence) */ -+ /* XXX; reg_100238 -+ * reg_100238: 0x00?????? */ - timing->reg_10023c = 0x202; -- if(dev_priv->chipset < 0xa3) { -+ if (dev_priv->chipset < 0x98 || -+ (dev_priv->chipset == 0x98 && -+ dev_priv->stepping <= 0xa1)) { - timing->reg_10023c |= 0x4000000 | (tUNK_2 - 1) << 16; - } else { -- /* currently unknown -+ /* XXX: reg_10023c -+ * currently unknown - * 10023c seen as 06xxxxxx, 0bxxxxxx or 0fxxxxxx */ - } -+ -+ /* XXX: reg_100240? */ - } -+ timing->id = i; - - NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i, - timing->reg_100220, timing->reg_100224, -@@ -695,10 +712,11 @@ - NV_DEBUG(dev, " 230: %08x %08x %08x %08x\n", - timing->reg_100230, timing->reg_100234, - timing->reg_100238, timing->reg_10023c); -+ NV_DEBUG(dev, " 240: %08x\n", timing->reg_100240); - } - - memtimings->nr_timing = entries; -- memtimings->supported = true; -+ memtimings->supported = (dev_priv->chipset <= 0x98); - } - - void -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_object.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_object.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_object.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_object.c 2011-05-09 00:36:22.000000000 +0200 -@@ -361,20 +361,6 @@ - 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 -@@ -606,11 +592,11 @@ - set to 0? - */ - static int --nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, -- struct nouveau_gpuobj **gpuobj_ret) -+nouveau_gpuobj_sw_new(struct nouveau_channel *chan, u32 handle, u16 class) - { - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct nouveau_gpuobj *gpuobj; -+ int ret; - - gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); - if (!gpuobj) -@@ -624,8 +610,10 @@ - spin_lock(&dev_priv->ramin_lock); - list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); - spin_unlock(&dev_priv->ramin_lock); -- *gpuobj_ret = gpuobj; -- return 0; -+ -+ ret = nouveau_ramht_insert(chan, handle, gpuobj); -+ nouveau_gpuobj_ref(NULL, &gpuobj); -+ return ret; - } - - int -@@ -634,101 +622,30 @@ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct drm_device *dev = chan->dev; - struct nouveau_gpuobj_class *oc; -- struct nouveau_gpuobj *gpuobj; - int ret; - - NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class); - - list_for_each_entry(oc, &dev_priv->classes, head) { -- if (oc->id == class) -- goto found; -- } -+ struct nouveau_exec_engine *eng = dev_priv->eng[oc->engine]; - -- NV_ERROR(dev, "illegal object class: 0x%x\n", class); -- return -EINVAL; -+ if (oc->id != class) -+ continue; - --found: -- switch (oc->engine) { -- case NVOBJ_ENGINE_SW: -- if (dev_priv->card_type < NV_C0) { -- ret = nouveau_gpuobj_sw_new(chan, class, &gpuobj); -- if (ret) -- return ret; -- goto insert; -- } -- break; -- case NVOBJ_ENGINE_GR: -- if ((dev_priv->card_type >= NV_20 && !chan->ramin_grctx) || -- (dev_priv->card_type < NV_20 && !chan->pgraph_ctx)) { -- struct nouveau_pgraph_engine *pgraph = -- &dev_priv->engine.graph; -+ if (oc->engine == NVOBJ_ENGINE_SW) -+ return nouveau_gpuobj_sw_new(chan, handle, class); - -- ret = pgraph->create_context(chan); -+ if (!chan->engctx[oc->engine]) { -+ ret = eng->context_new(chan, oc->engine); - if (ret) - return ret; - } -- break; -- case NVOBJ_ENGINE_CRYPT: -- if (!chan->crypt_ctx) { -- struct nouveau_crypt_engine *pcrypt = -- &dev_priv->engine.crypt; - -- ret = pcrypt->create_context(chan); -- if (ret) -- return ret; -- } -- break; -- } -- -- /* we're done if this is fermi */ -- if (dev_priv->card_type >= NV_C0) -- return 0; -- -- 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; -+ return eng->object_new(chan, oc->engine, handle, class); - } - -- if (dev_priv->card_type >= NV_50) { -- nv_wo32(gpuobj, 0, class); -- nv_wo32(gpuobj, 20, 0x00010000); -- } else { -- switch (class) { -- case NV_CLASS_NULL: -- nv_wo32(gpuobj, 0, 0x00001030); -- nv_wo32(gpuobj, 4, 0xFFFFFFFF); -- break; -- default: -- if (dev_priv->card_type >= NV_40) { -- nv_wo32(gpuobj, 0, class); --#ifdef __BIG_ENDIAN -- nv_wo32(gpuobj, 8, 0x01000000); --#endif -- } else { --#ifdef __BIG_ENDIAN -- nv_wo32(gpuobj, 0, class | 0x00080000); --#else -- nv_wo32(gpuobj, 0, class); --#endif -- } -- } -- } -- dev_priv->engine.instmem.flush(dev); -- -- gpuobj->engine = oc->engine; -- gpuobj->class = oc->id; -- --insert: -- ret = nouveau_ramht_insert(chan, handle, gpuobj); -- if (ret) -- NV_ERROR(dev, "error adding gpuobj to RAMHT: %d\n", ret); -- nouveau_gpuobj_ref(NULL, &gpuobj); -- return ret; -+ NV_ERROR(dev, "illegal object class: 0x%x\n", class); -+ return -EINVAL; - } - - static int -@@ -746,9 +663,6 @@ - size = 0x2000; - base = 0; - -- /* PGRAPH context */ -- size += dev_priv->engine.graph.grctx_size; -- - if (dev_priv->card_type == NV_50) { - /* Various fixed table thingos */ - size += 0x1400; /* mostly unknown stuff */ -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_perf.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_perf.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_perf.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_perf.c 2011-05-09 00:36:22.000000000 +0200 -@@ -72,6 +72,68 @@ - pm->nr_perflvl = 1; - } - -+static struct nouveau_pm_memtiming * -+nouveau_perf_timing(struct drm_device *dev, struct bit_entry *P, -+ u16 memclk, u8 *entry, u8 recordlen, u8 entries) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_pm_engine *pm = &dev_priv->engine.pm; -+ struct nvbios *bios = &dev_priv->vbios; -+ u8 ramcfg; -+ int i; -+ -+ /* perf v2 has a separate "timing map" table, we have to match -+ * the target memory clock to a specific entry, *then* use -+ * ramcfg to select the correct subentry -+ */ -+ if (P->version == 2) { -+ u8 *tmap = ROMPTR(bios, P->data[4]); -+ if (!tmap) { -+ NV_DEBUG(dev, "no timing map pointer\n"); -+ return NULL; -+ } -+ -+ if (tmap[0] != 0x10) { -+ NV_WARN(dev, "timing map 0x%02x unknown\n", tmap[0]); -+ return NULL; -+ } -+ -+ entry = tmap + tmap[1]; -+ recordlen = tmap[2] + (tmap[4] * tmap[3]); -+ for (i = 0; i < tmap[5]; i++, entry += recordlen) { -+ if (memclk >= ROM16(entry[0]) && -+ memclk <= ROM16(entry[2])) -+ break; -+ } -+ -+ if (i == tmap[5]) { -+ NV_WARN(dev, "no match in timing map table\n"); -+ return NULL; -+ } -+ -+ entry += tmap[2]; -+ recordlen = tmap[3]; -+ entries = tmap[4]; -+ } -+ -+ ramcfg = (nv_rd32(dev, NV_PEXTDEV_BOOT_0) & 0x0000003c) >> 2; -+ if (bios->ram_restrict_tbl_ptr) -+ ramcfg = bios->data[bios->ram_restrict_tbl_ptr + ramcfg]; -+ -+ if (ramcfg >= entries) { -+ NV_WARN(dev, "ramcfg strap out of bounds!\n"); -+ return NULL; -+ } -+ -+ entry += ramcfg * recordlen; -+ if (entry[1] >= pm->memtimings.nr_timing) { -+ NV_WARN(dev, "timingset %d does not exist\n", entry[1]); -+ return NULL; -+ } -+ -+ return &pm->memtimings.timing[entry[1]]; -+} -+ - void - nouveau_perf_init(struct drm_device *dev) - { -@@ -124,6 +186,8 @@ - for (i = 0; i < entries; i++) { - struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl]; - -+ perflvl->timing = NULL; -+ - if (entry[0] == 0xff) { - entry += recordlen; - continue; -@@ -174,9 +238,21 @@ - #define subent(n) entry[perf[2] + ((n) * perf[3])] - perflvl->fanspeed = 0; /*XXX*/ - perflvl->voltage = entry[2]; -- perflvl->core = (ROM16(subent(0)) & 0xfff) * 1000; -- perflvl->shader = (ROM16(subent(1)) & 0xfff) * 1000; -- perflvl->memory = (ROM16(subent(2)) & 0xfff) * 1000; -+ if (dev_priv->card_type == NV_50) { -+ perflvl->core = ROM16(subent(0)) & 0xfff; -+ perflvl->shader = ROM16(subent(1)) & 0xfff; -+ perflvl->memory = ROM16(subent(2)) & 0xfff; -+ } else { -+ perflvl->shader = ROM16(subent(3)) & 0xfff; -+ perflvl->core = perflvl->shader / 2; -+ perflvl->unk0a = ROM16(subent(4)) & 0xfff; -+ perflvl->memory = ROM16(subent(5)) & 0xfff; -+ } -+ -+ perflvl->core *= 1000; -+ perflvl->shader *= 1000; -+ perflvl->memory *= 1000; -+ perflvl->unk0a *= 1000; - break; - } - -@@ -190,6 +266,16 @@ - } - } - -+ /* get the corresponding memory timings */ -+ if (version > 0x15) { -+ /* last 3 args are for < 0x40, ignored for >= 0x40 */ -+ perflvl->timing = -+ nouveau_perf_timing(dev, &P, -+ perflvl->memory / 1000, -+ entry + perf[3], -+ perf[5], perf[4]); -+ } -+ - snprintf(perflvl->name, sizeof(perflvl->name), - "performance_level_%d", i); - perflvl->id = i; -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_pm.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_pm.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_pm.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_pm.c 2011-05-09 00:36:22.000000000 +0200 -@@ -156,7 +156,7 @@ - static void - nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len) - { -- char c[16], s[16], v[16], f[16]; -+ char c[16], s[16], v[16], f[16], t[16]; - - c[0] = '\0'; - if (perflvl->core) -@@ -174,8 +174,12 @@ - if (perflvl->fanspeed) - snprintf(f, sizeof(f), " fanspeed %d%%", perflvl->fanspeed); - -- snprintf(ptr, len, "memory %dMHz%s%s%s%s\n", perflvl->memory / 1000, -- c, s, v, f); -+ t[0] = '\0'; -+ if (perflvl->timing) -+ snprintf(t, sizeof(t), " timing %d", perflvl->timing->id); -+ -+ snprintf(ptr, len, "memory %dMHz%s%s%s%s%s\n", perflvl->memory / 1000, -+ c, s, v, f, t); - } - - static ssize_t -@@ -449,7 +453,7 @@ - #endif - } - --#ifdef CONFIG_ACPI -+#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) - static int - nouveau_pm_acpi_event(struct notifier_block *nb, unsigned long val, void *data) - { -@@ -476,10 +480,10 @@ - char info[256]; - int ret, i; - -+ nouveau_mem_timing_init(dev); - nouveau_volt_init(dev); - nouveau_perf_init(dev); - nouveau_temp_init(dev); -- nouveau_mem_timing_init(dev); - - NV_INFO(dev, "%d available performance level(s)\n", pm->nr_perflvl); - for (i = 0; i < pm->nr_perflvl; i++) { -@@ -490,6 +494,7 @@ - /* determine current ("boot") performance level */ - ret = nouveau_pm_perflvl_get(dev, &pm->boot); - if (ret == 0) { -+ strncpy(pm->boot.name, "boot", 4); - pm->cur = &pm->boot; - - nouveau_pm_perflvl_info(&pm->boot, info, sizeof(info)); -@@ -507,7 +512,7 @@ - - nouveau_sysfs_init(dev); - nouveau_hwmon_init(dev); --#ifdef CONFIG_ACPI -+#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) - pm->acpi_nb.notifier_call = nouveau_pm_acpi_event; - register_acpi_notifier(&pm->acpi_nb); - #endif -@@ -524,12 +529,12 @@ - if (pm->cur != &pm->boot) - nouveau_pm_perflvl_set(dev, &pm->boot); - -- nouveau_mem_timing_fini(dev); - nouveau_temp_fini(dev); - nouveau_perf_fini(dev); - nouveau_volt_fini(dev); -+ nouveau_mem_timing_fini(dev); - --#ifdef CONFIG_ACPI -+#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) - unregister_acpi_notifier(&pm->acpi_nb); - #endif - nouveau_hwmon_fini(dev); -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_reg.h linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_reg.h ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_reg.h 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_reg.h 2011-05-09 00:36:22.000000000 +0200 -@@ -639,9 +639,9 @@ - # define NV50_PCONNECTOR_I2C_PORT_4 0x0000e240 - # define NV50_PCONNECTOR_I2C_PORT_5 0x0000e258 - --#define NV50_AUXCH_DATA_OUT(i,n) ((n) * 4 + (i) * 0x50 + 0x0000e4c0) -+#define NV50_AUXCH_DATA_OUT(i, n) ((n) * 4 + (i) * 0x50 + 0x0000e4c0) - #define NV50_AUXCH_DATA_OUT__SIZE 4 --#define NV50_AUXCH_DATA_IN(i,n) ((n) * 4 + (i) * 0x50 + 0x0000e4d0) -+#define NV50_AUXCH_DATA_IN(i, n) ((n) * 4 + (i) * 0x50 + 0x0000e4d0) - #define NV50_AUXCH_DATA_IN__SIZE 4 - #define NV50_AUXCH_ADDR(i) ((i) * 0x50 + 0x0000e4e0) - #define NV50_AUXCH_CTRL(i) ((i) * 0x50 + 0x0000e4e4) -@@ -829,7 +829,7 @@ - #define NV50_PDISPLAY_SOR_BACKLIGHT 0x0061c084 - #define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000 - #define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff --#define NV50_SOR_DP_CTRL(i,l) (0x0061c10c + (i) * 0x800 + (l) * 0x80) -+#define NV50_SOR_DP_CTRL(i, l) (0x0061c10c + (i) * 0x800 + (l) * 0x80) - #define NV50_SOR_DP_CTRL_ENABLED 0x00000001 - #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000 - #define NV50_SOR_DP_CTRL_LANE_MASK 0x001f0000 -@@ -841,10 +841,10 @@ - #define NV50_SOR_DP_CTRL_TRAINING_PATTERN_DISABLED 0x00000000 - #define NV50_SOR_DP_CTRL_TRAINING_PATTERN_1 0x01000000 - #define NV50_SOR_DP_CTRL_TRAINING_PATTERN_2 0x02000000 --#define NV50_SOR_DP_UNK118(i,l) (0x0061c118 + (i) * 0x800 + (l) * 0x80) --#define NV50_SOR_DP_UNK120(i,l) (0x0061c120 + (i) * 0x800 + (l) * 0x80) --#define NV50_SOR_DP_UNK128(i,l) (0x0061c128 + (i) * 0x800 + (l) * 0x80) --#define NV50_SOR_DP_UNK130(i,l) (0x0061c130 + (i) * 0x800 + (l) * 0x80) -+#define NV50_SOR_DP_UNK118(i, l) (0x0061c118 + (i) * 0x800 + (l) * 0x80) -+#define NV50_SOR_DP_UNK120(i, l) (0x0061c120 + (i) * 0x800 + (l) * 0x80) -+#define NV50_SOR_DP_UNK128(i, l) (0x0061c128 + (i) * 0x800 + (l) * 0x80) -+#define NV50_SOR_DP_UNK130(i, l) (0x0061c130 + (i) * 0x800 + (l) * 0x80) - - #define NV50_PDISPLAY_USER(i) ((i) * 0x1000 + 0x00640000) - #define NV50_PDISPLAY_USER_PUT(i) ((i) * 0x1000 + 0x00640000) -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_state.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_state.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_state.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_state.c 2011-05-09 00:36:22.000000000 +0200 -@@ -65,14 +65,6 @@ - engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nv04_fb_init; - engine->fb.takedown = nv04_fb_takedown; -- 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 = nv04_fifo_fini; -@@ -98,8 +90,6 @@ - engine->pm.clock_get = nv04_pm_clock_get; - engine->pm.clock_pre = nv04_pm_clock_pre; - engine->pm.clock_set = nv04_pm_clock_set; -- engine->crypt.init = nouveau_stub_init; -- engine->crypt.takedown = nouveau_stub_takedown; - engine->vram.init = nouveau_mem_detect; - engine->vram.flags_valid = nouveau_mem_flags_valid; - break; -@@ -123,15 +113,6 @@ - engine->fb.init_tile_region = nv10_fb_init_tile_region; - engine->fb.set_tile_region = nv10_fb_set_tile_region; - engine->fb.free_tile_region = nv10_fb_free_tile_region; -- 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->graph.set_tile_region = nv10_graph_set_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; -@@ -157,8 +138,6 @@ - engine->pm.clock_get = nv04_pm_clock_get; - engine->pm.clock_pre = nv04_pm_clock_pre; - engine->pm.clock_set = nv04_pm_clock_set; -- engine->crypt.init = nouveau_stub_init; -- engine->crypt.takedown = nouveau_stub_takedown; - engine->vram.init = nouveau_mem_detect; - engine->vram.flags_valid = nouveau_mem_flags_valid; - break; -@@ -182,15 +161,6 @@ - engine->fb.init_tile_region = nv10_fb_init_tile_region; - engine->fb.set_tile_region = nv10_fb_set_tile_region; - engine->fb.free_tile_region = nv10_fb_free_tile_region; -- 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->graph.set_tile_region = nv20_graph_set_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; -@@ -216,8 +186,6 @@ - engine->pm.clock_get = nv04_pm_clock_get; - engine->pm.clock_pre = nv04_pm_clock_pre; - engine->pm.clock_set = nv04_pm_clock_set; -- engine->crypt.init = nouveau_stub_init; -- engine->crypt.takedown = nouveau_stub_takedown; - engine->vram.init = nouveau_mem_detect; - engine->vram.flags_valid = nouveau_mem_flags_valid; - break; -@@ -241,15 +209,6 @@ - engine->fb.init_tile_region = nv30_fb_init_tile_region; - engine->fb.set_tile_region = nv10_fb_set_tile_region; - engine->fb.free_tile_region = nv30_fb_free_tile_region; -- 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->graph.set_tile_region = nv20_graph_set_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; -@@ -277,8 +236,6 @@ - engine->pm.clock_set = nv04_pm_clock_set; - engine->pm.voltage_get = nouveau_voltage_gpio_get; - engine->pm.voltage_set = nouveau_voltage_gpio_set; -- engine->crypt.init = nouveau_stub_init; -- engine->crypt.takedown = nouveau_stub_takedown; - engine->vram.init = nouveau_mem_detect; - engine->vram.flags_valid = nouveau_mem_flags_valid; - break; -@@ -303,15 +260,6 @@ - engine->fb.init_tile_region = nv30_fb_init_tile_region; - engine->fb.set_tile_region = nv40_fb_set_tile_region; - engine->fb.free_tile_region = nv30_fb_free_tile_region; -- 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->graph.set_tile_region = nv40_graph_set_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv40_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; -@@ -340,8 +288,6 @@ - engine->pm.voltage_get = nouveau_voltage_gpio_get; - engine->pm.voltage_set = nouveau_voltage_gpio_set; - engine->pm.temp_get = nv40_temp_get; -- engine->crypt.init = nouveau_stub_init; -- engine->crypt.takedown = nouveau_stub_takedown; - engine->vram.init = nouveau_mem_detect; - engine->vram.flags_valid = nouveau_mem_flags_valid; - break; -@@ -368,19 +314,6 @@ - engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nv50_fb_init; - engine->fb.takedown = nv50_fb_takedown; -- 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; -- if (dev_priv->chipset == 0x50 || -- dev_priv->chipset == 0xac) -- engine->graph.tlb_flush = nv50_graph_tlb_flush; -- else -- engine->graph.tlb_flush = nv84_graph_tlb_flush; - engine->fifo.channels = 128; - engine->fifo.init = nv50_fifo_init; - engine->fifo.takedown = nv50_fifo_takedown; -@@ -432,24 +365,6 @@ - engine->pm.temp_get = nv84_temp_get; - else - engine->pm.temp_get = nv40_temp_get; -- switch (dev_priv->chipset) { -- case 0x84: -- case 0x86: -- case 0x92: -- case 0x94: -- case 0x96: -- case 0xa0: -- engine->crypt.init = nv84_crypt_init; -- engine->crypt.takedown = nv84_crypt_fini; -- engine->crypt.create_context = nv84_crypt_create_context; -- engine->crypt.destroy_context = nv84_crypt_destroy_context; -- engine->crypt.tlb_flush = nv84_crypt_tlb_flush; -- break; -- default: -- engine->crypt.init = nouveau_stub_init; -- engine->crypt.takedown = nouveau_stub_takedown; -- break; -- } - engine->vram.init = nv50_vram_init; - engine->vram.get = nv50_vram_new; - engine->vram.put = nv50_vram_del; -@@ -472,14 +387,6 @@ - engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nvc0_fb_init; - engine->fb.takedown = nvc0_fb_takedown; -- engine->graph.init = nvc0_graph_init; -- engine->graph.takedown = nvc0_graph_takedown; -- engine->graph.fifo_access = nvc0_graph_fifo_access; -- engine->graph.channel = nvc0_graph_channel; -- engine->graph.create_context = nvc0_graph_create_context; -- engine->graph.destroy_context = nvc0_graph_destroy_context; -- engine->graph.load_context = nvc0_graph_load_context; -- engine->graph.unload_context = nvc0_graph_unload_context; - engine->fifo.channels = 128; - engine->fifo.init = nvc0_fifo_init; - engine->fifo.takedown = nvc0_fifo_takedown; -@@ -503,8 +410,6 @@ - engine->gpio.irq_register = nv50_gpio_irq_register; - engine->gpio.irq_unregister = nv50_gpio_irq_unregister; - engine->gpio.irq_enable = nv50_gpio_irq_enable; -- engine->crypt.init = nouveau_stub_init; -- engine->crypt.takedown = nouveau_stub_takedown; - engine->vram.init = nvc0_vram_init; - engine->vram.get = nvc0_vram_new; - engine->vram.put = nv50_vram_del; -@@ -593,7 +498,7 @@ - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine; -- int ret; -+ int ret, e = 0; - - vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); - vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, -@@ -658,23 +563,80 @@ - if (ret) - goto out_timer; - -- if (nouveau_noaccel) -- engine->graph.accel_blocked = true; -- else { -- /* PGRAPH */ -- ret = engine->graph.init(dev); -- if (ret) -- goto out_fb; -+ switch (dev_priv->card_type) { -+ case NV_04: -+ nv04_graph_create(dev); -+ break; -+ case NV_10: -+ nv10_graph_create(dev); -+ break; -+ case NV_20: -+ case NV_30: -+ nv20_graph_create(dev); -+ break; -+ case NV_40: -+ nv40_graph_create(dev); -+ break; -+ case NV_50: -+ nv50_graph_create(dev); -+ break; -+ case NV_C0: -+ nvc0_graph_create(dev); -+ break; -+ default: -+ break; -+ } - -- /* PCRYPT */ -- ret = engine->crypt.init(dev); -- if (ret) -- goto out_graph; -+ switch (dev_priv->chipset) { -+ case 0x84: -+ case 0x86: -+ case 0x92: -+ case 0x94: -+ case 0x96: -+ case 0xa0: -+ nv84_crypt_create(dev); -+ break; -+ } -+ -+ switch (dev_priv->card_type) { -+ case NV_50: -+ switch (dev_priv->chipset) { -+ case 0xa3: -+ case 0xa5: -+ case 0xa8: -+ case 0xaf: -+ nva3_copy_create(dev); -+ break; -+ } -+ break; -+ case NV_C0: -+ nvc0_copy_create(dev, 0); -+ nvc0_copy_create(dev, 1); -+ break; -+ default: -+ break; -+ } -+ -+ if (dev_priv->card_type == NV_40) -+ nv40_mpeg_create(dev); -+ else -+ if (dev_priv->card_type == NV_50 && -+ (dev_priv->chipset < 0x98 || dev_priv->chipset == 0xa0)) -+ nv50_mpeg_create(dev); -+ -+ if (!nouveau_noaccel) { -+ for (e = 0; e < NVOBJ_ENGINE_NR; e++) { -+ if (dev_priv->eng[e]) { -+ ret = dev_priv->eng[e]->init(dev, e); -+ if (ret) -+ goto out_engine; -+ } -+ } - - /* PFIFO */ - ret = engine->fifo.init(dev); - if (ret) -- goto out_crypt; -+ goto out_engine; - } - - ret = engine->display.create(dev); -@@ -691,7 +653,7 @@ - - /* what about PVIDEO/PCRTC/PRAMDAC etc? */ - -- if (!engine->graph.accel_blocked) { -+ if (dev_priv->eng[NVOBJ_ENGINE_GR]) { - ret = nouveau_fence_init(dev); - if (ret) - goto out_irq; -@@ -715,13 +677,16 @@ - out_fifo: - if (!nouveau_noaccel) - engine->fifo.takedown(dev); --out_crypt: -- if (!nouveau_noaccel) -- engine->crypt.takedown(dev); --out_graph: -- if (!nouveau_noaccel) -- engine->graph.takedown(dev); --out_fb: -+out_engine: -+ if (!nouveau_noaccel) { -+ for (e = e - 1; e >= 0; e--) { -+ if (!dev_priv->eng[e]) -+ continue; -+ dev_priv->eng[e]->fini(dev, e); -+ dev_priv->eng[e]->destroy(dev,e ); -+ } -+ } -+ - engine->fb.takedown(dev); - out_timer: - engine->timer.takedown(dev); -@@ -751,16 +716,21 @@ - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; -+ int e; - -- if (!engine->graph.accel_blocked) { -+ if (dev_priv->channel) { - nouveau_fence_fini(dev); - nouveau_channel_put_unlocked(&dev_priv->channel); - } - - if (!nouveau_noaccel) { - engine->fifo.takedown(dev); -- engine->crypt.takedown(dev); -- engine->graph.takedown(dev); -+ for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) { -+ if (dev_priv->eng[e]) { -+ dev_priv->eng[e]->fini(dev, e); -+ dev_priv->eng[e]->destroy(dev,e ); -+ } -+ } - } - engine->fb.takedown(dev); - engine->timer.takedown(dev); -@@ -768,6 +738,11 @@ - engine->mc.takedown(dev); - engine->display.late_takedown(dev); - -+ if (dev_priv->vga_ram) { -+ nouveau_bo_unpin(dev_priv->vga_ram); -+ nouveau_bo_ref(NULL, &dev_priv->vga_ram); -+ } -+ - mutex_lock(&dev->struct_mutex); - ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); - ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); -@@ -861,7 +836,7 @@ - #ifdef CONFIG_X86 - primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; - #endif -- -+ - remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary); - return 0; - } -@@ -913,11 +888,13 @@ - - /* Time to determine the card architecture */ - reg0 = nv_rd32(dev, NV03_PMC_BOOT_0); -+ dev_priv->stepping = 0; /* XXX: add stepping for pre-NV10? */ - - /* We're dealing with >=NV10 */ - if ((reg0 & 0x0f000000) > 0) { - /* Bit 27-20 contain the architecture in hex */ - dev_priv->chipset = (reg0 & 0xff00000) >> 20; -+ dev_priv->stepping = (reg0 & 0xff); - /* NV04 or NV05 */ - } else if ((reg0 & 0xff00fff0) == 0x20004000) { - if (reg0 & 0x00f00000) -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_vm.h linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_vm.h ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_vm.h 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_vm.h 2011-05-09 00:36:22.000000000 +0200 -@@ -53,8 +53,7 @@ - int refcount; - - struct list_head pgd_list; -- atomic_t pgraph_refs; -- atomic_t pcrypt_refs; -+ atomic_t engref[16]; - - struct nouveau_vm_pgt *pgt; - u32 fpde; -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_volt.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_volt.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nouveau_volt.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nouveau_volt.c 2011-05-09 00:36:22.000000000 +0200 -@@ -159,8 +159,16 @@ - headerlen = volt[1]; - recordlen = volt[2]; - entries = volt[3]; -- vidshift = hweight8(volt[5]); - vidmask = volt[4]; -+ /* no longer certain what volt[5] is, if it's related to -+ * the vid shift then it's definitely not a function of -+ * how many bits are set. -+ * -+ * after looking at a number of nva3+ vbios images, they -+ * all seem likely to have a static shift of 2.. lets -+ * go with that for now until proven otherwise. -+ */ -+ vidshift = 2; - break; - default: - NV_WARN(dev, "voltage table 0x%02x unknown\n", volt[0]); -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv04_crtc.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv04_crtc.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv04_crtc.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv04_crtc.c 2011-05-09 00:36:22.000000000 +0200 -@@ -790,8 +790,7 @@ - if (atomic) { - drm_fb = passed_fb; - fb = nouveau_framebuffer(passed_fb); -- } -- else { -+ } else { - /* If not atomic, we can go ahead and pin, and unpin the - * old fb we were passed. - */ -@@ -944,14 +943,14 @@ - 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; - } - -+ if (width != 64 || height != 64) -+ return -EINVAL; -+ - gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); - if (!gem) - return -ENOENT; -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv04_graph.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv04_graph.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv04_graph.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv04_graph.c 2011-05-09 00:36:22.000000000 +0200 -@@ -28,9 +28,11 @@ - #include "nouveau_drv.h" - #include "nouveau_hw.h" - #include "nouveau_util.h" -+#include "nouveau_ramht.h" - --static int nv04_graph_register(struct drm_device *dev); --static void nv04_graph_isr(struct drm_device *dev); -+struct nv04_graph_engine { -+ struct nouveau_exec_engine base; -+}; - - static uint32_t nv04_graph_ctx_regs[] = { - 0x0040053c, -@@ -350,7 +352,7 @@ - uint32_t nv04[ARRAY_SIZE(nv04_graph_ctx_regs)]; - }; - --struct nouveau_channel * -+static struct nouveau_channel * - nv04_graph_channel(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -@@ -365,26 +367,6 @@ - return dev_priv->channels.ptr[chid]; - } - --static 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; -- -- 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->channels.ptr[chid]; -- if (chan) -- nv04_graph_load_context(chan); --} -- - static uint32_t *ctx_reg(struct graph_state *ctx, uint32_t reg) - { - int i; -@@ -397,48 +379,11 @@ - return NULL; - } - --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; -- -- *ctx_reg(pgraph_ctx, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31; -- -- return 0; --} -- --void nv04_graph_destroy_context(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 graph_state *pgraph_ctx = chan->pgraph_ctx; -- unsigned long flags; -- -- spin_lock_irqsave(&dev_priv->context_switch_lock, flags); -- pgraph->fifo_access(dev, false); -- -- /* Unload the context if it's the currently active one */ -- if (pgraph->channel(dev) == chan) -- pgraph->unload_context(dev); -- -- /* Free the context resources */ -- kfree(pgraph_ctx); -- chan->pgraph_ctx = NULL; -- -- pgraph->fifo_access(dev, true); -- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); --} -- --int nv04_graph_load_context(struct nouveau_channel *chan) -+static int -+nv04_graph_load_context(struct nouveau_channel *chan) - { -+ struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; - struct drm_device *dev = chan->dev; -- struct graph_state *pgraph_ctx = chan->pgraph_ctx; - uint32_t tmp; - int i; - -@@ -456,20 +401,19 @@ - return 0; - } - --int -+static 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); -+ chan = nv04_graph_channel(dev); - if (!chan) - return 0; -- ctx = chan->pgraph_ctx; -+ ctx = chan->engctx[NVOBJ_ENGINE_GR]; - - for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) - ctx->nv04[i] = nv_rd32(dev, nv04_graph_ctx_regs[i]); -@@ -481,23 +425,85 @@ - return 0; - } - --int nv04_graph_init(struct drm_device *dev) -+static int -+nv04_graph_context_new(struct nouveau_channel *chan, int engine) - { -+ struct graph_state *pgraph_ctx; -+ NV_DEBUG(chan->dev, "nv04_graph_context_create %d\n", chan->id); -+ -+ pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), GFP_KERNEL); -+ if (pgraph_ctx == NULL) -+ return -ENOMEM; -+ -+ *ctx_reg(pgraph_ctx, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31; -+ -+ chan->engctx[engine] = pgraph_ctx; -+ return 0; -+} -+ -+static void -+nv04_graph_context_del(struct nouveau_channel *chan, int engine) -+{ -+ struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; -- uint32_t tmp; -+ struct graph_state *pgraph_ctx = chan->engctx[engine]; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&dev_priv->context_switch_lock, flags); -+ nv04_graph_fifo_access(dev, false); -+ -+ /* Unload the context if it's the currently active one */ -+ if (nv04_graph_channel(dev) == chan) -+ nv04_graph_unload_context(dev); -+ -+ nv04_graph_fifo_access(dev, true); -+ spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); -+ -+ /* Free the context resources */ -+ kfree(pgraph_ctx); -+ chan->engctx[engine] = NULL; -+} -+ -+int -+nv04_graph_object_new(struct nouveau_channel *chan, int engine, -+ u32 handle, u16 class) -+{ -+ struct drm_device *dev = chan->dev; -+ struct nouveau_gpuobj *obj = NULL; - int ret; - -+ ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj); -+ if (ret) -+ return ret; -+ obj->engine = 1; -+ obj->class = class; -+ -+#ifdef __BIG_ENDIAN -+ nv_wo32(obj, 0x00, 0x00080000 | class); -+#else -+ nv_wo32(obj, 0x00, class); -+#endif -+ nv_wo32(obj, 0x04, 0x00000000); -+ nv_wo32(obj, 0x08, 0x00000000); -+ nv_wo32(obj, 0x0c, 0x00000000); -+ -+ ret = nouveau_ramht_insert(chan, handle, obj); -+ nouveau_gpuobj_ref(NULL, &obj); -+ return ret; -+} -+ -+static int -+nv04_graph_init(struct drm_device *dev, int engine) -+{ -+ 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); - -- ret = nv04_graph_register(dev); -- if (ret) -- return ret; -- - /* Enable PGRAPH interrupts */ -- nouveau_irq_register(dev, 12, nv04_graph_isr); - nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF); - nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); - -@@ -507,7 +513,7 @@ - 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);*/ -+ /*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);*/ -@@ -531,10 +537,12 @@ - return 0; - } - --void nv04_graph_takedown(struct drm_device *dev) -+static int -+nv04_graph_fini(struct drm_device *dev, int engine) - { -+ nv04_graph_unload_context(dev); - nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); -- nouveau_irq_unregister(dev, 12); -+ return 0; - } - - void -@@ -969,13 +977,138 @@ - return 1; - } - --static int --nv04_graph_register(struct drm_device *dev) -+static struct nouveau_bitfield nv04_graph_intr[] = { -+ { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" }, -+ {} -+}; -+ -+static struct nouveau_bitfield nv04_graph_nstatus[] = { -+ { 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" }, -+ {} -+}; -+ -+struct nouveau_bitfield nv04_graph_nsource[] = { -+ { 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 -+nv04_graph_context_switch(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_channel *chan = NULL; -+ int chid; - -- if (dev_priv->engine.graph.registered) -- return 0; -+ nouveau_wait_for_idle(dev); -+ -+ /* If previous context is valid, we need to save it */ -+ nv04_graph_unload_context(dev); -+ -+ /* Load context for next channel */ -+ chid = dev_priv->engine.fifo.channel_id(dev); -+ chan = dev_priv->channels.ptr[chid]; -+ if (chan) -+ nv04_graph_load_context(chan); -+} -+ -+static void -+nv04_graph_isr(struct drm_device *dev) -+{ -+ u32 stat; -+ -+ while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) { -+ u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); -+ u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS); -+ u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); -+ u32 chid = (addr & 0x0f000000) >> 24; -+ u32 subc = (addr & 0x0000e000) >> 13; -+ u32 mthd = (addr & 0x00001ffc); -+ u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); -+ u32 class = nv_rd32(dev, 0x400180 + subc * 4) & 0xff; -+ u32 show = stat; -+ -+ if (stat & NV_PGRAPH_INTR_NOTIFY) { -+ if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { -+ if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) -+ show &= ~NV_PGRAPH_INTR_NOTIFY; -+ } -+ } -+ -+ if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) { -+ nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); -+ stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; -+ show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; -+ nv04_graph_context_switch(dev); -+ } -+ -+ nv_wr32(dev, NV03_PGRAPH_INTR, stat); -+ nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001); -+ -+ if (show && nouveau_ratelimit()) { -+ NV_INFO(dev, "PGRAPH -"); -+ nouveau_bitfield_print(nv04_graph_intr, show); -+ printk(" nsource:"); -+ nouveau_bitfield_print(nv04_graph_nsource, nsource); -+ printk(" nstatus:"); -+ nouveau_bitfield_print(nv04_graph_nstatus, nstatus); -+ printk("\n"); -+ NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x " -+ "mthd 0x%04x data 0x%08x\n", -+ chid, subc, class, mthd, data); -+ } -+ } -+} -+ -+static void -+nv04_graph_destroy(struct drm_device *dev, int engine) -+{ -+ struct nv04_graph_engine *pgraph = nv_engine(dev, engine); -+ -+ nouveau_irq_unregister(dev, 12); -+ -+ NVOBJ_ENGINE_DEL(dev, GR); -+ kfree(pgraph); -+} -+ -+int -+nv04_graph_create(struct drm_device *dev) -+{ -+ struct nv04_graph_engine *pgraph; -+ -+ pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL); -+ if (!pgraph) -+ return -ENOMEM; -+ -+ pgraph->base.destroy = nv04_graph_destroy; -+ pgraph->base.init = nv04_graph_init; -+ pgraph->base.fini = nv04_graph_fini; -+ pgraph->base.context_new = nv04_graph_context_new; -+ pgraph->base.context_del = nv04_graph_context_del; -+ pgraph->base.object_new = nv04_graph_object_new; -+ -+ NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base); -+ nouveau_irq_register(dev, 12, nv04_graph_isr); - - /* dvd subpicture */ - NVOBJ_CLASS(dev, 0x0038, GR); -@@ -1222,93 +1355,5 @@ - NVOBJ_CLASS(dev, 0x506e, SW); - NVOBJ_MTHD (dev, 0x506e, 0x0150, nv04_graph_mthd_set_ref); - NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); -- -- dev_priv->engine.graph.registered = true; - return 0; --}; -- --static struct nouveau_bitfield nv04_graph_intr[] = { -- { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" }, -- {} --}; -- --static struct nouveau_bitfield nv04_graph_nstatus[] = --{ -- { 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" }, -- {} --}; -- --struct nouveau_bitfield nv04_graph_nsource[] = --{ -- { 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 --nv04_graph_isr(struct drm_device *dev) --{ -- u32 stat; -- -- while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) { -- u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); -- u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS); -- u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); -- u32 chid = (addr & 0x0f000000) >> 24; -- u32 subc = (addr & 0x0000e000) >> 13; -- u32 mthd = (addr & 0x00001ffc); -- u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); -- u32 class = nv_rd32(dev, 0x400180 + subc * 4) & 0xff; -- u32 show = stat; -- -- if (stat & NV_PGRAPH_INTR_NOTIFY) { -- if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { -- if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) -- show &= ~NV_PGRAPH_INTR_NOTIFY; -- } -- } -- -- if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) { -- nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); -- stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; -- show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; -- nv04_graph_context_switch(dev); -- } -- -- nv_wr32(dev, NV03_PGRAPH_INTR, stat); -- nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001); -- -- if (show && nouveau_ratelimit()) { -- NV_INFO(dev, "PGRAPH -"); -- nouveau_bitfield_print(nv04_graph_intr, show); -- printk(" nsource:"); -- nouveau_bitfield_print(nv04_graph_nsource, nsource); -- printk(" nstatus:"); -- nouveau_bitfield_print(nv04_graph_nstatus, nstatus); -- printk("\n"); -- NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x " -- "mthd 0x%04x data 0x%08x\n", -- chid, subc, class, mthd, data); -- } -- } - } -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv04_instmem.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv04_instmem.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv04_instmem.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv04_instmem.c 2011-05-09 00:36:22.000000000 +0200 -@@ -95,6 +95,9 @@ - nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL); - nouveau_gpuobj_ref(NULL, &dev_priv->ramro); - nouveau_gpuobj_ref(NULL, &dev_priv->ramfc); -+ -+ if (drm_mm_initialized(&dev_priv->ramin_heap)) -+ drm_mm_takedown(&dev_priv->ramin_heap); - } - - int -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv10_graph.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv10_graph.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv10_graph.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv10_graph.c 2011-05-09 00:36:22.000000000 +0200 -@@ -28,10 +28,9 @@ - #include "nouveau_drv.h" - #include "nouveau_util.h" - --static int nv10_graph_register(struct drm_device *); --static void nv10_graph_isr(struct drm_device *); -- --#define NV10_FIFO_NUMBER 32 -+struct nv10_graph_engine { -+ struct nouveau_exec_engine base; -+}; - - struct pipe_state { - uint32_t pipe_0x0000[0x040/4]; -@@ -414,9 +413,9 @@ - - 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 graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; - struct pipe_state *pipe = &pgraph_ctx->pipe_state; -+ struct drm_device *dev = chan->dev; - - PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400); - PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200); -@@ -432,9 +431,9 @@ - - 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 graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; - struct pipe_state *pipe = &pgraph_ctx->pipe_state; -+ struct drm_device *dev = chan->dev; - uint32_t xfmode0, xfmode1; - int i; - -@@ -482,9 +481,9 @@ - - 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 graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; - struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; -+ struct drm_device *dev = chan->dev; - uint32_t *fifo_pipe_state_addr; - int i; - #define PIPE_INIT(addr) \ -@@ -661,8 +660,6 @@ - uint32_t inst) - { - struct drm_device *dev = chan->dev; -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - uint32_t st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4]; - uint32_t ctx_user, ctx_switch[5]; - int i, subchan = -1; -@@ -711,8 +708,8 @@ - 0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c); - nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst); - nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000); -- pgraph->fifo_access(dev, true); -- pgraph->fifo_access(dev, false); -+ nv04_graph_fifo_access(dev, true); -+ nv04_graph_fifo_access(dev, false); - - /* Restore the FIFO state */ - for (i = 0; i < ARRAY_SIZE(fifo); i++) -@@ -729,11 +726,12 @@ - nv_wr32(dev, NV10_PGRAPH_CTX_USER, ctx_user); - } - --int nv10_graph_load_context(struct nouveau_channel *chan) -+static 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; -+ struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; - uint32_t tmp; - int i; - -@@ -757,21 +755,20 @@ - return 0; - } - --int -+static 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); -+ chan = nv10_graph_channel(dev); - if (!chan) - return 0; -- ctx = chan->pgraph_ctx; -+ ctx = chan->engctx[NVOBJ_ENGINE_GR]; - - for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) - ctx->nv10[i] = nv_rd32(dev, nv10_graph_ctx_regs[i]); -@@ -805,7 +802,7 @@ - /* Load context for next channel */ - chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; - chan = dev_priv->channels.ptr[chid]; -- if (chan && chan->pgraph_ctx) -+ if (chan && chan->engctx[NVOBJ_ENGINE_GR]) - nv10_graph_load_context(chan); - } - -@@ -836,7 +833,8 @@ - return dev_priv->channels.ptr[chid]; - } - --int nv10_graph_create_context(struct nouveau_channel *chan) -+static int -+nv10_graph_context_new(struct nouveau_channel *chan, int engine) - { - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; -@@ -844,11 +842,10 @@ - - NV_DEBUG(dev, "nv10_graph_context_create %d\n", chan->id); - -- chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), -- GFP_KERNEL); -+ pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), GFP_KERNEL); - if (pgraph_ctx == NULL) - return -ENOMEM; -- -+ chan->engctx[engine] = pgraph_ctx; - - NV_WRITE_CTX(0x00400e88, 0x08000000); - NV_WRITE_CTX(0x00400e9c, 0x4b7fffff); -@@ -873,30 +870,30 @@ - return 0; - } - --void nv10_graph_destroy_context(struct nouveau_channel *chan) -+static void -+nv10_graph_context_del(struct nouveau_channel *chan, int engine) - { - 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 graph_state *pgraph_ctx = chan->pgraph_ctx; -+ struct graph_state *pgraph_ctx = chan->engctx[engine]; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); -- pgraph->fifo_access(dev, false); -+ nv04_graph_fifo_access(dev, false); - - /* Unload the context if it's the currently active one */ -- if (pgraph->channel(dev) == chan) -- pgraph->unload_context(dev); -+ if (nv10_graph_channel(dev) == chan) -+ nv10_graph_unload_context(dev); -+ -+ nv04_graph_fifo_access(dev, true); -+ spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - /* Free the context resources */ -+ chan->engctx[engine] = NULL; - kfree(pgraph_ctx); -- chan->pgraph_ctx = NULL; -- -- pgraph->fifo_access(dev, true); -- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - } - --void -+static void - nv10_graph_set_tile_region(struct drm_device *dev, int i) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -@@ -907,22 +904,18 @@ - nv_wr32(dev, NV10_PGRAPH_TILE(i), tile->addr); - } - --int nv10_graph_init(struct drm_device *dev) -+static int -+nv10_graph_init(struct drm_device *dev, int engine) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -- uint32_t tmp; -- int ret, i; -+ u32 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); - -- ret = nv10_graph_register(dev); -- if (ret) -- return ret; -- -- nouveau_irq_register(dev, 12, nv10_graph_isr); - nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); - nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); - -@@ -963,18 +956,20 @@ - return 0; - } - --void nv10_graph_takedown(struct drm_device *dev) -+static int -+nv10_graph_fini(struct drm_device *dev, int engine) - { -+ nv10_graph_unload_context(dev); - nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); -- nouveau_irq_unregister(dev, 12); -+ return 0; - } - - static int - nv17_graph_mthd_lma_window(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) - { -+ struct graph_state *ctx = chan->engctx[NVOBJ_ENGINE_GR]; - struct drm_device *dev = chan->dev; -- struct graph_state *ctx = chan->pgraph_ctx; - struct pipe_state *pipe = &ctx->pipe_state; - uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3]; - uint32_t xfmode0, xfmode1; -@@ -1061,64 +1056,13 @@ - return 0; - } - --static int --nv10_graph_register(struct drm_device *dev) --{ -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- -- if (dev_priv->engine.graph.registered) -- return 0; -- -- NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ -- NVOBJ_CLASS(dev, 0x0030, GR); /* null */ -- NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ -- NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ -- NVOBJ_CLASS(dev, 0x005f, GR); /* imageblit */ -- NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ -- NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ -- NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ -- NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ -- NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ -- NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ -- NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ -- NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ -- NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ -- NVOBJ_CLASS(dev, 0x0052, GR); /* swzsurf */ -- NVOBJ_CLASS(dev, 0x0093, GR); /* surf3d */ -- NVOBJ_CLASS(dev, 0x0094, GR); /* tex_tri */ -- NVOBJ_CLASS(dev, 0x0095, GR); /* multitex_tri */ -- -- /* celcius */ -- if (dev_priv->chipset <= 0x10) { -- NVOBJ_CLASS(dev, 0x0056, GR); -- } else -- if (dev_priv->chipset < 0x17 || dev_priv->chipset == 0x1a) { -- NVOBJ_CLASS(dev, 0x0096, GR); -- } else { -- NVOBJ_CLASS(dev, 0x0099, GR); -- NVOBJ_MTHD (dev, 0x0099, 0x1638, nv17_graph_mthd_lma_window); -- NVOBJ_MTHD (dev, 0x0099, 0x163c, nv17_graph_mthd_lma_window); -- NVOBJ_MTHD (dev, 0x0099, 0x1640, nv17_graph_mthd_lma_window); -- NVOBJ_MTHD (dev, 0x0099, 0x1644, nv17_graph_mthd_lma_window); -- NVOBJ_MTHD (dev, 0x0099, 0x1658, nv17_graph_mthd_lma_enable); -- } -- -- /* nvsw */ -- NVOBJ_CLASS(dev, 0x506e, SW); -- NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); -- -- dev_priv->engine.graph.registered = true; -- return 0; --} -- - struct nouveau_bitfield nv10_graph_intr[] = { - { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" }, - { NV_PGRAPH_INTR_ERROR, "ERROR" }, - {} - }; - --struct nouveau_bitfield nv10_graph_nstatus[] = --{ -+struct nouveau_bitfield nv10_graph_nstatus[] = { - { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, - { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, - { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, -@@ -1173,3 +1117,73 @@ - } - } - } -+ -+static void -+nv10_graph_destroy(struct drm_device *dev, int engine) -+{ -+ struct nv10_graph_engine *pgraph = nv_engine(dev, engine); -+ -+ nouveau_irq_unregister(dev, 12); -+ kfree(pgraph); -+} -+ -+int -+nv10_graph_create(struct drm_device *dev) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nv10_graph_engine *pgraph; -+ -+ pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL); -+ if (!pgraph) -+ return -ENOMEM; -+ -+ pgraph->base.destroy = nv10_graph_destroy; -+ pgraph->base.init = nv10_graph_init; -+ pgraph->base.fini = nv10_graph_fini; -+ pgraph->base.context_new = nv10_graph_context_new; -+ pgraph->base.context_del = nv10_graph_context_del; -+ pgraph->base.object_new = nv04_graph_object_new; -+ pgraph->base.set_tile_region = nv10_graph_set_tile_region; -+ -+ NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base); -+ nouveau_irq_register(dev, 12, nv10_graph_isr); -+ -+ /* nvsw */ -+ NVOBJ_CLASS(dev, 0x506e, SW); -+ NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); -+ -+ NVOBJ_CLASS(dev, 0x0030, GR); /* null */ -+ NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ -+ NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ -+ NVOBJ_CLASS(dev, 0x005f, GR); /* imageblit */ -+ NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ -+ NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ -+ NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ -+ NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ -+ NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ -+ NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ -+ NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ -+ NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ -+ NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ -+ NVOBJ_CLASS(dev, 0x0052, GR); /* swzsurf */ -+ NVOBJ_CLASS(dev, 0x0093, GR); /* surf3d */ -+ NVOBJ_CLASS(dev, 0x0094, GR); /* tex_tri */ -+ NVOBJ_CLASS(dev, 0x0095, GR); /* multitex_tri */ -+ -+ /* celcius */ -+ if (dev_priv->chipset <= 0x10) { -+ NVOBJ_CLASS(dev, 0x0056, GR); -+ } else -+ if (dev_priv->chipset < 0x17 || dev_priv->chipset == 0x1a) { -+ NVOBJ_CLASS(dev, 0x0096, GR); -+ } else { -+ NVOBJ_CLASS(dev, 0x0099, GR); -+ NVOBJ_MTHD (dev, 0x0099, 0x1638, nv17_graph_mthd_lma_window); -+ NVOBJ_MTHD (dev, 0x0099, 0x163c, nv17_graph_mthd_lma_window); -+ NVOBJ_MTHD (dev, 0x0099, 0x1640, nv17_graph_mthd_lma_window); -+ NVOBJ_MTHD (dev, 0x0099, 0x1644, nv17_graph_mthd_lma_window); -+ NVOBJ_MTHD (dev, 0x0099, 0x1658, nv17_graph_mthd_lma_enable); -+ } -+ -+ return 0; -+} -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv20_graph.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv20_graph.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv20_graph.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv20_graph.c 2011-05-09 00:36:22.000000000 +0200 -@@ -24,6 +24,14 @@ - * - */ - -+struct nv20_graph_engine { -+ struct nouveau_exec_engine base; -+ struct nouveau_gpuobj *ctxtab; -+ void (*grctx_init)(struct nouveau_gpuobj *); -+ u32 grctx_size; -+ u32 grctx_user; -+}; -+ - #define NV20_GRCTX_SIZE (3580*4) - #define NV25_GRCTX_SIZE (3529*4) - #define NV2A_GRCTX_SIZE (3500*4) -@@ -32,12 +40,54 @@ - #define NV34_GRCTX_SIZE (18140) - #define NV35_36_GRCTX_SIZE (22396) - --static int nv20_graph_register(struct drm_device *); --static int nv30_graph_register(struct drm_device *); --static void nv20_graph_isr(struct drm_device *); -+int -+nv20_graph_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; -+ struct nouveau_gpuobj *grctx; -+ u32 tmp; -+ -+ chan = nv10_graph_channel(dev); -+ if (!chan) -+ return 0; -+ grctx = chan->engctx[NVOBJ_ENGINE_GR]; -+ -+ nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, grctx->pinst >> 4); -+ 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_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) -+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); -+} -+ -+static void -+nv20_graph_context_init(struct nouveau_gpuobj *ctx) - { - int i; - -@@ -87,7 +137,7 @@ - } - - static void --nv25_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) -+nv25_graph_context_init(struct nouveau_gpuobj *ctx) - { - int i; - -@@ -146,7 +196,7 @@ - } - - static void --nv2a_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) -+nv2a_graph_context_init(struct nouveau_gpuobj *ctx) - { - int i; - -@@ -196,7 +246,7 @@ - } - - static void --nv30_31_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) -+nv30_31_graph_context_init(struct nouveau_gpuobj *ctx) - { - int i; - -@@ -254,7 +304,7 @@ - } - - static void --nv34_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) -+nv34_graph_context_init(struct nouveau_gpuobj *ctx) - { - int i; - -@@ -312,7 +362,7 @@ - } - - static void --nv35_36_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) -+nv35_36_graph_context_init(struct nouveau_gpuobj *ctx) - { - int i; - -@@ -370,148 +420,57 @@ - } - - int --nv20_graph_create_context(struct nouveau_channel *chan) -+nv20_graph_context_new(struct nouveau_channel *chan, int engine) - { -+ struct nv20_graph_engine *pgraph = nv_engine(chan->dev, engine); -+ struct nouveau_gpuobj *grctx = NULL; - struct drm_device *dev = chan->dev; -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; -- void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *); -- unsigned int idoffs = 0x28; - int ret; - -- switch (dev_priv->chipset) { -- case 0x20: -- ctx_init = nv20_graph_context_init; -- idoffs = 0; -- break; -- case 0x25: -- case 0x28: -- ctx_init = nv25_graph_context_init; -- break; -- case 0x2a: -- ctx_init = nv2a_graph_context_init; -- idoffs = 0; -- break; -- case 0x30: -- case 0x31: -- ctx_init = nv30_31_graph_context_init; -- break; -- case 0x34: -- ctx_init = nv34_graph_context_init; -- break; -- case 0x35: -- case 0x36: -- ctx_init = nv35_36_graph_context_init; -- break; -- default: -- BUG_ON(1); -- } -- -- ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 16, -- NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin_grctx); -+ ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 16, -+ NVOBJ_FLAG_ZERO_ALLOC, &grctx); - if (ret) - return ret; - - /* Initialise default context values */ -- ctx_init(dev, chan->ramin_grctx); -+ pgraph->grctx_init(grctx); - - /* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */ -- nv_wo32(chan->ramin_grctx, idoffs, -- (chan->id << 24) | 0x1); /* CTX_USER */ -+ /* CTX_USER */ -+ nv_wo32(grctx, pgraph->grctx_user, (chan->id << 24) | 0x1); - -- nv_wo32(pgraph->ctx_table, chan->id * 4, chan->ramin_grctx->pinst >> 4); -+ nv_wo32(pgraph->ctxtab, chan->id * 4, grctx->pinst >> 4); -+ chan->engctx[engine] = grctx; - return 0; - } - - void --nv20_graph_destroy_context(struct nouveau_channel *chan) -+nv20_graph_context_del(struct nouveau_channel *chan, int engine) - { -+ struct nv20_graph_engine *pgraph = nv_engine(chan->dev, engine); -+ struct nouveau_gpuobj *grctx = chan->engctx[engine]; - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); -- pgraph->fifo_access(dev, false); -+ nv04_graph_fifo_access(dev, false); - - /* Unload the context if it's the currently active one */ -- if (pgraph->channel(dev) == chan) -- pgraph->unload_context(dev); -+ if (nv10_graph_channel(dev) == chan) -+ nv20_graph_unload_context(dev); - -- pgraph->fifo_access(dev, true); -+ nv04_graph_fifo_access(dev, true); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - /* Free the context resources */ -- nv_wo32(pgraph->ctx_table, chan->id * 4, 0); -- nouveau_gpuobj_ref(NULL, &chan->ramin_grctx); --} -- --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->pinst >> 4; -+ nv_wo32(pgraph->ctxtab, chan->id * 4, 0); - -- 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->pinst >> 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; -+ nouveau_gpuobj_ref(NULL, &grctx); -+ chan->engctx[engine] = NULL; - } - - 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); --} -- --void - nv20_graph_set_tile_region(struct drm_device *dev, int i) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -@@ -536,56 +495,22 @@ - } - - int --nv20_graph_init(struct drm_device *dev) -+nv20_graph_init(struct drm_device *dev, int engine) - { -+ struct nv20_graph_engine *pgraph = nv_engine(dev, engine); - struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - uint32_t tmp, vramsz; -- int ret, i; -- -- switch (dev_priv->chipset) { -- case 0x20: -- pgraph->grctx_size = NV20_GRCTX_SIZE; -- break; -- case 0x25: -- case 0x28: -- pgraph->grctx_size = NV25_GRCTX_SIZE; -- break; -- case 0x2a: -- pgraph->grctx_size = NV2A_GRCTX_SIZE; -- break; -- default: -- NV_ERROR(dev, "unknown chipset, disabling acceleration\n"); -- pgraph->accel_blocked = true; -- return 0; -- } -+ 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); - -- if (!pgraph->ctx_table) { -- /* Create Context Pointer Table */ -- ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16, -- NVOBJ_FLAG_ZERO_ALLOC, -- &pgraph->ctx_table); -- if (ret) -- return ret; -- } -- -- nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, -- pgraph->ctx_table->pinst >> 4); -+ nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, pgraph->ctxtab->pinst >> 4); - - nv20_graph_rdi(dev); - -- ret = nv20_graph_register(dev); -- if (ret) { -- nouveau_gpuobj_ref(NULL, &pgraph->ctx_table); -- return ret; -- } -- -- nouveau_irq_register(dev, 12, nv20_graph_isr); - nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); - nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); - -@@ -657,67 +582,20 @@ - return 0; - } - --void --nv20_graph_takedown(struct drm_device *dev) --{ -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; -- -- nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); -- nouveau_irq_unregister(dev, 12); -- -- nouveau_gpuobj_ref(NULL, &pgraph->ctx_table); --} -- - int --nv30_graph_init(struct drm_device *dev) -+nv30_graph_init(struct drm_device *dev, int engine) - { -+ struct nv20_graph_engine *pgraph = nv_engine(dev, engine); - struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; -- int ret, i; -- -- switch (dev_priv->chipset) { -- case 0x30: -- case 0x31: -- pgraph->grctx_size = NV30_31_GRCTX_SIZE; -- break; -- case 0x34: -- pgraph->grctx_size = NV34_GRCTX_SIZE; -- break; -- case 0x35: -- case 0x36: -- pgraph->grctx_size = NV35_36_GRCTX_SIZE; -- break; -- default: -- NV_ERROR(dev, "unknown chipset, disabling acceleration\n"); -- pgraph->accel_blocked = true; -- return 0; -- } -+ 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); - -- if (!pgraph->ctx_table) { -- /* Create Context Pointer Table */ -- ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16, -- NVOBJ_FLAG_ZERO_ALLOC, -- &pgraph->ctx_table); -- if (ret) -- return ret; -- } -- -- ret = nv30_graph_register(dev); -- if (ret) { -- nouveau_gpuobj_ref(NULL, &pgraph->ctx_table); -- return ret; -- } -+ nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, pgraph->ctxtab->pinst >> 4); - -- nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, -- pgraph->ctx_table->pinst >> 4); -- -- nouveau_irq_register(dev, 12, nv20_graph_isr); - nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); - nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); - -@@ -775,85 +653,11 @@ - return 0; - } - --static int --nv20_graph_register(struct drm_device *dev) --{ -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- -- if (dev_priv->engine.graph.registered) -- return 0; -- -- NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ -- NVOBJ_CLASS(dev, 0x0030, GR); /* null */ -- NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ -- NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ -- NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ -- NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ -- NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ -- NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ -- NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ -- NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ -- NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ -- NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ -- NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ -- NVOBJ_CLASS(dev, 0x009e, GR); /* swzsurf */ -- NVOBJ_CLASS(dev, 0x0096, GR); /* celcius */ -- -- /* kelvin */ -- if (dev_priv->chipset < 0x25) -- NVOBJ_CLASS(dev, 0x0097, GR); -- else -- NVOBJ_CLASS(dev, 0x0597, GR); -- -- /* nvsw */ -- NVOBJ_CLASS(dev, 0x506e, SW); -- NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); -- -- dev_priv->engine.graph.registered = true; -- return 0; --} -- --static int --nv30_graph_register(struct drm_device *dev) -+int -+nv20_graph_fini(struct drm_device *dev, int engine) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- -- if (dev_priv->engine.graph.registered) -- return 0; -- -- NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ -- NVOBJ_CLASS(dev, 0x0030, GR); /* null */ -- NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ -- NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ -- NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ -- NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ -- NVOBJ_CLASS(dev, 0x038a, GR); /* ifc (nv30) */ -- NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ -- NVOBJ_CLASS(dev, 0x0389, GR); /* sifm (nv30) */ -- NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ -- NVOBJ_CLASS(dev, 0x0362, GR); /* surf2d (nv30) */ -- NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ -- NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ -- NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ -- NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ -- NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ -- NVOBJ_CLASS(dev, 0x039e, GR); /* swzsurf */ -- -- /* rankine */ -- if (0x00000003 & (1 << (dev_priv->chipset & 0x0f))) -- NVOBJ_CLASS(dev, 0x0397, GR); -- else -- if (0x00000010 & (1 << (dev_priv->chipset & 0x0f))) -- NVOBJ_CLASS(dev, 0x0697, GR); -- else -- if (0x000001e0 & (1 << (dev_priv->chipset & 0x0f))) -- NVOBJ_CLASS(dev, 0x0497, GR); -- -- /* nvsw */ -- NVOBJ_CLASS(dev, 0x506e, SW); -- NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); -- -- dev_priv->engine.graph.registered = true; -+ nv20_graph_unload_context(dev); -+ nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); - return 0; - } - -@@ -897,3 +701,135 @@ - } - } - } -+ -+static void -+nv20_graph_destroy(struct drm_device *dev, int engine) -+{ -+ struct nv20_graph_engine *pgraph = nv_engine(dev, engine); -+ -+ nouveau_irq_unregister(dev, 12); -+ nouveau_gpuobj_ref(NULL, &pgraph->ctxtab); -+ -+ NVOBJ_ENGINE_DEL(dev, GR); -+ kfree(pgraph); -+} -+ -+int -+nv20_graph_create(struct drm_device *dev) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nv20_graph_engine *pgraph; -+ int ret; -+ -+ pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL); -+ if (!pgraph) -+ return -ENOMEM; -+ -+ pgraph->base.destroy = nv20_graph_destroy; -+ pgraph->base.fini = nv20_graph_fini; -+ pgraph->base.context_new = nv20_graph_context_new; -+ pgraph->base.context_del = nv20_graph_context_del; -+ pgraph->base.object_new = nv04_graph_object_new; -+ pgraph->base.set_tile_region = nv20_graph_set_tile_region; -+ -+ pgraph->grctx_user = 0x0028; -+ if (dev_priv->card_type == NV_20) { -+ pgraph->base.init = nv20_graph_init; -+ switch (dev_priv->chipset) { -+ case 0x20: -+ pgraph->grctx_init = nv20_graph_context_init; -+ pgraph->grctx_size = NV20_GRCTX_SIZE; -+ pgraph->grctx_user = 0x0000; -+ break; -+ case 0x25: -+ case 0x28: -+ pgraph->grctx_init = nv25_graph_context_init; -+ pgraph->grctx_size = NV25_GRCTX_SIZE; -+ break; -+ case 0x2a: -+ pgraph->grctx_init = nv2a_graph_context_init; -+ pgraph->grctx_size = NV2A_GRCTX_SIZE; -+ pgraph->grctx_user = 0x0000; -+ break; -+ default: -+ NV_ERROR(dev, "PGRAPH: unknown chipset\n"); -+ return 0; -+ } -+ } else { -+ pgraph->base.init = nv30_graph_init; -+ switch (dev_priv->chipset) { -+ case 0x30: -+ case 0x31: -+ pgraph->grctx_init = nv30_31_graph_context_init; -+ pgraph->grctx_size = NV30_31_GRCTX_SIZE; -+ break; -+ case 0x34: -+ pgraph->grctx_init = nv34_graph_context_init; -+ pgraph->grctx_size = NV34_GRCTX_SIZE; -+ break; -+ case 0x35: -+ case 0x36: -+ pgraph->grctx_init = nv35_36_graph_context_init; -+ pgraph->grctx_size = NV35_36_GRCTX_SIZE; -+ break; -+ default: -+ NV_ERROR(dev, "PGRAPH: unknown chipset\n"); -+ return 0; -+ } -+ } -+ -+ /* Create Context Pointer Table */ -+ ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16, NVOBJ_FLAG_ZERO_ALLOC, -+ &pgraph->ctxtab); -+ if (ret) { -+ kfree(pgraph); -+ return ret; -+ } -+ -+ NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base); -+ nouveau_irq_register(dev, 12, nv20_graph_isr); -+ -+ /* nvsw */ -+ NVOBJ_CLASS(dev, 0x506e, SW); -+ NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); -+ -+ NVOBJ_CLASS(dev, 0x0030, GR); /* null */ -+ NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ -+ NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ -+ NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ -+ NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ -+ NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ -+ NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ -+ NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ -+ NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ -+ NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ -+ NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ -+ NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ -+ if (dev_priv->card_type == NV_20) { -+ NVOBJ_CLASS(dev, 0x009e, GR); /* swzsurf */ -+ NVOBJ_CLASS(dev, 0x0096, GR); /* celcius */ -+ -+ /* kelvin */ -+ if (dev_priv->chipset < 0x25) -+ NVOBJ_CLASS(dev, 0x0097, GR); -+ else -+ NVOBJ_CLASS(dev, 0x0597, GR); -+ } else { -+ NVOBJ_CLASS(dev, 0x038a, GR); /* ifc (nv30) */ -+ NVOBJ_CLASS(dev, 0x0389, GR); /* sifm (nv30) */ -+ NVOBJ_CLASS(dev, 0x0362, GR); /* surf2d (nv30) */ -+ NVOBJ_CLASS(dev, 0x039e, GR); /* swzsurf */ -+ -+ /* rankine */ -+ if (0x00000003 & (1 << (dev_priv->chipset & 0x0f))) -+ NVOBJ_CLASS(dev, 0x0397, GR); -+ else -+ if (0x00000010 & (1 << (dev_priv->chipset & 0x0f))) -+ NVOBJ_CLASS(dev, 0x0697, GR); -+ else -+ if (0x000001e0 & (1 << (dev_priv->chipset & 0x0f))) -+ NVOBJ_CLASS(dev, 0x0497, GR); -+ } -+ -+ return 0; -+} -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv40_fifo.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv40_fifo.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv40_fifo.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv40_fifo.c 2011-05-09 00:36:22.000000000 +0200 -@@ -115,6 +115,7 @@ - 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)); -+ nv_wr32(dev, 0x330c, nv_ri32(dev, fc + 84)); - - nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); -@@ -186,6 +187,7 @@ - tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16); - nv_wi32(dev, fc + 72, tmp); - #endif -+ nv_wi32(dev, fc + 84, nv_rd32(dev, 0x330c)); - - nv40_fifo_do_load_context(dev, pfifo->channels - 1); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv40_graph.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv40_graph.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv40_graph.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv40_graph.c 2011-05-09 00:36:22.000000000 +0200 -@@ -28,14 +28,18 @@ - #include "drm.h" - #include "nouveau_drv.h" - #include "nouveau_grctx.h" -+#include "nouveau_ramht.h" - --static int nv40_graph_register(struct drm_device *); --static void nv40_graph_isr(struct drm_device *); -+struct nv40_graph_engine { -+ struct nouveau_exec_engine base; -+ u32 grctx_size; -+}; - --struct nouveau_channel * -+static struct nouveau_channel * - nv40_graph_channel(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_gpuobj *grctx; - uint32_t inst; - int i; - -@@ -45,74 +49,17 @@ - inst = (inst & NV40_PGRAPH_CTXCTL_CUR_INSTANCE) << 4; - - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { -- struct nouveau_channel *chan = dev_priv->channels.ptr[i]; -+ if (!dev_priv->channels.ptr[i]) -+ continue; - -- if (chan && chan->ramin_grctx && -- chan->ramin_grctx->pinst == inst) -- return chan; -+ grctx = dev_priv->channels.ptr[i]->engctx[NVOBJ_ENGINE_GR]; -+ if (grctx && grctx->pinst == inst) -+ return dev_priv->channels.ptr[i]; - } - - 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; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; -- struct nouveau_grctx ctx = {}; -- unsigned long flags; -- int ret; -- -- ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 16, -- NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin_grctx); -- if (ret) -- return ret; -- -- /* Initialise default context values */ -- ctx.dev = chan->dev; -- ctx.mode = NOUVEAU_GRCTX_VALS; -- ctx.data = chan->ramin_grctx; -- nv40_grctx_init(&ctx); -- -- nv_wo32(chan->ramin_grctx, 0, chan->ramin_grctx->pinst); -- -- /* init grctx pointer in ramfc, and on PFIFO if channel is -- * already active there -- */ -- spin_lock_irqsave(&dev_priv->context_switch_lock, flags); -- nv_wo32(chan->ramfc, 0x38, chan->ramin_grctx->pinst >> 4); -- nv_mask(dev, 0x002500, 0x00000001, 0x00000000); -- if ((nv_rd32(dev, 0x003204) & 0x0000001f) == chan->id) -- nv_wr32(dev, 0x0032e0, chan->ramin_grctx->pinst >> 4); -- nv_mask(dev, 0x002500, 0x00000001, 0x00000001); -- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); -- return 0; --} -- --void --nv40_graph_destroy_context(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; -- unsigned long flags; -- -- spin_lock_irqsave(&dev_priv->context_switch_lock, flags); -- pgraph->fifo_access(dev, false); -- -- /* Unload the context if it's the currently active one */ -- if (pgraph->channel(dev) == chan) -- pgraph->unload_context(dev); -- -- pgraph->fifo_access(dev, true); -- spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); -- -- /* Free the context resources */ -- nouveau_gpuobj_ref(NULL, &chan->ramin_grctx); --} -- - static int - nv40_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save) - { -@@ -154,57 +101,115 @@ - return 0; - } - --/* Restore the context for a specific channel into PGRAPH */ --int --nv40_graph_load_context(struct nouveau_channel *chan) -+static int -+nv40_graph_unload_context(struct drm_device *dev) - { -- struct drm_device *dev = chan->dev; - uint32_t inst; - int ret; - -- if (!chan->ramin_grctx) -- return -EINVAL; -- inst = chan->ramin_grctx->pinst >> 4; -+ 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; -+} -+ -+static int -+nv40_graph_context_new(struct nouveau_channel *chan, int engine) -+{ -+ struct nv40_graph_engine *pgraph = nv_engine(chan->dev, engine); -+ struct drm_device *dev = chan->dev; -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_gpuobj *grctx = NULL; -+ struct nouveau_grctx ctx = {}; -+ unsigned long flags; -+ int ret; - -- ret = nv40_graph_transfer_context(dev, inst, 0); -+ ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 16, -+ NVOBJ_FLAG_ZERO_ALLOC, &grctx); - 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 -- * receive PGRAPH_INTR_CONTEXT_SWITCH -+ /* Initialise default context values */ -+ ctx.dev = chan->dev; -+ ctx.mode = NOUVEAU_GRCTX_VALS; -+ ctx.data = grctx; -+ nv40_grctx_init(&ctx); -+ -+ nv_wo32(grctx, 0, grctx->vinst); -+ -+ /* init grctx pointer in ramfc, and on PFIFO if channel is -+ * already active there - */ -- nv_wr32(dev, NV40_PFIFO_GRCTX_INSTANCE, inst); -+ spin_lock_irqsave(&dev_priv->context_switch_lock, flags); -+ nv_wo32(chan->ramfc, 0x38, grctx->vinst >> 4); -+ nv_mask(dev, 0x002500, 0x00000001, 0x00000000); -+ if ((nv_rd32(dev, 0x003204) & 0x0000001f) == chan->id) -+ nv_wr32(dev, 0x0032e0, grctx->vinst >> 4); -+ nv_mask(dev, 0x002500, 0x00000001, 0x00000001); -+ spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); -+ -+ chan->engctx[engine] = grctx; - return 0; - } - -+static void -+nv40_graph_context_del(struct nouveau_channel *chan, int engine) -+{ -+ struct nouveau_gpuobj *grctx = chan->engctx[engine]; -+ struct drm_device *dev = chan->dev; -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&dev_priv->context_switch_lock, flags); -+ nv04_graph_fifo_access(dev, false); -+ -+ /* Unload the context if it's the currently active one */ -+ if (nv40_graph_channel(dev) == chan) -+ nv40_graph_unload_context(dev); -+ -+ nv04_graph_fifo_access(dev, true); -+ spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); -+ -+ /* Free the context resources */ -+ nouveau_gpuobj_ref(NULL, &grctx); -+ chan->engctx[engine] = NULL; -+} -+ - int --nv40_graph_unload_context(struct drm_device *dev) -+nv40_graph_object_new(struct nouveau_channel *chan, int engine, -+ u32 handle, u16 class) - { -- uint32_t inst; -+ struct drm_device *dev = chan->dev; -+ struct nouveau_gpuobj *obj = NULL; - 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 = nouveau_gpuobj_new(dev, chan, 20, 16, NVOBJ_FLAG_ZERO_FREE, &obj); -+ if (ret) -+ return ret; -+ obj->engine = 1; -+ obj->class = class; - -- ret = nv40_graph_transfer_context(dev, inst, 1); -+ nv_wo32(obj, 0x00, class); -+ nv_wo32(obj, 0x04, 0x00000000); -+#ifndef __BIG_ENDIAN -+ nv_wo32(obj, 0x08, 0x00000000); -+#else -+ nv_wo32(obj, 0x08, 0x01000000); -+#endif -+ nv_wo32(obj, 0x0c, 0x00000000); -+ nv_wo32(obj, 0x10, 0x00000000); - -- nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, inst); -+ ret = nouveau_ramht_insert(chan, handle, obj); -+ nouveau_gpuobj_ref(NULL, &obj); - return ret; - } - --void -+static void - nv40_graph_set_tile_region(struct drm_device *dev, int i) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -@@ -257,14 +262,14 @@ - * C51 0x4e - */ - int --nv40_graph_init(struct drm_device *dev) -+nv40_graph_init(struct drm_device *dev, int engine) - { -- struct drm_nouveau_private *dev_priv = -- (struct drm_nouveau_private *)dev->dev_private; -+ struct nv40_graph_engine *pgraph = nv_engine(dev, engine); -+ struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - struct nouveau_grctx ctx = {}; - uint32_t vramsz, *cp; -- int ret, i, j; -+ int i, j; - - nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & - ~NV_PMC_ENABLE_PGRAPH); -@@ -280,7 +285,7 @@ - ctx.data = cp; - ctx.ctxprog_max = 256; - nv40_grctx_init(&ctx); -- dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; -+ pgraph->grctx_size = ctx.ctxvals_pos * 4; - - nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); - for (i = 0; i < ctx.ctxprog_len; i++) -@@ -288,14 +293,9 @@ - - kfree(cp); - -- ret = nv40_graph_register(dev); -- if (ret) -- return ret; -- - /* No context present currently */ - nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); - -- nouveau_irq_register(dev, 12, nv40_graph_isr); - nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); - nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xFFFFFFFF); - -@@ -428,47 +428,10 @@ - return 0; - } - --void nv40_graph_takedown(struct drm_device *dev) --{ -- nouveau_irq_unregister(dev, 12); --} -- - static int --nv40_graph_register(struct drm_device *dev) -+nv40_graph_fini(struct drm_device *dev, int engine) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- -- if (dev_priv->engine.graph.registered) -- return 0; -- -- NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ -- NVOBJ_CLASS(dev, 0x0030, GR); /* null */ -- NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ -- NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ -- NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ -- NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ -- NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ -- NVOBJ_CLASS(dev, 0x3089, GR); /* sifm (nv40) */ -- NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ -- NVOBJ_CLASS(dev, 0x3062, GR); /* surf2d (nv40) */ -- NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ -- NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ -- NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ -- NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ -- NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ -- NVOBJ_CLASS(dev, 0x309e, GR); /* swzsurf */ -- -- /* curie */ -- if (nv44_graph_class(dev)) -- NVOBJ_CLASS(dev, 0x4497, GR); -- else -- NVOBJ_CLASS(dev, 0x4097, GR); -- -- /* nvsw */ -- NVOBJ_CLASS(dev, 0x506e, SW); -- NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); -- -- dev_priv->engine.graph.registered = true; -+ nv40_graph_unload_context(dev); - return 0; - } - -@@ -476,17 +439,17 @@ - nv40_graph_isr_chid(struct drm_device *dev, u32 inst) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_channel *chan; -+ struct nouveau_gpuobj *grctx; - unsigned long flags; - int i; - - spin_lock_irqsave(&dev_priv->channels.lock, flags); - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { -- chan = dev_priv->channels.ptr[i]; -- if (!chan || !chan->ramin_grctx) -+ if (!dev_priv->channels.ptr[i]) - continue; -+ grctx = dev_priv->channels.ptr[i]->engctx[NVOBJ_ENGINE_GR]; - -- if (inst == chan->ramin_grctx->pinst) -+ if (grctx && grctx->pinst == inst) - break; - } - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); -@@ -537,3 +500,63 @@ - } - } - } -+ -+static void -+nv40_graph_destroy(struct drm_device *dev, int engine) -+{ -+ struct nv40_graph_engine *pgraph = nv_engine(dev, engine); -+ -+ nouveau_irq_unregister(dev, 12); -+ -+ NVOBJ_ENGINE_DEL(dev, GR); -+ kfree(pgraph); -+} -+ -+int -+nv40_graph_create(struct drm_device *dev) -+{ -+ struct nv40_graph_engine *pgraph; -+ -+ pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL); -+ if (!pgraph) -+ return -ENOMEM; -+ -+ pgraph->base.destroy = nv40_graph_destroy; -+ pgraph->base.init = nv40_graph_init; -+ pgraph->base.fini = nv40_graph_fini; -+ pgraph->base.context_new = nv40_graph_context_new; -+ pgraph->base.context_del = nv40_graph_context_del; -+ pgraph->base.object_new = nv40_graph_object_new; -+ pgraph->base.set_tile_region = nv40_graph_set_tile_region; -+ -+ NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base); -+ nouveau_irq_register(dev, 12, nv40_graph_isr); -+ -+ NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ -+ NVOBJ_CLASS(dev, 0x0030, GR); /* null */ -+ NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ -+ NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ -+ NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ -+ NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ -+ NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ -+ NVOBJ_CLASS(dev, 0x3089, GR); /* sifm (nv40) */ -+ NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ -+ NVOBJ_CLASS(dev, 0x3062, GR); /* surf2d (nv40) */ -+ NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ -+ NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ -+ NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ -+ NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ -+ NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ -+ NVOBJ_CLASS(dev, 0x309e, GR); /* swzsurf */ -+ -+ /* curie */ -+ if (nv44_graph_class(dev)) -+ NVOBJ_CLASS(dev, 0x4497, GR); -+ else -+ NVOBJ_CLASS(dev, 0x4097, GR); -+ -+ /* nvsw */ -+ NVOBJ_CLASS(dev, 0x506e, SW); -+ NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); -+ return 0; -+} -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv40_mpeg.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv40_mpeg.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv40_mpeg.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv40_mpeg.c 2011-05-09 00:36:22.000000000 +0200 -@@ -0,0 +1,311 @@ -+/* -+ * Copyright 2011 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_ramht.h" -+ -+struct nv40_mpeg_engine { -+ struct nouveau_exec_engine base; -+}; -+ -+static int -+nv40_mpeg_context_new(struct nouveau_channel *chan, int engine) -+{ -+ struct drm_device *dev = chan->dev; -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_gpuobj *ctx = NULL; -+ unsigned long flags; -+ int ret; -+ -+ NV_DEBUG(dev, "ch%d\n", chan->id); -+ -+ ret = nouveau_gpuobj_new(dev, NULL, 264 * 4, 16, NVOBJ_FLAG_ZERO_ALLOC | -+ NVOBJ_FLAG_ZERO_FREE, &ctx); -+ if (ret) -+ return ret; -+ -+ nv_wo32(ctx, 0x78, 0x02001ec1); -+ -+ spin_lock_irqsave(&dev_priv->context_switch_lock, flags); -+ nv_mask(dev, 0x002500, 0x00000001, 0x00000000); -+ if ((nv_rd32(dev, 0x003204) & 0x1f) == chan->id) -+ nv_wr32(dev, 0x00330c, ctx->pinst >> 4); -+ nv_wo32(chan->ramfc, 0x54, ctx->pinst >> 4); -+ nv_mask(dev, 0x002500, 0x00000001, 0x00000001); -+ spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); -+ -+ chan->engctx[engine] = ctx; -+ return 0; -+} -+ -+static void -+nv40_mpeg_context_del(struct nouveau_channel *chan, int engine) -+{ -+ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; -+ struct nouveau_gpuobj *ctx = chan->engctx[engine]; -+ struct drm_device *dev = chan->dev; -+ unsigned long flags; -+ u32 inst = 0x80000000 | (ctx->pinst >> 4); -+ -+ spin_lock_irqsave(&dev_priv->context_switch_lock, flags); -+ nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000); -+ if (nv_rd32(dev, 0x00b318) == inst) -+ nv_mask(dev, 0x00b318, 0x80000000, 0x00000000); -+ nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001); -+ spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); -+ -+ nouveau_gpuobj_ref(NULL, &ctx); -+ chan->engctx[engine] = NULL; -+} -+ -+static int -+nv40_mpeg_object_new(struct nouveau_channel *chan, int engine, -+ u32 handle, u16 class) -+{ -+ struct drm_device *dev = chan->dev; -+ struct nouveau_gpuobj *obj = NULL; -+ int ret; -+ -+ ret = nouveau_gpuobj_new(dev, chan, 20, 16, NVOBJ_FLAG_ZERO_ALLOC | -+ NVOBJ_FLAG_ZERO_FREE, &obj); -+ if (ret) -+ return ret; -+ obj->engine = 2; -+ obj->class = class; -+ -+ nv_wo32(obj, 0x00, class); -+ -+ ret = nouveau_ramht_insert(chan, handle, obj); -+ nouveau_gpuobj_ref(NULL, &obj); -+ return ret; -+} -+ -+static int -+nv40_mpeg_init(struct drm_device *dev, int engine) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nv40_mpeg_engine *pmpeg = nv_engine(dev, engine); -+ int i; -+ -+ /* VPE init */ -+ nv_mask(dev, 0x000200, 0x00000002, 0x00000000); -+ nv_mask(dev, 0x000200, 0x00000002, 0x00000002); -+ nv_wr32(dev, 0x00b0e0, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */ -+ nv_wr32(dev, 0x00b0e8, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */ -+ -+ for (i = 0; i < dev_priv->engine.fb.num_tiles; i++) -+ pmpeg->base.set_tile_region(dev, i); -+ -+ /* PMPEG init */ -+ nv_wr32(dev, 0x00b32c, 0x00000000); -+ nv_wr32(dev, 0x00b314, 0x00000100); -+ nv_wr32(dev, 0x00b220, 0x00000044); -+ nv_wr32(dev, 0x00b300, 0x02001ec1); -+ nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001); -+ -+ nv_wr32(dev, 0x00b100, 0xffffffff); -+ nv_wr32(dev, 0x00b140, 0xffffffff); -+ -+ if (!nv_wait(dev, 0x00b200, 0x00000001, 0x00000000)) { -+ NV_ERROR(dev, "PMPEG init: 0x%08x\n", nv_rd32(dev, 0x00b200)); -+ return -EBUSY; -+ } -+ -+ return 0; -+} -+ -+static int -+nv40_mpeg_fini(struct drm_device *dev, int engine) -+{ -+ /*XXX: context save? */ -+ nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000); -+ nv_wr32(dev, 0x00b140, 0x00000000); -+ return 0; -+} -+ -+static int -+nv40_mpeg_mthd_dma(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data) -+{ -+ struct drm_device *dev = chan->dev; -+ u32 inst = data << 4; -+ u32 dma0 = nv_ri32(dev, inst + 0); -+ u32 dma1 = nv_ri32(dev, inst + 4); -+ u32 dma2 = nv_ri32(dev, inst + 8); -+ u32 base = (dma2 & 0xfffff000) | (dma0 >> 20); -+ u32 size = dma1 + 1; -+ -+ /* only allow linear DMA objects */ -+ if (!(dma0 & 0x00002000)) -+ return -EINVAL; -+ -+ if (mthd == 0x0190) { -+ /* DMA_CMD */ -+ nv_mask(dev, 0x00b300, 0x00030000, (dma0 & 0x00030000)); -+ nv_wr32(dev, 0x00b334, base); -+ nv_wr32(dev, 0x00b324, size); -+ } else -+ if (mthd == 0x01a0) { -+ /* DMA_DATA */ -+ nv_mask(dev, 0x00b300, 0x000c0000, (dma0 & 0x00030000) << 2); -+ nv_wr32(dev, 0x00b360, base); -+ nv_wr32(dev, 0x00b364, size); -+ } else { -+ /* DMA_IMAGE, VRAM only */ -+ if (dma0 & 0x000c0000) -+ return -EINVAL; -+ -+ nv_wr32(dev, 0x00b370, base); -+ nv_wr32(dev, 0x00b374, size); -+ } -+ -+ return 0; -+} -+ -+static int -+nv40_mpeg_isr_chid(struct drm_device *dev, u32 inst) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_gpuobj *ctx; -+ unsigned long flags; -+ int i; -+ -+ spin_lock_irqsave(&dev_priv->channels.lock, flags); -+ for (i = 0; i < dev_priv->engine.fifo.channels; i++) { -+ if (!dev_priv->channels.ptr[i]) -+ continue; -+ -+ ctx = dev_priv->channels.ptr[i]->engctx[NVOBJ_ENGINE_MPEG]; -+ if (ctx && ctx->pinst == inst) -+ break; -+ } -+ spin_unlock_irqrestore(&dev_priv->channels.lock, flags); -+ return i; -+} -+ -+static void -+nv40_vpe_set_tile_region(struct drm_device *dev, int i) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; -+ -+ nv_wr32(dev, 0x00b008 + (i * 0x10), tile->pitch); -+ nv_wr32(dev, 0x00b004 + (i * 0x10), tile->limit); -+ nv_wr32(dev, 0x00b000 + (i * 0x10), tile->addr); -+} -+ -+static void -+nv40_mpeg_isr(struct drm_device *dev) -+{ -+ u32 inst = (nv_rd32(dev, 0x00b318) & 0x000fffff) << 4; -+ u32 chid = nv40_mpeg_isr_chid(dev, inst); -+ u32 stat = nv_rd32(dev, 0x00b100); -+ u32 type = nv_rd32(dev, 0x00b230); -+ u32 mthd = nv_rd32(dev, 0x00b234); -+ u32 data = nv_rd32(dev, 0x00b238); -+ u32 show = stat; -+ -+ if (stat & 0x01000000) { -+ /* happens on initial binding of the object */ -+ if (type == 0x00000020 && mthd == 0x0000) { -+ nv_mask(dev, 0x00b308, 0x00000000, 0x00000000); -+ show &= ~0x01000000; -+ } -+ -+ if (type == 0x00000010) { -+ if (!nouveau_gpuobj_mthd_call2(dev, chid, 0x3174, mthd, data)) -+ show &= ~0x01000000; -+ } -+ } -+ -+ nv_wr32(dev, 0x00b100, stat); -+ nv_wr32(dev, 0x00b230, 0x00000001); -+ -+ if (show && nouveau_ratelimit()) { -+ NV_INFO(dev, "PMPEG: Ch %d [0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n", -+ chid, inst, stat, type, mthd, data); -+ } -+} -+ -+static void -+nv40_vpe_isr(struct drm_device *dev) -+{ -+ if (nv_rd32(dev, 0x00b100)) -+ nv40_mpeg_isr(dev); -+ -+ if (nv_rd32(dev, 0x00b800)) { -+ u32 stat = nv_rd32(dev, 0x00b800); -+ NV_INFO(dev, "PMSRCH: 0x%08x\n", stat); -+ nv_wr32(dev, 0xb800, stat); -+ } -+} -+ -+static void -+nv40_mpeg_destroy(struct drm_device *dev, int engine) -+{ -+ struct nv40_mpeg_engine *pmpeg = nv_engine(dev, engine); -+ -+ nouveau_irq_unregister(dev, 0); -+ -+ NVOBJ_ENGINE_DEL(dev, MPEG); -+ kfree(pmpeg); -+} -+ -+int -+nv40_mpeg_create(struct drm_device *dev) -+{ -+ struct nv40_mpeg_engine *pmpeg; -+ -+ pmpeg = kzalloc(sizeof(*pmpeg), GFP_KERNEL); -+ if (!pmpeg) -+ return -ENOMEM; -+ -+ pmpeg->base.destroy = nv40_mpeg_destroy; -+ pmpeg->base.init = nv40_mpeg_init; -+ pmpeg->base.fini = nv40_mpeg_fini; -+ pmpeg->base.context_new = nv40_mpeg_context_new; -+ pmpeg->base.context_del = nv40_mpeg_context_del; -+ pmpeg->base.object_new = nv40_mpeg_object_new; -+ -+ /* ISR vector, PMC_ENABLE bit, and TILE regs are shared between -+ * all VPE engines, for this driver's purposes the PMPEG engine -+ * will be treated as the "master" and handle the global VPE -+ * bits too -+ */ -+ pmpeg->base.set_tile_region = nv40_vpe_set_tile_region; -+ nouveau_irq_register(dev, 0, nv40_vpe_isr); -+ -+ NVOBJ_ENGINE_ADD(dev, MPEG, &pmpeg->base); -+ NVOBJ_CLASS(dev, 0x3174, MPEG); -+ NVOBJ_MTHD (dev, 0x3174, 0x0190, nv40_mpeg_mthd_dma); -+ NVOBJ_MTHD (dev, 0x3174, 0x01a0, nv40_mpeg_mthd_dma); -+ NVOBJ_MTHD (dev, 0x3174, 0x01b0, nv40_mpeg_mthd_dma); -+ -+#if 0 -+ NVOBJ_ENGINE_ADD(dev, ME, &pme->base); -+ NVOBJ_CLASS(dev, 0x4075, ME); -+#endif -+ return 0; -+ -+} -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_calc.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_calc.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_calc.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_calc.c 2011-05-09 00:36:22.000000000 +0200 -@@ -23,7 +23,6 @@ - */ - - #include "drmP.h" --#include "drm_fixed.h" - #include "nouveau_drv.h" - #include "nouveau_hw.h" - -@@ -47,45 +46,52 @@ - } - - int --nv50_calc_pll2(struct drm_device *dev, struct pll_lims *pll, int clk, -- int *N, int *fN, int *M, int *P) -+nva3_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk, -+ int *pN, int *pfN, int *pM, int *P) - { -- fixed20_12 fb_div, a, b; -- u32 refclk = pll->refclk / 10; -- u32 max_vco_freq = pll->vco1.maxfreq / 10; -- u32 max_vco_inputfreq = pll->vco1.max_inputfreq / 10; -- clk /= 10; -+ u32 best_err = ~0, err; -+ int M, lM, hM, N, fN; - -- *P = max_vco_freq / clk; -+ *P = pll->vco1.maxfreq / clk; - if (*P > pll->max_p) - *P = pll->max_p; - if (*P < pll->min_p) - *P = pll->min_p; - -- /* *M = floor((refclk + max_vco_inputfreq) / max_vco_inputfreq); */ -- a.full = dfixed_const(refclk + max_vco_inputfreq); -- b.full = dfixed_const(max_vco_inputfreq); -- a.full = dfixed_div(a, b); -- a.full = dfixed_floor(a); -- *M = dfixed_trunc(a); -- -- /* fb_div = (vco * *M) / refclk; */ -- fb_div.full = dfixed_const(clk * *P); -- fb_div.full = dfixed_mul(fb_div, a); -- a.full = dfixed_const(refclk); -- fb_div.full = dfixed_div(fb_div, a); -- -- /* *N = floor(fb_div); */ -- a.full = dfixed_floor(fb_div); -- *N = dfixed_trunc(fb_div); -- -- /* *fN = (fmod(fb_div, 1.0) * 8192) - 4096; */ -- b.full = dfixed_const(8192); -- a.full = dfixed_mul(a, b); -- fb_div.full = dfixed_mul(fb_div, b); -- fb_div.full = fb_div.full - a.full; -- *fN = dfixed_trunc(fb_div) - 4096; -- *fN &= 0xffff; -+ lM = (pll->refclk + pll->vco1.max_inputfreq) / pll->vco1.max_inputfreq; -+ lM = max(lM, (int)pll->vco1.min_m); -+ hM = (pll->refclk + pll->vco1.min_inputfreq) / pll->vco1.min_inputfreq; -+ hM = min(hM, (int)pll->vco1.max_m); -+ -+ for (M = lM; M <= hM; M++) { -+ u32 tmp = clk * *P * M; -+ N = tmp / pll->refclk; -+ fN = tmp % pll->refclk; -+ if (!pfN && fN >= pll->refclk / 2) -+ N++; -+ -+ if (N < pll->vco1.min_n) -+ continue; -+ if (N > pll->vco1.max_n) -+ break; -+ -+ err = abs(clk - (pll->refclk * N / M / *P)); -+ if (err < best_err) { -+ best_err = err; -+ *pN = N; -+ *pM = M; -+ } -+ -+ if (pfN) { -+ *pfN = (((fN << 13) / pll->refclk) - 4096) & 0xffff; -+ return clk; -+ } -+ } -+ -+ if (unlikely(best_err == ~0)) { -+ NV_ERROR(dev, "unable to find matching pll values\n"); -+ return -EINVAL; -+ } - -- return clk; -+ return pll->refclk * *pN / *pM / *P; - } -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_crtc.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_crtc.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_crtc.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_crtc.c 2011-05-09 00:36:22.000000000 +0200 -@@ -286,7 +286,7 @@ - nv_wr32(dev, pll.reg + 8, reg2 | (P << 28) | (M2 << 16) | N2); - } else - if (dev_priv->chipset < NV_C0) { -- ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P); -+ ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P); - if (ret <= 0) - return 0; - -@@ -298,7 +298,7 @@ - nv_wr32(dev, pll.reg + 4, reg1 | (P << 16) | (M1 << 8) | N1); - nv_wr32(dev, pll.reg + 8, N2); - } else { -- ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P); -+ ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P); - if (ret <= 0) - return 0; - -@@ -349,14 +349,14 @@ - 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; - } - -+ if (width != 64 || height != 64) -+ return -EINVAL; -+ - gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); - if (!gem) - return -ENOENT; -@@ -532,8 +532,7 @@ - if (atomic) { - drm_fb = passed_fb; - fb = nouveau_framebuffer(passed_fb); -- } -- else { -+ } else { - /* If not atomic, we can go ahead and pin, and unpin the - * old fb we were passed. - */ -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_display.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_display.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_display.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_display.c 2011-05-09 00:36:22.000000000 +0200 -@@ -517,13 +517,25 @@ - if (bios->fp.if_is_24bit) - script |= 0x0200; - } else { -+ /* determine number of lvds links */ -+ if (nv_connector && nv_connector->edid && -+ nv_connector->dcb->type == DCB_CONNECTOR_LVDS_SPWG) { -+ /* http://www.spwg.org */ -+ if (((u8 *)nv_connector->edid)[121] == 2) -+ script |= 0x0100; -+ } else - if (pxclk >= bios->fp.duallink_transition_clk) { - script |= 0x0100; -+ } -+ -+ /* determine panel depth */ -+ if (script & 0x0100) { - if (bios->fp.strapless_is_24bit & 2) - script |= 0x0200; -- } else -- if (bios->fp.strapless_is_24bit & 1) -- script |= 0x0200; -+ } else { -+ if (bios->fp.strapless_is_24bit & 1) -+ script |= 0x0200; -+ } - - if (nv_connector && nv_connector->edid && - (nv_connector->edid->revision >= 4) && -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_graph.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_graph.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_graph.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_graph.c 2011-05-09 00:36:22.000000000 +0200 -@@ -31,10 +31,95 @@ - #include "nouveau_grctx.h" - #include "nouveau_dma.h" - #include "nouveau_vm.h" -+#include "nouveau_ramht.h" - #include "nv50_evo.h" - --static int nv50_graph_register(struct drm_device *); --static void nv50_graph_isr(struct drm_device *); -+struct nv50_graph_engine { -+ struct nouveau_exec_engine base; -+ u32 ctxprog[512]; -+ u32 ctxprog_size; -+ u32 grctx_size; -+}; -+ -+static 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); -+} -+ -+static struct nouveau_channel * -+nv50_graph_channel(struct drm_device *dev) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ uint32_t inst; -+ int i; -+ -+ /* Be sure we're not in the middle of a context switch or bad things -+ * will happen, such as unloading the wrong pgraph context. -+ */ -+ if (!nv_wait(dev, 0x400300, 0x00000001, 0x00000000)) -+ NV_ERROR(dev, "Ctxprog is still running\n"); -+ -+ 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->channels.ptr[i]; -+ -+ if (chan && chan->ramin && chan->ramin->vinst == inst) -+ return chan; -+ } -+ -+ return NULL; -+} -+ -+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; -+} -+ -+static int -+nv50_graph_unload_context(struct drm_device *dev) -+{ -+ uint32_t inst; -+ -+ inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR); -+ if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED)) -+ return 0; -+ inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE; -+ -+ nouveau_wait_for_idle(dev); -+ 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, NV50_PGRAPH_CTXCTL_CUR, inst); -+ return 0; -+} - - static void - nv50_graph_init_reset(struct drm_device *dev) -@@ -52,7 +137,6 @@ - { - NV_DEBUG(dev, "\n"); - -- nouveau_irq_register(dev, 12, nv50_graph_isr); - nv_wr32(dev, NV03_PGRAPH_INTR, 0xffffffff); - nv_wr32(dev, 0x400138, 0xffffffff); - nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xffffffff); -@@ -135,34 +219,14 @@ - static int - nv50_graph_init_ctxctl(struct drm_device *dev) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_grctx ctx = {}; -- uint32_t *cp; -+ struct nv50_graph_engine *pgraph = nv_engine(dev, NVOBJ_ENGINE_GR); - int i; - - NV_DEBUG(dev, "\n"); - -- cp = kmalloc(512 * 4, GFP_KERNEL); -- if (!cp) { -- NV_ERROR(dev, "failed to allocate ctxprog\n"); -- dev_priv->engine.graph.accel_blocked = true; -- return 0; -- } -- -- ctx.dev = dev; -- ctx.mode = NOUVEAU_GRCTX_PROG; -- ctx.data = cp; -- ctx.ctxprog_max = 512; -- if (!nv50_grctx_init(&ctx)) { -- dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; -- -- nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); -- for (i = 0; i < ctx.ctxprog_len; i++) -- nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); -- } else { -- dev_priv->engine.graph.accel_blocked = true; -- } -- kfree(cp); -+ nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); -+ for (i = 0; i < pgraph->ctxprog_size; i++) -+ nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, pgraph->ctxprog[i]); - - nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */ - nv_wr32(dev, 0x400320, 4); -@@ -171,8 +235,8 @@ - return 0; - } - --int --nv50_graph_init(struct drm_device *dev) -+static int -+nv50_graph_init(struct drm_device *dev, int engine) - { - int ret; - -@@ -186,105 +250,66 @@ - if (ret) - return ret; - -- ret = nv50_graph_register(dev); -- if (ret) -- return ret; - nv50_graph_init_intr(dev); - return 0; - } - --void --nv50_graph_takedown(struct drm_device *dev) -+static int -+nv50_graph_fini(struct drm_device *dev, int engine) - { - NV_DEBUG(dev, "\n"); -+ nv50_graph_unload_context(dev); - nv_wr32(dev, 0x40013c, 0x00000000); -- nouveau_irq_unregister(dev, 12); --} -- --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; -- -- /* Be sure we're not in the middle of a context switch or bad things -- * will happen, such as unloading the wrong pgraph context. -- */ -- if (!nv_wait(dev, 0x400300, 0x00000001, 0x00000000)) -- NV_ERROR(dev, "Ctxprog is still running\n"); -- -- 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->channels.ptr[i]; -- -- if (chan && chan->ramin && chan->ramin->vinst == inst) -- return chan; -- } -- -- return NULL; -+ return 0; - } - --int --nv50_graph_create_context(struct nouveau_channel *chan) -+static int -+nv50_graph_context_new(struct nouveau_channel *chan, int engine) - { - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ramin = chan->ramin; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; -+ struct nouveau_gpuobj *grctx = NULL; -+ struct nv50_graph_engine *pgraph = nv_engine(dev, engine); - struct nouveau_grctx ctx = {}; - int hdr, ret; - - NV_DEBUG(dev, "ch%d\n", chan->id); - -- ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 0, -+ ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 0, - NVOBJ_FLAG_ZERO_ALLOC | -- NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); -+ NVOBJ_FLAG_ZERO_FREE, &grctx); - if (ret) - return ret; - - hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20; - nv_wo32(ramin, hdr + 0x00, 0x00190002); -- nv_wo32(ramin, hdr + 0x04, chan->ramin_grctx->vinst + -- pgraph->grctx_size - 1); -- nv_wo32(ramin, hdr + 0x08, chan->ramin_grctx->vinst); -+ nv_wo32(ramin, hdr + 0x04, grctx->vinst + grctx->size - 1); -+ nv_wo32(ramin, hdr + 0x08, grctx->vinst); - nv_wo32(ramin, hdr + 0x0c, 0); - nv_wo32(ramin, hdr + 0x10, 0); - nv_wo32(ramin, hdr + 0x14, 0x00010000); - - ctx.dev = chan->dev; - ctx.mode = NOUVEAU_GRCTX_VALS; -- ctx.data = chan->ramin_grctx; -+ ctx.data = grctx; - nv50_grctx_init(&ctx); - -- nv_wo32(chan->ramin_grctx, 0x00000, chan->ramin->vinst >> 12); -+ nv_wo32(grctx, 0x00000, chan->ramin->vinst >> 12); - - dev_priv->engine.instmem.flush(dev); -- atomic_inc(&chan->vm->pgraph_refs); -+ -+ atomic_inc(&chan->vm->engref[NVOBJ_ENGINE_GR]); -+ chan->engctx[NVOBJ_ENGINE_GR] = grctx; - return 0; - } - --void --nv50_graph_destroy_context(struct nouveau_channel *chan) -+static void -+nv50_graph_context_del(struct nouveau_channel *chan, int engine) - { -+ struct nouveau_gpuobj *grctx = chan->engctx[engine]; - 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; - int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20; - unsigned long flags; -@@ -296,72 +321,49 @@ - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - pfifo->reassign(dev, false); -- pgraph->fifo_access(dev, false); -+ nv50_graph_fifo_access(dev, false); - -- if (pgraph->channel(dev) == chan) -- pgraph->unload_context(dev); -+ if (nv50_graph_channel(dev) == chan) -+ nv50_graph_unload_context(dev); - - for (i = hdr; i < hdr + 24; i += 4) - nv_wo32(chan->ramin, i, 0); - dev_priv->engine.instmem.flush(dev); - -- pgraph->fifo_access(dev, true); -+ nv50_graph_fifo_access(dev, true); - pfifo->reassign(dev, true); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - -- nouveau_gpuobj_ref(NULL, &chan->ramin_grctx); -+ nouveau_gpuobj_ref(NULL, &grctx); - -- atomic_dec(&chan->vm->pgraph_refs); -+ atomic_dec(&chan->vm->engref[engine]); -+ chan->engctx[engine] = NULL; - } - - 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->vinst >> 12; -- -- NV_DEBUG(chan->dev, "ch%d\n", chan->id); -- return nv50_graph_do_load_context(chan->dev, inst); --} -- --int --nv50_graph_unload_context(struct drm_device *dev) -+nv50_graph_object_new(struct nouveau_channel *chan, int engine, -+ u32 handle, u16 class) - { -- uint32_t inst; -+ struct drm_device *dev = chan->dev; -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_gpuobj *obj = NULL; -+ 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 = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj); -+ if (ret) -+ return ret; -+ obj->engine = 1; -+ obj->class = class; - -- nouveau_wait_for_idle(dev); -- 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_wo32(obj, 0x00, class); -+ nv_wo32(obj, 0x04, 0x00000000); -+ nv_wo32(obj, 0x08, 0x00000000); -+ nv_wo32(obj, 0x0c, 0x00000000); -+ dev_priv->engine.instmem.flush(dev); - -- nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst); -- return 0; -+ ret = nouveau_ramht_insert(chan, handle, obj); -+ nouveau_gpuobj_ref(NULL, &obj); -+ return ret; - } - - static void -@@ -442,68 +444,15 @@ - return 0; - } - --static int --nv50_graph_register(struct drm_device *dev) --{ -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- -- if (dev_priv->engine.graph.registered) -- return 0; -- -- NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ -- NVOBJ_MTHD (dev, 0x506e, 0x018c, nv50_graph_nvsw_dma_vblsem); -- NVOBJ_MTHD (dev, 0x506e, 0x0400, nv50_graph_nvsw_vblsem_offset); -- NVOBJ_MTHD (dev, 0x506e, 0x0404, nv50_graph_nvsw_vblsem_release_val); -- NVOBJ_MTHD (dev, 0x506e, 0x0408, nv50_graph_nvsw_vblsem_release); -- NVOBJ_MTHD (dev, 0x506e, 0x0500, nv50_graph_nvsw_mthd_page_flip); -- -- NVOBJ_CLASS(dev, 0x0030, GR); /* null */ -- NVOBJ_CLASS(dev, 0x5039, GR); /* m2mf */ -- NVOBJ_CLASS(dev, 0x502d, GR); /* 2d */ -- -- /* tesla */ -- if (dev_priv->chipset == 0x50) -- NVOBJ_CLASS(dev, 0x5097, GR); /* tesla (nv50) */ -- else -- if (dev_priv->chipset < 0xa0) -- NVOBJ_CLASS(dev, 0x8297, GR); /* tesla (nv8x/nv9x) */ -- else { -- switch (dev_priv->chipset) { -- case 0xa0: -- case 0xaa: -- case 0xac: -- NVOBJ_CLASS(dev, 0x8397, GR); -- break; -- case 0xa3: -- case 0xa5: -- case 0xa8: -- NVOBJ_CLASS(dev, 0x8597, GR); -- break; -- case 0xaf: -- NVOBJ_CLASS(dev, 0x8697, GR); -- break; -- } -- } -- -- /* compute */ -- NVOBJ_CLASS(dev, 0x50c0, GR); -- if (dev_priv->chipset > 0xa0 && -- dev_priv->chipset != 0xaa && -- dev_priv->chipset != 0xac) -- NVOBJ_CLASS(dev, 0x85c0, GR); -- -- dev_priv->engine.graph.registered = true; -- return 0; --} - --void --nv50_graph_tlb_flush(struct drm_device *dev) -+static void -+nv50_graph_tlb_flush(struct drm_device *dev, int engine) - { - nv50_vm_flush_engine(dev, 0); - } - --void --nv84_graph_tlb_flush(struct drm_device *dev) -+static void -+nv84_graph_tlb_flush(struct drm_device *dev, int engine) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; -@@ -548,8 +497,7 @@ - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - } - --static struct nouveau_enum nv50_mp_exec_error_names[] = --{ -+static struct nouveau_enum nv50_mp_exec_error_names[] = { - { 3, "STACK_UNDERFLOW", NULL }, - { 4, "QUADON_ACTIVE", NULL }, - { 8, "TIMEOUT", NULL }, -@@ -663,7 +611,7 @@ - nv_rd32(dev, addr + 0x20); - pc = nv_rd32(dev, addr + 0x24); - oplow = nv_rd32(dev, addr + 0x70); -- ophigh= nv_rd32(dev, addr + 0x74); -+ ophigh = nv_rd32(dev, addr + 0x74); - NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - " - "TP %d MP %d: ", tpid, i); - nouveau_enum_print(nv50_mp_exec_error_names, status); -@@ -991,7 +939,7 @@ - return 1; - } - --static int -+int - nv50_graph_isr_chid(struct drm_device *dev, u64 inst) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -@@ -1073,3 +1021,101 @@ - if (nv_rd32(dev, 0x400824) & (1 << 31)) - nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); - } -+ -+static void -+nv50_graph_destroy(struct drm_device *dev, int engine) -+{ -+ struct nv50_graph_engine *pgraph = nv_engine(dev, engine); -+ -+ NVOBJ_ENGINE_DEL(dev, GR); -+ -+ nouveau_irq_unregister(dev, 12); -+ kfree(pgraph); -+} -+ -+int -+nv50_graph_create(struct drm_device *dev) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nv50_graph_engine *pgraph; -+ struct nouveau_grctx ctx = {}; -+ int ret; -+ -+ pgraph = kzalloc(sizeof(*pgraph),GFP_KERNEL); -+ if (!pgraph) -+ return -ENOMEM; -+ -+ ctx.dev = dev; -+ ctx.mode = NOUVEAU_GRCTX_PROG; -+ ctx.data = pgraph->ctxprog; -+ ctx.ctxprog_max = ARRAY_SIZE(pgraph->ctxprog); -+ -+ ret = nv50_grctx_init(&ctx); -+ if (ret) { -+ NV_ERROR(dev, "PGRAPH: ctxprog build failed\n"); -+ kfree(pgraph); -+ return 0; -+ } -+ -+ pgraph->grctx_size = ctx.ctxvals_pos * 4; -+ pgraph->ctxprog_size = ctx.ctxprog_len; -+ -+ pgraph->base.destroy = nv50_graph_destroy; -+ pgraph->base.init = nv50_graph_init; -+ pgraph->base.fini = nv50_graph_fini; -+ pgraph->base.context_new = nv50_graph_context_new; -+ pgraph->base.context_del = nv50_graph_context_del; -+ pgraph->base.object_new = nv50_graph_object_new; -+ if (dev_priv->chipset == 0x50 || dev_priv->chipset == 0xac) -+ pgraph->base.tlb_flush = nv50_graph_tlb_flush; -+ else -+ pgraph->base.tlb_flush = nv84_graph_tlb_flush; -+ -+ nouveau_irq_register(dev, 12, nv50_graph_isr); -+ -+ /* NVSW really doesn't live here... */ -+ NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ -+ NVOBJ_MTHD (dev, 0x506e, 0x018c, nv50_graph_nvsw_dma_vblsem); -+ NVOBJ_MTHD (dev, 0x506e, 0x0400, nv50_graph_nvsw_vblsem_offset); -+ NVOBJ_MTHD (dev, 0x506e, 0x0404, nv50_graph_nvsw_vblsem_release_val); -+ NVOBJ_MTHD (dev, 0x506e, 0x0408, nv50_graph_nvsw_vblsem_release); -+ NVOBJ_MTHD (dev, 0x506e, 0x0500, nv50_graph_nvsw_mthd_page_flip); -+ -+ NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base); -+ NVOBJ_CLASS(dev, 0x0030, GR); /* null */ -+ NVOBJ_CLASS(dev, 0x5039, GR); /* m2mf */ -+ NVOBJ_CLASS(dev, 0x502d, GR); /* 2d */ -+ -+ /* tesla */ -+ if (dev_priv->chipset == 0x50) -+ NVOBJ_CLASS(dev, 0x5097, GR); /* tesla (nv50) */ -+ else -+ if (dev_priv->chipset < 0xa0) -+ NVOBJ_CLASS(dev, 0x8297, GR); /* tesla (nv8x/nv9x) */ -+ else { -+ switch (dev_priv->chipset) { -+ case 0xa0: -+ case 0xaa: -+ case 0xac: -+ NVOBJ_CLASS(dev, 0x8397, GR); -+ break; -+ case 0xa3: -+ case 0xa5: -+ case 0xa8: -+ NVOBJ_CLASS(dev, 0x8597, GR); -+ break; -+ case 0xaf: -+ NVOBJ_CLASS(dev, 0x8697, GR); -+ break; -+ } -+ } -+ -+ /* compute */ -+ NVOBJ_CLASS(dev, 0x50c0, GR); -+ if (dev_priv->chipset > 0xa0 && -+ dev_priv->chipset != 0xaa && -+ dev_priv->chipset != 0xac) -+ NVOBJ_CLASS(dev, 0x85c0, GR); -+ -+ return 0; -+} -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_grctx.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_grctx.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_grctx.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_grctx.c 2011-05-09 00:36:22.000000000 +0200 -@@ -747,7 +747,7 @@ - gr_def(ctx, offset + 0x64, 0x0000001f); - gr_def(ctx, offset + 0x68, 0x0000000f); - gr_def(ctx, offset + 0x6c, 0x0000000f); -- } else if(dev_priv->chipset < 0xa0) { -+ } else if (dev_priv->chipset < 0xa0) { - cp_ctx(ctx, offset + 0x50, 1); - cp_ctx(ctx, offset + 0x70, 1); - } else { -@@ -924,7 +924,7 @@ - dd_emit(ctx, 1, 0); /* 0000007f MULTISAMPLE_SAMPLES_LOG2 */ - } else { - dd_emit(ctx, 1, 0); /* 0000000f MULTISAMPLE_SAMPLES_LOG2 */ -- } -+ } - dd_emit(ctx, 1, 0xc); /* 000000ff SEMANTIC_COLOR.BFC0_ID */ - if (dev_priv->chipset != 0x50) - dd_emit(ctx, 1, 0); /* 00000001 SEMANTIC_COLOR.CLMP_EN */ -@@ -1803,9 +1803,7 @@ - xf_emit(ctx, 1, 0); /* 1ff */ - xf_emit(ctx, 8, 0); /* 0? */ - xf_emit(ctx, 9, 0); /* ffffffff, 7ff */ -- } -- else -- { -+ } else { - xf_emit(ctx, 0xc, 0); /* RO */ - /* SEEK */ - xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ -@@ -2836,7 +2834,7 @@ - xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ -- if(dev_priv->chipset == 0x50) -+ if (dev_priv->chipset == 0x50) - xf_emit(ctx, 1, 0); /* ff */ - else - xf_emit(ctx, 3, 0); /* 1, 7, 3ff */ -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_mpeg.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_mpeg.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_mpeg.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_mpeg.c 2011-05-09 00:36:22.000000000 +0200 -@@ -0,0 +1,256 @@ -+/* -+ * Copyright 2011 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_ramht.h" -+ -+struct nv50_mpeg_engine { -+ struct nouveau_exec_engine base; -+}; -+ -+static inline u32 -+CTX_PTR(struct drm_device *dev, u32 offset) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ -+ if (dev_priv->chipset == 0x50) -+ offset += 0x0260; -+ else -+ offset += 0x0060; -+ -+ return offset; -+} -+ -+static int -+nv50_mpeg_context_new(struct nouveau_channel *chan, int engine) -+{ -+ struct drm_device *dev = chan->dev; -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_gpuobj *ramin = chan->ramin; -+ struct nouveau_gpuobj *ctx = NULL; -+ int ret; -+ -+ NV_DEBUG(dev, "ch%d\n", chan->id); -+ -+ ret = nouveau_gpuobj_new(dev, chan, 128 * 4, 0, NVOBJ_FLAG_ZERO_ALLOC | -+ NVOBJ_FLAG_ZERO_FREE, &ctx); -+ if (ret) -+ return ret; -+ -+ nv_wo32(ramin, CTX_PTR(dev, 0x00), 0x80190002); -+ nv_wo32(ramin, CTX_PTR(dev, 0x04), ctx->vinst + ctx->size - 1); -+ nv_wo32(ramin, CTX_PTR(dev, 0x08), ctx->vinst); -+ nv_wo32(ramin, CTX_PTR(dev, 0x0c), 0); -+ nv_wo32(ramin, CTX_PTR(dev, 0x10), 0); -+ nv_wo32(ramin, CTX_PTR(dev, 0x14), 0x00010000); -+ -+ nv_wo32(ctx, 0x70, 0x00801ec1); -+ nv_wo32(ctx, 0x7c, 0x0000037c); -+ dev_priv->engine.instmem.flush(dev); -+ -+ chan->engctx[engine] = ctx; -+ return 0; -+} -+ -+static void -+nv50_mpeg_context_del(struct nouveau_channel *chan, int engine) -+{ -+ struct drm_nouveau_private *dev_priv = chan->dev->dev_private; -+ struct nouveau_gpuobj *ctx = chan->engctx[engine]; -+ struct drm_device *dev = chan->dev; -+ unsigned long flags; -+ u32 inst, i; -+ -+ if (!chan->ramin) -+ return; -+ -+ inst = chan->ramin->vinst >> 12; -+ inst |= 0x80000000; -+ -+ spin_lock_irqsave(&dev_priv->context_switch_lock, flags); -+ nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000); -+ if (nv_rd32(dev, 0x00b318) == inst) -+ nv_mask(dev, 0x00b318, 0x80000000, 0x00000000); -+ nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001); -+ spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); -+ -+ for (i = 0x00; i <= 0x14; i += 4) -+ nv_wo32(chan->ramin, CTX_PTR(dev, i), 0x00000000); -+ nouveau_gpuobj_ref(NULL, &ctx); -+ chan->engctx[engine] = NULL; -+} -+ -+static int -+nv50_mpeg_object_new(struct nouveau_channel *chan, int engine, -+ u32 handle, u16 class) -+{ -+ struct drm_device *dev = chan->dev; -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_gpuobj *obj = NULL; -+ int ret; -+ -+ ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj); -+ if (ret) -+ return ret; -+ obj->engine = 2; -+ obj->class = class; -+ -+ nv_wo32(obj, 0x00, class); -+ nv_wo32(obj, 0x04, 0x00000000); -+ nv_wo32(obj, 0x08, 0x00000000); -+ nv_wo32(obj, 0x0c, 0x00000000); -+ dev_priv->engine.instmem.flush(dev); -+ -+ ret = nouveau_ramht_insert(chan, handle, obj); -+ nouveau_gpuobj_ref(NULL, &obj); -+ return ret; -+} -+ -+static void -+nv50_mpeg_tlb_flush(struct drm_device *dev, int engine) -+{ -+ nv50_vm_flush_engine(dev, 0x08); -+} -+ -+static int -+nv50_mpeg_init(struct drm_device *dev, int engine) -+{ -+ nv_wr32(dev, 0x00b32c, 0x00000000); -+ nv_wr32(dev, 0x00b314, 0x00000100); -+ nv_wr32(dev, 0x00b0e0, 0x0000001a); -+ -+ nv_wr32(dev, 0x00b220, 0x00000044); -+ nv_wr32(dev, 0x00b300, 0x00801ec1); -+ nv_wr32(dev, 0x00b390, 0x00000000); -+ nv_wr32(dev, 0x00b394, 0x00000000); -+ nv_wr32(dev, 0x00b398, 0x00000000); -+ nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001); -+ -+ nv_wr32(dev, 0x00b100, 0xffffffff); -+ nv_wr32(dev, 0x00b140, 0xffffffff); -+ -+ if (!nv_wait(dev, 0x00b200, 0x00000001, 0x00000000)) { -+ NV_ERROR(dev, "PMPEG init: 0x%08x\n", nv_rd32(dev, 0x00b200)); -+ return -EBUSY; -+ } -+ -+ return 0; -+} -+ -+static int -+nv50_mpeg_fini(struct drm_device *dev, int engine) -+{ -+ /*XXX: context save for s/r */ -+ nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000); -+ nv_wr32(dev, 0x00b140, 0x00000000); -+ return 0; -+} -+ -+static void -+nv50_mpeg_isr(struct drm_device *dev) -+{ -+ u32 stat = nv_rd32(dev, 0x00b100); -+ u32 type = nv_rd32(dev, 0x00b230); -+ u32 mthd = nv_rd32(dev, 0x00b234); -+ u32 data = nv_rd32(dev, 0x00b238); -+ u32 show = stat; -+ -+ if (stat & 0x01000000) { -+ /* happens on initial binding of the object */ -+ if (type == 0x00000020 && mthd == 0x0000) { -+ nv_wr32(dev, 0x00b308, 0x00000100); -+ show &= ~0x01000000; -+ } -+ } -+ -+ if (show && nouveau_ratelimit()) { -+ NV_INFO(dev, "PMPEG - 0x%08x 0x%08x 0x%08x 0x%08x\n", -+ stat, type, mthd, data); -+ } -+ -+ nv_wr32(dev, 0x00b100, stat); -+ nv_wr32(dev, 0x00b230, 0x00000001); -+ nv50_fb_vm_trap(dev, 1); -+} -+ -+static void -+nv50_vpe_isr(struct drm_device *dev) -+{ -+ if (nv_rd32(dev, 0x00b100)) -+ nv50_mpeg_isr(dev); -+ -+ if (nv_rd32(dev, 0x00b800)) { -+ u32 stat = nv_rd32(dev, 0x00b800); -+ NV_INFO(dev, "PMSRCH: 0x%08x\n", stat); -+ nv_wr32(dev, 0xb800, stat); -+ } -+} -+ -+static void -+nv50_mpeg_destroy(struct drm_device *dev, int engine) -+{ -+ struct nv50_mpeg_engine *pmpeg = nv_engine(dev, engine); -+ -+ nouveau_irq_unregister(dev, 0); -+ -+ NVOBJ_ENGINE_DEL(dev, MPEG); -+ kfree(pmpeg); -+} -+ -+int -+nv50_mpeg_create(struct drm_device *dev) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nv50_mpeg_engine *pmpeg; -+ -+ pmpeg = kzalloc(sizeof(*pmpeg), GFP_KERNEL); -+ if (!pmpeg) -+ return -ENOMEM; -+ -+ pmpeg->base.destroy = nv50_mpeg_destroy; -+ pmpeg->base.init = nv50_mpeg_init; -+ pmpeg->base.fini = nv50_mpeg_fini; -+ pmpeg->base.context_new = nv50_mpeg_context_new; -+ pmpeg->base.context_del = nv50_mpeg_context_del; -+ pmpeg->base.object_new = nv50_mpeg_object_new; -+ pmpeg->base.tlb_flush = nv50_mpeg_tlb_flush; -+ -+ if (dev_priv->chipset == 0x50) { -+ nouveau_irq_register(dev, 0, nv50_vpe_isr); -+ NVOBJ_ENGINE_ADD(dev, MPEG, &pmpeg->base); -+ NVOBJ_CLASS(dev, 0x3174, MPEG); -+#if 0 -+ NVOBJ_ENGINE_ADD(dev, ME, &pme->base); -+ NVOBJ_CLASS(dev, 0x4075, ME); -+#endif -+ } else { -+ nouveau_irq_register(dev, 0, nv50_mpeg_isr); -+ NVOBJ_ENGINE_ADD(dev, MPEG, &pmpeg->base); -+ NVOBJ_CLASS(dev, 0x8274, MPEG); -+ } -+ -+ return 0; -+ -+} -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_pm.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_pm.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_pm.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_pm.c 2011-05-09 00:36:22.000000000 +0200 -@@ -47,6 +47,21 @@ - - reg0 = nv_rd32(dev, pll.reg + 0); - reg1 = nv_rd32(dev, pll.reg + 4); -+ -+ if ((reg0 & 0x80000000) == 0) { -+ if (id == PLL_SHADER) { -+ NV_DEBUG(dev, "Shader PLL is disabled. " -+ "Shader clock is twice the core\n"); -+ ret = nv50_pm_clock_get(dev, PLL_CORE); -+ if (ret > 0) -+ return ret << 1; -+ } else if (id == PLL_MEMORY) { -+ NV_DEBUG(dev, "Memory PLL is disabled. " -+ "Memory clock is equal to the ref_clk\n"); -+ return pll.refclk; -+ } -+ } -+ - P = (reg0 & 0x00070000) >> 16; - N = (reg1 & 0x0000ff00) >> 8; - M = (reg1 & 0x000000ff); -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_vm.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_vm.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv50_vm.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv50_vm.c 2011-05-09 00:36:22.000000000 +0200 -@@ -151,8 +151,7 @@ - struct drm_nouveau_private *dev_priv = vm->dev->dev_private; - struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; -- struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; -+ int i; - - pinstmem->flush(vm->dev); - -@@ -163,11 +162,10 @@ - } - - pfifo->tlb_flush(vm->dev); -- -- if (atomic_read(&vm->pgraph_refs)) -- pgraph->tlb_flush(vm->dev); -- if (atomic_read(&vm->pcrypt_refs)) -- pcrypt->tlb_flush(vm->dev); -+ for (i = 0; i < NVOBJ_ENGINE_NR; i++) { -+ if (atomic_read(&vm->engref[i])) -+ dev_priv->eng[i]->tlb_flush(vm->dev, i); -+ } - } - - void -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv84_crypt.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv84_crypt.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nv84_crypt.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nv84_crypt.c 2011-05-09 00:36:22.000000000 +0200 -@@ -26,46 +26,48 @@ - #include "nouveau_drv.h" - #include "nouveau_util.h" - #include "nouveau_vm.h" -+#include "nouveau_ramht.h" - --static void nv84_crypt_isr(struct drm_device *); -+struct nv84_crypt_engine { -+ struct nouveau_exec_engine base; -+}; - --int --nv84_crypt_create_context(struct nouveau_channel *chan) -+static int -+nv84_crypt_context_new(struct nouveau_channel *chan, int engine) - { - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ramin = chan->ramin; -+ struct nouveau_gpuobj *ctx; - int ret; - - NV_DEBUG(dev, "ch%d\n", chan->id); - -- ret = nouveau_gpuobj_new(dev, chan, 256, 0, -- NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, -- &chan->crypt_ctx); -+ ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC | -+ NVOBJ_FLAG_ZERO_FREE, &ctx); - if (ret) - return ret; - - nv_wo32(ramin, 0xa0, 0x00190000); -- nv_wo32(ramin, 0xa4, chan->crypt_ctx->vinst + 0xff); -- nv_wo32(ramin, 0xa8, chan->crypt_ctx->vinst); -+ nv_wo32(ramin, 0xa4, ctx->vinst + ctx->size - 1); -+ nv_wo32(ramin, 0xa8, ctx->vinst); - nv_wo32(ramin, 0xac, 0); - nv_wo32(ramin, 0xb0, 0); - nv_wo32(ramin, 0xb4, 0); -- - dev_priv->engine.instmem.flush(dev); -- atomic_inc(&chan->vm->pcrypt_refs); -+ -+ atomic_inc(&chan->vm->engref[engine]); -+ chan->engctx[engine] = ctx; - return 0; - } - --void --nv84_crypt_destroy_context(struct nouveau_channel *chan) -+static void -+nv84_crypt_context_del(struct nouveau_channel *chan, int engine) - { -+ struct nouveau_gpuobj *ctx = chan->engctx[engine]; - struct drm_device *dev = chan->dev; - u32 inst; - -- if (!chan->crypt_ctx) -- return; -- - inst = (chan->ramin->vinst >> 12); - inst |= 0x80000000; - -@@ -80,43 +82,39 @@ - nv_mask(dev, 0x10218c, 0x80000000, 0x00000000); - nv_wr32(dev, 0x10200c, 0x00000010); - -- nouveau_gpuobj_ref(NULL, &chan->crypt_ctx); -- atomic_dec(&chan->vm->pcrypt_refs); --} -+ nouveau_gpuobj_ref(NULL, &ctx); - --void --nv84_crypt_tlb_flush(struct drm_device *dev) --{ -- nv50_vm_flush_engine(dev, 0x0a); -+ atomic_dec(&chan->vm->engref[engine]); -+ chan->engctx[engine] = NULL; - } - --int --nv84_crypt_init(struct drm_device *dev) -+static int -+nv84_crypt_object_new(struct nouveau_channel *chan, int engine, -+ u32 handle, u16 class) - { -+ struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; -- -- if (!pcrypt->registered) { -- NVOBJ_CLASS(dev, 0x74c1, CRYPT); -- pcrypt->registered = true; -- } -+ struct nouveau_gpuobj *obj = NULL; -+ int ret; - -- nv_mask(dev, 0x000200, 0x00004000, 0x00000000); -- nv_mask(dev, 0x000200, 0x00004000, 0x00004000); -+ ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj); -+ if (ret) -+ return ret; -+ obj->engine = 5; -+ obj->class = class; - -- nouveau_irq_register(dev, 14, nv84_crypt_isr); -- nv_wr32(dev, 0x102130, 0xffffffff); -- nv_wr32(dev, 0x102140, 0xffffffbf); -+ nv_wo32(obj, 0x00, class); -+ dev_priv->engine.instmem.flush(dev); - -- nv_wr32(dev, 0x10200c, 0x00000010); -- return 0; -+ ret = nouveau_ramht_insert(chan, handle, obj); -+ nouveau_gpuobj_ref(NULL, &obj); -+ return ret; - } - --void --nv84_crypt_fini(struct drm_device *dev) -+static void -+nv84_crypt_tlb_flush(struct drm_device *dev, int engine) - { -- nv_wr32(dev, 0x102140, 0x00000000); -- nouveau_irq_unregister(dev, 14); -+ nv50_vm_flush_engine(dev, 0x0a); - } - - static void -@@ -138,3 +136,58 @@ - - nv50_fb_vm_trap(dev, show); - } -+ -+static int -+nv84_crypt_fini(struct drm_device *dev, int engine) -+{ -+ nv_wr32(dev, 0x102140, 0x00000000); -+ return 0; -+} -+ -+static int -+nv84_crypt_init(struct drm_device *dev, int engine) -+{ -+ nv_mask(dev, 0x000200, 0x00004000, 0x00000000); -+ nv_mask(dev, 0x000200, 0x00004000, 0x00004000); -+ -+ nv_wr32(dev, 0x102130, 0xffffffff); -+ nv_wr32(dev, 0x102140, 0xffffffbf); -+ -+ nv_wr32(dev, 0x10200c, 0x00000010); -+ return 0; -+} -+ -+static void -+nv84_crypt_destroy(struct drm_device *dev, int engine) -+{ -+ struct nv84_crypt_engine *pcrypt = nv_engine(dev, engine); -+ -+ NVOBJ_ENGINE_DEL(dev, CRYPT); -+ -+ nouveau_irq_unregister(dev, 14); -+ kfree(pcrypt); -+} -+ -+int -+nv84_crypt_create(struct drm_device *dev) -+{ -+ struct nv84_crypt_engine *pcrypt; -+ -+ pcrypt = kzalloc(sizeof(*pcrypt), GFP_KERNEL); -+ if (!pcrypt) -+ return -ENOMEM; -+ -+ pcrypt->base.destroy = nv84_crypt_destroy; -+ pcrypt->base.init = nv84_crypt_init; -+ pcrypt->base.fini = nv84_crypt_fini; -+ pcrypt->base.context_new = nv84_crypt_context_new; -+ pcrypt->base.context_del = nv84_crypt_context_del; -+ pcrypt->base.object_new = nv84_crypt_object_new; -+ pcrypt->base.tlb_flush = nv84_crypt_tlb_flush; -+ -+ nouveau_irq_register(dev, 14, nv84_crypt_isr); -+ -+ NVOBJ_ENGINE_ADD(dev, CRYPT, &pcrypt->base); -+ NVOBJ_CLASS (dev, 0x74c1, CRYPT); -+ return 0; -+} -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nva3_copy.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nva3_copy.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nva3_copy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nva3_copy.c 2011-05-09 00:36:22.000000000 +0200 -@@ -0,0 +1,226 @@ -+/* -+ * Copyright 2011 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 -+#include "drmP.h" -+#include "nouveau_drv.h" -+#include "nouveau_util.h" -+#include "nouveau_vm.h" -+#include "nouveau_ramht.h" -+#include "nva3_copy.fuc.h" -+ -+struct nva3_copy_engine { -+ struct nouveau_exec_engine base; -+}; -+ -+static int -+nva3_copy_context_new(struct nouveau_channel *chan, int engine) -+{ -+ struct drm_device *dev = chan->dev; -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_gpuobj *ramin = chan->ramin; -+ struct nouveau_gpuobj *ctx = NULL; -+ int ret; -+ -+ NV_DEBUG(dev, "ch%d\n", chan->id); -+ -+ ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC | -+ NVOBJ_FLAG_ZERO_FREE, &ctx); -+ if (ret) -+ return ret; -+ -+ nv_wo32(ramin, 0xc0, 0x00190000); -+ nv_wo32(ramin, 0xc4, ctx->vinst + ctx->size - 1); -+ nv_wo32(ramin, 0xc8, ctx->vinst); -+ nv_wo32(ramin, 0xcc, 0x00000000); -+ nv_wo32(ramin, 0xd0, 0x00000000); -+ nv_wo32(ramin, 0xd4, 0x00000000); -+ dev_priv->engine.instmem.flush(dev); -+ -+ atomic_inc(&chan->vm->engref[engine]); -+ chan->engctx[engine] = ctx; -+ return 0; -+} -+ -+static int -+nva3_copy_object_new(struct nouveau_channel *chan, int engine, -+ u32 handle, u16 class) -+{ -+ struct nouveau_gpuobj *ctx = chan->engctx[engine]; -+ -+ /* fuc engine doesn't need an object, our ramht code does.. */ -+ ctx->engine = 3; -+ ctx->class = class; -+ return nouveau_ramht_insert(chan, handle, ctx); -+} -+ -+static void -+nva3_copy_context_del(struct nouveau_channel *chan, int engine) -+{ -+ struct nouveau_gpuobj *ctx = chan->engctx[engine]; -+ struct drm_device *dev = chan->dev; -+ u32 inst; -+ -+ inst = (chan->ramin->vinst >> 12); -+ inst |= 0x40000000; -+ -+ /* disable fifo access */ -+ nv_wr32(dev, 0x104048, 0x00000000); -+ /* mark channel as unloaded if it's currently active */ -+ if (nv_rd32(dev, 0x104050) == inst) -+ nv_mask(dev, 0x104050, 0x40000000, 0x00000000); -+ /* mark next channel as invalid if it's about to be loaded */ -+ if (nv_rd32(dev, 0x104054) == inst) -+ nv_mask(dev, 0x104054, 0x40000000, 0x00000000); -+ /* restore fifo access */ -+ nv_wr32(dev, 0x104048, 0x00000003); -+ -+ for (inst = 0xc0; inst <= 0xd4; inst += 4) -+ nv_wo32(chan->ramin, inst, 0x00000000); -+ -+ nouveau_gpuobj_ref(NULL, &ctx); -+ -+ atomic_dec(&chan->vm->engref[engine]); -+ chan->engctx[engine] = ctx; -+} -+ -+static void -+nva3_copy_tlb_flush(struct drm_device *dev, int engine) -+{ -+ nv50_vm_flush_engine(dev, 0x0d); -+} -+ -+static int -+nva3_copy_init(struct drm_device *dev, int engine) -+{ -+ int i; -+ -+ nv_mask(dev, 0x000200, 0x00002000, 0x00000000); -+ nv_mask(dev, 0x000200, 0x00002000, 0x00002000); -+ nv_wr32(dev, 0x104014, 0xffffffff); /* disable all interrupts */ -+ -+ /* upload ucode */ -+ nv_wr32(dev, 0x1041c0, 0x01000000); -+ for (i = 0; i < sizeof(nva3_pcopy_data) / 4; i++) -+ nv_wr32(dev, 0x1041c4, nva3_pcopy_data[i]); -+ -+ nv_wr32(dev, 0x104180, 0x01000000); -+ for (i = 0; i < sizeof(nva3_pcopy_code) / 4; i++) { -+ if ((i & 0x3f) == 0) -+ nv_wr32(dev, 0x104188, i >> 6); -+ nv_wr32(dev, 0x104184, nva3_pcopy_code[i]); -+ } -+ -+ /* start it running */ -+ nv_wr32(dev, 0x10410c, 0x00000000); -+ nv_wr32(dev, 0x104104, 0x00000000); /* ENTRY */ -+ nv_wr32(dev, 0x104100, 0x00000002); /* TRIGGER */ -+ return 0; -+} -+ -+static int -+nva3_copy_fini(struct drm_device *dev, int engine) -+{ -+ nv_mask(dev, 0x104048, 0x00000003, 0x00000000); -+ -+ /* trigger fuc context unload */ -+ nv_wait(dev, 0x104008, 0x0000000c, 0x00000000); -+ nv_mask(dev, 0x104054, 0x40000000, 0x00000000); -+ nv_wr32(dev, 0x104000, 0x00000008); -+ nv_wait(dev, 0x104008, 0x00000008, 0x00000000); -+ -+ nv_wr32(dev, 0x104014, 0xffffffff); -+ return 0; -+} -+ -+static struct nouveau_enum nva3_copy_isr_error_name[] = { -+ { 0x0001, "ILLEGAL_MTHD" }, -+ { 0x0002, "INVALID_ENUM" }, -+ { 0x0003, "INVALID_BITFIELD" }, -+ {} -+}; -+ -+static void -+nva3_copy_isr(struct drm_device *dev) -+{ -+ u32 dispatch = nv_rd32(dev, 0x10401c); -+ u32 stat = nv_rd32(dev, 0x104008) & dispatch & ~(dispatch >> 16); -+ u32 inst = nv_rd32(dev, 0x104050) & 0x3fffffff; -+ u32 ssta = nv_rd32(dev, 0x104040) & 0x0000ffff; -+ u32 addr = nv_rd32(dev, 0x104040) >> 16; -+ u32 mthd = (addr & 0x07ff) << 2; -+ u32 subc = (addr & 0x3800) >> 11; -+ u32 data = nv_rd32(dev, 0x104044); -+ int chid = nv50_graph_isr_chid(dev, inst); -+ -+ if (stat & 0x00000040) { -+ NV_INFO(dev, "PCOPY: DISPATCH_ERROR ["); -+ nouveau_enum_print(nva3_copy_isr_error_name, ssta); -+ printk("] ch %d [0x%08x] subc %d mthd 0x%04x data 0x%08x\n", -+ chid, inst, subc, mthd, data); -+ nv_wr32(dev, 0x104004, 0x00000040); -+ stat &= ~0x00000040; -+ } -+ -+ if (stat) { -+ NV_INFO(dev, "PCOPY: unhandled intr 0x%08x\n", stat); -+ nv_wr32(dev, 0x104004, stat); -+ } -+ nv50_fb_vm_trap(dev, 1); -+} -+ -+static void -+nva3_copy_destroy(struct drm_device *dev, int engine) -+{ -+ struct nva3_copy_engine *pcopy = nv_engine(dev, engine); -+ -+ nouveau_irq_unregister(dev, 22); -+ -+ NVOBJ_ENGINE_DEL(dev, COPY0); -+ kfree(pcopy); -+} -+ -+int -+nva3_copy_create(struct drm_device *dev) -+{ -+ struct nva3_copy_engine *pcopy; -+ -+ pcopy = kzalloc(sizeof(*pcopy), GFP_KERNEL); -+ if (!pcopy) -+ return -ENOMEM; -+ -+ pcopy->base.destroy = nva3_copy_destroy; -+ pcopy->base.init = nva3_copy_init; -+ pcopy->base.fini = nva3_copy_fini; -+ pcopy->base.context_new = nva3_copy_context_new; -+ pcopy->base.context_del = nva3_copy_context_del; -+ pcopy->base.object_new = nva3_copy_object_new; -+ pcopy->base.tlb_flush = nva3_copy_tlb_flush; -+ -+ nouveau_irq_register(dev, 22, nva3_copy_isr); -+ -+ NVOBJ_ENGINE_ADD(dev, COPY0, &pcopy->base); -+ NVOBJ_CLASS(dev, 0x85b5, COPY0); -+ return 0; -+} -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nva3_copy.fuc linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nva3_copy.fuc ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nva3_copy.fuc 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nva3_copy.fuc 2011-05-09 00:36:22.000000000 +0200 -@@ -0,0 +1,870 @@ -+/* fuc microcode for copy engine on nva3- chipsets -+ * -+ * Copyright 2011 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 -+ */ -+ -+/* To build for nva3:nvc0 -+ * m4 -DNVA3 nva3_copy.fuc | envyas -a -w -m fuc -V nva3 -o nva3_copy.fuc.h -+ * -+ * To build for nvc0- -+ * m4 -DNVC0 nva3_copy.fuc | envyas -a -w -m fuc -V nva3 -o nvc0_copy.fuc.h -+ */ -+ -+ifdef(`NVA3', -+.section nva3_pcopy_data, -+.section nvc0_pcopy_data -+) -+ -+ctx_object: .b32 0 -+ifdef(`NVA3', -+ctx_dma: -+ctx_dma_query: .b32 0 -+ctx_dma_src: .b32 0 -+ctx_dma_dst: .b32 0 -+,) -+.equ ctx_dma_count 3 -+ctx_query_address_high: .b32 0 -+ctx_query_address_low: .b32 0 -+ctx_query_counter: .b32 0 -+ctx_src_address_high: .b32 0 -+ctx_src_address_low: .b32 0 -+ctx_src_pitch: .b32 0 -+ctx_src_tile_mode: .b32 0 -+ctx_src_xsize: .b32 0 -+ctx_src_ysize: .b32 0 -+ctx_src_zsize: .b32 0 -+ctx_src_zoff: .b32 0 -+ctx_src_xoff: .b32 0 -+ctx_src_yoff: .b32 0 -+ctx_src_cpp: .b32 0 -+ctx_dst_address_high: .b32 0 -+ctx_dst_address_low: .b32 0 -+ctx_dst_pitch: .b32 0 -+ctx_dst_tile_mode: .b32 0 -+ctx_dst_xsize: .b32 0 -+ctx_dst_ysize: .b32 0 -+ctx_dst_zsize: .b32 0 -+ctx_dst_zoff: .b32 0 -+ctx_dst_xoff: .b32 0 -+ctx_dst_yoff: .b32 0 -+ctx_dst_cpp: .b32 0 -+ctx_format: .b32 0 -+ctx_swz_const0: .b32 0 -+ctx_swz_const1: .b32 0 -+ctx_xcnt: .b32 0 -+ctx_ycnt: .b32 0 -+.align 256 -+ -+dispatch_table: -+// mthd 0x0000, NAME -+.b16 0x000 1 -+.b32 ctx_object ~0xffffffff -+// mthd 0x0100, NOP -+.b16 0x040 1 -+.b32 0x00010000 + cmd_nop ~0xffffffff -+// mthd 0x0140, PM_TRIGGER -+.b16 0x050 1 -+.b32 0x00010000 + cmd_pm_trigger ~0xffffffff -+ifdef(`NVA3', ` -+// mthd 0x0180-0x018c, DMA_ -+.b16 0x060 ctx_dma_count -+dispatch_dma: -+.b32 0x00010000 + cmd_dma ~0xffffffff -+.b32 0x00010000 + cmd_dma ~0xffffffff -+.b32 0x00010000 + cmd_dma ~0xffffffff -+',) -+// mthd 0x0200-0x0218, SRC_TILE -+.b16 0x80 7 -+.b32 ctx_src_tile_mode ~0x00000fff -+.b32 ctx_src_xsize ~0x0007ffff -+.b32 ctx_src_ysize ~0x00001fff -+.b32 ctx_src_zsize ~0x000007ff -+.b32 ctx_src_zoff ~0x00000fff -+.b32 ctx_src_xoff ~0x0007ffff -+.b32 ctx_src_yoff ~0x00001fff -+// mthd 0x0220-0x0238, DST_TILE -+.b16 0x88 7 -+.b32 ctx_dst_tile_mode ~0x00000fff -+.b32 ctx_dst_xsize ~0x0007ffff -+.b32 ctx_dst_ysize ~0x00001fff -+.b32 ctx_dst_zsize ~0x000007ff -+.b32 ctx_dst_zoff ~0x00000fff -+.b32 ctx_dst_xoff ~0x0007ffff -+.b32 ctx_dst_yoff ~0x00001fff -+// mthd 0x0300-0x0304, EXEC, WRCACHE_FLUSH -+.b16 0xc0 2 -+.b32 0x00010000 + cmd_exec ~0xffffffff -+.b32 0x00010000 + cmd_wrcache_flush ~0xffffffff -+// mthd 0x030c-0x0340, various stuff -+.b16 0xc3 14 -+.b32 ctx_src_address_high ~0x000000ff -+.b32 ctx_src_address_low ~0xfffffff0 -+.b32 ctx_dst_address_high ~0x000000ff -+.b32 ctx_dst_address_low ~0xfffffff0 -+.b32 ctx_src_pitch ~0x0007ffff -+.b32 ctx_dst_pitch ~0x0007ffff -+.b32 ctx_xcnt ~0x0000ffff -+.b32 ctx_ycnt ~0x00001fff -+.b32 ctx_format ~0x0333ffff -+.b32 ctx_swz_const0 ~0xffffffff -+.b32 ctx_swz_const1 ~0xffffffff -+.b32 ctx_query_address_high ~0x000000ff -+.b32 ctx_query_address_low ~0xffffffff -+.b32 ctx_query_counter ~0xffffffff -+.b16 0x800 0 -+ -+ifdef(`NVA3', -+.section nva3_pcopy_code, -+.section nvc0_pcopy_code -+) -+ -+main: -+ clear b32 $r0 -+ mov $sp $r0 -+ -+ // setup i0 handler and route fifo and ctxswitch to it -+ mov $r1 ih -+ mov $iv0 $r1 -+ mov $r1 0x400 -+ movw $r2 0xfff3 -+ sethi $r2 0 -+ iowr I[$r2 + 0x300] $r2 -+ -+ // enable interrupts -+ or $r2 0xc -+ iowr I[$r1] $r2 -+ bset $flags ie0 -+ -+ // enable fifo access and context switching -+ mov $r1 0x1200 -+ mov $r2 3 -+ iowr I[$r1] $r2 -+ -+ // sleep forever, waking for interrupts -+ bset $flags $p0 -+ spin: -+ sleep $p0 -+ bra spin -+ -+// i0 handler -+ih: -+ iord $r1 I[$r0 + 0x200] -+ -+ and $r2 $r1 0x00000008 -+ bra e ih_no_chsw -+ call chsw -+ ih_no_chsw: -+ and $r2 $r1 0x00000004 -+ bra e ih_no_cmd -+ call dispatch -+ -+ ih_no_cmd: -+ and $r1 $r1 0x0000000c -+ iowr I[$r0 + 0x100] $r1 -+ iret -+ -+// $p1 direction (0 = unload, 1 = load) -+// $r3 channel -+swctx: -+ mov $r4 0x7700 -+ mov $xtargets $r4 -+ifdef(`NVA3', ` -+ // target 7 hardcoded to ctx dma object -+ mov $xdbase $r0 -+', ` // NVC0 -+ // read SCRATCH3 to decide if we are PCOPY0 or PCOPY1 -+ mov $r4 0x2100 -+ iord $r4 I[$r4 + 0] -+ and $r4 1 -+ shl b32 $r4 4 -+ add b32 $r4 0x30 -+ -+ // channel is in vram -+ mov $r15 0x61c -+ shl b32 $r15 6 -+ mov $r5 0x114 -+ iowrs I[$r15] $r5 -+ -+ // read 16-byte PCOPYn info, containing context pointer, from channel -+ shl b32 $r5 $r3 4 -+ add b32 $r5 2 -+ mov $xdbase $r5 -+ mov $r5 $sp -+ // get a chunk of stack space, aligned to 256 byte boundary -+ sub b32 $r5 0x100 -+ mov $r6 0xff -+ not b32 $r6 -+ and $r5 $r6 -+ sethi $r5 0x00020000 -+ xdld $r4 $r5 -+ xdwait -+ sethi $r5 0 -+ -+ // set context pointer, from within channel VM -+ mov $r14 0 -+ iowrs I[$r15] $r14 -+ ld b32 $r4 D[$r5 + 0] -+ shr b32 $r4 8 -+ ld b32 $r6 D[$r5 + 4] -+ shl b32 $r6 24 -+ or $r4 $r6 -+ mov $xdbase $r4 -+') -+ // 256-byte context, at start of data segment -+ mov b32 $r4 $r0 -+ sethi $r4 0x60000 -+ -+ // swap! -+ bra $p1 swctx_load -+ xdst $r0 $r4 -+ bra swctx_done -+ swctx_load: -+ xdld $r0 $r4 -+ swctx_done: -+ xdwait -+ ret -+ -+chsw: -+ // read current channel -+ mov $r2 0x1400 -+ iord $r3 I[$r2] -+ -+ // if it's active, unload it and return -+ xbit $r15 $r3 0x1e -+ bra e chsw_no_unload -+ bclr $flags $p1 -+ call swctx -+ bclr $r3 0x1e -+ iowr I[$r2] $r3 -+ mov $r4 1 -+ iowr I[$r2 + 0x200] $r4 -+ ret -+ -+ // read next channel -+ chsw_no_unload: -+ iord $r3 I[$r2 + 0x100] -+ -+ // is there a channel waiting to be loaded? -+ xbit $r13 $r3 0x1e -+ bra e chsw_finish_load -+ bset $flags $p1 -+ call swctx -+ifdef(`NVA3', -+ // load dma objects back into TARGET regs -+ mov $r5 ctx_dma -+ mov $r6 ctx_dma_count -+ chsw_load_ctx_dma: -+ ld b32 $r7 D[$r5 + $r6 * 4] -+ add b32 $r8 $r6 0x180 -+ shl b32 $r8 8 -+ iowr I[$r8] $r7 -+ sub b32 $r6 1 -+ bra nc chsw_load_ctx_dma -+,) -+ -+ chsw_finish_load: -+ mov $r3 2 -+ iowr I[$r2 + 0x200] $r3 -+ ret -+ -+dispatch: -+ // read incoming fifo command -+ mov $r3 0x1900 -+ iord $r2 I[$r3 + 0x100] -+ iord $r3 I[$r3 + 0x000] -+ and $r4 $r2 0x7ff -+ // $r2 will be used to store exception data -+ shl b32 $r2 0x10 -+ -+ // lookup method in the dispatch table, ILLEGAL_MTHD if not found -+ mov $r5 dispatch_table -+ clear b32 $r6 -+ clear b32 $r7 -+ dispatch_loop: -+ ld b16 $r6 D[$r5 + 0] -+ ld b16 $r7 D[$r5 + 2] -+ add b32 $r5 4 -+ cmpu b32 $r4 $r6 -+ bra c dispatch_illegal_mthd -+ add b32 $r7 $r6 -+ cmpu b32 $r4 $r7 -+ bra c dispatch_valid_mthd -+ sub b32 $r7 $r6 -+ shl b32 $r7 3 -+ add b32 $r5 $r7 -+ bra dispatch_loop -+ -+ // ensure no bits set in reserved fields, INVALID_BITFIELD -+ dispatch_valid_mthd: -+ sub b32 $r4 $r6 -+ shl b32 $r4 3 -+ add b32 $r4 $r5 -+ ld b32 $r5 D[$r4 + 4] -+ and $r5 $r3 -+ cmpu b32 $r5 0 -+ bra ne dispatch_invalid_bitfield -+ -+ // depending on dispatch flags: execute method, or save data as state -+ ld b16 $r5 D[$r4 + 0] -+ ld b16 $r6 D[$r4 + 2] -+ cmpu b32 $r6 0 -+ bra ne dispatch_cmd -+ st b32 D[$r5] $r3 -+ bra dispatch_done -+ dispatch_cmd: -+ bclr $flags $p1 -+ call $r5 -+ bra $p1 dispatch_error -+ bra dispatch_done -+ -+ dispatch_invalid_bitfield: -+ or $r2 2 -+ dispatch_illegal_mthd: -+ or $r2 1 -+ -+ // store exception data in SCRATCH0/SCRATCH1, signal hostirq -+ dispatch_error: -+ mov $r4 0x1000 -+ iowr I[$r4 + 0x000] $r2 -+ iowr I[$r4 + 0x100] $r3 -+ mov $r2 0x40 -+ iowr I[$r0] $r2 -+ hostirq_wait: -+ iord $r2 I[$r0 + 0x200] -+ and $r2 0x40 -+ cmpu b32 $r2 0 -+ bra ne hostirq_wait -+ -+ dispatch_done: -+ mov $r2 0x1d00 -+ mov $r3 1 -+ iowr I[$r2] $r3 -+ ret -+ -+// No-operation -+// -+// Inputs: -+// $r1: irqh state -+// $r2: hostirq state -+// $r3: data -+// $r4: dispatch table entry -+// Outputs: -+// $r1: irqh state -+// $p1: set on error -+// $r2: hostirq state -+// $r3: data -+cmd_nop: -+ ret -+ -+// PM_TRIGGER -+// -+// Inputs: -+// $r1: irqh state -+// $r2: hostirq state -+// $r3: data -+// $r4: dispatch table entry -+// Outputs: -+// $r1: irqh state -+// $p1: set on error -+// $r2: hostirq state -+// $r3: data -+cmd_pm_trigger: -+ mov $r2 0x2200 -+ clear b32 $r3 -+ sethi $r3 0x20000 -+ iowr I[$r2] $r3 -+ ret -+ -+ifdef(`NVA3', -+// SET_DMA_* method handler -+// -+// Inputs: -+// $r1: irqh state -+// $r2: hostirq state -+// $r3: data -+// $r4: dispatch table entry -+// Outputs: -+// $r1: irqh state -+// $p1: set on error -+// $r2: hostirq state -+// $r3: data -+cmd_dma: -+ sub b32 $r4 dispatch_dma -+ shr b32 $r4 1 -+ bset $r3 0x1e -+ st b32 D[$r4 + ctx_dma] $r3 -+ add b32 $r4 0x600 -+ shl b32 $r4 6 -+ iowr I[$r4] $r3 -+ ret -+,) -+ -+// Calculates the hw swizzle mask and adjusts the surface's xcnt to match -+// -+cmd_exec_set_format: -+ // zero out a chunk of the stack to store the swizzle into -+ add $sp -0x10 -+ st b32 D[$sp + 0x00] $r0 -+ st b32 D[$sp + 0x04] $r0 -+ st b32 D[$sp + 0x08] $r0 -+ st b32 D[$sp + 0x0c] $r0 -+ -+ // extract cpp, src_ncomp and dst_ncomp from FORMAT -+ ld b32 $r4 D[$r0 + ctx_format] -+ extr $r5 $r4 16:17 -+ add b32 $r5 1 -+ extr $r6 $r4 20:21 -+ add b32 $r6 1 -+ extr $r7 $r4 24:25 -+ add b32 $r7 1 -+ -+ // convert FORMAT swizzle mask to hw swizzle mask -+ bclr $flags $p2 -+ clear b32 $r8 -+ clear b32 $r9 -+ ncomp_loop: -+ and $r10 $r4 0xf -+ shr b32 $r4 4 -+ clear b32 $r11 -+ bpc_loop: -+ cmpu b8 $r10 4 -+ bra nc cmp_c0 -+ mulu $r12 $r10 $r5 -+ add b32 $r12 $r11 -+ bset $flags $p2 -+ bra bpc_next -+ cmp_c0: -+ bra ne cmp_c1 -+ mov $r12 0x10 -+ add b32 $r12 $r11 -+ bra bpc_next -+ cmp_c1: -+ cmpu b8 $r10 6 -+ bra nc cmp_zero -+ mov $r12 0x14 -+ add b32 $r12 $r11 -+ bra bpc_next -+ cmp_zero: -+ mov $r12 0x80 -+ bpc_next: -+ st b8 D[$sp + $r8] $r12 -+ add b32 $r8 1 -+ add b32 $r11 1 -+ cmpu b32 $r11 $r5 -+ bra c bpc_loop -+ add b32 $r9 1 -+ cmpu b32 $r9 $r7 -+ bra c ncomp_loop -+ -+ // SRC_XCNT = (xcnt * src_cpp), or 0 if no src ref in swz (hw will hang) -+ mulu $r6 $r5 -+ st b32 D[$r0 + ctx_src_cpp] $r6 -+ ld b32 $r8 D[$r0 + ctx_xcnt] -+ mulu $r6 $r8 -+ bra $p2 dst_xcnt -+ clear b32 $r6 -+ -+ dst_xcnt: -+ mulu $r7 $r5 -+ st b32 D[$r0 + ctx_dst_cpp] $r7 -+ mulu $r7 $r8 -+ -+ mov $r5 0x810 -+ shl b32 $r5 6 -+ iowr I[$r5 + 0x000] $r6 -+ iowr I[$r5 + 0x100] $r7 -+ add b32 $r5 0x800 -+ ld b32 $r6 D[$r0 + ctx_dst_cpp] -+ sub b32 $r6 1 -+ shl b32 $r6 8 -+ ld b32 $r7 D[$r0 + ctx_src_cpp] -+ sub b32 $r7 1 -+ or $r6 $r7 -+ iowr I[$r5 + 0x000] $r6 -+ add b32 $r5 0x100 -+ ld b32 $r6 D[$sp + 0x00] -+ iowr I[$r5 + 0x000] $r6 -+ ld b32 $r6 D[$sp + 0x04] -+ iowr I[$r5 + 0x100] $r6 -+ ld b32 $r6 D[$sp + 0x08] -+ iowr I[$r5 + 0x200] $r6 -+ ld b32 $r6 D[$sp + 0x0c] -+ iowr I[$r5 + 0x300] $r6 -+ add b32 $r5 0x400 -+ ld b32 $r6 D[$r0 + ctx_swz_const0] -+ iowr I[$r5 + 0x000] $r6 -+ ld b32 $r6 D[$r0 + ctx_swz_const1] -+ iowr I[$r5 + 0x100] $r6 -+ add $sp 0x10 -+ ret -+ -+// Setup to handle a tiled surface -+// -+// Calculates a number of parameters the hardware requires in order -+// to correctly handle tiling. -+// -+// Offset calculation is performed as follows (Tp/Th/Td from TILE_MODE): -+// nTx = round_up(w * cpp, 1 << Tp) >> Tp -+// nTy = round_up(h, 1 << Th) >> Th -+// Txo = (x * cpp) & ((1 << Tp) - 1) -+// Tx = (x * cpp) >> Tp -+// Tyo = y & ((1 << Th) - 1) -+// Ty = y >> Th -+// Tzo = z & ((1 << Td) - 1) -+// Tz = z >> Td -+// -+// off = (Tzo << Tp << Th) + (Tyo << Tp) + Txo -+// off += ((Tz * nTy * nTx)) + (Ty * nTx) + Tx) << Td << Th << Tp; -+// -+// Inputs: -+// $r4: hw command (0x104800) -+// $r5: ctx offset adjustment for src/dst selection -+// $p2: set if dst surface -+// -+cmd_exec_set_surface_tiled: -+ // translate TILE_MODE into Tp, Th, Td shift values -+ ld b32 $r7 D[$r5 + ctx_src_tile_mode] -+ extr $r9 $r7 8:11 -+ extr $r8 $r7 4:7 -+ifdef(`NVA3', -+ add b32 $r8 2 -+, -+ add b32 $r8 3 -+) -+ extr $r7 $r7 0:3 -+ cmp b32 $r7 0xe -+ bra ne xtile64 -+ mov $r7 4 -+ bra xtileok -+ xtile64: -+ xbit $r7 $flags $p2 -+ add b32 $r7 17 -+ bset $r4 $r7 -+ mov $r7 6 -+ xtileok: -+ -+ // Op = (x * cpp) & ((1 << Tp) - 1) -+ // Tx = (x * cpp) >> Tp -+ ld b32 $r10 D[$r5 + ctx_src_xoff] -+ ld b32 $r11 D[$r5 + ctx_src_cpp] -+ mulu $r10 $r11 -+ mov $r11 1 -+ shl b32 $r11 $r7 -+ sub b32 $r11 1 -+ and $r12 $r10 $r11 -+ shr b32 $r10 $r7 -+ -+ // Tyo = y & ((1 << Th) - 1) -+ // Ty = y >> Th -+ ld b32 $r13 D[$r5 + ctx_src_yoff] -+ mov $r14 1 -+ shl b32 $r14 $r8 -+ sub b32 $r14 1 -+ and $r11 $r13 $r14 -+ shr b32 $r13 $r8 -+ -+ // YTILE = ((1 << Th) << 12) | ((1 << Th) - Tyo) -+ add b32 $r14 1 -+ shl b32 $r15 $r14 12 -+ sub b32 $r14 $r11 -+ or $r15 $r14 -+ xbit $r6 $flags $p2 -+ add b32 $r6 0x208 -+ shl b32 $r6 8 -+ iowr I[$r6 + 0x000] $r15 -+ -+ // Op += Tyo << Tp -+ shl b32 $r11 $r7 -+ add b32 $r12 $r11 -+ -+ // nTx = ((w * cpp) + ((1 << Tp) - 1) >> Tp) -+ ld b32 $r15 D[$r5 + ctx_src_xsize] -+ ld b32 $r11 D[$r5 + ctx_src_cpp] -+ mulu $r15 $r11 -+ mov $r11 1 -+ shl b32 $r11 $r7 -+ sub b32 $r11 1 -+ add b32 $r15 $r11 -+ shr b32 $r15 $r7 -+ push $r15 -+ -+ // nTy = (h + ((1 << Th) - 1)) >> Th -+ ld b32 $r15 D[$r5 + ctx_src_ysize] -+ mov $r11 1 -+ shl b32 $r11 $r8 -+ sub b32 $r11 1 -+ add b32 $r15 $r11 -+ shr b32 $r15 $r8 -+ push $r15 -+ -+ // Tys = Tp + Th -+ // CFG_YZ_TILE_SIZE = ((1 << Th) >> 2) << Td -+ add b32 $r7 $r8 -+ sub b32 $r8 2 -+ mov $r11 1 -+ shl b32 $r11 $r8 -+ shl b32 $r11 $r9 -+ -+ // Tzo = z & ((1 << Td) - 1) -+ // Tz = z >> Td -+ // Op += Tzo << Tys -+ // Ts = Tys + Td -+ ld b32 $r8 D[$r5 + ctx_src_zoff] -+ mov $r14 1 -+ shl b32 $r14 $r9 -+ sub b32 $r14 1 -+ and $r15 $r8 $r14 -+ shl b32 $r15 $r7 -+ add b32 $r12 $r15 -+ add b32 $r7 $r9 -+ shr b32 $r8 $r9 -+ -+ // Ot = ((Tz * nTy * nTx) + (Ty * nTx) + Tx) << Ts -+ pop $r15 -+ pop $r9 -+ mulu $r13 $r9 -+ add b32 $r10 $r13 -+ mulu $r8 $r9 -+ mulu $r8 $r15 -+ add b32 $r10 $r8 -+ shl b32 $r10 $r7 -+ -+ // PITCH = (nTx - 1) << Ts -+ sub b32 $r9 1 -+ shl b32 $r9 $r7 -+ iowr I[$r6 + 0x200] $r9 -+ -+ // SRC_ADDRESS_LOW = (Ot + Op) & 0xffffffff -+ // CFG_ADDRESS_HIGH |= ((Ot + Op) >> 32) << 16 -+ ld b32 $r7 D[$r5 + ctx_src_address_low] -+ ld b32 $r8 D[$r5 + ctx_src_address_high] -+ add b32 $r10 $r12 -+ add b32 $r7 $r10 -+ adc b32 $r8 0 -+ shl b32 $r8 16 -+ or $r8 $r11 -+ sub b32 $r6 0x600 -+ iowr I[$r6 + 0x000] $r7 -+ add b32 $r6 0x400 -+ iowr I[$r6 + 0x000] $r8 -+ ret -+ -+// Setup to handle a linear surface -+// -+// Nothing to see here.. Sets ADDRESS and PITCH, pretty non-exciting -+// -+cmd_exec_set_surface_linear: -+ xbit $r6 $flags $p2 -+ add b32 $r6 0x202 -+ shl b32 $r6 8 -+ ld b32 $r7 D[$r5 + ctx_src_address_low] -+ iowr I[$r6 + 0x000] $r7 -+ add b32 $r6 0x400 -+ ld b32 $r7 D[$r5 + ctx_src_address_high] -+ shl b32 $r7 16 -+ iowr I[$r6 + 0x000] $r7 -+ add b32 $r6 0x400 -+ ld b32 $r7 D[$r5 + ctx_src_pitch] -+ iowr I[$r6 + 0x000] $r7 -+ ret -+ -+// wait for regs to be available for use -+cmd_exec_wait: -+ push $r0 -+ push $r1 -+ mov $r0 0x800 -+ shl b32 $r0 6 -+ loop: -+ iord $r1 I[$r0] -+ and $r1 1 -+ bra ne loop -+ pop $r1 -+ pop $r0 -+ ret -+ -+cmd_exec_query: -+ // if QUERY_SHORT not set, write out { -, 0, TIME_LO, TIME_HI } -+ xbit $r4 $r3 13 -+ bra ne query_counter -+ call cmd_exec_wait -+ mov $r4 0x80c -+ shl b32 $r4 6 -+ ld b32 $r5 D[$r0 + ctx_query_address_low] -+ add b32 $r5 4 -+ iowr I[$r4 + 0x000] $r5 -+ iowr I[$r4 + 0x100] $r0 -+ mov $r5 0xc -+ iowr I[$r4 + 0x200] $r5 -+ add b32 $r4 0x400 -+ ld b32 $r5 D[$r0 + ctx_query_address_high] -+ shl b32 $r5 16 -+ iowr I[$r4 + 0x000] $r5 -+ add b32 $r4 0x500 -+ mov $r5 0x00000b00 -+ sethi $r5 0x00010000 -+ iowr I[$r4 + 0x000] $r5 -+ mov $r5 0x00004040 -+ shl b32 $r5 1 -+ sethi $r5 0x80800000 -+ iowr I[$r4 + 0x100] $r5 -+ mov $r5 0x00001110 -+ sethi $r5 0x13120000 -+ iowr I[$r4 + 0x200] $r5 -+ mov $r5 0x00001514 -+ sethi $r5 0x17160000 -+ iowr I[$r4 + 0x300] $r5 -+ mov $r5 0x00002601 -+ sethi $r5 0x00010000 -+ mov $r4 0x800 -+ shl b32 $r4 6 -+ iowr I[$r4 + 0x000] $r5 -+ -+ // write COUNTER -+ query_counter: -+ call cmd_exec_wait -+ mov $r4 0x80c -+ shl b32 $r4 6 -+ ld b32 $r5 D[$r0 + ctx_query_address_low] -+ iowr I[$r4 + 0x000] $r5 -+ iowr I[$r4 + 0x100] $r0 -+ mov $r5 0x4 -+ iowr I[$r4 + 0x200] $r5 -+ add b32 $r4 0x400 -+ ld b32 $r5 D[$r0 + ctx_query_address_high] -+ shl b32 $r5 16 -+ iowr I[$r4 + 0x000] $r5 -+ add b32 $r4 0x500 -+ mov $r5 0x00000300 -+ iowr I[$r4 + 0x000] $r5 -+ mov $r5 0x00001110 -+ sethi $r5 0x13120000 -+ iowr I[$r4 + 0x100] $r5 -+ ld b32 $r5 D[$r0 + ctx_query_counter] -+ add b32 $r4 0x500 -+ iowr I[$r4 + 0x000] $r5 -+ mov $r5 0x00002601 -+ sethi $r5 0x00010000 -+ mov $r4 0x800 -+ shl b32 $r4 6 -+ iowr I[$r4 + 0x000] $r5 -+ ret -+ -+// Execute a copy operation -+// -+// Inputs: -+// $r1: irqh state -+// $r2: hostirq state -+// $r3: data -+// 000002000 QUERY_SHORT -+// 000001000 QUERY -+// 000000100 DST_LINEAR -+// 000000010 SRC_LINEAR -+// 000000001 FORMAT -+// $r4: dispatch table entry -+// Outputs: -+// $r1: irqh state -+// $p1: set on error -+// $r2: hostirq state -+// $r3: data -+cmd_exec: -+ call cmd_exec_wait -+ -+ // if format requested, call function to calculate it, otherwise -+ // fill in cpp/xcnt for both surfaces as if (cpp == 1) -+ xbit $r15 $r3 0 -+ bra e cmd_exec_no_format -+ call cmd_exec_set_format -+ mov $r4 0x200 -+ bra cmd_exec_init_src_surface -+ cmd_exec_no_format: -+ mov $r6 0x810 -+ shl b32 $r6 6 -+ mov $r7 1 -+ st b32 D[$r0 + ctx_src_cpp] $r7 -+ st b32 D[$r0 + ctx_dst_cpp] $r7 -+ ld b32 $r7 D[$r0 + ctx_xcnt] -+ iowr I[$r6 + 0x000] $r7 -+ iowr I[$r6 + 0x100] $r7 -+ clear b32 $r4 -+ -+ cmd_exec_init_src_surface: -+ bclr $flags $p2 -+ clear b32 $r5 -+ xbit $r15 $r3 4 -+ bra e src_tiled -+ call cmd_exec_set_surface_linear -+ bra cmd_exec_init_dst_surface -+ src_tiled: -+ call cmd_exec_set_surface_tiled -+ bset $r4 7 -+ -+ cmd_exec_init_dst_surface: -+ bset $flags $p2 -+ mov $r5 ctx_dst_address_high - ctx_src_address_high -+ xbit $r15 $r3 8 -+ bra e dst_tiled -+ call cmd_exec_set_surface_linear -+ bra cmd_exec_kick -+ dst_tiled: -+ call cmd_exec_set_surface_tiled -+ bset $r4 8 -+ -+ cmd_exec_kick: -+ mov $r5 0x800 -+ shl b32 $r5 6 -+ ld b32 $r6 D[$r0 + ctx_ycnt] -+ iowr I[$r5 + 0x100] $r6 -+ mov $r6 0x0041 -+ // SRC_TARGET = 1, DST_TARGET = 2 -+ sethi $r6 0x44000000 -+ or $r4 $r6 -+ iowr I[$r5] $r4 -+ -+ // if requested, queue up a QUERY write after the copy has completed -+ xbit $r15 $r3 12 -+ bra e cmd_exec_done -+ call cmd_exec_query -+ -+ cmd_exec_done: -+ ret -+ -+// Flush write cache -+// -+// Inputs: -+// $r1: irqh state -+// $r2: hostirq state -+// $r3: data -+// $r4: dispatch table entry -+// Outputs: -+// $r1: irqh state -+// $p1: set on error -+// $r2: hostirq state -+// $r3: data -+cmd_wrcache_flush: -+ mov $r2 0x2200 -+ clear b32 $r3 -+ sethi $r3 0x10000 -+ iowr I[$r2] $r3 -+ ret -+ -+.align 0x100 -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nva3_copy.fuc.h linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nva3_copy.fuc.h ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nva3_copy.fuc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nva3_copy.fuc.h 2011-05-09 00:36:22.000000000 +0200 -@@ -0,0 +1,534 @@ -+uint32_t nva3_pcopy_data[] = { -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00010000, -+ 0x00000000, -+ 0x00000000, -+ 0x00010040, -+ 0x00010160, -+ 0x00000000, -+ 0x00010050, -+ 0x00010162, -+ 0x00000000, -+ 0x00030060, -+ 0x00010170, -+ 0x00000000, -+ 0x00010170, -+ 0x00000000, -+ 0x00010170, -+ 0x00000000, -+ 0x00070080, -+ 0x00000028, -+ 0xfffff000, -+ 0x0000002c, -+ 0xfff80000, -+ 0x00000030, -+ 0xffffe000, -+ 0x00000034, -+ 0xfffff800, -+ 0x00000038, -+ 0xfffff000, -+ 0x0000003c, -+ 0xfff80000, -+ 0x00000040, -+ 0xffffe000, -+ 0x00070088, -+ 0x00000054, -+ 0xfffff000, -+ 0x00000058, -+ 0xfff80000, -+ 0x0000005c, -+ 0xffffe000, -+ 0x00000060, -+ 0xfffff800, -+ 0x00000064, -+ 0xfffff000, -+ 0x00000068, -+ 0xfff80000, -+ 0x0000006c, -+ 0xffffe000, -+ 0x000200c0, -+ 0x00010492, -+ 0x00000000, -+ 0x0001051b, -+ 0x00000000, -+ 0x000e00c3, -+ 0x0000001c, -+ 0xffffff00, -+ 0x00000020, -+ 0x0000000f, -+ 0x00000048, -+ 0xffffff00, -+ 0x0000004c, -+ 0x0000000f, -+ 0x00000024, -+ 0xfff80000, -+ 0x00000050, -+ 0xfff80000, -+ 0x00000080, -+ 0xffff0000, -+ 0x00000084, -+ 0xffffe000, -+ 0x00000074, -+ 0xfccc0000, -+ 0x00000078, -+ 0x00000000, -+ 0x0000007c, -+ 0x00000000, -+ 0x00000010, -+ 0xffffff00, -+ 0x00000014, -+ 0x00000000, -+ 0x00000018, -+ 0x00000000, -+ 0x00000800, -+}; -+ -+uint32_t nva3_pcopy_code[] = { -+ 0x04fe04bd, -+ 0x3517f000, -+ 0xf10010fe, -+ 0xf1040017, -+ 0xf0fff327, -+ 0x22d00023, -+ 0x0c25f0c0, -+ 0xf40012d0, -+ 0x17f11031, -+ 0x27f01200, -+ 0x0012d003, -+ 0xf40031f4, -+ 0x0ef40028, -+ 0x8001cffd, -+ 0xf40812c4, -+ 0x21f4060b, -+ 0x0412c472, -+ 0xf4060bf4, -+ 0x11c4c321, -+ 0x4001d00c, -+ 0x47f101f8, -+ 0x4bfe7700, -+ 0x0007fe00, -+ 0xf00204b9, -+ 0x01f40643, -+ 0x0604fa09, -+ 0xfa060ef4, -+ 0x03f80504, -+ 0x27f100f8, -+ 0x23cf1400, -+ 0x1e3fc800, -+ 0xf4170bf4, -+ 0x21f40132, -+ 0x1e3af052, -+ 0xf00023d0, -+ 0x24d00147, -+ 0xcf00f880, -+ 0x3dc84023, -+ 0x220bf41e, -+ 0xf40131f4, -+ 0x57f05221, -+ 0x0367f004, -+ 0xa07856bc, -+ 0xb6018068, -+ 0x87d00884, -+ 0x0162b600, -+ 0xf0f018f4, -+ 0x23d00237, -+ 0xf100f880, -+ 0xcf190037, -+ 0x33cf4032, -+ 0xff24e400, -+ 0x1024b607, -+ 0x010057f1, -+ 0x74bd64bd, -+ 0x58005658, -+ 0x50b60157, -+ 0x0446b804, -+ 0xbb4d08f4, -+ 0x47b80076, -+ 0x0f08f404, -+ 0xb60276bb, -+ 0x57bb0374, -+ 0xdf0ef400, -+ 0xb60246bb, -+ 0x45bb0344, -+ 0x01459800, -+ 0xb00453fd, -+ 0x1bf40054, -+ 0x00455820, -+ 0xb0014658, -+ 0x1bf40064, -+ 0x00538009, -+ 0xf4300ef4, -+ 0x55f90132, -+ 0xf40c01f4, -+ 0x25f0250e, -+ 0x0125f002, -+ 0x100047f1, -+ 0xd00042d0, -+ 0x27f04043, -+ 0x0002d040, -+ 0xf08002cf, -+ 0x24b04024, -+ 0xf71bf400, -+ 0x1d0027f1, -+ 0xd00137f0, -+ 0x00f80023, -+ 0x27f100f8, -+ 0x34bd2200, -+ 0xd00233f0, -+ 0x00f80023, -+ 0x012842b7, -+ 0xf00145b6, -+ 0x43801e39, -+ 0x0040b701, -+ 0x0644b606, -+ 0xf80043d0, -+ 0xf030f400, -+ 0xb00001b0, -+ 0x01b00101, -+ 0x0301b002, -+ 0xc71d0498, -+ 0x50b63045, -+ 0x3446c701, -+ 0xc70160b6, -+ 0x70b63847, -+ 0x0232f401, -+ 0x94bd84bd, -+ 0xb60f4ac4, -+ 0xb4bd0445, -+ 0xf404a430, -+ 0xa5ff0f18, -+ 0x00cbbbc0, -+ 0xf40231f4, -+ 0x1bf4220e, -+ 0x10c7f00c, -+ 0xf400cbbb, -+ 0xa430160e, -+ 0x0c18f406, -+ 0xbb14c7f0, -+ 0x0ef400cb, -+ 0x80c7f107, -+ 0x01c83800, -+ 0xb60180b6, -+ 0xb5b801b0, -+ 0xc308f404, -+ 0xb80190b6, -+ 0x08f40497, -+ 0x0065fdb2, -+ 0x98110680, -+ 0x68fd2008, -+ 0x0502f400, -+ 0x75fd64bd, -+ 0x1c078000, -+ 0xf10078fd, -+ 0xb6081057, -+ 0x56d00654, -+ 0x4057d000, -+ 0x080050b7, -+ 0xb61c0698, -+ 0x64b60162, -+ 0x11079808, -+ 0xfd0172b6, -+ 0x56d00567, -+ 0x0050b700, -+ 0x0060b401, -+ 0xb40056d0, -+ 0x56d00160, -+ 0x0260b440, -+ 0xb48056d0, -+ 0x56d00360, -+ 0x0050b7c0, -+ 0x1e069804, -+ 0x980056d0, -+ 0x56d01f06, -+ 0x1030f440, -+ 0x579800f8, -+ 0x6879c70a, -+ 0xb66478c7, -+ 0x77c70280, -+ 0x0e76b060, -+ 0xf0091bf4, -+ 0x0ef40477, -+ 0x027cf00f, -+ 0xfd1170b6, -+ 0x77f00947, -+ 0x0f5a9806, -+ 0xfd115b98, -+ 0xb7f000ab, -+ 0x04b7bb01, -+ 0xff01b2b6, -+ 0xa7bbc4ab, -+ 0x105d9805, -+ 0xbb01e7f0, -+ 0xe2b604e8, -+ 0xb4deff01, -+ 0xb605d8bb, -+ 0xef9401e0, -+ 0x02ebbb0c, -+ 0xf005fefd, -+ 0x60b7026c, -+ 0x64b60208, -+ 0x006fd008, -+ 0xbb04b7bb, -+ 0x5f9800cb, -+ 0x115b980b, -+ 0xf000fbfd, -+ 0xb7bb01b7, -+ 0x01b2b604, -+ 0xbb00fbbb, -+ 0xf0f905f7, -+ 0xf00c5f98, -+ 0xb8bb01b7, -+ 0x01b2b604, -+ 0xbb00fbbb, -+ 0xf0f905f8, -+ 0xb60078bb, -+ 0xb7f00282, -+ 0x04b8bb01, -+ 0x9804b9bb, -+ 0xe7f00e58, -+ 0x04e9bb01, -+ 0xff01e2b6, -+ 0xf7bbf48e, -+ 0x00cfbb04, -+ 0xbb0079bb, -+ 0xf0fc0589, -+ 0xd9fd90fc, -+ 0x00adbb00, -+ 0xfd0089fd, -+ 0xa8bb008f, -+ 0x04a7bb00, -+ 0xbb0192b6, -+ 0x69d00497, -+ 0x08579880, -+ 0xbb075898, -+ 0x7abb00ac, -+ 0x0081b600, -+ 0xfd1084b6, -+ 0x62b7058b, -+ 0x67d00600, -+ 0x0060b700, -+ 0x0068d004, -+ 0x6cf000f8, -+ 0x0260b702, -+ 0x0864b602, -+ 0xd0085798, -+ 0x60b70067, -+ 0x57980400, -+ 0x1074b607, -+ 0xb70067d0, -+ 0x98040060, -+ 0x67d00957, -+ 0xf900f800, -+ 0xf110f900, -+ 0xb6080007, -+ 0x01cf0604, -+ 0x0114f000, -+ 0xfcfa1bf4, -+ 0xf800fc10, -+ 0x0d34c800, -+ 0xf5701bf4, -+ 0xf103ab21, -+ 0xb6080c47, -+ 0x05980644, -+ 0x0450b605, -+ 0xd00045d0, -+ 0x57f04040, -+ 0x8045d00c, -+ 0x040040b7, -+ 0xb6040598, -+ 0x45d01054, -+ 0x0040b700, -+ 0x0057f105, -+ 0x0153f00b, -+ 0xf10045d0, -+ 0xb6404057, -+ 0x53f10154, -+ 0x45d08080, -+ 0x1057f140, -+ 0x1253f111, -+ 0x8045d013, -+ 0x151457f1, -+ 0x171653f1, -+ 0xf1c045d0, -+ 0xf0260157, -+ 0x47f10153, -+ 0x44b60800, -+ 0x0045d006, -+ 0x03ab21f5, -+ 0x080c47f1, -+ 0x980644b6, -+ 0x45d00505, -+ 0x4040d000, -+ 0xd00457f0, -+ 0x40b78045, -+ 0x05980400, -+ 0x1054b604, -+ 0xb70045d0, -+ 0xf1050040, -+ 0xd0030057, -+ 0x57f10045, -+ 0x53f11110, -+ 0x45d01312, -+ 0x06059840, -+ 0x050040b7, -+ 0xf10045d0, -+ 0xf0260157, -+ 0x47f10153, -+ 0x44b60800, -+ 0x0045d006, -+ 0x21f500f8, -+ 0x3fc803ab, -+ 0x0e0bf400, -+ 0x018921f5, -+ 0x020047f1, -+ 0xf11e0ef4, -+ 0xb6081067, -+ 0x77f00664, -+ 0x11078001, -+ 0x981c0780, -+ 0x67d02007, -+ 0x4067d000, -+ 0x32f444bd, -+ 0xc854bd02, -+ 0x0bf4043f, -+ 0x8221f50a, -+ 0x0a0ef403, -+ 0x027621f5, -+ 0xf40749f0, -+ 0x57f00231, -+ 0x083fc82c, -+ 0xf50a0bf4, -+ 0xf4038221, -+ 0x21f50a0e, -+ 0x49f00276, -+ 0x0057f108, -+ 0x0654b608, -+ 0xd0210698, -+ 0x67f04056, -+ 0x0063f141, -+ 0x0546fd44, -+ 0xc80054d0, -+ 0x0bf40c3f, -+ 0xc521f507, -+ 0xf100f803, -+ 0xbd220027, -+ 0x0133f034, -+ 0xf80023d0, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+}; -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nva3_pm.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nva3_pm.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nva3_pm.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nva3_pm.c 2011-05-09 00:36:22.000000000 +0200 -@@ -27,32 +27,74 @@ - #include "nouveau_bios.h" - #include "nouveau_pm.h" - --/*XXX: boards using limits 0x40 need fixing, the register layout -- * is correct here, but, there's some other funny magic -- * that modifies things, so it's not likely we'll set/read -- * the correct timings yet.. working on it... -+/* This is actually a lot more complex than it appears here, but hopefully -+ * this should be able to deal with what the VBIOS leaves for us.. -+ * -+ * If not, well, I'll jump off that bridge when I come to it. - */ - - struct nva3_pm_state { -- struct pll_lims pll; -- int N, M, P; -+ enum pll_types type; -+ u32 src0; -+ u32 src1; -+ u32 ctrl; -+ u32 coef; -+ u32 old_pnm; -+ u32 new_pnm; -+ u32 new_div; - }; - -+static int -+nva3_pm_pll_offset(u32 id) -+{ -+ static const u32 pll_map[] = { -+ 0x00, PLL_CORE, -+ 0x01, PLL_SHADER, -+ 0x02, PLL_MEMORY, -+ 0x00, 0x00 -+ }; -+ const u32 *map = pll_map; -+ -+ while (map[1]) { -+ if (id == map[1]) -+ return map[0]; -+ map += 2; -+ } -+ -+ return -ENOENT; -+} -+ - int - nva3_pm_clock_get(struct drm_device *dev, u32 id) - { -+ u32 src0, src1, ctrl, coef; - struct pll_lims pll; -- int P, N, M, ret; -- u32 reg; -+ int ret, off; -+ int P, N, M; - - ret = get_pll_limits(dev, id, &pll); - if (ret) - return ret; - -- reg = nv_rd32(dev, pll.reg + 4); -- P = (reg & 0x003f0000) >> 16; -- N = (reg & 0x0000ff00) >> 8; -- M = (reg & 0x000000ff); -+ off = nva3_pm_pll_offset(id); -+ if (off < 0) -+ return off; -+ -+ src0 = nv_rd32(dev, 0x4120 + (off * 4)); -+ src1 = nv_rd32(dev, 0x4160 + (off * 4)); -+ ctrl = nv_rd32(dev, pll.reg + 0); -+ coef = nv_rd32(dev, pll.reg + 4); -+ NV_DEBUG(dev, "PLL %02x: 0x%08x 0x%08x 0x%08x 0x%08x\n", -+ id, src0, src1, ctrl, coef); -+ -+ if (ctrl & 0x00000008) { -+ u32 div = ((src1 & 0x003c0000) >> 18) + 1; -+ return (pll.refclk * 2) / div; -+ } -+ -+ P = (coef & 0x003f0000) >> 16; -+ N = (coef & 0x0000ff00) >> 8; -+ M = (coef & 0x000000ff); - return pll.refclk * N / M / P; - } - -@@ -60,36 +102,103 @@ - nva3_pm_clock_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl, - u32 id, int khz) - { -- struct nva3_pm_state *state; -- int dummy, ret; -+ struct nva3_pm_state *pll; -+ struct pll_lims limits; -+ int N, M, P, diff; -+ int ret, off; - -- state = kzalloc(sizeof(*state), GFP_KERNEL); -- if (!state) -- return ERR_PTR(-ENOMEM); -- -- ret = get_pll_limits(dev, id, &state->pll); -- if (ret < 0) { -- kfree(state); -+ ret = get_pll_limits(dev, id, &limits); -+ if (ret < 0) - return (ret == -ENOENT) ? NULL : ERR_PTR(ret); -+ -+ off = nva3_pm_pll_offset(id); -+ if (id < 0) -+ return ERR_PTR(-EINVAL); -+ -+ -+ pll = kzalloc(sizeof(*pll), GFP_KERNEL); -+ if (!pll) -+ return ERR_PTR(-ENOMEM); -+ pll->type = id; -+ pll->src0 = 0x004120 + (off * 4); -+ pll->src1 = 0x004160 + (off * 4); -+ pll->ctrl = limits.reg + 0; -+ pll->coef = limits.reg + 4; -+ -+ /* If target clock is within [-2, 3) MHz of a divisor, we'll -+ * use that instead of calculating MNP values -+ */ -+ pll->new_div = min((limits.refclk * 2) / (khz - 2999), 16); -+ if (pll->new_div) { -+ diff = khz - ((limits.refclk * 2) / pll->new_div); -+ if (diff < -2000 || diff >= 3000) -+ pll->new_div = 0; - } - -- ret = nv50_calc_pll2(dev, &state->pll, khz, &state->N, &dummy, -- &state->M, &state->P); -- if (ret < 0) { -- kfree(state); -- return ERR_PTR(ret); -+ if (!pll->new_div) { -+ ret = nva3_calc_pll(dev, &limits, khz, &N, NULL, &M, &P); -+ if (ret < 0) -+ return ERR_PTR(ret); -+ -+ pll->new_pnm = (P << 16) | (N << 8) | M; -+ pll->new_div = 2 - 1; -+ } else { -+ pll->new_pnm = 0; -+ pll->new_div--; - } - -- return state; -+ if ((nv_rd32(dev, pll->src1) & 0x00000101) != 0x00000101) -+ pll->old_pnm = nv_rd32(dev, pll->coef); -+ return pll; - } - - void - nva3_pm_clock_set(struct drm_device *dev, void *pre_state) - { -- struct nva3_pm_state *state = pre_state; -- u32 reg = state->pll.reg; -+ struct nva3_pm_state *pll = pre_state; -+ u32 ctrl = 0; -+ -+ /* For the memory clock, NVIDIA will build a "script" describing -+ * the reclocking process and ask PDAEMON to execute it. -+ */ -+ if (pll->type == PLL_MEMORY) { -+ nv_wr32(dev, 0x100210, 0); -+ nv_wr32(dev, 0x1002dc, 1); -+ nv_wr32(dev, 0x004018, 0x00001000); -+ ctrl = 0x18000100; -+ } -+ -+ if (pll->old_pnm || !pll->new_pnm) { -+ nv_mask(dev, pll->src1, 0x003c0101, 0x00000101 | -+ (pll->new_div << 18)); -+ nv_wr32(dev, pll->ctrl, 0x0001001d | ctrl); -+ nv_mask(dev, pll->ctrl, 0x00000001, 0x00000000); -+ } -+ -+ if (pll->new_pnm) { -+ nv_mask(dev, pll->src0, 0x00000101, 0x00000101); -+ nv_wr32(dev, pll->coef, pll->new_pnm); -+ nv_wr32(dev, pll->ctrl, 0x0001001d | ctrl); -+ nv_mask(dev, pll->ctrl, 0x00000010, 0x00000000); -+ nv_mask(dev, pll->ctrl, 0x00020010, 0x00020010); -+ nv_wr32(dev, pll->ctrl, 0x00010015 | ctrl); -+ nv_mask(dev, pll->src1, 0x00000100, 0x00000000); -+ nv_mask(dev, pll->src1, 0x00000001, 0x00000000); -+ if (pll->type == PLL_MEMORY) -+ nv_wr32(dev, 0x4018, 0x10005000); -+ } else { -+ nv_mask(dev, pll->ctrl, 0x00000001, 0x00000000); -+ nv_mask(dev, pll->src0, 0x00000100, 0x00000000); -+ nv_mask(dev, pll->src0, 0x00000001, 0x00000000); -+ if (pll->type == PLL_MEMORY) -+ nv_wr32(dev, 0x4018, 0x1000d000); -+ } -+ -+ if (pll->type == PLL_MEMORY) { -+ nv_wr32(dev, 0x1002dc, 0); -+ nv_wr32(dev, 0x100210, 0x80000000); -+ } - -- nv_wr32(dev, reg + 4, (state->P << 16) | (state->N << 8) | state->M); -- kfree(state); -+ kfree(pll); - } - -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nvc0_copy.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nvc0_copy.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nvc0_copy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nvc0_copy.c 2011-05-09 00:36:22.000000000 +0200 -@@ -0,0 +1,243 @@ -+/* -+ * Copyright 2011 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 -+#include "drmP.h" -+#include "nouveau_drv.h" -+#include "nouveau_util.h" -+#include "nouveau_vm.h" -+#include "nouveau_ramht.h" -+#include "nvc0_copy.fuc.h" -+ -+struct nvc0_copy_engine { -+ struct nouveau_exec_engine base; -+ u32 irq; -+ u32 pmc; -+ u32 fuc; -+ u32 ctx; -+}; -+ -+static int -+nvc0_copy_context_new(struct nouveau_channel *chan, int engine) -+{ -+ struct nvc0_copy_engine *pcopy = nv_engine(chan->dev, engine); -+ struct drm_device *dev = chan->dev; -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nouveau_gpuobj *ramin = chan->ramin; -+ struct nouveau_gpuobj *ctx = NULL; -+ int ret; -+ -+ ret = nouveau_gpuobj_new(dev, NULL, 256, 256, -+ NVOBJ_FLAG_VM | NVOBJ_FLAG_VM_USER | -+ NVOBJ_FLAG_ZERO_ALLOC, &ctx); -+ if (ret) -+ return ret; -+ -+ nv_wo32(ramin, pcopy->ctx + 0, lower_32_bits(ctx->vinst)); -+ nv_wo32(ramin, pcopy->ctx + 4, upper_32_bits(ctx->vinst)); -+ dev_priv->engine.instmem.flush(dev); -+ -+ chan->engctx[engine] = ctx; -+ return 0; -+} -+ -+static int -+nvc0_copy_object_new(struct nouveau_channel *chan, int engine, -+ u32 handle, u16 class) -+{ -+ return 0; -+} -+ -+static void -+nvc0_copy_context_del(struct nouveau_channel *chan, int engine) -+{ -+ struct nvc0_copy_engine *pcopy = nv_engine(chan->dev, engine); -+ struct nouveau_gpuobj *ctx = chan->engctx[engine]; -+ struct drm_device *dev = chan->dev; -+ u32 inst; -+ -+ inst = (chan->ramin->vinst >> 12); -+ inst |= 0x40000000; -+ -+ /* disable fifo access */ -+ nv_wr32(dev, pcopy->fuc + 0x048, 0x00000000); -+ /* mark channel as unloaded if it's currently active */ -+ if (nv_rd32(dev, pcopy->fuc + 0x050) == inst) -+ nv_mask(dev, pcopy->fuc + 0x050, 0x40000000, 0x00000000); -+ /* mark next channel as invalid if it's about to be loaded */ -+ if (nv_rd32(dev, pcopy->fuc + 0x054) == inst) -+ nv_mask(dev, pcopy->fuc + 0x054, 0x40000000, 0x00000000); -+ /* restore fifo access */ -+ nv_wr32(dev, pcopy->fuc + 0x048, 0x00000003); -+ -+ nv_wo32(chan->ramin, pcopy->ctx + 0, 0x00000000); -+ nv_wo32(chan->ramin, pcopy->ctx + 4, 0x00000000); -+ nouveau_gpuobj_ref(NULL, &ctx); -+ -+ chan->engctx[engine] = ctx; -+} -+ -+static int -+nvc0_copy_init(struct drm_device *dev, int engine) -+{ -+ struct nvc0_copy_engine *pcopy = nv_engine(dev, engine); -+ int i; -+ -+ nv_mask(dev, 0x000200, pcopy->pmc, 0x00000000); -+ nv_mask(dev, 0x000200, pcopy->pmc, pcopy->pmc); -+ nv_wr32(dev, pcopy->fuc + 0x014, 0xffffffff); -+ -+ nv_wr32(dev, pcopy->fuc + 0x1c0, 0x01000000); -+ for (i = 0; i < sizeof(nvc0_pcopy_data) / 4; i++) -+ nv_wr32(dev, pcopy->fuc + 0x1c4, nvc0_pcopy_data[i]); -+ -+ nv_wr32(dev, pcopy->fuc + 0x180, 0x01000000); -+ for (i = 0; i < sizeof(nvc0_pcopy_code) / 4; i++) { -+ if ((i & 0x3f) == 0) -+ nv_wr32(dev, pcopy->fuc + 0x188, i >> 6); -+ nv_wr32(dev, pcopy->fuc + 0x184, nvc0_pcopy_code[i]); -+ } -+ -+ nv_wr32(dev, pcopy->fuc + 0x084, engine - NVOBJ_ENGINE_COPY0); -+ nv_wr32(dev, pcopy->fuc + 0x10c, 0x00000000); -+ nv_wr32(dev, pcopy->fuc + 0x104, 0x00000000); /* ENTRY */ -+ nv_wr32(dev, pcopy->fuc + 0x100, 0x00000002); /* TRIGGER */ -+ return 0; -+} -+ -+static int -+nvc0_copy_fini(struct drm_device *dev, int engine) -+{ -+ struct nvc0_copy_engine *pcopy = nv_engine(dev, engine); -+ -+ nv_mask(dev, pcopy->fuc + 0x048, 0x00000003, 0x00000000); -+ -+ /* trigger fuc context unload */ -+ nv_wait(dev, pcopy->fuc + 0x008, 0x0000000c, 0x00000000); -+ nv_mask(dev, pcopy->fuc + 0x054, 0x40000000, 0x00000000); -+ nv_wr32(dev, pcopy->fuc + 0x000, 0x00000008); -+ nv_wait(dev, pcopy->fuc + 0x008, 0x00000008, 0x00000000); -+ -+ nv_wr32(dev, pcopy->fuc + 0x014, 0xffffffff); -+ return 0; -+} -+ -+static struct nouveau_enum nvc0_copy_isr_error_name[] = { -+ { 0x0001, "ILLEGAL_MTHD" }, -+ { 0x0002, "INVALID_ENUM" }, -+ { 0x0003, "INVALID_BITFIELD" }, -+ {} -+}; -+ -+static void -+nvc0_copy_isr(struct drm_device *dev, int engine) -+{ -+ struct nvc0_copy_engine *pcopy = nv_engine(dev, engine); -+ u32 disp = nv_rd32(dev, pcopy->fuc + 0x01c); -+ u32 stat = nv_rd32(dev, pcopy->fuc + 0x008) & disp & ~(disp >> 16); -+ u64 inst = (u64)(nv_rd32(dev, pcopy->fuc + 0x050) & 0x0fffffff) << 12; -+ u32 chid = nvc0_graph_isr_chid(dev, inst); -+ u32 ssta = nv_rd32(dev, pcopy->fuc + 0x040) & 0x0000ffff; -+ u32 addr = nv_rd32(dev, pcopy->fuc + 0x040) >> 16; -+ u32 mthd = (addr & 0x07ff) << 2; -+ u32 subc = (addr & 0x3800) >> 11; -+ u32 data = nv_rd32(dev, pcopy->fuc + 0x044); -+ -+ if (stat & 0x00000040) { -+ NV_INFO(dev, "PCOPY: DISPATCH_ERROR ["); -+ nouveau_enum_print(nvc0_copy_isr_error_name, ssta); -+ printk("] ch %d [0x%010llx] subc %d mthd 0x%04x data 0x%08x\n", -+ chid, inst, subc, mthd, data); -+ nv_wr32(dev, pcopy->fuc + 0x004, 0x00000040); -+ stat &= ~0x00000040; -+ } -+ -+ if (stat) { -+ NV_INFO(dev, "PCOPY: unhandled intr 0x%08x\n", stat); -+ nv_wr32(dev, pcopy->fuc + 0x004, stat); -+ } -+} -+ -+static void -+nvc0_copy_isr_0(struct drm_device *dev) -+{ -+ nvc0_copy_isr(dev, NVOBJ_ENGINE_COPY0); -+} -+ -+static void -+nvc0_copy_isr_1(struct drm_device *dev) -+{ -+ nvc0_copy_isr(dev, NVOBJ_ENGINE_COPY1); -+} -+ -+static void -+nvc0_copy_destroy(struct drm_device *dev, int engine) -+{ -+ struct nvc0_copy_engine *pcopy = nv_engine(dev, engine); -+ -+ nouveau_irq_unregister(dev, pcopy->irq); -+ -+ if (engine == NVOBJ_ENGINE_COPY0) -+ NVOBJ_ENGINE_DEL(dev, COPY0); -+ else -+ NVOBJ_ENGINE_DEL(dev, COPY1); -+ kfree(pcopy); -+} -+ -+int -+nvc0_copy_create(struct drm_device *dev, int engine) -+{ -+ struct nvc0_copy_engine *pcopy; -+ -+ pcopy = kzalloc(sizeof(*pcopy), GFP_KERNEL); -+ if (!pcopy) -+ return -ENOMEM; -+ -+ pcopy->base.destroy = nvc0_copy_destroy; -+ pcopy->base.init = nvc0_copy_init; -+ pcopy->base.fini = nvc0_copy_fini; -+ pcopy->base.context_new = nvc0_copy_context_new; -+ pcopy->base.context_del = nvc0_copy_context_del; -+ pcopy->base.object_new = nvc0_copy_object_new; -+ -+ if (engine == 0) { -+ pcopy->irq = 5; -+ pcopy->pmc = 0x00000040; -+ pcopy->fuc = 0x104000; -+ pcopy->ctx = 0x0230; -+ nouveau_irq_register(dev, pcopy->irq, nvc0_copy_isr_0); -+ NVOBJ_ENGINE_ADD(dev, COPY0, &pcopy->base); -+ NVOBJ_CLASS(dev, 0x90b5, COPY0); -+ } else { -+ pcopy->irq = 6; -+ pcopy->pmc = 0x00000080; -+ pcopy->fuc = 0x105000; -+ pcopy->ctx = 0x0240; -+ nouveau_irq_register(dev, pcopy->irq, nvc0_copy_isr_1); -+ NVOBJ_ENGINE_ADD(dev, COPY1, &pcopy->base); -+ NVOBJ_CLASS(dev, 0x90b8, COPY1); -+ } -+ -+ return 0; -+} -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h 2011-05-09 00:36:22.000000000 +0200 -@@ -0,0 +1,527 @@ -+uint32_t nvc0_pcopy_data[] = { -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00010000, -+ 0x00000000, -+ 0x00000000, -+ 0x00010040, -+ 0x0001019f, -+ 0x00000000, -+ 0x00010050, -+ 0x000101a1, -+ 0x00000000, -+ 0x00070080, -+ 0x0000001c, -+ 0xfffff000, -+ 0x00000020, -+ 0xfff80000, -+ 0x00000024, -+ 0xffffe000, -+ 0x00000028, -+ 0xfffff800, -+ 0x0000002c, -+ 0xfffff000, -+ 0x00000030, -+ 0xfff80000, -+ 0x00000034, -+ 0xffffe000, -+ 0x00070088, -+ 0x00000048, -+ 0xfffff000, -+ 0x0000004c, -+ 0xfff80000, -+ 0x00000050, -+ 0xffffe000, -+ 0x00000054, -+ 0xfffff800, -+ 0x00000058, -+ 0xfffff000, -+ 0x0000005c, -+ 0xfff80000, -+ 0x00000060, -+ 0xffffe000, -+ 0x000200c0, -+ 0x000104b8, -+ 0x00000000, -+ 0x00010541, -+ 0x00000000, -+ 0x000e00c3, -+ 0x00000010, -+ 0xffffff00, -+ 0x00000014, -+ 0x0000000f, -+ 0x0000003c, -+ 0xffffff00, -+ 0x00000040, -+ 0x0000000f, -+ 0x00000018, -+ 0xfff80000, -+ 0x00000044, -+ 0xfff80000, -+ 0x00000074, -+ 0xffff0000, -+ 0x00000078, -+ 0xffffe000, -+ 0x00000068, -+ 0xfccc0000, -+ 0x0000006c, -+ 0x00000000, -+ 0x00000070, -+ 0x00000000, -+ 0x00000004, -+ 0xffffff00, -+ 0x00000008, -+ 0x00000000, -+ 0x0000000c, -+ 0x00000000, -+ 0x00000800, -+}; -+ -+uint32_t nvc0_pcopy_code[] = { -+ 0x04fe04bd, -+ 0x3517f000, -+ 0xf10010fe, -+ 0xf1040017, -+ 0xf0fff327, -+ 0x22d00023, -+ 0x0c25f0c0, -+ 0xf40012d0, -+ 0x17f11031, -+ 0x27f01200, -+ 0x0012d003, -+ 0xf40031f4, -+ 0x0ef40028, -+ 0x8001cffd, -+ 0xf40812c4, -+ 0x21f4060b, -+ 0x0412c4ca, -+ 0xf5070bf4, -+ 0xc4010221, -+ 0x01d00c11, -+ 0xf101f840, -+ 0xfe770047, -+ 0x47f1004b, -+ 0x44cf2100, -+ 0x0144f000, -+ 0xb60444b6, -+ 0xf7f13040, -+ 0xf4b6061c, -+ 0x1457f106, -+ 0x00f5d101, -+ 0xb6043594, -+ 0x57fe0250, -+ 0x0145fe00, -+ 0x010052b7, -+ 0x00ff67f1, -+ 0x56fd60bd, -+ 0x0253f004, -+ 0xf80545fa, -+ 0x0053f003, -+ 0xd100e7f0, -+ 0x549800fe, -+ 0x0845b600, -+ 0xb6015698, -+ 0x46fd1864, -+ 0x0047fe05, -+ 0xf00204b9, -+ 0x01f40643, -+ 0x0604fa09, -+ 0xfa060ef4, -+ 0x03f80504, -+ 0x27f100f8, -+ 0x23cf1400, -+ 0x1e3fc800, -+ 0xf4170bf4, -+ 0x21f40132, -+ 0x1e3af053, -+ 0xf00023d0, -+ 0x24d00147, -+ 0xcf00f880, -+ 0x3dc84023, -+ 0x090bf41e, -+ 0xf40131f4, -+ 0x37f05321, -+ 0x8023d002, -+ 0x37f100f8, -+ 0x32cf1900, -+ 0x0033cf40, -+ 0x07ff24e4, -+ 0xf11024b6, -+ 0xbd010057, -+ 0x5874bd64, -+ 0x57580056, -+ 0x0450b601, -+ 0xf40446b8, -+ 0x76bb4d08, -+ 0x0447b800, -+ 0xbb0f08f4, -+ 0x74b60276, -+ 0x0057bb03, -+ 0xbbdf0ef4, -+ 0x44b60246, -+ 0x0045bb03, -+ 0xfd014598, -+ 0x54b00453, -+ 0x201bf400, -+ 0x58004558, -+ 0x64b00146, -+ 0x091bf400, -+ 0xf4005380, -+ 0x32f4300e, -+ 0xf455f901, -+ 0x0ef40c01, -+ 0x0225f025, -+ 0xf10125f0, -+ 0xd0100047, -+ 0x43d00042, -+ 0x4027f040, -+ 0xcf0002d0, -+ 0x24f08002, -+ 0x0024b040, -+ 0xf1f71bf4, -+ 0xf01d0027, -+ 0x23d00137, -+ 0xf800f800, -+ 0x0027f100, -+ 0xf034bd22, -+ 0x23d00233, -+ 0xf400f800, -+ 0x01b0f030, -+ 0x0101b000, -+ 0xb00201b0, -+ 0x04980301, -+ 0x3045c71a, -+ 0xc70150b6, -+ 0x60b63446, -+ 0x3847c701, -+ 0xf40170b6, -+ 0x84bd0232, -+ 0x4ac494bd, -+ 0x0445b60f, -+ 0xa430b4bd, -+ 0x0f18f404, -+ 0xbbc0a5ff, -+ 0x31f400cb, -+ 0x220ef402, -+ 0xf00c1bf4, -+ 0xcbbb10c7, -+ 0x160ef400, -+ 0xf406a430, -+ 0xc7f00c18, -+ 0x00cbbb14, -+ 0xf1070ef4, -+ 0x380080c7, -+ 0x80b601c8, -+ 0x01b0b601, -+ 0xf404b5b8, -+ 0x90b6c308, -+ 0x0497b801, -+ 0xfdb208f4, -+ 0x06800065, -+ 0x1d08980e, -+ 0xf40068fd, -+ 0x64bd0502, -+ 0x800075fd, -+ 0x78fd1907, -+ 0x1057f100, -+ 0x0654b608, -+ 0xd00056d0, -+ 0x50b74057, -+ 0x06980800, -+ 0x0162b619, -+ 0x980864b6, -+ 0x72b60e07, -+ 0x0567fd01, -+ 0xb70056d0, -+ 0xb4010050, -+ 0x56d00060, -+ 0x0160b400, -+ 0xb44056d0, -+ 0x56d00260, -+ 0x0360b480, -+ 0xb7c056d0, -+ 0x98040050, -+ 0x56d01b06, -+ 0x1c069800, -+ 0xf44056d0, -+ 0x00f81030, -+ 0xc7075798, -+ 0x78c76879, -+ 0x0380b664, -+ 0xb06077c7, -+ 0x1bf40e76, -+ 0x0477f009, -+ 0xf00f0ef4, -+ 0x70b6027c, -+ 0x0947fd11, -+ 0x980677f0, -+ 0x5b980c5a, -+ 0x00abfd0e, -+ 0xbb01b7f0, -+ 0xb2b604b7, -+ 0xc4abff01, -+ 0x9805a7bb, -+ 0xe7f00d5d, -+ 0x04e8bb01, -+ 0xff01e2b6, -+ 0xd8bbb4de, -+ 0x01e0b605, -+ 0xbb0cef94, -+ 0xfefd02eb, -+ 0x026cf005, -+ 0x020860b7, -+ 0xd00864b6, -+ 0xb7bb006f, -+ 0x00cbbb04, -+ 0x98085f98, -+ 0xfbfd0e5b, -+ 0x01b7f000, -+ 0xb604b7bb, -+ 0xfbbb01b2, -+ 0x05f7bb00, -+ 0x5f98f0f9, -+ 0x01b7f009, -+ 0xb604b8bb, -+ 0xfbbb01b2, -+ 0x05f8bb00, -+ 0x78bbf0f9, -+ 0x0282b600, -+ 0xbb01b7f0, -+ 0xb9bb04b8, -+ 0x0b589804, -+ 0xbb01e7f0, -+ 0xe2b604e9, -+ 0xf48eff01, -+ 0xbb04f7bb, -+ 0x79bb00cf, -+ 0x0589bb00, -+ 0x90fcf0fc, -+ 0xbb00d9fd, -+ 0x89fd00ad, -+ 0x008ffd00, -+ 0xbb00a8bb, -+ 0x92b604a7, -+ 0x0497bb01, -+ 0x988069d0, -+ 0x58980557, -+ 0x00acbb04, -+ 0xb6007abb, -+ 0x84b60081, -+ 0x058bfd10, -+ 0x060062b7, -+ 0xb70067d0, -+ 0xd0040060, -+ 0x00f80068, -+ 0xb7026cf0, -+ 0xb6020260, -+ 0x57980864, -+ 0x0067d005, -+ 0x040060b7, -+ 0xb6045798, -+ 0x67d01074, -+ 0x0060b700, -+ 0x06579804, -+ 0xf80067d0, -+ 0xf900f900, -+ 0x0007f110, -+ 0x0604b608, -+ 0xf00001cf, -+ 0x1bf40114, -+ 0xfc10fcfa, -+ 0xc800f800, -+ 0x1bf40d34, -+ 0xd121f570, -+ 0x0c47f103, -+ 0x0644b608, -+ 0xb6020598, -+ 0x45d00450, -+ 0x4040d000, -+ 0xd00c57f0, -+ 0x40b78045, -+ 0x05980400, -+ 0x1054b601, -+ 0xb70045d0, -+ 0xf1050040, -+ 0xf00b0057, -+ 0x45d00153, -+ 0x4057f100, -+ 0x0154b640, -+ 0x808053f1, -+ 0xf14045d0, -+ 0xf1111057, -+ 0xd0131253, -+ 0x57f18045, -+ 0x53f11514, -+ 0x45d01716, -+ 0x0157f1c0, -+ 0x0153f026, -+ 0x080047f1, -+ 0xd00644b6, -+ 0x21f50045, -+ 0x47f103d1, -+ 0x44b6080c, -+ 0x02059806, -+ 0xd00045d0, -+ 0x57f04040, -+ 0x8045d004, -+ 0x040040b7, -+ 0xb6010598, -+ 0x45d01054, -+ 0x0040b700, -+ 0x0057f105, -+ 0x0045d003, -+ 0x111057f1, -+ 0x131253f1, -+ 0x984045d0, -+ 0x40b70305, -+ 0x45d00500, -+ 0x0157f100, -+ 0x0153f026, -+ 0x080047f1, -+ 0xd00644b6, -+ 0x00f80045, -+ 0x03d121f5, -+ 0xf4003fc8, -+ 0x21f50e0b, -+ 0x47f101af, -+ 0x0ef40200, -+ 0x1067f11e, -+ 0x0664b608, -+ 0x800177f0, -+ 0x07800e07, -+ 0x1d079819, -+ 0xd00067d0, -+ 0x44bd4067, -+ 0xbd0232f4, -+ 0x043fc854, -+ 0xf50a0bf4, -+ 0xf403a821, -+ 0x21f50a0e, -+ 0x49f0029c, -+ 0x0231f407, -+ 0xc82c57f0, -+ 0x0bf4083f, -+ 0xa821f50a, -+ 0x0a0ef403, -+ 0x029c21f5, -+ 0xf10849f0, -+ 0xb6080057, -+ 0x06980654, -+ 0x4056d01e, -+ 0xf14167f0, -+ 0xfd440063, -+ 0x54d00546, -+ 0x0c3fc800, -+ 0xf5070bf4, -+ 0xf803eb21, -+ 0x0027f100, -+ 0xf034bd22, -+ 0x23d00133, -+ 0x0000f800, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+}; -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nvc0_fifo.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nvc0_fifo.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nvc0_fifo.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nvc0_fifo.c 2011-05-09 00:36:22.000000000 +0200 -@@ -37,7 +37,7 @@ - }; - - struct nvc0_fifo_chan { -- struct nouveau_bo *user; -+ struct nouveau_gpuobj *user; - struct nouveau_gpuobj *ramfc; - }; - -@@ -106,7 +106,7 @@ - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nvc0_fifo_priv *priv = pfifo->priv; - struct nvc0_fifo_chan *fifoch; -- u64 ib_virt, user_vinst; -+ u64 ib_virt = chan->pushbuf_base + chan->dma.ib_base * 4; - int ret; - - chan->fifo_priv = kzalloc(sizeof(*fifoch), GFP_KERNEL); -@@ -115,28 +115,13 @@ - fifoch = chan->fifo_priv; - - /* allocate vram for control regs, map into polling area */ -- ret = nouveau_bo_new(dev, NULL, 0x1000, 0, TTM_PL_FLAG_VRAM, -- 0, 0, &fifoch->user); -+ ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 0x1000, -+ NVOBJ_FLAG_ZERO_ALLOC, &fifoch->user); - if (ret) - goto error; - -- ret = nouveau_bo_pin(fifoch->user, TTM_PL_FLAG_VRAM); -- if (ret) { -- nouveau_bo_ref(NULL, &fifoch->user); -- goto error; -- } -- -- user_vinst = fifoch->user->bo.mem.start << PAGE_SHIFT; -- -- ret = nouveau_bo_map(fifoch->user); -- if (ret) { -- nouveau_bo_unpin(fifoch->user); -- nouveau_bo_ref(NULL, &fifoch->user); -- goto error; -- } -- - nouveau_vm_map_at(&priv->user_vma, chan->id * 0x1000, -- fifoch->user->bo.mem.mm_node); -+ *(struct nouveau_mem **)fifoch->user->node); - - chan->user = ioremap_wc(pci_resource_start(dev->pdev, 1) + - priv->user_vma.offset + (chan->id * 0x1000), -@@ -146,20 +131,6 @@ - goto error; - } - -- ib_virt = chan->pushbuf_base + chan->dma.ib_base * 4; -- -- /* zero channel regs */ -- nouveau_bo_wr32(fifoch->user, 0x0040/4, 0); -- nouveau_bo_wr32(fifoch->user, 0x0044/4, 0); -- nouveau_bo_wr32(fifoch->user, 0x0048/4, 0); -- nouveau_bo_wr32(fifoch->user, 0x004c/4, 0); -- nouveau_bo_wr32(fifoch->user, 0x0050/4, 0); -- nouveau_bo_wr32(fifoch->user, 0x0058/4, 0); -- nouveau_bo_wr32(fifoch->user, 0x005c/4, 0); -- nouveau_bo_wr32(fifoch->user, 0x0060/4, 0); -- nouveau_bo_wr32(fifoch->user, 0x0088/4, 0); -- nouveau_bo_wr32(fifoch->user, 0x008c/4, 0); -- - /* ramfc */ - ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst, - chan->ramin->vinst, 0x100, -@@ -167,8 +138,8 @@ - if (ret) - goto error; - -- nv_wo32(fifoch->ramfc, 0x08, lower_32_bits(user_vinst)); -- nv_wo32(fifoch->ramfc, 0x0c, upper_32_bits(user_vinst)); -+ nv_wo32(fifoch->ramfc, 0x08, lower_32_bits(fifoch->user->vinst)); -+ nv_wo32(fifoch->ramfc, 0x0c, upper_32_bits(fifoch->user->vinst)); - nv_wo32(fifoch->ramfc, 0x10, 0x0000face); - nv_wo32(fifoch->ramfc, 0x30, 0xfffff902); - nv_wo32(fifoch->ramfc, 0x48, lower_32_bits(ib_virt)); -@@ -223,11 +194,7 @@ - return; - - nouveau_gpuobj_ref(NULL, &fifoch->ramfc); -- if (fifoch->user) { -- nouveau_bo_unmap(fifoch->user); -- nouveau_bo_unpin(fifoch->user); -- nouveau_bo_ref(NULL, &fifoch->user); -- } -+ nouveau_gpuobj_ref(NULL, &fifoch->user); - kfree(fifoch); - } - -@@ -240,6 +207,21 @@ - int - nvc0_fifo_unload_context(struct drm_device *dev) - { -+ int i; -+ -+ for (i = 0; i < 128; i++) { -+ if (!(nv_rd32(dev, 0x003004 + (i * 4)) & 1)) -+ continue; -+ -+ nv_mask(dev, 0x003004 + (i * 4), 0x00000001, 0x00000000); -+ nv_wr32(dev, 0x002634, i); -+ if (!nv_wait(dev, 0x002634, 0xffffffff, i)) { -+ NV_INFO(dev, "PFIFO: kick ch %d failed: 0x%08x\n", -+ i, nv_rd32(dev, 0x002634)); -+ return -EBUSY; -+ } -+ } -+ - return 0; - } - -@@ -309,6 +291,7 @@ - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; -+ struct nouveau_channel *chan; - struct nvc0_fifo_priv *priv; - int ret, i; - -@@ -351,23 +334,74 @@ - nv_wr32(dev, 0x002a00, 0xffffffff); /* clears PFIFO.INTR bit 30 */ - nv_wr32(dev, 0x002100, 0xffffffff); - nv_wr32(dev, 0x002140, 0xbfffffff); -+ -+ /* restore PFIFO context table */ -+ for (i = 0; i < 128; i++) { -+ chan = dev_priv->channels.ptr[i]; -+ if (!chan || !chan->fifo_priv) -+ continue; -+ -+ nv_wr32(dev, 0x003000 + (i * 8), 0xc0000000 | -+ (chan->ramin->vinst >> 12)); -+ nv_wr32(dev, 0x003004 + (i * 8), 0x001f0001); -+ } -+ nvc0_fifo_playlist_update(dev); -+ - return 0; - } - - struct nouveau_enum nvc0_fifo_fault_unit[] = { -- { 0, "PGRAPH" }, -- { 3, "PEEPHOLE" }, -- { 4, "BAR1" }, -- { 5, "BAR3" }, -- { 7, "PFIFO" }, -+ { 0x00, "PGRAPH" }, -+ { 0x03, "PEEPHOLE" }, -+ { 0x04, "BAR1" }, -+ { 0x05, "BAR3" }, -+ { 0x07, "PFIFO" }, -+ { 0x10, "PBSP" }, -+ { 0x11, "PPPP" }, -+ { 0x13, "PCOUNTER" }, -+ { 0x14, "PVP" }, -+ { 0x15, "PCOPY0" }, -+ { 0x16, "PCOPY1" }, -+ { 0x17, "PDAEMON" }, - {} - }; - - struct nouveau_enum nvc0_fifo_fault_reason[] = { -- { 0, "PT_NOT_PRESENT" }, -- { 1, "PT_TOO_SHORT" }, -- { 2, "PAGE_NOT_PRESENT" }, -- { 3, "VM_LIMIT_EXCEEDED" }, -+ { 0x00, "PT_NOT_PRESENT" }, -+ { 0x01, "PT_TOO_SHORT" }, -+ { 0x02, "PAGE_NOT_PRESENT" }, -+ { 0x03, "VM_LIMIT_EXCEEDED" }, -+ { 0x04, "NO_CHANNEL" }, -+ { 0x05, "PAGE_SYSTEM_ONLY" }, -+ { 0x06, "PAGE_READ_ONLY" }, -+ { 0x0a, "COMPRESSED_SYSRAM" }, -+ { 0x0c, "INVALID_STORAGE_TYPE" }, -+ {} -+}; -+ -+struct nouveau_enum nvc0_fifo_fault_hubclient[] = { -+ { 0x01, "PCOPY0" }, -+ { 0x02, "PCOPY1" }, -+ { 0x04, "DISPATCH" }, -+ { 0x05, "CTXCTL" }, -+ { 0x06, "PFIFO" }, -+ { 0x07, "BAR_READ" }, -+ { 0x08, "BAR_WRITE" }, -+ { 0x0b, "PVP" }, -+ { 0x0c, "PPPP" }, -+ { 0x0d, "PBSP" }, -+ { 0x11, "PCOUNTER" }, -+ { 0x12, "PDAEMON" }, -+ { 0x14, "CCACHE" }, -+ { 0x15, "CCACHE_POST" }, -+ {} -+}; -+ -+struct nouveau_enum nvc0_fifo_fault_gpcclient[] = { -+ { 0x01, "TEX" }, -+ { 0x0c, "ESETUP" }, -+ { 0x0e, "CTXCTL" }, -+ { 0x0f, "PROP" }, - {} - }; - -@@ -385,12 +419,20 @@ - u32 valo = nv_rd32(dev, 0x2804 + (unit * 0x10)); - u32 vahi = nv_rd32(dev, 0x2808 + (unit * 0x10)); - u32 stat = nv_rd32(dev, 0x280c + (unit * 0x10)); -+ u32 client = (stat & 0x00001f00) >> 8; - - NV_INFO(dev, "PFIFO: %s fault at 0x%010llx [", - (stat & 0x00000080) ? "write" : "read", (u64)vahi << 32 | valo); - nouveau_enum_print(nvc0_fifo_fault_reason, stat & 0x0000000f); - printk("] from "); - nouveau_enum_print(nvc0_fifo_fault_unit, unit); -+ if (stat & 0x00000040) { -+ printk("/"); -+ nouveau_enum_print(nvc0_fifo_fault_hubclient, client); -+ } else { -+ printk("/GPC%d/", (stat & 0x1f000000) >> 24); -+ nouveau_enum_print(nvc0_fifo_fault_gpcclient, client); -+ } - printk(" on channel 0x%010llx\n", (u64)inst << 12); - } - -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nvc0_graph.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nvc0_graph.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nvc0_graph.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nvc0_graph.c 2011-05-09 00:36:22.000000000 +0200 -@@ -30,27 +30,40 @@ - #include "nouveau_mm.h" - #include "nvc0_graph.h" - --static void nvc0_graph_isr(struct drm_device *); --static void nvc0_runk140_isr(struct drm_device *); --static int nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan); -- --void --nvc0_graph_fifo_access(struct drm_device *dev, bool enabled) -+static int -+nvc0_graph_load_context(struct nouveau_channel *chan) - { -+ struct drm_device *dev = chan->dev; -+ -+ nv_wr32(dev, 0x409840, 0x00000030); -+ nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12); -+ nv_wr32(dev, 0x409504, 0x00000003); -+ if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010)) -+ NV_ERROR(dev, "PGRAPH: load_ctx timeout\n"); -+ -+ return 0; - } - --struct nouveau_channel * --nvc0_graph_channel(struct drm_device *dev) -+static int -+nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan) - { -- return NULL; -+ nv_wr32(dev, 0x409840, 0x00000003); -+ nv_wr32(dev, 0x409500, 0x80000000 | chan >> 12); -+ nv_wr32(dev, 0x409504, 0x00000009); -+ if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000000)) { -+ NV_ERROR(dev, "PGRAPH: unload_ctx timeout\n"); -+ return -EBUSY; -+ } -+ -+ return 0; - } - - static int - nvc0_graph_construct_context(struct nouveau_channel *chan) - { - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; -- struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; -- struct nvc0_graph_chan *grch = chan->pgraph_ctx; -+ struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR); -+ struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR]; - struct drm_device *dev = chan->dev; - int ret, i; - u32 *ctx; -@@ -89,9 +102,8 @@ - static int - nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan) - { -- struct drm_nouveau_private *dev_priv = chan->dev->dev_private; -- struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; -- struct nvc0_graph_chan *grch = chan->pgraph_ctx; -+ struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR); -+ struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR]; - struct drm_device *dev = chan->dev; - int i = 0, gpc, tp, ret; - u32 magic; -@@ -158,29 +170,27 @@ - return 0; - } - --int --nvc0_graph_create_context(struct nouveau_channel *chan) -+static int -+nvc0_graph_context_new(struct nouveau_channel *chan, int engine) - { -- struct drm_nouveau_private *dev_priv = chan->dev->dev_private; -+ struct drm_device *dev = chan->dev; -+ struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; -- struct nvc0_graph_priv *priv = pgraph->priv; -+ struct nvc0_graph_priv *priv = nv_engine(dev, engine); - struct nvc0_graph_chan *grch; -- struct drm_device *dev = chan->dev; - struct nouveau_gpuobj *grctx; - int ret, i; - -- chan->pgraph_ctx = kzalloc(sizeof(*grch), GFP_KERNEL); -- if (!chan->pgraph_ctx) -+ grch = kzalloc(sizeof(*grch), GFP_KERNEL); -+ if (!grch) - return -ENOMEM; -- grch = chan->pgraph_ctx; -+ chan->engctx[NVOBJ_ENGINE_GR] = grch; - - ret = nouveau_gpuobj_new(dev, NULL, priv->grctx_size, 256, - NVOBJ_FLAG_VM | NVOBJ_FLAG_ZERO_ALLOC, - &grch->grctx); - if (ret) - goto error; -- chan->ramin_grctx = grch->grctx; - grctx = grch->grctx; - - ret = nvc0_graph_create_context_mmio_list(chan); -@@ -200,104 +210,49 @@ - for (i = 0; i < priv->grctx_size; i += 4) - nv_wo32(grctx, i, priv->grctx_vals[i / 4]); - -- nv_wo32(grctx, 0xf4, 0); -- nv_wo32(grctx, 0xf8, 0); -- nv_wo32(grctx, 0x10, grch->mmio_nr); -- nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->vinst)); -- nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->vinst)); -- nv_wo32(grctx, 0x1c, 1); -- nv_wo32(grctx, 0x20, 0); -- nv_wo32(grctx, 0x28, 0); -- nv_wo32(grctx, 0x2c, 0); -+ nv_wo32(grctx, 0xf4, 0); -+ nv_wo32(grctx, 0xf8, 0); -+ nv_wo32(grctx, 0x10, grch->mmio_nr); -+ nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->vinst)); -+ nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->vinst)); -+ nv_wo32(grctx, 0x1c, 1); -+ nv_wo32(grctx, 0x20, 0); -+ nv_wo32(grctx, 0x28, 0); -+ nv_wo32(grctx, 0x2c, 0); - pinstmem->flush(dev); - return 0; - - error: -- pgraph->destroy_context(chan); -+ priv->base.context_del(chan, engine); - return ret; - } - --void --nvc0_graph_destroy_context(struct nouveau_channel *chan) -+static void -+nvc0_graph_context_del(struct nouveau_channel *chan, int engine) - { -- struct nvc0_graph_chan *grch; -- -- grch = chan->pgraph_ctx; -- chan->pgraph_ctx = NULL; -- if (!grch) -- return; -+ struct nvc0_graph_chan *grch = chan->engctx[engine]; - - nouveau_gpuobj_ref(NULL, &grch->mmio); - nouveau_gpuobj_ref(NULL, &grch->unk418810); - nouveau_gpuobj_ref(NULL, &grch->unk40800c); - nouveau_gpuobj_ref(NULL, &grch->unk408004); - nouveau_gpuobj_ref(NULL, &grch->grctx); -- chan->ramin_grctx = NULL; -+ chan->engctx[engine] = NULL; - } - --int --nvc0_graph_load_context(struct nouveau_channel *chan) -+static int -+nvc0_graph_object_new(struct nouveau_channel *chan, int engine, -+ u32 handle, u16 class) - { -- struct drm_device *dev = chan->dev; -- -- nv_wr32(dev, 0x409840, 0x00000030); -- nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12); -- nv_wr32(dev, 0x409504, 0x00000003); -- if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010)) -- NV_ERROR(dev, "PGRAPH: load_ctx timeout\n"); -- - return 0; - } - - static int --nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan) -+nvc0_graph_fini(struct drm_device *dev, int engine) - { -- nv_wr32(dev, 0x409840, 0x00000003); -- nv_wr32(dev, 0x409500, 0x80000000 | chan >> 12); -- nv_wr32(dev, 0x409504, 0x00000009); -- if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000000)) { -- NV_ERROR(dev, "PGRAPH: unload_ctx timeout\n"); -- return -EBUSY; -- } -- - return 0; - } - --int --nvc0_graph_unload_context(struct drm_device *dev) --{ -- u64 inst = (u64)(nv_rd32(dev, 0x409b00) & 0x0fffffff) << 12; -- return nvc0_graph_unload_context_to(dev, inst); --} -- --static void --nvc0_graph_destroy(struct drm_device *dev) --{ -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; -- struct nvc0_graph_priv *priv; -- -- priv = pgraph->priv; -- if (!priv) -- return; -- -- nouveau_irq_unregister(dev, 12); -- nouveau_irq_unregister(dev, 25); -- -- nouveau_gpuobj_ref(NULL, &priv->unk4188b8); -- nouveau_gpuobj_ref(NULL, &priv->unk4188b4); -- -- if (priv->grctx_vals) -- kfree(priv->grctx_vals); -- kfree(priv); --} -- --void --nvc0_graph_takedown(struct drm_device *dev) --{ -- nvc0_graph_destroy(dev); --} -- - static int - nvc0_graph_mthd_page_flip(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -@@ -306,119 +261,10 @@ - return 0; - } - --static int --nvc0_graph_create(struct drm_device *dev) --{ -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; -- struct nvc0_graph_priv *priv; -- int ret, gpc, i; -- -- priv = kzalloc(sizeof(*priv), GFP_KERNEL); -- if (!priv) -- return -ENOMEM; -- pgraph->priv = priv; -- -- ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b4); -- if (ret) -- goto error; -- -- ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b8); -- if (ret) -- goto error; -- -- for (i = 0; i < 0x1000; i += 4) { -- nv_wo32(priv->unk4188b4, i, 0x00000010); -- nv_wo32(priv->unk4188b8, i, 0x00000010); -- } -- -- priv->gpc_nr = nv_rd32(dev, 0x409604) & 0x0000001f; -- priv->rop_nr = (nv_rd32(dev, 0x409604) & 0x001f0000) >> 16; -- for (gpc = 0; gpc < priv->gpc_nr; gpc++) { -- priv->tp_nr[gpc] = nv_rd32(dev, GPC_UNIT(gpc, 0x2608)); -- priv->tp_total += priv->tp_nr[gpc]; -- } -- -- /*XXX: these need figuring out... */ -- switch (dev_priv->chipset) { -- case 0xc0: -- if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */ -- priv->magic_not_rop_nr = 0x07; -- /* filled values up to tp_total, the rest 0 */ -- priv->magicgpc980[0] = 0x22111000; -- priv->magicgpc980[1] = 0x00000233; -- priv->magicgpc980[2] = 0x00000000; -- priv->magicgpc980[3] = 0x00000000; -- priv->magicgpc918 = 0x000ba2e9; -- } else -- if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */ -- priv->magic_not_rop_nr = 0x05; -- priv->magicgpc980[0] = 0x11110000; -- priv->magicgpc980[1] = 0x00233222; -- priv->magicgpc980[2] = 0x00000000; -- priv->magicgpc980[3] = 0x00000000; -- priv->magicgpc918 = 0x00092493; -- } else -- if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */ -- priv->magic_not_rop_nr = 0x06; -- priv->magicgpc980[0] = 0x11110000; -- priv->magicgpc980[1] = 0x03332222; -- priv->magicgpc980[2] = 0x00000000; -- priv->magicgpc980[3] = 0x00000000; -- priv->magicgpc918 = 0x00088889; -- } -- break; -- case 0xc3: /* 450, 4/0/0/0, 2 */ -- priv->magic_not_rop_nr = 0x03; -- priv->magicgpc980[0] = 0x00003210; -- priv->magicgpc980[1] = 0x00000000; -- priv->magicgpc980[2] = 0x00000000; -- priv->magicgpc980[3] = 0x00000000; -- priv->magicgpc918 = 0x00200000; -- break; -- case 0xc4: /* 460, 3/4/0/0, 4 */ -- priv->magic_not_rop_nr = 0x01; -- priv->magicgpc980[0] = 0x02321100; -- priv->magicgpc980[1] = 0x00000000; -- priv->magicgpc980[2] = 0x00000000; -- priv->magicgpc980[3] = 0x00000000; -- priv->magicgpc918 = 0x00124925; -- break; -- } -- -- if (!priv->magic_not_rop_nr) { -- NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n", -- priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2], -- priv->tp_nr[3], priv->rop_nr); -- /* use 0xc3's values... */ -- priv->magic_not_rop_nr = 0x03; -- priv->magicgpc980[0] = 0x00003210; -- priv->magicgpc980[1] = 0x00000000; -- priv->magicgpc980[2] = 0x00000000; -- priv->magicgpc980[3] = 0x00000000; -- priv->magicgpc918 = 0x00200000; -- } -- -- nouveau_irq_register(dev, 12, nvc0_graph_isr); -- nouveau_irq_register(dev, 25, nvc0_runk140_isr); -- NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */ -- NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */ -- NVOBJ_MTHD (dev, 0x9039, 0x0500, nvc0_graph_mthd_page_flip); -- NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */ -- NVOBJ_CLASS(dev, 0x90c0, GR); /* COMPUTE */ -- return 0; -- --error: -- nvc0_graph_destroy(dev); -- return ret; --} -- - static void - nvc0_graph_init_obj418880(struct drm_device *dev) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; -- struct nvc0_graph_priv *priv = pgraph->priv; -+ struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR); - int i; - - nv_wr32(dev, GPC_BCAST(0x0880), 0x00000000); -@@ -449,35 +295,42 @@ - static void - nvc0_graph_init_gpc_0(struct drm_device *dev) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; -- int gpc; -- -- // TP ROP UNKVAL(magic_not_rop_nr) -- // 450: 4/0/0/0 2 3 -- // 460: 3/4/0/0 4 1 -- // 465: 3/4/4/0 4 7 -- // 470: 3/3/4/4 5 5 -- // 480: 3/4/4/4 6 6 -- -- // magicgpc918 -- // 450: 00200000 00000000001000000000000000000000 -- // 460: 00124925 00000000000100100100100100100101 -- // 465: 000ba2e9 00000000000010111010001011101001 -- // 470: 00092493 00000000000010010010010010010011 -- // 480: 00088889 00000000000010001000100010001001 -- -- /* filled values up to tp_total, remainder 0 */ -- // 450: 00003210 00000000 00000000 00000000 -- // 460: 02321100 00000000 00000000 00000000 -- // 465: 22111000 00000233 00000000 00000000 -- // 470: 11110000 00233222 00000000 00000000 -- // 480: 11110000 03332222 00000000 00000000 -- -- nv_wr32(dev, GPC_BCAST(0x0980), priv->magicgpc980[0]); -- nv_wr32(dev, GPC_BCAST(0x0984), priv->magicgpc980[1]); -- nv_wr32(dev, GPC_BCAST(0x0988), priv->magicgpc980[2]); -- nv_wr32(dev, GPC_BCAST(0x098c), priv->magicgpc980[3]); -+ struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR); -+ u32 data[TP_MAX / 8]; -+ u8 tpnr[GPC_MAX]; -+ int i, gpc, tpc; -+ -+ /* -+ * TP ROP UNKVAL(magic_not_rop_nr) -+ * 450: 4/0/0/0 2 3 -+ * 460: 3/4/0/0 4 1 -+ * 465: 3/4/4/0 4 7 -+ * 470: 3/3/4/4 5 5 -+ * 480: 3/4/4/4 6 6 -+ * -+ * magicgpc918 -+ * 450: 00200000 00000000001000000000000000000000 -+ * 460: 00124925 00000000000100100100100100100101 -+ * 465: 000ba2e9 00000000000010111010001011101001 -+ * 470: 00092493 00000000000010010010010010010011 -+ * 480: 00088889 00000000000010001000100010001001 -+ */ -+ -+ memset(data, 0x00, sizeof(data)); -+ memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); -+ for (i = 0, gpc = -1; i < priv->tp_total; i++) { -+ do { -+ gpc = (gpc + 1) % priv->gpc_nr; -+ } while (!tpnr[gpc]); -+ tpc = priv->tp_nr[gpc] - tpnr[gpc]--; -+ -+ data[i / 8] |= tpc << ((i % 8) * 4); -+ } -+ -+ nv_wr32(dev, GPC_BCAST(0x0980), data[0]); -+ nv_wr32(dev, GPC_BCAST(0x0984), data[1]); -+ nv_wr32(dev, GPC_BCAST(0x0988), data[2]); -+ nv_wr32(dev, GPC_BCAST(0x098c), data[3]); - - for (gpc = 0; gpc < priv->gpc_nr; gpc++) { - nv_wr32(dev, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 | -@@ -509,8 +362,7 @@ - static void - nvc0_graph_init_gpc_1(struct drm_device *dev) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; -+ struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR); - int gpc, tp; - - for (gpc = 0; gpc < priv->gpc_nr; gpc++) { -@@ -535,8 +387,7 @@ - static void - nvc0_graph_init_rop(struct drm_device *dev) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; -+ struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR); - int rop; - - for (rop = 0; rop < priv->rop_nr; rop++) { -@@ -547,62 +398,36 @@ - } - } - --static int --nvc0_fuc_load_fw(struct drm_device *dev, u32 fuc_base, -- const char *code_fw, const char *data_fw) -+static void -+nvc0_graph_init_fuc(struct drm_device *dev, u32 fuc_base, -+ struct nvc0_graph_fuc *code, struct nvc0_graph_fuc *data) - { -- const struct firmware *fw; -- char name[32]; -- int ret, i; -- -- snprintf(name, sizeof(name), "nouveau/%s", data_fw); -- ret = request_firmware(&fw, name, &dev->pdev->dev); -- if (ret) { -- NV_ERROR(dev, "failed to load %s\n", data_fw); -- return ret; -- } -+ int i; - - nv_wr32(dev, fuc_base + 0x01c0, 0x01000000); -- for (i = 0; i < fw->size / 4; i++) -- nv_wr32(dev, fuc_base + 0x01c4, ((u32 *)fw->data)[i]); -- release_firmware(fw); -- -- snprintf(name, sizeof(name), "nouveau/%s", code_fw); -- ret = request_firmware(&fw, name, &dev->pdev->dev); -- if (ret) { -- NV_ERROR(dev, "failed to load %s\n", code_fw); -- return ret; -- } -+ for (i = 0; i < data->size / 4; i++) -+ nv_wr32(dev, fuc_base + 0x01c4, data->data[i]); - - nv_wr32(dev, fuc_base + 0x0180, 0x01000000); -- for (i = 0; i < fw->size / 4; i++) { -+ for (i = 0; i < code->size / 4; i++) { - if ((i & 0x3f) == 0) - nv_wr32(dev, fuc_base + 0x0188, i >> 6); -- nv_wr32(dev, fuc_base + 0x0184, ((u32 *)fw->data)[i]); -+ nv_wr32(dev, fuc_base + 0x0184, code->data[i]); - } -- release_firmware(fw); -- -- return 0; - } - - static int - nvc0_graph_init_ctxctl(struct drm_device *dev) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; -+ struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR); - u32 r000260; -- int ret; - - /* load fuc microcode */ - r000260 = nv_mask(dev, 0x000260, 0x00000001, 0x00000000); -- ret = nvc0_fuc_load_fw(dev, 0x409000, "fuc409c", "fuc409d"); -- if (ret == 0) -- ret = nvc0_fuc_load_fw(dev, 0x41a000, "fuc41ac", "fuc41ad"); -+ nvc0_graph_init_fuc(dev, 0x409000, &priv->fuc409c, &priv->fuc409d); -+ nvc0_graph_init_fuc(dev, 0x41a000, &priv->fuc41ac, &priv->fuc41ad); - nv_wr32(dev, 0x000260, r000260); - -- if (ret) -- return ret; -- - /* start both of them running */ - nv_wr32(dev, 0x409840, 0xffffffff); - nv_wr32(dev, 0x41a10c, 0x00000000); -@@ -644,41 +469,19 @@ - return 0; - } - --int --nvc0_graph_init(struct drm_device *dev) -+static int -+nvc0_graph_init(struct drm_device *dev, int engine) - { -- struct drm_nouveau_private *dev_priv = dev->dev_private; -- struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - int ret; - -- dev_priv->engine.graph.accel_blocked = true; -- -- switch (dev_priv->chipset) { -- case 0xc0: -- case 0xc3: -- case 0xc4: -- break; -- default: -- NV_ERROR(dev, "PGRAPH: unsupported chipset, please report!\n"); -- if (nouveau_noaccel != 0) -- return 0; -- break; -- } -- - nv_mask(dev, 0x000200, 0x18001000, 0x00000000); - nv_mask(dev, 0x000200, 0x18001000, 0x18001000); - -- if (!pgraph->priv) { -- ret = nvc0_graph_create(dev); -- if (ret) -- return ret; -- } -- - nvc0_graph_init_obj418880(dev); - nvc0_graph_init_regs(dev); -- //nvc0_graph_init_unitplemented_magics(dev); -+ /*nvc0_graph_init_unitplemented_magics(dev);*/ - nvc0_graph_init_gpc_0(dev); -- //nvc0_graph_init_unitplemented_c242(dev); -+ /*nvc0_graph_init_unitplemented_c242(dev);*/ - - nv_wr32(dev, 0x400500, 0x00010001); - nv_wr32(dev, 0x400100, 0xffffffff); -@@ -697,12 +500,13 @@ - nv_wr32(dev, 0x400054, 0x34ce3464); - - ret = nvc0_graph_init_ctxctl(dev); -- if (ret == 0) -- dev_priv->engine.graph.accel_blocked = false; -+ if (ret) -+ return ret; -+ - return 0; - } - --static int -+int - nvc0_graph_isr_chid(struct drm_device *dev, u64 inst) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -@@ -806,3 +610,187 @@ - units &= ~(1 << unit); - } - } -+ -+static int -+nvc0_graph_create_fw(struct drm_device *dev, const char *fwname, -+ struct nvc0_graph_fuc *fuc) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ const struct firmware *fw; -+ char f[32]; -+ int ret; -+ -+ snprintf(f, sizeof(f), "nouveau/nv%02x_%s", dev_priv->chipset, fwname); -+ ret = request_firmware(&fw, f, &dev->pdev->dev); -+ if (ret) { -+ snprintf(f, sizeof(f), "nouveau/%s", fwname); -+ ret = request_firmware(&fw, f, &dev->pdev->dev); -+ if (ret) { -+ NV_ERROR(dev, "failed to load %s\n", fwname); -+ return ret; -+ } -+ } -+ -+ fuc->size = fw->size; -+ fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL); -+ release_firmware(fw); -+ return (fuc->data != NULL) ? 0 : -ENOMEM; -+} -+ -+static void -+nvc0_graph_destroy_fw(struct nvc0_graph_fuc *fuc) -+{ -+ if (fuc->data) { -+ kfree(fuc->data); -+ fuc->data = NULL; -+ } -+} -+ -+static void -+nvc0_graph_destroy(struct drm_device *dev, int engine) -+{ -+ struct nvc0_graph_priv *priv = nv_engine(dev, engine); -+ -+ nvc0_graph_destroy_fw(&priv->fuc409c); -+ nvc0_graph_destroy_fw(&priv->fuc409d); -+ nvc0_graph_destroy_fw(&priv->fuc41ac); -+ nvc0_graph_destroy_fw(&priv->fuc41ad); -+ -+ nouveau_irq_unregister(dev, 12); -+ nouveau_irq_unregister(dev, 25); -+ -+ nouveau_gpuobj_ref(NULL, &priv->unk4188b8); -+ nouveau_gpuobj_ref(NULL, &priv->unk4188b4); -+ -+ if (priv->grctx_vals) -+ kfree(priv->grctx_vals); -+ -+ NVOBJ_ENGINE_DEL(dev, GR); -+ kfree(priv); -+} -+ -+int -+nvc0_graph_create(struct drm_device *dev) -+{ -+ struct drm_nouveau_private *dev_priv = dev->dev_private; -+ struct nvc0_graph_priv *priv; -+ int ret, gpc, i; -+ -+ switch (dev_priv->chipset) { -+ case 0xc0: -+ case 0xc3: -+ case 0xc4: -+ break; -+ default: -+ NV_ERROR(dev, "PGRAPH: unsupported chipset, please report!\n"); -+ return 0; -+ } -+ -+ priv = kzalloc(sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->base.destroy = nvc0_graph_destroy; -+ priv->base.init = nvc0_graph_init; -+ priv->base.fini = nvc0_graph_fini; -+ priv->base.context_new = nvc0_graph_context_new; -+ priv->base.context_del = nvc0_graph_context_del; -+ priv->base.object_new = nvc0_graph_object_new; -+ -+ NVOBJ_ENGINE_ADD(dev, GR, &priv->base); -+ nouveau_irq_register(dev, 12, nvc0_graph_isr); -+ nouveau_irq_register(dev, 25, nvc0_runk140_isr); -+ -+ if (nvc0_graph_create_fw(dev, "fuc409c", &priv->fuc409c) || -+ nvc0_graph_create_fw(dev, "fuc409d", &priv->fuc409d) || -+ nvc0_graph_create_fw(dev, "fuc41ac", &priv->fuc41ac) || -+ nvc0_graph_create_fw(dev, "fuc41ad", &priv->fuc41ad)) { -+ ret = 0; -+ goto error; -+ } -+ -+ -+ ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b4); -+ if (ret) -+ goto error; -+ -+ ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b8); -+ if (ret) -+ goto error; -+ -+ for (i = 0; i < 0x1000; i += 4) { -+ nv_wo32(priv->unk4188b4, i, 0x00000010); -+ nv_wo32(priv->unk4188b8, i, 0x00000010); -+ } -+ -+ priv->gpc_nr = nv_rd32(dev, 0x409604) & 0x0000001f; -+ priv->rop_nr = (nv_rd32(dev, 0x409604) & 0x001f0000) >> 16; -+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) { -+ priv->tp_nr[gpc] = nv_rd32(dev, GPC_UNIT(gpc, 0x2608)); -+ priv->tp_total += priv->tp_nr[gpc]; -+ } -+ -+ /*XXX: these need figuring out... */ -+ switch (dev_priv->chipset) { -+ case 0xc0: -+ if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */ -+ priv->magic_not_rop_nr = 0x07; -+ /* filled values up to tp_total, the rest 0 */ -+ priv->magicgpc918 = 0x000ba2e9; -+ } else -+ if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */ -+ priv->magic_not_rop_nr = 0x05; -+ priv->magicgpc918 = 0x00092493; -+ } else -+ if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */ -+ priv->magic_not_rop_nr = 0x06; -+ priv->magicgpc918 = 0x00088889; -+ } -+ break; -+ case 0xc3: /* 450, 4/0/0/0, 2 */ -+ priv->magic_not_rop_nr = 0x03; -+ priv->magicgpc918 = 0x00200000; -+ break; -+ case 0xc4: /* 460, 3/4/0/0, 4 */ -+ priv->magic_not_rop_nr = 0x01; -+ priv->magicgpc918 = 0x00124925; -+ break; -+ } -+ -+ if (!priv->magic_not_rop_nr) { -+ NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n", -+ priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2], -+ priv->tp_nr[3], priv->rop_nr); -+ /* use 0xc3's values... */ -+ priv->magic_not_rop_nr = 0x03; -+ priv->magicgpc918 = 0x00200000; -+ } -+ -+ NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */ -+ NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */ -+ NVOBJ_MTHD (dev, 0x9039, 0x0500, nvc0_graph_mthd_page_flip); -+ NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */ -+ NVOBJ_CLASS(dev, 0x90c0, GR); /* COMPUTE */ -+ return 0; -+ -+error: -+ nvc0_graph_destroy(dev, NVOBJ_ENGINE_GR); -+ return ret; -+} -+ -+MODULE_FIRMWARE("nouveau/nvc0_fuc409c"); -+MODULE_FIRMWARE("nouveau/nvc0_fuc409d"); -+MODULE_FIRMWARE("nouveau/nvc0_fuc41ac"); -+MODULE_FIRMWARE("nouveau/nvc0_fuc41ad"); -+MODULE_FIRMWARE("nouveau/nvc3_fuc409c"); -+MODULE_FIRMWARE("nouveau/nvc3_fuc409d"); -+MODULE_FIRMWARE("nouveau/nvc3_fuc41ac"); -+MODULE_FIRMWARE("nouveau/nvc3_fuc41ad"); -+MODULE_FIRMWARE("nouveau/nvc4_fuc409c"); -+MODULE_FIRMWARE("nouveau/nvc4_fuc409d"); -+MODULE_FIRMWARE("nouveau/nvc4_fuc41ac"); -+MODULE_FIRMWARE("nouveau/nvc4_fuc41ad"); -+MODULE_FIRMWARE("nouveau/fuc409c"); -+MODULE_FIRMWARE("nouveau/fuc409d"); -+MODULE_FIRMWARE("nouveau/fuc41ac"); -+MODULE_FIRMWARE("nouveau/fuc41ad"); -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nvc0_graph.h linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nvc0_graph.h ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nvc0_graph.h 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nvc0_graph.h 2011-05-09 00:36:22.000000000 +0200 -@@ -28,13 +28,25 @@ - #define GPC_MAX 4 - #define TP_MAX 32 - --#define ROP_BCAST(r) (0x408800 + (r)) --#define ROP_UNIT(u,r) (0x410000 + (u) * 0x400 + (r)) --#define GPC_BCAST(r) (0x418000 + (r)) --#define GPC_UNIT(t,r) (0x500000 + (t) * 0x8000 + (r)) --#define TP_UNIT(t,m,r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r)) -+#define ROP_BCAST(r) (0x408800 + (r)) -+#define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r)) -+#define GPC_BCAST(r) (0x418000 + (r)) -+#define GPC_UNIT(t, r) (0x500000 + (t) * 0x8000 + (r)) -+#define TP_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r)) -+ -+struct nvc0_graph_fuc { -+ u32 *data; -+ u32 size; -+}; - - struct nvc0_graph_priv { -+ struct nouveau_exec_engine base; -+ -+ struct nvc0_graph_fuc fuc409c; -+ struct nvc0_graph_fuc fuc409d; -+ struct nvc0_graph_fuc fuc41ac; -+ struct nvc0_graph_fuc fuc41ad; -+ - u8 gpc_nr; - u8 rop_nr; - u8 tp_nr[GPC_MAX]; -@@ -46,15 +58,14 @@ - struct nouveau_gpuobj *unk4188b8; - - u8 magic_not_rop_nr; -- u32 magicgpc980[4]; - u32 magicgpc918; - }; - - struct nvc0_graph_chan { - struct nouveau_gpuobj *grctx; -- struct nouveau_gpuobj *unk408004; // 0x418810 too -- struct nouveau_gpuobj *unk40800c; // 0x419004 too -- struct nouveau_gpuobj *unk418810; // 0x419848 too -+ struct nouveau_gpuobj *unk408004; /* 0x418810 too */ -+ struct nouveau_gpuobj *unk40800c; /* 0x419004 too */ -+ struct nouveau_gpuobj *unk418810; /* 0x419848 too */ - struct nouveau_gpuobj *mmio; - int mmio_nr; - }; -diff -Naur linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nvc0_grctx.c linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nvc0_grctx.c ---- linux-2.6.39-rc6/drivers/gpu/drm/nouveau/nvc0_grctx.c 2011-05-04 04:59:13.000000000 +0200 -+++ linux-2.6.39-rc6.nouveau/drivers/gpu/drm/nouveau/nvc0_grctx.c 2011-05-09 00:36:22.000000000 +0200 -@@ -1623,7 +1623,7 @@ - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - -- // ROPC_BROADCAST -+ /* ROPC_BROADCAST */ - nv_wr32(dev, 0x408800, 0x02802a3c); - nv_wr32(dev, 0x408804, 0x00000040); - nv_wr32(dev, 0x408808, 0x0003e00d); -@@ -1647,7 +1647,7 @@ - { - int i; - -- // GPC_BROADCAST -+ /* GPC_BROADCAST */ - nv_wr32(dev, 0x418380, 0x00000016); - nv_wr32(dev, 0x418400, 0x38004e00); - nv_wr32(dev, 0x418404, 0x71e0ffff); -@@ -1728,7 +1728,7 @@ - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - -- // GPC_BROADCAST.TP_BROADCAST -+ /* GPC_BROADCAST.TP_BROADCAST */ - nv_wr32(dev, 0x419848, 0x00000000); - nv_wr32(dev, 0x419864, 0x0000012a); - nv_wr32(dev, 0x419888, 0x00000000); -@@ -1741,7 +1741,7 @@ - nv_wr32(dev, 0x419a1c, 0x00000000); - nv_wr32(dev, 0x419a20, 0x00000800); - if (dev_priv->chipset != 0xc0) -- nv_wr32(dev, 0x00419ac4, 0x0007f440); // 0xc3 -+ nv_wr32(dev, 0x00419ac4, 0x0007f440); /* 0xc3 */ - nv_wr32(dev, 0x419b00, 0x0a418820); - nv_wr32(dev, 0x419b04, 0x062080e6); - nv_wr32(dev, 0x419b08, 0x020398a4); -@@ -1797,8 +1797,8 @@ - nvc0_grctx_generate(struct nouveau_channel *chan) - { - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; -- struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; -- struct nvc0_graph_chan *grch = chan->pgraph_ctx; -+ struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR); -+ struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR]; - struct drm_device *dev = chan->dev; - int i, gpc, tp, id; - u32 r000260, tmp; -@@ -1912,13 +1912,13 @@ - for (i = 1; i < 7; i++) - data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5); - -- // GPC_BROADCAST -+ /* GPC_BROADCAST */ - nv_wr32(dev, 0x418bb8, (priv->tp_total << 8) | - priv->magic_not_rop_nr); - for (i = 0; i < 6; i++) - nv_wr32(dev, 0x418b08 + (i * 4), data[i]); - -- // GPC_BROADCAST.TP_BROADCAST -+ /* GPC_BROADCAST.TP_BROADCAST */ - nv_wr32(dev, 0x419bd0, (priv->tp_total << 8) | - priv->magic_not_rop_nr | - data2[0]); -@@ -1926,7 +1926,7 @@ - for (i = 0; i < 6; i++) - nv_wr32(dev, 0x419b00 + (i * 4), data[i]); - -- // UNK78xx -+ /* UNK78xx */ - nv_wr32(dev, 0x4078bc, (priv->tp_total << 8) | - priv->magic_not_rop_nr); - for (i = 0; i < 6; i++) -@@ -1944,7 +1944,7 @@ - gpc = -1; - for (i = 0, gpc = -1; i < 32; i++) { - int ltp = i * (priv->tp_total - 1) / 32; -- -+ - do { - gpc = (gpc + 1) % priv->gpc_nr; - } while (!tpnr[gpc]); diff --git a/packages/linux/patches/linux-2.6.39-rc6-000_crosscompile.patch b/packages/linux/patches/linux-2.6.39-rc7-000_crosscompile.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-000_crosscompile.patch rename to packages/linux/patches/linux-2.6.39-rc7-000_crosscompile.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-002_bash_only_feature.patch b/packages/linux/patches/linux-2.6.39-rc7-002_bash_only_feature.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-002_bash_only_feature.patch rename to packages/linux/patches/linux-2.6.39-rc7-002_bash_only_feature.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-003-no_dev_console.patch b/packages/linux/patches/linux-2.6.39-rc7-003-no_dev_console.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-003-no_dev_console.patch rename to packages/linux/patches/linux-2.6.39-rc7-003-no_dev_console.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-004_lower_undefined_mode_timeout.patch b/packages/linux/patches/linux-2.6.39-rc7-004_lower_undefined_mode_timeout.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-004_lower_undefined_mode_timeout.patch rename to packages/linux/patches/linux-2.6.39-rc7-004_lower_undefined_mode_timeout.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-005_kconfig_no_timestamp.patch b/packages/linux/patches/linux-2.6.39-rc7-005_kconfig_no_timestamp.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-005_kconfig_no_timestamp.patch rename to packages/linux/patches/linux-2.6.39-rc7-005_kconfig_no_timestamp.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-006_enable_utf8.patch b/packages/linux/patches/linux-2.6.39-rc7-006_enable_utf8.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-006_enable_utf8.patch rename to packages/linux/patches/linux-2.6.39-rc7-006_enable_utf8.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-007_die_floppy_die.patch b/packages/linux/patches/linux-2.6.39-rc7-007_die_floppy_die.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-007_die_floppy_die.patch rename to packages/linux/patches/linux-2.6.39-rc7-007_die_floppy_die.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-008-hda_intel_prealloc_4mb_dmabuffer.patch b/packages/linux/patches/linux-2.6.39-rc7-008-hda_intel_prealloc_4mb_dmabuffer.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-008-hda_intel_prealloc_4mb_dmabuffer.patch rename to packages/linux/patches/linux-2.6.39-rc7-008-hda_intel_prealloc_4mb_dmabuffer.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-009_disable_i8042_check_on_apple_mac.patch b/packages/linux/patches/linux-2.6.39-rc7-009_disable_i8042_check_on_apple_mac.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-009_disable_i8042_check_on_apple_mac.patch rename to packages/linux/patches/linux-2.6.39-rc7-009_disable_i8042_check_on_apple_mac.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-041-add_rtl8192se_driver-0.2.patch b/packages/linux/patches/linux-2.6.39-rc7-041-add_rtl8192se_driver-0.2.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-041-add_rtl8192se_driver-0.2.patch rename to packages/linux/patches/linux-2.6.39-rc7-041-add_rtl8192se_driver-0.2.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-050_add_appleir_usb_driver.patch b/packages/linux/patches/linux-2.6.39-rc7-050_add_appleir_usb_driver.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-050_add_appleir_usb_driver.patch rename to packages/linux/patches/linux-2.6.39-rc7-050_add_appleir_usb_driver.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-052-aureal_remote_quirk-0.1.patch b/packages/linux/patches/linux-2.6.39-rc7-052-aureal_remote_quirk-0.1.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-052-aureal_remote_quirk-0.1.patch rename to packages/linux/patches/linux-2.6.39-rc7-052-aureal_remote_quirk-0.1.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-053_ati-remote_all_keys_and_keychange-0.1.patch b/packages/linux/patches/linux-2.6.39-rc7-053_ati-remote_all_keys_and_keychange-0.1.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-053_ati-remote_all_keys_and_keychange-0.1.patch rename to packages/linux/patches/linux-2.6.39-rc7-053_ati-remote_all_keys_and_keychange-0.1.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-054_nuvoton-cir-only-warn-about-unknown-chips.patch b/packages/linux/patches/linux-2.6.39-rc7-054_nuvoton-cir-only-warn-about-unknown-chips.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-054_nuvoton-cir-only-warn-about-unknown-chips.patch rename to packages/linux/patches/linux-2.6.39-rc7-054_nuvoton-cir-only-warn-about-unknown-chips.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-055_nuvoton-cir-enable-CIR-on-w83667hg-chip-variant.patch b/packages/linux/patches/linux-2.6.39-rc7-055_nuvoton-cir-enable-CIR-on-w83667hg-chip-variant.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-055_nuvoton-cir-enable-CIR-on-w83667hg-chip-variant.patch rename to packages/linux/patches/linux-2.6.39-rc7-055_nuvoton-cir-enable-CIR-on-w83667hg-chip-variant.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-057_ite-resume-debug-0.1.patch b/packages/linux/patches/linux-2.6.39-rc7-057_ite-resume-debug-0.1.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-057_ite-resume-debug-0.1.patch rename to packages/linux/patches/linux-2.6.39-rc7-057_ite-resume-debug-0.1.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-057_media-ite-cir-make-IR-receive-work-after-resume.patch b/packages/linux/patches/linux-2.6.39-rc7-057_media-ite-cir-make-IR-receive-work-after-resume.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-057_media-ite-cir-make-IR-receive-work-after-resume.patch rename to packages/linux/patches/linux-2.6.39-rc7-057_media-ite-cir-make-IR-receive-work-after-resume.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-062-Pioneer_DVR-216D_failed_xfermode-0.1.patch b/packages/linux/patches/linux-2.6.39-rc7-062-Pioneer_DVR-216D_failed_xfermode-0.1.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-062-Pioneer_DVR-216D_failed_xfermode-0.1.patch rename to packages/linux/patches/linux-2.6.39-rc7-062-Pioneer_DVR-216D_failed_xfermode-0.1.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-071-silence_i915_agp-module-0.1.patch b/packages/linux/patches/linux-2.6.39-rc7-071-silence_i915_agp-module-0.1.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-071-silence_i915_agp-module-0.1.patch rename to packages/linux/patches/linux-2.6.39-rc7-071-silence_i915_agp-module-0.1.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-322-omap4_pandaboard_fix_dvi_support-0.1.patch b/packages/linux/patches/linux-2.6.39-rc7-322-omap4_pandaboard_fix_dvi_support-0.1.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-322-omap4_pandaboard_fix_dvi_support-0.1.patch rename to packages/linux/patches/linux-2.6.39-rc7-322-omap4_pandaboard_fix_dvi_support-0.1.patch diff --git a/packages/linux/patches/linux-2.6.39-rc6-716_mm-zero_swappiness.patch b/packages/linux/patches/linux-2.6.39-rc7-716_mm-zero_swappiness.patch similarity index 100% rename from packages/linux/patches/linux-2.6.39-rc6-716_mm-zero_swappiness.patch rename to packages/linux/patches/linux-2.6.39-rc7-716_mm-zero_swappiness.patch