[PATCH 0/6] OMAPDSS: suspend/resume improvements

STALE4709d

11 messages, 2 authors, 2013-11-26 · open the first message on its own page

[PATCH 0/6] OMAPDSS: suspend/resume improvements

From: Tomi Valkeinen <hidden>
Date: 2013-11-18 12:50:03

DISPC's suspend/resume works ok on mainline, but there was recently a bug with
TI's kernel containing support for newer SoCs. The bug was that not all DISPC
registers were restored correctly on resume.

While this bug is not in the mainline, I realized that the current
suspend/resume support in DISPC is rather silly, and can be done much more
efficiently.

This series improves the suspend/resume, making introducing similar bugs as
seen in TI kernel not possible, and cleans up the code quite a bit.

There's also a patch to use runtime PM's autosuspend with DSS devices, which
should reduce the on/off cycles when e.g. starting omapdss.

 Tomi

Tomi Valkeinen (6):
  OMAPDSS: APPLY: set infos to dirty on enable
  OMAPDSS: DISPC: Remove context restore
  OMAPDSS: DSS remove ctx stuff
  OMAPDSS: remove dss_get_ctx_loss_count
  OMAPDSS: add debug print for runtime suspend/resume
  OMAPDSS: use runtime PM's autosuspend

 arch/arm/mach-omap2/display.c   |   1 -
 drivers/video/omap2/dss/apply.c |  22 ++++
 drivers/video/omap2/dss/dispc.c | 262 ++--------------------------------------
 drivers/video/omap2/dss/dsi.c   |   9 +-
 drivers/video/omap2/dss/dss.c   | 103 ++++++----------
 drivers/video/omap2/dss/dss.h   |   4 +-
 drivers/video/omap2/dss/hdmi4.c |   9 +-
 drivers/video/omap2/dss/rfbi.c  |   9 +-
 drivers/video/omap2/dss/venc.c  |   9 +-
 include/video/omapdss.h         |   1 -
 10 files changed, 101 insertions(+), 328 deletions(-)

-- 
1.8.3.2

[PATCH 1/6] OMAPDSS: APPLY: set infos to dirty on enable

From: Tomi Valkeinen <hidden>
Date: 2013-11-18 12:50:04

Currently when DISPC is suspended, the driver stores all DISPC registers
to memory, so that they can be restored on resume. This is a bad way to
handle suspend/resume, as it's prone to failures and requires somewhat
large amount of extra space to store the registers.

A better approach is to program the DISPC from scratch when resuming.
This can be easily accomplished in apply layer by setting the manager
and overlay infos to dirty when the manager is to be enabled.

Signed-off-by: Tomi Valkeinen <redacted>
---
 drivers/video/omap2/dss/apply.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 60758db..6ab4cb6 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1072,6 +1072,7 @@ static void dss_setup_fifos(void)
 static int dss_mgr_enable_compat(struct omap_overlay_manager *mgr)
 {
 	struct mgr_priv_data *mp = get_mgr_priv(mgr);
+	struct omap_overlay *ovl;
 	unsigned long flags;
 	int r;
 
@@ -1091,6 +1092,27 @@ static int dss_mgr_enable_compat(struct omap_overlay_manager *mgr)
 		goto err;
 	}
 
+	/*
+	 * Mark the info & extra_info dirty for the manager and its enabled
+	 * overlays to force register writes. This ensures that the relevant
+	 * registers are set after DSS has been off and the registers have been
+	 * reset.
+	 */
+
+	mp->info_dirty = true;
+	mp->extra_info_dirty = true;
+
+	list_for_each_entry(ovl, &mgr->overlays, list) {
+		struct ovl_priv_data *op = get_ovl_priv(ovl);
+
+		if (!op->enabled)
+			continue;
+
+		op->info_dirty = true;
+		op->extra_info_dirty = true;
+		dispc_ovl_set_channel_out(ovl->id, mgr->id);
+	}
+
 	dss_setup_fifos();
 
 	dss_write_regs();
-- 
1.8.3.2

[PATCH 2/6] OMAPDSS: DISPC: Remove context restore

From: Tomi Valkeinen <hidden>
Date: 2013-11-18 12:50:05

Now that the apply layer writes the registers after DISPC has been
resumed, we can remove all the context restore code.

Only _omap_dispc_initial_config call is needed on resume, which
configures the non-user-configurable registers.

Signed-off-by: Tomi Valkeinen <redacted>
---
 drivers/video/omap2/dss/dispc.c | 255 +---------------------------------------
 1 file changed, 1 insertion(+), 254 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 91c687f..54716ad 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -43,9 +43,6 @@
 #include "dss_features.h"
 #include "dispc.h"
 
