v4l2: add sys clk tree support
authorchanghuang.liang <changhuang.liang@starfivetech.com>
Sat, 16 Apr 2022 06:42:30 +0000 (14:42 +0800)
committerchanghuang.liang <changhuang.liang@starfivetech.com>
Tue, 26 Apr 2022 09:39:36 +0000 (17:39 +0800)
arch/riscv/boot/dts/starfive/jh7110.dtsi
drivers/media/platform/starfive/v4l2_driver/stf_vin_hw_ops.c
drivers/media/platform/starfive/v4l2_driver/stfcamss.c
drivers/media/platform/starfive/v4l2_driver/stfcamss.h

index 3df03da..3cecefa 100644 (file)
                                <0x0 0x11858000 0x0 0x10000>,
                                <0x0 0x17030000 0x0 0x10000>;
                        reg-names = "mipi0", "vclk", "vrst", "mipi1", "sctrl", "isp0", "isp1", "tclk", "trst", "iopad", "pmu";
+                       clocks = <&clkgen JH7110_ISP_TOP_CLK_ISPCORE_2X>,
+                                       <&clkgen JH7110_ISP_TOP_CLK_ISP_AXI>;
+                       clock-names = "clk_ispcore_2x", "clk_isp_axi";
                        resets = <&rstgen RSTN_U0_DOM_ISP_TOP_N>,
                                        <&rstgen RSTN_U0_DOM_ISP_TOP_AXI>,
                                        <&rstgen RSTN_U0_ISPV2_TOP_WRAPPER_P>,
index e712e20..382f899 100755 (executable)
@@ -271,8 +271,14 @@ static void stf_vin_power_on(struct stf_vin2_dev *vin_dev, int enable)
                reg_write(vin->pmu_test, SW_ENCOURAGE, 0x05);
                reg_write(vin->pmu_test, SW_ENCOURAGE, 0x50);
 
+#ifdef CONFIG_CLK_STARFIVE_JH7110
+               clk_prepare_enable(vin_dev->stfcamss->sys_clk[STFCLK_ISPCORE_2X].clk);
+               clk_prepare_enable(vin_dev->stfcamss->sys_clk[STFCLK_ISP_AXI].clk);
+#else
                reg_set_highest_bit(vin->sys_crg, 0xCCU);
                reg_set_highest_bit(vin->sys_crg, 0xD0U);
+#endif
+
 #ifdef CONFIG_RESET_STARFIVE_JH7110
                reset_control_deassert(vin_dev->stfcamss->sys_rst[STFRST_ISP_TOP_N].rst);
                reset_control_deassert(vin_dev->stfcamss->sys_rst[STFRST_ISP_TOP_AXI].rst);
@@ -280,9 +286,9 @@ static void stf_vin_power_on(struct stf_vin2_dev *vin_dev,  int enable)
                reg_clear_rst(vin->sys_crg, 0x2FCU, 0x30CU, (0x1 << 9));
                reg_clear_rst(vin->sys_crg, 0x2FCU, 0x30CU, (0x1 << 10));
 #endif
+
        } else {
-               reg = reg_read(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36);
-               if(reg && U0_VIN_CNFG_ISP_DVP_EN0) {
+
 #ifdef CONFIG_RESET_STARFIVE_JH7110
                        reset_control_assert(vin_dev->stfcamss->sys_rst[STFRST_ISP_TOP_N].rst);
                        reset_control_assert(vin_dev->stfcamss->sys_rst[STFRST_ISP_TOP_AXI].rst);
@@ -290,14 +296,20 @@ static void stf_vin_power_on(struct stf_vin2_dev *vin_dev,        int enable)
                        reg_assert_rst(vin->sys_crg, 0x2FCU, 0x30cu, BIT(9));
                        reg_assert_rst(vin->sys_crg, 0x2FCU, 0x30cu, BIT(10));
 #endif
-                       reg_set_bit(vin->sys_crg, 0xccu, BIT(31), 0x0);
-                       reg_set_bit(vin->sys_crg, 0xd0u, BIT(31), 0x0);
-                       reg_write(vin->pmu_test, SW_DEST_POWER_ON, (0x1<<5));
-                       //reg_write(vin->pmu_test, SW_DEST_POWER_OFF, (0x1<<5));        //changhuang modify 01-12
-                       reg_write(vin->pmu_test, SW_ENCOURAGE, 0xff);
-                       reg_write(vin->pmu_test, SW_ENCOURAGE, 0x0a);
-                       reg_write(vin->pmu_test, SW_ENCOURAGE, 0xa0);
-               }
+
+#ifdef CONFIG_CLK_STARFIVE_JH7110
+               clk_disable_unprepare(vin_dev->stfcamss->sys_clk[STFCLK_ISPCORE_2X].clk);
+               clk_disable_unprepare(vin_dev->stfcamss->sys_clk[STFCLK_ISP_AXI].clk);
+#else
+               reg_set_bit(vin->sys_crg, 0xccu, BIT(31), 0x0);
+               reg_set_bit(vin->sys_crg, 0xd0u, BIT(31), 0x0);
+#endif
+
+               reg_write(vin->pmu_test, SW_DEST_POWER_ON, (0x1<<5));
+               //reg_write(vin->pmu_test, SW_DEST_POWER_OFF, (0x1<<5));        //changhuang modify 01-12
+               reg_write(vin->pmu_test, SW_ENCOURAGE, 0xff);
+               reg_write(vin->pmu_test, SW_ENCOURAGE, 0x0a);
+               reg_write(vin->pmu_test, SW_ENCOURAGE, 0xa0);
        }
 }
 
