2 #include "nouveau_drv.h"
3 #include "nouveau_dma.h"
4 #include "nouveau_ramht.h"
5 #include "nouveau_fbcon.h"
8 nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
10 struct nouveau_fbdev *nfbdev = info->par;
11 struct drm_device *dev = nfbdev->dev;
12 struct drm_nouveau_private *dev_priv = dev->dev_private;
13 struct nouveau_channel *chan = dev_priv->channel;
16 ret = RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11);
20 if (rect->rop != ROP_COPY) {
21 BEGIN_RING(chan, NvSub2D, 0x02ac, 1);
24 BEGIN_RING(chan, NvSub2D, 0x0588, 1);
25 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
26 info->fix.visual == FB_VISUAL_DIRECTCOLOR)
27 OUT_RING(chan, ((uint32_t *)info->pseudo_palette)[rect->color]);
29 OUT_RING(chan, rect->color);
30 BEGIN_RING(chan, NvSub2D, 0x0600, 4);
31 OUT_RING(chan, rect->dx);
32 OUT_RING(chan, rect->dy);
33 OUT_RING(chan, rect->dx + rect->width);
34 OUT_RING(chan, rect->dy + rect->height);
35 if (rect->rop != ROP_COPY) {
36 BEGIN_RING(chan, NvSub2D, 0x02ac, 1);
44 nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
46 struct nouveau_fbdev *nfbdev = info->par;
47 struct drm_device *dev = nfbdev->dev;
48 struct drm_nouveau_private *dev_priv = dev->dev_private;
49 struct nouveau_channel *chan = dev_priv->channel;
52 ret = RING_SPACE(chan, 12);
56 BEGIN_RING(chan, NvSub2D, 0x0110, 1);
58 BEGIN_RING(chan, NvSub2D, 0x08b0, 4);
59 OUT_RING(chan, region->dx);
60 OUT_RING(chan, region->dy);
61 OUT_RING(chan, region->width);
62 OUT_RING(chan, region->height);
63 BEGIN_RING(chan, NvSub2D, 0x08d0, 4);
65 OUT_RING(chan, region->sx);
67 OUT_RING(chan, region->sy);
73 nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
75 struct nouveau_fbdev *nfbdev = info->par;
76 struct drm_device *dev = nfbdev->dev;
77 struct drm_nouveau_private *dev_priv = dev->dev_private;
78 struct nouveau_channel *chan = dev_priv->channel;
79 uint32_t width, dwords, *data = (uint32_t *)image->data;
80 uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
81 uint32_t *palette = info->pseudo_palette;
84 if (image->depth != 1)
87 ret = RING_SPACE(chan, 11);
91 width = ALIGN(image->width, 32);
92 dwords = (width * image->height) >> 5;
94 BEGIN_RING(chan, NvSub2D, 0x0814, 2);
95 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
96 info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
97 OUT_RING(chan, palette[image->bg_color] | mask);
98 OUT_RING(chan, palette[image->fg_color] | mask);
100 OUT_RING(chan, image->bg_color);
101 OUT_RING(chan, image->fg_color);
103 BEGIN_RING(chan, NvSub2D, 0x0838, 2);
104 OUT_RING(chan, image->width);
105 OUT_RING(chan, image->height);
106 BEGIN_RING(chan, NvSub2D, 0x0850, 4);
108 OUT_RING(chan, image->dx);
110 OUT_RING(chan, image->dy);
113 int push = dwords > 2047 ? 2047 : dwords;
115 ret = RING_SPACE(chan, push + 1);
121 BEGIN_RING(chan, NvSub2D, 0x40000860, push);
122 OUT_RINGp(chan, data, push);
131 nv50_fbcon_accel_init(struct fb_info *info)
133 struct nouveau_fbdev *nfbdev = info->par;
134 struct drm_device *dev = nfbdev->dev;
135 struct drm_nouveau_private *dev_priv = dev->dev_private;
136 struct nouveau_channel *chan = dev_priv->channel;
140 fb = info->fix.smem_start - dev_priv->fb_phys + dev_priv->vm_vram_base;
142 switch (info->var.bits_per_pixel) {
153 switch (info->var.transp.length) {
154 case 0: /* depth 24 */
155 case 8: /* depth 32, just use 24.. */
158 case 2: /* depth 30 */
169 ret = nouveau_gpuobj_gr_new(dev_priv->channel, Nv2D, 0x502d);
173 ret = RING_SPACE(chan, 59);
175 nouveau_fbcon_gpu_lockup(info);
179 BEGIN_RING(chan, NvSub2D, 0x0000, 1);
180 OUT_RING(chan, Nv2D);
181 BEGIN_RING(chan, NvSub2D, 0x0180, 4);
182 OUT_RING(chan, NvNotify0);
183 OUT_RING(chan, chan->vram_handle);
184 OUT_RING(chan, chan->vram_handle);
185 OUT_RING(chan, chan->vram_handle);
186 BEGIN_RING(chan, NvSub2D, 0x0290, 1);
188 BEGIN_RING(chan, NvSub2D, 0x0888, 1);
190 BEGIN_RING(chan, NvSub2D, 0x02ac, 1);
192 BEGIN_RING(chan, NvSub2D, 0x02a0, 1);
193 OUT_RING(chan, 0x55);
194 BEGIN_RING(chan, NvSub2D, 0x08c0, 4);
199 BEGIN_RING(chan, NvSub2D, 0x0580, 2);
201 OUT_RING(chan, format);
202 BEGIN_RING(chan, NvSub2D, 0x02e8, 2);
205 BEGIN_RING(chan, NvSub2D, 0x0804, 1);
206 OUT_RING(chan, format);
207 BEGIN_RING(chan, NvSub2D, 0x0800, 1);
209 BEGIN_RING(chan, NvSub2D, 0x0808, 3);
213 BEGIN_RING(chan, NvSub2D, 0x081c, 1);
215 BEGIN_RING(chan, NvSub2D, 0x0840, 4);
220 BEGIN_RING(chan, NvSub2D, 0x0200, 2);
221 OUT_RING(chan, format);
223 BEGIN_RING(chan, NvSub2D, 0x0214, 5);
224 OUT_RING(chan, info->fix.line_length);
225 OUT_RING(chan, info->var.xres_virtual);
226 OUT_RING(chan, info->var.yres_virtual);
227 OUT_RING(chan, upper_32_bits(fb));
228 OUT_RING(chan, lower_32_bits(fb));
229 BEGIN_RING(chan, NvSub2D, 0x0230, 2);
230 OUT_RING(chan, format);
232 BEGIN_RING(chan, NvSub2D, 0x0244, 5);
233 OUT_RING(chan, info->fix.line_length);
234 OUT_RING(chan, info->var.xres_virtual);
235 OUT_RING(chan, info->var.yres_virtual);
236 OUT_RING(chan, upper_32_bits(fb));
237 OUT_RING(chan, lower_32_bits(fb));