1/************************************************************************** 2 * Copyright (c) 2007, Intel Corporation. 3 * All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to 19 * develop this driver. 20 * 21 **************************************************************************/ 22/* 23 */ 24 25#include <drm/drmP.h> 26#include "psb_drv.h" 27#include "psb_reg.h" 28#include "psb_intel_reg.h" 29#include "power.h" 30#include "psb_irq.h" 31#include "mdfld_output.h" 32 33/* 34 * inline functions 35 */ 36 37static inline u32 38psb_pipestat(int pipe) 39{ 40 if (pipe == 0) 41 return PIPEASTAT; 42 if (pipe == 1) 43 return PIPEBSTAT; 44 if (pipe == 2) 45 return PIPECSTAT; 46 BUG(); 47} 48 49static inline u32 50mid_pipe_event(int pipe) 51{ 52 if (pipe == 0) 53 return _PSB_PIPEA_EVENT_FLAG; 54 if (pipe == 1) 55 return _MDFLD_PIPEB_EVENT_FLAG; 56 if (pipe == 2) 57 return _MDFLD_PIPEC_EVENT_FLAG; 58 BUG(); 59} 60 61static inline u32 62mid_pipe_vsync(int pipe) 63{ 64 if (pipe == 0) 65 return _PSB_VSYNC_PIPEA_FLAG; 66 if (pipe == 1) 67 return _PSB_VSYNC_PIPEB_FLAG; 68 if (pipe == 2) 69 return _MDFLD_PIPEC_VBLANK_FLAG; 70 BUG(); 71} 72 73static inline u32 74mid_pipeconf(int pipe) 75{ 76 if (pipe == 0) 77 return PIPEACONF; 78 if (pipe == 1) 79 return PIPEBCONF; 80 if (pipe == 2) 81 return PIPECCONF; 82 BUG(); 83} 84 85void 86psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) 87{ 88 if ((dev_priv->pipestat[pipe] & mask) != mask) { 89 u32 reg = psb_pipestat(pipe); 90 dev_priv->pipestat[pipe] |= mask; 91 /* Enable the interrupt, clear any pending status */ 92 if (gma_power_begin(dev_priv->dev, false)) { 93 u32 writeVal = PSB_RVDC32(reg); 94 writeVal |= (mask | (mask >> 16)); 95 PSB_WVDC32(writeVal, reg); 96 (void) PSB_RVDC32(reg); 97 gma_power_end(dev_priv->dev); 98 } 99 } 100} 101 102void 103psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) 104{ 105 if ((dev_priv->pipestat[pipe] & mask) != 0) { 106 u32 reg = psb_pipestat(pipe); 107 dev_priv->pipestat[pipe] &= ~mask; 108 if (gma_power_begin(dev_priv->dev, false)) { 109 u32 writeVal = PSB_RVDC32(reg); 110 writeVal &= ~mask; 111 PSB_WVDC32(writeVal, reg); 112 (void) PSB_RVDC32(reg); 113 gma_power_end(dev_priv->dev); 114 } 115 } 116} 117 118static void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe) 119{ 120 if (gma_power_begin(dev_priv->dev, false)) { 121 u32 pipe_event = mid_pipe_event(pipe); 122 dev_priv->vdc_irq_mask |= pipe_event; 123 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); 124 PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); 125 gma_power_end(dev_priv->dev); 126 } 127} 128 129static void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe) 130{ 131 if (dev_priv->pipestat[pipe] == 0) { 132 if (gma_power_begin(dev_priv->dev, false)) { 133 u32 pipe_event = mid_pipe_event(pipe); 134 dev_priv->vdc_irq_mask &= ~pipe_event; 135 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); 136 PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); 137 gma_power_end(dev_priv->dev); 138 } 139 } 140} 141 142/** 143 * Display controller interrupt handler for pipe event. 144 * 145 */ 146static void mid_pipe_event_handler(struct drm_device *dev, int pipe) 147{ 148 struct drm_psb_private *dev_priv = 149 (struct drm_psb_private *) dev->dev_private; 150 151 uint32_t pipe_stat_val = 0; 152 uint32_t pipe_stat_reg = psb_pipestat(pipe); 153 uint32_t pipe_enable = dev_priv->pipestat[pipe]; 154 uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16; 155 uint32_t pipe_clear; 156 uint32_t i = 0; 157 158 spin_lock(&dev_priv->irqmask_lock); 159 160 pipe_stat_val = PSB_RVDC32(pipe_stat_reg); 161 pipe_stat_val &= pipe_enable | pipe_status; 162 pipe_stat_val &= pipe_stat_val >> 16; 163 164 spin_unlock(&dev_priv->irqmask_lock); 165 166 /* Clear the 2nd level interrupt status bits 167 * Sometimes the bits are very sticky so we repeat until they unstick */ 168 for (i = 0; i < 0xffff; i++) { 169 PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg); 170 pipe_clear = PSB_RVDC32(pipe_stat_reg) & pipe_status; 171 172 if (pipe_clear == 0) 173 break; 174 } 175 176 if (pipe_clear) 177 dev_err(dev->dev, 178 "%s, can't clear status bits for pipe %d, its value = 0x%x.\n", 179 __func__, pipe, PSB_RVDC32(pipe_stat_reg)); 180 181 if (pipe_stat_val & PIPE_VBLANK_STATUS) 182 drm_handle_vblank(dev, pipe); 183 184 if (pipe_stat_val & PIPE_TE_STATUS) 185 drm_handle_vblank(dev, pipe); 186} 187 188/* 189 * Display controller interrupt handler. 190 */ 191static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) 192{ 193 if (vdc_stat & _PSB_IRQ_ASLE) 194 psb_intel_opregion_asle_intr(dev); 195 196 if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG) 197 mid_pipe_event_handler(dev, 0); 198 199 if (vdc_stat & _PSB_VSYNC_PIPEB_FLAG) 200 mid_pipe_event_handler(dev, 1); 201} 202 203/* 204 * SGX interrupt handler 205 */ 206static void psb_sgx_interrupt(struct drm_device *dev, u32 stat_1, u32 stat_2) 207{ 208 struct drm_psb_private *dev_priv = dev->dev_private; 209 u32 val, addr; 210 int error = false; 211 212 if (stat_1 & _PSB_CE_TWOD_COMPLETE) 213 val = PSB_RSGX32(PSB_CR_2D_BLIT_STATUS); 214 215 if (stat_2 & _PSB_CE2_BIF_REQUESTER_FAULT) { 216 val = PSB_RSGX32(PSB_CR_BIF_INT_STAT); 217 addr = PSB_RSGX32(PSB_CR_BIF_FAULT); 218 if (val) { 219 if (val & _PSB_CBI_STAT_PF_N_RW) 220 DRM_ERROR("SGX MMU page fault:"); 221 else 222 DRM_ERROR("SGX MMU read / write protection fault:"); 223 224 if (val & _PSB_CBI_STAT_FAULT_CACHE) 225 DRM_ERROR("\tCache requestor"); 226 if (val & _PSB_CBI_STAT_FAULT_TA) 227 DRM_ERROR("\tTA requestor"); 228 if (val & _PSB_CBI_STAT_FAULT_VDM) 229 DRM_ERROR("\tVDM requestor"); 230 if (val & _PSB_CBI_STAT_FAULT_2D) 231 DRM_ERROR("\t2D requestor"); 232 if (val & _PSB_CBI_STAT_FAULT_PBE) 233 DRM_ERROR("\tPBE requestor"); 234 if (val & _PSB_CBI_STAT_FAULT_TSP) 235 DRM_ERROR("\tTSP requestor"); 236 if (val & _PSB_CBI_STAT_FAULT_ISP) 237 DRM_ERROR("\tISP requestor"); 238 if (val & _PSB_CBI_STAT_FAULT_USSEPDS) 239 DRM_ERROR("\tUSSEPDS requestor"); 240 if (val & _PSB_CBI_STAT_FAULT_HOST) 241 DRM_ERROR("\tHost requestor"); 242 243 DRM_ERROR("\tMMU failing address is 0x%08x.\n", 244 (unsigned int)addr); 245 error = true; 246 } 247 } 248 249 /* Clear bits */ 250 PSB_WSGX32(stat_1, PSB_CR_EVENT_HOST_CLEAR); 251 PSB_WSGX32(stat_2, PSB_CR_EVENT_HOST_CLEAR2); 252 PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR2); 253} 254 255irqreturn_t psb_irq_handler(int irq, void *arg) 256{ 257 struct drm_device *dev = arg; 258 struct drm_psb_private *dev_priv = dev->dev_private; 259 uint32_t vdc_stat, dsp_int = 0, sgx_int = 0, hotplug_int = 0; 260 u32 sgx_stat_1, sgx_stat_2; 261 int handled = 0; 262 263 spin_lock(&dev_priv->irqmask_lock); 264 265 vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R); 266 267 if (vdc_stat & (_PSB_PIPE_EVENT_FLAG|_PSB_IRQ_ASLE)) 268 dsp_int = 1; 269 270 /* FIXME: Handle Medfield 271 if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG) 272 dsp_int = 1; 273 */ 274 275 if (vdc_stat & _PSB_IRQ_SGX_FLAG) 276 sgx_int = 1; 277 if (vdc_stat & _PSB_IRQ_DISP_HOTSYNC) 278 hotplug_int = 1; 279 280 vdc_stat &= dev_priv->vdc_irq_mask; 281 spin_unlock(&dev_priv->irqmask_lock); 282 283 if (dsp_int && gma_power_is_on(dev)) { 284 psb_vdc_interrupt(dev, vdc_stat); 285 handled = 1; 286 } 287 288 if (sgx_int) { 289 sgx_stat_1 = PSB_RSGX32(PSB_CR_EVENT_STATUS); 290 sgx_stat_2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2); 291 psb_sgx_interrupt(dev, sgx_stat_1, sgx_stat_2); 292 handled = 1; 293 } 294 295 /* Note: this bit has other meanings on some devices, so we will 296 need to address that later if it ever matters */ 297 if (hotplug_int && dev_priv->ops->hotplug) { 298 handled = dev_priv->ops->hotplug(dev); 299 REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT)); 300 } 301 302 PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R); 303 (void) PSB_RVDC32(PSB_INT_IDENTITY_R); 304 rmb(); 305 306 if (!handled) 307 return IRQ_NONE; 308 309 return IRQ_HANDLED; 310} 311 312void psb_irq_preinstall(struct drm_device *dev) 313{ 314 struct drm_psb_private *dev_priv = 315 (struct drm_psb_private *) dev->dev_private; 316 unsigned long irqflags; 317 318 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 319 320 if (gma_power_is_on(dev)) { 321 PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); 322 PSB_WVDC32(0x00000000, PSB_INT_MASK_R); 323 PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R); 324 PSB_WSGX32(0x00000000, PSB_CR_EVENT_HOST_ENABLE); 325 PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE); 326 } 327 if (dev->vblank[0].enabled) 328 dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG; 329 if (dev->vblank[1].enabled) 330 dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG; 331 332 /* FIXME: Handle Medfield irq mask 333 if (dev->vblank[1].enabled) 334 dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG; 335 if (dev->vblank[2].enabled) 336 dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; 337 */ 338 339 /* Revisit this area - want per device masks ? */ 340 if (dev_priv->ops->hotplug) 341 dev_priv->vdc_irq_mask |= _PSB_IRQ_DISP_HOTSYNC; 342 dev_priv->vdc_irq_mask |= _PSB_IRQ_ASLE | _PSB_IRQ_SGX_FLAG; 343 344 /* This register is safe even if display island is off */ 345 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); 346 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 347} 348 349int psb_irq_postinstall(struct drm_device *dev) 350{ 351 struct drm_psb_private *dev_priv = dev->dev_private; 352 unsigned long irqflags; 353 354 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 355 356 /* Enable 2D and MMU fault interrupts */ 357 PSB_WSGX32(_PSB_CE2_BIF_REQUESTER_FAULT, PSB_CR_EVENT_HOST_ENABLE2); 358 PSB_WSGX32(_PSB_CE_TWOD_COMPLETE, PSB_CR_EVENT_HOST_ENABLE); 359 PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE); /* Post */ 360 361 /* This register is safe even if display island is off */ 362 PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); 363 PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); 364 365 if (dev->vblank[0].enabled) 366 psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); 367 else 368 psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); 369 370 if (dev->vblank[1].enabled) 371 psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); 372 else 373 psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); 374 375 if (dev->vblank[2].enabled) 376 psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); 377 else 378 psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); 379 380 if (dev_priv->ops->hotplug_enable) 381 dev_priv->ops->hotplug_enable(dev, true); 382 383 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 384 return 0; 385} 386 387void psb_irq_uninstall(struct drm_device *dev) 388{ 389 struct drm_psb_private *dev_priv = dev->dev_private; 390 unsigned long irqflags; 391 392 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 393 394 if (dev_priv->ops->hotplug_enable) 395 dev_priv->ops->hotplug_enable(dev, false); 396 397 PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); 398 399 if (dev->vblank[0].enabled) 400 psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); 401 402 if (dev->vblank[1].enabled) 403 psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); 404 405 if (dev->vblank[2].enabled) 406 psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); 407 408 dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG | 409 _PSB_IRQ_MSVDX_FLAG | 410 _LNC_IRQ_TOPAZ_FLAG; 411 412 /* These two registers are safe even if display island is off */ 413 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); 414 PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); 415 416 wmb(); 417 418 /* This register is safe even if display island is off */ 419 PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R); 420 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 421} 422 423void psb_irq_turn_on_dpst(struct drm_device *dev) 424{ 425 struct drm_psb_private *dev_priv = 426 (struct drm_psb_private *) dev->dev_private; 427 u32 hist_reg; 428 u32 pwm_reg; 429 430 if (gma_power_begin(dev, false)) { 431 PSB_WVDC32(1 << 31, HISTOGRAM_LOGIC_CONTROL); 432 hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); 433 PSB_WVDC32(1 << 31, HISTOGRAM_INT_CONTROL); 434 hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); 435 436 PSB_WVDC32(0x80010100, PWM_CONTROL_LOGIC); 437 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 438 PSB_WVDC32(pwm_reg | PWM_PHASEIN_ENABLE 439 | PWM_PHASEIN_INT_ENABLE, 440 PWM_CONTROL_LOGIC); 441 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 442 443 psb_enable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); 444 445 hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); 446 PSB_WVDC32(hist_reg | HISTOGRAM_INT_CTRL_CLEAR, 447 HISTOGRAM_INT_CONTROL); 448 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 449 PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE, 450 PWM_CONTROL_LOGIC); 451 452 gma_power_end(dev); 453 } 454} 455 456int psb_irq_enable_dpst(struct drm_device *dev) 457{ 458 struct drm_psb_private *dev_priv = 459 (struct drm_psb_private *) dev->dev_private; 460 unsigned long irqflags; 461 462 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 463 464 /* enable DPST */ 465 mid_enable_pipe_event(dev_priv, 0); 466 psb_irq_turn_on_dpst(dev); 467 468 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 469 return 0; 470} 471 472void psb_irq_turn_off_dpst(struct drm_device *dev) 473{ 474 struct drm_psb_private *dev_priv = 475 (struct drm_psb_private *) dev->dev_private; 476 u32 hist_reg; 477 u32 pwm_reg; 478 479 if (gma_power_begin(dev, false)) { 480 PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL); 481 hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); 482 483 psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); 484 485 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 486 PSB_WVDC32(pwm_reg & ~PWM_PHASEIN_INT_ENABLE, 487 PWM_CONTROL_LOGIC); 488 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 489 490 gma_power_end(dev); 491 } 492} 493 494int psb_irq_disable_dpst(struct drm_device *dev) 495{ 496 struct drm_psb_private *dev_priv = 497 (struct drm_psb_private *) dev->dev_private; 498 unsigned long irqflags; 499 500 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 501 502 mid_disable_pipe_event(dev_priv, 0); 503 psb_irq_turn_off_dpst(dev); 504 505 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 506 507 return 0; 508} 509 510/* 511 * It is used to enable VBLANK interrupt 512 */ 513int psb_enable_vblank(struct drm_device *dev, int pipe) 514{ 515 struct drm_psb_private *dev_priv = dev->dev_private; 516 unsigned long irqflags; 517 uint32_t reg_val = 0; 518 uint32_t pipeconf_reg = mid_pipeconf(pipe); 519 520 /* Medfield is different - we should perhaps extract out vblank 521 and blacklight etc ops */ 522 if (IS_MFLD(dev)) 523 return mdfld_enable_te(dev, pipe); 524 525 if (gma_power_begin(dev, false)) { 526 reg_val = REG_READ(pipeconf_reg); 527 gma_power_end(dev); 528 } 529 530 if (!(reg_val & PIPEACONF_ENABLE)) 531 return -EINVAL; 532 533 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 534 535 if (pipe == 0) 536 dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG; 537 else if (pipe == 1) 538 dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG; 539 540 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); 541 PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); 542 psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); 543 544 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 545 546 return 0; 547} 548 549/* 550 * It is used to disable VBLANK interrupt 551 */ 552void psb_disable_vblank(struct drm_device *dev, int pipe) 553{ 554 struct drm_psb_private *dev_priv = dev->dev_private; 555 unsigned long irqflags; 556 557 if (IS_MFLD(dev)) 558 mdfld_disable_te(dev, pipe); 559 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 560 561 if (pipe == 0) 562 dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEA_FLAG; 563 else if (pipe == 1) 564 dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEB_FLAG; 565 566 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); 567 PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); 568 psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); 569 570 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 571} 572 573/* 574 * It is used to enable TE interrupt 575 */ 576int mdfld_enable_te(struct drm_device *dev, int pipe) 577{ 578 struct drm_psb_private *dev_priv = 579 (struct drm_psb_private *) dev->dev_private; 580 unsigned long irqflags; 581 uint32_t reg_val = 0; 582 uint32_t pipeconf_reg = mid_pipeconf(pipe); 583 584 if (gma_power_begin(dev, false)) { 585 reg_val = REG_READ(pipeconf_reg); 586 gma_power_end(dev); 587 } 588 589 if (!(reg_val & PIPEACONF_ENABLE)) 590 return -EINVAL; 591 592 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 593 594 mid_enable_pipe_event(dev_priv, pipe); 595 psb_enable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE); 596 597 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 598 599 return 0; 600} 601 602/* 603 * It is used to disable TE interrupt 604 */ 605void mdfld_disable_te(struct drm_device *dev, int pipe) 606{ 607 struct drm_psb_private *dev_priv = 608 (struct drm_psb_private *) dev->dev_private; 609 unsigned long irqflags; 610 611 if (!dev_priv->dsr_enable) 612 return; 613 614 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 615 616 mid_disable_pipe_event(dev_priv, pipe); 617 psb_disable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE); 618 619 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 620} 621 622/* Called from drm generic code, passed a 'crtc', which 623 * we use as a pipe index 624 */ 625u32 psb_get_vblank_counter(struct drm_device *dev, int pipe) 626{ 627 uint32_t high_frame = PIPEAFRAMEHIGH; 628 uint32_t low_frame = PIPEAFRAMEPIXEL; 629 uint32_t pipeconf_reg = PIPEACONF; 630 uint32_t reg_val = 0; 631 uint32_t high1 = 0, high2 = 0, low = 0, count = 0; 632 633 switch (pipe) { 634 case 0: 635 break; 636 case 1: 637 high_frame = PIPEBFRAMEHIGH; 638 low_frame = PIPEBFRAMEPIXEL; 639 pipeconf_reg = PIPEBCONF; 640 break; 641 case 2: 642 high_frame = PIPECFRAMEHIGH; 643 low_frame = PIPECFRAMEPIXEL; 644 pipeconf_reg = PIPECCONF; 645 break; 646 default: 647 dev_err(dev->dev, "%s, invalid pipe.\n", __func__); 648 return 0; 649 } 650 651 if (!gma_power_begin(dev, false)) 652 return 0; 653 654 reg_val = REG_READ(pipeconf_reg); 655 656 if (!(reg_val & PIPEACONF_ENABLE)) { 657 dev_err(dev->dev, "trying to get vblank count for disabled pipe %d\n", 658 pipe); 659 goto psb_get_vblank_counter_exit; 660 } 661 662 /* 663 * High & low register fields aren't synchronized, so make sure 664 * we get a low value that's stable across two reads of the high 665 * register. 666 */ 667 do { 668 high1 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> 669 PIPE_FRAME_HIGH_SHIFT); 670 low = ((REG_READ(low_frame) & PIPE_FRAME_LOW_MASK) >> 671 PIPE_FRAME_LOW_SHIFT); 672 high2 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> 673 PIPE_FRAME_HIGH_SHIFT); 674 } while (high1 != high2); 675 676 count = (high1 << 8) | low; 677 678psb_get_vblank_counter_exit: 679 680 gma_power_end(dev); 681 682 return count; 683} 684 685