index 5c800bb..370fb18 100755 (executable)
@@ -2,7 +2,6 @@
 /*
  * Copyright (C) 2021 StarFive Technology Co., Ltd.
  */
-#include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/dmaengine.h>
@@ -18,7 +17,6 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/reset.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
 #include <linux/uaccess.h>
@@ -59,6 +57,11 @@ static const struct reg_name mem_reg_name[] = {
        //{"syscrg"},
 };
 
+char *clocks[] = {
+       "clk_ispcore_2x",
+       "clk_isp_axi",
+};
+
 char *resets[] = {
        "rst_isp_top_n",
        "rst_isp_top_axi",
@@ -1014,6 +1017,28 @@ static int stfcamss_probe(struct platform_device *pdev)
                goto err_cam;
        }
 
+#ifdef CONFIG_CLK_STARFIVE_JH7110
+       stfcamss->nclks = ARRAY_SIZE(clocks);
+       stfcamss->sys_clk = devm_kzalloc(dev, stfcamss->nclks * sizeof(*stfcamss->sys_clk),
+                       GFP_KERNEL);
+       if (!stfcamss->sys_clk) {
+               ret = -ENOMEM;
+               goto err_cam;
+       }
+
+       for (i = 0; i < stfcamss->nclks; i++) {
+               struct stfcamss_clk *clock = &stfcamss->sys_clk[i];
+               clock->clk = devm_clk_get(dev, clocks[i]);
+               if (IS_ERR(clock->clk)) {
+                       st_err(ST_CAMSS, "get %s clocks name failed\n", clocks[i]);
+                       return PTR_ERR(clock->clk);
+               }
+               st_debug(ST_CAMSS, "get %s clocks name: \n", clocks[i]);
+
+               clock->name = clocks[i];
+       }
+#endif
+
 #ifdef CONFIG_RESET_STARFIVE_JH7110
        stfcamss->nrsts = ARRAY_SIZE(resets);
        stfcamss->sys_rst = devm_kzalloc(dev, stfcamss->nrsts * sizeof(*stfcamss->sys_rst),
index 4ebf4f5..3921052 100755 (executable)
@@ -8,6 +8,7 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/reset.h>
+#include <linux/clk.h>
 
 enum sensor_type {
        SENSOR_VIN,
@@ -40,6 +41,12 @@ enum port_num {
        CSI2RX1_SENSOR_PORT_NUMBER
 };
 
+enum stf_clk_num {
+       STFCLK_ISPCORE_2X = 0,
+       STFCLK_ISP_AXI,
+       STFCLK_NUM
+};
+
 enum stf_rst_num {
        STFRST_ISP_TOP_N = 0,
        STFRST_ISP_TOP_AXI,
@@ -52,6 +59,10 @@ enum stf_rst_num {
        STFRST_NUM
 };
 
+struct stfcamss_clk {
+       struct clk *clk;
+       const char *name;
+};
 
 struct stfcamss_rst {
        struct reset_control *rst;
@@ -72,6 +83,8 @@ struct stfcamss {
        int isp_num;
        struct stf_isp_dev *isp_dev;   // subdev
        struct v4l2_async_notifier notifier;
+       struct stfcamss_clk *sys_clk;
+       int nclks;
        struct stfcamss_rst *sys_rst;
        int nrsts;
 #ifdef CONFIG_DEBUG_FS