Add fixed frequency (480 MHz) PLL3, of which the FlexCAN clock is derived, and compute FlexCAN frequency based on divider configuration.
Signed-off-by: Matyáš Bobek <[email protected]> --- hw/misc/imx6_ccm.c | 24 ++++++++++++++++++++++++ hw/misc/trace-events | 2 ++ include/hw/misc/imx6_ccm.h | 4 ++++ include/hw/misc/imx_ccm.h | 1 + 4 files changed, 31 insertions(+) diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c index a10b67d396..45fdd0d5a8 100644 --- a/hw/misc/imx6_ccm.c +++ b/hw/misc/imx6_ccm.c @@ -257,6 +257,15 @@ static uint64_t imx6_analog_get_pll2_clk(IMX6CCMState *dev) return freq; } +static uint64_t imx6_analog_get_pll3_clk(IMX6CCMState *dev) +{ + uint64_t freq = 480000000; + + trace_imx6_analog_get_pll3_clk(freq); + + return freq; +} + static uint64_t imx6_analog_get_pll2_pfd0_clk(IMX6CCMState *dev) { uint64_t freq = 0; @@ -344,6 +353,18 @@ static uint64_t imx6_ccm_get_per_clk(IMX6CCMState *dev) return freq; } +static uint64_t imx6_ccm_get_can_clk(IMX6CCMState *dev) +{ + uint64_t freq = 0; + + freq = imx6_analog_get_pll3_clk(dev) / 8; + freq /= (1 + EXTRACT(dev->ccm[CCM_CSCMR2], CAN_CLK_PODF)); + + trace_imx6_ccm_get_can_clk(freq); + + return freq; +} + static uint32_t imx6_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock) { uint32_t freq = 0; @@ -358,6 +379,9 @@ static uint32_t imx6_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock) case CLK_IPG_HIGH: freq = imx6_ccm_get_per_clk(s); break; + case CLK_CAN: + freq = imx6_ccm_get_can_clk(s); + break; case CLK_32k: freq = CKIL_FREQ; break; diff --git a/hw/misc/trace-events b/hw/misc/trace-events index eeb9243898..7c4f1c45b8 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -242,11 +242,13 @@ imx6_analog_get_periph_clk(uint32_t freq) "freq = %u Hz" imx6_analog_get_pll2_clk(uint32_t freq) "freq = %u Hz" imx6_analog_get_pll2_pfd0_clk(uint32_t freq) "freq = %u Hz" imx6_analog_get_pll2_pfd2_clk(uint32_t freq) "freq = %u Hz" +imx6_analog_get_pll3_clk(uint32_t freq) "freq = %u Hz" imx6_analog_read(const char *reg, uint32_t value) "reg[%s] => 0x%" PRIx32 imx6_analog_write(const char *reg, uint32_t value) "reg[%s] <= 0x%" PRIx32 imx6_ccm_get_ahb_clk(uint32_t freq) "freq = %u Hz" imx6_ccm_get_ipg_clk(uint32_t freq) "freq = %u Hz" imx6_ccm_get_per_clk(uint32_t freq) "freq = %u Hz" +imx6_ccm_get_can_clk(uint32_t freq) "freq = %u Hz" imx6_ccm_get_clock_frequency(unsigned clock, uint32_t freq) "(Clock = %d) = %u" imx6_ccm_read(const char *reg, uint32_t value) "reg[%s] => 0x%" PRIx32 imx6_ccm_reset(void) "" diff --git a/include/hw/misc/imx6_ccm.h b/include/hw/misc/imx6_ccm.h index ccf46d7353..f498732727 100644 --- a/include/hw/misc/imx6_ccm.h +++ b/include/hw/misc/imx6_ccm.h @@ -164,6 +164,10 @@ #define PERCLK_PODF_SHIFT (0) #define PERCLK_PODF_LENGTH (6) +/* CCM_CSCMR2 */ +#define CAN_CLK_PODF_SHIFT (2) +#define CAN_CLK_PODF_LENGTH (6) + /* CCM_ANALOG_PFD_528 */ #define PFD0_FRAC_SHIFT (0) #define PFD0_FRAC_LENGTH (6) diff --git a/include/hw/misc/imx_ccm.h b/include/hw/misc/imx_ccm.h index 7e5678e972..9ce3adf332 100644 --- a/include/hw/misc/imx_ccm.h +++ b/include/hw/misc/imx_ccm.h @@ -46,6 +46,7 @@ typedef enum { CLK_EXT, CLK_HIGH_DIV, CLK_HIGH, + CLK_CAN, } IMXClk; struct IMXCCMClass { -- 2.52.0
