v4l2: add reset control support
authorchanghuang.liang <changhuang.liang@starfivetech.com>
Sat, 16 Apr 2022 05:48:40 +0000 (13:48 +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 ed35200..3df03da 100644 (file)
                                <0x0 0x11858000 0x0 0x10000>,
                                <0x0 0x17030000 0x0 0x10000>;
                        reg-names = "mipi0", "vclk", "vrst", "mipi1", "sctrl", "isp0", "isp1", "tclk", "trst", "iopad", "pmu";
+                       resets = <&rstgen RSTN_U0_DOM_ISP_TOP_N>,
+                                       <&rstgen RSTN_U0_DOM_ISP_TOP_AXI>,
+                                       <&rstgen RSTN_U0_ISPV2_TOP_WRAPPER_P>,
+                                       <&rstgen RSTN_U0_ISPV2_TOP_WRAPPER_C>,
+                                       <&rstgen RSTN_U0_VIN_N_PCLK>,
+                                       <&rstgen RSTN_U0_VIN_N_SYS_CLK>,
+                                       <&rstgen RSTN_U0_VIN_P_AXIRD>,
+                                       <&rstgen RSTN_U0_VIN_P_AXIWR>;
+                       reset-names = "rst_isp_top_n", "rst_isp_top_axi", "rst_wrapper_p",
+                                               "rst_wrapper_c", "rst_pclk", "rst_sys_clk",
+                                               "rst_axird", "rst_axiwr";
                        interrupts = <92 87 86>;
                        status = "disabled";
                };
