diff options
Diffstat (limited to 'drivers/gpu')
26 files changed, 2645 insertions, 2408 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index da78f2c0d90..5c8e53458ed 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
| @@ -8,6 +8,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
| 8 | i915_suspend.o \ | 8 | i915_suspend.o \ |
| 9 | i915_gem.o \ | 9 | i915_gem.o \ |
| 10 | i915_gem_debug.o \ | 10 | i915_gem_debug.o \ |
| 11 | i915_gem_evict.o \ | ||
| 11 | i915_gem_tiling.o \ | 12 | i915_gem_tiling.o \ |
| 12 | i915_trace_points.o \ | 13 | i915_trace_points.o \ |
| 13 | intel_display.o \ | 14 | intel_display.o \ |
| @@ -18,6 +19,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
| 18 | intel_hdmi.o \ | 19 | intel_hdmi.o \ |
| 19 | intel_sdvo.o \ | 20 | intel_sdvo.o \ |
| 20 | intel_modes.o \ | 21 | intel_modes.o \ |
| 22 | intel_panel.o \ | ||
| 21 | intel_i2c.o \ | 23 | intel_i2c.o \ |
| 22 | intel_fb.o \ | 24 | intel_fb.o \ |
| 23 | intel_tv.o \ | 25 | intel_tv.o \ |
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h index 0d6ff640e1c..8c2ad014c47 100644 --- a/drivers/gpu/drm/i915/dvo.h +++ b/drivers/gpu/drm/i915/dvo.h | |||
| @@ -30,20 +30,17 @@ | |||
| 30 | #include "intel_drv.h" | 30 | #include "intel_drv.h" |
| 31 | 31 | ||
| 32 | struct intel_dvo_device { | 32 | struct intel_dvo_device { |
| 33 | char *name; | 33 | const char *name; |
| 34 | int type; | 34 | int type; |
| 35 | /* DVOA/B/C output register */ | 35 | /* DVOA/B/C output register */ |
| 36 | u32 dvo_reg; | 36 | u32 dvo_reg; |
| 37 | /* GPIO register used for i2c bus to control this device */ | 37 | /* GPIO register used for i2c bus to control this device */ |
| 38 | u32 gpio; | 38 | u32 gpio; |
| 39 | int slave_addr; | 39 | int slave_addr; |
| 40 | struct i2c_adapter *i2c_bus; | ||
| 41 | 40 | ||
| 42 | const struct intel_dvo_dev_ops *dev_ops; | 41 | const struct intel_dvo_dev_ops *dev_ops; |
| 43 | void *dev_priv; | 42 | void *dev_priv; |
| 44 | 43 | struct i2c_adapter *i2c_bus; | |
| 45 | struct drm_display_mode *panel_fixed_mode; | ||
| 46 | bool panel_wants_dither; | ||
| 47 | }; | 44 | }; |
| 48 | 45 | ||
| 49 | struct intel_dvo_dev_ops { | 46 | struct intel_dvo_dev_ops { |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9214119c015..92d5605a34d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
| @@ -467,6 +467,9 @@ static int i915_error_state(struct seq_file *m, void *unused) | |||
| 467 | } | 467 | } |
| 468 | } | 468 | } |
| 469 | 469 | ||
| 470 | if (error->overlay) | ||
| 471 | intel_overlay_print_error_state(m, error->overlay); | ||
| 472 | |||
| 470 | out: | 473 | out: |
| 471 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | 474 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); |
| 472 | 475 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f19ffe87af3..44af317731b 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -499,6 +499,13 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
| 499 | } | 499 | } |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | |||
| 503 | if (IS_G4X(dev) || IS_IRONLAKE(dev)) { | ||
| 504 | BEGIN_LP_RING(2); | ||
| 505 | OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP); | ||
| 506 | OUT_RING(MI_NOOP); | ||
| 507 | ADVANCE_LP_RING(); | ||
| 508 | } | ||
| 502 | i915_emit_breadcrumb(dev); | 509 | i915_emit_breadcrumb(dev); |
| 503 | 510 | ||
| 504 | return 0; | 511 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5044f653e8e..00befce8fbb 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -181,6 +181,7 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
| 181 | INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), | 181 | INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), |
| 182 | INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), | 182 | INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), |
| 183 | INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), | 183 | INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), |
| 184 | INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), | ||
| 184 | {0, 0, 0} | 185 | {0, 0, 0} |
| 185 | }; | 186 | }; |
| 186 | 187 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 906663b9929..047cd7ce7e1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -113,6 +113,9 @@ struct intel_opregion { | |||
| 113 | int enabled; | 113 | int enabled; |
| 114 | }; | 114 | }; |
| 115 | 115 | ||
| 116 | struct intel_overlay; | ||
| 117 | struct intel_overlay_error_state; | ||
| 118 | |||
| 116 | struct drm_i915_master_private { | 119 | struct drm_i915_master_private { |
| 117 | drm_local_map_t *sarea; | 120 | drm_local_map_t *sarea; |
| 118 | struct _drm_i915_sarea *sarea_priv; | 121 | struct _drm_i915_sarea *sarea_priv; |
| @@ -166,6 +169,7 @@ struct drm_i915_error_state { | |||
| 166 | u32 purgeable:1; | 169 | u32 purgeable:1; |
| 167 | } *active_bo; | 170 | } *active_bo; |
| 168 | u32 active_bo_count; | 171 | u32 active_bo_count; |
| 172 | struct intel_overlay_error_state *overlay; | ||
| 169 | }; | 173 | }; |
| 170 | 174 | ||
| 171 | struct drm_i915_display_funcs { | 175 | struct drm_i915_display_funcs { |
| @@ -186,8 +190,6 @@ struct drm_i915_display_funcs { | |||
| 186 | /* clock gating init */ | 190 | /* clock gating init */ |
| 187 | }; | 191 | }; |
| 188 | 192 | ||
| 189 | struct intel_overlay; | ||
| 190 | |||
| 191 | struct intel_device_info { | 193 | struct intel_device_info { |
| 192 | u8 is_mobile : 1; | 194 | u8 is_mobile : 1; |
| 193 | u8 is_i8xx : 1; | 195 | u8 is_i8xx : 1; |
| @@ -242,6 +244,7 @@ typedef struct drm_i915_private { | |||
| 242 | struct pci_dev *bridge_dev; | 244 | struct pci_dev *bridge_dev; |
| 243 | struct intel_ring_buffer render_ring; | 245 | struct intel_ring_buffer render_ring; |
| 244 | struct intel_ring_buffer bsd_ring; | 246 | struct intel_ring_buffer bsd_ring; |
| 247 | uint32_t next_seqno; | ||
| 245 | 248 | ||
| 246 | drm_dma_handle_t *status_page_dmah; | 249 | drm_dma_handle_t *status_page_dmah; |
| 247 | void *seqno_page; | 250 | void *seqno_page; |
| @@ -251,6 +254,7 @@ typedef struct drm_i915_private { | |||
| 251 | drm_local_map_t hws_map; | 254 | drm_local_map_t hws_map; |
| 252 | struct drm_gem_object *seqno_obj; | 255 | struct drm_gem_object *seqno_obj; |
| 253 | struct drm_gem_object *pwrctx; | 256 | struct drm_gem_object *pwrctx; |
| 257 | struct drm_gem_object *renderctx; | ||
| 254 | 258 | ||
| 255 | struct resource mch_res; | 259 | struct resource mch_res; |
| 256 | 260 | ||
| @@ -285,6 +289,9 @@ typedef struct drm_i915_private { | |||
| 285 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; | 289 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; |
| 286 | int vblank_pipe; | 290 | int vblank_pipe; |
| 287 | int num_pipe; | 291 | int num_pipe; |
| 292 | u32 flush_rings; | ||
| 293 | #define FLUSH_RENDER_RING 0x1 | ||
| 294 | #define FLUSH_BSD_RING 0x2 | ||
| 288 | 295 | ||
| 289 | /* For hangcheck timer */ | 296 | /* For hangcheck timer */ |
| 290 | #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */ | 297 | #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */ |
| @@ -568,8 +575,6 @@ typedef struct drm_i915_private { | |||
| 568 | */ | 575 | */ |
| 569 | struct delayed_work retire_work; | 576 | struct delayed_work retire_work; |
| 570 | 577 | ||
| 571 | uint32_t next_gem_seqno; | ||
| 572 | |||
| 573 | /** | 578 | /** |
| 574 | * Waiting sequence number, if any | 579 | * Waiting sequence number, if any |
| 575 | */ | 580 | */ |
| @@ -610,6 +615,8 @@ typedef struct drm_i915_private { | |||
| 610 | struct sdvo_device_mapping sdvo_mappings[2]; | 615 | struct sdvo_device_mapping sdvo_mappings[2]; |
| 611 | /* indicate whether the LVDS_BORDER should be enabled or not */ | 616 | /* indicate whether the LVDS_BORDER should be enabled or not */ |
| 612 | unsigned int lvds_border_bits; | 617 | unsigned int lvds_border_bits; |
| 618 | /* Panel fitter placement and size for Ironlake+ */ | ||
| 619 | u32 pch_pf_pos, pch_pf_size; | ||
| 613 | 620 | ||
| 614 | struct drm_crtc *plane_to_crtc_mapping[2]; | 621 | struct drm_crtc *plane_to_crtc_mapping[2]; |
| 615 | struct drm_crtc *pipe_to_crtc_mapping[2]; | 622 | struct drm_crtc *pipe_to_crtc_mapping[2]; |
| @@ -669,6 +676,8 @@ struct drm_i915_gem_object { | |||
| 669 | struct list_head list; | 676 | struct list_head list; |
| 670 | /** This object's place on GPU write list */ | 677 | /** This object's place on GPU write list */ |
| 671 | struct list_head gpu_write_list; | 678 | struct list_head gpu_write_list; |
| 679 | /** This object's place on eviction list */ | ||
| 680 | struct list_head evict_list; | ||
| 672 | 681 | ||
| 673 | /** | 682 | /** |
| 674 | * This is set if the object is on the active or flushing lists | 683 | * This is set if the object is on the active or flushing lists |
| @@ -978,6 +987,7 @@ int i915_gem_init_ringbuffer(struct drm_device *dev); | |||
| 978 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); | 987 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); |
| 979 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, | 988 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, |
| 980 | unsigned long end); | 989 | unsigned long end); |
| 990 | int i915_gpu_idle(struct drm_device *dev); | ||
| 981 | int i915_gem_idle(struct drm_device *dev); | 991 | int i915_gem_idle(struct drm_device *dev); |
| 982 | uint32_t i915_add_request(struct drm_device *dev, | 992 | uint32_t i915_add_request(struct drm_device *dev, |
| 983 | struct drm_file *file_priv, | 993 | struct drm_file *file_priv, |
| @@ -991,7 +1001,9 @@ int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, | |||
| 991 | int write); | 1001 | int write); |
| 992 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj); | 1002 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj); |
| 993 | int i915_gem_attach_phys_object(struct drm_device *dev, | 1003 | int i915_gem_attach_phys_object(struct drm_device *dev, |
| 994 | struct drm_gem_object *obj, int id); | 1004 | struct drm_gem_object *obj, |
| 1005 | int id, | ||
| 1006 | int align); | ||
| 995 | void i915_gem_detach_phys_object(struct drm_device *dev, | 1007 | void i915_gem_detach_phys_object(struct drm_device *dev, |
| 996 | struct drm_gem_object *obj); | 1008 | struct drm_gem_object *obj); |
| 997 | void i915_gem_free_all_phys_object(struct drm_device *dev); | 1009 | void i915_gem_free_all_phys_object(struct drm_device *dev); |
| @@ -1003,6 +1015,11 @@ int i915_gem_object_flush_write_domain(struct drm_gem_object *obj); | |||
| 1003 | void i915_gem_shrinker_init(void); | 1015 | void i915_gem_shrinker_init(void); |
| 1004 | void i915_gem_shrinker_exit(void); | 1016 | void i915_gem_shrinker_exit(void); |
| 1005 | 1017 | ||
| 1018 | /* i915_gem_evict.c */ | ||
| 1019 | int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment); | ||
| 1020 | int i915_gem_evict_everything(struct drm_device *dev); | ||
| 1021 | int i915_gem_evict_inactive(struct drm_device *dev); | ||
| 1022 | |||
| 1006 | /* i915_gem_tiling.c */ | 1023 | /* i915_gem_tiling.c */ |
| 1007 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); | 1024 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); |
| 1008 | void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); | 1025 | void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); |
| @@ -1066,6 +1083,10 @@ extern bool ironlake_set_drps(struct drm_device *dev, u8 val); | |||
| 1066 | extern void intel_detect_pch (struct drm_device *dev); | 1083 | extern void intel_detect_pch (struct drm_device *dev); |
| 1067 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | 1084 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); |
| 1068 | 1085 | ||
| 1086 | /* overlay */ | ||
| 1087 | extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); | ||
| 1088 | extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); | ||
| 1089 | |||
| 1069 | /** | 1090 | /** |
| 1070 | * Lock test for when it's just for synchronization of ring access. | 1091 | * Lock test for when it's just for synchronization of ring access. |
| 1071 | * | 1092 | * |
| @@ -1092,26 +1113,26 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
| 1092 | #define I915_VERBOSE 0 | 1113 | #define I915_VERBOSE 0 |
| 1093 | 1114 | ||
| 1094 | #define BEGIN_LP_RING(n) do { \ | 1115 | #define BEGIN_LP_RING(n) do { \ |
| 1095 | drm_i915_private_t *dev_priv = dev->dev_private; \ | 1116 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ |
| 1096 | if (I915_VERBOSE) \ | 1117 | if (I915_VERBOSE) \ |
| 1097 | DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ | 1118 | DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ |
| 1098 | intel_ring_begin(dev, &dev_priv->render_ring, (n)); \ | 1119 | intel_ring_begin(dev, &dev_priv__->render_ring, (n)); \ |
| 1099 | } while (0) | 1120 | } while (0) |
| 1100 | 1121 | ||
| 1101 | 1122 | ||
| 1102 | #define OUT_RING(x) do { \ | 1123 | #define OUT_RING(x) do { \ |
| 1103 | drm_i915_private_t *dev_priv = dev->dev_private; \ | 1124 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ |
| 1104 | if (I915_VERBOSE) \ | 1125 | if (I915_VERBOSE) \ |
| 1105 | DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ | 1126 | DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ |
| 1106 | intel_ring_emit(dev, &dev_priv->render_ring, x); \ | 1127 | intel_ring_emit(dev, &dev_priv__->render_ring, x); \ |
| 1107 | } while (0) | 1128 | } while (0) |
| 1108 | 1129 | ||
| 1109 | #define ADVANCE_LP_RING() do { \ | 1130 | #define ADVANCE_LP_RING() do { \ |
| 1110 | drm_i915_private_t *dev_priv = dev->dev_private; \ | 1131 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ |
| 1111 | if (I915_VERBOSE) \ | 1132 | if (I915_VERBOSE) \ |
| 1112 | DRM_DEBUG("ADVANCE_LP_RING %x\n", \ | 1133 | DRM_DEBUG("ADVANCE_LP_RING %x\n", \ |
| 1113 | dev_priv->render_ring.tail); \ | 1134 | dev_priv__->render_ring.tail); \ |
| 1114 | intel_ring_advance(dev, &dev_priv->render_ring); \ | 1135 | intel_ring_advance(dev, &dev_priv__->render_ring); \ |
| 1115 | } while(0) | 1136 | } while(0) |
| 1116 | 1137 | ||
| 1117 | /** | 1138 | /** |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0758c7802e6..df5a7135c26 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/swap.h> | 35 | #include <linux/swap.h> |
| 36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
| 37 | 37 | ||
| 38 | static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); | ||
| 38 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); | 39 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); |
| 39 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); | 40 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); |
| 40 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); | 41 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); |
| @@ -48,8 +49,6 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); | |||
| 48 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 49 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, |
| 49 | unsigned alignment); | 50 | unsigned alignment); |
| 50 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); | 51 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); |
| 51 | static int i915_gem_evict_something(struct drm_device *dev, int min_size); | ||
| 52 | static int i915_gem_evict_from_inactive_list(struct drm_device *dev); | ||
| 53 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | 52 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, |
| 54 | struct drm_i915_gem_pwrite *args, | 53 | struct drm_i915_gem_pwrite *args, |
| 55 | struct drm_file *file_priv); | 54 | struct drm_file *file_priv); |
| @@ -58,6 +57,14 @@ static void i915_gem_free_object_tail(struct drm_gem_object *obj); | |||
| 58 | static LIST_HEAD(shrink_list); | 57 | static LIST_HEAD(shrink_list); |
| 59 | static DEFINE_SPINLOCK(shrink_list_lock); | 58 | static DEFINE_SPINLOCK(shrink_list_lock); |
| 60 | 59 | ||
| 60 | static inline bool | ||
| 61 | i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv) | ||
| 62 | { | ||
| 63 | return obj_priv->gtt_space && | ||
| 64 | !obj_priv->active && | ||
| 65 | obj_priv->pin_count == 0; | ||
| 66 | } | ||
| 67 | |||
| 61 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, | 68 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, |
| 62 | unsigned long end) | 69 | unsigned long end) |
| 63 | { | 70 | { |
| @@ -313,7 +320,8 @@ i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) | |||
| 313 | if (ret == -ENOMEM) { | 320 | if (ret == -ENOMEM) { |
| 314 | struct drm_device *dev = obj->dev; | 321 | struct drm_device *dev = obj->dev; |
| 315 | 322 | ||
| 316 | ret = i915_gem_evict_something(dev, obj->size); | 323 | ret = i915_gem_evict_something(dev, obj->size, |
| 324 | i915_gem_get_gtt_alignment(obj)); | ||
| 317 | if (ret) | 325 | if (ret) |
| 318 | return ret; | 326 | return ret; |
| 319 | 327 | ||
| @@ -1036,6 +1044,11 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
| 1036 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); | 1044 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); |
| 1037 | } | 1045 | } |
| 1038 | 1046 | ||
| 1047 | |||
| 1048 | /* Maintain LRU order of "inactive" objects */ | ||
| 1049 | if (ret == 0 && i915_gem_object_is_inactive(obj_priv)) | ||
| 1050 | list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
| 1051 | |||
| 1039 | drm_gem_object_unreference(obj); | 1052 | drm_gem_object_unreference(obj); |
| 1040 | mutex_unlock(&dev->struct_mutex); | 1053 | mutex_unlock(&dev->struct_mutex); |
| 1041 | return ret; | 1054 | return ret; |
| @@ -1137,7 +1150,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 1137 | { | 1150 | { |
| 1138 | struct drm_gem_object *obj = vma->vm_private_data; | 1151 | struct drm_gem_object *obj = vma->vm_private_data; |
| 1139 | struct drm_device *dev = obj->dev; | 1152 | struct drm_device *dev = obj->dev; |
| 1140 | struct drm_i915_private *dev_priv = dev->dev_private; | 1153 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 1141 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1154 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
| 1142 | pgoff_t page_offset; | 1155 | pgoff_t page_offset; |
| 1143 | unsigned long pfn; | 1156 | unsigned long pfn; |
| @@ -1155,8 +1168,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 1155 | if (ret) | 1168 | if (ret) |
| 1156 | goto unlock; | 1169 | goto unlock; |
| 1157 | 1170 | ||
| 1158 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
| 1159 | |||
| 1160 | ret = i915_gem_object_set_to_gtt_domain(obj, write); | 1171 | ret = i915_gem_object_set_to_gtt_domain(obj, write); |
| 1161 | if (ret) | 1172 | if (ret) |
| 1162 | goto unlock; | 1173 | goto unlock; |
| @@ -1169,6 +1180,9 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 1169 | goto unlock; | 1180 | goto unlock; |
| 1170 | } | 1181 | } |
| 1171 | 1182 | ||
| 1183 | if (i915_gem_object_is_inactive(obj_priv)) | ||
| 1184 | list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
| 1185 | |||
| 1172 | pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + | 1186 | pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + |
| 1173 | page_offset; | 1187 | page_offset; |
| 1174 | 1188 | ||
| @@ -1363,7 +1377,6 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
| 1363 | struct drm_file *file_priv) | 1377 | struct drm_file *file_priv) |
| 1364 | { | 1378 | { |
| 1365 | struct drm_i915_gem_mmap_gtt *args = data; | 1379 | struct drm_i915_gem_mmap_gtt *args = data; |
| 1366 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1367 | struct drm_gem_object *obj; | 1380 | struct drm_gem_object *obj; |
| 1368 | struct drm_i915_gem_object *obj_priv; | 1381 | struct drm_i915_gem_object *obj_priv; |
| 1369 | int ret; | 1382 | int ret; |
| @@ -1409,7 +1422,6 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
| 1409 | mutex_unlock(&dev->struct_mutex); | 1422 | mutex_unlock(&dev->struct_mutex); |
| 1410 | return ret; | 1423 | return ret; |
| 1411 | } | 1424 | } |
| 1412 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
| 1413 | } | 1425 | } |
| 1414 | 1426 | ||
| 1415 | drm_gem_object_unreference(obj); | 1427 | drm_gem_object_unreference(obj); |
| @@ -1493,9 +1505,16 @@ i915_gem_object_truncate(struct drm_gem_object *obj) | |||
| 1493 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1505 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
| 1494 | struct inode *inode; | 1506 | struct inode *inode; |
| 1495 | 1507 | ||
| 1508 | /* Our goal here is to return as much of the memory as | ||
| 1509 | * is possible back to the system as we are called from OOM. | ||
| 1510 | * To do this we must instruct the shmfs to drop all of its | ||
| 1511 | * backing pages, *now*. Here we mirror the actions taken | ||
| 1512 | * when by shmem_delete_inode() to release the backing store. | ||
| 1513 | */ | ||
| 1496 | inode = obj->filp->f_path.dentry->d_inode; | 1514 | inode = obj->filp->f_path.dentry->d_inode; |
| 1497 | if (inode->i_op->truncate) | 1515 | truncate_inode_pages(inode->i_mapping, 0); |
| 1498 | inode->i_op->truncate (inode); | 1516 | if (inode->i_op->truncate_range) |
| 1517 | inode->i_op->truncate_range(inode, 0, (loff_t)-1); | ||
| 1499 | 1518 | ||
| 1500 | obj_priv->madv = __I915_MADV_PURGED; | 1519 | obj_priv->madv = __I915_MADV_PURGED; |
| 1501 | } | 1520 | } |
| @@ -1887,19 +1906,6 @@ i915_gem_flush(struct drm_device *dev, | |||
| 1887 | flush_domains); | 1906 | flush_domains); |
| 1888 | } | 1907 | } |
| 1889 | 1908 | ||
| 1890 | static void | ||
| 1891 | i915_gem_flush_ring(struct drm_device *dev, | ||
| 1892 | uint32_t invalidate_domains, | ||
| 1893 | uint32_t flush_domains, | ||
| 1894 | struct intel_ring_buffer *ring) | ||
| 1895 | { | ||
| 1896 | if (flush_domains & I915_GEM_DOMAIN_CPU) | ||
| 1897 | drm_agp_chipset_flush(dev); | ||
| 1898 | ring->flush(dev, ring, | ||
| 1899 | invalidate_domains, | ||
| 1900 | flush_domains); | ||
| 1901 | } | ||
| 1902 | |||
| 1903 | /** | 1909 | /** |
| 1904 | * Ensures that all rendering to the object has completed and the object is | 1910 | * Ensures that all rendering to the object has completed and the object is |
| 1905 | * safe to unbind from the GTT or access from the CPU. | 1911 | * safe to unbind from the GTT or access from the CPU. |
| @@ -1973,8 +1979,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
| 1973 | * cause memory corruption through use-after-free. | 1979 | * cause memory corruption through use-after-free. |
| 1974 | */ | 1980 | */ |
| 1975 | 1981 | ||
| 1976 | BUG_ON(obj_priv->active); | ||
| 1977 | |||
| 1978 | /* release the fence reg _after_ flushing */ | 1982 | /* release the fence reg _after_ flushing */ |
| 1979 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 1983 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
| 1980 | i915_gem_clear_fence_reg(obj); | 1984 | i915_gem_clear_fence_reg(obj); |
| @@ -2010,34 +2014,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
| 2010 | return ret; | 2014 | return ret; |
| 2011 | } | 2015 | } |
| 2012 | 2016 | ||
| 2013 | static struct drm_gem_object * | 2017 | int |
| 2014 | i915_gem_find_inactive_object(struct drm_device *dev, int min_size) | ||
| 2015 | { | ||
| 2016 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 2017 | struct drm_i915_gem_object *obj_priv; | ||
| 2018 | struct drm_gem_object *best = NULL; | ||
| 2019 | struct drm_gem_object *first = NULL; | ||
| 2020 | |||
| 2021 | /* Try to find the smallest clean object */ | ||
| 2022 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
| 2023 | struct drm_gem_object *obj = &obj_priv->base; | ||
| 2024 | if (obj->size >= min_size) { | ||
| 2025 | if ((!obj_priv->dirty || | ||
| 2026 | i915_gem_object_is_purgeable(obj_priv)) && | ||
| 2027 | (!best || obj->size < best->size)) { | ||
| 2028 | best = obj; | ||
| 2029 | if (best->size == min_size) | ||
| 2030 | return best; | ||
| 2031 | } | ||
| 2032 | if (!first) | ||
| 2033 | first = obj; | ||
| 2034 | } | ||
| 2035 | } | ||
| 2036 | |||
| 2037 | return best ? best : first; | ||
| 2038 | } | ||
| 2039 | |||
| 2040 | static int | ||
| 2041 | i915_gpu_idle(struct drm_device *dev) | 2018 | i915_gpu_idle(struct drm_device *dev) |
| 2042 | { | 2019 | { |
| 2043 | drm_i915_private_t *dev_priv = dev->dev_private; | 2020 | drm_i915_private_t *dev_priv = dev->dev_private; |
| @@ -2078,155 +2055,6 @@ i915_gpu_idle(struct drm_device *dev) | |||
| 2078 | return ret; | 2055 | return ret; |
| 2079 | } | 2056 | } |
| 2080 | 2057 | ||
| 2081 | static int | ||
| 2082 | i915_gem_evict_everything(struct drm_device *dev) | ||
| 2083 | { | ||
| 2084 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 2085 | int ret; | ||
| 2086 | bool lists_empty; | ||
| 2087 | |||
| 2088 | spin_lock(&dev_priv->mm.active_list_lock); | ||
| 2089 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
| 2090 | list_empty(&dev_priv->mm.flushing_list) && | ||
| 2091 | list_empty(&dev_priv->render_ring.active_list) && | ||
| 2092 | (!HAS_BSD(dev) | ||
| 2093 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
| 2094 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
| 2095 | |||
| 2096 | if (lists_empty) | ||
| 2097 | return -ENOSPC; | ||
| 2098 | |||
| 2099 | /* Flush everything (on to the inactive lists) and evict */ | ||
| 2100 | ret = i915_gpu_idle(dev); | ||
| 2101 | if (ret) | ||
| 2102 | return ret; | ||
| 2103 | |||
| 2104 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
| 2105 | |||
| 2106 | ret = i915_gem_evict_from_inactive_list(dev); | ||
| 2107 | if (ret) | ||
| 2108 | return ret; | ||
| 2109 | |||
| 2110 | spin_lock(&dev_priv->mm.active_list_lock); | ||
| 2111 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
| 2112 | list_empty(&dev_priv->mm.flushing_list) && | ||
| 2113 | list_empty(&dev_priv->render_ring.active_list) && | ||
| 2114 | (!HAS_BSD(dev) | ||
| 2115 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
| 2116 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
| 2117 | BUG_ON(!lists_empty); | ||
| 2118 | |||
| 2119 | return 0; | ||
| 2120 | } | ||
| 2121 | |||
| 2122 | static int | ||
| 2123 | i915_gem_evict_something(struct drm_device *dev, int min_size) | ||
| 2124 | { | ||
| 2125 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 2126 | struct drm_gem_object *obj; | ||
| 2127 | int ret; | ||
| 2128 | |||
| 2129 | struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | ||
| 2130 | struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring; | ||
| 2131 | for (;;) { | ||
| 2132 | i915_gem_retire_requests(dev); | ||
| 2133 | |||
| 2134 | /* If there's an inactive buffer available now, grab it | ||
| 2135 | * and be done. | ||
| 2136 | */ | ||
| 2137 | obj = i915_gem_find_inactive_object(dev, min_size); | ||
| 2138 | if (obj) { | ||
| 2139 | struct drm_i915_gem_object *obj_priv; | ||
| 2140 | |||
| 2141 | #if WATCH_LRU | ||
| 2142 | DRM_INFO("%s: evicting %p\n", __func__, obj); | ||
| 2143 | #endif | ||
| 2144 | obj_priv = to_intel_bo(obj); | ||
| 2145 | BUG_ON(obj_priv->pin_count != 0); | ||
| 2146 | BUG_ON(obj_priv->active); | ||
| 2147 | |||
| 2148 | /* Wait on the rendering and unbind the buffer. */ | ||
| 2149 | return i915_gem_object_unbind(obj); | ||
| 2150 | } | ||
| 2151 | |||
| 2152 | /* If we didn't get anything, but the ring is still processing | ||
| 2153 | * things, wait for the next to finish and hopefully leave us | ||
| 2154 | * a buffer to evict. | ||
| 2155 | */ | ||
| 2156 | if (!list_empty(&render_ring->request_list)) { | ||
| 2157 | struct drm_i915_gem_request *request; | ||
| 2158 | |||
| 2159 | request = list_first_entry(&render_ring->request_list, | ||
| 2160 | struct drm_i915_gem_request, | ||
| 2161 | list); | ||
| 2162 | |||
| 2163 | ret = i915_wait_request(dev, | ||
| 2164 | request->seqno, request->ring); | ||
| 2165 | if (ret) | ||
| 2166 | return ret; | ||
| 2167 | |||
| 2168 | continue; | ||
| 2169 | } | ||
| 2170 | |||
| 2171 | if (HAS_BSD(dev) && !list_empty(&bsd_ring->request_list)) { | ||
| 2172 | struct drm_i915_gem_request *request; | ||
| 2173 | |||
| 2174 | request = list_first_entry(&bsd_ring->request_list, | ||
| 2175 | struct drm_i915_gem_request, | ||
| 2176 | list); | ||
| 2177 | |||
| 2178 | ret = i915_wait_request(dev, | ||
| 2179 | request->seqno, request->ring); | ||
| 2180 | if (ret) | ||
| 2181 | return ret; | ||
| 2182 | |||
| 2183 | continue; | ||
| 2184 | } | ||
| 2185 | |||
| 2186 | /* If we didn't have anything on the request list but there | ||
| 2187 | * are buffers awaiting a flush, emit one and try again. | ||
| 2188 | * When we wait on it, those buffers waiting for that flush | ||
| 2189 | * will get moved to inactive. | ||
| 2190 | */ | ||
| 2191 | if (!list_empty(&dev_priv->mm.flushing_list)) { | ||
| 2192 | struct drm_i915_gem_object *obj_priv; | ||
| 2193 | |||
| 2194 | /* Find an object that we can immediately reuse */ | ||
| 2195 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { | ||
| 2196 | obj = &obj_priv->base; | ||
| 2197 | if (obj->size >= min_size) | ||
| 2198 | break; | ||
| 2199 | |||
| 2200 | obj = NULL; | ||
| 2201 | } | ||
| 2202 | |||
| 2203 | if (obj != NULL) { | ||
| 2204 | uint32_t seqno; | ||
| 2205 | |||
| 2206 | i915_gem_flush_ring(dev, | ||
| 2207 | obj->write_domain, | ||
| 2208 | obj->write_domain, | ||
| 2209 | obj_priv->ring); | ||
| 2210 | seqno = i915_add_request(dev, NULL, | ||
| 2211 | obj->write_domain, | ||
| 2212 | obj_priv->ring); | ||
| 2213 | if (seqno == 0) | ||
| 2214 | return -ENOMEM; | ||
| 2215 | continue; | ||
| 2216 | } | ||
| 2217 | } | ||
| 2218 | |||
| 2219 | /* If we didn't do any of the above, there's no single buffer | ||
| 2220 | * large enough to swap out for the new one, so just evict | ||
| 2221 | * everything and start again. (This should be rare.) | ||
| 2222 | */ | ||
| 2223 | if (!list_empty (&dev_priv->mm.inactive_list)) | ||
| 2224 | return i915_gem_evict_from_inactive_list(dev); | ||
| 2225 | else | ||
| 2226 | return i915_gem_evict_everything(dev); | ||
| 2227 | } | ||
| 2228 | } | ||
| 2229 | |||
| 2230 | int | 2058 | int |
| 2231 | i915_gem_object_get_pages(struct drm_gem_object *obj, | 2059 | i915_gem_object_get_pages(struct drm_gem_object *obj, |
| 2232 | gfp_t gfpmask) | 2060 | gfp_t gfpmask) |
| @@ -2666,7 +2494,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
| 2666 | #if WATCH_LRU | 2494 | #if WATCH_LRU |
| 2667 | DRM_INFO("%s: GTT full, evicting something\n", __func__); | 2495 | DRM_INFO("%s: GTT full, evicting something\n", __func__); |
| 2668 | #endif | 2496 | #endif |
| 2669 | ret = i915_gem_evict_something(dev, obj->size); | 2497 | ret = i915_gem_evict_something(dev, obj->size, alignment); |
| 2670 | if (ret) | 2498 | if (ret) |
| 2671 | return ret; | 2499 | return ret; |
| 2672 | 2500 | ||
| @@ -2684,7 +2512,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
| 2684 | 2512 | ||
| 2685 | if (ret == -ENOMEM) { | 2513 | if (ret == -ENOMEM) { |
| 2686 | /* first try to clear up some space from the GTT */ | 2514 | /* first try to clear up some space from the GTT */ |
| 2687 | ret = i915_gem_evict_something(dev, obj->size); | 2515 | ret = i915_gem_evict_something(dev, obj->size, |
| 2516 | alignment); | ||
| 2688 | if (ret) { | 2517 | if (ret) { |
| 2689 | /* now try to shrink everyone else */ | 2518 | /* now try to shrink everyone else */ |
| 2690 | if (gfpmask) { | 2519 | if (gfpmask) { |
| @@ -2714,7 +2543,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
| 2714 | drm_mm_put_block(obj_priv->gtt_space); | 2543 | drm_mm_put_block(obj_priv->gtt_space); |
| 2715 | obj_priv->gtt_space = NULL; | 2544 | obj_priv->gtt_space = NULL; |
| 2716 | 2545 | ||
| 2717 | ret = i915_gem_evict_something(dev, obj->size); | 2546 | ret = i915_gem_evict_something(dev, obj->size, alignment); |
| 2718 | if (ret) | 2547 | if (ret) |
| 2719 | return ret; | 2548 | return ret; |
| 2720 | 2549 | ||
| @@ -2723,6 +2552,9 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
| 2723 | atomic_inc(&dev->gtt_count); | 2552 | atomic_inc(&dev->gtt_count); |
| 2724 | atomic_add(obj->size, &dev->gtt_memory); | 2553 | atomic_add(obj->size, &dev->gtt_memory); |
| 2725 | 2554 | ||
| 2555 | /* keep track of bounds object by adding it to the inactive list */ | ||
| 2556 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
| 2557 | |||
| 2726 | /* Assert that the object is not currently in any GPU domain. As it | 2558 | /* Assert that the object is not currently in any GPU domain. As it |
| 2727 | * wasn't in the GTT, there shouldn't be any way it could have been in | 2559 | * wasn't in the GTT, there shouldn't be any way it could have been in |
| 2728 | * a GPU cache | 2560 | * a GPU cache |
| @@ -3117,6 +2949,7 @@ static void | |||
| 3117 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | 2949 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) |
| 3118 | { | 2950 | { |
| 3119 | struct drm_device *dev = obj->dev; | 2951 | struct drm_device *dev = obj->dev; |
| 2952 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 3120 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2953 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
| 3121 | uint32_t invalidate_domains = 0; | 2954 | uint32_t invalidate_domains = 0; |
| 3122 | uint32_t flush_domains = 0; | 2955 | uint32_t flush_domains = 0; |
| @@ -3179,6 +3012,13 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | |||
| 3179 | obj->pending_write_domain = obj->write_domain; | 3012 | obj->pending_write_domain = obj->write_domain; |
| 3180 | obj->read_domains = obj->pending_read_domains; | 3013 | obj->read_domains = obj->pending_read_domains; |
| 3181 | 3014 | ||
| 3015 | if (flush_domains & I915_GEM_GPU_DOMAINS) { | ||
| 3016 | if (obj_priv->ring == &dev_priv->render_ring) | ||
| 3017 | dev_priv->flush_rings |= FLUSH_RENDER_RING; | ||
| 3018 | else if (obj_priv->ring == &dev_priv->bsd_ring) | ||
| 3019 | dev_priv->flush_rings |= FLUSH_BSD_RING; | ||
| 3020 | } | ||
| 3021 | |||
| 3182 | dev->invalidate_domains |= invalidate_domains; | 3022 | dev->invalidate_domains |= invalidate_domains; |
| 3183 | dev->flush_domains |= flush_domains; | 3023 | dev->flush_domains |= flush_domains; |
| 3184 | #if WATCH_BUF | 3024 | #if WATCH_BUF |
| @@ -3718,7 +3558,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 3718 | ring = &dev_priv->render_ring; | 3558 | ring = &dev_priv->render_ring; |
| 3719 | } | 3559 | } |
| 3720 | 3560 | ||
| 3721 | |||
| 3722 | if (args->buffer_count < 1) { | 3561 | if (args->buffer_count < 1) { |
| 3723 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | 3562 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); |
| 3724 | return -EINVAL; | 3563 | return -EINVAL; |
| @@ -3892,6 +3731,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 3892 | */ | 3731 | */ |
| 3893 | dev->invalidate_domains = 0; | 3732 | dev->invalidate_domains = 0; |
| 3894 | dev->flush_domains = 0; | 3733 | dev->flush_domains = 0; |
| 3734 | dev_priv->flush_rings = 0; | ||
| 3895 | 3735 | ||
| 3896 | for (i = 0; i < args->buffer_count; i++) { | 3736 | for (i = 0; i < args->buffer_count; i++) { |
| 3897 | struct drm_gem_object *obj = object_list[i]; | 3737 | struct drm_gem_object *obj = object_list[i]; |
| @@ -3912,16 +3752,14 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 3912 | i915_gem_flush(dev, | 3752 | i915_gem_flush(dev, |
| 3913 | dev->invalidate_domains, | 3753 | dev->invalidate_domains, |
| 3914 | dev->flush_domains); | 3754 | dev->flush_domains); |
| 3915 | if (dev->flush_domains & I915_GEM_GPU_DOMAINS) { | 3755 | if (dev_priv->flush_rings & FLUSH_RENDER_RING) |
| 3916 | (void)i915_add_request(dev, file_priv, | 3756 | (void)i915_add_request(dev, file_priv, |
| 3917 | dev->flush_domains, | 3757 | dev->flush_domains, |
| 3918 | &dev_priv->render_ring); | 3758 | &dev_priv->render_ring); |
| 3919 | 3759 | if (dev_priv->flush_rings & FLUSH_BSD_RING) | |
| 3920 | if (HAS_BSD(dev)) | 3760 | (void)i915_add_request(dev, file_priv, |
| 3921 | (void)i915_add_request(dev, file_priv, | 3761 | dev->flush_domains, |
| 3922 | dev->flush_domains, | 3762 | &dev_priv->bsd_ring); |
| 3923 | &dev_priv->bsd_ring); | ||
| 3924 | } | ||
| 3925 | } | 3763 | } |
| 3926 | 3764 | ||
| 3927 | for (i = 0; i < args->buffer_count; i++) { | 3765 | for (i = 0; i < args->buffer_count; i++) { |
| @@ -4192,6 +4030,10 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
| 4192 | if (alignment == 0) | 4030 | if (alignment == 0) |
| 4193 | alignment = i915_gem_get_gtt_alignment(obj); | 4031 | alignment = i915_gem_get_gtt_alignment(obj); |
| 4194 | if (obj_priv->gtt_offset & (alignment - 1)) { | 4032 | if (obj_priv->gtt_offset & (alignment - 1)) { |
| 4033 | WARN(obj_priv->pin_count, | ||
| 4034 | "bo is already pinned with incorrect alignment:" | ||
| 4035 | " offset=%x, req.alignment=%x\n", | ||
| 4036 | obj_priv->gtt_offset, alignment); | ||
| 4195 | ret = i915_gem_object_unbind(obj); | 4037 | ret = i915_gem_object_unbind(obj); |
| 4196 | if (ret) | 4038 | if (ret) |
| 4197 | return ret; | 4039 | return ret; |
| @@ -4213,8 +4055,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
| 4213 | atomic_inc(&dev->pin_count); | 4055 | atomic_inc(&dev->pin_count); |
| 4214 | atomic_add(obj->size, &dev->pin_memory); | 4056 | atomic_add(obj->size, &dev->pin_memory); |
| 4215 | if (!obj_priv->active && | 4057 | if (!obj_priv->active && |
| 4216 | (obj->write_domain & I915_GEM_GPU_DOMAINS) == 0 && | 4058 | (obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) |
| 4217 | !list_empty(&obj_priv->list)) | ||
| 4218 | list_del_init(&obj_priv->list); | 4059 | list_del_init(&obj_priv->list); |
| 4219 | } | 4060 | } |
| 4220 | i915_verify_inactive(dev, __FILE__, __LINE__); | 4061 | i915_verify_inactive(dev, __FILE__, __LINE__); |
| @@ -4359,22 +4200,34 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
| 4359 | } | 4200 | } |
| 4360 | 4201 | ||
| 4361 | mutex_lock(&dev->struct_mutex); | 4202 | mutex_lock(&dev->struct_mutex); |
| 4362 | /* Update the active list for the hardware's current position. | ||
| 4363 | * Otherwise this only updates on a delayed timer or when irqs are | ||
| 4364 | * actually unmasked, and our working set ends up being larger than | ||
| 4365 | * required. | ||
| 4366 | */ | ||
| 4367 | i915_gem_retire_requests(dev); | ||
| 4368 | 4203 | ||
| 4369 | obj_priv = to_intel_bo(obj); | 4204 | /* Count all active objects as busy, even if they are currently not used |
| 4370 | /* Don't count being on the flushing list against the object being | 4205 | * by the gpu. Users of this interface expect objects to eventually |
| 4371 | * done. Otherwise, a buffer left on the flushing list but not getting | 4206 | * become non-busy without any further actions, therefore emit any |
| 4372 | * flushed (because nobody's flushing that domain) won't ever return | 4207 | * necessary flushes here. |
| 4373 | * unbusy and get reused by libdrm's bo cache. The other expected | ||
| 4374 | * consumer of this interface, OpenGL's occlusion queries, also specs | ||
| 4375 | * that the objects get unbusy "eventually" without any interference. | ||
| 4376 | */ | 4208 | */ |
| 4377 | args->busy = obj_priv->active && obj_priv->last_rendering_seqno != 0; | 4209 | obj_priv = to_intel_bo(obj); |
| 4210 | args->busy = obj_priv->active; | ||
| 4211 | if (args->busy) { | ||
| 4212 | /* Unconditionally flush objects, even when the gpu still uses this | ||
| 4213 | * object. Userspace calling this function indicates that it wants to | ||
| 4214 | * use this buffer rather sooner than later, so issuing the required | ||
| 4215 | * flush earlier is beneficial. | ||
| 4216 | */ | ||
| 4217 | if (obj->write_domain) { | ||
| 4218 | i915_gem_flush(dev, 0, obj->write_domain); | ||
| 4219 | (void)i915_add_request(dev, file_priv, obj->write_domain, obj_priv->ring); | ||
| 4220 | } | ||
| 4221 | |||
| 4222 | /* Update the active list for the hardware's current position. | ||
| 4223 | * Otherwise this only updates on a delayed timer or when irqs | ||
| 4224 | * are actually unmasked, and our working set ends up being | ||
| 4225 | * larger than required. | ||
| 4226 | */ | ||
| 4227 | i915_gem_retire_requests_ring(dev, obj_priv->ring); | ||
| 4228 | |||
| 4229 | args->busy = obj_priv->active; | ||
| 4230 | } | ||
| 4378 | 4231 | ||
| 4379 | drm_gem_object_unreference(obj); | 4232 | drm_gem_object_unreference(obj); |
| 4380 | mutex_unlock(&dev->struct_mutex); | 4233 | mutex_unlock(&dev->struct_mutex); |
| @@ -4514,30 +4367,6 @@ void i915_gem_free_object(struct drm_gem_object *obj) | |||
| 4514 | i915_gem_free_object_tail(obj); | 4367 | i915_gem_free_object_tail(obj); |
| 4515 | } | 4368 | } |
| 4516 | 4369 | ||
| 4517 | /** Unbinds all inactive objects. */ | ||
| 4518 | static int | ||
| 4519 | i915_gem_evict_from_inactive_list(struct drm_device *dev) | ||
| 4520 | { | ||
| 4521 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 4522 | |||
| 4523 | while (!list_empty(&dev_priv->mm.inactive_list)) { | ||
| 4524 | struct drm_gem_object *obj; | ||
| 4525 | int ret; | ||
| 4526 | |||
| 4527 | obj = &list_first_entry(&dev_priv->mm.inactive_list, | ||
| 4528 | struct drm_i915_gem_object, | ||
| 4529 | list)->base; | ||
| 4530 | |||
| 4531 | ret = i915_gem_object_unbind(obj); | ||
| 4532 | if (ret != 0) { | ||
| 4533 | DRM_ERROR("Error unbinding object: %d\n", ret); | ||
| 4534 | return ret; | ||
| 4535 | } | ||
| 4536 | } | ||
| 4537 | |||
| 4538 | return 0; | ||
| 4539 | } | ||
| 4540 | |||
| 4541 | int | 4370 | int |
| 4542 | i915_gem_idle(struct drm_device *dev) | 4371 | i915_gem_idle(struct drm_device *dev) |
| 4543 | { | 4372 | { |
| @@ -4562,7 +4391,7 @@ i915_gem_idle(struct drm_device *dev) | |||
| 4562 | 4391 | ||
| 4563 | /* Under UMS, be paranoid and evict. */ | 4392 | /* Under UMS, be paranoid and evict. */ |
| 4564 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { | 4393 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { |
| 4565 | ret = i915_gem_evict_from_inactive_list(dev); | 4394 | ret = i915_gem_evict_inactive(dev); |
| 4566 | if (ret) { | 4395 | if (ret) { |
| 4567 | mutex_unlock(&dev->struct_mutex); | 4396 | mutex_unlock(&dev->struct_mutex); |
| 4568 | return ret; | 4397 | return ret; |
| @@ -4680,6 +4509,8 @@ i915_gem_init_ringbuffer(struct drm_device *dev) | |||
| 4680 | goto cleanup_render_ring; | 4509 | goto cleanup_render_ring; |
| 4681 | } | 4510 | } |
| 4682 | 4511 | ||
| 4512 | dev_priv->next_seqno = 1; | ||
| 4513 | |||
| 4683 | return 0; | 4514 | return 0; |
| 4684 | 4515 | ||
| 4685 | cleanup_render_ring: | 4516 | cleanup_render_ring: |
| @@ -4841,7 +4672,7 @@ i915_gem_load(struct drm_device *dev) | |||
| 4841 | * e.g. for cursor + overlay regs | 4672 | * e.g. for cursor + overlay regs |
| 4842 | */ | 4673 | */ |
| 4843 | int i915_gem_init_phys_object(struct drm_device *dev, | 4674 | int i915_gem_init_phys_object(struct drm_device *dev, |
| 4844 | int id, int size) | 4675 | int id, int size, int align) |
| 4845 | { | 4676 | { |
| 4846 | drm_i915_private_t *dev_priv = dev->dev_private; | 4677 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 4847 | struct drm_i915_gem_phys_object *phys_obj; | 4678 | struct drm_i915_gem_phys_object *phys_obj; |
| @@ -4856,7 +4687,7 @@ int i915_gem_init_phys_object(struct drm_device *dev, | |||
| 4856 | 4687 | ||
| 4857 | phys_obj->id = id; | 4688 | phys_obj->id = id; |
| 4858 | 4689 | ||
| 4859 | phys_obj->handle = drm_pci_alloc(dev, size, 0); | 4690 | phys_obj->handle = drm_pci_alloc(dev, size, align); |
| 4860 | if (!phys_obj->handle) { | 4691 | if (!phys_obj->handle) { |
| 4861 | ret = -ENOMEM; | 4692 | ret = -ENOMEM; |
| 4862 | goto kfree_obj; | 4693 | goto kfree_obj; |
| @@ -4938,7 +4769,9 @@ out: | |||
| 4938 | 4769 | ||
| 4939 | int | 4770 | int |
| 4940 | i915_gem_attach_phys_object(struct drm_device *dev, | 4771 | i915_gem_attach_phys_object(struct drm_device *dev, |
| 4941 | struct drm_gem_object *obj, int id) | 4772 | struct drm_gem_object *obj, |
| 4773 | int id, | ||
| 4774 | int align) | ||
| 4942 | { | 4775 | { |
| 4943 | drm_i915_private_t *dev_priv = dev->dev_private; | 4776 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 4944 | struct drm_i915_gem_object *obj_priv; | 4777 | struct drm_i915_gem_object *obj_priv; |
| @@ -4957,11 +4790,10 @@ i915_gem_attach_phys_object(struct drm_device *dev, | |||
| 4957 | i915_gem_detach_phys_object(dev, obj); | 4790 | i915_gem_detach_phys_object(dev, obj); |
| 4958 | } | 4791 | } |
| 4959 | 4792 | ||
| 4960 | |||
| 4961 | /* create a new object */ | 4793 | /* create a new object */ |
| 4962 | if (!dev_priv->mm.phys_objs[id - 1]) { | 4794 | if (!dev_priv->mm.phys_objs[id - 1]) { |
| 4963 | ret = i915_gem_init_phys_object(dev, id, | 4795 | ret = i915_gem_init_phys_object(dev, id, |
| 4964 | obj->size); | 4796 | obj->size, align); |
| 4965 | if (ret) { | 4797 | if (ret) { |
| 4966 | DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size); | 4798 | DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size); |
| 4967 | goto out; | 4799 | goto out; |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c new file mode 100644 index 00000000000..72cae3cccad --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
| @@ -0,0 +1,271 @@ | |||
| 1 | /* | ||
| 2 | * Copyright © 2008-2010 Intel Corporation | ||
| 3 | * | ||
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 5 | * copy of this software and associated documentation files (the "Software"), | ||
| 6 | * to deal in the Software without restriction, including without limitation | ||
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 9 | * Software is furnished to do so, subject to the following conditions: | ||
| 10 | * | ||
| 11 | * The above copyright notice and this permission notice (including the next | ||
| 12 | * paragraph) shall be included in all copies or substantial portions of the | ||
| 13 | * Software. | ||
| 14 | * | ||
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
| 21 | * IN THE SOFTWARE. | ||
| 22 | * | ||
| 23 | * Authors: | ||
| 24 | * Eric Anholt <eric@anholt.net> | ||
| 25 | * Chris Wilson <chris@chris-wilson.co.uuk> | ||
| 26 | * | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include "drmP.h" | ||
| 30 | #include "drm.h" | ||
| 31 | #include "i915_drv.h" | ||
| 32 | #include "i915_drm.h" | ||
| 33 | |||
| 34 | static struct drm_i915_gem_object * | ||
| 35 | i915_gem_next_active_object(struct drm_device *dev, | ||
| 36 | struct list_head **render_iter, | ||
| 37 | struct list_head **bsd_iter) | ||
| 38 | { | ||
| 39 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 40 | struct drm_i915_gem_object *render_obj = NULL, *bsd_obj = NULL; | ||
| 41 | |||
| 42 | if (*render_iter != &dev_priv->render_ring.active_list) | ||
| 43 | render_obj = list_entry(*render_iter, | ||
| 44 | struct drm_i915_gem_object, | ||
| 45 | list); | ||
| 46 | |||
| 47 | if (HAS_BSD(dev)) { | ||
| 48 | if (*bsd_iter != &dev_priv->bsd_ring.active_list) | ||
| 49 | bsd_obj = list_entry(*bsd_iter, | ||
| 50 | struct drm_i915_gem_object, | ||
| 51 | list); | ||
| 52 | |||
| 53 | if (render_obj == NULL) { | ||
| 54 | *bsd_iter = (*bsd_iter)->next; | ||
| 55 | return bsd_obj; | ||
| 56 | } | ||
| 57 | |||
| 58 | if (bsd_obj == NULL) { | ||
| 59 | *render_iter = (*render_iter)->next; | ||
| 60 | return render_obj; | ||
| 61 | } | ||
| 62 | |||
| 63 | /* XXX can we handle seqno wrapping? */ | ||
| 64 | if (render_obj->last_rendering_seqno < bsd_obj->last_rendering_seqno) { | ||
| 65 | *render_iter = (*render_iter)->next; | ||
| 66 | return render_obj; | ||
| 67 | } else { | ||
| 68 | *bsd_iter = (*bsd_iter)->next; | ||
| 69 | return bsd_obj; | ||
| 70 | } | ||
| 71 | } else { | ||
| 72 | *render_iter = (*render_iter)->next; | ||
| 73 | return render_obj; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | static bool | ||
| 78 | mark_free(struct drm_i915_gem_object *obj_priv, | ||
| 79 | struct list_head *unwind) | ||
| 80 | { | ||
| 81 | list_add(&obj_priv->evict_list, unwind); | ||
| 82 | return drm_mm_scan_add_block(obj_priv->gtt_space); | ||
| 83 | } | ||
| 84 | |||
| 85 | #define i915_for_each_active_object(OBJ, R, B) \ | ||
| 86 | *(R) = dev_priv->render_ring.active_list.next; \ | ||
| 87 | *(B) = dev_priv->bsd_ring.active_list.next; \ | ||
| 88 | while (((OBJ) = i915_gem_next_active_object(dev, (R), (B))) != NULL) | ||
| 89 | |||
| 90 | int | ||
| 91 | i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment) | ||
| 92 | { | ||
| 93 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 94 | struct list_head eviction_list, unwind_list; | ||
| 95 | struct drm_i915_gem_object *obj_priv, *tmp_obj_priv; | ||
| 96 | struct list_head *render_iter, *bsd_iter; | ||
| 97 | int ret = 0; | ||
| 98 | |||
| 99 | i915_gem_retire_requests(dev); | ||
| 100 | |||
| 101 | /* Re-check for free space after retiring requests */ | ||
| 102 | if (drm_mm_search_free(&dev_priv->mm.gtt_space, | ||
| 103 | min_size, alignment, 0)) | ||
| 104 | return 0; | ||
| 105 | |||
| 106 | /* | ||
| 107 | * The goal is to evict objects and amalgamate space in LRU order. | ||
| 108 | * The oldest idle objects reside on the inactive list, which is in | ||
| 109 | * retirement order. The next objects to retire are those on the (per | ||
| 110 | * ring) active list that do not have an outstanding flush. Once the | ||
| 111 | * hardware reports completion (the seqno is updated after the | ||
| 112 | * batchbuffer has been finished) the clean buffer objects would | ||
| 113 | * be retired to the inactive list. Any dirty objects would be added | ||
| 114 | * to the tail of the flushing list. So after processing the clean | ||
| 115 | * active objects we need to emit a MI_FLUSH to retire the flushing | ||
| 116 | * list, hence the retirement order of the flushing list is in | ||
| 117 | * advance of the dirty objects on the active lists. | ||
| 118 | * | ||
| 119 | * The retirement sequence is thus: | ||
| 120 | * 1. Inactive objects (already retired) | ||
| 121 | * 2. Clean active objects | ||
| 122 | * 3. Flushing list | ||
| 123 | * 4. Dirty active objects. | ||
| 124 | * | ||
| 125 | * On each list, the oldest objects lie at the HEAD with the freshest | ||
| 126 | * object on the TAIL. | ||
| 127 | */ | ||
| 128 | |||
| 129 | INIT_LIST_HEAD(&unwind_list); | ||
| 130 | drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment); | ||
| 131 | |||
| 132 | /* First see if there is a large enough contiguous idle region... */ | ||
| 133 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
| 134 | if (mark_free(obj_priv, &unwind_list)) | ||
| 135 | goto found; | ||
| 136 | } | ||
| 137 | |||
| 138 | /* Now merge in the soon-to-be-expired objects... */ | ||
| 139 | i915_for_each_active_object(obj_priv, &render_iter, &bsd_iter) { | ||
| 140 | /* Does the object require an outstanding flush? */ | ||
| 141 | if (obj_priv->base.write_domain || obj_priv->pin_count) | ||
| 142 | continue; | ||
| 143 | |||
| 144 | if (mark_free(obj_priv, &unwind_list)) | ||
| 145 | goto found; | ||
| 146 | } | ||
| 147 | |||
| 148 | /* Finally add anything with a pending flush (in order of retirement) */ | ||
| 149 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { | ||
| 150 | if (obj_priv->pin_count) | ||
| 151 | continue; | ||
| 152 | |||
| 153 | if (mark_free(obj_priv, &unwind_list)) | ||
| 154 | goto found; | ||
| 155 | } | ||
| 156 | i915_for_each_active_object(obj_priv, &render_iter, &bsd_iter) { | ||
| 157 | if (! obj_priv->base.write_domain || obj_priv->pin_count) | ||
| 158 | continue; | ||
| 159 | |||
| 160 | if (mark_free(obj_priv, &unwind_list)) | ||
| 161 | goto found; | ||
| 162 | } | ||
| 163 | |||
| 164 | /* Nothing found, clean up and bail out! */ | ||
| 165 | list_for_each_entry(obj_priv, &unwind_list, evict_list) { | ||
| 166 | ret = drm_mm_scan_remove_block(obj_priv->gtt_space); | ||
| 167 | BUG_ON(ret); | ||
| 168 | } | ||
| 169 | |||
| 170 | /* We expect the caller to unpin, evict all and try again, or give up. | ||
| 171 | * So calling i915_gem_evict_everything() is unnecessary. | ||
| 172 | */ | ||
| 173 | return -ENOSPC; | ||
| 174 | |||
| 175 | found: | ||
| 176 | INIT_LIST_HEAD(&eviction_list); | ||
| 177 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, | ||
| 178 | &unwind_list, evict_list) { | ||
| 179 | if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { | ||
| 180 | /* drm_mm doesn't allow any other other operations while | ||
| 181 | * scanning, therefore store to be evicted objects on a | ||
| 182 | * temporary list. */ | ||
| 183 | list_move(&obj_priv->evict_list, &eviction_list); | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | /* Unbinding will emit any required flushes */ | ||
| 188 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, | ||
| 189 | &eviction_list, evict_list) { | ||
| 190 | #if WATCH_LRU | ||
| 191 | DRM_INFO("%s: evicting %p\n", __func__, obj); | ||
| 192 | #endif | ||
| 193 | ret = i915_gem_object_unbind(&obj_priv->base); | ||
| 194 | if (ret) | ||
| 195 | return ret; | ||
| 196 | } | ||
| 197 | |||
| 198 | /* The just created free hole should be on the top of the free stack | ||
| 199 | * maintained by drm_mm, so this BUG_ON actually executes in O(1). | ||
| 200 | * Furthermore all accessed data has just recently been used, so it | ||
| 201 | * should be really fast, too. */ | ||
| 202 | BUG_ON(!drm_mm_search_free(&dev_priv->mm.gtt_space, min_size, | ||
| 203 | alignment, 0)); | ||
| 204 | |||
| 205 | return 0; | ||
| 206 | } | ||
| 207 | |||
| 208 | int | ||
| 209 | i915_gem_evict_everything(struct drm_device *dev) | ||
| 210 | { | ||
| 211 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 212 | int ret; | ||
| 213 | bool lists_empty; | ||
| 214 | |||
| 215 | spin_lock(&dev_priv->mm.active_list_lock); | ||
| 216 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
| 217 | list_empty(&dev_priv->mm.flushing_list) && | ||
| 218 | list_empty(&dev_priv->render_ring.active_list) && | ||
| 219 | (!HAS_BSD(dev) | ||
| 220 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
| 221 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
| 222 | |||
| 223 | if (lists_empty) | ||
| 224 | return -ENOSPC; | ||
| 225 | |||
| 226 | /* Flush everything (on to the inactive lists) and evict */ | ||
| 227 | ret = i915_gpu_idle(dev); | ||
| 228 | if (ret) | ||
| 229 | return ret; | ||
| 230 | |||
| 231 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
| 232 | |||
| 233 | ret = i915_gem_evict_inactive(dev); | ||
| 234 | if (ret) | ||
| 235 | return ret; | ||
| 236 | |||
| 237 | spin_lock(&dev_priv->mm.active_list_lock); | ||
| 238 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
| 239 | list_empty(&dev_priv->mm.flushing_list) && | ||
| 240 | list_empty(&dev_priv->render_ring.active_list) && | ||
| 241 | (!HAS_BSD(dev) | ||
| 242 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
| 243 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
| 244 | BUG_ON(!lists_empty); | ||
| 245 | |||
| 246 | return 0; | ||
| 247 | } | ||
| 248 | |||
| 249 | /** Unbinds all inactive objects. */ | ||
| 250 | int | ||
| 251 | i915_gem_evict_inactive(struct drm_device *dev) | ||
| 252 | { | ||
| 253 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 254 | |||
| 255 | while (!list_empty(&dev_priv->mm.inactive_list)) { | ||
| 256 | struct drm_gem_object *obj; | ||
| 257 | int ret; | ||
| 258 | |||
| 259 | obj = &list_first_entry(&dev_priv->mm.inactive_list, | ||
| 260 | struct drm_i915_gem_object, | ||
| 261 | list)->base; | ||
| 262 | |||
| 263 | ret = i915_gem_object_unbind(obj); | ||
| 264 | if (ret != 0) { | ||
| 265 | DRM_ERROR("Error unbinding object: %d\n", ret); | ||
| 266 | return ret; | ||
| 267 | } | ||
| 268 | } | ||
| 269 | |||
| 270 | return 0; | ||
| 271 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 85785a8844e..16861b800fe 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -425,9 +425,11 @@ static struct drm_i915_error_object * | |||
| 425 | i915_error_object_create(struct drm_device *dev, | 425 | i915_error_object_create(struct drm_device *dev, |
| 426 | struct drm_gem_object *src) | 426 | struct drm_gem_object *src) |
| 427 | { | 427 | { |
| 428 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 428 | struct drm_i915_error_object *dst; | 429 | struct drm_i915_error_object *dst; |
| 429 | struct drm_i915_gem_object *src_priv; | 430 | struct drm_i915_gem_object *src_priv; |
| 430 | int page, page_count; | 431 | int page, page_count; |
| 432 | u32 reloc_offset; | ||
| 431 | 433 | ||
| 432 | if (src == NULL) | 434 | if (src == NULL) |
| 433 | return NULL; | 435 | return NULL; |
| @@ -442,18 +444,27 @@ i915_error_object_create(struct drm_device *dev, | |||
| 442 | if (dst == NULL) | 444 | if (dst == NULL) |
| 443 | return NULL; | 445 | return NULL; |
| 444 | 446 | ||
| 447 | reloc_offset = src_priv->gtt_offset; | ||
| 445 | for (page = 0; page < page_count; page++) { | 448 | for (page = 0; page < page_count; page++) { |
| 446 | void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); | ||
| 447 | unsigned long flags; | 449 | unsigned long flags; |
| 450 | void __iomem *s; | ||
| 451 | void *d; | ||
| 448 | 452 | ||
| 453 | d = kmalloc(PAGE_SIZE, GFP_ATOMIC); | ||
| 449 | if (d == NULL) | 454 | if (d == NULL) |
| 450 | goto unwind; | 455 | goto unwind; |
| 456 | |||
| 451 | local_irq_save(flags); | 457 | local_irq_save(flags); |
| 452 | s = kmap_atomic(src_priv->pages[page], KM_IRQ0); | 458 | s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, |
| 453 | memcpy(d, s, PAGE_SIZE); | 459 | reloc_offset, |
| 454 | kunmap_atomic(s, KM_IRQ0); | 460 | KM_IRQ0); |
| 461 | memcpy_fromio(d, s, PAGE_SIZE); | ||
| 462 | io_mapping_unmap_atomic(s, KM_IRQ0); | ||
| 455 | local_irq_restore(flags); | 463 | local_irq_restore(flags); |
| 464 | |||
| 456 | dst->pages[page] = d; | 465 | dst->pages[page] = d; |
| 466 | |||
| 467 | reloc_offset += PAGE_SIZE; | ||
| 457 | } | 468 | } |
| 458 | dst->page_count = page_count; | 469 | dst->page_count = page_count; |
| 459 | dst->gtt_offset = src_priv->gtt_offset; | 470 | dst->gtt_offset = src_priv->gtt_offset; |
| @@ -489,6 +500,7 @@ i915_error_state_free(struct drm_device *dev, | |||
| 489 | i915_error_object_free(error->batchbuffer[1]); | 500 | i915_error_object_free(error->batchbuffer[1]); |
| 490 | i915_error_object_free(error->ringbuffer); | 501 | i915_error_object_free(error->ringbuffer); |
| 491 | kfree(error->active_bo); | 502 | kfree(error->active_bo); |
| 503 | kfree(error->overlay); | ||
| 492 | kfree(error); | 504 | kfree(error); |
| 493 | } | 505 | } |
| 494 | 506 | ||
| @@ -612,18 +624,57 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
| 612 | 624 | ||
| 613 | if (batchbuffer[1] == NULL && | 625 | if (batchbuffer[1] == NULL && |
| 614 | error->acthd >= obj_priv->gtt_offset && | 626 | error->acthd >= obj_priv->gtt_offset && |
| 615 | error->acthd < obj_priv->gtt_offset + obj->size && | 627 | error->acthd < obj_priv->gtt_offset + obj->size) |
| 616 | batchbuffer[0] != obj) | ||
| 617 | batchbuffer[1] = obj; | 628 | batchbuffer[1] = obj; |
| 618 | 629 | ||
| 619 | count++; | 630 | count++; |
| 620 | } | 631 | } |
| 632 | /* Scan the other lists for completeness for those bizarre errors. */ | ||
| 633 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { | ||
| 634 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { | ||
| 635 | struct drm_gem_object *obj = &obj_priv->base; | ||
| 636 | |||
| 637 | if (batchbuffer[0] == NULL && | ||
| 638 | bbaddr >= obj_priv->gtt_offset && | ||
| 639 | bbaddr < obj_priv->gtt_offset + obj->size) | ||
| 640 | batchbuffer[0] = obj; | ||
| 641 | |||
| 642 | if (batchbuffer[1] == NULL && | ||
| 643 | error->acthd >= obj_priv->gtt_offset && | ||
| 644 | error->acthd < obj_priv->gtt_offset + obj->size) | ||
| 645 | batchbuffer[1] = obj; | ||
| 646 | |||
| 647 | if (batchbuffer[0] && batchbuffer[1]) | ||
| 648 | break; | ||
| 649 | } | ||
| 650 | } | ||
| 651 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { | ||
| 652 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
| 653 | struct drm_gem_object *obj = &obj_priv->base; | ||
| 654 | |||
| 655 | if (batchbuffer[0] == NULL && | ||
| 656 | bbaddr >= obj_priv->gtt_offset && | ||
| 657 | bbaddr < obj_priv->gtt_offset + obj->size) | ||
| 658 | batchbuffer[0] = obj; | ||
| 659 | |||
| 660 | if (batchbuffer[1] == NULL && | ||
| 661 | error->acthd >= obj_priv->gtt_offset && | ||
| 662 | error->acthd < obj_priv->gtt_offset + obj->size) | ||
| 663 | batchbuffer[1] = obj; | ||
| 664 | |||
| 665 | if (batchbuffer[0] && batchbuffer[1]) | ||
| 666 | break; | ||
| 667 | } | ||
| 668 | } | ||
| 621 | 669 | ||
| 622 | /* We need to copy these to an anonymous buffer as the simplest | 670 | /* We need to copy these to an anonymous buffer as the simplest |
| 623 | * method to avoid being overwritten by userpace. | 671 | * method to avoid being overwritten by userpace. |
| 624 | */ | 672 | */ |
| 625 | error->batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]); | 673 | error->batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]); |
| 626 | error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); | 674 | if (batchbuffer[1] != batchbuffer[0]) |
| 675 | error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); | ||
| 676 | else | ||
| 677 | error->batchbuffer[1] = NULL; | ||
| 627 | 678 | ||
| 628 | /* Record the ringbuffer */ | 679 | /* Record the ringbuffer */ |
| 629 | error->ringbuffer = i915_error_object_create(dev, | 680 | error->ringbuffer = i915_error_object_create(dev, |
| @@ -667,6 +718,8 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
| 667 | 718 | ||
| 668 | do_gettimeofday(&error->time); | 719 | do_gettimeofday(&error->time); |
| 669 | 720 | ||
| 721 | error->overlay = intel_overlay_capture_error_state(dev); | ||
| 722 | |||
| 670 | spin_lock_irqsave(&dev_priv->error_lock, flags); | 723 | spin_lock_irqsave(&dev_priv->error_lock, flags); |
| 671 | if (dev_priv->first_error == NULL) { | 724 | if (dev_priv->first_error == NULL) { |
| 672 | dev_priv->first_error = error; | 725 | dev_priv->first_error = error; |
| @@ -1251,6 +1304,16 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
| 1251 | &dev_priv->render_ring), | 1304 | &dev_priv->render_ring), |
| 1252 | i915_get_tail_request(dev)->seqno)) { | 1305 | i915_get_tail_request(dev)->seqno)) { |
| 1253 | dev_priv->hangcheck_count = 0; | 1306 | dev_priv->hangcheck_count = 0; |
| 1307 | |||
| 1308 | /* Issue a wake-up to catch stuck h/w. */ | ||
| 1309 | if (dev_priv->render_ring.waiting_gem_seqno | | ||
| 1310 | dev_priv->bsd_ring.waiting_gem_seqno) { | ||
| 1311 | DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n"); | ||
| 1312 | if (dev_priv->render_ring.waiting_gem_seqno) | ||
| 1313 | DRM_WAKEUP(&dev_priv->render_ring.irq_queue); | ||
| 1314 | if (dev_priv->bsd_ring.waiting_gem_seqno) | ||
| 1315 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); | ||
| 1316 | } | ||
| 1254 | return; | 1317 | return; |
| 1255 | } | 1318 | } |
| 1256 | 1319 | ||
| @@ -1318,12 +1381,17 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
| 1318 | I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); | 1381 | I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); |
| 1319 | (void) I915_READ(DEIER); | 1382 | (void) I915_READ(DEIER); |
| 1320 | 1383 | ||
| 1321 | /* user interrupt should be enabled, but masked initial */ | 1384 | /* Gen6 only needs render pipe_control now */ |
| 1385 | if (IS_GEN6(dev)) | ||
| 1386 | render_mask = GT_PIPE_NOTIFY; | ||
| 1387 | |||
| 1322 | dev_priv->gt_irq_mask_reg = ~render_mask; | 1388 | dev_priv->gt_irq_mask_reg = ~render_mask; |
| 1323 | dev_priv->gt_irq_enable_reg = render_mask; | 1389 | dev_priv->gt_irq_enable_reg = render_mask; |
| 1324 | 1390 | ||
| 1325 | I915_WRITE(GTIIR, I915_READ(GTIIR)); | 1391 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
| 1326 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); | 1392 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); |
| 1393 | if (IS_GEN6(dev)) | ||
| 1394 | I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT); | ||
| 1327 | I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); | 1395 | I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); |
| 1328 | (void) I915_READ(GTIER); | 1396 | (void) I915_READ(GTIER); |
| 1329 | 1397 | ||
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c index d1bf92b9978..ea5d3fea4b6 100644 --- a/drivers/gpu/drm/i915/i915_opregion.c +++ b/drivers/gpu/drm/i915/i915_opregion.c | |||
| @@ -114,10 +114,6 @@ struct opregion_asle { | |||
| 114 | #define ASLE_REQ_MSK 0xf | 114 | #define ASLE_REQ_MSK 0xf |
| 115 | 115 | ||
| 116 | /* response bits of ASLE irq request */ | 116 | /* response bits of ASLE irq request */ |
| 117 | #define ASLE_ALS_ILLUM_FAIL (2<<10) | ||
| 118 | #define ASLE_BACKLIGHT_FAIL (2<<12) | ||
| 119 | #define ASLE_PFIT_FAIL (2<<14) | ||
| 120 | #define ASLE_PWM_FREQ_FAIL (2<<16) | ||
| 121 | #define ASLE_ALS_ILLUM_FAILED (1<<10) | 117 | #define ASLE_ALS_ILLUM_FAILED (1<<10) |
| 122 | #define ASLE_BACKLIGHT_FAILED (1<<12) | 118 | #define ASLE_BACKLIGHT_FAILED (1<<12) |
| 123 | #define ASLE_PFIT_FAILED (1<<14) | 119 | #define ASLE_PFIT_FAILED (1<<14) |
| @@ -155,11 +151,11 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | |||
| 155 | u32 max_backlight, level, shift; | 151 | u32 max_backlight, level, shift; |
| 156 | 152 | ||
| 157 | if (!(bclp & ASLE_BCLP_VALID)) | 153 | if (!(bclp & ASLE_BCLP_VALID)) |
| 158 | return ASLE_BACKLIGHT_FAIL; | 154 | return ASLE_BACKLIGHT_FAILED; |
| 159 | 155 | ||
| 160 | bclp &= ASLE_BCLP_MSK; | 156 | bclp &= ASLE_BCLP_MSK; |
| 161 | if (bclp < 0 || bclp > 255) | 157 | if (bclp < 0 || bclp > 255) |
| 162 | return ASLE_BACKLIGHT_FAIL; | 158 | return ASLE_BACKLIGHT_FAILED; |
| 163 | 159 | ||
| 164 | blc_pwm_ctl = I915_READ(BLC_PWM_CTL); | 160 | blc_pwm_ctl = I915_READ(BLC_PWM_CTL); |
| 165 | blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2); | 161 | blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2); |
| @@ -211,7 +207,7 @@ static u32 asle_set_pfit(struct drm_device *dev, u32 pfit) | |||
| 211 | /* Panel fitting is currently controlled by the X code, so this is a | 207 | /* Panel fitting is currently controlled by the X code, so this is a |
| 212 | noop until modesetting support works fully */ | 208 | noop until modesetting support works fully */ |
| 213 | if (!(pfit & ASLE_PFIT_VALID)) | 209 | if (!(pfit & ASLE_PFIT_VALID)) |
| 214 | return ASLE_PFIT_FAIL; | 210 | return ASLE_PFIT_FAILED; |
| 215 | return 0; | 211 | return 0; |
| 216 | } | 212 | } |
| 217 | 213 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 281db6e5403..67e3ec1a6af 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -170,6 +170,7 @@ | |||
| 170 | #define MI_NO_WRITE_FLUSH (1 << 2) | 170 | #define MI_NO_WRITE_FLUSH (1 << 2) |
| 171 | #define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ | 171 | #define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ |
| 172 | #define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ | 172 | #define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ |
| 173 | #define MI_INVALIDATE_ISP (1 << 5) /* invalidate indirect state pointers */ | ||
| 173 | #define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) | 174 | #define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) |
| 174 | #define MI_REPORT_HEAD MI_INSTR(0x07, 0) | 175 | #define MI_REPORT_HEAD MI_INSTR(0x07, 0) |
| 175 | #define MI_OVERLAY_FLIP MI_INSTR(0x11,0) | 176 | #define MI_OVERLAY_FLIP MI_INSTR(0x11,0) |
| @@ -180,6 +181,12 @@ | |||
| 180 | #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) | 181 | #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) |
| 181 | #define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) | 182 | #define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) |
| 182 | #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) | 183 | #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) |
| 184 | #define MI_SET_CONTEXT MI_INSTR(0x18, 0) | ||
| 185 | #define MI_MM_SPACE_GTT (1<<8) | ||
| 186 | #define MI_MM_SPACE_PHYSICAL (0<<8) | ||
| 187 | #define MI_SAVE_EXT_STATE_EN (1<<3) | ||
| 188 | #define MI_RESTORE_EXT_STATE_EN (1<<2) | ||
| 189 | #define MI_RESTORE_INHIBIT (1<<0) | ||
| 183 | #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) | 190 | #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) |
| 184 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ | 191 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ |
| 185 | #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) | 192 | #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) |
| @@ -1100,6 +1107,11 @@ | |||
| 1100 | #define PEG_BAND_GAP_DATA 0x14d68 | 1107 | #define PEG_BAND_GAP_DATA 0x14d68 |
| 1101 | 1108 | ||
| 1102 | /* | 1109 | /* |
| 1110 | * Logical Context regs | ||
| 1111 | */ | ||
| 1112 | #define CCID 0x2180 | ||
| 1113 | #define CCID_EN (1<<0) | ||
| 1114 | /* | ||
| 1103 | * Overlay regs | 1115 | * Overlay regs |
| 1104 | */ | 1116 | */ |
| 1105 | 1117 | ||
| @@ -2069,6 +2081,7 @@ | |||
| 2069 | #define PIPE_DITHER_TYPE_ST01 (1 << 2) | 2081 | #define PIPE_DITHER_TYPE_ST01 (1 << 2) |
| 2070 | /* Pipe A */ | 2082 | /* Pipe A */ |
| 2071 | #define PIPEADSL 0x70000 | 2083 | #define PIPEADSL 0x70000 |
| 2084 | #define DSL_LINEMASK 0x00000fff | ||
| 2072 | #define PIPEACONF 0x70008 | 2085 | #define PIPEACONF 0x70008 |
| 2073 | #define PIPEACONF_ENABLE (1<<31) | 2086 | #define PIPEACONF_ENABLE (1<<31) |
| 2074 | #define PIPEACONF_DISABLE 0 | 2087 | #define PIPEACONF_DISABLE 0 |
| @@ -2928,6 +2941,7 @@ | |||
| 2928 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 | 2941 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 |
| 2929 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) | 2942 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) |
| 2930 | #define TRANS_DP_HSYNC_ACTIVE_LOW 0 | 2943 | #define TRANS_DP_HSYNC_ACTIVE_LOW 0 |
| 2944 | #define TRANS_DP_SYNC_MASK (3<<3) | ||
| 2931 | 2945 | ||
| 2932 | /* SNB eDP training params */ | 2946 | /* SNB eDP training params */ |
| 2933 | /* SNB A-stepping */ | 2947 | /* SNB A-stepping */ |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 6e2025274db..2c6b98f2440 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
| @@ -34,7 +34,7 @@ static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) | |||
| 34 | struct drm_i915_private *dev_priv = dev->dev_private; | 34 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 35 | u32 dpll_reg; | 35 | u32 dpll_reg; |
| 36 | 36 | ||
| 37 | if (IS_IRONLAKE(dev)) { | 37 | if (HAS_PCH_SPLIT(dev)) { |
| 38 | dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B; | 38 | dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B; |
| 39 | } else { | 39 | } else { |
| 40 | dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B; | 40 | dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B; |
| @@ -53,7 +53,7 @@ static void i915_save_palette(struct drm_device *dev, enum pipe pipe) | |||
| 53 | if (!i915_pipe_enabled(dev, pipe)) | 53 | if (!i915_pipe_enabled(dev, pipe)) |
| 54 | return; | 54 | return; |
| 55 | 55 | ||
| 56 | if (IS_IRONLAKE(dev)) | 56 | if (HAS_PCH_SPLIT(dev)) |
| 57 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; | 57 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; |
| 58 | 58 | ||
| 59 | if (pipe == PIPE_A) | 59 | if (pipe == PIPE_A) |
| @@ -75,7 +75,7 @@ static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) | |||
| 75 | if (!i915_pipe_enabled(dev, pipe)) | 75 | if (!i915_pipe_enabled(dev, pipe)) |
| 76 | return; | 76 | return; |
| 77 | 77 | ||
| 78 | if (IS_IRONLAKE(dev)) | 78 | if (HAS_PCH_SPLIT(dev)) |
| 79 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; | 79 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; |
| 80 | 80 | ||
| 81 | if (pipe == PIPE_A) | 81 | if (pipe == PIPE_A) |
| @@ -239,7 +239,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 239 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 239 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
| 240 | return; | 240 | return; |
| 241 | 241 | ||
| 242 | if (IS_IRONLAKE(dev)) { | 242 | if (HAS_PCH_SPLIT(dev)) { |
| 243 | dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); | 243 | dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); |
| 244 | dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); | 244 | dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); |
| 245 | } | 245 | } |
| @@ -247,7 +247,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 247 | /* Pipe & plane A info */ | 247 | /* Pipe & plane A info */ |
| 248 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | 248 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); |
| 249 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | 249 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); |
| 250 | if (IS_IRONLAKE(dev)) { | 250 | if (HAS_PCH_SPLIT(dev)) { |
| 251 | dev_priv->saveFPA0 = I915_READ(PCH_FPA0); | 251 | dev_priv->saveFPA0 = I915_READ(PCH_FPA0); |
| 252 | dev_priv->saveFPA1 = I915_READ(PCH_FPA1); | 252 | dev_priv->saveFPA1 = I915_READ(PCH_FPA1); |
| 253 | dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A); | 253 | dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A); |
| @@ -256,7 +256,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 256 | dev_priv->saveFPA1 = I915_READ(FPA1); | 256 | dev_priv->saveFPA1 = I915_READ(FPA1); |
| 257 | dev_priv->saveDPLL_A = I915_READ(DPLL_A); | 257 | dev_priv->saveDPLL_A = I915_READ(DPLL_A); |
| 258 | } | 258 | } |
| 259 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 259 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) |
| 260 | dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); | 260 | dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); |
| 261 | dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); | 261 | dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); |
| 262 | dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); | 262 | dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); |
| @@ -264,10 +264,10 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 264 | dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); | 264 | dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); |
| 265 | dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); | 265 | dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); |
| 266 | dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); | 266 | dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); |
| 267 | if (!IS_IRONLAKE(dev)) | 267 | if (!HAS_PCH_SPLIT(dev)) |
| 268 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | 268 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); |
| 269 | 269 | ||
| 270 | if (IS_IRONLAKE(dev)) { | 270 | if (HAS_PCH_SPLIT(dev)) { |
| 271 | dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1); | 271 | dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1); |
| 272 | dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1); | 272 | dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1); |
| 273 | dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1); | 273 | dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1); |
| @@ -304,7 +304,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 304 | /* Pipe & plane B info */ | 304 | /* Pipe & plane B info */ |
| 305 | dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); | 305 | dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); |
| 306 | dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); | 306 | dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); |
| 307 | if (IS_IRONLAKE(dev)) { | 307 | if (HAS_PCH_SPLIT(dev)) { |
| 308 | dev_priv->saveFPB0 = I915_READ(PCH_FPB0); | 308 | dev_priv->saveFPB0 = I915_READ(PCH_FPB0); |
| 309 | dev_priv->saveFPB1 = I915_READ(PCH_FPB1); | 309 | dev_priv->saveFPB1 = I915_READ(PCH_FPB1); |
| 310 | dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B); | 310 | dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B); |
| @@ -313,7 +313,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 313 | dev_priv->saveFPB1 = I915_READ(FPB1); | 313 | dev_priv->saveFPB1 = I915_READ(FPB1); |
| 314 | dev_priv->saveDPLL_B = I915_READ(DPLL_B); | 314 | dev_priv->saveDPLL_B = I915_READ(DPLL_B); |
| 315 | } | 315 | } |
| 316 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 316 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) |
| 317 | dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); | 317 | dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); |
| 318 | dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); | 318 | dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); |
| 319 | dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); | 319 | dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); |
| @@ -321,10 +321,10 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
| 321 | dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); | 321 | dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); |
| 322 | dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); | 322 | dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); |
| 323 | dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); | 323 | dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); |
| 324 | if (!IS_IRONLAKE(dev)) | 324 | if (!HAS_PCH_SPLIT(dev)) |
| 325 | dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); | 325 | dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); |
| 326 | 326 | ||
| 327 | if (IS_IRONLAKE(dev)) { | 327 | if (HAS_PCH_SPLIT(dev)) { |
| 328 | dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1); | 328 | dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1); |
| 329 | dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1); | 329 | dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1); |
| 330 | dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1); | 330 | dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1); |
| @@ -369,7 +369,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
| 369 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 369 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
| 370 | return; | 370 | return; |
| 371 | 371 | ||
| 372 | if (IS_IRONLAKE(dev)) { | 372 | if (HAS_PCH_SPLIT(dev)) { |
| 373 | dpll_a_reg = PCH_DPLL_A; | 373 | dpll_a_reg = PCH_DPLL_A; |
| 374 | dpll_b_reg = PCH_DPLL_B; | 374 | dpll_b_reg = PCH_DPLL_B; |
| 375 | fpa0_reg = PCH_FPA0; | 375 | fpa0_reg = PCH_FPA0; |
| @@ -385,7 +385,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
| 385 | fpb1_reg = FPB1; | 385 | fpb1_reg = FPB1; |
| 386 | } | 386 | } |
| 387 | 387 | ||
| 388 | if (IS_IRONLAKE(dev)) { | 388 | if (HAS_PCH_SPLIT(dev)) { |
| 389 | I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); | 389 | I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); |
| 390 | I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); | 390 | I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); |
| 391 | } | 391 | } |
| @@ -395,16 +395,20 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
| 395 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | 395 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { |
| 396 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A & | 396 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A & |
| 397 | ~DPLL_VCO_ENABLE); | 397 | ~DPLL_VCO_ENABLE); |
| 398 | DRM_UDELAY(150); | 398 | POSTING_READ(dpll_a_reg); |
| 399 | udelay(150); | ||
| 399 | } | 400 | } |
| 400 | I915_WRITE(fpa0_reg, dev_priv->saveFPA0); | 401 | I915_WRITE(fpa0_reg, dev_priv->saveFPA0); |
| 401 | I915_WRITE(fpa1_reg, dev_priv->saveFPA1); | 402 | I915_WRITE(fpa1_reg, dev_priv->saveFPA1); |
| 402 | /* Actually enable it */ | 403 | /* Actually enable it */ |
| 403 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A); | 404 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A); |
| 404 | DRM_UDELAY(150); | 405 | POSTING_READ(dpll_a_reg); |
| 405 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 406 | udelay(150); |
| 407 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) { | ||
| 406 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | 408 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); |
| 407 | DRM_UDELAY(150); | 409 | POSTING_READ(DPLL_A_MD); |
| 410 | } | ||
| 411 | udelay(150); | ||
| 408 | 412 | ||
| 409 | /* Restore mode */ | 413 | /* Restore mode */ |
| 410 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | 414 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); |
| @@ -413,10 +417,10 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
| 413 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | 417 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); |
| 414 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | 418 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); |
| 415 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | 419 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); |
| 416 | if (!IS_IRONLAKE(dev)) | 420 | if (!HAS_PCH_SPLIT(dev)) |
| 417 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | 421 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); |
| 418 | 422 | ||
| 419 | if (IS_IRONLAKE(dev)) { | 423 | if (HAS_PCH_SPLIT(dev)) { |
| 420 | I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); | 424 | I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); |
| 421 | I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); | 425 | I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); |
| 422 | I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); | 426 | I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); |
| @@ -460,16 +464,20 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
| 460 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | 464 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { |
| 461 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B & | 465 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B & |
| 462 | ~DPLL_VCO_ENABLE); | 466 | ~DPLL_VCO_ENABLE); |
| 463 | DRM_UDELAY(150); | 467 | POSTING_READ(dpll_b_reg); |
| 468 | udelay(150); | ||
| 464 | } | 469 | } |
| 465 | I915_WRITE(fpb0_reg, dev_priv->saveFPB0); | 470 | I915_WRITE(fpb0_reg, dev_priv->saveFPB0); |
| 466 | I915_WRITE(fpb1_reg, dev_priv->saveFPB1); | 471 | I915_WRITE(fpb1_reg, dev_priv->saveFPB1); |
| 467 | /* Actually enable it */ | 472 | /* Actually enable it */ |
| 468 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); | 473 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); |
| 469 | DRM_UDELAY(150); | 474 | POSTING_READ(dpll_b_reg); |
| 470 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 475 | udelay(150); |
| 476 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) { | ||
| 471 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | 477 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); |
| 472 | DRM_UDELAY(150); | 478 | POSTING_READ(DPLL_B_MD); |
| 479 | } | ||
| 480 | udelay(150); | ||
| 473 | 481 | ||
| 474 | /* Restore mode */ | 482 | /* Restore mode */ |
| 475 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | 483 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); |
| @@ -478,10 +486,10 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
| 478 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | 486 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); |
| 479 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | 487 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); |
| 480 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | 488 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); |
| 481 | if (!IS_IRONLAKE(dev)) | 489 | if (!HAS_PCH_SPLIT(dev)) |
| 482 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | 490 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); |
| 483 | 491 | ||
| 484 | if (IS_IRONLAKE(dev)) { | 492 | if (HAS_PCH_SPLIT(dev)) { |
| 485 | I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); | 493 | I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); |
| 486 | I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); | 494 | I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); |
| 487 | I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); | 495 | I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); |
| @@ -546,14 +554,14 @@ void i915_save_display(struct drm_device *dev) | |||
| 546 | dev_priv->saveCURSIZE = I915_READ(CURSIZE); | 554 | dev_priv->saveCURSIZE = I915_READ(CURSIZE); |
| 547 | 555 | ||
| 548 | /* CRT state */ | 556 | /* CRT state */ |
| 549 | if (IS_IRONLAKE(dev)) { | 557 | if (HAS_PCH_SPLIT(dev)) { |
| 550 | dev_priv->saveADPA = I915_READ(PCH_ADPA); | 558 | dev_priv->saveADPA = I915_READ(PCH_ADPA); |
| 551 | } else { | 559 | } else { |
| 552 | dev_priv->saveADPA = I915_READ(ADPA); | 560 | dev_priv->saveADPA = I915_READ(ADPA); |
| 553 | } | 561 | } |
| 554 | 562 | ||
| 555 | /* LVDS state */ | 563 | /* LVDS state */ |
| 556 | if (IS_IRONLAKE(dev)) { | 564 | if (HAS_PCH_SPLIT(dev)) { |
| 557 | dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL); | 565 | dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL); |
| 558 | dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); | 566 | dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); |
| 559 | dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); | 567 | dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); |
| @@ -571,10 +579,10 @@ void i915_save_display(struct drm_device *dev) | |||
| 571 | dev_priv->saveLVDS = I915_READ(LVDS); | 579 | dev_priv->saveLVDS = I915_READ(LVDS); |
| 572 | } | 580 | } |
| 573 | 581 | ||
| 574 | if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev)) | 582 | if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) |
| 575 | dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); | 583 | dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); |
| 576 | 584 | ||
| 577 | if (IS_IRONLAKE(dev)) { | 585 | if (HAS_PCH_SPLIT(dev)) { |
| 578 | dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); | 586 | dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); |
| 579 | dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); | 587 | dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); |
| 580 | dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); | 588 | dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); |
| @@ -602,7 +610,7 @@ void i915_save_display(struct drm_device *dev) | |||
| 602 | 610 | ||
| 603 | /* Only save FBC state on the platform that supports FBC */ | 611 | /* Only save FBC state on the platform that supports FBC */ |
| 604 | if (I915_HAS_FBC(dev)) { | 612 | if (I915_HAS_FBC(dev)) { |
| 605 | if (IS_IRONLAKE_M(dev)) { | 613 | if (HAS_PCH_SPLIT(dev)) { |
| 606 | dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE); | 614 | dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE); |
| 607 | } else if (IS_GM45(dev)) { | 615 | } else if (IS_GM45(dev)) { |
| 608 | dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); | 616 | dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); |
| @@ -618,7 +626,7 @@ void i915_save_display(struct drm_device *dev) | |||
| 618 | dev_priv->saveVGA0 = I915_READ(VGA0); | 626 | dev_priv->saveVGA0 = I915_READ(VGA0); |
| 619 | dev_priv->saveVGA1 = I915_READ(VGA1); | 627 | dev_priv->saveVGA1 = I915_READ(VGA1); |
| 620 | dev_priv->saveVGA_PD = I915_READ(VGA_PD); | 628 | dev_priv->saveVGA_PD = I915_READ(VGA_PD); |
| 621 | if (IS_IRONLAKE(dev)) | 629 | if (HAS_PCH_SPLIT(dev)) |
| 622 | dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL); | 630 | dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL); |
| 623 | else | 631 | else |
| 624 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); | 632 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); |
| @@ -660,24 +668,24 @@ void i915_restore_display(struct drm_device *dev) | |||
| 660 | I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); | 668 | I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); |
| 661 | 669 | ||
| 662 | /* CRT state */ | 670 | /* CRT state */ |
| 663 | if (IS_IRONLAKE(dev)) | 671 | if (HAS_PCH_SPLIT(dev)) |
| 664 | I915_WRITE(PCH_ADPA, dev_priv->saveADPA); | 672 | I915_WRITE(PCH_ADPA, dev_priv->saveADPA); |
| 665 | else | 673 | else |
| 666 | I915_WRITE(ADPA, dev_priv->saveADPA); | 674 | I915_WRITE(ADPA, dev_priv->saveADPA); |
| 667 | 675 | ||
| 668 | /* LVDS state */ | 676 | /* LVDS state */ |
| 669 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 677 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) |
| 670 | I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); | 678 | I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); |
| 671 | 679 | ||
| 672 | if (IS_IRONLAKE(dev)) { | 680 | if (HAS_PCH_SPLIT(dev)) { |
| 673 | I915_WRITE(PCH_LVDS, dev_priv->saveLVDS); | 681 | I915_WRITE(PCH_LVDS, dev_priv->saveLVDS); |
| 674 | } else if (IS_MOBILE(dev) && !IS_I830(dev)) | 682 | } else if (IS_MOBILE(dev) && !IS_I830(dev)) |
| 675 | I915_WRITE(LVDS, dev_priv->saveLVDS); | 683 | I915_WRITE(LVDS, dev_priv->saveLVDS); |
| 676 | 684 | ||
| 677 | if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev)) | 685 | if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) |
| 678 | I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); | 686 | I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); |
| 679 | 687 | ||
| 680 | if (IS_IRONLAKE(dev)) { | 688 | if (HAS_PCH_SPLIT(dev)) { |
| 681 | I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); | 689 | I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); |
| 682 | I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); | 690 | I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); |
| 683 | I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); | 691 | I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); |
| @@ -708,7 +716,7 @@ void i915_restore_display(struct drm_device *dev) | |||
| 708 | 716 | ||
| 709 | /* only restore FBC info on the platform that supports FBC*/ | 717 | /* only restore FBC info on the platform that supports FBC*/ |
| 710 | if (I915_HAS_FBC(dev)) { | 718 | if (I915_HAS_FBC(dev)) { |
| 711 | if (IS_IRONLAKE_M(dev)) { | 719 | if (HAS_PCH_SPLIT(dev)) { |
| 712 | ironlake_disable_fbc(dev); | 720 | ironlake_disable_fbc(dev); |
| 713 | I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); | 721 | I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); |
| 714 | } else if (IS_GM45(dev)) { | 722 | } else if (IS_GM45(dev)) { |
| @@ -723,14 +731,15 @@ void i915_restore_display(struct drm_device *dev) | |||
| 723 | } | 731 | } |
| 724 | } | 732 | } |
| 725 | /* VGA state */ | 733 | /* VGA state */ |
| 726 | if (IS_IRONLAKE(dev)) | 734 | if (HAS_PCH_SPLIT(dev)) |
| 727 | I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); | 735 | I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); |
| 728 | else | 736 | else |
| 729 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); | 737 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); |
| 730 | I915_WRITE(VGA0, dev_priv->saveVGA0); | 738 | I915_WRITE(VGA0, dev_priv->saveVGA0); |
| 731 | I915_WRITE(VGA1, dev_priv->saveVGA1); | 739 | I915_WRITE(VGA1, dev_priv->saveVGA1); |
| 732 | I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); | 740 | I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); |
| 733 | DRM_UDELAY(150); | 741 | POSTING_READ(VGA_PD); |
| 742 | udelay(150); | ||
| 734 | 743 | ||
| 735 | i915_restore_vga(dev); | 744 | i915_restore_vga(dev); |
| 736 | } | 745 | } |
| @@ -748,7 +757,7 @@ int i915_save_state(struct drm_device *dev) | |||
| 748 | i915_save_display(dev); | 757 | i915_save_display(dev); |
| 749 | 758 | ||
| 750 | /* Interrupt state */ | 759 | /* Interrupt state */ |
| 751 | if (IS_IRONLAKE(dev)) { | 760 | if (HAS_PCH_SPLIT(dev)) { |
| 752 | dev_priv->saveDEIER = I915_READ(DEIER); | 761 | dev_priv->saveDEIER = I915_READ(DEIER); |
| 753 | dev_priv->saveDEIMR = I915_READ(DEIMR); | 762 | dev_priv->saveDEIMR = I915_READ(DEIMR); |
| 754 | dev_priv->saveGTIER = I915_READ(GTIER); | 763 | dev_priv->saveGTIER = I915_READ(GTIER); |
| @@ -762,7 +771,7 @@ int i915_save_state(struct drm_device *dev) | |||
| 762 | dev_priv->saveIMR = I915_READ(IMR); | 771 | dev_priv->saveIMR = I915_READ(IMR); |
| 763 | } | 772 | } |
| 764 | 773 | ||
| 765 | if (IS_IRONLAKE_M(dev)) | 774 | if (HAS_PCH_SPLIT(dev)) |
| 766 | ironlake_disable_drps(dev); | 775 | ironlake_disable_drps(dev); |
| 767 | 776 | ||
| 768 | /* Cache mode state */ | 777 | /* Cache mode state */ |
| @@ -820,7 +829,7 @@ int i915_restore_state(struct drm_device *dev) | |||
| 820 | i915_restore_display(dev); | 829 | i915_restore_display(dev); |
| 821 | 830 | ||
| 822 | /* Interrupt state */ | 831 | /* Interrupt state */ |
| 823 | if (IS_IRONLAKE(dev)) { | 832 | if (HAS_PCH_SPLIT(dev)) { |
| 824 | I915_WRITE(DEIER, dev_priv->saveDEIER); | 833 | I915_WRITE(DEIER, dev_priv->saveDEIER); |
| 825 | I915_WRITE(DEIMR, dev_priv->saveDEIMR); | 834 | I915_WRITE(DEIMR, dev_priv->saveDEIMR); |
| 826 | I915_WRITE(GTIER, dev_priv->saveGTIER); | 835 | I915_WRITE(GTIER, dev_priv->saveGTIER); |
| @@ -835,7 +844,7 @@ int i915_restore_state(struct drm_device *dev) | |||
| 835 | /* Clock gating state */ | 844 | /* Clock gating state */ |
| 836 | intel_init_clock_gating(dev); | 845 | intel_init_clock_gating(dev); |
| 837 | 846 | ||
| 838 | if (IS_IRONLAKE_M(dev)) | 847 | if (HAS_PCH_SPLIT(dev)) |
| 839 | ironlake_enable_drps(dev); | 848 | ironlake_enable_drps(dev); |
| 840 | 849 | ||
| 841 | /* Cache mode state */ | 850 | /* Cache mode state */ |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index ee0732b222a..4b7735196cd 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -160,19 +160,20 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
| 160 | struct drm_i915_private *dev_priv = dev->dev_private; | 160 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 161 | u32 adpa, temp; | 161 | u32 adpa, temp; |
| 162 | bool ret; | 162 | bool ret; |
| 163 | bool turn_off_dac = false; | ||
| 163 | 164 | ||
| 164 | temp = adpa = I915_READ(PCH_ADPA); | 165 | temp = adpa = I915_READ(PCH_ADPA); |
| 165 | 166 | ||
| 166 | if (HAS_PCH_CPT(dev)) { | 167 | if (HAS_PCH_SPLIT(dev)) |
| 167 | /* Disable DAC before force detect */ | 168 | turn_off_dac = true; |
| 168 | I915_WRITE(PCH_ADPA, adpa & ~ADPA_DAC_ENABLE); | 169 | |
| 169 | (void)I915_READ(PCH_ADPA); | 170 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; |
| 170 | } else { | 171 | if (turn_off_dac) |
| 171 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; | 172 | adpa &= ~ADPA_DAC_ENABLE; |
| 172 | /* disable HPD first */ | 173 | |
| 173 | I915_WRITE(PCH_ADPA, adpa); | 174 | /* disable HPD first */ |
| 174 | (void)I915_READ(PCH_ADPA); | 175 | I915_WRITE(PCH_ADPA, adpa); |
| 175 | } | 176 | (void)I915_READ(PCH_ADPA); |
| 176 | 177 | ||
| 177 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | | 178 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | |
| 178 | ADPA_CRT_HOTPLUG_WARMUP_10MS | | 179 | ADPA_CRT_HOTPLUG_WARMUP_10MS | |
| @@ -185,10 +186,11 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
| 185 | DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa); | 186 | DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa); |
| 186 | I915_WRITE(PCH_ADPA, adpa); | 187 | I915_WRITE(PCH_ADPA, adpa); |
| 187 | 188 | ||
| 188 | while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0) | 189 | if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, |
| 189 | ; | 190 | 1000, 1)) |
| 191 | DRM_ERROR("timed out waiting for FORCE_TRIGGER"); | ||
| 190 | 192 | ||
| 191 | if (HAS_PCH_CPT(dev)) { | 193 | if (turn_off_dac) { |
| 192 | I915_WRITE(PCH_ADPA, temp); | 194 | I915_WRITE(PCH_ADPA, temp); |
| 193 | (void)I915_READ(PCH_ADPA); | 195 | (void)I915_READ(PCH_ADPA); |
| 194 | } | 196 | } |
| @@ -237,17 +239,13 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
| 237 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; | 239 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; |
| 238 | 240 | ||
| 239 | for (i = 0; i < tries ; i++) { | 241 | for (i = 0; i < tries ; i++) { |
| 240 | unsigned long timeout; | ||
| 241 | /* turn on the FORCE_DETECT */ | 242 | /* turn on the FORCE_DETECT */ |
| 242 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | 243 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
| 243 | timeout = jiffies + msecs_to_jiffies(1000); | ||
| 244 | /* wait for FORCE_DETECT to go off */ | 244 | /* wait for FORCE_DETECT to go off */ |
| 245 | do { | 245 | if (wait_for((I915_READ(PORT_HOTPLUG_EN) & |
| 246 | if (!(I915_READ(PORT_HOTPLUG_EN) & | 246 | CRT_HOTPLUG_FORCE_DETECT) == 0, |
| 247 | CRT_HOTPLUG_FORCE_DETECT)) | 247 | 1000, 1)) |
| 248 | break; | 248 | DRM_ERROR("timed out waiting for FORCE_DETECT to go off"); |
| 249 | msleep(1); | ||
| 250 | } while (time_after(timeout, jiffies)); | ||
| 251 | } | 249 | } |
| 252 | 250 | ||
| 253 | stat = I915_READ(PORT_HOTPLUG_STAT); | 251 | stat = I915_READ(PORT_HOTPLUG_STAT); |
| @@ -331,7 +329,7 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
| 331 | I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); | 329 | I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); |
| 332 | /* Wait for next Vblank to substitue | 330 | /* Wait for next Vblank to substitue |
| 333 | * border color for Color info */ | 331 | * border color for Color info */ |
| 334 | intel_wait_for_vblank(dev); | 332 | intel_wait_for_vblank(dev, pipe); |
| 335 | st00 = I915_READ8(VGA_MSR_WRITE); | 333 | st00 = I915_READ8(VGA_MSR_WRITE); |
| 336 | status = ((st00 & (1 << 4)) != 0) ? | 334 | status = ((st00 & (1 << 4)) != 0) ? |
| 337 | connector_status_connected : | 335 | connector_status_connected : |
| @@ -508,17 +506,8 @@ static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs | |||
| 508 | .best_encoder = intel_attached_encoder, | 506 | .best_encoder = intel_attached_encoder, |
| 509 | }; | 507 | }; |
| 510 | 508 | ||
| 511 | static void intel_crt_enc_destroy(struct drm_encoder *encoder) | ||
| 512 | { | ||
| 513 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 514 | |||
| 515 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
| 516 | drm_encoder_cleanup(encoder); | ||
| 517 | kfree(intel_encoder); | ||
| 518 | } | ||
| 519 | |||
| 520 | static const struct drm_encoder_funcs intel_crt_enc_funcs = { | 509 | static const struct drm_encoder_funcs intel_crt_enc_funcs = { |
| 521 | .destroy = intel_crt_enc_destroy, | 510 | .destroy = intel_encoder_destroy, |
| 522 | }; | 511 | }; |
| 523 | 512 | ||
| 524 | void intel_crt_init(struct drm_device *dev) | 513 | void intel_crt_init(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5ec10e02341..23157e1de3b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
| 30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include <linux/vgaarb.h> | ||
| 32 | #include "drmP.h" | 33 | #include "drmP.h" |
| 33 | #include "intel_drv.h" | 34 | #include "intel_drv.h" |
| 34 | #include "i915_drm.h" | 35 | #include "i915_drm.h" |
| @@ -976,14 +977,54 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
| 976 | return true; | 977 | return true; |
| 977 | } | 978 | } |
| 978 | 979 | ||
| 979 | void | 980 | /** |
| 980 | intel_wait_for_vblank(struct drm_device *dev) | 981 | * intel_wait_for_vblank - wait for vblank on a given pipe |
| 982 | * @dev: drm device | ||
| 983 | * @pipe: pipe to wait for | ||
| 984 | * | ||
| 985 | * Wait for vblank to occur on a given pipe. Needed for various bits of | ||
| 986 | * mode setting code. | ||
| 987 | */ | ||
| 988 | void intel_wait_for_vblank(struct drm_device *dev, int pipe) | ||
| 981 | { | 989 | { |
| 982 | /* Wait for 20ms, i.e. one cycle at 50hz. */ | 990 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 983 | if (in_dbg_master()) | 991 | int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT); |
| 984 | mdelay(20); /* The kernel debugger cannot call msleep() */ | 992 | |
| 985 | else | 993 | /* Wait for vblank interrupt bit to set */ |
| 986 | msleep(20); | 994 | if (wait_for((I915_READ(pipestat_reg) & |
| 995 | PIPE_VBLANK_INTERRUPT_STATUS) == 0, | ||
| 996 | 50, 0)) | ||
| 997 | DRM_DEBUG_KMS("vblank wait timed out\n"); | ||
| 998 | } | ||
| 999 | |||
| 1000 | /** | ||
| 1001 | * intel_wait_for_vblank_off - wait for vblank after disabling a pipe | ||
| 1002 | * @dev: drm device | ||
| 1003 | * @pipe: pipe to wait for | ||
| 1004 | * | ||
| 1005 | * After disabling a pipe, we can't wait for vblank in the usual way, | ||
| 1006 | * spinning on the vblank interrupt status bit, since we won't actually | ||
| 1007 | * see an interrupt when the pipe is disabled. | ||
| 1008 | * | ||
| 1009 | * So this function waits for the display line value to settle (it | ||
| 1010 | * usually ends up stopping at the start of the next frame). | ||
| 1011 | */ | ||
| 1012 | void intel_wait_for_vblank_off(struct drm_device *dev, int pipe) | ||
| 1013 | { | ||
| 1014 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1015 | int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); | ||
| 1016 | unsigned long timeout = jiffies + msecs_to_jiffies(100); | ||
| 1017 | u32 last_line; | ||
| 1018 | |||
| 1019 | /* Wait for the display line to settle */ | ||
| 1020 | do { | ||
| 1021 | last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; | ||
| 1022 | mdelay(5); | ||
| 1023 | } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && | ||
| 1024 | time_after(timeout, jiffies)); | ||
| 1025 | |||
| 1026 | if (time_after(jiffies, timeout)) | ||
| 1027 | DRM_DEBUG_KMS("vblank wait timed out\n"); | ||
| 987 | } | 1028 | } |
| 988 | 1029 | ||
| 989 | /* Parameters have changed, update FBC info */ | 1030 | /* Parameters have changed, update FBC info */ |
| @@ -1037,7 +1078,6 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
| 1037 | void i8xx_disable_fbc(struct drm_device *dev) | 1078 | void i8xx_disable_fbc(struct drm_device *dev) |
| 1038 | { | 1079 | { |
| 1039 | struct drm_i915_private *dev_priv = dev->dev_private; | 1080 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1040 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | ||
| 1041 | u32 fbc_ctl; | 1081 | u32 fbc_ctl; |
| 1042 | 1082 | ||
| 1043 | if (!I915_HAS_FBC(dev)) | 1083 | if (!I915_HAS_FBC(dev)) |
| @@ -1052,16 +1092,11 @@ void i8xx_disable_fbc(struct drm_device *dev) | |||
| 1052 | I915_WRITE(FBC_CONTROL, fbc_ctl); | 1092 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
| 1053 | 1093 | ||
| 1054 | /* Wait for compressing bit to clear */ | 1094 | /* Wait for compressing bit to clear */ |
| 1055 | while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) { | 1095 | if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10, 0)) { |
| 1056 | if (time_after(jiffies, timeout)) { | 1096 | DRM_DEBUG_KMS("FBC idle timed out\n"); |
| 1057 | DRM_DEBUG_DRIVER("FBC idle timed out\n"); | 1097 | return; |
| 1058 | break; | ||
| 1059 | } | ||
| 1060 | ; /* do nothing */ | ||
| 1061 | } | 1098 | } |
| 1062 | 1099 | ||
| 1063 | intel_wait_for_vblank(dev); | ||
| 1064 | |||
| 1065 | DRM_DEBUG_KMS("disabled FBC\n"); | 1100 | DRM_DEBUG_KMS("disabled FBC\n"); |
| 1066 | } | 1101 | } |
| 1067 | 1102 | ||
| @@ -1118,7 +1153,6 @@ void g4x_disable_fbc(struct drm_device *dev) | |||
| 1118 | dpfc_ctl = I915_READ(DPFC_CONTROL); | 1153 | dpfc_ctl = I915_READ(DPFC_CONTROL); |
| 1119 | dpfc_ctl &= ~DPFC_CTL_EN; | 1154 | dpfc_ctl &= ~DPFC_CTL_EN; |
| 1120 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); | 1155 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); |
| 1121 | intel_wait_for_vblank(dev); | ||
| 1122 | 1156 | ||
| 1123 | DRM_DEBUG_KMS("disabled FBC\n"); | 1157 | DRM_DEBUG_KMS("disabled FBC\n"); |
| 1124 | } | 1158 | } |
| @@ -1179,7 +1213,6 @@ void ironlake_disable_fbc(struct drm_device *dev) | |||
| 1179 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | 1213 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); |
| 1180 | dpfc_ctl &= ~DPFC_CTL_EN; | 1214 | dpfc_ctl &= ~DPFC_CTL_EN; |
| 1181 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); | 1215 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); |
| 1182 | intel_wait_for_vblank(dev); | ||
| 1183 | 1216 | ||
| 1184 | DRM_DEBUG_KMS("disabled FBC\n"); | 1217 | DRM_DEBUG_KMS("disabled FBC\n"); |
| 1185 | } | 1218 | } |
| @@ -1478,7 +1511,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
| 1478 | if ((IS_I965G(dev) || plane == 0)) | 1511 | if ((IS_I965G(dev) || plane == 0)) |
| 1479 | intel_update_fbc(crtc, &crtc->mode); | 1512 | intel_update_fbc(crtc, &crtc->mode); |
| 1480 | 1513 | ||
| 1481 | intel_wait_for_vblank(dev); | 1514 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 1482 | intel_increase_pllclock(crtc, true); | 1515 | intel_increase_pllclock(crtc, true); |
| 1483 | 1516 | ||
| 1484 | return 0; | 1517 | return 0; |
| @@ -1585,20 +1618,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 1585 | Start, Offset, x, y, crtc->fb->pitch); | 1618 | Start, Offset, x, y, crtc->fb->pitch); |
| 1586 | I915_WRITE(dspstride, crtc->fb->pitch); | 1619 | I915_WRITE(dspstride, crtc->fb->pitch); |
| 1587 | if (IS_I965G(dev)) { | 1620 | if (IS_I965G(dev)) { |
| 1588 | I915_WRITE(dspbase, Offset); | ||
| 1589 | I915_READ(dspbase); | ||
| 1590 | I915_WRITE(dspsurf, Start); | 1621 | I915_WRITE(dspsurf, Start); |
| 1591 | I915_READ(dspsurf); | ||
| 1592 | I915_WRITE(dsptileoff, (y << 16) | x); | 1622 | I915_WRITE(dsptileoff, (y << 16) | x); |
| 1623 | I915_WRITE(dspbase, Offset); | ||
| 1593 | } else { | 1624 | } else { |
| 1594 | I915_WRITE(dspbase, Start + Offset); | 1625 | I915_WRITE(dspbase, Start + Offset); |
| 1595 | I915_READ(dspbase); | ||
| 1596 | } | 1626 | } |
| 1627 | POSTING_READ(dspbase); | ||
| 1597 | 1628 | ||
| 1598 | if ((IS_I965G(dev) || plane == 0)) | 1629 | if ((IS_I965G(dev) || plane == 0)) |
| 1599 | intel_update_fbc(crtc, &crtc->mode); | 1630 | intel_update_fbc(crtc, &crtc->mode); |
| 1600 | 1631 | ||
| 1601 | intel_wait_for_vblank(dev); | 1632 | intel_wait_for_vblank(dev, pipe); |
| 1602 | 1633 | ||
| 1603 | if (old_fb) { | 1634 | if (old_fb) { |
| 1604 | intel_fb = to_intel_framebuffer(old_fb); | 1635 | intel_fb = to_intel_framebuffer(old_fb); |
| @@ -1627,54 +1658,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 1627 | return 0; | 1658 | return 0; |
| 1628 | } | 1659 | } |
| 1629 | 1660 | ||
| 1630 | /* Disable the VGA plane that we never use */ | ||
| 1631 | static void i915_disable_vga (struct drm_device *dev) | ||
| 1632 | { | ||
| 1633 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1634 | u8 sr1; | ||
| 1635 | u32 vga_reg; | ||
| 1636 | |||
| 1637 | if (HAS_PCH_SPLIT(dev)) | ||
| 1638 | vga_reg = CPU_VGACNTRL; | ||
| 1639 | else | ||
| 1640 | vga_reg = VGACNTRL; | ||
| 1641 | |||
| 1642 | if (I915_READ(vga_reg) & VGA_DISP_DISABLE) | ||
| 1643 | return; | ||
| 1644 | |||
| 1645 | I915_WRITE8(VGA_SR_INDEX, 1); | ||
| 1646 | sr1 = I915_READ8(VGA_SR_DATA); | ||
| 1647 | I915_WRITE8(VGA_SR_DATA, sr1 | (1 << 5)); | ||
| 1648 | udelay(100); | ||
| 1649 | |||
| 1650 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
| 1651 | } | ||
| 1652 | |||
| 1653 | static void ironlake_disable_pll_edp (struct drm_crtc *crtc) | ||
| 1654 | { | ||
| 1655 | struct drm_device *dev = crtc->dev; | ||
| 1656 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1657 | u32 dpa_ctl; | ||
| 1658 | |||
| 1659 | DRM_DEBUG_KMS("\n"); | ||
| 1660 | dpa_ctl = I915_READ(DP_A); | ||
| 1661 | dpa_ctl &= ~DP_PLL_ENABLE; | ||
| 1662 | I915_WRITE(DP_A, dpa_ctl); | ||
| 1663 | } | ||
| 1664 | |||
| 1665 | static void ironlake_enable_pll_edp (struct drm_crtc *crtc) | ||
| 1666 | { | ||
| 1667 | struct drm_device *dev = crtc->dev; | ||
| 1668 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1669 | u32 dpa_ctl; | ||
| 1670 | |||
| 1671 | dpa_ctl = I915_READ(DP_A); | ||
| 1672 | dpa_ctl |= DP_PLL_ENABLE; | ||
| 1673 | I915_WRITE(DP_A, dpa_ctl); | ||
| 1674 | udelay(200); | ||
| 1675 | } | ||
| 1676 | |||
| 1677 | |||
| 1678 | static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock) | 1661 | static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock) |
| 1679 | { | 1662 | { |
| 1680 | struct drm_device *dev = crtc->dev; | 1663 | struct drm_device *dev = crtc->dev; |
| @@ -1945,7 +1928,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 1945 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; | 1928 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; |
| 1946 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; | 1929 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; |
| 1947 | u32 temp; | 1930 | u32 temp; |
| 1948 | int n; | ||
| 1949 | u32 pipe_bpc; | 1931 | u32 pipe_bpc; |
| 1950 | 1932 | ||
| 1951 | temp = I915_READ(pipeconf_reg); | 1933 | temp = I915_READ(pipeconf_reg); |
| @@ -1958,7 +1940,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 1958 | case DRM_MODE_DPMS_ON: | 1940 | case DRM_MODE_DPMS_ON: |
| 1959 | case DRM_MODE_DPMS_STANDBY: | 1941 | case DRM_MODE_DPMS_STANDBY: |
| 1960 | case DRM_MODE_DPMS_SUSPEND: | 1942 | case DRM_MODE_DPMS_SUSPEND: |
| 1961 | DRM_DEBUG_KMS("crtc %d dpms on\n", pipe); | 1943 | DRM_DEBUG_KMS("crtc %d/%d dpms on\n", pipe, plane); |
| 1962 | 1944 | ||
| 1963 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 1945 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
| 1964 | temp = I915_READ(PCH_LVDS); | 1946 | temp = I915_READ(PCH_LVDS); |
| @@ -1968,10 +1950,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 1968 | } | 1950 | } |
| 1969 | } | 1951 | } |
| 1970 | 1952 | ||
| 1971 | if (HAS_eDP) { | 1953 | if (!HAS_eDP) { |
| 1972 | /* enable eDP PLL */ | ||
| 1973 | ironlake_enable_pll_edp(crtc); | ||
| 1974 | } else { | ||
| 1975 | 1954 | ||
| 1976 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ | 1955 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ |
| 1977 | temp = I915_READ(fdi_rx_reg); | 1956 | temp = I915_READ(fdi_rx_reg); |
| @@ -2005,15 +1984,13 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2005 | /* Enable panel fitting for LVDS */ | 1984 | /* Enable panel fitting for LVDS */ |
| 2006 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) | 1985 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) |
| 2007 | || HAS_eDP || intel_pch_has_edp(crtc)) { | 1986 | || HAS_eDP || intel_pch_has_edp(crtc)) { |
| 2008 | temp = I915_READ(pf_ctl_reg); | 1987 | if (dev_priv->pch_pf_size) { |
| 2009 | I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); | 1988 | temp = I915_READ(pf_ctl_reg); |
| 2010 | 1989 | I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); | |
| 2011 | /* currently full aspect */ | 1990 | I915_WRITE(pf_win_pos, dev_priv->pch_pf_pos); |
| 2012 | I915_WRITE(pf_win_pos, 0); | 1991 | I915_WRITE(pf_win_size, dev_priv->pch_pf_size); |
| 2013 | 1992 | } else | |
| 2014 | I915_WRITE(pf_win_size, | 1993 | I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); |
| 2015 | (dev_priv->panel_fixed_mode->hdisplay << 16) | | ||
| 2016 | (dev_priv->panel_fixed_mode->vdisplay)); | ||
| 2017 | } | 1994 | } |
| 2018 | 1995 | ||
| 2019 | /* Enable CPU pipe */ | 1996 | /* Enable CPU pipe */ |
| @@ -2097,9 +2074,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2097 | int reg; | 2074 | int reg; |
| 2098 | 2075 | ||
| 2099 | reg = I915_READ(trans_dp_ctl); | 2076 | reg = I915_READ(trans_dp_ctl); |
| 2100 | reg &= ~TRANS_DP_PORT_SEL_MASK; | 2077 | reg &= ~(TRANS_DP_PORT_SEL_MASK | |
| 2101 | reg = TRANS_DP_OUTPUT_ENABLE | | 2078 | TRANS_DP_SYNC_MASK); |
| 2102 | TRANS_DP_ENH_FRAMING; | 2079 | reg |= (TRANS_DP_OUTPUT_ENABLE | |
| 2080 | TRANS_DP_ENH_FRAMING); | ||
| 2103 | 2081 | ||
| 2104 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | 2082 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
| 2105 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; | 2083 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; |
| @@ -2137,18 +2115,17 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2137 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | 2115 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); |
| 2138 | I915_READ(transconf_reg); | 2116 | I915_READ(transconf_reg); |
| 2139 | 2117 | ||
| 2140 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) | 2118 | if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 10, 0)) |
| 2141 | ; | 2119 | DRM_ERROR("failed to enable transcoder\n"); |
| 2142 | |||
| 2143 | } | 2120 | } |
| 2144 | 2121 | ||
| 2145 | intel_crtc_load_lut(crtc); | 2122 | intel_crtc_load_lut(crtc); |
| 2146 | 2123 | ||
| 2147 | intel_update_fbc(crtc, &crtc->mode); | 2124 | intel_update_fbc(crtc, &crtc->mode); |
| 2125 | break; | ||
| 2148 | 2126 | ||
| 2149 | break; | ||
| 2150 | case DRM_MODE_DPMS_OFF: | 2127 | case DRM_MODE_DPMS_OFF: |
| 2151 | DRM_DEBUG_KMS("crtc %d dpms off\n", pipe); | 2128 | DRM_DEBUG_KMS("crtc %d/%d dpms off\n", pipe, plane); |
| 2152 | 2129 | ||
| 2153 | drm_vblank_off(dev, pipe); | 2130 | drm_vblank_off(dev, pipe); |
| 2154 | /* Disable display plane */ | 2131 | /* Disable display plane */ |
| @@ -2164,26 +2141,14 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2164 | dev_priv->display.disable_fbc) | 2141 | dev_priv->display.disable_fbc) |
| 2165 | dev_priv->display.disable_fbc(dev); | 2142 | dev_priv->display.disable_fbc(dev); |
| 2166 | 2143 | ||
| 2167 | i915_disable_vga(dev); | ||
| 2168 | |||
| 2169 | /* disable cpu pipe, disable after all planes disabled */ | 2144 | /* disable cpu pipe, disable after all planes disabled */ |
| 2170 | temp = I915_READ(pipeconf_reg); | 2145 | temp = I915_READ(pipeconf_reg); |
| 2171 | if ((temp & PIPEACONF_ENABLE) != 0) { | 2146 | if ((temp & PIPEACONF_ENABLE) != 0) { |
| 2172 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); | 2147 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); |
| 2173 | I915_READ(pipeconf_reg); | 2148 | |
| 2174 | n = 0; | ||
| 2175 | /* wait for cpu pipe off, pipe state */ | 2149 | /* wait for cpu pipe off, pipe state */ |
| 2176 | while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) { | 2150 | if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0, 50, 1)) |
| 2177 | n++; | 2151 | DRM_ERROR("failed to turn off cpu pipe\n"); |
| 2178 | if (n < 60) { | ||
| 2179 | udelay(500); | ||
| 2180 | continue; | ||
| 2181 | } else { | ||
| 2182 | DRM_DEBUG_KMS("pipe %d off delay\n", | ||
| 2183 | pipe); | ||
| 2184 | break; | ||
| 2185 | } | ||
| 2186 | } | ||
| 2187 | } else | 2152 | } else |
| 2188 | DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); | 2153 | DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); |
| 2189 | 2154 | ||
| @@ -2244,20 +2209,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2244 | temp = I915_READ(transconf_reg); | 2209 | temp = I915_READ(transconf_reg); |
| 2245 | if ((temp & TRANS_ENABLE) != 0) { | 2210 | if ((temp & TRANS_ENABLE) != 0) { |
| 2246 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); | 2211 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); |
| 2247 | I915_READ(transconf_reg); | 2212 | |
| 2248 | n = 0; | ||
| 2249 | /* wait for PCH transcoder off, transcoder state */ | 2213 | /* wait for PCH transcoder off, transcoder state */ |
| 2250 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) { | 2214 | if (wait_for((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0, 50, 1)) |
| 2251 | n++; | 2215 | DRM_ERROR("failed to disable transcoder\n"); |
| 2252 | if (n < 60) { | ||
| 2253 | udelay(500); | ||
| 2254 | continue; | ||
| 2255 | } else { | ||
| 2256 | DRM_DEBUG_KMS("transcoder %d off " | ||
| 2257 | "delay\n", pipe); | ||
| 2258 | break; | ||
| 2259 | } | ||
| 2260 | } | ||
| 2261 | } | 2216 | } |
| 2262 | 2217 | ||
| 2263 | temp = I915_READ(transconf_reg); | 2218 | temp = I915_READ(transconf_reg); |
| @@ -2294,10 +2249,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2294 | I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE); | 2249 | I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE); |
| 2295 | I915_READ(pch_dpll_reg); | 2250 | I915_READ(pch_dpll_reg); |
| 2296 | 2251 | ||
| 2297 | if (HAS_eDP) { | ||
| 2298 | ironlake_disable_pll_edp(crtc); | ||
| 2299 | } | ||
| 2300 | |||
| 2301 | /* Switch from PCDclk to Rawclk */ | 2252 | /* Switch from PCDclk to Rawclk */ |
| 2302 | temp = I915_READ(fdi_rx_reg); | 2253 | temp = I915_READ(fdi_rx_reg); |
| 2303 | temp &= ~FDI_SEL_PCDCLK; | 2254 | temp &= ~FDI_SEL_PCDCLK; |
| @@ -2372,8 +2323,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2372 | case DRM_MODE_DPMS_ON: | 2323 | case DRM_MODE_DPMS_ON: |
| 2373 | case DRM_MODE_DPMS_STANDBY: | 2324 | case DRM_MODE_DPMS_STANDBY: |
| 2374 | case DRM_MODE_DPMS_SUSPEND: | 2325 | case DRM_MODE_DPMS_SUSPEND: |
| 2375 | intel_update_watermarks(dev); | ||
| 2376 | |||
| 2377 | /* Enable the DPLL */ | 2326 | /* Enable the DPLL */ |
| 2378 | temp = I915_READ(dpll_reg); | 2327 | temp = I915_READ(dpll_reg); |
| 2379 | if ((temp & DPLL_VCO_ENABLE) == 0) { | 2328 | if ((temp & DPLL_VCO_ENABLE) == 0) { |
| @@ -2413,8 +2362,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2413 | intel_crtc_dpms_overlay(intel_crtc, true); | 2362 | intel_crtc_dpms_overlay(intel_crtc, true); |
| 2414 | break; | 2363 | break; |
| 2415 | case DRM_MODE_DPMS_OFF: | 2364 | case DRM_MODE_DPMS_OFF: |
| 2416 | intel_update_watermarks(dev); | ||
| 2417 | |||
| 2418 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 2365 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
| 2419 | intel_crtc_dpms_overlay(intel_crtc, false); | 2366 | intel_crtc_dpms_overlay(intel_crtc, false); |
| 2420 | drm_vblank_off(dev, pipe); | 2367 | drm_vblank_off(dev, pipe); |
| @@ -2423,9 +2370,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2423 | dev_priv->display.disable_fbc) | 2370 | dev_priv->display.disable_fbc) |
| 2424 | dev_priv->display.disable_fbc(dev); | 2371 | dev_priv->display.disable_fbc(dev); |
| 2425 | 2372 | ||
| 2426 | /* Disable the VGA plane that we never use */ | ||
| 2427 | i915_disable_vga(dev); | ||
| 2428 | |||
| 2429 | /* Disable display plane */ | 2373 | /* Disable display plane */ |
| 2430 | temp = I915_READ(dspcntr_reg); | 2374 | temp = I915_READ(dspcntr_reg); |
| 2431 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { | 2375 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { |
| @@ -2435,10 +2379,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2435 | I915_READ(dspbase_reg); | 2379 | I915_READ(dspbase_reg); |
| 2436 | } | 2380 | } |
| 2437 | 2381 | ||
| 2438 | if (!IS_I9XX(dev)) { | 2382 | /* Wait for vblank for the disable to take effect */ |
| 2439 | /* Wait for vblank for the disable to take effect */ | 2383 | intel_wait_for_vblank_off(dev, pipe); |
| 2440 | intel_wait_for_vblank(dev); | ||
| 2441 | } | ||
| 2442 | 2384 | ||
| 2443 | /* Don't disable pipe A or pipe A PLLs if needed */ | 2385 | /* Don't disable pipe A or pipe A PLLs if needed */ |
| 2444 | if (pipeconf_reg == PIPEACONF && | 2386 | if (pipeconf_reg == PIPEACONF && |
| @@ -2453,7 +2395,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2453 | } | 2395 | } |
| 2454 | 2396 | ||
| 2455 | /* Wait for vblank for the disable to take effect. */ | 2397 | /* Wait for vblank for the disable to take effect. */ |
| 2456 | intel_wait_for_vblank(dev); | 2398 | intel_wait_for_vblank_off(dev, pipe); |
| 2457 | 2399 | ||
| 2458 | temp = I915_READ(dpll_reg); | 2400 | temp = I915_READ(dpll_reg); |
| 2459 | if ((temp & DPLL_VCO_ENABLE) != 0) { | 2401 | if ((temp & DPLL_VCO_ENABLE) != 0) { |
| @@ -2469,9 +2411,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2469 | 2411 | ||
| 2470 | /** | 2412 | /** |
| 2471 | * Sets the power management mode of the pipe and plane. | 2413 | * Sets the power management mode of the pipe and plane. |
| 2472 | * | ||
| 2473 | * This code should probably grow support for turning the cursor off and back | ||
| 2474 | * on appropriately at the same time as we're turning the pipe off/on. | ||
| 2475 | */ | 2414 | */ |
| 2476 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | 2415 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) |
| 2477 | { | 2416 | { |
| @@ -2482,9 +2421,26 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 2482 | int pipe = intel_crtc->pipe; | 2421 | int pipe = intel_crtc->pipe; |
| 2483 | bool enabled; | 2422 | bool enabled; |
| 2484 | 2423 | ||
| 2424 | intel_crtc->dpms_mode = mode; | ||
| 2425 | intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON; | ||
| 2426 | |||
| 2427 | /* When switching on the display, ensure that SR is disabled | ||
| 2428 | * with multiple pipes prior to enabling to new pipe. | ||
| 2429 | * | ||
| 2430 | * When switching off the display, make sure the cursor is | ||
| 2431 | * properly hidden prior to disabling the pipe. | ||
| 2432 | */ | ||
| 2433 | if (mode == DRM_MODE_DPMS_ON) | ||
| 2434 | intel_update_watermarks(dev); | ||
| 2435 | else | ||
| 2436 | intel_crtc_update_cursor(crtc); | ||
| 2437 | |||
| 2485 | dev_priv->display.dpms(crtc, mode); | 2438 | dev_priv->display.dpms(crtc, mode); |
| 2486 | 2439 | ||
| 2487 | intel_crtc->dpms_mode = mode; | 2440 | if (mode == DRM_MODE_DPMS_ON) |
| 2441 | intel_crtc_update_cursor(crtc); | ||
| 2442 | else | ||
| 2443 | intel_update_watermarks(dev); | ||
| 2488 | 2444 | ||
| 2489 | if (!dev->primary->master) | 2445 | if (!dev->primary->master) |
| 2490 | return; | 2446 | return; |
| @@ -2536,6 +2492,20 @@ void intel_encoder_commit (struct drm_encoder *encoder) | |||
| 2536 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); | 2492 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); |
| 2537 | } | 2493 | } |
| 2538 | 2494 | ||
| 2495 | void intel_encoder_destroy(struct drm_encoder *encoder) | ||
| 2496 | { | ||
| 2497 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 2498 | |||
| 2499 | if (intel_encoder->ddc_bus) | ||
| 2500 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
| 2501 | |||
| 2502 | if (intel_encoder->i2c_bus) | ||
| 2503 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
| 2504 | |||
| 2505 | drm_encoder_cleanup(encoder); | ||
| 2506 | kfree(intel_encoder); | ||
| 2507 | } | ||
| 2508 | |||
| 2539 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | 2509 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, |
| 2540 | struct drm_display_mode *mode, | 2510 | struct drm_display_mode *mode, |
| 2541 | struct drm_display_mode *adjusted_mode) | 2511 | struct drm_display_mode *adjusted_mode) |
| @@ -2867,7 +2837,7 @@ struct cxsr_latency { | |||
| 2867 | unsigned long cursor_hpll_disable; | 2837 | unsigned long cursor_hpll_disable; |
| 2868 | }; | 2838 | }; |
| 2869 | 2839 | ||
| 2870 | static struct cxsr_latency cxsr_latency_table[] = { | 2840 | static const struct cxsr_latency cxsr_latency_table[] = { |
| 2871 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | 2841 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ |
| 2872 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | 2842 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ |
| 2873 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | 2843 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ |
| @@ -2905,11 +2875,13 @@ static struct cxsr_latency cxsr_latency_table[] = { | |||
| 2905 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ | 2875 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ |
| 2906 | }; | 2876 | }; |
| 2907 | 2877 | ||
| 2908 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, | 2878 | static const struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, |
| 2909 | int fsb, int mem) | 2879 | int is_ddr3, |
| 2880 | int fsb, | ||
| 2881 | int mem) | ||
| 2910 | { | 2882 | { |
| 2883 | const struct cxsr_latency *latency; | ||
| 2911 | int i; | 2884 | int i; |
| 2912 | struct cxsr_latency *latency; | ||
| 2913 | 2885 | ||
| 2914 | if (fsb == 0 || mem == 0) | 2886 | if (fsb == 0 || mem == 0) |
| 2915 | return NULL; | 2887 | return NULL; |
| @@ -2930,13 +2902,9 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, | |||
| 2930 | static void pineview_disable_cxsr(struct drm_device *dev) | 2902 | static void pineview_disable_cxsr(struct drm_device *dev) |
| 2931 | { | 2903 | { |
| 2932 | struct drm_i915_private *dev_priv = dev->dev_private; | 2904 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 2933 | u32 reg; | ||
| 2934 | 2905 | ||
| 2935 | /* deactivate cxsr */ | 2906 | /* deactivate cxsr */ |
| 2936 | reg = I915_READ(DSPFW3); | 2907 | I915_WRITE(DSPFW3, I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN); |
| 2937 | reg &= ~(PINEVIEW_SELF_REFRESH_EN); | ||
| 2938 | I915_WRITE(DSPFW3, reg); | ||
| 2939 | DRM_INFO("Big FIFO is disabled\n"); | ||
| 2940 | } | 2908 | } |
| 2941 | 2909 | ||
| 2942 | /* | 2910 | /* |
| @@ -3024,12 +2992,12 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
| 3024 | int pixel_size) | 2992 | int pixel_size) |
| 3025 | { | 2993 | { |
| 3026 | struct drm_i915_private *dev_priv = dev->dev_private; | 2994 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 2995 | const struct cxsr_latency *latency; | ||
| 3027 | u32 reg; | 2996 | u32 reg; |
| 3028 | unsigned long wm; | 2997 | unsigned long wm; |
| 3029 | struct cxsr_latency *latency; | ||
| 3030 | int sr_clock; | 2998 | int sr_clock; |
| 3031 | 2999 | ||
| 3032 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, | 3000 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, |
| 3033 | dev_priv->fsb_freq, dev_priv->mem_freq); | 3001 | dev_priv->fsb_freq, dev_priv->mem_freq); |
| 3034 | if (!latency) { | 3002 | if (!latency) { |
| 3035 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); | 3003 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); |
| @@ -3075,9 +3043,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
| 3075 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); | 3043 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); |
| 3076 | 3044 | ||
| 3077 | /* activate cxsr */ | 3045 | /* activate cxsr */ |
| 3078 | reg = I915_READ(DSPFW3); | 3046 | I915_WRITE(DSPFW3, |
| 3079 | reg |= PINEVIEW_SELF_REFRESH_EN; | 3047 | I915_READ(DSPFW3) | PINEVIEW_SELF_REFRESH_EN); |
| 3080 | I915_WRITE(DSPFW3, reg); | ||
| 3081 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); | 3048 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); |
| 3082 | } else { | 3049 | } else { |
| 3083 | pineview_disable_cxsr(dev); | 3050 | pineview_disable_cxsr(dev); |
| @@ -3354,12 +3321,11 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | |||
| 3354 | int line_count; | 3321 | int line_count; |
| 3355 | int planea_htotal = 0, planeb_htotal = 0; | 3322 | int planea_htotal = 0, planeb_htotal = 0; |
| 3356 | struct drm_crtc *crtc; | 3323 | struct drm_crtc *crtc; |
| 3357 | struct intel_crtc *intel_crtc; | ||
| 3358 | 3324 | ||
| 3359 | /* Need htotal for all active display plane */ | 3325 | /* Need htotal for all active display plane */ |
| 3360 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3326 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
| 3361 | intel_crtc = to_intel_crtc(crtc); | 3327 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 3362 | if (crtc->enabled) { | 3328 | if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { |
| 3363 | if (intel_crtc->plane == 0) | 3329 | if (intel_crtc->plane == 0) |
| 3364 | planea_htotal = crtc->mode.htotal; | 3330 | planea_htotal = crtc->mode.htotal; |
| 3365 | else | 3331 | else |
| @@ -3519,7 +3485,6 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
| 3519 | { | 3485 | { |
| 3520 | struct drm_i915_private *dev_priv = dev->dev_private; | 3486 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 3521 | struct drm_crtc *crtc; | 3487 | struct drm_crtc *crtc; |
| 3522 | struct intel_crtc *intel_crtc; | ||
| 3523 | int sr_hdisplay = 0; | 3488 | int sr_hdisplay = 0; |
| 3524 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; | 3489 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; |
| 3525 | int enabled = 0, pixel_size = 0; | 3490 | int enabled = 0, pixel_size = 0; |
| @@ -3530,8 +3495,8 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
| 3530 | 3495 | ||
| 3531 | /* Get the clock config from both planes */ | 3496 | /* Get the clock config from both planes */ |
| 3532 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3497 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
| 3533 | intel_crtc = to_intel_crtc(crtc); | 3498 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 3534 | if (crtc->enabled) { | 3499 | if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { |
| 3535 | enabled++; | 3500 | enabled++; |
| 3536 | if (intel_crtc->plane == 0) { | 3501 | if (intel_crtc->plane == 0) { |
| 3537 | DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", | 3502 | DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", |
| @@ -3966,9 +3931,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 3966 | dpll_reg = pch_dpll_reg; | 3931 | dpll_reg = pch_dpll_reg; |
| 3967 | } | 3932 | } |
| 3968 | 3933 | ||
| 3969 | if (is_edp) { | 3934 | if (!is_edp) { |
| 3970 | ironlake_disable_pll_edp(crtc); | ||
| 3971 | } else if ((dpll & DPLL_VCO_ENABLE)) { | ||
| 3972 | I915_WRITE(fp_reg, fp); | 3935 | I915_WRITE(fp_reg, fp); |
| 3973 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); | 3936 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); |
| 3974 | I915_READ(dpll_reg); | 3937 | I915_READ(dpll_reg); |
| @@ -4167,7 +4130,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4167 | I915_WRITE(pipeconf_reg, pipeconf); | 4130 | I915_WRITE(pipeconf_reg, pipeconf); |
| 4168 | I915_READ(pipeconf_reg); | 4131 | I915_READ(pipeconf_reg); |
| 4169 | 4132 | ||
| 4170 | intel_wait_for_vblank(dev); | 4133 | intel_wait_for_vblank(dev, pipe); |
| 4171 | 4134 | ||
| 4172 | if (IS_IRONLAKE(dev)) { | 4135 | if (IS_IRONLAKE(dev)) { |
| 4173 | /* enable address swizzle for tiling buffer */ | 4136 | /* enable address swizzle for tiling buffer */ |
| @@ -4180,9 +4143,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4180 | /* Flush the plane changes */ | 4143 | /* Flush the plane changes */ |
| 4181 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 4144 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
| 4182 | 4145 | ||
| 4183 | if ((IS_I965G(dev) || plane == 0)) | ||
| 4184 | intel_update_fbc(crtc, &crtc->mode); | ||
| 4185 | |||
| 4186 | intel_update_watermarks(dev); | 4146 | intel_update_watermarks(dev); |
| 4187 | 4147 | ||
| 4188 | drm_vblank_post_modeset(dev, pipe); | 4148 | drm_vblank_post_modeset(dev, pipe); |
| @@ -4216,6 +4176,62 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) | |||
| 4216 | } | 4176 | } |
| 4217 | } | 4177 | } |
| 4218 | 4178 | ||
| 4179 | static void i845_update_cursor(struct drm_crtc *crtc, u32 base) | ||
| 4180 | { | ||
| 4181 | struct drm_device *dev = crtc->dev; | ||
| 4182 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 4183 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 4184 | bool visible = base != 0; | ||
| 4185 | u32 cntl; | ||
| 4186 | |||
| 4187 | if (intel_crtc->cursor_visible == visible) | ||
| 4188 | return; | ||
| 4189 | |||
| 4190 | cntl = I915_READ(CURACNTR); | ||
| 4191 | if (visible) { | ||
| 4192 | /* On these chipsets we can only modify the base whilst | ||
| 4193 | * the cursor is disabled. | ||
| 4194 | */ | ||
| 4195 | I915_WRITE(CURABASE, base); | ||
| 4196 | |||
| 4197 | cntl &= ~(CURSOR_FORMAT_MASK); | ||
| 4198 | /* XXX width must be 64, stride 256 => 0x00 << 28 */ | ||
| 4199 | cntl |= CURSOR_ENABLE | | ||
| 4200 | CURSOR_GAMMA_ENABLE | | ||
| 4201 | CURSOR_FORMAT_ARGB; | ||
| 4202 | } else | ||
| 4203 | cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); | ||
| 4204 | I915_WRITE(CURACNTR, cntl); | ||
| 4205 | |||
| 4206 | intel_crtc->cursor_visible = visible; | ||
| 4207 | } | ||
| 4208 | |||
| 4209 | static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) | ||
| 4210 | { | ||
| 4211 | struct drm_device *dev = crtc->dev; | ||
| 4212 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 4213 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 4214 | int pipe = intel_crtc->pipe; | ||
| 4215 | bool visible = base != 0; | ||
| 4216 | |||
| 4217 | if (intel_crtc->cursor_visible != visible) { | ||
| 4218 | uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); | ||
| 4219 | if (base) { | ||
| 4220 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); | ||
| 4221 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | ||
| 4222 | cntl |= pipe << 28; /* Connect to correct pipe */ | ||
| 4223 | } else { | ||
| 4224 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | ||
| 4225 | cntl |= CURSOR_MODE_DISABLE; | ||
| 4226 | } | ||
| 4227 | I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl); | ||
| 4228 | |||
| 4229 | intel_crtc->cursor_visible = visible; | ||
| 4230 | } | ||
| 4231 | /* and commit changes on next vblank */ | ||
| 4232 | I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base); | ||
| 4233 | } | ||
| 4234 | |||
| 4219 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ | 4235 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ |
| 4220 | static void intel_crtc_update_cursor(struct drm_crtc *crtc) | 4236 | static void intel_crtc_update_cursor(struct drm_crtc *crtc) |
| 4221 | { | 4237 | { |
| @@ -4225,12 +4241,12 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc) | |||
| 4225 | int pipe = intel_crtc->pipe; | 4241 | int pipe = intel_crtc->pipe; |
| 4226 | int x = intel_crtc->cursor_x; | 4242 | int x = intel_crtc->cursor_x; |
| 4227 | int y = intel_crtc->cursor_y; | 4243 | int y = intel_crtc->cursor_y; |
| 4228 | uint32_t base, pos; | 4244 | u32 base, pos; |
| 4229 | bool visible; | 4245 | bool visible; |
| 4230 | 4246 | ||
| 4231 | pos = 0; | 4247 | pos = 0; |
| 4232 | 4248 | ||
| 4233 | if (crtc->fb) { | 4249 | if (intel_crtc->cursor_on && crtc->fb) { |
| 4234 | base = intel_crtc->cursor_addr; | 4250 | base = intel_crtc->cursor_addr; |
| 4235 | if (x > (int) crtc->fb->width) | 4251 | if (x > (int) crtc->fb->width) |
| 4236 | base = 0; | 4252 | base = 0; |
| @@ -4259,37 +4275,14 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc) | |||
| 4259 | pos |= y << CURSOR_Y_SHIFT; | 4275 | pos |= y << CURSOR_Y_SHIFT; |
| 4260 | 4276 | ||
| 4261 | visible = base != 0; | 4277 | visible = base != 0; |
| 4262 | if (!visible && !intel_crtc->cursor_visble) | 4278 | if (!visible && !intel_crtc->cursor_visible) |
| 4263 | return; | 4279 | return; |
| 4264 | 4280 | ||
| 4265 | I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); | 4281 | I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); |
| 4266 | if (intel_crtc->cursor_visble != visible) { | 4282 | if (IS_845G(dev) || IS_I865G(dev)) |
| 4267 | uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); | 4283 | i845_update_cursor(crtc, base); |
| 4268 | if (base) { | 4284 | else |
| 4269 | /* Hooray for CUR*CNTR differences */ | 4285 | i9xx_update_cursor(crtc, base); |
| 4270 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
| 4271 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); | ||
| 4272 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | ||
| 4273 | cntl |= pipe << 28; /* Connect to correct pipe */ | ||
| 4274 | } else { | ||
| 4275 | cntl &= ~(CURSOR_FORMAT_MASK); | ||
| 4276 | cntl |= CURSOR_ENABLE; | ||
| 4277 | cntl |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; | ||
| 4278 | } | ||
| 4279 | } else { | ||
| 4280 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
| 4281 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | ||
| 4282 | cntl |= CURSOR_MODE_DISABLE; | ||
| 4283 | } else { | ||
| 4284 | cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); | ||
| 4285 | } | ||
| 4286 | } | ||
| 4287 | I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl); | ||
| 4288 | |||
| 4289 | intel_crtc->cursor_visble = visible; | ||
| 4290 | } | ||
| 4291 | /* and commit changes on next vblank */ | ||
| 4292 | I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base); | ||
| 4293 | 4286 | ||
| 4294 | if (visible) | 4287 | if (visible) |
| 4295 | intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); | 4288 | intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); |
| @@ -4354,8 +4347,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
| 4354 | 4347 | ||
| 4355 | addr = obj_priv->gtt_offset; | 4348 | addr = obj_priv->gtt_offset; |
| 4356 | } else { | 4349 | } else { |
| 4350 | int align = IS_I830(dev) ? 16 * 1024 : 256; | ||
| 4357 | ret = i915_gem_attach_phys_object(dev, bo, | 4351 | ret = i915_gem_attach_phys_object(dev, bo, |
| 4358 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); | 4352 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1, |
| 4353 | align); | ||
| 4359 | if (ret) { | 4354 | if (ret) { |
| 4360 | DRM_ERROR("failed to attach phys object\n"); | 4355 | DRM_ERROR("failed to attach phys object\n"); |
| 4361 | goto fail_locked; | 4356 | goto fail_locked; |
| @@ -4544,7 +4539,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | |||
| 4544 | encoder_funcs->commit(encoder); | 4539 | encoder_funcs->commit(encoder); |
| 4545 | } | 4540 | } |
| 4546 | /* let the connector get through one full cycle before testing */ | 4541 | /* let the connector get through one full cycle before testing */ |
| 4547 | intel_wait_for_vblank(dev); | 4542 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 4548 | 4543 | ||
| 4549 | return crtc; | 4544 | return crtc; |
| 4550 | } | 4545 | } |
| @@ -4749,7 +4744,7 @@ static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule) | |||
| 4749 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; | 4744 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; |
| 4750 | I915_WRITE(dpll_reg, dpll); | 4745 | I915_WRITE(dpll_reg, dpll); |
| 4751 | dpll = I915_READ(dpll_reg); | 4746 | dpll = I915_READ(dpll_reg); |
| 4752 | intel_wait_for_vblank(dev); | 4747 | intel_wait_for_vblank(dev, pipe); |
| 4753 | dpll = I915_READ(dpll_reg); | 4748 | dpll = I915_READ(dpll_reg); |
| 4754 | if (dpll & DISPLAY_RATE_SELECT_FPA1) | 4749 | if (dpll & DISPLAY_RATE_SELECT_FPA1) |
| 4755 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); | 4750 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); |
| @@ -4793,7 +4788,7 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) | |||
| 4793 | dpll |= DISPLAY_RATE_SELECT_FPA1; | 4788 | dpll |= DISPLAY_RATE_SELECT_FPA1; |
| 4794 | I915_WRITE(dpll_reg, dpll); | 4789 | I915_WRITE(dpll_reg, dpll); |
| 4795 | dpll = I915_READ(dpll_reg); | 4790 | dpll = I915_READ(dpll_reg); |
| 4796 | intel_wait_for_vblank(dev); | 4791 | intel_wait_for_vblank(dev, pipe); |
| 4797 | dpll = I915_READ(dpll_reg); | 4792 | dpll = I915_READ(dpll_reg); |
| 4798 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) | 4793 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) |
| 4799 | DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); | 4794 | DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); |
| @@ -5083,14 +5078,16 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
| 5083 | work->pending_flip_obj = obj; | 5078 | work->pending_flip_obj = obj; |
| 5084 | 5079 | ||
| 5085 | if (intel_crtc->plane) | 5080 | if (intel_crtc->plane) |
| 5086 | flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; | 5081 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; |
| 5087 | else | 5082 | else |
| 5088 | flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT; | 5083 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; |
| 5089 | 5084 | ||
| 5090 | /* Wait for any previous flip to finish */ | 5085 | if (IS_GEN3(dev) || IS_GEN2(dev)) { |
| 5091 | if (IS_GEN3(dev)) | 5086 | BEGIN_LP_RING(2); |
| 5092 | while (I915_READ(ISR) & flip_mask) | 5087 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); |
| 5093 | ; | 5088 | OUT_RING(0); |
| 5089 | ADVANCE_LP_RING(); | ||
| 5090 | } | ||
| 5094 | 5091 | ||
| 5095 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | 5092 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ |
| 5096 | offset = obj_priv->gtt_offset; | 5093 | offset = obj_priv->gtt_offset; |
| @@ -5104,12 +5101,18 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
| 5104 | OUT_RING(offset | obj_priv->tiling_mode); | 5101 | OUT_RING(offset | obj_priv->tiling_mode); |
| 5105 | pipesrc = I915_READ(pipesrc_reg); | 5102 | pipesrc = I915_READ(pipesrc_reg); |
| 5106 | OUT_RING(pipesrc & 0x0fff0fff); | 5103 | OUT_RING(pipesrc & 0x0fff0fff); |
| 5107 | } else { | 5104 | } else if (IS_GEN3(dev)) { |
| 5108 | OUT_RING(MI_DISPLAY_FLIP_I915 | | 5105 | OUT_RING(MI_DISPLAY_FLIP_I915 | |
| 5109 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5106 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
| 5110 | OUT_RING(fb->pitch); | 5107 | OUT_RING(fb->pitch); |
| 5111 | OUT_RING(offset); | 5108 | OUT_RING(offset); |
| 5112 | OUT_RING(MI_NOOP); | 5109 | OUT_RING(MI_NOOP); |
| 5110 | } else { | ||
| 5111 | OUT_RING(MI_DISPLAY_FLIP | | ||
| 5112 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
| 5113 | OUT_RING(fb->pitch); | ||
| 5114 | OUT_RING(offset); | ||
| 5115 | OUT_RING(MI_NOOP); | ||
| 5113 | } | 5116 | } |
| 5114 | ADVANCE_LP_RING(); | 5117 | ADVANCE_LP_RING(); |
| 5115 | 5118 | ||
| @@ -5432,37 +5435,37 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { | |||
| 5432 | }; | 5435 | }; |
| 5433 | 5436 | ||
| 5434 | static struct drm_gem_object * | 5437 | static struct drm_gem_object * |
| 5435 | intel_alloc_power_context(struct drm_device *dev) | 5438 | intel_alloc_context_page(struct drm_device *dev) |
| 5436 | { | 5439 | { |
| 5437 | struct drm_gem_object *pwrctx; | 5440 | struct drm_gem_object *ctx; |
| 5438 | int ret; | 5441 | int ret; |
| 5439 | 5442 | ||
| 5440 | pwrctx = i915_gem_alloc_object(dev, 4096); | 5443 | ctx = i915_gem_alloc_object(dev, 4096); |
| 5441 | if (!pwrctx) { | 5444 | if (!ctx) { |
| 5442 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); | 5445 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); |
| 5443 | return NULL; | 5446 | return NULL; |
| 5444 | } | 5447 | } |
| 5445 | 5448 | ||
| 5446 | mutex_lock(&dev->struct_mutex); | 5449 | mutex_lock(&dev->struct_mutex); |
| 5447 | ret = i915_gem_object_pin(pwrctx, 4096); | 5450 | ret = i915_gem_object_pin(ctx, 4096); |
| 5448 | if (ret) { | 5451 | if (ret) { |
| 5449 | DRM_ERROR("failed to pin power context: %d\n", ret); | 5452 | DRM_ERROR("failed to pin power context: %d\n", ret); |
| 5450 | goto err_unref; | 5453 | goto err_unref; |
| 5451 | } | 5454 | } |
| 5452 | 5455 | ||
| 5453 | ret = i915_gem_object_set_to_gtt_domain(pwrctx, 1); | 5456 | ret = i915_gem_object_set_to_gtt_domain(ctx, 1); |
| 5454 | if (ret) { | 5457 | if (ret) { |
| 5455 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); | 5458 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); |
| 5456 | goto err_unpin; | 5459 | goto err_unpin; |
| 5457 | } | 5460 | } |
| 5458 | mutex_unlock(&dev->struct_mutex); | 5461 | mutex_unlock(&dev->struct_mutex); |
| 5459 | 5462 | ||
| 5460 | return pwrctx; | 5463 | return ctx; |
| 5461 | 5464 | ||
| 5462 | err_unpin: | 5465 | err_unpin: |
| 5463 | i915_gem_object_unpin(pwrctx); | 5466 | i915_gem_object_unpin(ctx); |
| 5464 | err_unref: | 5467 | err_unref: |
| 5465 | drm_gem_object_unreference(pwrctx); | 5468 | drm_gem_object_unreference(ctx); |
| 5466 | mutex_unlock(&dev->struct_mutex); | 5469 | mutex_unlock(&dev->struct_mutex); |
| 5467 | return NULL; | 5470 | return NULL; |
| 5468 | } | 5471 | } |
| @@ -5494,7 +5497,6 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
| 5494 | struct drm_i915_private *dev_priv = dev->dev_private; | 5497 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 5495 | u32 rgvmodectl = I915_READ(MEMMODECTL); | 5498 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
| 5496 | u8 fmax, fmin, fstart, vstart; | 5499 | u8 fmax, fmin, fstart, vstart; |
| 5497 | int i = 0; | ||
| 5498 | 5500 | ||
| 5499 | /* 100ms RC evaluation intervals */ | 5501 | /* 100ms RC evaluation intervals */ |
| 5500 | I915_WRITE(RCUPEI, 100000); | 5502 | I915_WRITE(RCUPEI, 100000); |
| @@ -5538,13 +5540,8 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
| 5538 | rgvmodectl |= MEMMODE_SWMODE_EN; | 5540 | rgvmodectl |= MEMMODE_SWMODE_EN; |
| 5539 | I915_WRITE(MEMMODECTL, rgvmodectl); | 5541 | I915_WRITE(MEMMODECTL, rgvmodectl); |
| 5540 | 5542 | ||
| 5541 | while (I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) { | 5543 | if (wait_for((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 1, 0)) |
| 5542 | if (i++ > 100) { | 5544 | DRM_ERROR("stuck trying to change perf mode\n"); |
| 5543 | DRM_ERROR("stuck trying to change perf mode\n"); | ||
| 5544 | break; | ||
| 5545 | } | ||
| 5546 | msleep(1); | ||
| 5547 | } | ||
| 5548 | msleep(1); | 5545 | msleep(1); |
| 5549 | 5546 | ||
| 5550 | ironlake_set_drps(dev, fstart); | 5547 | ironlake_set_drps(dev, fstart); |
| @@ -5725,7 +5722,8 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
| 5725 | ILK_DPFC_DIS2 | | 5722 | ILK_DPFC_DIS2 | |
| 5726 | ILK_CLK_FBC); | 5723 | ILK_CLK_FBC); |
| 5727 | } | 5724 | } |
| 5728 | return; | 5725 | if (IS_GEN6(dev)) |
| 5726 | return; | ||
| 5729 | } else if (IS_G4X(dev)) { | 5727 | } else if (IS_G4X(dev)) { |
| 5730 | uint32_t dspclk_gate; | 5728 | uint32_t dspclk_gate; |
| 5731 | I915_WRITE(RENCLK_GATE_D1, 0); | 5729 | I915_WRITE(RENCLK_GATE_D1, 0); |
| @@ -5768,6 +5766,31 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
| 5768 | * GPU can automatically power down the render unit if given a page | 5766 | * GPU can automatically power down the render unit if given a page |
| 5769 | * to save state. | 5767 | * to save state. |
| 5770 | */ | 5768 | */ |
| 5769 | if (IS_IRONLAKE_M(dev)) { | ||
| 5770 | if (dev_priv->renderctx == NULL) | ||
| 5771 | dev_priv->renderctx = intel_alloc_context_page(dev); | ||
| 5772 | if (dev_priv->renderctx) { | ||
| 5773 | struct drm_i915_gem_object *obj_priv; | ||
| 5774 | obj_priv = to_intel_bo(dev_priv->renderctx); | ||
| 5775 | if (obj_priv) { | ||
| 5776 | BEGIN_LP_RING(4); | ||
| 5777 | OUT_RING(MI_SET_CONTEXT); | ||
| 5778 | OUT_RING(obj_priv->gtt_offset | | ||
| 5779 | MI_MM_SPACE_GTT | | ||
| 5780 | MI_SAVE_EXT_STATE_EN | | ||
| 5781 | MI_RESTORE_EXT_STATE_EN | | ||
| 5782 | MI_RESTORE_INHIBIT); | ||
| 5783 | OUT_RING(MI_NOOP); | ||
| 5784 | OUT_RING(MI_FLUSH); | ||
| 5785 | ADVANCE_LP_RING(); | ||
| 5786 | } | ||
| 5787 | } else { | ||
| 5788 | DRM_DEBUG_KMS("Failed to allocate render context." | ||
| 5789 | "Disable RC6\n"); | ||
| 5790 | return; | ||
| 5791 | } | ||
| 5792 | } | ||
| 5793 | |||
| 5771 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { | 5794 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { |
| 5772 | struct drm_i915_gem_object *obj_priv = NULL; | 5795 | struct drm_i915_gem_object *obj_priv = NULL; |
| 5773 | 5796 | ||
| @@ -5776,7 +5799,7 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
| 5776 | } else { | 5799 | } else { |
| 5777 | struct drm_gem_object *pwrctx; | 5800 | struct drm_gem_object *pwrctx; |
| 5778 | 5801 | ||
| 5779 | pwrctx = intel_alloc_power_context(dev); | 5802 | pwrctx = intel_alloc_context_page(dev); |
| 5780 | if (pwrctx) { | 5803 | if (pwrctx) { |
| 5781 | dev_priv->pwrctx = pwrctx; | 5804 | dev_priv->pwrctx = pwrctx; |
| 5782 | obj_priv = to_intel_bo(pwrctx); | 5805 | obj_priv = to_intel_bo(pwrctx); |
| @@ -5948,6 +5971,29 @@ static void intel_init_quirks(struct drm_device *dev) | |||
| 5948 | } | 5971 | } |
| 5949 | } | 5972 | } |
| 5950 | 5973 | ||
| 5974 | /* Disable the VGA plane that we never use */ | ||
| 5975 | static void i915_disable_vga(struct drm_device *dev) | ||
| 5976 | { | ||
| 5977 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 5978 | u8 sr1; | ||
| 5979 | u32 vga_reg; | ||
| 5980 | |||
| 5981 | if (HAS_PCH_SPLIT(dev)) | ||
| 5982 | vga_reg = CPU_VGACNTRL; | ||
| 5983 | else | ||
| 5984 | vga_reg = VGACNTRL; | ||
| 5985 | |||
| 5986 | vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); | ||
| 5987 | outb(1, VGA_SR_INDEX); | ||
| 5988 | sr1 = inb(VGA_SR_DATA); | ||
| 5989 | outb(sr1 | 1<<5, VGA_SR_DATA); | ||
| 5990 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); | ||
| 5991 | udelay(300); | ||
| 5992 | |||
| 5993 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
| 5994 | POSTING_READ(vga_reg); | ||
| 5995 | } | ||
| 5996 | |||
| 5951 | void intel_modeset_init(struct drm_device *dev) | 5997 | void intel_modeset_init(struct drm_device *dev) |
| 5952 | { | 5998 | { |
| 5953 | struct drm_i915_private *dev_priv = dev->dev_private; | 5999 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -5996,6 +6042,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
| 5996 | 6042 | ||
| 5997 | intel_init_clock_gating(dev); | 6043 | intel_init_clock_gating(dev); |
| 5998 | 6044 | ||
| 6045 | /* Just disable it once at startup */ | ||
| 6046 | i915_disable_vga(dev); | ||
| 6047 | |||
| 5999 | if (IS_IRONLAKE_M(dev)) { | 6048 | if (IS_IRONLAKE_M(dev)) { |
| 6000 | ironlake_enable_drps(dev); | 6049 | ironlake_enable_drps(dev); |
| 6001 | intel_init_emon(dev); | 6050 | intel_init_emon(dev); |
| @@ -6034,6 +6083,16 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
| 6034 | if (dev_priv->display.disable_fbc) | 6083 | if (dev_priv->display.disable_fbc) |
| 6035 | dev_priv->display.disable_fbc(dev); | 6084 | dev_priv->display.disable_fbc(dev); |
| 6036 | 6085 | ||
| 6086 | if (dev_priv->renderctx) { | ||
| 6087 | struct drm_i915_gem_object *obj_priv; | ||
| 6088 | |||
| 6089 | obj_priv = to_intel_bo(dev_priv->renderctx); | ||
| 6090 | I915_WRITE(CCID, obj_priv->gtt_offset &~ CCID_EN); | ||
| 6091 | I915_READ(CCID); | ||
| 6092 | i915_gem_object_unpin(dev_priv->renderctx); | ||
| 6093 | drm_gem_object_unreference(dev_priv->renderctx); | ||
| 6094 | } | ||
| 6095 | |||
| 6037 | if (dev_priv->pwrctx) { | 6096 | if (dev_priv->pwrctx) { |
| 6038 | struct drm_i915_gem_object *obj_priv; | 6097 | struct drm_i915_gem_object *obj_priv; |
| 6039 | 6098 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 40be1fa65be..9caccd03dcc 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -42,10 +42,11 @@ | |||
| 42 | 42 | ||
| 43 | #define DP_LINK_CONFIGURATION_SIZE 9 | 43 | #define DP_LINK_CONFIGURATION_SIZE 9 |
| 44 | 44 | ||
| 45 | #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP) | 45 | #define IS_eDP(i) ((i)->base.type == INTEL_OUTPUT_EDP) |
| 46 | #define IS_PCH_eDP(dp_priv) ((dp_priv)->is_pch_edp) | 46 | #define IS_PCH_eDP(i) ((i)->is_pch_edp) |
| 47 | 47 | ||
| 48 | struct intel_dp_priv { | 48 | struct intel_dp { |
| 49 | struct intel_encoder base; | ||
| 49 | uint32_t output_reg; | 50 | uint32_t output_reg; |
| 50 | uint32_t DP; | 51 | uint32_t DP; |
| 51 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; | 52 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; |
| @@ -54,40 +55,39 @@ struct intel_dp_priv { | |||
| 54 | uint8_t link_bw; | 55 | uint8_t link_bw; |
| 55 | uint8_t lane_count; | 56 | uint8_t lane_count; |
| 56 | uint8_t dpcd[4]; | 57 | uint8_t dpcd[4]; |
| 57 | struct intel_encoder *intel_encoder; | ||
| 58 | struct i2c_adapter adapter; | 58 | struct i2c_adapter adapter; |
| 59 | struct i2c_algo_dp_aux_data algo; | 59 | struct i2c_algo_dp_aux_data algo; |
| 60 | bool is_pch_edp; | 60 | bool is_pch_edp; |
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | static void | 63 | static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder) |
| 64 | intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | 64 | { |
| 65 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]); | 65 | return container_of(enc_to_intel_encoder(encoder), struct intel_dp, base); |
| 66 | } | ||
| 66 | 67 | ||
| 67 | static void | 68 | static void intel_dp_link_train(struct intel_dp *intel_dp); |
| 68 | intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP); | 69 | static void intel_dp_link_down(struct intel_dp *intel_dp); |
| 69 | 70 | ||
| 70 | void | 71 | void |
| 71 | intel_edp_link_config (struct intel_encoder *intel_encoder, | 72 | intel_edp_link_config (struct intel_encoder *intel_encoder, |
| 72 | int *lane_num, int *link_bw) | 73 | int *lane_num, int *link_bw) |
| 73 | { | 74 | { |
| 74 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 75 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); |
| 75 | 76 | ||
| 76 | *lane_num = dp_priv->lane_count; | 77 | *lane_num = intel_dp->lane_count; |
| 77 | if (dp_priv->link_bw == DP_LINK_BW_1_62) | 78 | if (intel_dp->link_bw == DP_LINK_BW_1_62) |
| 78 | *link_bw = 162000; | 79 | *link_bw = 162000; |
| 79 | else if (dp_priv->link_bw == DP_LINK_BW_2_7) | 80 | else if (intel_dp->link_bw == DP_LINK_BW_2_7) |
| 80 | *link_bw = 270000; | 81 | *link_bw = 270000; |
| 81 | } | 82 | } |
| 82 | 83 | ||
| 83 | static int | 84 | static int |
| 84 | intel_dp_max_lane_count(struct intel_encoder *intel_encoder) | 85 | intel_dp_max_lane_count(struct intel_dp *intel_dp) |
| 85 | { | 86 | { |
| 86 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 87 | int max_lane_count = 4; | 87 | int max_lane_count = 4; |
| 88 | 88 | ||
| 89 | if (dp_priv->dpcd[0] >= 0x11) { | 89 | if (intel_dp->dpcd[0] >= 0x11) { |
| 90 | max_lane_count = dp_priv->dpcd[2] & 0x1f; | 90 | max_lane_count = intel_dp->dpcd[2] & 0x1f; |
| 91 | switch (max_lane_count) { | 91 | switch (max_lane_count) { |
| 92 | case 1: case 2: case 4: | 92 | case 1: case 2: case 4: |
| 93 | break; | 93 | break; |
| @@ -99,10 +99,9 @@ intel_dp_max_lane_count(struct intel_encoder *intel_encoder) | |||
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | static int | 101 | static int |
| 102 | intel_dp_max_link_bw(struct intel_encoder *intel_encoder) | 102 | intel_dp_max_link_bw(struct intel_dp *intel_dp) |
| 103 | { | 103 | { |
| 104 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 104 | int max_link_bw = intel_dp->dpcd[1]; |
| 105 | int max_link_bw = dp_priv->dpcd[1]; | ||
| 106 | 105 | ||
| 107 | switch (max_link_bw) { | 106 | switch (max_link_bw) { |
| 108 | case DP_LINK_BW_1_62: | 107 | case DP_LINK_BW_1_62: |
| @@ -126,13 +125,11 @@ intel_dp_link_clock(uint8_t link_bw) | |||
| 126 | 125 | ||
| 127 | /* I think this is a fiction */ | 126 | /* I think this is a fiction */ |
| 128 | static int | 127 | static int |
| 129 | intel_dp_link_required(struct drm_device *dev, | 128 | intel_dp_link_required(struct drm_device *dev, struct intel_dp *intel_dp, int pixel_clock) |
| 130 | struct intel_encoder *intel_encoder, int pixel_clock) | ||
| 131 | { | 129 | { |
| 132 | struct drm_i915_private *dev_priv = dev->dev_private; | 130 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 133 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 134 | 131 | ||
| 135 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) | 132 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) |
| 136 | return (pixel_clock * dev_priv->edp_bpp) / 8; | 133 | return (pixel_clock * dev_priv->edp_bpp) / 8; |
| 137 | else | 134 | else |
| 138 | return pixel_clock * 3; | 135 | return pixel_clock * 3; |
| @@ -149,14 +146,13 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
| 149 | struct drm_display_mode *mode) | 146 | struct drm_display_mode *mode) |
| 150 | { | 147 | { |
| 151 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 148 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 152 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 149 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
| 153 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 154 | struct drm_device *dev = connector->dev; | 150 | struct drm_device *dev = connector->dev; |
| 155 | struct drm_i915_private *dev_priv = dev->dev_private; | 151 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 156 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); | 152 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); |
| 157 | int max_lanes = intel_dp_max_lane_count(intel_encoder); | 153 | int max_lanes = intel_dp_max_lane_count(intel_dp); |
| 158 | 154 | ||
| 159 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | 155 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && |
| 160 | dev_priv->panel_fixed_mode) { | 156 | dev_priv->panel_fixed_mode) { |
| 161 | if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay) | 157 | if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay) |
| 162 | return MODE_PANEL; | 158 | return MODE_PANEL; |
| @@ -167,8 +163,8 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
| 167 | 163 | ||
| 168 | /* only refuse the mode on non eDP since we have seen some wierd eDP panels | 164 | /* only refuse the mode on non eDP since we have seen some wierd eDP panels |
| 169 | which are outside spec tolerances but somehow work by magic */ | 165 | which are outside spec tolerances but somehow work by magic */ |
| 170 | if (!IS_eDP(intel_encoder) && | 166 | if (!IS_eDP(intel_dp) && |
| 171 | (intel_dp_link_required(connector->dev, intel_encoder, mode->clock) | 167 | (intel_dp_link_required(connector->dev, intel_dp, mode->clock) |
| 172 | > intel_dp_max_data_rate(max_link_clock, max_lanes))) | 168 | > intel_dp_max_data_rate(max_link_clock, max_lanes))) |
| 173 | return MODE_CLOCK_HIGH; | 169 | return MODE_CLOCK_HIGH; |
| 174 | 170 | ||
| @@ -232,13 +228,12 @@ intel_hrawclk(struct drm_device *dev) | |||
| 232 | } | 228 | } |
| 233 | 229 | ||
| 234 | static int | 230 | static int |
| 235 | intel_dp_aux_ch(struct intel_encoder *intel_encoder, | 231 | intel_dp_aux_ch(struct intel_dp *intel_dp, |
| 236 | uint8_t *send, int send_bytes, | 232 | uint8_t *send, int send_bytes, |
| 237 | uint8_t *recv, int recv_size) | 233 | uint8_t *recv, int recv_size) |
| 238 | { | 234 | { |
| 239 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 235 | uint32_t output_reg = intel_dp->output_reg; |
| 240 | uint32_t output_reg = dp_priv->output_reg; | 236 | struct drm_device *dev = intel_dp->base.enc.dev; |
| 241 | struct drm_device *dev = intel_encoder->enc.dev; | ||
| 242 | struct drm_i915_private *dev_priv = dev->dev_private; | 237 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 243 | uint32_t ch_ctl = output_reg + 0x10; | 238 | uint32_t ch_ctl = output_reg + 0x10; |
| 244 | uint32_t ch_data = ch_ctl + 4; | 239 | uint32_t ch_data = ch_ctl + 4; |
| @@ -253,7 +248,7 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder, | |||
| 253 | * and would like to run at 2MHz. So, take the | 248 | * and would like to run at 2MHz. So, take the |
| 254 | * hrawclk value and divide by 2 and use that | 249 | * hrawclk value and divide by 2 and use that |
| 255 | */ | 250 | */ |
| 256 | if (IS_eDP(intel_encoder)) { | 251 | if (IS_eDP(intel_dp)) { |
| 257 | if (IS_GEN6(dev)) | 252 | if (IS_GEN6(dev)) |
| 258 | aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */ | 253 | aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */ |
| 259 | else | 254 | else |
| @@ -344,7 +339,7 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder, | |||
| 344 | 339 | ||
| 345 | /* Write data to the aux channel in native mode */ | 340 | /* Write data to the aux channel in native mode */ |
| 346 | static int | 341 | static int |
| 347 | intel_dp_aux_native_write(struct intel_encoder *intel_encoder, | 342 | intel_dp_aux_native_write(struct intel_dp *intel_dp, |
| 348 | uint16_t address, uint8_t *send, int send_bytes) | 343 | uint16_t address, uint8_t *send, int send_bytes) |
| 349 | { | 344 | { |
| 350 | int ret; | 345 | int ret; |
| @@ -361,7 +356,7 @@ intel_dp_aux_native_write(struct intel_encoder *intel_encoder, | |||
| 361 | memcpy(&msg[4], send, send_bytes); | 356 | memcpy(&msg[4], send, send_bytes); |
| 362 | msg_bytes = send_bytes + 4; | 357 | msg_bytes = send_bytes + 4; |
| 363 | for (;;) { | 358 | for (;;) { |
| 364 | ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1); | 359 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1); |
| 365 | if (ret < 0) | 360 | if (ret < 0) |
| 366 | return ret; | 361 | return ret; |
| 367 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) | 362 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) |
| @@ -376,15 +371,15 @@ intel_dp_aux_native_write(struct intel_encoder *intel_encoder, | |||
| 376 | 371 | ||
| 377 | /* Write a single byte to the aux channel in native mode */ | 372 | /* Write a single byte to the aux channel in native mode */ |
| 378 | static int | 373 | static int |
| 379 | intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder, | 374 | intel_dp_aux_native_write_1(struct intel_dp *intel_dp, |
| 380 | uint16_t address, uint8_t byte) | 375 | uint16_t address, uint8_t byte) |
| 381 | { | 376 | { |
| 382 | return intel_dp_aux_native_write(intel_encoder, address, &byte, 1); | 377 | return intel_dp_aux_native_write(intel_dp, address, &byte, 1); |
| 383 | } | 378 | } |
| 384 | 379 | ||
| 385 | /* read bytes from a native aux channel */ | 380 | /* read bytes from a native aux channel */ |
| 386 | static int | 381 | static int |
| 387 | intel_dp_aux_native_read(struct intel_encoder *intel_encoder, | 382 | intel_dp_aux_native_read(struct intel_dp *intel_dp, |
| 388 | uint16_t address, uint8_t *recv, int recv_bytes) | 383 | uint16_t address, uint8_t *recv, int recv_bytes) |
| 389 | { | 384 | { |
| 390 | uint8_t msg[4]; | 385 | uint8_t msg[4]; |
| @@ -403,7 +398,7 @@ intel_dp_aux_native_read(struct intel_encoder *intel_encoder, | |||
| 403 | reply_bytes = recv_bytes + 1; | 398 | reply_bytes = recv_bytes + 1; |
| 404 | 399 | ||
| 405 | for (;;) { | 400 | for (;;) { |
| 406 | ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, | 401 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, |
| 407 | reply, reply_bytes); | 402 | reply, reply_bytes); |
| 408 | if (ret == 0) | 403 | if (ret == 0) |
| 409 | return -EPROTO; | 404 | return -EPROTO; |
| @@ -426,10 +421,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
| 426 | uint8_t write_byte, uint8_t *read_byte) | 421 | uint8_t write_byte, uint8_t *read_byte) |
| 427 | { | 422 | { |
| 428 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | 423 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; |
| 429 | struct intel_dp_priv *dp_priv = container_of(adapter, | 424 | struct intel_dp *intel_dp = container_of(adapter, |
| 430 | struct intel_dp_priv, | 425 | struct intel_dp, |
| 431 | adapter); | 426 | adapter); |
| 432 | struct intel_encoder *intel_encoder = dp_priv->intel_encoder; | ||
| 433 | uint16_t address = algo_data->address; | 427 | uint16_t address = algo_data->address; |
| 434 | uint8_t msg[5]; | 428 | uint8_t msg[5]; |
| 435 | uint8_t reply[2]; | 429 | uint8_t reply[2]; |
| @@ -468,7 +462,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
| 468 | } | 462 | } |
| 469 | 463 | ||
| 470 | for (;;) { | 464 | for (;;) { |
| 471 | ret = intel_dp_aux_ch(intel_encoder, | 465 | ret = intel_dp_aux_ch(intel_dp, |
| 472 | msg, msg_bytes, | 466 | msg, msg_bytes, |
| 473 | reply, reply_bytes); | 467 | reply, reply_bytes); |
| 474 | if (ret < 0) { | 468 | if (ret < 0) { |
| @@ -496,57 +490,42 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
| 496 | } | 490 | } |
| 497 | 491 | ||
| 498 | static int | 492 | static int |
| 499 | intel_dp_i2c_init(struct intel_encoder *intel_encoder, | 493 | intel_dp_i2c_init(struct intel_dp *intel_dp, |
| 500 | struct intel_connector *intel_connector, const char *name) | 494 | struct intel_connector *intel_connector, const char *name) |
| 501 | { | 495 | { |
| 502 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 503 | |||
| 504 | DRM_DEBUG_KMS("i2c_init %s\n", name); | 496 | DRM_DEBUG_KMS("i2c_init %s\n", name); |
| 505 | dp_priv->algo.running = false; | 497 | intel_dp->algo.running = false; |
| 506 | dp_priv->algo.address = 0; | 498 | intel_dp->algo.address = 0; |
| 507 | dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch; | 499 | intel_dp->algo.aux_ch = intel_dp_i2c_aux_ch; |
| 508 | 500 | ||
| 509 | memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter)); | 501 | memset(&intel_dp->adapter, '\0', sizeof (intel_dp->adapter)); |
| 510 | dp_priv->adapter.owner = THIS_MODULE; | 502 | intel_dp->adapter.owner = THIS_MODULE; |
| 511 | dp_priv->adapter.class = I2C_CLASS_DDC; | 503 | intel_dp->adapter.class = I2C_CLASS_DDC; |
| 512 | strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1); | 504 | strncpy (intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1); |
| 513 | dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0'; | 505 | intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0'; |
| 514 | dp_priv->adapter.algo_data = &dp_priv->algo; | 506 | intel_dp->adapter.algo_data = &intel_dp->algo; |
| 515 | dp_priv->adapter.dev.parent = &intel_connector->base.kdev; | 507 | intel_dp->adapter.dev.parent = &intel_connector->base.kdev; |
| 516 | 508 | ||
| 517 | return i2c_dp_aux_add_bus(&dp_priv->adapter); | 509 | return i2c_dp_aux_add_bus(&intel_dp->adapter); |
| 518 | } | 510 | } |
| 519 | 511 | ||
| 520 | static bool | 512 | static bool |
| 521 | intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | 513 | intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, |
| 522 | struct drm_display_mode *adjusted_mode) | 514 | struct drm_display_mode *adjusted_mode) |
| 523 | { | 515 | { |
| 524 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 525 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 526 | struct drm_device *dev = encoder->dev; | 516 | struct drm_device *dev = encoder->dev; |
| 527 | struct drm_i915_private *dev_priv = dev->dev_private; | 517 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 518 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
| 528 | int lane_count, clock; | 519 | int lane_count, clock; |
| 529 | int max_lane_count = intel_dp_max_lane_count(intel_encoder); | 520 | int max_lane_count = intel_dp_max_lane_count(intel_dp); |
| 530 | int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0; | 521 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; |
| 531 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | 522 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; |
| 532 | 523 | ||
| 533 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | 524 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && |
| 534 | dev_priv->panel_fixed_mode) { | 525 | dev_priv->panel_fixed_mode) { |
| 535 | struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode; | 526 | intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode); |
| 536 | 527 | intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN, | |
| 537 | adjusted_mode->hdisplay = fixed_mode->hdisplay; | 528 | mode, adjusted_mode); |
| 538 | adjusted_mode->hsync_start = fixed_mode->hsync_start; | ||
| 539 | adjusted_mode->hsync_end = fixed_mode->hsync_end; | ||
| 540 | adjusted_mode->htotal = fixed_mode->htotal; | ||
| 541 | |||
| 542 | adjusted_mode->vdisplay = fixed_mode->vdisplay; | ||
| 543 | adjusted_mode->vsync_start = fixed_mode->vsync_start; | ||
| 544 | adjusted_mode->vsync_end = fixed_mode->vsync_end; | ||
| 545 | adjusted_mode->vtotal = fixed_mode->vtotal; | ||
| 546 | |||
| 547 | adjusted_mode->clock = fixed_mode->clock; | ||
| 548 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
| 549 | |||
| 550 | /* | 529 | /* |
| 551 | * the mode->clock is used to calculate the Data&Link M/N | 530 | * the mode->clock is used to calculate the Data&Link M/N |
| 552 | * of the pipe. For the eDP the fixed clock should be used. | 531 | * of the pipe. For the eDP the fixed clock should be used. |
| @@ -558,31 +537,33 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 558 | for (clock = 0; clock <= max_clock; clock++) { | 537 | for (clock = 0; clock <= max_clock; clock++) { |
| 559 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); | 538 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
| 560 | 539 | ||
| 561 | if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock) | 540 | if (intel_dp_link_required(encoder->dev, intel_dp, mode->clock) |
| 562 | <= link_avail) { | 541 | <= link_avail) { |
| 563 | dp_priv->link_bw = bws[clock]; | 542 | intel_dp->link_bw = bws[clock]; |
| 564 | dp_priv->lane_count = lane_count; | 543 | intel_dp->lane_count = lane_count; |
| 565 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | 544 | adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); |
| 566 | DRM_DEBUG_KMS("Display port link bw %02x lane " | 545 | DRM_DEBUG_KMS("Display port link bw %02x lane " |
| 567 | "count %d clock %d\n", | 546 | "count %d clock %d\n", |
| 568 | dp_priv->link_bw, dp_priv->lane_count, | 547 | intel_dp->link_bw, intel_dp->lane_count, |
| 569 | adjusted_mode->clock); | 548 | adjusted_mode->clock); |
| 570 | return true; | 549 | return true; |
| 571 | } | 550 | } |
| 572 | } | 551 | } |
| 573 | } | 552 | } |
| 574 | 553 | ||
| 575 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | 554 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) { |
| 576 | /* okay we failed just pick the highest */ | 555 | /* okay we failed just pick the highest */ |
| 577 | dp_priv->lane_count = max_lane_count; | 556 | intel_dp->lane_count = max_lane_count; |
| 578 | dp_priv->link_bw = bws[max_clock]; | 557 | intel_dp->link_bw = bws[max_clock]; |
| 579 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | 558 | adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); |
| 580 | DRM_DEBUG_KMS("Force picking display port link bw %02x lane " | 559 | DRM_DEBUG_KMS("Force picking display port link bw %02x lane " |
| 581 | "count %d clock %d\n", | 560 | "count %d clock %d\n", |
| 582 | dp_priv->link_bw, dp_priv->lane_count, | 561 | intel_dp->link_bw, intel_dp->lane_count, |
| 583 | adjusted_mode->clock); | 562 | adjusted_mode->clock); |
| 563 | |||
| 584 | return true; | 564 | return true; |
| 585 | } | 565 | } |
| 566 | |||
| 586 | return false; | 567 | return false; |
| 587 | } | 568 | } |
| 588 | 569 | ||
| @@ -626,17 +607,14 @@ bool intel_pch_has_edp(struct drm_crtc *crtc) | |||
| 626 | struct drm_encoder *encoder; | 607 | struct drm_encoder *encoder; |
| 627 | 608 | ||
| 628 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 609 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
| 629 | struct intel_encoder *intel_encoder; | 610 | struct intel_dp *intel_dp; |
| 630 | struct intel_dp_priv *dp_priv; | ||
| 631 | 611 | ||
| 632 | if (!encoder || encoder->crtc != crtc) | 612 | if (encoder->crtc != crtc) |
| 633 | continue; | 613 | continue; |
| 634 | 614 | ||
| 635 | intel_encoder = enc_to_intel_encoder(encoder); | 615 | intel_dp = enc_to_intel_dp(encoder); |
| 636 | dp_priv = intel_encoder->dev_priv; | 616 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) |
| 637 | 617 | return intel_dp->is_pch_edp; | |
| 638 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) | ||
| 639 | return dp_priv->is_pch_edp; | ||
| 640 | } | 618 | } |
| 641 | return false; | 619 | return false; |
| 642 | } | 620 | } |
| @@ -657,18 +635,15 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
| 657 | * Find the lane count in the intel_encoder private | 635 | * Find the lane count in the intel_encoder private |
| 658 | */ | 636 | */ |
| 659 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 637 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
| 660 | struct intel_encoder *intel_encoder; | 638 | struct intel_dp *intel_dp; |
| 661 | struct intel_dp_priv *dp_priv; | ||
| 662 | 639 | ||
| 663 | if (encoder->crtc != crtc) | 640 | if (encoder->crtc != crtc) |
| 664 | continue; | 641 | continue; |
| 665 | 642 | ||
| 666 | intel_encoder = enc_to_intel_encoder(encoder); | 643 | intel_dp = enc_to_intel_dp(encoder); |
| 667 | dp_priv = intel_encoder->dev_priv; | 644 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) { |
| 668 | 645 | lane_count = intel_dp->lane_count; | |
| 669 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { | 646 | if (IS_PCH_eDP(intel_dp)) |
| 670 | lane_count = dp_priv->lane_count; | ||
| 671 | if (IS_PCH_eDP(dp_priv)) | ||
| 672 | bpp = dev_priv->edp_bpp; | 647 | bpp = dev_priv->edp_bpp; |
| 673 | break; | 648 | break; |
| 674 | } | 649 | } |
| @@ -724,107 +699,114 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 724 | struct drm_display_mode *adjusted_mode) | 699 | struct drm_display_mode *adjusted_mode) |
| 725 | { | 700 | { |
| 726 | struct drm_device *dev = encoder->dev; | 701 | struct drm_device *dev = encoder->dev; |
| 727 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 702 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
| 728 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 703 | struct drm_crtc *crtc = intel_dp->base.enc.crtc; |
| 729 | struct drm_crtc *crtc = intel_encoder->enc.crtc; | ||
| 730 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 704 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 731 | 705 | ||
| 732 | dp_priv->DP = (DP_VOLTAGE_0_4 | | 706 | intel_dp->DP = (DP_VOLTAGE_0_4 | |
| 733 | DP_PRE_EMPHASIS_0); | 707 | DP_PRE_EMPHASIS_0); |
| 734 | 708 | ||
| 735 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 709 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
| 736 | dp_priv->DP |= DP_SYNC_HS_HIGH; | 710 | intel_dp->DP |= DP_SYNC_HS_HIGH; |
| 737 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | 711 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
| 738 | dp_priv->DP |= DP_SYNC_VS_HIGH; | 712 | intel_dp->DP |= DP_SYNC_VS_HIGH; |
| 739 | 713 | ||
| 740 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 714 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
| 741 | dp_priv->DP |= DP_LINK_TRAIN_OFF_CPT; | 715 | intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; |
| 742 | else | 716 | else |
| 743 | dp_priv->DP |= DP_LINK_TRAIN_OFF; | 717 | intel_dp->DP |= DP_LINK_TRAIN_OFF; |
| 744 | 718 | ||
| 745 | switch (dp_priv->lane_count) { | 719 | switch (intel_dp->lane_count) { |
| 746 | case 1: | 720 | case 1: |
| 747 | dp_priv->DP |= DP_PORT_WIDTH_1; | 721 | intel_dp->DP |= DP_PORT_WIDTH_1; |
| 748 | break; | 722 | break; |
| 749 | case 2: | 723 | case 2: |
| 750 | dp_priv->DP |= DP_PORT_WIDTH_2; | 724 | intel_dp->DP |= DP_PORT_WIDTH_2; |
| 751 | break; | 725 | break; |
| 752 | case 4: | 726 | case 4: |
| 753 | dp_priv->DP |= DP_PORT_WIDTH_4; | 727 | intel_dp->DP |= DP_PORT_WIDTH_4; |
| 754 | break; | 728 | break; |
| 755 | } | 729 | } |
| 756 | if (dp_priv->has_audio) | 730 | if (intel_dp->has_audio) |
| 757 | dp_priv->DP |= DP_AUDIO_OUTPUT_ENABLE; | 731 | intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; |
| 758 | 732 | ||
| 759 | memset(dp_priv->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | 733 | memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); |
| 760 | dp_priv->link_configuration[0] = dp_priv->link_bw; | 734 | intel_dp->link_configuration[0] = intel_dp->link_bw; |
| 761 | dp_priv->link_configuration[1] = dp_priv->lane_count; | 735 | intel_dp->link_configuration[1] = intel_dp->lane_count; |
| 762 | 736 | ||
| 763 | /* | 737 | /* |
| 764 | * Check for DPCD version > 1.1 and enhanced framing support | 738 | * Check for DPCD version > 1.1 and enhanced framing support |
| 765 | */ | 739 | */ |
| 766 | if (dp_priv->dpcd[0] >= 0x11 && (dp_priv->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { | 740 | if (intel_dp->dpcd[0] >= 0x11 && (intel_dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { |
| 767 | dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | 741 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
| 768 | dp_priv->DP |= DP_ENHANCED_FRAMING; | 742 | intel_dp->DP |= DP_ENHANCED_FRAMING; |
| 769 | } | 743 | } |
| 770 | 744 | ||
| 771 | /* CPT DP's pipe select is decided in TRANS_DP_CTL */ | 745 | /* CPT DP's pipe select is decided in TRANS_DP_CTL */ |
| 772 | if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev)) | 746 | if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev)) |
| 773 | dp_priv->DP |= DP_PIPEB_SELECT; | 747 | intel_dp->DP |= DP_PIPEB_SELECT; |
| 774 | 748 | ||
| 775 | if (IS_eDP(intel_encoder)) { | 749 | if (IS_eDP(intel_dp)) { |
| 776 | /* don't miss out required setting for eDP */ | 750 | /* don't miss out required setting for eDP */ |
| 777 | dp_priv->DP |= DP_PLL_ENABLE; | 751 | intel_dp->DP |= DP_PLL_ENABLE; |
| 778 | if (adjusted_mode->clock < 200000) | 752 | if (adjusted_mode->clock < 200000) |
| 779 | dp_priv->DP |= DP_PLL_FREQ_160MHZ; | 753 | intel_dp->DP |= DP_PLL_FREQ_160MHZ; |
| 780 | else | 754 | else |
| 781 | dp_priv->DP |= DP_PLL_FREQ_270MHZ; | 755 | intel_dp->DP |= DP_PLL_FREQ_270MHZ; |
| 782 | } | 756 | } |
| 783 | } | 757 | } |
| 784 | 758 | ||
| 785 | static void ironlake_edp_panel_on (struct drm_device *dev) | 759 | static void ironlake_edp_panel_on (struct drm_device *dev) |
| 786 | { | 760 | { |
| 787 | struct drm_i915_private *dev_priv = dev->dev_private; | 761 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 788 | unsigned long timeout = jiffies + msecs_to_jiffies(5000); | 762 | u32 pp; |
| 789 | u32 pp, pp_status; | ||
| 790 | 763 | ||
| 791 | pp_status = I915_READ(PCH_PP_STATUS); | 764 | if (I915_READ(PCH_PP_STATUS) & PP_ON) |
| 792 | if (pp_status & PP_ON) | ||
| 793 | return; | 765 | return; |
| 794 | 766 | ||
| 795 | pp = I915_READ(PCH_PP_CONTROL); | 767 | pp = I915_READ(PCH_PP_CONTROL); |
| 768 | |||
| 769 | /* ILK workaround: disable reset around power sequence */ | ||
| 770 | pp &= ~PANEL_POWER_RESET; | ||
| 771 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
| 772 | POSTING_READ(PCH_PP_CONTROL); | ||
| 773 | |||
| 796 | pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON; | 774 | pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON; |
| 797 | I915_WRITE(PCH_PP_CONTROL, pp); | 775 | I915_WRITE(PCH_PP_CONTROL, pp); |
| 798 | do { | ||
| 799 | pp_status = I915_READ(PCH_PP_STATUS); | ||
| 800 | } while (((pp_status & PP_ON) == 0) && !time_after(jiffies, timeout)); | ||
| 801 | 776 | ||
| 802 | if (time_after(jiffies, timeout)) | 777 | if (wait_for(I915_READ(PCH_PP_STATUS) & PP_ON, 5000, 10)) |
| 803 | DRM_DEBUG_KMS("panel on wait timed out: 0x%08x\n", pp_status); | 778 | DRM_ERROR("panel on wait timed out: 0x%08x\n", |
| 779 | I915_READ(PCH_PP_STATUS)); | ||
| 804 | 780 | ||
| 805 | pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD); | 781 | pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD); |
| 782 | pp |= PANEL_POWER_RESET; /* restore panel reset bit */ | ||
| 806 | I915_WRITE(PCH_PP_CONTROL, pp); | 783 | I915_WRITE(PCH_PP_CONTROL, pp); |
| 784 | POSTING_READ(PCH_PP_CONTROL); | ||
| 807 | } | 785 | } |
| 808 | 786 | ||
| 809 | static void ironlake_edp_panel_off (struct drm_device *dev) | 787 | static void ironlake_edp_panel_off (struct drm_device *dev) |
| 810 | { | 788 | { |
| 811 | struct drm_i915_private *dev_priv = dev->dev_private; | 789 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 812 | unsigned long timeout = jiffies + msecs_to_jiffies(5000); | 790 | u32 pp; |
| 813 | u32 pp, pp_status; | ||
| 814 | 791 | ||
| 815 | pp = I915_READ(PCH_PP_CONTROL); | 792 | pp = I915_READ(PCH_PP_CONTROL); |
| 793 | |||
| 794 | /* ILK workaround: disable reset around power sequence */ | ||
| 795 | pp &= ~PANEL_POWER_RESET; | ||
| 796 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
| 797 | POSTING_READ(PCH_PP_CONTROL); | ||
| 798 | |||
| 816 | pp &= ~POWER_TARGET_ON; | 799 | pp &= ~POWER_TARGET_ON; |
| 817 | I915_WRITE(PCH_PP_CONTROL, pp); | 800 | I915_WRITE(PCH_PP_CONTROL, pp); |
| 818 | do { | ||
| 819 | pp_status = I915_READ(PCH_PP_STATUS); | ||
| 820 | } while ((pp_status & PP_ON) && !time_after(jiffies, timeout)); | ||
| 821 | 801 | ||
| 822 | if (time_after(jiffies, timeout)) | 802 | if (wait_for((I915_READ(PCH_PP_STATUS) & PP_ON) == 0, 5000, 10)) |
| 823 | DRM_DEBUG_KMS("panel off wait timed out\n"); | 803 | DRM_ERROR("panel off wait timed out: 0x%08x\n", |
| 804 | I915_READ(PCH_PP_STATUS)); | ||
| 824 | 805 | ||
| 825 | /* Make sure VDD is enabled so DP AUX will work */ | 806 | /* Make sure VDD is enabled so DP AUX will work */ |
| 826 | pp |= EDP_FORCE_VDD; | 807 | pp |= EDP_FORCE_VDD | PANEL_POWER_RESET; /* restore panel reset bit */ |
| 827 | I915_WRITE(PCH_PP_CONTROL, pp); | 808 | I915_WRITE(PCH_PP_CONTROL, pp); |
| 809 | POSTING_READ(PCH_PP_CONTROL); | ||
| 828 | } | 810 | } |
| 829 | 811 | ||
| 830 | static void ironlake_edp_backlight_on (struct drm_device *dev) | 812 | static void ironlake_edp_backlight_on (struct drm_device *dev) |
| @@ -849,33 +831,87 @@ static void ironlake_edp_backlight_off (struct drm_device *dev) | |||
| 849 | I915_WRITE(PCH_PP_CONTROL, pp); | 831 | I915_WRITE(PCH_PP_CONTROL, pp); |
| 850 | } | 832 | } |
| 851 | 833 | ||
| 834 | static void ironlake_edp_pll_on(struct drm_encoder *encoder) | ||
| 835 | { | ||
| 836 | struct drm_device *dev = encoder->dev; | ||
| 837 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 838 | u32 dpa_ctl; | ||
| 839 | |||
| 840 | DRM_DEBUG_KMS("\n"); | ||
| 841 | dpa_ctl = I915_READ(DP_A); | ||
| 842 | dpa_ctl &= ~DP_PLL_ENABLE; | ||
| 843 | I915_WRITE(DP_A, dpa_ctl); | ||
| 844 | } | ||
| 845 | |||
| 846 | static void ironlake_edp_pll_off(struct drm_encoder *encoder) | ||
| 847 | { | ||
| 848 | struct drm_device *dev = encoder->dev; | ||
| 849 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 850 | u32 dpa_ctl; | ||
| 851 | |||
| 852 | dpa_ctl = I915_READ(DP_A); | ||
| 853 | dpa_ctl |= DP_PLL_ENABLE; | ||
| 854 | I915_WRITE(DP_A, dpa_ctl); | ||
| 855 | udelay(200); | ||
| 856 | } | ||
| 857 | |||
| 858 | static void intel_dp_prepare(struct drm_encoder *encoder) | ||
| 859 | { | ||
| 860 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
| 861 | struct drm_device *dev = encoder->dev; | ||
| 862 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 863 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | ||
| 864 | |||
| 865 | if (IS_eDP(intel_dp)) { | ||
| 866 | ironlake_edp_backlight_off(dev); | ||
| 867 | ironlake_edp_panel_on(dev); | ||
| 868 | ironlake_edp_pll_on(encoder); | ||
| 869 | } | ||
| 870 | if (dp_reg & DP_PORT_EN) | ||
| 871 | intel_dp_link_down(intel_dp); | ||
| 872 | } | ||
| 873 | |||
| 874 | static void intel_dp_commit(struct drm_encoder *encoder) | ||
| 875 | { | ||
| 876 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
| 877 | struct drm_device *dev = encoder->dev; | ||
| 878 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 879 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | ||
| 880 | |||
| 881 | if (!(dp_reg & DP_PORT_EN)) { | ||
| 882 | intel_dp_link_train(intel_dp); | ||
| 883 | } | ||
| 884 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
| 885 | ironlake_edp_backlight_on(dev); | ||
| 886 | } | ||
| 887 | |||
| 852 | static void | 888 | static void |
| 853 | intel_dp_dpms(struct drm_encoder *encoder, int mode) | 889 | intel_dp_dpms(struct drm_encoder *encoder, int mode) |
| 854 | { | 890 | { |
| 855 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 891 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
| 856 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 857 | struct drm_device *dev = encoder->dev; | 892 | struct drm_device *dev = encoder->dev; |
| 858 | struct drm_i915_private *dev_priv = dev->dev_private; | 893 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 859 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); | 894 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); |
| 860 | 895 | ||
| 861 | if (mode != DRM_MODE_DPMS_ON) { | 896 | if (mode != DRM_MODE_DPMS_ON) { |
| 862 | if (dp_reg & DP_PORT_EN) { | 897 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) { |
| 863 | intel_dp_link_down(intel_encoder, dp_priv->DP); | 898 | ironlake_edp_backlight_off(dev); |
| 864 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | 899 | ironlake_edp_panel_off(dev); |
| 865 | ironlake_edp_backlight_off(dev); | ||
| 866 | ironlake_edp_panel_off(dev); | ||
| 867 | } | ||
| 868 | } | 900 | } |
| 901 | if (dp_reg & DP_PORT_EN) | ||
| 902 | intel_dp_link_down(intel_dp); | ||
| 903 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
| 904 | ironlake_edp_pll_off(encoder); | ||
| 869 | } else { | 905 | } else { |
| 870 | if (!(dp_reg & DP_PORT_EN)) { | 906 | if (!(dp_reg & DP_PORT_EN)) { |
| 871 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); | 907 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) |
| 872 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | ||
| 873 | ironlake_edp_panel_on(dev); | 908 | ironlake_edp_panel_on(dev); |
| 909 | intel_dp_link_train(intel_dp); | ||
| 910 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
| 874 | ironlake_edp_backlight_on(dev); | 911 | ironlake_edp_backlight_on(dev); |
| 875 | } | ||
| 876 | } | 912 | } |
| 877 | } | 913 | } |
| 878 | dp_priv->dpms_mode = mode; | 914 | intel_dp->dpms_mode = mode; |
| 879 | } | 915 | } |
| 880 | 916 | ||
| 881 | /* | 917 | /* |
| @@ -883,12 +919,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
| 883 | * link status information | 919 | * link status information |
| 884 | */ | 920 | */ |
| 885 | static bool | 921 | static bool |
| 886 | intel_dp_get_link_status(struct intel_encoder *intel_encoder, | 922 | intel_dp_get_link_status(struct intel_dp *intel_dp, |
| 887 | uint8_t link_status[DP_LINK_STATUS_SIZE]) | 923 | uint8_t link_status[DP_LINK_STATUS_SIZE]) |
| 888 | { | 924 | { |
| 889 | int ret; | 925 | int ret; |
| 890 | 926 | ||
| 891 | ret = intel_dp_aux_native_read(intel_encoder, | 927 | ret = intel_dp_aux_native_read(intel_dp, |
| 892 | DP_LANE0_1_STATUS, | 928 | DP_LANE0_1_STATUS, |
| 893 | link_status, DP_LINK_STATUS_SIZE); | 929 | link_status, DP_LINK_STATUS_SIZE); |
| 894 | if (ret != DP_LINK_STATUS_SIZE) | 930 | if (ret != DP_LINK_STATUS_SIZE) |
| @@ -965,7 +1001,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing) | |||
| 965 | } | 1001 | } |
| 966 | 1002 | ||
| 967 | static void | 1003 | static void |
| 968 | intel_get_adjust_train(struct intel_encoder *intel_encoder, | 1004 | intel_get_adjust_train(struct intel_dp *intel_dp, |
| 969 | uint8_t link_status[DP_LINK_STATUS_SIZE], | 1005 | uint8_t link_status[DP_LINK_STATUS_SIZE], |
| 970 | int lane_count, | 1006 | int lane_count, |
| 971 | uint8_t train_set[4]) | 1007 | uint8_t train_set[4]) |
| @@ -1101,27 +1137,27 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) | |||
| 1101 | } | 1137 | } |
| 1102 | 1138 | ||
| 1103 | static bool | 1139 | static bool |
| 1104 | intel_dp_set_link_train(struct intel_encoder *intel_encoder, | 1140 | intel_dp_set_link_train(struct intel_dp *intel_dp, |
| 1105 | uint32_t dp_reg_value, | 1141 | uint32_t dp_reg_value, |
| 1106 | uint8_t dp_train_pat, | 1142 | uint8_t dp_train_pat, |
| 1107 | uint8_t train_set[4], | 1143 | uint8_t train_set[4], |
| 1108 | bool first) | 1144 | bool first) |
| 1109 | { | 1145 | { |
| 1110 | struct drm_device *dev = intel_encoder->enc.dev; | 1146 | struct drm_device *dev = intel_dp->base.enc.dev; |
| 1111 | struct drm_i915_private *dev_priv = dev->dev_private; | 1147 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1112 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1148 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); |
| 1113 | int ret; | 1149 | int ret; |
| 1114 | 1150 | ||
| 1115 | I915_WRITE(dp_priv->output_reg, dp_reg_value); | 1151 | I915_WRITE(intel_dp->output_reg, dp_reg_value); |
| 1116 | POSTING_READ(dp_priv->output_reg); | 1152 | POSTING_READ(intel_dp->output_reg); |
| 1117 | if (first) | 1153 | if (first) |
| 1118 | intel_wait_for_vblank(dev); | 1154 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 1119 | 1155 | ||
| 1120 | intel_dp_aux_native_write_1(intel_encoder, | 1156 | intel_dp_aux_native_write_1(intel_dp, |
| 1121 | DP_TRAINING_PATTERN_SET, | 1157 | DP_TRAINING_PATTERN_SET, |
| 1122 | dp_train_pat); | 1158 | dp_train_pat); |
| 1123 | 1159 | ||
| 1124 | ret = intel_dp_aux_native_write(intel_encoder, | 1160 | ret = intel_dp_aux_native_write(intel_dp, |
| 1125 | DP_TRAINING_LANE0_SET, train_set, 4); | 1161 | DP_TRAINING_LANE0_SET, train_set, 4); |
| 1126 | if (ret != 4) | 1162 | if (ret != 4) |
| 1127 | return false; | 1163 | return false; |
| @@ -1130,12 +1166,10 @@ intel_dp_set_link_train(struct intel_encoder *intel_encoder, | |||
| 1130 | } | 1166 | } |
| 1131 | 1167 | ||
| 1132 | static void | 1168 | static void |
| 1133 | intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | 1169 | intel_dp_link_train(struct intel_dp *intel_dp) |
| 1134 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) | ||
| 1135 | { | 1170 | { |
| 1136 | struct drm_device *dev = intel_encoder->enc.dev; | 1171 | struct drm_device *dev = intel_dp->base.enc.dev; |
| 1137 | struct drm_i915_private *dev_priv = dev->dev_private; | 1172 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1138 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 1139 | uint8_t train_set[4]; | 1173 | uint8_t train_set[4]; |
| 1140 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | 1174 | uint8_t link_status[DP_LINK_STATUS_SIZE]; |
| 1141 | int i; | 1175 | int i; |
| @@ -1145,13 +1179,15 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
| 1145 | bool first = true; | 1179 | bool first = true; |
| 1146 | int tries; | 1180 | int tries; |
| 1147 | u32 reg; | 1181 | u32 reg; |
| 1182 | uint32_t DP = intel_dp->DP; | ||
| 1148 | 1183 | ||
| 1149 | /* Write the link configuration data */ | 1184 | /* Write the link configuration data */ |
| 1150 | intel_dp_aux_native_write(intel_encoder, DP_LINK_BW_SET, | 1185 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, |
| 1151 | link_configuration, DP_LINK_CONFIGURATION_SIZE); | 1186 | intel_dp->link_configuration, |
| 1187 | DP_LINK_CONFIGURATION_SIZE); | ||
| 1152 | 1188 | ||
| 1153 | DP |= DP_PORT_EN; | 1189 | DP |= DP_PORT_EN; |
| 1154 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1190 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
| 1155 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | 1191 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
| 1156 | else | 1192 | else |
| 1157 | DP &= ~DP_LINK_TRAIN_MASK; | 1193 | DP &= ~DP_LINK_TRAIN_MASK; |
| @@ -1162,39 +1198,39 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
| 1162 | for (;;) { | 1198 | for (;;) { |
| 1163 | /* Use train_set[0] to set the voltage and pre emphasis values */ | 1199 | /* Use train_set[0] to set the voltage and pre emphasis values */ |
| 1164 | uint32_t signal_levels; | 1200 | uint32_t signal_levels; |
| 1165 | if (IS_GEN6(dev) && IS_eDP(intel_encoder)) { | 1201 | if (IS_GEN6(dev) && IS_eDP(intel_dp)) { |
| 1166 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); | 1202 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); |
| 1167 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1203 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
| 1168 | } else { | 1204 | } else { |
| 1169 | signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | 1205 | signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count); |
| 1170 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1206 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
| 1171 | } | 1207 | } |
| 1172 | 1208 | ||
| 1173 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1209 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
| 1174 | reg = DP | DP_LINK_TRAIN_PAT_1_CPT; | 1210 | reg = DP | DP_LINK_TRAIN_PAT_1_CPT; |
| 1175 | else | 1211 | else |
| 1176 | reg = DP | DP_LINK_TRAIN_PAT_1; | 1212 | reg = DP | DP_LINK_TRAIN_PAT_1; |
| 1177 | 1213 | ||
| 1178 | if (!intel_dp_set_link_train(intel_encoder, reg, | 1214 | if (!intel_dp_set_link_train(intel_dp, reg, |
| 1179 | DP_TRAINING_PATTERN_1, train_set, first)) | 1215 | DP_TRAINING_PATTERN_1, train_set, first)) |
| 1180 | break; | 1216 | break; |
| 1181 | first = false; | 1217 | first = false; |
| 1182 | /* Set training pattern 1 */ | 1218 | /* Set training pattern 1 */ |
| 1183 | 1219 | ||
| 1184 | udelay(100); | 1220 | udelay(100); |
| 1185 | if (!intel_dp_get_link_status(intel_encoder, link_status)) | 1221 | if (!intel_dp_get_link_status(intel_dp, link_status)) |
| 1186 | break; | 1222 | break; |
| 1187 | 1223 | ||
| 1188 | if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) { | 1224 | if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { |
| 1189 | clock_recovery = true; | 1225 | clock_recovery = true; |
| 1190 | break; | 1226 | break; |
| 1191 | } | 1227 | } |
| 1192 | 1228 | ||
| 1193 | /* Check to see if we've tried the max voltage */ | 1229 | /* Check to see if we've tried the max voltage */ |
| 1194 | for (i = 0; i < dp_priv->lane_count; i++) | 1230 | for (i = 0; i < intel_dp->lane_count; i++) |
| 1195 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1231 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
| 1196 | break; | 1232 | break; |
| 1197 | if (i == dp_priv->lane_count) | 1233 | if (i == intel_dp->lane_count) |
| 1198 | break; | 1234 | break; |
| 1199 | 1235 | ||
| 1200 | /* Check to see if we've tried the same voltage 5 times */ | 1236 | /* Check to see if we've tried the same voltage 5 times */ |
| @@ -1207,7 +1243,7 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
| 1207 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | 1243 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; |
| 1208 | 1244 | ||
| 1209 | /* Compute new train_set as requested by target */ | 1245 | /* Compute new train_set as requested by target */ |
| 1210 | intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); | 1246 | intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set); |
| 1211 | } | 1247 | } |
| 1212 | 1248 | ||
| 1213 | /* channel equalization */ | 1249 | /* channel equalization */ |
| @@ -1217,30 +1253,30 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
| 1217 | /* Use train_set[0] to set the voltage and pre emphasis values */ | 1253 | /* Use train_set[0] to set the voltage and pre emphasis values */ |
| 1218 | uint32_t signal_levels; | 1254 | uint32_t signal_levels; |
| 1219 | 1255 | ||
| 1220 | if (IS_GEN6(dev) && IS_eDP(intel_encoder)) { | 1256 | if (IS_GEN6(dev) && IS_eDP(intel_dp)) { |
| 1221 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); | 1257 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); |
| 1222 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1258 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
| 1223 | } else { | 1259 | } else { |
| 1224 | signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | 1260 | signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count); |
| 1225 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1261 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
| 1226 | } | 1262 | } |
| 1227 | 1263 | ||
| 1228 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1264 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
| 1229 | reg = DP | DP_LINK_TRAIN_PAT_2_CPT; | 1265 | reg = DP | DP_LINK_TRAIN_PAT_2_CPT; |
| 1230 | else | 1266 | else |
| 1231 | reg = DP | DP_LINK_TRAIN_PAT_2; | 1267 | reg = DP | DP_LINK_TRAIN_PAT_2; |
| 1232 | 1268 | ||
| 1233 | /* channel eq pattern */ | 1269 | /* channel eq pattern */ |
| 1234 | if (!intel_dp_set_link_train(intel_encoder, reg, | 1270 | if (!intel_dp_set_link_train(intel_dp, reg, |
| 1235 | DP_TRAINING_PATTERN_2, train_set, | 1271 | DP_TRAINING_PATTERN_2, train_set, |
| 1236 | false)) | 1272 | false)) |
| 1237 | break; | 1273 | break; |
| 1238 | 1274 | ||
| 1239 | udelay(400); | 1275 | udelay(400); |
| 1240 | if (!intel_dp_get_link_status(intel_encoder, link_status)) | 1276 | if (!intel_dp_get_link_status(intel_dp, link_status)) |
| 1241 | break; | 1277 | break; |
| 1242 | 1278 | ||
| 1243 | if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) { | 1279 | if (intel_channel_eq_ok(link_status, intel_dp->lane_count)) { |
| 1244 | channel_eq = true; | 1280 | channel_eq = true; |
| 1245 | break; | 1281 | break; |
| 1246 | } | 1282 | } |
| @@ -1250,53 +1286,53 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
| 1250 | break; | 1286 | break; |
| 1251 | 1287 | ||
| 1252 | /* Compute new train_set as requested by target */ | 1288 | /* Compute new train_set as requested by target */ |
| 1253 | intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); | 1289 | intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set); |
| 1254 | ++tries; | 1290 | ++tries; |
| 1255 | } | 1291 | } |
| 1256 | 1292 | ||
| 1257 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1293 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
| 1258 | reg = DP | DP_LINK_TRAIN_OFF_CPT; | 1294 | reg = DP | DP_LINK_TRAIN_OFF_CPT; |
| 1259 | else | 1295 | else |
| 1260 | reg = DP | DP_LINK_TRAIN_OFF; | 1296 | reg = DP | DP_LINK_TRAIN_OFF; |
| 1261 | 1297 | ||
| 1262 | I915_WRITE(dp_priv->output_reg, reg); | 1298 | I915_WRITE(intel_dp->output_reg, reg); |
| 1263 | POSTING_READ(dp_priv->output_reg); | 1299 | POSTING_READ(intel_dp->output_reg); |
| 1264 | intel_dp_aux_native_write_1(intel_encoder, | 1300 | intel_dp_aux_native_write_1(intel_dp, |
| 1265 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); | 1301 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); |
| 1266 | } | 1302 | } |
| 1267 | 1303 | ||
| 1268 | static void | 1304 | static void |
| 1269 | intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) | 1305 | intel_dp_link_down(struct intel_dp *intel_dp) |
| 1270 | { | 1306 | { |
| 1271 | struct drm_device *dev = intel_encoder->enc.dev; | 1307 | struct drm_device *dev = intel_dp->base.enc.dev; |
| 1272 | struct drm_i915_private *dev_priv = dev->dev_private; | 1308 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1273 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1309 | uint32_t DP = intel_dp->DP; |
| 1274 | 1310 | ||
| 1275 | DRM_DEBUG_KMS("\n"); | 1311 | DRM_DEBUG_KMS("\n"); |
| 1276 | 1312 | ||
| 1277 | if (IS_eDP(intel_encoder)) { | 1313 | if (IS_eDP(intel_dp)) { |
| 1278 | DP &= ~DP_PLL_ENABLE; | 1314 | DP &= ~DP_PLL_ENABLE; |
| 1279 | I915_WRITE(dp_priv->output_reg, DP); | 1315 | I915_WRITE(intel_dp->output_reg, DP); |
| 1280 | POSTING_READ(dp_priv->output_reg); | 1316 | POSTING_READ(intel_dp->output_reg); |
| 1281 | udelay(100); | 1317 | udelay(100); |
| 1282 | } | 1318 | } |
| 1283 | 1319 | ||
| 1284 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) { | 1320 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) { |
| 1285 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | 1321 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
| 1286 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); | 1322 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); |
| 1287 | POSTING_READ(dp_priv->output_reg); | 1323 | POSTING_READ(intel_dp->output_reg); |
| 1288 | } else { | 1324 | } else { |
| 1289 | DP &= ~DP_LINK_TRAIN_MASK; | 1325 | DP &= ~DP_LINK_TRAIN_MASK; |
| 1290 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); | 1326 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); |
| 1291 | POSTING_READ(dp_priv->output_reg); | 1327 | POSTING_READ(intel_dp->output_reg); |
| 1292 | } | 1328 | } |
| 1293 | 1329 | ||
| 1294 | udelay(17000); | 1330 | udelay(17000); |
| 1295 | 1331 | ||
| 1296 | if (IS_eDP(intel_encoder)) | 1332 | if (IS_eDP(intel_dp)) |
| 1297 | DP |= DP_LINK_TRAIN_OFF; | 1333 | DP |= DP_LINK_TRAIN_OFF; |
| 1298 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); | 1334 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); |
| 1299 | POSTING_READ(dp_priv->output_reg); | 1335 | POSTING_READ(intel_dp->output_reg); |
| 1300 | } | 1336 | } |
| 1301 | 1337 | ||
| 1302 | /* | 1338 | /* |
| @@ -1309,41 +1345,39 @@ intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) | |||
| 1309 | */ | 1345 | */ |
| 1310 | 1346 | ||
| 1311 | static void | 1347 | static void |
| 1312 | intel_dp_check_link_status(struct intel_encoder *intel_encoder) | 1348 | intel_dp_check_link_status(struct intel_dp *intel_dp) |
| 1313 | { | 1349 | { |
| 1314 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 1315 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | 1350 | uint8_t link_status[DP_LINK_STATUS_SIZE]; |
| 1316 | 1351 | ||
| 1317 | if (!intel_encoder->enc.crtc) | 1352 | if (!intel_dp->base.enc.crtc) |
| 1318 | return; | 1353 | return; |
| 1319 | 1354 | ||
| 1320 | if (!intel_dp_get_link_status(intel_encoder, link_status)) { | 1355 | if (!intel_dp_get_link_status(intel_dp, link_status)) { |
| 1321 | intel_dp_link_down(intel_encoder, dp_priv->DP); | 1356 | intel_dp_link_down(intel_dp); |
| 1322 | return; | 1357 | return; |
| 1323 | } | 1358 | } |
| 1324 | 1359 | ||
| 1325 | if (!intel_channel_eq_ok(link_status, dp_priv->lane_count)) | 1360 | if (!intel_channel_eq_ok(link_status, intel_dp->lane_count)) |
| 1326 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); | 1361 | intel_dp_link_train(intel_dp); |
| 1327 | } | 1362 | } |
| 1328 | 1363 | ||
| 1329 | static enum drm_connector_status | 1364 | static enum drm_connector_status |
| 1330 | ironlake_dp_detect(struct drm_connector *connector) | 1365 | ironlake_dp_detect(struct drm_connector *connector) |
| 1331 | { | 1366 | { |
| 1332 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1367 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1333 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1368 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
| 1334 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 1335 | enum drm_connector_status status; | 1369 | enum drm_connector_status status; |
| 1336 | 1370 | ||
| 1337 | status = connector_status_disconnected; | 1371 | status = connector_status_disconnected; |
| 1338 | if (intel_dp_aux_native_read(intel_encoder, | 1372 | if (intel_dp_aux_native_read(intel_dp, |
| 1339 | 0x000, dp_priv->dpcd, | 1373 | 0x000, intel_dp->dpcd, |
| 1340 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | 1374 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) |
| 1341 | { | 1375 | { |
| 1342 | if (dp_priv->dpcd[0] != 0) | 1376 | if (intel_dp->dpcd[0] != 0) |
| 1343 | status = connector_status_connected; | 1377 | status = connector_status_connected; |
| 1344 | } | 1378 | } |
| 1345 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", dp_priv->dpcd[0], | 1379 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], |
| 1346 | dp_priv->dpcd[1], dp_priv->dpcd[2], dp_priv->dpcd[3]); | 1380 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); |
| 1347 | return status; | 1381 | return status; |
| 1348 | } | 1382 | } |
| 1349 | 1383 | ||
| @@ -1357,19 +1391,18 @@ static enum drm_connector_status | |||
| 1357 | intel_dp_detect(struct drm_connector *connector) | 1391 | intel_dp_detect(struct drm_connector *connector) |
| 1358 | { | 1392 | { |
| 1359 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1393 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1360 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1394 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
| 1361 | struct drm_device *dev = intel_encoder->enc.dev; | 1395 | struct drm_device *dev = intel_dp->base.enc.dev; |
| 1362 | struct drm_i915_private *dev_priv = dev->dev_private; | 1396 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1363 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 1364 | uint32_t temp, bit; | 1397 | uint32_t temp, bit; |
| 1365 | enum drm_connector_status status; | 1398 | enum drm_connector_status status; |
| 1366 | 1399 | ||
| 1367 | dp_priv->has_audio = false; | 1400 | intel_dp->has_audio = false; |
| 1368 | 1401 | ||
| 1369 | if (HAS_PCH_SPLIT(dev)) | 1402 | if (HAS_PCH_SPLIT(dev)) |
| 1370 | return ironlake_dp_detect(connector); | 1403 | return ironlake_dp_detect(connector); |
| 1371 | 1404 | ||
| 1372 | switch (dp_priv->output_reg) { | 1405 | switch (intel_dp->output_reg) { |
| 1373 | case DP_B: | 1406 | case DP_B: |
| 1374 | bit = DPB_HOTPLUG_INT_STATUS; | 1407 | bit = DPB_HOTPLUG_INT_STATUS; |
| 1375 | break; | 1408 | break; |
| @@ -1389,11 +1422,11 @@ intel_dp_detect(struct drm_connector *connector) | |||
| 1389 | return connector_status_disconnected; | 1422 | return connector_status_disconnected; |
| 1390 | 1423 | ||
| 1391 | status = connector_status_disconnected; | 1424 | status = connector_status_disconnected; |
| 1392 | if (intel_dp_aux_native_read(intel_encoder, | 1425 | if (intel_dp_aux_native_read(intel_dp, |
| 1393 | 0x000, dp_priv->dpcd, | 1426 | 0x000, intel_dp->dpcd, |
| 1394 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | 1427 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) |
| 1395 | { | 1428 | { |
| 1396 | if (dp_priv->dpcd[0] != 0) | 1429 | if (intel_dp->dpcd[0] != 0) |
| 1397 | status = connector_status_connected; | 1430 | status = connector_status_connected; |
| 1398 | } | 1431 | } |
| 1399 | return status; | 1432 | return status; |
| @@ -1402,18 +1435,17 @@ intel_dp_detect(struct drm_connector *connector) | |||
| 1402 | static int intel_dp_get_modes(struct drm_connector *connector) | 1435 | static int intel_dp_get_modes(struct drm_connector *connector) |
| 1403 | { | 1436 | { |
| 1404 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1437 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1405 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1438 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
| 1406 | struct drm_device *dev = intel_encoder->enc.dev; | 1439 | struct drm_device *dev = intel_dp->base.enc.dev; |
| 1407 | struct drm_i915_private *dev_priv = dev->dev_private; | 1440 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1408 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
| 1409 | int ret; | 1441 | int ret; |
| 1410 | 1442 | ||
| 1411 | /* We should parse the EDID data and find out if it has an audio sink | 1443 | /* We should parse the EDID data and find out if it has an audio sink |
| 1412 | */ | 1444 | */ |
| 1413 | 1445 | ||
| 1414 | ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 1446 | ret = intel_ddc_get_modes(connector, intel_dp->base.ddc_bus); |
| 1415 | if (ret) { | 1447 | if (ret) { |
| 1416 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | 1448 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && |
| 1417 | !dev_priv->panel_fixed_mode) { | 1449 | !dev_priv->panel_fixed_mode) { |
| 1418 | struct drm_display_mode *newmode; | 1450 | struct drm_display_mode *newmode; |
| 1419 | list_for_each_entry(newmode, &connector->probed_modes, | 1451 | list_for_each_entry(newmode, &connector->probed_modes, |
| @@ -1430,7 +1462,7 @@ static int intel_dp_get_modes(struct drm_connector *connector) | |||
| 1430 | } | 1462 | } |
| 1431 | 1463 | ||
| 1432 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ | 1464 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ |
| 1433 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | 1465 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) { |
| 1434 | if (dev_priv->panel_fixed_mode != NULL) { | 1466 | if (dev_priv->panel_fixed_mode != NULL) { |
| 1435 | struct drm_display_mode *mode; | 1467 | struct drm_display_mode *mode; |
| 1436 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); | 1468 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); |
| @@ -1452,9 +1484,9 @@ intel_dp_destroy (struct drm_connector *connector) | |||
| 1452 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { | 1484 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { |
| 1453 | .dpms = intel_dp_dpms, | 1485 | .dpms = intel_dp_dpms, |
| 1454 | .mode_fixup = intel_dp_mode_fixup, | 1486 | .mode_fixup = intel_dp_mode_fixup, |
| 1455 | .prepare = intel_encoder_prepare, | 1487 | .prepare = intel_dp_prepare, |
| 1456 | .mode_set = intel_dp_mode_set, | 1488 | .mode_set = intel_dp_mode_set, |
| 1457 | .commit = intel_encoder_commit, | 1489 | .commit = intel_dp_commit, |
| 1458 | }; | 1490 | }; |
| 1459 | 1491 | ||
| 1460 | static const struct drm_connector_funcs intel_dp_connector_funcs = { | 1492 | static const struct drm_connector_funcs intel_dp_connector_funcs = { |
| @@ -1470,27 +1502,17 @@ static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = | |||
| 1470 | .best_encoder = intel_attached_encoder, | 1502 | .best_encoder = intel_attached_encoder, |
| 1471 | }; | 1503 | }; |
| 1472 | 1504 | ||
| 1473 | static void intel_dp_enc_destroy(struct drm_encoder *encoder) | ||
| 1474 | { | ||
| 1475 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 1476 | |||
| 1477 | if (intel_encoder->i2c_bus) | ||
| 1478 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
| 1479 | drm_encoder_cleanup(encoder); | ||
| 1480 | kfree(intel_encoder); | ||
| 1481 | } | ||
| 1482 | |||
| 1483 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { | 1505 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { |
| 1484 | .destroy = intel_dp_enc_destroy, | 1506 | .destroy = intel_encoder_destroy, |
| 1485 | }; | 1507 | }; |
| 1486 | 1508 | ||
| 1487 | void | 1509 | void |
| 1488 | intel_dp_hot_plug(struct intel_encoder *intel_encoder) | 1510 | intel_dp_hot_plug(struct intel_encoder *intel_encoder) |
| 1489 | { | 1511 | { |
| 1490 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1512 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); |
| 1491 | 1513 | ||
| 1492 | if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) | 1514 | if (intel_dp->dpms_mode == DRM_MODE_DPMS_ON) |
| 1493 | intel_dp_check_link_status(intel_encoder); | 1515 | intel_dp_check_link_status(intel_dp); |
| 1494 | } | 1516 | } |
| 1495 | 1517 | ||
| 1496 | /* Return which DP Port should be selected for Transcoder DP control */ | 1518 | /* Return which DP Port should be selected for Transcoder DP control */ |
| @@ -1500,18 +1522,18 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc) | |||
| 1500 | struct drm_device *dev = crtc->dev; | 1522 | struct drm_device *dev = crtc->dev; |
| 1501 | struct drm_mode_config *mode_config = &dev->mode_config; | 1523 | struct drm_mode_config *mode_config = &dev->mode_config; |
| 1502 | struct drm_encoder *encoder; | 1524 | struct drm_encoder *encoder; |
| 1503 | struct intel_encoder *intel_encoder = NULL; | ||
| 1504 | 1525 | ||
| 1505 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 1526 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
| 1527 | struct intel_dp *intel_dp; | ||
| 1528 | |||
| 1506 | if (encoder->crtc != crtc) | 1529 | if (encoder->crtc != crtc) |
| 1507 | continue; | 1530 | continue; |
| 1508 | 1531 | ||
| 1509 | intel_encoder = enc_to_intel_encoder(encoder); | 1532 | intel_dp = enc_to_intel_dp(encoder); |
| 1510 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { | 1533 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) |
| 1511 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1534 | return intel_dp->output_reg; |
| 1512 | return dp_priv->output_reg; | ||
| 1513 | } | ||
| 1514 | } | 1535 | } |
| 1536 | |||
| 1515 | return -1; | 1537 | return -1; |
| 1516 | } | 1538 | } |
| 1517 | 1539 | ||
| @@ -1540,30 +1562,28 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
| 1540 | { | 1562 | { |
| 1541 | struct drm_i915_private *dev_priv = dev->dev_private; | 1563 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1542 | struct drm_connector *connector; | 1564 | struct drm_connector *connector; |
| 1565 | struct intel_dp *intel_dp; | ||
| 1543 | struct intel_encoder *intel_encoder; | 1566 | struct intel_encoder *intel_encoder; |
| 1544 | struct intel_connector *intel_connector; | 1567 | struct intel_connector *intel_connector; |
| 1545 | struct intel_dp_priv *dp_priv; | ||
| 1546 | const char *name = NULL; | 1568 | const char *name = NULL; |
| 1547 | int type; | 1569 | int type; |
| 1548 | 1570 | ||
| 1549 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + | 1571 | intel_dp = kzalloc(sizeof(struct intel_dp), GFP_KERNEL); |
| 1550 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); | 1572 | if (!intel_dp) |
| 1551 | if (!intel_encoder) | ||
| 1552 | return; | 1573 | return; |
| 1553 | 1574 | ||
| 1554 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 1575 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
| 1555 | if (!intel_connector) { | 1576 | if (!intel_connector) { |
| 1556 | kfree(intel_encoder); | 1577 | kfree(intel_dp); |
| 1557 | return; | 1578 | return; |
| 1558 | } | 1579 | } |
| 1580 | intel_encoder = &intel_dp->base; | ||
| 1559 | 1581 | ||
| 1560 | dp_priv = (struct intel_dp_priv *)(intel_encoder + 1); | 1582 | if (HAS_PCH_SPLIT(dev) && output_reg == PCH_DP_D) |
| 1561 | |||
| 1562 | if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D)) | ||
| 1563 | if (intel_dpd_is_edp(dev)) | 1583 | if (intel_dpd_is_edp(dev)) |
| 1564 | dp_priv->is_pch_edp = true; | 1584 | intel_dp->is_pch_edp = true; |
| 1565 | 1585 | ||
| 1566 | if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) { | 1586 | if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) { |
| 1567 | type = DRM_MODE_CONNECTOR_eDP; | 1587 | type = DRM_MODE_CONNECTOR_eDP; |
| 1568 | intel_encoder->type = INTEL_OUTPUT_EDP; | 1588 | intel_encoder->type = INTEL_OUTPUT_EDP; |
| 1569 | } else { | 1589 | } else { |
| @@ -1584,18 +1604,16 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
| 1584 | else if (output_reg == DP_D || output_reg == PCH_DP_D) | 1604 | else if (output_reg == DP_D || output_reg == PCH_DP_D) |
| 1585 | intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); | 1605 | intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); |
| 1586 | 1606 | ||
| 1587 | if (IS_eDP(intel_encoder)) | 1607 | if (IS_eDP(intel_dp)) |
| 1588 | intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); | 1608 | intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); |
| 1589 | 1609 | ||
| 1590 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1610 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
| 1591 | connector->interlace_allowed = true; | 1611 | connector->interlace_allowed = true; |
| 1592 | connector->doublescan_allowed = 0; | 1612 | connector->doublescan_allowed = 0; |
| 1593 | 1613 | ||
| 1594 | dp_priv->intel_encoder = intel_encoder; | 1614 | intel_dp->output_reg = output_reg; |
| 1595 | dp_priv->output_reg = output_reg; | 1615 | intel_dp->has_audio = false; |
| 1596 | dp_priv->has_audio = false; | 1616 | intel_dp->dpms_mode = DRM_MODE_DPMS_ON; |
| 1597 | dp_priv->dpms_mode = DRM_MODE_DPMS_ON; | ||
| 1598 | intel_encoder->dev_priv = dp_priv; | ||
| 1599 | 1617 | ||
| 1600 | drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs, | 1618 | drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs, |
| 1601 | DRM_MODE_ENCODER_TMDS); | 1619 | DRM_MODE_ENCODER_TMDS); |
| @@ -1630,12 +1648,12 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
| 1630 | break; | 1648 | break; |
| 1631 | } | 1649 | } |
| 1632 | 1650 | ||
| 1633 | intel_dp_i2c_init(intel_encoder, intel_connector, name); | 1651 | intel_dp_i2c_init(intel_dp, intel_connector, name); |
| 1634 | 1652 | ||
| 1635 | intel_encoder->ddc_bus = &dp_priv->adapter; | 1653 | intel_encoder->ddc_bus = &intel_dp->adapter; |
| 1636 | intel_encoder->hot_plug = intel_dp_hot_plug; | 1654 | intel_encoder->hot_plug = intel_dp_hot_plug; |
| 1637 | 1655 | ||
| 1638 | if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) { | 1656 | if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) { |
| 1639 | /* initialize panel mode from VBT if available for eDP */ | 1657 | /* initialize panel mode from VBT if available for eDP */ |
| 1640 | if (dev_priv->lfp_lvds_vbt_mode) { | 1658 | if (dev_priv->lfp_lvds_vbt_mode) { |
| 1641 | dev_priv->panel_fixed_mode = | 1659 | dev_priv->panel_fixed_mode = |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b2190148703..0e92aa07b38 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -32,6 +32,20 @@ | |||
| 32 | #include "drm_crtc.h" | 32 | #include "drm_crtc.h" |
| 33 | 33 | ||
| 34 | #include "drm_crtc_helper.h" | 34 | #include "drm_crtc_helper.h" |
| 35 | |||
| 36 | #define wait_for(COND, MS, W) ({ \ | ||
| 37 | unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ | ||
| 38 | int ret__ = 0; \ | ||
| 39 | while (! (COND)) { \ | ||
| 40 | if (time_after(jiffies, timeout__)) { \ | ||
| 41 | ret__ = -ETIMEDOUT; \ | ||
| 42 | break; \ | ||
| 43 | } \ | ||
| 44 | if (W) msleep(W); \ | ||
| 45 | } \ | ||
| 46 | ret__; \ | ||
| 47 | }) | ||
| 48 | |||
| 35 | /* | 49 | /* |
| 36 | * Display related stuff | 50 | * Display related stuff |
| 37 | */ | 51 | */ |
| @@ -102,7 +116,6 @@ struct intel_encoder { | |||
| 102 | struct i2c_adapter *ddc_bus; | 116 | struct i2c_adapter *ddc_bus; |
| 103 | bool load_detect_temp; | 117 | bool load_detect_temp; |
| 104 | bool needs_tv_clock; | 118 | bool needs_tv_clock; |
| 105 | void *dev_priv; | ||
| 106 | void (*hot_plug)(struct intel_encoder *); | 119 | void (*hot_plug)(struct intel_encoder *); |
| 107 | int crtc_mask; | 120 | int crtc_mask; |
| 108 | int clone_mask; | 121 | int clone_mask; |
| @@ -110,7 +123,6 @@ struct intel_encoder { | |||
| 110 | 123 | ||
| 111 | struct intel_connector { | 124 | struct intel_connector { |
| 112 | struct drm_connector base; | 125 | struct drm_connector base; |
| 113 | void *dev_priv; | ||
| 114 | }; | 126 | }; |
| 115 | 127 | ||
| 116 | struct intel_crtc; | 128 | struct intel_crtc; |
| @@ -156,7 +168,7 @@ struct intel_crtc { | |||
| 156 | uint32_t cursor_addr; | 168 | uint32_t cursor_addr; |
| 157 | int16_t cursor_x, cursor_y; | 169 | int16_t cursor_x, cursor_y; |
| 158 | int16_t cursor_width, cursor_height; | 170 | int16_t cursor_width, cursor_height; |
| 159 | bool cursor_visble; | 171 | bool cursor_visible, cursor_on; |
| 160 | }; | 172 | }; |
| 161 | 173 | ||
| 162 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) | 174 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) |
| @@ -188,10 +200,18 @@ extern bool intel_dpd_is_edp(struct drm_device *dev); | |||
| 188 | extern void intel_edp_link_config (struct intel_encoder *, int *, int *); | 200 | extern void intel_edp_link_config (struct intel_encoder *, int *, int *); |
| 189 | 201 | ||
| 190 | 202 | ||
| 203 | extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | ||
| 204 | struct drm_display_mode *adjusted_mode); | ||
| 205 | extern void intel_pch_panel_fitting(struct drm_device *dev, | ||
| 206 | int fitting_mode, | ||
| 207 | struct drm_display_mode *mode, | ||
| 208 | struct drm_display_mode *adjusted_mode); | ||
| 209 | |||
| 191 | extern int intel_panel_fitter_pipe (struct drm_device *dev); | 210 | extern int intel_panel_fitter_pipe (struct drm_device *dev); |
| 192 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); | 211 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
| 193 | extern void intel_encoder_prepare (struct drm_encoder *encoder); | 212 | extern void intel_encoder_prepare (struct drm_encoder *encoder); |
| 194 | extern void intel_encoder_commit (struct drm_encoder *encoder); | 213 | extern void intel_encoder_commit (struct drm_encoder *encoder); |
| 214 | extern void intel_encoder_destroy(struct drm_encoder *encoder); | ||
| 195 | 215 | ||
| 196 | extern struct drm_encoder *intel_attached_encoder(struct drm_connector *connector); | 216 | extern struct drm_encoder *intel_attached_encoder(struct drm_connector *connector); |
| 197 | 217 | ||
| @@ -199,7 +219,8 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | |||
| 199 | struct drm_crtc *crtc); | 219 | struct drm_crtc *crtc); |
| 200 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 220 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
| 201 | struct drm_file *file_priv); | 221 | struct drm_file *file_priv); |
| 202 | extern void intel_wait_for_vblank(struct drm_device *dev); | 222 | extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe); |
| 223 | extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); | ||
| 203 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); | 224 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); |
| 204 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | 225 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, |
| 205 | struct drm_connector *connector, | 226 | struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 227feca7cf8..a399f4b2c1c 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
| @@ -38,7 +38,7 @@ | |||
| 38 | #define CH7xxx_ADDR 0x76 | 38 | #define CH7xxx_ADDR 0x76 |
| 39 | #define TFP410_ADDR 0x38 | 39 | #define TFP410_ADDR 0x38 |
| 40 | 40 | ||
| 41 | static struct intel_dvo_device intel_dvo_devices[] = { | 41 | static const struct intel_dvo_device intel_dvo_devices[] = { |
| 42 | { | 42 | { |
| 43 | .type = INTEL_DVO_CHIP_TMDS, | 43 | .type = INTEL_DVO_CHIP_TMDS, |
| 44 | .name = "sil164", | 44 | .name = "sil164", |
| @@ -77,20 +77,33 @@ static struct intel_dvo_device intel_dvo_devices[] = { | |||
| 77 | } | 77 | } |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | struct intel_dvo { | ||
| 81 | struct intel_encoder base; | ||
| 82 | |||
| 83 | struct intel_dvo_device dev; | ||
| 84 | |||
| 85 | struct drm_display_mode *panel_fixed_mode; | ||
| 86 | bool panel_wants_dither; | ||
| 87 | }; | ||
| 88 | |||
| 89 | static struct intel_dvo *enc_to_intel_dvo(struct drm_encoder *encoder) | ||
| 90 | { | ||
| 91 | return container_of(enc_to_intel_encoder(encoder), struct intel_dvo, base); | ||
| 92 | } | ||
| 93 | |||
| 80 | static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) | 94 | static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) |
| 81 | { | 95 | { |
| 82 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | 96 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
| 83 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 97 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 84 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 98 | u32 dvo_reg = intel_dvo->dev.dvo_reg; |
| 85 | u32 dvo_reg = dvo->dvo_reg; | ||
| 86 | u32 temp = I915_READ(dvo_reg); | 99 | u32 temp = I915_READ(dvo_reg); |
| 87 | 100 | ||
| 88 | if (mode == DRM_MODE_DPMS_ON) { | 101 | if (mode == DRM_MODE_DPMS_ON) { |
| 89 | I915_WRITE(dvo_reg, temp | DVO_ENABLE); | 102 | I915_WRITE(dvo_reg, temp | DVO_ENABLE); |
| 90 | I915_READ(dvo_reg); | 103 | I915_READ(dvo_reg); |
| 91 | dvo->dev_ops->dpms(dvo, mode); | 104 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode); |
| 92 | } else { | 105 | } else { |
| 93 | dvo->dev_ops->dpms(dvo, mode); | 106 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode); |
| 94 | I915_WRITE(dvo_reg, temp & ~DVO_ENABLE); | 107 | I915_WRITE(dvo_reg, temp & ~DVO_ENABLE); |
| 95 | I915_READ(dvo_reg); | 108 | I915_READ(dvo_reg); |
| 96 | } | 109 | } |
| @@ -100,38 +113,36 @@ static int intel_dvo_mode_valid(struct drm_connector *connector, | |||
| 100 | struct drm_display_mode *mode) | 113 | struct drm_display_mode *mode) |
| 101 | { | 114 | { |
| 102 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 115 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 103 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 116 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 104 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
| 105 | 117 | ||
| 106 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 118 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
| 107 | return MODE_NO_DBLESCAN; | 119 | return MODE_NO_DBLESCAN; |
| 108 | 120 | ||
| 109 | /* XXX: Validate clock range */ | 121 | /* XXX: Validate clock range */ |
| 110 | 122 | ||
| 111 | if (dvo->panel_fixed_mode) { | 123 | if (intel_dvo->panel_fixed_mode) { |
| 112 | if (mode->hdisplay > dvo->panel_fixed_mode->hdisplay) | 124 | if (mode->hdisplay > intel_dvo->panel_fixed_mode->hdisplay) |
| 113 | return MODE_PANEL; | 125 | return MODE_PANEL; |
| 114 | if (mode->vdisplay > dvo->panel_fixed_mode->vdisplay) | 126 | if (mode->vdisplay > intel_dvo->panel_fixed_mode->vdisplay) |
| 115 | return MODE_PANEL; | 127 | return MODE_PANEL; |
| 116 | } | 128 | } |
| 117 | 129 | ||
| 118 | return dvo->dev_ops->mode_valid(dvo, mode); | 130 | return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode); |
| 119 | } | 131 | } |
| 120 | 132 | ||
| 121 | static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, | 133 | static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, |
| 122 | struct drm_display_mode *mode, | 134 | struct drm_display_mode *mode, |
| 123 | struct drm_display_mode *adjusted_mode) | 135 | struct drm_display_mode *adjusted_mode) |
| 124 | { | 136 | { |
| 125 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 137 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 126 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
| 127 | 138 | ||
| 128 | /* If we have timings from the BIOS for the panel, put them in | 139 | /* If we have timings from the BIOS for the panel, put them in |
| 129 | * to the adjusted mode. The CRTC will be set up for this mode, | 140 | * to the adjusted mode. The CRTC will be set up for this mode, |
| 130 | * with the panel scaling set up to source from the H/VDisplay | 141 | * with the panel scaling set up to source from the H/VDisplay |
| 131 | * of the original mode. | 142 | * of the original mode. |
| 132 | */ | 143 | */ |
| 133 | if (dvo->panel_fixed_mode != NULL) { | 144 | if (intel_dvo->panel_fixed_mode != NULL) { |
| 134 | #define C(x) adjusted_mode->x = dvo->panel_fixed_mode->x | 145 | #define C(x) adjusted_mode->x = intel_dvo->panel_fixed_mode->x |
| 135 | C(hdisplay); | 146 | C(hdisplay); |
| 136 | C(hsync_start); | 147 | C(hsync_start); |
| 137 | C(hsync_end); | 148 | C(hsync_end); |
| @@ -145,8 +156,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, | |||
| 145 | #undef C | 156 | #undef C |
| 146 | } | 157 | } |
| 147 | 158 | ||
| 148 | if (dvo->dev_ops->mode_fixup) | 159 | if (intel_dvo->dev.dev_ops->mode_fixup) |
| 149 | return dvo->dev_ops->mode_fixup(dvo, mode, adjusted_mode); | 160 | return intel_dvo->dev.dev_ops->mode_fixup(&intel_dvo->dev, mode, adjusted_mode); |
| 150 | 161 | ||
| 151 | return true; | 162 | return true; |
| 152 | } | 163 | } |
| @@ -158,11 +169,10 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
| 158 | struct drm_device *dev = encoder->dev; | 169 | struct drm_device *dev = encoder->dev; |
| 159 | struct drm_i915_private *dev_priv = dev->dev_private; | 170 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 160 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 171 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
| 161 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 172 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 162 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
| 163 | int pipe = intel_crtc->pipe; | 173 | int pipe = intel_crtc->pipe; |
| 164 | u32 dvo_val; | 174 | u32 dvo_val; |
| 165 | u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg; | 175 | u32 dvo_reg = intel_dvo->dev.dvo_reg, dvo_srcdim_reg; |
| 166 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | 176 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; |
| 167 | 177 | ||
| 168 | switch (dvo_reg) { | 178 | switch (dvo_reg) { |
| @@ -178,7 +188,7 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
| 178 | break; | 188 | break; |
| 179 | } | 189 | } |
| 180 | 190 | ||
| 181 | dvo->dev_ops->mode_set(dvo, mode, adjusted_mode); | 191 | intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, mode, adjusted_mode); |
| 182 | 192 | ||
| 183 | /* Save the data order, since I don't know what it should be set to. */ | 193 | /* Save the data order, since I don't know what it should be set to. */ |
| 184 | dvo_val = I915_READ(dvo_reg) & | 194 | dvo_val = I915_READ(dvo_reg) & |
| @@ -214,40 +224,38 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
| 214 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) | 224 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) |
| 215 | { | 225 | { |
| 216 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 226 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 217 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 227 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 218 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
| 219 | 228 | ||
| 220 | return dvo->dev_ops->detect(dvo); | 229 | return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev); |
| 221 | } | 230 | } |
| 222 | 231 | ||
| 223 | static int intel_dvo_get_modes(struct drm_connector *connector) | 232 | static int intel_dvo_get_modes(struct drm_connector *connector) |
| 224 | { | 233 | { |
| 225 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 234 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 226 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 235 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 227 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
| 228 | 236 | ||
| 229 | /* We should probably have an i2c driver get_modes function for those | 237 | /* We should probably have an i2c driver get_modes function for those |
| 230 | * devices which will have a fixed set of modes determined by the chip | 238 | * devices which will have a fixed set of modes determined by the chip |
| 231 | * (TV-out, for example), but for now with just TMDS and LVDS, | 239 | * (TV-out, for example), but for now with just TMDS and LVDS, |
| 232 | * that's not the case. | 240 | * that's not the case. |
| 233 | */ | 241 | */ |
| 234 | intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 242 | intel_ddc_get_modes(connector, intel_dvo->base.ddc_bus); |
| 235 | if (!list_empty(&connector->probed_modes)) | 243 | if (!list_empty(&connector->probed_modes)) |
| 236 | return 1; | 244 | return 1; |
| 237 | 245 | ||
| 238 | 246 | if (intel_dvo->panel_fixed_mode != NULL) { | |
| 239 | if (dvo->panel_fixed_mode != NULL) { | ||
| 240 | struct drm_display_mode *mode; | 247 | struct drm_display_mode *mode; |
| 241 | mode = drm_mode_duplicate(connector->dev, dvo->panel_fixed_mode); | 248 | mode = drm_mode_duplicate(connector->dev, intel_dvo->panel_fixed_mode); |
| 242 | if (mode) { | 249 | if (mode) { |
| 243 | drm_mode_probed_add(connector, mode); | 250 | drm_mode_probed_add(connector, mode); |
| 244 | return 1; | 251 | return 1; |
| 245 | } | 252 | } |
| 246 | } | 253 | } |
| 254 | |||
| 247 | return 0; | 255 | return 0; |
| 248 | } | 256 | } |
| 249 | 257 | ||
| 250 | static void intel_dvo_destroy (struct drm_connector *connector) | 258 | static void intel_dvo_destroy(struct drm_connector *connector) |
| 251 | { | 259 | { |
| 252 | drm_sysfs_connector_remove(connector); | 260 | drm_sysfs_connector_remove(connector); |
| 253 | drm_connector_cleanup(connector); | 261 | drm_connector_cleanup(connector); |
| @@ -277,28 +285,20 @@ static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs | |||
| 277 | 285 | ||
| 278 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) | 286 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) |
| 279 | { | 287 | { |
| 280 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 288 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 281 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 289 | |
| 282 | 290 | if (intel_dvo->dev.dev_ops->destroy) | |
| 283 | if (dvo) { | 291 | intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev); |
| 284 | if (dvo->dev_ops->destroy) | 292 | |
| 285 | dvo->dev_ops->destroy(dvo); | 293 | kfree(intel_dvo->panel_fixed_mode); |
| 286 | if (dvo->panel_fixed_mode) | 294 | |
| 287 | kfree(dvo->panel_fixed_mode); | 295 | intel_encoder_destroy(encoder); |
| 288 | } | ||
| 289 | if (intel_encoder->i2c_bus) | ||
| 290 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
| 291 | if (intel_encoder->ddc_bus) | ||
| 292 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
| 293 | drm_encoder_cleanup(encoder); | ||
| 294 | kfree(intel_encoder); | ||
| 295 | } | 296 | } |
| 296 | 297 | ||
| 297 | static const struct drm_encoder_funcs intel_dvo_enc_funcs = { | 298 | static const struct drm_encoder_funcs intel_dvo_enc_funcs = { |
| 298 | .destroy = intel_dvo_enc_destroy, | 299 | .destroy = intel_dvo_enc_destroy, |
| 299 | }; | 300 | }; |
| 300 | 301 | ||
| 301 | |||
| 302 | /** | 302 | /** |
| 303 | * Attempts to get a fixed panel timing for LVDS (currently only the i830). | 303 | * Attempts to get a fixed panel timing for LVDS (currently only the i830). |
| 304 | * | 304 | * |
| @@ -306,15 +306,13 @@ static const struct drm_encoder_funcs intel_dvo_enc_funcs = { | |||
| 306 | * chip being on DVOB/C and having multiple pipes. | 306 | * chip being on DVOB/C and having multiple pipes. |
| 307 | */ | 307 | */ |
| 308 | static struct drm_display_mode * | 308 | static struct drm_display_mode * |
| 309 | intel_dvo_get_current_mode (struct drm_connector *connector) | 309 | intel_dvo_get_current_mode(struct drm_connector *connector) |
| 310 | { | 310 | { |
| 311 | struct drm_device *dev = connector->dev; | 311 | struct drm_device *dev = connector->dev; |
| 312 | struct drm_i915_private *dev_priv = dev->dev_private; | 312 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 313 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 313 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 314 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 314 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
| 315 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 315 | uint32_t dvo_val = I915_READ(intel_dvo->dev.dvo_reg); |
| 316 | uint32_t dvo_reg = dvo->dvo_reg; | ||
| 317 | uint32_t dvo_val = I915_READ(dvo_reg); | ||
| 318 | struct drm_display_mode *mode = NULL; | 316 | struct drm_display_mode *mode = NULL; |
| 319 | 317 | ||
| 320 | /* If the DVO port is active, that'll be the LVDS, so we can pull out | 318 | /* If the DVO port is active, that'll be the LVDS, so we can pull out |
| @@ -327,7 +325,6 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
| 327 | crtc = intel_get_crtc_from_pipe(dev, pipe); | 325 | crtc = intel_get_crtc_from_pipe(dev, pipe); |
| 328 | if (crtc) { | 326 | if (crtc) { |
| 329 | mode = intel_crtc_mode_get(dev, crtc); | 327 | mode = intel_crtc_mode_get(dev, crtc); |
| 330 | |||
| 331 | if (mode) { | 328 | if (mode) { |
| 332 | mode->type |= DRM_MODE_TYPE_PREFERRED; | 329 | mode->type |= DRM_MODE_TYPE_PREFERRED; |
| 333 | if (dvo_val & DVO_HSYNC_ACTIVE_HIGH) | 330 | if (dvo_val & DVO_HSYNC_ACTIVE_HIGH) |
| @@ -337,28 +334,32 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
| 337 | } | 334 | } |
| 338 | } | 335 | } |
| 339 | } | 336 | } |
| 337 | |||
| 340 | return mode; | 338 | return mode; |
| 341 | } | 339 | } |
| 342 | 340 | ||
| 343 | void intel_dvo_init(struct drm_device *dev) | 341 | void intel_dvo_init(struct drm_device *dev) |
| 344 | { | 342 | { |
| 345 | struct intel_encoder *intel_encoder; | 343 | struct intel_encoder *intel_encoder; |
| 344 | struct intel_dvo *intel_dvo; | ||
| 346 | struct intel_connector *intel_connector; | 345 | struct intel_connector *intel_connector; |
| 347 | struct intel_dvo_device *dvo; | ||
| 348 | struct i2c_adapter *i2cbus = NULL; | 346 | struct i2c_adapter *i2cbus = NULL; |
| 349 | int ret = 0; | 347 | int ret = 0; |
| 350 | int i; | 348 | int i; |
| 351 | int encoder_type = DRM_MODE_ENCODER_NONE; | 349 | int encoder_type = DRM_MODE_ENCODER_NONE; |
| 352 | intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL); | 350 | |
| 353 | if (!intel_encoder) | 351 | intel_dvo = kzalloc(sizeof(struct intel_dvo), GFP_KERNEL); |
| 352 | if (!intel_dvo) | ||
| 354 | return; | 353 | return; |
| 355 | 354 | ||
| 356 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 355 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
| 357 | if (!intel_connector) { | 356 | if (!intel_connector) { |
| 358 | kfree(intel_encoder); | 357 | kfree(intel_dvo); |
| 359 | return; | 358 | return; |
| 360 | } | 359 | } |
| 361 | 360 | ||
| 361 | intel_encoder = &intel_dvo->base; | ||
| 362 | |||
| 362 | /* Set up the DDC bus */ | 363 | /* Set up the DDC bus */ |
| 363 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); | 364 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); |
| 364 | if (!intel_encoder->ddc_bus) | 365 | if (!intel_encoder->ddc_bus) |
| @@ -367,10 +368,9 @@ void intel_dvo_init(struct drm_device *dev) | |||
| 367 | /* Now, try to find a controller */ | 368 | /* Now, try to find a controller */ |
| 368 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { | 369 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { |
| 369 | struct drm_connector *connector = &intel_connector->base; | 370 | struct drm_connector *connector = &intel_connector->base; |
| 371 | const struct intel_dvo_device *dvo = &intel_dvo_devices[i]; | ||
| 370 | int gpio; | 372 | int gpio; |
| 371 | 373 | ||
| 372 | dvo = &intel_dvo_devices[i]; | ||
| 373 | |||
| 374 | /* Allow the I2C driver info to specify the GPIO to be used in | 374 | /* Allow the I2C driver info to specify the GPIO to be used in |
| 375 | * special cases, but otherwise default to what's defined | 375 | * special cases, but otherwise default to what's defined |
| 376 | * in the spec. | 376 | * in the spec. |
| @@ -393,11 +393,8 @@ void intel_dvo_init(struct drm_device *dev) | |||
| 393 | continue; | 393 | continue; |
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | if (dvo->dev_ops!= NULL) | 396 | intel_dvo->dev = *dvo; |
| 397 | ret = dvo->dev_ops->init(dvo, i2cbus); | 397 | ret = dvo->dev_ops->init(&intel_dvo->dev, i2cbus); |
| 398 | else | ||
| 399 | ret = false; | ||
| 400 | |||
| 401 | if (!ret) | 398 | if (!ret) |
| 402 | continue; | 399 | continue; |
| 403 | 400 | ||
| @@ -429,9 +426,6 @@ void intel_dvo_init(struct drm_device *dev) | |||
| 429 | connector->interlace_allowed = false; | 426 | connector->interlace_allowed = false; |
| 430 | connector->doublescan_allowed = false; | 427 | connector->doublescan_allowed = false; |
| 431 | 428 | ||
| 432 | intel_encoder->dev_priv = dvo; | ||
| 433 | intel_encoder->i2c_bus = i2cbus; | ||
| 434 | |||
| 435 | drm_encoder_init(dev, &intel_encoder->enc, | 429 | drm_encoder_init(dev, &intel_encoder->enc, |
| 436 | &intel_dvo_enc_funcs, encoder_type); | 430 | &intel_dvo_enc_funcs, encoder_type); |
| 437 | drm_encoder_helper_add(&intel_encoder->enc, | 431 | drm_encoder_helper_add(&intel_encoder->enc, |
| @@ -447,9 +441,9 @@ void intel_dvo_init(struct drm_device *dev) | |||
| 447 | * headers, likely), so for now, just get the current | 441 | * headers, likely), so for now, just get the current |
| 448 | * mode being output through DVO. | 442 | * mode being output through DVO. |
| 449 | */ | 443 | */ |
| 450 | dvo->panel_fixed_mode = | 444 | intel_dvo->panel_fixed_mode = |
| 451 | intel_dvo_get_current_mode(connector); | 445 | intel_dvo_get_current_mode(connector); |
| 452 | dvo->panel_wants_dither = true; | 446 | intel_dvo->panel_wants_dither = true; |
| 453 | } | 447 | } |
| 454 | 448 | ||
| 455 | drm_sysfs_connector_add(connector); | 449 | drm_sysfs_connector_add(connector); |
| @@ -461,6 +455,6 @@ void intel_dvo_init(struct drm_device *dev) | |||
| 461 | if (i2cbus != NULL) | 455 | if (i2cbus != NULL) |
| 462 | intel_i2c_destroy(i2cbus); | 456 | intel_i2c_destroy(i2cbus); |
| 463 | free_intel: | 457 | free_intel: |
| 464 | kfree(intel_encoder); | 458 | kfree(intel_dvo); |
| 465 | kfree(intel_connector); | 459 | kfree(intel_connector); |
| 466 | } | 460 | } |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 197887ed182..ccd4c97e652 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
| @@ -37,11 +37,17 @@ | |||
| 37 | #include "i915_drm.h" | 37 | #include "i915_drm.h" |
| 38 | #include "i915_drv.h" | 38 | #include "i915_drv.h" |
| 39 | 39 | ||
| 40 | struct intel_hdmi_priv { | 40 | struct intel_hdmi { |
| 41 | struct intel_encoder base; | ||
| 41 | u32 sdvox_reg; | 42 | u32 sdvox_reg; |
| 42 | bool has_hdmi_sink; | 43 | bool has_hdmi_sink; |
| 43 | }; | 44 | }; |
| 44 | 45 | ||
| 46 | static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder) | ||
| 47 | { | ||
| 48 | return container_of(enc_to_intel_encoder(encoder), struct intel_hdmi, base); | ||
| 49 | } | ||
| 50 | |||
| 45 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, | 51 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, |
| 46 | struct drm_display_mode *mode, | 52 | struct drm_display_mode *mode, |
| 47 | struct drm_display_mode *adjusted_mode) | 53 | struct drm_display_mode *adjusted_mode) |
| @@ -50,8 +56,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
| 50 | struct drm_i915_private *dev_priv = dev->dev_private; | 56 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 51 | struct drm_crtc *crtc = encoder->crtc; | 57 | struct drm_crtc *crtc = encoder->crtc; |
| 52 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 58 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 53 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 59 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
| 54 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
| 55 | u32 sdvox; | 60 | u32 sdvox; |
| 56 | 61 | ||
| 57 | sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; | 62 | sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; |
| @@ -60,7 +65,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
| 60 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 65 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
| 61 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; | 66 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; |
| 62 | 67 | ||
| 63 | if (hdmi_priv->has_hdmi_sink) { | 68 | if (intel_hdmi->has_hdmi_sink) { |
| 64 | sdvox |= SDVO_AUDIO_ENABLE; | 69 | sdvox |= SDVO_AUDIO_ENABLE; |
| 65 | if (HAS_PCH_CPT(dev)) | 70 | if (HAS_PCH_CPT(dev)) |
| 66 | sdvox |= HDMI_MODE_SELECT; | 71 | sdvox |= HDMI_MODE_SELECT; |
| @@ -73,26 +78,25 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
| 73 | sdvox |= SDVO_PIPE_B_SELECT; | 78 | sdvox |= SDVO_PIPE_B_SELECT; |
| 74 | } | 79 | } |
| 75 | 80 | ||
| 76 | I915_WRITE(hdmi_priv->sdvox_reg, sdvox); | 81 | I915_WRITE(intel_hdmi->sdvox_reg, sdvox); |
| 77 | POSTING_READ(hdmi_priv->sdvox_reg); | 82 | POSTING_READ(intel_hdmi->sdvox_reg); |
| 78 | } | 83 | } |
| 79 | 84 | ||
| 80 | static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | 85 | static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) |
| 81 | { | 86 | { |
| 82 | struct drm_device *dev = encoder->dev; | 87 | struct drm_device *dev = encoder->dev; |
| 83 | struct drm_i915_private *dev_priv = dev->dev_private; | 88 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 84 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 89 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
| 85 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
| 86 | u32 temp; | 90 | u32 temp; |
| 87 | 91 | ||
| 88 | temp = I915_READ(hdmi_priv->sdvox_reg); | 92 | temp = I915_READ(intel_hdmi->sdvox_reg); |
| 89 | 93 | ||
| 90 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but | 94 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but |
| 91 | * we do this anyway which shows more stable in testing. | 95 | * we do this anyway which shows more stable in testing. |
| 92 | */ | 96 | */ |
| 93 | if (HAS_PCH_SPLIT(dev)) { | 97 | if (HAS_PCH_SPLIT(dev)) { |
| 94 | I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE); | 98 | I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE); |
| 95 | POSTING_READ(hdmi_priv->sdvox_reg); | 99 | POSTING_READ(intel_hdmi->sdvox_reg); |
| 96 | } | 100 | } |
| 97 | 101 | ||
| 98 | if (mode != DRM_MODE_DPMS_ON) { | 102 | if (mode != DRM_MODE_DPMS_ON) { |
| @@ -101,15 +105,15 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
| 101 | temp |= SDVO_ENABLE; | 105 | temp |= SDVO_ENABLE; |
| 102 | } | 106 | } |
| 103 | 107 | ||
| 104 | I915_WRITE(hdmi_priv->sdvox_reg, temp); | 108 | I915_WRITE(intel_hdmi->sdvox_reg, temp); |
| 105 | POSTING_READ(hdmi_priv->sdvox_reg); | 109 | POSTING_READ(intel_hdmi->sdvox_reg); |
| 106 | 110 | ||
| 107 | /* HW workaround, need to write this twice for issue that may result | 111 | /* HW workaround, need to write this twice for issue that may result |
| 108 | * in first write getting masked. | 112 | * in first write getting masked. |
| 109 | */ | 113 | */ |
| 110 | if (HAS_PCH_SPLIT(dev)) { | 114 | if (HAS_PCH_SPLIT(dev)) { |
| 111 | I915_WRITE(hdmi_priv->sdvox_reg, temp); | 115 | I915_WRITE(intel_hdmi->sdvox_reg, temp); |
| 112 | POSTING_READ(hdmi_priv->sdvox_reg); | 116 | POSTING_READ(intel_hdmi->sdvox_reg); |
| 113 | } | 117 | } |
| 114 | } | 118 | } |
| 115 | 119 | ||
| @@ -138,19 +142,17 @@ static enum drm_connector_status | |||
| 138 | intel_hdmi_detect(struct drm_connector *connector) | 142 | intel_hdmi_detect(struct drm_connector *connector) |
| 139 | { | 143 | { |
| 140 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 144 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 141 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 145 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
| 142 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
| 143 | struct edid *edid = NULL; | 146 | struct edid *edid = NULL; |
| 144 | enum drm_connector_status status = connector_status_disconnected; | 147 | enum drm_connector_status status = connector_status_disconnected; |
| 145 | 148 | ||
| 146 | hdmi_priv->has_hdmi_sink = false; | 149 | intel_hdmi->has_hdmi_sink = false; |
| 147 | edid = drm_get_edid(connector, | 150 | edid = drm_get_edid(connector, intel_hdmi->base.ddc_bus); |
| 148 | intel_encoder->ddc_bus); | ||
| 149 | 151 | ||
| 150 | if (edid) { | 152 | if (edid) { |
| 151 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { | 153 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
| 152 | status = connector_status_connected; | 154 | status = connector_status_connected; |
| 153 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); | 155 | intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid); |
| 154 | } | 156 | } |
| 155 | connector->display_info.raw_edid = NULL; | 157 | connector->display_info.raw_edid = NULL; |
| 156 | kfree(edid); | 158 | kfree(edid); |
| @@ -162,13 +164,13 @@ intel_hdmi_detect(struct drm_connector *connector) | |||
| 162 | static int intel_hdmi_get_modes(struct drm_connector *connector) | 164 | static int intel_hdmi_get_modes(struct drm_connector *connector) |
| 163 | { | 165 | { |
| 164 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 166 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 165 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 167 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
| 166 | 168 | ||
| 167 | /* We should parse the EDID data and find out if it's an HDMI sink so | 169 | /* We should parse the EDID data and find out if it's an HDMI sink so |
| 168 | * we can send audio to it. | 170 | * we can send audio to it. |
| 169 | */ | 171 | */ |
| 170 | 172 | ||
| 171 | return intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 173 | return intel_ddc_get_modes(connector, intel_hdmi->base.ddc_bus); |
| 172 | } | 174 | } |
| 173 | 175 | ||
| 174 | static void intel_hdmi_destroy(struct drm_connector *connector) | 176 | static void intel_hdmi_destroy(struct drm_connector *connector) |
| @@ -199,18 +201,8 @@ static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs | |||
| 199 | .best_encoder = intel_attached_encoder, | 201 | .best_encoder = intel_attached_encoder, |
| 200 | }; | 202 | }; |
| 201 | 203 | ||
| 202 | static void intel_hdmi_enc_destroy(struct drm_encoder *encoder) | ||
| 203 | { | ||
| 204 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 205 | |||
| 206 | if (intel_encoder->i2c_bus) | ||
| 207 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
| 208 | drm_encoder_cleanup(encoder); | ||
| 209 | kfree(intel_encoder); | ||
| 210 | } | ||
| 211 | |||
| 212 | static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { | 204 | static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { |
| 213 | .destroy = intel_hdmi_enc_destroy, | 205 | .destroy = intel_encoder_destroy, |
| 214 | }; | 206 | }; |
| 215 | 207 | ||
| 216 | void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | 208 | void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) |
| @@ -219,21 +211,19 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
| 219 | struct drm_connector *connector; | 211 | struct drm_connector *connector; |
| 220 | struct intel_encoder *intel_encoder; | 212 | struct intel_encoder *intel_encoder; |
| 221 | struct intel_connector *intel_connector; | 213 | struct intel_connector *intel_connector; |
| 222 | struct intel_hdmi_priv *hdmi_priv; | 214 | struct intel_hdmi *intel_hdmi; |
| 223 | 215 | ||
| 224 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + | 216 | intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL); |
| 225 | sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); | 217 | if (!intel_hdmi) |
| 226 | if (!intel_encoder) | ||
| 227 | return; | 218 | return; |
| 228 | 219 | ||
| 229 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 220 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
| 230 | if (!intel_connector) { | 221 | if (!intel_connector) { |
| 231 | kfree(intel_encoder); | 222 | kfree(intel_hdmi); |
| 232 | return; | 223 | return; |
| 233 | } | 224 | } |
| 234 | 225 | ||
| 235 | hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1); | 226 | intel_encoder = &intel_hdmi->base; |
| 236 | |||
| 237 | connector = &intel_connector->base; | 227 | connector = &intel_connector->base; |
| 238 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, | 228 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, |
| 239 | DRM_MODE_CONNECTOR_HDMIA); | 229 | DRM_MODE_CONNECTOR_HDMIA); |
| @@ -274,8 +264,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
| 274 | if (!intel_encoder->ddc_bus) | 264 | if (!intel_encoder->ddc_bus) |
| 275 | goto err_connector; | 265 | goto err_connector; |
| 276 | 266 | ||
| 277 | hdmi_priv->sdvox_reg = sdvox_reg; | 267 | intel_hdmi->sdvox_reg = sdvox_reg; |
| 278 | intel_encoder->dev_priv = hdmi_priv; | ||
| 279 | 268 | ||
| 280 | drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs, | 269 | drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs, |
| 281 | DRM_MODE_ENCODER_TMDS); | 270 | DRM_MODE_ENCODER_TMDS); |
| @@ -298,7 +287,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
| 298 | 287 | ||
| 299 | err_connector: | 288 | err_connector: |
| 300 | drm_connector_cleanup(connector); | 289 | drm_connector_cleanup(connector); |
| 301 | kfree(intel_encoder); | 290 | kfree(intel_hdmi); |
| 302 | kfree(intel_connector); | 291 | kfree(intel_connector); |
| 303 | 292 | ||
| 304 | return; | 293 | return; |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 0a2e60059fb..b819c108114 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -41,12 +41,18 @@ | |||
| 41 | #include <linux/acpi.h> | 41 | #include <linux/acpi.h> |
| 42 | 42 | ||
| 43 | /* Private structure for the integrated LVDS support */ | 43 | /* Private structure for the integrated LVDS support */ |
| 44 | struct intel_lvds_priv { | 44 | struct intel_lvds { |
| 45 | struct intel_encoder base; | ||
| 45 | int fitting_mode; | 46 | int fitting_mode; |
| 46 | u32 pfit_control; | 47 | u32 pfit_control; |
| 47 | u32 pfit_pgm_ratios; | 48 | u32 pfit_pgm_ratios; |
| 48 | }; | 49 | }; |
| 49 | 50 | ||
| 51 | static struct intel_lvds *enc_to_intel_lvds(struct drm_encoder *encoder) | ||
| 52 | { | ||
| 53 | return container_of(enc_to_intel_encoder(encoder), struct intel_lvds, base); | ||
| 54 | } | ||
| 55 | |||
| 50 | /** | 56 | /** |
| 51 | * Sets the backlight level. | 57 | * Sets the backlight level. |
| 52 | * | 58 | * |
| @@ -90,7 +96,7 @@ static u32 intel_lvds_get_max_backlight(struct drm_device *dev) | |||
| 90 | static void intel_lvds_set_power(struct drm_device *dev, bool on) | 96 | static void intel_lvds_set_power(struct drm_device *dev, bool on) |
| 91 | { | 97 | { |
| 92 | struct drm_i915_private *dev_priv = dev->dev_private; | 98 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 93 | u32 pp_status, ctl_reg, status_reg, lvds_reg; | 99 | u32 ctl_reg, status_reg, lvds_reg; |
| 94 | 100 | ||
| 95 | if (HAS_PCH_SPLIT(dev)) { | 101 | if (HAS_PCH_SPLIT(dev)) { |
| 96 | ctl_reg = PCH_PP_CONTROL; | 102 | ctl_reg = PCH_PP_CONTROL; |
| @@ -108,9 +114,8 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on) | |||
| 108 | 114 | ||
| 109 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | | 115 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | |
| 110 | POWER_TARGET_ON); | 116 | POWER_TARGET_ON); |
| 111 | do { | 117 | if (wait_for(I915_READ(status_reg) & PP_ON, 1000, 0)) |
| 112 | pp_status = I915_READ(status_reg); | 118 | DRM_ERROR("timed out waiting to enable LVDS pipe"); |
| 113 | } while ((pp_status & PP_ON) == 0); | ||
| 114 | 119 | ||
| 115 | intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle); | 120 | intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle); |
| 116 | } else { | 121 | } else { |
| @@ -118,9 +123,8 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on) | |||
| 118 | 123 | ||
| 119 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & | 124 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & |
| 120 | ~POWER_TARGET_ON); | 125 | ~POWER_TARGET_ON); |
| 121 | do { | 126 | if (wait_for((I915_READ(status_reg) & PP_ON) == 0, 1000, 0)) |
| 122 | pp_status = I915_READ(status_reg); | 127 | DRM_ERROR("timed out waiting for LVDS pipe to turn off"); |
| 123 | } while (pp_status & PP_ON); | ||
| 124 | 128 | ||
| 125 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); | 129 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); |
| 126 | POSTING_READ(lvds_reg); | 130 | POSTING_READ(lvds_reg); |
| @@ -219,9 +223,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 219 | struct drm_device *dev = encoder->dev; | 223 | struct drm_device *dev = encoder->dev; |
| 220 | struct drm_i915_private *dev_priv = dev->dev_private; | 224 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 221 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 225 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
| 226 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); | ||
| 222 | struct drm_encoder *tmp_encoder; | 227 | struct drm_encoder *tmp_encoder; |
| 223 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 224 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | ||
| 225 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; | 228 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
| 226 | 229 | ||
| 227 | /* Should never happen!! */ | 230 | /* Should never happen!! */ |
| @@ -241,26 +244,20 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 241 | /* If we don't have a panel mode, there is nothing we can do */ | 244 | /* If we don't have a panel mode, there is nothing we can do */ |
| 242 | if (dev_priv->panel_fixed_mode == NULL) | 245 | if (dev_priv->panel_fixed_mode == NULL) |
| 243 | return true; | 246 | return true; |
| 247 | |||
| 244 | /* | 248 | /* |
| 245 | * We have timings from the BIOS for the panel, put them in | 249 | * We have timings from the BIOS for the panel, put them in |
| 246 | * to the adjusted mode. The CRTC will be set up for this mode, | 250 | * to the adjusted mode. The CRTC will be set up for this mode, |
| 247 | * with the panel scaling set up to source from the H/VDisplay | 251 | * with the panel scaling set up to source from the H/VDisplay |
| 248 | * of the original mode. | 252 | * of the original mode. |
| 249 | */ | 253 | */ |
| 250 | adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay; | 254 | intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode); |
| 251 | adjusted_mode->hsync_start = | 255 | |
| 252 | dev_priv->panel_fixed_mode->hsync_start; | 256 | if (HAS_PCH_SPLIT(dev)) { |
| 253 | adjusted_mode->hsync_end = | 257 | intel_pch_panel_fitting(dev, intel_lvds->fitting_mode, |
| 254 | dev_priv->panel_fixed_mode->hsync_end; | 258 | mode, adjusted_mode); |
| 255 | adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal; | 259 | return true; |
| 256 | adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay; | 260 | } |
| 257 | adjusted_mode->vsync_start = | ||
| 258 | dev_priv->panel_fixed_mode->vsync_start; | ||
| 259 | adjusted_mode->vsync_end = | ||
| 260 | dev_priv->panel_fixed_mode->vsync_end; | ||
| 261 | adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal; | ||
| 262 | adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; | ||
| 263 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
| 264 | 261 | ||
| 265 | /* Make sure pre-965s set dither correctly */ | 262 | /* Make sure pre-965s set dither correctly */ |
| 266 | if (!IS_I965G(dev)) { | 263 | if (!IS_I965G(dev)) { |
| @@ -273,10 +270,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 273 | adjusted_mode->vdisplay == mode->vdisplay) | 270 | adjusted_mode->vdisplay == mode->vdisplay) |
| 274 | goto out; | 271 | goto out; |
| 275 | 272 | ||
| 276 | /* full screen scale for now */ | ||
| 277 | if (HAS_PCH_SPLIT(dev)) | ||
| 278 | goto out; | ||
| 279 | |||
| 280 | /* 965+ wants fuzzy fitting */ | 273 | /* 965+ wants fuzzy fitting */ |
| 281 | if (IS_I965G(dev)) | 274 | if (IS_I965G(dev)) |
| 282 | pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | | 275 | pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | |
| @@ -288,12 +281,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 288 | * to register description and PRM. | 281 | * to register description and PRM. |
| 289 | * Change the value here to see the borders for debugging | 282 | * Change the value here to see the borders for debugging |
| 290 | */ | 283 | */ |
| 291 | if (!HAS_PCH_SPLIT(dev)) { | 284 | I915_WRITE(BCLRPAT_A, 0); |
| 292 | I915_WRITE(BCLRPAT_A, 0); | 285 | I915_WRITE(BCLRPAT_B, 0); |
| 293 | I915_WRITE(BCLRPAT_B, 0); | ||
| 294 | } | ||
| 295 | 286 | ||
| 296 | switch (lvds_priv->fitting_mode) { | 287 | switch (intel_lvds->fitting_mode) { |
| 297 | case DRM_MODE_SCALE_CENTER: | 288 | case DRM_MODE_SCALE_CENTER: |
| 298 | /* | 289 | /* |
| 299 | * For centered modes, we have to calculate border widths & | 290 | * For centered modes, we have to calculate border widths & |
| @@ -378,8 +369,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 378 | } | 369 | } |
| 379 | 370 | ||
| 380 | out: | 371 | out: |
| 381 | lvds_priv->pfit_control = pfit_control; | 372 | intel_lvds->pfit_control = pfit_control; |
| 382 | lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; | 373 | intel_lvds->pfit_pgm_ratios = pfit_pgm_ratios; |
| 383 | dev_priv->lvds_border_bits = border; | 374 | dev_priv->lvds_border_bits = border; |
| 384 | 375 | ||
| 385 | /* | 376 | /* |
| @@ -427,8 +418,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
| 427 | { | 418 | { |
| 428 | struct drm_device *dev = encoder->dev; | 419 | struct drm_device *dev = encoder->dev; |
| 429 | struct drm_i915_private *dev_priv = dev->dev_private; | 420 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 430 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 421 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); |
| 431 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | ||
| 432 | 422 | ||
| 433 | /* | 423 | /* |
| 434 | * The LVDS pin pair will already have been turned on in the | 424 | * The LVDS pin pair will already have been turned on in the |
| @@ -444,8 +434,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
| 444 | * screen. Should be enabled before the pipe is enabled, according to | 434 | * screen. Should be enabled before the pipe is enabled, according to |
| 445 | * register description and PRM. | 435 | * register description and PRM. |
| 446 | */ | 436 | */ |
| 447 | I915_WRITE(PFIT_PGM_RATIOS, lvds_priv->pfit_pgm_ratios); | 437 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); |
| 448 | I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control); | 438 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); |
| 449 | } | 439 | } |
| 450 | 440 | ||
| 451 | /** | 441 | /** |
| @@ -600,18 +590,17 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
| 600 | connector->encoder) { | 590 | connector->encoder) { |
| 601 | struct drm_crtc *crtc = connector->encoder->crtc; | 591 | struct drm_crtc *crtc = connector->encoder->crtc; |
| 602 | struct drm_encoder *encoder = connector->encoder; | 592 | struct drm_encoder *encoder = connector->encoder; |
| 603 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 593 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); |
| 604 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | ||
| 605 | 594 | ||
| 606 | if (value == DRM_MODE_SCALE_NONE) { | 595 | if (value == DRM_MODE_SCALE_NONE) { |
| 607 | DRM_DEBUG_KMS("no scaling not supported\n"); | 596 | DRM_DEBUG_KMS("no scaling not supported\n"); |
| 608 | return 0; | 597 | return 0; |
| 609 | } | 598 | } |
| 610 | if (lvds_priv->fitting_mode == value) { | 599 | if (intel_lvds->fitting_mode == value) { |
| 611 | /* the LVDS scaling property is not changed */ | 600 | /* the LVDS scaling property is not changed */ |
| 612 | return 0; | 601 | return 0; |
| 613 | } | 602 | } |
| 614 | lvds_priv->fitting_mode = value; | 603 | intel_lvds->fitting_mode = value; |
| 615 | if (crtc && crtc->enabled) { | 604 | if (crtc && crtc->enabled) { |
| 616 | /* | 605 | /* |
| 617 | * If the CRTC is enabled, the display will be changed | 606 | * If the CRTC is enabled, the display will be changed |
| @@ -647,19 +636,8 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = { | |||
| 647 | .destroy = intel_lvds_destroy, | 636 | .destroy = intel_lvds_destroy, |
| 648 | }; | 637 | }; |
| 649 | 638 | ||
| 650 | |||
| 651 | static void intel_lvds_enc_destroy(struct drm_encoder *encoder) | ||
| 652 | { | ||
| 653 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 654 | |||
| 655 | if (intel_encoder->ddc_bus) | ||
| 656 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
| 657 | drm_encoder_cleanup(encoder); | ||
| 658 | kfree(intel_encoder); | ||
| 659 | } | ||
| 660 | |||
| 661 | static const struct drm_encoder_funcs intel_lvds_enc_funcs = { | 639 | static const struct drm_encoder_funcs intel_lvds_enc_funcs = { |
| 662 | .destroy = intel_lvds_enc_destroy, | 640 | .destroy = intel_encoder_destroy, |
| 663 | }; | 641 | }; |
| 664 | 642 | ||
| 665 | static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) | 643 | static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) |
| @@ -843,13 +821,13 @@ static int lvds_is_present_in_vbt(struct drm_device *dev) | |||
| 843 | void intel_lvds_init(struct drm_device *dev) | 821 | void intel_lvds_init(struct drm_device *dev) |
| 844 | { | 822 | { |
| 845 | struct drm_i915_private *dev_priv = dev->dev_private; | 823 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 824 | struct intel_lvds *intel_lvds; | ||
| 846 | struct intel_encoder *intel_encoder; | 825 | struct intel_encoder *intel_encoder; |
| 847 | struct intel_connector *intel_connector; | 826 | struct intel_connector *intel_connector; |
| 848 | struct drm_connector *connector; | 827 | struct drm_connector *connector; |
| 849 | struct drm_encoder *encoder; | 828 | struct drm_encoder *encoder; |
| 850 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ | 829 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ |
| 851 | struct drm_crtc *crtc; | 830 | struct drm_crtc *crtc; |
| 852 | struct intel_lvds_priv *lvds_priv; | ||
| 853 | u32 lvds; | 831 | u32 lvds; |
| 854 | int pipe, gpio = GPIOC; | 832 | int pipe, gpio = GPIOC; |
| 855 | 833 | ||
| @@ -872,20 +850,20 @@ void intel_lvds_init(struct drm_device *dev) | |||
| 872 | gpio = PCH_GPIOC; | 850 | gpio = PCH_GPIOC; |
| 873 | } | 851 | } |
| 874 | 852 | ||
| 875 | intel_encoder = kzalloc(sizeof(struct intel_encoder) + | 853 | intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL); |
| 876 | sizeof(struct intel_lvds_priv), GFP_KERNEL); | 854 | if (!intel_lvds) { |
| 877 | if (!intel_encoder) { | ||
| 878 | return; | 855 | return; |
| 879 | } | 856 | } |
| 880 | 857 | ||
| 881 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 858 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
| 882 | if (!intel_connector) { | 859 | if (!intel_connector) { |
| 883 | kfree(intel_encoder); | 860 | kfree(intel_lvds); |
| 884 | return; | 861 | return; |
| 885 | } | 862 | } |
| 886 | 863 | ||
| 887 | connector = &intel_connector->base; | 864 | intel_encoder = &intel_lvds->base; |
| 888 | encoder = &intel_encoder->enc; | 865 | encoder = &intel_encoder->enc; |
| 866 | connector = &intel_connector->base; | ||
| 889 | drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, | 867 | drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, |
| 890 | DRM_MODE_CONNECTOR_LVDS); | 868 | DRM_MODE_CONNECTOR_LVDS); |
| 891 | 869 | ||
| @@ -905,8 +883,6 @@ void intel_lvds_init(struct drm_device *dev) | |||
| 905 | connector->interlace_allowed = false; | 883 | connector->interlace_allowed = false; |
| 906 | connector->doublescan_allowed = false; | 884 | connector->doublescan_allowed = false; |
| 907 | 885 | ||
| 908 | lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1); | ||
| 909 | intel_encoder->dev_priv = lvds_priv; | ||
| 910 | /* create the scaling mode property */ | 886 | /* create the scaling mode property */ |
| 911 | drm_mode_create_scaling_mode_property(dev); | 887 | drm_mode_create_scaling_mode_property(dev); |
| 912 | /* | 888 | /* |
| @@ -916,7 +892,7 @@ void intel_lvds_init(struct drm_device *dev) | |||
| 916 | drm_connector_attach_property(&intel_connector->base, | 892 | drm_connector_attach_property(&intel_connector->base, |
| 917 | dev->mode_config.scaling_mode_property, | 893 | dev->mode_config.scaling_mode_property, |
| 918 | DRM_MODE_SCALE_ASPECT); | 894 | DRM_MODE_SCALE_ASPECT); |
| 919 | lvds_priv->fitting_mode = DRM_MODE_SCALE_ASPECT; | 895 | intel_lvds->fitting_mode = DRM_MODE_SCALE_ASPECT; |
| 920 | /* | 896 | /* |
| 921 | * LVDS discovery: | 897 | * LVDS discovery: |
| 922 | * 1) check for EDID on DDC | 898 | * 1) check for EDID on DDC |
| @@ -1024,6 +1000,6 @@ failed: | |||
| 1024 | intel_i2c_destroy(intel_encoder->ddc_bus); | 1000 | intel_i2c_destroy(intel_encoder->ddc_bus); |
| 1025 | drm_connector_cleanup(connector); | 1001 | drm_connector_cleanup(connector); |
| 1026 | drm_encoder_cleanup(encoder); | 1002 | drm_encoder_cleanup(encoder); |
| 1027 | kfree(intel_encoder); | 1003 | kfree(intel_lvds); |
| 1028 | kfree(intel_connector); | 1004 | kfree(intel_connector); |
| 1029 | } | 1005 | } |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index d39aea24eab..4f00390d7c6 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
| @@ -1367,7 +1367,8 @@ void intel_setup_overlay(struct drm_device *dev) | |||
| 1367 | overlay->flip_addr = overlay->reg_bo->gtt_offset; | 1367 | overlay->flip_addr = overlay->reg_bo->gtt_offset; |
| 1368 | } else { | 1368 | } else { |
| 1369 | ret = i915_gem_attach_phys_object(dev, reg_bo, | 1369 | ret = i915_gem_attach_phys_object(dev, reg_bo, |
| 1370 | I915_GEM_PHYS_OVERLAY_REGS); | 1370 | I915_GEM_PHYS_OVERLAY_REGS, |
| 1371 | 0); | ||
| 1371 | if (ret) { | 1372 | if (ret) { |
| 1372 | DRM_ERROR("failed to attach phys overlay regs\n"); | 1373 | DRM_ERROR("failed to attach phys overlay regs\n"); |
| 1373 | goto out_free_bo; | 1374 | goto out_free_bo; |
| @@ -1416,3 +1417,99 @@ void intel_cleanup_overlay(struct drm_device *dev) | |||
| 1416 | kfree(dev_priv->overlay); | 1417 | kfree(dev_priv->overlay); |
| 1417 | } | 1418 | } |
| 1418 | } | 1419 | } |
| 1420 | |||
| 1421 | struct intel_overlay_error_state { | ||
| 1422 | struct overlay_registers regs; | ||
| 1423 | unsigned long base; | ||
| 1424 | u32 dovsta; | ||
| 1425 | u32 isr; | ||
| 1426 | }; | ||
| 1427 | |||
| 1428 | struct intel_overlay_error_state * | ||
| 1429 | intel_overlay_capture_error_state(struct drm_device *dev) | ||
| 1430 | { | ||
| 1431 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 1432 | struct intel_overlay *overlay = dev_priv->overlay; | ||
| 1433 | struct intel_overlay_error_state *error; | ||
| 1434 | struct overlay_registers __iomem *regs; | ||
| 1435 | |||
| 1436 | if (!overlay || !overlay->active) | ||
| 1437 | return NULL; | ||
| 1438 | |||
| 1439 | error = kmalloc(sizeof(*error), GFP_ATOMIC); | ||
| 1440 | if (error == NULL) | ||
| 1441 | return NULL; | ||
| 1442 | |||
| 1443 | error->dovsta = I915_READ(DOVSTA); | ||
| 1444 | error->isr = I915_READ(ISR); | ||
| 1445 | if (OVERLAY_NONPHYSICAL(overlay->dev)) | ||
| 1446 | error->base = (long) overlay->reg_bo->gtt_offset; | ||
| 1447 | else | ||
| 1448 | error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr; | ||
| 1449 | |||
| 1450 | regs = intel_overlay_map_regs_atomic(overlay); | ||
| 1451 | if (!regs) | ||
| 1452 | goto err; | ||
| 1453 | |||
| 1454 | memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers)); | ||
| 1455 | intel_overlay_unmap_regs_atomic(overlay); | ||
| 1456 | |||
| 1457 | return error; | ||
| 1458 | |||
| 1459 | err: | ||
| 1460 | kfree(error); | ||
| 1461 | return NULL; | ||
| 1462 | } | ||
| 1463 | |||
| 1464 | void | ||
| 1465 | intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error) | ||
| 1466 | { | ||
| 1467 | seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n", | ||
| 1468 | error->dovsta, error->isr); | ||
| 1469 | seq_printf(m, " Register file at 0x%08lx:\n", | ||
| 1470 | error->base); | ||
| 1471 | |||
| 1472 | #define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x) | ||
| 1473 | P(OBUF_0Y); | ||
| 1474 | P(OBUF_1Y); | ||
| 1475 | P(OBUF_0U); | ||
| 1476 | P(OBUF_0V); | ||
| 1477 | P(OBUF_1U); | ||
| 1478 | P(OBUF_1V); | ||
| 1479 | P(OSTRIDE); | ||
| 1480 | P(YRGB_VPH); | ||
| 1481 | P(UV_VPH); | ||
| 1482 | P(HORZ_PH); | ||
| 1483 | P(INIT_PHS); | ||
| 1484 | P(DWINPOS); | ||
| 1485 | P(DWINSZ); | ||
| 1486 | P(SWIDTH); | ||
| 1487 | P(SWIDTHSW); | ||
| 1488 | P(SHEIGHT); | ||
| 1489 | P(YRGBSCALE); | ||
| 1490 | P(UVSCALE); | ||
| 1491 | P(OCLRC0); | ||
| 1492 | P(OCLRC1); | ||
| 1493 | P(DCLRKV); | ||
| 1494 | P(DCLRKM); | ||
| 1495 | P(SCLRKVH); | ||
| 1496 | P(SCLRKVL); | ||
| 1497 | P(SCLRKEN); | ||
| 1498 | P(OCONFIG); | ||
| 1499 | P(OCMD); | ||
| 1500 | P(OSTART_0Y); | ||
| 1501 | P(OSTART_1Y); | ||
| 1502 | P(OSTART_0U); | ||
| 1503 | P(OSTART_0V); | ||
| 1504 | P(OSTART_1U); | ||
| 1505 | P(OSTART_1V); | ||
| 1506 | P(OTILEOFF_0Y); | ||
| 1507 | P(OTILEOFF_1Y); | ||
| 1508 | P(OTILEOFF_0U); | ||
| 1509 | P(OTILEOFF_0V); | ||
| 1510 | P(OTILEOFF_1U); | ||
| 1511 | P(OTILEOFF_1V); | ||
| 1512 | P(FASTHSCALE); | ||
| 1513 | P(UVSCALEV); | ||
| 1514 | #undef P | ||
| 1515 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c new file mode 100644 index 00000000000..e7f5299d9d5 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | /* | ||
| 2 | * Copyright © 2006-2010 Intel Corporation | ||
| 3 | * Copyright (c) 2006 Dave Airlie <airlied@linux.ie> | ||
| 4 | * | ||
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 6 | * copy of this software and associated documentation files (the "Software"), | ||
| 7 | * to deal in the Software without restriction, including without limitation | ||
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 10 | * Software is furnished to do so, subject to the following conditions: | ||
| 11 | * | ||
| 12 | * The above copyright notice and this permission notice (including the next | ||
| 13 | * paragraph) shall be included in all copies or substantial portions of the | ||
| 14 | * Software. | ||
| 15 | * | ||
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| 21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| 22 | * DEALINGS IN THE SOFTWARE. | ||
| 23 | * | ||
| 24 | * Authors: | ||
| 25 | * Eric Anholt <eric@anholt.net> | ||
| 26 | * Dave Airlie <airlied@linux.ie> | ||
| 27 | * Jesse Barnes <jesse.barnes@intel.com> | ||
| 28 | * Chris Wilson <chris@chris-wilson.co.uk> | ||
| 29 | */ | ||
| 30 | |||
| 31 | #include "intel_drv.h" | ||
| 32 | |||
| 33 | void | ||
| 34 | intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | ||
| 35 | struct drm_display_mode *adjusted_mode) | ||
| 36 | { | ||
| 37 | adjusted_mode->hdisplay = fixed_mode->hdisplay; | ||
| 38 | adjusted_mode->hsync_start = fixed_mode->hsync_start; | ||
| 39 | adjusted_mode->hsync_end = fixed_mode->hsync_end; | ||
| 40 | adjusted_mode->htotal = fixed_mode->htotal; | ||
| 41 | |||
| 42 | adjusted_mode->vdisplay = fixed_mode->vdisplay; | ||
| 43 | adjusted_mode->vsync_start = fixed_mode->vsync_start; | ||
| 44 | adjusted_mode->vsync_end = fixed_mode->vsync_end; | ||
| 45 | adjusted_mode->vtotal = fixed_mode->vtotal; | ||
| 46 | |||
| 47 | adjusted_mode->clock = fixed_mode->clock; | ||
| 48 | |||
| 49 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
| 50 | } | ||
| 51 | |||
| 52 | /* adjusted_mode has been preset to be the panel's fixed mode */ | ||
| 53 | void | ||
| 54 | intel_pch_panel_fitting(struct drm_device *dev, | ||
| 55 | int fitting_mode, | ||
| 56 | struct drm_display_mode *mode, | ||
| 57 | struct drm_display_mode *adjusted_mode) | ||
| 58 | { | ||
| 59 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 60 | int x, y, width, height; | ||
| 61 | |||
| 62 | x = y = width = height = 0; | ||
| 63 | |||
| 64 | /* Native modes don't need fitting */ | ||
| 65 | if (adjusted_mode->hdisplay == mode->hdisplay && | ||
| 66 | adjusted_mode->vdisplay == mode->vdisplay) | ||
| 67 | goto done; | ||
| 68 | |||
| 69 | switch (fitting_mode) { | ||
| 70 | case DRM_MODE_SCALE_CENTER: | ||
| 71 | width = mode->hdisplay; | ||
| 72 | height = mode->vdisplay; | ||
| 73 | x = (adjusted_mode->hdisplay - width + 1)/2; | ||
| 74 | y = (adjusted_mode->vdisplay - height + 1)/2; | ||
| 75 | break; | ||
| 76 | |||
| 77 | case DRM_MODE_SCALE_ASPECT: | ||
| 78 | /* Scale but preserve the aspect ratio */ | ||
| 79 | { | ||
| 80 | u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; | ||
| 81 | u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; | ||
| 82 | if (scaled_width > scaled_height) { /* pillar */ | ||
| 83 | width = scaled_height / mode->vdisplay; | ||
| 84 | x = (adjusted_mode->hdisplay - width + 1) / 2; | ||
| 85 | y = 0; | ||
| 86 | height = adjusted_mode->vdisplay; | ||
| 87 | } else if (scaled_width < scaled_height) { /* letter */ | ||
| 88 | height = scaled_width / mode->hdisplay; | ||
| 89 | y = (adjusted_mode->vdisplay - height + 1) / 2; | ||
| 90 | x = 0; | ||
| 91 | width = adjusted_mode->hdisplay; | ||
| 92 | } else { | ||
| 93 | x = y = 0; | ||
| 94 | width = adjusted_mode->hdisplay; | ||
| 95 | height = adjusted_mode->vdisplay; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | break; | ||
| 99 | |||
| 100 | default: | ||
| 101 | case DRM_MODE_SCALE_FULLSCREEN: | ||
| 102 | x = y = 0; | ||
| 103 | width = adjusted_mode->hdisplay; | ||
| 104 | height = adjusted_mode->vdisplay; | ||
| 105 | break; | ||
| 106 | } | ||
| 107 | |||
| 108 | done: | ||
| 109 | dev_priv->pch_pf_pos = (x << 16) | y; | ||
| 110 | dev_priv->pch_pf_size = (width << 16) | height; | ||
| 111 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 26362f8495a..51e9c9e718c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -33,18 +33,35 @@ | |||
| 33 | #include "i915_drm.h" | 33 | #include "i915_drm.h" |
| 34 | #include "i915_trace.h" | 34 | #include "i915_trace.h" |
| 35 | 35 | ||
| 36 | static u32 i915_gem_get_seqno(struct drm_device *dev) | ||
| 37 | { | ||
| 38 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 39 | u32 seqno; | ||
| 40 | |||
| 41 | seqno = dev_priv->next_seqno; | ||
| 42 | |||
| 43 | /* reserve 0 for non-seqno */ | ||
| 44 | if (++dev_priv->next_seqno == 0) | ||
| 45 | dev_priv->next_seqno = 1; | ||
| 46 | |||
| 47 | return seqno; | ||
| 48 | } | ||
| 49 | |||
| 36 | static void | 50 | static void |
| 37 | render_ring_flush(struct drm_device *dev, | 51 | render_ring_flush(struct drm_device *dev, |
| 38 | struct intel_ring_buffer *ring, | 52 | struct intel_ring_buffer *ring, |
| 39 | u32 invalidate_domains, | 53 | u32 invalidate_domains, |
| 40 | u32 flush_domains) | 54 | u32 flush_domains) |
| 41 | { | 55 | { |
| 56 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 57 | u32 cmd; | ||
| 58 | |||
| 42 | #if WATCH_EXEC | 59 | #if WATCH_EXEC |
| 43 | DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, | 60 | DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, |
| 44 | invalidate_domains, flush_domains); | 61 | invalidate_domains, flush_domains); |
| 45 | #endif | 62 | #endif |
| 46 | u32 cmd; | 63 | |
| 47 | trace_i915_gem_request_flush(dev, ring->next_seqno, | 64 | trace_i915_gem_request_flush(dev, dev_priv->next_seqno, |
| 48 | invalidate_domains, flush_domains); | 65 | invalidate_domains, flush_domains); |
| 49 | 66 | ||
| 50 | if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { | 67 | if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { |
| @@ -233,9 +250,10 @@ render_ring_add_request(struct drm_device *dev, | |||
| 233 | struct drm_file *file_priv, | 250 | struct drm_file *file_priv, |
| 234 | u32 flush_domains) | 251 | u32 flush_domains) |
| 235 | { | 252 | { |
| 236 | u32 seqno; | ||
| 237 | drm_i915_private_t *dev_priv = dev->dev_private; | 253 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 238 | seqno = intel_ring_get_seqno(dev, ring); | 254 | u32 seqno; |
| 255 | |||
| 256 | seqno = i915_gem_get_seqno(dev); | ||
| 239 | 257 | ||
| 240 | if (IS_GEN6(dev)) { | 258 | if (IS_GEN6(dev)) { |
| 241 | BEGIN_LP_RING(6); | 259 | BEGIN_LP_RING(6); |
| @@ -405,7 +423,9 @@ bsd_ring_add_request(struct drm_device *dev, | |||
| 405 | u32 flush_domains) | 423 | u32 flush_domains) |
| 406 | { | 424 | { |
| 407 | u32 seqno; | 425 | u32 seqno; |
| 408 | seqno = intel_ring_get_seqno(dev, ring); | 426 | |
| 427 | seqno = i915_gem_get_seqno(dev); | ||
| 428 | |||
| 409 | intel_ring_begin(dev, ring, 4); | 429 | intel_ring_begin(dev, ring, 4); |
| 410 | intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); | 430 | intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); |
| 411 | intel_ring_emit(dev, ring, | 431 | intel_ring_emit(dev, ring, |
| @@ -479,7 +499,7 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev, | |||
| 479 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | 499 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; |
| 480 | exec_len = (uint32_t) exec->batch_len; | 500 | exec_len = (uint32_t) exec->batch_len; |
| 481 | 501 | ||
| 482 | trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1); | 502 | trace_i915_gem_request_submit(dev, dev_priv->next_seqno + 1); |
| 483 | 503 | ||
| 484 | count = nbox ? nbox : 1; | 504 | count = nbox ? nbox : 1; |
| 485 | 505 | ||
| @@ -515,7 +535,16 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev, | |||
| 515 | intel_ring_advance(dev, ring); | 535 | intel_ring_advance(dev, ring); |
| 516 | } | 536 | } |
| 517 | 537 | ||
| 538 | if (IS_G4X(dev) || IS_IRONLAKE(dev)) { | ||
| 539 | intel_ring_begin(dev, ring, 2); | ||
| 540 | intel_ring_emit(dev, ring, MI_FLUSH | | ||
| 541 | MI_NO_WRITE_FLUSH | | ||
| 542 | MI_INVALIDATE_ISP ); | ||
| 543 | intel_ring_emit(dev, ring, MI_NOOP); | ||
| 544 | intel_ring_advance(dev, ring); | ||
| 545 | } | ||
| 518 | /* XXX breadcrumb */ | 546 | /* XXX breadcrumb */ |
| 547 | |||
| 519 | return 0; | 548 | return 0; |
| 520 | } | 549 | } |
| 521 | 550 | ||
| @@ -588,9 +617,10 @@ err: | |||
| 588 | int intel_init_ring_buffer(struct drm_device *dev, | 617 | int intel_init_ring_buffer(struct drm_device *dev, |
| 589 | struct intel_ring_buffer *ring) | 618 | struct intel_ring_buffer *ring) |
| 590 | { | 619 | { |
| 591 | int ret; | ||
| 592 | struct drm_i915_gem_object *obj_priv; | 620 | struct drm_i915_gem_object *obj_priv; |
| 593 | struct drm_gem_object *obj; | 621 | struct drm_gem_object *obj; |
| 622 | int ret; | ||
| 623 | |||
| 594 | ring->dev = dev; | 624 | ring->dev = dev; |
| 595 | 625 | ||
| 596 | if (I915_NEED_GFX_HWS(dev)) { | 626 | if (I915_NEED_GFX_HWS(dev)) { |
| @@ -603,16 +633,14 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
| 603 | if (obj == NULL) { | 633 | if (obj == NULL) { |
| 604 | DRM_ERROR("Failed to allocate ringbuffer\n"); | 634 | DRM_ERROR("Failed to allocate ringbuffer\n"); |
| 605 | ret = -ENOMEM; | 635 | ret = -ENOMEM; |
| 606 | goto cleanup; | 636 | goto err_hws; |
| 607 | } | 637 | } |
| 608 | 638 | ||
| 609 | ring->gem_object = obj; | 639 | ring->gem_object = obj; |
| 610 | 640 | ||
| 611 | ret = i915_gem_object_pin(obj, ring->alignment); | 641 | ret = i915_gem_object_pin(obj, ring->alignment); |
| 612 | if (ret != 0) { | 642 | if (ret) |
| 613 | drm_gem_object_unreference(obj); | 643 | goto err_unref; |
| 614 | goto cleanup; | ||
| 615 | } | ||
| 616 | 644 | ||
| 617 | obj_priv = to_intel_bo(obj); | 645 | obj_priv = to_intel_bo(obj); |
| 618 | ring->map.size = ring->size; | 646 | ring->map.size = ring->size; |
| @@ -624,18 +652,14 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
| 624 | drm_core_ioremap_wc(&ring->map, dev); | 652 | drm_core_ioremap_wc(&ring->map, dev); |
| 625 | if (ring->map.handle == NULL) { | 653 | if (ring->map.handle == NULL) { |
| 626 | DRM_ERROR("Failed to map ringbuffer.\n"); | 654 | DRM_ERROR("Failed to map ringbuffer.\n"); |
| 627 | i915_gem_object_unpin(obj); | ||
| 628 | drm_gem_object_unreference(obj); | ||
| 629 | ret = -EINVAL; | 655 | ret = -EINVAL; |
| 630 | goto cleanup; | 656 | goto err_unpin; |
| 631 | } | 657 | } |
| 632 | 658 | ||
| 633 | ring->virtual_start = ring->map.handle; | 659 | ring->virtual_start = ring->map.handle; |
| 634 | ret = ring->init(dev, ring); | 660 | ret = ring->init(dev, ring); |
| 635 | if (ret != 0) { | 661 | if (ret) |
| 636 | intel_cleanup_ring_buffer(dev, ring); | 662 | goto err_unmap; |
| 637 | return ret; | ||
| 638 | } | ||
| 639 | 663 | ||
| 640 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 664 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
| 641 | i915_kernel_lost_context(dev); | 665 | i915_kernel_lost_context(dev); |
| @@ -649,7 +673,15 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
| 649 | INIT_LIST_HEAD(&ring->active_list); | 673 | INIT_LIST_HEAD(&ring->active_list); |
| 650 | INIT_LIST_HEAD(&ring->request_list); | 674 | INIT_LIST_HEAD(&ring->request_list); |
| 651 | return ret; | 675 | return ret; |
| 652 | cleanup: | 676 | |
| 677 | err_unmap: | ||
| 678 | drm_core_ioremapfree(&ring->map, dev); | ||
| 679 | err_unpin: | ||
| 680 | i915_gem_object_unpin(obj); | ||
| 681 | err_unref: | ||
| 682 | drm_gem_object_unreference(obj); | ||
| 683 | ring->gem_object = NULL; | ||
| 684 | err_hws: | ||
| 653 | cleanup_status_page(dev, ring); | 685 | cleanup_status_page(dev, ring); |
| 654 | return ret; | 686 | return ret; |
| 655 | } | 687 | } |
| @@ -682,9 +714,11 @@ int intel_wrap_ring_buffer(struct drm_device *dev, | |||
| 682 | } | 714 | } |
| 683 | 715 | ||
| 684 | virt = (unsigned int *)(ring->virtual_start + ring->tail); | 716 | virt = (unsigned int *)(ring->virtual_start + ring->tail); |
| 685 | rem /= 4; | 717 | rem /= 8; |
| 686 | while (rem--) | 718 | while (rem--) { |
| 719 | *virt++ = MI_NOOP; | ||
| 687 | *virt++ = MI_NOOP; | 720 | *virt++ = MI_NOOP; |
| 721 | } | ||
| 688 | 722 | ||
| 689 | ring->tail = 0; | 723 | ring->tail = 0; |
| 690 | ring->space = ring->head - 8; | 724 | ring->space = ring->head - 8; |
| @@ -729,21 +763,14 @@ void intel_ring_begin(struct drm_device *dev, | |||
| 729 | intel_wrap_ring_buffer(dev, ring); | 763 | intel_wrap_ring_buffer(dev, ring); |
| 730 | if (unlikely(ring->space < n)) | 764 | if (unlikely(ring->space < n)) |
| 731 | intel_wait_ring_buffer(dev, ring, n); | 765 | intel_wait_ring_buffer(dev, ring, n); |
| 732 | } | ||
| 733 | 766 | ||
| 734 | void intel_ring_emit(struct drm_device *dev, | 767 | ring->space -= n; |
| 735 | struct intel_ring_buffer *ring, unsigned int data) | ||
| 736 | { | ||
| 737 | unsigned int *virt = ring->virtual_start + ring->tail; | ||
| 738 | *virt = data; | ||
| 739 | ring->tail += 4; | ||
| 740 | ring->tail &= ring->size - 1; | ||
| 741 | ring->space -= 4; | ||
| 742 | } | 768 | } |
| 743 | 769 | ||
| 744 | void intel_ring_advance(struct drm_device *dev, | 770 | void intel_ring_advance(struct drm_device *dev, |
| 745 | struct intel_ring_buffer *ring) | 771 | struct intel_ring_buffer *ring) |
| 746 | { | 772 | { |
| 773 | ring->tail &= ring->size - 1; | ||
| 747 | ring->advance_ring(dev, ring); | 774 | ring->advance_ring(dev, ring); |
| 748 | } | 775 | } |
| 749 | 776 | ||
| @@ -762,18 +789,6 @@ void intel_fill_struct(struct drm_device *dev, | |||
| 762 | intel_ring_advance(dev, ring); | 789 | intel_ring_advance(dev, ring); |
| 763 | } | 790 | } |
| 764 | 791 | ||
| 765 | u32 intel_ring_get_seqno(struct drm_device *dev, | ||
| 766 | struct intel_ring_buffer *ring) | ||
| 767 | { | ||
| 768 | u32 seqno; | ||
| 769 | seqno = ring->next_seqno; | ||
| 770 | |||
| 771 | /* reserve 0 for non-seqno */ | ||
| 772 | if (++ring->next_seqno == 0) | ||
| 773 | ring->next_seqno = 1; | ||
| 774 | return seqno; | ||
| 775 | } | ||
| 776 | |||
| 777 | struct intel_ring_buffer render_ring = { | 792 | struct intel_ring_buffer render_ring = { |
| 778 | .name = "render ring", | 793 | .name = "render ring", |
| 779 | .regs = { | 794 | .regs = { |
| @@ -791,7 +806,6 @@ struct intel_ring_buffer render_ring = { | |||
| 791 | .head = 0, | 806 | .head = 0, |
| 792 | .tail = 0, | 807 | .tail = 0, |
| 793 | .space = 0, | 808 | .space = 0, |
| 794 | .next_seqno = 1, | ||
| 795 | .user_irq_refcount = 0, | 809 | .user_irq_refcount = 0, |
| 796 | .irq_gem_seqno = 0, | 810 | .irq_gem_seqno = 0, |
| 797 | .waiting_gem_seqno = 0, | 811 | .waiting_gem_seqno = 0, |
| @@ -830,7 +844,6 @@ struct intel_ring_buffer bsd_ring = { | |||
| 830 | .head = 0, | 844 | .head = 0, |
| 831 | .tail = 0, | 845 | .tail = 0, |
| 832 | .space = 0, | 846 | .space = 0, |
| 833 | .next_seqno = 1, | ||
| 834 | .user_irq_refcount = 0, | 847 | .user_irq_refcount = 0, |
| 835 | .irq_gem_seqno = 0, | 848 | .irq_gem_seqno = 0, |
| 836 | .waiting_gem_seqno = 0, | 849 | .waiting_gem_seqno = 0, |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index d5568d3766d..525e7d3edda 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
| @@ -26,7 +26,6 @@ struct intel_ring_buffer { | |||
| 26 | unsigned int head; | 26 | unsigned int head; |
| 27 | unsigned int tail; | 27 | unsigned int tail; |
| 28 | unsigned int space; | 28 | unsigned int space; |
| 29 | u32 next_seqno; | ||
| 30 | struct intel_hw_status_page status_page; | 29 | struct intel_hw_status_page status_page; |
| 31 | 30 | ||
| 32 | u32 irq_gem_seqno; /* last seq seem at irq time */ | 31 | u32 irq_gem_seqno; /* last seq seem at irq time */ |
| @@ -106,8 +105,16 @@ int intel_wrap_ring_buffer(struct drm_device *dev, | |||
| 106 | struct intel_ring_buffer *ring); | 105 | struct intel_ring_buffer *ring); |
| 107 | void intel_ring_begin(struct drm_device *dev, | 106 | void intel_ring_begin(struct drm_device *dev, |
| 108 | struct intel_ring_buffer *ring, int n); | 107 | struct intel_ring_buffer *ring, int n); |
| 109 | void intel_ring_emit(struct drm_device *dev, | 108 | |
| 110 | struct intel_ring_buffer *ring, u32 data); | 109 | static inline void intel_ring_emit(struct drm_device *dev, |
| 110 | struct intel_ring_buffer *ring, | ||
| 111 | unsigned int data) | ||
| 112 | { | ||
| 113 | unsigned int *virt = ring->virtual_start + ring->tail; | ||
| 114 | *virt = data; | ||
| 115 | ring->tail += 4; | ||
| 116 | } | ||
| 117 | |||
| 111 | void intel_fill_struct(struct drm_device *dev, | 118 | void intel_fill_struct(struct drm_device *dev, |
| 112 | struct intel_ring_buffer *ring, | 119 | struct intel_ring_buffer *ring, |
| 113 | void *data, | 120 | void *data, |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d9d4d51aa89..093e914e8a4 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -31,8 +31,8 @@ | |||
| 31 | #include "drmP.h" | 31 | #include "drmP.h" |
| 32 | #include "drm.h" | 32 | #include "drm.h" |
| 33 | #include "drm_crtc.h" | 33 | #include "drm_crtc.h" |
| 34 | #include "intel_drv.h" | ||
| 35 | #include "drm_edid.h" | 34 | #include "drm_edid.h" |
| 35 | #include "intel_drv.h" | ||
| 36 | #include "i915_drm.h" | 36 | #include "i915_drm.h" |
| 37 | #include "i915_drv.h" | 37 | #include "i915_drv.h" |
| 38 | #include "intel_sdvo_regs.h" | 38 | #include "intel_sdvo_regs.h" |
| @@ -47,9 +47,10 @@ | |||
| 47 | 47 | ||
| 48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) | 48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) |
| 49 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) | 49 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) |
| 50 | #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) | ||
| 50 | 51 | ||
| 51 | 52 | ||
| 52 | static char *tv_format_names[] = { | 53 | static const char *tv_format_names[] = { |
| 53 | "NTSC_M" , "NTSC_J" , "NTSC_443", | 54 | "NTSC_M" , "NTSC_J" , "NTSC_443", |
| 54 | "PAL_B" , "PAL_D" , "PAL_G" , | 55 | "PAL_B" , "PAL_D" , "PAL_G" , |
| 55 | "PAL_H" , "PAL_I" , "PAL_M" , | 56 | "PAL_H" , "PAL_I" , "PAL_M" , |
| @@ -61,7 +62,9 @@ static char *tv_format_names[] = { | |||
| 61 | 62 | ||
| 62 | #define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) | 63 | #define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) |
| 63 | 64 | ||
| 64 | struct intel_sdvo_priv { | 65 | struct intel_sdvo { |
| 66 | struct intel_encoder base; | ||
| 67 | |||
| 65 | u8 slave_addr; | 68 | u8 slave_addr; |
| 66 | 69 | ||
| 67 | /* Register for the SDVO device: SDVOB or SDVOC */ | 70 | /* Register for the SDVO device: SDVOB or SDVOC */ |
| @@ -95,7 +98,7 @@ struct intel_sdvo_priv { | |||
| 95 | bool is_tv; | 98 | bool is_tv; |
| 96 | 99 | ||
| 97 | /* This is for current tv format name */ | 100 | /* This is for current tv format name */ |
| 98 | char *tv_format_name; | 101 | int tv_format_index; |
| 99 | 102 | ||
| 100 | /** | 103 | /** |
| 101 | * This is set if we treat the device as HDMI, instead of DVI. | 104 | * This is set if we treat the device as HDMI, instead of DVI. |
| @@ -132,37 +135,40 @@ struct intel_sdvo_priv { | |||
| 132 | }; | 135 | }; |
| 133 | 136 | ||
| 134 | struct intel_sdvo_connector { | 137 | struct intel_sdvo_connector { |
| 138 | struct intel_connector base; | ||
| 139 | |||
| 135 | /* Mark the type of connector */ | 140 | /* Mark the type of connector */ |
| 136 | uint16_t output_flag; | 141 | uint16_t output_flag; |
| 137 | 142 | ||
| 138 | /* This contains all current supported TV format */ | 143 | /* This contains all current supported TV format */ |
| 139 | char *tv_format_supported[TV_FORMAT_NUM]; | 144 | u8 tv_format_supported[TV_FORMAT_NUM]; |
| 140 | int format_supported_num; | 145 | int format_supported_num; |
| 141 | struct drm_property *tv_format_property; | 146 | struct drm_property *tv_format; |
| 142 | struct drm_property *tv_format_name_property[TV_FORMAT_NUM]; | ||
| 143 | |||
| 144 | /** | ||
| 145 | * Returned SDTV resolutions allowed for the current format, if the | ||
| 146 | * device reported it. | ||
| 147 | */ | ||
| 148 | struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; | ||
| 149 | 147 | ||
| 150 | /* add the property for the SDVO-TV */ | 148 | /* add the property for the SDVO-TV */ |
| 151 | struct drm_property *left_property; | 149 | struct drm_property *left; |
| 152 | struct drm_property *right_property; | 150 | struct drm_property *right; |
| 153 | struct drm_property *top_property; | 151 | struct drm_property *top; |
| 154 | struct drm_property *bottom_property; | 152 | struct drm_property *bottom; |
| 155 | struct drm_property *hpos_property; | 153 | struct drm_property *hpos; |
| 156 | struct drm_property *vpos_property; | 154 | struct drm_property *vpos; |
| 155 | struct drm_property *contrast; | ||
| 156 | struct drm_property *saturation; | ||
| 157 | struct drm_property *hue; | ||
| 158 | struct drm_property *sharpness; | ||
| 159 | struct drm_property *flicker_filter; | ||
| 160 | struct drm_property *flicker_filter_adaptive; | ||
| 161 | struct drm_property *flicker_filter_2d; | ||
| 162 | struct drm_property *tv_chroma_filter; | ||
| 163 | struct drm_property *tv_luma_filter; | ||
| 164 | struct drm_property *dot_crawl; | ||
| 157 | 165 | ||
| 158 | /* add the property for the SDVO-TV/LVDS */ | 166 | /* add the property for the SDVO-TV/LVDS */ |
| 159 | struct drm_property *brightness_property; | 167 | struct drm_property *brightness; |
| 160 | struct drm_property *contrast_property; | ||
| 161 | struct drm_property *saturation_property; | ||
| 162 | struct drm_property *hue_property; | ||
| 163 | 168 | ||
| 164 | /* Add variable to record current setting for the above property */ | 169 | /* Add variable to record current setting for the above property */ |
| 165 | u32 left_margin, right_margin, top_margin, bottom_margin; | 170 | u32 left_margin, right_margin, top_margin, bottom_margin; |
| 171 | |||
| 166 | /* this is to get the range of margin.*/ | 172 | /* this is to get the range of margin.*/ |
| 167 | u32 max_hscan, max_vscan; | 173 | u32 max_hscan, max_vscan; |
| 168 | u32 max_hpos, cur_hpos; | 174 | u32 max_hpos, cur_hpos; |
| @@ -171,36 +177,54 @@ struct intel_sdvo_connector { | |||
| 171 | u32 cur_contrast, max_contrast; | 177 | u32 cur_contrast, max_contrast; |
| 172 | u32 cur_saturation, max_saturation; | 178 | u32 cur_saturation, max_saturation; |
| 173 | u32 cur_hue, max_hue; | 179 | u32 cur_hue, max_hue; |
| 180 | u32 cur_sharpness, max_sharpness; | ||
| 181 | u32 cur_flicker_filter, max_flicker_filter; | ||
| 182 | u32 cur_flicker_filter_adaptive, max_flicker_filter_adaptive; | ||
| 183 | u32 cur_flicker_filter_2d, max_flicker_filter_2d; | ||
| 184 | u32 cur_tv_chroma_filter, max_tv_chroma_filter; | ||
| 185 | u32 cur_tv_luma_filter, max_tv_luma_filter; | ||
| 186 | u32 cur_dot_crawl, max_dot_crawl; | ||
| 174 | }; | 187 | }; |
| 175 | 188 | ||
| 189 | static struct intel_sdvo *enc_to_intel_sdvo(struct drm_encoder *encoder) | ||
| 190 | { | ||
| 191 | return container_of(enc_to_intel_encoder(encoder), struct intel_sdvo, base); | ||
| 192 | } | ||
| 193 | |||
| 194 | static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) | ||
| 195 | { | ||
| 196 | return container_of(to_intel_connector(connector), struct intel_sdvo_connector, base); | ||
| 197 | } | ||
| 198 | |||
| 176 | static bool | 199 | static bool |
| 177 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, | 200 | intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags); |
| 178 | uint16_t flags); | 201 | static bool |
| 179 | static void | 202 | intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
| 180 | intel_sdvo_tv_create_property(struct drm_connector *connector, int type); | 203 | struct intel_sdvo_connector *intel_sdvo_connector, |
| 181 | static void | 204 | int type); |
| 182 | intel_sdvo_create_enhance_property(struct drm_connector *connector); | 205 | static bool |
| 206 | intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, | ||
| 207 | struct intel_sdvo_connector *intel_sdvo_connector); | ||
| 183 | 208 | ||
| 184 | /** | 209 | /** |
| 185 | * Writes the SDVOB or SDVOC with the given value, but always writes both | 210 | * Writes the SDVOB or SDVOC with the given value, but always writes both |
| 186 | * SDVOB and SDVOC to work around apparent hardware issues (according to | 211 | * SDVOB and SDVOC to work around apparent hardware issues (according to |
| 187 | * comments in the BIOS). | 212 | * comments in the BIOS). |
| 188 | */ | 213 | */ |
| 189 | static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) | 214 | static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) |
| 190 | { | 215 | { |
| 191 | struct drm_device *dev = intel_encoder->enc.dev; | 216 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
| 192 | struct drm_i915_private *dev_priv = dev->dev_private; | 217 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 193 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 194 | u32 bval = val, cval = val; | 218 | u32 bval = val, cval = val; |
| 195 | int i; | 219 | int i; |
| 196 | 220 | ||
| 197 | if (sdvo_priv->sdvo_reg == PCH_SDVOB) { | 221 | if (intel_sdvo->sdvo_reg == PCH_SDVOB) { |
| 198 | I915_WRITE(sdvo_priv->sdvo_reg, val); | 222 | I915_WRITE(intel_sdvo->sdvo_reg, val); |
| 199 | I915_READ(sdvo_priv->sdvo_reg); | 223 | I915_READ(intel_sdvo->sdvo_reg); |
| 200 | return; | 224 | return; |
| 201 | } | 225 | } |
| 202 | 226 | ||
| 203 | if (sdvo_priv->sdvo_reg == SDVOB) { | 227 | if (intel_sdvo->sdvo_reg == SDVOB) { |
| 204 | cval = I915_READ(SDVOC); | 228 | cval = I915_READ(SDVOC); |
| 205 | } else { | 229 | } else { |
| 206 | bval = I915_READ(SDVOB); | 230 | bval = I915_READ(SDVOB); |
| @@ -219,33 +243,27 @@ static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) | |||
| 219 | } | 243 | } |
| 220 | } | 244 | } |
| 221 | 245 | ||
| 222 | static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr, | 246 | static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch) |
| 223 | u8 *ch) | ||
| 224 | { | 247 | { |
| 225 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 248 | u8 out_buf[2] = { addr, 0 }; |
| 226 | u8 out_buf[2]; | ||
| 227 | u8 buf[2]; | 249 | u8 buf[2]; |
| 228 | int ret; | ||
| 229 | |||
| 230 | struct i2c_msg msgs[] = { | 250 | struct i2c_msg msgs[] = { |
| 231 | { | 251 | { |
| 232 | .addr = sdvo_priv->slave_addr >> 1, | 252 | .addr = intel_sdvo->slave_addr >> 1, |
| 233 | .flags = 0, | 253 | .flags = 0, |
| 234 | .len = 1, | 254 | .len = 1, |
| 235 | .buf = out_buf, | 255 | .buf = out_buf, |
| 236 | }, | 256 | }, |
| 237 | { | 257 | { |
| 238 | .addr = sdvo_priv->slave_addr >> 1, | 258 | .addr = intel_sdvo->slave_addr >> 1, |
| 239 | .flags = I2C_M_RD, | 259 | .flags = I2C_M_RD, |
| 240 | .len = 1, | 260 | .len = 1, |
| 241 | .buf = buf, | 261 | .buf = buf, |
| 242 | } | 262 | } |
| 243 | }; | 263 | }; |
| 264 | int ret; | ||
| 244 | 265 | ||
| 245 | out_buf[0] = addr; | 266 | if ((ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 2)) == 2) |
| 246 | out_buf[1] = 0; | ||
| 247 | |||
| 248 | if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2) | ||
| 249 | { | 267 | { |
| 250 | *ch = buf[0]; | 268 | *ch = buf[0]; |
| 251 | return true; | 269 | return true; |
| @@ -255,35 +273,26 @@ static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr, | |||
| 255 | return false; | 273 | return false; |
| 256 | } | 274 | } |
| 257 | 275 | ||
| 258 | static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr, | 276 | static bool intel_sdvo_write_byte(struct intel_sdvo *intel_sdvo, int addr, u8 ch) |
| 259 | u8 ch) | ||
| 260 | { | 277 | { |
| 261 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 278 | u8 out_buf[2] = { addr, ch }; |
| 262 | u8 out_buf[2]; | ||
| 263 | struct i2c_msg msgs[] = { | 279 | struct i2c_msg msgs[] = { |
| 264 | { | 280 | { |
| 265 | .addr = sdvo_priv->slave_addr >> 1, | 281 | .addr = intel_sdvo->slave_addr >> 1, |
| 266 | .flags = 0, | 282 | .flags = 0, |
| 267 | .len = 2, | 283 | .len = 2, |
| 268 | .buf = out_buf, | 284 | .buf = out_buf, |
| 269 | } | 285 | } |
| 270 | }; | 286 | }; |
| 271 | 287 | ||
| 272 | out_buf[0] = addr; | 288 | return i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 1) == 1; |
| 273 | out_buf[1] = ch; | ||
| 274 | |||
| 275 | if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1) | ||
| 276 | { | ||
| 277 | return true; | ||
| 278 | } | ||
| 279 | return false; | ||
| 280 | } | 289 | } |
| 281 | 290 | ||
| 282 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} | 291 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} |
| 283 | /** Mapping of command numbers to names, for debug output */ | 292 | /** Mapping of command numbers to names, for debug output */ |
| 284 | static const struct _sdvo_cmd_name { | 293 | static const struct _sdvo_cmd_name { |
| 285 | u8 cmd; | 294 | u8 cmd; |
| 286 | char *name; | 295 | const char *name; |
| 287 | } sdvo_cmd_names[] = { | 296 | } sdvo_cmd_names[] = { |
| 288 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), | 297 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), |
| 289 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), | 298 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), |
| @@ -328,13 +337,14 @@ static const struct _sdvo_cmd_name { | |||
| 328 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), | 337 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), |
| 329 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), | 338 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), |
| 330 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), | 339 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), |
| 340 | |||
| 331 | /* Add the op code for SDVO enhancements */ | 341 | /* Add the op code for SDVO enhancements */ |
| 332 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_H), | 342 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HPOS), |
| 333 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_H), | 343 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HPOS), |
| 334 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_H), | 344 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HPOS), |
| 335 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_V), | 345 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_VPOS), |
| 336 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_V), | 346 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_VPOS), |
| 337 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_V), | 347 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_VPOS), |
| 338 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), | 348 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), |
| 339 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), | 349 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), |
| 340 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), | 350 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), |
| @@ -353,6 +363,27 @@ static const struct _sdvo_cmd_name { | |||
| 353 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), | 363 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), |
| 354 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), | 364 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), |
| 355 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), | 365 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), |
| 366 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER), | ||
| 367 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER), | ||
| 368 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER), | ||
| 369 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE), | ||
| 370 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE), | ||
| 371 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE), | ||
| 372 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_2D), | ||
| 373 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_2D), | ||
| 374 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_2D), | ||
| 375 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SHARPNESS), | ||
| 376 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SHARPNESS), | ||
| 377 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SHARPNESS), | ||
| 378 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DOT_CRAWL), | ||
| 379 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DOT_CRAWL), | ||
| 380 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_CHROMA_FILTER), | ||
| 381 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_CHROMA_FILTER), | ||
| 382 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_CHROMA_FILTER), | ||
| 383 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_LUMA_FILTER), | ||
| 384 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_LUMA_FILTER), | ||
| 385 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_LUMA_FILTER), | ||
| 386 | |||
| 356 | /* HDMI op code */ | 387 | /* HDMI op code */ |
| 357 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), | 388 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), |
| 358 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), | 389 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), |
| @@ -377,17 +408,15 @@ static const struct _sdvo_cmd_name { | |||
| 377 | }; | 408 | }; |
| 378 | 409 | ||
| 379 | #define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) | 410 | #define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) |
| 380 | #define SDVO_NAME(dev_priv) (IS_SDVOB((dev_priv)->sdvo_reg) ? "SDVOB" : "SDVOC") | 411 | #define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC") |
| 381 | #define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) | ||
| 382 | 412 | ||
| 383 | static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, | 413 | static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, |
| 384 | void *args, int args_len) | 414 | const void *args, int args_len) |
| 385 | { | 415 | { |
| 386 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 387 | int i; | 416 | int i; |
| 388 | 417 | ||
| 389 | DRM_DEBUG_KMS("%s: W: %02X ", | 418 | DRM_DEBUG_KMS("%s: W: %02X ", |
| 390 | SDVO_NAME(sdvo_priv), cmd); | 419 | SDVO_NAME(intel_sdvo), cmd); |
| 391 | for (i = 0; i < args_len; i++) | 420 | for (i = 0; i < args_len; i++) |
| 392 | DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); | 421 | DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); |
| 393 | for (; i < 8; i++) | 422 | for (; i < 8; i++) |
| @@ -403,19 +432,20 @@ static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, | |||
| 403 | DRM_LOG_KMS("\n"); | 432 | DRM_LOG_KMS("\n"); |
| 404 | } | 433 | } |
| 405 | 434 | ||
| 406 | static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd, | 435 | static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, |
| 407 | void *args, int args_len) | 436 | const void *args, int args_len) |
| 408 | { | 437 | { |
| 409 | int i; | 438 | int i; |
| 410 | 439 | ||
| 411 | intel_sdvo_debug_write(intel_encoder, cmd, args, args_len); | 440 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); |
| 412 | 441 | ||
| 413 | for (i = 0; i < args_len; i++) { | 442 | for (i = 0; i < args_len; i++) { |
| 414 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i, | 443 | if (!intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0 - i, |
| 415 | ((u8*)args)[i]); | 444 | ((u8*)args)[i])) |
| 445 | return false; | ||
| 416 | } | 446 | } |
| 417 | 447 | ||
| 418 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd); | 448 | return intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_OPCODE, cmd); |
| 419 | } | 449 | } |
| 420 | 450 | ||
| 421 | static const char *cmd_status_names[] = { | 451 | static const char *cmd_status_names[] = { |
| @@ -428,14 +458,13 @@ static const char *cmd_status_names[] = { | |||
| 428 | "Scaling not supported" | 458 | "Scaling not supported" |
| 429 | }; | 459 | }; |
| 430 | 460 | ||
| 431 | static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder, | 461 | static void intel_sdvo_debug_response(struct intel_sdvo *intel_sdvo, |
| 432 | void *response, int response_len, | 462 | void *response, int response_len, |
| 433 | u8 status) | 463 | u8 status) |
| 434 | { | 464 | { |
| 435 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 436 | int i; | 465 | int i; |
| 437 | 466 | ||
| 438 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv)); | 467 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo)); |
| 439 | for (i = 0; i < response_len; i++) | 468 | for (i = 0; i < response_len; i++) |
| 440 | DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); | 469 | DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); |
| 441 | for (; i < 8; i++) | 470 | for (; i < 8; i++) |
| @@ -447,8 +476,8 @@ static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder, | |||
| 447 | DRM_LOG_KMS("\n"); | 476 | DRM_LOG_KMS("\n"); |
| 448 | } | 477 | } |
| 449 | 478 | ||
| 450 | static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder, | 479 | static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, |
| 451 | void *response, int response_len) | 480 | void *response, int response_len) |
| 452 | { | 481 | { |
| 453 | int i; | 482 | int i; |
| 454 | u8 status; | 483 | u8 status; |
| @@ -457,24 +486,26 @@ static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder, | |||
| 457 | while (retry--) { | 486 | while (retry--) { |
| 458 | /* Read the command response */ | 487 | /* Read the command response */ |
| 459 | for (i = 0; i < response_len; i++) { | 488 | for (i = 0; i < response_len; i++) { |
| 460 | intel_sdvo_read_byte(intel_encoder, | 489 | if (!intel_sdvo_read_byte(intel_sdvo, |
| 461 | SDVO_I2C_RETURN_0 + i, | 490 | SDVO_I2C_RETURN_0 + i, |
| 462 | &((u8 *)response)[i]); | 491 | &((u8 *)response)[i])) |
| 492 | return false; | ||
| 463 | } | 493 | } |
| 464 | 494 | ||
| 465 | /* read the return status */ | 495 | /* read the return status */ |
| 466 | intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS, | 496 | if (!intel_sdvo_read_byte(intel_sdvo, SDVO_I2C_CMD_STATUS, |
| 467 | &status); | 497 | &status)) |
| 498 | return false; | ||
| 468 | 499 | ||
| 469 | intel_sdvo_debug_response(intel_encoder, response, response_len, | 500 | intel_sdvo_debug_response(intel_sdvo, response, response_len, |
| 470 | status); | 501 | status); |
| 471 | if (status != SDVO_CMD_STATUS_PENDING) | 502 | if (status != SDVO_CMD_STATUS_PENDING) |
| 472 | return status; | 503 | break; |
| 473 | 504 | ||
| 474 | mdelay(50); | 505 | mdelay(50); |
| 475 | } | 506 | } |
| 476 | 507 | ||
| 477 | return status; | 508 | return status == SDVO_CMD_STATUS_SUCCESS; |
| 478 | } | 509 | } |
| 479 | 510 | ||
| 480 | static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | 511 | static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) |
| @@ -494,37 +525,36 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | |||
| 494 | * another I2C transaction after issuing the DDC bus switch, it will be | 525 | * another I2C transaction after issuing the DDC bus switch, it will be |
| 495 | * switched to the internal SDVO register. | 526 | * switched to the internal SDVO register. |
| 496 | */ | 527 | */ |
| 497 | static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder, | 528 | static void intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, |
| 498 | u8 target) | 529 | u8 target) |
| 499 | { | 530 | { |
| 500 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 501 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; | 531 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; |
| 502 | struct i2c_msg msgs[] = { | 532 | struct i2c_msg msgs[] = { |
| 503 | { | 533 | { |
| 504 | .addr = sdvo_priv->slave_addr >> 1, | 534 | .addr = intel_sdvo->slave_addr >> 1, |
| 505 | .flags = 0, | 535 | .flags = 0, |
| 506 | .len = 2, | 536 | .len = 2, |
| 507 | .buf = out_buf, | 537 | .buf = out_buf, |
| 508 | }, | 538 | }, |
| 509 | /* the following two are to read the response */ | 539 | /* the following two are to read the response */ |
| 510 | { | 540 | { |
| 511 | .addr = sdvo_priv->slave_addr >> 1, | 541 | .addr = intel_sdvo->slave_addr >> 1, |
| 512 | .flags = 0, | 542 | .flags = 0, |
| 513 | .len = 1, | 543 | .len = 1, |
| 514 | .buf = cmd_buf, | 544 | .buf = cmd_buf, |
| 515 | }, | 545 | }, |
| 516 | { | 546 | { |
| 517 | .addr = sdvo_priv->slave_addr >> 1, | 547 | .addr = intel_sdvo->slave_addr >> 1, |
| 518 | .flags = I2C_M_RD, | 548 | .flags = I2C_M_RD, |
| 519 | .len = 1, | 549 | .len = 1, |
| 520 | .buf = ret_value, | 550 | .buf = ret_value, |
| 521 | }, | 551 | }, |
| 522 | }; | 552 | }; |
| 523 | 553 | ||
| 524 | intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH, | 554 | intel_sdvo_debug_write(intel_sdvo, SDVO_CMD_SET_CONTROL_BUS_SWITCH, |
| 525 | &target, 1); | 555 | &target, 1); |
| 526 | /* write the DDC switch command argument */ | 556 | /* write the DDC switch command argument */ |
| 527 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target); | 557 | intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0, target); |
| 528 | 558 | ||
| 529 | out_buf[0] = SDVO_I2C_OPCODE; | 559 | out_buf[0] = SDVO_I2C_OPCODE; |
| 530 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; | 560 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; |
| @@ -533,7 +563,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encode | |||
| 533 | ret_value[0] = 0; | 563 | ret_value[0] = 0; |
| 534 | ret_value[1] = 0; | 564 | ret_value[1] = 0; |
| 535 | 565 | ||
| 536 | ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3); | 566 | ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 3); |
| 537 | if (ret != 3) { | 567 | if (ret != 3) { |
| 538 | /* failure in I2C transfer */ | 568 | /* failure in I2C transfer */ |
| 539 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); | 569 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); |
| @@ -547,23 +577,29 @@ static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encode | |||
| 547 | return; | 577 | return; |
| 548 | } | 578 | } |
| 549 | 579 | ||
| 550 | static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1) | 580 | static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len) |
| 551 | { | 581 | { |
| 552 | struct intel_sdvo_set_target_input_args targets = {0}; | 582 | if (!intel_sdvo_write_cmd(intel_sdvo, cmd, data, len)) |
| 553 | u8 status; | 583 | return false; |
| 554 | |||
| 555 | if (target_0 && target_1) | ||
| 556 | return SDVO_CMD_STATUS_NOTSUPP; | ||
| 557 | 584 | ||
| 558 | if (target_1) | 585 | return intel_sdvo_read_response(intel_sdvo, NULL, 0); |
| 559 | targets.target_1 = 1; | 586 | } |
| 560 | 587 | ||
| 561 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets, | 588 | static bool |
| 562 | sizeof(targets)); | 589 | intel_sdvo_get_value(struct intel_sdvo *intel_sdvo, u8 cmd, void *value, int len) |
| 590 | { | ||
| 591 | if (!intel_sdvo_write_cmd(intel_sdvo, cmd, NULL, 0)) | ||
| 592 | return false; | ||
| 563 | 593 | ||
| 564 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | 594 | return intel_sdvo_read_response(intel_sdvo, value, len); |
| 595 | } | ||
| 565 | 596 | ||
| 566 | return (status == SDVO_CMD_STATUS_SUCCESS); | 597 | static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo) |
| 598 | { | ||
| 599 | struct intel_sdvo_set_target_input_args targets = {0}; | ||
| 600 | return intel_sdvo_set_value(intel_sdvo, | ||
| 601 | SDVO_CMD_SET_TARGET_INPUT, | ||
| 602 | &targets, sizeof(targets)); | ||
| 567 | } | 603 | } |
| 568 | 604 | ||
| 569 | /** | 605 | /** |
| @@ -572,14 +608,12 @@ static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, boo | |||
| 572 | * This function is making an assumption about the layout of the response, | 608 | * This function is making an assumption about the layout of the response, |
| 573 | * which should be checked against the docs. | 609 | * which should be checked against the docs. |
| 574 | */ | 610 | */ |
| 575 | static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2) | 611 | static bool intel_sdvo_get_trained_inputs(struct intel_sdvo *intel_sdvo, bool *input_1, bool *input_2) |
| 576 | { | 612 | { |
| 577 | struct intel_sdvo_get_trained_inputs_response response; | 613 | struct intel_sdvo_get_trained_inputs_response response; |
| 578 | u8 status; | ||
| 579 | 614 | ||
| 580 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); | 615 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS, |
| 581 | status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response)); | 616 | &response, sizeof(response))) |
| 582 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 583 | return false; | 617 | return false; |
| 584 | 618 | ||
| 585 | *input_1 = response.input0_trained; | 619 | *input_1 = response.input0_trained; |
| @@ -587,21 +621,18 @@ static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, b | |||
| 587 | return true; | 621 | return true; |
| 588 | } | 622 | } |
| 589 | 623 | ||
| 590 | static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder, | 624 | static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo, |
| 591 | u16 outputs) | 625 | u16 outputs) |
| 592 | { | 626 | { |
| 593 | u8 status; | 627 | return intel_sdvo_set_value(intel_sdvo, |
| 594 | 628 | SDVO_CMD_SET_ACTIVE_OUTPUTS, | |
| 595 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, | 629 | &outputs, sizeof(outputs)); |
| 596 | sizeof(outputs)); | ||
| 597 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 598 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
| 599 | } | 630 | } |
| 600 | 631 | ||
| 601 | static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder, | 632 | static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, |
| 602 | int mode) | 633 | int mode) |
| 603 | { | 634 | { |
| 604 | u8 status, state = SDVO_ENCODER_STATE_ON; | 635 | u8 state = SDVO_ENCODER_STATE_ON; |
| 605 | 636 | ||
| 606 | switch (mode) { | 637 | switch (mode) { |
| 607 | case DRM_MODE_DPMS_ON: | 638 | case DRM_MODE_DPMS_ON: |
| @@ -618,88 +649,63 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encod | |||
| 618 | break; | 649 | break; |
| 619 | } | 650 | } |
| 620 | 651 | ||
| 621 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, | 652 | return intel_sdvo_set_value(intel_sdvo, |
| 622 | sizeof(state)); | 653 | SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state)); |
| 623 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 624 | |||
| 625 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
| 626 | } | 654 | } |
| 627 | 655 | ||
| 628 | static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder, | 656 | static bool intel_sdvo_get_input_pixel_clock_range(struct intel_sdvo *intel_sdvo, |
| 629 | int *clock_min, | 657 | int *clock_min, |
| 630 | int *clock_max) | 658 | int *clock_max) |
| 631 | { | 659 | { |
| 632 | struct intel_sdvo_pixel_clock_range clocks; | 660 | struct intel_sdvo_pixel_clock_range clocks; |
| 633 | u8 status; | ||
| 634 | |||
| 635 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, | ||
| 636 | NULL, 0); | ||
| 637 | |||
| 638 | status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks)); | ||
| 639 | 661 | ||
| 640 | if (status != SDVO_CMD_STATUS_SUCCESS) | 662 | if (!intel_sdvo_get_value(intel_sdvo, |
| 663 | SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, | ||
| 664 | &clocks, sizeof(clocks))) | ||
| 641 | return false; | 665 | return false; |
| 642 | 666 | ||
| 643 | /* Convert the values from units of 10 kHz to kHz. */ | 667 | /* Convert the values from units of 10 kHz to kHz. */ |
| 644 | *clock_min = clocks.min * 10; | 668 | *clock_min = clocks.min * 10; |
| 645 | *clock_max = clocks.max * 10; | 669 | *clock_max = clocks.max * 10; |
| 646 | |||
| 647 | return true; | 670 | return true; |
| 648 | } | 671 | } |
| 649 | 672 | ||
| 650 | static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder, | 673 | static bool intel_sdvo_set_target_output(struct intel_sdvo *intel_sdvo, |
| 651 | u16 outputs) | 674 | u16 outputs) |
| 652 | { | 675 | { |
| 653 | u8 status; | 676 | return intel_sdvo_set_value(intel_sdvo, |
| 654 | 677 | SDVO_CMD_SET_TARGET_OUTPUT, | |
| 655 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs, | 678 | &outputs, sizeof(outputs)); |
| 656 | sizeof(outputs)); | ||
| 657 | |||
| 658 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 659 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
| 660 | } | 679 | } |
| 661 | 680 | ||
| 662 | static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd, | 681 | static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd, |
| 663 | struct intel_sdvo_dtd *dtd) | 682 | struct intel_sdvo_dtd *dtd) |
| 664 | { | 683 | { |
| 665 | u8 status; | 684 | return intel_sdvo_set_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) && |
| 666 | 685 | intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); | |
| 667 | intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1)); | ||
| 668 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 669 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 670 | return false; | ||
| 671 | |||
| 672 | intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2)); | ||
| 673 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 674 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 675 | return false; | ||
| 676 | |||
| 677 | return true; | ||
| 678 | } | 686 | } |
| 679 | 687 | ||
| 680 | static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder, | 688 | static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, |
| 681 | struct intel_sdvo_dtd *dtd) | 689 | struct intel_sdvo_dtd *dtd) |
| 682 | { | 690 | { |
| 683 | return intel_sdvo_set_timing(intel_encoder, | 691 | return intel_sdvo_set_timing(intel_sdvo, |
| 684 | SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); | 692 | SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); |
| 685 | } | 693 | } |
| 686 | 694 | ||
| 687 | static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder, | 695 | static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo, |
| 688 | struct intel_sdvo_dtd *dtd) | 696 | struct intel_sdvo_dtd *dtd) |
| 689 | { | 697 | { |
| 690 | return intel_sdvo_set_timing(intel_encoder, | 698 | return intel_sdvo_set_timing(intel_sdvo, |
| 691 | SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); | 699 | SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); |
| 692 | } | 700 | } |
| 693 | 701 | ||
| 694 | static bool | 702 | static bool |
| 695 | intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder, | 703 | intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, |
| 696 | uint16_t clock, | 704 | uint16_t clock, |
| 697 | uint16_t width, | 705 | uint16_t width, |
| 698 | uint16_t height) | 706 | uint16_t height) |
| 699 | { | 707 | { |
| 700 | struct intel_sdvo_preferred_input_timing_args args; | 708 | struct intel_sdvo_preferred_input_timing_args args; |
| 701 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 702 | uint8_t status; | ||
| 703 | 709 | ||
| 704 | memset(&args, 0, sizeof(args)); | 710 | memset(&args, 0, sizeof(args)); |
| 705 | args.clock = clock; | 711 | args.clock = clock; |
| @@ -707,59 +713,32 @@ intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder, | |||
| 707 | args.height = height; | 713 | args.height = height; |
| 708 | args.interlace = 0; | 714 | args.interlace = 0; |
| 709 | 715 | ||
| 710 | if (sdvo_priv->is_lvds && | 716 | if (intel_sdvo->is_lvds && |
| 711 | (sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width || | 717 | (intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width || |
| 712 | sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) | 718 | intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height)) |
| 713 | args.scaled = 1; | 719 | args.scaled = 1; |
| 714 | 720 | ||
| 715 | intel_sdvo_write_cmd(intel_encoder, | 721 | return intel_sdvo_set_value(intel_sdvo, |
| 716 | SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, | 722 | SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, |
| 717 | &args, sizeof(args)); | 723 | &args, sizeof(args)); |
| 718 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 719 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 720 | return false; | ||
| 721 | |||
| 722 | return true; | ||
| 723 | } | 724 | } |
| 724 | 725 | ||
| 725 | static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder, | 726 | static bool intel_sdvo_get_preferred_input_timing(struct intel_sdvo *intel_sdvo, |
| 726 | struct intel_sdvo_dtd *dtd) | 727 | struct intel_sdvo_dtd *dtd) |
| 727 | { | 728 | { |
| 728 | bool status; | 729 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, |
| 729 | 730 | &dtd->part1, sizeof(dtd->part1)) && | |
| 730 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, | 731 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, |
| 731 | NULL, 0); | 732 | &dtd->part2, sizeof(dtd->part2)); |
| 732 | |||
| 733 | status = intel_sdvo_read_response(intel_encoder, &dtd->part1, | ||
| 734 | sizeof(dtd->part1)); | ||
| 735 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 736 | return false; | ||
| 737 | |||
| 738 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, | ||
| 739 | NULL, 0); | ||
| 740 | |||
| 741 | status = intel_sdvo_read_response(intel_encoder, &dtd->part2, | ||
| 742 | sizeof(dtd->part2)); | ||
| 743 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 744 | return false; | ||
| 745 | |||
| 746 | return false; | ||
| 747 | } | 733 | } |
| 748 | 734 | ||
| 749 | static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val) | 735 | static bool intel_sdvo_set_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 val) |
| 750 | { | 736 | { |
| 751 | u8 status; | 737 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); |
| 752 | |||
| 753 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); | ||
| 754 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 755 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 756 | return false; | ||
| 757 | |||
| 758 | return true; | ||
| 759 | } | 738 | } |
| 760 | 739 | ||
| 761 | static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | 740 | static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, |
| 762 | struct drm_display_mode *mode) | 741 | const struct drm_display_mode *mode) |
| 763 | { | 742 | { |
| 764 | uint16_t width, height; | 743 | uint16_t width, height; |
| 765 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; | 744 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; |
| @@ -808,7 +787,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | |||
| 808 | } | 787 | } |
| 809 | 788 | ||
| 810 | static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, | 789 | static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, |
| 811 | struct intel_sdvo_dtd *dtd) | 790 | const struct intel_sdvo_dtd *dtd) |
| 812 | { | 791 | { |
| 813 | mode->hdisplay = dtd->part1.h_active; | 792 | mode->hdisplay = dtd->part1.h_active; |
| 814 | mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; | 793 | mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; |
| @@ -840,45 +819,33 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, | |||
| 840 | mode->flags |= DRM_MODE_FLAG_PVSYNC; | 819 | mode->flags |= DRM_MODE_FLAG_PVSYNC; |
| 841 | } | 820 | } |
| 842 | 821 | ||
| 843 | static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder, | 822 | static bool intel_sdvo_get_supp_encode(struct intel_sdvo *intel_sdvo, |
| 844 | struct intel_sdvo_encode *encode) | 823 | struct intel_sdvo_encode *encode) |
| 845 | { | 824 | { |
| 846 | uint8_t status; | 825 | if (intel_sdvo_get_value(intel_sdvo, |
| 847 | 826 | SDVO_CMD_GET_SUPP_ENCODE, | |
| 848 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); | 827 | encode, sizeof(*encode))) |
| 849 | status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode)); | 828 | return true; |
| 850 | if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */ | ||
| 851 | memset(encode, 0, sizeof(*encode)); | ||
| 852 | return false; | ||
| 853 | } | ||
| 854 | 829 | ||
| 855 | return true; | 830 | /* non-support means DVI */ |
| 831 | memset(encode, 0, sizeof(*encode)); | ||
| 832 | return false; | ||
| 856 | } | 833 | } |
| 857 | 834 | ||
| 858 | static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder, | 835 | static bool intel_sdvo_set_encode(struct intel_sdvo *intel_sdvo, |
| 859 | uint8_t mode) | 836 | uint8_t mode) |
| 860 | { | 837 | { |
| 861 | uint8_t status; | 838 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1); |
| 862 | |||
| 863 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1); | ||
| 864 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 865 | |||
| 866 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
| 867 | } | 839 | } |
| 868 | 840 | ||
| 869 | static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder, | 841 | static bool intel_sdvo_set_colorimetry(struct intel_sdvo *intel_sdvo, |
| 870 | uint8_t mode) | 842 | uint8_t mode) |
| 871 | { | 843 | { |
| 872 | uint8_t status; | 844 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1); |
| 873 | |||
| 874 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1); | ||
| 875 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
| 876 | |||
| 877 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
| 878 | } | 845 | } |
| 879 | 846 | ||
| 880 | #if 0 | 847 | #if 0 |
| 881 | static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) | 848 | static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) |
| 882 | { | 849 | { |
| 883 | int i, j; | 850 | int i, j; |
| 884 | uint8_t set_buf_index[2]; | 851 | uint8_t set_buf_index[2]; |
| @@ -887,8 +854,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) | |||
| 887 | uint8_t buf[48]; | 854 | uint8_t buf[48]; |
| 888 | uint8_t *pos; | 855 | uint8_t *pos; |
| 889 | 856 | ||
| 890 | intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); | 857 | intel_sdvo_get_value(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, &av_split, 1); |
| 891 | intel_sdvo_read_response(encoder, &av_split, 1); | ||
| 892 | 858 | ||
| 893 | for (i = 0; i <= av_split; i++) { | 859 | for (i = 0; i <= av_split; i++) { |
| 894 | set_buf_index[0] = i; set_buf_index[1] = 0; | 860 | set_buf_index[0] = i; set_buf_index[1] = 0; |
| @@ -908,7 +874,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) | |||
| 908 | } | 874 | } |
| 909 | #endif | 875 | #endif |
| 910 | 876 | ||
| 911 | static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder, | 877 | static bool intel_sdvo_set_hdmi_buf(struct intel_sdvo *intel_sdvo, |
| 912 | int index, | 878 | int index, |
| 913 | uint8_t *data, int8_t size, uint8_t tx_rate) | 879 | uint8_t *data, int8_t size, uint8_t tx_rate) |
| 914 | { | 880 | { |
| @@ -917,15 +883,18 @@ static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder, | |||
| 917 | set_buf_index[0] = index; | 883 | set_buf_index[0] = index; |
| 918 | set_buf_index[1] = 0; | 884 | set_buf_index[1] = 0; |
| 919 | 885 | ||
| 920 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX, | 886 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX, |
| 921 | set_buf_index, 2); | 887 | set_buf_index, 2)) |
| 888 | return false; | ||
| 922 | 889 | ||
| 923 | for (; size > 0; size -= 8) { | 890 | for (; size > 0; size -= 8) { |
| 924 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8); | 891 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA, data, 8)) |
| 892 | return false; | ||
| 893 | |||
| 925 | data += 8; | 894 | data += 8; |
| 926 | } | 895 | } |
| 927 | 896 | ||
| 928 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); | 897 | return intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); |
| 929 | } | 898 | } |
| 930 | 899 | ||
| 931 | static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) | 900 | static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) |
| @@ -1000,7 +969,7 @@ struct dip_infoframe { | |||
| 1000 | } __attribute__ ((packed)) u; | 969 | } __attribute__ ((packed)) u; |
| 1001 | } __attribute__((packed)); | 970 | } __attribute__((packed)); |
| 1002 | 971 | ||
| 1003 | static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder, | 972 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, |
| 1004 | struct drm_display_mode * mode) | 973 | struct drm_display_mode * mode) |
| 1005 | { | 974 | { |
| 1006 | struct dip_infoframe avi_if = { | 975 | struct dip_infoframe avi_if = { |
| @@ -1011,133 +980,105 @@ static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder, | |||
| 1011 | 980 | ||
| 1012 | avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, | 981 | avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, |
| 1013 | 4 + avi_if.len); | 982 | 4 + avi_if.len); |
| 1014 | intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if, | 983 | return intel_sdvo_set_hdmi_buf(intel_sdvo, 1, (uint8_t *)&avi_if, |
| 1015 | 4 + avi_if.len, | 984 | 4 + avi_if.len, |
| 1016 | SDVO_HBUF_TX_VSYNC); | 985 | SDVO_HBUF_TX_VSYNC); |
| 1017 | } | 986 | } |
| 1018 | 987 | ||
| 1019 | static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder) | 988 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) |
| 1020 | { | 989 | { |
| 1021 | |||
| 1022 | struct intel_sdvo_tv_format format; | 990 | struct intel_sdvo_tv_format format; |
| 1023 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 991 | uint32_t format_map; |
| 1024 | uint32_t format_map, i; | ||
| 1025 | uint8_t status; | ||
| 1026 | 992 | ||
| 1027 | for (i = 0; i < TV_FORMAT_NUM; i++) | 993 | format_map = 1 << intel_sdvo->tv_format_index; |
| 1028 | if (tv_format_names[i] == sdvo_priv->tv_format_name) | ||
| 1029 | break; | ||
| 1030 | |||
| 1031 | format_map = 1 << i; | ||
| 1032 | memset(&format, 0, sizeof(format)); | 994 | memset(&format, 0, sizeof(format)); |
| 1033 | memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? | 995 | memcpy(&format, &format_map, min(sizeof(format), sizeof(format_map))); |
| 1034 | sizeof(format) : sizeof(format_map)); | ||
| 1035 | |||
| 1036 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format, | ||
| 1037 | sizeof(format)); | ||
| 1038 | 996 | ||
| 1039 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | 997 | BUILD_BUG_ON(sizeof(format) != 6); |
| 1040 | if (status != SDVO_CMD_STATUS_SUCCESS) | 998 | return intel_sdvo_set_value(intel_sdvo, |
| 1041 | DRM_DEBUG_KMS("%s: Failed to set TV format\n", | 999 | SDVO_CMD_SET_TV_FORMAT, |
| 1042 | SDVO_NAME(sdvo_priv)); | 1000 | &format, sizeof(format)); |
| 1043 | } | 1001 | } |
| 1044 | 1002 | ||
| 1045 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | 1003 | static bool |
| 1046 | struct drm_display_mode *mode, | 1004 | intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, |
| 1047 | struct drm_display_mode *adjusted_mode) | 1005 | struct drm_display_mode *mode) |
| 1048 | { | 1006 | { |
| 1049 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1007 | struct intel_sdvo_dtd output_dtd; |
| 1050 | struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv; | ||
| 1051 | 1008 | ||
| 1052 | if (dev_priv->is_tv) { | 1009 | if (!intel_sdvo_set_target_output(intel_sdvo, |
| 1053 | struct intel_sdvo_dtd output_dtd; | 1010 | intel_sdvo->attached_output)) |
| 1054 | bool success; | 1011 | return false; |
| 1055 | 1012 | ||
| 1056 | /* We need to construct preferred input timings based on our | 1013 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
| 1057 | * output timings. To do that, we have to set the output | 1014 | if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd)) |
| 1058 | * timings, even though this isn't really the right place in | 1015 | return false; |
| 1059 | * the sequence to do it. Oh well. | ||
| 1060 | */ | ||
| 1061 | 1016 | ||
| 1017 | return true; | ||
| 1018 | } | ||
| 1062 | 1019 | ||
| 1063 | /* Set output timings */ | 1020 | static bool |
| 1064 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); | 1021 | intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, |
| 1065 | intel_sdvo_set_target_output(intel_encoder, | 1022 | struct drm_display_mode *mode, |
| 1066 | dev_priv->attached_output); | 1023 | struct drm_display_mode *adjusted_mode) |
| 1067 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); | 1024 | { |
| 1025 | struct intel_sdvo_dtd input_dtd; | ||
| 1068 | 1026 | ||
| 1069 | /* Set the input timing to the screen. Assume always input 0. */ | 1027 | /* Reset the input timing to the screen. Assume always input 0. */ |
| 1070 | intel_sdvo_set_target_input(intel_encoder, true, false); | 1028 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
| 1029 | return false; | ||
| 1071 | 1030 | ||
| 1031 | if (!intel_sdvo_create_preferred_input_timing(intel_sdvo, | ||
| 1032 | mode->clock / 10, | ||
| 1033 | mode->hdisplay, | ||
| 1034 | mode->vdisplay)) | ||
| 1035 | return false; | ||
| 1072 | 1036 | ||
| 1073 | success = intel_sdvo_create_preferred_input_timing(intel_encoder, | 1037 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, |
| 1074 | mode->clock / 10, | 1038 | &input_dtd)) |
| 1075 | mode->hdisplay, | 1039 | return false; |
| 1076 | mode->vdisplay); | ||
| 1077 | if (success) { | ||
| 1078 | struct intel_sdvo_dtd input_dtd; | ||
| 1079 | 1040 | ||
| 1080 | intel_sdvo_get_preferred_input_timing(intel_encoder, | 1041 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
| 1081 | &input_dtd); | 1042 | intel_sdvo->sdvo_flags = input_dtd.part2.sdvo_flags; |
| 1082 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
| 1083 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
| 1084 | 1043 | ||
| 1085 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 1044 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
| 1045 | mode->clock = adjusted_mode->clock; | ||
| 1046 | return true; | ||
| 1047 | } | ||
| 1086 | 1048 | ||
| 1087 | mode->clock = adjusted_mode->clock; | 1049 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, |
| 1050 | struct drm_display_mode *mode, | ||
| 1051 | struct drm_display_mode *adjusted_mode) | ||
| 1052 | { | ||
| 1053 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | ||
| 1088 | 1054 | ||
| 1089 | adjusted_mode->clock *= | 1055 | /* We need to construct preferred input timings based on our |
| 1090 | intel_sdvo_get_pixel_multiplier(mode); | 1056 | * output timings. To do that, we have to set the output |
| 1091 | } else { | 1057 | * timings, even though this isn't really the right place in |
| 1058 | * the sequence to do it. Oh well. | ||
| 1059 | */ | ||
| 1060 | if (intel_sdvo->is_tv) { | ||
| 1061 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) | ||
| 1092 | return false; | 1062 | return false; |
| 1093 | } | ||
| 1094 | } else if (dev_priv->is_lvds) { | ||
| 1095 | struct intel_sdvo_dtd output_dtd; | ||
| 1096 | bool success; | ||
| 1097 | |||
| 1098 | drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0); | ||
| 1099 | /* Set output timings */ | ||
| 1100 | intel_sdvo_get_dtd_from_mode(&output_dtd, | ||
| 1101 | dev_priv->sdvo_lvds_fixed_mode); | ||
| 1102 | |||
| 1103 | intel_sdvo_set_target_output(intel_encoder, | ||
| 1104 | dev_priv->attached_output); | ||
| 1105 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); | ||
| 1106 | |||
| 1107 | /* Set the input timing to the screen. Assume always input 0. */ | ||
| 1108 | intel_sdvo_set_target_input(intel_encoder, true, false); | ||
| 1109 | |||
| 1110 | |||
| 1111 | success = intel_sdvo_create_preferred_input_timing( | ||
| 1112 | intel_encoder, | ||
| 1113 | mode->clock / 10, | ||
| 1114 | mode->hdisplay, | ||
| 1115 | mode->vdisplay); | ||
| 1116 | 1063 | ||
| 1117 | if (success) { | 1064 | if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode)) |
| 1118 | struct intel_sdvo_dtd input_dtd; | 1065 | return false; |
| 1119 | 1066 | } else if (intel_sdvo->is_lvds) { | |
| 1120 | intel_sdvo_get_preferred_input_timing(intel_encoder, | 1067 | drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0); |
| 1121 | &input_dtd); | ||
| 1122 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
| 1123 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
| 1124 | |||
| 1125 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
| 1126 | |||
| 1127 | mode->clock = adjusted_mode->clock; | ||
| 1128 | 1068 | ||
| 1129 | adjusted_mode->clock *= | 1069 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, |
| 1130 | intel_sdvo_get_pixel_multiplier(mode); | 1070 | intel_sdvo->sdvo_lvds_fixed_mode)) |
| 1131 | } else { | ||
| 1132 | return false; | 1071 | return false; |
| 1133 | } | ||
| 1134 | 1072 | ||
| 1135 | } else { | 1073 | if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode)) |
| 1136 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | 1074 | return false; |
| 1137 | * SDVO device will be told of the multiplier during mode_set. | ||
| 1138 | */ | ||
| 1139 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
| 1140 | } | 1075 | } |
| 1076 | |||
| 1077 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
| 1078 | * SDVO device will be told of the multiplier during mode_set. | ||
| 1079 | */ | ||
| 1080 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
| 1081 | |||
| 1141 | return true; | 1082 | return true; |
| 1142 | } | 1083 | } |
| 1143 | 1084 | ||
| @@ -1149,13 +1090,11 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1149 | struct drm_i915_private *dev_priv = dev->dev_private; | 1090 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1150 | struct drm_crtc *crtc = encoder->crtc; | 1091 | struct drm_crtc *crtc = encoder->crtc; |
| 1151 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1092 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 1152 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1093 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1153 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1154 | u32 sdvox = 0; | 1094 | u32 sdvox = 0; |
| 1155 | int sdvo_pixel_multiply; | 1095 | int sdvo_pixel_multiply, rate; |
| 1156 | struct intel_sdvo_in_out_map in_out; | 1096 | struct intel_sdvo_in_out_map in_out; |
| 1157 | struct intel_sdvo_dtd input_dtd; | 1097 | struct intel_sdvo_dtd input_dtd; |
| 1158 | u8 status; | ||
| 1159 | 1098 | ||
| 1160 | if (!mode) | 1099 | if (!mode) |
| 1161 | return; | 1100 | return; |
| @@ -1166,41 +1105,50 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1166 | * channel on the motherboard. In a two-input device, the first input | 1105 | * channel on the motherboard. In a two-input device, the first input |
| 1167 | * will be SDVOB and the second SDVOC. | 1106 | * will be SDVOB and the second SDVOC. |
| 1168 | */ | 1107 | */ |
| 1169 | in_out.in0 = sdvo_priv->attached_output; | 1108 | in_out.in0 = intel_sdvo->attached_output; |
| 1170 | in_out.in1 = 0; | 1109 | in_out.in1 = 0; |
| 1171 | 1110 | ||
| 1172 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP, | 1111 | if (!intel_sdvo_set_value(intel_sdvo, |
| 1173 | &in_out, sizeof(in_out)); | 1112 | SDVO_CMD_SET_IN_OUT_MAP, |
| 1174 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | 1113 | &in_out, sizeof(in_out))) |
| 1114 | return; | ||
| 1115 | |||
| 1116 | if (intel_sdvo->is_hdmi) { | ||
| 1117 | if (!intel_sdvo_set_avi_infoframe(intel_sdvo, mode)) | ||
| 1118 | return; | ||
| 1175 | 1119 | ||
| 1176 | if (sdvo_priv->is_hdmi) { | ||
| 1177 | intel_sdvo_set_avi_infoframe(intel_encoder, mode); | ||
| 1178 | sdvox |= SDVO_AUDIO_ENABLE; | 1120 | sdvox |= SDVO_AUDIO_ENABLE; |
| 1179 | } | 1121 | } |
| 1180 | 1122 | ||
| 1181 | /* We have tried to get input timing in mode_fixup, and filled into | 1123 | /* We have tried to get input timing in mode_fixup, and filled into |
| 1182 | adjusted_mode */ | 1124 | adjusted_mode */ |
| 1183 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { | 1125 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { |
| 1184 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1126 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
| 1185 | input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags; | 1127 | input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags; |
| 1186 | } else | 1128 | } else |
| 1187 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); | 1129 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); |
| 1188 | 1130 | ||
| 1189 | /* If it's a TV, we already set the output timing in mode_fixup. | 1131 | /* If it's a TV, we already set the output timing in mode_fixup. |
| 1190 | * Otherwise, the output timing is equal to the input timing. | 1132 | * Otherwise, the output timing is equal to the input timing. |
| 1191 | */ | 1133 | */ |
| 1192 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { | 1134 | if (!intel_sdvo->is_tv && !intel_sdvo->is_lvds) { |
| 1193 | /* Set the output timing to the screen */ | 1135 | /* Set the output timing to the screen */ |
| 1194 | intel_sdvo_set_target_output(intel_encoder, | 1136 | if (!intel_sdvo_set_target_output(intel_sdvo, |
| 1195 | sdvo_priv->attached_output); | 1137 | intel_sdvo->attached_output)) |
| 1196 | intel_sdvo_set_output_timing(intel_encoder, &input_dtd); | 1138 | return; |
| 1139 | |||
| 1140 | if (!intel_sdvo_set_output_timing(intel_sdvo, &input_dtd)) | ||
| 1141 | return; | ||
| 1197 | } | 1142 | } |
| 1198 | 1143 | ||
| 1199 | /* Set the input timing to the screen. Assume always input 0. */ | 1144 | /* Set the input timing to the screen. Assume always input 0. */ |
| 1200 | intel_sdvo_set_target_input(intel_encoder, true, false); | 1145 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
| 1146 | return; | ||
| 1201 | 1147 | ||
| 1202 | if (sdvo_priv->is_tv) | 1148 | if (intel_sdvo->is_tv) { |
| 1203 | intel_sdvo_set_tv_format(intel_encoder); | 1149 | if (!intel_sdvo_set_tv_format(intel_sdvo)) |
| 1150 | return; | ||
| 1151 | } | ||
| 1204 | 1152 | ||
| 1205 | /* We would like to use intel_sdvo_create_preferred_input_timing() to | 1153 | /* We would like to use intel_sdvo_create_preferred_input_timing() to |
| 1206 | * provide the device with a timing it can support, if it supports that | 1154 | * provide the device with a timing it can support, if it supports that |
| @@ -1217,23 +1165,18 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1217 | intel_sdvo_set_input_timing(encoder, &input_dtd); | 1165 | intel_sdvo_set_input_timing(encoder, &input_dtd); |
| 1218 | } | 1166 | } |
| 1219 | #else | 1167 | #else |
| 1220 | intel_sdvo_set_input_timing(intel_encoder, &input_dtd); | 1168 | if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) |
| 1169 | return; | ||
| 1221 | #endif | 1170 | #endif |
| 1222 | 1171 | ||
| 1223 | switch (intel_sdvo_get_pixel_multiplier(mode)) { | 1172 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); |
| 1224 | case 1: | 1173 | switch (sdvo_pixel_multiply) { |
| 1225 | intel_sdvo_set_clock_rate_mult(intel_encoder, | 1174 | case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; |
| 1226 | SDVO_CLOCK_RATE_MULT_1X); | 1175 | case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; |
| 1227 | break; | 1176 | case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; |
| 1228 | case 2: | ||
| 1229 | intel_sdvo_set_clock_rate_mult(intel_encoder, | ||
| 1230 | SDVO_CLOCK_RATE_MULT_2X); | ||
| 1231 | break; | ||
| 1232 | case 4: | ||
| 1233 | intel_sdvo_set_clock_rate_mult(intel_encoder, | ||
| 1234 | SDVO_CLOCK_RATE_MULT_4X); | ||
| 1235 | break; | ||
| 1236 | } | 1177 | } |
| 1178 | if (!intel_sdvo_set_clock_rate_mult(intel_sdvo, rate)) | ||
| 1179 | return; | ||
| 1237 | 1180 | ||
| 1238 | /* Set the SDVO control regs. */ | 1181 | /* Set the SDVO control regs. */ |
| 1239 | if (IS_I965G(dev)) { | 1182 | if (IS_I965G(dev)) { |
| @@ -1243,8 +1186,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1243 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 1186 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
| 1244 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; | 1187 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; |
| 1245 | } else { | 1188 | } else { |
| 1246 | sdvox |= I915_READ(sdvo_priv->sdvo_reg); | 1189 | sdvox |= I915_READ(intel_sdvo->sdvo_reg); |
| 1247 | switch (sdvo_priv->sdvo_reg) { | 1190 | switch (intel_sdvo->sdvo_reg) { |
| 1248 | case SDVOB: | 1191 | case SDVOB: |
| 1249 | sdvox &= SDVOB_PRESERVE_MASK; | 1192 | sdvox &= SDVOB_PRESERVE_MASK; |
| 1250 | break; | 1193 | break; |
| @@ -1257,7 +1200,6 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1257 | if (intel_crtc->pipe == 1) | 1200 | if (intel_crtc->pipe == 1) |
| 1258 | sdvox |= SDVO_PIPE_B_SELECT; | 1201 | sdvox |= SDVO_PIPE_B_SELECT; |
| 1259 | 1202 | ||
| 1260 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); | ||
| 1261 | if (IS_I965G(dev)) { | 1203 | if (IS_I965G(dev)) { |
| 1262 | /* done in crtc_mode_set as the dpll_md reg must be written early */ | 1204 | /* done in crtc_mode_set as the dpll_md reg must be written early */ |
| 1263 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { | 1205 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { |
| @@ -1266,28 +1208,28 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1266 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; | 1208 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; |
| 1267 | } | 1209 | } |
| 1268 | 1210 | ||
| 1269 | if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) | 1211 | if (intel_sdvo->sdvo_flags & SDVO_NEED_TO_STALL) |
| 1270 | sdvox |= SDVO_STALL_SELECT; | 1212 | sdvox |= SDVO_STALL_SELECT; |
| 1271 | intel_sdvo_write_sdvox(intel_encoder, sdvox); | 1213 | intel_sdvo_write_sdvox(intel_sdvo, sdvox); |
| 1272 | } | 1214 | } |
| 1273 | 1215 | ||
| 1274 | static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | 1216 | static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) |
| 1275 | { | 1217 | { |
| 1276 | struct drm_device *dev = encoder->dev; | 1218 | struct drm_device *dev = encoder->dev; |
| 1277 | struct drm_i915_private *dev_priv = dev->dev_private; | 1219 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1278 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1220 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1279 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1221 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
| 1280 | u32 temp; | 1222 | u32 temp; |
| 1281 | 1223 | ||
| 1282 | if (mode != DRM_MODE_DPMS_ON) { | 1224 | if (mode != DRM_MODE_DPMS_ON) { |
| 1283 | intel_sdvo_set_active_outputs(intel_encoder, 0); | 1225 | intel_sdvo_set_active_outputs(intel_sdvo, 0); |
| 1284 | if (0) | 1226 | if (0) |
| 1285 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); | 1227 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
| 1286 | 1228 | ||
| 1287 | if (mode == DRM_MODE_DPMS_OFF) { | 1229 | if (mode == DRM_MODE_DPMS_OFF) { |
| 1288 | temp = I915_READ(sdvo_priv->sdvo_reg); | 1230 | temp = I915_READ(intel_sdvo->sdvo_reg); |
| 1289 | if ((temp & SDVO_ENABLE) != 0) { | 1231 | if ((temp & SDVO_ENABLE) != 0) { |
| 1290 | intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE); | 1232 | intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE); |
| 1291 | } | 1233 | } |
| 1292 | } | 1234 | } |
| 1293 | } else { | 1235 | } else { |
| @@ -1295,28 +1237,25 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | |||
| 1295 | int i; | 1237 | int i; |
| 1296 | u8 status; | 1238 | u8 status; |
| 1297 | 1239 | ||
| 1298 | temp = I915_READ(sdvo_priv->sdvo_reg); | 1240 | temp = I915_READ(intel_sdvo->sdvo_reg); |
| 1299 | if ((temp & SDVO_ENABLE) == 0) | 1241 | if ((temp & SDVO_ENABLE) == 0) |
| 1300 | intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE); | 1242 | intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE); |
| 1301 | for (i = 0; i < 2; i++) | 1243 | for (i = 0; i < 2; i++) |
| 1302 | intel_wait_for_vblank(dev); | 1244 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 1303 | |||
| 1304 | status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, | ||
| 1305 | &input2); | ||
| 1306 | |||
| 1307 | 1245 | ||
| 1246 | status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); | ||
| 1308 | /* Warn if the device reported failure to sync. | 1247 | /* Warn if the device reported failure to sync. |
| 1309 | * A lot of SDVO devices fail to notify of sync, but it's | 1248 | * A lot of SDVO devices fail to notify of sync, but it's |
| 1310 | * a given it the status is a success, we succeeded. | 1249 | * a given it the status is a success, we succeeded. |
| 1311 | */ | 1250 | */ |
| 1312 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { | 1251 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { |
| 1313 | DRM_DEBUG_KMS("First %s output reported failure to " | 1252 | DRM_DEBUG_KMS("First %s output reported failure to " |
| 1314 | "sync\n", SDVO_NAME(sdvo_priv)); | 1253 | "sync\n", SDVO_NAME(intel_sdvo)); |
| 1315 | } | 1254 | } |
| 1316 | 1255 | ||
| 1317 | if (0) | 1256 | if (0) |
| 1318 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); | 1257 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
| 1319 | intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->attached_output); | 1258 | intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); |
| 1320 | } | 1259 | } |
| 1321 | return; | 1260 | return; |
| 1322 | } | 1261 | } |
| @@ -1325,42 +1264,31 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, | |||
| 1325 | struct drm_display_mode *mode) | 1264 | struct drm_display_mode *mode) |
| 1326 | { | 1265 | { |
| 1327 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1266 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1328 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1267 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1329 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1330 | 1268 | ||
| 1331 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 1269 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
| 1332 | return MODE_NO_DBLESCAN; | 1270 | return MODE_NO_DBLESCAN; |
| 1333 | 1271 | ||
| 1334 | if (sdvo_priv->pixel_clock_min > mode->clock) | 1272 | if (intel_sdvo->pixel_clock_min > mode->clock) |
| 1335 | return MODE_CLOCK_LOW; | 1273 | return MODE_CLOCK_LOW; |
| 1336 | 1274 | ||
| 1337 | if (sdvo_priv->pixel_clock_max < mode->clock) | 1275 | if (intel_sdvo->pixel_clock_max < mode->clock) |
| 1338 | return MODE_CLOCK_HIGH; | 1276 | return MODE_CLOCK_HIGH; |
| 1339 | 1277 | ||
| 1340 | if (sdvo_priv->is_lvds == true) { | 1278 | if (intel_sdvo->is_lvds) { |
| 1341 | if (sdvo_priv->sdvo_lvds_fixed_mode == NULL) | 1279 | if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay) |
| 1342 | return MODE_PANEL; | 1280 | return MODE_PANEL; |
| 1343 | 1281 | ||
| 1344 | if (mode->hdisplay > sdvo_priv->sdvo_lvds_fixed_mode->hdisplay) | 1282 | if (mode->vdisplay > intel_sdvo->sdvo_lvds_fixed_mode->vdisplay) |
| 1345 | return MODE_PANEL; | ||
| 1346 | |||
| 1347 | if (mode->vdisplay > sdvo_priv->sdvo_lvds_fixed_mode->vdisplay) | ||
| 1348 | return MODE_PANEL; | 1283 | return MODE_PANEL; |
| 1349 | } | 1284 | } |
| 1350 | 1285 | ||
| 1351 | return MODE_OK; | 1286 | return MODE_OK; |
| 1352 | } | 1287 | } |
| 1353 | 1288 | ||
| 1354 | static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps) | 1289 | static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps) |
| 1355 | { | 1290 | { |
| 1356 | u8 status; | 1291 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DEVICE_CAPS, caps, sizeof(*caps)); |
| 1357 | |||
| 1358 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); | ||
| 1359 | status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps)); | ||
| 1360 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 1361 | return false; | ||
| 1362 | |||
| 1363 | return true; | ||
| 1364 | } | 1292 | } |
| 1365 | 1293 | ||
| 1366 | /* No use! */ | 1294 | /* No use! */ |
| @@ -1368,12 +1296,12 @@ static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, str | |||
| 1368 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) | 1296 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) |
| 1369 | { | 1297 | { |
| 1370 | struct drm_connector *connector = NULL; | 1298 | struct drm_connector *connector = NULL; |
| 1371 | struct intel_encoder *iout = NULL; | 1299 | struct intel_sdvo *iout = NULL; |
| 1372 | struct intel_sdvo_priv *sdvo; | 1300 | struct intel_sdvo *sdvo; |
| 1373 | 1301 | ||
| 1374 | /* find the sdvo connector */ | 1302 | /* find the sdvo connector */ |
| 1375 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1303 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 1376 | iout = to_intel_encoder(connector); | 1304 | iout = to_intel_sdvo(connector); |
| 1377 | 1305 | ||
| 1378 | if (iout->type != INTEL_OUTPUT_SDVO) | 1306 | if (iout->type != INTEL_OUTPUT_SDVO) |
| 1379 | continue; | 1307 | continue; |
| @@ -1395,75 +1323,69 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector) | |||
| 1395 | { | 1323 | { |
| 1396 | u8 response[2]; | 1324 | u8 response[2]; |
| 1397 | u8 status; | 1325 | u8 status; |
| 1398 | struct intel_encoder *intel_encoder; | 1326 | struct intel_sdvo *intel_sdvo; |
| 1399 | DRM_DEBUG_KMS("\n"); | 1327 | DRM_DEBUG_KMS("\n"); |
| 1400 | 1328 | ||
| 1401 | if (!connector) | 1329 | if (!connector) |
| 1402 | return 0; | 1330 | return 0; |
| 1403 | 1331 | ||
| 1404 | intel_encoder = to_intel_encoder(connector); | 1332 | intel_sdvo = to_intel_sdvo(connector); |
| 1405 | |||
| 1406 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); | ||
| 1407 | status = intel_sdvo_read_response(intel_encoder, &response, 2); | ||
| 1408 | |||
| 1409 | if (response[0] !=0) | ||
| 1410 | return 1; | ||
| 1411 | 1333 | ||
| 1412 | return 0; | 1334 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, |
| 1335 | &response, 2) && response[0]; | ||
| 1413 | } | 1336 | } |
| 1414 | 1337 | ||
| 1415 | void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) | 1338 | void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) |
| 1416 | { | 1339 | { |
| 1417 | u8 response[2]; | 1340 | u8 response[2]; |
| 1418 | u8 status; | 1341 | u8 status; |
| 1419 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1342 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(connector); |
| 1420 | 1343 | ||
| 1421 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); | 1344 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
| 1422 | intel_sdvo_read_response(intel_encoder, &response, 2); | 1345 | intel_sdvo_read_response(intel_sdvo, &response, 2); |
| 1423 | 1346 | ||
| 1424 | if (on) { | 1347 | if (on) { |
| 1425 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); | 1348 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); |
| 1426 | status = intel_sdvo_read_response(intel_encoder, &response, 2); | 1349 | status = intel_sdvo_read_response(intel_sdvo, &response, 2); |
| 1427 | 1350 | ||
| 1428 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); | 1351 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); |
| 1429 | } else { | 1352 | } else { |
| 1430 | response[0] = 0; | 1353 | response[0] = 0; |
| 1431 | response[1] = 0; | 1354 | response[1] = 0; |
| 1432 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); | 1355 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); |
| 1433 | } | 1356 | } |
| 1434 | 1357 | ||
| 1435 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); | 1358 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
| 1436 | intel_sdvo_read_response(intel_encoder, &response, 2); | 1359 | intel_sdvo_read_response(intel_sdvo, &response, 2); |
| 1437 | } | 1360 | } |
| 1438 | #endif | 1361 | #endif |
| 1439 | 1362 | ||
| 1440 | static bool | 1363 | static bool |
| 1441 | intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder) | 1364 | intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo) |
| 1442 | { | 1365 | { |
| 1443 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1444 | int caps = 0; | 1366 | int caps = 0; |
| 1445 | 1367 | ||
| 1446 | if (sdvo_priv->caps.output_flags & | 1368 | if (intel_sdvo->caps.output_flags & |
| 1447 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | 1369 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) |
| 1448 | caps++; | 1370 | caps++; |
| 1449 | if (sdvo_priv->caps.output_flags & | 1371 | if (intel_sdvo->caps.output_flags & |
| 1450 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) | 1372 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) |
| 1451 | caps++; | 1373 | caps++; |
| 1452 | if (sdvo_priv->caps.output_flags & | 1374 | if (intel_sdvo->caps.output_flags & |
| 1453 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1)) | 1375 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1)) |
| 1454 | caps++; | 1376 | caps++; |
| 1455 | if (sdvo_priv->caps.output_flags & | 1377 | if (intel_sdvo->caps.output_flags & |
| 1456 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) | 1378 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) |
| 1457 | caps++; | 1379 | caps++; |
| 1458 | if (sdvo_priv->caps.output_flags & | 1380 | if (intel_sdvo->caps.output_flags & |
| 1459 | (SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_YPRPB1)) | 1381 | (SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_YPRPB1)) |
| 1460 | caps++; | 1382 | caps++; |
| 1461 | 1383 | ||
| 1462 | if (sdvo_priv->caps.output_flags & | 1384 | if (intel_sdvo->caps.output_flags & |
| 1463 | (SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1)) | 1385 | (SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1)) |
| 1464 | caps++; | 1386 | caps++; |
| 1465 | 1387 | ||
| 1466 | if (sdvo_priv->caps.output_flags & | 1388 | if (intel_sdvo->caps.output_flags & |
| 1467 | (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) | 1389 | (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) |
| 1468 | caps++; | 1390 | caps++; |
| 1469 | 1391 | ||
| @@ -1475,11 +1397,11 @@ intel_find_analog_connector(struct drm_device *dev) | |||
| 1475 | { | 1397 | { |
| 1476 | struct drm_connector *connector; | 1398 | struct drm_connector *connector; |
| 1477 | struct drm_encoder *encoder; | 1399 | struct drm_encoder *encoder; |
| 1478 | struct intel_encoder *intel_encoder; | 1400 | struct intel_sdvo *intel_sdvo; |
| 1479 | 1401 | ||
| 1480 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1402 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| 1481 | intel_encoder = enc_to_intel_encoder(encoder); | 1403 | intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1482 | if (intel_encoder->type == INTEL_OUTPUT_ANALOG) { | 1404 | if (intel_sdvo->base.type == INTEL_OUTPUT_ANALOG) { |
| 1483 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1405 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 1484 | if (encoder == intel_attached_encoder(connector)) | 1406 | if (encoder == intel_attached_encoder(connector)) |
| 1485 | return connector; | 1407 | return connector; |
| @@ -1493,8 +1415,8 @@ static int | |||
| 1493 | intel_analog_is_connected(struct drm_device *dev) | 1415 | intel_analog_is_connected(struct drm_device *dev) |
| 1494 | { | 1416 | { |
| 1495 | struct drm_connector *analog_connector; | 1417 | struct drm_connector *analog_connector; |
| 1496 | analog_connector = intel_find_analog_connector(dev); | ||
| 1497 | 1418 | ||
| 1419 | analog_connector = intel_find_analog_connector(dev); | ||
| 1498 | if (!analog_connector) | 1420 | if (!analog_connector) |
| 1499 | return false; | 1421 | return false; |
| 1500 | 1422 | ||
| @@ -1509,54 +1431,52 @@ enum drm_connector_status | |||
| 1509 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | 1431 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) |
| 1510 | { | 1432 | { |
| 1511 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1433 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1512 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1434 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1513 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1435 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
| 1514 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
| 1515 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
| 1516 | enum drm_connector_status status = connector_status_connected; | 1436 | enum drm_connector_status status = connector_status_connected; |
| 1517 | struct edid *edid = NULL; | 1437 | struct edid *edid = NULL; |
| 1518 | 1438 | ||
| 1519 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); | 1439 | edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus); |
| 1520 | 1440 | ||
| 1521 | /* This is only applied to SDVO cards with multiple outputs */ | 1441 | /* This is only applied to SDVO cards with multiple outputs */ |
| 1522 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { | 1442 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) { |
| 1523 | uint8_t saved_ddc, temp_ddc; | 1443 | uint8_t saved_ddc, temp_ddc; |
| 1524 | saved_ddc = sdvo_priv->ddc_bus; | 1444 | saved_ddc = intel_sdvo->ddc_bus; |
| 1525 | temp_ddc = sdvo_priv->ddc_bus >> 1; | 1445 | temp_ddc = intel_sdvo->ddc_bus >> 1; |
| 1526 | /* | 1446 | /* |
| 1527 | * Don't use the 1 as the argument of DDC bus switch to get | 1447 | * Don't use the 1 as the argument of DDC bus switch to get |
| 1528 | * the EDID. It is used for SDVO SPD ROM. | 1448 | * the EDID. It is used for SDVO SPD ROM. |
| 1529 | */ | 1449 | */ |
| 1530 | while(temp_ddc > 1) { | 1450 | while(temp_ddc > 1) { |
| 1531 | sdvo_priv->ddc_bus = temp_ddc; | 1451 | intel_sdvo->ddc_bus = temp_ddc; |
| 1532 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); | 1452 | edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus); |
| 1533 | if (edid) { | 1453 | if (edid) { |
| 1534 | /* | 1454 | /* |
| 1535 | * When we can get the EDID, maybe it is the | 1455 | * When we can get the EDID, maybe it is the |
| 1536 | * correct DDC bus. Update it. | 1456 | * correct DDC bus. Update it. |
| 1537 | */ | 1457 | */ |
| 1538 | sdvo_priv->ddc_bus = temp_ddc; | 1458 | intel_sdvo->ddc_bus = temp_ddc; |
| 1539 | break; | 1459 | break; |
| 1540 | } | 1460 | } |
| 1541 | temp_ddc >>= 1; | 1461 | temp_ddc >>= 1; |
| 1542 | } | 1462 | } |
| 1543 | if (edid == NULL) | 1463 | if (edid == NULL) |
| 1544 | sdvo_priv->ddc_bus = saved_ddc; | 1464 | intel_sdvo->ddc_bus = saved_ddc; |
| 1545 | } | 1465 | } |
| 1546 | /* when there is no edid and no monitor is connected with VGA | 1466 | /* when there is no edid and no monitor is connected with VGA |
| 1547 | * port, try to use the CRT ddc to read the EDID for DVI-connector | 1467 | * port, try to use the CRT ddc to read the EDID for DVI-connector |
| 1548 | */ | 1468 | */ |
| 1549 | if (edid == NULL && sdvo_priv->analog_ddc_bus && | 1469 | if (edid == NULL && intel_sdvo->analog_ddc_bus && |
| 1550 | !intel_analog_is_connected(connector->dev)) | 1470 | !intel_analog_is_connected(connector->dev)) |
| 1551 | edid = drm_get_edid(connector, sdvo_priv->analog_ddc_bus); | 1471 | edid = drm_get_edid(connector, intel_sdvo->analog_ddc_bus); |
| 1552 | 1472 | ||
| 1553 | if (edid != NULL) { | 1473 | if (edid != NULL) { |
| 1554 | bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); | 1474 | bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); |
| 1555 | bool need_digital = !!(sdvo_connector->output_flag & SDVO_TMDS_MASK); | 1475 | bool need_digital = !!(intel_sdvo_connector->output_flag & SDVO_TMDS_MASK); |
| 1556 | 1476 | ||
| 1557 | /* DDC bus is shared, match EDID to connector type */ | 1477 | /* DDC bus is shared, match EDID to connector type */ |
| 1558 | if (is_digital && need_digital) | 1478 | if (is_digital && need_digital) |
| 1559 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | 1479 | intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid); |
| 1560 | else if (is_digital != need_digital) | 1480 | else if (is_digital != need_digital) |
| 1561 | status = connector_status_disconnected; | 1481 | status = connector_status_disconnected; |
| 1562 | 1482 | ||
| @@ -1572,33 +1492,29 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
| 1572 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) | 1492 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) |
| 1573 | { | 1493 | { |
| 1574 | uint16_t response; | 1494 | uint16_t response; |
| 1575 | u8 status; | ||
| 1576 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1495 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1577 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1496 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1578 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1497 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
| 1579 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1580 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
| 1581 | enum drm_connector_status ret; | 1498 | enum drm_connector_status ret; |
| 1582 | 1499 | ||
| 1583 | intel_sdvo_write_cmd(intel_encoder, | 1500 | if (!intel_sdvo_write_cmd(intel_sdvo, |
| 1584 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | 1501 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) |
| 1585 | if (sdvo_priv->is_tv) { | 1502 | return connector_status_unknown; |
| 1503 | if (intel_sdvo->is_tv) { | ||
| 1586 | /* add 30ms delay when the output type is SDVO-TV */ | 1504 | /* add 30ms delay when the output type is SDVO-TV */ |
| 1587 | mdelay(30); | 1505 | mdelay(30); |
| 1588 | } | 1506 | } |
| 1589 | status = intel_sdvo_read_response(intel_encoder, &response, 2); | 1507 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) |
| 1508 | return connector_status_unknown; | ||
| 1590 | 1509 | ||
| 1591 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); | 1510 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); |
| 1592 | 1511 | ||
| 1593 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 1594 | return connector_status_unknown; | ||
| 1595 | |||
| 1596 | if (response == 0) | 1512 | if (response == 0) |
| 1597 | return connector_status_disconnected; | 1513 | return connector_status_disconnected; |
| 1598 | 1514 | ||
| 1599 | sdvo_priv->attached_output = response; | 1515 | intel_sdvo->attached_output = response; |
| 1600 | 1516 | ||
| 1601 | if ((sdvo_connector->output_flag & response) == 0) | 1517 | if ((intel_sdvo_connector->output_flag & response) == 0) |
| 1602 | ret = connector_status_disconnected; | 1518 | ret = connector_status_disconnected; |
| 1603 | else if (response & SDVO_TMDS_MASK) | 1519 | else if (response & SDVO_TMDS_MASK) |
| 1604 | ret = intel_sdvo_hdmi_sink_detect(connector); | 1520 | ret = intel_sdvo_hdmi_sink_detect(connector); |
| @@ -1607,16 +1523,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
| 1607 | 1523 | ||
| 1608 | /* May update encoder flag for like clock for SDVO TV, etc.*/ | 1524 | /* May update encoder flag for like clock for SDVO TV, etc.*/ |
| 1609 | if (ret == connector_status_connected) { | 1525 | if (ret == connector_status_connected) { |
| 1610 | sdvo_priv->is_tv = false; | 1526 | intel_sdvo->is_tv = false; |
| 1611 | sdvo_priv->is_lvds = false; | 1527 | intel_sdvo->is_lvds = false; |
| 1612 | intel_encoder->needs_tv_clock = false; | 1528 | intel_sdvo->base.needs_tv_clock = false; |
| 1613 | 1529 | ||
| 1614 | if (response & SDVO_TV_MASK) { | 1530 | if (response & SDVO_TV_MASK) { |
| 1615 | sdvo_priv->is_tv = true; | 1531 | intel_sdvo->is_tv = true; |
| 1616 | intel_encoder->needs_tv_clock = true; | 1532 | intel_sdvo->base.needs_tv_clock = true; |
| 1617 | } | 1533 | } |
| 1618 | if (response & SDVO_LVDS_MASK) | 1534 | if (response & SDVO_LVDS_MASK) |
| 1619 | sdvo_priv->is_lvds = true; | 1535 | intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL; |
| 1620 | } | 1536 | } |
| 1621 | 1537 | ||
| 1622 | return ret; | 1538 | return ret; |
| @@ -1625,12 +1541,11 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
| 1625 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1541 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
| 1626 | { | 1542 | { |
| 1627 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1543 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1628 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1544 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1629 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1630 | int num_modes; | 1545 | int num_modes; |
| 1631 | 1546 | ||
| 1632 | /* set the bus switch and get the modes */ | 1547 | /* set the bus switch and get the modes */ |
| 1633 | num_modes = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 1548 | num_modes = intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus); |
| 1634 | 1549 | ||
| 1635 | /* | 1550 | /* |
| 1636 | * Mac mini hack. On this device, the DVI-I connector shares one DDC | 1551 | * Mac mini hack. On this device, the DVI-I connector shares one DDC |
| @@ -1639,11 +1554,11 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | |||
| 1639 | * which case we'll look there for the digital DDC data. | 1554 | * which case we'll look there for the digital DDC data. |
| 1640 | */ | 1555 | */ |
| 1641 | if (num_modes == 0 && | 1556 | if (num_modes == 0 && |
| 1642 | sdvo_priv->analog_ddc_bus && | 1557 | intel_sdvo->analog_ddc_bus && |
| 1643 | !intel_analog_is_connected(connector->dev)) { | 1558 | !intel_analog_is_connected(connector->dev)) { |
| 1644 | /* Switch to the analog ddc bus and try that | 1559 | /* Switch to the analog ddc bus and try that |
| 1645 | */ | 1560 | */ |
| 1646 | (void) intel_ddc_get_modes(connector, sdvo_priv->analog_ddc_bus); | 1561 | (void) intel_ddc_get_modes(connector, intel_sdvo->analog_ddc_bus); |
| 1647 | } | 1562 | } |
| 1648 | } | 1563 | } |
| 1649 | 1564 | ||
| @@ -1715,52 +1630,43 @@ struct drm_display_mode sdvo_tv_modes[] = { | |||
| 1715 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | 1630 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) |
| 1716 | { | 1631 | { |
| 1717 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1632 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1718 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1633 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1719 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1720 | struct intel_sdvo_sdtv_resolution_request tv_res; | 1634 | struct intel_sdvo_sdtv_resolution_request tv_res; |
| 1721 | uint32_t reply = 0, format_map = 0; | 1635 | uint32_t reply = 0, format_map = 0; |
| 1722 | int i; | 1636 | int i; |
| 1723 | uint8_t status; | ||
| 1724 | |||
| 1725 | 1637 | ||
| 1726 | /* Read the list of supported input resolutions for the selected TV | 1638 | /* Read the list of supported input resolutions for the selected TV |
| 1727 | * format. | 1639 | * format. |
| 1728 | */ | 1640 | */ |
| 1729 | for (i = 0; i < TV_FORMAT_NUM; i++) | 1641 | format_map = 1 << intel_sdvo->tv_format_index; |
| 1730 | if (tv_format_names[i] == sdvo_priv->tv_format_name) | ||
| 1731 | break; | ||
| 1732 | |||
| 1733 | format_map = (1 << i); | ||
| 1734 | memcpy(&tv_res, &format_map, | 1642 | memcpy(&tv_res, &format_map, |
| 1735 | sizeof(struct intel_sdvo_sdtv_resolution_request) > | 1643 | min(sizeof(format_map), sizeof(struct intel_sdvo_sdtv_resolution_request))); |
| 1736 | sizeof(format_map) ? sizeof(format_map) : | ||
| 1737 | sizeof(struct intel_sdvo_sdtv_resolution_request)); | ||
| 1738 | 1644 | ||
| 1739 | intel_sdvo_set_target_output(intel_encoder, sdvo_priv->attached_output); | 1645 | if (!intel_sdvo_set_target_output(intel_sdvo, intel_sdvo->attached_output)) |
| 1646 | return; | ||
| 1740 | 1647 | ||
| 1741 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, | 1648 | BUILD_BUG_ON(sizeof(tv_res) != 3); |
| 1742 | &tv_res, sizeof(tv_res)); | 1649 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, |
| 1743 | status = intel_sdvo_read_response(intel_encoder, &reply, 3); | 1650 | &tv_res, sizeof(tv_res))) |
| 1744 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1651 | return; |
| 1652 | if (!intel_sdvo_read_response(intel_sdvo, &reply, 3)) | ||
| 1745 | return; | 1653 | return; |
| 1746 | 1654 | ||
| 1747 | for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) | 1655 | for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) |
| 1748 | if (reply & (1 << i)) { | 1656 | if (reply & (1 << i)) { |
| 1749 | struct drm_display_mode *nmode; | 1657 | struct drm_display_mode *nmode; |
| 1750 | nmode = drm_mode_duplicate(connector->dev, | 1658 | nmode = drm_mode_duplicate(connector->dev, |
| 1751 | &sdvo_tv_modes[i]); | 1659 | &sdvo_tv_modes[i]); |
| 1752 | if (nmode) | 1660 | if (nmode) |
| 1753 | drm_mode_probed_add(connector, nmode); | 1661 | drm_mode_probed_add(connector, nmode); |
| 1754 | } | 1662 | } |
| 1755 | |||
| 1756 | } | 1663 | } |
| 1757 | 1664 | ||
| 1758 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1665 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
| 1759 | { | 1666 | { |
| 1760 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1667 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1761 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1668 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1762 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1669 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
| 1763 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 1764 | struct drm_display_mode *newmode; | 1670 | struct drm_display_mode *newmode; |
| 1765 | 1671 | ||
| 1766 | /* | 1672 | /* |
| @@ -1768,7 +1674,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
| 1768 | * Assume that the preferred modes are | 1674 | * Assume that the preferred modes are |
| 1769 | * arranged in priority order. | 1675 | * arranged in priority order. |
| 1770 | */ | 1676 | */ |
| 1771 | intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 1677 | intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus); |
| 1772 | if (list_empty(&connector->probed_modes) == false) | 1678 | if (list_empty(&connector->probed_modes) == false) |
| 1773 | goto end; | 1679 | goto end; |
| 1774 | 1680 | ||
| @@ -1787,8 +1693,9 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
| 1787 | end: | 1693 | end: |
| 1788 | list_for_each_entry(newmode, &connector->probed_modes, head) { | 1694 | list_for_each_entry(newmode, &connector->probed_modes, head) { |
| 1789 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { | 1695 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { |
| 1790 | sdvo_priv->sdvo_lvds_fixed_mode = | 1696 | intel_sdvo->sdvo_lvds_fixed_mode = |
| 1791 | drm_mode_duplicate(connector->dev, newmode); | 1697 | drm_mode_duplicate(connector->dev, newmode); |
| 1698 | intel_sdvo->is_lvds = true; | ||
| 1792 | break; | 1699 | break; |
| 1793 | } | 1700 | } |
| 1794 | } | 1701 | } |
| @@ -1797,66 +1704,67 @@ end: | |||
| 1797 | 1704 | ||
| 1798 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1705 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
| 1799 | { | 1706 | { |
| 1800 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1707 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
| 1801 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
| 1802 | 1708 | ||
| 1803 | if (IS_TV(sdvo_connector)) | 1709 | if (IS_TV(intel_sdvo_connector)) |
| 1804 | intel_sdvo_get_tv_modes(connector); | 1710 | intel_sdvo_get_tv_modes(connector); |
| 1805 | else if (IS_LVDS(sdvo_connector)) | 1711 | else if (IS_LVDS(intel_sdvo_connector)) |
| 1806 | intel_sdvo_get_lvds_modes(connector); | 1712 | intel_sdvo_get_lvds_modes(connector); |
| 1807 | else | 1713 | else |
| 1808 | intel_sdvo_get_ddc_modes(connector); | 1714 | intel_sdvo_get_ddc_modes(connector); |
| 1809 | 1715 | ||
| 1810 | if (list_empty(&connector->probed_modes)) | 1716 | return !list_empty(&connector->probed_modes); |
| 1811 | return 0; | ||
| 1812 | return 1; | ||
| 1813 | } | 1717 | } |
| 1814 | 1718 | ||
| 1815 | static | 1719 | static void |
| 1816 | void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | 1720 | intel_sdvo_destroy_enhance_property(struct drm_connector *connector) |
| 1817 | { | 1721 | { |
| 1818 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1722 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
| 1819 | struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv; | ||
| 1820 | struct drm_device *dev = connector->dev; | 1723 | struct drm_device *dev = connector->dev; |
| 1821 | 1724 | ||
| 1822 | if (IS_TV(sdvo_priv)) { | 1725 | if (intel_sdvo_connector->left) |
| 1823 | if (sdvo_priv->left_property) | 1726 | drm_property_destroy(dev, intel_sdvo_connector->left); |
| 1824 | drm_property_destroy(dev, sdvo_priv->left_property); | 1727 | if (intel_sdvo_connector->right) |
| 1825 | if (sdvo_priv->right_property) | 1728 | drm_property_destroy(dev, intel_sdvo_connector->right); |
| 1826 | drm_property_destroy(dev, sdvo_priv->right_property); | 1729 | if (intel_sdvo_connector->top) |
| 1827 | if (sdvo_priv->top_property) | 1730 | drm_property_destroy(dev, intel_sdvo_connector->top); |
| 1828 | drm_property_destroy(dev, sdvo_priv->top_property); | 1731 | if (intel_sdvo_connector->bottom) |
| 1829 | if (sdvo_priv->bottom_property) | 1732 | drm_property_destroy(dev, intel_sdvo_connector->bottom); |
| 1830 | drm_property_destroy(dev, sdvo_priv->bottom_property); | 1733 | if (intel_sdvo_connector->hpos) |
| 1831 | if (sdvo_priv->hpos_property) | 1734 | drm_property_destroy(dev, intel_sdvo_connector->hpos); |
| 1832 | drm_property_destroy(dev, sdvo_priv->hpos_property); | 1735 | if (intel_sdvo_connector->vpos) |
| 1833 | if (sdvo_priv->vpos_property) | 1736 | drm_property_destroy(dev, intel_sdvo_connector->vpos); |
| 1834 | drm_property_destroy(dev, sdvo_priv->vpos_property); | 1737 | if (intel_sdvo_connector->saturation) |
| 1835 | if (sdvo_priv->saturation_property) | 1738 | drm_property_destroy(dev, intel_sdvo_connector->saturation); |
| 1836 | drm_property_destroy(dev, | 1739 | if (intel_sdvo_connector->contrast) |
| 1837 | sdvo_priv->saturation_property); | 1740 | drm_property_destroy(dev, intel_sdvo_connector->contrast); |
| 1838 | if (sdvo_priv->contrast_property) | 1741 | if (intel_sdvo_connector->hue) |
| 1839 | drm_property_destroy(dev, | 1742 | drm_property_destroy(dev, intel_sdvo_connector->hue); |
| 1840 | sdvo_priv->contrast_property); | 1743 | if (intel_sdvo_connector->sharpness) |
| 1841 | if (sdvo_priv->hue_property) | 1744 | drm_property_destroy(dev, intel_sdvo_connector->sharpness); |
| 1842 | drm_property_destroy(dev, sdvo_priv->hue_property); | 1745 | if (intel_sdvo_connector->flicker_filter) |
| 1843 | } | 1746 | drm_property_destroy(dev, intel_sdvo_connector->flicker_filter); |
| 1844 | if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) { | 1747 | if (intel_sdvo_connector->flicker_filter_2d) |
| 1845 | if (sdvo_priv->brightness_property) | 1748 | drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_2d); |
| 1846 | drm_property_destroy(dev, | 1749 | if (intel_sdvo_connector->flicker_filter_adaptive) |
| 1847 | sdvo_priv->brightness_property); | 1750 | drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_adaptive); |
| 1848 | } | 1751 | if (intel_sdvo_connector->tv_luma_filter) |
| 1849 | return; | 1752 | drm_property_destroy(dev, intel_sdvo_connector->tv_luma_filter); |
| 1753 | if (intel_sdvo_connector->tv_chroma_filter) | ||
| 1754 | drm_property_destroy(dev, intel_sdvo_connector->tv_chroma_filter); | ||
| 1755 | if (intel_sdvo_connector->dot_crawl) | ||
| 1756 | drm_property_destroy(dev, intel_sdvo_connector->dot_crawl); | ||
| 1757 | if (intel_sdvo_connector->brightness) | ||
| 1758 | drm_property_destroy(dev, intel_sdvo_connector->brightness); | ||
| 1850 | } | 1759 | } |
| 1851 | 1760 | ||
| 1852 | static void intel_sdvo_destroy(struct drm_connector *connector) | 1761 | static void intel_sdvo_destroy(struct drm_connector *connector) |
| 1853 | { | 1762 | { |
| 1854 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1763 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
| 1855 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
| 1856 | 1764 | ||
| 1857 | if (sdvo_connector->tv_format_property) | 1765 | if (intel_sdvo_connector->tv_format) |
| 1858 | drm_property_destroy(connector->dev, | 1766 | drm_property_destroy(connector->dev, |
| 1859 | sdvo_connector->tv_format_property); | 1767 | intel_sdvo_connector->tv_format); |
| 1860 | 1768 | ||
| 1861 | intel_sdvo_destroy_enhance_property(connector); | 1769 | intel_sdvo_destroy_enhance_property(connector); |
| 1862 | drm_sysfs_connector_remove(connector); | 1770 | drm_sysfs_connector_remove(connector); |
| @@ -1870,132 +1778,118 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
| 1870 | uint64_t val) | 1778 | uint64_t val) |
| 1871 | { | 1779 | { |
| 1872 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1780 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1873 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1781 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 1874 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1782 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
| 1875 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
| 1876 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
| 1877 | struct drm_crtc *crtc = encoder->crtc; | ||
| 1878 | int ret = 0; | ||
| 1879 | bool changed = false; | ||
| 1880 | uint8_t cmd, status; | ||
| 1881 | uint16_t temp_value; | 1783 | uint16_t temp_value; |
| 1784 | uint8_t cmd; | ||
| 1785 | int ret; | ||
| 1882 | 1786 | ||
| 1883 | ret = drm_connector_property_set_value(connector, property, val); | 1787 | ret = drm_connector_property_set_value(connector, property, val); |
| 1884 | if (ret < 0) | 1788 | if (ret) |
| 1885 | goto out; | 1789 | return ret; |
| 1790 | |||
| 1791 | #define CHECK_PROPERTY(name, NAME) \ | ||
| 1792 | if (intel_sdvo_connector->name == property) { \ | ||
| 1793 | if (intel_sdvo_connector->cur_##name == temp_value) return 0; \ | ||
| 1794 | if (intel_sdvo_connector->max_##name < temp_value) return -EINVAL; \ | ||
| 1795 | cmd = SDVO_CMD_SET_##NAME; \ | ||
| 1796 | intel_sdvo_connector->cur_##name = temp_value; \ | ||
| 1797 | goto set_value; \ | ||
| 1798 | } | ||
| 1886 | 1799 | ||
| 1887 | if (property == sdvo_connector->tv_format_property) { | 1800 | if (property == intel_sdvo_connector->tv_format) { |
| 1888 | if (val >= TV_FORMAT_NUM) { | 1801 | if (val >= TV_FORMAT_NUM) |
| 1889 | ret = -EINVAL; | 1802 | return -EINVAL; |
| 1890 | goto out; | ||
| 1891 | } | ||
| 1892 | if (sdvo_priv->tv_format_name == | ||
| 1893 | sdvo_connector->tv_format_supported[val]) | ||
| 1894 | goto out; | ||
| 1895 | 1803 | ||
| 1896 | sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[val]; | 1804 | if (intel_sdvo->tv_format_index == |
| 1897 | changed = true; | 1805 | intel_sdvo_connector->tv_format_supported[val]) |
| 1898 | } | 1806 | return 0; |
| 1899 | 1807 | ||
| 1900 | if (IS_TV(sdvo_connector) || IS_LVDS(sdvo_connector)) { | 1808 | intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[val]; |
| 1901 | cmd = 0; | 1809 | goto done; |
| 1810 | } else if (IS_TV_OR_LVDS(intel_sdvo_connector)) { | ||
| 1902 | temp_value = val; | 1811 | temp_value = val; |
| 1903 | if (sdvo_connector->left_property == property) { | 1812 | if (intel_sdvo_connector->left == property) { |
| 1904 | drm_connector_property_set_value(connector, | 1813 | drm_connector_property_set_value(connector, |
| 1905 | sdvo_connector->right_property, val); | 1814 | intel_sdvo_connector->right, val); |
| 1906 | if (sdvo_connector->left_margin == temp_value) | 1815 | if (intel_sdvo_connector->left_margin == temp_value) |
| 1907 | goto out; | 1816 | return 0; |
| 1908 | 1817 | ||
| 1909 | sdvo_connector->left_margin = temp_value; | 1818 | intel_sdvo_connector->left_margin = temp_value; |
| 1910 | sdvo_connector->right_margin = temp_value; | 1819 | intel_sdvo_connector->right_margin = temp_value; |
| 1911 | temp_value = sdvo_connector->max_hscan - | 1820 | temp_value = intel_sdvo_connector->max_hscan - |
| 1912 | sdvo_connector->left_margin; | 1821 | intel_sdvo_connector->left_margin; |
| 1913 | cmd = SDVO_CMD_SET_OVERSCAN_H; | 1822 | cmd = SDVO_CMD_SET_OVERSCAN_H; |
| 1914 | } else if (sdvo_connector->right_property == property) { | 1823 | goto set_value; |
| 1824 | } else if (intel_sdvo_connector->right == property) { | ||
| 1915 | drm_connector_property_set_value(connector, | 1825 | drm_connector_property_set_value(connector, |
| 1916 | sdvo_connector->left_property, val); | 1826 | intel_sdvo_connector->left, val); |
| 1917 | if (sdvo_connector->right_margin == temp_value) | 1827 | if (intel_sdvo_connector->right_margin == temp_value) |
| 1918 | goto out; | 1828 | return 0; |
| 1919 | 1829 | ||
| 1920 | sdvo_connector->left_margin = temp_value; | 1830 | intel_sdvo_connector->left_margin = temp_value; |
| 1921 | sdvo_connector->right_margin = temp_value; | 1831 | intel_sdvo_connector->right_margin = temp_value; |
| 1922 | temp_value = sdvo_connector->max_hscan - | 1832 | temp_value = intel_sdvo_connector->max_hscan - |
| 1923 | sdvo_connector->left_margin; | 1833 | intel_sdvo_connector->left_margin; |
| 1924 | cmd = SDVO_CMD_SET_OVERSCAN_H; | 1834 | cmd = SDVO_CMD_SET_OVERSCAN_H; |
| 1925 | } else if (sdvo_connector->top_property == property) { | 1835 | goto set_value; |
| 1836 | } else if (intel_sdvo_connector->top == property) { | ||
| 1926 | drm_connector_property_set_value(connector, | 1837 | drm_connector_property_set_value(connector, |
| 1927 | sdvo_connector->bottom_property, val); | 1838 | intel_sdvo_connector->bottom, val); |
| 1928 | if (sdvo_connector->top_margin == temp_value) | 1839 | if (intel_sdvo_connector->top_margin == temp_value) |
| 1929 | goto out; | 1840 | return 0; |
| 1930 | 1841 | ||
| 1931 | sdvo_connector->top_margin = temp_value; | 1842 | intel_sdvo_connector->top_margin = temp_value; |
| 1932 | sdvo_connector->bottom_margin = temp_value; | 1843 | intel_sdvo_connector->bottom_margin = temp_value; |
| 1933 | temp_value = sdvo_connector->max_vscan - | 1844 | temp_value = intel_sdvo_connector->max_vscan - |
| 1934 | sdvo_connector->top_margin; | 1845 | intel_sdvo_connector->top_margin; |
| 1935 | cmd = SDVO_CMD_SET_OVERSCAN_V; | 1846 | cmd = SDVO_CMD_SET_OVERSCAN_V; |
| 1936 | } else if (sdvo_connector->bottom_property == property) { | 1847 | goto set_value; |
| 1848 | } else if (intel_sdvo_connector->bottom == property) { | ||
| 1937 | drm_connector_property_set_value(connector, | 1849 | drm_connector_property_set_value(connector, |
| 1938 | sdvo_connector->top_property, val); | 1850 | intel_sdvo_connector->top, val); |
| 1939 | if (sdvo_connector->bottom_margin == temp_value) | 1851 | if (intel_sdvo_connector->bottom_margin == temp_value) |
| 1940 | goto out; | 1852 | return 0; |
| 1941 | sdvo_connector->top_margin = temp_value; | 1853 | |
| 1942 | sdvo_connector->bottom_margin = temp_value; | 1854 | intel_sdvo_connector->top_margin = temp_value; |
| 1943 | temp_value = sdvo_connector->max_vscan - | 1855 | intel_sdvo_connector->bottom_margin = temp_value; |
| 1944 | sdvo_connector->top_margin; | 1856 | temp_value = intel_sdvo_connector->max_vscan - |
| 1857 | intel_sdvo_connector->top_margin; | ||
| 1945 | cmd = SDVO_CMD_SET_OVERSCAN_V; | 1858 | cmd = SDVO_CMD_SET_OVERSCAN_V; |
| 1946 | } else if (sdvo_connector->hpos_property == property) { | 1859 | goto set_value; |
| 1947 | if (sdvo_connector->cur_hpos == temp_value) | ||
| 1948 | goto out; | ||
| 1949 | |||
| 1950 | cmd = SDVO_CMD_SET_POSITION_H; | ||
| 1951 | sdvo_connector->cur_hpos = temp_value; | ||
| 1952 | } else if (sdvo_connector->vpos_property == property) { | ||
| 1953 | if (sdvo_connector->cur_vpos == temp_value) | ||
| 1954 | goto out; | ||
| 1955 | |||
| 1956 | cmd = SDVO_CMD_SET_POSITION_V; | ||
| 1957 | sdvo_connector->cur_vpos = temp_value; | ||
| 1958 | } else if (sdvo_connector->saturation_property == property) { | ||
| 1959 | if (sdvo_connector->cur_saturation == temp_value) | ||
| 1960 | goto out; | ||
| 1961 | |||
| 1962 | cmd = SDVO_CMD_SET_SATURATION; | ||
| 1963 | sdvo_connector->cur_saturation = temp_value; | ||
| 1964 | } else if (sdvo_connector->contrast_property == property) { | ||
| 1965 | if (sdvo_connector->cur_contrast == temp_value) | ||
| 1966 | goto out; | ||
| 1967 | |||
| 1968 | cmd = SDVO_CMD_SET_CONTRAST; | ||
| 1969 | sdvo_connector->cur_contrast = temp_value; | ||
| 1970 | } else if (sdvo_connector->hue_property == property) { | ||
| 1971 | if (sdvo_connector->cur_hue == temp_value) | ||
| 1972 | goto out; | ||
| 1973 | |||
| 1974 | cmd = SDVO_CMD_SET_HUE; | ||
| 1975 | sdvo_connector->cur_hue = temp_value; | ||
| 1976 | } else if (sdvo_connector->brightness_property == property) { | ||
| 1977 | if (sdvo_connector->cur_brightness == temp_value) | ||
| 1978 | goto out; | ||
| 1979 | |||
| 1980 | cmd = SDVO_CMD_SET_BRIGHTNESS; | ||
| 1981 | sdvo_connector->cur_brightness = temp_value; | ||
| 1982 | } | ||
| 1983 | if (cmd) { | ||
| 1984 | intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2); | ||
| 1985 | status = intel_sdvo_read_response(intel_encoder, | ||
| 1986 | NULL, 0); | ||
| 1987 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 1988 | DRM_DEBUG_KMS("Incorrect SDVO command \n"); | ||
| 1989 | return -EINVAL; | ||
| 1990 | } | ||
| 1991 | changed = true; | ||
| 1992 | } | 1860 | } |
| 1861 | CHECK_PROPERTY(hpos, HPOS) | ||
| 1862 | CHECK_PROPERTY(vpos, VPOS) | ||
| 1863 | CHECK_PROPERTY(saturation, SATURATION) | ||
| 1864 | CHECK_PROPERTY(contrast, CONTRAST) | ||
| 1865 | CHECK_PROPERTY(hue, HUE) | ||
| 1866 | CHECK_PROPERTY(brightness, BRIGHTNESS) | ||
| 1867 | CHECK_PROPERTY(sharpness, SHARPNESS) | ||
| 1868 | CHECK_PROPERTY(flicker_filter, FLICKER_FILTER) | ||
| 1869 | CHECK_PROPERTY(flicker_filter_2d, FLICKER_FILTER_2D) | ||
| 1870 | CHECK_PROPERTY(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE) | ||
| 1871 | CHECK_PROPERTY(tv_chroma_filter, TV_CHROMA_FILTER) | ||
| 1872 | CHECK_PROPERTY(tv_luma_filter, TV_LUMA_FILTER) | ||
| 1873 | CHECK_PROPERTY(dot_crawl, DOT_CRAWL) | ||
| 1993 | } | 1874 | } |
| 1994 | if (changed && crtc) | 1875 | |
| 1876 | return -EINVAL; /* unknown property */ | ||
| 1877 | |||
| 1878 | set_value: | ||
| 1879 | if (!intel_sdvo_set_value(intel_sdvo, cmd, &temp_value, 2)) | ||
| 1880 | return -EIO; | ||
| 1881 | |||
| 1882 | |||
| 1883 | done: | ||
| 1884 | if (encoder->crtc) { | ||
| 1885 | struct drm_crtc *crtc = encoder->crtc; | ||
| 1886 | |||
| 1995 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, | 1887 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, |
| 1996 | crtc->y, crtc->fb); | 1888 | crtc->y, crtc->fb); |
| 1997 | out: | 1889 | } |
| 1998 | return ret; | 1890 | |
| 1891 | return 0; | ||
| 1892 | #undef CHECK_PROPERTY | ||
| 1999 | } | 1893 | } |
| 2000 | 1894 | ||
| 2001 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | 1895 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { |
| @@ -2022,22 +1916,16 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs | |||
| 2022 | 1916 | ||
| 2023 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) | 1917 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) |
| 2024 | { | 1918 | { |
| 2025 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1919 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 2026 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 2027 | 1920 | ||
| 2028 | if (intel_encoder->i2c_bus) | 1921 | if (intel_sdvo->analog_ddc_bus) |
| 2029 | intel_i2c_destroy(intel_encoder->i2c_bus); | 1922 | intel_i2c_destroy(intel_sdvo->analog_ddc_bus); |
| 2030 | if (intel_encoder->ddc_bus) | ||
| 2031 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
| 2032 | if (sdvo_priv->analog_ddc_bus) | ||
| 2033 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | ||
| 2034 | 1923 | ||
| 2035 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | 1924 | if (intel_sdvo->sdvo_lvds_fixed_mode != NULL) |
| 2036 | drm_mode_destroy(encoder->dev, | 1925 | drm_mode_destroy(encoder->dev, |
| 2037 | sdvo_priv->sdvo_lvds_fixed_mode); | 1926 | intel_sdvo->sdvo_lvds_fixed_mode); |
| 2038 | 1927 | ||
| 2039 | drm_encoder_cleanup(encoder); | 1928 | intel_encoder_destroy(encoder); |
| 2040 | kfree(intel_encoder); | ||
| 2041 | } | 1929 | } |
| 2042 | 1930 | ||
| 2043 | static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | 1931 | static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { |
| @@ -2054,7 +1942,7 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | |||
| 2054 | */ | 1942 | */ |
| 2055 | static void | 1943 | static void |
| 2056 | intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | 1944 | intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, |
| 2057 | struct intel_sdvo_priv *sdvo, u32 reg) | 1945 | struct intel_sdvo *sdvo, u32 reg) |
| 2058 | { | 1946 | { |
| 2059 | struct sdvo_device_mapping *mapping; | 1947 | struct sdvo_device_mapping *mapping; |
| 2060 | 1948 | ||
| @@ -2067,57 +1955,46 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | |||
| 2067 | } | 1955 | } |
| 2068 | 1956 | ||
| 2069 | static bool | 1957 | static bool |
| 2070 | intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output, int device) | 1958 | intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device) |
| 2071 | { | 1959 | { |
| 2072 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1960 | return intel_sdvo_set_target_output(intel_sdvo, |
| 2073 | uint8_t status; | 1961 | device == 0 ? SDVO_OUTPUT_TMDS0 : SDVO_OUTPUT_TMDS1) && |
| 2074 | 1962 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE, | |
| 2075 | if (device == 0) | 1963 | &intel_sdvo->is_hdmi, 1); |
| 2076 | intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS0); | ||
| 2077 | else | ||
| 2078 | intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS1); | ||
| 2079 | |||
| 2080 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0); | ||
| 2081 | status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1); | ||
| 2082 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 2083 | return false; | ||
| 2084 | return true; | ||
| 2085 | } | 1964 | } |
| 2086 | 1965 | ||
| 2087 | static struct intel_encoder * | 1966 | static struct intel_sdvo * |
| 2088 | intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan) | 1967 | intel_sdvo_chan_to_intel_sdvo(struct intel_i2c_chan *chan) |
| 2089 | { | 1968 | { |
| 2090 | struct drm_device *dev = chan->drm_dev; | 1969 | struct drm_device *dev = chan->drm_dev; |
| 2091 | struct drm_encoder *encoder; | 1970 | struct drm_encoder *encoder; |
| 2092 | struct intel_encoder *intel_encoder = NULL; | ||
| 2093 | 1971 | ||
| 2094 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1972 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| 2095 | intel_encoder = enc_to_intel_encoder(encoder); | 1973 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
| 2096 | if (intel_encoder->ddc_bus == &chan->adapter) | 1974 | if (intel_sdvo->base.ddc_bus == &chan->adapter) |
| 2097 | break; | 1975 | return intel_sdvo; |
| 2098 | } | 1976 | } |
| 2099 | return intel_encoder; | 1977 | |
| 1978 | return NULL; | ||
| 2100 | } | 1979 | } |
| 2101 | 1980 | ||
| 2102 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | 1981 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, |
| 2103 | struct i2c_msg msgs[], int num) | 1982 | struct i2c_msg msgs[], int num) |
| 2104 | { | 1983 | { |
| 2105 | struct intel_encoder *intel_encoder; | 1984 | struct intel_sdvo *intel_sdvo; |
| 2106 | struct intel_sdvo_priv *sdvo_priv; | ||
| 2107 | struct i2c_algo_bit_data *algo_data; | 1985 | struct i2c_algo_bit_data *algo_data; |
| 2108 | const struct i2c_algorithm *algo; | 1986 | const struct i2c_algorithm *algo; |
| 2109 | 1987 | ||
| 2110 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; | 1988 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; |
| 2111 | intel_encoder = | 1989 | intel_sdvo = |
| 2112 | intel_sdvo_chan_to_intel_encoder( | 1990 | intel_sdvo_chan_to_intel_sdvo((struct intel_i2c_chan *) |
| 2113 | (struct intel_i2c_chan *)(algo_data->data)); | 1991 | (algo_data->data)); |
| 2114 | if (intel_encoder == NULL) | 1992 | if (intel_sdvo == NULL) |
| 2115 | return -EINVAL; | 1993 | return -EINVAL; |
| 2116 | 1994 | ||
| 2117 | sdvo_priv = intel_encoder->dev_priv; | 1995 | algo = intel_sdvo->base.i2c_bus->algo; |
| 2118 | algo = intel_encoder->i2c_bus->algo; | ||
| 2119 | 1996 | ||
| 2120 | intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus); | 1997 | intel_sdvo_set_control_bus_switch(intel_sdvo, intel_sdvo->ddc_bus); |
| 2121 | return algo->master_xfer(i2c_adap, msgs, num); | 1998 | return algo->master_xfer(i2c_adap, msgs, num); |
| 2122 | } | 1999 | } |
| 2123 | 2000 | ||
| @@ -2162,27 +2039,9 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) | |||
| 2162 | return 0x72; | 2039 | return 0x72; |
| 2163 | } | 2040 | } |
| 2164 | 2041 | ||
| 2165 | static bool | ||
| 2166 | intel_sdvo_connector_alloc (struct intel_connector **ret) | ||
| 2167 | { | ||
| 2168 | struct intel_connector *intel_connector; | ||
| 2169 | struct intel_sdvo_connector *sdvo_connector; | ||
| 2170 | |||
| 2171 | *ret = kzalloc(sizeof(*intel_connector) + | ||
| 2172 | sizeof(*sdvo_connector), GFP_KERNEL); | ||
| 2173 | if (!*ret) | ||
| 2174 | return false; | ||
| 2175 | |||
| 2176 | intel_connector = *ret; | ||
| 2177 | sdvo_connector = (struct intel_sdvo_connector *)(intel_connector + 1); | ||
| 2178 | intel_connector->dev_priv = sdvo_connector; | ||
| 2179 | |||
| 2180 | return true; | ||
| 2181 | } | ||
| 2182 | |||
| 2183 | static void | 2042 | static void |
| 2184 | intel_sdvo_connector_create (struct drm_encoder *encoder, | 2043 | intel_sdvo_connector_init(struct drm_encoder *encoder, |
| 2185 | struct drm_connector *connector) | 2044 | struct drm_connector *connector) |
| 2186 | { | 2045 | { |
| 2187 | drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs, | 2046 | drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs, |
| 2188 | connector->connector_type); | 2047 | connector->connector_type); |
| @@ -2198,582 +2057,470 @@ intel_sdvo_connector_create (struct drm_encoder *encoder, | |||
| 2198 | } | 2057 | } |
| 2199 | 2058 | ||
| 2200 | static bool | 2059 | static bool |
| 2201 | intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device) | 2060 | intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) |
| 2202 | { | 2061 | { |
| 2203 | struct drm_encoder *encoder = &intel_encoder->enc; | 2062 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
| 2204 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 2205 | struct drm_connector *connector; | 2063 | struct drm_connector *connector; |
| 2206 | struct intel_connector *intel_connector; | 2064 | struct intel_connector *intel_connector; |
| 2207 | struct intel_sdvo_connector *sdvo_connector; | 2065 | struct intel_sdvo_connector *intel_sdvo_connector; |
| 2208 | 2066 | ||
| 2209 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2067 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
| 2068 | if (!intel_sdvo_connector) | ||
| 2210 | return false; | 2069 | return false; |
| 2211 | 2070 | ||
| 2212 | sdvo_connector = intel_connector->dev_priv; | ||
| 2213 | |||
| 2214 | if (device == 0) { | 2071 | if (device == 0) { |
| 2215 | sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS0; | 2072 | intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0; |
| 2216 | sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; | 2073 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; |
| 2217 | } else if (device == 1) { | 2074 | } else if (device == 1) { |
| 2218 | sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS1; | 2075 | intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1; |
| 2219 | sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; | 2076 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; |
| 2220 | } | 2077 | } |
| 2221 | 2078 | ||
| 2079 | intel_connector = &intel_sdvo_connector->base; | ||
| 2222 | connector = &intel_connector->base; | 2080 | connector = &intel_connector->base; |
| 2223 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; | 2081 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; |
| 2224 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; | 2082 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; |
| 2225 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; | 2083 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; |
| 2226 | 2084 | ||
| 2227 | if (intel_sdvo_get_supp_encode(intel_encoder, &sdvo_priv->encode) | 2085 | if (intel_sdvo_get_supp_encode(intel_sdvo, &intel_sdvo->encode) |
| 2228 | && intel_sdvo_get_digital_encoding_mode(intel_encoder, device) | 2086 | && intel_sdvo_get_digital_encoding_mode(intel_sdvo, device) |
| 2229 | && sdvo_priv->is_hdmi) { | 2087 | && intel_sdvo->is_hdmi) { |
| 2230 | /* enable hdmi encoding mode if supported */ | 2088 | /* enable hdmi encoding mode if supported */ |
| 2231 | intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI); | 2089 | intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI); |
| 2232 | intel_sdvo_set_colorimetry(intel_encoder, | 2090 | intel_sdvo_set_colorimetry(intel_sdvo, |
| 2233 | SDVO_COLORIMETRY_RGB256); | 2091 | SDVO_COLORIMETRY_RGB256); |
| 2234 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2092 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
| 2235 | } | 2093 | } |
| 2236 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2094 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
| 2237 | (1 << INTEL_ANALOG_CLONE_BIT); | 2095 | (1 << INTEL_ANALOG_CLONE_BIT)); |
| 2238 | 2096 | ||
| 2239 | intel_sdvo_connector_create(encoder, connector); | 2097 | intel_sdvo_connector_init(encoder, connector); |
| 2240 | 2098 | ||
| 2241 | return true; | 2099 | return true; |
| 2242 | } | 2100 | } |
| 2243 | 2101 | ||
| 2244 | static bool | 2102 | static bool |
| 2245 | intel_sdvo_tv_init(struct intel_encoder *intel_encoder, int type) | 2103 | intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) |
| 2246 | { | 2104 | { |
| 2247 | struct drm_encoder *encoder = &intel_encoder->enc; | 2105 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
| 2248 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 2249 | struct drm_connector *connector; | 2106 | struct drm_connector *connector; |
| 2250 | struct intel_connector *intel_connector; | 2107 | struct intel_connector *intel_connector; |
| 2251 | struct intel_sdvo_connector *sdvo_connector; | 2108 | struct intel_sdvo_connector *intel_sdvo_connector; |
| 2252 | 2109 | ||
| 2253 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2110 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
| 2254 | return false; | 2111 | if (!intel_sdvo_connector) |
| 2112 | return false; | ||
| 2255 | 2113 | ||
| 2114 | intel_connector = &intel_sdvo_connector->base; | ||
| 2256 | connector = &intel_connector->base; | 2115 | connector = &intel_connector->base; |
| 2257 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | 2116 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; |
| 2258 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | 2117 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; |
| 2259 | sdvo_connector = intel_connector->dev_priv; | ||
| 2260 | 2118 | ||
| 2261 | sdvo_priv->controlled_output |= type; | 2119 | intel_sdvo->controlled_output |= type; |
| 2262 | sdvo_connector->output_flag = type; | 2120 | intel_sdvo_connector->output_flag = type; |
| 2263 | 2121 | ||
| 2264 | sdvo_priv->is_tv = true; | 2122 | intel_sdvo->is_tv = true; |
| 2265 | intel_encoder->needs_tv_clock = true; | 2123 | intel_sdvo->base.needs_tv_clock = true; |
| 2266 | intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | 2124 | intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; |
| 2267 | 2125 | ||
| 2268 | intel_sdvo_connector_create(encoder, connector); | 2126 | intel_sdvo_connector_init(encoder, connector); |
| 2269 | 2127 | ||
| 2270 | intel_sdvo_tv_create_property(connector, type); | 2128 | if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type)) |
| 2129 | goto err; | ||
| 2271 | 2130 | ||
| 2272 | intel_sdvo_create_enhance_property(connector); | 2131 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
| 2132 | goto err; | ||
| 2273 | 2133 | ||
| 2274 | return true; | 2134 | return true; |
| 2135 | |||
| 2136 | err: | ||
| 2137 | intel_sdvo_destroy_enhance_property(connector); | ||
| 2138 | kfree(intel_sdvo_connector); | ||
| 2139 | return false; | ||
| 2275 | } | 2140 | } |
| 2276 | 2141 | ||
| 2277 | static bool | 2142 | static bool |
| 2278 | intel_sdvo_analog_init(struct intel_encoder *intel_encoder, int device) | 2143 | intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) |
| 2279 | { | 2144 | { |
| 2280 | struct drm_encoder *encoder = &intel_encoder->enc; | 2145 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
| 2281 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 2282 | struct drm_connector *connector; | 2146 | struct drm_connector *connector; |
| 2283 | struct intel_connector *intel_connector; | 2147 | struct intel_connector *intel_connector; |
| 2284 | struct intel_sdvo_connector *sdvo_connector; | 2148 | struct intel_sdvo_connector *intel_sdvo_connector; |
| 2285 | 2149 | ||
| 2286 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2150 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
| 2287 | return false; | 2151 | if (!intel_sdvo_connector) |
| 2152 | return false; | ||
| 2288 | 2153 | ||
| 2154 | intel_connector = &intel_sdvo_connector->base; | ||
| 2289 | connector = &intel_connector->base; | 2155 | connector = &intel_connector->base; |
| 2290 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 2156 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
| 2291 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | 2157 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; |
| 2292 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | 2158 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; |
| 2293 | sdvo_connector = intel_connector->dev_priv; | ||
| 2294 | 2159 | ||
| 2295 | if (device == 0) { | 2160 | if (device == 0) { |
| 2296 | sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB0; | 2161 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0; |
| 2297 | sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; | 2162 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; |
| 2298 | } else if (device == 1) { | 2163 | } else if (device == 1) { |
| 2299 | sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB1; | 2164 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; |
| 2300 | sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; | 2165 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; |
| 2301 | } | 2166 | } |
| 2302 | 2167 | ||
| 2303 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2168 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
| 2304 | (1 << INTEL_ANALOG_CLONE_BIT); | 2169 | (1 << INTEL_ANALOG_CLONE_BIT)); |
| 2305 | 2170 | ||
| 2306 | intel_sdvo_connector_create(encoder, connector); | 2171 | intel_sdvo_connector_init(encoder, connector); |
| 2307 | return true; | 2172 | return true; |
| 2308 | } | 2173 | } |
| 2309 | 2174 | ||
| 2310 | static bool | 2175 | static bool |
| 2311 | intel_sdvo_lvds_init(struct intel_encoder *intel_encoder, int device) | 2176 | intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) |
| 2312 | { | 2177 | { |
| 2313 | struct drm_encoder *encoder = &intel_encoder->enc; | 2178 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
| 2314 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 2315 | struct drm_connector *connector; | 2179 | struct drm_connector *connector; |
| 2316 | struct intel_connector *intel_connector; | 2180 | struct intel_connector *intel_connector; |
| 2317 | struct intel_sdvo_connector *sdvo_connector; | 2181 | struct intel_sdvo_connector *intel_sdvo_connector; |
| 2318 | 2182 | ||
| 2319 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2183 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
| 2320 | return false; | 2184 | if (!intel_sdvo_connector) |
| 2185 | return false; | ||
| 2321 | 2186 | ||
| 2322 | connector = &intel_connector->base; | 2187 | intel_connector = &intel_sdvo_connector->base; |
| 2188 | connector = &intel_connector->base; | ||
| 2323 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | 2189 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
| 2324 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | 2190 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
| 2325 | sdvo_connector = intel_connector->dev_priv; | ||
| 2326 | |||
| 2327 | sdvo_priv->is_lvds = true; | ||
| 2328 | 2191 | ||
| 2329 | if (device == 0) { | 2192 | if (device == 0) { |
| 2330 | sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS0; | 2193 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0; |
| 2331 | sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; | 2194 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; |
| 2332 | } else if (device == 1) { | 2195 | } else if (device == 1) { |
| 2333 | sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS1; | 2196 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; |
| 2334 | sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; | 2197 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; |
| 2335 | } | 2198 | } |
| 2336 | 2199 | ||
| 2337 | intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | 2200 | intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) | |
| 2338 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | 2201 | (1 << INTEL_SDVO_LVDS_CLONE_BIT)); |
| 2339 | 2202 | ||
| 2340 | intel_sdvo_connector_create(encoder, connector); | 2203 | intel_sdvo_connector_init(encoder, connector); |
| 2341 | intel_sdvo_create_enhance_property(connector); | 2204 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
| 2342 | return true; | 2205 | goto err; |
| 2206 | |||
| 2207 | return true; | ||
| 2208 | |||
| 2209 | err: | ||
| 2210 | intel_sdvo_destroy_enhance_property(connector); | ||
| 2211 | kfree(intel_sdvo_connector); | ||
| 2212 | return false; | ||
| 2343 | } | 2213 | } |
| 2344 | 2214 | ||
| 2345 | static bool | 2215 | static bool |
| 2346 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags) | 2216 | intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) |
| 2347 | { | 2217 | { |
| 2348 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 2218 | intel_sdvo->is_tv = false; |
| 2349 | 2219 | intel_sdvo->base.needs_tv_clock = false; | |
| 2350 | sdvo_priv->is_tv = false; | 2220 | intel_sdvo->is_lvds = false; |
| 2351 | intel_encoder->needs_tv_clock = false; | ||
| 2352 | sdvo_priv->is_lvds = false; | ||
| 2353 | 2221 | ||
| 2354 | /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ | 2222 | /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ |
| 2355 | 2223 | ||
| 2356 | if (flags & SDVO_OUTPUT_TMDS0) | 2224 | if (flags & SDVO_OUTPUT_TMDS0) |
| 2357 | if (!intel_sdvo_dvi_init(intel_encoder, 0)) | 2225 | if (!intel_sdvo_dvi_init(intel_sdvo, 0)) |
| 2358 | return false; | 2226 | return false; |
| 2359 | 2227 | ||
| 2360 | if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) | 2228 | if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) |
| 2361 | if (!intel_sdvo_dvi_init(intel_encoder, 1)) | 2229 | if (!intel_sdvo_dvi_init(intel_sdvo, 1)) |
| 2362 | return false; | 2230 | return false; |
| 2363 | 2231 | ||
| 2364 | /* TV has no XXX1 function block */ | 2232 | /* TV has no XXX1 function block */ |
| 2365 | if (flags & SDVO_OUTPUT_SVID0) | 2233 | if (flags & SDVO_OUTPUT_SVID0) |
| 2366 | if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_SVID0)) | 2234 | if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_SVID0)) |
| 2367 | return false; | 2235 | return false; |
| 2368 | 2236 | ||
| 2369 | if (flags & SDVO_OUTPUT_CVBS0) | 2237 | if (flags & SDVO_OUTPUT_CVBS0) |
| 2370 | if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_CVBS0)) | 2238 | if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_CVBS0)) |
| 2371 | return false; | 2239 | return false; |
| 2372 | 2240 | ||
| 2373 | if (flags & SDVO_OUTPUT_RGB0) | 2241 | if (flags & SDVO_OUTPUT_RGB0) |
| 2374 | if (!intel_sdvo_analog_init(intel_encoder, 0)) | 2242 | if (!intel_sdvo_analog_init(intel_sdvo, 0)) |
| 2375 | return false; | 2243 | return false; |
| 2376 | 2244 | ||
| 2377 | if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) | 2245 | if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) |
| 2378 | if (!intel_sdvo_analog_init(intel_encoder, 1)) | 2246 | if (!intel_sdvo_analog_init(intel_sdvo, 1)) |
| 2379 | return false; | 2247 | return false; |
| 2380 | 2248 | ||
| 2381 | if (flags & SDVO_OUTPUT_LVDS0) | 2249 | if (flags & SDVO_OUTPUT_LVDS0) |
| 2382 | if (!intel_sdvo_lvds_init(intel_encoder, 0)) | 2250 | if (!intel_sdvo_lvds_init(intel_sdvo, 0)) |
| 2383 | return false; | 2251 | return false; |
| 2384 | 2252 | ||
| 2385 | if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) | 2253 | if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) |
| 2386 | if (!intel_sdvo_lvds_init(intel_encoder, 1)) | 2254 | if (!intel_sdvo_lvds_init(intel_sdvo, 1)) |
| 2387 | return false; | 2255 | return false; |
| 2388 | 2256 | ||
| 2389 | if ((flags & SDVO_OUTPUT_MASK) == 0) { | 2257 | if ((flags & SDVO_OUTPUT_MASK) == 0) { |
| 2390 | unsigned char bytes[2]; | 2258 | unsigned char bytes[2]; |
| 2391 | 2259 | ||
| 2392 | sdvo_priv->controlled_output = 0; | 2260 | intel_sdvo->controlled_output = 0; |
| 2393 | memcpy(bytes, &sdvo_priv->caps.output_flags, 2); | 2261 | memcpy(bytes, &intel_sdvo->caps.output_flags, 2); |
| 2394 | DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", | 2262 | DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", |
| 2395 | SDVO_NAME(sdvo_priv), | 2263 | SDVO_NAME(intel_sdvo), |
| 2396 | bytes[0], bytes[1]); | 2264 | bytes[0], bytes[1]); |
| 2397 | return false; | 2265 | return false; |
| 2398 | } | 2266 | } |
| 2399 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 2267 | intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1); |
| 2400 | 2268 | ||
| 2401 | return true; | 2269 | return true; |
| 2402 | } | 2270 | } |
| 2403 | 2271 | ||
| 2404 | static void intel_sdvo_tv_create_property(struct drm_connector *connector, int type) | 2272 | static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
| 2273 | struct intel_sdvo_connector *intel_sdvo_connector, | ||
| 2274 | int type) | ||
| 2405 | { | 2275 | { |
| 2406 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 2276 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
| 2407 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 2408 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
| 2409 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
| 2410 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
| 2411 | struct intel_sdvo_tv_format format; | 2277 | struct intel_sdvo_tv_format format; |
| 2412 | uint32_t format_map, i; | 2278 | uint32_t format_map, i; |
| 2413 | uint8_t status; | ||
| 2414 | 2279 | ||
| 2415 | intel_sdvo_set_target_output(intel_encoder, type); | 2280 | if (!intel_sdvo_set_target_output(intel_sdvo, type)) |
| 2281 | return false; | ||
| 2416 | 2282 | ||
| 2417 | intel_sdvo_write_cmd(intel_encoder, | 2283 | if (!intel_sdvo_get_value(intel_sdvo, |
| 2418 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); | 2284 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, |
| 2419 | status = intel_sdvo_read_response(intel_encoder, | 2285 | &format, sizeof(format))) |
| 2420 | &format, sizeof(format)); | 2286 | return false; |
| 2421 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
| 2422 | return; | ||
| 2423 | 2287 | ||
| 2424 | memcpy(&format_map, &format, sizeof(format) > sizeof(format_map) ? | 2288 | memcpy(&format_map, &format, min(sizeof(format_map), sizeof(format))); |
| 2425 | sizeof(format_map) : sizeof(format)); | ||
| 2426 | 2289 | ||
| 2427 | if (format_map == 0) | 2290 | if (format_map == 0) |
| 2428 | return; | 2291 | return false; |
| 2429 | 2292 | ||
| 2430 | sdvo_connector->format_supported_num = 0; | 2293 | intel_sdvo_connector->format_supported_num = 0; |
| 2431 | for (i = 0 ; i < TV_FORMAT_NUM; i++) | 2294 | for (i = 0 ; i < TV_FORMAT_NUM; i++) |
| 2432 | if (format_map & (1 << i)) { | 2295 | if (format_map & (1 << i)) |
| 2433 | sdvo_connector->tv_format_supported | 2296 | intel_sdvo_connector->tv_format_supported[intel_sdvo_connector->format_supported_num++] = i; |
| 2434 | [sdvo_connector->format_supported_num++] = | ||
| 2435 | tv_format_names[i]; | ||
| 2436 | } | ||
| 2437 | 2297 | ||
| 2438 | 2298 | ||
| 2439 | sdvo_connector->tv_format_property = | 2299 | intel_sdvo_connector->tv_format = |
| 2440 | drm_property_create( | 2300 | drm_property_create(dev, DRM_MODE_PROP_ENUM, |
| 2441 | connector->dev, DRM_MODE_PROP_ENUM, | 2301 | "mode", intel_sdvo_connector->format_supported_num); |
| 2442 | "mode", sdvo_connector->format_supported_num); | 2302 | if (!intel_sdvo_connector->tv_format) |
| 2303 | return false; | ||
| 2443 | 2304 | ||
| 2444 | for (i = 0; i < sdvo_connector->format_supported_num; i++) | 2305 | for (i = 0; i < intel_sdvo_connector->format_supported_num; i++) |
| 2445 | drm_property_add_enum( | 2306 | drm_property_add_enum( |
| 2446 | sdvo_connector->tv_format_property, i, | 2307 | intel_sdvo_connector->tv_format, i, |
| 2447 | i, sdvo_connector->tv_format_supported[i]); | 2308 | i, tv_format_names[intel_sdvo_connector->tv_format_supported[i]]); |
| 2448 | 2309 | ||
| 2449 | sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[0]; | 2310 | intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[0]; |
| 2450 | drm_connector_attach_property( | 2311 | drm_connector_attach_property(&intel_sdvo_connector->base.base, |
| 2451 | connector, sdvo_connector->tv_format_property, 0); | 2312 | intel_sdvo_connector->tv_format, 0); |
| 2313 | return true; | ||
| 2452 | 2314 | ||
| 2453 | } | 2315 | } |
| 2454 | 2316 | ||
| 2455 | static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | 2317 | #define ENHANCEMENT(name, NAME) do { \ |
| 2318 | if (enhancements.name) { \ | ||
| 2319 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_MAX_##NAME, &data_value, 4) || \ | ||
| 2320 | !intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \ | ||
| 2321 | return false; \ | ||
| 2322 | intel_sdvo_connector->max_##name = data_value[0]; \ | ||
| 2323 | intel_sdvo_connector->cur_##name = response; \ | ||
| 2324 | intel_sdvo_connector->name = \ | ||
| 2325 | drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \ | ||
| 2326 | if (!intel_sdvo_connector->name) return false; \ | ||
| 2327 | intel_sdvo_connector->name->values[0] = 0; \ | ||
| 2328 | intel_sdvo_connector->name->values[1] = data_value[0]; \ | ||
| 2329 | drm_connector_attach_property(connector, \ | ||
| 2330 | intel_sdvo_connector->name, \ | ||
| 2331 | intel_sdvo_connector->cur_##name); \ | ||
| 2332 | DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \ | ||
| 2333 | data_value[0], data_value[1], response); \ | ||
| 2334 | } \ | ||
| 2335 | } while(0) | ||
| 2336 | |||
| 2337 | static bool | ||
| 2338 | intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, | ||
| 2339 | struct intel_sdvo_connector *intel_sdvo_connector, | ||
| 2340 | struct intel_sdvo_enhancements_reply enhancements) | ||
| 2456 | { | 2341 | { |
| 2457 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 2342 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
| 2458 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 2343 | struct drm_connector *connector = &intel_sdvo_connector->base.base; |
| 2459 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
| 2460 | struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv; | ||
| 2461 | struct intel_sdvo_enhancements_reply sdvo_data; | ||
| 2462 | struct drm_device *dev = connector->dev; | ||
| 2463 | uint8_t status; | ||
| 2464 | uint16_t response, data_value[2]; | 2344 | uint16_t response, data_value[2]; |
| 2465 | 2345 | ||
| 2466 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, | 2346 | /* when horizontal overscan is supported, Add the left/right property */ |
| 2467 | NULL, 0); | 2347 | if (enhancements.overscan_h) { |
| 2468 | status = intel_sdvo_read_response(intel_encoder, &sdvo_data, | 2348 | if (!intel_sdvo_get_value(intel_sdvo, |
| 2469 | sizeof(sdvo_data)); | 2349 | SDVO_CMD_GET_MAX_OVERSCAN_H, |
| 2470 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2350 | &data_value, 4)) |
| 2471 | DRM_DEBUG_KMS(" incorrect response is returned\n"); | 2351 | return false; |
| 2472 | return; | 2352 | |
| 2353 | if (!intel_sdvo_get_value(intel_sdvo, | ||
| 2354 | SDVO_CMD_GET_OVERSCAN_H, | ||
| 2355 | &response, 2)) | ||
| 2356 | return false; | ||
| 2357 | |||
| 2358 | intel_sdvo_connector->max_hscan = data_value[0]; | ||
| 2359 | intel_sdvo_connector->left_margin = data_value[0] - response; | ||
| 2360 | intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin; | ||
| 2361 | intel_sdvo_connector->left = | ||
| 2362 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2363 | "left_margin", 2); | ||
| 2364 | if (!intel_sdvo_connector->left) | ||
| 2365 | return false; | ||
| 2366 | |||
| 2367 | intel_sdvo_connector->left->values[0] = 0; | ||
| 2368 | intel_sdvo_connector->left->values[1] = data_value[0]; | ||
| 2369 | drm_connector_attach_property(connector, | ||
| 2370 | intel_sdvo_connector->left, | ||
| 2371 | intel_sdvo_connector->left_margin); | ||
| 2372 | |||
| 2373 | intel_sdvo_connector->right = | ||
| 2374 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2375 | "right_margin", 2); | ||
| 2376 | if (!intel_sdvo_connector->right) | ||
| 2377 | return false; | ||
| 2378 | |||
| 2379 | intel_sdvo_connector->right->values[0] = 0; | ||
| 2380 | intel_sdvo_connector->right->values[1] = data_value[0]; | ||
| 2381 | drm_connector_attach_property(connector, | ||
| 2382 | intel_sdvo_connector->right, | ||
| 2383 | intel_sdvo_connector->right_margin); | ||
| 2384 | DRM_DEBUG_KMS("h_overscan: max %d, " | ||
| 2385 | "default %d, current %d\n", | ||
| 2386 | data_value[0], data_value[1], response); | ||
| 2473 | } | 2387 | } |
| 2474 | response = *((uint16_t *)&sdvo_data); | 2388 | |
| 2475 | if (!response) { | 2389 | if (enhancements.overscan_v) { |
| 2476 | DRM_DEBUG_KMS("No enhancement is supported\n"); | 2390 | if (!intel_sdvo_get_value(intel_sdvo, |
| 2477 | return; | 2391 | SDVO_CMD_GET_MAX_OVERSCAN_V, |
| 2392 | &data_value, 4)) | ||
| 2393 | return false; | ||
| 2394 | |||
| 2395 | if (!intel_sdvo_get_value(intel_sdvo, | ||
| 2396 | SDVO_CMD_GET_OVERSCAN_V, | ||
| 2397 | &response, 2)) | ||
| 2398 | return false; | ||
| 2399 | |||
| 2400 | intel_sdvo_connector->max_vscan = data_value[0]; | ||
| 2401 | intel_sdvo_connector->top_margin = data_value[0] - response; | ||
| 2402 | intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin; | ||
| 2403 | intel_sdvo_connector->top = | ||
| 2404 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2405 | "top_margin", 2); | ||
| 2406 | if (!intel_sdvo_connector->top) | ||
| 2407 | return false; | ||
| 2408 | |||
| 2409 | intel_sdvo_connector->top->values[0] = 0; | ||
| 2410 | intel_sdvo_connector->top->values[1] = data_value[0]; | ||
| 2411 | drm_connector_attach_property(connector, | ||
| 2412 | intel_sdvo_connector->top, | ||
| 2413 | intel_sdvo_connector->top_margin); | ||
| 2414 | |||
| 2415 | intel_sdvo_connector->bottom = | ||
| 2416 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2417 | "bottom_margin", 2); | ||
| 2418 | if (!intel_sdvo_connector->bottom) | ||
| 2419 | return false; | ||
| 2420 | |||
| 2421 | intel_sdvo_connector->bottom->values[0] = 0; | ||
| 2422 | intel_sdvo_connector->bottom->values[1] = data_value[0]; | ||
| 2423 | drm_connector_attach_property(connector, | ||
| 2424 | intel_sdvo_connector->bottom, | ||
| 2425 | intel_sdvo_connector->bottom_margin); | ||
| 2426 | DRM_DEBUG_KMS("v_overscan: max %d, " | ||
| 2427 | "default %d, current %d\n", | ||
| 2428 | data_value[0], data_value[1], response); | ||
| 2478 | } | 2429 | } |
| 2479 | if (IS_TV(sdvo_priv)) { | 2430 | |
| 2480 | /* when horizontal overscan is supported, Add the left/right | 2431 | ENHANCEMENT(hpos, HPOS); |
| 2481 | * property | 2432 | ENHANCEMENT(vpos, VPOS); |
| 2482 | */ | 2433 | ENHANCEMENT(saturation, SATURATION); |
| 2483 | if (sdvo_data.overscan_h) { | 2434 | ENHANCEMENT(contrast, CONTRAST); |
| 2484 | intel_sdvo_write_cmd(intel_encoder, | 2435 | ENHANCEMENT(hue, HUE); |
| 2485 | SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); | 2436 | ENHANCEMENT(sharpness, SHARPNESS); |
| 2486 | status = intel_sdvo_read_response(intel_encoder, | 2437 | ENHANCEMENT(brightness, BRIGHTNESS); |
| 2487 | &data_value, 4); | 2438 | ENHANCEMENT(flicker_filter, FLICKER_FILTER); |
| 2488 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2439 | ENHANCEMENT(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE); |
| 2489 | DRM_DEBUG_KMS("Incorrect SDVO max " | 2440 | ENHANCEMENT(flicker_filter_2d, FLICKER_FILTER_2D); |
| 2490 | "h_overscan\n"); | 2441 | ENHANCEMENT(tv_chroma_filter, TV_CHROMA_FILTER); |
| 2491 | return; | 2442 | ENHANCEMENT(tv_luma_filter, TV_LUMA_FILTER); |
| 2492 | } | 2443 | |
| 2493 | intel_sdvo_write_cmd(intel_encoder, | 2444 | if (enhancements.dot_crawl) { |
| 2494 | SDVO_CMD_GET_OVERSCAN_H, NULL, 0); | 2445 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DOT_CRAWL, &response, 2)) |
| 2495 | status = intel_sdvo_read_response(intel_encoder, | 2446 | return false; |
| 2496 | &response, 2); | 2447 | |
| 2497 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2448 | intel_sdvo_connector->max_dot_crawl = 1; |
| 2498 | DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n"); | 2449 | intel_sdvo_connector->cur_dot_crawl = response & 0x1; |
| 2499 | return; | 2450 | intel_sdvo_connector->dot_crawl = |
| 2500 | } | 2451 | drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2); |
| 2501 | sdvo_priv->max_hscan = data_value[0]; | 2452 | if (!intel_sdvo_connector->dot_crawl) |
| 2502 | sdvo_priv->left_margin = data_value[0] - response; | 2453 | return false; |
| 2503 | sdvo_priv->right_margin = sdvo_priv->left_margin; | 2454 | |
| 2504 | sdvo_priv->left_property = | 2455 | intel_sdvo_connector->dot_crawl->values[0] = 0; |
| 2505 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2456 | intel_sdvo_connector->dot_crawl->values[1] = 1; |
| 2506 | "left_margin", 2); | 2457 | drm_connector_attach_property(connector, |
| 2507 | sdvo_priv->left_property->values[0] = 0; | 2458 | intel_sdvo_connector->dot_crawl, |
| 2508 | sdvo_priv->left_property->values[1] = data_value[0]; | 2459 | intel_sdvo_connector->cur_dot_crawl); |
| 2509 | drm_connector_attach_property(connector, | 2460 | DRM_DEBUG_KMS("dot crawl: current %d\n", response); |
| 2510 | sdvo_priv->left_property, | ||
| 2511 | sdvo_priv->left_margin); | ||
| 2512 | sdvo_priv->right_property = | ||
| 2513 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2514 | "right_margin", 2); | ||
| 2515 | sdvo_priv->right_property->values[0] = 0; | ||
| 2516 | sdvo_priv->right_property->values[1] = data_value[0]; | ||
| 2517 | drm_connector_attach_property(connector, | ||
| 2518 | sdvo_priv->right_property, | ||
| 2519 | sdvo_priv->right_margin); | ||
| 2520 | DRM_DEBUG_KMS("h_overscan: max %d, " | ||
| 2521 | "default %d, current %d\n", | ||
| 2522 | data_value[0], data_value[1], response); | ||
| 2523 | } | ||
| 2524 | if (sdvo_data.overscan_v) { | ||
| 2525 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2526 | SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); | ||
| 2527 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2528 | &data_value, 4); | ||
| 2529 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2530 | DRM_DEBUG_KMS("Incorrect SDVO max " | ||
| 2531 | "v_overscan\n"); | ||
| 2532 | return; | ||
| 2533 | } | ||
| 2534 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2535 | SDVO_CMD_GET_OVERSCAN_V, NULL, 0); | ||
| 2536 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2537 | &response, 2); | ||
| 2538 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2539 | DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n"); | ||
| 2540 | return; | ||
| 2541 | } | ||
| 2542 | sdvo_priv->max_vscan = data_value[0]; | ||
| 2543 | sdvo_priv->top_margin = data_value[0] - response; | ||
| 2544 | sdvo_priv->bottom_margin = sdvo_priv->top_margin; | ||
| 2545 | sdvo_priv->top_property = | ||
| 2546 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2547 | "top_margin", 2); | ||
| 2548 | sdvo_priv->top_property->values[0] = 0; | ||
| 2549 | sdvo_priv->top_property->values[1] = data_value[0]; | ||
| 2550 | drm_connector_attach_property(connector, | ||
| 2551 | sdvo_priv->top_property, | ||
| 2552 | sdvo_priv->top_margin); | ||
| 2553 | sdvo_priv->bottom_property = | ||
| 2554 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2555 | "bottom_margin", 2); | ||
| 2556 | sdvo_priv->bottom_property->values[0] = 0; | ||
| 2557 | sdvo_priv->bottom_property->values[1] = data_value[0]; | ||
| 2558 | drm_connector_attach_property(connector, | ||
| 2559 | sdvo_priv->bottom_property, | ||
| 2560 | sdvo_priv->bottom_margin); | ||
| 2561 | DRM_DEBUG_KMS("v_overscan: max %d, " | ||
| 2562 | "default %d, current %d\n", | ||
| 2563 | data_value[0], data_value[1], response); | ||
| 2564 | } | ||
| 2565 | if (sdvo_data.position_h) { | ||
| 2566 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2567 | SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); | ||
| 2568 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2569 | &data_value, 4); | ||
| 2570 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2571 | DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n"); | ||
| 2572 | return; | ||
| 2573 | } | ||
| 2574 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2575 | SDVO_CMD_GET_POSITION_H, NULL, 0); | ||
| 2576 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2577 | &response, 2); | ||
| 2578 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2579 | DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n"); | ||
| 2580 | return; | ||
| 2581 | } | ||
| 2582 | sdvo_priv->max_hpos = data_value[0]; | ||
| 2583 | sdvo_priv->cur_hpos = response; | ||
| 2584 | sdvo_priv->hpos_property = | ||
| 2585 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2586 | "hpos", 2); | ||
| 2587 | sdvo_priv->hpos_property->values[0] = 0; | ||
| 2588 | sdvo_priv->hpos_property->values[1] = data_value[0]; | ||
| 2589 | drm_connector_attach_property(connector, | ||
| 2590 | sdvo_priv->hpos_property, | ||
| 2591 | sdvo_priv->cur_hpos); | ||
| 2592 | DRM_DEBUG_KMS("h_position: max %d, " | ||
| 2593 | "default %d, current %d\n", | ||
| 2594 | data_value[0], data_value[1], response); | ||
| 2595 | } | ||
| 2596 | if (sdvo_data.position_v) { | ||
| 2597 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2598 | SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); | ||
| 2599 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2600 | &data_value, 4); | ||
| 2601 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2602 | DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n"); | ||
| 2603 | return; | ||
| 2604 | } | ||
| 2605 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2606 | SDVO_CMD_GET_POSITION_V, NULL, 0); | ||
| 2607 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2608 | &response, 2); | ||
| 2609 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2610 | DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n"); | ||
| 2611 | return; | ||
| 2612 | } | ||
| 2613 | sdvo_priv->max_vpos = data_value[0]; | ||
| 2614 | sdvo_priv->cur_vpos = response; | ||
| 2615 | sdvo_priv->vpos_property = | ||
| 2616 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2617 | "vpos", 2); | ||
| 2618 | sdvo_priv->vpos_property->values[0] = 0; | ||
| 2619 | sdvo_priv->vpos_property->values[1] = data_value[0]; | ||
| 2620 | drm_connector_attach_property(connector, | ||
| 2621 | sdvo_priv->vpos_property, | ||
| 2622 | sdvo_priv->cur_vpos); | ||
| 2623 | DRM_DEBUG_KMS("v_position: max %d, " | ||
| 2624 | "default %d, current %d\n", | ||
| 2625 | data_value[0], data_value[1], response); | ||
| 2626 | } | ||
| 2627 | if (sdvo_data.saturation) { | ||
| 2628 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2629 | SDVO_CMD_GET_MAX_SATURATION, NULL, 0); | ||
| 2630 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2631 | &data_value, 4); | ||
| 2632 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2633 | DRM_DEBUG_KMS("Incorrect SDVO Max sat\n"); | ||
| 2634 | return; | ||
| 2635 | } | ||
| 2636 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2637 | SDVO_CMD_GET_SATURATION, NULL, 0); | ||
| 2638 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2639 | &response, 2); | ||
| 2640 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2641 | DRM_DEBUG_KMS("Incorrect SDVO get sat\n"); | ||
| 2642 | return; | ||
| 2643 | } | ||
| 2644 | sdvo_priv->max_saturation = data_value[0]; | ||
| 2645 | sdvo_priv->cur_saturation = response; | ||
| 2646 | sdvo_priv->saturation_property = | ||
| 2647 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2648 | "saturation", 2); | ||
| 2649 | sdvo_priv->saturation_property->values[0] = 0; | ||
| 2650 | sdvo_priv->saturation_property->values[1] = | ||
| 2651 | data_value[0]; | ||
| 2652 | drm_connector_attach_property(connector, | ||
| 2653 | sdvo_priv->saturation_property, | ||
| 2654 | sdvo_priv->cur_saturation); | ||
| 2655 | DRM_DEBUG_KMS("saturation: max %d, " | ||
| 2656 | "default %d, current %d\n", | ||
| 2657 | data_value[0], data_value[1], response); | ||
| 2658 | } | ||
| 2659 | if (sdvo_data.contrast) { | ||
| 2660 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2661 | SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); | ||
| 2662 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2663 | &data_value, 4); | ||
| 2664 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2665 | DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n"); | ||
| 2666 | return; | ||
| 2667 | } | ||
| 2668 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2669 | SDVO_CMD_GET_CONTRAST, NULL, 0); | ||
| 2670 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2671 | &response, 2); | ||
| 2672 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2673 | DRM_DEBUG_KMS("Incorrect SDVO get contrast\n"); | ||
| 2674 | return; | ||
| 2675 | } | ||
| 2676 | sdvo_priv->max_contrast = data_value[0]; | ||
| 2677 | sdvo_priv->cur_contrast = response; | ||
| 2678 | sdvo_priv->contrast_property = | ||
| 2679 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2680 | "contrast", 2); | ||
| 2681 | sdvo_priv->contrast_property->values[0] = 0; | ||
| 2682 | sdvo_priv->contrast_property->values[1] = data_value[0]; | ||
| 2683 | drm_connector_attach_property(connector, | ||
| 2684 | sdvo_priv->contrast_property, | ||
| 2685 | sdvo_priv->cur_contrast); | ||
| 2686 | DRM_DEBUG_KMS("contrast: max %d, " | ||
| 2687 | "default %d, current %d\n", | ||
| 2688 | data_value[0], data_value[1], response); | ||
| 2689 | } | ||
| 2690 | if (sdvo_data.hue) { | ||
| 2691 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2692 | SDVO_CMD_GET_MAX_HUE, NULL, 0); | ||
| 2693 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2694 | &data_value, 4); | ||
| 2695 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2696 | DRM_DEBUG_KMS("Incorrect SDVO Max hue\n"); | ||
| 2697 | return; | ||
| 2698 | } | ||
| 2699 | intel_sdvo_write_cmd(intel_encoder, | ||
| 2700 | SDVO_CMD_GET_HUE, NULL, 0); | ||
| 2701 | status = intel_sdvo_read_response(intel_encoder, | ||
| 2702 | &response, 2); | ||
| 2703 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
| 2704 | DRM_DEBUG_KMS("Incorrect SDVO get hue\n"); | ||
| 2705 | return; | ||
| 2706 | } | ||
| 2707 | sdvo_priv->max_hue = data_value[0]; | ||
| 2708 | sdvo_priv->cur_hue = response; | ||
| 2709 | sdvo_priv->hue_property = | ||
| 2710 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
| 2711 | "hue", 2); | ||
| 2712 | sdvo_priv->hue_property->values[0] = 0; | ||
| 2713 | sdvo_priv->hue_property->values[1] = | ||
| 2714 | data_value[0]; | ||
| 2715 | drm_connector_attach_property(connector, | ||
| 2716 | sdvo_priv->hue_property, | ||
| 2717 | sdvo_priv->cur_hue); | ||
| 2718 | DRM_DEBUG_KMS("hue: max %d, default %d, current %d\n", | ||
| 2719 | data_value[0], data_value[1], response); | ||
| 2720 | } | ||
| 2721 | } | 2461 | } |
| 2722 | if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) { | 2462 | |
| 2723 | if (sdvo_data.brightness) { | 2463 | return true; |
| 2724 | intel_sdvo_write_cmd(intel_encoder, | 2464 | } |
| 2725 | SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); | 2465 | |
| 2726 | status = intel_sdvo_read_response(intel_encoder, | 2466 | static bool |
| 2727 | &data_value, 4); | 2467 | intel_sdvo_create_enhance_property_lvds(struct intel_sdvo *intel_sdvo, |
| 2728 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2468 | struct intel_sdvo_connector *intel_sdvo_connector, |
| 2729 | DRM_DEBUG_KMS("Incorrect SDVO Max bright\n"); | 2469 | struct intel_sdvo_enhancements_reply enhancements) |
| 2730 | return; | 2470 | { |
| 2731 | } | 2471 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
| 2732 | intel_sdvo_write_cmd(intel_encoder, | 2472 | struct drm_connector *connector = &intel_sdvo_connector->base.base; |
| 2733 | SDVO_CMD_GET_BRIGHTNESS, NULL, 0); | 2473 | uint16_t response, data_value[2]; |
| 2734 | status = intel_sdvo_read_response(intel_encoder, | 2474 | |
| 2735 | &response, 2); | 2475 | ENHANCEMENT(brightness, BRIGHTNESS); |
| 2736 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2476 | |
| 2737 | DRM_DEBUG_KMS("Incorrect SDVO get brigh\n"); | 2477 | return true; |
| 2738 | return; | 2478 | } |
| 2739 | } | 2479 | #undef ENHANCEMENT |
| 2740 | sdvo_priv->max_brightness = data_value[0]; | 2480 | |
| 2741 | sdvo_priv->cur_brightness = response; | 2481 | static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, |
| 2742 | sdvo_priv->brightness_property = | 2482 | struct intel_sdvo_connector *intel_sdvo_connector) |
| 2743 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2483 | { |
| 2744 | "brightness", 2); | 2484 | union { |
| 2745 | sdvo_priv->brightness_property->values[0] = 0; | 2485 | struct intel_sdvo_enhancements_reply reply; |
| 2746 | sdvo_priv->brightness_property->values[1] = | 2486 | uint16_t response; |
| 2747 | data_value[0]; | 2487 | } enhancements; |
| 2748 | drm_connector_attach_property(connector, | 2488 | |
| 2749 | sdvo_priv->brightness_property, | 2489 | if (!intel_sdvo_get_value(intel_sdvo, |
| 2750 | sdvo_priv->cur_brightness); | 2490 | SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, |
| 2751 | DRM_DEBUG_KMS("brightness: max %d, " | 2491 | &enhancements, sizeof(enhancements))) |
| 2752 | "default %d, current %d\n", | 2492 | return false; |
| 2753 | data_value[0], data_value[1], response); | 2493 | |
| 2754 | } | 2494 | if (enhancements.response == 0) { |
| 2495 | DRM_DEBUG_KMS("No enhancement is supported\n"); | ||
| 2496 | return true; | ||
| 2755 | } | 2497 | } |
| 2756 | return; | 2498 | |
| 2499 | if (IS_TV(intel_sdvo_connector)) | ||
| 2500 | return intel_sdvo_create_enhance_property_tv(intel_sdvo, intel_sdvo_connector, enhancements.reply); | ||
| 2501 | else if(IS_LVDS(intel_sdvo_connector)) | ||
| 2502 | return intel_sdvo_create_enhance_property_lvds(intel_sdvo, intel_sdvo_connector, enhancements.reply); | ||
| 2503 | else | ||
| 2504 | return true; | ||
| 2505 | |||
| 2757 | } | 2506 | } |
| 2758 | 2507 | ||
| 2759 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | 2508 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) |
| 2760 | { | 2509 | { |
| 2761 | struct drm_i915_private *dev_priv = dev->dev_private; | 2510 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 2762 | struct intel_encoder *intel_encoder; | 2511 | struct intel_encoder *intel_encoder; |
| 2763 | struct intel_sdvo_priv *sdvo_priv; | 2512 | struct intel_sdvo *intel_sdvo; |
| 2764 | u8 ch[0x40]; | 2513 | u8 ch[0x40]; |
| 2765 | int i; | 2514 | int i; |
| 2766 | u32 i2c_reg, ddc_reg, analog_ddc_reg; | 2515 | u32 i2c_reg, ddc_reg, analog_ddc_reg; |
| 2767 | 2516 | ||
| 2768 | intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 2517 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); |
| 2769 | if (!intel_encoder) { | 2518 | if (!intel_sdvo) |
| 2770 | return false; | 2519 | return false; |
| 2771 | } | ||
| 2772 | 2520 | ||
| 2773 | sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1); | 2521 | intel_sdvo->sdvo_reg = sdvo_reg; |
| 2774 | sdvo_priv->sdvo_reg = sdvo_reg; | ||
| 2775 | 2522 | ||
| 2776 | intel_encoder->dev_priv = sdvo_priv; | 2523 | intel_encoder = &intel_sdvo->base; |
| 2777 | intel_encoder->type = INTEL_OUTPUT_SDVO; | 2524 | intel_encoder->type = INTEL_OUTPUT_SDVO; |
| 2778 | 2525 | ||
| 2779 | if (HAS_PCH_SPLIT(dev)) { | 2526 | if (HAS_PCH_SPLIT(dev)) { |
| @@ -2795,14 +2542,14 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
| 2795 | if (!intel_encoder->i2c_bus) | 2542 | if (!intel_encoder->i2c_bus) |
| 2796 | goto err_inteloutput; | 2543 | goto err_inteloutput; |
| 2797 | 2544 | ||
| 2798 | sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); | 2545 | intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); |
| 2799 | 2546 | ||
| 2800 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ | 2547 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ |
| 2801 | intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; | 2548 | intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; |
| 2802 | 2549 | ||
| 2803 | /* Read the regs to test if we can talk to the device */ | 2550 | /* Read the regs to test if we can talk to the device */ |
| 2804 | for (i = 0; i < 0x40; i++) { | 2551 | for (i = 0; i < 0x40; i++) { |
| 2805 | if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { | 2552 | if (!intel_sdvo_read_byte(intel_sdvo, i, &ch[i])) { |
| 2806 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", | 2553 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", |
| 2807 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); | 2554 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
| 2808 | goto err_i2c; | 2555 | goto err_i2c; |
| @@ -2812,17 +2559,16 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
| 2812 | /* setup the DDC bus. */ | 2559 | /* setup the DDC bus. */ |
| 2813 | if (IS_SDVOB(sdvo_reg)) { | 2560 | if (IS_SDVOB(sdvo_reg)) { |
| 2814 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); | 2561 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); |
| 2815 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, | 2562 | intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
| 2816 | "SDVOB/VGA DDC BUS"); | 2563 | "SDVOB/VGA DDC BUS"); |
| 2817 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; | 2564 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; |
| 2818 | } else { | 2565 | } else { |
| 2819 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); | 2566 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); |
| 2820 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, | 2567 | intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
| 2821 | "SDVOC/VGA DDC BUS"); | 2568 | "SDVOC/VGA DDC BUS"); |
| 2822 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | 2569 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; |
| 2823 | } | 2570 | } |
| 2824 | 2571 | if (intel_encoder->ddc_bus == NULL || intel_sdvo->analog_ddc_bus == NULL) | |
| 2825 | if (intel_encoder->ddc_bus == NULL) | ||
| 2826 | goto err_i2c; | 2572 | goto err_i2c; |
| 2827 | 2573 | ||
| 2828 | /* Wrap with our custom algo which switches to DDC mode */ | 2574 | /* Wrap with our custom algo which switches to DDC mode */ |
| @@ -2833,53 +2579,56 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
| 2833 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); | 2579 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); |
| 2834 | 2580 | ||
| 2835 | /* In default case sdvo lvds is false */ | 2581 | /* In default case sdvo lvds is false */ |
| 2836 | intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps); | 2582 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) |
| 2583 | goto err_enc; | ||
| 2837 | 2584 | ||
| 2838 | if (intel_sdvo_output_setup(intel_encoder, | 2585 | if (intel_sdvo_output_setup(intel_sdvo, |
| 2839 | sdvo_priv->caps.output_flags) != true) { | 2586 | intel_sdvo->caps.output_flags) != true) { |
| 2840 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", | 2587 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", |
| 2841 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); | 2588 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
| 2842 | goto err_i2c; | 2589 | goto err_enc; |
| 2843 | } | 2590 | } |
| 2844 | 2591 | ||
| 2845 | intel_sdvo_select_ddc_bus(dev_priv, sdvo_priv, sdvo_reg); | 2592 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); |
| 2846 | 2593 | ||
| 2847 | /* Set the input timing to the screen. Assume always input 0. */ | 2594 | /* Set the input timing to the screen. Assume always input 0. */ |
| 2848 | intel_sdvo_set_target_input(intel_encoder, true, false); | 2595 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
| 2849 | 2596 | goto err_enc; | |
| 2850 | intel_sdvo_get_input_pixel_clock_range(intel_encoder, | ||
| 2851 | &sdvo_priv->pixel_clock_min, | ||
| 2852 | &sdvo_priv->pixel_clock_max); | ||
| 2853 | 2597 | ||
| 2598 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, | ||
| 2599 | &intel_sdvo->pixel_clock_min, | ||
| 2600 | &intel_sdvo->pixel_clock_max)) | ||
| 2601 | goto err_enc; | ||
| 2854 | 2602 | ||
| 2855 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " | 2603 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " |
| 2856 | "clock range %dMHz - %dMHz, " | 2604 | "clock range %dMHz - %dMHz, " |
| 2857 | "input 1: %c, input 2: %c, " | 2605 | "input 1: %c, input 2: %c, " |
| 2858 | "output 1: %c, output 2: %c\n", | 2606 | "output 1: %c, output 2: %c\n", |
| 2859 | SDVO_NAME(sdvo_priv), | 2607 | SDVO_NAME(intel_sdvo), |
| 2860 | sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id, | 2608 | intel_sdvo->caps.vendor_id, intel_sdvo->caps.device_id, |
| 2861 | sdvo_priv->caps.device_rev_id, | 2609 | intel_sdvo->caps.device_rev_id, |
| 2862 | sdvo_priv->pixel_clock_min / 1000, | 2610 | intel_sdvo->pixel_clock_min / 1000, |
| 2863 | sdvo_priv->pixel_clock_max / 1000, | 2611 | intel_sdvo->pixel_clock_max / 1000, |
| 2864 | (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', | 2612 | (intel_sdvo->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', |
| 2865 | (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', | 2613 | (intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', |
| 2866 | /* check currently supported outputs */ | 2614 | /* check currently supported outputs */ |
| 2867 | sdvo_priv->caps.output_flags & | 2615 | intel_sdvo->caps.output_flags & |
| 2868 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', | 2616 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', |
| 2869 | sdvo_priv->caps.output_flags & | 2617 | intel_sdvo->caps.output_flags & |
| 2870 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); | 2618 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); |
| 2871 | |||
| 2872 | return true; | 2619 | return true; |
| 2873 | 2620 | ||
| 2621 | err_enc: | ||
| 2622 | drm_encoder_cleanup(&intel_encoder->enc); | ||
| 2874 | err_i2c: | 2623 | err_i2c: |
| 2875 | if (sdvo_priv->analog_ddc_bus != NULL) | 2624 | if (intel_sdvo->analog_ddc_bus != NULL) |
| 2876 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | 2625 | intel_i2c_destroy(intel_sdvo->analog_ddc_bus); |
| 2877 | if (intel_encoder->ddc_bus != NULL) | 2626 | if (intel_encoder->ddc_bus != NULL) |
| 2878 | intel_i2c_destroy(intel_encoder->ddc_bus); | 2627 | intel_i2c_destroy(intel_encoder->ddc_bus); |
| 2879 | if (intel_encoder->i2c_bus != NULL) | 2628 | if (intel_encoder->i2c_bus != NULL) |
| 2880 | intel_i2c_destroy(intel_encoder->i2c_bus); | 2629 | intel_i2c_destroy(intel_encoder->i2c_bus); |
| 2881 | err_inteloutput: | 2630 | err_inteloutput: |
| 2882 | kfree(intel_encoder); | 2631 | kfree(intel_sdvo); |
| 2883 | 2632 | ||
| 2884 | return false; | 2633 | return false; |
| 2885 | } | 2634 | } |
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index ba5cdf8ae40..a386b022e53 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h | |||
| @@ -312,7 +312,7 @@ struct intel_sdvo_set_target_input_args { | |||
| 312 | # define SDVO_CLOCK_RATE_MULT_4X (1 << 3) | 312 | # define SDVO_CLOCK_RATE_MULT_4X (1 << 3) |
| 313 | 313 | ||
| 314 | #define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 | 314 | #define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 |
| 315 | /** 5 bytes of bit flags for TV formats shared by all TV format functions */ | 315 | /** 6 bytes of bit flags for TV formats shared by all TV format functions */ |
| 316 | struct intel_sdvo_tv_format { | 316 | struct intel_sdvo_tv_format { |
| 317 | unsigned int ntsc_m:1; | 317 | unsigned int ntsc_m:1; |
| 318 | unsigned int ntsc_j:1; | 318 | unsigned int ntsc_j:1; |
| @@ -596,32 +596,32 @@ struct intel_sdvo_enhancements_reply { | |||
| 596 | unsigned int overscan_h:1; | 596 | unsigned int overscan_h:1; |
| 597 | 597 | ||
| 598 | unsigned int overscan_v:1; | 598 | unsigned int overscan_v:1; |
| 599 | unsigned int position_h:1; | 599 | unsigned int hpos:1; |
| 600 | unsigned int position_v:1; | 600 | unsigned int vpos:1; |
| 601 | unsigned int sharpness:1; | 601 | unsigned int sharpness:1; |
| 602 | unsigned int dot_crawl:1; | 602 | unsigned int dot_crawl:1; |
| 603 | unsigned int dither:1; | 603 | unsigned int dither:1; |
| 604 | unsigned int max_tv_chroma_filter:1; | 604 | unsigned int tv_chroma_filter:1; |
| 605 | unsigned int max_tv_luma_filter:1; | 605 | unsigned int tv_luma_filter:1; |
| 606 | } __attribute__((packed)); | 606 | } __attribute__((packed)); |
| 607 | 607 | ||
| 608 | /* Picture enhancement limits below are dependent on the current TV format, | 608 | /* Picture enhancement limits below are dependent on the current TV format, |
| 609 | * and thus need to be queried and set after it. | 609 | * and thus need to be queried and set after it. |
| 610 | */ | 610 | */ |
| 611 | #define SDVO_CMD_GET_MAX_FLICKER_FITER 0x4d | 611 | #define SDVO_CMD_GET_MAX_FLICKER_FILTER 0x4d |
| 612 | #define SDVO_CMD_GET_MAX_ADAPTIVE_FLICKER_FITER 0x7b | 612 | #define SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE 0x7b |
| 613 | #define SDVO_CMD_GET_MAX_2D_FLICKER_FITER 0x52 | 613 | #define SDVO_CMD_GET_MAX_FLICKER_FILTER_2D 0x52 |
| 614 | #define SDVO_CMD_GET_MAX_SATURATION 0x55 | 614 | #define SDVO_CMD_GET_MAX_SATURATION 0x55 |
| 615 | #define SDVO_CMD_GET_MAX_HUE 0x58 | 615 | #define SDVO_CMD_GET_MAX_HUE 0x58 |
| 616 | #define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b | 616 | #define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b |
| 617 | #define SDVO_CMD_GET_MAX_CONTRAST 0x5e | 617 | #define SDVO_CMD_GET_MAX_CONTRAST 0x5e |
| 618 | #define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 | 618 | #define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 |
| 619 | #define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 | 619 | #define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 |
| 620 | #define SDVO_CMD_GET_MAX_POSITION_H 0x67 | 620 | #define SDVO_CMD_GET_MAX_HPOS 0x67 |
| 621 | #define SDVO_CMD_GET_MAX_POSITION_V 0x6a | 621 | #define SDVO_CMD_GET_MAX_VPOS 0x6a |
| 622 | #define SDVO_CMD_GET_MAX_SHARPNESS_V 0x6d | 622 | #define SDVO_CMD_GET_MAX_SHARPNESS 0x6d |
| 623 | #define SDVO_CMD_GET_MAX_TV_CHROMA 0x74 | 623 | #define SDVO_CMD_GET_MAX_TV_CHROMA_FILTER 0x74 |
| 624 | #define SDVO_CMD_GET_MAX_TV_LUMA 0x77 | 624 | #define SDVO_CMD_GET_MAX_TV_LUMA_FILTER 0x77 |
| 625 | struct intel_sdvo_enhancement_limits_reply { | 625 | struct intel_sdvo_enhancement_limits_reply { |
| 626 | u16 max_value; | 626 | u16 max_value; |
| 627 | u16 default_value; | 627 | u16 default_value; |
| @@ -638,10 +638,10 @@ struct intel_sdvo_enhancement_limits_reply { | |||
| 638 | 638 | ||
| 639 | #define SDVO_CMD_GET_FLICKER_FILTER 0x4e | 639 | #define SDVO_CMD_GET_FLICKER_FILTER 0x4e |
| 640 | #define SDVO_CMD_SET_FLICKER_FILTER 0x4f | 640 | #define SDVO_CMD_SET_FLICKER_FILTER 0x4f |
| 641 | #define SDVO_CMD_GET_ADAPTIVE_FLICKER_FITER 0x50 | 641 | #define SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE 0x50 |
| 642 | #define SDVO_CMD_SET_ADAPTIVE_FLICKER_FITER 0x51 | 642 | #define SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE 0x51 |
| 643 | #define SDVO_CMD_GET_2D_FLICKER_FITER 0x53 | 643 | #define SDVO_CMD_GET_FLICKER_FILTER_2D 0x53 |
| 644 | #define SDVO_CMD_SET_2D_FLICKER_FITER 0x54 | 644 | #define SDVO_CMD_SET_FLICKER_FILTER_2D 0x54 |
| 645 | #define SDVO_CMD_GET_SATURATION 0x56 | 645 | #define SDVO_CMD_GET_SATURATION 0x56 |
| 646 | #define SDVO_CMD_SET_SATURATION 0x57 | 646 | #define SDVO_CMD_SET_SATURATION 0x57 |
| 647 | #define SDVO_CMD_GET_HUE 0x59 | 647 | #define SDVO_CMD_GET_HUE 0x59 |
| @@ -654,16 +654,16 @@ struct intel_sdvo_enhancement_limits_reply { | |||
| 654 | #define SDVO_CMD_SET_OVERSCAN_H 0x63 | 654 | #define SDVO_CMD_SET_OVERSCAN_H 0x63 |
| 655 | #define SDVO_CMD_GET_OVERSCAN_V 0x65 | 655 | #define SDVO_CMD_GET_OVERSCAN_V 0x65 |
| 656 | #define SDVO_CMD_SET_OVERSCAN_V 0x66 | 656 | #define SDVO_CMD_SET_OVERSCAN_V 0x66 |
| 657 | #define SDVO_CMD_GET_POSITION_H 0x68 | 657 | #define SDVO_CMD_GET_HPOS 0x68 |
| 658 | #define SDVO_CMD_SET_POSITION_H 0x69 | 658 | #define SDVO_CMD_SET_HPOS 0x69 |
| 659 | #define SDVO_CMD_GET_POSITION_V 0x6b | 659 | #define SDVO_CMD_GET_VPOS 0x6b |
| 660 | #define SDVO_CMD_SET_POSITION_V 0x6c | 660 | #define SDVO_CMD_SET_VPOS 0x6c |
| 661 | #define SDVO_CMD_GET_SHARPNESS 0x6e | 661 | #define SDVO_CMD_GET_SHARPNESS 0x6e |
| 662 | #define SDVO_CMD_SET_SHARPNESS 0x6f | 662 | #define SDVO_CMD_SET_SHARPNESS 0x6f |
| 663 | #define SDVO_CMD_GET_TV_CHROMA 0x75 | 663 | #define SDVO_CMD_GET_TV_CHROMA_FILTER 0x75 |
| 664 | #define SDVO_CMD_SET_TV_CHROMA 0x76 | 664 | #define SDVO_CMD_SET_TV_CHROMA_FILTER 0x76 |
| 665 | #define SDVO_CMD_GET_TV_LUMA 0x78 | 665 | #define SDVO_CMD_GET_TV_LUMA_FILTER 0x78 |
| 666 | #define SDVO_CMD_SET_TV_LUMA 0x79 | 666 | #define SDVO_CMD_SET_TV_LUMA_FILTER 0x79 |
| 667 | struct intel_sdvo_enhancements_arg { | 667 | struct intel_sdvo_enhancements_arg { |
| 668 | u16 value; | 668 | u16 value; |
| 669 | }__attribute__((packed)); | 669 | }__attribute__((packed)); |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index cc3726a4a1c..d2029efee98 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
| @@ -44,7 +44,9 @@ enum tv_margin { | |||
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | /** Private structure for the integrated TV support */ | 46 | /** Private structure for the integrated TV support */ |
| 47 | struct intel_tv_priv { | 47 | struct intel_tv { |
| 48 | struct intel_encoder base; | ||
| 49 | |||
| 48 | int type; | 50 | int type; |
| 49 | char *tv_format; | 51 | char *tv_format; |
| 50 | int margin[4]; | 52 | int margin[4]; |
| @@ -896,6 +898,11 @@ static const struct tv_mode tv_modes[] = { | |||
| 896 | }, | 898 | }, |
| 897 | }; | 899 | }; |
| 898 | 900 | ||
| 901 | static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) | ||
| 902 | { | ||
| 903 | return container_of(enc_to_intel_encoder(encoder), struct intel_tv, base); | ||
| 904 | } | ||
| 905 | |||
| 899 | static void | 906 | static void |
| 900 | intel_tv_dpms(struct drm_encoder *encoder, int mode) | 907 | intel_tv_dpms(struct drm_encoder *encoder, int mode) |
| 901 | { | 908 | { |
| @@ -929,19 +936,17 @@ intel_tv_mode_lookup (char *tv_format) | |||
| 929 | } | 936 | } |
| 930 | 937 | ||
| 931 | static const struct tv_mode * | 938 | static const struct tv_mode * |
| 932 | intel_tv_mode_find (struct intel_encoder *intel_encoder) | 939 | intel_tv_mode_find (struct intel_tv *intel_tv) |
| 933 | { | 940 | { |
| 934 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 941 | return intel_tv_mode_lookup(intel_tv->tv_format); |
| 935 | |||
| 936 | return intel_tv_mode_lookup(tv_priv->tv_format); | ||
| 937 | } | 942 | } |
| 938 | 943 | ||
| 939 | static enum drm_mode_status | 944 | static enum drm_mode_status |
| 940 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) | 945 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) |
| 941 | { | 946 | { |
| 942 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 947 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 943 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 948 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 944 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 949 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
| 945 | 950 | ||
| 946 | /* Ensure TV refresh is close to desired refresh */ | 951 | /* Ensure TV refresh is close to desired refresh */ |
| 947 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) | 952 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) |
| @@ -957,8 +962,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 957 | { | 962 | { |
| 958 | struct drm_device *dev = encoder->dev; | 963 | struct drm_device *dev = encoder->dev; |
| 959 | struct drm_mode_config *drm_config = &dev->mode_config; | 964 | struct drm_mode_config *drm_config = &dev->mode_config; |
| 960 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 965 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 961 | const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder); | 966 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
| 962 | struct drm_encoder *other_encoder; | 967 | struct drm_encoder *other_encoder; |
| 963 | 968 | ||
| 964 | if (!tv_mode) | 969 | if (!tv_mode) |
| @@ -983,9 +988,8 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 983 | struct drm_i915_private *dev_priv = dev->dev_private; | 988 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 984 | struct drm_crtc *crtc = encoder->crtc; | 989 | struct drm_crtc *crtc = encoder->crtc; |
| 985 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 990 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 986 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 991 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 987 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 992 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
| 988 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | ||
| 989 | u32 tv_ctl; | 993 | u32 tv_ctl; |
| 990 | u32 hctl1, hctl2, hctl3; | 994 | u32 hctl1, hctl2, hctl3; |
| 991 | u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; | 995 | u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; |
| @@ -1001,7 +1005,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 1001 | tv_ctl = I915_READ(TV_CTL); | 1005 | tv_ctl = I915_READ(TV_CTL); |
| 1002 | tv_ctl &= TV_CTL_SAVE; | 1006 | tv_ctl &= TV_CTL_SAVE; |
| 1003 | 1007 | ||
| 1004 | switch (tv_priv->type) { | 1008 | switch (intel_tv->type) { |
| 1005 | default: | 1009 | default: |
| 1006 | case DRM_MODE_CONNECTOR_Unknown: | 1010 | case DRM_MODE_CONNECTOR_Unknown: |
| 1007 | case DRM_MODE_CONNECTOR_Composite: | 1011 | case DRM_MODE_CONNECTOR_Composite: |
| @@ -1154,11 +1158,11 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 1154 | 1158 | ||
| 1155 | /* Wait for vblank for the disable to take effect */ | 1159 | /* Wait for vblank for the disable to take effect */ |
| 1156 | if (!IS_I9XX(dev)) | 1160 | if (!IS_I9XX(dev)) |
| 1157 | intel_wait_for_vblank(dev); | 1161 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 1158 | 1162 | ||
| 1159 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); | 1163 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); |
| 1160 | /* Wait for vblank for the disable to take effect. */ | 1164 | /* Wait for vblank for the disable to take effect. */ |
| 1161 | intel_wait_for_vblank(dev); | 1165 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 1162 | 1166 | ||
| 1163 | /* Filter ctl must be set before TV_WIN_SIZE */ | 1167 | /* Filter ctl must be set before TV_WIN_SIZE */ |
| 1164 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); | 1168 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); |
| @@ -1168,12 +1172,12 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 1168 | else | 1172 | else |
| 1169 | ysize = 2*tv_mode->nbr_end + 1; | 1173 | ysize = 2*tv_mode->nbr_end + 1; |
| 1170 | 1174 | ||
| 1171 | xpos += tv_priv->margin[TV_MARGIN_LEFT]; | 1175 | xpos += intel_tv->margin[TV_MARGIN_LEFT]; |
| 1172 | ypos += tv_priv->margin[TV_MARGIN_TOP]; | 1176 | ypos += intel_tv->margin[TV_MARGIN_TOP]; |
| 1173 | xsize -= (tv_priv->margin[TV_MARGIN_LEFT] + | 1177 | xsize -= (intel_tv->margin[TV_MARGIN_LEFT] + |
| 1174 | tv_priv->margin[TV_MARGIN_RIGHT]); | 1178 | intel_tv->margin[TV_MARGIN_RIGHT]); |
| 1175 | ysize -= (tv_priv->margin[TV_MARGIN_TOP] + | 1179 | ysize -= (intel_tv->margin[TV_MARGIN_TOP] + |
| 1176 | tv_priv->margin[TV_MARGIN_BOTTOM]); | 1180 | intel_tv->margin[TV_MARGIN_BOTTOM]); |
| 1177 | I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos); | 1181 | I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos); |
| 1178 | I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize); | 1182 | I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize); |
| 1179 | 1183 | ||
| @@ -1222,11 +1226,12 @@ static const struct drm_display_mode reported_modes[] = { | |||
| 1222 | * \return false if TV is disconnected. | 1226 | * \return false if TV is disconnected. |
| 1223 | */ | 1227 | */ |
| 1224 | static int | 1228 | static int |
| 1225 | intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder) | 1229 | intel_tv_detect_type (struct intel_tv *intel_tv) |
| 1226 | { | 1230 | { |
| 1227 | struct drm_encoder *encoder = &intel_encoder->enc; | 1231 | struct drm_encoder *encoder = &intel_tv->base.enc; |
| 1228 | struct drm_device *dev = encoder->dev; | 1232 | struct drm_device *dev = encoder->dev; |
| 1229 | struct drm_i915_private *dev_priv = dev->dev_private; | 1233 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1234 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
| 1230 | unsigned long irqflags; | 1235 | unsigned long irqflags; |
| 1231 | u32 tv_ctl, save_tv_ctl; | 1236 | u32 tv_ctl, save_tv_ctl; |
| 1232 | u32 tv_dac, save_tv_dac; | 1237 | u32 tv_dac, save_tv_dac; |
| @@ -1263,11 +1268,11 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
| 1263 | DAC_C_0_7_V); | 1268 | DAC_C_0_7_V); |
| 1264 | I915_WRITE(TV_CTL, tv_ctl); | 1269 | I915_WRITE(TV_CTL, tv_ctl); |
| 1265 | I915_WRITE(TV_DAC, tv_dac); | 1270 | I915_WRITE(TV_DAC, tv_dac); |
| 1266 | intel_wait_for_vblank(dev); | 1271 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 1267 | tv_dac = I915_READ(TV_DAC); | 1272 | tv_dac = I915_READ(TV_DAC); |
| 1268 | I915_WRITE(TV_DAC, save_tv_dac); | 1273 | I915_WRITE(TV_DAC, save_tv_dac); |
| 1269 | I915_WRITE(TV_CTL, save_tv_ctl); | 1274 | I915_WRITE(TV_CTL, save_tv_ctl); |
| 1270 | intel_wait_for_vblank(dev); | 1275 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 1271 | /* | 1276 | /* |
| 1272 | * A B C | 1277 | * A B C |
| 1273 | * 0 1 1 Composite | 1278 | * 0 1 1 Composite |
| @@ -1304,12 +1309,11 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
| 1304 | static void intel_tv_find_better_format(struct drm_connector *connector) | 1309 | static void intel_tv_find_better_format(struct drm_connector *connector) |
| 1305 | { | 1310 | { |
| 1306 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1311 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1307 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1312 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 1308 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 1313 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
| 1309 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | ||
| 1310 | int i; | 1314 | int i; |
| 1311 | 1315 | ||
| 1312 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == | 1316 | if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) == |
| 1313 | tv_mode->component_only) | 1317 | tv_mode->component_only) |
| 1314 | return; | 1318 | return; |
| 1315 | 1319 | ||
| @@ -1317,12 +1321,12 @@ static void intel_tv_find_better_format(struct drm_connector *connector) | |||
| 1317 | for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { | 1321 | for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { |
| 1318 | tv_mode = tv_modes + i; | 1322 | tv_mode = tv_modes + i; |
| 1319 | 1323 | ||
| 1320 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == | 1324 | if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) == |
| 1321 | tv_mode->component_only) | 1325 | tv_mode->component_only) |
| 1322 | break; | 1326 | break; |
| 1323 | } | 1327 | } |
| 1324 | 1328 | ||
| 1325 | tv_priv->tv_format = tv_mode->name; | 1329 | intel_tv->tv_format = tv_mode->name; |
| 1326 | drm_connector_property_set_value(connector, | 1330 | drm_connector_property_set_value(connector, |
| 1327 | connector->dev->mode_config.tv_mode_property, i); | 1331 | connector->dev->mode_config.tv_mode_property, i); |
| 1328 | } | 1332 | } |
| @@ -1336,31 +1340,31 @@ static void intel_tv_find_better_format(struct drm_connector *connector) | |||
| 1336 | static enum drm_connector_status | 1340 | static enum drm_connector_status |
| 1337 | intel_tv_detect(struct drm_connector *connector) | 1341 | intel_tv_detect(struct drm_connector *connector) |
| 1338 | { | 1342 | { |
| 1339 | struct drm_crtc *crtc; | ||
| 1340 | struct drm_display_mode mode; | 1343 | struct drm_display_mode mode; |
| 1341 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1344 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1342 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1345 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 1343 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 1346 | int type; |
| 1344 | int dpms_mode; | ||
| 1345 | int type = tv_priv->type; | ||
| 1346 | 1347 | ||
| 1347 | mode = reported_modes[0]; | 1348 | mode = reported_modes[0]; |
| 1348 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); | 1349 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); |
| 1349 | 1350 | ||
| 1350 | if (encoder->crtc && encoder->crtc->enabled) { | 1351 | if (encoder->crtc && encoder->crtc->enabled) { |
| 1351 | type = intel_tv_detect_type(encoder->crtc, intel_encoder); | 1352 | type = intel_tv_detect_type(intel_tv); |
| 1352 | } else { | 1353 | } else { |
| 1353 | crtc = intel_get_load_detect_pipe(intel_encoder, connector, | 1354 | struct drm_crtc *crtc; |
| 1355 | int dpms_mode; | ||
| 1356 | |||
| 1357 | crtc = intel_get_load_detect_pipe(&intel_tv->base, connector, | ||
| 1354 | &mode, &dpms_mode); | 1358 | &mode, &dpms_mode); |
| 1355 | if (crtc) { | 1359 | if (crtc) { |
| 1356 | type = intel_tv_detect_type(crtc, intel_encoder); | 1360 | type = intel_tv_detect_type(intel_tv); |
| 1357 | intel_release_load_detect_pipe(intel_encoder, connector, | 1361 | intel_release_load_detect_pipe(&intel_tv->base, connector, |
| 1358 | dpms_mode); | 1362 | dpms_mode); |
| 1359 | } else | 1363 | } else |
| 1360 | type = -1; | 1364 | type = -1; |
| 1361 | } | 1365 | } |
| 1362 | 1366 | ||
| 1363 | tv_priv->type = type; | 1367 | intel_tv->type = type; |
| 1364 | 1368 | ||
| 1365 | if (type < 0) | 1369 | if (type < 0) |
| 1366 | return connector_status_disconnected; | 1370 | return connector_status_disconnected; |
| @@ -1391,8 +1395,8 @@ intel_tv_chose_preferred_modes(struct drm_connector *connector, | |||
| 1391 | struct drm_display_mode *mode_ptr) | 1395 | struct drm_display_mode *mode_ptr) |
| 1392 | { | 1396 | { |
| 1393 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1397 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1394 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1398 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 1395 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 1399 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
| 1396 | 1400 | ||
| 1397 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) | 1401 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) |
| 1398 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; | 1402 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; |
| @@ -1417,8 +1421,8 @@ intel_tv_get_modes(struct drm_connector *connector) | |||
| 1417 | { | 1421 | { |
| 1418 | struct drm_display_mode *mode_ptr; | 1422 | struct drm_display_mode *mode_ptr; |
| 1419 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1423 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1420 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1424 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 1421 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 1425 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
| 1422 | int j, count = 0; | 1426 | int j, count = 0; |
| 1423 | u64 tmp; | 1427 | u64 tmp; |
| 1424 | 1428 | ||
| @@ -1483,8 +1487,7 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
| 1483 | { | 1487 | { |
| 1484 | struct drm_device *dev = connector->dev; | 1488 | struct drm_device *dev = connector->dev; |
| 1485 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1489 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
| 1486 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1490 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 1487 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | ||
| 1488 | struct drm_crtc *crtc = encoder->crtc; | 1491 | struct drm_crtc *crtc = encoder->crtc; |
| 1489 | int ret = 0; | 1492 | int ret = 0; |
| 1490 | bool changed = false; | 1493 | bool changed = false; |
| @@ -1494,30 +1497,30 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
| 1494 | goto out; | 1497 | goto out; |
| 1495 | 1498 | ||
| 1496 | if (property == dev->mode_config.tv_left_margin_property && | 1499 | if (property == dev->mode_config.tv_left_margin_property && |
| 1497 | tv_priv->margin[TV_MARGIN_LEFT] != val) { | 1500 | intel_tv->margin[TV_MARGIN_LEFT] != val) { |
| 1498 | tv_priv->margin[TV_MARGIN_LEFT] = val; | 1501 | intel_tv->margin[TV_MARGIN_LEFT] = val; |
| 1499 | changed = true; | 1502 | changed = true; |
| 1500 | } else if (property == dev->mode_config.tv_right_margin_property && | 1503 | } else if (property == dev->mode_config.tv_right_margin_property && |
| 1501 | tv_priv->margin[TV_MARGIN_RIGHT] != val) { | 1504 | intel_tv->margin[TV_MARGIN_RIGHT] != val) { |
| 1502 | tv_priv->margin[TV_MARGIN_RIGHT] = val; | 1505 | intel_tv->margin[TV_MARGIN_RIGHT] = val; |
| 1503 | changed = true; | 1506 | changed = true; |
| 1504 | } else if (property == dev->mode_config.tv_top_margin_property && | 1507 | } else if (property == dev->mode_config.tv_top_margin_property && |
| 1505 | tv_priv->margin[TV_MARGIN_TOP] != val) { | 1508 | intel_tv->margin[TV_MARGIN_TOP] != val) { |
| 1506 | tv_priv->margin[TV_MARGIN_TOP] = val; | 1509 | intel_tv->margin[TV_MARGIN_TOP] = val; |
| 1507 | changed = true; | 1510 | changed = true; |
| 1508 | } else if (property == dev->mode_config.tv_bottom_margin_property && | 1511 | } else if (property == dev->mode_config.tv_bottom_margin_property && |
| 1509 | tv_priv->margin[TV_MARGIN_BOTTOM] != val) { | 1512 | intel_tv->margin[TV_MARGIN_BOTTOM] != val) { |
| 1510 | tv_priv->margin[TV_MARGIN_BOTTOM] = val; | 1513 | intel_tv->margin[TV_MARGIN_BOTTOM] = val; |
| 1511 | changed = true; | 1514 | changed = true; |
| 1512 | } else if (property == dev->mode_config.tv_mode_property) { | 1515 | } else if (property == dev->mode_config.tv_mode_property) { |
| 1513 | if (val >= ARRAY_SIZE(tv_modes)) { | 1516 | if (val >= ARRAY_SIZE(tv_modes)) { |
| 1514 | ret = -EINVAL; | 1517 | ret = -EINVAL; |
| 1515 | goto out; | 1518 | goto out; |
| 1516 | } | 1519 | } |
| 1517 | if (!strcmp(tv_priv->tv_format, tv_modes[val].name)) | 1520 | if (!strcmp(intel_tv->tv_format, tv_modes[val].name)) |
| 1518 | goto out; | 1521 | goto out; |
| 1519 | 1522 | ||
| 1520 | tv_priv->tv_format = tv_modes[val].name; | 1523 | intel_tv->tv_format = tv_modes[val].name; |
| 1521 | changed = true; | 1524 | changed = true; |
| 1522 | } else { | 1525 | } else { |
| 1523 | ret = -EINVAL; | 1526 | ret = -EINVAL; |
| @@ -1553,16 +1556,8 @@ static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = | |||
| 1553 | .best_encoder = intel_attached_encoder, | 1556 | .best_encoder = intel_attached_encoder, |
| 1554 | }; | 1557 | }; |
| 1555 | 1558 | ||
| 1556 | static void intel_tv_enc_destroy(struct drm_encoder *encoder) | ||
| 1557 | { | ||
| 1558 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
| 1559 | |||
| 1560 | drm_encoder_cleanup(encoder); | ||
| 1561 | kfree(intel_encoder); | ||
| 1562 | } | ||
| 1563 | |||
| 1564 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { | 1559 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { |
| 1565 | .destroy = intel_tv_enc_destroy, | 1560 | .destroy = intel_encoder_destroy, |
| 1566 | }; | 1561 | }; |
| 1567 | 1562 | ||
| 1568 | /* | 1563 | /* |
| @@ -1606,9 +1601,9 @@ intel_tv_init(struct drm_device *dev) | |||
| 1606 | { | 1601 | { |
| 1607 | struct drm_i915_private *dev_priv = dev->dev_private; | 1602 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1608 | struct drm_connector *connector; | 1603 | struct drm_connector *connector; |
| 1604 | struct intel_tv *intel_tv; | ||
| 1609 | struct intel_encoder *intel_encoder; | 1605 | struct intel_encoder *intel_encoder; |
| 1610 | struct intel_connector *intel_connector; | 1606 | struct intel_connector *intel_connector; |
| 1611 | struct intel_tv_priv *tv_priv; | ||
| 1612 | u32 tv_dac_on, tv_dac_off, save_tv_dac; | 1607 | u32 tv_dac_on, tv_dac_off, save_tv_dac; |
| 1613 | char **tv_format_names; | 1608 | char **tv_format_names; |
| 1614 | int i, initial_mode = 0; | 1609 | int i, initial_mode = 0; |
| @@ -1647,18 +1642,18 @@ intel_tv_init(struct drm_device *dev) | |||
| 1647 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) | 1642 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) |
| 1648 | return; | 1643 | return; |
| 1649 | 1644 | ||
| 1650 | intel_encoder = kzalloc(sizeof(struct intel_encoder) + | 1645 | intel_tv = kzalloc(sizeof(struct intel_tv), GFP_KERNEL); |
| 1651 | sizeof(struct intel_tv_priv), GFP_KERNEL); | 1646 | if (!intel_tv) { |
| 1652 | if (!intel_encoder) { | ||
| 1653 | return; | 1647 | return; |
| 1654 | } | 1648 | } |
| 1655 | 1649 | ||
| 1656 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 1650 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
| 1657 | if (!intel_connector) { | 1651 | if (!intel_connector) { |
| 1658 | kfree(intel_encoder); | 1652 | kfree(intel_tv); |
| 1659 | return; | 1653 | return; |
| 1660 | } | 1654 | } |
| 1661 | 1655 | ||
| 1656 | intel_encoder = &intel_tv->base; | ||
| 1662 | connector = &intel_connector->base; | 1657 | connector = &intel_connector->base; |
| 1663 | 1658 | ||
| 1664 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1659 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
| @@ -1668,22 +1663,20 @@ intel_tv_init(struct drm_device *dev) | |||
| 1668 | DRM_MODE_ENCODER_TVDAC); | 1663 | DRM_MODE_ENCODER_TVDAC); |
| 1669 | 1664 | ||
| 1670 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); | 1665 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); |
| 1671 | tv_priv = (struct intel_tv_priv *)(intel_encoder + 1); | ||
| 1672 | intel_encoder->type = INTEL_OUTPUT_TVOUT; | 1666 | intel_encoder->type = INTEL_OUTPUT_TVOUT; |
| 1673 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1667 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
| 1674 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); | 1668 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); |
| 1675 | intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); | 1669 | intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); |
| 1676 | intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); | 1670 | intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); |
| 1677 | intel_encoder->dev_priv = tv_priv; | 1671 | intel_tv->type = DRM_MODE_CONNECTOR_Unknown; |
| 1678 | tv_priv->type = DRM_MODE_CONNECTOR_Unknown; | ||
| 1679 | 1672 | ||
| 1680 | /* BIOS margin values */ | 1673 | /* BIOS margin values */ |
| 1681 | tv_priv->margin[TV_MARGIN_LEFT] = 54; | 1674 | intel_tv->margin[TV_MARGIN_LEFT] = 54; |
| 1682 | tv_priv->margin[TV_MARGIN_TOP] = 36; | 1675 | intel_tv->margin[TV_MARGIN_TOP] = 36; |
| 1683 | tv_priv->margin[TV_MARGIN_RIGHT] = 46; | 1676 | intel_tv->margin[TV_MARGIN_RIGHT] = 46; |
| 1684 | tv_priv->margin[TV_MARGIN_BOTTOM] = 37; | 1677 | intel_tv->margin[TV_MARGIN_BOTTOM] = 37; |
| 1685 | 1678 | ||
| 1686 | tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); | 1679 | intel_tv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); |
| 1687 | 1680 | ||
| 1688 | drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); | 1681 | drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); |
| 1689 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); | 1682 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); |
| @@ -1703,16 +1696,16 @@ intel_tv_init(struct drm_device *dev) | |||
| 1703 | initial_mode); | 1696 | initial_mode); |
| 1704 | drm_connector_attach_property(connector, | 1697 | drm_connector_attach_property(connector, |
| 1705 | dev->mode_config.tv_left_margin_property, | 1698 | dev->mode_config.tv_left_margin_property, |
| 1706 | tv_priv->margin[TV_MARGIN_LEFT]); | 1699 | intel_tv->margin[TV_MARGIN_LEFT]); |
| 1707 | drm_connector_attach_property(connector, | 1700 | drm_connector_attach_property(connector, |
| 1708 | dev->mode_config.tv_top_margin_property, | 1701 | dev->mode_config.tv_top_margin_property, |
| 1709 | tv_priv->margin[TV_MARGIN_TOP]); | 1702 | intel_tv->margin[TV_MARGIN_TOP]); |
| 1710 | drm_connector_attach_property(connector, | 1703 | drm_connector_attach_property(connector, |
| 1711 | dev->mode_config.tv_right_margin_property, | 1704 | dev->mode_config.tv_right_margin_property, |
| 1712 | tv_priv->margin[TV_MARGIN_RIGHT]); | 1705 | intel_tv->margin[TV_MARGIN_RIGHT]); |
| 1713 | drm_connector_attach_property(connector, | 1706 | drm_connector_attach_property(connector, |
| 1714 | dev->mode_config.tv_bottom_margin_property, | 1707 | dev->mode_config.tv_bottom_margin_property, |
| 1715 | tv_priv->margin[TV_MARGIN_BOTTOM]); | 1708 | intel_tv->margin[TV_MARGIN_BOTTOM]); |
| 1716 | out: | 1709 | out: |
| 1717 | drm_sysfs_connector_add(connector); | 1710 | drm_sysfs_connector_add(connector); |
| 1718 | } | 1711 | } |
