Skip to content

Commit

Permalink
Merge tag 'samsung-fixes-3' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/kgene/linux-samsung into fixes

Merge "Samsung fixes-3 for 3.16" from Kukjin Kim:

Samsung fixes-3 for v3.16
- update the parent for Auudss clock because kernel will be hang
  during late boot if the parent clock is disabled in bootloader.
- enable clk handing in power domain because while power domain
  on/off, its regarding clock source will be reset and it causes
  a problem so need to handle it.
- add mux clocks to be used by power domain for exynos5420-mfc
  during power domain on/off and property in device tree also.
- register cpuidle only for exynos4210 and exynos5250 because a
  system failure will be happened on other exynos SoCs.

* tag 'samsung-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung:
  ARM: EXYNOS: Register cpuidle device only on exynos4210 and 5250
  ARM: dts: Add clock property for mfc_pd in exynos5420
  clk: exynos5420: Add IDs for clocks used in PD mfc
  ARM: EXYNOS: Add support for clock handling in power domain
  ARM: dts: Update the parent for Audss clocks in Exynos5420

Signed-off-by: Olof Johansson <[email protected]>
  • Loading branch information
olofj committed Jul 13, 2014
2 parents 363d4dd + bed7118 commit cacadb4
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 8 deletions.
20 changes: 20 additions & 0 deletions Documentation/devicetree/bindings/arm/exynos/power_domain.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@ Required Properties:
- reg: physical base address of the controller and length of memory mapped
region.

Optional Properties:
- clocks: List of clock handles. The parent clocks of the input clocks to the
devices in this power domain are set to oscclk before power gating
and restored back after powering on a domain. This is required for
all domains which are powered on and off and not required for unused
domains.
- clock-names: The following clocks can be specified:
- oscclk: Oscillator clock.
- pclkN, clkN: Pairs of parent of input clock and input clock to the
devices in this power domain. Maximum of 4 pairs (N = 0 to 3)
are supported currently.

Node of a device using power domains must have a samsung,power-domain property
defined with a phandle to respective power domain.

Expand All @@ -19,6 +31,14 @@ Example:
reg = <0x10023C00 0x10>;
};

mfc_pd: power-domain@10044060 {
compatible = "samsung,exynos4210-pd";
reg = <0x10044060 0x20>;
clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_SW_ACLK333>,
<&clock CLK_MOUT_USER_ACLK333>;
clock-names = "oscclk", "pclk0", "clk0";
};

Example of the node using power domain:

node {
Expand Down
5 changes: 4 additions & 1 deletion arch/arm/boot/dts/exynos5420.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@
compatible = "samsung,exynos5420-audss-clock";
reg = <0x03810000 0x0C>;
#clock-cells = <1>;
clocks = <&clock CLK_FIN_PLL>, <&clock CLK_FOUT_EPLL>,
clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MAU_EPLL>,
<&clock CLK_SCLK_MAUDIO0>, <&clock CLK_SCLK_MAUPCM0>;
clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in";
};
Expand Down Expand Up @@ -260,6 +260,9 @@
mfc_pd: power-domain@10044060 {
compatible = "samsung,exynos4210-pd";
reg = <0x10044060 0x20>;
clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_SW_ACLK333>,
<&clock CLK_MOUT_USER_ACLK333>;
clock-names = "oscclk", "pclk0", "clk0";
};

disp_pd: power-domain@100440C0 {
Expand Down
6 changes: 2 additions & 4 deletions arch/arm/mach-exynos/exynos.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,8 @@ static struct platform_device exynos_cpuidle = {

void __init exynos_cpuidle_init(void)
{
if (soc_is_exynos5440())
return;

platform_device_register(&exynos_cpuidle);
if (soc_is_exynos4210() || soc_is_exynos5250())
platform_device_register(&exynos_cpuidle);
}

void __init exynos_cpufreq_init(void)
Expand Down
61 changes: 60 additions & 1 deletion arch/arm/mach-exynos/pm_domains.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/pm_domain.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/sched.h>

#include "regs-pmu.h"

#define MAX_CLK_PER_DOMAIN 4

/*
* Exynos specific wrapper around the generic power domain
*/
Expand All @@ -32,6 +35,9 @@ struct exynos_pm_domain {
char const *name;
bool is_off;
struct generic_pm_domain pd;
struct clk *oscclk;
struct clk *clk[MAX_CLK_PER_DOMAIN];
struct clk *pclk[MAX_CLK_PER_DOMAIN];
};

static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
Expand All @@ -44,6 +50,19 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
pd = container_of(domain, struct exynos_pm_domain, pd);
base = pd->base;

/* Set oscclk before powering off a domain*/
if (!power_on) {
int i;

for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
if (IS_ERR(pd->clk[i]))
break;
if (clk_set_parent(pd->clk[i], pd->oscclk))
pr_err("%s: error setting oscclk as parent to clock %d\n",
pd->name, i);
}
}

pwr = power_on ? S5P_INT_LOCAL_PWR_EN : 0;
__raw_writel(pwr, base);

Expand All @@ -60,6 +79,20 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
cpu_relax();
usleep_range(80, 100);
}

