diff options
author | Ingo Molnar <mingo@kernel.org> | 2012-12-08 09:25:06 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-12-08 09:25:06 -0500 |
commit | f0b9abfb044649bc452fb2fb975ff2fd599cc6a3 (patch) | |
tree | 7800081c5cb16a4dfee1e57a70f3be90f7b50d9a /drivers/gpu/drm/i915/intel_sdvo.c | |
parent | adc1ef1e37358d3c17d1a74a58b2e104fc0bda15 (diff) | |
parent | 1b3c393cd43f22ead8a6a2f839efc6df8ebd7465 (diff) |
Merge branch 'linus' into perf/core
Conflicts:
tools/perf/Makefile
tools/perf/builtin-test.c
tools/perf/perf.h
tools/perf/tests/parse-events.c
tools/perf/util/evsel.h
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 101 |
1 files changed, 71 insertions, 30 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index c01d97db0061..a6ac0b416964 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -894,6 +894,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) | |||
894 | } | 894 | } |
895 | #endif | 895 | #endif |
896 | 896 | ||
897 | static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, | ||
898 | unsigned if_index, uint8_t tx_rate, | ||
899 | uint8_t *data, unsigned length) | ||
900 | { | ||
901 | uint8_t set_buf_index[2] = { if_index, 0 }; | ||
902 | uint8_t hbuf_size, tmp[8]; | ||
903 | int i; | ||
904 | |||
905 | if (!intel_sdvo_set_value(intel_sdvo, | ||
906 | SDVO_CMD_SET_HBUF_INDEX, | ||
907 | set_buf_index, 2)) | ||
908 | return false; | ||
909 | |||
910 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO, | ||
911 | &hbuf_size, 1)) | ||
912 | return false; | ||
913 | |||
914 | /* Buffer size is 0 based, hooray! */ | ||
915 | hbuf_size++; | ||
916 | |||
917 | DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n", | ||
918 | if_index, length, hbuf_size); | ||
919 | |||
920 | for (i = 0; i < hbuf_size; i += 8) { | ||
921 | memset(tmp, 0, 8); | ||
922 | if (i < length) | ||
923 | memcpy(tmp, data + i, min_t(unsigned, 8, length - i)); | ||
924 | |||
925 | if (!intel_sdvo_set_value(intel_sdvo, | ||
926 | SDVO_CMD_SET_HBUF_DATA, | ||
927 | tmp, 8)) | ||
928 | return false; | ||
929 | } | ||
930 | |||
931 | return intel_sdvo_set_value(intel_sdvo, | ||
932 | SDVO_CMD_SET_HBUF_TXRATE, | ||
933 | &tx_rate, 1); | ||
934 | } | ||
935 | |||
897 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) | 936 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) |
898 | { | 937 | { |
899 | struct dip_infoframe avi_if = { | 938 | struct dip_infoframe avi_if = { |
@@ -901,11 +940,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) | |||
901 | .ver = DIP_VERSION_AVI, | 940 | .ver = DIP_VERSION_AVI, |
902 | .len = DIP_LEN_AVI, | 941 | .len = DIP_LEN_AVI, |
903 | }; | 942 | }; |
904 | uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; | ||
905 | uint8_t set_buf_index[2] = { 1, 0 }; | ||
906 | uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; | 943 | uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; |
907 | uint64_t *data = (uint64_t *)sdvo_data; | ||
908 | unsigned i; | ||
909 | 944 | ||
910 | intel_dip_infoframe_csum(&avi_if); | 945 | intel_dip_infoframe_csum(&avi_if); |
911 | 946 | ||
@@ -915,22 +950,9 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) | |||
915 | sdvo_data[3] = avi_if.checksum; | 950 | sdvo_data[3] = avi_if.checksum; |
916 | memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); | 951 | memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); |
917 | 952 | ||
918 | if (!intel_sdvo_set_value(intel_sdvo, | 953 | return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, |
919 | SDVO_CMD_SET_HBUF_INDEX, | 954 | SDVO_HBUF_TX_VSYNC, |
920 | set_buf_index, 2)) | 955 | sdvo_data, sizeof(sdvo_data)); |
921 | return false; | ||
922 | |||
923 | for (i = 0; i < sizeof(sdvo_data); i += 8) { | ||
924 | if (!intel_sdvo_set_value(intel_sdvo, | ||
925 | SDVO_CMD_SET_HBUF_DATA, | ||
926 | data, 8)) | ||
927 | return false; | ||
928 | data++; | ||
929 | } | ||
930 | |||
931 | return intel_sdvo_set_value(intel_sdvo, | ||
932 | SDVO_CMD_SET_HBUF_TXRATE, | ||
933 | &tx_rate, 1); | ||
934 | } | 956 | } |
935 | 957 | ||
936 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) | 958 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) |
@@ -2179,7 +2201,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | |||
2179 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2201 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
2180 | intel_sdvo->is_hdmi = true; | 2202 | intel_sdvo->is_hdmi = true; |
2181 | } | 2203 | } |
2182 | intel_sdvo->base.cloneable = true; | ||
2183 | 2204 | ||
2184 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); | 2205 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2185 | if (intel_sdvo->is_hdmi) | 2206 | if (intel_sdvo->is_hdmi) |
@@ -2210,7 +2231,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) | |||
2210 | 2231 | ||
2211 | intel_sdvo->is_tv = true; | 2232 | intel_sdvo->is_tv = true; |
2212 | intel_sdvo->base.needs_tv_clock = true; | 2233 | intel_sdvo->base.needs_tv_clock = true; |
2213 | intel_sdvo->base.cloneable = false; | ||
2214 | 2234 | ||
2215 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); | 2235 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2216 | 2236 | ||
@@ -2253,8 +2273,6 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) | |||
2253 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; | 2273 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; |
2254 | } | 2274 | } |
2255 | 2275 | ||
2256 | intel_sdvo->base.cloneable = true; | ||
2257 | |||
2258 | intel_sdvo_connector_init(intel_sdvo_connector, | 2276 | intel_sdvo_connector_init(intel_sdvo_connector, |
2259 | intel_sdvo); | 2277 | intel_sdvo); |
2260 | return true; | 2278 | return true; |
@@ -2285,9 +2303,6 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) | |||
2285 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; | 2303 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; |
2286 | } | 2304 | } |
2287 | 2305 | ||
2288 | /* SDVO LVDS is not cloneable because the input mode gets adjusted by the encoder */ | ||
2289 | intel_sdvo->base.cloneable = false; | ||
2290 | |||
2291 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); | 2306 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2292 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) | 2307 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
2293 | goto err; | 2308 | goto err; |
@@ -2360,6 +2375,18 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) | |||
2360 | return true; | 2375 | return true; |
2361 | } | 2376 | } |
2362 | 2377 | ||
2378 | static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo) | ||
2379 | { | ||
2380 | struct drm_device *dev = intel_sdvo->base.base.dev; | ||
2381 | struct drm_connector *connector, *tmp; | ||
2382 | |||
2383 | list_for_each_entry_safe(connector, tmp, | ||
2384 | &dev->mode_config.connector_list, head) { | ||
2385 | if (intel_attached_encoder(connector) == &intel_sdvo->base) | ||
2386 | intel_sdvo_destroy(connector); | ||
2387 | } | ||
2388 | } | ||
2389 | |||
2363 | static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, | 2390 | static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
2364 | struct intel_sdvo_connector *intel_sdvo_connector, | 2391 | struct intel_sdvo_connector *intel_sdvo_connector, |
2365 | int type) | 2392 | int type) |
@@ -2683,9 +2710,20 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2683 | intel_sdvo->caps.output_flags) != true) { | 2710 | intel_sdvo->caps.output_flags) != true) { |
2684 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", | 2711 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", |
2685 | SDVO_NAME(intel_sdvo)); | 2712 | SDVO_NAME(intel_sdvo)); |
2686 | goto err; | 2713 | /* Output_setup can leave behind connectors! */ |
2714 | goto err_output; | ||
2687 | } | 2715 | } |
2688 | 2716 | ||
2717 | /* | ||
2718 | * Cloning SDVO with anything is often impossible, since the SDVO | ||
2719 | * encoder can request a special input timing mode. And even if that's | ||
2720 | * not the case we have evidence that cloning a plain unscaled mode with | ||
2721 | * VGA doesn't really work. Furthermore the cloning flags are way too | ||
2722 | * simplistic anyway to express such constraints, so just give up on | ||
2723 | * cloning for SDVO encoders. | ||
2724 | */ | ||
2725 | intel_sdvo->base.cloneable = false; | ||
2726 | |||
2689 | /* Only enable the hotplug irq if we need it, to work around noisy | 2727 | /* Only enable the hotplug irq if we need it, to work around noisy |
2690 | * hotplug lines. | 2728 | * hotplug lines. |
2691 | */ | 2729 | */ |
@@ -2696,12 +2734,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2696 | 2734 | ||
2697 | /* Set the input timing to the screen. Assume always input 0. */ | 2735 | /* Set the input timing to the screen. Assume always input 0. */ |
2698 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 2736 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
2699 | goto err; | 2737 | goto err_output; |
2700 | 2738 | ||
2701 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, | 2739 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, |
2702 | &intel_sdvo->pixel_clock_min, | 2740 | &intel_sdvo->pixel_clock_min, |
2703 | &intel_sdvo->pixel_clock_max)) | 2741 | &intel_sdvo->pixel_clock_max)) |
2704 | goto err; | 2742 | goto err_output; |
2705 | 2743 | ||
2706 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " | 2744 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " |
2707 | "clock range %dMHz - %dMHz, " | 2745 | "clock range %dMHz - %dMHz, " |
@@ -2721,6 +2759,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2721 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); | 2759 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); |
2722 | return true; | 2760 | return true; |
2723 | 2761 | ||
2762 | err_output: | ||
2763 | intel_sdvo_output_cleanup(intel_sdvo); | ||
2764 | |||
2724 | err: | 2765 | err: |
2725 | drm_encoder_cleanup(&intel_encoder->base); | 2766 | drm_encoder_cleanup(&intel_encoder->base); |
2726 | i2c_del_adapter(&intel_sdvo->ddc); | 2767 | i2c_del_adapter(&intel_sdvo->ddc); |