summaryrefslogtreecommitdiffstats
path: root/freed-ora/current/f15
diff options
context:
space:
mode:
authorAlexandre Oliva <lxoliva@fsfla.org>2011-05-28 02:47:00 +0000
committerAlexandre Oliva <lxoliva@fsfla.org>2011-05-28 02:47:00 +0000
commitf59025a5537482345d50258c40596b9ddad5f32a (patch)
tree58d2e2a4b48f355bf0192b6037a352cccaa84370 /freed-ora/current/f15
parent32f5a0305b0da635fd4d518c22deb9f0e1b20a1e (diff)
downloadlinux-libre-raptor-f59025a5537482345d50258c40596b9ddad5f32a.tar.gz
linux-libre-raptor-f59025a5537482345d50258c40596b9ddad5f32a.zip
2.6.38.7-30.fc15
Diffstat (limited to 'freed-ora/current/f15')
-rw-r--r--freed-ora/current/f15/acpi_reboot.patch6
-rw-r--r--freed-ora/current/f15/bluetooth-device-ids-for-ath3k-on-pegatron-lucid-tablets.patch37
-rw-r--r--freed-ora/current/f15/drm-nouveau-fixes.patch167
-rw-r--r--freed-ora/current/f15/drm-nouveau-updates.patch1013
-rw-r--r--freed-ora/current/f15/drm-radeon-update2.patch1708
-rw-r--r--freed-ora/current/f15/hid-multitouch-add-support-for-elo-touchsystems.patch78
-rw-r--r--freed-ora/current/f15/kernel.spec40
-rw-r--r--freed-ora/current/f15/mm-vmscan-correct-use-of-pgdat_balanced-in-sleeping_prematurely.patch114
-rw-r--r--freed-ora/current/f15/mm-vmscan-correctly-check-if-reclaimer-should-schedule-during-shrink_slab.patch153
-rw-r--r--freed-ora/current/f15/sources3
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
OpenPOWER on IntegriCloud