From: Subramani Venkatesh <x0108988@xxxxxx> Patch has definition for LPR enable and disable funtion. lpr_enable: Implements the power saving technique defined in the document by implementing FIFO merge and thus enabling long idle of the DMA, which inturn saves power when whole system is in IDLE state. lpr_disable: Restores the DSS into its old state before enabling the LPR. Signed-off-by: Kishore Y <kishore.y@xxxxxx> Signed-off-by: Sudeep Basavaraj <sudeep.basavaraj@xxxxxx> --- drivers/video/omap2/dss/dispc.c | 132 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 132 insertions(+), 0 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 5f7819b..daf1ae4 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -132,6 +132,13 @@ struct dispc_reg { u16 idx; }; #define DISPC_MAX_NR_ISRS 8 +#define LPR_GFX_FIFO_HIGH_THRES 0xB9C +#define LPR_GFX_FIFO_LOW_THRES 0x7F8 +#define DISPC_VID_ATTRIBUTES_ENABLE (1 << 0) +#define DSS_CONTROL_APLL_CLK 1 +static int lpr_enabled; +static int gfx_in_use; + struct omap_dispc_isr_data { omap_dispc_isr_t isr; void *arg; @@ -154,6 +161,7 @@ static struct { u32 fifo_size[3]; spinlock_t irq_lock; + spinlock_t lpr_lock; u32 irq_error_mask; struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS]; u32 error_irqs; @@ -2633,6 +2641,122 @@ int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask) } EXPORT_SYMBOL(omap_dispc_unregister_isr); +/* This functions adds the OMAPDSS power saving capability by + * FIFO Merge when display is not in use, thus ehancing the DSS for + * Screen saver support. + */ +int omap_dispc_lpr_enable(void) +{ + int rc = 0; + unsigned long flags; + struct omap_overlay *ovl; + int v_attr; + + /* Cannot enable lpr if DSS is inactive */ + if (!gfx_in_use) { + DSSDBG("\nGRX plane in use\n"); + return -EBUSY; + } + + spin_lock_irqsave(&dispc.lpr_lock, flags); + + if (lpr_enabled) { + DSSDBG("\nLPR is enabled\n"); + goto lpr_out; + } + + /* Check whether LPR can be triggered + * - gfx pipeline is routed to LCD + * - both video pipelines are disabled (this allows FIFOs merge) + */ + + ovl = omap_dss_get_overlay(0); + + if (!ovl) { + rc = -ENODEV; + goto lpr_out; + } + + if (ovl->manager->id != OMAP_DSS_CHANNEL_LCD) { + rc = -ENODEV; + goto lpr_out; + } + + v_attr = dispc_read_reg(DISPC_VID_ATTRIBUTES(0)) | + dispc_read_reg(DISPC_VID_ATTRIBUTES(1)); + + if (v_attr & DISPC_VID_ATTRIBUTES_ENABLE) { + rc = -ENODEV; + goto lpr_out; + } + + /* Currently DSS is running on DSS1 by default. just warn if it has + * changed in the future + */ + if (dss_get_dispc_clk_source() == DSS_CONTROL_APLL_CLK) + BUG(); + + dispc_setup_plane_fifo(ovl->id, LPR_GFX_FIFO_LOW_THRES, + LPR_GFX_FIFO_HIGH_THRES); + + dispc_enable_fifomerge(1); + + /* Enable LCD */ + dispc_enable_lcd_out(1); + + spin_unlock_irqrestore(&dispc.lpr_lock, flags); + + /* Let LPR settings take an effect */ + dispc_go(ovl->manager->id); + + lpr_enabled = 1; + + return 0; + +lpr_out: + spin_unlock_irqrestore(&dispc.lpr_lock, flags); + return rc; +} +EXPORT_SYMBOL(omap_dispc_lpr_enable); + +int omap_dispc_lpr_disable(void) +{ + unsigned long flags; + struct omap_overlay *ovl; + u32 fifo_low, fifo_high; + enum omap_burst_size burst_size; + + if (!gfx_in_use) + return -EBUSY; + + spin_lock_irqsave(&dispc.lpr_lock, flags); + + ovl = omap_dss_get_overlay(0); + + if (!lpr_enabled) { + spin_unlock_irqrestore(&dispc.lpr_lock, flags); + return 0; + } + /* Disable Fifo Merge */ + dispc_enable_fifomerge(0); + + default_get_overlay_fifo_thresholds(ovl->id, dispc.fifo_size[ovl->id], + &burst_size, &fifo_low, &fifo_high); + + /* Restore default fifo size*/ + dispc_setup_plane_fifo(ovl->id, fifo_low, fifo_high); + + lpr_enabled = 0; + + spin_unlock_irqrestore(&dispc.lpr_lock, flags); + + /* Let DSS take an effect */ + dispc_go(ovl->manager->id); + + return 0; +} +EXPORT_SYMBOL(omap_dispc_lpr_disable); + #ifdef DEBUG static void print_irq_status(u32 status) { @@ -3056,6 +3180,14 @@ int dispc_enable_plane(enum omap_plane plane, bool enable) enable_clocks(1); _dispc_enable_plane(plane, enable); + + if (plane == OMAP_DSS_GFX) { + if (enable) + gfx_in_use = 1; + else + gfx_in_use = 0; + } + enable_clocks(0); return 0; -- 1.5.4.3 Regards, Kishore Y -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html