forked from Minki/linux
Merge tag 'drm-misc-fixes-2017-12-21' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
drm-misc-fixes before holidays: - fixup for the lease fixup (Keith) - fb leak in the ww mutex fallback code (Maarten) - sun4i fixes (Maxime, Hans) * tag 'drm-misc-fixes-2017-12-21' of git://anongit.freedesktop.org/drm/drm-misc: drm: move lease init after validation in drm_lease_create drm/plane: Make framebuffer refcounting the responsibility of setplane_internal callers drm/sun4i: hdmi: Move the mode_valid callback to the encoder drm/sun4i: Fix error path handling drm/sun4i: validate modes for HDMI
This commit is contained in:
commit
12e412d785
@ -220,17 +220,6 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr
|
||||
|
||||
mutex_lock(&dev->mode_config.idr_mutex);
|
||||
|
||||
/* Insert the new lessee into the tree */
|
||||
id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL);
|
||||
if (id < 0) {
|
||||
error = id;
|
||||
goto out_lessee;
|
||||
}
|
||||
|
||||
lessee->lessee_id = id;
|
||||
lessee->lessor = drm_master_get(lessor);
|
||||
list_add_tail(&lessee->lessee_list, &lessor->lessees);
|
||||
|
||||
idr_for_each_entry(leases, entry, object) {
|
||||
error = 0;
|
||||
if (!idr_find(&dev->mode_config.crtc_idr, object))
|
||||
@ -246,6 +235,17 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert the new lessee into the tree */
|
||||
id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL);
|
||||
if (id < 0) {
|
||||
error = id;
|
||||
goto out_lessee;
|
||||
}
|
||||
|
||||
lessee->lessee_id = id;
|
||||
lessee->lessor = drm_master_get(lessor);
|
||||
list_add_tail(&lessee->lessee_list, &lessor->lessees);
|
||||
|
||||
/* Move the leases over */
|
||||
lessee->leases = *leases;
|
||||
DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor);
|
||||
|
@ -558,11 +558,10 @@ int drm_plane_check_pixel_format(const struct drm_plane *plane, u32 format)
|
||||
}
|
||||
|
||||
/*
|
||||
* setplane_internal - setplane handler for internal callers
|
||||
* __setplane_internal - setplane handler for internal callers
|
||||
*
|
||||
* Note that we assume an extra reference has already been taken on fb. If the
|
||||
* update fails, this reference will be dropped before return; if it succeeds,
|
||||
* the previous framebuffer (if any) will be unreferenced instead.
|
||||
* This function will take a reference on the new fb for the plane
|
||||
* on success.
|
||||
*
|
||||
* src_{x,y,w,h} are provided in 16.16 fixed point format
|
||||
*/
|
||||
@ -630,14 +629,12 @@ static int __setplane_internal(struct drm_plane *plane,
|
||||
if (!ret) {
|
||||
plane->crtc = crtc;
|
||||
plane->fb = fb;
|
||||
fb = NULL;
|
||||
drm_framebuffer_get(plane->fb);
|
||||
} else {
|
||||
plane->old_fb = NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
if (fb)
|
||||
drm_framebuffer_put(fb);
|
||||
if (plane->old_fb)
|
||||
drm_framebuffer_put(plane->old_fb);
|
||||
plane->old_fb = NULL;
|
||||
@ -685,6 +682,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
|
||||
struct drm_plane *plane;
|
||||
struct drm_crtc *crtc = NULL;
|
||||
struct drm_framebuffer *fb = NULL;
|
||||
int ret;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
return -EINVAL;
|
||||
@ -717,15 +715,16 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* setplane_internal will take care of deref'ing either the old or new
|
||||
* framebuffer depending on success.
|
||||
*/
|
||||
return setplane_internal(plane, crtc, fb,
|
||||
plane_req->crtc_x, plane_req->crtc_y,
|
||||
plane_req->crtc_w, plane_req->crtc_h,
|
||||
plane_req->src_x, plane_req->src_y,
|
||||
plane_req->src_w, plane_req->src_h);
|
||||
ret = setplane_internal(plane, crtc, fb,
|
||||
plane_req->crtc_x, plane_req->crtc_y,
|
||||
plane_req->crtc_w, plane_req->crtc_h,
|
||||
plane_req->src_x, plane_req->src_y,
|
||||
plane_req->src_w, plane_req->src_h);
|
||||
|
||||
if (fb)
|
||||
drm_framebuffer_put(fb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int drm_mode_cursor_universal(struct drm_crtc *crtc,
|
||||
@ -788,13 +787,12 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
|
||||
src_h = fb->height << 16;
|
||||
}
|
||||
|
||||
/*
|
||||
* setplane_internal will take care of deref'ing either the old or new
|
||||
* framebuffer depending on success.
|
||||
*/
|
||||
ret = __setplane_internal(crtc->cursor, crtc, fb,
|
||||
crtc_x, crtc_y, crtc_w, crtc_h,
|
||||
0, 0, src_w, src_h, ctx);
|
||||
crtc_x, crtc_y, crtc_w, crtc_h,
|
||||
0, 0, src_w, src_h, ctx);
|
||||
|
||||
if (fb)
|
||||
drm_framebuffer_put(fb);
|
||||
|
||||
/* Update successful; save new cursor position, if necessary */
|
||||
if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) {
|
||||
|
@ -175,11 +175,31 @@ static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
|
||||
writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG);
|
||||
}
|
||||
|
||||
static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
|
||||
unsigned long rate = mode->clock * 1000;
|
||||
unsigned long diff = rate / 200; /* +-0.5% allowed by HDMI spec */
|
||||
long rounded_rate;
|
||||
|
||||
/* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */
|
||||
if (rate > 165000000)
|
||||
return MODE_CLOCK_HIGH;
|
||||
rounded_rate = clk_round_rate(hdmi->tmds_clk, rate);
|
||||
if (rounded_rate > 0 &&
|
||||
max_t(unsigned long, rounded_rate, rate) -
|
||||
min_t(unsigned long, rounded_rate, rate) < diff)
|
||||
return MODE_OK;
|
||||
return MODE_NOCLOCK;
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
|
||||
.atomic_check = sun4i_hdmi_atomic_check,
|
||||
.disable = sun4i_hdmi_disable,
|
||||
.enable = sun4i_hdmi_enable,
|
||||
.mode_set = sun4i_hdmi_mode_set,
|
||||
.mode_valid = sun4i_hdmi_mode_valid,
|
||||
};
|
||||
|
||||
static const struct drm_encoder_funcs sun4i_hdmi_funcs = {
|
||||
|
@ -724,12 +724,12 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
|
||||
if (IS_ERR(tcon->crtc)) {
|
||||
dev_err(dev, "Couldn't create our CRTC\n");
|
||||
ret = PTR_ERR(tcon->crtc);
|
||||
goto err_free_clocks;
|
||||
goto err_free_dotclock;
|
||||
}
|
||||
|
||||
ret = sun4i_rgb_init(drm, tcon);
|
||||
if (ret < 0)
|
||||
goto err_free_clocks;
|
||||
goto err_free_dotclock;
|
||||
|
||||
if (tcon->quirks->needs_de_be_mux) {
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user