clk: rockchip: only enter pll slow-mode directly before reboots on rk3288
As commit1d33929e2a("clk: rockchip: switch PLLs to slow mode before reboot for rk3288") states, switching the PLLs to slow-mode is only necessary when rebooting using the soft-reset done through the CRU. The dwc2 controllers used create really big number of interrupts in special constellations involving usb-hubs and their number is so high, it can even overwhelm the interrupt handler if the cpu-speed os to low. Right now the PLLs are put into slow-mode in a shutdown syscore_ops callback which means it happens on all reboots (not only the soft-reset ones) and even on poweroff actions. This can result in the system not powering off and getting stuck instead, so we should move the slow-mode change nearer to the actual reboot action. For this we introduce the possiblity to also set a callback that gets called from the restart-handler directly prior to restarting the system and move the shutdown-callback to this new option. With this the slow-mode switch is done only on the necessary reboots and also has a smaller possibility of causing artifacts. Fixes:1d33929e2a("clk: rockchip: switch PLLs to slow mode before reboot for rk3288") Signed-off-by: Heiko Stuebner <heiko.stuebner@collabora.com> Reviewed-by: Douglas Anderson <dianders@chromium.org>
This commit is contained in:
@@ -473,6 +473,6 @@ static void __init rk3036_clk_init(struct device_node *np)
|
|||||||
rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
|
rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
|
||||||
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
||||||
|
|
||||||
rockchip_register_restart_notifier(RK2928_GLB_SRST_FST);
|
rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL);
|
||||||
}
|
}
|
||||||
CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init);
|
CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init);
|
||||||
|
|||||||
@@ -750,7 +750,7 @@ static void __init rk3188_common_clk_init(struct device_node *np)
|
|||||||
rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
|
rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
|
||||||
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
||||||
|
|
||||||
rockchip_register_restart_notifier(RK2928_GLB_SRST_FST);
|
rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init rk3066a_clk_init(struct device_node *np)
|
static void __init rk3066a_clk_init(struct device_node *np)
|
||||||
|
|||||||
@@ -673,6 +673,6 @@ static void __init rk3228_clk_init(struct device_node *np)
|
|||||||
rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
|
rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
|
||||||
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
||||||
|
|
||||||
rockchip_register_restart_notifier(RK3228_GLB_SRST_FST);
|
rockchip_register_restart_notifier(RK3228_GLB_SRST_FST, NULL);
|
||||||
}
|
}
|
||||||
CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init);
|
CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init);
|
||||||
|
|||||||
@@ -848,7 +848,6 @@ static void rk3288_clk_shutdown(void)
|
|||||||
static struct syscore_ops rk3288_clk_syscore_ops = {
|
static struct syscore_ops rk3288_clk_syscore_ops = {
|
||||||
.suspend = rk3288_clk_suspend,
|
.suspend = rk3288_clk_suspend,
|
||||||
.resume = rk3288_clk_resume,
|
.resume = rk3288_clk_resume,
|
||||||
.shutdown = rk3288_clk_shutdown,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __init rk3288_clk_init(struct device_node *np)
|
static void __init rk3288_clk_init(struct device_node *np)
|
||||||
@@ -906,7 +905,8 @@ static void __init rk3288_clk_init(struct device_node *np)
|
|||||||
rk3288_cru_base + RK3288_SOFTRST_CON(0),
|
rk3288_cru_base + RK3288_SOFTRST_CON(0),
|
||||||
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
||||||
|
|
||||||
rockchip_register_restart_notifier(RK3288_GLB_SRST_FST);
|
rockchip_register_restart_notifier(RK3288_GLB_SRST_FST,
|
||||||
|
rk3288_clk_shutdown);
|
||||||
register_syscore_ops(&rk3288_clk_syscore_ops);
|
register_syscore_ops(&rk3288_clk_syscore_ops);
|
||||||
}
|
}
|
||||||
CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
|
CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
|
||||||
|
|||||||
@@ -889,6 +889,6 @@ static void __init rk3368_clk_init(struct device_node *np)
|
|||||||
rockchip_register_softrst(np, 15, reg_base + RK3368_SOFTRST_CON(0),
|
rockchip_register_softrst(np, 15, reg_base + RK3368_SOFTRST_CON(0),
|
||||||
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
||||||
|
|
||||||
rockchip_register_restart_notifier(RK3368_GLB_SRST_FST);
|
rockchip_register_restart_notifier(RK3368_GLB_SRST_FST, NULL);
|
||||||
}
|
}
|
||||||
CLK_OF_DECLARE(rk3368_cru, "rockchip,rk3368-cru", rk3368_clk_init);
|
CLK_OF_DECLARE(rk3368_cru, "rockchip,rk3368-cru", rk3368_clk_init);
|
||||||
|
|||||||
@@ -341,9 +341,13 @@ void __init rockchip_clk_protect_critical(const char *const clocks[],
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int reg_restart;
|
static unsigned int reg_restart;
|
||||||
|
static void (*cb_restart)(void);
|
||||||
static int rockchip_restart_notify(struct notifier_block *this,
|
static int rockchip_restart_notify(struct notifier_block *this,
|
||||||
unsigned long mode, void *cmd)
|
unsigned long mode, void *cmd)
|
||||||
{
|
{
|
||||||
|
if (cb_restart)
|
||||||
|
cb_restart();
|
||||||
|
|
||||||
writel(0xfdb9, reg_base + reg_restart);
|
writel(0xfdb9, reg_base + reg_restart);
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
}
|
}
|
||||||
@@ -353,11 +357,12 @@ static struct notifier_block rockchip_restart_handler = {
|
|||||||
.priority = 128,
|
.priority = 128,
|
||||||
};
|
};
|
||||||
|
|
||||||
void __init rockchip_register_restart_notifier(unsigned int reg)
|
void __init rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void))
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
reg_restart = reg;
|
reg_restart = reg;
|
||||||
|
cb_restart = cb;
|
||||||
ret = register_restart_handler(&rockchip_restart_handler);
|
ret = register_restart_handler(&rockchip_restart_handler);
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_err("%s: cannot register restart handler, %d\n",
|
pr_err("%s: cannot register restart handler, %d\n",
|
||||||
|
|||||||
@@ -503,7 +503,7 @@ void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name,
|
|||||||
const struct rockchip_cpuclk_rate_table *rates,
|
const struct rockchip_cpuclk_rate_table *rates,
|
||||||
int nrates);
|
int nrates);
|
||||||
void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
|
void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
|
||||||
void rockchip_register_restart_notifier(unsigned int reg);
|
void rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void));
|
||||||
|
|
||||||
#define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0)
|
#define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user