-/* DISPC */
-#define DISPC_SZ_REGS			SZ_4K
-
 enum omap_burst_size {
 	BURST_SIZE_X2 = 0,
 	BURST_SIZE_X4 = 1,
@@ -98,8 +95,6 @@ static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
 
-	int		ctx_loss_cnt;
-
 	int irq;
 
 	unsigned long core_clk_rate;
@@ -109,9 +104,6 @@ static struct {
 	/* maps which plane is using a fifo. fifo-id -> plane-id */
 	int fifo_assignment[DISPC_MAX_NR_FIFOS];
 
-	bool		ctx_valid;
-	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
-
 	const struct dispc_features *feat;
 } dispc;
 
@@ -248,249 +240,6 @@ static void mgr_fld_write(enum omap_channel channel,
 	REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
 }
 
-#define SR(reg) \
-	dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg)
-#define RR(reg) \
-	dispc_write_reg(DISPC_##reg, dispc.ctx[DISPC_##reg / sizeof(u32)])
-
-static void dispc_save_context(void)
-{
-	int i, j;
-
-	DSSDBG("dispc_save_context\n");
-
-	SR(IRQENABLE);
-	SR(CONTROL);
-	SR(CONFIG);
-	SR(LINE_NUMBER);
-	if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
-			dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
-		SR(GLOBAL_ALPHA);
-	if (dss_has_feature(FEAT_MGR_LCD2)) {
-		SR(CONTROL2);
-		SR(CONFIG2);
-	}
-	if (dss_has_feature(FEAT_MGR_LCD3)) {
-		SR(CONTROL3);
-		SR(CONFIG3);
-	}
-
-	for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
-		SR(DEFAULT_COLOR(i));
-		SR(TRANS_COLOR(i));
-		SR(SIZE_MGR(i));
-		if (i = OMAP_DSS_CHANNEL_DIGIT)
-			continue;
-		SR(TIMING_H(i));
-		SR(TIMING_V(i));
-		SR(POL_FREQ(i));
-		SR(DIVISORo(i));
-
-		SR(DATA_CYCLE1(i));
-		SR(DATA_CYCLE2(i));
-		SR(DATA_CYCLE3(i));
-
-		if (dss_has_feature(FEAT_CPR)) {
-			SR(CPR_COEF_R(i));
-			SR(CPR_COEF_G(i));
-			SR(CPR_COEF_B(i));
-		}
-	}
-
-	for (i = 0; i < dss_feat_get_num_ovls(); i++) {
-		SR(OVL_BA0(i));
-		SR(OVL_BA1(i));
-		SR(OVL_POSITION(i));
-		SR(OVL_SIZE(i));
-		SR(OVL_ATTRIBUTES(i));
-		SR(OVL_FIFO_THRESHOLD(i));
-		SR(OVL_ROW_INC(i));
-		SR(OVL_PIXEL_INC(i));
-		if (dss_has_feature(FEAT_PRELOAD))
-			SR(OVL_PRELOAD(i));
-		if (i = OMAP_DSS_GFX) {
-			SR(OVL_WINDOW_SKIP(i));
-			SR(OVL_TABLE_BA(i));
-			continue;
-		}
-		SR(OVL_FIR(i));
-		SR(OVL_PICTURE_SIZE(i));
-		SR(OVL_ACCU0(i));
-		SR(OVL_ACCU1(i));
-
-		for (j = 0; j < 8; j++)
-			SR(OVL_FIR_COEF_H(i, j));
-
-		for (j = 0; j < 8; j++)
-			SR(OVL_FIR_COEF_HV(i, j));
-
-		for (j = 0; j < 5; j++)
-			SR(OVL_CONV_COEF(i, j));
-
-		if (dss_has_feature(FEAT_FIR_COEF_V)) {
-			for (j = 0; j < 8; j++)
-				SR(OVL_FIR_COEF_V(i, j));
-		}
-
-		if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
-			SR(OVL_BA0_UV(i));
-			SR(OVL_BA1_UV(i));
-			SR(OVL_FIR2(i));
-			SR(OVL_ACCU2_0(i));
-			SR(OVL_ACCU2_1(i));
-
-			for (j = 0; j < 8; j++)
-				SR(OVL_FIR_COEF_H2(i, j));
-
-			for (j = 0; j < 8; j++)
-				SR(OVL_FIR_COEF_HV2(i, j));
-
-			for (j = 0; j < 8; j++)
-				SR(OVL_FIR_COEF_V2(i, j));
-		}
-		if (dss_has_feature(FEAT_ATTR2))
-			SR(OVL_ATTRIBUTES2(i));
-	}
-
-	if (dss_has_feature(FEAT_CORE_CLK_DIV))
-		SR(DIVISOR);
-
-	dispc.ctx_loss_cnt = dss_get_ctx_loss_count();
-	dispc.ctx_valid = true;
-
-	DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt);
-}
-
-static void dispc_restore_context(void)
-{
-	int i, j, ctx;
-
-	DSSDBG("dispc_restore_context\n");
-
-	if (!dispc.ctx_valid)
-		return;
-
-	ctx = dss_get_ctx_loss_count();
-
-	if (ctx >= 0 && ctx = dispc.ctx_loss_cnt)
-		return;
-
-	DSSDBG("ctx_loss_count: saved %d, current %d\n",
-			dispc.ctx_loss_cnt, ctx);
-
-	/*RR(IRQENABLE);*/
-	/*RR(CONTROL);*/
-	RR(CONFIG);
-	RR(LINE_NUMBER);
-	if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
-			dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
-		RR(GLOBAL_ALPHA);
-	if (dss_has_feature(FEAT_MGR_LCD2))
-		RR(CONFIG2);
-	if (dss_has_feature(FEAT_MGR_LCD3))
-		RR(CONFIG3);
-
-	for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
-		RR(DEFAULT_COLOR(i));
-		RR(TRANS_COLOR(i));
-		RR(SIZE_MGR(i));
-		if (i = OMAP_DSS_CHANNEL_DIGIT)
-			continue;
-		RR(TIMING_H(i));
-		RR(TIMING_V(i));
-		RR(POL_FREQ(i));
-		RR(DIVISORo(i));
-
-		RR(DATA_CYCLE1(i));
-		RR(DATA_CYCLE2(i));
-		RR(DATA_CYCLE3(i));
-
-		if (dss_has_feature(FEAT_CPR)) {
-			RR(CPR_COEF_R(i));
-			RR(CPR_COEF_G(i));
-			RR(CPR_COEF_B(i));
-		}
-	}
-
-	for (i = 0; i < dss_feat_get_num_ovls(); i++) {
-		RR(OVL_BA0(i));
-		RR(OVL_BA1(i));
-		RR(OVL_POSITION(i));
-		RR(OVL_SIZE(i));
-		RR(OVL_ATTRIBUTES(i));
-		RR(OVL_FIFO_THRESHOLD(i));
-		RR(OVL_ROW_INC(i));
-		RR(OVL_PIXEL_INC(i));
-		if (dss_has_feature(FEAT_PRELOAD))
-			RR(OVL_PRELOAD(i));
-		if (i = OMAP_DSS_GFX) {
-			RR(OVL_WINDOW_SKIP(i));
-			RR(OVL_TABLE_BA(i));
-			continue;
-		}
-		RR(OVL_FIR(i));
-		RR(OVL_PICTURE_SIZE(i));
-		RR(OVL_ACCU0(i));
-		RR(OVL_ACCU1(i));
-
-		for (j = 0; j < 8; j++)
-			RR(OVL_FIR_COEF_H(i, j));
-
-		for (j = 0; j < 8; j++)
-			RR(OVL_FIR_COEF_HV(i, j));
-
-		for (j = 0; j < 5; j++)
-			RR(OVL_CONV_COEF(i, j));
-
-		if (dss_has_feature(FEAT_FIR_COEF_V)) {
-			for (j = 0; j < 8; j++)
-				RR(OVL_FIR_COEF_V(i, j));
-		}
-
-		if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
-			RR(OVL_BA0_UV(i));
-			RR(OVL_BA1_UV(i));
-			RR(OVL_FIR2(i));
-			RR(OVL_ACCU2_0(i));
-			RR(OVL_ACCU2_1(i));
-
-			for (j = 0; j < 8; j++)
-				RR(OVL_FIR_COEF_H2(i, j));
-
-			for (j = 0; j < 8; j++)
-				RR(OVL_FIR_COEF_HV2(i, j));
-
-			for (j = 0; j < 8; j++)
-				RR(OVL_FIR_COEF_V2(i, j));
-		}
-		if (dss_has_feature(FEAT_ATTR2))
-			RR(OVL_ATTRIBUTES2(i));
-	}
-
-	if (dss_has_feature(FEAT_CORE_CLK_DIV))
-		RR(DIVISOR);
-
-	/* enable last, because LCD & DIGIT enable are here */
-	RR(CONTROL);
-	if (dss_has_feature(FEAT_MGR_LCD2))
-		RR(CONTROL2);
-	if (dss_has_feature(FEAT_MGR_LCD3))
-		RR(CONTROL3);
-	/* clear spurious SYNC_LOST_DIGIT interrupts */
-	dispc_clear_irqstatus(DISPC_IRQ_SYNC_LOST_DIGIT);
-
-	/*
-	 * enable last so IRQs won't trigger before
-	 * the context is fully restored
-	 */
-	RR(IRQENABLE);
-
-	DSSDBG("context restored\n");
-}
-
-#undef SR
-#undef RR
-
 int dispc_runtime_get(void)
 {
 	int r;
@@ -3726,14 +3475,12 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)
 
 static int dispc_runtime_suspend(struct device *dev)
 {
-	dispc_save_context();
-
 	return 0;
 }
 
 static int dispc_runtime_resume(struct device *dev)
 {
-	dispc_restore_context();
+	_omap_dispc_initial_config();
 
 	return 0;
 }
-- 
1.8.3.2

[PATCH 3/6] OMAPDSS: DSS remove ctx stuff

From: Tomi Valkeinen <hidden>
Date: 2013-11-18 12:50:06

The DSS core driver's suspend/resume can be cleaned up by storing the
required registers to a 'dss_context' struct, instead of having a 512
byte block of memory where the registers are directly stored.

Signed-off-by: Tomi Valkeinen <redacted>
---
 drivers/video/omap2/dss/dss.c | 77 ++++++++++++++++---------------------------
 1 file changed, 28 insertions(+), 49 deletions(-)
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index bd01608..a5f674f 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -39,8 +39,6 @@
 #include "dss.h"
 #include "dss_features.h"
 
-#define DSS_SZ_REGS			SZ_512
-
 struct dss_reg {
 	u16 idx;
 };
@@ -71,6 +69,13 @@ struct dss_features {
 	int (*dpi_select_source)(enum omap_channel channel);
 };
 
+struct dss_context {
+	bool valid;
+	u32 control;
+	u32 sdi_control;
+	u32 pll_control;
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -88,8 +93,7 @@ static struct {
 	enum omap_dss_clk_source dispc_clk_source;
 	enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
 
-	bool		ctx_valid;
-	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+	struct dss_context ctx;
 
 	const struct dss_features *feat;
 } dss;
@@ -112,49 +116,6 @@ static inline u32 dss_read_reg(const struct dss_reg idx)
 	return __raw_readl(dss.base + idx.idx);
 }
 
-#define SR(reg) \
-	dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg)
-#define RR(reg) \
-	dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])
-
-static void dss_save_context(void)
-{
-	DSSDBG("dss_save_context\n");
-
-	SR(CONTROL);
-
-	if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
-			OMAP_DISPLAY_TYPE_SDI) {
-		SR(SDI_CONTROL);
-		SR(PLL_CONTROL);
-	}
-
-	dss.ctx_valid = true;
-
-	DSSDBG("context saved\n");
-}
-
-static void dss_restore_context(void)
-{
-	DSSDBG("dss_restore_context\n");
-
-	if (!dss.ctx_valid)
-		return;
-
-	RR(CONTROL);
-
-	if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
-			OMAP_DISPLAY_TYPE_SDI) {
-		RR(SDI_CONTROL);
-		RR(PLL_CONTROL);
-	}
-
-	DSSDBG("context restored\n");
-}
-
-#undef SR
-#undef RR
-
 int dss_get_ctx_loss_count(void)
 {
 	struct platform_device *core_pdev = dss_get_core_pdev();
@@ -927,7 +888,16 @@ static int __exit omap_dsshw_remove(struct platform_device *pdev)
 
 static int dss_runtime_suspend(struct device *dev)
 {
-	dss_save_context();
+	dss.ctx.control = dss_read_reg(DSS_CONTROL);
+
+	if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
+			OMAP_DISPLAY_TYPE_SDI) {
+		dss.ctx.sdi_control = dss_read_reg(DSS_SDI_CONTROL);
+		dss.ctx.pll_control = dss_read_reg(DSS_PLL_CONTROL);
+	}
+
+	dss.ctx.valid = true;
+
 	dss_set_min_bus_tput(dev, 0);
 	return 0;
 }
@@ -946,7 +916,16 @@ static int dss_runtime_resume(struct device *dev)
 	if (r)
 		return r;
 
-	dss_restore_context();
+	if (dss.ctx.valid) {
+		dss_write_reg(DSS_CONTROL, dss.ctx.control);
+
+		if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
+				OMAP_DISPLAY_TYPE_SDI) {
+			dss_write_reg(DSS_SDI_CONTROL, dss.ctx.sdi_control);
+			dss_write_reg(DSS_PLL_CONTROL, dss.ctx.pll_control);
+		}
+	}
+
 	return 0;
 }
 
-- 
1.8.3.2

[PATCH 4/6] OMAPDSS: remove dss_get_ctx_loss_count

From: Tomi Valkeinen <hidden>
Date: 2013-11-18 12:50:07

OMAPDSS driver no longer needs dss_get_ctx_loss_count, so it can be
removed.

Signed-off-by: Tomi Valkeinen <redacted>
---
 arch/arm/mach-omap2/display.c |  1 -
 drivers/video/omap2/dss/dss.c | 16 ----------------
 drivers/video/omap2/dss/dss.h |  2 --
 include/video/omapdss.h       |  1 -
 4 files changed, 20 deletions(-)
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 03a0516..e6d219c 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -341,7 +341,6 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
 	board_data->version = ver;
 	board_data->dsi_enable_pads = omap_dsi_enable_pads;
 	board_data->dsi_disable_pads = omap_dsi_disable_pads;
-	board_data->get_context_loss_count = omap_pm_get_dev_context_loss_count;
 	board_data->set_min_bus_tput = omap_dss_set_min_bus_tput;
 
 	omap_display_device.dev.platform_data = board_data;
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index a5f674f..0b78c89 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -116,22 +116,6 @@ static inline u32 dss_read_reg(const struct dss_reg idx)
 	return __raw_readl(dss.base + idx.idx);
 }
 
