From: dkl Date: Wed, 5 Nov 2014 06:30:39 +0000 (+0800) Subject: rockchip: clk: add rk3188_plus type pll enable/disable X-Git-Tag: firefly_0821_release~4469 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=81ba1a55151a36d1cb4bde527de201cb4268c425;p=firefly-linux-kernel-4.4.55.git rockchip: clk: add rk3188_plus type pll enable/disable Add rk3188_plus type pll enable/disable ops. Disable unused plls when display is off in rk3288. --- diff --git a/arch/arm/boot/dts/rk3288-clocks.dtsi b/arch/arm/boot/dts/rk3288-clocks.dtsi index 4d7a7591f5ce..9a1769372ac6 100755 --- a/arch/arm/boot/dts/rk3288-clocks.dtsi +++ b/arch/arm/boot/dts/rk3288-clocks.dtsi @@ -1459,7 +1459,7 @@ hclk_vio: hclk_vio_div { compatible = "rockchip,rk3188-div-con"; rockchip,bits = <8 5>; - clocks = <&aclk_vio0>; + clocks = <&clk_gates15 11>; clock-output-names = "hclk_vio"; rockchip,div-type = ; #clock-cells = <0>; @@ -2648,28 +2648,28 @@ reg = <0x019c 0x4>; clocks = <&aclk_rga>, <&hclk_vio>, - <&aclk_vio0>, <&hclk_vio>, + <&clk_gates15 11>, <&hclk_vio>, - <&dummy>, <&aclk_vio0>, - <&hclk_vio>, <&aclk_vio1>, + <&dummy>, <&clk_gates15 11>, + <&hclk_vio>, <&clk_gates15 12>, - <&hclk_vio>, <&hclk_vio>, - <&hclk_vio>, <&aclk_vio0>, + <&hclk_vio>, <&dummy>, + <&dummy>, <&aclk_vio0>, <&aclk_vio1>, <&aclk_rga>, - <&aclk_vio0>, <&hclk_vio>; + <&clk_gates15 11>, <&hclk_vio>; clock-output-names = - "reserved", /*"g_aclk_rga",*/ "g_hclk_rga", + "reserved", /*"g_aclk_rga"*/ "g_hclk_rga", "g_aclk_iep", "g_hclk_iep", "g_aclk_lcdc_iep", "g_aclk_lcdc0", "g_hclk_lcdc0", "g_aclk_lcdc1", - "g_hclk_lcdc1", "g_h_vio_ahb", - "g_hclk_vio_niu", "g_aclk_vio0_niu", + "g_hclk_lcdc1", "reserved", /* "g_h_vio_ahb" */ + "reserved",/*"g_hclk_vio_niu"*/ "g_aclk_vio0_niu", - "g_aclk_vio1_niu", "reserved",/*"g_aclk_rga_niu",*/ + "g_aclk_vio1_niu", "reserved",/*"g_aclk_rga_niu"*/ "g_aclk_vip", "g_hclk_vip"; rockchip,suspend-clkgating-setting=<0x0 0x0>; @@ -2681,13 +2681,13 @@ reg = <0x01a0 0x4>; clocks = <&pclkin_cif>, <&hclk_vio>, - <&aclk_vio1>, <&pclkin_isp>, + <&clk_gates15 12>, <&pclkin_isp>, <&hclk_vio>, <&hclk_vio>, <&hclk_vio>, <&hclk_vio>, <&hclk_vio>, <&hclk_vio>, - <&hclk_vio>, <&hclk_vio>, + <&dummy>, <&dummy>, <&dummy>, <&dummy>, <&dummy>, <&dummy>; @@ -2700,7 +2700,7 @@ "g_p_mipi_csi", "g_pclk_lvds_phy", "g_pclk_edp_ctrl", "g_p_hdmi_ctrl", - "g_hclk_vio2_h2p", "g_pclk_vio2_h2p", + "reserved", "reserved", /* bit10:"g_hclk_vio2_h2p" bit11: "g_pclk_vio2_h2p" */ "reserved", "reserved", "reserved", "reserved"; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 481063dc96bc..a15825a4e90e 100755 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -510,6 +510,9 @@ clocks-enable { compatible = "rockchip,clocks-enable"; clocks = + /*PLL*/ + <&clk_dpll>, <&clk_gpll>, + /*PD_CORE*/ <&clk_gates0 2>, <&clk_core0>, <&clk_core1>, <&clk_core2>, @@ -582,21 +585,6 @@ <&clk_gates17 2>,/*pclk_pmu_niu*/ <&clk_gates17 3>,/*pclk_sgrf*/ - /*hclk_vio*/ - <&clk_gates15 9>,/*hclk_vio_ahb_arbi*/ - <&clk_gates15 10>,/*hclk_vio_niu*/ - <&clk_gates16 10>,/*hclk_vio2_h2p*/ - <&clk_gates16 11>,/*pclk_vio2_h2p*/ - - /*aclk_vio0*/ - <&clk_gates15 11>,/*aclk_vio0_niu*/ - - /*aclk_vio1*/ - <&clk_gates15 12>,/*aclk_vio1_niu*/ - - /*HDMI*/ - //<&clk_gates5 12>,/*hdmi_hdcp_clk*/ - /*UART*/ <&clk_gates11 9>,/*pclk_uart2*/ diff --git a/arch/arm/mach-rockchip/rk3288.c b/arch/arm/mach-rockchip/rk3288.c index abcdb16e7c78..71fd7ff4467d 100755 --- a/arch/arm/mach-rockchip/rk3288.c +++ b/arch/arm/mach-rockchip/rk3288.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -490,6 +491,40 @@ static void __init rk3288_init_cpuidle(void) if (ret) pr_err("%s: failed to register cpuidle driver: %d\n", __func__, ret); } + +static int rk3288_pll_early_suspend_notifier_call(struct notifier_block *self, + unsigned long action, void *data) +{ + struct fb_event *event = data; + int blank_mode = *((int *)event->data); + + if (action == FB_EARLY_EVENT_BLANK) { + switch (blank_mode) { + case FB_BLANK_UNBLANK: + clk_prepare_enable(clk_get_sys(NULL, "clk_cpll")); + clk_prepare_enable(clk_get_sys(NULL, "clk_npll")); + break; + default: + break; + } + } else if (action == FB_EVENT_BLANK) { + switch (blank_mode) { + case FB_BLANK_POWERDOWN: + clk_disable_unprepare(clk_get_sys(NULL, "clk_cpll")); + clk_disable_unprepare(clk_get_sys(NULL, "clk_npll")); + break; + default: + break; + } + } + + return NOTIFY_OK; +} + +static struct notifier_block rk3288_pll_early_suspend_notifier = { + .notifier_call = rk3288_pll_early_suspend_notifier_call, +}; + #ifdef CONFIG_PM static void __init rk3288_init_suspend(void); #endif @@ -596,10 +631,11 @@ void inline rkpm_periph_pd_dn(bool on) static void __init rk3288_init_suspend(void) { printk("%s\n",__FUNCTION__); + fb_register_client(&rk3288_pll_early_suspend_notifier); rockchip_suspend_init(); rkpm_pie_init(); rk3288_suspend_init(); - rkpm_set_ops_pwr_dmns(rk_pm_soc_pd_suspend,rk_pm_soc_pd_resume); + rkpm_set_ops_pwr_dmns(rk_pm_soc_pd_suspend,rk_pm_soc_pd_resume); } #if 0 diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index ce8496577766..63f1b295fe40 100755 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -820,10 +820,113 @@ static int clk_pll_set_rate_3188plus(struct clk_hw *hw, unsigned long rate, return ret; } +static int clk_pll_is_enabled_3188plus(struct clk_hw *hw) +{ + unsigned long flags; + struct clk_pll *pll = to_clk_pll(hw); + int ret; + + if(pll->lock) + spin_lock_irqsave(pll->lock, flags); + + if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift)) + ret = 1; + else + ret = 0; + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); + + return ret; +} + +static int clk_pll_enable_3188plus(struct clk_hw *hw) +{ + struct clk_pll *pll = to_clk_pll(hw); + unsigned long flags; + unsigned long rst_dly; + u32 nr; + + clk_debug("%s enter\n", __func__); + + if (clk_pll_is_enabled_3188plus(hw)) { + clk_debug("pll has been enabled\n"); + return 0; + } + + if(pll->lock) + spin_lock_irqsave(pll->lock, flags); + + //enter slowmode + cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset); + + //power up + cru_writel(_RK3188PLUS_PLL_POWERDOWN_SET(0), pll->reg + RK3188_PLL_CON(3)); + + //enter reset + cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3)); + + //cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0)); + //cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1)); + //cru_writel(clk_set->pllcon2, pll->reg + RK3188_PLL_CON(2)); + + udelay(5); + + //return from reset + cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3)); + + //wating lock state + nr = RK3188PLUS_PLL_NR(cru_readl(pll->reg + RK3188_PLL_CON(0))); + rst_dly = ((nr*500)/24+1); + udelay(rst_dly); + + pll_wait_lock(hw); + + //return from slow + cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset); + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); + + clk_debug("pll %s dump reg:\n con0=0x%08x,\n con1=0x%08x,\n con2=0x%08x,\n" + "con3=0x%08x,\n mode=0x%08x\n", + __clk_get_name(hw->clk), + cru_readl(pll->reg + RK3188_PLL_CON(0)), + cru_readl(pll->reg + RK3188_PLL_CON(1)), + cru_readl(pll->reg + RK3188_PLL_CON(2)), + cru_readl(pll->reg + RK3188_PLL_CON(3)), + cru_readl(pll->mode_offset)); + + return 0; +} + +static void clk_pll_disable_3188plus(struct clk_hw *hw) +{ + struct clk_pll *pll = to_clk_pll(hw); + unsigned long flags; + + clk_debug("%s enter\n", __func__); + + if(pll->lock) + spin_lock_irqsave(pll->lock, flags); + + //enter slowmode + cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset); + + //power down + cru_writel(_RK3188PLUS_PLL_POWERDOWN_SET(1), pll->reg + RK3188_PLL_CON(3)); + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); +} + static const struct clk_ops clk_pll_ops_3188plus = { .recalc_rate = clk_pll_recalc_rate_3188plus, .round_rate = clk_pll_round_rate_3188plus, .set_rate = clk_pll_set_rate_3188plus, + .enable = clk_pll_enable_3188plus, + .disable = clk_pll_disable_3188plus, + .is_enabled = clk_pll_is_enabled_3188plus, }; /* CLK_PLL_3188PLUS_AUTO type ops */ @@ -999,6 +1102,9 @@ static const struct clk_ops clk_pll_ops_3188plus_auto = { .recalc_rate = clk_pll_recalc_rate_3188plus_auto, .round_rate = clk_pll_round_rate_3188plus_auto, .set_rate = clk_pll_set_rate_3188plus_auto, + .enable = clk_pll_enable_3188plus, + .disable = clk_pll_disable_3188plus, + .is_enabled = clk_pll_is_enabled_3188plus, };