diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/dispnv04/overlay.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/dispnv04/overlay.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c index 3618ac6b6316..32e7064b819b 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c +++ b/drivers/gpu/drm/nouveau/dispnv04/overlay.c | |||
@@ -58,8 +58,8 @@ struct nouveau_plane { | |||
58 | }; | 58 | }; |
59 | 59 | ||
60 | static uint32_t formats[] = { | 60 | static uint32_t formats[] = { |
61 | DRM_FORMAT_NV12, | ||
62 | DRM_FORMAT_UYVY, | 61 | DRM_FORMAT_UYVY, |
62 | DRM_FORMAT_NV12, | ||
63 | }; | 63 | }; |
64 | 64 | ||
65 | /* Sine can be approximated with | 65 | /* Sine can be approximated with |
@@ -99,13 +99,28 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
99 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 99 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
100 | struct nouveau_bo *cur = nv_plane->cur; | 100 | struct nouveau_bo *cur = nv_plane->cur; |
101 | bool flip = nv_plane->flip; | 101 | bool flip = nv_plane->flip; |
102 | int format = ALIGN(src_w * 4, 0x100); | ||
103 | int soff = NV_PCRTC0_SIZE * nv_crtc->index; | 102 | int soff = NV_PCRTC0_SIZE * nv_crtc->index; |
104 | int soff2 = NV_PCRTC0_SIZE * !nv_crtc->index; | 103 | int soff2 = NV_PCRTC0_SIZE * !nv_crtc->index; |
105 | int ret; | 104 | int format, ret; |
105 | |||
106 | /* Source parameters given in 16.16 fixed point, ignore fractional. */ | ||
107 | src_x >>= 16; | ||
108 | src_y >>= 16; | ||
109 | src_w >>= 16; | ||
110 | src_h >>= 16; | ||
111 | |||
112 | format = ALIGN(src_w * 4, 0x100); | ||
106 | 113 | ||
107 | if (format > 0xffff) | 114 | if (format > 0xffff) |
108 | return -EINVAL; | 115 | return -ERANGE; |
116 | |||
117 | if (dev->chipset >= 0x30) { | ||
118 | if (crtc_w < (src_w >> 1) || crtc_h < (src_h >> 1)) | ||
119 | return -ERANGE; | ||
120 | } else { | ||
121 | if (crtc_w < (src_w >> 3) || crtc_h < (src_h >> 3)) | ||
122 | return -ERANGE; | ||
123 | } | ||
109 | 124 | ||
110 | ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM); | 125 | ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM); |
111 | if (ret) | 126 | if (ret) |
@@ -113,12 +128,6 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
113 | 128 | ||
114 | nv_plane->cur = nv_fb->nvbo; | 129 | nv_plane->cur = nv_fb->nvbo; |
115 | 130 | ||
116 | /* Source parameters given in 16.16 fixed point, ignore fractional. */ | ||
117 | src_x = src_x >> 16; | ||
118 | src_y = src_y >> 16; | ||
119 | src_w = src_w >> 16; | ||
120 | src_h = src_h >> 16; | ||
121 | |||
122 | nv_mask(dev, NV_PCRTC_ENGINE_CTRL + soff, NV_CRTC_FSEL_OVERLAY, NV_CRTC_FSEL_OVERLAY); | 131 | nv_mask(dev, NV_PCRTC_ENGINE_CTRL + soff, NV_CRTC_FSEL_OVERLAY, NV_CRTC_FSEL_OVERLAY); |
123 | nv_mask(dev, NV_PCRTC_ENGINE_CTRL + soff2, NV_CRTC_FSEL_OVERLAY, 0); | 132 | nv_mask(dev, NV_PCRTC_ENGINE_CTRL + soff2, NV_CRTC_FSEL_OVERLAY, 0); |
124 | 133 | ||
@@ -245,14 +254,25 @@ nv10_overlay_init(struct drm_device *device) | |||
245 | { | 254 | { |
246 | struct nouveau_device *dev = nouveau_dev(device); | 255 | struct nouveau_device *dev = nouveau_dev(device); |
247 | struct nouveau_plane *plane = kzalloc(sizeof(struct nouveau_plane), GFP_KERNEL); | 256 | struct nouveau_plane *plane = kzalloc(sizeof(struct nouveau_plane), GFP_KERNEL); |
257 | int num_formats = ARRAY_SIZE(formats); | ||
248 | int ret; | 258 | int ret; |
249 | 259 | ||
250 | if (!plane) | 260 | if (!plane) |
251 | return; | 261 | return; |
252 | 262 | ||
263 | switch (dev->chipset) { | ||
264 | case 0x10: | ||
265 | case 0x11: | ||
266 | case 0x15: | ||
267 | case 0x1a: | ||
268 | case 0x20: | ||
269 | num_formats = 1; | ||
270 | break; | ||
271 | } | ||
272 | |||
253 | ret = drm_plane_init(device, &plane->base, 3 /* both crtc's */, | 273 | ret = drm_plane_init(device, &plane->base, 3 /* both crtc's */, |
254 | &nv10_plane_funcs, | 274 | &nv10_plane_funcs, |
255 | formats, ARRAY_SIZE(formats), false); | 275 | formats, num_formats, false); |
256 | if (ret) | 276 | if (ret) |
257 | goto err; | 277 | goto err; |
258 | 278 | ||