-int dss_get_ctx_loss_count(void)
-{
-	struct platform_device *core_pdev = dss_get_core_pdev();
-	struct omap_dss_board_info *board_data = core_pdev->dev.platform_data;
-	int cnt;
-
-	if (!board_data->get_context_loss_count)
-		return -ENOENT;
-
-	cnt = board_data->get_context_loss_count(&dss.pdev->dev);
-
-	WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt);
-
-	return cnt;
-}
-
 void dss_sdi_init(int datapairs)
 {
 	u32 l;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index f538e86..af83c4d 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -233,8 +233,6 @@ void dss_dump_clocks(struct seq_file *s);
 void dss_debug_dump_clocks(struct seq_file *s);
 #endif
 
-int dss_get_ctx_loss_count(void);
-
 void dss_sdi_init(int datapairs);
 int dss_sdi_enable(void);
 void dss_sdi_disable(void);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 3d7c51a..1eb9aa6 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -323,7 +323,6 @@ enum omapdss_version {
 
 /* Board specific data */
 struct omap_dss_board_info {
-	int (*get_context_loss_count)(struct device *dev);
 	int num_devices;
 	struct omap_dss_device **devices;
 	struct omap_dss_device *default_device;
-- 
1.8.3.2

[PATCH 5/6] OMAPDSS: add debug print for runtime suspend/resume

From: Tomi Valkeinen <hidden>
Date: 2013-11-18 12:50:08

Add consistent debug prints on all suspend & resume callbacks in omapdss
to make it simpler to debug runtime PM.

Signed-off-by: Tomi Valkeinen <redacted>
---
 drivers/video/omap2/dss/dispc.c | 4 ++++
 drivers/video/omap2/dss/dsi.c   | 4 ++++
 drivers/video/omap2/dss/dss.c   | 5 +++++
 drivers/video/omap2/dss/hdmi4.c | 4 ++++
 drivers/video/omap2/dss/rfbi.c  | 4 ++++
 drivers/video/omap2/dss/venc.c  | 4 ++++
 6 files changed, 25 insertions(+)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 54716ad..58f3626 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3475,11 +3475,15 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)
 
 static int dispc_runtime_suspend(struct device *dev)
 {
+	DSSDBG("suspend\n");
+
 	return 0;
 }
 
 static int dispc_runtime_resume(struct device *dev)
 {
+	DSSDBG("resume\n");
+
 	_omap_dispc_initial_config();
 
 	return 0;
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 6056b27..6b30a58 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -5477,6 +5477,8 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
 
 static int dsi_runtime_suspend(struct device *dev)
 {
+	DSSDBG("suspend\n");
+
 	dispc_runtime_put();
 
 	return 0;
@@ -5486,6 +5488,8 @@ static int dsi_runtime_resume(struct device *dev)
 {
 	int r;
 
+	DSSDBG("resume\n");
+
 	r = dispc_runtime_get();
 	if (r)
 		return r;
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 0b78c89..fa7bc00 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -872,6 +872,8 @@ static int __exit omap_dsshw_remove(struct platform_device *pdev)
 
 static int dss_runtime_suspend(struct device *dev)
 {
+	DSSDBG("suspend\n");
+
 	dss.ctx.control = dss_read_reg(DSS_CONTROL);
 
 	if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
@@ -889,6 +891,9 @@ static int dss_runtime_suspend(struct device *dev)
 static int dss_runtime_resume(struct device *dev)
 {
 	int r;
+
+	DSSDBG("resume\n");
+
 	/*
 	 * Set an arbitrarily high tput request to ensure OPP100.
 	 * What we should really do is to make a request to stay in OPP100,
diff --git a/drivers/video/omap2/dss/hdmi4.c b/drivers/video/omap2/dss/hdmi4.c
index e140096..f1a45fe 100644
--- a/drivers/video/omap2/dss/hdmi4.c
+++ b/drivers/video/omap2/dss/hdmi4.c
@@ -650,6 +650,8 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
 
 static int hdmi_runtime_suspend(struct device *dev)
 {
+	DSSDBG("suspend\n");
+
 	clk_disable_unprepare(hdmi.sys_clk);
 
 	dispc_runtime_put();
@@ -661,6 +663,8 @@ static int hdmi_runtime_resume(struct device *dev)
 {
 	int r;
 
+	DSSDBG("resume\n");
+
 	r = dispc_runtime_get();
 	if (r < 0)
 		return r;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index c8a81a2..74d3ed1 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -1016,6 +1016,8 @@ static int __exit omap_rfbihw_remove(struct platform_device *pdev)
 
 static int rfbi_runtime_suspend(struct device *dev)
 {
+	DSSDBG("suspend\n");
+
 	dispc_runtime_put();
 
 	return 0;
@@ -1025,6 +1027,8 @@ static int rfbi_runtime_resume(struct device *dev)
 {
 	int r;
 
+	DSSDBG("resume\n");
+
 	r = dispc_runtime_get();
 	if (r < 0)
 		return r;
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 5f88ac4..e173961 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -867,6 +867,8 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
 
 static int venc_runtime_suspend(struct device *dev)
 {
+	DSSDBG("suspend\n");
+
 	if (venc.tv_dac_clk)
 		clk_disable_unprepare(venc.tv_dac_clk);
 
@@ -879,6 +881,8 @@ static int venc_runtime_resume(struct device *dev)
 {
 	int r;
 
+	DSSDBG("resume\n");
+
 	r = dispc_runtime_get();
 	if (r < 0)
 		return r;
-- 
1.8.3.2

[PATCH 6/6] OMAPDSS: use runtime PM's autosuspend

From: Tomi Valkeinen <hidden>
Date: 2013-11-18 12:50:09

Use runtime PM's autosuspend support with delay of 100ms.

This will prevent the driver from turning the DSS modules off and on
multiple times e.g. when loading the module.

Signed-off-by: Tomi Valkeinen <redacted>
---
 drivers/video/omap2/dss/dispc.c | 5 ++++-
 drivers/video/omap2/dss/dsi.c   | 5 ++++-
 drivers/video/omap2/dss/dss.c   | 5 ++++-
 drivers/video/omap2/dss/dss.h   | 2 ++
 drivers/video/omap2/dss/hdmi4.c | 5 ++++-
 drivers/video/omap2/dss/rfbi.c  | 5 ++++-
 drivers/video/omap2/dss/venc.c  | 5 ++++-
 7 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 58f3626..0643eb0 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -258,7 +258,8 @@ void dispc_runtime_put(void)
 
 	DSSDBG("dispc_runtime_put\n");
 
-	r = pm_runtime_put_sync(&dispc.pdev->dev);
+	pm_runtime_mark_last_busy(&dispc.pdev->dev);
+	r = pm_runtime_put_autosuspend(&dispc.pdev->dev);
 	WARN_ON(r < 0 && r != -ENOSYS);
 }
 EXPORT_SYMBOL(dispc_runtime_put);
@@ -3440,6 +3441,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 	}
 
 	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, DSS_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);
 
 	r = dispc_runtime_get();
 	if (r)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 6b30a58..19e4cad 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1110,7 +1110,8 @@ void dsi_runtime_put(struct platform_device *dsidev)
 
 	DSSDBG("dsi_runtime_put\n");
 
-	r = pm_runtime_put_sync(&dsi->pdev->dev);
+	pm_runtime_mark_last_busy(&dsi->pdev->dev);
+	r = pm_runtime_put_autosuspend(&dsi->pdev->dev);
 	WARN_ON(r < 0 && r != -ENOSYS);
 }
 
@@ -5416,6 +5417,8 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
 		return r;
 
 	pm_runtime_enable(&dsidev->dev);
+	pm_runtime_set_autosuspend_delay(&dsidev->dev, DSS_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&dsidev->dev);
 
 	r = dsi_runtime_get(dsidev);
 	if (r)
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index fa7bc00..d3b0122 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -689,7 +689,8 @@ static void dss_runtime_put(void)
 
 	DSSDBG("dss_runtime_put\n");
 
-	r = pm_runtime_put_sync(&dss.pdev->dev);
+	pm_runtime_mark_last_busy(&dss.pdev->dev);
+	r = pm_runtime_put_autosuspend(&dss.pdev->dev);
 	WARN_ON(r < 0 && r != -ENOSYS && r != -EBUSY);
 }
 
@@ -821,6 +822,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 		goto err_setup_clocks;
 
 	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, DSS_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);
 
 	r = dss_runtime_get();
 	if (r)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index af83c4d..96505f0 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -73,6 +73,8 @@
 #define FLD_MOD(orig, val, start, end) \
 	(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
 
+#define DSS_AUTOSUSPEND_DELAY 100	/* in ms */
+
 enum dss_io_pad_mode {
 	DSS_IO_PAD_MODE_RESET,
 	DSS_IO_PAD_MODE_RFBI,
diff --git a/drivers/video/omap2/dss/hdmi4.c b/drivers/video/omap2/dss/hdmi4.c
index f1a45fe..f255641 100644
--- a/drivers/video/omap2/dss/hdmi4.c
+++ b/drivers/video/omap2/dss/hdmi4.c
@@ -77,7 +77,8 @@ static void hdmi_runtime_put(void)
 
 	DSSDBG("hdmi_runtime_put\n");
 
-	r = pm_runtime_put_sync(&hdmi.pdev->dev);
+	pm_runtime_mark_last_busy(&hdmi.pdev->dev);
+	r = pm_runtime_put_autosuspend(&hdmi.pdev->dev);
 	WARN_ON(r < 0 && r != -ENOSYS);
 }
 
@@ -631,6 +632,8 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
 	}
 
 	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, DSS_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);
 
 	hdmi_init_output(pdev);
 
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 74d3ed1..20dcbfb 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -147,7 +147,8 @@ static void rfbi_runtime_put(void)
 
 	DSSDBG("rfbi_runtime_put\n");
 
-	r = pm_runtime_put_sync(&rfbi.pdev->dev);
+	pm_runtime_mark_last_busy(&rfbi.pdev->dev);
+	r = pm_runtime_put_autosuspend(&rfbi.pdev->dev);
 	WARN_ON(r < 0 && r != -ENOSYS);
 }
 
@@ -981,6 +982,8 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
 	clk_put(clk);
 
 	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, DSS_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);
 
 	r = rfbi_runtime_get();
 	if (r)
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index e173961..bbd35bb 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -410,7 +410,8 @@ static void venc_runtime_put(void)
 
 	DSSDBG("venc_runtime_put\n");
 
-	r = pm_runtime_put_sync(&venc.pdev->dev);
+	pm_runtime_mark_last_busy(&venc.pdev->dev);
+	r = pm_runtime_put_autosuspend(&venc.pdev->dev);
 	WARN_ON(r < 0 && r != -ENOSYS);
 }
 
@@ -835,6 +836,8 @@ static int omap_venchw_probe(struct platform_device *pdev)
 		return r;
 
 	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, DSS_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);
 
 	r = venc_runtime_get();
 	if (r)
-- 
1.8.3.2

Re: [PATCH 1/6] OMAPDSS: APPLY: set infos to dirty on enable

From: Archit Taneja <hidden>
Date: 2013-11-25 01:18:50

On Monday 18 November 2013 06:20 PM, Tomi Valkeinen wrote:
Currently when DISPC is suspended, the driver stores all DISPC registers
to memory, so that they can be restored on resume. This is a bad way to
handle suspend/resume, as it's prone to failures and requires somewhat
large amount of extra space to store the registers.

A better approach is to program the DISPC from scratch when resuming.
This can be easily accomplished in apply layer by setting the manager
and overlay infos to dirty when the manager is to be enabled.
I guess this won't work if we wanted to support DSI command mode 
displays. I.e, only shut DSS off and keep the panel up. In that case, we 
would need to mark the flags dirty in dss_mgr_start_update_compat().

We don't support the above use case anyway, but just pointing out :)

Archit
quoted hunk
Signed-off-by: Tomi Valkeinen <redacted>
---
  drivers/video/omap2/dss/apply.c | 22 ++++++++++++++++++++++
  1 file changed, 22 insertions(+)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 60758db..6ab4cb6 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1072,6 +1072,7 @@ static void dss_setup_fifos(void)
  static int dss_mgr_enable_compat(struct omap_overlay_manager *mgr)
  {
  	struct mgr_priv_data *mp = get_mgr_priv(mgr);
+	struct omap_overlay *ovl;
  	unsigned long flags;
  	int r;
@@ -1091,6 +1092,27 @@ static int dss_mgr_enable_compat(struct omap_overlay_manager *mgr)
  		goto err;
  	}

+	/*
+	 * Mark the info & extra_info dirty for the manager and its enabled
+	 * overlays to force register writes. This ensures that the relevant
+	 * registers are set after DSS has been off and the registers have been
+	 * reset.
+	 */
+
+	mp->info_dirty = true;
+	mp->extra_info_dirty = true;
+
+	list_for_each_entry(ovl, &mgr->overlays, list) {
+		struct ovl_priv_data *op = get_ovl_priv(ovl);
+
+		if (!op->enabled)
+			continue;
+
+		op->info_dirty = true;
+		op->extra_info_dirty = true;
+		dispc_ovl_set_channel_out(ovl->id, mgr->id);
+	}
+
  	dss_setup_fifos();

  	dss_write_regs();

Re: [PATCH 6/6] OMAPDSS: use runtime PM's autosuspend

From: Archit Taneja <hidden>
Date: 2013-11-25 01:41:24

On Monday 18 November 2013 06:20 PM, Tomi Valkeinen wrote:
Use runtime PM's autosuspend support with delay of 100ms.

This will prevent the driver from turning the DSS modules off and on
multiple times e.g. when loading the module.
Could you explain this a bit more?

Are you saying that when we insert the omapdss module, we have a lot of 
runtime_get/put pairs in probe, which leads to us excessive writing of 
DISPC the registers during resume, and the autosuspend feature would 
delay the effect of runtime_put() for a while?

Also, do we need to do this for all the platform devices? Could we use 
autosuspend only for the parent platform device, and the children 
platform devices don't use it? Or am I understanding things wrongly here?

Archit
quoted hunk
Signed-off-by: Tomi Valkeinen <redacted>
---
  drivers/video/omap2/dss/dispc.c | 5 ++++-
  drivers/video/omap2/dss/dsi.c   | 5 ++++-
  drivers/video/omap2/dss/dss.c   | 5 ++++-
  drivers/video/omap2/dss/dss.h   | 2 ++
  drivers/video/omap2/dss/hdmi4.c | 5 ++++-
  drivers/video/omap2/dss/rfbi.c  | 5 ++++-
  drivers/video/omap2/dss/venc.c  | 5 ++++-
  7 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 58f3626..0643eb0 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -258,7 +258,8 @@ void dispc_runtime_put(void)

  	DSSDBG("dispc_runtime_put\n");

-	r = pm_runtime_put_sync(&dispc.pdev->dev);
+	pm_runtime_mark_last_busy(&dispc.pdev->dev);
+	r = pm_runtime_put_autosuspend(&dispc.pdev->dev);
  	WARN_ON(r < 0 && r != -ENOSYS);
  }
  EXPORT_SYMBOL(dispc_runtime_put);
