Subversion Repositories Kolibri OS

Rev

Rev 2160 | Rev 3120 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2008 Advanced Micro Devices, Inc.
  3.  * Copyright 2008 Red Hat Inc.
  4.  * Copyright 2009 Jerome Glisse.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included in
  14.  * all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * OTHER DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors: Dave Airlie
  25.  *          Alex Deucher
  26.  *          Jerome Glisse
  27.  */
  28. #include <drm/drmP.h>
  29. #include <drm/drm_crtc_helper.h>
  30. #include <drm/radeon_drm.h>
  31. #include "radeon_reg.h"
  32. #include "radeon.h"
  33. #include "atom.h"
  34.  
  35. #define RADEON_WAIT_IDLE_TIMEOUT 200
  36.  
  37. struct radeon_device *main_device;
  38.  
  39. extern int irq_override;
  40.  
  41.  
  42. /**
  43.  * radeon_driver_irq_handler_kms - irq handler for KMS
  44.  *
  45.  * @DRM_IRQ_ARGS: args
  46.  *
  47.  * This is the irq handler for the radeon KMS driver (all asics).
  48.  * radeon_irq_process is a macro that points to the per-asic
  49.  * irq handler callback.
  50.  */
  51. void irq_handler_kms()
  52. {
  53.     radeon_irq_process(main_device);
  54. }
  55.  
  56. /**
  57.  * radeon_driver_irq_preinstall_kms - drm irq preinstall callback
  58.  *
  59.  * @dev: drm dev pointer
  60.  *
  61.  * Gets the hw ready to enable irqs (all asics).
  62.  * This function disables all interrupt sources on the GPU.
  63.  */
  64. void radeon_irq_preinstall_kms(struct radeon_device *rdev)
  65. {
  66.         unsigned long irqflags;
  67.     unsigned i;
  68.  
  69.         spin_lock_irqsave(&rdev->irq.lock, irqflags);
  70.     /* Disable *all* interrupts */
  71.         for (i = 0; i < RADEON_NUM_RINGS; i++)
  72.                 atomic_set(&rdev->irq.ring_int[i], 0);
  73.         for (i = 0; i < RADEON_MAX_HPD_PINS; i++)
  74.                 rdev->irq.hpd[i] = false;
  75.         for (i = 0; i < RADEON_MAX_CRTCS; i++) {
  76.         rdev->irq.crtc_vblank_int[i] = false;
  77.                 atomic_set(&rdev->irq.pflip[i], 0);
  78.                 rdev->irq.afmt[i] = false;
  79.     }
  80.     radeon_irq_set(rdev);
  81.         spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
  82.     /* Clear bits */
  83.     radeon_irq_process(rdev);
  84. }
  85.  
  86. /**
  87.  * radeon_driver_irq_postinstall_kms - drm irq preinstall callback
  88.  *
  89.  * @dev: drm dev pointer
  90.  *
  91.  * Handles stuff to be done after enabling irqs (all asics).
  92.  * Returns 0 on success.
  93.  */
  94.  
  95. int radeon_driver_irq_postinstall_kms(struct radeon_device *rdev)
  96. {
  97. //    struct radeon_device *rdev = dev->dev_private;
  98.  
  99. //    dev->max_vblank_count = 0x001fffff;
  100.  
  101.     radeon_irq_set(rdev);
  102.     return 0;
  103. }
  104.  
  105. /**
  106.  * radeon_irq_kms_init - init driver interrupt info
  107.  *
  108.  * @rdev: radeon device pointer
  109.  *
  110.  * Sets up the work irq handlers, vblank init, MSIs, etc. (all asics).
  111.  * Returns 0 for success, error for failure.
  112.  */
  113. int radeon_irq_kms_init(struct radeon_device *rdev)
  114. {
  115.     int irq_line;
  116.         int r = 0;
  117.  
  118.     ENTER();
  119.  
  120. //    INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
  121. //      INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
  122.  
  123.         spin_lock_init(&rdev->irq.lock);
  124. //   r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
  125. //   if (r) {
  126. //       return r;
  127. //   }
  128.         /* enable msi */
  129.         rdev->msi_enabled = 0;
  130.  
  131. //      if (radeon_msi_ok(rdev)) {
  132. //              int ret = pci_enable_msi(rdev->pdev);
  133. //              if (!ret) {
  134. //                      rdev->msi_enabled = 1;
  135. //                      dev_info(rdev->dev, "radeon: using MSI.\n");
  136. //              }
  137. //      }
  138.     rdev->irq.installed = true;
  139.     main_device = rdev;
  140.  
  141.     radeon_irq_preinstall_kms(rdev);
  142.  
  143.     if (irq_override)
  144.         irq_line = irq_override;
  145.     else
  146.         irq_line = rdev->pdev->irq;
  147.  
  148.     dbgprintf("%s install irq %d\n", __FUNCTION__, irq_line);
  149.  
  150.     AttachIntHandler(irq_line, irq_handler_kms, 2);
  151.  
  152. //   r = drm_irq_install(rdev->ddev);
  153.  
  154.     r = radeon_driver_irq_postinstall_kms(rdev);
  155.     if (r) {
  156.        rdev->irq.installed = false;
  157.         LEAVE();
  158.        return r;
  159.    }
  160.         DRM_INFO("radeon: irq initialized.\n");
  161.         return 0;
  162. }
  163.  
  164. /**
  165.  * radeon_irq_kms_fini - tear down driver interrrupt info
  166.  *
  167.  * @rdev: radeon device pointer
  168.  *
  169.  * Tears down the work irq handlers, vblank handlers, MSIs, etc. (all asics).
  170.  */
  171. void radeon_irq_kms_fini(struct radeon_device *rdev)
  172. {
  173. //      drm_vblank_cleanup(rdev->ddev);
  174.         if (rdev->irq.installed) {
  175. //              drm_irq_uninstall(rdev->ddev);
  176.                 rdev->irq.installed = false;
  177. //       if (rdev->msi_enabled)
  178. //                      pci_disable_msi(rdev->pdev);
  179.         }
  180. //      flush_work(&rdev->hotplug_work);
  181. }
  182.  
  183. /**
  184.  * radeon_irq_kms_sw_irq_get - enable software interrupt
  185.  *
  186.  * @rdev: radeon device pointer
  187.  * @ring: ring whose interrupt you want to enable
  188.  *
  189.  * Enables the software interrupt for a specific ring (all asics).
  190.  * The software interrupt is generally used to signal a fence on
  191.  * a particular ring.
  192.  */
  193. void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev, int ring)
  194. {
  195.         unsigned long irqflags;
  196.  
  197.         if (!rdev->ddev->irq_enabled)
  198.                 return;
  199.  
  200.         if (atomic_inc_return(&rdev->irq.ring_int[ring]) == 1) {
  201.                 spin_lock_irqsave(&rdev->irq.lock, irqflags);
  202.                 radeon_irq_set(rdev);
  203.                 spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
  204.         }
  205. }
  206.  
  207. /**
  208.  * radeon_irq_kms_sw_irq_put - disable software interrupt
  209.  *
  210.  * @rdev: radeon device pointer
  211.  * @ring: ring whose interrupt you want to disable
  212.  *
  213.  * Disables the software interrupt for a specific ring (all asics).
  214.  * The software interrupt is generally used to signal a fence on
  215.  * a particular ring.
  216.  */
  217. void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring)
  218. {
  219.         unsigned long irqflags;
  220.  
  221.         if (!rdev->ddev->irq_enabled)
  222.                 return;
  223.  
  224.         if (atomic_dec_and_test(&rdev->irq.ring_int[ring])) {
  225.                 spin_lock_irqsave(&rdev->irq.lock, irqflags);
  226.                 radeon_irq_set(rdev);
  227.                 spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
  228.         }
  229. }
  230.  
  231.  
  232.