2 * tegra30_ahub.c - Tegra30 AHUB driver
4 * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <linux/clk.h>
20 #include <linux/device.h>
22 #include <linux/module.h>
23 #include <linux/of_platform.h>
24 #include <linux/platform_device.h>
25 #include <linux/pm_runtime.h>
26 #include <linux/regmap.h>
27 #include <linux/slab.h>
28 #include <linux/clk/tegra.h>
29 #include <sound/soc.h>
30 #include "tegra30_ahub.h"
32 #define DRV_NAME "tegra30-ahub"
34 static struct tegra30_ahub *ahub;
36 static inline void tegra30_apbif_write(u32 reg, u32 val)
38 regmap_write(ahub->regmap_apbif, reg, val);
41 static inline u32 tegra30_apbif_read(u32 reg)
44 regmap_read(ahub->regmap_apbif, reg, &val);
48 static inline void tegra30_audio_write(u32 reg, u32 val)
50 regmap_write(ahub->regmap_ahub, reg, val);
53 static int tegra30_ahub_runtime_suspend(struct device *dev)
55 regcache_cache_only(ahub->regmap_apbif, true);
56 regcache_cache_only(ahub->regmap_ahub, true);
58 clk_disable_unprepare(ahub->clk_apbif);
59 clk_disable_unprepare(ahub->clk_d_audio);
65 * clk_apbif isn't required for an I2S<->I2S configuration where no PCM data
66 * is read from or sent to memory. However, that's not something the rest of
67 * the driver supports right now, so we'll just treat the two clocks as one
70 * These functions should not be a plain ref-count. Instead, each active stream
71 * contributes some requirement to the minimum clock rate, so starting or
72 * stopping streams should dynamically adjust the clock as required. However,
73 * this is not yet implemented.
75 static int tegra30_ahub_runtime_resume(struct device *dev)
79 ret = clk_prepare_enable(ahub->clk_d_audio);
81 dev_err(dev, "clk_enable d_audio failed: %d\n", ret);
84 ret = clk_prepare_enable(ahub->clk_apbif);
86 dev_err(dev, "clk_enable apbif failed: %d\n", ret);
87 clk_disable(ahub->clk_d_audio);
91 regcache_cache_only(ahub->regmap_apbif, false);
92 regcache_cache_only(ahub->regmap_ahub, false);
98 * for TDM mode, ahub has to run faster than I2S controller. This will avoid
99 * FIFO overflow/underflow, the causes of slot-hopping symptoms
101 void tegra30_ahub_clock_set_rate(int rate)
103 clk_set_rate(ahub->clk_d_audio, rate);
105 EXPORT_SYMBOL_GPL(tegra30_ahub_clock_set_rate);
107 void tegra30_ahub_enable_clocks(void)
109 pm_runtime_get_sync(ahub->dev);
111 EXPORT_SYMBOL_GPL(tegra30_ahub_enable_clocks);
113 void tegra30_ahub_disable_clocks(void)
115 pm_runtime_put(ahub->dev);
117 EXPORT_SYMBOL_GPL(tegra30_ahub_disable_clocks);
119 static int tegra30_ahub_soft_reset_rx_channel(int channel)
123 reg = TEGRA30_AHUB_CHANNEL_CLEAR +
124 (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE);
125 val = TEGRA30_AHUB_CHANNEL_CLEAR_RX_SOFT_RESET;
126 tegra30_apbif_write(reg, val);
130 static int tegra30_ahub_soft_reset_tx_channel(int channel)
134 reg = TEGRA30_AHUB_CHANNEL_CLEAR +
135 (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE);
136 val = TEGRA30_AHUB_CHANNEL_CLEAR_TX_SOFT_RESET;
137 tegra30_apbif_write(reg, val);
141 int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
142 unsigned long *fiforeg,
143 unsigned long *reqsel)
148 channel = find_first_zero_bit(ahub->rx_usage,
149 TEGRA30_AHUB_CHANNEL_CTRL_COUNT);
150 if (channel >= TEGRA30_AHUB_CHANNEL_CTRL_COUNT)
153 __set_bit(channel, ahub->rx_usage);
155 *rxcif = TEGRA30_AHUB_RXCIF_APBIF_RX0 + channel;
156 *fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_RXFIFO +
157 (channel * TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE);
158 *reqsel = ahub->dma_sel + channel;
160 tegra30_ahub_soft_reset_rx_channel(channel);
162 reg = TEGRA30_AHUB_CHANNEL_CTRL +
163 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
164 val = tegra30_apbif_read(reg);
165 val &= ~(TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_MASK |
166 TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_MASK);
167 val |= (7 << TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_SHIFT) |
168 TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_EN |
169 TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_16;
170 tegra30_apbif_write(reg, val);
172 reg = TEGRA30_AHUB_CIF_RX_CTRL +
173 (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE);
174 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) |
175 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
176 (1 << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) |
177 TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_16 |
178 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_16 |
179 TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX;
180 tegra30_apbif_write(reg, val);
184 EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_rx_fifo);
186 int tegra30_ahub_rx_fifo_is_enabled(int i2s_id)
190 val = tegra30_apbif_read(TEGRA30_AHUB_I2S_LIVE_STATUS);
191 mask = (TEGRA30_AHUB_I2S_LIVE_STATUS_I2S0_RX_FIFO_ENABLED << (i2s_id*2));
195 EXPORT_SYMBOL_GPL(tegra30_ahub_rx_fifo_is_enabled);
197 int tegra30_ahub_tx_fifo_is_enabled(int i2s_id)
201 val = tegra30_apbif_read(TEGRA30_AHUB_I2S_LIVE_STATUS);
202 mask = (TEGRA30_AHUB_I2S_LIVE_STATUS_I2S0_TX_FIFO_ENABLED << (i2s_id*2));
207 EXPORT_SYMBOL_GPL(tegra30_ahub_tx_fifo_is_enabled);
210 int tegra30_ahub_rx_fifo_is_empty(int i2s_id)
214 val = tegra30_apbif_read(TEGRA30_AHUB_I2S_LIVE_STATUS);
215 mask = (TEGRA30_AHUB_I2S_LIVE_STATUS_I2S0_RX_FIFO_EMPTY << (i2s_id*2));
220 int tegra30_ahub_tx_fifo_is_empty(int i2s_id)
224 val = tegra30_apbif_read(TEGRA30_AHUB_I2S_LIVE_STATUS);
225 mask = (TEGRA30_AHUB_I2S_LIVE_STATUS_I2S0_TX_FIFO_EMPTY << (i2s_id*2));
232 int tegra30_ahub_dam_ch0_is_enabled(int dam_id)
236 val = tegra30_apbif_read((TEGRA30_AHUB_DAM_LIVE_STATUS) +
237 (dam_id * TEGRA30_AHUB_DAM_LIVE_STATUS_STRIDE));
238 mask = TEGRA30_AHUB_DAM_LIVE_STATUS_RX0_ENABLED;
243 EXPORT_SYMBOL_GPL(tegra30_ahub_dam_ch0_is_enabled);
245 int tegra30_ahub_dam_ch1_is_enabled(int dam_id)
249 val = tegra30_apbif_read((TEGRA30_AHUB_DAM_LIVE_STATUS) +
250 (dam_id * TEGRA30_AHUB_DAM_LIVE_STATUS_STRIDE));
251 mask = TEGRA30_AHUB_DAM_LIVE_STATUS_RX1_ENABLED;
256 EXPORT_SYMBOL_GPL(tegra30_ahub_dam_ch1_is_enabled);
258 int tegra30_ahub_dam_tx_is_enabled(int dam_id)
262 val = tegra30_apbif_read((TEGRA30_AHUB_DAM_LIVE_STATUS) +
263 (dam_id * TEGRA30_AHUB_DAM_LIVE_STATUS_STRIDE));
264 mask = TEGRA30_AHUB_DAM_LIVE_STATUS_TX_ENABLED;
269 EXPORT_SYMBOL_GPL(tegra30_ahub_dam_tx_is_enabled);
272 int tegra30_ahub_dam_ch0_is_empty(int dam_id)
276 val = tegra30_apbif_read((TEGRA30_AHUB_DAM_LIVE_STATUS) +
277 (dam_id * TEGRA30_AHUB_DAM_LIVE_STATUS_STRIDE));
278 mask = TEGRA30_AHUB_DAM_LIVE_STATUS_RX0FIFO_EMPTY;
284 int tegra30_ahub_dam_ch1_is_empty(int dam_id)
288 val = tegra30_apbif_read((TEGRA30_AHUB_DAM_LIVE_STATUS) +
289 (dam_id * TEGRA30_AHUB_DAM_LIVE_STATUS_STRIDE));
290 mask = TEGRA30_AHUB_DAM_LIVE_STATUS_RX1FIFO_EMPTY;
296 int tegra30_ahub_dam_tx_is_empty(int dam_id)
300 val = tegra30_apbif_read((TEGRA30_AHUB_DAM_LIVE_STATUS) +
301 (dam_id * TEGRA30_AHUB_DAM_LIVE_STATUS_STRIDE));
302 mask = TEGRA30_AHUB_DAM_LIVE_STATUS_TXFIFO_EMPTY;
309 int tegra30_ahub_set_rx_fifo_pack_mode(enum tegra30_ahub_rxcif rxcif,
310 unsigned int pack_mode)
312 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
315 reg = TEGRA30_AHUB_CHANNEL_CTRL +
316 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
317 val = tegra30_apbif_read(reg);
319 val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_MASK;
320 val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_EN;
322 if ((pack_mode == TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_16) ||
323 (pack_mode == TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_8_4))
324 val |= (TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_EN |
326 tegra30_apbif_write(reg, val);
330 EXPORT_SYMBOL_GPL(tegra30_ahub_set_rx_fifo_pack_mode);
332 int tegra30_ahub_set_tx_fifo_pack_mode(enum tegra30_ahub_txcif txcif,
333 unsigned int pack_mode)
335 int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
338 reg = TEGRA30_AHUB_CHANNEL_CTRL +
339 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
340 val = tegra30_apbif_read(reg);
342 val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_MASK;
343 val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_EN;
345 if ((pack_mode == TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_16) ||
346 (pack_mode == TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_8_4))
347 val |= (TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_EN |
349 tegra30_apbif_write(reg, val);
353 EXPORT_SYMBOL_GPL(tegra30_ahub_set_tx_fifo_pack_mode);
355 int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
357 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
360 reg = TEGRA30_AHUB_CHANNEL_CTRL +
361 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
362 val = tegra30_apbif_read(reg);
363 val |= TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
364 tegra30_apbif_write(reg, val);
368 EXPORT_SYMBOL_GPL(tegra30_ahub_enable_rx_fifo);
370 int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
372 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
375 reg = TEGRA30_AHUB_CHANNEL_CTRL +
376 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
377 val = tegra30_apbif_read(reg);
378 val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
379 tegra30_apbif_write(reg, val);
383 EXPORT_SYMBOL_GPL(tegra30_ahub_disable_rx_fifo);
385 int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif)
387 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
389 __clear_bit(channel, ahub->rx_usage);
393 EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo);
395 int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
396 unsigned long *fiforeg,
397 unsigned long *reqsel)
402 channel = find_first_zero_bit(ahub->tx_usage,
403 TEGRA30_AHUB_CHANNEL_CTRL_COUNT);
404 if (channel >= TEGRA30_AHUB_CHANNEL_CTRL_COUNT)
407 __set_bit(channel, ahub->tx_usage);
409 *txcif = TEGRA30_AHUB_TXCIF_APBIF_TX0 + channel;
410 *fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_TXFIFO +
411 (channel * TEGRA30_AHUB_CHANNEL_TXFIFO_STRIDE);
412 *reqsel = ahub->dma_sel + channel;
414 tegra30_ahub_soft_reset_tx_channel(channel);
416 reg = TEGRA30_AHUB_CHANNEL_CTRL +
417 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
418 val = tegra30_apbif_read(reg);
419 val &= ~(TEGRA30_AHUB_CHANNEL_CTRL_TX_THRESHOLD_MASK |
420 TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_MASK);
421 val |= (7 << TEGRA30_AHUB_CHANNEL_CTRL_TX_THRESHOLD_SHIFT) |
422 TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_EN |
423 TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_16;
424 tegra30_apbif_write(reg, val);
426 reg = TEGRA30_AHUB_CIF_TX_CTRL +
427 (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE);
428 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) |
429 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
430 (1 << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) |
431 TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_16 |
432 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_16 |
433 TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX;
434 tegra30_apbif_write(reg, val);
438 EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_tx_fifo);
440 int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif)
442 int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
445 reg = TEGRA30_AHUB_CHANNEL_CTRL +
446 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
447 val = tegra30_apbif_read(reg);
448 val |= TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
449 tegra30_apbif_write(reg, val);
453 EXPORT_SYMBOL_GPL(tegra30_ahub_enable_tx_fifo);
455 int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif)
457 int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
460 reg = TEGRA30_AHUB_CHANNEL_CTRL +
461 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
462 val = tegra30_apbif_read(reg);
463 val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
464 tegra30_apbif_write(reg, val);
468 EXPORT_SYMBOL_GPL(tegra30_ahub_disable_tx_fifo);
470 int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif)
472 int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
474 __clear_bit(channel, ahub->tx_usage);
478 EXPORT_SYMBOL_GPL(tegra30_ahub_free_tx_fifo);
480 int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif,
481 enum tegra30_ahub_txcif txcif)
483 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
486 reg = TEGRA30_AHUB_AUDIO_RX +
487 (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
488 tegra30_audio_write(reg, 1 << txcif);
492 EXPORT_SYMBOL_GPL(tegra30_ahub_set_rx_cif_source);
494 int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif)
496 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
499 reg = TEGRA30_AHUB_AUDIO_RX +
500 (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
501 tegra30_audio_write(reg, 0);
505 EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source);
507 int tegra30_ahub_set_rx_cif_channels(enum tegra30_ahub_rxcif rxcif,
508 unsigned int audio_ch,
509 unsigned int client_ch)
511 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
512 unsigned int reg, val;
514 reg = TEGRA30_AHUB_CIF_RX_CTRL +
515 (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE);
516 val = tegra30_apbif_read(reg);
517 val &= ~(TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK |
518 TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK);
519 val |= ((audio_ch - 1) << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
520 ((client_ch - 1) << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT);
521 tegra30_apbif_write(reg, val);
525 EXPORT_SYMBOL_GPL(tegra30_ahub_set_rx_cif_channels);
527 int tegra30_ahub_set_rx_cif_stereo_conv(enum tegra30_ahub_rxcif rxcif)
529 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
530 unsigned int reg, val;
532 tegra30_ahub_enable_clocks();
534 reg = TEGRA30_AHUB_CIF_RX_CTRL +
535 (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE);
536 val = tegra30_apbif_read(reg);
537 val &= ~TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_MASK;
538 val |= TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_AVG;
539 tegra30_apbif_write(reg, val);
541 tegra30_ahub_disable_clocks();
546 int tegra30_ahub_set_tx_cif_channels(enum tegra30_ahub_txcif txcif,
547 unsigned int audio_ch,
548 unsigned int client_ch)
550 int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
551 unsigned int reg, val;
553 reg = TEGRA30_AHUB_CIF_TX_CTRL +
554 (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE);
555 val = tegra30_apbif_read(reg);
556 val &= ~(TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK |
557 TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK);
558 val |= ((audio_ch - 1) << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
559 ((client_ch - 1) << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT);
561 tegra30_apbif_write(reg, val);
565 EXPORT_SYMBOL_GPL(tegra30_ahub_set_tx_cif_channels);
567 int tegra30_ahub_set_rx_cif_bits(enum tegra30_ahub_rxcif rxcif,
568 unsigned int audio_bits,
569 unsigned int client_bits)
571 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
572 unsigned int reg, val;
574 reg = TEGRA30_AHUB_CIF_RX_CTRL +
575 (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE);
576 val = tegra30_apbif_read(reg);
577 val &= ~(TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_MASK |
578 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_MASK);
579 val |= ((audio_bits) << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) |
580 ((client_bits) << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT);
581 tegra30_apbif_write(reg, val);
585 EXPORT_SYMBOL_GPL(tegra30_ahub_set_rx_cif_bits);
587 int tegra30_ahub_set_tx_cif_bits(enum tegra30_ahub_txcif txcif,
588 unsigned int audio_bits,
589 unsigned int client_bits)
591 int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
592 unsigned int reg, val;
594 reg = TEGRA30_AHUB_CIF_TX_CTRL +
595 (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE);
596 val = tegra30_apbif_read(reg);
597 val &= ~(TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_MASK |
598 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_MASK);
599 val |= ((audio_bits) << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) |
600 ((client_bits) << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT);
602 tegra30_apbif_write(reg, val);
606 EXPORT_SYMBOL_GPL(tegra30_ahub_set_tx_cif_bits);
608 static const char * const configlink_clocks[] = {
618 #ifndef CONFIG_ARCH_TEGRA_14x_SOC
621 #if defined(CONFIG_ARCH_TEGRA_11x_SOC) || defined(CONFIG_ARCH_TEGRA_12x_SOC)
625 #ifdef CONFIG_ARCH_TEGRA_12x_SOC
637 struct of_dev_auxdata ahub_auxdata[] = {
638 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080300, "tegra30-i2s.0", NULL),
639 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080400, "tegra30-i2s.1", NULL),
640 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080500, "tegra30-i2s.2", NULL),
641 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080600, "tegra30-i2s.3", NULL),
642 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080700, "tegra30-i2s.4", NULL),
643 OF_DEV_AUXDATA("nvidia,tegra30-dam", 0x70080800, "tegra30-dam.0", NULL),
644 OF_DEV_AUXDATA("nvidia,tegra30-dam", 0x70080900, "tegra30-dam.1", NULL),
645 OF_DEV_AUXDATA("nvidia,tegra30-dam", 0x70080A00, "tegra30-dam.2", NULL),
646 OF_DEV_AUXDATA("nvidia,tegra30-spdif", 0x70080B00, "tegra30-spdif",
651 #define LAST_REG(name) \
652 (TEGRA30_AHUB_##name + \
653 (TEGRA30_AHUB_##name##_STRIDE * TEGRA30_AHUB_##name##_COUNT) - 4)
655 #define REG_IN_ARRAY(reg, name) \
656 ((reg >= TEGRA30_AHUB_##name) && \
657 (reg <= LAST_REG(name) && \
658 (!((reg - TEGRA30_AHUB_##name) % TEGRA30_AHUB_##name##_STRIDE))))
660 static bool tegra30_ahub_apbif_wr_rd_reg(struct device *dev, unsigned int reg)
663 case TEGRA30_AHUB_CONFIG_LINK_CTRL:
664 case TEGRA30_AHUB_MISC_CTRL:
665 case TEGRA30_AHUB_APBDMA_LIVE_STATUS:
666 case TEGRA30_AHUB_I2S_LIVE_STATUS:
667 case TEGRA30_AHUB_SPDIF_LIVE_STATUS:
668 case TEGRA30_AHUB_I2S_INT_MASK:
669 case TEGRA30_AHUB_DAM_INT_MASK:
670 case TEGRA30_AHUB_SPDIF_INT_MASK:
671 case TEGRA30_AHUB_APBIF_INT_MASK:
672 case TEGRA30_AHUB_I2S_INT_STATUS:
673 case TEGRA30_AHUB_DAM_INT_STATUS:
674 case TEGRA30_AHUB_SPDIF_INT_STATUS:
675 case TEGRA30_AHUB_APBIF_INT_STATUS:
676 case TEGRA30_AHUB_I2S_INT_SOURCE:
677 case TEGRA30_AHUB_DAM_INT_SOURCE:
678 case TEGRA30_AHUB_SPDIF_INT_SOURCE:
679 case TEGRA30_AHUB_APBIF_INT_SOURCE:
680 case TEGRA30_AHUB_I2S_INT_SET:
681 case TEGRA30_AHUB_DAM_INT_SET:
682 case TEGRA30_AHUB_SPDIF_INT_SET:
683 case TEGRA30_AHUB_APBIF_INT_SET:
689 if (REG_IN_ARRAY(reg, CHANNEL_CTRL) ||
690 REG_IN_ARRAY(reg, CHANNEL_CLEAR) ||
691 REG_IN_ARRAY(reg, CHANNEL_STATUS) ||
692 REG_IN_ARRAY(reg, CHANNEL_TXFIFO) ||
693 REG_IN_ARRAY(reg, CHANNEL_RXFIFO) ||
694 REG_IN_ARRAY(reg, CIF_TX_CTRL) ||
695 REG_IN_ARRAY(reg, CIF_RX_CTRL) ||
696 REG_IN_ARRAY(reg, DAM_LIVE_STATUS))
702 static bool tegra30_ahub_apbif_volatile_reg(struct device *dev,
706 case TEGRA30_AHUB_CONFIG_LINK_CTRL:
707 case TEGRA30_AHUB_MISC_CTRL:
708 case TEGRA30_AHUB_APBDMA_LIVE_STATUS:
709 case TEGRA30_AHUB_I2S_LIVE_STATUS:
710 case TEGRA30_AHUB_SPDIF_LIVE_STATUS:
711 case TEGRA30_AHUB_I2S_INT_STATUS:
712 case TEGRA30_AHUB_DAM_INT_STATUS:
713 case TEGRA30_AHUB_SPDIF_INT_STATUS:
714 case TEGRA30_AHUB_APBIF_INT_STATUS:
715 case TEGRA30_AHUB_I2S_INT_SET:
716 case TEGRA30_AHUB_DAM_INT_SET:
717 case TEGRA30_AHUB_SPDIF_INT_SET:
718 case TEGRA30_AHUB_APBIF_INT_SET:
724 if (REG_IN_ARRAY(reg, CHANNEL_CLEAR) ||
725 REG_IN_ARRAY(reg, CHANNEL_STATUS) ||
726 REG_IN_ARRAY(reg, CHANNEL_TXFIFO) ||
727 REG_IN_ARRAY(reg, CHANNEL_RXFIFO) ||
728 REG_IN_ARRAY(reg, DAM_LIVE_STATUS))
734 static bool tegra30_ahub_apbif_precious_reg(struct device *dev,
737 if (REG_IN_ARRAY(reg, CHANNEL_TXFIFO) ||
738 REG_IN_ARRAY(reg, CHANNEL_RXFIFO))
744 static const struct regmap_config tegra30_ahub_apbif_regmap_config = {
749 .max_register = TEGRA30_AHUB_APBIF_INT_SET,
750 .writeable_reg = tegra30_ahub_apbif_wr_rd_reg,
751 .readable_reg = tegra30_ahub_apbif_wr_rd_reg,
752 .volatile_reg = tegra30_ahub_apbif_volatile_reg,
753 .precious_reg = tegra30_ahub_apbif_precious_reg,
754 .cache_type = REGCACHE_RBTREE,
757 static bool tegra30_ahub_ahub_wr_rd_reg(struct device *dev, unsigned int reg)
759 if (REG_IN_ARRAY(reg, AUDIO_RX))
765 static const struct regmap_config tegra30_ahub_ahub_regmap_config = {
770 .max_register = LAST_REG(AUDIO_RX),
771 .writeable_reg = tegra30_ahub_ahub_wr_rd_reg,
772 .readable_reg = tegra30_ahub_ahub_wr_rd_reg,
773 .cache_type = REGCACHE_RBTREE,
776 static int tegra30_ahub_probe(struct platform_device *pdev)
780 struct resource *res0, *res1, *region;
782 void __iomem *regs_apbif, *regs_ahub;
790 * The AHUB hosts a register bus: the "configlink". For this to
791 * operate correctly, all devices on this bus must be out of reset.
794 for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) {
795 clk = clk_get_sys(NULL, configlink_clocks[i]);
797 dev_err(&pdev->dev, "Can't get clock %s\n",
798 configlink_clocks[i]);
802 tegra_periph_reset_deassert(clk);
806 ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub),
809 dev_err(&pdev->dev, "Can't allocate tegra30_ahub\n");
813 dev_set_drvdata(&pdev->dev, ahub);
815 ahub->dev = &pdev->dev;
817 ahub->clk_d_audio = clk_get(&pdev->dev, "d_audio");
818 if (IS_ERR(ahub->clk_d_audio)) {
819 dev_err(&pdev->dev, "Can't retrieve ahub d_audio clock\n");
820 ret = PTR_ERR(ahub->clk_d_audio);
823 clkm_rate = clk_get_rate(clk_get_parent(ahub->clk_d_audio));
825 while (clkm_rate > 13000000)
828 clk_set_rate(ahub->clk_d_audio,clkm_rate);
830 ahub->clk_apbif = clk_get(&pdev->dev, "apbif");
831 if (IS_ERR(ahub->clk_apbif)) {
832 dev_err(&pdev->dev, "Can't retrieve ahub apbif clock\n");
833 ret = PTR_ERR(ahub->clk_apbif);
834 goto err_clk_put_d_audio;
837 if (!(pdev->dev.of_node))
840 if (of_property_read_u32_array(pdev->dev.of_node,
841 "nvidia,dma-request-selector",
844 "Missing property nvidia,dma-request-selector\n");
846 goto err_clk_put_d_audio;
848 ahub->dma_sel = of_dma[1];
851 res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
853 dev_err(&pdev->dev, "No apbif memory resource\n");
855 goto err_clk_put_apbif;
858 region = devm_request_mem_region(&pdev->dev, res0->start,
859 resource_size(res0), DRV_NAME);
861 dev_err(&pdev->dev, "request region apbif failed\n");
863 goto err_clk_put_apbif;
865 ahub->apbif_addr = res0->start;
867 regs_apbif = devm_ioremap(&pdev->dev, res0->start,
868 resource_size(res0));
870 dev_err(&pdev->dev, "ioremap apbif failed\n");
872 goto err_clk_put_apbif;
875 ahub->regmap_apbif = devm_regmap_init_mmio(&pdev->dev, regs_apbif,
876 &tegra30_ahub_apbif_regmap_config);
877 if (IS_ERR(ahub->regmap_apbif)) {
878 dev_err(&pdev->dev, "apbif regmap init failed\n");
879 ret = PTR_ERR(ahub->regmap_apbif);
880 goto err_clk_put_apbif;
882 regcache_cache_only(ahub->regmap_apbif, true);
884 res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
886 dev_err(&pdev->dev, "No ahub memory resource\n");
888 goto err_clk_put_apbif;
891 region = devm_request_mem_region(&pdev->dev, res1->start,
892 resource_size(res1), DRV_NAME);
894 dev_err(&pdev->dev, "request region ahub failed\n");
896 goto err_clk_put_apbif;
899 regs_ahub = devm_ioremap(&pdev->dev, res1->start,
900 resource_size(res1));
902 dev_err(&pdev->dev, "ioremap ahub failed\n");
904 goto err_clk_put_apbif;
907 ahub->regmap_ahub = devm_regmap_init_mmio(&pdev->dev, regs_ahub,
908 &tegra30_ahub_ahub_regmap_config);
909 if (IS_ERR(ahub->regmap_ahub)) {
910 dev_err(&pdev->dev, "ahub regmap init failed\n");
911 ret = PTR_ERR(ahub->regmap_ahub);
912 goto err_clk_put_apbif;
914 regcache_cache_only(ahub->regmap_ahub, true);
916 pm_runtime_enable(&pdev->dev);
917 if (!pm_runtime_enabled(&pdev->dev)) {
918 ret = tegra30_ahub_runtime_resume(&pdev->dev);
923 if (pdev->dev.of_node)
924 of_platform_populate(pdev->dev.of_node, NULL, ahub_auxdata,
930 pm_runtime_disable(&pdev->dev);
932 clk_put(ahub->clk_apbif);
934 clk_put(ahub->clk_d_audio);
940 static int tegra30_ahub_remove(struct platform_device *pdev)
945 pm_runtime_disable(&pdev->dev);
946 if (!pm_runtime_status_suspended(&pdev->dev))
947 tegra30_ahub_runtime_suspend(&pdev->dev);
949 clk_put(ahub->clk_apbif);
950 clk_put(ahub->clk_d_audio);
957 static const struct of_device_id tegra30_ahub_of_match[] = {
958 { .compatible = "nvidia,tegra30-ahub", },
962 static const struct dev_pm_ops tegra30_ahub_pm_ops = {
963 SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend,
964 tegra30_ahub_runtime_resume, NULL)
967 static struct platform_driver tegra30_ahub_driver = {
968 .probe = tegra30_ahub_probe,
969 .remove = tegra30_ahub_remove,
972 .owner = THIS_MODULE,
973 .of_match_table = tegra30_ahub_of_match,
974 .pm = &tegra30_ahub_pm_ops,
977 module_platform_driver(tegra30_ahub_driver);
979 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
980 MODULE_DESCRIPTION("Tegra30 AHUB driver");
981 MODULE_LICENSE("GPL v2");
982 MODULE_ALIAS("platform:" DRV_NAME);
983 MODULE_DEVICE_TABLE(of, tegra30_ahub_of_match);