diff options
Diffstat (limited to 'drivers/gpu/drm')
85 files changed, 979 insertions, 685 deletions
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 3f46772f0cb2..ba23790450e9 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c | |||
@@ -101,7 +101,7 @@ static int drm_add_magic(struct drm_master *master, struct drm_file *priv, | |||
101 | * Searches and unlinks the entry in drm_device::magiclist with the magic | 101 | * Searches and unlinks the entry in drm_device::magiclist with the magic |
102 | * number hash key, while holding the drm_device::struct_mutex lock. | 102 | * number hash key, while holding the drm_device::struct_mutex lock. |
103 | */ | 103 | */ |
104 | static int drm_remove_magic(struct drm_master *master, drm_magic_t magic) | 104 | int drm_remove_magic(struct drm_master *master, drm_magic_t magic) |
105 | { | 105 | { |
106 | struct drm_magic_entry *pt; | 106 | struct drm_magic_entry *pt; |
107 | struct drm_hash_item *hash; | 107 | struct drm_hash_item *hash; |
@@ -136,6 +136,8 @@ static int drm_remove_magic(struct drm_master *master, drm_magic_t magic) | |||
136 | * If there is a magic number in drm_file::magic then use it, otherwise | 136 | * If there is a magic number in drm_file::magic then use it, otherwise |
137 | * searches an unique non-zero magic number and add it associating it with \p | 137 | * searches an unique non-zero magic number and add it associating it with \p |
138 | * file_priv. | 138 | * file_priv. |
139 | * This ioctl needs protection by the drm_global_mutex, which protects | ||
140 | * struct drm_file::magic and struct drm_magic_entry::priv. | ||
139 | */ | 141 | */ |
140 | int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) | 142 | int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) |
141 | { | 143 | { |
@@ -173,6 +175,8 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
173 | * \return zero if authentication successed, or a negative number otherwise. | 175 | * \return zero if authentication successed, or a negative number otherwise. |
174 | * | 176 | * |
175 | * Checks if \p file_priv is associated with the magic number passed in \arg. | 177 | * Checks if \p file_priv is associated with the magic number passed in \arg. |
178 | * This ioctl needs protection by the drm_global_mutex, which protects | ||
179 | * struct drm_file::magic and struct drm_magic_entry::priv. | ||
176 | */ | 180 | */ |
177 | int drm_authmagic(struct drm_device *dev, void *data, | 181 | int drm_authmagic(struct drm_device *dev, void *data, |
178 | struct drm_file *file_priv) | 182 | struct drm_file *file_priv) |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index c00cf154cc0b..6263b0147598 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -487,6 +487,11 @@ int drm_release(struct inode *inode, struct file *filp) | |||
487 | (long)old_encode_dev(file_priv->minor->device), | 487 | (long)old_encode_dev(file_priv->minor->device), |
488 | dev->open_count); | 488 | dev->open_count); |
489 | 489 | ||
490 | /* Release any auth tokens that might point to this file_priv, | ||
491 | (do that under the drm_global_mutex) */ | ||
492 | if (file_priv->magic) | ||
493 | (void) drm_remove_magic(file_priv->master, file_priv->magic); | ||
494 | |||
490 | /* if the master has gone away we can't do anything with the lock */ | 495 | /* if the master has gone away we can't do anything with the lock */ |
491 | if (file_priv->minor->master) | 496 | if (file_priv->minor->master) |
492 | drm_master_release(dev, filp); | 497 | drm_master_release(dev, filp); |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 396e60ce8114..f8625e290728 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -140,7 +140,7 @@ int drm_gem_object_init(struct drm_device *dev, | |||
140 | obj->dev = dev; | 140 | obj->dev = dev; |
141 | obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); | 141 | obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); |
142 | if (IS_ERR(obj->filp)) | 142 | if (IS_ERR(obj->filp)) |
143 | return -ENOMEM; | 143 | return PTR_ERR(obj->filp); |
144 | 144 | ||
145 | kref_init(&obj->refcount); | 145 | kref_init(&obj->refcount); |
146 | atomic_set(&obj->handle_count, 0); | 146 | atomic_set(&obj->handle_count, 0); |
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c index ddd70db45f76..637fcc3766c7 100644 --- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c | |||
@@ -315,7 +315,8 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd, | |||
315 | if (err) | 315 | if (err) |
316 | return err; | 316 | return err; |
317 | 317 | ||
318 | if (__get_user(c32.auth, &client->auth) | 318 | if (__get_user(c32.idx, &client->idx) |
319 | || __get_user(c32.auth, &client->auth) | ||
319 | || __get_user(c32.pid, &client->pid) | 320 | || __get_user(c32.pid, &client->pid) |
320 | || __get_user(c32.uid, &client->uid) | 321 | || __get_user(c32.uid, &client->uid) |
321 | || __get_user(c32.magic, &client->magic) | 322 | || __get_user(c32.magic, &client->magic) |
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index f9aaa56eae07..b9e5266c341b 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig | |||
@@ -13,7 +13,7 @@ config DRM_EXYNOS | |||
13 | 13 | ||
14 | config DRM_EXYNOS_FIMD | 14 | config DRM_EXYNOS_FIMD |
15 | tristate "Exynos DRM FIMD" | 15 | tristate "Exynos DRM FIMD" |
16 | depends on DRM_EXYNOS | 16 | depends on DRM_EXYNOS && !FB_S3C |
17 | default n | 17 | default n |
18 | help | 18 | help |
19 | Choose this option if you want to use Exynos FIMD for DRM. | 19 | Choose this option if you want to use Exynos FIMD for DRM. |
@@ -21,7 +21,7 @@ config DRM_EXYNOS_FIMD | |||
21 | 21 | ||
22 | config DRM_EXYNOS_HDMI | 22 | config DRM_EXYNOS_HDMI |
23 | tristate "Exynos DRM HDMI" | 23 | tristate "Exynos DRM HDMI" |
24 | depends on DRM_EXYNOS | 24 | depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV |
25 | help | 25 | help |
26 | Choose this option if you want to use Exynos HDMI for DRM. | 26 | Choose this option if you want to use Exynos HDMI for DRM. |
27 | If M is selected, the module will be called exynos_drm_hdmi | 27 | If M is selected, the module will be called exynos_drm_hdmi |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c index d620b0784257..99d5527b2ca6 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "drmP.h" | 28 | #include "drmP.h" |
29 | #include "drm_crtc_helper.h" | 29 | #include "drm_crtc_helper.h" |
30 | 30 | ||
31 | #include <drm/exynos_drm.h> | ||
31 | #include "exynos_drm_drv.h" | 32 | #include "exynos_drm_drv.h" |
32 | #include "exynos_drm_encoder.h" | 33 | #include "exynos_drm_encoder.h" |
33 | 34 | ||
@@ -44,22 +45,25 @@ struct exynos_drm_connector { | |||
44 | /* convert exynos_video_timings to drm_display_mode */ | 45 | /* convert exynos_video_timings to drm_display_mode */ |
45 | static inline void | 46 | static inline void |
46 | convert_to_display_mode(struct drm_display_mode *mode, | 47 | convert_to_display_mode(struct drm_display_mode *mode, |
47 | struct fb_videomode *timing) | 48 | struct exynos_drm_panel_info *panel) |
48 | { | 49 | { |
50 | struct fb_videomode *timing = &panel->timing; | ||
49 | DRM_DEBUG_KMS("%s\n", __FILE__); | 51 | DRM_DEBUG_KMS("%s\n", __FILE__); |
50 | 52 | ||
51 | mode->clock = timing->pixclock / 1000; | 53 | mode->clock = timing->pixclock / 1000; |
52 | mode->vrefresh = timing->refresh; | 54 | mode->vrefresh = timing->refresh; |
53 | 55 | ||
54 | mode->hdisplay = timing->xres; | 56 | mode->hdisplay = timing->xres; |
55 | mode->hsync_start = mode->hdisplay + timing->left_margin; | 57 | mode->hsync_start = mode->hdisplay + timing->right_margin; |
56 | mode->hsync_end = mode->hsync_start + timing->hsync_len; | 58 | mode->hsync_end = mode->hsync_start + timing->hsync_len; |
57 | mode->htotal = mode->hsync_end + timing->right_margin; | 59 | mode->htotal = mode->hsync_end + timing->left_margin; |
58 | 60 | ||
59 | mode->vdisplay = timing->yres; | 61 | mode->vdisplay = timing->yres; |
60 | mode->vsync_start = mode->vdisplay + timing->upper_margin; | 62 | mode->vsync_start = mode->vdisplay + timing->lower_margin; |
61 | mode->vsync_end = mode->vsync_start + timing->vsync_len; | 63 | mode->vsync_end = mode->vsync_start + timing->vsync_len; |
62 | mode->vtotal = mode->vsync_end + timing->lower_margin; | 64 | mode->vtotal = mode->vsync_end + timing->upper_margin; |
65 | mode->width_mm = panel->width_mm; | ||
66 | mode->height_mm = panel->height_mm; | ||
63 | 67 | ||
64 | if (timing->vmode & FB_VMODE_INTERLACED) | 68 | if (timing->vmode & FB_VMODE_INTERLACED) |
65 | mode->flags |= DRM_MODE_FLAG_INTERLACE; | 69 | mode->flags |= DRM_MODE_FLAG_INTERLACE; |
@@ -81,14 +85,14 @@ convert_to_video_timing(struct fb_videomode *timing, | |||
81 | timing->refresh = drm_mode_vrefresh(mode); | 85 | timing->refresh = drm_mode_vrefresh(mode); |
82 | 86 | ||
83 | timing->xres = mode->hdisplay; | 87 | timing->xres = mode->hdisplay; |
84 | timing->left_margin = mode->hsync_start - mode->hdisplay; | 88 | timing->right_margin = mode->hsync_start - mode->hdisplay; |
85 | timing->hsync_len = mode->hsync_end - mode->hsync_start; | 89 | timing->hsync_len = mode->hsync_end - mode->hsync_start; |
86 | timing->right_margin = mode->htotal - mode->hsync_end; | 90 | timing->left_margin = mode->htotal - mode->hsync_end; |
87 | 91 | ||
88 | timing->yres = mode->vdisplay; | 92 | timing->yres = mode->vdisplay; |
89 | timing->upper_margin = mode->vsync_start - mode->vdisplay; | 93 | timing->lower_margin = mode->vsync_start - mode->vdisplay; |
90 | timing->vsync_len = mode->vsync_end - mode->vsync_start; | 94 | timing->vsync_len = mode->vsync_end - mode->vsync_start; |
91 | timing->lower_margin = mode->vtotal - mode->vsync_end; | 95 | timing->upper_margin = mode->vtotal - mode->vsync_end; |
92 | 96 | ||
93 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | 97 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
94 | timing->vmode = FB_VMODE_INTERLACED; | 98 | timing->vmode = FB_VMODE_INTERLACED; |
@@ -148,16 +152,18 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) | |||
148 | connector->display_info.raw_edid = edid; | 152 | connector->display_info.raw_edid = edid; |
149 | } else { | 153 | } else { |
150 | struct drm_display_mode *mode = drm_mode_create(connector->dev); | 154 | struct drm_display_mode *mode = drm_mode_create(connector->dev); |
151 | struct fb_videomode *timing; | 155 | struct exynos_drm_panel_info *panel; |
152 | 156 | ||
153 | if (display_ops->get_timing) | 157 | if (display_ops->get_panel) |
154 | timing = display_ops->get_timing(manager->dev); | 158 | panel = display_ops->get_panel(manager->dev); |
155 | else { | 159 | else { |
156 | drm_mode_destroy(connector->dev, mode); | 160 | drm_mode_destroy(connector->dev, mode); |
157 | return 0; | 161 | return 0; |
158 | } | 162 | } |
159 | 163 | ||
160 | convert_to_display_mode(mode, timing); | 164 | convert_to_display_mode(mode, panel); |
165 | connector->display_info.width_mm = mode->width_mm; | ||
166 | connector->display_info.height_mm = mode->height_mm; | ||
161 | 167 | ||
162 | mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; | 168 | mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; |
163 | drm_mode_set_name(mode); | 169 | drm_mode_set_name(mode); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c index 661a03571d0c..d08a55896d50 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_core.c +++ b/drivers/gpu/drm/exynos/exynos_drm_core.c | |||
@@ -193,6 +193,9 @@ int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv) | |||
193 | return err; | 193 | return err; |
194 | } | 194 | } |
195 | 195 | ||
196 | /* setup possible_clones. */ | ||
197 | exynos_drm_encoder_setup(drm_dev); | ||
198 | |||
196 | /* | 199 | /* |
197 | * if any specific driver such as fimd or hdmi driver called | 200 | * if any specific driver such as fimd or hdmi driver called |
198 | * exynos_drm_subdrv_register() later than drm_load(), | 201 | * exynos_drm_subdrv_register() later than drm_load(), |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index e3861ac49295..de818831a511 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c | |||
@@ -307,9 +307,6 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, | |||
307 | */ | 307 | */ |
308 | event->pipe = exynos_crtc->pipe; | 308 | event->pipe = exynos_crtc->pipe; |
309 | 309 | ||
310 | list_add_tail(&event->base.link, | ||
311 | &dev_priv->pageflip_event_list); | ||
312 | |||
313 | ret = drm_vblank_get(dev, exynos_crtc->pipe); | 310 | ret = drm_vblank_get(dev, exynos_crtc->pipe); |
314 | if (ret) { | 311 | if (ret) { |
315 | DRM_DEBUG("failed to acquire vblank counter\n"); | 312 | DRM_DEBUG("failed to acquire vblank counter\n"); |
@@ -318,6 +315,9 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, | |||
318 | goto out; | 315 | goto out; |
319 | } | 316 | } |
320 | 317 | ||
318 | list_add_tail(&event->base.link, | ||
319 | &dev_priv->pageflip_event_list); | ||
320 | |||
321 | crtc->fb = fb; | 321 | crtc->fb = fb; |
322 | ret = exynos_drm_crtc_update(crtc); | 322 | ret = exynos_drm_crtc_update(crtc); |
323 | if (ret) { | 323 | if (ret) { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 35889ca255e9..09cc13f791b3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | #include "exynos_drm_drv.h" | 34 | #include "exynos_drm_drv.h" |
35 | #include "exynos_drm_crtc.h" | 35 | #include "exynos_drm_crtc.h" |
36 | #include "exynos_drm_encoder.h" | ||
36 | #include "exynos_drm_fbdev.h" | 37 | #include "exynos_drm_fbdev.h" |
37 | #include "exynos_drm_fb.h" | 38 | #include "exynos_drm_fb.h" |
38 | #include "exynos_drm_gem.h" | 39 | #include "exynos_drm_gem.h" |
@@ -99,6 +100,9 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) | |||
99 | if (ret) | 100 | if (ret) |
100 | goto err_vblank; | 101 | goto err_vblank; |
101 | 102 | ||
103 | /* setup possible_clones. */ | ||
104 | exynos_drm_encoder_setup(dev); | ||
105 | |||
102 | /* | 106 | /* |
103 | * create and configure fb helper and also exynos specific | 107 | * create and configure fb helper and also exynos specific |
104 | * fbdev object. | 108 | * fbdev object. |
@@ -141,16 +145,21 @@ static int exynos_drm_unload(struct drm_device *dev) | |||
141 | } | 145 | } |
142 | 146 | ||
143 | static void exynos_drm_preclose(struct drm_device *dev, | 147 | static void exynos_drm_preclose(struct drm_device *dev, |
144 | struct drm_file *file_priv) | 148 | struct drm_file *file) |
145 | { | 149 | { |
146 | struct exynos_drm_private *dev_priv = dev->dev_private; | 150 | DRM_DEBUG_DRIVER("%s\n", __FILE__); |
147 | 151 | ||
148 | /* | 152 | } |
149 | * drm framework frees all events at release time, | 153 | |
150 | * so private event list should be cleared. | 154 | static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) |
151 | */ | 155 | { |
152 | if (!list_empty(&dev_priv->pageflip_event_list)) | 156 | DRM_DEBUG_DRIVER("%s\n", __FILE__); |
153 | INIT_LIST_HEAD(&dev_priv->pageflip_event_list); | 157 | |
158 | if (!file->driver_priv) | ||
159 | return; | ||
160 | |||
161 | kfree(file->driver_priv); | ||
162 | file->driver_priv = NULL; | ||
154 | } | 163 | } |
155 | 164 | ||
156 | static void exynos_drm_lastclose(struct drm_device *dev) | 165 | static void exynos_drm_lastclose(struct drm_device *dev) |
@@ -195,6 +204,7 @@ static struct drm_driver exynos_drm_driver = { | |||
195 | .unload = exynos_drm_unload, | 204 | .unload = exynos_drm_unload, |
196 | .preclose = exynos_drm_preclose, | 205 | .preclose = exynos_drm_preclose, |
197 | .lastclose = exynos_drm_lastclose, | 206 | .lastclose = exynos_drm_lastclose, |
207 | .postclose = exynos_drm_postclose, | ||
198 | .get_vblank_counter = drm_vblank_count, | 208 | .get_vblank_counter = drm_vblank_count, |
199 | .enable_vblank = exynos_drm_crtc_enable_vblank, | 209 | .enable_vblank = exynos_drm_crtc_enable_vblank, |
200 | .disable_vblank = exynos_drm_crtc_disable_vblank, | 210 | .disable_vblank = exynos_drm_crtc_disable_vblank, |
@@ -236,7 +246,7 @@ static struct platform_driver exynos_drm_platform_driver = { | |||
236 | .remove = __devexit_p(exynos_drm_platform_remove), | 246 | .remove = __devexit_p(exynos_drm_platform_remove), |
237 | .driver = { | 247 | .driver = { |
238 | .owner = THIS_MODULE, | 248 | .owner = THIS_MODULE, |
239 | .name = DRIVER_NAME, | 249 | .name = "exynos-drm", |
240 | }, | 250 | }, |
241 | }; | 251 | }; |
242 | 252 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index e685e1e33055..13540de90bfc 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -136,7 +136,7 @@ struct exynos_drm_overlay { | |||
136 | * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. | 136 | * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. |
137 | * @is_connected: check for that display is connected or not. | 137 | * @is_connected: check for that display is connected or not. |
138 | * @get_edid: get edid modes from display driver. | 138 | * @get_edid: get edid modes from display driver. |
139 | * @get_timing: get timing object from display driver. | 139 | * @get_panel: get panel object from display driver. |
140 | * @check_timing: check if timing is valid or not. | 140 | * @check_timing: check if timing is valid or not. |
141 | * @power_on: display device on or off. | 141 | * @power_on: display device on or off. |
142 | */ | 142 | */ |
@@ -145,7 +145,7 @@ struct exynos_drm_display_ops { | |||
145 | bool (*is_connected)(struct device *dev); | 145 | bool (*is_connected)(struct device *dev); |
146 | int (*get_edid)(struct device *dev, struct drm_connector *connector, | 146 | int (*get_edid)(struct device *dev, struct drm_connector *connector, |
147 | u8 *edid, int len); | 147 | u8 *edid, int len); |
148 | void *(*get_timing)(struct device *dev); | 148 | void *(*get_panel)(struct device *dev); |
149 | int (*check_timing)(struct device *dev, void *timing); | 149 | int (*check_timing)(struct device *dev, void *timing); |
150 | int (*power_on)(struct device *dev, int mode); | 150 | int (*power_on)(struct device *dev, int mode); |
151 | }; | 151 | }; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 86b93dde219a..ef4754f1519b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c | |||
@@ -195,6 +195,40 @@ static struct drm_encoder_funcs exynos_encoder_funcs = { | |||
195 | .destroy = exynos_drm_encoder_destroy, | 195 | .destroy = exynos_drm_encoder_destroy, |
196 | }; | 196 | }; |
197 | 197 | ||
198 | static unsigned int exynos_drm_encoder_clones(struct drm_encoder *encoder) | ||
199 | { | ||
200 | struct drm_encoder *clone; | ||
201 | struct drm_device *dev = encoder->dev; | ||
202 | struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); | ||
203 | struct exynos_drm_display_ops *display_ops = | ||
204 | exynos_encoder->manager->display_ops; | ||
205 | unsigned int clone_mask = 0; | ||
206 | int cnt = 0; | ||
207 | |||
208 | list_for_each_entry(clone, &dev->mode_config.encoder_list, head) { | ||
209 | switch (display_ops->type) { | ||
210 | case EXYNOS_DISPLAY_TYPE_LCD: | ||
211 | case EXYNOS_DISPLAY_TYPE_HDMI: | ||
212 | clone_mask |= (1 << (cnt++)); | ||
213 | break; | ||
214 | default: | ||
215 | continue; | ||
216 | } | ||
217 | } | ||
218 | |||
219 | return clone_mask; | ||
220 | } | ||
221 | |||
222 | void exynos_drm_encoder_setup(struct drm_device *dev) | ||
223 | { | ||
224 | struct drm_encoder *encoder; | ||
225 | |||
226 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
227 | |||
228 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) | ||
229 | encoder->possible_clones = exynos_drm_encoder_clones(encoder); | ||
230 | } | ||
231 | |||
198 | struct drm_encoder * | 232 | struct drm_encoder * |
199 | exynos_drm_encoder_create(struct drm_device *dev, | 233 | exynos_drm_encoder_create(struct drm_device *dev, |
200 | struct exynos_drm_manager *manager, | 234 | struct exynos_drm_manager *manager, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h index 97b087a51cb6..eb7d2316847e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.h | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | struct exynos_drm_manager; | 31 | struct exynos_drm_manager; |
32 | 32 | ||
33 | void exynos_drm_encoder_setup(struct drm_device *dev); | ||
33 | struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev, | 34 | struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev, |
34 | struct exynos_drm_manager *mgr, | 35 | struct exynos_drm_manager *mgr, |
35 | unsigned int possible_crtcs); | 36 | unsigned int possible_crtcs); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index d7ae29d2f3d6..54f8f074822f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c | |||
@@ -46,39 +46,13 @@ struct exynos_drm_fbdev { | |||
46 | struct exynos_drm_gem_obj *exynos_gem_obj; | 46 | struct exynos_drm_gem_obj *exynos_gem_obj; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static int exynos_drm_fbdev_set_par(struct fb_info *info) | ||
50 | { | ||
51 | struct fb_var_screeninfo *var = &info->var; | ||
52 | |||
53 | switch (var->bits_per_pixel) { | ||
54 | case 32: | ||
55 | case 24: | ||
56 | case 18: | ||
57 | case 16: | ||
58 | case 12: | ||
59 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
60 | break; | ||
61 | case 1: | ||
62 | info->fix.visual = FB_VISUAL_MONO01; | ||
63 | break; | ||
64 | default: | ||
65 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; | ||
66 | break; | ||
67 | } | ||
68 | |||
69 | info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; | ||
70 | |||
71 | return drm_fb_helper_set_par(info); | ||
72 | } | ||
73 | |||
74 | |||
75 | static struct fb_ops exynos_drm_fb_ops = { | 49 | static struct fb_ops exynos_drm_fb_ops = { |
76 | .owner = THIS_MODULE, | 50 | .owner = THIS_MODULE, |
77 | .fb_fillrect = cfb_fillrect, | 51 | .fb_fillrect = cfb_fillrect, |
78 | .fb_copyarea = cfb_copyarea, | 52 | .fb_copyarea = cfb_copyarea, |
79 | .fb_imageblit = cfb_imageblit, | 53 | .fb_imageblit = cfb_imageblit, |
80 | .fb_check_var = drm_fb_helper_check_var, | 54 | .fb_check_var = drm_fb_helper_check_var, |
81 | .fb_set_par = exynos_drm_fbdev_set_par, | 55 | .fb_set_par = drm_fb_helper_set_par, |
82 | .fb_blank = drm_fb_helper_blank, | 56 | .fb_blank = drm_fb_helper_blank, |
83 | .fb_pan_display = drm_fb_helper_pan_display, | 57 | .fb_pan_display = drm_fb_helper_pan_display, |
84 | .fb_setcmap = drm_fb_helper_setcmap, | 58 | .fb_setcmap = drm_fb_helper_setcmap, |
@@ -195,66 +169,6 @@ out: | |||
195 | return ret; | 169 | return ret; |
196 | } | 170 | } |
197 | 171 | ||
198 | static bool | ||
199 | exynos_drm_fbdev_is_samefb(struct drm_framebuffer *fb, | ||
200 | struct drm_fb_helper_surface_size *sizes) | ||
201 | { | ||
202 | if (fb->width != sizes->surface_width) | ||
203 | return false; | ||
204 | if (fb->height != sizes->surface_height) | ||
205 | return false; | ||
206 | if (fb->bits_per_pixel != sizes->surface_bpp) | ||
207 | return false; | ||
208 | if (fb->depth != sizes->surface_depth) | ||
209 | return false; | ||
210 | |||
211 | return true; | ||
212 | } | ||
213 | |||
214 | static int exynos_drm_fbdev_recreate(struct drm_fb_helper *helper, | ||
215 | struct drm_fb_helper_surface_size *sizes) | ||
216 | { | ||
217 | struct drm_device *dev = helper->dev; | ||
218 | struct exynos_drm_fbdev *exynos_fbdev = to_exynos_fbdev(helper); | ||
219 | struct exynos_drm_gem_obj *exynos_gem_obj; | ||
220 | struct drm_framebuffer *fb = helper->fb; | ||
221 | struct drm_mode_fb_cmd2 mode_cmd = { 0 }; | ||
222 | unsigned long size; | ||
223 | |||
224 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
225 | |||
226 | if (exynos_drm_fbdev_is_samefb(fb, sizes)) | ||
227 | return 0; | ||
228 | |||
229 | mode_cmd.width = sizes->surface_width; | ||
230 | mode_cmd.height = sizes->surface_height; | ||
231 | mode_cmd.pitches[0] = sizes->surface_width * (sizes->surface_bpp >> 3); | ||
232 | mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, | ||
233 | sizes->surface_depth); | ||
234 | |||
235 | if (exynos_fbdev->exynos_gem_obj) | ||
236 | exynos_drm_gem_destroy(exynos_fbdev->exynos_gem_obj); | ||
237 | |||
238 | if (fb->funcs->destroy) | ||
239 | fb->funcs->destroy(fb); | ||
240 | |||
241 | size = mode_cmd.pitches[0] * mode_cmd.height; | ||
242 | exynos_gem_obj = exynos_drm_gem_create(dev, size); | ||
243 | if (IS_ERR(exynos_gem_obj)) | ||
244 | return PTR_ERR(exynos_gem_obj); | ||
245 | |||
246 | exynos_fbdev->exynos_gem_obj = exynos_gem_obj; | ||
247 | |||
248 | helper->fb = exynos_drm_framebuffer_init(dev, &mode_cmd, | ||
249 | &exynos_gem_obj->base); | ||
250 | if (IS_ERR_OR_NULL(helper->fb)) { | ||
251 | DRM_ERROR("failed to create drm framebuffer.\n"); | ||
252 | return PTR_ERR(helper->fb); | ||
253 | } | ||
254 | |||
255 | return exynos_drm_fbdev_update(helper, helper->fb); | ||
256 | } | ||
257 | |||
258 | static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper, | 172 | static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper, |
259 | struct drm_fb_helper_surface_size *sizes) | 173 | struct drm_fb_helper_surface_size *sizes) |
260 | { | 174 | { |
@@ -262,6 +176,10 @@ static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper, | |||
262 | 176 | ||
263 | DRM_DEBUG_KMS("%s\n", __FILE__); | 177 | DRM_DEBUG_KMS("%s\n", __FILE__); |
264 | 178 | ||
179 | /* | ||
180 | * with !helper->fb, it means that this funcion is called first time | ||
181 | * and after that, the helper->fb would be used as clone mode. | ||
182 | */ | ||
265 | if (!helper->fb) { | 183 | if (!helper->fb) { |
266 | ret = exynos_drm_fbdev_create(helper, sizes); | 184 | ret = exynos_drm_fbdev_create(helper, sizes); |
267 | if (ret < 0) { | 185 | if (ret < 0) { |
@@ -274,12 +192,6 @@ static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper, | |||
274 | * because register_framebuffer() should be called. | 192 | * because register_framebuffer() should be called. |
275 | */ | 193 | */ |
276 | ret = 1; | 194 | ret = 1; |
277 | } else { | ||
278 | ret = exynos_drm_fbdev_recreate(helper, sizes); | ||
279 | if (ret < 0) { | ||
280 | DRM_ERROR("failed to reconfigure fbdev\n"); | ||
281 | return ret; | ||
282 | } | ||
283 | } | 195 | } |
284 | 196 | ||
285 | return ret; | 197 | return ret; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index ca83139cd309..56458eea0501 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -89,7 +89,7 @@ struct fimd_context { | |||
89 | bool suspended; | 89 | bool suspended; |
90 | struct mutex lock; | 90 | struct mutex lock; |
91 | 91 | ||
92 | struct fb_videomode *timing; | 92 | struct exynos_drm_panel_info *panel; |
93 | }; | 93 | }; |
94 | 94 | ||
95 | static bool fimd_display_is_connected(struct device *dev) | 95 | static bool fimd_display_is_connected(struct device *dev) |
@@ -101,13 +101,13 @@ static bool fimd_display_is_connected(struct device *dev) | |||
101 | return true; | 101 | return true; |
102 | } | 102 | } |
103 | 103 | ||
104 | static void *fimd_get_timing(struct device *dev) | 104 | static void *fimd_get_panel(struct device *dev) |
105 | { | 105 | { |
106 | struct fimd_context *ctx = get_fimd_context(dev); | 106 | struct fimd_context *ctx = get_fimd_context(dev); |
107 | 107 | ||
108 | DRM_DEBUG_KMS("%s\n", __FILE__); | 108 | DRM_DEBUG_KMS("%s\n", __FILE__); |
109 | 109 | ||
110 | return ctx->timing; | 110 | return ctx->panel; |
111 | } | 111 | } |
112 | 112 | ||
113 | static int fimd_check_timing(struct device *dev, void *timing) | 113 | static int fimd_check_timing(struct device *dev, void *timing) |
@@ -131,7 +131,7 @@ static int fimd_display_power_on(struct device *dev, int mode) | |||
131 | static struct exynos_drm_display_ops fimd_display_ops = { | 131 | static struct exynos_drm_display_ops fimd_display_ops = { |
132 | .type = EXYNOS_DISPLAY_TYPE_LCD, | 132 | .type = EXYNOS_DISPLAY_TYPE_LCD, |
133 | .is_connected = fimd_display_is_connected, | 133 | .is_connected = fimd_display_is_connected, |
134 | .get_timing = fimd_get_timing, | 134 | .get_panel = fimd_get_panel, |
135 | .check_timing = fimd_check_timing, | 135 | .check_timing = fimd_check_timing, |
136 | .power_on = fimd_display_power_on, | 136 | .power_on = fimd_display_power_on, |
137 | }; | 137 | }; |
@@ -158,7 +158,8 @@ static void fimd_dpms(struct device *subdrv_dev, int mode) | |||
158 | case DRM_MODE_DPMS_STANDBY: | 158 | case DRM_MODE_DPMS_STANDBY: |
159 | case DRM_MODE_DPMS_SUSPEND: | 159 | case DRM_MODE_DPMS_SUSPEND: |
160 | case DRM_MODE_DPMS_OFF: | 160 | case DRM_MODE_DPMS_OFF: |
161 | pm_runtime_put_sync(subdrv_dev); | 161 | if (!ctx->suspended) |
162 | pm_runtime_put_sync(subdrv_dev); | ||
162 | break; | 163 | break; |
163 | default: | 164 | default: |
164 | DRM_DEBUG_KMS("unspecified mode %d\n", mode); | 165 | DRM_DEBUG_KMS("unspecified mode %d\n", mode); |
@@ -192,7 +193,8 @@ static void fimd_apply(struct device *subdrv_dev) | |||
192 | static void fimd_commit(struct device *dev) | 193 | static void fimd_commit(struct device *dev) |
193 | { | 194 | { |
194 | struct fimd_context *ctx = get_fimd_context(dev); | 195 | struct fimd_context *ctx = get_fimd_context(dev); |
195 | struct fb_videomode *timing = ctx->timing; | 196 | struct exynos_drm_panel_info *panel = ctx->panel; |
197 | struct fb_videomode *timing = &panel->timing; | ||
196 | u32 val; | 198 | u32 val; |
197 | 199 | ||
198 | if (ctx->suspended) | 200 | if (ctx->suspended) |
@@ -603,7 +605,12 @@ static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc) | |||
603 | } | 605 | } |
604 | 606 | ||
605 | if (is_checked) { | 607 | if (is_checked) { |
606 | drm_vblank_put(drm_dev, crtc); | 608 | /* |
609 | * call drm_vblank_put only in case that drm_vblank_get was | ||
610 | * called. | ||
611 | */ | ||
612 | if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0) | ||
613 | drm_vblank_put(drm_dev, crtc); | ||
607 | 614 | ||
608 | /* | 615 | /* |
609 | * don't off vblank if vblank_disable_allowed is 1, | 616 | * don't off vblank if vblank_disable_allowed is 1, |
@@ -734,13 +741,53 @@ static void fimd_clear_win(struct fimd_context *ctx, int win) | |||
734 | writel(val, ctx->regs + SHADOWCON); | 741 | writel(val, ctx->regs + SHADOWCON); |
735 | } | 742 | } |
736 | 743 | ||
744 | static int fimd_power_on(struct fimd_context *ctx, bool enable) | ||
745 | { | ||
746 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | ||
747 | struct device *dev = subdrv->manager.dev; | ||
748 | |||
749 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
750 | |||
751 | if (enable != false && enable != true) | ||
752 | return -EINVAL; | ||
753 | |||
754 | if (enable) { | ||
755 | int ret; | ||
756 | |||
757 | ret = clk_enable(ctx->bus_clk); | ||
758 | if (ret < 0) | ||
759 | return ret; | ||
760 | |||
761 | ret = clk_enable(ctx->lcd_clk); | ||
762 | if (ret < 0) { | ||
763 | clk_disable(ctx->bus_clk); | ||
764 | return ret; | ||
765 | } | ||
766 | |||
767 | ctx->suspended = false; | ||
768 | |||
769 | /* if vblank was enabled status, enable it again. */ | ||
770 | if (test_and_clear_bit(0, &ctx->irq_flags)) | ||
771 | fimd_enable_vblank(dev); | ||
772 | |||
773 | fimd_apply(dev); | ||
774 | } else { | ||
775 | clk_disable(ctx->lcd_clk); | ||
776 | clk_disable(ctx->bus_clk); | ||
777 | |||
778 | ctx->suspended = true; | ||
779 | } | ||
780 | |||
781 | return 0; | ||
782 | } | ||
783 | |||
737 | static int __devinit fimd_probe(struct platform_device *pdev) | 784 | static int __devinit fimd_probe(struct platform_device *pdev) |
738 | { | 785 | { |
739 | struct device *dev = &pdev->dev; | 786 | struct device *dev = &pdev->dev; |
740 | struct fimd_context *ctx; | 787 | struct fimd_context *ctx; |
741 | struct exynos_drm_subdrv *subdrv; | 788 | struct exynos_drm_subdrv *subdrv; |
742 | struct exynos_drm_fimd_pdata *pdata; | 789 | struct exynos_drm_fimd_pdata *pdata; |
743 | struct fb_videomode *timing; | 790 | struct exynos_drm_panel_info *panel; |
744 | struct resource *res; | 791 | struct resource *res; |
745 | int win; | 792 | int win; |
746 | int ret = -EINVAL; | 793 | int ret = -EINVAL; |
@@ -753,9 +800,9 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
753 | return -EINVAL; | 800 | return -EINVAL; |
754 | } | 801 | } |
755 | 802 | ||
756 | timing = &pdata->timing; | 803 | panel = &pdata->panel; |
757 | if (!timing) { | 804 | if (!panel) { |
758 | dev_err(dev, "timing is null.\n"); | 805 | dev_err(dev, "panel is null.\n"); |
759 | return -EINVAL; | 806 | return -EINVAL; |
760 | } | 807 | } |
761 | 808 | ||
@@ -770,8 +817,6 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
770 | goto err_clk_get; | 817 | goto err_clk_get; |
771 | } | 818 | } |
772 | 819 | ||
773 | clk_enable(ctx->bus_clk); | ||
774 | |||
775 | ctx->lcd_clk = clk_get(dev, "sclk_fimd"); | 820 | ctx->lcd_clk = clk_get(dev, "sclk_fimd"); |
776 | if (IS_ERR(ctx->lcd_clk)) { | 821 | if (IS_ERR(ctx->lcd_clk)) { |
777 | dev_err(dev, "failed to get lcd clock\n"); | 822 | dev_err(dev, "failed to get lcd clock\n"); |
@@ -779,8 +824,6 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
779 | goto err_bus_clk; | 824 | goto err_bus_clk; |
780 | } | 825 | } |
781 | 826 | ||
782 | clk_enable(ctx->lcd_clk); | ||
783 | |||
784 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 827 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
785 | if (!res) { | 828 | if (!res) { |
786 | dev_err(dev, "failed to find registers\n"); | 829 | dev_err(dev, "failed to find registers\n"); |
@@ -817,16 +860,10 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
817 | goto err_req_irq; | 860 | goto err_req_irq; |
818 | } | 861 | } |
819 | 862 | ||
820 | ctx->clkdiv = fimd_calc_clkdiv(ctx, timing); | ||
821 | ctx->vidcon0 = pdata->vidcon0; | 863 | ctx->vidcon0 = pdata->vidcon0; |
822 | ctx->vidcon1 = pdata->vidcon1; | 864 | ctx->vidcon1 = pdata->vidcon1; |
823 | ctx->default_win = pdata->default_win; | 865 | ctx->default_win = pdata->default_win; |
824 | ctx->timing = timing; | 866 | ctx->panel = panel; |
825 | |||
826 | timing->pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv; | ||
827 | |||
828 | DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n", | ||
829 | timing->pixclock, ctx->clkdiv); | ||
830 | 867 | ||
831 | subdrv = &ctx->subdrv; | 868 | subdrv = &ctx->subdrv; |
832 | 869 | ||
@@ -842,10 +879,15 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
842 | 879 | ||
843 | platform_set_drvdata(pdev, ctx); | 880 | platform_set_drvdata(pdev, ctx); |
844 | 881 | ||
845 | pm_runtime_set_active(dev); | ||
846 | pm_runtime_enable(dev); | 882 | pm_runtime_enable(dev); |
847 | pm_runtime_get_sync(dev); | 883 | pm_runtime_get_sync(dev); |
848 | 884 | ||
885 | ctx->clkdiv = fimd_calc_clkdiv(ctx, &panel->timing); | ||
886 | panel->timing.pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv; | ||
887 | |||
888 | DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n", | ||
889 | panel->timing.pixclock, ctx->clkdiv); | ||
890 | |||
849 | for (win = 0; win < WINDOWS_NR; win++) | 891 | for (win = 0; win < WINDOWS_NR; win++) |
850 | fimd_clear_win(ctx, win); | 892 | fimd_clear_win(ctx, win); |
851 | 893 | ||
@@ -911,39 +953,30 @@ out: | |||
911 | #ifdef CONFIG_PM_SLEEP | 953 | #ifdef CONFIG_PM_SLEEP |
912 | static int fimd_suspend(struct device *dev) | 954 | static int fimd_suspend(struct device *dev) |
913 | { | 955 | { |
914 | int ret; | 956 | struct fimd_context *ctx = get_fimd_context(dev); |
915 | 957 | ||
916 | if (pm_runtime_suspended(dev)) | 958 | if (pm_runtime_suspended(dev)) |
917 | return 0; | 959 | return 0; |
918 | 960 | ||
919 | ret = pm_runtime_suspend(dev); | 961 | /* |
920 | if (ret < 0) | 962 | * do not use pm_runtime_suspend(). if pm_runtime_suspend() is |
921 | return ret; | 963 | * called here, an error would be returned by that interface |
922 | 964 | * because the usage_count of pm runtime is more than 1. | |
923 | return 0; | 965 | */ |
966 | return fimd_power_on(ctx, false); | ||
924 | } | 967 | } |
925 | 968 | ||
926 | static int fimd_resume(struct device *dev) | 969 | static int fimd_resume(struct device *dev) |
927 | { | 970 | { |
928 | int ret; | 971 | struct fimd_context *ctx = get_fimd_context(dev); |
929 | |||
930 | ret = pm_runtime_resume(dev); | ||
931 | if (ret < 0) { | ||
932 | DRM_ERROR("failed to resume runtime pm.\n"); | ||
933 | return ret; | ||
934 | } | ||
935 | |||
936 | pm_runtime_disable(dev); | ||
937 | |||
938 | ret = pm_runtime_set_active(dev); | ||
939 | if (ret < 0) { | ||
940 | DRM_ERROR("failed to active runtime pm.\n"); | ||
941 | pm_runtime_enable(dev); | ||
942 | pm_runtime_suspend(dev); | ||
943 | return ret; | ||
944 | } | ||
945 | 972 | ||
946 | pm_runtime_enable(dev); | 973 | /* |
974 | * if entered to sleep when lcd panel was on, the usage_count | ||
975 | * of pm runtime would still be 1 so in this case, fimd driver | ||
976 | * should be on directly not drawing on pm runtime interface. | ||
977 | */ | ||
978 | if (!pm_runtime_suspended(dev)) | ||
979 | return fimd_power_on(ctx, true); | ||
947 | 980 | ||
948 | return 0; | 981 | return 0; |
949 | } | 982 | } |
@@ -956,39 +989,16 @@ static int fimd_runtime_suspend(struct device *dev) | |||
956 | 989 | ||
957 | DRM_DEBUG_KMS("%s\n", __FILE__); | 990 | DRM_DEBUG_KMS("%s\n", __FILE__); |
958 | 991 | ||
959 | clk_disable(ctx->lcd_clk); | 992 | return fimd_power_on(ctx, false); |
960 | clk_disable(ctx->bus_clk); | ||
961 | |||
962 | ctx->suspended = true; | ||
963 | return 0; | ||
964 | } | 993 | } |
965 | 994 | ||
966 | static int fimd_runtime_resume(struct device *dev) | 995 | static int fimd_runtime_resume(struct device *dev) |
967 | { | 996 | { |
968 | struct fimd_context *ctx = get_fimd_context(dev); | 997 | struct fimd_context *ctx = get_fimd_context(dev); |
969 | int ret; | ||
970 | 998 | ||
971 | DRM_DEBUG_KMS("%s\n", __FILE__); | 999 | DRM_DEBUG_KMS("%s\n", __FILE__); |
972 | 1000 | ||
973 | ret = clk_enable(ctx->bus_clk); | 1001 | return fimd_power_on(ctx, true); |
974 | if (ret < 0) | ||
975 | return ret; | ||
976 | |||
977 | ret = clk_enable(ctx->lcd_clk); | ||
978 | if (ret < 0) { | ||
979 | clk_disable(ctx->bus_clk); | ||
980 | return ret; | ||
981 | } | ||
982 | |||
983 | ctx->suspended = false; | ||
984 | |||
985 | /* if vblank was enabled status, enable it again. */ | ||
986 | if (test_and_clear_bit(0, &ctx->irq_flags)) | ||
987 | fimd_enable_vblank(dev); | ||
988 | |||
989 | fimd_apply(dev); | ||
990 | |||
991 | return 0; | ||
992 | } | 1002 | } |
993 | #endif | 1003 | #endif |
994 | 1004 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index f48f7ce92f5f..3429d3fd93f3 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -1116,8 +1116,8 @@ err_ddc: | |||
1116 | err_iomap: | 1116 | err_iomap: |
1117 | iounmap(hdata->regs); | 1117 | iounmap(hdata->regs); |
1118 | err_req_region: | 1118 | err_req_region: |
1119 | release_resource(hdata->regs_res); | 1119 | release_mem_region(hdata->regs_res->start, |
1120 | kfree(hdata->regs_res); | 1120 | resource_size(hdata->regs_res)); |
1121 | err_resource: | 1121 | err_resource: |
1122 | hdmi_resources_cleanup(hdata); | 1122 | hdmi_resources_cleanup(hdata); |
1123 | err_data: | 1123 | err_data: |
@@ -1145,8 +1145,8 @@ static int __devexit hdmi_remove(struct platform_device *pdev) | |||
1145 | 1145 | ||
1146 | iounmap(hdata->regs); | 1146 | iounmap(hdata->regs); |
1147 | 1147 | ||
1148 | release_resource(hdata->regs_res); | 1148 | release_mem_region(hdata->regs_res->start, |
1149 | kfree(hdata->regs_res); | 1149 | resource_size(hdata->regs_res)); |
1150 | 1150 | ||
1151 | /* hdmiphy i2c driver */ | 1151 | /* hdmiphy i2c driver */ |
1152 | i2c_del_driver(&hdmiphy_driver); | 1152 | i2c_del_driver(&hdmiphy_driver); |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index ac24cff39775..93846e810e38 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
@@ -712,7 +712,12 @@ static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc) | |||
712 | } | 712 | } |
713 | 713 | ||
714 | if (is_checked) | 714 | if (is_checked) |
715 | drm_vblank_put(drm_dev, crtc); | 715 | /* |
716 | * call drm_vblank_put only in case that drm_vblank_get was | ||
717 | * called. | ||
718 | */ | ||
719 | if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0) | ||
720 | drm_vblank_put(drm_dev, crtc); | ||
716 | 721 | ||
717 | spin_unlock_irqrestore(&drm_dev->event_lock, flags); | 722 | spin_unlock_irqrestore(&drm_dev->event_lock, flags); |
718 | } | 723 | } |
@@ -779,15 +784,15 @@ static void mixer_win_reset(struct mixer_context *ctx) | |||
779 | mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST, | 784 | mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST, |
780 | MXR_STATUS_BURST_MASK); | 785 | MXR_STATUS_BURST_MASK); |
781 | 786 | ||
782 | /* setting default layer priority: layer1 > video > layer0 | 787 | /* setting default layer priority: layer1 > layer0 > video |
783 | * because typical usage scenario would be | 788 | * because typical usage scenario would be |
789 | * layer1 - OSD | ||
784 | * layer0 - framebuffer | 790 | * layer0 - framebuffer |
785 | * video - video overlay | 791 | * video - video overlay |
786 | * layer1 - OSD | ||
787 | */ | 792 | */ |
788 | val = MXR_LAYER_CFG_GRP0_VAL(1); | 793 | val = MXR_LAYER_CFG_GRP1_VAL(3); |
789 | val |= MXR_LAYER_CFG_VP_VAL(2); | 794 | val |= MXR_LAYER_CFG_GRP0_VAL(2); |
790 | val |= MXR_LAYER_CFG_GRP1_VAL(3); | 795 | val |= MXR_LAYER_CFG_VP_VAL(1); |
791 | mixer_reg_write(res, MXR_LAYER_CFG, val); | 796 | mixer_reg_write(res, MXR_LAYER_CFG, val); |
792 | 797 | ||
793 | /* setting background color */ | 798 | /* setting background color */ |
@@ -1044,7 +1049,7 @@ static int mixer_remove(struct platform_device *pdev) | |||
1044 | platform_get_drvdata(pdev); | 1049 | platform_get_drvdata(pdev); |
1045 | struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx; | 1050 | struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx; |
1046 | 1051 | ||
1047 | dev_info(dev, "remove sucessful\n"); | 1052 | dev_info(dev, "remove successful\n"); |
1048 | 1053 | ||
1049 | mixer_resource_poweroff(ctx); | 1054 | mixer_resource_poweroff(ctx); |
1050 | mixer_resources_cleanup(ctx); | 1055 | mixer_resources_cleanup(ctx); |
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c index 4a5b099c3bc5..53404af2e748 100644 --- a/drivers/gpu/drm/gma500/cdv_device.c +++ b/drivers/gpu/drm/gma500/cdv_device.c | |||
@@ -321,6 +321,8 @@ static int cdv_chip_setup(struct drm_device *dev) | |||
321 | cdv_get_core_freq(dev); | 321 | cdv_get_core_freq(dev); |
322 | gma_intel_opregion_init(dev); | 322 | gma_intel_opregion_init(dev); |
323 | psb_intel_init_bios(dev); | 323 | psb_intel_init_bios(dev); |
324 | REG_WRITE(PORT_HOTPLUG_EN, 0); | ||
325 | REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT)); | ||
324 | return 0; | 326 | return 0; |
325 | } | 327 | } |
326 | 328 | ||
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 791c0ef1a65b..be616735ec91 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c | |||
@@ -113,12 +113,12 @@ static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info) | |||
113 | 113 | ||
114 | void psbfb_suspend(struct drm_device *dev) | 114 | void psbfb_suspend(struct drm_device *dev) |
115 | { | 115 | { |
116 | struct drm_framebuffer *fb = 0; | 116 | struct drm_framebuffer *fb; |
117 | struct psb_framebuffer *psbfb = to_psb_fb(fb); | ||
118 | 117 | ||
119 | console_lock(); | 118 | console_lock(); |
120 | mutex_lock(&dev->mode_config.mutex); | 119 | mutex_lock(&dev->mode_config.mutex); |
121 | list_for_each_entry(fb, &dev->mode_config.fb_list, head) { | 120 | list_for_each_entry(fb, &dev->mode_config.fb_list, head) { |
121 | struct psb_framebuffer *psbfb = to_psb_fb(fb); | ||
122 | struct fb_info *info = psbfb->fbdev; | 122 | struct fb_info *info = psbfb->fbdev; |
123 | fb_set_suspend(info, 1); | 123 | fb_set_suspend(info, 1); |
124 | drm_fb_helper_blank(FB_BLANK_POWERDOWN, info); | 124 | drm_fb_helper_blank(FB_BLANK_POWERDOWN, info); |
@@ -129,12 +129,12 @@ void psbfb_suspend(struct drm_device *dev) | |||
129 | 129 | ||
130 | void psbfb_resume(struct drm_device *dev) | 130 | void psbfb_resume(struct drm_device *dev) |
131 | { | 131 | { |
132 | struct drm_framebuffer *fb = 0; | 132 | struct drm_framebuffer *fb; |
133 | struct psb_framebuffer *psbfb = to_psb_fb(fb); | ||
134 | 133 | ||
135 | console_lock(); | 134 | console_lock(); |
136 | mutex_lock(&dev->mode_config.mutex); | 135 | mutex_lock(&dev->mode_config.mutex); |
137 | list_for_each_entry(fb, &dev->mode_config.fb_list, head) { | 136 | list_for_each_entry(fb, &dev->mode_config.fb_list, head) { |
137 | struct psb_framebuffer *psbfb = to_psb_fb(fb); | ||
138 | struct fb_info *info = psbfb->fbdev; | 138 | struct fb_info *info = psbfb->fbdev; |
139 | fb_set_suspend(info, 0); | 139 | fb_set_suspend(info, 0); |
140 | drm_fb_helper_blank(FB_BLANK_UNBLANK, info); | 140 | drm_fb_helper_blank(FB_BLANK_UNBLANK, info); |
@@ -247,7 +247,6 @@ static struct fb_ops psbfb_roll_ops = { | |||
247 | .fb_imageblit = cfb_imageblit, | 247 | .fb_imageblit = cfb_imageblit, |
248 | .fb_pan_display = psbfb_pan, | 248 | .fb_pan_display = psbfb_pan, |
249 | .fb_mmap = psbfb_mmap, | 249 | .fb_mmap = psbfb_mmap, |
250 | .fb_sync = psbfb_sync, | ||
251 | .fb_ioctl = psbfb_ioctl, | 250 | .fb_ioctl = psbfb_ioctl, |
252 | }; | 251 | }; |
253 | 252 | ||
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index e770bd190a5c..aff194fbe9f3 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c | |||
@@ -20,6 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <drm/drmP.h> | 22 | #include <drm/drmP.h> |
23 | #include <linux/shmem_fs.h> | ||
23 | #include "psb_drv.h" | 24 | #include "psb_drv.h" |
24 | 25 | ||
25 | 26 | ||
@@ -203,9 +204,7 @@ static int psb_gtt_attach_pages(struct gtt_range *gt) | |||
203 | gt->npage = pages; | 204 | gt->npage = pages; |
204 | 205 | ||
205 | for (i = 0; i < pages; i++) { | 206 | for (i = 0; i < pages; i++) { |
206 | /* FIXME: needs updating as per mail from Hugh Dickins */ | 207 | p = shmem_read_mapping_page(mapping, i); |
207 | p = read_cache_page_gfp(mapping, i, | ||
208 | __GFP_COLD | GFP_KERNEL); | ||
209 | if (IS_ERR(p)) | 208 | if (IS_ERR(p)) |
210 | goto err; | 209 | goto err; |
211 | gt->pages[i] = p; | 210 | gt->pages[i] = p; |
@@ -447,10 +446,9 @@ int psb_gtt_init(struct drm_device *dev, int resume) | |||
447 | pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); | 446 | pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); |
448 | gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) | 447 | gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) |
449 | >> PAGE_SHIFT; | 448 | >> PAGE_SHIFT; |
450 | /* Some CDV firmware doesn't report this currently. In which case the | 449 | /* CDV doesn't report this. In which case the system has 64 gtt pages */ |
451 | system has 64 gtt pages */ | ||
452 | if (pg->gtt_start == 0 || gtt_pages == 0) { | 450 | if (pg->gtt_start == 0 || gtt_pages == 0) { |
453 | dev_err(dev->dev, "GTT PCI BAR not initialized.\n"); | 451 | dev_dbg(dev->dev, "GTT PCI BAR not initialized.\n"); |
454 | gtt_pages = 64; | 452 | gtt_pages = 64; |
455 | pg->gtt_start = dev_priv->pge_ctl; | 453 | pg->gtt_start = dev_priv->pge_ctl; |
456 | } | 454 | } |
@@ -462,10 +460,10 @@ int psb_gtt_init(struct drm_device *dev, int resume) | |||
462 | 460 | ||
463 | if (pg->gatt_pages == 0 || pg->gatt_start == 0) { | 461 | if (pg->gatt_pages == 0 || pg->gatt_start == 0) { |
464 | static struct resource fudge; /* Preferably peppermint */ | 462 | static struct resource fudge; /* Preferably peppermint */ |
465 | /* This can occur on CDV SDV systems. Fudge it in this case. | 463 | /* This can occur on CDV systems. Fudge it in this case. |
466 | We really don't care what imaginary space is being allocated | 464 | We really don't care what imaginary space is being allocated |
467 | at this point */ | 465 | at this point */ |
468 | dev_err(dev->dev, "GATT PCI BAR not initialized.\n"); | 466 | dev_dbg(dev->dev, "GATT PCI BAR not initialized.\n"); |
469 | pg->gatt_start = 0x40000000; | 467 | pg->gatt_start = 0x40000000; |
470 | pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT; | 468 | pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT; |
471 | /* This is a little confusing but in fact the GTT is providing | 469 | /* This is a little confusing but in fact the GTT is providing |
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index f7c17b239833..7f4b4e10246e 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
@@ -886,7 +886,7 @@ static int i810_flush_queue(struct drm_device *dev) | |||
886 | } | 886 | } |
887 | 887 | ||
888 | /* Must be called with the lock held */ | 888 | /* Must be called with the lock held */ |
889 | void i810_driver_reclaim_buffers(struct drm_device *dev, | 889 | static void i810_reclaim_buffers(struct drm_device *dev, |
890 | struct drm_file *file_priv) | 890 | struct drm_file *file_priv) |
891 | { | 891 | { |
892 | struct drm_device_dma *dma = dev->dma; | 892 | struct drm_device_dma *dma = dev->dma; |
@@ -1223,17 +1223,12 @@ void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) | |||
1223 | if (dev_priv->page_flipping) | 1223 | if (dev_priv->page_flipping) |
1224 | i810_do_cleanup_pageflip(dev); | 1224 | i810_do_cleanup_pageflip(dev); |
1225 | } | 1225 | } |
1226 | } | ||
1226 | 1227 | ||
1227 | if (file_priv->master && file_priv->master->lock.hw_lock) { | 1228 | void i810_driver_reclaim_buffers_locked(struct drm_device *dev, |
1228 | drm_idlelock_take(&file_priv->master->lock); | 1229 | struct drm_file *file_priv) |
1229 | i810_driver_reclaim_buffers(dev, file_priv); | 1230 | { |
1230 | drm_idlelock_release(&file_priv->master->lock); | 1231 | i810_reclaim_buffers(dev, file_priv); |
1231 | } else { | ||
1232 | /* master disappeared, clean up stuff anyway and hope nothing | ||
1233 | * goes wrong */ | ||
1234 | i810_driver_reclaim_buffers(dev, file_priv); | ||
1235 | } | ||
1236 | |||
1237 | } | 1232 | } |
1238 | 1233 | ||
1239 | int i810_driver_dma_quiescent(struct drm_device *dev) | 1234 | int i810_driver_dma_quiescent(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index 053f1ee58393..ec12f7dc717a 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c | |||
@@ -63,6 +63,7 @@ static struct drm_driver driver = { | |||
63 | .lastclose = i810_driver_lastclose, | 63 | .lastclose = i810_driver_lastclose, |
64 | .preclose = i810_driver_preclose, | 64 | .preclose = i810_driver_preclose, |
65 | .device_is_agp = i810_driver_device_is_agp, | 65 | .device_is_agp = i810_driver_device_is_agp, |
66 | .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked, | ||
66 | .dma_quiescent = i810_driver_dma_quiescent, | 67 | .dma_quiescent = i810_driver_dma_quiescent, |
67 | .ioctls = i810_ioctls, | 68 | .ioctls = i810_ioctls, |
68 | .fops = &i810_driver_fops, | 69 | .fops = &i810_driver_fops, |
diff --git a/drivers/gpu/drm/i810/i810_drv.h b/drivers/gpu/drm/i810/i810_drv.h index 6e0acad9e0f5..c9339f481795 100644 --- a/drivers/gpu/drm/i810/i810_drv.h +++ b/drivers/gpu/drm/i810/i810_drv.h | |||
@@ -116,12 +116,14 @@ typedef struct drm_i810_private { | |||
116 | 116 | ||
117 | /* i810_dma.c */ | 117 | /* i810_dma.c */ |
118 | extern int i810_driver_dma_quiescent(struct drm_device *dev); | 118 | extern int i810_driver_dma_quiescent(struct drm_device *dev); |
119 | void i810_driver_reclaim_buffers(struct drm_device *dev, | 119 | extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, |
120 | struct drm_file *file_priv); | 120 | struct drm_file *file_priv); |
121 | extern int i810_driver_load(struct drm_device *, unsigned long flags); | 121 | extern int i810_driver_load(struct drm_device *, unsigned long flags); |
122 | extern void i810_driver_lastclose(struct drm_device *dev); | 122 | extern void i810_driver_lastclose(struct drm_device *dev); |
123 | extern void i810_driver_preclose(struct drm_device *dev, | 123 | extern void i810_driver_preclose(struct drm_device *dev, |
124 | struct drm_file *file_priv); | 124 | struct drm_file *file_priv); |
125 | extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, | ||
126 | struct drm_file *file_priv); | ||
125 | extern int i810_driver_device_is_agp(struct drm_device *dev); | 127 | extern int i810_driver_device_is_agp(struct drm_device *dev); |
126 | 128 | ||
127 | extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | 129 | extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 11807989f918..deaa657292b4 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -121,11 +121,11 @@ static const char *cache_level_str(int type) | |||
121 | static void | 121 | static void |
122 | describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | 122 | describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) |
123 | { | 123 | { |
124 | seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s%s", | 124 | seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d%s%s%s", |
125 | &obj->base, | 125 | &obj->base, |
126 | get_pin_flag(obj), | 126 | get_pin_flag(obj), |
127 | get_tiling_flag(obj), | 127 | get_tiling_flag(obj), |
128 | obj->base.size, | 128 | obj->base.size / 1024, |
129 | obj->base.read_domains, | 129 | obj->base.read_domains, |
130 | obj->base.write_domain, | 130 | obj->base.write_domain, |
131 | obj->last_rendering_seqno, | 131 | obj->last_rendering_seqno, |
@@ -653,7 +653,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
653 | seq_printf(m, " Size : %08x\n", ring->size); | 653 | seq_printf(m, " Size : %08x\n", ring->size); |
654 | seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring)); | 654 | seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring)); |
655 | seq_printf(m, " NOPID : %08x\n", I915_READ_NOPID(ring)); | 655 | seq_printf(m, " NOPID : %08x\n", I915_READ_NOPID(ring)); |
656 | if (IS_GEN6(dev)) { | 656 | if (IS_GEN6(dev) || IS_GEN7(dev)) { |
657 | seq_printf(m, " Sync 0 : %08x\n", I915_READ_SYNC_0(ring)); | 657 | seq_printf(m, " Sync 0 : %08x\n", I915_READ_SYNC_0(ring)); |
658 | seq_printf(m, " Sync 1 : %08x\n", I915_READ_SYNC_1(ring)); | 658 | seq_printf(m, " Sync 1 : %08x\n", I915_READ_SYNC_1(ring)); |
659 | } | 659 | } |
@@ -1075,6 +1075,7 @@ static int gen6_drpc_info(struct seq_file *m) | |||
1075 | struct drm_device *dev = node->minor->dev; | 1075 | struct drm_device *dev = node->minor->dev; |
1076 | struct drm_i915_private *dev_priv = dev->dev_private; | 1076 | struct drm_i915_private *dev_priv = dev->dev_private; |
1077 | u32 rpmodectl1, gt_core_status, rcctl1; | 1077 | u32 rpmodectl1, gt_core_status, rcctl1; |
1078 | unsigned forcewake_count; | ||
1078 | int count=0, ret; | 1079 | int count=0, ret; |
1079 | 1080 | ||
1080 | 1081 | ||
@@ -1082,9 +1083,13 @@ static int gen6_drpc_info(struct seq_file *m) | |||
1082 | if (ret) | 1083 | if (ret) |
1083 | return ret; | 1084 | return ret; |
1084 | 1085 | ||
1085 | if (atomic_read(&dev_priv->forcewake_count)) { | 1086 | spin_lock_irq(&dev_priv->gt_lock); |
1086 | seq_printf(m, "RC information inaccurate because userspace " | 1087 | forcewake_count = dev_priv->forcewake_count; |
1087 | "holds a reference \n"); | 1088 | spin_unlock_irq(&dev_priv->gt_lock); |
1089 | |||
1090 | if (forcewake_count) { | ||
1091 | seq_printf(m, "RC information inaccurate because somebody " | ||
1092 | "holds a forcewake reference \n"); | ||
1088 | } else { | 1093 | } else { |
1089 | /* NB: we cannot use forcewake, else we read the wrong values */ | 1094 | /* NB: we cannot use forcewake, else we read the wrong values */ |
1090 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) | 1095 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) |
@@ -1106,7 +1111,7 @@ static int gen6_drpc_info(struct seq_file *m) | |||
1106 | seq_printf(m, "SW control enabled: %s\n", | 1111 | seq_printf(m, "SW control enabled: %s\n", |
1107 | yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) == | 1112 | yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) == |
1108 | GEN6_RP_MEDIA_SW_MODE)); | 1113 | GEN6_RP_MEDIA_SW_MODE)); |
1109 | seq_printf(m, "RC6 Enabled: %s\n", | 1114 | seq_printf(m, "RC1e Enabled: %s\n", |
1110 | yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE)); | 1115 | yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE)); |
1111 | seq_printf(m, "RC6 Enabled: %s\n", | 1116 | seq_printf(m, "RC6 Enabled: %s\n", |
1112 | yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE)); | 1117 | yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE)); |
@@ -1398,9 +1403,13 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) | |||
1398 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 1403 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
1399 | struct drm_device *dev = node->minor->dev; | 1404 | struct drm_device *dev = node->minor->dev; |
1400 | struct drm_i915_private *dev_priv = dev->dev_private; | 1405 | struct drm_i915_private *dev_priv = dev->dev_private; |
1406 | unsigned forcewake_count; | ||
1407 | |||
1408 | spin_lock_irq(&dev_priv->gt_lock); | ||
1409 | forcewake_count = dev_priv->forcewake_count; | ||
1410 | spin_unlock_irq(&dev_priv->gt_lock); | ||
1401 | 1411 | ||
1402 | seq_printf(m, "forcewake count = %d\n", | 1412 | seq_printf(m, "forcewake count = %u\n", forcewake_count); |
1403 | atomic_read(&dev_priv->forcewake_count)); | ||
1404 | 1413 | ||
1405 | return 0; | 1414 | return 0; |
1406 | } | 1415 | } |
@@ -1665,7 +1674,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file) | |||
1665 | struct drm_i915_private *dev_priv = dev->dev_private; | 1674 | struct drm_i915_private *dev_priv = dev->dev_private; |
1666 | int ret; | 1675 | int ret; |
1667 | 1676 | ||
1668 | if (!IS_GEN6(dev)) | 1677 | if (INTEL_INFO(dev)->gen < 6) |
1669 | return 0; | 1678 | return 0; |
1670 | 1679 | ||
1671 | ret = mutex_lock_interruptible(&dev->struct_mutex); | 1680 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
@@ -1682,7 +1691,7 @@ int i915_forcewake_release(struct inode *inode, struct file *file) | |||
1682 | struct drm_device *dev = inode->i_private; | 1691 | struct drm_device *dev = inode->i_private; |
1683 | struct drm_i915_private *dev_priv = dev->dev_private; | 1692 | struct drm_i915_private *dev_priv = dev->dev_private; |
1684 | 1693 | ||
1685 | if (!IS_GEN6(dev)) | 1694 | if (INTEL_INFO(dev)->gen < 6) |
1686 | return 0; | 1695 | return 0; |
1687 | 1696 | ||
1688 | /* | 1697 | /* |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 5f4d5893e983..ddfe3d902b2a 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -2045,6 +2045,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2045 | if (!IS_I945G(dev) && !IS_I945GM(dev)) | 2045 | if (!IS_I945G(dev) && !IS_I945GM(dev)) |
2046 | pci_enable_msi(dev->pdev); | 2046 | pci_enable_msi(dev->pdev); |
2047 | 2047 | ||
2048 | spin_lock_init(&dev_priv->gt_lock); | ||
2048 | spin_lock_init(&dev_priv->irq_lock); | 2049 | spin_lock_init(&dev_priv->irq_lock); |
2049 | spin_lock_init(&dev_priv->error_lock); | 2050 | spin_lock_init(&dev_priv->error_lock); |
2050 | spin_lock_init(&dev_priv->rps_lock); | 2051 | spin_lock_init(&dev_priv->rps_lock); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 8f7187915b0d..308f81913562 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -368,11 +368,12 @@ void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) | |||
368 | */ | 368 | */ |
369 | void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | 369 | void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) |
370 | { | 370 | { |
371 | WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); | 371 | unsigned long irqflags; |
372 | 372 | ||
373 | /* Forcewake is atomic in case we get in here without the lock */ | 373 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); |
374 | if (atomic_add_return(1, &dev_priv->forcewake_count) == 1) | 374 | if (dev_priv->forcewake_count++ == 0) |
375 | dev_priv->display.force_wake_get(dev_priv); | 375 | dev_priv->display.force_wake_get(dev_priv); |
376 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); | ||
376 | } | 377 | } |
377 | 378 | ||
378 | void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | 379 | void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
@@ -392,10 +393,12 @@ void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) | |||
392 | */ | 393 | */ |
393 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | 394 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
394 | { | 395 | { |
395 | WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); | 396 | unsigned long irqflags; |
396 | 397 | ||
397 | if (atomic_dec_and_test(&dev_priv->forcewake_count)) | 398 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); |
399 | if (--dev_priv->forcewake_count == 0) | ||
398 | dev_priv->display.force_wake_put(dev_priv); | 400 | dev_priv->display.force_wake_put(dev_priv); |
401 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); | ||
399 | } | 402 | } |
400 | 403 | ||
401 | void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) | 404 | void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) |
@@ -597,9 +600,36 @@ static int ironlake_do_reset(struct drm_device *dev, u8 flags) | |||
597 | static int gen6_do_reset(struct drm_device *dev, u8 flags) | 600 | static int gen6_do_reset(struct drm_device *dev, u8 flags) |
598 | { | 601 | { |
599 | struct drm_i915_private *dev_priv = dev->dev_private; | 602 | struct drm_i915_private *dev_priv = dev->dev_private; |
603 | int ret; | ||
604 | unsigned long irqflags; | ||
600 | 605 | ||
601 | I915_WRITE(GEN6_GDRST, GEN6_GRDOM_FULL); | 606 | /* Hold gt_lock across reset to prevent any register access |
602 | return wait_for((I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); | 607 | * with forcewake not set correctly |
608 | */ | ||
609 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); | ||
610 | |||
611 | /* Reset the chip */ | ||
612 | |||
613 | /* GEN6_GDRST is not in the gt power well, no need to check | ||
614 | * for fifo space for the write or forcewake the chip for | ||
615 | * the read | ||
616 | */ | ||
617 | I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL); | ||
618 | |||
619 | /* Spin waiting for the device to ack the reset request */ | ||
620 | ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); | ||
621 | |||
622 | /* If reset with a user forcewake, try to restore, otherwise turn it off */ | ||
623 | if (dev_priv->forcewake_count) | ||
624 | dev_priv->display.force_wake_get(dev_priv); | ||
625 | else | ||
626 | dev_priv->display.force_wake_put(dev_priv); | ||
627 | |||
628 | /* Restore fifo count */ | ||
629 | dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); | ||
630 | |||
631 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); | ||
632 | return ret; | ||
603 | } | 633 | } |
604 | 634 | ||
605 | /** | 635 | /** |
@@ -643,9 +673,6 @@ int i915_reset(struct drm_device *dev, u8 flags) | |||
643 | case 7: | 673 | case 7: |
644 | case 6: | 674 | case 6: |
645 | ret = gen6_do_reset(dev, flags); | 675 | ret = gen6_do_reset(dev, flags); |
646 | /* If reset with a user forcewake, try to restore */ | ||
647 | if (atomic_read(&dev_priv->forcewake_count)) | ||
648 | __gen6_gt_force_wake_get(dev_priv); | ||
649 | break; | 676 | break; |
650 | case 5: | 677 | case 5: |
651 | ret = ironlake_do_reset(dev, flags); | 678 | ret = ironlake_do_reset(dev, flags); |
@@ -927,9 +954,14 @@ MODULE_LICENSE("GPL and additional rights"); | |||
927 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ | 954 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ |
928 | u##x val = 0; \ | 955 | u##x val = 0; \ |
929 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ | 956 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
930 | gen6_gt_force_wake_get(dev_priv); \ | 957 | unsigned long irqflags; \ |
958 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ | ||
959 | if (dev_priv->forcewake_count == 0) \ | ||
960 | dev_priv->display.force_wake_get(dev_priv); \ | ||
931 | val = read##y(dev_priv->regs + reg); \ | 961 | val = read##y(dev_priv->regs + reg); \ |
932 | gen6_gt_force_wake_put(dev_priv); \ | 962 | if (dev_priv->forcewake_count == 0) \ |
963 | dev_priv->display.force_wake_put(dev_priv); \ | ||
964 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ | ||
933 | } else { \ | 965 | } else { \ |
934 | val = read##y(dev_priv->regs + reg); \ | 966 | val = read##y(dev_priv->regs + reg); \ |
935 | } \ | 967 | } \ |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 602bc80baabb..9689ca38b2b3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -288,7 +288,13 @@ typedef struct drm_i915_private { | |||
288 | int relative_constants_mode; | 288 | int relative_constants_mode; |
289 | 289 | ||
290 | void __iomem *regs; | 290 | void __iomem *regs; |
291 | u32 gt_fifo_count; | 291 | /** gt_fifo_count and the subsequent register write are synchronized |
292 | * with dev->struct_mutex. */ | ||
293 | unsigned gt_fifo_count; | ||
294 | /** forcewake_count is protected by gt_lock */ | ||
295 | unsigned forcewake_count; | ||
296 | /** gt_lock is also taken in irq contexts. */ | ||
297 | struct spinlock gt_lock; | ||
292 | 298 | ||
293 | struct intel_gmbus { | 299 | struct intel_gmbus { |
294 | struct i2c_adapter adapter; | 300 | struct i2c_adapter adapter; |
@@ -741,8 +747,6 @@ typedef struct drm_i915_private { | |||
741 | 747 | ||
742 | struct drm_property *broadcast_rgb_property; | 748 | struct drm_property *broadcast_rgb_property; |
743 | struct drm_property *force_audio_property; | 749 | struct drm_property *force_audio_property; |
744 | |||
745 | atomic_t forcewake_count; | ||
746 | } drm_i915_private_t; | 750 | } drm_i915_private_t; |
747 | 751 | ||
748 | enum i915_cache_level { | 752 | enum i915_cache_level { |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5d433fc11ace..5bd4361ea84d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1751,7 +1751,8 @@ static void ironlake_irq_preinstall(struct drm_device *dev) | |||
1751 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); | 1751 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); |
1752 | 1752 | ||
1753 | I915_WRITE(HWSTAM, 0xeffe); | 1753 | I915_WRITE(HWSTAM, 0xeffe); |
1754 | if (IS_GEN6(dev) || IS_GEN7(dev)) { | 1754 | |
1755 | if (IS_GEN6(dev)) { | ||
1755 | /* Workaround stalls observed on Sandy Bridge GPUs by | 1756 | /* Workaround stalls observed on Sandy Bridge GPUs by |
1756 | * making the blitter command streamer generate a | 1757 | * making the blitter command streamer generate a |
1757 | * write to the Hardware Status Page for | 1758 | * write to the Hardware Status Page for |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c3afb783cb9d..558ac716a328 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -2689,7 +2689,7 @@ | |||
2689 | #define DVS_FORMAT_RGBX888 (2<<25) | 2689 | #define DVS_FORMAT_RGBX888 (2<<25) |
2690 | #define DVS_FORMAT_RGBX161616 (3<<25) | 2690 | #define DVS_FORMAT_RGBX161616 (3<<25) |
2691 | #define DVS_SOURCE_KEY (1<<22) | 2691 | #define DVS_SOURCE_KEY (1<<22) |
2692 | #define DVS_RGB_ORDER_RGBX (1<<20) | 2692 | #define DVS_RGB_ORDER_XBGR (1<<20) |
2693 | #define DVS_YUV_BYTE_ORDER_MASK (3<<16) | 2693 | #define DVS_YUV_BYTE_ORDER_MASK (3<<16) |
2694 | #define DVS_YUV_ORDER_YUYV (0<<16) | 2694 | #define DVS_YUV_ORDER_YUYV (0<<16) |
2695 | #define DVS_YUV_ORDER_UYVY (1<<16) | 2695 | #define DVS_YUV_ORDER_UYVY (1<<16) |
@@ -3028,6 +3028,20 @@ | |||
3028 | #define DISP_TILE_SURFACE_SWIZZLING (1<<13) | 3028 | #define DISP_TILE_SURFACE_SWIZZLING (1<<13) |
3029 | #define DISP_FBC_WM_DIS (1<<15) | 3029 | #define DISP_FBC_WM_DIS (1<<15) |
3030 | 3030 | ||
3031 | /* GEN7 chicken */ | ||
3032 | #define GEN7_COMMON_SLICE_CHICKEN1 0x7010 | ||
3033 | # define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC ((1<<10) | (1<<26)) | ||
3034 | |||
3035 | #define GEN7_L3CNTLREG1 0xB01C | ||
3036 | #define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C4FFF8C | ||
3037 | |||
3038 | #define GEN7_L3_CHICKEN_MODE_REGISTER 0xB030 | ||
3039 | #define GEN7_WA_L3_CHICKEN_MODE 0x20000000 | ||
3040 | |||
3041 | /* WaCatErrorRejectionIssue */ | ||
3042 | #define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG 0x9030 | ||
3043 | #define GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB (1<<11) | ||
3044 | |||
3031 | /* PCH */ | 3045 | /* PCH */ |
3032 | 3046 | ||
3033 | /* south display engine interrupt */ | 3047 | /* south display engine interrupt */ |
@@ -3618,6 +3632,7 @@ | |||
3618 | #define GT_FIFO_NUM_RESERVED_ENTRIES 20 | 3632 | #define GT_FIFO_NUM_RESERVED_ENTRIES 20 |
3619 | 3633 | ||
3620 | #define GEN6_UCGCTL2 0x9404 | 3634 | #define GEN6_UCGCTL2 0x9404 |
3635 | # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13) | ||
3621 | # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) | 3636 | # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) |
3622 | # define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11) | 3637 | # define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11) |
3623 | 3638 | ||
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 7886e4fb60e3..2b5eb229ff2c 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -28,14 +28,19 @@ | |||
28 | #include "drm.h" | 28 | #include "drm.h" |
29 | #include "i915_drm.h" | 29 | #include "i915_drm.h" |
30 | #include "intel_drv.h" | 30 | #include "intel_drv.h" |
31 | #include "i915_reg.h" | ||
31 | 32 | ||
32 | static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) | 33 | static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) |
33 | { | 34 | { |
34 | struct drm_i915_private *dev_priv = dev->dev_private; | 35 | struct drm_i915_private *dev_priv = dev->dev_private; |
35 | u32 dpll_reg; | 36 | u32 dpll_reg; |
36 | 37 | ||
38 | /* On IVB, 3rd pipe shares PLL with another one */ | ||
39 | if (pipe > 1) | ||
40 | return false; | ||
41 | |||
37 | if (HAS_PCH_SPLIT(dev)) | 42 | if (HAS_PCH_SPLIT(dev)) |
38 | dpll_reg = (pipe == PIPE_A) ? _PCH_DPLL_A : _PCH_DPLL_B; | 43 | dpll_reg = PCH_DPLL(pipe); |
39 | else | 44 | else |
40 | dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B; | 45 | dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B; |
41 | 46 | ||
@@ -822,7 +827,7 @@ int i915_save_state(struct drm_device *dev) | |||
822 | 827 | ||
823 | if (IS_IRONLAKE_M(dev)) | 828 | if (IS_IRONLAKE_M(dev)) |
824 | ironlake_disable_drps(dev); | 829 | ironlake_disable_drps(dev); |
825 | if (IS_GEN6(dev)) | 830 | if (INTEL_INFO(dev)->gen >= 6) |
826 | gen6_disable_rps(dev); | 831 | gen6_disable_rps(dev); |
827 | 832 | ||
828 | /* Cache mode state */ | 833 | /* Cache mode state */ |
@@ -881,7 +886,7 @@ int i915_restore_state(struct drm_device *dev) | |||
881 | intel_init_emon(dev); | 886 | intel_init_emon(dev); |
882 | } | 887 | } |
883 | 888 | ||
884 | if (IS_GEN6(dev)) { | 889 | if (INTEL_INFO(dev)->gen >= 6) { |
885 | gen6_enable_rps(dev_priv); | 890 | gen6_enable_rps(dev_priv); |
886 | gen6_update_ring_freq(dev_priv); | 891 | gen6_update_ring_freq(dev_priv); |
887 | } | 892 | } |
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 8af3735e27c6..dbda6e3bdf07 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h | |||
@@ -467,8 +467,12 @@ struct edp_link_params { | |||
467 | struct bdb_edp { | 467 | struct bdb_edp { |
468 | struct edp_power_seq power_seqs[16]; | 468 | struct edp_power_seq power_seqs[16]; |
469 | u32 color_depth; | 469 | u32 color_depth; |
470 | u32 sdrrs_msa_timing_delay; | ||
471 | struct edp_link_params link_params[16]; | 470 | struct edp_link_params link_params[16]; |
471 | u32 sdrrs_msa_timing_delay; | ||
472 | |||
473 | /* ith bit indicates enabled/disabled for (i+1)th panel */ | ||
474 | u16 edp_s3d_feature; | ||
475 | u16 edp_t3_optimization; | ||
472 | } __attribute__ ((packed)); | 476 | } __attribute__ ((packed)); |
473 | 477 | ||
474 | void intel_setup_bios(struct drm_device *dev); | 478 | void intel_setup_bios(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index fee0ad02c6d0..dd729d46a61f 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -24,6 +24,7 @@ | |||
24 | * Eric Anholt <eric@anholt.net> | 24 | * Eric Anholt <eric@anholt.net> |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/dmi.h> | ||
27 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
28 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
29 | #include "drmP.h" | 30 | #include "drmP.h" |
@@ -540,6 +541,24 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { | |||
540 | .destroy = intel_encoder_destroy, | 541 | .destroy = intel_encoder_destroy, |
541 | }; | 542 | }; |
542 | 543 | ||
544 | static int __init intel_no_crt_dmi_callback(const struct dmi_system_id *id) | ||
545 | { | ||
546 | DRM_DEBUG_KMS("Skipping CRT initialization for %s\n", id->ident); | ||
547 | return 1; | ||
548 | } | ||
549 | |||
550 | static const struct dmi_system_id intel_no_crt[] = { | ||
551 | { | ||
552 | .callback = intel_no_crt_dmi_callback, | ||
553 | .ident = "ACER ZGB", | ||
554 | .matches = { | ||
555 | DMI_MATCH(DMI_SYS_VENDOR, "ACER"), | ||
556 | DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), | ||
557 | }, | ||
558 | }, | ||
559 | { } | ||
560 | }; | ||
561 | |||
543 | void intel_crt_init(struct drm_device *dev) | 562 | void intel_crt_init(struct drm_device *dev) |
544 | { | 563 | { |
545 | struct drm_connector *connector; | 564 | struct drm_connector *connector; |
@@ -547,6 +566,10 @@ void intel_crt_init(struct drm_device *dev) | |||
547 | struct intel_connector *intel_connector; | 566 | struct intel_connector *intel_connector; |
548 | struct drm_i915_private *dev_priv = dev->dev_private; | 567 | struct drm_i915_private *dev_priv = dev->dev_private; |
549 | 568 | ||
569 | /* Skip machines without VGA that falsely report hotplug events */ | ||
570 | if (dmi_check_system(intel_no_crt)) | ||
571 | return; | ||
572 | |||
550 | crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL); | 573 | crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL); |
551 | if (!crt) | 574 | if (!crt) |
552 | return; | 575 | return; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2a3f707caab8..397087cf689e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1872,7 +1872,7 @@ static void intel_update_fbc(struct drm_device *dev) | |||
1872 | if (enable_fbc < 0) { | 1872 | if (enable_fbc < 0) { |
1873 | DRM_DEBUG_KMS("fbc set to per-chip default\n"); | 1873 | DRM_DEBUG_KMS("fbc set to per-chip default\n"); |
1874 | enable_fbc = 1; | 1874 | enable_fbc = 1; |
1875 | if (INTEL_INFO(dev)->gen <= 5) | 1875 | if (INTEL_INFO(dev)->gen <= 6) |
1876 | enable_fbc = 0; | 1876 | enable_fbc = 0; |
1877 | } | 1877 | } |
1878 | if (!enable_fbc) { | 1878 | if (!enable_fbc) { |
@@ -4680,8 +4680,17 @@ sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane, | |||
4680 | 4680 | ||
4681 | crtc = intel_get_crtc_for_plane(dev, plane); | 4681 | crtc = intel_get_crtc_for_plane(dev, plane); |
4682 | clock = crtc->mode.clock; | 4682 | clock = crtc->mode.clock; |
4683 | if (!clock) { | ||
4684 | *sprite_wm = 0; | ||
4685 | return false; | ||
4686 | } | ||
4683 | 4687 | ||
4684 | line_time_us = (sprite_width * 1000) / clock; | 4688 | line_time_us = (sprite_width * 1000) / clock; |
4689 | if (!line_time_us) { | ||
4690 | *sprite_wm = 0; | ||
4691 | return false; | ||
4692 | } | ||
4693 | |||
4685 | line_count = (latency_ns / line_time_us + 1000) / 1000; | 4694 | line_count = (latency_ns / line_time_us + 1000) / 1000; |
4686 | line_size = sprite_width * pixel_size; | 4695 | line_size = sprite_width * pixel_size; |
4687 | 4696 | ||
@@ -5307,6 +5316,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
5307 | } | 5316 | } |
5308 | } | 5317 | } |
5309 | 5318 | ||
5319 | pipeconf &= ~PIPECONF_INTERLACE_MASK; | ||
5310 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { | 5320 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { |
5311 | pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; | 5321 | pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; |
5312 | /* the chip adds 2 halflines automatically */ | 5322 | /* the chip adds 2 halflines automatically */ |
@@ -5317,7 +5327,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
5317 | adjusted_mode->crtc_vsync_end -= 1; | 5327 | adjusted_mode->crtc_vsync_end -= 1; |
5318 | adjusted_mode->crtc_vsync_start -= 1; | 5328 | adjusted_mode->crtc_vsync_start -= 1; |
5319 | } else | 5329 | } else |
5320 | pipeconf &= ~PIPECONF_INTERLACE_MASK; /* progressive */ | 5330 | pipeconf |= PIPECONF_PROGRESSIVE; |
5321 | 5331 | ||
5322 | I915_WRITE(HTOTAL(pipe), | 5332 | I915_WRITE(HTOTAL(pipe), |
5323 | (adjusted_mode->crtc_hdisplay - 1) | | 5333 | (adjusted_mode->crtc_hdisplay - 1) | |
@@ -5808,12 +5818,15 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5808 | if (is_lvds) { | 5818 | if (is_lvds) { |
5809 | temp = I915_READ(PCH_LVDS); | 5819 | temp = I915_READ(PCH_LVDS); |
5810 | temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; | 5820 | temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; |
5811 | if (HAS_PCH_CPT(dev)) | 5821 | if (HAS_PCH_CPT(dev)) { |
5822 | temp &= ~PORT_TRANS_SEL_MASK; | ||
5812 | temp |= PORT_TRANS_SEL_CPT(pipe); | 5823 | temp |= PORT_TRANS_SEL_CPT(pipe); |
5813 | else if (pipe == 1) | 5824 | } else { |
5814 | temp |= LVDS_PIPEB_SELECT; | 5825 | if (pipe == 1) |
5815 | else | 5826 | temp |= LVDS_PIPEB_SELECT; |
5816 | temp &= ~LVDS_PIPEB_SELECT; | 5827 | else |
5828 | temp &= ~LVDS_PIPEB_SELECT; | ||
5829 | } | ||
5817 | 5830 | ||
5818 | /* set the corresponsding LVDS_BORDER bit */ | 5831 | /* set the corresponsding LVDS_BORDER bit */ |
5819 | temp |= dev_priv->lvds_border_bits; | 5832 | temp |= dev_priv->lvds_border_bits; |
@@ -5899,6 +5912,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5899 | } | 5912 | } |
5900 | } | 5913 | } |
5901 | 5914 | ||
5915 | pipeconf &= ~PIPECONF_INTERLACE_MASK; | ||
5902 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { | 5916 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { |
5903 | pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; | 5917 | pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; |
5904 | /* the chip adds 2 halflines automatically */ | 5918 | /* the chip adds 2 halflines automatically */ |
@@ -5909,7 +5923,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5909 | adjusted_mode->crtc_vsync_end -= 1; | 5923 | adjusted_mode->crtc_vsync_end -= 1; |
5910 | adjusted_mode->crtc_vsync_start -= 1; | 5924 | adjusted_mode->crtc_vsync_start -= 1; |
5911 | } else | 5925 | } else |
5912 | pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */ | 5926 | pipeconf |= PIPECONF_PROGRESSIVE; |
5913 | 5927 | ||
5914 | I915_WRITE(HTOTAL(pipe), | 5928 | I915_WRITE(HTOTAL(pipe), |
5915 | (adjusted_mode->crtc_hdisplay - 1) | | 5929 | (adjusted_mode->crtc_hdisplay - 1) | |
@@ -6170,7 +6184,7 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) | |||
6170 | int i; | 6184 | int i; |
6171 | 6185 | ||
6172 | /* The clocks have to be on to load the palette. */ | 6186 | /* The clocks have to be on to load the palette. */ |
6173 | if (!crtc->enabled) | 6187 | if (!crtc->enabled || !intel_crtc->active) |
6174 | return; | 6188 | return; |
6175 | 6189 | ||
6176 | /* use legacy palette for Ironlake */ | 6190 | /* use legacy palette for Ironlake */ |
@@ -6556,7 +6570,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev, | |||
6556 | mode_cmd.height = mode->vdisplay; | 6570 | mode_cmd.height = mode->vdisplay; |
6557 | mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width, | 6571 | mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width, |
6558 | bpp); | 6572 | bpp); |
6559 | mode_cmd.pixel_format = 0; | 6573 | mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth); |
6560 | 6574 | ||
6561 | return intel_framebuffer_create(dev, &mode_cmd, obj); | 6575 | return intel_framebuffer_create(dev, &mode_cmd, obj); |
6562 | } | 6576 | } |
@@ -7814,6 +7828,7 @@ int intel_framebuffer_init(struct drm_device *dev, | |||
7814 | case DRM_FORMAT_RGB332: | 7828 | case DRM_FORMAT_RGB332: |
7815 | case DRM_FORMAT_RGB565: | 7829 | case DRM_FORMAT_RGB565: |
7816 | case DRM_FORMAT_XRGB8888: | 7830 | case DRM_FORMAT_XRGB8888: |
7831 | case DRM_FORMAT_XBGR8888: | ||
7817 | case DRM_FORMAT_ARGB8888: | 7832 | case DRM_FORMAT_ARGB8888: |
7818 | case DRM_FORMAT_XRGB2101010: | 7833 | case DRM_FORMAT_XRGB2101010: |
7819 | case DRM_FORMAT_ARGB2101010: | 7834 | case DRM_FORMAT_ARGB2101010: |
@@ -8179,8 +8194,8 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) | |||
8179 | I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ | 8194 | I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ |
8180 | 8195 | ||
8181 | if (intel_enable_rc6(dev_priv->dev)) | 8196 | if (intel_enable_rc6(dev_priv->dev)) |
8182 | rc6_mask = GEN6_RC_CTL_RC6p_ENABLE | | 8197 | rc6_mask = GEN6_RC_CTL_RC6_ENABLE | |
8183 | GEN6_RC_CTL_RC6_ENABLE; | 8198 | ((IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0); |
8184 | 8199 | ||
8185 | I915_WRITE(GEN6_RC_CONTROL, | 8200 | I915_WRITE(GEN6_RC_CONTROL, |
8186 | rc6_mask | | 8201 | rc6_mask | |
@@ -8458,12 +8473,32 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) | |||
8458 | I915_WRITE(WM2_LP_ILK, 0); | 8473 | I915_WRITE(WM2_LP_ILK, 0); |
8459 | I915_WRITE(WM1_LP_ILK, 0); | 8474 | I915_WRITE(WM1_LP_ILK, 0); |
8460 | 8475 | ||
8476 | /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. | ||
8477 | * This implements the WaDisableRCZUnitClockGating workaround. | ||
8478 | */ | ||
8479 | I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); | ||
8480 | |||
8461 | I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); | 8481 | I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); |
8462 | 8482 | ||
8463 | I915_WRITE(IVB_CHICKEN3, | 8483 | I915_WRITE(IVB_CHICKEN3, |
8464 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | | 8484 | CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | |
8465 | CHICKEN3_DGMG_DONE_FIX_DISABLE); | 8485 | CHICKEN3_DGMG_DONE_FIX_DISABLE); |
8466 | 8486 | ||
8487 | /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ | ||
8488 | I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, | ||
8489 | GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); | ||
8490 | |||
8491 | /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */ | ||
8492 | I915_WRITE(GEN7_L3CNTLREG1, | ||
8493 | GEN7_WA_FOR_GEN7_L3_CONTROL); | ||
8494 | I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, | ||
8495 | GEN7_WA_L3_CHICKEN_MODE); | ||
8496 | |||
8497 | /* This is required by WaCatErrorRejectionIssue */ | ||
8498 | I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, | ||
8499 | I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | | ||
8500 | GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); | ||
8501 | |||
8467 | for_each_pipe(pipe) { | 8502 | for_each_pipe(pipe) { |
8468 | I915_WRITE(DSPCNTR(pipe), | 8503 | I915_WRITE(DSPCNTR(pipe), |
8469 | I915_READ(DSPCNTR(pipe)) | | 8504 | I915_READ(DSPCNTR(pipe)) | |
@@ -9025,12 +9060,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
9025 | 9060 | ||
9026 | for (i = 0; i < dev_priv->num_pipe; i++) { | 9061 | for (i = 0; i < dev_priv->num_pipe; i++) { |
9027 | intel_crtc_init(dev, i); | 9062 | intel_crtc_init(dev, i); |
9028 | if (HAS_PCH_SPLIT(dev)) { | 9063 | ret = intel_plane_init(dev, i); |
9029 | ret = intel_plane_init(dev, i); | 9064 | if (ret) |
9030 | if (ret) | 9065 | DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret); |
9031 | DRM_ERROR("plane %d init failed: %d\n", | ||
9032 | i, ret); | ||
9033 | } | ||
9034 | } | 9066 | } |
9035 | 9067 | ||
9036 | /* Just disable it once at startup */ | 9068 | /* Just disable it once at startup */ |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index db3b461ad412..94f860cce3f7 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -208,17 +208,8 @@ intel_dp_link_clock(uint8_t link_bw) | |||
208 | */ | 208 | */ |
209 | 209 | ||
210 | static int | 210 | static int |
211 | intel_dp_link_required(struct intel_dp *intel_dp, int pixel_clock, int check_bpp) | 211 | intel_dp_link_required(int pixel_clock, int bpp) |
212 | { | 212 | { |
213 | struct drm_crtc *crtc = intel_dp->base.base.crtc; | ||
214 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
215 | int bpp = 24; | ||
216 | |||
217 | if (check_bpp) | ||
218 | bpp = check_bpp; | ||
219 | else if (intel_crtc) | ||
220 | bpp = intel_crtc->bpp; | ||
221 | |||
222 | return (pixel_clock * bpp + 9) / 10; | 213 | return (pixel_clock * bpp + 9) / 10; |
223 | } | 214 | } |
224 | 215 | ||
@@ -245,12 +236,11 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
245 | return MODE_PANEL; | 236 | return MODE_PANEL; |
246 | } | 237 | } |
247 | 238 | ||
248 | mode_rate = intel_dp_link_required(intel_dp, mode->clock, 0); | 239 | mode_rate = intel_dp_link_required(mode->clock, 24); |
249 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); | 240 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); |
250 | 241 | ||
251 | if (mode_rate > max_rate) { | 242 | if (mode_rate > max_rate) { |
252 | mode_rate = intel_dp_link_required(intel_dp, | 243 | mode_rate = intel_dp_link_required(mode->clock, 18); |
253 | mode->clock, 18); | ||
254 | if (mode_rate > max_rate) | 244 | if (mode_rate > max_rate) |
255 | return MODE_CLOCK_HIGH; | 245 | return MODE_CLOCK_HIGH; |
256 | else | 246 | else |
@@ -683,7 +673,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
683 | int lane_count, clock; | 673 | int lane_count, clock; |
684 | int max_lane_count = intel_dp_max_lane_count(intel_dp); | 674 | int max_lane_count = intel_dp_max_lane_count(intel_dp); |
685 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; | 675 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; |
686 | int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 0; | 676 | int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; |
687 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | 677 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; |
688 | 678 | ||
689 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { | 679 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { |
@@ -701,7 +691,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
701 | for (clock = 0; clock <= max_clock; clock++) { | 691 | for (clock = 0; clock <= max_clock; clock++) { |
702 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); | 692 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
703 | 693 | ||
704 | if (intel_dp_link_required(intel_dp, mode->clock, bpp) | 694 | if (intel_dp_link_required(mode->clock, bpp) |
705 | <= link_avail) { | 695 | <= link_avail) { |
706 | intel_dp->link_bw = bws[clock]; | 696 | intel_dp->link_bw = bws[clock]; |
707 | intel_dp->lane_count = lane_count; | 697 | intel_dp->lane_count = lane_count; |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index e44191132ac4..aa84832b0e1a 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -694,6 +694,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
694 | }, | 694 | }, |
695 | { | 695 | { |
696 | .callback = intel_no_lvds_dmi_callback, | 696 | .callback = intel_no_lvds_dmi_callback, |
697 | .ident = "AOpen i45GMx-I", | ||
698 | .matches = { | ||
699 | DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), | ||
700 | DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"), | ||
701 | }, | ||
702 | }, | ||
703 | { | ||
704 | .callback = intel_no_lvds_dmi_callback, | ||
697 | .ident = "Aopen i945GTt-VFA", | 705 | .ident = "Aopen i945GTt-VFA", |
698 | .matches = { | 706 | .matches = { |
699 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), | 707 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), |
@@ -708,6 +716,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
708 | }, | 716 | }, |
709 | }, | 717 | }, |
710 | { | 718 | { |
719 | .callback = intel_no_lvds_dmi_callback, | ||
720 | .ident = "Clientron E830", | ||
721 | .matches = { | ||
722 | DMI_MATCH(DMI_SYS_VENDOR, "Clientron"), | ||
723 | DMI_MATCH(DMI_PRODUCT_NAME, "E830"), | ||
724 | }, | ||
725 | }, | ||
726 | { | ||
711 | .callback = intel_no_lvds_dmi_callback, | 727 | .callback = intel_no_lvds_dmi_callback, |
712 | .ident = "Asus EeeBox PC EB1007", | 728 | .ident = "Asus EeeBox PC EB1007", |
713 | .matches = { | 729 | .matches = { |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 77e729d4e4f0..536191540b03 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -301,7 +301,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
301 | 301 | ||
302 | I915_WRITE_CTL(ring, | 302 | I915_WRITE_CTL(ring, |
303 | ((ring->size - PAGE_SIZE) & RING_NR_PAGES) | 303 | ((ring->size - PAGE_SIZE) & RING_NR_PAGES) |
304 | | RING_REPORT_64K | RING_VALID); | 304 | | RING_VALID); |
305 | 305 | ||
306 | /* If the head is still not zero, the ring is dead */ | 306 | /* If the head is still not zero, the ring is dead */ |
307 | if ((I915_READ_CTL(ring) & RING_VALID) == 0 || | 307 | if ((I915_READ_CTL(ring) & RING_VALID) == 0 || |
@@ -636,6 +636,19 @@ render_ring_add_request(struct intel_ring_buffer *ring, | |||
636 | } | 636 | } |
637 | 637 | ||
638 | static u32 | 638 | static u32 |
639 | gen6_ring_get_seqno(struct intel_ring_buffer *ring) | ||
640 | { | ||
641 | struct drm_device *dev = ring->dev; | ||
642 | |||
643 | /* Workaround to force correct ordering between irq and seqno writes on | ||
644 | * ivb (and maybe also on snb) by reading from a CS register (like | ||
645 | * ACTHD) before reading the status page. */ | ||
646 | if (IS_GEN7(dev)) | ||
647 | intel_ring_get_active_head(ring); | ||
648 | return intel_read_status_page(ring, I915_GEM_HWS_INDEX); | ||
649 | } | ||
650 | |||
651 | static u32 | ||
639 | ring_get_seqno(struct intel_ring_buffer *ring) | 652 | ring_get_seqno(struct intel_ring_buffer *ring) |
640 | { | 653 | { |
641 | return intel_read_status_page(ring, I915_GEM_HWS_INDEX); | 654 | return intel_read_status_page(ring, I915_GEM_HWS_INDEX); |
@@ -792,17 +805,6 @@ ring_add_request(struct intel_ring_buffer *ring, | |||
792 | } | 805 | } |
793 | 806 | ||
794 | static bool | 807 | static bool |
795 | gen7_blt_ring_get_irq(struct intel_ring_buffer *ring) | ||
796 | { | ||
797 | /* The BLT ring on IVB appears to have broken synchronization | ||
798 | * between the seqno write and the interrupt, so that the | ||
799 | * interrupt appears first. Returning false here makes | ||
800 | * i915_wait_request() do a polling loop, instead. | ||
801 | */ | ||
802 | return false; | ||
803 | } | ||
804 | |||
805 | static bool | ||
806 | gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) | 808 | gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) |
807 | { | 809 | { |
808 | struct drm_device *dev = ring->dev; | 810 | struct drm_device *dev = ring->dev; |
@@ -811,6 +813,12 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) | |||
811 | if (!dev->irq_enabled) | 813 | if (!dev->irq_enabled) |
812 | return false; | 814 | return false; |
813 | 815 | ||
816 | /* It looks like we need to prevent the gt from suspending while waiting | ||
817 | * for an notifiy irq, otherwise irqs seem to get lost on at least the | ||
818 | * blt/bsd rings on ivb. */ | ||
819 | if (IS_GEN7(dev)) | ||
820 | gen6_gt_force_wake_get(dev_priv); | ||
821 | |||
814 | spin_lock(&ring->irq_lock); | 822 | spin_lock(&ring->irq_lock); |
815 | if (ring->irq_refcount++ == 0) { | 823 | if (ring->irq_refcount++ == 0) { |
816 | ring->irq_mask &= ~rflag; | 824 | ring->irq_mask &= ~rflag; |
@@ -835,6 +843,9 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) | |||
835 | ironlake_disable_irq(dev_priv, gflag); | 843 | ironlake_disable_irq(dev_priv, gflag); |
836 | } | 844 | } |
837 | spin_unlock(&ring->irq_lock); | 845 | spin_unlock(&ring->irq_lock); |
846 | |||
847 | if (IS_GEN7(dev)) | ||
848 | gen6_gt_force_wake_put(dev_priv); | ||
838 | } | 849 | } |
839 | 850 | ||
840 | static bool | 851 | static bool |
@@ -1121,18 +1132,6 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) | |||
1121 | struct drm_device *dev = ring->dev; | 1132 | struct drm_device *dev = ring->dev; |
1122 | struct drm_i915_private *dev_priv = dev->dev_private; | 1133 | struct drm_i915_private *dev_priv = dev->dev_private; |
1123 | unsigned long end; | 1134 | unsigned long end; |
1124 | u32 head; | ||
1125 | |||
1126 | /* If the reported head position has wrapped or hasn't advanced, | ||
1127 | * fallback to the slow and accurate path. | ||
1128 | */ | ||
1129 | head = intel_read_status_page(ring, 4); | ||
1130 | if (head > ring->head) { | ||
1131 | ring->head = head; | ||
1132 | ring->space = ring_space(ring); | ||
1133 | if (ring->space >= n) | ||
1134 | return 0; | ||
1135 | } | ||
1136 | 1135 | ||
1137 | trace_i915_ring_wait_begin(ring); | 1136 | trace_i915_ring_wait_begin(ring); |
1138 | if (drm_core_check_feature(dev, DRIVER_GEM)) | 1137 | if (drm_core_check_feature(dev, DRIVER_GEM)) |
@@ -1341,7 +1340,7 @@ static const struct intel_ring_buffer gen6_bsd_ring = { | |||
1341 | .write_tail = gen6_bsd_ring_write_tail, | 1340 | .write_tail = gen6_bsd_ring_write_tail, |
1342 | .flush = gen6_ring_flush, | 1341 | .flush = gen6_ring_flush, |
1343 | .add_request = gen6_add_request, | 1342 | .add_request = gen6_add_request, |
1344 | .get_seqno = ring_get_seqno, | 1343 | .get_seqno = gen6_ring_get_seqno, |
1345 | .irq_get = gen6_bsd_ring_get_irq, | 1344 | .irq_get = gen6_bsd_ring_get_irq, |
1346 | .irq_put = gen6_bsd_ring_put_irq, | 1345 | .irq_put = gen6_bsd_ring_put_irq, |
1347 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, | 1346 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, |
@@ -1476,7 +1475,7 @@ static const struct intel_ring_buffer gen6_blt_ring = { | |||
1476 | .write_tail = ring_write_tail, | 1475 | .write_tail = ring_write_tail, |
1477 | .flush = blt_ring_flush, | 1476 | .flush = blt_ring_flush, |
1478 | .add_request = gen6_add_request, | 1477 | .add_request = gen6_add_request, |
1479 | .get_seqno = ring_get_seqno, | 1478 | .get_seqno = gen6_ring_get_seqno, |
1480 | .irq_get = blt_ring_get_irq, | 1479 | .irq_get = blt_ring_get_irq, |
1481 | .irq_put = blt_ring_put_irq, | 1480 | .irq_put = blt_ring_put_irq, |
1482 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, | 1481 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, |
@@ -1499,6 +1498,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
1499 | ring->flush = gen6_render_ring_flush; | 1498 | ring->flush = gen6_render_ring_flush; |
1500 | ring->irq_get = gen6_render_ring_get_irq; | 1499 | ring->irq_get = gen6_render_ring_get_irq; |
1501 | ring->irq_put = gen6_render_ring_put_irq; | 1500 | ring->irq_put = gen6_render_ring_put_irq; |
1501 | ring->get_seqno = gen6_ring_get_seqno; | ||
1502 | } else if (IS_GEN5(dev)) { | 1502 | } else if (IS_GEN5(dev)) { |
1503 | ring->add_request = pc_render_add_request; | 1503 | ring->add_request = pc_render_add_request; |
1504 | ring->get_seqno = pc_render_get_seqno; | 1504 | ring->get_seqno = pc_render_get_seqno; |
@@ -1577,8 +1577,5 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) | |||
1577 | 1577 | ||
1578 | *ring = gen6_blt_ring; | 1578 | *ring = gen6_blt_ring; |
1579 | 1579 | ||
1580 | if (IS_GEN7(dev)) | ||
1581 | ring->irq_get = gen7_blt_ring_get_irq; | ||
1582 | |||
1583 | return intel_init_ring_buffer(dev, ring); | 1580 | return intel_init_ring_buffer(dev, ring); |
1584 | } | 1581 | } |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index f7b9268df266..e334ec33a47d 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1066,15 +1066,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1066 | 1066 | ||
1067 | /* Set the SDVO control regs. */ | 1067 | /* Set the SDVO control regs. */ |
1068 | if (INTEL_INFO(dev)->gen >= 4) { | 1068 | if (INTEL_INFO(dev)->gen >= 4) { |
1069 | sdvox = 0; | 1069 | /* The real mode polarity is set by the SDVO commands, using |
1070 | * struct intel_sdvo_dtd. */ | ||
1071 | sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH; | ||
1070 | if (intel_sdvo->is_hdmi) | 1072 | if (intel_sdvo->is_hdmi) |
1071 | sdvox |= intel_sdvo->color_range; | 1073 | sdvox |= intel_sdvo->color_range; |
1072 | if (INTEL_INFO(dev)->gen < 5) | 1074 | if (INTEL_INFO(dev)->gen < 5) |
1073 | sdvox |= SDVO_BORDER_ENABLE; | 1075 | sdvox |= SDVO_BORDER_ENABLE; |
1074 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | ||
1075 | sdvox |= SDVO_VSYNC_ACTIVE_HIGH; | ||
1076 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | ||
1077 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; | ||
1078 | } else { | 1076 | } else { |
1079 | sdvox = I915_READ(intel_sdvo->sdvo_reg); | 1077 | sdvox = I915_READ(intel_sdvo->sdvo_reg); |
1080 | switch (intel_sdvo->sdvo_reg) { | 1078 | switch (intel_sdvo->sdvo_reg) { |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index d13989fda501..a0835040c86b 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -225,16 +225,16 @@ snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
225 | 225 | ||
226 | /* Mask out pixel format bits in case we change it */ | 226 | /* Mask out pixel format bits in case we change it */ |
227 | dvscntr &= ~DVS_PIXFORMAT_MASK; | 227 | dvscntr &= ~DVS_PIXFORMAT_MASK; |
228 | dvscntr &= ~DVS_RGB_ORDER_RGBX; | 228 | dvscntr &= ~DVS_RGB_ORDER_XBGR; |
229 | dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; | 229 | dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; |
230 | 230 | ||
231 | switch (fb->pixel_format) { | 231 | switch (fb->pixel_format) { |
232 | case DRM_FORMAT_XBGR8888: | 232 | case DRM_FORMAT_XBGR8888: |
233 | dvscntr |= DVS_FORMAT_RGBX888; | 233 | dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; |
234 | pixel_size = 4; | 234 | pixel_size = 4; |
235 | break; | 235 | break; |
236 | case DRM_FORMAT_XRGB8888: | 236 | case DRM_FORMAT_XRGB8888: |
237 | dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_RGBX; | 237 | dvscntr |= DVS_FORMAT_RGBX888; |
238 | pixel_size = 4; | 238 | pixel_size = 4; |
239 | break; | 239 | break; |
240 | case DRM_FORMAT_YUYV: | 240 | case DRM_FORMAT_YUYV: |
@@ -466,10 +466,8 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
466 | mutex_lock(&dev->struct_mutex); | 466 | mutex_lock(&dev->struct_mutex); |
467 | 467 | ||
468 | ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); | 468 | ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); |
469 | if (ret) { | 469 | if (ret) |
470 | DRM_ERROR("failed to pin object\n"); | ||
471 | goto out_unlock; | 470 | goto out_unlock; |
472 | } | ||
473 | 471 | ||
474 | intel_plane->obj = obj; | 472 | intel_plane->obj = obj; |
475 | 473 | ||
@@ -632,10 +630,8 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) | |||
632 | unsigned long possible_crtcs; | 630 | unsigned long possible_crtcs; |
633 | int ret; | 631 | int ret; |
634 | 632 | ||
635 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) { | 633 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) |
636 | DRM_ERROR("new plane code only for SNB+\n"); | ||
637 | return -ENODEV; | 634 | return -ENODEV; |
638 | } | ||
639 | 635 | ||
640 | intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); | 636 | intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); |
641 | if (!intel_plane) | 637 | if (!intel_plane) |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index f3c6a9a8b081..1571be37ce3e 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -417,7 +417,7 @@ static const struct tv_mode tv_modes[] = { | |||
417 | { | 417 | { |
418 | .name = "NTSC-M", | 418 | .name = "NTSC-M", |
419 | .clock = 108000, | 419 | .clock = 108000, |
420 | .refresh = 29970, | 420 | .refresh = 59940, |
421 | .oversample = TV_OVERSAMPLE_8X, | 421 | .oversample = TV_OVERSAMPLE_8X, |
422 | .component_only = 0, | 422 | .component_only = 0, |
423 | /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ | 423 | /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ |
@@ -460,7 +460,7 @@ static const struct tv_mode tv_modes[] = { | |||
460 | { | 460 | { |
461 | .name = "NTSC-443", | 461 | .name = "NTSC-443", |
462 | .clock = 108000, | 462 | .clock = 108000, |
463 | .refresh = 29970, | 463 | .refresh = 59940, |
464 | .oversample = TV_OVERSAMPLE_8X, | 464 | .oversample = TV_OVERSAMPLE_8X, |
465 | .component_only = 0, | 465 | .component_only = 0, |
466 | /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */ | 466 | /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */ |
@@ -502,7 +502,7 @@ static const struct tv_mode tv_modes[] = { | |||
502 | { | 502 | { |
503 | .name = "NTSC-J", | 503 | .name = "NTSC-J", |
504 | .clock = 108000, | 504 | .clock = 108000, |
505 | .refresh = 29970, | 505 | .refresh = 59940, |
506 | .oversample = TV_OVERSAMPLE_8X, | 506 | .oversample = TV_OVERSAMPLE_8X, |
507 | .component_only = 0, | 507 | .component_only = 0, |
508 | 508 | ||
@@ -545,7 +545,7 @@ static const struct tv_mode tv_modes[] = { | |||
545 | { | 545 | { |
546 | .name = "PAL-M", | 546 | .name = "PAL-M", |
547 | .clock = 108000, | 547 | .clock = 108000, |
548 | .refresh = 29970, | 548 | .refresh = 59940, |
549 | .oversample = TV_OVERSAMPLE_8X, | 549 | .oversample = TV_OVERSAMPLE_8X, |
550 | .component_only = 0, | 550 | .component_only = 0, |
551 | 551 | ||
@@ -589,7 +589,7 @@ static const struct tv_mode tv_modes[] = { | |||
589 | /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ | 589 | /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ |
590 | .name = "PAL-N", | 590 | .name = "PAL-N", |
591 | .clock = 108000, | 591 | .clock = 108000, |
592 | .refresh = 25000, | 592 | .refresh = 50000, |
593 | .oversample = TV_OVERSAMPLE_8X, | 593 | .oversample = TV_OVERSAMPLE_8X, |
594 | .component_only = 0, | 594 | .component_only = 0, |
595 | 595 | ||
@@ -634,7 +634,7 @@ static const struct tv_mode tv_modes[] = { | |||
634 | /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ | 634 | /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ |
635 | .name = "PAL", | 635 | .name = "PAL", |
636 | .clock = 108000, | 636 | .clock = 108000, |
637 | .refresh = 25000, | 637 | .refresh = 50000, |
638 | .oversample = TV_OVERSAMPLE_8X, | 638 | .oversample = TV_OVERSAMPLE_8X, |
639 | .component_only = 0, | 639 | .component_only = 0, |
640 | 640 | ||
@@ -674,78 +674,6 @@ static const struct tv_mode tv_modes[] = { | |||
674 | .filter_table = filter_table, | 674 | .filter_table = filter_table, |
675 | }, | 675 | }, |
676 | { | 676 | { |
677 | .name = "480p@59.94Hz", | ||
678 | .clock = 107520, | ||
679 | .refresh = 59940, | ||
680 | .oversample = TV_OVERSAMPLE_4X, | ||
681 | .component_only = 1, | ||
682 | |||
683 | .hsync_end = 64, .hblank_end = 122, | ||
684 | .hblank_start = 842, .htotal = 857, | ||
685 | |||
686 | .progressive = true, .trilevel_sync = false, | ||
687 | |||
688 | .vsync_start_f1 = 12, .vsync_start_f2 = 12, | ||
689 | .vsync_len = 12, | ||
690 | |||
691 | .veq_ena = false, | ||
692 | |||
693 | .vi_end_f1 = 44, .vi_end_f2 = 44, | ||
694 | .nbr_end = 479, | ||
695 | |||
696 | .burst_ena = false, | ||
697 | |||
698 | .filter_table = filter_table, | ||
699 | }, | ||
700 | { | ||
701 | .name = "480p@60Hz", | ||
702 | .clock = 107520, | ||
703 | .refresh = 60000, | ||
704 | .oversample = TV_OVERSAMPLE_4X, | ||
705 | .component_only = 1, | ||
706 | |||
707 | .hsync_end = 64, .hblank_end = 122, | ||
708 | .hblank_start = 842, .htotal = 856, | ||
709 | |||
710 | .progressive = true, .trilevel_sync = false, | ||
711 | |||
712 | .vsync_start_f1 = 12, .vsync_start_f2 = 12, | ||
713 | .vsync_len = 12, | ||
714 | |||
715 | .veq_ena = false, | ||
716 | |||
717 | .vi_end_f1 = 44, .vi_end_f2 = 44, | ||
718 | .nbr_end = 479, | ||
719 | |||
720 | .burst_ena = false, | ||
721 | |||
722 | .filter_table = filter_table, | ||
723 | }, | ||
724 | { | ||
725 | .name = "576p", | ||
726 | .clock = 107520, | ||
727 | .refresh = 50000, | ||
728 | .oversample = TV_OVERSAMPLE_4X, | ||
729 | .component_only = 1, | ||
730 | |||
731 | .hsync_end = 64, .hblank_end = 139, | ||
732 | .hblank_start = 859, .htotal = 863, | ||
733 | |||
734 | .progressive = true, .trilevel_sync = false, | ||
735 | |||
736 | .vsync_start_f1 = 10, .vsync_start_f2 = 10, | ||
737 | .vsync_len = 10, | ||
738 | |||
739 | .veq_ena = false, | ||
740 | |||
741 | .vi_end_f1 = 48, .vi_end_f2 = 48, | ||
742 | .nbr_end = 575, | ||
743 | |||
744 | .burst_ena = false, | ||
745 | |||
746 | .filter_table = filter_table, | ||
747 | }, | ||
748 | { | ||
749 | .name = "720p@60Hz", | 677 | .name = "720p@60Hz", |
750 | .clock = 148800, | 678 | .clock = 148800, |
751 | .refresh = 60000, | 679 | .refresh = 60000, |
@@ -770,30 +698,6 @@ static const struct tv_mode tv_modes[] = { | |||
770 | .filter_table = filter_table, | 698 | .filter_table = filter_table, |
771 | }, | 699 | }, |
772 | { | 700 | { |
773 | .name = "720p@59.94Hz", | ||
774 | .clock = 148800, | ||
775 | .refresh = 59940, | ||
776 | .oversample = TV_OVERSAMPLE_2X, | ||
777 | .component_only = 1, | ||
778 | |||
779 | .hsync_end = 80, .hblank_end = 300, | ||
780 | .hblank_start = 1580, .htotal = 1651, | ||
781 | |||
782 | .progressive = true, .trilevel_sync = true, | ||
783 | |||
784 | .vsync_start_f1 = 10, .vsync_start_f2 = 10, | ||
785 | .vsync_len = 10, | ||
786 | |||
787 | .veq_ena = false, | ||
788 | |||
789 | .vi_end_f1 = 29, .vi_end_f2 = 29, | ||
790 | .nbr_end = 719, | ||
791 | |||
792 | .burst_ena = false, | ||
793 | |||
794 | .filter_table = filter_table, | ||
795 | }, | ||
796 | { | ||
797 | .name = "720p@50Hz", | 701 | .name = "720p@50Hz", |
798 | .clock = 148800, | 702 | .clock = 148800, |
799 | .refresh = 50000, | 703 | .refresh = 50000, |
@@ -821,7 +725,7 @@ static const struct tv_mode tv_modes[] = { | |||
821 | { | 725 | { |
822 | .name = "1080i@50Hz", | 726 | .name = "1080i@50Hz", |
823 | .clock = 148800, | 727 | .clock = 148800, |
824 | .refresh = 25000, | 728 | .refresh = 50000, |
825 | .oversample = TV_OVERSAMPLE_2X, | 729 | .oversample = TV_OVERSAMPLE_2X, |
826 | .component_only = 1, | 730 | .component_only = 1, |
827 | 731 | ||
@@ -847,7 +751,7 @@ static const struct tv_mode tv_modes[] = { | |||
847 | { | 751 | { |
848 | .name = "1080i@60Hz", | 752 | .name = "1080i@60Hz", |
849 | .clock = 148800, | 753 | .clock = 148800, |
850 | .refresh = 30000, | 754 | .refresh = 60000, |
851 | .oversample = TV_OVERSAMPLE_2X, | 755 | .oversample = TV_OVERSAMPLE_2X, |
852 | .component_only = 1, | 756 | .component_only = 1, |
853 | 757 | ||
@@ -870,32 +774,6 @@ static const struct tv_mode tv_modes[] = { | |||
870 | 774 | ||
871 | .filter_table = filter_table, | 775 | .filter_table = filter_table, |
872 | }, | 776 | }, |
873 | { | ||
874 | .name = "1080i@59.94Hz", | ||
875 | .clock = 148800, | ||
876 | .refresh = 29970, | ||
877 | .oversample = TV_OVERSAMPLE_2X, | ||
878 | .component_only = 1, | ||
879 | |||
880 | .hsync_end = 88, .hblank_end = 235, | ||
881 | .hblank_start = 2155, .htotal = 2201, | ||
882 | |||
883 | .progressive = false, .trilevel_sync = true, | ||
884 | |||
885 | .vsync_start_f1 = 4, .vsync_start_f2 = 5, | ||
886 | .vsync_len = 10, | ||
887 | |||
888 | .veq_ena = true, .veq_start_f1 = 4, | ||
889 | .veq_start_f2 = 4, .veq_len = 10, | ||
890 | |||
891 | |||
892 | .vi_end_f1 = 21, .vi_end_f2 = 22, | ||
893 | .nbr_end = 539, | ||
894 | |||
895 | .burst_ena = false, | ||
896 | |||
897 | .filter_table = filter_table, | ||
898 | }, | ||
899 | }; | 777 | }; |
900 | 778 | ||
901 | static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) | 779 | static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index 1e382ad5a2b8..a37c31e358aa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h | |||
@@ -54,9 +54,10 @@ struct bit_entry { | |||
54 | int bit_table(struct drm_device *, u8 id, struct bit_entry *); | 54 | int bit_table(struct drm_device *, u8 id, struct bit_entry *); |
55 | 55 | ||
56 | enum dcb_gpio_tag { | 56 | enum dcb_gpio_tag { |
57 | DCB_GPIO_TVDAC0 = 0xc, | 57 | DCB_GPIO_PANEL_POWER = 0x01, |
58 | DCB_GPIO_TVDAC0 = 0x0c, | ||
58 | DCB_GPIO_TVDAC1 = 0x2d, | 59 | DCB_GPIO_TVDAC1 = 0x2d, |
59 | DCB_GPIO_PWM_FAN = 0x9, | 60 | DCB_GPIO_PWM_FAN = 0x09, |
60 | DCB_GPIO_FAN_SENSE = 0x3d, | 61 | DCB_GPIO_FAN_SENSE = 0x3d, |
61 | DCB_GPIO_UNUSED = 0xff | 62 | DCB_GPIO_UNUSED = 0xff |
62 | }; | 63 | }; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 724b41a2b9e9..ec54364ac828 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -812,6 +812,10 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem) | |||
812 | struct nouveau_bo *nvbo = nouveau_bo(bo); | 812 | struct nouveau_bo *nvbo = nouveau_bo(bo); |
813 | struct nouveau_vma *vma; | 813 | struct nouveau_vma *vma; |
814 | 814 | ||
815 | /* ttm can now (stupidly) pass the driver bos it didn't create... */ | ||
816 | if (bo->destroy != nouveau_bo_del_ttm) | ||
817 | return; | ||
818 | |||
815 | list_for_each_entry(vma, &nvbo->vma_list, head) { | 819 | list_for_each_entry(vma, &nvbo->vma_list, head) { |
816 | if (new_mem && new_mem->mem_type == TTM_PL_VRAM) { | 820 | if (new_mem && new_mem->mem_type == TTM_PL_VRAM) { |
817 | nouveau_vm_map(vma, new_mem->mm_node); | 821 | nouveau_vm_map(vma, new_mem->mm_node); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 3cb52bc52b21..795a9e3c990a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -219,6 +219,16 @@ nouveau_display_init(struct drm_device *dev) | |||
219 | if (ret) | 219 | if (ret) |
220 | return ret; | 220 | return ret; |
221 | 221 | ||
222 | /* power on internal panel if it's not already. the init tables of | ||
223 | * some vbios default this to off for some reason, causing the | ||
224 | * panel to not work after resume | ||
225 | */ | ||
226 | if (nouveau_gpio_func_get(dev, DCB_GPIO_PANEL_POWER) == 0) { | ||
227 | nouveau_gpio_func_set(dev, DCB_GPIO_PANEL_POWER, true); | ||
228 | msleep(300); | ||
229 | } | ||
230 | |||
231 | /* enable polling for external displays */ | ||
222 | drm_kms_helper_poll_enable(dev); | 232 | drm_kms_helper_poll_enable(dev); |
223 | 233 | ||
224 | /* enable hotplug interrupts */ | 234 | /* enable hotplug interrupts */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index e4a7cfe7898d..81d7962e7252 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c | |||
@@ -124,7 +124,7 @@ MODULE_PARM_DESC(ctxfw, "Use external HUB/GPC ucode (fermi)\n"); | |||
124 | int nouveau_ctxfw; | 124 | int nouveau_ctxfw; |
125 | module_param_named(ctxfw, nouveau_ctxfw, int, 0400); | 125 | module_param_named(ctxfw, nouveau_ctxfw, int, 0400); |
126 | 126 | ||
127 | MODULE_PARM_DESC(ctxfw, "Santise DCB table according to MXM-SIS\n"); | 127 | MODULE_PARM_DESC(mxmdcb, "Santise DCB table according to MXM-SIS\n"); |
128 | int nouveau_mxmdcb = 1; | 128 | int nouveau_mxmdcb = 1; |
129 | module_param_named(mxmdcb, nouveau_mxmdcb, int, 0400); | 129 | module_param_named(mxmdcb, nouveau_mxmdcb, int, 0400); |
130 | 130 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 5f0bc57fdaab..7ce3fde40743 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -380,6 +380,25 @@ retry: | |||
380 | } | 380 | } |
381 | 381 | ||
382 | static int | 382 | static int |
383 | validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo) | ||
384 | { | ||
385 | struct nouveau_fence *fence = NULL; | ||
386 | int ret = 0; | ||
387 | |||
388 | spin_lock(&nvbo->bo.bdev->fence_lock); | ||
389 | if (nvbo->bo.sync_obj) | ||
390 | fence = nouveau_fence_ref(nvbo->bo.sync_obj); | ||
391 | spin_unlock(&nvbo->bo.bdev->fence_lock); | ||
392 | |||
393 | if (fence) { | ||
394 | ret = nouveau_fence_sync(fence, chan); | ||
395 | nouveau_fence_unref(&fence); | ||
396 | } | ||
397 | |||
398 | return ret; | ||
399 | } | ||
400 | |||
401 | static int | ||
383 | validate_list(struct nouveau_channel *chan, struct list_head *list, | 402 | validate_list(struct nouveau_channel *chan, struct list_head *list, |
384 | struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr) | 403 | struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr) |
385 | { | 404 | { |
@@ -393,7 +412,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
393 | list_for_each_entry(nvbo, list, entry) { | 412 | list_for_each_entry(nvbo, list, entry) { |
394 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; | 413 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; |
395 | 414 | ||
396 | ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan); | 415 | ret = validate_sync(chan, nvbo); |
397 | if (unlikely(ret)) { | 416 | if (unlikely(ret)) { |
398 | NV_ERROR(dev, "fail pre-validate sync\n"); | 417 | NV_ERROR(dev, "fail pre-validate sync\n"); |
399 | return ret; | 418 | return ret; |
@@ -416,7 +435,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
416 | return ret; | 435 | return ret; |
417 | } | 436 | } |
418 | 437 | ||
419 | ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan); | 438 | ret = validate_sync(chan, nvbo); |
420 | if (unlikely(ret)) { | 439 | if (unlikely(ret)) { |
421 | NV_ERROR(dev, "fail post-validate sync\n"); | 440 | NV_ERROR(dev, "fail post-validate sync\n"); |
422 | return ret; | 441 | return ret; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_mxm.c b/drivers/gpu/drm/nouveau/nouveau_mxm.c index 8bccddf4eff0..e5a64f0f4cb7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mxm.c +++ b/drivers/gpu/drm/nouveau/nouveau_mxm.c | |||
@@ -656,7 +656,16 @@ nouveau_mxm_init(struct drm_device *dev) | |||
656 | 656 | ||
657 | if (mxm_shadow(dev, mxm[0])) { | 657 | if (mxm_shadow(dev, mxm[0])) { |
658 | MXM_MSG(dev, "failed to locate valid SIS\n"); | 658 | MXM_MSG(dev, "failed to locate valid SIS\n"); |
659 | #if 0 | ||
660 | /* we should, perhaps, fall back to some kind of limited | ||
661 | * mode here if the x86 vbios hasn't already done the | ||
662 | * work for us (so we prevent loading with completely | ||
663 | * whacked vbios tables). | ||
664 | */ | ||
659 | return -EINVAL; | 665 | return -EINVAL; |
666 | #else | ||
667 | return 0; | ||
668 | #endif | ||
660 | } | 669 | } |
661 | 670 | ||
662 | MXM_MSG(dev, "MXMS Version %d.%d\n", | 671 | MXM_MSG(dev, "MXMS Version %d.%d\n", |
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c index 03937212e9d8..ec5481dfcd82 100644 --- a/drivers/gpu/drm/nouveau/nv50_pm.c +++ b/drivers/gpu/drm/nouveau/nv50_pm.c | |||
@@ -495,9 +495,9 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) | |||
495 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 495 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
496 | struct nv50_pm_state *info; | 496 | struct nv50_pm_state *info; |
497 | struct pll_lims pll; | 497 | struct pll_lims pll; |
498 | int ret = -EINVAL; | 498 | int clk, ret = -EINVAL; |
499 | int N, M, P1, P2; | 499 | int N, M, P1, P2; |
500 | u32 clk, out; | 500 | u32 out; |
501 | 501 | ||
502 | if (dev_priv->chipset == 0xaa || | 502 | if (dev_priv->chipset == 0xaa || |
503 | dev_priv->chipset == 0xac) | 503 | dev_priv->chipset == 0xac) |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 0fda830ef806..742f17f009a9 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -355,15 +355,12 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc, | |||
355 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 355 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
356 | } | 356 | } |
357 | 357 | ||
358 | static void atombios_disable_ss(struct drm_crtc *crtc) | 358 | static void atombios_disable_ss(struct radeon_device *rdev, int pll_id) |
359 | { | 359 | { |
360 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
361 | struct drm_device *dev = crtc->dev; | ||
362 | struct radeon_device *rdev = dev->dev_private; | ||
363 | u32 ss_cntl; | 360 | u32 ss_cntl; |
364 | 361 | ||
365 | if (ASIC_IS_DCE4(rdev)) { | 362 | if (ASIC_IS_DCE4(rdev)) { |
366 | switch (radeon_crtc->pll_id) { | 363 | switch (pll_id) { |
367 | case ATOM_PPLL1: | 364 | case ATOM_PPLL1: |
368 | ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL); | 365 | ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL); |
369 | ss_cntl &= ~EVERGREEN_PxPLL_SS_EN; | 366 | ss_cntl &= ~EVERGREEN_PxPLL_SS_EN; |
@@ -379,7 +376,7 @@ static void atombios_disable_ss(struct drm_crtc *crtc) | |||
379 | return; | 376 | return; |
380 | } | 377 | } |
381 | } else if (ASIC_IS_AVIVO(rdev)) { | 378 | } else if (ASIC_IS_AVIVO(rdev)) { |
382 | switch (radeon_crtc->pll_id) { | 379 | switch (pll_id) { |
383 | case ATOM_PPLL1: | 380 | case ATOM_PPLL1: |
384 | ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); | 381 | ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); |
385 | ss_cntl &= ~1; | 382 | ss_cntl &= ~1; |
@@ -406,13 +403,11 @@ union atom_enable_ss { | |||
406 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3; | 403 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3; |
407 | }; | 404 | }; |
408 | 405 | ||
409 | static void atombios_crtc_program_ss(struct drm_crtc *crtc, | 406 | static void atombios_crtc_program_ss(struct radeon_device *rdev, |
410 | int enable, | 407 | int enable, |
411 | int pll_id, | 408 | int pll_id, |
412 | struct radeon_atom_ss *ss) | 409 | struct radeon_atom_ss *ss) |
413 | { | 410 | { |
414 | struct drm_device *dev = crtc->dev; | ||
415 | struct radeon_device *rdev = dev->dev_private; | ||
416 | int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); | 411 | int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); |
417 | union atom_enable_ss args; | 412 | union atom_enable_ss args; |
418 | 413 | ||
@@ -479,7 +474,7 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc, | |||
479 | } else if (ASIC_IS_AVIVO(rdev)) { | 474 | } else if (ASIC_IS_AVIVO(rdev)) { |
480 | if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || | 475 | if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || |
481 | (ss->type & ATOM_EXTERNAL_SS_MASK)) { | 476 | (ss->type & ATOM_EXTERNAL_SS_MASK)) { |
482 | atombios_disable_ss(crtc); | 477 | atombios_disable_ss(rdev, pll_id); |
483 | return; | 478 | return; |
484 | } | 479 | } |
485 | args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); | 480 | args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); |
@@ -491,7 +486,7 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc, | |||
491 | } else { | 486 | } else { |
492 | if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || | 487 | if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || |
493 | (ss->type & ATOM_EXTERNAL_SS_MASK)) { | 488 | (ss->type & ATOM_EXTERNAL_SS_MASK)) { |
494 | atombios_disable_ss(crtc); | 489 | atombios_disable_ss(rdev, pll_id); |
495 | return; | 490 | return; |
496 | } | 491 | } |
497 | args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); | 492 | args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); |
@@ -523,6 +518,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
523 | int encoder_mode = 0; | 518 | int encoder_mode = 0; |
524 | u32 dp_clock = mode->clock; | 519 | u32 dp_clock = mode->clock; |
525 | int bpc = 8; | 520 | int bpc = 8; |
521 | bool is_duallink = false; | ||
526 | 522 | ||
527 | /* reset the pll flags */ | 523 | /* reset the pll flags */ |
528 | pll->flags = 0; | 524 | pll->flags = 0; |
@@ -557,6 +553,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
557 | if (connector && connector->display_info.bpc) | 553 | if (connector && connector->display_info.bpc) |
558 | bpc = connector->display_info.bpc; | 554 | bpc = connector->display_info.bpc; |
559 | encoder_mode = atombios_get_encoder_mode(encoder); | 555 | encoder_mode = atombios_get_encoder_mode(encoder); |
556 | is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); | ||
560 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || | 557 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || |
561 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { | 558 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { |
562 | if (connector) { | 559 | if (connector) { |
@@ -652,7 +649,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
652 | if (dig->coherent_mode) | 649 | if (dig->coherent_mode) |
653 | args.v3.sInput.ucDispPllConfig |= | 650 | args.v3.sInput.ucDispPllConfig |= |
654 | DISPPLL_CONFIG_COHERENT_MODE; | 651 | DISPPLL_CONFIG_COHERENT_MODE; |
655 | if (mode->clock > 165000) | 652 | if (is_duallink) |
656 | args.v3.sInput.ucDispPllConfig |= | 653 | args.v3.sInput.ucDispPllConfig |= |
657 | DISPPLL_CONFIG_DUAL_LINK; | 654 | DISPPLL_CONFIG_DUAL_LINK; |
658 | } | 655 | } |
@@ -702,11 +699,9 @@ union set_pixel_clock { | |||
702 | /* on DCE5, make sure the voltage is high enough to support the | 699 | /* on DCE5, make sure the voltage is high enough to support the |
703 | * required disp clk. | 700 | * required disp clk. |
704 | */ | 701 | */ |
705 | static void atombios_crtc_set_dcpll(struct drm_crtc *crtc, | 702 | static void atombios_crtc_set_dcpll(struct radeon_device *rdev, |
706 | u32 dispclk) | 703 | u32 dispclk) |
707 | { | 704 | { |
708 | struct drm_device *dev = crtc->dev; | ||
709 | struct radeon_device *rdev = dev->dev_private; | ||
710 | u8 frev, crev; | 705 | u8 frev, crev; |
711 | int index; | 706 | int index; |
712 | union set_pixel_clock args; | 707 | union set_pixel_clock args; |
@@ -996,7 +991,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
996 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | 991 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, |
997 | &ref_div, &post_div); | 992 | &ref_div, &post_div); |
998 | 993 | ||
999 | atombios_crtc_program_ss(crtc, ATOM_DISABLE, radeon_crtc->pll_id, &ss); | 994 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss); |
1000 | 995 | ||
1001 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, | 996 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
1002 | encoder_mode, radeon_encoder->encoder_id, mode->clock, | 997 | encoder_mode, radeon_encoder->encoder_id, mode->clock, |
@@ -1019,7 +1014,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
1019 | ss.step = step_size; | 1014 | ss.step = step_size; |
1020 | } | 1015 | } |
1021 | 1016 | ||
1022 | atombios_crtc_program_ss(crtc, ATOM_ENABLE, radeon_crtc->pll_id, &ss); | 1017 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss); |
1023 | } | 1018 | } |
1024 | } | 1019 | } |
1025 | 1020 | ||
@@ -1189,7 +1184,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
1189 | WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); | 1184 | WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
1190 | 1185 | ||
1191 | WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, | 1186 | WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, |
1192 | crtc->mode.vdisplay); | 1187 | target_fb->height); |
1193 | x &= ~3; | 1188 | x &= ~3; |
1194 | y &= ~1; | 1189 | y &= ~1; |
1195 | WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, | 1190 | WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, |
@@ -1358,7 +1353,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
1358 | WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); | 1353 | WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
1359 | 1354 | ||
1360 | WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, | 1355 | WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, |
1361 | crtc->mode.vdisplay); | 1356 | target_fb->height); |
1362 | x &= ~3; | 1357 | x &= ~3; |
1363 | y &= ~1; | 1358 | y &= ~1; |
1364 | WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, | 1359 | WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, |
@@ -1494,6 +1489,24 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1494 | 1489 | ||
1495 | } | 1490 | } |
1496 | 1491 | ||
1492 | void radeon_atom_dcpll_init(struct radeon_device *rdev) | ||
1493 | { | ||
1494 | /* always set DCPLL */ | ||
1495 | if (ASIC_IS_DCE4(rdev)) { | ||
1496 | struct radeon_atom_ss ss; | ||
1497 | bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss, | ||
1498 | ASIC_INTERNAL_SS_ON_DCPLL, | ||
1499 | rdev->clock.default_dispclk); | ||
1500 | if (ss_enabled) | ||
1501 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss); | ||
1502 | /* XXX: DCE5, make sure voltage, dispclk is high enough */ | ||
1503 | atombios_crtc_set_dcpll(rdev, rdev->clock.default_dispclk); | ||
1504 | if (ss_enabled) | ||
1505 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss); | ||
1506 | } | ||
1507 | |||
1508 | } | ||
1509 | |||
1497 | int atombios_crtc_mode_set(struct drm_crtc *crtc, | 1510 | int atombios_crtc_mode_set(struct drm_crtc *crtc, |
1498 | struct drm_display_mode *mode, | 1511 | struct drm_display_mode *mode, |
1499 | struct drm_display_mode *adjusted_mode, | 1512 | struct drm_display_mode *adjusted_mode, |
@@ -1515,19 +1528,6 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
1515 | } | 1528 | } |
1516 | } | 1529 | } |
1517 | 1530 | ||
1518 | /* always set DCPLL */ | ||
1519 | if (ASIC_IS_DCE4(rdev)) { | ||
1520 | struct radeon_atom_ss ss; | ||
1521 | bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss, | ||
1522 | ASIC_INTERNAL_SS_ON_DCPLL, | ||
1523 | rdev->clock.default_dispclk); | ||
1524 | if (ss_enabled) | ||
1525 | atombios_crtc_program_ss(crtc, ATOM_DISABLE, ATOM_DCPLL, &ss); | ||
1526 | /* XXX: DCE5, make sure voltage, dispclk is high enough */ | ||
1527 | atombios_crtc_set_dcpll(crtc, rdev->clock.default_dispclk); | ||
1528 | if (ss_enabled) | ||
1529 | atombios_crtc_program_ss(crtc, ATOM_ENABLE, ATOM_DCPLL, &ss); | ||
1530 | } | ||
1531 | atombios_crtc_set_pll(crtc, adjusted_mode); | 1531 | atombios_crtc_set_pll(crtc, adjusted_mode); |
1532 | 1532 | ||
1533 | if (ASIC_IS_DCE4(rdev)) | 1533 | if (ASIC_IS_DCE4(rdev)) |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 6fb335a4fdda..552b436451fd 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -549,8 +549,8 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) | |||
549 | return false; | 549 | return false; |
550 | } | 550 | } |
551 | 551 | ||
552 | static void radeon_dp_set_panel_mode(struct drm_encoder *encoder, | 552 | int radeon_dp_get_panel_mode(struct drm_encoder *encoder, |
553 | struct drm_connector *connector) | 553 | struct drm_connector *connector) |
554 | { | 554 | { |
555 | struct drm_device *dev = encoder->dev; | 555 | struct drm_device *dev = encoder->dev; |
556 | struct radeon_device *rdev = dev->dev_private; | 556 | struct radeon_device *rdev = dev->dev_private; |
@@ -558,28 +558,33 @@ static void radeon_dp_set_panel_mode(struct drm_encoder *encoder, | |||
558 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | 558 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
559 | 559 | ||
560 | if (!ASIC_IS_DCE4(rdev)) | 560 | if (!ASIC_IS_DCE4(rdev)) |
561 | return; | 561 | return panel_mode; |
562 | 562 | ||
563 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | 563 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == |
564 | ENCODER_OBJECT_ID_NUTMEG) | 564 | ENCODER_OBJECT_ID_NUTMEG) |
565 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 565 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; |
566 | else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | 566 | else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == |
567 | ENCODER_OBJECT_ID_TRAVIS) | 567 | ENCODER_OBJECT_ID_TRAVIS) { |
568 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 568 | u8 id[6]; |
569 | else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 569 | int i; |
570 | for (i = 0; i < 6; i++) | ||
571 | id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i); | ||
572 | if (id[0] == 0x73 && | ||
573 | id[1] == 0x69 && | ||
574 | id[2] == 0x76 && | ||
575 | id[3] == 0x61 && | ||
576 | id[4] == 0x72 && | ||
577 | id[5] == 0x54) | ||
578 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | ||
579 | else | ||
580 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | ||
581 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | ||
570 | u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); | 582 | u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); |
571 | if (tmp & 1) | 583 | if (tmp & 1) |
572 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 584 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
573 | } | 585 | } |
574 | 586 | ||
575 | atombios_dig_encoder_setup(encoder, | 587 | return panel_mode; |
576 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | ||
577 | panel_mode); | ||
578 | |||
579 | if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) && | ||
580 | (panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { | ||
581 | radeon_write_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_SET, 1); | ||
582 | } | ||
583 | } | 588 | } |
584 | 589 | ||
585 | void radeon_dp_set_link_config(struct drm_connector *connector, | 590 | void radeon_dp_set_link_config(struct drm_connector *connector, |
@@ -717,6 +722,8 @@ static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp) | |||
717 | 722 | ||
718 | static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) | 723 | static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) |
719 | { | 724 | { |
725 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder); | ||
726 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
720 | u8 tmp; | 727 | u8 tmp; |
721 | 728 | ||
722 | /* power up the sink */ | 729 | /* power up the sink */ |
@@ -732,7 +739,10 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) | |||
732 | radeon_write_dpcd_reg(dp_info->radeon_connector, | 739 | radeon_write_dpcd_reg(dp_info->radeon_connector, |
733 | DP_DOWNSPREAD_CTRL, 0); | 740 | DP_DOWNSPREAD_CTRL, 0); |
734 | 741 | ||
735 | radeon_dp_set_panel_mode(dp_info->encoder, dp_info->connector); | 742 | if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) && |
743 | (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { | ||
744 | radeon_write_dpcd_reg(dp_info->radeon_connector, DP_EDP_CONFIGURATION_SET, 1); | ||
745 | } | ||
736 | 746 | ||
737 | /* set the lane count on the sink */ | 747 | /* set the lane count on the sink */ |
738 | tmp = dp_info->dp_lane_count; | 748 | tmp = dp_info->dp_lane_count; |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index f1f06ca9f1f5..b88c4608731b 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -57,22 +57,6 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) | |||
57 | } | 57 | } |
58 | } | 58 | } |
59 | 59 | ||
60 | static struct drm_connector * | ||
61 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) | ||
62 | { | ||
63 | struct drm_device *dev = encoder->dev; | ||
64 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
65 | struct drm_connector *connector; | ||
66 | struct radeon_connector *radeon_connector; | ||
67 | |||
68 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
69 | radeon_connector = to_radeon_connector(connector); | ||
70 | if (radeon_encoder->devices & radeon_connector->devices) | ||
71 | return connector; | ||
72 | } | ||
73 | return NULL; | ||
74 | } | ||
75 | |||
76 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | 60 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, |
77 | struct drm_display_mode *mode, | 61 | struct drm_display_mode *mode, |
78 | struct drm_display_mode *adjusted_mode) | 62 | struct drm_display_mode *adjusted_mode) |
@@ -253,7 +237,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action) | |||
253 | /* R4xx, R5xx */ | 237 | /* R4xx, R5xx */ |
254 | args.ext_tmds.sXTmdsEncoder.ucEnable = action; | 238 | args.ext_tmds.sXTmdsEncoder.ucEnable = action; |
255 | 239 | ||
256 | if (radeon_encoder->pixel_clock > 165000) | 240 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
257 | args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 241 | args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
258 | 242 | ||
259 | args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB; | 243 | args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB; |
@@ -265,7 +249,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action) | |||
265 | /* DFP1, CRT1, TV1 depending on the type of port */ | 249 | /* DFP1, CRT1, TV1 depending on the type of port */ |
266 | args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX; | 250 | args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX; |
267 | 251 | ||
268 | if (radeon_encoder->pixel_clock > 165000) | 252 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
269 | args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL; | 253 | args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL; |
270 | break; | 254 | break; |
271 | case 3: | 255 | case 3: |
@@ -349,7 +333,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
349 | } else { | 333 | } else { |
350 | if (dig->linkb) | 334 | if (dig->linkb) |
351 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 335 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
352 | if (radeon_encoder->pixel_clock > 165000) | 336 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
353 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 337 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
354 | /*if (pScrn->rgbBits == 8) */ | 338 | /*if (pScrn->rgbBits == 8) */ |
355 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; | 339 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; |
@@ -388,7 +372,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
388 | } else { | 372 | } else { |
389 | if (dig->linkb) | 373 | if (dig->linkb) |
390 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 374 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
391 | if (radeon_encoder->pixel_clock > 165000) | 375 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
392 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 376 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
393 | } | 377 | } |
394 | break; | 378 | break; |
@@ -432,7 +416,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
432 | switch (connector->connector_type) { | 416 | switch (connector->connector_type) { |
433 | case DRM_MODE_CONNECTOR_DVII: | 417 | case DRM_MODE_CONNECTOR_DVII: |
434 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | 418 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ |
435 | if (drm_detect_monitor_audio(radeon_connector->edid) && | 419 | if (drm_detect_hdmi_monitor(radeon_connector->edid) && |
436 | radeon_audio) | 420 | radeon_audio) |
437 | return ATOM_ENCODER_MODE_HDMI; | 421 | return ATOM_ENCODER_MODE_HDMI; |
438 | else if (radeon_connector->use_digital) | 422 | else if (radeon_connector->use_digital) |
@@ -443,7 +427,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
443 | case DRM_MODE_CONNECTOR_DVID: | 427 | case DRM_MODE_CONNECTOR_DVID: |
444 | case DRM_MODE_CONNECTOR_HDMIA: | 428 | case DRM_MODE_CONNECTOR_HDMIA: |
445 | default: | 429 | default: |
446 | if (drm_detect_monitor_audio(radeon_connector->edid) && | 430 | if (drm_detect_hdmi_monitor(radeon_connector->edid) && |
447 | radeon_audio) | 431 | radeon_audio) |
448 | return ATOM_ENCODER_MODE_HDMI; | 432 | return ATOM_ENCODER_MODE_HDMI; |
449 | else | 433 | else |
@@ -457,7 +441,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
457 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 441 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
458 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | 442 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) |
459 | return ATOM_ENCODER_MODE_DP; | 443 | return ATOM_ENCODER_MODE_DP; |
460 | else if (drm_detect_monitor_audio(radeon_connector->edid) && | 444 | else if (drm_detect_hdmi_monitor(radeon_connector->edid) && |
461 | radeon_audio) | 445 | radeon_audio) |
462 | return ATOM_ENCODER_MODE_HDMI; | 446 | return ATOM_ENCODER_MODE_HDMI; |
463 | else | 447 | else |
@@ -587,7 +571,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
587 | 571 | ||
588 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | 572 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) |
589 | args.v1.ucLaneNum = dp_lane_count; | 573 | args.v1.ucLaneNum = dp_lane_count; |
590 | else if (radeon_encoder->pixel_clock > 165000) | 574 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
591 | args.v1.ucLaneNum = 8; | 575 | args.v1.ucLaneNum = 8; |
592 | else | 576 | else |
593 | args.v1.ucLaneNum = 4; | 577 | args.v1.ucLaneNum = 4; |
@@ -622,7 +606,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
622 | 606 | ||
623 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | 607 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) |
624 | args.v3.ucLaneNum = dp_lane_count; | 608 | args.v3.ucLaneNum = dp_lane_count; |
625 | else if (radeon_encoder->pixel_clock > 165000) | 609 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
626 | args.v3.ucLaneNum = 8; | 610 | args.v3.ucLaneNum = 8; |
627 | else | 611 | else |
628 | args.v3.ucLaneNum = 4; | 612 | args.v3.ucLaneNum = 4; |
@@ -662,7 +646,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
662 | 646 | ||
663 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | 647 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) |
664 | args.v4.ucLaneNum = dp_lane_count; | 648 | args.v4.ucLaneNum = dp_lane_count; |
665 | else if (radeon_encoder->pixel_clock > 165000) | 649 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
666 | args.v4.ucLaneNum = 8; | 650 | args.v4.ucLaneNum = 8; |
667 | else | 651 | else |
668 | args.v4.ucLaneNum = 4; | 652 | args.v4.ucLaneNum = 4; |
@@ -806,7 +790,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
806 | if (is_dp) | 790 | if (is_dp) |
807 | args.v1.usPixelClock = | 791 | args.v1.usPixelClock = |
808 | cpu_to_le16(dp_clock / 10); | 792 | cpu_to_le16(dp_clock / 10); |
809 | else if (radeon_encoder->pixel_clock > 165000) | 793 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
810 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 794 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
811 | else | 795 | else |
812 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 796 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
@@ -821,7 +805,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
821 | 805 | ||
822 | if ((rdev->flags & RADEON_IS_IGP) && | 806 | if ((rdev->flags & RADEON_IS_IGP) && |
823 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { | 807 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { |
824 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { | 808 | if (is_dp || |
809 | !radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) { | ||
825 | if (igp_lane_info & 0x1) | 810 | if (igp_lane_info & 0x1) |
826 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | 811 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; |
827 | else if (igp_lane_info & 0x2) | 812 | else if (igp_lane_info & 0x2) |
@@ -848,7 +833,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
848 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 833 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
849 | if (dig->coherent_mode) | 834 | if (dig->coherent_mode) |
850 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | 835 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; |
851 | if (radeon_encoder->pixel_clock > 165000) | 836 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
852 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; | 837 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; |
853 | } | 838 | } |
854 | break; | 839 | break; |
@@ -863,7 +848,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
863 | if (is_dp) | 848 | if (is_dp) |
864 | args.v2.usPixelClock = | 849 | args.v2.usPixelClock = |
865 | cpu_to_le16(dp_clock / 10); | 850 | cpu_to_le16(dp_clock / 10); |
866 | else if (radeon_encoder->pixel_clock > 165000) | 851 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
867 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 852 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
868 | else | 853 | else |
869 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 854 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
@@ -891,7 +876,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
891 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 876 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
892 | if (dig->coherent_mode) | 877 | if (dig->coherent_mode) |
893 | args.v2.acConfig.fCoherentMode = 1; | 878 | args.v2.acConfig.fCoherentMode = 1; |
894 | if (radeon_encoder->pixel_clock > 165000) | 879 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
895 | args.v2.acConfig.fDualLinkConnector = 1; | 880 | args.v2.acConfig.fDualLinkConnector = 1; |
896 | } | 881 | } |
897 | break; | 882 | break; |
@@ -906,7 +891,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
906 | if (is_dp) | 891 | if (is_dp) |
907 | args.v3.usPixelClock = | 892 | args.v3.usPixelClock = |
908 | cpu_to_le16(dp_clock / 10); | 893 | cpu_to_le16(dp_clock / 10); |
909 | else if (radeon_encoder->pixel_clock > 165000) | 894 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
910 | args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 895 | args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
911 | else | 896 | else |
912 | args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 897 | args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
@@ -914,7 +899,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
914 | 899 | ||
915 | if (is_dp) | 900 | if (is_dp) |
916 | args.v3.ucLaneNum = dp_lane_count; | 901 | args.v3.ucLaneNum = dp_lane_count; |
917 | else if (radeon_encoder->pixel_clock > 165000) | 902 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
918 | args.v3.ucLaneNum = 8; | 903 | args.v3.ucLaneNum = 8; |
919 | else | 904 | else |
920 | args.v3.ucLaneNum = 4; | 905 | args.v3.ucLaneNum = 4; |
@@ -951,7 +936,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
951 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 936 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
952 | if (dig->coherent_mode) | 937 | if (dig->coherent_mode) |
953 | args.v3.acConfig.fCoherentMode = 1; | 938 | args.v3.acConfig.fCoherentMode = 1; |
954 | if (radeon_encoder->pixel_clock > 165000) | 939 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
955 | args.v3.acConfig.fDualLinkConnector = 1; | 940 | args.v3.acConfig.fDualLinkConnector = 1; |
956 | } | 941 | } |
957 | break; | 942 | break; |
@@ -966,7 +951,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
966 | if (is_dp) | 951 | if (is_dp) |
967 | args.v4.usPixelClock = | 952 | args.v4.usPixelClock = |
968 | cpu_to_le16(dp_clock / 10); | 953 | cpu_to_le16(dp_clock / 10); |
969 | else if (radeon_encoder->pixel_clock > 165000) | 954 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
970 | args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 955 | args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
971 | else | 956 | else |
972 | args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 957 | args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
@@ -974,7 +959,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
974 | 959 | ||
975 | if (is_dp) | 960 | if (is_dp) |
976 | args.v4.ucLaneNum = dp_lane_count; | 961 | args.v4.ucLaneNum = dp_lane_count; |
977 | else if (radeon_encoder->pixel_clock > 165000) | 962 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
978 | args.v4.ucLaneNum = 8; | 963 | args.v4.ucLaneNum = 8; |
979 | else | 964 | else |
980 | args.v4.ucLaneNum = 4; | 965 | args.v4.ucLaneNum = 4; |
@@ -1014,7 +999,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
1014 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 999 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
1015 | if (dig->coherent_mode) | 1000 | if (dig->coherent_mode) |
1016 | args.v4.acConfig.fCoherentMode = 1; | 1001 | args.v4.acConfig.fCoherentMode = 1; |
1017 | if (radeon_encoder->pixel_clock > 165000) | 1002 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
1018 | args.v4.acConfig.fDualLinkConnector = 1; | 1003 | args.v4.acConfig.fDualLinkConnector = 1; |
1019 | } | 1004 | } |
1020 | break; | 1005 | break; |
@@ -1137,7 +1122,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
1137 | if (dp_clock == 270000) | 1122 | if (dp_clock == 270000) |
1138 | args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | 1123 | args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; |
1139 | args.v1.sDigEncoder.ucLaneNum = dp_lane_count; | 1124 | args.v1.sDigEncoder.ucLaneNum = dp_lane_count; |
1140 | } else if (radeon_encoder->pixel_clock > 165000) | 1125 | } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
1141 | args.v1.sDigEncoder.ucLaneNum = 8; | 1126 | args.v1.sDigEncoder.ucLaneNum = 8; |
1142 | else | 1127 | else |
1143 | args.v1.sDigEncoder.ucLaneNum = 4; | 1128 | args.v1.sDigEncoder.ucLaneNum = 4; |
@@ -1156,7 +1141,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
1156 | else if (dp_clock == 540000) | 1141 | else if (dp_clock == 540000) |
1157 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; | 1142 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; |
1158 | args.v3.sExtEncoder.ucLaneNum = dp_lane_count; | 1143 | args.v3.sExtEncoder.ucLaneNum = dp_lane_count; |
1159 | } else if (radeon_encoder->pixel_clock > 165000) | 1144 | } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
1160 | args.v3.sExtEncoder.ucLaneNum = 8; | 1145 | args.v3.sExtEncoder.ucLaneNum = 8; |
1161 | else | 1146 | else |
1162 | args.v3.sExtEncoder.ucLaneNum = 4; | 1147 | args.v3.sExtEncoder.ucLaneNum = 4; |
@@ -1341,7 +1326,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1341 | switch (mode) { | 1326 | switch (mode) { |
1342 | case DRM_MODE_DPMS_ON: | 1327 | case DRM_MODE_DPMS_ON: |
1343 | /* some early dce3.2 boards have a bug in their transmitter control table */ | 1328 | /* some early dce3.2 boards have a bug in their transmitter control table */ |
1344 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730)) | 1329 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || |
1330 | ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) | ||
1345 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1331 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
1346 | else | 1332 | else |
1347 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | 1333 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
@@ -1351,8 +1337,6 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1351 | ATOM_TRANSMITTER_ACTION_POWER_ON); | 1337 | ATOM_TRANSMITTER_ACTION_POWER_ON); |
1352 | radeon_dig_connector->edp_on = true; | 1338 | radeon_dig_connector->edp_on = true; |
1353 | } | 1339 | } |
1354 | if (ASIC_IS_DCE4(rdev)) | ||
1355 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | ||
1356 | radeon_dp_link_train(encoder, connector); | 1340 | radeon_dp_link_train(encoder, connector); |
1357 | if (ASIC_IS_DCE4(rdev)) | 1341 | if (ASIC_IS_DCE4(rdev)) |
1358 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); | 1342 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); |
@@ -1363,7 +1347,10 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1363 | case DRM_MODE_DPMS_STANDBY: | 1347 | case DRM_MODE_DPMS_STANDBY: |
1364 | case DRM_MODE_DPMS_SUSPEND: | 1348 | case DRM_MODE_DPMS_SUSPEND: |
1365 | case DRM_MODE_DPMS_OFF: | 1349 | case DRM_MODE_DPMS_OFF: |
1366 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | 1350 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) |
1351 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1352 | else | ||
1353 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
1367 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1354 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
1368 | if (ASIC_IS_DCE4(rdev)) | 1355 | if (ASIC_IS_DCE4(rdev)) |
1369 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | 1356 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); |
@@ -1810,7 +1797,21 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1810 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1797 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
1811 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1798 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1812 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1799 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1813 | if (ASIC_IS_DCE4(rdev)) { | 1800 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { |
1801 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
1802 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
1803 | |||
1804 | if (!connector) | ||
1805 | dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | ||
1806 | else | ||
1807 | dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); | ||
1808 | |||
1809 | /* setup and enable the encoder */ | ||
1810 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
1811 | atombios_dig_encoder_setup(encoder, | ||
1812 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | ||
1813 | dig->panel_mode); | ||
1814 | } else if (ASIC_IS_DCE4(rdev)) { | ||
1814 | /* disable the transmitter */ | 1815 | /* disable the transmitter */ |
1815 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | 1816 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
1816 | /* setup and enable the encoder */ | 1817 | /* setup and enable the encoder */ |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 636660fca8c2..f58254a3fb01 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -1455,6 +1455,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) | |||
1455 | #endif | 1455 | #endif |
1456 | WREG32(CP_RB_CNTL, tmp); | 1456 | WREG32(CP_RB_CNTL, tmp); |
1457 | WREG32(CP_SEM_WAIT_TIMER, 0x0); | 1457 | WREG32(CP_SEM_WAIT_TIMER, 0x0); |
1458 | WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); | ||
1458 | 1459 | ||
1459 | /* Set the write pointer delay */ | 1460 | /* Set the write pointer delay */ |
1460 | WREG32(CP_RB_WPTR_DELAY, 0); | 1461 | WREG32(CP_RB_WPTR_DELAY, 0); |
@@ -3190,6 +3191,7 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
3190 | if (r) { | 3191 | if (r) { |
3191 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); | 3192 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); |
3192 | rdev->accel_working = false; | 3193 | rdev->accel_working = false; |
3194 | return r; | ||
3193 | } | 3195 | } |
3194 | 3196 | ||
3195 | r = r600_audio_init(rdev); | 3197 | r = r600_audio_init(rdev); |
@@ -3221,6 +3223,7 @@ int evergreen_resume(struct radeon_device *rdev) | |||
3221 | r = evergreen_startup(rdev); | 3223 | r = evergreen_startup(rdev); |
3222 | if (r) { | 3224 | if (r) { |
3223 | DRM_ERROR("evergreen startup failed on resume\n"); | 3225 | DRM_ERROR("evergreen startup failed on resume\n"); |
3226 | rdev->accel_working = false; | ||
3224 | return r; | 3227 | return r; |
3225 | } | 3228 | } |
3226 | 3229 | ||
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index b502216d42af..74713d42df29 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -108,6 +108,7 @@ | |||
108 | #define CP_RB_WPTR_ADDR_HI 0xC11C | 108 | #define CP_RB_WPTR_ADDR_HI 0xC11C |
109 | #define CP_RB_WPTR_DELAY 0x8704 | 109 | #define CP_RB_WPTR_DELAY 0x8704 |
110 | #define CP_SEM_WAIT_TIMER 0x85BC | 110 | #define CP_SEM_WAIT_TIMER 0x85BC |
111 | #define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8 | ||
111 | #define CP_DEBUG 0xC1FC | 112 | #define CP_DEBUG 0xC1FC |
112 | 113 | ||
113 | 114 | ||
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 321137295400..2509c505acb8 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -1219,6 +1219,7 @@ int cayman_cp_resume(struct radeon_device *rdev) | |||
1219 | RREG32(GRBM_SOFT_RESET); | 1219 | RREG32(GRBM_SOFT_RESET); |
1220 | 1220 | ||
1221 | WREG32(CP_SEM_WAIT_TIMER, 0x0); | 1221 | WREG32(CP_SEM_WAIT_TIMER, 0x0); |
1222 | WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); | ||
1222 | 1223 | ||
1223 | /* Set the write pointer delay */ | 1224 | /* Set the write pointer delay */ |
1224 | WREG32(CP_RB_WPTR_DELAY, 0); | 1225 | WREG32(CP_RB_WPTR_DELAY, 0); |
@@ -1546,6 +1547,7 @@ int cayman_resume(struct radeon_device *rdev) | |||
1546 | r = cayman_startup(rdev); | 1547 | r = cayman_startup(rdev); |
1547 | if (r) { | 1548 | if (r) { |
1548 | DRM_ERROR("cayman startup failed on resume\n"); | 1549 | DRM_ERROR("cayman startup failed on resume\n"); |
1550 | rdev->accel_working = false; | ||
1549 | return r; | 1551 | return r; |
1550 | } | 1552 | } |
1551 | return r; | 1553 | return r; |
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index f9df2a645e79..9a7f3b6e02de 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h | |||
@@ -222,6 +222,7 @@ | |||
222 | #define SCRATCH_UMSK 0x8540 | 222 | #define SCRATCH_UMSK 0x8540 |
223 | #define SCRATCH_ADDR 0x8544 | 223 | #define SCRATCH_ADDR 0x8544 |
224 | #define CP_SEM_WAIT_TIMER 0x85BC | 224 | #define CP_SEM_WAIT_TIMER 0x85BC |
225 | #define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8 | ||
225 | #define CP_COHER_CNTL2 0x85E8 | 226 | #define CP_COHER_CNTL2 0x85E8 |
226 | #define CP_ME_CNTL 0x86D8 | 227 | #define CP_ME_CNTL 0x86D8 |
227 | #define CP_ME_HALT (1 << 28) | 228 | #define CP_ME_HALT (1 << 28) |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index bfd36ab643a6..333cde9d4e7b 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -789,9 +789,7 @@ int r100_irq_process(struct radeon_device *rdev) | |||
789 | WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM); | 789 | WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM); |
790 | break; | 790 | break; |
791 | default: | 791 | default: |
792 | msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; | 792 | WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); |
793 | WREG32(RADEON_MSI_REARM_EN, msi_rearm); | ||
794 | WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); | ||
795 | break; | 793 | break; |
796 | } | 794 | } |
797 | } | 795 | } |
@@ -3930,6 +3928,8 @@ static int r100_startup(struct radeon_device *rdev) | |||
3930 | 3928 | ||
3931 | int r100_resume(struct radeon_device *rdev) | 3929 | int r100_resume(struct radeon_device *rdev) |
3932 | { | 3930 | { |
3931 | int r; | ||
3932 | |||
3933 | /* Make sur GART are not working */ | 3933 | /* Make sur GART are not working */ |
3934 | if (rdev->flags & RADEON_IS_PCI) | 3934 | if (rdev->flags & RADEON_IS_PCI) |
3935 | r100_pci_gart_disable(rdev); | 3935 | r100_pci_gart_disable(rdev); |
@@ -3949,7 +3949,11 @@ int r100_resume(struct radeon_device *rdev) | |||
3949 | radeon_surface_init(rdev); | 3949 | radeon_surface_init(rdev); |
3950 | 3950 | ||
3951 | rdev->accel_working = true; | 3951 | rdev->accel_working = true; |
3952 | return r100_startup(rdev); | 3952 | r = r100_startup(rdev); |
3953 | if (r) { | ||
3954 | rdev->accel_working = false; | ||
3955 | } | ||
3956 | return r; | ||
3953 | } | 3957 | } |
3954 | 3958 | ||
3955 | int r100_suspend(struct radeon_device *rdev) | 3959 | int r100_suspend(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 3fc0d29a5f39..6829638cca40 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -1431,6 +1431,8 @@ static int r300_startup(struct radeon_device *rdev) | |||
1431 | 1431 | ||
1432 | int r300_resume(struct radeon_device *rdev) | 1432 | int r300_resume(struct radeon_device *rdev) |
1433 | { | 1433 | { |
1434 | int r; | ||
1435 | |||
1434 | /* Make sur GART are not working */ | 1436 | /* Make sur GART are not working */ |
1435 | if (rdev->flags & RADEON_IS_PCIE) | 1437 | if (rdev->flags & RADEON_IS_PCIE) |
1436 | rv370_pcie_gart_disable(rdev); | 1438 | rv370_pcie_gart_disable(rdev); |
@@ -1452,7 +1454,11 @@ int r300_resume(struct radeon_device *rdev) | |||
1452 | radeon_surface_init(rdev); | 1454 | radeon_surface_init(rdev); |
1453 | 1455 | ||
1454 | rdev->accel_working = true; | 1456 | rdev->accel_working = true; |
1455 | return r300_startup(rdev); | 1457 | r = r300_startup(rdev); |
1458 | if (r) { | ||
1459 | rdev->accel_working = false; | ||
1460 | } | ||
1461 | return r; | ||
1456 | } | 1462 | } |
1457 | 1463 | ||
1458 | int r300_suspend(struct radeon_device *rdev) | 1464 | int r300_suspend(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 666e28fe509c..b14323053bad 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
@@ -291,6 +291,8 @@ static int r420_startup(struct radeon_device *rdev) | |||
291 | 291 | ||
292 | int r420_resume(struct radeon_device *rdev) | 292 | int r420_resume(struct radeon_device *rdev) |
293 | { | 293 | { |
294 | int r; | ||
295 | |||
294 | /* Make sur GART are not working */ | 296 | /* Make sur GART are not working */ |
295 | if (rdev->flags & RADEON_IS_PCIE) | 297 | if (rdev->flags & RADEON_IS_PCIE) |
296 | rv370_pcie_gart_disable(rdev); | 298 | rv370_pcie_gart_disable(rdev); |
@@ -316,7 +318,11 @@ int r420_resume(struct radeon_device *rdev) | |||
316 | radeon_surface_init(rdev); | 318 | radeon_surface_init(rdev); |
317 | 319 | ||
318 | rdev->accel_working = true; | 320 | rdev->accel_working = true; |
319 | return r420_startup(rdev); | 321 | r = r420_startup(rdev); |
322 | if (r) { | ||
323 | rdev->accel_working = false; | ||
324 | } | ||
325 | return r; | ||
320 | } | 326 | } |
321 | 327 | ||
322 | int r420_suspend(struct radeon_device *rdev) | 328 | int r420_suspend(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 4ae1615e752f..25084e824dbc 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
@@ -218,6 +218,8 @@ static int r520_startup(struct radeon_device *rdev) | |||
218 | 218 | ||
219 | int r520_resume(struct radeon_device *rdev) | 219 | int r520_resume(struct radeon_device *rdev) |
220 | { | 220 | { |
221 | int r; | ||
222 | |||
221 | /* Make sur GART are not working */ | 223 | /* Make sur GART are not working */ |
222 | if (rdev->flags & RADEON_IS_PCIE) | 224 | if (rdev->flags & RADEON_IS_PCIE) |
223 | rv370_pcie_gart_disable(rdev); | 225 | rv370_pcie_gart_disable(rdev); |
@@ -237,7 +239,11 @@ int r520_resume(struct radeon_device *rdev) | |||
237 | radeon_surface_init(rdev); | 239 | radeon_surface_init(rdev); |
238 | 240 | ||
239 | rdev->accel_working = true; | 241 | rdev->accel_working = true; |
240 | return r520_startup(rdev); | 242 | r = r520_startup(rdev); |
243 | if (r) { | ||
244 | rdev->accel_working = false; | ||
245 | } | ||
246 | return r; | ||
241 | } | 247 | } |
242 | 248 | ||
243 | int r520_init(struct radeon_device *rdev) | 249 | int r520_init(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 4f08e5e6ee9d..17ca72ce3027 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2362,6 +2362,9 @@ void r600_semaphore_ring_emit(struct radeon_device *rdev, | |||
2362 | uint64_t addr = semaphore->gpu_addr; | 2362 | uint64_t addr = semaphore->gpu_addr; |
2363 | unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; | 2363 | unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; |
2364 | 2364 | ||
2365 | if (rdev->family < CHIP_CAYMAN) | ||
2366 | sel |= PACKET3_SEM_WAIT_ON_SIGNAL; | ||
2367 | |||
2365 | radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); | 2368 | radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); |
2366 | radeon_ring_write(ring, addr & 0xffffffff); | 2369 | radeon_ring_write(ring, addr & 0xffffffff); |
2367 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel); | 2370 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel); |
@@ -2529,6 +2532,7 @@ int r600_resume(struct radeon_device *rdev) | |||
2529 | r = r600_startup(rdev); | 2532 | r = r600_startup(rdev); |
2530 | if (r) { | 2533 | if (r) { |
2531 | DRM_ERROR("r600 startup failed on resume\n"); | 2534 | DRM_ERROR("r600 startup failed on resume\n"); |
2535 | rdev->accel_working = false; | ||
2532 | return r; | 2536 | return r; |
2533 | } | 2537 | } |
2534 | 2538 | ||
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index d996f4381130..accc032c103f 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -468,27 +468,42 @@ set_default_state(struct radeon_device *rdev) | |||
468 | radeon_ring_write(ring, sq_stack_resource_mgmt_2); | 468 | radeon_ring_write(ring, sq_stack_resource_mgmt_2); |
469 | } | 469 | } |
470 | 470 | ||
471 | #define I2F_MAX_BITS 15 | ||
472 | #define I2F_MAX_INPUT ((1 << I2F_MAX_BITS) - 1) | ||
473 | #define I2F_SHIFT (24 - I2F_MAX_BITS) | ||
474 | |||
475 | /* | ||
476 | * Converts unsigned integer into 32-bit IEEE floating point representation. | ||
477 | * Conversion is not universal and only works for the range from 0 | ||
478 | * to 2^I2F_MAX_BITS-1. Currently we only use it with inputs between | ||
479 | * 0 and 16384 (inclusive), so I2F_MAX_BITS=15 is enough. If necessary, | ||
480 | * I2F_MAX_BITS can be increased, but that will add to the loop iterations | ||
481 | * and slow us down. Conversion is done by shifting the input and counting | ||
482 | * down until the first 1 reaches bit position 23. The resulting counter | ||
483 | * and the shifted input are, respectively, the exponent and the fraction. | ||
484 | * The sign is always zero. | ||
485 | */ | ||
471 | static uint32_t i2f(uint32_t input) | 486 | static uint32_t i2f(uint32_t input) |
472 | { | 487 | { |
473 | u32 result, i, exponent, fraction; | 488 | u32 result, i, exponent, fraction; |
474 | 489 | ||
475 | if ((input & 0x3fff) == 0) | 490 | WARN_ON_ONCE(input > I2F_MAX_INPUT); |
476 | result = 0; /* 0 is a special case */ | 491 | |
492 | if ((input & I2F_MAX_INPUT) == 0) | ||
493 | result = 0; | ||
477 | else { | 494 | else { |
478 | exponent = 140; /* exponent biased by 127; */ | 495 | exponent = 126 + I2F_MAX_BITS; |
479 | fraction = (input & 0x3fff) << 10; /* cheat and only | 496 | fraction = (input & I2F_MAX_INPUT) << I2F_SHIFT; |
480 | handle numbers below 2^^15 */ | 497 | |
481 | for (i = 0; i < 14; i++) { | 498 | for (i = 0; i < I2F_MAX_BITS; i++) { |
482 | if (fraction & 0x800000) | 499 | if (fraction & 0x800000) |
483 | break; | 500 | break; |
484 | else { | 501 | else { |
485 | fraction = fraction << 1; /* keep | 502 | fraction = fraction << 1; |
486 | shifting left until top bit = 1 */ | ||
487 | exponent = exponent - 1; | 503 | exponent = exponent - 1; |
488 | } | 504 | } |
489 | } | 505 | } |
490 | result = exponent << 23 | (fraction & 0x7fffff); /* mask | 506 | result = exponent << 23 | (fraction & 0x7fffff); |
491 | off top bit; assumed 1 */ | ||
492 | } | 507 | } |
493 | return result; | 508 | return result; |
494 | } | 509 | } |
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index 2d1f6c5ee2a7..73e2c7c6edbc 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c | |||
@@ -314,6 +314,10 @@ const u32 r6xx_default_state[] = | |||
314 | 0x00000000, /* VGT_VTX_CNT_EN */ | 314 | 0x00000000, /* VGT_VTX_CNT_EN */ |
315 | 315 | ||
316 | 0xc0016900, | 316 | 0xc0016900, |
317 | 0x000000d4, | ||
318 | 0x00000000, /* SX_MISC */ | ||
319 | |||
320 | 0xc0016900, | ||
317 | 0x000002c8, | 321 | 0x000002c8, |
318 | 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ | 322 | 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ |
319 | 323 | ||
@@ -626,6 +630,10 @@ const u32 r7xx_default_state[] = | |||
626 | 0x00000000, /* VGT_VTX_CNT_EN */ | 630 | 0x00000000, /* VGT_VTX_CNT_EN */ |
627 | 631 | ||
628 | 0xc0016900, | 632 | 0xc0016900, |
633 | 0x000000d4, | ||
634 | 0x00000000, /* SX_MISC */ | ||
635 | |||
636 | 0xc0016900, | ||
629 | 0x000002c8, | 637 | 0x000002c8, |
630 | 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ | 638 | 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ |
631 | 639 | ||
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 38ce5d0427e3..387fcc9f03ef 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -1304,6 +1304,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1304 | h0 = G_038004_TEX_HEIGHT(word1) + 1; | 1304 | h0 = G_038004_TEX_HEIGHT(word1) + 1; |
1305 | d0 = G_038004_TEX_DEPTH(word1); | 1305 | d0 = G_038004_TEX_DEPTH(word1); |
1306 | nfaces = 1; | 1306 | nfaces = 1; |
1307 | array = 0; | ||
1307 | switch (G_038000_DIM(word0)) { | 1308 | switch (G_038000_DIM(word0)) { |
1308 | case V_038000_SQ_TEX_DIM_1D: | 1309 | case V_038000_SQ_TEX_DIM_1D: |
1309 | case V_038000_SQ_TEX_DIM_2D: | 1310 | case V_038000_SQ_TEX_DIM_2D: |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 3ee1fd7ef394..9b23670716f1 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -831,6 +831,7 @@ | |||
831 | #define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 | 831 | #define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 |
832 | #define PACKET3_INDIRECT_BUFFER_MP 0x38 | 832 | #define PACKET3_INDIRECT_BUFFER_MP 0x38 |
833 | #define PACKET3_MEM_SEMAPHORE 0x39 | 833 | #define PACKET3_MEM_SEMAPHORE 0x39 |
834 | # define PACKET3_SEM_WAIT_ON_SIGNAL (0x1 << 12) | ||
834 | # define PACKET3_SEM_SEL_SIGNAL (0x6 << 29) | 835 | # define PACKET3_SEM_SEL_SIGNAL (0x6 << 29) |
835 | # define PACKET3_SEM_SEL_WAIT (0x7 << 29) | 836 | # define PACKET3_SEM_SEL_WAIT (0x7 << 29) |
836 | #define PACKET3_MPEG_INDEX 0x3A | 837 | #define PACKET3_MPEG_INDEX 0x3A |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 73e05cb85eca..1668ec1ee770 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -157,6 +157,47 @@ bool radeon_get_bios(struct radeon_device *rdev); | |||
157 | 157 | ||
158 | 158 | ||
159 | /* | 159 | /* |
160 | * Mutex which allows recursive locking from the same process. | ||
161 | */ | ||
162 | struct radeon_mutex { | ||
163 | struct mutex mutex; | ||
164 | struct task_struct *owner; | ||
165 | int level; | ||
166 | }; | ||
167 | |||
168 | static inline void radeon_mutex_init(struct radeon_mutex *mutex) | ||
169 | { | ||
170 | mutex_init(&mutex->mutex); | ||
171 | mutex->owner = NULL; | ||
172 | mutex->level = 0; | ||
173 | } | ||
174 | |||
175 | static inline void radeon_mutex_lock(struct radeon_mutex *mutex) | ||
176 | { | ||
177 | if (mutex_trylock(&mutex->mutex)) { | ||
178 | /* The mutex was unlocked before, so it's ours now */ | ||
179 | mutex->owner = current; | ||
180 | } else if (mutex->owner != current) { | ||
181 | /* Another process locked the mutex, take it */ | ||
182 | mutex_lock(&mutex->mutex); | ||
183 | mutex->owner = current; | ||
184 | } | ||
185 | /* Otherwise the mutex was already locked by this process */ | ||
186 | |||
187 | mutex->level++; | ||
188 | } | ||
189 | |||
190 | static inline void radeon_mutex_unlock(struct radeon_mutex *mutex) | ||
191 | { | ||
192 | if (--mutex->level > 0) | ||
193 | return; | ||
194 | |||
195 | mutex->owner = NULL; | ||
196 | mutex_unlock(&mutex->mutex); | ||
197 | } | ||
198 | |||
199 | |||
200 | /* | ||
160 | * Dummy page | 201 | * Dummy page |
161 | */ | 202 | */ |
162 | struct radeon_dummy_page { | 203 | struct radeon_dummy_page { |
@@ -598,7 +639,7 @@ struct radeon_ib { | |||
598 | * mutex protects scheduled_ibs, ready, alloc_bm | 639 | * mutex protects scheduled_ibs, ready, alloc_bm |
599 | */ | 640 | */ |
600 | struct radeon_ib_pool { | 641 | struct radeon_ib_pool { |
601 | struct mutex mutex; | 642 | struct radeon_mutex mutex; |
602 | struct radeon_sa_manager sa_manager; | 643 | struct radeon_sa_manager sa_manager; |
603 | struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; | 644 | struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; |
604 | bool ready; | 645 | bool ready; |
@@ -1355,47 +1396,6 @@ struct r600_vram_scratch { | |||
1355 | 1396 | ||
1356 | 1397 | ||
1357 | /* | 1398 | /* |
1358 | * Mutex which allows recursive locking from the same process. | ||
1359 | */ | ||
1360 | struct radeon_mutex { | ||
1361 | struct mutex mutex; | ||
1362 | struct task_struct *owner; | ||
1363 | int level; | ||
1364 | }; | ||
1365 | |||
1366 | static inline void radeon_mutex_init(struct radeon_mutex *mutex) | ||
1367 | { | ||
1368 | mutex_init(&mutex->mutex); | ||
1369 | mutex->owner = NULL; | ||
1370 | mutex->level = 0; | ||
1371 | } | ||
1372 | |||
1373 | static inline void radeon_mutex_lock(struct radeon_mutex *mutex) | ||
1374 | { | ||
1375 | if (mutex_trylock(&mutex->mutex)) { | ||
1376 | /* The mutex was unlocked before, so it's ours now */ | ||
1377 | mutex->owner = current; | ||
1378 | } else if (mutex->owner != current) { | ||
1379 | /* Another process locked the mutex, take it */ | ||
1380 | mutex_lock(&mutex->mutex); | ||
1381 | mutex->owner = current; | ||
1382 | } | ||
1383 | /* Otherwise the mutex was already locked by this process */ | ||
1384 | |||
1385 | mutex->level++; | ||
1386 | } | ||
1387 | |||
1388 | static inline void radeon_mutex_unlock(struct radeon_mutex *mutex) | ||
1389 | { | ||
1390 | if (--mutex->level > 0) | ||
1391 | return; | ||
1392 | |||
1393 | mutex->owner = NULL; | ||
1394 | mutex_unlock(&mutex->mutex); | ||
1395 | } | ||
1396 | |||
1397 | |||
1398 | /* | ||
1399 | * Core structure, functions and helpers. | 1399 | * Core structure, functions and helpers. |
1400 | */ | 1400 | */ |
1401 | typedef uint32_t (*radeon_rreg_t)(struct radeon_device*, uint32_t); | 1401 | typedef uint32_t (*radeon_rreg_t)(struct radeon_device*, uint32_t); |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 5082d17d14dc..1f53ae74ada1 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -2931,6 +2931,20 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
2931 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5; | 2931 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5; |
2932 | } | 2932 | } |
2933 | } | 2933 | } |
2934 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP6_SUPPORT) && | ||
2935 | (radeon_connector->devices & ATOM_DEVICE_DFP6_SUPPORT)) { | ||
2936 | if (connected) { | ||
2937 | DRM_DEBUG_KMS("DFP6 connected\n"); | ||
2938 | bios_0_scratch |= ATOM_S0_DFP6; | ||
2939 | bios_3_scratch |= ATOM_S3_DFP6_ACTIVE; | ||
2940 | bios_6_scratch |= ATOM_S6_ACC_REQ_DFP6; | ||
2941 | } else { | ||
2942 | DRM_DEBUG_KMS("DFP6 disconnected\n"); | ||
2943 | bios_0_scratch &= ~ATOM_S0_DFP6; | ||
2944 | bios_3_scratch &= ~ATOM_S3_DFP6_ACTIVE; | ||
2945 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP6; | ||
2946 | } | ||
2947 | } | ||
2934 | 2948 | ||
2935 | if (rdev->family >= CHIP_R600) { | 2949 | if (rdev->family >= CHIP_R600) { |
2936 | WREG32(R600_BIOS_0_SCRATCH, bios_0_scratch); | 2950 | WREG32(R600_BIOS_0_SCRATCH, bios_0_scratch); |
@@ -2951,6 +2965,9 @@ radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc) | |||
2951 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 2965 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
2952 | uint32_t bios_3_scratch; | 2966 | uint32_t bios_3_scratch; |
2953 | 2967 | ||
2968 | if (ASIC_IS_DCE4(rdev)) | ||
2969 | return; | ||
2970 | |||
2954 | if (rdev->family >= CHIP_R600) | 2971 | if (rdev->family >= CHIP_R600) |
2955 | bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH); | 2972 | bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH); |
2956 | else | 2973 | else |
@@ -3003,6 +3020,9 @@ radeon_atombios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on) | |||
3003 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 3020 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
3004 | uint32_t bios_2_scratch; | 3021 | uint32_t bios_2_scratch; |
3005 | 3022 | ||
3023 | if (ASIC_IS_DCE4(rdev)) | ||
3024 | return; | ||
3025 | |||
3006 | if (rdev->family >= CHIP_R600) | 3026 | if (rdev->family >= CHIP_R600) |
3007 | bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH); | 3027 | bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH); |
3008 | else | 3028 | else |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 9d95792bea3e..98724fcb0088 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -58,7 +58,8 @@ static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, | |||
58 | } | 58 | } |
59 | 59 | ||
60 | obj = (union acpi_object *)buffer.pointer; | 60 | obj = (union acpi_object *)buffer.pointer; |
61 | memcpy(bios+offset, obj->buffer.pointer, len); | 61 | memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); |
62 | len = obj->buffer.length; | ||
62 | kfree(buffer.pointer); | 63 | kfree(buffer.pointer); |
63 | return len; | 64 | return len; |
64 | } | 65 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 229a20f10e2b..501f4881e5aa 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
@@ -120,7 +120,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) | |||
120 | ret = radeon_atrm_get_bios_chunk(rdev->bios, | 120 | ret = radeon_atrm_get_bios_chunk(rdev->bios, |
121 | (i * ATRM_BIOS_PAGE), | 121 | (i * ATRM_BIOS_PAGE), |
122 | ATRM_BIOS_PAGE); | 122 | ATRM_BIOS_PAGE); |
123 | if (ret <= 0) | 123 | if (ret < ATRM_BIOS_PAGE) |
124 | break; | 124 | break; |
125 | } | 125 | } |
126 | 126 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index e7cb3ab09243..8c9a8115b632 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -1057,7 +1057,7 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector, | |||
1057 | (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) | 1057 | (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) |
1058 | return MODE_OK; | 1058 | return MODE_OK; |
1059 | else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) { | 1059 | else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) { |
1060 | if (ASIC_IS_DCE3(rdev)) { | 1060 | if (0) { |
1061 | /* HDMI 1.3+ supports max clock of 340 Mhz */ | 1061 | /* HDMI 1.3+ supports max clock of 340 Mhz */ |
1062 | if (mode->clock > 340000) | 1062 | if (mode->clock > 340000) |
1063 | return MODE_CLOCK_HIGH; | 1063 | return MODE_CLOCK_HIGH; |
@@ -1117,13 +1117,23 @@ static int radeon_dp_get_modes(struct drm_connector *connector) | |||
1117 | (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { | 1117 | (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { |
1118 | struct drm_display_mode *mode; | 1118 | struct drm_display_mode *mode; |
1119 | 1119 | ||
1120 | if (!radeon_dig_connector->edp_on) | 1120 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
1121 | atombios_set_edp_panel_power(connector, | 1121 | if (!radeon_dig_connector->edp_on) |
1122 | ATOM_TRANSMITTER_ACTION_POWER_ON); | 1122 | atombios_set_edp_panel_power(connector, |
1123 | ret = radeon_ddc_get_modes(radeon_connector); | 1123 | ATOM_TRANSMITTER_ACTION_POWER_ON); |
1124 | if (!radeon_dig_connector->edp_on) | 1124 | ret = radeon_ddc_get_modes(radeon_connector); |
1125 | atombios_set_edp_panel_power(connector, | 1125 | if (!radeon_dig_connector->edp_on) |
1126 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | 1126 | atombios_set_edp_panel_power(connector, |
1127 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | ||
1128 | } else { | ||
1129 | /* need to setup ddc on the bridge */ | ||
1130 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != | ||
1131 | ENCODER_OBJECT_ID_NONE) { | ||
1132 | if (encoder) | ||
1133 | radeon_atom_ext_encoder_setup_ddc(encoder); | ||
1134 | } | ||
1135 | ret = radeon_ddc_get_modes(radeon_connector); | ||
1136 | } | ||
1127 | 1137 | ||
1128 | if (ret > 0) { | 1138 | if (ret > 0) { |
1129 | if (encoder) { | 1139 | if (encoder) { |
@@ -1134,7 +1144,6 @@ static int radeon_dp_get_modes(struct drm_connector *connector) | |||
1134 | return ret; | 1144 | return ret; |
1135 | } | 1145 | } |
1136 | 1146 | ||
1137 | encoder = radeon_best_single_encoder(connector); | ||
1138 | if (!encoder) | 1147 | if (!encoder) |
1139 | return 0; | 1148 | return 0; |
1140 | 1149 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 435a3d970ab8..e64bec488ed8 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -453,6 +453,10 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
453 | int r; | 453 | int r; |
454 | 454 | ||
455 | radeon_mutex_lock(&rdev->cs_mutex); | 455 | radeon_mutex_lock(&rdev->cs_mutex); |
456 | if (!rdev->accel_working) { | ||
457 | radeon_mutex_unlock(&rdev->cs_mutex); | ||
458 | return -EBUSY; | ||
459 | } | ||
456 | /* initialize parser */ | 460 | /* initialize parser */ |
457 | memset(&parser, 0, sizeof(struct radeon_cs_parser)); | 461 | memset(&parser, 0, sizeof(struct radeon_cs_parser)); |
458 | parser.filp = filp; | 462 | parser.filp = filp; |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 0afb13bd8dca..49f7cb7e226b 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -720,7 +720,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
720 | /* mutex initialization are all done here so we | 720 | /* mutex initialization are all done here so we |
721 | * can recall function without having locking issues */ | 721 | * can recall function without having locking issues */ |
722 | radeon_mutex_init(&rdev->cs_mutex); | 722 | radeon_mutex_init(&rdev->cs_mutex); |
723 | mutex_init(&rdev->ib_pool.mutex); | 723 | radeon_mutex_init(&rdev->ib_pool.mutex); |
724 | for (i = 0; i < RADEON_NUM_RINGS; ++i) | 724 | for (i = 0; i < RADEON_NUM_RINGS; ++i) |
725 | mutex_init(&rdev->ring[i].mutex); | 725 | mutex_init(&rdev->ring[i].mutex); |
726 | mutex_init(&rdev->dc_hw_i2c_mutex); | 726 | mutex_init(&rdev->dc_hw_i2c_mutex); |
@@ -883,6 +883,8 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
883 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) | 883 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
884 | return 0; | 884 | return 0; |
885 | 885 | ||
886 | drm_kms_helper_poll_disable(dev); | ||
887 | |||
886 | /* turn off display hw */ | 888 | /* turn off display hw */ |
887 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 889 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
888 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); | 890 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); |
@@ -959,9 +961,11 @@ int radeon_resume_kms(struct drm_device *dev) | |||
959 | radeon_fbdev_set_suspend(rdev, 0); | 961 | radeon_fbdev_set_suspend(rdev, 0); |
960 | console_unlock(); | 962 | console_unlock(); |
961 | 963 | ||
962 | /* init dig PHYs */ | 964 | /* init dig PHYs, disp eng pll */ |
963 | if (rdev->is_atom_bios) | 965 | if (rdev->is_atom_bios) { |
964 | radeon_atom_encoder_init(rdev); | 966 | radeon_atom_encoder_init(rdev); |
967 | radeon_atom_dcpll_init(rdev); | ||
968 | } | ||
965 | /* reset hpd state */ | 969 | /* reset hpd state */ |
966 | radeon_hpd_init(rdev); | 970 | radeon_hpd_init(rdev); |
967 | /* blat the mode back in */ | 971 | /* blat the mode back in */ |
@@ -970,6 +974,8 @@ int radeon_resume_kms(struct drm_device *dev) | |||
970 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 974 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
971 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); | 975 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); |
972 | } | 976 | } |
977 | |||
978 | drm_kms_helper_poll_enable(dev); | ||
973 | return 0; | 979 | return 0; |
974 | } | 980 | } |
975 | 981 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index d3ffc18774a6..3d314338d843 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -1078,15 +1078,21 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = { | |||
1078 | .create_handle = radeon_user_framebuffer_create_handle, | 1078 | .create_handle = radeon_user_framebuffer_create_handle, |
1079 | }; | 1079 | }; |
1080 | 1080 | ||
1081 | void | 1081 | int |
1082 | radeon_framebuffer_init(struct drm_device *dev, | 1082 | radeon_framebuffer_init(struct drm_device *dev, |
1083 | struct radeon_framebuffer *rfb, | 1083 | struct radeon_framebuffer *rfb, |
1084 | struct drm_mode_fb_cmd2 *mode_cmd, | 1084 | struct drm_mode_fb_cmd2 *mode_cmd, |
1085 | struct drm_gem_object *obj) | 1085 | struct drm_gem_object *obj) |
1086 | { | 1086 | { |
1087 | int ret; | ||
1087 | rfb->obj = obj; | 1088 | rfb->obj = obj; |
1088 | drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs); | 1089 | ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs); |
1090 | if (ret) { | ||
1091 | rfb->obj = NULL; | ||
1092 | return ret; | ||
1093 | } | ||
1089 | drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd); | 1094 | drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd); |
1095 | return 0; | ||
1090 | } | 1096 | } |
1091 | 1097 | ||
1092 | static struct drm_framebuffer * | 1098 | static struct drm_framebuffer * |
@@ -1096,6 +1102,7 @@ radeon_user_framebuffer_create(struct drm_device *dev, | |||
1096 | { | 1102 | { |
1097 | struct drm_gem_object *obj; | 1103 | struct drm_gem_object *obj; |
1098 | struct radeon_framebuffer *radeon_fb; | 1104 | struct radeon_framebuffer *radeon_fb; |
1105 | int ret; | ||
1099 | 1106 | ||
1100 | obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); | 1107 | obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); |
1101 | if (obj == NULL) { | 1108 | if (obj == NULL) { |
@@ -1108,7 +1115,12 @@ radeon_user_framebuffer_create(struct drm_device *dev, | |||
1108 | if (radeon_fb == NULL) | 1115 | if (radeon_fb == NULL) |
1109 | return ERR_PTR(-ENOMEM); | 1116 | return ERR_PTR(-ENOMEM); |
1110 | 1117 | ||
1111 | radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); | 1118 | ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); |
1119 | if (ret) { | ||
1120 | kfree(radeon_fb); | ||
1121 | drm_gem_object_unreference_unlocked(obj); | ||
1122 | return NULL; | ||
1123 | } | ||
1112 | 1124 | ||
1113 | return &radeon_fb->base; | 1125 | return &radeon_fb->base; |
1114 | } | 1126 | } |
@@ -1305,9 +1317,11 @@ int radeon_modeset_init(struct radeon_device *rdev) | |||
1305 | return ret; | 1317 | return ret; |
1306 | } | 1318 | } |
1307 | 1319 | ||
1308 | /* init dig PHYs */ | 1320 | /* init dig PHYs, disp eng pll */ |
1309 | if (rdev->is_atom_bios) | 1321 | if (rdev->is_atom_bios) { |
1310 | radeon_atom_encoder_init(rdev); | 1322 | radeon_atom_encoder_init(rdev); |
1323 | radeon_atom_dcpll_init(rdev); | ||
1324 | } | ||
1311 | 1325 | ||
1312 | /* initialize hpd */ | 1326 | /* initialize hpd */ |
1313 | radeon_hpd_init(rdev); | 1327 | radeon_hpd_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 4b27efa4405b..26e92708d114 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -202,6 +202,22 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
202 | return NULL; | 202 | return NULL; |
203 | } | 203 | } |
204 | 204 | ||
205 | struct drm_connector * | ||
206 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) | ||
207 | { | ||
208 | struct drm_device *dev = encoder->dev; | ||
209 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
210 | struct drm_connector *connector; | ||
211 | struct radeon_connector *radeon_connector; | ||
212 | |||
213 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
214 | radeon_connector = to_radeon_connector(connector); | ||
215 | if (radeon_encoder->devices & radeon_connector->devices) | ||
216 | return connector; | ||
217 | } | ||
218 | return NULL; | ||
219 | } | ||
220 | |||
205 | struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder) | 221 | struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder) |
206 | { | 222 | { |
207 | struct drm_device *dev = encoder->dev; | 223 | struct drm_device *dev = encoder->dev; |
@@ -288,3 +304,62 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder, | |||
288 | 304 | ||
289 | } | 305 | } |
290 | 306 | ||
307 | bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, | ||
308 | u32 pixel_clock) | ||
309 | { | ||
310 | struct drm_connector *connector; | ||
311 | struct radeon_connector *radeon_connector; | ||
312 | struct radeon_connector_atom_dig *dig_connector; | ||
313 | |||
314 | connector = radeon_get_connector_for_encoder(encoder); | ||
315 | /* if we don't have an active device yet, just use one of | ||
316 | * the connectors tied to the encoder. | ||
317 | */ | ||
318 | if (!connector) | ||
319 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
320 | radeon_connector = to_radeon_connector(connector); | ||
321 | |||
322 | switch (connector->connector_type) { | ||
323 | case DRM_MODE_CONNECTOR_DVII: | ||
324 | case DRM_MODE_CONNECTOR_HDMIB: | ||
325 | if (radeon_connector->use_digital) { | ||
326 | /* HDMI 1.3 supports up to 340 Mhz over single link */ | ||
327 | if (0 && drm_detect_hdmi_monitor(radeon_connector->edid)) { | ||
328 | if (pixel_clock > 340000) | ||
329 | return true; | ||
330 | else | ||
331 | return false; | ||
332 | } else { | ||
333 | if (pixel_clock > 165000) | ||
334 | return true; | ||
335 | else | ||
336 | return false; | ||
337 | } | ||
338 | } else | ||
339 | return false; | ||
340 | case DRM_MODE_CONNECTOR_DVID: | ||
341 | case DRM_MODE_CONNECTOR_HDMIA: | ||
342 | case DRM_MODE_CONNECTOR_DisplayPort: | ||
343 | dig_connector = radeon_connector->con_priv; | ||
344 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | ||
345 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | ||
346 | return false; | ||
347 | else { | ||
348 | /* HDMI 1.3 supports up to 340 Mhz over single link */ | ||
349 | if (0 && drm_detect_hdmi_monitor(radeon_connector->edid)) { | ||
350 | if (pixel_clock > 340000) | ||
351 | return true; | ||
352 | else | ||
353 | return false; | ||
354 | } else { | ||
355 | if (pixel_clock > 165000) | ||
356 | return true; | ||
357 | else | ||
358 | return false; | ||
359 | } | ||
360 | } | ||
361 | default: | ||
362 | return false; | ||
363 | } | ||
364 | } | ||
365 | |||
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index cf2bf35b56b8..195471cf65d3 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -209,6 +209,11 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, | |||
209 | sizes->surface_depth); | 209 | sizes->surface_depth); |
210 | 210 | ||
211 | ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj); | 211 | ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj); |
212 | if (ret) { | ||
213 | DRM_ERROR("failed to create fbcon object %d\n", ret); | ||
214 | return ret; | ||
215 | } | ||
216 | |||
212 | rbo = gem_to_radeon_bo(gobj); | 217 | rbo = gem_to_radeon_bo(gobj); |
213 | 218 | ||
214 | /* okay we have an object now allocate the framebuffer */ | 219 | /* okay we have an object now allocate the framebuffer */ |
@@ -220,7 +225,11 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, | |||
220 | 225 | ||
221 | info->par = rfbdev; | 226 | info->par = rfbdev; |
222 | 227 | ||
223 | radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); | 228 | ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); |
229 | if (ret) { | ||
230 | DRM_ERROR("failed to initalise framebuffer %d\n", ret); | ||
231 | goto out_unref; | ||
232 | } | ||
224 | 233 | ||
225 | fb = &rfbdev->rfb.base; | 234 | fb = &rfbdev->rfb.base; |
226 | 235 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 64ea3dd9e6ff..4bd36a354fbe 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -364,8 +364,10 @@ int radeon_fence_count_emitted(struct radeon_device *rdev, int ring) | |||
364 | int not_processed = 0; | 364 | int not_processed = 0; |
365 | 365 | ||
366 | read_lock_irqsave(&rdev->fence_lock, irq_flags); | 366 | read_lock_irqsave(&rdev->fence_lock, irq_flags); |
367 | if (!rdev->fence_drv[ring].initialized) | 367 | if (!rdev->fence_drv[ring].initialized) { |
368 | read_unlock_irqrestore(&rdev->fence_lock, irq_flags); | ||
368 | return 0; | 369 | return 0; |
370 | } | ||
369 | 371 | ||
370 | if (!list_empty(&rdev->fence_drv[ring].emitted)) { | 372 | if (!list_empty(&rdev->fence_drv[ring].emitted)) { |
371 | struct list_head *ptr; | 373 | struct list_head *ptr; |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 010dad8b66ae..c58a036233fb 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -597,13 +597,13 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
597 | if (bo_va == NULL) | 597 | if (bo_va == NULL) |
598 | return 0; | 598 | return 0; |
599 | 599 | ||
600 | list_del(&bo_va->bo_list); | ||
601 | mutex_lock(&vm->mutex); | 600 | mutex_lock(&vm->mutex); |
602 | radeon_mutex_lock(&rdev->cs_mutex); | 601 | radeon_mutex_lock(&rdev->cs_mutex); |
603 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); | 602 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); |
604 | radeon_mutex_unlock(&rdev->cs_mutex); | 603 | radeon_mutex_unlock(&rdev->cs_mutex); |
605 | list_del(&bo_va->vm_list); | 604 | list_del(&bo_va->vm_list); |
606 | mutex_unlock(&vm->mutex); | 605 | mutex_unlock(&vm->mutex); |
606 | list_del(&bo_va->bo_list); | ||
607 | 607 | ||
608 | kfree(bo_va); | 608 | kfree(bo_va); |
609 | return 0; | 609 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 7bb1b079f480..98a8ad680109 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -897,6 +897,7 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
897 | i2c->rec = *rec; | 897 | i2c->rec = *rec; |
898 | i2c->adapter.owner = THIS_MODULE; | 898 | i2c->adapter.owner = THIS_MODULE; |
899 | i2c->adapter.class = I2C_CLASS_DDC; | 899 | i2c->adapter.class = I2C_CLASS_DDC; |
900 | i2c->adapter.dev.parent = &dev->pdev->dev; | ||
900 | i2c->dev = dev; | 901 | i2c->dev = dev; |
901 | i2c_set_adapdata(&i2c->adapter, i2c); | 902 | i2c_set_adapdata(&i2c->adapter, i2c); |
902 | if (rec->mm_i2c || | 903 | if (rec->mm_i2c || |
@@ -957,6 +958,7 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, | |||
957 | i2c->rec = *rec; | 958 | i2c->rec = *rec; |
958 | i2c->adapter.owner = THIS_MODULE; | 959 | i2c->adapter.owner = THIS_MODULE; |
959 | i2c->adapter.class = I2C_CLASS_DDC; | 960 | i2c->adapter.class = I2C_CLASS_DDC; |
961 | i2c->adapter.dev.parent = &dev->pdev->dev; | ||
960 | i2c->dev = dev; | 962 | i2c->dev = dev; |
961 | snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), | 963 | snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), |
962 | "Radeon aux bus %s", name); | 964 | "Radeon aux bus %s", name); |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index be38921bf761..66d5fe1c8174 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -138,6 +138,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev) | |||
138 | /* Dell RS690 only seems to work with MSIs. */ | 138 | /* Dell RS690 only seems to work with MSIs. */ |
139 | if ((rdev->pdev->device == 0x791f) && | 139 | if ((rdev->pdev->device == 0x791f) && |
140 | (rdev->pdev->subsystem_vendor == 0x1028) && | 140 | (rdev->pdev->subsystem_vendor == 0x1028) && |
141 | (rdev->pdev->subsystem_device == 0x01fc)) | ||
142 | return true; | ||
143 | |||
144 | /* Dell RS690 only seems to work with MSIs. */ | ||
145 | if ((rdev->pdev->device == 0x791f) && | ||
146 | (rdev->pdev->subsystem_vendor == 0x1028) && | ||
141 | (rdev->pdev->subsystem_device == 0x01fd)) | 147 | (rdev->pdev->subsystem_device == 0x01fd)) |
142 | return true; | 148 | return true; |
143 | 149 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 08ff857c8fd6..8a85598fb242 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -362,6 +362,7 @@ struct radeon_encoder_atom_dig { | |||
362 | struct backlight_device *bl_dev; | 362 | struct backlight_device *bl_dev; |
363 | int dpms_mode; | 363 | int dpms_mode; |
364 | uint8_t backlight_level; | 364 | uint8_t backlight_level; |
365 | int panel_mode; | ||
365 | }; | 366 | }; |
366 | 367 | ||
367 | struct radeon_encoder_atom_dac { | 368 | struct radeon_encoder_atom_dac { |
@@ -466,6 +467,10 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev); | |||
466 | 467 | ||
467 | extern struct drm_connector * | 468 | extern struct drm_connector * |
468 | radeon_get_connector_for_encoder(struct drm_encoder *encoder); | 469 | radeon_get_connector_for_encoder(struct drm_encoder *encoder); |
470 | extern struct drm_connector * | ||
471 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder); | ||
472 | extern bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, | ||
473 | u32 pixel_clock); | ||
469 | 474 | ||
470 | extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder); | 475 | extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder); |
471 | extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); | 476 | extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); |
@@ -482,8 +487,11 @@ extern void radeon_dp_link_train(struct drm_encoder *encoder, | |||
482 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); | 487 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); |
483 | extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); | 488 | extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); |
484 | extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); | 489 | extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); |
490 | extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder, | ||
491 | struct drm_connector *connector); | ||
485 | extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); | 492 | extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); |
486 | extern void radeon_atom_encoder_init(struct radeon_device *rdev); | 493 | extern void radeon_atom_encoder_init(struct radeon_device *rdev); |
494 | extern void radeon_atom_dcpll_init(struct radeon_device *rdev); | ||
487 | extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, | 495 | extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, |
488 | int action, uint8_t lane_num, | 496 | int action, uint8_t lane_num, |
489 | uint8_t lane_set); | 497 | uint8_t lane_set); |
@@ -641,7 +649,7 @@ extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, | |||
641 | u16 blue, int regno); | 649 | u16 blue, int regno); |
642 | extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, | 650 | extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, |
643 | u16 *blue, int regno); | 651 | u16 *blue, int regno); |
644 | void radeon_framebuffer_init(struct drm_device *dev, | 652 | int radeon_framebuffer_init(struct drm_device *dev, |
645 | struct radeon_framebuffer *rfb, | 653 | struct radeon_framebuffer *rfb, |
646 | struct drm_mode_fb_cmd2 *mode_cmd, | 654 | struct drm_mode_fb_cmd2 *mode_cmd, |
647 | struct drm_gem_object *obj); | 655 | struct drm_gem_object *obj); |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index e8bc70933d1b..92c9ea4751fb 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -109,12 +109,12 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, | |||
109 | return r; | 109 | return r; |
110 | } | 110 | } |
111 | 111 | ||
112 | mutex_lock(&rdev->ib_pool.mutex); | 112 | radeon_mutex_lock(&rdev->ib_pool.mutex); |
113 | idx = rdev->ib_pool.head_id; | 113 | idx = rdev->ib_pool.head_id; |
114 | retry: | 114 | retry: |
115 | if (cretry > 5) { | 115 | if (cretry > 5) { |
116 | dev_err(rdev->dev, "failed to get an ib after 5 retry\n"); | 116 | dev_err(rdev->dev, "failed to get an ib after 5 retry\n"); |
117 | mutex_unlock(&rdev->ib_pool.mutex); | 117 | radeon_mutex_unlock(&rdev->ib_pool.mutex); |
118 | radeon_fence_unref(&fence); | 118 | radeon_fence_unref(&fence); |
119 | return -ENOMEM; | 119 | return -ENOMEM; |
120 | } | 120 | } |
@@ -139,7 +139,7 @@ retry: | |||
139 | */ | 139 | */ |
140 | rdev->ib_pool.head_id = (1 + idx); | 140 | rdev->ib_pool.head_id = (1 + idx); |
141 | rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1); | 141 | rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1); |
142 | mutex_unlock(&rdev->ib_pool.mutex); | 142 | radeon_mutex_unlock(&rdev->ib_pool.mutex); |
143 | return 0; | 143 | return 0; |
144 | } | 144 | } |
145 | } | 145 | } |
@@ -158,7 +158,7 @@ retry: | |||
158 | } | 158 | } |
159 | idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); | 159 | idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); |
160 | } | 160 | } |
161 | mutex_unlock(&rdev->ib_pool.mutex); | 161 | radeon_mutex_unlock(&rdev->ib_pool.mutex); |
162 | radeon_fence_unref(&fence); | 162 | radeon_fence_unref(&fence); |
163 | return r; | 163 | return r; |
164 | } | 164 | } |
@@ -171,12 +171,12 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) | |||
171 | if (tmp == NULL) { | 171 | if (tmp == NULL) { |
172 | return; | 172 | return; |
173 | } | 173 | } |
174 | mutex_lock(&rdev->ib_pool.mutex); | 174 | radeon_mutex_lock(&rdev->ib_pool.mutex); |
175 | if (tmp->fence && !tmp->fence->emitted) { | 175 | if (tmp->fence && !tmp->fence->emitted) { |
176 | radeon_sa_bo_free(rdev, &tmp->sa_bo); | 176 | radeon_sa_bo_free(rdev, &tmp->sa_bo); |
177 | radeon_fence_unref(&tmp->fence); | 177 | radeon_fence_unref(&tmp->fence); |
178 | } | 178 | } |
179 | mutex_unlock(&rdev->ib_pool.mutex); | 179 | radeon_mutex_unlock(&rdev->ib_pool.mutex); |
180 | } | 180 | } |
181 | 181 | ||
182 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) | 182 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) |
@@ -204,22 +204,25 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) | |||
204 | 204 | ||
205 | int radeon_ib_pool_init(struct radeon_device *rdev) | 205 | int radeon_ib_pool_init(struct radeon_device *rdev) |
206 | { | 206 | { |
207 | struct radeon_sa_manager tmp; | ||
207 | int i, r; | 208 | int i, r; |
208 | 209 | ||
209 | mutex_lock(&rdev->ib_pool.mutex); | 210 | r = radeon_sa_bo_manager_init(rdev, &tmp, |
210 | if (rdev->ib_pool.ready) { | ||
211 | mutex_unlock(&rdev->ib_pool.mutex); | ||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | r = radeon_sa_bo_manager_init(rdev, &rdev->ib_pool.sa_manager, | ||
216 | RADEON_IB_POOL_SIZE*64*1024, | 211 | RADEON_IB_POOL_SIZE*64*1024, |
217 | RADEON_GEM_DOMAIN_GTT); | 212 | RADEON_GEM_DOMAIN_GTT); |
218 | if (r) { | 213 | if (r) { |
219 | mutex_unlock(&rdev->ib_pool.mutex); | ||
220 | return r; | 214 | return r; |
221 | } | 215 | } |
222 | 216 | ||
217 | radeon_mutex_lock(&rdev->ib_pool.mutex); | ||
218 | if (rdev->ib_pool.ready) { | ||
219 | radeon_mutex_unlock(&rdev->ib_pool.mutex); | ||
220 | radeon_sa_bo_manager_fini(rdev, &tmp); | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | rdev->ib_pool.sa_manager = tmp; | ||
225 | INIT_LIST_HEAD(&rdev->ib_pool.sa_manager.sa_bo); | ||
223 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { | 226 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { |
224 | rdev->ib_pool.ibs[i].fence = NULL; | 227 | rdev->ib_pool.ibs[i].fence = NULL; |
225 | rdev->ib_pool.ibs[i].idx = i; | 228 | rdev->ib_pool.ibs[i].idx = i; |
@@ -236,7 +239,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev) | |||
236 | if (radeon_debugfs_ring_init(rdev)) { | 239 | if (radeon_debugfs_ring_init(rdev)) { |
237 | DRM_ERROR("Failed to register debugfs file for rings !\n"); | 240 | DRM_ERROR("Failed to register debugfs file for rings !\n"); |
238 | } | 241 | } |
239 | mutex_unlock(&rdev->ib_pool.mutex); | 242 | radeon_mutex_unlock(&rdev->ib_pool.mutex); |
240 | return 0; | 243 | return 0; |
241 | } | 244 | } |
242 | 245 | ||
@@ -244,7 +247,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) | |||
244 | { | 247 | { |
245 | unsigned i; | 248 | unsigned i; |
246 | 249 | ||
247 | mutex_lock(&rdev->ib_pool.mutex); | 250 | radeon_mutex_lock(&rdev->ib_pool.mutex); |
248 | if (rdev->ib_pool.ready) { | 251 | if (rdev->ib_pool.ready) { |
249 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { | 252 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { |
250 | radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo); | 253 | radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo); |
@@ -253,7 +256,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) | |||
253 | radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager); | 256 | radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager); |
254 | rdev->ib_pool.ready = false; | 257 | rdev->ib_pool.ready = false; |
255 | } | 258 | } |
256 | mutex_unlock(&rdev->ib_pool.mutex); | 259 | radeon_mutex_unlock(&rdev->ib_pool.mutex); |
257 | } | 260 | } |
258 | 261 | ||
259 | int radeon_ib_pool_start(struct radeon_device *rdev) | 262 | int radeon_ib_pool_start(struct radeon_device *rdev) |
@@ -497,8 +500,11 @@ static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32]; | |||
497 | int radeon_debugfs_ring_init(struct radeon_device *rdev) | 500 | int radeon_debugfs_ring_init(struct radeon_device *rdev) |
498 | { | 501 | { |
499 | #if defined(CONFIG_DEBUG_FS) | 502 | #if defined(CONFIG_DEBUG_FS) |
500 | return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, | 503 | if (rdev->family >= CHIP_CAYMAN) |
501 | ARRAY_SIZE(radeon_debugfs_ring_info_list)); | 504 | return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, |
505 | ARRAY_SIZE(radeon_debugfs_ring_info_list)); | ||
506 | else | ||
507 | return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, 1); | ||
502 | #else | 508 | #else |
503 | return 0; | 509 | return 0; |
504 | #endif | 510 | #endif |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index b0ce84a20a68..866a05be75f2 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -442,6 +442,8 @@ static int rs400_startup(struct radeon_device *rdev) | |||
442 | 442 | ||
443 | int rs400_resume(struct radeon_device *rdev) | 443 | int rs400_resume(struct radeon_device *rdev) |
444 | { | 444 | { |
445 | int r; | ||
446 | |||
445 | /* Make sur GART are not working */ | 447 | /* Make sur GART are not working */ |
446 | rs400_gart_disable(rdev); | 448 | rs400_gart_disable(rdev); |
447 | /* Resume clock before doing reset */ | 449 | /* Resume clock before doing reset */ |
@@ -462,7 +464,11 @@ int rs400_resume(struct radeon_device *rdev) | |||
462 | radeon_surface_init(rdev); | 464 | radeon_surface_init(rdev); |
463 | 465 | ||
464 | rdev->accel_working = true; | 466 | rdev->accel_working = true; |
465 | return rs400_startup(rdev); | 467 | r = rs400_startup(rdev); |
468 | if (r) { | ||
469 | rdev->accel_working = false; | ||
470 | } | ||
471 | return r; | ||
466 | } | 472 | } |
467 | 473 | ||
468 | int rs400_suspend(struct radeon_device *rdev) | 474 | int rs400_suspend(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index ec46eb45e34c..4fc700684dcd 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -684,9 +684,7 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
684 | WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM); | 684 | WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM); |
685 | break; | 685 | break; |
686 | default: | 686 | default: |
687 | msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; | 687 | WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); |
688 | WREG32(RADEON_MSI_REARM_EN, msi_rearm); | ||
689 | WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); | ||
690 | break; | 688 | break; |
691 | } | 689 | } |
692 | } | 690 | } |
@@ -878,6 +876,8 @@ static int rs600_startup(struct radeon_device *rdev) | |||
878 | 876 | ||
879 | int rs600_resume(struct radeon_device *rdev) | 877 | int rs600_resume(struct radeon_device *rdev) |
880 | { | 878 | { |
879 | int r; | ||
880 | |||
881 | /* Make sur GART are not working */ | 881 | /* Make sur GART are not working */ |
882 | rs600_gart_disable(rdev); | 882 | rs600_gart_disable(rdev); |
883 | /* Resume clock before doing reset */ | 883 | /* Resume clock before doing reset */ |
@@ -896,7 +896,11 @@ int rs600_resume(struct radeon_device *rdev) | |||
896 | radeon_surface_init(rdev); | 896 | radeon_surface_init(rdev); |
897 | 897 | ||
898 | rdev->accel_working = true; | 898 | rdev->accel_working = true; |
899 | return rs600_startup(rdev); | 899 | r = rs600_startup(rdev); |
900 | if (r) { | ||
901 | rdev->accel_working = false; | ||
902 | } | ||
903 | return r; | ||
900 | } | 904 | } |
901 | 905 | ||
902 | int rs600_suspend(struct radeon_device *rdev) | 906 | int rs600_suspend(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 4f24a0fa8c82..f68dff2fadcb 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -659,6 +659,8 @@ static int rs690_startup(struct radeon_device *rdev) | |||
659 | 659 | ||
660 | int rs690_resume(struct radeon_device *rdev) | 660 | int rs690_resume(struct radeon_device *rdev) |
661 | { | 661 | { |
662 | int r; | ||
663 | |||
662 | /* Make sur GART are not working */ | 664 | /* Make sur GART are not working */ |
663 | rs400_gart_disable(rdev); | 665 | rs400_gart_disable(rdev); |
664 | /* Resume clock before doing reset */ | 666 | /* Resume clock before doing reset */ |
@@ -677,7 +679,11 @@ int rs690_resume(struct radeon_device *rdev) | |||
677 | radeon_surface_init(rdev); | 679 | radeon_surface_init(rdev); |
678 | 680 | ||
679 | rdev->accel_working = true; | 681 | rdev->accel_working = true; |
680 | return rs690_startup(rdev); | 682 | r = rs690_startup(rdev); |
683 | if (r) { | ||
684 | rdev->accel_working = false; | ||
685 | } | ||
686 | return r; | ||
681 | } | 687 | } |
682 | 688 | ||
683 | int rs690_suspend(struct radeon_device *rdev) | 689 | int rs690_suspend(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 880637fd1946..959bf4483bea 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -424,6 +424,8 @@ static int rv515_startup(struct radeon_device *rdev) | |||
424 | 424 | ||
425 | int rv515_resume(struct radeon_device *rdev) | 425 | int rv515_resume(struct radeon_device *rdev) |
426 | { | 426 | { |
427 | int r; | ||
428 | |||
427 | /* Make sur GART are not working */ | 429 | /* Make sur GART are not working */ |
428 | if (rdev->flags & RADEON_IS_PCIE) | 430 | if (rdev->flags & RADEON_IS_PCIE) |
429 | rv370_pcie_gart_disable(rdev); | 431 | rv370_pcie_gart_disable(rdev); |
@@ -443,7 +445,11 @@ int rv515_resume(struct radeon_device *rdev) | |||
443 | radeon_surface_init(rdev); | 445 | radeon_surface_init(rdev); |
444 | 446 | ||
445 | rdev->accel_working = true; | 447 | rdev->accel_working = true; |
446 | return rv515_startup(rdev); | 448 | r = rv515_startup(rdev); |
449 | if (r) { | ||
450 | rdev->accel_working = false; | ||
451 | } | ||
452 | return r; | ||
447 | } | 453 | } |
448 | 454 | ||
449 | int rv515_suspend(struct radeon_device *rdev) | 455 | int rv515_suspend(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index a1668b659ddd..c049c0c51841 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -1139,6 +1139,7 @@ int rv770_resume(struct radeon_device *rdev) | |||
1139 | r = rv770_startup(rdev); | 1139 | r = rv770_startup(rdev); |
1140 | if (r) { | 1140 | if (r) { |
1141 | DRM_ERROR("r600 startup failed on resume\n"); | 1141 | DRM_ERROR("r600 startup failed on resume\n"); |
1142 | rdev->accel_working = false; | ||
1142 | return r; | 1143 | return r; |
1143 | } | 1144 | } |
1144 | 1145 | ||
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 06da063ece2e..573220cc5269 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c | |||
@@ -40,7 +40,6 @@ static struct pci_device_id pciidlist[] = { | |||
40 | static int sis_driver_load(struct drm_device *dev, unsigned long chipset) | 40 | static int sis_driver_load(struct drm_device *dev, unsigned long chipset) |
41 | { | 41 | { |
42 | drm_sis_private_t *dev_priv; | 42 | drm_sis_private_t *dev_priv; |
43 | int ret; | ||
44 | 43 | ||
45 | dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL); | 44 | dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL); |
46 | if (dev_priv == NULL) | 45 | if (dev_priv == NULL) |
@@ -50,7 +49,7 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) | |||
50 | dev_priv->chipset = chipset; | 49 | dev_priv->chipset = chipset; |
51 | idr_init(&dev->object_name_idr); | 50 | idr_init(&dev->object_name_idr); |
52 | 51 | ||
53 | return ret; | 52 | return 0; |
54 | } | 53 | } |
55 | 54 | ||
56 | static int sis_driver_unload(struct drm_device *dev) | 55 | static int sis_driver_unload(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 2f0eab66ece6..7c3a57de8187 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -404,6 +404,9 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, | |||
404 | } | 404 | } |
405 | } | 405 | } |
406 | 406 | ||
407 | if (bdev->driver->move_notify) | ||
408 | bdev->driver->move_notify(bo, mem); | ||
409 | |||
407 | if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) && | 410 | if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) && |
408 | !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) | 411 | !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) |
409 | ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, mem); | 412 | ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, mem); |
@@ -413,11 +416,17 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, | |||
413 | else | 416 | else |
414 | ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, mem); | 417 | ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, mem); |
415 | 418 | ||
416 | if (ret) | 419 | if (ret) { |
417 | goto out_err; | 420 | if (bdev->driver->move_notify) { |
421 | struct ttm_mem_reg tmp_mem = *mem; | ||
422 | *mem = bo->mem; | ||
423 | bo->mem = tmp_mem; | ||
424 | bdev->driver->move_notify(bo, mem); | ||
425 | bo->mem = *mem; | ||
426 | } | ||
418 | 427 | ||
419 | if (bdev->driver->move_notify) | 428 | goto out_err; |
420 | bdev->driver->move_notify(bo, mem); | 429 | } |
421 | 430 | ||
422 | moved: | 431 | moved: |
423 | if (bo->evicted) { | 432 | if (bo->evicted) { |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 0af6ebdf205d..b66ef0e3cde1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -378,7 +378,7 @@ int vmw_framebuffer_create_handle(struct drm_framebuffer *fb, | |||
378 | unsigned int *handle) | 378 | unsigned int *handle) |
379 | { | 379 | { |
380 | if (handle) | 380 | if (handle) |
381 | handle = 0; | 381 | *handle = 0; |
382 | 382 | ||
383 | return 0; | 383 | return 0; |
384 | } | 384 | } |