if (update_pending &&
(DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id,
&vpos, &hpos)) &&
- (vpos >=0) &&
- (vpos < (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100)) {
+ ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) ||
+ (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) {
+ /* crtc didn't flip in this target vblank interval,
+ * but flip is pending in crtc. Based on the current
+ * scanout position we know that the current frame is
+ * (nearly) complete and the flip will (likely)
+ * complete before the start of the next frame.
+ */
+ update_pending = 0;
+ }
+ if (update_pending) {
/* crtc didn't flip in this target vblank interval,
* but flip is pending in crtc. It will complete it
* in next vblank interval, so complete the flip at
.create_handle = radeon_user_framebuffer_create_handle,
};
-void
+int
radeon_framebuffer_init(struct drm_device *dev,
struct radeon_framebuffer *rfb,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_gem_object *obj)
{
+ int ret;
rfb->obj = obj;
- drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
+ ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
+ if (ret) {
+ rfb->obj = NULL;
+ return ret;
+ }
drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
+ return 0;
}
static struct drm_framebuffer *
{
struct drm_gem_object *obj;
struct radeon_framebuffer *radeon_fb;
+ int ret;
obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
if (obj == NULL) {
if (radeon_fb == NULL)
return ERR_PTR(-ENOMEM);
- radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
+ ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
+ if (ret) {
+ kfree(radeon_fb);
+ drm_gem_object_unreference_unlocked(obj);
+ return NULL;
+ }
return &radeon_fb->base;
}
.output_poll_changed = radeon_output_poll_changed
};
-struct drm_prop_enum_list {
- int type;
- char *name;
-};
-
static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] =
{ { 0, "driver" },
{ 1, "bios" },
static int radeon_modeset_create_props(struct radeon_device *rdev)
{
- int i, sz;
+ int sz;
if (rdev->is_atom_bios) {
rdev->mode_info.coherent_mode_property =
- drm_property_create(rdev->ddev,
- DRM_MODE_PROP_RANGE,
- "coherent", 2);
+ drm_property_create_range(rdev->ddev, 0 , "coherent", 0, 1);
if (!rdev->mode_info.coherent_mode_property)
return -ENOMEM;
-
- rdev->mode_info.coherent_mode_property->values[0] = 0;
- rdev->mode_info.coherent_mode_property->values[1] = 1;
}
if (!ASIC_IS_AVIVO(rdev)) {
sz = ARRAY_SIZE(radeon_tmds_pll_enum_list);
rdev->mode_info.tmds_pll_property =
- drm_property_create(rdev->ddev,
- DRM_MODE_PROP_ENUM,
- "tmds_pll", sz);
- for (i = 0; i < sz; i++) {
- drm_property_add_enum(rdev->mode_info.tmds_pll_property,
- i,
- radeon_tmds_pll_enum_list[i].type,
- radeon_tmds_pll_enum_list[i].name);
- }
+ drm_property_create_enum(rdev->ddev, 0,
+ "tmds_pll",
+ radeon_tmds_pll_enum_list, sz);
}
rdev->mode_info.load_detect_property =
- drm_property_create(rdev->ddev,
- DRM_MODE_PROP_RANGE,
- "load detection", 2);
+ drm_property_create_range(rdev->ddev, 0, "load detection", 0, 1);
if (!rdev->mode_info.load_detect_property)
return -ENOMEM;
- rdev->mode_info.load_detect_property->values[0] = 0;
- rdev->mode_info.load_detect_property->values[1] = 1;
drm_mode_create_scaling_mode_property(rdev->ddev);
sz = ARRAY_SIZE(radeon_tv_std_enum_list);
rdev->mode_info.tv_std_property =
- drm_property_create(rdev->ddev,
- DRM_MODE_PROP_ENUM,
- "tv standard", sz);
- for (i = 0; i < sz; i++) {
- drm_property_add_enum(rdev->mode_info.tv_std_property,
- i,
- radeon_tv_std_enum_list[i].type,
- radeon_tv_std_enum_list[i].name);
- }
+ drm_property_create_enum(rdev->ddev, 0,
+ "tv standard",
+ radeon_tv_std_enum_list, sz);
sz = ARRAY_SIZE(radeon_underscan_enum_list);
rdev->mode_info.underscan_property =
- drm_property_create(rdev->ddev,
- DRM_MODE_PROP_ENUM,
- "underscan", sz);
- for (i = 0; i < sz; i++) {
- drm_property_add_enum(rdev->mode_info.underscan_property,
- i,
- radeon_underscan_enum_list[i].type,
- radeon_underscan_enum_list[i].name);
- }
+ drm_property_create_enum(rdev->ddev, 0,
+ "underscan",
+ radeon_underscan_enum_list, sz);
rdev->mode_info.underscan_hborder_property =
- drm_property_create(rdev->ddev,
- DRM_MODE_PROP_RANGE,
- "underscan hborder", 2);
+ drm_property_create_range(rdev->ddev, 0,
+ "underscan hborder", 0, 128);
if (!rdev->mode_info.underscan_hborder_property)
return -ENOMEM;
- rdev->mode_info.underscan_hborder_property->values[0] = 0;
- rdev->mode_info.underscan_hborder_property->values[1] = 128;
rdev->mode_info.underscan_vborder_property =
- drm_property_create(rdev->ddev,
- DRM_MODE_PROP_RANGE,
- "underscan vborder", 2);
+ drm_property_create_range(rdev->ddev, 0,
+ "underscan vborder", 0, 128);
if (!rdev->mode_info.underscan_vborder_property)
return -ENOMEM;
- rdev->mode_info.underscan_vborder_property->values[0] = 0;
- rdev->mode_info.underscan_vborder_property->values[1] = 128;
return 0;
}
rdev->ddev->mode_config.max_height = 4096;
}
+ rdev->ddev->mode_config.preferred_depth = 24;
+ rdev->ddev->mode_config.prefer_shadow = 1;
+
rdev->ddev->mode_config.fb_base = rdev->mc.aper_base;
ret = radeon_modeset_create_props(rdev);