diff options
Diffstat (limited to 'drivers/gpu/drm/r128')
-rw-r--r-- | drivers/gpu/drm/r128/r128_drv.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/r128/r128_drv.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/r128/r128_irq.c | 55 |
3 files changed, 57 insertions, 38 deletions
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c index 6108e7587e12..3265d53ba91f 100644 --- a/drivers/gpu/drm/r128/r128_drv.c +++ b/drivers/gpu/drm/r128/r128_drv.c | |||
@@ -43,12 +43,13 @@ static struct pci_device_id pciidlist[] = { | |||
43 | static struct drm_driver driver = { | 43 | static struct drm_driver driver = { |
44 | .driver_features = | 44 | .driver_features = |
45 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | | 45 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | |
46 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | | 46 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, |
47 | DRIVER_IRQ_VBL, | ||
48 | .dev_priv_size = sizeof(drm_r128_buf_priv_t), | 47 | .dev_priv_size = sizeof(drm_r128_buf_priv_t), |
49 | .preclose = r128_driver_preclose, | 48 | .preclose = r128_driver_preclose, |
50 | .lastclose = r128_driver_lastclose, | 49 | .lastclose = r128_driver_lastclose, |
51 | .vblank_wait = r128_driver_vblank_wait, | 50 | .get_vblank_counter = r128_get_vblank_counter, |
51 | .enable_vblank = r128_enable_vblank, | ||
52 | .disable_vblank = r128_disable_vblank, | ||
52 | .irq_preinstall = r128_driver_irq_preinstall, | 53 | .irq_preinstall = r128_driver_irq_preinstall, |
53 | .irq_postinstall = r128_driver_irq_postinstall, | 54 | .irq_postinstall = r128_driver_irq_postinstall, |
54 | .irq_uninstall = r128_driver_irq_uninstall, | 55 | .irq_uninstall = r128_driver_irq_uninstall, |
@@ -59,21 +60,20 @@ static struct drm_driver driver = { | |||
59 | .ioctls = r128_ioctls, | 60 | .ioctls = r128_ioctls, |
60 | .dma_ioctl = r128_cce_buffers, | 61 | .dma_ioctl = r128_cce_buffers, |
61 | .fops = { | 62 | .fops = { |
62 | .owner = THIS_MODULE, | 63 | .owner = THIS_MODULE, |
63 | .open = drm_open, | 64 | .open = drm_open, |
64 | .release = drm_release, | 65 | .release = drm_release, |
65 | .ioctl = drm_ioctl, | 66 | .ioctl = drm_ioctl, |
66 | .mmap = drm_mmap, | 67 | .mmap = drm_mmap, |
67 | .poll = drm_poll, | 68 | .poll = drm_poll, |
68 | .fasync = drm_fasync, | 69 | .fasync = drm_fasync, |
69 | #ifdef CONFIG_COMPAT | 70 | #ifdef CONFIG_COMPAT |
70 | .compat_ioctl = r128_compat_ioctl, | 71 | .compat_ioctl = r128_compat_ioctl, |
71 | #endif | 72 | #endif |
72 | }, | 73 | }, |
73 | |||
74 | .pci_driver = { | 74 | .pci_driver = { |
75 | .name = DRIVER_NAME, | 75 | .name = DRIVER_NAME, |
76 | .id_table = pciidlist, | 76 | .id_table = pciidlist, |
77 | }, | 77 | }, |
78 | 78 | ||
79 | .name = DRIVER_NAME, | 79 | .name = DRIVER_NAME, |
@@ -87,6 +87,7 @@ static struct drm_driver driver = { | |||
87 | static int __init r128_init(void) | 87 | static int __init r128_init(void) |
88 | { | 88 | { |
89 | driver.num_ioctls = r128_max_ioctl; | 89 | driver.num_ioctls = r128_max_ioctl; |
90 | |||
90 | return drm_init(&driver); | 91 | return drm_init(&driver); |
91 | } | 92 | } |
92 | 93 | ||
diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h index 011105e51ac6..5898b274279d 100644 --- a/drivers/gpu/drm/r128/r128_drv.h +++ b/drivers/gpu/drm/r128/r128_drv.h | |||
@@ -29,7 +29,7 @@ | |||
29 | * Rickard E. (Rik) Faith <faith@valinux.com> | 29 | * Rickard E. (Rik) Faith <faith@valinux.com> |
30 | * Kevin E. Martin <martin@valinux.com> | 30 | * Kevin E. Martin <martin@valinux.com> |
31 | * Gareth Hughes <gareth@valinux.com> | 31 | * Gareth Hughes <gareth@valinux.com> |
32 | * Michel Dänzer <daenzerm@student.ethz.ch> | 32 | * Michel D�zer <daenzerm@student.ethz.ch> |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #ifndef __R128_DRV_H__ | 35 | #ifndef __R128_DRV_H__ |
@@ -97,6 +97,8 @@ typedef struct drm_r128_private { | |||
97 | u32 crtc_offset; | 97 | u32 crtc_offset; |
98 | u32 crtc_offset_cntl; | 98 | u32 crtc_offset_cntl; |
99 | 99 | ||
100 | atomic_t vbl_received; | ||
101 | |||
100 | u32 color_fmt; | 102 | u32 color_fmt; |
101 | unsigned int front_offset; | 103 | unsigned int front_offset; |
102 | unsigned int front_pitch; | 104 | unsigned int front_pitch; |
@@ -149,11 +151,12 @@ extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n); | |||
149 | extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); | 151 | extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); |
150 | extern int r128_do_cleanup_cce(struct drm_device * dev); | 152 | extern int r128_do_cleanup_cce(struct drm_device * dev); |
151 | 153 | ||
152 | extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); | 154 | extern int r128_enable_vblank(struct drm_device *dev, int crtc); |
153 | 155 | extern void r128_disable_vblank(struct drm_device *dev, int crtc); | |
156 | extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc); | ||
154 | extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); | 157 | extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); |
155 | extern void r128_driver_irq_preinstall(struct drm_device * dev); | 158 | extern void r128_driver_irq_preinstall(struct drm_device * dev); |
156 | extern void r128_driver_irq_postinstall(struct drm_device * dev); | 159 | extern int r128_driver_irq_postinstall(struct drm_device *dev); |
157 | extern void r128_driver_irq_uninstall(struct drm_device * dev); | 160 | extern void r128_driver_irq_uninstall(struct drm_device * dev); |
158 | extern void r128_driver_lastclose(struct drm_device * dev); | 161 | extern void r128_driver_lastclose(struct drm_device * dev); |
159 | extern void r128_driver_preclose(struct drm_device * dev, | 162 | extern void r128_driver_preclose(struct drm_device * dev, |
diff --git a/drivers/gpu/drm/r128/r128_irq.c b/drivers/gpu/drm/r128/r128_irq.c index c76fdca7662d..d7349012a680 100644 --- a/drivers/gpu/drm/r128/r128_irq.c +++ b/drivers/gpu/drm/r128/r128_irq.c | |||
@@ -35,6 +35,16 @@ | |||
35 | #include "r128_drm.h" | 35 | #include "r128_drm.h" |
36 | #include "r128_drv.h" | 36 | #include "r128_drv.h" |
37 | 37 | ||
38 | u32 r128_get_vblank_counter(struct drm_device *dev, int crtc) | ||
39 | { | ||
40 | const drm_r128_private_t *dev_priv = dev->dev_private; | ||
41 | |||
42 | if (crtc != 0) | ||
43 | return 0; | ||
44 | |||
45 | return atomic_read(&dev_priv->vbl_received); | ||
46 | } | ||
47 | |||
38 | irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) | 48 | irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) |
39 | { | 49 | { |
40 | struct drm_device *dev = (struct drm_device *) arg; | 50 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -46,30 +56,38 @@ irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) | |||
46 | /* VBLANK interrupt */ | 56 | /* VBLANK interrupt */ |
47 | if (status & R128_CRTC_VBLANK_INT) { | 57 | if (status & R128_CRTC_VBLANK_INT) { |
48 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); | 58 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); |
49 | atomic_inc(&dev->vbl_received); | 59 | atomic_inc(&dev_priv->vbl_received); |
50 | DRM_WAKEUP(&dev->vbl_queue); | 60 | drm_handle_vblank(dev, 0); |
51 | drm_vbl_send_signals(dev); | ||
52 | return IRQ_HANDLED; | 61 | return IRQ_HANDLED; |
53 | } | 62 | } |
54 | return IRQ_NONE; | 63 | return IRQ_NONE; |
55 | } | 64 | } |
56 | 65 | ||
57 | int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) | 66 | int r128_enable_vblank(struct drm_device *dev, int crtc) |
58 | { | 67 | { |
59 | unsigned int cur_vblank; | 68 | drm_r128_private_t *dev_priv = dev->dev_private; |
60 | int ret = 0; | ||
61 | 69 | ||
62 | /* Assume that the user has missed the current sequence number | 70 | if (crtc != 0) { |
63 | * by about a day rather than she wants to wait for years | 71 | DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); |
64 | * using vertical blanks... | 72 | return -EINVAL; |
65 | */ | 73 | } |
66 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | ||
67 | (((cur_vblank = atomic_read(&dev->vbl_received)) | ||
68 | - *sequence) <= (1 << 23))); | ||
69 | 74 | ||
70 | *sequence = cur_vblank; | 75 | R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); |
76 | return 0; | ||
77 | } | ||
78 | |||
79 | void r128_disable_vblank(struct drm_device *dev, int crtc) | ||
80 | { | ||
81 | if (crtc != 0) | ||
82 | DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); | ||
71 | 83 | ||
72 | return ret; | 84 | /* |
85 | * FIXME: implement proper interrupt disable by using the vblank | ||
86 | * counter register (if available) | ||
87 | * | ||
88 | * R128_WRITE(R128_GEN_INT_CNTL, | ||
89 | * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN); | ||
90 | */ | ||
73 | } | 91 | } |
74 | 92 | ||
75 | void r128_driver_irq_preinstall(struct drm_device * dev) | 93 | void r128_driver_irq_preinstall(struct drm_device * dev) |
@@ -82,12 +100,9 @@ void r128_driver_irq_preinstall(struct drm_device * dev) | |||
82 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); | 100 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); |
83 | } | 101 | } |
84 | 102 | ||
85 | void r128_driver_irq_postinstall(struct drm_device * dev) | 103 | int r128_driver_irq_postinstall(struct drm_device *dev) |
86 | { | 104 | { |
87 | drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; | 105 | return drm_vblank_init(dev, 1); |
88 | |||
89 | /* Turn on VBL interrupt */ | ||
90 | R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); | ||
91 | } | 106 | } |
92 | 107 | ||
93 | void r128_driver_irq_uninstall(struct drm_device * dev) | 108 | void r128_driver_irq_uninstall(struct drm_device * dev) |