diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv04_fbcon.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nv04_fbcon.c | 102 |
1 files changed, 33 insertions, 69 deletions
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index 33e4c9388bc1..7a1189371096 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c | |||
@@ -28,52 +28,39 @@ | |||
28 | #include "nouveau_ramht.h" | 28 | #include "nouveau_ramht.h" |
29 | #include "nouveau_fbcon.h" | 29 | #include "nouveau_fbcon.h" |
30 | 30 | ||
31 | void | 31 | int |
32 | nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) | 32 | nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) |
33 | { | 33 | { |
34 | struct nouveau_fbdev *nfbdev = info->par; | 34 | struct nouveau_fbdev *nfbdev = info->par; |
35 | struct drm_device *dev = nfbdev->dev; | 35 | struct drm_device *dev = nfbdev->dev; |
36 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 36 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
37 | struct nouveau_channel *chan = dev_priv->channel; | 37 | struct nouveau_channel *chan = dev_priv->channel; |
38 | int ret; | ||
38 | 39 | ||
39 | if (info->state != FBINFO_STATE_RUNNING) | 40 | ret = RING_SPACE(chan, 4); |
40 | return; | 41 | if (ret) |
41 | 42 | return ret; | |
42 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 4)) { | ||
43 | nouveau_fbcon_gpu_lockup(info); | ||
44 | } | ||
45 | |||
46 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | ||
47 | cfb_copyarea(info, region); | ||
48 | return; | ||
49 | } | ||
50 | 43 | ||
51 | BEGIN_RING(chan, NvSubImageBlit, 0x0300, 3); | 44 | BEGIN_RING(chan, NvSubImageBlit, 0x0300, 3); |
52 | OUT_RING(chan, (region->sy << 16) | region->sx); | 45 | OUT_RING(chan, (region->sy << 16) | region->sx); |
53 | OUT_RING(chan, (region->dy << 16) | region->dx); | 46 | OUT_RING(chan, (region->dy << 16) | region->dx); |
54 | OUT_RING(chan, (region->height << 16) | region->width); | 47 | OUT_RING(chan, (region->height << 16) | region->width); |
55 | FIRE_RING(chan); | 48 | FIRE_RING(chan); |
49 | return 0; | ||
56 | } | 50 | } |
57 | 51 | ||
58 | void | 52 | int |
59 | nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 53 | nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) |
60 | { | 54 | { |
61 | struct nouveau_fbdev *nfbdev = info->par; | 55 | struct nouveau_fbdev *nfbdev = info->par; |
62 | struct drm_device *dev = nfbdev->dev; | 56 | struct drm_device *dev = nfbdev->dev; |
63 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 57 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
64 | struct nouveau_channel *chan = dev_priv->channel; | 58 | struct nouveau_channel *chan = dev_priv->channel; |
59 | int ret; | ||
65 | 60 | ||
66 | if (info->state != FBINFO_STATE_RUNNING) | 61 | ret = RING_SPACE(chan, 7); |
67 | return; | 62 | if (ret) |
68 | 63 | return ret; | |
69 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 7)) { | ||
70 | nouveau_fbcon_gpu_lockup(info); | ||
71 | } | ||
72 | |||
73 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | ||
74 | cfb_fillrect(info, rect); | ||
75 | return; | ||
76 | } | ||
77 | 64 | ||
78 | BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1); | 65 | BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1); |
79 | OUT_RING(chan, (rect->rop != ROP_COPY) ? 1 : 3); | 66 | OUT_RING(chan, (rect->rop != ROP_COPY) ? 1 : 3); |
@@ -87,9 +74,10 @@ nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
87 | OUT_RING(chan, (rect->dx << 16) | rect->dy); | 74 | OUT_RING(chan, (rect->dx << 16) | rect->dy); |
88 | OUT_RING(chan, (rect->width << 16) | rect->height); | 75 | OUT_RING(chan, (rect->width << 16) | rect->height); |
89 | FIRE_RING(chan); | 76 | FIRE_RING(chan); |
77 | return 0; | ||
90 | } | 78 | } |
91 | 79 | ||
92 | void | 80 | int |
93 | nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | 81 | nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) |
94 | { | 82 | { |
95 | struct nouveau_fbdev *nfbdev = info->par; | 83 | struct nouveau_fbdev *nfbdev = info->par; |
@@ -101,23 +89,14 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
101 | uint32_t dsize; | 89 | uint32_t dsize; |
102 | uint32_t width; | 90 | uint32_t width; |
103 | uint32_t *data = (uint32_t *)image->data; | 91 | uint32_t *data = (uint32_t *)image->data; |
92 | int ret; | ||
104 | 93 | ||
105 | if (info->state != FBINFO_STATE_RUNNING) | 94 | if (image->depth != 1) |
106 | return; | 95 | return -ENODEV; |
107 | |||
108 | if (image->depth != 1) { | ||
109 | cfb_imageblit(info, image); | ||
110 | return; | ||
111 | } | ||
112 | |||
113 | if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 8)) { | ||
114 | nouveau_fbcon_gpu_lockup(info); | ||
115 | } | ||
116 | 96 | ||
117 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | 97 | ret = RING_SPACE(chan, 8); |
118 | cfb_imageblit(info, image); | 98 | if (ret) |
119 | return; | 99 | return ret; |
120 | } | ||
121 | 100 | ||
122 | width = ALIGN(image->width, 8); | 101 | width = ALIGN(image->width, 8); |
123 | dsize = ALIGN(width * image->height, 32) >> 5; | 102 | dsize = ALIGN(width * image->height, 32) >> 5; |
@@ -144,11 +123,9 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
144 | while (dsize) { | 123 | while (dsize) { |
145 | int iter_len = dsize > 128 ? 128 : dsize; | 124 | int iter_len = dsize > 128 ? 128 : dsize; |
146 | 125 | ||
147 | if (RING_SPACE(chan, iter_len + 1)) { | 126 | ret = RING_SPACE(chan, iter_len + 1); |
148 | nouveau_fbcon_gpu_lockup(info); | 127 | if (ret) |
149 | cfb_imageblit(info, image); | 128 | return ret; |
150 | return; | ||
151 | } | ||
152 | 129 | ||
153 | BEGIN_RING(chan, NvSubGdiRect, 0x0c00, iter_len); | 130 | BEGIN_RING(chan, NvSubGdiRect, 0x0c00, iter_len); |
154 | OUT_RINGp(chan, data, iter_len); | 131 | OUT_RINGp(chan, data, iter_len); |
@@ -157,22 +134,7 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
157 | } | 134 | } |
158 | 135 | ||
159 | FIRE_RING(chan); | 136 | FIRE_RING(chan); |
160 | } | 137 | return 0; |
161 | |||
162 | static int | ||
163 | nv04_fbcon_grobj_new(struct drm_device *dev, int class, uint32_t handle) | ||
164 | { | ||
165 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
166 | struct nouveau_gpuobj *obj = NULL; | ||
167 | int ret; | ||
168 | |||
169 | ret = nouveau_gpuobj_gr_new(dev_priv->channel, class, &obj); | ||
170 | if (ret) | ||
171 | return ret; | ||
172 | |||
173 | ret = nouveau_ramht_insert(dev_priv->channel, handle, obj); | ||
174 | nouveau_gpuobj_ref(NULL, &obj); | ||
175 | return ret; | ||
176 | } | 138 | } |
177 | 139 | ||
178 | int | 140 | int |
@@ -214,29 +176,31 @@ nv04_fbcon_accel_init(struct fb_info *info) | |||
214 | return -EINVAL; | 176 | return -EINVAL; |
215 | } | 177 | } |
216 | 178 | ||
217 | ret = nv04_fbcon_grobj_new(dev, dev_priv->card_type >= NV_10 ? | 179 | ret = nouveau_gpuobj_gr_new(chan, NvCtxSurf2D, |
218 | 0x0062 : 0x0042, NvCtxSurf2D); | 180 | dev_priv->card_type >= NV_10 ? |
181 | 0x0062 : 0x0042); | ||
219 | if (ret) | 182 | if (ret) |
220 | return ret; | 183 | return ret; |
221 | 184 | ||
222 | ret = nv04_fbcon_grobj_new(dev, 0x0019, NvClipRect); | 185 | ret = nouveau_gpuobj_gr_new(chan, NvClipRect, 0x0019); |
223 | if (ret) | 186 | if (ret) |
224 | return ret; | 187 | return ret; |
225 | 188 | ||
226 | ret = nv04_fbcon_grobj_new(dev, 0x0043, NvRop); | 189 | ret = nouveau_gpuobj_gr_new(chan, NvRop, 0x0043); |
227 | if (ret) | 190 | if (ret) |
228 | return ret; | 191 | return ret; |
229 | 192 | ||
230 | ret = nv04_fbcon_grobj_new(dev, 0x0044, NvImagePatt); | 193 | ret = nouveau_gpuobj_gr_new(chan, NvImagePatt, 0x0044); |
231 | if (ret) | 194 | if (ret) |
232 | return ret; | 195 | return ret; |
233 | 196 | ||
234 | ret = nv04_fbcon_grobj_new(dev, 0x004a, NvGdiRect); | 197 | ret = nouveau_gpuobj_gr_new(chan, NvGdiRect, 0x004a); |
235 | if (ret) | 198 | if (ret) |
236 | return ret; | 199 | return ret; |
237 | 200 | ||
238 | ret = nv04_fbcon_grobj_new(dev, dev_priv->chipset >= 0x11 ? | 201 | ret = nouveau_gpuobj_gr_new(chan, NvImageBlit, |
239 | 0x009f : 0x005f, NvImageBlit); | 202 | dev_priv->chipset >= 0x11 ? |
203 | 0x009f : 0x005f); | ||
240 | if (ret) | 204 | if (ret) |
241 | return ret; | 205 | return ret; |
242 | 206 | ||