From: changhuang.liang Date: Sat, 16 Apr 2022 05:48:40 +0000 (+0800) Subject: v4l2: add reset control support X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6829fb703ee98b9546dda4fe000f58cdd1347981;p=platform%2Fkernel%2Flinux-starfive.git v4l2: add reset control support --- diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi index ed35200..3df03da 100644 --- a/arch/riscv/boot/dts/starfive/jh7110.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi @@ -594,6 +594,17 @@ <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"; }; diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_vin_hw_ops.c b/drivers/media/platform/starfive/v4l2_driver/stf_vin_hw_ops.c index 62ac5a3..e712e20 100755 --- a/drivers/media/platform/starfive/v4l2_driver/stf_vin_hw_ops.c +++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin_hw_ops.c @@ -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)); diff --git a/drivers/media/platform/starfive/v4l2_driver/stfcamss.c b/drivers/media/platform/starfive/v4l2_driver/stfcamss.c index 6daf4cd..5c800bb 100755 --- a/drivers/media/platform/starfive/v4l2_driver/stfcamss.c +++ b/drivers/media/platform/starfive/v4l2_driver/stfcamss.c @@ -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"); diff --git a/drivers/media/platform/starfive/v4l2_driver/stfcamss.h b/drivers/media/platform/starfive/v4l2_driver/stfcamss.h index 6da9db0..4ebf4f5 100755 --- a/drivers/media/platform/starfive/v4l2_driver/stfcamss.h +++ b/drivers/media/platform/starfive/v4l2_driver/stfcamss.h @@ -7,6 +7,7 @@ #include #include +#include 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;