@@ -3440,6 +3441,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
  	}

  	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, DSS_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);

  	r = dispc_runtime_get();
  	if (r)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 6b30a58..19e4cad 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1110,7 +1110,8 @@ void dsi_runtime_put(struct platform_device *dsidev)

  	DSSDBG("dsi_runtime_put\n");

-	r = pm_runtime_put_sync(&dsi->pdev->dev);
+	pm_runtime_mark_last_busy(&dsi->pdev->dev);
+	r = pm_runtime_put_autosuspend(&dsi->pdev->dev);
  	WARN_ON(r < 0 && r != -ENOSYS);
  }
@@ -5416,6 +5417,8 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
  		return r;

  	pm_runtime_enable(&dsidev->dev);
+	pm_runtime_set_autosuspend_delay(&dsidev->dev, DSS_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&dsidev->dev);

  	r = dsi_runtime_get(dsidev);
  	if (r)
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index fa7bc00..d3b0122 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -689,7 +689,8 @@ static void dss_runtime_put(void)

  	DSSDBG("dss_runtime_put\n");

-	r = pm_runtime_put_sync(&dss.pdev->dev);
+	pm_runtime_mark_last_busy(&dss.pdev->dev);
+	r = pm_runtime_put_autosuspend(&dss.pdev->dev);
  	WARN_ON(r < 0 && r != -ENOSYS && r != -EBUSY);
  }
