History

Merge tag 'drm-misc-next-2017-10-20' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

Final drm-misc feature pull for 4.15: UAPI Changes: - new madvise ioctl for vc4 (Boris) Core Changes: - plane commit tracking fixes (Maarten) - vgaarb improvements for fancy new platforms (aka ppc64 and arm64) by Bjorn Helgaas Driver Changes: - pile of new panel drivers: Toshiba LT089AC19000, Innolux AT043TN24 - more sun4i work to support A10/A20 Tcon and hdmi outputs - vc4: fix sleep in irq handler by making it threaded (Eric) - udl probe/edid read fixes (Robert Tarasov) And a bunch of misc small cleanups/refactors and doc fixes all over. * tag 'drm-misc-next-2017-10-20' of git://anongit.freedesktop.org/drm/drm-misc: (32 commits) drm/vc4: Fix sleeps during the IRQ handler for DSI transactions. drm/vc4: Add the DRM_IOCTL_VC4_GEM_MADVISE ioctl drm/panel: simple: add Toshiba LT089AC19000 dma-fence: remove duplicate word in comment drm/panel: simple: add delays for Innolux AT043TN24 drm/panel: simple: add bus flags for Innolux AT043TN24 drm/panel: simple: fix vertical timings for Innolux AT043TN24 drm/atomic-helper: check that drivers call drm_crtc_vblank_off drm: some KMS todo ideas vgaarb: Factor out EFI and fallback default device selection vgaarb: Select a default VGA device even if there's no legacy VGA drm/bridge: adv7511: Fix a use after free drm/sun4i: Add support for A20 display pipeline components drm/sun4i: Add support for A10 display pipeline components drm/sun4i: hdmi: Support HDMI controller on A10 drm/sun4i: tcon: Add support for A10 TCON drm/sun4i: backend: Support output muxing drm/sun4i: tcon: Move out the tcon0 common setup drm/sun4i: tcon: Don't rely on encoders to set the TCON mode drm/sun4i: tcon: Don't rely on encoders to enable the TCON ...

Dave Airlie committed 9 years ago

Commit fef1aa42 parents 3b677e4 af0c8c139 files · +1154 −356Browse files

Unified · Split

39 files
  1. Documentation/devicetree/bindings/display/panel/toshiba,lt089ac29000.txt +8 −0
  2. Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +9 −0
  3. Documentation/gpu/todo.rst +12 −0
  4. arch/powerpc/kernel/pci-common.c +0 −12
  5. drivers/gpu/drm/armada/armada_crtc.c +11 −11
  6. drivers/gpu/drm/armada/armada_drv.c +1 −1
  7. drivers/gpu/drm/armada/armada_fb.c +4 −4
  8. drivers/gpu/drm/armada/armada_fbdev.c +3 −3
  9. drivers/gpu/drm/armada/armada_gem.c +6 −6
  10. drivers/gpu/drm/armada/armada_overlay.c +2 −2
  11. drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +2 −2
  12. drivers/gpu/drm/drm_atomic_helper.c +18 −10
  13. drivers/gpu/drm/drm_gem_cma_helper.c +1 −1
  14. drivers/gpu/drm/panel/panel-simple.c +34 −2
  15. drivers/gpu/drm/sun4i/Makefile +17 −16
  16. drivers/gpu/drm/sun4i/sun4i_backend.c +72 −3
  17. drivers/gpu/drm/sun4i/sun4i_backend.h +2 −1
  18. drivers/gpu/drm/sun4i/sun4i_crtc.c +30 −2
  19. drivers/gpu/drm/sun4i/sun4i_drv.c +21 −60
  20. drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c +0 −1
  21. drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +53 −15
  22. drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c +0 −1
  23. drivers/gpu/drm/sun4i/sun4i_rgb.c +4 −25
  24. drivers/gpu/drm/sun4i/sun4i_tcon.c +119 −64
  25. drivers/gpu/drm/sun4i/sun4i_tcon.h +6 −17
  26. drivers/gpu/drm/sun4i/sun4i_tv.c +0 −12
  27. drivers/gpu/drm/udl/udl_connector.c +104 −50
  28. drivers/gpu/drm/udl/udl_connector.h +13 −0
  29. drivers/gpu/drm/udl/udl_drv.c +4 −0
  30. drivers/gpu/drm/udl/udl_main.c +5 −0
  31. drivers/gpu/drm/vc4/vc4_bo.c +279 −8
  32. drivers/gpu/drm/vc4/vc4_drv.c +9 −1
  33. drivers/gpu/drm/vc4/vc4_drv.h +30 −0
  34. drivers/gpu/drm/vc4/vc4_dsi.c +30 −2
  35. drivers/gpu/drm/vc4/vc4_gem.c +150 −6
  36. drivers/gpu/drm/vc4/vc4_plane.c +20 −0
  37. drivers/gpu/vga/vgaarb.c +55 −17
  38. include/linux/dma-fence.h +1 −1
  39. include/uapi/drm/vc4_drm.h +19 −0
