Rev 3480 | Rev 3764 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3480 | Rev 3746 | ||
---|---|---|---|
Line 704... | Line 704... | ||
704 | connector->dev = dev; |
704 | connector->dev = dev; |
705 | connector->funcs = funcs; |
705 | connector->funcs = funcs; |
706 | connector->connector_type = connector_type; |
706 | connector->connector_type = connector_type; |
707 | connector->connector_type_id = |
707 | connector->connector_type_id = |
708 | ++drm_connector_enum_list[connector_type].count; /* TODO */ |
708 | ++drm_connector_enum_list[connector_type].count; /* TODO */ |
709 | INIT_LIST_HEAD(&connector->user_modes); |
- | |
710 | INIT_LIST_HEAD(&connector->probed_modes); |
709 | INIT_LIST_HEAD(&connector->probed_modes); |
711 | INIT_LIST_HEAD(&connector->modes); |
710 | INIT_LIST_HEAD(&connector->modes); |
712 | connector->edid_blob_ptr = NULL; |
711 | connector->edid_blob_ptr = NULL; |
713 | connector->status = connector_status_unknown; |
712 | connector->status = connector_status_unknown; |
Line 745... | Line 744... | ||
745 | drm_mode_remove(connector, mode); |
744 | drm_mode_remove(connector, mode); |
Line 746... | Line 745... | ||
746 | 745 | ||
747 | list_for_each_entry_safe(mode, t, &connector->modes, head) |
746 | list_for_each_entry_safe(mode, t, &connector->modes, head) |
Line 748... | Line -... | ||
748 | drm_mode_remove(connector, mode); |
- | |
749 | - | ||
750 | list_for_each_entry_safe(mode, t, &connector->user_modes, head) |
- | |
751 | drm_mode_remove(connector, mode); |
747 | drm_mode_remove(connector, mode); |
752 | 748 | ||
753 | drm_mode_object_put(dev, &connector->base); |
749 | drm_mode_object_put(dev, &connector->base); |
754 | list_del(&connector->head); |
750 | list_del(&connector->head); |
755 | dev->mode_config.num_connector--; |
751 | dev->mode_config.num_connector--; |
Line 1118... | Line 1114... | ||
1118 | 1114 | ||
1119 | return 0; |
1115 | return 0; |
1120 | } |
1116 | } |
Line 1121... | Line -... | ||
1121 | EXPORT_SYMBOL(drm_mode_create_dirty_info_property); |
- | |
1122 | - | ||
1123 | /** |
- | |
1124 | * drm_mode_config_init - initialize DRM mode_configuration structure |
- | |
1125 | * @dev: DRM device |
- | |
1126 | * |
- | |
1127 | * Initialize @dev's mode_config structure, used for tracking the graphics |
- | |
1128 | * configuration of @dev. |
- | |
1129 | * |
- | |
1130 | * Since this initializes the modeset locks, no locking is possible. Which is no |
- | |
1131 | * problem, since this should happen single threaded at init time. It is the |
- | |
1132 | * driver's problem to ensure this guarantee. |
- | |
1133 | * |
- | |
1134 | */ |
- | |
1135 | void drm_mode_config_init(struct drm_device *dev) |
- | |
1136 | { |
- | |
1137 | mutex_init(&dev->mode_config.mutex); |
- | |
1138 | mutex_init(&dev->mode_config.idr_mutex); |
- | |
1139 | mutex_init(&dev->mode_config.fb_lock); |
- | |
1140 | INIT_LIST_HEAD(&dev->mode_config.fb_list); |
- | |
1141 | INIT_LIST_HEAD(&dev->mode_config.crtc_list); |
- | |
1142 | INIT_LIST_HEAD(&dev->mode_config.connector_list); |
- | |
1143 | INIT_LIST_HEAD(&dev->mode_config.encoder_list); |
- | |
1144 | INIT_LIST_HEAD(&dev->mode_config.property_list); |
- | |
1145 | INIT_LIST_HEAD(&dev->mode_config.property_blob_list); |
- | |
1146 | INIT_LIST_HEAD(&dev->mode_config.plane_list); |
- | |
1147 | idr_init(&dev->mode_config.crtc_idr); |
- | |
1148 | - | ||
1149 | drm_modeset_lock_all(dev); |
- | |
1150 | drm_mode_create_standard_connector_properties(dev); |
- | |
1151 | drm_modeset_unlock_all(dev); |
- | |
1152 | - | ||
1153 | /* Just to be sure */ |
- | |
1154 | dev->mode_config.num_fb = 0; |
- | |
1155 | dev->mode_config.num_connector = 0; |
- | |
1156 | dev->mode_config.num_crtc = 0; |
- | |
1157 | dev->mode_config.num_encoder = 0; |
- | |
1158 | } |
- | |
1159 | EXPORT_SYMBOL(drm_mode_config_init); |
1117 | EXPORT_SYMBOL(drm_mode_create_dirty_info_property); |
1160 | 1118 | ||
1161 | int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group) |
1119 | static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group) |
Line 1162... | Line 1120... | ||
1162 | { |
1120 | { |
1163 | uint32_t total_objects = 0; |
1121 | uint32_t total_objects = 0; |
Line 1201... | Line 1159... | ||
1201 | return 0; |
1159 | return 0; |
1202 | } |
1160 | } |
1203 | EXPORT_SYMBOL(drm_mode_group_init_legacy_group); |
1161 | EXPORT_SYMBOL(drm_mode_group_init_legacy_group); |
Line 1204... | Line 1162... | ||
1204 | 1162 | ||
1205 | /** |
- | |
1206 | * drm_mode_config_cleanup - free up DRM mode_config info |
- | |
1207 | * @dev: DRM device |
- | |
1208 | * |
- | |
1209 | * Free up all the connectors and CRTCs associated with this DRM device, then |
- | |
1210 | * free up the framebuffers and associated buffer objects. |
- | |
1211 | * |
- | |
1212 | * Note that since this /should/ happen single-threaded at driver/device |
- | |
1213 | * teardown time, no locking is required. It's the driver's job to ensure that |
- | |
1214 | * this guarantee actually holds true. |
- | |
1215 | * |
- | |
1216 | * FIXME: cleanup any dangling user buffer objects too |
- | |
1217 | */ |
- | |
1218 | void drm_mode_config_cleanup(struct drm_device *dev) |
- | |
1219 | { |
- | |
1220 | struct drm_connector *connector, *ot; |
- | |
1221 | struct drm_crtc *crtc, *ct; |
- | |
1222 | struct drm_encoder *encoder, *enct; |
- | |
1223 | struct drm_framebuffer *fb, *fbt; |
- | |
1224 | struct drm_property *property, *pt; |
- | |
1225 | struct drm_plane *plane, *plt; |
- | |
1226 | - | ||
1227 | list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list, |
- | |
1228 | head) { |
- | |
1229 | encoder->funcs->destroy(encoder); |
- | |
1230 | } |
- | |
1231 | - | ||
1232 | list_for_each_entry_safe(connector, ot, |
- | |
1233 | &dev->mode_config.connector_list, head) { |
- | |
1234 | connector->funcs->destroy(connector); |
- | |
1235 | } |
- | |
1236 | - | ||
1237 | list_for_each_entry_safe(property, pt, &dev->mode_config.property_list, |
- | |
1238 | head) { |
- | |
1239 | drm_property_destroy(dev, property); |
- | |
1240 | } |
- | |
1241 | - | ||
1242 | /* |
- | |
1243 | * Single-threaded teardown context, so it's not required to grab the |
- | |
1244 | * fb_lock to protect against concurrent fb_list access. Contrary, it |
- | |
1245 | * would actually deadlock with the drm_framebuffer_cleanup function. |
- | |
1246 | * |
- | |
1247 | * Also, if there are any framebuffers left, that's a driver leak now, |
- | |
1248 | * so politely WARN about this. |
- | |
1249 | */ |
- | |
1250 | WARN_ON(!list_empty(&dev->mode_config.fb_list)); |
- | |
1251 | list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { |
- | |
1252 | drm_framebuffer_remove(fb); |
- | |
1253 | } |
- | |
1254 | - | ||
1255 | list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list, |
- | |
1256 | head) { |
- | |
1257 | plane->funcs->destroy(plane); |
- | |
1258 | } |
- | |
1259 | - | ||
1260 | list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) { |
- | |
1261 | crtc->funcs->destroy(crtc); |
- | |
1262 | } |
- | |
1263 | - | ||
1264 | idr_destroy(&dev->mode_config.crtc_idr); |
- | |
1265 | } |
- | |
1266 | EXPORT_SYMBOL(drm_mode_config_cleanup); |
- | |
1267 | - | ||
1268 | /** |
1163 | /** |
1269 | * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo |
1164 | * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo |
1270 | * @out: drm_mode_modeinfo struct to return to the user |
1165 | * @out: drm_mode_modeinfo struct to return to the user |
1271 | * @in: drm_display_mode to use |
1166 | * @in: drm_display_mode to use |
1272 | * |
1167 | * |
Line 2720... | Line 2615... | ||
2720 | } |
2615 | } |
2721 | mutex_unlock(&priv->fbs_lock); |
2616 | mutex_unlock(&priv->fbs_lock); |
2722 | } |
2617 | } |
2723 | #endif |
2618 | #endif |
Line 2724... | Line -... | ||
2724 | - | ||
2725 | /** |
- | |
2726 | * drm_mode_attachmode - add a mode to the user mode list |
- | |
2727 | * @dev: DRM device |
- | |
2728 | * @connector: connector to add the mode to |
- | |
2729 | * @mode: mode to add |
- | |
2730 | * |
- | |
2731 | * Add @mode to @connector's user mode list. |
- | |
2732 | */ |
- | |
2733 | static void drm_mode_attachmode(struct drm_device *dev, |
- | |
2734 | struct drm_connector *connector, |
- | |
2735 | struct drm_display_mode *mode) |
- | |
2736 | { |
- | |
2737 | list_add_tail(&mode->head, &connector->user_modes); |
- | |
2738 | } |
- | |
2739 | - | ||
2740 | int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc, |
- | |
2741 | const struct drm_display_mode *mode) |
- | |
2742 | { |
- | |
2743 | struct drm_connector *connector; |
- | |
2744 | int ret = 0; |
- | |
2745 | struct drm_display_mode *dup_mode, *next; |
- | |
2746 | LIST_HEAD(list); |
- | |
2747 | - | ||
2748 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
- | |
2749 | if (!connector->encoder) |
- | |
2750 | continue; |
- | |
2751 | if (connector->encoder->crtc == crtc) { |
- | |
2752 | dup_mode = drm_mode_duplicate(dev, mode); |
- | |
2753 | if (!dup_mode) { |
- | |
2754 | ret = -ENOMEM; |
- | |
2755 | goto out; |
- | |
2756 | } |
- | |
2757 | list_add_tail(&dup_mode->head, &list); |
- | |
2758 | } |
- | |
2759 | } |
- | |
2760 | - | ||
2761 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
- | |
2762 | if (!connector->encoder) |
- | |
2763 | continue; |
- | |
2764 | if (connector->encoder->crtc == crtc) |
- | |
2765 | list_move_tail(list.next, &connector->user_modes); |
- | |
2766 | } |
- | |
2767 | - | ||
2768 | WARN_ON(!list_empty(&list)); |
- | |
2769 | - | ||
2770 | out: |
- | |
2771 | list_for_each_entry_safe(dup_mode, next, &list, head) |
- | |
2772 | drm_mode_destroy(dev, dup_mode); |
- | |
2773 | - | ||
2774 | return ret; |
- | |
2775 | } |
- | |
2776 | EXPORT_SYMBOL(drm_mode_attachmode_crtc); |
- | |
2777 | - | ||
2778 | static int drm_mode_detachmode(struct drm_device *dev, |
- | |
2779 | struct drm_connector *connector, |
- | |
2780 | struct drm_display_mode *mode) |
- | |
2781 | { |
- | |
2782 | int found = 0; |
- | |
2783 | int ret = 0; |
- | |
2784 | struct drm_display_mode *match_mode, *t; |
- | |
2785 | - | ||
2786 | list_for_each_entry_safe(match_mode, t, &connector->user_modes, head) { |
- | |
2787 | if (drm_mode_equal(match_mode, mode)) { |
- | |
2788 | list_del(&match_mode->head); |
- | |
2789 | drm_mode_destroy(dev, match_mode); |
- | |
2790 | found = 1; |
- | |
2791 | break; |
- | |
2792 | } |
- | |
2793 | } |
- | |
2794 | - | ||
2795 | if (!found) |
- | |
2796 | ret = -EINVAL; |
- | |
2797 | - | ||
2798 | return ret; |
- | |
2799 | } |
- | |
2800 | - | ||
2801 | int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode) |
- | |
2802 | { |
- | |
2803 | struct drm_connector *connector; |
- | |
2804 | - | ||
2805 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
- | |
2806 | drm_mode_detachmode(dev, connector, mode); |
- | |
2807 | } |
- | |
2808 | return 0; |
- | |
2809 | } |
- | |
2810 | EXPORT_SYMBOL(drm_mode_detachmode_crtc); |
- | |
2811 | - | ||
2812 | #if 0 |
- | |
2813 | - | ||
2814 | /** |
- | |
2815 | * drm_fb_attachmode - Attach a user mode to an connector |
- | |
2816 | * @dev: drm device for the ioctl |
- | |
2817 | * @data: data pointer for the ioctl |
- | |
2818 | * @file_priv: drm file for the ioctl call |
- | |
2819 | * |
- | |
2820 | * This attaches a user specified mode to an connector. |
- | |
2821 | * Called by the user via ioctl. |
- | |
2822 | * |
- | |
2823 | * RETURNS: |
- | |
2824 | * Zero on success, errno on failure. |
- | |
2825 | */ |
- | |
2826 | int drm_mode_attachmode_ioctl(struct drm_device *dev, |
- | |
2827 | void *data, struct drm_file *file_priv) |
- | |
2828 | { |
- | |
2829 | struct drm_mode_mode_cmd *mode_cmd = data; |
- | |
2830 | struct drm_connector *connector; |
- | |
2831 | struct drm_display_mode *mode; |
- | |
2832 | struct drm_mode_object *obj; |
- | |
2833 | struct drm_mode_modeinfo *umode = &mode_cmd->mode; |
- | |
2834 | int ret; |
- | |
2835 | - | ||
2836 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
- | |
2837 | return -EINVAL; |
- | |
2838 | - | ||
2839 | drm_modeset_lock_all(dev); |
- | |
2840 | - | ||
2841 | obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); |
- | |
2842 | if (!obj) { |
- | |
2843 | ret = -EINVAL; |
- | |
2844 | goto out; |
- | |
2845 | } |
- | |
2846 | connector = obj_to_connector(obj); |
- | |
2847 | - | ||
2848 | mode = drm_mode_create(dev); |
- | |
2849 | if (!mode) { |
- | |
2850 | ret = -ENOMEM; |
- | |
2851 | goto out; |
- | |
2852 | } |
- | |
2853 | - | ||
2854 | ret = drm_crtc_convert_umode(mode, umode); |
- | |
2855 | if (ret) { |
- | |
2856 | DRM_DEBUG_KMS("Invalid mode\n"); |
- | |
2857 | drm_mode_destroy(dev, mode); |
- | |
2858 | goto out; |
- | |
2859 | } |
- | |
2860 | - | ||
2861 | drm_mode_attachmode(dev, connector, mode); |
- | |
2862 | out: |
- | |
2863 | drm_modeset_unlock_all(dev); |
- | |
2864 | return ret; |
- | |
2865 | } |
- | |
2866 | - | ||
2867 | - | ||
2868 | /** |
- | |
2869 | * drm_fb_detachmode - Detach a user specified mode from an connector |
- | |
2870 | * @dev: drm device for the ioctl |
- | |
2871 | * @data: data pointer for the ioctl |
- | |
2872 | * @file_priv: drm file for the ioctl call |
- | |
2873 | * |
- | |
2874 | * Called by the user via ioctl. |
- | |
2875 | * |
- | |
2876 | * RETURNS: |
- | |
2877 | * Zero on success, errno on failure. |
- | |
2878 | */ |
- | |
2879 | int drm_mode_detachmode_ioctl(struct drm_device *dev, |
- | |
2880 | void *data, struct drm_file *file_priv) |
- | |
2881 | { |
- | |
2882 | struct drm_mode_object *obj; |
- | |
2883 | struct drm_mode_mode_cmd *mode_cmd = data; |
- | |
2884 | struct drm_connector *connector; |
- | |
2885 | struct drm_display_mode mode; |
- | |
2886 | struct drm_mode_modeinfo *umode = &mode_cmd->mode; |
- | |
2887 | int ret; |
- | |
2888 | - | ||
2889 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
- | |
2890 | return -EINVAL; |
- | |
2891 | - | ||
2892 | drm_modeset_lock_all(dev); |
- | |
2893 | - | ||
2894 | obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); |
- | |
2895 | if (!obj) { |
- | |
2896 | ret = -EINVAL; |
- | |
2897 | goto out; |
- | |
2898 | } |
- | |
2899 | connector = obj_to_connector(obj); |
- | |
2900 | - | ||
2901 | ret = drm_crtc_convert_umode(&mode, umode); |
- | |
2902 | if (ret) { |
- | |
2903 | DRM_DEBUG_KMS("Invalid mode\n"); |
- | |
2904 | goto out; |
- | |
2905 | } |
- | |
2906 | - | ||
2907 | ret = drm_mode_detachmode(dev, connector, &mode); |
- | |
2908 | out: |
- | |
2909 | drm_modeset_unlock_all(dev); |
- | |
2910 | return ret; |
- | |
2911 | } |
- | |
Line 2912... | Line 2619... | ||
2912 | #endif |
2619 | |
2913 | 2620 | ||
2914 | struct drm_property *drm_property_create(struct drm_device *dev, int flags, |
2621 | struct drm_property *drm_property_create(struct drm_device *dev, int flags, |
2915 | const char *name, int num_values) |
2622 | const char *name, int num_values) |
Line 3890... | Line 3597... | ||
3890 | default: |
3597 | default: |
3891 | return 1; |
3598 | return 1; |
3892 | } |
3599 | } |
3893 | } |
3600 | } |
3894 | EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);>>>>>>>>>>=>=>>>>><>><>>>>>>>>>>> |
3601 | EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); |
- | 3602 | ||
- | 3603 | /** |
|
- | 3604 | * drm_mode_config_init - initialize DRM mode_configuration structure |
|
- | 3605 | * @dev: DRM device |
|
- | 3606 | * |
|
- | 3607 | * Initialize @dev's mode_config structure, used for tracking the graphics |
|
- | 3608 | * configuration of @dev. |
|
- | 3609 | * |
|
- | 3610 | * Since this initializes the modeset locks, no locking is possible. Which is no |
|
- | 3611 | * problem, since this should happen single threaded at init time. It is the |
|
- | 3612 | * driver's problem to ensure this guarantee. |
|
- | 3613 | * |
|
- | 3614 | */ |
|
- | 3615 | void drm_mode_config_init(struct drm_device *dev) |
|
- | 3616 | { |
|
- | 3617 | mutex_init(&dev->mode_config.mutex); |
|
- | 3618 | mutex_init(&dev->mode_config.idr_mutex); |
|
- | 3619 | mutex_init(&dev->mode_config.fb_lock); |
|
- | 3620 | INIT_LIST_HEAD(&dev->mode_config.fb_list); |
|
- | 3621 | INIT_LIST_HEAD(&dev->mode_config.crtc_list); |
|
- | 3622 | INIT_LIST_HEAD(&dev->mode_config.connector_list); |
|
- | 3623 | INIT_LIST_HEAD(&dev->mode_config.encoder_list); |
|
- | 3624 | INIT_LIST_HEAD(&dev->mode_config.property_list); |
|
- | 3625 | INIT_LIST_HEAD(&dev->mode_config.property_blob_list); |
|
- | 3626 | INIT_LIST_HEAD(&dev->mode_config.plane_list); |
|
- | 3627 | idr_init(&dev->mode_config.crtc_idr); |
|
- | 3628 | ||
- | 3629 | drm_modeset_lock_all(dev); |
|
- | 3630 | drm_mode_create_standard_connector_properties(dev); |
|
- | 3631 | drm_modeset_unlock_all(dev); |
|
- | 3632 | ||
- | 3633 | /* Just to be sure */ |
|
- | 3634 | dev->mode_config.num_fb = 0; |
|
- | 3635 | dev->mode_config.num_connector = 0; |
|
- | 3636 | dev->mode_config.num_crtc = 0; |
|
- | 3637 | dev->mode_config.num_encoder = 0; |
|
- | 3638 | } |
|
- | 3639 | EXPORT_SYMBOL(drm_mode_config_init);>>>>>>>>>>=>=>>>>><>><>>>>>>>>>>> |
|
- | 3640 |