Re: [PATCH V3] ARM: GIC: Convert GIC library to use the IO relaxed operations

2011-05-05 Thread Santosh Shilimkar

On 5/4/2011 10:34 PM, Will Deacon wrote:

Hi Santosh,

On Wed, 2011-05-04 at 12:02 +0100, Santosh Shilimkar wrote:

Will,
Can you queue this patch part of your series please?


Yes, providing that Russell is happy to pull the IRQ stuff (fasteoi,
Tegra changes and this) from me.


Thanks.

Regards
Santosh
--
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: Common clock and dvfs

2011-05-05 Thread Colin Cross
On Wed, May 4, 2011 at 10:08 PM, Cousson, Benoit b-cous...@ti.com wrote:
 (Cc folks with some DVFS interest)

 Hi Colin,

 On Fri, 22 Apr 2011, Colin Cross wrote:

 Now that we are approaching a common clock management implementation,
 I was thinking it might be the right place to put a common dvfs
 implementation as well.

 It is very common for SoC manufacturers to provide a table of the
 minimum voltage required on a voltage rail for a clock to run at a
 given frequency.  There may be multiple clocks in a voltage rail that
 each can specify their own minimum voltage, and one clock may affect
 multiple voltage rails.  I have seen two ways to handle keeping the
 clocks and voltages within spec:

 The Tegra way is to put everything dvfs related under the clock
 framework.  Enabling (or preparing, in the new clock world) or raising
 the frequency calls dvfs_set_rate before touching the clock, which
 looks up the required voltage on a voltage rail, aggregates it with
 the other voltage requests, and passes the minimum voltage required to
 the regulator api.  Disabling or unpreparing, or lowering the
 frequency changes the clock first, and then calls dvfs_set_rate.  For
 a generic implementation, an SoC would provide the clock/dvfs
 framework with a list of clocks, the voltages required for each
 frequency step on the clock, and the regulator name to change.  The
 frequency/voltage tables are similar to OPP, except that OPP gets
 voltages for a device instead of a clock.  In a few odd cases (Tegra
 always has a few odd cases), a clock that is internal to a device and
 not exposed to the clock framework (pclk output on the display, for
 example) has a voltage requirement, which requires some devices to
 manually call dvfs_set_rate directly, but with a common clock
 framework it would probably be possible for the display driver to
 export pclk as a real clock.

 Those kinds of exceptions are somehow the rules for an OMAP4 device. Most
 scalable devices are using some internal dividers or even internal PLL to
 control the scalable clock rate (DSS, HSI, MMC, McBSP... the OMAP4430 Data
 Manual [1] is providing the various clock rate limitation depending of the
 OPP).
 And none of these internal dividers are handled by the clock fmwk today.

 For sure, it should be possible to extend the clock data with internal
 devices clock nodes (like the UART baud rate divider for example), but then
 we will have to handle a bunch of nodes that may not be always available
 depending of device state. In order to do that, you have to tie these clocks
 node to the device that contains them.

I agree there are cases where the clock framework may not be a fit for
a specific divider, but it would be simple to export the same
dvfs_set_rate functions that the generic clk_set_rate calls, and allow
drivers that need to scale their own clocks to take advantage of the
common tables.

 And for the clocks that do not belong to any device, like most PRCM source
 clocks or DPLL inside OMAP, we can easily define a PRCM device or several CM
 (Clock Manager) devices that will handle all these clock nodes.

 The proposed OMAP4 way (I believe, correct me if I am wrong) is to
 create a new api outside the clock api that calls into both the clock
 api and the regulator api in the correct order for each operation,
 using OPP to determine the voltage.  This has a few disadvantages
 (obviously, I am biased, having written the Tegra code) - clocks and
 voltages are tied to a device, which is not always the case for
 platforms outside of OMAP, and drivers must know if their hardware
 requires voltage scaling.  The clock api becomes unsafe to use on any
 device that requires dvfs, as it could change the frequency higher
 than the supported voltage.

 You have to tie clock and voltage to a device. Most of the time a clock does
 not have any clear relation with a voltage domain. It can even cross power /
 voltage domain without any issue.
 The efficiency of the DVFS technique is mainly due to the reduction of the
 voltage rail that supply a device. In order to achieve that you have to
 reduce the clock rate of one or several clocks nodes that supply the
 critical path inside the HW.

A clock crossing a voltage domain is not a problem, a single clock can
have relationships to multiple regulators.  But a clock does not need
to be tied to a device.  From the silicon perspective, it doesn't
matter how you divide up the devices in the kernel, a clock is just a
line toggling at a rate, and the maximum speed it can toggle is
determined by the silicon it feeds and the voltage that silicon is
operating at.  If a device can be turned on or off, that's a clock
gate, and the line downstream from the clock gate is a separate clock.

 The clock node itself does not know anything about the device and that's why
 it should not be the proper structure to do DVFS.

One of us is confused here.  The clock node does not know about the
device, and it doesn't need to.  All the 

Re: Common clock and dvfs

2011-05-05 Thread Paul Walmsley
On Thu, 5 May 2011, Cousson, Benoit wrote:

 Those kinds of exceptions are somehow the rules for an OMAP4 device. 
 Most scalable devices are using some internal dividers or even internal 
 PLL to control the scalable clock rate (DSS, HSI, MMC, McBSP... the 
 OMAP4430 Data Manual [1] is providing the various clock rate limitation 
 depending of the OPP). And none of these internal dividers are handled 
 by the clock fmwk today.

That's mostly because no one has taken the time to implement them, not 
really for any technical reason.

 For sure, it should be possible to extend the clock data with internal 
 devices clock nodes (like the UART baud rate divider for example), but 
 then we will have to handle a bunch of nodes that may not be always 
 available depending of device state. In order to do that, you have to 
 tie these clocks node to the device that contains them.

It's only necessary to do that for the device where the clock's control 
registers are located.  In many cases (almost all on OMAP), this is a 
different device from the device that the clock actually drives.

 And for the clocks that do not belong to any device, like most PRCM 
 source clocks or DPLL inside OMAP, we can easily define a PRCM device or 
 several CM (Clock Manager) devices that will handle all these clock 
 nodes.
 
  The proposed OMAP4 way (I believe, correct me if I am wrong) is to 
  create a new api outside the clock api that calls into both the clock 
  api and the regulator api in the correct order for each operation, 
  using OPP to determine the voltage.  This has a few disadvantages 
  (obviously, I am biased, having written the Tegra code) - clocks and 
  voltages are tied to a device, which is not always the case for 
  platforms outside of OMAP, and drivers must know if their hardware 
  requires voltage scaling.  The clock api becomes unsafe to use on any 
  device that requires dvfs, as it could change the frequency higher 
  than the supported voltage.
 
 You have to tie clock and voltage to a device. 

As you mentioned above, there are several clocks that aren't associated 
with any specific device outside of the clock itself, or which are 
associated with multiple devices.

 Most of the time a clock does not have any clear relation with a voltage 
 domain.  It can even cross power / voltage domain without any issue.

Each instance of a clock signal -- a conductor on a chip that carries an 
AC signal that is used to drive some gates -- can only be driven by 
one voltage rail.  How could it be otherwise?

In the unusual instances where a clock crosses voltage rails (by virtue of 
some gates between the rails that handle the translation) and it is 
important for Linux to know this, then in the Linux-OMAP code, the 
intention is for separate struct clks to be used for the clock signals on 
either side of the voltage rail crossing.

 The clock node itself does not know anything about the device and that's 
 why it should not be the proper structure to do DVFS.

What aspects of the device are you referring to that the clock node would 
need to know?

 OMAP moved away from using the clock nodes to represent IP blocks 
 because the clock abstraction was not enough to represent the way an IP 
 is interacting with clocks. That's why omap_hwmod was introduced to 
 represent an IP block.

omap_hwmod was introduced to represent IP blocks and their 
interconnection.  Separating IP block gating from individual clock gating 
was one part of this, but not the only one; and gating isn't really 
related to DVFS.

 Because the clock is not the central piece of the DVFS sequence, I don't 
 think it deserves to handle the whole sequence including voltage 
 scaling.
 
 A change to a clock rate might trigger a voltage change, but the 
 opposite is true as well. A reduction of the voltage could trigger the 
 clock rate change inside all the devices that belong to the voltage 
 domain. Because of that, both fmwks are siblings. This is not a 
 parent-child relationship.

What's the use case for voltage reduction that isn't triggered by a clock 
rate reduction?

 Another important point is that in order to trigger a DVFS sequence you 
 have to do some voting to take into account shared clock and shared 
 voltage domains.
 
 Moreover, playing directly with a clock rate is not necessarily 
 appropriate or sufficient for some devices. For example, the 
 interconnect should expose a BW knob instead of a clock rate one.  In 
 general, some more abstract information like BW, latency or performance 
 level (P-state) should be the ones to be exposed at driver level.

It's definitely true, that, say, the SDMA driver should not specify its 
interconnect bandwidth requirements in terms of an interconnect clock 
frequency.  It should specify some variant of bytes per second.  But 
that's only possible because the goal is to provide the interconnect 
driver with have enough information to convert the bandwidth constraint to 
a clock rate 

Re: Common clock and dvfs

2011-05-05 Thread Paul Walmsley
On Wed, 4 May 2011, Colin Cross wrote:

 Imagine a chip where a clock can feed devices A, B, and C.  If the
 devices are always clocked at the same rate, and can't gate their
 clocks, the minimum voltage that can be applied to a rail is
 determined ONLY by the rate of the clock.

That's not so -- although admittedly it's a side issue, and not 
particularly related to DVFS.

For example, the device may have some external I/O lines which need to be 
at least some minimum voltage level for the externally-connected device to 
function.  This minimum voltage level can be unrelated to the device's 
clock frequency.


- Paul
--
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: Common clock and dvfs

2011-05-05 Thread Colin Cross
On Wed, May 4, 2011 at 11:35 PM, Paul Walmsley p...@pwsan.com wrote:
 On Wed, 4 May 2011, Colin Cross wrote:

 Imagine a chip where a clock can feed devices A, B, and C.  If the
 devices are always clocked at the same rate, and can't gate their
 clocks, the minimum voltage that can be applied to a rail is
 determined ONLY by the rate of the clock.

 That's not so -- although admittedly it's a side issue, and not
 particularly related to DVFS.

 For example, the device may have some external I/O lines which need to be
 at least some minimum voltage level for the externally-connected device to
 function.  This minimum voltage level can be unrelated to the device's
 clock frequency.

True, that was an oversimplificaiton. I meant the minimum voltage that
scales with clock frequencies only depends on the clock frequency, not
the device.  Devices do need to be able to specify a higher minimum
voltage, and the regulator api needs to handle it.
--
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/5] OMAP4: DSS2: HDMI: Add support for audio

2011-05-05 Thread Ricardo Neri
This is to add support for HDMI audio on OMAP4 chips. This work has two
parts: DSS implementation and ASoC implementation. This set of patches
presents the DSS implementation. The approach is to utilize the DSS
HDMI driver to act as an ASoC codec. Then, functionality and data
structures are added to the DSS HDMI driver to configure parameters
relevant to audio such as sample rate and frequency and DMA.
The ASoC implementation adds an HDMI audio card that will utilize this
HDMI ASoC codec. The ASoC implementation is also under review in the
alsa-devel list.

This implementation is for Basic Audio as defined in CEA-861-D: 16 bit/sample
linear PCM 2-channel audio with sample rates of 32, 44.1 and 48kHz. As
described in the HDMI specification, support for Basic Audio is mandatory
for HDMI sinks and does not require of EDID parsing.

Additionally, this implementation supports 24-bit samples in 32-bit words.
Further audio capabilities such as more sample rates and multichannel audio
will be added in the future when EDID parsing is available for HDMI driver.

This implementation is based on on:
* OMAP4: DSS2: Add dss_dss_clk opt clock for OMAP4, by Sumit Semwal
 
(http://gitorious.org/linux-omap-dss2/linux/commit/0da5637569bb9bf93e6930cd1c3b452eede50ba2)
* Kernel 2.6.39-rc6
 (git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git 
v2.6.39-rc6)

In order to validate functionality, it is necessary to utilize the ASoC
HDMI CPU and machine drivers for HDMI on OMAP4. The complete implementation,
DSS and ASoC parts, is available at:
 git://gitorious.org/omap-audio/linux-audio.git ricardon/topic/hdmi-audio-v1

Verification: Penguins on HDMI display with audio playback with sample
rates of 32, 44.1 and 48kHz and 16-bit and 24-bit (in 32-bit word) sample
format. Audio playback verified using ALSA aplay. Validation was performed on
SDP4430 ES2.1 and Panda ES2.1 and ES2.0.

Ricardo Neri (5):
  OMAP4: DSS2: Create a DSS features structure for OMAP4430 ES1.0
  OMAP4: DSS2: HDMI: Add DSS feature for CTS calculation
  OMAP4: DSS2: HDMI: Add enums and structures for audio
  OMAP4: DSS2: HDMI: Add functionality for audio configuration
  OMAP4: DSS2: HDMI: Implement ASoC Codec driver for HDMI audio

 drivers/video/omap2/dss/dss_features.c |   29 ++-
 drivers/video/omap2/dss/dss_features.h |1 +
 drivers/video/omap2/dss/hdmi.c |  432 
 drivers/video/omap2/dss/hdmi.h |  220 -
 4 files changed, 678 insertions(+), 4 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 2/5] OMAP4: DSS2: HDMI: Add DSS feature for CTS calculation

2011-05-05 Thread Ricardo Neri
CTS and N parameters are used to regenerate the audio clock from
the TMDS clock at the HDMI sink. In  OMAP4430 ES1.0 version
the calculation of the CTS parameter is done by the HDMI IP
(hardware mode) while in others it must be done by the HDMI driver
(software mode). A DSS feature is used to indicate the HDMI
driver which mode is used.

Signed-off-by: Ricardo Neri ricardo.n...@ti.com
---
 drivers/video/omap2/dss/dss_features.c |3 ++-
 drivers/video/omap2/dss/dss_features.h |1 +
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/video/omap2/dss/dss_features.c 
b/drivers/video/omap2/dss/dss_features.c
index 6c57af4..cfcc12b 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -308,7 +308,8 @@ static struct omap_dss_features omap4_dss_features = {
.has_feature=
FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
-   FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC,
+   FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
+   FEAT_HDMI_CTS_SWMODE,
 
.num_mgrs = 3,
.num_ovls = 3,
diff --git a/drivers/video/omap2/dss/dss_features.h 
b/drivers/video/omap2/dss/dss_features.h
index 12e9c4e..a732c24 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -40,6 +40,7 @@ enum dss_feat_id {
/* Independent core clk divider */
FEAT_CORE_CLK_DIV   = 1  11,
FEAT_LCD_CLK_SRC= 1  12,
+   FEAT_HDMI_CTS_SWMODE = 1  13,
 };
 
 /* DSS register field id */
-- 
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 1/5] OMAP4: DSS2: Create a DSS features structure for OMAP4430 ES1.0

2011-05-05 Thread Ricardo Neri
Create a separate DSS features structure for OMAP4430 ES1.0. This
structure is used to expose features only present in such
silicon version. Specifically, this is required to handle how
the HDMI IP calculates the CTS parameter for audio clock
regeneration packets. OMAP4430 ES1.0 is the only one that supports
computation of the CTS parameter by the HDMI IP (hardware mode).
The rest of the revisions require the HDMI driver to perform the
computation.

Signed-off-by: Ricardo Neri ricardo.n...@ti.com
---
 drivers/video/omap2/dss/dss_features.c |   26 +-
 1 files changed, 25 insertions(+), 1 deletions(-)

diff --git a/drivers/video/omap2/dss/dss_features.c 
b/drivers/video/omap2/dss/dss_features.c
index aa16222..6c57af4 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -282,6 +282,25 @@ static struct omap_dss_features omap3630_dss_features = {
 };
 
 /* OMAP4 DSS Features */
+/* For OMAP4430 ES 1.0 revision */
+static struct omap_dss_features omap4430_es1_0_dss_features = {
+   .reg_fields = omap4_dss_reg_fields,
+   .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
+
+   .has_feature=
+   FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
+   FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
+   FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC,
+
+   .num_mgrs = 3,
+   .num_ovls = 3,
+   .supported_displays = omap4_dss_supported_displays,
+   .supported_color_modes = omap3_dss_supported_color_modes,
+   .clksrc_names = omap4_dss_clk_source_names,
+   .dss_params = omap4_dss_param_range,
+};
+
+/* For all the other OMAP4 versions */
 static struct omap_dss_features omap4_dss_features = {
.reg_fields = omap4_dss_reg_fields,
.num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
@@ -299,6 +318,7 @@ static struct omap_dss_features omap4_dss_features = {
.dss_params = omap4_dss_param_range,
 };
 
+
 /* Functions returning values related to a DSS feature */
 int dss_feat_get_num_mgrs(void)
 {
@@ -365,6 +385,10 @@ void dss_features_init(void)
omap_current_dss_features = omap3630_dss_features;
else if (cpu_is_omap34xx())
omap_current_dss_features = omap3430_dss_features;
-   else
+   else if (omap_rev() == OMAP4430_REV_ES1_0)
+   omap_current_dss_features = omap4430_es1_0_dss_features;
+   else if (cpu_is_omap44xx())
omap_current_dss_features = omap4_dss_features;
+   else
+   DSSWARN(Unsupported OMAP version);
 }
-- 
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 4/5] OMAP4: DSS2: HDMI: Add functionality for audio configuration

2011-05-05 Thread Ricardo Neri
Add functionality for relevant audio configuration. Functions to
configure the audio FIFO and DMA as well as functions for the audio
core and Audio Info frame are included. This functionality is to
be used by the ASoC HDMI audio codec.

Signed-off-by: Ricardo Neri ricardo.n...@ti.com
---
 drivers/video/omap2/dss/hdmi.c |  215 
 1 files changed, 215 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index a981def..c5676ee 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -1275,6 +1275,221 @@ void omapdss_hdmi_display_disable(struct 
omap_dss_device *dssdev)
mutex_unlock(hdmi.lock);
 }
 
+#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
+   defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
+static void hdmi_wp_audio_config_format(
+   struct hdmi_audio_format *aud_fmt)
+{
+   u32 r;
+
+   DSSDBG(Enter hdmi_wp_audio_config_format\n);
+
+   r = hdmi_read_reg(HDMI_WP_AUDIO_CFG);
+   r = FLD_MOD(r, aud_fmt-stereo_channels, 26, 24);
+   r = FLD_MOD(r, aud_fmt-active_chnnls_msk, 23, 16);
+   r = FLD_MOD(r, aud_fmt-en_sig_blk_strt_end, 5, 5);
+   r = FLD_MOD(r, aud_fmt-type, 4, 4);
+   r = FLD_MOD(r, aud_fmt-justification, 3, 3);
+   r = FLD_MOD(r, aud_fmt-sample_order, 2, 2);
+   r = FLD_MOD(r, aud_fmt-samples_per_word, 1, 1);
+   r = FLD_MOD(r, aud_fmt-sample_size, 0, 0);
+   hdmi_write_reg(HDMI_WP_AUDIO_CFG, r);
+}
+
+static void hdmi_wp_audio_config_dma(struct hdmi_audio_dma *aud_dma)
+{
+   u32 r;
+
+   DSSDBG(Enter hdmi_wp_audio_config_dma\n);
+
+   r = hdmi_read_reg(HDMI_WP_AUDIO_CFG2);
+   r = FLD_MOD(r, aud_dma-transfer_size, 15, 8);
+   r = FLD_MOD(r, aud_dma-block_size, 7, 0);
+   hdmi_write_reg(HDMI_WP_AUDIO_CFG2, r);
+
+   r = hdmi_read_reg(HDMI_WP_AUDIO_CTRL);
+   r = FLD_MOD(r, aud_dma-mode, 9, 9);
+   r = FLD_MOD(r, aud_dma-fifo_threshold, 8, 0);
+   hdmi_write_reg(HDMI_WP_AUDIO_CTRL, r);
+}
+
+static void hdmi_core_audio_config(struct hdmi_core_audio_config *cfg)
+{
+   u32 r;
+
+   /* audio clock recovery parameters */
+   r = hdmi_read_reg(HDMI_CORE_AV_ACR_CTRL);
+   r = FLD_MOD(r, cfg-use_mclk, 2, 2);
+   r = FLD_MOD(r, cfg-en_acr_pkt, 1, 1);
+   r = FLD_MOD(r, cfg-cts_mode, 0, 0);
+   hdmi_write_reg(HDMI_CORE_AV_ACR_CTRL, r);
+
+   REG_FLD_MOD(HDMI_CORE_AV_N_SVAL1, cfg-n, 7, 0);
+   REG_FLD_MOD(HDMI_CORE_AV_N_SVAL2, cfg-n  8, 7, 0);
+   REG_FLD_MOD(HDMI_CORE_AV_N_SVAL3, cfg-n  16, 7, 0);
+
+   if (cfg-cts_mode == HDMI_AUDIO_CTS_MODE_SW) {
+   REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL1, cfg-cts, 7, 0);
+   REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL2, cfg-cts  8, 7, 0);
+   REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL3, cfg-cts  16, 7, 0);
+   } else {
+   /*
+* HDMI IP uses this configuration to divide the MCLK to
+* update CTS value.
+*/
+   REG_FLD_MOD(HDMI_CORE_AV_FREQ_SVAL, cfg-mclk_mode, 2, 0);
+
+   /* Configure clock for audio packets */
+   REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
+   cfg-aud_par_busclk, 7, 0);
+   REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_2,
+   (cfg-aud_par_busclk  8), 7, 0);
+   REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_3,
+   (cfg-aud_par_busclk  16), 7, 0);
+   }
+
+   /* Override of SPDIF sample frequency with value in I2S_CHST4 */
+   REG_FLD_MOD(HDMI_CORE_AV_SPDIF_CTRL, cfg-fs_override, 1, 1);
+
+   /* I2S parameters */
+   REG_FLD_MOD(HDMI_CORE_AV_I2S_CHST4, cfg-freq_sample, 3, 0);
+
+   r = hdmi_read_reg(HDMI_CORE_AV_I2S_IN_CTRL);
+   r = FLD_MOD(r, cfg-i2s_cfg.en_high_bitrate_aud, 7, 7);
+   r = FLD_MOD(r, cfg-i2s_cfg.sck_edge_mode, 6, 6);
+   r = FLD_MOD(r, cfg-i2s_cfg.cbit_order, 5, 5);
+   r = FLD_MOD(r, cfg-i2s_cfg.vbit, 4, 4);
+   r = FLD_MOD(r, cfg-i2s_cfg.ws_polarity, 3, 3);
+   r = FLD_MOD(r, cfg-i2s_cfg.justification, 2, 2);
+   r = FLD_MOD(r, cfg-i2s_cfg.direction, 1, 1);
+   r = FLD_MOD(r, cfg-i2s_cfg.shift, 0, 0);
+   hdmi_write_reg(HDMI_CORE_AV_I2S_IN_CTRL, r);
+
+   r = hdmi_read_reg(HDMI_CORE_AV_I2S_CHST5);
+   r = FLD_MOD(r, cfg-freq_sample, 7, 4);
+   r = FLD_MOD(r, cfg-i2s_cfg.word_length, 3, 1);
+   r = FLD_MOD(r, cfg-i2s_cfg.word_max_length, 0, 0);
+   hdmi_write_reg(HDMI_CORE_AV_I2S_CHST5, r);
+
+   REG_FLD_MOD(HDMI_CORE_AV_I2S_IN_LEN, cfg-i2s_cfg.in_length_bits, 3, 0);
+
+   /* Audio channels and mode parameters */
+   REG_FLD_MOD(HDMI_CORE_AV_HDMI_CTRL, cfg-layout, 2, 1);
+   r = hdmi_read_reg(HDMI_CORE_AV_AUD_MODE);
+   r = FLD_MOD(r, cfg-i2s_cfg.active_sds, 7, 4);
+   r = FLD_MOD(r, cfg-en_dsd_audio, 3, 3);
+   r = FLD_MOD(r, cfg-en_parallel_aud_input, 2, 2);
+

[PATCH 5/5] OMAP4: DSS2: HDMI: Implement ASoC Codec driver for HDMI audio

2011-05-05 Thread Ricardo Neri
Implement an ASoC Codec Driver to handle audio configuration. The
implementation offers an interface for audio configuration and
control to be exposed to ALSA while hidding the HDMI details.

The ASoC driver supports the Basic Audio configuration as described
in CEA-861-D: 2-channel linear PCM with 32, 44.1 and 48kHz sample
rates and 16 bits/sample. It additionally supports 24 bit/sample
in 32-bit words.

Signed-off-by: Ricardo Neri ricardo.n...@ti.com
---
 drivers/video/omap2/dss/hdmi.c |  217 
 1 files changed, 217 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index c5676ee..91b11a1 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -30,9 +30,15 @@
 #include linux/delay.h
 #include linux/string.h
 #include plat/display.h
+#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
+   defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
+#include sound/soc.h
+#include sound/pcm_params.h
+#endif
 
 #include dss.h
 #include hdmi.h
+#include dss_features.h
 
 static struct {
struct mutex lock;
@@ -1488,12 +1494,207 @@ static int hdmi_config_audio_acr(u32 sample_freq, u32 
*n, u32 *cts)
 
return 0;
 }
