.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2012 Red Hat |
---|
3 | 4 | * |
---|
.. | .. |
---|
6 | 7 | * Copyright (C) 2009 Jaya Kumar <jayakumar.lkml@gmail.com> |
---|
7 | 8 | * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com> |
---|
8 | 9 | |
---|
9 | | - * This file is subject to the terms and conditions of the GNU General Public |
---|
10 | | - * License v2. See the file COPYING in the main directory of this archive for |
---|
11 | | - * more details. |
---|
12 | 10 | */ |
---|
13 | 11 | |
---|
14 | | -#include <drm/drmP.h> |
---|
15 | | -#include <drm/drm_crtc.h> |
---|
| 12 | +#include <linux/dma-buf.h> |
---|
| 13 | + |
---|
| 14 | +#include <drm/drm_atomic_helper.h> |
---|
16 | 15 | #include <drm/drm_crtc_helper.h> |
---|
17 | | -#include <drm/drm_plane_helper.h> |
---|
| 16 | +#include <drm/drm_damage_helper.h> |
---|
| 17 | +#include <drm/drm_fourcc.h> |
---|
| 18 | +#include <drm/drm_gem_framebuffer_helper.h> |
---|
| 19 | +#include <drm/drm_gem_shmem_helper.h> |
---|
| 20 | +#include <drm/drm_modeset_helper_vtables.h> |
---|
| 21 | +#include <drm/drm_vblank.h> |
---|
| 22 | + |
---|
18 | 23 | #include "udl_drv.h" |
---|
| 24 | + |
---|
| 25 | +#define UDL_COLOR_DEPTH_16BPP 0 |
---|
19 | 26 | |
---|
20 | 27 | /* |
---|
21 | 28 | * All DisplayLink bulk operations start with 0xAF, followed by specific code |
---|
.. | .. |
---|
40 | 47 | return udl_set_register(buf, 0xFF, 0xFF); |
---|
41 | 48 | } |
---|
42 | 49 | |
---|
43 | | -/* |
---|
44 | | - * On/Off for driving the DisplayLink framebuffer to the display |
---|
45 | | - * 0x00 H and V sync on |
---|
46 | | - * 0x01 H and V sync off (screen blank but powered) |
---|
47 | | - * 0x07 DPMS powerdown (requires modeset to come back) |
---|
48 | | - */ |
---|
49 | | -static char *udl_set_blank(char *buf, int dpms_mode) |
---|
| 50 | +static char *udl_set_blank_mode(char *buf, u8 mode) |
---|
50 | 51 | { |
---|
51 | | - u8 reg; |
---|
52 | | - switch (dpms_mode) { |
---|
53 | | - case DRM_MODE_DPMS_OFF: |
---|
54 | | - reg = 0x07; |
---|
55 | | - break; |
---|
56 | | - case DRM_MODE_DPMS_STANDBY: |
---|
57 | | - reg = 0x05; |
---|
58 | | - break; |
---|
59 | | - case DRM_MODE_DPMS_SUSPEND: |
---|
60 | | - reg = 0x01; |
---|
61 | | - break; |
---|
62 | | - case DRM_MODE_DPMS_ON: |
---|
63 | | - reg = 0x00; |
---|
64 | | - break; |
---|
65 | | - } |
---|
66 | | - |
---|
67 | | - return udl_set_register(buf, 0x1f, reg); |
---|
| 52 | + return udl_set_register(buf, UDL_REG_BLANK_MODE, mode); |
---|
68 | 53 | } |
---|
69 | 54 | |
---|
70 | 55 | static char *udl_set_color_depth(char *buf, u8 selection) |
---|
.. | .. |
---|
230 | 215 | static int udl_crtc_write_mode_to_hw(struct drm_crtc *crtc) |
---|
231 | 216 | { |
---|
232 | 217 | struct drm_device *dev = crtc->dev; |
---|
233 | | - struct udl_device *udl = dev->dev_private; |
---|
| 218 | + struct udl_device *udl = to_udl(dev); |
---|
234 | 219 | struct urb *urb; |
---|
235 | 220 | char *buf; |
---|
236 | 221 | int retval; |
---|
| 222 | + |
---|
| 223 | + if (udl->mode_buf_len == 0) { |
---|
| 224 | + DRM_ERROR("No mode set\n"); |
---|
| 225 | + return -EINVAL; |
---|
| 226 | + } |
---|
237 | 227 | |
---|
238 | 228 | urb = udl_get_urb(dev); |
---|
239 | 229 | if (!urb) |
---|
.. | .. |
---|
247 | 237 | return retval; |
---|
248 | 238 | } |
---|
249 | 239 | |
---|
250 | | - |
---|
251 | | -static void udl_crtc_dpms(struct drm_crtc *crtc, int mode) |
---|
| 240 | +static long udl_log_cpp(unsigned int cpp) |
---|
252 | 241 | { |
---|
253 | | - struct drm_device *dev = crtc->dev; |
---|
254 | | - struct udl_device *udl = dev->dev_private; |
---|
255 | | - int retval; |
---|
| 242 | + if (WARN_ON(!is_power_of_2(cpp))) |
---|
| 243 | + return -EINVAL; |
---|
| 244 | + return __ffs(cpp); |
---|
| 245 | +} |
---|
256 | 246 | |
---|
257 | | - if (mode == DRM_MODE_DPMS_OFF) { |
---|
258 | | - char *buf; |
---|
259 | | - struct urb *urb; |
---|
260 | | - urb = udl_get_urb(dev); |
---|
261 | | - if (!urb) |
---|
262 | | - return; |
---|
| 247 | +static int udl_aligned_damage_clip(struct drm_rect *clip, int x, int y, |
---|
| 248 | + int width, int height) |
---|
| 249 | +{ |
---|
| 250 | + int x1, x2; |
---|
263 | 251 | |
---|
264 | | - buf = (char *)urb->transfer_buffer; |
---|
265 | | - buf = udl_vidreg_lock(buf); |
---|
266 | | - buf = udl_set_blank(buf, mode); |
---|
267 | | - buf = udl_vidreg_unlock(buf); |
---|
| 252 | + if (WARN_ON_ONCE(x < 0) || |
---|
| 253 | + WARN_ON_ONCE(y < 0) || |
---|
| 254 | + WARN_ON_ONCE(width < 0) || |
---|
| 255 | + WARN_ON_ONCE(height < 0)) |
---|
| 256 | + return -EINVAL; |
---|
268 | 257 | |
---|
269 | | - buf = udl_dummy_render(buf); |
---|
270 | | - retval = udl_submit_urb(dev, urb, buf - (char *) |
---|
271 | | - urb->transfer_buffer); |
---|
272 | | - } else { |
---|
273 | | - if (udl->mode_buf_len == 0) { |
---|
274 | | - DRM_ERROR("Trying to enable DPMS with no mode\n"); |
---|
275 | | - return; |
---|
276 | | - } |
---|
277 | | - udl_crtc_write_mode_to_hw(crtc); |
---|
| 258 | + x1 = ALIGN_DOWN(x, sizeof(unsigned long)); |
---|
| 259 | + x2 = ALIGN(width + (x - x1), sizeof(unsigned long)) + x1; |
---|
| 260 | + |
---|
| 261 | + clip->x1 = x1; |
---|
| 262 | + clip->y1 = y; |
---|
| 263 | + clip->x2 = x2; |
---|
| 264 | + clip->y2 = y + height; |
---|
| 265 | + |
---|
| 266 | + return 0; |
---|
| 267 | +} |
---|
| 268 | + |
---|
| 269 | +static int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, |
---|
| 270 | + int width, int height) |
---|
| 271 | +{ |
---|
| 272 | + struct drm_device *dev = fb->dev; |
---|
| 273 | + struct dma_buf_attachment *import_attach = fb->obj[0]->import_attach; |
---|
| 274 | + int i, ret, tmp_ret; |
---|
| 275 | + char *cmd; |
---|
| 276 | + struct urb *urb; |
---|
| 277 | + struct drm_rect clip; |
---|
| 278 | + int log_bpp; |
---|
| 279 | + void *vaddr; |
---|
| 280 | + |
---|
| 281 | + ret = udl_log_cpp(fb->format->cpp[0]); |
---|
| 282 | + if (ret < 0) |
---|
| 283 | + return ret; |
---|
| 284 | + log_bpp = ret; |
---|
| 285 | + |
---|
| 286 | + ret = udl_aligned_damage_clip(&clip, x, y, width, height); |
---|
| 287 | + if (ret) |
---|
| 288 | + return ret; |
---|
| 289 | + else if ((clip.x2 > fb->width) || (clip.y2 > fb->height)) |
---|
| 290 | + return -EINVAL; |
---|
| 291 | + |
---|
| 292 | + if (import_attach) { |
---|
| 293 | + ret = dma_buf_begin_cpu_access(import_attach->dmabuf, |
---|
| 294 | + DMA_FROM_DEVICE); |
---|
| 295 | + if (ret) |
---|
| 296 | + return ret; |
---|
278 | 297 | } |
---|
279 | 298 | |
---|
| 299 | + vaddr = drm_gem_shmem_vmap(fb->obj[0]); |
---|
| 300 | + if (IS_ERR(vaddr)) { |
---|
| 301 | + DRM_ERROR("failed to vmap fb\n"); |
---|
| 302 | + goto out_dma_buf_end_cpu_access; |
---|
| 303 | + } |
---|
| 304 | + |
---|
| 305 | + urb = udl_get_urb(dev); |
---|
| 306 | + if (!urb) { |
---|
| 307 | + ret = -ENOMEM; |
---|
| 308 | + goto out_drm_gem_shmem_vunmap; |
---|
| 309 | + } |
---|
| 310 | + cmd = urb->transfer_buffer; |
---|
| 311 | + |
---|
| 312 | + for (i = clip.y1; i < clip.y2; i++) { |
---|
| 313 | + const int line_offset = fb->pitches[0] * i; |
---|
| 314 | + const int byte_offset = line_offset + (clip.x1 << log_bpp); |
---|
| 315 | + const int dev_byte_offset = (fb->width * i + clip.x1) << log_bpp; |
---|
| 316 | + const int byte_width = (clip.x2 - clip.x1) << log_bpp; |
---|
| 317 | + ret = udl_render_hline(dev, log_bpp, &urb, (char *)vaddr, |
---|
| 318 | + &cmd, byte_offset, dev_byte_offset, |
---|
| 319 | + byte_width); |
---|
| 320 | + if (ret) |
---|
| 321 | + goto out_drm_gem_shmem_vunmap; |
---|
| 322 | + } |
---|
| 323 | + |
---|
| 324 | + if (cmd > (char *)urb->transfer_buffer) { |
---|
| 325 | + /* Send partial buffer remaining before exiting */ |
---|
| 326 | + int len; |
---|
| 327 | + if (cmd < (char *)urb->transfer_buffer + urb->transfer_buffer_length) |
---|
| 328 | + *cmd++ = 0xAF; |
---|
| 329 | + len = cmd - (char *)urb->transfer_buffer; |
---|
| 330 | + ret = udl_submit_urb(dev, urb, len); |
---|
| 331 | + } else { |
---|
| 332 | + udl_urb_completion(urb); |
---|
| 333 | + } |
---|
| 334 | + |
---|
| 335 | + ret = 0; |
---|
| 336 | + |
---|
| 337 | +out_drm_gem_shmem_vunmap: |
---|
| 338 | + drm_gem_shmem_vunmap(fb->obj[0], vaddr); |
---|
| 339 | +out_dma_buf_end_cpu_access: |
---|
| 340 | + if (import_attach) { |
---|
| 341 | + tmp_ret = dma_buf_end_cpu_access(import_attach->dmabuf, |
---|
| 342 | + DMA_FROM_DEVICE); |
---|
| 343 | + if (tmp_ret && !ret) |
---|
| 344 | + ret = tmp_ret; /* only update ret if not set yet */ |
---|
| 345 | + } |
---|
| 346 | + |
---|
| 347 | + return ret; |
---|
280 | 348 | } |
---|
281 | 349 | |
---|
282 | | -#if 0 |
---|
283 | | -static int |
---|
284 | | -udl_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
---|
285 | | - int x, int y, enum mode_set_atomic state) |
---|
| 350 | +/* |
---|
| 351 | + * Simple display pipeline |
---|
| 352 | + */ |
---|
| 353 | + |
---|
| 354 | +static const uint32_t udl_simple_display_pipe_formats[] = { |
---|
| 355 | + DRM_FORMAT_RGB565, |
---|
| 356 | + DRM_FORMAT_XRGB8888, |
---|
| 357 | +}; |
---|
| 358 | + |
---|
| 359 | +static enum drm_mode_status |
---|
| 360 | +udl_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe, |
---|
| 361 | + const struct drm_display_mode *mode) |
---|
286 | 362 | { |
---|
287 | | - return 0; |
---|
| 363 | + return MODE_OK; |
---|
288 | 364 | } |
---|
289 | 365 | |
---|
290 | | -static int |
---|
291 | | -udl_pipe_set_base(struct drm_crtc *crtc, int x, int y, |
---|
292 | | - struct drm_framebuffer *old_fb) |
---|
| 366 | +static void |
---|
| 367 | +udl_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, |
---|
| 368 | + struct drm_crtc_state *crtc_state, |
---|
| 369 | + struct drm_plane_state *plane_state) |
---|
293 | 370 | { |
---|
294 | | - return 0; |
---|
295 | | -} |
---|
296 | | -#endif |
---|
297 | | - |
---|
298 | | -static int udl_crtc_mode_set(struct drm_crtc *crtc, |
---|
299 | | - struct drm_display_mode *mode, |
---|
300 | | - struct drm_display_mode *adjusted_mode, |
---|
301 | | - int x, int y, |
---|
302 | | - struct drm_framebuffer *old_fb) |
---|
303 | | - |
---|
304 | | -{ |
---|
| 371 | + struct drm_crtc *crtc = &pipe->crtc; |
---|
305 | 372 | struct drm_device *dev = crtc->dev; |
---|
306 | | - struct udl_framebuffer *ufb = to_udl_fb(crtc->primary->fb); |
---|
307 | | - struct udl_device *udl = dev->dev_private; |
---|
| 373 | + struct drm_framebuffer *fb = plane_state->fb; |
---|
| 374 | + struct udl_device *udl = to_udl(dev); |
---|
| 375 | + struct drm_display_mode *mode = &crtc_state->mode; |
---|
308 | 376 | char *buf; |
---|
309 | 377 | char *wrptr; |
---|
310 | | - int color_depth = 0; |
---|
311 | | - |
---|
312 | | - udl->crtc = crtc; |
---|
| 378 | + int color_depth = UDL_COLOR_DEPTH_16BPP; |
---|
313 | 379 | |
---|
314 | 380 | buf = (char *)udl->mode_buf; |
---|
315 | 381 | |
---|
316 | | - /* for now we just clip 24 -> 16 - if we fix that fix this */ |
---|
317 | | - /*if (crtc->fb->bits_per_pixel != 16) |
---|
318 | | - color_depth = 1; */ |
---|
319 | | - |
---|
320 | 382 | /* This first section has to do with setting the base address on the |
---|
321 | | - * controller * associated with the display. There are 2 base |
---|
322 | | - * pointers, currently, we only * use the 16 bpp segment. |
---|
323 | | - */ |
---|
| 383 | + * controller associated with the display. There are 2 base |
---|
| 384 | + * pointers, currently, we only use the 16 bpp segment. |
---|
| 385 | + */ |
---|
324 | 386 | wrptr = udl_vidreg_lock(buf); |
---|
325 | 387 | wrptr = udl_set_color_depth(wrptr, color_depth); |
---|
326 | 388 | /* set base for 16bpp segment to 0 */ |
---|
.. | .. |
---|
328 | 390 | /* set base for 8bpp segment to end of fb */ |
---|
329 | 391 | wrptr = udl_set_base8bpp(wrptr, 2 * mode->vdisplay * mode->hdisplay); |
---|
330 | 392 | |
---|
331 | | - wrptr = udl_set_vid_cmds(wrptr, adjusted_mode); |
---|
332 | | - wrptr = udl_set_blank(wrptr, DRM_MODE_DPMS_ON); |
---|
| 393 | + wrptr = udl_set_vid_cmds(wrptr, mode); |
---|
| 394 | + wrptr = udl_set_blank_mode(wrptr, UDL_BLANK_MODE_ON); |
---|
333 | 395 | wrptr = udl_vidreg_unlock(wrptr); |
---|
334 | 396 | |
---|
335 | 397 | wrptr = udl_dummy_render(wrptr); |
---|
336 | 398 | |
---|
337 | | - if (old_fb) { |
---|
338 | | - struct udl_framebuffer *uold_fb = to_udl_fb(old_fb); |
---|
339 | | - uold_fb->active_16 = false; |
---|
340 | | - } |
---|
341 | | - ufb->active_16 = true; |
---|
342 | 399 | udl->mode_buf_len = wrptr - buf; |
---|
343 | 400 | |
---|
344 | | - /* damage all of it */ |
---|
345 | | - udl_handle_damage(ufb, 0, 0, ufb->base.width, ufb->base.height); |
---|
346 | | - return 0; |
---|
| 401 | + udl_handle_damage(fb, 0, 0, fb->width, fb->height); |
---|
| 402 | + |
---|
| 403 | + /* enable display */ |
---|
| 404 | + udl_crtc_write_mode_to_hw(crtc); |
---|
347 | 405 | } |
---|
348 | 406 | |
---|
349 | | - |
---|
350 | | -static void udl_crtc_disable(struct drm_crtc *crtc) |
---|
| 407 | +static void |
---|
| 408 | +udl_simple_display_pipe_disable(struct drm_simple_display_pipe *pipe) |
---|
351 | 409 | { |
---|
352 | | - udl_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
---|
353 | | -} |
---|
354 | | - |
---|
355 | | -static void udl_crtc_destroy(struct drm_crtc *crtc) |
---|
356 | | -{ |
---|
357 | | - drm_crtc_cleanup(crtc); |
---|
358 | | - kfree(crtc); |
---|
359 | | -} |
---|
360 | | - |
---|
361 | | -static int udl_crtc_page_flip(struct drm_crtc *crtc, |
---|
362 | | - struct drm_framebuffer *fb, |
---|
363 | | - struct drm_pending_vblank_event *event, |
---|
364 | | - uint32_t page_flip_flags, |
---|
365 | | - struct drm_modeset_acquire_ctx *ctx) |
---|
366 | | -{ |
---|
367 | | - struct udl_framebuffer *ufb = to_udl_fb(fb); |
---|
| 410 | + struct drm_crtc *crtc = &pipe->crtc; |
---|
368 | 411 | struct drm_device *dev = crtc->dev; |
---|
| 412 | + struct urb *urb; |
---|
| 413 | + char *buf; |
---|
369 | 414 | |
---|
370 | | - struct drm_framebuffer *old_fb = crtc->primary->fb; |
---|
371 | | - if (old_fb) { |
---|
372 | | - struct udl_framebuffer *uold_fb = to_udl_fb(old_fb); |
---|
373 | | - uold_fb->active_16 = false; |
---|
374 | | - } |
---|
375 | | - ufb->active_16 = true; |
---|
| 415 | + urb = udl_get_urb(dev); |
---|
| 416 | + if (!urb) |
---|
| 417 | + return; |
---|
376 | 418 | |
---|
377 | | - udl_handle_damage(ufb, 0, 0, fb->width, fb->height); |
---|
| 419 | + buf = (char *)urb->transfer_buffer; |
---|
| 420 | + buf = udl_vidreg_lock(buf); |
---|
| 421 | + buf = udl_set_blank_mode(buf, UDL_BLANK_MODE_POWERDOWN); |
---|
| 422 | + buf = udl_vidreg_unlock(buf); |
---|
| 423 | + buf = udl_dummy_render(buf); |
---|
378 | 424 | |
---|
379 | | - spin_lock_irq(&dev->event_lock); |
---|
380 | | - if (event) |
---|
381 | | - drm_crtc_send_vblank_event(crtc, event); |
---|
382 | | - spin_unlock_irq(&dev->event_lock); |
---|
383 | | - crtc->primary->fb = fb; |
---|
384 | | - |
---|
385 | | - return 0; |
---|
| 425 | + udl_submit_urb(dev, urb, buf - (char *)urb->transfer_buffer); |
---|
386 | 426 | } |
---|
387 | 427 | |
---|
388 | | -static void udl_crtc_prepare(struct drm_crtc *crtc) |
---|
| 428 | +static void |
---|
| 429 | +udl_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, |
---|
| 430 | + struct drm_plane_state *old_plane_state) |
---|
389 | 431 | { |
---|
| 432 | + struct drm_plane_state *state = pipe->plane.state; |
---|
| 433 | + struct drm_framebuffer *fb = state->fb; |
---|
| 434 | + struct drm_rect rect; |
---|
| 435 | + |
---|
| 436 | + if (!fb) |
---|
| 437 | + return; |
---|
| 438 | + |
---|
| 439 | + if (drm_atomic_helper_damage_merged(old_plane_state, state, &rect)) |
---|
| 440 | + udl_handle_damage(fb, rect.x1, rect.y1, rect.x2 - rect.x1, |
---|
| 441 | + rect.y2 - rect.y1); |
---|
390 | 442 | } |
---|
391 | 443 | |
---|
392 | | -static void udl_crtc_commit(struct drm_crtc *crtc) |
---|
393 | | -{ |
---|
394 | | - udl_crtc_dpms(crtc, DRM_MODE_DPMS_ON); |
---|
395 | | -} |
---|
396 | | - |
---|
397 | | -static const struct drm_crtc_helper_funcs udl_helper_funcs = { |
---|
398 | | - .dpms = udl_crtc_dpms, |
---|
399 | | - .mode_set = udl_crtc_mode_set, |
---|
400 | | - .prepare = udl_crtc_prepare, |
---|
401 | | - .commit = udl_crtc_commit, |
---|
402 | | - .disable = udl_crtc_disable, |
---|
| 444 | +static const |
---|
| 445 | +struct drm_simple_display_pipe_funcs udl_simple_display_pipe_funcs = { |
---|
| 446 | + .mode_valid = udl_simple_display_pipe_mode_valid, |
---|
| 447 | + .enable = udl_simple_display_pipe_enable, |
---|
| 448 | + .disable = udl_simple_display_pipe_disable, |
---|
| 449 | + .update = udl_simple_display_pipe_update, |
---|
| 450 | + .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb, |
---|
403 | 451 | }; |
---|
404 | 452 | |
---|
405 | | -static const struct drm_crtc_funcs udl_crtc_funcs = { |
---|
406 | | - .set_config = drm_crtc_helper_set_config, |
---|
407 | | - .destroy = udl_crtc_destroy, |
---|
408 | | - .page_flip = udl_crtc_page_flip, |
---|
409 | | -}; |
---|
410 | | - |
---|
411 | | -static int udl_crtc_init(struct drm_device *dev) |
---|
412 | | -{ |
---|
413 | | - struct drm_crtc *crtc; |
---|
414 | | - |
---|
415 | | - crtc = kzalloc(sizeof(struct drm_crtc) + sizeof(struct drm_connector *), GFP_KERNEL); |
---|
416 | | - if (crtc == NULL) |
---|
417 | | - return -ENOMEM; |
---|
418 | | - |
---|
419 | | - drm_crtc_init(dev, crtc, &udl_crtc_funcs); |
---|
420 | | - drm_crtc_helper_add(crtc, &udl_helper_funcs); |
---|
421 | | - |
---|
422 | | - return 0; |
---|
423 | | -} |
---|
| 453 | +/* |
---|
| 454 | + * Modesetting |
---|
| 455 | + */ |
---|
424 | 456 | |
---|
425 | 457 | static const struct drm_mode_config_funcs udl_mode_funcs = { |
---|
426 | | - .fb_create = udl_fb_user_fb_create, |
---|
427 | | - .output_poll_changed = NULL, |
---|
| 458 | + .fb_create = drm_gem_fb_create_with_dirty, |
---|
| 459 | + .atomic_check = drm_atomic_helper_check, |
---|
| 460 | + .atomic_commit = drm_atomic_helper_commit, |
---|
428 | 461 | }; |
---|
429 | 462 | |
---|
430 | 463 | int udl_modeset_init(struct drm_device *dev) |
---|
431 | 464 | { |
---|
432 | | - struct drm_encoder *encoder; |
---|
433 | | - drm_mode_config_init(dev); |
---|
| 465 | + size_t format_count = ARRAY_SIZE(udl_simple_display_pipe_formats); |
---|
| 466 | + struct udl_device *udl = to_udl(dev); |
---|
| 467 | + struct drm_connector *connector; |
---|
| 468 | + int ret; |
---|
| 469 | + |
---|
| 470 | + ret = drmm_mode_config_init(dev); |
---|
| 471 | + if (ret) |
---|
| 472 | + return ret; |
---|
434 | 473 | |
---|
435 | 474 | dev->mode_config.min_width = 640; |
---|
436 | 475 | dev->mode_config.min_height = 480; |
---|
.. | .. |
---|
439 | 478 | dev->mode_config.max_height = 2048; |
---|
440 | 479 | |
---|
441 | 480 | dev->mode_config.prefer_shadow = 0; |
---|
442 | | - dev->mode_config.preferred_depth = 24; |
---|
| 481 | + dev->mode_config.preferred_depth = 16; |
---|
443 | 482 | |
---|
444 | 483 | dev->mode_config.funcs = &udl_mode_funcs; |
---|
445 | 484 | |
---|
446 | | - udl_crtc_init(dev); |
---|
| 485 | + connector = udl_connector_init(dev); |
---|
| 486 | + if (IS_ERR(connector)) |
---|
| 487 | + return PTR_ERR(connector); |
---|
447 | 488 | |
---|
448 | | - encoder = udl_encoder_init(dev); |
---|
| 489 | + format_count = ARRAY_SIZE(udl_simple_display_pipe_formats); |
---|
449 | 490 | |
---|
450 | | - udl_connector_init(dev, encoder); |
---|
| 491 | + ret = drm_simple_display_pipe_init(dev, &udl->display_pipe, |
---|
| 492 | + &udl_simple_display_pipe_funcs, |
---|
| 493 | + udl_simple_display_pipe_formats, |
---|
| 494 | + format_count, NULL, connector); |
---|
| 495 | + if (ret) |
---|
| 496 | + return ret; |
---|
| 497 | + |
---|
| 498 | + drm_mode_config_reset(dev); |
---|
451 | 499 | |
---|
452 | 500 | return 0; |
---|
453 | | -} |
---|
454 | | - |
---|
455 | | -void udl_modeset_restore(struct drm_device *dev) |
---|
456 | | -{ |
---|
457 | | - struct udl_device *udl = dev->dev_private; |
---|
458 | | - struct udl_framebuffer *ufb; |
---|
459 | | - |
---|
460 | | - if (!udl->crtc || !udl->crtc->primary->fb) |
---|
461 | | - return; |
---|
462 | | - udl_crtc_commit(udl->crtc); |
---|
463 | | - ufb = to_udl_fb(udl->crtc->primary->fb); |
---|
464 | | - udl_handle_damage(ufb, 0, 0, ufb->base.width, ufb->base.height); |
---|
465 | | -} |
---|
466 | | - |
---|
467 | | -void udl_modeset_cleanup(struct drm_device *dev) |
---|
468 | | -{ |
---|
469 | | - drm_mode_config_cleanup(dev); |
---|
470 | 501 | } |
---|