From 6c5422851d8be8c7451e968fd2e6da41b6109e17 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 26 Sep 2022 10:45:09 +0200 Subject: clk: bcm2835: Make peripheral PLLC critical MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When testing for a series affecting the VEC, it was discovered that turning off and on the VEC clock is crashing the system. It turns out that, when disabling the VEC clock, it's the only child of the PLLC-per clock which will also get disabled. The source of the crash is PLLC-per being disabled. It's likely that some other device might not take a clock reference that it actually needs, but it's unclear which at this point. Let's make PLLC-per critical so that we don't have that crash. Reported-by: Noralf Trønnes Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20220926084509.12233-1-maxime@cerno.tech Reviewed-by: Stefan Wahren Acked-by: Noralf Trønnes Signed-off-by: Stephen Boyd --- drivers/clk/bcm/clk-bcm2835.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clk/bcm') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 48a1eb9f2d55..19de0e83b65d 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1784,7 +1784,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .load_mask = CM_PLLC_LOADPER, .hold_mask = CM_PLLC_HOLDPER, .fixed_divider = 1, - .flags = CLK_SET_RATE_PARENT), + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), /* * PLLD is the display PLL, used to drive DSI display panels. -- cgit v1.2.3 From f690a4d7a8f66430662975511c86819dc9965bcc Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 12 Sep 2022 11:13:04 +0300 Subject: clk: bcm2835: Round UART input clock up It was reported that RPi3[1] and RPi Zero 2W boards have issues with the Bluetooth. It turns out that when switching from initial to operation speed host and device no longer can talk each other because host uses incorrect UART baud rate. The UART driver used in this case is amba-pl011. Original fix, see below Github link[2], was inside pl011 module, but somehow it didn't look as the right place to fix. Beside that this original rounding function is not exactly perfect for all possible clock values. So I deiced to move the hack to the platform which actually need it. The UART clock is initialised to be as close to the requested frequency as possible without exceeding it. Now that there is a clock manager that returns the actual frequencies, an expected 48MHz clock is reported as 47999625. If the requested baud rate == requested clock/16, there is no headroom and the slight reduction in actual clock rate results in failure. If increasing a clock by less than 0.1% changes it from ..999.. to ..000.., round it up. [1] https://bugzilla.suse.com/show_bug.cgi?id=1188238 [2] https://github.com/raspberrypi/linux/commit/ab3f1b39537f6d3825b8873006fbe2fc5ff057b7 Cc: Phil Elwell Signed-off-by: Ivan T. Ivanov Reviewed-by: Stefan Wahren Link: https://lore.kernel.org/r/20220912081306.24662-1-iivanov@suse.de Signed-off-by: Stephen Boyd --- drivers/clk/bcm/clk-bcm2835.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'drivers/clk/bcm') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 19de0e83b65d..3f2ce20d27ec 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -502,6 +503,8 @@ struct bcm2835_clock_data { bool low_jitter; u32 tcnt_mux; + + bool round_up; }; struct bcm2835_gate_data { @@ -993,12 +996,34 @@ static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, return temp; } +static unsigned long bcm2835_round_rate(unsigned long rate) +{ + unsigned long scaler; + unsigned long limit; + + limit = rate / 100000; + + scaler = 1; + while (scaler < limit) + scaler *= 10; + + /* + * If increasing a clock by less than 0.1% changes it + * from ..999.. to ..000.., round up. + */ + if ((rate + scaler - 1) / scaler % 1000 == 0) + rate = roundup(rate, scaler); + + return rate; +} + static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw, unsigned long parent_rate) { struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); struct bcm2835_cprman *cprman = clock->cprman; const struct bcm2835_clock_data *data = clock->data; + unsigned long rate; u32 div; if (data->int_bits == 0 && data->frac_bits == 0) @@ -1006,7 +1031,12 @@ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw, div = cprman_read(cprman, data->div_reg); - return bcm2835_clock_rate_from_divisor(clock, parent_rate, div); + rate = bcm2835_clock_rate_from_divisor(clock, parent_rate, div); + + if (data->round_up) + rate = bcm2835_round_rate(rate); + + return rate; } static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock) @@ -2143,7 +2173,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .div_reg = CM_UARTDIV, .int_bits = 10, .frac_bits = 12, - .tcnt_mux = 28), + .tcnt_mux = 28, + .round_up = true), /* TV encoder clock. Only operating frequency is 108Mhz. */ [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK( -- cgit v1.2.3 From 0b919a3728691c172312dee99ba654055ccd8c84 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sun, 4 Sep 2022 16:10:37 +0200 Subject: clk: bcm2835: fix bcm2835_clock_rate_from_divisor declaration The return value of bcm2835_clock_rate_from_divisor is always unsigned and also all caller expect this. So fix the declaration accordingly. Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks") Signed-off-by: Stefan Wahren Link: https://lore.kernel.org/r/20220904141037.38816-1-stefan.wahren@i2se.com Reviewed-by: Ivan T. Ivanov Reviewed-by: Florian Fainelli Signed-off-by: Stephen Boyd --- drivers/clk/bcm/clk-bcm2835.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/clk/bcm') diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 3f2ce20d27ec..e74fe6219d14 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -969,9 +969,9 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw, return div; } -static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, - unsigned long parent_rate, - u32 div) +static unsigned long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, + unsigned long parent_rate, + u32 div) { const struct bcm2835_clock_data *data = clock->data; u64 temp; -- cgit v1.2.3 From 4c68a345c157db23a59edb8e3227932c00de83a1 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 29 Aug 2022 18:21:52 +0300 Subject: clk: bcm: rpi: Add support HEVC clock Export clock required for RPiVid video decoder hardware. Cc: Dom Cobley Acked-by: Maxime Ripard Signed-off-by: Ivan T. Ivanov Link: https://lore.kernel.org/r/20220829152154.147250-2-iivanov@suse.de Signed-off-by: Stephen Boyd --- drivers/clk/bcm/clk-raspberrypi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/clk/bcm') diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c index 73518009a0f2..8f560c6b602d 100644 --- a/drivers/clk/bcm/clk-raspberrypi.c +++ b/drivers/clk/bcm/clk-raspberrypi.c @@ -129,6 +129,9 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = { [RPI_FIRMWARE_V3D_CLK_ID] = { .export = true, }, + [RPI_FIRMWARE_HEVC_CLK_ID] = { + .export = true, + }, [RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = { .export = true, }, -- cgit v1.2.3 From 16baa8c1c1ba00506d367d00856c58f5985f9b2e Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 29 Aug 2022 18:21:53 +0300 Subject: clk: bcm: rpi: Handle pixel clock in firmware The clk-bcm2835 handling of the pixel clock does not function correctly when the HDMI power domain is disabled. The firmware supports it correctly, so add it to the firmware clock driver. Acked-by: Maxime Ripard Acked-by: Dave Stevenson Signed-off-by: Ivan T. Ivanov Link: https://lore.kernel.org/r/20220829152154.147250-3-iivanov@suse.de Signed-off-by: Stephen Boyd --- drivers/clk/bcm/clk-raspberrypi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/clk/bcm') diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c index 8f560c6b602d..1248c0d64eae 100644 --- a/drivers/clk/bcm/clk-raspberrypi.c +++ b/drivers/clk/bcm/clk-raspberrypi.c @@ -129,6 +129,9 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = { [RPI_FIRMWARE_V3D_CLK_ID] = { .export = true, }, + [RPI_FIRMWARE_PIXEL_CLK_ID] = { + .export = true, + }, [RPI_FIRMWARE_HEVC_CLK_ID] = { .export = true, }, -- cgit v1.2.3 From 1777cb60f7df80d9b4ca3385eca1d2c0bed61cb6 Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Mon, 29 Aug 2022 18:21:54 +0300 Subject: clk: bcm: rpi: Add support for VEC clock Platform driver clk-bcm2835 gets an inaccurate clock for VEC (107MHz). Export VEC clock trough clk-raspberrypi which uses the right PLL to get an accurate 108MHz. Signed-off-by: Dom Cobley [iivanov: Adapted on top of v5.17-rc6] Signed-off-by: Ivan T. Ivanov Link: https://lore.kernel.org/r/20220829152154.147250-4-iivanov@suse.de Signed-off-by: Stephen Boyd --- drivers/clk/bcm/clk-raspberrypi.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/clk/bcm') diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c index 1248c0d64eae..d70bb9283af7 100644 --- a/drivers/clk/bcm/clk-raspberrypi.c +++ b/drivers/clk/bcm/clk-raspberrypi.c @@ -33,6 +33,7 @@ enum rpi_firmware_clk_id { RPI_FIRMWARE_EMMC2_CLK_ID, RPI_FIRMWARE_M2MC_CLK_ID, RPI_FIRMWARE_PIXEL_BVB_CLK_ID, + RPI_FIRMWARE_VEC_CLK_ID, RPI_FIRMWARE_NUM_CLK_ID, }; @@ -51,6 +52,7 @@ static char *rpi_firmware_clk_names[] = { [RPI_FIRMWARE_EMMC2_CLK_ID] = "emmc2", [RPI_FIRMWARE_M2MC_CLK_ID] = "m2mc", [RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = "pixel-bvb", + [RPI_FIRMWARE_VEC_CLK_ID] = "vec", }; #define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0) @@ -138,6 +140,9 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = { [RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = { .export = true, }, + [RPI_FIRMWARE_VEC_CLK_ID] = { + .export = true, + }, }; /* -- cgit v1.2.3