提交 2d28b633 编写于 作者: D Dave Airlie

Merge tag 'omapdrm-4.2-fixes' of...

Merge tag 'omapdrm-4.2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux into drm-fixes

omapdrm fixes for 4.2

Small fixes for omapdrm, including:
* Fix packed 24 bit color formats
* Ensure the planes are inside the crtc
* Handle out-of-dma-memory error

* tag 'omapdrm-4.2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux:
  drm/omap: replace ALIGN(PAGE_SIZE) by PAGE_ALIGN
  drm/omap: fix align_pitch() for 24 bits per pixel
  drm/omap: fix omap_gem_put_paddr() error handling
  drm/omap: fix omap_framebuffer_unpin() error handling
  drm/omap: increase DMM transaction timeout
  drm/omap: check that plane is inside crtc
  drm/omap: return error if dma_alloc_writecombine fails
...@@ -285,7 +285,7 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait) ...@@ -285,7 +285,7 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
if (wait) { if (wait) {
if (!wait_for_completion_timeout(&engine->compl, if (!wait_for_completion_timeout(&engine->compl,
msecs_to_jiffies(1))) { msecs_to_jiffies(100))) {
dev_err(dmm->dev, "timed out waiting for done\n"); dev_err(dmm->dev, "timed out waiting for done\n");
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
} }
......
...@@ -177,7 +177,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev, ...@@ -177,7 +177,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos); struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb, int p); struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb, int p);
int omap_framebuffer_pin(struct drm_framebuffer *fb); int omap_framebuffer_pin(struct drm_framebuffer *fb);
int omap_framebuffer_unpin(struct drm_framebuffer *fb); void omap_framebuffer_unpin(struct drm_framebuffer *fb);
void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
struct omap_drm_window *win, struct omap_overlay_info *info); struct omap_drm_window *win, struct omap_overlay_info *info);
struct drm_connector *omap_framebuffer_get_next_connector( struct drm_connector *omap_framebuffer_get_next_connector(
...@@ -211,7 +211,7 @@ void omap_gem_dma_sync(struct drm_gem_object *obj, ...@@ -211,7 +211,7 @@ void omap_gem_dma_sync(struct drm_gem_object *obj,
enum dma_data_direction dir); enum dma_data_direction dir);
int omap_gem_get_paddr(struct drm_gem_object *obj, int omap_gem_get_paddr(struct drm_gem_object *obj,
dma_addr_t *paddr, bool remap); dma_addr_t *paddr, bool remap);
int omap_gem_put_paddr(struct drm_gem_object *obj); void omap_gem_put_paddr(struct drm_gem_object *obj);
int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages, int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages,
bool remap); bool remap);
int omap_gem_put_pages(struct drm_gem_object *obj); int omap_gem_put_pages(struct drm_gem_object *obj);
...@@ -236,7 +236,7 @@ static inline int align_pitch(int pitch, int width, int bpp) ...@@ -236,7 +236,7 @@ static inline int align_pitch(int pitch, int width, int bpp)
/* PVR needs alignment to 8 pixels.. right now that is the most /* PVR needs alignment to 8 pixels.. right now that is the most
* restrictive stride requirement.. * restrictive stride requirement..
*/ */
return ALIGN(pitch, 8 * bytespp); return roundup(pitch, 8 * bytespp);
} }
/* map crtc to vblank mask */ /* map crtc to vblank mask */
......
...@@ -287,10 +287,10 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb) ...@@ -287,10 +287,10 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb)
} }
/* unpin, no longer being scanned out: */ /* unpin, no longer being scanned out: */
int omap_framebuffer_unpin(struct drm_framebuffer *fb) void omap_framebuffer_unpin(struct drm_framebuffer *fb)
{ {
struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb); struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
int ret, i, n = drm_format_num_planes(fb->pixel_format); int i, n = drm_format_num_planes(fb->pixel_format);
mutex_lock(&omap_fb->lock); mutex_lock(&omap_fb->lock);
...@@ -298,24 +298,16 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb) ...@@ -298,24 +298,16 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb)
if (omap_fb->pin_count > 0) { if (omap_fb->pin_count > 0) {
mutex_unlock(&omap_fb->lock); mutex_unlock(&omap_fb->lock);
return 0; return;
} }
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
struct plane *plane = &omap_fb->planes[i]; struct plane *plane = &omap_fb->planes[i];
ret = omap_gem_put_paddr(plane->bo); omap_gem_put_paddr(plane->bo);
if (ret)
goto fail;
plane->paddr = 0; plane->paddr = 0;
} }
mutex_unlock(&omap_fb->lock); mutex_unlock(&omap_fb->lock);
return 0;
fail:
mutex_unlock(&omap_fb->lock);
return ret;
} }
struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb, int p) struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb, int p)
......
...@@ -135,7 +135,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, ...@@ -135,7 +135,7 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
fbdev->ywrap_enabled = priv->has_dmm && ywrap_enabled; fbdev->ywrap_enabled = priv->has_dmm && ywrap_enabled;
if (fbdev->ywrap_enabled) { if (fbdev->ywrap_enabled) {
/* need to align pitch to page size if using DMM scrolling */ /* need to align pitch to page size if using DMM scrolling */
mode_cmd.pitches[0] = ALIGN(mode_cmd.pitches[0], PAGE_SIZE); mode_cmd.pitches[0] = PAGE_ALIGN(mode_cmd.pitches[0]);
} }
/* allocate backing bo */ /* allocate backing bo */
......
...@@ -808,10 +808,10 @@ int omap_gem_get_paddr(struct drm_gem_object *obj, ...@@ -808,10 +808,10 @@ int omap_gem_get_paddr(struct drm_gem_object *obj,
/* Release physical address, when DMA is no longer being performed.. this /* Release physical address, when DMA is no longer being performed.. this
* could potentially unpin and unmap buffers from TILER * could potentially unpin and unmap buffers from TILER
*/ */
int omap_gem_put_paddr(struct drm_gem_object *obj) void omap_gem_put_paddr(struct drm_gem_object *obj)
{ {
struct omap_gem_object *omap_obj = to_omap_bo(obj); struct omap_gem_object *omap_obj = to_omap_bo(obj);
int ret = 0; int ret;
mutex_lock(&obj->dev->struct_mutex); mutex_lock(&obj->dev->struct_mutex);
if (omap_obj->paddr_cnt > 0) { if (omap_obj->paddr_cnt > 0) {
...@@ -821,7 +821,6 @@ int omap_gem_put_paddr(struct drm_gem_object *obj) ...@@ -821,7 +821,6 @@ int omap_gem_put_paddr(struct drm_gem_object *obj)
if (ret) { if (ret) {
dev_err(obj->dev->dev, dev_err(obj->dev->dev,
"could not unpin pages: %d\n", ret); "could not unpin pages: %d\n", ret);
goto fail;
} }
ret = tiler_release(omap_obj->block); ret = tiler_release(omap_obj->block);
if (ret) { if (ret) {
...@@ -832,9 +831,8 @@ int omap_gem_put_paddr(struct drm_gem_object *obj) ...@@ -832,9 +831,8 @@ int omap_gem_put_paddr(struct drm_gem_object *obj)
omap_obj->block = NULL; omap_obj->block = NULL;
} }
} }
fail:
mutex_unlock(&obj->dev->struct_mutex); mutex_unlock(&obj->dev->struct_mutex);
return ret;
} }
/* Get rotated scanout address (only valid if already pinned), at the /* Get rotated scanout address (only valid if already pinned), at the
...@@ -1378,11 +1376,7 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, ...@@ -1378,11 +1376,7 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
omap_obj = kzalloc(sizeof(*omap_obj), GFP_KERNEL); omap_obj = kzalloc(sizeof(*omap_obj), GFP_KERNEL);
if (!omap_obj) if (!omap_obj)
goto fail; return NULL;
spin_lock(&priv->list_lock);
list_add(&omap_obj->mm_list, &priv->obj_list);
spin_unlock(&priv->list_lock);
obj = &omap_obj->base; obj = &omap_obj->base;
...@@ -1392,11 +1386,19 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, ...@@ -1392,11 +1386,19 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
*/ */
omap_obj->vaddr = dma_alloc_writecombine(dev->dev, size, omap_obj->vaddr = dma_alloc_writecombine(dev->dev, size,
&omap_obj->paddr, GFP_KERNEL); &omap_obj->paddr, GFP_KERNEL);
if (omap_obj->vaddr) if (!omap_obj->vaddr) {
flags |= OMAP_BO_DMA; kfree(omap_obj);
return NULL;
}
flags |= OMAP_BO_DMA;
} }
spin_lock(&priv->list_lock);
list_add(&omap_obj->mm_list, &priv->obj_list);
spin_unlock(&priv->list_lock);
omap_obj->flags = flags; omap_obj->flags = flags;
if (flags & OMAP_BO_TILED) { if (flags & OMAP_BO_TILED) {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
* this program. If not, see <http://www.gnu.org/licenses/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_helper.h>
#include <drm/drm_plane_helper.h> #include <drm/drm_plane_helper.h>
...@@ -153,9 +154,34 @@ static void omap_plane_atomic_disable(struct drm_plane *plane, ...@@ -153,9 +154,34 @@ static void omap_plane_atomic_disable(struct drm_plane *plane,
dispc_ovl_enable(omap_plane->id, false); dispc_ovl_enable(omap_plane->id, false);
} }
static int omap_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
{
struct drm_crtc_state *crtc_state;
if (!state->crtc)
return 0;
crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
if (state->crtc_x < 0 || state->crtc_y < 0)
return -EINVAL;
if (state->crtc_x + state->crtc_w > crtc_state->adjusted_mode.hdisplay)
return -EINVAL;
if (state->crtc_y + state->crtc_h > crtc_state->adjusted_mode.vdisplay)
return -EINVAL;
return 0;
}
static const struct drm_plane_helper_funcs omap_plane_helper_funcs = { static const struct drm_plane_helper_funcs omap_plane_helper_funcs = {
.prepare_fb = omap_plane_prepare_fb, .prepare_fb = omap_plane_prepare_fb,
.cleanup_fb = omap_plane_cleanup_fb, .cleanup_fb = omap_plane_cleanup_fb,
.atomic_check = omap_plane_atomic_check,
.atomic_update = omap_plane_atomic_update, .atomic_update = omap_plane_atomic_update,
.atomic_disable = omap_plane_atomic_disable, .atomic_disable = omap_plane_atomic_disable,
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册