8
8
*/
9
9
#include <linux/bitfield.h>
10
10
#include <linux/clk.h>
11
+ #include <linux/clk-provider.h>
11
12
#include <linux/delay.h>
12
13
#include <linux/mfd/syscon.h>
13
14
#include <linux/module.h>
191
192
#define LN3_TX_SER_RATE_SEL_HBR2 BIT(3)
192
193
#define LN3_TX_SER_RATE_SEL_HBR3 BIT(2)
193
194
195
+ #define HDMI20_MAX_RATE 600000000
196
+
194
197
struct lcpll_config {
195
198
u32 bit_rate ;
196
199
u8 lcvco_mode_en ;
@@ -273,6 +276,12 @@ struct rk_hdptx_phy {
273
276
struct clk_bulk_data * clks ;
274
277
int nr_clks ;
275
278
struct reset_control_bulk_data rsts [RST_MAX ];
279
+
280
+ /* clk provider */
281
+ struct clk_hw hw ;
282
+ unsigned long rate ;
283
+
284
+ atomic_t usage_count ;
276
285
};
277
286
278
287
static const struct ropll_config ropll_tmds_cfg [] = {
@@ -760,6 +769,8 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
760
769
struct ropll_config rc = {0 };
761
770
int i ;
762
771
772
+ hdptx -> rate = rate * 100 ;
773
+
763
774
for (i = 0 ; i < ARRAY_SIZE (ropll_tmds_cfg ); i ++ )
764
775
if (rate == ropll_tmds_cfg [i ].bit_rate ) {
765
776
cfg = & ropll_tmds_cfg [i ];
@@ -823,19 +834,6 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx,
823
834
static int rk_hdptx_ropll_tmds_mode_config (struct rk_hdptx_phy * hdptx ,
824
835
unsigned int rate )
825
836
{
826
- u32 val ;
827
- int ret ;
828
-
829
- ret = regmap_read (hdptx -> grf , GRF_HDPTX_STATUS , & val );
830
- if (ret )
831
- return ret ;
832
-
833
- if (!(val & HDPTX_O_PLL_LOCK_DONE )) {
834
- ret = rk_hdptx_ropll_tmds_cmn_config (hdptx , rate );
835
- if (ret )
836
- return ret ;
837
- }
838
-
839
837
rk_hdptx_multi_reg_write (hdptx , rk_hdtpx_common_sb_init_seq );
840
838
841
839
regmap_write (hdptx -> regmap , LNTOP_REG (0200 ), 0x06 );
@@ -857,10 +855,68 @@ static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx,
857
855
return rk_hdptx_post_enable_lane (hdptx );
858
856
}
859
857
858
+ static int rk_hdptx_phy_consumer_get (struct rk_hdptx_phy * hdptx ,
859
+ unsigned int rate )
860
+ {
861
+ u32 status ;
862
+ int ret ;
863
+
864
+ if (atomic_inc_return (& hdptx -> usage_count ) > 1 )
865
+ return 0 ;
866
+
867
+ ret = regmap_read (hdptx -> grf , GRF_HDPTX_STATUS , & status );
868
+ if (ret )
869
+ goto dec_usage ;
870
+
871
+ if (status & HDPTX_O_PLL_LOCK_DONE )
872
+ dev_warn (hdptx -> dev , "PLL locked by unknown consumer!\n" );
873
+
874
+ if (rate ) {
875
+ ret = rk_hdptx_ropll_tmds_cmn_config (hdptx , rate );
876
+ if (ret )
877
+ goto dec_usage ;
878
+ }
879
+
880
+ return 0 ;
881
+
882
+ dec_usage :
883
+ atomic_dec (& hdptx -> usage_count );
884
+ return ret ;
885
+ }
886
+
887
+ static int rk_hdptx_phy_consumer_put (struct rk_hdptx_phy * hdptx , bool force )
888
+ {
889
+ u32 status ;
890
+ int ret ;
891
+
892
+ ret = atomic_dec_return (& hdptx -> usage_count );
893
+ if (ret > 0 )
894
+ return 0 ;
895
+
896
+ if (ret < 0 ) {
897
+ dev_warn (hdptx -> dev , "Usage count underflow!\n" );
898
+ ret = - EINVAL ;
899
+ } else {
900
+ ret = regmap_read (hdptx -> grf , GRF_HDPTX_STATUS , & status );
901
+ if (!ret ) {
902
+ if (status & HDPTX_O_PLL_LOCK_DONE )
903
+ rk_hdptx_phy_disable (hdptx );
904
+ return 0 ;
905
+ } else if (force ) {
906
+ return 0 ;
907
+ }
908
+ }
909
+
910
+ atomic_inc (& hdptx -> usage_count );
911
+ return ret ;
912
+ }
913
+
860
914
static int rk_hdptx_phy_power_on (struct phy * phy )
861
915
{
862
916
struct rk_hdptx_phy * hdptx = phy_get_drvdata (phy );
863
917
int bus_width = phy_get_bus_width (hdptx -> phy );
918
+ int ret ;
919
+
864
920
/*
865
921
* FIXME: Temporary workaround to pass pixel_clk_rate
866
922
* from the HDMI bridge driver until phy_configure_opts_hdmi
@@ -871,20 +927,22 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
871
927
dev_dbg (hdptx -> dev , "%s bus_width=%x rate=%u\n" ,
872
928
__func__ , bus_width , rate );
873
929
874
- return rk_hdptx_ropll_tmds_mode_config (hdptx , rate );
930
+ ret = rk_hdptx_phy_consumer_get (hdptx , rate );
931
+ if (ret )
932
+ return ret ;
933
+
934
+ ret = rk_hdptx_ropll_tmds_mode_config (hdptx , rate );
935
+ if (ret )
936
+ rk_hdptx_phy_consumer_put (hdptx , true);
937
+
938
+ return ret ;
875
939
}
876
940
877
941
static int rk_hdptx_phy_power_off (struct phy * phy )
878
942
{
879
943
struct rk_hdptx_phy * hdptx = phy_get_drvdata (phy );
880
- u32 val ;
881
- int ret ;
882
944
883
- ret = regmap_read (hdptx -> grf , GRF_HDPTX_STATUS , & val );
884
- if (ret == 0 && (val & HDPTX_O_PLL_LOCK_DONE ))
885
- rk_hdptx_phy_disable (hdptx );
886
-
887
- return ret ;
945
+ return rk_hdptx_phy_consumer_put (hdptx , false);
888
946
}
889
947
890
948
static const struct phy_ops rk_hdptx_phy_ops = {
@@ -893,6 +951,99 @@ static const struct phy_ops rk_hdptx_phy_ops = {
893
951
.owner = THIS_MODULE ,
894
952
};
895
953
954
+ static struct rk_hdptx_phy * to_rk_hdptx_phy (struct clk_hw * hw )
955
+ {
956
+ return container_of (hw , struct rk_hdptx_phy , hw );
957
+ }
958
+
959
+ static int rk_hdptx_phy_clk_prepare (struct clk_hw * hw )
960
+ {
961
+ struct rk_hdptx_phy * hdptx = to_rk_hdptx_phy (hw );
962
+
963
+ return rk_hdptx_phy_consumer_get (hdptx , hdptx -> rate / 100 );
964
+ }
965
+
966
+ static void rk_hdptx_phy_clk_unprepare (struct clk_hw * hw )
967
+ {
968
+ struct rk_hdptx_phy * hdptx = to_rk_hdptx_phy (hw );
969
+
970
+ rk_hdptx_phy_consumer_put (hdptx , true);
971
+ }
972
+
973
+ static unsigned long rk_hdptx_phy_clk_recalc_rate (struct clk_hw * hw ,
974
+ unsigned long parent_rate )
975
+ {
976
+ struct rk_hdptx_phy * hdptx = to_rk_hdptx_phy (hw );
977
+
978
+ return hdptx -> rate ;
979
+ }
980
+
981
+ static long rk_hdptx_phy_clk_round_rate (struct clk_hw * hw , unsigned long rate ,
982
+ unsigned long * parent_rate )
983
+ {
984
+ u32 bit_rate = rate / 100 ;
985
+ int i ;
986
+
987
+ if (rate > HDMI20_MAX_RATE )
988
+ return rate ;
989
+
990
+ for (i = 0 ; i < ARRAY_SIZE (ropll_tmds_cfg ); i ++ )
991
+ if (bit_rate == ropll_tmds_cfg [i ].bit_rate )
992
+ break ;
993
+
994
+ if (i == ARRAY_SIZE (ropll_tmds_cfg ) &&
995
+ !rk_hdptx_phy_clk_pll_calc (bit_rate , NULL ))
996
+ return - EINVAL ;
997
+
998
+ return rate ;
999
+ }
1000
+
1001
+ static int rk_hdptx_phy_clk_set_rate (struct clk_hw * hw , unsigned long rate ,
1002
+ unsigned long parent_rate )
1003
+ {
1004
+ struct rk_hdptx_phy * hdptx = to_rk_hdptx_phy (hw );
1005
+
1006
+ return rk_hdptx_ropll_tmds_cmn_config (hdptx , rate / 100 );
1007
+ }
1008
+
1009
+ static const struct clk_ops hdptx_phy_clk_ops = {
1010
+ .prepare = rk_hdptx_phy_clk_prepare ,
1011
+ .unprepare = rk_hdptx_phy_clk_unprepare ,
1012
+ .recalc_rate = rk_hdptx_phy_clk_recalc_rate ,
1013
+ .round_rate = rk_hdptx_phy_clk_round_rate ,
1014
+ .set_rate = rk_hdptx_phy_clk_set_rate ,
1015
+ };
1016
+
1017
+ static int rk_hdptx_phy_clk_register (struct rk_hdptx_phy * hdptx )
1018
+ {
1019
+ struct device * dev = hdptx -> dev ;
1020
+ const char * name , * pname ;
1021
+ struct clk * refclk ;
1022
+ int ret , id ;
1023
+
1024
+ refclk = devm_clk_get (dev , "ref" );
1025
+ if (IS_ERR (refclk ))
1026
+ return dev_err_probe (dev , PTR_ERR (refclk ),
1027
+ "Failed to get ref clock\n" );
1028
+
1029
+ id = of_alias_get_id (dev -> of_node , "hdptxphy" );
1030
+ name = id > 0 ? "clk_hdmiphy_pixel1" : "clk_hdmiphy_pixel0" ;
1031
+ pname = __clk_get_name (refclk );
1032
+
1033
+ hdptx -> hw .init = CLK_HW_INIT (name , pname , & hdptx_phy_clk_ops ,
1034
+ CLK_GET_RATE_NOCACHE );
1035
+
1036
+ ret = devm_clk_hw_register (dev , & hdptx -> hw );
1037
+ if (ret )
1038
+ return dev_err_probe (dev , ret , "Failed to register clock\n" );
1039
+
1040
+ ret = devm_of_clk_add_hw_provider (dev , of_clk_hw_simple_get , & hdptx -> hw );
1041
+ if (ret )
1042
+ return dev_err_probe (dev , ret ,
1043
+ "Failed to register clk provider\n" );
1044
+ return 0 ;
1045
+ }
1046
+
896
1047
static int rk_hdptx_phy_runtime_suspend (struct device * dev )
897
1048
{
898
1049
struct rk_hdptx_phy * hdptx = dev_get_drvdata (dev );
@@ -987,7 +1138,7 @@ static int rk_hdptx_phy_probe(struct platform_device *pdev)
987
1138
reset_control_deassert (hdptx -> rsts [RST_CMN ].rstc );
988
1139
reset_control_deassert (hdptx -> rsts [RST_INIT ].rstc );
989
1140
990
- return 0 ;
1141
+ return rk_hdptx_phy_clk_register ( hdptx ) ;
991
1142
}
992
1143
993
1144
static const struct dev_pm_ops rk_hdptx_phy_pm_ops = {
0 commit comments