Commit 9f821c675a389cf4aab7f1dc8ee0860fba4f3204
Committed by
Dave Airlie
1 parent
afe887df1c
Exists in
master
and in
38 other branches
gma500: Discard modes that don't fit in stolen memory
[This fixes a crash on boot if the system is plugged into an HDTV so it's probably appropriate to push even though it didn't make the window. We could be cleverer about this but the simple version seems to be the safe one] From: Patrik Jakobsson <patrik.r.jakobsson@gmail.com> At the moment we cannot allocate more than stolen memory size for framebuffers. To get around that issues we discard modes that doesn't fit. This is a temporary solution until we can freely allocate framebuffer memory. [Currently the framebuffer needs to be linear in kernel space due to limits in the kernel fb layer - AC] Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Showing 4 changed files with 24 additions and 8 deletions Side-by-side Diff
drivers/gpu/drm/gma500/cdv_intel_crt.c
... | ... | @@ -66,6 +66,7 @@ |
66 | 66 | static int cdv_intel_crt_mode_valid(struct drm_connector *connector, |
67 | 67 | struct drm_display_mode *mode) |
68 | 68 | { |
69 | + struct drm_psb_private *dev_priv = connector->dev->dev_private; | |
69 | 70 | int max_clock = 0; |
70 | 71 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
71 | 72 | return MODE_NO_DBLESCAN; |
... | ... | @@ -81,6 +82,11 @@ |
81 | 82 | |
82 | 83 | if (mode->hdisplay > 1680 || mode->vdisplay > 1050) |
83 | 84 | return MODE_PANEL; |
85 | + | |
86 | + /* We assume worst case scenario of 32 bpp here, since we don't know */ | |
87 | + if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > | |
88 | + dev_priv->vram_stolen_size) | |
89 | + return MODE_MEM; | |
84 | 90 | |
85 | 91 | return MODE_OK; |
86 | 92 | } |
drivers/gpu/drm/gma500/cdv_intel_hdmi.c
... | ... | @@ -241,6 +241,7 @@ |
241 | 241 | static int cdv_hdmi_mode_valid(struct drm_connector *connector, |
242 | 242 | struct drm_display_mode *mode) |
243 | 243 | { |
244 | + struct drm_psb_private *dev_priv = connector->dev->dev_private; | |
244 | 245 | |
245 | 246 | if (mode->clock > 165000) |
246 | 247 | return MODE_CLOCK_HIGH; |
... | ... | @@ -255,14 +256,11 @@ |
255 | 256 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
256 | 257 | return MODE_NO_INTERLACE; |
257 | 258 | |
258 | - /* | |
259 | - * FIXME: for now we limit the size to 1680x1050 on CDV, otherwise it | |
260 | - * will go beyond the stolen memory size allocated to the framebuffer | |
261 | - */ | |
262 | - if (mode->hdisplay > 1680) | |
263 | - return MODE_PANEL; | |
264 | - if (mode->vdisplay > 1050) | |
265 | - return MODE_PANEL; | |
259 | + /* We assume worst case scenario of 32 bpp here, since we don't know */ | |
260 | + if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > | |
261 | + dev_priv->vram_stolen_size) | |
262 | + return MODE_MEM; | |
263 | + | |
266 | 264 | return MODE_OK; |
267 | 265 | } |
268 | 266 |
drivers/gpu/drm/gma500/oaktrail_hdmi.c
... | ... | @@ -506,6 +506,7 @@ |
506 | 506 | static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, |
507 | 507 | struct drm_display_mode *mode) |
508 | 508 | { |
509 | + struct drm_psb_private *dev_priv = connector->dev->dev_private; | |
509 | 510 | if (mode->clock > 165000) |
510 | 511 | return MODE_CLOCK_HIGH; |
511 | 512 | if (mode->clock < 20000) |
... | ... | @@ -513,6 +514,11 @@ |
513 | 514 | |
514 | 515 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
515 | 516 | return MODE_NO_DBLESCAN; |
517 | + | |
518 | + /* We assume worst case scenario of 32 bpp here, since we don't know */ | |
519 | + if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > | |
520 | + dev_priv->vram_stolen_size) | |
521 | + return MODE_MEM; | |
516 | 522 | |
517 | 523 | return MODE_OK; |
518 | 524 | } |
drivers/gpu/drm/gma500/psb_intel_sdvo.c
... | ... | @@ -1141,6 +1141,7 @@ |
1141 | 1141 | static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, |
1142 | 1142 | struct drm_display_mode *mode) |
1143 | 1143 | { |
1144 | + struct drm_psb_private *dev_priv = connector->dev->dev_private; | |
1144 | 1145 | struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); |
1145 | 1146 | |
1146 | 1147 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
... | ... | @@ -1159,6 +1160,11 @@ |
1159 | 1160 | if (mode->vdisplay > psb_intel_sdvo->sdvo_lvds_fixed_mode->vdisplay) |
1160 | 1161 | return MODE_PANEL; |
1161 | 1162 | } |
1163 | + | |
1164 | + /* We assume worst case scenario of 32 bpp here, since we don't know */ | |
1165 | + if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > | |
1166 | + dev_priv->vram_stolen_size) | |
1167 | + return MODE_MEM; | |
1162 | 1168 | |
1163 | 1169 | return MODE_OK; |
1164 | 1170 | } |