diff options
author | Dave Airlie <airlied@redhat.com> | 2016-09-28 11:09:59 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-09-28 11:09:59 +1000 |
commit | f8049dd865a1de8b494c16a4cd18ee15fa896810 (patch) | |
tree | 37b874acba1392e97864dc24692736210543a4e4 /drivers/gpu/drm/msm | |
parent | 3f346d5dcb591c2a5a26653d093af710cf2e5a31 (diff) | |
parent | 7a3bcc0a8e2ad5fa7fe6d627e01c66b3488149b7 (diff) |
Merge branch 'msm-next' of git://people.freedesktop.org/~robclark/linux into drm-next
A bit smaller pull-req this time around. Some continued DT binding
cleanup to get the corresponding dts bits merged upstream (through
other trees). And explicit fence-fd support for submit ioctl.
* 'msm-next' of git://people.freedesktop.org/~robclark/linux:
drm/msm: bump kernel api version for explicit fencing
drm/msm: submit support for out-fences
drm/msm: move fence allocation out of msm_gpu_submit()
drm/msm: submit support for in-fences
drm/msm: extend the submit ioctl to pass in flags
drm/msm/mdp5: Set rotation property initial value to DRM_ROTATE_0 insted of 0
drm/msm/hdmi: don't print error when adding i2c adapter fails
drm/msm/mdp4: mark symbols static where possible
drm/msm: Remove call to reservation_object_test_signaled_rcu before wait
drm/msm/hdmi: Clean up HDMI gpio DT bindings
drm/msm/mdp4: Fix issue with LCDC/LVDS port parsing
Diffstat (limited to 'drivers/gpu/drm/msm')
-rw-r--r-- | drivers/gpu/drm/msm/Kconfig | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/hdmi/hdmi.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/hdmi/hdmi_i2c.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_gem.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_gem_submit.c | 73 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_gpu.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_gpu.h | 2 |
12 files changed, 120 insertions, 51 deletions
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 7c7a0314a756..d96b2b6898a3 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -11,6 +11,7 @@ config DRM_MSM select TMPFS select QCOM_SCM select SND_SOC_HDMI_CODEC if SND_SOC + select SYNC_FILE default y help DRM/KMS driver for MSM/snapdragon. diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 973720792236..a968cad509c2 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -422,12 +422,29 @@ static const struct { static int msm_hdmi_get_gpio(struct device_node *of_node, const char *name) { - int gpio = of_get_named_gpio(of_node, name, 0); + int gpio; + + /* try with the gpio names as in the table (downstream bindings) */ + gpio = of_get_named_gpio(of_node, name, 0); if (gpio < 0) { char name2[32]; - snprintf(name2, sizeof(name2), "%s-gpio", name); + + /* try with the gpio names as in the upstream bindings */ + snprintf(name2, sizeof(name2), "%s-gpios", name); gpio = of_get_named_gpio(of_node, name2, 0); if (gpio < 0) { + char name3[32]; + + /* + * try again after stripping out the "qcom,hdmi-tx" + * prefix. This is mainly to match "hpd-gpios" used + * in the upstream bindings + */ + if (sscanf(name2, "qcom,hdmi-tx-%s", name3)) + gpio = of_get_named_gpio(of_node, name3, 0); + } + + if (gpio < 0) { DBG("failed to get gpio: %s (%d)", name, gpio); gpio = -1; } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c index de9007e72f4e..73e20219d431 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c @@ -243,7 +243,6 @@ void msm_hdmi_i2c_destroy(struct i2c_adapter *i2c) struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi) { - struct drm_device *dev = hdmi->dev; struct hdmi_i2c_adapter *hdmi_i2c; struct i2c_adapter *i2c = NULL; int ret; @@ -267,10 +266,8 @@ struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi) i2c->algo = &msm_hdmi_i2c_algorithm; ret = i2c_add_adapter(i2c); - if (ret) { - dev_err(dev->dev, "failed to register hdmi i2c: %d\n", ret); + if (ret) goto fail; - } return i2c; diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index 7b39e89fbc2b..571a91ee9607 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c @@ -228,18 +228,21 @@ static struct device_node *mdp4_detect_lcdc_panel(struct drm_device *dev) struct device_node *endpoint, *panel_node; struct device_node *np = dev->dev->of_node; - endpoint = of_graph_get_next_endpoint(np, NULL); + /* + * LVDS/LCDC is the first port described in the list of ports in the + * MDP4 DT node. + */ + endpoint = of_graph_get_endpoint_by_regs(np, 0, -1); if (!endpoint) { - DBG("no endpoint in MDP4 to fetch LVDS panel\n"); + DBG("no LVDS remote endpoint\n"); return NULL; } - /* don't proceed if we have an endpoint but no panel_node tied to it */ panel_node = of_graph_get_remote_port_parent(endpoint); if (!panel_node) { - dev_err(dev->dev, "no valid panel node\n"); + DBG("no valid panel node in LVDS endpoint\n"); of_node_put(endpoint); - return ERR_PTR(-ENODEV); + return NULL; } of_node_put(endpoint); @@ -262,14 +265,12 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, switch (intf_type) { case DRM_MODE_ENCODER_LVDS: /* - * bail out early if: - * - there is no panel node (no need to initialize lcdc - * encoder and lvds connector), or - * - panel node is a bad pointer + * bail out early if there is no panel node (no need to + * initialize LCDC encoder and LVDS connector) */ panel_node = mdp4_detect_lcdc_panel(dev); - if (IS_ERR_OR_NULL(panel_node)) - return PTR_ERR(panel_node); + if (!panel_node) + return 0; encoder = mdp4_lcdc_encoder_init(dev, panel_node); if (IS_ERR(encoder)) { diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c index bc3d8e719c6c..a06b064f86c1 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c @@ -93,7 +93,7 @@ static const struct drm_encoder_funcs mdp4_lcdc_encoder_funcs = { }; /* this should probably be a helper: */ -struct drm_connector *get_connector(struct drm_encoder *encoder) +static struct drm_connector *get_connector(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct drm_connector *connector; diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index 7c9626d92019..3903dbcda763 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c @@ -81,7 +81,7 @@ static void mdp4_plane_install_properties(struct drm_plane *plane, // XXX } -int mdp4_plane_set_property(struct drm_plane *plane, +static int mdp4_plane_set_property(struct drm_plane *plane, struct drm_property *property, uint64_t val) { // XXX diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index ba8f43278a44..951c002b05df 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -78,12 +78,12 @@ static void mdp5_plane_install_rotation_property(struct drm_device *dev, if (!dev->mode_config.rotation_property) dev->mode_config.rotation_property = drm_mode_create_rotation_property(dev, - DRM_REFLECT_X | DRM_REFLECT_Y); + DRM_ROTATE_0 | DRM_REFLECT_X | DRM_REFLECT_Y); if (dev->mode_config.rotation_property) drm_object_attach_property(&plane->base, dev->mode_config.rotation_property, - 0); + DRM_ROTATE_0); } /* helper to install properties which are common to planes and crtcs */ diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 042bde48200d..fb5c0b0a7594 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -26,9 +26,10 @@ * MSM driver version: * - 1.0.0 - initial interface * - 1.1.0 - adds madvise, and support for submits with > 4 cmd buffers + * - 1.2.0 - adds explicit fence support for submit ioctl */ #define MSM_VERSION_MAJOR 1 -#define MSM_VERSION_MINOR 1 +#define MSM_VERSION_MINOR 2 #define MSM_VERSION_PATCHLEVEL 0 static void msm_fb_output_poll_changed(struct drm_device *dev) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 6cd4af443139..0a9b5580b2e9 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -584,18 +584,16 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, ktime_t *timeout) { struct msm_gem_object *msm_obj = to_msm_bo(obj); bool write = !!(op & MSM_PREP_WRITE); - - if (op & MSM_PREP_NOSYNC) { - if (!reservation_object_test_signaled_rcu(msm_obj->resv, write)) - return -EBUSY; - } else { - int ret; - - ret = reservation_object_wait_timeout_rcu(msm_obj->resv, write, - true, timeout_to_jiffies(timeout)); - if (ret <= 0) - return ret == 0 ? -ETIMEDOUT : ret; - } + unsigned long remain = + op & MSM_PREP_NOSYNC ? 0 : timeout_to_jiffies(timeout); + long ret; + + ret = reservation_object_wait_timeout_rcu(msm_obj->resv, write, + true, remain); + if (ret == 0) + return remain == 0 ? -EBUSY : -ETIMEDOUT; + else if (ret < 0) + return ret; /* TODO cache maintenance */ diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 9766f9ae4b7d..3ac14cd1e5b9 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -15,6 +15,8 @@ * this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/sync_file.h> + #include "msm_drv.h" #include "msm_gpu.h" #include "msm_gem.h" @@ -361,6 +363,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct msm_file_private *ctx = file->driver_priv; struct msm_gem_submit *submit; struct msm_gpu *gpu = priv->gpu; + struct fence *in_fence = NULL; + struct sync_file *sync_file = NULL; + int out_fence_fd = -1; unsigned i; int ret; @@ -370,13 +375,24 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, /* for now, we just have 3d pipe.. eventually this would need to * be more clever to dispatch to appropriate gpu module: */ - if (args->pipe != MSM_PIPE_3D0) + if (MSM_PIPE_ID(args->flags) != MSM_PIPE_3D0) + return -EINVAL; + + if (MSM_PIPE_FLAGS(args->flags) & ~MSM_SUBMIT_FLAGS) return -EINVAL; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; + if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) { + out_fence_fd = get_unused_fd_flags(O_CLOEXEC); + if (out_fence_fd < 0) { + ret = out_fence_fd; + goto out_unlock; + } + } + submit = submit_create(dev, gpu, args->nr_bos, args->nr_cmds); if (!submit) { ret = -ENOMEM; @@ -391,9 +407,32 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, if (ret) goto out; - ret = submit_fence_sync(submit); - if (ret) - goto out; + if (args->flags & MSM_SUBMIT_FENCE_FD_IN) { + in_fence = sync_file_get_fence(args->fence_fd); + + if (!in_fence) { + ret = -EINVAL; + goto out; + } + + /* TODO if we get an array-fence due to userspace merging multiple + * fences, we need a way to determine if all the backing fences + * are from our own context.. + */ + + if (in_fence->context != gpu->fctx->context) { + ret = fence_wait(in_fence, true); + if (ret) + goto out; + } + + } + + if (!(args->fence & MSM_SUBMIT_NO_IMPLICIT)) { + ret = submit_fence_sync(submit); + if (ret) + goto out; + } ret = submit_pin_objects(submit); if (ret) @@ -459,15 +498,39 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, submit->nr_cmds = i; - ret = msm_gpu_submit(gpu, submit, ctx); + submit->fence = msm_fence_alloc(gpu->fctx); + if (IS_ERR(submit->fence)) { + ret = PTR_ERR(submit->fence); + submit->fence = NULL; + goto out; + } + + if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) { + sync_file = sync_file_create(submit->fence); + if (!sync_file) { + ret = -ENOMEM; + goto out; + } + } + + msm_gpu_submit(gpu, submit, ctx); args->fence = submit->fence->seqno; + if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) { + fd_install(out_fence_fd, sync_file->file); + args->fence_fd = out_fence_fd; + } + out: + if (in_fence) + fence_put(in_fence); submit_cleanup(submit); if (ret) msm_gem_submit_free(submit); out_unlock: + if (ret && (out_fence_fd >= 0)) + put_unused_fd(out_fence_fd); mutex_unlock(&dev->struct_mutex); return ret; } diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 36ed53e661fe..5bb09838b5ae 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -509,22 +509,15 @@ void msm_gpu_retire(struct msm_gpu *gpu) } /* add bo's to gpu's ring, and kick gpu: */ -int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, +void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_file_private *ctx) { struct drm_device *dev = gpu->dev; struct msm_drm_private *priv = dev->dev_private; - int i, ret; + int i; WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - submit->fence = msm_fence_alloc(gpu->fctx); - if (IS_ERR(submit->fence)) { - ret = PTR_ERR(submit->fence); - submit->fence = NULL; - return ret; - } - inactive_cancel(gpu); list_add_tail(&submit->node, &gpu->submit_list); @@ -557,8 +550,6 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, priv->lastctx = ctx; hangcheck_timer_reset(gpu); - - return 0; } /* diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index c9022837a1a4..d61d98a6e047 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -163,7 +163,7 @@ int msm_gpu_perfcntr_sample(struct msm_gpu *gpu, uint32_t *activetime, uint32_t *totaltime, uint32_t ncntrs, uint32_t *cntrs); void msm_gpu_retire(struct msm_gpu *gpu); -int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, +void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_file_private *ctx); int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, |