summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/dispnv04/cursor.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2013-03-21 09:45:11 +0400
committerBen Skeggs <bskeggs@redhat.com>2013-04-26 09:37:51 +0400
commit1a6463425552a8b9960e5a19b25421895846925c (patch)
treedda4f2208f78dbc654fbfcecb97575c3cc564a7e /drivers/gpu/drm/nouveau/dispnv04/cursor.c
parentb9a3140ce8fcd616b02533fbdef375a87a910daf (diff)
downloadlinux-1a6463425552a8b9960e5a19b25421895846925c.tar.xz
drm/nv04/disp: hide all the cruft away in its own little hole
It'd be pretty awesome if someone would care enough to port this all properly to a class interface, perhaps submitting a command stream to the core via a sw object on PFIFO (emulating how EVO works basically, and also what nvidia have done forever..).. But, this seems unlikely given how old this hardware is now, so, lets just hide it away. There's a heap of other bits and pieces laying around that are still tangled. I'll (re)move them in pieces. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/dispnv04/cursor.c')
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/cursor.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv04/cursor.c b/drivers/gpu/drm/nouveau/dispnv04/cursor.c
new file mode 100644
index 000000000000..a810303169de
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/dispnv04/cursor.c
@@ -0,0 +1,70 @@
+#include <drm/drmP.h>
+#include <drm/drm_mode.h>
+#include "nouveau_drm.h"
+#include "nouveau_reg.h"
+#include "nouveau_crtc.h"
+#include "hw.h"
+
+static void
+nv04_cursor_show(struct nouveau_crtc *nv_crtc, bool update)
+{
+ nv_show_cursor(nv_crtc->base.dev, nv_crtc->index, true);
+}
+
+static void
+nv04_cursor_hide(struct nouveau_crtc *nv_crtc, bool update)
+{
+ nv_show_cursor(nv_crtc->base.dev, nv_crtc->index, false);
+}
+
+static void
+nv04_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
+{
+ nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y;
+ NVWriteRAMDAC(nv_crtc->base.dev, nv_crtc->index,
+ NV_PRAMDAC_CU_START_POS,
+ XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) |
+ XLATE(x, 0, NV_PRAMDAC_CU_START_POS_X));
+}
+
+static void
+crtc_wr_cio_state(struct drm_crtc *crtc, struct nv04_crtc_reg *crtcstate, int index)
+{
+ NVWriteVgaCrtc(crtc->dev, nouveau_crtc(crtc)->index, index,
+ crtcstate->CRTC[index]);
+}
+
+static void
+nv04_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset)
+{
+ struct drm_device *dev = nv_crtc->base.dev;
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index];
+ struct drm_crtc *crtc = &nv_crtc->base;
+
+ regp->CRTC[NV_CIO_CRE_HCUR_ADDR0_INDEX] =
+ MASK(NV_CIO_CRE_HCUR_ASI) |
+ XLATE(offset, 17, NV_CIO_CRE_HCUR_ADDR0_ADR);
+ regp->CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] =
+ XLATE(offset, 11, NV_CIO_CRE_HCUR_ADDR1_ADR);
+ if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)
+ regp->CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] |=
+ MASK(NV_CIO_CRE_HCUR_ADDR1_CUR_DBL);
+ regp->CRTC[NV_CIO_CRE_HCUR_ADDR2_INDEX] = offset >> 24;
+
+ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX);
+ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX);
+ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX);
+ if (nv_device(drm->device)->card_type == NV_40)
+ nv_fix_nv40_hw_cursor(dev, nv_crtc->index);
+}
+
+int
+nv04_cursor_init(struct nouveau_crtc *crtc)
+{
+ crtc->cursor.set_offset = nv04_cursor_set_offset;
+ crtc->cursor.set_pos = nv04_cursor_set_pos;
+ crtc->cursor.hide = nv04_cursor_hide;
+ crtc->cursor.show = nv04_cursor_show;
+ return 0;
+}