From 76cde6753ce91015b95a0619ec55adc6c98233b8 Mon Sep 17 00:00:00 2001 From: parazyd Date: Tue, 30 Jan 2018 11:08:43 +0100 Subject: [PATCH] Add linux-droid4-patches. --- ...-omap-remove-unused-function-defines.patch | 31 + ...0002-drm-omap-drop-incorrect-comment.patch | 33 + ...-plane-update-fifo-size-on-ovl-setup.patch | 52 + ...omap-add-framedone-interrupt-support.patch | 160 + ...p-add-manual-update-detection-helper.patch | 49 + ...upport-for-manually-updated-displays.patch | 263 + ...port-for-physical-size-hints-from-di.patch | 50 + ...008-drm-omap-panel-dsi-cm-fix-driver.patch | 124 + ...p-panel-dsi-cm-add-regulator-support.patch | 135 + ...nel-dsi-cm-add-physical-size-support.patch | 67 + ...si-cm-add-external-backlight-support.patch | 247 + ...rm-omap-panel-dsi-cm-switch-to-gpiod.patch | 172 + ...omap4-droid4-improve-LCD-description.patch | 39 + ...014-ARM-dts-n950-add-display-support.patch | 122 + ...cklight-add-ti-lmu-backlight-binding.patch | 89 + ...acklight-add-TI-LMU-backlight-driver.patch | 1222 ++++ .../0017-droid4-hdmi-on-4.14-rc4.patch | 102 + .../linux-droid4-patches/droid4-config | 5042 +++++++++++++++++ 18 files changed, 7999 insertions(+) create mode 100644 extra/patches/linux-droid4-patches/0001-drm-omap-remove-unused-function-defines.patch create mode 100644 extra/patches/linux-droid4-patches/0002-drm-omap-drop-incorrect-comment.patch create mode 100644 extra/patches/linux-droid4-patches/0003-drm-omap-plane-update-fifo-size-on-ovl-setup.patch create mode 100644 extra/patches/linux-droid4-patches/0004-drm-omap-add-framedone-interrupt-support.patch create mode 100644 extra/patches/linux-droid4-patches/0005-drm-omap-add-manual-update-detection-helper.patch create mode 100644 extra/patches/linux-droid4-patches/0006-drm-omap-add-support-for-manually-updated-displays.patch create mode 100644 extra/patches/linux-droid4-patches/0007-drm-omap-add-support-for-physical-size-hints-from-di.patch create mode 100644 extra/patches/linux-droid4-patches/0008-drm-omap-panel-dsi-cm-fix-driver.patch create mode 100644 extra/patches/linux-droid4-patches/0009-drm-omap-panel-dsi-cm-add-regulator-support.patch create mode 100644 extra/patches/linux-droid4-patches/0010-drm-omap-panel-dsi-cm-add-physical-size-support.patch create mode 100644 extra/patches/linux-droid4-patches/0011-drm-omap-panel-dsi-cm-add-external-backlight-support.patch create mode 100644 extra/patches/linux-droid4-patches/0012-drm-omap-panel-dsi-cm-switch-to-gpiod.patch create mode 100644 extra/patches/linux-droid4-patches/0013-ARM-dts-omap4-droid4-improve-LCD-description.patch create mode 100644 extra/patches/linux-droid4-patches/0014-ARM-dts-n950-add-display-support.patch create mode 100644 extra/patches/linux-droid4-patches/0015-dt-bindings-backlight-add-ti-lmu-backlight-binding.patch create mode 100644 extra/patches/linux-droid4-patches/0016-backlight-add-TI-LMU-backlight-driver.patch create mode 100644 extra/patches/linux-droid4-patches/0017-droid4-hdmi-on-4.14-rc4.patch create mode 100644 extra/patches/linux-droid4-patches/droid4-config diff --git a/extra/patches/linux-droid4-patches/0001-drm-omap-remove-unused-function-defines.patch b/extra/patches/linux-droid4-patches/0001-drm-omap-remove-unused-function-defines.patch new file mode 100644 index 0000000..8ff9326 --- /dev/null +++ b/extra/patches/linux-droid4-patches/0001-drm-omap-remove-unused-function-defines.patch @@ -0,0 +1,31 @@ +From a7129365bbffa136d3987e9ae8480337882f753a Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 24 Jul 2017 19:32:58 +0200 +Subject: [PATCH 01/17] drm/omap: remove unused function defines + +Remove driver (un)register API defines. They do not even exist +anymore. + +Signed-off-by: Sebastian Reichel +Acked-by: Pavel Machek +--- + drivers/gpu/drm/omapdrm/dss/omapdss.h | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h +index 47a3316..3d25359 100644 +--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h ++++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h +@@ -584,9 +584,6 @@ struct omap_dss_driver { + + bool omapdss_is_initialized(void); + +-int omap_dss_register_driver(struct omap_dss_driver *); +-void omap_dss_unregister_driver(struct omap_dss_driver *); +- + int omapdss_register_display(struct omap_dss_device *dssdev); + void omapdss_unregister_display(struct omap_dss_device *dssdev); + +-- +2.1.4 + diff --git a/extra/patches/linux-droid4-patches/0002-drm-omap-drop-incorrect-comment.patch b/extra/patches/linux-droid4-patches/0002-drm-omap-drop-incorrect-comment.patch new file mode 100644 index 0000000..f11655a --- /dev/null +++ b/extra/patches/linux-droid4-patches/0002-drm-omap-drop-incorrect-comment.patch @@ -0,0 +1,33 @@ +From faf0e2475147bd8e755dbce7f9f1a0fb8e731e4f Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 24 Jul 2017 19:32:59 +0200 +Subject: [PATCH 02/17] drm/omap: drop incorrect comment + +The wrappers have been removed in commit 5a35876e2830 +(drm: omapdrm: Remove manual update display support) +and will not be reintroduced, since the normal sys +functions properly call the dirty callback. + +Signed-off-by: Sebastian Reichel +Acked-by: Pavel Machek +--- + drivers/gpu/drm/omapdrm/omap_fbdev.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c +index 9273118..e037818 100644 +--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c ++++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c +@@ -84,9 +84,6 @@ static struct fb_ops omap_fb_ops = { + .owner = THIS_MODULE, + DRM_FB_HELPER_DEFAULT_OPS, + +- /* Note: to properly handle manual update displays, we wrap the +- * basic fbdev ops which write to the framebuffer +- */ + .fb_read = drm_fb_helper_sys_read, + .fb_write = drm_fb_helper_sys_write, + .fb_fillrect = drm_fb_helper_sys_fillrect, +-- +2.1.4 + diff --git a/extra/patches/linux-droid4-patches/0003-drm-omap-plane-update-fifo-size-on-ovl-setup.patch b/extra/patches/linux-droid4-patches/0003-drm-omap-plane-update-fifo-size-on-ovl-setup.patch new file mode 100644 index 0000000..d117879 --- /dev/null +++ b/extra/patches/linux-droid4-patches/0003-drm-omap-plane-update-fifo-size-on-ovl-setup.patch @@ -0,0 +1,52 @@ +From 8bb3dd3ffe60be576bd6a843ebb65979e49e3e25 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 24 Jul 2017 19:33:00 +0200 +Subject: [PATCH 03/17] drm/omap: plane: update fifo size on ovl setup + +This is a workaround for a hardware bug occuring on OMAP3 +with manually updated panels. Details about the HW bug are +unknown to me, but without this fix the panel refresh does +not work at all on Nokia N950. + +Signed-off-by: Sebastian Reichel +--- + drivers/gpu/drm/omapdrm/dss/dispc.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c +index 0f4fdb2..d5d2d3c 100644 +--- a/drivers/gpu/drm/omapdrm/dss/dispc.c ++++ b/drivers/gpu/drm/omapdrm/dss/dispc.c +@@ -1491,6 +1491,18 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane, + } + } + ++void dispc_ovl_set_manual_fifo_threshold(enum omap_plane_id plane) ++{ ++ u32 fifo_low, fifo_high; ++ bool use_fifo_merge = false; ++ bool use_manual_update = true; ++ ++ dispc_ovl_compute_fifo_thresholds(plane, &fifo_low, &fifo_high, ++ use_fifo_merge, use_manual_update); ++ ++ dispc_ovl_set_fifo_threshold(plane, fifo_low, fifo_high); ++} ++ + static void dispc_ovl_set_mflag(enum omap_plane_id plane, bool enable) + { + int bit; +@@ -2654,6 +2666,10 @@ static int dispc_ovl_setup(enum omap_plane_id plane, + oi->zorder, oi->pre_mult_alpha, oi->global_alpha, + oi->rotation_type, replication, vm, mem_to_mem); + ++ /* manual mode needs other fifo thresholds */ ++ if (mgr_fld_read(channel, DISPC_MGR_FLD_STALLMODE)) ++ dispc_ovl_set_manual_fifo_threshold(plane); ++ + return r; + } + +-- +2.1.4 + diff --git a/extra/patches/linux-droid4-patches/0004-drm-omap-add-framedone-interrupt-support.patch b/extra/patches/linux-droid4-patches/0004-drm-omap-add-framedone-interrupt-support.patch new file mode 100644 index 0000000..fba570a --- /dev/null +++ b/extra/patches/linux-droid4-patches/0004-drm-omap-add-framedone-interrupt-support.patch @@ -0,0 +1,160 @@ +From 8af6ec6efc7607cc5af52af895ac7f8e63820f80 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 24 Jul 2017 19:33:01 +0200 +Subject: [PATCH 04/17] drm/omap: add framedone interrupt support + +This prepares framedone interrupt handling for +manual display update support. + +Signed-off-by: Sebastian Reichel +--- + drivers/gpu/drm/omapdrm/omap_crtc.c | 48 +++++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/omapdrm/omap_drv.h | 2 ++ + drivers/gpu/drm/omapdrm/omap_irq.c | 24 +++++++++++++++++++ + 3 files changed, 74 insertions(+) + +diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c +index cc85c16..dee9b6e 100644 +--- a/drivers/gpu/drm/omapdrm/omap_crtc.c ++++ b/drivers/gpu/drm/omapdrm/omap_crtc.c +@@ -52,6 +52,9 @@ struct omap_crtc { + bool pending; + wait_queue_head_t pending_wait; + struct drm_pending_vblank_event *event; ++ ++ void (*framedone_handler)(void *); ++ void *framedone_handler_data; + }; + + /* ----------------------------------------------------------------------------- +@@ -248,6 +251,17 @@ static int omap_crtc_dss_register_framedone( + enum omap_channel channel, + void (*handler)(void *), void *data) + { ++ struct omap_crtc *omap_crtc = omap_crtcs[channel]; ++ struct drm_device *dev = omap_crtc->base.dev; ++ ++ if (omap_crtc->framedone_handler) ++ return -EBUSY; ++ ++ dev_dbg(dev->dev, "register framedone %s", omap_crtc->name); ++ ++ omap_crtc->framedone_handler = handler; ++ omap_crtc->framedone_handler_data = data; ++ + return 0; + } + +@@ -255,6 +269,16 @@ static void omap_crtc_dss_unregister_framedone( + enum omap_channel channel, + void (*handler)(void *), void *data) + { ++ struct omap_crtc *omap_crtc = omap_crtcs[channel]; ++ struct drm_device *dev = omap_crtc->base.dev; ++ ++ dev_dbg(dev->dev, "unregister framedone %s", omap_crtc->name); ++ ++ WARN_ON(omap_crtc->framedone_handler != handler); ++ WARN_ON(omap_crtc->framedone_handler_data != data); ++ ++ omap_crtc->framedone_handler = NULL; ++ omap_crtc->framedone_handler_data = NULL; + } + + static const struct dss_mgr_ops mgr_ops = { +@@ -322,6 +346,30 @@ void omap_crtc_vblank_irq(struct drm_crtc *crtc) + DBG("%s: apply done", omap_crtc->name); + } + ++void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus) ++{ ++ struct omap_crtc *omap_crtc = to_omap_crtc(crtc); ++ ++ if (!omap_crtc->framedone_handler) { ++ dev_warn(omap_crtc->base.dev->dev, "no framedone handler?"); ++ return; ++ } ++ ++ omap_crtc->framedone_handler(omap_crtc->framedone_handler_data); ++ ++ spin_lock(&crtc->dev->event_lock); ++ /* Send the vblank event if one has been requested. */ ++ if (omap_crtc->event) { ++ drm_crtc_send_vblank_event(crtc, omap_crtc->event); ++ omap_crtc->event = NULL; ++ } ++ omap_crtc->pending = false; ++ spin_unlock(&crtc->dev->event_lock); ++ ++ /* Wake up omap_atomic_complete. */ ++ wake_up(&omap_crtc->pending_wait); ++} ++ + static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc) + { + struct omap_drm_private *priv = crtc->dev->dev_private; +diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h +index 4bd1e90..22f3d94 100644 +--- a/drivers/gpu/drm/omapdrm/omap_drv.h ++++ b/drivers/gpu/drm/omapdrm/omap_drv.h +@@ -97,6 +97,7 @@ void omap_gem_describe_objects(struct list_head *list, struct seq_file *m); + int omap_gem_resume(struct device *dev); + #endif + ++int omap_irq_enable_framedone(struct drm_crtc *crtc, bool enable); + int omap_irq_enable_vblank(struct drm_crtc *crtc); + void omap_irq_disable_vblank(struct drm_crtc *crtc); + void omap_drm_irq_uninstall(struct drm_device *dev); +@@ -124,6 +125,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, + int omap_crtc_wait_pending(struct drm_crtc *crtc); + void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus); + void omap_crtc_vblank_irq(struct drm_crtc *crtc); ++void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus); + + struct drm_plane *omap_plane_init(struct drm_device *dev, + int idx, enum drm_plane_type type, +diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c +index 013b0bb..301c0e7 100644 +--- a/drivers/gpu/drm/omapdrm/omap_irq.c ++++ b/drivers/gpu/drm/omapdrm/omap_irq.c +@@ -87,6 +87,27 @@ int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait, + return ret == 0 ? -1 : 0; + } + ++int omap_irq_enable_framedone(struct drm_crtc *crtc, bool enable) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct omap_drm_private *priv = dev->dev_private; ++ unsigned long flags; ++ enum omap_channel channel = omap_crtc_channel(crtc); ++ int framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(channel); ++ ++ DBG("dev=%p, crtc=%u, enable=%d", dev, channel, enable); ++ ++ spin_lock_irqsave(&priv->wait_lock, flags); ++ if (enable) ++ priv->irq_mask |= framedone_irq; ++ else ++ priv->irq_mask &= ~framedone_irq; ++ omap_irq_update(dev); ++ spin_unlock_irqrestore(&priv->wait_lock, flags); ++ ++ return 0; ++} ++ + /** + * enable_vblank - enable vblank interrupt events + * @dev: DRM device +@@ -217,6 +238,9 @@ static irqreturn_t omap_irq_handler(int irq, void *arg) + + if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(channel)) + omap_crtc_error_irq(crtc, irqstatus); ++ ++ if (irqstatus & priv->dispc_ops->mgr_get_framedone_irq(channel)) ++ omap_crtc_framedone_irq(crtc, irqstatus); + } + + omap_irq_ocp_error_handler(dev, irqstatus); +-- +2.1.4 + diff --git a/extra/patches/linux-droid4-patches/0005-drm-omap-add-manual-update-detection-helper.patch b/extra/patches/linux-droid4-patches/0005-drm-omap-add-manual-update-detection-helper.patch new file mode 100644 index 0000000..030ec95 --- /dev/null +++ b/extra/patches/linux-droid4-patches/0005-drm-omap-add-manual-update-detection-helper.patch @@ -0,0 +1,49 @@ +From 6dae0575adf3b15c51832bfa8c0320e8526e9b8e Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 24 Jul 2017 19:33:02 +0200 +Subject: [PATCH 05/17] drm/omap: add manual update detection helper + +In preparation for manually updated display support, such as DSI +command mode panels, this adds a simple helper to see if a connector +is manually updated. + +Signed-off-by: Sebastian Reichel +--- + drivers/gpu/drm/omapdrm/omap_connector.c | 8 ++++++++ + drivers/gpu/drm/omapdrm/omap_drv.h | 1 + + 2 files changed, 9 insertions(+) + +diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c +index aa5ba9a..4f4c7ef 100644 +--- a/drivers/gpu/drm/omapdrm/omap_connector.c ++++ b/drivers/gpu/drm/omapdrm/omap_connector.c +@@ -59,6 +59,14 @@ bool omap_connector_get_hdmi_mode(struct drm_connector *connector) + return omap_connector->hdmi_mode; + } + ++bool omap_connector_get_manually_updated(struct drm_connector *connector) ++{ ++ struct omap_connector *omap_connector = to_omap_connector(connector); ++ ++ return !!(omap_connector->dssdev->caps & ++ OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE); ++} ++ + static enum drm_connector_status omap_connector_detect( + struct drm_connector *connector, bool force) + { +diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h +index 22f3d94..f6c48f2 100644 +--- a/drivers/gpu/drm/omapdrm/omap_drv.h ++++ b/drivers/gpu/drm/omapdrm/omap_drv.h +@@ -142,6 +142,7 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, + struct drm_encoder *omap_connector_attached_encoder( + struct drm_connector *connector); + bool omap_connector_get_hdmi_mode(struct drm_connector *connector); ++bool omap_connector_get_manually_updated(struct drm_connector *connector); + + struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev, + struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd); +-- +2.1.4 + diff --git a/extra/patches/linux-droid4-patches/0006-drm-omap-add-support-for-manually-updated-displays.patch b/extra/patches/linux-droid4-patches/0006-drm-omap-add-support-for-manually-updated-displays.patch new file mode 100644 index 0000000..86822c0 --- /dev/null +++ b/extra/patches/linux-droid4-patches/0006-drm-omap-add-support-for-manually-updated-displays.patch @@ -0,0 +1,263 @@ +From 2a51a11e2f2705bbf7642e2e08ae6b2f1372d79c Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 24 Jul 2017 19:33:03 +0200 +Subject: [PATCH 06/17] drm/omap: add support for manually updated displays + +This adds the required infrastructure for manually +updated displays, such as DSI command mode panels. + +While those panels often support partial updates +we currently always do a full refresh. Display +will be refreshed when something calls the dirty +callback, such as libdrm's drmModeDirtyFB(). + +This is currently being implemented for the kernel +console and for Xorg. Weston currently does not +implement this and is known not to work on manually +updated displays. + +Signed-off-by: Sebastian Reichel +--- + drivers/gpu/drm/omapdrm/omap_crtc.c | 110 +++++++++++++++++++++++++++++++++--- + drivers/gpu/drm/omapdrm/omap_drv.h | 1 + + drivers/gpu/drm/omapdrm/omap_fb.c | 20 +++++++ + 3 files changed, 123 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c +index dee9b6e..8255241 100644 +--- a/drivers/gpu/drm/omapdrm/omap_crtc.c ++++ b/drivers/gpu/drm/omapdrm/omap_crtc.c +@@ -52,6 +52,7 @@ struct omap_crtc { + bool pending; + wait_queue_head_t pending_wait; + struct drm_pending_vblank_event *event; ++ struct delayed_work update_work; + + void (*framedone_handler)(void *); + void *framedone_handler_data; +@@ -143,6 +144,28 @@ static void omap_crtc_dss_disconnect(enum omap_channel channel, + + static void omap_crtc_dss_start_update(enum omap_channel channel) + { ++ struct omap_crtc *omap_crtc = omap_crtcs[channel]; ++ struct omap_drm_private *priv = omap_crtc->base.dev->dev_private; ++ ++ priv->dispc_ops->mgr_enable(channel, true); ++} ++ ++static bool omap_crtc_is_manually_updated(struct drm_crtc *crtc) ++{ ++ struct drm_connector *connector; ++ struct drm_connector_list_iter conn_iter; ++ bool result = false; ++ ++ drm_connector_list_iter_begin(crtc->dev, &conn_iter); ++ drm_for_each_connector_iter(connector, &conn_iter) { ++ if (connector->state->crtc != crtc) ++ continue; ++ result = omap_connector_get_manually_updated(connector); ++ break; ++ } ++ drm_connector_list_iter_end(&conn_iter); ++ ++ return result; + } + + /* Called only from the encoder enable/disable and suspend/resume handlers. */ +@@ -154,12 +177,17 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) + enum omap_channel channel = omap_crtc->channel; + struct omap_irq_wait *wait; + u32 framedone_irq, vsync_irq; ++ bool is_manual = omap_crtc_is_manually_updated(crtc); ++ enum omap_display_type type = omap_crtc_output[channel]->output_type; + int ret; + + if (WARN_ON(omap_crtc->enabled == enable)) + return; + +- if (omap_crtc_output[channel]->output_type == OMAP_DISPLAY_TYPE_HDMI) { ++ if (is_manual) ++ omap_irq_enable_framedone(crtc, enable); ++ ++ if (is_manual || type == OMAP_DISPLAY_TYPE_HDMI) { + priv->dispc_ops->mgr_enable(channel, enable); + omap_crtc->enabled = enable; + return; +@@ -210,7 +238,6 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) + } + } + +- + static int omap_crtc_dss_enable(enum omap_channel channel) + { + struct omap_crtc *omap_crtc = omap_crtcs[channel]; +@@ -370,6 +397,53 @@ void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus) + wake_up(&omap_crtc->pending_wait); + } + ++void omap_crtc_flush(struct drm_crtc *crtc) ++{ ++ struct omap_crtc *omap_crtc = to_omap_crtc(crtc); ++ ++ if (!omap_crtc_is_manually_updated(crtc)) ++ return; ++ ++ if (!delayed_work_pending(&omap_crtc->update_work)) ++ schedule_delayed_work(&omap_crtc->update_work, 0); ++} ++ ++static void omap_crtc_manual_display_update(struct work_struct *data) ++{ ++ struct omap_crtc *omap_crtc = ++ container_of(data, struct omap_crtc, update_work.work); ++ struct omap_dss_device *dssdev = omap_crtc_output[omap_crtc->channel]; ++ struct drm_device *dev = omap_crtc->base.dev; ++ struct omap_dss_driver *dssdrv; ++ int ret, width, height; ++ ++ if (!dssdev || !dssdev->dst) { ++ dev_err_once(dev->dev, "missing dssdev!"); ++ return; ++ } ++ ++ dssdev = dssdev->dst; ++ dssdrv = dssdev->driver; ++ ++ if (!dssdrv || !dssdrv->update) { ++ dev_err_once(dev->dev, "incorrect dssdrv!"); ++ return; ++ } ++ ++ if (dssdrv->sync) ++ dssdrv->sync(dssdev); ++ ++ width = dssdev->panel.vm.hactive; ++ height = dssdev->panel.vm.vactive; ++ ret = dssdrv->update(dssdev, 0, 0, width, height); ++ if (ret < 0) { ++ spin_lock_irq(&dev->event_lock); ++ omap_crtc->pending = false; ++ spin_unlock_irq(&dev->event_lock); ++ wake_up(&omap_crtc->pending_wait); ++ } ++} ++ + static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc) + { + struct omap_drm_private *priv = crtc->dev->dev_private; +@@ -422,6 +496,10 @@ static void omap_crtc_atomic_enable(struct drm_crtc *crtc, + + DBG("%s", omap_crtc->name); + ++ /* manual updated display will not trigger vsync irq */ ++ if (omap_crtc_is_manually_updated(crtc)) ++ return; ++ + spin_lock_irq(&crtc->dev->event_lock); + drm_crtc_vblank_on(crtc); + ret = drm_crtc_vblank_get(crtc); +@@ -435,6 +513,7 @@ static void omap_crtc_atomic_disable(struct drm_crtc *crtc, + struct drm_crtc_state *old_state) + { + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); ++ struct drm_device *dev = crtc->dev; + + DBG("%s", omap_crtc->name); + +@@ -445,6 +524,11 @@ static void omap_crtc_atomic_disable(struct drm_crtc *crtc, + } + spin_unlock_irq(&crtc->dev->event_lock); + ++ cancel_delayed_work(&omap_crtc->update_work); ++ ++ if (!omap_crtc_wait_pending(crtc)) ++ dev_warn(dev->dev, "manual display update did not finish!"); ++ + drm_crtc_vblank_off(crtc); + } + +@@ -559,13 +643,20 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc, + + DBG("%s: GO", omap_crtc->name); + +- ret = drm_crtc_vblank_get(crtc); +- WARN_ON(ret != 0); ++ if (!omap_crtc_is_manually_updated(crtc)) { ++ ret = drm_crtc_vblank_get(crtc); ++ WARN_ON(ret != 0); + +- spin_lock_irq(&crtc->dev->event_lock); +- priv->dispc_ops->mgr_go(omap_crtc->channel); +- omap_crtc_arm_event(crtc); +- spin_unlock_irq(&crtc->dev->event_lock); ++ spin_lock_irq(&crtc->dev->event_lock); ++ priv->dispc_ops->mgr_go(omap_crtc->channel); ++ omap_crtc_arm_event(crtc); ++ spin_unlock_irq(&crtc->dev->event_lock); ++ } else { ++ spin_lock_irq(&crtc->dev->event_lock); ++ omap_crtc_flush(crtc); ++ omap_crtc_arm_event(crtc); ++ spin_unlock_irq(&crtc->dev->event_lock); ++ } + } + + static int omap_crtc_atomic_set_property(struct drm_crtc *crtc, +@@ -726,6 +817,9 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, + omap_crtc->channel = channel; + omap_crtc->name = channel_names[channel]; + ++ INIT_DELAYED_WORK(&omap_crtc->update_work, ++ omap_crtc_manual_display_update); ++ + ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL, + &omap_crtc_funcs, NULL); + if (ret < 0) { +diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h +index f6c48f2..3cb9f9a 100644 +--- a/drivers/gpu/drm/omapdrm/omap_drv.h ++++ b/drivers/gpu/drm/omapdrm/omap_drv.h +@@ -126,6 +126,7 @@ int omap_crtc_wait_pending(struct drm_crtc *crtc); + void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus); + void omap_crtc_vblank_irq(struct drm_crtc *crtc); + void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus); ++void omap_crtc_flush(struct drm_crtc *crtc); + + struct drm_plane *omap_plane_init(struct drm_device *dev, + int idx, enum drm_plane_type type, +diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c +index b1a762b..9492be6 100644 +--- a/drivers/gpu/drm/omapdrm/omap_fb.c ++++ b/drivers/gpu/drm/omapdrm/omap_fb.c +@@ -97,8 +97,28 @@ static void omap_framebuffer_destroy(struct drm_framebuffer *fb) + kfree(omap_fb); + } + ++static int omap_framebuffer_dirty(struct drm_framebuffer *fb, ++ struct drm_file *file_priv, ++ unsigned flags, unsigned color, ++ struct drm_clip_rect *clips, ++ unsigned num_clips) ++{ ++ struct drm_connector *connector = NULL; ++ ++ drm_modeset_lock_all(fb->dev); ++ ++ while ((connector = omap_framebuffer_get_next_connector(fb, connector))) ++ if (connector->encoder && connector->encoder->crtc) ++ omap_crtc_flush(connector->encoder->crtc); ++ ++ drm_modeset_unlock_all(fb->dev); ++ ++ return 0; ++} ++ + static const struct drm_framebuffer_funcs omap_framebuffer_funcs = { + .create_handle = omap_framebuffer_create_handle, ++ .dirty = omap_framebuffer_dirty, + .destroy = omap_framebuffer_destroy, + }; + +-- +2.1.4 + diff --git a/extra/patches/linux-droid4-patches/0007-drm-omap-add-support-for-physical-size-hints-from-di.patch b/extra/patches/linux-droid4-patches/0007-drm-omap-add-support-for-physical-size-hints-from-di.patch new file mode 100644 index 0000000..20f4a51 --- /dev/null +++ b/extra/patches/linux-droid4-patches/0007-drm-omap-add-support-for-physical-size-hints-from-di.patch @@ -0,0 +1,50 @@ +From 1e66c0a2f776d6054c2324daf55fc3e3df126c33 Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Mon, 24 Jul 2017 19:33:04 +0200 +Subject: [PATCH 07/17] drm/omap: add support for physical size hints from + display drivers + +While physical size information is automatically parsed for EDID +based displays, we need to provide it manually for displays providing +one fixed mode. + +Signed-off-by: Sebastian Reichel +Acked-by: Pavel Machek +--- + drivers/gpu/drm/omapdrm/dss/omapdss.h | 2 ++ + drivers/gpu/drm/omapdrm/omap_connector.c | 6 ++++++ + 2 files changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h +index 3d25359..5be6ff8 100644 +--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h ++++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h +@@ -562,6 +562,8 @@ struct omap_dss_driver { + struct videomode *vm); + void (*get_timings)(struct omap_dss_device *dssdev, + struct videomode *vm); ++ void (*get_size)(struct omap_dss_device *dssdev, ++ unsigned int *width, unsigned int *height); + + int (*set_wss)(struct omap_dss_device *dssdev, u32 wss); + u32 (*get_wss)(struct omap_dss_device *dssdev); +diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c +index 4f4c7ef..8874f55 100644 +--- a/drivers/gpu/drm/omapdrm/omap_connector.c ++++ b/drivers/gpu/drm/omapdrm/omap_connector.c +@@ -157,6 +157,12 @@ static int omap_connector_get_modes(struct drm_connector *connector) + drm_mode_set_name(mode); + drm_mode_probed_add(connector, mode); + ++ if (dssdrv->get_size) { ++ dssdrv->get_size(dssdev, ++ &connector->display_info.width_mm, ++ &connector->display_info.height_mm); ++ } ++ + n = 1; + } + +-- +2.1.4 + diff --git a/extra/patches/linux-droid4-patches/0008-drm-omap-panel-dsi-cm-fix-driver.patch b/extra/patches/linux-droid4-patches/0008-drm-omap-panel-dsi-cm-fix-driver.patch new file mode 100644 index 0000000..3db803e --- /dev/null +++ b/extra/patches/linux-droid4-patches/0008-drm-omap-panel-dsi-cm-fix-driver.patch @@ -0,0 +1,124 @@ +From 328a31aeb9e4cb56f312be7722010ede59ef96be Mon Sep 17 00:00:00 2001 +From: Tony Lindgren +Date: Mon, 24 Jul 2017 19:33:05 +0200 +Subject: [PATCH 08/17] drm/omap: panel-dsi-cm: fix driver + +This adds support for get_timings() and check_timings() +to get the driver working and properly initializes the +timing information from DT. + +Signed-off-by: Tony Lindgren +Signed-off-by: Sebastian Reichel +--- + drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 56 ++++++++++++++++++++++--- + 1 file changed, 51 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c +index 92c556a..905b717 100644 +--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c ++++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c +@@ -25,6 +25,7 @@ + #include + + #include