7272 * @logicore_reg_ba: logicore reg base address
7373 * @vcu_slcr_ba: vcu_slcr Register base address
7474 * @pll: handle for the VCU PLL
75+ * @pll_post: handle for the VCU PLL post divider
7576 * @clk_data: clocks provided by the vcu clock provider
7677 */
7778struct xvcu_device {
@@ -81,6 +82,7 @@ struct xvcu_device {
8182 struct regmap * logicore_reg_ba ;
8283 void __iomem * vcu_slcr_ba ;
8384 struct clk_hw * pll ;
85+ struct clk_hw * pll_post ;
8486 struct clk_hw_onecell_data * clk_data ;
8587};
8688
@@ -274,6 +276,29 @@ static int xvcu_pll_wait_for_lock(struct xvcu_device *xvcu)
274276 return - ETIMEDOUT ;
275277}
276278
279+ static struct clk_hw * xvcu_register_pll_post (struct device * dev ,
280+ const char * name ,
281+ const struct clk_hw * parent_hw ,
282+ void __iomem * reg_base )
283+ {
284+ u32 div ;
285+ u32 vcu_pll_ctrl ;
286+
287+ /*
288+ * The output divider of the PLL must be set to 1/2 to meet the
289+ * timing in the design.
290+ */
291+ vcu_pll_ctrl = xvcu_read (reg_base , VCU_PLL_CTRL );
292+ div = vcu_pll_ctrl >> VCU_PLL_CTRL_CLKOUTDIV_SHIFT ;
293+ div = div & VCU_PLL_CTRL_CLKOUTDIV_MASK ;
294+ if (div != 1 )
295+ return ERR_PTR (- EINVAL );
296+
297+ return clk_hw_register_fixed_factor (dev , "vcu_pll_post" ,
298+ clk_hw_get_name (parent_hw ),
299+ CLK_SET_RATE_PARENT , 1 , 2 );
300+ }
301+
277302static const struct xvcu_pll_cfg * xvcu_find_cfg (int div )
278303{
279304 const struct xvcu_pll_cfg * cfg = NULL ;
@@ -402,7 +427,7 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu)
402427{
403428 u32 refclk , coreclk , mcuclk , inte , deci ;
404429 u32 divisor_mcu , divisor_core , fvco ;
405- u32 clkoutdiv , vcu_pll_ctrl , pll_clk ;
430+ u32 pll_clk ;
406431 u32 mod ;
407432 int i ;
408433 int ret ;
@@ -425,19 +450,6 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu)
425450 dev_dbg (xvcu -> dev , "Core clock from logicoreIP is %uHz\n" , coreclk );
426451 dev_dbg (xvcu -> dev , "Mcu clock from logicoreIP is %uHz\n" , mcuclk );
427452
428- /*
429- * The divide-by-2 should be always enabled (==1)
430- * to meet the timing in the design.
431- * Otherwise, it's an error
432- */
433- vcu_pll_ctrl = xvcu_read (xvcu -> vcu_slcr_ba , VCU_PLL_CTRL );
434- clkoutdiv = vcu_pll_ctrl >> VCU_PLL_CTRL_CLKOUTDIV_SHIFT ;
435- clkoutdiv = clkoutdiv & VCU_PLL_CTRL_CLKOUTDIV_MASK ;
436- if (clkoutdiv != 1 ) {
437- dev_err (xvcu -> dev , "clkoutdiv value is invalid\n" );
438- return - EINVAL ;
439- }
440-
441453 for (i = ARRAY_SIZE (xvcu_pll_cfg ) - 1 ; i >= 0 ; i -- ) {
442454 const struct xvcu_pll_cfg * cfg = & xvcu_pll_cfg [i ];
443455
@@ -484,7 +496,7 @@ static int xvcu_set_vcu_pll_info(struct xvcu_device *xvcu)
484496
485497 hw = clk_hw_register_fixed_rate (xvcu -> dev , "vcu_pll" ,
486498 __clk_get_name (xvcu -> pll_ref ),
487- 0 , pll_clk );
499+ 0 , fvco );
488500 if (IS_ERR (hw ))
489501 return PTR_ERR (hw );
490502 xvcu -> pll = hw ;
@@ -607,6 +619,7 @@ static int xvcu_register_clock_provider(struct xvcu_device *xvcu)
607619 struct clk_parent_data parent_data [2 ] = { 0 };
608620 struct clk_hw_onecell_data * data ;
609621 struct clk_hw * * hws ;
622+ struct clk_hw * hw ;
610623 void __iomem * reg_base = xvcu -> vcu_slcr_ba ;
611624
612625 data = devm_kzalloc (dev , struct_size (data , hws , CLK_XVCU_NUM_CLOCKS ), GFP_KERNEL );
@@ -617,8 +630,13 @@ static int xvcu_register_clock_provider(struct xvcu_device *xvcu)
617630
618631 xvcu -> clk_data = data ;
619632
633+ hw = xvcu_register_pll_post (dev , "vcu_pll_post" , xvcu -> pll , reg_base );
634+ if (IS_ERR (hw ))
635+ return PTR_ERR (hw );
636+ xvcu -> pll_post = hw ;
637+
620638 parent_data [0 ].fw_name = "pll_ref" ;
621- parent_data [1 ].hw = xvcu -> pll ;
639+ parent_data [1 ].hw = xvcu -> pll_post ;
622640
623641 hws [CLK_XVCU_ENC_CORE ] =
624642 xvcu_clk_hw_register_leaf (dev , "venc_core_clk" ,
@@ -657,6 +675,8 @@ static void xvcu_unregister_clock_provider(struct xvcu_device *xvcu)
657675 xvcu_clk_hw_unregister_leaf (hws [CLK_XVCU_ENC_MCU ]);
658676 if (!IS_ERR_OR_NULL (hws [CLK_XVCU_ENC_CORE ]))
659677 xvcu_clk_hw_unregister_leaf (hws [CLK_XVCU_ENC_CORE ]);
678+
679+ clk_hw_unregister_fixed_factor (xvcu -> pll_post );
660680}
661681
662682/**
0 commit comments