mipi dsi: add mclk change from 11289600 to 12M
authorhhb <hhb@rock-chips.com>
Tue, 6 Aug 2013 02:32:51 +0000 (10:32 +0800)
committerhhb <hhb@rock-chips.com>
Tue, 6 Aug 2013 02:32:51 +0000 (10:32 +0800)
drivers/mfd/rk616-core.c
drivers/mfd/rk616-vif.c
drivers/video/rockchip/transmitter/rk616_mipi_dsi.c
drivers/video/rockchip/transmitter/rk616_mipi_dsi.h
include/linux/mfd/rk616.h
sound/soc/codecs/rk616_codec.c
sound/soc/rk29/rk_rk616.c

index 4303096f7a52b1bb897c046e73a5e80f8fc4661c..7c0347868acc50f774c63a58757a1bd2530182f6 100755 (executable)
 #include <linux/seq_file.h>
 #endif
 
+#if defined(RK616_MIPI_DSI)
+#include "../video/rockchip/transmitter/rk616_mipi_dsi.h"
+#endif
+
 #ifndef MHZ
 #define MHZ (1000*1000)
 #endif
@@ -36,6 +40,17 @@ static struct mfd_cell rk616_devs[] = {
        },
 };
 
+
+void rk616_mclk_set_rate(struct clk *mclk,unsigned long rate)
+{
+       clk_set_rate(mclk, rate);
+
+#if defined(RK616_MIPI_DSI)
+       rk_mipi_dsi_init_lite();
+#endif
+
+}
+
 static int rk616_i2c_read_reg(struct mfd_rk616 *rk616, u16 reg,u32 *pval)
 {
        struct i2c_client * client = rk616->client;
@@ -476,7 +491,8 @@ static int rk616_i2c_probe(struct i2c_client *client,const struct i2c_device_id
                iomux_set(I2S0_MCLK);
                #endif
                clk_enable(iis_clk);
-               clk_set_rate(iis_clk, 11289600);
+               //clk_set_rate(iis_clk, 11289600);
+               rk616_mclk_set_rate(iis_clk,11289600);
                //clk_put(iis_clk);
        }
 
index ac2b6f832b5e7a41946c8726855983686cf5d14f..efbefdbc7b72f79a299963d901488d3a0405e722 100755 (executable)
@@ -157,7 +157,8 @@ int rk616_vif_cfg(struct mfd_rk616 *rk616,rk_screen *screen,int id)
        
        if(pll_use_mclk12m)
        {
-               clk_set_rate(rk616->mclk, 12000000);
+               //clk_set_rate(rk616->mclk, 12000000);
+               rk616_mclk_set_rate(rk616->mclk,12000000);
        }
 
        
@@ -781,7 +782,6 @@ int rk616_set_vif(struct mfd_rk616 *rk616,rk_screen *screen,bool connect)
        {
                rk616_vif_disable(rk616,0);
                rk616_vif_disable(rk616,1);
-               clk_set_rate(rk616->mclk, 11289600); 
                return 0;
        }
 #if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
index 380612ee3e6e2a4e928dbd9de5635846623dc2fe..c3c3a1fb45e6c56aab878b29e06b9c2daf43e6e4 100644 (file)
@@ -18,7 +18,7 @@
 #define MIPI_DSI_REGISTER_IO   1
 #define CONFIG_MIPI_DSI_LINUX   1
 //#define CONFIG_MIPI_DSI_FT           1
-#define CONFIG_MFD_RK616               1
+//#define CONFIG_MFD_RK616             1
 
 #ifdef CONFIG_MIPI_DSI_LINUX
 #include <linux/kernel.h>
@@ -95,6 +95,7 @@ static struct mipi_dsi_screen *g_screen = NULL;
 #define msleep                 DelayMs_nops
 static u32 fre_to_period(u32 fre);
 #endif
+static int rk_mipi_dsi_is_active(void);
 static int rk_mipi_dsi_enable_hs_clk(u32 enable);
 static int rk_mipi_dsi_enable_video_mode(u32 enable);
 static int rk_mipi_dsi_enable_command_mode(u32 enable);
@@ -391,9 +392,9 @@ static int rk_mipi_dsi_phy_power_down(void) {
 }
 
 static void rk_mipi_dsi_set_hs_clk(void) {
-       dsi_set_bits((gDsi.phy.fbdiv >> 8) & 0x01, reg_fbdiv_8);
        dsi_set_bits(gDsi.phy.prediv, reg_prediv);
        dsi_set_bits(gDsi.phy.fbdiv & 0xff, reg_fbdiv);
+       dsi_set_bits((gDsi.phy.fbdiv >> 8) & 0x01, reg_fbdiv_8);
 }
 
 
@@ -469,8 +470,7 @@ static int rk_mipi_dsi_host_power_up(void) {
        return ret;
 }
 
-static int rk_mipi_dsi_host_power_down(void) {
-       
+static int rk_mipi_dsi_host_power_down(void) { 
        rk_mipi_dsi_enable_video_mode(0);
        rk_mipi_dsi_enable_hs_clk(0);
        dsi_set_bits(0, shutdownz);
@@ -723,6 +723,73 @@ static int rk_mipi_dsi_init(void *array, u32 n) {
 }
 
 
+int rk_mipi_dsi_init_lite(void) {
+
+       u32 decimals = 1000, i = 0, pre = 0, val = 0, ref_clk = 0;
+       struct mipi_dsi_screen *screen = g_screen;
+       
+       if(rk_mipi_dsi_is_active() == 0)
+               return -1;
+       
+       ref_clk = clk_get_rate(dsi_rk616->mclk);
+       if(gDsi.phy.ref_clk == ref_clk)
+               return -1;
+               
+       gDsi.phy.ref_clk = ref_clk;
+       gDsi.phy.sys_clk = gDsi.phy.ref_clk;
+       
+       if((screen->hs_tx_clk <= 80 * MHz) || (screen->hs_tx_clk >= 1000 * MHz))
+               gDsi.phy.ddr_clk = 1000 * MHz;    //default is 1HGz
+       else
+               gDsi.phy.ddr_clk = screen->hs_tx_clk;
+               
+       decimals = gDsi.phy.ref_clk;
+       for(i = 1; i < 6; i++) {
+               pre = gDsi.phy.ref_clk / i;
+               if((decimals > (gDsi.phy.ddr_clk % pre)) && (gDsi.phy.ddr_clk / pre < 512)) {
+                       decimals = gDsi.phy.ddr_clk % pre;
+                       gDsi.phy.prediv = i;
+                       gDsi.phy.fbdiv = gDsi.phy.ddr_clk / pre;
+               }       
+               if(decimals == 0) 
+                       break;          
+       }
+
+       MIPI_DBG("prediv:%d, fbdiv:%d\n", gDsi.phy.prediv, gDsi.phy.fbdiv);
+       gDsi.phy.ddr_clk = gDsi.phy.ref_clk / gDsi.phy.prediv * gDsi.phy.fbdiv; 
+       gDsi.phy.txbyte_clk = gDsi.phy.ddr_clk / 8;
+       
+       gDsi.phy.txclkesc = 20 * MHz;        // < 20MHz
+       gDsi.phy.txclkesc = gDsi.phy.txbyte_clk / (gDsi.phy.txbyte_clk / gDsi.phy.txclkesc + 1);
+       
+       gDsi.phy.pclk = div_u64(1000000000000llu, gDsi.phy.Tpclk);
+       gDsi.phy.Ttxclkesc = div_u64(1000000000000llu, gDsi.phy.txclkesc);
+       gDsi.phy.Tsys_clk = div_u64(1000000000000llu, gDsi.phy.sys_clk);
+       gDsi.phy.Tddr_clk = div_u64(1000000000000llu, gDsi.phy.ddr_clk);
+       gDsi.phy.Ttxbyte_clk = div_u64(1000000000000llu, gDsi.phy.txbyte_clk);
+       gDsi.phy.UI = gDsi.phy.Tddr_clk;
+               
+       MIPI_DBG("UI:%d\n", gDsi.phy.UI);       
+       MIPI_DBG("ref_clk:%d\n", gDsi.phy.ref_clk);
+       MIPI_DBG("pclk:%d, Tpclk:%d\n", gDsi.phy.pclk, gDsi.phy.Tpclk);
+       MIPI_DBG("sys_clk:%d, Tsys_clk:%d\n", gDsi.phy.sys_clk, gDsi.phy.Tsys_clk);
+       MIPI_DBG("ddr_clk:%d, Tddr_clk:%d\n", gDsi.phy.ddr_clk, gDsi.phy.Tddr_clk);
+       MIPI_DBG("txbyte_clk:%d, Ttxbyte_clk:%d\n", gDsi.phy.txbyte_clk, gDsi.phy.Ttxbyte_clk);
+       MIPI_DBG("txclkesc:%d, Ttxclkesc:%d\n", gDsi.phy.txclkesc, gDsi.phy.Ttxclkesc);
+               
+       rk_mipi_dsi_host_power_down();
+       rk_mipi_dsi_phy_power_down();
+       rk_mipi_dsi_phy_power_up();
+       rk_mipi_dsi_phy_init(screen, 0);
+       //rk_mipi_dsi_host_power_up();
+       //rk_mipi_dsi_host_init(screen, 0);
+       //dsi_set_bits(0, shutdownz);
+       rk_mipi_dsi_enable_hs_clk(1);
+       rk_mipi_dsi_enable_video_mode(1);
+       dsi_set_bits(1, shutdownz);
+       return 0;
+}
+
 
 static int rk_mipi_dsi_enable_video_mode(u32 enable) {
 
@@ -964,7 +1031,12 @@ int reg_proc_write(struct file *file, const char __user *buff, size_t count, lof
                case 's':
                                while(*(++data) == ' ');
                                sscanf(data, "%d", &read_val);
-                               rk_mipi_dsi_init(g_screen, read_val * MHz);
+                               if(read_val == 11)
+                                       read_val = 11289600;
+                               else    
+                                       read_val *= MHz;
+                               clk_set_rate(dsi_rk616->mclk, read_val);        
+                               rk_mipi_dsi_init_lite();
                        break;
                case 'd':
                case 'g':
index 6ec1805fed2a02ffc83c2f3fd67270285b874894..25d109d0ba9c0ae353df613ba61641b61df26445 100644 (file)
@@ -311,5 +311,5 @@ struct dsi {
 #define MHz   1000000
 #endif
 extern int rk616_mipi_dsi_ft_init(void);
-
+int rk_mipi_dsi_init_lite(void);
 #endif /* end of RK616_MIPI_DSI_H */
index 166a27fe4f02a50dca961f58f079c4aa4692561d..f598fef64fc43b18a9166b52a25efbcbf0918db2 100755 (executable)
@@ -289,6 +289,7 @@ struct mfd_rk616 {
 
 extern int rk616_set_vif(struct mfd_rk616 * rk616,rk_screen * screen,bool connect);
 extern int rk616_display_router_cfg(struct mfd_rk616 *rk616,rk_screen *screen,bool enable);
+extern void rk616_mclk_set_rate(struct clk *mclk,unsigned long rate);
 
 
 
index 83ae80b2c44feffe8a61c1957f97da3b2b70175c..ba44143344fce63284c4b613f901fb5c31ce0141 100755 (executable)
@@ -1809,6 +1809,9 @@ static int rk616_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
        rk616->stereo_sysclk = freq;
 
+       //set I2S mclk for mipi
+       rk616_mclk_set_rate(rk616_mfd->mclk, freq);
+
        return 0;
 }
 
index b595d6b1a0aaa26de5d6d5f9d05319a49f2630d5..9e408e5b0ba2335559361e0f2d823a57a7da5c56 100755 (executable)
@@ -162,7 +162,8 @@ static int rk_hifi_hw_params(struct snd_pcm_substream *substream,
        }
        #endif
 
-       /*Set the system clk for codec*/
+       /* Set the system clk for codec
+          mclk will be setted in set_sysclk of codec_dai*/
        ret = snd_soc_dai_set_sysclk(codec_dai, 0, pll_out, SND_SOC_CLOCK_IN);
        if (ret < 0) {
                DBG("rk_hifi_hw_params:failed to set the sysclk for codec side\n");
@@ -170,7 +171,6 @@ static int rk_hifi_hw_params(struct snd_pcm_substream *substream,
        }
 
 __setdiv:
-       snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
        snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, (pll_out / div)/params_rate(params)-1);
        snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div - 1);