/* Restore clocks after powering on a domain*/
if (power_on) {
int i;

for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
if (IS_ERR(pd->clk[i]))
break;
if (clk_set_parent(pd->clk[i], pd->pclk[i]))
pr_err("%s: error setting parent to clock%d\n",
pd->name, i);
}
}

return 0;
}

Expand Down Expand Up @@ -152,9 +185,11 @@ static __init int exynos4_pm_init_power_domain(void)

for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
struct exynos_pm_domain *pd;
int on;
int on, i;
struct device *dev;

pdev = of_find_device_by_node(np);
dev = &pdev->dev;

pd = kzalloc(sizeof(*pd), GFP_KERNEL);
if (!pd) {
Expand All @@ -170,6 +205,30 @@ static __init int exynos4_pm_init_power_domain(void)
pd->pd.power_on = exynos_pd_power_on;
pd->pd.of_node = np;

pd->oscclk = clk_get(dev, "oscclk");
if (IS_ERR(pd->oscclk))
goto no_clk;

for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
char clk_name[8];

snprintf(clk_name, sizeof(clk_name), "clk%d", i);
pd->clk[i] = clk_get(dev, clk_name);
if (IS_ERR(pd->clk[i]))
break;
snprintf(clk_name, sizeof(clk_name), "pclk%d", i);
pd->pclk[i] = clk_get(dev, clk_name);
if (IS_ERR(pd->pclk[i])) {
clk_put(pd->clk[i]);
pd->clk[i] = ERR_PTR(-EINVAL);
break;
}
}

if (IS_ERR(pd->clk[0]))
clk_put(pd->oscclk);

no_clk:
platform_set_drvdata(pdev, pd);

on = __raw_readl(pd->base + 0x4) & S5P_INT_LOCAL_PWR_EN;
Expand Down
6 changes: 4 additions & 2 deletions drivers/clk/samsung/clk-exynos5420.c
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,8 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
SRC_TOP4, 16, 1),
MUX(0, "mout_user_aclk266", mout_user_aclk266_p, SRC_TOP4, 20, 1),
MUX(0, "mout_user_aclk166", mout_user_aclk166_p, SRC_TOP4, 24, 1),
MUX(0, "mout_user_aclk333", mout_user_aclk333_p, SRC_TOP4, 28, 1),
MUX(CLK_MOUT_USER_ACLK333, "mout_user_aclk333", mout_user_aclk333_p,
SRC_TOP4, 28, 1),

MUX(0, "mout_user_aclk400_disp1", mout_user_aclk400_disp1_p,
SRC_TOP5, 0, 1),
Expand Down Expand Up @@ -684,7 +685,8 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
SRC_TOP11, 12, 1),
MUX(0, "mout_sw_aclk266", mout_sw_aclk266_p, SRC_TOP11, 20, 1),
MUX(0, "mout_sw_aclk166", mout_sw_aclk166_p, SRC_TOP11, 24, 1),
MUX(0, "mout_sw_aclk333", mout_sw_aclk333_p, SRC_TOP11, 28, 1),
MUX(CLK_MOUT_SW_ACLK333, "mout_sw_aclk333", mout_sw_aclk333_p,
SRC_TOP11, 28, 1),

MUX(0, "mout_sw_aclk400_disp1", mout_sw_aclk400_disp1_p,
SRC_TOP12, 4, 1),
Expand Down
2 changes: 2 additions & 0 deletions include/dt-bindings/clock/exynos5420.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@
#define CLK_MOUT_G3D 641
#define CLK_MOUT_VPLL 642
#define CLK_MOUT_MAUDIO0 643
#define CLK_MOUT_USER_ACLK333 644
#define CLK_MOUT_SW_ACLK333 645

/* divider clocks */
#define CLK_DOUT_PIXEL 768
Expand Down

0 comments on commit cacadb4

Please sign in to comment.