diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-08-31 23:22:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-08-31 23:22:10 -0400 |
commit | b5af754405e8cb8b14b3f5958581ebf63c3601e9 (patch) | |
tree | 52a64a53969c2fcd5ea2545cd74ece8c2eb24345 /drivers/gpu | |
parent | adda766193ea1cf3137484a9521972d080d0b7af (diff) | |
parent | db54501900ad3665dd669f5708ecd04fc5aed495 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel:
drm/i915: Improve CRTDDC mapping by using VBT info
drm/i915: Fix CPU-spinning hangs related to fence usage by using an LRU.
drm/i915: Set crtc/clone mask in different output devices
drm/i915: Always use SDVO_B detect bit for SDVO output detection.
drm/i915: Fix typo that broke SVID1 in intel_sdvo_multifunc_encoder()
drm/i915: Check if BIOS enabled dual-channel LVDS on 8xx, not only on 9xx
drm/i915: Set the multiplier for SDVO on G33 platform
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 86 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.c | 51 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 71 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dvo.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_tv.c | 2 |
12 files changed, 194 insertions, 105 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7537f57d8a87..5b4f87e55621 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -222,6 +222,7 @@ typedef struct drm_i915_private { | |||
222 | unsigned int edp_support:1; | 222 | unsigned int edp_support:1; |
223 | int lvds_ssc_freq; | 223 | int lvds_ssc_freq; |
224 | 224 | ||
225 | int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */ | ||
225 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ | 226 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ |
226 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ | 227 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ |
227 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ | 228 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ |
@@ -384,6 +385,9 @@ typedef struct drm_i915_private { | |||
384 | */ | 385 | */ |
385 | struct list_head inactive_list; | 386 | struct list_head inactive_list; |
386 | 387 | ||
388 | /** LRU list of objects with fence regs on them. */ | ||
389 | struct list_head fence_list; | ||
390 | |||
387 | /** | 391 | /** |
388 | * List of breadcrumbs associated with GPU requests currently | 392 | * List of breadcrumbs associated with GPU requests currently |
389 | * outstanding. | 393 | * outstanding. |
@@ -451,6 +455,9 @@ struct drm_i915_gem_object { | |||
451 | /** This object's place on the active/flushing/inactive lists */ | 455 | /** This object's place on the active/flushing/inactive lists */ |
452 | struct list_head list; | 456 | struct list_head list; |
453 | 457 | ||
458 | /** This object's place on the fenced object LRU */ | ||
459 | struct list_head fence_list; | ||
460 | |||
454 | /** | 461 | /** |
455 | * This is set if the object is on the active or flushing lists | 462 | * This is set if the object is on the active or flushing lists |
456 | * (has pending rendering), and is not set if it's on inactive (ready | 463 | * (has pending rendering), and is not set if it's on inactive (ready |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 140bee142fc2..0c07a755b3a3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -978,6 +978,7 @@ int | |||
978 | i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | 978 | i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, |
979 | struct drm_file *file_priv) | 979 | struct drm_file *file_priv) |
980 | { | 980 | { |
981 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
981 | struct drm_i915_gem_set_domain *args = data; | 982 | struct drm_i915_gem_set_domain *args = data; |
982 | struct drm_gem_object *obj; | 983 | struct drm_gem_object *obj; |
983 | uint32_t read_domains = args->read_domains; | 984 | uint32_t read_domains = args->read_domains; |
@@ -1010,8 +1011,18 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1010 | obj, obj->size, read_domains, write_domain); | 1011 | obj, obj->size, read_domains, write_domain); |
1011 | #endif | 1012 | #endif |
1012 | if (read_domains & I915_GEM_DOMAIN_GTT) { | 1013 | if (read_domains & I915_GEM_DOMAIN_GTT) { |
1014 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1015 | |||
1013 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); | 1016 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); |
1014 | 1017 | ||
1018 | /* Update the LRU on the fence for the CPU access that's | ||
1019 | * about to occur. | ||
1020 | */ | ||
1021 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | ||
1022 | list_move_tail(&obj_priv->fence_list, | ||
1023 | &dev_priv->mm.fence_list); | ||
1024 | } | ||
1025 | |||
1015 | /* Silently promote "you're not bound, there was nothing to do" | 1026 | /* Silently promote "you're not bound, there was nothing to do" |
1016 | * to success, since the client was just asking us to | 1027 | * to success, since the client was just asking us to |
1017 | * make sure everything was done. | 1028 | * make sure everything was done. |
@@ -1155,8 +1166,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1155 | } | 1166 | } |
1156 | 1167 | ||
1157 | /* Need a new fence register? */ | 1168 | /* Need a new fence register? */ |
1158 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE && | 1169 | if (obj_priv->tiling_mode != I915_TILING_NONE) { |
1159 | obj_priv->tiling_mode != I915_TILING_NONE) { | ||
1160 | ret = i915_gem_object_get_fence_reg(obj); | 1170 | ret = i915_gem_object_get_fence_reg(obj); |
1161 | if (ret) { | 1171 | if (ret) { |
1162 | mutex_unlock(&dev->struct_mutex); | 1172 | mutex_unlock(&dev->struct_mutex); |
@@ -2208,6 +2218,12 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2208 | struct drm_i915_gem_object *old_obj_priv = NULL; | 2218 | struct drm_i915_gem_object *old_obj_priv = NULL; |
2209 | int i, ret, avail; | 2219 | int i, ret, avail; |
2210 | 2220 | ||
2221 | /* Just update our place in the LRU if our fence is getting used. */ | ||
2222 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | ||
2223 | list_move_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); | ||
2224 | return 0; | ||
2225 | } | ||
2226 | |||
2211 | switch (obj_priv->tiling_mode) { | 2227 | switch (obj_priv->tiling_mode) { |
2212 | case I915_TILING_NONE: | 2228 | case I915_TILING_NONE: |
2213 | WARN(1, "allocating a fence for non-tiled object?\n"); | 2229 | WARN(1, "allocating a fence for non-tiled object?\n"); |
@@ -2229,7 +2245,6 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2229 | } | 2245 | } |
2230 | 2246 | ||
2231 | /* First try to find a free reg */ | 2247 | /* First try to find a free reg */ |
2232 | try_again: | ||
2233 | avail = 0; | 2248 | avail = 0; |
2234 | for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { | 2249 | for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { |
2235 | reg = &dev_priv->fence_regs[i]; | 2250 | reg = &dev_priv->fence_regs[i]; |
@@ -2243,52 +2258,41 @@ try_again: | |||
2243 | 2258 | ||
2244 | /* None available, try to steal one or wait for a user to finish */ | 2259 | /* None available, try to steal one or wait for a user to finish */ |
2245 | if (i == dev_priv->num_fence_regs) { | 2260 | if (i == dev_priv->num_fence_regs) { |
2246 | uint32_t seqno = dev_priv->mm.next_gem_seqno; | 2261 | struct drm_gem_object *old_obj = NULL; |
2247 | 2262 | ||
2248 | if (avail == 0) | 2263 | if (avail == 0) |
2249 | return -ENOSPC; | 2264 | return -ENOSPC; |
2250 | 2265 | ||
2251 | for (i = dev_priv->fence_reg_start; | 2266 | list_for_each_entry(old_obj_priv, &dev_priv->mm.fence_list, |
2252 | i < dev_priv->num_fence_regs; i++) { | 2267 | fence_list) { |
2253 | uint32_t this_seqno; | 2268 | old_obj = old_obj_priv->obj; |
2254 | 2269 | ||
2255 | reg = &dev_priv->fence_regs[i]; | 2270 | reg = &dev_priv->fence_regs[old_obj_priv->fence_reg]; |
2256 | old_obj_priv = reg->obj->driver_private; | ||
2257 | 2271 | ||
2258 | if (old_obj_priv->pin_count) | 2272 | if (old_obj_priv->pin_count) |
2259 | continue; | 2273 | continue; |
2260 | 2274 | ||
2275 | /* Take a reference, as otherwise the wait_rendering | ||
2276 | * below may cause the object to get freed out from | ||
2277 | * under us. | ||
2278 | */ | ||
2279 | drm_gem_object_reference(old_obj); | ||
2280 | |||
2261 | /* i915 uses fences for GPU access to tiled buffers */ | 2281 | /* i915 uses fences for GPU access to tiled buffers */ |
2262 | if (IS_I965G(dev) || !old_obj_priv->active) | 2282 | if (IS_I965G(dev) || !old_obj_priv->active) |
2263 | break; | 2283 | break; |
2264 | 2284 | ||
2265 | /* find the seqno of the first available fence */ | 2285 | /* This brings the object to the head of the LRU if it |
2266 | this_seqno = old_obj_priv->last_rendering_seqno; | 2286 | * had been written to. The only way this should |
2267 | if (this_seqno != 0 && | 2287 | * result in us waiting longer than the expected |
2268 | reg->obj->write_domain == 0 && | 2288 | * optimal amount of time is if there was a |
2269 | i915_seqno_passed(seqno, this_seqno)) | 2289 | * fence-using buffer later that was read-only. |
2270 | seqno = this_seqno; | 2290 | */ |
2271 | } | 2291 | i915_gem_object_flush_gpu_write_domain(old_obj); |
2272 | 2292 | ret = i915_gem_object_wait_rendering(old_obj); | |
2273 | /* | 2293 | if (ret != 0) |
2274 | * Now things get ugly... we have to wait for one of the | ||
2275 | * objects to finish before trying again. | ||
2276 | */ | ||
2277 | if (i == dev_priv->num_fence_regs) { | ||
2278 | if (seqno == dev_priv->mm.next_gem_seqno) { | ||
2279 | i915_gem_flush(dev, | ||
2280 | I915_GEM_GPU_DOMAINS, | ||
2281 | I915_GEM_GPU_DOMAINS); | ||
2282 | seqno = i915_add_request(dev, NULL, | ||
2283 | I915_GEM_GPU_DOMAINS); | ||
2284 | if (seqno == 0) | ||
2285 | return -ENOMEM; | ||
2286 | } | ||
2287 | |||
2288 | ret = i915_wait_request(dev, seqno); | ||
2289 | if (ret) | ||
2290 | return ret; | 2294 | return ret; |
2291 | goto try_again; | 2295 | break; |
2292 | } | 2296 | } |
2293 | 2297 | ||
2294 | /* | 2298 | /* |
@@ -2296,10 +2300,15 @@ try_again: | |||
2296 | * for this object next time we need it. | 2300 | * for this object next time we need it. |
2297 | */ | 2301 | */ |
2298 | i915_gem_release_mmap(reg->obj); | 2302 | i915_gem_release_mmap(reg->obj); |
2303 | i = old_obj_priv->fence_reg; | ||
2299 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; | 2304 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; |
2305 | list_del_init(&old_obj_priv->fence_list); | ||
2306 | drm_gem_object_unreference(old_obj); | ||
2300 | } | 2307 | } |
2301 | 2308 | ||
2302 | obj_priv->fence_reg = i; | 2309 | obj_priv->fence_reg = i; |
2310 | list_add_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); | ||
2311 | |||
2303 | reg->obj = obj; | 2312 | reg->obj = obj; |
2304 | 2313 | ||
2305 | if (IS_I965G(dev)) | 2314 | if (IS_I965G(dev)) |
@@ -2342,6 +2351,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2342 | 2351 | ||
2343 | dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL; | 2352 | dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL; |
2344 | obj_priv->fence_reg = I915_FENCE_REG_NONE; | 2353 | obj_priv->fence_reg = I915_FENCE_REG_NONE; |
2354 | list_del_init(&obj_priv->fence_list); | ||
2345 | } | 2355 | } |
2346 | 2356 | ||
2347 | /** | 2357 | /** |
@@ -3595,9 +3605,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
3595 | * Pre-965 chips need a fence register set up in order to | 3605 | * Pre-965 chips need a fence register set up in order to |
3596 | * properly handle tiled surfaces. | 3606 | * properly handle tiled surfaces. |
3597 | */ | 3607 | */ |
3598 | if (!IS_I965G(dev) && | 3608 | if (!IS_I965G(dev) && obj_priv->tiling_mode != I915_TILING_NONE) { |
3599 | obj_priv->fence_reg == I915_FENCE_REG_NONE && | ||
3600 | obj_priv->tiling_mode != I915_TILING_NONE) { | ||
3601 | ret = i915_gem_object_get_fence_reg(obj); | 3609 | ret = i915_gem_object_get_fence_reg(obj); |
3602 | if (ret != 0) { | 3610 | if (ret != 0) { |
3603 | if (ret != -EBUSY && ret != -ERESTARTSYS) | 3611 | if (ret != -EBUSY && ret != -ERESTARTSYS) |
@@ -3806,6 +3814,7 @@ int i915_gem_init_object(struct drm_gem_object *obj) | |||
3806 | obj_priv->obj = obj; | 3814 | obj_priv->obj = obj; |
3807 | obj_priv->fence_reg = I915_FENCE_REG_NONE; | 3815 | obj_priv->fence_reg = I915_FENCE_REG_NONE; |
3808 | INIT_LIST_HEAD(&obj_priv->list); | 3816 | INIT_LIST_HEAD(&obj_priv->list); |
3817 | INIT_LIST_HEAD(&obj_priv->fence_list); | ||
3809 | 3818 | ||
3810 | return 0; | 3819 | return 0; |
3811 | } | 3820 | } |
@@ -4253,6 +4262,7 @@ i915_gem_load(struct drm_device *dev) | |||
4253 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); | 4262 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); |
4254 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); | 4263 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); |
4255 | INIT_LIST_HEAD(&dev_priv->mm.request_list); | 4264 | INIT_LIST_HEAD(&dev_priv->mm.request_list); |
4265 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); | ||
4256 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, | 4266 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, |
4257 | i915_gem_retire_work_handler); | 4267 | i915_gem_retire_work_handler); |
4258 | dev_priv->mm.next_gem_seqno = 1; | 4268 | dev_priv->mm.next_gem_seqno = 1; |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 300aee3296c2..f806fcc54e09 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -59,6 +59,16 @@ find_section(struct bdb_header *bdb, int section_id) | |||
59 | return NULL; | 59 | return NULL; |
60 | } | 60 | } |
61 | 61 | ||
62 | static u16 | ||
63 | get_blocksize(void *p) | ||
64 | { | ||
65 | u16 *block_ptr, block_size; | ||
66 | |||
67 | block_ptr = (u16 *)((char *)p - 2); | ||
68 | block_size = *block_ptr; | ||
69 | return block_size; | ||
70 | } | ||
71 | |||
62 | static void | 72 | static void |
63 | fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, | 73 | fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, |
64 | struct lvds_dvo_timing *dvo_timing) | 74 | struct lvds_dvo_timing *dvo_timing) |
@@ -215,6 +225,41 @@ parse_general_features(struct drm_i915_private *dev_priv, | |||
215 | } | 225 | } |
216 | 226 | ||
217 | static void | 227 | static void |
228 | parse_general_definitions(struct drm_i915_private *dev_priv, | ||
229 | struct bdb_header *bdb) | ||
230 | { | ||
231 | struct bdb_general_definitions *general; | ||
232 | const int crt_bus_map_table[] = { | ||
233 | GPIOB, | ||
234 | GPIOA, | ||
235 | GPIOC, | ||
236 | GPIOD, | ||
237 | GPIOE, | ||
238 | GPIOF, | ||
239 | }; | ||
240 | |||
241 | /* Set sensible defaults in case we can't find the general block | ||
242 | or it is the wrong chipset */ | ||
243 | dev_priv->crt_ddc_bus = -1; | ||
244 | |||
245 | general = find_section(bdb, BDB_GENERAL_DEFINITIONS); | ||
246 | if (general) { | ||
247 | u16 block_size = get_blocksize(general); | ||
248 | if (block_size >= sizeof(*general)) { | ||
249 | int bus_pin = general->crt_ddc_gmbus_pin; | ||
250 | DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin); | ||
251 | if ((bus_pin >= 1) && (bus_pin <= 6)) { | ||
252 | dev_priv->crt_ddc_bus = | ||
253 | crt_bus_map_table[bus_pin-1]; | ||
254 | } | ||
255 | } else { | ||
256 | DRM_DEBUG("BDB_GD too small (%d). Invalid.\n", | ||
257 | block_size); | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | |||
262 | static void | ||
218 | parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | 263 | parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, |
219 | struct bdb_header *bdb) | 264 | struct bdb_header *bdb) |
220 | { | 265 | { |
@@ -222,7 +267,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
222 | struct bdb_general_definitions *p_defs; | 267 | struct bdb_general_definitions *p_defs; |
223 | struct child_device_config *p_child; | 268 | struct child_device_config *p_child; |
224 | int i, child_device_num, count; | 269 | int i, child_device_num, count; |
225 | u16 block_size, *block_ptr; | 270 | u16 block_size; |
226 | 271 | ||
227 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | 272 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
228 | if (!p_defs) { | 273 | if (!p_defs) { |
@@ -240,8 +285,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
240 | return; | 285 | return; |
241 | } | 286 | } |
242 | /* get the block size of general definitions */ | 287 | /* get the block size of general definitions */ |
243 | block_ptr = (u16 *)((char *)p_defs - 2); | 288 | block_size = get_blocksize(p_defs); |
244 | block_size = *block_ptr; | ||
245 | /* get the number of child device */ | 289 | /* get the number of child device */ |
246 | child_device_num = (block_size - sizeof(*p_defs)) / | 290 | child_device_num = (block_size - sizeof(*p_defs)) / |
247 | sizeof(*p_child); | 291 | sizeof(*p_child); |
@@ -362,6 +406,7 @@ intel_init_bios(struct drm_device *dev) | |||
362 | 406 | ||
363 | /* Grab useful general definitions */ | 407 | /* Grab useful general definitions */ |
364 | parse_general_features(dev_priv, bdb); | 408 | parse_general_features(dev_priv, bdb); |
409 | parse_general_definitions(dev_priv, bdb); | ||
365 | parse_lfp_panel_data(dev_priv, bdb); | 410 | parse_lfp_panel_data(dev_priv, bdb); |
366 | parse_sdvo_panel_data(dev_priv, bdb); | 411 | parse_sdvo_panel_data(dev_priv, bdb); |
367 | parse_sdvo_device_mapping(dev_priv, bdb); | 412 | parse_sdvo_device_mapping(dev_priv, bdb); |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 4cf8e2e88a40..590f81c8f594 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -508,6 +508,7 @@ void intel_crt_init(struct drm_device *dev) | |||
508 | { | 508 | { |
509 | struct drm_connector *connector; | 509 | struct drm_connector *connector; |
510 | struct intel_output *intel_output; | 510 | struct intel_output *intel_output; |
511 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
511 | u32 i2c_reg; | 512 | u32 i2c_reg; |
512 | 513 | ||
513 | intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); | 514 | intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); |
@@ -527,8 +528,12 @@ void intel_crt_init(struct drm_device *dev) | |||
527 | /* Set up the DDC bus. */ | 528 | /* Set up the DDC bus. */ |
528 | if (IS_IGDNG(dev)) | 529 | if (IS_IGDNG(dev)) |
529 | i2c_reg = PCH_GPIOA; | 530 | i2c_reg = PCH_GPIOA; |
530 | else | 531 | else { |
531 | i2c_reg = GPIOA; | 532 | i2c_reg = GPIOA; |
533 | /* Use VBT information for CRT DDC if available */ | ||
534 | if (dev_priv->crt_ddc_bus != -1) | ||
535 | i2c_reg = dev_priv->crt_ddc_bus; | ||
536 | } | ||
532 | intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); | 537 | intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); |
533 | if (!intel_output->ddc_bus) { | 538 | if (!intel_output->ddc_bus) { |
534 | dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " | 539 | dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " |
@@ -537,6 +542,10 @@ void intel_crt_init(struct drm_device *dev) | |||
537 | } | 542 | } |
538 | 543 | ||
539 | intel_output->type = INTEL_OUTPUT_ANALOG; | 544 | intel_output->type = INTEL_OUTPUT_ANALOG; |
545 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
546 | (1 << INTEL_ANALOG_CLONE_BIT) | | ||
547 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
548 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
540 | connector->interlace_allowed = 0; | 549 | connector->interlace_allowed = 0; |
541 | connector->doublescan_allowed = 0; | 550 | connector->doublescan_allowed = 0; |
542 | 551 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d6fce2133413..3fadb5358858 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -666,7 +666,7 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
666 | intel_clock_t clock; | 666 | intel_clock_t clock; |
667 | int err = target; | 667 | int err = target; |
668 | 668 | ||
669 | if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && | 669 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && |
670 | (I915_READ(LVDS)) != 0) { | 670 | (I915_READ(LVDS)) != 0) { |
671 | /* | 671 | /* |
672 | * For LVDS, if the panel is on, just rely on its current | 672 | * For LVDS, if the panel is on, just rely on its current |
@@ -2396,7 +2396,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2396 | if (is_sdvo) { | 2396 | if (is_sdvo) { |
2397 | dpll |= DPLL_DVO_HIGH_SPEED; | 2397 | dpll |= DPLL_DVO_HIGH_SPEED; |
2398 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | 2398 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; |
2399 | if (IS_I945G(dev) || IS_I945GM(dev)) | 2399 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) |
2400 | dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; | 2400 | dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; |
2401 | else if (IS_IGDNG(dev)) | 2401 | else if (IS_IGDNG(dev)) |
2402 | dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; | 2402 | dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; |
@@ -3170,7 +3170,7 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask) | |||
3170 | 3170 | ||
3171 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 3171 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
3172 | struct intel_output *intel_output = to_intel_output(connector); | 3172 | struct intel_output *intel_output = to_intel_output(connector); |
3173 | if (type_mask & (1 << intel_output->type)) | 3173 | if (type_mask & intel_output->clone_mask) |
3174 | index_mask |= (1 << entry); | 3174 | index_mask |= (1 << entry); |
3175 | entry++; | 3175 | entry++; |
3176 | } | 3176 | } |
@@ -3218,30 +3218,30 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
3218 | intel_dp_init(dev, PCH_DP_D); | 3218 | intel_dp_init(dev, PCH_DP_D); |
3219 | 3219 | ||
3220 | } else if (IS_I9XX(dev)) { | 3220 | } else if (IS_I9XX(dev)) { |
3221 | int found; | 3221 | bool found = false; |
3222 | u32 reg; | ||
3223 | 3222 | ||
3224 | if (I915_READ(SDVOB) & SDVO_DETECTED) { | 3223 | if (I915_READ(SDVOB) & SDVO_DETECTED) { |
3225 | found = intel_sdvo_init(dev, SDVOB); | 3224 | found = intel_sdvo_init(dev, SDVOB); |
3226 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) | 3225 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) |
3227 | intel_hdmi_init(dev, SDVOB); | 3226 | intel_hdmi_init(dev, SDVOB); |
3227 | |||
3228 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) | 3228 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) |
3229 | intel_dp_init(dev, DP_B); | 3229 | intel_dp_init(dev, DP_B); |
3230 | } | 3230 | } |
3231 | 3231 | ||
3232 | /* Before G4X SDVOC doesn't have its own detect register */ | 3232 | /* Before G4X SDVOC doesn't have its own detect register */ |
3233 | if (IS_G4X(dev)) | ||
3234 | reg = SDVOC; | ||
3235 | else | ||
3236 | reg = SDVOB; | ||
3237 | 3233 | ||
3238 | if (I915_READ(reg) & SDVO_DETECTED) { | 3234 | if (I915_READ(SDVOB) & SDVO_DETECTED) |
3239 | found = intel_sdvo_init(dev, SDVOC); | 3235 | found = intel_sdvo_init(dev, SDVOC); |
3240 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) | 3236 | |
3237 | if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) { | ||
3238 | |||
3239 | if (SUPPORTS_INTEGRATED_HDMI(dev)) | ||
3241 | intel_hdmi_init(dev, SDVOC); | 3240 | intel_hdmi_init(dev, SDVOC); |
3242 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) | 3241 | if (SUPPORTS_INTEGRATED_DP(dev)) |
3243 | intel_dp_init(dev, DP_C); | 3242 | intel_dp_init(dev, DP_C); |
3244 | } | 3243 | } |
3244 | |||
3245 | if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) | 3245 | if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) |
3246 | intel_dp_init(dev, DP_D); | 3246 | intel_dp_init(dev, DP_D); |
3247 | } else | 3247 | } else |
@@ -3253,51 +3253,10 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
3253 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 3253 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
3254 | struct intel_output *intel_output = to_intel_output(connector); | 3254 | struct intel_output *intel_output = to_intel_output(connector); |
3255 | struct drm_encoder *encoder = &intel_output->enc; | 3255 | struct drm_encoder *encoder = &intel_output->enc; |
3256 | int crtc_mask = 0, clone_mask = 0; | ||
3257 | 3256 | ||
3258 | /* valid crtcs */ | 3257 | encoder->possible_crtcs = intel_output->crtc_mask; |
3259 | switch(intel_output->type) { | 3258 | encoder->possible_clones = intel_connector_clones(dev, |
3260 | case INTEL_OUTPUT_HDMI: | 3259 | intel_output->clone_mask); |
3261 | crtc_mask = ((1 << 0)| | ||
3262 | (1 << 1)); | ||
3263 | clone_mask = ((1 << INTEL_OUTPUT_HDMI)); | ||
3264 | break; | ||
3265 | case INTEL_OUTPUT_DVO: | ||
3266 | case INTEL_OUTPUT_SDVO: | ||
3267 | crtc_mask = ((1 << 0)| | ||
3268 | (1 << 1)); | ||
3269 | clone_mask = ((1 << INTEL_OUTPUT_ANALOG) | | ||
3270 | (1 << INTEL_OUTPUT_DVO) | | ||
3271 | (1 << INTEL_OUTPUT_SDVO)); | ||
3272 | break; | ||
3273 | case INTEL_OUTPUT_ANALOG: | ||
3274 | crtc_mask = ((1 << 0)| | ||
3275 | (1 << 1)); | ||
3276 | clone_mask = ((1 << INTEL_OUTPUT_ANALOG) | | ||
3277 | (1 << INTEL_OUTPUT_DVO) | | ||
3278 | (1 << INTEL_OUTPUT_SDVO)); | ||
3279 | break; | ||
3280 | case INTEL_OUTPUT_LVDS: | ||
3281 | crtc_mask = (1 << 1); | ||
3282 | clone_mask = (1 << INTEL_OUTPUT_LVDS); | ||
3283 | break; | ||
3284 | case INTEL_OUTPUT_TVOUT: | ||
3285 | crtc_mask = ((1 << 0) | | ||
3286 | (1 << 1)); | ||
3287 | clone_mask = (1 << INTEL_OUTPUT_TVOUT); | ||
3288 | break; | ||
3289 | case INTEL_OUTPUT_DISPLAYPORT: | ||
3290 | crtc_mask = ((1 << 0) | | ||
3291 | (1 << 1)); | ||
3292 | clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); | ||
3293 | break; | ||
3294 | case INTEL_OUTPUT_EDP: | ||
3295 | crtc_mask = (1 << 1); | ||
3296 | clone_mask = (1 << INTEL_OUTPUT_EDP); | ||
3297 | break; | ||
3298 | } | ||
3299 | encoder->possible_crtcs = crtc_mask; | ||
3300 | encoder->possible_clones = intel_connector_clones(dev, clone_mask); | ||
3301 | } | 3260 | } |
3302 | } | 3261 | } |
3303 | 3262 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a6ff15ac548a..f2afc4af4bc9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1254,6 +1254,18 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1254 | else | 1254 | else |
1255 | intel_output->type = INTEL_OUTPUT_DISPLAYPORT; | 1255 | intel_output->type = INTEL_OUTPUT_DISPLAYPORT; |
1256 | 1256 | ||
1257 | if (output_reg == DP_B) | ||
1258 | intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); | ||
1259 | else if (output_reg == DP_C) | ||
1260 | intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); | ||
1261 | else if (output_reg == DP_D) | ||
1262 | intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); | ||
1263 | |||
1264 | if (IS_eDP(intel_output)) { | ||
1265 | intel_output->crtc_mask = (1 << 1); | ||
1266 | intel_output->clone_mask = (1 << INTEL_OUTPUT_EDP); | ||
1267 | } else | ||
1268 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
1257 | connector->interlace_allowed = true; | 1269 | connector->interlace_allowed = true; |
1258 | connector->doublescan_allowed = 0; | 1270 | connector->doublescan_allowed = 0; |
1259 | 1271 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d6f92ea1b553..25aa6facc12d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -57,6 +57,24 @@ | |||
57 | #define INTEL_OUTPUT_DISPLAYPORT 7 | 57 | #define INTEL_OUTPUT_DISPLAYPORT 7 |
58 | #define INTEL_OUTPUT_EDP 8 | 58 | #define INTEL_OUTPUT_EDP 8 |
59 | 59 | ||
60 | /* Intel Pipe Clone Bit */ | ||
61 | #define INTEL_HDMIB_CLONE_BIT 1 | ||
62 | #define INTEL_HDMIC_CLONE_BIT 2 | ||
63 | #define INTEL_HDMID_CLONE_BIT 3 | ||
64 | #define INTEL_HDMIE_CLONE_BIT 4 | ||
65 | #define INTEL_HDMIF_CLONE_BIT 5 | ||
66 | #define INTEL_SDVO_NON_TV_CLONE_BIT 6 | ||
67 | #define INTEL_SDVO_TV_CLONE_BIT 7 | ||
68 | #define INTEL_SDVO_LVDS_CLONE_BIT 8 | ||
69 | #define INTEL_ANALOG_CLONE_BIT 9 | ||
70 | #define INTEL_TV_CLONE_BIT 10 | ||
71 | #define INTEL_DP_B_CLONE_BIT 11 | ||
72 | #define INTEL_DP_C_CLONE_BIT 12 | ||
73 | #define INTEL_DP_D_CLONE_BIT 13 | ||
74 | #define INTEL_LVDS_CLONE_BIT 14 | ||
75 | #define INTEL_DVO_TMDS_CLONE_BIT 15 | ||
76 | #define INTEL_DVO_LVDS_CLONE_BIT 16 | ||
77 | |||
60 | #define INTEL_DVO_CHIP_NONE 0 | 78 | #define INTEL_DVO_CHIP_NONE 0 |
61 | #define INTEL_DVO_CHIP_LVDS 1 | 79 | #define INTEL_DVO_CHIP_LVDS 1 |
62 | #define INTEL_DVO_CHIP_TMDS 2 | 80 | #define INTEL_DVO_CHIP_TMDS 2 |
@@ -86,6 +104,8 @@ struct intel_output { | |||
86 | bool needs_tv_clock; | 104 | bool needs_tv_clock; |
87 | void *dev_priv; | 105 | void *dev_priv; |
88 | void (*hot_plug)(struct intel_output *); | 106 | void (*hot_plug)(struct intel_output *); |
107 | int crtc_mask; | ||
108 | int clone_mask; | ||
89 | }; | 109 | }; |
90 | 110 | ||
91 | struct intel_crtc { | 111 | struct intel_crtc { |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 13bff20930e8..a4d2606de778 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -435,14 +435,20 @@ void intel_dvo_init(struct drm_device *dev) | |||
435 | continue; | 435 | continue; |
436 | 436 | ||
437 | intel_output->type = INTEL_OUTPUT_DVO; | 437 | intel_output->type = INTEL_OUTPUT_DVO; |
438 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
438 | switch (dvo->type) { | 439 | switch (dvo->type) { |
439 | case INTEL_DVO_CHIP_TMDS: | 440 | case INTEL_DVO_CHIP_TMDS: |
441 | intel_output->clone_mask = | ||
442 | (1 << INTEL_DVO_TMDS_CLONE_BIT) | | ||
443 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
440 | drm_connector_init(dev, connector, | 444 | drm_connector_init(dev, connector, |
441 | &intel_dvo_connector_funcs, | 445 | &intel_dvo_connector_funcs, |
442 | DRM_MODE_CONNECTOR_DVII); | 446 | DRM_MODE_CONNECTOR_DVII); |
443 | encoder_type = DRM_MODE_ENCODER_TMDS; | 447 | encoder_type = DRM_MODE_ENCODER_TMDS; |
444 | break; | 448 | break; |
445 | case INTEL_DVO_CHIP_LVDS: | 449 | case INTEL_DVO_CHIP_LVDS: |
450 | intel_output->clone_mask = | ||
451 | (1 << INTEL_DVO_LVDS_CLONE_BIT); | ||
446 | drm_connector_init(dev, connector, | 452 | drm_connector_init(dev, connector, |
447 | &intel_dvo_connector_funcs, | 453 | &intel_dvo_connector_funcs, |
448 | DRM_MODE_CONNECTOR_LVDS); | 454 | DRM_MODE_CONNECTOR_LVDS); |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1842290cded3..fa304e136010 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -230,22 +230,28 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
230 | 230 | ||
231 | connector->interlace_allowed = 0; | 231 | connector->interlace_allowed = 0; |
232 | connector->doublescan_allowed = 0; | 232 | connector->doublescan_allowed = 0; |
233 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
233 | 234 | ||
234 | /* Set up the DDC bus. */ | 235 | /* Set up the DDC bus. */ |
235 | if (sdvox_reg == SDVOB) | 236 | if (sdvox_reg == SDVOB) { |
237 | intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); | ||
236 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); | 238 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); |
237 | else if (sdvox_reg == SDVOC) | 239 | } else if (sdvox_reg == SDVOC) { |
240 | intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); | ||
238 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); | 241 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); |
239 | else if (sdvox_reg == HDMIB) | 242 | } else if (sdvox_reg == HDMIB) { |
243 | intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); | ||
240 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, | 244 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, |
241 | "HDMIB"); | 245 | "HDMIB"); |
242 | else if (sdvox_reg == HDMIC) | 246 | } else if (sdvox_reg == HDMIC) { |
247 | intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); | ||
243 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, | 248 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, |
244 | "HDMIC"); | 249 | "HDMIC"); |
245 | else if (sdvox_reg == HDMID) | 250 | } else if (sdvox_reg == HDMID) { |
251 | intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); | ||
246 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, | 252 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, |
247 | "HDMID"); | 253 | "HDMID"); |
248 | 254 | } | |
249 | if (!intel_output->ddc_bus) | 255 | if (!intel_output->ddc_bus) |
250 | goto err_connector; | 256 | goto err_connector; |
251 | 257 | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 3f445a80c552..8df02ef89261 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -916,6 +916,8 @@ void intel_lvds_init(struct drm_device *dev) | |||
916 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 916 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); |
917 | intel_output->type = INTEL_OUTPUT_LVDS; | 917 | intel_output->type = INTEL_OUTPUT_LVDS; |
918 | 918 | ||
919 | intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); | ||
920 | intel_output->crtc_mask = (1 << 1); | ||
919 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); | 921 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); |
920 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); | 922 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); |
921 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | 923 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 5371d9332554..d3b74ba62b4a 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1458,7 +1458,7 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output) | |||
1458 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) | 1458 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) |
1459 | caps++; | 1459 | caps++; |
1460 | if (sdvo_priv->caps.output_flags & | 1460 | if (sdvo_priv->caps.output_flags & |
1461 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID0)) | 1461 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1)) |
1462 | caps++; | 1462 | caps++; |
1463 | if (sdvo_priv->caps.output_flags & | 1463 | if (sdvo_priv->caps.output_flags & |
1464 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) | 1464 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) |
@@ -1967,6 +1967,9 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
1967 | intel_sdvo_set_colorimetry(intel_output, | 1967 | intel_sdvo_set_colorimetry(intel_output, |
1968 | SDVO_COLORIMETRY_RGB256); | 1968 | SDVO_COLORIMETRY_RGB256); |
1969 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 1969 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
1970 | intel_output->clone_mask = | ||
1971 | (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
1972 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
1970 | } | 1973 | } |
1971 | } else if (flags & SDVO_OUTPUT_SVID0) { | 1974 | } else if (flags & SDVO_OUTPUT_SVID0) { |
1972 | 1975 | ||
@@ -1975,11 +1978,14 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
1975 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | 1978 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; |
1976 | sdvo_priv->is_tv = true; | 1979 | sdvo_priv->is_tv = true; |
1977 | intel_output->needs_tv_clock = true; | 1980 | intel_output->needs_tv_clock = true; |
1981 | intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | ||
1978 | } else if (flags & SDVO_OUTPUT_RGB0) { | 1982 | } else if (flags & SDVO_OUTPUT_RGB0) { |
1979 | 1983 | ||
1980 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; | 1984 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; |
1981 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | 1985 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; |
1982 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | 1986 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; |
1987 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
1988 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
1983 | } else if (flags & SDVO_OUTPUT_RGB1) { | 1989 | } else if (flags & SDVO_OUTPUT_RGB1) { |
1984 | 1990 | ||
1985 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; | 1991 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; |
@@ -1991,12 +1997,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
1991 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | 1997 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
1992 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | 1998 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
1993 | sdvo_priv->is_lvds = true; | 1999 | sdvo_priv->is_lvds = true; |
2000 | intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2001 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
1994 | } else if (flags & SDVO_OUTPUT_LVDS1) { | 2002 | } else if (flags & SDVO_OUTPUT_LVDS1) { |
1995 | 2003 | ||
1996 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; | 2004 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; |
1997 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | 2005 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
1998 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | 2006 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
1999 | sdvo_priv->is_lvds = true; | 2007 | sdvo_priv->is_lvds = true; |
2008 | intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2009 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
2000 | } else { | 2010 | } else { |
2001 | 2011 | ||
2002 | unsigned char bytes[2]; | 2012 | unsigned char bytes[2]; |
@@ -2009,6 +2019,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
2009 | bytes[0], bytes[1]); | 2019 | bytes[0], bytes[1]); |
2010 | ret = false; | 2020 | ret = false; |
2011 | } | 2021 | } |
2022 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
2012 | 2023 | ||
2013 | if (ret && registered) | 2024 | if (ret && registered) |
2014 | ret = drm_sysfs_connector_add(connector) == 0 ? true : false; | 2025 | ret = drm_sysfs_connector_add(connector) == 0 ? true : false; |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index da4ab4dc1630..2fbe13a0de81 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1718,6 +1718,7 @@ intel_tv_init(struct drm_device *dev) | |||
1718 | if (!intel_output) { | 1718 | if (!intel_output) { |
1719 | return; | 1719 | return; |
1720 | } | 1720 | } |
1721 | |||
1721 | connector = &intel_output->base; | 1722 | connector = &intel_output->base; |
1722 | 1723 | ||
1723 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1724 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
@@ -1729,6 +1730,7 @@ intel_tv_init(struct drm_device *dev) | |||
1729 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 1730 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); |
1730 | tv_priv = (struct intel_tv_priv *)(intel_output + 1); | 1731 | tv_priv = (struct intel_tv_priv *)(intel_output + 1); |
1731 | intel_output->type = INTEL_OUTPUT_TVOUT; | 1732 | intel_output->type = INTEL_OUTPUT_TVOUT; |
1733 | intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT); | ||
1732 | intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); | 1734 | intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); |
1733 | intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); | 1735 | intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); |
1734 | intel_output->dev_priv = tv_priv; | 1736 | intel_output->dev_priv = tv_priv; |