Commit 523d3de4 authored by Marek Szyprowski's avatar Marek Szyprowski Committed by Michael Turquette

clk: samsung: exynos5433: Add support for runtime PM

Add runtime pm support for all clock controller units (CMU), which belong
to power domains and require special handling during on/off operations.
Typically special values has to be written to MUX registers to change
internal clocks parents to OSC clock before turning power off. During such
operation all clocks, which enter CMU has to be enabled to let MUX to
stabilize. Also for each CMU there is one special parent clock, which has
to be enabled all the time when any access to CMU registers is being done.

This patch solves most of the mysterious external abort and freeze issues
caused by a lack of proper parent CMU clock enabled or incorrect turn off
procedure.
Signed-off-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Reviewed-by: default avatarChanwoo Choi <cw00.choi@samsung.com>
Tested-by: default avatarChanwoo Choi <cw00.choi@samsung.com>
Reviewed-by: default avatarKrzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: default avatarMichael Turquette <mturquette@baylibre.com>
Link: lkml.kernel.org/r/1503302703-13801-4-git-send-email-m.szyprowski@samsung.com
parent d2f18d7e
...@@ -168,6 +168,11 @@ Required Properties: ...@@ -168,6 +168,11 @@ Required Properties:
- aclk_cam1_400 - aclk_cam1_400
- aclk_cam1_552 - aclk_cam1_552
Optional properties:
- power-domains: a phandle to respective power domain node as described by
generic PM domain bindings (see power/power_domain.txt for more
information).
Each clock is assigned an identifier and client nodes can use this identifier Each clock is assigned an identifier and client nodes can use this identifier
to specify the clock which they consume. to specify the clock which they consume.
...@@ -270,6 +275,7 @@ Example 2: Examples of clock controller nodes are listed below. ...@@ -270,6 +275,7 @@ Example 2: Examples of clock controller nodes are listed below.
clocks = <&xxti>, clocks = <&xxti>,
<&cmu_top CLK_ACLK_G2D_266>, <&cmu_top CLK_ACLK_G2D_266>,
<&cmu_top CLK_ACLK_G2D_400>; <&cmu_top CLK_ACLK_G2D_400>;
power-domains = <&pd_g2d>;
}; };
cmu_disp: clock-controller@13b90000 { cmu_disp: clock-controller@13b90000 {
...@@ -295,6 +301,7 @@ Example 2: Examples of clock controller nodes are listed below. ...@@ -295,6 +301,7 @@ Example 2: Examples of clock controller nodes are listed below.
<&cmu_mif CLK_SCLK_DECON_ECLK_DISP>, <&cmu_mif CLK_SCLK_DECON_ECLK_DISP>,
<&cmu_mif CLK_SCLK_DECON_TV_VCLK_DISP>, <&cmu_mif CLK_SCLK_DECON_TV_VCLK_DISP>,
<&cmu_mif CLK_ACLK_DISP_333>; <&cmu_mif CLK_ACLK_DISP_333>;
power-domains = <&pd_disp>;
}; };
cmu_aud: clock-controller@114c0000 { cmu_aud: clock-controller@114c0000 {
...@@ -304,6 +311,7 @@ Example 2: Examples of clock controller nodes are listed below. ...@@ -304,6 +311,7 @@ Example 2: Examples of clock controller nodes are listed below.
clock-names = "oscclk", "fout_aud_pll"; clock-names = "oscclk", "fout_aud_pll";
clocks = <&xxti>, <&cmu_top CLK_FOUT_AUD_PLL>; clocks = <&xxti>, <&cmu_top CLK_FOUT_AUD_PLL>;
power-domains = <&pd_aud>;
}; };
cmu_bus0: clock-controller@13600000 { cmu_bus0: clock-controller@13600000 {
...@@ -340,6 +348,7 @@ Example 2: Examples of clock controller nodes are listed below. ...@@ -340,6 +348,7 @@ Example 2: Examples of clock controller nodes are listed below.
clock-names = "oscclk", "aclk_g3d_400"; clock-names = "oscclk", "aclk_g3d_400";
clocks = <&xxti>, <&cmu_top CLK_ACLK_G3D_400>; clocks = <&xxti>, <&cmu_top CLK_ACLK_G3D_400>;
power-domains = <&pd_g3d>;
}; };
cmu_gscl: clock-controller@13cf0000 { cmu_gscl: clock-controller@13cf0000 {
...@@ -353,6 +362,7 @@ Example 2: Examples of clock controller nodes are listed below. ...@@ -353,6 +362,7 @@ Example 2: Examples of clock controller nodes are listed below.
clocks = <&xxti>, clocks = <&xxti>,
<&cmu_top CLK_ACLK_GSCL_111>, <&cmu_top CLK_ACLK_GSCL_111>,
<&cmu_top CLK_ACLK_GSCL_333>; <&cmu_top CLK_ACLK_GSCL_333>;
power-domains = <&pd_gscl>;
}; };
cmu_apollo: clock-controller@11900000 { cmu_apollo: clock-controller@11900000 {
...@@ -384,6 +394,7 @@ Example 2: Examples of clock controller nodes are listed below. ...@@ -384,6 +394,7 @@ Example 2: Examples of clock controller nodes are listed below.
clocks = <&xxti>, clocks = <&xxti>,
<&cmu_top CLK_SCLK_JPEG_MSCL>, <&cmu_top CLK_SCLK_JPEG_MSCL>,
<&cmu_top CLK_ACLK_MSCL_400>; <&cmu_top CLK_ACLK_MSCL_400>;
power-domains = <&pd_mscl>;
}; };
cmu_mfc: clock-controller@15280000 { cmu_mfc: clock-controller@15280000 {
...@@ -393,6 +404,7 @@ Example 2: Examples of clock controller nodes are listed below. ...@@ -393,6 +404,7 @@ Example 2: Examples of clock controller nodes are listed below.
clock-names = "oscclk", "aclk_mfc_400"; clock-names = "oscclk", "aclk_mfc_400";
clocks = <&xxti>, <&cmu_top CLK_ACLK_MFC_400>; clocks = <&xxti>, <&cmu_top CLK_ACLK_MFC_400>;
power-domains = <&pd_mfc>;
}; };
cmu_hevc: clock-controller@14f80000 { cmu_hevc: clock-controller@14f80000 {
...@@ -402,6 +414,7 @@ Example 2: Examples of clock controller nodes are listed below. ...@@ -402,6 +414,7 @@ Example 2: Examples of clock controller nodes are listed below.
clock-names = "oscclk", "aclk_hevc_400"; clock-names = "oscclk", "aclk_hevc_400";
clocks = <&xxti>, <&cmu_top CLK_ACLK_HEVC_400>; clocks = <&xxti>, <&cmu_top CLK_ACLK_HEVC_400>;
power-domains = <&pd_hevc>;
}; };
cmu_isp: clock-controller@146d0000 { cmu_isp: clock-controller@146d0000 {
...@@ -415,6 +428,7 @@ Example 2: Examples of clock controller nodes are listed below. ...@@ -415,6 +428,7 @@ Example 2: Examples of clock controller nodes are listed below.
clocks = <&xxti>, clocks = <&xxti>,
<&cmu_top CLK_ACLK_ISP_DIS_400>, <&cmu_top CLK_ACLK_ISP_DIS_400>,
<&cmu_top CLK_ACLK_ISP_400>; <&cmu_top CLK_ACLK_ISP_400>;
power-domains = <&pd_isp>;
}; };
cmu_cam0: clock-controller@120d0000 { cmu_cam0: clock-controller@120d0000 {
...@@ -430,6 +444,7 @@ Example 2: Examples of clock controller nodes are listed below. ...@@ -430,6 +444,7 @@ Example 2: Examples of clock controller nodes are listed below.
<&cmu_top CLK_ACLK_CAM0_333>, <&cmu_top CLK_ACLK_CAM0_333>,
<&cmu_top CLK_ACLK_CAM0_400>, <&cmu_top CLK_ACLK_CAM0_400>,
<&cmu_top CLK_ACLK_CAM0_552>; <&cmu_top CLK_ACLK_CAM0_552>;
power-domains = <&pd_cam0>;
}; };
cmu_cam1: clock-controller@145d0000 { cmu_cam1: clock-controller@145d0000 {
...@@ -451,6 +466,7 @@ Example 2: Examples of clock controller nodes are listed below. ...@@ -451,6 +466,7 @@ Example 2: Examples of clock controller nodes are listed below.
<&cmu_top CLK_ACLK_CAM1_333>, <&cmu_top CLK_ACLK_CAM1_333>,
<&cmu_top CLK_ACLK_CAM1_400>, <&cmu_top CLK_ACLK_CAM1_400>,
<&cmu_top CLK_ACLK_CAM1_552>; <&cmu_top CLK_ACLK_CAM1_552>;
power-domains = <&pd_cam1>;
}; };
Example 3: UART controller node that consumes the clock generated by the clock Example 3: UART controller node that consumes the clock generated by the clock
......
This diff is collapsed.
...@@ -353,6 +353,12 @@ struct samsung_cmu_info { ...@@ -353,6 +353,12 @@ struct samsung_cmu_info {
/* list and number of clocks registers */ /* list and number of clocks registers */
const unsigned long *clk_regs; const unsigned long *clk_regs;
unsigned int nr_clk_regs; unsigned int nr_clk_regs;
/* list and number of clocks registers to set before suspend */
const struct samsung_clk_reg_dump *suspend_regs;
unsigned int nr_suspend_regs;
/* name of the parent clock needed for CMU register access */
const char *clk_name;
}; };
extern struct samsung_clk_provider *__init samsung_clk_init( extern struct samsung_clk_provider *__init samsung_clk_init(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment