diff options
Diffstat (limited to 'drivers/gpu/drm/i915')
22 files changed, 2219 insertions, 542 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f112c769d533..50d1f782768c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -846,7 +846,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
846 | return 0; | 846 | return 0; |
847 | } | 847 | } |
848 | 848 | ||
849 | printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws->addr); | 849 | DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr); |
850 | 850 | ||
851 | dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); | 851 | dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); |
852 | 852 | ||
@@ -885,8 +885,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
885 | * some RAM for the framebuffer at early boot. This code figures out | 885 | * some RAM for the framebuffer at early boot. This code figures out |
886 | * how much was set aside so we can use it for our own purposes. | 886 | * how much was set aside so we can use it for our own purposes. |
887 | */ | 887 | */ |
888 | static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size, | 888 | static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, |
889 | unsigned long *preallocated_size) | 889 | uint32_t *preallocated_size) |
890 | { | 890 | { |
891 | struct pci_dev *bridge_dev; | 891 | struct pci_dev *bridge_dev; |
892 | u16 tmp = 0; | 892 | u16 tmp = 0; |
@@ -984,10 +984,11 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size, | |||
984 | return 0; | 984 | return 0; |
985 | } | 985 | } |
986 | 986 | ||
987 | static int i915_load_modeset_init(struct drm_device *dev) | 987 | static int i915_load_modeset_init(struct drm_device *dev, |
988 | unsigned long prealloc_size, | ||
989 | unsigned long agp_size) | ||
988 | { | 990 | { |
989 | struct drm_i915_private *dev_priv = dev->dev_private; | 991 | struct drm_i915_private *dev_priv = dev->dev_private; |
990 | unsigned long agp_size, prealloc_size; | ||
991 | int fb_bar = IS_I9XX(dev) ? 2 : 0; | 992 | int fb_bar = IS_I9XX(dev) ? 2 : 0; |
992 | int ret = 0; | 993 | int ret = 0; |
993 | 994 | ||
@@ -1002,10 +1003,6 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1002 | if (IS_I965G(dev) || IS_G33(dev)) | 1003 | if (IS_I965G(dev) || IS_G33(dev)) |
1003 | dev_priv->cursor_needs_physical = false; | 1004 | dev_priv->cursor_needs_physical = false; |
1004 | 1005 | ||
1005 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size); | ||
1006 | if (ret) | ||
1007 | goto out; | ||
1008 | |||
1009 | /* Basic memrange allocator for stolen space (aka vram) */ | 1006 | /* Basic memrange allocator for stolen space (aka vram) */ |
1010 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); | 1007 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); |
1011 | 1008 | ||
@@ -1082,6 +1079,44 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) | |||
1082 | master->driver_priv = NULL; | 1079 | master->driver_priv = NULL; |
1083 | } | 1080 | } |
1084 | 1081 | ||
1082 | static void i915_get_mem_freq(struct drm_device *dev) | ||
1083 | { | ||
1084 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1085 | u32 tmp; | ||
1086 | |||
1087 | if (!IS_IGD(dev)) | ||
1088 | return; | ||
1089 | |||
1090 | tmp = I915_READ(CLKCFG); | ||
1091 | |||
1092 | switch (tmp & CLKCFG_FSB_MASK) { | ||
1093 | case CLKCFG_FSB_533: | ||
1094 | dev_priv->fsb_freq = 533; /* 133*4 */ | ||
1095 | break; | ||
1096 | case CLKCFG_FSB_800: | ||
1097 | dev_priv->fsb_freq = 800; /* 200*4 */ | ||
1098 | break; | ||
1099 | case CLKCFG_FSB_667: | ||
1100 | dev_priv->fsb_freq = 667; /* 167*4 */ | ||
1101 | break; | ||
1102 | case CLKCFG_FSB_400: | ||
1103 | dev_priv->fsb_freq = 400; /* 100*4 */ | ||
1104 | break; | ||
1105 | } | ||
1106 | |||
1107 | switch (tmp & CLKCFG_MEM_MASK) { | ||
1108 | case CLKCFG_MEM_533: | ||
1109 | dev_priv->mem_freq = 533; | ||
1110 | break; | ||
1111 | case CLKCFG_MEM_667: | ||
1112 | dev_priv->mem_freq = 667; | ||
1113 | break; | ||
1114 | case CLKCFG_MEM_800: | ||
1115 | dev_priv->mem_freq = 800; | ||
1116 | break; | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1085 | /** | 1120 | /** |
1086 | * i915_driver_load - setup chip and create an initial config | 1121 | * i915_driver_load - setup chip and create an initial config |
1087 | * @dev: DRM device | 1122 | * @dev: DRM device |
@@ -1098,6 +1133,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1098 | struct drm_i915_private *dev_priv = dev->dev_private; | 1133 | struct drm_i915_private *dev_priv = dev->dev_private; |
1099 | resource_size_t base, size; | 1134 | resource_size_t base, size; |
1100 | int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; | 1135 | int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; |
1136 | uint32_t agp_size, prealloc_size; | ||
1101 | 1137 | ||
1102 | /* i915 has 4 more counters */ | 1138 | /* i915 has 4 more counters */ |
1103 | dev->counters += 4; | 1139 | dev->counters += 4; |
@@ -1146,9 +1182,29 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1146 | "performance may suffer.\n"); | 1182 | "performance may suffer.\n"); |
1147 | } | 1183 | } |
1148 | 1184 | ||
1185 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size); | ||
1186 | if (ret) | ||
1187 | goto out_iomapfree; | ||
1188 | |||
1189 | dev_priv->wq = create_workqueue("i915"); | ||
1190 | if (dev_priv->wq == NULL) { | ||
1191 | DRM_ERROR("Failed to create our workqueue.\n"); | ||
1192 | ret = -ENOMEM; | ||
1193 | goto out_iomapfree; | ||
1194 | } | ||
1195 | |||
1149 | /* enable GEM by default */ | 1196 | /* enable GEM by default */ |
1150 | dev_priv->has_gem = 1; | 1197 | dev_priv->has_gem = 1; |
1151 | 1198 | ||
1199 | if (prealloc_size > agp_size * 3 / 4) { | ||
1200 | DRM_ERROR("Detected broken video BIOS with %d/%dkB of video " | ||
1201 | "memory stolen.\n", | ||
1202 | prealloc_size / 1024, agp_size / 1024); | ||
1203 | DRM_ERROR("Disabling GEM. (try reducing stolen memory or " | ||
1204 | "updating the BIOS to fix).\n"); | ||
1205 | dev_priv->has_gem = 0; | ||
1206 | } | ||
1207 | |||
1152 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | 1208 | dev->driver->get_vblank_counter = i915_get_vblank_counter; |
1153 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | 1209 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
1154 | if (IS_G4X(dev) || IS_IGDNG(dev)) { | 1210 | if (IS_G4X(dev) || IS_IGDNG(dev)) { |
@@ -1162,9 +1218,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1162 | if (!I915_NEED_GFX_HWS(dev)) { | 1218 | if (!I915_NEED_GFX_HWS(dev)) { |
1163 | ret = i915_init_phys_hws(dev); | 1219 | ret = i915_init_phys_hws(dev); |
1164 | if (ret != 0) | 1220 | if (ret != 0) |
1165 | goto out_iomapfree; | 1221 | goto out_workqueue_free; |
1166 | } | 1222 | } |
1167 | 1223 | ||
1224 | i915_get_mem_freq(dev); | ||
1225 | |||
1168 | /* On the 945G/GM, the chipset reports the MSI capability on the | 1226 | /* On the 945G/GM, the chipset reports the MSI capability on the |
1169 | * integrated graphics even though the support isn't actually there | 1227 | * integrated graphics even though the support isn't actually there |
1170 | * according to the published specs. It doesn't appear to function | 1228 | * according to the published specs. It doesn't appear to function |
@@ -1180,6 +1238,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1180 | pci_enable_msi(dev->pdev); | 1238 | pci_enable_msi(dev->pdev); |
1181 | 1239 | ||
1182 | spin_lock_init(&dev_priv->user_irq_lock); | 1240 | spin_lock_init(&dev_priv->user_irq_lock); |
1241 | spin_lock_init(&dev_priv->error_lock); | ||
1183 | dev_priv->user_irq_refcount = 0; | 1242 | dev_priv->user_irq_refcount = 0; |
1184 | 1243 | ||
1185 | ret = drm_vblank_init(dev, I915_NUM_PIPE); | 1244 | ret = drm_vblank_init(dev, I915_NUM_PIPE); |
@@ -1190,10 +1249,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1190 | } | 1249 | } |
1191 | 1250 | ||
1192 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 1251 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
1193 | ret = i915_load_modeset_init(dev); | 1252 | ret = i915_load_modeset_init(dev, prealloc_size, agp_size); |
1194 | if (ret < 0) { | 1253 | if (ret < 0) { |
1195 | DRM_ERROR("failed to init modeset\n"); | 1254 | DRM_ERROR("failed to init modeset\n"); |
1196 | goto out_rmmap; | 1255 | goto out_workqueue_free; |
1197 | } | 1256 | } |
1198 | } | 1257 | } |
1199 | 1258 | ||
@@ -1204,6 +1263,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1204 | 1263 | ||
1205 | return 0; | 1264 | return 0; |
1206 | 1265 | ||
1266 | out_workqueue_free: | ||
1267 | destroy_workqueue(dev_priv->wq); | ||
1207 | out_iomapfree: | 1268 | out_iomapfree: |
1208 | io_mapping_free(dev_priv->mm.gtt_mapping); | 1269 | io_mapping_free(dev_priv->mm.gtt_mapping); |
1209 | out_rmmap: | 1270 | out_rmmap: |
@@ -1217,6 +1278,8 @@ int i915_driver_unload(struct drm_device *dev) | |||
1217 | { | 1278 | { |
1218 | struct drm_i915_private *dev_priv = dev->dev_private; | 1279 | struct drm_i915_private *dev_priv = dev->dev_private; |
1219 | 1280 | ||
1281 | destroy_workqueue(dev_priv->wq); | ||
1282 | |||
1220 | io_mapping_free(dev_priv->mm.gtt_mapping); | 1283 | io_mapping_free(dev_priv->mm.gtt_mapping); |
1221 | if (dev_priv->mm.gtt_mtrr >= 0) { | 1284 | if (dev_priv->mm.gtt_mtrr >= 0) { |
1222 | mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, | 1285 | mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index e3cb4025e323..fc4b68aa2d05 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include "drm_pciids.h" | 36 | #include "drm_pciids.h" |
37 | #include <linux/console.h> | 37 | #include <linux/console.h> |
38 | #include "drm_crtc_helper.h" | ||
38 | 39 | ||
39 | static unsigned int i915_modeset = -1; | 40 | static unsigned int i915_modeset = -1; |
40 | module_param_named(modeset, i915_modeset, int, 0400); | 41 | module_param_named(modeset, i915_modeset, int, 0400); |
@@ -57,8 +58,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
57 | struct drm_i915_private *dev_priv = dev->dev_private; | 58 | struct drm_i915_private *dev_priv = dev->dev_private; |
58 | 59 | ||
59 | if (!dev || !dev_priv) { | 60 | if (!dev || !dev_priv) { |
60 | printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv); | 61 | DRM_ERROR("dev: %p, dev_priv: %p\n", dev, dev_priv); |
61 | printk(KERN_ERR "DRM not initialized, aborting suspend.\n"); | 62 | DRM_ERROR("DRM not initialized, aborting suspend.\n"); |
62 | return -ENODEV; | 63 | return -ENODEV; |
63 | } | 64 | } |
64 | 65 | ||
@@ -115,6 +116,10 @@ static int i915_resume(struct drm_device *dev) | |||
115 | 116 | ||
116 | drm_irq_install(dev); | 117 | drm_irq_install(dev); |
117 | } | 118 | } |
119 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
120 | /* Resume the modeset for every activated CRTC */ | ||
121 | drm_helper_resume_force_mode(dev); | ||
122 | } | ||
118 | 123 | ||
119 | return ret; | 124 | return ret; |
120 | } | 125 | } |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bb4c2d387b6c..7537f57d8a87 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -133,6 +133,22 @@ struct sdvo_device_mapping { | |||
133 | u8 initialized; | 133 | u8 initialized; |
134 | }; | 134 | }; |
135 | 135 | ||
136 | struct drm_i915_error_state { | ||
137 | u32 eir; | ||
138 | u32 pgtbl_er; | ||
139 | u32 pipeastat; | ||
140 | u32 pipebstat; | ||
141 | u32 ipeir; | ||
142 | u32 ipehr; | ||
143 | u32 instdone; | ||
144 | u32 acthd; | ||
145 | u32 instpm; | ||
146 | u32 instps; | ||
147 | u32 instdone1; | ||
148 | u32 seqno; | ||
149 | struct timeval time; | ||
150 | }; | ||
151 | |||
136 | typedef struct drm_i915_private { | 152 | typedef struct drm_i915_private { |
137 | struct drm_device *dev; | 153 | struct drm_device *dev; |
138 | 154 | ||
@@ -203,12 +219,20 @@ typedef struct drm_i915_private { | |||
203 | unsigned int lvds_vbt:1; | 219 | unsigned int lvds_vbt:1; |
204 | unsigned int int_crt_support:1; | 220 | unsigned int int_crt_support:1; |
205 | unsigned int lvds_use_ssc:1; | 221 | unsigned int lvds_use_ssc:1; |
222 | unsigned int edp_support:1; | ||
206 | int lvds_ssc_freq; | 223 | int lvds_ssc_freq; |
207 | 224 | ||
208 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ | 225 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ |
209 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ | 226 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ |
210 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ | 227 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ |
211 | 228 | ||
229 | unsigned int fsb_freq, mem_freq; | ||
230 | |||
231 | spinlock_t error_lock; | ||
232 | struct drm_i915_error_state *first_error; | ||
233 | struct work_struct error_work; | ||
234 | struct workqueue_struct *wq; | ||
235 | |||
212 | /* Register state */ | 236 | /* Register state */ |
213 | u8 saveLBB; | 237 | u8 saveLBB; |
214 | u32 saveDSPACNTR; | 238 | u32 saveDSPACNTR; |
@@ -468,9 +492,6 @@ struct drm_i915_gem_object { | |||
468 | */ | 492 | */ |
469 | int fence_reg; | 493 | int fence_reg; |
470 | 494 | ||
471 | /** Boolean whether this object has a valid gtt offset. */ | ||
472 | int gtt_bound; | ||
473 | |||
474 | /** How many users have pinned this object in GTT space */ | 495 | /** How many users have pinned this object in GTT space */ |
475 | int pin_count; | 496 | int pin_count; |
476 | 497 | ||
@@ -655,6 +676,7 @@ void i915_gem_free_object(struct drm_gem_object *obj); | |||
655 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); | 676 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); |
656 | void i915_gem_object_unpin(struct drm_gem_object *obj); | 677 | void i915_gem_object_unpin(struct drm_gem_object *obj); |
657 | int i915_gem_object_unbind(struct drm_gem_object *obj); | 678 | int i915_gem_object_unbind(struct drm_gem_object *obj); |
679 | void i915_gem_release_mmap(struct drm_gem_object *obj); | ||
658 | void i915_gem_lastclose(struct drm_device *dev); | 680 | void i915_gem_lastclose(struct drm_device *dev); |
659 | uint32_t i915_get_gem_seqno(struct drm_device *dev); | 681 | uint32_t i915_get_gem_seqno(struct drm_device *dev); |
660 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); | 682 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); |
@@ -869,7 +891,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
869 | IS_I915GM(dev))) | 891 | IS_I915GM(dev))) |
870 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 892 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
871 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 893 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
894 | #define SUPPORTS_EDP(dev) (IS_IGDNG_M(dev)) | ||
872 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) | 895 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) |
896 | /* dsparb controlled by hw only */ | ||
897 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | ||
873 | 898 | ||
874 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | 899 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) |
875 | 900 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 876b65cb7629..140bee142fc2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1252,6 +1252,31 @@ out_free_list: | |||
1252 | return ret; | 1252 | return ret; |
1253 | } | 1253 | } |
1254 | 1254 | ||
1255 | /** | ||
1256 | * i915_gem_release_mmap - remove physical page mappings | ||
1257 | * @obj: obj in question | ||
1258 | * | ||
1259 | * Preserve the reservation of the mmaping with the DRM core code, but | ||
1260 | * relinquish ownership of the pages back to the system. | ||
1261 | * | ||
1262 | * It is vital that we remove the page mapping if we have mapped a tiled | ||
1263 | * object through the GTT and then lose the fence register due to | ||
1264 | * resource pressure. Similarly if the object has been moved out of the | ||
1265 | * aperture, than pages mapped into userspace must be revoked. Removing the | ||
1266 | * mapping will then trigger a page fault on the next user access, allowing | ||
1267 | * fixup by i915_gem_fault(). | ||
1268 | */ | ||
1269 | void | ||
1270 | i915_gem_release_mmap(struct drm_gem_object *obj) | ||
1271 | { | ||
1272 | struct drm_device *dev = obj->dev; | ||
1273 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1274 | |||
1275 | if (dev->dev_mapping) | ||
1276 | unmap_mapping_range(dev->dev_mapping, | ||
1277 | obj_priv->mmap_offset, obj->size, 1); | ||
1278 | } | ||
1279 | |||
1255 | static void | 1280 | static void |
1256 | i915_gem_free_mmap_offset(struct drm_gem_object *obj) | 1281 | i915_gem_free_mmap_offset(struct drm_gem_object *obj) |
1257 | { | 1282 | { |
@@ -1545,7 +1570,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |||
1545 | } | 1570 | } |
1546 | 1571 | ||
1547 | if (was_empty && !dev_priv->mm.suspended) | 1572 | if (was_empty && !dev_priv->mm.suspended) |
1548 | schedule_delayed_work(&dev_priv->mm.retire_work, HZ); | 1573 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); |
1549 | return seqno; | 1574 | return seqno; |
1550 | } | 1575 | } |
1551 | 1576 | ||
@@ -1694,7 +1719,7 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
1694 | i915_gem_retire_requests(dev); | 1719 | i915_gem_retire_requests(dev); |
1695 | if (!dev_priv->mm.suspended && | 1720 | if (!dev_priv->mm.suspended && |
1696 | !list_empty(&dev_priv->mm.request_list)) | 1721 | !list_empty(&dev_priv->mm.request_list)) |
1697 | schedule_delayed_work(&dev_priv->mm.retire_work, HZ); | 1722 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); |
1698 | mutex_unlock(&dev->struct_mutex); | 1723 | mutex_unlock(&dev->struct_mutex); |
1699 | } | 1724 | } |
1700 | 1725 | ||
@@ -1861,7 +1886,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
1861 | { | 1886 | { |
1862 | struct drm_device *dev = obj->dev; | 1887 | struct drm_device *dev = obj->dev; |
1863 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1888 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
1864 | loff_t offset; | ||
1865 | int ret = 0; | 1889 | int ret = 0; |
1866 | 1890 | ||
1867 | #if WATCH_BUF | 1891 | #if WATCH_BUF |
@@ -1898,9 +1922,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
1898 | BUG_ON(obj_priv->active); | 1922 | BUG_ON(obj_priv->active); |
1899 | 1923 | ||
1900 | /* blow away mappings if mapped through GTT */ | 1924 | /* blow away mappings if mapped through GTT */ |
1901 | offset = ((loff_t) obj->map_list.hash.key) << PAGE_SHIFT; | 1925 | i915_gem_release_mmap(obj); |
1902 | if (dev->dev_mapping) | ||
1903 | unmap_mapping_range(dev->dev_mapping, offset, obj->size, 1); | ||
1904 | 1926 | ||
1905 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 1927 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
1906 | i915_gem_clear_fence_reg(obj); | 1928 | i915_gem_clear_fence_reg(obj); |
@@ -2222,7 +2244,6 @@ try_again: | |||
2222 | /* None available, try to steal one or wait for a user to finish */ | 2244 | /* None available, try to steal one or wait for a user to finish */ |
2223 | if (i == dev_priv->num_fence_regs) { | 2245 | if (i == dev_priv->num_fence_regs) { |
2224 | uint32_t seqno = dev_priv->mm.next_gem_seqno; | 2246 | uint32_t seqno = dev_priv->mm.next_gem_seqno; |
2225 | loff_t offset; | ||
2226 | 2247 | ||
2227 | if (avail == 0) | 2248 | if (avail == 0) |
2228 | return -ENOSPC; | 2249 | return -ENOSPC; |
@@ -2274,10 +2295,7 @@ try_again: | |||
2274 | * Zap this virtual mapping so we can set up a fence again | 2295 | * Zap this virtual mapping so we can set up a fence again |
2275 | * for this object next time we need it. | 2296 | * for this object next time we need it. |
2276 | */ | 2297 | */ |
2277 | offset = ((loff_t) reg->obj->map_list.hash.key) << PAGE_SHIFT; | 2298 | i915_gem_release_mmap(reg->obj); |
2278 | if (dev->dev_mapping) | ||
2279 | unmap_mapping_range(dev->dev_mapping, offset, | ||
2280 | reg->obj->size, 1); | ||
2281 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; | 2299 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; |
2282 | } | 2300 | } |
2283 | 2301 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c index 28146e405e87..cb3b97405fbf 100644 --- a/drivers/gpu/drm/i915/i915_gem_debugfs.c +++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c | |||
@@ -75,11 +75,10 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
75 | case ACTIVE_LIST: | 75 | case ACTIVE_LIST: |
76 | seq_printf(m, "Active:\n"); | 76 | seq_printf(m, "Active:\n"); |
77 | lock = &dev_priv->mm.active_list_lock; | 77 | lock = &dev_priv->mm.active_list_lock; |
78 | spin_lock(lock); | ||
79 | head = &dev_priv->mm.active_list; | 78 | head = &dev_priv->mm.active_list; |
80 | break; | 79 | break; |
81 | case INACTIVE_LIST: | 80 | case INACTIVE_LIST: |
82 | seq_printf(m, "Inctive:\n"); | 81 | seq_printf(m, "Inactive:\n"); |
83 | head = &dev_priv->mm.inactive_list; | 82 | head = &dev_priv->mm.inactive_list; |
84 | break; | 83 | break; |
85 | case FLUSHING_LIST: | 84 | case FLUSHING_LIST: |
@@ -91,6 +90,8 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
91 | return 0; | 90 | return 0; |
92 | } | 91 | } |
93 | 92 | ||
93 | if (lock) | ||
94 | spin_lock(lock); | ||
94 | list_for_each_entry(obj_priv, head, list) | 95 | list_for_each_entry(obj_priv, head, list) |
95 | { | 96 | { |
96 | struct drm_gem_object *obj = obj_priv->obj; | 97 | struct drm_gem_object *obj = obj_priv->obj; |
@@ -104,7 +105,10 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
104 | if (obj->name) | 105 | if (obj->name) |
105 | seq_printf(m, " (name: %d)", obj->name); | 106 | seq_printf(m, " (name: %d)", obj->name); |
106 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 107 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
107 | seq_printf(m, " (fence: %d)\n", obj_priv->fence_reg); | 108 | seq_printf(m, " (fence: %d)", obj_priv->fence_reg); |
109 | if (obj_priv->gtt_space != NULL) | ||
110 | seq_printf(m, " (gtt_offset: %08x)", obj_priv->gtt_offset); | ||
111 | |||
108 | seq_printf(m, "\n"); | 112 | seq_printf(m, "\n"); |
109 | } | 113 | } |
110 | 114 | ||
@@ -323,6 +327,41 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
323 | return 0; | 327 | return 0; |
324 | } | 328 | } |
325 | 329 | ||
330 | static int i915_error_state(struct seq_file *m, void *unused) | ||
331 | { | ||
332 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
333 | struct drm_device *dev = node->minor->dev; | ||
334 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
335 | struct drm_i915_error_state *error; | ||
336 | unsigned long flags; | ||
337 | |||
338 | spin_lock_irqsave(&dev_priv->error_lock, flags); | ||
339 | if (!dev_priv->first_error) { | ||
340 | seq_printf(m, "no error state collected\n"); | ||
341 | goto out; | ||
342 | } | ||
343 | |||
344 | error = dev_priv->first_error; | ||
345 | |||
346 | seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, | ||
347 | error->time.tv_usec); | ||
348 | seq_printf(m, "EIR: 0x%08x\n", error->eir); | ||
349 | seq_printf(m, " PGTBL_ER: 0x%08x\n", error->pgtbl_er); | ||
350 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); | ||
351 | seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); | ||
352 | seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); | ||
353 | seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); | ||
354 | seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); | ||
355 | if (IS_I965G(dev)) { | ||
356 | seq_printf(m, " INSTPS: 0x%08x\n", error->instps); | ||
357 | seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); | ||
358 | } | ||
359 | |||
360 | out: | ||
361 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | ||
362 | |||
363 | return 0; | ||
364 | } | ||
326 | 365 | ||
327 | static struct drm_info_list i915_gem_debugfs_list[] = { | 366 | static struct drm_info_list i915_gem_debugfs_list[] = { |
328 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, | 367 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, |
@@ -336,6 +375,7 @@ static struct drm_info_list i915_gem_debugfs_list[] = { | |||
336 | {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, | 375 | {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, |
337 | {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, | 376 | {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, |
338 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, | 377 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, |
378 | {"i915_error_state", i915_error_state, 0}, | ||
339 | }; | 379 | }; |
340 | #define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) | 380 | #define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) |
341 | 381 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index daeae62e1c28..a2d527b22ec4 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -521,6 +521,12 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
521 | goto err; | 521 | goto err; |
522 | } | 522 | } |
523 | 523 | ||
524 | /* If we've changed tiling, GTT-mappings of the object | ||
525 | * need to re-fault to ensure that the correct fence register | ||
526 | * setup is in place. | ||
527 | */ | ||
528 | i915_gem_release_mmap(obj); | ||
529 | |||
524 | obj_priv->tiling_mode = args->tiling_mode; | 530 | obj_priv->tiling_mode = args->tiling_mode; |
525 | obj_priv->stride = args->stride; | 531 | obj_priv->stride = args->stride; |
526 | } | 532 | } |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 228546f6eaa4..7ebc84c2881e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -26,6 +26,7 @@ | |||
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/sysrq.h> | ||
29 | #include "drmP.h" | 30 | #include "drmP.h" |
30 | #include "drm.h" | 31 | #include "drm.h" |
31 | #include "i915_drm.h" | 32 | #include "i915_drm.h" |
@@ -41,9 +42,10 @@ | |||
41 | * we leave them always unmasked in IMR and then control enabling them through | 42 | * we leave them always unmasked in IMR and then control enabling them through |
42 | * PIPESTAT alone. | 43 | * PIPESTAT alone. |
43 | */ | 44 | */ |
44 | #define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \ | 45 | #define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \ |
45 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ | 46 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ |
46 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) | 47 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \ |
48 | I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) | ||
47 | 49 | ||
48 | /** Interrupts that we mask and unmask at runtime. */ | 50 | /** Interrupts that we mask and unmask at runtime. */ |
49 | #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) | 51 | #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) |
@@ -188,7 +190,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | |||
188 | low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; | 190 | low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; |
189 | 191 | ||
190 | if (!i915_pipe_enabled(dev, pipe)) { | 192 | if (!i915_pipe_enabled(dev, pipe)) { |
191 | DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); | 193 | DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe); |
192 | return 0; | 194 | return 0; |
193 | } | 195 | } |
194 | 196 | ||
@@ -217,7 +219,7 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) | |||
217 | int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45; | 219 | int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45; |
218 | 220 | ||
219 | if (!i915_pipe_enabled(dev, pipe)) { | 221 | if (!i915_pipe_enabled(dev, pipe)) { |
220 | DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); | 222 | DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe); |
221 | return 0; | 223 | return 0; |
222 | } | 224 | } |
223 | 225 | ||
@@ -288,6 +290,201 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) | |||
288 | return ret; | 290 | return ret; |
289 | } | 291 | } |
290 | 292 | ||
293 | /** | ||
294 | * i915_error_work_func - do process context error handling work | ||
295 | * @work: work struct | ||
296 | * | ||
297 | * Fire an error uevent so userspace can see that a hang or error | ||
298 | * was detected. | ||
299 | */ | ||
300 | static void i915_error_work_func(struct work_struct *work) | ||
301 | { | ||
302 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, | ||
303 | error_work); | ||
304 | struct drm_device *dev = dev_priv->dev; | ||
305 | char *event_string = "ERROR=1"; | ||
306 | char *envp[] = { event_string, NULL }; | ||
307 | |||
308 | DRM_DEBUG("generating error event\n"); | ||
309 | |||
310 | kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp); | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * i915_capture_error_state - capture an error record for later analysis | ||
315 | * @dev: drm device | ||
316 | * | ||
317 | * Should be called when an error is detected (either a hang or an error | ||
318 | * interrupt) to capture error state from the time of the error. Fills | ||
319 | * out a structure which becomes available in debugfs for user level tools | ||
320 | * to pick up. | ||
321 | */ | ||
322 | static void i915_capture_error_state(struct drm_device *dev) | ||
323 | { | ||
324 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
325 | struct drm_i915_error_state *error; | ||
326 | unsigned long flags; | ||
327 | |||
328 | spin_lock_irqsave(&dev_priv->error_lock, flags); | ||
329 | if (dev_priv->first_error) | ||
330 | goto out; | ||
331 | |||
332 | error = kmalloc(sizeof(*error), GFP_ATOMIC); | ||
333 | if (!error) { | ||
334 | DRM_DEBUG("out ot memory, not capturing error state\n"); | ||
335 | goto out; | ||
336 | } | ||
337 | |||
338 | error->eir = I915_READ(EIR); | ||
339 | error->pgtbl_er = I915_READ(PGTBL_ER); | ||
340 | error->pipeastat = I915_READ(PIPEASTAT); | ||
341 | error->pipebstat = I915_READ(PIPEBSTAT); | ||
342 | error->instpm = I915_READ(INSTPM); | ||
343 | if (!IS_I965G(dev)) { | ||
344 | error->ipeir = I915_READ(IPEIR); | ||
345 | error->ipehr = I915_READ(IPEHR); | ||
346 | error->instdone = I915_READ(INSTDONE); | ||
347 | error->acthd = I915_READ(ACTHD); | ||
348 | } else { | ||
349 | error->ipeir = I915_READ(IPEIR_I965); | ||
350 | error->ipehr = I915_READ(IPEHR_I965); | ||
351 | error->instdone = I915_READ(INSTDONE_I965); | ||
352 | error->instps = I915_READ(INSTPS); | ||
353 | error->instdone1 = I915_READ(INSTDONE1); | ||
354 | error->acthd = I915_READ(ACTHD_I965); | ||
355 | } | ||
356 | |||
357 | do_gettimeofday(&error->time); | ||
358 | |||
359 | dev_priv->first_error = error; | ||
360 | |||
361 | out: | ||
362 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | ||
363 | } | ||
364 | |||
365 | /** | ||
366 | * i915_handle_error - handle an error interrupt | ||
367 | * @dev: drm device | ||
368 | * | ||
369 | * Do some basic checking of regsiter state at error interrupt time and | ||
370 | * dump it to the syslog. Also call i915_capture_error_state() to make | ||
371 | * sure we get a record and make it available in debugfs. Fire a uevent | ||
372 | * so userspace knows something bad happened (should trigger collection | ||
373 | * of a ring dump etc.). | ||
374 | */ | ||
375 | static void i915_handle_error(struct drm_device *dev) | ||
376 | { | ||
377 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
378 | u32 eir = I915_READ(EIR); | ||
379 | u32 pipea_stats = I915_READ(PIPEASTAT); | ||
380 | u32 pipeb_stats = I915_READ(PIPEBSTAT); | ||
381 | |||
382 | i915_capture_error_state(dev); | ||
383 | |||
384 | printk(KERN_ERR "render error detected, EIR: 0x%08x\n", | ||
385 | eir); | ||
386 | |||
387 | if (IS_G4X(dev)) { | ||
388 | if (eir & (GM45_ERROR_MEM_PRIV | GM45_ERROR_CP_PRIV)) { | ||
389 | u32 ipeir = I915_READ(IPEIR_I965); | ||
390 | |||
391 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
392 | I915_READ(IPEIR_I965)); | ||
393 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
394 | I915_READ(IPEHR_I965)); | ||
395 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
396 | I915_READ(INSTDONE_I965)); | ||
397 | printk(KERN_ERR " INSTPS: 0x%08x\n", | ||
398 | I915_READ(INSTPS)); | ||
399 | printk(KERN_ERR " INSTDONE1: 0x%08x\n", | ||
400 | I915_READ(INSTDONE1)); | ||
401 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
402 | I915_READ(ACTHD_I965)); | ||
403 | I915_WRITE(IPEIR_I965, ipeir); | ||
404 | (void)I915_READ(IPEIR_I965); | ||
405 | } | ||
406 | if (eir & GM45_ERROR_PAGE_TABLE) { | ||
407 | u32 pgtbl_err = I915_READ(PGTBL_ER); | ||
408 | printk(KERN_ERR "page table error\n"); | ||
409 | printk(KERN_ERR " PGTBL_ER: 0x%08x\n", | ||
410 | pgtbl_err); | ||
411 | I915_WRITE(PGTBL_ER, pgtbl_err); | ||
412 | (void)I915_READ(PGTBL_ER); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | if (IS_I9XX(dev)) { | ||
417 | if (eir & I915_ERROR_PAGE_TABLE) { | ||
418 | u32 pgtbl_err = I915_READ(PGTBL_ER); | ||
419 | printk(KERN_ERR "page table error\n"); | ||
420 | printk(KERN_ERR " PGTBL_ER: 0x%08x\n", | ||
421 | pgtbl_err); | ||
422 | I915_WRITE(PGTBL_ER, pgtbl_err); | ||
423 | (void)I915_READ(PGTBL_ER); | ||
424 | } | ||
425 | } | ||
426 | |||
427 | if (eir & I915_ERROR_MEMORY_REFRESH) { | ||
428 | printk(KERN_ERR "memory refresh error\n"); | ||
429 | printk(KERN_ERR "PIPEASTAT: 0x%08x\n", | ||
430 | pipea_stats); | ||
431 | printk(KERN_ERR "PIPEBSTAT: 0x%08x\n", | ||
432 | pipeb_stats); | ||
433 | /* pipestat has already been acked */ | ||
434 | } | ||
435 | if (eir & I915_ERROR_INSTRUCTION) { | ||
436 | printk(KERN_ERR "instruction error\n"); | ||
437 | printk(KERN_ERR " INSTPM: 0x%08x\n", | ||
438 | I915_READ(INSTPM)); | ||
439 | if (!IS_I965G(dev)) { | ||
440 | u32 ipeir = I915_READ(IPEIR); | ||
441 | |||
442 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
443 | I915_READ(IPEIR)); | ||
444 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
445 | I915_READ(IPEHR)); | ||
446 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
447 | I915_READ(INSTDONE)); | ||
448 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
449 | I915_READ(ACTHD)); | ||
450 | I915_WRITE(IPEIR, ipeir); | ||
451 | (void)I915_READ(IPEIR); | ||
452 | } else { | ||
453 | u32 ipeir = I915_READ(IPEIR_I965); | ||
454 | |||
455 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
456 | I915_READ(IPEIR_I965)); | ||
457 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
458 | I915_READ(IPEHR_I965)); | ||
459 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
460 | I915_READ(INSTDONE_I965)); | ||
461 | printk(KERN_ERR " INSTPS: 0x%08x\n", | ||
462 | I915_READ(INSTPS)); | ||
463 | printk(KERN_ERR " INSTDONE1: 0x%08x\n", | ||
464 | I915_READ(INSTDONE1)); | ||
465 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
466 | I915_READ(ACTHD_I965)); | ||
467 | I915_WRITE(IPEIR_I965, ipeir); | ||
468 | (void)I915_READ(IPEIR_I965); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | I915_WRITE(EIR, eir); | ||
473 | (void)I915_READ(EIR); | ||
474 | eir = I915_READ(EIR); | ||
475 | if (eir) { | ||
476 | /* | ||
477 | * some errors might have become stuck, | ||
478 | * mask them. | ||
479 | */ | ||
480 | DRM_ERROR("EIR stuck: 0x%08x, masking\n", eir); | ||
481 | I915_WRITE(EMR, I915_READ(EMR) | eir); | ||
482 | I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); | ||
483 | } | ||
484 | |||
485 | queue_work(dev_priv->wq, &dev_priv->error_work); | ||
486 | } | ||
487 | |||
291 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 488 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
292 | { | 489 | { |
293 | struct drm_device *dev = (struct drm_device *) arg; | 490 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -329,15 +526,22 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
329 | pipea_stats = I915_READ(PIPEASTAT); | 526 | pipea_stats = I915_READ(PIPEASTAT); |
330 | pipeb_stats = I915_READ(PIPEBSTAT); | 527 | pipeb_stats = I915_READ(PIPEBSTAT); |
331 | 528 | ||
529 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) | ||
530 | i915_handle_error(dev); | ||
531 | |||
332 | /* | 532 | /* |
333 | * Clear the PIPE(A|B)STAT regs before the IIR | 533 | * Clear the PIPE(A|B)STAT regs before the IIR |
334 | */ | 534 | */ |
335 | if (pipea_stats & 0x8000ffff) { | 535 | if (pipea_stats & 0x8000ffff) { |
536 | if (pipea_stats & PIPE_FIFO_UNDERRUN_STATUS) | ||
537 | DRM_DEBUG("pipe a underrun\n"); | ||
336 | I915_WRITE(PIPEASTAT, pipea_stats); | 538 | I915_WRITE(PIPEASTAT, pipea_stats); |
337 | irq_received = 1; | 539 | irq_received = 1; |
338 | } | 540 | } |
339 | 541 | ||
340 | if (pipeb_stats & 0x8000ffff) { | 542 | if (pipeb_stats & 0x8000ffff) { |
543 | if (pipeb_stats & PIPE_FIFO_UNDERRUN_STATUS) | ||
544 | DRM_DEBUG("pipe b underrun\n"); | ||
341 | I915_WRITE(PIPEBSTAT, pipeb_stats); | 545 | I915_WRITE(PIPEBSTAT, pipeb_stats); |
342 | irq_received = 1; | 546 | irq_received = 1; |
343 | } | 547 | } |
@@ -356,7 +560,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
356 | DRM_DEBUG("hotplug event received, stat 0x%08x\n", | 560 | DRM_DEBUG("hotplug event received, stat 0x%08x\n", |
357 | hotplug_status); | 561 | hotplug_status); |
358 | if (hotplug_status & dev_priv->hotplug_supported_mask) | 562 | if (hotplug_status & dev_priv->hotplug_supported_mask) |
359 | schedule_work(&dev_priv->hotplug_work); | 563 | queue_work(dev_priv->wq, |
564 | &dev_priv->hotplug_work); | ||
360 | 565 | ||
361 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); | 566 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
362 | I915_READ(PORT_HOTPLUG_STAT); | 567 | I915_READ(PORT_HOTPLUG_STAT); |
@@ -709,6 +914,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev) | |||
709 | atomic_set(&dev_priv->irq_received, 0); | 914 | atomic_set(&dev_priv->irq_received, 0); |
710 | 915 | ||
711 | INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); | 916 | INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); |
917 | INIT_WORK(&dev_priv->error_work, i915_error_work_func); | ||
712 | 918 | ||
713 | if (IS_IGDNG(dev)) { | 919 | if (IS_IGDNG(dev)) { |
714 | igdng_irq_preinstall(dev); | 920 | igdng_irq_preinstall(dev); |
@@ -732,6 +938,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
732 | { | 938 | { |
733 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 939 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
734 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; | 940 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; |
941 | u32 error_mask; | ||
735 | 942 | ||
736 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); | 943 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); |
737 | 944 | ||
@@ -768,6 +975,21 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
768 | i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT); | 975 | i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT); |
769 | } | 976 | } |
770 | 977 | ||
978 | /* | ||
979 | * Enable some error detection, note the instruction error mask | ||
980 | * bit is reserved, so we leave it masked. | ||
981 | */ | ||
982 | if (IS_G4X(dev)) { | ||
983 | error_mask = ~(GM45_ERROR_PAGE_TABLE | | ||
984 | GM45_ERROR_MEM_PRIV | | ||
985 | GM45_ERROR_CP_PRIV | | ||
986 | I915_ERROR_MEMORY_REFRESH); | ||
987 | } else { | ||
988 | error_mask = ~(I915_ERROR_PAGE_TABLE | | ||
989 | I915_ERROR_MEMORY_REFRESH); | ||
990 | } | ||
991 | I915_WRITE(EMR, error_mask); | ||
992 | |||
771 | /* Disable pipe interrupt enables, clear pending pipe status */ | 993 | /* Disable pipe interrupt enables, clear pending pipe status */ |
772 | I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); | 994 | I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); |
773 | I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); | 995 | I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 88bf7521405f..2955083aa471 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -206,6 +206,7 @@ | |||
206 | /* | 206 | /* |
207 | * Instruction and interrupt control regs | 207 | * Instruction and interrupt control regs |
208 | */ | 208 | */ |
209 | #define PGTBL_ER 0x02024 | ||
209 | #define PRB0_TAIL 0x02030 | 210 | #define PRB0_TAIL 0x02030 |
210 | #define PRB0_HEAD 0x02034 | 211 | #define PRB0_HEAD 0x02034 |
211 | #define PRB0_START 0x02038 | 212 | #define PRB0_START 0x02038 |
@@ -226,11 +227,18 @@ | |||
226 | #define PRB1_HEAD 0x02044 /* 915+ only */ | 227 | #define PRB1_HEAD 0x02044 /* 915+ only */ |
227 | #define PRB1_START 0x02048 /* 915+ only */ | 228 | #define PRB1_START 0x02048 /* 915+ only */ |
228 | #define PRB1_CTL 0x0204c /* 915+ only */ | 229 | #define PRB1_CTL 0x0204c /* 915+ only */ |
230 | #define IPEIR_I965 0x02064 | ||
231 | #define IPEHR_I965 0x02068 | ||
232 | #define INSTDONE_I965 0x0206c | ||
233 | #define INSTPS 0x02070 /* 965+ only */ | ||
234 | #define INSTDONE1 0x0207c /* 965+ only */ | ||
229 | #define ACTHD_I965 0x02074 | 235 | #define ACTHD_I965 0x02074 |
230 | #define HWS_PGA 0x02080 | 236 | #define HWS_PGA 0x02080 |
231 | #define HWS_ADDRESS_MASK 0xfffff000 | 237 | #define HWS_ADDRESS_MASK 0xfffff000 |
232 | #define HWS_START_ADDRESS_SHIFT 4 | 238 | #define HWS_START_ADDRESS_SHIFT 4 |
233 | #define IPEIR 0x02088 | 239 | #define IPEIR 0x02088 |
240 | #define IPEHR 0x0208c | ||
241 | #define INSTDONE 0x02090 | ||
234 | #define NOPID 0x02094 | 242 | #define NOPID 0x02094 |
235 | #define HWSTAM 0x02098 | 243 | #define HWSTAM 0x02098 |
236 | #define SCPD0 0x0209c /* 915+ only */ | 244 | #define SCPD0 0x0209c /* 915+ only */ |
@@ -258,10 +266,22 @@ | |||
258 | #define EIR 0x020b0 | 266 | #define EIR 0x020b0 |
259 | #define EMR 0x020b4 | 267 | #define EMR 0x020b4 |
260 | #define ESR 0x020b8 | 268 | #define ESR 0x020b8 |
269 | #define GM45_ERROR_PAGE_TABLE (1<<5) | ||
270 | #define GM45_ERROR_MEM_PRIV (1<<4) | ||
271 | #define I915_ERROR_PAGE_TABLE (1<<4) | ||
272 | #define GM45_ERROR_CP_PRIV (1<<3) | ||
273 | #define I915_ERROR_MEMORY_REFRESH (1<<1) | ||
274 | #define I915_ERROR_INSTRUCTION (1<<0) | ||
261 | #define INSTPM 0x020c0 | 275 | #define INSTPM 0x020c0 |
262 | #define ACTHD 0x020c8 | 276 | #define ACTHD 0x020c8 |
263 | #define FW_BLC 0x020d8 | 277 | #define FW_BLC 0x020d8 |
278 | #define FW_BLC2 0x020dc | ||
264 | #define FW_BLC_SELF 0x020e0 /* 915+ only */ | 279 | #define FW_BLC_SELF 0x020e0 /* 915+ only */ |
280 | #define FW_BLC_SELF_EN (1<<15) | ||
281 | #define MM_BURST_LENGTH 0x00700000 | ||
282 | #define MM_FIFO_WATERMARK 0x0001F000 | ||
283 | #define LM_BURST_LENGTH 0x00000700 | ||
284 | #define LM_FIFO_WATERMARK 0x0000001F | ||
265 | #define MI_ARB_STATE 0x020e4 /* 915+ only */ | 285 | #define MI_ARB_STATE 0x020e4 /* 915+ only */ |
266 | #define CACHE_MODE_0 0x02120 /* 915+ only */ | 286 | #define CACHE_MODE_0 0x02120 /* 915+ only */ |
267 | #define CM0_MASK_SHIFT 16 | 287 | #define CM0_MASK_SHIFT 16 |
@@ -571,17 +591,21 @@ | |||
571 | 591 | ||
572 | /* Clocking configuration register */ | 592 | /* Clocking configuration register */ |
573 | #define CLKCFG 0x10c00 | 593 | #define CLKCFG 0x10c00 |
574 | #define CLKCFG_FSB_400 (0 << 0) /* hrawclk 100 */ | 594 | #define CLKCFG_FSB_400 (5 << 0) /* hrawclk 100 */ |
575 | #define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */ | 595 | #define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */ |
576 | #define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */ | 596 | #define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */ |
577 | #define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */ | 597 | #define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */ |
578 | #define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */ | 598 | #define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */ |
579 | #define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */ | 599 | #define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */ |
580 | /* this is a guess, could be 5 as well */ | 600 | /* Note, below two are guess */ |
581 | #define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */ | 601 | #define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */ |
582 | #define CLKCFG_FSB_1600_ALT (5 << 0) /* hrawclk 400 */ | 602 | #define CLKCFG_FSB_1600_ALT (0 << 0) /* hrawclk 400 */ |
583 | #define CLKCFG_FSB_MASK (7 << 0) | 603 | #define CLKCFG_FSB_MASK (7 << 0) |
584 | 604 | #define CLKCFG_MEM_533 (1 << 4) | |
605 | #define CLKCFG_MEM_667 (2 << 4) | ||
606 | #define CLKCFG_MEM_800 (3 << 4) | ||
607 | #define CLKCFG_MEM_MASK (7 << 4) | ||
608 | |||
585 | /** GM965 GM45 render standby register */ | 609 | /** GM965 GM45 render standby register */ |
586 | #define MCHBAR_RENDER_STANDBY 0x111B8 | 610 | #define MCHBAR_RENDER_STANDBY 0x111B8 |
587 | 611 | ||
@@ -1371,6 +1395,7 @@ | |||
1371 | #define TV_V_CHROMA_42 0x684a8 | 1395 | #define TV_V_CHROMA_42 0x684a8 |
1372 | 1396 | ||
1373 | /* Display Port */ | 1397 | /* Display Port */ |
1398 | #define DP_A 0x64000 /* eDP */ | ||
1374 | #define DP_B 0x64100 | 1399 | #define DP_B 0x64100 |
1375 | #define DP_C 0x64200 | 1400 | #define DP_C 0x64200 |
1376 | #define DP_D 0x64300 | 1401 | #define DP_D 0x64300 |
@@ -1413,13 +1438,22 @@ | |||
1413 | /* Mystic DPCD version 1.1 special mode */ | 1438 | /* Mystic DPCD version 1.1 special mode */ |
1414 | #define DP_ENHANCED_FRAMING (1 << 18) | 1439 | #define DP_ENHANCED_FRAMING (1 << 18) |
1415 | 1440 | ||
1441 | /* eDP */ | ||
1442 | #define DP_PLL_FREQ_270MHZ (0 << 16) | ||
1443 | #define DP_PLL_FREQ_160MHZ (1 << 16) | ||
1444 | #define DP_PLL_FREQ_MASK (3 << 16) | ||
1445 | |||
1416 | /** locked once port is enabled */ | 1446 | /** locked once port is enabled */ |
1417 | #define DP_PORT_REVERSAL (1 << 15) | 1447 | #define DP_PORT_REVERSAL (1 << 15) |
1418 | 1448 | ||
1449 | /* eDP */ | ||
1450 | #define DP_PLL_ENABLE (1 << 14) | ||
1451 | |||
1419 | /** sends the clock on lane 15 of the PEG for debug */ | 1452 | /** sends the clock on lane 15 of the PEG for debug */ |
1420 | #define DP_CLOCK_OUTPUT_ENABLE (1 << 13) | 1453 | #define DP_CLOCK_OUTPUT_ENABLE (1 << 13) |
1421 | 1454 | ||
1422 | #define DP_SCRAMBLING_DISABLE (1 << 12) | 1455 | #define DP_SCRAMBLING_DISABLE (1 << 12) |
1456 | #define DP_SCRAMBLING_DISABLE_IGDNG (1 << 7) | ||
1423 | 1457 | ||
1424 | /** limit RGB values to avoid confusing TVs */ | 1458 | /** limit RGB values to avoid confusing TVs */ |
1425 | #define DP_COLOR_RANGE_16_235 (1 << 8) | 1459 | #define DP_COLOR_RANGE_16_235 (1 << 8) |
@@ -1439,6 +1473,13 @@ | |||
1439 | * is 20 bytes in each direction, hence the 5 fixed | 1473 | * is 20 bytes in each direction, hence the 5 fixed |
1440 | * data registers | 1474 | * data registers |
1441 | */ | 1475 | */ |
1476 | #define DPA_AUX_CH_CTL 0x64010 | ||
1477 | #define DPA_AUX_CH_DATA1 0x64014 | ||
1478 | #define DPA_AUX_CH_DATA2 0x64018 | ||
1479 | #define DPA_AUX_CH_DATA3 0x6401c | ||
1480 | #define DPA_AUX_CH_DATA4 0x64020 | ||
1481 | #define DPA_AUX_CH_DATA5 0x64024 | ||
1482 | |||
1442 | #define DPB_AUX_CH_CTL 0x64110 | 1483 | #define DPB_AUX_CH_CTL 0x64110 |
1443 | #define DPB_AUX_CH_DATA1 0x64114 | 1484 | #define DPB_AUX_CH_DATA1 0x64114 |
1444 | #define DPB_AUX_CH_DATA2 0x64118 | 1485 | #define DPB_AUX_CH_DATA2 0x64118 |
@@ -1581,6 +1622,34 @@ | |||
1581 | #define DSPARB_CSTART_SHIFT 7 | 1622 | #define DSPARB_CSTART_SHIFT 7 |
1582 | #define DSPARB_BSTART_MASK (0x7f) | 1623 | #define DSPARB_BSTART_MASK (0x7f) |
1583 | #define DSPARB_BSTART_SHIFT 0 | 1624 | #define DSPARB_BSTART_SHIFT 0 |
1625 | #define DSPARB_BEND_SHIFT 9 /* on 855 */ | ||
1626 | #define DSPARB_AEND_SHIFT 0 | ||
1627 | |||
1628 | #define DSPFW1 0x70034 | ||
1629 | #define DSPFW2 0x70038 | ||
1630 | #define DSPFW3 0x7003c | ||
1631 | #define IGD_SELF_REFRESH_EN (1<<30) | ||
1632 | |||
1633 | /* FIFO watermark sizes etc */ | ||
1634 | #define I915_FIFO_LINE_SIZE 64 | ||
1635 | #define I830_FIFO_LINE_SIZE 32 | ||
1636 | #define I945_FIFO_SIZE 127 /* 945 & 965 */ | ||
1637 | #define I915_FIFO_SIZE 95 | ||
1638 | #define I855GM_FIFO_SIZE 127 /* In cachelines */ | ||
1639 | #define I830_FIFO_SIZE 95 | ||
1640 | #define I915_MAX_WM 0x3f | ||
1641 | |||
1642 | #define IGD_DISPLAY_FIFO 512 /* in 64byte unit */ | ||
1643 | #define IGD_FIFO_LINE_SIZE 64 | ||
1644 | #define IGD_MAX_WM 0x1ff | ||
1645 | #define IGD_DFT_WM 0x3f | ||
1646 | #define IGD_DFT_HPLLOFF_WM 0 | ||
1647 | #define IGD_GUARD_WM 10 | ||
1648 | #define IGD_CURSOR_FIFO 64 | ||
1649 | #define IGD_CURSOR_MAX_WM 0x3f | ||
1650 | #define IGD_CURSOR_DFT_WM 0 | ||
1651 | #define IGD_CURSOR_GUARD_WM 5 | ||
1652 | |||
1584 | /* | 1653 | /* |
1585 | * The two pipe frame counter registers are not synchronized, so | 1654 | * The two pipe frame counter registers are not synchronized, so |
1586 | * reading a stable value is somewhat tricky. The following code | 1655 | * reading a stable value is somewhat tricky. The following code |
@@ -1796,6 +1865,8 @@ | |||
1796 | #define PFA_CTL_1 0x68080 | 1865 | #define PFA_CTL_1 0x68080 |
1797 | #define PFB_CTL_1 0x68880 | 1866 | #define PFB_CTL_1 0x68880 |
1798 | #define PF_ENABLE (1<<31) | 1867 | #define PF_ENABLE (1<<31) |
1868 | #define PFA_WIN_SZ 0x68074 | ||
1869 | #define PFB_WIN_SZ 0x68874 | ||
1799 | 1870 | ||
1800 | /* legacy palette */ | 1871 | /* legacy palette */ |
1801 | #define LGC_PALETTE_A 0x4a000 | 1872 | #define LGC_PALETTE_A 0x4a000 |
@@ -2156,4 +2227,28 @@ | |||
2156 | #define PCH_PP_OFF_DELAYS 0xc720c | 2227 | #define PCH_PP_OFF_DELAYS 0xc720c |
2157 | #define PCH_PP_DIVISOR 0xc7210 | 2228 | #define PCH_PP_DIVISOR 0xc7210 |
2158 | 2229 | ||
2230 | #define PCH_DP_B 0xe4100 | ||
2231 | #define PCH_DPB_AUX_CH_CTL 0xe4110 | ||
2232 | #define PCH_DPB_AUX_CH_DATA1 0xe4114 | ||
2233 | #define PCH_DPB_AUX_CH_DATA2 0xe4118 | ||
2234 | #define PCH_DPB_AUX_CH_DATA3 0xe411c | ||
2235 | #define PCH_DPB_AUX_CH_DATA4 0xe4120 | ||
2236 | #define PCH_DPB_AUX_CH_DATA5 0xe4124 | ||
2237 | |||
2238 | #define PCH_DP_C 0xe4200 | ||
2239 | #define PCH_DPC_AUX_CH_CTL 0xe4210 | ||
2240 | #define PCH_DPC_AUX_CH_DATA1 0xe4214 | ||
2241 | #define PCH_DPC_AUX_CH_DATA2 0xe4218 | ||
2242 | #define PCH_DPC_AUX_CH_DATA3 0xe421c | ||
2243 | #define PCH_DPC_AUX_CH_DATA4 0xe4220 | ||
2244 | #define PCH_DPC_AUX_CH_DATA5 0xe4224 | ||
2245 | |||
2246 | #define PCH_DP_D 0xe4300 | ||
2247 | #define PCH_DPD_AUX_CH_CTL 0xe4310 | ||
2248 | #define PCH_DPD_AUX_CH_DATA1 0xe4314 | ||
2249 | #define PCH_DPD_AUX_CH_DATA2 0xe4318 | ||
2250 | #define PCH_DPD_AUX_CH_DATA3 0xe431c | ||
2251 | #define PCH_DPD_AUX_CH_DATA4 0xe4320 | ||
2252 | #define PCH_DPD_AUX_CH_DATA5 0xe4324 | ||
2253 | |||
2159 | #endif /* _I915_REG_H_ */ | 2254 | #endif /* _I915_REG_H_ */ |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 8d8e083d14ab..1d04e1904ac6 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -222,23 +222,12 @@ static void i915_restore_vga(struct drm_device *dev) | |||
222 | I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); | 222 | I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); |
223 | } | 223 | } |
224 | 224 | ||
225 | int i915_save_state(struct drm_device *dev) | 225 | static void i915_save_modeset_reg(struct drm_device *dev) |
226 | { | 226 | { |
227 | struct drm_i915_private *dev_priv = dev->dev_private; | 227 | struct drm_i915_private *dev_priv = dev->dev_private; |
228 | int i; | ||
229 | |||
230 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
231 | |||
232 | /* Render Standby */ | ||
233 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
234 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | ||
235 | |||
236 | /* Hardware status page */ | ||
237 | dev_priv->saveHWS = I915_READ(HWS_PGA); | ||
238 | |||
239 | /* Display arbitration control */ | ||
240 | dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
241 | 228 | ||
229 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
230 | return; | ||
242 | /* Pipe & plane A info */ | 231 | /* Pipe & plane A info */ |
243 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | 232 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); |
244 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | 233 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); |
@@ -294,7 +283,122 @@ int i915_save_state(struct drm_device *dev) | |||
294 | } | 283 | } |
295 | i915_save_palette(dev, PIPE_B); | 284 | i915_save_palette(dev, PIPE_B); |
296 | dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); | 285 | dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); |
286 | return; | ||
287 | } | ||
288 | static void i915_restore_modeset_reg(struct drm_device *dev) | ||
289 | { | ||
290 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
291 | |||
292 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
293 | return; | ||
294 | |||
295 | /* Pipe & plane A info */ | ||
296 | /* Prime the clock */ | ||
297 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | ||
298 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | ||
299 | ~DPLL_VCO_ENABLE); | ||
300 | DRM_UDELAY(150); | ||
301 | } | ||
302 | I915_WRITE(FPA0, dev_priv->saveFPA0); | ||
303 | I915_WRITE(FPA1, dev_priv->saveFPA1); | ||
304 | /* Actually enable it */ | ||
305 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
306 | DRM_UDELAY(150); | ||
307 | if (IS_I965G(dev)) | ||
308 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
309 | DRM_UDELAY(150); | ||
310 | |||
311 | /* Restore mode */ | ||
312 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
313 | I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
314 | I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
315 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
316 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
317 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
318 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
319 | |||
320 | /* Restore plane info */ | ||
321 | I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
322 | I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
323 | I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
324 | I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); | ||
325 | I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
326 | if (IS_I965G(dev)) { | ||
327 | I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
328 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
329 | } | ||
330 | |||
331 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
332 | |||
333 | i915_restore_palette(dev, PIPE_A); | ||
334 | /* Enable the plane */ | ||
335 | I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
336 | I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); | ||
337 | |||
338 | /* Pipe & plane B info */ | ||
339 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
340 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
341 | ~DPLL_VCO_ENABLE); | ||
342 | DRM_UDELAY(150); | ||
343 | } | ||
344 | I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
345 | I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
346 | /* Actually enable it */ | ||
347 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
348 | DRM_UDELAY(150); | ||
349 | if (IS_I965G(dev)) | ||
350 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
351 | DRM_UDELAY(150); | ||
352 | |||
353 | /* Restore mode */ | ||
354 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
355 | I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
356 | I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
357 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
358 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
359 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
360 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
361 | |||
362 | /* Restore plane info */ | ||
363 | I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
364 | I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
365 | I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
366 | I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); | ||
367 | I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
368 | if (IS_I965G(dev)) { | ||
369 | I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
370 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
371 | } | ||
372 | |||
373 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
374 | |||
375 | i915_restore_palette(dev, PIPE_B); | ||
376 | /* Enable the plane */ | ||
377 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
378 | I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | ||
297 | 379 | ||
380 | return; | ||
381 | } | ||
382 | int i915_save_state(struct drm_device *dev) | ||
383 | { | ||
384 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
385 | int i; | ||
386 | |||
387 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
388 | |||
389 | /* Render Standby */ | ||
390 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
391 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | ||
392 | |||
393 | /* Hardware status page */ | ||
394 | dev_priv->saveHWS = I915_READ(HWS_PGA); | ||
395 | |||
396 | /* Display arbitration control */ | ||
397 | dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
398 | |||
399 | /* This is only meaningful in non-KMS mode */ | ||
400 | /* Don't save them in KMS mode */ | ||
401 | i915_save_modeset_reg(dev); | ||
298 | /* Cursor state */ | 402 | /* Cursor state */ |
299 | dev_priv->saveCURACNTR = I915_READ(CURACNTR); | 403 | dev_priv->saveCURACNTR = I915_READ(CURACNTR); |
300 | dev_priv->saveCURAPOS = I915_READ(CURAPOS); | 404 | dev_priv->saveCURAPOS = I915_READ(CURAPOS); |
@@ -430,92 +534,9 @@ int i915_restore_state(struct drm_device *dev) | |||
430 | I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); | 534 | I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); |
431 | I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); | 535 | I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); |
432 | } | 536 | } |
433 | 537 | /* This is only meaningful in non-KMS mode */ | |
434 | /* Pipe & plane A info */ | 538 | /* Don't restore them in KMS mode */ |
435 | /* Prime the clock */ | 539 | i915_restore_modeset_reg(dev); |
436 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | ||
437 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | ||
438 | ~DPLL_VCO_ENABLE); | ||
439 | DRM_UDELAY(150); | ||
440 | } | ||
441 | I915_WRITE(FPA0, dev_priv->saveFPA0); | ||
442 | I915_WRITE(FPA1, dev_priv->saveFPA1); | ||
443 | /* Actually enable it */ | ||
444 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
445 | DRM_UDELAY(150); | ||
446 | if (IS_I965G(dev)) | ||
447 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
448 | DRM_UDELAY(150); | ||
449 | |||
450 | /* Restore mode */ | ||
451 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
452 | I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
453 | I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
454 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
455 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
456 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
457 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
458 | |||
459 | /* Restore plane info */ | ||
460 | I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
461 | I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
462 | I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
463 | I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); | ||
464 | I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
465 | if (IS_I965G(dev)) { | ||
466 | I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
467 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
468 | } | ||
469 | |||
470 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
471 | |||
472 | i915_restore_palette(dev, PIPE_A); | ||
473 | /* Enable the plane */ | ||
474 | I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
475 | I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); | ||
476 | |||
477 | /* Pipe & plane B info */ | ||
478 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
479 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
480 | ~DPLL_VCO_ENABLE); | ||
481 | DRM_UDELAY(150); | ||
482 | } | ||
483 | I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
484 | I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
485 | /* Actually enable it */ | ||
486 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
487 | DRM_UDELAY(150); | ||
488 | if (IS_I965G(dev)) | ||
489 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
490 | DRM_UDELAY(150); | ||
491 | |||
492 | /* Restore mode */ | ||
493 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
494 | I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
495 | I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
496 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
497 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
498 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
499 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
500 | |||
501 | /* Restore plane info */ | ||
502 | I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
503 | I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
504 | I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
505 | I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); | ||
506 | I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
507 | if (IS_I965G(dev)) { | ||
508 | I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
509 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
510 | } | ||
511 | |||
512 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
513 | |||
514 | i915_restore_palette(dev, PIPE_B); | ||
515 | /* Enable the plane */ | ||
516 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
517 | I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | ||
518 | |||
519 | /* Cursor state */ | 540 | /* Cursor state */ |
520 | I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); | 541 | I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); |
521 | I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); | 542 | I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); |
@@ -577,7 +598,7 @@ int i915_restore_state(struct drm_device *dev) | |||
577 | 598 | ||
578 | for (i = 0; i < 16; i++) { | 599 | for (i = 0; i < 16; i++) { |
579 | I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]); | 600 | I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]); |
580 | I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); | 601 | I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i]); |
581 | } | 602 | } |
582 | for (i = 0; i < 3; i++) | 603 | for (i = 0; i < 3; i++) |
583 | I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); | 604 | I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 716409a57244..300aee3296c2 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -103,7 +103,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
103 | struct bdb_lvds_lfp_data_entry *entry; | 103 | struct bdb_lvds_lfp_data_entry *entry; |
104 | struct lvds_dvo_timing *dvo_timing; | 104 | struct lvds_dvo_timing *dvo_timing; |
105 | struct drm_display_mode *panel_fixed_mode; | 105 | struct drm_display_mode *panel_fixed_mode; |
106 | int lfp_data_size; | 106 | int lfp_data_size, dvo_timing_offset; |
107 | 107 | ||
108 | /* Defaults if we can't find VBT info */ | 108 | /* Defaults if we can't find VBT info */ |
109 | dev_priv->lvds_dither = 0; | 109 | dev_priv->lvds_dither = 0; |
@@ -132,7 +132,16 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
132 | entry = (struct bdb_lvds_lfp_data_entry *) | 132 | entry = (struct bdb_lvds_lfp_data_entry *) |
133 | ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * | 133 | ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * |
134 | lvds_options->panel_type)); | 134 | lvds_options->panel_type)); |
135 | dvo_timing = &entry->dvo_timing; | 135 | dvo_timing_offset = lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset - |
136 | lvds_lfp_data_ptrs->ptr[0].fp_timing_offset; | ||
137 | |||
138 | /* | ||
139 | * the size of fp_timing varies on the different platform. | ||
140 | * So calculate the DVO timing relative offset in LVDS data | ||
141 | * entry to get the DVO timing entry | ||
142 | */ | ||
143 | dvo_timing = (struct lvds_dvo_timing *) | ||
144 | ((unsigned char *)entry + dvo_timing_offset); | ||
136 | 145 | ||
137 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); | 146 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); |
138 | 147 | ||
@@ -195,10 +204,12 @@ parse_general_features(struct drm_i915_private *dev_priv, | |||
195 | dev_priv->lvds_use_ssc = general->enable_ssc; | 204 | dev_priv->lvds_use_ssc = general->enable_ssc; |
196 | 205 | ||
197 | if (dev_priv->lvds_use_ssc) { | 206 | if (dev_priv->lvds_use_ssc) { |
198 | if (IS_I855(dev_priv->dev)) | 207 | if (IS_I85X(dev_priv->dev)) |
199 | dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48; | 208 | dev_priv->lvds_ssc_freq = |
200 | else | 209 | general->ssc_freq ? 66 : 48; |
201 | dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96; | 210 | else |
211 | dev_priv->lvds_ssc_freq = | ||
212 | general->ssc_freq ? 100 : 96; | ||
202 | } | 213 | } |
203 | } | 214 | } |
204 | } | 215 | } |
@@ -285,6 +296,25 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
285 | } | 296 | } |
286 | return; | 297 | return; |
287 | } | 298 | } |
299 | |||
300 | static void | ||
301 | parse_driver_features(struct drm_i915_private *dev_priv, | ||
302 | struct bdb_header *bdb) | ||
303 | { | ||
304 | struct drm_device *dev = dev_priv->dev; | ||
305 | struct bdb_driver_features *driver; | ||
306 | |||
307 | /* set default for chips without eDP */ | ||
308 | if (!SUPPORTS_EDP(dev)) { | ||
309 | dev_priv->edp_support = 0; | ||
310 | return; | ||
311 | } | ||
312 | |||
313 | driver = find_section(bdb, BDB_DRIVER_FEATURES); | ||
314 | if (driver && driver->lvds_config == BDB_DRIVER_FEATURE_EDP) | ||
315 | dev_priv->edp_support = 1; | ||
316 | } | ||
317 | |||
288 | /** | 318 | /** |
289 | * intel_init_bios - initialize VBIOS settings & find VBT | 319 | * intel_init_bios - initialize VBIOS settings & find VBT |
290 | * @dev: DRM device | 320 | * @dev: DRM device |
@@ -335,6 +365,8 @@ intel_init_bios(struct drm_device *dev) | |||
335 | parse_lfp_panel_data(dev_priv, bdb); | 365 | parse_lfp_panel_data(dev_priv, bdb); |
336 | parse_sdvo_panel_data(dev_priv, bdb); | 366 | parse_sdvo_panel_data(dev_priv, bdb); |
337 | parse_sdvo_device_mapping(dev_priv, bdb); | 367 | parse_sdvo_device_mapping(dev_priv, bdb); |
368 | parse_driver_features(dev_priv, bdb); | ||
369 | |||
338 | pci_unmap_rom(pdev, bios); | 370 | pci_unmap_rom(pdev, bios); |
339 | 371 | ||
340 | return 0; | 372 | return 0; |
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index fe72e1c225d8..0f8e5f69ac7a 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h | |||
@@ -381,6 +381,51 @@ struct bdb_sdvo_lvds_options { | |||
381 | } __attribute__((packed)); | 381 | } __attribute__((packed)); |
382 | 382 | ||
383 | 383 | ||
384 | #define BDB_DRIVER_FEATURE_NO_LVDS 0 | ||
385 | #define BDB_DRIVER_FEATURE_INT_LVDS 1 | ||
386 | #define BDB_DRIVER_FEATURE_SDVO_LVDS 2 | ||
387 | #define BDB_DRIVER_FEATURE_EDP 3 | ||
388 | |||
389 | struct bdb_driver_features { | ||
390 | u8 boot_dev_algorithm:1; | ||
391 | u8 block_display_switch:1; | ||
392 | u8 allow_display_switch:1; | ||
393 | u8 hotplug_dvo:1; | ||
394 | u8 dual_view_zoom:1; | ||
395 | u8 int15h_hook:1; | ||
396 | u8 sprite_in_clone:1; | ||
397 | u8 primary_lfp_id:1; | ||
398 | |||
399 | u16 boot_mode_x; | ||
400 | u16 boot_mode_y; | ||
401 | u8 boot_mode_bpp; | ||
402 | u8 boot_mode_refresh; | ||
403 | |||
404 | u16 enable_lfp_primary:1; | ||
405 | u16 selective_mode_pruning:1; | ||
406 | u16 dual_frequency:1; | ||
407 | u16 render_clock_freq:1; /* 0: high freq; 1: low freq */ | ||
408 | u16 nt_clone_support:1; | ||
409 | u16 power_scheme_ui:1; /* 0: CUI; 1: 3rd party */ | ||
410 | u16 sprite_display_assign:1; /* 0: secondary; 1: primary */ | ||
411 | u16 cui_aspect_scaling:1; | ||
412 | u16 preserve_aspect_ratio:1; | ||
413 | u16 sdvo_device_power_down:1; | ||
414 | u16 crt_hotplug:1; | ||
415 | u16 lvds_config:2; | ||
416 | u16 tv_hotplug:1; | ||
417 | u16 hdmi_config:2; | ||
418 | |||
419 | u8 static_display:1; | ||
420 | u8 reserved2:7; | ||
421 | u16 legacy_crt_max_x; | ||
422 | u16 legacy_crt_max_y; | ||
423 | u8 legacy_crt_max_refresh; | ||
424 | |||
425 | u8 hdmi_termination; | ||
426 | u8 custom_vbt_version; | ||
427 | } __attribute__((packed)); | ||
428 | |||
384 | bool intel_init_bios(struct drm_device *dev); | 429 | bool intel_init_bios(struct drm_device *dev); |
385 | 430 | ||
386 | /* | 431 | /* |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 6de97fc66029..4cf8e2e88a40 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -46,7 +46,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode) | |||
46 | 46 | ||
47 | temp = I915_READ(reg); | 47 | temp = I915_READ(reg); |
48 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); | 48 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); |
49 | temp |= ADPA_DAC_ENABLE; | 49 | temp &= ~ADPA_DAC_ENABLE; |
50 | 50 | ||
51 | switch(mode) { | 51 | switch(mode) { |
52 | case DRM_MODE_DPMS_ON: | 52 | case DRM_MODE_DPMS_ON: |
@@ -156,6 +156,9 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector) | |||
156 | 156 | ||
157 | temp = adpa = I915_READ(PCH_ADPA); | 157 | temp = adpa = I915_READ(PCH_ADPA); |
158 | 158 | ||
159 | adpa &= ~ADPA_DAC_ENABLE; | ||
160 | I915_WRITE(PCH_ADPA, adpa); | ||
161 | |||
159 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; | 162 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; |
160 | 163 | ||
161 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | | 164 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | |
@@ -169,13 +172,14 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector) | |||
169 | DRM_DEBUG("pch crt adpa 0x%x", adpa); | 172 | DRM_DEBUG("pch crt adpa 0x%x", adpa); |
170 | I915_WRITE(PCH_ADPA, adpa); | 173 | I915_WRITE(PCH_ADPA, adpa); |
171 | 174 | ||
172 | /* This might not be needed as not specified in spec...*/ | 175 | while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0) |
173 | udelay(1000); | 176 | ; |
174 | 177 | ||
175 | /* Check the status to see if both blue and green are on now */ | 178 | /* Check the status to see if both blue and green are on now */ |
176 | adpa = I915_READ(PCH_ADPA); | 179 | adpa = I915_READ(PCH_ADPA); |
177 | if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) == | 180 | adpa &= ADPA_CRT_HOTPLUG_MONITOR_MASK; |
178 | ADPA_CRT_HOTPLUG_MONITOR_COLOR) | 181 | if ((adpa == ADPA_CRT_HOTPLUG_MONITOR_COLOR) || |
182 | (adpa == ADPA_CRT_HOTPLUG_MONITOR_MONO)) | ||
179 | ret = true; | 183 | ret = true; |
180 | else | 184 | else |
181 | ret = false; | 185 | ret = false; |
@@ -428,8 +432,34 @@ static void intel_crt_destroy(struct drm_connector *connector) | |||
428 | 432 | ||
429 | static int intel_crt_get_modes(struct drm_connector *connector) | 433 | static int intel_crt_get_modes(struct drm_connector *connector) |
430 | { | 434 | { |
435 | int ret; | ||
431 | struct intel_output *intel_output = to_intel_output(connector); | 436 | struct intel_output *intel_output = to_intel_output(connector); |
432 | return intel_ddc_get_modes(intel_output); | 437 | struct i2c_adapter *ddcbus; |
438 | struct drm_device *dev = connector->dev; | ||
439 | |||
440 | |||
441 | ret = intel_ddc_get_modes(intel_output); | ||
442 | if (ret || !IS_G4X(dev)) | ||
443 | goto end; | ||
444 | |||
445 | ddcbus = intel_output->ddc_bus; | ||
446 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ | ||
447 | intel_output->ddc_bus = | ||
448 | intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); | ||
449 | |||
450 | if (!intel_output->ddc_bus) { | ||
451 | intel_output->ddc_bus = ddcbus; | ||
452 | dev_printk(KERN_ERR, &connector->dev->pdev->dev, | ||
453 | "DDC bus registration failed for CRTDDC_D.\n"); | ||
454 | goto end; | ||
455 | } | ||
456 | /* Try to get modes by GPIOD port */ | ||
457 | ret = intel_ddc_get_modes(intel_output); | ||
458 | intel_i2c_destroy(ddcbus); | ||
459 | |||
460 | end: | ||
461 | return ret; | ||
462 | |||
433 | } | 463 | } |
434 | 464 | ||
435 | static int intel_crt_set_property(struct drm_connector *connector, | 465 | static int intel_crt_set_property(struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 73e7b9cecac8..d6fce2133413 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -25,6 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/kernel.h> | ||
28 | #include "drmP.h" | 29 | #include "drmP.h" |
29 | #include "intel_drv.h" | 30 | #include "intel_drv.h" |
30 | #include "i915_drm.h" | 31 | #include "i915_drm.h" |
@@ -33,7 +34,10 @@ | |||
33 | 34 | ||
34 | #include "drm_crtc_helper.h" | 35 | #include "drm_crtc_helper.h" |
35 | 36 | ||
37 | #define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) | ||
38 | |||
36 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); | 39 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); |
40 | static void intel_update_watermarks(struct drm_device *dev); | ||
37 | 41 | ||
38 | typedef struct { | 42 | typedef struct { |
39 | /* given values */ | 43 | /* given values */ |
@@ -86,7 +90,7 @@ struct intel_limit { | |||
86 | #define I8XX_P2_SLOW 4 | 90 | #define I8XX_P2_SLOW 4 |
87 | #define I8XX_P2_FAST 2 | 91 | #define I8XX_P2_FAST 2 |
88 | #define I8XX_P2_LVDS_SLOW 14 | 92 | #define I8XX_P2_LVDS_SLOW 14 |
89 | #define I8XX_P2_LVDS_FAST 14 /* No fast option */ | 93 | #define I8XX_P2_LVDS_FAST 7 |
90 | #define I8XX_P2_SLOW_LIMIT 165000 | 94 | #define I8XX_P2_SLOW_LIMIT 165000 |
91 | 95 | ||
92 | #define I9XX_DOT_MIN 20000 | 96 | #define I9XX_DOT_MIN 20000 |
@@ -266,6 +270,9 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
266 | static bool | 270 | static bool |
267 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, | 271 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, |
268 | int target, int refclk, intel_clock_t *best_clock); | 272 | int target, int refclk, intel_clock_t *best_clock); |
273 | static bool | ||
274 | intel_find_pll_igdng_dp(const intel_limit_t *, struct drm_crtc *crtc, | ||
275 | int target, int refclk, intel_clock_t *best_clock); | ||
269 | 276 | ||
270 | static const intel_limit_t intel_limits_i8xx_dvo = { | 277 | static const intel_limit_t intel_limits_i8xx_dvo = { |
271 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, | 278 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, |
@@ -596,6 +603,23 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) | |||
596 | return false; | 603 | return false; |
597 | } | 604 | } |
598 | 605 | ||
606 | struct drm_connector * | ||
607 | intel_pipe_get_output (struct drm_crtc *crtc) | ||
608 | { | ||
609 | struct drm_device *dev = crtc->dev; | ||
610 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
611 | struct drm_connector *l_entry, *ret = NULL; | ||
612 | |||
613 | list_for_each_entry(l_entry, &mode_config->connector_list, head) { | ||
614 | if (l_entry->encoder && | ||
615 | l_entry->encoder->crtc == crtc) { | ||
616 | ret = l_entry; | ||
617 | break; | ||
618 | } | ||
619 | } | ||
620 | return ret; | ||
621 | } | ||
622 | |||
599 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) | 623 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) |
600 | /** | 624 | /** |
601 | * Returns whether the given set of divisors are valid for a given refclk with | 625 | * Returns whether the given set of divisors are valid for a given refclk with |
@@ -643,7 +667,7 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
643 | int err = target; | 667 | int err = target; |
644 | 668 | ||
645 | if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && | 669 | if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && |
646 | (I915_READ(LVDS) & LVDS_PORT_EN) != 0) { | 670 | (I915_READ(LVDS)) != 0) { |
647 | /* | 671 | /* |
648 | * For LVDS, if the panel is on, just rely on its current | 672 | * For LVDS, if the panel is on, just rely on its current |
649 | * settings for dual-channel. We haven't figured out how to | 673 | * settings for dual-channel. We haven't figured out how to |
@@ -750,6 +774,30 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
750 | } | 774 | } |
751 | 775 | ||
752 | static bool | 776 | static bool |
777 | intel_find_pll_igdng_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
778 | int target, int refclk, intel_clock_t *best_clock) | ||
779 | { | ||
780 | struct drm_device *dev = crtc->dev; | ||
781 | intel_clock_t clock; | ||
782 | if (target < 200000) { | ||
783 | clock.n = 1; | ||
784 | clock.p1 = 2; | ||
785 | clock.p2 = 10; | ||
786 | clock.m1 = 12; | ||
787 | clock.m2 = 9; | ||
788 | } else { | ||
789 | clock.n = 2; | ||
790 | clock.p1 = 1; | ||
791 | clock.p2 = 10; | ||
792 | clock.m1 = 14; | ||
793 | clock.m2 = 8; | ||
794 | } | ||
795 | intel_clock(dev, refclk, &clock); | ||
796 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | ||
797 | return true; | ||
798 | } | ||
799 | |||
800 | static bool | ||
753 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 801 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
754 | int target, int refclk, intel_clock_t *best_clock) | 802 | int target, int refclk, intel_clock_t *best_clock) |
755 | { | 803 | { |
@@ -761,6 +809,14 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
761 | int err_most = 47; | 809 | int err_most = 47; |
762 | found = false; | 810 | found = false; |
763 | 811 | ||
812 | /* eDP has only 2 clock choice, no n/m/p setting */ | ||
813 | if (HAS_eDP) | ||
814 | return true; | ||
815 | |||
816 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) | ||
817 | return intel_find_pll_igdng_dp(limit, crtc, target, | ||
818 | refclk, best_clock); | ||
819 | |||
764 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 820 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
765 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == | 821 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == |
766 | LVDS_CLKB_POWER_UP) | 822 | LVDS_CLKB_POWER_UP) |
@@ -814,24 +870,21 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
814 | { | 870 | { |
815 | intel_clock_t clock; | 871 | intel_clock_t clock; |
816 | if (target < 200000) { | 872 | if (target < 200000) { |
817 | clock.dot = 161670; | ||
818 | clock.p = 20; | ||
819 | clock.p1 = 2; | 873 | clock.p1 = 2; |
820 | clock.p2 = 10; | 874 | clock.p2 = 10; |
821 | clock.n = 0x01; | 875 | clock.n = 2; |
822 | clock.m = 97; | 876 | clock.m1 = 23; |
823 | clock.m1 = 0x10; | 877 | clock.m2 = 8; |
824 | clock.m2 = 0x05; | ||
825 | } else { | 878 | } else { |
826 | clock.dot = 270000; | ||
827 | clock.p = 10; | ||
828 | clock.p1 = 1; | 879 | clock.p1 = 1; |
829 | clock.p2 = 10; | 880 | clock.p2 = 10; |
830 | clock.n = 0x02; | 881 | clock.n = 1; |
831 | clock.m = 108; | 882 | clock.m1 = 14; |
832 | clock.m1 = 0x12; | 883 | clock.m2 = 2; |
833 | clock.m2 = 0x06; | ||
834 | } | 884 | } |
885 | clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2); | ||
886 | clock.p = (clock.p1 * clock.p2); | ||
887 | clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; | ||
835 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | 888 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); |
836 | return true; | 889 | return true; |
837 | } | 890 | } |
@@ -999,13 +1052,97 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
999 | return 0; | 1052 | return 0; |
1000 | } | 1053 | } |
1001 | 1054 | ||
1055 | /* Disable the VGA plane that we never use */ | ||
1056 | static void i915_disable_vga (struct drm_device *dev) | ||
1057 | { | ||
1058 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1059 | u8 sr1; | ||
1060 | u32 vga_reg; | ||
1061 | |||
1062 | if (IS_IGDNG(dev)) | ||
1063 | vga_reg = CPU_VGACNTRL; | ||
1064 | else | ||
1065 | vga_reg = VGACNTRL; | ||
1066 | |||
1067 | if (I915_READ(vga_reg) & VGA_DISP_DISABLE) | ||
1068 | return; | ||
1069 | |||
1070 | I915_WRITE8(VGA_SR_INDEX, 1); | ||
1071 | sr1 = I915_READ8(VGA_SR_DATA); | ||
1072 | I915_WRITE8(VGA_SR_DATA, sr1 | (1 << 5)); | ||
1073 | udelay(100); | ||
1074 | |||
1075 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
1076 | } | ||
1077 | |||
1078 | static void igdng_disable_pll_edp (struct drm_crtc *crtc) | ||
1079 | { | ||
1080 | struct drm_device *dev = crtc->dev; | ||
1081 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1082 | u32 dpa_ctl; | ||
1083 | |||
1084 | DRM_DEBUG("\n"); | ||
1085 | dpa_ctl = I915_READ(DP_A); | ||
1086 | dpa_ctl &= ~DP_PLL_ENABLE; | ||
1087 | I915_WRITE(DP_A, dpa_ctl); | ||
1088 | } | ||
1089 | |||
1090 | static void igdng_enable_pll_edp (struct drm_crtc *crtc) | ||
1091 | { | ||
1092 | struct drm_device *dev = crtc->dev; | ||
1093 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1094 | u32 dpa_ctl; | ||
1095 | |||
1096 | dpa_ctl = I915_READ(DP_A); | ||
1097 | dpa_ctl |= DP_PLL_ENABLE; | ||
1098 | I915_WRITE(DP_A, dpa_ctl); | ||
1099 | udelay(200); | ||
1100 | } | ||
1101 | |||
1102 | |||
1103 | static void igdng_set_pll_edp (struct drm_crtc *crtc, int clock) | ||
1104 | { | ||
1105 | struct drm_device *dev = crtc->dev; | ||
1106 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1107 | u32 dpa_ctl; | ||
1108 | |||
1109 | DRM_DEBUG("eDP PLL enable for clock %d\n", clock); | ||
1110 | dpa_ctl = I915_READ(DP_A); | ||
1111 | dpa_ctl &= ~DP_PLL_FREQ_MASK; | ||
1112 | |||
1113 | if (clock < 200000) { | ||
1114 | u32 temp; | ||
1115 | dpa_ctl |= DP_PLL_FREQ_160MHZ; | ||
1116 | /* workaround for 160Mhz: | ||
1117 | 1) program 0x4600c bits 15:0 = 0x8124 | ||
1118 | 2) program 0x46010 bit 0 = 1 | ||
1119 | 3) program 0x46034 bit 24 = 1 | ||
1120 | 4) program 0x64000 bit 14 = 1 | ||
1121 | */ | ||
1122 | temp = I915_READ(0x4600c); | ||
1123 | temp &= 0xffff0000; | ||
1124 | I915_WRITE(0x4600c, temp | 0x8124); | ||
1125 | |||
1126 | temp = I915_READ(0x46010); | ||
1127 | I915_WRITE(0x46010, temp | 1); | ||
1128 | |||
1129 | temp = I915_READ(0x46034); | ||
1130 | I915_WRITE(0x46034, temp | (1 << 24)); | ||
1131 | } else { | ||
1132 | dpa_ctl |= DP_PLL_FREQ_270MHZ; | ||
1133 | } | ||
1134 | I915_WRITE(DP_A, dpa_ctl); | ||
1135 | |||
1136 | udelay(500); | ||
1137 | } | ||
1138 | |||
1002 | static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | 1139 | static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) |
1003 | { | 1140 | { |
1004 | struct drm_device *dev = crtc->dev; | 1141 | struct drm_device *dev = crtc->dev; |
1005 | struct drm_i915_private *dev_priv = dev->dev_private; | 1142 | struct drm_i915_private *dev_priv = dev->dev_private; |
1006 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1143 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1007 | int pipe = intel_crtc->pipe; | 1144 | int pipe = intel_crtc->pipe; |
1008 | int plane = intel_crtc->pipe; | 1145 | int plane = intel_crtc->plane; |
1009 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; | 1146 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; |
1010 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; | 1147 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; |
1011 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; | 1148 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; |
@@ -1016,6 +1153,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1016 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; | 1153 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; |
1017 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; | 1154 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; |
1018 | int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; | 1155 | int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; |
1156 | int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ; | ||
1019 | int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; | 1157 | int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; |
1020 | int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; | 1158 | int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; |
1021 | int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; | 1159 | int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; |
@@ -1029,7 +1167,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1029 | int trans_vblank_reg = (pipe == 0) ? TRANS_VBLANK_A : TRANS_VBLANK_B; | 1167 | int trans_vblank_reg = (pipe == 0) ? TRANS_VBLANK_A : TRANS_VBLANK_B; |
1030 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; | 1168 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; |
1031 | u32 temp; | 1169 | u32 temp; |
1032 | int tries = 5, j; | 1170 | int tries = 5, j, n; |
1033 | 1171 | ||
1034 | /* XXX: When our outputs are all unaware of DPMS modes other than off | 1172 | /* XXX: When our outputs are all unaware of DPMS modes other than off |
1035 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. | 1173 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. |
@@ -1039,27 +1177,32 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1039 | case DRM_MODE_DPMS_STANDBY: | 1177 | case DRM_MODE_DPMS_STANDBY: |
1040 | case DRM_MODE_DPMS_SUSPEND: | 1178 | case DRM_MODE_DPMS_SUSPEND: |
1041 | DRM_DEBUG("crtc %d dpms on\n", pipe); | 1179 | DRM_DEBUG("crtc %d dpms on\n", pipe); |
1042 | /* enable PCH DPLL */ | 1180 | if (HAS_eDP) { |
1043 | temp = I915_READ(pch_dpll_reg); | 1181 | /* enable eDP PLL */ |
1044 | if ((temp & DPLL_VCO_ENABLE) == 0) { | 1182 | igdng_enable_pll_edp(crtc); |
1045 | I915_WRITE(pch_dpll_reg, temp | DPLL_VCO_ENABLE); | 1183 | } else { |
1046 | I915_READ(pch_dpll_reg); | 1184 | /* enable PCH DPLL */ |
1047 | } | 1185 | temp = I915_READ(pch_dpll_reg); |
1048 | 1186 | if ((temp & DPLL_VCO_ENABLE) == 0) { | |
1049 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ | 1187 | I915_WRITE(pch_dpll_reg, temp | DPLL_VCO_ENABLE); |
1050 | temp = I915_READ(fdi_rx_reg); | 1188 | I915_READ(pch_dpll_reg); |
1051 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | | 1189 | } |
1052 | FDI_SEL_PCDCLK | | ||
1053 | FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ | ||
1054 | I915_READ(fdi_rx_reg); | ||
1055 | udelay(200); | ||
1056 | 1190 | ||
1057 | /* Enable CPU FDI TX PLL, always on for IGDNG */ | 1191 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ |
1058 | temp = I915_READ(fdi_tx_reg); | 1192 | temp = I915_READ(fdi_rx_reg); |
1059 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { | 1193 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | |
1060 | I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE); | 1194 | FDI_SEL_PCDCLK | |
1061 | I915_READ(fdi_tx_reg); | 1195 | FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ |
1062 | udelay(100); | 1196 | I915_READ(fdi_rx_reg); |
1197 | udelay(200); | ||
1198 | |||
1199 | /* Enable CPU FDI TX PLL, always on for IGDNG */ | ||
1200 | temp = I915_READ(fdi_tx_reg); | ||
1201 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { | ||
1202 | I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE); | ||
1203 | I915_READ(fdi_tx_reg); | ||
1204 | udelay(100); | ||
1205 | } | ||
1063 | } | 1206 | } |
1064 | 1207 | ||
1065 | /* Enable CPU pipe */ | 1208 | /* Enable CPU pipe */ |
@@ -1078,122 +1221,126 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1078 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); | 1221 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); |
1079 | } | 1222 | } |
1080 | 1223 | ||
1081 | /* enable CPU FDI TX and PCH FDI RX */ | 1224 | if (!HAS_eDP) { |
1082 | temp = I915_READ(fdi_tx_reg); | 1225 | /* enable CPU FDI TX and PCH FDI RX */ |
1083 | temp |= FDI_TX_ENABLE; | 1226 | temp = I915_READ(fdi_tx_reg); |
1084 | temp |= FDI_DP_PORT_WIDTH_X4; /* default */ | 1227 | temp |= FDI_TX_ENABLE; |
1085 | temp &= ~FDI_LINK_TRAIN_NONE; | 1228 | temp |= FDI_DP_PORT_WIDTH_X4; /* default */ |
1086 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1229 | temp &= ~FDI_LINK_TRAIN_NONE; |
1087 | I915_WRITE(fdi_tx_reg, temp); | 1230 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1088 | I915_READ(fdi_tx_reg); | 1231 | I915_WRITE(fdi_tx_reg, temp); |
1232 | I915_READ(fdi_tx_reg); | ||
1089 | 1233 | ||
1090 | temp = I915_READ(fdi_rx_reg); | 1234 | temp = I915_READ(fdi_rx_reg); |
1091 | temp &= ~FDI_LINK_TRAIN_NONE; | 1235 | temp &= ~FDI_LINK_TRAIN_NONE; |
1092 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1236 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1093 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENABLE); | 1237 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENABLE); |
1094 | I915_READ(fdi_rx_reg); | 1238 | I915_READ(fdi_rx_reg); |
1095 | 1239 | ||
1096 | udelay(150); | 1240 | udelay(150); |
1097 | 1241 | ||
1098 | /* Train FDI. */ | 1242 | /* Train FDI. */ |
1099 | /* umask FDI RX Interrupt symbol_lock and bit_lock bit | 1243 | /* umask FDI RX Interrupt symbol_lock and bit_lock bit |
1100 | for train result */ | 1244 | for train result */ |
1101 | temp = I915_READ(fdi_rx_imr_reg); | 1245 | temp = I915_READ(fdi_rx_imr_reg); |
1102 | temp &= ~FDI_RX_SYMBOL_LOCK; | 1246 | temp &= ~FDI_RX_SYMBOL_LOCK; |
1103 | temp &= ~FDI_RX_BIT_LOCK; | 1247 | temp &= ~FDI_RX_BIT_LOCK; |
1104 | I915_WRITE(fdi_rx_imr_reg, temp); | 1248 | I915_WRITE(fdi_rx_imr_reg, temp); |
1105 | I915_READ(fdi_rx_imr_reg); | 1249 | I915_READ(fdi_rx_imr_reg); |
1106 | udelay(150); | 1250 | udelay(150); |
1107 | 1251 | ||
1108 | temp = I915_READ(fdi_rx_iir_reg); | 1252 | temp = I915_READ(fdi_rx_iir_reg); |
1109 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1253 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1110 | 1254 | ||
1111 | if ((temp & FDI_RX_BIT_LOCK) == 0) { | 1255 | if ((temp & FDI_RX_BIT_LOCK) == 0) { |
1112 | for (j = 0; j < tries; j++) { | 1256 | for (j = 0; j < tries; j++) { |
1113 | temp = I915_READ(fdi_rx_iir_reg); | 1257 | temp = I915_READ(fdi_rx_iir_reg); |
1114 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1258 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1115 | if (temp & FDI_RX_BIT_LOCK) | 1259 | if (temp & FDI_RX_BIT_LOCK) |
1116 | break; | 1260 | break; |
1117 | udelay(200); | 1261 | udelay(200); |
1118 | } | 1262 | } |
1119 | if (j != tries) | 1263 | if (j != tries) |
1264 | I915_WRITE(fdi_rx_iir_reg, | ||
1265 | temp | FDI_RX_BIT_LOCK); | ||
1266 | else | ||
1267 | DRM_DEBUG("train 1 fail\n"); | ||
1268 | } else { | ||
1120 | I915_WRITE(fdi_rx_iir_reg, | 1269 | I915_WRITE(fdi_rx_iir_reg, |
1121 | temp | FDI_RX_BIT_LOCK); | 1270 | temp | FDI_RX_BIT_LOCK); |
1122 | else | 1271 | DRM_DEBUG("train 1 ok 2!\n"); |
1123 | DRM_DEBUG("train 1 fail\n"); | 1272 | } |
1124 | } else { | 1273 | temp = I915_READ(fdi_tx_reg); |
1125 | I915_WRITE(fdi_rx_iir_reg, | 1274 | temp &= ~FDI_LINK_TRAIN_NONE; |
1126 | temp | FDI_RX_BIT_LOCK); | 1275 | temp |= FDI_LINK_TRAIN_PATTERN_2; |
1127 | DRM_DEBUG("train 1 ok 2!\n"); | 1276 | I915_WRITE(fdi_tx_reg, temp); |
1128 | } | 1277 | |
1129 | temp = I915_READ(fdi_tx_reg); | 1278 | temp = I915_READ(fdi_rx_reg); |
1130 | temp &= ~FDI_LINK_TRAIN_NONE; | 1279 | temp &= ~FDI_LINK_TRAIN_NONE; |
1131 | temp |= FDI_LINK_TRAIN_PATTERN_2; | 1280 | temp |= FDI_LINK_TRAIN_PATTERN_2; |
1132 | I915_WRITE(fdi_tx_reg, temp); | 1281 | I915_WRITE(fdi_rx_reg, temp); |
1133 | |||
1134 | temp = I915_READ(fdi_rx_reg); | ||
1135 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1136 | temp |= FDI_LINK_TRAIN_PATTERN_2; | ||
1137 | I915_WRITE(fdi_rx_reg, temp); | ||
1138 | 1282 | ||
1139 | udelay(150); | 1283 | udelay(150); |
1140 | 1284 | ||
1141 | temp = I915_READ(fdi_rx_iir_reg); | 1285 | temp = I915_READ(fdi_rx_iir_reg); |
1142 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1286 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1143 | 1287 | ||
1144 | if ((temp & FDI_RX_SYMBOL_LOCK) == 0) { | 1288 | if ((temp & FDI_RX_SYMBOL_LOCK) == 0) { |
1145 | for (j = 0; j < tries; j++) { | 1289 | for (j = 0; j < tries; j++) { |
1146 | temp = I915_READ(fdi_rx_iir_reg); | 1290 | temp = I915_READ(fdi_rx_iir_reg); |
1147 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); | 1291 | DRM_DEBUG("FDI_RX_IIR 0x%x\n", temp); |
1148 | if (temp & FDI_RX_SYMBOL_LOCK) | 1292 | if (temp & FDI_RX_SYMBOL_LOCK) |
1149 | break; | 1293 | break; |
1150 | udelay(200); | 1294 | udelay(200); |
1151 | } | 1295 | } |
1152 | if (j != tries) { | 1296 | if (j != tries) { |
1297 | I915_WRITE(fdi_rx_iir_reg, | ||
1298 | temp | FDI_RX_SYMBOL_LOCK); | ||
1299 | DRM_DEBUG("train 2 ok 1!\n"); | ||
1300 | } else | ||
1301 | DRM_DEBUG("train 2 fail\n"); | ||
1302 | } else { | ||
1153 | I915_WRITE(fdi_rx_iir_reg, | 1303 | I915_WRITE(fdi_rx_iir_reg, |
1154 | temp | FDI_RX_SYMBOL_LOCK); | 1304 | temp | FDI_RX_SYMBOL_LOCK); |
1155 | DRM_DEBUG("train 2 ok 1!\n"); | 1305 | DRM_DEBUG("train 2 ok 2!\n"); |
1156 | } else | 1306 | } |
1157 | DRM_DEBUG("train 2 fail\n"); | 1307 | DRM_DEBUG("train done\n"); |
1158 | } else { | ||
1159 | I915_WRITE(fdi_rx_iir_reg, temp | FDI_RX_SYMBOL_LOCK); | ||
1160 | DRM_DEBUG("train 2 ok 2!\n"); | ||
1161 | } | ||
1162 | DRM_DEBUG("train done\n"); | ||
1163 | 1308 | ||
1164 | /* set transcoder timing */ | 1309 | /* set transcoder timing */ |
1165 | I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg)); | 1310 | I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg)); |
1166 | I915_WRITE(trans_hblank_reg, I915_READ(cpu_hblank_reg)); | 1311 | I915_WRITE(trans_hblank_reg, I915_READ(cpu_hblank_reg)); |
1167 | I915_WRITE(trans_hsync_reg, I915_READ(cpu_hsync_reg)); | 1312 | I915_WRITE(trans_hsync_reg, I915_READ(cpu_hsync_reg)); |
1168 | 1313 | ||
1169 | I915_WRITE(trans_vtot_reg, I915_READ(cpu_vtot_reg)); | 1314 | I915_WRITE(trans_vtot_reg, I915_READ(cpu_vtot_reg)); |
1170 | I915_WRITE(trans_vblank_reg, I915_READ(cpu_vblank_reg)); | 1315 | I915_WRITE(trans_vblank_reg, I915_READ(cpu_vblank_reg)); |
1171 | I915_WRITE(trans_vsync_reg, I915_READ(cpu_vsync_reg)); | 1316 | I915_WRITE(trans_vsync_reg, I915_READ(cpu_vsync_reg)); |
1172 | 1317 | ||
1173 | /* enable PCH transcoder */ | 1318 | /* enable PCH transcoder */ |
1174 | temp = I915_READ(transconf_reg); | 1319 | temp = I915_READ(transconf_reg); |
1175 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | 1320 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); |
1176 | I915_READ(transconf_reg); | 1321 | I915_READ(transconf_reg); |
1177 | 1322 | ||
1178 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) | 1323 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) |
1179 | ; | 1324 | ; |
1180 | 1325 | ||
1181 | /* enable normal */ | 1326 | /* enable normal */ |
1182 | 1327 | ||
1183 | temp = I915_READ(fdi_tx_reg); | 1328 | temp = I915_READ(fdi_tx_reg); |
1184 | temp &= ~FDI_LINK_TRAIN_NONE; | 1329 | temp &= ~FDI_LINK_TRAIN_NONE; |
1185 | I915_WRITE(fdi_tx_reg, temp | FDI_LINK_TRAIN_NONE | | 1330 | I915_WRITE(fdi_tx_reg, temp | FDI_LINK_TRAIN_NONE | |
1186 | FDI_TX_ENHANCE_FRAME_ENABLE); | 1331 | FDI_TX_ENHANCE_FRAME_ENABLE); |
1187 | I915_READ(fdi_tx_reg); | 1332 | I915_READ(fdi_tx_reg); |
1188 | 1333 | ||
1189 | temp = I915_READ(fdi_rx_reg); | 1334 | temp = I915_READ(fdi_rx_reg); |
1190 | temp &= ~FDI_LINK_TRAIN_NONE; | 1335 | temp &= ~FDI_LINK_TRAIN_NONE; |
1191 | I915_WRITE(fdi_rx_reg, temp | FDI_LINK_TRAIN_NONE | | 1336 | I915_WRITE(fdi_rx_reg, temp | FDI_LINK_TRAIN_NONE | |
1192 | FDI_RX_ENHANCE_FRAME_ENABLE); | 1337 | FDI_RX_ENHANCE_FRAME_ENABLE); |
1193 | I915_READ(fdi_rx_reg); | 1338 | I915_READ(fdi_rx_reg); |
1194 | 1339 | ||
1195 | /* wait one idle pattern time */ | 1340 | /* wait one idle pattern time */ |
1196 | udelay(100); | 1341 | udelay(100); |
1342 | |||
1343 | } | ||
1197 | 1344 | ||
1198 | intel_crtc_load_lut(crtc); | 1345 | intel_crtc_load_lut(crtc); |
1199 | 1346 | ||
@@ -1201,8 +1348,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1201 | case DRM_MODE_DPMS_OFF: | 1348 | case DRM_MODE_DPMS_OFF: |
1202 | DRM_DEBUG("crtc %d dpms off\n", pipe); | 1349 | DRM_DEBUG("crtc %d dpms off\n", pipe); |
1203 | 1350 | ||
1204 | /* Disable the VGA plane that we never use */ | 1351 | i915_disable_vga(dev); |
1205 | I915_WRITE(CPU_VGACNTRL, VGA_DISP_DISABLE); | ||
1206 | 1352 | ||
1207 | /* Disable display plane */ | 1353 | /* Disable display plane */ |
1208 | temp = I915_READ(dspcntr_reg); | 1354 | temp = I915_READ(dspcntr_reg); |
@@ -1218,17 +1364,23 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1218 | if ((temp & PIPEACONF_ENABLE) != 0) { | 1364 | if ((temp & PIPEACONF_ENABLE) != 0) { |
1219 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); | 1365 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); |
1220 | I915_READ(pipeconf_reg); | 1366 | I915_READ(pipeconf_reg); |
1367 | n = 0; | ||
1221 | /* wait for cpu pipe off, pipe state */ | 1368 | /* wait for cpu pipe off, pipe state */ |
1222 | while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) | 1369 | while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) { |
1223 | ; | 1370 | n++; |
1371 | if (n < 60) { | ||
1372 | udelay(500); | ||
1373 | continue; | ||
1374 | } else { | ||
1375 | DRM_DEBUG("pipe %d off delay\n", pipe); | ||
1376 | break; | ||
1377 | } | ||
1378 | } | ||
1224 | } else | 1379 | } else |
1225 | DRM_DEBUG("crtc %d is disabled\n", pipe); | 1380 | DRM_DEBUG("crtc %d is disabled\n", pipe); |
1226 | 1381 | ||
1227 | /* IGDNG-A : disable cpu panel fitter ? */ | 1382 | if (HAS_eDP) { |
1228 | temp = I915_READ(pf_ctl_reg); | 1383 | igdng_disable_pll_edp(crtc); |
1229 | if ((temp & PF_ENABLE) != 0) { | ||
1230 | I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); | ||
1231 | I915_READ(pf_ctl_reg); | ||
1232 | } | 1384 | } |
1233 | 1385 | ||
1234 | /* disable CPU FDI tx and PCH FDI rx */ | 1386 | /* disable CPU FDI tx and PCH FDI rx */ |
@@ -1240,6 +1392,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1240 | I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE); | 1392 | I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE); |
1241 | I915_READ(fdi_rx_reg); | 1393 | I915_READ(fdi_rx_reg); |
1242 | 1394 | ||
1395 | udelay(100); | ||
1396 | |||
1243 | /* still set train pattern 1 */ | 1397 | /* still set train pattern 1 */ |
1244 | temp = I915_READ(fdi_tx_reg); | 1398 | temp = I915_READ(fdi_tx_reg); |
1245 | temp &= ~FDI_LINK_TRAIN_NONE; | 1399 | temp &= ~FDI_LINK_TRAIN_NONE; |
@@ -1251,14 +1405,25 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1251 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1405 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1252 | I915_WRITE(fdi_rx_reg, temp); | 1406 | I915_WRITE(fdi_rx_reg, temp); |
1253 | 1407 | ||
1408 | udelay(100); | ||
1409 | |||
1254 | /* disable PCH transcoder */ | 1410 | /* disable PCH transcoder */ |
1255 | temp = I915_READ(transconf_reg); | 1411 | temp = I915_READ(transconf_reg); |
1256 | if ((temp & TRANS_ENABLE) != 0) { | 1412 | if ((temp & TRANS_ENABLE) != 0) { |
1257 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); | 1413 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); |
1258 | I915_READ(transconf_reg); | 1414 | I915_READ(transconf_reg); |
1415 | n = 0; | ||
1259 | /* wait for PCH transcoder off, transcoder state */ | 1416 | /* wait for PCH transcoder off, transcoder state */ |
1260 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) | 1417 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) { |
1261 | ; | 1418 | n++; |
1419 | if (n < 60) { | ||
1420 | udelay(500); | ||
1421 | continue; | ||
1422 | } else { | ||
1423 | DRM_DEBUG("transcoder %d off delay\n", pipe); | ||
1424 | break; | ||
1425 | } | ||
1426 | } | ||
1262 | } | 1427 | } |
1263 | 1428 | ||
1264 | /* disable PCH DPLL */ | 1429 | /* disable PCH DPLL */ |
@@ -1276,6 +1441,22 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1276 | I915_READ(fdi_rx_reg); | 1441 | I915_READ(fdi_rx_reg); |
1277 | } | 1442 | } |
1278 | 1443 | ||
1444 | /* Disable CPU FDI TX PLL */ | ||
1445 | temp = I915_READ(fdi_tx_reg); | ||
1446 | if ((temp & FDI_TX_PLL_ENABLE) != 0) { | ||
1447 | I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_PLL_ENABLE); | ||
1448 | I915_READ(fdi_tx_reg); | ||
1449 | udelay(100); | ||
1450 | } | ||
1451 | |||
1452 | /* Disable PF */ | ||
1453 | temp = I915_READ(pf_ctl_reg); | ||
1454 | if ((temp & PF_ENABLE) != 0) { | ||
1455 | I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); | ||
1456 | I915_READ(pf_ctl_reg); | ||
1457 | } | ||
1458 | I915_WRITE(pf_win_size, 0); | ||
1459 | |||
1279 | /* Wait for the clocks to turn off. */ | 1460 | /* Wait for the clocks to turn off. */ |
1280 | udelay(150); | 1461 | udelay(150); |
1281 | break; | 1462 | break; |
@@ -1335,13 +1516,15 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1335 | 1516 | ||
1336 | /* Give the overlay scaler a chance to enable if it's on this pipe */ | 1517 | /* Give the overlay scaler a chance to enable if it's on this pipe */ |
1337 | //intel_crtc_dpms_video(crtc, true); TODO | 1518 | //intel_crtc_dpms_video(crtc, true); TODO |
1519 | intel_update_watermarks(dev); | ||
1338 | break; | 1520 | break; |
1339 | case DRM_MODE_DPMS_OFF: | 1521 | case DRM_MODE_DPMS_OFF: |
1522 | intel_update_watermarks(dev); | ||
1340 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 1523 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
1341 | //intel_crtc_dpms_video(crtc, FALSE); TODO | 1524 | //intel_crtc_dpms_video(crtc, FALSE); TODO |
1342 | 1525 | ||
1343 | /* Disable the VGA plane that we never use */ | 1526 | /* Disable the VGA plane that we never use */ |
1344 | I915_WRITE(VGACNTRL, VGA_DISP_DISABLE); | 1527 | i915_disable_vga(dev); |
1345 | 1528 | ||
1346 | /* Disable display plane */ | 1529 | /* Disable display plane */ |
1347 | temp = I915_READ(dspcntr_reg); | 1530 | temp = I915_READ(dspcntr_reg); |
@@ -1515,7 +1698,6 @@ static int intel_get_core_clock_speed(struct drm_device *dev) | |||
1515 | return 0; /* Silence gcc warning */ | 1698 | return 0; /* Silence gcc warning */ |
1516 | } | 1699 | } |
1517 | 1700 | ||
1518 | |||
1519 | /** | 1701 | /** |
1520 | * Return the pipe currently connected to the panel fitter, | 1702 | * Return the pipe currently connected to the panel fitter, |
1521 | * or -1 if the panel fitter is not present or not in use | 1703 | * or -1 if the panel fitter is not present or not in use |
@@ -1574,7 +1756,7 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes, | |||
1574 | 1756 | ||
1575 | temp = (u64) DATA_N * pixel_clock; | 1757 | temp = (u64) DATA_N * pixel_clock; |
1576 | temp = div_u64(temp, link_clock); | 1758 | temp = div_u64(temp, link_clock); |
1577 | m_n->gmch_m = (temp * bytes_per_pixel) / nlanes; | 1759 | m_n->gmch_m = div_u64(temp * bytes_per_pixel, nlanes); |
1578 | m_n->gmch_n = DATA_N; | 1760 | m_n->gmch_n = DATA_N; |
1579 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | 1761 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
1580 | 1762 | ||
@@ -1585,6 +1767,464 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes, | |||
1585 | } | 1767 | } |
1586 | 1768 | ||
1587 | 1769 | ||
1770 | struct intel_watermark_params { | ||
1771 | unsigned long fifo_size; | ||
1772 | unsigned long max_wm; | ||
1773 | unsigned long default_wm; | ||
1774 | unsigned long guard_size; | ||
1775 | unsigned long cacheline_size; | ||
1776 | }; | ||
1777 | |||
1778 | /* IGD has different values for various configs */ | ||
1779 | static struct intel_watermark_params igd_display_wm = { | ||
1780 | IGD_DISPLAY_FIFO, | ||
1781 | IGD_MAX_WM, | ||
1782 | IGD_DFT_WM, | ||
1783 | IGD_GUARD_WM, | ||
1784 | IGD_FIFO_LINE_SIZE | ||
1785 | }; | ||
1786 | static struct intel_watermark_params igd_display_hplloff_wm = { | ||
1787 | IGD_DISPLAY_FIFO, | ||
1788 | IGD_MAX_WM, | ||
1789 | IGD_DFT_HPLLOFF_WM, | ||
1790 | IGD_GUARD_WM, | ||
1791 | IGD_FIFO_LINE_SIZE | ||
1792 | }; | ||
1793 | static struct intel_watermark_params igd_cursor_wm = { | ||
1794 | IGD_CURSOR_FIFO, | ||
1795 | IGD_CURSOR_MAX_WM, | ||
1796 | IGD_CURSOR_DFT_WM, | ||
1797 | IGD_CURSOR_GUARD_WM, | ||
1798 | IGD_FIFO_LINE_SIZE, | ||
1799 | }; | ||
1800 | static struct intel_watermark_params igd_cursor_hplloff_wm = { | ||
1801 | IGD_CURSOR_FIFO, | ||
1802 | IGD_CURSOR_MAX_WM, | ||
1803 | IGD_CURSOR_DFT_WM, | ||
1804 | IGD_CURSOR_GUARD_WM, | ||
1805 | IGD_FIFO_LINE_SIZE | ||
1806 | }; | ||
1807 | static struct intel_watermark_params i945_wm_info = { | ||
1808 | I945_FIFO_SIZE, | ||
1809 | I915_MAX_WM, | ||
1810 | 1, | ||
1811 | 2, | ||
1812 | I915_FIFO_LINE_SIZE | ||
1813 | }; | ||
1814 | static struct intel_watermark_params i915_wm_info = { | ||
1815 | I915_FIFO_SIZE, | ||
1816 | I915_MAX_WM, | ||
1817 | 1, | ||
1818 | 2, | ||
1819 | I915_FIFO_LINE_SIZE | ||
1820 | }; | ||
1821 | static struct intel_watermark_params i855_wm_info = { | ||
1822 | I855GM_FIFO_SIZE, | ||
1823 | I915_MAX_WM, | ||
1824 | 1, | ||
1825 | 2, | ||
1826 | I830_FIFO_LINE_SIZE | ||
1827 | }; | ||
1828 | static struct intel_watermark_params i830_wm_info = { | ||
1829 | I830_FIFO_SIZE, | ||
1830 | I915_MAX_WM, | ||
1831 | 1, | ||
1832 | 2, | ||
1833 | I830_FIFO_LINE_SIZE | ||
1834 | }; | ||
1835 | |||
1836 | /** | ||
1837 | * intel_calculate_wm - calculate watermark level | ||
1838 | * @clock_in_khz: pixel clock | ||
1839 | * @wm: chip FIFO params | ||
1840 | * @pixel_size: display pixel size | ||
1841 | * @latency_ns: memory latency for the platform | ||
1842 | * | ||
1843 | * Calculate the watermark level (the level at which the display plane will | ||
1844 | * start fetching from memory again). Each chip has a different display | ||
1845 | * FIFO size and allocation, so the caller needs to figure that out and pass | ||
1846 | * in the correct intel_watermark_params structure. | ||
1847 | * | ||
1848 | * As the pixel clock runs, the FIFO will be drained at a rate that depends | ||
1849 | * on the pixel size. When it reaches the watermark level, it'll start | ||
1850 | * fetching FIFO line sized based chunks from memory until the FIFO fills | ||
1851 | * past the watermark point. If the FIFO drains completely, a FIFO underrun | ||
1852 | * will occur, and a display engine hang could result. | ||
1853 | */ | ||
1854 | static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | ||
1855 | struct intel_watermark_params *wm, | ||
1856 | int pixel_size, | ||
1857 | unsigned long latency_ns) | ||
1858 | { | ||
1859 | long entries_required, wm_size; | ||
1860 | |||
1861 | entries_required = (clock_in_khz * pixel_size * latency_ns) / 1000000; | ||
1862 | entries_required /= wm->cacheline_size; | ||
1863 | |||
1864 | DRM_DEBUG("FIFO entries required for mode: %d\n", entries_required); | ||
1865 | |||
1866 | wm_size = wm->fifo_size - (entries_required + wm->guard_size); | ||
1867 | |||
1868 | DRM_DEBUG("FIFO watermark level: %d\n", wm_size); | ||
1869 | |||
1870 | /* Don't promote wm_size to unsigned... */ | ||
1871 | if (wm_size > (long)wm->max_wm) | ||
1872 | wm_size = wm->max_wm; | ||
1873 | if (wm_size <= 0) | ||
1874 | wm_size = wm->default_wm; | ||
1875 | return wm_size; | ||
1876 | } | ||
1877 | |||
1878 | struct cxsr_latency { | ||
1879 | int is_desktop; | ||
1880 | unsigned long fsb_freq; | ||
1881 | unsigned long mem_freq; | ||
1882 | unsigned long display_sr; | ||
1883 | unsigned long display_hpll_disable; | ||
1884 | unsigned long cursor_sr; | ||
1885 | unsigned long cursor_hpll_disable; | ||
1886 | }; | ||
1887 | |||
1888 | static struct cxsr_latency cxsr_latency_table[] = { | ||
1889 | {1, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | ||
1890 | {1, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | ||
1891 | {1, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | ||
1892 | |||
1893 | {1, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ | ||
1894 | {1, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ | ||
1895 | {1, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ | ||
1896 | |||
1897 | {1, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ | ||
1898 | {1, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ | ||
1899 | {1, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ | ||
1900 | |||
1901 | {0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ | ||
1902 | {0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ | ||
1903 | {0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ | ||
1904 | |||
1905 | {0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ | ||
1906 | {0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ | ||
1907 | {0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ | ||
1908 | |||
1909 | {0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ | ||
1910 | {0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ | ||
1911 | {0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ | ||
1912 | }; | ||
1913 | |||
1914 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, | ||
1915 | int mem) | ||
1916 | { | ||
1917 | int i; | ||
1918 | struct cxsr_latency *latency; | ||
1919 | |||
1920 | if (fsb == 0 || mem == 0) | ||
1921 | return NULL; | ||
1922 | |||
1923 | for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { | ||
1924 | latency = &cxsr_latency_table[i]; | ||
1925 | if (is_desktop == latency->is_desktop && | ||
1926 | fsb == latency->fsb_freq && mem == latency->mem_freq) | ||
1927 | break; | ||
1928 | } | ||
1929 | if (i >= ARRAY_SIZE(cxsr_latency_table)) { | ||
1930 | DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n"); | ||
1931 | return NULL; | ||
1932 | } | ||
1933 | return latency; | ||
1934 | } | ||
1935 | |||
1936 | static void igd_disable_cxsr(struct drm_device *dev) | ||
1937 | { | ||
1938 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1939 | u32 reg; | ||
1940 | |||
1941 | /* deactivate cxsr */ | ||
1942 | reg = I915_READ(DSPFW3); | ||
1943 | reg &= ~(IGD_SELF_REFRESH_EN); | ||
1944 | I915_WRITE(DSPFW3, reg); | ||
1945 | DRM_INFO("Big FIFO is disabled\n"); | ||
1946 | } | ||
1947 | |||
1948 | static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock, | ||
1949 | int pixel_size) | ||
1950 | { | ||
1951 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1952 | u32 reg; | ||
1953 | unsigned long wm; | ||
1954 | struct cxsr_latency *latency; | ||
1955 | |||
1956 | latency = intel_get_cxsr_latency(IS_IGDG(dev), dev_priv->fsb_freq, | ||
1957 | dev_priv->mem_freq); | ||
1958 | if (!latency) { | ||
1959 | DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n"); | ||
1960 | igd_disable_cxsr(dev); | ||
1961 | return; | ||
1962 | } | ||
1963 | |||
1964 | /* Display SR */ | ||
1965 | wm = intel_calculate_wm(clock, &igd_display_wm, pixel_size, | ||
1966 | latency->display_sr); | ||
1967 | reg = I915_READ(DSPFW1); | ||
1968 | reg &= 0x7fffff; | ||
1969 | reg |= wm << 23; | ||
1970 | I915_WRITE(DSPFW1, reg); | ||
1971 | DRM_DEBUG("DSPFW1 register is %x\n", reg); | ||
1972 | |||
1973 | /* cursor SR */ | ||
1974 | wm = intel_calculate_wm(clock, &igd_cursor_wm, pixel_size, | ||
1975 | latency->cursor_sr); | ||
1976 | reg = I915_READ(DSPFW3); | ||
1977 | reg &= ~(0x3f << 24); | ||
1978 | reg |= (wm & 0x3f) << 24; | ||
1979 | I915_WRITE(DSPFW3, reg); | ||
1980 | |||
1981 | /* Display HPLL off SR */ | ||
1982 | wm = intel_calculate_wm(clock, &igd_display_hplloff_wm, | ||
1983 | latency->display_hpll_disable, I915_FIFO_LINE_SIZE); | ||
1984 | reg = I915_READ(DSPFW3); | ||
1985 | reg &= 0xfffffe00; | ||
1986 | reg |= wm & 0x1ff; | ||
1987 | I915_WRITE(DSPFW3, reg); | ||
1988 | |||
1989 | /* cursor HPLL off SR */ | ||
1990 | wm = intel_calculate_wm(clock, &igd_cursor_hplloff_wm, pixel_size, | ||
1991 | latency->cursor_hpll_disable); | ||
1992 | reg = I915_READ(DSPFW3); | ||
1993 | reg &= ~(0x3f << 16); | ||
1994 | reg |= (wm & 0x3f) << 16; | ||
1995 | I915_WRITE(DSPFW3, reg); | ||
1996 | DRM_DEBUG("DSPFW3 register is %x\n", reg); | ||
1997 | |||
1998 | /* activate cxsr */ | ||
1999 | reg = I915_READ(DSPFW3); | ||
2000 | reg |= IGD_SELF_REFRESH_EN; | ||
2001 | I915_WRITE(DSPFW3, reg); | ||
2002 | |||
2003 | DRM_INFO("Big FIFO is enabled\n"); | ||
2004 | |||
2005 | return; | ||
2006 | } | ||
2007 | |||
2008 | const static int latency_ns = 3000; /* default for non-igd platforms */ | ||
2009 | |||
2010 | static int intel_get_fifo_size(struct drm_device *dev, int plane) | ||
2011 | { | ||
2012 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2013 | uint32_t dsparb = I915_READ(DSPARB); | ||
2014 | int size; | ||
2015 | |||
2016 | if (IS_I9XX(dev)) { | ||
2017 | if (plane == 0) | ||
2018 | size = dsparb & 0x7f; | ||
2019 | else | ||
2020 | size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - | ||
2021 | (dsparb & 0x7f); | ||
2022 | } else if (IS_I85X(dev)) { | ||
2023 | if (plane == 0) | ||
2024 | size = dsparb & 0x1ff; | ||
2025 | else | ||
2026 | size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - | ||
2027 | (dsparb & 0x1ff); | ||
2028 | size >>= 1; /* Convert to cachelines */ | ||
2029 | } else if (IS_845G(dev)) { | ||
2030 | size = dsparb & 0x7f; | ||
2031 | size >>= 2; /* Convert to cachelines */ | ||
2032 | } else { | ||
2033 | size = dsparb & 0x7f; | ||
2034 | size >>= 1; /* Convert to cachelines */ | ||
2035 | } | ||
2036 | |||
2037 | DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A", | ||
2038 | size); | ||
2039 | |||
2040 | return size; | ||
2041 | } | ||
2042 | |||
2043 | static void i965_update_wm(struct drm_device *dev) | ||
2044 | { | ||
2045 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2046 | |||
2047 | DRM_DEBUG("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR 8\n"); | ||
2048 | |||
2049 | /* 965 has limitations... */ | ||
2050 | I915_WRITE(DSPFW1, (8 << 16) | (8 << 8) | (8 << 0)); | ||
2051 | I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); | ||
2052 | } | ||
2053 | |||
2054 | static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | ||
2055 | int planeb_clock, int sr_hdisplay, int pixel_size) | ||
2056 | { | ||
2057 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2058 | uint32_t fwater_lo; | ||
2059 | uint32_t fwater_hi; | ||
2060 | int total_size, cacheline_size, cwm, srwm = 1; | ||
2061 | int planea_wm, planeb_wm; | ||
2062 | struct intel_watermark_params planea_params, planeb_params; | ||
2063 | unsigned long line_time_us; | ||
2064 | int sr_clock, sr_entries = 0; | ||
2065 | |||
2066 | /* Create copies of the base settings for each pipe */ | ||
2067 | if (IS_I965GM(dev) || IS_I945GM(dev)) | ||
2068 | planea_params = planeb_params = i945_wm_info; | ||
2069 | else if (IS_I9XX(dev)) | ||
2070 | planea_params = planeb_params = i915_wm_info; | ||
2071 | else | ||
2072 | planea_params = planeb_params = i855_wm_info; | ||
2073 | |||
2074 | /* Grab a couple of global values before we overwrite them */ | ||
2075 | total_size = planea_params.fifo_size; | ||
2076 | cacheline_size = planea_params.cacheline_size; | ||
2077 | |||
2078 | /* Update per-plane FIFO sizes */ | ||
2079 | planea_params.fifo_size = intel_get_fifo_size(dev, 0); | ||
2080 | planeb_params.fifo_size = intel_get_fifo_size(dev, 1); | ||
2081 | |||
2082 | planea_wm = intel_calculate_wm(planea_clock, &planea_params, | ||
2083 | pixel_size, latency_ns); | ||
2084 | planeb_wm = intel_calculate_wm(planeb_clock, &planeb_params, | ||
2085 | pixel_size, latency_ns); | ||
2086 | DRM_DEBUG("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); | ||
2087 | |||
2088 | /* | ||
2089 | * Overlay gets an aggressive default since video jitter is bad. | ||
2090 | */ | ||
2091 | cwm = 2; | ||
2092 | |||
2093 | /* Calc sr entries for one plane configs */ | ||
2094 | if (sr_hdisplay && (!planea_clock || !planeb_clock)) { | ||
2095 | /* self-refresh has much higher latency */ | ||
2096 | const static int sr_latency_ns = 6000; | ||
2097 | |||
2098 | sr_clock = planea_clock ? planea_clock : planeb_clock; | ||
2099 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); | ||
2100 | |||
2101 | /* Use ns/us then divide to preserve precision */ | ||
2102 | sr_entries = (((sr_latency_ns / line_time_us) + 1) * | ||
2103 | pixel_size * sr_hdisplay) / 1000; | ||
2104 | sr_entries = roundup(sr_entries / cacheline_size, 1); | ||
2105 | DRM_DEBUG("self-refresh entries: %d\n", sr_entries); | ||
2106 | srwm = total_size - sr_entries; | ||
2107 | if (srwm < 0) | ||
2108 | srwm = 1; | ||
2109 | if (IS_I9XX(dev)) | ||
2110 | I915_WRITE(FW_BLC_SELF, (srwm & 0x3f)); | ||
2111 | } | ||
2112 | |||
2113 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", | ||
2114 | planea_wm, planeb_wm, cwm, srwm); | ||
2115 | |||
2116 | fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f); | ||
2117 | fwater_hi = (cwm & 0x1f); | ||
2118 | |||
2119 | /* Set request length to 8 cachelines per fetch */ | ||
2120 | fwater_lo = fwater_lo | (1 << 24) | (1 << 8); | ||
2121 | fwater_hi = fwater_hi | (1 << 8); | ||
2122 | |||
2123 | I915_WRITE(FW_BLC, fwater_lo); | ||
2124 | I915_WRITE(FW_BLC2, fwater_hi); | ||
2125 | } | ||
2126 | |||
2127 | static void i830_update_wm(struct drm_device *dev, int planea_clock, | ||
2128 | int pixel_size) | ||
2129 | { | ||
2130 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2131 | uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff; | ||
2132 | int planea_wm; | ||
2133 | |||
2134 | i830_wm_info.fifo_size = intel_get_fifo_size(dev, 0); | ||
2135 | |||
2136 | planea_wm = intel_calculate_wm(planea_clock, &i830_wm_info, | ||
2137 | pixel_size, latency_ns); | ||
2138 | fwater_lo |= (3<<8) | planea_wm; | ||
2139 | |||
2140 | DRM_DEBUG("Setting FIFO watermarks - A: %d\n", planea_wm); | ||
2141 | |||
2142 | I915_WRITE(FW_BLC, fwater_lo); | ||
2143 | } | ||
2144 | |||
2145 | /** | ||
2146 | * intel_update_watermarks - update FIFO watermark values based on current modes | ||
2147 | * | ||
2148 | * Calculate watermark values for the various WM regs based on current mode | ||
2149 | * and plane configuration. | ||
2150 | * | ||
2151 | * There are several cases to deal with here: | ||
2152 | * - normal (i.e. non-self-refresh) | ||
2153 | * - self-refresh (SR) mode | ||
2154 | * - lines are large relative to FIFO size (buffer can hold up to 2) | ||
2155 | * - lines are small relative to FIFO size (buffer can hold more than 2 | ||
2156 | * lines), so need to account for TLB latency | ||
2157 | * | ||
2158 | * The normal calculation is: | ||
2159 | * watermark = dotclock * bytes per pixel * latency | ||
2160 | * where latency is platform & configuration dependent (we assume pessimal | ||
2161 | * values here). | ||
2162 | * | ||
2163 | * The SR calculation is: | ||
2164 | * watermark = (trunc(latency/line time)+1) * surface width * | ||
2165 | * bytes per pixel | ||
2166 | * where | ||
2167 | * line time = htotal / dotclock | ||
2168 | * and latency is assumed to be high, as above. | ||
2169 | * | ||
2170 | * The final value programmed to the register should always be rounded up, | ||
2171 | * and include an extra 2 entries to account for clock crossings. | ||
2172 | * | ||
2173 | * We don't use the sprite, so we can ignore that. And on Crestline we have | ||
2174 | * to set the non-SR watermarks to 8. | ||
2175 | */ | ||
2176 | static void intel_update_watermarks(struct drm_device *dev) | ||
2177 | { | ||
2178 | struct drm_crtc *crtc; | ||
2179 | struct intel_crtc *intel_crtc; | ||
2180 | int sr_hdisplay = 0; | ||
2181 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; | ||
2182 | int enabled = 0, pixel_size = 0; | ||
2183 | |||
2184 | if (DSPARB_HWCONTROL(dev)) | ||
2185 | return; | ||
2186 | |||
2187 | /* Get the clock config from both planes */ | ||
2188 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
2189 | intel_crtc = to_intel_crtc(crtc); | ||
2190 | if (crtc->enabled) { | ||
2191 | enabled++; | ||
2192 | if (intel_crtc->plane == 0) { | ||
2193 | DRM_DEBUG("plane A (pipe %d) clock: %d\n", | ||
2194 | intel_crtc->pipe, crtc->mode.clock); | ||
2195 | planea_clock = crtc->mode.clock; | ||
2196 | } else { | ||
2197 | DRM_DEBUG("plane B (pipe %d) clock: %d\n", | ||
2198 | intel_crtc->pipe, crtc->mode.clock); | ||
2199 | planeb_clock = crtc->mode.clock; | ||
2200 | } | ||
2201 | sr_hdisplay = crtc->mode.hdisplay; | ||
2202 | sr_clock = crtc->mode.clock; | ||
2203 | if (crtc->fb) | ||
2204 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
2205 | else | ||
2206 | pixel_size = 4; /* by default */ | ||
2207 | } | ||
2208 | } | ||
2209 | |||
2210 | if (enabled <= 0) | ||
2211 | return; | ||
2212 | |||
2213 | /* Single plane configs can enable self refresh */ | ||
2214 | if (enabled == 1 && IS_IGD(dev)) | ||
2215 | igd_enable_cxsr(dev, sr_clock, pixel_size); | ||
2216 | else if (IS_IGD(dev)) | ||
2217 | igd_disable_cxsr(dev); | ||
2218 | |||
2219 | if (IS_I965G(dev)) | ||
2220 | i965_update_wm(dev); | ||
2221 | else if (IS_I9XX(dev) || IS_MOBILE(dev)) | ||
2222 | i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, | ||
2223 | pixel_size); | ||
2224 | else | ||
2225 | i830_update_wm(dev, planea_clock, pixel_size); | ||
2226 | } | ||
2227 | |||
1588 | static int intel_crtc_mode_set(struct drm_crtc *crtc, | 2228 | static int intel_crtc_mode_set(struct drm_crtc *crtc, |
1589 | struct drm_display_mode *mode, | 2229 | struct drm_display_mode *mode, |
1590 | struct drm_display_mode *adjusted_mode, | 2230 | struct drm_display_mode *adjusted_mode, |
@@ -1614,6 +2254,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1614 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; | 2254 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; |
1615 | bool ok, is_sdvo = false, is_dvo = false; | 2255 | bool ok, is_sdvo = false, is_dvo = false; |
1616 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; | 2256 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
2257 | bool is_edp = false; | ||
1617 | struct drm_mode_config *mode_config = &dev->mode_config; | 2258 | struct drm_mode_config *mode_config = &dev->mode_config; |
1618 | struct drm_connector *connector; | 2259 | struct drm_connector *connector; |
1619 | const intel_limit_t *limit; | 2260 | const intel_limit_t *limit; |
@@ -1629,6 +2270,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1629 | int lvds_reg = LVDS; | 2270 | int lvds_reg = LVDS; |
1630 | u32 temp; | 2271 | u32 temp; |
1631 | int sdvo_pixel_multiply; | 2272 | int sdvo_pixel_multiply; |
2273 | int target_clock; | ||
1632 | 2274 | ||
1633 | drm_vblank_pre_modeset(dev, pipe); | 2275 | drm_vblank_pre_modeset(dev, pipe); |
1634 | 2276 | ||
@@ -1660,6 +2302,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1660 | case INTEL_OUTPUT_DISPLAYPORT: | 2302 | case INTEL_OUTPUT_DISPLAYPORT: |
1661 | is_dp = true; | 2303 | is_dp = true; |
1662 | break; | 2304 | break; |
2305 | case INTEL_OUTPUT_EDP: | ||
2306 | is_edp = true; | ||
2307 | break; | ||
1663 | } | 2308 | } |
1664 | 2309 | ||
1665 | num_outputs++; | 2310 | num_outputs++; |
@@ -1711,11 +2356,29 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1711 | } | 2356 | } |
1712 | 2357 | ||
1713 | /* FDI link */ | 2358 | /* FDI link */ |
1714 | if (IS_IGDNG(dev)) | 2359 | if (IS_IGDNG(dev)) { |
1715 | igdng_compute_m_n(3, 4, /* lane num 4 */ | 2360 | int lane, link_bw; |
1716 | adjusted_mode->clock, | 2361 | /* eDP doesn't require FDI link, so just set DP M/N |
1717 | 270000, /* lane clock */ | 2362 | according to current link config */ |
1718 | &m_n); | 2363 | if (is_edp) { |
2364 | struct drm_connector *edp; | ||
2365 | target_clock = mode->clock; | ||
2366 | edp = intel_pipe_get_output(crtc); | ||
2367 | intel_edp_link_config(to_intel_output(edp), | ||
2368 | &lane, &link_bw); | ||
2369 | } else { | ||
2370 | /* DP over FDI requires target mode clock | ||
2371 | instead of link clock */ | ||
2372 | if (is_dp) | ||
2373 | target_clock = mode->clock; | ||
2374 | else | ||
2375 | target_clock = adjusted_mode->clock; | ||
2376 | lane = 4; | ||
2377 | link_bw = 270000; | ||
2378 | } | ||
2379 | igdng_compute_m_n(3, lane, target_clock, | ||
2380 | link_bw, &m_n); | ||
2381 | } | ||
1719 | 2382 | ||
1720 | if (IS_IGD(dev)) | 2383 | if (IS_IGD(dev)) |
1721 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; | 2384 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; |
@@ -1836,29 +2499,15 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1836 | dpll_reg = pch_dpll_reg; | 2499 | dpll_reg = pch_dpll_reg; |
1837 | } | 2500 | } |
1838 | 2501 | ||
1839 | if (dpll & DPLL_VCO_ENABLE) { | 2502 | if (is_edp) { |
2503 | igdng_disable_pll_edp(crtc); | ||
2504 | } else if ((dpll & DPLL_VCO_ENABLE)) { | ||
1840 | I915_WRITE(fp_reg, fp); | 2505 | I915_WRITE(fp_reg, fp); |
1841 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); | 2506 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); |
1842 | I915_READ(dpll_reg); | 2507 | I915_READ(dpll_reg); |
1843 | udelay(150); | 2508 | udelay(150); |
1844 | } | 2509 | } |
1845 | 2510 | ||
1846 | if (IS_IGDNG(dev)) { | ||
1847 | /* enable PCH clock reference source */ | ||
1848 | /* XXX need to change the setting for other outputs */ | ||
1849 | u32 temp; | ||
1850 | temp = I915_READ(PCH_DREF_CONTROL); | ||
1851 | temp &= ~DREF_NONSPREAD_SOURCE_MASK; | ||
1852 | temp |= DREF_NONSPREAD_CK505_ENABLE; | ||
1853 | temp &= ~DREF_SSC_SOURCE_MASK; | ||
1854 | temp |= DREF_SSC_SOURCE_ENABLE; | ||
1855 | temp &= ~DREF_SSC1_ENABLE; | ||
1856 | /* if no eDP, disable source output to CPU */ | ||
1857 | temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; | ||
1858 | temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; | ||
1859 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
1860 | } | ||
1861 | |||
1862 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. | 2511 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
1863 | * This is an exception to the general rule that mode_set doesn't turn | 2512 | * This is an exception to the general rule that mode_set doesn't turn |
1864 | * things on. | 2513 | * things on. |
@@ -1890,23 +2539,25 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1890 | if (is_dp) | 2539 | if (is_dp) |
1891 | intel_dp_set_m_n(crtc, mode, adjusted_mode); | 2540 | intel_dp_set_m_n(crtc, mode, adjusted_mode); |
1892 | 2541 | ||
1893 | I915_WRITE(fp_reg, fp); | 2542 | if (!is_edp) { |
1894 | I915_WRITE(dpll_reg, dpll); | 2543 | I915_WRITE(fp_reg, fp); |
1895 | I915_READ(dpll_reg); | ||
1896 | /* Wait for the clocks to stabilize. */ | ||
1897 | udelay(150); | ||
1898 | |||
1899 | if (IS_I965G(dev) && !IS_IGDNG(dev)) { | ||
1900 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | ||
1901 | I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | | ||
1902 | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); | ||
1903 | } else { | ||
1904 | /* write it again -- the BIOS does, after all */ | ||
1905 | I915_WRITE(dpll_reg, dpll); | 2544 | I915_WRITE(dpll_reg, dpll); |
2545 | I915_READ(dpll_reg); | ||
2546 | /* Wait for the clocks to stabilize. */ | ||
2547 | udelay(150); | ||
2548 | |||
2549 | if (IS_I965G(dev) && !IS_IGDNG(dev)) { | ||
2550 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | ||
2551 | I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | | ||
2552 | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); | ||
2553 | } else { | ||
2554 | /* write it again -- the BIOS does, after all */ | ||
2555 | I915_WRITE(dpll_reg, dpll); | ||
2556 | } | ||
2557 | I915_READ(dpll_reg); | ||
2558 | /* Wait for the clocks to stabilize. */ | ||
2559 | udelay(150); | ||
1906 | } | 2560 | } |
1907 | I915_READ(dpll_reg); | ||
1908 | /* Wait for the clocks to stabilize. */ | ||
1909 | udelay(150); | ||
1910 | 2561 | ||
1911 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | | 2562 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | |
1912 | ((adjusted_mode->crtc_htotal - 1) << 16)); | 2563 | ((adjusted_mode->crtc_htotal - 1) << 16)); |
@@ -1936,10 +2587,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1936 | I915_WRITE(link_m1_reg, m_n.link_m); | 2587 | I915_WRITE(link_m1_reg, m_n.link_m); |
1937 | I915_WRITE(link_n1_reg, m_n.link_n); | 2588 | I915_WRITE(link_n1_reg, m_n.link_n); |
1938 | 2589 | ||
1939 | /* enable FDI RX PLL too */ | 2590 | if (is_edp) { |
1940 | temp = I915_READ(fdi_rx_reg); | 2591 | igdng_set_pll_edp(crtc, adjusted_mode->clock); |
1941 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); | 2592 | } else { |
1942 | udelay(200); | 2593 | /* enable FDI RX PLL too */ |
2594 | temp = I915_READ(fdi_rx_reg); | ||
2595 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); | ||
2596 | udelay(200); | ||
2597 | } | ||
1943 | } | 2598 | } |
1944 | 2599 | ||
1945 | I915_WRITE(pipeconf_reg, pipeconf); | 2600 | I915_WRITE(pipeconf_reg, pipeconf); |
@@ -1951,6 +2606,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1951 | 2606 | ||
1952 | /* Flush the plane changes */ | 2607 | /* Flush the plane changes */ |
1953 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 2608 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
2609 | |||
2610 | intel_update_watermarks(dev); | ||
2611 | |||
1954 | drm_vblank_post_modeset(dev, pipe); | 2612 | drm_vblank_post_modeset(dev, pipe); |
1955 | 2613 | ||
1956 | return ret; | 2614 | return ret; |
@@ -2439,6 +3097,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
2439 | 3097 | ||
2440 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); | 3098 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); |
2441 | intel_crtc->pipe = pipe; | 3099 | intel_crtc->pipe = pipe; |
3100 | intel_crtc->plane = pipe; | ||
2442 | for (i = 0; i < 256; i++) { | 3101 | for (i = 0; i < 256; i++) { |
2443 | intel_crtc->lut_r[i] = i; | 3102 | intel_crtc->lut_r[i] = i; |
2444 | intel_crtc->lut_g[i] = i; | 3103 | intel_crtc->lut_g[i] = i; |
@@ -2533,12 +3192,17 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2533 | if (IS_IGDNG(dev)) { | 3192 | if (IS_IGDNG(dev)) { |
2534 | int found; | 3193 | int found; |
2535 | 3194 | ||
3195 | if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED)) | ||
3196 | intel_dp_init(dev, DP_A); | ||
3197 | |||
2536 | if (I915_READ(HDMIB) & PORT_DETECTED) { | 3198 | if (I915_READ(HDMIB) & PORT_DETECTED) { |
2537 | /* check SDVOB */ | 3199 | /* check SDVOB */ |
2538 | /* found = intel_sdvo_init(dev, HDMIB); */ | 3200 | /* found = intel_sdvo_init(dev, HDMIB); */ |
2539 | found = 0; | 3201 | found = 0; |
2540 | if (!found) | 3202 | if (!found) |
2541 | intel_hdmi_init(dev, HDMIB); | 3203 | intel_hdmi_init(dev, HDMIB); |
3204 | if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED)) | ||
3205 | intel_dp_init(dev, PCH_DP_B); | ||
2542 | } | 3206 | } |
2543 | 3207 | ||
2544 | if (I915_READ(HDMIC) & PORT_DETECTED) | 3208 | if (I915_READ(HDMIC) & PORT_DETECTED) |
@@ -2547,6 +3211,12 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2547 | if (I915_READ(HDMID) & PORT_DETECTED) | 3211 | if (I915_READ(HDMID) & PORT_DETECTED) |
2548 | intel_hdmi_init(dev, HDMID); | 3212 | intel_hdmi_init(dev, HDMID); |
2549 | 3213 | ||
3214 | if (I915_READ(PCH_DP_C) & DP_DETECTED) | ||
3215 | intel_dp_init(dev, PCH_DP_C); | ||
3216 | |||
3217 | if (I915_READ(PCH_DP_D) & DP_DETECTED) | ||
3218 | intel_dp_init(dev, PCH_DP_D); | ||
3219 | |||
2550 | } else if (IS_I9XX(dev)) { | 3220 | } else if (IS_I9XX(dev)) { |
2551 | int found; | 3221 | int found; |
2552 | u32 reg; | 3222 | u32 reg; |
@@ -2621,6 +3291,10 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2621 | (1 << 1)); | 3291 | (1 << 1)); |
2622 | clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); | 3292 | clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); |
2623 | break; | 3293 | break; |
3294 | case INTEL_OUTPUT_EDP: | ||
3295 | crtc_mask = (1 << 1); | ||
3296 | clone_mask = (1 << INTEL_OUTPUT_EDP); | ||
3297 | break; | ||
2624 | } | 3298 | } |
2625 | encoder->possible_crtcs = crtc_mask; | 3299 | encoder->possible_crtcs = crtc_mask; |
2626 | encoder->possible_clones = intel_connector_clones(dev, clone_mask); | 3300 | encoder->possible_clones = intel_connector_clones(dev, clone_mask); |
@@ -2730,6 +3404,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
2730 | if (IS_I965G(dev)) { | 3404 | if (IS_I965G(dev)) { |
2731 | dev->mode_config.max_width = 8192; | 3405 | dev->mode_config.max_width = 8192; |
2732 | dev->mode_config.max_height = 8192; | 3406 | dev->mode_config.max_height = 8192; |
3407 | } else if (IS_I9XX(dev)) { | ||
3408 | dev->mode_config.max_width = 4096; | ||
3409 | dev->mode_config.max_height = 4096; | ||
2733 | } else { | 3410 | } else { |
2734 | dev->mode_config.max_width = 2048; | 3411 | dev->mode_config.max_width = 2048; |
2735 | dev->mode_config.max_height = 2048; | 3412 | dev->mode_config.max_height = 2048; |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 8f8d37d5663a..a6ff15ac548a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -40,6 +40,8 @@ | |||
40 | 40 | ||
41 | #define DP_LINK_CONFIGURATION_SIZE 9 | 41 | #define DP_LINK_CONFIGURATION_SIZE 9 |
42 | 42 | ||
43 | #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP) | ||
44 | |||
43 | struct intel_dp_priv { | 45 | struct intel_dp_priv { |
44 | uint32_t output_reg; | 46 | uint32_t output_reg; |
45 | uint32_t DP; | 47 | uint32_t DP; |
@@ -63,6 +65,19 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | |||
63 | static void | 65 | static void |
64 | intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); | 66 | intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); |
65 | 67 | ||
68 | void | ||
69 | intel_edp_link_config (struct intel_output *intel_output, | ||
70 | int *lane_num, int *link_bw) | ||
71 | { | ||
72 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
73 | |||
74 | *lane_num = dp_priv->lane_count; | ||
75 | if (dp_priv->link_bw == DP_LINK_BW_1_62) | ||
76 | *link_bw = 162000; | ||
77 | else if (dp_priv->link_bw == DP_LINK_BW_2_7) | ||
78 | *link_bw = 270000; | ||
79 | } | ||
80 | |||
66 | static int | 81 | static int |
67 | intel_dp_max_lane_count(struct intel_output *intel_output) | 82 | intel_dp_max_lane_count(struct intel_output *intel_output) |
68 | { | 83 | { |
@@ -206,7 +221,13 @@ intel_dp_aux_ch(struct intel_output *intel_output, | |||
206 | * and would like to run at 2MHz. So, take the | 221 | * and would like to run at 2MHz. So, take the |
207 | * hrawclk value and divide by 2 and use that | 222 | * hrawclk value and divide by 2 and use that |
208 | */ | 223 | */ |
209 | aux_clock_divider = intel_hrawclk(dev) / 2; | 224 | if (IS_eDP(intel_output)) |
225 | aux_clock_divider = 225; /* eDP input clock at 450Mhz */ | ||
226 | else if (IS_IGDNG(dev)) | ||
227 | aux_clock_divider = 62; /* IGDNG: input clock fixed at 125Mhz */ | ||
228 | else | ||
229 | aux_clock_divider = intel_hrawclk(dev) / 2; | ||
230 | |||
210 | /* Must try at least 3 times according to DP spec */ | 231 | /* Must try at least 3 times according to DP spec */ |
211 | for (try = 0; try < 5; try++) { | 232 | for (try = 0; try < 5; try++) { |
212 | /* Load the send data into the aux channel data registers */ | 233 | /* Load the send data into the aux channel data registers */ |
@@ -236,7 +257,7 @@ intel_dp_aux_ch(struct intel_output *intel_output, | |||
236 | } | 257 | } |
237 | 258 | ||
238 | /* Clear done status and any errors */ | 259 | /* Clear done status and any errors */ |
239 | I915_WRITE(ch_ctl, (ctl | | 260 | I915_WRITE(ch_ctl, (status | |
240 | DP_AUX_CH_CTL_DONE | | 261 | DP_AUX_CH_CTL_DONE | |
241 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | 262 | DP_AUX_CH_CTL_TIME_OUT_ERROR | |
242 | DP_AUX_CH_CTL_RECEIVE_ERROR)); | 263 | DP_AUX_CH_CTL_RECEIVE_ERROR)); |
@@ -246,7 +267,7 @@ intel_dp_aux_ch(struct intel_output *intel_output, | |||
246 | } | 267 | } |
247 | 268 | ||
248 | if ((status & DP_AUX_CH_CTL_DONE) == 0) { | 269 | if ((status & DP_AUX_CH_CTL_DONE) == 0) { |
249 | printk(KERN_ERR "dp_aux_ch not done status 0x%08x\n", status); | 270 | DRM_ERROR("dp_aux_ch not done status 0x%08x\n", status); |
250 | return -EBUSY; | 271 | return -EBUSY; |
251 | } | 272 | } |
252 | 273 | ||
@@ -254,11 +275,14 @@ intel_dp_aux_ch(struct intel_output *intel_output, | |||
254 | * Timeouts occur when the sink is not connected | 275 | * Timeouts occur when the sink is not connected |
255 | */ | 276 | */ |
256 | if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { | 277 | if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { |
257 | printk(KERN_ERR "dp_aux_ch receive error status 0x%08x\n", status); | 278 | DRM_ERROR("dp_aux_ch receive error status 0x%08x\n", status); |
258 | return -EIO; | 279 | return -EIO; |
259 | } | 280 | } |
281 | |||
282 | /* Timeouts occur when the device isn't connected, so they're | ||
283 | * "normal" -- don't fill the kernel log with these */ | ||
260 | if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { | 284 | if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { |
261 | printk(KERN_ERR "dp_aux_ch timeout status 0x%08x\n", status); | 285 | DRM_DEBUG("dp_aux_ch timeout status 0x%08x\n", status); |
262 | return -ETIMEDOUT; | 286 | return -ETIMEDOUT; |
263 | } | 287 | } |
264 | 288 | ||
@@ -292,7 +316,7 @@ intel_dp_aux_native_write(struct intel_output *intel_output, | |||
292 | return -1; | 316 | return -1; |
293 | msg[0] = AUX_NATIVE_WRITE << 4; | 317 | msg[0] = AUX_NATIVE_WRITE << 4; |
294 | msg[1] = address >> 8; | 318 | msg[1] = address >> 8; |
295 | msg[2] = address; | 319 | msg[2] = address & 0xff; |
296 | msg[3] = send_bytes - 1; | 320 | msg[3] = send_bytes - 1; |
297 | memcpy(&msg[4], send, send_bytes); | 321 | memcpy(&msg[4], send, send_bytes); |
298 | msg_bytes = send_bytes + 4; | 322 | msg_bytes = send_bytes + 4; |
@@ -384,8 +408,8 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name) | |||
384 | memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter)); | 408 | memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter)); |
385 | dp_priv->adapter.owner = THIS_MODULE; | 409 | dp_priv->adapter.owner = THIS_MODULE; |
386 | dp_priv->adapter.class = I2C_CLASS_DDC; | 410 | dp_priv->adapter.class = I2C_CLASS_DDC; |
387 | strncpy (dp_priv->adapter.name, name, sizeof dp_priv->adapter.name - 1); | 411 | strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1); |
388 | dp_priv->adapter.name[sizeof dp_priv->adapter.name - 1] = '\0'; | 412 | dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0'; |
389 | dp_priv->adapter.algo_data = &dp_priv->algo; | 413 | dp_priv->adapter.algo_data = &dp_priv->algo; |
390 | dp_priv->adapter.dev.parent = &intel_output->base.kdev; | 414 | dp_priv->adapter.dev.parent = &intel_output->base.kdev; |
391 | 415 | ||
@@ -411,7 +435,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
411 | dp_priv->link_bw = bws[clock]; | 435 | dp_priv->link_bw = bws[clock]; |
412 | dp_priv->lane_count = lane_count; | 436 | dp_priv->lane_count = lane_count; |
413 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | 437 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); |
414 | printk(KERN_ERR "link bw %02x lane count %d clock %d\n", | 438 | DRM_DEBUG("Display port link bw %02x lane count %d clock %d\n", |
415 | dp_priv->link_bw, dp_priv->lane_count, | 439 | dp_priv->link_bw, dp_priv->lane_count, |
416 | adjusted_mode->clock); | 440 | adjusted_mode->clock); |
417 | return true; | 441 | return true; |
@@ -490,22 +514,40 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
490 | intel_dp_compute_m_n(3, lane_count, | 514 | intel_dp_compute_m_n(3, lane_count, |
491 | mode->clock, adjusted_mode->clock, &m_n); | 515 | mode->clock, adjusted_mode->clock, &m_n); |
492 | 516 | ||
493 | if (intel_crtc->pipe == 0) { | 517 | if (IS_IGDNG(dev)) { |
494 | I915_WRITE(PIPEA_GMCH_DATA_M, | 518 | if (intel_crtc->pipe == 0) { |
495 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | | 519 | I915_WRITE(TRANSA_DATA_M1, |
496 | m_n.gmch_m); | 520 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | |
497 | I915_WRITE(PIPEA_GMCH_DATA_N, | 521 | m_n.gmch_m); |
498 | m_n.gmch_n); | 522 | I915_WRITE(TRANSA_DATA_N1, m_n.gmch_n); |
499 | I915_WRITE(PIPEA_DP_LINK_M, m_n.link_m); | 523 | I915_WRITE(TRANSA_DP_LINK_M1, m_n.link_m); |
500 | I915_WRITE(PIPEA_DP_LINK_N, m_n.link_n); | 524 | I915_WRITE(TRANSA_DP_LINK_N1, m_n.link_n); |
525 | } else { | ||
526 | I915_WRITE(TRANSB_DATA_M1, | ||
527 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | | ||
528 | m_n.gmch_m); | ||
529 | I915_WRITE(TRANSB_DATA_N1, m_n.gmch_n); | ||
530 | I915_WRITE(TRANSB_DP_LINK_M1, m_n.link_m); | ||
531 | I915_WRITE(TRANSB_DP_LINK_N1, m_n.link_n); | ||
532 | } | ||
501 | } else { | 533 | } else { |
502 | I915_WRITE(PIPEB_GMCH_DATA_M, | 534 | if (intel_crtc->pipe == 0) { |
503 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | | 535 | I915_WRITE(PIPEA_GMCH_DATA_M, |
504 | m_n.gmch_m); | 536 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | |
505 | I915_WRITE(PIPEB_GMCH_DATA_N, | 537 | m_n.gmch_m); |
506 | m_n.gmch_n); | 538 | I915_WRITE(PIPEA_GMCH_DATA_N, |
507 | I915_WRITE(PIPEB_DP_LINK_M, m_n.link_m); | 539 | m_n.gmch_n); |
508 | I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n); | 540 | I915_WRITE(PIPEA_DP_LINK_M, m_n.link_m); |
541 | I915_WRITE(PIPEA_DP_LINK_N, m_n.link_n); | ||
542 | } else { | ||
543 | I915_WRITE(PIPEB_GMCH_DATA_M, | ||
544 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | | ||
545 | m_n.gmch_m); | ||
546 | I915_WRITE(PIPEB_GMCH_DATA_N, | ||
547 | m_n.gmch_n); | ||
548 | I915_WRITE(PIPEB_DP_LINK_M, m_n.link_m); | ||
549 | I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n); | ||
550 | } | ||
509 | } | 551 | } |
510 | } | 552 | } |
511 | 553 | ||
@@ -553,8 +595,38 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
553 | 595 | ||
554 | if (intel_crtc->pipe == 1) | 596 | if (intel_crtc->pipe == 1) |
555 | dp_priv->DP |= DP_PIPEB_SELECT; | 597 | dp_priv->DP |= DP_PIPEB_SELECT; |
598 | |||
599 | if (IS_eDP(intel_output)) { | ||
600 | /* don't miss out required setting for eDP */ | ||
601 | dp_priv->DP |= DP_PLL_ENABLE; | ||
602 | if (adjusted_mode->clock < 200000) | ||
603 | dp_priv->DP |= DP_PLL_FREQ_160MHZ; | ||
604 | else | ||
605 | dp_priv->DP |= DP_PLL_FREQ_270MHZ; | ||
606 | } | ||
556 | } | 607 | } |
557 | 608 | ||
609 | static void igdng_edp_backlight_on (struct drm_device *dev) | ||
610 | { | ||
611 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
612 | u32 pp; | ||
613 | |||
614 | DRM_DEBUG("\n"); | ||
615 | pp = I915_READ(PCH_PP_CONTROL); | ||
616 | pp |= EDP_BLC_ENABLE; | ||
617 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
618 | } | ||
619 | |||
620 | static void igdng_edp_backlight_off (struct drm_device *dev) | ||
621 | { | ||
622 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
623 | u32 pp; | ||
624 | |||
625 | DRM_DEBUG("\n"); | ||
626 | pp = I915_READ(PCH_PP_CONTROL); | ||
627 | pp &= ~EDP_BLC_ENABLE; | ||
628 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
629 | } | ||
558 | 630 | ||
559 | static void | 631 | static void |
560 | intel_dp_dpms(struct drm_encoder *encoder, int mode) | 632 | intel_dp_dpms(struct drm_encoder *encoder, int mode) |
@@ -566,11 +638,17 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
566 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); | 638 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); |
567 | 639 | ||
568 | if (mode != DRM_MODE_DPMS_ON) { | 640 | if (mode != DRM_MODE_DPMS_ON) { |
569 | if (dp_reg & DP_PORT_EN) | 641 | if (dp_reg & DP_PORT_EN) { |
570 | intel_dp_link_down(intel_output, dp_priv->DP); | 642 | intel_dp_link_down(intel_output, dp_priv->DP); |
643 | if (IS_eDP(intel_output)) | ||
644 | igdng_edp_backlight_off(dev); | ||
645 | } | ||
571 | } else { | 646 | } else { |
572 | if (!(dp_reg & DP_PORT_EN)) | 647 | if (!(dp_reg & DP_PORT_EN)) { |
573 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); | 648 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); |
649 | if (IS_eDP(intel_output)) | ||
650 | igdng_edp_backlight_on(dev); | ||
651 | } | ||
574 | } | 652 | } |
575 | dp_priv->dpms_mode = mode; | 653 | dp_priv->dpms_mode = mode; |
576 | } | 654 | } |
@@ -932,6 +1010,23 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) | |||
932 | struct drm_i915_private *dev_priv = dev->dev_private; | 1010 | struct drm_i915_private *dev_priv = dev->dev_private; |
933 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 1011 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; |
934 | 1012 | ||
1013 | DRM_DEBUG("\n"); | ||
1014 | |||
1015 | if (IS_eDP(intel_output)) { | ||
1016 | DP &= ~DP_PLL_ENABLE; | ||
1017 | I915_WRITE(dp_priv->output_reg, DP); | ||
1018 | POSTING_READ(dp_priv->output_reg); | ||
1019 | udelay(100); | ||
1020 | } | ||
1021 | |||
1022 | DP &= ~DP_LINK_TRAIN_MASK; | ||
1023 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); | ||
1024 | POSTING_READ(dp_priv->output_reg); | ||
1025 | |||
1026 | udelay(17000); | ||
1027 | |||
1028 | if (IS_eDP(intel_output)) | ||
1029 | DP |= DP_LINK_TRAIN_OFF; | ||
935 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); | 1030 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); |
936 | POSTING_READ(dp_priv->output_reg); | 1031 | POSTING_READ(dp_priv->output_reg); |
937 | } | 1032 | } |
@@ -975,6 +1070,24 @@ intel_dp_check_link_status(struct intel_output *intel_output) | |||
975 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); | 1070 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); |
976 | } | 1071 | } |
977 | 1072 | ||
1073 | static enum drm_connector_status | ||
1074 | igdng_dp_detect(struct drm_connector *connector) | ||
1075 | { | ||
1076 | struct intel_output *intel_output = to_intel_output(connector); | ||
1077 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
1078 | enum drm_connector_status status; | ||
1079 | |||
1080 | status = connector_status_disconnected; | ||
1081 | if (intel_dp_aux_native_read(intel_output, | ||
1082 | 0x000, dp_priv->dpcd, | ||
1083 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | ||
1084 | { | ||
1085 | if (dp_priv->dpcd[0] != 0) | ||
1086 | status = connector_status_connected; | ||
1087 | } | ||
1088 | return status; | ||
1089 | } | ||
1090 | |||
978 | /** | 1091 | /** |
979 | * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. | 1092 | * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. |
980 | * | 1093 | * |
@@ -993,6 +1106,9 @@ intel_dp_detect(struct drm_connector *connector) | |||
993 | 1106 | ||
994 | dp_priv->has_audio = false; | 1107 | dp_priv->has_audio = false; |
995 | 1108 | ||
1109 | if (IS_IGDNG(dev)) | ||
1110 | return igdng_dp_detect(connector); | ||
1111 | |||
996 | temp = I915_READ(PORT_HOTPLUG_EN); | 1112 | temp = I915_READ(PORT_HOTPLUG_EN); |
997 | 1113 | ||
998 | I915_WRITE(PORT_HOTPLUG_EN, | 1114 | I915_WRITE(PORT_HOTPLUG_EN, |
@@ -1036,11 +1152,27 @@ intel_dp_detect(struct drm_connector *connector) | |||
1036 | static int intel_dp_get_modes(struct drm_connector *connector) | 1152 | static int intel_dp_get_modes(struct drm_connector *connector) |
1037 | { | 1153 | { |
1038 | struct intel_output *intel_output = to_intel_output(connector); | 1154 | struct intel_output *intel_output = to_intel_output(connector); |
1155 | struct drm_device *dev = intel_output->base.dev; | ||
1156 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1157 | int ret; | ||
1039 | 1158 | ||
1040 | /* We should parse the EDID data and find out if it has an audio sink | 1159 | /* We should parse the EDID data and find out if it has an audio sink |
1041 | */ | 1160 | */ |
1042 | 1161 | ||
1043 | return intel_ddc_get_modes(intel_output); | 1162 | ret = intel_ddc_get_modes(intel_output); |
1163 | if (ret) | ||
1164 | return ret; | ||
1165 | |||
1166 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ | ||
1167 | if (IS_eDP(intel_output)) { | ||
1168 | if (dev_priv->panel_fixed_mode != NULL) { | ||
1169 | struct drm_display_mode *mode; | ||
1170 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); | ||
1171 | drm_mode_probed_add(connector, mode); | ||
1172 | return 1; | ||
1173 | } | ||
1174 | } | ||
1175 | return 0; | ||
1044 | } | 1176 | } |
1045 | 1177 | ||
1046 | static void | 1178 | static void |
@@ -1103,6 +1235,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1103 | struct drm_connector *connector; | 1235 | struct drm_connector *connector; |
1104 | struct intel_output *intel_output; | 1236 | struct intel_output *intel_output; |
1105 | struct intel_dp_priv *dp_priv; | 1237 | struct intel_dp_priv *dp_priv; |
1238 | const char *name = NULL; | ||
1106 | 1239 | ||
1107 | intel_output = kcalloc(sizeof(struct intel_output) + | 1240 | intel_output = kcalloc(sizeof(struct intel_output) + |
1108 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); | 1241 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); |
@@ -1116,7 +1249,10 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1116 | DRM_MODE_CONNECTOR_DisplayPort); | 1249 | DRM_MODE_CONNECTOR_DisplayPort); |
1117 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); | 1250 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); |
1118 | 1251 | ||
1119 | intel_output->type = INTEL_OUTPUT_DISPLAYPORT; | 1252 | if (output_reg == DP_A) |
1253 | intel_output->type = INTEL_OUTPUT_EDP; | ||
1254 | else | ||
1255 | intel_output->type = INTEL_OUTPUT_DISPLAYPORT; | ||
1120 | 1256 | ||
1121 | connector->interlace_allowed = true; | 1257 | connector->interlace_allowed = true; |
1122 | connector->doublescan_allowed = 0; | 1258 | connector->doublescan_allowed = 0; |
@@ -1136,12 +1272,41 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1136 | drm_sysfs_connector_add(connector); | 1272 | drm_sysfs_connector_add(connector); |
1137 | 1273 | ||
1138 | /* Set up the DDC bus. */ | 1274 | /* Set up the DDC bus. */ |
1139 | intel_dp_i2c_init(intel_output, | 1275 | switch (output_reg) { |
1140 | (output_reg == DP_B) ? "DPDDC-B" : | 1276 | case DP_A: |
1141 | (output_reg == DP_C) ? "DPDDC-C" : "DPDDC-D"); | 1277 | name = "DPDDC-A"; |
1278 | break; | ||
1279 | case DP_B: | ||
1280 | case PCH_DP_B: | ||
1281 | name = "DPDDC-B"; | ||
1282 | break; | ||
1283 | case DP_C: | ||
1284 | case PCH_DP_C: | ||
1285 | name = "DPDDC-C"; | ||
1286 | break; | ||
1287 | case DP_D: | ||
1288 | case PCH_DP_D: | ||
1289 | name = "DPDDC-D"; | ||
1290 | break; | ||
1291 | } | ||
1292 | |||
1293 | intel_dp_i2c_init(intel_output, name); | ||
1294 | |||
1142 | intel_output->ddc_bus = &dp_priv->adapter; | 1295 | intel_output->ddc_bus = &dp_priv->adapter; |
1143 | intel_output->hot_plug = intel_dp_hot_plug; | 1296 | intel_output->hot_plug = intel_dp_hot_plug; |
1144 | 1297 | ||
1298 | if (output_reg == DP_A) { | ||
1299 | /* initialize panel mode from VBT if available for eDP */ | ||
1300 | if (dev_priv->lfp_lvds_vbt_mode) { | ||
1301 | dev_priv->panel_fixed_mode = | ||
1302 | drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); | ||
1303 | if (dev_priv->panel_fixed_mode) { | ||
1304 | dev_priv->panel_fixed_mode->type |= | ||
1305 | DRM_MODE_TYPE_PREFERRED; | ||
1306 | } | ||
1307 | } | ||
1308 | } | ||
1309 | |||
1145 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written | 1310 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written |
1146 | * 0xd. Failure to do so will result in spurious interrupts being | 1311 | * 0xd. Failure to do so will result in spurious interrupts being |
1147 | * generated on the port when a cable is not attached. | 1312 | * generated on the port when a cable is not attached. |
diff --git a/drivers/gpu/drm/i915/intel_dp_i2c.c b/drivers/gpu/drm/i915/intel_dp_i2c.c index 4e60f14b1a6d..a63b6f57d2d4 100644 --- a/drivers/gpu/drm/i915/intel_dp_i2c.c +++ b/drivers/gpu/drm/i915/intel_dp_i2c.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
31 | #include "intel_dp.h" | 31 | #include "intel_dp.h" |
32 | #include "drmP.h" | ||
32 | 33 | ||
33 | /* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ | 34 | /* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ |
34 | 35 | ||
@@ -84,7 +85,7 @@ i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, | |||
84 | msg, msg_bytes, | 85 | msg, msg_bytes, |
85 | reply, reply_bytes); | 86 | reply, reply_bytes); |
86 | if (ret < 0) { | 87 | if (ret < 0) { |
87 | printk(KERN_ERR "aux_ch failed %d\n", ret); | 88 | DRM_DEBUG("aux_ch failed %d\n", ret); |
88 | return ret; | 89 | return ret; |
89 | } | 90 | } |
90 | switch (reply[0] & AUX_I2C_REPLY_MASK) { | 91 | switch (reply[0] & AUX_I2C_REPLY_MASK) { |
@@ -94,14 +95,14 @@ i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, | |||
94 | } | 95 | } |
95 | return reply_bytes - 1; | 96 | return reply_bytes - 1; |
96 | case AUX_I2C_REPLY_NACK: | 97 | case AUX_I2C_REPLY_NACK: |
97 | printk(KERN_ERR "aux_ch nack\n"); | 98 | DRM_DEBUG("aux_ch nack\n"); |
98 | return -EREMOTEIO; | 99 | return -EREMOTEIO; |
99 | case AUX_I2C_REPLY_DEFER: | 100 | case AUX_I2C_REPLY_DEFER: |
100 | printk(KERN_ERR "aux_ch defer\n"); | 101 | DRM_DEBUG("aux_ch defer\n"); |
101 | udelay(100); | 102 | udelay(100); |
102 | break; | 103 | break; |
103 | default: | 104 | default: |
104 | printk(KERN_ERR "aux_ch invalid reply 0x%02x\n", reply[0]); | 105 | DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]); |
105 | return -EREMOTEIO; | 106 | return -EREMOTEIO; |
106 | } | 107 | } |
107 | } | 108 | } |
@@ -223,7 +224,7 @@ i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter, | |||
223 | if (ret >= 0) | 224 | if (ret >= 0) |
224 | ret = num; | 225 | ret = num; |
225 | i2c_algo_dp_aux_stop(adapter, reading); | 226 | i2c_algo_dp_aux_stop(adapter, reading); |
226 | printk(KERN_ERR "dp_aux_xfer return %d\n", ret); | 227 | DRM_DEBUG("dp_aux_xfer return %d\n", ret); |
227 | return ret; | 228 | return ret; |
228 | } | 229 | } |
229 | 230 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 004541c935a8..d6f92ea1b553 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -55,6 +55,7 @@ | |||
55 | #define INTEL_OUTPUT_TVOUT 5 | 55 | #define INTEL_OUTPUT_TVOUT 5 |
56 | #define INTEL_OUTPUT_HDMI 6 | 56 | #define INTEL_OUTPUT_HDMI 6 |
57 | #define INTEL_OUTPUT_DISPLAYPORT 7 | 57 | #define INTEL_OUTPUT_DISPLAYPORT 7 |
58 | #define INTEL_OUTPUT_EDP 8 | ||
58 | 59 | ||
59 | #define INTEL_DVO_CHIP_NONE 0 | 60 | #define INTEL_DVO_CHIP_NONE 0 |
60 | #define INTEL_DVO_CHIP_LVDS 1 | 61 | #define INTEL_DVO_CHIP_LVDS 1 |
@@ -121,6 +122,8 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg); | |||
121 | void | 122 | void |
122 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | 123 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, |
123 | struct drm_display_mode *adjusted_mode); | 124 | struct drm_display_mode *adjusted_mode); |
125 | extern void intel_edp_link_config (struct intel_output *, int *, int *); | ||
126 | |||
124 | 127 | ||
125 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); | 128 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
126 | extern void intel_encoder_prepare (struct drm_encoder *encoder); | 129 | extern void intel_encoder_prepare (struct drm_encoder *encoder); |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 1af7d68e3807..1d30802e773e 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -453,7 +453,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
453 | size = ALIGN(size, PAGE_SIZE); | 453 | size = ALIGN(size, PAGE_SIZE); |
454 | fbo = drm_gem_object_alloc(dev, size); | 454 | fbo = drm_gem_object_alloc(dev, size); |
455 | if (!fbo) { | 455 | if (!fbo) { |
456 | printk(KERN_ERR "failed to allocate framebuffer\n"); | 456 | DRM_ERROR("failed to allocate framebuffer\n"); |
457 | ret = -ENOMEM; | 457 | ret = -ENOMEM; |
458 | goto out; | 458 | goto out; |
459 | } | 459 | } |
@@ -610,8 +610,8 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
610 | par->dev = dev; | 610 | par->dev = dev; |
611 | 611 | ||
612 | /* To allow resizeing without swapping buffers */ | 612 | /* To allow resizeing without swapping buffers */ |
613 | printk("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width, | 613 | DRM_DEBUG("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width, |
614 | intel_fb->base.height, obj_priv->gtt_offset, fbo); | 614 | intel_fb->base.height, obj_priv->gtt_offset, fbo); |
615 | 615 | ||
616 | mutex_unlock(&dev->struct_mutex); | 616 | mutex_unlock(&dev->struct_mutex); |
617 | return 0; | 617 | return 0; |
@@ -698,13 +698,13 @@ static int intelfb_multi_fb_probe_crtc(struct drm_device *dev, struct drm_crtc * | |||
698 | } else | 698 | } else |
699 | intelfb_set_par(info); | 699 | intelfb_set_par(info); |
700 | 700 | ||
701 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, | 701 | DRM_INFO("fb%d: %s frame buffer device\n", info->node, |
702 | info->fix.id); | 702 | info->fix.id); |
703 | 703 | ||
704 | /* Switch back to kernel console on panic */ | 704 | /* Switch back to kernel console on panic */ |
705 | kernelfb_mode = *modeset; | 705 | kernelfb_mode = *modeset; |
706 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); | 706 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); |
707 | printk(KERN_INFO "registered panic notifier\n"); | 707 | DRM_DEBUG("registered panic notifier\n"); |
708 | 708 | ||
709 | return 0; | 709 | return 0; |
710 | } | 710 | } |
@@ -852,13 +852,13 @@ static int intelfb_single_fb_probe(struct drm_device *dev) | |||
852 | } else | 852 | } else |
853 | intelfb_set_par(info); | 853 | intelfb_set_par(info); |
854 | 854 | ||
855 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, | 855 | DRM_INFO("fb%d: %s frame buffer device\n", info->node, |
856 | info->fix.id); | 856 | info->fix.id); |
857 | 857 | ||
858 | /* Switch back to kernel console on panic */ | 858 | /* Switch back to kernel console on panic */ |
859 | kernelfb_mode = *modeset; | 859 | kernelfb_mode = *modeset; |
860 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); | 860 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); |
861 | printk(KERN_INFO "registered panic notifier\n"); | 861 | DRM_DEBUG("registered panic notifier\n"); |
862 | 862 | ||
863 | return 0; | 863 | return 0; |
864 | } | 864 | } |
@@ -872,8 +872,8 @@ void intelfb_restore(void) | |||
872 | { | 872 | { |
873 | int ret; | 873 | int ret; |
874 | if ((ret = drm_crtc_helper_set_config(&kernelfb_mode)) != 0) { | 874 | if ((ret = drm_crtc_helper_set_config(&kernelfb_mode)) != 0) { |
875 | printk(KERN_ERR "Failed to restore crtc configuration: %d\n", | 875 | DRM_ERROR("Failed to restore crtc configuration: %d\n", |
876 | ret); | 876 | ret); |
877 | } | 877 | } |
878 | } | 878 | } |
879 | 879 | ||
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 9e30daae37dc..1842290cded3 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -130,16 +130,17 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
130 | } | 130 | } |
131 | 131 | ||
132 | static enum drm_connector_status | 132 | static enum drm_connector_status |
133 | intel_hdmi_edid_detect(struct drm_connector *connector) | 133 | intel_hdmi_detect(struct drm_connector *connector) |
134 | { | 134 | { |
135 | struct intel_output *intel_output = to_intel_output(connector); | 135 | struct intel_output *intel_output = to_intel_output(connector); |
136 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | 136 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; |
137 | struct edid *edid = NULL; | 137 | struct edid *edid = NULL; |
138 | enum drm_connector_status status = connector_status_disconnected; | 138 | enum drm_connector_status status = connector_status_disconnected; |
139 | 139 | ||
140 | hdmi_priv->has_hdmi_sink = false; | ||
140 | edid = drm_get_edid(&intel_output->base, | 141 | edid = drm_get_edid(&intel_output->base, |
141 | intel_output->ddc_bus); | 142 | intel_output->ddc_bus); |
142 | hdmi_priv->has_hdmi_sink = false; | 143 | |
143 | if (edid) { | 144 | if (edid) { |
144 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { | 145 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
145 | status = connector_status_connected; | 146 | status = connector_status_connected; |
@@ -148,65 +149,8 @@ intel_hdmi_edid_detect(struct drm_connector *connector) | |||
148 | intel_output->base.display_info.raw_edid = NULL; | 149 | intel_output->base.display_info.raw_edid = NULL; |
149 | kfree(edid); | 150 | kfree(edid); |
150 | } | 151 | } |
151 | return status; | ||
152 | } | ||
153 | |||
154 | static enum drm_connector_status | ||
155 | igdng_hdmi_detect(struct drm_connector *connector) | ||
156 | { | ||
157 | struct intel_output *intel_output = to_intel_output(connector); | ||
158 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | ||
159 | |||
160 | /* FIXME hotplug detect */ | ||
161 | |||
162 | hdmi_priv->has_hdmi_sink = false; | ||
163 | return intel_hdmi_edid_detect(connector); | ||
164 | } | ||
165 | 152 | ||
166 | static enum drm_connector_status | 153 | return status; |
167 | intel_hdmi_detect(struct drm_connector *connector) | ||
168 | { | ||
169 | struct drm_device *dev = connector->dev; | ||
170 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
171 | struct intel_output *intel_output = to_intel_output(connector); | ||
172 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | ||
173 | u32 temp, bit; | ||
174 | |||
175 | if (IS_IGDNG(dev)) | ||
176 | return igdng_hdmi_detect(connector); | ||
177 | |||
178 | temp = I915_READ(PORT_HOTPLUG_EN); | ||
179 | |||
180 | switch (hdmi_priv->sdvox_reg) { | ||
181 | case SDVOB: | ||
182 | temp |= HDMIB_HOTPLUG_INT_EN; | ||
183 | break; | ||
184 | case SDVOC: | ||
185 | temp |= HDMIC_HOTPLUG_INT_EN; | ||
186 | break; | ||
187 | default: | ||
188 | return connector_status_unknown; | ||
189 | } | ||
190 | |||
191 | I915_WRITE(PORT_HOTPLUG_EN, temp); | ||
192 | |||
193 | POSTING_READ(PORT_HOTPLUG_EN); | ||
194 | |||
195 | switch (hdmi_priv->sdvox_reg) { | ||
196 | case SDVOB: | ||
197 | bit = HDMIB_HOTPLUG_INT_STATUS; | ||
198 | break; | ||
199 | case SDVOC: | ||
200 | bit = HDMIC_HOTPLUG_INT_STATUS; | ||
201 | break; | ||
202 | default: | ||
203 | return connector_status_unknown; | ||
204 | } | ||
205 | |||
206 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) | ||
207 | return intel_hdmi_edid_detect(connector); | ||
208 | else | ||
209 | return connector_status_disconnected; | ||
210 | } | 154 | } |
211 | 155 | ||
212 | static int intel_hdmi_get_modes(struct drm_connector *connector) | 156 | static int intel_hdmi_get_modes(struct drm_connector *connector) |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 9564ca44a977..3f445a80c552 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "intel_drv.h" | 36 | #include "intel_drv.h" |
37 | #include "i915_drm.h" | 37 | #include "i915_drm.h" |
38 | #include "i915_drv.h" | 38 | #include "i915_drv.h" |
39 | #include <linux/acpi.h> | ||
39 | 40 | ||
40 | #define I915_LVDS "i915_lvds" | 41 | #define I915_LVDS "i915_lvds" |
41 | 42 | ||
@@ -252,14 +253,14 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
252 | 253 | ||
253 | /* Should never happen!! */ | 254 | /* Should never happen!! */ |
254 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { | 255 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { |
255 | printk(KERN_ERR "Can't support LVDS on pipe A\n"); | 256 | DRM_ERROR("Can't support LVDS on pipe A\n"); |
256 | return false; | 257 | return false; |
257 | } | 258 | } |
258 | 259 | ||
259 | /* Should never happen!! */ | 260 | /* Should never happen!! */ |
260 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { | 261 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { |
261 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { | 262 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { |
262 | printk(KERN_ERR "Can't enable LVDS and another " | 263 | DRM_ERROR("Can't enable LVDS and another " |
263 | "encoder on the same pipe\n"); | 264 | "encoder on the same pipe\n"); |
264 | return false; | 265 | return false; |
265 | } | 266 | } |
@@ -779,6 +780,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
779 | }, | 780 | }, |
780 | { | 781 | { |
781 | .callback = intel_no_lvds_dmi_callback, | 782 | .callback = intel_no_lvds_dmi_callback, |
783 | .ident = "AOpen Mini PC MP915", | ||
784 | .matches = { | ||
785 | DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), | ||
786 | DMI_MATCH(DMI_BOARD_NAME, "i915GMx-F"), | ||
787 | }, | ||
788 | }, | ||
789 | { | ||
790 | .callback = intel_no_lvds_dmi_callback, | ||
782 | .ident = "Aopen i945GTt-VFA", | 791 | .ident = "Aopen i945GTt-VFA", |
783 | .matches = { | 792 | .matches = { |
784 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), | 793 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), |
@@ -788,6 +797,65 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
788 | { } /* terminating entry */ | 797 | { } /* terminating entry */ |
789 | }; | 798 | }; |
790 | 799 | ||
800 | #ifdef CONFIG_ACPI | ||
801 | /* | ||
802 | * check_lid_device -- check whether @handle is an ACPI LID device. | ||
803 | * @handle: ACPI device handle | ||
804 | * @level : depth in the ACPI namespace tree | ||
805 | * @context: the number of LID device when we find the device | ||
806 | * @rv: a return value to fill if desired (Not use) | ||
807 | */ | ||
808 | static acpi_status | ||
809 | check_lid_device(acpi_handle handle, u32 level, void *context, | ||
810 | void **return_value) | ||
811 | { | ||
812 | struct acpi_device *acpi_dev; | ||
813 | int *lid_present = context; | ||
814 | |||
815 | acpi_dev = NULL; | ||
816 | /* Get the acpi device for device handle */ | ||
817 | if (acpi_bus_get_device(handle, &acpi_dev) || !acpi_dev) { | ||
818 | /* If there is no ACPI device for handle, return */ | ||
819 | return AE_OK; | ||
820 | } | ||
821 | |||
822 | if (!strncmp(acpi_device_hid(acpi_dev), "PNP0C0D", 7)) | ||
823 | *lid_present = 1; | ||
824 | |||
825 | return AE_OK; | ||
826 | } | ||
827 | |||
828 | /** | ||
829 | * check whether there exists the ACPI LID device by enumerating the ACPI | ||
830 | * device tree. | ||
831 | */ | ||
832 | static int intel_lid_present(void) | ||
833 | { | ||
834 | int lid_present = 0; | ||
835 | |||
836 | if (acpi_disabled) { | ||
837 | /* If ACPI is disabled, there is no ACPI device tree to | ||
838 | * check, so assume the LID device would have been present. | ||
839 | */ | ||
840 | return 1; | ||
841 | } | ||
842 | |||
843 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
844 | ACPI_UINT32_MAX, | ||
845 | check_lid_device, &lid_present, NULL); | ||
846 | |||
847 | return lid_present; | ||
848 | } | ||
849 | #else | ||
850 | static int intel_lid_present(void) | ||
851 | { | ||
852 | /* In the absence of ACPI built in, assume that the LID device would | ||
853 | * have been present. | ||
854 | */ | ||
855 | return 1; | ||
856 | } | ||
857 | #endif | ||
858 | |||
791 | /** | 859 | /** |
792 | * intel_lvds_init - setup LVDS connectors on this device | 860 | * intel_lvds_init - setup LVDS connectors on this device |
793 | * @dev: drm device | 861 | * @dev: drm device |
@@ -811,9 +879,23 @@ void intel_lvds_init(struct drm_device *dev) | |||
811 | if (dmi_check_system(intel_no_lvds)) | 879 | if (dmi_check_system(intel_no_lvds)) |
812 | return; | 880 | return; |
813 | 881 | ||
882 | /* Assume that any device without an ACPI LID device also doesn't | ||
883 | * have an integrated LVDS. We would be better off parsing the BIOS | ||
884 | * to get a reliable indicator, but that code isn't written yet. | ||
885 | * | ||
886 | * In the case of all-in-one desktops using LVDS that we've seen, | ||
887 | * they're using SDVO LVDS. | ||
888 | */ | ||
889 | if (!intel_lid_present()) | ||
890 | return; | ||
891 | |||
814 | if (IS_IGDNG(dev)) { | 892 | if (IS_IGDNG(dev)) { |
815 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) | 893 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) |
816 | return; | 894 | return; |
895 | if (dev_priv->edp_support) { | ||
896 | DRM_DEBUG("disable LVDS for eDP support\n"); | ||
897 | return; | ||
898 | } | ||
817 | gpio = PCH_GPIOC; | 899 | gpio = PCH_GPIOC; |
818 | } | 900 | } |
819 | 901 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index f03473779feb..5371d9332554 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "drm.h" | 31 | #include "drm.h" |
32 | #include "drm_crtc.h" | 32 | #include "drm_crtc.h" |
33 | #include "intel_drv.h" | 33 | #include "intel_drv.h" |
34 | #include "drm_edid.h" | ||
34 | #include "i915_drm.h" | 35 | #include "i915_drm.h" |
35 | #include "i915_drv.h" | 36 | #include "i915_drv.h" |
36 | #include "intel_sdvo_regs.h" | 37 | #include "intel_sdvo_regs.h" |
@@ -55,6 +56,12 @@ struct intel_sdvo_priv { | |||
55 | /* Pixel clock limitations reported by the SDVO device, in kHz */ | 56 | /* Pixel clock limitations reported by the SDVO device, in kHz */ |
56 | int pixel_clock_min, pixel_clock_max; | 57 | int pixel_clock_min, pixel_clock_max; |
57 | 58 | ||
59 | /* | ||
60 | * For multiple function SDVO device, | ||
61 | * this is for current attached outputs. | ||
62 | */ | ||
63 | uint16_t attached_output; | ||
64 | |||
58 | /** | 65 | /** |
59 | * This is set if we're going to treat the device as TV-out. | 66 | * This is set if we're going to treat the device as TV-out. |
60 | * | 67 | * |
@@ -68,12 +75,23 @@ struct intel_sdvo_priv { | |||
68 | * This is set if we treat the device as HDMI, instead of DVI. | 75 | * This is set if we treat the device as HDMI, instead of DVI. |
69 | */ | 76 | */ |
70 | bool is_hdmi; | 77 | bool is_hdmi; |
78 | |||
71 | /** | 79 | /** |
72 | * This is set if we detect output of sdvo device as LVDS. | 80 | * This is set if we detect output of sdvo device as LVDS. |
73 | */ | 81 | */ |
74 | bool is_lvds; | 82 | bool is_lvds; |
75 | 83 | ||
76 | /** | 84 | /** |
85 | * This is sdvo flags for input timing. | ||
86 | */ | ||
87 | uint8_t sdvo_flags; | ||
88 | |||
89 | /** | ||
90 | * This is sdvo fixed pannel mode pointer | ||
91 | */ | ||
92 | struct drm_display_mode *sdvo_lvds_fixed_mode; | ||
93 | |||
94 | /** | ||
77 | * Returned SDTV resolutions allowed for the current format, if the | 95 | * Returned SDTV resolutions allowed for the current format, if the |
78 | * device reported it. | 96 | * device reported it. |
79 | */ | 97 | */ |
@@ -103,6 +121,9 @@ struct intel_sdvo_priv { | |||
103 | u32 save_SDVOX; | 121 | u32 save_SDVOX; |
104 | }; | 122 | }; |
105 | 123 | ||
124 | static bool | ||
125 | intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags); | ||
126 | |||
106 | /** | 127 | /** |
107 | * Writes the SDVOB or SDVOC with the given value, but always writes both | 128 | * Writes the SDVOB or SDVOC with the given value, but always writes both |
108 | * SDVOB and SDVOC to work around apparent hardware issues (according to | 129 | * SDVOB and SDVOC to work around apparent hardware issues (according to |
@@ -592,6 +613,7 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, | |||
592 | uint16_t height) | 613 | uint16_t height) |
593 | { | 614 | { |
594 | struct intel_sdvo_preferred_input_timing_args args; | 615 | struct intel_sdvo_preferred_input_timing_args args; |
616 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | ||
595 | uint8_t status; | 617 | uint8_t status; |
596 | 618 | ||
597 | memset(&args, 0, sizeof(args)); | 619 | memset(&args, 0, sizeof(args)); |
@@ -599,7 +621,12 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, | |||
599 | args.width = width; | 621 | args.width = width; |
600 | args.height = height; | 622 | args.height = height; |
601 | args.interlace = 0; | 623 | args.interlace = 0; |
602 | args.scaled = 0; | 624 | |
625 | if (sdvo_priv->is_lvds && | ||
626 | (sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width || | ||
627 | sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) | ||
628 | args.scaled = 1; | ||
629 | |||
603 | intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, | 630 | intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, |
604 | &args, sizeof(args)); | 631 | &args, sizeof(args)); |
605 | status = intel_sdvo_read_response(output, NULL, 0); | 632 | status = intel_sdvo_read_response(output, NULL, 0); |
@@ -944,12 +971,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
944 | struct intel_output *output = enc_to_intel_output(encoder); | 971 | struct intel_output *output = enc_to_intel_output(encoder); |
945 | struct intel_sdvo_priv *dev_priv = output->dev_priv; | 972 | struct intel_sdvo_priv *dev_priv = output->dev_priv; |
946 | 973 | ||
947 | if (!dev_priv->is_tv) { | 974 | if (dev_priv->is_tv) { |
948 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
949 | * SDVO device will be told of the multiplier during mode_set. | ||
950 | */ | ||
951 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
952 | } else { | ||
953 | struct intel_sdvo_dtd output_dtd; | 975 | struct intel_sdvo_dtd output_dtd; |
954 | bool success; | 976 | bool success; |
955 | 977 | ||
@@ -980,6 +1002,47 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
980 | intel_sdvo_get_preferred_input_timing(output, | 1002 | intel_sdvo_get_preferred_input_timing(output, |
981 | &input_dtd); | 1003 | &input_dtd); |
982 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | 1004 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
1005 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
1006 | |||
1007 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
1008 | |||
1009 | mode->clock = adjusted_mode->clock; | ||
1010 | |||
1011 | adjusted_mode->clock *= | ||
1012 | intel_sdvo_get_pixel_multiplier(mode); | ||
1013 | } else { | ||
1014 | return false; | ||
1015 | } | ||
1016 | } else if (dev_priv->is_lvds) { | ||
1017 | struct intel_sdvo_dtd output_dtd; | ||
1018 | bool success; | ||
1019 | |||
1020 | drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0); | ||
1021 | /* Set output timings */ | ||
1022 | intel_sdvo_get_dtd_from_mode(&output_dtd, | ||
1023 | dev_priv->sdvo_lvds_fixed_mode); | ||
1024 | |||
1025 | intel_sdvo_set_target_output(output, | ||
1026 | dev_priv->controlled_output); | ||
1027 | intel_sdvo_set_output_timing(output, &output_dtd); | ||
1028 | |||
1029 | /* Set the input timing to the screen. Assume always input 0. */ | ||
1030 | intel_sdvo_set_target_input(output, true, false); | ||
1031 | |||
1032 | |||
1033 | success = intel_sdvo_create_preferred_input_timing( | ||
1034 | output, | ||
1035 | mode->clock / 10, | ||
1036 | mode->hdisplay, | ||
1037 | mode->vdisplay); | ||
1038 | |||
1039 | if (success) { | ||
1040 | struct intel_sdvo_dtd input_dtd; | ||
1041 | |||
1042 | intel_sdvo_get_preferred_input_timing(output, | ||
1043 | &input_dtd); | ||
1044 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
1045 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
983 | 1046 | ||
984 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 1047 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
985 | 1048 | ||
@@ -990,6 +1053,12 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
990 | } else { | 1053 | } else { |
991 | return false; | 1054 | return false; |
992 | } | 1055 | } |
1056 | |||
1057 | } else { | ||
1058 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
1059 | * SDVO device will be told of the multiplier during mode_set. | ||
1060 | */ | ||
1061 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
993 | } | 1062 | } |
994 | return true; | 1063 | return true; |
995 | } | 1064 | } |
@@ -1033,15 +1102,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1033 | 1102 | ||
1034 | /* We have tried to get input timing in mode_fixup, and filled into | 1103 | /* We have tried to get input timing in mode_fixup, and filled into |
1035 | adjusted_mode */ | 1104 | adjusted_mode */ |
1036 | if (sdvo_priv->is_tv) | 1105 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { |
1037 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1106 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1038 | else | 1107 | input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags; |
1108 | } else | ||
1039 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); | 1109 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); |
1040 | 1110 | ||
1041 | /* If it's a TV, we already set the output timing in mode_fixup. | 1111 | /* If it's a TV, we already set the output timing in mode_fixup. |
1042 | * Otherwise, the output timing is equal to the input timing. | 1112 | * Otherwise, the output timing is equal to the input timing. |
1043 | */ | 1113 | */ |
1044 | if (!sdvo_priv->is_tv) { | 1114 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { |
1045 | /* Set the output timing to the screen */ | 1115 | /* Set the output timing to the screen */ |
1046 | intel_sdvo_set_target_output(output, | 1116 | intel_sdvo_set_target_output(output, |
1047 | sdvo_priv->controlled_output); | 1117 | sdvo_priv->controlled_output); |
@@ -1116,6 +1186,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1116 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; | 1186 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; |
1117 | } | 1187 | } |
1118 | 1188 | ||
1189 | if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) | ||
1190 | sdvox |= SDVO_STALL_SELECT; | ||
1119 | intel_sdvo_write_sdvox(output, sdvox); | 1191 | intel_sdvo_write_sdvox(output, sdvox); |
1120 | } | 1192 | } |
1121 | 1193 | ||
@@ -1276,6 +1348,17 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, | |||
1276 | if (sdvo_priv->pixel_clock_max < mode->clock) | 1348 | if (sdvo_priv->pixel_clock_max < mode->clock) |
1277 | return MODE_CLOCK_HIGH; | 1349 | return MODE_CLOCK_HIGH; |
1278 | 1350 | ||
1351 | if (sdvo_priv->is_lvds == true) { | ||
1352 | if (sdvo_priv->sdvo_lvds_fixed_mode == NULL) | ||
1353 | return MODE_PANEL; | ||
1354 | |||
1355 | if (mode->hdisplay > sdvo_priv->sdvo_lvds_fixed_mode->hdisplay) | ||
1356 | return MODE_PANEL; | ||
1357 | |||
1358 | if (mode->vdisplay > sdvo_priv->sdvo_lvds_fixed_mode->vdisplay) | ||
1359 | return MODE_PANEL; | ||
1360 | } | ||
1361 | |||
1279 | return MODE_OK; | 1362 | return MODE_OK; |
1280 | } | 1363 | } |
1281 | 1364 | ||
@@ -1362,41 +1445,96 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) | |||
1362 | intel_sdvo_read_response(intel_output, &response, 2); | 1445 | intel_sdvo_read_response(intel_output, &response, 2); |
1363 | } | 1446 | } |
1364 | 1447 | ||
1365 | static void | 1448 | static bool |
1366 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | 1449 | intel_sdvo_multifunc_encoder(struct intel_output *intel_output) |
1450 | { | ||
1451 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1452 | int caps = 0; | ||
1453 | |||
1454 | if (sdvo_priv->caps.output_flags & | ||
1455 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | ||
1456 | caps++; | ||
1457 | if (sdvo_priv->caps.output_flags & | ||
1458 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) | ||
1459 | caps++; | ||
1460 | if (sdvo_priv->caps.output_flags & | ||
1461 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID0)) | ||
1462 | caps++; | ||
1463 | if (sdvo_priv->caps.output_flags & | ||
1464 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) | ||
1465 | caps++; | ||
1466 | if (sdvo_priv->caps.output_flags & | ||
1467 | (SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_YPRPB1)) | ||
1468 | caps++; | ||
1469 | |||
1470 | if (sdvo_priv->caps.output_flags & | ||
1471 | (SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1)) | ||
1472 | caps++; | ||
1473 | |||
1474 | if (sdvo_priv->caps.output_flags & | ||
1475 | (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) | ||
1476 | caps++; | ||
1477 | |||
1478 | return (caps > 1); | ||
1479 | } | ||
1480 | |||
1481 | enum drm_connector_status | ||
1482 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | ||
1367 | { | 1483 | { |
1368 | struct intel_output *intel_output = to_intel_output(connector); | 1484 | struct intel_output *intel_output = to_intel_output(connector); |
1369 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1485 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; |
1486 | enum drm_connector_status status = connector_status_connected; | ||
1370 | struct edid *edid = NULL; | 1487 | struct edid *edid = NULL; |
1371 | 1488 | ||
1372 | edid = drm_get_edid(&intel_output->base, | 1489 | edid = drm_get_edid(&intel_output->base, |
1373 | intel_output->ddc_bus); | 1490 | intel_output->ddc_bus); |
1374 | if (edid != NULL) { | 1491 | if (edid != NULL) { |
1375 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | 1492 | /* Don't report the output as connected if it's a DVI-I |
1493 | * connector with a non-digital EDID coming out. | ||
1494 | */ | ||
1495 | if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | ||
1496 | if (edid->input & DRM_EDID_INPUT_DIGITAL) | ||
1497 | sdvo_priv->is_hdmi = | ||
1498 | drm_detect_hdmi_monitor(edid); | ||
1499 | else | ||
1500 | status = connector_status_disconnected; | ||
1501 | } | ||
1502 | |||
1376 | kfree(edid); | 1503 | kfree(edid); |
1377 | intel_output->base.display_info.raw_edid = NULL; | 1504 | intel_output->base.display_info.raw_edid = NULL; |
1378 | } | 1505 | |
1506 | } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | ||
1507 | status = connector_status_disconnected; | ||
1508 | |||
1509 | return status; | ||
1379 | } | 1510 | } |
1380 | 1511 | ||
1381 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) | 1512 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) |
1382 | { | 1513 | { |
1383 | u8 response[2]; | 1514 | uint16_t response; |
1384 | u8 status; | 1515 | u8 status; |
1385 | struct intel_output *intel_output = to_intel_output(connector); | 1516 | struct intel_output *intel_output = to_intel_output(connector); |
1517 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1386 | 1518 | ||
1387 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | 1519 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); |
1388 | status = intel_sdvo_read_response(intel_output, &response, 2); | 1520 | status = intel_sdvo_read_response(intel_output, &response, 2); |
1389 | 1521 | ||
1390 | DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]); | 1522 | DRM_DEBUG("SDVO response %d %d\n", response & 0xff, response >> 8); |
1391 | 1523 | ||
1392 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1524 | if (status != SDVO_CMD_STATUS_SUCCESS) |
1393 | return connector_status_unknown; | 1525 | return connector_status_unknown; |
1394 | 1526 | ||
1395 | if ((response[0] != 0) || (response[1] != 0)) { | 1527 | if (response == 0) |
1396 | intel_sdvo_hdmi_sink_detect(connector); | ||
1397 | return connector_status_connected; | ||
1398 | } else | ||
1399 | return connector_status_disconnected; | 1528 | return connector_status_disconnected; |
1529 | |||
1530 | if (intel_sdvo_multifunc_encoder(intel_output) && | ||
1531 | sdvo_priv->attached_output != response) { | ||
1532 | if (sdvo_priv->controlled_output != response && | ||
1533 | intel_sdvo_output_setup(intel_output, response) != true) | ||
1534 | return connector_status_unknown; | ||
1535 | sdvo_priv->attached_output = response; | ||
1536 | } | ||
1537 | return intel_sdvo_hdmi_sink_detect(connector, response); | ||
1400 | } | 1538 | } |
1401 | 1539 | ||
1402 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1540 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
@@ -1549,6 +1687,8 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1549 | { | 1687 | { |
1550 | struct intel_output *intel_output = to_intel_output(connector); | 1688 | struct intel_output *intel_output = to_intel_output(connector); |
1551 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1689 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1690 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1691 | struct drm_display_mode *newmode; | ||
1552 | 1692 | ||
1553 | /* | 1693 | /* |
1554 | * Attempt to get the mode list from DDC. | 1694 | * Attempt to get the mode list from DDC. |
@@ -1557,11 +1697,10 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1557 | */ | 1697 | */ |
1558 | intel_ddc_get_modes(intel_output); | 1698 | intel_ddc_get_modes(intel_output); |
1559 | if (list_empty(&connector->probed_modes) == false) | 1699 | if (list_empty(&connector->probed_modes) == false) |
1560 | return; | 1700 | goto end; |
1561 | 1701 | ||
1562 | /* Fetch modes from VBT */ | 1702 | /* Fetch modes from VBT */ |
1563 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { | 1703 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { |
1564 | struct drm_display_mode *newmode; | ||
1565 | newmode = drm_mode_duplicate(connector->dev, | 1704 | newmode = drm_mode_duplicate(connector->dev, |
1566 | dev_priv->sdvo_lvds_vbt_mode); | 1705 | dev_priv->sdvo_lvds_vbt_mode); |
1567 | if (newmode != NULL) { | 1706 | if (newmode != NULL) { |
@@ -1571,6 +1710,16 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1571 | drm_mode_probed_add(connector, newmode); | 1710 | drm_mode_probed_add(connector, newmode); |
1572 | } | 1711 | } |
1573 | } | 1712 | } |
1713 | |||
1714 | end: | ||
1715 | list_for_each_entry(newmode, &connector->probed_modes, head) { | ||
1716 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { | ||
1717 | sdvo_priv->sdvo_lvds_fixed_mode = | ||
1718 | drm_mode_duplicate(connector->dev, newmode); | ||
1719 | break; | ||
1720 | } | ||
1721 | } | ||
1722 | |||
1574 | } | 1723 | } |
1575 | 1724 | ||
1576 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1725 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
@@ -1593,14 +1742,20 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) | |||
1593 | static void intel_sdvo_destroy(struct drm_connector *connector) | 1742 | static void intel_sdvo_destroy(struct drm_connector *connector) |
1594 | { | 1743 | { |
1595 | struct intel_output *intel_output = to_intel_output(connector); | 1744 | struct intel_output *intel_output = to_intel_output(connector); |
1745 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1596 | 1746 | ||
1597 | if (intel_output->i2c_bus) | 1747 | if (intel_output->i2c_bus) |
1598 | intel_i2c_destroy(intel_output->i2c_bus); | 1748 | intel_i2c_destroy(intel_output->i2c_bus); |
1599 | if (intel_output->ddc_bus) | 1749 | if (intel_output->ddc_bus) |
1600 | intel_i2c_destroy(intel_output->ddc_bus); | 1750 | intel_i2c_destroy(intel_output->ddc_bus); |
1601 | 1751 | ||
1752 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | ||
1753 | drm_mode_destroy(connector->dev, | ||
1754 | sdvo_priv->sdvo_lvds_fixed_mode); | ||
1755 | |||
1602 | drm_sysfs_connector_remove(connector); | 1756 | drm_sysfs_connector_remove(connector); |
1603 | drm_connector_cleanup(connector); | 1757 | drm_connector_cleanup(connector); |
1758 | |||
1604 | kfree(intel_output); | 1759 | kfree(intel_output); |
1605 | } | 1760 | } |
1606 | 1761 | ||
@@ -1776,16 +1931,101 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device) | |||
1776 | return 0x72; | 1931 | return 0x72; |
1777 | } | 1932 | } |
1778 | 1933 | ||
1934 | static bool | ||
1935 | intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | ||
1936 | { | ||
1937 | struct drm_connector *connector = &intel_output->base; | ||
1938 | struct drm_encoder *encoder = &intel_output->enc; | ||
1939 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1940 | bool ret = true, registered = false; | ||
1941 | |||
1942 | sdvo_priv->is_tv = false; | ||
1943 | intel_output->needs_tv_clock = false; | ||
1944 | sdvo_priv->is_lvds = false; | ||
1945 | |||
1946 | if (device_is_registered(&connector->kdev)) { | ||
1947 | drm_sysfs_connector_remove(connector); | ||
1948 | registered = true; | ||
1949 | } | ||
1950 | |||
1951 | if (flags & | ||
1952 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | ||
1953 | if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) | ||
1954 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0; | ||
1955 | else | ||
1956 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1; | ||
1957 | |||
1958 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; | ||
1959 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; | ||
1960 | |||
1961 | if (intel_sdvo_get_supp_encode(intel_output, | ||
1962 | &sdvo_priv->encode) && | ||
1963 | intel_sdvo_get_digital_encoding_mode(intel_output) && | ||
1964 | sdvo_priv->is_hdmi) { | ||
1965 | /* enable hdmi encoding mode if supported */ | ||
1966 | intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI); | ||
1967 | intel_sdvo_set_colorimetry(intel_output, | ||
1968 | SDVO_COLORIMETRY_RGB256); | ||
1969 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | ||
1970 | } | ||
1971 | } else if (flags & SDVO_OUTPUT_SVID0) { | ||
1972 | |||
1973 | sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; | ||
1974 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
1975 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
1976 | sdvo_priv->is_tv = true; | ||
1977 | intel_output->needs_tv_clock = true; | ||
1978 | } else if (flags & SDVO_OUTPUT_RGB0) { | ||
1979 | |||
1980 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; | ||
1981 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | ||
1982 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | ||
1983 | } else if (flags & SDVO_OUTPUT_RGB1) { | ||
1984 | |||
1985 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; | ||
1986 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | ||
1987 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | ||
1988 | } else if (flags & SDVO_OUTPUT_LVDS0) { | ||
1989 | |||
1990 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; | ||
1991 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | ||
1992 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
1993 | sdvo_priv->is_lvds = true; | ||
1994 | } else if (flags & SDVO_OUTPUT_LVDS1) { | ||
1995 | |||
1996 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; | ||
1997 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | ||
1998 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
1999 | sdvo_priv->is_lvds = true; | ||
2000 | } else { | ||
2001 | |||
2002 | unsigned char bytes[2]; | ||
2003 | |||
2004 | sdvo_priv->controlled_output = 0; | ||
2005 | memcpy(bytes, &sdvo_priv->caps.output_flags, 2); | ||
2006 | DRM_DEBUG_KMS(I915_SDVO, | ||
2007 | "%s: Unknown SDVO output type (0x%02x%02x)\n", | ||
2008 | SDVO_NAME(sdvo_priv), | ||
2009 | bytes[0], bytes[1]); | ||
2010 | ret = false; | ||
2011 | } | ||
2012 | |||
2013 | if (ret && registered) | ||
2014 | ret = drm_sysfs_connector_add(connector) == 0 ? true : false; | ||
2015 | |||
2016 | |||
2017 | return ret; | ||
2018 | |||
2019 | } | ||
2020 | |||
1779 | bool intel_sdvo_init(struct drm_device *dev, int output_device) | 2021 | bool intel_sdvo_init(struct drm_device *dev, int output_device) |
1780 | { | 2022 | { |
1781 | struct drm_connector *connector; | 2023 | struct drm_connector *connector; |
1782 | struct intel_output *intel_output; | 2024 | struct intel_output *intel_output; |
1783 | struct intel_sdvo_priv *sdvo_priv; | 2025 | struct intel_sdvo_priv *sdvo_priv; |
1784 | 2026 | ||
1785 | int connector_type; | ||
1786 | u8 ch[0x40]; | 2027 | u8 ch[0x40]; |
1787 | int i; | 2028 | int i; |
1788 | int encoder_type; | ||
1789 | 2029 | ||
1790 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 2030 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); |
1791 | if (!intel_output) { | 2031 | if (!intel_output) { |
@@ -1835,88 +2075,28 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1835 | intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; | 2075 | intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; |
1836 | 2076 | ||
1837 | /* In defaut case sdvo lvds is false */ | 2077 | /* In defaut case sdvo lvds is false */ |
1838 | sdvo_priv->is_lvds = false; | ||
1839 | intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); | 2078 | intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); |
1840 | 2079 | ||
1841 | if (sdvo_priv->caps.output_flags & | 2080 | if (intel_sdvo_output_setup(intel_output, |
1842 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | 2081 | sdvo_priv->caps.output_flags) != true) { |
1843 | if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) | 2082 | DRM_DEBUG("SDVO output failed to setup on SDVO%c\n", |
1844 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0; | 2083 | output_device == SDVOB ? 'B' : 'C'); |
1845 | else | ||
1846 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1; | ||
1847 | |||
1848 | encoder_type = DRM_MODE_ENCODER_TMDS; | ||
1849 | connector_type = DRM_MODE_CONNECTOR_DVID; | ||
1850 | |||
1851 | if (intel_sdvo_get_supp_encode(intel_output, | ||
1852 | &sdvo_priv->encode) && | ||
1853 | intel_sdvo_get_digital_encoding_mode(intel_output) && | ||
1854 | sdvo_priv->is_hdmi) { | ||
1855 | /* enable hdmi encoding mode if supported */ | ||
1856 | intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI); | ||
1857 | intel_sdvo_set_colorimetry(intel_output, | ||
1858 | SDVO_COLORIMETRY_RGB256); | ||
1859 | connector_type = DRM_MODE_CONNECTOR_HDMIA; | ||
1860 | } | ||
1861 | } | ||
1862 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0) | ||
1863 | { | ||
1864 | sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; | ||
1865 | encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
1866 | connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
1867 | sdvo_priv->is_tv = true; | ||
1868 | intel_output->needs_tv_clock = true; | ||
1869 | } | ||
1870 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) | ||
1871 | { | ||
1872 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; | ||
1873 | encoder_type = DRM_MODE_ENCODER_DAC; | ||
1874 | connector_type = DRM_MODE_CONNECTOR_VGA; | ||
1875 | } | ||
1876 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) | ||
1877 | { | ||
1878 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; | ||
1879 | encoder_type = DRM_MODE_ENCODER_DAC; | ||
1880 | connector_type = DRM_MODE_CONNECTOR_VGA; | ||
1881 | } | ||
1882 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0) | ||
1883 | { | ||
1884 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; | ||
1885 | encoder_type = DRM_MODE_ENCODER_LVDS; | ||
1886 | connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
1887 | sdvo_priv->is_lvds = true; | ||
1888 | } | ||
1889 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1) | ||
1890 | { | ||
1891 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; | ||
1892 | encoder_type = DRM_MODE_ENCODER_LVDS; | ||
1893 | connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
1894 | sdvo_priv->is_lvds = true; | ||
1895 | } | ||
1896 | else | ||
1897 | { | ||
1898 | unsigned char bytes[2]; | ||
1899 | |||
1900 | sdvo_priv->controlled_output = 0; | ||
1901 | memcpy (bytes, &sdvo_priv->caps.output_flags, 2); | ||
1902 | DRM_DEBUG_KMS(I915_SDVO, | ||
1903 | "%s: Unknown SDVO output type (0x%02x%02x)\n", | ||
1904 | SDVO_NAME(sdvo_priv), | ||
1905 | bytes[0], bytes[1]); | ||
1906 | encoder_type = DRM_MODE_ENCODER_NONE; | ||
1907 | connector_type = DRM_MODE_CONNECTOR_Unknown; | ||
1908 | goto err_i2c; | 2084 | goto err_i2c; |
1909 | } | 2085 | } |
1910 | 2086 | ||
2087 | |||
1911 | connector = &intel_output->base; | 2088 | connector = &intel_output->base; |
1912 | drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, | 2089 | drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, |
1913 | connector_type); | 2090 | connector->connector_type); |
2091 | |||
1914 | drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs); | 2092 | drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs); |
1915 | connector->interlace_allowed = 0; | 2093 | connector->interlace_allowed = 0; |
1916 | connector->doublescan_allowed = 0; | 2094 | connector->doublescan_allowed = 0; |
1917 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | 2095 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
1918 | 2096 | ||
1919 | drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type); | 2097 | drm_encoder_init(dev, &intel_output->enc, |
2098 | &intel_sdvo_enc_funcs, intel_output->enc.encoder_type); | ||
2099 | |||
1920 | drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); | 2100 | drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); |
1921 | 2101 | ||
1922 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 2102 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index 193938b7d7f9..ba5cdf8ae40b 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h | |||
@@ -715,6 +715,7 @@ struct intel_sdvo_enhancements_arg { | |||
715 | #define SDVO_HBUF_TX_ONCE (2 << 6) | 715 | #define SDVO_HBUF_TX_ONCE (2 << 6) |
716 | #define SDVO_HBUF_TX_VSYNC (3 << 6) | 716 | #define SDVO_HBUF_TX_VSYNC (3 << 6) |
717 | #define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c | 717 | #define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c |
718 | #define SDVO_NEED_TO_STALL (1 << 7) | ||
718 | 719 | ||
719 | struct intel_sdvo_encode{ | 720 | struct intel_sdvo_encode{ |
720 | u8 dvi_rev; | 721 | u8 dvi_rev; |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index a43c98e3f077..da4ab4dc1630 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1490,6 +1490,27 @@ static struct input_res { | |||
1490 | {"1920x1080", 1920, 1080}, | 1490 | {"1920x1080", 1920, 1080}, |
1491 | }; | 1491 | }; |
1492 | 1492 | ||
1493 | /* | ||
1494 | * Chose preferred mode according to line number of TV format | ||
1495 | */ | ||
1496 | static void | ||
1497 | intel_tv_chose_preferred_modes(struct drm_connector *connector, | ||
1498 | struct drm_display_mode *mode_ptr) | ||
1499 | { | ||
1500 | struct intel_output *intel_output = to_intel_output(connector); | ||
1501 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); | ||
1502 | |||
1503 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) | ||
1504 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; | ||
1505 | else if (tv_mode->nbr_end > 480) { | ||
1506 | if (tv_mode->progressive == true && tv_mode->nbr_end < 720) { | ||
1507 | if (mode_ptr->vdisplay == 720) | ||
1508 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; | ||
1509 | } else if (mode_ptr->vdisplay == 1080) | ||
1510 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; | ||
1511 | } | ||
1512 | } | ||
1513 | |||
1493 | /** | 1514 | /** |
1494 | * Stub get_modes function. | 1515 | * Stub get_modes function. |
1495 | * | 1516 | * |
@@ -1544,6 +1565,7 @@ intel_tv_get_modes(struct drm_connector *connector) | |||
1544 | mode_ptr->clock = (int) tmp; | 1565 | mode_ptr->clock = (int) tmp; |
1545 | 1566 | ||
1546 | mode_ptr->type = DRM_MODE_TYPE_DRIVER; | 1567 | mode_ptr->type = DRM_MODE_TYPE_DRIVER; |
1568 | intel_tv_chose_preferred_modes(connector, mode_ptr); | ||
1547 | drm_mode_probed_add(connector, mode_ptr); | 1569 | drm_mode_probed_add(connector, mode_ptr); |
1548 | count++; | 1570 | count++; |
1549 | } | 1571 | } |