[PATCH] clk: bcm2835: Do not use prediv with bcm2711's PLLs

From: Nicolas Saenz Julienne
Date: Thu Jul 30 2020 - 10:13:47 EST


Contrary to previous SoCs, bcm2711 doesn't have a prescaler in the PLL
feedback loop. Bypass it by zeroing fb_prediv_mask.

Note that, since the prediv configuration bits were re-purposed, this
was triggering a miscalculation on all clock hanging from the VPU clock,
notably the aux UART, making its output unintelligible.

Fixes: 42de9ad400af ("clk: bcm2835: Add BCM2711_CLOCK_EMMC2 support")
Reported-by: Nathan Chancellor <natechancellor@xxxxxxxxx>
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@xxxxxxx>
---

FYI relevant discussion with RPi engineers:
https://github.com/raspberrypi/firmware/issues/1435#issuecomment-666242077

drivers/clk/bcm/clk-bcm2835.c | 79 +++++++++++++++++++++++++++++++++--
1 file changed, 75 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 027eba31f793..acf499d26263 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -454,6 +454,16 @@ static const struct bcm2835_pll_ana_bits bcm2835_ana_default = {
.fb_prediv_mask = BIT(14),
};

+static const struct bcm2835_pll_ana_bits bcm2711_ana_default = {
+ .mask0 = 0,
+ .set0 = 0,
+ .mask1 = A2W_PLL_KI_MASK | A2W_PLL_KP_MASK,
+ .set1 = (2 << A2W_PLL_KI_SHIFT) | (8 << A2W_PLL_KP_SHIFT),
+ .mask3 = A2W_PLL_KA_MASK,
+ .set3 = (2 << A2W_PLL_KA_SHIFT),
+ .fb_prediv_mask = 0, /* No prediv in bcm2711 */
+};
+
static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = {
.mask0 = A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK,
.set0 = (2 << A2W_PLLH_KA_SHIFT) | (2 << A2W_PLLH_KI_LOW_SHIFT),
@@ -1631,7 +1641,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* AUDIO domain is on.
*/
[BCM2835_PLLA] = REGISTER_PLL(
- SOC_ALL,
+ SOC_BCM2835,
.name = "plla",
.cm_ctrl_reg = CM_PLLA,
.a2w_ctrl_reg = A2W_PLLA_CTRL,
@@ -1642,6 +1652,21 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {

.ana = &bcm2835_ana_default,

+ .min_rate = 600000000u,
+ .max_rate = 2400000000u,
+ .max_fb_rate = BCM2835_MAX_FB_RATE),
+ [BCM2835_PLLA] = REGISTER_PLL(
+ SOC_BCM2711,
+ .name = "plla",
+ .cm_ctrl_reg = CM_PLLA,
+ .a2w_ctrl_reg = A2W_PLLA_CTRL,
+ .frac_reg = A2W_PLLA_FRAC,
+ .ana_reg_base = A2W_PLLA_ANA0,
+ .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE,
+ .lock_mask = CM_LOCK_FLOCKA,
+
+ .ana = &bcm2711_ana_default,
+
.min_rate = 600000000u,
.max_rate = 2400000000u,
.max_fb_rate = BCM2835_MAX_FB_RATE),
@@ -1687,7 +1712,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {

/* PLLB is used for the ARM's clock. */
[BCM2835_PLLB] = REGISTER_PLL(
- SOC_ALL,
+ SOC_BCM2835,
.name = "pllb",
.cm_ctrl_reg = CM_PLLB,
.a2w_ctrl_reg = A2W_PLLB_CTRL,
@@ -1698,6 +1723,22 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {

.ana = &bcm2835_ana_default,

+ .min_rate = 600000000u,
+ .max_rate = 3000000000u,
+ .max_fb_rate = BCM2835_MAX_FB_RATE,
+ .flags = CLK_GET_RATE_NOCACHE),
+ [BCM2835_PLLB] = REGISTER_PLL(
+ SOC_BCM2711,
+ .name = "pllb",
+ .cm_ctrl_reg = CM_PLLB,
+ .a2w_ctrl_reg = A2W_PLLB_CTRL,
+ .frac_reg = A2W_PLLB_FRAC,
+ .ana_reg_base = A2W_PLLB_ANA0,
+ .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
+ .lock_mask = CM_LOCK_FLOCKB,
+
+ .ana = &bcm2711_ana_default,
+
.min_rate = 600000000u,
.max_rate = 3000000000u,
.max_fb_rate = BCM2835_MAX_FB_RATE,
@@ -1720,7 +1761,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* AUDIO domain is on.
*/
[BCM2835_PLLC] = REGISTER_PLL(
- SOC_ALL,
+ SOC_BCM2835,
.name = "pllc",
.cm_ctrl_reg = CM_PLLC,
.a2w_ctrl_reg = A2W_PLLC_CTRL,
@@ -1731,6 +1772,21 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {

.ana = &bcm2835_ana_default,

+ .min_rate = 600000000u,
+ .max_rate = 3000000000u,
+ .max_fb_rate = BCM2835_MAX_FB_RATE),
+ [BCM2835_PLLC] = REGISTER_PLL(
+ SOC_BCM2711,
+ .name = "pllc",
+ .cm_ctrl_reg = CM_PLLC,
+ .a2w_ctrl_reg = A2W_PLLC_CTRL,
+ .frac_reg = A2W_PLLC_FRAC,
+ .ana_reg_base = A2W_PLLC_ANA0,
+ .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
+ .lock_mask = CM_LOCK_FLOCKC,
+
+ .ana = &bcm2711_ana_default,
+
.min_rate = 600000000u,
.max_rate = 3000000000u,
.max_fb_rate = BCM2835_MAX_FB_RATE),
@@ -1782,7 +1838,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* AUDIO domain is on.
*/
[BCM2835_PLLD] = REGISTER_PLL(
- SOC_ALL,
+ SOC_BCM2835,
.name = "plld",
.cm_ctrl_reg = CM_PLLD,
.a2w_ctrl_reg = A2W_PLLD_CTRL,
@@ -1793,6 +1849,21 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {

.ana = &bcm2835_ana_default,

+ .min_rate = 600000000u,
+ .max_rate = 2400000000u,
+ .max_fb_rate = BCM2835_MAX_FB_RATE),
+ [BCM2835_PLLD] = REGISTER_PLL(
+ SOC_BCM2711,
+ .name = "plld",
+ .cm_ctrl_reg = CM_PLLD,
+ .a2w_ctrl_reg = A2W_PLLD_CTRL,
+ .frac_reg = A2W_PLLD_FRAC,
+ .ana_reg_base = A2W_PLLD_ANA0,
+ .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE,
+ .lock_mask = CM_LOCK_FLOCKD,
+
+ .ana = &bcm2711_ana_default,
+
.min_rate = 600000000u,
.max_rate = 2400000000u,
.max_fb_rate = BCM2835_MAX_FB_RATE),
--
2.27.0