Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1592642 > unrolled thread
| Started by | Sebastian Reichel <sre@kernel.org> |
|---|---|
| First post | 2017-03-05 01:00 +0100 |
| Last post | 2017-03-05 01:50 +0100 |
| Articles | 15 — 2 participants |
Back to article view | Back to linux.kernel
[PATCHv2 00/10] Nokia N950 basic display support Sebastian Reichel <sre@kernel.org> - 2017-03-05 01:00 +0100
[PATCHv2 03/10] Revert "drm: omapdrm: Remove manual update display support" Sebastian Reichel <sre@kernel.org> - 2017-03-05 01:50 +0100
[PATCHv2 07/10] drm: omapdrm: plane: update fifo size on atomic update Sebastian Reichel <sre@kernel.org> - 2017-03-05 01:50 +0100
[PATCHv2 01/10] drm: omapdrm: panel-dsi-cm: Fix probe for device tree Sebastian Reichel <sre@kernel.org> - 2017-03-05 01:50 +0100
[PATCHv2 08/10] drm: omapdrm: crtc: handle framedone directly Sebastian Reichel <sre@kernel.org> - 2017-03-05 01:50 +0100
[PATCHv2 05/10] drm: omapdrm: crtc: detect manually updated displays Sebastian Reichel <sre@kernel.org> - 2017-03-05 01:50 +0100
Re: [PATCHv2 05/10] drm: omapdrm: crtc: detect manually updated displays Tony Lindgren <tony@atomide.com> - 2017-03-05 06:50 +0100
[PATCHv2 10/10] ARM: dts: n950: add display support Sebastian Reichel <sre@kernel.org> - 2017-03-05 01:50 +0100
[PATCHv2 09/10] drm: omapdrm: crtc: get manual mode displays working Sebastian Reichel <sre@kernel.org> - 2017-03-05 01:50 +0100
Re: [PATCHv2 09/10] drm: omapdrm: crtc: get manual mode displays working Tony Lindgren <tony@atomide.com> - 2017-03-05 06:50 +0100
[PATCHv2 04/10] drm: omapdrm: crtc: save framedone callback from dss Sebastian Reichel <sre@kernel.org> - 2017-03-05 01:50 +0100
Re: [PATCHv2 04/10] drm: omapdrm: crtc: save framedone callback from dss Tony Lindgren <tony@atomide.com> - 2017-03-05 06:50 +0100
[PATCHv2 02/10] drm: omapdrm: panel-dsi-cm: add regulator support Sebastian Reichel <sre@kernel.org> - 2017-03-05 01:50 +0100
Re: [PATCHv2 02/10] drm: omapdrm: panel-dsi-cm: add regulator support Tony Lindgren <tony@atomide.com> - 2017-03-05 06:50 +0100
[PATCHv2 06/10] drm: omapdrm: crtc: add support for manual updated displays Sebastian Reichel <sre@kernel.org> - 2017-03-05 01:50 +0100
| From | Sebastian Reichel <sre@kernel.org> |
|---|---|
| Date | 2017-03-05 01:00 +0100 |
| Subject | [PATCHv2 00/10] Nokia N950 basic display support |
| Message-ID | <thrKF-8kZ-5@gated-at.bofh.it> |
Hi, Some of you may remember, that I sent a series for the N950 display some time ago. N950 has command mode DSI panel, so the main part of the patchset takes care of adding manual display update support in omapdrm. The N950 also requires display rotation (the panel is mounted vertically and bottom-up) and offset. The required bits will be sent separately. The patchset is based on 2d62e0768d3c, which is the current commit torvald's master branch points to. I tested the patches on N950 with kernel console (fbcon), Tomi's kmstest and Xorg from Debian sid. Rough changelog, most of that work was done by Tony (thanks!) * lots of patches dropped for now * rebased to current omapdrm interface * added OMAP4 support * misc. cleanup -- Sebastian Sebastian Reichel (7): drm: omapdrm: panel-dsi-cm: add regulator support Revert "drm: omapdrm: Remove manual update display support" drm: omapdrm: crtc: save framedone callback from dss drm: omapdrm: crtc: detect manually updated displays drm: omapdrm: crtc: add support for manual updated displays drm: omapdrm: plane: update fifo size on atomic update ARM: dts: n950: add display support Tony Lindgren (3): drm: omapdrm: panel-dsi-cm: Fix probe for device tree drm: omapdrm: crtc: handle framedone directly drm: omapdrm: crtc: get manual mode displays working arch/arm/boot/dts/omap3-n950.dts | 89 +++++++++++++ drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 120 ++++++++++++++--- drivers/gpu/drm/omapdrm/dss/dispc.c | 2 + drivers/gpu/drm/omapdrm/dss/omapdss.h | 5 + drivers/gpu/drm/omapdrm/dss/output.c | 6 + drivers/gpu/drm/omapdrm/omap_connector.c | 7 + drivers/gpu/drm/omapdrm/omap_crtc.c | 165 ++++++++++++++++++++++-- drivers/gpu/drm/omapdrm/omap_drv.h | 8 ++ drivers/gpu/drm/omapdrm/omap_fb.c | 28 ++++ drivers/gpu/drm/omapdrm/omap_fbdev.c | 57 +++++++- drivers/gpu/drm/omapdrm/omap_irq.c | 7 +- drivers/gpu/drm/omapdrm/omap_plane.c | 23 ++++ 12 files changed, 487 insertions(+), 30 deletions(-) -- 2.11.0
[toc] | [next] | [standalone]
| From | Sebastian Reichel <sre@kernel.org> |
|---|---|
| Date | 2017-03-05 01:50 +0100 |
| Subject | [PATCHv2 03/10] Revert "drm: omapdrm: Remove manual update display support" |
| Message-ID | <thsx3-rY-1@gated-at.bofh.it> |
| In reply to | #1592642 |
This reverts commit 5a35876e2830511cb8110667fc426c6a6165a593.
Revert the removal of manual update display support in
preparation for DSI command mode panels.
Signed-off-By: Sebastian Reichel <sre@kernel.org>
[tony@atomide.com: left out unused omap_framebuffer_dirty]
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
drivers/gpu/drm/omapdrm/omap_connector.c | 12 +++++++
drivers/gpu/drm/omapdrm/omap_drv.h | 4 +++
drivers/gpu/drm/omapdrm/omap_fb.c | 28 ++++++++++++++++
drivers/gpu/drm/omapdrm/omap_fbdev.c | 57 +++++++++++++++++++++++++++++---
4 files changed, 97 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index f90e2d22c5ec..7b2a9f680dce 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -205,6 +205,18 @@ static const struct drm_connector_helper_funcs omap_connector_helper_funcs = {
.mode_valid = omap_connector_mode_valid,
};
+/* flush an area of the framebuffer (in case of manual update display that
+ * is not automatically flushed)
+ */
+void omap_connector_flush(struct drm_connector *connector,
+ int x, int y, int w, int h)
+{
+ struct omap_connector *omap_connector = to_omap_connector(connector);
+
+ /* TODO: enable when supported in dss */
+ VERB("%s: %d,%d, %dx%d", omap_connector->dssdev->name, x, y, w, h);
+}
+
/* initialize connector */
struct drm_connector *omap_connector_init(struct drm_device *dev,
int connector_type, struct omap_dss_device *dssdev,
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 65977982f15f..5b1061586401 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -155,6 +155,8 @@ 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);
+void omap_connector_flush(struct drm_connector *connector,
+ int x, int y, int w, int h);
uint32_t omap_framebuffer_get_formats(uint32_t *pixel_formats,
uint32_t max_formats, enum omap_color_mode supported_modes);
@@ -169,6 +171,8 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
struct drm_connector *omap_framebuffer_get_next_connector(
struct drm_framebuffer *fb, struct drm_connector *from);
bool omap_framebuffer_supports_rotation(struct drm_framebuffer *fb);
+void omap_framebuffer_flush(struct drm_framebuffer *fb,
+ int x, int y, int w, int h);
void omap_gem_init(struct drm_device *dev);
void omap_gem_deinit(struct drm_device *dev);
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index 29dc677dd4d3..b6ae28fe3257 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -333,6 +333,34 @@ struct drm_connector *omap_framebuffer_get_next_connector(
return NULL;
}
+/* flush an area of the framebuffer (in case of manual update display that
+ * is not automatically flushed)
+ */
+void omap_framebuffer_flush(struct drm_framebuffer *fb,
+ int x, int y, int w, int h)
+{
+ struct drm_connector *connector = NULL;
+
+ VERB("flush: %d,%d %dx%d, fb=%p", x, y, w, h, fb);
+
+ /* FIXME: This is racy - no protection against modeset config changes. */
+ while ((connector = omap_framebuffer_get_next_connector(fb, connector))) {
+ /* only consider connectors that are part of a chain */
+ if (connector->encoder && connector->encoder->crtc) {
+ /* TODO: maybe this should propagate thru the crtc who
+ * could do the coordinate translation..
+ */
+ struct drm_crtc *crtc = connector->encoder->crtc;
+ int cx = max(0, x - crtc->x);
+ int cy = max(0, y - crtc->y);
+ int cw = w + (x - crtc->x) - cx;
+ int ch = h + (y - crtc->y) - cy;
+
+ omap_connector_flush(connector, cx, cy, cw, ch);
+ }
+ }
+}
+
#ifdef CONFIG_DEBUG_FS
void omap_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m)
{
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index 942c4d483008..6c52a9fa4a37 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -42,8 +42,42 @@ struct omap_fbdev {
struct work_struct work;
};
+static void omap_fbdev_flush(struct fb_info *fbi, int x, int y, int w, int h);
static struct drm_fb_helper *get_fb(struct fb_info *fbi);
+static ssize_t omap_fbdev_write(struct fb_info *fbi, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ ssize_t res;
+
+ res = fb_sys_write(fbi, buf, count, ppos);
+ omap_fbdev_flush(fbi, 0, 0, fbi->var.xres, fbi->var.yres);
+
+ return res;
+}
+
+static void omap_fbdev_fillrect(struct fb_info *fbi,
+ const struct fb_fillrect *rect)
+{
+ sys_fillrect(fbi, rect);
+ omap_fbdev_flush(fbi, rect->dx, rect->dy, rect->width, rect->height);
+}
+
+static void omap_fbdev_copyarea(struct fb_info *fbi,
+ const struct fb_copyarea *area)
+{
+ sys_copyarea(fbi, area);
+ omap_fbdev_flush(fbi, area->dx, area->dy, area->width, area->height);
+}
+
+static void omap_fbdev_imageblit(struct fb_info *fbi,
+ const struct fb_image *image)
+{
+ sys_imageblit(fbi, image);
+ omap_fbdev_flush(fbi, image->dx, image->dy,
+ image->width, image->height);
+}
+
static void pan_worker(struct work_struct *work)
{
struct omap_fbdev *fbdev = container_of(work, struct omap_fbdev, work);
@@ -88,10 +122,10 @@ static struct fb_ops omap_fb_ops = {
* 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,
- .fb_copyarea = drm_fb_helper_sys_copyarea,
- .fb_imageblit = drm_fb_helper_sys_imageblit,
+ .fb_write = omap_fbdev_write,
+ .fb_fillrect = omap_fbdev_fillrect,
+ .fb_copyarea = omap_fbdev_copyarea,
+ .fb_imageblit = omap_fbdev_imageblit,
.fb_pan_display = omap_fbdev_pan_display,
};
@@ -245,6 +279,21 @@ static struct drm_fb_helper *get_fb(struct fb_info *fbi)
return fbi->par;
}
+/* flush an area of the framebuffer (in case of manual update display that
+ * is not automatically flushed)
+ */
+static void omap_fbdev_flush(struct fb_info *fbi, int x, int y, int w, int h)
+{
+ struct drm_fb_helper *helper = get_fb(fbi);
+
+ if (!helper)
+ return;
+
+ VERB("flush fbdev: %d,%d %dx%d, fbi=%p", x, y, w, h, fbi);
+
+ omap_framebuffer_flush(helper->fb, x, y, w, h);
+}
+
/* initialize fbdev helper */
struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
{
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Sebastian Reichel <sre@kernel.org> |
|---|---|
| Date | 2017-03-05 01:50 +0100 |
| Subject | [PATCHv2 07/10] drm: omapdrm: plane: update fifo size on atomic update |
| Message-ID | <thsx3-rY-5@gated-at.bofh.it> |
| In reply to | #1592642 |
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 <sre@kernel.org>
---
drivers/gpu/drm/omapdrm/dss/dispc.c | 2 ++
drivers/gpu/drm/omapdrm/dss/omapdss.h | 4 ++++
drivers/gpu/drm/omapdrm/omap_drv.h | 1 +
drivers/gpu/drm/omapdrm/omap_plane.c | 23 +++++++++++++++++++++++
4 files changed, 30 insertions(+)
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index d956e6266368..97240e59b248 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -1321,6 +1321,7 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
plane != OMAP_DSS_WB)
dispc_write_reg(DISPC_OVL_PRELOAD(plane), min(high, 0xfffu));
}
+EXPORT_SYMBOL(dispc_ovl_set_fifo_threshold);
void dispc_enable_fifomerge(bool enable)
{
@@ -1379,6 +1380,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
*fifo_high = total_fifo_size - buf_unit;
}
}
+EXPORT_SYMBOL(dispc_ovl_compute_fifo_thresholds);
static void dispc_ovl_set_mflag(enum omap_plane plane, bool enable)
{
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 5666ecbe4b80..65c3530a3b53 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -878,6 +878,10 @@ void dispc_ovl_set_channel_out(enum omap_plane plane,
enum omap_channel channel);
int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
bool replication, const struct videomode *vm, bool mem_to_mem);
+void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
+ u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
+ bool manual_update);
+void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum omap_channel channel);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index ee8901dc0381..71b5c5e25ee4 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -146,6 +146,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
u32 possible_crtcs);
void omap_plane_install_properties(struct drm_plane *plane,
struct drm_mode_object *obj);
+void omap_plane_update_fifo(struct drm_plane *plane);
struct drm_encoder *omap_encoder_init(struct drm_device *dev,
struct omap_dss_device *dssdev);
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 386d90af70f7..8d290cfe8925 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -73,6 +73,28 @@ static void omap_plane_cleanup_fb(struct drm_plane *plane,
omap_framebuffer_unpin(old_state->fb);
}
+void omap_plane_update_fifo(struct drm_plane *plane)
+{
+ struct omap_plane *omap_plane = to_omap_plane(plane);
+ struct drm_plane_state *state = plane->state;
+ struct drm_device *dev = plane->dev;
+ bool use_fifo_merge = false;
+ u32 fifo_low, fifo_high;
+ bool use_manual_update;
+
+ if (!dispc_ovl_enabled(omap_plane->id))
+ return;
+
+ use_manual_update = omap_crtc_is_manual_updated(state->crtc);
+
+ dispc_ovl_compute_fifo_thresholds(omap_plane->id, &fifo_low, &fifo_high,
+ use_fifo_merge, use_manual_update);
+
+ dev_dbg(dev->dev, "update fifo: %d %d", fifo_low, fifo_high);
+
+ dispc_ovl_set_fifo_threshold(omap_plane->id, fifo_low, fifo_high);
+}
+
static void omap_plane_atomic_update(struct drm_plane *plane,
struct drm_plane_state *old_state)
{
@@ -137,6 +159,7 @@ static void omap_plane_atomic_update(struct drm_plane *plane,
}
dispc_ovl_enable(omap_plane->id, true);
+ omap_plane_update_fifo(plane);
}
static void omap_plane_atomic_disable(struct drm_plane *plane,
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Sebastian Reichel <sre@kernel.org> |
|---|---|
| Date | 2017-03-05 01:50 +0100 |
| Subject | [PATCHv2 01/10] drm: omapdrm: panel-dsi-cm: Fix probe for device tree |
| Message-ID | <thsx3-rY-3@gated-at.bofh.it> |
| In reply to | #1592642 |
From: Tony Lindgren <tony@atomide.com>
Things are a bit whacked right now for panel-dsi-cm:
1. We're missing call to of_get_display_timing() and
videomode_from_timing()
2. We need to call dsicm_probe_of() after we initialize the
default values to not overwrite device tree configured
values
3. We need to implement minimal get_timings() and check_timings()
for the panel to work
With these changes we get panel-dsi-cm to probe with device tree
configuraion. Note that the dsicm_check_timings adapted from an
earlier patch by Sebastian Reichel <sre@kernel.org>.
Signed-off-by: Tony Lindgren <tony@atomide.com>
Tested-By: Sebastian Reichel <sre@kernel.org>
---
drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 65 ++++++++++++++++++++-----
1 file changed, 52 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index ac5800c72cb4..ad1058fafe92 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 <linux/of_gpio.h>
#include <video/mipi_display.h>
+#include <video/of_display_timing.h>
#include "../dss/omapdss.h"
@@ -379,13 +380,6 @@ static const struct backlight_ops dsicm_bl_ops = {
.update_status = dsicm_bl_update_status,
};
-static void dsicm_get_resolution(struct omap_dss_device *dssdev,
- u16 *xres, u16 *yres)
-{
- *xres = dssdev->panel.vm.hactive;
- *yres = dssdev->panel.vm.vactive;
-}
-
static ssize_t dsicm_num_errors_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1106,6 +1100,36 @@ static void dsicm_ulps_work(struct work_struct *work)
mutex_unlock(&ddata->lock);
}
+static void dsicm_get_timings(struct omap_dss_device *dssdev,
+ struct videomode *vm)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ *vm = ddata->vm;
+}
+
+static int dsicm_check_timings(struct omap_dss_device *dssdev,
+ struct videomode *vm)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ int ret = 0;
+
+ if (vm->hactive != ddata->vm.hactive)
+ ret = -EINVAL;
+
+ if (vm->vactive != ddata->vm.vactive)
+ ret = -EINVAL;
+
+ if (ret) {
+ dev_warn(dssdev->dev, "wrong resolution: %d x %d",
+ vm->hactive, vm->vactive);
+ dev_warn(dssdev->dev, "panel resolution: %d x %d",
+ ddata->vm.hactive, ddata->vm.vactive);
+ }
+
+ return ret;
+}
+
static struct omap_dss_driver dsicm_ops = {
.connect = dsicm_connect,
.disconnect = dsicm_disconnect,
@@ -1116,7 +1140,10 @@ static struct omap_dss_driver dsicm_ops = {
.update = dsicm_update,
.sync = dsicm_sync,
- .get_resolution = dsicm_get_resolution,
+ .get_timings = dsicm_get_timings,
+ .check_timings = dsicm_check_timings,
+
+ .get_resolution = omapdss_default_get_resolution,
.get_recommended_bpp = omapdss_default_get_recommended_bpp,
.enable_te = dsicm_enable_te,
@@ -1130,7 +1157,8 @@ static int dsicm_probe_of(struct platform_device *pdev)
struct device_node *node = pdev->dev.of_node;
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
struct omap_dss_device *in;
- int gpio;
+ struct display_timing timing;
+ int gpio, err;
gpio = of_get_named_gpio(node, "reset-gpios", 0);
if (!gpio_is_valid(gpio)) {
@@ -1147,6 +1175,17 @@ static int dsicm_probe_of(struct platform_device *pdev)
return gpio;
}
+ err = of_get_display_timing(node, "panel-timing", &timing);
+ if (!err) {
+ videomode_from_timing(&timing, &ddata->vm);
+ if (!ddata->vm.pixelclock)
+ ddata->vm.pixelclock =
+ ddata->vm.hactive * ddata->vm.vactive * 60;
+ } else {
+ dev_warn(&pdev->dev,
+ "failed to get video timing, using defaults\n");
+ }
+
in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&pdev->dev, "failed to find video source\n");
@@ -1181,14 +1220,14 @@ static int dsicm_probe(struct platform_device *pdev)
if (!pdev->dev.of_node)
return -ENODEV;
- r = dsicm_probe_of(pdev);
- if (r)
- return r;
-
ddata->vm.hactive = 864;
ddata->vm.vactive = 480;
ddata->vm.pixelclock = 864 * 480 * 60;
+ r = dsicm_probe_of(pdev);
+ if (r)
+ return r;
+
dssdev = &ddata->dssdev;
dssdev->dev = dev;
dssdev->driver = &dsicm_ops;
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Sebastian Reichel <sre@kernel.org> |
|---|---|
| Date | 2017-03-05 01:50 +0100 |
| Subject | [PATCHv2 08/10] drm: omapdrm: crtc: handle framedone directly |
| Message-ID | <thsx3-rY-9@gated-at.bofh.it> |
| In reply to | #1592656 |
From: Tony Lindgren <tony@atomide.com>
We can handle framedone interrupt directly simlar to commit
e0519af75d6e ("drm: omapdrm: Handle CRTC error IRQs directly").
By default we just print a warning on framedone and do nothing.
Any manually refreshed displays can register a callback.
Signed-off-by: Tony Lindgren <tony@atomide.com>
[Drop REVISIT comment for omap3, patch works on N950]
Signed-off-by: Sebastian Reichel <sre@kernel.org>
---
drivers/gpu/drm/omapdrm/omap_crtc.c | 25 +++++++++++++++++++++++++
drivers/gpu/drm/omapdrm/omap_drv.h | 1 +
drivers/gpu/drm/omapdrm/omap_irq.c | 7 ++++++-
3 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 432ad6023f27..4601533215d6 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -349,6 +349,31 @@ 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?\n");
+
+ 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);
+}
+
void omap_crtc_flush(struct drm_crtc *crtc,
int x, int y, int w, int h)
{
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 71b5c5e25ee4..9586551960e9 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -138,6 +138,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
struct drm_plane *plane, enum omap_channel channel, int id);
int omap_crtc_wait_pending(struct drm_crtc *crtc);
void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus);
+void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus);
void omap_crtc_vblank_irq(struct drm_crtc *crtc);
bool omap_crtc_is_manual_updated(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c
index 9adfa7c99695..fb39601721f6 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -215,6 +215,9 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
if (irqstatus & dispc_mgr_get_sync_lost_irq(channel))
omap_crtc_error_irq(crtc, irqstatus);
+
+ if (irqstatus & dispc_mgr_get_framedone_irq(channel))
+ omap_crtc_framedone_irq(crtc, irqstatus);
}
omap_irq_ocp_error_handler(irqstatus);
@@ -264,8 +267,10 @@ int omap_drm_irq_install(struct drm_device *dev)
priv->irq_mask |= omap_underflow_irqs[i];
}
- for (i = 0; i < num_mgrs; ++i)
+ for (i = 0; i < num_mgrs; ++i) {
priv->irq_mask |= dispc_mgr_get_sync_lost_irq(i);
+ priv->irq_mask |= dispc_mgr_get_framedone_irq(i);
+ }
dispc_runtime_get();
dispc_clear_irqstatus(0xffffffff);
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Sebastian Reichel <sre@kernel.org> |
|---|---|
| Date | 2017-03-05 01:50 +0100 |
| Subject | [PATCHv2 05/10] drm: omapdrm: crtc: detect manually updated displays |
| Message-ID | <thsx3-rY-7@gated-at.bofh.it> |
| In reply to | #1592656 |
Signed-off-by: Sebastian Reichel <sre@kernel.org>
[tony@atomide.com: rebased on event_lock changes]
---
drivers/gpu/drm/omapdrm/dss/omapdss.h | 1 +
drivers/gpu/drm/omapdrm/dss/output.c | 6 ++++++
drivers/gpu/drm/omapdrm/omap_connector.c | 7 +++++++
drivers/gpu/drm/omapdrm/omap_crtc.c | 29 +++++++++++++++++++++++++++--
drivers/gpu/drm/omapdrm/omap_drv.h | 2 ++
5 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 5b3b961127bd..5666ecbe4b80 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -918,5 +918,6 @@ int dss_mgr_register_framedone_handler(enum omap_channel channel,
void (*handler)(void *), void *data);
void dss_mgr_unregister_framedone_handler(enum omap_channel channel,
void (*handler)(void *), void *data);
+bool dss_lcd_mgr_config_get_stallmode(const struct dss_lcd_mgr_config *config);
#endif /* __OMAP_DRM_DSS_H */
diff --git a/drivers/gpu/drm/omapdrm/dss/output.c b/drivers/gpu/drm/omapdrm/dss/output.c
index a901af5a9bc3..08c730d1dada 100644
--- a/drivers/gpu/drm/omapdrm/dss/output.c
+++ b/drivers/gpu/drm/omapdrm/dss/output.c
@@ -214,6 +214,12 @@ void dss_mgr_set_lcd_config(enum omap_channel channel,
}
EXPORT_SYMBOL(dss_mgr_set_lcd_config);
+bool dss_lcd_mgr_config_get_stallmode(const struct dss_lcd_mgr_config *config)
+{
+ return config->stallmode;
+}
+EXPORT_SYMBOL(dss_lcd_mgr_config_get_stallmode);
+
int dss_mgr_enable(enum omap_channel channel)
{
return dss_mgr_ops->enable(channel);
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index 7b2a9f680dce..b09d8989b789 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -35,6 +35,13 @@ struct omap_connector {
bool 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);
+}
+
bool omap_connector_get_hdmi_mode(struct drm_connector *connector)
{
struct omap_connector *omap_connector = to_omap_connector(connector);
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 76a411fe957a..03351ca2ee41 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -35,6 +35,7 @@ struct omap_crtc {
enum omap_channel channel;
struct videomode vm;
+ bool manually_updated;
bool ignore_digit_sync_lost;
@@ -89,6 +90,12 @@ int omap_crtc_wait_pending(struct drm_crtc *crtc)
msecs_to_jiffies(250));
}
+bool omap_crtc_is_manual_updated(struct drm_crtc *crtc)
+{
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+ return omap_crtc->manually_updated;
+}
+
/* -----------------------------------------------------------------------------
* DSS Manager Functions
*/
@@ -237,6 +244,9 @@ static void omap_crtc_dss_set_lcd_config(enum omap_channel channel,
{
struct omap_crtc *omap_crtc = omap_crtcs[channel];
DBG("%s", omap_crtc->name);
+
+ omap_crtc->manually_updated = dss_lcd_mgr_config_get_stallmode(config);
+
dispc_mgr_set_lcd_config(omap_crtc->channel, config);
}
@@ -355,10 +365,23 @@ static void omap_crtc_destroy(struct drm_crtc *crtc)
static void omap_crtc_enable(struct drm_crtc *crtc)
{
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct drm_connector *connector;
int ret;
DBG("%s", omap_crtc->name);
+ /* manual updated display will not trigger vsync irq */
+ /* omap_crtc->manually_updated is not yet set */
+ drm_for_each_connector(connector, crtc->dev) {
+ if (connector->state->crtc != crtc)
+ continue;
+ if (!omap_connector_get_manually_updated(connector))
+ continue;
+ dev_dbg(dev->dev, "manually updated display detected!");
+ return;
+ }
+
spin_lock_irq(&crtc->dev->event_lock);
drm_crtc_vblank_on(crtc);
ret = drm_crtc_vblank_get(crtc);
@@ -440,8 +463,10 @@ 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->manually_updated) {
+ ret = drm_crtc_vblank_get(crtc);
+ WARN_ON(ret != 0);
+ }
spin_lock_irq(&crtc->dev->event_lock);
dispc_mgr_go(omap_crtc->channel);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 5b1061586401..5a0106239be2 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -139,6 +139,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);
+bool omap_crtc_is_manual_updated(struct drm_crtc *crtc);
struct drm_plane *omap_plane_init(struct drm_device *dev,
int id, enum drm_plane_type type,
@@ -155,6 +156,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);
void omap_connector_flush(struct drm_connector *connector,
int x, int y, int w, int h);
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Tony Lindgren <tony@atomide.com> |
|---|---|
| Date | 2017-03-05 06:50 +0100 |
| Subject | Re: [PATCHv2 05/10] drm: omapdrm: crtc: detect manually updated displays |
| Message-ID | <thxdo-3TP-9@gated-at.bofh.it> |
| In reply to | #1592658 |
* Sebastian Reichel <sre@kernel.org> [170304 16:45]: > Signed-off-by: Sebastian Reichel <sre@kernel.org> > [tony@atomide.com: rebased on event_lock changes] So for this feel free to add: Tested-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
[toc] | [prev] | [next] | [standalone]
| From | Sebastian Reichel <sre@kernel.org> |
|---|---|
| Date | 2017-03-05 01:50 +0100 |
| Subject | [PATCHv2 10/10] ARM: dts: n950: add display support |
| Message-ID | <thsx3-rY-15@gated-at.bofh.it> |
| In reply to | #1592656 |
Add basic panel support for the Nokia N950. It must be tweaked a
little bit later, since the panel was built into the device
upside-down. Also the first 5 and the last 5 pixels are covered
by plastic.
Signed-off-By: Sebastian Reichel <sre@kernel.org>
---
arch/arm/boot/dts/omap3-n950.dts | 89 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts
index 646601a3ebd8..1aa4251b39d7 100644
--- a/arch/arm/boot/dts/omap3-n950.dts
+++ b/arch/arm/boot/dts/omap3-n950.dts
@@ -51,6 +51,26 @@
};
};
+&omap3_pmx_core {
+ dsi_pins: pinmux_dsi_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE1) /* dsi_dx0 - data0+ */
+ OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE1) /* dsi_dy0 - data0- */
+ OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE1) /* dsi_dx1 - clk+ */
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE1) /* dsi_dy1 - clk- */
+ OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE1) /* dsi_dx2 - data1+ */
+ OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE1) /* dsi_dy2 - data1- */
+ >;
+ };
+
+ display_pins: pinmux_display_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20ca, PIN_INPUT | MUX_MODE4) /* gpio 62 - display te */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE4) /* gpio 87 - display reset */
+ >;
+ };
+};
+
&i2c2 {
smia_1: camera@10 {
compatible = "nokia,smia";
@@ -185,3 +205,72 @@
st,max-limit-y = <32>;
st,max-limit-z = <32>;
};
+
+&dss {
+ status = "ok";
+
+ vdda_video-supply = <&vdac>;
+};
+
+&dsi {
+ status = "ok";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&dsi_pins>;
+
+ vdd-supply = <&vpll2>;
+
+ port {
+ dsi_out_ep: endpoint {
+ remote-endpoint = <&lcd0_in>;
+ lanes = <2 3 0 1 4 5>;
+ };
+ };
+
+ lcd0: display {
+ compatible = "nokia,himalaya", "panel-dsi-cm";
+ label = "lcd0";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&display_pins>;
+
+ vpnl-supply = <&vmmc2>;
+ vddi-supply = <&vio>;
+
+ reset-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; /* 87 */
+ te-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>; /* 62 */
+
+ has-dsi-backlight;
+
+ /* panel is upside-down, 480x464 pixels */
+ /* top and bottom 5 lines are not visible */
+ /* physical dimensions: 48960µm x 88128µm */
+ panel-timing {
+ clock-frequency = <0>; /* Calculated by dsi */
+
+ hback-porch = <2>;
+ hactive = <480>;
+ hfront-porch = <0>;
+ hsync-len = <2>;
+
+ vback-porch = <1>;
+ vactive = <864>;
+ vfront-porch = <0>;
+ vsync-len = <1>;
+
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+
+ /* TODO: rotate panel by 180° */
+ /* TODO: add 5 pixel y-offset and limit vactive to 854 */
+ };
+
+ port {
+ lcd0_in: endpoint {
+ remote-endpoint = <&dsi_out_ep>;
+ };
+ };
+ };
+};
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Sebastian Reichel <sre@kernel.org> |
|---|---|
| Date | 2017-03-05 01:50 +0100 |
| Subject | [PATCHv2 09/10] drm: omapdrm: crtc: get manual mode displays working |
| Message-ID | <thsx4-rY-25@gated-at.bofh.it> |
| In reply to | #1592656 |
From: Tony Lindgren <tony@atomide.com>
With manual mode displays we need to flush the panel manually.
Let's add flushing so we get Tomi's fbtest, kmstest, kmstest --flip,
and X and wayland working.
Signed-off-by: Tony Lindgren <tony@atomide.com>
[On Nokia N950]
Tested-By: Sebastian Reichel <sre@kernel.org>
---
drivers/gpu/drm/omapdrm/omap_crtc.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 4601533215d6..e07b0a0be4bf 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -97,6 +97,11 @@ bool omap_crtc_is_manual_updated(struct drm_crtc *crtc)
return omap_crtc->manually_updated;
}
+static void omap_crtc_manual_needs_flush(struct drm_crtc *crtc)
+{
+ omap_crtc_flush(crtc, 0, 0, 0, 0);
+}
+
/* -----------------------------------------------------------------------------
* DSS Manager Functions
*/
@@ -139,7 +144,11 @@ 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 drm_crtc *crtc = &omap_crtc->base;
+
dispc_mgr_enable(channel, true);
+ omap_crtc_manual_needs_flush(crtc);
}
/* Called only from the encoder enable/disable and suspend/resume handlers. */
@@ -155,11 +164,12 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
if (WARN_ON(omap_crtc->enabled == enable))
return;
- if (omap_crtc_output[channel]->output_type == OMAP_DISPLAY_TYPE_HDMI) {
- dispc_mgr_enable(channel, enable);
- omap_crtc->enabled = enable;
+ dispc_mgr_enable(channel, enable);
+ omap_crtc->enabled = enable;
+ omap_crtc_manual_needs_flush(crtc);
+
+ if (omap_crtc_output[channel]->output_type == OMAP_DISPLAY_TYPE_HDMI)
return;
- }
if (omap_crtc->channel == OMAP_DSS_CHANNEL_DIGIT) {
/*
@@ -190,9 +200,6 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
wait = omap_irq_wait_init(dev, vsync_irq, 2);
}
- dispc_mgr_enable(channel, enable);
- omap_crtc->enabled = enable;
-
ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
if (ret) {
dev_err(dev->dev, "%s: timeout waiting for %s\n",
@@ -554,6 +561,7 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
ret = drm_crtc_vblank_get(crtc);
WARN_ON(ret != 0);
}
+ omap_crtc_flush(&omap_crtc->base, 0, 0, 0, 0);
spin_lock_irq(&crtc->dev->event_lock);
dispc_mgr_enable(omap_crtc->channel, true);
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Tony Lindgren <tony@atomide.com> |
|---|---|
| Date | 2017-03-05 06:50 +0100 |
| Subject | Re: [PATCHv2 09/10] drm: omapdrm: crtc: get manual mode displays working |
| Message-ID | <thxdo-3TP-7@gated-at.bofh.it> |
| In reply to | #1592660 |
* Sebastian Reichel <sre@kernel.org> [170304 16:45]:
> From: Tony Lindgren <tony@atomide.com>
>
> With manual mode displays we need to flush the panel manually.
>
> Let's add flushing so we get Tomi's fbtest, kmstest, kmstest --flip,
> and X and wayland working.
> --- a/drivers/gpu/drm/omapdrm/omap_crtc.c
> +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
> @@ -97,6 +97,11 @@ bool omap_crtc_is_manual_updated(struct drm_crtc *crtc)
> return omap_crtc->manually_updated;
> }
>
> +static void omap_crtc_manual_needs_flush(struct drm_crtc *crtc)
> +{
> + omap_crtc_flush(crtc, 0, 0, 0, 0);
> +}
...
> @@ -554,6 +561,7 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
> ret = drm_crtc_vblank_get(crtc);
> WARN_ON(ret != 0);
> }
> + omap_crtc_flush(&omap_crtc->base, 0, 0, 0, 0);
Just noticed that this should also just use omap_crtc_manual_needs_flush()
here if you care to update it.
Regards,
Tony
[toc] | [prev] | [next] | [standalone]
| From | Sebastian Reichel <sre@kernel.org> |
|---|---|
| Date | 2017-03-05 01:50 +0100 |
| Subject | [PATCHv2 04/10] drm: omapdrm: crtc: save framedone callback from dss |
| Message-ID | <thsx3-rY-19@gated-at.bofh.it> |
| In reply to | #1592656 |
Save the framedone callback supplied by dss for later
usage.
Signed-off-by: Sebastian Reichel <sre@kernel.org>
---
drivers/gpu/drm/omapdrm/omap_crtc.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index b68c70eb395f..76a411fe957a 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -42,6 +42,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;
};
/* -----------------------------------------------------------------------------
@@ -241,6 +244,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;
}
@@ -248,6 +262,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 = {
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Tony Lindgren <tony@atomide.com> |
|---|---|
| Date | 2017-03-05 06:50 +0100 |
| Subject | Re: [PATCHv2 04/10] drm: omapdrm: crtc: save framedone callback from dss |
| Message-ID | <thxdn-3TP-3@gated-at.bofh.it> |
| In reply to | #1592661 |
* Sebastian Reichel <sre@kernel.org> [170304 16:45]: > Save the framedone callback supplied by dss for later > usage. > > Signed-off-by: Sebastian Reichel <sre@kernel.org> Tested-by: Tony Lindgren <tony@atomide.com>
[toc] | [prev] | [next] | [standalone]
| From | Sebastian Reichel <sre@kernel.org> |
|---|---|
| Date | 2017-03-05 01:50 +0100 |
| Subject | [PATCHv2 02/10] drm: omapdrm: panel-dsi-cm: add regulator support |
| Message-ID | <thsx4-rY-21@gated-at.bofh.it> |
| In reply to | #1592656 |
The N950's display requires two regulators.
Signed-off-by: Sebastian Reichel <sre@kernel.org>
---
drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 55 +++++++++++++++++++++++--
1 file changed, 52 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index ad1058fafe92..8d13123708ae 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -23,6 +23,7 @@
#include <linux/workqueue.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
#include <video/mipi_display.h>
#include <video/of_display_timing.h>
@@ -60,6 +61,9 @@ struct panel_drv_data {
int reset_gpio;
int ext_te_gpio;
+ struct regulator *vpnl;
+ struct regulator *vddi;
+
bool use_dsi_backlight;
struct omap_dsi_pin_config pin_config;
@@ -590,25 +594,43 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
.lp_clk_max = 10000000,
};
+ if (ddata->vpnl) {
+ r = regulator_enable(ddata->vpnl);
+ if (r) {
+ dev_err(&ddata->pdev->dev,
+ "failed to enable VPNL: %d\n", r);
+ goto err0;
+ }
+ }
+
+ if (ddata->vddi) {
+ r = regulator_enable(ddata->vddi);
+ if (r) {
+ dev_err(&ddata->pdev->dev,
+ "failed to enable VDDI: %d\n", r);
+ goto err1;
+ }
+ }
+
if (ddata->pin_config.num_pins > 0) {
r = in->ops.dsi->configure_pins(in, &ddata->pin_config);
if (r) {
dev_err(&ddata->pdev->dev,
"failed to configure DSI pins\n");
- goto err0;
+ goto err2;
}
}
r = in->ops.dsi->set_config(in, &dsi_config);
if (r) {
dev_err(&ddata->pdev->dev, "failed to configure DSI\n");
- goto err0;
+ goto err2;
}
r = in->ops.dsi->enable(in);
if (r) {
dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
- goto err0;
+ goto err2;
}
dsicm_hw_reset(ddata);
@@ -666,6 +688,12 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
dsicm_hw_reset(ddata);
in->ops.dsi->disable(in, true, false);
+err2:
+ if (ddata->vddi)
+ regulator_disable(ddata->vddi);
+err1:
+ if (ddata->vpnl)
+ regulator_disable(ddata->vpnl);
err0:
return r;
}
@@ -689,6 +717,11 @@ static void dsicm_power_off(struct panel_drv_data *ddata)
in->ops.dsi->disable(in, true, false);
+ if (ddata->vddi)
+ regulator_disable(ddata->vddi);
+ if (ddata->vpnl)
+ regulator_disable(ddata->vpnl);
+
ddata->enabled = 0;
}
@@ -1192,6 +1225,22 @@ static int dsicm_probe_of(struct platform_device *pdev)
return PTR_ERR(in);
}
+ ddata->vpnl = devm_regulator_get_optional(&pdev->dev, "vpnl");
+ if (IS_ERR(ddata->vpnl)) {
+ err = PTR_ERR(ddata->vpnl);
+ if (err == -EPROBE_DEFER)
+ return err;
+ ddata->vpnl = NULL;
+ }
+
+ ddata->vddi = devm_regulator_get_optional(&pdev->dev, "vddi");
+ if (IS_ERR(ddata->vddi)) {
+ err = PTR_ERR(ddata->vddi);
+ if (err == -EPROBE_DEFER)
+ return err;
+ ddata->vddi = NULL;
+ }
+
ddata->in = in;
/* TODO: ulps, backlight */
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Tony Lindgren <tony@atomide.com> |
|---|---|
| Date | 2017-03-05 06:50 +0100 |
| Subject | Re: [PATCHv2 02/10] drm: omapdrm: panel-dsi-cm: add regulator support |
| Message-ID | <thxdn-3TP-1@gated-at.bofh.it> |
| In reply to | #1592662 |
* Sebastian Reichel <sre@kernel.org> [170304 16:45]: > The N950's display requires two regulators. Also needed for droid 4: Tested-by: Tony Lindgren <tony@atomide.com>
[toc] | [prev] | [next] | [standalone]
| From | Sebastian Reichel <sre@kernel.org> |
|---|---|
| Date | 2017-03-05 01:50 +0100 |
| Subject | [PATCHv2 06/10] drm: omapdrm: crtc: add support for manual updated displays |
| Message-ID | <thsx4-rY-29@gated-at.bofh.it> |
| In reply to | #1592656 |
Signed-off-by: Sebastian Reichel <sre@kernel.org>
[tony@atomide.com: rebased and fixed up to work with droid 4]
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
drivers/gpu/drm/omapdrm/omap_connector.c | 12 ------
drivers/gpu/drm/omapdrm/omap_crtc.c | 65 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/omapdrm/omap_drv.h | 2 +-
drivers/gpu/drm/omapdrm/omap_fb.c | 2 +-
4 files changed, 67 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index b09d8989b789..5ab672cac0b2 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -212,18 +212,6 @@ static const struct drm_connector_helper_funcs omap_connector_helper_funcs = {
.mode_valid = omap_connector_mode_valid,
};
-/* flush an area of the framebuffer (in case of manual update display that
- * is not automatically flushed)
- */
-void omap_connector_flush(struct drm_connector *connector,
- int x, int y, int w, int h)
-{
- struct omap_connector *omap_connector = to_omap_connector(connector);
-
- /* TODO: enable when supported in dss */
- VERB("%s: %d,%d, %dx%d", omap_connector->dssdev->name, x, y, w, h);
-}
-
/* initialize connector */
struct drm_connector *omap_connector_init(struct drm_device *dev,
int connector_type, struct omap_dss_device *dssdev,
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 03351ca2ee41..432ad6023f27 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -43,6 +43,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;
@@ -138,6 +139,7 @@ static void omap_crtc_dss_disconnect(enum omap_channel channel,
static void omap_crtc_dss_start_update(enum omap_channel channel)
{
+ dispc_mgr_enable(channel, true);
}
/* Called only from the encoder enable/disable and suspend/resume handlers. */
@@ -347,6 +349,60 @@ void omap_crtc_vblank_irq(struct drm_crtc *crtc)
DBG("%s: apply done", omap_crtc->name);
}
+void omap_crtc_flush(struct drm_crtc *crtc,
+ int x, int y, int w, int h)
+{
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+
+ if (!omap_crtc->manually_updated)
+ 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 drm_crtc *crtc = &omap_crtc->base;
+ struct omap_dss_device *dssdev = omap_crtc_output[omap_crtc->channel];
+ struct omap_dss_driver *dssdrv;
+ int ret;
+
+ if (!dssdev || !dssdev->dst) {
+ dev_err_once(omap_crtc->base.dev->dev, "missing dssdev!\n");
+ return;
+ }
+
+ dssdev = dssdev->dst;
+ dssdrv = dssdev->driver;
+
+ if (!dssdrv)
+ return;
+
+ if (!dssdrv || !dssdrv->update)
+ return;
+
+ /*
+ * REVISIT: Testing and setting omap_crtc->pending here will cause all
+ * kind of warnings at least on droid 4. Maybe we should be testing
+ * something else here instead of omap_crtc->pending?
+ */
+
+ if (dssdrv->sync)
+ dssdrv->sync(dssdev);
+
+ ret = dssdrv->update(dssdev, 0, 0,
+ dssdev->panel.vm.vactive, dssdev->panel.vm.hactive);
+ if (ret < 0) {
+ spin_lock_irq(&crtc->dev->event_lock);
+ omap_crtc->pending = false;
+ spin_unlock_irq(&crtc->dev->event_lock);
+ wake_up(&omap_crtc->pending_wait);
+ }
+}
+
/* -----------------------------------------------------------------------------
* CRTC Functions
*/
@@ -395,9 +451,15 @@ static void omap_crtc_enable(struct drm_crtc *crtc)
static void omap_crtc_disable(struct drm_crtc *crtc)
{
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
DBG("%s", omap_crtc->name);
+ 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);
}
@@ -469,6 +531,7 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
}
spin_lock_irq(&crtc->dev->event_lock);
+ dispc_mgr_enable(omap_crtc->channel, true);
dispc_mgr_go(omap_crtc->channel);
WARN_ON(omap_crtc->pending);
@@ -597,6 +660,8 @@ 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 5a0106239be2..ee8901dc0381 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -157,7 +157,7 @@ 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);
-void omap_connector_flush(struct drm_connector *connector,
+void omap_crtc_flush(struct drm_crtc *crtc,
int x, int y, int w, int h);
uint32_t omap_framebuffer_get_formats(uint32_t *pixel_formats,
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index b6ae28fe3257..5bf05916de03 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -356,7 +356,7 @@ void omap_framebuffer_flush(struct drm_framebuffer *fb,
int cw = w + (x - crtc->x) - cx;
int ch = h + (y - crtc->y) - cy;
- omap_connector_flush(connector, cx, cy, cw, ch);
+ omap_crtc_flush(crtc, cx, cy, cw, ch);
}
}
}
--
2.11.0
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web