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>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
---
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 b88accc437..99910fc068 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..a54b940686 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 c4212d04ea..6839716ea3 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.53.0