summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/msm_fbdev.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-08-05 09:22:27 +1000
committerDave Airlie <airlied@redhat.com>2014-08-05 09:22:27 +1000
commiteceb55a0ecd584ac5bebf667ffd8e859f261d0c0 (patch)
tree6b990d26748e5fc85308c563bc8ec736d9042f72 /drivers/gpu/drm/msm/msm_fbdev.c
parent5d42f82a9b8c5168d75cf59307cd271feca94464 (diff)
parenta2fe6cdc03d7a9b0d048a7f32f9d8827e06c67fa (diff)
Merge branch 'msm-next' of git://people.freedesktop.org/~robclark/linux into drm-next
This time around we have a mix of new hw enablement (mdp5 v1.3 / apq8084), plus devicetree and various upstream changes (mostly adapting to CCF vs downstream clk driver differences) for mdp4 / apq8064. With these drm/msm patches plus a few other small patchsets (from linaro qcom integration branch.. mostly stuff queued up for 3.17) we have the inforce ifc6410 board working, with gpu. Much nicer to work with than ancient vendor android branch :-) * 'msm-next' of git://people.freedesktop.org/~robclark/linux: drm/msm/hdmi: fix HDMI_MUX_EN gpio request typo drm/msm/hdmi: enable lpm-mux if it is present drm/msm/mdp5: add support for MDP5 v1.3 drm/msm: fix potential deadlock in gpu init drm/msm: use upstream iommu drm/msm: no mmu is only error if not using vram carveout drm/msm: fix BUG_ON() in error cleanup path drm/msm/mdp4: add mdp axi clk drm/msm: hdmi phy 8960 phy pll drm/msm: update generated headers drm/msm: DT support for 8960/8064 (v3) drm/msm: Implement msm drm fb_mmap callback function drm/msm: activate iommu support drm/msm: fix double struct_mutex acquire
Diffstat (limited to 'drivers/gpu/drm/msm/msm_fbdev.c')
-rw-r--r--drivers/gpu/drm/msm/msm_fbdev.c45
1 files changed, 42 insertions, 3 deletions
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index c437065933e..9c5221ce391 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -19,6 +19,11 @@
#include "drm_crtc.h"
#include "drm_fb_helper.h"
+#include "msm_gem.h"
+
+extern int msm_gem_mmap_obj(struct drm_gem_object *obj,
+ struct vm_area_struct *vma);
+static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma);
/*
* fbdev funcs, to implement legacy fbdev interface on top of drm driver
@@ -43,6 +48,7 @@ static struct fb_ops msm_fb_ops = {
.fb_fillrect = sys_fillrect,
.fb_copyarea = sys_copyarea,
.fb_imageblit = sys_imageblit,
+ .fb_mmap = msm_fbdev_mmap,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
@@ -51,6 +57,31 @@ static struct fb_ops msm_fb_ops = {
.fb_setcmap = drm_fb_helper_setcmap,
};
+static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;
+ struct msm_fbdev *fbdev = to_msm_fbdev(helper);
+ struct drm_gem_object *drm_obj = fbdev->bo;
+ struct drm_device *dev = helper->dev;
+ int ret = 0;
+
+ if (drm_device_is_unplugged(dev))
+ return -ENODEV;
+
+ mutex_lock(&dev->struct_mutex);
+
+ ret = drm_gem_mmap_obj(drm_obj, drm_obj->size, vma);
+
+ mutex_unlock(&dev->struct_mutex);
+
+ if (ret) {
+ pr_err("%s:drm_gem_mmap_obj fail\n", __func__);
+ return ret;
+ }
+
+ return msm_gem_mmap_obj(drm_obj, vma);
+}
+
static int msm_fbdev_create(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
@@ -104,8 +135,16 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
mutex_lock(&dev->struct_mutex);
- /* TODO implement our own fb_mmap so we don't need this: */
- msm_gem_get_iova_locked(fbdev->bo, 0, &paddr);
+ /*
+ * NOTE: if we can be guaranteed to be able to map buffer
+ * in panic (ie. lock-safe, etc) we could avoid pinning the
+ * buffer now:
+ */
+ ret = msm_gem_get_iova_locked(fbdev->bo, 0, &paddr);
+ if (ret) {
+ dev_err(dev->dev, "failed to get buffer obj iova: %d\n", ret);
+ goto fail;
+ }
fbi = framebuffer_alloc(0, dev->dev);
if (!fbi) {
@@ -189,7 +228,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
struct msm_drm_private *priv = dev->dev_private;
struct msm_fbdev *fbdev = NULL;
struct drm_fb_helper *helper;
- int ret = 0;
+ int ret;
fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
if (!fbdev)