Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-3.1-rc1' of git://gitorious.org/linux-omap-dss2/linux

* 'for-3.1-rc1' of git://gitorious.org/linux-omap-dss2/linux: (31 commits)
OMAP: DSS2: HDMI: fix hdmi clock name
HACK: OMAP: DSS2: clk hack for OMAP2/3
OMAP: DSS2: DSS: Fix context save/restore
OMAP: DSS2: DISPC: Fix context save/restore
OMAP: DSS2: Remove ctx loss count from dss.c
OMAP: DSS2: Remove unused code from display.c
OMAP: DSS2: DISPC: remove finegrained clk enables/disables
OMAP: DSS2: Remove unused opt_clock_available
OMAP: DSS2: Use PM runtime & HWMOD support
OMAP: DSS2: Remove CONFIG_OMAP2_DSS_SLEEP_BEFORE_RESET
OMAP: DSS2: Remove core_dump_clocks
OMAP: DSS2: DPI: remove unneeded SYSCK enable/disable
OMAP: DSS2: Use omap_pm_get_dev_context_loss_count to get ctx loss count
OMAP: DSS2: rewrite use of context_loss_count
OMAP: DSS2: Remove clk optimization at dss init
OMAP: DSS2: Fix init and unit sequence
OMAP: DSS2: Clean up probe for DSS & DSI
OMAP: DSS2: Handle dpll4_m4_ck in dss_get/put_clocks
OMAP: DSS2: Fix FIFO threshold and burst size for OMAP4
OMAP: DSS2: DSI: sync when disabling a display
...

