Rev 3764 | Rev 4104 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3764 | Rev 4075 | ||
---|---|---|---|
Line 27... | Line 27... | ||
27 | * Keith Packard |
27 | * Keith Packard |
28 | * Eric Anholt |
28 | * Eric Anholt |
29 | * Dave Airlie |
29 | * Dave Airlie |
30 | * Jesse Barnes |
30 | * Jesse Barnes |
31 | */ |
31 | */ |
- | 32 | #include |
|
32 | #include |
33 | #include |
33 | #include |
34 | #include |
34 | #include |
35 | #include |
35 | #include |
36 | #include |
36 | #include |
37 | #include |
Line 85... | Line 86... | ||
85 | } |
86 | } |
86 | EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked); |
87 | EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked); |
Line 87... | Line 88... | ||
87 | 88 | ||
88 | /* Avoid boilerplate. I'm tired of typing. */ |
89 | /* Avoid boilerplate. I'm tired of typing. */ |
89 | #define DRM_ENUM_NAME_FN(fnname, list) \ |
90 | #define DRM_ENUM_NAME_FN(fnname, list) \ |
90 | char *fnname(int val) \ |
91 | const char *fnname(int val) \ |
91 | { \ |
92 | { \ |
92 | int i; \ |
93 | int i; \ |
93 | for (i = 0; i < ARRAY_SIZE(list); i++) { \ |
94 | for (i = 0; i < ARRAY_SIZE(list); i++) { \ |
94 | if (list[i].type == val) \ |
95 | if (list[i].type == val) \ |
Line 98... | Line 99... | ||
98 | } |
99 | } |
Line 99... | Line 100... | ||
99 | 100 | ||
100 | /* |
101 | /* |
101 | * Global properties |
102 | * Global properties |
102 | */ |
103 | */ |
103 | static struct drm_prop_enum_list drm_dpms_enum_list[] = |
104 | static const struct drm_prop_enum_list drm_dpms_enum_list[] = |
104 | { { DRM_MODE_DPMS_ON, "On" }, |
105 | { { DRM_MODE_DPMS_ON, "On" }, |
105 | { DRM_MODE_DPMS_STANDBY, "Standby" }, |
106 | { DRM_MODE_DPMS_STANDBY, "Standby" }, |
106 | { DRM_MODE_DPMS_SUSPEND, "Suspend" }, |
107 | { DRM_MODE_DPMS_SUSPEND, "Suspend" }, |
107 | { DRM_MODE_DPMS_OFF, "Off" } |
108 | { DRM_MODE_DPMS_OFF, "Off" } |
Line 110... | Line 111... | ||
110 | DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list) |
111 | DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list) |
Line 111... | Line 112... | ||
111 | 112 | ||
112 | /* |
113 | /* |
113 | * Optional properties |
114 | * Optional properties |
114 | */ |
115 | */ |
115 | static struct drm_prop_enum_list drm_scaling_mode_enum_list[] = |
116 | static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] = |
116 | { |
117 | { |
117 | { DRM_MODE_SCALE_NONE, "None" }, |
118 | { DRM_MODE_SCALE_NONE, "None" }, |
118 | { DRM_MODE_SCALE_FULLSCREEN, "Full" }, |
119 | { DRM_MODE_SCALE_FULLSCREEN, "Full" }, |
119 | { DRM_MODE_SCALE_CENTER, "Center" }, |
120 | { DRM_MODE_SCALE_CENTER, "Center" }, |
120 | { DRM_MODE_SCALE_ASPECT, "Full aspect" }, |
121 | { DRM_MODE_SCALE_ASPECT, "Full aspect" }, |
Line 121... | Line 122... | ||
121 | }; |
122 | }; |
122 | 123 | ||
123 | static struct drm_prop_enum_list drm_dithering_mode_enum_list[] = |
124 | static const struct drm_prop_enum_list drm_dithering_mode_enum_list[] = |
124 | { |
125 | { |
125 | { DRM_MODE_DITHERING_OFF, "Off" }, |
126 | { DRM_MODE_DITHERING_OFF, "Off" }, |
126 | { DRM_MODE_DITHERING_ON, "On" }, |
127 | { DRM_MODE_DITHERING_ON, "On" }, |
Line 127... | Line 128... | ||
127 | { DRM_MODE_DITHERING_AUTO, "Automatic" }, |
128 | { DRM_MODE_DITHERING_AUTO, "Automatic" }, |
128 | }; |
129 | }; |
129 | 130 | ||
130 | /* |
131 | /* |
131 | * Non-global properties, but "required" for certain connectors. |
132 | * Non-global properties, but "required" for certain connectors. |
132 | */ |
133 | */ |
133 | static struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = |
134 | static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = |
134 | { |
135 | { |
135 | { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ |
136 | { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ |
Line 136... | Line 137... | ||
136 | { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ |
137 | { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ |
Line 137... | Line 138... | ||
137 | { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ |
138 | { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ |
138 | }; |
139 | }; |
139 | 140 | ||
140 | DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list) |
141 | DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list) |
141 | 142 | ||
142 | static struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = |
143 | static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = |
Line 143... | Line 144... | ||
143 | { |
144 | { |
144 | { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ |
145 | { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ |
Line 145... | Line 146... | ||
145 | { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ |
146 | { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ |
146 | { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ |
147 | { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ |
147 | }; |
148 | }; |
148 | 149 | ||
149 | DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name, |
150 | DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name, |
150 | drm_dvi_i_subconnector_enum_list) |
151 | drm_dvi_i_subconnector_enum_list) |
151 | 152 | ||
152 | static struct drm_prop_enum_list drm_tv_select_enum_list[] = |
153 | static const struct drm_prop_enum_list drm_tv_select_enum_list[] = |
Line 153... | Line 154... | ||
153 | { |
154 | { |
Line 154... | Line 155... | ||
154 | { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ |
155 | { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ |
155 | { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ |
156 | { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ |
156 | { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ |
157 | { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ |
157 | { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ |
158 | { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ |
158 | { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */ |
159 | { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */ |
159 | }; |
160 | }; |
Line 170... | Line 171... | ||
170 | }; |
171 | }; |
Line 171... | Line 172... | ||
171 | 172 | ||
172 | DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name, |
173 | DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name, |
Line 173... | Line 174... | ||
173 | drm_tv_subconnector_enum_list) |
174 | drm_tv_subconnector_enum_list) |
174 | 175 | ||
175 | static struct drm_prop_enum_list drm_dirty_info_enum_list[] = { |
176 | static const struct drm_prop_enum_list drm_dirty_info_enum_list[] = { |
176 | { DRM_MODE_DIRTY_OFF, "Off" }, |
177 | { DRM_MODE_DIRTY_OFF, "Off" }, |
177 | { DRM_MODE_DIRTY_ON, "On" }, |
178 | { DRM_MODE_DIRTY_ON, "On" }, |
Line 178... | Line -... | ||
178 | { DRM_MODE_DIRTY_ANNOTATE, "Annotate" }, |
- | |
179 | }; |
- | |
180 | - | ||
181 | DRM_ENUM_NAME_FN(drm_get_dirty_info_name, |
179 | { DRM_MODE_DIRTY_ANNOTATE, "Annotate" }, |
182 | drm_dirty_info_enum_list) |
180 | }; |
183 | 181 | ||
184 | struct drm_conn_prop_enum_list { |
182 | struct drm_conn_prop_enum_list { |
185 | int type; |
183 | int type; |
Line 186... | Line 184... | ||
186 | char *name; |
184 | const char *name; |
187 | int count; |
185 | int count; |
Line 207... | Line 205... | ||
207 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, |
205 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, |
208 | { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, |
206 | { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, |
209 | { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0}, |
207 | { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0}, |
210 | }; |
208 | }; |
Line 211... | Line 209... | ||
211 | 209 | ||
212 | static struct drm_prop_enum_list drm_encoder_enum_list[] = |
210 | static const struct drm_prop_enum_list drm_encoder_enum_list[] = |
213 | { { DRM_MODE_ENCODER_NONE, "None" }, |
211 | { { DRM_MODE_ENCODER_NONE, "None" }, |
214 | { DRM_MODE_ENCODER_DAC, "DAC" }, |
212 | { DRM_MODE_ENCODER_DAC, "DAC" }, |
215 | { DRM_MODE_ENCODER_TMDS, "TMDS" }, |
213 | { DRM_MODE_ENCODER_TMDS, "TMDS" }, |
216 | { DRM_MODE_ENCODER_LVDS, "LVDS" }, |
214 | { DRM_MODE_ENCODER_LVDS, "LVDS" }, |
217 | { DRM_MODE_ENCODER_TVDAC, "TV" }, |
215 | { DRM_MODE_ENCODER_TVDAC, "TV" }, |
218 | { DRM_MODE_ENCODER_VIRTUAL, "Virtual" }, |
216 | { DRM_MODE_ENCODER_VIRTUAL, "Virtual" }, |
Line 219... | Line 217... | ||
219 | }; |
217 | }; |
220 | 218 | ||
221 | char *drm_get_encoder_name(struct drm_encoder *encoder) |
219 | const char *drm_get_encoder_name(const struct drm_encoder *encoder) |
Line 222... | Line 220... | ||
222 | { |
220 | { |
223 | static char buf[32]; |
221 | static char buf[32]; |
224 | 222 | ||
225 | snprintf(buf, 32, "%s-%d", |
223 | snprintf(buf, 32, "%s-%d", |
226 | drm_encoder_enum_list[encoder->encoder_type].name, |
224 | drm_encoder_enum_list[encoder->encoder_type].name, |
227 | encoder->base.id); |
225 | encoder->base.id); |
Line 228... | Line 226... | ||
228 | return buf; |
226 | return buf; |
229 | } |
227 | } |
230 | EXPORT_SYMBOL(drm_get_encoder_name); |
228 | EXPORT_SYMBOL(drm_get_encoder_name); |
Line 231... | Line 229... | ||
231 | 229 | ||
232 | char *drm_get_connector_name(struct drm_connector *connector) |
230 | const char *drm_get_connector_name(const struct drm_connector *connector) |
233 | { |
231 | { |
234 | static char buf[32]; |
232 | static char buf[32]; |
235 | 233 | ||
236 | snprintf(buf, 32, "%s-%d", |
234 | snprintf(buf, 32, "%s-%d", |
Line 237... | Line 235... | ||
237 | drm_connector_enum_list[connector->connector_type].name, |
235 | drm_connector_enum_list[connector->connector_type].name, |
238 | connector->connector_type_id); |
236 | connector->connector_type_id); |
239 | return buf; |
237 | return buf; |
240 | } |
238 | } |
241 | EXPORT_SYMBOL(drm_get_connector_name); |
239 | EXPORT_SYMBOL(drm_get_connector_name); |
242 | 240 | ||
243 | char *drm_get_connector_status_name(enum drm_connector_status status) |
241 | const char *drm_get_connector_status_name(enum drm_connector_status status) |
244 | { |
242 | { |
245 | if (status == connector_status_connected) |
243 | if (status == connector_status_connected) |
246 | return "connected"; |
244 | return "connected"; |
Line -... | Line 245... | ||
- | 245 | else if (status == connector_status_disconnected) |
|
- | 246 | return "disconnected"; |
|
- | 247 | else |
|
- | 248 | return "unknown"; |
|
- | 249 | } |
|
- | 250 | EXPORT_SYMBOL(drm_get_connector_status_name); |
|
- | 251 | ||
- | 252 | static char printable_char(int c) |
|
- | 253 | { |
|
- | 254 | return isascii(c) && isprint(c) ? c : '?'; |
|
- | 255 | } |
|
- | 256 | ||
- | 257 | const char *drm_get_format_name(uint32_t format) |
|
- | 258 | { |
|
- | 259 | static char buf[32]; |
|
- | 260 | ||
- | 261 | snprintf(buf, sizeof(buf), |
|
- | 262 | "%c%c%c%c %s-endian (0x%08x)", |
|
- | 263 | printable_char(format & 0xff), |
|
- | 264 | printable_char((format >> 8) & 0xff), |
|
- | 265 | printable_char((format >> 16) & 0xff), |
|
- | 266 | printable_char((format >> 24) & 0x7f), |
|
247 | else if (status == connector_status_disconnected) |
267 | format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little", |
248 | return "disconnected"; |
268 | format); |
249 | else |
269 | |
250 | return "unknown"; |
270 | return buf; |
251 | } |
271 | } |
Line 411... | Line 431... | ||
411 | struct drm_framebuffer *fb; |
431 | struct drm_framebuffer *fb; |
Line 412... | Line 432... | ||
412 | 432 | ||
413 | mutex_lock(&dev->mode_config.fb_lock); |
433 | mutex_lock(&dev->mode_config.fb_lock); |
414 | fb = __drm_framebuffer_lookup(dev, id); |
434 | fb = __drm_framebuffer_lookup(dev, id); |
415 | if (fb) |
435 | if (fb) |
416 | kref_get(&fb->refcount); |
436 | drm_framebuffer_reference(fb); |
Line 417... | Line 437... | ||
417 | mutex_unlock(&dev->mode_config.fb_lock); |
437 | mutex_unlock(&dev->mode_config.fb_lock); |
418 | 438 | ||
419 | return fb; |
439 | return fb; |
Line 566... | Line 586... | ||
566 | DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc); |
586 | DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc); |
567 | } |
587 | } |
568 | } |
588 | } |
Line 569... | Line 589... | ||
569 | 589 | ||
570 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) { |
590 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) { |
571 | if (plane->fb == fb) { |
- | |
572 | /* should turn off the crtc */ |
591 | if (plane->fb == fb) |
573 | ret = plane->funcs->disable_plane(plane); |
- | |
574 | if (ret) |
- | |
575 | DRM_ERROR("failed to disable plane with busy fb\n"); |
- | |
576 | /* disconnect the plane from the fb and crtc: */ |
- | |
577 | __drm_framebuffer_unreference(plane->fb); |
- | |
578 | plane->fb = NULL; |
- | |
579 | plane->crtc = NULL; |
- | |
580 | } |
592 | drm_plane_force_disable(plane); |
581 | } |
593 | } |
582 | drm_modeset_unlock_all(dev); |
594 | drm_modeset_unlock_all(dev); |
Line 583... | Line 595... | ||
583 | } |
595 | } |
Line 590... | Line 602... | ||
590 | * drm_crtc_init - Initialise a new CRTC object |
602 | * drm_crtc_init - Initialise a new CRTC object |
591 | * @dev: DRM device |
603 | * @dev: DRM device |
592 | * @crtc: CRTC object to init |
604 | * @crtc: CRTC object to init |
593 | * @funcs: callbacks for the new CRTC |
605 | * @funcs: callbacks for the new CRTC |
594 | * |
606 | * |
595 | * Inits a new object created as base part of an driver crtc object. |
607 | * Inits a new object created as base part of a driver crtc object. |
596 | * |
608 | * |
597 | * RETURNS: |
609 | * RETURNS: |
598 | * Zero on success, error code on failure. |
610 | * Zero on success, error code on failure. |
599 | */ |
611 | */ |
600 | int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, |
612 | int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, |
Line 625... | Line 637... | ||
625 | return ret; |
637 | return ret; |
626 | } |
638 | } |
627 | EXPORT_SYMBOL(drm_crtc_init); |
639 | EXPORT_SYMBOL(drm_crtc_init); |
Line 628... | Line 640... | ||
628 | 640 | ||
629 | /** |
641 | /** |
630 | * drm_crtc_cleanup - Cleans up the core crtc usage. |
642 | * drm_crtc_cleanup - Clean up the core crtc usage |
631 | * @crtc: CRTC to cleanup |
643 | * @crtc: CRTC to cleanup |
632 | * |
644 | * |
- | 645 | * This function cleans up @crtc and removes it from the DRM mode setting |
|
633 | * Cleanup @crtc. Removes from drm modesetting space |
646 | * core. Note that the function does *not* free the crtc structure itself, |
634 | * does NOT free object, caller does that. |
647 | * this is the responsibility of the caller. |
635 | */ |
648 | */ |
636 | void drm_crtc_cleanup(struct drm_crtc *crtc) |
649 | void drm_crtc_cleanup(struct drm_crtc *crtc) |
637 | { |
650 | { |
Line 654... | Line 667... | ||
654 | * Add @mode to @connector's mode list for later use. |
667 | * Add @mode to @connector's mode list for later use. |
655 | */ |
668 | */ |
656 | void drm_mode_probed_add(struct drm_connector *connector, |
669 | void drm_mode_probed_add(struct drm_connector *connector, |
657 | struct drm_display_mode *mode) |
670 | struct drm_display_mode *mode) |
658 | { |
671 | { |
659 | list_add(&mode->head, &connector->probed_modes); |
672 | list_add_tail(&mode->head, &connector->probed_modes); |
660 | } |
673 | } |
661 | EXPORT_SYMBOL(drm_mode_probed_add); |
674 | EXPORT_SYMBOL(drm_mode_probed_add); |
Line 662... | Line 675... | ||
662 | 675 | ||
663 | /** |
676 | /** |
Line 800... | Line 813... | ||
800 | dev->mode_config.num_encoder--; |
813 | dev->mode_config.num_encoder--; |
801 | drm_modeset_unlock_all(dev); |
814 | drm_modeset_unlock_all(dev); |
802 | } |
815 | } |
803 | EXPORT_SYMBOL(drm_encoder_cleanup); |
816 | EXPORT_SYMBOL(drm_encoder_cleanup); |
Line -... | Line 817... | ||
- | 817 | ||
- | 818 | /** |
|
- | 819 | * drm_plane_init - Initialise a new plane object |
|
- | 820 | * @dev: DRM device |
|
- | 821 | * @plane: plane object to init |
|
- | 822 | * @possible_crtcs: bitmask of possible CRTCs |
|
- | 823 | * @funcs: callbacks for the new plane |
|
- | 824 | * @formats: array of supported formats (%DRM_FORMAT_*) |
|
- | 825 | * @format_count: number of elements in @formats |
|
- | 826 | * @priv: plane is private (hidden from userspace)? |
|
- | 827 | * |
|
- | 828 | * Inits a new object created as base part of a driver plane object. |
|
- | 829 | * |
|
- | 830 | * RETURNS: |
|
- | 831 | * Zero on success, error code on failure. |
|
804 | 832 | */ |
|
805 | int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, |
833 | int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, |
806 | unsigned long possible_crtcs, |
834 | unsigned long possible_crtcs, |
807 | const struct drm_plane_funcs *funcs, |
835 | const struct drm_plane_funcs *funcs, |
808 | const uint32_t *formats, uint32_t format_count, |
836 | const uint32_t *formats, uint32_t format_count, |
Line 848... | Line 876... | ||
848 | 876 | ||
849 | return ret; |
877 | return ret; |
850 | } |
878 | } |
Line -... | Line 879... | ||
- | 879 | EXPORT_SYMBOL(drm_plane_init); |
|
- | 880 | ||
- | 881 | /** |
|
- | 882 | * drm_plane_cleanup - Clean up the core plane usage |
|
- | 883 | * @plane: plane to cleanup |
|
- | 884 | * |
|
- | 885 | * This function cleans up @plane and removes it from the DRM mode setting |
|
- | 886 | * core. Note that the function does *not* free the plane structure itself, |
|
851 | EXPORT_SYMBOL(drm_plane_init); |
887 | * this is the responsibility of the caller. |
852 | 888 | */ |
|
853 | void drm_plane_cleanup(struct drm_plane *plane) |
889 | void drm_plane_cleanup(struct drm_plane *plane) |
Line 854... | Line 890... | ||
854 | { |
890 | { |
Line 865... | Line 901... | ||
865 | drm_modeset_unlock_all(dev); |
901 | drm_modeset_unlock_all(dev); |
866 | } |
902 | } |
867 | EXPORT_SYMBOL(drm_plane_cleanup); |
903 | EXPORT_SYMBOL(drm_plane_cleanup); |
Line 868... | Line 904... | ||
868 | 904 | ||
- | 905 | /** |
|
- | 906 | * drm_plane_force_disable - Forcibly disable a plane |
|
- | 907 | * @plane: plane to disable |
|
- | 908 | * |
|
- | 909 | * Forces the plane to be disabled. |
|
- | 910 | * |
|
- | 911 | * Used when the plane's current framebuffer is destroyed, |
|
- | 912 | * and when restoring fbdev mode. |
|
- | 913 | */ |
|
- | 914 | void drm_plane_force_disable(struct drm_plane *plane) |
|
- | 915 | { |
|
- | 916 | int ret; |
|
- | 917 | ||
- | 918 | if (!plane->fb) |
|
- | 919 | return; |
|
- | 920 | ||
- | 921 | ret = plane->funcs->disable_plane(plane); |
|
- | 922 | if (ret) |
|
- | 923 | DRM_ERROR("failed to disable plane with busy fb\n"); |
|
- | 924 | /* disconnect the plane from the fb and crtc: */ |
|
- | 925 | __drm_framebuffer_unreference(plane->fb); |
|
- | 926 | plane->fb = NULL; |
|
- | 927 | plane->crtc = NULL; |
|
- | 928 | } |
|
- | 929 | EXPORT_SYMBOL(drm_plane_force_disable); |
|
- | 930 | ||
869 | /** |
931 | /** |
870 | * drm_mode_create - create a new display mode |
932 | * drm_mode_create - create a new display mode |
871 | * @dev: DRM device |
933 | * @dev: DRM device |
872 | * |
934 | * |
873 | * Create a new drm_display_mode, give it an ID, and return it. |
935 | * Create a new drm_display_mode, give it an ID, and return it. |
Line 1739... | Line 1801... | ||
1739 | else |
1801 | else |
1740 | plane_resp->fb_id = 0; |
1802 | plane_resp->fb_id = 0; |
Line 1741... | Line 1803... | ||
1741 | 1803 | ||
1742 | plane_resp->plane_id = plane->base.id; |
1804 | plane_resp->plane_id = plane->base.id; |
1743 | plane_resp->possible_crtcs = plane->possible_crtcs; |
1805 | plane_resp->possible_crtcs = plane->possible_crtcs; |
Line 1744... | Line 1806... | ||
1744 | plane_resp->gamma_size = plane->gamma_size; |
1806 | plane_resp->gamma_size = 0; |
1745 | 1807 | ||
1746 | /* |
1808 | /* |
1747 | * This ioctl is called twice, once to determine how much space is |
1809 | * This ioctl is called twice, once to determine how much space is |
Line 1833... | Line 1895... | ||
1833 | /* Check whether this plane supports the fb pixel format. */ |
1895 | /* Check whether this plane supports the fb pixel format. */ |
1834 | for (i = 0; i < plane->format_count; i++) |
1896 | for (i = 0; i < plane->format_count; i++) |
1835 | if (fb->pixel_format == plane->format_types[i]) |
1897 | if (fb->pixel_format == plane->format_types[i]) |
1836 | break; |
1898 | break; |
1837 | if (i == plane->format_count) { |
1899 | if (i == plane->format_count) { |
1838 | DRM_DEBUG_KMS("Invalid pixel format 0x%08x\n", fb->pixel_format); |
1900 | DRM_DEBUG_KMS("Invalid pixel format %s\n", |
- | 1901 | drm_get_format_name(fb->pixel_format)); |
|
1839 | ret = -EINVAL; |
1902 | ret = -EINVAL; |
1840 | goto out; |
1903 | goto out; |
1841 | } |
1904 | } |
Line 1842... | Line 1905... | ||
1842 | 1905 | ||
Line 1906... | Line 1969... | ||
1906 | * interface. The only thing it adds is correct refcounting dance. |
1969 | * interface. The only thing it adds is correct refcounting dance. |
1907 | */ |
1970 | */ |
1908 | int drm_mode_set_config_internal(struct drm_mode_set *set) |
1971 | int drm_mode_set_config_internal(struct drm_mode_set *set) |
1909 | { |
1972 | { |
1910 | struct drm_crtc *crtc = set->crtc; |
1973 | struct drm_crtc *crtc = set->crtc; |
1911 | struct drm_framebuffer *fb, *old_fb; |
1974 | struct drm_framebuffer *fb; |
- | 1975 | struct drm_crtc *tmp; |
|
1912 | int ret; |
1976 | int ret; |
Line -... | Line 1977... | ||
- | 1977 | ||
- | 1978 | /* |
|
- | 1979 | * NOTE: ->set_config can also disable other crtcs (if we steal all |
|
- | 1980 | * connectors from it), hence we need to refcount the fbs across all |
|
- | 1981 | * crtcs. Atomic modeset will have saner semantics ... |
|
- | 1982 | */ |
|
1913 | 1983 | list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) |
|
- | 1984 | tmp->old_fb = tmp->fb; |
|
1914 | old_fb = crtc->fb; |
1985 | |
Line 1915... | Line 1986... | ||
1915 | fb = set->fb; |
1986 | fb = set->fb; |
1916 | 1987 | ||
- | 1988 | ret = crtc->funcs->set_config(set); |
|
- | 1989 | if (ret == 0) { |
|
- | 1990 | /* crtc->fb must be updated by ->set_config, enforces this. */ |
|
- | 1991 | WARN_ON(fb != crtc->fb); |
|
- | 1992 | } |
|
1917 | ret = crtc->funcs->set_config(set); |
1993 | |
1918 | if (ret == 0) { |
1994 | list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) { |
1919 | if (old_fb) |
1995 | if (tmp->fb) |
1920 | drm_framebuffer_unreference(old_fb); |
1996 | drm_framebuffer_reference(tmp->fb); |
1921 | if (fb) |
1997 | // if (tmp->old_fb) |
Line 1922... | Line 1998... | ||
1922 | drm_framebuffer_reference(fb); |
1998 | // drm_framebuffer_unreference(tmp->old_fb); |
1923 | } |
1999 | } |
1924 | 2000 | ||
Line 2100... | Line 2176... | ||
2100 | drm_mode_destroy(dev, mode); |
2176 | drm_mode_destroy(dev, mode); |
2101 | drm_modeset_unlock_all(dev); |
2177 | drm_modeset_unlock_all(dev); |
2102 | return ret; |
2178 | return ret; |
2103 | } |
2179 | } |
Line 2104... | Line 2180... | ||
2104 | 2180 | ||
- | 2181 | static int drm_mode_cursor_common(struct drm_device *dev, |
|
2105 | int drm_mode_cursor_ioctl(struct drm_device *dev, |
2182 | struct drm_mode_cursor2 *req, |
2106 | void *data, struct drm_file *file_priv) |
2183 | struct drm_file *file_priv) |
2107 | { |
- | |
2108 | struct drm_mode_cursor *req = data; |
2184 | { |
2109 | struct drm_mode_object *obj; |
2185 | struct drm_mode_object *obj; |
2110 | struct drm_crtc *crtc; |
2186 | struct drm_crtc *crtc; |
Line 2111... | Line 2187... | ||
2111 | int ret = 0; |
2187 | int ret = 0; |
Line 2123... | Line 2199... | ||
2123 | } |
2199 | } |
2124 | crtc = obj_to_crtc(obj); |
2200 | crtc = obj_to_crtc(obj); |
Line 2125... | Line 2201... | ||
2125 | 2201 | ||
2126 | mutex_lock(&crtc->mutex); |
2202 | mutex_lock(&crtc->mutex); |
2127 | if (req->flags & DRM_MODE_CURSOR_BO) { |
2203 | if (req->flags & DRM_MODE_CURSOR_BO) { |
2128 | if (!crtc->funcs->cursor_set) { |
2204 | if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) { |
2129 | ret = -ENXIO; |
2205 | ret = -ENXIO; |
2130 | goto out; |
2206 | goto out; |
2131 | } |
2207 | } |
- | 2208 | /* Turns off the cursor if handle is 0 */ |
|
- | 2209 | if (crtc->funcs->cursor_set2) |
|
- | 2210 | ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle, |
|
- | 2211 | req->width, req->height, req->hot_x, req->hot_y); |
|
2132 | /* Turns off the cursor if handle is 0 */ |
2212 | else |
2133 | ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle, |
2213 | ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle, |
2134 | req->width, req->height); |
2214 | req->width, req->height); |
Line 2135... | Line 2215... | ||
2135 | } |
2215 | } |
Line 2144... | Line 2224... | ||
2144 | } |
2224 | } |
2145 | out: |
2225 | out: |
2146 | mutex_unlock(&crtc->mutex); |
2226 | mutex_unlock(&crtc->mutex); |
Line 2147... | Line 2227... | ||
2147 | 2227 | ||
- | 2228 | return ret; |
|
- | 2229 | ||
- | 2230 | } |
|
- | 2231 | int drm_mode_cursor_ioctl(struct drm_device *dev, |
|
- | 2232 | void *data, struct drm_file *file_priv) |
|
- | 2233 | { |
|
- | 2234 | struct drm_mode_cursor *req = data; |
|
- | 2235 | struct drm_mode_cursor2 new_req; |
|
- | 2236 | ||
- | 2237 | memcpy(&new_req, req, sizeof(struct drm_mode_cursor)); |
|
- | 2238 | new_req.hot_x = new_req.hot_y = 0; |
|
- | 2239 | ||
- | 2240 | return drm_mode_cursor_common(dev, &new_req, file_priv); |
|
- | 2241 | } |
|
- | 2242 | ||
- | 2243 | int drm_mode_cursor2_ioctl(struct drm_device *dev, |
|
- | 2244 | void *data, struct drm_file *file_priv) |
|
- | 2245 | { |
|
- | 2246 | struct drm_mode_cursor2 *req = data; |
|
2148 | return ret; |
2247 | return drm_mode_cursor_common(dev, req, file_priv); |
2149 | } |
2248 | } |
2150 | #endif |
2249 | #endif |
2151 | /* Original addfb only supported RGB formats, so figure out which one */ |
2250 | /* Original addfb only supported RGB formats, so figure out which one */ |
2152 | uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth) |
2251 | uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth) |
Line 2313... | Line 2412... | ||
2313 | { |
2412 | { |
2314 | int ret, hsub, vsub, num_planes, i; |
2413 | int ret, hsub, vsub, num_planes, i; |
Line 2315... | Line 2414... | ||
2315 | 2414 | ||
2316 | ret = format_check(r); |
2415 | ret = format_check(r); |
2317 | if (ret) { |
2416 | if (ret) { |
- | 2417 | DRM_DEBUG_KMS("bad framebuffer format %s\n", |
|
2318 | DRM_DEBUG_KMS("bad framebuffer format 0x%08x\n", r->pixel_format); |
2418 | drm_get_format_name(r->pixel_format)); |
2319 | return ret; |
2419 | return ret; |
Line 2320... | Line 2420... | ||
2320 | } |
2420 | } |
2321 | 2421 |