提交 9f821c67 编写于 作者: A Alan Cox 提交者: Dave Airlie

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: NPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
Signed-off-by: NAlan Cox <alan@linux.intel.com>
Signed-off-by: NDave Airlie <airlied@redhat.com>
上级 afe887df
...@@ -66,6 +66,7 @@ static void cdv_intel_crt_dpms(struct drm_encoder *encoder, int mode) ...@@ -66,6 +66,7 @@ static void cdv_intel_crt_dpms(struct drm_encoder *encoder, int mode)
static int cdv_intel_crt_mode_valid(struct drm_connector *connector, static int cdv_intel_crt_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode) struct drm_display_mode *mode)
{ {
struct drm_psb_private *dev_priv = connector->dev->dev_private;
int max_clock = 0; int max_clock = 0;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN) if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN; return MODE_NO_DBLESCAN;
...@@ -82,6 +83,11 @@ static int cdv_intel_crt_mode_valid(struct drm_connector *connector, ...@@ -82,6 +83,11 @@ static int cdv_intel_crt_mode_valid(struct drm_connector *connector,
if (mode->hdisplay > 1680 || mode->vdisplay > 1050) if (mode->hdisplay > 1680 || mode->vdisplay > 1050)
return MODE_PANEL; return MODE_PANEL;
/* We assume worst case scenario of 32 bpp here, since we don't know */
if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) >
dev_priv->vram_stolen_size)
return MODE_MEM;
return MODE_OK; return MODE_OK;
} }
......
...@@ -241,6 +241,7 @@ static int cdv_hdmi_get_modes(struct drm_connector *connector) ...@@ -241,6 +241,7 @@ static int cdv_hdmi_get_modes(struct drm_connector *connector)
static int cdv_hdmi_mode_valid(struct drm_connector *connector, static int cdv_hdmi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode) struct drm_display_mode *mode)
{ {
struct drm_psb_private *dev_priv = connector->dev->dev_private;
if (mode->clock > 165000) if (mode->clock > 165000)
return MODE_CLOCK_HIGH; return MODE_CLOCK_HIGH;
...@@ -255,14 +256,11 @@ static int cdv_hdmi_mode_valid(struct drm_connector *connector, ...@@ -255,14 +256,11 @@ static int cdv_hdmi_mode_valid(struct drm_connector *connector,
if (mode->flags & DRM_MODE_FLAG_INTERLACE) if (mode->flags & DRM_MODE_FLAG_INTERLACE)
return MODE_NO_INTERLACE; return MODE_NO_INTERLACE;
/* /* We assume worst case scenario of 32 bpp here, since we don't know */
* FIXME: for now we limit the size to 1680x1050 on CDV, otherwise it if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) >
* will go beyond the stolen memory size allocated to the framebuffer dev_priv->vram_stolen_size)
*/ return MODE_MEM;
if (mode->hdisplay > 1680)
return MODE_PANEL;
if (mode->vdisplay > 1050)
return MODE_PANEL;
return MODE_OK; return MODE_OK;
} }
......
...@@ -506,6 +506,7 @@ int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc, ...@@ -506,6 +506,7 @@ int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc,
static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, static int oaktrail_hdmi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode) struct drm_display_mode *mode)
{ {
struct drm_psb_private *dev_priv = connector->dev->dev_private;
if (mode->clock > 165000) if (mode->clock > 165000)
return MODE_CLOCK_HIGH; return MODE_CLOCK_HIGH;
if (mode->clock < 20000) if (mode->clock < 20000)
...@@ -514,6 +515,11 @@ static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, ...@@ -514,6 +515,11 @@ static int oaktrail_hdmi_mode_valid(struct drm_connector *connector,
if (mode->flags & DRM_MODE_FLAG_DBLSCAN) if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN; return MODE_NO_DBLESCAN;
/* We assume worst case scenario of 32 bpp here, since we don't know */
if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) >
dev_priv->vram_stolen_size)
return MODE_MEM;
return MODE_OK; return MODE_OK;
} }
......
...@@ -1141,6 +1141,7 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode) ...@@ -1141,6 +1141,7 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, static int psb_intel_sdvo_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode) struct drm_display_mode *mode)
{ {
struct drm_psb_private *dev_priv = connector->dev->dev_private;
struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector);
if (mode->flags & DRM_MODE_FLAG_DBLSCAN) if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
...@@ -1160,6 +1161,11 @@ static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, ...@@ -1160,6 +1161,11 @@ static int psb_intel_sdvo_mode_valid(struct drm_connector *connector,
return MODE_PANEL; return MODE_PANEL;
} }
/* We assume worst case scenario of 32 bpp here, since we don't know */
if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) >
dev_priv->vram_stolen_size)
return MODE_MEM;
return MODE_OK; return MODE_OK;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册