diff options
author | Dave Airlie <airlied@redhat.com> | 2016-10-10 02:36:16 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-10-10 02:36:16 -0400 |
commit | 9c704d14386dc1deeb695f2a180f9a00f23fa650 (patch) | |
tree | fd4b11b8119a0d8fca8a3ccf45e76e2334b86b8e | |
parent | a74feb65a451105bb9aba6ea695b7068b0690046 (diff) | |
parent | 0546d685f07cc4fc5748fd36e57d167877c2842d (diff) |
Merge tag 'topic/drm-misc-2016-10-05' of git://anongit.freedesktop.org/drm-intel into drm-next
Another attempt, this time rebased and without the pipe crc patches:
- display_info cleanups from Ville
- make prime/gem lookups faster with rbtrees (Chris)
- misc stuff all over
* tag 'topic/drm-misc-2016-10-05' of git://anongit.freedesktop.org/drm-intel:
drm/rockchip: analogix_dp: Refuse to enable PSR if panel doesn't support it
drm/bridge: analogix_dp: Add analogix_dp_psr_supported
drm/fb-helper: add DRM_FB_HELPER_DEFAULT_OPS for fb_ops
drm: Document caveats around atomic event handling
uapi: add missing install of sync_file.h
drm: Simplify drm_printk to reduce object size quite a bit
drm/i915: Account for sink max TMDS clock when checking the port clock
drm/i915: Replace a bunch of connector->base.display_info with a local variable
drm/edid: Move dvi_dual/max_tmds_clock parsing out from drm_edid_to_eld()
drm/edid: Clear the old cea_rev when there's no CEA extension in the new EDID
drm/edid: Reduce the number of times we parse the CEA extension block
drm/edid: Don't pass around drm_display_info needlessly
drm/edid: Move dvi_dual/max_tmds_clock to drm_display_info
drm/edid: Make max_tmds_clock kHz instead of MHz
drm/edid: Clear old dvi_dual/max_tmds_clock before parsing the new EDID
drm/edid: Clear old audio latency values before parsing the new EDID
drm: Convert prime dma-buf <-> handle to rbtree
drm/mediatek: mark symbols static where possible
drm/rockchip: mark symbols static where possible
drm/rockchip: add missing header dependencies
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_edid.c | 248 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_irq.c | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_prime.c | 85 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/mediatek/mtk_hdmi.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 1 | ||||
-rw-r--r-- | include/drm/bridge/analogix_dp.h | 1 | ||||
-rw-r--r-- | include/drm/drmP.h | 35 | ||||
-rw-r--r-- | include/drm/drm_connector.h | 15 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 56 | ||||
-rw-r--r-- | include/drm/drm_fb_helper.h | 13 | ||||
-rw-r--r-- | include/uapi/linux/Kbuild | 1 |
19 files changed, 361 insertions, 188 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index decbba5ad438..22c11e7698c8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | |||
@@ -168,12 +168,12 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector) | |||
168 | } | 168 | } |
169 | 169 | ||
170 | /* Any defined maximum tmds clock limit we must not exceed? */ | 170 | /* Any defined maximum tmds clock limit we must not exceed? */ |
171 | if (connector->max_tmds_clock > 0) { | 171 | if (connector->display_info.max_tmds_clock > 0) { |
172 | /* mode_clock is clock in kHz for mode to be modeset on this connector */ | 172 | /* mode_clock is clock in kHz for mode to be modeset on this connector */ |
173 | mode_clock = amdgpu_connector->pixelclock_for_modeset; | 173 | mode_clock = amdgpu_connector->pixelclock_for_modeset; |
174 | 174 | ||
175 | /* Maximum allowable input clock in kHz */ | 175 | /* Maximum allowable input clock in kHz */ |
176 | max_tmds_clock = connector->max_tmds_clock * 1000; | 176 | max_tmds_clock = connector->display_info.max_tmds_clock; |
177 | 177 | ||
178 | DRM_DEBUG("%s: hdmi mode dotclock %d kHz, max tmds input clock %d kHz.\n", | 178 | DRM_DEBUG("%s: hdmi mode dotclock %d kHz, max tmds input clock %d kHz.\n", |
179 | connector->name, mode_clock, max_tmds_clock); | 179 | connector->name, mode_clock, max_tmds_clock); |
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 0f2e42310694..001b075e171b 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | |||
@@ -98,6 +98,14 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp) | |||
98 | return 0; | 98 | return 0; |
99 | } | 99 | } |
100 | 100 | ||
101 | int analogix_dp_psr_supported(struct device *dev) | ||
102 | { | ||
103 | struct analogix_dp_device *dp = dev_get_drvdata(dev); | ||
104 | |||
105 | return dp->psr_support; | ||
106 | } | ||
107 | EXPORT_SYMBOL_GPL(analogix_dp_psr_supported); | ||
108 | |||
101 | int analogix_dp_enable_psr(struct device *dev) | 109 | int analogix_dp_enable_psr(struct device *dev) |
102 | { | 110 | { |
103 | struct analogix_dp_device *dp = dev_get_drvdata(dev); | 111 | struct analogix_dp_device *dp = dev_get_drvdata(dev); |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 80c7f25b5b74..6efdba4993fc 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -89,7 +89,6 @@ void drm_dev_printk(const struct device *dev, const char *level, | |||
89 | EXPORT_SYMBOL(drm_dev_printk); | 89 | EXPORT_SYMBOL(drm_dev_printk); |
90 | 90 | ||
91 | void drm_printk(const char *level, unsigned int category, | 91 | void drm_printk(const char *level, unsigned int category, |
92 | const char *function_name, const char *prefix, | ||
93 | const char *format, ...) | 92 | const char *format, ...) |
94 | { | 93 | { |
95 | struct va_format vaf; | 94 | struct va_format vaf; |
@@ -102,7 +101,9 @@ void drm_printk(const char *level, unsigned int category, | |||
102 | vaf.fmt = format; | 101 | vaf.fmt = format; |
103 | vaf.va = &args; | 102 | vaf.va = &args; |
104 | 103 | ||
105 | printk("%s" DRM_PRINTK_FMT, level, function_name, prefix, &vaf); | 104 | printk("%s" "[" DRM_NAME ":%ps]%s %pV", |
105 | level, __builtin_return_address(0), | ||
106 | strcmp(level, KERN_ERR) == 0 ? " *ERROR*" : "", &vaf); | ||
106 | 107 | ||
107 | va_end(args); | 108 | va_end(args); |
108 | } | 109 | } |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 50541324a4ab..ec77bd3e1f08 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -3253,16 +3253,12 @@ static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode) | |||
3253 | } | 3253 | } |
3254 | 3254 | ||
3255 | static void | 3255 | static void |
3256 | parse_hdmi_vsdb(struct drm_connector *connector, const u8 *db) | 3256 | drm_parse_hdmi_vsdb_audio(struct drm_connector *connector, const u8 *db) |
3257 | { | 3257 | { |
3258 | u8 len = cea_db_payload_len(db); | 3258 | u8 len = cea_db_payload_len(db); |
3259 | 3259 | ||
3260 | if (len >= 6) { | 3260 | if (len >= 6) |
3261 | connector->eld[5] |= (db[6] >> 7) << 1; /* Supports_AI */ | 3261 | connector->eld[5] |= (db[6] >> 7) << 1; /* Supports_AI */ |
3262 | connector->dvi_dual = db[6] & 1; | ||
3263 | } | ||
3264 | if (len >= 7) | ||
3265 | connector->max_tmds_clock = db[7] * 5; | ||
3266 | if (len >= 8) { | 3262 | if (len >= 8) { |
3267 | connector->latency_present[0] = db[8] >> 7; | 3263 | connector->latency_present[0] = db[8] >> 7; |
3268 | connector->latency_present[1] = (db[8] >> 6) & 1; | 3264 | connector->latency_present[1] = (db[8] >> 6) & 1; |
@@ -3276,19 +3272,15 @@ parse_hdmi_vsdb(struct drm_connector *connector, const u8 *db) | |||
3276 | if (len >= 12) | 3272 | if (len >= 12) |
3277 | connector->audio_latency[1] = db[12]; | 3273 | connector->audio_latency[1] = db[12]; |
3278 | 3274 | ||
3279 | DRM_DEBUG_KMS("HDMI: DVI dual %d, " | 3275 | DRM_DEBUG_KMS("HDMI: latency present %d %d, " |
3280 | "max TMDS clock %d, " | 3276 | "video latency %d %d, " |
3281 | "latency present %d %d, " | 3277 | "audio latency %d %d\n", |
3282 | "video latency %d %d, " | 3278 | connector->latency_present[0], |
3283 | "audio latency %d %d\n", | 3279 | connector->latency_present[1], |
3284 | connector->dvi_dual, | 3280 | connector->video_latency[0], |
3285 | connector->max_tmds_clock, | 3281 | connector->video_latency[1], |
3286 | (int) connector->latency_present[0], | 3282 | connector->audio_latency[0], |
3287 | (int) connector->latency_present[1], | 3283 | connector->audio_latency[1]); |
3288 | connector->video_latency[0], | ||
3289 | connector->video_latency[1], | ||
3290 | connector->audio_latency[0], | ||
3291 | connector->audio_latency[1]); | ||
3292 | } | 3284 | } |
3293 | 3285 | ||
3294 | static void | 3286 | static void |
@@ -3358,6 +3350,13 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) | |||
3358 | 3350 | ||
3359 | memset(eld, 0, sizeof(connector->eld)); | 3351 | memset(eld, 0, sizeof(connector->eld)); |
3360 | 3352 | ||
3353 | connector->latency_present[0] = false; | ||
3354 | connector->latency_present[1] = false; | ||
3355 | connector->video_latency[0] = 0; | ||
3356 | connector->audio_latency[0] = 0; | ||
3357 | connector->video_latency[1] = 0; | ||
3358 | connector->audio_latency[1] = 0; | ||
3359 | |||
3361 | cea = drm_find_cea_extension(edid); | 3360 | cea = drm_find_cea_extension(edid); |
3362 | if (!cea) { | 3361 | if (!cea) { |
3363 | DRM_DEBUG_KMS("ELD: no CEA Extension found\n"); | 3362 | DRM_DEBUG_KMS("ELD: no CEA Extension found\n"); |
@@ -3407,7 +3406,7 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) | |||
3407 | case VENDOR_BLOCK: | 3406 | case VENDOR_BLOCK: |
3408 | /* HDMI Vendor-Specific Data Block */ | 3407 | /* HDMI Vendor-Specific Data Block */ |
3409 | if (cea_db_is_hdmi_vsdb(db)) | 3408 | if (cea_db_is_hdmi_vsdb(db)) |
3410 | parse_hdmi_vsdb(connector, db); | 3409 | drm_parse_hdmi_vsdb_audio(connector, db); |
3411 | break; | 3410 | break; |
3412 | default: | 3411 | default: |
3413 | break; | 3412 | break; |
@@ -3721,105 +3720,127 @@ bool drm_rgb_quant_range_selectable(struct edid *edid) | |||
3721 | } | 3720 | } |
3722 | EXPORT_SYMBOL(drm_rgb_quant_range_selectable); | 3721 | EXPORT_SYMBOL(drm_rgb_quant_range_selectable); |
3723 | 3722 | ||
3724 | /* | 3723 | static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector, |
3725 | * Parse the CEA extension according to CEA-861-B. | 3724 | const u8 *hdmi) |
3726 | * Return true if HDMI deep color supported, false if not or unknown. | ||
3727 | */ | ||
3728 | static bool drm_assign_hdmi_deep_color_info(struct edid *edid, | ||
3729 | struct drm_display_info *info, | ||
3730 | struct drm_connector *connector) | ||
3731 | { | 3725 | { |
3732 | u8 *edid_ext, *hdmi; | 3726 | struct drm_display_info *info = &connector->display_info; |
3733 | int i; | ||
3734 | int start_offset, end_offset; | ||
3735 | unsigned int dc_bpc = 0; | 3727 | unsigned int dc_bpc = 0; |
3736 | 3728 | ||
3737 | edid_ext = drm_find_cea_extension(edid); | 3729 | /* HDMI supports at least 8 bpc */ |
3738 | if (!edid_ext) | 3730 | info->bpc = 8; |
3739 | return false; | ||
3740 | 3731 | ||
3741 | if (cea_db_offsets(edid_ext, &start_offset, &end_offset)) | 3732 | if (cea_db_payload_len(hdmi) < 6) |
3742 | return false; | 3733 | return; |
3734 | |||
3735 | if (hdmi[6] & DRM_EDID_HDMI_DC_30) { | ||
3736 | dc_bpc = 10; | ||
3737 | info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_30; | ||
3738 | DRM_DEBUG("%s: HDMI sink does deep color 30.\n", | ||
3739 | connector->name); | ||
3740 | } | ||
3741 | |||
3742 | if (hdmi[6] & DRM_EDID_HDMI_DC_36) { | ||
3743 | dc_bpc = 12; | ||
3744 | info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_36; | ||
3745 | DRM_DEBUG("%s: HDMI sink does deep color 36.\n", | ||
3746 | connector->name); | ||
3747 | } | ||
3748 | |||
3749 | if (hdmi[6] & DRM_EDID_HDMI_DC_48) { | ||
3750 | dc_bpc = 16; | ||
3751 | info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_48; | ||
3752 | DRM_DEBUG("%s: HDMI sink does deep color 48.\n", | ||
3753 | connector->name); | ||
3754 | } | ||
3755 | |||
3756 | if (dc_bpc == 0) { | ||
3757 | DRM_DEBUG("%s: No deep color support on this HDMI sink.\n", | ||
3758 | connector->name); | ||
3759 | return; | ||
3760 | } | ||
3761 | |||
3762 | DRM_DEBUG("%s: Assigning HDMI sink color depth as %d bpc.\n", | ||
3763 | connector->name, dc_bpc); | ||
3764 | info->bpc = dc_bpc; | ||
3743 | 3765 | ||
3744 | /* | 3766 | /* |
3745 | * Because HDMI identifier is in Vendor Specific Block, | 3767 | * Deep color support mandates RGB444 support for all video |
3746 | * search it from all data blocks of CEA extension. | 3768 | * modes and forbids YCRCB422 support for all video modes per |
3769 | * HDMI 1.3 spec. | ||
3747 | */ | 3770 | */ |
3748 | for_each_cea_db(edid_ext, i, start_offset, end_offset) { | 3771 | info->color_formats = DRM_COLOR_FORMAT_RGB444; |
3749 | if (cea_db_is_hdmi_vsdb(&edid_ext[i])) { | ||
3750 | /* HDMI supports at least 8 bpc */ | ||
3751 | info->bpc = 8; | ||
3752 | |||
3753 | hdmi = &edid_ext[i]; | ||
3754 | if (cea_db_payload_len(hdmi) < 6) | ||
3755 | return false; | ||
3756 | |||
3757 | if (hdmi[6] & DRM_EDID_HDMI_DC_30) { | ||
3758 | dc_bpc = 10; | ||
3759 | info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_30; | ||
3760 | DRM_DEBUG("%s: HDMI sink does deep color 30.\n", | ||
3761 | connector->name); | ||
3762 | } | ||
3763 | 3772 | ||
3764 | if (hdmi[6] & DRM_EDID_HDMI_DC_36) { | 3773 | /* YCRCB444 is optional according to spec. */ |
3765 | dc_bpc = 12; | 3774 | if (hdmi[6] & DRM_EDID_HDMI_DC_Y444) { |
3766 | info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_36; | 3775 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; |
3767 | DRM_DEBUG("%s: HDMI sink does deep color 36.\n", | 3776 | DRM_DEBUG("%s: HDMI sink does YCRCB444 in deep color.\n", |
3768 | connector->name); | 3777 | connector->name); |
3769 | } | 3778 | } |
3770 | 3779 | ||
3771 | if (hdmi[6] & DRM_EDID_HDMI_DC_48) { | 3780 | /* |
3772 | dc_bpc = 16; | 3781 | * Spec says that if any deep color mode is supported at all, |
3773 | info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_48; | 3782 | * then deep color 36 bit must be supported. |
3774 | DRM_DEBUG("%s: HDMI sink does deep color 48.\n", | 3783 | */ |
3775 | connector->name); | 3784 | if (!(hdmi[6] & DRM_EDID_HDMI_DC_36)) { |
3776 | } | 3785 | DRM_DEBUG("%s: HDMI sink should do DC_36, but does not!\n", |
3786 | connector->name); | ||
3787 | } | ||
3788 | } | ||
3777 | 3789 | ||
3778 | if (dc_bpc > 0) { | 3790 | static void |
3779 | DRM_DEBUG("%s: Assigning HDMI sink color depth as %d bpc.\n", | 3791 | drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db) |
3780 | connector->name, dc_bpc); | 3792 | { |
3781 | info->bpc = dc_bpc; | 3793 | struct drm_display_info *info = &connector->display_info; |
3782 | 3794 | u8 len = cea_db_payload_len(db); | |
3783 | /* | ||
3784 | * Deep color support mandates RGB444 support for all video | ||
3785 | * modes and forbids YCRCB422 support for all video modes per | ||
3786 | * HDMI 1.3 spec. | ||
3787 | */ | ||
3788 | info->color_formats = DRM_COLOR_FORMAT_RGB444; | ||
3789 | |||
3790 | /* YCRCB444 is optional according to spec. */ | ||
3791 | if (hdmi[6] & DRM_EDID_HDMI_DC_Y444) { | ||
3792 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; | ||
3793 | DRM_DEBUG("%s: HDMI sink does YCRCB444 in deep color.\n", | ||
3794 | connector->name); | ||
3795 | } | ||
3796 | 3795 | ||
3797 | /* | 3796 | if (len >= 6) |
3798 | * Spec says that if any deep color mode is supported at all, | 3797 | info->dvi_dual = db[6] & 1; |
3799 | * then deep color 36 bit must be supported. | 3798 | if (len >= 7) |
3800 | */ | 3799 | info->max_tmds_clock = db[7] * 5000; |
3801 | if (!(hdmi[6] & DRM_EDID_HDMI_DC_36)) { | ||
3802 | DRM_DEBUG("%s: HDMI sink should do DC_36, but does not!\n", | ||
3803 | connector->name); | ||
3804 | } | ||
3805 | 3800 | ||
3806 | return true; | 3801 | DRM_DEBUG_KMS("HDMI: DVI dual %d, " |
3807 | } | 3802 | "max TMDS clock %d kHz\n", |
3808 | else { | 3803 | info->dvi_dual, |
3809 | DRM_DEBUG("%s: No deep color support on this HDMI sink.\n", | 3804 | info->max_tmds_clock); |
3810 | connector->name); | ||
3811 | } | ||
3812 | } | ||
3813 | } | ||
3814 | 3805 | ||
3815 | return false; | 3806 | drm_parse_hdmi_deep_color_info(connector, db); |
3816 | } | 3807 | } |
3817 | 3808 | ||
3818 | static void drm_add_display_info(struct edid *edid, | 3809 | static void drm_parse_cea_ext(struct drm_connector *connector, |
3819 | struct drm_display_info *info, | 3810 | struct edid *edid) |
3820 | struct drm_connector *connector) | ||
3821 | { | 3811 | { |
3822 | u8 *edid_ext; | 3812 | struct drm_display_info *info = &connector->display_info; |
3813 | const u8 *edid_ext; | ||
3814 | int i, start, end; | ||
3815 | |||
3816 | edid_ext = drm_find_cea_extension(edid); | ||
3817 | if (!edid_ext) | ||
3818 | return; | ||
3819 | |||
3820 | info->cea_rev = edid_ext[1]; | ||
3821 | |||
3822 | /* The existence of a CEA block should imply RGB support */ | ||
3823 | info->color_formats = DRM_COLOR_FORMAT_RGB444; | ||
3824 | if (edid_ext[3] & EDID_CEA_YCRCB444) | ||
3825 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; | ||
3826 | if (edid_ext[3] & EDID_CEA_YCRCB422) | ||
3827 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; | ||
3828 | |||
3829 | if (cea_db_offsets(edid_ext, &start, &end)) | ||
3830 | return; | ||
3831 | |||
3832 | for_each_cea_db(edid_ext, i, start, end) { | ||
3833 | const u8 *db = &edid_ext[i]; | ||
3834 | |||
3835 | if (cea_db_is_hdmi_vsdb(db)) | ||
3836 | drm_parse_hdmi_vsdb_video(connector, db); | ||
3837 | } | ||
3838 | } | ||
3839 | |||
3840 | static void drm_add_display_info(struct drm_connector *connector, | ||
3841 | struct edid *edid) | ||
3842 | { | ||
3843 | struct drm_display_info *info = &connector->display_info; | ||
3823 | 3844 | ||
3824 | info->width_mm = edid->width_cm * 10; | 3845 | info->width_mm = edid->width_cm * 10; |
3825 | info->height_mm = edid->height_cm * 10; | 3846 | info->height_mm = edid->height_cm * 10; |
@@ -3827,6 +3848,9 @@ static void drm_add_display_info(struct edid *edid, | |||
3827 | /* driver figures it out in this case */ | 3848 | /* driver figures it out in this case */ |
3828 | info->bpc = 0; | 3849 | info->bpc = 0; |
3829 | info->color_formats = 0; | 3850 | info->color_formats = 0; |
3851 | info->cea_rev = 0; | ||
3852 | info->max_tmds_clock = 0; | ||
3853 | info->dvi_dual = false; | ||
3830 | 3854 | ||
3831 | if (edid->revision < 3) | 3855 | if (edid->revision < 3) |
3832 | return; | 3856 | return; |
@@ -3834,21 +3858,7 @@ static void drm_add_display_info(struct edid *edid, | |||
3834 | if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) | 3858 | if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) |
3835 | return; | 3859 | return; |
3836 | 3860 | ||
3837 | /* Get data from CEA blocks if present */ | 3861 | drm_parse_cea_ext(connector, edid); |
3838 | edid_ext = drm_find_cea_extension(edid); | ||
3839 | if (edid_ext) { | ||
3840 | info->cea_rev = edid_ext[1]; | ||
3841 | |||
3842 | /* The existence of a CEA block should imply RGB support */ | ||
3843 | info->color_formats = DRM_COLOR_FORMAT_RGB444; | ||
3844 | if (edid_ext[3] & EDID_CEA_YCRCB444) | ||
3845 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; | ||
3846 | if (edid_ext[3] & EDID_CEA_YCRCB422) | ||
3847 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; | ||
3848 | } | ||
3849 | |||
3850 | /* HDMI deep color modes supported? Assign to info, if so */ | ||
3851 | drm_assign_hdmi_deep_color_info(edid, info, connector); | ||
3852 | 3862 | ||
3853 | /* | 3863 | /* |
3854 | * Digital sink with "DFP 1.x compliant TMDS" according to EDID 1.3? | 3864 | * Digital sink with "DFP 1.x compliant TMDS" according to EDID 1.3? |
@@ -4084,7 +4094,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) | |||
4084 | if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) | 4094 | if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) |
4085 | edid_fixup_preferred(connector, quirks); | 4095 | edid_fixup_preferred(connector, quirks); |
4086 | 4096 | ||
4087 | drm_add_display_info(edid, &connector->display_info, connector); | 4097 | drm_add_display_info(connector, edid); |
4088 | 4098 | ||
4089 | if (quirks & EDID_QUIRK_FORCE_6BPC) | 4099 | if (quirks & EDID_QUIRK_FORCE_6BPC) |
4090 | connector->display_info.bpc = 6; | 4100 | connector->display_info.bpc = 6; |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 404a1ce7730c..b969a64a1514 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -1008,6 +1008,31 @@ static void send_vblank_event(struct drm_device *dev, | |||
1008 | * period. This helper function implements exactly the required vblank arming | 1008 | * period. This helper function implements exactly the required vblank arming |
1009 | * behaviour. | 1009 | * behaviour. |
1010 | * | 1010 | * |
1011 | * NOTE: Drivers using this to send out the event in struct &drm_crtc_state | ||
1012 | * as part of an atomic commit must ensure that the next vblank happens at | ||
1013 | * exactly the same time as the atomic commit is committed to the hardware. This | ||
1014 | * function itself does **not** protect again the next vblank interrupt racing | ||
1015 | * with either this function call or the atomic commit operation. A possible | ||
1016 | * sequence could be: | ||
1017 | * | ||
1018 | * 1. Driver commits new hardware state into vblank-synchronized registers. | ||
1019 | * 2. A vblank happens, committing the hardware state. Also the corresponding | ||
1020 | * vblank interrupt is fired off and fully processed by the interrupt | ||
1021 | * handler. | ||
1022 | * 3. The atomic commit operation proceeds to call drm_crtc_arm_vblank_event(). | ||
1023 | * 4. The event is only send out for the next vblank, which is wrong. | ||
1024 | * | ||
1025 | * An equivalent race can happen when the driver calls | ||
1026 | * drm_crtc_arm_vblank_event() before writing out the new hardware state. | ||
1027 | * | ||
1028 | * The only way to make this work safely is to prevent the vblank from firing | ||
1029 | * (and the hardware from committing anything else) until the entire atomic | ||
1030 | * commit sequence has run to completion. If the hardware does not have such a | ||
1031 | * feature (e.g. using a "go" bit), then it is unsafe to use this functions. | ||
1032 | * Instead drivers need to manually send out the event from their interrupt | ||
1033 | * handler by calling drm_crtc_send_vblank_event() and make sure that there's no | ||
1034 | * possible race with the hardware committing the atomic update. | ||
1035 | * | ||
1011 | * Caller must hold event lock. Caller must also hold a vblank reference for | 1036 | * Caller must hold event lock. Caller must also hold a vblank reference for |
1012 | * the event @e, which will be dropped when the next vblank arrives. | 1037 | * the event @e, which will be dropped when the next vblank arrives. |
1013 | */ | 1038 | */ |
@@ -1030,8 +1055,11 @@ EXPORT_SYMBOL(drm_crtc_arm_vblank_event); | |||
1030 | * @crtc: the source CRTC of the vblank event | 1055 | * @crtc: the source CRTC of the vblank event |
1031 | * @e: the event to send | 1056 | * @e: the event to send |
1032 | * | 1057 | * |
1033 | * Updates sequence # and timestamp on event, and sends it to userspace. | 1058 | * Updates sequence # and timestamp on event for the most recently processed |
1034 | * Caller must hold event lock. | 1059 | * vblank, and sends it to userspace. Caller must hold event lock. |
1060 | * | ||
1061 | * See drm_crtc_arm_vblank_event() for a helper which can be used in certain | ||
1062 | * situation, especially to send out events for atomic commit operations. | ||
1035 | */ | 1063 | */ |
1036 | void drm_crtc_send_vblank_event(struct drm_crtc *crtc, | 1064 | void drm_crtc_send_vblank_event(struct drm_crtc *crtc, |
1037 | struct drm_pending_vblank_event *e) | 1065 | struct drm_pending_vblank_event *e) |
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 780589b420a4..57201d68cf61 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include <linux/export.h> | 29 | #include <linux/export.h> |
30 | #include <linux/dma-buf.h> | 30 | #include <linux/dma-buf.h> |
31 | #include <linux/rbtree.h> | ||
31 | #include <drm/drmP.h> | 32 | #include <drm/drmP.h> |
32 | #include <drm/drm_gem.h> | 33 | #include <drm/drm_gem.h> |
33 | 34 | ||
@@ -61,9 +62,11 @@ | |||
61 | */ | 62 | */ |
62 | 63 | ||
63 | struct drm_prime_member { | 64 | struct drm_prime_member { |
64 | struct list_head entry; | ||
65 | struct dma_buf *dma_buf; | 65 | struct dma_buf *dma_buf; |
66 | uint32_t handle; | 66 | uint32_t handle; |
67 | |||
68 | struct rb_node dmabuf_rb; | ||
69 | struct rb_node handle_rb; | ||
67 | }; | 70 | }; |
68 | 71 | ||
69 | struct drm_prime_attachment { | 72 | struct drm_prime_attachment { |
@@ -75,6 +78,7 @@ static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, | |||
75 | struct dma_buf *dma_buf, uint32_t handle) | 78 | struct dma_buf *dma_buf, uint32_t handle) |
76 | { | 79 | { |
77 | struct drm_prime_member *member; | 80 | struct drm_prime_member *member; |
81 | struct rb_node **p, *rb; | ||
78 | 82 | ||
79 | member = kmalloc(sizeof(*member), GFP_KERNEL); | 83 | member = kmalloc(sizeof(*member), GFP_KERNEL); |
80 | if (!member) | 84 | if (!member) |
@@ -83,18 +87,56 @@ static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, | |||
83 | get_dma_buf(dma_buf); | 87 | get_dma_buf(dma_buf); |
84 | member->dma_buf = dma_buf; | 88 | member->dma_buf = dma_buf; |
85 | member->handle = handle; | 89 | member->handle = handle; |
86 | list_add(&member->entry, &prime_fpriv->head); | 90 | |
91 | rb = NULL; | ||
92 | p = &prime_fpriv->dmabufs.rb_node; | ||
93 | while (*p) { | ||
94 | struct drm_prime_member *pos; | ||
95 | |||
96 | rb = *p; | ||
97 | pos = rb_entry(rb, struct drm_prime_member, dmabuf_rb); | ||
98 | if (dma_buf > pos->dma_buf) | ||
99 | p = &rb->rb_right; | ||
100 | else | ||
101 | p = &rb->rb_left; | ||
102 | } | ||
103 | rb_link_node(&member->dmabuf_rb, rb, p); | ||
104 | rb_insert_color(&member->dmabuf_rb, &prime_fpriv->dmabufs); | ||
105 | |||
106 | rb = NULL; | ||
107 | p = &prime_fpriv->handles.rb_node; | ||
108 | while (*p) { | ||
109 | struct drm_prime_member *pos; | ||
110 | |||
111 | rb = *p; | ||
112 | pos = rb_entry(rb, struct drm_prime_member, handle_rb); | ||
113 | if (handle > pos->handle) | ||
114 | p = &rb->rb_right; | ||
115 | else | ||
116 | p = &rb->rb_left; | ||
117 | } | ||
118 | rb_link_node(&member->handle_rb, rb, p); | ||
119 | rb_insert_color(&member->handle_rb, &prime_fpriv->handles); | ||
120 | |||
87 | return 0; | 121 | return 0; |
88 | } | 122 | } |
89 | 123 | ||
90 | static struct dma_buf *drm_prime_lookup_buf_by_handle(struct drm_prime_file_private *prime_fpriv, | 124 | static struct dma_buf *drm_prime_lookup_buf_by_handle(struct drm_prime_file_private *prime_fpriv, |
91 | uint32_t handle) | 125 | uint32_t handle) |
92 | { | 126 | { |
93 | struct drm_prime_member *member; | 127 | struct rb_node *rb; |
128 | |||
129 | rb = prime_fpriv->handles.rb_node; | ||
130 | while (rb) { | ||
131 | struct drm_prime_member *member; | ||
94 | 132 | ||
95 | list_for_each_entry(member, &prime_fpriv->head, entry) { | 133 | member = rb_entry(rb, struct drm_prime_member, handle_rb); |
96 | if (member->handle == handle) | 134 | if (member->handle == handle) |
97 | return member->dma_buf; | 135 | return member->dma_buf; |
136 | else if (member->handle < handle) | ||
137 | rb = rb->rb_right; | ||
138 | else | ||
139 | rb = rb->rb_left; | ||
98 | } | 140 | } |
99 | 141 | ||
100 | return NULL; | 142 | return NULL; |
@@ -104,14 +146,23 @@ static int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpri | |||
104 | struct dma_buf *dma_buf, | 146 | struct dma_buf *dma_buf, |
105 | uint32_t *handle) | 147 | uint32_t *handle) |
106 | { | 148 | { |
107 | struct drm_prime_member *member; | 149 | struct rb_node *rb; |
150 | |||
151 | rb = prime_fpriv->dmabufs.rb_node; | ||
152 | while (rb) { | ||
153 | struct drm_prime_member *member; | ||
108 | 154 | ||
109 | list_for_each_entry(member, &prime_fpriv->head, entry) { | 155 | member = rb_entry(rb, struct drm_prime_member, dmabuf_rb); |
110 | if (member->dma_buf == dma_buf) { | 156 | if (member->dma_buf == dma_buf) { |
111 | *handle = member->handle; | 157 | *handle = member->handle; |
112 | return 0; | 158 | return 0; |
159 | } else if (member->dma_buf < dma_buf) { | ||
160 | rb = rb->rb_right; | ||
161 | } else { | ||
162 | rb = rb->rb_left; | ||
113 | } | 163 | } |
114 | } | 164 | } |
165 | |||
115 | return -ENOENT; | 166 | return -ENOENT; |
116 | } | 167 | } |
117 | 168 | ||
@@ -166,13 +217,24 @@ static void drm_gem_map_detach(struct dma_buf *dma_buf, | |||
166 | void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv, | 217 | void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv, |
167 | struct dma_buf *dma_buf) | 218 | struct dma_buf *dma_buf) |
168 | { | 219 | { |
169 | struct drm_prime_member *member, *safe; | 220 | struct rb_node *rb; |
170 | 221 | ||
171 | list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) { | 222 | rb = prime_fpriv->dmabufs.rb_node; |
223 | while (rb) { | ||
224 | struct drm_prime_member *member; | ||
225 | |||
226 | member = rb_entry(rb, struct drm_prime_member, dmabuf_rb); | ||
172 | if (member->dma_buf == dma_buf) { | 227 | if (member->dma_buf == dma_buf) { |
228 | rb_erase(&member->handle_rb, &prime_fpriv->handles); | ||
229 | rb_erase(&member->dmabuf_rb, &prime_fpriv->dmabufs); | ||
230 | |||
173 | dma_buf_put(dma_buf); | 231 | dma_buf_put(dma_buf); |
174 | list_del(&member->entry); | ||
175 | kfree(member); | 232 | kfree(member); |
233 | return; | ||
234 | } else if (member->dma_buf < dma_buf) { | ||
235 | rb = rb->rb_right; | ||
236 | } else { | ||
237 | rb = rb->rb_left; | ||
176 | } | 238 | } |
177 | } | 239 | } |
178 | } | 240 | } |
@@ -759,12 +821,13 @@ EXPORT_SYMBOL(drm_prime_gem_destroy); | |||
759 | 821 | ||
760 | void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv) | 822 | void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv) |
761 | { | 823 | { |
762 | INIT_LIST_HEAD(&prime_fpriv->head); | ||
763 | mutex_init(&prime_fpriv->lock); | 824 | mutex_init(&prime_fpriv->lock); |
825 | prime_fpriv->dmabufs = RB_ROOT; | ||
826 | prime_fpriv->handles = RB_ROOT; | ||
764 | } | 827 | } |
765 | 828 | ||
766 | void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv) | 829 | void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv) |
767 | { | 830 | { |
768 | /* by now drm_gem_release should've made sure the list is empty */ | 831 | /* by now drm_gem_release should've made sure the list is empty */ |
769 | WARN_ON(!list_empty(&prime_fpriv->head)); | 832 | WARN_ON(!RB_EMPTY_ROOT(&prime_fpriv->dmabufs)); |
770 | } | 833 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8d4c35d55b1b..ad8d712ae84c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -12654,22 +12654,22 @@ static void | |||
12654 | connected_sink_compute_bpp(struct intel_connector *connector, | 12654 | connected_sink_compute_bpp(struct intel_connector *connector, |
12655 | struct intel_crtc_state *pipe_config) | 12655 | struct intel_crtc_state *pipe_config) |
12656 | { | 12656 | { |
12657 | const struct drm_display_info *info = &connector->base.display_info; | ||
12657 | int bpp = pipe_config->pipe_bpp; | 12658 | int bpp = pipe_config->pipe_bpp; |
12658 | 12659 | ||
12659 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] checking for sink bpp constrains\n", | 12660 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] checking for sink bpp constrains\n", |
12660 | connector->base.base.id, | 12661 | connector->base.base.id, |
12661 | connector->base.name); | 12662 | connector->base.name); |
12662 | 12663 | ||
12663 | /* Don't use an invalid EDID bpc value */ | 12664 | /* Don't use an invalid EDID bpc value */ |
12664 | if (connector->base.display_info.bpc && | 12665 | if (info->bpc != 0 && info->bpc * 3 < bpp) { |
12665 | connector->base.display_info.bpc * 3 < bpp) { | ||
12666 | DRM_DEBUG_KMS("clamping display bpp (was %d) to EDID reported max of %d\n", | 12666 | DRM_DEBUG_KMS("clamping display bpp (was %d) to EDID reported max of %d\n", |
12667 | bpp, connector->base.display_info.bpc*3); | 12667 | bpp, info->bpc * 3); |
12668 | pipe_config->pipe_bpp = connector->base.display_info.bpc*3; | 12668 | pipe_config->pipe_bpp = info->bpc * 3; |
12669 | } | 12669 | } |
12670 | 12670 | ||
12671 | /* Clamp bpp to 8 on screens without EDID 1.4 */ | 12671 | /* Clamp bpp to 8 on screens without EDID 1.4 */ |
12672 | if (connector->base.display_info.bpc == 0 && bpp > 24) { | 12672 | if (info->bpc == 0 && bpp > 24) { |
12673 | DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of 24\n", | 12673 | DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of 24\n", |
12674 | bpp); | 12674 | bpp); |
12675 | pipe_config->pipe_bpp = 24; | 12675 | pipe_config->pipe_bpp = 24; |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index c51073f78730..f40a35f2913a 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -1220,10 +1220,17 @@ static int hdmi_port_clock_limit(struct intel_hdmi *hdmi, | |||
1220 | int max_tmds_clock = intel_hdmi_source_max_tmds_clock(to_i915(dev)); | 1220 | int max_tmds_clock = intel_hdmi_source_max_tmds_clock(to_i915(dev)); |
1221 | 1221 | ||
1222 | if (respect_downstream_limits) { | 1222 | if (respect_downstream_limits) { |
1223 | struct intel_connector *connector = hdmi->attached_connector; | ||
1224 | const struct drm_display_info *info = &connector->base.display_info; | ||
1225 | |||
1223 | if (hdmi->dp_dual_mode.max_tmds_clock) | 1226 | if (hdmi->dp_dual_mode.max_tmds_clock) |
1224 | max_tmds_clock = min(max_tmds_clock, | 1227 | max_tmds_clock = min(max_tmds_clock, |
1225 | hdmi->dp_dual_mode.max_tmds_clock); | 1228 | hdmi->dp_dual_mode.max_tmds_clock); |
1226 | if (!hdmi->has_hdmi_sink) | 1229 | |
1230 | if (info->max_tmds_clock) | ||
1231 | max_tmds_clock = min(max_tmds_clock, | ||
1232 | info->max_tmds_clock); | ||
1233 | else if (!hdmi->has_hdmi_sink) | ||
1227 | max_tmds_clock = min(max_tmds_clock, 165000); | 1234 | max_tmds_clock = min(max_tmds_clock, 165000); |
1228 | } | 1235 | } |
1229 | 1236 | ||
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index 334562d06731..71227deef21b 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c | |||
@@ -1086,20 +1086,20 @@ static int mtk_hdmi_output_init(struct mtk_hdmi *hdmi) | |||
1086 | return 0; | 1086 | return 0; |
1087 | } | 1087 | } |
1088 | 1088 | ||
1089 | void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi) | 1089 | static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi) |
1090 | { | 1090 | { |
1091 | mtk_hdmi_aud_enable_packet(hdmi, true); | 1091 | mtk_hdmi_aud_enable_packet(hdmi, true); |
1092 | hdmi->audio_enable = true; | 1092 | hdmi->audio_enable = true; |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | void mtk_hdmi_audio_disable(struct mtk_hdmi *hdmi) | 1095 | static void mtk_hdmi_audio_disable(struct mtk_hdmi *hdmi) |
1096 | { | 1096 | { |
1097 | mtk_hdmi_aud_enable_packet(hdmi, false); | 1097 | mtk_hdmi_aud_enable_packet(hdmi, false); |
1098 | hdmi->audio_enable = false; | 1098 | hdmi->audio_enable = false; |
1099 | } | 1099 | } |
1100 | 1100 | ||
1101 | int mtk_hdmi_audio_set_param(struct mtk_hdmi *hdmi, | 1101 | static int mtk_hdmi_audio_set_param(struct mtk_hdmi *hdmi, |
1102 | struct hdmi_audio_param *param) | 1102 | struct hdmi_audio_param *param) |
1103 | { | 1103 | { |
1104 | if (!hdmi->audio_enable) { | 1104 | if (!hdmi->audio_enable) { |
1105 | dev_err(hdmi->dev, "hdmi audio is in disable state!\n"); | 1105 | dev_err(hdmi->dev, "hdmi audio is in disable state!\n"); |
@@ -1624,7 +1624,8 @@ static void mtk_hdmi_audio_shutdown(struct device *dev, void *data) | |||
1624 | mtk_hdmi_audio_disable(hdmi); | 1624 | mtk_hdmi_audio_disable(hdmi); |
1625 | } | 1625 | } |
1626 | 1626 | ||
1627 | int mtk_hdmi_audio_digital_mute(struct device *dev, void *data, bool enable) | 1627 | static int |
1628 | mtk_hdmi_audio_digital_mute(struct device *dev, void *data, bool enable) | ||
1628 | { | 1629 | { |
1629 | struct mtk_hdmi *hdmi = dev_get_drvdata(dev); | 1630 | struct mtk_hdmi *hdmi = dev_get_drvdata(dev); |
1630 | 1631 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index b79f3b002471..50e96d2c593d 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -198,12 +198,12 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) | |||
198 | } | 198 | } |
199 | 199 | ||
200 | /* Any defined maximum tmds clock limit we must not exceed? */ | 200 | /* Any defined maximum tmds clock limit we must not exceed? */ |
201 | if (connector->max_tmds_clock > 0) { | 201 | if (connector->display_info.max_tmds_clock > 0) { |
202 | /* mode_clock is clock in kHz for mode to be modeset on this connector */ | 202 | /* mode_clock is clock in kHz for mode to be modeset on this connector */ |
203 | mode_clock = radeon_connector->pixelclock_for_modeset; | 203 | mode_clock = radeon_connector->pixelclock_for_modeset; |
204 | 204 | ||
205 | /* Maximum allowable input clock in kHz */ | 205 | /* Maximum allowable input clock in kHz */ |
206 | max_tmds_clock = connector->max_tmds_clock * 1000; | 206 | max_tmds_clock = connector->display_info.max_tmds_clock; |
207 | 207 | ||
208 | DRM_DEBUG("%s: hdmi mode dotclock %d kHz, max tmds input clock %d kHz.\n", | 208 | DRM_DEBUG("%s: hdmi mode dotclock %d kHz, max tmds input clock %d kHz.\n", |
209 | connector->name, mode_clock, max_tmds_clock); | 209 | connector->name, mode_clock, max_tmds_clock); |
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index e83be157cc2a..8548e8271639 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | |||
@@ -85,6 +85,9 @@ static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled) | |||
85 | struct rockchip_dp_device *dp = to_dp(encoder); | 85 | struct rockchip_dp_device *dp = to_dp(encoder); |
86 | unsigned long flags; | 86 | unsigned long flags; |
87 | 87 | ||
88 | if (!analogix_dp_psr_supported(dp->dev)) | ||
89 | return; | ||
90 | |||
88 | dev_dbg(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit"); | 91 | dev_dbg(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit"); |
89 | 92 | ||
90 | spin_lock_irqsave(&dp->psr_lock, flags); | 93 | spin_lock_irqsave(&dp->psr_lock, flags); |
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 446b5d7e85f7..8c8cbe837e61 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c | |||
@@ -309,7 +309,7 @@ static struct drm_driver rockchip_drm_driver = { | |||
309 | }; | 309 | }; |
310 | 310 | ||
311 | #ifdef CONFIG_PM_SLEEP | 311 | #ifdef CONFIG_PM_SLEEP |
312 | void rockchip_drm_fb_suspend(struct drm_device *drm) | 312 | static void rockchip_drm_fb_suspend(struct drm_device *drm) |
313 | { | 313 | { |
314 | struct rockchip_drm_private *priv = drm->dev_private; | 314 | struct rockchip_drm_private *priv = drm->dev_private; |
315 | 315 | ||
@@ -318,7 +318,7 @@ void rockchip_drm_fb_suspend(struct drm_device *drm) | |||
318 | console_unlock(); | 318 | console_unlock(); |
319 | } | 319 | } |
320 | 320 | ||
321 | void rockchip_drm_fb_resume(struct drm_device *drm) | 321 | static void rockchip_drm_fb_resume(struct drm_device *drm) |
322 | { | 322 | { |
323 | struct rockchip_drm_private *priv = drm->dev_private; | 323 | struct rockchip_drm_private *priv = drm->dev_private; |
324 | 324 | ||
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c index 207e01de6e32..a16c69f96ed5 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include "rockchip_drm_drv.h" | 20 | #include "rockchip_drm_drv.h" |
21 | #include "rockchip_drm_gem.h" | 21 | #include "rockchip_drm_gem.h" |
22 | #include "rockchip_drm_fb.h" | 22 | #include "rockchip_drm_fb.h" |
23 | #include "rockchip_drm_fbdev.h" | ||
23 | 24 | ||
24 | #define PREFERRED_BPP 32 | 25 | #define PREFERRED_BPP 32 |
25 | #define to_drm_private(x) \ | 26 | #define to_drm_private(x) \ |
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index 9cd8838e1ec3..f6f0c062205c 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h | |||
@@ -38,6 +38,7 @@ struct analogix_dp_plat_data { | |||
38 | struct drm_connector *); | 38 | struct drm_connector *); |
39 | }; | 39 | }; |
40 | 40 | ||
41 | int analogix_dp_psr_supported(struct device *dev); | ||
41 | int analogix_dp_enable_psr(struct device *dev); | 42 | int analogix_dp_enable_psr(struct device *dev); |
42 | int analogix_dp_disable_psr(struct device *dev); | 43 | int analogix_dp_disable_psr(struct device *dev); |
43 | 44 | ||
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c53dc90942e0..0e99669159c1 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/platform_device.h> | 51 | #include <linux/platform_device.h> |
52 | #include <linux/poll.h> | 52 | #include <linux/poll.h> |
53 | #include <linux/ratelimit.h> | 53 | #include <linux/ratelimit.h> |
54 | #include <linux/rbtree.h> | ||
54 | #include <linux/sched.h> | 55 | #include <linux/sched.h> |
55 | #include <linux/slab.h> | 56 | #include <linux/slab.h> |
56 | #include <linux/types.h> | 57 | #include <linux/types.h> |
@@ -140,9 +141,8 @@ void drm_dev_printk(const struct device *dev, const char *level, | |||
140 | unsigned int category, const char *function_name, | 141 | unsigned int category, const char *function_name, |
141 | const char *prefix, const char *format, ...); | 142 | const char *prefix, const char *format, ...); |
142 | 143 | ||
143 | extern __printf(5, 6) | 144 | extern __printf(3, 4) |
144 | void drm_printk(const char *level, unsigned int category, | 145 | void drm_printk(const char *level, unsigned int category, |
145 | const char *function_name, const char *prefix, | ||
146 | const char *format, ...); | 146 | const char *format, ...); |
147 | 147 | ||
148 | /***********************************************************************/ | 148 | /***********************************************************************/ |
@@ -198,8 +198,7 @@ void drm_printk(const char *level, unsigned int category, | |||
198 | drm_dev_printk(dev, KERN_ERR, DRM_UT_NONE, __func__, " *ERROR*",\ | 198 | drm_dev_printk(dev, KERN_ERR, DRM_UT_NONE, __func__, " *ERROR*",\ |
199 | fmt, ##__VA_ARGS__) | 199 | fmt, ##__VA_ARGS__) |
200 | #define DRM_ERROR(fmt, ...) \ | 200 | #define DRM_ERROR(fmt, ...) \ |
201 | drm_printk(KERN_ERR, DRM_UT_NONE, __func__, " *ERROR*", fmt, \ | 201 | drm_printk(KERN_ERR, DRM_UT_NONE, fmt, ##__VA_ARGS__) |
202 | ##__VA_ARGS__) | ||
203 | 202 | ||
204 | /** | 203 | /** |
205 | * Rate limited error output. Like DRM_ERROR() but won't flood the log. | 204 | * Rate limited error output. Like DRM_ERROR() but won't flood the log. |
@@ -241,38 +240,38 @@ void drm_printk(const char *level, unsigned int category, | |||
241 | #define DRM_DEV_DEBUG(dev, fmt, args...) \ | 240 | #define DRM_DEV_DEBUG(dev, fmt, args...) \ |
242 | drm_dev_printk(dev, KERN_DEBUG, DRM_UT_CORE, __func__, "", fmt, \ | 241 | drm_dev_printk(dev, KERN_DEBUG, DRM_UT_CORE, __func__, "", fmt, \ |
243 | ##args) | 242 | ##args) |
244 | #define DRM_DEBUG(fmt, args...) \ | 243 | #define DRM_DEBUG(fmt, ...) \ |
245 | drm_printk(KERN_DEBUG, DRM_UT_CORE, __func__, "", fmt, ##args) | 244 | drm_printk(KERN_DEBUG, DRM_UT_CORE, fmt, ##__VA_ARGS__) |
246 | 245 | ||
247 | #define DRM_DEV_DEBUG_DRIVER(dev, fmt, args...) \ | 246 | #define DRM_DEV_DEBUG_DRIVER(dev, fmt, args...) \ |
248 | drm_dev_printk(dev, KERN_DEBUG, DRM_UT_DRIVER, __func__, "", \ | 247 | drm_dev_printk(dev, KERN_DEBUG, DRM_UT_DRIVER, __func__, "", \ |
249 | fmt, ##args) | 248 | fmt, ##args) |
250 | #define DRM_DEBUG_DRIVER(fmt, args...) \ | 249 | #define DRM_DEBUG_DRIVER(fmt, ...) \ |
251 | drm_printk(KERN_DEBUG, DRM_UT_DRIVER, __func__, "", fmt, ##args) | 250 | drm_printk(KERN_DEBUG, DRM_UT_DRIVER, fmt, ##__VA_ARGS__) |
252 | 251 | ||
253 | #define DRM_DEV_DEBUG_KMS(dev, fmt, args...) \ | 252 | #define DRM_DEV_DEBUG_KMS(dev, fmt, args...) \ |
254 | drm_dev_printk(dev, KERN_DEBUG, DRM_UT_KMS, __func__, "", fmt, \ | 253 | drm_dev_printk(dev, KERN_DEBUG, DRM_UT_KMS, __func__, "", fmt, \ |
255 | ##args) | 254 | ##args) |
256 | #define DRM_DEBUG_KMS(fmt, args...) \ | 255 | #define DRM_DEBUG_KMS(fmt, ...) \ |
257 | drm_printk(KERN_DEBUG, DRM_UT_KMS, __func__, "", fmt, ##args) | 256 | drm_printk(KERN_DEBUG, DRM_UT_KMS, fmt, ##__VA_ARGS__) |
258 | 257 | ||
259 | #define DRM_DEV_DEBUG_PRIME(dev, fmt, args...) \ | 258 | #define DRM_DEV_DEBUG_PRIME(dev, fmt, args...) \ |
260 | drm_dev_printk(dev, KERN_DEBUG, DRM_UT_PRIME, __func__, "", \ | 259 | drm_dev_printk(dev, KERN_DEBUG, DRM_UT_PRIME, __func__, "", \ |
261 | fmt, ##args) | 260 | fmt, ##args) |
262 | #define DRM_DEBUG_PRIME(fmt, args...) \ | 261 | #define DRM_DEBUG_PRIME(fmt, ...) \ |
263 | drm_printk(KERN_DEBUG, DRM_UT_PRIME, __func__, "", fmt, ##args) | 262 | drm_printk(KERN_DEBUG, DRM_UT_PRIME, fmt, ##__VA_ARGS__) |
264 | 263 | ||
265 | #define DRM_DEV_DEBUG_ATOMIC(dev, fmt, args...) \ | 264 | #define DRM_DEV_DEBUG_ATOMIC(dev, fmt, args...) \ |
266 | drm_dev_printk(dev, KERN_DEBUG, DRM_UT_ATOMIC, __func__, "", \ | 265 | drm_dev_printk(dev, KERN_DEBUG, DRM_UT_ATOMIC, __func__, "", \ |
267 | fmt, ##args) | 266 | fmt, ##args) |
268 | #define DRM_DEBUG_ATOMIC(fmt, args...) \ | 267 | #define DRM_DEBUG_ATOMIC(fmt, ...) \ |
269 | drm_printk(KERN_DEBUG, DRM_UT_ATOMIC, __func__, "", fmt, ##args) | 268 | drm_printk(KERN_DEBUG, DRM_UT_ATOMIC, fmt, ##__VA_ARGS__) |
270 | 269 | ||
271 | #define DRM_DEV_DEBUG_VBL(dev, fmt, args...) \ | 270 | #define DRM_DEV_DEBUG_VBL(dev, fmt, args...) \ |
272 | drm_dev_printk(dev, KERN_DEBUG, DRM_UT_VBL, __func__, "", fmt, \ | 271 | drm_dev_printk(dev, KERN_DEBUG, DRM_UT_VBL, __func__, "", fmt, \ |
273 | ##args) | 272 | ##args) |
274 | #define DRM_DEBUG_VBL(fmt, args...) \ | 273 | #define DRM_DEBUG_VBL(fmt, ...) \ |
275 | drm_printk(KERN_DEBUG, DRM_UT_VBL, __func__, "", fmt, ##args) | 274 | drm_printk(KERN_DEBUG, DRM_UT_VBL, fmt, ##__VA_ARGS__) |
276 | 275 | ||
277 | #define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, level, fmt, args...) \ | 276 | #define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, level, fmt, args...) \ |
278 | ({ \ | 277 | ({ \ |
@@ -371,10 +370,10 @@ struct drm_pending_event { | |||
371 | we deliver the event, for tracing only */ | 370 | we deliver the event, for tracing only */ |
372 | }; | 371 | }; |
373 | 372 | ||
374 | /* initial implementaton using a linked list - todo hashtab */ | ||
375 | struct drm_prime_file_private { | 373 | struct drm_prime_file_private { |
376 | struct list_head head; | ||
377 | struct mutex lock; | 374 | struct mutex lock; |
375 | struct rb_root dmabufs; | ||
376 | struct rb_root handles; | ||
378 | }; | 377 | }; |
379 | 378 | ||
380 | /** File private data */ | 379 | /** File private data */ |
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 51a15deda161..287a610f464e 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h | |||
@@ -167,6 +167,17 @@ struct drm_display_info { | |||
167 | u32 bus_flags; | 167 | u32 bus_flags; |
168 | 168 | ||
169 | /** | 169 | /** |
170 | * @max_tmds_clock: Maximum TMDS clock rate supported by the | ||
171 | * sink in kHz. 0 means undefined. | ||
172 | */ | ||
173 | int max_tmds_clock; | ||
174 | |||
175 | /** | ||
176 | * @dvi_dual: Dual-link DVI sink? | ||
177 | */ | ||
178 | bool dvi_dual; | ||
179 | |||
180 | /** | ||
170 | * @edid_hdmi_dc_modes: Mask of supported hdmi deep color modes. Even | 181 | * @edid_hdmi_dc_modes: Mask of supported hdmi deep color modes. Even |
171 | * more stuff redundant with @bus_formats. | 182 | * more stuff redundant with @bus_formats. |
172 | */ | 183 | */ |
@@ -515,8 +526,6 @@ struct drm_cmdline_mode { | |||
515 | * @encoder_ids: valid encoders for this connector | 526 | * @encoder_ids: valid encoders for this connector |
516 | * @encoder: encoder driving this connector, if any | 527 | * @encoder: encoder driving this connector, if any |
517 | * @eld: EDID-like data, if present | 528 | * @eld: EDID-like data, if present |
518 | * @dvi_dual: dual link DVI, if found | ||
519 | * @max_tmds_clock: max clock rate, if found | ||
520 | * @latency_present: AV delay info from ELD, if found | 529 | * @latency_present: AV delay info from ELD, if found |
521 | * @video_latency: video latency info from ELD, if found | 530 | * @video_latency: video latency info from ELD, if found |
522 | * @audio_latency: audio latency info from ELD, if found | 531 | * @audio_latency: audio latency info from ELD, if found |
@@ -650,8 +659,6 @@ struct drm_connector { | |||
650 | #define MAX_ELD_BYTES 128 | 659 | #define MAX_ELD_BYTES 128 |
651 | /* EDID bits */ | 660 | /* EDID bits */ |
652 | uint8_t eld[MAX_ELD_BYTES]; | 661 | uint8_t eld[MAX_ELD_BYTES]; |
653 | bool dvi_dual; | ||
654 | int max_tmds_clock; /* in MHz */ | ||
655 | bool latency_present[2]; | 662 | bool latency_present[2]; |
656 | int video_latency[2]; /* [0]: progressive, [1]: interlaced */ | 663 | int video_latency[2]; /* [0]: progressive, [1]: interlaced */ |
657 | int audio_latency[2]; | 664 | int audio_latency[2]; |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index a544b7502493..61932f55f788 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -109,8 +109,6 @@ struct drm_plane_helper_funcs; | |||
109 | * @ctm: Transformation matrix | 109 | * @ctm: Transformation matrix |
110 | * @gamma_lut: Lookup table for converting pixel data after the | 110 | * @gamma_lut: Lookup table for converting pixel data after the |
111 | * conversion matrix | 111 | * conversion matrix |
112 | * @event: optional pointer to a DRM event to signal upon completion of the | ||
113 | * state update | ||
114 | * @state: backpointer to global drm_atomic_state | 112 | * @state: backpointer to global drm_atomic_state |
115 | * | 113 | * |
116 | * Note that the distinction between @enable and @active is rather subtile: | 114 | * Note that the distinction between @enable and @active is rather subtile: |
@@ -159,6 +157,46 @@ struct drm_crtc_state { | |||
159 | struct drm_property_blob *ctm; | 157 | struct drm_property_blob *ctm; |
160 | struct drm_property_blob *gamma_lut; | 158 | struct drm_property_blob *gamma_lut; |
161 | 159 | ||
160 | /** | ||
161 | * @event: | ||
162 | * | ||
163 | * Optional pointer to a DRM event to signal upon completion of the | ||
164 | * state update. The driver must send out the event when the atomic | ||
165 | * commit operation completes. There are two cases: | ||
166 | * | ||
167 | * - The event is for a CRTC which is being disabled through this | ||
168 | * atomic commit. In that case the event can be send out any time | ||
169 | * after the hardware has stopped scanning out the current | ||
170 | * framebuffers. It should contain the timestamp and counter for the | ||
171 | * last vblank before the display pipeline was shut off. | ||
172 | * | ||
173 | * - For a CRTC which is enabled at the end of the commit (even when it | ||
174 | * undergoes an full modeset) the vblank timestamp and counter must | ||
175 | * be for the vblank right before the first frame that scans out the | ||
176 | * new set of buffers. Again the event can only be sent out after the | ||
177 | * hardware has stopped scanning out the old buffers. | ||
178 | * | ||
179 | * - Events for disabled CRTCs are not allowed, and drivers can ignore | ||
180 | * that case. | ||
181 | * | ||
182 | * This can be handled by the drm_crtc_send_vblank_event() function, | ||
183 | * which the driver should call on the provided event upon completion of | ||
184 | * the atomic commit. Note that if the driver supports vblank signalling | ||
185 | * and timestamping the vblank counters and timestamps must agree with | ||
186 | * the ones returned from page flip events. With the current vblank | ||
187 | * helper infrastructure this can be achieved by holding a vblank | ||
188 | * reference while the page flip is pending, acquired through | ||
189 | * drm_crtc_vblank_get() and released with drm_crtc_vblank_put(). | ||
190 | * Drivers are free to implement their own vblank counter and timestamp | ||
191 | * tracking though, e.g. if they have accurate timestamp registers in | ||
192 | * hardware. | ||
193 | * | ||
194 | * For hardware which supports some means to synchronize vblank | ||
195 | * interrupt delivery with committing display state there's also | ||
196 | * drm_crtc_arm_vblank_event(). See the documentation of that function | ||
197 | * for a detailed discussion of the constraints it needs to be used | ||
198 | * safely. | ||
199 | */ | ||
162 | struct drm_pending_vblank_event *event; | 200 | struct drm_pending_vblank_event *event; |
163 | 201 | ||
164 | struct drm_atomic_state *state; | 202 | struct drm_atomic_state *state; |
@@ -835,17 +873,9 @@ struct drm_mode_config_funcs { | |||
835 | * CRTC index supplied in &drm_event to userspace. | 873 | * CRTC index supplied in &drm_event to userspace. |
836 | * | 874 | * |
837 | * The drm core will supply a struct &drm_event in the event | 875 | * The drm core will supply a struct &drm_event in the event |
838 | * member of each CRTC's &drm_crtc_state structure. This can be handled by the | 876 | * member of each CRTC's &drm_crtc_state structure. See the |
839 | * drm_crtc_send_vblank_event() function, which the driver should call on | 877 | * documentation for &drm_crtc_state for more details about the precise |
840 | * the provided event upon completion of the atomic commit. Note that if | 878 | * semantics of this event. |
841 | * the driver supports vblank signalling and timestamping the vblank | ||
842 | * counters and timestamps must agree with the ones returned from page | ||
843 | * flip events. With the current vblank helper infrastructure this can | ||
844 | * be achieved by holding a vblank reference while the page flip is | ||
845 | * pending, acquired through drm_crtc_vblank_get() and released with | ||
846 | * drm_crtc_vblank_put(). Drivers are free to implement their own vblank | ||
847 | * counter and timestamp tracking though, e.g. if they have accurate | ||
848 | * timestamp registers in hardware. | ||
849 | * | 879 | * |
850 | * NOTE: | 880 | * NOTE: |
851 | * | 881 | * |
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index e19458dd1a43..3c5f5992b96a 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h | |||
@@ -217,6 +217,19 @@ struct drm_fb_helper { | |||
217 | bool delayed_hotplug; | 217 | bool delayed_hotplug; |
218 | }; | 218 | }; |
219 | 219 | ||
220 | /** | ||
221 | * @DRM_FB_HELPER_DEFAULT_OPS: | ||
222 | * | ||
223 | * Helper define to register default implementations of drm_fb_helper | ||
224 | * functions. To be used in struct fb_ops of drm drivers. | ||
225 | */ | ||
226 | #define DRM_FB_HELPER_DEFAULT_OPS \ | ||
227 | .fb_check_var = drm_fb_helper_check_var, \ | ||
228 | .fb_set_par = drm_fb_helper_set_par, \ | ||
229 | .fb_setcmap = drm_fb_helper_setcmap, \ | ||
230 | .fb_blank = drm_fb_helper_blank, \ | ||
231 | .fb_pan_display = drm_fb_helper_pan_display | ||
232 | |||
220 | #ifdef CONFIG_DRM_FBDEV_EMULATION | 233 | #ifdef CONFIG_DRM_FBDEV_EMULATION |
221 | void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, | 234 | void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, |
222 | const struct drm_fb_helper_funcs *funcs); | 235 | const struct drm_fb_helper_funcs *funcs); |
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 185f8ea2702f..407ca0d7a938 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild | |||
@@ -396,6 +396,7 @@ header-y += string.h | |||
396 | header-y += suspend_ioctls.h | 396 | header-y += suspend_ioctls.h |
397 | header-y += swab.h | 397 | header-y += swab.h |
398 | header-y += synclink.h | 398 | header-y += synclink.h |
399 | header-y += sync_file.h | ||
399 | header-y += sysctl.h | 400 | header-y += sysctl.h |
400 | header-y += sysinfo.h | 401 | header-y += sysinfo.h |
401 | header-y += target_core_user.h | 402 | header-y += target_core_user.h |