[PATCH 4/5] drm/tegra: Implement VBLANK support

2013-01-31 Thread Daniel Vetter
On Thu, Jan 31, 2013 at 3:06 AM, Mario Kleiner
 wrote:
> At least AMD hw as of a while ago didn't, older intel hw didn't (afaik), and
> NVidia i don't know. You'd also need hw vblank timestamps and counters
> independent of page-flip completion to not regress existing important
> functionality if you want to get rid of the irq based method.

Intel hw has counters+timestamps for pageflips and vblanks, so you get
the cake and eat it, too. I'm also aware of your stringent
requirements wrt timestamps, so the recently pimped kms_flip test we
have for drm/i915.ko checks vblank timestamps, pageflip timestamps and
whether those don't get out of sync somehow in a rather anal way.
Results thus far is that the current vblank stuff is (at least for
intel) pretty horribly broken - QA reported random and sometimes
not-so-random failures across all generations.

So we still have plenty of fixing to do until we can get around to
implement pageflip timestamping without the irq vblank running all the
time.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


[PATCH 4/5] drm/tegra: Implement VBLANK support

2013-01-31 Thread Mario Kleiner
On 30.01.13 13:36, Daniel Vetter wrote:
> On Wed, Jan 30, 2013 at 9:34 AM, Thierry Reding
>  wrote:
>> On Tue, Jan 22, 2013 at 10:21:40AM -0800, Jon Mayo wrote:
>>> On Mon, Jan 14, 2013 at 7:55 AM, Thierry Reding
>>>  wrote:
 Implement support for the VBLANK IOCTL. Note that Tegra is somewhat
 special in this case because it doesn't use the generic IRQ support
 provided by the DRM core (DRIVER_HAVE_IRQ) but rather registers one
 interrupt handler for each display controller.

 While at it, clean up the way that interrupts are enabled to ensure
 that the VBLANK interrupt only gets enabled when required.

 Signed-off-by: Thierry Reding 
 ---
>>>
>>> Sorry Thierry, but is this a useful feature? Are applications really
>>> making use of it? Because it means that that an IRQ will have to
>>> trigger every 16.67ms when it is taken, which means the device can't
>>> sleep. (probably OK because it should go back to idle when the app
>>> lets go of the vblank). But worse, for one-shot panels there is no
>>> continuous vblank. I've been doing weird hacks to run a timer when the
>>> smart panel is idle to trick applications into thinking they have a
>>> vblank pulse. But really I think the whole feature of a vblank pulse
>>> is pretty lame and I wish it would die. Were you going to use it for
>>> something specific, or just adding it for completeness?
>>
>> This is mainly added for completeness. I know that on Tegra we can do a
>> lot better by using syncpoints, but applications such as Weston (in
>> general applications that use the generic DRM API) rely on this to sync
>> rendering with VBLANK.
>>
>> I don't think there's another way to achieve the same thing. And as you
>> already mentioned, this is only enabled when an application actively
>> uses it, in which case the device won't sleep anyway.
>
> I think driving animations with the vblank signal is nice, but we
> kinda only need that with the pageflip support. Unfortunately the
> current drm code is a bit a mess in that area, so pageflips force you
> to enable the vblank interrupt for otherwise the timestamp'ed pageflip
> completion events won't work.
>

Extensions like SGI_video_sync, OML_sync_control, INTEL_swap_events 
expose vblank counts and related functionality for synchronizing to the 
vblank and some applications really use and need them in addition to the 
pageflip timestamps, so you need a running reliable vblank counter to 
support these. Some scienctific/medical applications need to also 
synchronize things like audio playback or capture, or triggering of 
special research equipment (fMRI/MEG/EEG brain scanners and recordign 
equipment, eye trackers, TMS brain stimulators etc.) to the vblank of a 
completed or future bufferswap, with sometimes better than 1 msec 
precision, sometimes ahead of the event.

That we can't timestamp non-pageflipped swaps precisely/reliably is a 
limitation, not a feature for such uses.

> Recent intel hw has pageflip timestamp registers, so we don't really
> need that. And I guess other hw is similar. So we probably should
> clean up and untangle the infrastructure a bit around the drm vblank
> support code.

At least AMD hw as of a while ago didn't, older intel hw didn't (afaik), 
and NVidia i don't know. You'd also need hw vblank timestamps and 
counters independent of page-flip completion to not regress existing 
important functionality if you want to get rid of the irq based method.