+1689 -1405
+3 -23
arch/arm/mach-omap2/display.c
··· 25 25 #include <video/omapdss.h> 26 26 #include <plat/omap_hwmod.h> 27 27 #include <plat/omap_device.h> 28 + #include <plat/omap-pm.h> 28 29 29 30 static struct platform_device omap_display_device = { 30 31 .name = "omapdss", ··· 42 41 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, 43 42 }, 44 43 }; 45 - 46 - /* oh_core is used for getting opt-clocks */ 47 - static struct omap_hwmod *oh_core; 48 - 49 - static bool opt_clock_available(const char *clk_role) 50 - { 51 - int i; 52 - 53 - for (i = 0; i < oh_core->opt_clks_cnt; i++) { 54 - if (!strcmp(oh_core->opt_clks[i].role, clk_role)) 55 - return true; 56 - } 57 - return false; 58 - } 59 44 60 45 struct omap_dss_hwmod_data { 61 46 const char *oh_name; ··· 96 109 oh_count = ARRAY_SIZE(omap4_dss_hwmod_data); 97 110 } 98 111 99 - /* opt_clks are always associated with dss hwmod */ 100 - oh_core = omap_hwmod_lookup("dss_core"); 101 - if (!oh_core) { 102 - pr_err("Could not look up dss_core.\n"); 103 - return -ENODEV; 104 - } 105 - 106 112 pdata.board_data = board_data; 107 - pdata.board_data->get_last_off_on_transaction_id = NULL; 108 - pdata.opt_clock_available = opt_clock_available; 113 + pdata.board_data->get_context_loss_count = 114 + omap_pm_get_dev_context_loss_count; 109 115 110 116 for (i = 0; i < oh_count; i++) { 111 117 oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name);
+22 -33
drivers/video/omap2/displays/panel-taal.c
··· 504 504 return 0; 505 505 506 506 r = omapdss_dsi_display_enable(dssdev); 507 - if (r) 508 - goto err; 507 + if (r) { 508 + dev_err(&dssdev->dev, "failed to enable DSI\n"); 509 + goto err1; 510 + } 509 511 510 512 omapdss_dsi_vc_enable_hs(dssdev, td->channel, true); 511 513 512 514 r = _taal_enable_te(dssdev, true); 513 - if (r) 514 - goto err; 515 + if (r) { 516 + dev_err(&dssdev->dev, "failed to re-enable TE"); 517 + goto err2; 518 + } 515 519 516 520 enable_irq(gpio_to_irq(panel_data->ext_te_gpio)); 517 521 ··· 525 521 526 522 return 0; 527 523 528 - err: 529 - dev_err(&dssdev->dev, "exit ULPS failed"); 524 + err2: 525 + dev_err(&dssdev->dev, "failed to exit ULPS"); 526 + 530 527 r = taal_panel_reset(dssdev); 531 - 532 - enable_irq(gpio_to_irq(panel_data->ext_te_gpio)); 533 - td->ulps_enabled = false; 534 - 528 + if (!r) { 529 + enable_irq(gpio_to_irq(panel_data->ext_te_gpio)); 530 + td->ulps_enabled = false; 531 + } 532 + err1: 535 533 taal_queue_ulps_work(dssdev); 536 534 537 535 return r; ··· 1247 1241 int r; 1248 1242 1249 1243 r = taal_dcs_write_0(td, DCS_DISPLAY_OFF); 1250 - if (!r) { 1244 + if (!r) 1251 1245 r = taal_sleep_in(td); 1252 - /* HACK: wait a bit so that the message goes through */ 1253 - msleep(10); 1254 - } 1255 1246 1256 1247 if (r) { 1257 1248 dev_err(&dssdev->dev, ··· 1320 1317 dsi_bus_lock(dssdev); 1321 1318 1322 1319 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 1323 - taal_wake_up(dssdev); 1324 - taal_power_off(dssdev); 1320 + int r; 1321 + 1322 + r = taal_wake_up(dssdev); 1323 + if (!r) 1324 + taal_power_off(dssdev); 1325 1325 } 1326 1326 1327 1327 dsi_bus_unlock(dssdev); ··· 1903 1897 mutex_unlock(&td->lock); 1904 1898 } 1905 1899 1906 - static int taal_set_update_mode(struct omap_dss_device *dssdev, 1907 - enum omap_dss_update_mode mode) 1908 - { 1909 - if (mode != OMAP_DSS_UPDATE_MANUAL) 1910 - return -EINVAL; 1911 - return 0; 1912 - } 1913 - 1914 - static enum omap_dss_update_mode taal_get_update_mode( 1915 - struct omap_dss_device *dssdev) 1916 - { 1917 - return OMAP_DSS_UPDATE_MANUAL; 1918 - } 1919 - 1920 1900 static struct omap_dss_driver taal_driver = { 1921 1901 .probe = taal_probe, 1922 1902 .remove = __exit_p(taal_remove), ··· 1911 1919 .disable = taal_disable, 1912 1920 .suspend = taal_suspend, 1913 1921 .resume = taal_resume, 1914 - 1915 - .set_update_mode = taal_set_update_mode, 1916 - .get_update_mode = taal_get_update_mode, 1917 1922 1918 1923 .update = taal_update, 1919 1924 .sync = taal_sync,
-12
drivers/video/omap2/dss/Kconfig
··· 117 117 Max FCK is 173MHz, so this doesn't work if your PCK 118 118 is very high. 119 119 120 - config OMAP2_DSS_SLEEP_BEFORE_RESET 121 - bool "Sleep 50ms before DSS reset" 122 - default y 123 - help 124 - For some unknown reason we may get SYNC_LOST errors from the display 125 - subsystem at initialization time if we don't sleep before resetting 126 - the DSS. See the source (dss.c) for more comments. 127 - 128 - However, 50ms is quite long time to sleep, and with some 129 - configurations the SYNC_LOST may never happen, so the sleep can 130 - be disabled here. 131 - 132 120 config OMAP2_DSS_SLEEP_AFTER_VENC_RESET 133 121 bool "Sleep 20ms after VENC reset" 134 122 default y
+9 -14
drivers/video/omap2/dss/core.c
··· 183 183 goto err_dss; 184 184 } 185 185 186 - /* keep clocks enabled to prevent context saves/restores during init */ 187 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 186 + r = dispc_init_platform_driver(); 187 + if (r) { 188 + DSSERR("Failed to initialize dispc platform driver\n"); 189 + goto err_dispc; 190 + } 188 191 189 192 r = rfbi_init_platform_driver(); 190 193 if (r) { 191 194 DSSERR("Failed to initialize rfbi platform driver\n"); 192 195 goto err_rfbi; 193 - } 194 - 195 - r = dispc_init_platform_driver(); 196 - if (r) { 197 - DSSERR("Failed to initialize dispc platform driver\n"); 198 - goto err_dispc; 199 196 } 200 197 201 198 r = venc_init_platform_driver(); ··· 235 238 pdata->default_device = dssdev; 236 239 } 237 240 238 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 239 - 240 241 return 0; 241 242 242 243 err_register: ··· 263 268 264 269 dss_uninitialize_debugfs(); 265 270 266 - venc_uninit_platform_driver(); 267 - dispc_uninit_platform_driver(); 268 - rfbi_uninit_platform_driver(); 269 - dsi_uninit_platform_driver(); 270 271 hdmi_uninit_platform_driver(); 272 + dsi_uninit_platform_driver(); 273 + venc_uninit_platform_driver(); 274 + rfbi_uninit_platform_driver(); 275 + dispc_uninit_platform_driver(); 271 276 dss_uninit_platform_driver(); 272 277 273 278 dss_uninit_overlays(pdev);
+322 -240
drivers/video/omap2/dss/dispc.c
··· 33 33 #include <linux/workqueue.h> 34 34 #include <linux/hardirq.h> 35 35 #include <linux/interrupt.h> 36 + #include <linux/platform_device.h> 37 + #include <linux/pm_runtime.h> 36 38 37 39 #include <plat/sram.h> 38 40 #include <plat/clock.h> ··· 79 77 s8 vc00; 80 78 }; 81 79 80 + enum omap_burst_size { 81 + BURST_SIZE_X2 = 0, 82 + BURST_SIZE_X4 = 1, 83 + BURST_SIZE_X8 = 2, 84 + }; 85 + 82 86 #define REG_GET(idx, start, end) \ 83 87 FLD_GET(dispc_read_reg(idx), start, end) 84 88 ··· 100 92 static struct { 101 93 struct platform_device *pdev; 102 94 void __iomem *base; 95 + 96 + int ctx_loss_cnt; 97 + 103 98 int irq; 99 + struct clk *dss_clk; 104 100 105 101 u32 fifo_size[3]; 106 102 ··· 114 102 u32 error_irqs; 115 103 struct work_struct error_work; 116 104 105 + bool ctx_valid; 117 106 u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; 118 107 119 108 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS ··· 147 134 return __raw_readl(dispc.base + idx); 148 135 } 149 136 137 + static int dispc_get_ctx_loss_count(void) 138 + { 139 + struct device *dev = &dispc.pdev->dev; 140 + struct omap_display_platform_data *pdata = dev->platform_data; 141 + struct omap_dss_board_info *board_data = pdata->board_data; 142 + int cnt; 143 + 144 + if (!board_data->get_context_loss_count) 145 + return -ENOENT; 146 + 147 + cnt = board_data->get_context_loss_count(dev); 148 + 149 + WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt); 150 + 151 + return cnt; 152 + } 153 + 150 154 #define SR(reg) \ 151 155 dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg) 152 156 #define RR(reg) \ 153 157 dispc_write_reg(DISPC_##reg, dispc.ctx[DISPC_##reg / sizeof(u32)]) 154 158 155 - void dispc_save_context(void) 159 + static void dispc_save_context(void) 156 160 { 157 161 int i; 158 - if (cpu_is_omap24xx()) 159 - return; 160 162 161 - SR(SYSCONFIG); 163 + DSSDBG("dispc_save_context\n"); 164 + 162 165 SR(IRQENABLE); 163 166 SR(CONTROL); 164 167 SR(CONFIG); ··· 187 158 SR(TIMING_V(OMAP_DSS_CHANNEL_LCD)); 188 159 SR(POL_FREQ(OMAP_DSS_CHANNEL_LCD)); 189 160 SR(DIVISORo(OMAP_DSS_CHANNEL_LCD)); 190 - SR(GLOBAL_ALPHA); 161 + if (dss_has_feature(FEAT_GLOBAL_ALPHA)) 162 + SR(GLOBAL_ALPHA); 191 163 SR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT)); 192 164 SR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD)); 193 165 if (dss_has_feature(FEAT_MGR_LCD2)) { ··· 218 188 SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD)); 219 189 SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD)); 220 190 221 - SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD)); 222 - SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD)); 223 - SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD)); 191 + if (dss_has_feature(FEAT_CPR)) { 192 + SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD)); 193 + SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD)); 194 + SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD)); 195 + } 224 196 if (dss_has_feature(FEAT_MGR_LCD2)) { 225 - SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2)); 226 - SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2)); 227 - SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2)); 197 + if (dss_has_feature(FEAT_CPR)) { 198 + SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2)); 199 + SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2)); 200 + SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2)); 201 + } 228 202 229 203 SR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2)); 230 204 SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2)); 231 205 SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2)); 232 206 } 233 207 234 - SR(OVL_PRELOAD(OMAP_DSS_GFX)); 208 + if (dss_has_feature(FEAT_PRELOAD)) 209 + SR(OVL_PRELOAD(OMAP_DSS_GFX)); 235 210 236 211 /* VID1 */ 237 212 SR(OVL_BA0(OMAP_DSS_VIDEO1)); ··· 261 226 for (i = 0; i < 5; i++) 262 227 SR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i)); 263 228 264 - for (i = 0; i < 8; i++) 265 - SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i)); 229 + if (dss_has_feature(FEAT_FIR_COEF_V)) { 230 + for (i = 0; i < 8; i++) 231 + SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i)); 232 + } 266 233 267 234 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 268 235 SR(OVL_BA0_UV(OMAP_DSS_VIDEO1)); ··· 285 248 if (dss_has_feature(FEAT_ATTR2)) 286 249 SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1)); 287 250 288 - SR(OVL_PRELOAD(OMAP_DSS_VIDEO1)); 251 + if (dss_has_feature(FEAT_PRELOAD)) 252 + SR(OVL_PRELOAD(OMAP_DSS_VIDEO1)); 289 253 290 254 /* VID2 */ 291 255 SR(OVL_BA0(OMAP_DSS_VIDEO2)); ··· 311 273 for (i = 0; i < 5; i++) 312 274 SR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i)); 313 275 314 - for (i = 0; i < 8; i++) 315 - SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i)); 276 + if (dss_has_feature(FEAT_FIR_COEF_V)) { 277 + for (i = 0; i < 8; i++) 278 + SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i)); 279 + } 316 280 317 281 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 318 282 SR(OVL_BA0_UV(OMAP_DSS_VIDEO2)); ··· 335 295 if (dss_has_feature(FEAT_ATTR2)) 336 296 SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2)); 337 297 338 - SR(OVL_PRELOAD(OMAP_DSS_VIDEO2)); 298 + if (dss_has_feature(FEAT_PRELOAD)) 299 + SR(OVL_PRELOAD(OMAP_DSS_VIDEO2)); 339 300 340 301 if (dss_has_feature(FEAT_CORE_CLK_DIV)) 341 302 SR(DIVISOR); 303 + 304 + dispc.ctx_loss_cnt = dispc_get_ctx_loss_count(); 305 + dispc.ctx_valid = true; 306 + 307 + DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt); 342 308 } 343 309 344 - void dispc_restore_context(void) 310 + static void dispc_restore_context(void) 345 311 { 346 - int i; 347 - RR(SYSCONFIG); 312 + int i, ctx; 313 + 314 + DSSDBG("dispc_restore_context\n"); 315 + 316 + if (!dispc.ctx_valid) 317 + return; 318 + 319 + ctx = dispc_get_ctx_loss_count(); 320 + 321 + if (ctx >= 0 && ctx == dispc.ctx_loss_cnt) 322 + return; 323 + 324 + DSSDBG("ctx_loss_count: saved %d, current %d\n", 325 + dispc.ctx_loss_cnt, ctx); 326 + 348 327 /*RR(IRQENABLE);*/ 349 328 /*RR(CONTROL);*/ 350 329 RR(CONFIG); ··· 376 317 RR(TIMING_V(OMAP_DSS_CHANNEL_LCD)); 377 318 RR(POL_FREQ(OMAP_DSS_CHANNEL_LCD)); 378 319 RR(DIVISORo(OMAP_DSS_CHANNEL_LCD)); 379 - RR(GLOBAL_ALPHA); 320 + if (dss_has_feature(FEAT_GLOBAL_ALPHA)) 321 + RR(GLOBAL_ALPHA); 380 322 RR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT)); 381 323 RR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD)); 382 324 if (dss_has_feature(FEAT_MGR_LCD2)) { ··· 407 347 RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD)); 408 348 RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD)); 409 349 410 - RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD)); 411 - RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD)); 412 - RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD)); 350 + if (dss_has_feature(FEAT_CPR)) { 351 + RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD)); 352 + RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD)); 353 + RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD)); 354 + } 413 355 if (dss_has_feature(FEAT_MGR_LCD2)) { 414 356 RR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2)); 415 357 RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2)); 416 358 RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2)); 417 359 418 - RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2)); 419 - RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2)); 420 - RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2)); 360 + if (dss_has_feature(FEAT_CPR)) { 361 + RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2)); 362 + RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2)); 363 + RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2)); 364 + } 421 365 } 422 366 423 - RR(OVL_PRELOAD(OMAP_DSS_GFX)); 367 + if (dss_has_feature(FEAT_PRELOAD)) 368 + RR(OVL_PRELOAD(OMAP_DSS_GFX)); 424 369 425 370 /* VID1 */ 426 371 RR(OVL_BA0(OMAP_DSS_VIDEO1)); ··· 450 385 for (i = 0; i < 5; i++) 451 386 RR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i)); 452 387 453 - for (i = 0; i < 8; i++) 454 - RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i)); 388 + if (dss_has_feature(FEAT_FIR_COEF_V)) { 389 + for (i = 0; i < 8; i++) 390 + RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i)); 391 + } 455 392 456 393 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 457 394 RR(OVL_BA0_UV(OMAP_DSS_VIDEO1)); ··· 474 407 if (dss_has_feature(FEAT_ATTR2)) 475 408 RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1)); 476 409 477 - RR(OVL_PRELOAD(OMAP_DSS_VIDEO1)); 410 + if (dss_has_feature(FEAT_PRELOAD)) 411 + RR(OVL_PRELOAD(OMAP_DSS_VIDEO1)); 478 412 479 413 /* VID2 */ 480 414 RR(OVL_BA0(OMAP_DSS_VIDEO2)); ··· 500 432 for (i = 0; i < 5; i++) 501 433 RR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i)); 502 434 503 - for (i = 0; i < 8; i++) 504 - RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i)); 435 + if (dss_has_feature(FEAT_FIR_COEF_V)) { 436 + for (i = 0; i < 8; i++) 437 + RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i)); 438 + } 505 439 506 440 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 507 441 RR(OVL_BA0_UV(OMAP_DSS_VIDEO2)); ··· 524 454 if (dss_has_feature(FEAT_ATTR2)) 525 455 RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2)); 526 456 527 - RR(OVL_PRELOAD(OMAP_DSS_VIDEO2)); 457 + if (dss_has_feature(FEAT_PRELOAD)) 458 + RR(OVL_PRELOAD(OMAP_DSS_VIDEO2)); 528 459 529 460 if (dss_has_feature(FEAT_CORE_CLK_DIV)) 530 461 RR(DIVISOR); ··· 542 471 * the context is fully restored 543 472 */ 544 473 RR(IRQENABLE); 474 + 475 + DSSDBG("context restored\n"); 545 476 } 546 477 547 478 #undef SR 548 479 #undef RR 549 480 550 - static inline void enable_clocks(bool enable) 481 + int dispc_runtime_get(void) 551 482 { 552 - if (enable) 553 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 554 - else 555 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 483 + int r; 484 + 485 + DSSDBG("dispc_runtime_get\n"); 486 + 487 + r = pm_runtime_get_sync(&dispc.pdev->dev); 488 + WARN_ON(r < 0); 489 + return r < 0 ? r : 0; 556 490 } 491 + 492 + void dispc_runtime_put(void) 493 + { 494 + int r; 495 + 496 + DSSDBG("dispc_runtime_put\n"); 497 + 498 + r = pm_runtime_put(&dispc.pdev->dev); 499 + WARN_ON(r < 0); 500 + } 501 + 557 502 558 503 bool dispc_go_busy(enum omap_channel channel) 559 504 { ··· 592 505 int bit; 593 506 bool enable_bit, go_bit; 594 507 595 - enable_clocks(1); 596 - 597 508 if (channel == OMAP_DSS_CHANNEL_LCD || 598 509 channel == OMAP_DSS_CHANNEL_LCD2) 599 510 bit = 0; /* LCDENABLE */ ··· 605 520 enable_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1; 606 521 607 522 if (!enable_bit) 608 - goto end; 523 + return; 609 524 610 525 if (channel == OMAP_DSS_CHANNEL_LCD || 611 526 channel == OMAP_DSS_CHANNEL_LCD2) ··· 620 535 621 536 if (go_bit) { 622 537 DSSERR("GO bit not down for channel %d\n", channel); 623 - goto end; 538 + return; 624 539 } 625 540 626 541 DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" : ··· 630 545 REG_FLD_MOD(DISPC_CONTROL2, 1, bit, bit); 631 546 else 632 547 REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit); 633 - end: 634 - enable_clocks(0); 635 548 } 636 549 637 550 static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value) ··· 1003 920 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1); 1004 921 } 1005 922 1006 - static void _dispc_set_channel_out(enum omap_plane plane, 923 + void dispc_set_channel_out(enum omap_plane plane, 1007 924 enum omap_channel channel) 1008 925 { 1009 926 int shift; ··· 1050 967 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); 1051 968 } 1052 969 1053 - void dispc_set_burst_size(enum omap_plane plane, 970 + static void dispc_set_burst_size(enum omap_plane plane, 1054 971 enum omap_burst_size burst_size) 1055 972 { 1056 973 int shift; 1057 - u32 val; 1058 - 1059 - enable_clocks(1); 1060 974 1061 975 switch (plane) { 1062 976 case OMAP_DSS_GFX: ··· 1068 988 return; 1069 989 } 1070 990 1071 - val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); 1072 - val = FLD_MOD(val, burst_size, shift+1, shift); 1073 - dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); 991 + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), burst_size, shift + 1, shift); 992 + } 1074 993 1075 - enable_clocks(0); 994 + static void dispc_configure_burst_sizes(void) 995 + { 996 + int i; 997 + const int burst_size = BURST_SIZE_X8; 998 + 999 + /* Configure burst size always to maximum size */ 1000 + for (i = 0; i < omap_dss_get_num_overlays(); ++i) 1001 + dispc_set_burst_size(i, burst_size); 1002 + } 1003 + 1004 + u32 dispc_get_burst_size(enum omap_plane plane) 1005 + { 1006 + unsigned unit = dss_feat_get_burst_size_unit(); 1007 + /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ 1008 + return unit * 8; 1076 1009 } 1077 1010 1078 1011 void dispc_enable_gamma_table(bool enable) ··· 1100 1007 } 1101 1008 1102 1009 REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9); 1010 + } 1011 + 1012 + void dispc_enable_cpr(enum omap_channel channel, bool enable) 1013 + { 1014 + u16 reg; 1015 + 1016 + if (channel == OMAP_DSS_CHANNEL_LCD) 1017 + reg = DISPC_CONFIG; 1018 + else if (channel == OMAP_DSS_CHANNEL_LCD2) 1019 + reg = DISPC_CONFIG2; 1020 + else 1021 + return; 1022 + 1023 + REG_FLD_MOD(reg, enable, 15, 15); 1024 + } 1025 + 1026 + void dispc_set_cpr_coef(enum omap_channel channel, 1027 + struct omap_dss_cpr_coefs *coefs) 1028 + { 1029 + u32 coef_r, coef_g, coef_b; 1030 + 1031 + if (channel != OMAP_DSS_CHANNEL_LCD && channel != OMAP_DSS_CHANNEL_LCD2) 1032 + return; 1033 + 1034 + coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) | 1035 + FLD_VAL(coefs->rb, 9, 0); 1036 + coef_g = FLD_VAL(coefs->gr, 31, 22) | FLD_VAL(coefs->gg, 20, 11) | 1037 + FLD_VAL(coefs->gb, 9, 0); 1038 + coef_b = FLD_VAL(coefs->br, 31, 22) | FLD_VAL(coefs->bg, 20, 11) | 1039 + FLD_VAL(coefs->bb, 9, 0); 1040 + 1041 + dispc_write_reg(DISPC_CPR_COEF_R(channel), coef_r); 1042 + dispc_write_reg(DISPC_CPR_COEF_G(channel), coef_g); 1043 + dispc_write_reg(DISPC_CPR_COEF_B(channel), coef_b); 1103 1044 } 1104 1045 1105 1046 static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) ··· 1156 1029 else 1157 1030 bit = 10; 1158 1031 1159 - enable_clocks(1); 1160 1032 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit); 1161 - enable_clocks(0); 1162 1033 } 1163 1034 1164 1035 void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height) ··· 1164 1039 u32 val; 1165 1040 BUG_ON((width > (1 << 11)) || (height > (1 << 11))); 1166 1041 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 1167 - enable_clocks(1); 1168 1042 dispc_write_reg(DISPC_SIZE_MGR(channel), val); 1169 - enable_clocks(0); 1170 1043 } 1171 1044 1172 1045 void dispc_set_digit_size(u16 width, u16 height) ··· 1172 1049 u32 val; 1173 1050 BUG_ON((width > (1 << 11)) || (height > (1 << 11))); 1174 1051 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 1175 - enable_clocks(1); 1176 1052 dispc_write_reg(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT), val); 1177 - enable_clocks(0); 1178 1053 } 1179 1054 1180 1055 static void dispc_read_plane_fifo_sizes(void) ··· 1180 1059 u32 size; 1181 1060 int plane; 1182 1061 u8 start, end; 1062 + u32 unit; 1183 1063 1184 - enable_clocks(1); 1064 + unit = dss_feat_get_buffer_size_unit(); 1185 1065 1186 1066 dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end); 1187 1067 1188 1068 for (plane = 0; plane < ARRAY_SIZE(dispc.fifo_size); ++plane) { 1189 - size = FLD_GET(dispc_read_reg(DISPC_OVL_FIFO_SIZE_STATUS(plane)), 1190 - start, end); 1069 + size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(plane), start, end); 1070 + size *= unit; 1191 1071 dispc.fifo_size[plane] = size; 1192 1072 } 1193 - 1194 - enable_clocks(0); 1195 1073 } 1196 1074 1197 1075 u32 dispc_get_plane_fifo_size(enum omap_plane plane) ··· 1198 1078 return dispc.fifo_size[plane]; 1199 1079 } 1200 1080 1201 - void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high) 1081 + void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) 1202 1082 { 1203 1083 u8 hi_start, hi_end, lo_start, lo_end; 1084 + u32 unit; 1085 + 1086 + unit = dss_feat_get_buffer_size_unit(); 1087 + 1088 + WARN_ON(low % unit != 0); 1089 + WARN_ON(high % unit != 0); 1090 + 1091 + low /= unit; 1092 + high /= unit; 1204 1093 1205 1094 dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end); 1206 1095 dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end); 1207 - 1208 - enable_clocks(1); 1209 1096 1210 1097 DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n", 1211 1098 plane, ··· 1225 1098 dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane), 1226 1099 FLD_VAL(high, hi_start, hi_end) | 1227 1100 FLD_VAL(low, lo_start, lo_end)); 1228 - 1229 - enable_clocks(0); 1230 1101 } 1231 1102 1232 1103 void dispc_enable_fifomerge(bool enable) 1233 1104 { 1234 - enable_clocks(1); 1235 - 1236 1105 DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); 1237 1106 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); 1238 - 1239 - enable_clocks(0); 1240 1107 } 1241 1108 1242 1109 static void _dispc_set_fir(enum omap_plane plane, ··· 1850 1729 return dispc_pclk_rate(channel) * vf * hf; 1851 1730 } 1852 1731 1853 - void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out) 1854 - { 1855 - enable_clocks(1); 1856 - _dispc_set_channel_out(plane, channel_out); 1857 - enable_clocks(0); 1858 - } 1859 - 1860 - static int _dispc_setup_plane(enum omap_plane plane, 1732 + int dispc_setup_plane(enum omap_plane plane, 1861 1733 u32 paddr, u16 screen_width, 1862 1734 u16 pos_x, u16 pos_y, 1863 1735 u16 width, u16 height, ··· 1858 1744 enum omap_color_mode color_mode, 1859 1745 bool ilace, 1860 1746 enum omap_dss_rotation_type rotation_type, 1861 - u8 rotation, int mirror, 1747 + u8 rotation, bool mirror, 1862 1748 u8 global_alpha, u8 pre_mult_alpha, 1863 1749 enum omap_channel channel, u32 puv_addr) 1864 1750 { ··· 1871 1757 s32 pix_inc; 1872 1758 u16 frame_height = height; 1873 1759 unsigned int field_offset = 0; 1760 + 1761 + DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> " 1762 + "%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n", 1763 + plane, paddr, screen_width, pos_x, pos_y, 1764 + width, height, 1765 + out_width, out_height, 1766 + ilace, color_mode, 1767 + rotation, mirror, channel); 1874 1768 1875 1769 if (paddr == 0) 1876 1770 return -EINVAL; ··· 2025 1903 return 0; 2026 1904 } 2027 1905 2028 - static void _dispc_enable_plane(enum omap_plane plane, bool enable) 1906 + int dispc_enable_plane(enum omap_plane plane, bool enable) 2029 1907 { 1908 + DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); 1909 + 2030 1910 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0); 1911 + 1912 + return 0; 2031 1913 } 2032 1914 2033 1915 static void dispc_disable_isr(void *data, u32 mask) ··· 2054 1928 bool is_on; 2055 1929 int r; 2056 1930 u32 irq; 2057 - 2058 - enable_clocks(1); 2059 1931 2060 1932 /* When we disable LCD output, we need to wait until frame is done. 2061 1933 * Otherwise the DSS is still working, and turning off the clocks ··· 2088 1964 if (r) 2089 1965 DSSERR("failed to unregister FRAMEDONE isr\n"); 2090 1966 } 2091 - 2092 - enable_clocks(0); 2093 1967 } 2094 1968 2095 1969 static void _enable_digit_out(bool enable) ··· 2100 1978 struct completion frame_done_completion; 2101 1979 int r; 2102 1980 2103 - enable_clocks(1); 2104 - 2105 - if (REG_GET(DISPC_CONTROL, 1, 1) == enable) { 2106 - enable_clocks(0); 1981 + if (REG_GET(DISPC_CONTROL, 1, 1) == enable) 2107 1982 return; 2108 - } 2109 1983 2110 1984 if (enable) { 2111 1985 unsigned long flags; ··· 2153 2035 _omap_dispc_set_irqs(); 2154 2036 spin_unlock_irqrestore(&dispc.irq_lock, flags); 2155 2037 } 2156 - 2157 - enable_clocks(0); 2158 2038 } 2159 2039 2160 2040 bool dispc_is_channel_enabled(enum omap_channel channel) ··· 2183 2067 if (!dss_has_feature(FEAT_LCDENABLEPOL)) 2184 2068 return; 2185 2069 2186 - enable_clocks(1); 2187 2070 REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29); 2188 - enable_clocks(0); 2189 2071 } 2190 2072 2191 2073 void dispc_lcd_enable_signal(bool enable) ··· 2191 2077 if (!dss_has_feature(FEAT_LCDENABLESIGNAL)) 2192 2078 return; 2193 2079 2194 - enable_clocks(1); 2195 2080 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28); 2196 - enable_clocks(0); 2197 2081 } 2198 2082 2199 2083 void dispc_pck_free_enable(bool enable) ··· 2199 2087 if (!dss_has_feature(FEAT_PCKFREEENABLE)) 2200 2088 return; 2201 2089 2202 - enable_clocks(1); 2203 2090 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27); 2204 - enable_clocks(0); 2205 2091 } 2206 2092 2207 2093 void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable) 2208 2094 { 2209 - enable_clocks(1); 2210 2095 if (channel == OMAP_DSS_CHANNEL_LCD2) 2211 2096 REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16); 2212 2097 else 2213 2098 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16); 2214 - enable_clocks(0); 2215 2099 } 2216 2100 2217 2101 ··· 2230 2122 return; 2231 2123 } 2232 2124 2233 - enable_clocks(1); 2234 2125 if (channel == OMAP_DSS_CHANNEL_LCD2) 2235 2126 REG_FLD_MOD(DISPC_CONTROL2, mode, 3, 3); 2236 2127 else 2237 2128 REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3); 2238 - enable_clocks(0); 2239 2129 } 2240 2130 2241 2131 void dispc_set_loadmode(enum omap_dss_load_mode mode) 2242 2132 { 2243 - enable_clocks(1); 2244 2133 REG_FLD_MOD(DISPC_CONFIG, mode, 2, 1); 2245 - enable_clocks(0); 2246 2134 } 2247 2135 2248 2136 2249 2137 void dispc_set_default_color(enum omap_channel channel, u32 color) 2250 2138 { 2251 - enable_clocks(1); 2252 2139 dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color); 2253 - enable_clocks(0); 2254 2140 } 2255 2141 2256 2142 u32 dispc_get_default_color(enum omap_channel channel) ··· 2255 2153 channel != OMAP_DSS_CHANNEL_LCD && 2256 2154 channel != OMAP_DSS_CHANNEL_LCD2); 2257 2155 2258 - enable_clocks(1); 2259 2156 l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel)); 2260 - enable_clocks(0); 2261 2157 2262 2158 return l; 2263 2159 } ··· 2264 2164 enum omap_dss_trans_key_type type, 2265 2165 u32 trans_key) 2266 2166 { 2267 - enable_clocks(1); 2268 2167 if (ch == OMAP_DSS_CHANNEL_LCD) 2269 2168 REG_FLD_MOD(DISPC_CONFIG, type, 11, 11); 2270 2169 else if (ch == OMAP_DSS_CHANNEL_DIGIT) ··· 2272 2173 REG_FLD_MOD(DISPC_CONFIG2, type, 11, 11); 2273 2174 2274 2175 dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key); 2275 - enable_clocks(0); 2276 2176 } 2277 2177 2278 2178 void dispc_get_trans_key(enum omap_channel ch, 2279 2179 enum omap_dss_trans_key_type *type, 2280 2180 u32 *trans_key) 2281 2181 { 2282 - enable_clocks(1); 2283 2182 if (type) { 2284 2183 if (ch == OMAP_DSS_CHANNEL_LCD) 2285 2184 *type = REG_GET(DISPC_CONFIG, 11, 11); ··· 2291 2194 2292 2195 if (trans_key) 2293 2196 *trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch)); 2294 - enable_clocks(0); 2295 2197 } 2296 2198 2297 2199 void dispc_enable_trans_key(enum omap_channel ch, bool enable) 2298 2200 { 2299 - enable_clocks(1); 2300 2201 if (ch == OMAP_DSS_CHANNEL_LCD) 2301 2202 REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10); 2302 2203 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2303 2204 REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12); 2304 2205 else /* OMAP_DSS_CHANNEL_LCD2 */ 2305 2206 REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10); 2306 - enable_clocks(0); 2307 2207 } 2308 2208 void dispc_enable_alpha_blending(enum omap_channel ch, bool enable) 2309 2209 { 2310 2210 if (!dss_has_feature(FEAT_GLOBAL_ALPHA)) 2311 2211 return; 2312 2212 2313 - enable_clocks(1); 2314 2213 if (ch == OMAP_DSS_CHANNEL_LCD) 2315 2214 REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18); 2316 2215 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2317 2216 REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); 2318 2217 else /* OMAP_DSS_CHANNEL_LCD2 */ 2319 2218 REG_FLD_MOD(DISPC_CONFIG2, enable, 18, 18); 2320 - enable_clocks(0); 2321 2219 } 2322 2220 bool dispc_alpha_blending_enabled(enum omap_channel ch) 2323 2221 { ··· 2321 2229 if (!dss_has_feature(FEAT_GLOBAL_ALPHA)) 2322 2230 return false; 2323 2231 2324 - enable_clocks(1); 2325 2232 if (ch == OMAP_DSS_CHANNEL_LCD) 2326 2233 enabled = REG_GET(DISPC_CONFIG, 18, 18); 2327 2234 else if (ch == OMAP_DSS_CHANNEL_DIGIT) ··· 2329 2238 enabled = REG_GET(DISPC_CONFIG2, 18, 18); 2330 2239 else 2331 2240 BUG(); 2332 - enable_clocks(0); 2333 2241 2334 2242 return enabled; 2335 2243 } ··· 2338 2248 { 2339 2249 bool enabled; 2340 2250 2341 - enable_clocks(1); 2342 2251 if (ch == OMAP_DSS_CHANNEL_LCD) 2343 2252 enabled = REG_GET(DISPC_CONFIG, 10, 10); 2344 2253 else if (ch == OMAP_DSS_CHANNEL_DIGIT) ··· 2346 2257 enabled = REG_GET(DISPC_CONFIG2, 10, 10); 2347 2258 else 2348 2259 BUG(); 2349 - enable_clocks(0); 2350 2260 2351 2261 return enabled; 2352 2262 } ··· 2373 2285 return; 2374 2286 } 2375 2287 2376 - enable_clocks(1); 2377 2288 if (channel == OMAP_DSS_CHANNEL_LCD2) 2378 2289 REG_FLD_MOD(DISPC_CONTROL2, code, 9, 8); 2379 2290 else 2380 2291 REG_FLD_MOD(DISPC_CONTROL, code, 9, 8); 2381 - enable_clocks(0); 2382 2292 } 2383 2293 2384 2294 void dispc_set_parallel_interface_mode(enum omap_channel channel, ··· 2408 2322 return; 2409 2323 } 2410 2324 2411 - enable_clocks(1); 2412 - 2413 2325 if (channel == OMAP_DSS_CHANNEL_LCD2) { 2414 2326 l = dispc_read_reg(DISPC_CONTROL2); 2415 2327 l = FLD_MOD(l, stallmode, 11, 11); ··· 2419 2335 l = FLD_MOD(l, gpout1, 16, 16); 2420 2336 dispc_write_reg(DISPC_CONTROL, l); 2421 2337 } 2422 - 2423 - enable_clocks(0); 2424 2338 } 2425 2339 2426 2340 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, ··· 2471 2389 FLD_VAL(vbp, 31, 20); 2472 2390 } 2473 2391 2474 - enable_clocks(1); 2475 2392 dispc_write_reg(DISPC_TIMING_H(channel), timing_h); 2476 2393 dispc_write_reg(DISPC_TIMING_V(channel), timing_v); 2477 - enable_clocks(0); 2478 2394 } 2479 2395 2480 2396 /* change name to mode? */ ··· 2515 2435 BUG_ON(lck_div < 1); 2516 2436 BUG_ON(pck_div < 2); 2517 2437 2518 - enable_clocks(1); 2519 2438 dispc_write_reg(DISPC_DIVISORo(channel), 2520 2439 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); 2521 - enable_clocks(0); 2522 2440 } 2523 2441 2524 2442 static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div, ··· 2535 2457 2536 2458 switch (dss_get_dispc_clk_source()) { 2537 2459 case OMAP_DSS_CLK_SRC_FCK: 2538 - r = dss_clk_get_rate(DSS_CLK_FCK); 2460 + r = clk_get_rate(dispc.dss_clk); 2539 2461 break; 2540 2462 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 2541 2463 dsidev = dsi_get_dsidev_from_id(0); ··· 2565 2487 2566 2488 switch (dss_get_lcd_clk_source(channel)) { 2567 2489 case OMAP_DSS_CLK_SRC_FCK: 2568 - r = dss_clk_get_rate(DSS_CLK_FCK); 2490 + r = clk_get_rate(dispc.dss_clk); 2569 2491 break; 2570 2492 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 2571 2493 dsidev = dsi_get_dsidev_from_id(0); ··· 2604 2526 enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); 2605 2527 enum omap_dss_clk_source lcd_clk_src; 2606 2528 2607 - enable_clocks(1); 2529 + if (dispc_runtime_get()) 2530 + return; 2608 2531 2609 2532 seq_printf(s, "- DISPC -\n"); 2610 2533 ··· 2653 2574 seq_printf(s, "pck\t\t%-16lupck div\t%u\n", 2654 2575 dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd); 2655 2576 } 2656 - enable_clocks(0); 2577 + 2578 + dispc_runtime_put(); 2657 2579 } 2658 2580 2659 2581 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS ··· 2709 2629 { 2710 2630 #define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r)) 2711 2631 2712 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 2632 + if (dispc_runtime_get()) 2633 + return; 2713 2634 2714 2635 DUMPREG(DISPC_REVISION); 2715 2636 DUMPREG(DISPC_SYSCONFIG); ··· 2730 2649 DUMPREG(DISPC_TIMING_V(OMAP_DSS_CHANNEL_LCD)); 2731 2650 DUMPREG(DISPC_POL_FREQ(OMAP_DSS_CHANNEL_LCD)); 2732 2651 DUMPREG(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD)); 2733 - DUMPREG(DISPC_GLOBAL_ALPHA); 2652 + if (dss_has_feature(FEAT_GLOBAL_ALPHA)) 2653 + DUMPREG(DISPC_GLOBAL_ALPHA); 2734 2654 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT)); 2735 2655 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_LCD)); 2736 2656 if (dss_has_feature(FEAT_MGR_LCD2)) { ··· 2762 2680 DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD)); 2763 2681 DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD)); 2764 2682 2765 - DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD)); 2766 - DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD)); 2767 - DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD)); 2683 + if (dss_has_feature(FEAT_CPR)) { 2684 + DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD)); 2685 + DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD)); 2686 + DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD)); 2687 + } 2768 2688 if (dss_has_feature(FEAT_MGR_LCD2)) { 2769 2689 DUMPREG(DISPC_DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2)); 2770 2690 DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2)); 2771 2691 DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2)); 2772 2692 2773 - DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2)); 2774 - DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2)); 2775 - DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2)); 2693 + if (dss_has_feature(FEAT_CPR)) { 2694 + DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2)); 2695 + DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2)); 2696 + DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2)); 2697 + } 2776 2698 } 2777 2699 2778 - DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_GFX)); 2700 + if (dss_has_feature(FEAT_PRELOAD)) 2701 + DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_GFX)); 2779 2702 2780 2703 DUMPREG(DISPC_OVL_BA0(OMAP_DSS_VIDEO1)); 2781 2704 DUMPREG(DISPC_OVL_BA1(OMAP_DSS_VIDEO1)); ··· 2831 2744 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 2)); 2832 2745 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 3)); 2833 2746 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 4)); 2834 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 0)); 2835 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 1)); 2836 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 2)); 2837 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 3)); 2838 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 4)); 2839 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 5)); 2840 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 6)); 2841 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 7)); 2747 + if (dss_has_feature(FEAT_FIR_COEF_V)) { 2748 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 0)); 2749 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 1)); 2750 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 2)); 2751 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 3)); 2752 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 4)); 2753 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 5)); 2754 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 6)); 2755 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 7)); 2756 + } 2842 2757 2843 2758 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 2844 2759 DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO1)); ··· 2901 2812 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 2)); 2902 2813 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 3)); 2903 2814 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 4)); 2904 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 0)); 2905 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 1)); 2906 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 2)); 2907 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 3)); 2908 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 4)); 2909 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 5)); 2910 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 6)); 2911 - DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 7)); 2815 + 2816 + if (dss_has_feature(FEAT_FIR_COEF_V)) { 2817 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 0)); 2818 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 1)); 2819 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 2)); 2820 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 3)); 2821 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 4)); 2822 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 5)); 2823 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 6)); 2824 + DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 7)); 2825 + } 2912 2826 2913 2827 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 2914 2828 DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO2)); ··· 2950 2858 if (dss_has_feature(FEAT_ATTR2)) 2951 2859 DUMPREG(DISPC_OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2)); 2952 2860 2953 - DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO1)); 2954 - DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO2)); 2861 + if (dss_has_feature(FEAT_PRELOAD)) { 2862 + DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO1)); 2863 + DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO2)); 2864 + } 2955 2865 2956 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 2866 + dispc_runtime_put(); 2957 2867 #undef DUMPREG 2958 2868 } 2959 2869 ··· 2976 2882 l |= FLD_VAL(acbi, 11, 8); 2977 2883 l |= FLD_VAL(acb, 7, 0); 2978 2884 2979 - enable_clocks(1); 2980 2885 dispc_write_reg(DISPC_POL_FREQ(channel), l); 2981 - enable_clocks(0); 2982 2886 } 2983 2887 2984 2888 void dispc_set_pol_freq(enum omap_channel channel, ··· 3097 3005 mask |= isr_data->mask; 3098 3006 } 3099 3007 3100 - enable_clocks(1); 3101 - 3102 3008 old_mask = dispc_read_reg(DISPC_IRQENABLE); 3103 3009 /* clear the irqstatus for newly enabled irqs */ 3104 3010 dispc_write_reg(DISPC_IRQSTATUS, (mask ^ old_mask) & mask); 3105 3011 3106 3012 dispc_write_reg(DISPC_IRQENABLE, mask); 3107 - 3108 - enable_clocks(0); 3109 3013 } 3110 3014 3111 3015 int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask) ··· 3610 3522 { 3611 3523 u32 l; 3612 3524 3613 - l = dispc_read_reg(DISPC_SYSCONFIG); 3614 - l = FLD_MOD(l, 2, 13, 12); /* MIDLEMODE: smart standby */ 3615 - l = FLD_MOD(l, 2, 4, 3); /* SIDLEMODE: smart idle */ 3616 - l = FLD_MOD(l, 1, 2, 2); /* ENWAKEUP */ 3617 - l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */ 3618 - dispc_write_reg(DISPC_SYSCONFIG, l); 3619 - 3620 3525 /* Exclusively enable DISPC_CORE_CLK and set divider to 1 */ 3621 3526 if (dss_has_feature(FEAT_CORE_CLK_DIV)) { 3622 3527 l = dispc_read_reg(DISPC_DIVISOR); ··· 3633 3552 dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY); 3634 3553 3635 3554 dispc_read_plane_fifo_sizes(); 3636 - } 3637 3555 3638 - int dispc_enable_plane(enum omap_plane plane, bool enable) 3639 - { 3640 - DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); 3641 - 3642 - enable_clocks(1); 3643 - _dispc_enable_plane(plane, enable); 3644 - enable_clocks(0); 3645 - 3646 - return 0; 3647 - } 3648 - 3649 - int dispc_setup_plane(enum omap_plane plane, 3650 - u32 paddr, u16 screen_width, 3651 - u16 pos_x, u16 pos_y, 3652 - u16 width, u16 height, 3653 - u16 out_width, u16 out_height, 3654 - enum omap_color_mode color_mode, 3655 - bool ilace, 3656 - enum omap_dss_rotation_type rotation_type, 3657 - u8 rotation, bool mirror, u8 global_alpha, 3658 - u8 pre_mult_alpha, enum omap_channel channel, 3659 - u32 puv_addr) 3660 - { 3661 - int r = 0; 3662 - 3663 - DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d, %d, %dx%d -> " 3664 - "%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n", 3665 - plane, paddr, screen_width, pos_x, pos_y, 3666 - width, height, 3667 - out_width, out_height, 3668 - ilace, color_mode, 3669 - rotation, mirror, channel); 3670 - 3671 - enable_clocks(1); 3672 - 3673 - r = _dispc_setup_plane(plane, 3674 - paddr, screen_width, 3675 - pos_x, pos_y, 3676 - width, height, 3677 - out_width, out_height, 3678 - color_mode, ilace, 3679 - rotation_type, 3680 - rotation, mirror, 3681 - global_alpha, 3682 - pre_mult_alpha, 3683 - channel, puv_addr); 3684 - 3685 - enable_clocks(0); 3686 - 3687 - return r; 3556 + dispc_configure_burst_sizes(); 3688 3557 } 3689 3558 3690 3559 /* DISPC HW IP initialisation */ ··· 3643 3612 u32 rev; 3644 3613 int r = 0; 3645 3614 struct resource *dispc_mem; 3615 + struct clk *clk; 3646 3616 3647 3617 dispc.pdev = pdev; 3618 + 3619 + clk = clk_get(&pdev->dev, "fck"); 3620 + if (IS_ERR(clk)) { 3621 + DSSERR("can't get fck\n"); 3622 + r = PTR_ERR(clk); 3623 + goto err_get_clk; 3624 + } 3625 + 3626 + dispc.dss_clk = clk; 3648 3627 3649 3628 spin_lock_init(&dispc.irq_lock); 3650 3629 ··· 3669 3628 if (!dispc_mem) { 3670 3629 DSSERR("can't get IORESOURCE_MEM DISPC\n"); 3671 3630 r = -EINVAL; 3672 - goto fail0; 3631 + goto err_ioremap; 3673 3632 } 3674 3633 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem)); 3675 3634 if (!dispc.base) { 3676 3635 DSSERR("can't ioremap DISPC\n"); 3677 3636 r = -ENOMEM; 3678 - goto fail0; 3637 + goto err_ioremap; 3679 3638 } 3680 3639 dispc.irq = platform_get_irq(dispc.pdev, 0); 3681 3640 if (dispc.irq < 0) { 3682 3641 DSSERR("platform_get_irq failed\n"); 3683 3642 r = -ENODEV; 3684 - goto fail1; 3643 + goto err_irq; 3685 3644 } 3686 3645 3687 3646 r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED, 3688 3647 "OMAP DISPC", dispc.pdev); 3689 3648 if (r < 0) { 3690 3649 DSSERR("request_irq failed\n"); 3691 - goto fail1; 3650 + goto err_irq; 3692 3651 } 3693 3652 3694 - enable_clocks(1); 3653 + pm_runtime_enable(&pdev->dev); 3654 + 3655 + r = dispc_runtime_get(); 3656 + if (r) 3657 + goto err_runtime_get; 3695 3658 3696 3659 _omap_dispc_initial_config(); 3697 3660 3698 3661 _omap_dispc_initialize_irq(); 3699 3662 3700 - dispc_save_context(); 3701 - 3702 3663 rev = dispc_read_reg(DISPC_REVISION); 3703 3664 dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n", 3704 3665 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 3705 3666 3706 - enable_clocks(0); 3667 + dispc_runtime_put(); 3707 3668 3708 3669 return 0; 3709 - fail1: 3670 + 3671 + err_runtime_get: 3672 + pm_runtime_disable(&pdev->dev); 3673 + free_irq(dispc.irq, dispc.pdev); 3674 + err_irq: 3710 3675 iounmap(dispc.base); 3711 - fail0: 3676 + err_ioremap: 3677 + clk_put(dispc.dss_clk); 3678 + err_get_clk: 3712 3679 return r; 3713 3680 } 3714 3681 3715 3682 static int omap_dispchw_remove(struct platform_device *pdev) 3716 3683 { 3684 + pm_runtime_disable(&pdev->dev); 3685 + 3686 + clk_put(dispc.dss_clk); 3687 + 3717 3688 free_irq(dispc.irq, dispc.pdev); 3718 3689 iounmap(dispc.base); 3719 3690 return 0; 3720 3691 } 3692 + 3693 + static int dispc_runtime_suspend(struct device *dev) 3694 + { 3695 + dispc_save_context(); 3696 + clk_disable(dispc.dss_clk); 3697 + dss_runtime_put(); 3698 + 3699 + return 0; 3700 + } 3701 + 3702 + static int dispc_runtime_resume(struct device *dev) 3703 + { 3704 + int r; 3705 + 3706 + r = dss_runtime_get(); 3707 + if (r < 0) 3708 + return r; 3709 + 3710 + clk_enable(dispc.dss_clk); 3711 + dispc_restore_context(); 3712 + 3713 + return 0; 3714 + } 3715 + 3716 + static const struct dev_pm_ops dispc_pm_ops = { 3717 + .runtime_suspend = dispc_runtime_suspend, 3718 + .runtime_resume = dispc_runtime_resume, 3719 + }; 3721 3720 3722 3721 static struct platform_driver omap_dispchw_driver = { 3723 3722 .probe = omap_dispchw_probe, ··· 3765 3684 .driver = { 3766 3685 .name = "omapdss_dispc", 3767 3686 .owner = THIS_MODULE, 3687 + .pm = &dispc_pm_ops, 3768 3688 }, 3769 3689 }; 3770 3690
+5 -52
drivers/video/omap2/dss/display.c
··· 29 29 30 30 #include <video/omapdss.h> 31 31 #include "dss.h" 32 + #include "dss_features.h" 32 33 33 34 static ssize_t display_enabled_show(struct device *dev, 34 35 struct device_attribute *attr, char *buf) ··· 62 61 dssdev->driver->disable(dssdev); 63 62 } 64 63 } 65 - 66 - return size; 67 - } 68 - 69 - static ssize_t display_upd_mode_show(struct device *dev, 70 - struct device_attribute *attr, char *buf) 71 - { 72 - struct omap_dss_device *dssdev = to_dss_device(dev); 73 - enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO; 74 - if (dssdev->driver->get_update_mode) 75 - mode = dssdev->driver->get_update_mode(dssdev); 76 - return snprintf(buf, PAGE_SIZE, "%d\n", mode); 77 - } 78 - 79 - static ssize_t display_upd_mode_store(struct device *dev, 80 - struct device_attribute *attr, 81 - const char *buf, size_t size) 82 - { 83 - struct omap_dss_device *dssdev = to_dss_device(dev); 84 - int val, r; 85 - enum omap_dss_update_mode mode; 86 - 87 - if (!dssdev->driver->set_update_mode) 88 - return -EINVAL; 89 - 90 - r = kstrtoint(buf, 0, &val); 91 - if (r) 92 - return r; 93 - 94 - switch (val) { 95 - case OMAP_DSS_UPDATE_DISABLED: 96 - case OMAP_DSS_UPDATE_AUTO: 97 - case OMAP_DSS_UPDATE_MANUAL: 98 - mode = (enum omap_dss_update_mode)val; 99 - break; 100 - default: 101 - return -EINVAL; 102 - } 103 - 104 - r = dssdev->driver->set_update_mode(dssdev, mode); 105 - if (r) 106 - return r; 107 64 108 65 return size; 109 66 } ··· 253 294 254 295 static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR, 255 296 display_enabled_show, display_enabled_store); 256 - static DEVICE_ATTR(update_mode, S_IRUGO|S_IWUSR, 257 - display_upd_mode_show, display_upd_mode_store); 258 297 static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR, 259 298 display_tear_show, display_tear_store); 260 299 static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR, ··· 266 309 267 310 static struct device_attribute *display_sysfs_attrs[] = { 268 311 &dev_attr_enabled, 269 - &dev_attr_update_mode, 270 312 &dev_attr_tear_elim, 271 313 &dev_attr_timings, 272 314 &dev_attr_rotate, ··· 283 327 EXPORT_SYMBOL(omapdss_default_get_resolution); 284 328 285 329 void default_get_overlay_fifo_thresholds(enum omap_plane plane, 286 - u32 fifo_size, enum omap_burst_size *burst_size, 330 + u32 fifo_size, u32 burst_size, 287 331 u32 *fifo_low, u32 *fifo_high) 288 332 { 289 - unsigned burst_size_bytes; 333 + unsigned buf_unit = dss_feat_get_buffer_size_unit(); 290 334 291 - *burst_size = OMAP_DSS_BURST_16x32; 292 - burst_size_bytes = 16 * 32 / 8; 293 - 294 - *fifo_high = fifo_size - 1; 295 - *fifo_low = fifo_size - burst_size_bytes; 335 + *fifo_high = fifo_size - buf_unit; 336 + *fifo_low = fifo_size - burst_size; 296 337 } 297 338 298 339 int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
+47 -28
drivers/video/omap2/dss/dpi.c
··· 23 23 #define DSS_SUBSYS_NAME "DPI" 24 24 25 25 #include <linux/kernel.h> 26 - #include <linux/clk.h> 27 26 #include <linux/delay.h> 28 27 #include <linux/err.h> 29 28 #include <linux/errno.h> ··· 129 130 bool is_tft; 130 131 int r = 0; 131 132 132 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 133 - 134 133 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, 135 134 dssdev->panel.acbi, dssdev->panel.acb); 136 135 ··· 141 144 r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000, 142 145 &fck, &lck_div, &pck_div); 143 146 if (r) 144 - goto err0; 147 + return r; 145 148 146 149 pck = fck / lck_div / pck_div / 1000; 147 150 ··· 155 158 156 159 dispc_set_lcd_timings(dssdev->manager->id, t); 157 160 158 - err0: 159 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 160 - return r; 161 + return 0; 161 162 } 162 163 163 - static int dpi_basic_init(struct omap_dss_device *dssdev) 164 + static void dpi_basic_init(struct omap_dss_device *dssdev) 164 165 { 165 166 bool is_tft; 166 167 ··· 170 175 OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN); 171 176 dispc_set_tft_data_lines(dssdev->manager->id, 172 177 dssdev->phy.dpi.data_lines); 173 - 174 - return 0; 175 178 } 176 179 177 180 int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) ··· 179 186 r = omap_dss_start_device(dssdev); 180 187 if (r) { 181 188 DSSERR("failed to start device\n"); 182 - goto err0; 189 + goto err_start_dev; 183 190 } 184 191 185 192 if (cpu_is_omap34xx()) { 186 193 r = regulator_enable(dpi.vdds_dsi_reg); 187 194 if (r) 188 - goto err1; 195 + goto err_reg_enable; 189 196 } 190 197 191 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 192 - 193 - r = dpi_basic_init(dssdev); 198 + r = dss_runtime_get(); 194 199 if (r) 195 - goto err2; 200 + goto err_get_dss; 201 + 202 + r = dispc_runtime_get(); 203 + if (r) 204 + goto err_get_dispc; 205 + 206 + dpi_basic_init(dssdev); 196 207 197 208 if (dpi_use_dsi_pll(dssdev)) { 198 - dss_clk_enable(DSS_CLK_SYSCK); 209 + r = dsi_runtime_get(dpi.dsidev); 210 + if (r) 211 + goto err_get_dsi; 212 + 199 213 r = dsi_pll_init(dpi.dsidev, 0, 1); 200 214 if (r) 201 - goto err3; 215 + goto err_dsi_pll_init; 202 216 } 203 217 204 218 r = dpi_set_mode(dssdev); 205 219 if (r) 206 - goto err4; 220 + goto err_set_mode; 207 221 208 222 mdelay(2); 209 223 ··· 218 218 219 219 return 0; 220 220 221 - err4: 221 + err_set_mode: 222 222 if (dpi_use_dsi_pll(dssdev)) 223 223 dsi_pll_uninit(dpi.dsidev, true); 224 - err3: 224 + err_dsi_pll_init: 225 225 if (dpi_use_dsi_pll(dssdev)) 226 - dss_clk_disable(DSS_CLK_SYSCK); 227 - err2: 228 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 226 + dsi_runtime_put(dpi.dsidev); 227 + err_get_dsi: 228 + dispc_runtime_put(); 229 + err_get_dispc: 230 + dss_runtime_put(); 231 + err_get_dss: 229 232 if (cpu_is_omap34xx()) 230 233 regulator_disable(dpi.vdds_dsi_reg); 231 - err1: 234 + err_reg_enable: 232 235 omap_dss_stop_device(dssdev); 233 - err0: 236 + err_start_dev: 234 237 return r; 235 238 } 236 239 EXPORT_SYMBOL(omapdss_dpi_display_enable); ··· 245 242 if (dpi_use_dsi_pll(dssdev)) { 246 243 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); 247 244 dsi_pll_uninit(dpi.dsidev, true); 248 - dss_clk_disable(DSS_CLK_SYSCK); 245 + dsi_runtime_put(dpi.dsidev); 249 246 } 250 247 251 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 248 + dispc_runtime_put(); 249 + dss_runtime_put(); 252 250 253 251 if (cpu_is_omap34xx()) 254 252 regulator_disable(dpi.vdds_dsi_reg); ··· 261 257 void dpi_set_timings(struct omap_dss_device *dssdev, 262 258 struct omap_video_timings *timings) 263 259 { 260 + int r; 261 + 264 262 DSSDBG("dpi_set_timings\n"); 265 263 dssdev->panel.timings = *timings; 266 264 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 265 + r = dss_runtime_get(); 266 + if (r) 267 + return; 268 + 269 + r = dispc_runtime_get(); 270 + if (r) { 271 + dss_runtime_put(); 272 + return; 273 + } 274 + 267 275 dpi_set_mode(dssdev); 268 276 dispc_go(dssdev->manager->id); 277 + 278 + dispc_runtime_put(); 279 + dss_runtime_put(); 269 280 } 270 281 } 271 282 EXPORT_SYMBOL(dpi_set_timings);
+181 -119
drivers/video/omap2/dss/dsi.c
··· 36 36 #include <linux/sched.h> 37 37 #include <linux/slab.h> 38 38 #include <linux/debugfs.h> 39 + #include <linux/pm_runtime.h> 39 40 40 41 #include <video/omapdss.h> 41 42 #include <plat/clock.h> ··· 268 267 struct dsi_data { 269 268 struct platform_device *pdev; 270 269 void __iomem *base; 270 + 271 271 int irq; 272 + 273 + struct clk *dss_clk; 274 + struct clk *sys_clk; 272 275 273 276 void (*dsi_mux_pads)(bool enable); 274 277 ··· 394 389 return __raw_readl(dsi->base + idx.idx); 395 390 } 396 391 397 - 398 - void dsi_save_context(void) 399 - { 400 - } 401 - 402 - void dsi_restore_context(void) 403 - { 404 - } 405 - 406 392 void dsi_bus_lock(struct omap_dss_device *dssdev) 407 393 { 408 394 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); ··· 489 493 total_bytes * 1000 / total_us); 490 494 } 491 495 #else 492 - #define dsi_perf_mark_setup(x) 493 - #define dsi_perf_mark_start(x) 494 - #define dsi_perf_show(x, y) 496 + static inline void dsi_perf_mark_setup(struct platform_device *dsidev) 497 + { 498 + } 499 + 500 + static inline void dsi_perf_mark_start(struct platform_device *dsidev) 501 + { 502 + } 503 + 504 + static inline void dsi_perf_show(struct platform_device *dsidev, 505 + const char *name) 506 + { 507 + } 495 508 #endif 496 509 497 510 static void print_irq_status(u32 status) ··· 1044 1039 return e; 1045 1040 } 1046 1041 1047 - /* DSI func clock. this could also be dsi_pll_hsdiv_dsi_clk */ 1048 - static inline void enable_clocks(bool enable) 1042 + int dsi_runtime_get(struct platform_device *dsidev) 1049 1043 { 1050 - if (enable) 1051 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 1052 - else 1053 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 1044 + int r; 1045 + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1046 + 1047 + DSSDBG("dsi_runtime_get\n"); 1048 + 1049 + r = pm_runtime_get_sync(&dsi->pdev->dev); 1050 + WARN_ON(r < 0); 1051 + return r < 0 ? r : 0; 1052 + } 1053 + 1054 + void dsi_runtime_put(struct platform_device *dsidev) 1055 + { 1056 + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1057 + int r; 1058 + 1059 + DSSDBG("dsi_runtime_put\n"); 1060 + 1061 + r = pm_runtime_put(&dsi->pdev->dev); 1062 + WARN_ON(r < 0); 1054 1063 } 1055 1064 1056 1065 /* source clock for DSI PLL. this could also be PCLKFREE */ ··· 1074 1055 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1075 1056 1076 1057 if (enable) 1077 - dss_clk_enable(DSS_CLK_SYSCK); 1058 + clk_enable(dsi->sys_clk); 1078 1059 else 1079 - dss_clk_disable(DSS_CLK_SYSCK); 1060 + clk_disable(dsi->sys_clk); 1080 1061 1081 1062 if (enable && dsi->pll_locked) { 1082 1063 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) ··· 1169 1150 { 1170 1151 unsigned long r; 1171 1152 int dsi_module = dsi_get_dsidev_id(dsidev); 1153 + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1172 1154 1173 1155 if (dss_get_dsi_clk_source(dsi_module) == OMAP_DSS_CLK_SRC_FCK) { 1174 1156 /* DSI FCLK source is DSS_CLK_FCK */ 1175 - r = dss_clk_get_rate(DSS_CLK_FCK); 1157 + r = clk_get_rate(dsi->dss_clk); 1176 1158 } else { 1177 1159 /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */ 1178 1160 r = dsi_get_pll_hsdiv_dsi_rate(dsidev); ··· 1282 1262 return -EINVAL; 1283 1263 1284 1264 if (cinfo->use_sys_clk) { 1285 - cinfo->clkin = dss_clk_get_rate(DSS_CLK_SYSCK); 1265 + cinfo->clkin = clk_get_rate(dsi->sys_clk); 1286 1266 /* XXX it is unclear if highfreq should be used 1287 1267 * with DSS_SYS_CLK source also */ 1288 1268 cinfo->highfreq = 0; ··· 1331 1311 int match = 0; 1332 1312 unsigned long dss_sys_clk, max_dss_fck; 1333 1313 1334 - dss_sys_clk = dss_clk_get_rate(DSS_CLK_SYSCK); 1314 + dss_sys_clk = clk_get_rate(dsi->sys_clk); 1335 1315 1336 1316 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); 1337 1317 ··· 1621 1601 dsi->vdds_dsi_reg = vdds_dsi; 1622 1602 } 1623 1603 1624 - enable_clocks(1); 1625 1604 dsi_enable_pll_clock(dsidev, 1); 1626 1605 /* 1627 1606 * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4. ··· 1672 1653 } 1673 1654 err0: 1674 1655 dsi_disable_scp_clk(dsidev); 1675 - enable_clocks(0); 1676 1656 dsi_enable_pll_clock(dsidev, 0); 1677 1657 return r; 1678 1658 } ··· 1689 1671 } 1690 1672 1691 1673 dsi_disable_scp_clk(dsidev); 1692 - enable_clocks(0); 1693 1674 dsi_enable_pll_clock(dsidev, 0); 1694 1675 1695 1676 DSSDBG("PLL uninit done\n"); ··· 1705 1688 dispc_clk_src = dss_get_dispc_clk_source(); 1706 1689 dsi_clk_src = dss_get_dsi_clk_source(dsi_module); 1707 1690 1708 - enable_clocks(1); 1691 + if (dsi_runtime_get(dsidev)) 1692 + return; 1709 1693 1710 1694 seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1); 1711 1695 ··· 1749 1731 1750 1732 seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk); 1751 1733 1752 - enable_clocks(0); 1734 + dsi_runtime_put(dsidev); 1753 1735 } 1754 1736 1755 1737 void dsi_dump_clocks(struct seq_file *s) ··· 1891 1873 { 1892 1874 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(dsidev, r)) 1893 1875 1894 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 1876 + if (dsi_runtime_get(dsidev)) 1877 + return; 1895 1878 dsi_enable_scp_clk(dsidev); 1896 1879 1897 1880 DUMPREG(DSI_REVISION); ··· 1966 1947 DUMPREG(DSI_PLL_CONFIGURATION2); 1967 1948 1968 1949 dsi_disable_scp_clk(dsidev); 1969 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 1950 + dsi_runtime_put(dsidev); 1970 1951 #undef DUMPREG 1971 1952 } 1972 1953 ··· 2480 2461 dsi_disable_scp_clk(dsidev); 2481 2462 if (dsi->dsi_mux_pads) 2482 2463 dsi->dsi_mux_pads(false); 2483 - } 2484 - 2485 - static int _dsi_wait_reset(struct platform_device *dsidev) 2486 - { 2487 - int t = 0; 2488 - 2489 - while (REG_GET(dsidev, DSI_SYSSTATUS, 0, 0) == 0) { 2490 - if (++t > 5) { 2491 - DSSERR("soft reset failed\n"); 2492 - return -ENODEV; 2493 - } 2494 - udelay(1); 2495 - } 2496 - 2497 - return 0; 2498 - } 2499 - 2500 - static int _dsi_reset(struct platform_device *dsidev) 2501 - { 2502 - /* Soft reset */ 2503 - REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 1, 1); 2504 - return _dsi_wait_reset(dsidev); 2505 2464 } 2506 2465 2507 2466 static void dsi_config_tx_fifo(struct platform_device *dsidev, ··· 3383 3386 dsi_unregister_isr_cio(dsidev, dsi_completion_handler, &completion, 3384 3387 DSI_CIO_IRQ_ULPSACTIVENOT_ALL0); 3385 3388 3389 + /* Reset LANEx_ULPS_SIG2 */ 3390 + REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (0 << 0) | (0 << 1) | (0 << 2), 3391 + 7, 5); 3392 + 3386 3393 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ULPS); 3387 3394 3388 3395 dsi_if_enable(dsidev, false); ··· 4199 4198 dsi_pll_uninit(dsidev, disconnect_lanes); 4200 4199 } 4201 4200 4202 - static int dsi_core_init(struct platform_device *dsidev) 4203 - { 4204 - /* Autoidle */ 4205 - REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 0, 0); 4206 - 4207 - /* ENWAKEUP */ 4208 - REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 2, 2); 4209 - 4210 - /* SIDLEMODE smart-idle */ 4211 - REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 2, 4, 3); 4212 - 4213 - _dsi_initialize_irq(dsidev); 4214 - 4215 - return 0; 4216 - } 4217 - 4218 4201 int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) 4219 4202 { 4220 4203 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); ··· 4214 4229 r = omap_dss_start_device(dssdev); 4215 4230 if (r) { 4216 4231 DSSERR("failed to start device\n"); 4217 - goto err0; 4232 + goto err_start_dev; 4218 4233 } 4219 4234 4220 - enable_clocks(1); 4235 + r = dsi_runtime_get(dsidev); 4236 + if (r) 4237 + goto err_get_dsi; 4238 + 4221 4239 dsi_enable_pll_clock(dsidev, 1); 4222 4240 4223 - r = _dsi_reset(dsidev); 4224 - if (r) 4225 - goto err1; 4226 - 4227 - dsi_core_init(dsidev); 4241 + _dsi_initialize_irq(dsidev); 4228 4242 4229 4243 r = dsi_display_init_dispc(dssdev); 4230 4244 if (r) 4231 - goto err1; 4245 + goto err_init_dispc; 4232 4246 4233 4247 r = dsi_display_init_dsi(dssdev); 4234 4248 if (r) 4235 - goto err2; 4249 + goto err_init_dsi; 4236 4250 4237 4251 mutex_unlock(&dsi->lock); 4238 4252 4239 4253 return 0; 4240 4254 4241 - err2: 4255 + err_init_dsi: 4242 4256 dsi_display_uninit_dispc(dssdev); 4243 - err1: 4244 - enable_clocks(0); 4257 + err_init_dispc: 4245 4258 dsi_enable_pll_clock(dsidev, 0); 4259 + dsi_runtime_put(dsidev); 4260 + err_get_dsi: 4246 4261 omap_dss_stop_device(dssdev); 4247 - err0: 4262 + err_start_dev: 4248 4263 mutex_unlock(&dsi->lock); 4249 4264 DSSDBG("dsi_display_enable FAILED\n"); 4250 4265 return r; ··· 4263 4278 4264 4279 mutex_lock(&dsi->lock); 4265 4280 4281 + dsi_sync_vc(dsidev, 0); 4282 + dsi_sync_vc(dsidev, 1); 4283 + dsi_sync_vc(dsidev, 2); 4284 + dsi_sync_vc(dsidev, 3); 4285 + 4266 4286 dsi_display_uninit_dispc(dssdev); 4267 4287 4268 4288 dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps); 4269 4289 4270 - enable_clocks(0); 4290 + dsi_runtime_put(dsidev); 4271 4291 dsi_enable_pll_clock(dsidev, 0); 4272 4292 4273 4293 omap_dss_stop_device(dssdev); ··· 4292 4302 EXPORT_SYMBOL(omapdss_dsi_enable_te); 4293 4303 4294 4304 void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 4295 - u32 fifo_size, enum omap_burst_size *burst_size, 4305 + u32 fifo_size, u32 burst_size, 4296 4306 u32 *fifo_low, u32 *fifo_high) 4297 4307 { 4298 - unsigned burst_size_bytes; 4299 - 4300 - *burst_size = OMAP_DSS_BURST_16x32; 4301 - burst_size_bytes = 16 * 32 / 8; 4302 - 4303 - *fifo_high = fifo_size - burst_size_bytes; 4304 - *fifo_low = fifo_size - burst_size_bytes * 2; 4308 + *fifo_high = fifo_size - burst_size; 4309 + *fifo_low = fifo_size - burst_size * 2; 4305 4310 } 4306 4311 4307 4312 int dsi_init_display(struct omap_dss_device *dssdev) ··· 4422 4437 dsi->lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV); 4423 4438 } 4424 4439 4425 - static int dsi_init(struct platform_device *dsidev) 4440 + static int dsi_get_clocks(struct platform_device *dsidev) 4441 + { 4442 + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4443 + struct clk *clk; 4444 + 4445 + clk = clk_get(&dsidev->dev, "fck"); 4446 + if (IS_ERR(clk)) { 4447 + DSSERR("can't get fck\n"); 4448 + return PTR_ERR(clk); 4449 + } 4450 + 4451 + dsi->dss_clk = clk; 4452 + 4453 + if (cpu_is_omap34xx() || cpu_is_omap3630()) 4454 + clk = clk_get(&dsidev->dev, "dss2_alwon_fck"); 4455 + else 4456 + clk = clk_get(&dsidev->dev, "sys_clk"); 4457 + if (IS_ERR(clk)) { 4458 + DSSERR("can't get sys_clk\n"); 4459 + clk_put(dsi->dss_clk); 4460 + dsi->dss_clk = NULL; 4461 + return PTR_ERR(clk); 4462 + } 4463 + 4464 + dsi->sys_clk = clk; 4465 + 4466 + return 0; 4467 + } 4468 + 4469 + static void dsi_put_clocks(struct platform_device *dsidev) 4470 + { 4471 + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4472 + 4473 + if (dsi->dss_clk) 4474 + clk_put(dsi->dss_clk); 4475 + if (dsi->sys_clk) 4476 + clk_put(dsi->sys_clk); 4477 + } 4478 + 4479 + /* DSI1 HW IP initialisation */ 4480 + static int omap_dsi1hw_probe(struct platform_device *dsidev) 4426 4481 { 4427 4482 struct omap_display_platform_data *dss_plat_data; 4428 4483 struct omap_dss_board_info *board_info; ··· 4474 4449 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); 4475 4450 if (!dsi) { 4476 4451 r = -ENOMEM; 4477 - goto err0; 4452 + goto err_alloc; 4478 4453 } 4479 4454 4480 4455 dsi->pdev = dsidev; ··· 4497 4472 mutex_init(&dsi->lock); 4498 4473 sema_init(&dsi->bus_lock, 1); 4499 4474 4475 + r = dsi_get_clocks(dsidev); 4476 + if (r) 4477 + goto err_get_clk; 4478 + 4479 + pm_runtime_enable(&dsidev->dev); 4480 + 4500 4481 INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work, 4501 4482 dsi_framedone_timeout_work_callback); 4502 4483 ··· 4515 4484 if (!dsi_mem) { 4516 4485 DSSERR("can't get IORESOURCE_MEM DSI\n"); 4517 4486 r = -EINVAL; 4518 - goto err1; 4487 + goto err_ioremap; 4519 4488 } 4520 4489 dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem)); 4521 4490 if (!dsi->base) { 4522 4491 DSSERR("can't ioremap DSI\n"); 4523 4492 r = -ENOMEM; 4524 - goto err1; 4493 + goto err_ioremap; 4525 4494 } 4526 4495 dsi->irq = platform_get_irq(dsi->pdev, 0); 4527 4496 if (dsi->irq < 0) { 4528 4497 DSSERR("platform_get_irq failed\n"); 4529 4498 r = -ENODEV; 4530 - goto err2; 4499 + goto err_get_irq; 4531 4500 } 4532 4501 4533 4502 r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED, 4534 4503 dev_name(&dsidev->dev), dsi->pdev); 4535 4504 if (r < 0) { 4536 4505 DSSERR("request_irq failed\n"); 4537 - goto err2; 4506 + goto err_get_irq; 4538 4507 } 4539 4508 4540 4509 /* DSI VCs initialization */ ··· 4546 4515 4547 4516 dsi_calc_clock_param_ranges(dsidev); 4548 4517 4549 - enable_clocks(1); 4518 + r = dsi_runtime_get(dsidev); 4519 + if (r) 4520 + goto err_get_dsi; 4550 4521 4551 4522 rev = dsi_read_reg(dsidev, DSI_REVISION); 4552 4523 dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n", ··· 4556 4523 4557 4524 dsi->num_data_lanes = dsi_get_num_data_lanes(dsidev); 4558 4525 4559 - enable_clocks(0); 4526 + dsi_runtime_put(dsidev); 4560 4527 4561 4528 return 0; 4562 - err2: 4529 + 4530 + err_get_dsi: 4531 + free_irq(dsi->irq, dsi->pdev); 4532 + err_get_irq: 4563 4533 iounmap(dsi->base); 4564 - err1: 4534 + err_ioremap: 4535 + pm_runtime_disable(&dsidev->dev); 4536 + err_get_clk: 4565 4537 kfree(dsi); 4566 - err0: 4538 + err_alloc: 4567 4539 return r; 4568 4540 } 4569 4541 4570 - static void dsi_exit(struct platform_device *dsidev) 4542 + static int omap_dsi1hw_remove(struct platform_device *dsidev) 4571 4543 { 4572 4544 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4545 + 4546 + WARN_ON(dsi->scp_clk_refcount > 0); 4547 + 4548 + pm_runtime_disable(&dsidev->dev); 4549 + 4550 + dsi_put_clocks(dsidev); 4573 4551 4574 4552 if (dsi->vdds_dsi_reg != NULL) { 4575 4553 if (dsi->vdds_dsi_enabled) { ··· 4597 4553 4598 4554 kfree(dsi); 4599 4555 4600 - DSSDBG("omap_dsi_exit\n"); 4556 + return 0; 4601 4557 } 4602 4558 4603 - /* DSI1 HW IP initialisation */ 4604 - static int omap_dsi1hw_probe(struct platform_device *dsidev) 4559 + static int dsi_runtime_suspend(struct device *dev) 4605 4560 { 4561 + struct dsi_data *dsi = dsi_get_dsidrv_data(to_platform_device(dev)); 4562 + 4563 + clk_disable(dsi->dss_clk); 4564 + 4565 + dispc_runtime_put(); 4566 + dss_runtime_put(); 4567 + 4568 + return 0; 4569 + } 4570 + 4571 + static int dsi_runtime_resume(struct device *dev) 4572 + { 4573 + struct dsi_data *dsi = dsi_get_dsidrv_data(to_platform_device(dev)); 4606 4574 int r; 4607 4575 4608 - r = dsi_init(dsidev); 4609 - if (r) { 4610 - DSSERR("Failed to initialize DSI\n"); 4611 - goto err_dsi; 4612 - } 4613 - err_dsi: 4576 + r = dss_runtime_get(); 4577 + if (r) 4578 + goto err_get_dss; 4579 + 4580 + r = dispc_runtime_get(); 4581 + if (r) 4582 + goto err_get_dispc; 4583 + 4584 + clk_enable(dsi->dss_clk); 4585 + 4586 + return 0; 4587 + 4588 + err_get_dispc: 4589 + dss_runtime_put(); 4590 + err_get_dss: 4614 4591 return r; 4615 4592 } 4616 4593 4617 - static int omap_dsi1hw_remove(struct platform_device *dsidev) 4618 - { 4619 - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4620 - 4621 - dsi_exit(dsidev); 4622 - WARN_ON(dsi->scp_clk_refcount > 0); 4623 - return 0; 4624 - } 4594 + static const struct dev_pm_ops dsi_pm_ops = { 4595 + .runtime_suspend = dsi_runtime_suspend, 4596 + .runtime_resume = dsi_runtime_resume, 4597 + }; 4625 4598 4626 4599 static struct platform_driver omap_dsi1hw_driver = { 4627 4600 .probe = omap_dsi1hw_probe, ··· 4646 4585 .driver = { 4647 4586 .name = "omapdss_dsi1", 4648 4587 .owner = THIS_MODULE, 4588 + .pm = &dsi_pm_ops, 4649 4589 }, 4650 4590 }; 4651 4591
+169 -482
drivers/video/omap2/dss/dss.c
··· 28 28 #include <linux/delay.h> 29 29 #include <linux/seq_file.h> 30 30 #include <linux/clk.h> 31 + #include <linux/platform_device.h> 32 + #include <linux/pm_runtime.h> 31 33 32 34 #include <video/omapdss.h> 33 35 #include <plat/clock.h> ··· 61 59 static struct { 62 60 struct platform_device *pdev; 63 61 void __iomem *base; 64 - int ctx_id; 65 62 66 63 struct clk *dpll4_m4_ck; 67 - struct clk *dss_ick; 68 - struct clk *dss_fck; 69 - struct clk *dss_sys_clk; 70 - struct clk *dss_tv_fck; 71 - struct clk *dss_video_fck; 72 - unsigned num_clks_enabled; 64 + struct clk *dss_clk; 73 65 74 66 unsigned long cache_req_pck; 75 67 unsigned long cache_prate; ··· 74 78 enum omap_dss_clk_source dispc_clk_source; 75 79 enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS]; 76 80 81 + bool ctx_valid; 77 82 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 78 83 } dss; 79 84 ··· 83 86 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI", 84 87 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK", 85 88 }; 86 - 87 - static void dss_clk_enable_all_no_ctx(void); 88 - static void dss_clk_disable_all_no_ctx(void); 89 - static void dss_clk_enable_no_ctx(enum dss_clock clks); 90 - static void dss_clk_disable_no_ctx(enum dss_clock clks); 91 - 92 - static int _omap_dss_wait_reset(void); 93 89 94 90 static inline void dss_write_reg(const struct dss_reg idx, u32 val) 95 91 { ··· 99 109 #define RR(reg) \ 100 110 dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)]) 101 111 102 - void dss_save_context(void) 112 + static void dss_save_context(void) 103 113 { 104 - if (cpu_is_omap24xx()) 105 - return; 114 + DSSDBG("dss_save_context\n"); 106 115 107 - SR(SYSCONFIG); 108 116 SR(CONTROL); 109 117 110 118 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) & ··· 110 122 SR(SDI_CONTROL); 111 123 SR(PLL_CONTROL); 112 124 } 125 + 126 + dss.ctx_valid = true; 127 + 128 + DSSDBG("context saved\n"); 113 129 } 114 130 115 - void dss_restore_context(void) 131 + static void dss_restore_context(void) 116 132 { 117 - if (_omap_dss_wait_reset()) 118 - DSSERR("DSS not coming out of reset after sleep\n"); 133 + DSSDBG("dss_restore_context\n"); 119 134 120 - RR(SYSCONFIG); 135 + if (!dss.ctx_valid) 136 + return; 137 + 121 138 RR(CONTROL); 122 139 123 140 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) & ··· 130 137 RR(SDI_CONTROL); 131 138 RR(PLL_CONTROL); 132 139 } 140 + 141 + DSSDBG("context restored\n"); 133 142 } 134 143 135 144 #undef SR ··· 229 234 return dss_generic_clk_source_names[clk_src]; 230 235 } 231 236 237 + 232 238 void dss_dump_clocks(struct seq_file *s) 233 239 { 234 240 unsigned long dpll4_ck_rate; ··· 237 241 const char *fclk_name, *fclk_real_name; 238 242 unsigned long fclk_rate; 239 243 240 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 244 + if (dss_runtime_get()) 245 + return; 241 246 242 247 seq_printf(s, "- DSS -\n"); 243 248 244 249 fclk_name = dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_FCK); 245 250 fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK); 246 - fclk_rate = dss_clk_get_rate(DSS_CLK_FCK); 251 + fclk_rate = clk_get_rate(dss.dss_clk); 247 252 248 253 if (dss.dpll4_m4_ck) { 249 254 dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); ··· 270 273 fclk_rate); 271 274 } 272 275 273 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 276 + dss_runtime_put(); 274 277 } 275 278 276 279 void dss_dump_regs(struct seq_file *s) 277 280 { 278 281 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) 279 282 280 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 283 + if (dss_runtime_get()) 284 + return; 281 285 282 286 DUMPREG(DSS_REVISION); 283 287 DUMPREG(DSS_SYSCONFIG); ··· 292 294 DUMPREG(DSS_SDI_STATUS); 293 295 } 294 296 295 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 297 + dss_runtime_put(); 296 298 #undef DUMPREG 297 299 } 298 300 ··· 435 437 } else { 436 438 if (cinfo->fck_div != 0) 437 439 return -EINVAL; 438 - cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK); 440 + cinfo->fck = clk_get_rate(dss.dss_clk); 439 441 } 440 442 441 443 return 0; ··· 465 467 466 468 int dss_get_clock_div(struct dss_clock_info *cinfo) 467 469 { 468 - cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK); 470 + cinfo->fck = clk_get_rate(dss.dss_clk); 469 471 470 472 if (dss.dpll4_m4_ck) { 471 473 unsigned long prate; ··· 510 512 511 513 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); 512 514 513 - fck = dss_clk_get_rate(DSS_CLK_FCK); 515 + fck = clk_get_rate(dss.dss_clk); 514 516 if (req_pck == dss.cache_req_pck && 515 517 ((cpu_is_omap34xx() && prate == dss.cache_prate) || 516 518 dss.cache_dss_cinfo.fck == fck)) { ··· 537 539 if (dss.dpll4_m4_ck == NULL) { 538 540 struct dispc_clock_info cur_dispc; 539 541 /* XXX can we change the clock on omap2? */ 540 - fck = dss_clk_get_rate(DSS_CLK_FCK); 542 + fck = clk_get_rate(dss.dss_clk); 541 543 fck_div = 1; 542 544 543 545 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); ··· 614 616 return 0; 615 617 } 616 618 617 - static int _omap_dss_wait_reset(void) 618 - { 619 - int t = 0; 620 - 621 - while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) { 622 - if (++t > 1000) { 623 - DSSERR("soft reset failed\n"); 624 - return -ENODEV; 625 - } 626 - udelay(1); 627 - } 628 - 629 - return 0; 630 - } 631 - 632 - static int _omap_dss_reset(void) 633 - { 634 - /* Soft reset */ 635 - REG_FLD_MOD(DSS_SYSCONFIG, 1, 1, 1); 636 - return _omap_dss_wait_reset(); 637 - } 638 - 639 619 void dss_set_venc_output(enum omap_dss_venc_type type) 640 620 { 641 621 int l = 0; ··· 639 663 REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */ 640 664 } 641 665 642 - static int dss_init(void) 666 + static int dss_get_clocks(void) 667 + { 668 + struct clk *clk; 669 + int r; 670 + 671 + clk = clk_get(&dss.pdev->dev, "fck"); 672 + if (IS_ERR(clk)) { 673 + DSSERR("can't get clock fck\n"); 674 + r = PTR_ERR(clk); 675 + goto err; 676 + } 677 + 678 + dss.dss_clk = clk; 679 + 680 + if (cpu_is_omap34xx()) { 681 + clk = clk_get(NULL, "dpll4_m4_ck"); 682 + if (IS_ERR(clk)) { 683 + DSSERR("Failed to get dpll4_m4_ck\n"); 684 + r = PTR_ERR(clk); 685 + goto err; 686 + } 687 + } else if (cpu_is_omap44xx()) { 688 + clk = clk_get(NULL, "dpll_per_m5x2_ck"); 689 + if (IS_ERR(clk)) { 690 + DSSERR("Failed to get dpll_per_m5x2_ck\n"); 691 + r = PTR_ERR(clk); 692 + goto err; 693 + } 694 + } else { /* omap24xx */ 695 + clk = NULL; 696 + } 697 + 698 + dss.dpll4_m4_ck = clk; 699 + 700 + return 0; 701 + 702 + err: 703 + if (dss.dss_clk) 704 + clk_put(dss.dss_clk); 705 + if (dss.dpll4_m4_ck) 706 + clk_put(dss.dpll4_m4_ck); 707 + 708 + return r; 709 + } 710 + 711 + static void dss_put_clocks(void) 712 + { 713 + if (dss.dpll4_m4_ck) 714 + clk_put(dss.dpll4_m4_ck); 715 + clk_put(dss.dss_clk); 716 + } 717 + 718 + struct clk *dss_get_ick(void) 719 + { 720 + return clk_get(&dss.pdev->dev, "ick"); 721 + } 722 + 723 + int dss_runtime_get(void) 643 724 { 644 725 int r; 645 - u32 rev; 726 + 727 + DSSDBG("dss_runtime_get\n"); 728 + 729 + r = pm_runtime_get_sync(&dss.pdev->dev); 730 + WARN_ON(r < 0); 731 + return r < 0 ? r : 0; 732 + } 733 + 734 + void dss_runtime_put(void) 735 + { 736 + int r; 737 + 738 + DSSDBG("dss_runtime_put\n"); 739 + 740 + r = pm_runtime_put(&dss.pdev->dev); 741 + WARN_ON(r < 0); 742 + } 743 + 744 + /* DEBUGFS */ 745 + #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 746 + void dss_debug_dump_clocks(struct seq_file *s) 747 + { 748 + dss_dump_clocks(s); 749 + dispc_dump_clocks(s); 750 + #ifdef CONFIG_OMAP2_DSS_DSI 751 + dsi_dump_clocks(s); 752 + #endif 753 + } 754 + #endif 755 + 756 + /* DSS HW IP initialisation */ 757 + static int omap_dsshw_probe(struct platform_device *pdev) 758 + { 646 759 struct resource *dss_mem; 647 - struct clk *dpll4_m4_ck; 760 + u32 rev; 761 + int r; 762 + 763 + dss.pdev = pdev; 648 764 649 765 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0); 650 766 if (!dss_mem) { 651 767 DSSERR("can't get IORESOURCE_MEM DSS\n"); 652 768 r = -EINVAL; 653 - goto fail0; 769 + goto err_ioremap; 654 770 } 655 771 dss.base = ioremap(dss_mem->start, resource_size(dss_mem)); 656 772 if (!dss.base) { 657 773 DSSERR("can't ioremap DSS\n"); 658 774 r = -ENOMEM; 659 - goto fail0; 775 + goto err_ioremap; 660 776 } 661 777 662 - /* disable LCD and DIGIT output. This seems to fix the synclost 663 - * problem that we get, if the bootloader starts the DSS and 664 - * the kernel resets it */ 665 - omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440); 778 + r = dss_get_clocks(); 779 + if (r) 780 + goto err_clocks; 666 781 667 - #ifdef CONFIG_OMAP2_DSS_SLEEP_BEFORE_RESET 668 - /* We need to wait here a bit, otherwise we sometimes start to 669 - * get synclost errors, and after that only power cycle will 670 - * restore DSS functionality. I have no idea why this happens. 671 - * And we have to wait _before_ resetting the DSS, but after 672 - * enabling clocks. 673 - * 674 - * This bug was at least present on OMAP3430. It's unknown 675 - * if it happens on OMAP2 or OMAP3630. 676 - */ 677 - msleep(50); 678 - #endif 782 + pm_runtime_enable(&pdev->dev); 679 783 680 - _omap_dss_reset(); 681 - 682 - /* autoidle */ 683 - REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); 784 + r = dss_runtime_get(); 785 + if (r) 786 + goto err_runtime_get; 684 787 685 788 /* Select DPLL */ 686 789 REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); ··· 769 714 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ 770 715 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ 771 716 #endif 772 - if (cpu_is_omap34xx()) { 773 - dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); 774 - if (IS_ERR(dpll4_m4_ck)) { 775 - DSSERR("Failed to get dpll4_m4_ck\n"); 776 - r = PTR_ERR(dpll4_m4_ck); 777 - goto fail1; 778 - } 779 - } else if (cpu_is_omap44xx()) { 780 - dpll4_m4_ck = clk_get(NULL, "dpll_per_m5x2_ck"); 781 - if (IS_ERR(dpll4_m4_ck)) { 782 - DSSERR("Failed to get dpll4_m4_ck\n"); 783 - r = PTR_ERR(dpll4_m4_ck); 784 - goto fail1; 785 - } 786 - } else { /* omap24xx */ 787 - dpll4_m4_ck = NULL; 788 - } 789 - 790 - dss.dpll4_m4_ck = dpll4_m4_ck; 791 - 792 717 dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; 793 718 dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; 794 719 dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK; 795 720 dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; 796 721 dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; 797 - 798 - dss_save_context(); 799 - 800 - rev = dss_read_reg(DSS_REVISION); 801 - printk(KERN_INFO "OMAP DSS rev %d.%d\n", 802 - FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 803 - 804 - return 0; 805 - 806 - fail1: 807 - iounmap(dss.base); 808 - fail0: 809 - return r; 810 - } 811 - 812 - static void dss_exit(void) 813 - { 814 - if (dss.dpll4_m4_ck) 815 - clk_put(dss.dpll4_m4_ck); 816 - 817 - iounmap(dss.base); 818 - } 819 - 820 - /* CONTEXT */ 821 - static int dss_get_ctx_id(void) 822 - { 823 - struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data; 824 - int r; 825 - 826 - if (!pdata->board_data->get_last_off_on_transaction_id) 827 - return 0; 828 - r = pdata->board_data->get_last_off_on_transaction_id(&dss.pdev->dev); 829 - if (r < 0) { 830 - dev_err(&dss.pdev->dev, "getting transaction ID failed, " 831 - "will force context restore\n"); 832 - r = -1; 833 - } 834 - return r; 835 - } 836 - 837 - int dss_need_ctx_restore(void) 838 - { 839 - int id = dss_get_ctx_id(); 840 - 841 - if (id < 0 || id != dss.ctx_id) { 842 - DSSDBG("ctx id %d -> id %d\n", 843 - dss.ctx_id, id); 844 - dss.ctx_id = id; 845 - return 1; 846 - } else { 847 - return 0; 848 - } 849 - } 850 - 851 - static void save_all_ctx(void) 852 - { 853 - DSSDBG("save context\n"); 854 - 855 - dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK); 856 - 857 - dss_save_context(); 858 - dispc_save_context(); 859 - #ifdef CONFIG_OMAP2_DSS_DSI 860 - dsi_save_context(); 861 - #endif 862 - 863 - dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK); 864 - } 865 - 866 - static void restore_all_ctx(void) 867 - { 868 - DSSDBG("restore context\n"); 869 - 870 - dss_clk_enable_all_no_ctx(); 871 - 872 - dss_restore_context(); 873 - dispc_restore_context(); 874 - #ifdef CONFIG_OMAP2_DSS_DSI 875 - dsi_restore_context(); 876 - #endif 877 - 878 - dss_clk_disable_all_no_ctx(); 879 - } 880 - 881 - static int dss_get_clock(struct clk **clock, const char *clk_name) 882 - { 883 - struct clk *clk; 884 - 885 - clk = clk_get(&dss.pdev->dev, clk_name); 886 - 887 - if (IS_ERR(clk)) { 888 - DSSERR("can't get clock %s", clk_name); 889 - return PTR_ERR(clk); 890 - } 891 - 892 - *clock = clk; 893 - 894 - DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk)); 895 - 896 - return 0; 897 - } 898 - 899 - static int dss_get_clocks(void) 900 - { 901 - int r; 902 - struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data; 903 - 904 - dss.dss_ick = NULL; 905 - dss.dss_fck = NULL; 906 - dss.dss_sys_clk = NULL; 907 - dss.dss_tv_fck = NULL; 908 - dss.dss_video_fck = NULL; 909 - 910 - r = dss_get_clock(&dss.dss_ick, "ick"); 911 - if (r) 912 - goto err; 913 - 914 - r = dss_get_clock(&dss.dss_fck, "fck"); 915 - if (r) 916 - goto err; 917 - 918 - if (!pdata->opt_clock_available) { 919 - r = -ENODEV; 920 - goto err; 921 - } 922 - 923 - if (pdata->opt_clock_available("sys_clk")) { 924 - r = dss_get_clock(&dss.dss_sys_clk, "sys_clk"); 925 - if (r) 926 - goto err; 927 - } 928 - 929 - if (pdata->opt_clock_available("tv_clk")) { 930 - r = dss_get_clock(&dss.dss_tv_fck, "tv_clk"); 931 - if (r) 932 - goto err; 933 - } 934 - 935 - if (pdata->opt_clock_available("video_clk")) { 936 - r = dss_get_clock(&dss.dss_video_fck, "video_clk"); 937 - if (r) 938 - goto err; 939 - } 940 - 941 - return 0; 942 - 943 - err: 944 - if (dss.dss_ick) 945 - clk_put(dss.dss_ick); 946 - if (dss.dss_fck) 947 - clk_put(dss.dss_fck); 948 - if (dss.dss_sys_clk) 949 - clk_put(dss.dss_sys_clk); 950 - if (dss.dss_tv_fck) 951 - clk_put(dss.dss_tv_fck); 952 - if (dss.dss_video_fck) 953 - clk_put(dss.dss_video_fck); 954 - 955 - return r; 956 - } 957 - 958 - static void dss_put_clocks(void) 959 - { 960 - if (dss.dss_video_fck) 961 - clk_put(dss.dss_video_fck); 962 - if (dss.dss_tv_fck) 963 - clk_put(dss.dss_tv_fck); 964 - if (dss.dss_sys_clk) 965 - clk_put(dss.dss_sys_clk); 966 - clk_put(dss.dss_fck); 967 - clk_put(dss.dss_ick); 968 - } 969 - 970 - unsigned long dss_clk_get_rate(enum dss_clock clk) 971 - { 972 - switch (clk) { 973 - case DSS_CLK_ICK: 974 - return clk_get_rate(dss.dss_ick); 975 - case DSS_CLK_FCK: 976 - return clk_get_rate(dss.dss_fck); 977 - case DSS_CLK_SYSCK: 978 - return clk_get_rate(dss.dss_sys_clk); 979 - case DSS_CLK_TVFCK: 980 - return clk_get_rate(dss.dss_tv_fck); 981 - case DSS_CLK_VIDFCK: 982 - return clk_get_rate(dss.dss_video_fck); 983 - } 984 - 985 - BUG(); 986 - return 0; 987 - } 988 - 989 - static unsigned count_clk_bits(enum dss_clock clks) 990 - { 991 - unsigned num_clks = 0; 992 - 993 - if (clks & DSS_CLK_ICK) 994 - ++num_clks; 995 - if (clks & DSS_CLK_FCK) 996 - ++num_clks; 997 - if (clks & DSS_CLK_SYSCK) 998 - ++num_clks; 999 - if (clks & DSS_CLK_TVFCK) 1000 - ++num_clks; 1001 - if (clks & DSS_CLK_VIDFCK) 1002 - ++num_clks; 1003 - 1004 - return num_clks; 1005 - } 1006 - 1007 - static void dss_clk_enable_no_ctx(enum dss_clock clks) 1008 - { 1009 - unsigned num_clks = count_clk_bits(clks); 1010 - 1011 - if (clks & DSS_CLK_ICK) 1012 - clk_enable(dss.dss_ick); 1013 - if (clks & DSS_CLK_FCK) 1014 - clk_enable(dss.dss_fck); 1015 - if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk) 1016 - clk_enable(dss.dss_sys_clk); 1017 - if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck) 1018 - clk_enable(dss.dss_tv_fck); 1019 - if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck) 1020 - clk_enable(dss.dss_video_fck); 1021 - 1022 - dss.num_clks_enabled += num_clks; 1023 - } 1024 - 1025 - void dss_clk_enable(enum dss_clock clks) 1026 - { 1027 - bool check_ctx = dss.num_clks_enabled == 0; 1028 - 1029 - dss_clk_enable_no_ctx(clks); 1030 - 1031 - /* 1032 - * HACK: On omap4 the registers may not be accessible right after 1033 - * enabling the clocks. At some point this will be handled by 1034 - * pm_runtime, but for the time begin this should make things work. 1035 - */ 1036 - if (cpu_is_omap44xx() && check_ctx) 1037 - udelay(10); 1038 - 1039 - if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore()) 1040 - restore_all_ctx(); 1041 - } 1042 - 1043 - static void dss_clk_disable_no_ctx(enum dss_clock clks) 1044 - { 1045 - unsigned num_clks = count_clk_bits(clks); 1046 - 1047 - if (clks & DSS_CLK_ICK) 1048 - clk_disable(dss.dss_ick); 1049 - if (clks & DSS_CLK_FCK) 1050 - clk_disable(dss.dss_fck); 1051 - if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk) 1052 - clk_disable(dss.dss_sys_clk); 1053 - if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck) 1054 - clk_disable(dss.dss_tv_fck); 1055 - if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck) 1056 - clk_disable(dss.dss_video_fck); 1057 - 1058 - dss.num_clks_enabled -= num_clks; 1059 - } 1060 - 1061 - void dss_clk_disable(enum dss_clock clks) 1062 - { 1063 - if (cpu_is_omap34xx()) { 1064 - unsigned num_clks = count_clk_bits(clks); 1065 - 1066 - BUG_ON(dss.num_clks_enabled < num_clks); 1067 - 1068 - if (dss.num_clks_enabled == num_clks) 1069 - save_all_ctx(); 1070 - } 1071 - 1072 - dss_clk_disable_no_ctx(clks); 1073 - } 1074 - 1075 - static void dss_clk_enable_all_no_ctx(void) 1076 - { 1077 - enum dss_clock clks; 1078 - 1079 - clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK; 1080 - if (cpu_is_omap34xx()) 1081 - clks |= DSS_CLK_VIDFCK; 1082 - dss_clk_enable_no_ctx(clks); 1083 - } 1084 - 1085 - static void dss_clk_disable_all_no_ctx(void) 1086 - { 1087 - enum dss_clock clks; 1088 - 1089 - clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK; 1090 - if (cpu_is_omap34xx()) 1091 - clks |= DSS_CLK_VIDFCK; 1092 - dss_clk_disable_no_ctx(clks); 1093 - } 1094 - 1095 - #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 1096 - /* CLOCKS */ 1097 - static void core_dump_clocks(struct seq_file *s) 1098 - { 1099 - int i; 1100 - struct clk *clocks[5] = { 1101 - dss.dss_ick, 1102 - dss.dss_fck, 1103 - dss.dss_sys_clk, 1104 - dss.dss_tv_fck, 1105 - dss.dss_video_fck 1106 - }; 1107 - 1108 - const char *names[5] = { 1109 - "ick", 1110 - "fck", 1111 - "sys_clk", 1112 - "tv_fck", 1113 - "video_fck" 1114 - }; 1115 - 1116 - seq_printf(s, "- CORE -\n"); 1117 - 1118 - seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled); 1119 - 1120 - for (i = 0; i < 5; i++) { 1121 - if (!clocks[i]) 1122 - continue; 1123 - seq_printf(s, "%s (%s)%*s\t%lu\t%d\n", 1124 - names[i], 1125 - clocks[i]->name, 1126 - 24 - strlen(names[i]) - strlen(clocks[i]->name), 1127 - "", 1128 - clk_get_rate(clocks[i]), 1129 - clocks[i]->usecount); 1130 - } 1131 - } 1132 - #endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */ 1133 - 1134 - /* DEBUGFS */ 1135 - #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 1136 - void dss_debug_dump_clocks(struct seq_file *s) 1137 - { 1138 - core_dump_clocks(s); 1139 - dss_dump_clocks(s); 1140 - dispc_dump_clocks(s); 1141 - #ifdef CONFIG_OMAP2_DSS_DSI 1142 - dsi_dump_clocks(s); 1143 - #endif 1144 - } 1145 - #endif 1146 - 1147 - 1148 - /* DSS HW IP initialisation */ 1149 - static int omap_dsshw_probe(struct platform_device *pdev) 1150 - { 1151 - int r; 1152 - 1153 - dss.pdev = pdev; 1154 - 1155 - r = dss_get_clocks(); 1156 - if (r) 1157 - goto err_clocks; 1158 - 1159 - dss_clk_enable_all_no_ctx(); 1160 - 1161 - dss.ctx_id = dss_get_ctx_id(); 1162 - DSSDBG("initial ctx id %u\n", dss.ctx_id); 1163 - 1164 - r = dss_init(); 1165 - if (r) { 1166 - DSSERR("Failed to initialize DSS\n"); 1167 - goto err_dss; 1168 - } 1169 722 1170 723 r = dpi_init(); 1171 724 if (r) { ··· 787 1124 goto err_sdi; 788 1125 } 789 1126 790 - dss_clk_disable_all_no_ctx(); 1127 + rev = dss_read_reg(DSS_REVISION); 1128 + printk(KERN_INFO "OMAP DSS rev %d.%d\n", 1129 + FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 1130 + 1131 + dss_runtime_put(); 1132 + 791 1133 return 0; 792 1134 err_sdi: 793 1135 dpi_exit(); 794 1136 err_dpi: 795 - dss_exit(); 796 - err_dss: 797 - dss_clk_disable_all_no_ctx(); 1137 + dss_runtime_put(); 1138 + err_runtime_get: 1139 + pm_runtime_disable(&pdev->dev); 798 1140 dss_put_clocks(); 799 1141 err_clocks: 1142 + iounmap(dss.base); 1143 + err_ioremap: 800 1144 return r; 801 1145 } 802 1146 803 1147 static int omap_dsshw_remove(struct platform_device *pdev) 804 1148 { 1149 + dpi_exit(); 1150 + sdi_exit(); 805 1151 806 - dss_exit(); 1152 + iounmap(dss.base); 807 1153 808 - /* 809 - * As part of hwmod changes, DSS is not the only controller of dss 810 - * clocks; hwmod framework itself will also enable clocks during hwmod 811 - * init for dss, and autoidle is set in h/w for DSS. Hence, there's no 812 - * need to disable clocks if their usecounts > 1. 813 - */ 814 - WARN_ON(dss.num_clks_enabled > 0); 1154 + pm_runtime_disable(&pdev->dev); 815 1155 816 1156 dss_put_clocks(); 1157 + 817 1158 return 0; 818 1159 } 1160 + 1161 + static int dss_runtime_suspend(struct device *dev) 1162 + { 1163 + dss_save_context(); 1164 + clk_disable(dss.dss_clk); 1165 + return 0; 1166 + } 1167 + 1168 + static int dss_runtime_resume(struct device *dev) 1169 + { 1170 + clk_enable(dss.dss_clk); 1171 + dss_restore_context(); 1172 + return 0; 1173 + } 1174 + 1175 + static const struct dev_pm_ops dss_pm_ops = { 1176 + .runtime_suspend = dss_runtime_suspend, 1177 + .runtime_resume = dss_runtime_resume, 1178 + }; 819 1179 820 1180 static struct platform_driver omap_dsshw_driver = { 821 1181 .probe = omap_dsshw_probe, ··· 846 1160 .driver = { 847 1161 .name = "omapdss_dss", 848 1162 .owner = THIS_MODULE, 1163 + .pm = &dss_pm_ops, 849 1164 }, 850 1165 }; 851 1166
+24 -30
drivers/video/omap2/dss/dss.h
··· 97 97 #define FLD_MOD(orig, val, start, end) \ 98 98 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) 99 99 100 - enum omap_burst_size { 101 - OMAP_DSS_BURST_4x32 = 0, 102 - OMAP_DSS_BURST_8x32 = 1, 103 - OMAP_DSS_BURST_16x32 = 2, 104 - }; 105 - 106 100 enum omap_parallel_interface_mode { 107 101 OMAP_DSS_PARALLELMODE_BYPASS, /* MIPI DPI */ 108 102 OMAP_DSS_PARALLELMODE_RFBI, /* MIPI DBI */ 109 103 OMAP_DSS_PARALLELMODE_DSI, 110 - }; 111 - 112 - enum dss_clock { 113 - DSS_CLK_ICK = 1 << 0, /* DSS_L3_ICLK and DSS_L4_ICLK */ 114 - DSS_CLK_FCK = 1 << 1, /* DSS1_ALWON_FCLK */ 115 - DSS_CLK_SYSCK = 1 << 2, /* DSS2_ALWON_FCLK */ 116 - DSS_CLK_TVFCK = 1 << 3, /* DSS_TV_FCLK */ 117 - DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/ 118 104 }; 119 105 120 106 enum dss_hdmi_venc_clk_source_select { ··· 180 194 bool dss_use_replication(struct omap_dss_device *dssdev, 181 195 enum omap_color_mode mode); 182 196 void default_get_overlay_fifo_thresholds(enum omap_plane plane, 183 - u32 fifo_size, enum omap_burst_size *burst_size, 197 + u32 fifo_size, u32 burst_size, 184 198 u32 *fifo_low, u32 *fifo_high); 185 199 186 200 /* manager */ ··· 206 220 int dss_init_platform_driver(void); 207 221 void dss_uninit_platform_driver(void); 208 222 223 + int dss_runtime_get(void); 224 + void dss_runtime_put(void); 225 + 226 + struct clk *dss_get_ick(void); 227 + 209 228 void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); 210 - void dss_save_context(void); 211 - void dss_restore_context(void); 212 - void dss_clk_enable(enum dss_clock clks); 213 - void dss_clk_disable(enum dss_clock clks); 214 - unsigned long dss_clk_get_rate(enum dss_clock clk); 215 - int dss_need_ctx_restore(void); 216 229 const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); 217 230 void dss_dump_clocks(struct seq_file *s); 218 231 ··· 268 283 int dsi_init_platform_driver(void); 269 284 void dsi_uninit_platform_driver(void); 270 285 286 + int dsi_runtime_get(struct platform_device *dsidev); 287 + void dsi_runtime_put(struct platform_device *dsidev); 288 + 271 289 void dsi_dump_clocks(struct seq_file *s); 272 290 void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir, 273 291 const struct file_operations *debug_fops); 274 292 void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir, 275 293 const struct file_operations *debug_fops); 276 - 277 - void dsi_save_context(void); 278 - void dsi_restore_context(void); 279 294 280 295 int dsi_init_display(struct omap_dss_device *display); 281 296 void dsi_irq_handler(void); ··· 289 304 bool enable_hsdiv); 290 305 void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); 291 306 void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 292 - u32 fifo_size, enum omap_burst_size *burst_size, 307 + u32 fifo_size, u32 burst_size, 293 308 u32 *fifo_low, u32 *fifo_high); 294 309 void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); 295 310 void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); ··· 300 315 return 0; 301 316 } 302 317 static inline void dsi_uninit_platform_driver(void) 318 + { 319 + } 320 + static inline int dsi_runtime_get(struct platform_device *dsidev) 321 + { 322 + return 0; 323 + } 324 + static inline void dsi_runtime_put(struct platform_device *dsidev) 303 325 { 304 326 } 305 327 static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev) ··· 376 384 void dispc_irq_handler(void); 377 385 void dispc_fake_vsync_irq(void); 378 386 379 - void dispc_save_context(void); 380 - void dispc_restore_context(void); 387 + int dispc_runtime_get(void); 388 + void dispc_runtime_put(void); 381 389 382 390 void dispc_enable_sidle(void); 383 391 void dispc_disable_sidle(void); ··· 390 398 void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height); 391 399 void dispc_set_digit_size(u16 width, u16 height); 392 400 u32 dispc_get_plane_fifo_size(enum omap_plane plane); 393 - void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high); 401 + void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); 394 402 void dispc_enable_fifomerge(bool enable); 395 - void dispc_set_burst_size(enum omap_plane plane, 396 - enum omap_burst_size burst_size); 403 + u32 dispc_get_burst_size(enum omap_plane plane); 404 + void dispc_enable_cpr(enum omap_channel channel, bool enable); 405 + void dispc_set_cpr_coef(enum omap_channel channel, 406 + struct omap_dss_cpr_coefs *coefs); 397 407 398 408 void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr); 399 409 void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr);
+32 -4
drivers/video/omap2/dss/dss_features.c
··· 49 49 const enum omap_color_mode *supported_color_modes; 50 50 const char * const *clksrc_names; 51 51 const struct dss_param_range *dss_params; 52 + 53 + const u32 buffer_size_unit; 54 + const u32 burst_size_unit; 52 55 }; 53 56 54 57 /* This struct is assigned to one of the below during initialization */ ··· 277 274 .supported_color_modes = omap2_dss_supported_color_modes, 278 275 .clksrc_names = omap2_dss_clk_source_names, 279 276 .dss_params = omap2_dss_param_range, 277 + .buffer_size_unit = 1, 278 + .burst_size_unit = 8, 280 279 }; 281 280 282 281 /* OMAP3 DSS Features */ ··· 291 286 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 292 287 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE | 293 288 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | 294 - FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC, 289 + FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC | 290 + FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD | 291 + FEAT_FIR_COEF_V, 295 292 296 293 .num_mgrs = 2, 297 294 .num_ovls = 3, ··· 301 294 .supported_color_modes = omap3_dss_supported_color_modes, 302 295 .clksrc_names = omap3_dss_clk_source_names, 303 296 .dss_params = omap3_dss_param_range, 297 + .buffer_size_unit = 1, 298 + .burst_size_unit = 8, 304 299 }; 305 300 306 301 static const struct omap_dss_features omap3630_dss_features = { ··· 315 306 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED | 316 307 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | 317 308 FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG | 318 - FEAT_DSI_PLL_FREQSEL, 309 + FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD | 310 + FEAT_FIR_COEF_V, 319 311 320 312 .num_mgrs = 2, 321 313 .num_ovls = 3, ··· 324 314 .supported_color_modes = omap3_dss_supported_color_modes, 325 315 .clksrc_names = omap3_dss_clk_source_names, 326 316 .dss_params = omap3_dss_param_range, 317 + .buffer_size_unit = 1, 318 + .burst_size_unit = 8, 327 319 }; 328 320 329 321 /* OMAP4 DSS Features */ ··· 339 327 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 | 340 328 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC | 341 329 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | 342 - FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2, 330 + FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | 331 + FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V, 343 332 344 333 .num_mgrs = 3, 345 334 .num_ovls = 3, ··· 348 335 .supported_color_modes = omap4_dss_supported_color_modes, 349 336 .clksrc_names = omap4_dss_clk_source_names, 350 337 .dss_params = omap4_dss_param_range, 338 + .buffer_size_unit = 16, 339 + .burst_size_unit = 16, 351 340 }; 352 341 353 342 /* For all the other OMAP4 versions */ ··· 363 348 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC | 364 349 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | 365 350 FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE | 366 - FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2, 351 + FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR | 352 + FEAT_PRELOAD | FEAT_FIR_COEF_V, 367 353 368 354 .num_mgrs = 3, 369 355 .num_ovls = 3, ··· 372 356 .supported_color_modes = omap4_dss_supported_color_modes, 373 357 .clksrc_names = omap4_dss_clk_source_names, 374 358 .dss_params = omap4_dss_param_range, 359 + .buffer_size_unit = 16, 360 + .burst_size_unit = 16, 375 361 }; 376 362 377 363 /* Functions returning values related to a DSS feature */ ··· 417 399 const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id) 418 400 { 419 401 return omap_current_dss_features->clksrc_names[id]; 402 + } 403 + 404 + u32 dss_feat_get_buffer_size_unit(void) 405 + { 406 + return omap_current_dss_features->buffer_size_unit; 407 + } 408 + 409 + u32 dss_feat_get_burst_size_unit(void) 410 + { 411 + return omap_current_dss_features->burst_size_unit; 420 412 } 421 413 422 414 /* DSS has_feature check */
+7
drivers/video/omap2/dss/dss_features.h
··· 51 51 FEAT_HDMI_CTS_SWMODE = 1 << 19, 52 52 FEAT_HANDLE_UV_SEPARATE = 1 << 20, 53 53 FEAT_ATTR2 = 1 << 21, 54 + FEAT_VENC_REQUIRES_TV_DAC_CLK = 1 << 22, 55 + FEAT_CPR = 1 << 23, 56 + FEAT_PRELOAD = 1 << 24, 57 + FEAT_FIR_COEF_V = 1 << 25, 54 58 }; 55 59 56 60 /* DSS register field id */ ··· 93 89 bool dss_feat_color_mode_supported(enum omap_plane plane, 94 90 enum omap_color_mode color_mode); 95 91 const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id); 92 + 93 + u32 dss_feat_get_buffer_size_unit(void); /* in bytes */ 94 + u32 dss_feat_get_burst_size_unit(void); /* in bytes */ 96 95 97 96 bool dss_has_feature(enum dss_feat_id id); 98 97 void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
+122 -40
drivers/video/omap2/dss/hdmi.c
··· 29 29 #include <linux/mutex.h> 30 30 #include <linux/delay.h> 31 31 #include <linux/string.h> 32 + #include <linux/platform_device.h> 33 + #include <linux/pm_runtime.h> 34 + #include <linux/clk.h> 32 35 #include <video/omapdss.h> 33 36 #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 34 37 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) ··· 54 51 u8 edid_set; 55 52 bool custom_set; 56 53 struct hdmi_config cfg; 54 + 55 + struct clk *sys_clk; 56 + struct clk *hdmi_clk; 57 57 } hdmi; 58 58 59 59 /* ··· 166 160 return !val; 167 161 } 168 162 return val; 163 + } 164 + 165 + static int hdmi_runtime_get(void) 166 + { 167 + int r; 168 + 169 + DSSDBG("hdmi_runtime_get\n"); 170 + 171 + r = pm_runtime_get_sync(&hdmi.pdev->dev); 172 + WARN_ON(r < 0); 173 + return r < 0 ? r : 0; 174 + } 175 + 176 + static void hdmi_runtime_put(void) 177 + { 178 + int r; 179 + 180 + DSSDBG("hdmi_runtime_put\n"); 181 + 182 + r = pm_runtime_put(&hdmi.pdev->dev); 183 + WARN_ON(r < 0); 169 184 } 170 185 171 186 int hdmi_init_display(struct omap_dss_device *dssdev) ··· 338 311 return 0; 339 312 } 340 313 341 - static int hdmi_wait_softreset(void) 342 - { 343 - /* reset W1 */ 344 - REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0); 345 - 346 - /* wait till SOFTRESET == 0 */ 347 - if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) { 348 - DSSERR("sysconfig reset failed\n"); 349 - return -ETIMEDOUT; 350 - } 351 - 352 - return 0; 353 - } 354 - 355 314 static int hdmi_pll_program(struct hdmi_pll_info *fmt) 356 315 { 357 316 u16 r = 0; 358 317 enum hdmi_clk_refsel refsel; 359 - 360 - /* wait for wrapper reset */ 361 - r = hdmi_wait_softreset(); 362 - if (r) 363 - return r; 364 318 365 319 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF); 366 320 if (r) ··· 1072 1064 unsigned long clkin, refclk; 1073 1065 u32 mf; 1074 1066 1075 - clkin = dss_clk_get_rate(DSS_CLK_SYSCK) / 10000; 1067 + clkin = clk_get_rate(hdmi.sys_clk) / 10000; 1076 1068 /* 1077 1069 * Input clock is predivided by N + 1 1078 1070 * out put of which is reference clk ··· 1106 1098 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); 1107 1099 } 1108 1100 1109 - static void hdmi_enable_clocks(int enable) 1110 - { 1111 - if (enable) 1112 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | 1113 - DSS_CLK_SYSCK | DSS_CLK_VIDFCK); 1114 - else 1115 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | 1116 - DSS_CLK_SYSCK | DSS_CLK_VIDFCK); 1117 - } 1118 - 1119 1101 static int hdmi_power_on(struct omap_dss_device *dssdev) 1120 1102 { 1121 1103 int r, code = 0; ··· 1113 1115 struct omap_video_timings *p; 1114 1116 unsigned long phy; 1115 1117 1116 - hdmi_enable_clocks(1); 1118 + r = hdmi_runtime_get(); 1119 + if (r) 1120 + return r; 1117 1121 1118 1122 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0); 1119 1123 ··· 1180 1180 1181 1181 return 0; 1182 1182 err: 1183 - hdmi_enable_clocks(0); 1183 + hdmi_runtime_put(); 1184 1184 return -EIO; 1185 1185 } 1186 1186 ··· 1191 1191 hdmi_wp_video_start(0); 1192 1192 hdmi_phy_off(); 1193 1193 hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF); 1194 - hdmi_enable_clocks(0); 1194 + hdmi_runtime_put(); 1195 1195 1196 1196 hdmi.edid_set = 0; 1197 1197 } ··· 1686 1686 }; 1687 1687 #endif 1688 1688 1689 + static int hdmi_get_clocks(struct platform_device *pdev) 1690 + { 1691 + struct clk *clk; 1692 + 1693 + clk = clk_get(&pdev->dev, "sys_clk"); 1694 + if (IS_ERR(clk)) { 1695 + DSSERR("can't get sys_clk\n"); 1696 + return PTR_ERR(clk); 1697 + } 1698 + 1699 + hdmi.sys_clk = clk; 1700 + 1701 + clk = clk_get(&pdev->dev, "dss_48mhz_clk"); 1702 + if (IS_ERR(clk)) { 1703 + DSSERR("can't get hdmi_clk\n"); 1704 + clk_put(hdmi.sys_clk); 1705 + return PTR_ERR(clk); 1706 + } 1707 + 1708 + hdmi.hdmi_clk = clk; 1709 + 1710 + return 0; 1711 + } 1712 + 1713 + static void hdmi_put_clocks(void) 1714 + { 1715 + if (hdmi.sys_clk) 1716 + clk_put(hdmi.sys_clk); 1717 + if (hdmi.hdmi_clk) 1718 + clk_put(hdmi.hdmi_clk); 1719 + } 1720 + 1689 1721 /* HDMI HW IP initialisation */ 1690 1722 static int omapdss_hdmihw_probe(struct platform_device *pdev) 1691 1723 { 1692 1724 struct resource *hdmi_mem; 1693 - #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 1694 - defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 1695 - int ret; 1696 - #endif 1725 + int r; 1697 1726 1698 1727 hdmi.pdata = pdev->dev.platform_data; 1699 1728 hdmi.pdev = pdev; ··· 1742 1713 return -ENOMEM; 1743 1714 } 1744 1715 1716 + r = hdmi_get_clocks(pdev); 1717 + if (r) { 1718 + iounmap(hdmi.base_wp); 1719 + return r; 1720 + } 1721 + 1722 + pm_runtime_enable(&pdev->dev); 1723 + 1745 1724 hdmi_panel_init(); 1746 1725 1747 1726 #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 1748 1727 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 1749 1728 1750 1729 /* Register ASoC codec DAI */ 1751 - ret = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv, 1730 + r = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv, 1752 1731 &hdmi_codec_dai_drv, 1); 1753 - if (ret) { 1732 + if (r) { 1754 1733 DSSERR("can't register ASoC HDMI audio codec\n"); 1755 - return ret; 1734 + return r; 1756 1735 } 1757 1736 #endif 1758 1737 return 0; ··· 1775 1738 snd_soc_unregister_codec(&pdev->dev); 1776 1739 #endif 1777 1740 1741 + pm_runtime_disable(&pdev->dev); 1742 + 1743 + hdmi_put_clocks(); 1744 + 1778 1745 iounmap(hdmi.base_wp); 1779 1746 1780 1747 return 0; 1781 1748 } 1749 + 1750 + static int hdmi_runtime_suspend(struct device *dev) 1751 + { 1752 + clk_disable(hdmi.hdmi_clk); 1753 + clk_disable(hdmi.sys_clk); 1754 + 1755 + dispc_runtime_put(); 1756 + dss_runtime_put(); 1757 + 1758 + return 0; 1759 + } 1760 + 1761 + static int hdmi_runtime_resume(struct device *dev) 1762 + { 1763 + int r; 1764 + 1765 + r = dss_runtime_get(); 1766 + if (r < 0) 1767 + goto err_get_dss; 1768 + 1769 + r = dispc_runtime_get(); 1770 + if (r < 0) 1771 + goto err_get_dispc; 1772 + 1773 + 1774 + clk_enable(hdmi.sys_clk); 1775 + clk_enable(hdmi.hdmi_clk); 1776 + 1777 + return 0; 1778 + 1779 + err_get_dispc: 1780 + dss_runtime_put(); 1781 + err_get_dss: 1782 + return r; 1783 + } 1784 + 1785 + static const struct dev_pm_ops hdmi_pm_ops = { 1786 + .runtime_suspend = hdmi_runtime_suspend, 1787 + .runtime_resume = hdmi_runtime_resume, 1788 + }; 1782 1789 1783 1790 static struct platform_driver omapdss_hdmihw_driver = { 1784 1791 .probe = omapdss_hdmihw_probe, ··· 1830 1749 .driver = { 1831 1750 .name = "omapdss_hdmi", 1832 1751 .owner = THIS_MODULE, 1752 + .pm = &hdmi_pm_ops, 1833 1753 }, 1834 1754 }; 1835 1755
+202 -149
drivers/video/omap2/dss/manager.c
··· 275 275 return size; 276 276 } 277 277 278 + static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr, 279 + char *buf) 280 + { 281 + return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.cpr_enable); 282 + } 283 + 284 + static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr, 285 + const char *buf, size_t size) 286 + { 287 + struct omap_overlay_manager_info info; 288 + int v; 289 + int r; 290 + bool enable; 291 + 292 + if (!dss_has_feature(FEAT_CPR)) 293 + return -ENODEV; 294 + 295 + r = kstrtoint(buf, 0, &v); 296 + if (r) 297 + return r; 298 + 299 + enable = !!v; 300 + 301 + mgr->get_manager_info(mgr, &info); 302 + 303 + if (info.cpr_enable == enable) 304 + return size; 305 + 306 + info.cpr_enable = enable; 307 + 308 + r = mgr->set_manager_info(mgr, &info); 309 + if (r) 310 + return r; 311 + 312 + r = mgr->apply(mgr); 313 + if (r) 314 + return r; 315 + 316 + return size; 317 + } 318 + 319 + static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr, 320 + char *buf) 321 + { 322 + struct omap_overlay_manager_info info; 323 + 324 + mgr->get_manager_info(mgr, &info); 325 + 326 + return snprintf(buf, PAGE_SIZE, 327 + "%d %d %d %d %d %d %d %d %d\n", 328 + info.cpr_coefs.rr, 329 + info.cpr_coefs.rg, 330 + info.cpr_coefs.rb, 331 + info.cpr_coefs.gr, 332 + info.cpr_coefs.gg, 333 + info.cpr_coefs.gb, 334 + info.cpr_coefs.br, 335 + info.cpr_coefs.bg, 336 + info.cpr_coefs.bb); 337 + } 338 + 339 + static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr, 340 + const char *buf, size_t size) 341 + { 342 + struct omap_overlay_manager_info info; 343 + struct omap_dss_cpr_coefs coefs; 344 + int r, i; 345 + s16 *arr; 346 + 347 + if (!dss_has_feature(FEAT_CPR)) 348 + return -ENODEV; 349 + 350 + if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd", 351 + &coefs.rr, &coefs.rg, &coefs.rb, 352 + &coefs.gr, &coefs.gg, &coefs.gb, 353 + &coefs.br, &coefs.bg, &coefs.bb) != 9) 354 + return -EINVAL; 355 + 356 + arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb, 357 + coefs.gr, coefs.gg, coefs.gb, 358 + coefs.br, coefs.bg, coefs.bb }; 359 + 360 + for (i = 0; i < 9; ++i) { 361 + if (arr[i] < -512 || arr[i] > 511) 362 + return -EINVAL; 363 + } 364 + 365 + mgr->get_manager_info(mgr, &info); 366 + 367 + info.cpr_coefs = coefs; 368 + 369 + r = mgr->set_manager_info(mgr, &info); 370 + if (r) 371 + return r; 372 + 373 + r = mgr->apply(mgr); 374 + if (r) 375 + return r; 376 + 377 + return size; 378 + } 379 + 278 380 struct manager_attribute { 279 381 struct attribute attr; 280 382 ssize_t (*show)(struct omap_overlay_manager *, char *); ··· 402 300 static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR, 403 301 manager_alpha_blending_enabled_show, 404 302 manager_alpha_blending_enabled_store); 303 + static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR, 304 + manager_cpr_enable_show, 305 + manager_cpr_enable_store); 306 + static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR, 307 + manager_cpr_coef_show, 308 + manager_cpr_coef_store); 405 309 406 310 407 311 static struct attribute *manager_sysfs_attrs[] = { ··· 418 310 &manager_attr_trans_key_value.attr, 419 311 &manager_attr_trans_key_enabled.attr, 420 312 &manager_attr_alpha_blending_enabled.attr, 313 + &manager_attr_cpr_enable.attr, 314 + &manager_attr_cpr_coef.attr, 421 315 NULL 422 316 }; 423 317 ··· 501 391 502 392 bool enabled; 503 393 504 - u32 paddr; 505 - void __iomem *vaddr; 506 - u32 p_uv_addr; /* relevant for NV12 format only */ 507 - u16 screen_width; 508 - u16 width; 509 - u16 height; 510 - enum omap_color_mode color_mode; 511 - u8 rotation; 512 - enum omap_dss_rotation_type rotation_type; 513 - bool mirror; 514 - 515 - u16 pos_x; 516 - u16 pos_y; 517 - u16 out_width; /* if 0, out_width == width */ 518 - u16 out_height; /* if 0, out_height == height */ 519 - u8 global_alpha; 520 - u8 pre_mult_alpha; 394 + struct omap_overlay_info info; 521 395 522 396 enum omap_channel channel; 523 397 bool replication; 524 398 bool ilace; 525 399 526 - enum omap_burst_size burst_size; 527 400 u32 fifo_low; 528 401 u32 fifo_high; 529 - 530 - bool manual_update; 531 402 }; 532 403 533 404 struct manager_cache_data { ··· 520 429 * VSYNC/EVSYNC */ 521 430 bool shadow_dirty; 522 431 523 - u32 default_color; 432 + struct omap_overlay_manager_info info; 524 433 525 - enum omap_dss_trans_key_type trans_key_type; 526 - u32 trans_key; 527 - bool trans_enabled; 528 - 529 - bool alpha_enabled; 530 - 531 - bool manual_upd_display; 532 434 bool manual_update; 533 435 bool do_manual_update; 534 436 ··· 623 539 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 624 540 return 0; 625 541 542 + if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) 543 + return 0; 544 + 626 545 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC 627 546 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) { 628 547 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 629 548 } else { 630 - if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 631 - enum omap_dss_update_mode mode; 632 - mode = dssdev->driver->get_update_mode(dssdev); 633 - if (mode != OMAP_DSS_UPDATE_AUTO) 634 - return 0; 635 - 636 - irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ? 637 - DISPC_IRQ_FRAMEDONE 638 - : DISPC_IRQ_FRAMEDONE2; 639 - } else { 640 - irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ? 641 - DISPC_IRQ_VSYNC 642 - : DISPC_IRQ_VSYNC2; 643 - } 549 + irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ? 550 + DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2; 644 551 } 645 552 646 553 mc = &dss_cache.manager_cache[mgr->id]; ··· 692 617 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 693 618 return 0; 694 619 620 + if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) 621 + return 0; 622 + 695 623 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC 696 624 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) { 697 625 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 698 626 } else { 699 - if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 700 - enum omap_dss_update_mode mode; 701 - mode = dssdev->driver->get_update_mode(dssdev); 702 - if (mode != OMAP_DSS_UPDATE_AUTO) 703 - return 0; 704 - 705 - irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ? 706 - DISPC_IRQ_FRAMEDONE 707 - : DISPC_IRQ_FRAMEDONE2; 708 - } else { 709 - irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ? 710 - DISPC_IRQ_VSYNC 711 - : DISPC_IRQ_VSYNC2; 712 - } 627 + irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ? 628 + DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2; 713 629 } 714 630 715 631 oc = &dss_cache.overlay_cache[ovl->id]; ··· 786 720 787 721 static bool dispc_is_overlay_scaled(struct overlay_cache_data *oc) 788 722 { 789 - if (oc->out_width != 0 && oc->width != oc->out_width) 723 + struct omap_overlay_info *oi = &oc->info; 724 + 725 + if (oi->out_width != 0 && oi->width != oi->out_width) 790 726 return true; 791 727 792 - if (oc->out_height != 0 && oc->height != oc->out_height) 728 + if (oi->out_height != 0 && oi->height != oi->out_height) 793 729 return true; 794 730 795 731 return false; ··· 801 733 { 802 734 struct overlay_cache_data *c; 803 735 struct manager_cache_data *mc; 736 + struct omap_overlay_info *oi; 737 + struct omap_overlay_manager_info *mi; 804 738 u16 outw, outh; 805 739 u16 x, y, w, h; 806 740 u32 paddr; ··· 812 742 DSSDBGF("%d", plane); 813 743 814 744 c = &dss_cache.overlay_cache[plane]; 745 + oi = &c->info; 815 746 816 747 if (!c->enabled) { 817 748 dispc_enable_plane(plane, 0); ··· 820 749 } 821 750 822 751 mc = &dss_cache.manager_cache[c->channel]; 752 + mi = &mc->info; 823 753 824 - x = c->pos_x; 825 - y = c->pos_y; 826 - w = c->width; 827 - h = c->height; 828 - outw = c->out_width == 0 ? c->width : c->out_width; 829 - outh = c->out_height == 0 ? c->height : c->out_height; 830 - paddr = c->paddr; 754 + x = oi->pos_x; 755 + y = oi->pos_y; 756 + w = oi->width; 757 + h = oi->height; 758 + outw = oi->out_width == 0 ? oi->width : oi->out_width; 759 + outh = oi->out_height == 0 ? oi->height : oi->out_height; 760 + paddr = oi->paddr; 831 761 832 762 orig_w = w; 833 763 orig_h = h; 834 764 orig_outw = outw; 835 765 orig_outh = outh; 836 766 837 - if (c->manual_update && mc->do_manual_update) { 767 + if (mc->manual_update && mc->do_manual_update) { 838 768 unsigned bpp; 839 769 unsigned scale_x_m = w, scale_x_d = outw; 840 770 unsigned scale_y_m = h, scale_y_d = outh; ··· 847 775 return 0; 848 776 } 849 777 850 - switch (c->color_mode) { 778 + switch (oi->color_mode) { 851 779 case OMAP_DSS_COLOR_NV12: 852 780 bpp = 8; 853 781 break; ··· 877 805 BUG(); 878 806 } 879 807 880 - if (mc->x > c->pos_x) { 808 + if (mc->x > oi->pos_x) { 881 809 x = 0; 882 - outw -= (mc->x - c->pos_x); 883 - paddr += (mc->x - c->pos_x) * 810 + outw -= (mc->x - oi->pos_x); 811 + paddr += (mc->x - oi->pos_x) * 884 812 scale_x_m / scale_x_d * bpp / 8; 885 813 } else { 886 - x = c->pos_x - mc->x; 814 + x = oi->pos_x - mc->x; 887 815 } 888 816 889 - if (mc->y > c->pos_y) { 817 + if (mc->y > oi->pos_y) { 890 818 y = 0; 891 - outh -= (mc->y - c->pos_y); 892 - paddr += (mc->y - c->pos_y) * 819 + outh -= (mc->y - oi->pos_y); 820 + paddr += (mc->y - oi->pos_y) * 893 821 scale_y_m / scale_y_d * 894 - c->screen_width * bpp / 8; 822 + oi->screen_width * bpp / 8; 895 823 } else { 896 - y = c->pos_y - mc->y; 824 + y = oi->pos_y - mc->y; 897 825 } 898 826 899 827 if (mc->w < (x + outw)) ··· 912 840 * the width if the original width was bigger. 913 841 */ 914 842 if ((w & 1) && 915 - (c->color_mode == OMAP_DSS_COLOR_YUV2 || 916 - c->color_mode == OMAP_DSS_COLOR_UYVY)) { 843 + (oi->color_mode == OMAP_DSS_COLOR_YUV2 || 844 + oi->color_mode == OMAP_DSS_COLOR_UYVY)) { 917 845 if (orig_w > w) 918 846 w += 1; 919 847 else ··· 923 851 924 852 r = dispc_setup_plane(plane, 925 853 paddr, 926 - c->screen_width, 854 + oi->screen_width, 927 855 x, y, 928 856 w, h, 929 857 outw, outh, 930 - c->color_mode, 858 + oi->color_mode, 931 859 c->ilace, 932 - c->rotation_type, 933 - c->rotation, 934 - c->mirror, 935 - c->global_alpha, 936 - c->pre_mult_alpha, 860 + oi->rotation_type, 861 + oi->rotation, 862 + oi->mirror, 863 + oi->global_alpha, 864 + oi->pre_mult_alpha, 937 865 c->channel, 938 - c->p_uv_addr); 866 + oi->p_uv_addr); 939 867 940 868 if (r) { 941 869 /* this shouldn't happen */ ··· 946 874 947 875 dispc_enable_replication(plane, c->replication); 948 876 949 - dispc_set_burst_size(plane, c->burst_size); 950 - dispc_setup_plane_fifo(plane, c->fifo_low, c->fifo_high); 877 + dispc_set_fifo_threshold(plane, c->fifo_low, c->fifo_high); 951 878 952 879 dispc_enable_plane(plane, 1); 953 880 ··· 955 884 956 885 static void configure_manager(enum omap_channel channel) 957 886 { 958 - struct manager_cache_data *c; 887 + struct omap_overlay_manager_info *mi; 959 888 960 889 DSSDBGF("%d", channel); 961 890 962 - c = &dss_cache.manager_cache[channel]; 891 + /* picking info from the cache */ 892 + mi = &dss_cache.manager_cache[channel].info; 963 893 964 - dispc_set_default_color(channel, c->default_color); 965 - dispc_set_trans_key(channel, c->trans_key_type, c->trans_key); 966 - dispc_enable_trans_key(channel, c->trans_enabled); 967 - dispc_enable_alpha_blending(channel, c->alpha_enabled); 894 + dispc_set_default_color(channel, mi->default_color); 895 + dispc_set_trans_key(channel, mi->trans_key_type, mi->trans_key); 896 + dispc_enable_trans_key(channel, mi->trans_enabled); 897 + dispc_enable_alpha_blending(channel, mi->alpha_enabled); 898 + if (dss_has_feature(FEAT_CPR)) { 899 + dispc_enable_cpr(channel, mi->cpr_enable); 900 + dispc_set_cpr_coef(channel, &mi->cpr_coefs); 901 + } 968 902 } 969 903 970 904 /* configure_dispc() tries to write values from cache to shadow registers. ··· 1004 928 if (!oc->dirty) 1005 929 continue; 1006 930 1007 - if (oc->manual_update && !mc->do_manual_update) 931 + if (mc->manual_update && !mc->do_manual_update) 1008 932 continue; 1009 933 1010 934 if (mgr_busy[oc->channel]) { ··· 1052 976 /* We don't need GO with manual update display. LCD iface will 1053 977 * always be turned off after frame, and new settings will be 1054 978 * taken in to use at next update */ 1055 - if (!mc->manual_upd_display) 979 + if (!mc->manual_update) 1056 980 dispc_go(i); 1057 981 } 1058 982 ··· 1087 1011 { 1088 1012 struct overlay_cache_data *oc; 1089 1013 struct manager_cache_data *mc; 1014 + struct omap_overlay_info *oi; 1090 1015 const int num_ovls = dss_feat_get_num_ovls(); 1091 1016 struct omap_overlay_manager *mgr; 1092 1017 int i; ··· 1130 1053 unsigned outw, outh; 1131 1054 1132 1055 oc = &dss_cache.overlay_cache[i]; 1056 + oi = &oc->info; 1133 1057 1134 1058 if (oc->channel != mgr->id) 1135 1059 continue; ··· 1146 1068 if (!dispc_is_overlay_scaled(oc)) 1147 1069 continue; 1148 1070 1149 - outw = oc->out_width == 0 ? 1150 - oc->width : oc->out_width; 1151 - outh = oc->out_height == 0 ? 1152 - oc->height : oc->out_height; 1071 + outw = oi->out_width == 0 ? 1072 + oi->width : oi->out_width; 1073 + outh = oi->out_height == 0 ? 1074 + oi->height : oi->out_height; 1153 1075 1154 1076 /* is the overlay outside the update region? */ 1155 1077 if (!rectangle_intersects(x, y, w, h, 1156 - oc->pos_x, oc->pos_y, 1078 + oi->pos_x, oi->pos_y, 1157 1079 outw, outh)) 1158 1080 continue; 1159 1081 1160 1082 /* if the overlay totally inside the update region? */ 1161 - if (rectangle_subset(oc->pos_x, oc->pos_y, outw, outh, 1083 + if (rectangle_subset(oi->pos_x, oi->pos_y, outw, outh, 1162 1084 x, y, w, h)) 1163 1085 continue; 1164 1086 1165 - if (x > oc->pos_x) 1166 - x1 = oc->pos_x; 1087 + if (x > oi->pos_x) 1088 + x1 = oi->pos_x; 1167 1089 else 1168 1090 x1 = x; 1169 1091 1170 - if (y > oc->pos_y) 1171 - y1 = oc->pos_y; 1092 + if (y > oi->pos_y) 1093 + y1 = oi->pos_y; 1172 1094 else 1173 1095 y1 = y; 1174 1096 1175 - if ((x + w) < (oc->pos_x + outw)) 1176 - x2 = oc->pos_x + outw; 1097 + if ((x + w) < (oi->pos_x + outw)) 1098 + x2 = oi->pos_x + outw; 1177 1099 else 1178 1100 x2 = x + w; 1179 1101 1180 - if ((y + h) < (oc->pos_y + outh)) 1181 - y2 = oc->pos_y + outh; 1102 + if ((y + h) < (oi->pos_y + outh)) 1103 + y2 = oi->pos_y + outh; 1182 1104 else 1183 1105 y2 = y + h; 1184 1106 ··· 1314 1236 1315 1237 DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name); 1316 1238 1239 + r = dispc_runtime_get(); 1240 + if (r) 1241 + return r; 1242 + 1317 1243 spin_lock_irqsave(&dss_cache.lock, flags); 1318 1244 1319 1245 /* Configure overlays */ ··· 1357 1275 1358 1276 ovl->info_dirty = false; 1359 1277 oc->dirty = true; 1360 - 1361 - oc->paddr = ovl->info.paddr; 1362 - oc->vaddr = ovl->info.vaddr; 1363 - oc->p_uv_addr = ovl->info.p_uv_addr; 1364 - oc->screen_width = ovl->info.screen_width; 1365 - oc->width = ovl->info.width; 1366 - oc->height = ovl->info.height; 1367 - oc->color_mode = ovl->info.color_mode; 1368 - oc->rotation = ovl->info.rotation; 1369 - oc->rotation_type = ovl->info.rotation_type; 1370 - oc->mirror = ovl->info.mirror; 1371 - oc->pos_x = ovl->info.pos_x; 1372 - oc->pos_y = ovl->info.pos_y; 1373 - oc->out_width = ovl->info.out_width; 1374 - oc->out_height = ovl->info.out_height; 1375 - oc->global_alpha = ovl->info.global_alpha; 1376 - oc->pre_mult_alpha = ovl->info.pre_mult_alpha; 1278 + oc->info = ovl->info; 1377 1279 1378 1280 oc->replication = 1379 1281 dss_use_replication(dssdev, ovl->info.color_mode); ··· 1367 1301 oc->channel = ovl->manager->id; 1368 1302 1369 1303 oc->enabled = true; 1370 - 1371 - oc->manual_update = 1372 - dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE && 1373 - dssdev->driver->get_update_mode(dssdev) != 1374 - OMAP_DSS_UPDATE_AUTO; 1375 1304 1376 1305 ++num_planes_enabled; 1377 1306 } ··· 1395 1334 1396 1335 mgr->info_dirty = false; 1397 1336 mc->dirty = true; 1398 - 1399 - mc->default_color = mgr->info.default_color; 1400 - mc->trans_key_type = mgr->info.trans_key_type; 1401 - mc->trans_key = mgr->info.trans_key; 1402 - mc->trans_enabled = mgr->info.trans_enabled; 1403 - mc->alpha_enabled = mgr->info.alpha_enabled; 1404 - 1405 - mc->manual_upd_display = 1406 - dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 1337 + mc->info = mgr->info; 1407 1338 1408 1339 mc->manual_update = 1409 - dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE && 1410 - dssdev->driver->get_update_mode(dssdev) != 1411 - OMAP_DSS_UPDATE_AUTO; 1340 + dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 1412 1341 } 1413 1342 1414 1343 /* XXX TODO: Try to get fifomerge working. The problem is that it ··· 1419 1368 /* Configure overlay fifos */ 1420 1369 for (i = 0; i < omap_dss_get_num_overlays(); ++i) { 1421 1370 struct omap_dss_device *dssdev; 1422 - u32 size; 1371 + u32 size, burst_size; 1423 1372 1424 1373 ovl = omap_dss_get_overlay(i); 1425 1374 ··· 1437 1386 if (use_fifomerge) 1438 1387 size *= 3; 1439 1388 1389 + burst_size = dispc_get_burst_size(ovl->id); 1390 + 1440 1391 switch (dssdev->type) { 1441 1392 case OMAP_DISPLAY_TYPE_DPI: 1442 1393 case OMAP_DISPLAY_TYPE_DBI: ··· 1446 1393 case OMAP_DISPLAY_TYPE_VENC: 1447 1394 case OMAP_DISPLAY_TYPE_HDMI: 1448 1395 default_get_overlay_fifo_thresholds(ovl->id, size, 1449 - &oc->burst_size, &oc->fifo_low, 1396 + burst_size, &oc->fifo_low, 1450 1397 &oc->fifo_high); 1451 1398 break; 1452 1399 #ifdef CONFIG_OMAP2_DSS_DSI 1453 1400 case OMAP_DISPLAY_TYPE_DSI: 1454 1401 dsi_get_overlay_fifo_thresholds(ovl->id, size, 1455 - &oc->burst_size, &oc->fifo_low, 1402 + burst_size, &oc->fifo_low, 1456 1403 &oc->fifo_high); 1457 1404 break; 1458 1405 #endif ··· 1462 1409 } 1463 1410 1464 1411 r = 0; 1465 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 1466 1412 if (!dss_cache.irq_enabled) { 1467 1413 u32 mask; 1468 1414 ··· 1474 1422 dss_cache.irq_enabled = true; 1475 1423 } 1476 1424 configure_dispc(); 1477 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 1478 1425 1479 1426 spin_unlock_irqrestore(&dss_cache.lock, flags); 1427 + 1428 + dispc_runtime_put(); 1480 1429 1481 1430 return r; 1482 1431 }
+21 -6
drivers/video/omap2/dss/overlay.c
··· 84 84 85 85 old_mgr = ovl->manager; 86 86 87 + r = dispc_runtime_get(); 88 + if (r) 89 + return r; 90 + 87 91 /* detach old manager */ 88 92 if (old_mgr) { 89 93 r = ovl->unset_manager(ovl); 90 94 if (r) { 91 95 DSSERR("detach failed\n"); 92 - return r; 96 + goto err; 93 97 } 94 98 95 99 r = old_mgr->apply(old_mgr); 96 100 if (r) 97 - return r; 101 + goto err; 98 102 } 99 103 100 104 if (mgr) { 101 105 r = ovl->set_manager(ovl, mgr); 102 106 if (r) { 103 107 DSSERR("Failed to attach overlay\n"); 104 - return r; 108 + goto err; 105 109 } 106 110 107 111 r = mgr->apply(mgr); 108 112 if (r) 109 - return r; 113 + goto err; 110 114 } 111 115 116 + dispc_runtime_put(); 117 + 112 118 return size; 119 + 120 + err: 121 + dispc_runtime_put(); 122 + return r; 113 123 } 114 124 115 125 static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf) ··· 247 237 int r; 248 238 u8 alpha; 249 239 struct omap_overlay_info info; 240 + 241 + if (!dss_has_feature(FEAT_GLOBAL_ALPHA)) 242 + return -ENODEV; 250 243 251 244 r = kstrtou8(buf, 0, &alpha); 252 245 if (r) ··· 517 504 518 505 ovl->manager = mgr; 519 506 520 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 521 507 /* XXX: When there is an overlay on a DSI manual update display, and 522 508 * the overlay is first disabled, then moved to tv, and enabled, we 523 509 * seem to get SYNC_LOST_DIGIT error. ··· 530 518 * the overlay, but before moving the overlay to TV. 531 519 */ 532 520 dispc_set_channel_out(ovl->id, mgr->id); 533 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 534 521 535 522 return 0; 536 523 } ··· 730 719 } 731 720 732 721 if (mgr) { 722 + dispc_runtime_get(); 723 + 733 724 for (i = 0; i < dss_feat_get_num_ovls(); i++) { 734 725 struct omap_overlay *ovl; 735 726 ovl = omap_dss_get_overlay(i); ··· 741 728 omap_dss_set_manager(ovl, mgr); 742 729 } 743 730 } 731 + 732 + dispc_runtime_put(); 744 733 } 745 734 } 746 735
+95 -19
drivers/video/omap2/dss/rfbi.c
··· 33 33 #include <linux/hrtimer.h> 34 34 #include <linux/seq_file.h> 35 35 #include <linux/semaphore.h> 36 + #include <linux/platform_device.h> 37 + #include <linux/pm_runtime.h> 36 38 37 39 #include <video/omapdss.h> 38 40 #include "dss.h" ··· 122 120 return __raw_readl(rfbi.base + idx.idx); 123 121 } 124 122 125 - static void rfbi_enable_clocks(bool enable) 123 + static int rfbi_runtime_get(void) 126 124 { 127 - if (enable) 128 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 129 - else 130 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 125 + int r; 126 + 127 + DSSDBG("rfbi_runtime_get\n"); 128 + 129 + r = pm_runtime_get_sync(&rfbi.pdev->dev); 130 + WARN_ON(r < 0); 131 + return r < 0 ? r : 0; 132 + } 133 + 134 + static void rfbi_runtime_put(void) 135 + { 136 + int r; 137 + 138 + DSSDBG("rfbi_runtime_put\n"); 139 + 140 + r = pm_runtime_put(&rfbi.pdev->dev); 141 + WARN_ON(r < 0); 131 142 } 132 143 133 144 void rfbi_bus_lock(void) ··· 820 805 { 821 806 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) 822 807 823 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 808 + if (rfbi_runtime_get()) 809 + return; 824 810 825 811 DUMPREG(RFBI_REVISION); 826 812 DUMPREG(RFBI_SYSCONFIG); ··· 852 836 DUMPREG(RFBI_VSYNC_WIDTH); 853 837 DUMPREG(RFBI_HSYNC_WIDTH); 854 838 855 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 839 + rfbi_runtime_put(); 856 840 #undef DUMPREG 857 841 } 858 842 ··· 860 844 { 861 845 int r; 862 846 863 - rfbi_enable_clocks(1); 847 + r = rfbi_runtime_get(); 848 + if (r) 849 + return r; 864 850 865 851 r = omap_dss_start_device(dssdev); 866 852 if (r) { ··· 897 879 err1: 898 880 omap_dss_stop_device(dssdev); 899 881 err0: 882 + rfbi_runtime_put(); 900 883 return r; 901 884 } 902 885 EXPORT_SYMBOL(omapdss_rfbi_display_enable); ··· 908 889 DISPC_IRQ_FRAMEDONE); 909 890 omap_dss_stop_device(dssdev); 910 891 911 - rfbi_enable_clocks(0); 892 + rfbi_runtime_put(); 912 893 } 913 894 EXPORT_SYMBOL(omapdss_rfbi_display_disable); 914 895 ··· 923 904 static int omap_rfbihw_probe(struct platform_device *pdev) 924 905 { 925 906 u32 rev; 926 - u32 l; 927 907 struct resource *rfbi_mem; 908 + struct clk *clk; 909 + int r; 928 910 929 911 rfbi.pdev = pdev; 930 912 ··· 934 914 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0); 935 915 if (!rfbi_mem) { 936 916 DSSERR("can't get IORESOURCE_MEM RFBI\n"); 937 - return -EINVAL; 917 + r = -EINVAL; 918 + goto err_ioremap; 938 919 } 939 920 rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem)); 940 921 if (!rfbi.base) { 941 922 DSSERR("can't ioremap RFBI\n"); 942 - return -ENOMEM; 923 + r = -ENOMEM; 924 + goto err_ioremap; 943 925 } 944 926 945 - rfbi_enable_clocks(1); 927 + pm_runtime_enable(&pdev->dev); 928 + 929 + r = rfbi_runtime_get(); 930 + if (r) 931 + goto err_get_rfbi; 946 932 947 933 msleep(10); 948 934 949 - rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000; 935 + if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap3630()) 936 + clk = dss_get_ick(); 937 + else 938 + clk = clk_get(&pdev->dev, "ick"); 939 + if (IS_ERR(clk)) { 940 + DSSERR("can't get ick\n"); 941 + r = PTR_ERR(clk); 942 + goto err_get_ick; 943 + } 950 944 951 - /* Enable autoidle and smart-idle */ 952 - l = rfbi_read_reg(RFBI_SYSCONFIG); 953 - l |= (1 << 0) | (2 << 3); 954 - rfbi_write_reg(RFBI_SYSCONFIG, l); 945 + rfbi.l4_khz = clk_get_rate(clk) / 1000; 946 + 947 + clk_put(clk); 955 948 956 949 rev = rfbi_read_reg(RFBI_REVISION); 957 950 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n", 958 951 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 959 952 960 - rfbi_enable_clocks(0); 953 + rfbi_runtime_put(); 961 954 962 955 return 0; 956 + 957 + err_get_ick: 958 + rfbi_runtime_put(); 959 + err_get_rfbi: 960 + pm_runtime_disable(&pdev->dev); 961 + iounmap(rfbi.base); 962 + err_ioremap: 963 + return r; 963 964 } 964 965 965 966 static int omap_rfbihw_remove(struct platform_device *pdev) 966 967 { 968 + pm_runtime_disable(&pdev->dev); 967 969 iounmap(rfbi.base); 968 970 return 0; 969 971 } 972 + 973 + static int rfbi_runtime_suspend(struct device *dev) 974 + { 975 + dispc_runtime_put(); 976 + dss_runtime_put(); 977 + 978 + return 0; 979 + } 980 + 981 + static int rfbi_runtime_resume(struct device *dev) 982 + { 983 + int r; 984 + 985 + r = dss_runtime_get(); 986 + if (r < 0) 987 + goto err_get_dss; 988 + 989 + r = dispc_runtime_get(); 990 + if (r < 0) 991 + goto err_get_dispc; 992 + 993 + return 0; 994 + 995 + err_get_dispc: 996 + dss_runtime_put(); 997 + err_get_dss: 998 + return r; 999 + } 1000 + 1001 + static const struct dev_pm_ops rfbi_pm_ops = { 1002 + .runtime_suspend = rfbi_runtime_suspend, 1003 + .runtime_resume = rfbi_runtime_resume, 1004 + }; 970 1005 971 1006 static struct platform_driver omap_rfbihw_driver = { 972 1007 .probe = omap_rfbihw_probe, ··· 1029 954 .driver = { 1030 955 .name = "omapdss_rfbi", 1031 956 .owner = THIS_MODULE, 957 + .pm = &rfbi_pm_ops, 1032 958 }, 1033 959 }; 1034 960
+26 -14
drivers/video/omap2/dss/sdi.c
··· 20 20 #define DSS_SUBSYS_NAME "SDI" 21 21 22 22 #include <linux/kernel.h> 23 - #include <linux/clk.h> 24 23 #include <linux/delay.h> 25 24 #include <linux/err.h> 26 25 #include <linux/regulator/consumer.h> 27 26 28 27 #include <video/omapdss.h> 29 - #include <plat/cpu.h> 30 28 #include "dss.h" 31 29 32 30 static struct { ··· 58 60 r = omap_dss_start_device(dssdev); 59 61 if (r) { 60 62 DSSERR("failed to start device\n"); 61 - goto err0; 63 + goto err_start_dev; 62 64 } 63 65 64 66 r = regulator_enable(sdi.vdds_sdi_reg); 65 67 if (r) 66 - goto err1; 68 + goto err_reg_enable; 67 69 68 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 70 + r = dss_runtime_get(); 71 + if (r) 72 + goto err_get_dss; 73 + 74 + r = dispc_runtime_get(); 75 + if (r) 76 + goto err_get_dispc; 69 77 70 78 sdi_basic_init(dssdev); 71 79 ··· 84 80 r = dss_calc_clock_div(1, t->pixel_clock * 1000, 85 81 &dss_cinfo, &dispc_cinfo); 86 82 if (r) 87 - goto err2; 83 + goto err_calc_clock_div; 88 84 89 85 fck = dss_cinfo.fck; 90 86 lck_div = dispc_cinfo.lck_div; ··· 105 101 106 102 r = dss_set_clock_div(&dss_cinfo); 107 103 if (r) 108 - goto err2; 104 + goto err_set_dss_clock_div; 109 105 110 106 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); 111 107 if (r) 112 - goto err2; 108 + goto err_set_dispc_clock_div; 113 109 114 110 dss_sdi_init(dssdev->phy.sdi.datapairs); 115 111 r = dss_sdi_enable(); 116 112 if (r) 117 - goto err1; 113 + goto err_sdi_enable; 118 114 mdelay(2); 119 115 120 116 dssdev->manager->enable(dssdev->manager); 121 117 122 118 return 0; 123 - err2: 124 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 119 + 120 + err_sdi_enable: 121 + err_set_dispc_clock_div: 122 + err_set_dss_clock_div: 123 + err_calc_clock_div: 124 + dispc_runtime_put(); 125 + err_get_dispc: 126 + dss_runtime_put(); 127 + err_get_dss: 125 128 regulator_disable(sdi.vdds_sdi_reg); 126 - err1: 129 + err_reg_enable: 127 130 omap_dss_stop_device(dssdev); 128 - err0: 131 + err_start_dev: 129 132 return r; 130 133 } 131 134 EXPORT_SYMBOL(omapdss_sdi_display_enable); ··· 143 132 144 133 dss_sdi_disable(); 145 134 146 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 135 + dispc_runtime_put(); 136 + dss_runtime_put(); 147 137 148 138 regulator_disable(sdi.vdds_sdi_reg); 149 139
+146 -37
drivers/video/omap2/dss/venc.c
··· 33 33 #include <linux/seq_file.h> 34 34 #include <linux/platform_device.h> 35 35 #include <linux/regulator/consumer.h> 36 + #include <linux/pm_runtime.h> 36 37 37 38 #include <video/omapdss.h> 38 39 #include <plat/cpu.h> 39 40 40 41 #include "dss.h" 42 + #include "dss_features.h" 41 43 42 44 /* Venc registers */ 43 45 #define VENC_REV_ID 0x00 ··· 294 292 struct mutex venc_lock; 295 293 u32 wss_data; 296 294 struct regulator *vdda_dac_reg; 295 + 296 + struct clk *tv_clk; 297 + struct clk *tv_dac_clk; 297 298 } venc; 298 299 299 300 static inline void venc_write_reg(int idx, u32 val) ··· 385 380 #endif 386 381 } 387 382 388 - static void venc_enable_clocks(int enable) 383 + static int venc_runtime_get(void) 389 384 { 390 - if (enable) 391 - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK | 392 - DSS_CLK_VIDFCK); 393 - else 394 - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK | 395 - DSS_CLK_VIDFCK); 385 + int r; 386 + 387 + DSSDBG("venc_runtime_get\n"); 388 + 389 + r = pm_runtime_get_sync(&venc.pdev->dev); 390 + WARN_ON(r < 0); 391 + return r < 0 ? r : 0; 392 + } 393 + 394 + static void venc_runtime_put(void) 395 + { 396 + int r; 397 + 398 + DSSDBG("venc_runtime_put\n"); 399 + 400 + r = pm_runtime_put(&venc.pdev->dev); 401 + WARN_ON(r < 0); 396 402 } 397 403 398 404 static const struct venc_config *venc_timings_to_config( ··· 421 405 static void venc_power_on(struct omap_dss_device *dssdev) 422 406 { 423 407 u32 l; 424 - 425 - venc_enable_clocks(1); 426 408 427 409 venc_reset(); 428 410 venc_write_config(venc_timings_to_config(&dssdev->panel.timings)); ··· 462 448 dssdev->platform_disable(dssdev); 463 449 464 450 regulator_disable(venc.vdda_dac_reg); 465 - 466 - venc_enable_clocks(0); 467 451 } 468 452 469 453 ··· 499 487 goto err1; 500 488 } 501 489 490 + r = venc_runtime_get(); 491 + if (r) 492 + goto err1; 493 + 502 494 venc_power_on(dssdev); 503 495 504 496 venc.wss_data = 0; ··· 536 520 537 521 venc_power_off(dssdev); 538 522 523 + venc_runtime_put(); 524 + 539 525 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 540 526 541 527 omap_dss_stop_device(dssdev); ··· 554 536 static int venc_panel_resume(struct omap_dss_device *dssdev) 555 537 { 556 538 return venc_panel_enable(dssdev); 557 - } 558 - 559 - static enum omap_dss_update_mode venc_get_update_mode( 560 - struct omap_dss_device *dssdev) 561 - { 562 - return OMAP_DSS_UPDATE_AUTO; 563 - } 564 - 565 - static int venc_set_update_mode(struct omap_dss_device *dssdev, 566 - enum omap_dss_update_mode mode) 567 - { 568 - if (mode != OMAP_DSS_UPDATE_AUTO) 569 - return -EINVAL; 570 - return 0; 571 539 } 572 540 573 541 static void venc_get_timings(struct omap_dss_device *dssdev, ··· 602 598 static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss) 603 599 { 604 600 const struct venc_config *config; 601 + int r; 605 602 606 603 DSSDBG("venc_set_wss\n"); 607 604 ··· 613 608 /* Invert due to VENC_L21_WC_CTL:INV=1 */ 614 609 venc.wss_data = (wss ^ 0xfffff) << 8; 615 610 616 - venc_enable_clocks(1); 611 + r = venc_runtime_get(); 612 + if (r) 613 + goto err; 617 614 618 615 venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data | 619 616 venc.wss_data); 620 617 621 - venc_enable_clocks(0); 618 + venc_runtime_put(); 622 619 620 + err: 623 621 mutex_unlock(&venc.venc_lock); 624 622 625 - return 0; 623 + return r; 626 624 } 627 625 628 626 static struct omap_dss_driver venc_driver = { ··· 639 631 640 632 .get_resolution = omapdss_default_get_resolution, 641 633 .get_recommended_bpp = omapdss_default_get_recommended_bpp, 642 - 643 - .set_update_mode = venc_set_update_mode, 644 - .get_update_mode = venc_get_update_mode, 645 634 646 635 .get_timings = venc_get_timings, 647 636 .set_timings = venc_set_timings, ··· 678 673 { 679 674 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r)) 680 675 681 - venc_enable_clocks(1); 676 + if (venc_runtime_get()) 677 + return; 682 678 683 679 DUMPREG(VENC_F_CONTROL); 684 680 DUMPREG(VENC_VIDOUT_CTRL); ··· 723 717 DUMPREG(VENC_OUTPUT_CONTROL); 724 718 DUMPREG(VENC_OUTPUT_TEST); 725 719 726 - venc_enable_clocks(0); 720 + venc_runtime_put(); 727 721 728 722 #undef DUMPREG 723 + } 724 + 725 + static int venc_get_clocks(struct platform_device *pdev) 726 + { 727 + struct clk *clk; 728 + 729 + clk = clk_get(&pdev->dev, "fck"); 730 + if (IS_ERR(clk)) { 731 + DSSERR("can't get fck\n"); 732 + return PTR_ERR(clk); 733 + } 734 + 735 + venc.tv_clk = clk; 736 + 737 + if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK)) { 738 + if (cpu_is_omap34xx() || cpu_is_omap3630()) 739 + clk = clk_get(&pdev->dev, "dss_96m_fck"); 740 + else 741 + clk = clk_get(&pdev->dev, "tv_dac_clk"); 742 + if (IS_ERR(clk)) { 743 + DSSERR("can't get tv_dac_clk\n"); 744 + clk_put(venc.tv_clk); 745 + return PTR_ERR(clk); 746 + } 747 + } else { 748 + clk = NULL; 749 + } 750 + 751 + venc.tv_dac_clk = clk; 752 + 753 + return 0; 754 + } 755 + 756 + static void venc_put_clocks(void) 757 + { 758 + if (venc.tv_clk) 759 + clk_put(venc.tv_clk); 760 + if (venc.tv_dac_clk) 761 + clk_put(venc.tv_dac_clk); 729 762 } 730 763 731 764 /* VENC HW IP initialisation */ ··· 772 727 { 773 728 u8 rev_id; 774 729 struct resource *venc_mem; 730 + int r; 775 731 776 732 venc.pdev = pdev; 777 733 ··· 783 737 venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0); 784 738 if (!venc_mem) { 785 739 DSSERR("can't get IORESOURCE_MEM VENC\n"); 786 - return -EINVAL; 740 + r = -EINVAL; 741 + goto err_ioremap; 787 742 } 788 743 venc.base = ioremap(venc_mem->start, resource_size(venc_mem)); 789 744 if (!venc.base) { 790 745 DSSERR("can't ioremap VENC\n"); 791 - return -ENOMEM; 746 + r = -ENOMEM; 747 + goto err_ioremap; 792 748 } 793 749 794 - venc_enable_clocks(1); 750 + r = venc_get_clocks(pdev); 751 + if (r) 752 + goto err_get_clk; 753 + 754 + pm_runtime_enable(&pdev->dev); 755 + 756 + r = venc_runtime_get(); 757 + if (r) 758 + goto err_get_venc; 795 759 796 760 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff); 797 761 dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id); 798 762 799 - venc_enable_clocks(0); 763 + venc_runtime_put(); 800 764 801 765 return omap_dss_register_driver(&venc_driver); 766 + 767 + err_get_venc: 768 + pm_runtime_disable(&pdev->dev); 769 + venc_put_clocks(); 770 + err_get_clk: 771 + iounmap(venc.base); 772 + err_ioremap: 773 + return r; 802 774 } 803 775 804 776 static int omap_venchw_remove(struct platform_device *pdev) ··· 827 763 } 828 764 omap_dss_unregister_driver(&venc_driver); 829 765 766 + pm_runtime_disable(&pdev->dev); 767 + venc_put_clocks(); 768 + 830 769 iounmap(venc.base); 831 770 return 0; 832 771 } 772 + 773 + static int venc_runtime_suspend(struct device *dev) 774 + { 775 + if (venc.tv_dac_clk) 776 + clk_disable(venc.tv_dac_clk); 777 + clk_disable(venc.tv_clk); 778 + 779 + dispc_runtime_put(); 780 + dss_runtime_put(); 781 + 782 + return 0; 783 + } 784 + 785 + static int venc_runtime_resume(struct device *dev) 786 + { 787 + int r; 788 + 789 + r = dss_runtime_get(); 790 + if (r < 0) 791 + goto err_get_dss; 792 + 793 + r = dispc_runtime_get(); 794 + if (r < 0) 795 + goto err_get_dispc; 796 + 797 + clk_enable(venc.tv_clk); 798 + if (venc.tv_dac_clk) 799 + clk_enable(venc.tv_dac_clk); 800 + 801 + return 0; 802 + 803 + err_get_dispc: 804 + dss_runtime_put(); 805 + err_get_dss: 806 + return r; 807 + } 808 + 809 + static const struct dev_pm_ops venc_pm_ops = { 810 + .runtime_suspend = venc_runtime_suspend, 811 + .runtime_resume = venc_runtime_resume, 812 + }; 833 813 834 814 static struct platform_driver omap_venchw_driver = { 835 815 .probe = omap_venchw_probe, ··· 881 773 .driver = { 882 774 .name = "omapdss_venc", 883 775 .owner = THIS_MODULE, 776 + .pm = &venc_pm_ops, 884 777 }, 885 778 }; 886 779
+48 -48
drivers/video/omap2/omapfb/omapfb-ioctl.c
··· 316 316 } 317 317 EXPORT_SYMBOL(omapfb_update_window); 318 318 319 - static int omapfb_set_update_mode(struct fb_info *fbi, 319 + int omapfb_set_update_mode(struct fb_info *fbi, 320 320 enum omapfb_update_mode mode) 321 321 { 322 322 struct omap_dss_device *display = fb2display(fbi); 323 - enum omap_dss_update_mode um; 323 + struct omapfb_info *ofbi = FB2OFB(fbi); 324 + struct omapfb2_device *fbdev = ofbi->fbdev; 325 + struct omapfb_display_data *d; 324 326 int r; 325 - 326 - if (!display || !display->driver->set_update_mode) 327 - return -EINVAL; 328 - 329 - switch (mode) { 330 - case OMAPFB_UPDATE_DISABLED: 331 - um = OMAP_DSS_UPDATE_DISABLED; 332 - break; 333 - 334 - case OMAPFB_AUTO_UPDATE: 335 - um = OMAP_DSS_UPDATE_AUTO; 336 - break; 337 - 338 - case OMAPFB_MANUAL_UPDATE: 339 - um = OMAP_DSS_UPDATE_MANUAL; 340 - break; 341 - 342 - default: 343 - return -EINVAL; 344 - } 345 - 346 - r = display->driver->set_update_mode(display, um); 347 - 348 - return r; 349 - } 350 - 351 - static int omapfb_get_update_mode(struct fb_info *fbi, 352 - enum omapfb_update_mode *mode) 353 - { 354 - struct omap_dss_device *display = fb2display(fbi); 355 - enum omap_dss_update_mode m; 356 327 357 328 if (!display) 358 329 return -EINVAL; 359 330 360 - if (!display->driver->get_update_mode) { 361 - *mode = OMAPFB_AUTO_UPDATE; 331 + if (mode != OMAPFB_AUTO_UPDATE && mode != OMAPFB_MANUAL_UPDATE) 332 + return -EINVAL; 333 + 334 + omapfb_lock(fbdev); 335 + 336 + d = get_display_data(fbdev, display); 337 + 338 + if (d->update_mode == mode) { 339 + omapfb_unlock(fbdev); 362 340 return 0; 363 341 } 364 342 365 - m = display->driver->get_update_mode(display); 343 + r = 0; 366 344 367 - switch (m) { 368 - case OMAP_DSS_UPDATE_DISABLED: 369 - *mode = OMAPFB_UPDATE_DISABLED; 370 - break; 371 - case OMAP_DSS_UPDATE_AUTO: 372 - *mode = OMAPFB_AUTO_UPDATE; 373 - break; 374 - case OMAP_DSS_UPDATE_MANUAL: 375 - *mode = OMAPFB_MANUAL_UPDATE; 376 - break; 377 - default: 378 - BUG(); 345 + if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 346 + if (mode == OMAPFB_AUTO_UPDATE) 347 + omapfb_start_auto_update(fbdev, display); 348 + else /* MANUAL_UPDATE */ 349 + omapfb_stop_auto_update(fbdev, display); 350 + 351 + d->update_mode = mode; 352 + } else { /* AUTO_UPDATE */ 353 + if (mode == OMAPFB_MANUAL_UPDATE) 354 + r = -EINVAL; 379 355 } 356 + 357 + omapfb_unlock(fbdev); 358 + 359 + return r; 360 + } 361 + 362 + int omapfb_get_update_mode(struct fb_info *fbi, 363 + enum omapfb_update_mode *mode) 364 + { 365 + struct omap_dss_device *display = fb2display(fbi); 366 + struct omapfb_info *ofbi = FB2OFB(fbi); 367 + struct omapfb2_device *fbdev = ofbi->fbdev; 368 + struct omapfb_display_data *d; 369 + 370 + if (!display) 371 + return -EINVAL; 372 + 373 + omapfb_lock(fbdev); 374 + 375 + d = get_display_data(fbdev, display); 376 + 377 + *mode = d->update_mode; 378 + 379 + omapfb_unlock(fbdev); 380 380 381 381 return 0; 382 382 }
+133 -33
drivers/video/omap2/omapfb/omapfb-main.c
··· 46 46 static int def_vrfb; 47 47 static int def_rotate; 48 48 static int def_mirror; 49 + static bool auto_update; 50 + static unsigned int auto_update_freq; 51 + module_param(auto_update, bool, 0); 52 + module_param(auto_update_freq, uint, 0644); 49 53 50 54 #ifdef DEBUG 51 55 unsigned int omapfb_debug; ··· 1246 1242 struct omapfb_info *ofbi = FB2OFB(fbi); 1247 1243 struct omapfb2_device *fbdev = ofbi->fbdev; 1248 1244 struct omap_dss_device *display = fb2display(fbi); 1245 + struct omapfb_display_data *d; 1249 1246 int r = 0; 1250 1247 1251 1248 if (!display) 1252 1249 return -EINVAL; 1253 1250 1254 1251 omapfb_lock(fbdev); 1252 + 1253 + d = get_display_data(fbdev, display); 1255 1254 1256 1255 switch (blank) { 1257 1256 case FB_BLANK_UNBLANK: ··· 1263 1256 1264 1257 if (display->driver->resume) 1265 1258 r = display->driver->resume(display); 1259 + 1260 + if ((display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) && 1261 + d->update_mode == OMAPFB_AUTO_UPDATE && 1262 + !d->auto_update_work_enabled) 1263 + omapfb_start_auto_update(fbdev, display); 1266 1264 1267 1265 break; 1268 1266 ··· 1279 1267 case FB_BLANK_POWERDOWN: 1280 1268 if (display->state != OMAP_DSS_DISPLAY_ACTIVE) 1281 1269 goto exit; 1270 + 1271 + if (d->auto_update_work_enabled) 1272 + omapfb_stop_auto_update(fbdev, display); 1282 1273 1283 1274 if (display->driver->suspend) 1284 1275 r = display->driver->suspend(display); ··· 1739 1724 return r; 1740 1725 } 1741 1726 1727 + static void omapfb_auto_update_work(struct work_struct *work) 1728 + { 1729 + struct omap_dss_device *dssdev; 1730 + struct omap_dss_driver *dssdrv; 1731 + struct omapfb_display_data *d; 1732 + u16 w, h; 1733 + unsigned int freq; 1734 + struct omapfb2_device *fbdev; 1735 + 1736 + d = container_of(work, struct omapfb_display_data, 1737 + auto_update_work.work); 1738 + 1739 + dssdev = d->dssdev; 1740 + dssdrv = dssdev->driver; 1741 + fbdev = d->fbdev; 1742 + 1743 + if (!dssdrv || !dssdrv->update) 1744 + return; 1745 + 1746 + if (dssdrv->sync) 1747 + dssdrv->sync(dssdev); 1748 + 1749 + dssdrv->get_resolution(dssdev, &w, &h); 1750 + dssdrv->update(dssdev, 0, 0, w, h); 1751 + 1752 + freq = auto_update_freq; 1753 + if (freq == 0) 1754 + freq = 20; 1755 + queue_delayed_work(fbdev->auto_update_wq, 1756 + &d->auto_update_work, HZ / freq); 1757 + } 1758 + 1759 + void omapfb_start_auto_update(struct omapfb2_device *fbdev, 1760 + struct omap_dss_device *display) 1761 + { 1762 + struct omapfb_display_data *d; 1763 + 1764 + if (fbdev->auto_update_wq == NULL) { 1765 + struct workqueue_struct *wq; 1766 + 1767 + wq = create_singlethread_workqueue("omapfb_auto_update"); 1768 + 1769 + if (wq == NULL) { 1770 + dev_err(fbdev->dev, "Failed to create workqueue for " 1771 + "auto-update\n"); 1772 + return; 1773 + } 1774 + 1775 + fbdev->auto_update_wq = wq; 1776 + } 1777 + 1778 + d = get_display_data(fbdev, display); 1779 + 1780 + INIT_DELAYED_WORK(&d->auto_update_work, omapfb_auto_update_work); 1781 + 1782 + d->auto_update_work_enabled = true; 1783 + 1784 + omapfb_auto_update_work(&d->auto_update_work.work); 1785 + } 1786 + 1787 + void omapfb_stop_auto_update(struct omapfb2_device *fbdev, 1788 + struct omap_dss_device *display) 1789 + { 1790 + struct omapfb_display_data *d; 1791 + 1792 + d = get_display_data(fbdev, display); 1793 + 1794 + cancel_delayed_work_sync(&d->auto_update_work); 1795 + 1796 + d->auto_update_work_enabled = false; 1797 + } 1798 + 1742 1799 /* initialize fb_info, var, fix to something sane based on the display */ 1743 1800 static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi) 1744 1801 { ··· 1945 1858 } 1946 1859 1947 1860 for (i = 0; i < fbdev->num_displays; i++) { 1948 - if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED) 1949 - fbdev->displays[i]->driver->disable(fbdev->displays[i]); 1861 + struct omap_dss_device *dssdev = fbdev->displays[i].dssdev; 1950 1862 1951 - omap_dss_put_device(fbdev->displays[i]); 1863 + if (fbdev->displays[i].auto_update_work_enabled) 1864 + omapfb_stop_auto_update(fbdev, dssdev); 1865 + 1866 + if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) 1867 + dssdev->driver->disable(dssdev); 1868 + 1869 + omap_dss_put_device(dssdev); 1870 + } 1871 + 1872 + if (fbdev->auto_update_wq != NULL) { 1873 + flush_workqueue(fbdev->auto_update_wq); 1874 + destroy_workqueue(fbdev->auto_update_wq); 1875 + fbdev->auto_update_wq = NULL; 1952 1876 } 1953 1877 1954 1878 dev_set_drvdata(fbdev->dev, NULL); ··· 2182 2084 int r; 2183 2085 u8 bpp; 2184 2086 struct omap_video_timings timings, temp_timings; 2087 + struct omapfb_display_data *d; 2185 2088 2186 2089 r = omapfb_mode_to_timings(mode_str, &timings, &bpp); 2187 2090 if (r) 2188 2091 return r; 2189 2092 2190 - fbdev->bpp_overrides[fbdev->num_bpp_overrides].dssdev = display; 2191 - fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp; 2192 - ++fbdev->num_bpp_overrides; 2093 + d = get_display_data(fbdev, display); 2094 + d->bpp_override = bpp; 2193 2095 2194 2096 if (display->driver->check_timings) { 2195 2097 r = display->driver->check_timings(display, &timings); ··· 2215 2117 static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev, 2216 2118 struct omap_dss_device *dssdev) 2217 2119 { 2218 - int i; 2120 + struct omapfb_display_data *d; 2219 2121 2220 2122 BUG_ON(dssdev->driver->get_recommended_bpp == NULL); 2221 2123 2222 - for (i = 0; i < fbdev->num_bpp_overrides; ++i) { 2223 - if (dssdev == fbdev->bpp_overrides[i].dssdev) 2224 - return fbdev->bpp_overrides[i].bpp; 2225 - } 2124 + d = get_display_data(fbdev, dssdev); 2125 + 2126 + if (d->bpp_override != 0) 2127 + return d->bpp_override; 2226 2128 2227 2129 return dssdev->driver->get_recommended_bpp(dssdev); 2228 2130 } ··· 2254 2156 2255 2157 display = NULL; 2256 2158 for (i = 0; i < fbdev->num_displays; ++i) { 2257 - if (strcmp(fbdev->displays[i]->name, 2159 + if (strcmp(fbdev->displays[i].dssdev->name, 2258 2160 display_str) == 0) { 2259 - display = fbdev->displays[i]; 2161 + display = fbdev->displays[i].dssdev; 2260 2162 break; 2261 2163 } 2262 2164 } ··· 2280 2182 struct omap_dss_device *dssdev) 2281 2183 { 2282 2184 struct omap_dss_driver *dssdrv = dssdev->driver; 2185 + struct omapfb_display_data *d; 2283 2186 int r; 2284 2187 2285 2188 r = dssdrv->enable(dssdev); ··· 2290 2191 return r; 2291 2192 } 2292 2193 2194 + d = get_display_data(fbdev, dssdev); 2195 + 2196 + d->fbdev = fbdev; 2197 + 2293 2198 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 2294 2199 u16 w, h; 2200 + 2201 + if (auto_update) { 2202 + omapfb_start_auto_update(fbdev, dssdev); 2203 + d->update_mode = OMAPFB_AUTO_UPDATE; 2204 + } else { 2205 + d->update_mode = OMAPFB_MANUAL_UPDATE; 2206 + } 2207 + 2295 2208 if (dssdrv->enable_te) { 2296 2209 r = dssdrv->enable_te(dssdev, 1); 2297 2210 if (r) { 2298 2211 dev_err(fbdev->dev, "Failed to set TE\n"); 2299 - return r; 2300 - } 2301 - } 2302 - 2303 - if (dssdrv->set_update_mode) { 2304 - r = dssdrv->set_update_mode(dssdev, 2305 - OMAP_DSS_UPDATE_MANUAL); 2306 - if (r) { 2307 - dev_err(fbdev->dev, 2308 - "Failed to set update mode\n"); 2309 2212 return r; 2310 2213 } 2311 2214 } ··· 2320 2219 return r; 2321 2220 } 2322 2221 } else { 2323 - if (dssdrv->set_update_mode) { 2324 - r = dssdrv->set_update_mode(dssdev, 2325 - OMAP_DSS_UPDATE_AUTO); 2326 - if (r) { 2327 - dev_err(fbdev->dev, 2328 - "Failed to set update mode\n"); 2329 - return r; 2330 - } 2331 - } 2222 + d->update_mode = OMAPFB_AUTO_UPDATE; 2332 2223 } 2333 2224 2334 2225 return 0; ··· 2368 2275 fbdev->num_displays = 0; 2369 2276 dssdev = NULL; 2370 2277 for_each_dss_dev(dssdev) { 2278 + struct omapfb_display_data *d; 2279 + 2371 2280 omap_dss_get_device(dssdev); 2372 2281 2373 2282 if (!dssdev->driver) { ··· 2377 2282 r = -ENODEV; 2378 2283 } 2379 2284 2380 - fbdev->displays[fbdev->num_displays++] = dssdev; 2285 + d = &fbdev->displays[fbdev->num_displays++]; 2286 + d->dssdev = dssdev; 2287 + if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) 2288 + d->update_mode = OMAPFB_MANUAL_UPDATE; 2289 + else 2290 + d->update_mode = OMAPFB_AUTO_UPDATE; 2381 2291 } 2382 2292 2383 2293 if (r)
+34
drivers/video/omap2/omapfb/omapfb-sysfs.c
··· 518 518 return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region->vaddr); 519 519 } 520 520 521 + static ssize_t show_upd_mode(struct device *dev, 522 + struct device_attribute *attr, char *buf) 523 + { 524 + struct fb_info *fbi = dev_get_drvdata(dev); 525 + enum omapfb_update_mode mode; 526 + int r; 527 + 528 + r = omapfb_get_update_mode(fbi, &mode); 529 + 530 + if (r) 531 + return r; 532 + 533 + return snprintf(buf, PAGE_SIZE, "%u\n", (unsigned)mode); 534 + } 535 + 536 + static ssize_t store_upd_mode(struct device *dev, struct device_attribute *attr, 537 + const char *buf, size_t count) 538 + { 539 + struct fb_info *fbi = dev_get_drvdata(dev); 540 + unsigned mode; 541 + int r; 542 + 543 + r = kstrtouint(buf, 0, &mode); 544 + if (r) 545 + return r; 546 + 547 + r = omapfb_set_update_mode(fbi, mode); 548 + if (r) 549 + return r; 550 + 551 + return count; 552 + } 553 + 521 554 static struct device_attribute omapfb_attrs[] = { 522 555 __ATTR(rotate_type, S_IRUGO | S_IWUSR, show_rotate_type, 523 556 store_rotate_type), ··· 561 528 store_overlays_rotate), 562 529 __ATTR(phys_addr, S_IRUGO, show_phys, NULL), 563 530 __ATTR(virt_addr, S_IRUGO, show_virt, NULL), 531 + __ATTR(update_mode, S_IRUGO | S_IWUSR, show_upd_mode, store_upd_mode), 564 532 }; 565 533 566 534 int omapfb_create_sysfs(struct omapfb2_device *fbdev)
+31 -6
drivers/video/omap2/omapfb/omapfb.h
··· 73 73 bool mirror; 74 74 }; 75 75 76 + struct omapfb_display_data { 77 + struct omapfb2_device *fbdev; 78 + struct omap_dss_device *dssdev; 79 + u8 bpp_override; 80 + enum omapfb_update_mode update_mode; 81 + bool auto_update_work_enabled; 82 + struct delayed_work auto_update_work; 83 + }; 84 + 76 85 struct omapfb2_device { 77 86 struct device *dev; 78 87 struct mutex mtx; ··· 95 86 struct omapfb2_mem_region regions[10]; 96 87 97 88 unsigned num_displays; 98 - struct omap_dss_device *displays[10]; 89 + struct omapfb_display_data displays[10]; 99 90 unsigned num_overlays; 100 91 struct omap_overlay *overlays[10]; 101 92 unsigned num_managers; 102 93 struct omap_overlay_manager *managers[10]; 103 94 104 - unsigned num_bpp_overrides; 105 - struct { 106 - struct omap_dss_device *dssdev; 107 - u8 bpp; 108 - } bpp_overrides[10]; 95 + struct workqueue_struct *auto_update_wq; 109 96 }; 110 97 111 98 struct omapfb_colormode { ··· 133 128 int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, 134 129 u16 posx, u16 posy, u16 outw, u16 outh); 135 130 131 + void omapfb_start_auto_update(struct omapfb2_device *fbdev, 132 + struct omap_dss_device *display); 133 + void omapfb_stop_auto_update(struct omapfb2_device *fbdev, 134 + struct omap_dss_device *display); 135 + int omapfb_get_update_mode(struct fb_info *fbi, enum omapfb_update_mode *mode); 136 + int omapfb_set_update_mode(struct fb_info *fbi, enum omapfb_update_mode mode); 137 + 136 138 /* find the display connected to this fb, if any */ 137 139 static inline struct omap_dss_device *fb2display(struct fb_info *fbi) 138 140 { ··· 153 141 } 154 142 155 143 return NULL; 144 + } 145 + 146 + static inline struct omapfb_display_data *get_display_data( 147 + struct omapfb2_device *fbdev, struct omap_dss_device *dssdev) 148 + { 149 + int i; 150 + 151 + for (i = 0; i < fbdev->num_displays; ++i) 152 + if (fbdev->displays[i].dssdev == dssdev) 153 + return &fbdev->displays[i]; 154 + 155 + /* This should never happen */ 156 + BUG(); 156 157 } 157 158 158 159 static inline void omapfb_lock(struct omapfb2_device *fbdev)
+10 -16
include/video/omapdss.h
··· 21 21 #include <linux/list.h> 22 22 #include <linux/kobject.h> 23 23 #include <linux/device.h> 24 - #include <linux/platform_device.h> 25 - #include <asm/atomic.h> 26 24 27 25 #define DISPC_IRQ_FRAMEDONE (1 << 0) 28 26 #define DISPC_IRQ_VSYNC (1 << 1) ··· 134 136 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM = 1 << 1, 135 137 }; 136 138 137 - enum omap_dss_update_mode { 138 - OMAP_DSS_UPDATE_DISABLED = 0, 139 - OMAP_DSS_UPDATE_AUTO, 140 - OMAP_DSS_UPDATE_MANUAL, 141 - }; 142 - 143 139 enum omap_dss_display_state { 144 140 OMAP_DSS_DISPLAY_DISABLED = 0, 145 141 OMAP_DSS_DISPLAY_ACTIVE, ··· 238 246 239 247 /* Board specific data */ 240 248 struct omap_dss_board_info { 241 - int (*get_last_off_on_transaction_id)(struct device *dev); 249 + int (*get_context_loss_count)(struct device *dev); 242 250 int num_devices; 243 251 struct omap_dss_device **devices; 244 252 struct omap_dss_device *default_device; ··· 258 266 struct omap_display_platform_data { 259 267 struct omap_dss_board_info *board_data; 260 268 /* TODO: Additional members to be added when PM is considered */ 261 - 262 - bool (*opt_clock_available)(const char *clk_role); 263 269 }; 264 270 265 271 struct omap_video_timings { ··· 289 299 extern const struct omap_video_timings omap_dss_pal_timings; 290 300 extern const struct omap_video_timings omap_dss_ntsc_timings; 291 301 #endif 302 + 303 + struct omap_dss_cpr_coefs { 304 + s16 rr, rg, rb; 305 + s16 gr, gg, gb; 306 + s16 br, bg, bb; 307 + }; 292 308 293 309 struct omap_overlay_info { 294 310 bool enabled; ··· 355 359 bool trans_enabled; 356 360 357 361 bool alpha_enabled; 362 + 363 + bool cpr_enable; 364 + struct omap_dss_cpr_coefs cpr_coefs; 358 365 }; 359 366 360 367 struct omap_overlay_manager { ··· 524 525 int (*suspend)(struct omap_dss_device *display); 525 526 int (*resume)(struct omap_dss_device *display); 526 527 int (*run_test)(struct omap_dss_device *display, int test); 527 - 528 - int (*set_update_mode)(struct omap_dss_device *dssdev, 529 - enum omap_dss_update_mode); 530 - enum omap_dss_update_mode (*get_update_mode)( 531 - struct omap_dss_device *dssdev); 532 528 533 529 int (*update)(struct omap_dss_device *dssdev, 534 530 u16 x, u16 y, u16 w, u16 h);