diff options
author | Jakob Bornecrantz <jakob@vmware.com> | 2011-10-04 14:13:20 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-10-05 05:17:12 -0400 |
commit | 626ab771c2f2d060d29470f18b3f7d710ba909dc (patch) | |
tree | 158e9d80e3c66708aee32a0378d5748f88448ba1 /drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | |
parent | 4084fb89e6b463686219a2369d1d35e6b78f785d (diff) |
vmwgfx: Refactor common display unit functions to shared file
More preparation for Screen Object support.
Signed-off-by: Jakob Bornecrantz <jakob@vmware.com>
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 268 |
1 files changed, 15 insertions, 253 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 7e1901c4f065..4a4e5ccd40d6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | |||
@@ -51,11 +51,6 @@ struct vmw_legacy_display { | |||
51 | struct vmw_legacy_display_unit { | 51 | struct vmw_legacy_display_unit { |
52 | struct vmw_display_unit base; | 52 | struct vmw_display_unit base; |
53 | 53 | ||
54 | unsigned pref_width; | ||
55 | unsigned pref_height; | ||
56 | bool pref_active; | ||
57 | struct drm_display_mode *pref_mode; | ||
58 | |||
59 | struct list_head active; | 54 | struct list_head active; |
60 | }; | 55 | }; |
61 | 56 | ||
@@ -71,29 +66,6 @@ static void vmw_ldu_destroy(struct vmw_legacy_display_unit *ldu) | |||
71 | * Legacy Display Unit CRTC functions | 66 | * Legacy Display Unit CRTC functions |
72 | */ | 67 | */ |
73 | 68 | ||
74 | static void vmw_ldu_crtc_save(struct drm_crtc *crtc) | ||
75 | { | ||
76 | } | ||
77 | |||
78 | static void vmw_ldu_crtc_restore(struct drm_crtc *crtc) | ||
79 | { | ||
80 | } | ||
81 | |||
82 | static void vmw_ldu_crtc_gamma_set(struct drm_crtc *crtc, | ||
83 | u16 *r, u16 *g, u16 *b, | ||
84 | uint32_t start, uint32_t size) | ||
85 | { | ||
86 | struct vmw_private *dev_priv = vmw_priv(crtc->dev); | ||
87 | int i; | ||
88 | |||
89 | for (i = 0; i < size; i++) { | ||
90 | DRM_DEBUG("%d r/g/b = 0x%04x / 0x%04x / 0x%04x\n", i, r[i], g[i], b[i]); | ||
91 | vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 0, r[i] >> 8); | ||
92 | vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 1, g[i] >> 8); | ||
93 | vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 2, b[i] >> 8); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | static void vmw_ldu_crtc_destroy(struct drm_crtc *crtc) | 69 | static void vmw_ldu_crtc_destroy(struct drm_crtc *crtc) |
98 | { | 70 | { |
99 | vmw_ldu_destroy(vmw_crtc_to_ldu(crtc)); | 71 | vmw_ldu_destroy(vmw_crtc_to_ldu(crtc)); |
@@ -301,15 +273,16 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set) | |||
301 | } | 273 | } |
302 | 274 | ||
303 | static struct drm_crtc_funcs vmw_legacy_crtc_funcs = { | 275 | static struct drm_crtc_funcs vmw_legacy_crtc_funcs = { |
304 | .save = vmw_ldu_crtc_save, | 276 | .save = vmw_du_crtc_save, |
305 | .restore = vmw_ldu_crtc_restore, | 277 | .restore = vmw_du_crtc_restore, |
306 | .cursor_set = vmw_du_crtc_cursor_set, | 278 | .cursor_set = vmw_du_crtc_cursor_set, |
307 | .cursor_move = vmw_du_crtc_cursor_move, | 279 | .cursor_move = vmw_du_crtc_cursor_move, |
308 | .gamma_set = vmw_ldu_crtc_gamma_set, | 280 | .gamma_set = vmw_du_crtc_gamma_set, |
309 | .destroy = vmw_ldu_crtc_destroy, | 281 | .destroy = vmw_ldu_crtc_destroy, |
310 | .set_config = vmw_ldu_crtc_set_config, | 282 | .set_config = vmw_ldu_crtc_set_config, |
311 | }; | 283 | }; |
312 | 284 | ||
285 | |||
313 | /* | 286 | /* |
314 | * Legacy Display Unit encoder functions | 287 | * Legacy Display Unit encoder functions |
315 | */ | 288 | */ |
@@ -327,190 +300,18 @@ static struct drm_encoder_funcs vmw_legacy_encoder_funcs = { | |||
327 | * Legacy Display Unit connector functions | 300 | * Legacy Display Unit connector functions |
328 | */ | 301 | */ |
329 | 302 | ||
330 | static void vmw_ldu_connector_dpms(struct drm_connector *connector, int mode) | ||
331 | { | ||
332 | } | ||
333 | |||
334 | static void vmw_ldu_connector_save(struct drm_connector *connector) | ||
335 | { | ||
336 | } | ||
337 | |||
338 | static void vmw_ldu_connector_restore(struct drm_connector *connector) | ||
339 | { | ||
340 | } | ||
341 | |||
342 | static enum drm_connector_status | ||
343 | vmw_ldu_connector_detect(struct drm_connector *connector, | ||
344 | bool force) | ||
345 | { | ||
346 | uint32_t num_displays; | ||
347 | struct drm_device *dev = connector->dev; | ||
348 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
349 | |||
350 | mutex_lock(&dev_priv->hw_mutex); | ||
351 | num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS); | ||
352 | mutex_unlock(&dev_priv->hw_mutex); | ||
353 | |||
354 | return ((vmw_connector_to_ldu(connector)->base.unit < num_displays) ? | ||
355 | connector_status_connected : connector_status_disconnected); | ||
356 | } | ||
357 | |||
358 | static const struct drm_display_mode vmw_ldu_connector_builtin[] = { | ||
359 | /* 640x480@60Hz */ | ||
360 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, | ||
361 | 752, 800, 0, 480, 489, 492, 525, 0, | ||
362 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
363 | /* 800x600@60Hz */ | ||
364 | { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, | ||
365 | 968, 1056, 0, 600, 601, 605, 628, 0, | ||
366 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
367 | /* 1024x768@60Hz */ | ||
368 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, | ||
369 | 1184, 1344, 0, 768, 771, 777, 806, 0, | ||
370 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
371 | /* 1152x864@75Hz */ | ||
372 | { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216, | ||
373 | 1344, 1600, 0, 864, 865, 868, 900, 0, | ||
374 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
375 | /* 1280x768@60Hz */ | ||
376 | { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344, | ||
377 | 1472, 1664, 0, 768, 771, 778, 798, 0, | ||
378 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
379 | /* 1280x800@60Hz */ | ||
380 | { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352, | ||
381 | 1480, 1680, 0, 800, 803, 809, 831, 0, | ||
382 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
383 | /* 1280x960@60Hz */ | ||
384 | { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376, | ||
385 | 1488, 1800, 0, 960, 961, 964, 1000, 0, | ||
386 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
387 | /* 1280x1024@60Hz */ | ||
388 | { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328, | ||
389 | 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, | ||
390 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
391 | /* 1360x768@60Hz */ | ||
392 | { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424, | ||
393 | 1536, 1792, 0, 768, 771, 777, 795, 0, | ||
394 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
395 | /* 1440x1050@60Hz */ | ||
396 | { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488, | ||
397 | 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, | ||
398 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
399 | /* 1440x900@60Hz */ | ||
400 | { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520, | ||
401 | 1672, 1904, 0, 900, 903, 909, 934, 0, | ||
402 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
403 | /* 1600x1200@60Hz */ | ||
404 | { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664, | ||
405 | 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, | ||
406 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
407 | /* 1680x1050@60Hz */ | ||
408 | { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784, | ||
409 | 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, | ||
410 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
411 | /* 1792x1344@60Hz */ | ||
412 | { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920, | ||
413 | 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, | ||
414 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
415 | /* 1853x1392@60Hz */ | ||
416 | { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952, | ||
417 | 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, | ||
418 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
419 | /* 1920x1200@60Hz */ | ||
420 | { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056, | ||
421 | 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, | ||
422 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
423 | /* 1920x1440@60Hz */ | ||
424 | { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048, | ||
425 | 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, | ||
426 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
427 | /* 2560x1600@60Hz */ | ||
428 | { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752, | ||
429 | 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, | ||
430 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | ||
431 | /* Terminate */ | ||
432 | { DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) }, | ||
433 | }; | ||
434 | |||
435 | static int vmw_ldu_connector_fill_modes(struct drm_connector *connector, | ||
436 | uint32_t max_width, uint32_t max_height) | ||
437 | { | ||
438 | struct vmw_legacy_display_unit *ldu = vmw_connector_to_ldu(connector); | ||
439 | struct drm_device *dev = connector->dev; | ||
440 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
441 | struct drm_display_mode *mode = NULL; | ||
442 | struct drm_display_mode prefmode = { DRM_MODE("preferred", | ||
443 | DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, | ||
444 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
445 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) | ||
446 | }; | ||
447 | int i; | ||
448 | |||
449 | /* Add preferred mode */ | ||
450 | { | ||
451 | mode = drm_mode_duplicate(dev, &prefmode); | ||
452 | if (!mode) | ||
453 | return 0; | ||
454 | mode->hdisplay = ldu->pref_width; | ||
455 | mode->vdisplay = ldu->pref_height; | ||
456 | mode->vrefresh = drm_mode_vrefresh(mode); | ||
457 | if (vmw_kms_validate_mode_vram(dev_priv, mode->hdisplay * 2, | ||
458 | mode->vdisplay)) { | ||
459 | drm_mode_probed_add(connector, mode); | ||
460 | |||
461 | if (ldu->pref_mode) { | ||
462 | list_del_init(&ldu->pref_mode->head); | ||
463 | drm_mode_destroy(dev, ldu->pref_mode); | ||
464 | } | ||
465 | |||
466 | ldu->pref_mode = mode; | ||
467 | } | ||
468 | } | ||
469 | |||
470 | for (i = 0; vmw_ldu_connector_builtin[i].type != 0; i++) { | ||
471 | const struct drm_display_mode *bmode; | ||
472 | |||
473 | bmode = &vmw_ldu_connector_builtin[i]; | ||
474 | if (bmode->hdisplay > max_width || | ||
475 | bmode->vdisplay > max_height) | ||
476 | continue; | ||
477 | |||
478 | if (!vmw_kms_validate_mode_vram(dev_priv, bmode->hdisplay * 2, | ||
479 | bmode->vdisplay)) | ||
480 | continue; | ||
481 | |||
482 | mode = drm_mode_duplicate(dev, bmode); | ||
483 | if (!mode) | ||
484 | return 0; | ||
485 | mode->vrefresh = drm_mode_vrefresh(mode); | ||
486 | |||
487 | drm_mode_probed_add(connector, mode); | ||
488 | } | ||
489 | |||
490 | drm_mode_connector_list_update(connector); | ||
491 | |||
492 | return 1; | ||
493 | } | ||
494 | |||
495 | static int vmw_ldu_connector_set_property(struct drm_connector *connector, | ||
496 | struct drm_property *property, | ||
497 | uint64_t val) | ||
498 | { | ||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static void vmw_ldu_connector_destroy(struct drm_connector *connector) | 303 | static void vmw_ldu_connector_destroy(struct drm_connector *connector) |
503 | { | 304 | { |
504 | vmw_ldu_destroy(vmw_connector_to_ldu(connector)); | 305 | vmw_ldu_destroy(vmw_connector_to_ldu(connector)); |
505 | } | 306 | } |
506 | 307 | ||
507 | static struct drm_connector_funcs vmw_legacy_connector_funcs = { | 308 | static struct drm_connector_funcs vmw_legacy_connector_funcs = { |
508 | .dpms = vmw_ldu_connector_dpms, | 309 | .dpms = vmw_du_connector_dpms, |
509 | .save = vmw_ldu_connector_save, | 310 | .save = vmw_du_connector_save, |
510 | .restore = vmw_ldu_connector_restore, | 311 | .restore = vmw_du_connector_restore, |
511 | .detect = vmw_ldu_connector_detect, | 312 | .detect = vmw_du_connector_detect, |
512 | .fill_modes = vmw_ldu_connector_fill_modes, | 313 | .fill_modes = vmw_du_connector_fill_modes, |
513 | .set_property = vmw_ldu_connector_set_property, | 314 | .set_property = vmw_du_connector_set_property, |
514 | .destroy = vmw_ldu_connector_destroy, | 315 | .destroy = vmw_ldu_connector_destroy, |
515 | }; | 316 | }; |
516 | 317 | ||
@@ -533,14 +334,14 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) | |||
533 | 334 | ||
534 | INIT_LIST_HEAD(&ldu->active); | 335 | INIT_LIST_HEAD(&ldu->active); |
535 | 336 | ||
536 | ldu->pref_active = (unit == 0); | 337 | ldu->base.pref_active = (unit == 0); |
537 | ldu->pref_width = 800; | 338 | ldu->base.pref_width = 800; |
538 | ldu->pref_height = 600; | 339 | ldu->base.pref_height = 600; |
539 | ldu->pref_mode = NULL; | 340 | ldu->base.pref_mode = NULL; |
540 | 341 | ||
541 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, | 342 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, |
542 | DRM_MODE_CONNECTOR_LVDS); | 343 | DRM_MODE_CONNECTOR_LVDS); |
543 | connector->status = vmw_ldu_connector_detect(connector, true); | 344 | connector->status = vmw_du_connector_detect(connector, true); |
544 | 345 | ||
545 | drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, | 346 | drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, |
546 | DRM_MODE_ENCODER_LVDS); | 347 | DRM_MODE_ENCODER_LVDS); |
@@ -609,42 +410,3 @@ int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) | |||
609 | 410 | ||
610 | return 0; | 411 | return 0; |
611 | } | 412 | } |
612 | |||
613 | int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num, | ||
614 | struct drm_vmw_rect *rects) | ||
615 | { | ||
616 | struct drm_device *dev = dev_priv->dev; | ||
617 | struct vmw_legacy_display_unit *ldu; | ||
618 | struct drm_connector *con; | ||
619 | int i; | ||
620 | |||
621 | mutex_lock(&dev->mode_config.mutex); | ||
622 | |||
623 | #if 0 | ||
624 | DRM_INFO("%s: new layout ", __func__); | ||
625 | for (i = 0; i < (int)num; i++) | ||
626 | DRM_INFO("(%i, %i %ux%u) ", rects[i].x, rects[i].y, | ||
627 | rects[i].w, rects[i].h); | ||
628 | DRM_INFO("\n"); | ||
629 | #else | ||
630 | (void)i; | ||
631 | #endif | ||
632 | |||
633 | list_for_each_entry(con, &dev->mode_config.connector_list, head) { | ||
634 | ldu = vmw_connector_to_ldu(con); | ||
635 | if (num > ldu->base.unit) { | ||
636 | ldu->pref_width = rects[ldu->base.unit].w; | ||
637 | ldu->pref_height = rects[ldu->base.unit].h; | ||
638 | ldu->pref_active = true; | ||
639 | } else { | ||
640 | ldu->pref_width = 800; | ||
641 | ldu->pref_height = 600; | ||
642 | ldu->pref_active = false; | ||
643 | } | ||
644 | con->status = vmw_ldu_connector_detect(con, true); | ||
645 | } | ||
646 | |||
647 | mutex_unlock(&dev->mode_config.mutex); | ||
648 | |||
649 | return 0; | ||
650 | } | ||