-mario

>
> Another issue is that the vblank ioctl itself doesn't deal with
> modeset crtc ids, so adding a new interface for that would be good.
> Otoh most kms clients don't really use it, but only care about
> pageflips.
> -Daniel
>



Re: [PATCH 4/5] drm/tegra: Implement VBLANK support

2013-01-31 Thread Daniel Vetter
On Thu, Jan 31, 2013 at 3:06 AM, Mario Kleiner
mario.klei...@tuebingen.mpg.de wrote:
 At least AMD hw as of a while ago didn't, older intel hw didn't (afaik), and
 NVidia i don't know. You'd also need hw vblank timestamps and counters
 independent of page-flip completion to not regress existing important
 functionality if you want to get rid of the irq based method.

Intel hw has counters+timestamps for pageflips and vblanks, so you get
the cake and eat it, too. I'm also aware of your stringent
requirements wrt timestamps, so the recently pimped kms_flip test we
have for drm/i915.ko checks vblank timestamps, pageflip timestamps and
whether those don't get out of sync somehow in a rather anal way.
Results thus far is that the current vblank stuff is (at least for
intel) pretty horribly broken - QA reported random and sometimes
not-so-random failures across all generations.

So we still have plenty of fixing to do until we can get around to
implement pageflip timestamping without the irq vblank running all the
time.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 4/5] drm/tegra: Implement VBLANK support

2013-01-30 Thread Daniel Vetter
On Wed, Jan 30, 2013 at 9:34 AM, Thierry Reding
 wrote:
> On Tue, Jan 22, 2013 at 10:21:40AM -0800, Jon Mayo wrote:
>> On Mon, Jan 14, 2013 at 7:55 AM, Thierry Reding
>>  wrote:
>> > Implement support for the VBLANK IOCTL. Note that Tegra is somewhat
>> > special in this case because it doesn't use the generic IRQ support
>> > provided by the DRM core (DRIVER_HAVE_IRQ) but rather registers one
>> > interrupt handler for each display controller.
>> >
>> > While at it, clean up the way that interrupts are enabled to ensure
>> > that the VBLANK interrupt only gets enabled when required.
>> >
>> > Signed-off-by: Thierry Reding 
>> > ---
>>
>> Sorry Thierry, but is this a useful feature? Are applications really
>> making use of it? Because it means that that an IRQ will have to
>> trigger every 16.67ms when it is taken, which means the device can't
>> sleep. (probably OK because it should go back to idle when the app
>> lets go of the vblank). But worse, for one-shot panels there is no
>> continuous vblank. I've been doing weird hacks to run a timer when the
>> smart panel is idle to trick applications into thinking they have a
>> vblank pulse. But really I think the whole feature of a vblank pulse
>> is pretty lame and I wish it would die. Were you going to use it for
>> something specific, or just adding it for completeness?
>
> This is mainly added for completeness. I know that on Tegra we can do a
> lot better by using syncpoints, but applications such as Weston (in
> general applications that use the generic DRM API) rely on this to sync
> rendering with VBLANK.
>
> I don't think there's another way to achieve the same thing. And as you
> already mentioned, this is only enabled when an application actively
> uses it, in which case the device won't sleep anyway.

I think driving animations with the vblank signal is nice, but we
kinda only need that with the pageflip support. Unfortunately the
current drm code is a bit a mess in that area, so pageflips force you
to enable the vblank interrupt for otherwise the timestamp'ed pageflip
completion events won't work.

Recent intel hw has pageflip timestamp registers, so we don't really
need that. And I guess other hw is similar. So we probably should
clean up and untangle the infrastructure a bit around the drm vblank
support code.

Another issue is that the vblank ioctl itself doesn't deal with
modeset crtc ids, so adding a new interface for that would be good.
Otoh most kms clients don't really use it, but only care about
pageflips.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


[PATCH 4/5] drm/tegra: Implement VBLANK support

