From: Sandor Yu Date: Thu, 17 May 2012 07:28:54 +0000 (+0800) Subject: ENGR00182769 HDMI: No sound when playing audio in 480p mode X-Git-Tag: v3.0.35-fsl_4.1.0~1178 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=91c5a150be5f0735ece4e38d795f32f99cea5bc1;p=karo-tx-linux.git ENGR00182769 HDMI: No sound when playing audio in 480p mode It is cause by HDMI audio driver can't get right pixel clock from IPU driver if pixel clock source from HSP clock not from DI clock. HDMI driver get pixel clock by call clk_get_rate() function, but the function return actually clock, in some videomode the actually pixel clock is not right equal the pixel clock in CEA spec. Get pixel clock from video mode struct instead of CCM register. 480P HDMI audio can work. Signed-off-by: Sandor Yu --- diff --git a/drivers/mfd/mxc-hdmi-core.c b/drivers/mfd/mxc-hdmi-core.c index 7ca594351e2e..896f53b4f6e8 100644 --- a/drivers/mfd/mxc-hdmi-core.c +++ b/drivers/mfd/mxc-hdmi-core.c @@ -72,7 +72,7 @@ u8 hdmi_readb(unsigned int reg) value = __raw_readb(hdmi_base + reg); - pr_debug("hdmi rd: 0x%04x = 0x%02x\n", reg, value); +/* pr_debug("hdmi rd: 0x%04x = 0x%02x\n", reg, value);*/ return value; } @@ -108,7 +108,7 @@ bool hdmi_check_overflow(void) void hdmi_writeb(u8 value, unsigned int reg) { hdmi_check_overflow(); - pr_debug("hdmi wr: 0x%04x = 0x%02x\n", reg, value); +/* pr_debug("hdmi wr: 0x%04x = 0x%02x\n", reg, value);*/ __raw_writeb(value, hdmi_base + reg); hdmi_check_overflow(); } @@ -288,29 +288,33 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk, switch (freq) { case 32000: - if (pixel_clk == 25170000) + if (pixel_clk == 25174000) n = (ratio == 150) ? 9152 : 4576; else if (pixel_clk == 27020000) n = (ratio == 150) ? 8192 : 4096; else if (pixel_clk == 74170000 || pixel_clk == 148350000) n = 11648; + else if (pixel_clk == 297000000) + n = (ratio == 150) ? 6144 : 3072; else n = 4096; break; case 44100: - if (pixel_clk == 25170000) + if (pixel_clk == 25174000) n = 7007; else if (pixel_clk == 74170000) n = 17836; else if (pixel_clk == 148350000) n = (ratio == 150) ? 17836 : 8918; + else if (pixel_clk == 297000000) + n = (ratio == 150) ? 9408 : 4704; else n = 6272; break; case 48000: - if (pixel_clk == 25170000) + if (pixel_clk == 25174000) n = (ratio == 150) ? 9152 : 6864; else if (pixel_clk == 27020000) n = (ratio == 150) ? 8192 : 6144; @@ -318,6 +322,8 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk, n = 11648; else if (pixel_clk == 148350000) n = (ratio == 150) ? 11648 : 5824; + else if (pixel_clk == 297000000) + n = (ratio == 150) ? 10240 : 5120; else n = 6144; break; @@ -354,6 +360,9 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk, if (pixel_clk == 297000000) { cts = 222750; break; + } else if (pixel_clk == 25174000) { + cts = 28125; + break; } case 48000: case 96000: @@ -369,6 +378,9 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk, case 297000000: cts = 247500; break; + case 25174000: + cts = 28125l; + break; /* * All other TMDS clocks are not supported by * DWC_hdmi_tx. The TMDS clocks divided or @@ -386,6 +398,9 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk, case 25200000: cts = 28000; break; + case 25174000: + cts = 31250; + break; case 27000000: cts = 30000; break; @@ -414,27 +429,6 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk, return (cts * ratio) / 100; } -static void hdmi_get_pixel_clk(void) -{ - struct ipu_soc *ipu; - unsigned long rate; - - if (pixel_clk == NULL) { - ipu = ipu_get_soc(mxc_hdmi_ipu_id); - pixel_clk = clk_get(ipu->dev, - ipu_lookups[mxc_hdmi_ipu_id][mxc_hdmi_disp_id].con_id); - if (IS_ERR(pixel_clk)) { - pr_err("%s could not get ipu%d_pixel_clk_%d\n", __func__, - mxc_hdmi_ipu_id + 1, mxc_hdmi_disp_id); - return; - } - } - - rate = clk_get_rate(pixel_clk); - if (rate != 0) - pixel_clk_rate = rate; -} - static void hdmi_set_clk_regenerator(void) { unsigned int clk_n, clk_cts; @@ -466,10 +460,11 @@ void hdmi_init_clk_regenerator(void) } } -void hdmi_clk_regenerator_update_pixel_clock(void) +void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock) { - /* Get pixel clock from ipu */ - hdmi_get_pixel_clk(); + + /* Translate pixel clock in ps (pico seconds) to Hz */ + pixel_clk_rate = PICOS2KHZ(pixclock) * 1000UL; hdmi_set_clk_regenerator(); } diff --git a/drivers/video/mxc_hdmi.c b/drivers/video/mxc_hdmi.c index fc5df129bcb1..f486d9a18058 100644 --- a/drivers/video/mxc_hdmi.c +++ b/drivers/video/mxc_hdmi.c @@ -2009,7 +2009,7 @@ static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event) dev_dbg(&hdmi->pdev->dev, "%s CEA mode\n", __func__); /* HDMI Initialization Step E - Configure audio */ - hdmi_clk_regenerator_update_pixel_clock(); + hdmi_clk_regenerator_update_pixel_clock(hdmi->fbi->var.pixclock); hdmi_enable_audio_clk(hdmi); /* HDMI Initialization Step F - Configure AVI InfoFrame */ diff --git a/include/linux/mfd/mxc-hdmi-core.h b/include/linux/mfd/mxc-hdmi-core.h index 8681053d231f..6ed08d31b02c 100644 --- a/include/linux/mfd/mxc-hdmi-core.h +++ b/include/linux/mfd/mxc-hdmi-core.h @@ -39,7 +39,7 @@ 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); +void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock); void hdmi_set_edid_cfg(struct mxc_edid_cfg *cfg); void hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg);