Commit 9f821c675a389cf4aab7f1dc8ee0860fba4f3204

Authored by Alan Cox
Committed by Dave Airlie
1 parent afe887df1c

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 }