index 62ac5a3..e712e20 100755 (executable)
@@ -105,28 +105,40 @@ static int stf_vin_clk_enable(struct stf_vin2_dev *vin_dev)
 {
 
        struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
-
-       reg_set_bit(vin->clkgen_base, CLK_DOM4_APB_FUNC, CLK_MUX_SEL, 0x8);
-       reg_set_bit(vin->clkgen_base, CLK_U0_VIN_PCLK, CLK_U0_VIN_PCLK_ICG, 0x1<<31);
-       reg_set_bit(vin->clkgen_base, CLK_U0_VIN_SYS_CLK, CLK_MUX_SEL, 0x2);
-       reg_set_bit(vin->clkgen_base, CLK_U0_ISPV2_TOP_WRAPPER_CLK_C, CLK_U0_ISPV2_CLK_ICG, 0x1<<31);
+#ifdef CONFIG_RESET_STARFIVE_JH7110
+       reset_control_deassert(vin_dev->stfcamss->sys_rst[STFRST_WRAPPER_C].rst);
+       reset_control_deassert(vin_dev->stfcamss->sys_rst[STFRST_WRAPPER_P].rst);
+       reset_control_deassert(vin_dev->stfcamss->sys_rst[STFRST_PCLK].rst);
+       reset_control_deassert(vin_dev->stfcamss->sys_rst[STFRST_SYS_CLK].rst);
+       reset_control_deassert(vin_dev->stfcamss->sys_rst[STFRST_AXIRD].rst);
+       reset_control_deassert(vin_dev->stfcamss->sys_rst[STFRST_AXIWR].rst);
+#else
        reg_clear_rst(vin->clkgen_base, SOFTWARE_RESET_ASSERT0_ASSERT_SET,
                SOFTWARE_RESET_ASSERT0_ASSERT_SET_STATE,
                RST_U0_ISPV2_TOP_WRAPPER_RST_P);
-       reg_set_bit(vin->clkgen_base, CLK_U0_ISPV2_TOP_WRAPPER_CLK_C, CLK_U0_ISPV2_MUX_SEL, 0x0);
        reg_clear_rst(vin->clkgen_base, SOFTWARE_RESET_ASSERT0_ASSERT_SET,
                SOFTWARE_RESET_ASSERT0_ASSERT_SET_STATE,
                RST_U0_ISPV2_TOP_WRAPPER_RST_C);
-       reg_set_bit(vin->clkgen_base, CLK_DVP_INV, CLK_POLARITY, 0x0);
-       reg_set_bit(vin->clkgen_base, CLK_U0_ISPV2_TOP_WRAPPER_CLK_C, CLK_U0_ISPV2_MUX_SEL, 0x1<<24);
        reg_clear_rst(vin->clkgen_base, SOFTWARE_RESET_ASSERT0_ASSERT_SET,
                SOFTWARE_RESET_ASSERT0_ASSERT_SET_STATE,
                RSTN_U0_VIN_RST_N_PCLK
                | RSTN_U0_VIN_RST_P_AXIRD
                | RSTN_U0_VIN_RST_N_SYS_CLK);
-       reg_set_bit(vin->clkgen_base,   CLK_U0_VIN_CLK_P_AXIWR, CLK_U0_VIN_MUX_SEL, 0x0);
        reg_clear_rst(vin->clkgen_base, SOFTWARE_RESET_ASSERT0_ASSERT_SET,
                SOFTWARE_RESET_ASSERT0_ASSERT_SET_STATE, RSTN_U0_VIN_RST_P_AXIWR);
+#endif
+       reg_set_bit(vin->clkgen_base, CLK_DOM4_APB_FUNC, CLK_MUX_SEL, 0x8);
+       reg_set_bit(vin->clkgen_base, CLK_U0_VIN_PCLK, CLK_U0_VIN_PCLK_ICG, 0x1<<31);
+       reg_set_bit(vin->clkgen_base, CLK_U0_VIN_SYS_CLK, CLK_MUX_SEL, 0x2);
+       reg_set_bit(vin->clkgen_base, CLK_U0_ISPV2_TOP_WRAPPER_CLK_C, CLK_U0_ISPV2_CLK_ICG, 0x1<<31);
+
+       reg_set_bit(vin->clkgen_base, CLK_U0_ISPV2_TOP_WRAPPER_CLK_C, CLK_U0_ISPV2_MUX_SEL, 0x0);
+
+       reg_set_bit(vin->clkgen_base, CLK_DVP_INV, CLK_POLARITY, 0x0);
+       reg_set_bit(vin->clkgen_base, CLK_U0_ISPV2_TOP_WRAPPER_CLK_C, CLK_U0_ISPV2_MUX_SEL, 0x1<<24);
+
+       reg_set_bit(vin->clkgen_base,   CLK_U0_VIN_CLK_P_AXIWR, CLK_U0_VIN_MUX_SEL, 0x0);
+
        reg_set_bit(vin->clkgen_base,   CLK_U0_VIN_CLK_P_AXIWR, CLK_U0_VIN_MUX_SEL, 0x1<<24);
 
 #if 0
@@ -160,11 +172,18 @@ static int stf_vin_clk_disable(struct stf_vin2_dev *vin_dev)
 
        struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
 
+#ifdef CONFIG_RESET_STARFIVE_JH7110
+       reset_control_assert(vin_dev->stfcamss->sys_rst[STFRST_PCLK].rst);
+       reset_control_assert(vin_dev->stfcamss->sys_rst[STFRST_SYS_CLK].rst);
+       reset_control_assert(vin_dev->stfcamss->sys_rst[STFRST_AXIRD].rst);
+       reset_control_assert(vin_dev->stfcamss->sys_rst[STFRST_AXIWR].rst);
+#else
        reg_assert_rst(vin->clkgen_base,SOFTWARE_RESET_ASSERT0_ASSERT_SET,
                SOFTWARE_RESET_ASSERT0_ASSERT_SET_STATE, RSTN_U0_VIN_RST_N_PCLK
                | RSTN_U0_VIN_RST_N_SYS_CLK
                | RSTN_U0_VIN_RST_P_AXIRD
                | RSTN_U0_VIN_RST_P_AXIWR);
+#endif
 
        reg_set_bit(vin->clkgen_base, CLK_U0_VIN_PCLK, CLK_U0_VIN_PCLK_ICG, 0x0);
 
@@ -254,13 +273,23 @@ static void stf_vin_power_on(struct stf_vin2_dev *vin_dev,        int enable)
 
                reg_set_highest_bit(vin->sys_crg, 0xCCU);
                reg_set_highest_bit(vin->sys_crg, 0xD0U);
-               reg_clear_rst(vin->sys_crg, 0x2FCU,0x30CU, (0x1 << 9));
-               reg_clear_rst(vin->sys_crg, 0x2FCU,0x30CU, (0x1 << 10));
+#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);
+#else
+               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) {
-                       reg_assert_rst(vin->sys_crg, 0x2FCU ,0x30cu, BIT(9));  
-                       reg_assert_rst(vin->sys_crg, 0x2FCU ,0x30cu, BIT(10)); 
+#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);
+#else
+                       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));
index 6daf4cd..5c800bb 100755 (executable)
@@ -46,7 +46,7 @@ static const struct reg_name mem_reg_name[] = {
 #ifndef CONFIG_VIDEO_CADENCE_CSI2RX
        {"mipi0"},
 #endif
-       {"vclk"},
+       //{"vclk"},
        {"vrst"},
        {"mipi1"},
        {"sctrl"},
@@ -59,6 +59,17 @@ static const struct reg_name mem_reg_name[] = {
        //{"syscrg"},
 };
 
+char *resets[] = {
+       "rst_isp_top_n",
+       "rst_isp_top_axi",
+       "rst_wrapper_p",
+       "rst_wrapper_c",
+       "rst_pclk",
+       "rst_sys_clk",
+       "rst_axird",
+       "rst_axiwr",
+};
+
 int stfcamss_get_mem_res(struct platform_device *pdev, struct stf_vin_dev *vin)
 {
        struct device *dev = &pdev->dev;
@@ -76,8 +87,8 @@ int stfcamss_get_mem_res(struct platform_device *pdev, struct stf_vin_dev *vin)
 
                if (!strcmp(name, "mipi0"))
                        vin->mipi0_base = regs;
-               else if (!strcmp(name, "vclk"))
-                       vin->clkgen_base = regs;
+               // else if (!strcmp(name, "vclk"))
+               //      vin->clkgen_base = regs;
                else if (!strcmp(name, "vrst"))
                        vin->rstgen_base = regs;
                else if (!strcmp(name, "mipi1"))
@@ -100,7 +111,8 @@ int stfcamss_get_mem_res(struct platform_device *pdev, struct stf_vin_dev *vin)
                        st_err(ST_CAMSS, "Could not match resource name\n");
        }
 
-       vin->sys_crg = ioremap(0x13020000, 10000);
+       vin->clkgen_base = ioremap(0x19810000, 0x10000);
+       vin->sys_crg = ioremap(0x13020000, 0x10000);
 
        return 0;
 }