Documentation/devicetree/bindings/display/panel/toshiba,lt089ac29000.txt+8−0
@@ -0,0 +1,8 @@
1+Toshiba 8.9" WXGA (1280x768) TFT LCD panel
2+
3+Required properties:
4+- compatible: should be "toshiba,lt089ac29000.txt"
5+- power-supply: as specified in the base binding
6+
7+This binding is compatible with the simple-panel binding, which is specified
8+in simple-panel.txt in this directory.
Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt+9−0
@@ -40,6 +40,7 @@ CEC. It is one end of the pipeline. · 39 unmodified lines
4040
4141 Required properties:
4242 - compatible: value must be one of:
43+ * allwinner,sun4i-a10-hdmi
4344 * allwinner,sun5i-a10s-hdmi
4445 * allwinner,sun6i-a31-hdmi
4546 - reg: base address and size of memory-mapped region
@@ -86,9 +87,11 @@ The TCON acts as a timing controller for RGB, LVDS and TV interfaces. · 40 unmodified lines
8687
8788 Required properties:
8889 - compatible: value must be either:
90+ * allwinner,sun4i-a10-tcon
8991 * allwinner,sun5i-a13-tcon
9092 * allwinner,sun6i-a31-tcon
9193 * allwinner,sun6i-a31s-tcon
94+ * allwinner,sun7i-a20-tcon
9295 * allwinner,sun8i-a33-tcon
9396 * allwinner,sun8i-v3s-tcon
9497 - reg: base address and size of memory-mapped region
@@ -153,8 +156,10 @@ system. · 58 unmodified lines
153156
154157 Required properties:
155158 - compatible: value must be one of:
159+ * allwinner,sun4i-a10-display-backend
156160 * allwinner,sun5i-a13-display-backend
157161 * allwinner,sun6i-a31-display-backend
162+ * allwinner,sun7i-a20-display-backend
158163 * allwinner,sun8i-a33-display-backend
159164 - reg: base address and size of the memory-mapped region.
160165 - interrupts: interrupt associated to this IP
@@ -185,8 +190,10 @@ deinterlacing and color space conversion. · 24 unmodified lines
185190
186191 Required properties:
187192 - compatible: value must be one of:
193+ * allwinner,sun4i-a10-display-frontend
188194 * allwinner,sun5i-a13-display-frontend
189195 * allwinner,sun6i-a31-display-frontend
196+ * allwinner,sun7i-a20-display-frontend
190197 * allwinner,sun8i-a33-display-frontend
191198 - reg: base address and size of the memory-mapped region.
192199 - interrupts: interrupt associated to this IP
@@ -231,10 +238,12 @@ extra node. · 38 unmodified lines
231238
232239 Required properties:
233240 - compatible: value must be one of:
241+ * allwinner,sun4i-a10-display-engine
234242 * allwinner,sun5i-a10s-display-engine
235243 * allwinner,sun5i-a13-display-engine
236244 * allwinner,sun6i-a31-display-engine
237245 * allwinner,sun6i-a31s-display-engine
246+ * allwinner,sun7i-a20-display-engine
238247 * allwinner,sun8i-a33-display-engine
239248 * allwinner,sun8i-v3s-display-engine
240249
Documentation/gpu/todo.rst+12−0
@@ -304,6 +304,18 @@ There's a bunch of issues with it: · 303 unmodified lines
304304
305305 Contact: Daniel Vetter
306306
307+KMS cleanups
308+------------
309+
310+Some of these date from the very introduction of KMS in 2008 ...
311+
312+- drm_mode_config.crtc_idr is misnamed, since it contains all KMS object. Should
313+ be renamed to drm_mode_config.object_idr.
314+
315+- drm_display_mode doesn't need to be derived from drm_mode_object. That's
316+ leftovers from older (never merged into upstream) KMS designs where modes
317+ where set using their ID, including support to add/remove modes.
318+
307319 Better Testing
308320 ==============
309321
arch/powerpc/kernel/pci-common.c+0−12
@@ -1740,15 +1740,3 @@ static void fixup_hide_host_resource_fsl(struct pci_dev *dev) · 1739 unmodified lines
17401740 }
17411741 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID, fixup_hide_host_resource_fsl);
17421742 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, fixup_hide_host_resource_fsl);
1743−
1744−static void fixup_vga(struct pci_dev *pdev)
1745−{
1746− u16 cmd;
1747−
1748− pci_read_config_word(pdev, PCI_COMMAND, &cmd);
1749− if ((cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) || !vga_default_device())
1750− vga_set_default_device(pdev);
1751−
1752−}
1753−DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID,
1754− PCI_CLASS_DISPLAY_VGA, 8, fixup_vga);
drivers/gpu/drm/armada/armada_crtc.c+11−11
@@ -298,7 +298,7 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc, · 297 unmodified lines
298298
299299 if (force) {
300300 /* Display is disabled, so just drop the old fb */
301− drm_framebuffer_unreference(fb);
301+ drm_framebuffer_put(fb);
302302 return;
303303 }
304304
@@ -321,7 +321,7 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc, · 16 unmodified lines
321321 * the best. The worst that will happen is the buffer gets
322322 * reused before it has finished being displayed.
323323 */
324− drm_framebuffer_unreference(fb);
324+ drm_framebuffer_put(fb);
325325 }
326326
327327 static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
@@ -577,7 +577,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, · 249 unmodified lines
577577 unsigned i;
578578 bool interlaced;
579579
580− drm_framebuffer_reference(crtc->primary->fb);
580+ drm_framebuffer_get(crtc->primary->fb);
581581
582582 interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE);
583583
@@ -718,7 +718,7 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, · 134 unmodified lines
718718 MAX_SCHEDULE_TIMEOUT);
719719
720720 /* Take a reference to the new fb as we're using it */
721− drm_framebuffer_reference(crtc->primary->fb);
721+ drm_framebuffer_get(crtc->primary->fb);
722722
723723 /* Update the base in the CRTC */
724724 armada_drm_crtc_update_regs(dcrtc, regs);
@@ -742,7 +742,7 @@ void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc, · 17 unmodified lines
742742 * primary plane.
743743 */
744744 if (plane->fb)
745− drm_framebuffer_unreference(plane->fb);
745+ drm_framebuffer_put(plane->fb);
746746
747747 /* Power down the Y/U/V FIFOs */
748748 sram_para1 = CFG_PDWN16x66 | CFG_PDWN32x66;
@@ -947,13 +947,13 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc, · 198 unmodified lines
947947
948948 /* Must be a kernel-mapped object */
949949 if (!obj->addr) {
950− drm_gem_object_unreference_unlocked(&obj->obj);
950+ drm_gem_object_put_unlocked(&obj->obj);
951951 return -EINVAL;
952952 }
953953
954954 if (obj->obj.size < w * h * 4) {
955955 DRM_ERROR("buffer is too small\n");
956− drm_gem_object_unreference_unlocked(&obj->obj);
956+ drm_gem_object_put_unlocked(&obj->obj);
957957 return -ENOMEM;
958958 }
959959 }
@@ -961,7 +961,7 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc, · 1 unmodified line
961961 if (dcrtc->cursor_obj) {
962962 dcrtc->cursor_obj->update = NULL;
963963 dcrtc->cursor_obj->update_data = NULL;
964− drm_gem_object_unreference_unlocked(&dcrtc->cursor_obj->obj);
964+ drm_gem_object_put_unlocked(&dcrtc->cursor_obj->obj);
965965 }
966966 dcrtc->cursor_obj = obj;
967967 dcrtc->cursor_w = w;
@@ -997,7 +997,7 @@ static void armada_drm_crtc_destroy(struct drm_crtc *crtc) · 29 unmodified lines
997997 struct armada_private *priv = crtc->dev->dev_private;
998998
999999 if (dcrtc->cursor_obj)
1000− drm_gem_object_unreference_unlocked(&dcrtc->cursor_obj->obj);
1000+ drm_gem_object_put_unlocked(&dcrtc->cursor_obj->obj);
10011001
10021002 priv->dcrtc[dcrtc->num] = NULL;
10031003 drm_crtc_cleanup(&dcrtc->crtc);
@@ -1045,12 +1045,12 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc, · 41 unmodified lines
10451045 * Ensure that we hold a reference on the new framebuffer.
10461046 * This has to match the behaviour in mode_set.
10471047 */
1048− drm_framebuffer_reference(fb);
1048+ drm_framebuffer_get(fb);
10491049
10501050 ret = armada_drm_crtc_queue_frame_work(dcrtc, work);
10511051 if (ret) {
10521052 /* Undo our reference above */
1053− drm_framebuffer_unreference(fb);
1053+ drm_framebuffer_put(fb);
10541054 kfree(work);
10551055 return ret;
10561056 }
drivers/gpu/drm/armada/armada_drv.c+1−1
@@ -25,7 +25,7 @@ static void armada_drm_unref_work(struct work_struct *work) · 24 unmodified lines
2525 struct drm_framebuffer *fb;
2626
2727 while (kfifo_get(&priv->fb_unref, &fb))
28− drm_framebuffer_unreference(fb);
28+ drm_framebuffer_put(fb);
2929 }
3030
3131 /* Must be called with dev->event_lock held */
drivers/gpu/drm/armada/armada_fb.c+4−4
@@ -17,7 +17,7 @@ static void armada_fb_destroy(struct drm_framebuffer *fb) · 16 unmodified lines
1717 struct armada_framebuffer *dfb = drm_fb_to_armada_fb(fb);
1818
1919 drm_framebuffer_cleanup(&dfb->fb);
20− drm_gem_object_unreference_unlocked(&dfb->obj->obj);
20+ drm_gem_object_put_unlocked(&dfb->obj->obj);
2121 kfree(dfb);
2222 }
2323
@@ -94,7 +94,7 @@ struct armada_framebuffer *armada_framebuffer_create(struct drm_device *dev, · 70 unmodified lines
9494 * the above call, but the caller will drop their reference
9595 * to it. Hence we need to take our own reference.
9696 */
97− drm_gem_object_reference(&obj->obj);
97+ drm_gem_object_get(&obj->obj);
9898
9999 return dfb;
100100 }
@@ -143,12 +143,12 @@ static struct drm_framebuffer *armada_fb_create(struct drm_device *dev, · 42 unmodified lines
143143 goto err;
144144 }
145145
146− drm_gem_object_unreference_unlocked(&obj->obj);
146+ drm_gem_object_put_unlocked(&obj->obj);
147147
148148 return &dfb->fb;
149149
150150 err_unref:
151− drm_gem_object_unreference_unlocked(&obj->obj);
151+ drm_gem_object_put_unlocked(&obj->obj);
152152 err:
153153 DRM_ERROR("failed to initialize framebuffer: %d\n", ret);
154154 return ERR_PTR(ret);
drivers/gpu/drm/armada/armada_fbdev.c+3−3
@@ -51,13 +51,13 @@ static int armada_fb_create(struct drm_fb_helper *fbh, · 50 unmodified lines
5151
5252 ret = armada_gem_linear_back(dev, obj);
5353 if (ret) {
54− drm_gem_object_unreference_unlocked(&obj->obj);
54+ drm_gem_object_put_unlocked(&obj->obj);
5555 return ret;
5656 }
5757
5858 ptr = armada_gem_map_object(dev, obj);
5959 if (!ptr) {
60− drm_gem_object_unreference_unlocked(&obj->obj);
60+ drm_gem_object_put_unlocked(&obj->obj);
6161 return -ENOMEM;
6262 }
6363
@@ -67,7 +67,7 @@ static int armada_fb_create(struct drm_fb_helper *fbh, · 3 unmodified lines
6767 * A reference is now held by the framebuffer object if
6868 * successful, otherwise this drops the ref for the error path.
6969 */
70− drm_gem_object_unreference_unlocked(&obj->obj);
70+ drm_gem_object_put_unlocked(&obj->obj);
7171
7272 if (IS_ERR(dfb))
7373 return PTR_ERR(dfb);
drivers/gpu/drm/armada/armada_gem.c+6−6
@@ -265,7 +265,7 @@ int armada_gem_dumb_create(struct drm_file *file, struct drm_device *dev, · 264 unmodified lines
265265 /* drop reference from allocate - handle holds it now */
266266 DRM_DEBUG_DRIVER("obj %p size %zu handle %#x\n", dobj, size, handle);
267267 err:
268− drm_gem_object_unreference_unlocked(&dobj->obj);
268+ drm_gem_object_put_unlocked(&dobj->obj);
269269 return ret;
270270 }
271271
@@ -297,7 +297,7 @@ int armada_gem_create_ioctl(struct drm_device *dev, void *data, · 25 unmodified lines
297297 /* drop reference from allocate - handle holds it now */
298298 DRM_DEBUG_DRIVER("obj %p size %zu handle %#x\n", dobj, size, handle);
299299 err:
300− drm_gem_object_unreference_unlocked(&dobj->obj);
300+ drm_gem_object_put_unlocked(&dobj->obj);
301301 return ret;
302302 }
303303
@@ -314,13 +314,13 @@ int armada_gem_mmap_ioctl(struct drm_device *dev, void *data, · 10 unmodified lines
314314 return -ENOENT;
315315
316316 if (!dobj->obj.filp) {
317− drm_gem_object_unreference_unlocked(&dobj->obj);
317+ drm_gem_object_put_unlocked(&dobj->obj);
318318 return -EINVAL;
319319 }
320320
321321 addr = vm_mmap(dobj->obj.filp, 0, args->size, PROT_READ | PROT_WRITE,
322322 MAP_SHARED, args->offset);
323− drm_gem_object_unreference_unlocked(&dobj->obj);
323+ drm_gem_object_put_unlocked(&dobj->obj);
324324 if (IS_ERR_VALUE(addr))
325325 return addr;
326326
@@ -375,7 +375,7 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data, · 48 unmodified lines
375375 }
376376
377377 unref:
378− drm_gem_object_unreference_unlocked(&dobj->obj);
378+ drm_gem_object_put_unlocked(&dobj->obj);
379379 return ret;
380380 }
381381
@@ -524,7 +524,7 @@ armada_gem_prime_import(struct drm_device *dev, struct dma_buf *buf) · 142 unmodified lines
524524 * Importing our own dmabuf(s) increases the
525525 * refcount on the gem object itself.
526526 */
527− drm_gem_object_reference(obj);
527+ drm_gem_object_get(obj);
528528 return obj;
529529 }
530530 }
drivers/gpu/drm/armada/armada_overlay.c+2−2
@@ -177,7 +177,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, · 176 unmodified lines
177177 * Take a reference on the new framebuffer - we want to
178178 * hold on to it while the hardware is displaying it.
179179 */
180− drm_framebuffer_reference(fb);
180+ drm_framebuffer_get(fb);
181181
182182 if (plane->fb)
183183 armada_ovl_retire_fb(dplane, plane->fb);
@@ -278,7 +278,7 @@ static int armada_ovl_plane_disable(struct drm_plane *plane, · 94 unmodified lines
278278
279279 fb = xchg(&dplane->old_fb, NULL);
280280 if (fb)
281− drm_framebuffer_unreference(fb);
281+ drm_framebuffer_put(fb);
282282
283283 return 0;
284284 }
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c+2−2
@@ -607,10 +607,10 @@ static int adv7511_get_modes(struct adv7511 *adv7511, · 606 unmodified lines
607607 adv7511_set_config_csc(adv7511, connector, adv7511->rgb,
608608 drm_detect_hdmi_monitor(edid));
609609
610− kfree(edid);
611−
612610 cec_s_phys_addr_from_edid(adv7511->cec_adap, edid);
613611
612+ kfree(edid);
613+
614614 return count;
615615 }
616616
drivers/gpu/drm/drm_atomic_helper.c+18−10
@@ -860,6 +860,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) · 859 unmodified lines
860860
861861 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
862862 const struct drm_crtc_helper_funcs *funcs;
863+ int ret;
863864
864865 /* Shut down everything that needs a full modeset. */
865866 if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
@@ -883,6 +884,14 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) · 17 unmodified lines
883884 funcs->disable(crtc);
884885 else
885886 funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
887+
888+ if (!(dev->irq_enabled && dev->num_crtcs))
889+ continue;
890+
891+ ret = drm_crtc_vblank_get(crtc);
892+ WARN_ONCE(ret != -EINVAL, "driver forgot to call drm_crtc_vblank_off()\n");
893+ if (ret == 0)
894+ drm_crtc_vblank_put(crtc);
886895 }
887896 }
888897
@@ -1772,16 +1781,16 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, · 883 unmodified lines
17721781 }
17731782
17741783 for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) {
1775− /* commit tracked through new_crtc_state->commit, no need to do it explicitly */
1776− if (new_conn_state->crtc)
1777− continue;
1778−
17791784 /* Userspace is not allowed to get ahead of the previous
17801785 * commit with nonblocking ones. */
17811786 if (nonblock && old_conn_state->commit &&
17821787 !try_wait_for_completion(&old_conn_state->commit->flip_done))
17831788 return -EBUSY;
17841789
1790+ /* commit tracked through new_crtc_state->commit, no need to do it explicitly */
1791+ if (new_conn_state->crtc)
1792+ continue;
1793+
17851794 commit = crtc_or_fake_commit(state, old_conn_state->crtc);
17861795 if (!commit)
17871796 return -ENOMEM;
@@ -1790,18 +1799,17 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, · 2 unmodified lines
17901799 }
17911800
17921801 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
1793− /*
1794− * Unlike connectors, always track planes explicitly for
1795− * async pageflip support.
1796− */
1797−
17981802 /* Userspace is not allowed to get ahead of the previous
17991803 * commit with nonblocking ones. */
18001804 if (nonblock && old_plane_state->commit &&
18011805 !try_wait_for_completion(&old_plane_state->commit->flip_done))
18021806 return -EBUSY;
18031807
1804− commit = crtc_or_fake_commit(state, old_plane_state->crtc);
1808+ /*
1809+ * Unlike connectors, always track planes explicitly for
1810+ * async pageflip support.
1811+ */
1812+ commit = crtc_or_fake_commit(state, new_plane_state->crtc ?: old_plane_state->crtc);
18051813 if (!commit)
18061814 return -ENOMEM;
18071815
drivers/gpu/drm/drm_gem_cma_helper.c+1−1
@@ -112,7 +112,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, · 111 unmodified lines
112112 cma_obj->vaddr = dma_alloc_wc(drm->dev, size, &cma_obj->paddr,
113113 GFP_KERNEL | __GFP_NOWARN);
114114 if (!cma_obj->vaddr) {
115− dev_err(drm->dev, "failed to allocate buffer with size %zu\n",
115+ dev_dbg(drm->dev, "failed to allocate buffer with size %zu\n",
116116 size);
117117 ret = -ENOMEM;
118118 goto error;
drivers/gpu/drm/panel/panel-simple.c+34−2
@@ -1008,6 +1008,10 @@ static const struct panel_desc hitachi_tx23d38vm0caa = { · 1007 unmodified lines
10081008 .width = 195,
10091009 .height = 117,
10101010 },
1011+ .delay = {
1012+ .enable = 160,
1013+ .disable = 160,
1014+ },
10111015 };
10121016
10131017 static const struct drm_display_mode innolux_at043tn24_mode = {
@@ -1018,8 +1022,8 @@ static const struct drm_display_mode innolux_at043tn24_mode = { · 4 unmodified lines
10181022 .htotal = 480 + 2 + 41 + 2,
10191023 .vdisplay = 272,
10201024 .vsync_start = 272 + 2,
1021− .vsync_end = 272 + 2 + 11,
1022− .vtotal = 272 + 2 + 11 + 2,
1025+ .vsync_end = 272 + 2 + 10,
1026+ .vtotal = 272 + 2 + 10 + 2,
10231027 .vrefresh = 60,
10241028 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
10251029 };
@@ -1033,6 +1037,7 @@ static const struct panel_desc innolux_at043tn24 = { · 7 unmodified lines
10331037 .height = 54,
10341038 },
10351039 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1040+ .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE,
10361041 };
10371042
10381043 static const struct drm_display_mode innolux_at070tn92_mode = {
@@ -1832,6 +1837,30 @@ static const struct panel_desc tianma_tm070jdhg30 = { · 793 unmodified lines
18321837 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
18331838 };
18341839
1840+static const struct drm_display_mode toshiba_lt089ac29000_mode = {
1841+ .clock = 79500,
1842+ .hdisplay = 1280,
1843+ .hsync_start = 1280 + 192,
1844+ .hsync_end = 1280 + 192 + 128,
1845+ .htotal = 1280 + 192 + 128 + 64,
1846+ .vdisplay = 768,
1847+ .vsync_start = 768 + 20,
1848+ .vsync_end = 768 + 20 + 7,
1849+ .vtotal = 768 + 20 + 7 + 3,
1850+ .vrefresh = 60,
1851+};
1852+
1853+static const struct panel_desc toshiba_lt089ac29000 = {
1854+ .modes = &toshiba_lt089ac29000_mode,
1855+ .num_modes = 1,
1856+ .size = {
1857+ .width = 194,
1858+ .height = 116,
1859+ },
1860+ .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1861+ .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE,
1862+};
1863+
18351864 static const struct drm_display_mode tpk_f07a_0102_mode = {
18361865 .clock = 33260,
18371866 .hdisplay = 800,
@@ -2113,6 +2142,9 @@ static const struct of_device_id platform_of_match[] = { · 275 unmodified lines
21132142 }, {
21142143 .compatible = "tianma,tm070jdhg30",
21152144 .data = &tianma_tm070jdhg30,
2145+ }, {
2146+ .compatible = "toshiba,lt089ac29000",
2147+ .data = &toshiba_lt089ac29000,
21162148 }, {
21172149 .compatible = "tpk,f07a-0102",
21182150 .data = &tpk_f07a_0102,
drivers/gpu/drm/sun4i/Makefile+17−16
@@ -1,24 +1,25 @@
1−sun4i-drm-y += sun4i_drv.o
2−sun4i-drm-y += sun4i_framebuffer.o
1+sun4i-backend-y += sun4i_backend.o sun4i_layer.o
32
4−sun4i-drm-hdmi-y += sun4i_hdmi_enc.o
5−sun4i-drm-hdmi-y += sun4i_hdmi_i2c.o
6−sun4i-drm-hdmi-y += sun4i_hdmi_ddc_clk.o
7−sun4i-drm-hdmi-y += sun4i_hdmi_tmds_clk.o
3+sun4i-drm-y += sun4i_drv.o
4+sun4i-drm-y += sun4i_framebuffer.o
85
9−sun4i-tcon-y += sun4i_tcon.o
10−sun4i-tcon-y += sun4i_rgb.o
11−sun4i-tcon-y += sun4i_dotclock.o
12−sun4i-tcon-y += sun4i_crtc.o
6+sun4i-drm-hdmi-y += sun4i_hdmi_ddc_clk.o
7+sun4i-drm-hdmi-y += sun4i_hdmi_enc.o
8+sun4i-drm-hdmi-y += sun4i_hdmi_i2c.o
9+sun4i-drm-hdmi-y += sun4i_hdmi_tmds_clk.o
1310
14−sun4i-backend-y += sun4i_backend.o sun4i_layer.o
11+sun8i-mixer-y += sun8i_mixer.o sun8i_layer.o
1512
16−sun8i-mixer-y += sun8i_mixer.o sun8i_layer.o
13+sun4i-tcon-y += sun4i_crtc.o
14+sun4i-tcon-y += sun4i_dotclock.o
15+sun4i-tcon-y += sun4i_tcon.o
16+sun4i-tcon-y += sun4i_rgb.o
1717
18−obj-$(CONFIG_DRM_SUN4I) += sun4i-drm.o sun4i-tcon.o
19−obj-$(CONFIG_DRM_SUN4I) += sun6i_drc.o
18+obj-$(CONFIG_DRM_SUN4I) += sun4i-drm.o
19+obj-$(CONFIG_DRM_SUN4I) += sun4i-tcon.o
2020 obj-$(CONFIG_DRM_SUN4I) += sun4i_tv.o
21+obj-$(CONFIG_DRM_SUN4I) += sun6i_drc.o
2122
22−obj-$(CONFIG_DRM_SUN4I_BACKEND) += sun4i-backend.o
23+obj-$(CONFIG_DRM_SUN4I_BACKEND) += sun4i-backend.o
2324 obj-$(CONFIG_DRM_SUN4I_HDMI) += sun4i-drm-hdmi.o
24−obj-$(CONFIG_DRM_SUN8I_MIXER) += sun8i-mixer.o
25+obj-$(CONFIG_DRM_SUN8I_MIXER) += sun8i-mixer.o
drivers/gpu/drm/sun4i/sun4i_backend.c+72−3
@@ -20,6 +20,7 @@ · 19 unmodified lines
2020
2121 #include <linux/component.h>
2222 #include <linux/list.h>
23+#include <linux/of_device.h>
2324 #include <linux/of_graph.h>
2425 #include <linux/reset.h>
2526
@@ -28,6 +29,11 @@ · 2 unmodified lines
2829 #include "sun4i_layer.h"
2930 #include "sunxi_engine.h"
3031
32+struct sun4i_backend_quirks {
33+ /* backend <-> TCON muxing selection done in backend */
34+ bool needs_output_muxing;
35+};
36+
3137 static const u32 sunxi_rgb2yuv_coef[12] = {
3238 0x00000107, 0x00000204, 0x00000064, 0x00000108,
3339 0x00003f69, 0x00003ed6, 0x000001c1, 0x00000808,
@@ -216,6 +222,13 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, · 182 unmodified lines
216222 paddr = drm_fb_cma_get_gem_addr(fb, state, 0);
217223 DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr);
218224
225+ /*
226+ * backend DMA accesses DRAM directly, bypassing the system
227+ * bus. As such, the address range is different and the buffer
228+ * address needs to be corrected.
229+ */
230+ paddr -= PHYS_OFFSET;
231+
219232 /* Write the 32 lower bits of the address (in bits) */
220233 lo_paddr = paddr << 3;
221234 DRM_DEBUG_DRIVER("Setting address lower bits to 0x%x\n", lo_paddr);
@@ -338,6 +351,7 @@ static int sun4i_backend_bind(struct device *dev, struct device *master, · 116 unmodified lines
338351 struct drm_device *drm = data;
339352 struct sun4i_drv *drv = drm->dev_private;
340353 struct sun4i_backend *backend;
354+ const struct sun4i_backend_quirks *quirks;
341355 struct resource *res;
342356 void __iomem *regs;
343357 int i, ret;
@@ -432,6 +446,27 @@ static int sun4i_backend_bind(struct device *dev, struct device *master, · 88 unmodified lines
432446 SUN4I_BACKEND_MODCTL_DEBE_EN |
433447 SUN4I_BACKEND_MODCTL_START_CTL);
434448
449+ /* Set output selection if needed */
450+ quirks = of_device_get_match_data(dev);
451+ if (quirks->needs_output_muxing) {
452+ /*
453+ * We assume there is no dynamic muxing of backends
454+ * and TCONs, so we select the backend with same ID.
455+ *
456+ * While dynamic selection might be interesting, since
457+ * the CRTC is tied to the TCON, while the layers are
458+ * tied to the backends, this means, we will need to
459+ * switch between groups of layers. There might not be
460+ * a way to represent this constraint in DRM.
461+ */
462+ regmap_update_bits(backend->engine.regs,
463+ SUN4I_BACKEND_MODCTL_REG,
464+ SUN4I_BACKEND_MODCTL_OUT_SEL,
465+ (backend->engine.id
466+ ? SUN4I_BACKEND_MODCTL_OUT_LCD1
467+ : SUN4I_BACKEND_MODCTL_OUT_LCD0));
468+ }
469+
435470 return 0;
436471
437472 err_disable_ram_clk:
@@ -479,10 +514,44 @@ static int sun4i_backend_remove(struct platform_device *pdev) · 41 unmodified lines
479514 return 0;
480515 }
481516
517+static const struct sun4i_backend_quirks sun4i_backend_quirks = {
518+ .needs_output_muxing = true,
519+};
520+
521+static const struct sun4i_backend_quirks sun5i_backend_quirks = {
522+};
523+
524+static const struct sun4i_backend_quirks sun6i_backend_quirks = {
525+};
526+
527+static const struct sun4i_backend_quirks sun7i_backend_quirks = {
528+ .needs_output_muxing = true,
529+};
530+
531+static const struct sun4i_backend_quirks sun8i_a33_backend_quirks = {
532+};
533+
482534 static const struct of_device_id sun4i_backend_of_table[] = {
483− { .compatible = "allwinner,sun5i-a13-display-backend" },
484− { .compatible = "allwinner,sun6i-a31-display-backend" },
485− { .compatible = "allwinner,sun8i-a33-display-backend" },
535+ {
536+ .compatible = "allwinner,sun4i-a10-display-backend",
537+ .data = &sun4i_backend_quirks,
538+ },
539+ {
540+ .compatible = "allwinner,sun5i-a13-display-backend",
541+ .data = &sun5i_backend_quirks,
542+ },
543+ {
544+ .compatible = "allwinner,sun6i-a31-display-backend",
545+ .data = &sun6i_backend_quirks,
546+ },
547+ {
548+ .compatible = "allwinner,sun7i-a20-display-backend",
549+ .data = &sun7i_backend_quirks,
550+ },
551+ {
552+ .compatible = "allwinner,sun8i-a33-display-backend",
553+ .data = &sun8i_a33_backend_quirks,
554+ },
486555 { }
487556 };
488557 MODULE_DEVICE_TABLE(of, sun4i_backend_of_table);
drivers/gpu/drm/sun4i/sun4i_backend.h+2−1
@@ -25,7 +25,8 @@ · 24 unmodified lines
2525 #define SUN4I_BACKEND_MODCTL_LINE_SEL BIT(29)
2626 #define SUN4I_BACKEND_MODCTL_ITLMOD_EN BIT(28)
2727 #define SUN4I_BACKEND_MODCTL_OUT_SEL GENMASK(22, 20)
28−#define SUN4I_BACKEND_MODCTL_OUT_LCD (0 << 20)
28+#define SUN4I_BACKEND_MODCTL_OUT_LCD0 (0 << 20)
29+#define SUN4I_BACKEND_MODCTL_OUT_LCD1 (1 << 20)
2930 #define SUN4I_BACKEND_MODCTL_OUT_FE0 (6 << 20)
3031 #define SUN4I_BACKEND_MODCTL_OUT_FE1 (7 << 20)
3132 #define SUN4I_BACKEND_MODCTL_HWC_EN BIT(16)
drivers/gpu/drm/sun4i/sun4i_crtc.c+30−2
@@ -30,6 +30,22 @@ · 29 unmodified lines
3030 #include "sunxi_engine.h"
3131 #include "sun4i_tcon.h"
3232
33+/*
34+ * While this isn't really working in the DRM theory, in practice we
35+ * can only ever have one encoder per TCON since we have a mux in our
36+ * TCON.
37+ */
38+static struct drm_encoder *sun4i_crtc_get_encoder(struct drm_crtc *crtc)
39+{
40+ struct drm_encoder *encoder;
41+
42+ drm_for_each_encoder(encoder, crtc->dev)
43+ if (encoder->crtc == crtc)
44+ return encoder;
45+
46+ return NULL;
47+}
48+
3349 static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc,
3450 struct drm_crtc_state *old_state)
3551 {
@@ -72,11 +88,12 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc, · 36 unmodified lines
7288 static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc,
7389 struct drm_crtc_state *old_state)
7490 {
91+ struct drm_encoder *encoder = sun4i_crtc_get_encoder(crtc);
7592 struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
7693
7794 DRM_DEBUG_DRIVER("Disabling the CRTC\n");
7895
79− sun4i_tcon_disable(scrtc->tcon);
96+ sun4i_tcon_set_status(scrtc->tcon, encoder, false);
8097
8198 if (crtc->state->event && !crtc->state->active) {
8299 spin_lock_irq(&crtc->dev->event_lock);
@@ -90,11 +107,21 @@ static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc, · 7 unmodified lines
90107 static void sun4i_crtc_atomic_enable(struct drm_crtc *crtc,
91108 struct drm_crtc_state *old_state)
92109 {
110+ struct drm_encoder *encoder = sun4i_crtc_get_encoder(crtc);
93111 struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
94112
95113 DRM_DEBUG_DRIVER("Enabling the CRTC\n");
96114
97− sun4i_tcon_enable(scrtc->tcon);
115+ sun4i_tcon_set_status(scrtc->tcon, encoder, true);
116+}
117+
118+static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc)
119+{
120+ struct drm_display_mode *mode = &crtc->state->adjusted_mode;
121+ struct drm_encoder *encoder = sun4i_crtc_get_encoder(crtc);
122+ struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
123+
124+ sun4i_tcon_mode_set(scrtc->tcon, encoder, mode);
98125 }
99126
100127 static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = {
@@ -102,6 +129,7 @@ static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = { · 1 unmodified line
102129 .atomic_flush = sun4i_crtc_atomic_flush,
103130 .atomic_enable = sun4i_crtc_atomic_enable,
104131 .atomic_disable = sun4i_crtc_atomic_disable,
132+ .mode_set_nofb = sun4i_crtc_mode_set_nofb,
105133 };
106134
107135 static int sun4i_crtc_enable_vblank(struct drm_crtc *crtc)
drivers/gpu/drm/sun4i/sun4i_drv.c+21−60
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 */
1212
1313 #include <linux/component.h>
14+#include <linux/kfifo.h>
1415 #include <linux/of_graph.h>
1516 #include <linux/of_reserved_mem.h>
1617
@@ -177,16 +178,20 @@ static bool sun4i_drv_node_is_connector(struct device_node *node) · 160 unmodified lines
177178
178179 static bool sun4i_drv_node_is_frontend(struct device_node *node)
179180 {
180− return of_device_is_compatible(node, "allwinner,sun5i-a13-display-frontend") ||
181+ return of_device_is_compatible(node, "allwinner,sun4i-a10-display-frontend") ||
182+ of_device_is_compatible(node, "allwinner,sun5i-a13-display-frontend") ||
181183 of_device_is_compatible(node, "allwinner,sun6i-a31-display-frontend") ||
184+ of_device_is_compatible(node, "allwinner,sun7i-a20-display-frontend") ||
182185 of_device_is_compatible(node, "allwinner,sun8i-a33-display-frontend");
183186 }
184187
185188 static bool sun4i_drv_node_is_tcon(struct device_node *node)
186189 {
187− return of_device_is_compatible(node, "allwinner,sun5i-a13-tcon") ||
190+ return of_device_is_compatible(node, "allwinner,sun4i-a10-tcon") ||
191+ of_device_is_compatible(node, "allwinner,sun5i-a13-tcon") ||
188192 of_device_is_compatible(node, "allwinner,sun6i-a31-tcon") ||
189193 of_device_is_compatible(node, "allwinner,sun6i-a31s-tcon") ||
194+ of_device_is_compatible(node, "allwinner,sun7i-a20-tcon") ||
190195 of_device_is_compatible(node, "allwinner,sun8i-a33-tcon") ||
191196 of_device_is_compatible(node, "allwinner,sun8i-v3s-tcon");
192197 }
@@ -222,29 +227,15 @@ static int compare_of(struct device *dev, void *data) · 29 unmodified lines
222227 * matching system handles this for us.
223228 */
224229 struct endpoint_list {
225− struct device_node *node;
226− struct list_head list;
230+ DECLARE_KFIFO(fifo, struct device_node *, 16);
227231 };
228232
229−static bool node_is_in_list(struct list_head *endpoints,
230− struct device_node *node)
231−{
232− struct endpoint_list *endpoint;
233−
234− list_for_each_entry(endpoint, endpoints, list)
235− if (endpoint->node == node)
236− return true;
237−
238− return false;
239−}
240−
241233 static int sun4i_drv_add_endpoints(struct device *dev,
242− struct list_head *endpoints,
234+ struct endpoint_list *list,
243235 struct component_match **match,
244236 struct device_node *node)
245237 {
246238 struct device_node *port, *ep, *remote;
247− struct endpoint_list *endpoint;
248239 int count = 0;
249240
250241 /*
@@ -304,19 +295,7 @@ static int sun4i_drv_add_endpoints(struct device *dev, · 53 unmodified lines
304295 }
305296 }
306297
307− /* skip downstream node if it is already in the queue */
308− if (node_is_in_list(endpoints, remote))
309− continue;
310−
311− /* Add downstream nodes to the queue */
312− endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL);
313− if (!endpoint) {
314− of_node_put(remote);
315− return -ENOMEM;
316− }
317−
318− endpoint->node = remote;
319− list_add_tail(&endpoint->list, endpoints);
298+ kfifo_put(&list->fifo, remote);
320299 }
321300
322301 return count;
@@ -325,10 +304,11 @@ static int sun4i_drv_add_endpoints(struct device *dev, · 2 unmodified lines
325304 static int sun4i_drv_probe(struct platform_device *pdev)
326305 {
327306 struct component_match *match = NULL;
328− struct device_node *np = pdev->dev.of_node;
329− struct endpoint_list *endpoint, *endpoint_temp;
307+ struct device_node *np = pdev->dev.of_node, *endpoint;
308+ struct endpoint_list list;
330309 int i, ret, count = 0;
331− LIST_HEAD(endpoints);
310+
311+ INIT_KFIFO(list.fifo);
332312
333313 for (i = 0;; i++) {
334314 struct device_node *pipeline = of_parse_phandle(np,
@@ -337,31 +317,19 @@ static int sun4i_drv_probe(struct platform_device *pdev) · 2 unmodified lines
337317 if (!pipeline)
338318 break;
339319
340− endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL);
341− if (!endpoint) {
342− ret = -ENOMEM;
343− goto err_free_endpoints;
344− }
345−
346− endpoint->node = pipeline;
347− list_add_tail(&endpoint->list, &endpoints);
320+ kfifo_put(&list.fifo, pipeline);
348321 }
349322
350− list_for_each_entry_safe(endpoint, endpoint_temp, &endpoints, list) {
323+ while (kfifo_get(&list.fifo, &endpoint)) {
351324 /* process this endpoint */
352− ret = sun4i_drv_add_endpoints(&pdev->dev, &endpoints, &match,
353− endpoint->node);
325+ ret = sun4i_drv_add_endpoints(&pdev->dev, &list, &match,
326+ endpoint);
354327
355328 /* sun4i_drv_add_endpoints can fail to allocate memory */
356329 if (ret < 0)
357− goto err_free_endpoints;
330+ return ret;
358331
359332 count += ret;
360−
361− /* delete and cleanup the current entry */
362− list_del(&endpoint->list);
363− of_node_put(endpoint->node);
364− kfree(endpoint);
365333 }
366334
367335 if (count)
@@ -370,15 +338,6 @@ static int sun4i_drv_probe(struct platform_device *pdev) · 2 unmodified lines
370338 match);
371339 else
372340 return 0;
373−
374−err_free_endpoints:
375− list_for_each_entry_safe(endpoint, endpoint_temp, &endpoints, list) {
376− list_del(&endpoint->list);
377− of_node_put(endpoint->node);
378− kfree(endpoint);
379− }
380−
381− return ret;
382341 }
383342
384343 static int sun4i_drv_remove(struct platform_device *pdev)
@@ -387,10 +346,12 @@ static int sun4i_drv_remove(struct platform_device *pdev) · 2 unmodified lines
387346 }
388347
389348 static const struct of_device_id sun4i_drv_of_table[] = {
349+ { .compatible = "allwinner,sun4i-a10-display-engine" },
390350 { .compatible = "allwinner,sun5i-a10s-display-engine" },
391351 { .compatible = "allwinner,sun5i-a13-display-engine" },
392352 { .compatible = "allwinner,sun6i-a31-display-engine" },
393353 { .compatible = "allwinner,sun6i-a31s-display-engine" },
354+ { .compatible = "allwinner,sun7i-a20-display-engine" },
394355 { .compatible = "allwinner,sun8i-a33-display-engine" },
395356 { .compatible = "allwinner,sun8i-v3s-display-engine" },
396357 { }
drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c+0−1
@@ -13,7 +13,6 @@ · 12 unmodified lines
1313 #include <linux/clk-provider.h>
1414 #include <linux/regmap.h>
1515
16−#include "sun4i_tcon.h"
1716 #include "sun4i_hdmi.h"
1817
1918 struct sun4i_ddc {
drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c+53−15
@@ -30,7 +30,6 @@ · 29 unmodified lines
3030 #include "sun4i_crtc.h"
3131 #include "sun4i_drv.h"
3232 #include "sun4i_hdmi.h"
33−#include "sun4i_tcon.h"
3433
3534 static inline struct sun4i_hdmi *
3635 drm_encoder_to_sun4i_hdmi(struct drm_encoder *encoder)
@@ -86,8 +85,6 @@ static int sun4i_hdmi_atomic_check(struct drm_encoder *encoder, · 49 unmodified lines
8685 static void sun4i_hdmi_disable(struct drm_encoder *encoder)
8786 {
8887 struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
89− struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
90− struct sun4i_tcon *tcon = crtc->tcon;
9188 u32 val;
9289
9390 DRM_DEBUG_DRIVER("Disabling the HDMI Output\n");
@@ -95,22 +92,16 @@ static void sun4i_hdmi_disable(struct drm_encoder *encoder) · 1 unmodified line
9592 val = readl(hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
9693 val &= ~SUN4I_HDMI_VID_CTRL_ENABLE;
9794 writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
98−
99− sun4i_tcon_channel_disable(tcon, 1);
10095 }
10196
10297 static void sun4i_hdmi_enable(struct drm_encoder *encoder)
10398 {
10499 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
105100 struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
106− struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
107− struct sun4i_tcon *tcon = crtc->tcon;
108101 u32 val = 0;
109102
110103 DRM_DEBUG_DRIVER("Enabling the HDMI Output\n");
111104
112− sun4i_tcon_channel_enable(tcon, 1);
113−
114105 sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
115106 val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
116107 val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
@@ -128,15 +119,9 @@ static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, · 11 unmodified lines
128119 struct drm_display_mode *adjusted_mode)
129120 {
130121 struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
131− struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
132− struct sun4i_tcon *tcon = crtc->tcon;
133122 unsigned int x, y;
134123 u32 val;
135124
136− sun4i_tcon1_mode_set(tcon, mode);
137− sun4i_tcon_set_mux(tcon, 1, encoder);
138−
139− clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000);
140125 clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000);
141126 clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000);
142127
@@ -289,6 +274,58 @@ static const struct cec_pin_ops sun4i_hdmi_cec_pin_ops = { · 146 unmodified lines
289274 #define SUN4I_HDMI_PAD_CTRL1_MASK (GENMASK(24, 7) | GENMASK(5, 0))
290275 #define SUN4I_HDMI_PLL_CTRL_MASK (GENMASK(31, 8) | GENMASK(3, 0))
291276
277+/* Only difference from sun5i is AMP is 4 instead of 6 */
278+static const struct sun4i_hdmi_variant sun4i_variant = {
279+ .pad_ctrl0_init_val = SUN4I_HDMI_PAD_CTRL0_TXEN |
280+ SUN4I_HDMI_PAD_CTRL0_CKEN |
281+ SUN4I_HDMI_PAD_CTRL0_PWENG |
282+ SUN4I_HDMI_PAD_CTRL0_PWEND |
283+ SUN4I_HDMI_PAD_CTRL0_PWENC |
284+ SUN4I_HDMI_PAD_CTRL0_LDODEN |
285+ SUN4I_HDMI_PAD_CTRL0_LDOCEN |
286+ SUN4I_HDMI_PAD_CTRL0_BIASEN,
287+ .pad_ctrl1_init_val = SUN4I_HDMI_PAD_CTRL1_REG_AMP(4) |
288+ SUN4I_HDMI_PAD_CTRL1_REG_EMP(2) |
289+ SUN4I_HDMI_PAD_CTRL1_REG_DENCK |
290+ SUN4I_HDMI_PAD_CTRL1_REG_DEN |
291+ SUN4I_HDMI_PAD_CTRL1_EMPCK_OPT |
292+ SUN4I_HDMI_PAD_CTRL1_EMP_OPT |
293+ SUN4I_HDMI_PAD_CTRL1_AMPCK_OPT |
294+ SUN4I_HDMI_PAD_CTRL1_AMP_OPT,
295+ .pll_ctrl_init_val = SUN4I_HDMI_PLL_CTRL_VCO_S(8) |
296+ SUN4I_HDMI_PLL_CTRL_CS(7) |
297+ SUN4I_HDMI_PLL_CTRL_CP_S(15) |
298+ SUN4I_HDMI_PLL_CTRL_S(7) |
299+ SUN4I_HDMI_PLL_CTRL_VCO_GAIN(4) |
300+ SUN4I_HDMI_PLL_CTRL_SDIV2 |
301+ SUN4I_HDMI_PLL_CTRL_LDO2_EN |
302+ SUN4I_HDMI_PLL_CTRL_LDO1_EN |
303+ SUN4I_HDMI_PLL_CTRL_HV_IS_33 |
304+ SUN4I_HDMI_PLL_CTRL_BWS |
305+ SUN4I_HDMI_PLL_CTRL_PLL_EN,
306+
307+ .ddc_clk_reg = REG_FIELD(SUN4I_HDMI_DDC_CLK_REG, 0, 6),
308+ .ddc_clk_pre_divider = 2,
309+ .ddc_clk_m_offset = 1,
310+
311+ .field_ddc_en = REG_FIELD(SUN4I_HDMI_DDC_CTRL_REG, 31, 31),
312+ .field_ddc_start = REG_FIELD(SUN4I_HDMI_DDC_CTRL_REG, 30, 30),
313+ .field_ddc_reset = REG_FIELD(SUN4I_HDMI_DDC_CTRL_REG, 0, 0),
314+ .field_ddc_addr_reg = REG_FIELD(SUN4I_HDMI_DDC_ADDR_REG, 0, 31),
315+ .field_ddc_slave_addr = REG_FIELD(SUN4I_HDMI_DDC_ADDR_REG, 0, 6),
316+ .field_ddc_int_status = REG_FIELD(SUN4I_HDMI_DDC_INT_STATUS_REG, 0, 8),
317+ .field_ddc_fifo_clear = REG_FIELD(SUN4I_HDMI_DDC_FIFO_CTRL_REG, 31, 31),
318+ .field_ddc_fifo_rx_thres = REG_FIELD(SUN4I_HDMI_DDC_FIFO_CTRL_REG, 4, 7),
319+ .field_ddc_fifo_tx_thres = REG_FIELD(SUN4I_HDMI_DDC_FIFO_CTRL_REG, 0, 3),
320+ .field_ddc_byte_count = REG_FIELD(SUN4I_HDMI_DDC_BYTE_COUNT_REG, 0, 9),
321+ .field_ddc_cmd = REG_FIELD(SUN4I_HDMI_DDC_CMD_REG, 0, 2),
322+ .field_ddc_sda_en = REG_FIELD(SUN4I_HDMI_DDC_LINE_CTRL_REG, 9, 9),
323+ .field_ddc_sck_en = REG_FIELD(SUN4I_HDMI_DDC_LINE_CTRL_REG, 8, 8),
324+
325+ .ddc_fifo_reg = SUN4I_HDMI_DDC_FIFO_DATA_REG,
326+ .ddc_fifo_has_dir = true,
327+};
328+
292329 static const struct sun4i_hdmi_variant sun5i_variant = {
293330 .pad_ctrl0_init_val = SUN4I_HDMI_PAD_CTRL0_TXEN |
294331 SUN4I_HDMI_PAD_CTRL0_CKEN |
@@ -613,6 +650,7 @@ static int sun4i_hdmi_remove(struct platform_device *pdev) · 318 unmodified lines
613650 }
614651
615652 static const struct of_device_id sun4i_hdmi_of_table[] = {
653+ { .compatible = "allwinner,sun4i-a10-hdmi", .data = &sun4i_variant, },
616654 { .compatible = "allwinner,sun5i-a10s-hdmi", .data = &sun5i_variant, },
617655 { .compatible = "allwinner,sun6i-a31-hdmi", .data = &sun6i_variant, },
618656 { }
drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c+0−1
@@ -12,7 +12,6 @@ · 11 unmodified lines
1212
1313 #include <linux/clk-provider.h>
1414
15−#include "sun4i_tcon.h"
1615 #include "sun4i_hdmi.h"
1716
1817 struct sun4i_tmds {
drivers/gpu/drm/sun4i/sun4i_rgb.c+4−25
@@ -134,13 +134,10 @@ static void sun4i_rgb_encoder_enable(struct drm_encoder *encoder) · 133 unmodified lines
134134
135135 DRM_DEBUG_DRIVER("Enabling RGB output\n");
136136
137− if (!IS_ERR(tcon->panel))
137+ if (!IS_ERR(tcon->panel)) {
138138 drm_panel_prepare(tcon->panel);
139−
140− sun4i_tcon_channel_enable(tcon, 0);
141−
142− if (!IS_ERR(tcon->panel))
143139 drm_panel_enable(tcon->panel);
140+ }
144141 }
145142
146143 static void sun4i_rgb_encoder_disable(struct drm_encoder *encoder)
@@ -150,31 +147,13 @@ static void sun4i_rgb_encoder_disable(struct drm_encoder *encoder) · 3 unmodified lines
150147
151148 DRM_DEBUG_DRIVER("Disabling RGB output\n");
152149
153− if (!IS_ERR(tcon->panel))
150+ if (!IS_ERR(tcon->panel)) {
154151 drm_panel_disable(tcon->panel);
155−
156− sun4i_tcon_channel_disable(tcon, 0);
157−
158− if (!IS_ERR(tcon->panel))
159152 drm_panel_unprepare(tcon->panel);
160−}
161−
162−static void sun4i_rgb_encoder_mode_set(struct drm_encoder *encoder,
163− struct drm_display_mode *mode,
164− struct drm_display_mode *adjusted_mode)
165−{
166− struct sun4i_rgb *rgb = drm_encoder_to_sun4i_rgb(encoder);
167− struct sun4i_tcon *tcon = rgb->tcon;
168−
169− sun4i_tcon0_mode_set(tcon, mode);
170− sun4i_tcon_set_mux(tcon, 0, encoder);
171−
172− /* FIXME: This seems to be board specific */
173− clk_set_phase(tcon->dclk, 120);
153+ }
174154 }
175155
176156 static struct drm_encoder_helper_funcs sun4i_rgb_enc_helper_funcs = {
177− .mode_set = sun4i_rgb_encoder_mode_set,
178157 .disable = sun4i_rgb_encoder_disable,
179158 .enable = sun4i_rgb_encoder_enable,
180159 };
drivers/gpu/drm/sun4i/sun4i_tcon.c+119−64
@@ -35,66 +35,61 @@ · 34 unmodified lines
3535 #include "sun4i_tcon.h"
3636 #include "sunxi_engine.h"
3737
38−void sun4i_tcon_disable(struct sun4i_tcon *tcon)
38+static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
39+ bool enabled)
3940 {
40− DRM_DEBUG_DRIVER("Disabling TCON\n");
41+ struct clk *clk;
4142
42− /* Disable the TCON */
43− regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
44− SUN4I_TCON_GCTL_TCON_ENABLE, 0);
45−}
46−EXPORT_SYMBOL(sun4i_tcon_disable);
47−
48−void sun4i_tcon_enable(struct sun4i_tcon *tcon)
49−{
50− DRM_DEBUG_DRIVER("Enabling TCON\n");
51−
52− /* Enable the TCON */
53− regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
54− SUN4I_TCON_GCTL_TCON_ENABLE,
55− SUN4I_TCON_GCTL_TCON_ENABLE);
56−}
57−EXPORT_SYMBOL(sun4i_tcon_enable);
58−
59−void sun4i_tcon_channel_disable(struct sun4i_tcon *tcon, int channel)
60−{
61− DRM_DEBUG_DRIVER("Disabling TCON channel %d\n", channel);
62−
63− /* Disable the TCON's channel */
64− if (channel == 0) {
43+ switch (channel) {
44+ case 0:
6545 regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
66− SUN4I_TCON0_CTL_TCON_ENABLE, 0);
67− clk_disable_unprepare(tcon->dclk);
46+ SUN4I_TCON0_CTL_TCON_ENABLE,
47+ enabled ? SUN4I_TCON0_CTL_TCON_ENABLE : 0);
48+ clk = tcon->dclk;
49+ break;
50+ case 1:
51+ WARN_ON(!tcon->quirks->has_channel_1);
52+ regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
53+ SUN4I_TCON1_CTL_TCON_ENABLE,
54+ enabled ? SUN4I_TCON1_CTL_TCON_ENABLE : 0);
55+ clk = tcon->sclk1;
56+ break;
57+ default:
58+ DRM_WARN("Unknown channel... doing nothing\n");
6859 return;
6960 }
7061
71− WARN_ON(!tcon->quirks->has_channel_1);
72− regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
73− SUN4I_TCON1_CTL_TCON_ENABLE, 0);
74− clk_disable_unprepare(tcon->sclk1);
62+ if (enabled)
63+ clk_prepare_enable(clk);
64+ else
65+ clk_disable_unprepare(clk);
7566 }
76−EXPORT_SYMBOL(sun4i_tcon_channel_disable);
7767
78−void sun4i_tcon_channel_enable(struct sun4i_tcon *tcon, int channel)
68+void sun4i_tcon_set_status(struct sun4i_tcon *tcon,
69+ const struct drm_encoder *encoder,
70+ bool enabled)
7971 {
80− DRM_DEBUG_DRIVER("Enabling TCON channel %d\n", channel);
72+ int channel;
8173
82− /* Enable the TCON's channel */
83− if (channel == 0) {
84− regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
85− SUN4I_TCON0_CTL_TCON_ENABLE,
86− SUN4I_TCON0_CTL_TCON_ENABLE);
87− clk_prepare_enable(tcon->dclk);
74+ switch (encoder->encoder_type) {
75+ case DRM_MODE_ENCODER_NONE:
76+ channel = 0;
77+ break;
78+ case DRM_MODE_ENCODER_TMDS:
79+ case DRM_MODE_ENCODER_TVDAC:
80+ channel = 1;
81+ break;
82+ default:
83+ DRM_DEBUG_DRIVER("Unknown encoder type, doing nothing...\n");
8884 return;
8985 }
9086
91− WARN_ON(!tcon->quirks->has_channel_1);
92− regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
93− SUN4I_TCON1_CTL_TCON_ENABLE,
94− SUN4I_TCON1_CTL_TCON_ENABLE);
95− clk_prepare_enable(tcon->sclk1);
87+ regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
88+ SUN4I_TCON_GCTL_TCON_ENABLE,
89+ enabled ? SUN4I_TCON_GCTL_TCON_ENABLE : 0);
90+
91+ sun4i_tcon_channel_set_status(tcon, channel, enabled);
9692 }
97−EXPORT_SYMBOL(sun4i_tcon_channel_enable);
9893
9994 void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable)
10095 {
@@ -134,7 +129,7 @@ static struct sun4i_tcon *sun4i_get_tcon0(struct drm_device *drm) · 33 unmodified lines
134129 }
135130
136131 void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel,
137− struct drm_encoder *encoder)
132+ const struct drm_encoder *encoder)
138133 {
139134 int ret = -ENOTSUPP;
140135
@@ -144,9 +139,8 @@ void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel, · 3 unmodified lines
144139 DRM_DEBUG_DRIVER("Muxing encoder %s to CRTC %s: %d\n",
145140 encoder->name, encoder->crtc->name, ret);
146141 }
147−EXPORT_SYMBOL(sun4i_tcon_set_mux);
148142
149−static int sun4i_tcon_get_clk_delay(struct drm_display_mode *mode,
143+static int sun4i_tcon_get_clk_delay(const struct drm_display_mode *mode,
150144 int channel)
151145 {
152146 int delay = mode->vtotal - mode->vdisplay;
@@ -164,15 +158,26 @@ static int sun4i_tcon_get_clk_delay(struct drm_display_mode *mode, · 11 unmodified lines
164158 return delay;
165159 }
166160
167−void sun4i_tcon0_mode_set(struct sun4i_tcon *tcon,
168− struct drm_display_mode *mode)
161+static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
162+ const struct drm_display_mode *mode)
163+{
164+ /* Configure the dot clock */
165+ clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
166+
167+ /* Set the resolution */
168+ regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
169+ SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) |
170+ SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
171+}
172+
173+static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
174+ const struct drm_display_mode *mode)
169175 {
170176 unsigned int bp, hsync, vsync;
171177 u8 clk_delay;
172178 u32 val = 0;
173179
174− /* Configure the dot clock */
175− clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
180+ sun4i_tcon0_mode_set_common(tcon, mode);
176181
177182 /* Adjust clock delay */
178183 clk_delay = sun4i_tcon_get_clk_delay(mode, 0);
@@ -180,11 +185,6 @@ void sun4i_tcon0_mode_set(struct sun4i_tcon *tcon, · 1 unmodified line
180185 SUN4I_TCON0_CTL_CLK_DELAY_MASK,
181186 SUN4I_TCON0_CTL_CLK_DELAY(clk_delay));
182187
183− /* Set the resolution */
184− regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
185− SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) |
186− SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
187−
188188 /*
189189 * This is called a backporch in the register documentation,
190190 * but it really is the back porch + hsync
@@ -238,10 +238,9 @@ void sun4i_tcon0_mode_set(struct sun4i_tcon *tcon, · 47 unmodified lines
238238 /* Enable the output on the pins */
239239 regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0);
240240 }
241−EXPORT_SYMBOL(sun4i_tcon0_mode_set);
242241
243−void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
244− struct drm_display_mode *mode)
242+static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
243+ const struct drm_display_mode *mode)
245244 {
246245 unsigned int bp, hsync, vsync, vtotal;
247246 u8 clk_delay;
@@ -329,7 +328,26 @@ void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, · 81 unmodified lines
329328 SUN4I_TCON_GCTL_IOMAP_MASK,
330329 SUN4I_TCON_GCTL_IOMAP_TCON1);
331330 }
332−EXPORT_SYMBOL(sun4i_tcon1_mode_set);
331+
332+void sun4i_tcon_mode_set(struct sun4i_tcon *tcon,
333+ const struct drm_encoder *encoder,
334+ const struct drm_display_mode *mode)
335+{
336+ switch (encoder->encoder_type) {
337+ case DRM_MODE_ENCODER_NONE:
338+ sun4i_tcon0_mode_set_rgb(tcon, mode);
339+ sun4i_tcon_set_mux(tcon, 0, encoder);
340+ break;
341+ case DRM_MODE_ENCODER_TVDAC:
342+ case DRM_MODE_ENCODER_TMDS:
343+ sun4i_tcon1_mode_set(tcon, mode);
344+ sun4i_tcon_set_mux(tcon, 1, encoder);
345+ break;
346+ default:
347+ DRM_DEBUG_DRIVER("Unknown encoder type, doing nothing...\n");
348+ }
349+}
350+EXPORT_SYMBOL(sun4i_tcon_mode_set);
333351
334352 static void sun4i_tcon_finish_page_flip(struct drm_device *dev,
335353 struct sun4i_crtc *scrtc)
@@ -782,8 +800,32 @@ static int sun4i_tcon_remove(struct platform_device *pdev) · 446 unmodified lines
782800 }
783801
784802 /* platform specific TCON muxing callbacks */
803+static int sun4i_a10_tcon_set_mux(struct sun4i_tcon *tcon,
804+ const struct drm_encoder *encoder)
805+{
806+ struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev);
807+ u32 shift;
808+
809+ if (!tcon0)
810+ return -EINVAL;
811+
812+ switch (encoder->encoder_type) {
813+ case DRM_MODE_ENCODER_TMDS:
814+ /* HDMI */
815+ shift = 8;
816+ break;
817+ default:
818+ return -EINVAL;
819+ }
820+
821+ regmap_update_bits(tcon0->regs, SUN4I_TCON_MUX_CTRL_REG,
822+ 0x3 << shift, tcon->id << shift);
823+
824+ return 0;
825+}
826+
785827 static int sun5i_a13_tcon_set_mux(struct sun4i_tcon *tcon,
786− struct drm_encoder *encoder)
828+ const struct drm_encoder *encoder)
787829 {
788830 u32 val;
789831
@@ -799,7 +841,7 @@ static int sun5i_a13_tcon_set_mux(struct sun4i_tcon *tcon, · 9 unmodified lines
799841 }
800842
801843 static int sun6i_tcon_set_mux(struct sun4i_tcon *tcon,
802− struct drm_encoder *encoder)
844+ const struct drm_encoder *encoder)
803845 {
804846 struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev);
805847 u32 shift;
@@ -823,6 +865,11 @@ static int sun6i_tcon_set_mux(struct sun4i_tcon *tcon, · 17 unmodified lines
823865 return 0;
824866 }
825867
868+static const struct sun4i_tcon_quirks sun4i_a10_quirks = {
869+ .has_channel_1 = true,
870+ .set_mux = sun4i_a10_tcon_set_mux,
871+};
872+
826873 static const struct sun4i_tcon_quirks sun5i_a13_quirks = {
827874 .has_channel_1 = true,
828875 .set_mux = sun5i_a13_tcon_set_mux,
@@ -839,6 +886,12 @@ static const struct sun4i_tcon_quirks sun6i_a31s_quirks = { · 10 unmodified lines
839886 .needs_de_be_mux = true,
840887 };
841888
889+static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
890+ .has_channel_1 = true,
891+ /* Same display pipeline structure as A10 */
892+ .set_mux = sun4i_a10_tcon_set_mux,
893+};
894+
842895 static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
843896 /* nothing is supported */
844897 };
@@ -848,9 +901,11 @@ static const struct sun4i_tcon_quirks sun8i_v3s_quirks = { · 3 unmodified lines
848901 };
849902
850903 static const struct of_device_id sun4i_tcon_of_table[] = {
904+ { .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i_a10_quirks },
851905 { .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks },
852906 { .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks },
853907 { .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks },
908+ { .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i_a20_quirks },
854909 { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks },
855910 { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks },
856911 { }
drivers/gpu/drm/sun4i/sun4i_tcon.h+6−17
@@ -152,7 +152,7 @@ struct sun4i_tcon_quirks { · 151 unmodified lines
152152 bool needs_de_be_mux; /* sun6i needs mux to select backend */
153153
154154 /* callback to handle tcon muxing options */
155− int (*set_mux)(struct sun4i_tcon *, struct drm_encoder *);
155+ int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *);
156156 };
157157
158158 struct sun4i_tcon {
@@ -190,22 +190,11 @@ struct sun4i_tcon { · 31 unmodified lines
190190 struct drm_bridge *sun4i_tcon_find_bridge(struct device_node *node);
191191 struct drm_panel *sun4i_tcon_find_panel(struct device_node *node);
192192
193−/* Global Control */
194−void sun4i_tcon_disable(struct sun4i_tcon *tcon);
195−void sun4i_tcon_enable(struct sun4i_tcon *tcon);
196−
197−/* Channel Control */
198−void sun4i_tcon_channel_disable(struct sun4i_tcon *tcon, int channel);
199−void sun4i_tcon_channel_enable(struct sun4i_tcon *tcon, int channel);
200−
201193 void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable);
202−
203−/* Mode Related Controls */
204−void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel,
205− struct drm_encoder *encoder);
206−void sun4i_tcon0_mode_set(struct sun4i_tcon *tcon,
207− struct drm_display_mode *mode);
208−void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
209− struct drm_display_mode *mode);
194+void sun4i_tcon_mode_set(struct sun4i_tcon *tcon,
195+ const struct drm_encoder *encoder,
196+ const struct drm_display_mode *mode);
197+void sun4i_tcon_set_status(struct sun4i_tcon *crtc,
198+ const struct drm_encoder *encoder, bool enable);
210199
211200 #endif /* __SUN4I_TCON_H__ */
drivers/gpu/drm/sun4i/sun4i_tv.c+0−12
@@ -24,7 +24,6 @@ · 23 unmodified lines
2424
2525 #include "sun4i_crtc.h"
2626 #include "sun4i_drv.h"
27−#include "sun4i_tcon.h"
2827 #include "sunxi_engine.h"
2928
3029 #define SUN4I_TVE_EN_REG 0x000
@@ -345,12 +344,9 @@ static void sun4i_tv_disable(struct drm_encoder *encoder) · 314 unmodified lines
345344 {
346345 struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
347346 struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
348− struct sun4i_tcon *tcon = crtc->tcon;
349347
350348 DRM_DEBUG_DRIVER("Disabling the TV Output\n");
351349
352− sun4i_tcon_channel_disable(tcon, 1);
353−
354350 regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
355351 SUN4I_TVE_EN_ENABLE,
356352 0);
@@ -362,7 +358,6 @@ static void sun4i_tv_enable(struct drm_encoder *encoder) · 5 unmodified lines
362358 {
363359 struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
364360 struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
365− struct sun4i_tcon *tcon = crtc->tcon;
366361
367362 DRM_DEBUG_DRIVER("Enabling the TV Output\n");
368363
@@ -371,8 +366,6 @@ static void sun4i_tv_enable(struct drm_encoder *encoder) · 2 unmodified lines
371366 regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
372367 SUN4I_TVE_EN_ENABLE,
373368 SUN4I_TVE_EN_ENABLE);
374−
375− sun4i_tcon_channel_enable(tcon, 1);
376369 }
377370
378371 static void sun4i_tv_mode_set(struct drm_encoder *encoder,
@@ -380,13 +373,8 @@ static void sun4i_tv_mode_set(struct drm_encoder *encoder, · 1 unmodified line
380373 struct drm_display_mode *adjusted_mode)
381374 {
382375 struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
383− struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
384− struct sun4i_tcon *tcon = crtc->tcon;
385376 const struct tv_mode *tv_mode = sun4i_tv_find_tv_by_mode(mode);
386377
387− sun4i_tcon1_mode_set(tcon, mode);
388− sun4i_tcon_set_mux(tcon, 1, encoder);
389−
390378 /* Enable and map the DAC to the output */
391379 regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
392380 SUN4I_TVE_EN_DAC_MAP_MASK,
drivers/gpu/drm/udl/udl_connector.c+104−50
@@ -14,70 +14,95 @@ · 13 unmodified lines
1414 #include <drm/drm_crtc.h>
1515 #include <drm/drm_edid.h>
1616 #include <drm/drm_crtc_helper.h>
17+#include "udl_connector.h"
1718 #include "udl_drv.h"
1819
19−/* dummy connector to just get EDID,
20− all UDL appear to have a DVI-D */
21−
22−static u8 *udl_get_edid(struct udl_device *udl)
20+static bool udl_get_edid_block(struct udl_device *udl, int block_idx,
21+ u8 *buff)
2322 {
24− u8 *block;
25− char *rbuf;
2623 int ret, i;
24+ u8 *read_buff;
2725
28− block = kmalloc(EDID_LENGTH, GFP_KERNEL);
29− if (block == NULL)
30− return NULL;
31−
32− rbuf = kmalloc(2, GFP_KERNEL);
33− if (rbuf == NULL)
34− goto error;
26+ read_buff = kmalloc(2, GFP_KERNEL);
27+ if (!read_buff)
28+ return false;
3529
3630 for (i = 0; i < EDID_LENGTH; i++) {
31+ int bval = (i + block_idx * EDID_LENGTH) << 8;
3732 ret = usb_control_msg(udl->udev,
38− usb_rcvctrlpipe(udl->udev, 0), (0x02),
39− (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2,
40− HZ);
33+ usb_rcvctrlpipe(udl->udev, 0),
34+ (0x02), (0x80 | (0x02 << 5)), bval,
35+ 0xA1, read_buff, 2, HZ);
4136 if (ret < 1) {
4237 DRM_ERROR("Read EDID byte %d failed err %x\n", i, ret);
43− goto error;
38+ kfree(read_buff);
39+ return false;
4440 }
45− block[i] = rbuf[1];
41+ buff[i] = read_buff[1];
4642 }
4743
48− kfree(rbuf);
49− return block;
50−
51−error:
52− kfree(block);
53− kfree(rbuf);
54− return NULL;
44+ kfree(read_buff);
45+ return true;
5546 }
5647
57−static int udl_get_modes(struct drm_connector *connector)
48+static bool udl_get_edid(struct udl_device *udl, u8 **result_buff,
49+ int *result_buff_size)
5850 {
59− struct udl_device *udl = connector->dev->dev_private;
60− struct edid *edid;
61− int ret;
62−
63− edid = (struct edid *)udl_get_edid(udl);
64− if (!edid) {
65− drm_mode_connector_update_edid_property(connector, NULL);
66− return 0;
51+ int i, extensions;
52+ u8 *block_buff = NULL, *buff_ptr;
53+
54+ block_buff = kmalloc(EDID_LENGTH, GFP_KERNEL);
55+ if (block_buff == NULL)
56+ return false;
57+
58+ if (udl_get_edid_block(udl, 0, block_buff) &&
59+ memchr_inv(block_buff, 0, EDID_LENGTH)) {
60+ extensions = ((struct edid *)block_buff)->extensions;
61+ if (extensions > 0) {
62+ /* we have to read all extensions one by one */
63+ *result_buff_size = EDID_LENGTH * (extensions + 1);
64+ *result_buff = kmalloc(*result_buff_size, GFP_KERNEL);
65+ buff_ptr = *result_buff;
66+ if (buff_ptr == NULL) {
67+ kfree(block_buff);
68+ return false;
69+ }
70+ memcpy(buff_ptr, block_buff, EDID_LENGTH);
71+ kfree(block_buff);
72+ buff_ptr += EDID_LENGTH;
73+ for (i = 1; i < extensions; ++i) {
74+ if (udl_get_edid_block(udl, i, buff_ptr)) {
75+ buff_ptr += EDID_LENGTH;
76+ } else {
77+ kfree(*result_buff);
78+ *result_buff = NULL;
79+ return false;
80+ }
81+ }
82+ return true;
83+ }
84+ /* we have only base edid block */
85+ *result_buff = block_buff;
86+ *result_buff_size = EDID_LENGTH;
87+ return true;
6788 }
6889
69− /*
70− * We only read the main block, but if the monitor reports extension
71− * blocks then the drm edid code expects them to be present, so patch
72− * the extension count to 0.
73− */
74− edid->checksum += edid->extensions;
75− edid->extensions = 0;
76−
77− drm_mode_connector_update_edid_property(connector, edid);
78− ret = drm_add_edid_modes(connector, edid);
79− kfree(edid);
80− return ret;
90+ kfree(block_buff);
91+
92+ return false;
93+}
94+
95+static int udl_get_modes(struct drm_connector *connector)
96+{
97+ struct udl_drm_connector *udl_connector =
98+ container_of(connector,
99+ struct udl_drm_connector,
100+ connector);
101+
102+ drm_mode_connector_update_edid_property(connector, udl_connector->edid);
103+ if (udl_connector->edid)
104+ return drm_add_edid_modes(connector, udl_connector->edid);
105+ return 0;
81106 }
82107
83108 static int udl_mode_valid(struct drm_connector *connector,
@@ -96,8 +121,26 @@ static int udl_mode_valid(struct drm_connector *connector, · 12 unmodified lines
96121 static enum drm_connector_status
97122 udl_detect(struct drm_connector *connector, bool force)
98123 {
99− if (drm_dev_is_unplugged(connector->dev))
124+ u8 *edid_buff = NULL;
125+ int edid_buff_size = 0;
126+ struct udl_device *udl = connector->dev->dev_private;
127+ struct udl_drm_connector *udl_connector =
128+ container_of(connector,
129+ struct udl_drm_connector,
130+ connector);
131+
132+ /* cleanup previous edid */
133+ if (udl_connector->edid != NULL) {
134+ kfree(udl_connector->edid);
135+ udl_connector->edid = NULL;
136+ }
137+
138+
139+ if (!udl_get_edid(udl, &edid_buff, &edid_buff_size))
100140 return connector_status_disconnected;
141+
142+ udl_connector->edid = (struct edid *)edid_buff;
143+
101144 return connector_status_connected;
102145 }
103146
@@ -117,8 +160,14 @@ static int udl_connector_set_property(struct drm_connector *connector, · 13 unmodified lines
117160
118161 static void udl_connector_destroy(struct drm_connector *connector)
119162 {
163+ struct udl_drm_connector *udl_connector =
164+ container_of(connector,
165+ struct udl_drm_connector,
166+ connector);
167+
120168 drm_connector_unregister(connector);
121169 drm_connector_cleanup(connector);
170+ kfree(udl_connector->edid);
122171 kfree(connector);
123172 }
124173
@@ -138,17 +187,22 @@ static const struct drm_connector_funcs udl_connector_funcs = { · 13 unmodified lines
138187
139188 int udl_connector_init(struct drm_device *dev, struct drm_encoder *encoder)
140189 {
190+ struct udl_drm_connector *udl_connector;
141191 struct drm_connector *connector;
142192
143− connector = kzalloc(sizeof(struct drm_connector), GFP_KERNEL);
144− if (!connector)
193+ udl_connector = kzalloc(sizeof(struct udl_drm_connector), GFP_KERNEL);
194+ if (!udl_connector)
145195 return -ENOMEM;
146196
147− drm_connector_init(dev, connector, &udl_connector_funcs, DRM_MODE_CONNECTOR_DVII);
197+ connector = &udl_connector->connector;
198+ drm_connector_init(dev, connector, &udl_connector_funcs,
199+ DRM_MODE_CONNECTOR_DVII);
148200 drm_connector_helper_add(connector, &udl_connector_helper_funcs);
149201
150202 drm_connector_register(connector);
151203 drm_mode_connector_attach_encoder(connector, encoder);
204+ connector->polled = DRM_CONNECTOR_POLL_HPD |
205+ DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
152206
153207 return 0;
154208 }
drivers/gpu/drm/udl/udl_connector.h+13−0
@@ -0,0 +1,13 @@
1+#ifndef __UDL_CONNECTOR_H__
2+#define __UDL_CONNECTOR_H__
3+
4+#include <drm/drm_crtc.h>
5+
6+struct udl_drm_connector {
7+ struct drm_connector connector;
8+ /* last udl_detect edid */
9+ struct edid *edid;
10+};
11+
12+
13+#endif //__UDL_CONNECTOR_H__
drivers/gpu/drm/udl/udl_drv.c+4−0
@@ -14,6 +14,9 @@ · 13 unmodified lines
1414 static int udl_usb_suspend(struct usb_interface *interface,
1515 pm_message_t message)
1616 {
17+ struct drm_device *dev = usb_get_intfdata(interface);
18+
19+ drm_kms_helper_poll_disable(dev);
1720 return 0;
1821 }
1922
@@ -21,6 +24,7 @@ static int udl_usb_resume(struct usb_interface *interface) · 1 unmodified line
2124 {
2225 struct drm_device *dev = usb_get_intfdata(interface);
2326
27+ drm_kms_helper_poll_enable(dev);
2428 udl_modeset_restore(dev);
2529 return 0;
2630 }
drivers/gpu/drm/udl/udl_main.c+5−0
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 * more details.
1212 */
1313 #include <drm/drmP.h>
14+#include <drm/drm_crtc_helper.h>
1415 #include "udl_drv.h"
1516
1617 /* -BULK_SIZE as per usb-skeleton. Can we get full page and avoid overhead? */
@@ -350,6 +351,8 @@ int udl_driver_load(struct drm_device *dev, unsigned long flags) · 333 unmodified lines
350351 if (ret)
351352 goto err_fb;
352353
354+ drm_kms_helper_poll_init(dev);
355+
353356 return 0;
354357 err_fb:
355358 udl_fbdev_cleanup(dev);
@@ -371,6 +374,8 @@ void udl_driver_unload(struct drm_device *dev) · 15 unmodified lines
371374 {
372375 struct udl_device *udl = dev->dev_private;
373376
377+ drm_kms_helper_poll_fini(dev);
378+
374379 if (udl->urbs.count)
375380 udl_free_urb_list(dev);
376381
drivers/gpu/drm/vc4/vc4_bo.c+279−8
@@ -53,6 +53,17 @@ static void vc4_bo_stats_dump(struct vc4_dev *vc4) · 52 unmodified lines
5353 vc4->bo_labels[i].size_allocated / 1024,
5454 vc4->bo_labels[i].num_allocated);
5555 }
56+
57+ mutex_lock(&vc4->purgeable.lock);
58+ if (vc4->purgeable.num)
59+ DRM_INFO("%30s: %6zdkb BOs (%d)\n", "userspace BO cache",
60+ vc4->purgeable.size / 1024, vc4->purgeable.num);
61+
62+ if (vc4->purgeable.purged_num)
63+ DRM_INFO("%30s: %6zdkb BOs (%d)\n", "total purged BO",
64+ vc4->purgeable.purged_size / 1024,
65+ vc4->purgeable.purged_num);
66+ mutex_unlock(&vc4->purgeable.lock);
5667 }
5768
5869 #ifdef CONFIG_DEBUG_FS
@@ -75,6 +86,17 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused) · 16 unmodified lines
7586 }
7687 mutex_unlock(&vc4->bo_lock);
7788
89+ mutex_lock(&vc4->purgeable.lock);
90+ if (vc4->purgeable.num)
91+ seq_printf(m, "%30s: %6dkb BOs (%d)\n", "userspace BO cache",
92+ vc4->purgeable.size / 1024, vc4->purgeable.num);
93+
94+ if (vc4->purgeable.purged_num)
95+ seq_printf(m, "%30s: %6dkb BOs (%d)\n", "total purged BO",
96+ vc4->purgeable.purged_size / 1024,
97+ vc4->purgeable.purged_num);
98+ mutex_unlock(&vc4->purgeable.lock);
99+
78100 return 0;
79101 }
80102 #endif
@@ -247,6 +269,109 @@ static void vc4_bo_cache_purge(struct drm_device *dev) · 166 unmodified lines
247269 mutex_unlock(&vc4->bo_lock);
248270 }
249271
272+void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo)
273+{
274+ struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
275+
276+ mutex_lock(&vc4->purgeable.lock);
277+ list_add_tail(&bo->size_head, &vc4->purgeable.list);
278+ vc4->purgeable.num++;
279+ vc4->purgeable.size += bo->base.base.size;
280+ mutex_unlock(&vc4->purgeable.lock);
281+}
282+
283+static void vc4_bo_remove_from_purgeable_pool_locked(struct vc4_bo *bo)
284+{
285+ struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
286+
287+ /* list_del_init() is used here because the caller might release
288+ * the purgeable lock in order to acquire the madv one and update the
289+ * madv status.
290+ * During this short period of time a user might decide to mark
291+ * the BO as unpurgeable, and if bo->madv is set to
292+ * VC4_MADV_DONTNEED it will try to remove the BO from the
293+ * purgeable list which will fail if the ->next/prev fields
294+ * are set to LIST_POISON1/LIST_POISON2 (which is what
295+ * list_del() does).
296+ * Re-initializing the list element guarantees that list_del()
297+ * will work correctly even if it's a NOP.
298+ */
299+ list_del_init(&bo->size_head);
300+ vc4->purgeable.num--;
301+ vc4->purgeable.size -= bo->base.base.size;
302+}
303+
304+void vc4_bo_remove_from_purgeable_pool(struct vc4_bo *bo)
305+{
306+ struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
307+
308+ mutex_lock(&vc4->purgeable.lock);
309+ vc4_bo_remove_from_purgeable_pool_locked(bo);
310+ mutex_unlock(&vc4->purgeable.lock);
311+}
312+
313+static void vc4_bo_purge(struct drm_gem_object *obj)
314+{
315+ struct vc4_bo *bo = to_vc4_bo(obj);
316+ struct drm_device *dev = obj->dev;
317+
318+ WARN_ON(!mutex_is_locked(&bo->madv_lock));
319+ WARN_ON(bo->madv != VC4_MADV_DONTNEED);
320+
321+ drm_vma_node_unmap(&obj->vma_node, dev->anon_inode->i_mapping);
322+
323+ dma_free_wc(dev->dev, obj->size, bo->base.vaddr, bo->base.paddr);
324+ bo->base.vaddr = NULL;
325+ bo->madv = __VC4_MADV_PURGED;
326+}
327+
328+static void vc4_bo_userspace_cache_purge(struct drm_device *dev)
329+{
330+ struct vc4_dev *vc4 = to_vc4_dev(dev);
331+
332+ mutex_lock(&vc4->purgeable.lock);
333+ while (!list_empty(&vc4->purgeable.list)) {
334+ struct vc4_bo *bo = list_first_entry(&vc4->purgeable.list,
335+ struct vc4_bo, size_head);
336+ struct drm_gem_object *obj = &bo->base.base;
337+ size_t purged_size = 0;
338+
339+ vc4_bo_remove_from_purgeable_pool_locked(bo);
340+
341+ /* Release the purgeable lock while we're purging the BO so
342+ * that other people can continue inserting things in the
343+ * purgeable pool without having to wait for all BOs to be
344+ * purged.
345+ */
346+ mutex_unlock(&vc4->purgeable.lock);
347+ mutex_lock(&bo->madv_lock);
348+
349+ /* Since we released the purgeable pool lock before acquiring
350+ * the BO madv one, the user may have marked the BO as WILLNEED
351+ * and re-used it in the meantime.
352+ * Before purging the BO we need to make sure
353+ * - it is still marked as DONTNEED
354+ * - it has not been re-inserted in the purgeable list
355+ * - it is not used by HW blocks
356+ * If one of these conditions is not met, just skip the entry.
357+ */
358+ if (bo->madv == VC4_MADV_DONTNEED &&
359+ list_empty(&bo->size_head) &&
360+ !refcount_read(&bo->usecnt)) {
361+ purged_size = bo->base.base.size;
362+ vc4_bo_purge(obj);
363+ }
364+ mutex_unlock(&bo->madv_lock);
365+ mutex_lock(&vc4->purgeable.lock);
366+
367+ if (purged_size) {
368+ vc4->purgeable.purged_size += purged_size;
369+ vc4->purgeable.purged_num++;
370+ }
371+ }
372+ mutex_unlock(&vc4->purgeable.lock);
373+}
374+
250375 static struct vc4_bo *vc4_bo_get_from_cache(struct drm_device *dev,
251376 uint32_t size,
252377 enum vc4_kernel_bo_type type)
@@ -293,6 +418,9 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) · 40 unmodified lines
293418 if (!bo)
294419 return ERR_PTR(-ENOMEM);
295420
421+ bo->madv = VC4_MADV_WILLNEED;
422+ refcount_set(&bo->usecnt, 0);
423+ mutex_init(&bo->madv_lock);
296424 mutex_lock(&vc4->bo_lock);
297425 bo->label = VC4_BO_TYPE_KERNEL;
298426 vc4->bo_labels[VC4_BO_TYPE_KERNEL].num_allocated++;
@@ -330,16 +458,38 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, · 31 unmodified lines
330458 * CMA allocations we've got laying around and try again.
331459 */
332460 vc4_bo_cache_purge(dev);
461+ cma_obj = drm_gem_cma_create(dev, size);
462+ }
333463
464+ if (IS_ERR(cma_obj)) {
465+ /*
466+ * Still not enough CMA memory, purge the userspace BO
467+ * cache and retry.
468+ * This is sub-optimal since we purge the whole userspace
469+ * BO cache which forces user that want to re-use the BO to
470+ * restore its initial content.
471+ * Ideally, we should purge entries one by one and retry
472+ * after each to see if CMA allocation succeeds. Or even
473+ * better, try to find an entry with at least the same
474+ * size.
475+ */
476+ vc4_bo_userspace_cache_purge(dev);
334477 cma_obj = drm_gem_cma_create(dev, size);
335− if (IS_ERR(cma_obj)) {
336− DRM_ERROR("Failed to allocate from CMA:\n");
337− vc4_bo_stats_dump(vc4);
338− return ERR_PTR(-ENOMEM);
339− }
478+ }
479+
480+ if (IS_ERR(cma_obj)) {
481+ DRM_ERROR("Failed to allocate from CMA:\n");
482+ vc4_bo_stats_dump(vc4);
483+ return ERR_PTR(-ENOMEM);
340484 }
341485 bo = to_vc4_bo(&cma_obj->base);
342486
487+ /* By default, BOs do not support the MADV ioctl. This will be enabled
488+ * only on BOs that are exposed to userspace (V3D, V3D_SHADER and DUMB
489+ * BOs).
490+ */
491+ bo->madv = __VC4_MADV_NOTSUPP;
492+
343493 mutex_lock(&vc4->bo_lock);
344494 vc4_bo_set_label(&cma_obj->base, type);
345495 mutex_unlock(&vc4->bo_lock);
@@ -365,6 +515,8 @@ int vc4_dumb_create(struct drm_file *file_priv, · 19 unmodified lines
365515 if (IS_ERR(bo))
366516 return PTR_ERR(bo);
367517
518+ bo->madv = VC4_MADV_WILLNEED;
519+
368520 ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
369521 drm_gem_object_put_unlocked(&bo->base.base);
370522
@@ -403,6 +555,12 @@ void vc4_free_object(struct drm_gem_object *gem_bo) · 32 unmodified lines
403555 struct vc4_bo *bo = to_vc4_bo(gem_bo);
404556 struct list_head *cache_list;
405557
558+ /* Remove the BO from the purgeable list. */
559+ mutex_lock(&bo->madv_lock);
560+ if (bo->madv == VC4_MADV_DONTNEED && !refcount_read(&bo->usecnt))
561+ vc4_bo_remove_from_purgeable_pool(bo);
562+ mutex_unlock(&bo->madv_lock);
563+
406564 mutex_lock(&vc4->bo_lock);
407565 /* If the object references someone else's memory, we can't cache it.
408566 */
@@ -418,7 +576,8 @@ void vc4_free_object(struct drm_gem_object *gem_bo) · 9 unmodified lines
418576 }
419577
420578 /* If this object was partially constructed but CMA allocation
421− * had failed, just free it.
579+ * had failed, just free it. Can also happen when the BO has been
580+ * purged.
422581 */
423582 if (!bo->base.vaddr) {
424583 vc4_bo_destroy(bo);
@@ -437,6 +596,10 @@ void vc4_free_object(struct drm_gem_object *gem_bo) · 12 unmodified lines
437596 bo->validated_shader = NULL;
438597 }
439598
599+ /* Reset madv and usecnt before adding the BO to the cache. */
600+ bo->madv = __VC4_MADV_NOTSUPP;
601+ refcount_set(&bo->usecnt, 0);
602+
440603 bo->t_format = false;
441604 bo->free_time = jiffies;
442605 list_add(&bo->size_head, cache_list);
@@ -461,6 +624,56 @@ static void vc4_bo_cache_time_work(struct work_struct *work) · 18 unmodified lines
461624 mutex_unlock(&vc4->bo_lock);
462625 }
463626
627+int vc4_bo_inc_usecnt(struct vc4_bo *bo)
628+{
629+ int ret;
630+
631+ /* Fast path: if the BO is already retained by someone, no need to
632+ * check the madv status.
633+ */
634+ if (refcount_inc_not_zero(&bo->usecnt))
635+ return 0;
636+
637+ mutex_lock(&bo->madv_lock);
638+ switch (bo->madv) {
639+ case VC4_MADV_WILLNEED:
640+ refcount_inc(&bo->usecnt);
641+ ret = 0;
642+ break;
643+ case VC4_MADV_DONTNEED:
644+ /* We shouldn't use a BO marked as purgeable if at least
645+ * someone else retained its content by incrementing usecnt.
646+ * Luckily the BO hasn't been purged yet, but something wrong
647+ * is happening here. Just throw an error instead of
648+ * authorizing this use case.
649+ */
650+ case __VC4_MADV_PURGED:
651+ /* We can't use a purged BO. */
652+ default:
653+ /* Invalid madv value. */
654+ ret = -EINVAL;
655+ break;
656+ }
657+ mutex_unlock(&bo->madv_lock);
658+
659+ return ret;
660+}
661+
662+void vc4_bo_dec_usecnt(struct vc4_bo *bo)
663+{
664+ /* Fast path: if the BO is still retained by someone, no need to test
665+ * the madv value.
666+ */
667+ if (refcount_dec_not_one(&bo->usecnt))
668+ return;
669+
670+ mutex_lock(&bo->madv_lock);
671+ if (refcount_dec_and_test(&bo->usecnt) &&
672+ bo->madv == VC4_MADV_DONTNEED)
673+ vc4_bo_add_to_purgeable_pool(bo);
674+ mutex_unlock(&bo->madv_lock);
675+}
676+
464677 static void vc4_bo_cache_time_timer(unsigned long data)
465678 {
466679 struct drm_device *dev = (struct drm_device *)data;
@@ -480,18 +693,52 @@ struct dma_buf * · 13 unmodified lines
480693 vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags)
481694 {
482695 struct vc4_bo *bo = to_vc4_bo(obj);
696+ struct dma_buf *dmabuf;
697+ int ret;
483698
484699 if (bo->validated_shader) {
485700 DRM_DEBUG("Attempting to export shader BO\n");
486701 return ERR_PTR(-EINVAL);
487702 }
488703
489− return drm_gem_prime_export(dev, obj, flags);
704+ /* Note: as soon as the BO is exported it becomes unpurgeable, because
705+ * noone ever decrements the usecnt even if the reference held by the
706+ * exported BO is released. This shouldn't be a problem since we don't
707+ * expect exported BOs to be marked as purgeable.
708+ */
709+ ret = vc4_bo_inc_usecnt(bo);
710+ if (ret) {
711+ DRM_ERROR("Failed to increment BO usecnt\n");
712+ return ERR_PTR(ret);
713+ }
714+
715+ dmabuf = drm_gem_prime_export(dev, obj, flags);
716+ if (IS_ERR(dmabuf))
717+ vc4_bo_dec_usecnt(bo);
718+
719+ return dmabuf;
720+}
721+
722+int vc4_fault(struct vm_fault *vmf)
723+{
724+ struct vm_area_struct *vma = vmf->vma;
725+ struct drm_gem_object *obj = vma->vm_private_data;
726+ struct vc4_bo *bo = to_vc4_bo(obj);
727+
728+ /* The only reason we would end up here is when user-space accesses
729+ * BO's memory after it's been purged.
730+ */
731+ mutex_lock(&bo->madv_lock);
732+ WARN_ON(bo->madv != __VC4_MADV_PURGED);
733+ mutex_unlock(&bo->madv_lock);
734+
735+ return VM_FAULT_SIGBUS;
490736 }
491737
492738 int vc4_mmap(struct file *filp, struct vm_area_struct *vma)
493739 {
494740 struct drm_gem_object *gem_obj;
741+ unsigned long vm_pgoff;
495742 struct vc4_bo *bo;
496743 int ret;
497744
@@ -507,16 +754,36 @@ int vc4_mmap(struct file *filp, struct vm_area_struct *vma) · 9 unmodified lines
507754 return -EINVAL;
508755 }
509756
757+ if (bo->madv != VC4_MADV_WILLNEED) {
758+ DRM_DEBUG("mmaping of %s BO not allowed\n",
759+ bo->madv == VC4_MADV_DONTNEED ?
760+ "purgeable" : "purged");
761+ return -EINVAL;
762+ }
763+
510764 /*
511765 * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the
512766 * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map
513767 * the whole buffer.
514768 */
515769 vma->vm_flags &= ~VM_PFNMAP;
516− vma->vm_pgoff = 0;
517770
771+ /* This ->vm_pgoff dance is needed to make all parties happy:
772+ * - dma_mmap_wc() uses ->vm_pgoff as an offset within the allocated
773+ * mem-region, hence the need to set it to zero (the value set by
774+ * the DRM core is a virtual offset encoding the GEM object-id)
775+ * - the mmap() core logic needs ->vm_pgoff to be restored to its
776+ * initial value before returning from this function because it
777+ * encodes the offset of this GEM in the dev->anon_inode pseudo-file
778+ * and this information will be used when we invalidate userspace
779+ * mappings with drm_vma_node_unmap() (called from vc4_gem_purge()).
780+ */
781+ vm_pgoff = vma->vm_pgoff;
782+ vma->vm_pgoff = 0;
518783 ret = dma_mmap_wc(bo->base.base.dev->dev, vma, bo->base.vaddr,
519784 bo->base.paddr, vma->vm_end - vma->vm_start);
785+ vma->vm_pgoff = vm_pgoff;
786+
520787 if (ret)
521788 drm_gem_vm_close(vma);
522789
@@ -580,6 +847,8 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data, · 57 unmodified lines
580847 if (IS_ERR(bo))
581848 return PTR_ERR(bo);
582849
850+ bo->madv = VC4_MADV_WILLNEED;
851+
583852 ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
584853 drm_gem_object_put_unlocked(&bo->base.base);
585854
@@ -633,6 +902,8 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, · 47 unmodified lines
633902 if (IS_ERR(bo))
634903 return PTR_ERR(bo);
635904
905+ bo->madv = VC4_MADV_WILLNEED;
906+
636907 if (copy_from_user(bo->base.vaddr,
637908 (void __user *)(uintptr_t)args->data,
638909 args->size)) {
drivers/gpu/drm/vc4/vc4_drv.c+9−1
@@ -100,6 +100,7 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data, · 99 unmodified lines
100100 case DRM_VC4_PARAM_SUPPORTS_ETC1:
101101 case DRM_VC4_PARAM_SUPPORTS_THREADED_FS:
102102 case DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER:
103+ case DRM_VC4_PARAM_SUPPORTS_MADVISE:
103104 args->value = true;
104105 break;
105106 default:
@@ -117,6 +118,12 @@ static void vc4_lastclose(struct drm_device *dev) · 11 unmodified lines
117118 drm_fbdev_cma_restore_mode(vc4->fbdev);
118119 }
119120
121+static const struct vm_operations_struct vc4_vm_ops = {
122+ .fault = vc4_fault,
123+ .open = drm_gem_vm_open,
124+ .close = drm_gem_vm_close,
125+};
126+
120127 static const struct file_operations vc4_drm_fops = {
121128 .owner = THIS_MODULE,
122129 .open = drm_open,
@@ -142,6 +149,7 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = { · 19 unmodified lines
142149 DRM_IOCTL_DEF_DRV(VC4_SET_TILING, vc4_set_tiling_ioctl, DRM_RENDER_ALLOW),
143150 DRM_IOCTL_DEF_DRV(VC4_GET_TILING, vc4_get_tiling_ioctl, DRM_RENDER_ALLOW),
144151 DRM_IOCTL_DEF_DRV(VC4_LABEL_BO, vc4_label_bo_ioctl, DRM_RENDER_ALLOW),
152+ DRM_IOCTL_DEF_DRV(VC4_GEM_MADVISE, vc4_gem_madvise_ioctl, DRM_RENDER_ALLOW),
145153 };
146154
147155 static struct drm_driver vc4_drm_driver = {
@@ -166,7 +174,7 @@ static struct drm_driver vc4_drm_driver = { · 18 unmodified lines
166174
167175 .gem_create_object = vc4_create_object,
168176 .gem_free_object_unlocked = vc4_free_object,
169− .gem_vm_ops = &drm_gem_cma_vm_ops,
177+ .gem_vm_ops = &vc4_vm_ops,
170178
171179 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
172180 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
drivers/gpu/drm/vc4/vc4_drv.h+30−0
@@ -74,6 +74,19 @@ struct vc4_dev { · 73 unmodified lines
7474 /* Protects bo_cache and bo_labels. */
7575 struct mutex bo_lock;
7676
77+ /* Purgeable BO pool. All BOs in this pool can have their memory
78+ * reclaimed if the driver is unable to allocate new BOs. We also
79+ * keep stats related to the purge mechanism here.
80+ */
81+ struct {
82+ struct list_head list;
83+ unsigned int num;
84+ size_t size;
85+ unsigned int purged_num;
86+ size_t purged_size;
87+ struct mutex lock;
88+ } purgeable;
89+
7790 uint64_t dma_fence_context;
7891
7992 /* Sequence number for the last job queued in bin_job_list.
@@ -192,6 +205,16 @@ struct vc4_bo { · 112 unmodified lines
192205 * for user-allocated labels.
193206 */
194207 int label;
208+
209+ /* Count the number of active users. This is needed to determine
210+ * whether we can move the BO to the purgeable list or not (when the BO
211+ * is used by the GPU or the display engine we can't purge it).
212+ */
213+ refcount_t usecnt;
214+
215+ /* Store purgeable/purged state here */
216+ u32 madv;
217+ struct mutex madv_lock;
195218 };
196219
197220 static inline struct vc4_bo *
@@ -503,6 +526,7 @@ int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, · 305 unmodified lines
503526 struct drm_file *file_priv);
504527 int vc4_label_bo_ioctl(struct drm_device *dev, void *data,
505528 struct drm_file *file_priv);
529+int vc4_fault(struct vm_fault *vmf);
506530 int vc4_mmap(struct file *filp, struct vm_area_struct *vma);
507531 struct reservation_object *vc4_prime_res_obj(struct drm_gem_object *obj);
508532 int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
@@ -513,6 +537,10 @@ void *vc4_prime_vmap(struct drm_gem_object *obj); · 4 unmodified lines
513537 int vc4_bo_cache_init(struct drm_device *dev);
514538 void vc4_bo_cache_destroy(struct drm_device *dev);
515539 int vc4_bo_stats_debugfs(struct seq_file *m, void *arg);
540+int vc4_bo_inc_usecnt(struct vc4_bo *bo);
541+void vc4_bo_dec_usecnt(struct vc4_bo *bo);
542+void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo);
543+void vc4_bo_remove_from_purgeable_pool(struct vc4_bo *bo);
516544
517545 /* vc4_crtc.c */
518546 extern struct platform_driver vc4_crtc_driver;
@@ -557,6 +585,8 @@ void vc4_job_handle_completed(struct vc4_dev *vc4); · 38 unmodified lines
557585 int vc4_queue_seqno_cb(struct drm_device *dev,
558586 struct vc4_seqno_cb *cb, uint64_t seqno,
559587 void (*func)(struct vc4_seqno_cb *cb));
588+int vc4_gem_madvise_ioctl(struct drm_device *dev, void *data,
589+ struct drm_file *file_priv);
560590
561591 /* vc4_hdmi.c */
562592 extern struct platform_driver vc4_hdmi_driver;
drivers/gpu/drm/vc4/vc4_dsi.c+30−2
@@ -1360,6 +1360,27 @@ static void dsi_handle_error(struct vc4_dsi *dsi, · 1359 unmodified lines
13601360 *ret = IRQ_HANDLED;
13611361 }
13621362
1363+/*
1364+ * Initial handler for port 1 where we need the reg_dma workaround.
1365+ * The register DMA writes sleep, so we can't do it in the top half.
1366+ * Instead we use IRQF_ONESHOT so that the IRQ gets disabled in the
1367+ * parent interrupt contrller until our interrupt thread is done.
1368+ */
1369+static irqreturn_t vc4_dsi_irq_defer_to_thread_handler(int irq, void *data)
1370+{
1371+ struct vc4_dsi *dsi = data;
1372+ u32 stat = DSI_PORT_READ(INT_STAT);
1373+
1374+ if (!stat)
1375+ return IRQ_NONE;
1376+
1377+ return IRQ_WAKE_THREAD;
1378+}
1379+
1380+/*
1381+ * Normal IRQ handler for port 0, or the threaded IRQ handler for port
1382+ * 1 where we need the reg_dma workaround.
1383+ */
13631384 static irqreturn_t vc4_dsi_irq_handler(int irq, void *data)
13641385 {
13651386 struct vc4_dsi *dsi = data;
@@ -1539,8 +1560,15 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) · 173 unmodified lines
15391560 /* Clear any existing interrupt state. */
15401561 DSI_PORT_WRITE(INT_STAT, DSI_PORT_READ(INT_STAT));
15411562
1542− ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
1543− vc4_dsi_irq_handler, 0, "vc4 dsi", dsi);
1563+ if (dsi->reg_dma_mem)
1564+ ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0),
1565+ vc4_dsi_irq_defer_to_thread_handler,
1566+ vc4_dsi_irq_handler,
1567+ IRQF_ONESHOT,
1568+ "vc4 dsi", dsi);
1569+ else
1570+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
1571+ vc4_dsi_irq_handler, 0, "vc4 dsi", dsi);
15441572 if (ret) {
15451573 if (ret != -EPROBE_DEFER)
15461574 dev_err(dev, "Failed to get interrupt: %d\n", ret);
drivers/gpu/drm/vc4/vc4_gem.c+150−6
@@ -188,11 +188,22 @@ vc4_save_hang_state(struct drm_device *dev) · 187 unmodified lines
188188 continue;
189189
190190 for (j = 0; j < exec[i]->bo_count; j++) {
191+ bo = to_vc4_bo(&exec[i]->bo[j]->base);
192+
193+ /* Retain BOs just in case they were marked purgeable.
194+ * This prevents the BO from being purged before
195+ * someone had a chance to dump the hang state.
196+ */
197+ WARN_ON(!refcount_read(&bo->usecnt));
198+ refcount_inc(&bo->usecnt);
191199 drm_gem_object_get(&exec[i]->bo[j]->base);
192200 kernel_state->bo[j + prev_idx] = &exec[i]->bo[j]->base;
193201 }
194202
195203 list_for_each_entry(bo, &exec[i]->unref_list, unref_head) {
204+ /* No need to retain BOs coming from the ->unref_list
205+ * because they are naturally unpurgeable.
206+ */
196207 drm_gem_object_get(&bo->base.base);
197208 kernel_state->bo[j + prev_idx] = &bo->base.base;
198209 j++;
@@ -233,6 +244,26 @@ vc4_save_hang_state(struct drm_device *dev) · 34 unmodified lines
233244 state->fdbgs = V3D_READ(V3D_FDBGS);
234245 state->errstat = V3D_READ(V3D_ERRSTAT);
235246
247+ /* We need to turn purgeable BOs into unpurgeable ones so that
248+ * userspace has a chance to dump the hang state before the kernel
249+ * decides to purge those BOs.
250+ * Note that BO consistency at dump time cannot be guaranteed. For
251+ * example, if the owner of these BOs decides to re-use them or mark
252+ * them purgeable again there's nothing we can do to prevent it.
253+ */
254+ for (i = 0; i < kernel_state->user_state.bo_count; i++) {
255+ struct vc4_bo *bo = to_vc4_bo(kernel_state->bo[i]);
256+
257+ if (bo->madv == __VC4_MADV_NOTSUPP)
258+ continue;
259+
260+ mutex_lock(&bo->madv_lock);
261+ if (!WARN_ON(bo->madv == __VC4_MADV_PURGED))
262+ bo->madv = VC4_MADV_WILLNEED;
263+ refcount_dec(&bo->usecnt);
264+ mutex_unlock(&bo->madv_lock);
265+ }
266+
236267 spin_lock_irqsave(&vc4->job_lock, irqflags);
237268 if (vc4->hang_state) {
238269 spin_unlock_irqrestore(&vc4->job_lock, irqflags);
@@ -639,9 +670,6 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec, · 400 unmodified lines
639670 * The command validator needs to reference BOs by their index within
640671 * the submitted job's BO list. This does the validation of the job's
641672 * BO list and reference counting for the lifetime of the job.
642− *
643− * Note that this function doesn't need to unreference the BOs on
644− * failure, because that will happen at vc4_complete_exec() time.
645673 */
646674 static int
647675 vc4_cl_lookup_bos(struct drm_device *dev,
@@ -693,16 +721,47 @@ vc4_cl_lookup_bos(struct drm_device *dev, · 45 unmodified lines
693721 DRM_DEBUG("Failed to look up GEM BO %d: %d\n",
694722 i, handles[i]);
695723 ret = -EINVAL;
696− spin_unlock(&file_priv->table_lock);
697− goto fail;
724+ break;
698725 }
726+
699727 drm_gem_object_get(bo);
700728 exec->bo[i] = (struct drm_gem_cma_object *)bo;
701729 }
702730 spin_unlock(&file_priv->table_lock);
703731
732+ if (ret)
733+ goto fail_put_bo;
734+
735+ for (i = 0; i < exec->bo_count; i++) {
736+ ret = vc4_bo_inc_usecnt(to_vc4_bo(&exec->bo[i]->base));
737+ if (ret)
738+ goto fail_dec_usecnt;
739+ }
740+
741+ kvfree(handles);
742+ return 0;
743+
744+fail_dec_usecnt:
745+ /* Decrease usecnt on acquired objects.
746+ * We cannot rely on vc4_complete_exec() to release resources here,
747+ * because vc4_complete_exec() has no information about which BO has
748+ * had its ->usecnt incremented.
749+ * To make things easier we just free everything explicitly and set
750+ * exec->bo to NULL so that vc4_complete_exec() skips the 'BO release'
751+ * step.
752+ */
753+ for (i-- ; i >= 0; i--)
754+ vc4_bo_dec_usecnt(to_vc4_bo(&exec->bo[i]->base));
755+
756+fail_put_bo:
757+ /* Release any reference to acquired objects. */
758+ for (i = 0; i < exec->bo_count && exec->bo[i]; i++)
759+ drm_gem_object_put_unlocked(&exec->bo[i]->base);
760+
704761 fail:
705762 kvfree(handles);
763+ kvfree(exec->bo);
764+ exec->bo = NULL;
706765 return ret;
707766 }
708767
@@ -833,8 +892,12 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) · 124 unmodified lines
833892 dma_fence_signal(exec->fence);
834893
835894 if (exec->bo) {
836− for (i = 0; i < exec->bo_count; i++)
895+ for (i = 0; i < exec->bo_count; i++) {
896+ struct vc4_bo *bo = to_vc4_bo(&exec->bo[i]->base);
897+
898+ vc4_bo_dec_usecnt(bo);
837899 drm_gem_object_put_unlocked(&exec->bo[i]->base);
900+ }
838901 kvfree(exec->bo);
839902 }
840903
@@ -1098,6 +1161,9 @@ vc4_gem_init(struct drm_device *dev) · 257 unmodified lines
10981161 INIT_WORK(&vc4->job_done_work, vc4_job_done_work);
10991162
11001163 mutex_init(&vc4->power_lock);
1164+
1165+ INIT_LIST_HEAD(&vc4->purgeable.list);
1166+ mutex_init(&vc4->purgeable.lock);
11011167 }
11021168
11031169 void
@@ -1121,3 +1187,81 @@ vc4_gem_destroy(struct drm_device *dev) · 17 unmodified lines
11211187 if (vc4->hang_state)
11221188 vc4_free_hang_state(dev, vc4->hang_state);
11231189 }
1190+
1191+int vc4_gem_madvise_ioctl(struct drm_device *dev, void *data,
1192+ struct drm_file *file_priv)
1193+{
1194+ struct drm_vc4_gem_madvise *args = data;
1195+ struct drm_gem_object *gem_obj;
1196+ struct vc4_bo *bo;
1197+ int ret;
1198+
1199+ switch (args->madv) {
1200+ case VC4_MADV_DONTNEED:
1201+ case VC4_MADV_WILLNEED:
1202+ break;
1203+ default:
1204+ return -EINVAL;
1205+ }
1206+
1207+ if (args->pad != 0)
1208+ return -EINVAL;
1209+
1210+ gem_obj = drm_gem_object_lookup(file_priv, args->handle);
1211+ if (!gem_obj) {
1212+ DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
1213+ return -ENOENT;
1214+ }
1215+
1216+ bo = to_vc4_bo(gem_obj);
1217+
1218+ /* Only BOs exposed to userspace can be purged. */
1219+ if (bo->madv == __VC4_MADV_NOTSUPP) {
1220+ DRM_DEBUG("madvise not supported on this BO\n");
1221+ ret = -EINVAL;
1222+ goto out_put_gem;
1223+ }
1224+
1225+ /* Not sure it's safe to purge imported BOs. Let's just assume it's
1226+ * not until proven otherwise.
1227+ */
1228+ if (gem_obj->import_attach) {
1229+ DRM_DEBUG("madvise not supported on imported BOs\n");
1230+ ret = -EINVAL;
1231+ goto out_put_gem;
1232+ }
1233+
1234+ mutex_lock(&bo->madv_lock);
1235+
1236+ if (args->madv == VC4_MADV_DONTNEED && bo->madv == VC4_MADV_WILLNEED &&
1237+ !refcount_read(&bo->usecnt)) {
1238+ /* If the BO is about to be marked as purgeable, is not used
1239+ * and is not already purgeable or purged, add it to the
1240+ * purgeable list.
1241+ */
1242+ vc4_bo_add_to_purgeable_pool(bo);
1243+ } else if (args->madv == VC4_MADV_WILLNEED &&
1244+ bo->madv == VC4_MADV_DONTNEED &&
1245+ !refcount_read(&bo->usecnt)) {
1246+ /* The BO has not been purged yet, just remove it from
1247+ * the purgeable list.
1248+ */
1249+ vc4_bo_remove_from_purgeable_pool(bo);
1250+ }
1251+
1252+ /* Save the purged state. */
1253+ args->retained = bo->madv != __VC4_MADV_PURGED;
1254+
1255+ /* Update internal madv state only if the bo was not purged. */
1256+ if (bo->madv != __VC4_MADV_PURGED)
1257+ bo->madv = args->madv;
1258+
1259+ mutex_unlock(&bo->madv_lock);
1260+
1261+ ret = 0;
1262+
1263+out_put_gem:
1264+ drm_gem_object_put_unlocked(gem_obj);
1265+
1266+ return ret;
1267+}
drivers/gpu/drm/vc4/vc4_plane.c+20−0
@@ -23,6 +23,7 @@ · 22 unmodified lines
2323 #include <drm/drm_fb_cma_helper.h>
2424 #include <drm/drm_plane_helper.h>
2525
26+#include "uapi/drm/vc4_drm.h"
2627 #include "vc4_drv.h"
2728 #include "vc4_regs.h"
2829
@@ -774,21 +775,40 @@ static int vc4_prepare_fb(struct drm_plane *plane, · 745 unmodified lines
774775 {
775776 struct vc4_bo *bo;
776777 struct dma_fence *fence;
778+ int ret;
777779
778780 if ((plane->state->fb == state->fb) || !state->fb)
779781 return 0;
780782
781783 bo = to_vc4_bo(&drm_fb_cma_get_gem_obj(state->fb, 0)->base);
784+
785+ ret = vc4_bo_inc_usecnt(bo);
786+ if (ret)
787+ return ret;
788+
782789 fence = reservation_object_get_excl_rcu(bo->resv);
783790 drm_atomic_set_fence_for_plane(state, fence);
784791
785792 return 0;
786793 }
787794
795+static void vc4_cleanup_fb(struct drm_plane *plane,
796+ struct drm_plane_state *state)
797+{
798+ struct vc4_bo *bo;
799+
800+ if (plane->state->fb == state->fb || !state->fb)
801+ return;
802+
803+ bo = to_vc4_bo(&drm_fb_cma_get_gem_obj(state->fb, 0)->base);
804+ vc4_bo_dec_usecnt(bo);
805+}
806+
788807 static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
789808 .atomic_check = vc4_plane_atomic_check,
790809 .atomic_update = vc4_plane_atomic_update,
791810 .prepare_fb = vc4_prepare_fb,
811+ .cleanup_fb = vc4_cleanup_fb,
792812 };
793813
794814 static void vc4_plane_destroy(struct drm_plane *plane)
drivers/gpu/vga/vgaarb.c+55−17
@@ -1402,29 +1402,14 @@ static struct miscdevice vga_arb_device = { · 1401 unmodified lines
14021402 MISC_DYNAMIC_MINOR, "vga_arbiter", &vga_arb_device_fops
14031403 };
14041404
1405−static int __init vga_arb_device_init(void)
1405+static void __init vga_arb_select_default_device(void)
14061406 {
1407− int rc;
14081407 struct pci_dev *pdev;
14091408 struct vga_device *vgadev;
14101409
1411− rc = misc_register(&vga_arb_device);
1412− if (rc < 0)
1413− pr_err("error %d registering device\n", rc);
1414−
1415− bus_register_notifier(&pci_bus_type, &pci_notifier);
1416−
1417− /* We add all pci devices satisfying vga class in the arbiter by
1418− * default */
1419− pdev = NULL;
1420− while ((pdev =
1421− pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
1422− PCI_ANY_ID, pdev)) != NULL)
1423− vga_arbiter_add_pci_device(pdev);
1424−
1410+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
14251411 list_for_each_entry(vgadev, &vga_list, list) {
14261412 struct device *dev = &vgadev->pdev->dev;
1427−#if defined(CONFIG_X86) || defined(CONFIG_IA64)
14281413 /*
14291414 * Override vga_arbiter_add_pci_device()'s I/O based detection
14301415 * as it may take the wrong device (e.g. on Apple system under
@@ -1461,13 +1446,66 @@ static int __init vga_arb_device_init(void) · 30 unmodified lines
14611446 vgaarb_info(dev, "overriding boot device\n");
14621447 vga_set_default_device(vgadev->pdev);
14631448 }
1449+ }
14641450 #endif
1451+
1452+ if (!vga_default_device()) {
1453+ list_for_each_entry(vgadev, &vga_list, list) {
1454+ struct device *dev = &vgadev->pdev->dev;
1455+ u16 cmd;
1456+
1457+ pdev = vgadev->pdev;
1458+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
1459+ if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
1460+ vgaarb_info(dev, "setting as boot device (VGA legacy resources not available)\n");
1461+ vga_set_default_device(pdev);
1462+ break;
1463+ }
1464+ }
1465+ }
1466+
1467+ if (!vga_default_device()) {
1468+ vgadev = list_first_entry_or_null(&vga_list,
1469+ struct vga_device, list);
1470+ if (vgadev) {
1471+ struct device *dev = &vgadev->pdev->dev;
1472+ vgaarb_info(dev, "setting as boot device (VGA legacy resources not available)\n");
1473+ vga_set_default_device(vgadev->pdev);
1474+ }
1475+ }
1476+}
1477+
1478+static int __init vga_arb_device_init(void)
1479+{
1480+ int rc;
1481+ struct pci_dev *pdev;
1482+ struct vga_device *vgadev;
1483+
1484+ rc = misc_register(&vga_arb_device);
1485+ if (rc < 0)
1486+ pr_err("error %d registering device\n", rc);
1487+
1488+ bus_register_notifier(&pci_bus_type, &pci_notifier);
1489+
1490+ /* We add all PCI devices satisfying VGA class in the arbiter by
1491+ * default */
1492+ pdev = NULL;
1493+ while ((pdev =
1494+ pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
1495+ PCI_ANY_ID, pdev)) != NULL)
1496+ vga_arbiter_add_pci_device(pdev);
1497+
1498+ list_for_each_entry(vgadev, &vga_list, list) {
1499+ struct device *dev = &vgadev->pdev->dev;
1500+
14651501 if (vgadev->bridge_has_one_vga)
14661502 vgaarb_info(dev, "bridge control possible\n");
14671503 else
14681504 vgaarb_info(dev, "no bridge control possible\n");
14691505 }
14701506
1507+ vga_arb_select_default_device();
1508+
14711509 pr_info("loaded\n");
14721510 return rc;
14731511 }
include/linux/dma-fence.h+1−1
@@ -128,7 +128,7 @@ struct dma_fence_cb { · 127 unmodified lines
128128 * implementation know that there is another driver waiting on
129129 * the signal (ie. hw->sw case).
130130 *
131− * This function can be called called from atomic context, but not
131+ * This function can be called from atomic context, but not
132132 * from irq context, so normal spinlocks can be used.
133133 *
134134 * A return value of false indicates the fence already passed,
include/uapi/drm/vc4_drm.h+19−0
@@ -41,6 +41,7 @@ extern "C" { · 40 unmodified lines
4141 #define DRM_VC4_SET_TILING 0x08
4242 #define DRM_VC4_GET_TILING 0x09
4343 #define DRM_VC4_LABEL_BO 0x0a
44+#define DRM_VC4_GEM_MADVISE 0x0b
4445
4546 #define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl)
4647 #define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno)
@@ -53,6 +54,7 @@ extern "C" { · 6 unmodified lines
5354 #define DRM_IOCTL_VC4_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling)
5455 #define DRM_IOCTL_VC4_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling)
5556 #define DRM_IOCTL_VC4_LABEL_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_LABEL_BO, struct drm_vc4_label_bo)
57+#define DRM_IOCTL_VC4_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GEM_MADVISE, struct drm_vc4_gem_madvise)
5658
5759 struct drm_vc4_submit_rcl_surface {
5860 __u32 hindex; /* Handle index, or ~0 if not present. */
@@ -305,6 +307,7 @@ struct drm_vc4_get_hang_state { · 246 unmodified lines
305307 #define DRM_VC4_PARAM_SUPPORTS_ETC1 4
306308 #define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5
307309 #define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6
310+#define DRM_VC4_PARAM_SUPPORTS_MADVISE 7
308311
309312 struct drm_vc4_get_param {
310313 __u32 param;
@@ -333,6 +336,22 @@ struct drm_vc4_label_bo { · 22 unmodified lines
333336 __u64 name;
334337 };
335338
339+/*
340+ * States prefixed with '__' are internal states and cannot be passed to the
341+ * DRM_IOCTL_VC4_GEM_MADVISE ioctl.
342+ */
343+#define VC4_MADV_WILLNEED 0
344+#define VC4_MADV_DONTNEED 1
345+#define __VC4_MADV_PURGED 2
346+#define __VC4_MADV_NOTSUPP 3
347+
348+struct drm_vc4_gem_madvise {
349+ __u32 handle;
350+ __u32 madv;
351+ __u32 retained;
352+ __u32 pad;
353+};
354+
336355 #if defined(__cplusplus)
337356 }
338357 #endif