diff options
| -rw-r--r-- | arch/arm/mach-omap2/Makefile | 5 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/display.c | 159 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/display.h | 29 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_2420_data.c | 17 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_2430_data.c | 17 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c | 5 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 37 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 24 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_common_data.c | 4 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_common_data.h | 4 | ||||
| -rw-r--r-- | arch/arm/plat-omap/include/plat/common.h | 3 | ||||
| -rw-r--r-- | include/video/omapdss.h | 7 |
12 files changed, 276 insertions, 35 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 69ab1c069134..b009f17dee56 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | # Common support | 5 | # Common support |
| 6 | obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \ | 6 | obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \ |
| 7 | common.o gpio.o dma.o wd_timer.o | 7 | common.o gpio.o dma.o wd_timer.o display.o |
| 8 | 8 | ||
| 9 | omap-2-3-common = irq.o sdrc.o | 9 | omap-2-3-common = irq.o sdrc.o |
| 10 | hwmod-common = omap_hwmod.o \ | 10 | hwmod-common = omap_hwmod.o \ |
| @@ -264,7 +264,4 @@ smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o | |||
| 264 | obj-y += $(smsc911x-m) $(smsc911x-y) | 264 | obj-y += $(smsc911x-m) $(smsc911x-y) |
| 265 | obj-$(CONFIG_ARCH_OMAP4) += hwspinlock.o | 265 | obj-$(CONFIG_ARCH_OMAP4) += hwspinlock.o |
| 266 | 266 | ||
| 267 | disp-$(CONFIG_OMAP2_DSS) := display.o | ||
| 268 | obj-y += $(disp-m) $(disp-y) | ||
| 269 | |||
| 270 | obj-y += common-board-devices.o twl-common.o | 267 | obj-y += common-board-devices.o twl-common.o |
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index adb2756e242f..dce9905d64bb 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c | |||
| @@ -27,8 +27,35 @@ | |||
| 27 | #include <plat/omap_hwmod.h> | 27 | #include <plat/omap_hwmod.h> |
| 28 | #include <plat/omap_device.h> | 28 | #include <plat/omap_device.h> |
| 29 | #include <plat/omap-pm.h> | 29 | #include <plat/omap-pm.h> |
| 30 | #include <plat/common.h> | ||
| 30 | 31 | ||
| 31 | #include "control.h" | 32 | #include "control.h" |
| 33 | #include "display.h" | ||
| 34 | |||
| 35 | #define DISPC_CONTROL 0x0040 | ||
| 36 | #define DISPC_CONTROL2 0x0238 | ||
| 37 | #define DISPC_IRQSTATUS 0x0018 | ||
| 38 | |||
| 39 | #define DSS_SYSCONFIG 0x10 | ||
| 40 | #define DSS_SYSSTATUS 0x14 | ||
| 41 | #define DSS_CONTROL 0x40 | ||
| 42 | #define DSS_SDI_CONTROL 0x44 | ||
| 43 | #define DSS_PLL_CONTROL 0x48 | ||
| 44 | |||
| 45 | #define LCD_EN_MASK (0x1 << 0) | ||
| 46 | #define DIGIT_EN_MASK (0x1 << 1) | ||
| 47 | |||
| 48 | #define FRAMEDONE_IRQ_SHIFT 0 | ||
| 49 | #define EVSYNC_EVEN_IRQ_SHIFT 2 | ||
| 50 | #define EVSYNC_ODD_IRQ_SHIFT 3 | ||
| 51 | #define FRAMEDONE2_IRQ_SHIFT 22 | ||
| 52 | #define FRAMEDONETV_IRQ_SHIFT 24 | ||
| 53 | |||
| 54 | /* | ||
| 55 | * FRAMEDONE_IRQ_TIMEOUT: how long (in milliseconds) to wait during DISPC | ||
| 56 | * reset before deciding that something has gone wrong | ||
| 57 | */ | ||
| 58 | #define FRAMEDONE_IRQ_TIMEOUT 100 | ||
| 32 | 59 | ||
| 33 | static struct platform_device omap_display_device = { | 60 | static struct platform_device omap_display_device = { |
| 34 | .name = "omapdss", | 61 | .name = "omapdss", |
| @@ -172,3 +199,135 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) | |||
| 172 | 199 | ||
| 173 | return r; | 200 | return r; |
| 174 | } | 201 | } |
| 202 | |||
| 203 | static void dispc_disable_outputs(void) | ||
| 204 | { | ||
| 205 | u32 v, irq_mask = 0; | ||
| 206 | bool lcd_en, digit_en, lcd2_en = false; | ||
| 207 | int i; | ||
| 208 | struct omap_dss_dispc_dev_attr *da; | ||
| 209 | struct omap_hwmod *oh; | ||
| 210 | |||
| 211 | oh = omap_hwmod_lookup("dss_dispc"); | ||
| 212 | if (!oh) { | ||
| 213 | WARN(1, "display: could not disable outputs during reset - could not find dss_dispc hwmod\n"); | ||
| 214 | return; | ||
| 215 | } | ||
| 216 | |||
| 217 | if (!oh->dev_attr) { | ||
| 218 | pr_err("display: could not disable outputs during reset due to missing dev_attr\n"); | ||
| 219 | return; | ||
| 220 | } | ||
| 221 | |||
| 222 | da = (struct omap_dss_dispc_dev_attr *)oh->dev_attr; | ||
| 223 | |||
| 224 | /* store value of LCDENABLE and DIGITENABLE bits */ | ||
| 225 | v = omap_hwmod_read(oh, DISPC_CONTROL); | ||
| 226 | lcd_en = v & LCD_EN_MASK; | ||
| 227 | digit_en = v & DIGIT_EN_MASK; | ||
| 228 | |||
| 229 | /* store value of LCDENABLE for LCD2 */ | ||
| 230 | if (da->manager_count > 2) { | ||
| 231 | v = omap_hwmod_read(oh, DISPC_CONTROL2); | ||
| 232 | lcd2_en = v & LCD_EN_MASK; | ||
| 233 | } | ||
| 234 | |||
| 235 | if (!(lcd_en | digit_en | lcd2_en)) | ||
| 236 | return; /* no managers currently enabled */ | ||
| 237 | |||
| 238 | /* | ||
| 239 | * If any manager was enabled, we need to disable it before | ||
| 240 | * DSS clocks are disabled or DISPC module is reset | ||
| 241 | */ | ||
| 242 | if (lcd_en) | ||
| 243 | irq_mask |= 1 << FRAMEDONE_IRQ_SHIFT; | ||
| 244 | |||
| 245 | if (digit_en) { | ||
| 246 | if (da->has_framedonetv_irq) { | ||
| 247 | irq_mask |= 1 << FRAMEDONETV_IRQ_SHIFT; | ||
| 248 | } else { | ||
| 249 | irq_mask |= 1 << EVSYNC_EVEN_IRQ_SHIFT | | ||
| 250 | 1 << EVSYNC_ODD_IRQ_SHIFT; | ||
| 251 | } | ||
| 252 | } | ||
| 253 | |||
| 254 | if (lcd2_en) | ||
| 255 | irq_mask |= 1 << FRAMEDONE2_IRQ_SHIFT; | ||
| 256 | |||
| 257 | /* | ||
| 258 | * clear any previous FRAMEDONE, FRAMEDONETV, | ||
| 259 | * EVSYNC_EVEN/ODD or FRAMEDONE2 interrupts | ||
| 260 | */ | ||
| 261 | omap_hwmod_write(irq_mask, oh, DISPC_IRQSTATUS); | ||
| 262 | |||
| 263 | /* disable LCD and TV managers */ | ||
| 264 | v = omap_hwmod_read(oh, DISPC_CONTROL); | ||
| 265 | v &= ~(LCD_EN_MASK | DIGIT_EN_MASK); | ||
| 266 | omap_hwmod_write(v, oh, DISPC_CONTROL); | ||
| 267 | |||
| 268 | /* disable LCD2 manager */ | ||
| 269 | if (da->manager_count > 2) { | ||
| 270 | v = omap_hwmod_read(oh, DISPC_CONTROL2); | ||
| 271 | v &= ~LCD_EN_MASK; | ||
| 272 | omap_hwmod_write(v, oh, DISPC_CONTROL2); | ||
| 273 | } | ||
| 274 | |||
| 275 | i = 0; | ||
| 276 | while ((omap_hwmod_read(oh, DISPC_IRQSTATUS) & irq_mask) != | ||
| 277 | irq_mask) { | ||
| 278 | i++; | ||
| 279 | if (i > FRAMEDONE_IRQ_TIMEOUT) { | ||
| 280 | pr_err("didn't get FRAMEDONE1/2 or TV interrupt\n"); | ||
| 281 | break; | ||
| 282 | } | ||
| 283 | mdelay(1); | ||
| 284 | } | ||
| 285 | } | ||
| 286 | |||
| 287 | #define MAX_MODULE_SOFTRESET_WAIT 10000 | ||
| 288 | int omap_dss_reset(struct omap_hwmod *oh) | ||
| 289 | { | ||
| 290 | struct omap_hwmod_opt_clk *oc; | ||
| 291 | int c = 0; | ||
| 292 | int i, r; | ||
| 293 | |||
| 294 | if (!(oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)) { | ||
| 295 | pr_err("dss_core: hwmod data doesn't contain reset data\n"); | ||
| 296 | return -EINVAL; | ||
| 297 | } | ||
| 298 | |||
| 299 | for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) | ||
| 300 | if (oc->_clk) | ||
| 301 | clk_enable(oc->_clk); | ||
| 302 | |||
| 303 | dispc_disable_outputs(); | ||
| 304 | |||
| 305 | /* clear SDI registers */ | ||
| 306 | if (cpu_is_omap3430()) { | ||
| 307 | omap_hwmod_write(0x0, oh, DSS_SDI_CONTROL); | ||
| 308 | omap_hwmod_write(0x0, oh, DSS_PLL_CONTROL); | ||
| 309 | } | ||
| 310 | |||
| 311 | /* | ||
| 312 | * clear DSS_CONTROL register to switch DSS clock sources to | ||
| 313 | * PRCM clock, if any | ||
| 314 | */ | ||
| 315 | omap_hwmod_write(0x0, oh, DSS_CONTROL); | ||
| 316 | |||