@@ -821,6 +822,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
  		goto err_setup_clocks;

  	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, DSS_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);

  	r = dss_runtime_get();
  	if (r)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index af83c4d..96505f0 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -73,6 +73,8 @@
  #define FLD_MOD(orig, val, start, end) \
  	(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))

+#define DSS_AUTOSUSPEND_DELAY 100	/* in ms */
+
  enum dss_io_pad_mode {
  	DSS_IO_PAD_MODE_RESET,
  	DSS_IO_PAD_MODE_RFBI,
diff --git a/drivers/video/omap2/dss/hdmi4.c b/drivers/video/omap2/dss/hdmi4.c
index f1a45fe..f255641 100644
--- a/drivers/video/omap2/dss/hdmi4.c
+++ b/drivers/video/omap2/dss/hdmi4.c
@@ -77,7 +77,8 @@ static void hdmi_runtime_put(void)

  	DSSDBG("hdmi_runtime_put\n");

-	r = pm_runtime_put_sync(&hdmi.pdev->dev);
+	pm_runtime_mark_last_busy(&hdmi.pdev->dev);
+	r = pm_runtime_put_autosuspend(&hdmi.pdev->dev);
  	WARN_ON(r < 0 && r != -ENOSYS);
  }
@@ -631,6 +632,8 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
  	}

  	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, DSS_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);

  	hdmi_init_output(pdev);
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 74d3ed1..20dcbfb 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -147,7 +147,8 @@ static void rfbi_runtime_put(void)

  	DSSDBG("rfbi_runtime_put\n");

