From: <dar...@ke...> - 2009-03-19 06:13:51
|
linux-core/nouveau_bo.c | 3 linux-core/nouveau_crtc.h | 12 ++- linux-core/nouveau_fence.c | 2 linux-core/nouveau_gem.c | 11 ++ linux-core/nv50_connector.c | 5 + linux-core/nv50_crtc.c | 80 +++++++++++++++----- linux-core/nv50_cursor.c | 175 +++++++++++++------------------------------- linux-core/nv50_cursor.h | 45 ----------- linux-core/nv50_dac.c | 10 +- linux-core/nv50_sor.c | 17 ++-- shared-core/nouveau_drv.h | 4 + 11 files changed, 161 insertions(+), 203 deletions(-) New commits: commit 47c68ee6e4c180c18b8d58c74f12c8f90af9da3d Author: Ben Skeggs <bs...@re...> Date: Wed Mar 18 22:15:10 2009 +1000 nv50: enable dithering by default on lvds diff --git a/linux-core/nv50_connector.c b/linux-core/nv50_connector.c index f70cb42..c820cf8 100644 --- a/linux-core/nv50_connector.c +++ b/linux-core/nv50_connector.c @@ -540,7 +540,10 @@ int nv50_connector_create(struct drm_device *dev, int bus, int i2c_index, int ty break; } - connector->use_dithering = false; + if (type == DRM_MODE_CONNECTOR_LVDS) + connector->use_dithering = true; + else + connector->use_dithering = false; if (i2c_index < 0xf) { i2c_index = dev_priv->dcb_table.i2c_read[i2c_index]; commit 56887e62e7306a6b37f9c62c391fbf2592eb529b Author: Ben Skeggs <bs...@re...> Date: Wed Mar 18 19:29:10 2009 +1000 nv50: some kms fixes diff --git a/linux-core/nv50_crtc.c b/linux-core/nv50_crtc.c index ed38425..a01679e 100644 --- a/linux-core/nv50_crtc.c +++ b/linux-core/nv50_crtc.c @@ -506,25 +506,39 @@ nv50_crtc_gamma_set(struct drm_crtc *drm_crtc, u16 *r, u16 *g, u16 *b, nv50_crtc_lut_load(crtc); } +static int +nv50_crtc_helper_set_config(struct drm_mode_set *set) +{ + struct drm_nouveau_private *dev_priv = set->crtc->dev->dev_private; + int ret; + + dev_priv->in_modeset = true; + ret = drm_crtc_helper_set_config(set); + dev_priv->in_modeset = false; + return ret; +} + static const struct drm_crtc_funcs nv50_crtc_funcs = { .save = NULL, .restore = NULL, .cursor_set = nv50_crtc_cursor_set, .cursor_move = nv50_crtc_cursor_move, .gamma_set = nv50_crtc_gamma_set, - .set_config = drm_crtc_helper_set_config, + .set_config = nv50_crtc_helper_set_config, .destroy = nv50_crtc_destroy, }; static void nv50_crtc_dpms(struct drm_crtc *drm_crtc, int mode) { + struct drm_nouveau_private *dev_priv = drm_crtc->dev->dev_private; + struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); + + if (dev_priv->in_modeset) + nv50_crtc_blank(crtc, true); } static void nv50_crtc_prepare(struct drm_crtc *drm_crtc) { - struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); - - nv50_crtc_blank(crtc, true); } static void nv50_crtc_commit(struct drm_crtc *drm_crtc) diff --git a/linux-core/nv50_dac.c b/linux-core/nv50_dac.c index 98c378f..31c73d2 100644 --- a/linux-core/nv50_dac.c +++ b/linux-core/nv50_dac.c @@ -121,6 +121,11 @@ static void nv50_dac_dpms(struct drm_encoder *drm_encoder, int mode) DRM_DEBUG("or %d\n", or); + if (dev_priv->in_modeset) { + nv50_dac_disconnect(encoder); + return; + } + /* wait for it to be done */ if (!nv_wait(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or), NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_PENDING, 0)) { @@ -211,15 +216,14 @@ static void nv50_dac_mode_set(struct drm_encoder *drm_encoder, mode_ctl |= 0x100; } - if (mode->flags & DRM_MODE_FLAG_NHSYNC) + if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) mode_ctl2 |= NV50_DAC_MODE_CTRL2_NHSYNC; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) + if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) mode_ctl2 |= NV50_DAC_MODE_CTRL2_NVSYNC; OUT_MODE(NV50_DAC0_MODE_CTRL + offset, mode_ctl); OUT_MODE(NV50_DAC0_MODE_CTRL2 + offset, mode_ctl2); - OUT_MODE(NV50_UPDATE_DISPLAY, 0); } static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { diff --git a/linux-core/nv50_sor.c b/linux-core/nv50_sor.c index a147fb6..ff3dd42 100644 --- a/linux-core/nv50_sor.c +++ b/linux-core/nv50_sor.c @@ -80,6 +80,11 @@ static void nv50_sor_dpms(struct drm_encoder *drm_encoder, int mode) DRM_DEBUG("or %d\n", encoder->or); + if (dev_priv->in_modeset) { + nv50_sor_disconnect(encoder); + return; + } + /* wait for it to be done */ if (!nv_wait(NV50_PDISPLAY_SOR_REGS_DPMS_CTRL(or), NV50_PDISPLAY_SOR_REGS_DPMS_CTRL_PENDING, 0)) { @@ -147,15 +152,10 @@ static bool nv50_sor_mode_fixup(struct drm_encoder *drm_encoder, static void nv50_sor_prepare(struct drm_encoder *drm_encoder) { - struct nouveau_encoder *encoder = to_nouveau_encoder(drm_encoder); - - nv50_sor_dpms(drm_encoder, DRM_MODE_DPMS_OFF); - nv50_sor_disconnect(encoder); } static void nv50_sor_commit(struct drm_encoder *drm_encoder) { - nv50_sor_dpms(drm_encoder, DRM_MODE_DPMS_ON); } static void nv50_sor_mode_set(struct drm_encoder *drm_encoder, @@ -174,7 +174,7 @@ static void nv50_sor_mode_set(struct drm_encoder *drm_encoder, mode_ctl |= NV50_SOR_MODE_CTRL_LVDS; } else { mode_ctl |= NV50_SOR_MODE_CTRL_TMDS; - if (mode->clock > 165000) + if (adjusted_mode->clock > 165000) mode_ctl |= NV50_SOR_MODE_CTRL_TMDS_DUAL_LINK; } @@ -183,14 +183,13 @@ static void nv50_sor_mode_set(struct drm_encoder *drm_encoder, else mode_ctl |= NV50_SOR_MODE_CTRL_CRTC0; - if (mode->flags & DRM_MODE_FLAG_NHSYNC) + if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) mode_ctl |= NV50_SOR_MODE_CTRL_NHSYNC; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) + if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) mode_ctl |= NV50_SOR_MODE_CTRL_NVSYNC; OUT_MODE(NV50_SOR0_MODE_CTRL + offset, mode_ctl); - OUT_MODE(NV50_UPDATE_DISPLAY, 0); } static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = { diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 09f1bc9..87ef8ef 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -347,6 +347,7 @@ struct drm_nouveau_private { struct list_head gpuobj_list; void *display_priv; /* internal modesetting */ + bool in_modeset; struct bios bios; commit 4fec64f1663441eea4b5a1e8550c6bf3cae6e1fb Author: Ben Skeggs <bs...@re...> Date: Wed Mar 18 19:28:27 2009 +1000 nv50: unpin cursor when not bound to a crtc diff --git a/linux-core/nv50_crtc.c b/linux-core/nv50_crtc.c index 3536237..ed38425 100644 --- a/linux-core/nv50_crtc.c +++ b/linux-core/nv50_crtc.c @@ -431,6 +431,8 @@ static int nv50_crtc_cursor_set(struct drm_crtc *drm_crtc, return -EINVAL; if (crtc->cursor.gem) { + nouveau_gem_unpin(crtc->cursor.gem); + mutex_lock(&dev->struct_mutex); drm_gem_object_unreference(crtc->cursor.gem); mutex_unlock(&dev->struct_mutex); commit abfe1738e084a9a9f94dc3b69140848c5c0fab64 Author: Ben Skeggs <bs...@re...> Date: Wed Mar 18 19:27:48 2009 +1000 nv50: pin/unpin framebuffer as required diff --git a/linux-core/nouveau_gem.c b/linux-core/nouveau_gem.c index 0956825..32ecec5 100644 --- a/linux-core/nouveau_gem.c +++ b/linux-core/nouveau_gem.c @@ -151,6 +151,17 @@ nouveau_gem_pin(struct drm_gem_object *gem, uint32_t domain) } int +nouveau_gem_unpin(struct drm_gem_object *gem) +{ + struct nouveau_gem_object *ngem = gem->driver_private; + int ret; + + ret = drm_bo_do_validate(ngem->bo, 0, DRM_BO_FLAG_NO_EVICT, + DRM_BO_HINT_DONT_FENCE, 0); + return ret; +} + +int nouveau_gem_ioctl_new(struct drm_device *dev, void *data, struct drm_file *file_priv) { diff --git a/linux-core/nv50_crtc.c b/linux-core/nv50_crtc.c index f4e704e..3536237 100644 --- a/linux-core/nv50_crtc.c +++ b/linux-core/nv50_crtc.c @@ -553,6 +553,19 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *drm_crtc, int x, int y, struct nouveau_framebuffer *fb = to_nouveau_framebuffer(drm_fb); struct nouveau_gem_object *ngem = nouveau_gem_object(fb->gem); uint32_t offset = crtc->index * 0x400; + int ret; + + /*FIXME: drm.git is a little behind kernel kms... */ +#if 0 + ret = nouveau_gem_pin(fb->gem, NOUVEAU_GEM_DOMAIN_VRAM); + if (ret) + return ret; + + if (old_fb) { + struct nouveau_framebuffer *fb = to_nouveau_framebuffer(old_fb); + nouveau_gem_unpin(fb->gem); + } +#endif crtc->fb.offset = ngem->bo->offset - dev_priv->vm_vram_base; diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index a13f377..09f1bc9 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -691,6 +691,7 @@ extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *, int size, int align, uint32_t domain, struct drm_gem_object **); extern int nouveau_gem_pin(struct drm_gem_object *, uint32_t domain); +extern int nouveau_gem_unpin(struct drm_gem_object *); extern int nouveau_gem_ioctl_new(struct drm_device *, void *, struct drm_file *); extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *, commit 7e0ed73e0cf952f3378abae854dd39dcf3787292 Author: Ben Skeggs <bs...@re...> Date: Wed Mar 18 19:26:51 2009 +1000 nouveau: use nouveau_fence_channel() to get chan for m2mf move diff --git a/linux-core/nouveau_bo.c b/linux-core/nouveau_bo.c index 1d4d1be..09328e9 100644 --- a/linux-core/nouveau_bo.c +++ b/linux-core/nouveau_bo.c @@ -161,9 +161,10 @@ nouveau_bo_move_m2mf(struct drm_buffer_object *bo, int evict, int no_wait, { struct drm_device *dev = bo->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->fifos[bo->new_fence_class]; + struct nouveau_channel *chan; uint32_t page_count; + chan = nouveau_fence_channel(dev, bo->new_fence_class); if (!chan) { DRM_ERROR("channel %d non-existant, using kchan\n", bo->fence_class); diff --git a/linux-core/nouveau_fence.c b/linux-core/nouveau_fence.c index 26f98c0..6ba3c04 100644 --- a/linux-core/nouveau_fence.c +++ b/linux-core/nouveau_fence.c @@ -29,7 +29,7 @@ #include "nouveau_drv.h" #include "nouveau_dma.h" -static struct nouveau_channel * +struct nouveau_channel * nouveau_fence_channel(struct drm_device *dev, uint32_t class) { struct drm_nouveau_private *dev_priv = dev->dev_private; diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index eb99ce5..a13f377 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -681,6 +681,8 @@ extern struct drm_bo_driver nouveau_bo_driver; /* nouveau_fence.c */ extern struct drm_fence_driver nouveau_fence_driver; extern void nouveau_fence_handler(struct drm_device *dev, int channel); +extern struct nouveau_channel * +nouveau_fence_channel(struct drm_device *, uint32_t fence_class); /* nouveau_gem.c */ extern int nouveau_gem_object_new(struct drm_gem_object *); commit ec5abde7b330ce944a9639dbbc039cdb331755ad Author: Ben Skeggs <bs...@re...> Date: Wed Mar 18 19:21:57 2009 +1000 nv50: kill off nv50_cursor diff --git a/linux-core/nouveau_crtc.h b/linux-core/nouveau_crtc.h index 53b9584..5104431 100644 --- a/linux-core/nouveau_crtc.h +++ b/linux-core/nouveau_crtc.h @@ -41,7 +41,15 @@ struct nouveau_crtc { uint32_t offset; } fb; - struct nv50_cursor *cursor; + struct { + struct drm_gem_object *gem; + bool visible; + uint32_t offset; + void (*set_offset)(struct nouveau_crtc *, uint32_t offset); + void (*set_pos)(struct nouveau_crtc *, int x, int y); + void (*hide)(struct nouveau_crtc *, bool update); + void (*show)(struct nouveau_crtc *, bool update); + } cursor; struct { struct mem_block *mem; @@ -60,5 +68,7 @@ struct nouveau_crtc { #define to_nouveau_crtc(x) container_of((x), struct nouveau_crtc, base) int nv50_crtc_create(struct drm_device *dev, int index); +int nv50_cursor_init(struct nouveau_crtc *); +void nv50_cursor_fini(struct nouveau_crtc *); #endif /* __NOUVEAU_CRTC_H__ */ diff --git a/linux-core/nv50_crtc.c b/linux-core/nv50_crtc.c index 95b5fc9..f4e704e 100644 --- a/linux-core/nv50_crtc.c +++ b/linux-core/nv50_crtc.c @@ -34,7 +34,6 @@ #include "nouveau_fb.h" #include "nouveau_fbcon.h" #include "nouveau_connector.h" -#include "nv50_cursor.h" #define NV50_LUT_INDEX(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8))) static int @@ -95,7 +94,7 @@ nv50_crtc_blank(struct nouveau_crtc *crtc, bool blanked) DRM_DEBUG("%s\n", blanked ? "blanked" : "unblanked"); if (blanked) { - crtc->cursor->hide(crtc, false); + crtc->cursor.hide(crtc, false); OUT_MODE(NV50_CRTC0_CLUT_MODE + offset, NV50_CRTC0_CLUT_MODE_BLANK); @@ -107,11 +106,11 @@ nv50_crtc_blank(struct nouveau_crtc *crtc, bool blanked) OUT_MODE(NV50_CRTC0_BLANK_CTRL + offset, NV50_CRTC0_BLANK_CTRL_BLANK); } else { - crtc->cursor->set_offset(crtc); - if (crtc->cursor->visible) - crtc->cursor->show(crtc, false); + crtc->cursor.set_offset(crtc, crtc->cursor.offset); + if (crtc->cursor.visible) + crtc->cursor.show(crtc, false); else - crtc->cursor->hide(crtc, false); + crtc->cursor.hide(crtc, false); OUT_MODE(NV50_CRTC0_CLUT_MODE + offset, crtc->lut.depth == 8 ? NV50_CRTC0_CLUT_MODE_OFF : NV50_CRTC0_CLUT_MODE_ON); @@ -410,7 +409,7 @@ static void nv50_crtc_destroy(struct drm_crtc *drm_crtc) drm_crtc_cleanup(&crtc->base); - nv50_cursor_destroy(crtc); + nv50_cursor_fini(crtc); if (crtc->lut.mem) nouveau_mem_free(drm_crtc->dev, crtc->lut.mem); @@ -431,10 +430,21 @@ static int nv50_crtc_cursor_set(struct drm_crtc *drm_crtc, if (width != 64 || height != 64) return -EINVAL; + if (crtc->cursor.gem) { + mutex_lock(&dev->struct_mutex); + drm_gem_object_unreference(crtc->cursor.gem); + mutex_unlock(&dev->struct_mutex); + crtc->cursor.gem = NULL; + } + if (buffer_handle) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gem_object *ngem; + gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); if (!gem) return -EINVAL; + ngem = gem->driver_private; ret = nouveau_gem_pin(gem, NOUVEAU_GEM_DOMAIN_VRAM); if (ret) { @@ -444,22 +454,25 @@ static int nv50_crtc_cursor_set(struct drm_crtc *drm_crtc, return ret; } - crtc->cursor->set_bo(crtc, gem); - crtc->cursor->set_offset(crtc); - ret = crtc->cursor->show(crtc, true); + crtc->cursor.offset = ngem->bo->offset - + dev_priv->vm_vram_base; + crtc->cursor.set_offset(crtc, crtc->cursor.offset); + crtc->cursor.show(crtc, true); + crtc->cursor.gem = gem; } else { - crtc->cursor->set_bo(crtc, NULL); - crtc->cursor->hide(crtc, true); + crtc->cursor.hide(crtc, true); } return ret; } -static int nv50_crtc_cursor_move(struct drm_crtc *drm_crtc, int x, int y) +static int +nv50_crtc_cursor_move(struct drm_crtc *drm_crtc, int x, int y) { struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); - return crtc->cursor->set_pos(crtc, x, y); + crtc->cursor.set_pos(crtc, x, y); + return 0; } void @@ -756,6 +769,6 @@ int nv50_crtc_create(struct drm_device *dev, int index) drm_crtc_helper_add(&crtc->base, &nv50_crtc_helper_funcs); drm_mode_crtc_set_gamma_size(&crtc->base, 256); - nv50_cursor_create(crtc); + nv50_cursor_init(crtc); return 0; } diff --git a/linux-core/nv50_cursor.c b/linux-core/nv50_cursor.c index 10736de..61cf304 100644 --- a/linux-core/nv50_cursor.c +++ b/linux-core/nv50_cursor.c @@ -29,62 +29,10 @@ #include "nouveau_reg.h" #include "nouveau_drv.h" #include "nouveau_crtc.h" -#include "nv50_cursor.h" #include "nv50_display.h" -static int nv50_cursor_enable(struct nouveau_crtc *crtc) -{ - struct drm_device *dev = crtc->base.dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - int idx = crtc->index; - - DRM_DEBUG("\n"); - - nv_wr32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0x2000); - if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_MASK, 0)) { - DRM_ERROR("timeout: CURSOR_CTRL2_STATUS == 0\n"); - DRM_ERROR("CURSOR_CTRL2 = 0x%08x\n", - nv_rd32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx))); - return -EBUSY; - } - - nv_wr32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(crtc->index), - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON); - if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE, - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) { - DRM_ERROR("timeout: CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", idx); - DRM_ERROR("CURSOR_CTRL2(%d) = 0x%08x\n", idx, - nv_rd32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx))); - return -EBUSY; - } - - return 0; -} - -static int nv50_cursor_disable(struct nouveau_crtc *crtc) -{ - struct drm_device *dev = crtc->base.dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - int idx = crtc->index; - - DRM_DEBUG("\n"); - - nv_wr32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0); - if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_MASK, 0)) { - DRM_ERROR("timeout: CURSOR_CTRL2_STATUS == 0\n"); - DRM_ERROR("CURSOR_CTRL2 = 0x%08x\n", - nv_rd32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx))); - return -EBUSY; - } - - return 0; -} - -/* Calling update or changing the stored cursor state is left to the higher level ioctl's. */ -static int nv50_cursor_show(struct nouveau_crtc *crtc, bool update) +static void +nv50_cursor_show(struct nouveau_crtc *crtc, bool update) { struct drm_nouveau_private *dev_priv = crtc->base.dev->dev_private; struct drm_device *dev = crtc->base.dev; @@ -92,13 +40,6 @@ static int nv50_cursor_show(struct nouveau_crtc *crtc, bool update) DRM_DEBUG("\n"); - /* Better not show the cursor when we have none. */ - /* TODO: is cursor offset actually set? */ - if (!crtc->cursor->gem) { - DRM_ERROR("No cursor available on crtc %d\n", crtc->index); - return -EINVAL; - } - if (dev_priv->chipset != 0x50) OUT_MODE(NV84_CRTC0_CURSOR_DMA + offset, NV84_CRTC0_CURSOR_DMA_LOCAL); @@ -106,13 +47,12 @@ static int nv50_cursor_show(struct nouveau_crtc *crtc, bool update) if (update) { OUT_MODE(NV50_UPDATE_DISPLAY, 0); - crtc->cursor->visible = true; + crtc->cursor.visible = true; } - - return 0; } -static int nv50_cursor_hide(struct nouveau_crtc *crtc, bool update) +static void +nv50_cursor_hide(struct nouveau_crtc *crtc, bool update) { struct drm_nouveau_private *dev_priv = crtc->base.dev->dev_private; struct drm_device *dev = crtc->base.dev; @@ -127,91 +67,80 @@ static int nv50_cursor_hide(struct nouveau_crtc *crtc, bool update) if (update) { OUT_MODE(NV50_UPDATE_DISPLAY, 0); - crtc->cursor->visible = false; + crtc->cursor.visible = false; } - - return 0; } -static int nv50_cursor_set_pos(struct nouveau_crtc *crtc, int x, int y) +static void +nv50_cursor_set_pos(struct nouveau_crtc *crtc, int x, int y) { struct drm_nouveau_private *dev_priv = crtc->base.dev->dev_private; - nv_wr32(NV50_HW_CURSOR_POS(crtc->index), ((y & 0xFFFF) << 16) | (x & 0xFFFF)); + nv_wr32(NV50_HW_CURSOR_POS(crtc->index), + ((y & 0xFFFF) << 16) | (x & 0xFFFF)); /* Needed to make the cursor move. */ nv_wr32(NV50_HW_CURSOR_POS_CTRL(crtc->index), 0); - - return 0; } -static int nv50_cursor_set_offset(struct nouveau_crtc *crtc) +static void +nv50_cursor_set_offset(struct nouveau_crtc *crtc, uint32_t offset) { struct drm_device *dev = crtc->base.dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gem_object *ngem = nouveau_gem_object(crtc->cursor->gem); DRM_DEBUG("\n"); - if (ngem) { - OUT_MODE(NV50_CRTC0_CURSOR_OFFSET + crtc->index * 0x400, - (ngem->bo->offset - dev_priv->vm_vram_base) >> 8); - } else { - OUT_MODE(NV50_CRTC0_CURSOR_OFFSET + crtc->index * 0x400, 0); - } - - return 0; + OUT_MODE(NV50_CRTC0_CURSOR_OFFSET + crtc->index * 0x0400, offset >> 8); } -static int -nv50_cursor_set_bo(struct nouveau_crtc *crtc, struct drm_gem_object *gem) +int +nv50_cursor_init(struct nouveau_crtc *crtc) { - struct nv50_cursor *cursor = crtc->cursor; + struct drm_device *dev = crtc->base.dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int idx = crtc->index; - if (cursor->gem) { - mutex_lock(&crtc->base.dev->struct_mutex); - drm_gem_object_unreference(cursor->gem); - mutex_unlock(&crtc->base.dev->struct_mutex); + nv_wr32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0x2000); + if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_MASK, 0)) { + DRM_ERROR("timeout: CURSOR_CTRL2_STATUS == 0\n"); + DRM_ERROR("CURSOR_CTRL2 = 0x%08x\n", + nv_rd32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx))); + return -EBUSY; + } - cursor->gem = NULL; + nv_wr32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(crtc->index), + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON); + if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE, + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) { + DRM_ERROR("timeout: CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", idx); + DRM_ERROR("CURSOR_CTRL2(%d) = 0x%08x\n", idx, + nv_rd32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx))); + return -EBUSY; } - cursor->gem = gem; + crtc->cursor.set_offset = nv50_cursor_set_offset; + crtc->cursor.set_pos = nv50_cursor_set_pos; + crtc->cursor.hide = nv50_cursor_hide; + crtc->cursor.show = nv50_cursor_show; return 0; } -int nv50_cursor_create(struct nouveau_crtc *crtc) +void +nv50_cursor_fini(struct nouveau_crtc *crtc) { - DRM_DEBUG("\n"); - - if (!crtc || crtc->cursor) - return -EINVAL; - - crtc->cursor = kzalloc(sizeof(struct nv50_cursor), GFP_KERNEL); - if (!crtc->cursor) - return -ENOMEM; - - nv50_cursor_enable(crtc); - - /* function pointers */ - crtc->cursor->show = nv50_cursor_show; - crtc->cursor->hide = nv50_cursor_hide; - crtc->cursor->set_pos = nv50_cursor_set_pos; - crtc->cursor->set_offset = nv50_cursor_set_offset; - crtc->cursor->set_bo = nv50_cursor_set_bo; - return 0; -} + struct drm_device *dev = crtc->base.dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int idx = crtc->index; -int nv50_cursor_destroy(struct nouveau_crtc *crtc) -{ DRM_DEBUG("\n"); - if (!crtc || !crtc->cursor) - return -EINVAL; - - nv50_cursor_disable(crtc); - - kfree(crtc->cursor); - crtc->cursor = NULL; - - return 0; + nv_wr32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0); + if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_MASK, 0)) { + DRM_ERROR("timeout: CURSOR_CTRL2_STATUS == 0\n"); + DRM_ERROR("CURSOR_CTRL2 = 0x%08x\n", + nv_rd32(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx))); + } } + diff --git a/linux-core/nv50_cursor.h b/linux-core/nv50_cursor.h deleted file mode 100644 index 089a69c..0000000 --- a/linux-core/nv50_cursor.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __NV50_CURSOR_H__ -#define __NV50_CURSOR_H__ - -struct nv50_cursor { - struct drm_gem_object *gem; - int x, y; - bool visible; - - int (*show) (struct nouveau_crtc *crtc, bool update); - int (*hide) (struct nouveau_crtc *crtc, bool update); - int (*set_pos) (struct nouveau_crtc *crtc, int x, int y); - int (*set_offset) (struct nouveau_crtc *crtc); - int (*set_bo) (struct nouveau_crtc *crtc, struct drm_gem_object *gem); -}; - -int nv50_cursor_create(struct nouveau_crtc *crtc); -int nv50_cursor_destroy(struct nouveau_crtc *crtc); - -#endif /* __NV50_CURSOR_H__ */ |