xilinx: versal-net: Add support for timer and start it
authorAshok Reddy Soma <ashok.reddy.soma@amd.com>
Tue, 10 Jan 2023 07:44:07 +0000 (08:44 +0100)
committerMichal Simek <michal.simek@amd.com>
Mon, 16 Jan 2023 14:34:37 +0000 (15:34 +0100)
Add support for starting timer by setting up time stamp generator
registers. This is done only for EL3 i.e. mini U-Boot case.
For other cases, it will be done TF-A.

Add COUNTER_FREQUENCY and IOU_SWITCH_DIVISOR0 to Kconfig so that they
can be tuned as required.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@amd.com>
Signed-off-by: Michal Simek <michal.simek@amd.com>
Link: https://lore.kernel.org/r/fcd8b0dc4b45a11f5e753afff42f84738ac813da.1673336645.git.michal.simek@amd.com
arch/arm/mach-versal-net/Kconfig
arch/arm/mach-versal-net/include/mach/hardware.h
board/xilinx/versal-net/board.c
configs/xilinx_versal_net_mini_defconfig
configs/xilinx_versal_net_virt_defconfig

index 62825e1..edff5b0 100644 (file)
@@ -21,6 +21,18 @@ config SYS_CONFIG_NAME
          Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
          will be used for board configuration.
 
+config COUNTER_FREQUENCY
+       int "Timer clock frequency"
+       default 0
+       help
+         Setup time clock frequency for certain platform
+
+config IOU_SWITCH_DIVISOR0
+       hex "IOU switch divisor0"
+       default 0x20
+       help
+         Setup time clock divisor for input clock.
+
 config SYS_MEM_RSVD_FOR_MMU
        bool "Reserve memory for MMU Table"
        help
index 808ce48..c5e4e22 100644 (file)
@@ -8,6 +8,36 @@
 #include <linux/bitops.h>
 #endif
 
+struct crlapb_regs {
+       u32 reserved0[67];
+       u32 cpu_r5_ctrl;
+       u32 reserved;
+       u32 iou_switch_ctrl; /* 0x114 */
+       u32 reserved1[13];
+       u32 timestamp_ref_ctrl; /* 0x14c */
+       u32 reserved3[108];
+       u32 rst_cpu_r5;
+       u32 reserved2[17];
+       u32 rst_timestamp; /* 0x348 */
+};
+
+struct iou_scntrs_regs {
+       u32 counter_control_register; /* 0x0 */
+       u32 reserved0[7];
+       u32 base_frequency_id_register; /* 0x20 */
+};
+
+#define VERSAL_NET_CRL_APB_BASEADDR            0xEB5E0000
+#define VERSAL_NET_IOU_SCNTR_SECURE            0xEC920000
+
+#define CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT  BIT(25)
+#define IOU_SWITCH_CTRL_CLKACT_BIT             BIT(25)
+#define IOU_SWITCH_CTRL_DIVISOR0_SHIFT         8
+#define IOU_SCNTRS_CONTROL_EN                  1
+
+#define crlapb_base ((struct crlapb_regs *)VERSAL_NET_CRL_APB_BASEADDR)
+#define iou_scntr_secure ((struct iou_scntrs_regs *)VERSAL_NET_IOU_SCNTR_SECURE)
+
 #define PMC_TAP        0xF11A0000
 
 #define PMC_TAP_IDCODE         (PMC_TAP + 0)
index 7600319..5fb7110 100644 (file)
@@ -121,6 +121,47 @@ int board_early_init_f(void)
 
 int board_early_init_r(void)
 {
+       u32 val;
+
+       if (current_el() != 3)
+               return 0;
+
+       debug("iou_switch ctrl div0 %x\n",
+             readl(&crlapb_base->iou_switch_ctrl));
+
+       writel(IOU_SWITCH_CTRL_CLKACT_BIT |
+              (CONFIG_IOU_SWITCH_DIVISOR0 << IOU_SWITCH_CTRL_DIVISOR0_SHIFT),
+              &crlapb_base->iou_switch_ctrl);
+
+       /* Global timer init - Program time stamp reference clk */
+       val = readl(&crlapb_base->timestamp_ref_ctrl);
+       val |= CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT;
+       writel(val, &crlapb_base->timestamp_ref_ctrl);
+
+       debug("ref ctrl 0x%x\n",
+             readl(&crlapb_base->timestamp_ref_ctrl));
+
+       /* Clear reset of timestamp reg */
+       writel(0, &crlapb_base->rst_timestamp);
+
+       /*
+        * Program freq register in System counter and
+        * enable system counter.
+        */
+       writel(CONFIG_COUNTER_FREQUENCY,
+              &iou_scntr_secure->base_frequency_id_register);
+
+       debug("counter val 0x%x\n",
+             readl(&iou_scntr_secure->base_frequency_id_register));
+
+       writel(IOU_SCNTRS_CONTROL_EN,
+              &iou_scntr_secure->counter_control_register);
+
+       debug("scntrs control 0x%x\n",
+             readl(&iou_scntr_secure->counter_control_register));
+       debug("timer 0x%llx\n", get_ticks());
+       debug("timer 0x%llx\n", get_ticks());
+
        return 0;
 }
 
index c5fa431..5bad179 100644 (file)
@@ -2,6 +2,7 @@ CONFIG_ARM=y
 CONFIG_SYS_CONFIG_NAME="xilinx_versal_net_mini"
 CONFIG_SYS_ICACHE_OFF=y
 # CONFIG_ARM64_CRC32 is not set
+CONFIG_COUNTER_FREQUENCY=100000000
 # CONFIG_ARM64_SUPPORT_AARCH32 is not set
 CONFIG_ARCH_VERSAL_NET=y
 CONFIG_TEXT_BASE=0xBBF10000
index 2fdf99f..729c6ad 100644 (file)
@@ -1,4 +1,5 @@
 CONFIG_ARM=y
+CONFIG_COUNTER_FREQUENCY=100000000
 CONFIG_POSITION_INDEPENDENT=y
 CONFIG_SYS_INIT_SP_BSS_OFFSET=1572864
 CONFIG_ARCH_VERSAL_NET=y