summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorSumit Bhattacharya <sumitb@nvidia.com>2011-09-28 22:18:46 +0530
committerVarun Colbert <vcolbert@nvidia.com>2011-10-11 11:25:24 -0700
commit785b8f8fb2e07c1c14cee371dc1ce2a998599c63 (patch)
tree0ec131faa8480c34f998b55f4fe2f842fb2ac89e /sound
parent76e67f1a09ba6e068769adab67c974fcc4f32b09 (diff)
ASoC: Tegra: Modifiy I2s and AHUB clock management
Remove redundant ref counting for I2s and AHUB clocks. For Tegra30 enable AHUB clocks before I2s registers are accessed. Disable clocks when they are not in use. Bug 872652 Change-Id: I7ec4e45cecd0391d0b5a2765214d6c03fa5cc339 Signed-off-by: Sumit Bhattacharya <sumitb@nvidia.com> Reviewed-on: http://git-master/r/55005 Reviewed-by: Scott Peterson <speterson@nvidia.com> Reviewed-by: Stephen Warren <swarren@nvidia.com> Tested-by: Gerrit_Virtual_Submit
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/tegra/tegra20_i2s.c28
-rw-r--r--sound/soc/tegra/tegra20_i2s.h1
-rw-r--r--sound/soc/tegra/tegra30_ahub.c48
-rw-r--r--sound/soc/tegra/tegra30_ahub.h4
-rw-r--r--sound/soc/tegra/tegra30_i2s.c36
-rw-r--r--sound/soc/tegra/tegra30_i2s.h1
6 files changed, 49 insertions, 69 deletions
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index 38116a75d53e..6117ed02c46f 100644
--- a/sound/soc/tegra/tegra20_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -57,22 +57,6 @@ static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg)
return __raw_readl(i2s->regs + reg);
}
-static void tegra20_i2s_inc_clock_ref(struct tegra20_i2s *i2s)
-{
- i2s->clk_refs++;
- if (i2s->clk_refs == 1)
- clk_enable(i2s->clk_i2s);
-}
-
-static void tegra20_i2s_dec_clock_ref(struct tegra20_i2s *i2s)
-{
- BUG_ON(!i2s->clk_refs);
-
- i2s->clk_refs--;
- if (!i2s->clk_refs)
- clk_enable(i2s->clk_i2s);
-}
-
#ifdef CONFIG_DEBUG_FS
static int tegra20_i2s_show(struct seq_file *s, void *unused)
{
@@ -95,14 +79,14 @@ static int tegra20_i2s_show(struct seq_file *s, void *unused)
struct tegra20_i2s *i2s = s->private;
int i;
- tegra20_i2s_inc_clock_ref(i2s);
+ clk_enable(i2s->clk_i2s);
for (i = 0; i < ARRAY_SIZE(regs); i++) {
u32 val = tegra20_i2s_read(i2s, regs[i].offset);
seq_printf(s, "%s = %08x\n", regs[i].name, val);
}
- tegra20_i2s_dec_clock_ref(i2s);
+ clk_disable(i2s->clk_i2s);
return 0;
}
@@ -242,7 +226,7 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream,
if (i2sclock % (2 * srate))
reg |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE;
- tegra20_i2s_inc_clock_ref(i2s);
+ clk_enable(i2s->clk_i2s);
tegra20_i2s_write(i2s, TEGRA20_I2S_TIMING, reg);
@@ -250,7 +234,7 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream,
TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
- tegra20_i2s_dec_clock_ref(i2s);
+ clk_disable(i2s->clk_i2s);
return 0;
}
@@ -288,7 +272,7 @@ static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
case SNDRV_PCM_TRIGGER_RESUME:
- tegra20_i2s_inc_clock_ref(i2s);
+ clk_enable(i2s->clk_i2s);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
tegra20_i2s_start_playback(i2s);
else
@@ -301,7 +285,7 @@ static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
tegra20_i2s_stop_playback(i2s);
else
tegra20_i2s_stop_capture(i2s);
- tegra20_i2s_dec_clock_ref(i2s);
+ clk_disable(i2s->clk_i2s);
break;
default:
return -EINVAL;
diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h
index 08fcb4b2dc32..198c02345dbb 100644
--- a/sound/soc/tegra/tegra20_i2s.h
+++ b/sound/soc/tegra/tegra20_i2s.h
@@ -154,7 +154,6 @@
struct tegra20_i2s {
struct clk *clk_i2s;
- int clk_refs;
struct tegra_pcm_dma_params capture_dma_data;
struct tegra_pcm_dma_params playback_dma_data;
void __iomem *regs;
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index 78836091875d..10e95edb4cab 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -68,24 +68,16 @@ static inline u32 tegra30_audio_read(u32 reg)
* stopping streams should dynamically adjust the clock as required. However,
* this is not yet implemented.
*/
-static void tegra30_ahub_inc_clock_ref(void)
+void tegra30_ahub_enable_clocks(void)
{
- ahub->clk_refs++;
- if (ahub->clk_refs == 1) {
- clk_enable(ahub->clk_d_audio);
- clk_enable(ahub->clk_apbif);
- }
+ clk_enable(ahub->clk_d_audio);
+ clk_enable(ahub->clk_apbif);
}
-static void tegra30_ahub_dec_clock_ref(void)
+void tegra30_ahub_disable_clocks(void)
{
- BUG_ON(!ahub->clk_refs);
-
- ahub->clk_refs--;
- if (!ahub->clk_refs) {
- clk_enable(ahub->clk_apbif);
- clk_enable(ahub->clk_d_audio);
- }
+ clk_disable(ahub->clk_apbif);
+ clk_disable(ahub->clk_d_audio);
}
#ifdef CONFIG_DEBUG_FS
@@ -142,7 +134,7 @@ static int tegra30_ahub_show(struct seq_file *s, void *unused)
int i, j;
- tegra30_ahub_inc_clock_ref();
+ tegra30_ahub_enable_clocks();
for (i = 0; i < ARRAY_SIZE(regs); i++) {
if (regs[i].count > 1) {
@@ -159,7 +151,7 @@ static int tegra30_ahub_show(struct seq_file *s, void *unused)
}
}
- tegra30_ahub_dec_clock_ref();
+ tegra30_ahub_disable_clocks();
return 0;
}
@@ -217,7 +209,7 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
(channel * TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE);
*reqsel = TEGRA_DMA_REQ_SEL_APBIF_CH0 + channel;
- tegra30_ahub_inc_clock_ref();
+ tegra30_ahub_enable_clocks();
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
@@ -239,7 +231,7 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX;
tegra30_apbif_write(reg, val);
- tegra30_ahub_dec_clock_ref();
+ tegra30_ahub_disable_clocks();
return 0;
}
@@ -249,7 +241,7 @@ int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg, val;
- tegra30_ahub_inc_clock_ref();
+ tegra30_ahub_enable_clocks();
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
@@ -271,7 +263,7 @@ int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
tegra30_apbif_write(reg, val);
- tegra30_ahub_dec_clock_ref();
+ tegra30_ahub_disable_clocks();
return 0;
}
@@ -304,7 +296,7 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
(channel * TEGRA30_AHUB_CHANNEL_TXFIFO_STRIDE);
*reqsel = TEGRA_DMA_REQ_SEL_APBIF_CH0 + channel;
- tegra30_ahub_inc_clock_ref();
+ tegra30_ahub_enable_clocks();
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
@@ -326,7 +318,7 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX;
tegra30_apbif_write(reg, val);
- tegra30_ahub_dec_clock_ref();
+ tegra30_ahub_disable_clocks();
return 0;
}
@@ -336,7 +328,7 @@ int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif)
int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
int reg, val;
- tegra30_ahub_inc_clock_ref();
+ tegra30_ahub_enable_clocks();
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
@@ -358,7 +350,7 @@ int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif)
val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
tegra30_apbif_write(reg, val);
- tegra30_ahub_dec_clock_ref();
+ tegra30_ahub_disable_clocks();
return 0;
}
@@ -378,13 +370,13 @@ int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif,
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg;
- tegra30_ahub_inc_clock_ref();
+ tegra30_ahub_enable_clocks();
reg = TEGRA30_AHUB_AUDIO_RX +
(channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
tegra30_audio_write(reg, 1 << txcif);
- tegra30_ahub_dec_clock_ref();
+ tegra30_ahub_disable_clocks();
return 0;
}
@@ -394,13 +386,13 @@ int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif)
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg;
- tegra30_ahub_inc_clock_ref();
+ tegra30_ahub_enable_clocks();
reg = TEGRA30_AHUB_AUDIO_RX +
(channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
tegra30_audio_write(reg, 0);
- tegra30_ahub_dec_clock_ref();
+ tegra30_ahub_disable_clocks();
return 0;
}
diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h
index 76a6b101b468..cac80aa93e16 100644
--- a/sound/soc/tegra/tegra30_ahub.h
+++ b/sound/soc/tegra/tegra30_ahub.h
@@ -454,6 +454,9 @@ enum tegra30_ahub_rxcif {
TEGRA30_AHUB_RXCIF_SPDIF_RX1,
};
+extern void tegra30_ahub_enable_clocks(void);
+extern void tegra30_ahub_disable_clocks(void);
+
extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
unsigned long *fiforeg,
unsigned long *reqsel);
@@ -476,7 +479,6 @@ struct tegra30_ahub {
struct device *dev;
struct clk *clk_d_audio;
struct clk *clk_apbif;
- int clk_refs;
resource_size_t apbif_addr;
void __iomem *apbif_regs;
void __iomem *audio_regs;
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 7d6d9673acdb..ea1e310722ba 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -57,20 +57,16 @@ static inline u32 tegra30_i2s_read(struct tegra30_i2s *i2s, u32 reg)
return __raw_readl(i2s->regs + reg);
}
-static void tegra30_i2s_inc_clock_ref(struct tegra30_i2s *i2s)
+static void tegra30_i2s_enable_clocks(struct tegra30_i2s *i2s)
{
- i2s->clk_refs++;
- if (i2s->clk_refs == 1)
- clk_enable(i2s->clk_i2s);
+ tegra30_ahub_enable_clocks();
+ clk_enable(i2s->clk_i2s);
}
-static void tegra30_i2s_dec_clock_ref(struct tegra30_i2s *i2s)
+static void tegra30_i2s_disable_clocks(struct tegra30_i2s *i2s)
{
- BUG_ON(!i2s->clk_refs);
-
- i2s->clk_refs--;
- if (!i2s->clk_refs)
- clk_enable(i2s->clk_i2s);
+ clk_disable(i2s->clk_i2s);
+ tegra30_ahub_disable_clocks();
}
#ifdef CONFIG_DEBUG_FS
@@ -109,14 +105,14 @@ static int tegra30_i2s_show(struct seq_file *s, void *unused)
struct tegra30_i2s *i2s = s->private;
int i;
- tegra30_i2s_inc_clock_ref(i2s);
+ tegra30_i2s_enable_clocks(i2s);
for (i = 0; i < ARRAY_SIZE(regs); i++) {
u32 val = tegra30_i2s_read(i2s, regs[i].offset);
seq_printf(s, "%s = %08x\n", regs[i].name, val);
}
- tegra30_i2s_dec_clock_ref(i2s);
+ tegra30_i2s_disable_clocks(i2s);
return 0;
}
@@ -163,6 +159,8 @@ int tegra30_i2s_startup(struct snd_pcm_substream *substream,
struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
int ret;
+ tegra30_i2s_enable_clocks(i2s);
+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = tegra30_ahub_allocate_tx_fifo(&i2s->txcif,
&i2s->playback_dma_data.addr,
@@ -182,6 +180,8 @@ int tegra30_i2s_startup(struct snd_pcm_substream *substream,
TEGRA30_AHUB_TXCIF_I2S0_TX0 + i2s->id);
}
+ tegra30_i2s_disable_clocks(i2s);
+
return ret;
}
@@ -190,6 +190,8 @@ void tegra30_i2s_shutdown(struct snd_pcm_substream *substream,
{
struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+ tegra30_i2s_enable_clocks(i2s);
+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
tegra30_ahub_unset_rx_cif_source(
TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id);
@@ -198,6 +200,8 @@ void tegra30_i2s_shutdown(struct snd_pcm_substream *substream,
tegra30_ahub_unset_rx_cif_source(i2s->rxcif);
tegra30_ahub_free_rx_fifo(i2s->rxcif);
}
+
+ tegra30_i2s_disable_clocks(i2s);
}
static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
@@ -290,7 +294,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
return ret;
}
- tegra30_i2s_inc_clock_ref(i2s);
+ tegra30_i2s_enable_clocks(i2s);
val = bitcnt << TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
@@ -317,7 +321,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
(1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT);
tegra30_i2s_write(i2s, TEGRA30_I2S_OFFSET, val);
- tegra30_i2s_dec_clock_ref(i2s);
+ tegra30_i2s_disable_clocks(i2s);
return 0;
}
@@ -359,7 +363,7 @@ static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
case SNDRV_PCM_TRIGGER_RESUME:
- tegra30_i2s_inc_clock_ref(i2s);
+ tegra30_i2s_enable_clocks(i2s);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
tegra30_i2s_start_playback(i2s);
else
@@ -372,7 +376,7 @@ static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
tegra30_i2s_stop_playback(i2s);
else
tegra30_i2s_stop_capture(i2s);
- tegra30_i2s_dec_clock_ref(i2s);
+ tegra30_i2s_disable_clocks(i2s);
break;
default:
return -EINVAL;
diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h
index 6c5205f089d8..da3bedc55946 100644
--- a/sound/soc/tegra/tegra30_i2s.h
+++ b/sound/soc/tegra/tegra30_i2s.h
@@ -231,7 +231,6 @@
struct tegra30_i2s {
int id;
struct clk *clk_i2s;
- int clk_refs;
enum tegra30_ahub_rxcif rxcif;
struct tegra_pcm_dma_params capture_dma_data;
enum tegra30_ahub_txcif txcif;