@@ -919,7 +931,7 @@ static int stfcamss_probe(struct platform_device *pdev)
        struct device_node *node;
        struct resource res_mem;
        struct device *dev = &pdev->dev;
-       int ret = 0, num_subdevs;
+       int ret = 0, i, num_subdevs;
 
        printk("stfcamss probe enter!\n");
 
@@ -1002,6 +1014,28 @@ static int stfcamss_probe(struct platform_device *pdev)
                goto err_cam;
        }
 
+#ifdef CONFIG_RESET_STARFIVE_JH7110
+       stfcamss->nrsts = ARRAY_SIZE(resets);
+       stfcamss->sys_rst = devm_kzalloc(dev, stfcamss->nrsts * sizeof(*stfcamss->sys_rst),
+                       GFP_KERNEL);
+       if (!stfcamss->sys_rst) {
+               ret = -ENOMEM;
+               goto err_cam;
+       }
+
+       for (i = 0; i < stfcamss->nrsts; i++) {
+               struct stfcamss_rst *reset = &stfcamss->sys_rst[i];
+               reset->rst = devm_reset_control_get_exclusive(dev, resets[i]);
+               if (IS_ERR(reset->rst)) {
+                       st_err(ST_CAMSS, "get %s resets name failed\n", resets[i]);
+                       return PTR_ERR(reset->rst);
+               }
+               st_debug(ST_CAMSS, "get %s resets name: \n", resets[i]);
+
+               reset->name = resets[i];
+       }
+#endif
+
        ret = stfcamss_get_mem_res(pdev, vin);
        if (ret) {
                st_err(ST_CAMSS, "Could not map registers\n");
index 6da9db0..4ebf4f5 100755 (executable)
@@ -7,6 +7,7 @@
 
 #include <linux/io.h>
 #include <linux/delay.h>
+#include <linux/reset.h>
 
 enum sensor_type {
        SENSOR_VIN,
@@ -39,6 +40,24 @@ enum port_num {
        CSI2RX1_SENSOR_PORT_NUMBER
 };
 
+enum stf_rst_num {
+       STFRST_ISP_TOP_N = 0,
+       STFRST_ISP_TOP_AXI,
+       STFRST_WRAPPER_P,
+       STFRST_WRAPPER_C,
+       STFRST_PCLK,
+       STFRST_SYS_CLK,
+       STFRST_AXIRD,
+       STFRST_AXIWR,
+       STFRST_NUM
+};
+
+
+struct stfcamss_rst {
+       struct reset_control *rst;
+       const char *name;
+};
+
 struct stfcamss {
        struct stf_vin_dev *vin;  // stfcamss phy res
        struct v4l2_device v4l2_dev;
@@ -53,6 +72,8 @@ struct stfcamss {
        int isp_num;
        struct stf_isp_dev *isp_dev;   // subdev
        struct v4l2_async_notifier notifier;
+       struct stfcamss_rst *sys_rst;
+       int nrsts;
 #ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs_entry;
        struct dentry *vin_debugfs;