aboutsummaryrefslogtreecommitdiff
path: root/board/thead/light-c910/digital_sensor_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/thead/light-c910/digital_sensor_test.c')
-rw-r--r--board/thead/light-c910/digital_sensor_test.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/board/thead/light-c910/digital_sensor_test.c b/board/thead/light-c910/digital_sensor_test.c
new file mode 100644
index 00000000..ba776893
--- /dev/null
+++ b/board/thead/light-c910/digital_sensor_test.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2017-2022 Alibaba Group Holding Limited
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/types.h>
+#include <thead/clock_config.h>
+#include <linux/bitops.h>
+#include <asm/arch-thead/light-iopmp.h>
+#include <asm/arch-thead/light-plic.h>
+#include <thead/clock_config.h>
+
+#define TEE_LIGHT_APCLK_ADDRBASE ((void __iomem *)0xffff011000)
+#define REG_TEESYS_CLK_TEECFG ((void __iomem *)TEE_LIGHT_APCLK_ADDRBASE + 0x1cc)
+
+/* VIDEO PLL */
+#define TEESYS_I1_HCLK_DIV_EN BIT(12)
+#define TEESYS_I1_HCLK_DIV_NUM_SHIFT 8
+#define TEESYS_I1_HCLK_DIV_NUM_MASK 0xf
+
+#define LIGHT_CPUFREQ_THRE 1500000
+#define LIGHT_C910_BUS_CLK_SYNC BIT(11)
+#define LIGHT_C910_BUS_CLK_RATIO_MASK 0x700
+#define LIGHT_C910_BUS_CLK_DIV_RATIO_2 0x100
+#define LIGHT_C910_BUS_CLK_DIV_RATIO_3 0x200
+
+extern int ds_init(void);
+
+bool global_ds_init = false;
+
+static int ds_cpu_alarm_clk_set(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ unsigned long new_freq;
+ int ret = 0;
+ u32 val;
+ const struct clk_info *parent;
+
+ if (argc != 2) {
+ printf("invalid input parameters\n");
+ return -EINVAL;
+ }
+
+ if (strict_strtoul(argv[1], 10, &new_freq) < 0)
+ return CMD_RET_USAGE;
+
+ val = readl(TEE_LIGHT_APCLK_ADDRBASE + 0x100);
+ val &= ~LIGHT_C910_BUS_CLK_RATIO_MASK;
+ val |= LIGHT_C910_BUS_CLK_DIV_RATIO_3;
+
+ writel(val, TEE_LIGHT_APCLK_ADDRBASE + 0x100);
+ val &= ~LIGHT_C910_BUS_CLK_SYNC;
+ writel(val, TEE_LIGHT_APCLK_ADDRBASE + 0x100);
+ udelay(1);
+ val |= LIGHT_C910_BUS_CLK_SYNC;
+ writel(val, TEE_LIGHT_APCLK_ADDRBASE + 0x100);
+ udelay(1);
+
+ printf("wait for cpu frequency alarm, rate: %ld\n", new_freq);
+
+ parent = clk_light_get_parent("c910_cclk");
+ if (!strcmp(parent->clk_name, "cpu_pll1_foutpostdiv")) {
+ ret = clk_light_set_rate("c910_cclk_i0", CLK_DEV_MUX, new_freq);
+ if (ret) {
+ printf("failed to set cpu frequency\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ udelay(3);
+ ret = clk_light_set_parent("c910_cclk", "c910_cclk_i0");
+ if (ret) {
+ printf("failed to set parent clock for cpu\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ } else {
+ ret = clk_light_set_rate("cpu_pll1_foutpostdiv", CLK_DEV_PLL, new_freq);
+ if (ret) {
+ printf("failed to set cpu frequency\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ udelay(3);
+ ret = clk_light_set_parent("c910_cclk", "cpu_pll1_foutpostdiv");
+ if (ret) {
+ printf("failed to set parent clock for cpu\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+
+ printf("C910 CPU FREQ: %ldMHz\n", new_freq / 1000000);
+
+out:
+ return ret;
+}
+
+static int ds_3to6_alarm_clk_set(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ unsigned long div;
+ int ret = 0;
+ u32 cfg;
+
+ if (argc != 2) {
+ printf("invalid input parameters\n");
+ return -EINVAL;
+ }
+
+ if (strict_strtoul(argv[1], 10, &div) < 0)
+ return CMD_RET_USAGE;
+
+ if (div < 2 || div > 15) {
+ printf("invalid teesys clock divider number(%ld)\n", div);
+ return -EINVAL;
+ }
+
+ cfg = readl(REG_TEESYS_CLK_TEECFG);
+ cfg &= ~TEESYS_I1_HCLK_DIV_EN;
+ writel(cfg, REG_TEESYS_CLK_TEECFG);
+
+ cfg &= ~(TEESYS_I1_HCLK_DIV_NUM_MASK << TEESYS_I1_HCLK_DIV_NUM_SHIFT);
+ cfg |= (div & TEESYS_I1_HCLK_DIV_NUM_MASK) << TEESYS_I1_HCLK_DIV_NUM_SHIFT;
+ cfg |= TEESYS_I1_HCLK_DIV_EN;
+ writel(cfg, REG_TEESYS_CLK_TEECFG);
+
+ return ret;
+}
+
+static int ds_7_alarm_clk_set(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ return ds_3to6_alarm_clk_set(cmdtp, flag, argc, argv);
+}
+
+static int ds_init_cfg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ if (!global_ds_init) {
+ global_ds_init = true;
+ return ds_init();
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(ds_init, 1, 0, ds_init_cfg, "ds_init", "Initalize the digital sensor controller");
+U_BOOT_CMD(ds_cpu_alarm, 2, 0, ds_cpu_alarm_clk_set, "ds_cpu_alarm 1500000000", "digital sensor cpu0~cpu3 alarm test");
+U_BOOT_CMD(ds_3to6_alarm, 2, 0, ds_3to6_alarm_clk_set, "ds_3to6_alarm 3", "digital sensor for digital3~digital6 alarm test");
+U_BOOT_CMD(ds_7_alarm, 2, 0, ds_7_alarm_clk_set, "ds_7_alarm 3", "digital sensor for digital7 alarm test");
+