-	r = pm_runtime_put_sync(&rfbi.pdev->dev);
+	pm_runtime_mark_last_busy(&rfbi.pdev->dev);
+	r = pm_runtime_put_autosuspend(&rfbi.pdev->dev);
  	WARN_ON(r < 0 && r != -ENOSYS);
  }
@@ -981,6 +982,8 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
  	clk_put(clk);

  	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, DSS_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);

  	r = rfbi_runtime_get();
  	if (r)
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index e173961..bbd35bb 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -410,7 +410,8 @@ static void venc_runtime_put(void)

  	DSSDBG("venc_runtime_put\n");

-	r = pm_runtime_put_sync(&venc.pdev->dev);
+	pm_runtime_mark_last_busy(&venc.pdev->dev);
+	r = pm_runtime_put_autosuspend(&venc.pdev->dev);
  	WARN_ON(r < 0 && r != -ENOSYS);
  }
@@ -835,6 +836,8 @@ static int omap_venchw_probe(struct platform_device *pdev)
  		return r;

  	pm_runtime_enable(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, DSS_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);

  	r = venc_runtime_get();
  	if (r)

Re: [PATCH 1/6] OMAPDSS: APPLY: set infos to dirty on enable

From: Tomi Valkeinen <hidden>
Date: 2013-11-26 10:21:14

On 2013-11-25 03:06, Archit Taneja wrote:
On Monday 18 November 2013 06:20 PM, Tomi Valkeinen wrote:
quoted
Currently when DISPC is suspended, the driver stores all DISPC registers
to memory, so that they can be restored on resume. This is a bad way to
handle suspend/resume, as it's prone to failures and requires somewhat
large amount of extra space to store the registers.

A better approach is to program the DISPC from scratch when resuming.
This can be easily accomplished in apply layer by setting the manager
and overlay infos to dirty when the manager is to be enabled.
I guess this won't work if we wanted to support DSI command mode
displays. I.e, only shut DSS off and keep the panel up. In that case, we
would need to mark the flags dirty in dss_mgr_start_update_compat().
Hmm, true, I didn't try with DSI command mode panel. But I think it
should work. The DSI driver should call mgr->enable before update, if
the mgr has been off.

 Tomi

Re: [PATCH 6/6] OMAPDSS: use runtime PM's autosuspend

From: Tomi Valkeinen <hidden>
Date: 2013-11-26 10:27:47

On 2013-11-25 03:29, Archit Taneja wrote:
On Monday 18 November 2013 06:20 PM, Tomi Valkeinen wrote:
quoted
Use runtime PM's autosuspend support with delay of 100ms.

This will prevent the driver from turning the DSS modules off and on
multiple times e.g. when loading the module.
Could you explain this a bit more?
First of all, I'm not quite sure if this is even needed. Things are
probably simpler without autosuspend, and we don't have much on/off
cycles going on in DSS, so I don't think autosuspend helps much.

Maybe it's even bad if somebody wants to enable/disable the DSS HW very
quickly. So in the minimum, autosuspend should be made configurable. For
now, I think I'll just leave it out.
Are you saying that when we insert the omapdss module, we have a lot of
runtime_get/put pairs in probe, which leads to us excessive writing of
DISPC the registers during resume, and the autosuspend feature would
delay the effect of runtime_put() for a while?
For example, first DSS is probed. the dss.c driver will enable dss_core
(i.e. the whole DSS hw block), do some register reads/writes, and
disable dss_core. Then DISPC is probed, and things go very much like
with DSS. And so on. Each submodule will enable and disable the whole
DSS, because nothing is keeping the DSS enabled between the probes.

With autosuspend, the DSS HW block will stay enabled long enough so the
next probe gets ran.
Also, do we need to do this for all the platform devices? Could we use
autosuspend only for the parent platform device, and the children
platform devices don't use it? Or am I understanding things wrongly here?
In theory, yes. In practice, if I'm not mistaken, no. When a device is
enabled, it'll enable the parent device. When the device is disabled,
its parent device will be immediately disabled (if nothing is using it),
so autosuspend doesn't have an effect there.

So we need to use autosuspend for the child devices.

 Tomi

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help