diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-11 21:12:22 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-11 21:12:22 -0400 |
| commit | 6b25e21fa6f26d0f0d45f161d169029411c84286 (patch) | |
| tree | fdff805ecd81ec46951f49577efe450ddb7d060a /drivers/gpu/drm/msm | |
| parent | a379f71a30dddbd2e7393624e455ce53c87965d1 (diff) | |
| parent | 69405d3da98b48633b78a49403e4f9cdb7c6a0f5 (diff) | |
Merge tag 'drm-for-v4.9' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"Core:
- Fence destaging work
- DRIVER_LEGACY to split off legacy drm drivers
- drm_mm refactoring
- Splitting drm_crtc.c into chunks and documenting better
- Display info fixes
- rbtree support for prime buffer lookup
- Simple VGA DAC driver
Panel:
- Add Nexus 7 panel
- More simple panels
i915:
- Refactoring GEM naming
- Refactored vma/active tracking
- Lockless request lookups
- Better stolen memory support
- FBC fixes
- SKL watermark fixes
- VGPU improvements
- dma-buf fencing support
- Better DP dongle support
amdgpu:
- Powerplay for Iceland asics
- Improved GPU reset support
- UVD/VEC powergating support for CZ/ST
- Preinitialised VRAM buffer support
- Virtual display support
- Initial SI support
- GTT rework
- PCI shutdown callback support
- HPD IRQ storm fixes
amdkfd:
- bugfixes
tilcdc:
- Atomic modesetting support
mediatek:
- AAL + GAMMA engine support
- Hook up gamma LUT
- Temporal dithering support
imx:
- Pixel clock from devicetree
- drm bridge support for LVDS bridges
- active plane reconfiguration
- VDIC deinterlacer support
- Frame synchronisation unit support
- Color space conversion support
analogix:
- PSR support
- Better panel on/off support
rockchip:
- rk3399 vop/crtc support
- PSR support
vc4:
- Interlaced vblank timing
- 3D rendering CPU overhead reduction
- HDMI output fixes
tda998x:
- HDMI audio ASoC support
sunxi:
- Allwinner A33 support
- better TCON support
msm:
- DT binding cleanups
- Explicit fence-fd support
sti:
- remove sti415/416 support
etnaviv:
- MMUv2 refactoring
- GC3000 support
exynos:
- Refactoring HDMI DCC/PHY
- G2D pm regression fix
- Page fault issues with wait for vblank
There is no nouveau work in this tree, as Ben didn't get a pull
request in, and he was fighting moving to atomic and adding mst
support, so maybe best it waits for a cycle"
* tag 'drm-for-v4.9' of git://people.freedesktop.org/~airlied/linux: (1412 commits)
drm/crtc: constify drm_crtc_index parameter
drm/i915: Fix conflict resolution from backmerge of v4.8-rc8 to drm-next
drm/i915/guc: Unwind GuC workqueue reservation if request construction fails
drm/i915: Reset the breadcrumbs IRQ more carefully
drm/i915: Force relocations via cpu if we run out of idle aperture
drm/i915: Distinguish last emitted request from last submitted request
drm/i915: Allow DP to work w/o EDID
drm/i915: Move long hpd handling into the hotplug work
drm/i915/execlists: Reinitialise context image after GPU hang
drm/i915: Use correct index for backtracking HUNG semaphores
drm/i915: Unalias obj->phys_handle and obj->userptr
drm/i915: Just clear the mmiodebug before a register access
drm/i915/gen9: only add the planes actually affected by ddb changes
drm/i915: Allow PCH DPLL sharing regardless of DPLL_SDVO_HIGH_SPEED
drm/i915/bxt: Fix HDMI DPLL configuration
drm/i915/gen9: fix the watermark res_blocks value
drm/i915/gen9: fix plane_blocks_per_line on watermarks calculations
drm/i915/gen9: minimum scanlines for Y tile is not always 4
drm/i915/gen9: fix the WaWmMemoryReadLatency implementation
drm/i915/kbl: KBL also needs to run the SAGV code
...
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 | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 16 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_atomic.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gem.c | 22 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gem_submit.c | 72 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gpu.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gpu.h | 2 |
13 files changed, 131 insertions, 63 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 | |||
| 11 | select TMPFS | 11 | select TMPFS |
| 12 | select QCOM_SCM | 12 | select QCOM_SCM |
| 13 | select SND_SOC_HDMI_CODEC if SND_SOC | 13 | select SND_SOC_HDMI_CODEC if SND_SOC |
| 14 | select SYNC_FILE | ||
| 14 | default y | 15 | default y |
| 15 | help | 16 | help |
| 16 | DRM/KMS driver for MSM/snapdragon. | 17 | 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 { | |||
| 422 | 422 | ||
| 423 | static int msm_hdmi_get_gpio(struct device_node *of_node, const char *name) | 423 | static int msm_hdmi_get_gpio(struct device_node *of_node, const char *name) |
| 424 | { | 424 | { |
| 425 | int gpio = of_get_named_gpio(of_node, name, 0); | 425 | int gpio; |
| 426 | |||
| 427 | /* try with the gpio names as in the table (downstream bindings) */ | ||
| 428 | gpio = of_get_named_gpio(of_node, name, 0); | ||
| 426 | if (gpio < 0) { | 429 | if (gpio < 0) { |
| 427 | char name2[32]; | 430 | char name2[32]; |
| 428 | snprintf(name2, sizeof(name2), "%s-gpio", name); | 431 | |
| 432 | /* try with the gpio names as in the upstream bindings */ | ||
| 433 | snprintf(name2, sizeof(name2), "%s-gpios", name); | ||
| 429 | gpio = of_get_named_gpio(of_node, name2, 0); | 434 | gpio = of_get_named_gpio(of_node, name2, 0); |
| 430 | if (gpio < 0) { | 435 | if (gpio < 0) { |
| 436 | char name3[32]; | ||
| 437 | |||
| 438 | /* | ||
| 439 | * try again after stripping out the "qcom,hdmi-tx" | ||
| 440 | * prefix. This is mainly to match "hpd-gpios" used | ||
| 441 | * in the upstream bindings | ||
| 442 | */ | ||
| 443 | if (sscanf(name2, "qcom,hdmi-tx-%s", name3)) | ||
| 444 | gpio = of_get_named_gpio(of_node, name3, 0); | ||
| 445 | } | ||
| 446 | |||
| 447 | if (gpio < 0) { | ||
| 431 | DBG("failed to get gpio: %s (%d)", name, gpio); | 448 | DBG("failed to get gpio: %s (%d)", name, gpio); |
| 432 | gpio = -1; | 449 | gpio = -1; |
| 433 | } | 450 | } |
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) | |||
| 243 | 243 | ||
| 244 | struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi) | 244 | struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi) |
| 245 | { | 245 | { |
| 246 | struct drm_device *dev = hdmi->dev; | ||
| 247 | struct hdmi_i2c_adapter *hdmi_i2c; | 246 | struct hdmi_i2c_adapter *hdmi_i2c; |
| 248 | struct i2c_adapter *i2c = NULL; | 247 | struct i2c_adapter *i2c = NULL; |
| 249 | int ret; | 248 | int ret; |
| @@ -267,10 +266,8 @@ struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi) | |||
| 267 | i2c->algo = &msm_hdmi_i2c_algorithm; | 266 | i2c->algo = &msm_hdmi_i2c_algorithm; |
| 268 | 267 | ||
| 269 | ret = i2c_add_adapter(i2c); | 268 | ret = i2c_add_adapter(i2c); |
| 270 | if (ret) { | 269 | if (ret) |
| 271 | dev_err(dev->dev, "failed to register hdmi i2c: %d\n", ret); | ||
| 272 | goto fail; | 270 | goto fail; |
| 273 | } | ||
| 274 | 271 | ||
| 275 | return i2c; | 272 | return i2c; |
| 276 | 273 | ||
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) | |||
| 228 | struct device_node *endpoint, *panel_node; | 228 | struct device_node *endpoint, *panel_node; |
| 229 | struct device_node *np = dev->dev->of_node; | 229 | struct device_node *np = dev->dev->of_node; |
| 230 | 230 | ||
| 231 | endpoint = of_graph_get_next_endpoint(np, NULL); | 231 | /* |
| 232 | * LVDS/LCDC is the first port described in the list of ports in the | ||
| 233 | * MDP4 DT node. | ||
| 234 | */ | ||
| 235 | endpoint = of_graph_get_endpoint_by_regs(np, 0, -1); | ||
| 232 | if (!endpoint) { | 236 | if (!endpoint) { |
| 233 | DBG("no endpoint in MDP4 to fetch LVDS panel\n"); | 237 | DBG("no LVDS remote endpoint\n"); |
| 234 | return NULL; | 238 | return NULL; |
| 235 | } | 239 | } |
| 236 | 240 | ||
| 237 | /* don't proceed if we have an endpoint but no panel_node tied to it */ | ||
| 238 | panel_node = of_graph_get_remote_port_parent(endpoint); | 241 | panel_node = of_graph_get_remote_port_parent(endpoint); |
| 239 | if (!panel_node) { | 242 | if (!panel_node) { |
| 240 | dev_err(dev->dev, "no valid panel node\n"); | 243 | DBG("no valid panel node in LVDS endpoint\n"); |
| 241 | of_node_put(endpoint); | 244 | of_node_put(endpoint); |
| 242 | return ERR_PTR(-ENODEV); | 245 | return NULL; |
| 243 | } | 246 | } |
| 244 | 247 | ||
| 245 | of_node_put(endpoint); | 248 | of_node_put(endpoint); |
| @@ -262,14 +265,12 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, | |||
| 262 | switch (intf_type) { | 265 | switch (intf_type) { |
| 263 | case DRM_MODE_ENCODER_LVDS: | 266 | case DRM_MODE_ENCODER_LVDS: |
| 264 | /* | 267 | /* |
| 265 | * bail out early if: | 268 | * bail out early if there is no panel node (no need to |
| 266 | * - there is no panel node (no need to initialize lcdc | 269 | * initialize LCDC encoder and LVDS connector) |
| 267 | * encoder and lvds connector), or | ||
| 268 | * - panel node is a bad pointer | ||
| 269 | */ | 270 | */ |
| 270 | panel_node = mdp4_detect_lcdc_panel(dev); | 271 | panel_node = mdp4_detect_lcdc_panel(dev); |
| 271 | if (IS_ERR_OR_NULL(panel_node)) | 272 | if (!panel_node) |
| 272 | return PTR_ERR(panel_node); | 273 | return 0; |
| 273 | 274 | ||
| 274 | encoder = mdp4_lcdc_encoder_init(dev, panel_node); | 275 | encoder = mdp4_lcdc_encoder_init(dev, panel_node); |
| 275 | if (IS_ERR(encoder)) { | 276 | 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 = { | |||
| 93 | }; | 93 | }; |
| 94 | 94 | ||
| 95 | /* this should probably be a helper: */ | 95 | /* this should probably be a helper: */ |
| 96 | struct drm_connector *get_connector(struct drm_encoder *encoder) | 96 | static struct drm_connector *get_connector(struct drm_encoder *encoder) |
| 97 | { | 97 | { |
| 98 | struct drm_device *dev = encoder->dev; | 98 | struct drm_device *dev = encoder->dev; |
| 99 | struct drm_connector *connector; | 99 | 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 9f96dfe67769..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, | |||
| 81 | // XXX | 81 | // XXX |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | int mdp4_plane_set_property(struct drm_plane *plane, | 84 | static int mdp4_plane_set_property(struct drm_plane *plane, |
| 85 | struct drm_property *property, uint64_t val) | 85 | struct drm_property *property, uint64_t val) |
| 86 | { | 86 | { |
| 87 | // XXX | 87 | // XXX |
| @@ -99,7 +99,7 @@ static const struct drm_plane_funcs mdp4_plane_funcs = { | |||
| 99 | }; | 99 | }; |
| 100 | 100 | ||
| 101 | static int mdp4_plane_prepare_fb(struct drm_plane *plane, | 101 | static int mdp4_plane_prepare_fb(struct drm_plane *plane, |
| 102 | const struct drm_plane_state *new_state) | 102 | struct drm_plane_state *new_state) |
| 103 | { | 103 | { |
| 104 | struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); | 104 | struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); |
| 105 | struct mdp4_kms *mdp4_kms = get_kms(plane); | 105 | struct mdp4_kms *mdp4_kms = get_kms(plane); |
| @@ -113,7 +113,7 @@ static int mdp4_plane_prepare_fb(struct drm_plane *plane, | |||
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | static void mdp4_plane_cleanup_fb(struct drm_plane *plane, | 115 | static void mdp4_plane_cleanup_fb(struct drm_plane *plane, |
| 116 | const struct drm_plane_state *old_state) | 116 | struct drm_plane_state *old_state) |
| 117 | { | 117 | { |
| 118 | struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); | 118 | struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); |
| 119 | struct mdp4_kms *mdp4_kms = get_kms(plane); | 119 | struct mdp4_kms *mdp4_kms = get_kms(plane); |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 432c09836b0e..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, | |||
| 78 | if (!dev->mode_config.rotation_property) | 78 | if (!dev->mode_config.rotation_property) |
| 79 | dev->mode_config.rotation_property = | 79 | dev->mode_config.rotation_property = |
| 80 | drm_mode_create_rotation_property(dev, | 80 | drm_mode_create_rotation_property(dev, |
| 81 | BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y)); | 81 | DRM_ROTATE_0 | DRM_REFLECT_X | DRM_REFLECT_Y); |
| 82 | 82 | ||
| 83 | if (dev->mode_config.rotation_property) | 83 | if (dev->mode_config.rotation_property) |
| 84 | drm_object_attach_property(&plane->base, | 84 | drm_object_attach_property(&plane->base, |
| 85 | dev->mode_config.rotation_property, | 85 | dev->mode_config.rotation_property, |
| 86 | 0); | 86 | DRM_ROTATE_0); |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | /* helper to install properties which are common to planes and crtcs */ | 89 | /* helper to install properties which are common to planes and crtcs */ |
| @@ -250,7 +250,7 @@ static const struct drm_plane_funcs mdp5_plane_funcs = { | |||
| 250 | }; | 250 | }; |
| 251 | 251 | ||
| 252 | static int mdp5_plane_prepare_fb(struct drm_plane *plane, | 252 | static int mdp5_plane_prepare_fb(struct drm_plane *plane, |
| 253 | const struct drm_plane_state *new_state) | 253 | struct drm_plane_state *new_state) |
| 254 | { | 254 | { |
| 255 | struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); | 255 | struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); |
| 256 | struct mdp5_kms *mdp5_kms = get_kms(plane); | 256 | struct mdp5_kms *mdp5_kms = get_kms(plane); |
| @@ -264,7 +264,7 @@ static int mdp5_plane_prepare_fb(struct drm_plane *plane, | |||
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | static void mdp5_plane_cleanup_fb(struct drm_plane *plane, | 266 | static void mdp5_plane_cleanup_fb(struct drm_plane *plane, |
| 267 | const struct drm_plane_state *old_state) | 267 | struct drm_plane_state *old_state) |
| 268 | { | 268 | { |
| 269 | struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); | 269 | struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); |
| 270 | struct mdp5_kms *mdp5_kms = get_kms(plane); | 270 | struct mdp5_kms *mdp5_kms = get_kms(plane); |
| @@ -309,8 +309,8 @@ static int mdp5_plane_atomic_check(struct drm_plane *plane, | |||
| 309 | return -EINVAL; | 309 | return -EINVAL; |
| 310 | } | 310 | } |
| 311 | 311 | ||
| 312 | hflip = !!(state->rotation & BIT(DRM_REFLECT_X)); | 312 | hflip = !!(state->rotation & DRM_REFLECT_X); |
| 313 | vflip = !!(state->rotation & BIT(DRM_REFLECT_Y)); | 313 | vflip = !!(state->rotation & DRM_REFLECT_Y); |
| 314 | if ((vflip && !(mdp5_plane->caps & MDP_PIPE_CAP_VFLIP)) || | 314 | if ((vflip && !(mdp5_plane->caps & MDP_PIPE_CAP_VFLIP)) || |
| 315 | (hflip && !(mdp5_plane->caps & MDP_PIPE_CAP_HFLIP))) { | 315 | (hflip && !(mdp5_plane->caps & MDP_PIPE_CAP_HFLIP))) { |
| 316 | dev_err(plane->dev->dev, | 316 | dev_err(plane->dev->dev, |
| @@ -743,8 +743,8 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, | |||
| 743 | config |= get_scale_config(format, src_h, crtc_h, false); | 743 | config |= get_scale_config(format, src_h, crtc_h, false); |
| 744 | DBG("scale config = %x", config); | 744 | DBG("scale config = %x", config); |
| 745 | 745 | ||
| 746 | hflip = !!(pstate->rotation & BIT(DRM_REFLECT_X)); | 746 | hflip = !!(pstate->rotation & DRM_REFLECT_X); |
| 747 | vflip = !!(pstate->rotation & BIT(DRM_REFLECT_Y)); | 747 | vflip = !!(pstate->rotation & DRM_REFLECT_Y); |
| 748 | 748 | ||
| 749 | spin_lock_irqsave(&mdp5_plane->pipe_lock, flags); | 749 | spin_lock_irqsave(&mdp5_plane->pipe_lock, flags); |
| 750 | 750 | ||
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 4a8a6f1f1151..73bae382eac3 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c | |||
| @@ -112,13 +112,13 @@ static void complete_commit(struct msm_commit *c, bool async) | |||
| 112 | struct msm_drm_private *priv = dev->dev_private; | 112 | struct msm_drm_private *priv = dev->dev_private; |
| 113 | struct msm_kms *kms = priv->kms; | 113 | struct msm_kms *kms = priv->kms; |
| 114 | 114 | ||
| 115 | drm_atomic_helper_wait_for_fences(dev, state); | 115 | drm_atomic_helper_wait_for_fences(dev, state, false); |
| 116 | 116 | ||
| 117 | kms->funcs->prepare_commit(kms, state); | 117 | kms->funcs->prepare_commit(kms, state); |
| 118 | 118 | ||
| 119 | drm_atomic_helper_commit_modeset_disables(dev, state); | 119 | drm_atomic_helper_commit_modeset_disables(dev, state); |
| 120 | 120 | ||
| 121 | drm_atomic_helper_commit_planes(dev, state, false); | 121 | drm_atomic_helper_commit_planes(dev, state, 0); |
| 122 | 122 | ||
| 123 | drm_atomic_helper_commit_modeset_enables(dev, state); | 123 | drm_atomic_helper_commit_modeset_enables(dev, state); |
| 124 | 124 | ||
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 8a0237008f74..fb5c0b0a7594 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c | |||
| @@ -26,9 +26,10 @@ | |||
| 26 | * MSM driver version: | 26 | * MSM driver version: |
| 27 | * - 1.0.0 - initial interface | 27 | * - 1.0.0 - initial interface |
| 28 | * - 1.1.0 - adds madvise, and support for submits with > 4 cmd buffers | 28 | * - 1.1.0 - adds madvise, and support for submits with > 4 cmd buffers |
| 29 | * - 1.2.0 - adds explicit fence support for submit ioctl | ||
| 29 | */ | 30 | */ |
| 30 | #define MSM_VERSION_MAJOR 1 | 31 | #define MSM_VERSION_MAJOR 1 |
| 31 | #define MSM_VERSION_MINOR 1 | 32 | #define MSM_VERSION_MINOR 2 |
| 32 | #define MSM_VERSION_PATCHLEVEL 0 | 33 | #define MSM_VERSION_PATCHLEVEL 0 |
| 33 | 34 | ||
| 34 | static void msm_fb_output_poll_changed(struct drm_device *dev) | 35 | static void msm_fb_output_poll_changed(struct drm_device *dev) |
| @@ -347,9 +348,9 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) | |||
| 347 | int ret; | 348 | int ret; |
| 348 | 349 | ||
| 349 | ddev = drm_dev_alloc(drv, dev); | 350 | ddev = drm_dev_alloc(drv, dev); |
| 350 | if (!ddev) { | 351 | if (IS_ERR(ddev)) { |
| 351 | dev_err(dev, "failed to allocate drm_device\n"); | 352 | dev_err(dev, "failed to allocate drm_device\n"); |
| 352 | return -ENOMEM; | 353 | return PTR_ERR(ddev); |
| 353 | } | 354 | } |
| 354 | 355 | ||
| 355 | platform_set_drvdata(pdev, ddev); | 356 | platform_set_drvdata(pdev, ddev); |
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 85f3047e05ae..b6ac27e31929 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c | |||
| @@ -593,18 +593,16 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, ktime_t *timeout) | |||
| 593 | { | 593 | { |
| 594 | struct msm_gem_object *msm_obj = to_msm_bo(obj); | 594 | struct msm_gem_object *msm_obj = to_msm_bo(obj); |
| 595 | bool write = !!(op & MSM_PREP_WRITE); | 595 | bool write = !!(op & MSM_PREP_WRITE); |
| 596 | 596 | unsigned long remain = | |
| 597 | if (op & MSM_PREP_NOSYNC) { | 597 | op & MSM_PREP_NOSYNC ? 0 : timeout_to_jiffies(timeout); |
| 598 | if (!reservation_object_test_signaled_rcu(msm_obj->resv, write)) | 598 | long ret; |
| 599 | return -EBUSY; | 599 | |
| 600 | } else { | 600 | ret = reservation_object_wait_timeout_rcu(msm_obj->resv, write, |
| 601 | int ret; | 601 | true, remain); |
| 602 | 602 | if (ret == 0) | |
| 603 | ret = reservation_object_wait_timeout_rcu(msm_obj->resv, write, | 603 | return remain == 0 ? -EBUSY : -ETIMEDOUT; |
| 604 | true, timeout_to_jiffies(timeout)); | 604 | else if (ret < 0) |
| 605 | if (ret <= 0) | 605 | return ret; |
| 606 | return ret == 0 ? -ETIMEDOUT : ret; | ||
| 607 | } | ||
| 608 | 606 | ||
| 609 | /* TODO cache maintenance */ | 607 | /* TODO cache maintenance */ |
| 610 | 608 | ||
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 880d6a9af7c8..b6a0f37a65f3 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | * this program. If not, see <http://www.gnu.org/licenses/>. | 15 | * this program. If not, see <http://www.gnu.org/licenses/>. |
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #include <linux/sync_file.h> | ||
| 19 | |||
| 18 | #include "msm_drv.h" | 20 | #include "msm_drv.h" |
| 19 | #include "msm_gpu.h" | 21 | #include "msm_gpu.h" |
| 20 | #include "msm_gem.h" | 22 | #include "msm_gem.h" |
| @@ -378,6 +380,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, | |||
| 378 | struct msm_file_private *ctx = file->driver_priv; | 380 | struct msm_file_private *ctx = file->driver_priv; |
| 379 | struct msm_gem_submit *submit; | 381 | struct msm_gem_submit *submit; |
| 380 | struct msm_gpu *gpu = priv->gpu; | 382 | struct msm_gpu *gpu = priv->gpu; |
| 383 | struct fence *in_fence = NULL; | ||
| 384 | struct sync_file *sync_file = NULL; | ||
| 385 | int out_fence_fd = -1; | ||
| 381 | unsigned i; | 386 | unsigned i; |
| 382 | int ret; | 387 | int ret; |
| 383 | 388 | ||
| @@ -387,13 +392,23 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, | |||
| 387 | /* for now, we just have 3d pipe.. eventually this would need to | 392 | /* for now, we just have 3d pipe.. eventually this would need to |
| 388 | * be more clever to dispatch to appropriate gpu module: | 393 | * be more clever to dispatch to appropriate gpu module: |
| 389 | */ | 394 | */ |
| 390 | if (args->pipe != MSM_PIPE_3D0) | 395 | if (MSM_PIPE_ID(args->flags) != MSM_PIPE_3D0) |
| 396 | return -EINVAL; | ||
| 397 | |||
| 398 | if (MSM_PIPE_FLAGS(args->flags) & ~MSM_SUBMIT_FLAGS) | ||
| 391 | return -EINVAL; | 399 | return -EINVAL; |
| 392 | 400 | ||
| 393 | ret = mutex_lock_interruptible(&dev->struct_mutex); | 401 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
| 394 | if (ret) | 402 | if (ret) |
| 395 | return ret; | 403 | return ret; |
| 396 | 404 | ||
| 405 | if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) { | ||
| 406 | out_fence_fd = get_unused_fd_flags(O_CLOEXEC); | ||
| 407 | if (out_fence_fd < 0) { | ||
| 408 | ret = out_fence_fd; | ||
| 409 | goto out_unlock; | ||
| 410 | } | ||
| 411 | } | ||
| 397 | priv->struct_mutex_task = current; | 412 | priv->struct_mutex_task = current; |
| 398 | 413 | ||
| 399 | submit = submit_create(dev, gpu, args->nr_bos, args->nr_cmds); | 414 | submit = submit_create(dev, gpu, args->nr_bos, args->nr_cmds); |
| @@ -410,9 +425,32 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, | |||
| 410 | if (ret) | 425 | if (ret) |
| 411 | goto out; | 426 | goto out; |
| 412 | 427 | ||
| 413 | ret = submit_fence_sync(submit); | 428 | if (args->flags & MSM_SUBMIT_FENCE_FD_IN) { |
| 414 | if (ret) | 429 | in_fence = sync_file_get_fence(args->fence_fd); |
| 415 | goto out; | 430 | |
| 431 | if (!in_fence) { | ||
| 432 | ret = -EINVAL; | ||
| 433 | goto out; | ||
| 434 | } | ||
| 435 | |||
| 436 | /* TODO if we get an array-fence due to userspace merging multiple | ||
| 437 | * fences, we need a way to determine if all the backing fences | ||
| 438 | * are from our own context.. | ||
| 439 | */ | ||
| 440 | |||
| 441 | if (in_fence->context != gpu->fctx->context) { | ||
| 442 | ret = fence_wait(in_fence, true); | ||
| 443 | if (ret) | ||
| 444 | goto out; | ||
| 445 | } | ||
| 446 | |||
| 447 | } | ||
| 448 | |||
| 449 | if (!(args->fence & MSM_SUBMIT_NO_IMPLICIT)) { | ||
| 450 | ret = submit_fence_sync(submit); | ||
| 451 | if (ret) | ||
| 452 | goto out; | ||
| 453 | } | ||
| 416 | 454 | ||
| 417 | ret = submit_pin_objects(submit); | 455 | ret = submit_pin_objects(submit); |
| 418 | if (ret) | 456 | if (ret) |
| @@ -478,15 +516,39 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, | |||
| 478 | 516 | ||
| 479 | submit->nr_cmds = i; | 517 | submit->nr_cmds = i; |
| 480 | 518 | ||
| 481 | ret = msm_gpu_submit(gpu, submit, ctx); | 519 | submit->fence = msm_fence_alloc(gpu->fctx); |
| 520 | if (IS_ERR(submit->fence)) { | ||
| 521 | ret = PTR_ERR(submit->fence); | ||
| 522 | submit->fence = NULL; | ||
| 523 | goto out; | ||
| 524 | } | ||
| 525 | |||
| 526 | if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) { | ||
| 527 | sync_file = sync_file_create(submit->fence); | ||
| 528 | if (!sync_file) { | ||
| 529 | ret = -ENOMEM; | ||
| 530 | goto out; | ||
| 531 | } | ||
| 532 | } | ||
| 533 | |||
| 534 | msm_gpu_submit(gpu, submit, ctx); | ||
| 482 | 535 | ||
| 483 | args->fence = submit->fence->seqno; | 536 | args->fence = submit->fence->seqno; |
| 484 | 537 | ||
| 538 | if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) { | ||
| 539 | fd_install(out_fence_fd, sync_file->file); | ||
| 540 | args->fence_fd = out_fence_fd; | ||
| 541 | } | ||
| 542 | |||
| 485 | out: | 543 | out: |
| 544 | if (in_fence) | ||
| 545 | fence_put(in_fence); | ||
| 486 | submit_cleanup(submit); | 546 | submit_cleanup(submit); |
| 487 | if (ret) | 547 | if (ret) |
| 488 | msm_gem_submit_free(submit); | 548 | msm_gem_submit_free(submit); |
| 489 | out_unlock: | 549 | out_unlock: |
| 550 | if (ret && (out_fence_fd >= 0)) | ||
| 551 | put_unused_fd(out_fence_fd); | ||
| 490 | priv->struct_mutex_task = NULL; | 552 | priv->struct_mutex_task = NULL; |
| 491 | mutex_unlock(&dev->struct_mutex); | 553 | mutex_unlock(&dev->struct_mutex); |
| 492 | return ret; | 554 | 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) | |||
| 509 | } | 509 | } |
| 510 | 510 | ||
| 511 | /* add bo's to gpu's ring, and kick gpu: */ | 511 | /* add bo's to gpu's ring, and kick gpu: */ |
| 512 | int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, | 512 | void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, |
| 513 | struct msm_file_private *ctx) | 513 | struct msm_file_private *ctx) |
| 514 | { | 514 | { |
| 515 | struct drm_device *dev = gpu->dev; | 515 | struct drm_device *dev = gpu->dev; |
| 516 | struct msm_drm_private *priv = dev->dev_private; | 516 | struct msm_drm_private *priv = dev->dev_private; |
| 517 | int i, ret; | 517 | int i; |
| 518 | 518 | ||
| 519 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); | 519 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); |
| 520 | 520 | ||
| 521 | submit->fence = msm_fence_alloc(gpu->fctx); | ||
| 522 | if (IS_ERR(submit->fence)) { | ||
| 523 | ret = PTR_ERR(submit->fence); | ||
| 524 | submit->fence = NULL; | ||
| 525 | return ret; | ||
| 526 | } | ||
| 527 | |||
| 528 | inactive_cancel(gpu); | 521 | inactive_cancel(gpu); |
| 529 | 522 | ||
| 530 | list_add_tail(&submit->node, &gpu->submit_list); | 523 | 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, | |||
| 557 | priv->lastctx = ctx; | 550 | priv->lastctx = ctx; |
| 558 | 551 | ||
| 559 | hangcheck_timer_reset(gpu); | 552 | hangcheck_timer_reset(gpu); |
| 560 | |||
| 561 | return 0; | ||
| 562 | } | 553 | } |
| 563 | 554 | ||
| 564 | /* | 555 | /* |
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, | |||
| 163 | uint32_t *totaltime, uint32_t ncntrs, uint32_t *cntrs); | 163 | uint32_t *totaltime, uint32_t ncntrs, uint32_t *cntrs); |
| 164 | 164 | ||
| 165 | void msm_gpu_retire(struct msm_gpu *gpu); | 165 | void msm_gpu_retire(struct msm_gpu *gpu); |
| 166 | int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, | 166 | void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, |
| 167 | struct msm_file_private *ctx); | 167 | struct msm_file_private *ctx); |
| 168 | 168 | ||
| 169 | int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, | 169 | int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, |