+
+static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
+   struct snd_pcm_hw_params *params,
+   struct snd_soc_dai *dai)
+{
+   struct hdmi_audio_format audio_format;
+   struct hdmi_audio_dma audio_dma;
+   struct hdmi_core_audio_config core_cfg;
+   struct hdmi_core_infoframe_audio aud_if_cfg;
+   int err, n, cts;
+   enum hdmi_core_audio_sample_freq sample_freq;
+
+   switch (params_format(params)) {
+   case SNDRV_PCM_FORMAT_S16_LE:
+   core_cfg.i2s_cfg.word_max_length =
+   HDMI_AUDIO_I2S_MAX_WORD_20BITS;
+   core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_16_BITS;
+   core_cfg.i2s_cfg.in_length_bits =
+   HDMI_AUDIO_I2S_INPUT_LENGTH_16;
+   core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT;
+   audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES;
+   audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS;
+   audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT;
+   audio_dma.transfer_size = 0x10;
+   break;
+   case SNDRV_PCM_FORMAT_S24_LE:
+   core_cfg.i2s_cfg.word_max_length =
+   HDMI_AUDIO_I2S_MAX_WORD_24BITS;
+   core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_24_BITS;
+   core_cfg.i2s_cfg.in_length_bits =
+   HDMI_AUDIO_I2S_INPUT_LENGTH_24;
+   audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE;
+   audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS;
+   audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
+   core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
+   audio_dma.transfer_size = 0x20;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   switch (params_rate(params)) {
+   case 32000:
+   sample_freq = HDMI_AUDIO_FS_32000;
+   break;
+   case 44100:
+   sample_freq = HDMI_AUDIO_FS_44100;
+   break;
+   case 48000:
+   sample_freq = HDMI_AUDIO_FS_48000;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   err = hdmi_config_audio_acr(params_rate(params), n, cts);
+   if (err  0)
+   return err;
+
+   /* Audio wrapper config */
+   audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL;
+   audio_format.active_chnnls_msk = 0x03;
+   audio_format.type = HDMI_AUDIO_TYPE_LPCM;
+   audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
+   /* Disable start/stop signals of IEC 60958 blocks */
+   audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF;
+
+   audio_dma.block_size = 0xC0;
+   audio_dma.mode = HDMI_AUDIO_TRANSF_DMA;
+   audio_dma.fifo_threshold = 0x20; /* in number of samples */
+
+   hdmi_wp_audio_config_dma(audio_dma);
+   hdmi_wp_audio_config_format(audio_format);
+
+   /*
+* I2S config
+*/
+   core_cfg.i2s_cfg.en_high_bitrate_aud = false;
+   /* Only used with high bitrate audio */
+   core_cfg.i2s_cfg.cbit_order = false;
+   /* Serial data and word select should change on sck rising edge */
+   core_cfg.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING;
+   core_cfg.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM;
+   /* Set I2S word select polarity */
+   core_cfg.i2s_cfg.ws_polarity = HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT;
+   core_cfg.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST;
+   /* Set serial 

[PATCH 3/5] OMAP4: DSS2: HDMI: Add enums and structures for audio

2011-05-05 Thread Ricardo Neri
Add enurations and structures for audio configuration. This includes
enumerations for the Audio InfoFrame, I2S, audio FIFO and audio core.

Signed-off-by: Ricardo Neri ricardo.n...@ti.com
---
 drivers/video/omap2/dss/hdmi.h |  220 +++-
 1 files changed, 218 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
index 9887ab9..1a5da3c 100644
--- a/drivers/video/omap2/dss/hdmi.h
+++ b/drivers/video/omap2/dss/hdmi.h
@@ -48,6 +48,10 @@ struct hdmi_reg { u16 idx; };
 #define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68)
 #define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C)
 #define HDMI_WP_WP_CLK HDMI_WP_REG(0x70)
+#define HDMI_WP_AUDIO_CFG  HDMI_WP_REG(0x80)
+#define HDMI_WP_AUDIO_CFG2 HDMI_WP_REG(0x84)
+#define HDMI_WP_AUDIO_CTRL HDMI_WP_REG(0x88)
+#define HDMI_WP_AUDIO_DATA HDMI_WP_REG(0x8C)
 
 /* HDMI IP Core System */
 #define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx)
@@ -105,6 +109,8 @@ struct hdmi_reg { u16 idx; };
 #define HDMI_CORE_AV_AVI_DBYTE_NELEMS  HDMI_CORE_AV_REG(15)
 #define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190)
 #define HDMI_CORE_AV_SPD_DBYTE_NELEMS  HDMI_CORE_AV_REG(27)
+#define HDMI_CORE_AV_AUD_DBYTE(n)  HDMI_CORE_AV_REG(n * 4 + 0x210)
+#define HDMI_CORE_AV_AUD_DBYTE_NELEMS  HDMI_CORE_AV_REG(10)
 #define HDMI_CORE_AV_MPEG_DBYTEHDMI_CORE_AV_REG(0x290)
 #define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
 #define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300)
@@ -153,6 +159,10 @@ struct hdmi_reg { u16 idx; };
 #define HDMI_CORE_AV_SPD_VERS  HDMI_CORE_AV_REG(0x184)
 #define HDMI_CORE_AV_SPD_LEN   HDMI_CORE_AV_REG(0x188)
 #define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C)
+#define HDMI_CORE_AV_AUDIO_TYPEHDMI_CORE_AV_REG(0x200)
+#define HDMI_CORE_AV_AUDIO_VERSHDMI_CORE_AV_REG(0x204)
+#define HDMI_CORE_AV_AUDIO_LEN HDMI_CORE_AV_REG(0x208)
+#define HDMI_CORE_AV_AUDIO_CHSUM   HDMI_CORE_AV_REG(0x20C)
 #define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280)
 #define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284)
 #define HDMI_CORE_AV_MPEG_LEN  HDMI_CORE_AV_REG(0x288)
@@ -272,7 +282,7 @@ enum hdmi_core_packet_ctrl {
HDMI_PACKETREPEATOFF = 0
 };
 
-/* INFOFRAME_AVI_ definitions */
+/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */
 enum hdmi_core_infoframe {
HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
@@ -317,7 +327,36 @@ enum hdmi_core_infoframe {
HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
-   HDMI_INFOFRAME_AVI_DB5PR_10 = 9
+   HDMI_INFOFRAME_AVI_DB5PR_10 = 9,
+   HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM = 0,
+   HDMI_INFOFRAME_AUDIO_DB1CT_IEC60958 = 1,
+   HDMI_INFOFRAME_AUDIO_DB1CT_AC3 = 2,
+   HDMI_INFOFRAME_AUDIO_DB1CT_MPEG1 = 3,
+   HDMI_INFOFRAME_AUDIO_DB1CT_MP3 = 4,
+   HDMI_INFOFRAME_AUDIO_DB1CT_MPEG2_MULTICH = 5,
+   HDMI_INFOFRAME_AUDIO_DB1CT_AAC = 6,
+   HDMI_INFOFRAME_AUDIO_DB1CT_DTS = 7,
+   HDMI_INFOFRAME_AUDIO_DB1CT_ATRAC = 8,
+   HDMI_INFOFRAME_AUDIO_DB1CT_ONEBIT = 9,
+   HDMI_INFOFRAME_AUDIO_DB1CT_DOLBY_DIGITAL_PLUS = 10,
+   HDMI_INFOFRAME_AUDIO_DB1CT_DTS_HD = 11,
+   HDMI_INFOFRAME_AUDIO_DB1CT_MAT = 12,
+   HDMI_INFOFRAME_AUDIO_DB1CT_DST = 13,
+   HDMI_INFOFRAME_AUDIO_DB1CT_WMA_PRO = 14,
+   HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM = 0,
+   HDMI_INFOFRAME_AUDIO_DB2SF_32000 = 1,
+   HDMI_INFOFRAME_AUDIO_DB2SF_44100 = 2,
+   HDMI_INFOFRAME_AUDIO_DB2SF_48000 = 3,
+   HDMI_INFOFRAME_AUDIO_DB2SF_88200 = 4,
+   HDMI_INFOFRAME_AUDIO_DB2SF_96000 = 5,
+   HDMI_INFOFRAME_AUDIO_DB2SF_176400 = 6,
+   HDMI_INFOFRAME_AUDIO_DB2SF_192000 = 7,
+   HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM = 0,
+   HDMI_INFOFRAME_AUDIO_DB2SS_16BIT = 1,
+   HDMI_INFOFRAME_AUDIO_DB2SS_20BIT = 2,
+   HDMI_INFOFRAME_AUDIO_DB2SS_24BIT = 3,
+   HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PERMITTED = 0,
+   HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PROHIBITED = 1
 };
 
 enum hdmi_packing_mode {
@@ -327,6 +366,121 @@ enum hdmi_packing_mode {
HDMI_PACK_ALREADYPACKED = 7
 };
 
+enum hdmi_core_audio_sample_freq {
+   HDMI_AUDIO_FS_32000 = 0x3,
+   HDMI_AUDIO_FS_44100 = 0x0,
+   HDMI_AUDIO_FS_48000 = 0x2,
+   HDMI_AUDIO_FS_88200 = 0x8,
+   HDMI_AUDIO_FS_96000 = 0xA,
+   HDMI_AUDIO_FS_176400 = 0xC,
+   HDMI_AUDIO_FS_192000 = 0xE,
+   HDMI_AUDIO_FS_NOT_INDICATED = 0x1
+};
+
+enum hdmi_core_audio_layout {
+   HDMI_AUDIO_LAYOUT_2CH = 0,
+   HDMI_AUDIO_LAYOUT_8CH = 

RE: [PATCH] rtc-twl: Switch to using threaded irq

2011-05-05 Thread ilkka.koskinen

Hi,

Tony and John: What would be the appropriate path for this patch?

Cheers, Ilkka

On Apr 13, 2011 Krishnamoorthy, Balaji T  wrote:
On Wed, Mar 16, 2011 at 9:37 PM, Ilkka Koskinen
ilkka.koski...@nokia.com wrote:

 The driver is accessing to i2c bus in interrupt handler.
 Therefore, it should use threaded irq.

Acked-by: Balaji T K balaj...@ti.com


 Signed-off-by: Ilkka Koskinen ilkka.koski...@nokia.com
 ---
  drivers/rtc/rtc-twl.c |2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)

 diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
 index ed1b868..2715b96 100644
 --- a/drivers/rtc/rtc-twl.c
 +++ b/drivers/rtc/rtc-twl.c
 @@ -475,7 +475,7 @@ static int __devinit twl_rtc_probe(struct 
 platform_device *pdev)
if (ret  0)
goto out1;

 -   ret = request_irq(irq, twl_rtc_interrupt,
 +   ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
IRQF_TRIGGER_RISING,
dev_name(rtc-dev), rtc);
if (ret  0) {
 --
 1.7.0.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


[Patch v1] AM35xx-Craneboard:Update

2011-05-05 Thread srinath
From: Srinath.R srin...@mistralsolutions.com

Replaced gpio_request()/gpio_direction_output() with gpio_request_one() in 
am3517_crane_init.

Signed-off-by: Srinath.R srin...@mistralsolutions.com
---
 arch/arm/mach-omap2/board-am3517crane.c |   10 ++
 1 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/board-am3517crane.c 
b/arch/arm/mach-omap2/board-am3517crane.c
index a890d24..b8c7150 100644
--- a/arch/arm/mach-omap2/board-am3517crane.c
+++ b/arch/arm/mach-omap2/board-am3517crane.c
@@ -89,19 +89,13 @@ static void __init am3517_crane_init(void)
return;
}
 
-   ret = gpio_request(GPIO_USB_POWER, usb_ehci_enable);
+   ret = gpio_request_one(GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH,
+   usb_ehci_enable);
if (ret  0) {
pr_err(Can not request GPIO %d\n, GPIO_USB_POWER);
return;
}
 
-   ret = gpio_direction_output(GPIO_USB_POWER, 1);
-   if (ret  0) {
-   gpio_free(GPIO_USB_POWER);
-   pr_err(Unable to initialize EHCI power\n);
-   return;
-   }
-
usbhs_init(usbhs_bdata);
 }
 
-- 
1.5.3.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: [Patch v1] AM35xx-Craneboard:Update

2011-05-05 Thread Igor Grinberg
Hi Srinath,


On 05/05/11 10:15, srin...@mistralsolutions.com wrote:

 From: Srinath.R srin...@mistralsolutions.com

 Replaced gpio_request()/gpio_direction_output() with gpio_request_one() in 
 am3517_crane_init.

This has been already done and waits for Tony to apply.
Please, see:
http://www.spinics.net/lists/arm-kernel/msg123823.html


-- 
Regards,
Igor.

--
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] OMAP: DSS2: Add new color formats

2011-05-05 Thread Amber Jain
Added new color formats supported by OMAP4.

Signed-off-by: Amber Jain am...@ti.com
---
 arch/arm/plat-omap/include/plat/display.h |5 ++
 drivers/video/omap2/dss/dispc.c   |  107 -
 drivers/video/omap2/dss/dss_features.c|   43 +++-
 drivers/video/omap2/dss/manager.c |7 ++
 4 files changed, 129 insertions(+), 33 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/display.h 
b/arch/arm/plat-omap/include/plat/display.h
index 43b887b..1b8d83a 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -88,6 +88,11 @@ enum omap_color_mode {
OMAP_DSS_COLOR_ARGB32   = 1  11, /* ARGB32 */
OMAP_DSS_COLOR_RGBA32   = 1  12, /* RGBA32 */
OMAP_DSS_COLOR_RGBX32   = 1  13, /* RGBx32 */
+   OMAP_DSS_COLOR_NV12 = 1  14, /* NV12 format: YUV 4:2:0 */
+   OMAP_DSS_COLOR_RGBA16   = 1  15, /* RGBA16 -  */
+   OMAP_DSS_COLOR_RGBX16   = 1  16, /* RGBx16 -  */
+   OMAP_DSS_COLOR_ARGB16_1555  = 1  17, /* ARGB16 - 1555 */
+   OMAP_DSS_COLOR_XRGB16_1555  = 1  18, /* xRGB16 - 1555 */
 };
 
 enum omap_lcd_display_type {
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 4ed2ecf..f5a15dc 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -896,38 +896,76 @@ static void _dispc_set_color_mode(enum omap_plane plane,
enum omap_color_mode color_mode)
 {
u32 m = 0;
-
-   switch (color_mode) {
-   case OMAP_DSS_COLOR_CLUT1:
-   m = 0x0; break;
-   case OMAP_DSS_COLOR_CLUT2:
-   m = 0x1; break;
-   case OMAP_DSS_COLOR_CLUT4:
-   m = 0x2; break;
-   case OMAP_DSS_COLOR_CLUT8:
-   m = 0x3; break;
-   case OMAP_DSS_COLOR_RGB12U:
-   m = 0x4; break;
-   case OMAP_DSS_COLOR_ARGB16:
-   m = 0x5; break;
-   case OMAP_DSS_COLOR_RGB16:
-   m = 0x6; break;
-   case OMAP_DSS_COLOR_RGB24U:
-   m = 0x8; break;
-   case OMAP_DSS_COLOR_RGB24P:
-   m = 0x9; break;
-   case OMAP_DSS_COLOR_YUV2:
-   m = 0xa; break;
-   case OMAP_DSS_COLOR_UYVY:
-   m = 0xb; break;
-   case OMAP_DSS_COLOR_ARGB32:
-   m = 0xc; break;
-   case OMAP_DSS_COLOR_RGBA32:
-   m = 0xd; break;
-   case OMAP_DSS_COLOR_RGBX32:
-   m = 0xe; break;
-   default:
-   BUG(); break;
+   if (plane != OMAP_DSS_GFX) {
+   switch (color_mode) {
+   case OMAP_DSS_COLOR_NV12:
+   m = 0x0; break;
+   case OMAP_DSS_COLOR_RGB12U:
+   m = 0x1; break;
+   case OMAP_DSS_COLOR_RGBA16:
+   m = 0x2; break;
+   case OMAP_DSS_COLOR_RGBX16:
+   m = 0x4; break;
+   case OMAP_DSS_COLOR_ARGB16:
+   m = 0x5; break;
+   case OMAP_DSS_COLOR_RGB16:
+   m = 0x6; break;
+   case OMAP_DSS_COLOR_ARGB16_1555:
+   m = 0x7; break;
+   case OMAP_DSS_COLOR_RGB24U:
+   m = 0x8; break;
+   case OMAP_DSS_COLOR_RGB24P:
+   m = 0x9; break;
+   case OMAP_DSS_COLOR_YUV2:
+   m = 0xA; break;
+   case OMAP_DSS_COLOR_UYVY:
+   m = 0xB; break;
+   case OMAP_DSS_COLOR_ARGB32:
+   m = 0xC; break;
+   case OMAP_DSS_COLOR_RGBA32:
+   m = 0xD; break;
+   case OMAP_DSS_COLOR_RGBX32:
+   m = 0xE; break;
+   case OMAP_DSS_COLOR_XRGB16_1555:
+   m = 0xF; break;
+   default:
+   BUG(); break;
+   }
+   } else {
+   switch (color_mode) {
+   case OMAP_DSS_COLOR_CLUT1:
+   m = 0x0; break;
+   case OMAP_DSS_COLOR_CLUT2:
+   m = 0x1; break;
+   case OMAP_DSS_COLOR_CLUT4:
+   m = 0x2; break;
+   case OMAP_DSS_COLOR_CLUT8:
+   m = 0x3; break;
+   case OMAP_DSS_COLOR_RGB12U:
+   m = 0x4; break;
+   case OMAP_DSS_COLOR_ARGB16:
+   m = 0x5; break;
+   case OMAP_DSS_COLOR_RGB16:
+   m = 0x6; break;
+   case OMAP_DSS_COLOR_ARGB16_1555:
+   m = 0x7; break;
+   case OMAP_DSS_COLOR_RGB24U:
+   m = 0x8; break;
+   case OMAP_DSS_COLOR_RGB24P:
+   m = 0x9; break;
+   case OMAP_DSS_COLOR_YUV2:
+   m = 0xa; break;
+   case 

[PATCH] arm: omap3: cm-t35: add support for cm-t3730

2011-05-05 Thread Igor Grinberg
cm-t3730 is basically the same board as cm-t35, but has DM3730 SoC
assembled and therefore some changes are required.

Signed-off-by: Igor Grinberg grinb...@compulab.co.il
---
 arch/arm/mach-omap2/Kconfig|2 +-
 arch/arm/mach-omap2/board-cm-t35.c |   62 +++-
 2 files changed, 48 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index b997a35..920b6bc 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -266,7 +266,7 @@ config MACH_OMAP_ZOOM3
select REGULATOR_FIXED_VOLTAGE
 
 config MACH_CM_T35
-   bool CompuLab CM-T35 module
+   bool CompuLab CM-T35/CM-T3730 modules
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CUS
diff --git a/arch/arm/mach-omap2/board-cm-t35.c 
b/arch/arm/mach-omap2/board-cm-t35.c
index 6063be8..c0f6ce0 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -524,7 +524,7 @@ static void __init cm_t35_init_early(void)
 }
 
 #ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
+static struct omap_board_mux cm_t35_common_board_mux[] __initdata = {
/* nCS and IRQ for CM-T35 ethernet */
OMAP3_MUX(GPMC_NCS5, OMAP_MUX_MODE0),
OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
@@ -580,17 +580,12 @@ static struct omap_board_mux board_mux[] __initdata = {
OMAP3_MUX(UART1_TX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(UART1_RX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
 
-   /* DSS */
+   /* common DSS */
OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-   OMAP3_MUX(DSS_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-   OMAP3_MUX(DSS_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-   OMAP3_MUX(DSS_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-   OMAP3_MUX(DSS_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-   OMAP3_MUX(DSS_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-   OMAP3_MUX(DSS_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+
OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
@@ -603,12 +598,6 @@ static struct omap_board_mux board_mux[] __initdata = {
OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-   OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-   OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-   OMAP3_MUX(DSS_DATA20, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-   OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-   OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-   OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 
/* display controls */
OMAP3_MUX(MCBSP1_FSR, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
@@ -621,6 +610,39 @@ static struct omap_board_mux board_mux[] __initdata = {
 
{ .reg_offset = OMAP_MUX_TERMINATOR },
 };
+
+static void cm_t35_mux_init(void)
+{
+   int mux_mode = OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT;
+
+   omap3_mux_init(cm_t35_common_board_mux, OMAP_PACKAGE_CUS);
+
+   if (cpu_is_omap34xx()) {
+   omap_mux_init_signal(gpio_70, mux_mode);
+   omap_mux_init_signal(gpio_71, mux_mode);
+   omap_mux_init_signal(gpio_72, mux_mode);
+   omap_mux_init_signal(gpio_73, mux_mode);
+   omap_mux_init_signal(gpio_74, mux_mode);
+   omap_mux_init_signal(gpio_75, mux_mode);
+   } else if (cpu_is_omap3630()) {
+   mux_mode = OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT;
+   omap_mux_init_signal(sys_boot0, mux_mode);
+   omap_mux_init_signal(sys_boot1, mux_mode);
+   omap_mux_init_signal(sys_boot3, mux_mode);
+   omap_mux_init_signal(sys_boot4, mux_mode);
+   omap_mux_init_signal(sys_boot5, mux_mode);
+   omap_mux_init_signal(sys_boot6, mux_mode);
+   }
+
+   omap_mux_init_signal(dss_data18, mux_mode);
+   omap_mux_init_signal(dss_data19, mux_mode);
+   omap_mux_init_signal(dss_data20, mux_mode);
+   omap_mux_init_signal(dss_data21, mux_mode);
+   omap_mux_init_signal(dss_data22, mux_mode);
+   omap_mux_init_signal(dss_data23, mux_mode);
+}
+#else
+static inline void cm_t35_mux_init(void) {}
 #endif
 
 static struct omap_board_config_kernel cm_t35_config[] __initdata = {
@@ -630,7 +652,7 @@ static void __init cm_t35_init(void)
 {
omap_board_config = cm_t35_config;
omap_board_config_size = ARRAY_SIZE(cm_t35_config);
-   

RE: [PATCH v2 5/7] OMAP: DSS: Adding initialization routine to picodlp panel

2011-05-05 Thread Tomi Valkeinen
On Wed, 2011-05-04 at 20:01 +0530, Janorkar, Mayuresh wrote:
 
  -Original Message-
  From: Valkeinen, Tomi
  Sent: Wednesday, May 04, 2011 12:28 AM
  To: Janorkar, Mayuresh
  Cc: linux-omap@vger.kernel.org; K, Mythri P
  Subject: Re: [PATCH v2 5/7] OMAP: DSS: Adding initialization routine to
  picodlp panel
  
  On Mon, 2011-05-02 at 20:22 +0530, Mayuresh Janorkar wrote:
   From: Mythri P K mythr...@ti.com
  
   picodlp_i2c_client needs to send commands over i2c as a part of
  initialiazation.
   system controller dlp pico processor dpp2600 is used.
   It configures the splash screen of picodlp using a sequence of commands.
   A programmer's guide is available at:
   http://focus.ti.com/lit/ug/dlpu002a/dlpu002a.pdf
  
   API is defined for sending command over i2c as an i2c_write operation.
  
   Signed-off-by: Mythri P K mythr...@ti.com
   Signed-off-by: Mayuresh Janorkar ma...@ti.com
   ---
   Changes since v1:
 1. Removed initial splash screen
 2. i2c_commands regrouped
 3. Removed long msleep
 4. Added try-after-sleep in i2c_write
  
drivers/video/omap2/displays/panel-picodlp.c |  212
  ++
1 files changed, 212 insertions(+), 0 deletions(-)
  
   diff --git a/drivers/video/omap2/displays/panel-picodlp.c
  b/drivers/video/omap2/displays/panel-picodlp.c
   index fdbfdcf..493a411 100644
   --- a/drivers/video/omap2/displays/panel-picodlp.c
   +++ b/drivers/video/omap2/displays/panel-picodlp.c
   @@ -32,7 +32,15 @@
#include plat/display.h
#include plat/panel-picodlp.h
  
   +#include panel-picodlp.h
   +
#define DRIVER_NAME  picodlp_i2c_driver
   +
   +/* This defines the minit of data which is allowed into single write
  block */
   +#define MAX_I2C_WRITE_BLOCK_SIZE 32
   +#define PICO_MAJOR   1 /* 2 bits */
   +#define PICO_MINOR   1 /* 2 bits */
   +
struct picodlp_data {
 struct mutex lock;
 struct i2c_client *picodlp_i2c_client;
   @@ -50,6 +58,11 @@ struct i2c_device_id picodlp_i2c_id[] = {
 { picodlp_i2c_driver, 0 },
};
  
   +struct picodlp_i2c_command {
   + u8 reg;
   + u32 value;
   +};
   +
static struct omap_video_timings pico_ls_timings = {
 .x_res  = 864,
 .y_res  = 480,
   @@ -70,6 +83,197 @@ static inline struct picodlp_panel_data
 return (struct picodlp_panel_data *) dssdev-data;
}
  
   +static int picodlp_i2c_write_block(struct i2c_client *client,
   + u8 *data, int len)
   +{
   + struct i2c_msg msg;
   + int i, r, msg_count = 1, trial = 4;
   +
   + struct picodlp_i2c_data *picodlp_i2c_data =
  i2c_get_clientdata(client);
   +
   + if (len  1 || len  MAX_I2C_WRITE_BLOCK_SIZE) {
   + dev_err(client-dev,
   + too long syn_write_block len %d\n, len);
   + return -EIO;
   + }
   +retry:
   + mutex_lock(picodlp_i2c_data-xfer_lock);
   +
   + msg.addr = client-addr;
   + msg.flags = 0;
   + msg.len = len;
   + msg.buf = data;
   + r = i2c_transfer(client-adapter, msg, msg_count);
   + mutex_unlock(picodlp_i2c_data-xfer_lock);
   +
   + /*
   +  * i2c_transfer returns:
   +  * number of messages sent in case of success
   +  * a negative error number in case of failure
   +  * i2c controller might timeout, in such a case sleep for sometime
   +  * and then retry
   +  */
   + if (r != msg_count) {
   + msleep(2);
   + if (trial--)
   + goto retry;
  
  This is not good. Hacks like these should only be used as a last option.
  
  I'm still saying that you should find the document mentioned in the
  documents you have. I refuse to believe that we (TI) do not know what
  our hardware does, especially in a basic issue like this.
  
  I'm 99% sure there is documentation telling the required power-up
  sequence. And if that 1% happens, we should find the HW designers and
  yell at them until they make the documents.
 
 Yes it is mentioned.
 You can check it here:
 https://focus.ti.com/myti/docs/extranet.tsp?sectionId=403
 
 A delay is required after i2c client creation and it is 1 second.
 So this part of code would be removed.

The document says that time between when PWRGOOD goes high and when the
first i2c command can be sent is 1 second. (although I have no idea what
PWRGOOD is since the gpio names in the code do not match any documents).

In that case you should probably store the current time when PWRGOOD is
set high, and wait before sending the first i2c commands so that one
second has passed since PWRGOOD.

If that happens in the same function it's most likely just the same to
use msleep(1) there.

 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] arm: omap3: cm-t35: add support for cm-t3730

2011-05-05 Thread Mike Rapoport
On 05/05/11 11:53, Igor Grinberg wrote:
 cm-t3730 is basically the same board as cm-t35, but has DM3730 SoC
 assembled and therefore some changes are required.
 
 Signed-off-by: Igor Grinberg grinb...@compulab.co.il
 ---
  arch/arm/mach-omap2/Kconfig|2 +-
  arch/arm/mach-omap2/board-cm-t35.c |   62 
 +++-
  2 files changed, 48 insertions(+), 16 deletions(-)

Acked-by: Mike Rapoport m...@compulab.co.il

 
 diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
 index b997a35..920b6bc 100644
 --- a/arch/arm/mach-omap2/Kconfig
 +++ b/arch/arm/mach-omap2/Kconfig
 @@ -266,7 +266,7 @@ config MACH_OMAP_ZOOM3
   select REGULATOR_FIXED_VOLTAGE
  
  config MACH_CM_T35
 - bool CompuLab CM-T35 module
 + bool CompuLab CM-T35/CM-T3730 modules
   depends on ARCH_OMAP3
   default y
   select OMAP_PACKAGE_CUS
 diff --git a/arch/arm/mach-omap2/board-cm-t35.c 
 b/arch/arm/mach-omap2/board-cm-t35.c
 index 6063be8..c0f6ce0 100644
 --- a/arch/arm/mach-omap2/board-cm-t35.c
 +++ b/arch/arm/mach-omap2/board-cm-t35.c
 @@ -524,7 +524,7 @@ static void __init cm_t35_init_early(void)
  }
  
  #ifdef CONFIG_OMAP_MUX
 -static struct omap_board_mux board_mux[] __initdata = {
 +static struct omap_board_mux cm_t35_common_board_mux[] __initdata = {
   /* nCS and IRQ for CM-T35 ethernet */
   OMAP3_MUX(GPMC_NCS5, OMAP_MUX_MODE0),
   OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
 @@ -580,17 +580,12 @@ static struct omap_board_mux board_mux[] __initdata = {
   OMAP3_MUX(UART1_TX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
   OMAP3_MUX(UART1_RX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
  
 - /* DSS */
 + /* common DSS */
   OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
   OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
   OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
   OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 - OMAP3_MUX(DSS_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 - OMAP3_MUX(DSS_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 - OMAP3_MUX(DSS_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 - OMAP3_MUX(DSS_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 - OMAP3_MUX(DSS_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 - OMAP3_MUX(DSS_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 +
   OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
   OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
   OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 @@ -603,12 +598,6 @@ static struct omap_board_mux board_mux[] __initdata = {
   OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
   OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
   OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 - OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 - OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 - OMAP3_MUX(DSS_DATA20, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 - OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 - OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
 - OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
  
   /* display controls */
   OMAP3_MUX(MCBSP1_FSR, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
 @@ -621,6 +610,39 @@ static struct omap_board_mux board_mux[] __initdata = {
  
   { .reg_offset = OMAP_MUX_TERMINATOR },
  };
 +
 +static void cm_t35_mux_init(void)
 +{
 + int mux_mode = OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT;
 +
 + omap3_mux_init(cm_t35_common_board_mux, OMAP_PACKAGE_CUS);
 +
 + if (cpu_is_omap34xx()) {
 + omap_mux_init_signal(gpio_70, mux_mode);
 + omap_mux_init_signal(gpio_71, mux_mode);
 + omap_mux_init_signal(gpio_72, mux_mode);
 + omap_mux_init_signal(gpio_73, mux_mode);
 + omap_mux_init_signal(gpio_74, mux_mode);
 + omap_mux_init_signal(gpio_75, mux_mode);
 + } else if (cpu_is_omap3630()) {
 + mux_mode = OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT;
 + omap_mux_init_signal(sys_boot0, mux_mode);
 + omap_mux_init_signal(sys_boot1, mux_mode);
 + omap_mux_init_signal(sys_boot3, mux_mode);
 + omap_mux_init_signal(sys_boot4, mux_mode);
 + omap_mux_init_signal(sys_boot5, mux_mode);
 + omap_mux_init_signal(sys_boot6, mux_mode);
 + }
 +
 + omap_mux_init_signal(dss_data18, mux_mode);
 + omap_mux_init_signal(dss_data19, mux_mode);
 + omap_mux_init_signal(dss_data20, mux_mode);
 + omap_mux_init_signal(dss_data21, mux_mode);
 + omap_mux_init_signal(dss_data22, mux_mode);
 + omap_mux_init_signal(dss_data23, mux_mode);
 +}
 +#else
 +static inline void cm_t35_mux_init(void) {}
  #endif
  
  static struct omap_board_config_kernel cm_t35_config[] __initdata = {
 @@ -630,7 +652,7 @@ static void __init cm_t35_init(void)
  {
   omap_board_config = cm_t35_config;
   

Re: Is there boot logo support for OMAP3530?

2011-05-05 Thread Mohamed Thalib H

Hi Elvis,

Thanks for the information..

On Wednesday 04 May 2011 04:44 PM, Elvis Dowson wrote:

Hi,

On May 4, 2011, at 12:59 PM, Mohamed Thalib H wrote:

Is boot logo not supported in OMAP3530?

There are two ways you can add a boot logo to your target platform (Overo or 
BeagleBoard), one is to modify u-boot so that a boot logo is display immediately 
after powering on the system. The other is to add the boot logo to the kernel, in 
which case you have run 'make menuconfig', go to Device Drivers -  Graphics - 
 OMAP 2/3 display subysystem and somewhere in those options, you will see a boot logo 
option.

I prefer the u-boot option. The standard Overo distribution images have the 
linux boot option (you'll see a penguin on boot)
I was missing some options in the kernel config. after setting those I 
can see the penguin on boot.

To embed your logo within u-boot, you will need to modify the Denx u-boot 
sources. v2010.06 works from the denx git repo. I had some issues with v2011.03 
with the Overo.

http://git.denx.de/?p=u-boot.git;a=summary

What you will need to do is to use the linux gimp program to open a boot logo 
image file and save it as a C header file.

After that, you can copy the *header_data array to the logo.h file for the 
target board; and adjust the beagle/overo_width and beagle/overo_height values 
to correctly reflect to your logo image size.
Thanks for this pointer, I really need this since the logo can be shown 
very earlier.

Elvis Dowson

Best Regards,
Mohamed Thalib H
--
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: [Q] USB OTG host

2011-05-05 Thread Mohamed Thalib H

Hi,

On Wednesday 04 May 2011 07:33 PM, Jan Weitzel wrote:

Hello,
I am using drivers/usb/musb/omap2430.c for a board configured in
MUSB_OTG mode.
Is it correct that I need to load gadget driver to get it working as
host?

No. Host mode don't need gadget driver. Once OTG mode needs them.

I got an USB_EVENT_ID event, but in musb_otg_notifications vbus will not
switched on if !musb-gadget_driver.
Any ideas?
Kind regards,
Jan Weitzel

--
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

Mohamed Thalib H.
--
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 02/22] OMAP: DMA: add omap_dma_has_sglist()

2011-05-05 Thread Adrian Hunter
Simplify detection of the sglist feature and add a
define for the super block end event that occurs
with sglist transfers.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
CC: Venkatraman S svenk...@ti.com
CC: Madhusudhan C madhu...@ti.com
CC: Shilimkar Santosh santosh.shilim...@ti.com
CC: Tony Lindgren t...@atomide.com
---
 arch/arm/plat-omap/dma.c  |5 +
 arch/arm/plat-omap/include/plat/dma.h |3 +++
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 7f64366..32a923a 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -1862,6 +1862,11 @@ int omap_get_dma_chain_src_pos(int chain_id)
 EXPORT_SYMBOL(omap_get_dma_chain_src_pos);
 #endif /* ifndef CONFIG_ARCH_OMAP1 */
 
+int omap_dma_has_sglist_mode(void)
+{
+   return dma_caps0_status  DMA_CAPS_SGLIST_SUPPORT;
+}
+
 int omap_set_dma_sglist_mode(int lch, struct omap_dma_sglist_node *sgparams,
dma_addr_t padd, int nelem, struct omap_dma_channel_params *chparams)
 {
diff --git a/arch/arm/plat-omap/include/plat/dma.h 
b/arch/arm/plat-omap/include/plat/dma.h
index 4d73eb1..3536eb4 100644
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -209,6 +209,7 @@
 #define OMAP2_DMA_SECURE_ERR_IRQ   (1  9)
 #define OMAP2_DMA_SUPERVISOR_ERR_IRQ   (1  10)
 #define OMAP2_DMA_MISALIGNED_ERR_IRQ   (1  11)
+#define OMAP2_DMA_SUPER_BLOCK_IRQ  (1  14)
 
 #define OMAP_DMA_CCR_EN(1  7)
 #define OMAP_DMA_CCR_RD_ACTIVE (1  9)
@@ -616,6 +617,8 @@ static inline int omap_lcd_dma_running(void)
 }
 #endif
 
+extern int omap_dma_has_sglist_mode(void);
+
 /**
  * omap_set_dma_sglist_mode()  Switch channel to scatter gather mode
  * @lch:   Logical channel to switch to sglist mode
-- 
1.7.0.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


[PATCH 04/22] mmc: omap hsmmc: adaptation of sdma descriptor

2011-05-05 Thread Adrian Hunter
From: Venkatraman S svenk...@ti.com

autoloading feature

Start to use the sDMA descriptor autoloading feature.
For large datablocks, the MMC driver has to repeatedly setup,
program and teardown the dma channel for each element of the
sglist received in omap_hsmmc_request.

By using descriptor autoloading, transfers from / to each element of
the sglist is pre programmed into a linked list. The sDMA driver
completes the entire transaction and provides a single interrupt.

Due to this, number of dma interrupts for a typical 100MB transfer on the MMC is
reduced from 25000 to about 400 (approximate). Transfer speeds are improved by 
~5%.
(Though it varies on the size of read / write  improves on huge transfers)

Descriptor autoloading is available only in 3630 and 4430 (as of now).
Hence normal DMA mode is also retained.

Signed-off-by: Venkatraman S svenk...@ti.com
CC: Madhusudhan C madhu...@ti.com
CC: Shilimkar Santosh santosh.shilim...@ti.com
CC: Tony Lindgren t...@atomide.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |  147 ++--
 1 files changed, 125 insertions(+), 22 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 259ece0..ebcef31 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -104,6 +104,8 @@
 #define SRD(1  26)
 #define SOFTRESET  (1  1)
 #define RESETDONE  (1  0)
+/* End of superblock indicator for sglist transfers */
+#define DMA_ICR_SGLIST_END 0x4D00
 
 /*
  * FIXME: Most likely all the data using these _DEVID defines should come
@@ -120,6 +122,12 @@
 #define OMAP_MMC_MASTER_CLOCK  9600
 #define DRIVER_NAMEomap_hsmmc
 
+#define DMA_TYPE_NODMA 0
+#define DMA_TYPE_SDMA  1
+#define DMA_TYPE_SDMA_DLOAD 2
+
+#define DMA_CTRL_BUF_SIZE  (PAGE_SIZE * 3)
+
 /* Timeouts for entering power saving states on inactivity, msec */
 #define OMAP_MMC_DISABLED_TIMEOUT  100
 #define OMAP_MMC_SLEEP_TIMEOUT 1000
@@ -172,7 +180,11 @@ struct omap_hsmmc_host {
u32 bytesleft;
int suspended;
int irq;
-   int use_dma, dma_ch;
+   int dma_caps;
+   int dma_in_use;
+   int dma_ch;
+   void*dma_ctrl_buf;
+   dma_addr_t  dma_ctrl_buf_phy;
int dma_line_tx, dma_line_rx;
int slot_id;
int got_dbclk;
@@ -561,7 +573,7 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host 
*host,
 {
unsigned int irq_mask;
 
-   if (host-use_dma)
+   if (host-dma_in_use)
irq_mask = INT_EN_MASK  ~(BRR_ENABLE | BWR_ENABLE);
else
irq_mask = INT_EN_MASK;
@@ -851,7 +863,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, 
struct mmc_command *cmd,
cmdreg = ~(DDIR);
}
 
-   if (host-use_dma)
+   if (host-dma_in_use)
cmdreg |= DMA_EN;
 
host-req_in_progress = 1;
@@ -880,7 +892,7 @@ static void omap_hsmmc_request_done(struct omap_hsmmc_host 
*host, struct mmc_req
 
omap_hsmmc_disable_irq(host);
/* Do not complete the request if DMA is still in progress */
-   if (mrq-data  host-use_dma  dma_ch != -1)
+   if (mrq-data  host-dma_in_use  dma_ch != -1)
return;
host-mrq = NULL;
mmc_request_done(host-mmc, mrq);
@@ -958,7 +970,7 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host 
*host, int errno)
host-dma_ch = -1;
spin_unlock(host-irq_lock);
 
-   if (host-use_dma  dma_ch != -1) {
+   if (host-dma_in_use  dma_ch != -1) {
dma_unmap_sg(mmc_dev(host-mmc), host-data-sg, host-dma_len,
omap_hsmmc_get_dma_dir(host, host-data));
omap_free_dma(dma_ch);
@@ -1310,7 +1322,6 @@ static void omap_hsmmc_config_dma_params(struct 
omap_hsmmc_host *host,
omap_hsmmc_get_dma_sync_dev(host, data),
!(data-flags  MMC_DATA_WRITE));
 
-   omap_start_dma(dma_ch);
 }
 
 /*
@@ -1334,13 +1345,16 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, 
void *cb_data)
return;
}
 
-   host-dma_sg_idx++;
-   if (host-dma_sg_idx  host-dma_len) {
-   /* Fire up the next transfer. */
-   omap_hsmmc_config_dma_params(host, data,
-  data-sg + host-dma_sg_idx);
-   spin_unlock(host-irq_lock);
-   return;
+   if (host-dma_in_use == DMA_TYPE_SDMA) {
+   host-dma_sg_idx++;
+   if (host-dma_sg_idx  host-dma_len) {
+   /* Fire up the next transfer. */
+   

[PATCH 01/22] OMAP: sDMA: descriptor autoloading feature

2011-05-05 Thread Adrian Hunter
From: Venkatraman S svenk...@ti.com

Add sDMA driver support for descriptor autoloading feature.
 Descriptor autoloading is OMAP sDMA v5 hardware capability that can be 
exploited for scatter gather
 scenarios, currently available in OMAP3630 and OMAP4430.

  The feature works as described below.
  1) A sDMA channel is programmed to be in 'linked list' mode.
  2) The client (sDMA user) provides a list of descriptors in a linked list 
format.
  3) Each of the 'descriptor' (element in the linked list) contains an updated 
set of DMA
  configuration register values.
  4) Client starts DMA transfer.
  5) sDMA controller loads the first element to its register configuration 
memory and executes the
  transfer.
  6) After completion, loads the next element (in linked list) to configuration 
memory and executes
  the transfer, without MCU intervention.
  7) Interrupt is generated after all transfers are completed; this can be 
configured to be done
  differently.

  Configurations and additional features
  1) Fast mode  non-fast mode
Fast mode/non-fast decides on how the first transfer begins. In 
non-fast mode, the first
element in the linked list is loaded only after completing the transfer 
according to the
configurations already in the sDMA channel registers. In fast mode, the 
loading of the first
element precedes the transfer.

  2) Pause / resume of transfers
A transfer can be paused after a descriptor set has been loaded, 
provided the 'pause
bit' is set in the linked list element.
An ongoing transfer cannot be paused. If the 'pause bit' is set, 
transfer is not
started after loading the register set from memory.
Such a transfer can be resumed later.

  3) Descriptor types
3 possible configurations of descriptors (initialized as linked list 
elements)
are possible. Type 1 provides the maximum flexibility, which contains 
most
register definitions of a DMA logical channel. Fewer options are 
present in type
2. Type 3 can just modify source/destinations address of transfers. In 
all
transfers, unmodified registers settings are maintained for the next 
transfer.

Patch provides options / API for
1) Setting up a descriptor loading for DMA channel for sg type 
transfers
2) configuration with linked list elements
3) Starting / pause and resume of the said transfers, query state
4) Clearing the sglist mode

Signed-off-by: Venkatraman S svenk...@ti.com
CC: Madhusudhan C madhu...@ti.com
CC: Shilimkar Santosh santosh.shilim...@ti.com
CC: Tony Lindgren t...@atomide.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 arch/arm/plat-omap/dma.c  |  279 +
 arch/arm/plat-omap/include/plat/dma.h |  173 
 2 files changed, 452 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index c22217c..7f64366 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -52,16 +52,37 @@ enum { DMA_CH_ALLOC_DONE, DMA_CH_PARAMS_SET_DONE, 
DMA_CH_STARTED,
 enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
 #endif
 
+/* CDP Register bitmaps */
+#define DMA_LIST_CDP_DST_VALID BIT(0)
+#define DMA_LIST_CDP_SRC_VALID BIT(2)
+#define DMA_LIST_CDP_TYPE1 BIT(4)
+#define DMA_LIST_CDP_TYPE2 BIT(5)
+#define DMA_LIST_CDP_TYPE3 (BIT(4) | BIT(5))
+#define DMA_LIST_CDP_PAUSEMODE BIT(7)
+#define DMA_LIST_CDP_LISTMODE  BIT(8)
+#define DMA_LIST_CDP_FASTMODE  BIT(10)
+/* CAPS register bitmaps */
+#define DMA_CAPS_SGLIST_SUPPORTBIT(20)
+
+#define DMA_LIST_DESC_PAUSEBIT(0)
+#define DMA_LIST_DESC_SRC_VALIDBIT(24)
+#define DMA_LIST_DESC_DST_VALIDBIT(26)
+#define DMA_LIST_DESC_BLK_END  BIT(28)
+
 #define OMAP_DMA_ACTIVE0x01
 #define OMAP2_DMA_CSR_CLEAR_MASK   0x
 
 #define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
+#define OMAP_DMA_INVALID_FRAME_COUNT   0x
+#define OMAP_DMA_INVALID_ELEM_COUNT0xff
+#define OMAP_DMA_INVALID_DESCRIPTOR_POINTER0xfffc
 
 static struct omap_system_dma_plat_info *p;
 static struct omap_dma_dev_attr *d;
 
 static int enable_1510_mode;
 static u32 errata;
+static int dma_caps0_status;
 
 static struct omap_dma_global_context_registers {
u32 dma_irqenable_l0;
@@ -166,6 +187,76 @@ static inline void set_gdma_dev(int req, int dev)
 #define set_gdma_dev(req, dev) do {} while (0)
 #endif
 
+static inline void omap_dma_list_set_ntype(struct omap_dma_sglist_node *node,
+  int value)
+{
+   node-num_of_elem |= ((value)  29);
+}
+
+static void omap_set_dma_sglist_pausebit(
+   struct omap_dma_list_config_params *lcfg, int nelem, int set)
+{
+   struct omap_dma_sglist_node *sgn = lcfg-sghead;
+
+   if (nelem  0  nelem  lcfg-num_elem) {
+   lcfg-pausenode = nelem;
+ 

[PATCH 16/22] OMAP: board-rm680: set MMC nomux flag

2011-05-05 Thread Adrian Hunter
Let the bootloader do all the pad configuration.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 arch/arm/mach-omap2/board-rm680.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-rm680.c 
b/arch/arm/mach-omap2/board-rm680.c
index 2af8b05..2dba9d0 100644
--- a/arch/arm/mach-omap2/board-rm680.c
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -125,6 +125,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
.caps   = MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED,
.gpio_cd= -EINVAL,
.gpio_wp= -EINVAL,
+   .nomux  = true,
},
{ /* Terminator */ }
 };
-- 
1.7.0.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


[PATCH 15/22] OMAP: hsmmc: Do not mux the slot if non default muxing is already done

2011-05-05 Thread Adrian Hunter
From: Jarkko Lavinen jarkko.lavi...@nokia.com

Allow the bootloader do all the muxing.

Signed-off-by: Jarkko Lavinen jarkko.lavi...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 arch/arm/mach-omap2/hsmmc.c |3 ++-
 arch/arm/mach-omap2/hsmmc.h |1 +
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index b2f30be..6b97fae 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -440,7 +440,8 @@ void __init omap_init_hsmmc(struct omap2_hsmmc_info 
*hsmmcinfo, int ctrl_nr)
pr_err(%s fails!\n, __func__);
goto done;
}
-   omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
+   if (!hsmmcinfo-nomux)
+   omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
 
name = omap_hsmmc;
ohl = omap_hsmmc_latency;
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index f119348..0f2a87e 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -19,6 +19,7 @@ struct omap2_hsmmc_info {
boolpower_saving;   /* Try to sleep or power off when possible */
boolno_off; /* power_saving and power is not to go off */
boolvcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
+   boolnomux;  /* No default muxing for this slot */
int gpio_cd;/* or -EINVAL */
int gpio_wp;/* or -EINVAL */
char*name;  /* or NULL for default */
-- 
1.7.0.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


[PATCH 09/22] mmc: omap_hsmmc: move hardcoded frequency constants to definition block

2011-05-05 Thread Adrian Hunter
From: Andy Shevchenko ext-andriy.shevche...@nokia.com

Move the min and max frequency constants to the definition block in the source
file.

Signed-off-by: Andy Shevchenko ext-andriy.shevche...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index a1a1101..a727bf8 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -120,6 +120,8 @@
 
 #define MMC_TIMEOUT_MS 20
 #define OMAP_MMC_MASTER_CLOCK  9600
+#define OMAP_MMC_MIN_CLOCK 40
+#define OMAP_MMC_MAX_CLOCK 5200
 #define DRIVER_NAMEomap_hsmmc
 
 #define DMA_TYPE_NODMA 0
@@ -2176,8 +2178,8 @@ static int __init omap_hsmmc_probe(struct platform_device 
*pdev)
if (mmc_slot(host).vcc_aux_disable_is_sleep)
mmc_slot(host).no_off = 1;
 
-   mmc-f_min  = 40;
-   mmc-f_max  = 5200;
+   mmc-f_min  = OMAP_MMC_MIN_CLOCK;
+   mmc-f_max  = OMAP_MMC_MAX_CLOCK;
 
spin_lock_init(host-irq_lock);
 
-- 
1.7.0.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


[PATCH 12/22] mmc: omap_hsmmc: introduce start_clock and re-use stop_clock

2011-05-05 Thread Adrian Hunter
From: Andy Shevchenko ext-andriy.shevche...@nokia.com

There is similar piece of code in two functions which enables clock. Split this
code to omap_hsmmc_start_clock(). Re-use omap_hsmmc_stop_clock() in
omap_hsmmc_context_restore() as well.

Signed-off-by: Andy Shevchenko ext-andriy.shevche...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   19 +--
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 045c581..ae6d204 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -560,6 +560,15 @@ static void omap_hsmmc_gpio_free(struct 
omap_mmc_platform_data *pdata)
 }
 
 /*
+ * Start clock to the card
+ */
+static void omap_hsmmc_start_clock(struct omap_hsmmc_host *host)
+{
+   OMAP_HSMMC_WRITE(host-base, SYSCTL,
+   OMAP_HSMMC_READ(host-base, SYSCTL) | CEN);
+}
+
+/*
  * Stop clock to the card
  */
 static void omap_hsmmc_stop_clock(struct omap_hsmmc_host *host)
@@ -700,8 +709,8 @@ static int omap_hsmmc_context_restore(struct 
omap_hsmmc_host *host)
break;
}
 
-   OMAP_HSMMC_WRITE(host-base, SYSCTL,
-   OMAP_HSMMC_READ(host-base, SYSCTL)  ~CEN);
+   omap_hsmmc_stop_clock(host);
+
OMAP_HSMMC_WRITE(host-base, SYSCTL,
(calc_divisor(ios)  6) | (DTO  16));
OMAP_HSMMC_WRITE(host-base, SYSCTL,
@@ -712,8 +721,7 @@ static int omap_hsmmc_context_restore(struct 
omap_hsmmc_host *host)
 time_before(jiffies, timeout))
;
 
-   OMAP_HSMMC_WRITE(host-base, SYSCTL,
-   OMAP_HSMMC_READ(host-base, SYSCTL) | CEN);
+   omap_hsmmc_start_clock(host);
 
con = OMAP_HSMMC_READ(host-base, CON);
if (ios-bus_mode == MMC_BUSMODE_OPENDRAIN)
@@ -1692,8 +1700,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
 time_before(jiffies, timeout))
msleep(1);
 
-   OMAP_HSMMC_WRITE(host-base, SYSCTL,
-   OMAP_HSMMC_READ(host-base, SYSCTL) | CEN);
+   omap_hsmmc_start_clock(host);
 
if (do_send_init_stream)
send_init_stream(host);
-- 
1.7.0.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


[PATCH 06/22] mmc: omap_hsmmc: limit scatterlist size for sDMA autoloading

2011-05-05 Thread Adrian Hunter
The sDMA descriptor autoloading feature uses a fixed size
buffer to store descriptors for scatterlist segments.
That limits the scatterlist size to the maximum number
of descriptors that fit in the buffer.  The driver must
set this limit for upper layers to obey.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   15 ---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 114cd68..bab25ff 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2239,9 +2239,18 @@ static int __init omap_hsmmc_probe(struct 
platform_device *pdev)
host-dma_caps |= DMA_TYPE_SDMA_DLOAD;
}
 
-   /* Since we do only SG emulation, we can have as many segs
-* as we want. */
-   mmc-max_segs = 1024;
+   if (host-dma_caps  DMA_TYPE_SDMA_DLOAD) {
+   unsigned int max = DMA_CTRL_BUF_SIZE /
+  sizeof(struct omap_dma_sglist_node);
+
+   mmc-max_segs = 1  (fls(max) - 1);
+   } else {
+   /*
+* Since we do only SG emulation, we can have as many segs as we
+* want.
+*/
+   mmc-max_segs = 1024;
+   }
 
mmc-max_blk_size = 512;   /* Block Length at max can be 1024 */
mmc-max_blk_count = 0x;/* No. of Blocks is 16 bits */
-- 
1.7.0.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


[PATCH 07/22] mmc: omap_hsmmc: fix missing mmc_release_host() in no_off case

2011-05-05 Thread Adrian Hunter
From: Sudhir Bera ext-sudhir.b...@nokia.com

In fact the no_off check here will not be hit because
'omap_hsmmc_disabled_to_sleep()' won't schedule a
deeper disable in the no_off case.

Signed-off-by: Sudhir Bera ext-sudhir.b...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |7 +++
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index bab25ff..bd52849 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1852,14 +1852,13 @@ static int omap_hsmmc_sleep_to_off(struct 
omap_hsmmc_host *host)
return 0;
 
if (mmc_slot(host).no_off)
-   return 0;
+   goto out;
 
if (!((host-mmc-caps  MMC_CAP_NONREMOVABLE) ||
  mmc_slot(host).card_detect ||
  (mmc_slot(host).get_cover_state 
   mmc_slot(host).get_cover_state(host-dev, host-slot_id {
-   mmc_release_host(host-mmc);
-   return 0;
+   goto out;
}
 
mmc_slot(host).set_power(host-dev, host-slot_id, 0, 0);
@@ -1870,7 +1869,7 @@ static int omap_hsmmc_sleep_to_off(struct omap_hsmmc_host 
*host)
host-dpm_state == CARDSLEEP ? CARDSLEEP : REGSLEEP);
 
host-dpm_state = OFF;
-
+out:
mmc_release_host(host-mmc);
 
return 0;
-- 
1.7.0.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


[PATCH 11/22] mmc: omap_hsmmc: split duplicate code to calc_divisor() function

2011-05-05 Thread Adrian Hunter
From: Andy Shevchenko ext-andriy.shevche...@nokia.com

There are two places where the same calculations are done. Let's split them to
separate function.

In addition the new function is simplified by usage DIV_ROUND_UP kernel macro.

Signed-off-by: Andy Shevchenko ext-andriy.shevche...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   45 
 1 files changed, 18 insertions(+), 27 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 7a153af..045c581 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -596,6 +596,20 @@ static void omap_hsmmc_disable_irq(struct omap_hsmmc_host 
*host)
OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
 }
 
+/* Calculate divisor for the given clock frequency */
+static u16 calc_divisor(struct mmc_ios *ios)
+{
+   u16 dsor = 0;
+
+   if (ios-clock) {
+   dsor = DIV_ROUND_UP(OMAP_MMC_MASTER_CLOCK, ios-clock);
+   if (dsor  250)
+   dsor = 250;
+   }
+
+   return dsor;
+}
+
 #ifdef CONFIG_PM
 
 /*
@@ -608,7 +622,6 @@ static int omap_hsmmc_context_restore(struct 
omap_hsmmc_host *host)
struct omap_mmc_platform_data *pdata = host-pdata;
int context_loss = 0;
u32 hctl, capa, con;
-   u16 dsor = 0;
unsigned long timeout;
 
if (pdata-get_context_loss_count) {
@@ -687,21 +700,10 @@ static int omap_hsmmc_context_restore(struct 
omap_hsmmc_host *host)
break;
}
 
-   if (ios-clock) {
-   dsor = OMAP_MMC_MASTER_CLOCK / ios-clock;
-   if (dsor  1)
-   dsor = 1;
-
-   if (OMAP_MMC_MASTER_CLOCK / dsor  ios-clock)
-   dsor++;
-
-   if (dsor  250)
-   dsor = 250;
-   }
-
OMAP_HSMMC_WRITE(host-base, SYSCTL,
OMAP_HSMMC_READ(host-base, SYSCTL)  ~CEN);
-   OMAP_HSMMC_WRITE(host-base, SYSCTL, (dsor  6) | (DTO  16));
+   OMAP_HSMMC_WRITE(host-base, SYSCTL,
+   (calc_divisor(ios)  6) | (DTO  16));
OMAP_HSMMC_WRITE(host-base, SYSCTL,
OMAP_HSMMC_READ(host-base, SYSCTL) | ICE);
 
@@ -1612,7 +1614,6 @@ static void omap_hsmmc_request(struct mmc_host *mmc, 
struct mmc_request *req)
 static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
struct omap_hsmmc_host *host = mmc_priv(mmc);
-   u16 dsor = 0;
unsigned long regval;
unsigned long timeout;
u32 con;
@@ -1676,21 +1677,11 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
}
}
 
-   if (ios-clock) {
-   dsor = OMAP_MMC_MASTER_CLOCK / ios-clock;
-   if (dsor  1)
-   dsor = 1;
-
-   if (OMAP_MMC_MASTER_CLOCK / dsor  ios-clock)
-   dsor++;
-
-   if (dsor  250)
-   dsor = 250;
-   }
omap_hsmmc_stop_clock(host);
+
regval = OMAP_HSMMC_READ(host-base, SYSCTL);
regval = regval  ~(CLKD_MASK);
-   regval = regval | (dsor  6) | (DTO  16);
+   regval = regval | (calc_divisor(ios)  6) | (DTO  16);
OMAP_HSMMC_WRITE(host-base, SYSCTL, regval);
OMAP_HSMMC_WRITE(host-base, SYSCTL,
OMAP_HSMMC_READ(host-base, SYSCTL) | ICE);
-- 
1.7.0.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


[PATCH 08/22] mmc: omap_hsmmc: correct debug report error status mnemonics

2011-05-05 Thread Adrian Hunter
CERR and BADA were in the wrong place and there are only
32 not 35.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   19 +++
 1 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index bd52849..a1a1101 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -982,14 +982,14 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host 
*host, int errno)
  * Readable error output
  */
 #ifdef CONFIG_MMC_DEBUG
-static void omap_hsmmc_report_irq(struct omap_hsmmc_host *host, u32 status)
+static void omap_hsmmc_dbg_report_irq(struct omap_hsmmc_host *host, u32 status)
 {
/* --- means reserved bit without definition at documentation */
static const char *omap_hsmmc_status_bits[] = {
-   CC, TC, BGE, ---, BWR, BRR, ---, ---, CIRQ,
-   OBI, ---, ---, ---, ---, ---, ERRI, CTO, CCRC,
-   CEB, CIE, DTO, DCRC, DEB, ---, ACE, ---,
-   ---, ---, ---, CERR, CERR, BADA, ---, ---, ---
+   CC  , TC  , BGE, ---, BWR , BRR , --- , --- ,
+   CIRQ, OBI , ---, ---, --- , --- , --- , ERRI,
+   CTO , CCRC, CEB, CIE, DTO , DCRC, DEB , --- ,
+   ACE , --- , ---, ---, CERR, BADA, --- , ---
};
char res[256];
char *buf = res;
@@ -1006,6 +1006,11 @@ static void omap_hsmmc_report_irq(struct omap_hsmmc_host 
*host, u32 status)
 
dev_dbg(mmc_dev(host-mmc), %s\n, res);
 }
+#else
+static inline void omap_hsmmc_dbg_report_irq(struct omap_hsmmc_host *host,
+u32 status)
+{
+}
 #endif  /* CONFIG_MMC_DEBUG */
 
 /*
@@ -1064,9 +1069,7 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host 
*host, int status)
dev_dbg(mmc_dev(host-mmc), IRQ Status is %x\n, status);
 
if (status  ERR) {
-#ifdef CONFIG_MMC_DEBUG
-   omap_hsmmc_report_irq(host, status);
-#endif
+   omap_hsmmc_dbg_report_irq(host, status);
if ((status  CMD_TIMEOUT) ||
(status  CMD_CRC)) {
if (host-cmd) {
-- 
1.7.0.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


[PATCH 13/22] mmc: omap_hsmmc: fix few bugs when set the clock divisor

2011-05-05 Thread Adrian Hunter
From: Andy Shevchenko ext-andriy.shevche...@nokia.com

There are two pieces of code which similar, but not the same. Each of them
contains a bug.

The SYSCTL register should be read before write in the
omap_hsmmc_context_restore() to remain the state of the reserved bits.

Before set the clock divisor and DTO bits the value from the SYSCTL register
should be masked properly. We were lucky to have no problems with DTO bits. So,
make sure we have clear DTO bits properly in the omap_hsmmc_set_ios().

Additionally get rid of msleep(1). The actual time rare higher than 30us on
OMAP 3630.

The result pieces of code are split to omap_hsmmc_set_clock() function.

Signed-off-by: Andy Shevchenko ext-andriy.shevche...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   59 +++-
 1 files changed, 28 insertions(+), 31 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index ae6d204..3c76911 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -619,6 +619,32 @@ static u16 calc_divisor(struct mmc_ios *ios)
return dsor;
 }
 
+static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
+{
+   struct mmc_ios *ios = host-mmc-ios;
+   unsigned long regval;
+   unsigned long timeout;
+
+   dev_dbg(mmc_dev(host-mmc), Set clock to %uHz\n, ios-clock);
+
+   omap_hsmmc_stop_clock(host);
+
+   regval = OMAP_HSMMC_READ(host-base, SYSCTL);
+   regval = regval  ~(CLKD_MASK | DTO_MASK);
+   regval = regval | (calc_divisor(ios)  6) | (DTO  16);
+   OMAP_HSMMC_WRITE(host-base, SYSCTL, regval);
+   OMAP_HSMMC_WRITE(host-base, SYSCTL,
+   OMAP_HSMMC_READ(host-base, SYSCTL) | ICE);
+
+   /* Wait till the ICS bit is set */
+   timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
+   while ((OMAP_HSMMC_READ(host-base, SYSCTL)  ICS) != ICS
+time_before(jiffies, timeout))
+   ;
+
+   omap_hsmmc_start_clock(host);
+}
+
 #ifdef CONFIG_PM
 
 /*
@@ -709,19 +735,7 @@ static int omap_hsmmc_context_restore(struct 
omap_hsmmc_host *host)
break;
}
 
-   omap_hsmmc_stop_clock(host);
-
-   OMAP_HSMMC_WRITE(host-base, SYSCTL,
-   (calc_divisor(ios)  6) | (DTO  16));
-   OMAP_HSMMC_WRITE(host-base, SYSCTL,
-   OMAP_HSMMC_READ(host-base, SYSCTL) | ICE);
-
-   timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
-   while ((OMAP_HSMMC_READ(host-base, SYSCTL)  ICS) != ICS
-time_before(jiffies, timeout))
-   ;
-
-   omap_hsmmc_start_clock(host);
+   omap_hsmmc_set_clock(host);
 
con = OMAP_HSMMC_READ(host-base, CON);
if (ios-bus_mode == MMC_BUSMODE_OPENDRAIN)
@@ -1622,8 +1636,6 @@ static void omap_hsmmc_request(struct mmc_host *mmc, 
struct mmc_request *req)
 static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
struct omap_hsmmc_host *host = mmc_priv(mmc);
-   unsigned long regval;
-   unsigned long timeout;
u32 con;
int do_send_init_stream = 0;
 
@@ -1685,22 +1697,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
}
}
 
-   omap_hsmmc_stop_clock(host);
-
-   regval = OMAP_HSMMC_READ(host-base, SYSCTL);
-   regval = regval  ~(CLKD_MASK);
-   regval = regval | (calc_divisor(ios)  6) | (DTO  16);
-   OMAP_HSMMC_WRITE(host-base, SYSCTL, regval);
-   OMAP_HSMMC_WRITE(host-base, SYSCTL,
-   OMAP_HSMMC_READ(host-base, SYSCTL) | ICE);
-
-   /* Wait till the ICS bit is set */
-   timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
-   while ((OMAP_HSMMC_READ(host-base, SYSCTL)  ICS) != ICS
-time_before(jiffies, timeout))
-   msleep(1);
-
-   omap_hsmmc_start_clock(host);
+   omap_hsmmc_set_clock(host);
 
if (do_send_init_stream)
send_init_stream(host);
-- 
1.7.0.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


[PATCH 14/22] mmc: omap_hsmmc: split same pieces of code to separate functions

2011-05-05 Thread Adrian Hunter
From: Andy Shevchenko ext-andriy.shevche...@nokia.com

There are few places with the same functionality. This patch creates two
functions omap_hsmmc_set_bus_width() and omap_hsmmc_set_bus_mode() to do the
job.

Signed-off-by: Andy Shevchenko ext-andriy.shevche...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   85 -
 1 files changed, 41 insertions(+), 44 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 3c76911..e7c181a 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -645,6 +645,41 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host 
*host)
omap_hsmmc_start_clock(host);
 }
 
+static void omap_hsmmc_set_bus_width(struct omap_hsmmc_host *host)
+{
+   struct mmc_ios *ios = host-mmc-ios;
+   u32 con;
+
+   con = OMAP_HSMMC_READ(host-base, CON);
+   switch (ios-bus_width) {
+   case MMC_BUS_WIDTH_8:
+   OMAP_HSMMC_WRITE(host-base, CON, con | DW8);
+   break;
+   case MMC_BUS_WIDTH_4:
+   OMAP_HSMMC_WRITE(host-base, CON, con  ~DW8);
+   OMAP_HSMMC_WRITE(host-base, HCTL,
+   OMAP_HSMMC_READ(host-base, HCTL) | FOUR_BIT);
+   break;
+   case MMC_BUS_WIDTH_1:
+   OMAP_HSMMC_WRITE(host-base, CON, con  ~DW8);
+   OMAP_HSMMC_WRITE(host-base, HCTL,
+   OMAP_HSMMC_READ(host-base, HCTL)  ~FOUR_BIT);
+   break;
+   }
+}
+
+static void omap_hsmmc_set_bus_mode(struct omap_hsmmc_host *host)
+{
+   struct mmc_ios *ios = host-mmc-ios;
+   u32 con;
+
+   con = OMAP_HSMMC_READ(host-base, CON);
+   if (ios-bus_mode == MMC_BUSMODE_OPENDRAIN)
+   OMAP_HSMMC_WRITE(host-base, CON, con | OD);
+   else
+   OMAP_HSMMC_WRITE(host-base, CON, con  ~OD);
+}
+
 #ifdef CONFIG_PM
 
 /*
@@ -656,7 +691,7 @@ static int omap_hsmmc_context_restore(struct 
omap_hsmmc_host *host)
struct mmc_ios *ios = host-mmc-ios;
struct omap_mmc_platform_data *pdata = host-pdata;
int context_loss = 0;
-   u32 hctl, capa, con;
+   u32 hctl, capa;
unsigned long timeout;
 
if (pdata-get_context_loss_count) {
@@ -718,30 +753,12 @@ static int omap_hsmmc_context_restore(struct 
omap_hsmmc_host *host)
if (host-power_mode == MMC_POWER_OFF)
goto out;
 
-   con = OMAP_HSMMC_READ(host-base, CON);
-   switch (ios-bus_width) {
-   case MMC_BUS_WIDTH_8:
-   OMAP_HSMMC_WRITE(host-base, CON, con | DW8);
-   break;
-   case MMC_BUS_WIDTH_4:
-   OMAP_HSMMC_WRITE(host-base, CON, con  ~DW8);
-   OMAP_HSMMC_WRITE(host-base, HCTL,
-   OMAP_HSMMC_READ(host-base, HCTL) | FOUR_BIT);
-   break;
-   case MMC_BUS_WIDTH_1:
-   OMAP_HSMMC_WRITE(host-base, CON, con  ~DW8);
-   OMAP_HSMMC_WRITE(host-base, HCTL,
-   OMAP_HSMMC_READ(host-base, HCTL)  ~FOUR_BIT);
-   break;
-   }
+   omap_hsmmc_set_bus_width(host);
 
omap_hsmmc_set_clock(host);
 
-   con = OMAP_HSMMC_READ(host-base, CON);
-   if (ios-bus_mode == MMC_BUSMODE_OPENDRAIN)
-   OMAP_HSMMC_WRITE(host-base, CON, con | OD);
-   else
-   OMAP_HSMMC_WRITE(host-base, CON, con  ~OD);
+   omap_hsmmc_set_bus_mode(host);
+
 out:
host-context_loss = context_loss;
 
@@ -1636,7 +1653,6 @@ static void omap_hsmmc_request(struct mmc_host *mmc, 
struct mmc_request *req)
 static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
struct omap_hsmmc_host *host = mmc_priv(mmc);
-   u32 con;
int do_send_init_stream = 0;
 
mmc_host_enable(host-mmc);
@@ -1662,22 +1678,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
 
/* FIXME: set registers based only on changes to ios */
 
-   con = OMAP_HSMMC_READ(host-base, CON);
-   switch (mmc-ios.bus_width) {
-   case MMC_BUS_WIDTH_8:
-   OMAP_HSMMC_WRITE(host-base, CON, con | DW8);
-   break;
-   case MMC_BUS_WIDTH_4:
-   OMAP_HSMMC_WRITE(host-base, CON, con  ~DW8);
-   OMAP_HSMMC_WRITE(host-base, HCTL,
-   OMAP_HSMMC_READ(host-base, HCTL) | FOUR_BIT);
-   break;
-   case MMC_BUS_WIDTH_1:
-   OMAP_HSMMC_WRITE(host-base, CON, con  ~DW8);
-   OMAP_HSMMC_WRITE(host-base, HCTL,
-   OMAP_HSMMC_READ(host-base, HCTL)  ~FOUR_BIT);
-   break;
-   }
+   omap_hsmmc_set_bus_width(host);
 
if (host-pdata-controller_flags  OMAP_HSMMC_SUPPORTS_DUAL_VOLT) {
/* Only MMC1 can interface at 3V without some flavor
@@ -1702,11 +1703,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, 
struct 

[PATCH 10/22] mmc: omap_hsmmc: reduce a bit the error handlers in probe()

2011-05-05 Thread Adrian Hunter
From: Andy Shevchenko ext-andriy.shevche...@nokia.com

Signed-off-by: Andy Shevchenko ext-andriy.shevche...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   17 ++---
 1 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index a727bf8..7a153af 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2204,18 +2204,11 @@ static int __init omap_hsmmc_probe(struct 
platform_device *pdev)
/* we start off in DISABLED state */
host-dpm_state = DISABLED;
 
-   if (clk_enable(host-iclk) != 0) {
-   clk_put(host-iclk);
-   clk_put(host-fclk);
-   goto err1;
-   }
+   if (clk_enable(host-iclk) != 0)
+   goto err2;
 
-   if (mmc_host_enable(host-mmc) != 0) {
-   clk_disable(host-iclk);
-   clk_put(host-iclk);
-   clk_put(host-fclk);
-   goto err1;
-   }
+   if (mmc_host_enable(host-mmc) != 0)
+   goto err3;
 
if (cpu_is_omap2430()) {
host-dbclk = clk_get(pdev-dev, mmchsdb_fck);
@@ -2382,7 +2375,9 @@ err_irq:
host-dma_ctrl_buf,
host-dma_ctrl_buf_phy);
mmc_host_disable(host-mmc);
+err3:
clk_disable(host-iclk);
+err2:
clk_put(host-fclk);
clk_put(host-iclk);
if (host-got_dbclk) {
-- 
1.7.0.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


[PATCH 20/22] mmc: omap_hsmmc: adjust host controller clock in regard to current OPP

2011-05-05 Thread Adrian Hunter
From: Andy Shevchenko ext-andriy.shevche...@nokia.com

We should like to adjust MMC host controller clock whenever the OPP is changed.
OPP affects to L3/L4 bus frequency. Due to this we update the maximum frequency
limits before each upcoming request and when the divisor is calculated.

Signed-off-by: Andy Shevchenko ext-andriy.shevche...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   65 +
 1 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 2c8fa01..8c5e7d3 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -199,6 +199,9 @@ struct omap_hsmmc_host {
int use_reg;
int req_in_progress;
 
+   /* Actual output frequency of host controller */
+   unsigned intfreq;
+
struct  omap_mmc_platform_data  *pdata;
 };
 
@@ -604,13 +607,31 @@ static void omap_hsmmc_disable_irq(struct omap_hsmmc_host 
*host)
OMAP_HSMMC_WRITE(host-base, STAT, STAT_CLEAR);
 }
 
+/*
+ * Recalculate desired clock frequency with regard to maximum possible
+ * frequency at current OPP.
+ *
+ * Choose either target frequency (ios-clock) or maximum possible frequency at
+ * current OPP (get_max_freq() returns this limit)
+ */
+static void omap_hsmmc_recalc_freq(struct omap_hsmmc_host *host,
+  struct mmc_ios *ios)
+{
+   struct omap_mmc_platform_data *pdata = host-pdata;
+
+   if (pdata-get_max_freq)
+   host-freq = min(ios-clock, pdata-get_max_freq(host-dev));
+   else
+   host-freq = ios-clock;
+}
+
 /* Calculate divisor for the given clock frequency */
-static u16 calc_divisor(struct mmc_ios *ios)
+static u16 calc_divisor(struct omap_hsmmc_host *host)
 {
u16 dsor = 0;
 
-   if (ios-clock) {
-   dsor = DIV_ROUND_UP(OMAP_MMC_MASTER_CLOCK, ios-clock);
+   if (host-freq) {
+   dsor = DIV_ROUND_UP(OMAP_MMC_MASTER_CLOCK, host-freq);
if (dsor  250)
dsor = 250;
}
@@ -620,17 +641,16 @@ static u16 calc_divisor(struct mmc_ios *ios)
 
 static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
 {
-   struct mmc_ios *ios = host-mmc-ios;
unsigned long regval;
unsigned long timeout;
 
-   dev_dbg(mmc_dev(host-mmc), Set clock to %uHz\n, ios-clock);
+   dev_dbg(mmc_dev(host-mmc), Set clock to %uHz\n, host-freq);
 
omap_hsmmc_stop_clock(host);
 
regval = OMAP_HSMMC_READ(host-base, SYSCTL);
regval = regval  ~(CLKD_MASK | DTO_MASK);
-   regval = regval | (calc_divisor(ios)  6) | (DTO  16);
+   regval = regval | (calc_divisor(host)  6) | (DTO  16);
OMAP_HSMMC_WRITE(host-base, SYSCTL, regval);
OMAP_HSMMC_WRITE(host-base, SYSCTL,
OMAP_HSMMC_READ(host-base, SYSCTL) | ICE);
@@ -754,6 +774,7 @@ static int omap_hsmmc_context_restore(struct 
omap_hsmmc_host *host)
 
omap_hsmmc_set_bus_width(host);
 
+   omap_hsmmc_recalc_freq(host, ios);
omap_hsmmc_set_clock(host);
 
omap_hsmmc_set_bus_mode(host);
@@ -937,6 +958,8 @@ static void omap_hsmmc_request_done(struct omap_hsmmc_host 
*host, struct mmc_req
if (mrq-data  host-dma_in_use  dma_ch != -1)
return;
host-mrq = NULL;
+   if (host-pdata-inactive)
+   host-pdata-inactive(host-dev);
mmc_request_done(host-mmc, mrq);
 }
 
@@ -996,6 +1019,9 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct 
mmc_command *cmd)
}
if ((host-data == NULL  !host-response_busy) || cmd-error)
omap_hsmmc_request_done(host, cmd-mrq);
+   else if (host-data == NULL  host-response_busy 
+host-pdata-inactive)
+   host-pdata-inactive(host-dev);
 }
 
 /*
@@ -1418,6 +1444,8 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, 
void *cb_data)
struct mmc_request *mrq = host-mrq;
 
host-mrq = NULL;
+   if (host-pdata-inactive)
+   host-pdata-inactive(host-dev);
mmc_request_done(host-mmc, mrq);
}
 }
@@ -1615,6 +1643,26 @@ static void omap_hsmmc_request(struct mmc_host *mmc, 
struct mmc_request *req)
 
BUG_ON(host-req_in_progress);
BUG_ON(host-dma_ch != -1);
+
+   if (host-pdata-active) {
+   unsigned int new_freq;
+
+   /*
+* active() returns minimum of two (target, maximum)
+* frequencies.
+*/
+   new_freq = host-pdata-active(host-dev, mmc-ios.clock);
+
+   /*
+* We need to update actual frequency if it is not equal to the
+* minimum of two (target and maximum) frequencies
+*/
+   if (host-freq != 

[PATCH 19/22] OMAP: hsmmc: implement clock switcher

2011-05-05 Thread Adrian Hunter
From: Andy Shevchenko ext-andriy.shevche...@nokia.com

There are 3 new platform data methods which should help us to do a clock
switching when notification is happened or request is started.

The purpose of the patch is to avoid high frequency of MMC controller on low
OPPs due to an HW bug in OMAP 3630.

The algorithm:
 - the PM governor switches the clock of L3 (and therefore L4) bus on demand
 - the MMC controller clock should follow the change

We have considered two OPPs for L3/L4 bus. Thus, we have corresponding flow:
 - OPP1 - OPP2 (in case of abort - OPP1)
 - OPP2 - OPP1 (in case of abort - OPP2)

During idle the MMC gates functional clock and we don't care about the
frequency. Most important to get proper solution when notification comes during
request. Then:
 - in case of OPP1 - OPP2 we update frequency limit and it will be used for
   new coming requests (it assumes the current frequency of the controller is
   lower then new one)
 - otherwise we wait until no device has used higher frequency then upcoming
   one

Known issues and limitations:
 - originally a clock notifier was used for the core L4 iclk but for upstream
   Adrian changed to a cpufreq notifier where we assume OPP1 below 400MHz and
   OPP2 above 400MHz

Signed-off-by: Andy Shevchenko ext-andriy.shevche...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 arch/arm/mach-omap2/hsmmc.c   |  180 -
 arch/arm/plat-omap/include/plat/mmc.h |8 ++
 2 files changed, 187 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 6b97fae..34cba89 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -10,10 +10,15 @@
  * published by the Free Software Foundation.
  */
 #include linux/kernel.h
+#include linux/err.h
 #include linux/slab.h
 #include linux/string.h
 #include linux/delay.h
+#include linux/platform_device.h
+#include linux/clk.h
+#include linux/mmc/card.h
 #include mach/hardware.h
+#include plat/clock.h
 #include plat/mmc.h
 #include plat/omap-pm.h
 #include plat/mux.h
@@ -23,6 +28,8 @@
 #include hsmmc.h
 #include control.h
 
+#define HSMMC_MAX_FREQ 4800
+
 #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
 
 static u16 control_pbias_offset;
@@ -203,6 +210,155 @@ static int nop_mmc_set_power(struct device *dev, int 
slot, int power_on,
return 0;
 }
 
+#ifdef CONFIG_ARCH_OMAP3
+static struct hsmmc_max_freq_info {
+   struct device *dev;
+   int freq;
+   int high_speed;
+} hsmmc_max_freq_info[OMAP34XX_NR_MMC];
+
+static unsigned int hsmmc_max_freq = HSMMC_MAX_FREQ;
+static DEFINE_SPINLOCK(hsmmc_max_freq_lock);
+
+static DECLARE_WAIT_QUEUE_HEAD(hsmmc_max_freq_wq);
+
+static int hsmmc_high_speed(struct device *dev)
+{
+   void *drvdata = platform_get_drvdata(to_platform_device(dev));
+   struct mmc_host *mmc = container_of(drvdata, struct mmc_host, private);
+
+   return mmc-card ? mmc_card_highspeed(mmc-card) : 0;
+}
+
+static unsigned int hsmmc_get_max_freq_hs(struct device *dev, int high_speed)
+{
+   return high_speed ? hsmmc_max_freq : hsmmc_max_freq  1;
+}
+
+static unsigned int hsmmc_get_max_freq(struct device *dev)
+{
+   return hsmmc_get_max_freq_hs(dev, hsmmc_high_speed(dev));
+}
+
+static unsigned int hsmmc_active(struct device *dev, unsigned int target_freq)
+{
+   int high_speed = hsmmc_high_speed(dev);
+   int i;
+   unsigned int max_freq, freq;
+   unsigned long flags;
+
+   spin_lock_irqsave(hsmmc_max_freq_lock, flags);
+   max_freq = hsmmc_get_max_freq_hs(dev, high_speed);
+   freq = min(target_freq, max_freq);
+   for (i = 0; i  ARRAY_SIZE(hsmmc_max_freq_info); i++) {
+   if (!hsmmc_max_freq_info[i].dev) {
+   hsmmc_max_freq_info[i].dev = dev;
+   hsmmc_max_freq_info[i].freq = freq;
+   hsmmc_max_freq_info[i].high_speed = high_speed;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(hsmmc_max_freq_lock, flags);
+   return freq;
+}
+
+static void hsmmc_inactive(struct device *dev)
+{
+   int i;
+   unsigned long flags;
+
+   spin_lock_irqsave(hsmmc_max_freq_lock, flags);
+   for (i = 0; i  ARRAY_SIZE(hsmmc_max_freq_info); i++) {
+   if (hsmmc_max_freq_info[i].dev == dev) {
+   hsmmc_max_freq_info[i].dev = NULL;
+   spin_unlock_irqrestore(hsmmc_max_freq_lock, flags);
+   /*
+* Wake up the queue only in case we deactivated a
+* device.
+*/
+   wake_up(hsmmc_max_freq_wq);
+   return;
+   }
+   }
+   spin_unlock_irqrestore(hsmmc_max_freq_lock, flags);
+}
+
+static bool hsmmc_max_freq_ok(void)
+{
+   int i;
+   bool ret = true;
+   unsigned long flags;
+
+   

[PATCH 21/22] OMAP: hsmmc: add platform data for eMMC hardware reset gpio

2011-05-05 Thread Adrian Hunter
eMMC may have a hardware reset line connected to a gpio,
so pass it to the driver.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 arch/arm/mach-omap2/hsmmc.c   |5 +
 arch/arm/mach-omap2/hsmmc.h   |1 +
 arch/arm/plat-omap/include/plat/mmc.h |1 +
 3 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 34cba89..85f27af 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -472,6 +472,11 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
mmc-slots[0].switch_pin = c-gpio_cd;
mmc-slots[0].gpio_wp = c-gpio_wp;
 
+   if (c-gpio_hw_reset)
+   mmc-slots[0].gpio_hw_reset = c-gpio_hw_reset;
+   else
+   mmc-slots[0].gpio_hw_reset = -EINVAL;
+
mmc-slots[0].remux = c-remux;
mmc-slots[0].init_card = c-init_card;
 
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 0f2a87e..b78ed41 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -22,6 +22,7 @@ struct omap2_hsmmc_info {
boolnomux;  /* No default muxing for this slot */
int gpio_cd;/* or -EINVAL */
int gpio_wp;/* or -EINVAL */
+   int gpio_hw_reset;  /* hardware reset */
char*name;  /* or NULL for default */
struct device *dev; /* returned: pointer to mmc adapter */
int ocr_mask;   /* temporary HACK */
diff --git a/arch/arm/plat-omap/include/plat/mmc.h 
b/arch/arm/plat-omap/include/plat/mmc.h
index e3c9b20..9b69b7e 100644
--- a/arch/arm/plat-omap/include/plat/mmc.h
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -119,6 +119,7 @@ struct omap_mmc_platform_data {
 
int switch_pin; /* gpio (card detect) */
int gpio_wp;/* gpio (write protect) */
+   int gpio_hw_reset;  /* gpio (hardware reset) */
 
int (*set_bus_mode)(struct device *dev, int slot, int bus_mode);
int (*set_power)(struct device *dev, int slot,
-- 
1.7.0.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


[PATCH 18/22] mmc: omap_hsmmc: fix oops in omap_hsmmc_dma_cb

2011-05-05 Thread Adrian Hunter
In the case of an I/O error, the DMA will have been
cleaned up in the MMC interrupt and the request
structure pointer will be null.

In that case, it is essential to check if the DMA
DMA is over before dereferencing host-mrq-data.

Oops as follows:

3[ 2293.695281] wl1271: ERROR sdio read failed (-110)
1[ 2293.695739] Unable to handle kernel NULL pointer dereference at virtual
address 0004
1[ 2293.703094] pgd = b0004000
1[ 2293.705780] [0004] *pgd=
0[ 2293.709381] Internal error: Oops: 17 [#1] PREEMPT
0[ 2293.714080] last sysfs file:
/sys/devices/platform/omapdss/manager0/cpr_enable
4[ 2293.721313] Modules linked in: ext2 dm_crypt xt_NFLOG xt_rateest
xt_RATEEST xt_condition iptable_filter ip_tables dm_mod xt_IDLETIMER
nfnetlink_log nfnetlink as3645a ad58xx smiapp smiapp_power omap3_isp iovmm
omap3_iommu iommu2 iommu wl12xx_spi bnep omaplfb bridgedriver g_file_storage
cmt_speech ssi_protocol phonet hsi_char wl12xx_sdio wl12xx pvrsrvkm omap_ssi
mailbox_mach vibra_spi radio_wl1273 mailbox bcm4751_gps lis3lv02d_i2c ak8975
lis3lv02d leds_lp5521 apds990x pn544 rtc_twl4030 twl4030_keypad
twl4030_pwrbutton cmt twl5031_aci hci_h4p
4[ 2293.769287] CPU: 0Not tainted  (2.6.32.36-dfl61-20111603 #1)
4[ 2293.775329] PC is at omap_hsmmc_dma_cb+0x18/0x140
4[ 2293.780029] LR is at omap2_dma_irq_handler+0x244/0x28c
4[ 2293.785156] pc : [b024e180]lr : [b0049ed0]psr: a1d3
4[ 2293.785186] sp : edfb3c48  ip : edfb3bf8  fp : edfb3d3c
4[ 2293.796661] r10: fa05632c  r9 : fa056000  r8 : ee4889c0
4[ 2293.801910] r7 : 0020  r6 : 0001  r5 : edfb2000  r4 : ee53e1c0
4[ 2293.808441] r3 :   r2 : edfb3c48  r1 : 0020  r0 : 0007
4[ 2293.814971] Flags: NzCv  IRQs off  FIQs off  Mode SVC_32  ISA ARM
Segment kernel
4[ 2293.822479] Control: 10c5387d  Table: bc9f4019  DAC: 0017
0[ 2293.828247] Process phy0 (pid: 313, stack limit = 0xedfb22e8)
0[ 2293.833984] Stack: (0xedfb3c48 to 0xedfb4000)
...
4[ 2294.084320] [b024e180] (omap_hsmmc_dma_cb+0x18/0x140) from [b0049ed0]
(omap2_dma_irq_handler+0x244/0x28c)
4[ 2294.094268] [b0049ed0] (omap2_dma_irq_handler+0x244/0x28c) from
[b0093d44] (handle_IRQ_event+0x34/0xf0)
4[ 2294.104034] [b0093d44] (handle_IRQ_event+0x34/0xf0) from [b0095bec]
(handle_level_irq+0xcc/0x170)
4[ 2294.113250] [b0095bec] (handle_level_irq+0xcc/0x170) from [b002c068]
(asm_do_IRQ+0x68/0x84)
4[ 2294.121978] [b002c068] (asm_do_IRQ+0x68/0x84) from [b002ca84]
(__irq_svc+0x44/0xa8)
4[ 2294.129974] Exception stack(0xedfb3cc0 to 0xedfb3d08)
4[ 2294.135040] 3cc0: 0021d5cd  3d20cc2d 0002 edf7dd40 edfb2000
edf7dee8 edf7ddd8
4[ 2294.143249] 3ce0: 0001  ee516080 edfb3d3c b04880b8 edfb3d08
b0059e5c b0344184
4[ 2294.151428] 3d00: 0053 
4[ 2294.154968] [b002ca84] (__irq_svc+0x44/0xa8) from [b0344184]
(schedule+0x248/0x3a8)
4[ 2294.162963] [b0344184] (schedule+0x248/0x3a8) from [b03448ac]
(schedule_timeout+0x1c/0x224)
4[ 2294.171691] [b03448ac] (schedule_timeout+0x1c/0x224) from [b0344738]
(wait_for_common+0xe8/0x1a8)
4[ 2294.180938] [b0344738] (wait_for_common+0xe8/0x1a8) from [b02459f8]
(mmc_wait_for_req+0x110/0x120)
4[ 2294.190277] [b02459f8] (mmc_wait_for_req+0x110/0x120) from [b0249bac]
(mmc_io_rw_extended+0x178/0x1e0)
4[ 2294.199951] [b0249bac] (mmc_io_rw_extended+0x178/0x1e0) from
[b024ab54] (sdio_io_rw_ext_helper+0x164/0x190)
4[ 2294.210052] [b024ab54] (sdio_io_rw_ext_helper+0x164/0x190) from
[b024aba0] (sdio_writesb+0x20/0x24)
4[ 2294.219512] [b024aba0] (sdio_writesb+0x20/0x24) from [af0d50e0]
(wl1271_sdio_raw_write+0x64/0xa4 [wl12xx_sdio])
4[ 2294.230041] [af0d50e0] (wl1271_sdio_raw_write+0x64/0xa4 [wl12xx_sdio])
from [af0bd4bc] (wl1271_tx_work_locked+0x548/0x5fc [wl12xx])
4[ 2294.242218] [af0bd4bc] (wl1271_tx_work_locked+0x548/0x5fc [wl12xx])
from [af0ba944] (wl1271_irq_work+0x230/0x314 [wl12xx])
4[ 2294.253631] [af0ba944] (wl1271_irq_work+0x230/0x314 [wl12xx]) from
[b00725ac] (worker_thread+0x174/0x224)
4[ 2294.263519] [b00725ac] (worker_thread+0x174/0x224) from [b0075bac]
(kthread+0x7c/0x84)
4[ 2294.271820] [b0075bac] (kthread+0x7c/0x84) from [b002d950]
(kernel_thread_exit+0x0/0x8)
0[ 2294.280181] Code: e5923008 e1a0200d e3c25d7f e3c5503f (e5936004)
4[ 2294.286529] ---[ end trace e8fb05c679bd87ff ]---

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index de7f15c..2c8fa01 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1375,7 +1375,7 @@ static void omap_hsmmc_config_dma_params(struct 
omap_hsmmc_host *host,
 static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data)
 {
struct omap_hsmmc_host *host = cb_data;
-   struct mmc_data *data = host-mrq-data;
+   struct mmc_data *data;
int dma_ch, req_in_progress;
 
if (!(ch_status  (OMAP_DMA_BLOCK_IRQ | OMAP2_DMA_SUPER_BLOCK_IRQ))) {
@@ -1390,6 

[PATCH 17/22] mmc: omap_hsmmc: ensure pbias configuration is always done

2011-05-05 Thread Adrian Hunter
Go through the driver's set_power() functions rather than
calling regulator_enable/disable() directly because otherwise
pbias configuration for MMC1 is not done.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   17 -
 1 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index e7c181a..de7f15c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -457,15 +457,14 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host 
*host)
* framework is fixed, we need a workaround like this
* (which is safe for MMC, but not in general).
*/
-   if (regulator_is_enabled(host-vcc)  0) {
-   regulator_enable(host-vcc);
-   regulator_disable(host-vcc);
-   }
-   if (host-vcc_aux) {
-   if (regulator_is_enabled(reg)  0) {
-   regulator_enable(reg);
-   regulator_disable(reg);
-   }
+   if (regulator_is_enabled(host-vcc)  0 ||
+   (host-vcc_aux  regulator_is_enabled(host-vcc_aux))) {
+   int vdd = ffs(mmc_slot(host).ocr_mask) - 1;
+
+   mmc_slot(host).set_power(host-dev, host-slot_id,
+1, vdd);
+   mmc_slot(host).set_power(host-dev, host-slot_id,
+0, 0);
}
}
 
-- 
1.7.0.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


[PATCH 22/22] mmc: omap_hsmmc: add a hardware reset before initialization

2011-05-05 Thread Adrian Hunter
After a warm restart, an eMMC which cannot be powered off is
in an unknown state, so reset it to be sure it will initialize.

Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
 drivers/mmc/host/omap_hsmmc.c |   38 +-
 1 files changed, 37 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 8c5e7d3..c791230 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -542,10 +542,25 @@ static int omap_hsmmc_gpio_init(struct 
omap_mmc_platform_data *pdata)
} else
pdata-slots[0].gpio_wp = -EINVAL;
 
+   if (gpio_is_valid(pdata-slots[0].gpio_hw_reset)) {
+   ret = gpio_request(pdata-slots[0].gpio_hw_reset,
+  mmc_hw_reset);
+   if (ret)
+   goto err_free_wp;
+   ret = gpio_direction_output(pdata-slots[0].gpio_hw_reset, 1);
+   if (ret)
+   goto err_free_hw_reset;
+   } else
+   pdata-slots[0].gpio_hw_reset = -EINVAL;
+
return 0;
 
+
+err_free_hw_reset:
+   gpio_free(pdata-slots[0].gpio_hw_reset);
 err_free_wp:
-   gpio_free(pdata-slots[0].gpio_wp);
+   if (gpio_is_valid(pdata-slots[0].gpio_wp))
+   gpio_free(pdata-slots[0].gpio_wp);
 err_free_cd:
if (gpio_is_valid(pdata-slots[0].switch_pin))
 err_free_sp:
@@ -555,6 +570,8 @@ err_free_sp:
 
 static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata)
 {
+   if (gpio_is_valid(pdata-slots[0].gpio_hw_reset))
+   gpio_free(pdata-slots[0].gpio_hw_reset);
if (gpio_is_valid(pdata-slots[0].gpio_wp))
gpio_free(pdata-slots[0].gpio_wp);
if (gpio_is_valid(pdata-slots[0].switch_pin))
@@ -815,6 +832,18 @@ static void omap_hsmmc_context_save(struct omap_hsmmc_host 
*host)
 
 #endif
 
+static void omap_hsmmc_do_hw_reset(struct omap_hsmmc_host *host)
+{
+   if (!gpio_is_valid(mmc_slot(host).gpio_hw_reset))
+   return;
+
+   gpio_set_value_cansleep(mmc_slot(host).gpio_hw_reset, 0);
+   udelay(9);
+   gpio_set_value_cansleep(mmc_slot(host).gpio_hw_reset, 1);
+   usleep_range(1000, 2000);
+   printk(KERN_INFO %s: hardware reset done\n, mmc_hostname(host-mmc));
+}
+
 /*
  * Send init stream sequence to card
  * before sending IDLE command
@@ -827,6 +856,13 @@ static void send_init_stream(struct omap_hsmmc_host *host)
if (host-protect_card)
return;
 
+   /*
+* After a warm restart, an eMMC which cannot be powered off is in an
+* unknown state so reset it to be sure it will initialize.
+*/
+   if (mmc_slot(host).no_off)
+   omap_hsmmc_do_hw_reset(host);
+
disable_irq(host-irq);
 
OMAP_HSMMC_WRITE(host-base, IE, INT_EN_MASK);
-- 
1.7.0.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: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from omapdss_dsi1 to omapdss_dsi

2011-05-05 Thread Tomi Valkeinen
On Thu, 2011-05-05 at 04:50 -0700, Tony Lindgren wrote:
 * Tomi Valkeinen tomi.valkei...@ti.com [110505 04:33]:
  On Wed, 2011-05-04 at 12:40 +0300, Tony Lindgren wrote:
   
   Looks like we should first combine all this cut and paste data
   for each board file into some common init function to cut
   down the crazy churn.
  
  Sorry, I don't see how this would be possible with the regulator
  framework. What we would need is to setup some
  regulator_consumer_supplies dynamically depending on the omap and on the
  given parameters.
  
  Adding Liam and Mark for possible comments. A short summary of the
  situation:
  
  OMAP display subsystem (DSS) HW needs a few power supplies (vdds_dsi,
  vdds_sdi, vdda_dac), depending on the OMAP version. All the known boards
  have the standard TWL power chip which provides these powers, and they
  are connected almost always the same way. However, there's no reason
  that the powers for DSS couldn't be provided from some other source.
  
  As an example, on OMAP3 we could have:
  (regulator - name - driver)
  VDDA_DAC - vdda_dac - omapdss_venc
  VPLL2 - vdds_dsi - omapdss
  VPLL2 - vdds_dsi - omapdss_dsi
  
  So currently we have REGULATOR_SUPPLY defines for each board in all the
  board files which support display. It would be much better to have an
  overrideable standard setup for the DSS powers, but this would require
  dynamically setting up the regulator_consumer_supplies. And I can't see
  how this could be done, except dynamically creating the
  regulator_consumer_supply array before initializing the TWL chip, but as
  DSS is not the only user of those powers the end result could be quite a
  mess with changes needed in every board file.
 
 What if you just do all common DSS REGULATOR_SUPPLY entries in the common
 platform init code for DSS? Then just set the regulator_init_data pointers
 based on the desired configuration.
 
 Or maybe I misunderstood your problem..

The problem with that approach is that there could be other users for
the same regulator, so the consumer_supplies list could also need to
contain some other entries than dss.

Then again, I guess those cases are minority, so we would still get
majority of the board files cleaned up.

Thanks for the idea, I'll try this approach.

 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 13/22] mmc: omap_hsmmc: fix few bugs when set the clock divisor

2011-05-05 Thread Grazvydas Ignotas
On Thu, May 5, 2011 at 2:51 PM, Adrian Hunter adrian.hun...@nokia.com wrote:
 From: Andy Shevchenko ext-andriy.shevche...@nokia.com

 There are two pieces of code which similar, but not the same. Each of them
 contains a bug.

 The SYSCTL register should be read before write in the
 omap_hsmmc_context_restore() to remain the state of the reserved bits.

 Before set the clock divisor and DTO bits the value from the SYSCTL register
 should be masked properly. We were lucky to have no problems with DTO bits. 
 So,
 make sure we have clear DTO bits properly in the omap_hsmmc_set_ios().

 Additionally get rid of msleep(1). The actual time rare higher than 30us on
 OMAP 3630.

 The result pieces of code are split to omap_hsmmc_set_clock() function.

 Signed-off-by: Andy Shevchenko ext-andriy.shevche...@nokia.com
 Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
 ---
  drivers/mmc/host/omap_hsmmc.c |   59 +++-
  1 files changed, 28 insertions(+), 31 deletions(-)

 diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
 index ae6d204..3c76911 100644
 --- a/drivers/mmc/host/omap_hsmmc.c
 +++ b/drivers/mmc/host/omap_hsmmc.c
 @@ -619,6 +619,32 @@ static u16 calc_divisor(struct mmc_ios *ios)
        return dsor;
  }

 +static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
 +{
 +       struct mmc_ios *ios = host-mmc-ios;
 +       unsigned long regval;
 +       unsigned long timeout;
 +
 +       dev_dbg(mmc_dev(host-mmc), Set clock to %uHz\n, ios-clock);
 +
 +       omap_hsmmc_stop_clock(host);
 +
 +       regval = OMAP_HSMMC_READ(host-base, SYSCTL);
 +       regval = regval  ~(CLKD_MASK | DTO_MASK);
 +       regval = regval | (calc_divisor(ios)  6) | (DTO  16);
 +       OMAP_HSMMC_WRITE(host-base, SYSCTL, regval);
 +       OMAP_HSMMC_WRITE(host-base, SYSCTL,
 +               OMAP_HSMMC_READ(host-base, SYSCTL) | ICE);
 +
 +       /* Wait till the ICS bit is set */
 +       timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
 +       while ((OMAP_HSMMC_READ(host-base, SYSCTL)  ICS) != ICS
 +                time_before(jiffies, timeout))
 +               ;

Since you are busywaiting now, cpu_relax() is advisable I guess.
--
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/9] OMAP: DSS2: Change DSI platform device name from omapdss_dsi1 to omapdss_dsi

2011-05-05 Thread Mark Brown
On Thu, May 05, 2011 at 02:36:48PM +0300, Tomi Valkeinen wrote:

 So currently we have REGULATOR_SUPPLY defines for each board in all the
 board files which support display. It would be much better to have an
 overrideable standard setup for the DSS powers, but this would require
 dynamically setting up the regulator_consumer_supplies. And I can't see
 how this could be done, except dynamically creating the
 regulator_consumer_supply array before initializing the TWL chip, but as
 DSS is not the only user of those powers the end result could be quite a
 mess with changes needed in every board file.

I'm not sure I see a problem that needs solving here?  This wiring is
all totally system specific.  Once we have viable device tree for
relevant platforms I'd expect to see these things mapped in the device
tree for the system with a standard regulator API device tree mapping.
--
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/9] OMAP: DSS2: Change DSI platform device name from omapdss_dsi1 to omapdss_dsi

2011-05-05 Thread Tomi Valkeinen
On Thu, 2011-05-05 at 04:50 -0700, Tony Lindgren wrote:
 * Tomi Valkeinen tomi.valkei...@ti.com [110505 04:33]:
  On Wed, 2011-05-04 at 12:40 +0300, Tony Lindgren wrote:
   
   Looks like we should first combine all this cut and paste data
   for each board file into some common init function to cut
   down the crazy churn.
  
  Sorry, I don't see how this would be possible with the regulator
  framework. What we would need is to setup some
  regulator_consumer_supplies dynamically depending on the omap and on the
  given parameters.
  
  Adding Liam and Mark for possible comments. A short summary of the
  situation:
  
  OMAP display subsystem (DSS) HW needs a few power supplies (vdds_dsi,
  vdds_sdi, vdda_dac), depending on the OMAP version. All the known boards
  have the standard TWL power chip which provides these powers, and they
  are connected almost always the same way. However, there's no reason
  that the powers for DSS couldn't be provided from some other source.
  
  As an example, on OMAP3 we could have:
  (regulator - name - driver)
  VDDA_DAC - vdda_dac - omapdss_venc
  VPLL2 - vdds_dsi - omapdss
  VPLL2 - vdds_dsi - omapdss_dsi
  
  So currently we have REGULATOR_SUPPLY defines for each board in all the
  board files which support display. It would be much better to have an
  overrideable standard setup for the DSS powers, but this would require
  dynamically setting up the regulator_consumer_supplies. And I can't see
  how this could be done, except dynamically creating the
  regulator_consumer_supply array before initializing the TWL chip, but as
  DSS is not the only user of those powers the end result could be quite a
  mess with changes needed in every board file.
 
 What if you just do all common DSS REGULATOR_SUPPLY entries in the common
 platform init code for DSS? Then just set the regulator_init_data pointers
 based on the desired configuration.
 
 Or maybe I misunderstood your problem..

I made a test patch for this (below), but after looking at OMAP3 and 4
TRMs, I don't think this is going to be very good solution. It looks
like on OMAP3 the VPLL2 is used (at least) for DSI and CSI. On OMAP4
VCXIO is used for vdda_dpll_mpu, vdda_dpll_core_audio,
vdda_dpll_iva_per, vdda_dsi[1:2], vdda_csi2[1:2], vdda_usba0otg_1p8v.

VPLL2 and VCXIO do not look like to be dedicated for DSS, so I'm
guessing it's more than normal to have more users for the regulators
than just DSS (but they just aren't implemented currently).

Another option that came to my mind is defining simple macros like:

#define OMAP_DSS_REG_SUPPLY_DSS REGULATOR_SUPPLY(vdds_dsi, omapdss)
#define OMAP_DSS_REG_SUPPLY_DSI1 REGULATOR_SUPPLY(vdds_dsi, omapdss_dsi1)

And then use them instead:

static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
OMAP_DSS_REG_SUPPLY_DSS,
OMAP_DSS_REG_SUPPLY_DSI1,
};

But that is quite minor improvement, and I'm not even sure if it's an
improvement...

 Tomi


diff --git a/arch/arm/mach-omap2/board-3430sdp.c 
b/arch/arm/mach-omap2/board-3430sdp.c
index 9afd087..dedc150 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -394,16 +394,6 @@ static struct regulator_consumer_supply 
sdp3430_vaux3_supplies[] = {
REGULATOR_SUPPLY(vcc, spi1.0),
 };
 
-static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
-   REGULATOR_SUPPLY(vdda_dac, omapdss_venc),
-};
-
-/* VPLL2 for digital video outputs */
-static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
-   REGULATOR_SUPPLY(vdds_dsi, omapdss),
-   REGULATOR_SUPPLY(vdds_dsi, omapdss_dsi1),
-};
-
 static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
REGULATOR_SUPPLY(vmmc, omap_hsmmc.0),
 };
@@ -531,8 +521,8 @@ static struct regulator_init_data sdp3430_vdac = {
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
-   .num_consumer_supplies  = ARRAY_SIZE(sdp3430_vdda_dac_supplies),
-   .consumer_supplies  = sdp3430_vdda_dac_supplies,
+   .num_consumer_supplies  = ARRAY_SIZE(omap_std_vdda_dac_supplies),
+   .consumer_supplies  = omap_std_vdda_dac_supplies,
 };
 
 static struct regulator_init_data sdp3430_vpll2 = {
@@ -546,8 +536,8 @@ static struct regulator_init_data sdp3430_vpll2 = {
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
-   .num_consumer_supplies  = ARRAY_SIZE(sdp3430_vpll2_supplies),
-   .consumer_supplies  = sdp3430_vpll2_supplies,
+   .num_consumer_supplies  = ARRAY_SIZE(omap_std_vdds_dsi_supplies),
+   .consumer_supplies  = omap_std_vdds_dsi_supplies,
 };
 
 static struct twl4030_codec_audio_data sdp3430_audio;
diff --git a/arch/arm/mach-omap2/board-4430sdp.c 
b/arch/arm/mach-omap2/board-4430sdp.c
index 570e83f..bef42bb 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ 

Re: [PATCH 07/22] mmc: omap_hsmmc: fix missing mmc_release_host() in no_off case

2011-05-05 Thread Sergei Shtylyov

Hello.

On 05-05-2011 15:51, Adrian Hunter wrote:


From: Sudhir Bera ext-sudhir.b...@nokia.com



In fact the no_off check here will not be hit because
'omap_hsmmc_disabled_to_sleep()' won't schedule a
deeper disable in the no_off case.



Signed-off-by: Sudhir Bera ext-sudhir.b...@nokia.com
Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
---
  drivers/mmc/host/omap_hsmmc.c |7 +++
  1 files changed, 3 insertions(+), 4 deletions(-)



diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index bab25ff..bd52849 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1852,14 +1852,13 @@ static int omap_hsmmc_sleep_to_off(struct 
omap_hsmmc_host *host)
return 0;

if (mmc_slot(host).no_off)
-   return 0;
+   goto out;

if (!((host-mmc-caps  MMC_CAP_NONREMOVABLE) ||
  mmc_slot(host).card_detect ||
  (mmc_slot(host).get_cover_state 
   mmc_slot(host).get_cover_state(host-dev, host-slot_id {
-   mmc_release_host(host-mmc);
-   return 0;
+   goto out;
}


   This has become a single statement, so {} shpould be removed, no? 
checkpatch.pl probably warns here?..


WBR, Sergei
--
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 19/22] OMAP: hsmmc: implement clock switcher

2011-05-05 Thread Grazvydas Ignotas
On Thu, May 5, 2011 at 2:51 PM, Adrian Hunter adrian.hun...@nokia.com wrote:
 From: Andy Shevchenko ext-andriy.shevche...@nokia.com

 There are 3 new platform data methods which should help us to do a clock
 switching when notification is happened or request is started.

 The purpose of the patch is to avoid high frequency of MMC controller on low
 OPPs due to an HW bug in OMAP 3630.

 The algorithm:
  - the PM governor switches the clock of L3 (and therefore L4) bus on demand
  - the MMC controller clock should follow the change

 We have considered two OPPs for L3/L4 bus. Thus, we have corresponding flow:
  - OPP1 - OPP2 (in case of abort - OPP1)
  - OPP2 - OPP1 (in case of abort - OPP2)

 During idle the MMC gates functional clock and we don't care about the
 frequency. Most important to get proper solution when notification comes 
 during
 request. Then:
  - in case of OPP1 - OPP2 we update frequency limit and it will be used for
   new coming requests (it assumes the current frequency of the controller is
   lower then new one)
  - otherwise we wait until no device has used higher frequency then upcoming
   one

 Known issues and limitations:
  - originally a clock notifier was used for the core L4 iclk but for upstream
   Adrian changed to a cpufreq notifier where we assume OPP1 below 400MHz and
   OPP2 above 400MHz

 Signed-off-by: Andy Shevchenko ext-andriy.shevche...@nokia.com
 Signed-off-by: Adrian Hunter adrian.hun...@nokia.com
 ---
  arch/arm/mach-omap2/hsmmc.c           |  180 
 -
  arch/arm/plat-omap/include/plat/mmc.h |    8 ++
  2 files changed, 187 insertions(+), 1 deletions(-)

 diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
 index 6b97fae..34cba89 100644
 --- a/arch/arm/mach-omap2/hsmmc.c
 +++ b/arch/arm/mach-omap2/hsmmc.c

snip

 +
 +static int hsmmc_clk_notifier(struct notifier_block *nb, unsigned long event,
 +                             void *data)
 +{
 +       struct cpufreq_freqs *freqs = data;
 +       unsigned int threshold = 40; /* between opp1 and opp2 */
 +
 +       switch (event) {
 +       case CPUFREQ_PRECHANGE:
 +               if (freqs-new  threshold  freqs-old  threshold) {

What if we go from 40 to, say, 20?

 +                       /* opp2 - opp1 */
 +                       hsmmc_max_freq = HSMMC_MAX_FREQ  1;
 +
 +                       /* Timeout is 1 sec */
 +                       if (!wait_event_timeout(hsmmc_max_freq_wq,
 +                                               hsmmc_max_freq_ok(),
 +                                               msecs_to_jiffies(1000)))
 +                               pr_err(MMC violates maximum frequency 
 +                                      constraint\n);
 +               }
 +               break;
 +       case CPUFREQ_POSTCHANGE:
 +               if (freqs-old  threshold  freqs-new  threshold) {

Same here, you could go from 20 to 40 and then 60 and code
would never notice it.

 +                       /* opp1 - opp2 */
 +                       hsmmc_max_freq = HSMMC_MAX_FREQ;
 +               }
--
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 v5 03/10] OMAP4 : DSS2 : HDMI: Dispc gamma enable set/reset function for TV.

2011-05-05 Thread Laurent Pinchart
Hi Mythri,

Sorry for the late reply, I've only noticed this issue today.

On Thursday 10 March 2011 11:44:11 Mythri P K wrote:
 Adding function to reset/set gamma table bit for TV interface
 currentl only support for disabled is added.
 
 Signed-off-by: Mythri P K mythr...@ti.com
 ---
  drivers/video/omap2/dss/dispc.c |   13 +
  drivers/video/omap2/dss/dss.h   |1 +
  2 files changed, 14 insertions(+), 0 deletions(-)
 
 diff --git a/drivers/video/omap2/dss/dispc.c
 b/drivers/video/omap2/dss/dispc.c index b8c576a..9b86f5f 100644
 --- a/drivers/video/omap2/dss/dispc.c
 +++ b/drivers/video/omap2/dss/dispc.c
 @@ -1008,6 +1008,19 @@ void dispc_set_burst_size(enum omap_plane plane,
   enable_clocks(0);
  }
 
 +void dispc_enable_gamma_table(bool enable)
 +{
 + /* This is partially implemented to support only
 +  *  disabling of the gamma table.
 +  */
 + if (enable) {
 + DSSWARN(Gamma table enabling for TV not yet supported);
 + return;
 + }
 +
 + REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);

Bit 9 in the DISPC_CONFIG register is as FUNCGATED for the OMAP3. From a quick 
glance at the OMAP36xx and OMAP4430 public TRMs, that's the only DISPC_CONFIG 
bit that has been changed between OMAP3 and OMAP4.

 +}
 +
  static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
  {
   u32 val;
 diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
 index c2c0fcf..9f563a6 100644
 --- a/drivers/video/omap2/dss/dss.h
 +++ b/drivers/video/omap2/dss/dss.h
 @@ -376,6 +376,7 @@ void dispc_set_plane_size(enum omap_plane plane, u16
 width, u16 height); void dispc_set_channel_out(enum omap_plane plane,
   enum omap_channel channel_out);
 
 +void dispc_enable_gamma_table(bool enable);
  int dispc_setup_plane(enum omap_plane plane,
 u32 paddr, u16 screen_width,
 u16 pos_x, u16 pos_y,

-- 
Regards,

Laurent Pinchart
--
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: Common clock and dvfs

2011-05-05 Thread Mark Brown
On Wed, May 04, 2011 at 11:50:52PM -0700, Colin Cross wrote:

 True, that was an oversimplificaiton. I meant the minimum voltage that
 scales with clock frequencies only depends on the clock frequency, not
 the device.  Devices do need to be able to specify a higher minimum
 voltage, and the regulator api needs to handle it.

The regulator API already supports this so we're fine there.
--
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] omap : nand : fix subpage ecc issue with prefetch

2011-05-05 Thread Vimal Singh
Hi Artem,

Can you please give a look on this patch?
This patch fixes is required for anyone who wants to use this driver
without using HW ECC.

-- Vimal

On Mon, May 2, 2011 at 4:40 PM, Kishore Kadiyala
kishore.kadiy...@ti.com wrote:
 For prefetch engine, read and write  got broken in commit '2c01946c'.
 We never hit a scenario of not getting 'gpmc_prefetch_enable'
 call success.
 When reading/writing a subpage with a non divisible by 4 ecc number
 of bytes, the mis-aligned bytes gets handled first before enabling
 the Prefetch engine, then it reads/writes rest of the bytes.

 Signed-off-by: Kishore Kadiyala kishore.kadiy...@ti.com
 Signed-off-by: Vimal Singh vimal.neww...@gmail.com
 Reported-by: Bryan DE FARIA bdefa...@adeneo-embedded.com
 ---
  drivers/mtd/nand/omap2.c |   12 +---
  1 files changed, 5 insertions(+), 7 deletions(-)

 diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
 index da9a351..2c8040f 100644
 --- a/drivers/mtd/nand/omap2.c
 +++ b/drivers/mtd/nand/omap2.c
 @@ -263,11 +263,10 @@ static void omap_read_buf_pref(struct mtd_info *mtd, 
 u_char *buf, int len)
        if (ret) {
                /* PFPW engine is busy, use cpu copy method */
                if (info-nand.options  NAND_BUSWIDTH_16)
 -                       omap_read_buf16(mtd, buf, len);
 +                       omap_read_buf16(mtd, (u_char *)p, len);
                else
 -                       omap_read_buf8(mtd, buf, len);
 +                       omap_read_buf8(mtd, (u_char *)p, len);
        } else {
 -               p = (u32 *) buf;
                do {
                        r_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT);
                        r_count = r_count  2;
 @@ -293,7 +292,7 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
                                                struct omap_nand_info, mtd);
        uint32_t w_count = 0;
        int i = 0, ret = 0;
 -       u16 *p;
 +       u16 *p = (u16 *)buf;
        unsigned long tim, limit;

        /* take care of subpage writes */
 @@ -309,11 +308,10 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
        if (ret) {
                /* PFPW engine is busy, use cpu copy method */
                if (info-nand.options  NAND_BUSWIDTH_16)
 -                       omap_write_buf16(mtd, buf, len);
 +                       omap_write_buf16(mtd, (u_char *)p, len);
                else
 -                       omap_write_buf8(mtd, buf, len);
 +                       omap_write_buf8(mtd, (u_char *)p, len);
        } else {
 -               p = (u16 *) buf;
                while (len) {
                        w_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT);
                        w_count = w_count  1;
 --
 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 05/12] OMAP: Serial: Hold console lock for console usage.

2011-05-05 Thread Kevin Hilman
Govindraj govindraj...@gmail.com writes:

 On Thu, May 5, 2011 at 2:13 AM, Kevin Hilman khil...@ti.com wrote:
 Govindraj.R govindraj.r...@ti.com writes:

 Acquire console lock before enabling and writing to console-uart
 to avoid any recursive prints from console write.
 for ex:
       -- printk
         -- uart_console_write
           -- get_sync
             -- printk from omap_device enable
               -- uart_console write

 By this time, since the device's runtime PM hooks have been called, the
 device's rutime PM state should be set to RPM_SUSPENDING (not yet
 RPM_SUSPENDED).

 In addition to the console lock, you should be able to use that flag to
 avoid console writes while the console is in the process of suspending.


 Yes RPM_SUSPENDING check helps along with console lock

Great!

  Changes as below 
 ---
 diff --git a/drivers/tty/serial/omap-serial.c 
 b/drivers/tty/serial/omap-serial.c
 index 59f548f..71964c3 100644
 --- a/drivers/tty/serial/omap-serial.c
 +++ b/drivers/tty/serial/omap-serial.c
 @@ -1040,6 +1040,18 @@ serial_omap_console_write(struct console *co,
 const char *s,
 if (console_trylock())
 console_lock = 1;

 +   /*
 +* If console_lock is not available and we are in suspending
 +* state then we can avoid the console usage scenario
 +* as this may introduce recursive prints.
 +* Basically this scenario occurs during boot while
 +* printing debug bootlogs.
 +*/
 +
 +   if (!console_lock 
 +   up-pdev-dev.power.runtime_status == RPM_SUSPENDING)
 +   return;
 +
 local_irq_save(flags);
 if (up-port.sysrq)
 locked = 0;

 

 Is it ok to check the RPM_SUSPENDING flag in driver ?
 I can't find any API currently available under runtime.h to use.

I would propose a new API in pm_runtime.h similar to
pm_runtime_suspended() that checks for this.

Kevin
--
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 11/12] OMAP: Serial: Use resume call from prcm to enable uart

2011-05-05 Thread Kevin Hilman
Govindraj govindraj...@gmail.com writes:

[...]


 ... this is just putting back basically the same thing that was removed in
 patch 1.  IOW, this is now being checked for *every* PRCM wakeup, which
 is no different than having it in the idle path.

 I thought I understood that you had the SW IRQ triggering working, so
 this part should not be necessary.

 Actually I tried few experiments but couldn't get it working.

What exactly is not working?   The interrupt is not firing at all?  The
driver's ISR is not being called? 

 Tried below but didn't help.

 
 diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
 index 3960330..2c1dfc2 100644
 --- a/arch/arm/mach-omap2/pm34xx.c
 +++ b/arch/arm/mach-omap2/pm34xx.c
 @@ -288,6 +288,16 @@ static irqreturn_t prcm_interrupt_handler (int
 irq, void *dev_id)
 do {
 if (irqstatus_mpu  (OMAP3430_WKUP_ST_MASK |
  OMAP3430_IO_ST_MASK)) {
 +#if 1
 +   /*
 +* EXP-1: SET UART1 SOFT IRQ BIT
 +* 3430 -SDP UART1 console.
 +* M_IRQ_72, INTCPS_ISR_SET
 +* 0x4820 0090 + (0x20 * n)
 +* bit-8 n = 2
 +*/
 +   __raw_writel(0x100 , 0x482000D0);
 +#endif
 c = _prcm_int_handle_wakeup();

 /*

 ---

 Currently we are planning to integrate irq_chaining patches
 on top uart_runtime patches which is work-in-progress.
 Will remove resume_idle once we have irq_chaining patches available.

Well, I'm not OK with $SUBJECT patch as it is since it's just moving an
ugly hack from serial.c to the PRCM ISR.  If the hack is going to stay,
then it should stay where it is until it can be fixed for real.

Kevin
--
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 0/4] OMAP: cpuidle code clean-up

2011-05-05 Thread jean . pihet
From: Jean Pihet j-pi...@ti.com

Rework of the OMAP2+ cpuidle code

v2: rework after comments on linux-omap ML:
- remove useless macros,
- replace the C-state common data fill-in helper macro by an inline
   function, for better readability,
- update commits description.

v1:
- optimize the cpuidle C-states data registration and storage,
- change the interaction with the debugfs 'enable_off_mode' knob
 and the use of the C-states 'valid' internal field,
- remove dead code,
- improve code readability.

Tested on Beagleboard B5 with cpuidle in RET and OFF modes.

Another 145 lines of OMAP code gone ;p

Notes:
1) the debugfs 'enable_off_mode' knob will be deprecated by the use
 of the devices constraints framework to restrict the power domains
 power modes.
2) the MPU and CORE power domains low power modes are controlled
 by cpuidle, based on the allowed overall sleep+wake-up latencies
 and the wake-up latency constraints on the MPU. This is incorrect.
 The devices constraints framework shall be used instead to control
 all power domains.

ToDo:
- integrate cpuidle with the devices constraints framework, when merged in,
- refine the latency figures and express them in term of available data
 from other frameworks (OMAP PM, constaints framework, omap_devices,
 new VC/VP voltage and DVFS code ...),

Rebased on khilman's for_2.6.40/pm-cleanup branch

Jean Pihet (4):
  OMAP3: clean-up mach specific cpuidle data structures
  OMAP3: cpuidle: re-organize the C-states data
  OMAP3: cpuidle: code rework for improved readability
  OMAP3: cpuidle: change the power domains modes determination logic

 arch/arm/mach-omap2/board-rx51.c  |   18 +-
 arch/arm/mach-omap2/cpuidle34xx.c |  426 +
 arch/arm/mach-omap2/pm.h  |   17 +-
 arch/arm/mach-omap2/pm34xx.c  |   12 -
 4 files changed, 164 insertions(+), 309 deletions(-)

-- 
1.7.2.5

--
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/4] OMAP3: clean-up mach specific cpuidle data structures

2011-05-05 Thread jean . pihet
From: Jean Pihet j-pi...@ti.com

- sleep_latency and wake_latency are not used, replace them by
  exit_latency which is used by cpuidle. exit_latency simply is
  the sum of sleep_latency and wake_latency,
- replace threshold by target_residency,
- changed the OMAP3 specific cpuidle code accordingly,
- changed the OMAP3 board code accordingly.

Signed-off-by: Jean Pihet j-pi...@ti.com
---
 arch/arm/mach-omap2/board-rx51.c  |   18 ---
 arch/arm/mach-omap2/cpuidle34xx.c |  103 +++-
 arch/arm/mach-omap2/pm.h  |   13 +++--
 3 files changed, 63 insertions(+), 71 deletions(-)

diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index e964895..3629f9e 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -58,21 +58,25 @@ static struct platform_device leds_gpio = {
},
 };
 
+/*
+ * cpuidle C-states definition override from the default values.
+ * The 'exit_latency' field is the sum of sleep and wake-up latencies.
+ */
 static struct cpuidle_params rx51_cpuidle_params[] = {
/* C1 */
-   {1, 110, 162, 5},
+   {110 + 162, 5 , 1},
/* C2 */
-   {1, 106, 180, 309},
+   {106 + 180, 309, 1},
/* C3 */
-   {0, 107, 410, 46057},
+   {107 + 410, 46057, 0},
/* C4 */
-   {0, 121, 3374, 46057},
+   {121 + 3374, 46057, 0},
/* C5 */
-   {1, 855, 1146, 46057},
+   {855 + 1146, 46057, 1},
/* C6 */
-   {0, 7580, 4134, 484329},
+   {7580 + 4134, 484329, 0},
/* C7 */
-   {1, 7505, 15274, 484329},
+   {7505 + 15274, 484329, 1},
 };
 
 static struct omap_lcd_config rx51_lcd_config = {
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c 
b/arch/arm/mach-omap2/cpuidle34xx.c
index 1c240ef..d7bc31a 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -52,11 +52,10 @@
 struct omap3_processor_cx {
u8 valid;
u8 type;
-   u32 sleep_latency;
-   u32 wakeup_latency;
+   u32 exit_latency;
u32 mpu_state;
u32 core_state;
-   u32 threshold;
+   u32 target_residency;
u32 flags;
const char *desc;
 };
@@ -75,19 +74,19 @@ struct powerdomain *cam_pd;
  */
 static struct cpuidle_params cpuidle_params_table[] = {
/* C1 */
-   {1, 2, 2, 5},
+   {2 + 2, 5, 1},
/* C2 */
-   {1, 10, 10, 30},
+   {10 + 10, 30, 1},
/* C3 */
-   {1, 50, 50, 300},
+   {50 + 50, 300, 1},
/* C4 */
-   {1, 1500, 1800, 4000},
+   {1500 + 1800, 4000, 1},
/* C5 */
-   {1, 2500, 7500, 12000},
+   {2500 + 7500, 12000, 1},
/* C6 */
-   {1, 3000, 8500, 15000},
+   {3000 + 8500, 15000, 1},
/* C7 */
-   {1, 1, 3, 30},
+   {1 + 3, 30, 1},
 };
 
 static int omap3_idle_bm_check(void)
@@ -330,12 +329,10 @@ void omap3_pm_init_cpuidle(struct cpuidle_params 
*cpuidle_board_params)
for (i = OMAP3_STATE_C1; i  OMAP3_MAX_STATES; i++) {
cpuidle_params_table[i].valid =
cpuidle_board_params[i].valid;
-   cpuidle_params_table[i].sleep_latency =
-   cpuidle_board_params[i].sleep_latency;
-   cpuidle_params_table[i].wake_latency =
-   cpuidle_board_params[i].wake_latency;
-   cpuidle_params_table[i].threshold =
-   cpuidle_board_params[i].threshold;
+   cpuidle_params_table[i].exit_latency =
+   cpuidle_board_params[i].exit_latency;
+   cpuidle_params_table[i].target_residency =
+   cpuidle_board_params[i].target_residency;
}
return;
 }
@@ -357,12 +354,10 @@ void omap_init_power_states(void)
omap3_power_states[OMAP3_STATE_C1].valid =
cpuidle_params_table[OMAP3_STATE_C1].valid;
omap3_power_states[OMAP3_STATE_C1].type = OMAP3_STATE_C1;
-   omap3_power_states[OMAP3_STATE_C1].sleep_latency =
-   cpuidle_params_table[OMAP3_STATE_C1].sleep_latency;
-   omap3_power_states[OMAP3_STATE_C1].wakeup_latency =
-   cpuidle_params_table[OMAP3_STATE_C1].wake_latency;
-   omap3_power_states[OMAP3_STATE_C1].threshold =
-   cpuidle_params_table[OMAP3_STATE_C1].threshold;
+   omap3_power_states[OMAP3_STATE_C1].exit_latency =
+   cpuidle_params_table[OMAP3_STATE_C1].exit_latency;
+   omap3_power_states[OMAP3_STATE_C1].target_residency =
+   cpuidle_params_table[OMAP3_STATE_C1].target_residency;
omap3_power_states[OMAP3_STATE_C1].mpu_state = PWRDM_POWER_ON;
omap3_power_states[OMAP3_STATE_C1].core_state = PWRDM_POWER_ON;
omap3_power_states[OMAP3_STATE_C1].flags = CPUIDLE_FLAG_TIME_VALID;
@@ -372,12 +367,10 @@ void omap_init_power_states(void)

[PATCH 2/4] OMAP3: cpuidle: re-organize the C-states data

2011-05-05 Thread jean . pihet
From: Jean Pihet j-pi...@ti.com

The current implementation defines an internal structure and a
C-states array. Using those structures is redundant to the
structs used by the cpuidle framework.

This patch provides a clean-up of the internal struct, removes the
internal C-states array, stores the data using the existing cpuidle
per C-state struct and registers the mach specific data to cpuidle
C-state driver_data (accessed using cpuidle_[gs]et_statedata).
Also removes unused macros, fields and code and compacts the repeating
code using an inline helper function.

The result is more compact and more readable code as well as
reduced data RAM usage.

Signed-off-by: Jean Pihet j-pi...@ti.com
---
 arch/arm/mach-omap2/cpuidle34xx.c |  291 
 1 files changed, 97 insertions(+), 194 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c 
b/arch/arm/mach-omap2/cpuidle34xx.c
index d7bc31a..816b483 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -36,34 +36,19 @@
 
 #ifdef CONFIG_CPU_IDLE
 
-#define OMAP3_MAX_STATES 7
-#define OMAP3_STATE_C1 0 /* C1 - MPU WFI + Core active */
-#define OMAP3_STATE_C2 1 /* C2 - MPU WFI + Core inactive */
-#define OMAP3_STATE_C3 2 /* C3 - MPU CSWR + Core inactive */
-#define OMAP3_STATE_C4 3 /* C4 - MPU OFF + Core iactive */
-#define OMAP3_STATE_C5 4 /* C5 - MPU RET + Core RET */
-#define OMAP3_STATE_C6 5 /* C6 - MPU OFF + Core RET */
-#define OMAP3_STATE_C7 6 /* C7 - MPU OFF + Core OFF */
+#define OMAP3_STATE_MIN0
+#define OMAP3_STATE_MAX6 /* Deepest sleep C-state */
+#define OMAP3_NB_STATES(OMAP3_STATE_MAX + 1)
 
-#define OMAP3_STATE_MAX OMAP3_STATE_C7
-
-#define CPUIDLE_FLAG_CHECK_BM  0x1 /* use omap3_enter_idle_bm() */
-
-struct omap3_processor_cx {
-   u8 valid;
-   u8 type;
-   u32 exit_latency;
+/* Mach specific information to be recorded in the C-state driver_data */
+struct omap3_idle_statedata {
u32 mpu_state;
u32 core_state;
-   u32 target_residency;
-   u32 flags;
-   const char *desc;
+   u8 valid;
 };
+struct omap3_idle_statedata omap3_idle_data[OMAP3_NB_STATES];
 
-struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
-struct omap3_processor_cx current_cx_state;
-struct powerdomain *mpu_pd, *core_pd, *per_pd;
-struct powerdomain *cam_pd;
+struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
 
 /*
  * The latencies/thresholds for various C states have
@@ -72,7 +57,7 @@ struct powerdomain *cam_pd;
  * the best power savings) used on boards which do not
  * pass these details from the board file.
  */
-static struct cpuidle_params cpuidle_params_table[] = {
+static struct cpuidle_params cpuidle_params_table[OMAP3_NB_STATES] = {
/* C1 */
{2 + 2, 5, 1},
/* C2 */
@@ -121,12 +106,10 @@ static int _cpuidle_deny_idle(struct powerdomain *pwrdm,
 static int omap3_enter_idle(struct cpuidle_device *dev,
struct cpuidle_state *state)
 {
-   struct omap3_processor_cx *cx = cpuidle_get_statedata(state);
+   struct omap3_idle_statedata *cx = cpuidle_get_statedata(state);
struct timespec ts_preidle, ts_postidle, ts_idle;
u32 mpu_state = cx-mpu_state, core_state = cx-core_state;
 
-   current_cx_state = *cx;
-
/* Used to keep track of the total time in idle */
getnstimeofday(ts_preidle);
 
@@ -139,7 +122,8 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
if (omap_irq_pending() || need_resched())
goto return_sleep_time;
 
-   if (cx-type == OMAP3_STATE_C1) {
+   /* Deny idle for C1 */
+   if (state == dev-states[0]) {
pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle);
pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle);
}
@@ -147,7 +131,8 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
/* Execute ARM wfi */
omap_sram_idle();
 
-   if (cx-type == OMAP3_STATE_C1) {
+   /* Re-allow idle for C1 */
+   if (state == dev-states[0]) {
pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle);
pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle);
}
@@ -169,15 +154,15 @@ return_sleep_time:
  *
  * If the current state is valid, it is returned back to the caller.
  * Else, this function searches for a lower c-state which is still
- * valid (as defined in omap3_power_states[]).
+ * valid.
  */
 static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
-   struct cpuidle_state *curr)
+ struct cpuidle_state *curr)
 {
struct cpuidle_state *next = NULL;
-   struct omap3_processor_cx *cx;
+   struct omap3_idle_statedata *cx;
 
-   cx = (struct omap3_processor_cx *)cpuidle_get_statedata(curr);
+   cx = cpuidle_get_statedata(curr);
 
/* Check if 

[PATCH 3/4] OMAP3: cpuidle: code rework for improved readability

2011-05-05 Thread jean . pihet
From: Jean Pihet j-pi...@ti.com

- fix single and multi-lines comments format
- removed the omap3_idle_bm_check function and replaced the test
   in omap3_enter_idle_bm by the equivalent code
- re-organize omap3_enter_idle_bm code path, assign local variables
   only when needed
- reword some comments

Signed-off-by: Jean Pihet j-pi...@ti.com
---
 arch/arm/mach-omap2/cpuidle34xx.c |   52 +---
 1 files changed, 19 insertions(+), 33 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c 
b/arch/arm/mach-omap2/cpuidle34xx.c
index 816b483..5621b6e 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -74,13 +74,6 @@ static struct cpuidle_params 
cpuidle_params_table[OMAP3_NB_STATES] = {
{1 + 3, 30, 1},
 };
 
-static int omap3_idle_bm_check(void)
-{
-   if (!omap3_can_sleep())
-   return 1;
-   return 0;
-}
-
 static int _cpuidle_allow_idle(struct powerdomain *pwrdm,
struct clockdomain *clkdm)
 {
@@ -160,9 +153,7 @@ static struct cpuidle_state *next_valid_state(struct 
cpuidle_device *dev,
  struct cpuidle_state *curr)
 {
struct cpuidle_state *next = NULL;
-   struct omap3_idle_statedata *cx;
-
-   cx = cpuidle_get_statedata(curr);
+   struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
 
/* Check if current state is valid */
if (cx-valid) {
@@ -170,9 +161,7 @@ static struct cpuidle_state *next_valid_state(struct 
cpuidle_device *dev,
} else {
u8 idx = OMAP3_STATE_MAX;
 
-   /*
-* Reach the current state starting at highest C-state
-*/
+   /* Reach the current state starting at highest C-state */
for (; idx = OMAP3_STATE_MIN; idx--) {
if (dev-states[idx] == curr) {
next = dev-states[idx];
@@ -180,9 +169,7 @@ static struct cpuidle_state *next_valid_state(struct 
cpuidle_device *dev,
}
}
 
-   /*
-* Should never hit this condition.
-*/
+   /* Should never hit this condition */
WARN_ON(next == NULL);
 
/*
@@ -217,29 +204,16 @@ static struct cpuidle_state *next_valid_state(struct 
cpuidle_device *dev,
 static int omap3_enter_idle_bm(struct cpuidle_device *dev,
   struct cpuidle_state *state)
 {
-   struct cpuidle_state *new_state = next_valid_state(dev, state);
-   u32 core_next_state, per_next_state = 0, per_saved_state = 0;
-   u32 cam_state;
+   struct cpuidle_state *new_state;
+   u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state;
struct omap3_idle_statedata *cx;
int ret;
 
-   if (omap3_idle_bm_check()) {
-   BUG_ON(!dev-safe_state);
+   if (!omap3_can_sleep()) {
new_state = dev-safe_state;
goto select_state;
}
 
-   cx = cpuidle_get_statedata(state);
-   core_next_state = cx-core_state;
-
-   /*
-* FIXME: we currently manage device-specific idle states
-*for PER and CORE in combination with CPU-specific
-*idle states.  This is wrong, and device-specific
-*idle management needs to be separated out into 
-*its own code.
-*/
-
/*
 * Prevent idle completely if CAM is active.
 * CAM does not have wakeup capability in OMAP3.
@@ -251,9 +225,19 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
}
 
/*
+* FIXME: we currently manage device-specific idle states
+*for PER and CORE in combination with CPU-specific
+*idle states.  This is wrong, and device-specific
+*idle management needs to be separated out into
+*its own code.
+*/
+
+   /*
 * Prevent PER off if CORE is not in retention or off as this
 * would disable PER wakeups completely.
 */
+   cx = cpuidle_get_statedata(state);
+   core_next_state = cx-core_state;
per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
if ((per_next_state == PWRDM_POWER_OFF) 
(core_next_state  PWRDM_POWER_RET))
@@ -263,6 +247,8 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
if (per_next_state != per_saved_state)
pwrdm_set_next_pwrst(per_pd, per_next_state);
 
+   new_state = next_valid_state(dev, state);
+
 select_state:
dev-last_state = new_state;
ret = omap3_enter_idle(dev, new_state);
@@ -323,7 +309,7 @@ struct cpuidle_driver omap3_idle_driver = {
.owner =THIS_MODULE,
 };
 
-/* Fill in the state data from the mach tables and register the driver_data */
+/* Helper 

[PATCH 4/4] OMAP3: cpuidle: change the power domains modes determination logic

2011-05-05 Thread jean . pihet
From: Jean Pihet j-pi...@ti.com

The achievable power modes of the power domains in cpuidle
depends on the system wide 'enable_off_mode' knob in debugfs.
Upon changing enable_off_mode, do not change the C-states
'valid' field but instead dynamically restrict the power modes
when entering idle.

The C-states 'valid' field is just used to enable/disable some
C-states at init and shall not be changed later on.

Signed-off-by: Jean Pihet j-pi...@ti.com
---
 arch/arm/mach-omap2/cpuidle34xx.c |   58 +++-
 arch/arm/mach-omap2/pm.h  |4 --
 arch/arm/mach-omap2/pm34xx.c  |   12 ---
 3 files changed, 24 insertions(+), 50 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c 
b/arch/arm/mach-omap2/cpuidle34xx.c
index 5621b6e..402fd4d 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -141,22 +141,40 @@ return_sleep_time:
 }
 
 /**
- * next_valid_state - Find next valid c-state
+ * next_valid_state - Find next valid C-state
  * @dev: cpuidle device
- * @state: Currently selected c-state
+ * @state: Currently selected C-state
  *
  * If the current state is valid, it is returned back to the caller.
  * Else, this function searches for a lower c-state which is still
  * valid.
+ *
+ * A state is valid if the 'valid' field is enabled and
+ * if it satisfies the enable_off_mode condition.
  */
 static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
  struct cpuidle_state *curr)
 {
struct cpuidle_state *next = NULL;
struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
+   u32 mpu_deepest_state = PWRDM_POWER_RET;
+   u32 core_deepest_state = PWRDM_POWER_RET;
+
+   if (enable_off_mode) {
+   mpu_deepest_state = PWRDM_POWER_OFF;
+   /*
+* Erratum i583: valable for ES rev  Es1.2 on 3630.
+* CORE OFF mode is not supported in a stable form, restrict
+* instead the CORE state to RET.
+*/
+   if (!IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
+   core_deepest_state = PWRDM_POWER_OFF;
+   }
 
/* Check if current state is valid */
-   if (cx-valid) {
+   if ((cx-valid) 
+   (cx-mpu_state = mpu_deepest_state) 
+   (cx-core_state = core_deepest_state)) {
return curr;
} else {
u8 idx = OMAP3_STATE_MAX;
@@ -179,7 +197,9 @@ static struct cpuidle_state *next_valid_state(struct 
cpuidle_device *dev,
idx--;
for (; idx = OMAP3_STATE_MIN; idx--) {
cx = cpuidle_get_statedata(dev-states[idx]);
-   if (cx-valid) {
+   if ((cx-valid) 
+   (cx-mpu_state = mpu_deepest_state) 
+   (cx-core_state = core_deepest_state)) {
next = dev-states[idx];
break;
}
@@ -262,31 +282,6 @@ select_state:
 
 DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
 
-/**
- * omap3_cpuidle_update_states() - Update the cpuidle states
- * @mpu_deepest_state: Enable states up to and including this for mpu domain
- * @core_deepest_state:Enable states up to and including this for core 
domain
- *
- * This goes through the list of states available and enables and disables the
- * validity of C states based on deepest state that can be achieved for the
- * variable domain
- */
-void omap3_cpuidle_update_states(u32 mpu_deepest_state, u32 core_deepest_state)
-{
-   int i;
-
-   for (i = OMAP3_STATE_MIN; i  OMAP3_NB_STATES; i++) {
-   struct omap3_idle_statedata *cx = omap3_idle_data[i];
-
-   if ((cx-mpu_state = mpu_deepest_state) 
-   (cx-core_state = core_deepest_state)) {
-   cx-valid = 1;
-   } else {
-   cx-valid = 0;
-   }
-   }
-}
-
 void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
 {
int i;
@@ -400,11 +395,6 @@ int __init omap3_idle_init(void)
 
dev-state_count = OMAP3_NB_STATES;
 
-   if (enable_off_mode)
-   omap3_cpuidle_update_states(PWRDM_POWER_OFF, PWRDM_POWER_OFF);
-   else
-   omap3_cpuidle_update_states(PWRDM_POWER_RET, PWRDM_POWER_RET);
-
if (cpuidle_register_device(dev)) {
printk(KERN_ERR %s: CPUidle register device failed\n,
   __func__);
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 32dbc13..45bcfce 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -78,10 +78,6 @@ extern u32 sleep_while_idle;
 #define sleep_while_idle 0
 #endif
 
-#if defined(CONFIG_CPU_IDLE)
-extern void omap3_cpuidle_update_states(u32, u32);
-#endif
-
 #if defined(CONFIG_PM_DEBUG)  

DSS pm_runtime problem

2011-05-05 Thread Tomi Valkeinen
Hi Paul, Benoit,

I've started testing pm runtime with DSS, and I encountered a problem.

I'm using latest -rc5 as a base, and it looks like
omap_hwmod:_wait_target_ready() does not succeed for dss_core hwmod.
This causes _enable() to fail, but omap_device_enable_hwmods() does not
check the return values so it looks like everything went well, until the
driver crashes as the DSS HW module was off.

Ideas about _wait_target_ready()? And omap_device_enable_hwmods() would
need some fixing, I wasted quite a while debugging this =).

 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


Module + offset calculations have to be signed in arch/arm/mach-omap2/pm-debug.c

2011-05-05 Thread Peter Barada
I've been working on getting the TI OMAPPSP-03.00.01.06 kernel to 
properly suspend/resume on my DM37x board and all was going well until I 
added OTG support to the kernel and on suspend, the IVA2 and CORE pwrdms 
would not properly go into suspend.  When comparing output from 
/debug/pm-debug/registers/current to the TRM, I noticed the following:


MOD: CM_IVA2 (48014000)
  04 = 0017  20 = 0001  24 = 0001  34 = 0001
  40 = 00080a00  44 = 0001  48 = 0003
MOD: PRM_IVA2 (48316000)
  50 = 0007  e0 = 00ff0f05  e4 = 0ff7  e8 = 0ff7
  f8 = 0001

Looking at the TRM, the PRM_IVA2 registers are at 0x48306000, not 
0x48316000.  OMAP3430_IVA2_MOD is defined in prcm-common.h as -0x800 
which means any module + reg_offset address calculation has to be 
signed.  Once I corrected the unsigned short offset declaration in 
pm_module_def, rebuilt and tested again, IVA2/core pwrdms go into 
suspend correctly (and addresses look correct):



Signed-off-by: Peter Barada peter.bar...@logicpd.com


diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 125f565..b731ef3 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -199,7 +199,7 @@ enum {
 struct pm_module_def {
 char name[8]; /* Name of the module */
 short type; /* CM or PRM */
-unsigned short offset;
+short offset;
 int low; /* First register address on this module */
 int high; /* Last register address on this module */
 };

--
Peter Barada
peter.bar...@gmail.com

--
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: DSS pm_runtime problem

2011-05-05 Thread Tomi Valkeinen
On Thu, 2011-05-05 at 18:59 +0300, Tomi Valkeinen wrote:
 Hi Paul, Benoit,
 
 I've started testing pm runtime with DSS, and I encountered a problem.
 
 I'm using latest -rc5 as a base, and it looks like
 omap_hwmod:_wait_target_ready() does not succeed for dss_core hwmod.
 This causes _enable() to fail, but omap_device_enable_hwmods() does not
 check the return values so it looks like everything went well, until the
 driver crashes as the DSS HW module was off.
 
 Ideas about _wait_target_ready()? And omap_device_enable_hwmods() would
 need some fixing, I wasted quite a while debugging this =).

Ah, the HW needs dss_dss_clk to be enabled before calling
pm_runtime_get, otherwise _wait_target_ready() fails. Now that I think,
I guess Sumit mentioned this at some point.

Too bad, I was hoping I could enable the required opt clocks in
runtime_resume callback.

Shouldn't the hwmod code be able to enable/reset/etc the HW module
independently?

I wonder if this goes for all other DSS modules also...

 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: DSS pm_runtime problem

2011-05-05 Thread Cousson, Benoit

Hi Tomi,

On 5/5/2011 5:59 PM, Valkeinen, Tomi wrote:

Hi Paul, Benoit,

I've started testing pm runtime with DSS, and I encountered a problem.

I'm using latest -rc5 as a base, and it looks like
omap_hwmod:_wait_target_ready() does not succeed for dss_core hwmod.
This causes _enable() to fail, but omap_device_enable_hwmods() does not
check the return values so it looks like everything went well, until the
driver crashes as the DSS HW module was off.

Ideas about _wait_target_ready()? And omap_device_enable_hwmods() would
need some fixing, I wasted quite a while debugging this =).


The wait_target_ready is waiting for the PRCM status. It the status does 
not change, it is probably because some inputs clocks... like the 
optional ones are not enabled.


In your case, you have to enable the DSS fck before calling into PM 
runtime because hwmod does mark this clock as optional:-(



Regards,
Benoit
--
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: Module + offset calculations have to be signed in arch/arm/mach-omap2/pm-debug.c

2011-05-05 Thread Kevin Hilman
Peter Barada peter.bar...@gmail.com writes:

 I've been working on getting the TI OMAPPSP-03.00.01.06 kernel to
 properly suspend/resume on my DM37x board and all was going well until
 I added OTG support to the kernel and on suspend, the IVA2 and CORE
 pwrdms would not properly go into suspend.  When comparing output from
 /debug/pm-debug/registers/current to the TRM, I noticed the following:

 MOD: CM_IVA2 (48014000)
   04 = 0017  20 = 0001  24 = 0001  34 = 0001
   40 = 00080a00  44 = 0001  48 = 0003
 MOD: PRM_IVA2 (48316000)
   50 = 0007  e0 = 00ff0f05  e4 = 0ff7  e8 = 0ff7
   f8 = 0001

 Looking at the TRM, the PRM_IVA2 registers are at 0x48306000, not
 0x48316000.  OMAP3430_IVA2_MOD is defined in prcm-common.h as -0x800
 which means any module + reg_offset address calculation has to be
 signed.  Once I corrected the unsigned short offset declaration in
 pm_module_def, rebuilt and tested again, IVA2/core pwrdms go into
 suspend correctly (and addresses look correct):

Just to be clear, this should only affect the display of the registers,
not whether or not the power domains actually suspend correctly, right?

Or, did you actually notice via some other method that this powerdomain
was not hitting retention/off?

Kevin


 Signed-off-by: Peter Barada peter.bar...@logicpd.com


 diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
 index 125f565..b731ef3 100644
 --- a/arch/arm/mach-omap2/pm-debug.c
 +++ b/arch/arm/mach-omap2/pm-debug.c
 @@ -199,7 +199,7 @@ enum {
  struct pm_module_def {
  char name[8]; /* Name of the module */
  short type; /* CM or PRM */
 -unsigned short offset;
 +short offset;
  int low; /* First register address on this module */
  int high; /* Last register address on this module */
  };
--
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: DSS pm_runtime problem

2011-05-05 Thread Cousson, Benoit

You were faster than me :-)

On 5/5/2011 7:02 PM, Valkeinen, Tomi wrote:

On Thu, 2011-05-05 at 18:59 +0300, Tomi Valkeinen wrote:

Hi Paul, Benoit,

I've started testing pm runtime with DSS, and I encountered a problem.

I'm using latest -rc5 as a base, and it looks like
omap_hwmod:_wait_target_ready() does not succeed for dss_core hwmod.
This causes _enable() to fail, but omap_device_enable_hwmods() does not
check the return values so it looks like everything went well, until the
driver crashes as the DSS HW module was off.

Ideas about _wait_target_ready()? And omap_device_enable_hwmods() would
need some fixing, I wasted quite a while debugging this =).


Ah, the HW needs dss_dss_clk to be enabled before calling
pm_runtime_get, otherwise _wait_target_ready() fails. Now that I think,
I guess Sumit mentioned this at some point.

Too bad, I was hoping I could enable the required opt clocks in
runtime_resume callback.


I guess we should at some point control that clock from the fmwk. 
Unfortunately, we still do not have the good hwmod representation for 
the DSS for the moment.


I'm working on something for all these big subsystems like DSS, ISS, c2c 
to try to fix that. It will unfortunately not be there for 2.6.40 :-(



Shouldn't the hwmod code be able to enable/reset/etc the HW module
independently?


Yes, it should, but we have to change the fck / modulemode / opt_clk 
management for the DSS hwmod.



I wonder if this goes for all other DSS modules also...


We do have some dependency between all DSS modules and the dss_core that 
are not handled today by the fmwk:-(


Regards,
Benoit
--
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: Module + offset calculations have to be signed in arch/arm/mach-omap2/pm-debug.c

2011-05-05 Thread Peter Barada

On 05/05/2011 01:11 PM, Kevin Hilman wrote:

Peter Baradapeter.bar...@gmail.com  writes:


I've been working on getting the TI OMAPPSP-03.00.01.06 kernel to
properly suspend/resume on my DM37x board and all was going well until
I added OTG support to the kernel and on suspend, the IVA2 and CORE
pwrdms would not properly go into suspend.  When comparing output from
/debug/pm-debug/registers/current to the TRM, I noticed the following:

MOD: CM_IVA2 (48014000)
   04 =  0017  20 =  0001  24 =  0001  34 =  0001
   40 =  00080a00  44 =  0001  48 =  0003
MOD: PRM_IVA2 (48316000)
   50 =  0007  e0 =  00ff0f05  e4 =  0ff7  e8 =  0ff7
   f8 =  0001

Looking at the TRM, the PRM_IVA2 registers are at 0x48306000, not
0x48316000.  OMAP3430_IVA2_MOD is defined in prcm-common.h as -0x800
which means any module + reg_offset address calculation has to be
signed.  Once I corrected the unsigned short offset declaration in
pm_module_def, rebuilt and tested again, IVA2/core pwrdms go into
suspend correctly (and addresses look correct):

Just to be clear, this should only affect the display of the registers,
not whether or not the power domains actually suspend correctly, right?

Or, did you actually notice via some other method that this powerdomain
was not hitting retention/off?
Yes the change affects the registers displayed, but since the address 
calculation is incorrect with CONFIG_PM_DEBUG enabled, the PM_DEBUG code 
is reading the CM_IVA2/PRM_IVA2 registers at incorrect addresses.  On my 
DM37x board when I suspended with OTG enabled (and without the patch), I 
see the following on resume:


[  496.168151] Powerdomain (iva2_pwrdm) didn't enter target state 1 
(last power state 3)
[  496.176025] Powerdomain (core_pwrdm) didn't enter target state 1 
(last power state 3)

[  496.183898] Could not enter target state in pm_suspend

With the patch (and same kernel config) I see the following on resume:

[  234.867889] Successfully put all powerdomains to target state

Before enabling the OTG code all powerdomains went into suspend.

It could be that accessing registers at the incorrect addresses is 
causing DM37x to keep those domains out of retention...



Kevin


Signed-off-by: Peter Baradapeter.bar...@logicpd.com


diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 125f565..b731ef3 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -199,7 +199,7 @@ enum {
  struct pm_module_def {
  char name[8]; /* Name of the module */
  short type; /* CM or PRM */
-unsigned short offset;
+short offset;
  int low; /* First register address on this module */
  int high; /* Last register address on this module */
  };

--
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



--
Peter Barada
peter.bar...@gmail.com

--
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 12/12] OMAP2: Serial: Add no async wake flag.

2011-05-05 Thread Kevin Hilman
Govindraj.R govindraj.r...@ti.com writes:

 For omap2 cpu_idle thread will not be available

Why not?

 and uart_clock cutting happens only in suspend path.

Aren't clocks also cut after runtime PM autosuspend?

 Prior to this patch the uart_clock was cut using prepare/resume
 calls since these funcs are no more available with runtime
 changes use no_async_wake flag to keep clock active during bootup
 otherwise uart port will disabled during boot-up and cannot be
 enabled back.

This doesn't just keep clock active during bootup, but it keeps clock
active always, except during suspend.

 Also based on this flag we can disable uart port during suspend
 and enable back during resume.

I think disabling UART port during suspend should already be part of an
earlier patch.  This patch should then only make it conditional.

 Signed-off-by: Govindraj.R govindraj.r...@ti.com
 ---
  arch/arm/mach-omap2/serial.c  |7 +++
  arch/arm/plat-omap/include/plat/omap-serial.h |3 +++
  drivers/tty/serial/omap-serial.c  |   14 ++
  3 files changed, 24 insertions(+), 0 deletions(-)

 diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
 index d4ef370..1af9fd5 100644
 --- a/arch/arm/mach-omap2/serial.c
 +++ b/arch/arm/mach-omap2/serial.c
 @@ -245,6 +245,12 @@ static void omap_uart_wakeup_enable(struct 
 platform_device *pdev, bool enable)
  static void omap_uart_idle_init(struct omap_uart_port_info *uart,
   unsigned short num)
  {
 + /* On omap2 no cpu_idle and async wakeup from prcm_module.

Please remove comments about CPU idle, as the need for this has nothing
to do with CPU idle.

 +  * This flag can be used to cut clocks only in suspend path.
 +  * to avoid boot break due to aggressive clock cutting from
 +  * omap-serial driver.
 +  */

fix multi-line comment style throughout

 + uart-no_async_wake = true;

If needed (which I still don't think I understand), for readability sake
this flag should be called 'has_async_wake', and default to false.  It
should then be set to true on available SoCs.

Kevin

   if (cpu_is_omap34xx()) {
   u32 mod = num  1 ? OMAP3430_PER_MOD : CORE_MOD;
   u32 wk_mask = 0;
 @@ -266,6 +272,7 @@ static void omap_uart_idle_init(struct 
 omap_uart_port_info *uart,
   break;
   }
   uart-wk_mask = wk_mask;
 + uart-no_async_wake = false;
   } else if (cpu_is_omap24xx()) {
   u32 wk_mask = 0;
   u32 wk_en = PM_WKEN1, wk_st = PM_WKST1;
 diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h 
 b/arch/arm/plat-omap/include/plat/omap-serial.h
 index b5117bd..1de5bc4 100644
 --- a/arch/arm/plat-omap/include/plat/omap-serial.h
 +++ b/arch/arm/plat-omap/include/plat/omap-serial.h
 @@ -79,6 +79,7 @@ struct omap_uart_port_info {
   void __iomem *wk_st;
   void __iomem *wk_en;
   u32 wk_mask;
 + boolno_async_wake;
  };
  
  struct uart_omap_dma {
 @@ -134,6 +135,8 @@ struct uart_omap_port {
   unsigned interrata;
   void (*enable_wakeup)(struct platform_device *, bool);
   bool (*chk_wakeup)(struct platform_device *);
 +
 + boolno_async_wake;
  };
  
  #endif /* __OMAP_SERIAL_H__ */
 diff --git a/drivers/tty/serial/omap-serial.c 
 b/drivers/tty/serial/omap-serial.c
 index eea478c..59f548f 100644
 --- a/drivers/tty/serial/omap-serial.c
 +++ b/drivers/tty/serial/omap-serial.c
 @@ -1168,6 +1168,13 @@ static int serial_omap_suspend(struct device *dev)
   uart_suspend_port(serial_omap_reg, up-port);
   console_trylock();
   serial_omap_pm(up-port, 3, 0);
 +
 + /* OMAP2 dont have cpu_idle thread and async wakeup from prcm.
 +  * For such socs clocks will be kept active from probe and
 +  * cut only in suspend path.
 +  */
 + if (up-no_async_wake)
 + serial_omap_port_disable(up);
   }
   return 0;
  }
 @@ -1179,6 +1186,9 @@ static int serial_omap_resume(struct device *dev)
   if (up) {
   uart_resume_port(serial_omap_reg, up-port);
   console_unlock();
 +
 + if (up-no_async_wake)
 + serial_omap_port_enable(up);
   }
  
   return 0;
 @@ -1402,6 +1412,7 @@ static int serial_omap_probe(struct platform_device 
 *pdev)
   up-errata = omap_up_info-errata;
   up-enable_wakeup = omap_up_info-enable_wakeup;
   up-chk_wakeup = omap_up_info-chk_wakeup;
 + up-no_async_wake = omap_up_info-no_async_wake;
  
   if (omap_up_info-dma_enabled) {
   up-uart_dma.uart_dma_tx = dma_tx-start;
 @@ -1430,6 +1441,9 @@ static int serial_omap_probe(struct platform_device 
 *pdev)
   serial_omap_port_disable(up);
   }
  
 + if (up-no_async_wake)
 + serial_omap_port_enable(up);
 +

Re: [PATCH 2/4] OMAP3: cpuidle: re-organize the C-states data

2011-05-05 Thread Kevin Hilman
Hi Jean,

jean.pi...@newoldbits.com writes:

 From: Jean Pihet j-pi...@ti.com

 The current implementation defines an internal structure and a
 C-states array. Using those structures is redundant to the
 structs used by the cpuidle framework.

 This patch provides a clean-up of the internal struct, removes the
 internal C-states array, stores the data using the existing cpuidle
 per C-state struct and registers the mach specific data to cpuidle
 C-state driver_data (accessed using cpuidle_[gs]et_statedata).
 Also removes unused macros, fields and code and compacts the repeating
 code using an inline helper function.

 The result is more compact and more readable code as well as
 reduced data RAM usage.

 Signed-off-by: Jean Pihet j-pi...@ti.com

Some minor comments below...

 ---
  arch/arm/mach-omap2/cpuidle34xx.c |  291 
  1 files changed, 97 insertions(+), 194 deletions(-)

 diff --git a/arch/arm/mach-omap2/cpuidle34xx.c 
 b/arch/arm/mach-omap2/cpuidle34xx.c
 index d7bc31a..816b483 100644
 --- a/arch/arm/mach-omap2/cpuidle34xx.c
 +++ b/arch/arm/mach-omap2/cpuidle34xx.c
 @@ -36,34 +36,19 @@
  
  #ifdef CONFIG_CPU_IDLE
  
 -#define OMAP3_MAX_STATES 7
 -#define OMAP3_STATE_C1 0 /* C1 - MPU WFI + Core active */
 -#define OMAP3_STATE_C2 1 /* C2 - MPU WFI + Core inactive */
 -#define OMAP3_STATE_C3 2 /* C3 - MPU CSWR + Core inactive */
 -#define OMAP3_STATE_C4 3 /* C4 - MPU OFF + Core iactive */
 -#define OMAP3_STATE_C5 4 /* C5 - MPU RET + Core RET */
 -#define OMAP3_STATE_C6 5 /* C6 - MPU OFF + Core RET */
 -#define OMAP3_STATE_C7 6 /* C7 - MPU OFF + Core OFF */
 +#define OMAP3_STATE_MIN  0
 +#define OMAP3_STATE_MAX  6 /* Deepest sleep C-state */
 +#define OMAP3_NB_STATES  (OMAP3_STATE_MAX + 1)

How about droping MIN and MAX all together.  Min is always zero, just
use zero in the code.

Then later, 

static struct cpuidle_params cpuidle_params_table[] = {
/* C1 */
{2 + 2, 5, 1},
...
};

#define OMAP3_NUM_STATES ARRAY_SIZE(cpuidle_params_table);

This way is less error prone, since when adding/removing states, you
don't also have to manually update NUM_STATES.

 -#define OMAP3_STATE_MAX OMAP3_STATE_C7
 -
 -#define CPUIDLE_FLAG_CHECK_BM0x1 /* use omap3_enter_idle_bm() */
 -
 -struct omap3_processor_cx {
 - u8 valid;
 - u8 type;
 - u32 exit_latency;
 +/* Mach specific information to be recorded in the C-state driver_data */
 +struct omap3_idle_statedata {
   u32 mpu_state;
   u32 core_state;
 - u32 target_residency;
 - u32 flags;
 - const char *desc;
 + u8 valid;
  };
 +struct omap3_idle_statedata omap3_idle_data[OMAP3_NB_STATES];
 -struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
 -struct omap3_processor_cx current_cx_state;
 -struct powerdomain *mpu_pd, *core_pd, *per_pd;
 -struct powerdomain *cam_pd;
 +struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
  
  /*
   * The latencies/thresholds for various C states have
 @@ -72,7 +57,7 @@ struct powerdomain *cam_pd;
   * the best power savings) used on boards which do not
   * pass these details from the board file.
   */
 -static struct cpuidle_params cpuidle_params_table[] = {
 +static struct cpuidle_params cpuidle_params_table[OMAP3_NB_STATES] = {
   /* C1 */
   {2 + 2, 5, 1},
   /* C2 */
 @@ -121,12 +106,10 @@ static int _cpuidle_deny_idle(struct powerdomain *pwrdm,
  static int omap3_enter_idle(struct cpuidle_device *dev,
   struct cpuidle_state *state)
  {
 - struct omap3_processor_cx *cx = cpuidle_get_statedata(state);
 + struct omap3_idle_statedata *cx = cpuidle_get_statedata(state);
   struct timespec ts_preidle, ts_postidle, ts_idle;
   u32 mpu_state = cx-mpu_state, core_state = cx-core_state;
  
 - current_cx_state = *cx;
 -
   /* Used to keep track of the total time in idle */
   getnstimeofday(ts_preidle);
  
 @@ -139,7 +122,8 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
   if (omap_irq_pending() || need_resched())
   goto return_sleep_time;
  
 - if (cx-type == OMAP3_STATE_C1) {
 + /* Deny idle for C1 */
 + if (state == dev-states[0]) {
   pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle);
   pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle);
   }
 @@ -147,7 +131,8 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
   /* Execute ARM wfi */
   omap_sram_idle();
  
 - if (cx-type == OMAP3_STATE_C1) {
 + /* Re-allow idle for C1 */
 + if (state == dev-states[0]) {
   pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle);
   pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle);
   }
 @@ -169,15 +154,15 @@ return_sleep_time:
   *
   * If the current state is valid, it is returned back to the caller.
   * Else, this function searches for a lower c-state which is still
 - * valid (as defined in omap3_power_states[]).
 + 

Re: Module + offset calculations have to be signed in arch/arm/mach-omap2/pm-debug.c

2011-05-05 Thread Kevin Hilman
Peter Barada peter.bar...@gmail.com writes:

 On 05/05/2011 01:11 PM, Kevin Hilman wrote:
 Peter Baradapeter.bar...@gmail.com  writes:

 I've been working on getting the TI OMAPPSP-03.00.01.06 kernel to
 properly suspend/resume on my DM37x board and all was going well until
 I added OTG support to the kernel and on suspend, the IVA2 and CORE
 pwrdms would not properly go into suspend.  When comparing output from
 /debug/pm-debug/registers/current to the TRM, I noticed the following:

 MOD: CM_IVA2 (48014000)
04 =  0017  20 =  0001  24 =  0001  34 =  0001
40 =  00080a00  44 =  0001  48 =  0003
 MOD: PRM_IVA2 (48316000)
50 =  0007  e0 =  00ff0f05  e4 =  0ff7  e8 =  0ff7
f8 =  0001

 Looking at the TRM, the PRM_IVA2 registers are at 0x48306000, not
 0x48316000.  OMAP3430_IVA2_MOD is defined in prcm-common.h as -0x800
 which means any module + reg_offset address calculation has to be
 signed.  Once I corrected the unsigned short offset declaration in
 pm_module_def, rebuilt and tested again, IVA2/core pwrdms go into
 suspend correctly (and addresses look correct):
 Just to be clear, this should only affect the display of the registers,
 not whether or not the power domains actually suspend correctly, right?

 Or, did you actually notice via some other method that this powerdomain
 was not hitting retention/off?
 Yes the change affects the registers displayed, but since the address
 calculation is incorrect with CONFIG_PM_DEBUG enabled, the PM_DEBUG
 code is reading the CM_IVA2/PRM_IVA2 registers at incorrect addresses.
 On my DM37x board when I suspended with OTG enabled (and without the
 patch), I see the following on resume:

 [  496.168151] Powerdomain (iva2_pwrdm) didn't enter target state 1
 (last power state 3)
 [  496.176025] Powerdomain (core_pwrdm) didn't enter target state 1
 (last power state 3)

Hmm, this 'last power state' printk isn't in mainline, so it appears
there are some other local modifications to this code.

 [  496.183898] Could not enter target state in pm_suspend

 With the patch (and same kernel config) I see the following on resume:

 [  234.867889] Successfully put all powerdomains to target state

 Before enabling the OTG code all powerdomains went into suspend.

 It could be that accessing registers at the incorrect addresses is
 causing DM37x to keep those domains out of retention...

Hmm, very strange.  The PM debug code only ever reads registers, never
writes, so I can't imagine how that should prevent those power domains
from hitting retention.  Are there any other out-of-tree patches to the
pm-debug code in your kernel?

In any case, you've found a real bug, and your patch is valid.  However,
it doesn't currently apply to mainline, and it looks like it's because
your patch is using spaces and the code being patched is using tabs.

Also, you can simplify the changelog to to just describe the fix needed
due to using negative offsets in some PRM modules.

Kevin


 Kevin

 Signed-off-by: Peter Baradapeter.bar...@logicpd.com


 diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
 index 125f565..b731ef3 100644
 --- a/arch/arm/mach-omap2/pm-debug.c
 +++ b/arch/arm/mach-omap2/pm-debug.c
 @@ -199,7 +199,7 @@ enum {
   struct pm_module_def {
   char name[8]; /* Name of the module */
   short type; /* CM or PRM */
 -unsigned short offset;
 +short offset;
   int low; /* First register address on this module */
   int high; /* Last register address on this module */
   };
 --
 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] omap : nand : fix subpage ecc issue with prefetch

2011-05-05 Thread Artem Bityutskiy
On Mon, 2011-05-02 at 16:40 +0530, Kishore Kadiyala wrote:
 For prefetch engine, read and write  got broken in commit '2c01946c'.
 We never hit a scenario of not getting 'gpmc_prefetch_enable'
 call success.
 When reading/writing a subpage with a non divisible by 4 ecc number
 of bytes, the mis-aligned bytes gets handled first before enabling
 the Prefetch engine, then it reads/writes rest of the bytes.
 
 Signed-off-by: Kishore Kadiyala kishore.kadiy...@ti.com
 Signed-off-by: Vimal Singh vimal.neww...@gmail.com
 Reported-by: Bryan DE FARIA bdefa...@adeneo-embedded.com

This needs a better commit message with more explanation and analysis of
the problem and how it was fixed.This commit message is not very
understandable. And then it needs also:

Cc: sta...@kernel.org [2.6.36+]

Right? And then we could send it upstream.

-- 
Best Regards,
Artem Bityutskiy (Артём Битюцкий)

--
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: Module + offset calculations have to be signed in arch/arm/mach-omap2/pm-debug.c

2011-05-05 Thread Peter Barada

On 05/05/2011 02:16 PM, Kevin Hilman wrote:

Peter Baradapeter.bar...@gmail.com  writes:


On 05/05/2011 01:11 PM, Kevin Hilman wrote:

Peter Baradapeter.bar...@gmail.com   writes:


I've been working on getting the TI OMAPPSP-03.00.01.06 kernel to
properly suspend/resume on my DM37x board and all was going well until
I added OTG support to the kernel and on suspend, the IVA2 and CORE
pwrdms would not properly go into suspend.  When comparing output from
/debug/pm-debug/registers/current to the TRM, I noticed the following:

MOD: CM_IVA2 (48014000)
04 =   0017  20 =   0001  24 =   0001  34 =   0001
40 =   00080a00  44 =   0001  48 =   0003
MOD: PRM_IVA2 (48316000)
50 =   0007  e0 =   00ff0f05  e4 =   0ff7  e8 =   0ff7
f8 =   0001

Looking at the TRM, the PRM_IVA2 registers are at 0x48306000, not
0x48316000.  OMAP3430_IVA2_MOD is defined in prcm-common.h as -0x800
which means any module + reg_offset address calculation has to be
signed.  Once I corrected the unsigned short offset declaration in
pm_module_def, rebuilt and tested again, IVA2/core pwrdms go into
suspend correctly (and addresses look correct):

Just to be clear, this should only affect the display of the registers,
not whether or not the power domains actually suspend correctly, right?

Or, did you actually notice via some other method that this powerdomain
was not hitting retention/off?

Yes the change affects the registers displayed, but since the address
calculation is incorrect with CONFIG_PM_DEBUG enabled, the PM_DEBUG
code is reading the CM_IVA2/PRM_IVA2 registers at incorrect addresses.
On my DM37x board when I suspended with OTG enabled (and without the
patch), I see the following on resume:

[  496.168151] Powerdomain (iva2_pwrdm) didn't enter target state 1
(last power state 3)
[  496.176025] Powerdomain (core_pwrdm) didn't enter target state 1
(last power state 3)

Hmm, this 'last power state' printk isn't in mainline, so it appears
there are some other local modifications to this code.
Yes, I added it to the printk to help figure out what state the domain 
was in:


list_for_each_entry(pwrst, pwrst_list, node) {
state = pwrdm_read_prev_pwrst(pwrst-pwrdm);
if (state  pwrst-next_state) {
printk(KERN_INFO Powerdomain (%s) didn't enter 
   target state %d (last power state %d)\n,
pwrst-pwrdm-name, pwrst-next_state, state);
ret = -1;
}
set_pwrdm_state(pwrst-pwrdm, pwrst-saved_state);
}


[  496.183898] Could not enter target state in pm_suspend

With the patch (and same kernel config) I see the following on resume:

[  234.867889] Successfully put all powerdomains to target state

Before enabling the OTG code all powerdomains went into suspend.

It could be that accessing registers at the incorrect addresses is
causing DM37x to keep those domains out of retention...

Hmm, very strange.  The PM debug code only ever reads registers, never
writes, so I can't imagine how that should prevent those power domains
from hitting retention.  Are there any other out-of-tree patches to the
pm-debug code in your kernel?
Yes there are, but I've kept it to just reading PRM/CM registers (and 
store them into SRAM to print out on resume).  Still, I don't understand 
how just changing the address where to read the IVA2 registers can make 
it break/work, unless some side-effect of hte read make's life happy.  
I'll have to retry w/o PM_DEBUG enabled to see if the effect changes.



In any case, you've found a real bug, and your patch is valid.  However,
it doesn't currently apply to mainline, and it looks like it's because
your patch is using spaces and the code being patched is using tabs.

Hmm, could be Thunderbird munching it...

Also, you can simplify the changelog to to just describe the fix needed
due to using negative offsets in some PRM modules.
I'll rework the patch and send it back.  I'm also comparing the list of 
registers you read with what the TRM lists (for the AM3730), and I see 
that you read entire ranges even if the range is sparsely populated, eg:


{ IVA2, MOD_CM, OMAP3430_IVA2_MOD, 0x00, 0x04 },
{ IVA2, MOD_CM, OMAP3430_IVA2_MOD, 0x20, 0x24 },
{ IVA2, MOD_CM, OMAP3430_IVA2_MOD, 0x34, 0x34 },
{ IVA2, MOD_CM, OMAP3430_IVA2_MOD, 0x40, 0x4c },

and code to detect that its still looking at a pm_module_def entry that 
has the same type/offset as the previous to prevent the headers from 
being repeatedly printed.




Kevin


Kevin


Signed-off-by: Peter Baradapeter.bar...@logicpd.com


diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 125f565..b731ef3 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -199,7 +199,7 @@ enum {
   struct pm_module_def {
   char name[8]; /* Name of the module */
   short type; /* CM or PRM */
-unsigned short offset;
+short offset;
   int low; /* First register 

Re: Module + offset calculations have to be signed in arch/arm/mach-omap2/pm-debug.c

2011-05-05 Thread Kevin Hilman
Peter Barada peter.bar...@gmail.com writes:

 On 05/05/2011 02:16 PM, Kevin Hilman wrote:
 Peter Baradapeter.bar...@gmail.com  writes:

 On 05/05/2011 01:11 PM, Kevin Hilman wrote:
 Peter Baradapeter.bar...@gmail.com   writes:

 I've been working on getting the TI OMAPPSP-03.00.01.06 kernel to
 properly suspend/resume on my DM37x board and all was going well until
 I added OTG support to the kernel and on suspend, the IVA2 and CORE
 pwrdms would not properly go into suspend.  When comparing output from
 /debug/pm-debug/registers/current to the TRM, I noticed the following:

 MOD: CM_IVA2 (48014000)
 04 =   0017  20 =   0001  24 =   0001  34 =   0001
 40 =   00080a00  44 =   0001  48 =   0003
 MOD: PRM_IVA2 (48316000)
 50 =   0007  e0 =   00ff0f05  e4 =   0ff7  e8 =   0ff7
 f8 =   0001

 Looking at the TRM, the PRM_IVA2 registers are at 0x48306000, not
 0x48316000.  OMAP3430_IVA2_MOD is defined in prcm-common.h as -0x800
 which means any module + reg_offset address calculation has to be
 signed.  Once I corrected the unsigned short offset declaration in
 pm_module_def, rebuilt and tested again, IVA2/core pwrdms go into
 suspend correctly (and addresses look correct):
 Just to be clear, this should only affect the display of the registers,
 not whether or not the power domains actually suspend correctly, right?

 Or, did you actually notice via some other method that this powerdomain
 was not hitting retention/off?
 Yes the change affects the registers displayed, but since the address
 calculation is incorrect with CONFIG_PM_DEBUG enabled, the PM_DEBUG
 code is reading the CM_IVA2/PRM_IVA2 registers at incorrect addresses.
 On my DM37x board when I suspended with OTG enabled (and without the
 patch), I see the following on resume:

 [  496.168151] Powerdomain (iva2_pwrdm) didn't enter target state 1
 (last power state 3)
 [  496.176025] Powerdomain (core_pwrdm) didn't enter target state 1
 (last power state 3)
 Hmm, this 'last power state' printk isn't in mainline, so it appears
 there are some other local modifications to this code.
 Yes, I added it to the printk to help figure out what state the domain
 was in:

 list_for_each_entry(pwrst, pwrst_list, node) {
 state = pwrdm_read_prev_pwrst(pwrst-pwrdm);
 if (state  pwrst-next_state) {
 printk(KERN_INFO Powerdomain (%s) didn't enter 
target state %d (last power state %d)\n,
 pwrst-pwrdm-name, pwrst-next_state, state);
 ret = -1;
 }
 set_pwrdm_state(pwrst-pwrdm, pwrst-saved_state);
 }

 [  496.183898] Could not enter target state in pm_suspend

 With the patch (and same kernel config) I see the following on resume:

 [  234.867889] Successfully put all powerdomains to target state

 Before enabling the OTG code all powerdomains went into suspend.

 It could be that accessing registers at the incorrect addresses is
 causing DM37x to keep those domains out of retention...
 Hmm, very strange.  The PM debug code only ever reads registers, never
 writes, so I can't imagine how that should prevent those power domains
 from hitting retention.  Are there any other out-of-tree patches to the
 pm-debug code in your kernel?
 Yes there are, but I've kept it to just reading PRM/CM registers (and
 store them into SRAM to print out on resume).  Still, I don't
 understand how just changing the address where to read the IVA2
 registers can make it break/work, unless some side-effect of hte read
 make's life happy.  I'll have to retry w/o PM_DEBUG enabled to see if
 the effect changes.

Rather than disable PM_DEBUG...

Does your kernel do any pm_dbg_regset_save() calls in the suspend/idle
path?  If so, it would suffice to comment those out and see if that
makes it work again (without your patch.)  Would be interesting.

 In any case, you've found a real bug, and your patch is valid.  However,
 it doesn't currently apply to mainline, and it looks like it's because
 your patch is using spaces and the code being patched is using tabs.
 Hmm, could be Thunderbird munching it...
 Also, you can simplify the changelog to to just describe the fix needed
 due to using negative offsets in some PRM modules.
 I'll rework the patch and send it back.  I'm also comparing the list
 of registers you read with what the TRM lists (for the AM3730), and I
 see that you read entire ranges even if the range is sparsely
 populated, eg:

 { IVA2, MOD_CM, OMAP3430_IVA2_MOD, 0x00, 0x04 },
 { IVA2, MOD_CM, OMAP3430_IVA2_MOD, 0x20, 0x24 },
 { IVA2, MOD_CM, OMAP3430_IVA2_MOD, 0x34, 0x34 },
 { IVA2, MOD_CM, OMAP3430_IVA2_MOD, 0x40, 0x4c },

 and code to detect that its still looking at a pm_module_def entry
 that has the same type/offset as the previous to prevent the headers
 from being repeatedly printed.

Yes, admittedly this code is really awful and doesn't even belong in the
kernel.  It also doesn't scale well for OMAP4.  Don't be 

Re: Common clock and dvfs

2011-05-05 Thread Cousson, Benoit

On 5/5/2011 8:11 AM, Colin Cross wrote:

On Wed, May 4, 2011 at 10:08 PM, Cousson, Benoitb-cous...@ti.com  wrote:

(Cc folks with some DVFS interest)

Hi Colin,

On Fri, 22 Apr 2011, Colin Cross wrote:


Now that we are approaching a common clock management implementation,
I was thinking it might be the right place to put a common dvfs
implementation as well.

It is very common for SoC manufacturers to provide a table of the
minimum voltage required on a voltage rail for a clock to run at a
given frequency.  There may be multiple clocks in a voltage rail that
each can specify their own minimum voltage, and one clock may affect
multiple voltage rails.  I have seen two ways to handle keeping the
clocks and voltages within spec:

The Tegra way is to put everything dvfs related under the clock
framework.  Enabling (or preparing, in the new clock world) or raising
the frequency calls dvfs_set_rate before touching the clock, which
looks up the required voltage on a voltage rail, aggregates it with
the other voltage requests, and passes the minimum voltage required to
the regulator api.  Disabling or unpreparing, or lowering the
frequency changes the clock first, and then calls dvfs_set_rate.  For
a generic implementation, an SoC would provide the clock/dvfs
framework with a list of clocks, the voltages required for each
frequency step on the clock, and the regulator name to change.  The
frequency/voltage tables are similar to OPP, except that OPP gets
voltages for a device instead of a clock.  In a few odd cases (Tegra
always has a few odd cases), a clock that is internal to a device and
not exposed to the clock framework (pclk output on the display, for
example) has a voltage requirement, which requires some devices to
manually call dvfs_set_rate directly, but with a common clock
framework it would probably be possible for the display driver to
export pclk as a real clock.


Those kinds of exceptions are somehow the rules for an OMAP4 device. Most
scalable devices are using some internal dividers or even internal PLL to
control the scalable clock rate (DSS, HSI, MMC, McBSP... the OMAP4430 Data
Manual [1] is providing the various clock rate limitation depending of the
OPP).
And none of these internal dividers are handled by the clock fmwk today.

For sure, it should be possible to extend the clock data with internal
devices clock nodes (like the UART baud rate divider for example), but then
we will have to handle a bunch of nodes that may not be always available
depending of device state. In order to do that, you have to tie these clocks
node to the device that contains them.


I agree there are cases where the clock framework may not be a fit for
a specific divider, but it would be simple to export the same
dvfs_set_rate functions that the generic clk_set_rate calls, and allow
drivers that need to scale their own clocks to take advantage of the
common tables.


And for the clocks that do not belong to any device, like most PRCM source
clocks or DPLL inside OMAP, we can easily define a PRCM device or several CM
(Clock Manager) devices that will handle all these clock nodes.


The proposed OMAP4 way (I believe, correct me if I am wrong) is to
create a new api outside the clock api that calls into both the clock
api and the regulator api in the correct order for each operation,
using OPP to determine the voltage.  This has a few disadvantages
(obviously, I am biased, having written the Tegra code) - clocks and
voltages are tied to a device, which is not always the case for
platforms outside of OMAP, and drivers must know if their hardware
requires voltage scaling.  The clock api becomes unsafe to use on any
device that requires dvfs, as it could change the frequency higher
than the supported voltage.


You have to tie clock and voltage to a device. Most of the time a clock does
not have any clear relation with a voltage domain. It can even cross power /
voltage domain without any issue.
The efficiency of the DVFS technique is mainly due to the reduction of the
voltage rail that supply a device. In order to achieve that you have to
reduce the clock rate of one or several clocks nodes that supply the
critical path inside the HW.


A clock crossing a voltage domain is not a problem, a single clock can
have relationships to multiple regulators.  But a clock does not need
to be tied to a device.  From the silicon perspective, it doesn't
matter how you divide up the devices in the kernel, a clock is just a
line toggling at a rate, and the maximum speed it can toggle is
determined by the silicon it feeds and the voltage that silicon is
operating at.  If a device can be turned on or off, that's a clock
gate, and the line downstream from the clock gate is a separate clock.


Fully agree.

Just to clarify the terminology, I'm using device to represent the IP 
block as well. The mapping is not necessarily one to one, but for most 
relevant IPs this is mostly true. In our case, the hwmod will represent 
the HW device.


My 

Re: [PATCH v3] OMAP2/3: hwmod: fix the i2c-reset timeout during bootup

2011-05-05 Thread Paul Walmsley
Hello Avinash

On Mon, 2 May 2011, Avinash.H.M wrote:

 The sequence of _ocp_softreset doesn't work for i2c. The i2c module has a
 special sequence to reset the module. The sequence is
  - Disable the I2C.
  - Write to SOFTRESET bit.
  - Enable the I2C.
  - Poll on the RESETDONE bit.
 The sequence is implemented as a function and the i2c_class is updated with
 the correct 'reset' pointer.  omap_hwmod_softreset function is implemented
 which triggers the softreset by writing into sysconfig register. On following
 this sequence, i2c module resets properly and timeouts are not seen.
 
 Cc: Rajendra Nayak rna...@ti.com
 Cc: Paul Walmsley p...@pwsan.com
 Cc: Benoit Cousson b-cous...@ti.com
 Cc: Kevin Hilman khil...@ti.com
 Signed-off-by: Avinash.H.M avinas...@ti.com
 ---
 
 The patch is based on
  * git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
  * master branch.
  * 9be20f0 commit. ( Linux-omap rebuilt: Updated to -rc5 )

Please base all your patches against mainline commits.  I suggest using 
v2.6.39-rc6.

Also some comments:

 Changes from previous versions:
 from v1:
   - moved i2c specific things from hwmod files to i2c files.
   - fixed comments from Paul.
   - http://www.spinics.net/lists/linux-omap/msg49483.html
 
 from v2: 
   - Avoided direct SYSCONFIG access in i2c.c
   - http://www.spinics.net/lists/linux-omap/msg49632.html
 
 Testing:
 * build tested omap2plus_defconfig for warnings and errors. none introduced.
 * boot tested on 2430. 
 * tested for 'core off' in suspend resume on 3430 sdp. core off counters
   increment after suspend resume. 
 
  arch/arm/mach-omap2/i2c.c|   54 
 ++
  arch/arm/mach-omap2/omap_hwmod.c |   12 ++
  arch/arm/mach-omap2/omap_hwmod_2420_data.c   |1 +
  arch/arm/mach-omap2/omap_hwmod_2430_data.c   |1 +
  arch/arm/mach-omap2/omap_hwmod_3xxx_data.c   |1 +
  arch/arm/plat-omap/include/plat/i2c.h|4 ++
  arch/arm/plat-omap/include/plat/omap_hwmod.h |1 +
  7 files changed, 74 insertions(+), 0 deletions(-)
 
 diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c
 index 79c478c..bd50e26 100644
 --- a/arch/arm/mach-omap2/i2c.c
 +++ b/arch/arm/mach-omap2/i2c.c
 @@ -21,9 +21,16 @@
  
  #include plat/cpu.h
  #include plat/i2c.h
 +#include plat/common.h
  
  #include mux.h
  
 +/* In register I2C_CON, Bit 15 is the I2C enable bit */
 +#define I2C_EN   BIT(15)
 +#define I2C_CON_OFFSET   0x24
 +/* Maximum microseconds to wait for OMAP module to softreset */
 +#define MAX_MODULE_SOFTRESET_WAIT1
 +
  void __init omap2_i2c_mux_pins(int bus_id)
  {
   char mux_name[sizeof(i2c2_scl.i2c2_scl)];
 @@ -37,3 +44,50 @@ void __init omap2_i2c_mux_pins(int bus_id)
   sprintf(mux_name, i2c%i_sda.i2c%i_sda, bus_id, bus_id);
   omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
  }
 +
 +/**
 + * omap_i2c_reset- reset the omap i2c module.

Please put a space before the dash.

 + * @oh: struct omap_hwmod *
 + *
 + * The i2c moudle in omap2, omap3 had a special sequence to reset. The
 + * sequence is:
 + * - Disable the I2C.
 + * - Write to SOFTRESET bit.
 + * - Enable the I2C.
 + * - Poll on the RESETDONE bit.
 + * The sequence is implemented in below function. This is called for 2420,
 + * 2430 and omap3.
 + */
 +int omap_i2c_reset(struct omap_hwmod *oh)
 +{
 + u32 v;
 + int c = 0;
 +
 + /* Disable I2C */
 + v = omap_hwmod_read(oh, I2C_CON_OFFSET);
 + v = v  ~I2C_EN;
 + omap_hwmod_write(v, oh, I2C_CON_OFFSET);
 +
 + /* Write to the SOFTRESET bit */
 + omap_hwmod_softreset(oh);
 +
 + /* Enable I2C */
 + v = omap_hwmod_read(oh, I2C_CON_OFFSET);
 + v |= I2C_EN;
 + omap_hwmod_write(v, oh, I2C_CON_OFFSET);
 +
 + /* Poll on RESETDONE bit */
 + omap_test_timeout((omap_hwmod_read(oh,
 + oh-class-sysc-syss_offs)
 +  SYSS_RESETDONE_MASK),
 + MAX_MODULE_SOFTRESET_WAIT, c);
 +
 + if (c == MAX_MODULE_SOFTRESET_WAIT)
 + pr_warning(%s: %s: softreset failed (waited %d usec)\n,
 + __func__, oh-name, MAX_MODULE_SOFTRESET_WAIT);
 + else
 + pr_debug(%s: %s: softreset in %d usec\n, __func__,
 + oh-name, c);
 +
 + return 0;
 +}
 diff --git a/arch/arm/mach-omap2/omap_hwmod.c 
 b/arch/arm/mach-omap2/omap_hwmod.c
 index e034294..771fc15 100644
 --- a/arch/arm/mach-omap2/omap_hwmod.c
 +++ b/arch/arm/mach-omap2/omap_hwmod.c
 @@ -1561,6 +1561,18 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, 
 u16 reg_offs)
   __raw_writel(v, oh-_mpu_rt_va + reg_offs);
  }
  

You're missing kerneldoc here.  Please add it.

 +void omap_hwmod_softreset(struct omap_hwmod *oh)
 +{
 + u32 v;
 +
 + /* Write to the SOFTRESET bit in SYSCONFIG */
 + v = oh-_sysc_cache;
 + v |= (0x1  

Re: Common clock and dvfs

2011-05-05 Thread Colin Cross
On Thu, May 5, 2011 at 2:08 PM, Cousson, Benoit b-cous...@ti.com wrote:
 On 5/5/2011 8:11 AM, Colin Cross wrote:

 On Wed, May 4, 2011 at 10:08 PM, Cousson, Benoitb-cous...@ti.com  wrote:

 (Cc folks with some DVFS interest)

 Hi Colin,

 On Fri, 22 Apr 2011, Colin Cross wrote:

 Now that we are approaching a common clock management implementation,
 I was thinking it might be the right place to put a common dvfs
 implementation as well.

 It is very common for SoC manufacturers to provide a table of the
 minimum voltage required on a voltage rail for a clock to run at a
 given frequency.  There may be multiple clocks in a voltage rail that
 each can specify their own minimum voltage, and one clock may affect
 multiple voltage rails.  I have seen two ways to handle keeping the
 clocks and voltages within spec:

 The Tegra way is to put everything dvfs related under the clock
 framework.  Enabling (or preparing, in the new clock world) or raising
 the frequency calls dvfs_set_rate before touching the clock, which
 looks up the required voltage on a voltage rail, aggregates it with
 the other voltage requests, and passes the minimum voltage required to
 the regulator api.  Disabling or unpreparing, or lowering the
 frequency changes the clock first, and then calls dvfs_set_rate.  For
 a generic implementation, an SoC would provide the clock/dvfs
 framework with a list of clocks, the voltages required for each
 frequency step on the clock, and the regulator name to change.  The
 frequency/voltage tables are similar to OPP, except that OPP gets
 voltages for a device instead of a clock.  In a few odd cases (Tegra
 always has a few odd cases), a clock that is internal to a device and
 not exposed to the clock framework (pclk output on the display, for
 example) has a voltage requirement, which requires some devices to
 manually call dvfs_set_rate directly, but with a common clock
 framework it would probably be possible for the display driver to
 export pclk as a real clock.

 Those kinds of exceptions are somehow the rules for an OMAP4 device. Most
 scalable devices are using some internal dividers or even internal PLL to
 control the scalable clock rate (DSS, HSI, MMC, McBSP... the OMAP4430
 Data
 Manual [1] is providing the various clock rate limitation depending of
 the
 OPP).
 And none of these internal dividers are handled by the clock fmwk today.

 For sure, it should be possible to extend the clock data with internal
 devices clock nodes (like the UART baud rate divider for example), but
 then
 we will have to handle a bunch of nodes that may not be always available
 depending of device state. In order to do that, you have to tie these
 clocks
 node to the device that contains them.

 I agree there are cases where the clock framework may not be a fit for
 a specific divider, but it would be simple to export the same
 dvfs_set_rate functions that the generic clk_set_rate calls, and allow
 drivers that need to scale their own clocks to take advantage of the
 common tables.

 And for the clocks that do not belong to any device, like most PRCM
 source
 clocks or DPLL inside OMAP, we can easily define a PRCM device or several
 CM
 (Clock Manager) devices that will handle all these clock nodes.

 The proposed OMAP4 way (I believe, correct me if I am wrong) is to
 create a new api outside the clock api that calls into both the clock
 api and the regulator api in the correct order for each operation,
 using OPP to determine the voltage.  This has a few disadvantages
 (obviously, I am biased, having written the Tegra code) - clocks and
 voltages are tied to a device, which is not always the case for
 platforms outside of OMAP, and drivers must know if their hardware
 requires voltage scaling.  The clock api becomes unsafe to use on any
 device that requires dvfs, as it could change the frequency higher
 than the supported voltage.

 You have to tie clock and voltage to a device. Most of the time a clock
 does
 not have any clear relation with a voltage domain. It can even cross
 power /
 voltage domain without any issue.
 The efficiency of the DVFS technique is mainly due to the reduction of
 the
 voltage rail that supply a device. In order to achieve that you have to
 reduce the clock rate of one or several clocks nodes that supply the
 critical path inside the HW.

 A clock crossing a voltage domain is not a problem, a single clock can
 have relationships to multiple regulators.  But a clock does not need
 to be tied to a device.  From the silicon perspective, it doesn't
 matter how you divide up the devices in the kernel, a clock is just a
 line toggling at a rate, and the maximum speed it can toggle is
 determined by the silicon it feeds and the voltage that silicon is
 operating at.  If a device can be turned on or off, that's a clock
 gate, and the line downstream from the clock gate is a separate clock.

 Fully agree.

 Just to clarify the terminology, I'm using device to represent the IP block
 as well.