From df8d252aa58442627b75c2dd49b5ee1064c44d7f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 3 Mar 2010 13:39:13 -0500 Subject: [PATCH] --- yaml --- r: 189313 b: refs/heads/master c: 338e2b1d571e4873908b199c90d6a31f65137fe3 h: refs/heads/master i: 189311: 0ae8262b445f89e6638396c1a0980a043e7cb385 v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/drm_crtc_helper.c | 1 - trunk/drivers/gpu/drm/drm_edid.c | 9 + trunk/drivers/gpu/drm/nouveau/Makefile | 2 +- trunk/drivers/gpu/drm/nouveau/nouveau_bios.c | 28 +- trunk/drivers/gpu/drm/nouveau/nouveau_bios.h | 3 +- trunk/drivers/gpu/drm/nouveau/nouveau_bo.c | 3 +- .../gpu/drm/nouveau/nouveau_connector.c | 2 +- trunk/drivers/gpu/drm/nouveau/nouveau_dma.c | 5 - trunk/drivers/gpu/drm/nouveau/nouveau_drv.c | 10 - trunk/drivers/gpu/drm/nouveau/nouveau_drv.h | 6 - trunk/drivers/gpu/drm/nouveau/nouveau_irq.c | 609 ++---------------- trunk/drivers/gpu/drm/nouveau/nouveau_state.c | 5 +- trunk/drivers/gpu/drm/nouveau/nv04_crtc.c | 6 +- trunk/drivers/gpu/drm/nouveau/nv04_fbcon.c | 6 +- trunk/drivers/gpu/drm/nouveau/nv50_display.c | 4 +- trunk/drivers/gpu/drm/nouveau/nv50_fb.c | 32 - trunk/drivers/gpu/drm/nouveau/nv50_fbcon.c | 2 +- trunk/drivers/gpu/drm/nouveau/nv50_graph.c | 22 +- trunk/drivers/gpu/drm/nouveau/nv50_grctx.c | 13 +- trunk/drivers/gpu/drm/ttm/ttm_bo.c | 4 +- trunk/drivers/gpu/drm/ttm/ttm_memory.c | 18 +- trunk/drivers/gpu/drm/ttm/ttm_tt.c | 23 +- trunk/drivers/gpu/drm/vmwgfx/Kconfig | 2 +- trunk/include/drm/drmP.h | 34 +- trunk/include/drm/drm_mem_util.h | 65 -- trunk/include/drm/drm_pciids.h | 1 + trunk/include/drm/ttm/ttm_bo_driver.h | 1 + 28 files changed, 153 insertions(+), 765 deletions(-) delete mode 100644 trunk/drivers/gpu/drm/nouveau/nv50_fb.c delete mode 100644 trunk/include/drm/drm_mem_util.h diff --git a/[refs] b/[refs] index 522b10028437..b893ecaade0b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d5e5deddf67389eabc3d9b13004c108120d397e1 +refs/heads/master: 338e2b1d571e4873908b199c90d6a31f65137fe3 diff --git a/trunk/drivers/gpu/drm/drm_crtc_helper.c b/trunk/drivers/gpu/drm/drm_crtc_helper.c index 51103aa469f8..f2aaf39be398 100644 --- a/trunk/drivers/gpu/drm/drm_crtc_helper.c +++ b/trunk/drivers/gpu/drm/drm_crtc_helper.c @@ -104,7 +104,6 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, if (connector->status == connector_status_disconnected) { DRM_DEBUG_KMS("%s is disconnected\n", drm_get_connector_name(connector)); - drm_mode_connector_update_edid_property(connector, NULL); goto prune; } diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index 7e608f4a0df9..f97e7c42ac8e 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -707,6 +707,15 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, mode->vsync_end = mode->vsync_start + vsync_pulse_width; mode->vtotal = mode->vdisplay + vblank; + /* perform the basic check for the detailed timing */ + if (mode->hsync_end > mode->htotal || + mode->vsync_end > mode->vtotal) { + drm_mode_destroy(dev, mode); + DRM_DEBUG_KMS("Incorrect detailed timing. " + "Sync is beyond the blank.\n"); + return NULL; + } + /* Some EDIDs have bogus h/vtotal values */ if (mode->hsync_end > mode->htotal) mode->htotal = mode->hsync_end + 1; diff --git a/trunk/drivers/gpu/drm/nouveau/Makefile b/trunk/drivers/gpu/drm/nouveau/Makefile index 7f0d807a0d0d..32db806f3b5a 100644 --- a/trunk/drivers/gpu/drm/nouveau/Makefile +++ b/trunk/drivers/gpu/drm/nouveau/Makefile @@ -12,7 +12,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nouveau_dp.o nouveau_grctx.o \ nv04_timer.o \ nv04_mc.o nv40_mc.o nv50_mc.o \ - nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \ + nv04_fb.o nv10_fb.o nv40_fb.o \ nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ nv04_graph.o nv10_graph.o nv20_graph.o \ nv40_graph.o nv50_graph.o \ diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c index aed6068a6ca5..71247da17da5 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -5210,21 +5210,6 @@ divine_connector_type(struct nvbios *bios, int index) return type; } -static void -apply_dcb_connector_quirks(struct nvbios *bios, int idx) -{ - struct dcb_connector_table_entry *cte = &bios->dcb.connector.entry[idx]; - struct drm_device *dev = bios->dev; - - /* Gigabyte NX85T */ - if ((dev->pdev->device == 0x0421) && - (dev->pdev->subsystem_vendor == 0x1458) && - (dev->pdev->subsystem_device == 0x344c)) { - if (cte->type == DCB_CONNECTOR_HDMI_1) - cte->type = DCB_CONNECTOR_DVI_I; - } -} - static void parse_dcb_connector_table(struct nvbios *bios) { @@ -5253,14 +5238,13 @@ parse_dcb_connector_table(struct nvbios *bios) entry = conntab + conntab[1]; cte = &ct->entry[0]; for (i = 0; i < conntab[2]; i++, entry += conntab[3], cte++) { - cte->index = i; if (conntab[3] == 2) cte->entry = ROM16(entry[0]); else cte->entry = ROM32(entry[0]); cte->type = (cte->entry & 0x000000ff) >> 0; - cte->index2 = (cte->entry & 0x00000f00) >> 8; + cte->index = (cte->entry & 0x00000f00) >> 8; switch (cte->entry & 0x00033000) { case 0x00001000: cte->gpio_tag = 0x07; @@ -5282,8 +5266,6 @@ parse_dcb_connector_table(struct nvbios *bios) if (cte->type == 0xff) continue; - apply_dcb_connector_quirks(bios, i); - NV_INFO(dev, " %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n", i, cte->entry, cte->type, cte->index, cte->gpio_tag); @@ -5305,16 +5287,10 @@ parse_dcb_connector_table(struct nvbios *bios) break; default: cte->type = divine_connector_type(bios, cte->index); - NV_WARN(dev, "unknown type, using 0x%02x\n", cte->type); + NV_WARN(dev, "unknown type, using 0x%02x", cte->type); break; } - if (nouveau_override_conntype) { - int type = divine_connector_type(bios, cte->index); - if (type != cte->type) - NV_WARN(dev, " -> type 0x%02x\n", cte->type); - } - } } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h index 4f88e6924d27..9f688aa9a655 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h @@ -72,10 +72,9 @@ enum dcb_connector_type { }; struct dcb_connector_table_entry { - uint8_t index; uint32_t entry; enum dcb_connector_type type; - uint8_t index2; + uint8_t index; uint8_t gpio_tag; }; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c index 026612471c92..028719fddf76 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -439,7 +439,8 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) switch (bo->mem.mem_type) { case TTM_PL_VRAM: - nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT); + nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT | + TTM_PL_FLAG_SYSTEM); break; default: nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c index 14afe1e47e57..24327f468c4b 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -302,7 +302,7 @@ nouveau_connector_detect(struct drm_connector *connector) detect_analog: nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG); - if (!nv_encoder && !nouveau_tv_disable) + if (!nv_encoder) nv_encoder = find_encoder_by_type(connector, OUTPUT_TV); if (nv_encoder) { struct drm_encoder *encoder = to_drm_encoder(nv_encoder); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_dma.c b/trunk/drivers/gpu/drm/nouveau/nouveau_dma.c index 65c441a1999f..c8482a108a78 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -190,11 +190,6 @@ nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo, nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8); chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max; - - DRM_MEMORYBARRIER(); - /* Flush writes. */ - nouveau_bo_rd32(pb, 0); - nvchan_wr32(chan, 0x8c, chan->dma.ib_put); chan->dma.ib_free--; } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c index 1de974acbc65..30cc09e8a709 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -83,14 +83,6 @@ MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration"); int nouveau_nofbaccel = 0; module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400); -MODULE_PARM_DESC(override_conntype, "Ignore DCB connector type"); -int nouveau_override_conntype = 0; -module_param_named(override_conntype, nouveau_override_conntype, int, 0400); - -MODULE_PARM_DESC(tv_disable, "Disable TV-out detection\n"); -int nouveau_tv_disable = 0; -module_param_named(tv_disable, nouveau_tv_disable, int, 0400); - MODULE_PARM_DESC(tv_norm, "Default TV norm.\n" "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n" "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n" @@ -162,11 +154,9 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) if (pm_state.event == PM_EVENT_PRETHAW) return 0; - NV_INFO(dev, "Disabling fbcon acceleration...\n"); fbdev_flags = dev_priv->fbdev_info->flags; dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED; - NV_INFO(dev, "Unpinning framebuffer(s)...\n"); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_framebuffer *nouveau_fb; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.h b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.h index 5bd8071523d2..5f8d987af363 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -681,7 +681,6 @@ extern int nouveau_uscript_tmds; extern int nouveau_vram_pushbuf; extern int nouveau_vram_notify; extern int nouveau_fbpercrtc; -extern int nouveau_tv_disable; extern char *nouveau_tv_norm; extern int nouveau_reg_debug; extern char *nouveau_vbios; @@ -689,7 +688,6 @@ extern int nouveau_ctxfw; extern int nouveau_ignorelid; extern int nouveau_nofbaccel; extern int nouveau_noaccel; -extern int nouveau_override_conntype; extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state); extern int nouveau_pci_resume(struct pci_dev *pdev); @@ -928,10 +926,6 @@ extern void nv40_fb_takedown(struct drm_device *); extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t, uint32_t, uint32_t); -/* nv50_fb.c */ -extern int nv50_fb_init(struct drm_device *); -extern void nv50_fb_takedown(struct drm_device *); - /* nv04_fifo.c */ extern int nv04_fifo_init(struct drm_device *); extern void nv04_fifo_disable(struct drm_device *); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_irq.c b/trunk/drivers/gpu/drm/nouveau/nouveau_irq.c index 2bd59a92fee5..95220ddebb45 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -311,31 +311,6 @@ nouveau_print_bitfield_names_(uint32_t value, #define nouveau_print_bitfield_names(val, namelist) \ nouveau_print_bitfield_names_((val), (namelist), ARRAY_SIZE(namelist)) -struct nouveau_enum_names { - uint32_t value; - const char *name; -}; - -static void -nouveau_print_enum_names_(uint32_t value, - const struct nouveau_enum_names *namelist, - const int namelist_len) -{ - /* - * Caller must have already printed the KERN_* log level for us. - * Also the caller is responsible for adding the newline. - */ - int i; - for (i = 0; i < namelist_len; ++i) { - if (value == namelist[i].value) { - printk("%s", namelist[i].name); - return; - } - } - printk("unknown value 0x%08x", value); -} -#define nouveau_print_enum_names(val, namelist) \ - nouveau_print_enum_names_((val), (namelist), ARRAY_SIZE(namelist)) static int nouveau_graph_chid_from_grctx(struct drm_device *dev) @@ -452,16 +427,14 @@ nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id, struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t nsource = trap->nsource, nstatus = trap->nstatus; - if (dev_priv->card_type < NV_50) { - NV_INFO(dev, "%s - nSource:", id); - nouveau_print_bitfield_names(nsource, nsource_names); - printk(", nStatus:"); - if (dev_priv->card_type < NV_10) - nouveau_print_bitfield_names(nstatus, nstatus_names); - else - nouveau_print_bitfield_names(nstatus, nstatus_names_nv10); - printk("\n"); - } + NV_INFO(dev, "%s - nSource:", id); + nouveau_print_bitfield_names(nsource, nsource_names); + printk(", nStatus:"); + if (dev_priv->card_type < NV_10) + nouveau_print_bitfield_names(nstatus, nstatus_names); + else + nouveau_print_bitfield_names(nstatus, nstatus_names_nv10); + printk("\n"); NV_INFO(dev, "%s - Ch %d/%d Class 0x%04x Mthd 0x%04x " "Data 0x%08x:0x%08x\n", @@ -604,503 +577,28 @@ nouveau_pgraph_irq_handler(struct drm_device *dev) nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); } -static void -nv50_pfb_vm_trap(struct drm_device *dev, int display, const char *name) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t trap[6]; - int i, ch; - uint32_t idx = nv_rd32(dev, 0x100c90); - if (idx & 0x80000000) { - idx &= 0xffffff; - if (display) { - for (i = 0; i < 6; i++) { - nv_wr32(dev, 0x100c90, idx | i << 24); - trap[i] = nv_rd32(dev, 0x100c94); - } - for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) { - struct nouveau_channel *chan = dev_priv->fifos[ch]; - - if (!chan || !chan->ramin) - continue; - - if (trap[1] == chan->ramin->instance >> 12) - break; - } - NV_INFO(dev, "%s - VM: Trapped %s at %02x%04x%04x status %08x %08x channel %d\n", - name, (trap[5]&0x100?"read":"write"), - trap[5]&0xff, trap[4]&0xffff, - trap[3]&0xffff, trap[0], trap[2], ch); - } - nv_wr32(dev, 0x100c90, idx | 0x80000000); - } else if (display) { - NV_INFO(dev, "%s - no VM fault?\n", name); - } -} - -static struct nouveau_enum_names nv50_mp_exec_error_names[] = -{ - { 3, "STACK_UNDERFLOW" }, - { 4, "QUADON_ACTIVE" }, - { 8, "TIMEOUT" }, - { 0x10, "INVALID_OPCODE" }, - { 0x40, "BREAKPOINT" }, -}; - -static void -nv50_pgraph_mp_trap(struct drm_device *dev, int tpid, int display) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t units = nv_rd32(dev, 0x1540); - uint32_t addr, mp10, status, pc, oplow, ophigh; - int i; - int mps = 0; - for (i = 0; i < 4; i++) { - if (!(units & 1 << (i+24))) - continue; - if (dev_priv->chipset < 0xa0) - addr = 0x408200 + (tpid << 12) + (i << 7); - else - addr = 0x408100 + (tpid << 11) + (i << 7); - mp10 = nv_rd32(dev, addr + 0x10); - status = nv_rd32(dev, addr + 0x14); - if (!status) - continue; - if (display) { - nv_rd32(dev, addr + 0x20); - pc = nv_rd32(dev, addr + 0x24); - oplow = nv_rd32(dev, addr + 0x70); - ophigh= nv_rd32(dev, addr + 0x74); - NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - " - "TP %d MP %d: ", tpid, i); - nouveau_print_enum_names(status, - nv50_mp_exec_error_names); - printk(" at %06x warp %d, opcode %08x %08x\n", - pc&0xffffff, pc >> 24, - oplow, ophigh); - } - nv_wr32(dev, addr + 0x10, mp10); - nv_wr32(dev, addr + 0x14, 0); - mps++; - } - if (!mps && display) - NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - TP %d: " - "No MPs claiming errors?\n", tpid); -} - -static void -nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old, - uint32_t ustatus_new, int display, const char *name) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int tps = 0; - uint32_t units = nv_rd32(dev, 0x1540); - int i, r; - uint32_t ustatus_addr, ustatus; - for (i = 0; i < 16; i++) { - if (!(units & (1 << i))) - continue; - if (dev_priv->chipset < 0xa0) - ustatus_addr = ustatus_old + (i << 12); - else - ustatus_addr = ustatus_new + (i << 11); - ustatus = nv_rd32(dev, ustatus_addr) & 0x7fffffff; - if (!ustatus) - continue; - tps++; - switch (type) { - case 6: /* texture error... unknown for now */ - nv50_pfb_vm_trap(dev, display, name); - if (display) { - NV_ERROR(dev, "magic set %d:\n", i); - for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4) - NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, - nv_rd32(dev, r)); - } - break; - case 7: /* MP error */ - if (ustatus & 0x00010000) { - nv50_pgraph_mp_trap(dev, i, display); - ustatus &= ~0x00010000; - } - break; - case 8: /* TPDMA error */ - { - uint32_t e0c = nv_rd32(dev, ustatus_addr + 4); - uint32_t e10 = nv_rd32(dev, ustatus_addr + 8); - uint32_t e14 = nv_rd32(dev, ustatus_addr + 0xc); - uint32_t e18 = nv_rd32(dev, ustatus_addr + 0x10); - uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14); - uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18); - uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c); - nv50_pfb_vm_trap(dev, display, name); - /* 2d engine destination */ - if (ustatus & 0x00000010) { - if (display) { - NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - Unknown fault at address %02x%08x\n", - i, e14, e10); - NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", - i, e0c, e18, e1c, e20, e24); - } - ustatus &= ~0x00000010; - } - /* Render target */ - if (ustatus & 0x00000040) { - if (display) { - NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - Unknown fault at address %02x%08x\n", - i, e14, e10); - NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", - i, e0c, e18, e1c, e20, e24); - } - ustatus &= ~0x00000040; - } - /* CUDA memory: l[], g[] or stack. */ - if (ustatus & 0x00000080) { - if (display) { - if (e18 & 0x80000000) { - /* g[] read fault? */ - NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global read fault at address %02x%08x\n", - i, e14, e10 | ((e18 >> 24) & 0x1f)); - e18 &= ~0x1f000000; - } else if (e18 & 0xc) { - /* g[] write fault? */ - NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global write fault at address %02x%08x\n", - i, e14, e10 | ((e18 >> 7) & 0x1f)); - e18 &= ~0x00000f80; - } else { - NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Unknown CUDA fault at address %02x%08x\n", - i, e14, e10); - } - NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", - i, e0c, e18, e1c, e20, e24); - } - ustatus &= ~0x00000080; - } - } - break; - } - if (ustatus) { - if (display) - NV_INFO(dev, "%s - TP%d: Unhandled ustatus 0x%08x\n", name, i, ustatus); - } - nv_wr32(dev, ustatus_addr, 0xc0000000); - } - - if (!tps && display) - NV_INFO(dev, "%s - No TPs claiming errors?\n", name); -} - -static void -nv50_pgraph_trap_handler(struct drm_device *dev) -{ - struct nouveau_pgraph_trap trap; - uint32_t status = nv_rd32(dev, 0x400108); - uint32_t ustatus; - int display = nouveau_ratelimit(); - - - if (!status && display) { - nouveau_graph_trap_info(dev, &trap); - nouveau_graph_dump_trap_info(dev, "PGRAPH_TRAP", &trap); - NV_INFO(dev, "PGRAPH_TRAP - no units reporting traps?\n"); - } - - /* DISPATCH: Relays commands to other units and handles NOTIFY, - * COND, QUERY. If you get a trap from it, the command is still stuck - * in DISPATCH and you need to do something about it. */ - if (status & 0x001) { - ustatus = nv_rd32(dev, 0x400804) & 0x7fffffff; - if (!ustatus && display) { - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - no ustatus?\n"); - } - - /* Known to be triggered by screwed up NOTIFY and COND... */ - if (ustatus & 0x00000001) { - nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_FAULT"); - nv_wr32(dev, 0x400500, 0); - if (nv_rd32(dev, 0x400808) & 0x80000000) { - if (display) { - if (nouveau_graph_trapped_channel(dev, &trap.channel)) - trap.channel = -1; - trap.class = nv_rd32(dev, 0x400814); - trap.mthd = nv_rd32(dev, 0x400808) & 0x1ffc; - trap.subc = (nv_rd32(dev, 0x400808) >> 16) & 0x7; - trap.data = nv_rd32(dev, 0x40080c); - trap.data2 = nv_rd32(dev, 0x400810); - nouveau_graph_dump_trap_info(dev, - "PGRAPH_TRAP_DISPATCH_FAULT", &trap); - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400808: %08x\n", nv_rd32(dev, 0x400808)); - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400848: %08x\n", nv_rd32(dev, 0x400848)); - } - nv_wr32(dev, 0x400808, 0); - } else if (display) { - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - No stuck command?\n"); - } - nv_wr32(dev, 0x4008e8, nv_rd32(dev, 0x4008e8) & 3); - nv_wr32(dev, 0x400848, 0); - ustatus &= ~0x00000001; - } - if (ustatus & 0x00000002) { - nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_QUERY"); - nv_wr32(dev, 0x400500, 0); - if (nv_rd32(dev, 0x40084c) & 0x80000000) { - if (display) { - if (nouveau_graph_trapped_channel(dev, &trap.channel)) - trap.channel = -1; - trap.class = nv_rd32(dev, 0x400814); - trap.mthd = nv_rd32(dev, 0x40084c) & 0x1ffc; - trap.subc = (nv_rd32(dev, 0x40084c) >> 16) & 0x7; - trap.data = nv_rd32(dev, 0x40085c); - trap.data2 = 0; - nouveau_graph_dump_trap_info(dev, - "PGRAPH_TRAP_DISPATCH_QUERY", &trap); - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - 40084c: %08x\n", nv_rd32(dev, 0x40084c)); - } - nv_wr32(dev, 0x40084c, 0); - } else if (display) { - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - No stuck command?\n"); - } - ustatus &= ~0x00000002; - } - if (ustatus && display) - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - Unhandled ustatus 0x%08x\n", ustatus); - nv_wr32(dev, 0x400804, 0xc0000000); - nv_wr32(dev, 0x400108, 0x001); - status &= ~0x001; - } - - /* TRAPs other than dispatch use the "normal" trap regs. */ - if (status && display) { - nouveau_graph_trap_info(dev, &trap); - nouveau_graph_dump_trap_info(dev, - "PGRAPH_TRAP", &trap); - } - - /* M2MF: Memory to memory copy engine. */ - if (status & 0x002) { - ustatus = nv_rd32(dev, 0x406800) & 0x7fffffff; - if (!ustatus && display) { - NV_INFO(dev, "PGRAPH_TRAP_M2MF - no ustatus?\n"); - } - if (ustatus & 0x00000001) { - nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_NOTIFY"); - ustatus &= ~0x00000001; - } - if (ustatus & 0x00000002) { - nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_IN"); - ustatus &= ~0x00000002; - } - if (ustatus & 0x00000004) { - nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_OUT"); - ustatus &= ~0x00000004; - } - NV_INFO (dev, "PGRAPH_TRAP_M2MF - %08x %08x %08x %08x\n", - nv_rd32(dev, 0x406804), - nv_rd32(dev, 0x406808), - nv_rd32(dev, 0x40680c), - nv_rd32(dev, 0x406810)); - if (ustatus && display) - NV_INFO(dev, "PGRAPH_TRAP_M2MF - Unhandled ustatus 0x%08x\n", ustatus); - /* No sane way found yet -- just reset the bugger. */ - nv_wr32(dev, 0x400040, 2); - nv_wr32(dev, 0x400040, 0); - nv_wr32(dev, 0x406800, 0xc0000000); - nv_wr32(dev, 0x400108, 0x002); - status &= ~0x002; - } - - /* VFETCH: Fetches data from vertex buffers. */ - if (status & 0x004) { - ustatus = nv_rd32(dev, 0x400c04) & 0x7fffffff; - if (!ustatus && display) { - NV_INFO(dev, "PGRAPH_TRAP_VFETCH - no ustatus?\n"); - } - if (ustatus & 0x00000001) { - nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_VFETCH_FAULT"); - NV_INFO (dev, "PGRAPH_TRAP_VFETCH_FAULT - %08x %08x %08x %08x\n", - nv_rd32(dev, 0x400c00), - nv_rd32(dev, 0x400c08), - nv_rd32(dev, 0x400c0c), - nv_rd32(dev, 0x400c10)); - ustatus &= ~0x00000001; - } - if (ustatus && display) - NV_INFO(dev, "PGRAPH_TRAP_VFETCH - Unhandled ustatus 0x%08x\n", ustatus); - nv_wr32(dev, 0x400c04, 0xc0000000); - nv_wr32(dev, 0x400108, 0x004); - status &= ~0x004; - } - - /* STRMOUT: DirectX streamout / OpenGL transform feedback. */ - if (status & 0x008) { - ustatus = nv_rd32(dev, 0x401800) & 0x7fffffff; - if (!ustatus && display) { - NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - no ustatus?\n"); - } - if (ustatus & 0x00000001) { - nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_STRMOUT_FAULT"); - NV_INFO (dev, "PGRAPH_TRAP_STRMOUT_FAULT - %08x %08x %08x %08x\n", - nv_rd32(dev, 0x401804), - nv_rd32(dev, 0x401808), - nv_rd32(dev, 0x40180c), - nv_rd32(dev, 0x401810)); - ustatus &= ~0x00000001; - } - if (ustatus && display) - NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - Unhandled ustatus 0x%08x\n", ustatus); - /* No sane way found yet -- just reset the bugger. */ - nv_wr32(dev, 0x400040, 0x80); - nv_wr32(dev, 0x400040, 0); - nv_wr32(dev, 0x401800, 0xc0000000); - nv_wr32(dev, 0x400108, 0x008); - status &= ~0x008; - } - - /* CCACHE: Handles code and c[] caches and fills them. */ - if (status & 0x010) { - ustatus = nv_rd32(dev, 0x405018) & 0x7fffffff; - if (!ustatus && display) { - NV_INFO(dev, "PGRAPH_TRAP_CCACHE - no ustatus?\n"); - } - if (ustatus & 0x00000001) { - nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_CCACHE_FAULT"); - NV_INFO (dev, "PGRAPH_TRAP_CCACHE_FAULT - %08x %08x %08x %08x %08x %08x %08x\n", - nv_rd32(dev, 0x405800), - nv_rd32(dev, 0x405804), - nv_rd32(dev, 0x405808), - nv_rd32(dev, 0x40580c), - nv_rd32(dev, 0x405810), - nv_rd32(dev, 0x405814), - nv_rd32(dev, 0x40581c)); - ustatus &= ~0x00000001; - } - if (ustatus && display) - NV_INFO(dev, "PGRAPH_TRAP_CCACHE - Unhandled ustatus 0x%08x\n", ustatus); - nv_wr32(dev, 0x405018, 0xc0000000); - nv_wr32(dev, 0x400108, 0x010); - status &= ~0x010; - } - - /* Unknown, not seen yet... 0x402000 is the only trap status reg - * remaining, so try to handle it anyway. Perhaps related to that - * unknown DMA slot on tesla? */ - if (status & 0x20) { - nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_UNKC04"); - ustatus = nv_rd32(dev, 0x402000) & 0x7fffffff; - if (display) - NV_INFO(dev, "PGRAPH_TRAP_UNKC04 - Unhandled ustatus 0x%08x\n", ustatus); - nv_wr32(dev, 0x402000, 0xc0000000); - /* no status modifiction on purpose */ - } - - /* TEXTURE: CUDA texturing units */ - if (status & 0x040) { - nv50_pgraph_tp_trap (dev, 6, 0x408900, 0x408600, display, - "PGRAPH_TRAP_TEXTURE"); - nv_wr32(dev, 0x400108, 0x040); - status &= ~0x040; - } - - /* MP: CUDA execution engines. */ - if (status & 0x080) { - nv50_pgraph_tp_trap (dev, 7, 0x408314, 0x40831c, display, - "PGRAPH_TRAP_MP"); - nv_wr32(dev, 0x400108, 0x080); - status &= ~0x080; - } - - /* TPDMA: Handles TP-initiated uncached memory accesses: - * l[], g[], stack, 2d surfaces, render targets. */ - if (status & 0x100) { - nv50_pgraph_tp_trap (dev, 8, 0x408e08, 0x408708, display, - "PGRAPH_TRAP_TPDMA"); - nv_wr32(dev, 0x400108, 0x100); - status &= ~0x100; - } - - if (status) { - if (display) - NV_INFO(dev, "PGRAPH_TRAP - Unknown trap 0x%08x\n", - status); - nv_wr32(dev, 0x400108, status); - } -} - -/* There must be a *lot* of these. Will take some time to gather them up. */ -static struct nouveau_enum_names nv50_data_error_names[] = -{ - { 4, "INVALID_VALUE" }, - { 5, "INVALID_ENUM" }, - { 8, "INVALID_OBJECT" }, - { 0xc, "INVALID_BITFIELD" }, - { 0x28, "MP_NO_REG_SPACE" }, - { 0x2b, "MP_BLOCK_SIZE_MISMATCH" }, -}; - static void nv50_pgraph_irq_handler(struct drm_device *dev) { - struct nouveau_pgraph_trap trap; - int unhandled = 0; uint32_t status; while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) { - /* NOTIFY: You've set a NOTIFY an a command and it's done. */ + uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); + if (status & 0x00000001) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_NOTIFY", &trap); + nouveau_pgraph_intr_notify(dev, nsource); status &= ~0x00000001; nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001); } - /* COMPUTE_QUERY: Purpose and exact cause unknown, happens - * when you write 0x200 to 0x50c0 method 0x31c. */ - if (status & 0x00000002) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_COMPUTE_QUERY", &trap); - status &= ~0x00000002; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000002); - } - - /* Unknown, never seen: 0x4 */ - - /* ILLEGAL_MTHD: You used a wrong method for this class. */ if (status & 0x00000010) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_pgraph_intr_swmthd(dev, &trap)) - unhandled = 1; - if (unhandled && nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_ILLEGAL_MTHD", &trap); + nouveau_pgraph_intr_error(dev, nsource | + NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD); + status &= ~0x00000010; nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010); } - /* ILLEGAL_CLASS: You used a wrong class. */ - if (status & 0x00000020) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_ILLEGAL_CLASS", &trap); - status &= ~0x00000020; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000020); - } - - /* DOUBLE_NOTIFY: You tried to set a NOTIFY on another NOTIFY. */ - if (status & 0x00000040) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_DOUBLE_NOTIFY", &trap); - status &= ~0x00000040; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000040); - } - - /* CONTEXT_SWITCH: PGRAPH needs us to load a new context */ if (status & 0x00001000) { nv_wr32(dev, 0x400500, 0x00000000); nv_wr32(dev, NV03_PGRAPH_INTR, @@ -1115,59 +613,49 @@ nv50_pgraph_irq_handler(struct drm_device *dev) status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; } - /* BUFFER_NOTIFY: Your m2mf transfer finished */ - if (status & 0x00010000) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_BUFFER_NOTIFY", &trap); - status &= ~0x00010000; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x00010000); - } - - /* DATA_ERROR: Invalid value for this method, or invalid - * state in current PGRAPH context for this operation */ if (status & 0x00100000) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) { - nouveau_graph_dump_trap_info(dev, - "PGRAPH_DATA_ERROR", &trap); - NV_INFO (dev, "PGRAPH_DATA_ERROR - "); - nouveau_print_enum_names(nv_rd32(dev, 0x400110), - nv50_data_error_names); - printk("\n"); - } + nouveau_pgraph_intr_error(dev, nsource | + NV03_PGRAPH_NSOURCE_DATA_ERROR); + status &= ~0x00100000; nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000); } - /* TRAP: Something bad happened in the middle of command - * execution. Has a billion types, subtypes, and even - * subsubtypes. */ if (status & 0x00200000) { - nv50_pgraph_trap_handler(dev); + int r; + + nouveau_pgraph_intr_error(dev, nsource | + NV03_PGRAPH_NSOURCE_PROTECTION_ERROR); + + NV_ERROR(dev, "magic set 1:\n"); + for (r = 0x408900; r <= 0x408910; r += 4) + NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, + nv_rd32(dev, r)); + nv_wr32(dev, 0x408900, + nv_rd32(dev, 0x408904) | 0xc0000000); + for (r = 0x408e08; r <= 0x408e24; r += 4) + NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, + nv_rd32(dev, r)); + nv_wr32(dev, 0x408e08, + nv_rd32(dev, 0x408e08) | 0xc0000000); + + NV_ERROR(dev, "magic set 2:\n"); + for (r = 0x409900; r <= 0x409910; r += 4) + NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, + nv_rd32(dev, r)); + nv_wr32(dev, 0x409900, + nv_rd32(dev, 0x409904) | 0xc0000000); + for (r = 0x409e08; r <= 0x409e24; r += 4) + NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, + nv_rd32(dev, r)); + nv_wr32(dev, 0x409e08, + nv_rd32(dev, 0x409e08) | 0xc0000000); + status &= ~0x00200000; + nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource); nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000); } - /* Unknown, never seen: 0x00400000 */ - - /* SINGLE_STEP: Happens on every method if you turned on - * single stepping in 40008c */ - if (status & 0x01000000) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_SINGLE_STEP", &trap); - status &= ~0x01000000; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x01000000); - } - - /* 0x02000000 happens when you pause a ctxprog... - * but the only way this can happen that I know is by - * poking the relevant MMIO register, and we don't - * do that. */ - if (status) { NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status); @@ -1184,8 +672,7 @@ nv50_pgraph_irq_handler(struct drm_device *dev) } nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); - if (nv_rd32(dev, 0x400824) & (1 << 31)) - nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); + nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); } static void diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_state.c b/trunk/drivers/gpu/drm/nouveau/nouveau_state.c index 58b46807de23..eb8f084d5f53 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_state.c @@ -35,6 +35,7 @@ #include "nouveau_drm.h" #include "nv50_display.h" +static int nouveau_stub_init(struct drm_device *dev) { return 0; } static void nouveau_stub_takedown(struct drm_device *dev) {} static int nouveau_init_engine_ptrs(struct drm_device *dev) @@ -276,8 +277,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.init = nv04_timer_init; engine->timer.read = nv04_timer_read; engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nv50_fb_init; - engine->fb.takedown = nv50_fb_takedown; + engine->fb.init = nouveau_stub_init; + engine->fb.takedown = nouveau_stub_takedown; engine->graph.grclass = nv50_graph_grclass; engine->graph.init = nv50_graph_init; engine->graph.takedown = nv50_graph_takedown; diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_crtc.c b/trunk/drivers/gpu/drm/nouveau/nv04_crtc.c index eba687f1099e..a1d1ebb073d9 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -230,9 +230,9 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode) struct drm_framebuffer *fb = crtc->fb; /* Calculate our timings */ - int horizDisplay = (mode->crtc_hdisplay >> 3) - 1; - int horizStart = (mode->crtc_hsync_start >> 3) + 1; - int horizEnd = (mode->crtc_hsync_end >> 3) + 1; + int horizDisplay = (mode->crtc_hdisplay >> 3) - 1; + int horizStart = (mode->crtc_hsync_start >> 3) - 1; + int horizEnd = (mode->crtc_hsync_end >> 3) - 1; int horizTotal = (mode->crtc_htotal >> 3) - 5; int horizBlankStart = (mode->crtc_hdisplay >> 3) - 1; int horizBlankEnd = (mode->crtc_htotal >> 3) - 1; diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_fbcon.c b/trunk/drivers/gpu/drm/nouveau/nv04_fbcon.c index 813b25cec726..3da90c2c4e63 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -118,8 +118,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) return; } - width = ALIGN(image->width, 8); - dsize = ALIGN(width * image->height, 32) >> 5; + width = ALIGN(image->width, 32); + dsize = (width * image->height) >> 5; if (info->fix.visual == FB_VISUAL_TRUECOLOR || info->fix.visual == FB_VISUAL_DIRECTCOLOR) { @@ -136,8 +136,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) ((image->dx + image->width) & 0xffff)); OUT_RING(chan, bg); OUT_RING(chan, fg); - OUT_RING(chan, (image->height << 16) | width); OUT_RING(chan, (image->height << 16) | image->width); + OUT_RING(chan, (image->height << 16) | width); OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); while (dsize) { diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_display.c b/trunk/drivers/gpu/drm/nouveau/nv50_display.c index fac6c88a2b1f..61a89f2dc553 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_display.c @@ -522,8 +522,8 @@ int nv50_display_create(struct drm_device *dev) } for (i = 0 ; i < dcb->connector.entries; i++) { - if (i != 0 && dcb->connector.entry[i].index2 == - dcb->connector.entry[i - 1].index2) + if (i != 0 && dcb->connector.entry[i].index == + dcb->connector.entry[i - 1].index) continue; nouveau_connector_create(dev, &dcb->connector.entry[i]); } diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_fb.c b/trunk/drivers/gpu/drm/nouveau/nv50_fb.c deleted file mode 100644 index a95e6941ba88..000000000000 --- a/trunk/drivers/gpu/drm/nouveau/nv50_fb.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" - -int -nv50_fb_init(struct drm_device *dev) -{ - /* This is needed to get meaningful information from 100c90 - * on traps. No idea what these values mean exactly. */ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - switch (dev_priv->chipset) { - case 0x50: - nv_wr32(dev, 0x100c90, 0x0707ff); - break; - case 0xa5: - case 0xa8: - nv_wr32(dev, 0x100c90, 0x0d0fff); - break; - default: - nv_wr32(dev, 0x100c90, 0x1d07ff); - break; - } - - return 0; -} - -void -nv50_fb_takedown(struct drm_device *dev) -{ -} diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_fbcon.c b/trunk/drivers/gpu/drm/nouveau/nv50_fbcon.c index 25a3cd8794f9..993c7126fbde 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -233,7 +233,7 @@ nv50_fbcon_accel_init(struct fb_info *info) BEGIN_RING(chan, NvSub2D, 0x0808, 3); OUT_RING(chan, 0); OUT_RING(chan, 0); - OUT_RING(chan, 1); + OUT_RING(chan, 0); BEGIN_RING(chan, NvSub2D, 0x081c, 1); OUT_RING(chan, 1); BEGIN_RING(chan, NvSub2D, 0x0840, 4); diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_graph.c b/trunk/drivers/gpu/drm/nouveau/nv50_graph.c index c62b33a02f88..857a09671a39 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_graph.c @@ -56,10 +56,6 @@ nv50_graph_init_intr(struct drm_device *dev) static void nv50_graph_init_regs__nv(struct drm_device *dev) { - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t units = nv_rd32(dev, 0x1540); - int i; - NV_DEBUG(dev, "\n"); nv_wr32(dev, 0x400804, 0xc0000000); @@ -69,20 +65,6 @@ nv50_graph_init_regs__nv(struct drm_device *dev) nv_wr32(dev, 0x405018, 0xc0000000); nv_wr32(dev, 0x402000, 0xc0000000); - for (i = 0; i < 16; i++) { - if (units & 1 << i) { - if (dev_priv->chipset < 0xa0) { - nv_wr32(dev, 0x408900 + (i << 12), 0xc0000000); - nv_wr32(dev, 0x408e08 + (i << 12), 0xc0000000); - nv_wr32(dev, 0x408314 + (i << 12), 0xc0000000); - } else { - nv_wr32(dev, 0x408600 + (i << 11), 0xc0000000); - nv_wr32(dev, 0x408708 + (i << 11), 0xc0000000); - nv_wr32(dev, 0x40831c + (i << 11), 0xc0000000); - } - } - } - nv_wr32(dev, 0x400108, 0xffffffff); nv_wr32(dev, 0x400824, 0x00004000); @@ -247,6 +229,10 @@ nv50_graph_create_context(struct nouveau_channel *chan) nouveau_grctx_vals_load(dev, ctx); } nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); + if ((dev_priv->chipset & 0xf0) == 0xa0) + nv_wo32(dev, ctx, 0x00004/4, 0x00000000); + else + nv_wo32(dev, ctx, 0x0011c/4, 0x00000000); dev_priv->engine.instmem.finish_access(dev); return 0; diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_grctx.c b/trunk/drivers/gpu/drm/nouveau/nv50_grctx.c index 546b31949a30..d105fcd42ca0 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_grctx.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_grctx.c @@ -64,9 +64,6 @@ #define CP_FLAG_ALWAYS ((2 * 32) + 13) #define CP_FLAG_ALWAYS_FALSE 0 #define CP_FLAG_ALWAYS_TRUE 1 -#define CP_FLAG_INTR ((2 * 32) + 15) -#define CP_FLAG_INTR_NOT_PENDING 0 -#define CP_FLAG_INTR_PENDING 1 #define CP_CTX 0x00100000 #define CP_CTX_COUNT 0x000f0000 @@ -217,8 +214,6 @@ nv50_grctx_init(struct nouveau_grctx *ctx) cp_name(ctx, cp_setup_save); cp_set (ctx, UNK1D, SET); cp_wait(ctx, STATUS, BUSY); - cp_wait(ctx, INTR, PENDING); - cp_bra (ctx, STATUS, BUSY, cp_setup_save); cp_set (ctx, UNK01, SET); cp_set (ctx, SWAP_DIRECTION, SAVE); @@ -274,7 +269,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) int offset, base; uint32_t units = nv_rd32 (ctx->dev, 0x1540); - /* 0800: DISPATCH */ + /* 0800 */ cp_ctx(ctx, 0x400808, 7); gr_def(ctx, 0x400814, 0x00000030); cp_ctx(ctx, 0x400834, 0x32); @@ -305,7 +300,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) gr_def(ctx, 0x400b20, 0x0001629d); } - /* 0C00: VFETCH */ + /* 0C00 */ cp_ctx(ctx, 0x400c08, 0x2); gr_def(ctx, 0x400c08, 0x0000fe0c); @@ -331,7 +326,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) cp_ctx(ctx, 0x401540, 0x5); gr_def(ctx, 0x401550, 0x00001018); - /* 1800: STREAMOUT */ + /* 1800 */ cp_ctx(ctx, 0x401814, 0x1); gr_def(ctx, 0x401814, 0x000000ff); if (dev_priv->chipset == 0x50) { @@ -646,7 +641,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) if (dev_priv->chipset == 0x50) cp_ctx(ctx, 0x4063e0, 0x1); - /* 6800: M2MF */ + /* 6800 */ if (dev_priv->chipset < 0x90) { cp_ctx(ctx, 0x406814, 0x2b); gr_def(ctx, 0x406818, 0x00000f80); diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo.c b/trunk/drivers/gpu/drm/ttm/ttm_bo.c index 9db02bb3e3fe..c7320ce4567d 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo.c @@ -1425,8 +1425,8 @@ int ttm_bo_global_init(struct ttm_global_reference *ref) atomic_set(&glob->bo_count, 0); - ret = kobject_init_and_add( - &glob->kobj, &ttm_bo_glob_kobj_type, ttm_get_kobj(), "buffer_objects"); + kobject_init(&glob->kobj, &ttm_bo_glob_kobj_type); + ret = kobject_add(&glob->kobj, ttm_get_kobj(), "buffer_objects"); if (unlikely(ret != 0)) kobject_put(&glob->kobj); return ret; diff --git a/trunk/drivers/gpu/drm/ttm/ttm_memory.c b/trunk/drivers/gpu/drm/ttm/ttm_memory.c index f9d6b35c3b88..f5245c02b8fd 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_memory.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_memory.c @@ -260,8 +260,8 @@ static int ttm_mem_init_kernel_zone(struct ttm_mem_global *glob, zone->used_mem = 0; zone->glob = glob; glob->zone_kernel = zone; - ret = kobject_init_and_add( - &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name); + kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type); + ret = kobject_add(&zone->kobj, &glob->kobj, zone->name); if (unlikely(ret != 0)) { kobject_put(&zone->kobj); return ret; @@ -296,8 +296,8 @@ static int ttm_mem_init_highmem_zone(struct ttm_mem_global *glob, zone->used_mem = 0; zone->glob = glob; glob->zone_highmem = zone; - ret = kobject_init_and_add( - &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name); + kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type); + ret = kobject_add(&zone->kobj, &glob->kobj, zone->name); if (unlikely(ret != 0)) { kobject_put(&zone->kobj); return ret; @@ -343,8 +343,8 @@ static int ttm_mem_init_dma32_zone(struct ttm_mem_global *glob, zone->used_mem = 0; zone->glob = glob; glob->zone_dma32 = zone; - ret = kobject_init_and_add( - &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name); + kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type); + ret = kobject_add(&zone->kobj, &glob->kobj, zone->name); if (unlikely(ret != 0)) { kobject_put(&zone->kobj); return ret; @@ -365,8 +365,10 @@ int ttm_mem_global_init(struct ttm_mem_global *glob) glob->swap_queue = create_singlethread_workqueue("ttm_swap"); INIT_WORK(&glob->work, ttm_shrink_work); init_waitqueue_head(&glob->queue); - ret = kobject_init_and_add( - &glob->kobj, &ttm_mem_glob_kobj_type, ttm_get_kobj(), "memory_accounting"); + kobject_init(&glob->kobj, &ttm_mem_glob_kobj_type); + ret = kobject_add(&glob->kobj, + ttm_get_kobj(), + "memory_accounting"); if (unlikely(ret != 0)) { kobject_put(&glob->kobj); return ret; diff --git a/trunk/drivers/gpu/drm/ttm/ttm_tt.c b/trunk/drivers/gpu/drm/ttm/ttm_tt.c index bab6cd8d8a1e..a759170763bb 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_tt.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_tt.c @@ -28,13 +28,13 @@ * Authors: Thomas Hellstrom */ +#include #include #include #include #include #include #include "drm_cache.h" -#include "drm_mem_util.h" #include "ttm/ttm_module.h" #include "ttm/ttm_bo_driver.h" #include "ttm/ttm_placement.h" @@ -43,15 +43,32 @@ static int ttm_tt_swapin(struct ttm_tt *ttm); /** * Allocates storage for pointers to the pages that back the ttm. + * + * Uses kmalloc if possible. Otherwise falls back to vmalloc. */ static void ttm_tt_alloc_page_directory(struct ttm_tt *ttm) { - ttm->pages = drm_calloc_large(ttm->num_pages, sizeof(*ttm->pages)); + unsigned long size = ttm->num_pages * sizeof(*ttm->pages); + ttm->pages = NULL; + + if (size <= PAGE_SIZE) + ttm->pages = kzalloc(size, GFP_KERNEL); + + if (!ttm->pages) { + ttm->pages = vmalloc_user(size); + if (ttm->pages) + ttm->page_flags |= TTM_PAGE_FLAG_VMALLOC; + } } static void ttm_tt_free_page_directory(struct ttm_tt *ttm) { - drm_free_large(ttm->pages); + if (ttm->page_flags & TTM_PAGE_FLAG_VMALLOC) { + vfree(ttm->pages); + ttm->page_flags &= ~TTM_PAGE_FLAG_VMALLOC; + } else { + kfree(ttm->pages); + } ttm->pages = NULL; } diff --git a/trunk/drivers/gpu/drm/vmwgfx/Kconfig b/trunk/drivers/gpu/drm/vmwgfx/Kconfig index 30ad13344f7b..f20b8bcbef39 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/Kconfig +++ b/trunk/drivers/gpu/drm/vmwgfx/Kconfig @@ -1,6 +1,6 @@ config DRM_VMWGFX tristate "DRM driver for VMware Virtual GPU" - depends on DRM && PCI && FB + depends on DRM && PCI select FB_DEFERRED_IO select FB_CFB_FILLRECT select FB_CFB_COPYAREA diff --git a/trunk/include/drm/drmP.h b/trunk/include/drm/drmP.h index de2f82efb15f..4a3c4e441027 100644 --- a/trunk/include/drm/drmP.h +++ b/trunk/include/drm/drmP.h @@ -1545,7 +1545,39 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map) { } -#include "drm_mem_util.h" + +static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) +{ + if (size != 0 && nmemb > ULONG_MAX / size) + return NULL; + + if (size * nmemb <= PAGE_SIZE) + return kcalloc(nmemb, size, GFP_KERNEL); + + return __vmalloc(size * nmemb, + GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); +} + +/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */ +static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size) +{ + if (size != 0 && nmemb > ULONG_MAX / size) + return NULL; + + if (size * nmemb <= PAGE_SIZE) + return kmalloc(nmemb * size, GFP_KERNEL); + + return __vmalloc(size * nmemb, + GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL); +} + +static __inline void drm_free_large(void *ptr) +{ + if (!is_vmalloc_addr(ptr)) + return kfree(ptr); + + vfree(ptr); +} /*@}*/ #endif /* __KERNEL__ */ diff --git a/trunk/include/drm/drm_mem_util.h b/trunk/include/drm/drm_mem_util.h deleted file mode 100644 index 6bd325fedc87..000000000000 --- a/trunk/include/drm/drm_mem_util.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Jesse Barnes - * - */ -#ifndef _DRM_MEM_UTIL_H_ -#define _DRM_MEM_UTIL_H_ - -#include - -static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) -{ - if (size != 0 && nmemb > ULONG_MAX / size) - return NULL; - - if (size * nmemb <= PAGE_SIZE) - return kcalloc(nmemb, size, GFP_KERNEL); - - return __vmalloc(size * nmemb, - GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); -} - -/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */ -static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size) -{ - if (size != 0 && nmemb > ULONG_MAX / size) - return NULL; - - if (size * nmemb <= PAGE_SIZE) - return kmalloc(nmemb * size, GFP_KERNEL); - - return __vmalloc(size * nmemb, - GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL); -} - -static __inline void drm_free_large(void *ptr) -{ - if (!is_vmalloc_addr(ptr)) - return kfree(ptr); - - vfree(ptr); -} - -#endif diff --git a/trunk/include/drm/drm_pciids.h b/trunk/include/drm/drm_pciids.h index 676104b7818c..04a6ebc27b96 100644 --- a/trunk/include/drm/drm_pciids.h +++ b/trunk/include/drm/drm_pciids.h @@ -410,6 +410,7 @@ {0x1002, 0x9712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9714, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9715, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0, 0, 0} #define r128_PCI_IDS \ diff --git a/trunk/include/drm/ttm/ttm_bo_driver.h b/trunk/include/drm/ttm/ttm_bo_driver.h index e929c27ede22..e3f1b4a4b601 100644 --- a/trunk/include/drm/ttm/ttm_bo_driver.h +++ b/trunk/include/drm/ttm/ttm_bo_driver.h @@ -115,6 +115,7 @@ struct ttm_backend { struct ttm_backend_func *func; }; +#define TTM_PAGE_FLAG_VMALLOC (1 << 0) #define TTM_PAGE_FLAG_USER (1 << 1) #define TTM_PAGE_FLAG_USER_DIRTY (1 << 2) #define TTM_PAGE_FLAG_WRITE (1 << 3)