From ef18a69d3765aeb4dfec3fa4fe4c166ee5a57758 Mon Sep 17 00:00:00 2001 From: Jonathan Bell Date: Wed, 6 Mar 2024 10:14:50 +0000 Subject: [PATCH 0929/1085] drivers: clk: rp1: constrain clock divider outputs to design maximums Overclocking peripherals is generally a bad thing to do - so reject any attempt to set a clock output higher than it should be. Signed-off-by: Jonathan Bell --- drivers/clk/clk-rp1.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) --- a/drivers/clk/clk-rp1.c +++ b/drivers/clk/clk-rp1.c @@ -361,6 +361,7 @@ struct rp1_clock_data { u32 div_frac_reg; u32 sel_reg; u32 div_int_max; + unsigned long max_freq; u32 fc0_src; }; @@ -1211,7 +1212,15 @@ static void rp1_clock_choose_div_and_pra /* Recalculate to account for rounding errors */ tmp = (u64)*prate << CLK_DIV_FRAC_BITS; tmp = div_u64(tmp, div); - *calc_rate = tmp; + /* + * Prevent overclocks - if all parent choices result in + * a downstream clock in excess of the maximum, then the + * call to set the clock will fail. + */ + if (tmp > clock->data->max_freq) + *calc_rate = 0; + else + *calc_rate = tmp; } static int rp1_clock_determine_rate(struct clk_hw *hw, @@ -1672,6 +1681,7 @@ static const struct rp1_clk_desc clk_des .div_int_reg = CLK_SYS_DIV_INT, .sel_reg = CLK_SYS_SEL, .div_int_max = DIV_INT_24BIT_MAX, + .max_freq = 200 * MHz, .fc0_src = FC_NUM(0, 4), .clk_src_mask = 0x3, ), @@ -1685,6 +1695,7 @@ static const struct rp1_clk_desc clk_des .div_int_reg = CLK_SLOW_SYS_DIV_INT, .sel_reg = CLK_SLOW_SYS_SEL, .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 50 * MHz, .fc0_src = FC_NUM(1, 4), .clk_src_mask = 0x1, ), @@ -1706,6 +1717,7 @@ static const struct rp1_clk_desc clk_des .div_int_reg = CLK_UART_DIV_INT, .sel_reg = CLK_UART_SEL, .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 100 * MHz, .fc0_src = FC_NUM(6, 7), ), @@ -1726,6 +1738,7 @@ static const struct rp1_clk_desc clk_des .div_int_reg = CLK_ETH_DIV_INT, .sel_reg = CLK_ETH_SEL, .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 125 * MHz, .fc0_src = FC_NUM(4, 6), ), @@ -1747,6 +1760,7 @@ static const struct rp1_clk_desc clk_des .div_frac_reg = CLK_PWM0_DIV_FRAC, .sel_reg = CLK_PWM0_SEL, .div_int_max = DIV_INT_16BIT_MAX, + .max_freq = 76800 * KHz, .fc0_src = FC_NUM(0, 5), ), @@ -1768,6 +1782,7 @@ static const struct rp1_clk_desc clk_des .div_frac_reg = CLK_PWM1_DIV_FRAC, .sel_reg = CLK_PWM1_SEL, .div_int_max = DIV_INT_16BIT_MAX, + .max_freq = 76800 * KHz, .fc0_src = FC_NUM(1, 5), ), @@ -1790,6 +1805,7 @@ static const struct rp1_clk_desc clk_des .div_int_reg = CLK_AUDIO_IN_DIV_INT, .sel_reg = CLK_AUDIO_IN_SEL, .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 76800 * KHz, .fc0_src = FC_NUM(2, 5), ), @@ -1811,6 +1827,7 @@ static const struct rp1_clk_desc clk_des .div_int_reg = CLK_AUDIO_OUT_DIV_INT, .sel_reg = CLK_AUDIO_OUT_SEL, .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 153600 * KHz, .fc0_src = FC_NUM(3, 5), ), @@ -1831,6 +1848,7 @@ static const struct rp1_clk_desc clk_des .div_int_reg = CLK_I2S_DIV_INT, .sel_reg = CLK_I2S_SEL, .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 50 * MHz, .fc0_src = FC_NUM(4, 4), ), @@ -1843,6 +1861,7 @@ static const struct rp1_clk_desc clk_des .div_int_reg = CLK_MIPI0_CFG_DIV_INT, .sel_reg = CLK_MIPI0_CFG_SEL, .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 50 * MHz, .fc0_src = FC_NUM(4, 5), ), @@ -1856,6 +1875,7 @@ static const struct rp1_clk_desc clk_des .sel_reg = CLK_MIPI1_CFG_SEL, .clk_src_mask = 1, .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 50 * MHz, .fc0_src = FC_NUM(5, 6), ), @@ -1875,6 +1895,7 @@ static const struct rp1_clk_desc clk_des .div_int_reg = CLK_ETH_TSU_DIV_INT, .sel_reg = CLK_ETH_TSU_SEL, .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 50 * MHz, .fc0_src = FC_NUM(5, 7), ), @@ -1894,6 +1915,7 @@ static const struct rp1_clk_desc clk_des .div_int_reg = CLK_ADC_DIV_INT, .sel_reg = CLK_ADC_SEL, .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 50 * MHz, .fc0_src = FC_NUM(5, 5), ), @@ -1906,6 +1928,7 @@ static const struct rp1_clk_desc clk_des .div_int_reg = CLK_SDIO_TIMER_DIV_INT, .sel_reg = CLK_SDIO_TIMER_SEL, .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 50 * MHz, .fc0_src = FC_NUM(3, 4), ), @@ -1918,6 +1941,7 @@ static const struct rp1_clk_desc clk_des .div_int_reg = CLK_SDIO_ALT_SRC_DIV_INT, .sel_reg = CLK_SDIO_ALT_SRC_SEL, .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 200 * MHz, .fc0_src = FC_NUM(5, 4), ), @@ -1947,6 +1971,7 @@ static const struct rp1_clk_desc clk_des .div_frac_reg = CLK_GP0_DIV_FRAC, .sel_reg = CLK_GP0_SEL, .div_int_max = DIV_INT_16BIT_MAX, + .max_freq = 100 * MHz, .fc0_src = FC_NUM(0, 1), ), @@ -1976,6 +2001,7 @@ static const struct rp1_clk_desc clk_des .div_frac_reg = CLK_GP1_DIV_FRAC, .sel_reg = CLK_GP1_SEL, .div_int_max = DIV_INT_16BIT_MAX, + .max_freq = 100 * MHz, .fc0_src = FC_NUM(1, 1), ), @@ -2005,6 +2031,7 @@ static const struct rp1_clk_desc clk_des .div_frac_reg = CLK_GP2_DIV_FRAC, .sel_reg = CLK_GP2_SEL, .div_int_max = DIV_INT_16BIT_MAX, + .max_freq = 100 * MHz, .fc0_src = FC_NUM(2, 1), ), @@ -2034,6 +2061,7 @@ static const struct rp1_clk_desc clk_des .div_frac_reg = CLK_GP3_DIV_FRAC, .sel_reg = CLK_GP3_SEL, .div_int_max = DIV_INT_16BIT_MAX, + .max_freq = 100 * MHz, .fc0_src = FC_NUM(3, 1), ), @@ -2064,6 +2092,7 @@ static const struct rp1_clk_desc clk_des .div_frac_reg = CLK_GP4_DIV_FRAC, .sel_reg = CLK_GP4_SEL, .div_int_max = DIV_INT_16BIT_MAX, + .max_freq = 100 * MHz, .fc0_src = FC_NUM(4, 1), ), @@ -2093,6 +2122,7 @@ static const struct rp1_clk_desc clk_des .div_frac_reg = CLK_GP5_DIV_FRAC, .sel_reg = CLK_GP5_SEL, .div_int_max = DIV_INT_16BIT_MAX, + .max_freq = 100 * MHz, .fc0_src = FC_NUM(5, 1), ), @@ -2113,6 +2143,7 @@ static const struct rp1_clk_desc clk_des .sel_reg = VIDEO_CLK_VEC_SEL, .flags = CLK_SET_RATE_NO_REPARENT, /* Let VEC driver set parent */ .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 108 * MHz, .fc0_src = FC_NUM(0, 6), ), @@ -2133,6 +2164,7 @@ static const struct rp1_clk_desc clk_des .sel_reg = VIDEO_CLK_DPI_SEL, .flags = CLK_SET_RATE_NO_REPARENT, /* Let DPI driver set parent */ .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 200 * MHz, .fc0_src = FC_NUM(1, 6), ), @@ -2154,6 +2186,7 @@ static const struct rp1_clk_desc clk_des .sel_reg = VIDEO_CLK_MIPI0_DPI_SEL, .flags = CLK_SET_RATE_NO_REPARENT, /* Let DSI driver set parent */ .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 200 * MHz, .fc0_src = FC_NUM(2, 6), ), @@ -2175,6 +2208,7 @@ static const struct rp1_clk_desc clk_des .sel_reg = VIDEO_CLK_MIPI1_DPI_SEL, .flags = CLK_SET_RATE_NO_REPARENT, /* Let DSI driver set parent */ .div_int_max = DIV_INT_8BIT_MAX, + .max_freq = 200 * MHz, .fc0_src = FC_NUM(3, 6), ), };