@@ -1818,12 +1818,101 @@ static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw)
18181818 rk_hdptx_phy_consumer_put (hdptx , true);
18191819}
18201820
1821+ #define PLL_REF_CLK 24000000ULL
1822+
1823+ static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg (struct rk_hdptx_phy * hdptx )
1824+ {
1825+ struct ropll_config ropll_hw ;
1826+ u64 fout , sdm ;
1827+ u32 mode , val ;
1828+ int ret ;
1829+
1830+ ret = regmap_read (hdptx -> regmap , CMN_REG (0008 ), & mode );
1831+ if (ret )
1832+ return 0 ;
1833+
1834+ if (mode & LCPLL_LCVCO_MODE_EN_MASK )
1835+ return 0 ;
1836+
1837+ ret = regmap_read (hdptx -> regmap , CMN_REG (0051 ), & val );
1838+ if (ret )
1839+ return 0 ;
1840+ ropll_hw .pms_mdiv = val ;
1841+
1842+ ret = regmap_read (hdptx -> regmap , CMN_REG (005E ), & val );
1843+ if (ret )
1844+ return 0 ;
1845+ ropll_hw .sdm_en = val & ROPLL_SDM_EN_MASK ;
1846+
1847+ ret = regmap_read (hdptx -> regmap , CMN_REG (0064 ), & val );
1848+ if (ret )
1849+ return 0 ;
1850+ ropll_hw .sdm_num_sign = val & ROPLL_SDM_NUM_SIGN_RBR_MASK ;
1851+
1852+ ret = regmap_read (hdptx -> regmap , CMN_REG (0065 ), & val );
1853+ if (ret )
1854+ return 0 ;
1855+ ropll_hw .sdm_num = val ;
1856+
1857+ ret = regmap_read (hdptx -> regmap , CMN_REG (0060 ), & val );
1858+ if (ret )
1859+ return 0 ;
1860+ ropll_hw .sdm_deno = val ;
1861+
1862+ ret = regmap_read (hdptx -> regmap , CMN_REG (0069 ), & val );
1863+ if (ret )
1864+ return 0 ;
1865+ ropll_hw .sdc_n = (val & ROPLL_SDC_N_RBR_MASK ) + 3 ;
1866+
1867+ ret = regmap_read (hdptx -> regmap , CMN_REG (006 c ), & val );
1868+ if (ret )
1869+ return 0 ;
1870+ ropll_hw .sdc_num = val ;
1871+
1872+ ret = regmap_read (hdptx -> regmap , CMN_REG (0070 ), & val );
1873+ if (ret )
1874+ return 0 ;
1875+ ropll_hw .sdc_deno = val ;
1876+
1877+ ret = regmap_read (hdptx -> regmap , CMN_REG (0086 ), & val );
1878+ if (ret )
1879+ return 0 ;
1880+ ropll_hw .pms_sdiv = ((val & PLL_PCG_POSTDIV_SEL_MASK ) >> 4 ) + 1 ;
1881+
1882+ fout = PLL_REF_CLK * ropll_hw .pms_mdiv ;
1883+ if (ropll_hw .sdm_en ) {
1884+ sdm = div_u64 (PLL_REF_CLK * ropll_hw .sdc_deno *
1885+ ropll_hw .pms_mdiv * ropll_hw .sdm_num ,
1886+ 16 * ropll_hw .sdm_deno *
1887+ (ropll_hw .sdc_deno * ropll_hw .sdc_n - ropll_hw .sdc_num ));
1888+
1889+ if (ropll_hw .sdm_num_sign )
1890+ fout = fout - sdm ;
1891+ else
1892+ fout = fout + sdm ;
1893+ }
1894+
1895+ return div_u64 (fout * 2 , ropll_hw .pms_sdiv * 10 );
1896+ }
1897+
18211898static unsigned long rk_hdptx_phy_clk_recalc_rate (struct clk_hw * hw ,
18221899 unsigned long parent_rate )
18231900{
18241901 struct rk_hdptx_phy * hdptx = to_rk_hdptx_phy (hw );
1902+ u32 status ;
1903+ u64 rate ;
1904+ int ret ;
1905+
1906+ if (hdptx -> hw_rate )
1907+ return hdptx -> hw_rate ;
1908+
1909+ ret = regmap_read (hdptx -> grf , GRF_HDPTX_CON0 , & status );
1910+ if (ret || !(status & HDPTX_I_PLL_EN ))
1911+ return 0 ;
1912+
1913+ rate = rk_hdptx_phy_clk_calc_rate_from_pll_cfg (hdptx );
18251914
1826- return hdptx -> hw_rate ;
1915+ return DIV_ROUND_CLOSEST_ULL ( rate * 8 , hdptx -> hdmi_cfg . bpc ) ;
18271916}
18281917
18291918static int rk_hdptx_phy_clk_determine_rate (struct clk_hw * hw ,
0 commit comments