@samitouri / QOSamiQemu / commits / 9f61499c4a

hw/misc/imx6_ccm: Add PLL3 and CAN clock

Add fixed frequency (480 MHz) PLL3, of which the FlexCAN clock is derived, and compute FlexCAN frequency based on the divider configuration (CCM_CSCMR2). The clock frequency will be used for computing timestamps in FlexCAN emulator. Signed-off-by: Matyáš Bobek <matyas.bobek@gmail.com> Signed-off-by: Pavel Pisa <pisa@fel.cvut.cz> Tested-by: Pavel Pisa <pisa@fel.cvut.cz> Reviewed-by: Bernhard Beschow <shentey@gmail.com> Reviewed-by: Pavel Pisa <pisa@fel.cvut.cz> Message-id: 95da33074f8b79842566d61e4e04448b1e622080.1782140438.git.matyas.bobek@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Matyáš Bobek committed Jun 22, 2026 at 18:08 UTC 9f61499c4add725e91b294d92deeedb894512a14
4 files changed +31
hw/misc/imx6_ccm.c
+24
@@ -257,6 +257,15 @@ static uint64_t imx6_analog_get_pll2_clk(IMX6CCMState *dev)
257 return freq;
258 }
259
260 +static uint64_t imx6_analog_get_pll3_clk(IMX6CCMState *dev)
261 +{
262 + uint64_t freq = 480000000;
263 +
264 + trace_imx6_analog_get_pll3_clk(freq);
265 +
266 + return freq;
267 +}
268 +
269 static uint64_t imx6_analog_get_pll2_pfd0_clk(IMX6CCMState *dev)
270 {
271 uint64_t freq = 0;
@@ -344,6 +353,18 @@ static uint64_t imx6_ccm_get_per_clk(IMX6CCMState *dev)
353 return freq;
354 }
355
356 +static uint64_t imx6_ccm_get_can_clk(IMX6CCMState *dev)
357 +{
358 + uint64_t freq = 0;
359 +
360 + freq = imx6_analog_get_pll3_clk(dev) / 8;
361 + freq /= (1 + EXTRACT(dev->ccm[CCM_CSCMR2], CAN_CLK_PODF));
362 +
363 + trace_imx6_ccm_get_can_clk(freq);
364 +
365 + return freq;
366 +}
367 +
368 static uint32_t imx6_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
369 {
370 uint32_t freq = 0;
@@ -358,6 +379,9 @@ static uint32_t imx6_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
379 case CLK_IPG_HIGH:
380 freq = imx6_ccm_get_per_clk(s);
381 break;
382 + case CLK_CAN:
383 + freq = imx6_ccm_get_can_clk(s);
384 + break;
385 case CLK_32k:
386 freq = CKIL_FREQ;
387 break;
hw/misc/trace-events
+2
@@ -242,11 +242,13 @@ imx6_analog_get_periph_clk(uint32_t freq) "freq = %u Hz"
242 imx6_analog_get_pll2_clk(uint32_t freq) "freq = %u Hz"
243 imx6_analog_get_pll2_pfd0_clk(uint32_t freq) "freq = %u Hz"
244 imx6_analog_get_pll2_pfd2_clk(uint32_t freq) "freq = %u Hz"
245 +imx6_analog_get_pll3_clk(uint32_t freq) "freq = %u Hz"
246 imx6_analog_read(const char *reg, uint32_t value) "reg[%s] => 0x%" PRIx32
247 imx6_analog_write(const char *reg, uint32_t value) "reg[%s] <= 0x%" PRIx32
248 imx6_ccm_get_ahb_clk(uint32_t freq) "freq = %u Hz"
249 imx6_ccm_get_ipg_clk(uint32_t freq) "freq = %u Hz"
250 imx6_ccm_get_per_clk(uint32_t freq) "freq = %u Hz"
251 +imx6_ccm_get_can_clk(uint32_t freq) "freq = %u Hz"
252 imx6_ccm_get_clock_frequency(unsigned clock, uint32_t freq) "(Clock = %d) = %u"
253 imx6_ccm_read(const char *reg, uint32_t value) "reg[%s] => 0x%" PRIx32
254 imx6_ccm_reset(void) ""
include/hw/misc/imx6_ccm.h
+4
@@ -164,6 +164,10 @@
164 #define PERCLK_PODF_SHIFT (0)
165 #define PERCLK_PODF_LENGTH (6)
166
167 +/* CCM_CSCMR2 */
168 +#define CAN_CLK_PODF_SHIFT (2)
169 +#define CAN_CLK_PODF_LENGTH (6)
170 +
171 /* CCM_ANALOG_PFD_528 */
172 #define PFD0_FRAC_SHIFT (0)
173 #define PFD0_FRAC_LENGTH (6)
include/hw/misc/imx_ccm.h
+1
@@ -46,6 +46,7 @@ typedef enum {
46 CLK_EXT,
47 CLK_HIGH_DIV,
48 CLK_HIGH,
49 + CLK_CAN,
50 } IMXClk;
51
52 struct IMXCCMClass {