0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include "mga_drv.h"
0035
0036 u32 mga_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
0037 {
0038 const drm_mga_private_t *const dev_priv =
0039 (drm_mga_private_t *) dev->dev_private;
0040
0041 if (pipe != 0)
0042 return 0;
0043
0044 return atomic_read(&dev_priv->vbl_received);
0045 }
0046
0047
0048 irqreturn_t mga_driver_irq_handler(int irq, void *arg)
0049 {
0050 struct drm_device *dev = (struct drm_device *) arg;
0051 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
0052 int status;
0053 int handled = 0;
0054
0055 status = MGA_READ(MGA_STATUS);
0056
0057
0058 if (status & MGA_VLINEPEN) {
0059 MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
0060 atomic_inc(&dev_priv->vbl_received);
0061 drm_handle_vblank(dev, 0);
0062 handled = 1;
0063 }
0064
0065
0066 if (status & MGA_SOFTRAPEN) {
0067 const u32 prim_start = MGA_READ(MGA_PRIMADDRESS);
0068 const u32 prim_end = MGA_READ(MGA_PRIMEND);
0069
0070
0071 MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR);
0072
0073
0074
0075
0076 if ((prim_start & ~0x03) != (prim_end & ~0x03))
0077 MGA_WRITE(MGA_PRIMEND, prim_end);
0078
0079 atomic_inc(&dev_priv->last_fence_retired);
0080 wake_up(&dev_priv->fence_queue);
0081 handled = 1;
0082 }
0083
0084 if (handled)
0085 return IRQ_HANDLED;
0086 return IRQ_NONE;
0087 }
0088
0089 int mga_enable_vblank(struct drm_device *dev, unsigned int pipe)
0090 {
0091 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
0092
0093 if (pipe != 0) {
0094 DRM_ERROR("tried to enable vblank on non-existent crtc %u\n",
0095 pipe);
0096 return 0;
0097 }
0098
0099 MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
0100 return 0;
0101 }
0102
0103
0104 void mga_disable_vblank(struct drm_device *dev, unsigned int pipe)
0105 {
0106 if (pipe != 0) {
0107 DRM_ERROR("tried to disable vblank on non-existent crtc %u\n",
0108 pipe);
0109 }
0110
0111
0112
0113
0114
0115
0116
0117 }
0118
0119 void mga_driver_fence_wait(struct drm_device *dev, unsigned int *sequence)
0120 {
0121 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
0122 unsigned int cur_fence;
0123
0124
0125
0126
0127
0128 wait_event_timeout(dev_priv->fence_queue,
0129 (((cur_fence = atomic_read(&dev_priv->last_fence_retired))
0130 - *sequence) <= (1 << 23)),
0131 msecs_to_jiffies(3000));
0132
0133 *sequence = cur_fence;
0134 }
0135
0136 void mga_driver_irq_preinstall(struct drm_device *dev)
0137 {
0138 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
0139
0140
0141 MGA_WRITE(MGA_IEN, 0);
0142
0143 MGA_WRITE(MGA_ICLEAR, ~0);
0144 }
0145
0146 int mga_driver_irq_postinstall(struct drm_device *dev)
0147 {
0148 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
0149
0150 init_waitqueue_head(&dev_priv->fence_queue);
0151
0152
0153
0154
0155 MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN);
0156 return 0;
0157 }
0158
0159 void mga_driver_irq_uninstall(struct drm_device *dev)
0160 {
0161 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
0162 if (!dev_priv)
0163 return;
0164
0165
0166 MGA_WRITE(MGA_IEN, 0);
0167
0168 dev->irq_enabled = false;
0169 }