aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/mgag200/mgag200_main.c
diff options
context:
space:
mode:
authorChristopher Harvey <charvey@matrox.com>2013-06-05 15:24:26 -0400
committerDave Airlie <airlied@gmail.com>2013-06-17 05:42:48 -0400
commita080db9fdda77ffaa43679d21b4bd78ead0cf9e1 (patch)
tree67a6b89e7d3b40dbe79fabc60b742b4992c1720f /drivers/gpu/drm/mgag200/mgag200_main.c
parentfb85ac4da8d202f89e0635e4ac2ac680d662be98 (diff)
drm/mgag200: Hardware cursor support
G200 cards support, at best, 16 colour palleted images for the cursor so we do a conversion in the cursor_set function, and reject cursors with more than 16 colours, or cursors with partial transparency. Xorg falls back gracefully to software cursors in this case. We can't disable/enable the cursor hardware without causing momentary corruption around the cursor. Instead, once the cursor is on we leave it on, and simulate turning the cursor off by moving it offscreen. This works well. Since we can't disable -> update -> enable the cursors, we double buffer cursor icons, then just move the base address that points to the old cursor, to the new. This also works well, but uses an extra page of memory. The cursor buffers are lazily-allocated on first cursor_set. This is to make sure they don't take priority over any framebuffers in case of limited memory. Here is a representation of how the bitmap for the cursor is mapped in G200 memory : Each line of color cursor use 6 Slices of 8 bytes. Slices 0 to 3 are used for the 4bpp bitmap, slice 4 for XOR mask and slice 5 for AND mask. Each line has the following format: // Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6 Byte 7 // // S0: P00-01 P02-03 P04-05 P06-07 P08-09 P10-11 P12-13 P14-15 // S1: P16-17 P18-19 P20-21 P22-23 P24-25 P26-27 P28-29 P30-31 // S2: P32-33 P34-35 P36-37 P38-39 P40-41 P42-43 P44-45 P46-47 // S3: P48-49 P50-51 P52-53 P54-55 P56-57 P58-59 P60-61 P62-63 // S4: X63-56 X55-48 X47-40 X39-32 X31-24 X23-16 X15-08 X07-00 // S5: A63-56 A55-48 A47-40 A39-32 A31-24 A23-16 A15-08 A07-00 // // S0 to S5 = Slices 0 to 5 // P00 to P63 = Bitmap - pixels 0 to 63 // X00 to X63 = always 0 - pixels 0 to 63 // A00 to A63 = transparent markers - pixels 0 to 63 // 1 means colour, 0 means transparent Signed-off-by: Christopher Harvey <charvey@matrox.com> Signed-off-by: Mathieu Larouche <mathieu.larouche@matrox.com> Acked-by: Julia Lemire <jlemire@matrox.com> Tested-by: Julia Lemire <jlemire@matrox.com> Signed-off-by: Dave Airlie <airlied@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/mgag200/mgag200_main.c')
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_main.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
index 99059237da38..51896757b3c2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -221,8 +221,27 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags)
221 dev->mode_config.prefer_shadow = 1; 221 dev->mode_config.prefer_shadow = 1;
222 222
223 r = mgag200_modeset_init(mdev); 223 r = mgag200_modeset_init(mdev);
224 if (r) 224 if (r) {
225 dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r); 225 dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r);
226 goto out;
227 }
228
229 /* Make small buffers to store a hardware cursor (double buffered icon updates) */
230 mgag200_bo_create(dev, roundup(48*64, PAGE_SIZE), 0, 0,
231 &mdev->cursor.pixels_1);
232 mgag200_bo_create(dev, roundup(48*64, PAGE_SIZE), 0, 0,
233 &mdev->cursor.pixels_2);
234 if (!mdev->cursor.pixels_2 || !mdev->cursor.pixels_1)
235 goto cursor_nospace;
236 mdev->cursor.pixels_current = mdev->cursor.pixels_1;
237 mdev->cursor.pixels_prev = mdev->cursor.pixels_2;
238 goto cursor_done;
239 cursor_nospace:
240 mdev->cursor.pixels_1 = NULL;
241 mdev->cursor.pixels_2 = NULL;
242 dev_warn(&dev->pdev->dev, "Could not allocate space for cursors. Not doing hardware cursors.\n");
243 cursor_done:
244
226out: 245out:
227 if (r) 246 if (r)
228 mgag200_driver_unload(dev); 247 mgag200_driver_unload(dev);