* [PATCH 4/5] xen-fbfront: handle backend CLOSED without CLOSING
From: David Vrabel @ 2012-10-18 10:03 UTC (permalink / raw)
To: xen-devel
Cc: David Vrabel, Konrad Rzeszutek Wilk, linux-kernel, linux-fbdev,
Florian Tobias Schandinat
In-Reply-To: <507FD39F.4060601@citrix.com>
From: David Vrabel <david.vrabel@citrix.com>
Backend drivers shouldn't transistion to CLOSED unless the frontend is
CLOSED. If a backend does transition to CLOSED too soon then the
frontend may not see the CLOSING state and will not properly shutdown.
So, treat an unexpected backend CLOSED state the same as CLOSING.
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
Cc: linux-fbdev@vger.kernel.org
Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
---
drivers/video/xen-fbfront.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
index b7f5173..917bb56 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -641,7 +641,6 @@ static void xenfb_backend_changed(struct xenbus_device *dev,
case XenbusStateReconfiguring:
case XenbusStateReconfigured:
case XenbusStateUnknown:
- case XenbusStateClosed:
break;
case XenbusStateInitWait:
@@ -670,6 +669,10 @@ InitWait:
info->feature_resize = val;
break;
+ case XenbusStateClosed:
+ if (dev->state = XenbusStateClosed)
+ break;
+ /* Missed the backend's CLOSING state -- fallthrough */
case XenbusStateClosing:
xenbus_frontend_closed(dev);
break;
--
1.7.2.5
^ permalink raw reply related
* [PATCH 0/5] drivers: xen frontend devices should handle missed backend CLOSING
From: David Vrabel @ 2012-10-18 10:02 UTC (permalink / raw)
To: xen-devel@lists.xensource.com, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, David S. Miller, Jens Axboe, linux-pci,
Bjorn Helgaas, linux-fbdev, Florian Tobias Schandinat,
linux-input, Dmitry Torokhov
Cc: David Vrabel
Subsystem maintainers, you can either pick up the relevant driver patch
or ack it to go via Konrad's Xen tree.
The series makes all the Xen frontend drivers handle the backend
transitioning to CLOSED without the frontend having previously seen
the backend in the CLOSING state.
Backends shouldn't do this but some do. e.g., if the host is
XenServer and the toolstack decides to do a forced shutdown of a VBD,
then the blkfront may miss the CLOSING transition and the /dev/xvdX
device will not be destroyed which prevents it being reused.
I have seen systems that ended up in this state but it's not clear if
this was the actual cause. However, I think in general it's a good
thing to thing to improve the handling of unexpected state
transitions.
David
^ permalink raw reply
* Re: [PATCHv3 0/5] OMAP: VRFB: convert to platform device
From: Tony Lindgren @ 2012-10-17 18:29 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, archit
In-Reply-To: <507E87B7.3070707@ti.com>
* Tomi Valkeinen <tomi.valkeinen@ti.com> [121017 03:27]:
> Hi Tony,
>
> I have pushed this vrfb series and the omapdss version series to:
>
> git://gitorious.org/linux-omap-dss2/linux.git 3.8/dss-version
I used this branch up to commit 35f70935c64ae229ebd1fc65398ec68d4d803712,
but left out the x86 compile changes as those seem unrelated to the plat
issue.
> git://gitorious.org/linux-omap-dss2/linux.git 3.8/vrfb-conversion
And then I merged in this branch. I have the merged branch at
omap-for-v3.8/cleanup-headers-dss.
> If they look ok to you and we don't get any other comments, I think
> these branches can be considered stable and you can pull them.
Thanks yes let's consider those frozen and if something needs to
be fixed it should be done on top of those commits.
> After these are merged:
>
> $ git grep -E "(plat/)|(mach/)" drivers/video/omap2/
> drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vram.h>
> drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vram.h>
> drivers/video/omap2/vram.c:#include <plat/vram.h>
>
> So the vram stuff should be the only omap dependency left in omapdss and
> omapfb. I'll start working on that soon.
OK thanks a lot. Then there's also the two vout files that
you may already have patches for:
drivers/media/platform/omap/omap_vout.c
drivers/media/platform/omap/omap_voutlib.c
Regards,
Tony
^ permalink raw reply
* Re: [PATCH 9/9] OMAPDSS: DISPC: cleanup lcd/digit enable/disable
From: Archit Taneja @ 2012-10-17 14:50 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev
In-Reply-To: <1350472835-28727-10-git-send-email-tomi.valkeinen@ti.com>
Hi,
On Wednesday 17 October 2012 04:50 PM, Tomi Valkeinen wrote:
> We currently have a single function to enable and disable the manager
> output for LCD and DIGIT. The functions are a bit complex, as handling
> both enable and disable require some extra steps to ensure that the
> output is enabled or disabled properly without errors before exiting the
> function.
>
> The code can be made simpler to understand by splitting the functions
> into separate enable and disable functions. We'll also clean up the
> comments and some parameter names at the same time.
>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---
> drivers/video/omap2/dss/apply.c | 6 +-
> drivers/video/omap2/dss/dispc.c | 178 ++++++++++++++++++++++++---------------
> drivers/video/omap2/dss/dss.h | 3 +-
> 3 files changed, 116 insertions(+), 71 deletions(-)
>
> diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
> index ae9f70d..4fff8ac 100644
> --- a/drivers/video/omap2/dss/apply.c
> +++ b/drivers/video/omap2/dss/apply.c
> @@ -772,7 +772,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
> if (!dss_data.irq_enabled && need_isr())
> dss_register_vsync_isr();
>
> - dispc_mgr_enable(mgr->id, true);
> + dispc_mgr_enable(mgr->id);
>
> mgr_clear_shadow_dirty(mgr);
>
> @@ -1027,7 +1027,7 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
> spin_unlock_irqrestore(&data_lock, flags);
>
> if (!mgr_manual_update(mgr))
> - dispc_mgr_enable(mgr->id, true);
> + dispc_mgr_enable(mgr->id);
>
> out:
> mutex_unlock(&apply_lock);
> @@ -1052,7 +1052,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
> goto out;
>
> if (!mgr_manual_update(mgr))
> - dispc_mgr_enable(mgr->id, false);
> + dispc_mgr_disable(mgr->id);
>
> spin_lock_irqsave(&data_lock, flags);
>
> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> index 82339ad..94f393ec 100644
> --- a/drivers/video/omap2/dss/dispc.c
> +++ b/drivers/video/omap2/dss/dispc.c
> @@ -2590,7 +2590,7 @@ int dispc_ovl_enable(enum omap_plane plane, bool enable)
> return 0;
> }
>
> -static void dispc_disable_isr(void *data, u32 mask)
> +static void dispc_mgr_disable_isr(void *data, u32 mask)
> {
> struct completion *compl = data;
> complete(compl);
> @@ -2608,122 +2608,166 @@ bool dispc_mgr_is_enabled(enum omap_channel channel)
> return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
> }
>
> -static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
> +static void dispc_mgr_enable_lcd_out(enum omap_channel channel)
> {
> - struct completion frame_done_completion;
> - bool is_on;
> + _enable_mgr_out(channel, true);
> +}
> +
> +static void dispc_mgr_disable_lcd_out(enum omap_channel channel)
> +{
> + DECLARE_COMPLETION_ONSTACK(framedone_compl);
> int r;
> u32 irq;
>
> - /* When we disable LCD output, we need to wait until frame is done.
> - * Otherwise the DSS is still working, and turning off the clocks
> - * prevents DSS from going to OFF mode */
> - is_on = dispc_mgr_is_enabled(channel);
> + if (dispc_mgr_is_enabled(channel) = false)
> + return;
> +
> + /*
> + * When we disable LCD output, we need to wait for FRAMEDONE to know
> + * that DISPC has finished with the LCD output.
> + */
>
> - irq = mgr_desc[channel].framedone_irq;
> + irq = dispc_mgr_get_framedone_irq(channel);
>
> - if (!enable && is_on) {
> - init_completion(&frame_done_completion);
> + r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
> + irq);
> + if (r)
> + DSSERR("failed to register FRAMEDONE isr\n");
>
> - r = omap_dispc_register_isr(dispc_disable_isr,
> - &frame_done_completion, irq);
> + _enable_mgr_out(channel, false);
>
> - if (r)
> - DSSERR("failed to register FRAMEDONE isr\n");
> + /* if we couldn't register for framedone, just sleep and exit */
> + if (r) {
> + msleep(200);
We sleep for 200 ms if we fail to register for framedone. But we just
wait for 100ms for FRAMEDONE to occur. It seems a bit incorrect, both
should be kept the same, shouldn't they?
> + return;
> }
>
> - _enable_mgr_out(channel, enable);
> + if (!wait_for_completion_timeout(&framedone_compl,
> + msecs_to_jiffies(100)))
> + DSSERR("timeout waiting for FRAME DONE\n");
>
> - if (!enable && is_on) {
> - if (!wait_for_completion_timeout(&frame_done_completion,
> - msecs_to_jiffies(100)))
> - DSSERR("timeout waiting for FRAME DONE\n");
> + r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
> + irq);
> + if (r)
> + DSSERR("failed to unregister FRAMEDONE isr\n");
> +}
>
> - r = omap_dispc_unregister_isr(dispc_disable_isr,
> - &frame_done_completion, irq);
> +static void dispc_digit_out_enable_isr(void *data, u32 mask)
> +{
> + struct completion *compl = data;
>
> - if (r)
> - DSSERR("failed to unregister FRAMEDONE isr\n");
> + /* ignore any sync lost interrupts */
> + if (mask & (DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD))
> + complete(compl);
> +}
> +
> +static void dispc_mgr_enable_digit_out(void)
> +{
> + DECLARE_COMPLETION_ONSTACK(vsync_compl);
> + int r;
> + u32 irq_mask;
> +
> + if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) = true)
> + return;
> +
> + /*
> + * Digit output produces some sync lost interrupts during the first
> + * frame when enabling. Those need to be ignored, so we register for the
> + * sync lost irq to prevent the error handler from triggering.
> + */
> +
> + irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT) |
> + dispc_mgr_get_sync_lost_irq(OMAP_DSS_CHANNEL_DIGIT);
> +
> + r = omap_dispc_register_isr(dispc_digit_out_enable_isr, &vsync_compl,
> + irq_mask);
> + if (r) {
> + DSSERR("failed to register %x isr\n", irq_mask);
> + return;
> }
> +
> + _enable_mgr_out(OMAP_DSS_CHANNEL_DIGIT, true);
> +
> + /* wait for the first evsync */
> + if (!wait_for_completion_timeout(&vsync_compl, msecs_to_jiffies(100)))
> + DSSERR("timeout waiting for digit out to start\n");
> +
> + r = omap_dispc_unregister_isr(dispc_digit_out_enable_isr, &vsync_compl,
> + irq_mask);
> + if (r)
> + DSSERR("failed to unregister %x isr\n", irq_mask);
> }
>
> -static void dispc_mgr_enable_digit_out(bool enable)
> +static void dispc_mgr_disable_digit_out(void)
> {
> - struct completion frame_done_completion;
> + DECLARE_COMPLETION_ONSTACK(framedone_compl);
> enum dss_hdmi_venc_clk_source_select src;
> int r, i;
> u32 irq_mask;
> int num_irqs;
>
> - if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) = enable)
> + if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) = false)
> return;
>
> src = dss_get_hdmi_venc_clk_source();
>
> - if (enable) {
> - unsigned long flags;
> - /* When we enable digit output, we'll get an extra digit
> - * sync lost interrupt, that we need to ignore */
> - spin_lock_irqsave(&dispc.irq_lock, flags);
> - dispc.irq_error_mask &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
> - _omap_dispc_set_irqs();
> - spin_unlock_irqrestore(&dispc.irq_lock, flags);
> - }
> -
> - /* When we disable digit output, we need to wait until fields are done.
> - * Otherwise the DSS is still working, and turning off the clocks
> - * prevents DSS from going to OFF mode. And when enabling, we need to
> - * wait for the extra sync losts */
> - init_completion(&frame_done_completion);
> + /*
> + * When we disable the digit output, we need to wait for FRAMEDONE to
> + * know that DISPC has finished with the output. For analog tv out we'll
> + * use vsync, as omap2/3 don't have framedone for TV.
> + */
>
> - if (src = DSS_HDMI_M_PCLK && enable = false) {
> + if (src = DSS_HDMI_M_PCLK) {
> irq_mask = DISPC_IRQ_FRAMEDONETV;
> num_irqs = 1;
> } else {
> - irq_mask = DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD;
> - /* XXX I understand from TRM that we should only wait for the
> - * current field to complete. But it seems we have to wait for
> - * both fields */
> + irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT);
> + /*
> + * We need to wait for both even and odd vsyncs. Note that this
> + * is not totally reliable, as we could get a vsync interrupt
> + * before we disable the output, which leads to timeout in the
> + * wait_for_completion.
> + */
> num_irqs = 2;
> }
>
> - r = omap_dispc_register_isr(dispc_disable_isr, &frame_done_completion,
> + r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
> irq_mask);
> if (r)
> DSSERR("failed to register %x isr\n", irq_mask);
We should probably sleep here too as we did for LCD above.
Archit
^ permalink raw reply
* [PATCH 9/9] OMAPDSS: DISPC: cleanup lcd/digit enable/disable
From: Tomi Valkeinen @ 2012-10-17 11:20 UTC (permalink / raw)
To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1350472835-28727-1-git-send-email-tomi.valkeinen@ti.com>
We currently have a single function to enable and disable the manager
output for LCD and DIGIT. The functions are a bit complex, as handling
both enable and disable require some extra steps to ensure that the
output is enabled or disabled properly without errors before exiting the
function.
The code can be made simpler to understand by splitting the functions
into separate enable and disable functions. We'll also clean up the
comments and some parameter names at the same time.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 6 +-
drivers/video/omap2/dss/dispc.c | 178 ++++++++++++++++++++++++---------------
drivers/video/omap2/dss/dss.h | 3 +-
3 files changed, 116 insertions(+), 71 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index ae9f70d..4fff8ac 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -772,7 +772,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
if (!dss_data.irq_enabled && need_isr())
dss_register_vsync_isr();
- dispc_mgr_enable(mgr->id, true);
+ dispc_mgr_enable(mgr->id);
mgr_clear_shadow_dirty(mgr);
@@ -1027,7 +1027,7 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
spin_unlock_irqrestore(&data_lock, flags);
if (!mgr_manual_update(mgr))
- dispc_mgr_enable(mgr->id, true);
+ dispc_mgr_enable(mgr->id);
out:
mutex_unlock(&apply_lock);
@@ -1052,7 +1052,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
goto out;
if (!mgr_manual_update(mgr))
- dispc_mgr_enable(mgr->id, false);
+ dispc_mgr_disable(mgr->id);
spin_lock_irqsave(&data_lock, flags);
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 82339ad..94f393ec 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2590,7 +2590,7 @@ int dispc_ovl_enable(enum omap_plane plane, bool enable)
return 0;
}
-static void dispc_disable_isr(void *data, u32 mask)
+static void dispc_mgr_disable_isr(void *data, u32 mask)
{
struct completion *compl = data;
complete(compl);
@@ -2608,122 +2608,166 @@ bool dispc_mgr_is_enabled(enum omap_channel channel)
return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
}
-static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
+static void dispc_mgr_enable_lcd_out(enum omap_channel channel)
{
- struct completion frame_done_completion;
- bool is_on;
+ _enable_mgr_out(channel, true);
+}
+
+static void dispc_mgr_disable_lcd_out(enum omap_channel channel)
+{
+ DECLARE_COMPLETION_ONSTACK(framedone_compl);
int r;
u32 irq;
- /* When we disable LCD output, we need to wait until frame is done.
- * Otherwise the DSS is still working, and turning off the clocks
- * prevents DSS from going to OFF mode */
- is_on = dispc_mgr_is_enabled(channel);
+ if (dispc_mgr_is_enabled(channel) = false)
+ return;
+
+ /*
+ * When we disable LCD output, we need to wait for FRAMEDONE to know
+ * that DISPC has finished with the LCD output.
+ */
- irq = mgr_desc[channel].framedone_irq;
+ irq = dispc_mgr_get_framedone_irq(channel);
- if (!enable && is_on) {
- init_completion(&frame_done_completion);
+ r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
+ irq);
+ if (r)
+ DSSERR("failed to register FRAMEDONE isr\n");
- r = omap_dispc_register_isr(dispc_disable_isr,
- &frame_done_completion, irq);
+ _enable_mgr_out(channel, false);
- if (r)
- DSSERR("failed to register FRAMEDONE isr\n");
+ /* if we couldn't register for framedone, just sleep and exit */
+ if (r) {
+ msleep(200);
+ return;
}
- _enable_mgr_out(channel, enable);
+ if (!wait_for_completion_timeout(&framedone_compl,
+ msecs_to_jiffies(100)))
+ DSSERR("timeout waiting for FRAME DONE\n");
- if (!enable && is_on) {
- if (!wait_for_completion_timeout(&frame_done_completion,
- msecs_to_jiffies(100)))
- DSSERR("timeout waiting for FRAME DONE\n");
+ r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
+ irq);
+ if (r)
+ DSSERR("failed to unregister FRAMEDONE isr\n");
+}
- r = omap_dispc_unregister_isr(dispc_disable_isr,
- &frame_done_completion, irq);
+static void dispc_digit_out_enable_isr(void *data, u32 mask)
+{
+ struct completion *compl = data;
- if (r)
- DSSERR("failed to unregister FRAMEDONE isr\n");
+ /* ignore any sync lost interrupts */
+ if (mask & (DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD))
+ complete(compl);
+}
+
+static void dispc_mgr_enable_digit_out(void)
+{
+ DECLARE_COMPLETION_ONSTACK(vsync_compl);
+ int r;
+ u32 irq_mask;
+
+ if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) = true)
+ return;
+
+ /*
+ * Digit output produces some sync lost interrupts during the first
+ * frame when enabling. Those need to be ignored, so we register for the
+ * sync lost irq to prevent the error handler from triggering.
+ */
+
+ irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT) |
+ dispc_mgr_get_sync_lost_irq(OMAP_DSS_CHANNEL_DIGIT);
+
+ r = omap_dispc_register_isr(dispc_digit_out_enable_isr, &vsync_compl,
+ irq_mask);
+ if (r) {
+ DSSERR("failed to register %x isr\n", irq_mask);
+ return;
}
+
+ _enable_mgr_out(OMAP_DSS_CHANNEL_DIGIT, true);
+
+ /* wait for the first evsync */
+ if (!wait_for_completion_timeout(&vsync_compl, msecs_to_jiffies(100)))
+ DSSERR("timeout waiting for digit out to start\n");
+
+ r = omap_dispc_unregister_isr(dispc_digit_out_enable_isr, &vsync_compl,
+ irq_mask);
+ if (r)
+ DSSERR("failed to unregister %x isr\n", irq_mask);
}
-static void dispc_mgr_enable_digit_out(bool enable)
+static void dispc_mgr_disable_digit_out(void)
{
- struct completion frame_done_completion;
+ DECLARE_COMPLETION_ONSTACK(framedone_compl);
enum dss_hdmi_venc_clk_source_select src;
int r, i;
u32 irq_mask;
int num_irqs;
- if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) = enable)
+ if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) = false)
return;
src = dss_get_hdmi_venc_clk_source();
- if (enable) {
- unsigned long flags;
- /* When we enable digit output, we'll get an extra digit
- * sync lost interrupt, that we need to ignore */
- spin_lock_irqsave(&dispc.irq_lock, flags);
- dispc.irq_error_mask &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
- _omap_dispc_set_irqs();
- spin_unlock_irqrestore(&dispc.irq_lock, flags);
- }
-
- /* When we disable digit output, we need to wait until fields are done.
- * Otherwise the DSS is still working, and turning off the clocks
- * prevents DSS from going to OFF mode. And when enabling, we need to
- * wait for the extra sync losts */
- init_completion(&frame_done_completion);
+ /*
+ * When we disable the digit output, we need to wait for FRAMEDONE to
+ * know that DISPC has finished with the output. For analog tv out we'll
+ * use vsync, as omap2/3 don't have framedone for TV.
+ */
- if (src = DSS_HDMI_M_PCLK && enable = false) {
+ if (src = DSS_HDMI_M_PCLK) {
irq_mask = DISPC_IRQ_FRAMEDONETV;
num_irqs = 1;
} else {
- irq_mask = DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD;
- /* XXX I understand from TRM that we should only wait for the
- * current field to complete. But it seems we have to wait for
- * both fields */
+ irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT);
+ /*
+ * We need to wait for both even and odd vsyncs. Note that this
+ * is not totally reliable, as we could get a vsync interrupt
+ * before we disable the output, which leads to timeout in the
+ * wait_for_completion.
+ */
num_irqs = 2;
}
- r = omap_dispc_register_isr(dispc_disable_isr, &frame_done_completion,
+ r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
irq_mask);
if (r)
DSSERR("failed to register %x isr\n", irq_mask);
- _enable_mgr_out(OMAP_DSS_CHANNEL_DIGIT, enable);
+ _enable_mgr_out(OMAP_DSS_CHANNEL_DIGIT, false);
for (i = 0; i < num_irqs; ++i) {
- if (!wait_for_completion_timeout(&frame_done_completion,
+ if (!wait_for_completion_timeout(&framedone_compl,
msecs_to_jiffies(100)))
- DSSERR("timeout waiting for digit out to %s\n",
- enable ? "start" : "stop");
+ DSSERR("timeout waiting for digit out to stop\n");
}
- r = omap_dispc_unregister_isr(dispc_disable_isr, &frame_done_completion,
+ r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
irq_mask);
if (r)
DSSERR("failed to unregister %x isr\n", irq_mask);
+}
- if (enable) {
- unsigned long flags;
- spin_lock_irqsave(&dispc.irq_lock, flags);
- dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST_DIGIT;
- dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
- _omap_dispc_set_irqs();
- spin_unlock_irqrestore(&dispc.irq_lock, flags);
- }
+void dispc_mgr_enable(enum omap_channel channel)
+{
+ if (dss_mgr_is_lcd(channel))
+ dispc_mgr_enable_lcd_out(channel);
+ else if (channel = OMAP_DSS_CHANNEL_DIGIT)
+ dispc_mgr_enable_digit_out();
+ else
+ WARN_ON(1);
}
-void dispc_mgr_enable(enum omap_channel channel, bool enable)
+void dispc_mgr_disable(enum omap_channel channel)
{
if (dss_mgr_is_lcd(channel))
- dispc_mgr_enable_lcd_out(channel, enable);
+ dispc_mgr_disable_lcd_out(channel);
else if (channel = OMAP_DSS_CHANNEL_DIGIT)
- dispc_mgr_enable_digit_out(enable);
+ dispc_mgr_disable_digit_out();
else
- BUG();
+ WARN_ON(1);
}
void dispc_wb_enable(bool enable)
@@ -2740,7 +2784,7 @@ void dispc_wb_enable(bool enable)
if (!enable && is_on) {
init_completion(&frame_done_completion);
- r = omap_dispc_register_isr(dispc_disable_isr,
+ r = omap_dispc_register_isr(dispc_mgr_disable_isr,
&frame_done_completion, irq);
if (r)
DSSERR("failed to register FRAMEDONEWB isr\n");
@@ -2753,7 +2797,7 @@ void dispc_wb_enable(bool enable)
msecs_to_jiffies(100)))
DSSERR("timeout waiting for FRAMEDONEWB\n");
- r = omap_dispc_unregister_isr(dispc_disable_isr,
+ r = omap_dispc_unregister_isr(dispc_mgr_disable_isr,
&frame_done_completion, irq);
if (r)
DSSERR("failed to unregister FRAMEDONEWB isr\n");
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index b6e3a06..e501a77 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -464,7 +464,8 @@ u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel);
bool dispc_mgr_go_busy(enum omap_channel channel);
void dispc_mgr_go(enum omap_channel channel);
bool dispc_mgr_is_enabled(enum omap_channel channel);
-void dispc_mgr_enable(enum omap_channel channel, bool enable);
+void dispc_mgr_enable(enum omap_channel channel);
+void dispc_mgr_disable(enum omap_channel channel);
bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
void dispc_mgr_set_lcd_config(enum omap_channel channel,
const struct dss_lcd_mgr_config *config);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 8/9] OMAPDSS: DISPC: add dispc_mgr_get_sync_lost_irq()
From: Tomi Valkeinen @ 2012-10-17 11:20 UTC (permalink / raw)
To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1350472835-28727-1-git-send-email-tomi.valkeinen@ti.com>
Add function that returns the sync lost irq mask for the given channel.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 5 +++++
drivers/video/omap2/dss/dss.h | 1 +
2 files changed, 6 insertions(+)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 492740e..82339ad 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -543,6 +543,11 @@ u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
return mgr_desc[channel].framedone_irq;
}
+u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel)
+{
+ return mgr_desc[channel].sync_lost_irq;
+}
+
u32 dispc_wb_get_framedone_irq(void)
{
return DISPC_IRQ_FRAMEDONEWB;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 373847c..b6e3a06 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -460,6 +460,7 @@ void dispc_ovl_set_channel_out(enum omap_plane plane,
u32 dispc_mgr_get_vsync_irq(enum omap_channel channel);
u32 dispc_mgr_get_framedone_irq(enum omap_channel channel);
+u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel);
bool dispc_mgr_go_busy(enum omap_channel channel);
void dispc_mgr_go(enum omap_channel channel);
bool dispc_mgr_is_enabled(enum omap_channel channel);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 7/9] OMAPDSS: DISPC: cleanup lcd and digit enable
From: Tomi Valkeinen @ 2012-10-17 11:20 UTC (permalink / raw)
To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1350472835-28727-1-git-send-email-tomi.valkeinen@ti.com>
dispc.c's functions to enable LCD and DIGIT outputs can be cleaned up a
bit by using common functions to set the enable bit and to check if the
output is enabled.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 27 ++++++++++-----------------
1 file changed, 10 insertions(+), 17 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 9f0ce18..492740e 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2591,13 +2591,18 @@ static void dispc_disable_isr(void *data, u32 mask)
complete(compl);
}
-static void _enable_lcd_out(enum omap_channel channel, bool enable)
+static void _enable_mgr_out(enum omap_channel channel, bool enable)
{
mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable);
/* flush posted write */
mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
}
+bool dispc_mgr_is_enabled(enum omap_channel channel)
+{
+ return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
+}
+
static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
{
struct completion frame_done_completion;
@@ -2608,7 +2613,7 @@ static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
/* When we disable LCD output, we need to wait until frame is done.
* Otherwise the DSS is still working, and turning off the clocks
* prevents DSS from going to OFF mode */
- is_on = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
+ is_on = dispc_mgr_is_enabled(channel);
irq = mgr_desc[channel].framedone_irq;
@@ -2622,7 +2627,7 @@ static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
DSSERR("failed to register FRAMEDONE isr\n");
}
- _enable_lcd_out(channel, enable);
+ _enable_mgr_out(channel, enable);
if (!enable && is_on) {
if (!wait_for_completion_timeout(&frame_done_completion,
@@ -2637,13 +2642,6 @@ static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
}
}
-static void _enable_digit_out(bool enable)
-{
- REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
- /* flush posted write */
- dispc_read_reg(DISPC_CONTROL);
-}
-
static void dispc_mgr_enable_digit_out(bool enable)
{
struct completion frame_done_completion;
@@ -2652,7 +2650,7 @@ static void dispc_mgr_enable_digit_out(bool enable)
u32 irq_mask;
int num_irqs;
- if (REG_GET(DISPC_CONTROL, 1, 1) = enable)
+ if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) = enable)
return;
src = dss_get_hdmi_venc_clk_source();
@@ -2689,7 +2687,7 @@ static void dispc_mgr_enable_digit_out(bool enable)
if (r)
DSSERR("failed to register %x isr\n", irq_mask);
- _enable_digit_out(enable);
+ _enable_mgr_out(OMAP_DSS_CHANNEL_DIGIT, enable);
for (i = 0; i < num_irqs; ++i) {
if (!wait_for_completion_timeout(&frame_done_completion,
@@ -2713,11 +2711,6 @@ static void dispc_mgr_enable_digit_out(bool enable)
}
}
-bool dispc_mgr_is_enabled(enum omap_channel channel)
-{
- return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
-}
-
void dispc_mgr_enable(enum omap_channel channel, bool enable)
{
if (dss_mgr_is_lcd(channel))
--
1.7.9.5
^ permalink raw reply related
* [PATCH 6/9] OMAPDSS: DISPC: remove struct omap_overlay use
From: Tomi Valkeinen @ 2012-10-17 11:20 UTC (permalink / raw)
To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1350472835-28727-1-git-send-email-tomi.valkeinen@ti.com>
dispc_ovl_setup() uses struct omap_overlay to get the caps for the
overlay. We can change the code to get the caps directly from dss
features, thus removing the dependency to struct omap_overlay.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index d3c58eb..9f0ce18 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2505,7 +2505,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
bool mem_to_mem)
{
int r;
- const struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+ enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane);
enum omap_channel channel;
channel = dispc_ovl_get_channel_out(plane);
@@ -2516,7 +2516,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height,
oi->color_mode, oi->rotation, oi->mirror, channel, replication);
- r = dispc_ovl_setup_common(plane, ovl->caps, oi->paddr, oi->p_uv_addr,
+ r = dispc_ovl_setup_common(plane, caps, oi->paddr, oi->p_uv_addr,
oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha,
--
1.7.9.5
^ permalink raw reply related
* [PATCH 5/9] OMAPDSS: remove declarations for non-existing funcs
From: Tomi Valkeinen @ 2012-10-17 11:20 UTC (permalink / raw)
To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1350472835-28727-1-git-send-email-tomi.valkeinen@ti.com>
dss_mgr_set_device and dss_mgr_unset_device are declared in dss.h, but
the functions do not exist. Remove the declarations.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dss.h | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 8447871..373847c 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -217,9 +217,6 @@ int dss_mgr_set_info(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info);
void dss_mgr_get_info(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info);
-int dss_mgr_set_device(struct omap_overlay_manager *mgr,
- struct omap_dss_device *dssdev);
-int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
int dss_mgr_set_output(struct omap_overlay_manager *mgr,
struct omap_dss_output *output);
int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 4/9] OMAPDSS: combine LCD related config into one func
From: Tomi Valkeinen @ 2012-10-17 11:20 UTC (permalink / raw)
To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1350472835-28727-1-git-send-email-tomi.valkeinen@ti.com>
Dispc has a bunch of functions used to configure output related
parameters:
- dispc_mgr_set_io_pad_mode
- dispc_mgr_enable_stallmode
- dispc_mgr_enable_fifohandcheck
- dispc_mgr_set_clock_div
- dispc_mgr_set_tft_data_lines
- dispc_lcd_enable_signal_polarity
- dispc_mgr_set_lcd_type_tft
These are all called together, and the configuration values are taken
from struct dss_lcd_mgr_config.
Instead of exposing those individual dispc functions, create a new one,
dispc_mgr_set_lcd_config(), which is used to configure the above
parameters from values in struct dss_lcd_mgr_config.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 18 ++----------------
drivers/video/omap2/dss/dispc.c | 29 +++++++++++++++++++++++------
drivers/video/omap2/dss/dss.h | 8 ++------
3 files changed, 27 insertions(+), 28 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 29ce5a8..ae9f70d 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -666,22 +666,8 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
dispc_mgr_set_timings(mgr->id, &mp->timings);
/* lcd_config parameters */
- if (dss_mgr_is_lcd(mgr->id)) {
- dispc_mgr_set_io_pad_mode(mp->lcd_config.io_pad_mode);
-
- dispc_mgr_enable_stallmode(mgr->id, mp->lcd_config.stallmode);
- dispc_mgr_enable_fifohandcheck(mgr->id,
- mp->lcd_config.fifohandcheck);
-
- dispc_mgr_set_clock_div(mgr->id, &mp->lcd_config.clock_info);
-
- dispc_mgr_set_tft_data_lines(mgr->id,
- mp->lcd_config.video_port_width);
-
- dispc_lcd_enable_signal_polarity(mp->lcd_config.lcden_sig_polarity);
-
- dispc_mgr_set_lcd_type_tft(mgr->id);
- }
+ if (dss_mgr_is_lcd(mgr->id))
+ dispc_mgr_set_lcd_config(mgr->id, &mp->lcd_config);
mp->extra_info_dirty = false;
if (mp->updating)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 4dfc90a..d3c58eb 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2769,7 +2769,7 @@ bool dispc_wb_is_enabled(void)
return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
}
-void dispc_lcd_enable_signal_polarity(bool act_high)
+static void dispc_lcd_enable_signal_polarity(bool act_high)
{
if (!dss_has_feature(FEAT_LCDENABLEPOL))
return;
@@ -2793,13 +2793,13 @@ void dispc_pck_free_enable(bool enable)
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
}
-void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
+static void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
{
mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable);
}
-void dispc_mgr_set_lcd_type_tft(enum omap_channel channel)
+static void dispc_mgr_set_lcd_type_tft(enum omap_channel channel)
{
mgr_fld_write(channel, DISPC_MGR_FLD_STNTFT, 1);
}
@@ -2855,7 +2855,7 @@ void dispc_mgr_setup(enum omap_channel channel,
}
}
-void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
+static void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
{
int code;
@@ -2880,7 +2880,7 @@ void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
mgr_fld_write(channel, DISPC_MGR_FLD_TFTDATALINES, code);
}
-void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
+static void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
{
u32 l;
int gpout0, gpout1;
@@ -2909,11 +2909,28 @@ void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
dispc_write_reg(DISPC_CONTROL, l);
}
-void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
+static void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
{
mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable);
}
+void dispc_mgr_set_lcd_config(enum omap_channel channel,
+ const struct dss_lcd_mgr_config *config)
+{
+ dispc_mgr_set_io_pad_mode(config->io_pad_mode);
+
+ dispc_mgr_enable_stallmode(channel, config->stallmode);
+ dispc_mgr_enable_fifohandcheck(channel, config->fifohandcheck);
+
+ dispc_mgr_set_clock_div(channel, &config->clock_info);
+
+ dispc_mgr_set_tft_data_lines(channel, config->video_port_width);
+
+ dispc_lcd_enable_signal_polarity(config->lcden_sig_polarity);
+
+ dispc_mgr_set_lcd_type_tft(channel);
+}
+
static bool _dispc_mgr_size_ok(u16 width, u16 height)
{
return width <= dss_feat_get_param_max(FEAT_PARAM_MGR_WIDTH) &&
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index eaf0856..8447871 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -435,7 +435,6 @@ void dispc_runtime_put(void);
void dispc_enable_sidle(void);
void dispc_disable_sidle(void);
-void dispc_lcd_enable_signal_polarity(bool act_high);
void dispc_lcd_enable_signal(bool enable);
void dispc_pck_free_enable(bool enable);
void dispc_enable_fifomerge(bool enable);
@@ -462,7 +461,6 @@ int dispc_ovl_enable(enum omap_plane plane, bool enable);
void dispc_ovl_set_channel_out(enum omap_plane plane,
enum omap_channel channel);
-void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable);
u32 dispc_mgr_get_vsync_irq(enum omap_channel channel);
u32 dispc_mgr_get_framedone_irq(enum omap_channel channel);
bool dispc_mgr_go_busy(enum omap_channel channel);
@@ -470,10 +468,8 @@ void dispc_mgr_go(enum omap_channel channel);
bool dispc_mgr_is_enabled(enum omap_channel channel);
void dispc_mgr_enable(enum omap_channel channel, bool enable);
bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
-void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode);
-void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
-void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
-void dispc_mgr_set_lcd_type_tft(enum omap_channel channel);
+void dispc_mgr_set_lcd_config(enum omap_channel channel,
+ const struct dss_lcd_mgr_config *config);
void dispc_mgr_set_timings(enum omap_channel channel,
const struct omap_video_timings *timings);
unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 3/9] OMAPDSS: DISPC: constify function parameters
From: Tomi Valkeinen @ 2012-10-17 11:20 UTC (permalink / raw)
To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1350472835-28727-1-git-send-email-tomi.valkeinen@ti.com>
Add consts to dispc function parameters which do not modify the passed
structs.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 10 +++++-----
drivers/video/omap2/dss/dss.h | 6 +++---
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index b43477a..4dfc90a 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1076,7 +1076,7 @@ static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
}
static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
- struct omap_dss_cpr_coefs *coefs)
+ const struct omap_dss_cpr_coefs *coefs)
{
u32 coef_r, coef_g, coef_b;
@@ -2505,7 +2505,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
bool mem_to_mem)
{
int r;
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+ const struct omap_overlay *ovl = omap_dss_get_overlay(plane);
enum omap_channel channel;
channel = dispc_ovl_get_channel_out(plane);
@@ -2842,7 +2842,7 @@ static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
}
void dispc_mgr_setup(enum omap_channel channel,
- struct omap_overlay_manager_info *info)
+ const struct omap_overlay_manager_info *info)
{
dispc_mgr_set_default_color(channel, info->default_color);
dispc_mgr_set_trans_key(channel, info->trans_key_type, info->trans_key);
@@ -3012,7 +3012,7 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
/* change name to mode? */
void dispc_mgr_set_timings(enum omap_channel channel,
- struct omap_video_timings *timings)
+ const struct omap_video_timings *timings)
{
unsigned xtot, ytot;
unsigned long ht, vt;
@@ -3533,7 +3533,7 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
}
void dispc_mgr_set_clock_div(enum omap_channel channel,
- struct dispc_clock_info *cinfo)
+ const struct dispc_clock_info *cinfo)
{
DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div);
DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 6728892..eaf0856 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -475,16 +475,16 @@ void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
void dispc_mgr_set_lcd_type_tft(enum omap_channel channel);
void dispc_mgr_set_timings(enum omap_channel channel,
- struct omap_video_timings *timings);
+ const struct omap_video_timings *timings);
unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
unsigned long dispc_core_clk_rate(void);
void dispc_mgr_set_clock_div(enum omap_channel channel,
- struct dispc_clock_info *cinfo);
+ const struct dispc_clock_info *cinfo);
int dispc_mgr_get_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
void dispc_mgr_setup(enum omap_channel channel,
- struct omap_overlay_manager_info *info);
+ const struct omap_overlay_manager_info *info);
u32 dispc_wb_get_framedone_irq(void);
bool dispc_wb_go_busy(void);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 2/9] OMAPDSS: fix registering the vsync isr in apply
From: Tomi Valkeinen @ 2012-10-17 11:20 UTC (permalink / raw)
To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1350472835-28727-1-git-send-email-tomi.valkeinen@ti.com>
When we enable an output we don't check if we need to register the vsync
isr. This causes us to miss vsync interrupts until somebody changes the
configuration of an overlay or an overlay manager.
Add the registration to dss_mgr_enable to fix the problem.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/apply.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 19d66f4..29ce5a8 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1035,6 +1035,9 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
if (!mgr_manual_update(mgr))
mp->updating = true;
+ if (!dss_data.irq_enabled && need_isr())
+ dss_register_vsync_isr();
+
spin_unlock_irqrestore(&data_lock, flags);
if (!mgr_manual_update(mgr))
--
1.7.9.5
^ permalink raw reply related
* [PATCH 1/9] OMAPDSS: DSI: fix dsi_get_dsidev_from_id()
From: Tomi Valkeinen @ 2012-10-17 11:20 UTC (permalink / raw)
To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1350472835-28727-1-git-send-email-tomi.valkeinen@ti.com>
If dsi_get_dsidev_from_id() is called with a DSI module id that does not
exist on the board, the function will crash as omap_dss_get_output()
will return NULL.
This happens on omap3 boards when dumping DSI clocks, as the dumping
code will try to get the dsidev for DSI modules 0 and 1, but omap3 only
has DSI module 0.
Also clean up the id -> output mapping, so that if the function is
called with invalid module ID it will return NULL.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dsi.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index d64ac38..bee9284 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -365,11 +365,20 @@ struct platform_device *dsi_get_dsidev_from_id(int module)
struct omap_dss_output *out;
enum omap_dss_output_id id;
- id = module = 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+ switch (module) {
+ case 0:
+ id = OMAP_DSS_OUTPUT_DSI1;
+ break;
+ case 1:
+ id = OMAP_DSS_OUTPUT_DSI2;
+ break;
+ default:
+ return NULL;
+ }
out = omap_dss_get_output(id);
- return out->pdev;
+ return out ? out->pdev : NULL;
}
static inline void dsi_write_reg(struct platform_device *dsidev,
--
1.7.9.5
^ permalink raw reply related
* [PATCH 0/9] OMAPDSS: minor fixes & cleanups
From: Tomi Valkeinen @ 2012-10-17 11:20 UTC (permalink / raw)
To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
Hi,
This series contains minor cleanups and fixes for omapdss.
Tomi
Tomi Valkeinen (9):
OMAPDSS: DSI: fix dsi_get_dsidev_from_id()
OMAPDSS: fix registering the vsync isr in apply
OMAPDSS: DISPC: constify function parameters
OMAPDSS: combine LCD related config into one func
OMAPDSS: remove declarations for non-existing funcs
OMAPDSS: DISPC: remove struct omap_overlay use
OMAPDSS: DISPC: cleanup lcd and digit enable
OMAPDSS: DISPC: add dispc_mgr_get_sync_lost_irq()
OMAPDSS: DISPC: cleanup lcd/digit enable/disable
drivers/video/omap2/dss/apply.c | 27 ++---
drivers/video/omap2/dss/dispc.c | 235 ++++++++++++++++++++++++---------------
drivers/video/omap2/dss/dsi.c | 13 ++-
drivers/video/omap2/dss/dss.h | 21 ++--
4 files changed, 174 insertions(+), 122 deletions(-)
--
1.7.9.5
^ permalink raw reply
* Re: [PATCHv3 0/5] OMAP: VRFB: convert to platform device
From: Tomi Valkeinen @ 2012-10-17 10:25 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, tony, archit
In-Reply-To: <1350469102-24888-1-git-send-email-tomi.valkeinen@ti.com>
[-- Attachment #1: Type: text/plain, Size: 2393 bytes --]
Hi Tony,
I have pushed this vrfb series and the omapdss version series to:
git://gitorious.org/linux-omap-dss2/linux.git 3.8/dss-version
git://gitorious.org/linux-omap-dss2/linux.git 3.8/vrfb-conversion
If they look ok to you and we don't get any other comments, I think
these branches can be considered stable and you can pull them.
After these are merged:
$ git grep -E "(plat/)|(mach/)" drivers/video/omap2/
drivers/video/omap2/omapfb/omapfb-ioctl.c:#include <plat/vram.h>
drivers/video/omap2/omapfb/omapfb-main.c:#include <plat/vram.h>
drivers/video/omap2/vram.c:#include <plat/vram.h>
So the vram stuff should be the only omap dependency left in omapdss and
omapfb. I'll start working on that soon.
Tomi
On 2012-10-17 13:18, Tomi Valkeinen wrote:
> This is the third version of the series. Changes to v2 are:
> * rebased on 3.7-rc1 to resolve conflicts
> * add omap_vrfb_supported() so that cpu_is_* check can be removed from omapfb
>
> As Kevin Hilman pointed out, the context restore is not functional. I didn't
> touch that, as it's not functional with the current kernel either (and nobody
> has complained, so it can't be that critical).
>
> Tomi
>
> Tomi Valkeinen (5):
> OMAP: VRFB: convert vrfb to platform device
> OMAP: move arch/arm/plat-omap/include/plat/vrfb.h
> OMAP: SDRC: remove VRFB code
> OMAPDSS: VRFB: add omap_vrfb_supported()
> OMAPFB: use omap_vrfb_supported()
>
> arch/arm/mach-omap2/sdrc.c | 16 ---
> arch/arm/plat-omap/fb.c | 61 +++++++++++
> arch/arm/plat-omap/include/plat/sdrc.h | 7 --
> arch/arm/plat-omap/include/plat/vrfb.h | 66 ------------
> drivers/media/platform/omap/omap_vout.c | 2 +-
> drivers/media/platform/omap/omap_vout_vrfb.c | 2 +-
> drivers/media/platform/omap/omap_voutdef.h | 2 +-
> drivers/video/omap2/omapfb/omapfb-ioctl.c | 2 +-
> drivers/video/omap2/omapfb/omapfb-main.c | 8 +-
> drivers/video/omap2/omapfb/omapfb-sysfs.c | 2 +-
> drivers/video/omap2/vrfb.c | 142 ++++++++++++++++++++++----
> include/video/omapvrfb.h | 68 ++++++++++++
> 12 files changed, 257 insertions(+), 121 deletions(-)
> delete mode 100644 arch/arm/plat-omap/include/plat/vrfb.h
> create mode 100644 include/video/omapvrfb.h
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 897 bytes --]
^ permalink raw reply
* [PATCHv3 5/5] OMAPFB: use omap_vrfb_supported()
From: Tomi Valkeinen @ 2012-10-17 10:18 UTC (permalink / raw)
To: linux-omap, linux-fbdev, tony; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1350469102-24888-1-git-send-email-tomi.valkeinen@ti.com>
Replace cpu_is_*() check with omap_vrfb_supported().
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/omapfb/omapfb-main.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 5943b3a..bc225e4 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -31,7 +31,6 @@
#include <linux/omapfb.h>
#include <video/omapdss.h>
-#include <plat/cpu.h>
#include <plat/vram.h>
#include <video/omapvrfb.h>
@@ -2396,10 +2395,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
goto err0;
}
- /* TODO : Replace cpu check with omap_has_vrfb once HAS_FEATURE
- * available for OMAP2 and OMAP3
- */
- if (def_vrfb && !cpu_is_omap24xx() && !cpu_is_omap34xx()) {
+ if (def_vrfb && !omap_vrfb_supported()) {
def_vrfb = 0;
dev_warn(&pdev->dev, "VRFB is not supported on this hardware, "
"ignoring the module parameter vrfb=y\n");
--
1.7.9.5
^ permalink raw reply related
* [PATCHv3 4/5] OMAPDSS: VRFB: add omap_vrfb_supported()
From: Tomi Valkeinen @ 2012-10-17 10:18 UTC (permalink / raw)
To: linux-omap, linux-fbdev, tony; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1350469102-24888-1-git-send-email-tomi.valkeinen@ti.com>
Add an exported function omap_vrfb_supported() which returns true if the
vrfb driver has been loaded succesfully. This can be used to decide if
VRFB can be used or not.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/vrfb.c | 16 ++++++++++++++++
include/video/omapvrfb.h | 2 ++
2 files changed, 18 insertions(+)
diff --git a/drivers/video/omap2/vrfb.c b/drivers/video/omap2/vrfb.c
index e4a0450..5d8fdac 100644
--- a/drivers/video/omap2/vrfb.c
+++ b/drivers/video/omap2/vrfb.c
@@ -77,6 +77,8 @@ static void __iomem *vrfb_base;
static int num_ctxs;
static struct vrfb_ctx *ctxs;
+static bool vrfb_loaded;
+
static void omap2_sms_write_rot_control(u32 val, unsigned ctx)
{
__raw_writel(val, vrfb_base + SMS_ROT_CONTROL(ctx));
@@ -336,6 +338,12 @@ out:
}
EXPORT_SYMBOL(omap_vrfb_request_ctx);
+bool omap_vrfb_supported(void)
+{
+ return vrfb_loaded;
+}
+EXPORT_SYMBOL(omap_vrfb_supported);
+
static int __init vrfb_probe(struct platform_device *pdev)
{
struct resource *mem;
@@ -375,11 +383,19 @@ static int __init vrfb_probe(struct platform_device *pdev)
ctxs[i].base = mem->start;
}
+ vrfb_loaded = true;
+
return 0;
}
+static void __exit vrfb_remove(struct platform_device *pdev)
+{
+ vrfb_loaded = false;
+}
+
static struct platform_driver vrfb_driver = {
.driver.name = "omapvrfb",
+ .remove = __exit_p(vrfb_remove),
};
static int __init vrfb_init(void)
diff --git a/include/video/omapvrfb.h b/include/video/omapvrfb.h
index 3792bde..bb0bd89 100644
--- a/include/video/omapvrfb.h
+++ b/include/video/omapvrfb.h
@@ -36,6 +36,7 @@ struct vrfb {
};
#ifdef CONFIG_OMAP2_VRFB
+extern bool omap_vrfb_supported(void);
extern int omap_vrfb_request_ctx(struct vrfb *vrfb);
extern void omap_vrfb_release_ctx(struct vrfb *vrfb);
extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
@@ -49,6 +50,7 @@ extern int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot);
extern void omap_vrfb_restore_context(void);
#else
+static inline bool omap_vrfb_supported(void) { return false; }
static inline int omap_vrfb_request_ctx(struct vrfb *vrfb) { return 0; }
static inline void omap_vrfb_release_ctx(struct vrfb *vrfb) {}
static inline void omap_vrfb_adjust_size(u16 *width, u16 *height,
--
1.7.9.5
^ permalink raw reply related
* [PATCHv3 3/5] OMAP: SDRC: remove VRFB code
From: Tomi Valkeinen @ 2012-10-17 10:18 UTC (permalink / raw)
To: linux-omap, linux-fbdev, tony; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1350469102-24888-1-git-send-email-tomi.valkeinen@ti.com>
Now that VRFB driver handles its registers independently, we can remove
the VRFB related code from OMAP's sdrc.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap2/sdrc.c | 16 ----------------
arch/arm/plat-omap/include/plat/sdrc.h | 7 -------
2 files changed, 23 deletions(-)
diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c
index e3d345f..4282e6e 100644
--- a/arch/arm/mach-omap2/sdrc.c
+++ b/arch/arm/mach-omap2/sdrc.c
@@ -160,19 +160,3 @@ void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
sdrc_write_reg(l, SDRC_POWER);
omap2_sms_save_context();
}
-
-void omap2_sms_write_rot_control(u32 val, unsigned ctx)
-{
- sms_write_reg(val, SMS_ROT_CONTROL(ctx));
-}
-
-void omap2_sms_write_rot_size(u32 val, unsigned ctx)
-{
- sms_write_reg(val, SMS_ROT_SIZE(ctx));
-}
-
-void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx)
-{
- sms_write_reg(val, SMS_ROT_PHYSICAL_BA(ctx));
-}
-
diff --git a/arch/arm/plat-omap/include/plat/sdrc.h b/arch/arm/plat-omap/include/plat/sdrc.h
index 36d6a76..c68bab2 100644
--- a/arch/arm/plat-omap/include/plat/sdrc.h
+++ b/arch/arm/plat-omap/include/plat/sdrc.h
@@ -94,9 +94,6 @@
/* SMS register offsets - read/write with sms_{read,write}_reg() */
#define SMS_SYSCONFIG 0x010
-#define SMS_ROT_CONTROL(context) (0x180 + 0x10 * context)
-#define SMS_ROT_SIZE(context) (0x184 + 0x10 * context)
-#define SMS_ROT_PHYSICAL_BA(context) (0x188 + 0x10 * context)
/* REVISIT: fill in other SMS registers here */
@@ -137,10 +134,6 @@ int omap2_sdrc_get_params(unsigned long r,
void omap2_sms_save_context(void);
void omap2_sms_restore_context(void);
-void omap2_sms_write_rot_control(u32 val, unsigned ctx);
-void omap2_sms_write_rot_size(u32 val, unsigned ctx);
-void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx);
-
#ifdef CONFIG_ARCH_OMAP2
struct memory_timings {
--
1.7.9.5
^ permalink raw reply related
* [PATCHv3 2/5] OMAP: move arch/arm/plat-omap/include/plat/vrfb.h
From: Tomi Valkeinen @ 2012-10-17 10:18 UTC (permalink / raw)
To: linux-omap, linux-fbdev, tony; +Cc: archit, Tomi Valkeinen, Vaibhav Hiremath
In-Reply-To: <1350469102-24888-1-git-send-email-tomi.valkeinen@ti.com>
Now that vrfb driver is not omap dependent anymore, we can move vrfb.h
from arch/arm/plat-omap/include/plat to include/video/omapvrfb.h.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
arch/arm/plat-omap/include/plat/vrfb.h | 66 --------------------------
drivers/media/platform/omap/omap_vout.c | 2 +-
drivers/media/platform/omap/omap_vout_vrfb.c | 2 +-
drivers/media/platform/omap/omap_voutdef.h | 2 +-
drivers/video/omap2/omapfb/omapfb-ioctl.c | 2 +-
drivers/video/omap2/omapfb/omapfb-main.c | 2 +-
drivers/video/omap2/omapfb/omapfb-sysfs.c | 2 +-
drivers/video/omap2/vrfb.c | 2 +-
include/video/omapvrfb.h | 66 ++++++++++++++++++++++++++
9 files changed, 73 insertions(+), 73 deletions(-)
delete mode 100644 arch/arm/plat-omap/include/plat/vrfb.h
create mode 100644 include/video/omapvrfb.h
diff --git a/arch/arm/plat-omap/include/plat/vrfb.h b/arch/arm/plat-omap/include/plat/vrfb.h
deleted file mode 100644
index 3792bde..0000000
--- a/arch/arm/plat-omap/include/plat/vrfb.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * VRFB Rotation Engine
- *
- * Copyright (C) 2009 Nokia Corporation
- * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __OMAP_VRFB_H__
-#define __OMAP_VRFB_H__
-
-#define OMAP_VRFB_LINE_LEN 2048
-
-struct vrfb {
- u8 context;
- void __iomem *vaddr[4];
- unsigned long paddr[4];
- u16 xres;
- u16 yres;
- u16 xoffset;
- u16 yoffset;
- u8 bytespp;
- bool yuv_mode;
-};
-
-#ifdef CONFIG_OMAP2_VRFB
-extern int omap_vrfb_request_ctx(struct vrfb *vrfb);
-extern void omap_vrfb_release_ctx(struct vrfb *vrfb);
-extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
- u8 bytespp);
-extern u32 omap_vrfb_min_phys_size(u16 width, u16 height, u8 bytespp);
-extern u16 omap_vrfb_max_height(u32 phys_size, u16 width, u8 bytespp);
-extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
- u16 width, u16 height,
- unsigned bytespp, bool yuv_mode);
-extern int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot);
-extern void omap_vrfb_restore_context(void);
-
-#else
-static inline int omap_vrfb_request_ctx(struct vrfb *vrfb) { return 0; }
-static inline void omap_vrfb_release_ctx(struct vrfb *vrfb) {}
-static inline void omap_vrfb_adjust_size(u16 *width, u16 *height,
- u8 bytespp) {}
-static inline u32 omap_vrfb_min_phys_size(u16 width, u16 height, u8 bytespp)
- { return 0; }
-static inline u16 omap_vrfb_max_height(u32 phys_size, u16 width, u8 bytespp)
- { return 0; }
-static inline void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
- u16 width, u16 height, unsigned bytespp, bool yuv_mode) {}
-static inline int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot)
- { return 0; }
-static inline void omap_vrfb_restore_context(void) {}
-#endif
-#endif /* __VRFB_H */
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index a3b1a34..3ff94a3 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -46,7 +46,7 @@
#include <plat/cpu.h>
#include <plat/dma.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
#include <video/omapdss.h>
#include "omap_voutlib.h"
diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c
index 4be26abf6c..6c37f92 100644
--- a/drivers/media/platform/omap/omap_vout_vrfb.c
+++ b/drivers/media/platform/omap/omap_vout_vrfb.c
@@ -17,7 +17,7 @@
#include <media/v4l2-device.h>
#include <plat/dma.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
#include "omap_voutdef.h"
#include "omap_voutlib.h"
diff --git a/drivers/media/platform/omap/omap_voutdef.h b/drivers/media/platform/omap/omap_voutdef.h
index 27a95d2..9ccfe1f 100644
--- a/drivers/media/platform/omap/omap_voutdef.h
+++ b/drivers/media/platform/omap/omap_voutdef.h
@@ -12,7 +12,7 @@
#define OMAP_VOUTDEF_H
#include <video/omapdss.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
#define YUYV_BPP 2
#define RGB565_BPP 2
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 606b89f..55a39be 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -30,7 +30,7 @@
#include <linux/export.h>
#include <video/omapdss.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
#include <plat/vram.h>
#include "omapfb.h"
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 16db158..5943b3a 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -33,7 +33,7 @@
#include <video/omapdss.h>
#include <plat/cpu.h>
#include <plat/vram.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
#include "omapfb.h"
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index e8d8cc7..17aa174 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -30,7 +30,7 @@
#include <linux/omapfb.h>
#include <video/omapdss.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
#include "omapfb.h"
diff --git a/drivers/video/omap2/vrfb.c b/drivers/video/omap2/vrfb.c
index fda45cc..e4a0450 100644
--- a/drivers/video/omap2/vrfb.c
+++ b/drivers/video/omap2/vrfb.c
@@ -28,7 +28,7 @@
#include <linux/mutex.h>
#include <linux/platform_device.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
#ifdef DEBUG
#define DBG(format, ...) pr_debug("VRFB: " format, ## __VA_ARGS__)
diff --git a/include/video/omapvrfb.h b/include/video/omapvrfb.h
new file mode 100644
index 0000000..3792bde
--- /dev/null
+++ b/include/video/omapvrfb.h
@@ -0,0 +1,66 @@
+/*
+ * VRFB Rotation Engine
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __OMAP_VRFB_H__
+#define __OMAP_VRFB_H__
+
+#define OMAP_VRFB_LINE_LEN 2048
+
+struct vrfb {
+ u8 context;
+ void __iomem *vaddr[4];
+ unsigned long paddr[4];
+ u16 xres;
+ u16 yres;
+ u16 xoffset;
+ u16 yoffset;
+ u8 bytespp;
+ bool yuv_mode;
+};
+
+#ifdef CONFIG_OMAP2_VRFB
+extern int omap_vrfb_request_ctx(struct vrfb *vrfb);
+extern void omap_vrfb_release_ctx(struct vrfb *vrfb);
+extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
+ u8 bytespp);
+extern u32 omap_vrfb_min_phys_size(u16 width, u16 height, u8 bytespp);
+extern u16 omap_vrfb_max_height(u32 phys_size, u16 width, u8 bytespp);
+extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
+ u16 width, u16 height,
+ unsigned bytespp, bool yuv_mode);
+extern int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot);
+extern void omap_vrfb_restore_context(void);
+
+#else
+static inline int omap_vrfb_request_ctx(struct vrfb *vrfb) { return 0; }
+static inline void omap_vrfb_release_ctx(struct vrfb *vrfb) {}
+static inline void omap_vrfb_adjust_size(u16 *width, u16 *height,
+ u8 bytespp) {}
+static inline u32 omap_vrfb_min_phys_size(u16 width, u16 height, u8 bytespp)
+ { return 0; }
+static inline u16 omap_vrfb_max_height(u32 phys_size, u16 width, u8 bytespp)
+ { return 0; }
+static inline void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
+ u16 width, u16 height, unsigned bytespp, bool yuv_mode) {}
+static inline int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot)
+ { return 0; }
+static inline void omap_vrfb_restore_context(void) {}
+#endif
+#endif /* __VRFB_H */
--
1.7.9.5
^ permalink raw reply related
* [PATCHv3 1/5] OMAP: VRFB: convert vrfb to platform device
From: Tomi Valkeinen @ 2012-10-17 10:18 UTC (permalink / raw)
To: linux-omap, linux-fbdev, tony; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1350469102-24888-1-git-send-email-tomi.valkeinen@ti.com>
This patch converts vrfb library into a platform device, in an effort to
remove omap dependencies.
The platform device is registered in arch/arm/plat-omap/fb.c and
assigned resources depending on whether running on omap2 or omap3.
The vrfb driver will parse those resources and use them to access vrfb
configuration registers and the vrfb virtual rotation areas.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
---
arch/arm/plat-omap/fb.c | 61 ++++++++++++++++++++++
drivers/video/omap2/vrfb.c | 124 +++++++++++++++++++++++++++++++++++++-------
2 files changed, 165 insertions(+), 20 deletions(-)
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index bcbb9d5..f868cae 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -33,6 +33,67 @@
#include <mach/hardware.h>
#include <asm/mach/map.h>
+#include <plat/cpu.h>
+
+#ifdef CONFIG_OMAP2_VRFB
+
+/*
+ * The first memory resource is the register region for VRFB,
+ * the rest are VRFB virtual memory areas for each VRFB context.
+ */
+
+static const struct resource omap2_vrfb_resources[] = {
+ DEFINE_RES_MEM_NAMED(0x68008000u, 0x40, "vrfb-regs"),
+ DEFINE_RES_MEM_NAMED(0x70000000u, 0x4000000, "vrfb-area-0"),
+ DEFINE_RES_MEM_NAMED(0x74000000u, 0x4000000, "vrfb-area-1"),
+ DEFINE_RES_MEM_NAMED(0x78000000u, 0x4000000, "vrfb-area-2"),
+ DEFINE_RES_MEM_NAMED(0x7c000000u, 0x4000000, "vrfb-area-3"),
+};
+
+static const struct resource omap3_vrfb_resources[] = {
+ DEFINE_RES_MEM_NAMED(0x6C000180u, 0xc0, "vrfb-regs"),
+ DEFINE_RES_MEM_NAMED(0x70000000u, 0x4000000, "vrfb-area-0"),
+ DEFINE_RES_MEM_NAMED(0x74000000u, 0x4000000, "vrfb-area-1"),
+ DEFINE_RES_MEM_NAMED(0x78000000u, 0x4000000, "vrfb-area-2"),
+ DEFINE_RES_MEM_NAMED(0x7c000000u, 0x4000000, "vrfb-area-3"),
+ DEFINE_RES_MEM_NAMED(0xe0000000u, 0x4000000, "vrfb-area-4"),
+ DEFINE_RES_MEM_NAMED(0xe4000000u, 0x4000000, "vrfb-area-5"),
+ DEFINE_RES_MEM_NAMED(0xe8000000u, 0x4000000, "vrfb-area-6"),
+ DEFINE_RES_MEM_NAMED(0xec000000u, 0x4000000, "vrfb-area-7"),
+ DEFINE_RES_MEM_NAMED(0xf0000000u, 0x4000000, "vrfb-area-8"),
+ DEFINE_RES_MEM_NAMED(0xf4000000u, 0x4000000, "vrfb-area-9"),
+ DEFINE_RES_MEM_NAMED(0xf8000000u, 0x4000000, "vrfb-area-10"),
+ DEFINE_RES_MEM_NAMED(0xfc000000u, 0x4000000, "vrfb-area-11"),
+};
+
+static int __init omap_init_vrfb(void)
+{
+ struct platform_device *pdev;
+ const struct resource *res;
+ unsigned int num_res;
+
+ if (cpu_is_omap24xx()) {
+ res = omap2_vrfb_resources;
+ num_res = ARRAY_SIZE(omap2_vrfb_resources);
+ } else if (cpu_is_omap34xx()) {
+ res = omap3_vrfb_resources;
+ num_res = ARRAY_SIZE(omap3_vrfb_resources);
+ } else {
+ return 0;
+ }
+
+ pdev = platform_device_register_resndata(NULL, "omapvrfb", -1,
+ res, num_res, NULL, 0);
+
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+ else
+ return 0;
+}
+
+arch_initcall(omap_init_vrfb);
+#endif
+
#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
static bool omapfb_lcd_configured;
diff --git a/drivers/video/omap2/vrfb.c b/drivers/video/omap2/vrfb.c
index 7e99022..fda45cc 100644
--- a/drivers/video/omap2/vrfb.c
+++ b/drivers/video/omap2/vrfb.c
@@ -26,9 +26,9 @@
#include <linux/io.h>
#include <linux/bitops.h>
#include <linux/mutex.h>
+#include <linux/platform_device.h>
#include <plat/vrfb.h>
-#include <plat/sdrc.h>
#ifdef DEBUG
#define DBG(format, ...) pr_debug("VRFB: " format, ## __VA_ARGS__)
@@ -36,10 +36,10 @@
#define DBG(format, ...)
#endif
-#define SMS_ROT_VIRT_BASE(context, rot) \
- (((context >= 4) ? 0xD0000000 : 0x70000000) \
- + (0x4000000 * (context)) \
- + (0x1000000 * (rot)))
+#define SMS_ROT_CONTROL(context) (0x0 + 0x10 * context)
+#define SMS_ROT_SIZE(context) (0x4 + 0x10 * context)
+#define SMS_ROT_PHYSICAL_BA(context) (0x8 + 0x10 * context)
+#define SMS_ROT_VIRT_BASE(rot) (0x1000000 * (rot))
#define OMAP_VRFB_SIZE (2048 * 2048 * 4)
@@ -53,10 +53,16 @@
#define SMS_PW_OFFSET 4
#define SMS_PS_OFFSET 0
-#define VRFB_NUM_CTXS 12
/* bitmap of reserved contexts */
static unsigned long ctx_map;
+struct vrfb_ctx {
+ u32 base;
+ u32 physical_ba;
+ u32 control;
+ u32 size;
+};
+
static DEFINE_MUTEX(ctx_lock);
/*
@@ -65,17 +71,32 @@ static DEFINE_MUTEX(ctx_lock);
* we don't need locking, since no drivers will run until after the wake-up
* has finished.
*/
-static struct {
- u32 physical_ba;
- u32 control;
- u32 size;
-} vrfb_hw_context[VRFB_NUM_CTXS];
+
+static void __iomem *vrfb_base;
+
+static int num_ctxs;
+static struct vrfb_ctx *ctxs;
+
+static void omap2_sms_write_rot_control(u32 val, unsigned ctx)
+{
+ __raw_writel(val, vrfb_base + SMS_ROT_CONTROL(ctx));
+}
+
+static void omap2_sms_write_rot_size(u32 val, unsigned ctx)
+{
+ __raw_writel(val, vrfb_base + SMS_ROT_SIZE(ctx));
+}
+
+static void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx)
+{
+ __raw_writel(val, vrfb_base + SMS_ROT_PHYSICAL_BA(ctx));
+}
static inline void restore_hw_context(int ctx)
{
- omap2_sms_write_rot_control(vrfb_hw_context[ctx].control, ctx);
- omap2_sms_write_rot_size(vrfb_hw_context[ctx].size, ctx);
- omap2_sms_write_rot_physical_ba(vrfb_hw_context[ctx].physical_ba, ctx);
+ omap2_sms_write_rot_control(ctxs[ctx].control, ctx);
+ omap2_sms_write_rot_size(ctxs[ctx].size, ctx);
+ omap2_sms_write_rot_physical_ba(ctxs[ctx].physical_ba, ctx);
}
static u32 get_image_width_roundup(u16 width, u8 bytespp)
@@ -196,9 +217,9 @@ void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
control |= VRFB_PAGE_WIDTH_EXP << SMS_PW_OFFSET;
control |= VRFB_PAGE_HEIGHT_EXP << SMS_PH_OFFSET;
- vrfb_hw_context[ctx].physical_ba = paddr;
- vrfb_hw_context[ctx].size = size;
- vrfb_hw_context[ctx].control = control;
+ ctxs[ctx].physical_ba = paddr;
+ ctxs[ctx].size = size;
+ ctxs[ctx].control = control;
omap2_sms_write_rot_physical_ba(paddr, ctx);
omap2_sms_write_rot_size(size, ctx);
@@ -274,11 +295,11 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb)
mutex_lock(&ctx_lock);
- for (ctx = 0; ctx < VRFB_NUM_CTXS; ++ctx)
+ for (ctx = 0; ctx < num_ctxs; ++ctx)
if ((ctx_map & (1 << ctx)) = 0)
break;
- if (ctx = VRFB_NUM_CTXS) {
+ if (ctx = num_ctxs) {
pr_err("vrfb: no free contexts\n");
r = -EBUSY;
goto out;
@@ -293,7 +314,7 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb)
vrfb->context = ctx;
for (rot = 0; rot < 4; ++rot) {
- paddr = SMS_ROT_VIRT_BASE(ctx, rot);
+ paddr = ctxs[ctx].base + SMS_ROT_VIRT_BASE(rot);
if (!request_mem_region(paddr, OMAP_VRFB_SIZE, "vrfb")) {
pr_err("vrfb: failed to reserve VRFB "
"area for ctx %d, rotation %d\n",
@@ -314,3 +335,66 @@ out:
return r;
}
EXPORT_SYMBOL(omap_vrfb_request_ctx);
+
+static int __init vrfb_probe(struct platform_device *pdev)
+{
+ struct resource *mem;
+ int i;
+
+ /* first resource is the register res, the rest are vrfb contexts */
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "can't get vrfb base address\n");
+ return -EINVAL;
+ }
+
+ vrfb_base = devm_request_and_ioremap(&pdev->dev, mem);
+ if (!vrfb_base) {
+ dev_err(&pdev->dev, "can't ioremap vrfb memory\n");
+ return -ENOMEM;
+ }
+
+ num_ctxs = pdev->num_resources - 1;
+
+ ctxs = devm_kzalloc(&pdev->dev,
+ sizeof(struct vrfb_ctx) * num_ctxs,
+ GFP_KERNEL);
+
+ if (!ctxs)
+ return -ENOMEM;
+
+ for (i = 0; i < num_ctxs; ++i) {
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i);
+ if (!mem) {
+ dev_err(&pdev->dev, "can't get vrfb ctx %d address\n",
+ i);
+ return -EINVAL;
+ }
+
+ ctxs[i].base = mem->start;
+ }
+
+ return 0;
+}
+
+static struct platform_driver vrfb_driver = {
+ .driver.name = "omapvrfb",
+};
+
+static int __init vrfb_init(void)
+{
+ return platform_driver_probe(&vrfb_driver, &vrfb_probe);
+}
+
+static void __exit vrfb_exit(void)
+{
+ platform_driver_unregister(&vrfb_driver);
+}
+
+module_init(vrfb_init);
+module_exit(vrfb_exit);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
+MODULE_DESCRIPTION("OMAP VRFB");
+MODULE_LICENSE("GPL v2");
--
1.7.9.5
^ permalink raw reply related
* [PATCHv3 0/5] OMAP: VRFB: convert to platform device
From: Tomi Valkeinen @ 2012-10-17 10:18 UTC (permalink / raw)
To: linux-omap, linux-fbdev, tony; +Cc: archit, Tomi Valkeinen
This is the third version of the series. Changes to v2 are:
* rebased on 3.7-rc1 to resolve conflicts
* add omap_vrfb_supported() so that cpu_is_* check can be removed from omapfb
As Kevin Hilman pointed out, the context restore is not functional. I didn't
touch that, as it's not functional with the current kernel either (and nobody
has complained, so it can't be that critical).
Tomi
Tomi Valkeinen (5):
OMAP: VRFB: convert vrfb to platform device
OMAP: move arch/arm/plat-omap/include/plat/vrfb.h
OMAP: SDRC: remove VRFB code
OMAPDSS: VRFB: add omap_vrfb_supported()
OMAPFB: use omap_vrfb_supported()
arch/arm/mach-omap2/sdrc.c | 16 ---
arch/arm/plat-omap/fb.c | 61 +++++++++++
arch/arm/plat-omap/include/plat/sdrc.h | 7 --
arch/arm/plat-omap/include/plat/vrfb.h | 66 ------------
drivers/media/platform/omap/omap_vout.c | 2 +-
drivers/media/platform/omap/omap_vout_vrfb.c | 2 +-
drivers/media/platform/omap/omap_voutdef.h | 2 +-
drivers/video/omap2/omapfb/omapfb-ioctl.c | 2 +-
drivers/video/omap2/omapfb/omapfb-main.c | 8 +-
drivers/video/omap2/omapfb/omapfb-sysfs.c | 2 +-
drivers/video/omap2/vrfb.c | 142 ++++++++++++++++++++++----
include/video/omapvrfb.h | 68 ++++++++++++
12 files changed, 257 insertions(+), 121 deletions(-)
delete mode 100644 arch/arm/plat-omap/include/plat/vrfb.h
create mode 100644 include/video/omapvrfb.h
--
1.7.9.5
^ permalink raw reply
* [PATCH 9/9] drivers/video: fsl-diu-fb: store EDID data in the global object
From: Timur Tabi @ 2012-10-16 22:33 UTC (permalink / raw)
To: linux-fbdev
Although the DIU driver creates five framebuffer devices, only the first
one controls the physical display. The remaining four are virtual "AOIs".
Therefore, the EDID data should be stored in the global fsl_diu_data
object, instead of the per-framebuffer object.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
drivers/video/fsl-diu-fb.c | 30 +++++++++++++-----------------
1 files changed, 13 insertions(+), 17 deletions(-)
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 0883bc4..d3fc92e 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -342,7 +342,6 @@ struct mfb_info {
int x_aoi_d; /* aoi display x offset to physical screen */
int y_aoi_d; /* aoi display y offset to physical screen */
struct fsl_diu_data *parent;
- u8 *edid_data;
};
/**
@@ -377,6 +376,8 @@ struct fsl_diu_data {
struct diu_ad ad[NUM_AOIS] __aligned(8);
u8 gamma[256 * 3] __aligned(32);
u8 cursor[MAX_CURS * MAX_CURS * 2] __aligned(32);
+ uint8_t edid_data[EDID_LENGTH];
+ bool has_edid;
} __aligned(32);
/* Determine the DMA address of a member of the fsl_diu_data structure */
@@ -1310,6 +1311,7 @@ static int __devinit install_fb(struct fb_info *info)
{
int rc;
struct mfb_info *mfbi = info->par;
+ struct fsl_diu_data *data = mfbi->parent;
const char *aoi_mode, *init_aoi_mode = "320x240";
struct fb_videomode *db = fsl_diu_mode_db;
unsigned int dbsize = ARRAY_SIZE(fsl_diu_mode_db);
@@ -1326,9 +1328,9 @@ static int __devinit install_fb(struct fb_info *info)
return rc;
if (mfbi->index = PLANE0) {
- if (mfbi->edid_data) {
+ if (data->has_edid) {
/* Now build modedb from EDID */
- fb_edid_to_monspecs(mfbi->edid_data, &info->monspecs);
+ fb_edid_to_monspecs(data->edid_data, &info->monspecs);
fb_videomode_to_modelist(info->monspecs.modedb,
info->monspecs.modedb_len,
&info->modelist);
@@ -1346,7 +1348,7 @@ static int __devinit install_fb(struct fb_info *info)
* For plane 0 we continue and look into
* driver's internal modedb.
*/
- if ((mfbi->index = PLANE0) && mfbi->edid_data)
+ if ((mfbi->index = PLANE0) && data->has_edid)
has_default_mode = 0;
else
return -EINVAL;
@@ -1410,9 +1412,6 @@ static void uninstall_fb(struct fb_info *info)
if (!mfbi->registered)
return;
- if (mfbi->index = PLANE0)
- kfree(mfbi->edid_data);
-
unregister_framebuffer(info);
unmap_video_memory(info);
if (&info->cmap)
@@ -1525,6 +1524,7 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
struct mfb_info *mfbi;
struct fsl_diu_data *data;
dma_addr_t dma_addr; /* DMA addr of fsl_diu_data struct */
+ const void *prop;
unsigned int i;
int ret;
@@ -1568,17 +1568,13 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info));
mfbi->parent = data;
mfbi->ad = &data->ad[i];
+ }
- if (mfbi->index = PLANE0) {
- const u8 *prop;
- int len;
-
- /* Get EDID */
- prop = of_get_property(np, "edid", &len);
- if (prop && len = EDID_LENGTH)
- mfbi->edid_data = kmemdup(prop, EDID_LENGTH,
- GFP_KERNEL);
- }
+ /* Get the EDID data from the device tree, if present */
+ prop = of_get_property(np, "edid", &ret);
+ if (prop && ret = EDID_LENGTH) {
+ memcpy(data->edid_data, prop, EDID_LENGTH);
+ data->has_edid = true;
}
data->diu_reg = of_iomap(np, 0);
--
1.7.3.4
^ permalink raw reply related
* [PATCH 8/9] drivers/video: fsl-diu-fb: don't touch registers for unused features
From: Timur Tabi @ 2012-10-16 22:33 UTC (permalink / raw)
To: linux-fbdev
We don't use the writeback buffer, so don't initialize the registers for
that feature.
The default value for SYN_POL is already zero, so don't re-initialize it.
Writing the INT_STATUS register does nothing.
The value that we write to the PLUT register only makes sense on the
MPC8610 and P1022, so don't touch that register on the MPC5121.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
drivers/video/fsl-diu-fb.c | 23 +++++++++++++++--------
1 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 37175ac..0883bc4 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -825,12 +825,8 @@ static void update_lcdc(struct fb_info *info)
out_be32(&hw->gamma, DMA_ADDR(data, gamma));
out_be32(&hw->cursor, DMA_ADDR(data, cursor));
- out_be32(&hw->bgnd, 0x007F7F7F); /* BGND */
- out_be32(&hw->bgnd_wb, 0); /* BGND_WB */
- out_be32(&hw->disp_size, (var->yres << 16 | var->xres));
- /* DISP SIZE */
- out_be32(&hw->wb_size, 0); /* WB SIZE */
- out_be32(&hw->wb_mem_addr, 0); /* WB MEM ADDR */
+ out_be32(&hw->bgnd, 0x007F7F7F); /* Set background to grey */
+ out_be32(&hw->disp_size, (var->yres << 16) | var->xres);
/* Horizontal and vertical configuration register */
temp = var->left_margin << 22 | /* BP_H */
@@ -847,9 +843,20 @@ static void update_lcdc(struct fb_info *info)
diu_ops.set_pixel_clock(var->pixclock);
- out_be32(&hw->syn_pol, 0); /* SYNC SIGNALS POLARITY */
- out_be32(&hw->int_status, 0); /* INTERRUPT STATUS */
+#ifndef CONFIG_PPC_MPC512x
+ /*
+ * The PLUT register is defined differently on the MPC5121 than it
+ * is on other SOCs. Unfortunately, there's no documentation that
+ * explains how it's supposed to be programmed, so for now, we leave
+ * it at the default value on the MPC5121.
+ *
+ * For other SOCs, program it for the highest priority, which will
+ * reduce the chance of underrun. Technically, we should scale the
+ * priority to match the screen resolution, but doing that properly
+ * requires delicate fine-tuning for each use-case.
+ */
out_be32(&hw->plut, 0x01F5F666);
+#endif
/* Enable the DIU */
enable_lcdc(info);
--
1.7.3.4
^ permalink raw reply related
* [PATCH 7/9] drivers/video: fsl-diu-fb: clean up reset of primary display
From: Timur Tabi @ 2012-10-16 22:33 UTC (permalink / raw)
To: linux-fbdev
Commit 4b5006ec ("shared DIU framebuffer support") added the ability to
retain the splash screen until the framebuffer is opened by user space.
Clean up this code to eliminate redundant writes to registers, and eliminate
the use of dummy area descriptor.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
drivers/video/fsl-diu-fb.c | 19 ++++++-------------
1 files changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index fa7f200..37175ac 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -496,8 +496,7 @@ static void fsl_diu_enable_panel(struct fb_info *info)
switch (mfbi->index) {
case PLANE0:
- if (hw->desc[0] != ad->paddr)
- wr_reg_wa(&hw->desc[0], ad->paddr);
+ wr_reg_wa(&hw->desc[0], ad->paddr);
break;
case PLANE1_AOI0:
cmfbi = &data->mfb[2];
@@ -549,8 +548,7 @@ static void fsl_diu_disable_panel(struct fb_info *info)
switch (mfbi->index) {
case PLANE0:
- if (hw->desc[0] != data->dummy_ad.paddr)
- wr_reg_wa(&hw->desc[0], data->dummy_ad.paddr);
+ wr_reg_wa(&hw->desc[0], 0);
break;
case PLANE1_AOI0:
cmfbi = &data->mfb[2];
@@ -1519,7 +1517,6 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct mfb_info *mfbi;
struct fsl_diu_data *data;
- int diu_mode;
dma_addr_t dma_addr; /* DMA addr of fsl_diu_data struct */
unsigned int i;
int ret;
@@ -1584,10 +1581,6 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
goto error;
}
- diu_mode = in_be32(&data->diu_reg->diu_mode);
- if (diu_mode = MFB_MODE0)
- out_be32(&data->diu_reg->diu_mode, 0); /* disable DIU */
-
/* Get the IRQ of the DIU */
data->irq = irq_of_parse_and_map(np, 0);
@@ -1609,11 +1602,11 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
data->dummy_ad.paddr = DMA_ADDR(data, dummy_ad);
/*
- * Let DIU display splash screen if it was pre-initialized
- * by the bootloader, set dummy area descriptor otherwise.
+ * Let DIU continue to display splash screen if it was pre-initialized
+ * by the bootloader; otherwise, clear the display.
*/
- if (diu_mode = MFB_MODE0)
- out_be32(&data->diu_reg->desc[0], data->dummy_ad.paddr);
+ if (in_be32(&data->diu_reg->diu_mode) = MFB_MODE0)
+ out_be32(&data->diu_reg->desc[0], 0);
out_be32(&data->diu_reg->desc[1], data->dummy_ad.paddr);
out_be32(&data->diu_reg->desc[2], data->dummy_ad.paddr);
--
1.7.3.4
^ permalink raw reply related
* [PATCH 6/9] drivers/video: fsl-diu-fb: remove unused 'cursor_reset' variable
From: Timur Tabi @ 2012-10-16 22:33 UTC (permalink / raw)
To: linux-fbdev
Probably left over from initial development in hardware cursor support
that never made it upstream.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
drivers/video/fsl-diu-fb.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 6e32ba8..fa7f200 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -337,7 +337,6 @@ struct mfb_info {
int registered;
unsigned long pseudo_palette[16];
struct diu_ad *ad;
- int cursor_reset;
unsigned char g_alpha;
unsigned int count;
int x_aoi_d; /* aoi display x offset to physical screen */
@@ -982,7 +981,6 @@ static int fsl_diu_set_par(struct fb_info *info)
hw = data->diu_reg;
set_fix(info);
- mfbi->cursor_reset = 1;
len = info->var.yres_virtual * info->fix.line_length;
/* Alloc & dealloc each time resolution/bpp change */
--
1.7.3.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox