mdp4_irq.c 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * Copyright (C) 2013 Red Hat
  3. * Author: Rob Clark <robdclark@gmail.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License version 2 as published by
  7. * the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "msm_drv.h"
  18. #include "mdp4_kms.h"
  19. void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask)
  20. {
  21. mdp4_write(to_mdp4_kms(mdp_kms), REG_MDP4_INTR_ENABLE, irqmask);
  22. }
  23. static void mdp4_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus)
  24. {
  25. DRM_ERROR("errors: %08x\n", irqstatus);
  26. }
  27. void mdp4_irq_preinstall(struct msm_kms *kms)
  28. {
  29. struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
  30. mdp4_enable(mdp4_kms);
  31. mdp4_write(mdp4_kms, REG_MDP4_INTR_CLEAR, 0xffffffff);
  32. mdp4_write(mdp4_kms, REG_MDP4_INTR_ENABLE, 0x00000000);
  33. mdp4_disable(mdp4_kms);
  34. }
  35. int mdp4_irq_postinstall(struct msm_kms *kms)
  36. {
  37. struct mdp_kms *mdp_kms = to_mdp_kms(kms);
  38. struct mdp4_kms *mdp4_kms = to_mdp4_kms(mdp_kms);
  39. struct mdp_irq *error_handler = &mdp4_kms->error_handler;
  40. error_handler->irq = mdp4_irq_error_handler;
  41. error_handler->irqmask = MDP4_IRQ_PRIMARY_INTF_UDERRUN |
  42. MDP4_IRQ_EXTERNAL_INTF_UDERRUN;
  43. mdp_irq_register(mdp_kms, error_handler);
  44. return 0;
  45. }
  46. void mdp4_irq_uninstall(struct msm_kms *kms)
  47. {
  48. struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
  49. mdp4_enable(mdp4_kms);
  50. mdp4_write(mdp4_kms, REG_MDP4_INTR_ENABLE, 0x00000000);
  51. mdp4_disable(mdp4_kms);
  52. }
  53. irqreturn_t mdp4_irq(struct msm_kms *kms)
  54. {
  55. struct mdp_kms *mdp_kms = to_mdp_kms(kms);
  56. struct mdp4_kms *mdp4_kms = to_mdp4_kms(mdp_kms);
  57. struct drm_device *dev = mdp4_kms->dev;
  58. struct msm_drm_private *priv = dev->dev_private;
  59. unsigned int id;
  60. uint32_t status;
  61. status = mdp4_read(mdp4_kms, REG_MDP4_INTR_STATUS);
  62. mdp4_write(mdp4_kms, REG_MDP4_INTR_CLEAR, status);
  63. VERB("status=%08x", status);
  64. mdp_dispatch_irqs(mdp_kms, status);
  65. for (id = 0; id < priv->num_crtcs; id++)
  66. if (status & mdp4_crtc_vblank(priv->crtcs[id]))
  67. drm_handle_vblank(dev, id);
  68. return IRQ_HANDLED;
  69. }
  70. int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
  71. {
  72. mdp_update_vblank_mask(to_mdp_kms(kms),
  73. mdp4_crtc_vblank(crtc), true);
  74. return 0;
  75. }
  76. void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
  77. {
  78. mdp_update_vblank_mask(to_mdp_kms(kms),
  79. mdp4_crtc_vblank(crtc), false);
  80. }