diff options
| author | Koen Kooi <koen@openembedded.org> | 2008-12-08 20:03:10 +0100 |
|---|---|---|
| committer | Koen Kooi <koen@openembedded.org> | 2008-12-08 20:03:10 +0100 |
| commit | e1af703acc24a2ecf523b9fe6903f649799870b4 (patch) | |
| tree | fdd1d188de6ae65cbdbb23c08b89b374472a6212 | |
| parent | bd37ae33873c0d4004f59f10d69f5567896cd1f5 (diff) | |
linux-omap git: refresh DSS2 patches against upstream git
10 files changed, 1900 insertions, 738 deletions
diff --git a/packages/linux/linux-omap/0003-DSS-Documentation-for-OMAP2-3-display-subsystem.patch b/packages/linux/linux-omap/0003-DSS-Documentation-for-OMAP2-3-display-subsystem.patch index 6cc8ce12c6..c3dba570d6 100644 --- a/packages/linux/linux-omap/0003-DSS-Documentation-for-OMAP2-3-display-subsystem.patch +++ b/packages/linux/linux-omap/0003-DSS-Documentation-for-OMAP2-3-display-subsystem.patch @@ -1,4 +1,4 @@ -From e8cc995ace5ef4c8e920ccac6bacc1a0129ad2c4 Mon Sep 17 00:00:00 2001 +From 66fad2b53d3427962407b40af79e227635aed780 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen <tomi.valkeinen@nokia.com> Date: Tue, 4 Nov 2008 15:08:07 +0200 Subject: [PATCH] DSS: Documentation for OMAP2/3 display subsystem diff --git a/packages/linux/linux-omap/0004-DSS-New-display-subsystem-driver-for-OMAP2-3.patch b/packages/linux/linux-omap/0004-DSS-New-display-subsystem-driver-for-OMAP2-3.patch index e7beec7898..8e64005c68 100644 --- a/packages/linux/linux-omap/0004-DSS-New-display-subsystem-driver-for-OMAP2-3.patch +++ b/packages/linux/linux-omap/0004-DSS-New-display-subsystem-driver-for-OMAP2-3.patch @@ -1,6 +1,6 @@ -From 6bec28d7c3d7cf97d644c610beadfef354fa596e Mon Sep 17 00:00:00 2001 +From 0eceac2ba3548ae41200403a8dae9907ab788fd0 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen <tomi.valkeinen@nokia.com> -Date: Thu, 13 Nov 2008 15:38:15 +0200 +Date: Mon, 8 Dec 2008 13:43:36 +0200 Subject: [PATCH] DSS: New display subsystem driver for OMAP2/3 Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com> @@ -9,17 +9,17 @@ Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com> arch/arm/plat-omap/Makefile | 2 + arch/arm/plat-omap/dss/Kconfig | 66 + arch/arm/plat-omap/dss/Makefile | 6 + - arch/arm/plat-omap/dss/dispc.c | 1722 ++++++++++++++++ - arch/arm/plat-omap/dss/display.c | 775 ++++++++ - arch/arm/plat-omap/dss/dpi.c | 323 +++ - arch/arm/plat-omap/dss/dsi.c | 3020 +++++++++++++++++++++++++++++ - arch/arm/plat-omap/dss/dss.c | 554 ++++++ - arch/arm/plat-omap/dss/dss.h | 254 +++ - arch/arm/plat-omap/dss/rfbi.c | 1234 ++++++++++++ - arch/arm/plat-omap/dss/sdi.c | 157 ++ - arch/arm/plat-omap/dss/venc.c | 515 +++++ - arch/arm/plat-omap/include/mach/display.h | 458 +++++ - 14 files changed, 9088 insertions(+), 0 deletions(-) + arch/arm/plat-omap/dss/dispc.c | 2021 +++++++++++++++++++ + arch/arm/plat-omap/dss/display.c | 765 +++++++ + arch/arm/plat-omap/dss/dpi.c | 320 +++ + arch/arm/plat-omap/dss/dsi.c | 3135 +++++++++++++++++++++++++++++ + arch/arm/plat-omap/dss/dss.c | 784 +++++++ + arch/arm/plat-omap/dss/dss.h | 268 +++ + arch/arm/plat-omap/dss/rfbi.c | 1225 +++++++++++ + arch/arm/plat-omap/dss/sdi.c | 150 ++ + arch/arm/plat-omap/dss/venc.c | 501 +++++ + arch/arm/plat-omap/include/mach/display.h | 463 +++++ + 14 files changed, 9708 insertions(+), 0 deletions(-) create mode 100644 arch/arm/plat-omap/dss/Kconfig create mode 100644 arch/arm/plat-omap/dss/Makefile create mode 100644 arch/arm/plat-omap/dss/dispc.c @@ -142,10 +142,10 @@ index 0000000..e98c6c1 +omap-dss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o diff --git a/arch/arm/plat-omap/dss/dispc.c b/arch/arm/plat-omap/dss/dispc.c new file mode 100644 -index 0000000..3738cf3 +index 0000000..33fbd0a --- /dev/null +++ b/arch/arm/plat-omap/dss/dispc.c -@@ -0,0 +1,1722 @@ +@@ -0,0 +1,2021 @@ +/* + * linux/arch/arm/plat-omap/dss/dispc.c + * @@ -188,6 +188,8 @@ index 0000000..3738cf3 +/* DISPC */ +#define DISPC_BASE 0x48050400 + ++#define DISPC_SZ_REGS SZ_1K ++ +struct dispc_reg { u16 idx; }; + +#define DISPC_REG(idx) ((const struct dispc_reg) { idx }) @@ -211,13 +213,10 @@ index 0000000..3738cf3 +#define DISPC_TIMING_V DISPC_REG(0x0068) +#define DISPC_POL_FREQ DISPC_REG(0x006C) +#define DISPC_DIVISOR DISPC_REG(0x0070) ++#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074) +#define DISPC_SIZE_DIG DISPC_REG(0x0078) +#define DISPC_SIZE_LCD DISPC_REG(0x007C) + -+#define DISPC_DATA_CYCLE1 DISPC_REG(0x01D4) -+#define DISPC_DATA_CYCLE2 DISPC_REG(0x01D8) -+#define DISPC_DATA_CYCLE3 DISPC_REG(0x01DC) -+ +/* DISPC GFX plane */ +#define DISPC_GFX_BA0 DISPC_REG(0x0080) +#define DISPC_GFX_BA1 DISPC_REG(0x0084) @@ -231,6 +230,16 @@ index 0000000..3738cf3 +#define DISPC_GFX_WINDOW_SKIP DISPC_REG(0x00B4) +#define DISPC_GFX_TABLE_BA DISPC_REG(0x00B8) + ++#define DISPC_DATA_CYCLE1 DISPC_REG(0x01D4) ++#define DISPC_DATA_CYCLE2 DISPC_REG(0x01D8) ++#define DISPC_DATA_CYCLE3 DISPC_REG(0x01DC) ++ ++#define DISPC_CPR_COEF_R DISPC_REG(0x0220) ++#define DISPC_CPR_COEF_G DISPC_REG(0x0224) ++#define DISPC_CPR_COEF_B DISPC_REG(0x0228) ++ ++#define DISPC_GFX_PRELOAD DISPC_REG(0x022C) ++ +/* DISPC Video plane, n = 0 for VID1 and n = 1 for VID2 */ +#define DISPC_VID_REG(n, idx) DISPC_REG(0x00BC + (n)*0x90 + idx) + @@ -254,6 +263,11 @@ index 0000000..3738cf3 +#define DISPC_VID_FIR_COEF_HV(n, i) DISPC_REG(0x00F4 + (n)*0x90 + (i)*0x8) +/* coef index i = {0, 1, 2, 3, 4} */ +#define DISPC_VID_CONV_COEF(n, i) DISPC_REG(0x0130 + (n)*0x90 + (i)*0x4) ++/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ ++#define DISPC_VID_FIR_COEF_V(n, i) DISPC_REG(0x01E0 + (n)*0x20 + (i)*0x4) ++ ++#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04) ++ + +#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \ + DISPC_IRQ_OCP_ERR | \ @@ -283,24 +297,12 @@ index 0000000..3738cf3 +static struct { + void __iomem *base; + -+ struct clk *dss_ick; -+ struct clk *dss1_fck; -+ struct clk *dss_54m_fck; + struct clk *dpll4_m4_ck; -+} dispc; + -+static spinlock_t dss_lock; ++ spinlock_t irq_lock; + -+static inline void enable_clocks(int enable) -+{ -+ if (enable) { -+ clk_enable(dispc.dss_ick); -+ clk_enable(dispc.dss1_fck); -+ } else { -+ clk_disable(dispc.dss1_fck); -+ clk_disable(dispc.dss_ick); -+ } -+} ++ u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; ++} dispc; + +static inline void dispc_write_reg(const struct dispc_reg idx, u32 val) +{ @@ -312,6 +314,303 @@ index 0000000..3738cf3 + return __raw_readl(dispc.base + idx.idx); +} + ++#define SR(reg) \ ++ dispc.ctx[(DISPC_##reg).idx / sizeof(u32)] = dispc_read_reg(DISPC_##reg) ++#define RR(reg) \ ++ dispc_write_reg(DISPC_##reg, dispc.ctx[(DISPC_##reg).idx / sizeof(u32)]) ++ ++void dispc_save_context(void) ++{ ++ SR(SYSCONFIG); ++ SR(IRQENABLE); ++ SR(CONTROL); ++ SR(CONFIG); ++ SR(DEFAULT_COLOR0); ++ SR(DEFAULT_COLOR1); ++ SR(TRANS_COLOR0); ++ SR(TRANS_COLOR1); ++ SR(LINE_NUMBER); ++ SR(TIMING_H); ++ SR(TIMING_V); ++ SR(POL_FREQ); ++ SR(DIVISOR); ++ SR(GLOBAL_ALPHA); ++ SR(SIZE_DIG); ++ SR(SIZE_LCD); ++ ++ SR(GFX_BA0); ++ SR(GFX_BA1); ++ SR(GFX_POSITION); ++ SR(GFX_SIZE); ++ SR(GFX_ATTRIBUTES); ++ SR(GFX_FIFO_THRESHOLD); ++ SR(GFX_ROW_INC); ++ SR(GFX_PIXEL_INC); ++ SR(GFX_WINDOW_SKIP); ++ SR(GFX_TABLE_BA); ++ ++ SR(DATA_CYCLE1); ++ SR(DATA_CYCLE2); ++ SR(DATA_CYCLE3); ++ ++ SR(CPR_COEF_R); ++ SR(CPR_COEF_G); ++ SR(CPR_COEF_B); ++ ++ SR(GFX_PRELOAD); ++ ++ /* VID1 */ ++ SR(VID_BA0(0)); ++ SR(VID_BA1(0)); ++ SR(VID_POSITION(0)); ++ SR(VID_SIZE(0)); ++ SR(VID_ATTRIBUTES(0)); ++ SR(VID_FIFO_THRESHOLD(0)); ++ SR(VID_ROW_INC(0)); ++ SR(VID_PIXEL_INC(0)); ++ SR(VID_FIR(0)); ++ SR(VID_PICTURE_SIZE(0)); ++ SR(VID_ACCU0(0)); ++ SR(VID_ACCU1(0)); ++ ++ SR(VID_FIR_COEF_H(0, 0)); ++ SR(VID_FIR_COEF_H(0, 1)); ++ SR(VID_FIR_COEF_H(0, 2)); ++ SR(VID_FIR_COEF_H(0, 3)); ++ SR(VID_FIR_COEF_H(0, 4)); ++ SR(VID_FIR_COEF_H(0, 5)); ++ SR(VID_FIR_COEF_H(0, 6)); ++ SR(VID_FIR_COEF_H(0, 7)); ++ ++ SR(VID_FIR_COEF_HV(0, 0)); ++ SR(VID_FIR_COEF_HV(0, 1)); ++ SR(VID_FIR_COEF_HV(0, 2)); ++ SR(VID_FIR_COEF_HV(0, 3)); ++ SR(VID_FIR_COEF_HV(0, 4)); ++ SR(VID_FIR_COEF_HV(0, 5)); ++ SR(VID_FIR_COEF_HV(0, 6)); ++ SR(VID_FIR_COEF_HV(0, 7)); ++ ++ SR(VID_CONV_COEF(0, 0)); ++ SR(VID_CONV_COEF(0, 1)); ++ SR(VID_CONV_COEF(0, 2)); ++ SR(VID_CONV_COEF(0, 3)); ++ SR(VID_CONV_COEF(0, 4)); ++ ++ SR(VID_FIR_COEF_V(0, 0)); ++ SR(VID_FIR_COEF_V(0, 1)); ++ SR(VID_FIR_COEF_V(0, 2)); ++ SR(VID_FIR_COEF_V(0, 3)); ++ SR(VID_FIR_COEF_V(0, 4)); ++ SR(VID_FIR_COEF_V(0, 5)); ++ SR(VID_FIR_COEF_V(0, 6)); ++ SR(VID_FIR_COEF_V(0, 7)); ++ ++ SR(VID_PRELOAD(0)); ++ ++ /* VID2 */ ++ SR(VID_BA0(1)); ++ SR(VID_BA1(1)); ++ SR(VID_POSITION(1)); ++ SR(VID_SIZE(1)); ++ SR(VID_ATTRIBUTES(1)); ++ SR(VID_FIFO_THRESHOLD(1)); ++ SR(VID_ROW_INC(1)); ++ SR(VID_PIXEL_INC(1)); ++ SR(VID_FIR(1)); ++ SR(VID_PICTURE_SIZE(1)); ++ SR(VID_ACCU0(1)); ++ SR(VID_ACCU1(1)); ++ ++ SR(VID_FIR_COEF_H(1, 0)); ++ SR(VID_FIR_COEF_H(1, 1)); ++ SR(VID_FIR_COEF_H(1, 2)); ++ SR(VID_FIR_COEF_H(1, 3)); ++ SR(VID_FIR_COEF_H(1, 4)); ++ SR(VID_FIR_COEF_H(1, 5)); ++ SR(VID_FIR_COEF_H(1, 6)); ++ SR(VID_FIR_COEF_H(1, 7)); ++ ++ SR(VID_FIR_COEF_HV(1, 0)); ++ SR(VID_FIR_COEF_HV(1, 1)); ++ SR(VID_FIR_COEF_HV(1, 2)); ++ SR(VID_FIR_COEF_HV(1, 3)); ++ SR(VID_FIR_COEF_HV(1, 4)); ++ SR(VID_FIR_COEF_HV(1, 5)); ++ SR(VID_FIR_COEF_HV(1, 6)); ++ SR(VID_FIR_COEF_HV(1, 7)); ++ ++ SR(VID_CONV_COEF(1, 0)); ++ SR(VID_CONV_COEF(1, 1)); ++ SR(VID_CONV_COEF(1, 2)); ++ SR(VID_CONV_COEF(1, 3)); ++ SR(VID_CONV_COEF(1, 4)); ++ ++ SR(VID_FIR_COEF_V(1, 0)); ++ SR(VID_FIR_COEF_V(1, 1)); ++ SR(VID_FIR_COEF_V(1, 2)); ++ SR(VID_FIR_COEF_V(1, 3)); ++ SR(VID_FIR_COEF_V(1, 4)); ++ SR(VID_FIR_COEF_V(1, 5)); ++ SR(VID_FIR_COEF_V(1, 6)); ++ SR(VID_FIR_COEF_V(1, 7)); ++ ++ SR(VID_PRELOAD(1)); ++} ++ ++void dispc_restore_context(void) ++{ ++ RR(SYSCONFIG); ++ RR(IRQENABLE); ++ //RR(CONTROL); ++ RR(CONFIG); ++ RR(DEFAULT_COLOR0); ++ RR(DEFAULT_COLOR1); ++ RR(TRANS_COLOR0); ++ RR(TRANS_COLOR1); ++ RR(LINE_NUMBER); ++ RR(TIMING_H); ++ RR(TIMING_V); ++ RR(POL_FREQ); ++ RR(DIVISOR); ++ RR(GLOBAL_ALPHA); ++ RR(SIZE_DIG); ++ RR(SIZE_LCD); ++ ++ RR(GFX_BA0); ++ RR(GFX_BA1); ++ RR(GFX_POSITION); ++ RR(GFX_SIZE); ++ RR(GFX_ATTRIBUTES); ++ RR(GFX_FIFO_THRESHOLD); ++ RR(GFX_ROW_INC); ++ RR(GFX_PIXEL_INC); ++ RR(GFX_WINDOW_SKIP); ++ RR(GFX_TABLE_BA); ++ ++ RR(DATA_CYCLE1); ++ RR(DATA_CYCLE2); ++ RR(DATA_CYCLE3); ++ ++ RR(CPR_COEF_R); ++ RR(CPR_COEF_G); ++ RR(CPR_COEF_B); ++ ++ RR(GFX_PRELOAD); ++ ++ /* VID1 */ ++ RR(VID_BA0(0)); ++ RR(VID_BA1(0)); ++ RR(VID_POSITION(0)); ++ RR(VID_SIZE(0)); ++ RR(VID_ATTRIBUTES(0)); ++ RR(VID_FIFO_THRESHOLD(0)); ++ RR(VID_ROW_INC(0)); ++ RR(VID_PIXEL_INC(0)); ++ RR(VID_FIR(0)); ++ RR(VID_PICTURE_SIZE(0)); ++ RR(VID_ACCU0(0)); ++ RR(VID_ACCU1(0)); ++ ++ RR(VID_FIR_COEF_H(0, 0)); ++ RR(VID_FIR_COEF_H(0, 1)); ++ RR(VID_FIR_COEF_H(0, 2)); ++ RR(VID_FIR_COEF_H(0, 3)); ++ RR(VID_FIR_COEF_H(0, 4)); ++ RR(VID_FIR_COEF_H(0, 5)); ++ RR(VID_FIR_COEF_H(0, 6)); ++ RR(VID_FIR_COEF_H(0, 7)); ++ ++ RR(VID_FIR_COEF_HV(0, 0)); ++ RR(VID_FIR_COEF_HV(0, 1)); ++ RR(VID_FIR_COEF_HV(0, 2)); ++ RR(VID_FIR_COEF_HV(0, 3)); ++ RR(VID_FIR_COEF_HV(0, 4)); ++ RR(VID_FIR_COEF_HV(0, 5)); ++ RR(VID_FIR_COEF_HV(0, 6)); ++ RR(VID_FIR_COEF_HV(0, 7)); ++ ++ RR(VID_CONV_COEF(0, 0)); ++ RR(VID_CONV_COEF(0, 1)); ++ RR(VID_CONV_COEF(0, 2)); ++ RR(VID_CONV_COEF(0, 3)); ++ RR(VID_CONV_COEF(0, 4)); ++ ++ RR(VID_FIR_COEF_V(0, 0)); ++ RR(VID_FIR_COEF_V(0, 1)); ++ RR(VID_FIR_COEF_V(0, 2)); ++ RR(VID_FIR_COEF_V(0, 3)); ++ RR(VID_FIR_COEF_V(0, 4)); ++ RR(VID_FIR_COEF_V(0, 5)); ++ RR(VID_FIR_COEF_V(0, 6)); ++ RR(VID_FIR_COEF_V(0, 7)); ++ ++ RR(VID_PRELOAD(0)); ++ ++ /* VID2 */ ++ RR(VID_BA0(1)); ++ RR(VID_BA1(1)); ++ RR(VID_POSITION(1)); ++ RR(VID_SIZE(1)); ++ RR(VID_ATTRIBUTES(1)); ++ RR(VID_FIFO_THRESHOLD(1)); ++ RR(VID_ROW_INC(1)); ++ RR(VID_PIXEL_INC(1)); ++ RR(VID_FIR(1)); ++ RR(VID_PICTURE_SIZE(1)); ++ RR(VID_ACCU0(1)); ++ RR(VID_ACCU1(1)); ++ ++ RR(VID_FIR_COEF_H(1, 0)); ++ RR(VID_FIR_COEF_H(1, 1)); ++ RR(VID_FIR_COEF_H(1, 2)); ++ RR(VID_FIR_COEF_H(1, 3)); ++ RR(VID_FIR_COEF_H(1, 4)); ++ RR(VID_FIR_COEF_H(1, 5)); ++ RR(VID_FIR_COEF_H(1, 6)); ++ RR(VID_FIR_COEF_H(1, 7)); ++ ++ RR(VID_FIR_COEF_HV(1, 0)); ++ RR(VID_FIR_COEF_HV(1, 1)); ++ RR(VID_FIR_COEF_HV(1, 2)); ++ RR(VID_FIR_COEF_HV(1, 3)); ++ RR(VID_FIR_COEF_HV(1, 4)); ++ RR(VID_FIR_COEF_HV(1, 5)); ++ RR(VID_FIR_COEF_HV(1, 6)); ++ RR(VID_FIR_COEF_HV(1, 7)); ++ ++ RR(VID_CONV_COEF(1, 0)); ++ RR(VID_CONV_COEF(1, 1)); ++ RR(VID_CONV_COEF(1, 2)); ++ RR(VID_CONV_COEF(1, 3)); ++ RR(VID_CONV_COEF(1, 4)); ++ ++ RR(VID_FIR_COEF_V(1, 0)); ++ RR(VID_FIR_COEF_V(1, 1)); ++ RR(VID_FIR_COEF_V(1, 2)); ++ RR(VID_FIR_COEF_V(1, 3)); ++ RR(VID_FIR_COEF_V(1, 4)); ++ RR(VID_FIR_COEF_V(1, 5)); ++ RR(VID_FIR_COEF_V(1, 6)); ++ RR(VID_FIR_COEF_V(1, 7)); ++ ++ RR(VID_PRELOAD(1)); ++ ++ /* enable last, because LCD & DIGIT enable are here */ ++ RR(CONTROL); ++} ++ ++#undef SR ++#undef RR ++ ++static inline void enable_clocks(int enable) ++{ ++ if (enable) ++ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); ++ else ++ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); ++} ++ +void dispc_go(enum omap_channel channel) +{ + int bit; @@ -962,13 +1261,6 @@ index 0000000..3738cf3 +} + + -+static inline void get_dss_clocks(void) -+{ -+ dispc.dss_ick = get_dss_ick(); -+ dispc.dss1_fck = get_dss1_fck(); -+ dispc.dss_54m_fck = get_tv_fck(); -+} -+ +void dispc_set_lcd_display_type(enum omap_lcd_display_type type) +{ + int mode; @@ -1160,7 +1452,7 @@ index 0000000..3738cf3 + unsigned long r = 0; + + if (dss_get_dispc_clk_source() == 0) -+ r = clk_get_rate(dispc.dss1_fck); ++ r = dss_clk_get_rate(DSS_CLK_FCK1); + else +#ifdef CONFIG_OMAP2_DSS_DSI + r = dsi_get_dsi1_pll_rate(); @@ -1387,7 +1679,7 @@ index 0000000..3738cf3 + if (isr == NULL) + return -EINVAL; + -+ spin_lock_irqsave(&dss_lock, flags); ++ spin_lock_irqsave(&dispc.irq_lock, flags); + + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) { + if (registered_isr[i].isr == isr) { @@ -1412,7 +1704,7 @@ index 0000000..3738cf3 + break; + } + -+ spin_unlock_irqrestore(&dss_lock, flags); ++ spin_unlock_irqrestore(&dispc.irq_lock, flags); + + return ret; +} @@ -1425,7 +1717,7 @@ index 0000000..3738cf3 + u32 new_mask = DISPC_IRQ_MASK_ERROR; + int ret = -EINVAL; + -+ spin_lock_irqsave(&dss_lock, flags); ++ spin_lock_irqsave(&dispc.irq_lock, flags); + + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) { + if (registered_isr[i].isr != isr) @@ -1446,7 +1738,7 @@ index 0000000..3738cf3 + break; + } + -+ spin_unlock_irqrestore(&dss_lock, flags); ++ spin_unlock_irqrestore(&dispc.irq_lock, flags); + + return ret; +} @@ -1551,7 +1843,7 @@ index 0000000..3738cf3 + l = FLD_MOD(l, 2, 13, 12); /* MIDLEMODE: smart standby */ + l = FLD_MOD(l, 2, 4, 3); /* SIDLEMODE: smart idle */ + l = FLD_MOD(l, 1, 2, 2); /* ENWAKEUP */ -+ l = FLD_MOD(l, 1, 1, 1); /* AUTOIDLE */ ++ l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */ + dispc_write_reg(DISPC_SYSCONFIG, l); + + /* FUNCGATED */ @@ -1570,24 +1862,29 @@ index 0000000..3738cf3 + + /* Set logic clock to fck, pixel clock to fck/2 for now */ + dispc_set_lcd_divisor(1, 2); ++ ++ dispc_setup_plane_fifo(OMAP_DSS_GFX, 0); ++ dispc_setup_plane_fifo(OMAP_DSS_VIDEO1, 0); ++ dispc_setup_plane_fifo(OMAP_DSS_VIDEO2, 0); +} + +int dispc_init(void) +{ + u32 rev; + -+ spin_lock_init(&dss_lock); ++ spin_lock_init(&dispc.irq_lock); + -+ dispc.base = ioremap(DISPC_BASE, SZ_1K); ++ dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS); + if (!dispc.base) { + DSSERR("can't ioremap DISPC\n"); + return -ENOMEM; + } + -+ get_dss_clocks(); + dispc.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); -+ if (IS_ERR(dispc.dpll4_m4_ck)) ++ if (IS_ERR(dispc.dpll4_m4_ck)) { + DSSERR("Failed to get dpll4_m4_ck\n"); ++ return -ENODEV; ++ } + + enable_clocks(1); + @@ -1595,6 +1892,8 @@ index 0000000..3738cf3 + + _omap_dispc_initialize_irq(); + ++ dispc_save_context(); ++ + rev = dispc_read_reg(DISPC_REVISION); + printk(KERN_INFO "OMAP DISPC rev %d.%d\n", + FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); @@ -1870,10 +2169,10 @@ index 0000000..3738cf3 + diff --git a/arch/arm/plat-omap/dss/display.c b/arch/arm/plat-omap/dss/display.c new file mode 100644 -index 0000000..4d7238f +index 0000000..b7f7aff --- /dev/null +++ b/arch/arm/plat-omap/dss/display.c -@@ -0,0 +1,775 @@ +@@ -0,0 +1,765 @@ +/* + * linux/arch/arm/plat-omap/dss/display.c + * @@ -1917,26 +2216,11 @@ index 0000000..4d7238f +static ssize_t show_clk(struct device *dev, struct device_attribute *attr, + char *buf) +{ -+ struct clk *clocks[5]; -+ int i; + ssize_t l, size = PAGE_SIZE; + -+ clocks[0] = get_dss_ick(); -+ clocks[1] = get_dss1_fck(); -+ clocks[2] = get_dss2_fck(); -+ clocks[3] = get_tv_fck(); -+ clocks[4] = get_96m_fck(); -+ + l = 0; + -+ l += snprintf(buf + l, size - l, "- dss -\n"); -+ -+ for (i = 0; i < 5; i++) { -+ l += snprintf(buf + l, size - l, "%-15s\t%lu\t%d\n", -+ clocks[i]->name, -+ clk_get_rate(clocks[i]), -+ clk_get_usecount(clocks[i])); -+ } ++ l += dss_print_clocks(buf + l, size - l); + + l += dispc_print_clocks(buf + l, size - l); +#ifdef CONFIG_OMAP2_DSS_DSI @@ -2218,7 +2502,7 @@ index 0000000..4d7238f +static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) +{ + int i; -+ int r; ++ int r = 0; + + DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name); + @@ -2236,6 +2520,8 @@ index 0000000..4d7238f + return 0; + } + ++ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); ++ + for (i = 0; i < mgr->num_overlays; i++) { + int ilace = 0; + int outw, outh; @@ -2282,7 +2568,7 @@ index 0000000..4d7238f + + if (r) { + DSSERR("dispc_setup_plane failed\n"); -+ return r; ++ goto exit; + } + + dispc_enable_plane(ovl->id, 1); @@ -2290,7 +2576,10 @@ index 0000000..4d7238f + + dispc_go(mgr->id); + -+ return 0; ++exit: ++ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); ++ ++ return r; +} + +static struct omap_overlay dispc_overlays[] = { @@ -2651,10 +2940,10 @@ index 0000000..4d7238f +EXPORT_SYMBOL(omap_dss_unregister_panel); diff --git a/arch/arm/plat-omap/dss/dpi.c b/arch/arm/plat-omap/dss/dpi.c new file mode 100644 -index 0000000..2261288 +index 0000000..e3ad44e --- /dev/null +++ b/arch/arm/plat-omap/dss/dpi.c -@@ -0,0 +1,323 @@ +@@ -0,0 +1,320 @@ +/* + * linux/arch/arm/plat-omap/dss/dpi.c + * @@ -2688,8 +2977,6 @@ index 0000000..2261288 + + +static struct { -+ struct clk *dss_ick; -+ struct clk *dss1_fck; + int update_enabled; +} dpi; + @@ -2790,11 +3077,13 @@ index 0000000..2261288 + if (r) + return r; + -+ clk_enable(dpi.dss_ick); -+ clk_enable(dpi.dss1_fck); ++ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL -+ dsi_pll_init(0, 1); ++ dss_clk_enable(DSS_CLK_FCK2); ++ r = dsi_pll_init(0, 1); ++ if (r) ++ return r; +#endif + is_tft = (display->panel->config & OMAP_DSS_LCD_TFT) != 0; + @@ -2830,10 +3119,10 @@ index 0000000..2261288 +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL + dss_select_clk_source(0, 0); + dsi_pll_uninit(); ++ dss_clk_disable(DSS_CLK_FCK2); +#endif + -+ clk_disable(dpi.dss_ick); -+ clk_disable(dpi.dss1_fck); ++ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + + display->state = OMAP_DSS_DISPLAY_DISABLED; +} @@ -2848,8 +3137,7 @@ index 0000000..2261288 + + dispc_enable_lcd_out(0); + -+ clk_disable(dpi.dss_ick); -+ clk_disable(dpi.dss1_fck); ++ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + + display->state = OMAP_DSS_DISPLAY_SUSPENDED; + @@ -2863,8 +3151,7 @@ index 0000000..2261288 + + dispc_enable_lcd_out(1); + -+ clk_enable(dpi.dss_ick); -+ clk_enable(dpi.dss1_fck); ++ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + + if (display->panel->resume) + display->panel->resume(display); @@ -2906,6 +3193,8 @@ index 0000000..2261288 + return -EINVAL; + } + ++ if (timings->pixel_clock == 0) ++ return -EINVAL; + + is_tft = (display->panel->config & OMAP_DSS_LCD_TFT) != 0; + @@ -2968,9 +3257,6 @@ index 0000000..2261288 + +int dpi_init(void) +{ -+ dpi.dss_ick = get_dss_ick(); -+ dpi.dss1_fck = get_dss1_fck(); -+ + return 0; +} + @@ -2980,10 +3266,10 @@ index 0000000..2261288 + diff --git a/arch/arm/plat-omap/dss/dsi.c b/arch/arm/plat-omap/dss/dsi.c new file mode 100644 -index 0000000..9f31ac3 +index 0000000..7f7db32 --- /dev/null +++ b/arch/arm/plat-omap/dss/dsi.c -@@ -0,0 +1,3020 @@ +@@ -0,0 +1,3135 @@ +/* + * linux/arch/arm/plat-omap/dss/dsi.c + * @@ -3017,6 +3303,7 @@ index 0000000..9f31ac3 + +#include <mach/board.h> +#include <mach/display.h> ++#include <mach/clock.h> + +#include "dss.h" + @@ -3030,6 +3317,7 @@ index 0000000..9f31ac3 + +#define DSI_REG(idx) ((const struct dsi_reg) { idx }) + ++#define DSI_SZ_REGS SZ_1K +/* DSI Protocol Engine */ + +#define DSI_REVISION DSI_REG(0x0000) @@ -3068,10 +3356,10 @@ index 0000000..9f31ac3 + +/* DSIPHY_SCP */ + -+#define DSIPHY_CFG0 DSI_REG(0x200 + 0x0000) -+#define DSIPHY_CFG1 DSI_REG(0x200 + 0x0004) -+#define DSIPHY_CFG2 DSI_REG(0x200 + 0x0008) -+#define DSIPHY_CFG5 DSI_REG(0x200 + 0x0014) ++#define DSI_DSIPHY_CFG0 DSI_REG(0x200 + 0x0000) ++#define DSI_DSIPHY_CFG1 DSI_REG(0x200 + 0x0004) ++#define DSI_DSIPHY_CFG2 DSI_REG(0x200 + 0x0008) ++#define DSI_DSIPHY_CFG5 DSI_REG(0x200 + 0x0014) + +/* DSI_PLL_CTRL_SCP */ + @@ -3178,15 +3466,13 @@ index 0000000..9f31ac3 +{ + void __iomem *base; + -+ struct clk *dss_ick; -+ struct clk *dss1_fck; -+ struct clk *dss2_fck; -+ + unsigned long dsi1_pll_fclk; /* Hz */ + unsigned long dsi2_pll_fclk; /* Hz */ + unsigned long dsiphy; /* Hz */ + unsigned long ddr_clk; /* Hz */ + ++ u32 ctx[DSI_SZ_REGS / sizeof(u32)]; ++ + struct { + enum fifo_size fifo_size; + int dest_per; /* destination peripheral 0-3 */ @@ -3194,15 +3480,18 @@ index 0000000..9f31ac3 + + struct mutex lock; + ++ unsigned pll_locked; ++ + struct completion bta_completion; + + spinlock_t update_lock; + int update_ongoing; + int update_syncers; + struct completion update_completion; -+ struct work_struct framedone_work; ++ struct delayed_work framedone_work; + -+ enum omap_dss_update_mode update_mode; ++ enum omap_dss_update_mode user_update_mode; /* what the user wants */ ++ enum omap_dss_update_mode update_mode; /* current mode */ + int use_te; + int framedone_scheduled; /* helps to catch strange framedone bugs */ + @@ -3218,7 +3507,6 @@ index 0000000..9f31ac3 +#endif +} dsi; + -+ +static inline void dsi_write_reg(const struct dsi_reg idx, u32 val) +{ + __raw_writel(val, dsi.base + idx.idx); @@ -3229,10 +3517,113 @@ index 0000000..9f31ac3 + return __raw_readl(dsi.base + idx.idx); +} + ++ ++#define SR(reg) \ ++ dsi.ctx[(DSI_##reg).idx / sizeof(u32)] = dsi_read_reg(DSI_##reg) ++#define RR(reg) \ ++ dsi_write_reg(DSI_##reg, dsi.ctx[(DSI_##reg).idx / sizeof(u32)]) ++ ++void dsi_save_context(void) ++{ ++ SR(SYSCONFIG); ++ SR(IRQENABLE); ++ SR(CTRL); ++ SR(COMPLEXIO_CFG1); ++ SR(COMPLEXIO_IRQ_ENABLE); ++ SR(CLK_CTRL); ++ SR(TIMING1); ++ SR(TIMING2); ++ SR(VM_TIMING1); ++ SR(VM_TIMING2); ++ SR(VM_TIMING3); ++ SR(CLK_TIMING); ++ SR(TX_FIFO_VC_SIZE); ++ SR(RX_FIFO_VC_SIZE); ++ SR(COMPLEXIO_CFG2); ++ SR(VM_TIMING4); ++ SR(VM_TIMING5); ++ SR(VM_TIMING6); ++ SR(VM_TIMING7); ++ SR(STOPCLK_TIMING); ++ ++ SR(VC_CTRL(0)); ++ SR(VC_TE(0)); ++ SR(VC_IRQENABLE(0)); ++ ++ SR(VC_CTRL(1)); ++ SR(VC_TE(1)); ++ SR(VC_IRQENABLE(1)); ++ ++ SR(VC_CTRL(2)); ++ SR(VC_TE(2)); ++ SR(VC_IRQENABLE(2)); ++ ++ SR(VC_CTRL(3)); ++ SR(VC_TE(3)); ++ SR(VC_IRQENABLE(3)); ++ ++ SR(DSIPHY_CFG0); ++ SR(DSIPHY_CFG1); ++ SR(DSIPHY_CFG2); ++ SR(DSIPHY_CFG5); ++ ++ SR(PLL_CONTROL); ++ SR(PLL_CONFIGURATION1); ++ SR(PLL_CONFIGURATION2); ++} ++ ++void dsi_restore_context(void) ++{ ++ RR(SYSCONFIG); ++ RR(IRQENABLE); ++ RR(CTRL); ++ RR(COMPLEXIO_CFG1); ++ RR(COMPLEXIO_IRQ_ENABLE); ++ RR(CLK_CTRL); ++ RR(TIMING1); ++ RR(TIMING2); ++ RR(VM_TIMING1); ++ RR(VM_TIMING2); ++ RR(VM_TIMING3); ++ RR(CLK_TIMING); ++ RR(TX_FIFO_VC_SIZE); ++ RR(RX_FIFO_VC_SIZE); ++ RR(COMPLEXIO_CFG2); ++ RR(VM_TIMING4); ++ RR(VM_TIMING5); ++ RR(VM_TIMING6); ++ RR(VM_TIMING7); ++ RR(STOPCLK_TIMING); ++ ++ RR(VC_CTRL(0)); ++ RR(VC_IRQENABLE(0)); ++ ++ RR(VC_CTRL(1)); ++ RR(VC_IRQENABLE(1)); ++ ++ RR(VC_CTRL(2)); ++ RR(VC_IRQENABLE(2)); ++ ++ RR(VC_CTRL(3)); ++ RR(VC_IRQENABLE(3)); ++ ++ RR(DSIPHY_CFG0); ++ RR(DSIPHY_CFG1); ++ RR(DSIPHY_CFG2); ++ RR(DSIPHY_CFG5); ++ ++ RR(PLL_CONTROL); ++ RR(PLL_CONFIGURATION1); ++ RR(PLL_CONFIGURATION2); ++} ++ ++#undef SR ++#undef RR ++ +static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, + int value) +{ -+ int t = 1000; ++ int t = 100000; + + while (REG_GET(idx, bitnum, bitnum) != value) { + if (--t == 0) @@ -3500,22 +3891,24 @@ index 0000000..9f31ac3 +/* DSI func clock. this could also be DSI2_PLL_FCLK */ +static inline void enable_clocks(int enable) +{ -+ if (enable) { -+ clk_enable(dsi.dss_ick); -+ clk_enable(dsi.dss1_fck); -+ } else { -+ clk_disable(dsi.dss1_fck); -+ clk_disable(dsi.dss_ick); -+ } ++ if (enable) ++ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); ++ else ++ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); +} + +/* source clock for DSI PLL. this could also be PCLKFREE */ +static inline void dsi_enable_pll_clock(int enable) +{ + if (enable) -+ clk_enable(dsi.dss2_fck); ++ dss_clk_enable(DSS_CLK_FCK2); + else -+ clk_disable(dsi.dss2_fck); ++ dss_clk_disable(DSS_CLK_FCK2); ++ ++ if (enable && dsi.pll_locked) { ++ if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) ++ DSSERR("cannot lock PLL when enabling clocks\n"); ++ } +} + +#if 1 @@ -3528,7 +3921,7 @@ index 0000000..9f31ac3 + /* A dummy read using the SCP interface to any DSIPHY register is + * required after DSIPHY reset to complete the reset of the DSI complex + * I/O. */ -+ l = dsi_read_reg(DSIPHY_CFG5); ++ l = dsi_read_reg(DSI_DSIPHY_CFG5); + + printk(KERN_DEBUG "DSI resets: "); + @@ -3538,7 +3931,7 @@ index 0000000..9f31ac3 + l = dsi_read_reg(DSI_COMPLEXIO_CFG1); + printk("CIO (%d) ", FLD_GET(l, 29, 29)); + -+ l = dsi_read_reg(DSIPHY_CFG5); ++ l = dsi_read_reg(DSI_DSIPHY_CFG5); + printk("PHY (%x, %d, %d, %d)\n", + FLD_GET(l, 28, 26), + FLD_GET(l, 29, 29), @@ -3564,7 +3957,7 @@ index 0000000..9f31ac3 + /* A dummy read using the SCP interface to any DSIPHY register is + * required after DSIPHY reset to complete the reset of the DSI complex + * I/O. */ -+ dsi_read_reg(DSIPHY_CFG5); ++ dsi_read_reg(DSI_DSIPHY_CFG5); + + _dsi_print_reset_status(); + @@ -3593,7 +3986,7 @@ index 0000000..9f31ac3 + + if (dss_get_dsi_clk_source() == 0) { + /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ -+ r = clk_get_rate(dsi.dss1_fck); ++ r = dss_clk_get_rate(DSS_CLK_FCK1); + } else { + /* DSI FCLK source is DSI2_PLL_FCLK */ + r = dsi.dsi2_pll_fclk; @@ -3619,7 +4012,7 @@ index 0000000..9f31ac3 + } + + if (n == (1 << 13) - 1) { -+ DSSERR("DSI: Failed to find LP_CLK_DIVISOR\n"); ++ DSSERR("Failed to find LP_CLK_DIVISOR\n"); + return -EINVAL; + } + @@ -3650,7 +4043,7 @@ index 0000000..9f31ac3 + while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) { + udelay(1); + if (t++ > 1000) { -+ DSSERR("DSI: Failed to set DSI PLL power mode to %d\n", ++ DSSERR("Failed to set DSI PLL power mode to %d\n", + state); + return -ENODEV; + } @@ -3682,7 +4075,7 @@ index 0000000..9f31ac3 + memset(&best, 0, sizeof(best)); + + memset(&cur, 0, sizeof(cur)); -+ cur.clkin = clk_get_rate(dsi.dss2_fck); ++ cur.clkin = dss_clk_get_rate(DSS_CLK_FCK2); + cur.use_dss2_fck = 1; + cur.highfreq = 0; + @@ -3789,7 +4182,7 @@ index 0000000..9f31ac3 + memset(&cur, 0, sizeof(cur)); + cur.use_dss2_fck = use_dss2_fck; + if (use_dss2_fck) { -+ cur.clkin = clk_get_rate(dsi.dss2_fck); ++ cur.clkin = dss_clk_get_rate(DSS_CLK_FCK2); + cur.highfreq = 0; + } else { + cur.clkin = dispc_pclk_rate(); @@ -3861,6 +4254,7 @@ index 0000000..9f31ac3 + DSSDBG("dsi_pll_program\n"); + + enable_clocks(1); ++ dsi_enable_pll_clock(1); + + dsi.dsiphy = cinfo->dsiphy; + dsi.ddr_clk = dsi.dsiphy / 4; @@ -3921,11 +4315,13 @@ index 0000000..9f31ac3 + } + + if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) { -+ DSSERR("DSI: cannot lock PLL\n"); ++ DSSERR("cannot lock PLL\n"); + r = -EIO; + goto err; + } + ++ dsi.pll_locked = 1; ++ + l = dsi_read_reg(DSI_PLL_CONFIGURATION2); + l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */ + l = FLD_MOD(l, 0, 5, 5); /* DSI_PLL_PLLLPMODE */ @@ -3946,6 +4342,7 @@ index 0000000..9f31ac3 + DSSDBG("PLL config done\n"); +err: + enable_clocks(0); ++ dsi_enable_pll_clock(0); + + return r; +} @@ -3967,14 +4364,16 @@ index 0000000..9f31ac3 + return r; + + r = dispc_set_clock_div(&cinfo); -+ if (r) ++ if (r) { ++ DSSERR("Failed to set basic clocks\n"); + return r; ++ } + + /* PLL does not come out of reset without this... */ + dispc_pck_free_enable(1); + + if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) { -+ DSSERR("DSI: PLL not coming out of reset.\n"); ++ DSSERR("PLL not coming out of reset.\n"); + r = -ENODEV; + goto err; + } @@ -3998,6 +4397,7 @@ index 0000000..9f31ac3 + goto err; + + enable_clocks(0); ++ dsi_enable_pll_clock(0); + + DSSDBG("PLL init done\n"); + @@ -4010,8 +4410,8 @@ index 0000000..9f31ac3 + +void dsi_pll_uninit(void) +{ ++ dsi.pll_locked = 0; + dsi_pll_power(DSI_PLL_POWER_OFF); -+ dsi_enable_pll_clock(0); + DSSDBG("PLL uninit done\n"); +} + @@ -4079,7 +4479,7 @@ index 0000000..9f31ac3 + while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) { + udelay(1); + if (t++ > 1000) { -+ DSSERR("DSI: failed to set complexio power state to " ++ D |