2013-01-30 Thread Thierry Reding
On Tue, Jan 22, 2013 at 10:21:40AM -0800, Jon Mayo wrote:
> On Mon, Jan 14, 2013 at 7:55 AM, Thierry Reding
>  wrote:
> > Implement support for the VBLANK IOCTL. Note that Tegra is somewhat
> > special in this case because it doesn't use the generic IRQ support
> > provided by the DRM core (DRIVER_HAVE_IRQ) but rather registers one
> > interrupt handler for each display controller.
> >
> > While at it, clean up the way that interrupts are enabled to ensure
> > that the VBLANK interrupt only gets enabled when required.
> >
> > Signed-off-by: Thierry Reding 
> > ---
> 
> Sorry Thierry, but is this a useful feature? Are applications really
> making use of it? Because it means that that an IRQ will have to
> trigger every 16.67ms when it is taken, which means the device can't
> sleep. (probably OK because it should go back to idle when the app
> lets go of the vblank). But worse, for one-shot panels there is no
> continuous vblank. I've been doing weird hacks to run a timer when the
> smart panel is idle to trick applications into thinking they have a
> vblank pulse. But really I think the whole feature of a vblank pulse
> is pretty lame and I wish it would die. Were you going to use it for
> something specific, or just adding it for completeness?

This is mainly added for completeness. I know that on Tegra we can do a
lot better by using syncpoints, but applications such as Weston (in
general applications that use the generic DRM API) rely on this to sync
rendering with VBLANK.

I don't think there's another way to achieve the same thing. And as you
already mentioned, this is only enabled when an application actively
uses it, in which case the device won't sleep anyway.

Thierry
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: 



Re: [PATCH 4/5] drm/tegra: Implement VBLANK support

2013-01-30 Thread Daniel Vetter
On Wed, Jan 30, 2013 at 9:34 AM, Thierry Reding
thierry.red...@avionic-design.de wrote:
 On Tue, Jan 22, 2013 at 10:21:40AM -0800, Jon Mayo wrote:
 On Mon, Jan 14, 2013 at 7:55 AM, Thierry Reding
 thierry.red...@avionic-design.de wrote:
  Implement support for the VBLANK IOCTL. Note that Tegra is somewhat
  special in this case because it doesn't use the generic IRQ support
  provided by the DRM core (DRIVER_HAVE_IRQ) but rather registers one
  interrupt handler for each display controller.
 
  While at it, clean up the way that interrupts are enabled to ensure
  that the VBLANK interrupt only gets enabled when required.
 
  Signed-off-by: Thierry Reding thierry.red...@avionic-design.de
  ---

 Sorry Thierry, but is this a useful feature? Are applications really
 making use of it? Because it means that that an IRQ will have to
 trigger every 16.67ms when it is taken, which means the device can't
 sleep. (probably OK because it should go back to idle when the app
 lets go of the vblank). But worse, for one-shot panels there is no
 continuous vblank. I've been doing weird hacks to run a timer when the
 smart panel is idle to trick applications into thinking they have a
 vblank pulse. But really I think the whole feature of a vblank pulse
 is pretty lame and I wish it would die. Were you going to use it for
 something specific, or just adding it for completeness?

 This is mainly added for completeness. I know that on Tegra we can do a
 lot better by using syncpoints, but applications such as Weston (in
 general applications that use the generic DRM API) rely on this to sync
 rendering with VBLANK.

 I don't think there's another way to achieve the same thing. And as you
 already mentioned, this is only enabled when an application actively
 uses it, in which case the device won't sleep anyway.

I think driving animations with the vblank signal is nice, but we
kinda only need that with the pageflip support. Unfortunately the
current drm code is a bit a mess in that area, so pageflips force you
to enable the vblank interrupt for otherwise the timestamp'ed pageflip
completion events won't work.

Recent intel hw has pageflip timestamp registers, so we don't really
need that. And I guess other hw is similar. So we probably should
clean up and untangle the infrastructure a bit around the drm vblank
support code.

Another issue is that the vblank ioctl itself doesn't deal with
modeset crtc ids, so adding a new interface for that would be good.
Otoh most kms clients don't really use it, but only care about
pageflips.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 4/5] drm/tegra: Implement VBLANK support

2013-01-30 Thread Mario Kleiner

On 30.01.13 13:36, Daniel Vetter wrote:

On Wed, Jan 30, 2013 at 9:34 AM, Thierry Reding
thierry.red...@avionic-design.de wrote:

On Tue, Jan 22, 2013 at 10:21:40AM -0800, Jon Mayo wrote:

On Mon, Jan 14, 2013 at 7:55 AM, Thierry Reding
thierry.red...@avionic-design.de wrote:

Implement support for the VBLANK IOCTL. Note that Tegra is somewhat
special in this case because it doesn't use the generic IRQ support
provided by the DRM core (DRIVER_HAVE_IRQ) but rather registers one
interrupt handler for each display controller.

While at it, clean up the way that interrupts are enabled to ensure
that the VBLANK interrupt only gets enabled when required.

Signed-off-by: Thierry Reding thierry.red...@avionic-design.de
---


Sorry Thierry, but is this a useful feature? Are applications really
making use of it? Because it means that that an IRQ will have to
trigger every 16.67ms when it is taken, which means the device can't
sleep. (probably OK because it should go back to idle when the app
lets go of the vblank). But worse, for one-shot panels there is no
continuous vblank. I've been doing weird hacks to run a timer when the
smart panel is idle to trick applications into thinking they have a
vblank pulse. But really I think the whole feature of a vblank pulse
is pretty lame and I wish it would die. Were you going to use it for
something specific, or just adding it for completeness?


This is mainly added for completeness. I know that on Tegra we can do a
lot better by using syncpoints, but applications such as Weston (in
general applications that use the generic DRM API) rely on this to sync
rendering with VBLANK.

I don't think there's another way to achieve the same thing. And as you
already mentioned, this is only enabled when an application actively
uses it, in which case the device won't sleep anyway.


I think driving animations with the vblank signal is nice, but we
kinda only need that with the pageflip support. Unfortunately the
current drm code is a bit a mess in that area, so pageflips force you
to enable the vblank interrupt for otherwise the timestamp'ed pageflip
completion events won't work.



Extensions like SGI_video_sync, OML_sync_control, INTEL_swap_events 
expose vblank counts and related functionality for synchronizing to the 
vblank and some applications really use and need them in addition to the 
pageflip timestamps, so you need a running reliable vblank counter to 
support these. Some scienctific/medical applications need to also 
synchronize things like audio playback or capture, or triggering of 
special research equipment (fMRI/MEG/EEG brain scanners and recordign 
equipment, eye trackers, TMS brain stimulators etc.) to the vblank of a 
completed or future bufferswap, with sometimes better than 1 msec 
precision, sometimes ahead of the event.


That we can't timestamp non-pageflipped swaps precisely/reliably is a 
limitation, not a feature for such uses.



Recent intel hw has pageflip timestamp registers, so we don't really
need that. And I guess other hw is similar. So we probably should
clean up and untangle the infrastructure a bit around the drm vblank
support code.


At least AMD hw as of a while ago didn't, older intel hw didn't (afaik), 
and NVidia i don't know. You'd also need hw vblank timestamps and 
counters independent of page-flip completion to not regress existing 
important functionality if you want to get rid of the irq based method.


-mario



Another issue is that the vblank ioctl itself doesn't deal with
modeset crtc ids, so adding a new interface for that would be good.
Otoh most kms clients don't really use it, but only care about
pageflips.
-Daniel



___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 4/5] drm/tegra: Implement VBLANK support

2013-01-23 Thread Mark Zhang
On 01/23/2013 02:21 AM, Jon Mayo wrote:
> On Mon, Jan 14, 2013 at 7:55 AM, Thierry Reding
>  wrote:
>> Implement support for the VBLANK IOCTL. Note that Tegra is somewhat
>> special in this case because it doesn't use the generic IRQ support
>> provided by the DRM core (DRIVER_HAVE_IRQ) but rather registers one
>> interrupt handler for each display controller.
>>
>> While at it, clean up the way that interrupts are enabled to ensure
>> that the VBLANK interrupt only gets enabled when required.
>>
>> Signed-off-by: Thierry Reding 
>> ---
> 
> Sorry Thierry, but is this a useful feature? Are applications really
> making use of it? Because it means that that an IRQ will have to
> trigger every 16.67ms when it is taken, which means the device can't
> sleep. (probably OK because it should go back to idle when the app
> lets go of the vblank). But worse, for one-shot panels there is no
> continuous vblank. I've been doing weird hacks to run a timer when the
> smart panel is idle to trick applications into thinking they have a
> vblank pulse. But really I think the whole feature of a vblank pulse
> is pretty lame and I wish it would die. Were you going to use it for
> something specific, or just adding it for completeness?
> 

I guess people don't use this to really wait vblanks because that can be
done by polling drm fd. Normally they use this ioctl to get the vblank
counts which may be useful for their applications.

Mark
> - Jon
> --
> To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


Re: [PATCH 4/5] drm/tegra: Implement VBLANK support

