diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-06-12 11:02:03 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-06-12 11:02:03 -0400 |
commit | 82681a318f9f028ea64e61f24bbd9ac535531921 (patch) | |
tree | 529b6a5b4fd040fb54b7672b1a224ebd47445876 /drivers/gpu | |
parent | 3860c97bd60a4525bb62eb90e3e7d2f02662ac59 (diff) | |
parent | 8ebf975608aaebd7feb33d77f07ba21a6380e086 (diff) |
[SCSI] Merge branch 'linus'
Conflicts:
drivers/message/fusion/mptsas.c
fixed up conflict between req->data_len accessors and mptsas driver updates.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/gpu')
24 files changed, 602 insertions, 137 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 4cd35d8fd799..f5d46e7199d4 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -67,12 +67,18 @@ config DRM_I830 | |||
67 | will load the correct one. | 67 | will load the correct one. |
68 | 68 | ||
69 | config DRM_I915 | 69 | config DRM_I915 |
70 | tristate "i915 driver" | ||
70 | select FB_CFB_FILLRECT | 71 | select FB_CFB_FILLRECT |
71 | select FB_CFB_COPYAREA | 72 | select FB_CFB_COPYAREA |
72 | select FB_CFB_IMAGEBLIT | 73 | select FB_CFB_IMAGEBLIT |
73 | select FB | 74 | select FB |
74 | select FRAMEBUFFER_CONSOLE if !EMBEDDED | 75 | select FRAMEBUFFER_CONSOLE if !EMBEDDED |
75 | tristate "i915 driver" | 76 | # i915 depends on ACPI_VIDEO when ACPI is enabled |
77 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick | ||
78 | select VIDEO_OUTPUT_CONTROL if ACPI | ||
79 | select BACKLIGHT_CLASS_DEVICE if ACPI | ||
80 | select INPUT if ACPI | ||
81 | select ACPI_VIDEO if ACPI | ||
76 | help | 82 | help |
77 | Choose this option if you have a system that has Intel 830M, 845G, | 83 | Choose this option if you have a system that has Intel 830M, 845G, |
78 | 852GM, 855GM 865G or 915G integrated graphics. If M is selected, the | 84 | 852GM, 855GM 865G or 915G integrated graphics. If M is selected, the |
@@ -84,12 +90,6 @@ config DRM_I915 | |||
84 | config DRM_I915_KMS | 90 | config DRM_I915_KMS |
85 | bool "Enable modesetting on intel by default" | 91 | bool "Enable modesetting on intel by default" |
86 | depends on DRM_I915 | 92 | depends on DRM_I915 |
87 | # i915 KMS depends on ACPI_VIDEO when ACPI is enabled | ||
88 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick | ||
89 | select VIDEO_OUTPUT_CONTROL if ACPI | ||
90 | select BACKLIGHT_CLASS_DEVICE if ACPI | ||
91 | select INPUT if ACPI | ||
92 | select ACPI_VIDEO if ACPI | ||
93 | help | 93 | help |
94 | Choose this option if you want kernel modesetting enabled by default, | 94 | Choose this option if you want kernel modesetting enabled by default, |
95 | and you have a new enough userspace to support this. Running old | 95 | and you have a new enough userspace to support this. Running old |
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 6d80d17f1e96..0411d912d82a 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c | |||
@@ -170,6 +170,14 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
170 | } | 170 | } |
171 | DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n", | 171 | DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n", |
172 | (unsigned long long)map->offset, map->size, map->type); | 172 | (unsigned long long)map->offset, map->size, map->type); |
173 | |||
174 | /* page-align _DRM_SHM maps. They are allocated here so there is no security | ||
175 | * hole created by that and it works around various broken drivers that use | ||
176 | * a non-aligned quantity to map the SAREA. --BenH | ||
177 | */ | ||
178 | if (map->type == _DRM_SHM) | ||
179 | map->size = PAGE_ALIGN(map->size); | ||
180 | |||
173 | if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) { | 181 | if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) { |
174 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 182 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
175 | return -EINVAL; | 183 | return -EINVAL; |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 94a768871734..8fab7890a363 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -2294,7 +2294,12 @@ int drm_mode_connector_property_set_ioctl(struct drm_device *dev, | |||
2294 | } | 2294 | } |
2295 | } | 2295 | } |
2296 | 2296 | ||
2297 | if (connector->funcs->set_property) | 2297 | /* Do DPMS ourselves */ |
2298 | if (property == connector->dev->mode_config.dpms_property) { | ||
2299 | if (connector->funcs->dpms) | ||
2300 | (*connector->funcs->dpms)(connector, (int) out_resp->value); | ||
2301 | ret = 0; | ||
2302 | } else if (connector->funcs->set_property) | ||
2298 | ret = connector->funcs->set_property(connector, property, out_resp->value); | 2303 | ret = connector->funcs->set_property(connector, property, out_resp->value); |
2299 | 2304 | ||
2300 | /* store the property value if succesful */ | 2305 | /* store the property value if succesful */ |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 45890447feec..a6f73f1e99d9 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -199,6 +199,29 @@ static void drm_helper_add_std_modes(struct drm_device *dev, | |||
199 | } | 199 | } |
200 | 200 | ||
201 | /** | 201 | /** |
202 | * drm_helper_encoder_in_use - check if a given encoder is in use | ||
203 | * @encoder: encoder to check | ||
204 | * | ||
205 | * LOCKING: | ||
206 | * Caller must hold mode config lock. | ||
207 | * | ||
208 | * Walk @encoders's DRM device's mode_config and see if it's in use. | ||
209 | * | ||
210 | * RETURNS: | ||
211 | * True if @encoder is part of the mode_config, false otherwise. | ||
212 | */ | ||
213 | bool drm_helper_encoder_in_use(struct drm_encoder *encoder) | ||
214 | { | ||
215 | struct drm_connector *connector; | ||
216 | struct drm_device *dev = encoder->dev; | ||
217 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
218 | if (connector->encoder == encoder) | ||
219 | return true; | ||
220 | return false; | ||
221 | } | ||
222 | EXPORT_SYMBOL(drm_helper_encoder_in_use); | ||
223 | |||
224 | /** | ||
202 | * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config | 225 | * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config |
203 | * @crtc: CRTC to check | 226 | * @crtc: CRTC to check |
204 | * | 227 | * |
@@ -216,7 +239,7 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc) | |||
216 | struct drm_device *dev = crtc->dev; | 239 | struct drm_device *dev = crtc->dev; |
217 | /* FIXME: Locking around list access? */ | 240 | /* FIXME: Locking around list access? */ |
218 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) | 241 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) |
219 | if (encoder->crtc == crtc) | 242 | if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder)) |
220 | return true; | 243 | return true; |
221 | return false; | 244 | return false; |
222 | } | 245 | } |
@@ -240,7 +263,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) | |||
240 | 263 | ||
241 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 264 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
242 | encoder_funcs = encoder->helper_private; | 265 | encoder_funcs = encoder->helper_private; |
243 | if (!encoder->crtc) | 266 | if (!drm_helper_encoder_in_use(encoder)) |
244 | (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); | 267 | (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); |
245 | } | 268 | } |
246 | 269 | ||
@@ -935,6 +958,88 @@ bool drm_helper_initial_config(struct drm_device *dev) | |||
935 | } | 958 | } |
936 | EXPORT_SYMBOL(drm_helper_initial_config); | 959 | EXPORT_SYMBOL(drm_helper_initial_config); |
937 | 960 | ||
961 | static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder) | ||
962 | { | ||
963 | int dpms = DRM_MODE_DPMS_OFF; | ||
964 | struct drm_connector *connector; | ||
965 | struct drm_device *dev = encoder->dev; | ||
966 | |||
967 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
968 | if (connector->encoder == encoder) | ||
969 | if (connector->dpms < dpms) | ||
970 | dpms = connector->dpms; | ||
971 | return dpms; | ||
972 | } | ||
973 | |||
974 | static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc) | ||
975 | { | ||
976 | int dpms = DRM_MODE_DPMS_OFF; | ||
977 | struct drm_connector *connector; | ||
978 | struct drm_device *dev = crtc->dev; | ||
979 | |||
980 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
981 | if (connector->encoder && connector->encoder->crtc == crtc) | ||
982 | if (connector->dpms < dpms) | ||
983 | dpms = connector->dpms; | ||
984 | return dpms; | ||
985 | } | ||
986 | |||
987 | /** | ||
988 | * drm_helper_connector_dpms | ||
989 | * @connector affected connector | ||
990 | * @mode DPMS mode | ||
991 | * | ||
992 | * Calls the low-level connector DPMS function, then | ||
993 | * calls appropriate encoder and crtc DPMS functions as well | ||
994 | */ | ||
995 | void drm_helper_connector_dpms(struct drm_connector *connector, int mode) | ||
996 | { | ||
997 | struct drm_encoder *encoder = connector->encoder; | ||
998 | struct drm_crtc *crtc = encoder ? encoder->crtc : NULL; | ||
999 | int old_dpms; | ||
1000 | |||
1001 | if (mode == connector->dpms) | ||
1002 | return; | ||
1003 | |||
1004 | old_dpms = connector->dpms; | ||
1005 | connector->dpms = mode; | ||
1006 | |||
1007 | /* from off to on, do crtc then encoder */ | ||
1008 | if (mode < old_dpms) { | ||
1009 | if (crtc) { | ||
1010 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | ||
1011 | if (crtc_funcs->dpms) | ||
1012 | (*crtc_funcs->dpms) (crtc, | ||
1013 | drm_helper_choose_crtc_dpms(crtc)); | ||
1014 | } | ||
1015 | if (encoder) { | ||
1016 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | ||
1017 | if (encoder_funcs->dpms) | ||
1018 | (*encoder_funcs->dpms) (encoder, | ||
1019 | drm_helper_choose_encoder_dpms(encoder)); | ||
1020 | } | ||
1021 | } | ||
1022 | |||
1023 | /* from on to off, do encoder then crtc */ | ||
1024 | if (mode > old_dpms) { | ||
1025 | if (encoder) { | ||
1026 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | ||
1027 | if (encoder_funcs->dpms) | ||
1028 | (*encoder_funcs->dpms) (encoder, | ||
1029 | drm_helper_choose_encoder_dpms(encoder)); | ||
1030 | } | ||
1031 | if (crtc) { | ||
1032 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | ||
1033 | if (crtc_funcs->dpms) | ||
1034 | (*crtc_funcs->dpms) (crtc, | ||
1035 | drm_helper_choose_crtc_dpms(crtc)); | ||
1036 | } | ||
1037 | } | ||
1038 | |||
1039 | return; | ||
1040 | } | ||
1041 | EXPORT_SYMBOL(drm_helper_connector_dpms); | ||
1042 | |||
938 | /** | 1043 | /** |
939 | * drm_hotplug_stage_two | 1044 | * drm_hotplug_stage_two |
940 | * @dev DRM device | 1045 | * @dev DRM device |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index f01def16a669..019b7c578236 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -481,7 +481,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, | |||
481 | } | 481 | } |
482 | retcode = func(dev, kdata, file_priv); | 482 | retcode = func(dev, kdata, file_priv); |
483 | 483 | ||
484 | if ((retcode == 0) && (cmd & IOC_OUT)) { | 484 | if (cmd & IOC_OUT) { |
485 | if (copy_to_user((void __user *)arg, kdata, | 485 | if (copy_to_user((void __user *)arg, kdata, |
486 | _IOC_SIZE(cmd)) != 0) | 486 | _IOC_SIZE(cmd)) != 0) |
487 | retcode = -EFAULT; | 487 | retcode = -EFAULT; |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index ca9c61656714..6f6b26479d82 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -289,6 +289,11 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
289 | struct drm_display_mode *mode; | 289 | struct drm_display_mode *mode; |
290 | struct detailed_pixel_timing *pt = &timing->data.pixel_data; | 290 | struct detailed_pixel_timing *pt = &timing->data.pixel_data; |
291 | 291 | ||
292 | /* ignore tiny modes */ | ||
293 | if (((pt->hactive_hi << 8) | pt->hactive_lo) < 64 || | ||
294 | ((pt->vactive_hi << 8) | pt->hactive_lo) < 64) | ||
295 | return NULL; | ||
296 | |||
292 | if (pt->stereo) { | 297 | if (pt->stereo) { |
293 | printk(KERN_WARNING "stereo mode not supported\n"); | 298 | printk(KERN_WARNING "stereo mode not supported\n"); |
294 | return NULL; | 299 | return NULL; |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 93e677a481f5..fc8e5acd9d9a 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -196,6 +196,7 @@ int drm_irq_install(struct drm_device *dev) | |||
196 | { | 196 | { |
197 | int ret = 0; | 197 | int ret = 0; |
198 | unsigned long sh_flags = 0; | 198 | unsigned long sh_flags = 0; |
199 | char *irqname; | ||
199 | 200 | ||
200 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) | 201 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) |
201 | return -EINVAL; | 202 | return -EINVAL; |
@@ -227,8 +228,13 @@ int drm_irq_install(struct drm_device *dev) | |||
227 | if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) | 228 | if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) |
228 | sh_flags = IRQF_SHARED; | 229 | sh_flags = IRQF_SHARED; |
229 | 230 | ||
231 | if (dev->devname) | ||
232 | irqname = dev->devname; | ||
233 | else | ||
234 | irqname = dev->driver->name; | ||
235 | |||
230 | ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler, | 236 | ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler, |
231 | sh_flags, dev->devname, dev); | 237 | sh_flags, irqname, dev); |
232 | 238 | ||
233 | if (ret < 0) { | 239 | if (ret < 0) { |
234 | mutex_lock(&dev->struct_mutex); | 240 | mutex_lock(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 8f9372921f82..9987ab880835 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -147,7 +147,7 @@ static ssize_t status_show(struct device *device, | |||
147 | enum drm_connector_status status; | 147 | enum drm_connector_status status; |
148 | 148 | ||
149 | status = connector->funcs->detect(connector); | 149 | status = connector->funcs->detect(connector); |
150 | return snprintf(buf, PAGE_SIZE, "%s", | 150 | return snprintf(buf, PAGE_SIZE, "%s\n", |
151 | drm_get_connector_status_name(status)); | 151 | drm_get_connector_status_name(status)); |
152 | } | 152 | } |
153 | 153 | ||
@@ -166,7 +166,7 @@ static ssize_t dpms_show(struct device *device, | |||
166 | if (ret) | 166 | if (ret) |
167 | return 0; | 167 | return 0; |
168 | 168 | ||
169 | return snprintf(buf, PAGE_SIZE, "%s", | 169 | return snprintf(buf, PAGE_SIZE, "%s\n", |
170 | drm_get_dpms_name((int)dpms_status)); | 170 | drm_get_dpms_name((int)dpms_status)); |
171 | } | 171 | } |
172 | 172 | ||
@@ -176,7 +176,7 @@ static ssize_t enabled_show(struct device *device, | |||
176 | { | 176 | { |
177 | struct drm_connector *connector = to_drm_connector(device); | 177 | struct drm_connector *connector = to_drm_connector(device); |
178 | 178 | ||
179 | return snprintf(buf, PAGE_SIZE, connector->encoder ? "enabled" : | 179 | return snprintf(buf, PAGE_SIZE, "%s\n", connector->encoder ? "enabled" : |
180 | "disabled"); | 180 | "disabled"); |
181 | } | 181 | } |
182 | 182 | ||
@@ -317,6 +317,7 @@ static struct device_attribute connector_attrs_opt1[] = { | |||
317 | 317 | ||
318 | static struct bin_attribute edid_attr = { | 318 | static struct bin_attribute edid_attr = { |
319 | .attr.name = "edid", | 319 | .attr.name = "edid", |
320 | .attr.mode = 0444, | ||
320 | .size = 128, | 321 | .size = 128, |
321 | .read = edid_show, | 322 | .read = edid_show, |
322 | }; | 323 | }; |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 53d544552625..0ccb63ee50ee 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -987,12 +987,6 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
987 | int fb_bar = IS_I9XX(dev) ? 2 : 0; | 987 | int fb_bar = IS_I9XX(dev) ? 2 : 0; |
988 | int ret = 0; | 988 | int ret = 0; |
989 | 989 | ||
990 | dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL); | ||
991 | if (!dev->devname) { | ||
992 | ret = -ENOMEM; | ||
993 | goto out; | ||
994 | } | ||
995 | |||
996 | dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) & | 990 | dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) & |
997 | 0xff000000; | 991 | 0xff000000; |
998 | 992 | ||
@@ -1006,7 +1000,7 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1006 | 1000 | ||
1007 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size); | 1001 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size); |
1008 | if (ret) | 1002 | if (ret) |
1009 | goto kfree_devname; | 1003 | goto out; |
1010 | 1004 | ||
1011 | /* Basic memrange allocator for stolen space (aka vram) */ | 1005 | /* Basic memrange allocator for stolen space (aka vram) */ |
1012 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); | 1006 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); |
@@ -1024,7 +1018,7 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1024 | 1018 | ||
1025 | ret = i915_gem_init_ringbuffer(dev); | 1019 | ret = i915_gem_init_ringbuffer(dev); |
1026 | if (ret) | 1020 | if (ret) |
1027 | goto kfree_devname; | 1021 | goto out; |
1028 | 1022 | ||
1029 | /* Allow hardware batchbuffers unless told otherwise. | 1023 | /* Allow hardware batchbuffers unless told otherwise. |
1030 | */ | 1024 | */ |
@@ -1056,8 +1050,6 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1056 | 1050 | ||
1057 | destroy_ringbuffer: | 1051 | destroy_ringbuffer: |
1058 | i915_gem_cleanup_ringbuffer(dev); | 1052 | i915_gem_cleanup_ringbuffer(dev); |
1059 | kfree_devname: | ||
1060 | kfree(dev->devname); | ||
1061 | out: | 1053 | out: |
1062 | return ret; | 1054 | return ret; |
1063 | } | 1055 | } |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9b149fe824c3..c431fa54bbb5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -180,7 +180,8 @@ typedef struct drm_i915_private { | |||
180 | int backlight_duty_cycle; /* restore backlight to this value */ | 180 | int backlight_duty_cycle; /* restore backlight to this value */ |
181 | bool panel_wants_dither; | 181 | bool panel_wants_dither; |
182 | struct drm_display_mode *panel_fixed_mode; | 182 | struct drm_display_mode *panel_fixed_mode; |
183 | struct drm_display_mode *vbt_mode; /* if any */ | 183 | struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */ |
184 | struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */ | ||
184 | 185 | ||
185 | /* Feature bits from the VBIOS */ | 186 | /* Feature bits from the VBIOS */ |
186 | unsigned int int_tv_support:1; | 187 | unsigned int int_tv_support:1; |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b189b49c7602..39f5c658ef5e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -349,7 +349,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
349 | last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; | 349 | last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; |
350 | num_pages = last_data_page - first_data_page + 1; | 350 | num_pages = last_data_page - first_data_page + 1; |
351 | 351 | ||
352 | user_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL); | 352 | user_pages = drm_calloc_large(num_pages, sizeof(struct page *)); |
353 | if (user_pages == NULL) | 353 | if (user_pages == NULL) |
354 | return -ENOMEM; | 354 | return -ENOMEM; |
355 | 355 | ||
@@ -429,7 +429,7 @@ fail_put_user_pages: | |||
429 | SetPageDirty(user_pages[i]); | 429 | SetPageDirty(user_pages[i]); |
430 | page_cache_release(user_pages[i]); | 430 | page_cache_release(user_pages[i]); |
431 | } | 431 | } |
432 | kfree(user_pages); | 432 | drm_free_large(user_pages); |
433 | 433 | ||
434 | return ret; | 434 | return ret; |
435 | } | 435 | } |
@@ -649,7 +649,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
649 | last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; | 649 | last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; |
650 | num_pages = last_data_page - first_data_page + 1; | 650 | num_pages = last_data_page - first_data_page + 1; |
651 | 651 | ||
652 | user_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL); | 652 | user_pages = drm_calloc_large(num_pages, sizeof(struct page *)); |
653 | if (user_pages == NULL) | 653 | if (user_pages == NULL) |
654 | return -ENOMEM; | 654 | return -ENOMEM; |
655 | 655 | ||
@@ -719,7 +719,7 @@ out_unlock: | |||
719 | out_unpin_pages: | 719 | out_unpin_pages: |
720 | for (i = 0; i < pinned_pages; i++) | 720 | for (i = 0; i < pinned_pages; i++) |
721 | page_cache_release(user_pages[i]); | 721 | page_cache_release(user_pages[i]); |
722 | kfree(user_pages); | 722 | drm_free_large(user_pages); |
723 | 723 | ||
724 | return ret; | 724 | return ret; |
725 | } | 725 | } |
@@ -824,7 +824,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
824 | last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; | 824 | last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; |
825 | num_pages = last_data_page - first_data_page + 1; | 825 | num_pages = last_data_page - first_data_page + 1; |
826 | 826 | ||
827 | user_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL); | 827 | user_pages = drm_calloc_large(num_pages, sizeof(struct page *)); |
828 | if (user_pages == NULL) | 828 | if (user_pages == NULL) |
829 | return -ENOMEM; | 829 | return -ENOMEM; |
830 | 830 | ||
@@ -902,7 +902,7 @@ fail_unlock: | |||
902 | fail_put_user_pages: | 902 | fail_put_user_pages: |
903 | for (i = 0; i < pinned_pages; i++) | 903 | for (i = 0; i < pinned_pages; i++) |
904 | page_cache_release(user_pages[i]); | 904 | page_cache_release(user_pages[i]); |
905 | kfree(user_pages); | 905 | drm_free_large(user_pages); |
906 | 906 | ||
907 | return ret; | 907 | return ret; |
908 | } | 908 | } |
@@ -1145,7 +1145,14 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1145 | mutex_unlock(&dev->struct_mutex); | 1145 | mutex_unlock(&dev->struct_mutex); |
1146 | return VM_FAULT_SIGBUS; | 1146 | return VM_FAULT_SIGBUS; |
1147 | } | 1147 | } |
1148 | list_add(&obj_priv->list, &dev_priv->mm.inactive_list); | 1148 | |
1149 | ret = i915_gem_object_set_to_gtt_domain(obj, write); | ||
1150 | if (ret) { | ||
1151 | mutex_unlock(&dev->struct_mutex); | ||
1152 | return VM_FAULT_SIGBUS; | ||
1153 | } | ||
1154 | |||
1155 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
1149 | } | 1156 | } |
1150 | 1157 | ||
1151 | /* Need a new fence register? */ | 1158 | /* Need a new fence register? */ |
@@ -1375,7 +1382,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
1375 | mutex_unlock(&dev->struct_mutex); | 1382 | mutex_unlock(&dev->struct_mutex); |
1376 | return ret; | 1383 | return ret; |
1377 | } | 1384 | } |
1378 | list_add(&obj_priv->list, &dev_priv->mm.inactive_list); | 1385 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); |
1379 | } | 1386 | } |
1380 | 1387 | ||
1381 | drm_gem_object_unreference(obj); | 1388 | drm_gem_object_unreference(obj); |
@@ -1408,9 +1415,7 @@ i915_gem_object_put_pages(struct drm_gem_object *obj) | |||
1408 | } | 1415 | } |
1409 | obj_priv->dirty = 0; | 1416 | obj_priv->dirty = 0; |
1410 | 1417 | ||
1411 | drm_free(obj_priv->pages, | 1418 | drm_free_large(obj_priv->pages); |
1412 | page_count * sizeof(struct page *), | ||
1413 | DRM_MEM_DRIVER); | ||
1414 | obj_priv->pages = NULL; | 1419 | obj_priv->pages = NULL; |
1415 | } | 1420 | } |
1416 | 1421 | ||
@@ -2024,8 +2029,7 @@ i915_gem_object_get_pages(struct drm_gem_object *obj) | |||
2024 | */ | 2029 | */ |
2025 | page_count = obj->size / PAGE_SIZE; | 2030 | page_count = obj->size / PAGE_SIZE; |
2026 | BUG_ON(obj_priv->pages != NULL); | 2031 | BUG_ON(obj_priv->pages != NULL); |
2027 | obj_priv->pages = drm_calloc(page_count, sizeof(struct page *), | 2032 | obj_priv->pages = drm_calloc_large(page_count, sizeof(struct page *)); |
2028 | DRM_MEM_DRIVER); | ||
2029 | if (obj_priv->pages == NULL) { | 2033 | if (obj_priv->pages == NULL) { |
2030 | DRM_ERROR("Faled to allocate page list\n"); | 2034 | DRM_ERROR("Faled to allocate page list\n"); |
2031 | obj_priv->pages_refcount--; | 2035 | obj_priv->pages_refcount--; |
@@ -2131,8 +2135,10 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) | |||
2131 | return; | 2135 | return; |
2132 | } | 2136 | } |
2133 | 2137 | ||
2134 | pitch_val = (obj_priv->stride / 128) - 1; | 2138 | pitch_val = obj_priv->stride / 128; |
2135 | WARN_ON(pitch_val & ~0x0000000f); | 2139 | pitch_val = ffs(pitch_val) - 1; |
2140 | WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); | ||
2141 | |||
2136 | val = obj_priv->gtt_offset; | 2142 | val = obj_priv->gtt_offset; |
2137 | if (obj_priv->tiling_mode == I915_TILING_Y) | 2143 | if (obj_priv->tiling_mode == I915_TILING_Y) |
2138 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; | 2144 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; |
@@ -2254,9 +2260,6 @@ try_again: | |||
2254 | goto try_again; | 2260 | goto try_again; |
2255 | } | 2261 | } |
2256 | 2262 | ||
2257 | BUG_ON(old_obj_priv->active || | ||
2258 | (reg->obj->write_domain & I915_GEM_GPU_DOMAINS)); | ||
2259 | |||
2260 | /* | 2263 | /* |
2261 | * Zap this virtual mapping so we can set up a fence again | 2264 | * Zap this virtual mapping so we can set up a fence again |
2262 | * for this object next time we need it. | 2265 | * for this object next time we need it. |
@@ -2424,6 +2427,16 @@ i915_gem_clflush_object(struct drm_gem_object *obj) | |||
2424 | if (obj_priv->pages == NULL) | 2427 | if (obj_priv->pages == NULL) |
2425 | return; | 2428 | return; |
2426 | 2429 | ||
2430 | /* XXX: The 865 in particular appears to be weird in how it handles | ||
2431 | * cache flushing. We haven't figured it out, but the | ||
2432 | * clflush+agp_chipset_flush doesn't appear to successfully get the | ||
2433 | * data visible to the PGU, while wbinvd + agp_chipset_flush does. | ||
2434 | */ | ||
2435 | if (IS_I865G(obj->dev)) { | ||
2436 | wbinvd(); | ||
2437 | return; | ||
2438 | } | ||
2439 | |||
2427 | drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE); | 2440 | drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE); |
2428 | } | 2441 | } |
2429 | 2442 | ||
@@ -3111,7 +3124,7 @@ i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list, | |||
3111 | reloc_count += exec_list[i].relocation_count; | 3124 | reloc_count += exec_list[i].relocation_count; |
3112 | } | 3125 | } |
3113 | 3126 | ||
3114 | *relocs = drm_calloc(reloc_count, sizeof(**relocs), DRM_MEM_DRIVER); | 3127 | *relocs = drm_calloc_large(reloc_count, sizeof(**relocs)); |
3115 | if (*relocs == NULL) | 3128 | if (*relocs == NULL) |
3116 | return -ENOMEM; | 3129 | return -ENOMEM; |
3117 | 3130 | ||
@@ -3125,8 +3138,7 @@ i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list, | |||
3125 | exec_list[i].relocation_count * | 3138 | exec_list[i].relocation_count * |
3126 | sizeof(**relocs)); | 3139 | sizeof(**relocs)); |
3127 | if (ret != 0) { | 3140 | if (ret != 0) { |
3128 | drm_free(*relocs, reloc_count * sizeof(**relocs), | 3141 | drm_free_large(*relocs); |
3129 | DRM_MEM_DRIVER); | ||
3130 | *relocs = NULL; | 3142 | *relocs = NULL; |
3131 | return -EFAULT; | 3143 | return -EFAULT; |
3132 | } | 3144 | } |
@@ -3165,7 +3177,7 @@ i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object *exec_list, | |||
3165 | } | 3177 | } |
3166 | 3178 | ||
3167 | err: | 3179 | err: |
3168 | drm_free(relocs, reloc_count * sizeof(*relocs), DRM_MEM_DRIVER); | 3180 | drm_free_large(relocs); |
3169 | 3181 | ||
3170 | return ret; | 3182 | return ret; |
3171 | } | 3183 | } |
@@ -3198,10 +3210,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
3198 | return -EINVAL; | 3210 | return -EINVAL; |
3199 | } | 3211 | } |
3200 | /* Copy in the exec list from userland */ | 3212 | /* Copy in the exec list from userland */ |
3201 | exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count, | 3213 | exec_list = drm_calloc_large(sizeof(*exec_list), args->buffer_count); |
3202 | DRM_MEM_DRIVER); | 3214 | object_list = drm_calloc_large(sizeof(*object_list), args->buffer_count); |
3203 | object_list = drm_calloc(sizeof(*object_list), args->buffer_count, | ||
3204 | DRM_MEM_DRIVER); | ||
3205 | if (exec_list == NULL || object_list == NULL) { | 3215 | if (exec_list == NULL || object_list == NULL) { |
3206 | DRM_ERROR("Failed to allocate exec or object list " | 3216 | DRM_ERROR("Failed to allocate exec or object list " |
3207 | "for %d buffers\n", | 3217 | "for %d buffers\n", |
@@ -3462,10 +3472,8 @@ err: | |||
3462 | } | 3472 | } |
3463 | 3473 | ||
3464 | pre_mutex_err: | 3474 | pre_mutex_err: |
3465 | drm_free(object_list, sizeof(*object_list) * args->buffer_count, | 3475 | drm_free_large(object_list); |
3466 | DRM_MEM_DRIVER); | 3476 | drm_free_large(exec_list); |
3467 | drm_free(exec_list, sizeof(*exec_list) * args->buffer_count, | ||
3468 | DRM_MEM_DRIVER); | ||
3469 | drm_free(cliprects, sizeof(*cliprects) * args->num_cliprects, | 3477 | drm_free(cliprects, sizeof(*cliprects) * args->num_cliprects, |
3470 | DRM_MEM_DRIVER); | 3478 | DRM_MEM_DRIVER); |
3471 | 3479 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 52a059354e83..540dd336e6ec 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -213,7 +213,8 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) | |||
213 | if (tiling_mode == I915_TILING_NONE) | 213 | if (tiling_mode == I915_TILING_NONE) |
214 | return true; | 214 | return true; |
215 | 215 | ||
216 | if (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) | 216 | if (!IS_I9XX(dev) || |
217 | (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) | ||
217 | tile_width = 128; | 218 | tile_width = 128; |
218 | else | 219 | else |
219 | tile_width = 512; | 220 | tile_width = 512; |
@@ -225,11 +226,18 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) | |||
225 | if (stride / 128 > I965_FENCE_MAX_PITCH_VAL) | 226 | if (stride / 128 > I965_FENCE_MAX_PITCH_VAL) |
226 | return false; | 227 | return false; |
227 | } else if (IS_I9XX(dev)) { | 228 | } else if (IS_I9XX(dev)) { |
228 | if (stride / tile_width > I830_FENCE_MAX_PITCH_VAL || | 229 | uint32_t pitch_val = ffs(stride / tile_width) - 1; |
230 | |||
231 | /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB) | ||
232 | * instead of 4 (2KB) on 945s. | ||
233 | */ | ||
234 | if (pitch_val > I915_FENCE_MAX_PITCH_VAL || | ||
229 | size > (I830_FENCE_MAX_SIZE_VAL << 20)) | 235 | size > (I830_FENCE_MAX_SIZE_VAL << 20)) |
230 | return false; | 236 | return false; |
231 | } else { | 237 | } else { |
232 | if (stride / 128 > I830_FENCE_MAX_PITCH_VAL || | 238 | uint32_t pitch_val = ffs(stride / tile_width) - 1; |
239 | |||
240 | if (pitch_val > I830_FENCE_MAX_PITCH_VAL || | ||
233 | size > (I830_FENCE_MAX_SIZE_VAL << 19)) | 241 | size > (I830_FENCE_MAX_SIZE_VAL << 19)) |
234 | return false; | 242 | return false; |
235 | } | 243 | } |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 15da44cf21b1..375569d01d01 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -190,7 +190,8 @@ | |||
190 | #define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) | 190 | #define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) |
191 | #define I830_FENCE_PITCH_SHIFT 4 | 191 | #define I830_FENCE_PITCH_SHIFT 4 |
192 | #define I830_FENCE_REG_VALID (1<<0) | 192 | #define I830_FENCE_REG_VALID (1<<0) |
193 | #define I830_FENCE_MAX_PITCH_VAL 0x10 | 193 | #define I915_FENCE_MAX_PITCH_VAL 0x10 |
194 | #define I830_FENCE_MAX_PITCH_VAL 6 | ||
194 | #define I830_FENCE_MAX_SIZE_VAL (1<<8) | 195 | #define I830_FENCE_MAX_SIZE_VAL (1<<8) |
195 | 196 | ||
196 | #define I915_FENCE_START_MASK 0x0ff00000 | 197 | #define I915_FENCE_START_MASK 0x0ff00000 |
@@ -1410,9 +1411,25 @@ | |||
1410 | 1411 | ||
1411 | /* Cursor A & B regs */ | 1412 | /* Cursor A & B regs */ |
1412 | #define CURACNTR 0x70080 | 1413 | #define CURACNTR 0x70080 |
1414 | /* Old style CUR*CNTR flags (desktop 8xx) */ | ||
1415 | #define CURSOR_ENABLE 0x80000000 | ||
1416 | #define CURSOR_GAMMA_ENABLE 0x40000000 | ||
1417 | #define CURSOR_STRIDE_MASK 0x30000000 | ||
1418 | #define CURSOR_FORMAT_SHIFT 24 | ||
1419 | #define CURSOR_FORMAT_MASK (0x07 << CURSOR_FORMAT_SHIFT) | ||
1420 | #define CURSOR_FORMAT_2C (0x00 << CURSOR_FORMAT_SHIFT) | ||
1421 | #define CURSOR_FORMAT_3C (0x01 << CURSOR_FORMAT_SHIFT) | ||
1422 | #define CURSOR_FORMAT_4C (0x02 << CURSOR_FORMAT_SHIFT) | ||
1423 | #define CURSOR_FORMAT_ARGB (0x04 << CURSOR_FORMAT_SHIFT) | ||
1424 | #define CURSOR_FORMAT_XRGB (0x05 << CURSOR_FORMAT_SHIFT) | ||
1425 | /* New style CUR*CNTR flags */ | ||
1426 | #define CURSOR_MODE 0x27 | ||
1413 | #define CURSOR_MODE_DISABLE 0x00 | 1427 | #define CURSOR_MODE_DISABLE 0x00 |
1414 | #define CURSOR_MODE_64_32B_AX 0x07 | 1428 | #define CURSOR_MODE_64_32B_AX 0x07 |
1415 | #define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) | 1429 | #define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) |
1430 | #define MCURSOR_PIPE_SELECT (1 << 28) | ||
1431 | #define MCURSOR_PIPE_A 0x00 | ||
1432 | #define MCURSOR_PIPE_B (1 << 28) | ||
1416 | #define MCURSOR_GAMMA_ENABLE (1 << 26) | 1433 | #define MCURSOR_GAMMA_ENABLE (1 << 26) |
1417 | #define CURABASE 0x70084 | 1434 | #define CURABASE 0x70084 |
1418 | #define CURAPOS 0x70088 | 1435 | #define CURAPOS 0x70088 |
@@ -1420,6 +1437,7 @@ | |||
1420 | #define CURSOR_POS_SIGN 0x8000 | 1437 | #define CURSOR_POS_SIGN 0x8000 |
1421 | #define CURSOR_X_SHIFT 0 | 1438 | #define CURSOR_X_SHIFT 0 |
1422 | #define CURSOR_Y_SHIFT 16 | 1439 | #define CURSOR_Y_SHIFT 16 |
1440 | #define CURSIZE 0x700a0 | ||
1423 | #define CURBCNTR 0x700c0 | 1441 | #define CURBCNTR 0x700c0 |
1424 | #define CURBBASE 0x700c4 | 1442 | #define CURBBASE 0x700c4 |
1425 | #define CURBPOS 0x700c8 | 1443 | #define CURBPOS 0x700c8 |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index fc28e2bbd542..9d78cff33b24 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -57,9 +57,43 @@ find_section(struct bdb_header *bdb, int section_id) | |||
57 | return NULL; | 57 | return NULL; |
58 | } | 58 | } |
59 | 59 | ||
60 | /* Try to find panel data */ | ||
61 | static void | 60 | static void |
62 | parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb) | 61 | fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, |
62 | struct lvds_dvo_timing *dvo_timing) | ||
63 | { | ||
64 | panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) | | ||
65 | dvo_timing->hactive_lo; | ||
66 | panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay + | ||
67 | ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo); | ||
68 | panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start + | ||
69 | dvo_timing->hsync_pulse_width; | ||
70 | panel_fixed_mode->htotal = panel_fixed_mode->hdisplay + | ||
71 | ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo); | ||
72 | |||
73 | panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) | | ||
74 | dvo_timing->vactive_lo; | ||
75 | panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay + | ||
76 | dvo_timing->vsync_off; | ||
77 | panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start + | ||
78 | dvo_timing->vsync_pulse_width; | ||
79 | panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay + | ||
80 | ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo); | ||
81 | panel_fixed_mode->clock = dvo_timing->clock * 10; | ||
82 | panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; | ||
83 | |||
84 | /* Some VBTs have bogus h/vtotal values */ | ||
85 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) | ||
86 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; | ||
87 | if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal) | ||
88 | panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1; | ||
89 | |||
90 | drm_mode_set_name(panel_fixed_mode); | ||
91 | } | ||
92 | |||
93 | /* Try to find integrated panel data */ | ||
94 | static void | ||
95 | parse_lfp_panel_data(struct drm_i915_private *dev_priv, | ||
96 | struct bdb_header *bdb) | ||
63 | { | 97 | { |
64 | struct bdb_lvds_options *lvds_options; | 98 | struct bdb_lvds_options *lvds_options; |
65 | struct bdb_lvds_lfp_data *lvds_lfp_data; | 99 | struct bdb_lvds_lfp_data *lvds_lfp_data; |
@@ -91,38 +125,45 @@ parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb) | |||
91 | panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode), | 125 | panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode), |
92 | DRM_MEM_DRIVER); | 126 | DRM_MEM_DRIVER); |
93 | 127 | ||
94 | panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) | | 128 | fill_detail_timing_data(panel_fixed_mode, dvo_timing); |
95 | dvo_timing->hactive_lo; | ||
96 | panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay + | ||
97 | ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo); | ||
98 | panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start + | ||
99 | dvo_timing->hsync_pulse_width; | ||
100 | panel_fixed_mode->htotal = panel_fixed_mode->hdisplay + | ||
101 | ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo); | ||
102 | 129 | ||
103 | panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) | | 130 | dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode; |
104 | dvo_timing->vactive_lo; | ||
105 | panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay + | ||
106 | dvo_timing->vsync_off; | ||
107 | panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start + | ||
108 | dvo_timing->vsync_pulse_width; | ||
109 | panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay + | ||
110 | ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo); | ||
111 | panel_fixed_mode->clock = dvo_timing->clock * 10; | ||
112 | panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; | ||
113 | 131 | ||
114 | /* Some VBTs have bogus h/vtotal values */ | 132 | DRM_DEBUG("Found panel mode in BIOS VBT tables:\n"); |
115 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) | 133 | drm_mode_debug_printmodeline(panel_fixed_mode); |
116 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; | ||
117 | if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal) | ||
118 | panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1; | ||
119 | 134 | ||
120 | drm_mode_set_name(panel_fixed_mode); | 135 | return; |
136 | } | ||
137 | |||
138 | /* Try to find sdvo panel data */ | ||
139 | static void | ||
140 | parse_sdvo_panel_data(struct drm_i915_private *dev_priv, | ||
141 | struct bdb_header *bdb) | ||
142 | { | ||
143 | struct bdb_sdvo_lvds_options *sdvo_lvds_options; | ||
144 | struct lvds_dvo_timing *dvo_timing; | ||
145 | struct drm_display_mode *panel_fixed_mode; | ||
121 | 146 | ||
122 | dev_priv->vbt_mode = panel_fixed_mode; | 147 | dev_priv->sdvo_lvds_vbt_mode = NULL; |
123 | 148 | ||
124 | DRM_DEBUG("Found panel mode in BIOS VBT tables:\n"); | 149 | sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS); |
125 | drm_mode_debug_printmodeline(panel_fixed_mode); | 150 | if (!sdvo_lvds_options) |
151 | return; | ||
152 | |||
153 | dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS); | ||
154 | if (!dvo_timing) | ||
155 | return; | ||
156 | |||
157 | panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode), | ||
158 | DRM_MEM_DRIVER); | ||
159 | |||
160 | if (!panel_fixed_mode) | ||
161 | return; | ||
162 | |||
163 | fill_detail_timing_data(panel_fixed_mode, | ||
164 | dvo_timing + sdvo_lvds_options->panel_type); | ||
165 | |||
166 | dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode; | ||
126 | 167 | ||
127 | return; | 168 | return; |
128 | } | 169 | } |
@@ -199,7 +240,8 @@ intel_init_bios(struct drm_device *dev) | |||
199 | 240 | ||
200 | /* Grab useful general definitions */ | 241 | /* Grab useful general definitions */ |
201 | parse_general_features(dev_priv, bdb); | 242 | parse_general_features(dev_priv, bdb); |
202 | parse_panel_data(dev_priv, bdb); | 243 | parse_lfp_panel_data(dev_priv, bdb); |
244 | parse_sdvo_panel_data(dev_priv, bdb); | ||
203 | 245 | ||
204 | pci_unmap_rom(pdev, bios); | 246 | pci_unmap_rom(pdev, bios); |
205 | 247 | ||
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index de621aad85b5..8ca2cde15804 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h | |||
@@ -279,6 +279,23 @@ struct vch_bdb_22 { | |||
279 | struct vch_panel_data panels[16]; | 279 | struct vch_panel_data panels[16]; |
280 | } __attribute__((packed)); | 280 | } __attribute__((packed)); |
281 | 281 | ||
282 | struct bdb_sdvo_lvds_options { | ||
283 | u8 panel_backlight; | ||
284 | u8 h40_set_panel_type; | ||
285 | u8 panel_type; | ||
286 | u8 ssc_clk_freq; | ||
287 | u16 als_low_trip; | ||
288 | u16 als_high_trip; | ||
289 | u8 sclalarcoeff_tab_row_num; | ||
290 | u8 sclalarcoeff_tab_row_size; | ||
291 | u8 coefficient[8]; | ||
292 | u8 panel_misc_bits_1; | ||
293 | u8 panel_misc_bits_2; | ||
294 | u8 panel_misc_bits_3; | ||
295 | u8 panel_misc_bits_4; | ||
296 | } __attribute__((packed)); | ||
297 | |||
298 | |||
282 | bool intel_init_bios(struct drm_device *dev); | 299 | bool intel_init_bios(struct drm_device *dev); |
283 | 300 | ||
284 | /* | 301 | /* |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 19148c3df637..79acc4f4c1f8 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -198,9 +198,142 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector) | |||
198 | return intel_ddc_probe(intel_output); | 198 | return intel_ddc_probe(intel_output); |
199 | } | 199 | } |
200 | 200 | ||
201 | static enum drm_connector_status | ||
202 | intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output) | ||
203 | { | ||
204 | struct drm_encoder *encoder = &intel_output->enc; | ||
205 | struct drm_device *dev = encoder->dev; | ||
206 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
207 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
208 | uint32_t pipe = intel_crtc->pipe; | ||
209 | uint32_t save_bclrpat; | ||
210 | uint32_t save_vtotal; | ||
211 | uint32_t vtotal, vactive; | ||
212 | uint32_t vsample; | ||
213 | uint32_t vblank, vblank_start, vblank_end; | ||
214 | uint32_t dsl; | ||
215 | uint32_t bclrpat_reg; | ||
216 | uint32_t vtotal_reg; | ||
217 | uint32_t vblank_reg; | ||
218 | uint32_t vsync_reg; | ||
219 | uint32_t pipeconf_reg; | ||
220 | uint32_t pipe_dsl_reg; | ||
221 | uint8_t st00; | ||
222 | enum drm_connector_status status; | ||
223 | |||
224 | if (pipe == 0) { | ||
225 | bclrpat_reg = BCLRPAT_A; | ||
226 | vtotal_reg = VTOTAL_A; | ||
227 | vblank_reg = VBLANK_A; | ||
228 | vsync_reg = VSYNC_A; | ||
229 | pipeconf_reg = PIPEACONF; | ||
230 | pipe_dsl_reg = PIPEADSL; | ||
231 | } else { | ||
232 | bclrpat_reg = BCLRPAT_B; | ||
233 | vtotal_reg = VTOTAL_B; | ||
234 | vblank_reg = VBLANK_B; | ||
235 | vsync_reg = VSYNC_B; | ||
236 | pipeconf_reg = PIPEBCONF; | ||
237 | pipe_dsl_reg = PIPEBDSL; | ||
238 | } | ||
239 | |||
240 | save_bclrpat = I915_READ(bclrpat_reg); | ||
241 | save_vtotal = I915_READ(vtotal_reg); | ||
242 | vblank = I915_READ(vblank_reg); | ||
243 | |||
244 | vtotal = ((save_vtotal >> 16) & 0xfff) + 1; | ||
245 | vactive = (save_vtotal & 0x7ff) + 1; | ||
246 | |||
247 | vblank_start = (vblank & 0xfff) + 1; | ||
248 | vblank_end = ((vblank >> 16) & 0xfff) + 1; | ||
249 | |||
250 | /* Set the border color to purple. */ | ||
251 | I915_WRITE(bclrpat_reg, 0x500050); | ||
252 | |||
253 | if (IS_I9XX(dev)) { | ||
254 | uint32_t pipeconf = I915_READ(pipeconf_reg); | ||
255 | I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); | ||
256 | /* Wait for next Vblank to substitue | ||
257 | * border color for Color info */ | ||
258 | intel_wait_for_vblank(dev); | ||
259 | st00 = I915_READ8(VGA_MSR_WRITE); | ||
260 | status = ((st00 & (1 << 4)) != 0) ? | ||
261 | connector_status_connected : | ||
262 | connector_status_disconnected; | ||
263 | |||
264 | I915_WRITE(pipeconf_reg, pipeconf); | ||
265 | } else { | ||
266 | bool restore_vblank = false; | ||
267 | int count, detect; | ||
268 | |||
269 | /* | ||
270 | * If there isn't any border, add some. | ||
271 | * Yes, this will flicker | ||
272 | */ | ||
273 | if (vblank_start <= vactive && vblank_end >= vtotal) { | ||
274 | uint32_t vsync = I915_READ(vsync_reg); | ||
275 | uint32_t vsync_start = (vsync & 0xffff) + 1; | ||
276 | |||
277 | vblank_start = vsync_start; | ||
278 | I915_WRITE(vblank_reg, | ||
279 | (vblank_start - 1) | | ||
280 | ((vblank_end - 1) << 16)); | ||
281 | restore_vblank = true; | ||
282 | } | ||
283 | /* sample in the vertical border, selecting the larger one */ | ||
284 | if (vblank_start - vactive >= vtotal - vblank_end) | ||
285 | vsample = (vblank_start + vactive) >> 1; | ||
286 | else | ||
287 | vsample = (vtotal + vblank_end) >> 1; | ||
288 | |||
289 | /* | ||
290 | * Wait for the border to be displayed | ||
291 | */ | ||
292 | while (I915_READ(pipe_dsl_reg) >= vactive) | ||
293 | ; | ||
294 | while ((dsl = I915_READ(pipe_dsl_reg)) <= vsample) | ||
295 | ; | ||
296 | /* | ||
297 | * Watch ST00 for an entire scanline | ||
298 | */ | ||
299 | detect = 0; | ||
300 | count = 0; | ||
301 | do { | ||
302 | count++; | ||
303 | /* Read the ST00 VGA status register */ | ||
304 | st00 = I915_READ8(VGA_MSR_WRITE); | ||
305 | if (st00 & (1 << 4)) | ||
306 | detect++; | ||
307 | } while ((I915_READ(pipe_dsl_reg) == dsl)); | ||
308 | |||
309 | /* restore vblank if necessary */ | ||
310 | if (restore_vblank) | ||
311 | I915_WRITE(vblank_reg, vblank); | ||
312 | /* | ||
313 | * If more than 3/4 of the scanline detected a monitor, | ||
314 | * then it is assumed to be present. This works even on i830, | ||
315 | * where there isn't any way to force the border color across | ||
316 | * the screen | ||
317 | */ | ||
318 | status = detect * 4 > count * 3 ? | ||
319 | connector_status_connected : | ||
320 | connector_status_disconnected; | ||
321 | } | ||
322 | |||
323 | /* Restore previous settings */ | ||
324 | I915_WRITE(bclrpat_reg, save_bclrpat); | ||
325 | |||
326 | return status; | ||
327 | } | ||
328 | |||
201 | static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) | 329 | static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) |
202 | { | 330 | { |
203 | struct drm_device *dev = connector->dev; | 331 | struct drm_device *dev = connector->dev; |
332 | struct intel_output *intel_output = to_intel_output(connector); | ||
333 | struct drm_encoder *encoder = &intel_output->enc; | ||
334 | struct drm_crtc *crtc; | ||
335 | int dpms_mode; | ||
336 | enum drm_connector_status status; | ||
204 | 337 | ||
205 | if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { | 338 | if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) { |
206 | if (intel_crt_detect_hotplug(connector)) | 339 | if (intel_crt_detect_hotplug(connector)) |
@@ -212,8 +345,20 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto | |||
212 | if (intel_crt_detect_ddc(connector)) | 345 | if (intel_crt_detect_ddc(connector)) |
213 | return connector_status_connected; | 346 | return connector_status_connected; |
214 | 347 | ||
215 | /* TODO use load detect */ | 348 | /* for pre-945g platforms use load detect */ |
216 | return connector_status_unknown; | 349 | if (encoder->crtc && encoder->crtc->enabled) { |
350 | status = intel_crt_load_detect(encoder->crtc, intel_output); | ||
351 | } else { | ||
352 | crtc = intel_get_load_detect_pipe(intel_output, | ||
353 | NULL, &dpms_mode); | ||
354 | if (crtc) { | ||
355 | status = intel_crt_load_detect(crtc, intel_output); | ||
356 | intel_release_load_detect_pipe(intel_output, dpms_mode); | ||
357 | } else | ||
358 | status = connector_status_unknown; | ||
359 | } | ||
360 | |||
361 | return status; | ||
217 | } | 362 | } |
218 | 363 | ||
219 | static void intel_crt_destroy(struct drm_connector *connector) | 364 | static void intel_crt_destroy(struct drm_connector *connector) |
@@ -236,11 +381,6 @@ static int intel_crt_set_property(struct drm_connector *connector, | |||
236 | struct drm_property *property, | 381 | struct drm_property *property, |
237 | uint64_t value) | 382 | uint64_t value) |
238 | { | 383 | { |
239 | struct drm_device *dev = connector->dev; | ||
240 | |||
241 | if (property == dev->mode_config.dpms_property && connector->encoder) | ||
242 | intel_crt_dpms(connector->encoder, (uint32_t)(value & 0xf)); | ||
243 | |||
244 | return 0; | 384 | return 0; |
245 | } | 385 | } |
246 | 386 | ||
@@ -257,6 +397,7 @@ static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = { | |||
257 | }; | 397 | }; |
258 | 398 | ||
259 | static const struct drm_connector_funcs intel_crt_connector_funcs = { | 399 | static const struct drm_connector_funcs intel_crt_connector_funcs = { |
400 | .dpms = drm_helper_connector_dpms, | ||
260 | .detect = intel_crt_detect, | 401 | .detect = intel_crt_detect, |
261 | .fill_modes = drm_helper_probe_single_connector_modes, | 402 | .fill_modes = drm_helper_probe_single_connector_modes, |
262 | .destroy = intel_crt_destroy, | 403 | .destroy = intel_crt_destroy, |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3387cf32f385..c9d6f10ba92e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1357,7 +1357,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
1357 | int pipe = intel_crtc->pipe; | 1357 | int pipe = intel_crtc->pipe; |
1358 | uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; | 1358 | uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; |
1359 | uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; | 1359 | uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; |
1360 | uint32_t temp; | 1360 | uint32_t temp = I915_READ(control); |
1361 | size_t addr; | 1361 | size_t addr; |
1362 | int ret; | 1362 | int ret; |
1363 | 1363 | ||
@@ -1366,7 +1366,12 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
1366 | /* if we want to turn off the cursor ignore width and height */ | 1366 | /* if we want to turn off the cursor ignore width and height */ |
1367 | if (!handle) { | 1367 | if (!handle) { |
1368 | DRM_DEBUG("cursor off\n"); | 1368 | DRM_DEBUG("cursor off\n"); |
1369 | temp = CURSOR_MODE_DISABLE; | 1369 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { |
1370 | temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | ||
1371 | temp |= CURSOR_MODE_DISABLE; | ||
1372 | } else { | ||
1373 | temp &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); | ||
1374 | } | ||
1370 | addr = 0; | 1375 | addr = 0; |
1371 | bo = NULL; | 1376 | bo = NULL; |
1372 | mutex_lock(&dev->struct_mutex); | 1377 | mutex_lock(&dev->struct_mutex); |
@@ -1409,10 +1414,19 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
1409 | addr = obj_priv->phys_obj->handle->busaddr; | 1414 | addr = obj_priv->phys_obj->handle->busaddr; |
1410 | } | 1415 | } |
1411 | 1416 | ||
1412 | temp = 0; | 1417 | if (!IS_I9XX(dev)) |
1413 | /* set the pipe for the cursor */ | 1418 | I915_WRITE(CURSIZE, (height << 12) | width); |
1414 | temp |= (pipe << 28); | 1419 | |
1415 | temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | 1420 | /* Hooray for CUR*CNTR differences */ |
1421 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
1422 | temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); | ||
1423 | temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | ||
1424 | temp |= (pipe << 28); /* Connect to correct pipe */ | ||
1425 | } else { | ||
1426 | temp &= ~(CURSOR_FORMAT_MASK); | ||
1427 | temp |= CURSOR_ENABLE; | ||
1428 | temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; | ||
1429 | } | ||
1416 | 1430 | ||
1417 | finish: | 1431 | finish: |
1418 | I915_WRITE(control, temp); | 1432 | I915_WRITE(control, temp); |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 8b8d6e65cd3f..1ee3007d6ec0 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -316,6 +316,7 @@ static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { | |||
316 | }; | 316 | }; |
317 | 317 | ||
318 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { | 318 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { |
319 | .dpms = drm_helper_connector_dpms, | ||
319 | .save = intel_dvo_save, | 320 | .save = intel_dvo_save, |
320 | .restore = intel_dvo_restore, | 321 | .restore = intel_dvo_restore, |
321 | .detect = intel_dvo_detect, | 322 | .detect = intel_dvo_detect, |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index d0983bb93a18..7d6bdd705326 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -219,6 +219,7 @@ static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { | |||
219 | }; | 219 | }; |
220 | 220 | ||
221 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { | 221 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { |
222 | .dpms = drm_helper_connector_dpms, | ||
222 | .save = intel_hdmi_save, | 223 | .save = intel_hdmi_save, |
223 | .restore = intel_hdmi_restore, | 224 | .restore = intel_hdmi_restore, |
224 | .detect = intel_hdmi_detect, | 225 | .detect = intel_hdmi_detect, |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 439a86514993..53cccfa58b95 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -343,11 +343,6 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
343 | struct drm_property *property, | 343 | struct drm_property *property, |
344 | uint64_t value) | 344 | uint64_t value) |
345 | { | 345 | { |
346 | struct drm_device *dev = connector->dev; | ||
347 | |||
348 | if (property == dev->mode_config.dpms_property && connector->encoder) | ||
349 | intel_lvds_dpms(connector->encoder, (uint32_t)(value & 0xf)); | ||
350 | |||
351 | return 0; | 346 | return 0; |
352 | } | 347 | } |
353 | 348 | ||
@@ -366,6 +361,7 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs | |||
366 | }; | 361 | }; |
367 | 362 | ||
368 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { | 363 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { |
364 | .dpms = drm_helper_connector_dpms, | ||
369 | .save = intel_lvds_save, | 365 | .save = intel_lvds_save, |
370 | .restore = intel_lvds_restore, | 366 | .restore = intel_lvds_restore, |
371 | .detect = intel_lvds_detect, | 367 | .detect = intel_lvds_detect, |
@@ -391,7 +387,7 @@ static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) | |||
391 | } | 387 | } |
392 | 388 | ||
393 | /* These systems claim to have LVDS, but really don't */ | 389 | /* These systems claim to have LVDS, but really don't */ |
394 | static const struct dmi_system_id __initdata intel_no_lvds[] = { | 390 | static const struct dmi_system_id intel_no_lvds[] = { |
395 | { | 391 | { |
396 | .callback = intel_no_lvds_dmi_callback, | 392 | .callback = intel_no_lvds_dmi_callback, |
397 | .ident = "Apple Mac Mini (Core series)", | 393 | .ident = "Apple Mac Mini (Core series)", |
@@ -511,10 +507,10 @@ void intel_lvds_init(struct drm_device *dev) | |||
511 | } | 507 | } |
512 | 508 | ||
513 | /* Failed to get EDID, what about VBT? */ | 509 | /* Failed to get EDID, what about VBT? */ |
514 | if (dev_priv->vbt_mode) { | 510 | if (dev_priv->lfp_lvds_vbt_mode) { |
515 | mutex_lock(&dev->mode_config.mutex); | 511 | mutex_lock(&dev->mode_config.mutex); |
516 | dev_priv->panel_fixed_mode = | 512 | dev_priv->panel_fixed_mode = |
517 | drm_mode_duplicate(dev, dev_priv->vbt_mode); | 513 | drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); |
518 | mutex_unlock(&dev->mode_config.mutex); | 514 | mutex_unlock(&dev->mode_config.mutex); |
519 | if (dev_priv->panel_fixed_mode) { | 515 | if (dev_priv->panel_fixed_mode) { |
520 | dev_priv->panel_fixed_mode->type |= | 516 | dev_priv->panel_fixed_mode->type |= |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 9913651c1e17..3093b4d4a4dd 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -69,6 +69,10 @@ struct intel_sdvo_priv { | |||
69 | * This is set if we treat the device as HDMI, instead of DVI. | 69 | * This is set if we treat the device as HDMI, instead of DVI. |
70 | */ | 70 | */ |
71 | bool is_hdmi; | 71 | bool is_hdmi; |
72 | /** | ||
73 | * This is set if we detect output of sdvo device as LVDS. | ||
74 | */ | ||
75 | bool is_lvds; | ||
72 | 76 | ||
73 | /** | 77 | /** |
74 | * Returned SDTV resolutions allowed for the current format, if the | 78 | * Returned SDTV resolutions allowed for the current format, if the |
@@ -1398,10 +1402,8 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1398 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1402 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
1399 | { | 1403 | { |
1400 | struct intel_output *intel_output = to_intel_output(connector); | 1404 | struct intel_output *intel_output = to_intel_output(connector); |
1401 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1402 | 1405 | ||
1403 | /* set the bus switch and get the modes */ | 1406 | /* set the bus switch and get the modes */ |
1404 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1405 | intel_ddc_get_modes(intel_output); | 1407 | intel_ddc_get_modes(intel_output); |
1406 | 1408 | ||
1407 | #if 0 | 1409 | #if 0 |
@@ -1543,6 +1545,37 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1543 | } | 1545 | } |
1544 | } | 1546 | } |
1545 | 1547 | ||
1548 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | ||
1549 | { | ||
1550 | struct intel_output *intel_output = to_intel_output(connector); | ||
1551 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1552 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | ||
1553 | |||
1554 | /* | ||
1555 | * Attempt to get the mode list from DDC. | ||
1556 | * Assume that the preferred modes are | ||
1557 | * arranged in priority order. | ||
1558 | */ | ||
1559 | /* set the bus switch and get the modes */ | ||
1560 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1561 | intel_ddc_get_modes(intel_output); | ||
1562 | if (list_empty(&connector->probed_modes) == false) | ||
1563 | return; | ||
1564 | |||
1565 | /* Fetch modes from VBT */ | ||
1566 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { | ||
1567 | struct drm_display_mode *newmode; | ||
1568 | newmode = drm_mode_duplicate(connector->dev, | ||
1569 | dev_priv->sdvo_lvds_vbt_mode); | ||
1570 | if (newmode != NULL) { | ||
1571 | /* Guarantee the mode is preferred */ | ||
1572 | newmode->type = (DRM_MODE_TYPE_PREFERRED | | ||
1573 | DRM_MODE_TYPE_DRIVER); | ||
1574 | drm_mode_probed_add(connector, newmode); | ||
1575 | } | ||
1576 | } | ||
1577 | } | ||
1578 | |||
1546 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1579 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
1547 | { | 1580 | { |
1548 | struct intel_output *output = to_intel_output(connector); | 1581 | struct intel_output *output = to_intel_output(connector); |
@@ -1550,6 +1583,8 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) | |||
1550 | 1583 | ||
1551 | if (sdvo_priv->is_tv) | 1584 | if (sdvo_priv->is_tv) |
1552 | intel_sdvo_get_tv_modes(connector); | 1585 | intel_sdvo_get_tv_modes(connector); |
1586 | else if (sdvo_priv->is_lvds == true) | ||
1587 | intel_sdvo_get_lvds_modes(connector); | ||
1553 | else | 1588 | else |
1554 | intel_sdvo_get_ddc_modes(connector); | 1589 | intel_sdvo_get_ddc_modes(connector); |
1555 | 1590 | ||
@@ -1564,6 +1599,9 @@ static void intel_sdvo_destroy(struct drm_connector *connector) | |||
1564 | 1599 | ||
1565 | if (intel_output->i2c_bus) | 1600 | if (intel_output->i2c_bus) |
1566 | intel_i2c_destroy(intel_output->i2c_bus); | 1601 | intel_i2c_destroy(intel_output->i2c_bus); |
1602 | if (intel_output->ddc_bus) | ||
1603 | intel_i2c_destroy(intel_output->ddc_bus); | ||
1604 | |||
1567 | drm_sysfs_connector_remove(connector); | 1605 | drm_sysfs_connector_remove(connector); |
1568 | drm_connector_cleanup(connector); | 1606 | drm_connector_cleanup(connector); |
1569 | kfree(intel_output); | 1607 | kfree(intel_output); |
@@ -1578,6 +1616,7 @@ static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | |||
1578 | }; | 1616 | }; |
1579 | 1617 | ||
1580 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | 1618 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { |
1619 | .dpms = drm_helper_connector_dpms, | ||
1581 | .save = intel_sdvo_save, | 1620 | .save = intel_sdvo_save, |
1582 | .restore = intel_sdvo_restore, | 1621 | .restore = intel_sdvo_restore, |
1583 | .detect = intel_sdvo_detect, | 1622 | .detect = intel_sdvo_detect, |
@@ -1660,12 +1699,56 @@ intel_sdvo_get_digital_encoding_mode(struct intel_output *output) | |||
1660 | return true; | 1699 | return true; |
1661 | } | 1700 | } |
1662 | 1701 | ||
1702 | static struct intel_output * | ||
1703 | intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan) | ||
1704 | { | ||
1705 | struct drm_device *dev = chan->drm_dev; | ||
1706 | struct drm_connector *connector; | ||
1707 | struct intel_output *intel_output = NULL; | ||
1708 | |||
1709 | list_for_each_entry(connector, | ||
1710 | &dev->mode_config.connector_list, head) { | ||
1711 | if (to_intel_output(connector)->ddc_bus == chan) { | ||
1712 | intel_output = to_intel_output(connector); | ||
1713 | break; | ||
1714 | } | ||
1715 | } | ||
1716 | return intel_output; | ||
1717 | } | ||
1718 | |||
1719 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | ||
1720 | struct i2c_msg msgs[], int num) | ||
1721 | { | ||
1722 | struct intel_output *intel_output; | ||
1723 | struct intel_sdvo_priv *sdvo_priv; | ||
1724 | struct i2c_algo_bit_data *algo_data; | ||
1725 | struct i2c_algorithm *algo; | ||
1726 | |||
1727 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; | ||
1728 | intel_output = | ||
1729 | intel_sdvo_chan_to_intel_output( | ||
1730 | (struct intel_i2c_chan *)(algo_data->data)); | ||
1731 | if (intel_output == NULL) | ||
1732 | return -EINVAL; | ||
1733 | |||
1734 | sdvo_priv = intel_output->dev_priv; | ||
1735 | algo = (struct i2c_algorithm *)intel_output->i2c_bus->adapter.algo; | ||
1736 | |||
1737 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1738 | return algo->master_xfer(i2c_adap, msgs, num); | ||
1739 | } | ||
1740 | |||
1741 | static struct i2c_algorithm intel_sdvo_i2c_bit_algo = { | ||
1742 | .master_xfer = intel_sdvo_master_xfer, | ||
1743 | }; | ||
1744 | |||
1663 | bool intel_sdvo_init(struct drm_device *dev, int output_device) | 1745 | bool intel_sdvo_init(struct drm_device *dev, int output_device) |
1664 | { | 1746 | { |
1665 | struct drm_connector *connector; | 1747 | struct drm_connector *connector; |
1666 | struct intel_output *intel_output; | 1748 | struct intel_output *intel_output; |
1667 | struct intel_sdvo_priv *sdvo_priv; | 1749 | struct intel_sdvo_priv *sdvo_priv; |
1668 | struct intel_i2c_chan *i2cbus = NULL; | 1750 | struct intel_i2c_chan *i2cbus = NULL; |
1751 | struct intel_i2c_chan *ddcbus = NULL; | ||
1669 | int connector_type; | 1752 | int connector_type; |
1670 | u8 ch[0x40]; | 1753 | u8 ch[0x40]; |
1671 | int i; | 1754 | int i; |
@@ -1676,17 +1759,9 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1676 | return false; | 1759 | return false; |
1677 | } | 1760 | } |
1678 | 1761 | ||
1679 | connector = &intel_output->base; | ||
1680 | |||
1681 | drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, | ||
1682 | DRM_MODE_CONNECTOR_Unknown); | ||
1683 | drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs); | ||
1684 | sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); | 1762 | sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); |
1685 | intel_output->type = INTEL_OUTPUT_SDVO; | 1763 | intel_output->type = INTEL_OUTPUT_SDVO; |
1686 | 1764 | ||
1687 | connector->interlace_allowed = 0; | ||
1688 | connector->doublescan_allowed = 0; | ||
1689 | |||
1690 | /* setup the DDC bus. */ | 1765 | /* setup the DDC bus. */ |
1691 | if (output_device == SDVOB) | 1766 | if (output_device == SDVOB) |
1692 | i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); | 1767 | i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); |
@@ -1694,7 +1769,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1694 | i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); | 1769 | i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); |
1695 | 1770 | ||
1696 | if (!i2cbus) | 1771 | if (!i2cbus) |
1697 | goto err_connector; | 1772 | goto err_inteloutput; |
1698 | 1773 | ||
1699 | sdvo_priv->i2c_bus = i2cbus; | 1774 | sdvo_priv->i2c_bus = i2cbus; |
1700 | 1775 | ||
@@ -1710,7 +1785,6 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1710 | intel_output->i2c_bus = i2cbus; | 1785 | intel_output->i2c_bus = i2cbus; |
1711 | intel_output->dev_priv = sdvo_priv; | 1786 | intel_output->dev_priv = sdvo_priv; |
1712 | 1787 | ||
1713 | |||
1714 | /* Read the regs to test if we can talk to the device */ | 1788 | /* Read the regs to test if we can talk to the device */ |
1715 | for (i = 0; i < 0x40; i++) { | 1789 | for (i = 0; i < 0x40; i++) { |
1716 | if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) { | 1790 | if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) { |
@@ -1720,6 +1794,22 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1720 | } | 1794 | } |
1721 | } | 1795 | } |
1722 | 1796 | ||
1797 | /* setup the DDC bus. */ | ||
1798 | if (output_device == SDVOB) | ||
1799 | ddcbus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); | ||
1800 | else | ||
1801 | ddcbus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); | ||
1802 | |||
1803 | if (ddcbus == NULL) | ||
1804 | goto err_i2c; | ||
1805 | |||
1806 | intel_sdvo_i2c_bit_algo.functionality = | ||
1807 | intel_output->i2c_bus->adapter.algo->functionality; | ||
1808 | ddcbus->adapter.algo = &intel_sdvo_i2c_bit_algo; | ||
1809 | intel_output->ddc_bus = ddcbus; | ||
1810 | |||
1811 | /* In defaut case sdvo lvds is false */ | ||
1812 | sdvo_priv->is_lvds = false; | ||
1723 | intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); | 1813 | intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); |
1724 | 1814 | ||
1725 | if (sdvo_priv->caps.output_flags & | 1815 | if (sdvo_priv->caps.output_flags & |
@@ -1729,7 +1819,6 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1729 | else | 1819 | else |
1730 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1; | 1820 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1; |
1731 | 1821 | ||
1732 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | ||
1733 | encoder_type = DRM_MODE_ENCODER_TMDS; | 1822 | encoder_type = DRM_MODE_ENCODER_TMDS; |
1734 | connector_type = DRM_MODE_CONNECTOR_DVID; | 1823 | connector_type = DRM_MODE_CONNECTOR_DVID; |
1735 | 1824 | ||
@@ -1747,7 +1836,6 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1747 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0) | 1836 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0) |
1748 | { | 1837 | { |
1749 | sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; | 1838 | sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; |
1750 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | ||
1751 | encoder_type = DRM_MODE_ENCODER_TVDAC; | 1839 | encoder_type = DRM_MODE_ENCODER_TVDAC; |
1752 | connector_type = DRM_MODE_CONNECTOR_SVIDEO; | 1840 | connector_type = DRM_MODE_CONNECTOR_SVIDEO; |
1753 | sdvo_priv->is_tv = true; | 1841 | sdvo_priv->is_tv = true; |
@@ -1756,30 +1844,28 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1756 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) | 1844 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) |
1757 | { | 1845 | { |
1758 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; | 1846 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; |
1759 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | ||
1760 | encoder_type = DRM_MODE_ENCODER_DAC; | 1847 | encoder_type = DRM_MODE_ENCODER_DAC; |
1761 | connector_type = DRM_MODE_CONNECTOR_VGA; | 1848 | connector_type = DRM_MODE_CONNECTOR_VGA; |
1762 | } | 1849 | } |
1763 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) | 1850 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) |
1764 | { | 1851 | { |
1765 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; | 1852 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; |
1766 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | ||
1767 | encoder_type = DRM_MODE_ENCODER_DAC; | 1853 | encoder_type = DRM_MODE_ENCODER_DAC; |
1768 | connector_type = DRM_MODE_CONNECTOR_VGA; | 1854 | connector_type = DRM_MODE_CONNECTOR_VGA; |
1769 | } | 1855 | } |
1770 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0) | 1856 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0) |
1771 | { | 1857 | { |
1772 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; | 1858 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; |
1773 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | ||
1774 | encoder_type = DRM_MODE_ENCODER_LVDS; | 1859 | encoder_type = DRM_MODE_ENCODER_LVDS; |
1775 | connector_type = DRM_MODE_CONNECTOR_LVDS; | 1860 | connector_type = DRM_MODE_CONNECTOR_LVDS; |
1861 | sdvo_priv->is_lvds = true; | ||
1776 | } | 1862 | } |
1777 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1) | 1863 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1) |
1778 | { | 1864 | { |
1779 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; | 1865 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; |
1780 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | ||
1781 | encoder_type = DRM_MODE_ENCODER_LVDS; | 1866 | encoder_type = DRM_MODE_ENCODER_LVDS; |
1782 | connector_type = DRM_MODE_CONNECTOR_LVDS; | 1867 | connector_type = DRM_MODE_CONNECTOR_LVDS; |
1868 | sdvo_priv->is_lvds = true; | ||
1783 | } | 1869 | } |
1784 | else | 1870 | else |
1785 | { | 1871 | { |
@@ -1795,9 +1881,16 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1795 | goto err_i2c; | 1881 | goto err_i2c; |
1796 | } | 1882 | } |
1797 | 1883 | ||
1884 | connector = &intel_output->base; | ||
1885 | drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, | ||
1886 | connector_type); | ||
1887 | drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs); | ||
1888 | connector->interlace_allowed = 0; | ||
1889 | connector->doublescan_allowed = 0; | ||
1890 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | ||
1891 | |||
1798 | drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type); | 1892 | drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type); |
1799 | drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); | 1893 | drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); |
1800 | connector->connector_type = connector_type; | ||
1801 | 1894 | ||
1802 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 1895 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); |
1803 | drm_sysfs_connector_add(connector); | 1896 | drm_sysfs_connector_add(connector); |
@@ -1829,14 +1922,13 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1829 | sdvo_priv->caps.output_flags & | 1922 | sdvo_priv->caps.output_flags & |
1830 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); | 1923 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); |
1831 | 1924 | ||
1832 | intel_output->ddc_bus = i2cbus; | ||
1833 | |||
1834 | return true; | 1925 | return true; |
1835 | 1926 | ||
1836 | err_i2c: | 1927 | err_i2c: |
1928 | if (ddcbus != NULL) | ||
1929 | intel_i2c_destroy(intel_output->ddc_bus); | ||
1837 | intel_i2c_destroy(intel_output->i2c_bus); | 1930 | intel_i2c_destroy(intel_output->i2c_bus); |
1838 | err_connector: | 1931 | err_inteloutput: |
1839 | drm_connector_cleanup(connector); | ||
1840 | kfree(intel_output); | 1932 | kfree(intel_output); |
1841 | 1933 | ||
1842 | return false; | 1934 | return false; |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index d2c32983242d..98ac0546b7bd 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1626,6 +1626,7 @@ static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = { | |||
1626 | }; | 1626 | }; |
1627 | 1627 | ||
1628 | static const struct drm_connector_funcs intel_tv_connector_funcs = { | 1628 | static const struct drm_connector_funcs intel_tv_connector_funcs = { |
1629 | .dpms = drm_helper_connector_dpms, | ||
1629 | .save = intel_tv_save, | 1630 | .save = intel_tv_save, |
1630 | .restore = intel_tv_restore, | 1631 | .restore = intel_tv_restore, |
1631 | .detect = intel_tv_detect, | 1632 | .detect = intel_tv_detect, |
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 77a7a4d84650..aff90bb96488 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -2185,9 +2185,9 @@ void radeon_commit_ring(drm_radeon_private_t *dev_priv) | |||
2185 | 2185 | ||
2186 | /* check if the ring is padded out to 16-dword alignment */ | 2186 | /* check if the ring is padded out to 16-dword alignment */ |
2187 | 2187 | ||
2188 | tail_aligned = dev_priv->ring.tail & 0xf; | 2188 | tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN-1); |
2189 | if (tail_aligned) { | 2189 | if (tail_aligned) { |
2190 | int num_p2 = 16 - tail_aligned; | 2190 | int num_p2 = RADEON_RING_ALIGN - tail_aligned; |
2191 | 2191 | ||
2192 | ring = dev_priv->ring.start; | 2192 | ring = dev_priv->ring.start; |
2193 | /* pad with some CP_PACKET2 */ | 2193 | /* pad with some CP_PACKET2 */ |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 8071d965f142..0c6bfc1de153 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -1964,11 +1964,14 @@ do { \ | |||
1964 | 1964 | ||
1965 | #define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring; | 1965 | #define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring; |
1966 | 1966 | ||
1967 | #define RADEON_RING_ALIGN 16 | ||
1968 | |||
1967 | #define BEGIN_RING( n ) do { \ | 1969 | #define BEGIN_RING( n ) do { \ |
1968 | if ( RADEON_VERBOSE ) { \ | 1970 | if ( RADEON_VERBOSE ) { \ |
1969 | DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ | 1971 | DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ |
1970 | } \ | 1972 | } \ |
1971 | _align_nr = (n + 0xf) & ~0xf; \ | 1973 | _align_nr = RADEON_RING_ALIGN - ((dev_priv->ring.tail + n) & (RADEON_RING_ALIGN-1)); \ |
1974 | _align_nr += n; \ | ||
1972 | if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \ | 1975 | if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \ |
1973 | COMMIT_RING(); \ | 1976 | COMMIT_RING(); \ |
1974 | radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \ | 1977 | radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \ |