Re: [PATCH v2] OMAPDSS: HACK: Ensure DSS clock domain gets out of idle when HDMI is enabled
Hi, On Tuesday 14 February 2012 06:45 PM, Tomi Valkeinen wrote: On Tue, 2012-02-14 at 13:58 +0100, Cousson, Benoit wrote: Hi Tomi, Benoit, do you think we'll get the MODULEMODE mess cleaned up in the hwmod/clk framework at some point, and the drivers could do without these kinds of hacks? =) The best way to fix that for my point of view is to go to device tree or/and to consider the DSS as the parent of all the DSS modules. pm_runtime will then always ensure that the parent is enabled before any of the child are used. Ah, right. Sounds fine to me. But is that a proper fix? Are we sure the MODULEMODE will then always be handled correctly? Isn't the core problem still there, it just doesn't happen with the setup anymore? I mean, if we have these special requirements regarding MODULEMODE, and the code doesn't really know about it, would it get broken easily with restructuring/changes? And no, I don't have any clear idea why/how it would break, but I have just gotten the impression that the MODULEMODE is not handled quite properly (and so we have these current problems), and having dss_core as the parent of other dss modules doesn't really fix that in any way. I agree with that. In the current approach, we have multiple platform devices for DSS, and all of them belong to the same clock domain, and the clock domain has just one MODULEMODE bit field. When shutting off a platform device(by calling pm_runtime_put()), hwmod enables/disables MODULEMODE without taking into mind that other active platform devices may still need it. So, for example, if we have 2 platform devices, say dss and dispc, and we have code like: dispc_foo() { pm_runtime_get(dispc_pdev); ... ... pm_runtime_put(dispc_pdev); } dss_foo() { pm_runtime_get(dss_pdev); ... ... dispc_foo(); /* MODULEMODE off after this */ ... ... pm_runtime_put(dss_pdev); } This will lead to the situation of one platform device disabling MODULEMODE even though other platform devices need it. This may not be resolved in device tree either. We would need to have some use count mechanism for these bits, or attach MODULEMODE only to one platform device, and don't give others control to enable/disable it. Archit -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] OMAPDSS: HACK: Ensure DSS clock domain gets out of idle when HDMI is enabled
On Tuesday 14 February 2012 07:03 PM, Tomi Valkeinen wrote: On Tue, 2012-02-14 at 19:00 +0530, Archit Taneja wrote: Hi, On Tuesday 14 February 2012 06:45 PM, Tomi Valkeinen wrote: On Tue, 2012-02-14 at 13:58 +0100, Cousson, Benoit wrote: Hi Tomi, Benoit, do you think we'll get the MODULEMODE mess cleaned up in the hwmod/clk framework at some point, and the drivers could do without these kinds of hacks? =) The best way to fix that for my point of view is to go to device tree or/and to consider the DSS as the parent of all the DSS modules. pm_runtime will then always ensure that the parent is enabled before any of the child are used. Ah, right. Sounds fine to me. But is that a proper fix? Are we sure the MODULEMODE will then always be handled correctly? Isn't the core problem still there, it just doesn't happen with the setup anymore? I mean, if we have these special requirements regarding MODULEMODE, and the code doesn't really know about it, would it get broken easily with restructuring/changes? And no, I don't have any clear idea why/how it would break, but I have just gotten the impression that the MODULEMODE is not handled quite properly (and so we have these current problems), and having dss_core as the parent of other dss modules doesn't really fix that in any way. I agree with that. In the current approach, we have multiple platform devices for DSS, and all of them belong to the same clock domain, and the clock domain has just one MODULEMODE bit field. When shutting off a platform device(by calling pm_runtime_put()), hwmod enables/disables MODULEMODE without taking into mind that other active platform devices may still need it. So, for example, if we have 2 platform devices, say dss and dispc, and we have code like: dispc_foo() { pm_runtime_get(dispc_pdev); ... ... pm_runtime_put(dispc_pdev); } dss_foo() { pm_runtime_get(dss_pdev); ... ... dispc_foo(); /* MODULEMODE off after this */ ... ... pm_runtime_put(dss_pdev); } This will lead to the situation of one platform device disabling MODULEMODE even though other platform devices need it. This may not be resolved in device tree either. We would need to have some use count mechanism for these bits, or attach MODULEMODE only to one platform device, and don't give others control to enable/disable it. Hmm, are you sure? Not that I checked the code, but isn't MODULEMODE mapped to a dss clock (was it dss_clk)?. And so, the clock's refcount should keep the MODULEMODE enabled/disabled? Yes, that's how we are currently dealing with it and making things work. We are forced to represent MODULEMODE as a clock. I forgot to mention that in the last mail :) However, other modules don't do this. modulemode control is taken care by hwmod by itself. We just have to fill the hwmod field '.prcm.omap4.modulemode' and get done with it. If we try this approach, we get into the trouble I mentioned before. We represent MODULEMODE as dss_fck, and make this the l3 slave clock for all DSS hwmods. This way, we ensure that it gets enabled, and we get a usecount associated to it. We shouldn't stick to this approach because: - It isn't exactly correct. MODULEMODE isn't a clock, and others don't do it. - DSS requires a particular sequence of disabling clocks to go into lower power states, and with the current approach, this doesn't happen. So, DSS doesn't idle, and that's the whole purpose of this :) Archit Tomi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] OMAPDSS: HACK: Ensure DSS clock domain gets out of idle when HDMI is enabled
On Tuesday 14 February 2012 10:29 PM, Shilimkar, Santosh wrote: On Tue, Feb 14, 2012 at 9:32 PM, Cousson, Benoitb-cous...@ti.com wrote: On 2/14/2012 2:45 PM, Archit Taneja wrote: On Tuesday 14 February 2012 07:03 PM, Tomi Valkeinen wrote: On Tue, 2012-02-14 at 19:00 +0530, Archit Taneja wrote: Hi, On Tuesday 14 February 2012 06:45 PM, Tomi Valkeinen wrote: On Tue, 2012-02-14 at 13:58 +0100, Cousson, Benoit wrote: Hi Tomi, Benoit, do you think we'll get the MODULEMODE mess cleaned up in the hwmod/clk framework at some point, and the drivers could do without these kinds of hacks? =) The best way to fix that for my point of view is to go to device tree or/and to consider the DSS as the parent of all the DSS modules. pm_runtime will then always ensure that the parent is enabled before any of the child are used. Ah, right. Sounds fine to me. But is that a proper fix? Are we sure the MODULEMODE will then always be handled correctly? Isn't the core problem still there, it just doesn't happen with the setup anymore? I mean, if we have these special requirements regarding MODULEMODE, and the code doesn't really know about it, would it get broken easily with restructuring/changes? And no, I don't have any clear idea why/how it would break, but I have just gotten the impression that the MODULEMODE is not handled quite properly (and so we have these current problems), and having dss_core as the parent of other dss modules doesn't really fix that in any way. I agree with that. In the current approach, we have multiple platform devices for DSS, and all of them belong to the same clock domain, and the clock domain has just one MODULEMODE bit field. When shutting off a platform device(by calling pm_runtime_put()), hwmod enables/disables MODULEMODE without taking into mind that other active platform devices may still need it. So, for example, if we have 2 platform devices, say dss and dispc, and we have code like: dispc_foo() { pm_runtime_get(dispc_pdev); ... ... pm_runtime_put(dispc_pdev); } dss_foo() { pm_runtime_get(dss_pdev); ... ... dispc_foo(); /* MODULEMODE off after this */ ... ... pm_runtime_put(dss_pdev); } This will lead to the situation of one platform device disabling MODULEMODE even though other platform devices need it. This may not be resolved in device tree either. We would need to have some use count mechanism for these bits, or attach MODULEMODE only to one platform device, and don't give others control to enable/disable it. Hmm, are you sure? Not that I checked the code, but isn't MODULEMODE mapped to a dss clock (was it dss_clk)?. And so, the clock's refcount should keep the MODULEMODE enabled/disabled? Yes, that's how we are currently dealing with it and making things work. We are forced to represent MODULEMODE as a clock. I forgot to mention that in the last mail :) However, other modules don't do this. modulemode control is taken care by hwmod by itself. We just have to fill the hwmod field '.prcm.omap4.modulemode' and get done with it. If we try this approach, we get into the trouble I mentioned before. We represent MODULEMODE as dss_fck, and make this the l3 slave clock for all DSS hwmods. This way, we ensure that it gets enabled, and we get a usecount associated to it. We shouldn't stick to this approach because: - It isn't exactly correct. MODULEMODE isn't a clock, and others don't do it. Yes, fully agree. This was done like that as a hack to avoid any regression because at that time we were not sure if that dependency will have to be handled by the hwmod fmwk or by the driver. Now, I'm sure it should not be handled by the hwmod fmwk :-) - DSS requires a particular sequence of disabling clocks to go into lower power states, and with the current approach, this doesn't happen. So, DSS doesn't idle, and that's the whole purpose of this :) I'm just curious, what particular sequence is required? IIRC, the main issue is the order in which functional clock and what is so called optional clock enabled While enabling the module 1. Enable optional clock 2. Enabled module mode. While disabling module 1. Disable module mode 2. Disable optional clock. I think only above sequence work. Not following above in either path leads to modules being stuck in transition. Is that right Archit ? Yes. Also, this transition failure happens when DSS clock domain is set to hardware supervised wakeup(HWAUTO). The opt clock which requires this ordering with module mode is DSS_FCLK by default. However, if some other clock (like DSI PLL, sourced by SYS_CLK) is the source for DISPC_FCLK, then that clock is the one which needs to be ordered with module mode. Archit -- To unsubscribe from this list: send the line unsubscribe linux-fbdev in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message
Re: [PATCH] OMAPDSS: HACK: Ensure DSS clock domain gets out of idle when HDMI is enabled
On Thursday 09 February 2012 05:32 PM, Tomi Valkeinen wrote: Hi, On Thu, 2012-02-09 at 12:14 +0530, Archit Taneja wrote: For DSS clock domain to transition from idle to active state, it's necessary to enable the optional clock DSS_FCLK before we enable the module using the MODULEMODE bits in the DSS clock domain's CM_DSS_DSS_CLKCTRL register. This sequence was not followed correctly for the 'dss_hdmi' hwmod and it led to DSS clock domain not getting out of idle when pm_runtime_get_sync() was called for hdmi's platform device. Since the clock domain failed to change it's state to active, the hwmod code disables any clocks it had enabled before for this hwmod. This led to the clock 'dss_48mhz_clk' getting disabled. When hdmi's runtime_resume() op is called, the call to dss_runtime_get() correctly enables the DSS clock domain this time. But the clock 'dss_48mhz_clk' disabled before is needed for HDMI's PHY to function. Hence, the driver fails There's something wrong with the But the clock... sentence above. The patch looks good, but I think it'd be better to add brief HACK comments in the code also. Otherwise it's too easy to forget about this. I'll make the changes and repost. Archit Tomi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] OMAPDSS: HACK: Ensure DSS clock domain gets out of idle when HDMI is enabled
For DSS clock domain to transition from idle to active state. It's necessary to enable the optional clock DSS_FCLK before we enable the module using the MODULEMODE bits in the clock domain's CM_DSS_DSS_CLKCTRL register. This sequence was not followed correctly for the 'dss_hdmi' hwmod and it led to DSS clock domain not getting out of idle when pm_runtime_get_sync() was called for hdmi's platform device. Since the clock domain failed to change it's state to active, the hwmod code disables any clocks it had enabled before for this hwmod. This led to the clock 'dss_48mhz_clk' gettind disabled. When hdmi's runtime_resume() op is called, the call to dss_runtime_get() correctly enables the DSS clock domain this time. However, the clock 'dss_48mhz_clk' is needed for HDMI's PHY to function correctly. Since it was disabled previously, the driver fails when it tries to enable HDMI's PHY. Fix this for now by ensuring that dss_runtime_get() is called before we call pm_runtime_get_sync() for hdmi's platform device. A correct fix for later would be to modify the DSS related hwmod's mainclks, and also some changes in how opt clocks are handled in the DSS driver. This fixes the issue of HDMI not working when it's the default display. The issue is not seen if any other display is already enabled as the first display would have correctly enabled the DSS clockdomain. Signed-off-by: Archit Taneja arc...@ti.com --- Changes in v2: - Rewrite an unclear paragraph in the commit message - Add comments mentioning that this is a hack drivers/video/omap2/dss/hdmi.c | 24 +++- 1 files changed, 23 insertions(+), 1 deletions(-) diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index d7aa3b0..a36b934 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -165,9 +165,25 @@ static int hdmi_runtime_get(void) DSSDBG(hdmi_runtime_get\n); + /* +* HACK: Add dss_runtime_get() to ensure DSS clock domain is enabled. +* This should be removed later. +*/ + r = dss_runtime_get(); + if (r 0) + goto err_get_dss; + r = pm_runtime_get_sync(hdmi.pdev-dev); WARN_ON(r 0); - return r 0 ? r : 0; + if (r 0) + goto err_get_hdmi; + + return 0; + +err_get_hdmi: + dss_runtime_put(); +err_get_dss: + return r; } static void hdmi_runtime_put(void) @@ -178,6 +194,12 @@ static void hdmi_runtime_put(void) r = pm_runtime_put_sync(hdmi.pdev-dev); WARN_ON(r 0); + + /* +* HACK: This is added to complement the dss_runtime_get() call in +* hdmi_runtime_get(). This should be removed later. +*/ + dss_runtime_put(); } int hdmi_init_display(struct omap_dss_device *dssdev) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: OMAP34xx
On Friday 10 February 2012 04:04 AM, Russell King - ARM Linux wrote: On Thu, Feb 09, 2012 at 12:22:42PM +0530, Archit Taneja wrote: Hi, On Sunday 05 February 2012 08:08 PM, Russell King - ARM Linux wrote: Okay, so this requires backlight support, and TAAL selected, so that sorts that error, but causes others: taal display0: taal panel revision e3.83.7d omapdss DSI error: DSI CIO error, cio irqstatus 20 DSI CIO IRQ 0x20: ERRCONTENTIONLP1_1 omapdss DSI error: DSI CIO error, cio irqstatus 20 DSI CIO IRQ 0x20: ERRCONTENTIONLP1_1 omapdss DSI error: DSI CIO error, cio irqstatus 20 DSI CIO IRQ 0x20: ERRCONTENTIONLP1_1 omapdss DSI error: DSI CIO error, cio irqstatus 20 DSI CIO IRQ 0x20: ERRCONTENTIONLP1_1 omapdss DSI error: DSI CIO error, cio irqstatus 20 DSI CIO IRQ 0x20: ERRCONTENTIONLP1_1 omapdss DSI error: DSI CIO error, cio irqstatus 20 DSI CIO IRQ 0x20: ERRCONTENTIONLP1_1 This happens when the flex cable connected to the display is faulty or loose. Well, I don't know - it works with ES1 and an old kernel just fine. Okay, I'll look into this more. Thanks, Archit -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] OMAPDSS: HACK: Ensure DSS clock domain gets out of idle when HDMI is enabled
For DSS clock domain to transition from idle to active state, it's necessary to enable the optional clock DSS_FCLK before we enable the module using the MODULEMODE bits in the DSS clock domain's CM_DSS_DSS_CLKCTRL register. This sequence was not followed correctly for the 'dss_hdmi' hwmod and it led to DSS clock domain not getting out of idle when pm_runtime_get_sync() was called for hdmi's platform device. Since the clock domain failed to change it's state to active, the hwmod code disables any clocks it had enabled before for this hwmod. This led to the clock 'dss_48mhz_clk' getting disabled. When hdmi's runtime_resume() op is called, the call to dss_runtime_get() correctly enables the DSS clock domain this time. But the clock 'dss_48mhz_clk' disabled before is needed for HDMI's PHY to function. Hence, the driver fails when it tries to enable HDMI's PHY. Fix this for now by ensuring that dss_runtime_get() is called before we call pm_runtime_get_sync() for hdmi's platform device. A correct fix for later would be to modify the DSS related hwmod's mainclks, and also some changes in how opt clocks are handled in the DSS driver. This fixes the issue of HDMI not working when it's the default display. The issue is not seen if any other display is already enabled as the first display would have already correctly enabled the DSS clock domain. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/hdmi.c | 16 +++- 1 files changed, 15 insertions(+), 1 deletions(-) diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index d7aa3b0..ce16a91 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -165,9 +165,21 @@ static int hdmi_runtime_get(void) DSSDBG(hdmi_runtime_get\n); + r = dss_runtime_get(); + if (r 0) + goto err_get_dss; + r = pm_runtime_get_sync(hdmi.pdev-dev); WARN_ON(r 0); - return r 0 ? r : 0; + if (r 0) + goto err_get_hdmi; + + return 0; + +err_get_hdmi: + dss_runtime_put(); +err_get_dss: + return r; } static void hdmi_runtime_put(void) @@ -178,6 +190,8 @@ static void hdmi_runtime_put(void) r = pm_runtime_put_sync(hdmi.pdev-dev); WARN_ON(r 0); + + dss_runtime_put(); } int hdmi_init_display(struct omap_dss_device *dssdev) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: OMAP34xx
Hi, On Sunday 05 February 2012 08:08 PM, Russell King - ARM Linux wrote: On Sun, Feb 05, 2012 at 12:56:26PM +, Russell King - ARM Linux wrote: And here's another (set of) problem(s) on the 4430SDP board once the previous have been worked around: omap_hwmod: l3_div_ck: missing clockdomain for l3_div_ck. omap_hwmod: ipu: failed to hardreset omap_hwmod: mcpdm: cannot be enabled (3) ... machine_constraints_voltage: VUSB: failed to apply 330uV constraint ... twl_reg twl_reg.46: can't register VUSB, -22 twl_reg: probe of twl_reg.46 failed with error -22 ... omap_vc_i2c_init: I2C config for all channels must match. omap_vc_i2c_init: I2C config for all channels must match. Fixing this error message to provide something useful allows this problem to be diagnosed. omap_vc_i2c_init: I2C config for vdd_iva does not match other channels (0). omap_vc_i2c_init: I2C config for vdd_mpu does not match other channels (0). Let's look at the PMIC data for OMAP4: static struct omap_voltdm_pmic omap3_mpu_pmic = { .i2c_high_speed= true, static struct omap_voltdm_pmic omap3_core_pmic = { .i2c_high_speed= true, static struct omap_voltdm_pmic omap4_mpu_pmic = { .i2c_high_speed= true, static struct omap_voltdm_pmic omap4_iva_pmic = { .i2c_high_speed= true, static struct omap_voltdm_pmic omap4_core_pmic = { So, OMAP4's PMIC information for the core domain does not have I2C high speed set, yet the others do. So if this is an illegal configuration then the TWL data is plainly wrong. If it's a legal configuration, the voltage domain code is talking utter crap about requiring all these to match. They can't both be right. Has this code been tested on OMAP4 platforms? I think not (or if it was, it was done blindly without regard for the messages the kernel was spitting out - again, that's a failing of people to properly test their code _before_ sending it upstream.) Power Management for TI OMAP4. clock: disabling unused clocks to save power omapfb omapfb: no driver for display: lcd omapfb omapfb: no driver for display: lcd2 Okay, so this requires backlight support, and TAAL selected, so that sorts that error, but causes others: taal display0: taal panel revision e3.83.7d omapdss DSI error: DSI CIO error, cio irqstatus 20 DSI CIO IRQ 0x20: ERRCONTENTIONLP1_1 omapdss DSI error: DSI CIO error, cio irqstatus 20 DSI CIO IRQ 0x20: ERRCONTENTIONLP1_1 omapdss DSI error: DSI CIO error, cio irqstatus 20 DSI CIO IRQ 0x20: ERRCONTENTIONLP1_1 omapdss DSI error: DSI CIO error, cio irqstatus 20 DSI CIO IRQ 0x20: ERRCONTENTIONLP1_1 omapdss DSI error: DSI CIO error, cio irqstatus 20 DSI CIO IRQ 0x20: ERRCONTENTIONLP1_1 omapdss DSI error: DSI CIO error, cio irqstatus 20 DSI CIO IRQ 0x20: ERRCONTENTIONLP1_1 This happens when the flex cable connected to the display is faulty or loose. Failed to set PHY power mode to 1 omapdss HDMI error: failed to power on device For some reason, enabling TAAL fixes this HDMI error. Why I don't understand but it's very very counter intuitive. This was an issue with our driver. I've posted a fix for this. Thanks, Archit [ cut here ] WARNING: at /home/rmk/git/linux-omap/arch/arm/mach-omap2/omap_hwmod.c:1604 _idle+0x34/0xc8() omap_hwmod: dss_hdmi: idle state can only be entered from enabled state This message doesn't exist in the kernel source as far as I can find. Ah, yes it does, someone well wrapped the message. WARN(1, omap_hwmod: %s: idle state can only be entered from enabled state\n, oh-name); So that goes into my patch of omap fixes. There's others in that file which will get the same treatment. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] OMAPDSS: Features: Maintain dss_feats as a list
On Monday 06 February 2012 04:12 PM, Tomi Valkeinen wrote: Hi, On Mon, 2012-01-30 at 10:52 +0530, Archit Taneja wrote: The number of dss_feat_id members has increased to a large value, the current way of assigning a subset of these features (for a particular OMAP) as a mask is no longer feasible. Maintain the subset of features supported as lists. Make the function dss_has_feature() traverse through this list. I think this makes the code easier to maintain, so in that sense it is good. But I do hesitate a bit, I think many features are checked in often used code paths (the configuration done on each frame when swapping/panning), and bit compare versus finding an item in a list could have performance impact. Then again, I'm purely guessing here, as it could well be that compared to the other code, checking the features is insignificant. Thus, I'm fine with this patch, and we can optimize it later if need be. However, I'm anyway giving a few ideas how this could also be handled: - 64 bit mask. Would be simple, but we'd still have a hard limit there. - Variable length bitmask, i.e. an int or byte array from which a particular bit is checked. There could be a ready made datatype for this in the kernel. There seems to be a bitmask library: tools/power/cpupower/utils/helpers/bitmask.c I don't know how easy it would be to access this though. - Lists like in this patch, but in sorted order. Then, if we're looking for a feat which has, say, number 4 assigned to it, we can stop iterating the list when we hit a feat 4 in the list. Quite simple optimization, but needs extra maintenance to keep the feat lists sorted. This sounds fine. It shouldn't be too much of an effort to maintain sorted lists. We'll just need to ensure that a new feature added has the largest integer value, and is always added at the end of the list(s). Archit Tomi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] OMAPDSS: Features: Maintain dss_feats as a list
On Monday 06 February 2012 04:58 PM, Tomi Valkeinen wrote: On Mon, 2012-02-06 at 16:54 +0530, Archit Taneja wrote: On Monday 06 February 2012 04:12 PM, Tomi Valkeinen wrote: Hi, On Mon, 2012-01-30 at 10:52 +0530, Archit Taneja wrote: The number of dss_feat_id members has increased to a large value, the current way of assigning a subset of these features (for a particular OMAP) as a mask is no longer feasible. Maintain the subset of features supported as lists. Make the function dss_has_feature() traverse through this list. I think this makes the code easier to maintain, so in that sense it is good. But I do hesitate a bit, I think many features are checked in often used code paths (the configuration done on each frame when swapping/panning), and bit compare versus finding an item in a list could have performance impact. Then again, I'm purely guessing here, as it could well be that compared to the other code, checking the features is insignificant. Thus, I'm fine with this patch, and we can optimize it later if need be. However, I'm anyway giving a few ideas how this could also be handled: - 64 bit mask. Would be simple, but we'd still have a hard limit there. - Variable length bitmask, i.e. an int or byte array from which a particular bit is checked. There could be a ready made datatype for this in the kernel. There seems to be a bitmask library: tools/power/cpupower/utils/helpers/bitmask.c I don't know how easy it would be to access this though. - Lists like in this patch, but in sorted order. Then, if we're looking for a feat which has, say, number 4 assigned to it, we can stop iterating the list when we hit a feat 4 in the list. Quite simple optimization, but needs extra maintenance to keep the feat lists sorted. This sounds fine. It shouldn't be too much of an effort to maintain sorted lists. We'll just need to ensure that a new feature added has the largest integer value, and is always added at the end of the list(s). Not necessarily. As we always search the list from index 0 forward, the most often needed features could be in the beginning of the list so they are found faster. At least some features are clearly needed only in some enable/disable paths or similar, and they could clearly be low priority. Right, it would be harder to maintain sorted lists in this case, and it wouldn't be always straight forward to decide which feature has more priority over other :) Archit Tomi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [DSS2] kernel freeze with panel driver
Hi, On Tuesday 31 January 2012 04:26 PM, Patrick wrote: Dear mailing-list, I am working with a vanilla 3.0.17 kernel with some patch for my Omap4430 based board. I am using the driver video/omap2/panel-lgphilips-lb025q02.c with a very similar screen. I have added on my board init file the init code for both the SPI and the panel, like below. static struct omap_dss_device sb_dpi_device = { .type = OMAP_DISPLAY_TYPE_DPI, .name = lcd35, .driver_name= lgphilips_lb035q02_panel, .phy.dpi.data_lines = 24, .platform_enable= sb_panel_enable_lcd, .platform_disable = sb_panel_disable_lcd, }; You have to add a channel field in this, like: .channel = OMAP_DSS_CHANNEL_LCD2, On OMAP4, the DPI interface is connected to LCD2 interface and not LCD interface. That's why you get the error 'display 'lcd35' does not support manager 'lcd'' Can you try with this change and see what happens? Archit ... static struct spi_board_info sb_spi_board_info[] __initdata = { { .modalias = lgphilips_lb035q02_panel-spi, .bus_num= 1, .chip_select= 0, .max_speed_hz = 50, .mode = SPI_MODE_3, }, }; The init of the SPI is done before the one of the panel. When my kernel boot he freeze (without error message) at the moment where it should do the : Console: switching to colour frame buffer device... But in my case it freeze somewhere just before this print. Earlier in the boot process I have the following error message: OMAP DSS rev 4.0 omapdss MANAGER error: display 'lcd35' does not support manager 'lcd' Lcd35 is the name of the screen declared in the board config file. I use the followings bootargs: omapdss.def_disp=lcd35 omapdss.debug=y vram=10M I have tried with the video/omap2/panel-generic-display.c driver with the correct timming. The kernel boot but the screen doesn't work correctly (Only one vertical line is colored). I have tried with panel-lgphilips-lb025q02.c but with initialising only the SPI from the board config file (without calling the display init). The kernel boot but of course the screen doesn't work at all. So it seems that the problem is not from the SPI side. Do you have any idea why I have this problems ? Thanks in advance for your help. Patrick static struct spi_board_info sb_spi_board_info[] __initdata = { { .modalias = lgphilips_lb035q02_panel-spi, .bus_num= 1, .chip_select= 0, .max_speed_hz = 50, .mode = SPI_MODE_3, }, }; I init the SPI before the panel as in your overo board file. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] OMAPDSS: Features: Maintain dss_feats as a list
The number of dss_feat_id members has increased to a large value, the current way of assigning a subset of these features (for a particular OMAP) as a mask is no longer feasible. Maintain the subset of features supported as lists. Make the function dss_has_feature() traverse through this list. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/dss_features.c | 140 +++- drivers/video/omap2/dss/dss_features.h | 54 ++-- 2 files changed, 128 insertions(+), 66 deletions(-) diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index 419419a..656cb69 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -41,7 +41,8 @@ struct omap_dss_features { const struct dss_reg_field *reg_fields; const int num_reg_fields; - const u32 has_feature; + const enum dss_feat_id *features; + const int num_features; const int num_mgrs; const int num_ovls; @@ -337,15 +338,92 @@ static const struct dss_param_range omap4_dss_param_range[] = { [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, }; +static const enum dss_feat_id omap2_dss_feat_list[] = { + FEAT_LCDENABLEPOL, + FEAT_LCDENABLESIGNAL, + FEAT_PCKFREEENABLE, + FEAT_FUNCGATED, + FEAT_ROWREPEATENABLE, + FEAT_RESIZECONF, +}; + +static const enum dss_feat_id omap3430_dss_feat_list[] = { + FEAT_LCDENABLEPOL, + FEAT_LCDENABLESIGNAL, + FEAT_PCKFREEENABLE, + FEAT_FUNCGATED, + FEAT_LINEBUFFERSPLIT, + FEAT_ROWREPEATENABLE, + FEAT_RESIZECONF, + FEAT_DSI_PLL_FREQSEL, + FEAT_DSI_REVERSE_TXCLKESC, + FEAT_VENC_REQUIRES_TV_DAC_CLK, + FEAT_CPR, + FEAT_PRELOAD, + FEAT_FIR_COEF_V, + FEAT_ALPHA_FIXED_ZORDER, + FEAT_FIFO_MERGE, + FEAT_OMAP3_DSI_FIFO_BUG, +}; + +static const enum dss_feat_id omap3630_dss_feat_list[] = { + FEAT_LCDENABLEPOL, + FEAT_LCDENABLESIGNAL, + FEAT_PCKFREEENABLE, + FEAT_FUNCGATED, + FEAT_LINEBUFFERSPLIT, + FEAT_ROWREPEATENABLE, + FEAT_RESIZECONF, + FEAT_DSI_PLL_PWR_BUG, + FEAT_DSI_PLL_FREQSEL, + FEAT_CPR, + FEAT_PRELOAD, + FEAT_FIR_COEF_V, + FEAT_ALPHA_FIXED_ZORDER, + FEAT_FIFO_MERGE, + FEAT_OMAP3_DSI_FIFO_BUG, +}; + +static const enum dss_feat_id omap4430_es1_0_dss_feat_list[] = { + FEAT_MGR_LCD2, + FEAT_CORE_CLK_DIV, + FEAT_LCD_CLK_SRC, + FEAT_DSI_DCS_CMD_CONFIG_VC, + FEAT_DSI_VC_OCP_WIDTH, + FEAT_DSI_GNQ, + FEAT_HANDLE_UV_SEPARATE, + FEAT_ATTR2, + FEAT_CPR, + FEAT_PRELOAD, + FEAT_FIR_COEF_V, + FEAT_ALPHA_FREE_ZORDER, + FEAT_FIFO_MERGE, +}; + +static const enum dss_feat_id omap4_dss_feat_list[] = { + FEAT_MGR_LCD2, + FEAT_CORE_CLK_DIV, + FEAT_LCD_CLK_SRC, + FEAT_DSI_DCS_CMD_CONFIG_VC, + FEAT_DSI_VC_OCP_WIDTH, + FEAT_DSI_GNQ, + FEAT_HDMI_CTS_SWMODE, + FEAT_HANDLE_UV_SEPARATE, + FEAT_ATTR2, + FEAT_CPR, + FEAT_PRELOAD, + FEAT_FIR_COEF_V, + FEAT_ALPHA_FREE_ZORDER, + FEAT_FIFO_MERGE, +}; + /* OMAP2 DSS Features */ static const struct omap_dss_features omap2_dss_features = { .reg_fields = omap2_dss_reg_fields, .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields), - .has_feature= - FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL | - FEAT_PCKFREEENABLE | FEAT_FUNCGATED | - FEAT_ROWREPEATENABLE | FEAT_RESIZECONF, + .features = omap2_dss_feat_list, + .num_features = ARRAY_SIZE(omap2_dss_feat_list), .num_mgrs = 2, .num_ovls = 3, @@ -363,15 +441,8 @@ static const struct omap_dss_features omap3430_dss_features = { .reg_fields = omap3_dss_reg_fields, .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), - .has_feature= - FEAT_LCDENABLEPOL | - FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | - FEAT_FUNCGATED | FEAT_ROWREPEATENABLE | - FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | - FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC | - FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD | - FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE | - FEAT_OMAP3_DSI_FIFO_BUG, + .features = omap3430_dss_feat_list, + .num_features = ARRAY_SIZE(omap3430_dss_feat_list), .num_mgrs = 2, .num_ovls = 3, @@ -388,15 +459,8 @@ static const struct omap_dss_features omap3630_dss_features = { .reg_fields = omap3_dss_reg_fields, .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), - .has_feature= - FEAT_LCDENABLEPOL | - FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | - FEAT_FUNCGATED
[PATCH 2/2] OMAPDSS: DISPC: Fix scaling constraints for OMAP4
The calculation of required DISPC_FCLK for downscaling is done by multplying the pixel clock with an integer factor. This isn't true for OMAP4 where the required clock is calculated using the exact ratio of downscaling done. Fix this calculation for OMAP4. Also, do a minor clean up of calc_fclk(). Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/dispc.c | 12 1 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 3deb982..14b1f54 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1694,6 +1694,7 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width, u16 height, u16 out_width, u16 out_height) { unsigned int hf, vf; + unsigned long pclk = dispc_mgr_pclk_rate(channel); /* * FIXME how to determine the 'A' factor @@ -1716,13 +1717,16 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width, if (cpu_is_omap24xx()) { if (vf 1 hf 1) - return dispc_mgr_pclk_rate(channel) * 4; + return pclk * 4; else - return dispc_mgr_pclk_rate(channel) * 2; + return pclk * 2; } else if (cpu_is_omap34xx()) { - return dispc_mgr_pclk_rate(channel) * vf * hf; + return pclk * vf * hf; } else { - return dispc_mgr_pclk_rate(channel) * hf; + if (hf 1) + return DIV_ROUND_UP(pclk, out_width) * width; + else + return pclk; } } -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2] OMAP3: hwmod_data: register dss hwmods after dss_core
Hi, On Wednesday 28 December 2011 05:01 AM, Ilya Yanok wrote: dss_core has to be initialized before any other DSS hwmod. Currently this is broken as dss_core is listed in chip/revision specific hwmod lists while other DSS hwmods are listed in common list which is registered first. This patch moves DSS hwmods (except for dss_core) to the separate list which is registered last to ensure that dss_core is already registered. This solves the problem with BUG() in L3 interrupt handler on boards with DSS enabled in bootloader. CC: Tomi Valkeinentomi.valkei...@ti.com CC: Archit Tanejaarc...@ti.com CC: Paul Walmsleyp...@pwsan.com Signed-off-by: Ilya Yanokya...@emcraft.com --- Changes from V1: - Added extended comment arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 28 ++-- 1 files changed, 22 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 5324e8d..f263d3c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3523,12 +3523,6 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { omap3xxx_uart2_hwmod, omap3xxx_uart3_hwmod, - /* dss class */ - omap3xxx_dss_dispc_hwmod, - omap3xxx_dss_dsi1_hwmod, - omap3xxx_dss_rfbi_hwmod, - omap3xxx_dss_venc_hwmod, - /* i2c class */ omap3xxx_i2c1_hwmod, omap3xxx_i2c2_hwmod, @@ -3635,6 +3629,15 @@ static __initdata struct omap_hwmod *am35xx_hwmods[] = { NULL }; +static __initdata struct omap_hwmod *omap3xxx_dss_hwmods[] = { + /* dss class */ + omap3xxx_dss_dispc_hwmod, + omap3xxx_dss_dsi1_hwmod, + omap3xxx_dss_rfbi_hwmod, + omap3xxx_dss_venc_hwmod, + NULL +}; + int __init omap3xxx_hwmod_init(void) { int r; @@ -3708,6 +3711,19 @@ int __init omap3xxx_hwmod_init(void) if (h) r = omap_hwmod_register(h); + if (r 0) + return r; + + /* +* DSS code presumes that dss_core hwmod is handled first, +* _before_ any other DSS related hwmods so register common +* DSS hwmods last to ensure that dss_core is already registered. +* Otherwise some change things may happen, for ex. if dispc +* is handled before dss_core and DSS is enabled in bootloader +* DIPSC will be reset with outputs enabled which sometimes leads +* to unrecoverable L3 error. +*/ + r = omap_hwmod_register(omap3xxx_dss_hwmods); This looks fine, but it should be needed for other OMAP2 and OMAP4 also. If you could extend the patch we could test it out for the other OMAPs. Thanks, Archit return r; } -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 22/29] OMAPDSS: DISPC: Setup writeback go, enable and channel_in functions
Fill up dispc_wb_go(), dispc_wb_go_busy(), dispc_wb_enable() and dispc_wb_get_channel_in()/set_channel_in() with writeback register writes. Make a minor modification in dss_wb_write_regs_extra() to pass the plane_id instead of the writeback id when calling dispc_wb_set_channel_in(). Setup dispc_wb_enable() as dispc_enable_lcd_out() function and wait for the FRAMEDONEWB interrupt while disabling writeback. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/apply.c |2 +- drivers/video/omap2/dss/dispc.c | 68 +++ drivers/video/omap2/dss/dss.h |2 +- 3 files changed, 63 insertions(+), 9 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index dd1fd419..57b061f 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -690,7 +690,7 @@ static void dss_wb_write_regs_extra(struct omap_dss_writeback *wb) if (!wp-extra_info_dirty) return; - dispc_wb_set_channel_in(wb-id, wp-channel_in); + dispc_wb_set_channel_in(wb-plane_id, wp-channel_in); dispc_ovl_set_fifo_threshold(wb-plane_id, wp-fifo_low, wp-fifo_high); wp-extra_info_dirty = false; diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index c7de56d..cbce120 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -510,12 +510,26 @@ void dispc_mgr_go(enum omap_channel channel) bool dispc_wb_go_busy(int id) { - return false; + return REG_GET(DISPC_CONTROL2, 6, 6) == 1; } void dispc_wb_go(int id) { - return; + struct omap_dss_writeback *wb = omap_dss_get_writeback(id); + bool enable, go; + + enable = REG_GET(DISPC_OVL_ATTRIBUTES(wb-plane_id), 0, 0) == 1; + + if (!enable) + return; + + go = REG_GET(DISPC_CONTROL2, 6, 6) == 1; + if (go) { + DSSERR(GO bit not down for WB\n); + return; + } + + REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6); } static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value) @@ -903,16 +917,24 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane) return channel; } -void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in) +void dispc_wb_set_channel_in(int plane, enum dss_writeback_channel_in ch_in) { - return; + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), ch_in, 18, 16); } static enum omap_channel dispc_wb_get_channel_in(int plane) { - /* Return LCD channel for now */ + int channel_in = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 18, 16); - return OMAP_DSS_CHANNEL_LCD; + switch (channel_in) { + case OMAP_DSS_WB_LCD2_MGR: + return OMAP_DSS_CHANNEL_LCD2; + case OMAP_DSS_WB_TV_MGR: + return OMAP_DSS_CHANNEL_DIGIT; + case OMAP_DSS_WB_LCD1_MGR: + default: + return OMAP_DSS_CHANNEL_LCD; + }; } static void dispc_ovl_set_burst_size(enum omap_plane plane, @@ -2138,7 +2160,39 @@ void dispc_mgr_enable(enum omap_channel channel, bool enable) void dispc_wb_enable(int id, bool enable) { - return; + struct omap_dss_writeback *wb = omap_dss_get_writeback(id); + enum omap_plane plane = wb-plane_id; + struct completion frame_done_completion; + bool is_on; + int r; + u32 irq; + + is_on = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0); + irq = DISPC_IRQ_FRAMEDONEWB; + + if (!enable is_on) { + init_completion(frame_done_completion); + + r = omap_dispc_register_isr(dispc_disable_isr, + frame_done_completion, irq); + + if (r) + DSSERR(failed to register FRAMEDONEWB isr\n); + } + + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0); + + if (!enable is_on) { + if (!wait_for_completion_timeout(frame_done_completion, + msecs_to_jiffies(100))) + DSSERR(timeout waiting for FRAMEDONEWB\n); + + r = omap_dispc_unregister_isr(dispc_disable_isr, + frame_done_completion, irq); + + if (r) + DSSERR(failed to unregister FRAMEDONEWB isr\n); + } } void dispc_lcd_enable_signal_polarity(bool act_high) diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 69b4793..c05658b 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -498,7 +498,7 @@ void dispc_wb_go(int id); int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi, u16 in_width, u16 in_height); void dispc_wb_enable(int id, bool enable); -void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in); +void dispc_wb_set_channel_in(int plane, enum
[RFC PATCH 20/29] OMAPDSS: Writeback: Add writeback capabilities
Add a capabilities parameter of type omap_overlay_caps to omap_dss_writeback. These caps let us reuse some of the DISPC overlay functions. Set the capabilities so the writeback supports scaling and pre multiplied alpha. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/writeback.c |3 +++ include/video/omapdss.h |3 +++ 2 files changed, 6 insertions(+), 0 deletions(-) diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c index 540e61d..14103bf 100644 --- a/drivers/video/omap2/dss/writeback.c +++ b/drivers/video/omap2/dss/writeback.c @@ -90,6 +90,9 @@ void dss_init_writeback(void) wb-id = i; wb-plane_id = OMAP_DSS_WB + i; + wb-caps = OMAP_DSS_OVL_CAP_SCALE | + OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA; + wb-set_wb_info = dss_wb_set_info; wb-get_wb_info = dss_wb_get_info; } diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 49e3ccb..291457c 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -493,6 +493,9 @@ struct omap_dss_writeback { int id; int plane_id; + /* overlay-like capabilities writeback supports */ + enum omap_overlay_caps caps; + /* dummy panel we are connected to */ struct omap_dss_device *dssdev; -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support
DSS HW on OMAP4 supports a new pipeline called writeback. Unlike other pipelines(called overlays in DSS2 SW), writeback takes pixel data from an overlay output or a overlay manager output and writes it back into a specified address in memory. writeback allows us to take benefit of the hardware processing available inside the DISPC like color space conversion, rescaling, compositing etc and do either a) perform memory-to-memory transfer with data processing, b) capture a displayed frame. The former is known as memory to memory mode of the writeback pipeline, and the latter is known as capture mode. More details about writeback can be found in the Display Subsystem section of the OMAP4 TRM. In the current DSS2 design, there are 3 major entities: overlay(represents pipelines), overlay manager(represents a compositor of pipelines and the output going to a display) and a omap_dss_device(to represent a display). These entities can be linked to each other. One or more overlays can connect to a manager, and a manager connects to a display. Writeback HW has some properties of an overlay, and some of an overlay manager. But as far as DSS2 design is concerned, it best fits as a special panel. This panel connects to a manager and displays/writes the content back to memory after doing some optional data processing. The design adopted for writeback support in DSS2 is as follows: - Writeback exists as an entity of its own, this entity is used to configure and represent the actual writeback HW. - This entity doesn't connect itself directly to a manager, it connects to a manager via a dummy writeback panel. - The dummy writeback panel is just a place holder of the actual writeback entity. To do any writeback configuration, we extract the writeback pointer through the dummy writeback panel pointer. - In capture mode, an overlay manager needs to be connected to 2 outputs at the same time. The first output is the display device, and the second is the writeback panel. For this requirement, managers don't connect to a dss device, they now connect to an entity called output. This entity is just a container for 2 omap_dss_devices, one for display and one for writeback. With the design mentioned above. The three different ways writeback is used is explained: - capture mode: A manager is connected to both display and writeback dss_devices. - memory to memory mode(connected to a manager): A manager is connected to only the writeback dss_device. - memory to memory mode(connected to an overlay): A dummy writeback manager is connect to the writeback dss_device. This patch series only enables capture mode support, i.e., allowing us to write to the memory a processed version of the frame that we display onto a panel through an overlay manager. The memory to memory mode support will be extended later. In order to use writeback, we need a capture device driver of some sort, a v4l2 capture device is currently in the works. The patches are currently tested by extending writeback panel's sysfs attributes to allow us to configure the destination addresses and other parameters via sysfs. This can be tried out here: git://gitorious.org:~boddob/linux-omap-dss2/archit-dss2-clone.git wb-v1 The patches are based on the following tree: git://gitorious.org/linux-omap-dss2/linux.git master Tested on a OMAP4 based blaze tablet. Note that this isn't tested thoroughly for all possible writeback configurations, the aim is to get comments on the design. Archit Taneja (29): omapdss/omapfb/omap_vout: Introduce manager output struct OMAPDSS: Add writeback to omap_dss_mgr_output OMAPDSS: Writeback: Add writeback interface and panel driver OMAPDSS: APPLY/Writeback: Add writeback_info OMAPDSS: APPLY/Writeback: Apply writeback configurations OMAPDSS: APPLY: Add writeback enable/disable functions OMAPDSS: APPLY: Add extra_info for writeback OMAPDSS: APPLY: Modify manager unset device op OMAPDSS: APPLY: Allow manager set/unset_device ops to set/unset writeback OMAPDSS: APPLY: Calculate channel_in for writeback OMAPDSS: DISPC: Add writeback as a new plane OMAPDSS: Writeback: Add check for color_mode in dss_wb_simple_check() OMAPDSS: APPLY: Configure writeback FIFOs OMAPDSS: DISPC: Allow both upscaling and downscaling of chroma OMAPDSS: DISPC: Pass overlay caps as a parameter to dispc overlay related functions OMAPDSS: OVERLAY: Add position and replication as overlay caps OMAPDSS: DISPC: Make dispc_ovl_setup call dispc_plane_setup OMAPDSS: DISPC: Make chroma_upscale an argument to dispc_plane_setup OMAPDSS: DISPC: Don't set chroma resampling bit for writeback OMAPDSS: Writeback: Add writeback capabilities OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup OMAPDSS: DISPC: Setup writeback go, enable and channel_in functions OMAPDSS: Writeback: Configure writeback specific parameters OMAPDSS: Writeback: Use panel driver ops to configure mirroring rotation
[RFC PATCH 21/29] OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup
Call dispc_plane_setup() through dispc_wb_setup() to configure overlay-like parameters. Create a helper function in writeback.c called dss_wb_calc_params() which for now calculates the input width and height which goes to writeback. Create a dummy dispc function which returns the channel of the manager to which the writeback pipeline is connected. The parameters in dispc_plane_setup() which do not hold for writeback are filled passed as zeroes or false, dispc_plane_setup() takes care of not configuring them if the plane is writeback. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/apply.c |5 - drivers/video/omap2/dss/dispc.c | 33 +++-- drivers/video/omap2/dss/dss.h |6 +- drivers/video/omap2/dss/writeback.c | 17 + 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index a17cc47..dd1fd419 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -661,6 +661,7 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb) { struct wb_priv_data *wp = get_wb_priv(wb); struct omap_dss_writeback_info *wi; + u16 in_width, in_height; int r; if (!wp-enabled || !wp-info_dirty) @@ -670,7 +671,9 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb) wi = wp-info; - r = dispc_wb_setup(wb-id, wi); + dss_wb_calc_params(wb, wi, in_width, in_height); + + r = dispc_wb_setup(wb-id, wi, in_width, in_height); if (r) { DSSERR(dispc_wb_setup failed\n); return; diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 3a40f8e..c7de56d 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -908,6 +908,13 @@ void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in) return; } +static enum omap_channel dispc_wb_get_channel_in(int plane) +{ + /* Return LCD channel for now */ + + return OMAP_DSS_CHANNEL_LCD; +} + static void dispc_ovl_set_burst_size(enum omap_plane plane, enum omap_burst_size burst_size) { @@ -1935,9 +1942,31 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, return r; } -int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi) +int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi, + u16 in_width, u16 in_height) { - return 0; + int r; + struct omap_dss_writeback *wb = omap_dss_get_writeback(id); + const int pos_x = 0, pos_y = 0; + const u8 zorder = 0, global_alpha = 0; + const bool chroma_upscale = false, ilace = false, replication = false; + enum omap_channel channel; + + channel = dispc_wb_get_channel_in(wb-plane_id); + + DSSDBG(dispc_wb_setup %d, pa %x, pa_uv %x, %d,%d - %dx%d, cmode %x, + rot %d, mir %d, chan %d\n, + wb-id, wi-paddr, wi-p_uv_addr, in_width, in_height, + wi-buf_width, wi-buf_height, wi-color_mode, wi-rotation, + wi-mirror, channel); + + r = dispc_plane_setup(wb-plane_id, channel, wb-caps, wi-paddr, + wi-p_uv_addr, in_width, pos_x, pos_y, in_width, in_height, + wi-buf_width, wi-buf_height, wi-color_mode, wi-rotation, + wi-mirror, zorder, wi-pre_mult_alpha, global_alpha, + wi-rotation_type, chroma_upscale, ilace, replication); + + return r; } int dispc_ovl_enable(enum omap_plane plane, bool enable) diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 1b128f1..69b4793 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -249,6 +249,9 @@ void dss_init_writeback(void); void dss_uninit_writeback(void); int writeback_init_display(struct omap_dss_device *dssdev); enum dss_writeback_channel_in dss_wb_calc_channel_in(struct omap_dss_writeback *wb); +void dss_wb_calc_params(struct omap_dss_writeback *wb, + struct omap_dss_writeback_info *wi, u16 *in_width, + u16 *in_height); int dss_wb_simple_check(struct omap_dss_writeback *wb, const struct omap_dss_writeback_info *info); @@ -492,7 +495,8 @@ void dispc_mgr_setup(enum omap_channel channel, bool dispc_wb_go_busy(int id); void dispc_wb_go(int id); -int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi); +int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi, + u16 in_width, u16 in_height); void dispc_wb_enable(int id, bool enable); void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in); diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c index 14103bf..7c4e9c0 100644 --- a/drivers/video/omap2/dss/writeback.c +++ b/drivers/video/omap2/dss/writeback.c @@ -141,6 +141,23 @@ enum
[RFC PATCH 10/29] OMAPDSS: APPLY: Calculate channel_in for writeback
Add channel_in as a parameter in writeback's private data. This sets the extra_info_dirty flag as this parameter is configured when we set/unset the dummy writeback panel's manager unlike the other parameter which are configured through set/unset_wb_info ops by the DSS2 user. Add a helper function dss_mgr_set_writeback() which is called by the manager set/unset_device ops to configure the channel_in parameter and set the extra_info_dirty flags. It returns an error if we try to unset writeback when it is enabled. Add a dummy dispc_wb_set_channel_in() function. This will be filled up later. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/apply.c | 59 +- drivers/video/omap2/dss/dispc.c |5 +++ drivers/video/omap2/dss/dss.h | 12 +++ drivers/video/omap2/dss/writeback.c | 15 + 4 files changed, 82 insertions(+), 9 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index aee0420..9f3c174 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -114,6 +114,8 @@ struct wb_priv_data { bool extra_info_dirty; bool shadow_extra_info_dirty; + enum dss_writeback_channel_in channel_in; + /* If true, GO bit is up and shadow registers cannot be written. * Never true for writeback in memory to memory mode */ bool busy; @@ -137,6 +139,8 @@ static DEFINE_MUTEX(apply_lock); static DECLARE_COMPLETION(extra_updated_completion); static void dss_register_vsync_isr(void); +static int dss_mgr_set_writeback(struct omap_overlay_manager *mgr, + struct omap_dss_writeback *wb, bool set); static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl) { @@ -682,7 +686,7 @@ static void dss_wb_write_regs_extra(struct omap_dss_writeback *wb) if (!wp-extra_info_dirty) return; - /* Write extra registers here */ + dispc_wb_set_channel_in(wb-id, wp-channel_in); wp-extra_info_dirty = false; wp-shadow_extra_info_dirty = true; @@ -1282,6 +1286,7 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr, struct omap_dss_device *dssdev) { int r; + struct omap_dss_writeback *wb = dssdev-wbdev; mutex_lock(apply_lock); @@ -1301,10 +1306,13 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr, dssdev-manager = mgr; - if (dssdev-wbdev) - mgr-output-writeback = dssdev; - else + if (wb) { + r = dss_mgr_set_writeback(mgr, wb, true); + if (r) + goto err; + } else { mgr-output-device = dssdev; + } mutex_unlock(apply_lock); @@ -1319,11 +1327,11 @@ int dss_mgr_unset_device(struct omap_overlay_manager *mgr, { int r; struct omap_dss_device *curr_dssdev; + struct omap_dss_writeback *wb = dssdev-wbdev; mutex_lock(apply_lock); - curr_dssdev = dssdev-wbdev ? mgr-get_writeback(mgr) : - mgr-get_display(mgr); + curr_dssdev = wb ? mgr-get_writeback(mgr) : mgr-get_display(mgr); if (!curr_dssdev) { DSSERR(failed to unset device, device not set.\n); @@ -1342,10 +1350,13 @@ int dss_mgr_unset_device(struct omap_overlay_manager *mgr, curr_dssdev-manager = NULL; - if (dssdev-wbdev) - mgr-output-writeback = NULL; - else + if (wb) { + r = dss_mgr_set_writeback(mgr, wb, false); + if (r) + goto err; + } else { mgr-output-device = NULL; + } mutex_unlock(apply_lock); @@ -1593,6 +1604,36 @@ err: return r; } +static int dss_mgr_set_writeback(struct omap_overlay_manager *mgr, + struct omap_dss_writeback *wb, bool set) +{ + struct wb_priv_data *wp = get_wb_priv(wb); + unsigned long flags; + + spin_lock_irqsave(data_lock, flags); + + if (set) { + wp-channel_in = dss_wb_calc_channel_in(wb); + wp-extra_info_dirty = true; + mgr-output-writeback = wb-dssdev; + + } else { + if (wp-enabled) { + DSSERR(Failed to unset writeback%d from manager%d\n, + wb-id, mgr-id); + spin_unlock_irqrestore(data_lock, flags); + return -EINVAL; + } + + wp-channel_in = -1; + mgr-output-writeback = NULL; + } + + spin_unlock_irqrestore(data_lock, flags); + + return 0; +} + int dss_wb_set_info(struct omap_dss_writeback *wb, struct omap_dss_writeback_info *info) { diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 35ed6ca..a4d5504 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss
[RFC PATCH 28/29] OMAPDSS: MANAGER: Add writeback as a sysfs attribute
Add writeback as a sysfs attribute. This can be used to show and store the dummy writeback panel that the manager can connect to. Add checks so that in the store functions so that a display store cant set a writeback device and vice versa. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/manager.c | 38 + 1 files changed, 38 insertions(+), 0 deletions(-) diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index fb7c1e6..a064656 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -129,6 +129,41 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr, if (r) return r; + if (dssdev-wbdev) { + r = -EINVAL; + return r; + } + + r = dss_mgr_set_output(mgr, dssdev); + if (r) + return r; + + return size; +} + +static ssize_t manager_writeback_show(struct omap_overlay_manager *mgr, char *buf) +{ + struct omap_dss_device *wb_device = mgr-get_writeback(mgr); + + return snprintf(buf, PAGE_SIZE, %s\n, wb_device ? + wb_device-name : none); +} + +static ssize_t manager_writeback_store(struct omap_overlay_manager *mgr, + const char *buf, size_t size) +{ + int r; + struct omap_dss_device *dssdev; + + r = dss_find_device_buf(dssdev, buf, size); + if (r) + return r; + + if (!dssdev-wbdev) { + r = -EINVAL; + return r; + } + r = dss_mgr_set_output(mgr, dssdev); if (r) return r; @@ -452,6 +487,8 @@ struct manager_attribute { static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL); static MANAGER_ATTR(display, S_IRUGO|S_IWUSR, manager_display_show, manager_display_store); +static MANAGER_ATTR(writeback, S_IRUGO|S_IWUSR, + manager_writeback_show, manager_writeback_store); static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR, manager_default_color_show, manager_default_color_store); static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR, @@ -475,6 +512,7 @@ static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR, static struct attribute *manager_sysfs_attrs[] = { manager_attr_name.attr, manager_attr_display.attr, + manager_attr_writeback.attr, manager_attr_default_color.attr, manager_attr_trans_key_type.attr, manager_attr_trans_key_value.attr, -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 02/29] OMAPDSS: Add writeback to omap_dss_mgr_output
Add a omap_dss_device pointer in omap_dss_mgr_output to represent a writeback device. The writeback device is a dummy omap_dss_device pointer connected to the manager. It is a place holder for the actual writeback entity and is used for compatibility with the existing DSS2 code. Create helper overlay manager functions get_display() and get_writeback() which return mgr-output-device and mgr-output-writeback devices. Modify get_output() to return the display device if both device and writeback pointers are set. Otherwise, return the omap_dss_device pointer which is set. If writeback is in use, get_output() returns the display device if we are in capture mode, and it returns the writeback device if we are in memory to memory mode. This is beneficial as most checks/configurations for overlays and managers should be done on the basis of the manager's output display in capture mode, and the writeback device in case of memory to memory mode. get_display() should be used when we are interested specifically in the connected display, the same holds for get_writeback(). Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/manager.c | 19 +-- include/video/omapdss.h |3 +++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 094c96c..4962f7b 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -43,7 +43,7 @@ static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf) static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf) { - struct omap_dss_device *dssdev = mgr-get_output(mgr); + struct omap_dss_device *dssdev = mgr-get_display(mgr); return snprintf(buf, PAGE_SIZE, %s\n, dssdev ? dssdev-name : none); @@ -74,7 +74,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr, if (dssdev) DSSDBG(display %s found\n, dssdev-name); - if (mgr-get_output(mgr)) { + if (mgr-get_display(mgr)) { r = mgr-unset_device(mgr); if (r) { DSSERR(failed to unset display\n); @@ -494,9 +494,22 @@ static struct kobj_type manager_ktype = { static inline struct omap_dss_device *dss_mgr_get_output(struct omap_overlay_manager *mgr) { + if (mgr-output-device) + return mgr-output-device; + + return mgr-output-writeback; +} + +static inline struct omap_dss_device *dss_mgr_get_display(struct omap_overlay_manager *mgr) +{ return mgr-output-device; } +static inline struct omap_dss_device *dss_mgr_get_writeback(struct omap_overlay_manager *mgr) +{ + return mgr-output-writeback; +} + static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) { unsigned long timeout = msecs_to_jiffies(500); @@ -562,6 +575,8 @@ int dss_init_overlay_managers(struct platform_device *pdev) mgr-wait_for_vsync = dss_mgr_wait_for_vsync; mgr-get_output = dss_mgr_get_output; + mgr-get_display = dss_mgr_get_display; + mgr-get_writeback = dss_mgr_get_writeback; mgr-caps = 0; mgr-supported_displays = diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 1b968bb..93a1cd3 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -413,6 +413,7 @@ struct omap_overlay { struct omap_dss_mgr_output { struct omap_dss_device *device; + struct omap_dss_device *writeback; }; struct omap_overlay_manager_info { @@ -466,6 +467,8 @@ struct omap_overlay_manager { int (*wait_for_vsync)(struct omap_overlay_manager *mgr); struct omap_dss_device *(*get_output)(struct omap_overlay_manager *mgr); + struct omap_dss_device *(*get_display)(struct omap_overlay_manager *mgr); + struct omap_dss_device *(*get_writeback)(struct omap_overlay_manager *mgr); }; struct omap_dss_device { -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 01/29] omapdss/omapfb/omap_vout: Introduce manager output struct
Introduce struct omap_dss_mgr_output, this describes the output connected to the manager. This has been introduced as the output of a manager may not be just a a display device, it could be connected to writeback or both. The output struct will act as a container for 2 omap_dss_device pointers, one for the display attached, and one for the writeback panel if that manager is using writeback pipeline. The mode of operation(only displaying on a panel, writeback capture mode, writeback memory to memory mode) is configured within DSS2 based on how the user sets these outputs. The omap_dss_device pointer connected to a manager is accessed by a omap_overlay or a omap_overlay_manager pointer by references like manager-device and ovl-manager-device. Replace such accesses by creating a helper function get_output() in the overlay_manager struct. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c | 78 +- drivers/video/omap2/dss/apply.c | 73 +++ drivers/video/omap2/dss/dispc.c | 11 +++-- drivers/video/omap2/dss/manager.c| 29 +-- drivers/video/omap2/dss/overlay.c| 12 ++-- drivers/video/omap2/omapfb/omapfb-main.c |7 ++- drivers/video/omap2/omapfb/omapfb.h |5 +- include/video/omapdss.h |8 +++- 8 files changed, 158 insertions(+), 65 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 27c19fe..b9cdb1e 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -453,11 +453,16 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr) win = vout-win; for (i = 0; i ovid-num_overlays; i++) { + struct omap_dss_device *dssdev; + ovl = ovid-overlays[i]; - if (!ovl-manager || !ovl-manager-device) + dssdev = ovl-manager ? + ovl-manager-get_output(ovl-manager) : NULL; + + if (!dssdev) return -EINVAL; - timing = ovl-manager-device-panel.timings; + timing = dssdev-panel.timings; outw = win-w.width; outh = win-w.height; @@ -514,8 +519,12 @@ static int omapvid_apply_changes(struct omap_vout_device *vout) struct omapvideo_info *ovid = vout-vid_info; for (i = 0; i ovid-num_overlays; i++) { + struct omap_dss_device *dssdev; + ovl = ovid-overlays[i]; - if (!ovl-manager || !ovl-manager-device) + dssdev = ovl-manager ? + ovl-manager-get_output(ovl-manager) : NULL; + if (!dssdev) return -EINVAL; ovl-manager-apply(ovl-manager); } @@ -539,10 +548,11 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) ovid = vout-vid_info; ovl = ovid-overlays[0]; /* get the display device attached to the overlay */ - if (!ovl-manager || !ovl-manager-device) - return; + cur_display = ovl-manager ? + ovl-manager-get_output(ovl-manager) : NULL; - cur_display = ovl-manager-device; + if (!cur_display) + return; spin_lock(vout-vbq_lock); do_gettimeofday(timevalue); @@ -942,7 +952,10 @@ static int omap_vout_release(struct file *file) /* Disable all the overlay managers connected with this interface */ for (i = 0; i ovid-num_overlays; i++) { struct omap_overlay *ovl = ovid-overlays[i]; - if (ovl-manager ovl-manager-device) + struct omap_dss_device *dssdev = ovl-manager ? + ovl-manager-get_output(ovl-manager) : NULL; + + if (dssdev) ovl-disable(ovl); } /* Turn off the pipeline */ @@ -1074,14 +1087,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh, struct omapvideo_info *ovid; struct omap_video_timings *timing; struct omap_vout_device *vout = fh; + struct omap_dss_device *dssdev; ovid = vout-vid_info; ovl = ovid-overlays[0]; + /* get the display device attached to the overlay */ + dssdev = ovl-manager ? ovl-manager-get_output(ovl-manager) : NULL; - if (!ovl-manager || !ovl-manager-device) + if (!dssdev) return -EINVAL; - /* get the display device attached to the overlay */ - timing = ovl-manager-device-panel.timings; + + timing = dssdev-panel.timings; vout-fbuf.fmt.height = timing-y_res; vout-fbuf.fmt.width = timing-x_res; @@ -1098,6 +1114,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh, struct omapvideo_info *ovid; struct omap_video_timings *timing; struct omap_vout_device *vout = fh
[RFC PATCH 11/29] OMAPDSS: DISPC: Add writeback as a new plane
Since writeback has many overlay like properties, and most of it's registers are similar to that of overlays, it's possible to reuse most of the overlay related DISPC code for writeback if it is added as a plane. Add OMAP_DSS_WB as new plane in the omap_plane struct. Add the writeback register offsets in dispc.h, add minimal WB plane related info needed in dss_features. Add a new omap_dss_writeback parameter called plane_id, this represents the plane or pipeline number out of all the pipelines. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/dispc.h| 36 drivers/video/omap2/dss/dss_features.c | 10 drivers/video/omap2/dss/writeback.c|1 + include/video/omapdss.h|2 + 4 files changed, 49 insertions(+), 0 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h index 5836bd1..7f69a51 100644 --- a/drivers/video/omap2/dss/dispc.h +++ b/drivers/video/omap2/dss/dispc.h @@ -304,6 +304,8 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane) return 0x014C; case OMAP_DSS_VIDEO3: return 0x0300; + case OMAP_DSS_WB: + return 0x0500; default: BUG(); } @@ -318,6 +320,7 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0008; default: BUG(); @@ -332,6 +335,7 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0004; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x000C; default: BUG(); @@ -349,6 +353,8 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane) return 0x04BC; case OMAP_DSS_VIDEO3: return 0x0310; + case OMAP_DSS_WB: + return 0x0118; default: BUG(); } @@ -365,6 +371,8 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane) return 0x04C0; case OMAP_DSS_VIDEO3: return 0x0314; + case OMAP_DSS_WB: + return 0x011C; default: BUG(); } @@ -392,6 +400,7 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x000C; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x00A8; default: BUG(); @@ -407,6 +416,7 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0010; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0070; default: BUG(); @@ -424,6 +434,8 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane) return 0x04DC; case OMAP_DSS_VIDEO3: return 0x032C; + case OMAP_DSS_WB: + return 0x0310; default: BUG(); } @@ -438,6 +450,7 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0014; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x008C; default: BUG(); @@ -453,6 +466,7 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0018; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0088; default: BUG(); @@ -468,6 +482,7 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x001C; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x00A4; default: BUG(); @@ -483,6 +498,7 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0020; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0098; default: BUG(); @@ -526,6 +542,7 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0024; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0090; default: BUG(); @@ -543,6 +560,8 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane) return 0x055C; case OMAP_DSS_VIDEO3: return 0x0424; + case OMAP_DSS_WB: + return 0x290; default: BUG(); } @@ -557,6 +576,7 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0028; case
[RFC PATCH 07/29] OMAPDSS: APPLY: Add extra_info for writeback
Like overlays, writeback pipeline has a a FIFO and a channel which shouldn't be configured along with the other info struct. Introduce flags extra_info dirty and shadow_dirty flags. Configure them like done for overlays. No extra parameters have been added for now. They will be added on later. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/apply.c | 48 ++- 1 files changed, 47 insertions(+), 1 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 5263ae7..ff0baeb 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -111,6 +111,9 @@ struct wb_priv_data { bool shadow_info_dirty; + bool extra_info_dirty; + bool shadow_extra_info_dirty; + /* If true, GO bit is up and shadow registers cannot be written. * Never true for writeback in memory to memory mode */ bool busy; @@ -335,6 +338,12 @@ static bool need_isr(void) if (wp-shadow_info_dirty) return true; + if (wp-extra_info_dirty) + return true; + + if (wp-shadow_extra_info_dirty) + return true; + } } } @@ -368,7 +377,7 @@ static bool need_wb_go(struct omap_dss_writeback *wb) wp = get_wb_priv(wb); - if (wp-shadow_info_dirty) + if (wp-shadow_info_dirty || wp-shadow_extra_info_dirty) return true; return false; @@ -378,6 +387,7 @@ static bool need_wb_go(struct omap_dss_writeback *wb) static bool extra_info_update_ongoing(void) { const int num_ovls = omap_dss_get_num_overlays(); + const int num_wb = dss_feat_get_num_wb(); struct ovl_priv_data *op; struct omap_overlay *ovl; struct mgr_priv_data *mp; @@ -402,6 +412,27 @@ static bool extra_info_update_ongoing(void) return true; } + for (i = 0; i num_wb; ++i) { + struct omap_dss_writeback *wb; + struct wb_priv_data *wp; + + wb = omap_dss_get_writeback(i); + wp = get_wb_priv(wb); + mp = get_mgr_priv(wb-dssdev-manager); + + if (!mp-enabled) + continue; + + if (!mp-updating) + continue; + + if (!wp-enabled) + continue; + + if (wp-extra_info_dirty || wp-shadow_extra_info_dirty) + return true; + } + return false; } @@ -644,6 +675,19 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb) wp-shadow_info_dirty = true; } +static void dss_wb_write_regs_extra(struct omap_dss_writeback *wb) +{ + struct wb_priv_data *wp = get_wb_priv(wb); + + if (!wp-extra_info_dirty) + return; + + /* Write extra registers here */ + + wp-extra_info_dirty = false; + wp-shadow_extra_info_dirty = true; +} + static void dss_mgr_write_regs(struct omap_overlay_manager *mgr) { struct mgr_priv_data *mp = get_mgr_priv(mgr); @@ -716,6 +760,7 @@ static void dss_write_regs(void) continue; dss_wb_write_regs(wb); + dss_wb_write_regs_extra(wb); } } @@ -867,6 +912,7 @@ static void wb_clear_shadow_dirty(struct omap_dss_writeback *wb) wp = get_wb_priv(wb); wp-shadow_info_dirty = false; + wp-shadow_extra_info_dirty = false; } static void dss_apply_irq_handler(void *data, u32 mask) -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 27/29] OMAPDSS: MANAGER: Split manager_display_store into smaller functions
Split manager_display_store() into two function, the first function finds a device with the same name. The second unsets the current output attached and sets the one we had searched for. This is done so that there can be re use between display store and writeback store sysfs ops. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/manager.c | 46 ++-- 1 files changed, 38 insertions(+), 8 deletions(-) diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index f4fd3d8..fb7c1e6 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -49,13 +49,11 @@ static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf) dssdev-name : none); } -static ssize_t manager_display_store(struct omap_overlay_manager *mgr, +static int dss_find_device_buf(struct omap_dss_device **pdssdev, const char *buf, size_t size) { - int r = 0; size_t len = size; struct omap_dss_device *dssdev = NULL; - struct omap_dss_device *curr_display; int match(struct omap_dss_device *dssdev, void *data) { @@ -73,12 +71,25 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr, return -EINVAL; if (dssdev) - DSSDBG(display %s found\n, dssdev-name); + DSSDBG(device %s found\n, dssdev-name); + + *pdssdev = dssdev; + + return 0; +} +static int dss_mgr_set_output(struct omap_overlay_manager *mgr, + struct omap_dss_device *dssdev) +{ + int r; + struct omap_dss_device *curr_dssdev; - curr_display = mgr-get_display(mgr); + if (dssdev-wbdev) + curr_dssdev = mgr-get_writeback(mgr); + else + curr_dssdev = mgr-get_display(mgr); - if (curr_display) { - r = mgr-unset_device(mgr, curr_display); + if (curr_dssdev) { + r = mgr-unset_device(mgr, curr_dssdev); if (r) { DSSERR(failed to unset display\n); goto put_device; @@ -99,11 +110,30 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr, } } + return 0; + put_device: if (dssdev) omap_dss_put_device(dssdev); - return r ? r : size; + return r; +} + +static ssize_t manager_display_store(struct omap_overlay_manager *mgr, + const char *buf, size_t size) +{ + int r; + struct omap_dss_device *dssdev; + + r = dss_find_device_buf(dssdev, buf, size); + if (r) + return r; + + r = dss_mgr_set_output(mgr, dssdev); + if (r) + return r; + + return size; } static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr, -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 24/29] OMAPDSS: Writeback: Use panel driver ops to configure mirroring rotation and buffer size
Add rotation and mirroring ops to writeback panel driver. Use these ops to get/set wb info. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/writeback.c | 79 +++ 1 files changed, 79 insertions(+), 0 deletions(-) diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c index 82d601c..215958e 100644 --- a/drivers/video/omap2/dss/writeback.c +++ b/drivers/video/omap2/dss/writeback.c @@ -287,9 +287,83 @@ static int writeback_panel_resume(struct omap_dss_device *dssdev) return 0; } +static int writeback_panel_rotate(struct omap_dss_device *dssdev, u8 rotate) +{ + int r; + struct omap_dss_writeback *wb = dssdev-wbdev; + struct omap_dss_writeback_info info; + + wb-get_wb_info(wb, info); + + info.rotation = rotate; + + r = wb-set_wb_info(wb, info); + if (r) { + dev_err(dssdev-dev, failed to set rotation %d\n, rotate); + return -EINVAL; + } + + return 0; +} + +static u8 writeback_panel_get_rotate(struct omap_dss_device *dssdev) +{ + struct omap_dss_writeback *wb = dssdev-wbdev; + struct omap_dss_writeback_info info; + + wb-get_wb_info(wb, info); + + return info.rotation; +} + +static int writeback_panel_mirror(struct omap_dss_device *dssdev, bool mirror) +{ + int r; + struct omap_dss_writeback *wb = dssdev-wbdev; + struct omap_dss_writeback_info info; + + wb-get_wb_info(wb, info); + + info.mirror = mirror; + + r = wb-set_wb_info(wb, info); + if (r) { + dev_err(dssdev-dev, failed to set mirror %d\n, mirror); + return -EINVAL; + } + + return 0; +} + +static bool writeback_panel_get_mirror(struct omap_dss_device *dssdev) +{ + struct omap_dss_writeback *wb = dssdev-wbdev; + struct omap_dss_writeback_info info; + + wb-get_wb_info(wb, info); + + return info.mirror; +} + static void writeback_panel_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { + int r; + struct omap_dss_writeback *wb = dssdev-wbdev; + struct omap_dss_writeback_info info; + + wb-get_wb_info(wb, info); + + info.buf_width = timings-x_res; + info.buf_height = timings-y_res; + + r = wb-set_wb_info(wb, info); + if (r) { + dev_err(dssdev-dev, failed to set timings %d, %d\n, + timings-x_res, timings-y_res); + return; + } + dssdev-panel.timings.x_res = timings-x_res; dssdev-panel.timings.y_res = timings-y_res; } @@ -315,6 +389,11 @@ static struct omap_dss_driver writeback_panel_driver = { .suspend = writeback_panel_suspend, .resume = writeback_panel_resume, + .set_rotate = writeback_panel_rotate, + .get_rotate = writeback_panel_get_rotate, + .set_mirror = writeback_panel_mirror, + .get_mirror = writeback_panel_get_mirror, + .set_timings = writeback_panel_set_timings, .get_timings = writeback_panel_get_timings, .check_timings = writeback_panel_check_timings, -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 06/29] OMAPDSS: APPLY: Add writeback enable/disable functions
In writeback capture mode, enabling writeback is similar to enabling an overlay manager. It leads to an immediate copy of shadow registers to main registers and starts DISPC DMA for frame transfer to the destination base addresses. Hence, 'enabled' parameter for writeback is not a part of the writeback_info struct. Its is maintained as a separate parameter like it's done for an overlay manager. Add dss_wb_enable/disable functions. Since we need to be connected to an enabled manager when enabling writeback. Add checks to ensure that the connected manager is enabled, add a check in dss_mgr_disable to issue a warning if writeback is in use. Call dss_setup_fifos() in dss_wb_enable(), this would be used to configure writeback FIFOs in the future. Create a dummy dispc_wb_enable() function which will be later filled up. Call dss_mgr_enable/disable through the dummy writeback panel's enable/disable ops. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/apply.c | 92 +- drivers/video/omap2/dss/dispc.c |5 ++ drivers/video/omap2/dss/dss.h |3 + drivers/video/omap2/dss/writeback.c | 12 - 4 files changed, 108 insertions(+), 4 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index f40f58c..5263ae7 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -114,6 +114,9 @@ struct wb_priv_data { /* If true, GO bit is up and shadow registers cannot be written. * Never true for writeback in memory to memory mode */ bool busy; + + /* If true, someone is using writeback */ + bool enabled; }; static struct { @@ -320,6 +323,9 @@ static bool need_isr(void) struct omap_dss_writeback *wb = dssdev-wbdev; struct wb_priv_data *wp = get_wb_priv(wb); + if (!wp-enabled) + continue; + if (wp-busy) return true; @@ -621,7 +627,7 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb) struct omap_dss_writeback_info *wi; int r; - if (!wp-info_dirty) + if (!wp-enabled || !wp-info_dirty) return; WARN_ON(wp-busy); @@ -703,7 +709,7 @@ static void dss_write_regs(void) wp = get_wb_priv(wb); mp = get_mgr_priv(wb-dssdev-manager); - if (!mp-enabled) + if (!mp-enabled || !wp-enabled) continue; if (wp-busy) @@ -752,7 +758,7 @@ static void dss_set_go_bits(void) if (!mp-enabled) continue; - if (wp-busy) + if (!wp-enabled || wp-busy) continue; if (!need_wb_go(wb)) @@ -1163,6 +1169,7 @@ err: void dss_mgr_disable(struct omap_overlay_manager *mgr) { struct mgr_priv_data *mp = get_mgr_priv(mgr); + struct omap_dss_device *dssdev = mgr-get_writeback(mgr); unsigned long flags; mutex_lock(apply_lock); @@ -1170,6 +1177,13 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) if (!mp-enabled) goto out; + if (dssdev) { + /* if writeback is connected to the manager, issue a warning +* if it is enabled */ + struct wb_priv_data *wp = get_wb_priv(dssdev-wbdev); + WARN_ON(wp-enabled); + } + if (!mgr_manual_update(mgr)) dispc_mgr_enable(mgr-id, false); @@ -1556,3 +1570,75 @@ void dss_wb_get_info(struct omap_dss_writeback *wb, spin_unlock_irqrestore(data_lock, flags); } + +int dss_wb_enable(struct omap_dss_writeback *wb) +{ + struct wb_priv_data *wp = get_wb_priv(wb); + struct mgr_priv_data *mp; + unsigned long flags; + int r = 0; + + mutex_lock(apply_lock); + + /* don't enable if it isn't connected to any manager */ + if (!wb-dssdev-manager) { + r = -EINVAL; + goto out; + } + + mp = get_mgr_priv(wb-dssdev-manager); + + /* don't enable if the manager WB is connected to is disabled */ + if (!mp-enabled) { + r = -EINVAL; + goto out; + } + + if (wp-enabled) + goto out; + + /* use a simple check for now */ + r = dss_wb_simple_check(wb, wp-info); + if (r) + goto out; + + spin_lock_irqsave(data_lock, flags); + + wp-enabled = true; + + dss_setup_fifos(); + + dss_write_regs(); + dss_set_go_bits(); + + spin_unlock_irqrestore(data_lock, flags); + + dispc_wb_enable(wb-id, true); + +out: + mutex_unlock(apply_lock); + + return r; +} + +void dss_wb_disable(struct omap_dss_writeback *wb) +{ + struct
[RFC PATCH 29/29] OMAPDSS: FEATURES: Allow WB panels to attach to managers
Add WB panel type in supported displays for all managers of OMAP4. A manager can now use set/unset ops on the dummy writeback panel. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/dss_features.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index 9478ed8..dbde3b9 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -132,14 +132,16 @@ static const enum omap_display_type omap3630_dss_supported_displays[] = { static const enum omap_display_type omap4_dss_supported_displays[] = { /* OMAP_DSS_CHANNEL_LCD */ - OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI, + OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI | + OMAP_DISPLAY_TYPE_WB, /* OMAP_DSS_CHANNEL_DIGIT */ OMAP_DISPLAY_TYPE_VENC | OMAP_DISPLAY_TYPE_HDMI, + OMAP_DISPLAY_TYPE_WB, /* OMAP_DSS_CHANNEL_LCD2 */ OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | - OMAP_DISPLAY_TYPE_DSI, + OMAP_DISPLAY_TYPE_DSI | OMAP_DISPLAY_TYPE_WB, }; static const enum omap_color_mode omap2_dss_supported_color_modes[] = { -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 26/29] OMAPDSS: DISPLAY: Add a manager apply to sysfs store attributes for writeback
Writeback driver ops don't apply the writeback attribute changes, they just set the writeback info parameters. Add manager apply calls in sysfs store ops for timings, rotation and mirroring when its the writeback panel. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/display.c | 18 ++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 03d7fb0..71ef0d7 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -144,6 +144,12 @@ static ssize_t display_timings_store(struct device *dev, dssdev-driver-set_timings(dssdev, t); + if (dssdev-wbdev dssdev-manager) { + r = dssdev-manager-apply(dssdev-manager); + if (r) + return r; + } + return size; } @@ -175,6 +181,12 @@ static ssize_t display_rotate_store(struct device *dev, if (r) return r; + if (dssdev-wbdev dssdev-manager) { + r = dssdev-manager-apply(dssdev-manager); + if (r) + return r; + } + return size; } @@ -207,6 +219,12 @@ static ssize_t display_mirror_store(struct device *dev, if (r) return r; + if (dssdev-wbdev dssdev-manager) { + r = dssdev-manager-apply(dssdev-manager); + if (r) + return r; + } + return size; } -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 19/29] OMAPDSS: DISPC: Don't set chroma resampling bit for writeback
The bit YUVCHROMARESAMPLING isn't there for writeback in DISPC_WB_ATTRIBUTES2. Ignore this bit in dispc_ovl_set_scaling_uv() if the plane is OMAP_DSS_WB. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/dispc.c |9 ++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 21d6286..3a40f8e 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1238,7 +1238,8 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, color_mode != OMAP_DSS_COLOR_UYVY color_mode != OMAP_DSS_COLOR_NV12)) { /* reset chroma resampling for RGB formats */ - REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8); + if (plane != OMAP_DSS_WB) + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8); return; } switch (color_mode) { @@ -1277,8 +1278,10 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, out_width, out_height, five_taps, rotation, DISPC_COLOR_COMPONENT_UV); - REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), - (scale_x || scale_y) ? 1 : 0, 8, 8); + if (plane != OMAP_DSS_WB) + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), + (scale_x || scale_y) ? 1 : 0, 8, 8); + /* set H scaling */ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5); /* set V scaling */ -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 17/29] OMAPDSS: DISPC: Make dispc_ovl_setup call dispc_plane_setup
Add a new static function called dispc_plane_setup(). This function is used by dispc_ovl_setup() to configure the overlay registers. This split is done so that dispc_wb_setup() can reuse the common overlay related registers configured in dispc_plane_setup(). Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/dispc.c | 126 ++- 1 files changed, 71 insertions(+), 55 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 58de7d7..eca6157 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1783,63 +1783,54 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, return 0; } -int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, +static int dispc_plane_setup(enum omap_plane plane, enum omap_channel channel, + enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr, + u16 screen_width, int pos_x, int pos_y, u16 width, u16 height, + u16 out_width, u16 out_height, enum omap_color_mode color_mode, + u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha, + u8 global_alpha, enum omap_dss_rotation_type rotation_type, bool ilace, bool replication) { - struct omap_overlay *ovl = omap_dss_get_overlay(plane); - enum omap_overlay_caps caps = ovl-caps; bool five_taps = true; bool fieldmode = 0; int r, cconv = 0; unsigned offset0, offset1; s32 row_inc; s32 pix_inc; - u16 frame_height = oi-height; + u16 frame_height = height; unsigned int field_offset = 0; u16 outw, outh; - enum omap_channel channel; - - channel = dispc_ovl_get_channel_out(plane); - DSSDBG(dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d - - %dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n, - plane, 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, ilace, channel, replication); - - if (oi-paddr == 0) + if (paddr == 0) return -EINVAL; - outw = oi-out_width == 0 ? oi-width : oi-out_width; - outh = oi-out_height == 0 ? oi-height : oi-out_height; + outw = out_width == 0 ? width : out_width; + outh = out_height == 0 ? height : out_height; - if (ilace oi-height == outh) + if (ilace height == outh) fieldmode = 1; if (ilace) { if (fieldmode) - oi-height /= 2; - oi-pos_y /= 2; + height /= 2; + pos_y /= 2; outh /= 2; DSSDBG(adjusting for ilace: height %d, pos_y %d, - out_height %d\n, - oi-height, oi-pos_y, outh); + out_height %d\n, height, pos_y, outh); } - if (!dss_feat_color_mode_supported(plane, oi-color_mode)) + if (!dss_feat_color_mode_supported(plane, color_mode)) return -EINVAL; - r = dispc_ovl_calc_scaling(plane, channel, caps, oi-width, oi-height, - outw, outh, oi-color_mode, - five_taps); + r = dispc_ovl_calc_scaling(plane, channel, caps, width, height, + outw, outh, color_mode, five_taps); if (r) return r; - if (oi-color_mode == OMAP_DSS_COLOR_YUV2 || - oi-color_mode == OMAP_DSS_COLOR_UYVY || - oi-color_mode == OMAP_DSS_COLOR_NV12) + if (color_mode == OMAP_DSS_COLOR_YUV2 || + color_mode == OMAP_DSS_COLOR_UYVY || + color_mode == OMAP_DSS_COLOR_NV12) cconv = 1; if (ilace !fieldmode) { @@ -1850,72 +1841,97 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, * so the integer part must be added to the base address of the * bottom field. */ - if (!oi-height || oi-height == outh) + if (!height || height == outh) field_offset = 0; else - field_offset = oi-height / outh / 2; + field_offset = height / outh / 2; } /* Fields are independent but interleaved in memory. */ if (fieldmode) field_offset = 1; - if (oi-rotation_type == OMAP_DSS_ROT_DMA) - calc_dma_rotation_offset(oi-rotation, oi-mirror, - oi-screen_width, oi-width, frame_height, - oi-color_mode, fieldmode, field_offset, + if (rotation_type == OMAP_DSS_ROT_DMA
[RFC PATCH 09/29] OMAPDSS: APPLY: Allow manager set/unset_device ops to set/unset writeback
Allow dss_mgr_set_device/unset_device to set/unset either display or writeback based on the dssdev argument passed to the function. Check if the device is a writeback device by seeing if the wbdev pointer is populated for it or not. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/apply.c | 15 --- 1 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 4624f86..aee0420 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -1300,7 +1300,11 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr, } dssdev-manager = mgr; - mgr-output-device = dssdev; + + if (dssdev-wbdev) + mgr-output-writeback = dssdev; + else + mgr-output-device = dssdev; mutex_unlock(apply_lock); @@ -1318,7 +1322,8 @@ int dss_mgr_unset_device(struct omap_overlay_manager *mgr, mutex_lock(apply_lock); - curr_dssdev = mgr-output-device; + curr_dssdev = dssdev-wbdev ? mgr-get_writeback(mgr) : + mgr-get_display(mgr); if (!curr_dssdev) { DSSERR(failed to unset device, device not set.\n); @@ -1336,7 +1341,11 @@ int dss_mgr_unset_device(struct omap_overlay_manager *mgr, } curr_dssdev-manager = NULL; - mgr-output-device = NULL; + + if (dssdev-wbdev) + mgr-output-writeback = NULL; + else + mgr-output-device = NULL; mutex_unlock(apply_lock); -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 04/29] OMAPDSS: APPLY/Writeback: Add writeback_info
Create a struct called omap_dss_writeback_info. This contains 'overlay like' parameters of the writeback pipeline. These parameters are expected to be configured via get/set_info ops by the DSS2 user similar to how overlay and manager parameters are configured. These will also be configurable via sysfs attributes of the dummy writeback panel. Add get_wb_info/set_wb_info ops in omap_dss_writeback struct. Create a minimal wb_priv_data structure and a writeback simple_check function used for dss_wb_get_info and dss_wb_set_info functions in apply.c Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/apply.c| 45 drivers/video/omap2/dss/dss.h |7 + drivers/video/omap2/dss/dss_features.h |1 + drivers/video/omap2/dss/writeback.c| 27 +++ include/video/omapdss.h| 18 5 files changed, 98 insertions(+), 0 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index d529664..19120c1 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -101,9 +101,16 @@ struct mgr_priv_data { bool enabled; }; +struct wb_priv_data { + + bool user_info_dirty; + struct omap_dss_writeback_info user_info; +}; + static struct { struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; + struct wb_priv_data wb_priv_data_array[MAX_DSS_WB]; bool irq_enabled; } dss_data; @@ -126,6 +133,11 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr) return dss_data.mgr_priv_data_array[mgr-id]; } +static struct wb_priv_data *get_wb_priv(struct omap_dss_writeback *wb) +{ + return dss_data.wb_priv_data_array[wb-id]; +} + void dss_apply_init(void) { const int num_ovls = dss_feat_get_num_ovls(); @@ -1351,3 +1363,36 @@ err: return r; } +int dss_wb_set_info(struct omap_dss_writeback *wb, + struct omap_dss_writeback_info *info) +{ + struct wb_priv_data *wp = get_wb_priv(wb); + unsigned long flags; + int r; + + r = dss_wb_simple_check(wb, info); + if (r) + return r; + + spin_lock_irqsave(data_lock, flags); + + wp-user_info = *info; + wp-user_info_dirty = true; + + spin_unlock_irqrestore(data_lock, flags); + + return 0; +} + +void dss_wb_get_info(struct omap_dss_writeback *wb, + struct omap_dss_writeback_info *info) +{ + struct wb_priv_data *wp = get_wb_priv(wb); + unsigned long flags; + + spin_lock_irqsave(data_lock, flags); + + *info = wp-user_info; + + spin_unlock_irqrestore(data_lock, flags); +} diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 607e730..9b3b93c 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -191,6 +191,11 @@ int dss_ovl_set_manager(struct omap_overlay *ovl, struct omap_overlay_manager *mgr); int dss_ovl_unset_manager(struct omap_overlay *ovl); +int dss_wb_set_info(struct omap_dss_writeback *wb, + struct omap_dss_writeback_info *info); +void dss_wb_get_info(struct omap_dss_writeback *wb, + struct omap_dss_writeback_info *info); + /* display */ int dss_suspend_all_devices(void); int dss_resume_all_devices(void); @@ -230,6 +235,8 @@ int dss_ovl_check(struct omap_overlay *ovl, void dss_init_writeback(void); void dss_uninit_writeback(void); int writeback_init_display(struct omap_dss_device *dssdev); +int dss_wb_simple_check(struct omap_dss_writeback *wb, + const struct omap_dss_writeback_info *info); /* DSS */ int dss_init_platform_driver(void); diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index 75ee1f1..b3486da 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -28,6 +28,7 @@ #define MAX_DSS_OVERLAYS 4 #define MAX_DSS_LCD_MANAGERS 2 #define MAX_NUM_DSI2 +#define MAX_DSS_WB 1 /* DSS has feature id */ enum dss_feat_id { diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c index ac5d3ba..5e54221 100644 --- a/drivers/video/omap2/dss/writeback.c +++ b/drivers/video/omap2/dss/writeback.c @@ -78,6 +78,9 @@ void dss_init_writeback(void) struct omap_dss_writeback *wb = writeback[i]; wb-id = i; + + wb-set_wb_info = dss_wb_set_info; + wb-get_wb_info = dss_wb_get_info; } omap_dss_register_driver(writeback_panel_driver); @@ -109,6 +112,30 @@ int writeback_init_display(struct omap_dss_device *dssdev) return 0; } +int dss_wb_simple_check(struct omap_dss_writeback *wb, + const struct omap_dss_writeback_info *info) +{ + if (info
[RFC PATCH 25/29] OMAPDSS: Writeback: Add sysfs attributes to writeback panel
Add the following sysfs attributes to the writeback panel driver: - paddr - p_uv_addr - rotation_type - color_mode - pre_mult_alpha - capture_rate Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/writeback.c | 210 +++ 1 files changed, 210 insertions(+), 0 deletions(-) diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c index 215958e..c6450e7 100644 --- a/drivers/video/omap2/dss/writeback.c +++ b/drivers/video/omap2/dss/writeback.c @@ -214,8 +214,218 @@ int dss_wb_simple_check(struct omap_dss_writeback *wb, /* Dummy Writeback Panel driver */ +static ssize_t writeback_panel_paddr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_writeback_info info; + struct omap_dss_device *dssdev = to_dss_device(dev); + struct omap_dss_writeback *wb = dssdev-wbdev; + + wb-get_wb_info(wb, info); + + return snprintf(buf, PAGE_SIZE, %x\n, info.paddr); +} + +static ssize_t writeback_panel_p_uv_addr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_writeback_info info; + struct omap_dss_device *dssdev = to_dss_device(dev); + struct omap_dss_writeback *wb = dssdev-wbdev; + + wb-get_wb_info(wb, info); + + return snprintf(buf, PAGE_SIZE, %x\n, info.p_uv_addr); +} + +static ssize_t writeback_panel_rotation_type_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_writeback_info info; + struct omap_dss_device *dssdev = to_dss_device(dev); + struct omap_dss_writeback *wb = dssdev-wbdev; + + wb-get_wb_info(wb, info); + + return snprintf(buf, PAGE_SIZE, %d\n, info.rotation_type); +} + +static ssize_t writeback_panel_color_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_writeback_info info; + struct omap_dss_device *dssdev = to_dss_device(dev); + struct omap_dss_writeback *wb = dssdev-wbdev; + + wb-get_wb_info(wb, info); + + return snprintf(buf, PAGE_SIZE, %d\n, info.color_mode); +} + +static ssize_t writeback_panel_color_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t size) +{ + int r; + int color_mode; + struct omap_dss_writeback_info info; + struct omap_dss_device *dssdev = to_dss_device(dev); + struct omap_dss_writeback *wb = dssdev-wbdev; + + r = kstrtoint(buf, 0, color_mode); + if (r) + return r; + + wb-get_wb_info(wb, info); + + info.color_mode = color_mode; + + r = wb-set_wb_info(wb, info); + if (r) { + dev_err(dssdev-dev, failed to set color mode %d\n, + color_mode); + return r; + } + + if (dssdev-manager) { + r = dssdev-manager-apply(dssdev-manager); + if (r) + return r; + } + + return size; +} + +static ssize_t writeback_panel_pre_mult_alpha_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_writeback_info info; + struct omap_dss_device *dssdev = to_dss_device(dev); + struct omap_dss_writeback *wb = dssdev-wbdev; + + wb-get_wb_info(wb, info); + + return snprintf(buf, PAGE_SIZE, %d\n, info.pre_mult_alpha); +} + +static ssize_t writeback_panel_pre_mult_alpha_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t size) +{ + int r; + u8 pre_mult_alpha; + struct omap_dss_writeback_info info; + struct omap_dss_device *dssdev = to_dss_device(dev); + struct omap_dss_writeback *wb = dssdev-wbdev; + + r = kstrtou8(buf, 0, pre_mult_alpha); + if (r) + return r; + + wb-get_wb_info(wb, info); + + info.pre_mult_alpha = pre_mult_alpha; + + r = wb-set_wb_info(wb, info); + if (r) { + dev_err(dssdev-dev, failed to set pre_mult_alpha %d\n, + pre_mult_alpha); + return r; + } + + if (dssdev-manager) { + r = dssdev-manager-apply(dssdev-manager); + if (r) + return r; + } + + return size; +} + +static ssize_t writeback_panel_capture_rate_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_writeback_info info; + struct omap_dss_device *dssdev = to_dss_device(dev); + struct omap_dss_writeback *wb = dssdev-wbdev; + + wb-get_wb_info(wb, info); + + return snprintf(buf, PAGE_SIZE, %d\n, info.capture_rate); +} + +static ssize_t writeback_panel_capture_rate_store(struct device *dev, + struct device_attribute *attr, const
[RFC PATCH 14/29] OMAPDSS: DISPC: Allow both upscaling and downscaling of chroma
Make the function dispc_ovl_set_scaling_uv() take a boolean argument which tells if we want to upscale or downscale the chroma plane. Downscaling of chroma is required by writeback pipeline for converting the input YUV444 color format to YUV422 or NV12. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/dispc.c | 17 ++--- 1 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 231369a..dfbb39b 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1219,7 +1219,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, u16 out_width, u16 out_height, bool ilace, bool five_taps, bool fieldmode, enum omap_color_mode color_mode, - u8 rotation) + u8 rotation, bool chroma_upscale) { int scale_x = out_width != orig_width; int scale_y = out_height != orig_height; @@ -1236,9 +1236,11 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, switch (color_mode) { case OMAP_DSS_COLOR_NV12: /* UV is subsampled by 2 vertically*/ - orig_height = 1; + orig_height = chroma_upscale ? + orig_height 1 : orig_height 1; /* UV is subsampled by 2 horz.*/ - orig_width = 1; + orig_width = chroma_upscale ? + orig_width 1 : orig_width 1; break; case OMAP_DSS_COLOR_YUV2: case OMAP_DSS_COLOR_UYVY: @@ -1248,7 +1250,8 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, if (rotation == OMAP_DSS_ROT_0 || rotation == OMAP_DSS_ROT_180) /* UV is subsampled by 2 hrz*/ - orig_width = 1; + orig_width = chroma_upscale ? + orig_width 1 : orig_width 1; /* must use FIR for YUV422 if rotated */ if (rotation != OMAP_DSS_ROT_0) scale_x = scale_y = true; @@ -1282,7 +1285,7 @@ static void dispc_ovl_set_scaling(enum omap_plane plane, u16 out_width, u16 out_height, bool ilace, bool five_taps, bool fieldmode, enum omap_color_mode color_mode, - u8 rotation) + u8 rotation, bool chroma_upscale) { BUG_ON(plane == OMAP_DSS_GFX); @@ -1298,7 +1301,7 @@ static void dispc_ovl_set_scaling(enum omap_plane plane, out_width, out_height, ilace, five_taps, fieldmode, color_mode, - rotation); + rotation, chroma_upscale); } static void dispc_ovl_set_rotation_attrs(enum omap_plane plane, u8 rotation, @@ -1888,7 +1891,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, dispc_ovl_set_scaling(plane, oi-width, oi-height, outw, outh, ilace, five_taps, fieldmode, - oi-color_mode, oi-rotation); + oi-color_mode, oi-rotation, true); dispc_ovl_set_vid_size(plane, outw, outh); dispc_ovl_set_vid_color_conv(plane, cconv); } -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 23/29] OMAPDSS: Writeback: Configure writeback specific parameters
Calculate writeback specific parameters capture mode, truncation and delay count in dss_wb_calc_params(). The writeback parameters calculated are: truncation: This is needs to be set if the color depth input to writeback is more than the color depth of the color mode we want to store in memory. writeback mode: This configures whether we want to use writeback in mem to mem or capture mode. A helper function called wb_manual_update() is created, it returns true if we are in mem to mem mode. It will be used later again when mem to mem support is added. delay_count: This specifies the time(in lines) when the HW flushes writeback FIFOs and takes in new register configurations after the VSYNC is generated by the manager to which writeback is connected. Pass these parameters to dispc_wb_setup() so that they can be written in writeback registers. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/apply.c | 15 +-- drivers/video/omap2/dss/dispc.c | 28 +--- drivers/video/omap2/dss/dss.h |5 +++-- drivers/video/omap2/dss/writeback.c | 31 +++ 4 files changed, 64 insertions(+), 15 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 57b061f..b941d95 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -208,6 +208,13 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr) return dssdev-caps OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; } +static bool wb_manual_update(struct omap_dss_writeback *wb) +{ + struct omap_overlay_manager *mgr = wb-dssdev-manager; + + return mgr-get_display(mgr) ? false : true; +} + static int dss_check_settings_low(struct omap_overlay_manager *mgr, struct omap_dss_device *dssdev, bool applying) { @@ -662,6 +669,8 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb) struct wb_priv_data *wp = get_wb_priv(wb); struct omap_dss_writeback_info *wi; u16 in_width, in_height; + bool truncation; + int delay_count; int r; if (!wp-enabled || !wp-info_dirty) @@ -671,9 +680,11 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb) wi = wp-info; - dss_wb_calc_params(wb, wi, in_width, in_height); + dss_wb_calc_params(wb, wi, in_width, in_height, truncation, + delay_count); - r = dispc_wb_setup(wb-id, wi, in_width, in_height); + r = dispc_wb_setup(wb-id, wi, in_width, in_height, + wb_manual_update(wb), truncation, delay_count); if (r) { DSSERR(dispc_wb_setup failed\n); return; diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index cbce120..73ba7cd 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1965,29 +1965,43 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, } int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi, - u16 in_width, u16 in_height) + u16 in_width, u16 in_height, bool mem_to_mem_mode, + bool truncation, int delay_count) { int r; struct omap_dss_writeback *wb = omap_dss_get_writeback(id); + enum omap_plane plane = wb-plane_id; const int pos_x = 0, pos_y = 0; const u8 zorder = 0, global_alpha = 0; const bool chroma_upscale = false, ilace = false, replication = false; enum omap_channel channel; + u32 l; - channel = dispc_wb_get_channel_in(wb-plane_id); + channel = dispc_wb_get_channel_in(plane); DSSDBG(dispc_wb_setup %d, pa %x, pa_uv %x, %d,%d - %dx%d, cmode %x, - rot %d, mir %d, chan %d\n, - wb-id, wi-paddr, wi-p_uv_addr, in_width, in_height, - wi-buf_width, wi-buf_height, wi-color_mode, wi-rotation, - wi-mirror, channel); + rot %d, mir %d, chan %d, wb_mode %d, trunc %d, + delay_count %d\n, wb-id, wi-paddr, wi-p_uv_addr, in_width, + in_height, wi-buf_width, wi-buf_height, wi-color_mode, + wi-rotation, wi-mirror, channel, mem_to_mem_mode, truncation, + delay_count); - r = dispc_plane_setup(wb-plane_id, channel, wb-caps, wi-paddr, + r = dispc_plane_setup(plane, channel, wb-caps, wi-paddr, wi-p_uv_addr, in_width, pos_x, pos_y, in_width, in_height, wi-buf_width, wi-buf_height, wi-color_mode, wi-rotation, wi-mirror, zorder, wi-pre_mult_alpha, global_alpha, wi-rotation_type, chroma_upscale, ilace, replication); + /* setup extra DISPC_WB_ATTRIBUTES */ + l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); + l = FLD_MOD(l, truncation, 10, 10); /* TRUNCATIONENABLE */ + l = FLD_MOD(l, mem_to_mem_mode, 19, 19
[RFC PATCH 15/29] OMAPDSS: DISPC: Pass overlay caps as a parameter to DISPC overlay related functions
Currently, the functions below take the omap_plane parameter and derive the overlay caps within them. Pass the overlay caps as a parameter to the function to allow writeback functions to use them too. - dispc_ovl_set_zorder() - dispc_ovl_set_pre_mult_alpha() - dispc_ovl_setup_global_alpha() - dispc_ovl_calc_scaling() - dispc_ovl_setup() These functions will be used for writeback later, and the caps will help in deciding if they are to be used for writeback or not. This allows reuse of overlay caps for writeback. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/dispc.c | 38 ++ 1 files changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index dfbb39b..d9e04f0 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -684,11 +684,10 @@ static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height) dispc_write_reg(DISPC_OVL_SIZE(plane), val); } -static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder) +static void dispc_ovl_set_zorder(enum omap_plane plane, + enum omap_overlay_caps caps, u8 zorder) { - struct omap_overlay *ovl = omap_dss_get_overlay(plane); - - if ((ovl-caps OMAP_DSS_OVL_CAP_ZORDER) == 0) + if ((caps OMAP_DSS_OVL_CAP_ZORDER) == 0) return; REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26); @@ -705,23 +704,22 @@ static void dispc_ovl_enable_zorder_planes(void) REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25); } -static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable) +static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, + enum omap_overlay_caps caps, bool enable) { - struct omap_overlay *ovl = omap_dss_get_overlay(plane); - - if ((ovl-caps OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0) + if ((caps OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0) return; REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28); } -static void dispc_ovl_setup_global_alpha(enum omap_plane plane, u8 global_alpha) +static void dispc_ovl_setup_global_alpha(enum omap_plane plane, + enum omap_overlay_caps caps, u8 global_alpha) { static const unsigned shifts[] = { 0, 8, 16, 24, }; int shift; - struct omap_overlay *ovl = omap_dss_get_overlay(plane); - if ((ovl-caps OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) + if ((caps OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) return; shift = shifts[plane]; @@ -1704,11 +1702,10 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width, } static int dispc_ovl_calc_scaling(enum omap_plane plane, - enum omap_channel channel, u16 width, u16 height, - u16 out_width, u16 out_height, + enum omap_channel channel, enum omap_overlay_caps caps, + u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool *five_taps) { - struct omap_overlay *ovl = omap_dss_get_overlay(plane); const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); const int maxsinglelinewidth = dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); @@ -1717,7 +1714,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, if (width == out_width height == out_height) return 0; - if ((ovl-caps OMAP_DSS_OVL_CAP_SCALE) == 0) + if ((caps OMAP_DSS_OVL_CAP_SCALE) == 0) return -EINVAL; if (out_width width / maxdownscale || @@ -1780,6 +1777,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, bool ilace, bool replication) { struct omap_overlay *ovl = omap_dss_get_overlay(plane); + enum omap_overlay_caps caps = ovl-caps; bool five_taps = true; bool fieldmode = 0; int r, cconv = 0; @@ -1823,7 +1821,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, if (!dss_feat_color_mode_supported(plane, oi-color_mode)) return -EINVAL; - r = dispc_ovl_calc_scaling(plane, channel, oi-width, oi-height, + r = dispc_ovl_calc_scaling(plane, channel, caps, oi-width, oi-height, outw, outh, oi-color_mode, five_taps); if (r) @@ -1887,7 +1885,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, dispc_ovl_set_pic_size(plane, oi-width, oi-height); - if (ovl-caps OMAP_DSS_OVL_CAP_SCALE) { + if (caps OMAP_DSS_OVL_CAP_SCALE) { dispc_ovl_set_scaling(plane, oi-width, oi-height, outw, outh, ilace, five_taps, fieldmode, @@ -1899,9 +1897,9 @@ int
[RFC PATCH 08/29] OMAPDSS: APPLY: Modify manager unset device op
Modify manager's unset_device op so that it can be used to unset any one of the devices connected to the overlay manager output. The unset_device function now takes a pointer to omap_dss_device struct which needs to be unset. The function ignores it for now, but since there can be two devices connected to a manager now, it will be used later to unset either the display or writeback device. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/apply.c |3 ++- drivers/video/omap2/dss/display.c |2 +- drivers/video/omap2/dss/dss.h |3 ++- drivers/video/omap2/dss/manager.c |7 +-- drivers/video/omap2/dss/overlay.c |9 ++--- include/video/omapdss.h |3 ++- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index ff0baeb..4624f86 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -1310,7 +1310,8 @@ err: return r; } -int dss_mgr_unset_device(struct omap_overlay_manager *mgr) +int dss_mgr_unset_device(struct omap_overlay_manager *mgr, + struct omap_dss_device *dssdev) { int r; struct omap_dss_device *curr_dssdev; diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index a712bad..03d7fb0 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -432,7 +432,7 @@ void dss_uninit_device(struct platform_device *pdev, device_remove_file(dssdev-dev, attr); if (dssdev-manager) - dssdev-manager-unset_device(dssdev-manager); + dssdev-manager-unset_device(dssdev-manager, dssdev); } static int dss_suspend_device(struct device *dev, void *data) diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index bb25d96..b4b60fc 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -178,7 +178,8 @@ 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_unset_device(struct omap_overlay_manager *mgr, + struct omap_dss_device *dssdev); bool dss_ovl_is_enabled(struct omap_overlay *ovl); int dss_ovl_enable(struct omap_overlay *ovl); diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 4962f7b..f4fd3d8 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -55,6 +55,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr, int r = 0; size_t len = size; struct omap_dss_device *dssdev = NULL; + struct omap_dss_device *curr_display; int match(struct omap_dss_device *dssdev, void *data) { @@ -74,8 +75,10 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr, if (dssdev) DSSDBG(display %s found\n, dssdev-name); - if (mgr-get_display(mgr)) { - r = mgr-unset_device(mgr); + curr_display = mgr-get_display(mgr); + + if (curr_display) { + r = mgr-unset_device(mgr, curr_display); if (r) { DSSERR(failed to unset display\n); goto put_device; diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index c72275e..dc0cc52 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -538,7 +538,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) if (dssdev-channel == OMAP_DSS_CHANNEL_LCD2) { if (!lcd2_mgr-output-device || force) { if (lcd2_mgr-output-device) - lcd2_mgr-unset_device(lcd2_mgr); + lcd2_mgr-unset_device(lcd2_mgr, + lcd2_mgr-output-device); lcd2_mgr-set_device(lcd2_mgr, dssdev); mgr = lcd2_mgr; } @@ -546,7 +547,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) dssdev-type != OMAP_DISPLAY_TYPE_HDMI) { if (!lcd_mgr-output-device || force) { if (lcd_mgr-output-device) - lcd_mgr-unset_device(lcd_mgr); + lcd_mgr-unset_device(lcd_mgr, + lcd_mgr-output-device); lcd_mgr-set_device(lcd_mgr, dssdev); mgr = lcd_mgr; } @@ -556,7 +558,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) || dssdev-type == OMAP_DISPLAY_TYPE_HDMI
[RFC PATCH 13/29] OMAPDSS: APPLY: Configure writeback FIFOs
Add writeback FIFO thresholds as extra_info parameters. Modify function dss_ovl_fifo_setup() so that it can also also configure writeback pipeline FIFOs. Extend the DISPC fifo functions to also configure the writeback registers. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/apply.c | 70 +- drivers/video/omap2/dss/dispc.c |8 +++-- 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 9f3c174..a17cc47 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -115,6 +115,7 @@ struct wb_priv_data { bool shadow_extra_info_dirty; enum dss_writeback_channel_in channel_in; + u32 fifo_low, fifo_high; /* If true, GO bit is up and shadow registers cannot be written. * Never true for writeback in memory to memory mode */ @@ -687,6 +688,7 @@ static void dss_wb_write_regs_extra(struct omap_dss_writeback *wb) return; dispc_wb_set_channel_in(wb-id, wp-channel_in); + dispc_ovl_set_fifo_threshold(wb-plane_id, wp-fifo_low, wp-fifo_high); wp-extra_info_dirty = false; wp-shadow_extra_info_dirty = true; @@ -1102,21 +1104,59 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl, op-extra_info_dirty = true; } -static void dss_ovl_setup_fifo(struct omap_overlay *ovl) +static void dss_apply_wb_fifo_thresholds(struct omap_dss_writeback *wb, + u32 fifo_low, u32 fifo_high) { - struct ovl_priv_data *op = get_ovl_priv(ovl); + struct wb_priv_data *wp = get_wb_priv(wb); + + if (wp-fifo_low == fifo_low wp-fifo_high == fifo_high) + return; + + wp-fifo_low = fifo_low; + wp-fifo_high = fifo_high; + wp-extra_info_dirty = true; +} + +static void dss_plane_setup_fifo(struct omap_overlay *ovl, + struct omap_dss_writeback *wb) +{ + enum omap_plane plane; + struct omap_overlay_manager *mgr; struct omap_dss_device *dssdev; + bool enabled, enabling; u32 size, burst_size; u32 fifo_low, fifo_high; - if (!op-enabled !op-enabling) + if (ovl) { + struct ovl_priv_data *op; + + mgr = ovl-manager; + op = get_ovl_priv(ovl); + + enabled = op-enabled; + enabling = op-enabling; + + plane = ovl-id; + } else { + struct wb_priv_data *wp; + + mgr = wb-dssdev-manager; + wp = get_wb_priv(wb); + + enabled = wp-enabled; + enabling = false; + + plane = wb-plane_id; + } + + if (!enabled !enabling) return; - dssdev = ovl-manager-get_output(ovl-manager); + dssdev = mgr-get_output(mgr); - size = dispc_ovl_get_fifo_size(ovl-id); + size = dispc_ovl_get_fifo_size(plane); - burst_size = dispc_ovl_get_burst_size(ovl-id); + burst_size = dispc_ovl_get_burst_size(plane); switch (dssdev-type) { case OMAP_DISPLAY_TYPE_DPI: @@ -1124,12 +1164,12 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl) case OMAP_DISPLAY_TYPE_SDI: case OMAP_DISPLAY_TYPE_VENC: case OMAP_DISPLAY_TYPE_HDMI: - default_get_overlay_fifo_thresholds(ovl-id, size, + default_get_overlay_fifo_thresholds(plane, size, burst_size, fifo_low, fifo_high); break; #ifdef CONFIG_OMAP2_DSS_DSI case OMAP_DISPLAY_TYPE_DSI: - dsi_get_overlay_fifo_thresholds(ovl-id, size, + dsi_get_overlay_fifo_thresholds(plane, size, burst_size, fifo_low, fifo_high); break; #endif @@ -1137,13 +1177,17 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl) BUG(); } - dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); + if (ovl) + dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); + else + dss_apply_wb_fifo_thresholds(wb, fifo_low, fifo_high); } static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) { struct omap_overlay *ovl; struct mgr_priv_data *mp; + struct omap_dss_device *dssdev; mp = get_mgr_priv(mgr); @@ -1151,7 +1195,13 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) return; list_for_each_entry(ovl, mgr-overlays, list) - dss_ovl_setup_fifo(ovl); + dss_plane_setup_fifo(ovl, NULL); + + dssdev = mgr-get_writeback(mgr); + if (dssdev) { + struct omap_dss_writeback *wb = dssdev-wbdev; + dss_plane_setup_fifo(NULL, wb); + } } static void dss_setup_fifos(void) diff --git a/drivers/video/omap2/dss/dispc.c b
[RFC PATCH 03/29] OMAPDSS: Writeback: Add writeback interface and panel driver
Create a new struct called omap_dss_writeback. This will represent a writeback pipeline the way omap_overlay and omap_overlay_manager represent overlay and managers respectively. Create a writeback interface and a dummy writeback panel driver. The writeback panel driver is needed for the omap_dss_device pointer which represents writeback in omap_dss_mgr_output. Add a omap_dss_device pointer to the omap_dss_writeback struct, and a omap_dss_writeback pointer in omap_dss_device struct, link the writeback and dss_device together when the latter is added. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/Makefile |2 +- drivers/video/omap2/dss/core.c |2 + drivers/video/omap2/dss/display.c |3 + drivers/video/omap2/dss/dss.h |5 + drivers/video/omap2/dss/dss_features.c |8 + drivers/video/omap2/dss/dss_features.h |1 + drivers/video/omap2/dss/writeback.c| 223 include/video/omapdss.h| 13 ++ 8 files changed, 256 insertions(+), 1 deletions(-) create mode 100644 drivers/video/omap2/dss/writeback.c diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile index 5c450b0..51c544e 100644 --- a/drivers/video/omap2/dss/Makefile +++ b/drivers/video/omap2/dss/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_OMAP2_DSS) += omapdss.o omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ - manager.o overlay.o apply.o + manager.o overlay.o apply.o writeback.o omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 5c46430..21bfd0a 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -182,6 +182,7 @@ static int omap_dss_probe(struct platform_device *pdev) dss_init_overlay_managers(pdev); dss_init_overlays(pdev); + dss_init_writeback(); r = dss_init_platform_driver(); if (r) { @@ -276,6 +277,7 @@ static int omap_dss_remove(struct platform_device *pdev) dispc_uninit_platform_driver(); dss_uninit_platform_driver(); + dss_uninit_writeback(); dss_uninit_overlays(pdev); dss_uninit_overlay_managers(pdev); diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index be331dc..a712bad 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -391,6 +391,9 @@ void dss_init_device(struct platform_device *pdev, case OMAP_DISPLAY_TYPE_HDMI: r = hdmi_init_display(dssdev); break; + case OMAP_DISPLAY_TYPE_WB: + r = writeback_init_display(dssdev); + break; default: DSSERR(Support for display '%s' not compiled in.\n, dssdev-name); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 3cf99a9..607e730 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -226,6 +226,11 @@ int dss_ovl_simple_check(struct omap_overlay *ovl, int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, struct omap_dss_device *dssdev); +/* writeback */ +void dss_init_writeback(void); +void dss_uninit_writeback(void); +int writeback_init_display(struct omap_dss_device *dssdev); + /* DSS */ int dss_init_platform_driver(void); void dss_uninit_platform_driver(void); diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index 5e4b829..ca41620 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -45,6 +45,7 @@ struct omap_dss_features { const int num_mgrs; const int num_ovls; + const int num_wb; const enum omap_display_type *supported_displays; const enum omap_color_mode *supported_color_modes; const enum omap_overlay_caps *overlay_caps; @@ -423,6 +424,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = { .num_mgrs = 3, .num_ovls = 4, + .num_wb = 1, .supported_displays = omap4_dss_supported_displays, .supported_color_modes = omap4_dss_supported_color_modes, .overlay_caps = omap4_dss_overlay_caps, @@ -447,6 +449,7 @@ static const struct omap_dss_features omap4_dss_features = { .num_mgrs = 3, .num_ovls = 4, + .num_wb = 1, .supported_displays = omap4_dss_supported_displays, .supported_color_modes = omap4_dss_supported_color_modes, .overlay_caps = omap4_dss_overlay_caps, @@ -493,6 +496,11 @@ int dss_feat_get_num_ovls(void) return omap_current_dss_features-num_ovls; } +int dss_feat_get_num_wb(void) +{ + return omap_current_dss_features-num_wb; +} + unsigned long dss_feat_get_param_min
[RFC PATCH 05/29] OMAPDSS: APPLY/Writeback: Apply writeback configurations
The writeback pipeline has properties of both overlays and overlay managers. It is like an overlay as it has programmable base addresses and contains blocks like scalar, color conversion unit, truncation unit, DISPC DMA FIFO. It is like a manager as enabling it immediately starts transfer to the memory, and it has a GO bit to use a new writeback configuration. Hence, writeback is a separate entity when it comes to applying configurations. When it comes to applying user_info to the private info maintained by DSS2, the writeback pipeline can be considered tightly coupled with the manager it is connected to. This makes sense as in the current DSS2 design as writeback is always connected to a manager in all its modes. In capture mode, writeback is connected to the manager from which we are capturing the frames. In memory to memory mode, we would either connected to a manager if we are capturing the manager's output, or we would connect to a dummy writeback manager when we are capturing data from just one overlay.Calling a manager's apply() calls omap_dss_mgr_apply_wb(), which copies the user_info to the private info struct only if that manager has writeback connected to it. Hence, copying user_info to private info for writeback is similar to how it is done for overlays. Unlike overlays, writeback configurations can't be totally governed by the state of the manager. In capture mode, writeback registers are governed by the GO bit of WB. Hence, a new configuration can be written to writeback shadow registers even if the manager it is connected to is busy. Hence, copying of private info to shadow register and setting GO bit for writeback is similar to how it is done for managers. We register to dss_apply_irq_handler() if writeback needs to write a pending configuration or clear the busy and shadow_dirty status if the previous configuration was transferred from the shadow registers successfully. This isn't optimal for capture mode as a new/pending writeback configuration is applied sometime later than the connected manager's VSYNC interrupt. The new configuration is taken only after WBDELAYCOUNT lines(in time) are generated by the manager after the VSYNC interrupt. Since we don't have any interrupt to get this event. We currently register to the manager's VSYNC interrupt itself. The correct approach would be to generate a timer based interrupt event after approximately WBDELAYCOUNT lines after we get the VSYNC interrupts. This is not done for now. Create dummy dispc_wb_go/go_busy and wb_setup functions. These will be filled up in a later commit. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/apply.c | 164 ++- drivers/video/omap2/dss/dispc.c | 15 drivers/video/omap2/dss/dss.h |4 + 3 files changed, 181 insertions(+), 2 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 19120c1..f40f58c 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -105,6 +105,15 @@ struct wb_priv_data { bool user_info_dirty; struct omap_dss_writeback_info user_info; + + bool info_dirty; + struct omap_dss_writeback_info info; + + bool shadow_info_dirty; + + /* If true, GO bit is up and shadow registers cannot be written. +* Never true for writeback in memory to memory mode */ + bool busy; }; static struct { @@ -250,6 +259,7 @@ static bool need_isr(void) struct omap_overlay_manager *mgr; struct mgr_priv_data *mp; struct omap_overlay *ovl; + struct omap_dss_device *dssdev; mgr = omap_dss_get_overlay_manager(i); mp = get_mgr_priv(mgr); @@ -304,13 +314,29 @@ static bool need_isr(void) if (op-shadow_info_dirty) return true; } + + dssdev = mgr-get_writeback(mgr); + if (dssdev) { + struct omap_dss_writeback *wb = dssdev-wbdev; + struct wb_priv_data *wp = get_wb_priv(wb); + + if (wp-busy) + return true; + + if (wp-info_dirty) + return true; + + if (wp-shadow_info_dirty) + return true; + + } } } return false; } -static bool need_go(struct omap_overlay_manager *mgr) +static bool need_mgr_go(struct omap_overlay_manager *mgr) { struct omap_overlay *ovl; struct mgr_priv_data *mp; @@ -330,6 +356,18 @@ static bool need_go(struct omap_overlay_manager *mgr) return false; } +static bool need_wb_go(struct omap_dss_writeback *wb) +{ + struct wb_priv_data *wp
[RFC PATCH 16/29] OMAPDSS: OVERLAY: Add position and replication as overlay caps
Add position and replication as overlay caps. Pass overlay caps as an argument to the corresponding functions. These caps will be set for all overlays, but not for writeback. This is done so writeback can reuse dispc_ovl_setup() to the maximum. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/dispc.c | 20 +++- drivers/video/omap2/dss/overlay.c |6 ++ include/video/omapdss.h |2 ++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index d9e04f0..58de7d7 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -656,9 +656,15 @@ static void dispc_ovl_set_ba1_uv(enum omap_plane plane, u32 paddr) dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr); } -static void dispc_ovl_set_pos(enum omap_plane plane, int x, int y) +static void dispc_ovl_set_pos(enum omap_plane plane, + enum omap_overlay_caps caps, int x, int y) { - u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0); + u32 val; + + if ((caps OMAP_DSS_OVL_CAP_POS) == 0) + return; + + val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0); dispc_write_reg(DISPC_OVL_POSITION(plane), val); } @@ -988,11 +994,15 @@ static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable) dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); } -static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable) +static void dispc_ovl_enable_replication(enum omap_plane plane, + enum omap_overlay_caps caps, bool enable) { static const unsigned shifts[] = { 5, 10, 10, 10 }; int shift; + if ((caps OMAP_DSS_OVL_CAP_REPLICATION) == 0) + return; + shift = shifts[plane]; REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift); } @@ -1881,7 +1891,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, DSSDBG(%d,%d %dx%d - %dx%d\n, oi-pos_x, oi-pos_y, oi-width, oi-height, outw, outh); - dispc_ovl_set_pos(plane, oi-pos_x, oi-pos_y); + dispc_ovl_set_pos(plane, caps, oi-pos_x, oi-pos_y); dispc_ovl_set_pic_size(plane, oi-width, oi-height); @@ -1901,7 +1911,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, dispc_ovl_set_pre_mult_alpha(plane, caps, oi-pre_mult_alpha); dispc_ovl_setup_global_alpha(plane, caps, oi-global_alpha); - dispc_ovl_enable_replication(plane, replication); + dispc_ovl_enable_replication(plane, caps, replication); return 0; } diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index dc0cc52..cb548c0 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -509,6 +509,12 @@ void dss_init_overlays(struct platform_device *pdev) ovl-wait_for_go = dss_mgr_wait_for_go_ovl; ovl-caps = dss_feat_get_overlay_caps(ovl-id); + + /* these caps are common to all ovelays across all OMAPs, they +* are used to differentiate between an overlay and writeback */ + ovl-caps |= OMAP_DSS_OVL_CAP_POS | + OMAP_DSS_OVL_CAP_REPLICATION; + ovl-supported_modes = dss_feat_get_supported_color_modes(ovl-id); diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 6bf84b2..49e3ccb 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -185,6 +185,8 @@ enum omap_overlay_caps { OMAP_DSS_OVL_CAP_GLOBAL_ALPHA = 1 1, OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA = 1 2, OMAP_DSS_OVL_CAP_ZORDER = 1 3, + OMAP_DSS_OVL_CAP_POS = 1 4, + OMAP_DSS_OVL_CAP_REPLICATION = 1 5, }; enum omap_overlay_manager_caps { -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 18/29] OMAPDSS: DISPC: Make chroma_upscale an argument to dispc_plane_setup
Pass chroma_upscale boolean parameter to dispc_plane_setup(), this will be set to true when dispc_plane_setup() is called from dispc_ovl_setup() and false when called from dispc_wb_setup(). Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/dispc.c | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index eca6157..21d6286 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1789,7 +1789,7 @@ static int dispc_plane_setup(enum omap_plane plane, enum omap_channel channel, u16 out_width, u16 out_height, enum omap_color_mode color_mode, u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha, u8 global_alpha, enum omap_dss_rotation_type rotation_type, - bool ilace, bool replication) + bool chroma_upscale, bool ilace, bool replication) { bool five_taps = true; bool fieldmode = 0; @@ -1887,10 +1887,9 @@ static int dispc_plane_setup(enum omap_plane plane, enum omap_channel channel, dispc_ovl_set_pic_size(plane, width, height); if (caps OMAP_DSS_OVL_CAP_SCALE) { - dispc_ovl_set_scaling(plane, width, height, - outw, outh, - ilace, five_taps, fieldmode, - color_mode, rotation, true); + dispc_ovl_set_scaling(plane, width, height, outw, outh, + ilace, five_taps, fieldmode, color_mode, + rotation, chroma_upscale); dispc_ovl_set_vid_size(plane, outw, outh); dispc_ovl_set_vid_color_conv(plane, cconv); } @@ -1911,6 +1910,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, { int r; struct omap_overlay *ovl = omap_dss_get_overlay(plane); + const bool chroma_upscale = true; enum omap_channel channel; channel = dispc_ovl_get_channel_out(plane); @@ -1927,7 +1927,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, 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, oi-rotation_type, - ilace, replication); + chroma_upscale, ilace, replication); return r; } -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 12/29] OMAPDSS: Writeback: Add check for color_mode in dss_wb_simple_check()
Add a check for the color_mode parameter provided by the user in dss_wb_simple_check(). Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/writeback.c |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c index 8b2c9b8..540e61d 100644 --- a/drivers/video/omap2/dss/writeback.c +++ b/drivers/video/omap2/dss/writeback.c @@ -153,6 +153,13 @@ int dss_wb_simple_check(struct omap_dss_writeback *wb, return -EINVAL; } + if ((dss_feat_get_supported_color_modes(wb-plane_id) + info-color_mode) == 0) { + DSSERR(wb_simple_check: wb%d doesn't support mode %d\n, + wb-id, info-color_mode); + return -EINVAL; + } + if (info-capture_rate 0 || info-capture_rate 7) { DSSERR(wb_simple_check: capture rate cannot be %d\n, info-capture_rate); -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Interesting L3 driver panic on v3.2-rc5 on 3530
Hi Ilya, On Tuesday 20 December 2011 06:09 AM, Ilya Yanok wrote: Hi Paul, Paul Walmsleypaulat pwsan.com writes: [0.238494] Kernel BUG at c0033e34 [verbose debug info unavailable] [0.245025] Internal error: Oops - undefined instruction: 0 [#1] SMP [0.262390] PC is at omap3_l3_app_irq+0x108/0x12c I'm getting the same error on one of my AM3517 boards. L3_SI_FLAG_STATUS_0 register has bit 15 set that means Display SS IA burst timeout according to the RM. Regards, Ilya. Do the bootloaders on these boards enable display? There was a patch which got into the kernel in 3.2-rc4: b923d40dd4211c4ef7d4efa2bd81b7ca1d8744c1 ARM: OMAP2PLUS: DSS: Ensure DSS works correctly if display is enabled in bootloader This tries to disable any display outputs if enabled in bootloader. If this issue didn't happen before, we might want to look into this code. Could you share what debug prints you get from the function omap_dss_reset() (its in arch/arm/mach-omap2/display.c) Thanks, Archit -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs settings
Hi, On Thursday 08 December 2011 01:59 PM, Tomi Valkeinen wrote: On Wed, 2011-12-07 at 18:35 +0530, Archit Taneja wrote: Hi, On Tuesday 22 November 2011 02:52 PM, Tomi Valkeinen wrote: Add checks for overlay and manager settings. The checks are a bit complex, as we need to observe the bigger picture instead of overlays and managers independently. Things like the used display and the zorder of other overlays affect the validity of the settings. Minor comment: dss_ovl_check, dss_mgr_check and dss_mgr_check_zorder don't really qualify as functions which do actual applying of configurations, they could be moved from apply.c to manager.c and overlay.c. I had the check functions in apply.c because they used apply.c's internal datastructures. However, looking the functions now, only dss_mgr_check_zorder() used the internal datas, and the function doesn't even use those variables for anything =). Also, the function dss_mgr_check() takes 'struct omap_overlay_manager_info *info' as a parameter but doesn't use it. We might want to remove that too. Archit So you're right, they can be moved to manager.c and overlay.c, thanks. Tomi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/3] OMAPDSS: Miscellaneous Fixes
These are some minor fixes for DSS2. Based on Tomi's master branch in: git://gitorious.org/linux-omap-dss2/linux.git Archit Taneja (3): OMAPDSS: DSI: Fix HSDIV related PLL info in dsi_dump_clocks() OMAPDSS: Panel NEC: Set omap_dss_device states correctly OMAPDSS: Displays: Make PICODLP driver depend on DPI drivers/video/omap2/displays/Kconfig |2 +- .../omap2/displays/panel-nec-nl8048hl11-01b.c | 61 +--- drivers/video/omap2/dss/dsi.c | 14 +++-- 3 files changed, 61 insertions(+), 16 deletions(-) -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] OMAPDSS: DSI: Fix HSDIV related PLL info in dsi_dump_clocks()
The clock names of DSI_PLL_HSDIV_DISPC and DSI_PLL_HSDIV_DSI was made dynamic based on the current value of DISPC and DSI FCLK sources. This doesn't need to be done since we are just interested in the clock names, and not the current clock sources for DISPC and DSI FCLKs. Use only the generic and omap specific names for the DSI PLL's HSDIV clocks. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/dsi.c | 14 -- 1 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 4dc98b6..511ae2a 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1734,17 +1734,19 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev, seq_printf(s, CLKIN4DDR\t%-16luregm %u\n, cinfo-clkin4ddr, cinfo-regm); - seq_printf(s, %s (%s)\t%-16luregm_dispc %u\t(%s)\n, - dss_get_generic_clk_source_name(dispc_clk_src), - dss_feat_get_clk_source_name(dispc_clk_src), + seq_printf(s, DSI_PLL_HSDIV_DISPC (%s)\t%-16luregm_dispc %u\t(%s)\n, + dss_feat_get_clk_source_name(dsi_module == 0 ? + OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC : + OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC), cinfo-dsi_pll_hsdiv_dispc_clk, cinfo-regm_dispc, dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ? off : on); - seq_printf(s, %s (%s)\t%-16luregm_dsi %u\t(%s)\n, - dss_get_generic_clk_source_name(dsi_clk_src), - dss_feat_get_clk_source_name(dsi_clk_src), + seq_printf(s, DSI_PLL_HSDIV_DSI (%s)\t%-16luregm_dsi %u\t(%s)\n, + dss_feat_get_clk_source_name(dsi_module == 0 ? + OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI : + OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI), cinfo-dsi_pll_hsdiv_dsi_clk, cinfo-regm_dsi, dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ? -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] OMAPDSS: Panel NEC: Set omap_dss_device states correctly
The display state parameter of omap_dss_device struct is not being set correctly in the panel driver NEC panel driver panel-nec-nl8048hl11-01b.c. Set the correct states in the panel's enable/disable/suspend/resume functions. CC: Erik Gilling konk...@android.com Signed-off-by: Archit Taneja arc...@ti.com --- .../omap2/displays/panel-nec-nl8048hl11-01b.c | 61 +--- 1 files changed, 52 insertions(+), 9 deletions(-) diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c index 2ba9d0c..94e0f20 100644 --- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c +++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c @@ -163,50 +163,93 @@ static void nec_8048_panel_remove(struct omap_dss_device *dssdev) kfree(necd); } -static int nec_8048_panel_enable(struct omap_dss_device *dssdev) +static int nec_8048_panel_power_on(struct omap_dss_device *dssdev) { - int r = 0; + int r; struct nec_8048_data *necd = dev_get_drvdata(dssdev-dev); struct backlight_device *bl = necd-bl; + if (dssdev-state == OMAP_DSS_DISPLAY_ACTIVE) + return 0; + + r = omapdss_dpi_display_enable(dssdev); + if (r) + goto err0; + if (dssdev-platform_enable) { r = dssdev-platform_enable(dssdev); if (r) - return r; + goto err1; } r = nec_8048_bl_update_status(bl); if (r 0) dev_err(dssdev-dev, failed to set lcd brightness\n); - r = omapdss_dpi_display_enable(dssdev); - + return 0; +err1: + omapdss_dpi_display_disable(dssdev); +err0: return r; } -static void nec_8048_panel_disable(struct omap_dss_device *dssdev) +static void nec_8048_panel_power_off(struct omap_dss_device *dssdev) { struct nec_8048_data *necd = dev_get_drvdata(dssdev-dev); struct backlight_device *bl = necd-bl; - omapdss_dpi_display_disable(dssdev); + if (dssdev-state != OMAP_DSS_DISPLAY_ACTIVE) + return; bl-props.brightness = 0; nec_8048_bl_update_status(bl); if (dssdev-platform_disable) dssdev-platform_disable(dssdev); + + omapdss_dpi_display_disable(dssdev); +} + +static int nec_8048_panel_enable(struct omap_dss_device *dssdev) +{ + int r; + + r = nec_8048_panel_power_on(dssdev); + if (r) + return r; + + dssdev-state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; +} + +static void nec_8048_panel_disable(struct omap_dss_device *dssdev) +{ + nec_8048_panel_power_off(dssdev); + + dssdev-state = OMAP_DSS_DISPLAY_DISABLED; } static int nec_8048_panel_suspend(struct omap_dss_device *dssdev) { - nec_8048_panel_disable(dssdev); + nec_8048_panel_power_off(dssdev); + + dssdev-state = OMAP_DSS_DISPLAY_SUSPENDED; + return 0; } static int nec_8048_panel_resume(struct omap_dss_device *dssdev) { - return nec_8048_panel_enable(dssdev); + int r; + + r = nec_8048_panel_power_on(dssdev); + if (r) + return r; + + dssdev-state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; } static int nec_8048_recommended_bpp(struct omap_dss_device *dssdev) -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] OMAPDSS: Displays: Make PICODLP driver depend on DPI
Make PICODLP driver on OMAP2_DSS_DPI since it is the display interface it uses. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/displays/Kconfig |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index 8d8e1fe..74d29b5 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -41,7 +41,7 @@ config PANEL_NEC_NL8048HL11_01B config PANEL_PICODLP tristate TI PICO DLP mini-projector - depends on OMAP2_DSS I2C + depends on OMAP2_DSS_DPI I2C help A mini-projector used in TI's SDP4430 and EVM boards For more info please visit http://www.dlp.com/projector/ -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 63/65] OMAPDSS: APPLY: add checking of ovls/mgrs settings
Hi, On Tuesday 22 November 2011 02:52 PM, Tomi Valkeinen wrote: Add checks for overlay and manager settings. The checks are a bit complex, as we need to observe the bigger picture instead of overlays and managers independently. Things like the used display and the zorder of other overlays affect the validity of the settings. Minor comment: dss_ovl_check, dss_mgr_check and dss_mgr_check_zorder don't really qualify as functions which do actual applying of configurations, they could be moved from apply.c to manager.c and overlay.c. Archit Signed-off-by: Tomi Valkeinentomi.valkei...@ti.com --- drivers/video/omap2/dss/apply.c | 215 ++- 1 files changed, 212 insertions(+), 3 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 5d933b9..72afa85 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -166,6 +166,169 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr) return mgr-device-caps OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; } +/* Check if overlay parameters are compatible with display */ +static int dss_ovl_check(struct omap_overlay *ovl, + struct omap_overlay_info *info, struct omap_dss_device *dssdev) +{ + u16 outw, outh; + u16 dw, dh; + + if (dssdev == NULL) + return 0; + + dssdev-driver-get_resolution(dssdev,dw,dh); + + if ((ovl-caps OMAP_DSS_OVL_CAP_SCALE) == 0) { + outw = info-width; + outh = info-height; + } else { + if (info-out_width == 0) + outw = info-width; + else + outw = info-out_width; + + if (info-out_height == 0) + outh = info-height; + else + outh = info-out_height; + } + + if (dw info-pos_x + outw) { + DSSERR(overlay %d horizontally not inside the display area + (%d + %d= %d)\n, + ovl-id, info-pos_x, outw, dw); + return -EINVAL; + } + + if (dh info-pos_y + outh) { + DSSERR(overlay %d vertically not inside the display area + (%d + %d= %d)\n, + ovl-id, info-pos_y, outh, dh); + return -EINVAL; + } + + return 0; +} + +static int dss_mgr_check_zorder(struct omap_overlay_manager *mgr, + struct omap_overlay_info **overlay_infos) +{ + struct omap_overlay *ovl1, *ovl2; + struct ovl_priv_data *op1, *op2; + struct omap_overlay_info *info1, *info2; + + list_for_each_entry(ovl1,mgr-overlays, list) { + op1 = get_ovl_priv(ovl1); + info1 = overlay_infos[ovl1-id]; + + if (info1 == NULL) + continue; + + list_for_each_entry(ovl2,mgr-overlays, list) { + if (ovl1 == ovl2) + continue; + + op2 = get_ovl_priv(ovl2); + info2 = overlay_infos[ovl2-id]; + + if (info2 == NULL) + continue; + + if (info1-zorder == info2-zorder) { + DSSERR(overlays %d and %d have the same + zorder %d\n, + ovl1-id, ovl2-id, info1-zorder); + return -EINVAL; + } + } + } + + return 0; +} + +static int dss_mgr_check(struct omap_overlay_manager *mgr, + struct omap_dss_device *dssdev, + struct omap_overlay_manager_info *info, + struct omap_overlay_info **overlay_infos) +{ + struct omap_overlay *ovl; + int r; + + if (dss_has_feature(FEAT_ALPHA_FREE_ZORDER)) { + r = dss_mgr_check_zorder(mgr, overlay_infos); + if (r) + return r; + } + + list_for_each_entry(ovl,mgr-overlays, list) { + struct omap_overlay_info *oi; + int r; + + oi = overlay_infos[ovl-id]; + + if (oi == NULL) + continue; + + r = dss_ovl_check(ovl, oi, dssdev); + if (r) + return r; + } + + return 0; +} +static int dss_check_settings_low(struct omap_overlay_manager *mgr, + struct omap_dss_device *dssdev, bool applying) +{ + struct omap_overlay_info *oi; + struct omap_overlay_manager_info *mi; + struct omap_overlay *ovl; + struct omap_overlay_info *ois[MAX_DSS_OVERLAYS]; + struct ovl_priv_data *op; + struct mgr_priv_data *mp; + + mp = get_mgr_priv(mgr); + + if (applying mp-user_info_dirty) +
Re: [PATCH 58/65] OMAPDSS: APPLY: add wait_pending_extra_info_updates()
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote: Add wait_pending_extra_info_updates() function which can be used to wait until any extra_info changes have been taken into use by the hardware. This can be only called when holding the apply mutex, so that other threads cannot insert new extra_info changes. This will be used to handle fifo-configurations. Signed-off-by: Tomi Valkeinentomi.valkei...@ti.com --- drivers/video/omap2/dss/apply.c | 70 +++ 1 files changed, 70 insertions(+), 0 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 76b5b02..75db522 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -106,6 +106,7 @@ static struct { static spinlock_t data_lock; /* lock for blocking functions */ static DEFINE_MUTEX(apply_lock); +static DECLARE_COMPLETION(extra_updated_completion); static void dss_register_vsync_isr(void); @@ -232,6 +233,70 @@ static bool need_go(struct omap_overlay_manager *mgr) return false; } +/* returns true if an extra_info field is currently being updated */ +static bool extra_info_update_ongoing(void) +{ + const int num_ovls = omap_dss_get_num_overlays(); + struct ovl_priv_data *op; + struct omap_overlay *ovl; + struct mgr_priv_data *mp; + int i; + bool eid; + + for (i = 0; i num_ovls; ++i) { + ovl = omap_dss_get_overlay(i); + op = get_ovl_priv(ovl); + + if (!op-enabled) + continue; + + mp = get_mgr_priv(ovl-manager); + + if (!mp-enabled) + continue; + + eid = op-extra_info_dirty || op-shadow_extra_info_dirty; + + if (!eid) + continue; + + if (ovl_manual_update(ovl) !mp-updating) + continue; + + return true; + } + + return false; +} + +/* wait until no extra_info updates are pending */ +static void wait_pending_extra_info_updates(void) +{ + bool updating; + unsigned long flags; + unsigned long t; + + spin_lock_irqsave(data_lock, flags); + + updating = extra_info_update_ongoing(); + + if (!updating) { + spin_unlock_irqrestore(data_lock, flags); + return; + } + + init_completion(extra_updated_completion); + + spin_unlock_irqrestore(data_lock, flags); + + t = msecs_to_jiffies(500); + wait_for_completion_timeout(extra_updated_completion, t); + + updating = extra_info_update_ongoing(); + + WARN_ON(updating); +} This function isn't used, are you planning to use it later? Archit + int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) { unsigned long timeout = msecs_to_jiffies(500); @@ -553,6 +618,7 @@ static void dss_apply_irq_handler(void *data, u32 mask) { const int num_mgrs = dss_feat_get_num_mgrs(); int i; + bool extra_updating; spin_lock(data_lock); @@ -582,6 +648,10 @@ static void dss_apply_irq_handler(void *data, u32 mask) dss_write_regs(); + extra_updating = extra_info_update_ongoing(); + if (!extra_updating) + complete_all(extra_updated_completion); + if (!need_isr()) dss_unregister_vsync_isr(); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote: dss_cache struct contains a spinlock used to protect the struct. A more logical place for the spinlock is outside the struct that it is protecting. So move it there. Signed-off-by: Tomi Valkeinentomi.valkei...@ti.com --- drivers/video/omap2/dss/apply.c | 22 -- 1 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 23c723a..17639c0 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -89,13 +89,15 @@ struct mgr_priv_data { }; static struct { - spinlock_t lock; struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; bool irq_enabled; } dss_cache; +/* protects dss_cache */ +static spinlock_t data_lock; Minor comment: The name 'data_lock' doesn't tell much that its protecting the dss_cache struct. Probably 'cache_lock' or 'priv_data_lock' or something like that may be more informative. Archit + static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl) { returndss_cache.ovl_priv_data_array[ovl-id]; @@ -108,7 +110,7 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr) void dss_apply_init(void) { - spin_lock_init(dss_cache.lock); + spin_lock_init(data_lock); } static bool ovl_manual_update(struct omap_overlay *ovl) @@ -149,10 +151,10 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) unsigned long flags; bool shadow_dirty, dirty; - spin_lock_irqsave(dss_cache.lock, flags); + spin_lock_irqsave(data_lock, flags); dirty = mp-dirty; shadow_dirty = mp-shadow_dirty; - spin_unlock_irqrestore(dss_cache.lock, flags); + spin_unlock_irqrestore(data_lock, flags); if (!dirty !shadow_dirty) { r = 0; @@ -212,10 +214,10 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) unsigned long flags; bool shadow_dirty, dirty; - spin_lock_irqsave(dss_cache.lock, flags); + spin_lock_irqsave(data_lock, flags); dirty = op-dirty; shadow_dirty = op-shadow_dirty; - spin_unlock_irqrestore(dss_cache.lock, flags); + spin_unlock_irqrestore(data_lock, flags); if (!dirty !shadow_dirty) { r = 0; @@ -464,7 +466,7 @@ static void dss_apply_irq_handler(void *data, u32 mask) for (i = 0; i num_mgrs; i++) mgr_busy[i] = dispc_mgr_go_busy(i); - spin_lock(dss_cache.lock); + spin_lock(data_lock); for (i = 0; i num_ovls; ++i) { ovl = omap_dss_get_overlay(i); @@ -498,7 +500,7 @@ static void dss_apply_irq_handler(void *data, u32 mask) dss_unregister_vsync_isr(); end: - spin_unlock(dss_cache.lock); + spin_unlock(data_lock); } static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl) @@ -620,7 +622,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) if (r) return r; - spin_lock_irqsave(dss_cache.lock, flags); + spin_lock_irqsave(data_lock, flags); /* Configure overlays */ list_for_each_entry(ovl,mgr-overlays, list) @@ -641,7 +643,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) dss_write_regs(); } - spin_unlock_irqrestore(dss_cache.lock, flags); + spin_unlock_irqrestore(data_lock, flags); dispc_runtime_put(); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 35/65] OMAPDSS: APPLY: move spinlock outside the struct
On Wednesday 23 November 2011 02:55 PM, Archit Taneja wrote: snip Minor comment: The name 'data_lock' doesn't tell much that its protecting the dss_cache struct. Probably 'cache_lock' or 'priv_data_lock' or something like that may be more informative. Archit Ah, just saw the next patch, you renamed dss_cache to dss_data, so 'data_lock' seems to make more sense now. Archit + static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl) { returndss_cache.ovl_priv_data_array[ovl-id]; @@ -108,7 +110,7 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr) void dss_apply_init(void) { - spin_lock_init(dss_cache.lock); + spin_lock_init(data_lock); } static bool ovl_manual_update(struct omap_overlay *ovl) @@ -149,10 +151,10 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) unsigned long flags; bool shadow_dirty, dirty; - spin_lock_irqsave(dss_cache.lock, flags); + spin_lock_irqsave(data_lock, flags); dirty = mp-dirty; shadow_dirty = mp-shadow_dirty; - spin_unlock_irqrestore(dss_cache.lock, flags); + spin_unlock_irqrestore(data_lock, flags); if (!dirty !shadow_dirty) { r = 0; @@ -212,10 +214,10 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) unsigned long flags; bool shadow_dirty, dirty; - spin_lock_irqsave(dss_cache.lock, flags); + spin_lock_irqsave(data_lock, flags); dirty = op-dirty; shadow_dirty = op-shadow_dirty; - spin_unlock_irqrestore(dss_cache.lock, flags); + spin_unlock_irqrestore(data_lock, flags); if (!dirty !shadow_dirty) { r = 0; @@ -464,7 +466,7 @@ static void dss_apply_irq_handler(void *data, u32 mask) for (i = 0; i num_mgrs; i++) mgr_busy[i] = dispc_mgr_go_busy(i); - spin_lock(dss_cache.lock); + spin_lock(data_lock); for (i = 0; i num_ovls; ++i) { ovl = omap_dss_get_overlay(i); @@ -498,7 +500,7 @@ static void dss_apply_irq_handler(void *data, u32 mask) dss_unregister_vsync_isr(); end: - spin_unlock(dss_cache.lock); + spin_unlock(data_lock); } static int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl) @@ -620,7 +622,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) if (r) return r; - spin_lock_irqsave(dss_cache.lock, flags); + spin_lock_irqsave(data_lock, flags); /* Configure overlays */ list_for_each_entry(ovl,mgr-overlays, list) @@ -641,7 +643,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) dss_write_regs(); } - spin_unlock_irqrestore(dss_cache.lock, flags); + spin_unlock_irqrestore(data_lock, flags); dispc_runtime_put(); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 40/65] OMAPDSS: APPLY: add mutex
Hi, On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote: The functions in apply.c, called mostly via function pointers in overlay and overlay_manager structs, will be divided into two groups. The other group will not sleep and can be called from interrupts, and the other group may sleep. Small sentence issue above, both groups are called the 'other group'. The idea is that the non-sleeping functions may only change certain settings in overlays and managers, and those settings may only affect the particular overlay/manager. For example, set the base address of the overlay. The blocking functions, however, will handle more complex configuration changes. For example, when an overlay is enabled and fifo-merge feature is used, we need to do the enable in multiple steps, waiting in between, and the change affects multiple overlays and managers. This patch adds the mutex which is used in the blocking functions to have exclusive access to overlays and overlay managers. Previously, when we changed the links between 'overlay-managers' and 'manager-devices', it wasn't protected by a lock. Why is it needed now? As an example, suppose we are changing a manager's device to some other display. Is this lock preventing someone else to get the older 'mgr-device' rather than the new one? Archit Signed-off-by: Tomi Valkeinentomi.valkei...@ti.com --- drivers/video/omap2/dss/apply.c | 71 ++- 1 files changed, 62 insertions(+), 9 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index b935264..fb6d3c2 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -97,6 +97,8 @@ static struct { /* protects dss_data */ static spinlock_t data_lock; +/* lock for blocking functions */ +static DEFINE_MUTEX(apply_lock); static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl) { @@ -639,14 +641,22 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) void dss_mgr_enable(struct omap_overlay_manager *mgr) { + mutex_lock(apply_lock); + dispc_mgr_enable(mgr-id, true); mgr-enabled = true; + + mutex_unlock(apply_lock); } void dss_mgr_disable(struct omap_overlay_manager *mgr) { + mutex_lock(apply_lock); + dispc_mgr_enable(mgr-id, false); mgr-enabled = false; + + mutex_unlock(apply_lock); } int dss_mgr_set_info(struct omap_overlay_manager *mgr, @@ -669,44 +679,65 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr, { int r; + mutex_lock(apply_lock); + if (dssdev-manager) { DSSERR(display '%s' already has a manager '%s'\n, dssdev-name, dssdev-manager-name); - return -EINVAL; + r = -EINVAL; + goto err; } if ((mgr-supported_displays dssdev-type) == 0) { DSSERR(display '%s' does not support manager '%s'\n, dssdev-name, mgr-name); - return -EINVAL; + r = -EINVAL; + goto err; } dssdev-manager = mgr; mgr-device = dssdev; mgr-device_changed = true; + mutex_unlock(apply_lock); + return 0; +err: + mutex_unlock(apply_lock); + return r; } int dss_mgr_unset_device(struct omap_overlay_manager *mgr) { + int r; + + mutex_lock(apply_lock); + if (!mgr-device) { DSSERR(failed to unset display, display not set.\n); - return -EINVAL; + r = -EINVAL; + goto err; } /* * Don't allow currently enabled displays to have the overlay manager * pulled out from underneath them */ - if (mgr-device-state != OMAP_DSS_DISPLAY_DISABLED) - return -EINVAL; + if (mgr-device-state != OMAP_DSS_DISPLAY_DISABLED) { + r = -EINVAL; + goto err; + } mgr-device-manager = NULL; mgr-device = NULL; mgr-device_changed = true; + mutex_unlock(apply_lock); + return 0; +err: + mutex_unlock(apply_lock); + return r; } @@ -729,18 +760,24 @@ void dss_ovl_get_info(struct omap_overlay *ovl, int dss_ovl_set_manager(struct omap_overlay *ovl, struct omap_overlay_manager *mgr) { + int r; + if (!mgr) return -EINVAL; + mutex_lock(apply_lock); + if (ovl-manager) { DSSERR(overlay '%s' already has a manager '%s'\n, ovl-name, ovl-manager-name); - return -EINVAL; + r = -EINVAL; + goto err; } if (ovl-info.enabled) { DSSERR(overlay has to be disabled to change the manager\n); - return -EINVAL; + r = -EINVAL; + goto err; }
Re: [PATCH 41/65] OMAPDSS: APPLY: add missing uses of spinlock
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote: The functions in apply.c, called mostly via function pointers in overlay and overlay_manager structs, will be divided into two groups. The other group will not sleep and can be called from interrupts, and the other group may sleep. The idea is that the non-sleeping functions may only change certain settings in overlays and managers, and those settings may only affect the particular overlay/manager. For example, set the base address of the overlay. The blocking functions, however, will handle more complex configuration changes. For example, when an overlay is enabled and fifo-merge feature is used, we need to do the enable in multiple steps, waiting in between, and the change affects multiple overlays and managers. apply.c already contains a spinlock, which has been used to protect (badly) the dss_data. This patch adds locks/unlocks of the spinlock to the missing places, and the lock should now properly protect dss_data. Signed-off-by: Tomi Valkeinentomi.valkei...@ti.com --- drivers/video/omap2/dss/apply.c | 29 + 1 files changed, 29 insertions(+), 0 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index fb6d3c2..9ad2a36 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -405,6 +405,9 @@ void dss_start_update(struct omap_overlay_manager *mgr) struct mgr_priv_data *mp = get_mgr_priv(mgr); struct ovl_priv_data *op; struct omap_overlay *ovl; + unsigned long flags; + + spin_lock_irqsave(data_lock, flags); mp-do_manual_update = true; dss_write_regs(); @@ -418,6 +421,8 @@ void dss_start_update(struct omap_overlay_manager *mgr) mp-shadow_dirty = false; dispc_mgr_enable(mgr-id, true); + + spin_unlock_irqrestore(data_lock, flags); } static void dss_apply_irq_handler(void *data, u32 mask); @@ -662,16 +667,28 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) int dss_mgr_set_info(struct omap_overlay_manager *mgr, struct omap_overlay_manager_info *info) { + unsigned long flags; + + spin_lock_irqsave(data_lock, flags); + mgr-info = *info; mgr-info_dirty = true; + spin_unlock_irqrestore(data_lock, flags); + return 0; } void dss_mgr_get_info(struct omap_overlay_manager *mgr, struct omap_overlay_manager_info *info) { + unsigned long flags; + + spin_lock_irqsave(data_lock, flags); + *info = mgr-info; + + spin_unlock_irqrestore(data_lock, flags); } int dss_mgr_set_device(struct omap_overlay_manager *mgr, @@ -745,16 +762,28 @@ err: int dss_ovl_set_info(struct omap_overlay *ovl, struct omap_overlay_info *info) { + unsigned long flags; + + spin_lock_irqsave(data_lock, flags); + ovl-info = *info; ovl-info_dirty = true; + spin_unlock_irqrestore(data_lock, flags); + return 0; } void dss_ovl_get_info(struct omap_overlay *ovl, struct omap_overlay_info *info) { + unsigned long flags; + + spin_lock_irqsave(data_lock, flags); + *info = ovl-info; + + spin_unlock_irqrestore(data_lock, flags); } The get/set info functions for overlays and managers only modify the omap_overlay_info or manager_info structs, these aren't really a part of 'dss_data', they only become a part of dss_data only when we call mgr-apply(). So, are we protecting these functions so that 2 users of the same overlay don't see incorrect info values? Archit int dss_ovl_set_manager(struct omap_overlay *ovl, -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode displays
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote: The current code uses dsi_video_mode_enable/disable functions to enable/disable DISPC output for video mode displays. For command mode displays we have no notion in the DISPC side of whether the panel is enabled, except when a dss_start_update() call is made. However, to properly maintain the DISPC state in apply.c, we need to know if a manager used for a manual update display is currently in use. This patch achieves that by changing dsi_video_mode_enable/disable to dsi_enable/disable_video_output, which is called by both video and command mode displays. For video mode displays it starts the actual pixel stream, as it did before. For command mode displays it doesn't do anything else than mark that the manager is currently in use. dsi_video_mode_enable() doesn't only enable the DISPC output, it also sends the long packet header to start video mode transfer. I think it would be better if we had 2 separate functions, one which starts/stops DSI video mode, and the other which enables/disables the DISPC video port. This way, a manual update panel would need to call only dsi_enable/disable_video_output(which just enables or disables the manager), whereas a video mode panel will need to call both. This is just a suggestion though. It's probably okay to have both in the same function too. We might have to separate them out later if we were planning to standardise mipi dsi across SoCs. Archit Signed-off-by: Tomi Valkeinentomi.valkei...@ti.com --- drivers/video/omap2/displays/panel-taal.c |6 ++ drivers/video/omap2/dss/apply.c |6 ++- drivers/video/omap2/dss/dsi.c | 73 +++- include/video/omapdss.h |4 +- 4 files changed, 51 insertions(+), 38 deletions(-) diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index dd64bd1..00c5c61 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -1182,6 +1182,10 @@ static int taal_power_on(struct omap_dss_device *dssdev) if (r) goto err; + r = dsi_enable_video_output(dssdev, td-channel); + if (r) + goto err; + td-enabled = 1; if (!td-intro_printed) { @@ -1211,6 +1215,8 @@ static void taal_power_off(struct omap_dss_device *dssdev) struct taal_data *td = dev_get_drvdata(dssdev-dev); int r; + dsi_disable_video_output(dssdev, td-channel); + r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF); if (!r) r = taal_sleep_in(td); diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 9ad2a36..66f4c56 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -648,7 +648,8 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr) { mutex_lock(apply_lock); - dispc_mgr_enable(mgr-id, true); + if (!mgr_manual_update(mgr)) + dispc_mgr_enable(mgr-id, true); mgr-enabled = true; mutex_unlock(apply_lock); @@ -658,7 +659,8 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) { mutex_lock(apply_lock); - dispc_mgr_enable(mgr-id, false); + if (!mgr_manual_update(mgr)) + dispc_mgr_enable(mgr-id, false); mgr-enabled = false; mutex_unlock(apply_lock); diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 08d3de90..a35f3fb 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3939,65 +3939,70 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) } } -int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel) +int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); int bpp = dsi_get_pixel_size(dssdev-panel.dsi_pix_fmt); u8 data_type; u16 word_count; - switch (dssdev-panel.dsi_pix_fmt) { - case OMAP_DSS_DSI_FMT_RGB888: - data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24; - break; - case OMAP_DSS_DSI_FMT_RGB666: - data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18; - break; - case OMAP_DSS_DSI_FMT_RGB666_PACKED: - data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18; - break; - case OMAP_DSS_DSI_FMT_RGB565: - data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16; - break; - default: - BUG(); - }; + if (dssdev-panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { + switch (dssdev-panel.dsi_pix_fmt) { + case OMAP_DSS_DSI_FMT_RGB888: + data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24; + break; + case OMAP_DSS_DSI_FMT_RGB666: +
Re: [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode displays
On Wednesday 23 November 2011 04:12 PM, Tomi Valkeinen wrote: On Wed, 2011-11-23 at 15:40 +0530, Archit Taneja wrote: On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote: The current code uses dsi_video_mode_enable/disable functions to enable/disable DISPC output for video mode displays. For command mode displays we have no notion in the DISPC side of whether the panel is enabled, except when a dss_start_update() call is made. However, to properly maintain the DISPC state in apply.c, we need to know if a manager used for a manual update display is currently in use. This patch achieves that by changing dsi_video_mode_enable/disable to dsi_enable/disable_video_output, which is called by both video and command mode displays. For video mode displays it starts the actual pixel stream, as it did before. For command mode displays it doesn't do anything else than mark that the manager is currently in use. dsi_video_mode_enable() doesn't only enable the DISPC output, it also sends the long packet header to start video mode transfer. I think it would be better if we had 2 separate functions, one which starts/stops DSI video mode, and the other which enables/disables the DISPC video port. This way, a manual update panel would need to call only dsi_enable/disable_video_output(which just enables or disables the manager), whereas a video mode panel will need to call both. This is just a suggestion though. It's probably okay to have both in the same function too. We might have to separate them out later if we were planning to standardise mipi dsi across SoCs. If you think from the panel driver's point of view, it doesn't know about DISPC. It just wants to enable the video stream (on video mode displays). If we had two functions, could only the first be used? I.e. is it possible to just enable the video mode transfer, without enabling DISPC? If not, I'm not sure what would be the use for two separate functions. And even if it can, I'm not sure what use it would be to enable only the video mode output without the actual pixel data from DISPC. It is true that the function in thsi patch is not the best one. For command mode display it's more about reserving the ovl manager for use than actually enabling it. Then again, how I thought the function's purpose was that it enables the DSI video output, but because for command mode there's need to trigger the actual frame transfer later, the function doesn't start the pixel feed for command mode displays. It just prepares the output. But even if we had the functions separated, the function called by video mode and command mode displays would be different, as for the former one it enables the pixel stream, and for latter one it just reserves the output. So, I'm fine with changing the function, but the reasoning for what functions we have and what they do should come from the panel driver's perspective, not because of OMAP DSS's HW details. If you look from the panel driver's perspective, we shouldn't split this. I think it would be best to stuff the 'video mode enabling and manager enabling' functionality in omapdss_dsi_display_enable() itself, the panel driver shouldn't need to call a function separately to enable video mode for the panel. This way we would be more along the lines of the dpi driver, where dpi_display_enable() enables the manager in the end. I guess we can leave this the way you are doing it currently, and move this code into dsi_display_enable() code later on. Archit Tomi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 42/65] OMAPDSS: DSI: call mgr_enable/disable for cmd mode displays
On Wednesday 23 November 2011 04:57 PM, Tomi Valkeinen wrote: On Wed, 2011-11-23 at 16:38 +0530, Archit Taneja wrote: I think it would be best to stuff the 'video mode enabling and manager enabling' functionality in omapdss_dsi_display_enable() itself, the panel driver shouldn't need to call a function separately to enable video mode for the panel. This way we would be more along the lines of the dpi driver, where dpi_display_enable() enables the manager in the end. But we need to configure the panel between enabling the DSI interface and enabling the video output, so we can't combine those two functions. Oh okay, that's right, we can't start video mode before preparing the panel. Archit For DPI things are simpler, as enabling the interface and the video output are more or less the same thing. Tomi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 06/65] OMAPDSS: remove partial update from the overlay manager
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote: Partial update for manual update displays has never worked quite well: * The HW has limitations on the update area, and the x and width need to be even. There are also some issues with partial update on OMAP4 even when 'x and width are even'. There seems to be DISPC timeouts when the update area is too small. Its easy to reproduce it by running the 'rect' test for a while. For those who are interested, the rect testcase can be found in: git://gitorious.org/linux-omap-dss2/omapfb-tests.git Archit * Showing a part of a scaled overlay causes artifacts. * Makes the management of dispc very complex Considering the above points and the fact that partial update is not used anywhere, this and the following patches remove the partial update support. This will greatly simplify the following re-write of the apply mechanism to get proper locking and additional features like fifo-merge. This patch removes the partial update from the manager.c. Signed-off-by: Tomi Valkeinentomi.valkei...@ti.com --- drivers/video/omap2/dss/dsi.c |2 - drivers/video/omap2/dss/dss.h |3 - drivers/video/omap2/dss/manager.c | 333 + drivers/video/omap2/dss/rfbi.c|1 - 4 files changed, 6 insertions(+), 333 deletions(-) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 5abf8e7..787cebd 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4172,8 +4172,6 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev, dsi_perf_mark_setup(dsidev); - dss_setup_partial_planes(dssdev, x, y, w, h, - enlarge_update_area); dispc_mgr_set_lcd_size(dssdev-manager-id, *w, *h); return 0; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 313a7ca..7f6a612 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -182,9 +182,6 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane, int dss_init_overlay_managers(struct platform_device *pdev); void dss_uninit_overlay_managers(struct platform_device *pdev); int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl); -void dss_setup_partial_planes(struct omap_dss_device *dssdev, - u16 *x, u16 *y, u16 *w, u16 *h, - bool enlarge_update_area); void dss_start_update(struct omap_dss_device *dssdev); /* overlay */ diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 1be5f47..c616f85 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -530,13 +530,6 @@ struct manager_cache_data { bool manual_update; bool do_manual_update; - - /* manual update region */ - u16 x, y, w, h; - - /* enlarge the update area if the update area contains scaled -* overlays */ - bool enlarge_update_area; }; static struct { @@ -762,65 +755,11 @@ static int overlay_enabled(struct omap_overlay *ovl) return ovl-info.enabled ovl-manager ovl-manager-device; } -/* Is rect1 a subset of rect2? */ -static bool rectangle_subset(int x1, int y1, int w1, int h1, - int x2, int y2, int w2, int h2) -{ - if (x1 x2 || y1 y2) - return false; - - if (x1 + w1 x2 + w2) - return false; - - if (y1 + h1 y2 + h2) - return false; - - return true; -} - -/* Do rect1 and rect2 overlap? */ -static bool rectangle_intersects(int x1, int y1, int w1, int h1, - int x2, int y2, int w2, int h2) -{ - if (x1= x2 + w2) - return false; - - if (x2= x1 + w1) - return false; - - if (y1= y2 + h2) - return false; - - if (y2= y1 + h1) - return false; - - return true; -} - -static bool dispc_is_overlay_scaled(struct overlay_cache_data *oc) -{ - struct omap_overlay_info *oi =oc-info; - - if (oi-out_width != 0 oi-width != oi-out_width) - return true; - - if (oi-out_height != 0 oi-height != oi-out_height) - return true; - - return false; -} - static int configure_overlay(enum omap_plane plane) { struct overlay_cache_data *c; - struct manager_cache_data *mc; - struct omap_overlay_info *oi, new_oi; - struct omap_overlay_manager_info *mi; - u16 outw, outh; - u16 x, y, w, h; - u32 paddr; + struct omap_overlay_info *oi; int r; - u16 orig_w, orig_h, orig_outw, orig_outh; DSSDBGF(%d, plane); @@ -832,120 +771,7 @@ static int configure_overlay(enum omap_plane plane) return 0; } - mc =dss_cache.manager_cache[c-channel]; - mi =mc-info; - - x = oi-pos_x; - y = oi-pos_y; - w = oi-width; - h = oi-height; - outw
Re: [PATCH 08/65] OMAPDSS: remove partial update from panel-taal
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote: Partial update for manual update displays has never worked quite well: * The HW has limitations on the update area, and the x and width need to be even. * Showing a part of a scaled overlay causes artifacts. * Makes the management of dispc very complex Considering the above points and the fact that partial update is not used anywhere, this and the following patches remove the partial update support. This will greatly simplify the following re-write of the apply mechanism to get proper locking and additional features like fifo-merge. This patch removes the partial update from the panel-taal.c. Signed-off-by: Tomi Valkeinentomi.valkei...@ti.com --- drivers/video/omap2/displays/panel-taal.c | 16 1 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 0aa6c5d..dd64bd1 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -198,12 +198,6 @@ struct taal_data { bool te_enabled; atomic_t do_update; - struct { - u16 x; - u16 y; - u16 w; - u16 h; - } update_region; int channel; struct delayed_work te_timeout_work; @@ -1440,16 +1434,14 @@ static int taal_update(struct omap_dss_device *dssdev, goto err; } - r = taal_set_update_window(td, x, y, w, h); + /* XXX no need to send this every frame, but dsi break if not done */ + r = taal_set_update_window(td, 0, 0, + td-panel_config-timings.x_res, + td-panel_config-timings.y_res); How about sending a null short packet, and a BTA after that. This will keep automatic TE mode in place, and we'll need to send 1 short packet instead of 2 long packets every frame. We should of course do this if we aren't planning to get partial update back in the near future. Archit if (r) goto err; if (td-te_enabled panel_data-use_ext_te) { - td-update_region.x = x; - td-update_region.y = y; - td-update_region.w = w; - td-update_region.h = h; - barrier(); schedule_delayed_work(td-te_timeout_work, msecs_to_jiffies(250)); atomic_set(td-do_update, 1); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/65] OMAPDSS: remove partial update from panel-taal
On Tuesday 22 November 2011 06:02 PM, Tomi Valkeinen wrote: On Tue, 2011-11-22 at 17:23 +0530, Archit Taneja wrote: - r = taal_set_update_window(td, x, y, w, h); + /* XXX no need to send this every frame, but dsi break if not done */ + r = taal_set_update_window(td, 0, 0, + td-panel_config-timings.x_res, + td-panel_config-timings.y_res); How about sending a null short packet, and a BTA after that. This will keep automatic TE mode in place, and we'll need to send 1 short packet instead of 2 long packets every frame. To be honest, I didn't spend any time with this. True, sending a null packet and BTA instead of the 2 long packets is possible. But probably even better would be to track the TE status, and send a BTA only when needed. Right, if we maintain the TE status, we may not need to send a packet at all, so I guess we could stick with this for now, and remove it once we start maintaining the number of BTAs we have sent to the panel. Archit Tomi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 09/65] OMAPDSS: pass ovl manager to dss_start_update
On Tuesday 22 November 2011 02:51 PM, Tomi Valkeinen wrote: dss_start_update() takes currently the dss device as a parameter. Change the parameter to ovl manager, as that is what the dss_start_update() actually needs. Minor comment: We could rename dss_start_update() to dss_mgr_start_update() to stick to the new way of telling if this function is meant for an overlay or a manager. Archit Signed-off-by: Tomi Valkeinentomi.valkei...@ti.com --- drivers/video/omap2/dss/dsi.c |2 +- drivers/video/omap2/dss/dss.h |2 +- drivers/video/omap2/dss/manager.c |7 ++- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 9ef04ff..e5a2dcc 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4063,7 +4063,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, msecs_to_jiffies(250)); BUG_ON(r == 0); - dss_start_update(dssdev); + dss_start_update(dssdev-manager); if (dsi-te_enabled) { /* disable LP_RX_TO, so that we can receive TE. Time to wait diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 7f6a612..0937bd8 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -182,7 +182,7 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane, int dss_init_overlay_managers(struct platform_device *pdev); void dss_uninit_overlay_managers(struct platform_device *pdev); int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl); -void dss_start_update(struct omap_dss_device *dssdev); +void dss_start_update(struct omap_overlay_manager *mgr); /* overlay */ void dss_init_overlays(struct platform_device *pdev); diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index c616f85..bc28bfa 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -896,17 +896,14 @@ static int configure_dispc(void) return r; } -void dss_start_update(struct omap_dss_device *dssdev) +void dss_start_update(struct omap_overlay_manager *mgr) { struct manager_cache_data *mc; struct overlay_cache_data *oc; const int num_ovls = dss_feat_get_num_ovls(); const int num_mgrs = dss_feat_get_num_mgrs(); - struct omap_overlay_manager *mgr; int i; - mgr = dssdev-manager; - mc =dss_cache.manager_cache[mgr-id]; mc-do_manual_update = true; @@ -929,7 +926,7 @@ void dss_start_update(struct omap_dss_device *dssdev) mc-shadow_dirty = false; } - dssdev-manager-enable(dssdev-manager); + mgr-enable(mgr); } static void dss_apply_irq_handler(void *data, u32 mask) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] AM35xx: DSS: there is no VDDS_DSI on AM35xx
Hi, On Wednesday 09 November 2011 05:42 AM, Ilya Yanok wrote: AM35xx don't have VDDS_DSI regulator. AM35xx do have vdds_dsi regulator. Are you saying that your particular board doesn't have vdds_dsi connected to a regulator? I assumed that vdds_dsi regulator was required for DPI to function properly on omap3 devices. Archit Signed-off-by: Ilya Yanokya...@emcraft.com --- drivers/video/omap2/dss/dpi.c |9 + drivers/video/omap2/dss/dsi.c | 18 -- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 976ac23..929e451 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -191,7 +191,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) goto err_start_dev; } - if (cpu_is_omap34xx()) { + if (cpu_is_omap34xx() !cpu_is_omap3505() !cpu_is_omap3517()) { r = regulator_enable(dpi.vdds_dsi_reg); if (r) goto err_reg_enable; @@ -238,7 +238,7 @@ err_get_dsi: err_get_dispc: dss_runtime_put(); err_get_dss: - if (cpu_is_omap34xx()) + if (cpu_is_omap34xx() !cpu_is_omap3505() !cpu_is_omap3517()) regulator_disable(dpi.vdds_dsi_reg); err_reg_enable: omap_dss_stop_device(dssdev); @@ -260,7 +260,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) dispc_runtime_put(); dss_runtime_put(); - if (cpu_is_omap34xx()) + if (cpu_is_omap34xx() !cpu_is_omap3505() !cpu_is_omap3517()) regulator_disable(dpi.vdds_dsi_reg); omap_dss_stop_device(dssdev); @@ -348,7 +348,8 @@ int dpi_init_display(struct omap_dss_device *dssdev) { DSSDBG(init_display\n); - if (cpu_is_omap34xx() dpi.vdds_dsi_reg == NULL) { + if (cpu_is_omap34xx() (dpi.vdds_dsi_reg == NULL) + !cpu_is_omap3505() !cpu_is_omap3517()) { struct regulator *vdds_dsi; vdds_dsi = dss_get_vdds_dsi(); diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 5abf8e7..7f38ab6 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1610,7 +1610,8 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, DSSDBG(PLL init\n); - if (dsi-vdds_dsi_reg == NULL) { + if ((dsi-vdds_dsi_reg == NULL) + !cpu_is_omap3517() !cpu_is_omap3505()) { struct regulator *vdds_dsi; vdds_dsi = regulator_get(dsi-pdev-dev, vdds_dsi); @@ -1629,7 +1630,8 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, */ dsi_enable_scp_clk(dsidev); - if (!dsi-vdds_dsi_enabled) { + if (!dsi-vdds_dsi_enabled + !cpu_is_omap3517() !cpu_is_omap3505()) { r = regulator_enable(dsi-vdds_dsi_reg); if (r) goto err0; @@ -1668,7 +1670,8 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, return 0; err1: - if (dsi-vdds_dsi_enabled) { + if (dsi-vdds_dsi_enabled + !cpu_is_omap3517() !cpu_is_omap3505()) { regulator_disable(dsi-vdds_dsi_reg); dsi-vdds_dsi_enabled = false; } @@ -1684,7 +1687,8 @@ void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes) dsi-pll_locked = 0; dsi_pll_power(dsidev, DSI_PLL_POWER_OFF); - if (disconnect_lanes) { + if (disconnect_lanes + !cpu_is_omap3517() !cpu_is_omap3505()) { WARN_ON(!dsi-vdds_dsi_enabled); regulator_disable(dsi-vdds_dsi_reg); dsi-vdds_dsi_enabled = false; @@ -4530,7 +4534,8 @@ int dsi_init_display(struct omap_dss_device *dssdev) OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; } - if (dsi-vdds_dsi_reg == NULL) { + if ((dsi-vdds_dsi_reg == NULL) + !cpu_is_omap3517() !cpu_is_omap3505()) { struct regulator *vdds_dsi; vdds_dsi = regulator_get(dsi-pdev-dev, vdds_dsi); @@ -4799,7 +4804,8 @@ static int omap_dsihw_remove(struct platform_device *dsidev) dsi_put_clocks(dsidev); - if (dsi-vdds_dsi_reg != NULL) { + if ((dsi-vdds_dsi_reg != NULL) + !cpu_is_omap3517() !cpu_is_omap3505()) { if (dsi-vdds_dsi_enabled) { regulator_disable(dsi-vdds_dsi_reg); dsi-vdds_dsi_enabled = false; -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] AM35xx: DSS: there is no VDDS_DSI on AM35xx
Hi, On Wednesday 09 November 2011 11:56 PM, Ilya Yanok wrote: Hi Archit, 09.11.2011 14:10, Archit Taneja wrote: AM35xx don't have VDDS_DSI regulator. AM35xx do have vdds_dsi regulator. Are you saying that your particular board doesn't have vdds_dsi connected to a regulator? Yes, you are right. But looking at the manual (and name) I think it's needed only for DSI operation. On our board we have LCD connected through DPI. I assumed that vdds_dsi regulator was required for DPI to function properly on omap3 devices. Ok, please ignore this patch then. I think I'll create fake regulator from the board code to fix this. Also, could you push the DSS related patches as a separate series? It will be easier to pull them since DSS2 driver has a different maintainer. Thanks, Archit Regards, Ilya. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 20/30] media/omap_vout: disable driver for now
Hi Arnd, On Sunday 02 October 2011 08:15 PM, Arnd Bergmann wrote: This driver was broken by 8cff88c5d OMAP: DSS2: remove update_mode from omapdss: /home/arnd/linux-arm/drivers/media/video/omap/omap_vout.c: In function 'omap_vout_probe': /home/arnd/linux-arm/drivers/media/video/omap/omap_vout.c:2202:15: error: 'struct omap_dss_driver' has no member named 'set_update_mode' /home/arnd/linux-arm/drivers/media/video/omap/omap_vout.c:2203:12: error: 'struct omap_dss_driver' has no member named 'set_update_mode' /home/arnd/linux-arm/drivers/media/video/omap/omap_vout.c:2204:8: error: 'OMAP_DSS_UPDATE_MANUAL' undeclared (first use in this function) /home/arnd/linux-arm/drivers/media/video/omap/omap_vout.c:2204:8: note: each undeclared identifier is reported only once for each function it appears in /home/arnd/linux-arm/drivers/media/video/omap/omap_vout.c:2206:15: error: 'struct omap_dss_driver' has no member named 'set_update_mode' /home/arnd/linux-arm/drivers/media/video/omap/omap_vout.c:2207:12: error: 'struct omap_dss_driver' has no member named 'set_update_mode' /home/arnd/linux-arm/drivers/media/video/omap/omap_vout.c:2208:8: error: 'OMAP_DSS_UPDATE_AUTO' undeclared (first use in this function) make[3]: *** [drivers/media/video/omap/omap_vout.o] Error 1 make[2]: *** [drivers/media/video/omap] Error 2 make[1]: *** [drivers/media/video/] Error 2 make: *** [sub-make] Error 2 A fix for this is already in the master branch of Mauro's tree: git://linuxtv.org/media_tree.git with the commit id: 5ebbf72dc51bd3b481aa91fea37a7157da5fc548 I am guessing this would during the 3.2 merge window. Regards, Archit Let's disable it for now. Signed-off-by: Arnd Bergmanna...@arndb.de Cc: Mauro Carvalho Chehabmche...@infradead.org Cc: Archit Tanejaarc...@ti.com Cc: Amber Jainam...@ti.com Cc: Vaibhav Hiremathhvaib...@ti.com --- drivers/media/video/omap/Kconfig |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/media/video/omap/Kconfig b/drivers/media/video/omap/Kconfig index 390ab09..ee21f36 100644 --- a/drivers/media/video/omap/Kconfig +++ b/drivers/media/video/omap/Kconfig @@ -4,6 +4,7 @@ config VIDEO_OMAP2_VOUT_VRFB config VIDEO_OMAP2_VOUT tristate OMAP2/OMAP3 V4L2-Display driver depends on ARCH_OMAP2 || ARCH_OMAP3 + depends on BROKEN # broken by 8cff88c5da OMAP: DSS2: remove update_mode from omapdss select VIDEOBUF_GEN select VIDEOBUF_DMA_CONTIG select OMAP2_DSS -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] OMAP2PLUS: DSS: Ensure DSS works correctly if display is enabled in bootloader
Hi Paul, On Monday 03 October 2011 10:15 AM, Paul Walmsley wrote: Hi some comments: On Mon, 12 Sep 2011, Archit Taneja wrote: Resetting DISPC when a DISPC output is enabled causes the DSS to go into an inconsistent state. Thus if the bootloader has enabled a display, the hwmod code cannot reset the DISPC module just like that, but the outputs need to be disabled first. Add function dispc_disable_outputs() which disables all active overlay manager and ensure all frame transfers are completed. Modify omap_dss_reset() to call this function and clear DSS_CONTROL, DSS_SDI_CONTROL and DSS_PLL_CONTROL so that DSS is in a clean state when the DSS2 driver starts. This resolves the hang issue(caused by a L3 error during boot) seen on the beagle board C3, which has a factory bootloader that enables display. The issue is resolved with this patch. Acked-by: Tomi Valkeinentomi.valkei...@ti.com Tested-by: R, Sricharanr.sricha...@ti.com Signed-off-by: Archit Tanejaarc...@ti.com --- v2: - Added more info in the commit message, fixed some typos. The patch depends on a HWMOD patch series which has been posted by Tomi, it can be tested by applying over the following branch: https://gitorious.org/linux-omap-dss2/linux/commits/master arch/arm/mach-omap2/display.c | 110 + 1 files changed, 110 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 93db7c1..eab81f4 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -30,6 +30,30 @@ #include control.h +#define DISPC_BASE_OMAP2 0x48050400 +#define DISPC_BASE_OMAP4 0x48041000 These should definitely not be needed -- they can be obtained from the hwmod data and there is clearly something wrong if any IP block addresses exist outside of those data files. The reason we had to do this was because the function omap_dss_reset() is tied to the dss hwmod and not dispc hwmod. Hence, we don't have DISPC related info through the hwmod struct available through omap_dss_reset(). It would have been easy(and more sensible) if we had tied the code in dispc_disable_outputs() to a custom reset function for the dispc hwmod directly, but that unfortunately breaks some functionality. The current omap_dss_reset() function does this: - enable DSS opt clocks to complete power on reset. - see if the power on reset is completed by reading DSS_SYSNCONG - disable DSS opt clocks If we don't do the things done in dispc_disable_outputs() before disabling DSS opt clocks, we would be in trouble. Hence, there is a need to access DISPC registers in the dss hwmod itself, this forced us to create the base macros and the use of omap_readl/writel functions. I considered changing the order in which the hwmods are registered, i.e dispc first and dss later, but that didn't seem right Could you suggest how we could go about this? Is there a way to access dispc hwmod's data in dss hwmod's custom reset function? I agree with all the other comments and things you have done in the patch you made. Thanks for the thorough review and the patch, i'll keep these comments in mind for future. Regards, Archit + +#define DISPC_REG(base, offset) (base + offset) + +#define DISPC_CONTROL0x0040 +#define DISPC_CONTROL2 0x0238 +#define DISPC_IRQSTATUS 0x0018 + +#define DSS_SYSCONFIG0x10 +#define DSS_SYSSTATUS0x14 +#define DSS_CONTROL 0x40 +#define DSS_SDI_CONTROL 0x44 +#define DSS_PLL_CONTROL 0x48 + +#define LCD_EN_MASK (0x1 0) +#define DIGIT_EN_MASK(0x1 1) + +#define FRAMEDONE_IRQ_SHIFT 0 +#define EVSYNC_EVEN_IRQ_SHIFT2 +#define EVSYNC_ODD_IRQ_SHIFT 3 +#define FRAMEDONE2_IRQ_SHIFT 22 +#define FRAMEDONETV_IRQ_SHIFT24 + static struct platform_device omap_display_device = { .name = omapdss, .id= -1, @@ -182,6 +206,78 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) return r; } +static void dispc_disable_outputs(void) +{ + u32 val, irq_mask, base; + bool lcd_en, digit_en, lcd2_en = false; + int i, num_mgrs; + + if (cpu_is_omap44xx()) { + base = DISPC_BASE_OMAP4; + num_mgrs = 3; + } else { + base = DISPC_BASE_OMAP2; + num_mgrs = 2; + } base should not be needed here. The num_mgrs should come from the hwmod data. We're trying to get rid of cpu_is_omap*() functions wherever possible. + + /* store value of LCDENABLE and DIGITENABLE bits */ + val = omap_readl(DISPC_REG(base, DISPC_CONTROL)); omap_{read,write}l() are deprecated and should no longer be used. This code can use omap_hwmod_{read,write}() instead. You can pass the struct omap_hwmod * into this function from the caller. + lcd_en = val LCD_EN_MASK
[PATCH v4 0/5] OMAP_VOUT: Misc fixes and cleanup patches for 3.2
This set includes patches which do the following: - Fix crash if number of displays registered by DSS2 is more than 4. - Fix the issue of not being able to request for a buffer which is larger than what we did the last time. - Fix a small bug in omap_vout_isr() - Remove some redundant code in omap_vout_isr() - Add basic support for DSI panels Changes in v4: - Fix issue in OMAP_VOUT: Fix check in reqbuf for buf_size allocation, improve commit message - Remove patch OMAP_VOUT: Don't trigger updates in omap_vout_probe, replace with OMAP_VOUT: Increase MAX_DISPLAYS to a larger value Archit Taneja (5): OMAP_VOUT: Fix check in reqbuf for buf_size allocation OMAP_VOUT: CLEANUP: Remove redundant code from omap_vout_isr OMAP_VOUT: Fix VSYNC IRQ handling in omap_vout_isr OMAP_VOUT: Add support for DSI panels OMAP_VOUT: Increase MAX_DISPLAYS to a larger value drivers/media/video/omap/omap_vout.c| 187 --- drivers/media/video/omap/omap_voutdef.h |2 +- 2 files changed, 97 insertions(+), 92 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/5] OMAP_VOUT: Fix check in reqbuf for buf_size allocation
The commit 383e4f69879d11c86ebdd38b3356f6d0690fb4cc makes reqbuf prevent requesting a larger size buffer than what is allocated at kernel boot during omap_vout_probe. In omap_vout_buffer_setup callback API, the requested size is compared with vout-buffer_size, this isn't correct as vout-buffer_size is later set to the size requested in reqbuf. When the video device is opened the next time, this check will prevent us to allocate a buffer which is larger than what we requested the last time. Don't use vout-buffer_size, always check with the parameters video1_bufsize or video2_bufsize. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c |6 +- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index d9e64f3..e64a83c 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -664,10 +664,14 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, u32 phy_addr = 0, virt_addr = 0; struct omap_vout_device *vout = q-priv_data; struct omapvideo_info *ovid = vout-vid_info; + int vid_max_buf_size; if (!vout) return -EINVAL; + vid_max_buf_size = vout-vid == OMAP_VIDEO1 ? video1_bufsize : + video2_bufsize; + if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q-type) return -EINVAL; @@ -690,7 +694,7 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, video1_numbuffers : video2_numbuffers; /* Check the size of the buffer */ - if (*size vout-buffer_size) { + if (*size vid_max_buf_size) { v4l2_err(vout-vid_dev-v4l2_dev, buffer allocation mismatch [%u] [%u]\n, *size, vout-buffer_size); -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 3/5] OMAP_VOUT: Fix VSYNC IRQ handling in omap_vout_isr
Currently, in omap_vout_isr(), if the panel type is DPI, and if we get either VSYNC or VSYNC2 interrupts, we proceed ahead to set the current buffers state to VIDEOBUF_DONE and prepare to display the next frame in the queue. On OMAP4, because we have 2 LCD managers, the panel type itself is not sufficient to tell if we have received the correct irq, i.e, we shouldn't proceed ahead if we get a VSYNC interrupt for LCD2 manager, or a VSYNC2 interrupt for LCD manager. Fix this by correlating LCD manager to VSYNC interrupt and LCD2 manager to VSYNC2 interrupt. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c | 14 +++--- 1 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 247ea31..6bc2620 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -566,8 +566,8 @@ err: static void omap_vout_isr(void *arg, unsigned int irqstatus) { - int ret, fid; - u32 addr; + int ret, fid, mgr_id; + u32 addr, irq; struct omap_overlay *ovl; struct timeval timevalue; struct omapvideo_info *ovid; @@ -583,6 +583,7 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) if (!ovl-manager || !ovl-manager-device) return; + mgr_id = ovl-manager-id; cur_display = ovl-manager-device; spin_lock(vout-vbq_lock); @@ -590,7 +591,14 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) switch (cur_display-type) { case OMAP_DISPLAY_TYPE_DPI: - if (!(irqstatus (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) + if (mgr_id == OMAP_DSS_CHANNEL_LCD) + irq = DISPC_IRQ_VSYNC; + else if (mgr_id == OMAP_DSS_CHANNEL_LCD2) + irq = DISPC_IRQ_VSYNC2; + else + goto vout_isr_err; + + if (!(irqstatus irq)) goto vout_isr_err; break; case OMAP_DISPLAY_TYPE_VENC: -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 2/5] OMAP_VOUT: CLEANUP: Remove redundant code from omap_vout_isr
Currently, there is a lot of redundant code is between DPI and VENC panels, this can be made common by moving out field/interlace specific code to a separate function called omapvid_handle_interlace_display(). There is no functional change made. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c | 172 -- 1 files changed, 82 insertions(+), 90 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index e64a83c..247ea31 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -524,10 +524,50 @@ static int omapvid_apply_changes(struct omap_vout_device *vout) return 0; } +static int omapvid_handle_interlace_display(struct omap_vout_device *vout, + unsigned int irqstatus, struct timeval timevalue) +{ + u32 fid; + + if (vout-first_int) { + vout-first_int = 0; + goto err; + } + + if (irqstatus DISPC_IRQ_EVSYNC_ODD) + fid = 1; + else if (irqstatus DISPC_IRQ_EVSYNC_EVEN) + fid = 0; + else + goto err; + + vout-field_id ^= 1; + if (fid != vout-field_id) { + if (fid == 0) + vout-field_id = fid; + } else if (0 == fid) { + if (vout-cur_frm == vout-next_frm) + goto err; + + vout-cur_frm-ts = timevalue; + vout-cur_frm-state = VIDEOBUF_DONE; + wake_up_interruptible(vout-cur_frm-done); + vout-cur_frm = vout-next_frm; + } else { + if (list_empty(vout-dma_queue) || + (vout-cur_frm != vout-next_frm)) + goto err; + } + + return vout-field_id; +err: + return 0; +} + static void omap_vout_isr(void *arg, unsigned int irqstatus) { - int ret; - u32 addr, fid; + int ret, fid; + u32 addr; struct omap_overlay *ovl; struct timeval timevalue; struct omapvideo_info *ovid; @@ -548,107 +588,59 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) spin_lock(vout-vbq_lock); do_gettimeofday(timevalue); - if (cur_display-type != OMAP_DISPLAY_TYPE_VENC) { - switch (cur_display-type) { - case OMAP_DISPLAY_TYPE_DPI: - if (!(irqstatus (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) - goto vout_isr_err; - break; - case OMAP_DISPLAY_TYPE_HDMI: - if (!(irqstatus DISPC_IRQ_EVSYNC_EVEN)) - goto vout_isr_err; - break; - default: + switch (cur_display-type) { + case OMAP_DISPLAY_TYPE_DPI: + if (!(irqstatus (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) goto vout_isr_err; - } - if (!vout-first_int (vout-cur_frm != vout-next_frm)) { - vout-cur_frm-ts = timevalue; - vout-cur_frm-state = VIDEOBUF_DONE; - wake_up_interruptible(vout-cur_frm-done); - vout-cur_frm = vout-next_frm; - } - vout-first_int = 0; - if (list_empty(vout-dma_queue)) + break; + case OMAP_DISPLAY_TYPE_VENC: + fid = omapvid_handle_interlace_display(vout, irqstatus, + timevalue); + if (!fid) goto vout_isr_err; + break; + case OMAP_DISPLAY_TYPE_HDMI: + if (!(irqstatus DISPC_IRQ_EVSYNC_EVEN)) + goto vout_isr_err; + break; + default: + goto vout_isr_err; + } - vout-next_frm = list_entry(vout-dma_queue.next, - struct videobuf_buffer, queue); - list_del(vout-next_frm-queue); - - vout-next_frm-state = VIDEOBUF_ACTIVE; - - addr = (unsigned long) vout-queued_buf_addr[vout-next_frm-i] - + vout-cropped_offset; + if (!vout-first_int (vout-cur_frm != vout-next_frm)) { + vout-cur_frm-ts = timevalue; + vout-cur_frm-state = VIDEOBUF_DONE; + wake_up_interruptible(vout-cur_frm-done); + vout-cur_frm = vout-next_frm; + } - /* First save the configuration in ovelray structure */ - ret = omapvid_init(vout, addr); - if (ret) - printk(KERN_ERR VOUT_NAME - failed to set overlay info\n); - /* Enable the pipeline and set the Go bit */ - ret = omapvid_apply_changes(vout); - if (ret) - printk(KERN_ERR
[PATCH v4 4/5] OMAP_VOUT: Add support for DSI panels
Add support for DSI panels. DSI video mode panels will work directly. For command mode panels, we will need to trigger updates regularly. This isn't done by the omap_vout driver currently. It can still be supported if we connect a framebuffer device to the panel and configure it in auto update mode. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 6bc2620..65374b5 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -590,6 +590,7 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) do_gettimeofday(timevalue); switch (cur_display-type) { + case OMAP_DISPLAY_TYPE_DSI: case OMAP_DISPLAY_TYPE_DPI: if (mgr_id == OMAP_DSS_CHANNEL_LCD) irq = DISPC_IRQ_VSYNC; -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 5/5] OMAP_VOUT: Increase MAX_DISPLAYS to a larger value
There is no limit to the number of displays that can registered with DSS2. The current value of MAX_DISPLAYS is 3, set this to 10 so that the 'displays' member of omap2video_device struct can store more omap_dss_device pointers. This fixes a crash seen in omap_vout_probe when DSS2 registers for more than 3 displays. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_voutdef.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/media/video/omap/omap_voutdef.h b/drivers/media/video/omap/omap_voutdef.h index d793501..27a95d2 100644 --- a/drivers/media/video/omap/omap_voutdef.h +++ b/drivers/media/video/omap/omap_voutdef.h @@ -25,7 +25,7 @@ #define MAC_VRFB_CTXS 4 #define MAX_VOUT_DEV 2 #define MAX_OVLS 3 -#define MAX_DISPLAYS 3 +#define MAX_DISPLAYS 10 #define MAX_MANAGERS 3 #define QQVGA_WIDTH160 -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/5] [media]: OMAP_VOUT: Fix VSYNC IRQ handling in omap_vout_isr
On Tuesday 27 September 2011 12:24 PM, Hiremath, Vaibhav wrote: -Original Message- From: Valkeinen, Tomi Sent: Tuesday, September 27, 2011 12:19 PM To: Hiremath, Vaibhav Cc: Semwal, Sumit; Taneja, Archit; linux-omap@vger.kernel.org; linux- me...@vger.kernel.org Subject: RE: [PATCH 3/5] [media]: OMAP_VOUT: Fix VSYNC IRQ handling in omap_vout_isr On Tue, 2011-09-27 at 12:09 +0530, Hiremath, Vaibhav wrote: Please look at the patch carefully, it does exactly same thing. I understand the use-case what Archit explained in the last email but in this patch context, the use-case change anything here in this patch. With the current code, the ISR code will be ran for a panel connected to LCD1 output when VSYNC for LCD2 happens. After Archit's patch, this no longer happens. I don't know what the ISR code does, so it may not cause any problems, but it sure doesn't sound right running the code when a wrong interrupt happens. If you look at the patch, the patch barely checks for the condition and makes sure that the interrupt is either of VSYNC or VSYNC2, else return. Rest everything is same. It doesn't only make sure that the interrupt it one of them, it uses it later too in the check: if (!(irqstatus irq)) goto vout_isr_err; ... ... The right fix is in streamon api, where you mask the interrupt before registering it. If this is the right fix, we should have a purely selective method of selecting the interrupts. Even for OMAP3, we register interrupts for LCD and TV, and then check the interrupt in the handler using panel type. Now, since have 2 different interrupts for the same panel type, we have to further distinguish using the manager id. Archit Thanks, Vaibhav Tomi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 4/4] OMAP_VOUT: Don't trigger updates in omap_vout_probe
On Tuesday 27 September 2011 11:40 AM, Valkeinen, Tomi wrote: On Mon, 2011-09-26 at 17:29 +0530, Archit Taneja wrote: Remove the code in omap_vout_probe() which calls display-driver-update() for all the displays. This isn't correct because: - An update in probe doesn't make sense, because we don't have any valid content to show at this time. - Calling update for a panel which isn't enabled is not supported by DSS2. This leads to a crash at probe. Calling update() on a disabled panel should not crash... Where is the crash coming from? you are right, the crash isn't coming from the updates. I see the crash when we have 4 dss devices in our board file. The last display pointer is corrupted in that case. I'm trying to figure out why. Archit Tomi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 4/4] OMAP_VOUT: Don't trigger updates in omap_vout_probe
On Tuesday 27 September 2011 12:37 PM, Valkeinen, Tomi wrote: On Tue, 2011-09-27 at 12:32 +0530, Archit Taneja wrote: On Tuesday 27 September 2011 11:40 AM, Valkeinen, Tomi wrote: On Mon, 2011-09-26 at 17:29 +0530, Archit Taneja wrote: Remove the code in omap_vout_probe() which calls display-driver-update() for all the displays. This isn't correct because: - An update in probe doesn't make sense, because we don't have any valid content to show at this time. - Calling update for a panel which isn't enabled is not supported by DSS2. This leads to a crash at probe. Calling update() on a disabled panel should not crash... Where is the crash coming from? you are right, the crash isn't coming from the updates. I see the crash when we have 4 dss devices in our board file. The last display pointer is corrupted in that case. I'm trying to figure out why. Could be totally unrelated, but does the V4L2 driver make sure that the used dss devices have a driver loaded? OMAPFB previously refused to start if all the devices do not have a driver, but nowadays it starts fine by skipping the devices without a driver. The drivers were loaded in. The issue was something else totally. I assumed it was something related to update call. In drivers/media/video/omap/omap_voutdef.h: struct omap2video_device { ... ... struct omap_dss_device *displays[MAX_DISPLAYS]; ... ... }; MAX_DISPLAYS is 3, so the 4th display pointer was getting messed up wherever we used it. I guess we don't need this patch. We may want to set MAX_DISPLAYS to a higher number i guess, because we could theoretically register as many panels as we want, and set/unset them. Thanks, Archit Tomi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/4] OMAP_VOUT: Fix check in reqbuf for buf_size allocation
Hi, On Tuesday 27 September 2011 12:49 PM, Hiremath, Vaibhav wrote: -Original Message- From: Taneja, Archit Sent: Monday, September 26, 2011 5:29 PM To: Hiremath, Vaibhav Cc: Valkeinen, Tomi; linux-omap@vger.kernel.org; Semwal, Sumit; linux- me...@vger.kernel.org; Taneja, Archit Subject: [PATCH v3 1/4] OMAP_VOUT: Fix check in reqbuf for buf_size allocation The commit 383e4f69879d11c86ebdd38b3356f6d0690fb4cc makes reqbuf prevent requesting a larger size buffer than what is allocated at kernel boot during omap_vout_probe. The requested size is compared with vout-buffer_size, this isn't correct as vout-buffer_size is later set to the size requested in reqbuf. When the video device is opened the next time, this check will prevent us to allocate a buffer which is larger than what we requested the last time. Don't use vout-buffer_size, always check with the parameters video1_bufsize or video2_bufsize. Signed-off-by: Archit Tanejaarc...@ti.com --- drivers/media/video/omap/omap_vout.c | 10 -- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index d9e64f3..16ebff6 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -664,10 +664,14 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, u32 phy_addr = 0, virt_addr = 0; struct omap_vout_device *vout = q-priv_data; struct omapvideo_info *ovid =vout-vid_info; + int vid_max_buf_size; if (!vout) return -EINVAL; + vid_max_buf_size = vout-vid == OMAP_VIDEO1 ? video1_bufsize : + video2_bufsize; + if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q-type) return -EINVAL; @@ -690,7 +694,7 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, video1_numbuffers : video2_numbuffers; /* Check the size of the buffer */ - if (*size vout-buffer_size) { + if (*size vid_max_buf_size) { v4l2_err(vout-vid_dev-v4l2_dev, buffer allocation mismatch [%u] [%u]\n, *size, vout-buffer_size); @@ -865,6 +869,8 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma) unsigned long size = (vma-vm_end - vma-vm_start); struct omap_vout_device *vout = file-private_data; struct videobuf_queue *q =vout-vbq; + int vid_max_buf_size = vout-vid == OMAP_VIDEO1 ? video1_bufsize : + video2_bufsize; v4l2_dbg(1, debug,vout-vid_dev-v4l2_dev, %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n, __func__, @@ -887,7 +893,7 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma) return -EINVAL; } /* Check the size of the buffer */ - if (size vout-buffer_size) { + if (size vid_max_buf_size) { I think we agreed in your last version patch patch-series that, the check in mmap should be against vout-buffer_size. Am I missing something here? I totally missed this out for some reason. I'll correct this in the next set. Sorry about this. Archit Thanks, Vaibhav v4l2_err(vout-vid_dev-v4l2_dev, insufficient memory [%lu] [%u]\n, size, vout-buffer_size); -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 3/3] OMAPDSS/OMAP_VOUT: Fix incorrect OMAP3-alpha compatibility setting
On OMAP3, in order to enable alpha blending for LCD and TV managers, we needed to set LCDALPHABLENDERENABLE/TVALPHABLENDERENABLE bits in DISPC_CONFIG. On OMAP4, alpha blending is always enabled by default, if the above bits are set, we switch to an OMAP3 compatibility mode where the zorder values in the pipeline attribute registers are ignored and a fixed priority is configured. Rename the manager_info member alpha_enabled to partial_alpha_enabled for more clarity. Introduce two dss_features FEAT_ALPHA_FIXED_ZORDER and FEAT_ALPHA_FREE_ZORDER which represent OMAP3-alpha compatibility mode and OMAP4 alpha mode respectively. Introduce an overlay cap for ZORDER. The DSS2 user is expected to check for the ZORDER cap, if an overlay doesn't have this cap, the user is expected to set the parameter partial_alpha_enabled. If the overlay has ZORDER cap, the DSS2 user can assume that alpha blending is already enabled. Don't support OMAP3 compatibility mode for now. Trying to read/write to alpha_blending_enabled sysfs attribute issues a warning for OMAP4 and does not set the LCDALPHABLENDERENABLE/TVALPHABLENDERENABLE bits. Change alpha_enabled to partial_alpha_enabled in the omap_vout driver. Use overlay cap OMAP_DSS_OVL_CAP_GLOBAL_ALPHA to check if overlay supports alpha blending or not. Replace this with checks for VIDEO1 pipeline. Cc: linux-me...@vger.kernel.org Cc: Lajos Molnar mol...@ti.com Signed-off-by: Archit Taneja arc...@ti.com --- Changes in v3: - Fix some spelling mistakes in commit message. - Add comment about video1 limitation in omap_vout . drivers/media/video/omap/omap_vout.c | 17 - drivers/video/omap2/dss/dispc.c| 24 drivers/video/omap2/dss/dss.h |4 ++-- drivers/video/omap2/dss/dss_features.c | 22 +++--- drivers/video/omap2/dss/dss_features.h |3 ++- drivers/video/omap2/dss/manager.c | 28 +++- include/video/omapdss.h|3 ++- 7 files changed, 60 insertions(+), 41 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index b3a5ecd..d9e64f3 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -1165,12 +1165,17 @@ static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, { int ret = 0; struct omap_vout_device *vout = fh; + struct omap_overlay *ovl; + struct omapvideo_info *ovid; struct v4l2_window *win = f-fmt.win; + ovid = vout-vid_info; + ovl = ovid-overlays[0]; + ret = omap_vout_try_window(vout-fbuf, win); if (!ret) { - if (vout-vid == OMAP_VIDEO1) + if ((ovl-caps OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) win-global_alpha = 255; else win-global_alpha = f-fmt.win.global_alpha; @@ -1194,8 +1199,8 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh, ret = omap_vout_new_window(vout-crop, vout-win, vout-fbuf, win); if (!ret) { - /* Video1 plane does not support global alpha */ - if (ovl-id == OMAP_DSS_VIDEO1) + /* Video1 plane does not support global alpha on OMAP3 */ + if ((ovl-caps OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) vout-win.global_alpha = 255; else vout-win.global_alpha = f-fmt.win.global_alpha; @@ -1788,7 +1793,9 @@ static int vidioc_s_fbuf(struct file *file, void *fh, if (ovl-manager ovl-manager-get_manager_info ovl-manager-set_manager_info) { ovl-manager-get_manager_info(ovl-manager, info); - info.alpha_enabled = enable; + /* enable this only if there is no zorder cap */ + if ((ovl-caps OMAP_DSS_OVL_CAP_ZORDER) == 0) + info.partial_alpha_enabled = enable; if (ovl-manager-set_manager_info(ovl-manager, info)) return -EINVAL; } @@ -1820,7 +1827,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh, } if (ovl-manager ovl-manager-get_manager_info) { ovl-manager-get_manager_info(ovl-manager, info); - if (info.alpha_enabled) + if (info.partial_alpha_enabled) a-flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; } diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 5e6849e..e0639d3 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -179,7 +179,8 @@ static void dispc_save_context(void) SR(CONTROL); SR(CONFIG); SR(LINE_NUMBER); - if (dss_has_feature(FEAT_GLOBAL_ALPHA)) + if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) || + dss_has_feature(FEAT_ALPHA_FREE_ZORDER)) SR
[PATCH v2 0/5] [media]: OMAP_VOUT: Misc fixes and cleanup patches for 3.2
This set includes patches which do the following: - Fix crash if a we call dssdev-driver-update for a disabled panel. - Fix the issue of not being able to request for a buffer which is larger than what we did the last time. - Fix a small bug in omap_vout_isr() - Remove some redundant code in omap_vout_isr() - Add basic support for DSI panels Changes in v2: - Add fid == 0 check in CLEANUP: Remove redundant code from omap_vout_isr for more clarity. - Use vout-buffer_size as done originally for mmap in Fix check in reqbuf for buf_size allocation Refernce base: g...@gitorious.org:~boddob/linux-omap-dss2/archit-dss2-clone.git 'for_omap_vout2' Archit Taneja (5): OMAP_VOUT: Fix check in reqbuf for buf_size allocation OMAP_VOUT: CLEANUP: Remove redundant code from omap_vout_isr OMAP_VOUT: Fix VSYNC IRQ handling in omap_vout_isr OMAP_VOUT: Add support for DSI panels OMAP_VOUT: Don't trigger updates in omap_vout_probe drivers/media/video/omap/omap_vout.c | 199 +- 1 files changed, 99 insertions(+), 100 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/5] OMAP_VOUT: Fix check in reqbuf for buf_size allocation
The commit 383e4f69879d11c86ebdd38b3356f6d0690fb4cc makes reqbuf prevent requesting a larger size buffer than what is allocated at kernel boot during omap_vout_probe. The requested size is compared with vout-buffer_size, this isn't correct as vout-buffer_size is later set to the size requested in reqbuf. When the video device is opened the next time, this check will prevent us to allocate a buffer which is larger than what we requested the last time. Don't use vout-buffer_size, always check with the parameters video1_bufsize or video2_bufsize. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c | 10 -- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index d9e64f3..16ebff6 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -664,10 +664,14 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, u32 phy_addr = 0, virt_addr = 0; struct omap_vout_device *vout = q-priv_data; struct omapvideo_info *ovid = vout-vid_info; + int vid_max_buf_size; if (!vout) return -EINVAL; + vid_max_buf_size = vout-vid == OMAP_VIDEO1 ? video1_bufsize : + video2_bufsize; + if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q-type) return -EINVAL; @@ -690,7 +694,7 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, video1_numbuffers : video2_numbuffers; /* Check the size of the buffer */ - if (*size vout-buffer_size) { + if (*size vid_max_buf_size) { v4l2_err(vout-vid_dev-v4l2_dev, buffer allocation mismatch [%u] [%u]\n, *size, vout-buffer_size); @@ -865,6 +869,8 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma) unsigned long size = (vma-vm_end - vma-vm_start); struct omap_vout_device *vout = file-private_data; struct videobuf_queue *q = vout-vbq; + int vid_max_buf_size = vout-vid == OMAP_VIDEO1 ? video1_bufsize : + video2_bufsize; v4l2_dbg(1, debug, vout-vid_dev-v4l2_dev, %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n, __func__, @@ -887,7 +893,7 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma) return -EINVAL; } /* Check the size of the buffer */ - if (size vout-buffer_size) { + if (size vid_max_buf_size) { v4l2_err(vout-vid_dev-v4l2_dev, insufficient memory [%lu] [%u]\n, size, vout-buffer_size); -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/5] OMAP_VOUT: CLEANUP: Remove redundant code from omap_vout_isr
Currently, there is a lot of redundant code is between DPI and VENC panels, this can be made common by moving out field/interlace specific code to a separate function called omapvid_handle_interlace_display(). There is no functional change made. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c | 172 -- 1 files changed, 82 insertions(+), 90 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 16ebff6..01c24a4 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -524,10 +524,50 @@ static int omapvid_apply_changes(struct omap_vout_device *vout) return 0; } +static int omapvid_handle_interlace_display(struct omap_vout_device *vout, + unsigned int irqstatus, struct timeval timevalue) +{ + u32 fid; + + if (vout-first_int) { + vout-first_int = 0; + goto err; + } + + if (irqstatus DISPC_IRQ_EVSYNC_ODD) + fid = 1; + else if (irqstatus DISPC_IRQ_EVSYNC_EVEN) + fid = 0; + else + goto err; + + vout-field_id ^= 1; + if (fid != vout-field_id) { + if (fid == 0) + vout-field_id = fid; + } else if (0 == fid) { + if (vout-cur_frm == vout-next_frm) + goto err; + + vout-cur_frm-ts = timevalue; + vout-cur_frm-state = VIDEOBUF_DONE; + wake_up_interruptible(vout-cur_frm-done); + vout-cur_frm = vout-next_frm; + } else { + if (list_empty(vout-dma_queue) || + (vout-cur_frm != vout-next_frm)) + goto err; + } + + return vout-field_id; +err: + return 0; +} + static void omap_vout_isr(void *arg, unsigned int irqstatus) { - int ret; - u32 addr, fid; + int ret, fid; + u32 addr; struct omap_overlay *ovl; struct timeval timevalue; struct omapvideo_info *ovid; @@ -548,107 +588,59 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) spin_lock(vout-vbq_lock); do_gettimeofday(timevalue); - if (cur_display-type != OMAP_DISPLAY_TYPE_VENC) { - switch (cur_display-type) { - case OMAP_DISPLAY_TYPE_DPI: - if (!(irqstatus (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) - goto vout_isr_err; - break; - case OMAP_DISPLAY_TYPE_HDMI: - if (!(irqstatus DISPC_IRQ_EVSYNC_EVEN)) - goto vout_isr_err; - break; - default: + switch (cur_display-type) { + case OMAP_DISPLAY_TYPE_DPI: + if (!(irqstatus (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) goto vout_isr_err; - } - if (!vout-first_int (vout-cur_frm != vout-next_frm)) { - vout-cur_frm-ts = timevalue; - vout-cur_frm-state = VIDEOBUF_DONE; - wake_up_interruptible(vout-cur_frm-done); - vout-cur_frm = vout-next_frm; - } - vout-first_int = 0; - if (list_empty(vout-dma_queue)) + break; + case OMAP_DISPLAY_TYPE_VENC: + fid = omapvid_handle_interlace_display(vout, irqstatus, + timevalue); + if (!fid) goto vout_isr_err; + break; + case OMAP_DISPLAY_TYPE_HDMI: + if (!(irqstatus DISPC_IRQ_EVSYNC_EVEN)) + goto vout_isr_err; + break; + default: + goto vout_isr_err; + } - vout-next_frm = list_entry(vout-dma_queue.next, - struct videobuf_buffer, queue); - list_del(vout-next_frm-queue); - - vout-next_frm-state = VIDEOBUF_ACTIVE; - - addr = (unsigned long) vout-queued_buf_addr[vout-next_frm-i] - + vout-cropped_offset; + if (!vout-first_int (vout-cur_frm != vout-next_frm)) { + vout-cur_frm-ts = timevalue; + vout-cur_frm-state = VIDEOBUF_DONE; + wake_up_interruptible(vout-cur_frm-done); + vout-cur_frm = vout-next_frm; + } - /* First save the configuration in ovelray structure */ - ret = omapvid_init(vout, addr); - if (ret) - printk(KERN_ERR VOUT_NAME - failed to set overlay info\n); - /* Enable the pipeline and set the Go bit */ - ret = omapvid_apply_changes(vout); - if (ret) - printk(KERN_ERR
[PATCH v2 3/5] OMAP_VOUT: Fix VSYNC IRQ handling in omap_vout_isr
Currently, in omap_vout_isr(), if the panel type is DPI, and if we get either VSYNC or VSYNC2 interrupts, we proceed ahead to set the current buffers state to VIDEOBUF_DONE and prepare to display the next frame in the queue. On OMAP4, because we have 2 LCD managers, the panel type itself is not sufficient to tell if we have received the correct irq, i.e, we shouldn't proceed ahead if we get a VSYNC interrupt for LCD2 manager, or a VSYNC2 interrupt for LCD manager. Fix this by correlating LCD manager to VSYNC interrupt and LCD2 manager to VSYNC2 interrupt. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c | 14 +++--- 1 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 01c24a4..a0ca5f5 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -566,8 +566,8 @@ err: static void omap_vout_isr(void *arg, unsigned int irqstatus) { - int ret, fid; - u32 addr; + int ret, fid, mgr_id; + u32 addr, irq; struct omap_overlay *ovl; struct timeval timevalue; struct omapvideo_info *ovid; @@ -583,6 +583,7 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) if (!ovl-manager || !ovl-manager-device) return; + mgr_id = ovl-manager-id; cur_display = ovl-manager-device; spin_lock(vout-vbq_lock); @@ -590,7 +591,14 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) switch (cur_display-type) { case OMAP_DISPLAY_TYPE_DPI: - if (!(irqstatus (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) + if (mgr_id == OMAP_DSS_CHANNEL_LCD) + irq = DISPC_IRQ_VSYNC; + else if (mgr_id == OMAP_DSS_CHANNEL_LCD2) + irq = DISPC_IRQ_VSYNC2; + else + goto vout_isr_err; + + if (!(irqstatus irq)) goto vout_isr_err; break; case OMAP_DISPLAY_TYPE_VENC: -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 4/5] OMAP_VOUT: Add support for DSI panels
Add support for DSI panels. DSI video mode panels will work directly. For command mode panels, we will need to trigger updates regularly. This isn't done by the omap_vout driver currently. It can still be supported if we connect a framebuffer device to the panel and configure it in auto update mode. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index a0ca5f5..df0713c 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -590,6 +590,7 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) do_gettimeofday(timevalue); switch (cur_display-type) { + case OMAP_DISPLAY_TYPE_DSI: case OMAP_DISPLAY_TYPE_DPI: if (mgr_id == OMAP_DSS_CHANNEL_LCD) irq = DISPC_IRQ_VSYNC; -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 5/5] OMAP_VOUT: Don't trigger updates in omap_vout_probe
Remove the code in omap_vout_probe() which calls display-driver-update() for all the displays. This isn't correct because: - An update in probe doesn't make sense, because we don't have any valid content to show at this time. - Calling update for a panel which isn't enabled is not supported by DSS2. This leads to a crash at probe. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c |8 1 files changed, 0 insertions(+), 8 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index df0713c..5473601 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -2221,14 +2221,6 @@ static int __init omap_vout_probe(struct platform_device *pdev) if (ret) goto probe_err2; - for (i = 0; i vid_dev-num_displays; i++) { - struct omap_dss_device *display = vid_dev-displays[i]; - - if (display-driver-update) - display-driver-update(display, 0, 0, - display-panel.timings.x_res, - display-panel.timings.y_res); - } return 0; probe_err2: -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 0/4] OMAP_VOUT: Misc fixes and cleanup patches for 3.2
This set includes patches which do the following: - Fix crash if a we call dssdev-driver-update for a disabled panel. - Fix the issue of not being able to request for a buffer which is larger than what we did the last time. - Remove some redundant code in omap_vout_isr() - Add basic support for DSI panels Changes in v3: - Remove patch OMAP_VOUT: Fix VSYNC IRQ handling in omap_vout_isr since its still not clear whether its needed or not. Refernce base: g...@gitorious.org:~boddob/linux-omap-dss2/archit-dss2-clone.git 'for_omap_vout2' Archit Taneja (4): OMAP_VOUT: Fix check in reqbuf for buf_size allocation OMAP_VOUT: CLEANUP: Remove redundant code from omap_vout_isr OMAP_VOUT: Add support for DSI panels OMAP_VOUT: Don't trigger updates in omap_vout_probe drivers/media/video/omap/omap_vout.c | 191 -- 1 files changed, 91 insertions(+), 100 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/4] OMAP_VOUT: Fix check in reqbuf for buf_size allocation
The commit 383e4f69879d11c86ebdd38b3356f6d0690fb4cc makes reqbuf prevent requesting a larger size buffer than what is allocated at kernel boot during omap_vout_probe. The requested size is compared with vout-buffer_size, this isn't correct as vout-buffer_size is later set to the size requested in reqbuf. When the video device is opened the next time, this check will prevent us to allocate a buffer which is larger than what we requested the last time. Don't use vout-buffer_size, always check with the parameters video1_bufsize or video2_bufsize. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c | 10 -- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index d9e64f3..16ebff6 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -664,10 +664,14 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, u32 phy_addr = 0, virt_addr = 0; struct omap_vout_device *vout = q-priv_data; struct omapvideo_info *ovid = vout-vid_info; + int vid_max_buf_size; if (!vout) return -EINVAL; + vid_max_buf_size = vout-vid == OMAP_VIDEO1 ? video1_bufsize : + video2_bufsize; + if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q-type) return -EINVAL; @@ -690,7 +694,7 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, video1_numbuffers : video2_numbuffers; /* Check the size of the buffer */ - if (*size vout-buffer_size) { + if (*size vid_max_buf_size) { v4l2_err(vout-vid_dev-v4l2_dev, buffer allocation mismatch [%u] [%u]\n, *size, vout-buffer_size); @@ -865,6 +869,8 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma) unsigned long size = (vma-vm_end - vma-vm_start); struct omap_vout_device *vout = file-private_data; struct videobuf_queue *q = vout-vbq; + int vid_max_buf_size = vout-vid == OMAP_VIDEO1 ? video1_bufsize : + video2_bufsize; v4l2_dbg(1, debug, vout-vid_dev-v4l2_dev, %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n, __func__, @@ -887,7 +893,7 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma) return -EINVAL; } /* Check the size of the buffer */ - if (size vout-buffer_size) { + if (size vid_max_buf_size) { v4l2_err(vout-vid_dev-v4l2_dev, insufficient memory [%lu] [%u]\n, size, vout-buffer_size); -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/4] OMAP_VOUT: CLEANUP: Remove redundant code from omap_vout_isr
Currently, there is a lot of redundant code is between DPI and VENC panels, this can be made common by moving out field/interlace specific code to a separate function called omapvid_handle_interlace_display(). There is no functional change made. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c | 172 -- 1 files changed, 82 insertions(+), 90 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 16ebff6..01c24a4 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -524,10 +524,50 @@ static int omapvid_apply_changes(struct omap_vout_device *vout) return 0; } +static int omapvid_handle_interlace_display(struct omap_vout_device *vout, + unsigned int irqstatus, struct timeval timevalue) +{ + u32 fid; + + if (vout-first_int) { + vout-first_int = 0; + goto err; + } + + if (irqstatus DISPC_IRQ_EVSYNC_ODD) + fid = 1; + else if (irqstatus DISPC_IRQ_EVSYNC_EVEN) + fid = 0; + else + goto err; + + vout-field_id ^= 1; + if (fid != vout-field_id) { + if (fid == 0) + vout-field_id = fid; + } else if (0 == fid) { + if (vout-cur_frm == vout-next_frm) + goto err; + + vout-cur_frm-ts = timevalue; + vout-cur_frm-state = VIDEOBUF_DONE; + wake_up_interruptible(vout-cur_frm-done); + vout-cur_frm = vout-next_frm; + } else { + if (list_empty(vout-dma_queue) || + (vout-cur_frm != vout-next_frm)) + goto err; + } + + return vout-field_id; +err: + return 0; +} + static void omap_vout_isr(void *arg, unsigned int irqstatus) { - int ret; - u32 addr, fid; + int ret, fid; + u32 addr; struct omap_overlay *ovl; struct timeval timevalue; struct omapvideo_info *ovid; @@ -548,107 +588,59 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) spin_lock(vout-vbq_lock); do_gettimeofday(timevalue); - if (cur_display-type != OMAP_DISPLAY_TYPE_VENC) { - switch (cur_display-type) { - case OMAP_DISPLAY_TYPE_DPI: - if (!(irqstatus (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) - goto vout_isr_err; - break; - case OMAP_DISPLAY_TYPE_HDMI: - if (!(irqstatus DISPC_IRQ_EVSYNC_EVEN)) - goto vout_isr_err; - break; - default: + switch (cur_display-type) { + case OMAP_DISPLAY_TYPE_DPI: + if (!(irqstatus (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) goto vout_isr_err; - } - if (!vout-first_int (vout-cur_frm != vout-next_frm)) { - vout-cur_frm-ts = timevalue; - vout-cur_frm-state = VIDEOBUF_DONE; - wake_up_interruptible(vout-cur_frm-done); - vout-cur_frm = vout-next_frm; - } - vout-first_int = 0; - if (list_empty(vout-dma_queue)) + break; + case OMAP_DISPLAY_TYPE_VENC: + fid = omapvid_handle_interlace_display(vout, irqstatus, + timevalue); + if (!fid) goto vout_isr_err; + break; + case OMAP_DISPLAY_TYPE_HDMI: + if (!(irqstatus DISPC_IRQ_EVSYNC_EVEN)) + goto vout_isr_err; + break; + default: + goto vout_isr_err; + } - vout-next_frm = list_entry(vout-dma_queue.next, - struct videobuf_buffer, queue); - list_del(vout-next_frm-queue); - - vout-next_frm-state = VIDEOBUF_ACTIVE; - - addr = (unsigned long) vout-queued_buf_addr[vout-next_frm-i] - + vout-cropped_offset; + if (!vout-first_int (vout-cur_frm != vout-next_frm)) { + vout-cur_frm-ts = timevalue; + vout-cur_frm-state = VIDEOBUF_DONE; + wake_up_interruptible(vout-cur_frm-done); + vout-cur_frm = vout-next_frm; + } - /* First save the configuration in ovelray structure */ - ret = omapvid_init(vout, addr); - if (ret) - printk(KERN_ERR VOUT_NAME - failed to set overlay info\n); - /* Enable the pipeline and set the Go bit */ - ret = omapvid_apply_changes(vout); - if (ret) - printk(KERN_ERR
[PATCH v3 3/4] OMAP_VOUT: Add support for DSI panels
Add support for DSI panels. DSI video mode panels will work directly. For command mode panels, we will need to trigger updates regularly. This isn't done by the omap_vout driver currently. It can still be supported if we connect a framebuffer device to the panel and configure it in auto update mode. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 01c24a4..7b8e87a 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -589,6 +589,7 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) do_gettimeofday(timevalue); switch (cur_display-type) { + case OMAP_DISPLAY_TYPE_DSI: case OMAP_DISPLAY_TYPE_DPI: if (!(irqstatus (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) goto vout_isr_err; -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 4/4] OMAP_VOUT: Don't trigger updates in omap_vout_probe
Remove the code in omap_vout_probe() which calls display-driver-update() for all the displays. This isn't correct because: - An update in probe doesn't make sense, because we don't have any valid content to show at this time. - Calling update for a panel which isn't enabled is not supported by DSS2. This leads to a crash at probe. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c |8 1 files changed, 0 insertions(+), 8 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 7b8e87a..3d9c83e 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -2213,14 +2213,6 @@ static int __init omap_vout_probe(struct platform_device *pdev) if (ret) goto probe_err2; - for (i = 0; i vid_dev-num_displays; i++) { - struct omap_dss_device *display = vid_dev-displays[i]; - - if (display-driver-update) - display-driver-update(display, 0, 0, - display-panel.timings.x_res, - display-panel.timings.y_res); - } return 0; probe_err2: -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5] [media]: OMAP_VOUT: CLEANUP: Remove redundant code from omap_vout_isr
Hi, On Wednesday 21 September 2011 04:15 PM, Taneja, Archit wrote: Hi, On Wednesday 21 September 2011 03:35 PM, Hiremath, Vaibhav wrote: -Original Message- From: Taneja, Archit Sent: Friday, September 16, 2011 3:31 PM To: Hiremath, Vaibhav Cc: Valkeinen, Tomi; linux-omap@vger.kernel.org; Semwal, Sumit; linux- me...@vger.kernel.org; Taneja, Archit Subject: [PATCH 2/5] [media]: OMAP_VOUT: CLEANUP: Remove redundant code from omap_vout_isr Currently, there is a lot of redundant code is between DPI and VENC panels, this can be made common by moving out field/interlace specific code to a separate function called omapvid_handle_interlace_display(). There is no functional change made. Signed-off-by: Archit Tanejaarc...@ti.com --- drivers/media/video/omap/omap_vout.c | 172 - - [Hiremath, Vaibhav] Have you tested TV out functionality? I haven't checked it yet to be totally honest. Its hard to find a VENC TV! I wanted to anyway get some kind of Ack from you before starting to test this. Since you also feel that this clean up is needed, I'll start testing this out :) I tested the TV out functionality. It works fine. I have left the extra fid == 0 check so that the code is more clear. Will post out the new patch soon. Archit -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/5] [media]: OMAP_VOUT: Fix VSYNC IRQ handling in omap_vout_isr
Hi, On Wednesday 21 September 2011 07:04 PM, Hiremath, Vaibhav wrote: -Original Message- From: Taneja, Archit Sent: Friday, September 16, 2011 3:31 PM To: Hiremath, Vaibhav Cc: Valkeinen, Tomi; linux-omap@vger.kernel.org; Semwal, Sumit; linux- me...@vger.kernel.org; Taneja, Archit Subject: [PATCH 3/5] [media]: OMAP_VOUT: Fix VSYNC IRQ handling in omap_vout_isr Currently, in omap_vout_isr(), if the panel type is DPI, and if we get either VSYNC or VSYNC2 interrupts, we proceed ahead to set the current buffers state to VIDEOBUF_DONE and prepare to display the next frame in the queue. On OMAP4, because we have 2 LCD managers, the panel type itself is not sufficient to tell if we have received the correct irq, i.e, we shouldn't proceed ahead if we get a VSYNC interrupt for LCD2 manager, or a VSYNC2 interrupt for LCD manager. Fix this by correlating LCD manager to VSYNC interrupt and LCD2 manager to VSYNC2 interrupt. Signed-off-by: Archit Tanejaarc...@ti.com --- drivers/media/video/omap/omap_vout.c | 14 +++--- 1 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index c5f2ea0..20638c3 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -566,8 +566,8 @@ err: static void omap_vout_isr(void *arg, unsigned int irqstatus) { - int ret, fid; - u32 addr; + int ret, fid, mgr_id; + u32 addr, irq; struct omap_overlay *ovl; struct timeval timevalue; struct omapvideo_info *ovid; @@ -583,6 +583,7 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) if (!ovl-manager || !ovl-manager-device) return; + mgr_id = ovl-manager-id; cur_display = ovl-manager-device; spin_lock(vout-vbq_lock); @@ -590,7 +591,14 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) switch (cur_display-type) { case OMAP_DISPLAY_TYPE_DPI: - if (!(irqstatus (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) + if (mgr_id == OMAP_DSS_CHANNEL_LCD) + irq = DISPC_IRQ_VSYNC; + else if (mgr_id == OMAP_DSS_CHANNEL_LCD2) + irq = DISPC_IRQ_VSYNC2; + else + goto vout_isr_err; + + if (!(irqstatus irq)) goto vout_isr_err; break; I understand what this patch meant for, but I am more curious to know What is value addition of this patch? if (!(irqstatus (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) Vs if (mgr_id == OMAP_DSS_CHANNEL_LCD) irq = DISPC_IRQ_VSYNC; else if (mgr_id == OMAP_DSS_CHANNEL_LCD2) irq = DISPC_IRQ_VSYNC2; Isn't this same, because we are not doing anything separate and special for VSYNC and VSYNC2? Consider a use case where the primary LCD panel(connected to LCD manager) is configured at a 60 Hz refresh rate, and the secondary panel(connected to LCD2) refreshes at 30 Hz. Let the overlay configuration be something like this: /dev/video1-overlay1-LCD manager-Primary panel(60 Hz) /dev/video2-overlay2-LCD2 manager-Secondary Panel(30 Hz) Now if we are doing streaming on both video1 and video2, since we deque on either VSYNC or VSYNC2, video2 buffers will deque faster than the panels refresh, which is incorrect. So for video2, we should only deque when we get a VSYNC2 interrupt. Thats why there is a need to correlate the interrupt and the overlay manager. Regards, Archit Thanks, Vaibhav case OMAP_DISPLAY_TYPE_VENC: -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5] [media]: OMAP_VOUT: CLEANUP: Remove redundant code from omap_vout_isr
Hi, On Wednesday 21 September 2011 03:35 PM, Hiremath, Vaibhav wrote: -Original Message- From: Taneja, Archit Sent: Friday, September 16, 2011 3:31 PM To: Hiremath, Vaibhav Cc: Valkeinen, Tomi; linux-omap@vger.kernel.org; Semwal, Sumit; linux- me...@vger.kernel.org; Taneja, Archit Subject: [PATCH 2/5] [media]: OMAP_VOUT: CLEANUP: Remove redundant code from omap_vout_isr Currently, there is a lot of redundant code is between DPI and VENC panels, this can be made common by moving out field/interlace specific code to a separate function called omapvid_handle_interlace_display(). There is no functional change made. Signed-off-by: Archit Tanejaarc...@ti.com --- drivers/media/video/omap/omap_vout.c | 172 - - 1 files changed, 82 insertions(+), 90 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index e14c82b..c5f2ea0 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -524,10 +524,50 @@ static int omapvid_apply_changes(struct omap_vout_device *vout) return 0; } +static int omapvid_handle_interlace_display(struct omap_vout_device *vout, + unsigned int irqstatus, struct timeval timevalue) +{ + u32 fid; + + if (vout-first_int) { + vout-first_int = 0; + goto err; + } + + if (irqstatus DISPC_IRQ_EVSYNC_ODD) + fid = 1; + else if (irqstatus DISPC_IRQ_EVSYNC_EVEN) + fid = 0; + else + goto err; + + vout-field_id ^= 1; + if (fid != vout-field_id) { + /* reset field ID */ + vout-field_id = 0; [Hiremath, Vaibhav] You should check whether fid == 0 before resetting it. + } else if (0 == fid) { [Hiremath, Vaibhav] This is not matching with the original code, probably I have to be more careful here. I need to spend more time here... If you do a dry run of it you'll see that it does the same thing functionally. If fid was 1, vout-field_id would have been 0 anyway. So the check for fid == 0 looked a bit redundant to me. However, if you think that doing this makes the code less clear, we can surely keep this check. + if (vout-cur_frm == vout-next_frm) + goto err; + + vout-cur_frm-ts = timevalue; + vout-cur_frm-state = VIDEOBUF_DONE; + wake_up_interruptible(vout-cur_frm-done); + vout-cur_frm = vout-next_frm; + } else { + if (list_empty(vout-dma_queue) || + (vout-cur_frm != vout-next_frm)) + goto err; + } + + return vout-field_id; +err: + return 0; +} + static void omap_vout_isr(void *arg, unsigned int irqstatus) { - int ret; - u32 addr, fid; + int ret, fid; + u32 addr; struct omap_overlay *ovl; struct timeval timevalue; struct omapvideo_info *ovid; @@ -548,107 +588,59 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) spin_lock(vout-vbq_lock); do_gettimeofday(timevalue); - if (cur_display-type != OMAP_DISPLAY_TYPE_VENC) { - switch (cur_display-type) { - case OMAP_DISPLAY_TYPE_DPI: - if (!(irqstatus (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) - goto vout_isr_err; - break; - case OMAP_DISPLAY_TYPE_HDMI: - if (!(irqstatus DISPC_IRQ_EVSYNC_EVEN)) - goto vout_isr_err; - break; - default: + switch (cur_display-type) { + case OMAP_DISPLAY_TYPE_DPI: + if (!(irqstatus (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2))) goto vout_isr_err; - } - if (!vout-first_int (vout-cur_frm != vout-next_frm)) { - vout-cur_frm-ts = timevalue; - vout-cur_frm-state = VIDEOBUF_DONE; - wake_up_interruptible(vout-cur_frm-done); - vout-cur_frm = vout-next_frm; - } - vout-first_int = 0; - if (list_empty(vout-dma_queue)) + break; + case OMAP_DISPLAY_TYPE_VENC: + fid = omapvid_handle_interlace_display(vout, irqstatus, + timevalue); + if (!fid) goto vout_isr_err; [Hiremath, Vaibhav] Have you tested TV out functionality? I haven't checked it yet to be totally honest. Its hard to find a VENC TV! I wanted to anyway get some kind of Ack from you before starting to test this. Since you also feel that this clean up is needed, I'll start testing this out :) + break; + case OMAP_DISPLAY_TYPE_HDMI: + if (!(irqstatus
Re: [PATCH 1/5] [media]: OMAP_VOUT: Fix check in reqbuf mmap for buf_size allocation
Hi, On Wednesday 21 September 2011 02:10 PM, Hiremath, Vaibhav wrote: -Original Message- From: Taneja, Archit Sent: Friday, September 16, 2011 3:30 PM To: Hiremath, Vaibhav Cc: Valkeinen, Tomi; linux-omap@vger.kernel.org; Semwal, Sumit; linux- me...@vger.kernel.org; Taneja, Archit Subject: [PATCH 1/5] [media]: OMAP_VOUT: Fix check in reqbuf mmap for buf_size allocation The commit 383e4f69879d11c86ebdd38b3356f6d0690fb4cc makes reqbuf and mmap prevent requesting a larger size buffer than what is allocated at kernel boot during omap_vout_probe. The requested size is compared with vout-buffer_size, this isn't correct as vout-buffer_size is later set to the size requested in reqbuf. When the video device is opened the next time, this check will prevent us to allocate a buffer which is larger than what we requested the last time. Don't use vout-buffer_size, always check with the parameters video1_bufsize or video2_bufsize. Signed-off-by: Archit Tanejaarc...@ti.com --- drivers/media/video/omap/omap_vout.c | 10 -- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 95daf98..e14c82b 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -664,10 +664,14 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, u32 phy_addr = 0, virt_addr = 0; struct omap_vout_device *vout = q-priv_data; struct omapvideo_info *ovid =vout-vid_info; + int vid_max_buf_size; if (!vout) return -EINVAL; + vid_max_buf_size = vout-vid == OMAP_VIDEO1 ? video1_bufsize : + video2_bufsize; + if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q-type) return -EINVAL; @@ -690,7 +694,7 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, video1_numbuffers : video2_numbuffers; /* Check the size of the buffer */ - if (*size vout-buffer_size) { + if (*size vid_max_buf_size) { Good catch !!! v4l2_err(vout-vid_dev-v4l2_dev, buffer allocation mismatch [%u] [%u]\n, *size, vout-buffer_size); @@ -865,6 +869,8 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma) unsigned long size = (vma-vm_end - vma-vm_start); struct omap_vout_device *vout = file-private_data; struct videobuf_queue *q =vout-vbq; + int vid_max_buf_size = vout-vid == OMAP_VIDEO1 ? video1_bufsize : + video2_bufsize; v4l2_dbg(1, debug,vout-vid_dev-v4l2_dev, %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n, __func__, @@ -887,7 +893,7 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma) return -EINVAL; } /* Check the size of the buffer */ - if (size vout-buffer_size) { + if (size vid_max_buf_size) { Don't you think in case of mmap we should still check for the vout-buffer_size, since this is the size user has requested in req_buf. Ah, you are right, the check for the maximum size should only be in the reqbuf path. vout-buffer_size would have been updated correctly at time of mmap. I'll change this back to vout-buffer_size. Thanks, Archit Thanks, Vaibhav v4l2_err(vout-vid_dev-v4l2_dev, insufficient memory [%lu] [%u]\n, size, vout-buffer_size); -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/3] OMAPDSS/OMAP_VOUT: Fix incorrect OMAP3-alpha compatibility setting
Hi, On Tuesday 20 September 2011 01:06 AM, Hiremath, Vaibhav wrote: -Original Message- From: Taneja, Archit Sent: Friday, September 16, 2011 12:09 PM To: Valkeinen, Tomi Cc: Hiremath, Vaibhav; linux-omap@vger.kernel.org; Taneja, Archit; linux- me...@vger.kernel.org; Molnar, Lajos Subject: [PATCH v2 1/3] OMAPDSS/OMAP_VOUT: Fix incorrect OMAP3-alpha compatibility setting [Hiremath, Vaibhav] Few minor comments below - On OMAP3, in order to enable alpha blending for LCD and TV managers, we needed to set LCDALPHABLENDERENABLE/TVALPHABLENDERENABLE bits in DISPC_CONFIG. On OMAP4, alpha blending is always enabled by default, if the above bits are set, we switch to an OMAP3 compatibility mode where the zorder values in the pipeline [Hiremath, Vaibhav] Spelling mistake??? Thanks, I'll fix this. attribute registers are ignored and a fixed priority is configured. Rename the manager_info member alpha_enabled to partial_alpha_enabled for more clarity. Introduce two dss_features FEAT_ALPHA_FIXED_ZORDER and FEAT_ALPHA_FREE_ZORDER which represent OMAP3-alpha compatibility mode and OMAP4 alpha mode respectively. Introduce an overlay cap for ZORDER. The DSS2 user is expected to check for the ZORDER cap, if an overlay doesn't have this cap, the user is expected to set the parameter partial_alpha_enabled. If the overlay has ZORDER cap, the DSS2 user can assume that alpha blending is already enabled. Don't support OMAP3 compatibility mode for now. Trying to read/write to alpha_blending_enabled sysfs attribute issues a warning for OMAP4 and does not set the LCDALPHABLENDERENABLE/TVALPHABLENDERENABLE bits. Change alpha_enabled to partial_alpha_enabled int the omap_vout driver. Use overlay cap OMAP_DSS_OVL_CAP_GLOBAL_ALPHA to check if overlay supports alpha blending or not. Replace this with checks for VIDEO1 pipeline. Initial patch was made by: Lajos Molnarmol...@ti.com [Hiremath, Vaibhav] I think you can put his sign-off as well and remove this line or move it below --- Okay, I'll wait for his comments, and then put his sign-off. Cc: linux-me...@vger.kernel.org Cc: Lajos Molnarmol...@ti.com Signed-off-by: Archit Tanejaarc...@ti.com --- drivers/media/video/omap/omap_vout.c | 16 +++- drivers/video/omap2/dss/dispc.c| 24 drivers/video/omap2/dss/dss.h |4 ++-- drivers/video/omap2/dss/dss_features.c | 22 +++--- drivers/video/omap2/dss/dss_features.h |3 ++- drivers/video/omap2/dss/manager.c | 28 +++ - include/video/omapdss.h|3 ++- 7 files changed, 59 insertions(+), 41 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index b3a5ecd..95daf98 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -1165,12 +1165,17 @@ static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, { int ret = 0; struct omap_vout_device *vout = fh; + struct omap_overlay *ovl; + struct omapvideo_info *ovid; struct v4l2_window *win =f-fmt.win; + ovid =vout-vid_info; + ovl = ovid-overlays[0]; + [Hiremath, Vaibhav] I think it will be helpful if you put some comment above this line on why video1, something like, /* * Global alpha is not supported on Video1 pipeline/overlay */ Sure, i'll add this comment. ret = omap_vout_try_window(vout-fbuf, win); if (!ret) { - if (vout-vid == OMAP_VIDEO1) + if ((ovl-caps OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) win-global_alpha = 255; else win-global_alpha = f-fmt.win.global_alpha; @@ -1194,8 +1199,7 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh, ret = omap_vout_new_window(vout-crop,vout-win,vout-fbuf, win); if (!ret) { - /* Video1 plane does not support global alpha */ - if (ovl-id == OMAP_DSS_VIDEO1) + if ((ovl-caps OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) vout-win.global_alpha = 255; else vout-win.global_alpha = f-fmt.win.global_alpha; @@ -1788,7 +1792,9 @@ static int vidioc_s_fbuf(struct file *file, void *fh, if (ovl-manager ovl-manager-get_manager_info ovl-manager-set_manager_info) { ovl-manager-get_manager_info(ovl-manager,info); - info.alpha_enabled = enable; + /* enable this only if there is no zorder cap */ + if ((ovl-caps OMAP_DSS_OVL_CAP_ZORDER) == 0) + info.partial_alpha_enabled = enable; if (ovl-manager-set_manager_info(ovl-manager,info)) return -EINVAL; } @@ -1820,7 +1826,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh, } if (ovl-manager ovl-manager-get_manager_info) {
Re: [PATCH v2 2/3] OMAPDSS: DISPC: VIDEO3 pipeline support
Hi, On Tuesday 20 September 2011 01:13 AM, Hiremath, Vaibhav wrote: -Original Message- From: Taneja, Archit Sent: Friday, September 16, 2011 12:09 PM To: Valkeinen, Tomi Cc: Hiremath, Vaibhav; linux-omap@vger.kernel.org; Taneja, Archit Subject: [PATCH v2 2/3] OMAPDSS: DISPC: VIDEO3 pipeline support Add support for VIDEO3 pipeline on OMAP4: - Add VIDEO3 pipeline information in dss_features and omapdss.h - Add VIDEO3 pipeline register coefficients in dispc.h - Create a new overlay structure corresponding to VIDEO3. - Make changes in dispc.c for VIDEO3 Signed-off-by: Archit Tanejaarc...@ti.com snip diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index e81271a..6a6c05d 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -25,7 +25,7 @@ #endif #define MAX_DSS_MANAGERS 3 -#define MAX_DSS_OVERLAYS 3 +#define MAX_DSS_OVERLAYS 4 [Hiremath, Vaibhav] Not related to this patch as such, but I think we should now get rid of these macros and use run-time mechanism. This macro is used within DSS2 to declare the size of some arrays. So a runtime mechanism isn't possible(unless we allocate the arrays dynamically itself, but they are used for trivial purposes, and won't be large in size, so I don't think that this is needed). We anyway use the function omap_dss_get_num_overlays() wherever possible. Overall this patch looks ok to me, I will test it tomorrow and will update you. Thanks, Archit Thanks, Vaibhav #define MAX_DSS_LCD_MANAGERS 2 #define MAX_NUM_DSI 2 diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index afb7583..11d21e3 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -615,6 +615,11 @@ void dss_init_overlays(struct platform_device *pdev) ovl-id = OMAP_DSS_VIDEO2; ovl-info.global_alpha = 255; break; + case 3: + ovl-name = vid3; + ovl-id = OMAP_DSS_VIDEO3; + ovl-info.global_alpha = 255; + break; } ovl-set_manager =omap_dss_set_manager; diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 5f0ce5e..1f12559 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -41,6 +41,8 @@ #define DISPC_IRQ_WAKEUP (1 16) #define DISPC_IRQ_SYNC_LOST2 (1 17) #define DISPC_IRQ_VSYNC2 (1 18) +#define DISPC_IRQ_VID3_END_WIN (1 19) +#define DISPC_IRQ_VID3_FIFO_UNDERFLOW(1 20) #define DISPC_IRQ_ACBIAS_COUNT_STAT2 (1 21) #define DISPC_IRQ_FRAMEDONE2 (1 22) #define DISPC_IRQ_FRAMEDONEWB(1 23) @@ -63,7 +65,8 @@ enum omap_display_type { enum omap_plane { OMAP_DSS_GFX= 0, OMAP_DSS_VIDEO1 = 1, - OMAP_DSS_VIDEO2 = 2 + OMAP_DSS_VIDEO2 = 2, + OMAP_DSS_VIDEO3 = 3, }; enum omap_channel { -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] OMAP2PLUS: DSS: Ensure DSS works correctly if display is enabled in bootloader
Hi Paul, On Monday 12 September 2011 12:38 PM, Taneja, Archit wrote: Resetting DISPC when a DISPC output is enabled causes the DSS to go into an inconsistent state. Thus if the bootloader has enabled a display, the hwmod code cannot reset the DISPC module just like that, but the outputs need to be disabled first. Add function dispc_disable_outputs() which disables all active overlay manager and ensure all frame transfers are completed. Modify omap_dss_reset() to call this function and clear DSS_CONTROL, DSS_SDI_CONTROL and DSS_PLL_CONTROL so that DSS is in a clean state when the DSS2 driver starts. This resolves the hang issue(caused by a L3 error during boot) seen on the beagle board C3, which has a factory bootloader that enables display. The issue is resolved with this patch. Is it possible to get this in for the next merge window? It applies over your branch hwmod_dss_fixes_3.2. Thanks, Archit Acked-by: Tomi Valkeinentomi.valkei...@ti.com Tested-by: R, Sricharanr.sricha...@ti.com Signed-off-by: Archit Tanejaarc...@ti.com --- v2: - Added more info in the commit message, fixed some typos. The patch depends on a HWMOD patch series which has been posted by Tomi, it can be tested by applying over the following branch: https://gitorious.org/linux-omap-dss2/linux/commits/master arch/arm/mach-omap2/display.c | 110 + 1 files changed, 110 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 93db7c1..eab81f4 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -30,6 +30,30 @@ #include control.h +#define DISPC_BASE_OMAP2 0x48050400 +#define DISPC_BASE_OMAP4 0x48041000 + +#define DISPC_REG(base, offset)(base + offset) + +#define DISPC_CONTROL 0x0040 +#define DISPC_CONTROL2 0x0238 +#define DISPC_IRQSTATUS0x0018 + +#define DSS_SYSCONFIG 0x10 +#define DSS_SYSSTATUS 0x14 +#define DSS_CONTROL0x40 +#define DSS_SDI_CONTROL0x44 +#define DSS_PLL_CONTROL0x48 + +#define LCD_EN_MASK(0x1 0) +#define DIGIT_EN_MASK (0x1 1) + +#define FRAMEDONE_IRQ_SHIFT0 +#define EVSYNC_EVEN_IRQ_SHIFT 2 +#define EVSYNC_ODD_IRQ_SHIFT 3 +#define FRAMEDONE2_IRQ_SHIFT 22 +#define FRAMEDONETV_IRQ_SHIFT 24 + static struct platform_device omap_display_device = { .name = omapdss, .id= -1, @@ -182,6 +206,78 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) return r; } +static void dispc_disable_outputs(void) +{ + u32 val, irq_mask, base; + bool lcd_en, digit_en, lcd2_en = false; + int i, num_mgrs; + + if (cpu_is_omap44xx()) { + base = DISPC_BASE_OMAP4; + num_mgrs = 3; + } else { + base = DISPC_BASE_OMAP2; + num_mgrs = 2; + } + + /* store value of LCDENABLE and DIGITENABLE bits */ + val = omap_readl(DISPC_REG(base, DISPC_CONTROL)); + lcd_en = val LCD_EN_MASK; + digit_en = val DIGIT_EN_MASK; + + /* store value of LCDENABLE for LCD2 */ + if (num_mgrs 2) { + val = omap_readl(DISPC_REG(base, DISPC_CONTROL2)); + lcd2_en = val LCD_EN_MASK; + } + + /* +* If any manager was enabled, we need to disable it before DSS clocks +* are disabled or DISPC module is reset +*/ + if (lcd_en || digit_en || lcd2_en) { + irq_mask = (lcd_en ? 1 : 0) FRAMEDONE_IRQ_SHIFT; + + if (cpu_is_omap44xx()) + irq_mask |= (digit_en ? 1 : 0) FRAMEDONETV_IRQ_SHIFT; + else + irq_mask |= (digit_en ? 1 : 0) EVSYNC_EVEN_IRQ_SHIFT | + (digit_en ? 1 : 0) EVSYNC_ODD_IRQ_SHIFT; + + irq_mask |= (lcd2_en ? 1 : 0) FRAMEDONE2_IRQ_SHIFT; + + /* +* clear any previous FRAMEDONE, FRAMEDONETV, EVSYNC_EVEN/ODD +* or FRAMEDONE2 interrupts +*/ + omap_writel(irq_mask, DISPC_REG(base, DISPC_IRQSTATUS)); + + /* disable LCD and TV managers */ + val = omap_readl(DISPC_REG(base, DISPC_CONTROL)); + val= ~(LCD_EN_MASK | DIGIT_EN_MASK); + omap_writel(val, DISPC_REG(base, DISPC_CONTROL)); + + /* disable LCD2 manager */ + if (num_mgrs 2) { + val = omap_readl(DISPC_REG(base, DISPC_CONTROL2)); + val= ~LCD_EN_MASK; + omap_writel(val, DISPC_REG(base, DISPC_CONTROL2)); + } + + i = 0; + while ((omap_readl(DISPC_REG(base, DISPC_IRQSTATUS)) irq_mask) != + irq_mask) { + i++; + if (i 100) { +
[PATCH v2 1/3] OMAPDSS/OMAP_VOUT: Fix incorrect OMAP3-alpha compatibility setting
On OMAP3, in order to enable alpha blending for LCD and TV managers, we needed to set LCDALPHABLENDERENABLE/TVALPHABLENDERENABLE bits in DISPC_CONFIG. On OMAP4, alpha blending is always enabled by default, if the above bits are set, we switch to an OMAP3 compatibility mode where the zorder values in the pipleine attribute registers are ignored and a fixed priority is configured. Rename the manager_info member alpha_enabled to partial_alpha_enabled for more clarity. Introduce two dss_features FEAT_ALPHA_FIXED_ZORDER and FEAT_ALPHA_FREE_ZORDER which represent OMAP3-alpha compatibility mode and OMAP4 alpha mode respectively. Introduce an overlay cap for ZORDER. The DSS2 user is expected to check for the ZORDER cap, if an overlay doesn't have this cap, the user is expected to set the parameter partial_alpha_enabled. If the overlay has ZORDER cap, the DSS2 user can assume that alpha blending is already enabled. Don't support OMAP3 compatibility mode for now. Trying to read/write to alpha_blending_enabled sysfs attribute issues a warning for OMAP4 and does not set the LCDALPHABLENDERENABLE/TVALPHABLENDERENABLE bits. Change alpha_enabled to partial_alpha_enabled int the omap_vout driver. Use overlay cap OMAP_DSS_OVL_CAP_GLOBAL_ALPHA to check if overlay supports alpha blending or not. Replace this with checks for VIDEO1 pipeline. Initial patch was made by: Lajos Molnar mol...@ti.com Cc: linux-me...@vger.kernel.org Cc: Lajos Molnar mol...@ti.com Signed-off-by: Archit Taneja arc...@ti.com --- drivers/media/video/omap/omap_vout.c | 16 +++- drivers/video/omap2/dss/dispc.c| 24 drivers/video/omap2/dss/dss.h |4 ++-- drivers/video/omap2/dss/dss_features.c | 22 +++--- drivers/video/omap2/dss/dss_features.h |3 ++- drivers/video/omap2/dss/manager.c | 28 +++- include/video/omapdss.h|3 ++- 7 files changed, 59 insertions(+), 41 deletions(-) diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index b3a5ecd..95daf98 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -1165,12 +1165,17 @@ static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, { int ret = 0; struct omap_vout_device *vout = fh; + struct omap_overlay *ovl; + struct omapvideo_info *ovid; struct v4l2_window *win = f-fmt.win; + ovid = vout-vid_info; + ovl = ovid-overlays[0]; + ret = omap_vout_try_window(vout-fbuf, win); if (!ret) { - if (vout-vid == OMAP_VIDEO1) + if ((ovl-caps OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) win-global_alpha = 255; else win-global_alpha = f-fmt.win.global_alpha; @@ -1194,8 +1199,7 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh, ret = omap_vout_new_window(vout-crop, vout-win, vout-fbuf, win); if (!ret) { - /* Video1 plane does not support global alpha */ - if (ovl-id == OMAP_DSS_VIDEO1) + if ((ovl-caps OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) vout-win.global_alpha = 255; else vout-win.global_alpha = f-fmt.win.global_alpha; @@ -1788,7 +1792,9 @@ static int vidioc_s_fbuf(struct file *file, void *fh, if (ovl-manager ovl-manager-get_manager_info ovl-manager-set_manager_info) { ovl-manager-get_manager_info(ovl-manager, info); - info.alpha_enabled = enable; + /* enable this only if there is no zorder cap */ + if ((ovl-caps OMAP_DSS_OVL_CAP_ZORDER) == 0) + info.partial_alpha_enabled = enable; if (ovl-manager-set_manager_info(ovl-manager, info)) return -EINVAL; } @@ -1820,7 +1826,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh, } if (ovl-manager ovl-manager-get_manager_info) { ovl-manager-get_manager_info(ovl-manager, info); - if (info.alpha_enabled) + if (info.partial_alpha_enabled) a-flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; } diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 5e6849e..e0639d3 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -179,7 +179,8 @@ static void dispc_save_context(void) SR(CONTROL); SR(CONFIG); SR(LINE_NUMBER); - if (dss_has_feature(FEAT_GLOBAL_ALPHA)) + if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) || + dss_has_feature(FEAT_ALPHA_FREE_ZORDER)) SR(GLOBAL_ALPHA); if (dss_has_feature(FEAT_MGR_LCD2)) { SR(CONTROL2); @@ -293,7 +294,8 @@ static void dispc_restore_context
[PATCH v2 2/3] OMAPDSS: DISPC: VIDEO3 pipeline support
Add support for VIDEO3 pipeline on OMAP4: - Add VIDEO3 pipeline information in dss_features and omapdss.h - Add VIDEO3 pipeline register coefficients in dispc.h - Create a new overlay structure corresponding to VIDEO3. - Make changes in dispc.c for VIDEO3 Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/dispc.c| 17 -- drivers/video/omap2/dss/dispc.h| 57 drivers/video/omap2/dss/dss_features.c | 18 +- drivers/video/omap2/dss/dss_features.h |2 +- drivers/video/omap2/dss/overlay.c |5 +++ include/video/omapdss.h|5 ++- 6 files changed, 97 insertions(+), 7 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index e0639d3..fa7aadf 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -751,7 +751,7 @@ static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable) static void dispc_ovl_setup_global_alpha(enum omap_plane plane, u8 global_alpha) { - static const unsigned shifts[] = { 0, 8, 16, }; + static const unsigned shifts[] = { 0, 8, 16, 24, }; int shift; struct omap_overlay *ovl = omap_dss_get_overlay(plane); @@ -866,6 +866,7 @@ static void dispc_ovl_set_channel_out(enum omap_plane plane, break; case OMAP_DSS_VIDEO1: case OMAP_DSS_VIDEO2: + case OMAP_DSS_VIDEO3: shift = 16; break; default: @@ -903,7 +904,7 @@ static void dispc_ovl_set_channel_out(enum omap_plane plane, static void dispc_ovl_set_burst_size(enum omap_plane plane, enum omap_burst_size burst_size) { - static const unsigned shifts[] = { 6, 14, 14, }; + static const unsigned shifts[] = { 6, 14, 14, 14, }; int shift; shift = shifts[plane]; @@ -988,7 +989,7 @@ static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable) static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable) { - static const unsigned shifts[] = { 5, 10, 10 }; + static const unsigned shifts[] = { 5, 10, 10, 10 }; int shift; shift = shifts[plane]; @@ -2558,6 +2559,10 @@ void dispc_dump_irqs(struct seq_file *s) PIS(VID1_END_WIN); PIS(VID2_FIFO_UNDERFLOW); PIS(VID2_END_WIN); + if (dss_feat_get_num_ovls() 3) { + PIS(VID3_FIFO_UNDERFLOW); + PIS(VID3_END_WIN); + } PIS(SYNC_LOST); PIS(SYNC_LOST_DIGIT); PIS(WAKEUP); @@ -2583,6 +2588,7 @@ void dispc_dump_regs(struct seq_file *s) [OMAP_DSS_GFX] = GFX, [OMAP_DSS_VIDEO1] = VID1, [OMAP_DSS_VIDEO2] = VID2, + [OMAP_DSS_VIDEO3] = VID3, }; const char **p_names; @@ -2985,6 +2991,8 @@ static void print_irq_status(u32 status) PIS(OCP_ERR); PIS(VID1_FIFO_UNDERFLOW); PIS(VID2_FIFO_UNDERFLOW); + if (dss_feat_get_num_ovls() 3) + PIS(VID3_FIFO_UNDERFLOW); PIS(SYNC_LOST); PIS(SYNC_LOST_DIGIT); if (dss_has_feature(FEAT_MGR_LCD2)) @@ -3082,6 +3090,7 @@ static void dispc_error_worker(struct work_struct *work) DISPC_IRQ_GFX_FIFO_UNDERFLOW, DISPC_IRQ_VID1_FIFO_UNDERFLOW, DISPC_IRQ_VID2_FIFO_UNDERFLOW, + DISPC_IRQ_VID3_FIFO_UNDERFLOW, }; static const unsigned sync_lost_bits[] = { @@ -3257,6 +3266,8 @@ static void _omap_dispc_initialize_irq(void) dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; if (dss_has_feature(FEAT_MGR_LCD2)) dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2; + if (dss_feat_get_num_ovls() 3) + dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW; /* there's SYNC_LOST_DIGIT waiting after enabling the DSS, * so clear it */ diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h index 6c9ee0a..c06efc3 100644 --- a/drivers/video/omap2/dss/dispc.h +++ b/drivers/video/omap2/dss/dispc.h @@ -291,6 +291,8 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane) return 0x00BC; case OMAP_DSS_VIDEO2: return 0x014C; + case OMAP_DSS_VIDEO3: + return 0x0300; default: BUG(); } @@ -304,6 +306,8 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO1: case OMAP_DSS_VIDEO2: return 0x; + case OMAP_DSS_VIDEO3: + return 0x0008; default: BUG(); } @@ -316,6 +320,8 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO1: case OMAP_DSS_VIDEO2: return 0x0004; + case OMAP_DSS_VIDEO3: + return 0x000C; default
[PATCH v2 3/3] OMAPDSS: DISPC: zorder support for DSS overlays
Add zorder support on OMAP4, this feature allows deciding the visibility order of the overlays based on the zorder value provided as an overlay info parameter or a sysfs attribute of the overlay object. Use the overlay cap OMAP_DSS_OVL_CAP_ZORDER to determine whether zorder is supported for the overlay or not. Use dss feature FEAT_ALPHA_FREE_ZORDER if the caps are not available. Ensure that all overlays that are enabled and connected to the same manager have different zorders. Swapping zorders of 2 enabled overlays currently requires disabling one of the overlays. Signed-off-by: Archit Taneja arc...@ti.com --- drivers/video/omap2/dss/dispc.c | 24 drivers/video/omap2/dss/overlay.c | 72 + include/video/omapdss.h |1 + 3 files changed, 97 insertions(+), 0 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index fa7aadf..6892cfd 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -739,6 +739,27 @@ static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height) dispc_write_reg(DISPC_OVL_SIZE(plane), val); } +static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder) +{ + struct omap_overlay *ovl = omap_dss_get_overlay(plane); + + if ((ovl-caps OMAP_DSS_OVL_CAP_ZORDER) == 0) + return; + + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26); +} + +static void dispc_ovl_enable_zorder_planes(void) +{ + int i; + + if (!dss_has_feature(FEAT_ALPHA_FREE_ZORDER)) + return; + + for (i = 0; i dss_feat_get_num_ovls(); i++) + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25); +} + static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable) { struct omap_overlay *ovl = omap_dss_get_overlay(plane); @@ -1866,6 +1887,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, dispc_ovl_set_rotation_attrs(plane, oi-rotation, oi-mirror, oi-color_mode); + dispc_ovl_set_zorder(plane, oi-zorder); dispc_ovl_set_pre_mult_alpha(plane, oi-pre_mult_alpha); dispc_ovl_setup_global_alpha(plane, oi-global_alpha); @@ -3317,6 +3339,8 @@ static void _omap_dispc_initial_config(void) dispc_read_plane_fifo_sizes(); dispc_configure_burst_sizes(); + + dispc_ovl_enable_zorder_planes(); } /* DISPC HW IP initialisation */ diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index 11d21e3..ab8e40e 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -311,6 +311,42 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl, return size; } +static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf) +{ + return snprintf(buf, PAGE_SIZE, %d\n, ovl-info.zorder); +} + +static ssize_t overlay_zorder_store(struct omap_overlay *ovl, + const char *buf, size_t size) +{ + int r; + u8 zorder; + struct omap_overlay_info info; + + if ((ovl-caps OMAP_DSS_OVL_CAP_ZORDER) == 0) + return -ENODEV; + + r = kstrtou8(buf, 0, zorder); + if (r) + return r; + + ovl-get_overlay_info(ovl, info); + + info.zorder = zorder; + + r = ovl-set_overlay_info(ovl, info); + if (r) + return r; + + if (ovl-manager) { + r = ovl-manager-apply(ovl-manager); + if (r) + return r; + } + + return size; +} + struct overlay_attribute { struct attribute attr; ssize_t (*show)(struct omap_overlay *, char *); @@ -337,6 +373,8 @@ static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR, static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR, overlay_pre_mult_alpha_show, overlay_pre_mult_alpha_store); +static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR, + overlay_zorder_show, overlay_zorder_store); static struct attribute *overlay_sysfs_attrs[] = { overlay_attr_name.attr, @@ -348,6 +386,7 @@ static struct attribute *overlay_sysfs_attrs[] = { overlay_attr_enabled.attr, overlay_attr_global_alpha.attr, overlay_attr_pre_mult_alpha.attr, + overlay_attr_zorder.attr, NULL }; @@ -397,6 +436,7 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev) struct omap_overlay_info *info; u16 outw, outh; u16 dw, dh; + int i; if (!dssdev) return 0; @@ -452,6 +492,31 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev) return -EINVAL; } + if (ovl-caps OMAP_DSS_OVL_CAP_ZORDER) { + if (info-zorder 0 || info-zorder 3) { + DSSERR(zorder out of range: %d\n
[PATCH v2 0/3] OMAPDSS: DISPC: VIDEO3 and ZORDER support
This contains support for VIDEO3 pipeline and zorder support for OMAP4 Display controller. This set originally had some more miscellaneous patches. Those patches have been separated out and this set is created since it makes some trivial changes in the omap_vout driver. The patch set is based on Tomi's master branch. It can be tried on: https://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone/commits/dispc_misc Tested on 4430sdp, 3430sdp. Archit Taneja (3): OMAPDSS/OMAP_VOUT: Fix incorrect OMAP3-alpha compatibility setting OMAPDSS: DISPC: VIDEO3 pipeline support OMAPDSS: DISPC: zorder support for DSS overlays drivers/media/video/omap/omap_vout.c | 16 +-- drivers/video/omap2/dss/dispc.c| 65 -- drivers/video/omap2/dss/dispc.h| 57 +++ drivers/video/omap2/dss/dss.h |4 +- drivers/video/omap2/dss/dss_features.c | 40 +++- drivers/video/omap2/dss/dss_features.h |5 +- drivers/video/omap2/dss/manager.c | 28 drivers/video/omap2/dss/overlay.c | 77 include/video/omapdss.h|9 +++- 9 files changed, 253 insertions(+), 48 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html