2013-01-23 Thread Mark Zhang
On 01/23/2013 02:21 AM, Jon Mayo wrote:
 On Mon, Jan 14, 2013 at 7:55 AM, Thierry Reding
 thierry.red...@avionic-design.de wrote:
 Implement support for the VBLANK IOCTL. Note that Tegra is somewhat
 special in this case because it doesn't use the generic IRQ support
 provided by the DRM core (DRIVER_HAVE_IRQ) but rather registers one
 interrupt handler for each display controller.

 While at it, clean up the way that interrupts are enabled to ensure
 that the VBLANK interrupt only gets enabled when required.

 Signed-off-by: Thierry Reding thierry.red...@avionic-design.de
 ---
 
 Sorry Thierry, but is this a useful feature? Are applications really
 making use of it? Because it means that that an IRQ will have to
 trigger every 16.67ms when it is taken, which means the device can't
 sleep. (probably OK because it should go back to idle when the app
 lets go of the vblank). But worse, for one-shot panels there is no
 continuous vblank. I've been doing weird hacks to run a timer when the
 smart panel is idle to trick applications into thinking they have a
 vblank pulse. But really I think the whole feature of a vblank pulse
 is pretty lame and I wish it would die. Were you going to use it for
 something specific, or just adding it for completeness?
 

I guess people don't use this to really wait vblanks because that can be
done by polling drm fd. Normally they use this ioctl to get the vblank
counts which may be useful for their applications.

Mark
 - Jon
 --
 To unsubscribe from this list: send the line unsubscribe linux-tegra in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 4/5] drm/tegra: Implement VBLANK support

2013-01-22 Thread Jon Mayo
On Mon, Jan 14, 2013 at 7:55 AM, Thierry Reding
 wrote:
> Implement support for the VBLANK IOCTL. Note that Tegra is somewhat
> special in this case because it doesn't use the generic IRQ support
> provided by the DRM core (DRIVER_HAVE_IRQ) but rather registers one
> interrupt handler for each display controller.
>
> While at it, clean up the way that interrupts are enabled to ensure
> that the VBLANK interrupt only gets enabled when required.
>
> Signed-off-by: Thierry Reding 
> ---

Sorry Thierry, but is this a useful feature? Are applications really
making use of it? Because it means that that an IRQ will have to
trigger every 16.67ms when it is taken, which means the device can't
sleep. (probably OK because it should go back to idle when the app
lets go of the vblank). But worse, for one-shot panels there is no
continuous vblank. I've been doing weird hacks to run a timer when the
smart panel is idle to trick applications into thinking they have a
vblank pulse. But really I think the whole feature of a vblank pulse
is pretty lame and I wish it would die. Were you going to use it for
something specific, or just adding it for completeness?

- Jon


Re: [PATCH 4/5] drm/tegra: Implement VBLANK support

2013-01-22 Thread Jon Mayo
On Mon, Jan 14, 2013 at 7:55 AM, Thierry Reding
thierry.red...@avionic-design.de wrote:
 Implement support for the VBLANK IOCTL. Note that Tegra is somewhat
 special in this case because it doesn't use the generic IRQ support
 provided by the DRM core (DRIVER_HAVE_IRQ) but rather registers one
 interrupt handler for each display controller.

 While at it, clean up the way that interrupts are enabled to ensure
 that the VBLANK interrupt only gets enabled when required.

 Signed-off-by: Thierry Reding thierry.red...@avionic-design.de
 ---

Sorry Thierry, but is this a useful feature? Are applications really
making use of it? Because it means that that an IRQ will have to
trigger every 16.67ms when it is taken, which means the device can't
sleep. (probably OK because it should go back to idle when the app
lets go of the vblank). But worse, for one-shot panels there is no
continuous vblank. I've been doing weird hacks to run a timer when the
smart panel is idle to trick applications into thinking they have a
vblank pulse. But really I think the whole feature of a vblank pulse
is pretty lame and I wish it would die. Were you going to use it for
something specific, or just adding it for completeness?

- Jon
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 4/5] drm/tegra: Implement VBLANK support

2013-01-14 Thread Thierry Reding
Implement support for the VBLANK IOCTL. Note that Tegra is somewhat
special in this case because it doesn't use the generic IRQ support
provided by the DRM core (DRIVER_HAVE_IRQ) but rather registers one
interrupt handler for each display controller.

While at it, clean up the way that interrupts are enabled to ensure
that the VBLANK interrupt only gets enabled when required.

Signed-off-by: Thierry Reding 
---
 drivers/gpu/drm/tegra/dc.c  | 55 +++--
 drivers/gpu/drm/tegra/drm.c | 44 
 drivers/gpu/drm/tegra/drm.h |  3 +++
 3 files changed, 85 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 8dd7d8a..3aa7ccc 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -135,6 +135,32 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, 
int y,
return 0;
 }

+void tegra_dc_enable_vblank(struct tegra_dc *dc)
+{
+   unsigned long value, flags;
+
+   spin_lock_irqsave(>lock, flags);
+
+   value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
+   value |= VBLANK_INT;
+   tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
+
+   spin_unlock_irqrestore(>lock, flags);
+}
+
+void tegra_dc_disable_vblank(struct tegra_dc *dc)
+{
+   unsigned long value, flags;
+
+   spin_lock_irqsave(>lock, flags);
+
+   value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
+   value &= ~VBLANK_INT;
+   tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
+
+   spin_unlock_irqrestore(>lock, flags);
+}
+
 static const struct drm_crtc_funcs tegra_crtc_funcs = {
.set_config = drm_crtc_helper_set_config,
.destroy = drm_crtc_cleanup,
@@ -375,6 +401,8 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc,
unsigned long div, value;
int err;

+   drm_vblank_pre_modeset(crtc->dev, dc->pipe);
+
err = tegra_crtc_setup_clk(crtc, mode, );
if (err) {
dev_err(dc->dev, "failed to setup clock for CRTC: %d\n", err);
@@ -476,31 +504,23 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc)
tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);

value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
-   tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
-
-   value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
+
+   value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
+   tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
 }

 static void tegra_crtc_commit(struct drm_crtc *crtc)
 {
struct tegra_dc *dc = to_tegra_dc(crtc);
-   unsigned long update_mask;
unsigned long value;

-   update_mask = GENERAL_ACT_REQ | WIN_A_ACT_REQ;
-
-   tegra_dc_writel(dc, update_mask << 8, DC_CMD_STATE_CONTROL);
-
-   value = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
-   value |= FRAME_END_INT;
-   tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
+   value = GENERAL_ACT_REQ | WIN_A_ACT_REQ |
+   GENERAL_UPDATE | WIN_A_UPDATE;

-   value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
-   value |= FRAME_END_INT;
-   tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
+   tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);

-   tegra_dc_writel(dc, update_mask, DC_CMD_STATE_CONTROL);
+   drm_vblank_post_modeset(crtc->dev, dc->pipe);
 }

 static void tegra_crtc_load_lut(struct drm_crtc *crtc)
@@ -517,7 +537,7 @@ static const struct drm_crtc_helper_funcs 
tegra_crtc_helper_funcs = {
.load_lut = tegra_crtc_load_lut,
 };

-static irqreturn_t tegra_drm_irq(int irq, void *data)
+static irqreturn_t tegra_dc_irq(int irq, void *data)
 {
struct tegra_dc *dc = data;
unsigned long status;
@@ -862,7 +882,7 @@ static int tegra_dc_drm_init(struct host1x_client *client,
dev_err(dc->dev, "debugfs setup failed: %d\n", err);
}

-   err = devm_request_irq(dc->dev, dc->irq, tegra_drm_irq, 0,
+   err = devm_request_irq(dc->dev, dc->irq, tegra_dc_irq, 0,
   dev_name(dc->dev), dc);
if (err < 0) {
dev_err(dc->dev, "failed to request IRQ#%u: %d\n", dc->irq,
@@ -911,6 +931,7 @@ static int tegra_dc_probe(struct platform_device *pdev)
if (!dc)
return -ENOMEM;

+   spin_lock_init(>lock);
INIT_LIST_HEAD(>list);
dc->dev = >dev;

diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 3a503c9..62f8121 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -40,6 +40,10 @@ static int tegra_drm_load(struct drm_device *drm, unsigned 
long flags)
if (err < 0)
return err;

+   err = drm_vblank_init(drm, drm->mode_config.num_crtc);
+   if (err < 0)
+   return err;
+
err = tegra_drm_fb_init(drm);
if (err < 0)
return err;
@@ -89,6 +93,42 

[PATCH 4/5] drm/tegra: Implement VBLANK support

2013-01-14 Thread Thierry Reding
Implement support for the VBLANK IOCTL. Note that Tegra is somewhat
special in this case because it doesn't use the generic IRQ support
provided by the DRM core (DRIVER_HAVE_IRQ) but rather registers one
interrupt handler for each display controller.

While at it, clean up the way that interrupts are enabled to ensure
that the VBLANK interrupt only gets enabled when required.

Signed-off-by: Thierry Reding thierry.red...@avionic-design.de
---
 drivers/gpu/drm/tegra/dc.c  | 55 +++--
 drivers/gpu/drm/tegra/drm.c | 44 
 drivers/gpu/drm/tegra/drm.h |  3 +++
 3 files changed, 85 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 8dd7d8a..3aa7ccc 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -135,6 +135,32 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, 
int y,
return 0;
 }
 
+void tegra_dc_enable_vblank(struct tegra_dc *dc)
+{
+   unsigned long value, flags;
+
+   spin_lock_irqsave(dc-lock, flags);
+
+   value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
+   value |= VBLANK_INT;
+   tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
+
+   spin_unlock_irqrestore(dc-lock, flags);
+}
+
+void tegra_dc_disable_vblank(struct tegra_dc *dc)
+{
+   unsigned long value, flags;
+
+   spin_lock_irqsave(dc-lock, flags);
+
+   value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
+   value = ~VBLANK_INT;
+   tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
+
+   spin_unlock_irqrestore(dc-lock, flags);
+}
+
 static const struct drm_crtc_funcs tegra_crtc_funcs = {
.set_config = drm_crtc_helper_set_config,
.destroy = drm_crtc_cleanup,
@@ -375,6 +401,8 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc,
unsigned long div, value;
int err;
 
+   drm_vblank_pre_modeset(crtc-dev, dc-pipe);
+
err = tegra_crtc_setup_clk(crtc, mode, div);
if (err) {
dev_err(dc-dev, failed to setup clock for CRTC: %d\n, err);
@@ -476,31 +504,23 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc)
tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
 
value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
-   tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
-
-   value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
+
+   value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
+   tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
 }
 
 static void tegra_crtc_commit(struct drm_crtc *crtc)
 {
struct tegra_dc *dc = to_tegra_dc(crtc);
-   unsigned long update_mask;
unsigned long value;
 
-   update_mask = GENERAL_ACT_REQ | WIN_A_ACT_REQ;
-
-   tegra_dc_writel(dc, update_mask  8, DC_CMD_STATE_CONTROL);
-
-   value = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
-   value |= FRAME_END_INT;
-   tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
+   value = GENERAL_ACT_REQ | WIN_A_ACT_REQ |
+   GENERAL_UPDATE | WIN_A_UPDATE;
 
-   value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
-   value |= FRAME_END_INT;
-   tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
+   tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
 
-   tegra_dc_writel(dc, update_mask, DC_CMD_STATE_CONTROL);
+   drm_vblank_post_modeset(crtc-dev, dc-pipe);
 }
 
 static void tegra_crtc_load_lut(struct drm_crtc *crtc)
@@ -517,7 +537,7 @@ static const struct drm_crtc_helper_funcs 
tegra_crtc_helper_funcs = {
.load_lut = tegra_crtc_load_lut,
 };
 
-static irqreturn_t tegra_drm_irq(int irq, void *data)
+static irqreturn_t tegra_dc_irq(int irq, void *data)
 {
struct tegra_dc *dc = data;
unsigned long status;
@@ -862,7 +882,7 @@ static int tegra_dc_drm_init(struct host1x_client *client,
dev_err(dc-dev, debugfs setup failed: %d\n, err);
}
 
-   err = devm_request_irq(dc-dev, dc-irq, tegra_drm_irq, 0,
+   err = devm_request_irq(dc-dev, dc-irq, tegra_dc_irq, 0,
   dev_name(dc-dev), dc);
if (err  0) {
dev_err(dc-dev, failed to request IRQ#%u: %d\n, dc-irq,
@@ -911,6 +931,7 @@ static int tegra_dc_probe(struct platform_device *pdev)
if (!dc)
return -ENOMEM;
 
+   spin_lock_init(dc-lock);
INIT_LIST_HEAD(dc-list);
dc-dev = pdev-dev;
 
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 3a503c9..62f8121 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -40,6 +40,10 @@ static int tegra_drm_load(struct drm_device *drm, unsigned 
long flags)
if (err  0)
return err;
 
+   err = drm_vblank_init(drm, drm-mode_config.num_crtc);
+   if (err  0)
+   return err;
+
err = tegra_drm_fb_init(drm);
if (err  0)