3434
3535#define RK3288_GRF_SOC_CON6 0x025C
3636#define RK3288_HDMI_LCDC_SEL BIT(4)
37+ #define RK3366_GRF_SOC_CON0 0x0400
38+ #define RK3366_HDMI_LCDC_SEL BIT(1)
3739#define RK3399_GRF_SOC_CON20 0x6250
3840#define RK3399_HDMI_LCDC_SEL BIT(6)
3941
@@ -57,6 +59,7 @@ struct rockchip_hdmi {
5759 struct clk * vpll_clk ;
5860 struct clk * grf_clk ;
5961 struct clk * hclk_vio ;
62+ struct clk * dclk ;
6063
6164 struct phy * phy ;
6265};
@@ -331,6 +334,16 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
331334 return PTR_ERR (hdmi -> hclk_vio );
332335 }
333336
337+ hdmi -> dclk = devm_clk_get (hdmi -> dev , "dclk" );
338+ if (PTR_ERR (hdmi -> dclk ) == - ENOENT ) {
339+ hdmi -> dclk = NULL ;
340+ } else if (PTR_ERR (hdmi -> dclk ) == - EPROBE_DEFER ) {
341+ return - EPROBE_DEFER ;
342+ } else if (IS_ERR (hdmi -> dclk )) {
343+ dev_err (hdmi -> dev , "failed to get dclk\n" );
344+ return PTR_ERR (hdmi -> dclk );
345+ }
346+
334347 ret = clk_prepare_enable (hdmi -> vpll_clk );
335348 if (ret ) {
336349 dev_err (hdmi -> dev , "Failed to enable HDMI vpll: %d\n" , ret );
@@ -438,6 +451,9 @@ static const struct drm_encoder_funcs dw_hdmi_rockchip_encoder_funcs = {
438451
439452static void dw_hdmi_rockchip_encoder_disable (struct drm_encoder * encoder )
440453{
454+ struct rockchip_hdmi * hdmi = to_rockchip_hdmi (encoder );
455+
456+ clk_disable_unprepare (hdmi -> dclk );
441457}
442458
443459static void dw_hdmi_rockchip_encoder_enable (struct drm_encoder * encoder )
@@ -455,18 +471,25 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
455471 clk_set_rate (hdmi -> vpll_clk ,
456472 crtc -> state -> adjusted_mode .crtc_clock * 1000 );
457473
474+ clk_set_rate (hdmi -> dclk , crtc -> state -> adjusted_mode .crtc_clock * 1000 );
475+ clk_prepare_enable (hdmi -> dclk );
476+
458477 switch (hdmi -> dev_type ) {
459478 case RK3288_HDMI :
460479 lcdsel_grf_reg = RK3288_GRF_SOC_CON6 ;
461480 lcdsel_mask = RK3288_HDMI_LCDC_SEL ;
462481 break ;
482+ case RK3366_HDMI :
483+ lcdsel_grf_reg = RK3366_GRF_SOC_CON0 ;
484+ lcdsel_mask = RK3366_HDMI_LCDC_SEL ;
485+ break ;
463486 case RK3399_HDMI :
464487 lcdsel_grf_reg = RK3399_GRF_SOC_CON20 ;
465488 lcdsel_mask = RK3399_HDMI_LCDC_SEL ;
466489 break ;
467490 default :
468491 return ;
469- };
492+ }
470493
471494 mux = drm_of_encoder_active_endpoint_id (hdmi -> dev -> of_node , encoder );
472495 if (mux )
@@ -553,6 +576,14 @@ static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
553576 .dev_type = RK3328_HDMI ,
554577};
555578
579+ static const struct dw_hdmi_plat_data rk3366_hdmi_drv_data = {
580+ .mode_valid = dw_hdmi_rockchip_mode_valid ,
581+ .mpll_cfg = rockchip_mpll_cfg ,
582+ .cur_ctr = rockchip_cur_ctr ,
583+ .phy_config = rockchip_phy_config ,
584+ .dev_type = RK3366_HDMI ,
585+ };
586+
556587static const struct dw_hdmi_plat_data rk3368_hdmi_drv_data = {
557588 .mode_valid = dw_hdmi_rockchip_mode_valid ,
558589 .mpll_cfg = rockchip_mpll_cfg ,
@@ -580,6 +611,10 @@ static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
580611 .compatible = "rockchip,rk3328-dw-hdmi" ,
581612 .data = & rk3328_hdmi_drv_data
582613 },
614+ {
615+ .compatible = "rockchip,rk3366-dw-hdmi" ,
616+ .data = & rk3366_hdmi_drv_data
617+ },
583618 {
584619 .compatible = "rockchip,rk3368-dw-hdmi" ,
585620 .data = & rk3368_hdmi_drv_data
0 commit comments