Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1512574 > unrolled thread
| Started by | Bartosz Golaszewski <bgolaszewski@baylibre.com> |
|---|---|
| First post | 2016-10-31 15:30 +0100 |
| Last post | 2016-11-01 15:30 +0100 |
| Articles | 5 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH v5 0/2] drm: tilcdc: improved support for rev1 Bartosz Golaszewski <bgolaszewski@baylibre.com> - 2016-10-31 15:30 +0100
[PATCH v5 2/2] drm: tilcdc: clear the sync lost bit in crtc isr Bartosz Golaszewski <bgolaszewski@baylibre.com> - 2016-10-31 15:30 +0100
Re: [PATCH v5 2/2] drm: tilcdc: clear the sync lost bit in crtc isr Karl Beldan <karl.beldan@gmail.com> - 2016-10-31 17:40 +0100
Re: [PATCH v5 2/2] drm: tilcdc: clear the sync lost bit in crtc isr Jyri Sarha <jsarha@ti.com> - 2016-11-01 15:30 +0100
Re: [PATCH v5 2/2] drm: tilcdc: clear the sync lost bit in crtc isr Jyri Sarha <jsarha@ti.com> - 2016-11-01 15:30 +0100
| From | Bartosz Golaszewski <bgolaszewski@baylibre.com> |
|---|---|
| Date | 2016-10-31 15:30 +0100 |
| Subject | [PATCH v5 0/2] drm: tilcdc: improved support for rev1 |
| Message-ID | <sylL3-3AW-15@gated-at.bofh.it> |
This series contains two patches needed to support revision 1 of the LCD controller on da850 SoCs. The first one implements palette loading - this is a resend of v4 of the stand-alone patch. The second resets the input FIFO in the DMA controller if a sync lost error occurs and disables the interrupt completely if we're being flooded with these errors. v1 -> v2: - only allocate dma memory for revision 1 v2 -> v3: - use devres managed API for dma memory allocation v3 -> v4: - reinit the palette completion in tilcdc_crtc_disable() v4 -> v5: - add a second patch clearing the sync lost bit in case of a sync lost error due to insufficient bandwidth Bartosz Golaszewski (2): drm: tilcdc: implement palette loading for rev1 drm: tilcdc: clear the sync lost bit in crtc isr drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 138 +++++++++++++++++++++++++++++++---- drivers/gpu/drm/tilcdc/tilcdc_regs.h | 1 + 2 files changed, 124 insertions(+), 15 deletions(-) -- 2.9.3
[toc] | [next] | [standalone]
| From | Bartosz Golaszewski <bgolaszewski@baylibre.com> |
|---|---|
| Date | 2016-10-31 15:30 +0100 |
| Subject | [PATCH v5 2/2] drm: tilcdc: clear the sync lost bit in crtc isr |
| Message-ID | <sylL3-3AW-19@gated-at.bofh.it> |
| In reply to | #1512574 |
The frame synchronization error happens when the DMA engine attempts
to read what it believes to be the first word of the video buffer but
it cannot be recognized as such or when the LCDC is starved of data
due to insufficient bandwidth of the system interconnect.
On some SoCs (notably: da850) the memory settings do not meet the
LCDC throughput requirements even after increasing the memory
controller command re-ordering and the LDCD master peripheral
priority, sometimes causing the sync lost error (typically when
changing the resolution).
When the sync lost error occurs, simply reset the input FIFO in the
DMA controller unless a sync lost flood is detected in which case
disable the interrupt.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 50 ++++++++++++++++++++++++++----------
drivers/gpu/drm/tilcdc/tilcdc_regs.h | 1 +
2 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 937697d..c4c6323 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -163,7 +163,7 @@ static void tilcdc_crtc_enable_irqs(struct drm_device *dev)
if (priv->rev == 1) {
tilcdc_set(dev, LCDC_RASTER_CTRL_REG,
- LCDC_V1_UNDERFLOW_INT_ENA);
+ LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_SYNC_LOST_ENA);
tilcdc_set(dev, LCDC_DMA_CTRL_REG,
LCDC_V1_END_OF_FRAME_INT_ENA);
} else {
@@ -181,7 +181,9 @@ static void tilcdc_crtc_disable_irqs(struct drm_device *dev)
/* disable irqs that we might have enabled: */
if (priv->rev == 1) {
tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
- LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA);
+ LCDC_V1_UNDERFLOW_INT_ENA |
+ LCDC_V1_PL_INT_ENA |
+ LCDC_V1_SYNC_LOST_ENA);
tilcdc_clear(dev, LCDC_DMA_CTRL_REG,
LCDC_V1_END_OF_FRAME_INT_ENA);
} else {
@@ -885,24 +887,44 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
wake_up(&tilcdc_crtc->frame_done_wq);
}
- if (stat & LCDC_SYNC_LOST) {
- dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost",
- __func__, stat);
- tilcdc_crtc->frame_intact = false;
- if (tilcdc_crtc->sync_lost_count++ >
- SYNC_LOST_COUNT_LIMIT) {
- dev_err(dev->dev, "%s(0x%08x): Sync lost flood detected, disabling the interrupt", __func__, stat);
- tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
- LCDC_SYNC_LOST);
- }
- }
-
/* Indicate to LCDC that the interrupt service routine has
* completed, see 13.3.6.1.6 in AM335x TRM.
*/
tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0);
}
+ if (stat & LCDC_SYNC_LOST) {
+ dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost",
+ __func__, stat);
+
+ tilcdc_crtc->frame_intact = false;
+ if (tilcdc_crtc->sync_lost_count++ > SYNC_LOST_COUNT_LIMIT) {
+ dev_err(dev->dev,
+ "%s(0x%08x): Sync lost flood detected, disabling the interrupt",
+ __func__, stat);
+ if (priv->rev == 2)
+ tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
+ LCDC_SYNC_LOST);
+ else if (priv->rev == 1)
+ tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
+ LCDC_V1_SYNC_LOST_ENA);
+ }
+
+ if (priv->rev == 2) {
+ /*
+ * Indicate to LCDC that the interrupt service routine
+ * has completed, see 13.3.6.1.6 in AM335x TRM.
+ */
+ tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0);
+ } else if (priv->rev == 1) {
+ /* Reset the input FIFO in the DMA controller. */
+ tilcdc_clear(dev,
+ LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
+ tilcdc_set(dev,
+ LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
+ }
+ }
+
return IRQ_HANDLED;
}
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_regs.h b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
index f57c0d6..beb8c21 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_regs.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
@@ -61,6 +61,7 @@
#define LCDC_V2_UNDERFLOW_INT_ENA BIT(5)
#define LCDC_V1_PL_INT_ENA BIT(4)
#define LCDC_V2_PL_INT_ENA BIT(6)
+#define LCDC_V1_SYNC_LOST_ENA BIT(5)
#define LCDC_MONOCHROME_MODE BIT(1)
#define LCDC_RASTER_ENABLE BIT(0)
#define LCDC_TFT_ALT_ENABLE BIT(23)
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Karl Beldan <karl.beldan@gmail.com> |
|---|---|
| Date | 2016-10-31 17:40 +0100 |
| Subject | Re: [PATCH v5 2/2] drm: tilcdc: clear the sync lost bit in crtc isr |
| Message-ID | <synMR-4SB-15@gated-at.bofh.it> |
| In reply to | #1512575 |
Hi,
On Mon, Oct 31, 2016 at 2:19 PM, Bartosz Golaszewski
<bgolaszewski@baylibre.com> wrote:
> The frame synchronization error happens when the DMA engine attempts
> to read what it believes to be the first word of the video buffer but
> it cannot be recognized as such or when the LCDC is starved of data
> due to insufficient bandwidth of the system interconnect.
>
This also happens when the framebuffer boundaries are "incorrect", eg
when flipping while the crtc is enabled. The driver doesn't handle it yet,
so working around it is made via toggling LCDC_RASTER_ENABLE as
you put in this change, it is worth noting because that's how modetest
for example can "seem" to work with v1 when handling SYNC_LOST
and is partly why the "vsynced page flipping" of modetest won't work
either with v1 ATM. I haven't looked at the different trees since early
september but my guess would be that nobody has reworked this yet.
> On some SoCs (notably: da850) the memory settings do not meet the
> LCDC throughput requirements even after increasing the memory
> controller command re-ordering and the LDCD master peripheral
> priority, sometimes causing the sync lost error (typically when
> changing the resolution).
>
> When the sync lost error occurs, simply reset the input FIFO in the
> DMA controller unless a sync lost flood is detected in which case
> disable the interrupt.
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> ---
> drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 50 ++++++++++++++++++++++++++----------
> drivers/gpu/drm/tilcdc/tilcdc_regs.h | 1 +
> 2 files changed, 37 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> index 937697d..c4c6323 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> @@ -163,7 +163,7 @@ static void tilcdc_crtc_enable_irqs(struct drm_device *dev)
>
> if (priv->rev == 1) {
> tilcdc_set(dev, LCDC_RASTER_CTRL_REG,
> - LCDC_V1_UNDERFLOW_INT_ENA);
> + LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_SYNC_LOST_ENA);
> tilcdc_set(dev, LCDC_DMA_CTRL_REG,
> LCDC_V1_END_OF_FRAME_INT_ENA);
> } else {
> @@ -181,7 +181,9 @@ static void tilcdc_crtc_disable_irqs(struct drm_device *dev)
> /* disable irqs that we might have enabled: */
> if (priv->rev == 1) {
> tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
> - LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA);
> + LCDC_V1_UNDERFLOW_INT_ENA |
> + LCDC_V1_PL_INT_ENA |
> + LCDC_V1_SYNC_LOST_ENA);
> tilcdc_clear(dev, LCDC_DMA_CTRL_REG,
> LCDC_V1_END_OF_FRAME_INT_ENA);
> } else {
> @@ -885,24 +887,44 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
> wake_up(&tilcdc_crtc->frame_done_wq);
> }
>
> - if (stat & LCDC_SYNC_LOST) {
> - dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost",
> - __func__, stat);
> - tilcdc_crtc->frame_intact = false;
> - if (tilcdc_crtc->sync_lost_count++ >
> - SYNC_LOST_COUNT_LIMIT) {
> - dev_err(dev->dev, "%s(0x%08x): Sync lost flood detected, disabling the interrupt", __func__, stat);
> - tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
> - LCDC_SYNC_LOST);
> - }
> - }
> -
> /* Indicate to LCDC that the interrupt service routine has
> * completed, see 13.3.6.1.6 in AM335x TRM.
> */
> tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0);
> }
>
> + if (stat & LCDC_SYNC_LOST) {
> + dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost",
> + __func__, stat);
> +
> + tilcdc_crtc->frame_intact = false;
> + if (tilcdc_crtc->sync_lost_count++ > SYNC_LOST_COUNT_LIMIT) {
> + dev_err(dev->dev,
> + "%s(0x%08x): Sync lost flood detected, disabling the interrupt",
> + __func__, stat);
> + if (priv->rev == 2)
> + tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
> + LCDC_SYNC_LOST);
> + else if (priv->rev == 1)
> + tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
> + LCDC_V1_SYNC_LOST_ENA);
> + }
> +
> + if (priv->rev == 2) {
> + /*
> + * Indicate to LCDC that the interrupt service routine
> + * has completed, see 13.3.6.1.6 in AM335x TRM.
> + */
> + tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0);
> + } else if (priv->rev == 1) {
> + /* Reset the input FIFO in the DMA controller. */
> + tilcdc_clear(dev,
> + LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
> + tilcdc_set(dev,
> + LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
Here you are leaving the RASTER_ENABLE bit set unconditionnally.
It is disabled in tilcdc_crtc_disable with the irqs on (for v2 to handle
the last vblank), if the controller loses sync in the window between
disabling it and disabling the irqs in tilcdc_crtc_disable it is likely to
be problematic for the next call to tilcdc_crtc_enable.
Regards,
Karl
[toc] | [prev] | [next] | [standalone]
| From | Jyri Sarha <jsarha@ti.com> |
|---|---|
| Date | 2016-11-01 15:30 +0100 |
| Subject | Re: [PATCH v5 2/2] drm: tilcdc: clear the sync lost bit in crtc isr |
| Message-ID | <syIeB-1oI-9@gated-at.bofh.it> |
| In reply to | #1512575 |
On 10/31/16 16:19, Bartosz Golaszewski wrote:
> The frame synchronization error happens when the DMA engine attempts
> to read what it believes to be the first word of the video buffer but
> it cannot be recognized as such or when the LCDC is starved of data
> due to insufficient bandwidth of the system interconnect.
>
> On some SoCs (notably: da850) the memory settings do not meet the
> LCDC throughput requirements even after increasing the memory
> controller command re-ordering and the LDCD master peripheral
> priority, sometimes causing the sync lost error (typically when
> changing the resolution).
>
> When the sync lost error occurs, simply reset the input FIFO in the
> DMA controller unless a sync lost flood is detected in which case
> disable the interrupt.
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> ---
> drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 50 ++++++++++++++++++++++++++----------
> drivers/gpu/drm/tilcdc/tilcdc_regs.h | 1 +
> 2 files changed, 37 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> index 937697d..c4c6323 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> @@ -163,7 +163,7 @@ static void tilcdc_crtc_enable_irqs(struct drm_device *dev)
>
> if (priv->rev == 1) {
> tilcdc_set(dev, LCDC_RASTER_CTRL_REG,
> - LCDC_V1_UNDERFLOW_INT_ENA);
> + LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_SYNC_LOST_ENA);
> tilcdc_set(dev, LCDC_DMA_CTRL_REG,
> LCDC_V1_END_OF_FRAME_INT_ENA);
> } else {
> @@ -181,7 +181,9 @@ static void tilcdc_crtc_disable_irqs(struct drm_device *dev)
> /* disable irqs that we might have enabled: */
> if (priv->rev == 1) {
> tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
> - LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA);
> + LCDC_V1_UNDERFLOW_INT_ENA |
> + LCDC_V1_PL_INT_ENA |
> + LCDC_V1_SYNC_LOST_ENA);
> tilcdc_clear(dev, LCDC_DMA_CTRL_REG,
> LCDC_V1_END_OF_FRAME_INT_ENA);
> } else {
> @@ -885,24 +887,44 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
> wake_up(&tilcdc_crtc->frame_done_wq);
> }
>
> - if (stat & LCDC_SYNC_LOST) {
> - dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost",
> - __func__, stat);
> - tilcdc_crtc->frame_intact = false;
> - if (tilcdc_crtc->sync_lost_count++ >
> - SYNC_LOST_COUNT_LIMIT) {
> - dev_err(dev->dev, "%s(0x%08x): Sync lost flood detected, disabling the interrupt", __func__, stat);
> - tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
> - LCDC_SYNC_LOST);
> - }
> - }
> -
> /* Indicate to LCDC that the interrupt service routine has
> * completed, see 13.3.6.1.6 in AM335x TRM.
> */
> tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0);
Oh, I think this should the last thing done in the irq routine, thought
I do not really know what it does :).
> }
>
> + if (stat & LCDC_SYNC_LOST) {
> + dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost",
> + __func__, stat);
> +
> + tilcdc_crtc->frame_intact = false;
> + if (tilcdc_crtc->sync_lost_count++ > SYNC_LOST_COUNT_LIMIT) {
> + dev_err(dev->dev,
> + "%s(0x%08x): Sync lost flood detected, disabling the interrupt",
> + __func__, stat);
> + if (priv->rev == 2)
> + tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
> + LCDC_SYNC_LOST);
> + else if (priv->rev == 1)
> + tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
> + LCDC_V1_SYNC_LOST_ENA);
> + }
> +
> + if (priv->rev == 2) {
> + /*
> + * Indicate to LCDC that the interrupt service routine
> + * has completed, see 13.3.6.1.6 in AM335x TRM.
> + */
> + tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0);
> + } else if (priv->rev == 1) {
> + /* Reset the input FIFO in the DMA controller. */
> + tilcdc_clear(dev,
> + LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
> + tilcdc_set(dev,
> + LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
> + }
> + }
> +
> return IRQ_HANDLED;
> }
>
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_regs.h b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
> index f57c0d6..beb8c21 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_regs.h
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
> @@ -61,6 +61,7 @@
> #define LCDC_V2_UNDERFLOW_INT_ENA BIT(5)
> #define LCDC_V1_PL_INT_ENA BIT(4)
> #define LCDC_V2_PL_INT_ENA BIT(6)
> +#define LCDC_V1_SYNC_LOST_ENA BIT(5)
> #define LCDC_MONOCHROME_MODE BIT(1)
> #define LCDC_RASTER_ENABLE BIT(0)
> #define LCDC_TFT_ALT_ENABLE BIT(23)
>
[toc] | [prev] | [next] | [standalone]
| From | Jyri Sarha <jsarha@ti.com> |
|---|---|
| Date | 2016-11-01 15:30 +0100 |
| Subject | Re: [PATCH v5 2/2] drm: tilcdc: clear the sync lost bit in crtc isr |
| Message-ID | <syIeB-1oI-13@gated-at.bofh.it> |
| In reply to | #1512575 |
On 10/31/16 16:19, Bartosz Golaszewski wrote:
> The frame synchronization error happens when the DMA engine attempts
> to read what it believes to be the first word of the video buffer but
> it cannot be recognized as such or when the LCDC is starved of data
> due to insufficient bandwidth of the system interconnect.
>
> On some SoCs (notably: da850) the memory settings do not meet the
> LCDC throughput requirements even after increasing the memory
> controller command re-ordering and the LDCD master peripheral
> priority, sometimes causing the sync lost error (typically when
> changing the resolution).
>
> When the sync lost error occurs, simply reset the input FIFO in the
> DMA controller unless a sync lost flood is detected in which case
> disable the interrupt.
>
I don't think the current behaviour after detecting a sync lost flood is
really good for ver2 either. The flood is an indication of an error
situation on LCDC IP and the picture on the screen may be corrupted.
Simply turning off the interrupt does not make the problem (specifically
the screen corruption) to go away.
I have a patch for an alternative approach that turns off the display
and resets the LCDC and turns it back on again. It fixes the sync lost
flood and the screen corruption (usually shifting to right and rolling
over to left hand side). According to my experiments the toggling of
raster to off and back on again does not fix the the flood or the the
screen corruption.
I think it is about time for me the send my sync lost flood patch
forward. Then you could extend it to work also on rev1 LCDC.
Best regards,
Jyri
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> ---
> drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 50 ++++++++++++++++++++++++++----------
> drivers/gpu/drm/tilcdc/tilcdc_regs.h | 1 +
> 2 files changed, 37 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> index 937697d..c4c6323 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
> @@ -163,7 +163,7 @@ static void tilcdc_crtc_enable_irqs(struct drm_device *dev)
>
> if (priv->rev == 1) {
> tilcdc_set(dev, LCDC_RASTER_CTRL_REG,
> - LCDC_V1_UNDERFLOW_INT_ENA);
> + LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_SYNC_LOST_ENA);
> tilcdc_set(dev, LCDC_DMA_CTRL_REG,
> LCDC_V1_END_OF_FRAME_INT_ENA);
> } else {
> @@ -181,7 +181,9 @@ static void tilcdc_crtc_disable_irqs(struct drm_device *dev)
> /* disable irqs that we might have enabled: */
> if (priv->rev == 1) {
> tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
> - LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA);
> + LCDC_V1_UNDERFLOW_INT_ENA |
> + LCDC_V1_PL_INT_ENA |
> + LCDC_V1_SYNC_LOST_ENA);
> tilcdc_clear(dev, LCDC_DMA_CTRL_REG,
> LCDC_V1_END_OF_FRAME_INT_ENA);
> } else {
> @@ -885,24 +887,44 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
> wake_up(&tilcdc_crtc->frame_done_wq);
> }
>
> - if (stat & LCDC_SYNC_LOST) {
> - dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost",
> - __func__, stat);
> - tilcdc_crtc->frame_intact = false;
> - if (tilcdc_crtc->sync_lost_count++ >
> - SYNC_LOST_COUNT_LIMIT) {
> - dev_err(dev->dev, "%s(0x%08x): Sync lost flood detected, disabling the interrupt", __func__, stat);
> - tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
> - LCDC_SYNC_LOST);
> - }
> - }
> -
> /* Indicate to LCDC that the interrupt service routine has
> * completed, see 13.3.6.1.6 in AM335x TRM.
> */
> tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0);
> }
>
> + if (stat & LCDC_SYNC_LOST) {
> + dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost",
> + __func__, stat);
> +
> + tilcdc_crtc->frame_intact = false;
> + if (tilcdc_crtc->sync_lost_count++ > SYNC_LOST_COUNT_LIMIT) {
> + dev_err(dev->dev,
> + "%s(0x%08x): Sync lost flood detected, disabling the interrupt",
> + __func__, stat);
> + if (priv->rev == 2)
> + tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
> + LCDC_SYNC_LOST);
> + else if (priv->rev == 1)
> + tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
> + LCDC_V1_SYNC_LOST_ENA);
> + }
> +
> + if (priv->rev == 2) {
> + /*
> + * Indicate to LCDC that the interrupt service routine
> + * has completed, see 13.3.6.1.6 in AM335x TRM.
> + */
> + tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0);
> + } else if (priv->rev == 1) {
> + /* Reset the input FIFO in the DMA controller. */
> + tilcdc_clear(dev,
> + LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
> + tilcdc_set(dev,
> + LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
> + }
> + }
> +
> return IRQ_HANDLED;
> }
>
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_regs.h b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
> index f57c0d6..beb8c21 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_regs.h
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
> @@ -61,6 +61,7 @@
> #define LCDC_V2_UNDERFLOW_INT_ENA BIT(5)
> #define LCDC_V1_PL_INT_ENA BIT(4)
> #define LCDC_V2_PL_INT_ENA BIT(6)
> +#define LCDC_V1_SYNC_LOST_ENA BIT(5)
> #define LCDC_MONOCHROME_MODE BIT(1)
> #define LCDC_RASTER_ENABLE BIT(0)
> #define LCDC_TFT_ALT_ENABLE BIT(23)
>
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web