From 3326ccc11648e5ff482102ec401b22cc795006ae Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Sat, 11 Aug 2018 11:11:10 +0200 Subject: [PATCH] Allwinner H3 - address some stability issues --- ...ard-h3-address-some-stability-issues.patch | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 patch/kernel/sunxi-next/board-h3-address-some-stability-issues.patch diff --git a/patch/kernel/sunxi-next/board-h3-address-some-stability-issues.patch b/patch/kernel/sunxi-next/board-h3-address-some-stability-issues.patch new file mode 100644 index 0000000000..344c4fe198 --- /dev/null +++ b/patch/kernel/sunxi-next/board-h3-address-some-stability-issues.patch @@ -0,0 +1,151 @@ +From 8477a566b36aaae77e53a9949f963ce6ebad55fe Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Thu, 12 Jan 2017 16:34:57 +0100 +Subject: [PATCH] clk: sunxi-ng: Set maximum M = 1 for H3 pll-cpux clock + +When using M factor greater than 1 system is experiencing +occasional lockups. + +This change was verified to fix lockups with PLL stress +tester available at https://github.com/megous/h3-firmware. + +Note that M factor must not be used outside the kernel +either, so for example u-boot needs a similar patch. +--- + drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 24 +++++++++++++++--------- + 1 file changed, 15 insertions(+), 9 deletions(-) + +diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +index 77ed0b0ba6819..8d47742def49d 100644 +--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c ++++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +@@ -30,15 +30,21 @@ + + #include "ccu-sun8i-h3.h" + +-static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpux_clk, "pll-cpux", +- "osc24M", 0x000, +- 8, 5, /* N */ +- 4, 2, /* K */ +- 0, 2, /* M */ +- 16, 2, /* P */ +- BIT(31), /* gate */ +- BIT(28), /* lock */ +- CLK_SET_RATE_UNGATE); ++static struct ccu_nkmp pll_cpux_clk = { ++ .enable = BIT(31), ++ .lock = BIT(28), ++ .n = _SUNXI_CCU_MULT(8, 5), ++ .k = _SUNXI_CCU_MULT(4, 2), ++ .m = _SUNXI_CCU_DIV_MAX(0, 2, 1), ++ .p = _SUNXI_CCU_DIV(16, 2), ++ .common = { ++ .reg = 0x000, ++ .hw.init = CLK_HW_INIT("pll-cpux", ++ "osc24M", ++ &ccu_nkmp_ops, ++ CLK_SET_RATE_UNGATE), ++ }, ++}; + + /* + * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from +From c313a0ac340bf1131d475527171764dc49901895 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Wed, 5 Apr 2017 15:43:48 +0200 +Subject: [PATCH] clk: sunxi-ng: Limit pll_cpux P factor for rates > 288MHz on + H3 + +Datasheet for H3 mandates that CPUX PLL must not use postdivider +(P factor must be 1) for clock rates above 288MHz. + +Signed-off-by: Ondrej Jirman +--- + drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +index 8d47742def49d..7cc9467f373f2 100644 +--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c ++++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +@@ -37,6 +37,7 @@ static struct ccu_nkmp pll_cpux_clk = { + .k = _SUNXI_CCU_MULT(4, 2), + .m = _SUNXI_CCU_DIV_MAX(0, 2, 1), + .p = _SUNXI_CCU_DIV(16, 2), ++ .max_rate_for_p = 288000000, + .common = { + .reg = 0x000, + .hw.init = CLK_HW_INIT("pll-cpux", +From f07a20e4ce93e7e0f333f9f6e57f14fd4ab66abd Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Thu, 12 Jan 2017 16:37:24 +0100 +Subject: [PATCH] clk: sunxi-ng: Allow to limit the use of NKMP clock's P + factor + +Some SoCs mandate the maximum clock rate for which the use +of postdivider P factor is allowed. Allow to configure maximum +clock rate. + +Signed-off-by: Ondrej Jirman +--- + drivers/clk/sunxi-ng/ccu_nkmp.c | 13 ++++++++----- + drivers/clk/sunxi-ng/ccu_nkmp.h | 1 + + 2 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c +index ebd9436d2c7cd..96dbc543b2cbc 100644 +--- a/drivers/clk/sunxi-ng/ccu_nkmp.c ++++ b/drivers/clk/sunxi-ng/ccu_nkmp.c +@@ -33,16 +33,19 @@ static unsigned long ccu_nkmp_calc_rate(unsigned long parent, + } + + static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate, +- struct _ccu_nkmp *nkmp) ++ struct _ccu_nkmp *nkmp, struct ccu_nkmp *_nkmp) + { + unsigned long best_rate = 0; + unsigned long best_n = 0, best_k = 0, best_m = 0, best_p = 0; +- unsigned long _n, _k, _m, _p; ++ unsigned long _n, _k, _m, _p, _max_p; ++ ++ _max_p = (_nkmp->max_rate_for_p == 0 || rate <= _nkmp->max_rate_for_p) ? ++ nkmp->max_p : nkmp->min_p; + + for (_k = nkmp->min_k; _k <= nkmp->max_k; _k++) { + for (_n = nkmp->min_n; _n <= nkmp->max_n; _n++) { + for (_m = nkmp->min_m; _m <= nkmp->max_m; _m++) { +- for (_p = nkmp->min_p; _p <= nkmp->max_p; _p <<= 1) { ++ for (_p = nkmp->min_p; _p <= _max_p; _p <<= 1) { + unsigned long tmp_rate; + + tmp_rate = ccu_nkmp_calc_rate(parent, +@@ -146,7 +149,7 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, + _nkmp.min_p = 1; + _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1); + +- ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); ++ ccu_nkmp_find_best(*parent_rate, rate, &_nkmp, nkmp); + + rate = ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, + _nkmp.m, _nkmp.p); +@@ -177,7 +180,7 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, + _nkmp.min_p = 1; + _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1); + +- ccu_nkmp_find_best(parent_rate, rate, &_nkmp); ++ ccu_nkmp_find_best(parent_rate, rate, &_nkmp, nkmp); + + n_mask = GENMASK(nkmp->n.width + nkmp->n.shift - 1, nkmp->n.shift); + k_mask = GENMASK(nkmp->k.width + nkmp->k.shift - 1, nkmp->k.shift); +diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.h b/drivers/clk/sunxi-ng/ccu_nkmp.h +index 6940503e7fc46..bbea3e5ed6fba 100644 +--- a/drivers/clk/sunxi-ng/ccu_nkmp.h ++++ b/drivers/clk/sunxi-ng/ccu_nkmp.h +@@ -33,6 +33,7 @@ struct ccu_nkmp { + struct ccu_mult_internal k; + struct ccu_div_internal m; + struct ccu_div_internal p; ++ unsigned long max_rate_for_p; + + unsigned int fixed_post_div; +