diff options
-rw-r--r-- | drivers/mfd/mxc-hdmi-core.c | 29 | ||||
-rw-r--r-- | include/linux/mfd/mxc-hdmi-core.h | 1 | ||||
-rw-r--r-- | sound/soc/imx/imx-hdmi-dma.c | 35 |
3 files changed, 51 insertions, 14 deletions
diff --git a/drivers/mfd/mxc-hdmi-core.c b/drivers/mfd/mxc-hdmi-core.c index 18fd1a67ba83..92fdf710a5b1 100644 --- a/drivers/mfd/mxc-hdmi-core.c +++ b/drivers/mfd/mxc-hdmi-core.c @@ -64,6 +64,7 @@ int mxc_hdmi_ipu_id; int mxc_hdmi_disp_id; static struct mxc_edid_cfg hdmi_core_edid_cfg; static int hdmi_core_init; +static unsigned int hdmi_dma_running; u8 hdmi_readb(unsigned int reg) { @@ -243,6 +244,12 @@ static void hdmi_set_clock_regenerator_n(unsigned int value) { u8 val; + if (!hdmi_dma_running) { + hdmi_writeb(value & 0xff, HDMI_AUD_N1); + hdmi_writeb(0, HDMI_AUD_N2); + hdmi_writeb(0, HDMI_AUD_N3); + } + hdmi_writeb(value & 0xff, HDMI_AUD_N1); hdmi_writeb((value >> 8) & 0xff, HDMI_AUD_N2); hdmi_writeb((value >> 16) & 0x0f, HDMI_AUD_N3); @@ -257,6 +264,12 @@ static void hdmi_set_clock_regenerator_cts(unsigned int cts) { u8 val; + if (!hdmi_dma_running) { + hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1); + hdmi_writeb(0, HDMI_AUD_CTS2); + hdmi_writeb(0, HDMI_AUD_CTS3); + } + /* Must be set/cleared first */ val = hdmi_readb(HDMI_AUD_CTS3); val &= ~HDMI_AUD_CTS3_CTS_MANUAL; @@ -433,18 +446,12 @@ static void hdmi_set_clk_regenerator(void) return; } - clk_enable(isfr_clk); - clk_enable(iahb_clk); - pr_debug("%s: samplerate=%d ratio=%d pixelclk=%d N=%d cts=%d\n", __func__, sample_rate, hdmi_ratio, (int)pixel_clk_rate, clk_n, clk_cts); - hdmi_set_clock_regenerator_n(clk_n); hdmi_set_clock_regenerator_cts(clk_cts); - - clk_disable(iahb_clk); - clk_disable(isfr_clk); + hdmi_set_clock_regenerator_n(clk_n); } /* Need to run this before phy is enabled the first time to prevent @@ -464,10 +471,15 @@ void hdmi_clk_regenerator_update_pixel_clock(void) hdmi_set_clk_regenerator(); } +void hdmi_set_dma_mode(unsigned int dma_running) +{ + hdmi_dma_running = dma_running; + hdmi_set_clk_regenerator(); +} + void hdmi_set_sample_rate(unsigned int rate) { sample_rate = rate; - hdmi_set_clk_regenerator(); } void hdmi_set_edid_cfg(struct mxc_edid_cfg *cfg) @@ -511,6 +523,7 @@ static int mxc_hdmi_core_probe(struct platform_device *pdev) #endif hdmi_core_init = 0; + hdmi_dma_running = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) diff --git a/include/linux/mfd/mxc-hdmi-core.h b/include/linux/mfd/mxc-hdmi-core.h index 0b241838f1b9..8681053d231f 100644 --- a/include/linux/mfd/mxc-hdmi-core.h +++ b/include/linux/mfd/mxc-hdmi-core.h @@ -37,6 +37,7 @@ void hdmi_irq_enable(int irq); unsigned int hdmi_irq_disable(int irq); void hdmi_set_sample_rate(unsigned int rate); +void hdmi_set_dma_mode(unsigned int dma_running); void hdmi_init_clk_regenerator(void); void hdmi_clk_regenerator_update_pixel_clock(void); diff --git a/sound/soc/imx/imx-hdmi-dma.c b/sound/soc/imx/imx-hdmi-dma.c index c8e88ff79e3b..1bd36ca1ea57 100644 --- a/sound/soc/imx/imx-hdmi-dma.c +++ b/sound/soc/imx/imx-hdmi-dma.c @@ -35,6 +35,11 @@ #include <mach/mxc_hdmi.h> #include "imx-hdmi.h" +#define HDMI_DMA_BURST_UNSPECIFIED_LEGNTH 0 +#define HDMI_DMA_BURST_INCR4 1 +#define HDMI_DMA_BURST_INCR8 2 +#define HDMI_DMA_BURST_INCR16 3 + struct imx_hdmi_dma_runtime_data { struct snd_pcm_substream *tx_substream; @@ -315,16 +320,16 @@ static void hdmi_dma_set_incr_type(int incr_type) HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK); switch (incr_type) { - case 1: + case HDMI_DMA_BURST_UNSPECIFIED_LEGNTH: break; - case 4: + case HDMI_DMA_BURST_INCR4: value |= HDMI_AHB_DMA_CONF0_BURST_MODE; break; - case 8: + case HDMI_DMA_BURST_INCR8: value |= HDMI_AHB_DMA_CONF0_BURST_MODE | HDMI_AHB_DMA_CONF0_INCR8; break; - case 16: + case HDMI_DMA_BURST_INCR16: value |= HDMI_AHB_DMA_CONF0_BURST_MODE | HDMI_AHB_DMA_CONF0_INCR16; break; @@ -359,11 +364,27 @@ static void hdmi_dma_enable_channels(int channels) } } +static void hdmi_dma_set_thrsld(void) +{ + int rev = hdmi_readb(HDMI_REVISION_ID); + + switch (rev) { + case 0x0a: + hdmi_writeb(126, HDMI_AHB_DMA_THRSLD); + break; + default: + hdmi_writeb(64, HDMI_AHB_DMA_THRSLD); + break; + } + + pr_debug("HDMI_AHB_DMA_THRSLD 0x%02x\n", hdmi_readb(HDMI_AHB_DMA_THRSLD)); +} + static void hdmi_dma_configure_dma(int channels) { hdmi_dma_enable_hlock(1); - hdmi_dma_set_incr_type(4); - hdmi_writeb(64, HDMI_AHB_DMA_THRSLD); + hdmi_dma_set_incr_type(HDMI_DMA_BURST_UNSPECIFIED_LEGNTH); + hdmi_dma_set_thrsld(); hdmi_dma_enable_channels(channels); } @@ -548,6 +569,7 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd) hdmi_dma_irq_mask(0); hdmi_dma_priv->tx_active = true; hdmi_dma_start(); + hdmi_set_dma_mode(1); break; case SNDRV_PCM_TRIGGER_STOP: @@ -555,6 +577,7 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_PUSH: hdmi_dma_priv->tx_active = false; hdmi_dma_stop(); + hdmi_set_dma_mode(0); hdmi_dma_irq_mask(1); break; |