diff options
author | Alexandre Oliva <lxoliva@fsfla.org> | 2011-05-28 02:47:00 +0000 |
---|---|---|
committer | Alexandre Oliva <lxoliva@fsfla.org> | 2011-05-28 02:47:00 +0000 |
commit | f59025a5537482345d50258c40596b9ddad5f32a (patch) | |
tree | 58d2e2a4b48f355bf0192b6037a352cccaa84370 /freed-ora/current/f15 | |
parent | 32f5a0305b0da635fd4d518c22deb9f0e1b20a1e (diff) | |
download | linux-libre-raptor-f59025a5537482345d50258c40596b9ddad5f32a.tar.gz linux-libre-raptor-f59025a5537482345d50258c40596b9ddad5f32a.zip |
2.6.38.7-30.fc15
Diffstat (limited to 'freed-ora/current/f15')
10 files changed, 3073 insertions, 246 deletions
diff --git a/freed-ora/current/f15/acpi_reboot.patch b/freed-ora/current/f15/acpi_reboot.patch index a980b31f7..82bffaa64 100644 --- a/freed-ora/current/f15/acpi_reboot.patch +++ b/freed-ora/current/f15/acpi_reboot.patch @@ -1,4 +1,8 @@ -Improve our reboot handling for compatibility with Windows. Upstream in .38? +Improve our reboot handling for compatibility with Windows. + +Upstream commits: +660e34cebf0a11d54f2d5dd8838607452355f321 +f17d9cbf20c4734c4199caa6dee87047f2f8278f diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index c495aa8..c770e66 100644 diff --git a/freed-ora/current/f15/bluetooth-device-ids-for-ath3k-on-pegatron-lucid-tablets.patch b/freed-ora/current/f15/bluetooth-device-ids-for-ath3k-on-pegatron-lucid-tablets.patch new file mode 100644 index 000000000..767105587 --- /dev/null +++ b/freed-ora/current/f15/bluetooth-device-ids-for-ath3k-on-pegatron-lucid-tablets.patch @@ -0,0 +1,37 @@ +From: Andy Ross <andy.ross@windriver.com> +Date: Mon, 9 May 2011 23:11:16 +0000 (-0700) +Subject: Bluetooth: Device ids for ath3k on Pegatron Lucid tablets +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fpadovan%2Fbluetooth-next-2.6.git;a=commitdiff_plain;h=2a7bccccdb9604a717c2128a931f022267d35629 + +Bluetooth: Device ids for ath3k on Pegatron Lucid tablets + +New ath3k device IDs used on the Pegatron Lucid (ExoPC and WeTab) units. + +Signed-off-by: Andy Ross <andy.ross@windriver.com> +Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi> +--- + +diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c +index 695d441..6bacef3 100644 +--- a/drivers/bluetooth/ath3k.c ++++ b/drivers/bluetooth/ath3k.c +@@ -62,6 +62,7 @@ static struct usb_device_id ath3k_table[] = { + + /* Atheros AR3011 with sflash firmware*/ + { USB_DEVICE(0x0CF3, 0x3002) }, ++ { USB_DEVICE(0x13d3, 0x3304) }, + + /* Atheros AR9285 Malbec with sflash firmware */ + { USB_DEVICE(0x03F0, 0x311D) }, +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 762a510..c2de895 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -104,6 +104,7 @@ static struct usb_device_id blacklist_table[] = { + + /* Atheros 3011 with sflash firmware */ + { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, ++ { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, + + /* Atheros AR9285 Malbec with sflash firmware */ + { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, diff --git a/freed-ora/current/f15/drm-nouveau-fixes.patch b/freed-ora/current/f15/drm-nouveau-fixes.patch index d74feb7d2..8b1378917 100644 --- a/freed-ora/current/f15/drm-nouveau-fixes.patch +++ b/freed-ora/current/f15/drm-nouveau-fixes.patch @@ -1,168 +1 @@ -diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h -index 982d70b..c01e43f 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_drv.h -+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h -@@ -681,6 +681,9 @@ struct drm_nouveau_private { - /* For PFIFO and PGRAPH. */ - spinlock_t context_switch_lock; -+ /* VM/PRAMIN flush, legacy PRAMIN aperture */ -+ spinlock_t vm_lock; -+ - /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ - struct nouveau_ramht *ramht; - struct nouveau_gpuobj *ramfc; -diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c -index 30b6544..2002a43 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_object.c -+++ b/drivers/gpu/drm/nouveau/nouveau_object.c -@@ -1013,19 +1013,20 @@ nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset) - { - struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; - struct drm_device *dev = gpuobj->dev; -+ unsigned long flags; - - if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { - u64 ptr = gpuobj->vinst + offset; - u32 base = ptr >> 16; - u32 val; - -- spin_lock(&dev_priv->ramin_lock); -+ spin_lock_irqsave(&dev_priv->vm_lock, flags); - if (dev_priv->ramin_base != base) { - dev_priv->ramin_base = base; - nv_wr32(dev, 0x001700, dev_priv->ramin_base); - } - val = nv_rd32(dev, 0x700000 + (ptr & 0xffff)); -- spin_unlock(&dev_priv->ramin_lock); -+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - return val; - } - -@@ -1037,18 +1038,19 @@ nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val) - { - struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; - struct drm_device *dev = gpuobj->dev; -+ unsigned long flags; - - if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { - u64 ptr = gpuobj->vinst + offset; - u32 base = ptr >> 16; - -- spin_lock(&dev_priv->ramin_lock); -+ spin_lock_irqsave(&dev_priv->vm_lock, flags); - if (dev_priv->ramin_base != base) { - dev_priv->ramin_base = base; - nv_wr32(dev, 0x001700, dev_priv->ramin_base); - } - nv_wr32(dev, 0x700000 + (ptr & 0xffff), val); -- spin_unlock(&dev_priv->ramin_lock); -+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - return; - } - -diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c -index a54fc43..a358dc5 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_state.c -+++ b/drivers/gpu/drm/nouveau/nouveau_state.c -@@ -646,6 +646,7 @@ nouveau_card_init(struct drm_device *dev) - spin_lock_init(&dev_priv->channels.lock); - spin_lock_init(&dev_priv->tile.lock); - spin_lock_init(&dev_priv->context_switch_lock); -+ spin_lock_init(&dev_priv->vm_lock); - - /* Make the CRTCs and I2C buses accessible */ - ret = engine->display.early_init(dev); -diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c -index e57caa2..53a4b40 100644 ---- a/drivers/gpu/drm/nouveau/nv50_instmem.c -+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c -@@ -404,23 +404,25 @@ void - nv50_instmem_flush(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ unsigned long flags; - -- spin_lock(&dev_priv->ramin_lock); -+ spin_lock_irqsave(&dev_priv->vm_lock, flags); - nv_wr32(dev, 0x00330c, 0x00000001); - if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) - NV_ERROR(dev, "PRAMIN flush timeout\n"); -- spin_unlock(&dev_priv->ramin_lock); -+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - } - - void - nv84_instmem_flush(struct drm_device *dev) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ unsigned long flags; - -- spin_lock(&dev_priv->ramin_lock); -+ spin_lock_irqsave(&dev_priv->vm_lock, flags); - nv_wr32(dev, 0x070000, 0x00000001); - if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) - NV_ERROR(dev, "PRAMIN flush timeout\n"); -- spin_unlock(&dev_priv->ramin_lock); -+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - } - -diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c -index 6144156..248496f 100644 ---- a/drivers/gpu/drm/nouveau/nv50_vm.c -+++ b/drivers/gpu/drm/nouveau/nv50_vm.c -@@ -170,10 +170,11 @@ void - nv50_vm_flush_engine(struct drm_device *dev, int engine) - { - struct drm_nouveau_private *dev_priv = dev->dev_private; -+ unsigned long flags; - -- spin_lock(&dev_priv->ramin_lock); -+ spin_lock_irqsave(&dev_priv->vm_lock, flags); - nv_wr32(dev, 0x100c80, (engine << 16) | 1); - if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) - NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); -- spin_unlock(&dev_priv->ramin_lock); -+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - } -diff --git a/drivers/gpu/drm/nouveau/nvc0_vm.c b/drivers/gpu/drm/nouveau/nvc0_vm.c -index e4e83c2..10a5a99 100644 ---- a/drivers/gpu/drm/nouveau/nvc0_vm.c -+++ b/drivers/gpu/drm/nouveau/nvc0_vm.c -@@ -104,20 +104,27 @@ nvc0_vm_flush(struct nouveau_vm *vm) - struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; - struct drm_device *dev = vm->dev; - struct nouveau_vm_pgd *vpgd; -- u32 r100c80, engine; -+ unsigned long flags; -+ u32 engine = (dev_priv->chan_vm == vm) ? 1 : 5; - - pinstmem->flush(vm->dev); - -- if (vm == dev_priv->chan_vm) -- engine = 1; -- else -- engine = 5; -- -+ spin_lock_irqsave(&dev_priv->vm_lock, flags); - list_for_each_entry(vpgd, &vm->pgd_list, head) { -- r100c80 = nv_rd32(dev, 0x100c80); -+ /* looks like maybe a "free flush slots" counter, the -+ * faster you write to 0x100cbc to more it decreases -+ */ -+ if (!nv_wait_ne(dev, 0x100c80, 0x00ff0000, 0x00000000)) { -+ NV_ERROR(dev, "vm timeout 0: 0x%08x %d\n", -+ nv_rd32(dev, 0x100c80), engine); -+ } - nv_wr32(dev, 0x100cb8, vpgd->obj->vinst >> 8); - nv_wr32(dev, 0x100cbc, 0x80000000 | engine); -- if (!nv_wait(dev, 0x100c80, 0xffffffff, r100c80)) -- NV_ERROR(dev, "vm flush timeout eng %d\n", engine); -+ /* wait for flush to be queued? */ -+ if (!nv_wait(dev, 0x100c80, 0x00008000, 0x00008000)) { -+ NV_ERROR(dev, "vm timeout 1: 0x%08x %d\n", -+ nv_rd32(dev, 0x100c80), engine); -+ } - } -+ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - } diff --git a/freed-ora/current/f15/drm-nouveau-updates.patch b/freed-ora/current/f15/drm-nouveau-updates.patch index 60f8d4d64..7a703e897 100644 --- a/freed-ora/current/f15/drm-nouveau-updates.patch +++ b/freed-ora/current/f15/drm-nouveau-updates.patch @@ -1,5 +1,5 @@ diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c -index 6bdab89..90aef64 100644 +index 6bdab89..729d5fd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -269,7 +269,7 @@ struct init_tbl_entry { @@ -102,7 +102,20 @@ index 6bdab89..90aef64 100644 } #ifdef __powerpc__ /* Powerbook specific quirks */ -@@ -5950,6 +5971,11 @@ apply_dcb_connector_quirks(struct nvbios *bios, int idx) +@@ -5028,11 +5049,7 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims + 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; + } + + /* +@@ -5950,6 +5967,11 @@ apply_dcb_connector_quirks(struct nvbios *bios, int idx) } } @@ -114,7 +127,7 @@ index 6bdab89..90aef64 100644 static void parse_dcb_connector_table(struct nvbios *bios) { -@@ -5986,23 +6012,9 @@ parse_dcb_connector_table(struct nvbios *bios) +@@ -5986,23 +6008,9 @@ parse_dcb_connector_table(struct nvbios *bios) cte->type = (cte->entry & 0x000000ff) >> 0; cte->index2 = (cte->entry & 0x00000f00) >> 8; @@ -141,7 +154,15 @@ index 6bdab89..90aef64 100644 if (cte->type == 0xff) continue; -@@ -6342,6 +6354,32 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) +@@ -6023,6 +6031,7 @@ parse_dcb_connector_table(struct nvbios *bios) + 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: +@@ -6342,6 +6351,32 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) } } @@ -174,7 +195,7 @@ index 6bdab89..90aef64 100644 return true; } -@@ -6702,11 +6740,11 @@ nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table, +@@ -6702,11 +6737,11 @@ nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table, struct nvbios *bios = &dev_priv->vbios; struct init_exec iexec = { true, false }; @@ -188,7 +209,7 @@ index 6bdab89..90aef64 100644 } static bool NVInitVBIOS(struct drm_device *dev) -@@ -6715,7 +6753,7 @@ static bool NVInitVBIOS(struct drm_device *dev) +@@ -6715,7 +6750,7 @@ static bool NVInitVBIOS(struct drm_device *dev) struct nvbios *bios = &dev_priv->vbios; memset(bios, 0, sizeof(struct nvbios)); @@ -198,10 +219,18 @@ index 6bdab89..90aef64 100644 if (!NVShadowVBIOS(dev, bios->data)) diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h -index 50a648e..8a54fa7 100644 +index 50a648e..050c314 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h -@@ -251,7 +251,7 @@ struct nvbios { +@@ -82,6 +82,7 @@ enum dcb_connector_type { + 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, +@@ -251,7 +252,7 @@ struct nvbios { uint8_t digital_min_front_porch; bool fp_no_ddc; @@ -716,6 +745,53 @@ index 3960d66..3837090 100644 if (ret) { NV_ERROR(dev, "error allocating DMA push buffer: %d\n", ret); return NULL; +diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c +index 390d82c..084c089 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_connector.c ++++ b/drivers/gpu/drm/nouveau/nouveau_connector.c +@@ -438,7 +438,7 @@ nouveau_connector_set_property(struct drm_connector *connector, + } + + /* 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; + +@@ -646,6 +646,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) + 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); + +@@ -806,6 +807,7 @@ nouveau_connector_create(struct drm_device *dev, int index) + 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; +@@ -834,7 +836,7 @@ nouveau_connector_create(struct drm_device *dev, int index) + 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); +@@ -879,7 +881,7 @@ nouveau_connector_create(struct drm_device *dev, int index) + 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 --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 505c6bf..764c15d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c @@ -852,9 +928,18 @@ index 505c6bf..764c15d 100644 spin_unlock_irqrestore(&dev->event_lock, flags); diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c -index b368ed7..ce38e97 100644 +index b368ed7..568caed 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c +@@ -83,7 +83,7 @@ nouveau_dma_init(struct nouveau_channel *chan) + return ret; + + /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ +- ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfd0, 0x1000, ++ ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000, + &chan->m2mf_ntfy); + if (ret) + return ret; @@ -97,13 +97,15 @@ nouveau_dma_init(struct nouveau_channel *chan) OUT_RING(chan, 0); @@ -926,7 +1011,7 @@ index 38d5995..7beb82a 100644 ret = auxch_rd(encoder, DP_ADJUST_REQUEST_LANE0_1, request, 2); if (ret) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h -index 982d70b..e172d72 100644 +index 982d70b..b260c55 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -57,7 +57,7 @@ struct nouveau_fpriv { @@ -981,7 +1066,15 @@ index 982d70b..e172d72 100644 int (*early_init)(struct drm_device *); void (*late_takedown)(struct drm_device *); int (*create)(struct drm_device *); -@@ -463,6 +466,7 @@ struct nouveau_pm_memtiming { +@@ -433,6 +436,7 @@ struct nouveau_pm_level { + u32 memory; + u32 shader; + u32 unk05; ++ u32 unk0a; + + u8 voltage; + u8 fanspeed; +@@ -463,6 +467,7 @@ struct nouveau_pm_memtiming { u32 reg_100234; u32 reg_100238; u32 reg_10023c; @@ -989,7 +1082,7 @@ index 982d70b..e172d72 100644 }; struct nouveau_pm_memtimings { -@@ -509,8 +513,8 @@ struct nouveau_crypt_engine { +@@ -509,8 +514,8 @@ struct nouveau_crypt_engine { struct nouveau_vram_engine { int (*init)(struct drm_device *); int (*get)(struct drm_device *, u64, u32 align, u32 size_nc, @@ -1000,7 +1093,7 @@ index 982d70b..e172d72 100644 bool (*flags_valid)(struct drm_device *, u32 tile_flags); }; -@@ -634,6 +638,7 @@ struct drm_nouveau_private { +@@ -634,6 +639,7 @@ struct drm_nouveau_private { enum nouveau_card_type card_type; /* exact chipset, derived from NV_PMC_BOOT_0 */ int chipset; @@ -1008,7 +1101,7 @@ index 982d70b..e172d72 100644 int flags; void __iomem *mmio; -@@ -652,8 +657,6 @@ struct drm_nouveau_private { +@@ -652,8 +658,6 @@ struct drm_nouveau_private { /* interrupt handling */ void (*irq_handler[32])(struct drm_device *); bool msi_enabled; @@ -1017,7 +1110,17 @@ index 982d70b..e172d72 100644 struct list_head vbl_waiting; -@@ -691,15 +694,22 @@ struct drm_nouveau_private { +@@ -681,6 +685,9 @@ struct drm_nouveau_private { + /* For PFIFO and PGRAPH. */ + spinlock_t context_switch_lock; + ++ /* VM/PRAMIN flush, legacy PRAMIN aperture */ ++ spinlock_t vm_lock; ++ + /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ + struct nouveau_ramht *ramht; + struct nouveau_gpuobj *ramfc; +@@ -691,15 +698,22 @@ struct drm_nouveau_private { struct { enum { NOUVEAU_GART_NONE = 0, @@ -1043,7 +1146,7 @@ index 982d70b..e172d72 100644 } gart_info; /* nv10-nv40 tiling regions */ -@@ -740,14 +750,6 @@ struct drm_nouveau_private { +@@ -740,14 +754,6 @@ struct drm_nouveau_private { struct backlight_device *backlight; @@ -1058,7 +1161,7 @@ index 982d70b..e172d72 100644 struct { struct dentry *channel_root; } debugfs; -@@ -847,6 +849,7 @@ extern void nv10_mem_put_tile_region(struct drm_device *dev, +@@ -847,6 +853,7 @@ extern void nv10_mem_put_tile_region(struct drm_device *dev, struct nouveau_tile_reg *tile, struct nouveau_fence *fence); extern const struct ttm_mem_type_manager_func nouveau_vram_manager; @@ -1066,7 +1169,7 @@ index 982d70b..e172d72 100644 /* nouveau_notifier.c */ extern int nouveau_notifier_init_channel(struct nouveau_channel *); -@@ -879,17 +882,17 @@ extern void nouveau_channel_ref(struct nouveau_channel *chan, +@@ -879,17 +886,17 @@ extern void nouveau_channel_ref(struct nouveau_channel *chan, extern void nouveau_channel_idle(struct nouveau_channel *chan); /* nouveau_object.c */ @@ -1088,7 +1191,7 @@ index 982d70b..e172d72 100644 extern int nouveau_gpuobj_early_init(struct drm_device *); extern int nouveau_gpuobj_init(struct drm_device *); -@@ -899,7 +902,7 @@ extern void nouveau_gpuobj_resume(struct drm_device *dev); +@@ -899,7 +906,7 @@ extern void nouveau_gpuobj_resume(struct drm_device *dev); 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 *, @@ -1097,7 +1200,7 @@ index 982d70b..e172d72 100644 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 *, -@@ -1076,7 +1079,7 @@ extern void nv40_fb_set_tile_region(struct drm_device *dev, int i); +@@ -1076,7 +1083,7 @@ extern void nv40_fb_set_tile_region(struct drm_device *dev, int i); /* nv50_fb.c */ extern int nv50_fb_init(struct drm_device *); extern void nv50_fb_takedown(struct drm_device *); @@ -1106,7 +1209,7 @@ index 982d70b..e172d72 100644 /* nvc0_fb.c */ extern int nvc0_fb_init(struct drm_device *); -@@ -1189,7 +1192,7 @@ extern int nv50_graph_load_context(struct nouveau_channel *); +@@ -1189,7 +1196,7 @@ extern int nv50_graph_load_context(struct nouveau_channel *); extern int nv50_graph_unload_context(struct drm_device *); extern int nv50_grctx_init(struct nouveau_grctx *); extern void nv50_graph_tlb_flush(struct drm_device *dev); @@ -1115,7 +1218,7 @@ index 982d70b..e172d72 100644 extern struct nouveau_enum nv50_data_error_names[]; /* nvc0_graph.c */ -@@ -1295,7 +1298,7 @@ extern struct ttm_bo_driver nouveau_bo_driver; +@@ -1295,7 +1302,7 @@ extern struct ttm_bo_driver nouveau_bo_driver; extern int nouveau_bo_new(struct drm_device *, struct nouveau_channel *, int size, int align, uint32_t flags, uint32_t tile_mode, uint32_t tile_flags, @@ -1124,7 +1227,7 @@ index 982d70b..e172d72 100644 extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags); extern int nouveau_bo_unpin(struct nouveau_bo *); extern int nouveau_bo_map(struct nouveau_bo *); -@@ -1356,9 +1359,9 @@ static inline struct nouveau_fence *nouveau_fence_ref(struct nouveau_fence *obj) +@@ -1356,9 +1363,9 @@ static inline struct nouveau_fence *nouveau_fence_ref(struct nouveau_fence *obj) /* nouveau_gem.c */ extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *, @@ -1136,6 +1239,17 @@ index 982d70b..e172d72 100644 extern int nouveau_gem_object_new(struct drm_gem_object *); extern void nouveau_gem_object_del(struct drm_gem_object *); extern int nouveau_gem_ioctl_new(struct drm_device *, void *, +@@ -1398,8 +1405,8 @@ bool nv50_gpio_irq_enable(struct drm_device *, enum dcb_gpio_tag, bool on); + /* 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 diff --git a/drivers/gpu/drm/nouveau/nouveau_fb.h b/drivers/gpu/drm/nouveau/nouveau_fb.h index d432134..a3a88ad 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fb.h @@ -1151,7 +1265,7 @@ index d432134..a3a88ad 100644 static inline struct nouveau_framebuffer * diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c -index 60769d2..889c445 100644 +index 7826be0..39aee6d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -296,8 +296,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, @@ -1679,19 +1793,41 @@ index 4a8ad13..86c2e37 100644 static inline void cp_pos(struct nouveau_grctx *ctx, int offset) +diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c +index 053edf9..ba896e5 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_hw.c ++++ b/drivers/gpu/drm/nouveau/nouveau_hw.c +@@ -900,6 +900,7 @@ nv_save_state_ext(struct drm_device *dev, int head, + } + /* NV11 and NV20 don't have this, they stop at 0x52. */ + if (nv_gf4_disp_arch(dev)) { ++ rd_cio_state(dev, head, regp, NV_CIO_CRE_42); + rd_cio_state(dev, head, regp, NV_CIO_CRE_53); + rd_cio_state(dev, head, regp, NV_CIO_CRE_54); + +@@ -1003,6 +1004,7 @@ nv_load_state_ext(struct drm_device *dev, int head, + nouveau_wait_eq(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0); + } + ++ wr_cio_state(dev, head, regp, NV_CIO_CRE_42); + wr_cio_state(dev, head, regp, NV_CIO_CRE_53); + wr_cio_state(dev, head, regp, NV_CIO_CRE_54); + diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c -index b0fb9bd..f017997 100644 +index b0fb9bd..4942294 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c -@@ -152,7 +152,6 @@ nouveau_mem_vram_fini(struct drm_device *dev) +@@ -152,9 +152,6 @@ nouveau_mem_vram_fini(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - nouveau_bo_unpin(dev_priv->vga_ram); - nouveau_bo_ref(NULL, &dev_priv->vga_ram); - +- nouveau_bo_ref(NULL, &dev_priv->vga_ram); +- ttm_bo_device_release(&dev_priv->ttm.bdev); -@@ -393,11 +392,17 @@ nouveau_mem_vram_init(struct drm_device *dev) + + nouveau_ttm_global_release(dev_priv); +@@ -393,11 +390,17 @@ nouveau_mem_vram_init(struct drm_device *dev) struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; int ret, dma_bits; @@ -1714,7 +1850,7 @@ index b0fb9bd..f017997 100644 ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits)); if (ret) -@@ -419,14 +424,32 @@ nouveau_mem_vram_init(struct drm_device *dev) +@@ -419,14 +422,32 @@ nouveau_mem_vram_init(struct drm_device *dev) } /* reserve space at end of VRAM for PRAMIN */ @@ -1755,7 +1891,7 @@ index b0fb9bd..f017997 100644 ret = dev_priv->engine.vram.init(dev); if (ret) -@@ -455,13 +478,17 @@ nouveau_mem_vram_init(struct drm_device *dev) +@@ -455,13 +476,17 @@ nouveau_mem_vram_init(struct drm_device *dev) return ret; } @@ -1780,7 +1916,7 @@ index b0fb9bd..f017997 100644 } dev_priv->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1), -@@ -525,6 +552,7 @@ nouveau_mem_timing_init(struct drm_device *dev) +@@ -525,6 +550,7 @@ nouveau_mem_timing_init(struct drm_device *dev) u8 tRC; /* Byte 9 */ u8 tUNK_10, tUNK_11, tUNK_12, tUNK_13, tUNK_14; u8 tUNK_18, tUNK_19, tUNK_20, tUNK_21; @@ -1788,7 +1924,7 @@ index b0fb9bd..f017997 100644 u8 *mem = NULL, *entry; int i, recordlen, entries; -@@ -569,6 +597,12 @@ nouveau_mem_timing_init(struct drm_device *dev) +@@ -569,6 +595,12 @@ nouveau_mem_timing_init(struct drm_device *dev) if (!memtimings->timing) return; @@ -1801,7 +1937,7 @@ index b0fb9bd..f017997 100644 entry = mem + mem[1]; for (i = 0; i < entries; i++, entry += recordlen) { struct nouveau_pm_memtiming *timing = &pm->memtimings.timing[i]; -@@ -608,36 +642,67 @@ nouveau_mem_timing_init(struct drm_device *dev) +@@ -608,36 +640,67 @@ nouveau_mem_timing_init(struct drm_device *dev) /* XXX: I don't trust the -1's and +1's... they must come * from somewhere! */ @@ -1896,7 +2032,7 @@ index b0fb9bd..f017997 100644 } NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i, -@@ -646,9 +711,10 @@ nouveau_mem_timing_init(struct drm_device *dev) +@@ -646,9 +709,10 @@ nouveau_mem_timing_init(struct drm_device *dev) NV_DEBUG(dev, " 230: %08x %08x %08x %08x\n", timing->reg_100230, timing->reg_100234, timing->reg_100238, timing->reg_10023c); @@ -1908,7 +2044,7 @@ index b0fb9bd..f017997 100644 memtimings->supported = true; } -@@ -666,13 +732,14 @@ nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long p_size +@@ -666,13 +730,14 @@ nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long p_size { struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); struct nouveau_mm *mm; @@ -1927,7 +2063,7 @@ index b0fb9bd..f017997 100644 if (ret) return ret; -@@ -700,9 +767,15 @@ nouveau_vram_manager_del(struct ttm_mem_type_manager *man, +@@ -700,9 +765,15 @@ nouveau_vram_manager_del(struct ttm_mem_type_manager *man, { struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); struct nouveau_vram_engine *vram = &dev_priv->engine.vram; @@ -1944,7 +2080,7 @@ index b0fb9bd..f017997 100644 } static int -@@ -715,7 +788,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, +@@ -715,7 +786,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, struct nouveau_vram_engine *vram = &dev_priv->engine.vram; struct drm_device *dev = dev_priv->dev; struct nouveau_bo *nvbo = nouveau_bo(bo); @@ -1953,7 +2089,7 @@ index b0fb9bd..f017997 100644 u32 size_nc = 0; int ret; -@@ -724,7 +797,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, +@@ -724,7 +795,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, ret = vram->get(dev, mem->num_pages << PAGE_SHIFT, mem->page_alignment << PAGE_SHIFT, size_nc, @@ -1962,7 +2098,7 @@ index b0fb9bd..f017997 100644 if (ret) { mem->mm_node = NULL; return (ret == -ENOSPC) ? 0 : ret; -@@ -771,3 +844,84 @@ const struct ttm_mem_type_manager_func nouveau_vram_manager = { +@@ -771,3 +842,84 @@ const struct ttm_mem_type_manager_func nouveau_vram_manager = { nouveau_vram_manager_del, nouveau_vram_manager_debug }; @@ -2069,18 +2205,28 @@ index 798eaf3..1f7483a 100644 #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c -index 5ea1676..7ba3fc0 100644 +index 5ea1676..5b39718 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c -@@ -39,12 +39,11 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan) +@@ -35,20 +35,22 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan) + { + struct drm_device *dev = chan->dev; + struct nouveau_bo *ntfy = NULL; +- uint32_t flags; ++ uint32_t flags, ttmpl; int ret; - if (nouveau_vram_notify) +- if (nouveau_vram_notify) - flags = TTM_PL_FLAG_VRAM; -+ flags = NOUVEAU_GEM_DOMAIN_VRAM; - else +- else - flags = TTM_PL_FLAG_TT; ++ if (nouveau_vram_notify) { ++ flags = NOUVEAU_GEM_DOMAIN_VRAM; ++ ttmpl = TTM_PL_FLAG_VRAM; ++ } else { + flags = NOUVEAU_GEM_DOMAIN_GART; ++ ttmpl = TTM_PL_FLAG_TT; ++ } - ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, flags, - 0, 0x0000, false, true, &ntfy); @@ -2088,7 +2234,12 @@ index 5ea1676..7ba3fc0 100644 if (ret) return ret; -@@ -100,6 +99,7 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, +- ret = nouveau_bo_pin(ntfy, flags); ++ ret = nouveau_bo_pin(ntfy, ttmpl); + if (ret) + goto out_err; + +@@ -100,6 +102,7 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, uint32_t *b_offset) { struct drm_device *dev = chan->dev; @@ -2096,7 +2247,7 @@ index 5ea1676..7ba3fc0 100644 struct nouveau_gpuobj *nobj = NULL; struct drm_mm_node *mem; uint32_t offset; -@@ -114,11 +114,16 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, +@@ -114,11 +117,16 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, return -ENOMEM; } @@ -2119,7 +2270,7 @@ index 5ea1676..7ba3fc0 100644 ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset, diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c -index 30b6544..823800d 100644 +index 30b6544..59b446e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -36,6 +36,7 @@ @@ -2196,8 +2347,53 @@ index 30b6544..823800d 100644 } /* VRAM ctxdma */ +@@ -1013,19 +1039,20 @@ nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset) + { + struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; + struct drm_device *dev = gpuobj->dev; ++ unsigned long flags; + + if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { + u64 ptr = gpuobj->vinst + offset; + u32 base = ptr >> 16; + u32 val; + +- spin_lock(&dev_priv->ramin_lock); ++ spin_lock_irqsave(&dev_priv->vm_lock, flags); + if (dev_priv->ramin_base != base) { + dev_priv->ramin_base = base; + nv_wr32(dev, 0x001700, dev_priv->ramin_base); + } + val = nv_rd32(dev, 0x700000 + (ptr & 0xffff)); +- spin_unlock(&dev_priv->ramin_lock); ++ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); + return val; + } + +@@ -1037,18 +1064,19 @@ nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val) + { + struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; + struct drm_device *dev = gpuobj->dev; ++ unsigned long flags; + + if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { + u64 ptr = gpuobj->vinst + offset; + u32 base = ptr >> 16; + +- spin_lock(&dev_priv->ramin_lock); ++ spin_lock_irqsave(&dev_priv->vm_lock, flags); + if (dev_priv->ramin_base != base) { + dev_priv->ramin_base = base; + nv_wr32(dev, 0x001700, dev_priv->ramin_base); + } + nv_wr32(dev, 0x700000 + (ptr & 0xffff), val); +- spin_unlock(&dev_priv->ramin_lock); ++ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); + return; + } + diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c -index ac62a1b..670e3cb 100644 +index ac62a1b..3045566 100644 --- a/drivers/gpu/drm/nouveau/nouveau_perf.c +++ b/drivers/gpu/drm/nouveau/nouveau_perf.c @@ -134,7 +134,7 @@ nouveau_perf_init(struct drm_device *dev) @@ -2209,6 +2405,31 @@ index ac62a1b..670e3cb 100644 perflvl->core = ROM32(entry[1]) * 10; perflvl->memory = ROM32(entry[5]) * 20; break; +@@ -174,9 +174,21 @@ nouveau_perf_init(struct drm_device *dev) + #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; + } + diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index 4399e2f..0b1caeb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -2712,7 +2933,7 @@ index 9a250eb..2bf9686 100644 uint32_t diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c -index a54fc43..eb4f09e 100644 +index a54fc43..adf6dac 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -376,15 +376,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) @@ -2735,7 +2956,15 @@ index a54fc43..eb4f09e 100644 engine->fifo.channels = 128; engine->fifo.init = nv50_fifo_init; engine->fifo.takedown = nv50_fifo_takedown; -@@ -544,7 +540,6 @@ static int +@@ -513,6 +509,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) + engine->vram.get = nvc0_vram_new; + engine->vram.put = nv50_vram_del; + engine->vram.flags_valid = nvc0_vram_flags_valid; ++ engine->pm.temp_get = nv84_temp_get; + break; + default: + NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); +@@ -544,7 +541,6 @@ static int nouveau_card_init_channel(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -2743,7 +2972,7 @@ index a54fc43..eb4f09e 100644 int ret; ret = nouveau_channel_alloc(dev, &dev_priv->channel, -@@ -552,41 +547,8 @@ nouveau_card_init_channel(struct drm_device *dev) +@@ -552,41 +548,8 @@ nouveau_card_init_channel(struct drm_device *dev) if (ret) return ret; @@ -2785,7 +3014,27 @@ index a54fc43..eb4f09e 100644 } static void nouveau_switcheroo_set_state(struct pci_dev *pdev, -@@ -904,7 +866,7 @@ static int nouveau_remove_conflicting_drivers(struct drm_device *dev) +@@ -646,6 +609,7 @@ nouveau_card_init(struct drm_device *dev) + spin_lock_init(&dev_priv->channels.lock); + spin_lock_init(&dev_priv->tile.lock); + spin_lock_init(&dev_priv->context_switch_lock); ++ spin_lock_init(&dev_priv->vm_lock); + + /* Make the CRTCs and I2C buses accessible */ + ret = engine->display.early_init(dev); +@@ -811,6 +775,11 @@ static void nouveau_card_takedown(struct drm_device *dev) + 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); +@@ -904,7 +873,7 @@ static int nouveau_remove_conflicting_drivers(struct drm_device *dev) #ifdef CONFIG_X86 primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif @@ -2794,7 +3043,7 @@ index a54fc43..eb4f09e 100644 remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary); return 0; } -@@ -929,12 +891,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) +@@ -929,12 +898,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", dev->pci_vendor, dev->pci_device, dev->pdev->class); @@ -2807,7 +3056,7 @@ index a54fc43..eb4f09e 100644 /* resource 0 is mmio regs */ /* resource 1 is linear FB */ /* resource 2 is RAMIN (mmio regs + 0x1000000) */ -@@ -947,7 +903,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) +@@ -947,7 +910,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) NV_ERROR(dev, "Unable to initialize the mmio mapping. " "Please report your setup to " DRIVER_EMAIL "\n"); ret = -EINVAL; @@ -2816,7 +3065,7 @@ index a54fc43..eb4f09e 100644 } NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", (unsigned long long)mmio_start_offs); -@@ -962,11 +918,13 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) +@@ -962,11 +925,13 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) /* Time to determine the card architecture */ reg0 = nv_rd32(dev, NV03_PMC_BOOT_0); @@ -2830,7 +3079,7 @@ index a54fc43..eb4f09e 100644 /* NV04 or NV05 */ } else if ((reg0 & 0xff00fff0) == 0x20004000) { if (reg0 & 0x00f00000) -@@ -1054,8 +1012,6 @@ err_ramin: +@@ -1054,8 +1019,6 @@ err_ramin: iounmap(dev_priv->ramin); err_mmio: iounmap(dev_priv->mmio); @@ -2839,7 +3088,7 @@ index a54fc43..eb4f09e 100644 err_priv: kfree(dev_priv); dev->dev_private = NULL; -@@ -1126,7 +1082,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, +@@ -1126,7 +1089,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, getparam->value = 1; break; case NOUVEAU_GETPARAM_HAS_PAGEFLIP: @@ -3089,10 +3338,22 @@ index 04fdc00..75e87274 100644 default: NV_WARN(dev, "voltage table 0x%02x unknown\n", volt[0]); diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c -index 297505e..5ffc5ba 100644 +index 297505e..9eaafcc 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c -@@ -790,8 +790,7 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, +@@ -376,7 +376,10 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode) + */ + + /* framebuffer can be larger than crtc scanout area. */ +- regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = XLATE(fb->pitch / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8); ++ regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = ++ XLATE(fb->pitch / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8); ++ regp->CRTC[NV_CIO_CRE_42] = ++ XLATE(fb->pitch / 8, 11, NV_CIO_CRE_42_OFFSET_11); + regp->CRTC[NV_CIO_CRE_RPC1_INDEX] = mode->crtc_hdisplay < 1280 ? + MASK(NV_CIO_CRE_RPC1_LARGE) : 0x00; + regp->CRTC[NV_CIO_CRE_LSR_INDEX] = XLATE(horizBlankEnd, 6, NV_CIO_CRE_LSR_HBE_6) | +@@ -790,8 +793,7 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, if (atomic) { drm_fb = passed_fb; fb = nouveau_framebuffer(passed_fb); @@ -3102,7 +3363,37 @@ index 297505e..5ffc5ba 100644 /* If not atomic, we can go ahead and pin, and unpin the * old fb we were passed. */ -@@ -1031,7 +1030,7 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num) +@@ -825,8 +827,11 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, + regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = drm_fb->pitch >> 3; + regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = + XLATE(drm_fb->pitch >> 3, 8, NV_CIO_CRE_RPC0_OFFSET_10_8); ++ regp->CRTC[NV_CIO_CRE_42] = ++ XLATE(drm_fb->pitch / 8, 11, NV_CIO_CRE_42_OFFSET_11); + crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_RPC0_INDEX); + crtc_wr_cio_state(crtc, regp, NV_CIO_CR_OFFSET_INDEX); ++ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_42); + + /* Update the framebuffer location. */ + regp->fb_start = nv_crtc->fb.offset & ~3; +@@ -944,14 +949,14 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, + 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; +@@ -1031,7 +1036,7 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num) drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256); ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM, @@ -3221,6 +3512,20 @@ index af75015..055677a 100644 { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" }, { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" }, { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" }, +diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c +index b8e3edb..0671b7f 100644 +--- a/drivers/gpu/drm/nouveau/nv04_instmem.c ++++ b/drivers/gpu/drm/nouveau/nv04_instmem.c +@@ -95,6 +95,9 @@ nv04_instmem_takedown(struct drm_device *dev) + nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL); + nouveau_gpuobj_ref(NULL, &dev_priv->ramro); + nouveau_gpuobj_ref(NULL, &dev_priv->ramfc); ++ ++ if (dev_priv->ramin_heap.free_stack.next) ++ drm_mm_takedown(&dev_priv->ramin_heap); + } + + int diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index 8c92edb..531d7ba 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c @@ -3312,8 +3617,103 @@ index f3d9c05..f0ac2a7 100644 switch (dev_priv->chipset) { case 0x40: +diff --git a/drivers/gpu/drm/nouveau/nv50_calc.c b/drivers/gpu/drm/nouveau/nv50_calc.c +index de81151..8cf63a8 100644 +--- a/drivers/gpu/drm/nouveau/nv50_calc.c ++++ b/drivers/gpu/drm/nouveau/nv50_calc.c +@@ -23,7 +23,6 @@ + */ + + #include "drmP.h" +-#include "drm_fixed.h" + #include "nouveau_drv.h" + #include "nouveau_hw.h" + +@@ -47,45 +46,52 @@ nv50_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk, + } + + 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); ++ 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); + +- /* 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); ++ 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++; + +- /* *N = floor(fb_div); */ +- a.full = dfixed_floor(fb_div); +- *N = dfixed_trunc(fb_div); ++ if (N < pll->vco1.min_n) ++ continue; ++ if (N > pll->vco1.max_n) ++ break; + +- /* *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; ++ err = abs(clk - (pll->refclk * N / M / *P)); ++ if (err < best_err) { ++ best_err = err; ++ *pN = N; ++ *pM = M; ++ } + +- return clk; ++ 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 pll->refclk * *pN / *pM / *P; + } diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c -index 9023c4d..e900a51 100644 +index 9023c4d..ebabacf 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c @@ -65,7 +65,7 @@ nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked) @@ -3345,6 +3745,42 @@ index 9023c4d..e900a51 100644 struct drm_display_mode *native_mode = NULL; struct drm_display_mode *mode = &nv_crtc->base.mode; uint32_t outX, outY, horiz, vert; +@@ -288,7 +286,7 @@ nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk) + 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; + +@@ -300,7 +298,7 @@ nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk) + 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; + +@@ -351,14 +349,14 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, + 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; @@ -445,6 +443,39 @@ nv50_crtc_dpms(struct drm_crtc *crtc, int mode) { } @@ -3674,7 +4110,7 @@ index 875414b..808f3ec 100644 uint32_t mode_ctl = 0, mode_ctl2 = 0; int ret; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c -index 7cc94ed..75a376c 100644 +index 7cc94ed..74a3f68 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -24,6 +24,7 @@ @@ -3909,7 +4345,36 @@ index 7cc94ed..75a376c 100644 } static u16 -@@ -466,11 +600,12 @@ static void +@@ -383,13 +517,25 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb, + 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) && +@@ -466,11 +612,12 @@ static void nv50_display_unk10_handler(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -3923,7 +4388,7 @@ index 7cc94ed..75a376c 100644 nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8); -@@ -541,7 +676,7 @@ nv50_display_unk10_handler(struct drm_device *dev) +@@ -541,7 +688,7 @@ nv50_display_unk10_handler(struct drm_device *dev) if (dcb->type == type && (dcb->or & (1 << or))) { nouveau_bios_run_display_table(dev, dcb, 0, -1); @@ -3932,7 +4397,7 @@ index 7cc94ed..75a376c 100644 goto ack; } } -@@ -587,15 +722,16 @@ static void +@@ -587,15 +734,16 @@ static void nv50_display_unk20_handler(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -3952,7 +4417,7 @@ index 7cc94ed..75a376c 100644 } /* CRTC clock change requested? */ -@@ -692,9 +828,9 @@ nv50_display_unk20_handler(struct drm_device *dev) +@@ -692,9 +840,9 @@ nv50_display_unk20_handler(struct drm_device *dev) nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0); } @@ -3965,7 +4430,7 @@ index 7cc94ed..75a376c 100644 ack: nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20); -@@ -735,13 +871,13 @@ nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb) +@@ -735,13 +883,13 @@ nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb) static void nv50_display_unk40_handler(struct drm_device *dev) { @@ -3984,7 +4449,7 @@ index 7cc94ed..75a376c 100644 if (!dcb) goto ack; -@@ -754,12 +890,10 @@ ack: +@@ -754,12 +902,10 @@ ack: nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) | 8); } @@ -4000,7 +4465,7 @@ index 7cc94ed..75a376c 100644 for (;;) { uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); -@@ -807,7 +941,7 @@ nv50_display_error_handler(struct drm_device *dev) +@@ -807,7 +953,7 @@ nv50_display_error_handler(struct drm_device *dev) static void nv50_display_isr(struct drm_device *dev) { @@ -4009,7 +4474,7 @@ index 7cc94ed..75a376c 100644 uint32_t delayed = 0; while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { -@@ -835,8 +969,7 @@ nv50_display_isr(struct drm_device *dev) +@@ -835,8 +981,7 @@ nv50_display_isr(struct drm_device *dev) NV50_PDISPLAY_INTR_1_CLK_UNK40)); if (clock) { nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); @@ -5154,7 +5619,7 @@ index 336aab2..de9abff 100644 else xf_emit(ctx, 3, 0); /* 1, 7, 3ff */ diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c -index e57caa2..fa94973 100644 +index e57caa2..993ad3f 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -300,7 +300,7 @@ nv50_instmem_resume(struct drm_device *dev) @@ -5166,6 +5631,36 @@ index e57caa2..fa94973 100644 struct nouveau_vma chan_vma; u32 align; }; +@@ -404,23 +404,25 @@ void + nv50_instmem_flush(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; ++ unsigned long flags; + +- spin_lock(&dev_priv->ramin_lock); ++ spin_lock_irqsave(&dev_priv->vm_lock, flags); + nv_wr32(dev, 0x00330c, 0x00000001); + if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) + NV_ERROR(dev, "PRAMIN flush timeout\n"); +- spin_unlock(&dev_priv->ramin_lock); ++ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); + } + + void + nv84_instmem_flush(struct drm_device *dev) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; ++ unsigned long flags; + +- spin_lock(&dev_priv->ramin_lock); ++ spin_lock_irqsave(&dev_priv->vm_lock, flags); + nv_wr32(dev, 0x070000, 0x00000001); + if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) + NV_ERROR(dev, "PRAMIN flush timeout\n"); +- spin_unlock(&dev_priv->ramin_lock); ++ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); + } + diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index b4a5ecb..c25c593 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c @@ -5191,7 +5686,7 @@ index b4a5ecb..c25c593 100644 struct drm_device *dev = encoder->dev; struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc); diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c -index 6144156..4fd3432 100644 +index 6144156..6c26944 100644 --- a/drivers/gpu/drm/nouveau/nv50_vm.c +++ b/drivers/gpu/drm/nouveau/nv50_vm.c @@ -31,7 +31,6 @@ void @@ -5257,6 +5752,20 @@ index 6144156..4fd3432 100644 nv_wo32(pgt, pte + 0, lower_32_bits(phys)); nv_wo32(pgt, pte + 4, upper_32_bits(phys)); pte += 8; +@@ -170,10 +174,11 @@ void + nv50_vm_flush_engine(struct drm_device *dev, int engine) + { + struct drm_nouveau_private *dev_priv = dev->dev_private; ++ unsigned long flags; + +- spin_lock(&dev_priv->ramin_lock); ++ spin_lock_irqsave(&dev_priv->vm_lock, flags); + nv_wr32(dev, 0x100c80, (engine << 16) | 1); + if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) + NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); +- spin_unlock(&dev_priv->ramin_lock); ++ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); + } diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c index 58e98ad..ffbc3d8 100644 --- a/drivers/gpu/drm/nouveau/nv50_vram.c @@ -5391,6 +5900,312 @@ index ec18ae1..fabc7fd 100644 - nv50_fb_vm_trap(dev, show, "PCRYPT"); + nv50_fb_vm_trap(dev, show); } +diff --git a/drivers/gpu/drm/nouveau/nva3_pm.c b/drivers/gpu/drm/nouveau/nva3_pm.c +index dbbafed..e4b2b9e 100644 +--- a/drivers/gpu/drm/nouveau/nva3_pm.c ++++ b/drivers/gpu/drm/nouveau/nva3_pm.c +@@ -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 @@ void * + 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; ++ ++ 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); + +- state = kzalloc(sizeof(*state), GFP_KERNEL); +- if (!state) ++ ++ 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; + +- ret = get_pll_limits(dev, id, &state->pll); +- if (ret < 0) { +- kfree(state); +- return (ret == -ENOENT) ? NULL : ERR_PTR(ret); ++ /* 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 --git a/drivers/gpu/drm/nouveau/nvc0_fb.c b/drivers/gpu/drm/nouveau/nvc0_fb.c +index 26a9960..08e6b11 100644 +--- a/drivers/gpu/drm/nouveau/nvc0_fb.c ++++ b/drivers/gpu/drm/nouveau/nvc0_fb.c +@@ -1,5 +1,5 @@ + /* +- * Copyright 2010 Red Hat Inc. ++ * 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"), +@@ -23,16 +23,80 @@ + */ + + #include "drmP.h" +- ++#include "drm.h" + #include "nouveau_drv.h" ++#include "nouveau_drm.h" ++ ++struct nvc0_fb_priv { ++ struct page *r100c10_page; ++ dma_addr_t r100c10; ++}; ++ ++static void ++nvc0_fb_destroy(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; ++ struct nvc0_fb_priv *priv = pfb->priv; ++ ++ if (priv->r100c10_page) { ++ pci_unmap_page(dev->pdev, priv->r100c10, PAGE_SIZE, ++ PCI_DMA_BIDIRECTIONAL); ++ __free_page(priv->r100c10_page); ++ } ++ ++ kfree(priv); ++ pfb->priv = NULL; ++} ++ ++static int ++nvc0_fb_create(struct drm_device *dev) ++{ ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; ++ struct nvc0_fb_priv *priv; ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ pfb->priv = priv; ++ ++ priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO); ++ if (!priv->r100c10_page) { ++ nvc0_fb_destroy(dev); ++ return -ENOMEM; ++ } ++ ++ priv->r100c10 = pci_map_page(dev->pdev, priv->r100c10_page, 0, ++ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); ++ if (pci_dma_mapping_error(dev->pdev, priv->r100c10)) { ++ nvc0_fb_destroy(dev); ++ return -EFAULT; ++ } ++ ++ return 0; ++} + + int + nvc0_fb_init(struct drm_device *dev) + { ++ struct drm_nouveau_private *dev_priv = dev->dev_private; ++ struct nvc0_fb_priv *priv; ++ int ret; ++ ++ if (!dev_priv->engine.fb.priv) { ++ ret = nvc0_fb_create(dev); ++ if (ret) ++ return ret; ++ } ++ priv = dev_priv->engine.fb.priv; ++ ++ nv_wr32(dev, 0x100c10, priv->r100c10 >> 8); + return 0; + } + + void + nvc0_fb_takedown(struct drm_device *dev) + { ++ nvc0_fb_destroy(dev); + } diff --git a/drivers/gpu/drm/nouveau/nvc0_fifo.c b/drivers/gpu/drm/nouveau/nvc0_fifo.c index e6f92c5..55a4245 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fifo.c @@ -5777,7 +6592,7 @@ index f880ff7..6cede9f 100644 gpc = (gpc + 1) % priv->gpc_nr; } while (!tpnr[gpc]); diff --git a/drivers/gpu/drm/nouveau/nvc0_vm.c b/drivers/gpu/drm/nouveau/nvc0_vm.c -index e4e83c2..69af0ba 100644 +index e4e83c2..a179e6c 100644 --- a/drivers/gpu/drm/nouveau/nvc0_vm.c +++ b/drivers/gpu/drm/nouveau/nvc0_vm.c @@ -59,7 +59,7 @@ nvc0_vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target) @@ -5803,6 +6618,43 @@ index e4e83c2..69af0ba 100644 nv_wo32(pgt, pte + 0, lower_32_bits(phys)); nv_wo32(pgt, pte + 4, upper_32_bits(phys)); pte += 8; +@@ -104,20 +104,27 @@ nvc0_vm_flush(struct nouveau_vm *vm) + struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; + struct drm_device *dev = vm->dev; + struct nouveau_vm_pgd *vpgd; +- u32 r100c80, engine; ++ unsigned long flags; ++ u32 engine = (dev_priv->chan_vm == vm) ? 1 : 5; + + pinstmem->flush(vm->dev); + +- if (vm == dev_priv->chan_vm) +- engine = 1; +- else +- engine = 5; +- ++ spin_lock_irqsave(&dev_priv->vm_lock, flags); + list_for_each_entry(vpgd, &vm->pgd_list, head) { +- r100c80 = nv_rd32(dev, 0x100c80); ++ /* looks like maybe a "free flush slots" counter, the ++ * faster you write to 0x100cbc to more it decreases ++ */ ++ if (!nv_wait_ne(dev, 0x100c80, 0x00ff0000, 0x00000000)) { ++ NV_ERROR(dev, "vm timeout 0: 0x%08x %d\n", ++ nv_rd32(dev, 0x100c80), engine); ++ } + nv_wr32(dev, 0x100cb8, vpgd->obj->vinst >> 8); + nv_wr32(dev, 0x100cbc, 0x80000000 | engine); +- if (!nv_wait(dev, 0x100c80, 0xffffffff, r100c80)) +- NV_ERROR(dev, "vm flush timeout eng %d\n", engine); ++ /* wait for flush to be queued? */ ++ if (!nv_wait(dev, 0x100c80, 0x00008000, 0x00008000)) { ++ NV_ERROR(dev, "vm timeout 1: 0x%08x %d\n", ++ nv_rd32(dev, 0x100c80), engine); ++ } + } ++ spin_unlock_irqrestore(&dev_priv->vm_lock, flags); + } diff --git a/drivers/gpu/drm/nouveau/nvc0_vram.c b/drivers/gpu/drm/nouveau/nvc0_vram.c index 858eda5..67c6ec6 100644 --- a/drivers/gpu/drm/nouveau/nvc0_vram.c @@ -5910,3 +6762,16 @@ index 858eda5..67c6ec6 100644 return 0; } +diff --git a/drivers/gpu/drm/nouveau/nvreg.h b/drivers/gpu/drm/nouveau/nvreg.h +index fe0f253..bbfb1a6 100644 +--- a/drivers/gpu/drm/nouveau/nvreg.h ++++ b/drivers/gpu/drm/nouveau/nvreg.h +@@ -277,6 +277,8 @@ + # define NV_CIO_CRE_EBR_VDE_11 2:2 + # define NV_CIO_CRE_EBR_VRS_11 4:4 + # define NV_CIO_CRE_EBR_VBS_11 6:6 ++# define NV_CIO_CRE_42 0x42 ++# define NV_CIO_CRE_42_OFFSET_11 6:6 + # define NV_CIO_CRE_43 0x43 + # define NV_CIO_CRE_44 0x44 /* head control */ + # define NV_CIO_CRE_CSB 0x45 /* colour saturation boost */ diff --git a/freed-ora/current/f15/drm-radeon-update2.patch b/freed-ora/current/f15/drm-radeon-update2.patch new file mode 100644 index 000000000..1224c0fba --- /dev/null +++ b/freed-ora/current/f15/drm-radeon-update2.patch @@ -0,0 +1,1708 @@ +commit 05d1ee2878c955f7cf4254ed7f94bd65758f9208 +Author: Alex Deucher <alexdeucher@gmail.com> +Date: Wed May 25 01:00:45 2011 -0400 + + drm/radeon/kms/blit: workaround some hw issues on evergreen+ + + Signed-off-by: Alex Deucher <alexdeucher@gmail.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit e520c516656b3c361ebf8add4e00428b7c37afd6 +Author: Alex Deucher <alexdeucher@gmail.com> +Date: Wed May 25 16:39:00 2011 -0400 + + drm/radeon/kms: add blit support for cayman (v2) + + Allows us to use the 3D engine for memory management + and allows us to use vram beyond the BAR aperture. + + v2: fix copy paste typo + Reported-by: Nils Wallménius <nils.wallmenius@gmail.com> + + Signed-off-by: Alex Deucher <alexdeucher@gmail.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit e1b12b63f9df3a5480972c21f504163b36ceaa88 +Author: Alex Deucher <alexdeucher@gmail.com> +Date: Wed May 25 18:45:37 2011 -0400 + + drm/radeon/kms: fix thermal sensor reading on juniper + + Uses a different method than other evergreen asics. + + Signed-off-by: Alex Deucher <alexdeucher@gmail.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit 46f21922e84d074158781368eee24727a60f9d32 +Author: Alex Deucher <alexdeucher@gmail.com> +Date: Wed May 25 17:49:54 2011 -0400 + + drm/radeon/kms: add missing case for cayman thermal sensor + + The rest of the code is already in place. + + Signed-off-by: Alex Deucher <alexdeucher@gmail.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit 8cc42a1f51ada532c76009fd8b3261d5e7e8f02b +Author: Alex Deucher <alexdeucher@gmail.com> +Date: Fri May 20 12:35:23 2011 -0400 + + drm/radeon/kms: bump kms version number + + - proper bank size for fusion for 2D tiling. + + Signed-off-by: Alex Deucher <alexdeucher@gmail.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit e0014e347d1d15e12c5beffd6af9d22a8d495969 +Author: Alex Deucher <alexdeucher@gmail.com> +Date: Fri May 20 12:35:22 2011 -0400 + + drm/radeon/kms: properly set num banks for fusion asics + + Needed by userspace for 2D tiled buffer alignment + + Signed-off-by: Alex Deucher <alexdeucher@gmail.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit 48c7304eb2af97b6e50a93e22b656c9f3ead5f90 +Author: Alex Deucher <alexdeucher@gmail.com> +Date: Mon May 23 14:22:26 2011 -0400 + + drm/radeon/kms/cayman: fix typo in register mask + + Noticed by Droste on IRC. + + Signed-off-by: Alex Deucher <alexdeucher@gmail.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit 13e5c224cdd62fc3d454f1ef6d8157181ade07d9 +Author: Dave Airlie <airlied@redhat.com> +Date: Thu May 19 14:14:41 2011 +1000 + + drm/radeon/kms: fix tile_config value reported to userspace on cayman. + + cayman is reporting the wrong tile config value to userspace, this + causes piglit mipmap generation tests to fail. + + Reviewed-by: Alex Deucher <alexdeucher@gmail.com> + cc: stable@kernel.org + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit a9b83345a9c37d3bdea30be5a7d0cd34a0f28a68 +Author: Dave Airlie <airlied@redhat.com> +Date: Thu May 19 14:14:40 2011 +1000 + + drm/radeon/kms: fix incorrect comparison in cayman setup code. + + This was leading to a bogus value being programmed to the backend + routing register. + + Reviewed-by: Alex Deucher <alexdeucher@gmail.com> + cc: stable@kernel.org + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit 4f71384abcb866214a927510d7e315ad00692faa +Author: Dave Airlie <airlied@redhat.com> +Date: Thu May 19 14:14:43 2011 +1000 + + drm/radeon/kms: add wait idle ioctl for eg->cayman + + None of the latest GPUs had this hooked up, this is necessary for + correct operation in a lot of cases, however we should test this on a few + GPUs in these families as we've had problems in this area before. + + Reviewed-by: Alex Deucher <alexdeucher@gmail.com> + cc: stable@kernel.org + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit 0676d9dc1e66566af98e1192a041c9e983a69eaf +Author: Dave Airlie <airlied@redhat.com> +Date: Thu May 19 14:14:42 2011 +1000 + + drm/radeon/cayman: setup hdp to invalidate and flush when asked + + On cayman we need to set the bit to cause HDP flushes to invalidate the + HDP cache also. + + Reviewed-by: Alex Deucher <alexdeucher@gmail.com> + cc: stable@kernel.org + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit 5e9df070bdc59db0b8718b8e2e6a387e49acda7c +Author: Alex Deucher <alexdeucher@gmail.com> +Date: Thu May 19 11:07:57 2011 -0400 + + drm/radeon/evergreen/btc/fusion: setup hdp to invalidate and flush when asked + + This needs to be explicitly set on btc. It's set by default + on evergreen/fusion, so it fine to just unconditionally enable it for + all chips. + + Signed-off-by: Alex Deucher <alexdeucher@gmail.com> + cc: stable@kernel.org + Signed-off-by: Dave Airlie <airlied@gmail.com> + +commit 97bce584876b2293c0ceeeb1abc33ec568d320ea +Author: Alex Deucher <alexdeucher@gmail.com> +Date: Thu May 12 21:15:15 2011 -0400 + + drm/radeon/kms: add some evergreen/ni safe regs + + need to programmed from the userspace drivers. + + Signed-off-by: Alex Deucher <alexdeucher@gmail.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit d3be86b8137152ebf1be2ee2ccf90fea7f9a07a9 +Author: Alex Deucher <alexdeucher@gmail.com> +Date: Wed May 11 03:15:24 2011 -0400 + + drm/radeon/kms: fix tiling reg on fusion + + The location of MC_ARB_RAMCFG changed on fusion. + I've diffed all the other regs in evergreend.h and this + is the only other reg that changed. + + Signed-off-by: Alex Deucher <alexdeucher@gmail.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit 740da77e0792cd804510d018924df8f149f58fe4 +Author: Alex Deucher <alexdeucher@gmail.com> +Date: Tue May 10 02:14:52 2011 +0000 + + drm/radeon/kms: fix cayman acceleration + + The TCC disable setup was incorrect. This + prevents the GPU from hanging when draw commands + are issued. + + Signed-off-by: Alex Deucher <alexdeucher@gmail.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit 02b1b583d1c9b2559288ea5f46f04b0c8385f1ef +Author: Dave Airlie <airlied@redhat.com> +Date: Mon May 9 14:54:33 2011 +1000 + + drm/radeon: fix cayman struct accessors. + + We are accessing totally the wrong struct in this case, and putting + uninitialised values into the GPU, which it doesn't like unsurprisingly. + + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit 202ea65cf5d6451baf74feb4becdad19ab53eadc +Author: Ilija Hadzic <ihadzic@research.bell-labs.com> +Date: Wed May 4 20:15:03 2011 -0400 + + drm/radeon: fix order of doing things in radeon_crtc_cursor_set + + if object pin or object lookup in radeon_cursor_set fail, the function + could leave inconsistent mouse width and hight values in radeon_crtc + fixed by moving cursor width and height assignments after all + checks have passed + + Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com> + Reviewed-by: Alex Deucher <alexdeucher@gmail.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit a796f1fc096d0032972480657d6d9c4fc5836496 +Author: Alex Deucher <alexdeucher@gmail.com> +Date: Fri May 6 01:42:49 2011 -0400 + + drm/radeon/kms: ATPX switcheroo fixes + + When we switch the display mux, also switch + the i2c mux. Also use the start and finish + methods to let the sbios know that the switch + is happening. + + Should fix: + https://bugs.freedesktop.org/show_bug.cgi?id=35398 + + Signed-off-by: Alex Deucher <alexdeucher@gmail.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> + +commit 134627db513fffd8ecc90b96d477c18ae76d2d61 +Author: Alex Deucher <alexdeucher@gmail.com> +Date: Tue May 3 12:44:54 2011 -0400 + + drm/radeon/kms: add support for thermal chips on combios asics + + Signed-off-by: Alex Deucher <alexdeucher@gmail.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> +diff --git a/drivers/gpu/drm/radeon/cayman_blit_shaders.c b/drivers/gpu/drm/radeon/cayman_blit_shaders.c +index e148ab0..7b4eeb7 100644 +--- a/drivers/gpu/drm/radeon/cayman_blit_shaders.c ++++ b/drivers/gpu/drm/radeon/cayman_blit_shaders.c +@@ -39,17 +39,335 @@ + + const u32 cayman_default_state[] = + { +- /* XXX fill in additional blit state */ ++ 0xc0066900, ++ 0x00000000, ++ 0x00000060, /* DB_RENDER_CONTROL */ ++ 0x00000000, /* DB_COUNT_CONTROL */ ++ 0x00000000, /* DB_DEPTH_VIEW */ ++ 0x0000002a, /* DB_RENDER_OVERRIDE */ ++ 0x00000000, /* DB_RENDER_OVERRIDE2 */ ++ 0x00000000, /* DB_HTILE_DATA_BASE */ + + 0xc0026900, +- 0x00000316, +- 0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */ +- 0x00000010, /* */ ++ 0x0000000a, ++ 0x00000000, /* DB_STENCIL_CLEAR */ ++ 0x00000000, /* DB_DEPTH_CLEAR */ ++ ++ 0xc0036900, ++ 0x0000000f, ++ 0x00000000, /* DB_DEPTH_INFO */ ++ 0x00000000, /* DB_Z_INFO */ ++ 0x00000000, /* DB_STENCIL_INFO */ ++ ++ 0xc0016900, ++ 0x00000080, ++ 0x00000000, /* PA_SC_WINDOW_OFFSET */ ++ ++ 0xc00d6900, ++ 0x00000083, ++ 0x0000ffff, /* PA_SC_CLIPRECT_RULE */ ++ 0x00000000, /* PA_SC_CLIPRECT_0_TL */ ++ 0x20002000, /* PA_SC_CLIPRECT_0_BR */ ++ 0x00000000, ++ 0x20002000, ++ 0x00000000, ++ 0x20002000, ++ 0x00000000, ++ 0x20002000, ++ 0xaaaaaaaa, /* PA_SC_EDGERULE */ ++ 0x00000000, /* PA_SU_HARDWARE_SCREEN_OFFSET */ ++ 0x0000000f, /* CB_TARGET_MASK */ ++ 0x0000000f, /* CB_SHADER_MASK */ ++ ++ 0xc0226900, ++ 0x00000094, ++ 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ ++ 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x80000000, ++ 0x20002000, ++ 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ ++ 0x3f800000, /* PA_SC_VPORT_ZMAX_0 */ ++ ++ 0xc0016900, ++ 0x000000d4, ++ 0x00000000, /* SX_MISC */ + + 0xc0026900, + 0x000000d9, + 0x00000000, /* CP_RINGID */ + 0x00000000, /* CP_VMID */ ++ ++ 0xc0096900, ++ 0x00000100, ++ 0x00ffffff, /* VGT_MAX_VTX_INDX */ ++ 0x00000000, /* VGT_MIN_VTX_INDX */ ++ 0x00000000, /* VGT_INDX_OFFSET */ ++ 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ ++ 0x00000000, /* SX_ALPHA_TEST_CONTROL */ ++ 0x00000000, /* CB_BLEND_RED */ ++ 0x00000000, /* CB_BLEND_GREEN */ ++ 0x00000000, /* CB_BLEND_BLUE */ ++ 0x00000000, /* CB_BLEND_ALPHA */ ++ ++ 0xc0016900, ++ 0x00000187, ++ 0x00000100, /* SPI_VS_OUT_ID_0 */ ++ ++ 0xc0026900, ++ 0x00000191, ++ 0x00000100, /* SPI_PS_INPUT_CNTL_0 */ ++ 0x00000101, /* SPI_PS_INPUT_CNTL_1 */ ++ ++ 0xc0016900, ++ 0x000001b1, ++ 0x00000000, /* SPI_VS_OUT_CONFIG */ ++ ++ 0xc0106900, ++ 0x000001b3, ++ 0x20000001, /* SPI_PS_IN_CONTROL_0 */ ++ 0x00000000, /* SPI_PS_IN_CONTROL_1 */ ++ 0x00000000, /* SPI_INTERP_CONTROL_0 */ ++ 0x00000000, /* SPI_INPUT_Z */ ++ 0x00000000, /* SPI_FOG_CNTL */ ++ 0x00100000, /* SPI_BARYC_CNTL */ ++ 0x00000000, /* SPI_PS_IN_CONTROL_2 */ ++ 0x00000000, /* SPI_COMPUTE_INPUT_CNTL */ ++ 0x00000000, /* SPI_COMPUTE_NUM_THREAD_X */ ++ 0x00000000, /* SPI_COMPUTE_NUM_THREAD_Y */ ++ 0x00000000, /* SPI_COMPUTE_NUM_THREAD_Z */ ++ 0x00000000, /* SPI_GPR_MGMT */ ++ 0x00000000, /* SPI_LDS_MGMT */ ++ 0x00000000, /* SPI_STACK_MGMT */ ++ 0x00000000, /* SPI_WAVE_MGMT_1 */ ++ 0x00000000, /* SPI_WAVE_MGMT_2 */ ++ ++ 0xc0016900, ++ 0x000001e0, ++ 0x00000000, /* CB_BLEND0_CONTROL */ ++ ++ 0xc00e6900, ++ 0x00000200, ++ 0x00000000, /* DB_DEPTH_CONTROL */ ++ 0x00000000, /* DB_EQAA */ ++ 0x00cc0010, /* CB_COLOR_CONTROL */ ++ 0x00000210, /* DB_SHADER_CONTROL */ ++ 0x00010000, /* PA_CL_CLIP_CNTL */ ++ 0x00000004, /* PA_SU_SC_MODE_CNTL */ ++ 0x00000100, /* PA_CL_VTE_CNTL */ ++ 0x00000000, /* PA_CL_VS_OUT_CNTL */ ++ 0x00000000, /* PA_CL_NANINF_CNTL */ ++ 0x00000000, /* PA_SU_LINE_STIPPLE_CNTL */ ++ 0x00000000, /* PA_SU_LINE_STIPPLE_SCALE */ ++ 0x00000000, /* PA_SU_PRIM_FILTER_CNTL */ ++ 0x00000000, /* */ ++ 0x00000000, /* */ ++ ++ 0xc0026900, ++ 0x00000229, ++ 0x00000000, /* SQ_PGM_START_FS */ ++ 0x00000000, ++ ++ 0xc0016900, ++ 0x0000023b, ++ 0x00000000, /* SQ_LDS_ALLOC_PS */ ++ ++ 0xc0066900, ++ 0x00000240, ++ 0x00000000, /* SQ_ESGS_RING_ITEMSIZE */ ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ ++ 0xc0046900, ++ 0x00000247, ++ 0x00000000, /* SQ_GS_VERT_ITEMSIZE */ ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ ++ 0xc0116900, ++ 0x00000280, ++ 0x00000000, /* PA_SU_POINT_SIZE */ ++ 0x00000000, /* PA_SU_POINT_MINMAX */ ++ 0x00000008, /* PA_SU_LINE_CNTL */ ++ 0x00000000, /* PA_SC_LINE_STIPPLE */ ++ 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ ++ 0x00000000, /* VGT_HOS_CNTL */ ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, /* VGT_GS_MODE */ ++ ++ 0xc0026900, ++ 0x00000292, ++ 0x00000000, /* PA_SC_MODE_CNTL_0 */ ++ 0x00000000, /* PA_SC_MODE_CNTL_1 */ ++ ++ 0xc0016900, ++ 0x000002a1, ++ 0x00000000, /* VGT_PRIMITIVEID_EN */ ++ ++ 0xc0016900, ++ 0x000002a5, ++ 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_EN */ ++ ++ 0xc0026900, ++ 0x000002a8, ++ 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ ++ 0x00000000, ++ ++ 0xc0026900, ++ 0x000002ad, ++ 0x00000000, /* VGT_REUSE_OFF */ ++ 0x00000000, ++ ++ 0xc0016900, ++ 0x000002d5, ++ 0x00000000, /* VGT_SHADER_STAGES_EN */ ++ ++ 0xc0016900, ++ 0x000002dc, ++ 0x0000aa00, /* DB_ALPHA_TO_MASK */ ++ ++ 0xc0066900, ++ 0x000002de, ++ 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ ++ 0xc0026900, ++ 0x000002e5, ++ 0x00000000, /* VGT_STRMOUT_CONFIG */ ++ 0x00000000, ++ ++ 0xc01b6900, ++ 0x000002f5, ++ 0x76543210, /* PA_SC_CENTROID_PRIORITY_0 */ ++ 0xfedcba98, /* PA_SC_CENTROID_PRIORITY_1 */ ++ 0x00000000, /* PA_SC_LINE_CNTL */ ++ 0x00000000, /* PA_SC_AA_CONFIG */ ++ 0x00000005, /* PA_SU_VTX_CNTL */ ++ 0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ ++ 0x3f800000, /* PA_CL_GB_VERT_DISC_ADJ */ ++ 0x3f800000, /* PA_CL_GB_HORZ_CLIP_ADJ */ ++ 0x3f800000, /* PA_CL_GB_HORZ_DISC_ADJ */ ++ 0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */ ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0xffffffff, /* PA_SC_AA_MASK_X0Y0_X1Y0 */ ++ 0xffffffff, ++ ++ 0xc0026900, ++ 0x00000316, ++ 0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */ ++ 0x00000010, /* */ ++}; ++ ++const u32 cayman_vs[] = ++{ ++ 0x00000004, ++ 0x80400400, ++ 0x0000a03c, ++ 0x95000688, ++ 0x00004000, ++ 0x15000688, ++ 0x00000000, ++ 0x88000000, ++ 0x04000000, ++ 0x67961001, ++#ifdef __BIG_ENDIAN ++ 0x00020000, ++#else ++ 0x00000000, ++#endif ++ 0x00000000, ++ 0x04000000, ++ 0x67961000, ++#ifdef __BIG_ENDIAN ++ 0x00020008, ++#else ++ 0x00000008, ++#endif ++ 0x00000000, ++}; ++ ++const u32 cayman_ps[] = ++{ ++ 0x00000004, ++ 0xa00c0000, ++ 0x00000008, ++ 0x80400000, ++ 0x00000000, ++ 0x95000688, ++ 0x00000000, ++ 0x88000000, ++ 0x00380400, ++ 0x00146b10, ++ 0x00380000, ++ 0x20146b10, ++ 0x00380400, ++ 0x40146b00, ++ 0x80380000, ++ 0x60146b00, ++ 0x00000010, ++ 0x000d1000, ++ 0xb0800000, ++ 0x00000000, + }; + ++const u32 cayman_ps_size = ARRAY_SIZE(cayman_ps); ++const u32 cayman_vs_size = ARRAY_SIZE(cayman_vs); + const u32 cayman_default_size = ARRAY_SIZE(cayman_default_state); +diff --git a/drivers/gpu/drm/radeon/cayman_blit_shaders.h b/drivers/gpu/drm/radeon/cayman_blit_shaders.h +index 33b75e5..f5d0e9a 100644 +--- a/drivers/gpu/drm/radeon/cayman_blit_shaders.h ++++ b/drivers/gpu/drm/radeon/cayman_blit_shaders.h +@@ -25,8 +25,11 @@ + #ifndef CAYMAN_BLIT_SHADERS_H + #define CAYMAN_BLIT_SHADERS_H + ++extern const u32 cayman_ps[]; ++extern const u32 cayman_vs[]; + extern const u32 cayman_default_state[]; + ++extern const u32 cayman_ps_size, cayman_vs_size; + extern const u32 cayman_default_size; + + #endif +diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c +index f7e0376..1b583f8 100644 +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -88,21 +88,39 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) + /* get temperature in millidegrees */ + int evergreen_get_temp(struct radeon_device *rdev) + { +- u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> +- ASIC_T_SHIFT; +- u32 actual_temp = 0; +- +- if (temp & 0x400) +- actual_temp = -256; +- else if (temp & 0x200) +- actual_temp = 255; +- else if (temp & 0x100) { +- actual_temp = temp & 0x1ff; +- actual_temp |= ~0x1ff; +- } else +- actual_temp = temp & 0xff; ++ u32 temp, toffset, actual_temp = 0; ++ ++ if (rdev->family == CHIP_JUNIPER) { ++ toffset = (RREG32(CG_THERMAL_CTRL) & TOFFSET_MASK) >> ++ TOFFSET_SHIFT; ++ temp = (RREG32(CG_TS0_STATUS) & TS0_ADC_DOUT_MASK) >> ++ TS0_ADC_DOUT_SHIFT; ++ ++ if (toffset & 0x100) ++ actual_temp = temp / 2 - (0x200 - toffset); ++ else ++ actual_temp = temp / 2 + toffset; ++ ++ actual_temp = actual_temp * 1000; ++ ++ } else { ++ temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> ++ ASIC_T_SHIFT; ++ ++ if (temp & 0x400) ++ actual_temp = -256; ++ else if (temp & 0x200) ++ actual_temp = 255; ++ else if (temp & 0x100) { ++ actual_temp = temp & 0x1ff; ++ actual_temp |= ~0x1ff; ++ } else ++ actual_temp = temp & 0xff; + +- return (actual_temp * 1000) / 2; ++ actual_temp = (actual_temp * 1000) / 2; ++ } ++ ++ return actual_temp; + } + + int sumo_get_temp(struct radeon_device *rdev) +@@ -1578,7 +1596,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) + u32 sq_stack_resource_mgmt_2; + u32 sq_stack_resource_mgmt_3; + u32 vgt_cache_invalidation; +- u32 hdp_host_path_cntl; ++ u32 hdp_host_path_cntl, tmp; + int i, j, num_shader_engines, ps_thread_count; + + switch (rdev->family) { +@@ -1780,7 +1798,10 @@ static void evergreen_gpu_init(struct radeon_device *rdev) + + + mc_shared_chmap = RREG32(MC_SHARED_CHMAP); +- mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); ++ if (rdev->flags & RADEON_IS_IGP) ++ mc_arb_ramcfg = RREG32(FUS_MC_ARB_RAMCFG); ++ else ++ mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); + + switch (rdev->config.evergreen.max_tile_pipes) { + case 1: +@@ -1933,8 +1954,12 @@ static void evergreen_gpu_init(struct radeon_device *rdev) + rdev->config.evergreen.tile_config |= (3 << 0); + break; + } +- rdev->config.evergreen.tile_config |= +- ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; ++ /* num banks is 8 on all fusion asics */ ++ if (rdev->flags & RADEON_IS_IGP) ++ rdev->config.evergreen.tile_config |= 8 << 4; ++ else ++ rdev->config.evergreen.tile_config |= ++ ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; + rdev->config.evergreen.tile_config |= + ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) << 8; + rdev->config.evergreen.tile_config |= +@@ -2138,6 +2163,10 @@ static void evergreen_gpu_init(struct radeon_device *rdev) + for (i = SQ_ALU_CONST_BUFFER_SIZE_HS_0; i < 0x29000; i += 4) + WREG32(i, 0); + ++ tmp = RREG32(HDP_MISC_CNTL); ++ tmp |= HDP_FLUSH_INVALIDATE_CACHE; ++ WREG32(HDP_MISC_CNTL, tmp); ++ + hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); + WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); + +diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c +index 2be698e..9c91468 100644 +--- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c ++++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c +@@ -31,6 +31,7 @@ + + #include "evergreend.h" + #include "evergreen_blit_shaders.h" ++#include "cayman_blit_shaders.h" + + #define DI_PT_RECTLIST 0x11 + #define DI_INDEX_SIZE_16_BIT 0x0 +@@ -199,6 +200,16 @@ static void + set_scissors(struct radeon_device *rdev, int x1, int y1, + int x2, int y2) + { ++ /* workaround some hw bugs */ ++ if (x2 == 0) ++ x1 = 1; ++ if (y2 == 0) ++ y1 = 1; ++ if (rdev->family == CHIP_CAYMAN) { ++ if ((x2 == 1) && (y2 == 1)) ++ x2 = 2; ++ } ++ + radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); + radeon_ring_write(rdev, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); + radeon_ring_write(rdev, (x1 << 0) | (y1 << 16)); +@@ -255,238 +266,240 @@ set_default_state(struct radeon_device *rdev) + u64 gpu_addr; + int dwords; + +- switch (rdev->family) { +- case CHIP_CEDAR: +- default: +- num_ps_gprs = 93; +- num_vs_gprs = 46; +- num_temp_gprs = 4; +- num_gs_gprs = 31; +- num_es_gprs = 31; +- num_hs_gprs = 23; +- num_ls_gprs = 23; +- num_ps_threads = 96; +- num_vs_threads = 16; +- num_gs_threads = 16; +- num_es_threads = 16; +- num_hs_threads = 16; +- num_ls_threads = 16; +- num_ps_stack_entries = 42; +- num_vs_stack_entries = 42; +- num_gs_stack_entries = 42; +- num_es_stack_entries = 42; +- num_hs_stack_entries = 42; +- num_ls_stack_entries = 42; +- break; +- case CHIP_REDWOOD: +- num_ps_gprs = 93; +- num_vs_gprs = 46; +- num_temp_gprs = 4; +- num_gs_gprs = 31; +- num_es_gprs = 31; +- num_hs_gprs = 23; +- num_ls_gprs = 23; +- num_ps_threads = 128; +- num_vs_threads = 20; +- num_gs_threads = 20; +- num_es_threads = 20; +- num_hs_threads = 20; +- num_ls_threads = 20; +- num_ps_stack_entries = 42; +- num_vs_stack_entries = 42; +- num_gs_stack_entries = 42; +- num_es_stack_entries = 42; +- num_hs_stack_entries = 42; +- num_ls_stack_entries = 42; +- break; +- case CHIP_JUNIPER: +- num_ps_gprs = 93; +- num_vs_gprs = 46; +- num_temp_gprs = 4; +- num_gs_gprs = 31; +- num_es_gprs = 31; +- num_hs_gprs = 23; +- num_ls_gprs = 23; +- num_ps_threads = 128; +- num_vs_threads = 20; +- num_gs_threads = 20; +- num_es_threads = 20; +- num_hs_threads = 20; +- num_ls_threads = 20; +- num_ps_stack_entries = 85; +- num_vs_stack_entries = 85; +- num_gs_stack_entries = 85; +- num_es_stack_entries = 85; +- num_hs_stack_entries = 85; +- num_ls_stack_entries = 85; +- break; +- case CHIP_CYPRESS: +- case CHIP_HEMLOCK: +- num_ps_gprs = 93; +- num_vs_gprs = 46; +- num_temp_gprs = 4; +- num_gs_gprs = 31; +- num_es_gprs = 31; +- num_hs_gprs = 23; +- num_ls_gprs = 23; +- num_ps_threads = 128; +- num_vs_threads = 20; +- num_gs_threads = 20; +- num_es_threads = 20; +- num_hs_threads = 20; +- num_ls_threads = 20; +- num_ps_stack_entries = 85; +- num_vs_stack_entries = 85; +- num_gs_stack_entries = 85; +- num_es_stack_entries = 85; +- num_hs_stack_entries = 85; +- num_ls_stack_entries = 85; +- break; +- case CHIP_PALM: +- num_ps_gprs = 93; +- num_vs_gprs = 46; +- num_temp_gprs = 4; +- num_gs_gprs = 31; +- num_es_gprs = 31; +- num_hs_gprs = 23; +- num_ls_gprs = 23; +- num_ps_threads = 96; +- num_vs_threads = 16; +- num_gs_threads = 16; +- num_es_threads = 16; +- num_hs_threads = 16; +- num_ls_threads = 16; +- num_ps_stack_entries = 42; +- num_vs_stack_entries = 42; +- num_gs_stack_entries = 42; +- num_es_stack_entries = 42; +- num_hs_stack_entries = 42; +- num_ls_stack_entries = 42; +- break; +- case CHIP_BARTS: +- num_ps_gprs = 93; +- num_vs_gprs = 46; +- num_temp_gprs = 4; +- num_gs_gprs = 31; +- num_es_gprs = 31; +- num_hs_gprs = 23; +- num_ls_gprs = 23; +- num_ps_threads = 128; +- num_vs_threads = 20; +- num_gs_threads = 20; +- num_es_threads = 20; +- num_hs_threads = 20; +- num_ls_threads = 20; +- num_ps_stack_entries = 85; +- num_vs_stack_entries = 85; +- num_gs_stack_entries = 85; +- num_es_stack_entries = 85; +- num_hs_stack_entries = 85; +- num_ls_stack_entries = 85; +- break; +- case CHIP_TURKS: +- num_ps_gprs = 93; +- num_vs_gprs = 46; +- num_temp_gprs = 4; +- num_gs_gprs = 31; +- num_es_gprs = 31; +- num_hs_gprs = 23; +- num_ls_gprs = 23; +- num_ps_threads = 128; +- num_vs_threads = 20; +- num_gs_threads = 20; +- num_es_threads = 20; +- num_hs_threads = 20; +- num_ls_threads = 20; +- num_ps_stack_entries = 42; +- num_vs_stack_entries = 42; +- num_gs_stack_entries = 42; +- num_es_stack_entries = 42; +- num_hs_stack_entries = 42; +- num_ls_stack_entries = 42; +- break; +- case CHIP_CAICOS: +- num_ps_gprs = 93; +- num_vs_gprs = 46; +- num_temp_gprs = 4; +- num_gs_gprs = 31; +- num_es_gprs = 31; +- num_hs_gprs = 23; +- num_ls_gprs = 23; +- num_ps_threads = 128; +- num_vs_threads = 10; +- num_gs_threads = 10; +- num_es_threads = 10; +- num_hs_threads = 10; +- num_ls_threads = 10; +- num_ps_stack_entries = 42; +- num_vs_stack_entries = 42; +- num_gs_stack_entries = 42; +- num_es_stack_entries = 42; +- num_hs_stack_entries = 42; +- num_ls_stack_entries = 42; +- break; +- } +- +- if ((rdev->family == CHIP_CEDAR) || +- (rdev->family == CHIP_PALM) || +- (rdev->family == CHIP_CAICOS)) +- sq_config = 0; +- else +- sq_config = VC_ENABLE; +- +- sq_config |= (EXPORT_SRC_C | +- CS_PRIO(0) | +- LS_PRIO(0) | +- HS_PRIO(0) | +- PS_PRIO(0) | +- VS_PRIO(1) | +- GS_PRIO(2) | +- ES_PRIO(3)); +- +- sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) | +- NUM_VS_GPRS(num_vs_gprs) | +- NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); +- sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) | +- NUM_ES_GPRS(num_es_gprs)); +- sq_gpr_resource_mgmt_3 = (NUM_HS_GPRS(num_hs_gprs) | +- NUM_LS_GPRS(num_ls_gprs)); +- sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) | +- NUM_VS_THREADS(num_vs_threads) | +- NUM_GS_THREADS(num_gs_threads) | +- NUM_ES_THREADS(num_es_threads)); +- sq_thread_resource_mgmt_2 = (NUM_HS_THREADS(num_hs_threads) | +- NUM_LS_THREADS(num_ls_threads)); +- sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) | +- NUM_VS_STACK_ENTRIES(num_vs_stack_entries)); +- sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) | +- NUM_ES_STACK_ENTRIES(num_es_stack_entries)); +- sq_stack_resource_mgmt_3 = (NUM_HS_STACK_ENTRIES(num_hs_stack_entries) | +- NUM_LS_STACK_ENTRIES(num_ls_stack_entries)); +- + /* set clear context state */ + radeon_ring_write(rdev, PACKET3(PACKET3_CLEAR_STATE, 0)); + radeon_ring_write(rdev, 0); + +- /* disable dyn gprs */ +- radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); +- radeon_ring_write(rdev, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2); +- radeon_ring_write(rdev, 0); ++ if (rdev->family < CHIP_CAYMAN) { ++ switch (rdev->family) { ++ case CHIP_CEDAR: ++ default: ++ num_ps_gprs = 93; ++ num_vs_gprs = 46; ++ num_temp_gprs = 4; ++ num_gs_gprs = 31; ++ num_es_gprs = 31; ++ num_hs_gprs = 23; ++ num_ls_gprs = 23; ++ num_ps_threads = 96; ++ num_vs_threads = 16; ++ num_gs_threads = 16; ++ num_es_threads = 16; ++ num_hs_threads = 16; ++ num_ls_threads = 16; ++ num_ps_stack_entries = 42; ++ num_vs_stack_entries = 42; ++ num_gs_stack_entries = 42; ++ num_es_stack_entries = 42; ++ num_hs_stack_entries = 42; ++ num_ls_stack_entries = 42; ++ break; ++ case CHIP_REDWOOD: ++ num_ps_gprs = 93; ++ num_vs_gprs = 46; ++ num_temp_gprs = 4; ++ num_gs_gprs = 31; ++ num_es_gprs = 31; ++ num_hs_gprs = 23; ++ num_ls_gprs = 23; ++ num_ps_threads = 128; ++ num_vs_threads = 20; ++ num_gs_threads = 20; ++ num_es_threads = 20; ++ num_hs_threads = 20; ++ num_ls_threads = 20; ++ num_ps_stack_entries = 42; ++ num_vs_stack_entries = 42; ++ num_gs_stack_entries = 42; ++ num_es_stack_entries = 42; ++ num_hs_stack_entries = 42; ++ num_ls_stack_entries = 42; ++ break; ++ case CHIP_JUNIPER: ++ num_ps_gprs = 93; ++ num_vs_gprs = 46; ++ num_temp_gprs = 4; ++ num_gs_gprs = 31; ++ num_es_gprs = 31; ++ num_hs_gprs = 23; ++ num_ls_gprs = 23; ++ num_ps_threads = 128; ++ num_vs_threads = 20; ++ num_gs_threads = 20; ++ num_es_threads = 20; ++ num_hs_threads = 20; ++ num_ls_threads = 20; ++ num_ps_stack_entries = 85; ++ num_vs_stack_entries = 85; ++ num_gs_stack_entries = 85; ++ num_es_stack_entries = 85; ++ num_hs_stack_entries = 85; ++ num_ls_stack_entries = 85; ++ break; ++ case CHIP_CYPRESS: ++ case CHIP_HEMLOCK: ++ num_ps_gprs = 93; ++ num_vs_gprs = 46; ++ num_temp_gprs = 4; ++ num_gs_gprs = 31; ++ num_es_gprs = 31; ++ num_hs_gprs = 23; ++ num_ls_gprs = 23; ++ num_ps_threads = 128; ++ num_vs_threads = 20; ++ num_gs_threads = 20; ++ num_es_threads = 20; ++ num_hs_threads = 20; ++ num_ls_threads = 20; ++ num_ps_stack_entries = 85; ++ num_vs_stack_entries = 85; ++ num_gs_stack_entries = 85; ++ num_es_stack_entries = 85; ++ num_hs_stack_entries = 85; ++ num_ls_stack_entries = 85; ++ break; ++ case CHIP_PALM: ++ num_ps_gprs = 93; ++ num_vs_gprs = 46; ++ num_temp_gprs = 4; ++ num_gs_gprs = 31; ++ num_es_gprs = 31; ++ num_hs_gprs = 23; ++ num_ls_gprs = 23; ++ num_ps_threads = 96; ++ num_vs_threads = 16; ++ num_gs_threads = 16; ++ num_es_threads = 16; ++ num_hs_threads = 16; ++ num_ls_threads = 16; ++ num_ps_stack_entries = 42; ++ num_vs_stack_entries = 42; ++ num_gs_stack_entries = 42; ++ num_es_stack_entries = 42; ++ num_hs_stack_entries = 42; ++ num_ls_stack_entries = 42; ++ break; ++ case CHIP_BARTS: ++ num_ps_gprs = 93; ++ num_vs_gprs = 46; ++ num_temp_gprs = 4; ++ num_gs_gprs = 31; ++ num_es_gprs = 31; ++ num_hs_gprs = 23; ++ num_ls_gprs = 23; ++ num_ps_threads = 128; ++ num_vs_threads = 20; ++ num_gs_threads = 20; ++ num_es_threads = 20; ++ num_hs_threads = 20; ++ num_ls_threads = 20; ++ num_ps_stack_entries = 85; ++ num_vs_stack_entries = 85; ++ num_gs_stack_entries = 85; ++ num_es_stack_entries = 85; ++ num_hs_stack_entries = 85; ++ num_ls_stack_entries = 85; ++ break; ++ case CHIP_TURKS: ++ num_ps_gprs = 93; ++ num_vs_gprs = 46; ++ num_temp_gprs = 4; ++ num_gs_gprs = 31; ++ num_es_gprs = 31; ++ num_hs_gprs = 23; ++ num_ls_gprs = 23; ++ num_ps_threads = 128; ++ num_vs_threads = 20; ++ num_gs_threads = 20; ++ num_es_threads = 20; ++ num_hs_threads = 20; ++ num_ls_threads = 20; ++ num_ps_stack_entries = 42; ++ num_vs_stack_entries = 42; ++ num_gs_stack_entries = 42; ++ num_es_stack_entries = 42; ++ num_hs_stack_entries = 42; ++ num_ls_stack_entries = 42; ++ break; ++ case CHIP_CAICOS: ++ num_ps_gprs = 93; ++ num_vs_gprs = 46; ++ num_temp_gprs = 4; ++ num_gs_gprs = 31; ++ num_es_gprs = 31; ++ num_hs_gprs = 23; ++ num_ls_gprs = 23; ++ num_ps_threads = 128; ++ num_vs_threads = 10; ++ num_gs_threads = 10; ++ num_es_threads = 10; ++ num_hs_threads = 10; ++ num_ls_threads = 10; ++ num_ps_stack_entries = 42; ++ num_vs_stack_entries = 42; ++ num_gs_stack_entries = 42; ++ num_es_stack_entries = 42; ++ num_hs_stack_entries = 42; ++ num_ls_stack_entries = 42; ++ break; ++ } + +- /* SQ config */ +- radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 11)); +- radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2); +- radeon_ring_write(rdev, sq_config); +- radeon_ring_write(rdev, sq_gpr_resource_mgmt_1); +- radeon_ring_write(rdev, sq_gpr_resource_mgmt_2); +- radeon_ring_write(rdev, sq_gpr_resource_mgmt_3); +- radeon_ring_write(rdev, 0); +- radeon_ring_write(rdev, 0); +- radeon_ring_write(rdev, sq_thread_resource_mgmt); +- radeon_ring_write(rdev, sq_thread_resource_mgmt_2); +- radeon_ring_write(rdev, sq_stack_resource_mgmt_1); +- radeon_ring_write(rdev, sq_stack_resource_mgmt_2); +- radeon_ring_write(rdev, sq_stack_resource_mgmt_3); ++ if ((rdev->family == CHIP_CEDAR) || ++ (rdev->family == CHIP_PALM) || ++ (rdev->family == CHIP_CAICOS)) ++ sq_config = 0; ++ else ++ sq_config = VC_ENABLE; ++ ++ sq_config |= (EXPORT_SRC_C | ++ CS_PRIO(0) | ++ LS_PRIO(0) | ++ HS_PRIO(0) | ++ PS_PRIO(0) | ++ VS_PRIO(1) | ++ GS_PRIO(2) | ++ ES_PRIO(3)); ++ ++ sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) | ++ NUM_VS_GPRS(num_vs_gprs) | ++ NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); ++ sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) | ++ NUM_ES_GPRS(num_es_gprs)); ++ sq_gpr_resource_mgmt_3 = (NUM_HS_GPRS(num_hs_gprs) | ++ NUM_LS_GPRS(num_ls_gprs)); ++ sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) | ++ NUM_VS_THREADS(num_vs_threads) | ++ NUM_GS_THREADS(num_gs_threads) | ++ NUM_ES_THREADS(num_es_threads)); ++ sq_thread_resource_mgmt_2 = (NUM_HS_THREADS(num_hs_threads) | ++ NUM_LS_THREADS(num_ls_threads)); ++ sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) | ++ NUM_VS_STACK_ENTRIES(num_vs_stack_entries)); ++ sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) | ++ NUM_ES_STACK_ENTRIES(num_es_stack_entries)); ++ sq_stack_resource_mgmt_3 = (NUM_HS_STACK_ENTRIES(num_hs_stack_entries) | ++ NUM_LS_STACK_ENTRIES(num_ls_stack_entries)); ++ ++ /* disable dyn gprs */ ++ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); ++ radeon_ring_write(rdev, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2); ++ radeon_ring_write(rdev, 0); ++ ++ /* SQ config */ ++ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 11)); ++ radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2); ++ radeon_ring_write(rdev, sq_config); ++ radeon_ring_write(rdev, sq_gpr_resource_mgmt_1); ++ radeon_ring_write(rdev, sq_gpr_resource_mgmt_2); ++ radeon_ring_write(rdev, sq_gpr_resource_mgmt_3); ++ radeon_ring_write(rdev, 0); ++ radeon_ring_write(rdev, 0); ++ radeon_ring_write(rdev, sq_thread_resource_mgmt); ++ radeon_ring_write(rdev, sq_thread_resource_mgmt_2); ++ radeon_ring_write(rdev, sq_stack_resource_mgmt_1); ++ radeon_ring_write(rdev, sq_stack_resource_mgmt_2); ++ radeon_ring_write(rdev, sq_stack_resource_mgmt_3); ++ } + + /* CONTEXT_CONTROL */ + radeon_ring_write(rdev, 0xc0012800); +@@ -560,7 +573,10 @@ int evergreen_blit_init(struct radeon_device *rdev) + mutex_init(&rdev->r600_blit.mutex); + rdev->r600_blit.state_offset = 0; + +- rdev->r600_blit.state_len = evergreen_default_size; ++ if (rdev->family < CHIP_CAYMAN) ++ rdev->r600_blit.state_len = evergreen_default_size; ++ else ++ rdev->r600_blit.state_len = cayman_default_size; + + dwords = rdev->r600_blit.state_len; + while (dwords & 0xf) { +@@ -572,11 +588,17 @@ int evergreen_blit_init(struct radeon_device *rdev) + obj_size = ALIGN(obj_size, 256); + + rdev->r600_blit.vs_offset = obj_size; +- obj_size += evergreen_vs_size * 4; ++ if (rdev->family < CHIP_CAYMAN) ++ obj_size += evergreen_vs_size * 4; ++ else ++ obj_size += cayman_vs_size * 4; + obj_size = ALIGN(obj_size, 256); + + rdev->r600_blit.ps_offset = obj_size; +- obj_size += evergreen_ps_size * 4; ++ if (rdev->family < CHIP_CAYMAN) ++ obj_size += evergreen_ps_size * 4; ++ else ++ obj_size += cayman_ps_size * 4; + obj_size = ALIGN(obj_size, 256); + + r = radeon_bo_create(rdev, NULL, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, +@@ -599,16 +621,29 @@ int evergreen_blit_init(struct radeon_device *rdev) + return r; + } + +- memcpy_toio(ptr + rdev->r600_blit.state_offset, +- evergreen_default_state, rdev->r600_blit.state_len * 4); +- +- if (num_packet2s) +- memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), +- packet2s, num_packet2s * 4); +- for (i = 0; i < evergreen_vs_size; i++) +- *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(evergreen_vs[i]); +- for (i = 0; i < evergreen_ps_size; i++) +- *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(evergreen_ps[i]); ++ if (rdev->family < CHIP_CAYMAN) { ++ memcpy_toio(ptr + rdev->r600_blit.state_offset, ++ evergreen_default_state, rdev->r600_blit.state_len * 4); ++ ++ if (num_packet2s) ++ memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), ++ packet2s, num_packet2s * 4); ++ for (i = 0; i < evergreen_vs_size; i++) ++ *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(evergreen_vs[i]); ++ for (i = 0; i < evergreen_ps_size; i++) ++ *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(evergreen_ps[i]); ++ } else { ++ memcpy_toio(ptr + rdev->r600_blit.state_offset, ++ cayman_default_state, rdev->r600_blit.state_len * 4); ++ ++ if (num_packet2s) ++ memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), ++ packet2s, num_packet2s * 4); ++ for (i = 0; i < cayman_vs_size; i++) ++ *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(cayman_vs[i]); ++ for (i = 0; i < cayman_ps_size; i++) ++ *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(cayman_ps[i]); ++ } + radeon_bo_kunmap(rdev->r600_blit.shader_obj); + radeon_bo_unreserve(rdev->r600_blit.shader_obj); + +diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h +index 9453384..1636e34 100644 +--- a/drivers/gpu/drm/radeon/evergreend.h ++++ b/drivers/gpu/drm/radeon/evergreend.h +@@ -64,6 +64,8 @@ + #define GB_BACKEND_MAP 0x98FC + #define DMIF_ADDR_CONFIG 0xBD4 + #define HDP_ADDR_CONFIG 0x2F48 ++#define HDP_MISC_CNTL 0x2F4C ++#define HDP_FLUSH_INVALIDATE_CACHE (1 << 0) + + #define CC_SYS_RB_BACKEND_DISABLE 0x3F88 + #define GC_USER_RB_BACKEND_DISABLE 0x9B7C +@@ -166,10 +168,16 @@ + #define SE_DB_BUSY (1 << 30) + #define SE_CB_BUSY (1 << 31) + /* evergreen */ ++#define CG_THERMAL_CTRL 0x72c ++#define TOFFSET_MASK 0x00003FE0 ++#define TOFFSET_SHIFT 5 + #define CG_MULT_THERMAL_STATUS 0x740 + #define ASIC_T(x) ((x) << 16) +-#define ASIC_T_MASK 0x7FF0000 ++#define ASIC_T_MASK 0x07FF0000 + #define ASIC_T_SHIFT 16 ++#define CG_TS0_STATUS 0x760 ++#define TS0_ADC_DOUT_MASK 0x000003FF ++#define TS0_ADC_DOUT_SHIFT 0 + /* APU */ + #define CG_THERMAL_STATUS 0x678 + +@@ -200,6 +208,7 @@ + #define BURSTLENGTH_SHIFT 9 + #define BURSTLENGTH_MASK 0x00000200 + #define CHANSIZE_OVERRIDE (1 << 11) ++#define FUS_MC_ARB_RAMCFG 0x2768 + #define MC_VM_AGP_TOP 0x2028 + #define MC_VM_AGP_BOT 0x202C + #define MC_VM_AGP_BASE 0x2030 +diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c +index 8c199c4..b226cca 100644 +--- a/drivers/gpu/drm/radeon/ni.c ++++ b/drivers/gpu/drm/radeon/ni.c +@@ -417,7 +417,7 @@ static u32 cayman_get_tile_pipe_to_backend_map(struct radeon_device *rdev, + num_shader_engines = 1; + if (num_shader_engines > rdev->config.cayman.max_shader_engines) + num_shader_engines = rdev->config.cayman.max_shader_engines; +- if (num_backends_per_asic > num_shader_engines) ++ if (num_backends_per_asic < num_shader_engines) + num_backends_per_asic = num_shader_engines; + if (num_backends_per_asic > (rdev->config.cayman.max_backends_per_se * num_shader_engines)) + num_backends_per_asic = rdev->config.cayman.max_backends_per_se * num_shader_engines; +@@ -674,7 +674,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) + + cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE); + cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG); +- cgts_tcc_disable = RREG32(CGTS_TCC_DISABLE); ++ cgts_tcc_disable = 0xff000000; + gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE); + gc_user_shader_pipe_config = RREG32(GC_USER_SHADER_PIPE_CONFIG); + cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE); +@@ -829,7 +829,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) + rdev->config.cayman.tile_config |= + ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; + rdev->config.cayman.tile_config |= +- (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT; ++ ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; + rdev->config.cayman.tile_config |= + ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; + +@@ -871,7 +871,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) + + smx_dc_ctl0 = RREG32(SMX_DC_CTL0); + smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff); +- smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets); ++ smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets); + WREG32(SMX_DC_CTL0, smx_dc_ctl0); + + WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE); +@@ -887,20 +887,20 @@ static void cayman_gpu_init(struct radeon_device *rdev) + + WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO); + +- WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) | +- POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) | +- SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1))); ++ WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) | ++ POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) | ++ SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1))); + +- WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.evergreen.sc_prim_fifo_size) | +- SC_HIZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_hiz_tile_fifo_size) | +- SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_earlyz_tile_fifo_size))); ++ WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) | ++ SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) | ++ SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size))); + + + WREG32(VGT_NUM_INSTANCES, 1); + + WREG32(CP_PERFMON_CNTL, 0); + +- WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.evergreen.sq_num_cf_insts) | ++ WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) | + FETCH_FIFO_HIWATER(0x4) | + DONE_FIFO_HIWATER(0xe0) | + ALU_UPDATE_FIFO_HIWATER(0x8))); +@@ -931,6 +931,10 @@ static void cayman_gpu_init(struct radeon_device *rdev) + WREG32(CB_PERF_CTR3_SEL_0, 0); + WREG32(CB_PERF_CTR3_SEL_1, 0); + ++ tmp = RREG32(HDP_MISC_CNTL); ++ tmp |= HDP_FLUSH_INVALIDATE_CACHE; ++ WREG32(HDP_MISC_CNTL, tmp); ++ + hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); + WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); + +@@ -1383,14 +1387,12 @@ static int cayman_startup(struct radeon_device *rdev) + return r; + cayman_gpu_init(rdev); + +-#if 0 +- r = cayman_blit_init(rdev); ++ r = evergreen_blit_init(rdev); + if (r) { +- cayman_blit_fini(rdev); ++ evergreen_blit_fini(rdev); + rdev->asic->copy = NULL; + dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); + } +-#endif + + /* allocate wb buffer */ + r = radeon_wb_init(rdev); +@@ -1448,7 +1450,7 @@ int cayman_resume(struct radeon_device *rdev) + + int cayman_suspend(struct radeon_device *rdev) + { +- /* int r; */ ++ int r; + + /* FIXME: we should wait for ring to be empty */ + cayman_cp_enable(rdev, false); +@@ -1457,14 +1459,13 @@ int cayman_suspend(struct radeon_device *rdev) + radeon_wb_disable(rdev); + cayman_pcie_gart_disable(rdev); + +-#if 0 + /* unpin shaders bo */ + r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); + if (likely(r == 0)) { + radeon_bo_unpin(rdev->r600_blit.shader_obj); + radeon_bo_unreserve(rdev->r600_blit.shader_obj); + } +-#endif ++ + return 0; + } + +@@ -1576,7 +1577,7 @@ int cayman_init(struct radeon_device *rdev) + + void cayman_fini(struct radeon_device *rdev) + { +- /* cayman_blit_fini(rdev); */ ++ evergreen_blit_fini(rdev); + cayman_cp_fini(rdev); + r600_irq_fini(rdev); + radeon_wb_fini(rdev); +diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h +index 0f9a08b..9736746 100644 +--- a/drivers/gpu/drm/radeon/nid.h ++++ b/drivers/gpu/drm/radeon/nid.h +@@ -136,6 +136,8 @@ + #define HDP_NONSURFACE_INFO 0x2C08 + #define HDP_NONSURFACE_SIZE 0x2C0C + #define HDP_ADDR_CONFIG 0x2F48 ++#define HDP_MISC_CNTL 0x2F4C ++#define HDP_FLUSH_INVALIDATE_CACHE (1 << 0) + + #define CC_SYS_RB_BACKEND_DISABLE 0x3F88 + #define GC_USER_SYS_RB_BACKEND_DISABLE 0x3F8C +@@ -351,7 +353,7 @@ + #define MULTI_GPU_TILE_SIZE_MASK 0x03000000 + #define MULTI_GPU_TILE_SIZE_SHIFT 24 + #define ROW_SIZE(x) ((x) << 28) +-#define ROW_SIZE_MASK 0x30000007 ++#define ROW_SIZE_MASK 0x30000000 + #define ROW_SIZE_SHIFT 28 + #define NUM_LOWER_PIPES(x) ((x) << 30) + #define NUM_LOWER_PIPES_MASK 0x40000000 +diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c +index ca57619..b9b3c2a 100644 +--- a/drivers/gpu/drm/radeon/radeon_asic.c ++++ b/drivers/gpu/drm/radeon/radeon_asic.c +@@ -782,6 +782,7 @@ static struct radeon_asic evergreen_asic = { + .hpd_fini = &evergreen_hpd_fini, + .hpd_sense = &evergreen_hpd_sense, + .hpd_set_polarity = &evergreen_hpd_set_polarity, ++ .ioctl_wait_idle = r600_ioctl_wait_idle, + .gui_idle = &r600_gui_idle, + .pm_misc = &evergreen_pm_misc, + .pm_prepare = &evergreen_pm_prepare, +@@ -828,6 +829,7 @@ static struct radeon_asic sumo_asic = { + .hpd_fini = &evergreen_hpd_fini, + .hpd_sense = &evergreen_hpd_sense, + .hpd_set_polarity = &evergreen_hpd_set_polarity, ++ .ioctl_wait_idle = r600_ioctl_wait_idle, + .gui_idle = &r600_gui_idle, + .pm_misc = &evergreen_pm_misc, + .pm_prepare = &evergreen_pm_prepare, +@@ -874,6 +876,7 @@ static struct radeon_asic btc_asic = { + .hpd_fini = &evergreen_hpd_fini, + .hpd_sense = &evergreen_hpd_sense, + .hpd_set_polarity = &evergreen_hpd_set_polarity, ++ .ioctl_wait_idle = r600_ioctl_wait_idle, + .gui_idle = &r600_gui_idle, + .pm_misc = &evergreen_pm_misc, + .pm_prepare = &evergreen_pm_prepare, +@@ -903,9 +906,9 @@ static struct radeon_asic cayman_asic = { + .get_vblank_counter = &evergreen_get_vblank_counter, + .fence_ring_emit = &r600_fence_ring_emit, + .cs_parse = &evergreen_cs_parse, +- .copy_blit = NULL, +- .copy_dma = NULL, +- .copy = NULL, ++ .copy_blit = &evergreen_copy_blit, ++ .copy_dma = &evergreen_copy_blit, ++ .copy = &evergreen_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, + .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, +@@ -920,6 +923,7 @@ static struct radeon_asic cayman_asic = { + .hpd_fini = &evergreen_hpd_fini, + .hpd_sense = &evergreen_hpd_sense, + .hpd_set_polarity = &evergreen_hpd_set_polarity, ++ .ioctl_wait_idle = r600_ioctl_wait_idle, + .gui_idle = &r600_gui_idle, + .pm_misc = &evergreen_pm_misc, + .pm_prepare = &evergreen_pm_prepare, +diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c +index ed5dfe5..9d95792 100644 +--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c ++++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c +@@ -15,6 +15,9 @@ + #define ATPX_VERSION 0 + #define ATPX_GPU_PWR 2 + #define ATPX_MUX_SELECT 3 ++#define ATPX_I2C_MUX_SELECT 4 ++#define ATPX_SWITCH_START 5 ++#define ATPX_SWITCH_END 6 + + #define ATPX_INTEGRATED 0 + #define ATPX_DISCRETE 1 +@@ -149,13 +152,35 @@ static int radeon_atpx_switch_mux(acpi_handle handle, int mux_id) + return radeon_atpx_execute(handle, ATPX_MUX_SELECT, mux_id); + } + ++static int radeon_atpx_switch_i2c_mux(acpi_handle handle, int mux_id) ++{ ++ return radeon_atpx_execute(handle, ATPX_I2C_MUX_SELECT, mux_id); ++} ++ ++static int radeon_atpx_switch_start(acpi_handle handle, int gpu_id) ++{ ++ return radeon_atpx_execute(handle, ATPX_SWITCH_START, gpu_id); ++} ++ ++static int radeon_atpx_switch_end(acpi_handle handle, int gpu_id) ++{ ++ return radeon_atpx_execute(handle, ATPX_SWITCH_END, gpu_id); ++} + + static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) + { ++ int gpu_id; ++ + if (id == VGA_SWITCHEROO_IGD) +- radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 0); ++ gpu_id = ATPX_INTEGRATED; + else +- radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 1); ++ gpu_id = ATPX_DISCRETE; ++ ++ radeon_atpx_switch_start(radeon_atpx_priv.atpx_handle, gpu_id); ++ radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, gpu_id); ++ radeon_atpx_switch_i2c_mux(radeon_atpx_priv.atpx_handle, gpu_id); ++ radeon_atpx_switch_end(radeon_atpx_priv.atpx_handle, gpu_id); ++ + return 0; + } + +diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c +index 8caf546..089ab92 100644 +--- a/drivers/gpu/drm/radeon/radeon_combios.c ++++ b/drivers/gpu/drm/radeon/radeon_combios.c +@@ -2504,6 +2504,12 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) + return true; + } + ++static const char *thermal_controller_names[] = { ++ "NONE", ++ "lm63", ++ "adm1032", ++}; ++ + void radeon_combios_get_power_modes(struct radeon_device *rdev) + { + struct drm_device *dev = rdev->ddev; +@@ -2524,6 +2530,54 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) + return; + } + ++ /* check for a thermal chip */ ++ offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE); ++ if (offset) { ++ u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0; ++ struct radeon_i2c_bus_rec i2c_bus; ++ ++ rev = RBIOS8(offset); ++ ++ if (rev == 0) { ++ thermal_controller = RBIOS8(offset + 3); ++ gpio = RBIOS8(offset + 4) & 0x3f; ++ i2c_addr = RBIOS8(offset + 5); ++ } else if (rev == 1) { ++ thermal_controller = RBIOS8(offset + 4); ++ gpio = RBIOS8(offset + 5) & 0x3f; ++ i2c_addr = RBIOS8(offset + 6); ++ } else if (rev == 2) { ++ thermal_controller = RBIOS8(offset + 4); ++ gpio = RBIOS8(offset + 5) & 0x3f; ++ i2c_addr = RBIOS8(offset + 6); ++ clk_bit = RBIOS8(offset + 0xa); ++ data_bit = RBIOS8(offset + 0xb); ++ } ++ if ((thermal_controller > 0) && (thermal_controller < 3)) { ++ DRM_INFO("Possible %s thermal controller at 0x%02x\n", ++ thermal_controller_names[thermal_controller], ++ i2c_addr >> 1); ++ if (gpio == DDC_LCD) { ++ /* MM i2c */ ++ i2c_bus.valid = true; ++ i2c_bus.hw_capable = true; ++ i2c_bus.mm_i2c = true; ++ i2c_bus.i2c_id = 0xa0; ++ } else if (gpio == DDC_GPIO) ++ i2c_bus = combios_setup_i2c_bus(rdev, gpio, 1 << clk_bit, 1 << data_bit); ++ else ++ i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0); ++ rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); ++ if (rdev->pm.i2c_bus) { ++ struct i2c_board_info info = { }; ++ const char *name = thermal_controller_names[thermal_controller]; ++ info.addr = i2c_addr >> 1; ++ strlcpy(info.type, name, sizeof(info.type)); ++ i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); ++ } ++ } ++ } ++ + if (rdev->flags & RADEON_IS_MOBILITY) { + offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE); + if (offset) { +diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c +index 017ac54..5df2acd 100644 +--- a/drivers/gpu/drm/radeon/radeon_cursor.c ++++ b/drivers/gpu/drm/radeon/radeon_cursor.c +@@ -167,9 +167,6 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, + return -EINVAL; + } + +- radeon_crtc->cursor_width = width; +- radeon_crtc->cursor_height = height; +- + obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); + if (!obj) { + DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); +@@ -180,6 +177,9 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, + if (ret) + goto fail; + ++ radeon_crtc->cursor_width = width; ++ radeon_crtc->cursor_height = height; ++ + radeon_lock_cursor(crtc, true); + /* XXX only 27 bit offset for legacy cursor */ + radeon_set_cursor(crtc, obj, gpu_addr); +diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c +index 0444911..fc44376 100644 +--- a/drivers/gpu/drm/radeon/radeon_drv.c ++++ b/drivers/gpu/drm/radeon/radeon_drv.c +@@ -50,9 +50,10 @@ + * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs + * 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK, clock crystal query + * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query ++ * 2.10.0 - fusion 2D tiling + */ + #define KMS_DRIVER_MAJOR 2 +-#define KMS_DRIVER_MINOR 9 ++#define KMS_DRIVER_MINOR 10 + #define KMS_DRIVER_PATCHLEVEL 0 + int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); + int radeon_driver_unload_kms(struct drm_device *dev); +diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c +index 320ddc3..4fec348 100644 +--- a/drivers/gpu/drm/radeon/radeon_pm.c ++++ b/drivers/gpu/drm/radeon/radeon_pm.c +@@ -485,6 +485,7 @@ static int radeon_hwmon_init(struct radeon_device *rdev) + case THERMAL_TYPE_RV6XX: + case THERMAL_TYPE_RV770: + case THERMAL_TYPE_EVERGREEN: ++ case THERMAL_TYPE_NI: + case THERMAL_TYPE_SUMO: + rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev); + if (IS_ERR(rdev->pm.int_hwmon_dev)) { +diff --git a/drivers/gpu/drm/radeon/reg_srcs/cayman b/drivers/gpu/drm/radeon/reg_srcs/cayman +index 6334f8a..0aa8e85 100644 +--- a/drivers/gpu/drm/radeon/reg_srcs/cayman ++++ b/drivers/gpu/drm/radeon/reg_srcs/cayman +@@ -33,6 +33,7 @@ cayman 0x9400 + 0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS + 0x00009100 SPI_CONFIG_CNTL + 0x0000913C SPI_CONFIG_CNTL_1 ++0x00009508 TA_CNTL_AUX + 0x00009830 DB_DEBUG + 0x00009834 DB_DEBUG2 + 0x00009838 DB_DEBUG3 +diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen +index 7e16371..0e28cae 100644 +--- a/drivers/gpu/drm/radeon/reg_srcs/evergreen ++++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen +@@ -46,6 +46,7 @@ evergreen 0x9400 + 0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS + 0x00009100 SPI_CONFIG_CNTL + 0x0000913C SPI_CONFIG_CNTL_1 ++0x00009508 TA_CNTL_AUX + 0x00009700 VC_CNTL + 0x00009714 VC_ENHANCE + 0x00009830 DB_DEBUG diff --git a/freed-ora/current/f15/hid-multitouch-add-support-for-elo-touchsystems.patch b/freed-ora/current/f15/hid-multitouch-add-support-for-elo-touchsystems.patch new file mode 100644 index 000000000..1294f4630 --- /dev/null +++ b/freed-ora/current/f15/hid-multitouch-add-support-for-elo-touchsystems.patch @@ -0,0 +1,78 @@ +From: Benjamin Tissoires <benjamin.tissoires@enac.fr> +Date: Thu, 19 May 2011 09:37:29 +0000 (+0200) +Subject: HID: hid-multitouch: add support for Elo TouchSystems 2515 IntelliTouch Plus +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjikos%2Fhid.git;a=commitdiff_plain;h=c04abeeff9d76a703cac1e6d312853b0fc8136f5 + +HID: hid-multitouch: add support for Elo TouchSystems 2515 IntelliTouch Plus + +This patch adds support for Elo TouchSystems 2515 IntelliTouch Plus +that can be found in Lenovo A700 all-in-one. + +Signed-off-by: Benjamin Tissoires <benjamin.tissoires@enac.fr> +Tested-by: Bastien Nocera <hadess@hadess.net> +Signed-off-by: Jiri Kosina <jkosina@suse.cz> + +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -309,6 +309,7 @@ config HID_MULTITOUCH + + Say Y here if you have one of the following devices: + - Cypress TrueTouch panels ++ - Elo TouchSystems IntelliTouch Plus panels + - Hanvon dual touch panels + - Pixcir dual touch panels + - 'Sensing Win7-TwoFinger' panel by GeneralTouch +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1335,6 +1335,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2515) }, + { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, + { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, + { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -219,6 +219,7 @@ + #define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 + + #define USB_VENDOR_ID_ELO 0x04E7 ++#define USB_DEVICE_ID_ELO_TS2515 0x0022 + #define USB_DEVICE_ID_ELO_TS2700 0x0020 + + #define USB_VENDOR_ID_EMS 0x2006 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -69,6 +69,7 @@ struct mt_class { + #define MT_CLS_DUAL1 2 + #define MT_CLS_DUAL2 3 + #define MT_CLS_CYPRESS 4 ++#define MT_CLS_DUAL_NSMU_CONTACTID 5 + + /* + * these device-dependent functions determine what slot corresponds +@@ -119,6 +120,11 @@ struct mt_class mt_classes[] = { + MT_QUIRK_CYPRESS, + .maxcontacts = 10 }, + ++ { .name = MT_CLS_DUAL_NSMU_CONTACTID, ++ .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | ++ MT_QUIRK_SLOT_IS_CONTACTID, ++ .maxcontacts = 2 }, ++ + { } + }; + +@@ -465,6 +471,11 @@ static const struct hid_device_id mt_devices[] = { + HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, + USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, + ++ /* Elo TouchSystems IntelliTouch Plus panel */ ++ { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID, ++ HID_USB_DEVICE(USB_VENDOR_ID_ELO, ++ USB_DEVICE_ID_ELO_TS2515) }, ++ + /* GeneralTouch panel */ + { .driver_data = MT_CLS_DUAL2, + HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, diff --git a/freed-ora/current/f15/kernel.spec b/freed-ora/current/f15/kernel.spec index 1562f55df..2b3ea4b4b 100644 --- a/freed-ora/current/f15/kernel.spec +++ b/freed-ora/current/f15/kernel.spec @@ -51,7 +51,7 @@ Summary: The Linux kernel # For non-released -rc kernels, this will be prepended with "0.", so # for example a 3 here will become 0.3 # -%global baserelease 28 +%global baserelease 30 %global fedora_build %{baserelease} # base_sublevel is the kernel version we're starting with and patching @@ -79,7 +79,7 @@ Summary: The Linux kernel # Do we have a -stable update to apply? %define stable_update 7 # Is it a -stable RC? -%define stable_rc 1 +%define stable_rc 0 # Set rpm version accordingly %if 0%{?stable_update} %define stablerev .%{stable_update} @@ -710,6 +710,7 @@ Patch1829: drm-intel-restore-mode.patch # radeon - new hw + fixes for fusion and t500 regression Patch1839: drm-radeon-fix-regression-on-atom-cards-with-hardcoded-EDID-record.patch Patch1840: drm-radeon-update.patch +Patch1841: drm-radeon-update2.patch Patch1900: linux-2.6-intel-iommu-igfx.patch @@ -772,6 +773,14 @@ Patch12407: scsi_dh_hp_sw-fix-deadlock-in-start_stop_endio.patch # temporary fix for Sempron machines stalling (#704059) Patch12408: x86-amd-arat-bug-on-sempron-workaround.patch +# Eliminate hangs when using frequent high-order allocations V4 +# (will be in 2.6.38.8) +Patch12410: mm-vmscan-correct-use-of-pgdat_balanced-in-sleeping_prematurely.patch +Patch12411: mm-vmscan-correctly-check-if-reclaimer-should-schedule-during-shrink_slab.patch + +Patch12415: hid-multitouch-add-support-for-elo-touchsystems.patch +Patch12416: bluetooth-device-ids-for-ath3k-on-pegatron-lucid-tablets.patch + %endif BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root @@ -1390,6 +1399,7 @@ ApplyPatch drm-intel-restore-mode.patch # radeon DRM (add cayman support) ApplyPatch drm-radeon-fix-regression-on-atom-cards-with-hardcoded-EDID-record.patch -R ApplyPatch drm-radeon-update.patch +ApplyPatch drm-radeon-update2.patch # linux1394 git patches #ApplyPatch linux-2.6-firewire-git-update.patch @@ -1445,6 +1455,14 @@ ApplyPatch scsi_dh_hp_sw-fix-deadlock-in-start_stop_endio.patch # temporary fix for Sempron machines stalling (#704059) ApplyPatch x86-amd-arat-bug-on-sempron-workaround.patch +# Eliminate hangs when using frequent high-order allocations V4 +# (will be in 2.6.38.8) +ApplyPatch mm-vmscan-correct-use-of-pgdat_balanced-in-sleeping_prematurely.patch +ApplyPatch mm-vmscan-correctly-check-if-reclaimer-should-schedule-during-shrink_slab.patch + +ApplyPatch hid-multitouch-add-support-for-elo-touchsystems.patch +ApplyPatch bluetooth-device-ids-for-ath3k-on-pegatron-lucid-tablets.patch + # END OF PATCH APPLICATIONS %endif @@ -2053,6 +2071,24 @@ fi # and build. %changelog +* Fri May 27 2011 Ben Skeggs <bskeggs@redhat.com> 2.6.38.7-30 +- nouveau: minor fixes for various issues from upstream +- nv40 modesetting fix (rhbz#708235) +- nv50+ support for LVDS panels using SPWG spec (blank/corrupt screen fixes) +- nva3+ pm clock get/set fixes + +* Wed May 25 2011 Dave Airlie <airlied@redhat.com> +- drm-radeon-update2.patch: more radeon updates + cayman accel support + +* Tue May 24 2011 Kyle McMartin <kmcmartin@redhat.com> +- hid-multitouch: add support for elo touchsystems panels (requested + by hadess, backported from hid-next) +- bluetooth: add support for more ath3k devices (Ditto.) + +* Mon May 23 2011 Chuck Ebbert <cebbert@redhat.com> 2.6.38.7-29 +- Linux 2.6.38.7 +- Eliminate hangs when using frequent high-order allocations + * Fri May 20 2011 Chuck Ebbert <cebbert@redhat.com> 2.6.38.7-28.rc1 - Linux 2.6.38.7-rc1 - Fix up context in utrace-ptrace.patch diff --git a/freed-ora/current/f15/mm-vmscan-correct-use-of-pgdat_balanced-in-sleeping_prematurely.patch b/freed-ora/current/f15/mm-vmscan-correct-use-of-pgdat_balanced-in-sleeping_prematurely.patch new file mode 100644 index 000000000..a619a59ad --- /dev/null +++ b/freed-ora/current/f15/mm-vmscan-correct-use-of-pgdat_balanced-in-sleeping_prematurely.patch @@ -0,0 +1,114 @@ +Return-Path: stable-bounces@linux.kernel.org +Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO + zmta03.collab.prod.int.phx2.redhat.com) (10.5.5.33) by + mail02.corp.redhat.com with LMTP; Mon, 23 May 2011 05:54:46 -0400 (EDT) +Received: from localhost (localhost.localdomain [127.0.0.1]) + by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 3139D4E5E6 + for <cebbert@redhat.com>; Mon, 23 May 2011 05:54:46 -0400 (EDT) +Received: from zmta03.collab.prod.int.phx2.redhat.com ([127.0.0.1]) + by localhost (zmta03.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id Xko2+8bJJ7po for <cebbert@redhat.com>; + Mon, 23 May 2011 05:54:46 -0400 (EDT) +Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) + by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 1A5854D284 + for <cebbert@mail.corp.redhat.com>; Mon, 23 May 2011 05:54:46 -0400 (EDT) +Received: from mx1.redhat.com (ext-mx13.extmail.prod.ext.phx2.redhat.com [10.5.110.18]) + by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p4N9sjdi005829 + for <cebbert@redhat.com>; Mon, 23 May 2011 05:54:45 -0400 +Received: from hera.kernel.org (hera.kernel.org [140.211.167.34]) + by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p4N9siLf018408 + for <cebbert@redhat.com>; Mon, 23 May 2011 05:54:45 -0400 +Received: from hera.kernel.org (localhost [127.0.0.1]) + by hera.kernel.org (8.14.4/8.14.3) with ESMTP id p4N9s7Yv010104; + Mon, 23 May 2011 09:54:09 GMT +X-Virus-Status: Clean +X-Virus-Scanned: clamav-milter 0.97 at hera.kernel.org +Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) + by hera.kernel.org (8.14.4/8.14.3) with ESMTP id p4N9s1LC009736; + Mon, 23 May 2011 09:54:02 GMT +X-Virus-Status: Clean +X-Virus-Scanned: clamav-milter 0.97 at hera.kernel.org +Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) + by mx2.suse.de (Postfix) with ESMTP id 98E7590072; + Mon, 23 May 2011 11:53:59 +0200 (CEST) +From: Mel Gorman <mgorman@suse.de> +To: Andrew Morton <akpm@linux-foundation.org> +Date: Mon, 23 May 2011 10:53:54 +0100 +Message-Id: <1306144435-2516-2-git-send-email-mgorman@suse.de> +In-Reply-To: <1306144435-2516-1-git-send-email-mgorman@suse.de> +References: <1306144435-2516-1-git-send-email-mgorman@suse.de> +X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED + autolearn=unavailable version=3.3.2-r929478 +X-Spam-Checker-Version: SpamAssassin 3.3.2-r929478 (2010-03-31) on + hera.kernel.org +X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.2.3 (hera.kernel.org [127.0.0.1]); Mon, 23 May 2011 09:54:12 +0000 (UTC) +X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by + milter-greylist-4.2.3 (hera.kernel.org [140.211.167.34]); + Mon, 23 May 2011 09:54:04 +0000 (UTC) +Cc: Pekka Enberg <penberg@kernel.org>, Rik van Riel <riel@redhat.com>, + Jan Kara <jack@suse.cz>, linux-kernel <linux-kernel@vger.kernel.org>, + James Bottomley <James.Bottomley@HansenPartnership.com>, + linux-mm <linux-mm@kvack.org>, Minchan Kim <minchan.kim@gmail.com>, + Raghavendra D Prabhu <raghu.prabhu13@gmail.com>, + Johannes Weiner <hannes@cmpxchg.org>, + linux-fsdevel <linux-fsdevel@vger.kernel.org>, + Colin King <colin.king@canonical.com>, + Christoph Lameter <cl@linux.com>, + linux-ext4 <linux-ext4@vger.kernel.org>, stable <stable@kernel.org>, + Chris Mason <chris.mason@oracle.com>, Mel Gorman <mgorman@suse.de> +Subject: [stable] [PATCH 1/2] mm: vmscan: Correct use of pgdat_balanced in + sleeping_prematurely +X-BeenThere: stable@linux.kernel.org +X-Mailman-Version: 2.1.12 +Precedence: list +List-Id: For maintainers of the stable Linux series <stable.linux.kernel.org> +List-Unsubscribe: <http://linux.kernel.org/mailman/options/stable>, + <mailto:stable-request@linux.kernel.org?subject=unsubscribe> +List-Archive: <http://linux.kernel.org/mailman/private/stable/> +List-Post: <mailto:stable@linux.kernel.org> +List-Help: <mailto:stable-request@linux.kernel.org?subject=help> +List-Subscribe: <http://linux.kernel.org/mailman/listinfo/stable>, + <mailto:stable-request@linux.kernel.org?subject=subscribe> +MIME-Version: 1.0 +Content-Type: text/plain; charset="us-ascii" +Content-Transfer-Encoding: 7bit +Sender: stable-bounces@linux.kernel.org +Errors-To: stable-bounces@linux.kernel.org +X-RedHat-Spam-Score: -2.31 (RCVD_IN_DNSWL_MED,T_RP_MATCHES_RCVD) +X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 +X-Scanned-By: MIMEDefang 2.68 on 10.5.110.18 + +From: Johannes Weiner <hannes@cmpxchg.org> + +Johannes Weiner poined out that the logic in commit [1741c877: mm: +kswapd: keep kswapd awake for high-order allocations until a percentage +of the node is balanced] is backwards. Instead of allowing kswapd to go +to sleep when balancing for high order allocations, it keeps it kswapd +running uselessly. + +Signed-off-by: Mel Gorman <mgorman@suse.de> +Reviewed-by: Rik van Riel <riel@redhat.com> +--- + mm/vmscan.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/mm/vmscan.c b/mm/vmscan.c +index 8bfd450..1aa262b 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -2286,7 +2286,7 @@ static bool sleeping_prematurely(pg_data_t *pgdat, int order, long remaining, + * must be balanced + */ + if (order) +- return pgdat_balanced(pgdat, balanced, classzone_idx); ++ return !pgdat_balanced(pgdat, balanced, classzone_idx); + else + return !all_zones_ok; + } +-- +1.7.3.4 + +_______________________________________________ +stable mailing list +stable@linux.kernel.org +http://linux.kernel.org/mailman/listinfo/stable diff --git a/freed-ora/current/f15/mm-vmscan-correctly-check-if-reclaimer-should-schedule-during-shrink_slab.patch b/freed-ora/current/f15/mm-vmscan-correctly-check-if-reclaimer-should-schedule-during-shrink_slab.patch new file mode 100644 index 000000000..b5b053eac --- /dev/null +++ b/freed-ora/current/f15/mm-vmscan-correctly-check-if-reclaimer-should-schedule-during-shrink_slab.patch @@ -0,0 +1,153 @@ +Return-Path: stable-bounces@linux.kernel.org +Received: from zmta01.collab.prod.int.phx2.redhat.com (LHLO + zmta01.collab.prod.int.phx2.redhat.com) (10.5.5.31) by + mail02.corp.redhat.com with LMTP; Mon, 23 May 2011 05:54:49 -0400 (EDT) +Received: from localhost (localhost.localdomain [127.0.0.1]) + by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 443AC9289D + for <cebbert@redhat.com>; Mon, 23 May 2011 05:54:49 -0400 (EDT) +Received: from zmta01.collab.prod.int.phx2.redhat.com ([127.0.0.1]) + by localhost (zmta01.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id WTG56s2uAm8Z for <cebbert@redhat.com>; + Mon, 23 May 2011 05:54:49 -0400 (EDT) +Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) + by zmta01.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 2D1D2906E4 + for <cebbert@mail.corp.redhat.com>; Mon, 23 May 2011 05:54:49 -0400 (EDT) +Received: from mx1.redhat.com (ext-mx11.extmail.prod.ext.phx2.redhat.com [10.5.110.16]) + by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p4N9snmk002150 + for <cebbert@redhat.com>; Mon, 23 May 2011 05:54:49 -0400 +Received: from hera.kernel.org (hera.kernel.org [140.211.167.34]) + by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p4N9smZs008302 + for <cebbert@redhat.com>; Mon, 23 May 2011 05:54:48 -0400 +Received: from hera.kernel.org (localhost [127.0.0.1]) + by hera.kernel.org (8.14.4/8.14.3) with ESMTP id p4N9sGZo010150; + Mon, 23 May 2011 09:54:16 GMT +X-Virus-Status: Clean +X-Virus-Scanned: clamav-milter 0.97 at hera.kernel.org +Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) + by hera.kernel.org (8.14.4/8.14.3) with ESMTP id p4N9s1xm009737; + Mon, 23 May 2011 09:54:02 GMT +X-Virus-Status: Clean +X-Virus-Scanned: clamav-milter 0.97 at hera.kernel.org +Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) + by mx2.suse.de (Postfix) with ESMTP id 2B4998FFEB; + Mon, 23 May 2011 11:54:01 +0200 (CEST) +From: Mel Gorman <mgorman@suse.de> +To: Andrew Morton <akpm@linux-foundation.org> +Date: Mon, 23 May 2011 10:53:55 +0100 +Message-Id: <1306144435-2516-3-git-send-email-mgorman@suse.de> +In-Reply-To: <1306144435-2516-1-git-send-email-mgorman@suse.de> +References: <1306144435-2516-1-git-send-email-mgorman@suse.de> +X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED + autolearn=unavailable version=3.3.2-r929478 +X-Spam-Checker-Version: SpamAssassin 3.3.2-r929478 (2010-03-31) on + hera.kernel.org +X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.2.3 (hera.kernel.org [127.0.0.1]); Mon, 23 May 2011 09:54:16 +0000 (UTC) +X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by + milter-greylist-4.2.3 (hera.kernel.org [140.211.167.34]); + Mon, 23 May 2011 09:54:03 +0000 (UTC) +Cc: Pekka Enberg <penberg@kernel.org>, Rik van Riel <riel@redhat.com>, + Jan Kara <jack@suse.cz>, linux-kernel <linux-kernel@vger.kernel.org>, + James Bottomley <James.Bottomley@HansenPartnership.com>, + linux-mm <linux-mm@kvack.org>, Minchan Kim <minchan.kim@gmail.com>, + Raghavendra D Prabhu <raghu.prabhu13@gmail.com>, + Johannes Weiner <hannes@cmpxchg.org>, + linux-fsdevel <linux-fsdevel@vger.kernel.org>, + Colin King <colin.king@canonical.com>, + Christoph Lameter <cl@linux.com>, + linux-ext4 <linux-ext4@vger.kernel.org>, stable <stable@kernel.org>, + Chris Mason <chris.mason@oracle.com>, Mel Gorman <mgorman@suse.de> +Subject: [stable] [PATCH 2/2] mm: vmscan: Correctly check if reclaimer + should schedule during shrink_slab +X-BeenThere: stable@linux.kernel.org +X-Mailman-Version: 2.1.12 +Precedence: list +List-Id: For maintainers of the stable Linux series <stable.linux.kernel.org> +List-Unsubscribe: <http://linux.kernel.org/mailman/options/stable>, + <mailto:stable-request@linux.kernel.org?subject=unsubscribe> +List-Archive: <http://linux.kernel.org/mailman/private/stable/> +List-Post: <mailto:stable@linux.kernel.org> +List-Help: <mailto:stable-request@linux.kernel.org?subject=help> +List-Subscribe: <http://linux.kernel.org/mailman/listinfo/stable>, + <mailto:stable-request@linux.kernel.org?subject=subscribe> +MIME-Version: 1.0 +Content-Type: text/plain; charset="us-ascii" +Content-Transfer-Encoding: 7bit +Sender: stable-bounces@linux.kernel.org +Errors-To: stable-bounces@linux.kernel.org +X-RedHat-Spam-Score: -2.31 (RCVD_IN_DNSWL_MED,T_RP_MATCHES_RCVD) +X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 +X-Scanned-By: MIMEDefang 2.68 on 10.5.110.16 + +It has been reported on some laptops that kswapd is consuming large +amounts of CPU and not being scheduled when SLUB is enabled during +large amounts of file copying. It is expected that this is due to +kswapd missing every cond_resched() point because; + +shrink_page_list() calls cond_resched() if inactive pages were isolated + which in turn may not happen if all_unreclaimable is set in + shrink_zones(). If for whatver reason, all_unreclaimable is + set on all zones, we can miss calling cond_resched(). + +balance_pgdat() only calls cond_resched if the zones are not + balanced. For a high-order allocation that is balanced, it + checks order-0 again. During that window, order-0 might have + become unbalanced so it loops again for order-0 and returns + that it was reclaiming for order-0 to kswapd(). It can then + find that a caller has rewoken kswapd for a high-order and + re-enters balance_pgdat() without ever calling cond_resched(). + +shrink_slab only calls cond_resched() if we are reclaiming slab + pages. If there are a large number of direct reclaimers, the + shrinker_rwsem can be contended and prevent kswapd calling + cond_resched(). + +This patch modifies the shrink_slab() case. If the semaphore is +contended, the caller will still check cond_resched(). After each +successful call into a shrinker, the check for cond_resched() remains +in case one shrinker is particularly slow. + +This patch replaces +mm-vmscan-if-kswapd-has-been-running-too-long-allow-it-to-sleep.patch +in -mm. + +[mgorman@suse.de: Preserve call to cond_resched after each call into shrinker] +From: Minchan Kim <minchan.kim@gmail.com> +Signed-off-by: Mel Gorman <mgorman@suse.de> +--- + mm/vmscan.c | 9 +++++++-- + 1 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/mm/vmscan.c b/mm/vmscan.c +index 1aa262b..cc1470b 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -230,8 +230,11 @@ unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask, + if (scanned == 0) + scanned = SWAP_CLUSTER_MAX; + +- if (!down_read_trylock(&shrinker_rwsem)) +- return 1; /* Assume we'll be able to shrink next time */ ++ if (!down_read_trylock(&shrinker_rwsem)) { ++ /* Assume we'll be able to shrink next time */ ++ ret = 1; ++ goto out; ++ } + + list_for_each_entry(shrinker, &shrinker_list, list) { + unsigned long long delta; +@@ -282,6 +285,8 @@ unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask, + shrinker->nr += total_scan; + } + up_read(&shrinker_rwsem); ++out: ++ cond_resched(); + return ret; + } + +-- +1.7.3.4 + +_______________________________________________ +stable mailing list +stable@linux.kernel.org +http://linux.kernel.org/mailman/listinfo/stable diff --git a/freed-ora/current/f15/sources b/freed-ora/current/f15/sources index 4f99b81f1..655401a4c 100644 --- a/freed-ora/current/f15/sources +++ b/freed-ora/current/f15/sources @@ -1,3 +1,2 @@ 21911d61ac22d66e71697a3d5ae092ba linux-2.6.38-libre.tar.bz2 -527fab8162c682ad849eb21fc30d28ef patch-2.6.38.6.bz2 -10c4659d759236f1e71fe2431adcc957 patch-2.6.38.7-rc1.bz2 +2639b4b98a2dcfc8b7f091543f289205 patch-2.6.38.7.bz2 |