diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_fbcon.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_fbcon.c | 69 |
1 files changed, 23 insertions, 46 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 6dcf048eddb..6edf9dca35c 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c | |||
@@ -4,26 +4,18 @@ | |||
4 | #include "nouveau_ramht.h" | 4 | #include "nouveau_ramht.h" |
5 | #include "nouveau_fbcon.h" | 5 | #include "nouveau_fbcon.h" |
6 | 6 | ||
7 | void | 7 | int |
8 | nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 8 | nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) |
9 | { | 9 | { |
10 | struct nouveau_fbdev *nfbdev = info->par; | 10 | struct nouveau_fbdev *nfbdev = info->par; |
11 | struct drm_device *dev = nfbdev->dev; | 11 | struct drm_device *dev = nfbdev->dev; |
12 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 12 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
13 | struct nouveau_channel *chan = dev_priv->channel; | 13 | struct nouveau_channel *chan = dev_priv->channel; |
14 | int ret; | ||
14 | 15 | ||
15 | if (info->state != FBINFO_STATE_RUNNING) | 16 | ret = RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11); |
16 | return; | 17 | if (ret) |
17 | 18 | return ret; | |
18 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && | ||
19 | RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11)) { | ||
20 | nouveau_fbcon_gpu_lockup(info); | ||
21 | } | ||
22 | |||
23 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | ||
24 | cfb_fillrect(info, rect); | ||
25 | return; | ||
26 | } | ||
27 | 19 | ||
28 | if (rect->rop != ROP_COPY) { | 20 | if (rect->rop != ROP_COPY) { |
29 | BEGIN_RING(chan, NvSub2D, 0x02ac, 1); | 21 | BEGIN_RING(chan, NvSub2D, 0x02ac, 1); |
@@ -45,27 +37,21 @@ nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
45 | OUT_RING(chan, 3); | 37 | OUT_RING(chan, 3); |
46 | } | 38 | } |
47 | FIRE_RING(chan); | 39 | FIRE_RING(chan); |
40 | return 0; | ||
48 | } | 41 | } |
49 | 42 | ||
50 | void | 43 | int |
51 | nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) | 44 | nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) |
52 | { | 45 | { |
53 | struct nouveau_fbdev *nfbdev = info->par; | 46 | struct nouveau_fbdev *nfbdev = info->par; |
54 | struct drm_device *dev = nfbdev->dev; | 47 | struct drm_device *dev = nfbdev->dev; |
55 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 48 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
56 | struct nouveau_channel *chan = dev_priv->channel; | 49 | struct nouveau_channel *chan = dev_priv->channel; |
50 | int ret; | ||
57 | 51 | ||
58 | if (info->state != FBINFO_STATE_RUNNING) | 52 | ret = RING_SPACE(chan, 12); |
59 | return; | 53 | if (ret) |
60 | 54 | return ret; | |
61 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 12)) { | ||
62 | nouveau_fbcon_gpu_lockup(info); | ||
63 | } | ||
64 | |||
65 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | ||
66 | cfb_copyarea(info, region); | ||
67 | return; | ||
68 | } | ||
69 | 55 | ||
70 | BEGIN_RING(chan, NvSub2D, 0x0110, 1); | 56 | BEGIN_RING(chan, NvSub2D, 0x0110, 1); |
71 | OUT_RING(chan, 0); | 57 | OUT_RING(chan, 0); |
@@ -80,9 +66,10 @@ nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) | |||
80 | OUT_RING(chan, 0); | 66 | OUT_RING(chan, 0); |
81 | OUT_RING(chan, region->sy); | 67 | OUT_RING(chan, region->sy); |
82 | FIRE_RING(chan); | 68 | FIRE_RING(chan); |
69 | return 0; | ||
83 | } | 70 | } |
84 | 71 | ||
85 | void | 72 | int |
86 | nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | 73 | nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) |
87 | { | 74 | { |
88 | struct nouveau_fbdev *nfbdev = info->par; | 75 | struct nouveau_fbdev *nfbdev = info->par; |
@@ -92,23 +79,14 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
92 | uint32_t width, dwords, *data = (uint32_t *)image->data; | 79 | uint32_t width, dwords, *data = (uint32_t *)image->data; |
93 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); | 80 | uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); |
94 | uint32_t *palette = info->pseudo_palette; | 81 | uint32_t *palette = info->pseudo_palette; |
82 | int ret; | ||
95 | 83 | ||
96 | if (info->state != FBINFO_STATE_RUNNING) | 84 | if (image->depth != 1) |
97 | return; | 85 | return -ENODEV; |
98 | |||
99 | if (image->depth != 1) { | ||
100 | cfb_imageblit(info, image); | ||
101 | return; | ||
102 | } | ||
103 | |||
104 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 11)) { | ||
105 | nouveau_fbcon_gpu_lockup(info); | ||
106 | } | ||
107 | 86 | ||
108 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | 87 | ret = RING_SPACE(chan, 11); |
109 | cfb_imageblit(info, image); | 88 | if (ret) |
110 | return; | 89 | return ret; |
111 | } | ||
112 | 90 | ||
113 | width = ALIGN(image->width, 32); | 91 | width = ALIGN(image->width, 32); |
114 | dwords = (width * image->height) >> 5; | 92 | dwords = (width * image->height) >> 5; |
@@ -134,11 +112,9 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
134 | while (dwords) { | 112 | while (dwords) { |
135 | int push = dwords > 2047 ? 2047 : dwords; | 113 | int push = dwords > 2047 ? 2047 : dwords; |
136 | 114 | ||
137 | if (RING_SPACE(chan, push + 1)) { | 115 | ret = RING_SPACE(chan, push + 1); |
138 | nouveau_fbcon_gpu_lockup(info); | 116 | if (ret) |
139 | cfb_imageblit(info, image); | 117 | return ret; |
140 | return; | ||
141 | } | ||
142 | 118 | ||
143 | dwords -= push; | 119 | dwords -= push; |
144 | 120 | ||
@@ -148,6 +124,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
148 | } | 124 | } |
149 | 125 | ||
150 | FIRE_RING(chan); | 126 | FIRE_RING(chan); |
127 | return 0; | ||
151 | } | 128 | } |
152 | 129 | ||
153 | int | 130 | int |