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

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.38-rc8 1113 lines 26 kB view raw
1/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. 2 * 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License version 2 and 5 * only version 2 as published by the Free Software Foundation. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 * 02110-1301, USA. 16 */ 17 18#include <linux/module.h> 19#include <linux/kernel.h> 20#include <linux/sched.h> 21#include <linux/time.h> 22#include <linux/init.h> 23#include <linux/interrupt.h> 24#include <linux/spinlock.h> 25#include <linux/hrtimer.h> 26#include <linux/clk.h> 27#include <mach/hardware.h> 28#include <linux/io.h> 29#include <linux/debugfs.h> 30#include <linux/delay.h> 31#include <linux/mutex.h> 32 33#include <asm/system.h> 34#include <asm/mach-types.h> 35#include <linux/semaphore.h> 36#include <linux/uaccess.h> 37 38#include "mdp.h" 39#include "msm_fb.h" 40#ifdef CONFIG_FB_MSM_MDP40 41#include "mdp4.h" 42#endif 43 44static struct clk *mdp_clk; 45static struct clk *mdp_pclk; 46 47struct completion mdp_ppp_comp; 48struct semaphore mdp_ppp_mutex; 49struct semaphore mdp_pipe_ctrl_mutex; 50 51unsigned long mdp_timer_duration = (HZ); /* 1 sec */ 52/* unsigned long mdp_mdp_timer_duration=0; */ 53 54boolean mdp_ppp_waiting = FALSE; 55uint32 mdp_tv_underflow_cnt; 56uint32 mdp_lcdc_underflow_cnt; 57 58boolean mdp_current_clk_on = FALSE; 59boolean mdp_is_in_isr = FALSE; 60 61/* 62 * legacy mdp_in_processing is only for DMA2-MDDI 63 * this applies to DMA2 block only 64 */ 65uint32 mdp_in_processing = FALSE; 66 67#ifdef CONFIG_FB_MSM_MDP40 68uint32 mdp_intr_mask = MDP4_ANY_INTR_MASK; 69#else 70uint32 mdp_intr_mask = MDP_ANY_INTR_MASK; 71#endif 72 73MDP_BLOCK_TYPE mdp_debug[MDP_MAX_BLOCK]; 74 75int32 mdp_block_power_cnt[MDP_MAX_BLOCK]; 76 77spinlock_t mdp_spin_lock; 78struct workqueue_struct *mdp_dma_wq; /*mdp dma wq */ 79struct workqueue_struct *mdp_vsync_wq; /*mdp vsync wq */ 80 81static struct workqueue_struct *mdp_pipe_ctrl_wq; /* mdp mdp pipe ctrl wq */ 82static struct delayed_work mdp_pipe_ctrl_worker; 83 84#ifdef CONFIG_FB_MSM_MDP40 85struct mdp_dma_data dma2_data; 86struct mdp_dma_data dma_s_data; 87struct mdp_dma_data dma_e_data; 88#else 89static struct mdp_dma_data dma2_data; 90static struct mdp_dma_data dma_s_data; 91static struct mdp_dma_data dma_e_data; 92#endif 93static struct mdp_dma_data dma3_data; 94 95extern ktime_t mdp_dma2_last_update_time; 96 97extern uint32 mdp_dma2_update_time_in_usec; 98extern int mdp_lcd_rd_cnt_offset_slow; 99extern int mdp_lcd_rd_cnt_offset_fast; 100extern int mdp_usec_diff_threshold; 101 102#ifdef CONFIG_FB_MSM_LCDC 103extern int mdp_lcdc_pclk_clk_rate; 104extern int mdp_lcdc_pad_pclk_clk_rate; 105extern int first_pixel_start_x; 106extern int first_pixel_start_y; 107#endif 108 109#ifdef MSM_FB_ENABLE_DBGFS 110struct dentry *mdp_dir; 111#endif 112 113#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND) 114static int mdp_suspend(struct platform_device *pdev, pm_message_t state); 115#else 116#define mdp_suspend NULL 117#endif 118 119struct timeval mdp_dma2_timeval; 120struct timeval mdp_ppp_timeval; 121 122#ifdef CONFIG_HAS_EARLYSUSPEND 123static struct early_suspend early_suspend; 124#endif 125 126#ifndef CONFIG_FB_MSM_MDP22 127DEFINE_MUTEX(mdp_lut_push_sem); 128static int mdp_lut_i; 129static int mdp_lut_hw_update(struct fb_cmap *cmap) 130{ 131 int i; 132 u16 *c[3]; 133 u16 r, g, b; 134 135 c[0] = cmap->green; 136 c[1] = cmap->blue; 137 c[2] = cmap->red; 138 139 for (i = 0; i < cmap->len; i++) { 140 if (copy_from_user(&r, cmap->red++, sizeof(r)) || 141 copy_from_user(&g, cmap->green++, sizeof(g)) || 142 copy_from_user(&b, cmap->blue++, sizeof(b))) 143 return -EFAULT; 144 145#ifdef CONFIG_FB_MSM_MDP40 146 MDP_OUTP(MDP_BASE + 0x94800 + 147#else 148 MDP_OUTP(MDP_BASE + 0x93800 + 149#endif 150 (0x400*mdp_lut_i) + cmap->start*4 + i*4, 151 ((g & 0xff) | 152 ((b & 0xff) << 8) | 153 ((r & 0xff) << 16))); 154 } 155 156 return 0; 157} 158 159static int mdp_lut_push; 160static int mdp_lut_push_i; 161static int mdp_lut_update_nonlcdc(struct fb_info *info, struct fb_cmap *cmap) 162{ 163 int ret; 164 165 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); 166 ret = mdp_lut_hw_update(cmap); 167 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); 168 169 if (ret) 170 return ret; 171 172 mutex_lock(&mdp_lut_push_sem); 173 mdp_lut_push = 1; 174 mdp_lut_push_i = mdp_lut_i; 175 mutex_unlock(&mdp_lut_push_sem); 176 177 mdp_lut_i = (mdp_lut_i + 1)%2; 178 179 return 0; 180} 181 182static int mdp_lut_update_lcdc(struct fb_info *info, struct fb_cmap *cmap) 183{ 184 int ret; 185 186 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); 187 ret = mdp_lut_hw_update(cmap); 188 189 if (ret) { 190 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); 191 return ret; 192 } 193 194 MDP_OUTP(MDP_BASE + 0x90070, (mdp_lut_i << 10) | 0x17); 195 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); 196 mdp_lut_i = (mdp_lut_i + 1)%2; 197 198 return 0; 199} 200 201#define MDP_HIST_MAX_BIN 32 202static __u32 mdp_hist_r[MDP_HIST_MAX_BIN]; 203static __u32 mdp_hist_g[MDP_HIST_MAX_BIN]; 204static __u32 mdp_hist_b[MDP_HIST_MAX_BIN]; 205 206#ifdef CONFIG_FB_MSM_MDP40 207struct mdp_histogram mdp_hist; 208struct completion mdp_hist_comp; 209#else 210static struct mdp_histogram mdp_hist; 211static struct completion mdp_hist_comp; 212#endif 213 214static int mdp_do_histogram(struct fb_info *info, struct mdp_histogram *hist) 215{ 216 int ret = 0; 217 218 if (!hist->frame_cnt || (hist->bin_cnt == 0) || 219 (hist->bin_cnt > MDP_HIST_MAX_BIN)) 220 return -EINVAL; 221 222 INIT_COMPLETION(mdp_hist_comp); 223 224 mdp_hist.bin_cnt = hist->bin_cnt; 225 mdp_hist.r = (hist->r) ? mdp_hist_r : 0; 226 mdp_hist.g = (hist->g) ? mdp_hist_g : 0; 227 mdp_hist.b = (hist->b) ? mdp_hist_b : 0; 228 229#ifdef CONFIG_FB_MSM_MDP40 230 MDP_OUTP(MDP_BASE + 0x95004, hist->frame_cnt); 231 MDP_OUTP(MDP_BASE + 0x95000, 1); 232#else 233 MDP_OUTP(MDP_BASE + 0x94004, hist->frame_cnt); 234 MDP_OUTP(MDP_BASE + 0x94000, 1); 235#endif 236 wait_for_completion_killable(&mdp_hist_comp); 237 238 if (hist->r) { 239 ret = copy_to_user(hist->r, mdp_hist.r, hist->bin_cnt*4); 240 if (ret) 241 goto hist_err; 242 } 243 if (hist->g) { 244 ret = copy_to_user(hist->g, mdp_hist.g, hist->bin_cnt*4); 245 if (ret) 246 goto hist_err; 247 } 248 if (hist->b) { 249 ret = copy_to_user(hist->b, mdp_hist.b, hist->bin_cnt*4); 250 if (ret) 251 goto hist_err; 252 } 253 return 0; 254 255hist_err: 256 printk(KERN_ERR "%s: invalid hist buffer\n", __func__); 257 return ret; 258} 259#endif 260 261/* Returns < 0 on error, 0 on timeout, or > 0 on successful wait */ 262 263int mdp_ppp_pipe_wait(void) 264{ 265 int ret = 1; 266 267 /* wait 5 seconds for the operation to complete before declaring 268 the MDP hung */ 269 270 if (mdp_ppp_waiting == TRUE) { 271 ret = wait_for_completion_interruptible_timeout(&mdp_ppp_comp, 272 5 * HZ); 273 274 if (!ret) 275 printk(KERN_ERR "%s: Timed out waiting for the MDP.\n", 276 __func__); 277 } 278 279 return ret; 280} 281 282static DEFINE_SPINLOCK(mdp_lock); 283static int mdp_irq_mask; 284static int mdp_irq_enabled; 285 286void mdp_enable_irq(uint32 term) 287{ 288 unsigned long irq_flags; 289 290 spin_lock_irqsave(&mdp_lock, irq_flags); 291 if (mdp_irq_mask & term) { 292 printk(KERN_ERR "MDP IRQ term-0x%x is already set\n", term); 293 } else { 294 mdp_irq_mask |= term; 295 if (mdp_irq_mask && !mdp_irq_enabled) { 296 mdp_irq_enabled = 1; 297 enable_irq(INT_MDP); 298 } 299 } 300 spin_unlock_irqrestore(&mdp_lock, irq_flags); 301} 302 303void mdp_disable_irq(uint32 term) 304{ 305 unsigned long irq_flags; 306 307 spin_lock_irqsave(&mdp_lock, irq_flags); 308 if (!(mdp_irq_mask & term)) { 309 printk(KERN_ERR "MDP IRQ term-0x%x is not set\n", term); 310 } else { 311 mdp_irq_mask &= ~term; 312 if (!mdp_irq_mask && mdp_irq_enabled) { 313 mdp_irq_enabled = 0; 314 disable_irq(INT_MDP); 315 } 316 } 317 spin_unlock_irqrestore(&mdp_lock, irq_flags); 318} 319 320void mdp_disable_irq_nolock(uint32 term) 321{ 322 323 if (!(mdp_irq_mask & term)) { 324 printk(KERN_ERR "MDP IRQ term-0x%x is not set\n", term); 325 } else { 326 mdp_irq_mask &= ~term; 327 if (!mdp_irq_mask && mdp_irq_enabled) { 328 mdp_irq_enabled = 0; 329 disable_irq(INT_MDP); 330 } 331 } 332} 333 334void mdp_pipe_kickoff(uint32 term, struct msm_fb_data_type *mfd) 335{ 336 337 dmb(); /* memory barrier */ 338 339 /* kick off PPP engine */ 340 if (term == MDP_PPP_TERM) { 341 if (mdp_debug[MDP_PPP_BLOCK]) 342 jiffies_to_timeval(jiffies, &mdp_ppp_timeval); 343 344 /* let's turn on PPP block */ 345 mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_ON, FALSE); 346 347 mdp_enable_irq(term); 348 INIT_COMPLETION(mdp_ppp_comp); 349 mdp_ppp_waiting = TRUE; 350 outpdw(MDP_BASE + 0x30, 0x1000); 351 wait_for_completion_killable(&mdp_ppp_comp); 352 mdp_disable_irq(term); 353 354 if (mdp_debug[MDP_PPP_BLOCK]) { 355 struct timeval now; 356 357 jiffies_to_timeval(jiffies, &now); 358 mdp_ppp_timeval.tv_usec = 359 now.tv_usec - mdp_ppp_timeval.tv_usec; 360 MSM_FB_INFO("MDP-PPP: %d\n", 361 (int)mdp_ppp_timeval.tv_usec); 362 } 363 } else if (term == MDP_DMA2_TERM) { 364 if (mdp_debug[MDP_DMA2_BLOCK]) { 365 MSM_FB_INFO("MDP-DMA2: %d\n", 366 (int)mdp_dma2_timeval.tv_usec); 367 jiffies_to_timeval(jiffies, &mdp_dma2_timeval); 368 } 369 /* DMA update timestamp */ 370 mdp_dma2_last_update_time = ktime_get_real(); 371 /* let's turn on DMA2 block */ 372#if 0 373 mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE); 374#endif 375#ifdef CONFIG_FB_MSM_MDP22 376 outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x0044, 0x0);/* start DMA */ 377#else 378 if (mdp_lut_push) { 379 mutex_lock(&mdp_lut_push_sem); 380 mdp_lut_push = 0; 381 MDP_OUTP(MDP_BASE + 0x90070, 382 (mdp_lut_push_i << 10) | 0x17); 383 mutex_unlock(&mdp_lut_push_sem); 384 } 385#ifdef CONFIG_FB_MSM_MDP40 386 outpdw(MDP_BASE + 0x000c, 0x0); /* start DMA */ 387#else 388 outpdw(MDP_BASE + 0x0044, 0x0); /* start DMA */ 389#endif 390#endif 391#ifdef CONFIG_FB_MSM_MDP40 392 } else if (term == MDP_DMA_S_TERM) { 393 mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_ON, FALSE); 394 outpdw(MDP_BASE + 0x0010, 0x0); /* start DMA */ 395 } else if (term == MDP_DMA_E_TERM) { 396 mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_ON, FALSE); 397 outpdw(MDP_BASE + 0x0014, 0x0); /* start DMA */ 398 } else if (term == MDP_OVERLAY0_TERM) { 399 mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE); 400 outpdw(MDP_BASE + 0x0004, 0); 401 } else if (term == MDP_OVERLAY1_TERM) { 402 mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_ON, FALSE); 403 outpdw(MDP_BASE + 0x0008, 0); 404 } 405#else 406 } else if (term == MDP_DMA_S_TERM) { 407 mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_ON, FALSE); 408 outpdw(MDP_BASE + 0x0048, 0x0); /* start DMA */ 409 } 410#endif 411} 412 413static void mdp_pipe_ctrl_workqueue_handler(struct work_struct *work) 414{ 415 mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); 416} 417 418void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state, 419 boolean isr) 420{ 421 boolean mdp_all_blocks_off = TRUE; 422 int i; 423 unsigned long flag; 424 425 spin_lock_irqsave(&mdp_spin_lock, flag); 426 if (MDP_BLOCK_POWER_ON == state) { 427 mdp_block_power_cnt[block]++; 428 429 if (MDP_DMA2_BLOCK == block) 430 mdp_in_processing = TRUE; 431 } else { 432 mdp_block_power_cnt[block]--; 433 434 if (mdp_block_power_cnt[block] < 0) { 435 /* 436 * Master has to serve a request to power off MDP always 437 * It also has a timer to power off. So, in case of 438 * timer expires first and DMA2 finishes later, 439 * master has to power off two times 440 * There shouldn't be multiple power-off request for 441 * other blocks 442 */ 443 if (block != MDP_MASTER_BLOCK) { 444 MSM_FB_INFO("mdp_block_power_cnt[block=%d] \ 445 multiple power-off request\n", block); 446 } 447 mdp_block_power_cnt[block] = 0; 448 } 449 450 if (MDP_DMA2_BLOCK == block) 451 mdp_in_processing = FALSE; 452 } 453 spin_unlock_irqrestore(&mdp_spin_lock, flag); 454 455 /* 456 * If it's in isr, we send our request to workqueue. 457 * Otherwise, processing happens in the current context 458 */ 459 if (isr) { 460 /* checking all blocks power state */ 461 for (i = 0; i < MDP_MAX_BLOCK; i++) { 462 if (mdp_block_power_cnt[i] > 0) 463 mdp_all_blocks_off = FALSE; 464 } 465 466 if ((mdp_all_blocks_off) && (mdp_current_clk_on)) { 467 /* send workqueue to turn off mdp power */ 468 queue_delayed_work(mdp_pipe_ctrl_wq, 469 &mdp_pipe_ctrl_worker, 470 mdp_timer_duration); 471 } 472 } else { 473 down(&mdp_pipe_ctrl_mutex); 474 /* checking all blocks power state */ 475 for (i = 0; i < MDP_MAX_BLOCK; i++) { 476 if (mdp_block_power_cnt[i] > 0) 477 mdp_all_blocks_off = FALSE; 478 } 479 480 /* 481 * find out whether a delayable work item is currently 482 * pending 483 */ 484 485 if (delayed_work_pending(&mdp_pipe_ctrl_worker)) { 486 /* 487 * try to cancel the current work if it fails to 488 * stop (which means del_timer can't delete it 489 * from the list, it's about to expire and run), 490 * we have to let it run. queue_delayed_work won't 491 * accept the next job which is same as 492 * queue_delayed_work(mdp_timer_duration = 0) 493 */ 494 cancel_delayed_work(&mdp_pipe_ctrl_worker); 495 } 496 497 if ((mdp_all_blocks_off) && (mdp_current_clk_on)) { 498 if (block == MDP_MASTER_BLOCK) { 499 mdp_current_clk_on = FALSE; 500 /* turn off MDP clks */ 501 if (mdp_clk != NULL) { 502 clk_disable(mdp_clk); 503 MSM_FB_DEBUG("MDP CLK OFF\n"); 504 } 505 if (mdp_pclk != NULL) { 506 clk_disable(mdp_pclk); 507 MSM_FB_DEBUG("MDP PCLK OFF\n"); 508 } 509 } else { 510 /* send workqueue to turn off mdp power */ 511 queue_delayed_work(mdp_pipe_ctrl_wq, 512 &mdp_pipe_ctrl_worker, 513 mdp_timer_duration); 514 } 515 } else if ((!mdp_all_blocks_off) && (!mdp_current_clk_on)) { 516 mdp_current_clk_on = TRUE; 517 /* turn on MDP clks */ 518 if (mdp_clk != NULL) { 519 clk_enable(mdp_clk); 520 MSM_FB_DEBUG("MDP CLK ON\n"); 521 } 522 if (mdp_pclk != NULL) { 523 clk_enable(mdp_pclk); 524 MSM_FB_DEBUG("MDP PCLK ON\n"); 525 } 526 } 527 up(&mdp_pipe_ctrl_mutex); 528 } 529} 530 531#ifndef CONFIG_FB_MSM_MDP40 532irqreturn_t mdp_isr(int irq, void *ptr) 533{ 534 uint32 mdp_interrupt = 0; 535 struct mdp_dma_data *dma; 536 537 mdp_is_in_isr = TRUE; 538 do { 539 mdp_interrupt = inp32(MDP_INTR_STATUS); 540 outp32(MDP_INTR_CLEAR, mdp_interrupt); 541 542 mdp_interrupt &= mdp_intr_mask; 543 544 if (mdp_interrupt & TV_ENC_UNDERRUN) { 545 mdp_interrupt &= ~(TV_ENC_UNDERRUN); 546 mdp_tv_underflow_cnt++; 547 } 548 549 if (!mdp_interrupt) 550 break; 551 552 /* DMA3 TV-Out Start */ 553 if (mdp_interrupt & TV_OUT_DMA3_START) { 554 /* let's disable TV out interrupt */ 555 mdp_intr_mask &= ~TV_OUT_DMA3_START; 556 outp32(MDP_INTR_ENABLE, mdp_intr_mask); 557 558 dma = &dma3_data; 559 if (dma->waiting) { 560 dma->waiting = FALSE; 561 complete(&dma->comp); 562 } 563 } 564#ifndef CONFIG_FB_MSM_MDP22 565 if (mdp_interrupt & MDP_HIST_DONE) { 566 outp32(MDP_BASE + 0x94018, 0x3); 567 outp32(MDP_INTR_CLEAR, MDP_HIST_DONE); 568 if (mdp_hist.r) 569 memcpy(mdp_hist.r, MDP_BASE + 0x94100, 570 mdp_hist.bin_cnt*4); 571 if (mdp_hist.g) 572 memcpy(mdp_hist.g, MDP_BASE + 0x94200, 573 mdp_hist.bin_cnt*4); 574 if (mdp_hist.b) 575 memcpy(mdp_hist.b, MDP_BASE + 0x94300, 576 mdp_hist.bin_cnt*4); 577 complete(&mdp_hist_comp); 578 } 579 580 /* LCDC UnderFlow */ 581 if (mdp_interrupt & LCDC_UNDERFLOW) { 582 mdp_lcdc_underflow_cnt++; 583 } 584 /* LCDC Frame Start */ 585 if (mdp_interrupt & LCDC_FRAME_START) { 586 /* let's disable LCDC interrupt */ 587 mdp_intr_mask &= ~LCDC_FRAME_START; 588 outp32(MDP_INTR_ENABLE, mdp_intr_mask); 589 590 dma = &dma2_data; 591 if (dma->waiting) { 592 dma->waiting = FALSE; 593 complete(&dma->comp); 594 } 595 } 596 597 /* DMA2 LCD-Out Complete */ 598 if (mdp_interrupt & MDP_DMA_S_DONE) { 599 dma = &dma_s_data; 600 dma->busy = FALSE; 601 mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_OFF, 602 TRUE); 603 complete(&dma->comp); 604 } 605#endif 606 607 /* DMA2 LCD-Out Complete */ 608 if (mdp_interrupt & MDP_DMA_P_DONE) { 609 struct timeval now; 610 ktime_t now_k; 611 612 now_k = ktime_get_real(); 613 mdp_dma2_last_update_time.tv.sec = 614 now_k.tv.sec - mdp_dma2_last_update_time.tv.sec; 615 mdp_dma2_last_update_time.tv.nsec = 616 now_k.tv.nsec - mdp_dma2_last_update_time.tv.nsec; 617 618 if (mdp_debug[MDP_DMA2_BLOCK]) { 619 jiffies_to_timeval(jiffies, &now); 620 mdp_dma2_timeval.tv_usec = 621 now.tv_usec - mdp_dma2_timeval.tv_usec; 622 } 623 624 dma = &dma2_data; 625 dma->busy = FALSE; 626 mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF, 627 TRUE); 628 complete(&dma->comp); 629 } 630 /* PPP Complete */ 631 if (mdp_interrupt & MDP_PPP_DONE) { 632#ifdef CONFIG_MDP_PPP_ASYNC_OP 633 mdp_ppp_djob_done(); 634#else 635 mdp_pipe_ctrl(MDP_PPP_BLOCK, 636 MDP_BLOCK_POWER_OFF, TRUE); 637 if (mdp_ppp_waiting) { 638 mdp_ppp_waiting = FALSE; 639 complete(&mdp_ppp_comp); 640 } 641#endif 642 } 643 } while (1); 644 645 mdp_is_in_isr = FALSE; 646 647 return IRQ_HANDLED; 648} 649#endif 650 651static void mdp_drv_init(void) 652{ 653 int i; 654 655 for (i = 0; i < MDP_MAX_BLOCK; i++) { 656 mdp_debug[i] = 0; 657 } 658 659 /* initialize spin lock and workqueue */ 660 spin_lock_init(&mdp_spin_lock); 661 mdp_dma_wq = create_singlethread_workqueue("mdp_dma_wq"); 662 mdp_vsync_wq = create_singlethread_workqueue("mdp_vsync_wq"); 663 mdp_pipe_ctrl_wq = create_singlethread_workqueue("mdp_pipe_ctrl_wq"); 664 INIT_DELAYED_WORK(&mdp_pipe_ctrl_worker, 665 mdp_pipe_ctrl_workqueue_handler); 666#ifdef CONFIG_MDP_PPP_ASYNC_OP 667 mdp_ppp_dq_init(); 668#endif 669 670 /* initialize semaphore */ 671 init_completion(&mdp_ppp_comp); 672 sema_init(&mdp_ppp_mutex, 1); 673 sema_init(&mdp_pipe_ctrl_mutex, 1); 674 675 dma2_data.busy = FALSE; 676 dma2_data.waiting = FALSE; 677 init_completion(&dma2_data.comp); 678 sema_init(&dma2_data.mutex, 1); 679 mutex_init(&dma2_data.ov_mutex); 680 681 dma3_data.busy = FALSE; 682 dma3_data.waiting = FALSE; 683 init_completion(&dma3_data.comp); 684 sema_init(&dma3_data.mutex, 1); 685 686 dma_s_data.busy = FALSE; 687 dma_s_data.waiting = FALSE; 688 init_completion(&dma_s_data.comp); 689 sema_init(&dma_s_data.mutex, 1); 690 691 dma_e_data.busy = FALSE; 692 dma_e_data.waiting = FALSE; 693 init_completion(&dma_e_data.comp); 694 695#ifndef CONFIG_FB_MSM_MDP22 696 init_completion(&mdp_hist_comp); 697#endif 698 699 /* initializing mdp power block counter to 0 */ 700 for (i = 0; i < MDP_MAX_BLOCK; i++) { 701 mdp_block_power_cnt[i] = 0; 702 } 703 704#ifdef MSM_FB_ENABLE_DBGFS 705 { 706 struct dentry *root; 707 char sub_name[] = "mdp"; 708 709 root = msm_fb_get_debugfs_root(); 710 if (root != NULL) { 711 mdp_dir = debugfs_create_dir(sub_name, root); 712 713 if (mdp_dir) { 714 msm_fb_debugfs_file_create(mdp_dir, 715 "dma2_update_time_in_usec", 716 (u32 *) &mdp_dma2_update_time_in_usec); 717 msm_fb_debugfs_file_create(mdp_dir, 718 "vs_rdcnt_slow", 719 (u32 *) &mdp_lcd_rd_cnt_offset_slow); 720 msm_fb_debugfs_file_create(mdp_dir, 721 "vs_rdcnt_fast", 722 (u32 *) &mdp_lcd_rd_cnt_offset_fast); 723 msm_fb_debugfs_file_create(mdp_dir, 724 "mdp_usec_diff_threshold", 725 (u32 *) &mdp_usec_diff_threshold); 726 msm_fb_debugfs_file_create(mdp_dir, 727 "mdp_current_clk_on", 728 (u32 *) &mdp_current_clk_on); 729#ifdef CONFIG_FB_MSM_LCDC 730 msm_fb_debugfs_file_create(mdp_dir, 731 "lcdc_start_x", 732 (u32 *) &first_pixel_start_x); 733 msm_fb_debugfs_file_create(mdp_dir, 734 "lcdc_start_y", 735 (u32 *) &first_pixel_start_y); 736 msm_fb_debugfs_file_create(mdp_dir, 737 "mdp_lcdc_pclk_clk_rate", 738 (u32 *) &mdp_lcdc_pclk_clk_rate); 739 msm_fb_debugfs_file_create(mdp_dir, 740 "mdp_lcdc_pad_pclk_clk_rate", 741 (u32 *) &mdp_lcdc_pad_pclk_clk_rate); 742#endif 743 } 744 } 745 } 746#endif 747} 748 749static int mdp_probe(struct platform_device *pdev); 750static int mdp_remove(struct platform_device *pdev); 751 752static struct platform_driver mdp_driver = { 753 .probe = mdp_probe, 754 .remove = mdp_remove, 755#ifndef CONFIG_HAS_EARLYSUSPEND 756 .suspend = mdp_suspend, 757 .resume = NULL, 758#endif 759 .shutdown = NULL, 760 .driver = { 761 /* 762 * Driver name must match the device name added in 763 * platform.c. 764 */ 765 .name = "mdp", 766 }, 767}; 768 769static int mdp_off(struct platform_device *pdev) 770{ 771 int ret = 0; 772 773#ifdef MDP_HW_VSYNC 774 struct msm_fb_data_type *mfd = platform_get_drvdata(pdev); 775#endif 776 777 ret = panel_next_off(pdev); 778 779#ifdef MDP_HW_VSYNC 780 mdp_hw_vsync_clk_disable(mfd); 781#endif 782 783 return ret; 784} 785 786static int mdp_on(struct platform_device *pdev) 787{ 788#ifdef MDP_HW_VSYNC 789 struct msm_fb_data_type *mfd = platform_get_drvdata(pdev); 790#endif 791 792 int ret = 0; 793 794#ifdef MDP_HW_VSYNC 795 mdp_hw_vsync_clk_enable(mfd); 796#endif 797 798 ret = panel_next_on(pdev); 799 800 return ret; 801} 802 803static int mdp_irq_clk_setup(void) 804{ 805 int ret; 806 807#ifdef CONFIG_FB_MSM_MDP40 808 ret = request_irq(INT_MDP, mdp4_isr, IRQF_DISABLED, "MDP", 0); 809#else 810 ret = request_irq(INT_MDP, mdp_isr, IRQF_DISABLED, "MDP", 0); 811#endif 812 if (ret) { 813 printk(KERN_ERR "mdp request_irq() failed!\n"); 814 return ret; 815 } 816 disable_irq(INT_MDP); 817 818 mdp_clk = clk_get(NULL, "mdp_clk"); 819 820 if (IS_ERR(mdp_clk)) { 821 ret = PTR_ERR(mdp_clk); 822 printk(KERN_ERR "can't get mdp_clk error:%d!\n", ret); 823 free_irq(INT_MDP, 0); 824 return ret; 825 } 826 827 mdp_pclk = clk_get(NULL, "mdp_pclk"); 828 if (IS_ERR(mdp_pclk)) 829 mdp_pclk = NULL; 830 831 832#ifdef CONFIG_FB_MSM_MDP40 833 /* 834 * mdp_clk should greater than mdp_pclk always 835 */ 836 clk_set_rate(mdp_clk, 122880000); /* 122.88 Mhz */ 837 printk(KERN_INFO "mdp_clk: mdp_clk=%d mdp_pclk=%d\n", 838 (int)clk_get_rate(mdp_clk), (int)clk_get_rate(mdp_pclk)); 839#endif 840 841 return 0; 842} 843 844static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST]; 845static int pdev_list_cnt; 846static int mdp_resource_initialized; 847static struct msm_panel_common_pdata *mdp_pdata; 848 849static int mdp_probe(struct platform_device *pdev) 850{ 851 struct platform_device *msm_fb_dev = NULL; 852 struct msm_fb_data_type *mfd; 853 struct msm_fb_panel_data *pdata = NULL; 854 int rc; 855 resource_size_t size ; 856#ifdef CONFIG_FB_MSM_MDP40 857 int intf, if_no; 858#else 859 unsigned long flag; 860#endif 861 862 if ((pdev->id == 0) && (pdev->num_resources > 0)) { 863 mdp_pdata = pdev->dev.platform_data; 864 865 size = resource_size(&pdev->resource[0]); 866 msm_mdp_base = ioremap(pdev->resource[0].start, size); 867 868 MSM_FB_INFO("MDP HW Base phy_Address = 0x%x virt = 0x%x\n", 869 (int)pdev->resource[0].start, (int)msm_mdp_base); 870 871 if (unlikely(!msm_mdp_base)) 872 return -ENOMEM; 873 874 printk("irq clk setup\n"); 875 rc = mdp_irq_clk_setup(); 876 printk("irq clk setup done\n"); 877 if (rc) 878 return rc; 879 880 /* initializing mdp hw */ 881#ifdef CONFIG_FB_MSM_MDP40 882 mdp4_hw_init(); 883#else 884 mdp_hw_init(); 885#endif 886 887 mdp_resource_initialized = 1; 888 return 0; 889 } 890 891 if (!mdp_resource_initialized) 892 return -EPERM; 893 894 mfd = platform_get_drvdata(pdev); 895 896 if (!mfd) 897 return -ENODEV; 898 899 if (mfd->key != MFD_KEY) 900 return -EINVAL; 901 902 if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST) 903 return -ENOMEM; 904 905 msm_fb_dev = platform_device_alloc("msm_fb", pdev->id); 906 if (!msm_fb_dev) 907 return -ENOMEM; 908 909 /* link to the latest pdev */ 910 mfd->pdev = msm_fb_dev; 911 912 /* add panel data */ 913 if (platform_device_add_data 914 (msm_fb_dev, pdev->dev.platform_data, 915 sizeof(struct msm_fb_panel_data))) { 916 printk(KERN_ERR "mdp_probe: platform_device_add_data failed!\n"); 917 rc = -ENOMEM; 918 goto mdp_probe_err; 919 } 920 /* data chain */ 921 pdata = msm_fb_dev->dev.platform_data; 922 pdata->on = mdp_on; 923 pdata->off = mdp_off; 924 pdata->next = pdev; 925 926 switch (mfd->panel.type) { 927 case EXT_MDDI_PANEL: 928 case MDDI_PANEL: 929 case EBI2_PANEL: 930 INIT_WORK(&mfd->dma_update_worker, 931 mdp_lcd_update_workqueue_handler); 932 INIT_WORK(&mfd->vsync_resync_worker, 933 mdp_vsync_resync_workqueue_handler); 934 mfd->hw_refresh = FALSE; 935 936 if (mfd->panel.type == EXT_MDDI_PANEL) { 937 /* 15 fps -> 66 msec */ 938 mfd->refresh_timer_duration = (66 * HZ / 1000); 939 } else { 940 /* 24 fps -> 42 msec */ 941 mfd->refresh_timer_duration = (42 * HZ / 1000); 942 } 943 944#ifdef CONFIG_FB_MSM_MDP22 945 mfd->dma_fnc = mdp_dma2_update; 946 mfd->dma = &dma2_data; 947#else 948 if (mfd->panel_info.pdest == DISPLAY_1) { 949#ifdef CONFIG_FB_MSM_OVERLAY 950 mfd->dma_fnc = mdp4_mddi_overlay; 951#else 952 mfd->dma_fnc = mdp_dma2_update; 953#endif 954 mfd->dma = &dma2_data; 955 mfd->lut_update = mdp_lut_update_nonlcdc; 956 mfd->do_histogram = mdp_do_histogram; 957 } else { 958 mfd->dma_fnc = mdp_dma_s_update; 959 mfd->dma = &dma_s_data; 960 } 961#endif 962 if (mdp_pdata) 963 mfd->vsync_gpio = mdp_pdata->gpio; 964 else 965 mfd->vsync_gpio = -1; 966 967#ifdef CONFIG_FB_MSM_MDP40 968 if (mfd->panel.type == EBI2_PANEL) 969 intf = EBI2_INTF; 970 else 971 intf = MDDI_INTF; 972 973 if (mfd->panel_info.pdest == DISPLAY_1) 974 if_no = PRIMARY_INTF_SEL; 975 else 976 if_no = SECONDARY_INTF_SEL; 977 978 mdp4_display_intf_sel(if_no, intf); 979#endif 980 mdp_config_vsync(mfd); 981 break; 982 983 case HDMI_PANEL: 984 case LCDC_PANEL: 985 pdata->on = mdp_lcdc_on; 986 pdata->off = mdp_lcdc_off; 987 mfd->hw_refresh = TRUE; 988 mfd->cursor_update = mdp_hw_cursor_update; 989#ifndef CONFIG_FB_MSM_MDP22 990 mfd->lut_update = mdp_lut_update_lcdc; 991 mfd->do_histogram = mdp_do_histogram; 992#endif 993#ifdef CONFIG_FB_MSM_OVERLAY 994 mfd->dma_fnc = mdp4_lcdc_overlay; 995#else 996 mfd->dma_fnc = mdp_lcdc_update; 997#endif 998 999#ifdef CONFIG_FB_MSM_MDP40 1000 if (mfd->panel.type == HDMI_PANEL) { 1001 mfd->dma = &dma_e_data; 1002 mdp4_display_intf_sel(EXTERNAL_INTF_SEL, LCDC_RGB_INTF); 1003 } else { 1004 mfd->dma = &dma2_data; 1005 mdp4_display_intf_sel(PRIMARY_INTF_SEL, LCDC_RGB_INTF); 1006 } 1007#else 1008 mfd->dma = &dma2_data; 1009 spin_lock_irqsave(&mdp_spin_lock, flag); 1010 mdp_intr_mask &= ~MDP_DMA_P_DONE; 1011 outp32(MDP_INTR_ENABLE, mdp_intr_mask); 1012 spin_unlock_irqrestore(&mdp_spin_lock, flag); 1013#endif 1014 break; 1015 1016 case TV_PANEL: 1017 pdata->on = mdp_dma3_on; 1018 pdata->off = mdp_dma3_off; 1019 mfd->hw_refresh = TRUE; 1020 mfd->dma_fnc = mdp_dma3_update; 1021 mfd->dma = &dma3_data; 1022 break; 1023 1024 default: 1025 printk(KERN_ERR "mdp_probe: unknown device type!\n"); 1026 rc = -ENODEV; 1027 goto mdp_probe_err; 1028 } 1029 1030 /* set driver data */ 1031 platform_set_drvdata(msm_fb_dev, mfd); 1032 1033 rc = platform_device_add(msm_fb_dev); 1034 if (rc) { 1035 goto mdp_probe_err; 1036 } 1037 1038 pdev_list[pdev_list_cnt++] = pdev; 1039 return 0; 1040 1041 mdp_probe_err: 1042 platform_device_put(msm_fb_dev); 1043 return rc; 1044} 1045 1046static void mdp_suspend_sub(void) 1047{ 1048 /* cancel pipe ctrl worker */ 1049 cancel_delayed_work(&mdp_pipe_ctrl_worker); 1050 1051 /* for workder can't be cancelled... */ 1052 flush_workqueue(mdp_pipe_ctrl_wq); 1053 1054 /* let's wait for PPP completion */ 1055 while (mdp_block_power_cnt[MDP_PPP_BLOCK] > 0) ; 1056 1057 /* try to power down */ 1058 mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); 1059} 1060 1061#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND) 1062static int mdp_suspend(struct platform_device *pdev, pm_message_t state) 1063{ 1064 mdp_suspend_sub(); 1065 return 0; 1066} 1067#endif 1068 1069#ifdef CONFIG_HAS_EARLYSUSPEND 1070static void mdp_early_suspend(struct early_suspend *h) 1071{ 1072 mdp_suspend_sub(); 1073} 1074#endif 1075 1076static int mdp_remove(struct platform_device *pdev) 1077{ 1078 iounmap(msm_mdp_base); 1079 return 0; 1080} 1081 1082static int mdp_register_driver(void) 1083{ 1084#ifdef CONFIG_HAS_EARLYSUSPEND 1085 early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1; 1086 early_suspend.suspend = mdp_early_suspend; 1087 register_early_suspend(&early_suspend); 1088#endif 1089 1090 return platform_driver_register(&mdp_driver); 1091} 1092 1093static int __init mdp_driver_init(void) 1094{ 1095 int ret; 1096 1097 mdp_drv_init(); 1098 1099 ret = mdp_register_driver(); 1100 if (ret) { 1101 printk(KERN_ERR "mdp_register_driver() failed!\n"); 1102 return ret; 1103 } 1104 1105#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_FB_MSM_MDP40) 1106 mdp4_debugfs_init(); 1107#endif 1108 1109 return 0; 1110 1111} 1112 1113module_init(mdp_driver_init);