aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-07-05 16:28:05 -0400
committerDave Airlie <airlied@redhat.com>2018-07-05 16:29:24 -0400
commit96b2bb0b9637df1a68bb5b6853903a207fabcefd (patch)
tree6f9d61aeb2a46c0492aa18a98b77106c84306724 /drivers
parentf29135ee4e0d4e01911ed569f731bfdb841cea6d (diff)
parentf8466184bd5b5c21eb6196cd0e44668725a2e47a (diff)
Merge tag 'omapdrm-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux into drm-next
omapdrm changes for 4.19 * Workaround for DRA7 errata i932 * Fix mm_list locking * Cleanups Signed-off-by: Dave Airlie <airlied@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/88b2e77f-9646-d15f-645b-ba45af2a1966@ti.com
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c2
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/core.c4
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dispc.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/display.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dpi.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dsi.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.h5
-rw-r--r--drivers/gpu/drm/omapdrm/dss/pll.c73
-rw-r--r--drivers/gpu/drm/omapdrm/dss/sdi.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/venc.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/video-pll.c1
-rw-r--r--drivers/gpu/drm/omapdrm/omap_debugfs.c9
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c4
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h2
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fbdev.c8
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem.c286
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem.h3
19 files changed, 237 insertions, 176 deletions
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
index 92fe125ce22e..f34c06bb5bd7 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
@@ -4,7 +4,7 @@
4 * Copyright (C) 2010 Nokia Corporation 4 * Copyright (C) 2010 Nokia Corporation
5 * 5 *
6 * Original Driver Author: Imre Deak <imre.deak@nokia.com> 6 * Original Driver Author: Imre Deak <imre.deak@nokia.com>
7 * Based on panel-generic.c by Tomi Valkeinen <tomi.valkeinen@nokia.com> 7 * Based on panel-generic.c by Tomi Valkeinen <tomi.valkeinen@ti.com>
8 * Adapted to new DSS2 framework: Roger Quadros <roger.quadros@nokia.com> 8 * Adapted to new DSS2 framework: Roger Quadros <roger.quadros@nokia.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
index b5d8a00df811..a1f1dc18407a 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
@@ -2,7 +2,7 @@
2 * Toppoly TD028TTEC1 panel support 2 * Toppoly TD028TTEC1 panel support
3 * 3 *
4 * Copyright (C) 2008 Nokia Corporation 4 * Copyright (C) 2008 Nokia Corporation
5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
6 * 6 *
7 * Neo 1973 code (jbt6k74.c): 7 * Neo 1973 code (jbt6k74.c):
8 * Copyright (C) 2006-2007 by OpenMoko, Inc. 8 * Copyright (C) 2006-2007 by OpenMoko, Inc.
diff --git a/drivers/gpu/drm/omapdrm/dss/core.c b/drivers/gpu/drm/omapdrm/dss/core.c
index acef7ece5783..07d00a186f15 100644
--- a/drivers/gpu/drm/omapdrm/dss/core.c
+++ b/drivers/gpu/drm/omapdrm/dss/core.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2009 Nokia Corporation 2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4 * 4 *
5 * Some code and ideas taken from drivers/video/omap/ driver 5 * Some code and ideas taken from drivers/video/omap/ driver
6 * by Imre Deak. 6 * by Imre Deak.
@@ -82,7 +82,7 @@ static void __exit omap_dss_exit(void)
82module_init(omap_dss_init); 82module_init(omap_dss_init);
83module_exit(omap_dss_exit); 83module_exit(omap_dss_exit);
84 84
85MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); 85MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
86MODULE_DESCRIPTION("OMAP2/3 Display Subsystem"); 86MODULE_DESCRIPTION("OMAP2/3 Display Subsystem");
87MODULE_LICENSE("GPL v2"); 87MODULE_LICENSE("GPL v2");
88 88
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 7f3ac6b13b56..84f274c4a4cb 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2009 Nokia Corporation 2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4 * 4 *
5 * Some code and ideas taken from drivers/video/omap/ driver 5 * Some code and ideas taken from drivers/video/omap/ driver
6 * by Imre Deak. 6 * by Imre Deak.
diff --git a/drivers/gpu/drm/omapdrm/dss/display.c b/drivers/gpu/drm/omapdrm/dss/display.c
index 424143128cd4..9e7fcbd57e52 100644
--- a/drivers/gpu/drm/omapdrm/dss/display.c
+++ b/drivers/gpu/drm/omapdrm/dss/display.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2009 Nokia Corporation 2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4 * 4 *
5 * Some code and ideas taken from drivers/video/omap/ driver 5 * Some code and ideas taken from drivers/video/omap/ driver
6 * by Imre Deak. 6 * by Imre Deak.
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 3d662e6805eb..9fcc50217133 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2009 Nokia Corporation 2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4 * 4 *
5 * Some code and ideas taken from drivers/video/omap/ driver 5 * Some code and ideas taken from drivers/video/omap/ driver
6 * by Imre Deak. 6 * by Imre Deak.
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index d4a680629825..74467b308721 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2009 Nokia Corporation 2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by 6 * under the terms of the GNU General Public License version 2 as published by
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
index 0b908e9de792..cb80ddaa19d2 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2009 Nokia Corporation 2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4 * 4 *
5 * Some code and ideas taken from drivers/video/omap/ driver 5 * Some code and ideas taken from drivers/video/omap/ driver
6 * by Imre Deak. 6 * by Imre Deak.
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h
index 847c78ade024..38302631b64b 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2009 Nokia Corporation 2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4 * 4 *
5 * Some code and ideas taken from drivers/video/omap/ driver 5 * Some code and ideas taken from drivers/video/omap/ driver
6 * by Imre Deak. 6 * by Imre Deak.
@@ -180,6 +180,9 @@ struct dss_pll_hw {
180 180
181 /* DRA7 errata i886: use high N & M to avoid jitter */ 181 /* DRA7 errata i886: use high N & M to avoid jitter */
182 bool errata_i886; 182 bool errata_i886;
183
184 /* DRA7 errata i932: retry pll lock on failure */
185 bool errata_i932;
183}; 186};
184 187
185struct dss_pll { 188struct dss_pll {
diff --git a/drivers/gpu/drm/omapdrm/dss/pll.c b/drivers/gpu/drm/omapdrm/dss/pll.c
index 078b0e8216c3..ff362b38bf0d 100644
--- a/drivers/gpu/drm/omapdrm/dss/pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/pll.c
@@ -16,6 +16,7 @@
16 16
17#define DSS_SUBSYS_NAME "PLL" 17#define DSS_SUBSYS_NAME "PLL"
18 18
19#include <linux/delay.h>
19#include <linux/clk.h> 20#include <linux/clk.h>
20#include <linux/io.h> 21#include <linux/io.h>
21#include <linux/kernel.h> 22#include <linux/kernel.h>
@@ -381,6 +382,22 @@ static int dss_wait_hsdiv_ack(struct dss_pll *pll, u32 hsdiv_ack_mask)
381 return -ETIMEDOUT; 382 return -ETIMEDOUT;
382} 383}
383 384
385static bool pll_is_locked(u32 stat)
386{
387 /*
388 * Required value for each bitfield listed below
389 *
390 * PLL_STATUS[6] = 0 PLL_BYPASS
391 * PLL_STATUS[5] = 0 PLL_HIGHJITTER
392 *
393 * PLL_STATUS[3] = 0 PLL_LOSSREF
394 * PLL_STATUS[2] = 0 PLL_RECAL
395 * PLL_STATUS[1] = 1 PLL_LOCK
396 * PLL_STATUS[0] = 1 PLL_CTRL_RESET_DONE
397 */
398 return ((stat & 0x6f) == 0x3);
399}
400
384int dss_pll_write_config_type_a(struct dss_pll *pll, 401int dss_pll_write_config_type_a(struct dss_pll *pll,
385 const struct dss_pll_clock_info *cinfo) 402 const struct dss_pll_clock_info *cinfo)
386{ 403{
@@ -436,18 +453,54 @@ int dss_pll_write_config_type_a(struct dss_pll *pll,
436 l = FLD_MOD(l, 0, 25, 25); /* M7_CLOCK_EN */ 453 l = FLD_MOD(l, 0, 25, 25); /* M7_CLOCK_EN */
437 writel_relaxed(l, base + PLL_CONFIGURATION2); 454 writel_relaxed(l, base + PLL_CONFIGURATION2);
438 455
439 writel_relaxed(1, base + PLL_GO); /* PLL_GO */ 456 if (hw->errata_i932) {
457 int cnt = 0;
458 u32 sleep_time;
459 const u32 max_lock_retries = 20;
440 460
441 if (wait_for_bit_change(base + PLL_GO, 0, 0) != 0) { 461 /*
442 DSSERR("DSS DPLL GO bit not going down.\n"); 462 * Calculate wait time for PLL LOCK
443 r = -EIO; 463 * 1000 REFCLK cycles in us.
444 goto err; 464 */
445 } 465 sleep_time = DIV_ROUND_UP(1000*1000*1000, cinfo->fint);
446 466
447 if (wait_for_bit_change(base + PLL_STATUS, 1, 1) != 1) { 467 for (cnt = 0; cnt < max_lock_retries; cnt++) {
448 DSSERR("cannot lock DSS DPLL\n"); 468 writel_relaxed(1, base + PLL_GO); /* PLL_GO */
449 r = -EIO; 469
450 goto err; 470 /**
471 * read the register back to ensure the write is
472 * flushed
473 */
474 readl_relaxed(base + PLL_GO);
475
476 usleep_range(sleep_time, sleep_time + 5);
477 l = readl_relaxed(base + PLL_STATUS);
478
479 if (pll_is_locked(l) &&
480 !(readl_relaxed(base + PLL_GO) & 0x1))
481 break;
482
483 }
484
485 if (cnt == max_lock_retries) {
486 DSSERR("cannot lock PLL\n");
487 r = -EIO;
488 goto err;
489 }
490 } else {
491 writel_relaxed(1, base + PLL_GO); /* PLL_GO */
492
493 if (wait_for_bit_change(base + PLL_GO, 0, 0) != 0) {
494 DSSERR("DSS DPLL GO bit not going down.\n");
495 r = -EIO;
496 goto err;
497 }
498
499 if (wait_for_bit_change(base + PLL_STATUS, 1, 1) != 1) {
500 DSSERR("cannot lock DSS DPLL\n");
501 r = -EIO;
502 goto err;
503 }
451 } 504 }
452 505
453 l = readl_relaxed(base + PLL_CONFIGURATION2); 506 l = readl_relaxed(base + PLL_CONFIGURATION2);
diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c
index 1e2c931f6acf..69c3b7a3d5c7 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2009 Nokia Corporation 2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by 6 * under the terms of the GNU General Public License version 2 as published by
diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
index 24d1ced210bd..ac01907dcc34 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2009 Nokia Corporation 2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4 * 4 *
5 * VENC settings from TI's DSS driver 5 * VENC settings from TI's DSS driver
6 * 6 *
diff --git a/drivers/gpu/drm/omapdrm/dss/video-pll.c b/drivers/gpu/drm/omapdrm/dss/video-pll.c
index 585ed94ccf17..cb46311f92c9 100644
--- a/drivers/gpu/drm/omapdrm/dss/video-pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/video-pll.c
@@ -134,6 +134,7 @@ static const struct dss_pll_hw dss_dra7_video_pll_hw = {
134 .has_refsel = true, 134 .has_refsel = true,
135 135
136 .errata_i886 = true, 136 .errata_i886 = true,
137 .errata_i932 = true,
137}; 138};
138 139
139struct dss_pll *dss_video_pll_init(struct dss_device *dss, 140struct dss_pll *dss_video_pll_init(struct dss_device *dss,
diff --git a/drivers/gpu/drm/omapdrm/omap_debugfs.c b/drivers/gpu/drm/omapdrm/omap_debugfs.c
index b42e286616b0..91cf043f2b6b 100644
--- a/drivers/gpu/drm/omapdrm/omap_debugfs.c
+++ b/drivers/gpu/drm/omapdrm/omap_debugfs.c
@@ -30,16 +30,11 @@ static int gem_show(struct seq_file *m, void *arg)
30 struct drm_info_node *node = (struct drm_info_node *) m->private; 30 struct drm_info_node *node = (struct drm_info_node *) m->private;
31 struct drm_device *dev = node->minor->dev; 31 struct drm_device *dev = node->minor->dev;
32 struct omap_drm_private *priv = dev->dev_private; 32 struct omap_drm_private *priv = dev->dev_private;
33 int ret;
34
35 ret = mutex_lock_interruptible(&dev->struct_mutex);
36 if (ret)
37 return ret;
38 33
39 seq_printf(m, "All Objects:\n"); 34 seq_printf(m, "All Objects:\n");
35 mutex_lock(&priv->list_lock);
40 omap_gem_describe_objects(&priv->obj_list, m); 36 omap_gem_describe_objects(&priv->obj_list, m);
41 37 mutex_unlock(&priv->list_lock);
42 mutex_unlock(&dev->struct_mutex);
43 38
44 return 0; 39 return 0;
45} 40}
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index ef3b0e3571ec..5005ecc284d2 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -493,7 +493,7 @@ static struct drm_driver omap_drm_driver = {
493 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 493 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
494 .gem_prime_export = omap_gem_prime_export, 494 .gem_prime_export = omap_gem_prime_export,
495 .gem_prime_import = omap_gem_prime_import, 495 .gem_prime_import = omap_gem_prime_import,
496 .gem_free_object = omap_gem_free_object, 496 .gem_free_object_unlocked = omap_gem_free_object,
497 .gem_vm_ops = &omap_gem_vm_ops, 497 .gem_vm_ops = &omap_gem_vm_ops,
498 .dumb_create = omap_gem_dumb_create, 498 .dumb_create = omap_gem_dumb_create,
499 .dumb_map_offset = omap_gem_dumb_map_offset, 499 .dumb_map_offset = omap_gem_dumb_map_offset,
@@ -540,7 +540,7 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev)
540 priv->omaprev = soc ? (unsigned int)soc->data : 0; 540 priv->omaprev = soc ? (unsigned int)soc->data : 0;
541 priv->wq = alloc_ordered_workqueue("omapdrm", 0); 541 priv->wq = alloc_ordered_workqueue("omapdrm", 0);
542 542
543 spin_lock_init(&priv->list_lock); 543 mutex_init(&priv->list_lock);
544 INIT_LIST_HEAD(&priv->obj_list); 544 INIT_LIST_HEAD(&priv->obj_list);
545 545
546 /* Allocate and initialize the DRM device. */ 546 /* Allocate and initialize the DRM device. */
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 6eaee4df4559..f27c8e216adf 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -71,7 +71,7 @@ struct omap_drm_private {
71 struct workqueue_struct *wq; 71 struct workqueue_struct *wq;
72 72
73 /* lock for obj_list below */ 73 /* lock for obj_list below */
74 spinlock_t list_lock; 74 struct mutex list_lock;
75 75
76 /* list of GEM objects: */ 76 /* list of GEM objects: */
77 struct list_head obj_list; 77 struct list_head obj_list;
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index 0f66c74a54b0..d958cc813a94 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -170,13 +170,11 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
170 goto fail; 170 goto fail;
171 } 171 }
172 172
173 mutex_lock(&dev->struct_mutex);
174
175 fbi = drm_fb_helper_alloc_fbi(helper); 173 fbi = drm_fb_helper_alloc_fbi(helper);
176 if (IS_ERR(fbi)) { 174 if (IS_ERR(fbi)) {
177 dev_err(dev->dev, "failed to allocate fb info\n"); 175 dev_err(dev->dev, "failed to allocate fb info\n");
178 ret = PTR_ERR(fbi); 176 ret = PTR_ERR(fbi);
179 goto fail_unlock; 177 goto fail;
180 } 178 }
181 179
182 DBG("fbi=%p, dev=%p", fbi, dev); 180 DBG("fbi=%p, dev=%p", fbi, dev);
@@ -212,12 +210,8 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
212 DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres); 210 DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);
213 DBG("allocated %dx%d fb", fbdev->fb->width, fbdev->fb->height); 211 DBG("allocated %dx%d fb", fbdev->fb->width, fbdev->fb->height);
214 212
215 mutex_unlock(&dev->struct_mutex);
216
217 return 0; 213 return 0;
218 214
219fail_unlock:
220 mutex_unlock(&dev->struct_mutex);
221fail: 215fail:
222 216
223 if (ret) { 217 if (ret) {
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index 17a53d207978..4ba5d035c590 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -47,6 +47,9 @@ struct omap_gem_object {
47 /** roll applied when mapping to DMM */ 47 /** roll applied when mapping to DMM */
48 u32 roll; 48 u32 roll;
49 49
50 /** protects dma_addr_cnt, block, pages, dma_addrs and vaddr */
51 struct mutex lock;
52
50 /** 53 /**
51 * dma_addr contains the buffer DMA address. It is valid for 54 * dma_addr contains the buffer DMA address. It is valid for
52 * 55 *
@@ -137,14 +140,12 @@ struct omap_drm_usergart {
137 */ 140 */
138 141
139/** get mmap offset */ 142/** get mmap offset */
140static u64 mmap_offset(struct drm_gem_object *obj) 143u64 omap_gem_mmap_offset(struct drm_gem_object *obj)
141{ 144{
142 struct drm_device *dev = obj->dev; 145 struct drm_device *dev = obj->dev;
143 int ret; 146 int ret;
144 size_t size; 147 size_t size;
145 148
146 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
147
148 /* Make it mmapable */ 149 /* Make it mmapable */
149 size = omap_gem_mmap_size(obj); 150 size = omap_gem_mmap_size(obj);
150 ret = drm_gem_create_mmap_offset_size(obj, size); 151 ret = drm_gem_create_mmap_offset_size(obj, size);
@@ -156,7 +157,7 @@ static u64 mmap_offset(struct drm_gem_object *obj)
156 return drm_vma_node_offset_addr(&obj->vma_node); 157 return drm_vma_node_offset_addr(&obj->vma_node);
157} 158}
158 159
159static bool is_contiguous(struct omap_gem_object *omap_obj) 160static bool omap_gem_is_contiguous(struct omap_gem_object *omap_obj)
160{ 161{
161 if (omap_obj->flags & OMAP_BO_MEM_DMA_API) 162 if (omap_obj->flags & OMAP_BO_MEM_DMA_API)
162 return true; 163 return true;
@@ -171,14 +172,14 @@ static bool is_contiguous(struct omap_gem_object *omap_obj)
171 * Eviction 172 * Eviction
172 */ 173 */
173 174
174static void evict_entry(struct drm_gem_object *obj, 175static void omap_gem_evict_entry(struct drm_gem_object *obj,
175 enum tiler_fmt fmt, struct omap_drm_usergart_entry *entry) 176 enum tiler_fmt fmt, struct omap_drm_usergart_entry *entry)
176{ 177{
177 struct omap_gem_object *omap_obj = to_omap_bo(obj); 178 struct omap_gem_object *omap_obj = to_omap_bo(obj);
178 struct omap_drm_private *priv = obj->dev->dev_private; 179 struct omap_drm_private *priv = obj->dev->dev_private;
179 int n = priv->usergart[fmt].height; 180 int n = priv->usergart[fmt].height;
180 size_t size = PAGE_SIZE * n; 181 size_t size = PAGE_SIZE * n;
181 loff_t off = mmap_offset(obj) + 182 loff_t off = omap_gem_mmap_offset(obj) +
182 (entry->obj_pgoff << PAGE_SHIFT); 183 (entry->obj_pgoff << PAGE_SHIFT);
183 const int m = DIV_ROUND_UP(omap_obj->width << fmt, PAGE_SIZE); 184 const int m = DIV_ROUND_UP(omap_obj->width << fmt, PAGE_SIZE);
184 185
@@ -199,7 +200,7 @@ static void evict_entry(struct drm_gem_object *obj,
199} 200}
200 201
201/* Evict a buffer from usergart, if it is mapped there */ 202/* Evict a buffer from usergart, if it is mapped there */
202static void evict(struct drm_gem_object *obj) 203static void omap_gem_evict(struct drm_gem_object *obj)
203{ 204{
204 struct omap_gem_object *omap_obj = to_omap_bo(obj); 205 struct omap_gem_object *omap_obj = to_omap_bo(obj);
205 struct omap_drm_private *priv = obj->dev->dev_private; 206 struct omap_drm_private *priv = obj->dev->dev_private;
@@ -213,7 +214,7 @@ static void evict(struct drm_gem_object *obj)
213 &priv->usergart[fmt].entry[i]; 214 &priv->usergart[fmt].entry[i];
214 215
215 if (entry->obj == obj) 216 if (entry->obj == obj)
216 evict_entry(obj, fmt, entry); 217 omap_gem_evict_entry(obj, fmt, entry);
217 } 218 }
218 } 219 }
219} 220}
@@ -222,7 +223,10 @@ static void evict(struct drm_gem_object *obj)
222 * Page Management 223 * Page Management
223 */ 224 */
224 225
225/** ensure backing pages are allocated */ 226/*
227 * Ensure backing pages are allocated. Must be called with the omap_obj.lock
228 * held.
229 */
226static int omap_gem_attach_pages(struct drm_gem_object *obj) 230static int omap_gem_attach_pages(struct drm_gem_object *obj)
227{ 231{
228 struct drm_device *dev = obj->dev; 232 struct drm_device *dev = obj->dev;
@@ -232,7 +236,14 @@ static int omap_gem_attach_pages(struct drm_gem_object *obj)
232 int i, ret; 236 int i, ret;
233 dma_addr_t *addrs; 237 dma_addr_t *addrs;
234 238
235 WARN_ON(omap_obj->pages); 239 lockdep_assert_held(&omap_obj->lock);
240
241 /*
242 * If not using shmem (in which case backing pages don't need to be
243 * allocated) or if pages are already allocated we're done.
244 */
245 if (!(omap_obj->flags & OMAP_BO_MEM_SHMEM) || omap_obj->pages)
246 return 0;
236 247
237 pages = drm_gem_get_pages(obj); 248 pages = drm_gem_get_pages(obj);
238 if (IS_ERR(pages)) { 249 if (IS_ERR(pages)) {
@@ -288,35 +299,15 @@ free_pages:
288 return ret; 299 return ret;
289} 300}
290 301
291/* acquire pages when needed (for example, for DMA where physically 302/* Release backing pages. Must be called with the omap_obj.lock held. */
292 * contiguous buffer is not required
293 */
294static int get_pages(struct drm_gem_object *obj, struct page ***pages)
295{
296 struct omap_gem_object *omap_obj = to_omap_bo(obj);
297 int ret = 0;
298
299 if ((omap_obj->flags & OMAP_BO_MEM_SHMEM) && !omap_obj->pages) {
300 ret = omap_gem_attach_pages(obj);
301 if (ret) {
302 dev_err(obj->dev->dev, "could not attach pages\n");
303 return ret;
304 }
305 }
306
307 /* TODO: even phys-contig.. we should have a list of pages? */
308 *pages = omap_obj->pages;
309
310 return 0;
311}
312
313/** release backing pages */
314static void omap_gem_detach_pages(struct drm_gem_object *obj) 303static void omap_gem_detach_pages(struct drm_gem_object *obj)
315{ 304{
316 struct omap_gem_object *omap_obj = to_omap_bo(obj); 305 struct omap_gem_object *omap_obj = to_omap_bo(obj);
317 unsigned int npages = obj->size >> PAGE_SHIFT; 306 unsigned int npages = obj->size >> PAGE_SHIFT;
318 unsigned int i; 307 unsigned int i;
319 308
309 lockdep_assert_held(&omap_obj->lock);
310
320 for (i = 0; i < npages; i++) { 311 for (i = 0; i < npages; i++) {
321 if (omap_obj->dma_addrs[i]) 312 if (omap_obj->dma_addrs[i])
322 dma_unmap_page(obj->dev->dev, omap_obj->dma_addrs[i], 313 dma_unmap_page(obj->dev->dev, omap_obj->dma_addrs[i],
@@ -336,16 +327,6 @@ u32 omap_gem_flags(struct drm_gem_object *obj)
336 return to_omap_bo(obj)->flags; 327 return to_omap_bo(obj)->flags;
337} 328}
338 329
339u64 omap_gem_mmap_offset(struct drm_gem_object *obj)
340{
341 u64 offset;
342
343 mutex_lock(&obj->dev->struct_mutex);
344 offset = mmap_offset(obj);
345 mutex_unlock(&obj->dev->struct_mutex);
346 return offset;
347}
348
349/** get mmap size */ 330/** get mmap size */
350size_t omap_gem_mmap_size(struct drm_gem_object *obj) 331size_t omap_gem_mmap_size(struct drm_gem_object *obj)
351{ 332{
@@ -371,7 +352,7 @@ size_t omap_gem_mmap_size(struct drm_gem_object *obj)
371 */ 352 */
372 353
373/* Normal handling for the case of faulting in non-tiled buffers */ 354/* Normal handling for the case of faulting in non-tiled buffers */
374static int fault_1d(struct drm_gem_object *obj, 355static vm_fault_t omap_gem_fault_1d(struct drm_gem_object *obj,
375 struct vm_area_struct *vma, struct vm_fault *vmf) 356 struct vm_area_struct *vma, struct vm_fault *vmf)
376{ 357{
377 struct omap_gem_object *omap_obj = to_omap_bo(obj); 358 struct omap_gem_object *omap_obj = to_omap_bo(obj);
@@ -385,18 +366,19 @@ static int fault_1d(struct drm_gem_object *obj,
385 omap_gem_cpu_sync_page(obj, pgoff); 366 omap_gem_cpu_sync_page(obj, pgoff);
386 pfn = page_to_pfn(omap_obj->pages[pgoff]); 367 pfn = page_to_pfn(omap_obj->pages[pgoff]);
387 } else { 368 } else {
388 BUG_ON(!is_contiguous(omap_obj)); 369 BUG_ON(!omap_gem_is_contiguous(omap_obj));
389 pfn = (omap_obj->dma_addr >> PAGE_SHIFT) + pgoff; 370 pfn = (omap_obj->dma_addr >> PAGE_SHIFT) + pgoff;
390 } 371 }
391 372
392 VERB("Inserting %p pfn %lx, pa %lx", (void *)vmf->address, 373 VERB("Inserting %p pfn %lx, pa %lx", (void *)vmf->address,
393 pfn, pfn << PAGE_SHIFT); 374 pfn, pfn << PAGE_SHIFT);
394 375
395 return vm_insert_mixed(vma, vmf->address, __pfn_to_pfn_t(pfn, PFN_DEV)); 376 return vmf_insert_mixed(vma, vmf->address,
377 __pfn_to_pfn_t(pfn, PFN_DEV));
396} 378}
397 379
398/* Special handling for the case of faulting in 2d tiled buffers */ 380/* Special handling for the case of faulting in 2d tiled buffers */
399static int fault_2d(struct drm_gem_object *obj, 381static vm_fault_t omap_gem_fault_2d(struct drm_gem_object *obj,
400 struct vm_area_struct *vma, struct vm_fault *vmf) 382 struct vm_area_struct *vma, struct vm_fault *vmf)
401{ 383{
402 struct omap_gem_object *omap_obj = to_omap_bo(obj); 384 struct omap_gem_object *omap_obj = to_omap_bo(obj);
@@ -407,7 +389,8 @@ static int fault_2d(struct drm_gem_object *obj,
407 unsigned long pfn; 389 unsigned long pfn;
408 pgoff_t pgoff, base_pgoff; 390 pgoff_t pgoff, base_pgoff;
409 unsigned long vaddr; 391 unsigned long vaddr;
410 int i, ret, slots; 392 int i, err, slots;
393 vm_fault_t ret = VM_FAULT_NOPAGE;
411 394
412 /* 395 /*
413 * Note the height of the slot is also equal to the number of pages 396 * Note the height of the slot is also equal to the number of pages
@@ -443,7 +426,7 @@ static int fault_2d(struct drm_gem_object *obj,
443 426
444 /* evict previous buffer using this usergart entry, if any: */ 427 /* evict previous buffer using this usergart entry, if any: */
445 if (entry->obj) 428 if (entry->obj)
446 evict_entry(entry->obj, fmt, entry); 429 omap_gem_evict_entry(entry->obj, fmt, entry);
447 430
448 entry->obj = obj; 431 entry->obj = obj;
449 entry->obj_pgoff = base_pgoff; 432 entry->obj_pgoff = base_pgoff;
@@ -473,9 +456,10 @@ static int fault_2d(struct drm_gem_object *obj,
473 memset(pages + slots, 0, 456 memset(pages + slots, 0,
474 sizeof(struct page *) * (n - slots)); 457 sizeof(struct page *) * (n - slots));
475 458
476 ret = tiler_pin(entry->block, pages, ARRAY_SIZE(pages), 0, true); 459 err = tiler_pin(entry->block, pages, ARRAY_SIZE(pages), 0, true);
477 if (ret) { 460 if (err) {
478 dev_err(obj->dev->dev, "failed to pin: %d\n", ret); 461 ret = vmf_error(err);
462 dev_err(obj->dev->dev, "failed to pin: %d\n", err);
479 return ret; 463 return ret;
480 } 464 }
481 465
@@ -485,7 +469,10 @@ static int fault_2d(struct drm_gem_object *obj,
485 pfn, pfn << PAGE_SHIFT); 469 pfn, pfn << PAGE_SHIFT);
486 470
487 for (i = n; i > 0; i--) { 471 for (i = n; i > 0; i--) {
488 vm_insert_mixed(vma, vaddr, __pfn_to_pfn_t(pfn, PFN_DEV)); 472 ret = vmf_insert_mixed(vma,
473 vaddr, __pfn_to_pfn_t(pfn, PFN_DEV));
474 if (ret & VM_FAULT_ERROR)
475 break;
489 pfn += priv->usergart[fmt].stride_pfn; 476 pfn += priv->usergart[fmt].stride_pfn;
490 vaddr += PAGE_SIZE * m; 477 vaddr += PAGE_SIZE * m;
491 } 478 }
@@ -494,7 +481,7 @@ static int fault_2d(struct drm_gem_object *obj,
494 priv->usergart[fmt].last = (priv->usergart[fmt].last + 1) 481 priv->usergart[fmt].last = (priv->usergart[fmt].last + 1)
495 % NUM_USERGART_ENTRIES; 482 % NUM_USERGART_ENTRIES;
496 483
497 return 0; 484 return ret;
498} 485}
499 486
500/** 487/**
@@ -509,24 +496,25 @@ static int fault_2d(struct drm_gem_object *obj,
509 * vma->vm_private_data points to the GEM object that is backing this 496 * vma->vm_private_data points to the GEM object that is backing this
510 * mapping. 497 * mapping.
511 */ 498 */
512int omap_gem_fault(struct vm_fault *vmf) 499vm_fault_t omap_gem_fault(struct vm_fault *vmf)
513{ 500{
514 struct vm_area_struct *vma = vmf->vma; 501 struct vm_area_struct *vma = vmf->vma;
515 struct drm_gem_object *obj = vma->vm_private_data; 502 struct drm_gem_object *obj = vma->vm_private_data;
516 struct omap_gem_object *omap_obj = to_omap_bo(obj); 503 struct omap_gem_object *omap_obj = to_omap_bo(obj);
517 struct drm_device *dev = obj->dev; 504 int err;
518 struct page **pages; 505 vm_fault_t ret;
519 int ret;
520 506
521 /* Make sure we don't parallel update on a fault, nor move or remove 507 /* Make sure we don't parallel update on a fault, nor move or remove
522 * something from beneath our feet 508 * something from beneath our feet
523 */ 509 */
524 mutex_lock(&dev->struct_mutex); 510 mutex_lock(&omap_obj->lock);
525 511
526 /* if a shmem backed object, make sure we have pages attached now */ 512 /* if a shmem backed object, make sure we have pages attached now */
527 ret = get_pages(obj, &pages); 513 err = omap_gem_attach_pages(obj);
528 if (ret) 514 if (err) {
515 ret = vmf_error(err);
529 goto fail; 516 goto fail;
517 }
530 518
531 /* where should we do corresponding put_pages().. we are mapping 519 /* where should we do corresponding put_pages().. we are mapping
532 * the original page, rather than thru a GART, so we can't rely 520 * the original page, rather than thru a GART, so we can't rely
@@ -535,28 +523,14 @@ int omap_gem_fault(struct vm_fault *vmf)
535 */ 523 */
536 524
537 if (omap_obj->flags & OMAP_BO_TILED) 525 if (omap_obj->flags & OMAP_BO_TILED)
538 ret = fault_2d(obj, vma, vmf); 526 ret = omap_gem_fault_2d(obj, vma, vmf);
539 else 527 else
540 ret = fault_1d(obj, vma, vmf); 528 ret = omap_gem_fault_1d(obj, vma, vmf);
541 529
542 530
543fail: 531fail:
544 mutex_unlock(&dev->struct_mutex); 532 mutex_unlock(&omap_obj->lock);
545 switch (ret) { 533 return ret;
546 case 0:
547 case -ERESTARTSYS:
548 case -EINTR:
549 case -EBUSY:
550 /*
551 * EBUSY is ok: this just means that another thread
552 * already did the job.
553 */
554 return VM_FAULT_NOPAGE;
555 case -ENOMEM:
556 return VM_FAULT_OOM;
557 default:
558 return VM_FAULT_SIGBUS;
559 }
560} 534}
561 535
562/** We override mainly to fix up some of the vm mapping flags.. */ 536/** We override mainly to fix up some of the vm mapping flags.. */
@@ -689,21 +663,22 @@ int omap_gem_roll(struct drm_gem_object *obj, u32 roll)
689 663
690 omap_obj->roll = roll; 664 omap_obj->roll = roll;
691 665
692 mutex_lock(&obj->dev->struct_mutex); 666 mutex_lock(&omap_obj->lock);
693 667
694 /* if we aren't mapped yet, we don't need to do anything */ 668 /* if we aren't mapped yet, we don't need to do anything */
695 if (omap_obj->block) { 669 if (omap_obj->block) {
696 struct page **pages; 670 ret = omap_gem_attach_pages(obj);
697 ret = get_pages(obj, &pages);
698 if (ret) 671 if (ret)
699 goto fail; 672 goto fail;
700 ret = tiler_pin(omap_obj->block, pages, npages, roll, true); 673
674 ret = tiler_pin(omap_obj->block, omap_obj->pages, npages,
675 roll, true);
701 if (ret) 676 if (ret)
702 dev_err(obj->dev->dev, "could not repin: %d\n", ret); 677 dev_err(obj->dev->dev, "could not repin: %d\n", ret);
703 } 678 }
704 679
705fail: 680fail:
706 mutex_unlock(&obj->dev->struct_mutex); 681 mutex_unlock(&omap_obj->lock);
707 682
708 return ret; 683 return ret;
709} 684}
@@ -722,7 +697,7 @@ fail:
722 * the omap_obj->dma_addrs[i] is set to the DMA address, and the page is 697 * the omap_obj->dma_addrs[i] is set to the DMA address, and the page is
723 * unmapped from the CPU. 698 * unmapped from the CPU.
724 */ 699 */
725static inline bool is_cached_coherent(struct drm_gem_object *obj) 700static inline bool omap_gem_is_cached_coherent(struct drm_gem_object *obj)
726{ 701{
727 struct omap_gem_object *omap_obj = to_omap_bo(obj); 702 struct omap_gem_object *omap_obj = to_omap_bo(obj);
728 703
@@ -738,7 +713,7 @@ void omap_gem_cpu_sync_page(struct drm_gem_object *obj, int pgoff)
738 struct drm_device *dev = obj->dev; 713 struct drm_device *dev = obj->dev;
739 struct omap_gem_object *omap_obj = to_omap_bo(obj); 714 struct omap_gem_object *omap_obj = to_omap_bo(obj);
740 715
741 if (is_cached_coherent(obj)) 716 if (omap_gem_is_cached_coherent(obj))
742 return; 717 return;
743 718
744 if (omap_obj->dma_addrs[pgoff]) { 719 if (omap_obj->dma_addrs[pgoff]) {
@@ -758,7 +733,7 @@ void omap_gem_dma_sync_buffer(struct drm_gem_object *obj,
758 struct page **pages = omap_obj->pages; 733 struct page **pages = omap_obj->pages;
759 bool dirty = false; 734 bool dirty = false;
760 735
761 if (is_cached_coherent(obj)) 736 if (omap_gem_is_cached_coherent(obj))
762 return; 737 return;
763 738
764 for (i = 0; i < npages; i++) { 739 for (i = 0; i < npages; i++) {
@@ -804,18 +779,17 @@ int omap_gem_pin(struct drm_gem_object *obj, dma_addr_t *dma_addr)
804 struct omap_gem_object *omap_obj = to_omap_bo(obj); 779 struct omap_gem_object *omap_obj = to_omap_bo(obj);
805 int ret = 0; 780 int ret = 0;
806 781
807 mutex_lock(&obj->dev->struct_mutex); 782 mutex_lock(&omap_obj->lock);
808 783
809 if (!is_contiguous(omap_obj) && priv->has_dmm) { 784 if (!omap_gem_is_contiguous(omap_obj) && priv->has_dmm) {
810 if (omap_obj->dma_addr_cnt == 0) { 785 if (omap_obj->dma_addr_cnt == 0) {
811 struct page **pages;
812 u32 npages = obj->size >> PAGE_SHIFT; 786 u32 npages = obj->size >> PAGE_SHIFT;
813 enum tiler_fmt fmt = gem2fmt(omap_obj->flags); 787 enum tiler_fmt fmt = gem2fmt(omap_obj->flags);
814 struct tiler_block *block; 788 struct tiler_block *block;
815 789
816 BUG_ON(omap_obj->block); 790 BUG_ON(omap_obj->block);
817 791
818 ret = get_pages(obj, &pages); 792 ret = omap_gem_attach_pages(obj);
819 if (ret) 793 if (ret)
820 goto fail; 794 goto fail;
821 795
@@ -835,7 +809,7 @@ int omap_gem_pin(struct drm_gem_object *obj, dma_addr_t *dma_addr)
835 } 809 }
836 810
837 /* TODO: enable async refill.. */ 811 /* TODO: enable async refill.. */
838 ret = tiler_pin(block, pages, npages, 812 ret = tiler_pin(block, omap_obj->pages, npages,
839 omap_obj->roll, true); 813 omap_obj->roll, true);
840 if (ret) { 814 if (ret) {
841 tiler_release(block); 815 tiler_release(block);
@@ -853,7 +827,7 @@ int omap_gem_pin(struct drm_gem_object *obj, dma_addr_t *dma_addr)
853 omap_obj->dma_addr_cnt++; 827 omap_obj->dma_addr_cnt++;
854 828
855 *dma_addr = omap_obj->dma_addr; 829 *dma_addr = omap_obj->dma_addr;
856 } else if (is_contiguous(omap_obj)) { 830 } else if (omap_gem_is_contiguous(omap_obj)) {
857 *dma_addr = omap_obj->dma_addr; 831 *dma_addr = omap_obj->dma_addr;
858 } else { 832 } else {
859 ret = -EINVAL; 833 ret = -EINVAL;
@@ -861,7 +835,7 @@ int omap_gem_pin(struct drm_gem_object *obj, dma_addr_t *dma_addr)
861 } 835 }
862 836
863fail: 837fail:
864 mutex_unlock(&obj->dev->struct_mutex); 838 mutex_unlock(&omap_obj->lock);
865 839
866 return ret; 840 return ret;
867} 841}
@@ -879,7 +853,8 @@ void omap_gem_unpin(struct drm_gem_object *obj)
879 struct omap_gem_object *omap_obj = to_omap_bo(obj); 853 struct omap_gem_object *omap_obj = to_omap_bo(obj);
880 int ret; 854 int ret;
881 855
882 mutex_lock(&obj->dev->struct_mutex); 856 mutex_lock(&omap_obj->lock);
857
883 if (omap_obj->dma_addr_cnt > 0) { 858 if (omap_obj->dma_addr_cnt > 0) {
884 omap_obj->dma_addr_cnt--; 859 omap_obj->dma_addr_cnt--;
885 if (omap_obj->dma_addr_cnt == 0) { 860 if (omap_obj->dma_addr_cnt == 0) {
@@ -898,7 +873,7 @@ void omap_gem_unpin(struct drm_gem_object *obj)
898 } 873 }
899 } 874 }
900 875
901 mutex_unlock(&obj->dev->struct_mutex); 876 mutex_unlock(&omap_obj->lock);
902} 877}
903 878
904/* Get rotated scanout address (only valid if already pinned), at the 879/* Get rotated scanout address (only valid if already pinned), at the
@@ -911,13 +886,16 @@ int omap_gem_rotated_dma_addr(struct drm_gem_object *obj, u32 orient,
911 struct omap_gem_object *omap_obj = to_omap_bo(obj); 886 struct omap_gem_object *omap_obj = to_omap_bo(obj);
912 int ret = -EINVAL; 887 int ret = -EINVAL;
913 888
914 mutex_lock(&obj->dev->struct_mutex); 889 mutex_lock(&omap_obj->lock);
890
915 if ((omap_obj->dma_addr_cnt > 0) && omap_obj->block && 891 if ((omap_obj->dma_addr_cnt > 0) && omap_obj->block &&
916 (omap_obj->flags & OMAP_BO_TILED)) { 892 (omap_obj->flags & OMAP_BO_TILED)) {
917 *dma_addr = tiler_tsptr(omap_obj->block, orient, x, y); 893 *dma_addr = tiler_tsptr(omap_obj->block, orient, x, y);
918 ret = 0; 894 ret = 0;
919 } 895 }
920 mutex_unlock(&obj->dev->struct_mutex); 896
897 mutex_unlock(&omap_obj->lock);
898
921 return ret; 899 return ret;
922} 900}
923 901
@@ -944,17 +922,27 @@ int omap_gem_tiled_stride(struct drm_gem_object *obj, u32 orient)
944int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages, 922int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages,
945 bool remap) 923 bool remap)
946{ 924{
947 int ret; 925 struct omap_gem_object *omap_obj = to_omap_bo(obj);
948 if (!remap) { 926 int ret = 0;
949 struct omap_gem_object *omap_obj = to_omap_bo(obj); 927
950 if (!omap_obj->pages) 928 mutex_lock(&omap_obj->lock);
951 return -ENOMEM; 929
952 *pages = omap_obj->pages; 930 if (remap) {
953 return 0; 931 ret = omap_gem_attach_pages(obj);
932 if (ret)
933 goto unlock;
954 } 934 }
955 mutex_lock(&obj->dev->struct_mutex); 935
956 ret = get_pages(obj, pages); 936 if (!omap_obj->pages) {
957 mutex_unlock(&obj->dev->struct_mutex); 937 ret = -ENOMEM;
938 goto unlock;
939 }
940
941 *pages = omap_obj->pages;
942
943unlock:
944 mutex_unlock(&omap_obj->lock);
945
958 return ret; 946 return ret;
959} 947}
960 948
@@ -969,23 +957,34 @@ int omap_gem_put_pages(struct drm_gem_object *obj)
969} 957}
970 958
971#ifdef CONFIG_DRM_FBDEV_EMULATION 959#ifdef CONFIG_DRM_FBDEV_EMULATION
972/* Get kernel virtual address for CPU access.. this more or less only 960/*
973 * exists for omap_fbdev. This should be called with struct_mutex 961 * Get kernel virtual address for CPU access.. this more or less only
974 * held. 962 * exists for omap_fbdev.
975 */ 963 */
976void *omap_gem_vaddr(struct drm_gem_object *obj) 964void *omap_gem_vaddr(struct drm_gem_object *obj)
977{ 965{
978 struct omap_gem_object *omap_obj = to_omap_bo(obj); 966 struct omap_gem_object *omap_obj = to_omap_bo(obj);
979 WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex)); 967 void *vaddr;
968 int ret;
969
970 mutex_lock(&omap_obj->lock);
971
980 if (!omap_obj->vaddr) { 972 if (!omap_obj->vaddr) {
981 struct page **pages; 973 ret = omap_gem_attach_pages(obj);
982 int ret = get_pages(obj, &pages); 974 if (ret) {
983 if (ret) 975 vaddr = ERR_PTR(ret);
984 return ERR_PTR(ret); 976 goto unlock;
985 omap_obj->vaddr = vmap(pages, obj->size >> PAGE_SHIFT, 977 }
978
979 omap_obj->vaddr = vmap(omap_obj->pages, obj->size >> PAGE_SHIFT,
986 VM_MAP, pgprot_writecombine(PAGE_KERNEL)); 980 VM_MAP, pgprot_writecombine(PAGE_KERNEL));
987 } 981 }
988 return omap_obj->vaddr; 982
983 vaddr = omap_obj->vaddr;
984
985unlock:
986 mutex_unlock(&omap_obj->lock);
987 return vaddr;
989} 988}
990#endif 989#endif
991 990
@@ -1001,6 +1000,7 @@ int omap_gem_resume(struct drm_device *dev)
1001 struct omap_gem_object *omap_obj; 1000 struct omap_gem_object *omap_obj;
1002 int ret = 0; 1001 int ret = 0;
1003 1002
1003 mutex_lock(&priv->list_lock);
1004 list_for_each_entry(omap_obj, &priv->obj_list, mm_list) { 1004 list_for_each_entry(omap_obj, &priv->obj_list, mm_list) {
1005 if (omap_obj->block) { 1005 if (omap_obj->block) {
1006 struct drm_gem_object *obj = &omap_obj->base; 1006 struct drm_gem_object *obj = &omap_obj->base;
@@ -1012,12 +1012,14 @@ int omap_gem_resume(struct drm_device *dev)
1012 omap_obj->roll, true); 1012 omap_obj->roll, true);
1013 if (ret) { 1013 if (ret) {
1014 dev_err(dev->dev, "could not repin: %d\n", ret); 1014 dev_err(dev->dev, "could not repin: %d\n", ret);
1015 return ret; 1015 goto done;
1016 } 1016 }
1017 } 1017 }
1018 } 1018 }
1019 1019
1020 return 0; 1020done:
1021 mutex_unlock(&priv->list_lock);
1022 return ret;
1021} 1023}
1022#endif 1024#endif
1023 1025
@@ -1033,6 +1035,8 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
1033 1035
1034 off = drm_vma_node_start(&obj->vma_node); 1036 off = drm_vma_node_start(&obj->vma_node);
1035 1037
1038 mutex_lock(&omap_obj->lock);
1039
1036 seq_printf(m, "%08x: %2d (%2d) %08llx %pad (%2d) %p %4d", 1040 seq_printf(m, "%08x: %2d (%2d) %08llx %pad (%2d) %p %4d",
1037 omap_obj->flags, obj->name, kref_read(&obj->refcount), 1041 omap_obj->flags, obj->name, kref_read(&obj->refcount),
1038 off, &omap_obj->dma_addr, omap_obj->dma_addr_cnt, 1042 off, &omap_obj->dma_addr, omap_obj->dma_addr_cnt,
@@ -1050,6 +1054,8 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
1050 seq_printf(m, " %zu", obj->size); 1054 seq_printf(m, " %zu", obj->size);
1051 } 1055 }
1052 1056
1057 mutex_unlock(&omap_obj->lock);
1058
1053 seq_printf(m, "\n"); 1059 seq_printf(m, "\n");
1054} 1060}
1055 1061
@@ -1081,17 +1087,21 @@ void omap_gem_free_object(struct drm_gem_object *obj)
1081 struct omap_drm_private *priv = dev->dev_private; 1087 struct omap_drm_private *priv = dev->dev_private;
1082 struct omap_gem_object *omap_obj = to_omap_bo(obj); 1088 struct omap_gem_object *omap_obj = to_omap_bo(obj);
1083 1089
1084 evict(obj); 1090 omap_gem_evict(obj);
1085
1086 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
1087 1091
1088 spin_lock(&priv->list_lock); 1092 mutex_lock(&priv->list_lock);
1089 list_del(&omap_obj->mm_list); 1093 list_del(&omap_obj->mm_list);
1090 spin_unlock(&priv->list_lock); 1094 mutex_unlock(&priv->list_lock);
1091 1095
1092 /* this means the object is still pinned.. which really should 1096 /*
1093 * not happen. I think.. 1097 * We own the sole reference to the object at this point, but to keep
1098 * lockdep happy, we must still take the omap_obj_lock to call
1099 * omap_gem_detach_pages(). This should hardly make any difference as
1100 * there can't be any lock contention.
1094 */ 1101 */
1102 mutex_lock(&omap_obj->lock);
1103
1104 /* The object should not be pinned. */
1095 WARN_ON(omap_obj->dma_addr_cnt > 0); 1105 WARN_ON(omap_obj->dma_addr_cnt > 0);
1096 1106
1097 if (omap_obj->pages) { 1107 if (omap_obj->pages) {
@@ -1110,8 +1120,12 @@ void omap_gem_free_object(struct drm_gem_object *obj)
1110 drm_prime_gem_destroy(obj, omap_obj->sgt); 1120 drm_prime_gem_destroy(obj, omap_obj->sgt);
1111 } 1121 }
1112 1122
1123 mutex_unlock(&omap_obj->lock);
1124
1113 drm_gem_object_release(obj); 1125 drm_gem_object_release(obj);
1114 1126
1127 mutex_destroy(&omap_obj->lock);
1128
1115 kfree(omap_obj); 1129 kfree(omap_obj);
1116} 1130}
1117 1131
@@ -1167,6 +1181,7 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
1167 1181
1168 obj = &omap_obj->base; 1182 obj = &omap_obj->base;
1169 omap_obj->flags = flags; 1183 omap_obj->flags = flags;
1184 mutex_init(&omap_obj->lock);
1170 1185
1171 if (flags & OMAP_BO_TILED) { 1186 if (flags & OMAP_BO_TILED) {
1172 /* 1187 /*
@@ -1206,9 +1221,9 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
1206 goto err_release; 1221 goto err_release;
1207 } 1222 }
1208 1223
1209 spin_lock(&priv->list_lock); 1224 mutex_lock(&priv->list_lock);
1210 list_add(&omap_obj->mm_list, &priv->obj_list); 1225 list_add(&omap_obj->mm_list, &priv->obj_list);
1211 spin_unlock(&priv->list_lock); 1226 mutex_unlock(&priv->list_lock);
1212 1227
1213 return obj; 1228 return obj;
1214 1229
@@ -1231,16 +1246,15 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
1231 if (sgt->orig_nents != 1 && !priv->has_dmm) 1246 if (sgt->orig_nents != 1 && !priv->has_dmm)
1232 return ERR_PTR(-EINVAL); 1247 return ERR_PTR(-EINVAL);
1233 1248
1234 mutex_lock(&dev->struct_mutex);
1235
1236 gsize.bytes = PAGE_ALIGN(size); 1249 gsize.bytes = PAGE_ALIGN(size);
1237 obj = omap_gem_new(dev, gsize, OMAP_BO_MEM_DMABUF | OMAP_BO_WC); 1250 obj = omap_gem_new(dev, gsize, OMAP_BO_MEM_DMABUF | OMAP_BO_WC);
1238 if (!obj) { 1251 if (!obj)
1239 obj = ERR_PTR(-ENOMEM); 1252 return ERR_PTR(-ENOMEM);
1240 goto done;
1241 }
1242 1253
1243 omap_obj = to_omap_bo(obj); 1254 omap_obj = to_omap_bo(obj);
1255
1256 mutex_lock(&omap_obj->lock);
1257
1244 omap_obj->sgt = sgt; 1258 omap_obj->sgt = sgt;
1245 1259
1246 if (sgt->orig_nents == 1) { 1260 if (sgt->orig_nents == 1) {
@@ -1276,7 +1290,7 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
1276 } 1290 }
1277 1291
1278done: 1292done:
1279 mutex_unlock(&dev->struct_mutex); 1293 mutex_unlock(&omap_obj->lock);
1280 return obj; 1294 return obj;
1281} 1295}
1282 1296
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.h b/drivers/gpu/drm/omapdrm/omap_gem.h
index a78bde05193a..c1c45fbde155 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.h
+++ b/drivers/gpu/drm/omapdrm/omap_gem.h
@@ -21,6 +21,7 @@
21#define __OMAPDRM_GEM_H__ 21#define __OMAPDRM_GEM_H__
22 22
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/mm_types.h>
24 25
25enum dma_data_direction; 26enum dma_data_direction;
26 27
@@ -80,7 +81,7 @@ struct dma_buf *omap_gem_prime_export(struct drm_device *dev,
80struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev, 81struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
81 struct dma_buf *buffer); 82 struct dma_buf *buffer);
82 83
83int omap_gem_fault(struct vm_fault *vmf); 84vm_fault_t omap_gem_fault(struct vm_fault *vmf);
84int omap_gem_roll(struct drm_gem_object *obj, u32 roll); 85int omap_gem_roll(struct drm_gem_object *obj, u32 roll);
85void omap_gem_cpu_sync_page(struct drm_gem_object *obj, int pgoff); 86void omap_gem_cpu_sync_page(struct drm_gem_object *obj, int pgoff);
86void omap_gem_dma_sync_buffer(struct drm_gem_object *obj, 87void omap_gem_dma_sync_buffer(struct drm_gem_object *obj,