mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 21:07:02 +09:00
clk: sm1: add sm1 dsu clk notify for change dsu freq [1/1]
PD#SWPL-8145 Problem: dsu clk can't change freq Solution: add sm1 dsu clk notify Verify: sm1_skt Change-Id: If3ecf1066b49c07e6af69ce342956cb0469a5f87 Signed-off-by: Shunzhou Jiang <shunzhou.jiang@amlogic.com> Signed-off-by: Hong Guo <hong.guo@amlogic.com>
This commit is contained in:
committed by
Jianxin Pan
parent
1e43395b55
commit
efc28c832f
@@ -58,10 +58,14 @@
|
||||
cpu-idle-states = <&CPU_SLEEP_0>;
|
||||
clocks = <&clkc CLKID_CPU_CLK>,
|
||||
<&clkc CLKID_CPU_FCLK_P>,
|
||||
<&clkc CLKID_SYS_PLL>;
|
||||
<&clkc CLKID_SYS_PLL>,
|
||||
<&clkc CLKID_DSU_CLK>,
|
||||
<&clkc CLKID_DSU_PRE_CLK>;
|
||||
clock-names = "core_clk",
|
||||
"low_freq_clk_parent",
|
||||
"high_freq_clk_parent";
|
||||
"high_freq_clk_parent",
|
||||
"dsu_clk",
|
||||
"dsu_pre_parent";
|
||||
operating-points-v2 = <&cpu_opp_table0>;
|
||||
cpu-supply = <&vddcpu0>;
|
||||
voltage-tolerance = <0>;
|
||||
@@ -76,10 +80,14 @@
|
||||
cpu-idle-states = <&CPU_SLEEP_0>;
|
||||
clocks = <&clkc CLKID_CPU_CLK>,
|
||||
<&clkc CLKID_CPU_FCLK_P>,
|
||||
<&clkc CLKID_SYS_PLL>;
|
||||
<&clkc CLKID_SYS_PLL>,
|
||||
<&clkc CLKID_DSU_CLK>,
|
||||
<&clkc CLKID_DSU_PRE_CLK>;
|
||||
clock-names = "core_clk",
|
||||
"low_freq_clk_parent",
|
||||
"high_freq_clk_parent";
|
||||
"high_freq_clk_parent",
|
||||
"dsu_clk",
|
||||
"dsu_pre_parent";
|
||||
operating-points-v2 = <&cpu_opp_table0>;
|
||||
cpu-supply = <&vddcpu0>;
|
||||
voltage-tolerance = <0>;
|
||||
@@ -94,10 +102,14 @@
|
||||
cpu-idle-states = <&CPU_SLEEP_0>;
|
||||
clocks = <&clkc CLKID_CPU_CLK>,
|
||||
<&clkc CLKID_CPU_FCLK_P>,
|
||||
<&clkc CLKID_SYS_PLL>;
|
||||
<&clkc CLKID_SYS_PLL>,
|
||||
<&clkc CLKID_DSU_CLK>,
|
||||
<&clkc CLKID_DSU_PRE_CLK>;
|
||||
clock-names = "core_clk",
|
||||
"low_freq_clk_parent",
|
||||
"high_freq_clk_parent";
|
||||
"high_freq_clk_parent",
|
||||
"dsu_clk",
|
||||
"dsu_pre_parent";
|
||||
operating-points-v2 = <&cpu_opp_table0>;
|
||||
cpu-supply = <&vddcpu0>;
|
||||
voltage-tolerance = <0>;
|
||||
@@ -112,10 +124,14 @@
|
||||
cpu-idle-states = <&CPU_SLEEP_0>;
|
||||
clocks = <&clkc CLKID_CPU_CLK>,
|
||||
<&clkc CLKID_CPU_FCLK_P>,
|
||||
<&clkc CLKID_SYS_PLL>;
|
||||
<&clkc CLKID_SYS_PLL>,
|
||||
<&clkc CLKID_DSU_CLK>,
|
||||
<&clkc CLKID_DSU_PRE_CLK>;
|
||||
clock-names = "core_clk",
|
||||
"low_freq_clk_parent",
|
||||
"high_freq_clk_parent";
|
||||
"high_freq_clk_parent",
|
||||
"dsu_clk",
|
||||
"dsu_pre_parent";
|
||||
operating-points-v2 = <&cpu_opp_table0>;
|
||||
cpu-supply = <&vddcpu0>;
|
||||
voltage-tolerance = <0>;
|
||||
@@ -757,6 +773,7 @@
|
||||
compatible = "amlogic,sm1-clkc-2";
|
||||
#clock-cells = <1>;
|
||||
reg = <0x0 0x3dc>;
|
||||
own-dsu-clk;
|
||||
};
|
||||
};/* end of hiubus*/
|
||||
|
||||
|
||||
@@ -58,10 +58,14 @@
|
||||
cpu-idle-states = <&CPU_SLEEP_0>;
|
||||
clocks = <&clkc CLKID_CPU_CLK>,
|
||||
<&clkc CLKID_CPU_FCLK_P>,
|
||||
<&clkc CLKID_SYS_PLL>;
|
||||
<&clkc CLKID_SYS_PLL>,
|
||||
<&clkc CLKID_DSU_CLK>,
|
||||
<&clkc CLKID_DSU_PRE_CLK>;
|
||||
clock-names = "core_clk",
|
||||
"low_freq_clk_parent",
|
||||
"high_freq_clk_parent";
|
||||
"high_freq_clk_parent",
|
||||
"dsu_clk",
|
||||
"dsu_pre_parent";
|
||||
operating-points-v2 = <&cpu_opp_table0>;
|
||||
cpu-supply = <&vddcpu0>;
|
||||
voltage-tolerance = <0>;
|
||||
@@ -76,10 +80,14 @@
|
||||
cpu-idle-states = <&CPU_SLEEP_0>;
|
||||
clocks = <&clkc CLKID_CPU_CLK>,
|
||||
<&clkc CLKID_CPU_FCLK_P>,
|
||||
<&clkc CLKID_SYS_PLL>;
|
||||
<&clkc CLKID_SYS_PLL>,
|
||||
<&clkc CLKID_DSU_CLK>,
|
||||
<&clkc CLKID_DSU_PRE_CLK>;
|
||||
clock-names = "core_clk",
|
||||
"low_freq_clk_parent",
|
||||
"high_freq_clk_parent";
|
||||
"high_freq_clk_parent",
|
||||
"dsu_clk",
|
||||
"dsu_pre_parent";
|
||||
operating-points-v2 = <&cpu_opp_table0>;
|
||||
cpu-supply = <&vddcpu0>;
|
||||
voltage-tolerance = <0>;
|
||||
@@ -94,10 +102,14 @@
|
||||
cpu-idle-states = <&CPU_SLEEP_0>;
|
||||
clocks = <&clkc CLKID_CPU_CLK>,
|
||||
<&clkc CLKID_CPU_FCLK_P>,
|
||||
<&clkc CLKID_SYS_PLL>;
|
||||
<&clkc CLKID_SYS_PLL>,
|
||||
<&clkc CLKID_DSU_CLK>,
|
||||
<&clkc CLKID_DSU_PRE_CLK>;
|
||||
clock-names = "core_clk",
|
||||
"low_freq_clk_parent",
|
||||
"high_freq_clk_parent";
|
||||
"high_freq_clk_parent",
|
||||
"dsu_clk",
|
||||
"dsu_pre_parent";
|
||||
operating-points-v2 = <&cpu_opp_table0>;
|
||||
cpu-supply = <&vddcpu0>;
|
||||
voltage-tolerance = <0>;
|
||||
@@ -112,10 +124,14 @@
|
||||
cpu-idle-states = <&CPU_SLEEP_0>;
|
||||
clocks = <&clkc CLKID_CPU_CLK>,
|
||||
<&clkc CLKID_CPU_FCLK_P>,
|
||||
<&clkc CLKID_SYS_PLL>;
|
||||
<&clkc CLKID_SYS_PLL>,
|
||||
<&clkc CLKID_DSU_CLK>,
|
||||
<&clkc CLKID_DSU_PRE_CLK>;
|
||||
clock-names = "core_clk",
|
||||
"low_freq_clk_parent",
|
||||
"high_freq_clk_parent";
|
||||
"high_freq_clk_parent",
|
||||
"dsu_clk",
|
||||
"dsu_pre_parent";
|
||||
operating-points-v2 = <&cpu_opp_table0>;
|
||||
cpu-supply = <&vddcpu0>;
|
||||
voltage-tolerance = <0>;
|
||||
@@ -757,6 +773,7 @@
|
||||
compatible = "amlogic,sm1-clkc-2";
|
||||
#clock-cells = <1>;
|
||||
reg = <0x0 0x0 0x0 0x3dc>;
|
||||
own-dsu-clk;
|
||||
};
|
||||
};/* end of hiubus*/
|
||||
|
||||
|
||||
@@ -1028,19 +1028,6 @@ static void __init g12a_clkc_init(struct device_node *np)
|
||||
goto iounmap;
|
||||
}
|
||||
|
||||
if (of_property_read_bool(np, "own-dsu-clk")) {
|
||||
if (clks[CLKID_DSU_CLK]) {
|
||||
clk_set_parent(clks[CLKID_DSU_CLK],
|
||||
clks[CLKID_CPU_CLK]);
|
||||
/* set sm1_dsu_pre_clk to 1.5G, gp1 pll is 1.5G */
|
||||
clk_set_rate(clks[CLKID_DSU_PRE_CLK], 1500000000);
|
||||
clk_prepare_enable(clks[CLKID_DSU_PRE_CLK]);
|
||||
/* set sm1_dsu_pre_clk as dsu_pre's parent */
|
||||
clk_set_parent(clks[CLKID_DSU_CLK],
|
||||
clks[CLKID_DSU_PRE_CLK]);
|
||||
}
|
||||
}
|
||||
|
||||
pr_debug("%s: cpu clk register notifier ok!", __func__);
|
||||
|
||||
ret = of_clk_add_provider(np, of_clk_src_onecell_get,
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "../clkc.h"
|
||||
#include "../g12a/g12a.h"
|
||||
#include "sm1.h"
|
||||
#include <linux/delay.h>
|
||||
|
||||
static struct meson_clk_pll sm1_gp1_pll = {
|
||||
.m = {
|
||||
@@ -244,7 +245,7 @@ static struct clk_mux sm1_dsu_pre_src_clk_mux0 = {
|
||||
.parent_names = (const char *[]){ "xtal", "fclk_div2",
|
||||
"fclk_div3", "gp1_pll" },
|
||||
.num_parents = 4,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -259,7 +260,7 @@ static struct clk_mux sm1_dsu_pre_src_clk_mux1 = {
|
||||
.parent_names = (const char *[]){ "xtal", "fclk_div2",
|
||||
"fclk_div3", "gp1_pll" },
|
||||
.num_parents = 4,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -423,12 +424,53 @@ static struct clk_hw *sm1_clk_hws[] = {
|
||||
&sm1_csi_phy.hw,
|
||||
};
|
||||
|
||||
struct sm1_nb_data {
|
||||
struct notifier_block nb;
|
||||
};
|
||||
|
||||
static int sm1_dsu_mux_clk_notifier_cb(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
struct clk *dsu_pre_clk, *parent_clk;
|
||||
int ret;
|
||||
|
||||
switch (event) {
|
||||
case PRE_RATE_CHANGE:
|
||||
/* switch to sm1_dsu_fixed_sel1, set it to 1G (default 24M) */
|
||||
ret = clk_set_rate(sm1_dsu_pre_clk_mux1.hw.clk, 1000000000);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
parent_clk = sm1_dsu_pre_clk_mux1.hw.clk;
|
||||
break;
|
||||
case POST_RATE_CHANGE:
|
||||
parent_clk = sm1_dsu_pre_clk_mux0.hw.clk;
|
||||
break;
|
||||
default:
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
dsu_pre_clk = sm1_dsu_pre_post_clk_mux.hw.clk;
|
||||
|
||||
ret = clk_set_parent(dsu_pre_clk, parent_clk);
|
||||
if (ret)
|
||||
return notifier_from_errno(ret);
|
||||
|
||||
usleep_range(80, 120);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct sm1_nb_data sm1_dsu_nb_data = {
|
||||
.nb.notifier_call = sm1_dsu_mux_clk_notifier_cb,
|
||||
};
|
||||
|
||||
static void __init sm1_clkc_init(struct device_node *np)
|
||||
{
|
||||
int ret = 0, clkid, i;
|
||||
|
||||
if (!clk_base)
|
||||
clk_base = of_iomap(np, 0);
|
||||
|
||||
if (!clk_base) {
|
||||
pr_err("%s: Unable to map clk base\n", __func__);
|
||||
return;
|
||||
@@ -560,17 +602,20 @@ static void __init sm1_clkc_init(struct device_node *np)
|
||||
panic("%s: %d register cts_csi_adapt_clk_composite error\n",
|
||||
__func__, __LINE__);
|
||||
|
||||
if (clks[CLKID_CPU_CLK]) {
|
||||
if (!of_property_read_bool(np, "own-dsu-clk"))
|
||||
return;
|
||||
/* set cpu clk as dsu_clk's parent*/
|
||||
clk_set_parent(sm1_dsu_clk.hw.clk, clks[CLKID_CPU_CLK]);
|
||||
/* set sm1_dsu_pre_clk to 1.5G, gp1 pll is 1.5G */
|
||||
clk_set_rate(sm1_dsu_pre_clk.hw.clk, 1500000000);
|
||||
clk_prepare_enable(sm1_dsu_pre_clk.hw.clk);
|
||||
/* set sm1_dsu_pre_clk as dsu_clk's parent */
|
||||
clk_set_parent(sm1_dsu_clk.hw.clk, sm1_dsu_pre_clk.hw.clk);
|
||||
if (of_property_read_bool(np, "own-dsu-clk")) {
|
||||
/*
|
||||
* when change sm1_dsu_pre_clk_mux0, switch to
|
||||
* sm1_dsu_pre_clk_mux1 to avoid crash
|
||||
*/
|
||||
ret = clk_notifier_register(sm1_dsu_pre_clk_mux0.hw.clk,
|
||||
&sm1_dsu_nb_data.nb);
|
||||
if (ret) {
|
||||
pr_err("%s: failed to register clock notifier for cpu_clk\n",
|
||||
__func__);
|
||||
goto iounmap;
|
||||
}
|
||||
}
|
||||
pr_err("sm1 clk probe ok\n");
|
||||
return;
|
||||
|
||||
iounmap:
|
||||
@@ -579,5 +624,3 @@ iounmap:
|
||||
}
|
||||
|
||||
CLK_OF_DECLARE(sm1, "amlogic,sm1-clkc-2", sm1_clkc_init);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user