diff options
author | changhuang.liang <changhuang.liang@starfivetech.com> | 2022-05-05 12:26:20 +0300 |
---|---|---|
committer | Jianlong Huang <jianlong.huang@starfivetech.com> | 2022-06-13 06:39:17 +0300 |
commit | 49a7af92502e5d077aaa194cd8c4c69254651d1b (patch) | |
tree | ed8d725cd1ece2b95b1ca27a88afac8352dc403a | |
parent | 5ed7dc8b50733dcb47d0dcc11ad78fb52ae191a1 (diff) | |
download | linux-49a7af92502e5d077aaa194cd8c4c69254651d1b.tar.xz |
drivers/clk: add isp clk support!
dts/starfive: add isp clk configure!
Signed-off-by: changhuang.liang <changhuang.liang@starfivetech.com>
-rwxr-xr-x | arch/riscv/boot/dts/starfive/jh7100.dtsi | 10 | ||||
-rwxr-xr-x | drivers/clk/starfive/Kconfig | 6 | ||||
-rw-r--r-- | drivers/clk/starfive/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/starfive/clk-starfive-jh7100-isp.c | 170 | ||||
-rw-r--r-- | include/dt-bindings/clock/starfive-jh7100-isp.h | 42 |
5 files changed, 229 insertions, 0 deletions
diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi index 7ca2ffb1b212..a2f7b6f38900 100755 --- a/arch/riscv/boot/dts/starfive/jh7100.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi @@ -8,6 +8,7 @@ #include "starfive_vic7100_clk.dtsi" #include <dt-bindings/clock/starfive-jh7100.h> #include <dt-bindings/clock/starfive-jh7100-audio.h> +#include <dt-bindings/clock/starfive-jh7100-isp.h> #include <dt-bindings/reset/starfive-jh7100.h> #include <dt-bindings/reset/starfive-jh7100-audio.h> @@ -426,6 +427,15 @@ interrupts = <98>; }; + ispclk: clock-controller@19810000 { + compatible = "starfive,jh7100-ispclk"; + reg = <0x0 0x19810000 0x0 0x10000>; + clocks = <&clkgen JH7100_CLK_VIN_SRC>, + <&clkgen JH7100_CLK_ISPSLV_AXI>; + clock-names = "vin_src", "ispslv_axi"; + #clock-cells = <1>; + }; + vpu_enc: vpu_enc@118e0000 { compatible = "cm,cm521-vpu"; reg = <0x0 0x118e0000 0x0 0x4000>; diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig index d6c6e6ea8a9f..e9e42984cc0e 100755 --- a/drivers/clk/starfive/Kconfig +++ b/drivers/clk/starfive/Kconfig @@ -14,3 +14,9 @@ config CLK_STARFIVE_JH7100_AUDIO default SOC_STARFIVE_VIC7100 help Say yes here to support the audio clocks on the StarFive JH7100 SoC. +config CLK_STARFIVE_JH7100_ISP + tristate "StarFive JH7100 isp clock support" + depends on CLK_STARFIVE_JH7100 + default SOC_STARFIVE + help + Say yes here to support the isp clocks on the StarFive JH7100 SoC. diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile index 0fa8ecb9ec1c..90c28ff8e1d9 100644 --- a/drivers/clk/starfive/Makefile +++ b/drivers/clk/starfive/Makefile @@ -2,3 +2,4 @@ # StarFive Clock obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o +obj-$(CONFIG_CLK_STARFIVE_JH7100_ISP) += clk-starfive-jh7100-isp.o diff --git a/drivers/clk/starfive/clk-starfive-jh7100-isp.c b/drivers/clk/starfive/clk-starfive-jh7100-isp.c new file mode 100644 index 000000000000..c3e1a1b23995 --- /dev/null +++ b/drivers/clk/starfive/clk-starfive-jh7100-isp.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * StarFive JH7100 Isp Clock Driver + * + * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk> + * Copyright (C) 2021 Hal Feng <hal.feng@starfivetech.com> + */ + +#include <linux/bits.h> +#include <linux/clk-provider.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include <dt-bindings/clock/starfive-jh7100-isp.h> + +#include "clk-starfive-jh7100.h" + +/* external clocks */ +#define JH7100_ISPCLK_VIN_SRC (JH7100_ISPCLK_END + 0) +#define JH7100_ISPCLK_ISPSLV_AXI (JH7100_ISPCLK_END + 1) +#define JH7100_ISPCLK_DVP (JH7100_ISPCLK_END + 2) + +static const struct jh7100_clk_data jh7100_ispclk_data[] = { + JH7100_GDIV(JH7100_ISPCLK_DPHY_CFGCLK, "dphy_cfgclk", CLK_IGNORE_UNUSED, 0x1f, JH7100_ISPCLK_ISPCORE_2X), //reg offset: 0x00 + JH7100_GDIV(JH7100_ISPCLK_DPHY_REFCLK, "dphy_refclk", CLK_IGNORE_UNUSED, 0x1f, JH7100_ISPCLK_ISPCORE_2X), + JH7100_GDIV(JH7100_ISPCLK_DPHY_TXCLKESC, "dphy_txclkesc", CLK_IGNORE_UNUSED, 0x3f, JH7100_ISPCLK_ISPCORE_2X), + JH7100__DIV(JH7100_ISPCLK_MIPI_RX0_PXL, "mipi_rx0_pxl", 0x1f, JH7100_ISPCLK_ISPCORE_2X), + JH7100__DIV(JH7100_ISPCLK_MIPI_RX1_PXL, "mipi_rx1_pxl", 0x1f, JH7100_ISPCLK_ISPCORE_2X), //0x10 + + JH7100_GATE(JH7100_ISPCLK_MIPI_RX0_PXL_0, "mipi_rx0_pxl_0", CLK_IGNORE_UNUSED, JH7100_ISPCLK_MIPI_RX0_PXL), + JH7100_GATE(JH7100_ISPCLK_MIPI_RX0_PXL_1, "mipi_rx0_pxl_1", CLK_IGNORE_UNUSED, JH7100_ISPCLK_MIPI_RX0_PXL), + JH7100_GATE(JH7100_ISPCLK_MIPI_RX0_PXL_2, "mipi_rx0_pxl_2", CLK_IGNORE_UNUSED, JH7100_ISPCLK_MIPI_RX0_PXL), + JH7100_GATE(JH7100_ISPCLK_MIPI_RX0_PXL_3, "mipi_rx0_pxl_3", CLK_IGNORE_UNUSED, JH7100_ISPCLK_MIPI_RX0_PXL), //0x20 + JH7100_GDIV(JH7100_ISPCLK_MIPI_RX0_SYS, "mipi_rx0_sys", CLK_IGNORE_UNUSED, 0x1f, JH7100_ISPCLK_ISPCORE_2X), + + JH7100_GATE(JH7100_ISPCLK_MIPI_RX1_PXL_0, "mipi_rx1_pxl_0", CLK_IGNORE_UNUSED, JH7100_ISPCLK_MIPI_RX1_PXL), + JH7100_GATE(JH7100_ISPCLK_MIPI_RX1_PXL_1, "mipi_rx1_pxl_1", CLK_IGNORE_UNUSED, JH7100_ISPCLK_MIPI_RX1_PXL), + JH7100_GATE(JH7100_ISPCLK_MIPI_RX1_PXL_2, "mipi_rx1_pxl_2", CLK_IGNORE_UNUSED, JH7100_ISPCLK_MIPI_RX1_PXL), //0x30 + JH7100_GATE(JH7100_ISPCLK_MIPI_RX1_PXL_3, "mipi_rx1_pxl_3", CLK_IGNORE_UNUSED, JH7100_ISPCLK_MIPI_RX1_PXL), + JH7100_GDIV(JH7100_ISPCLK_MIPI_RX1_SYS, "mipi_rx1_sys", CLK_IGNORE_UNUSED, 0x1f, JH7100_ISPCLK_ISPCORE_2X), + + JH7100_GDIV(JH7100_ISPCLK_ISP0, "isp0", CLK_IGNORE_UNUSED, 0x3, JH7100_ISPCLK_ISPCORE_2X), + JH7100_GATE(JH7100_ISPCLK_ISP0_2X, "isp0_2x", CLK_IGNORE_UNUSED, JH7100_ISPCLK_ISPCORE_2X), //0x40 + JH7100_GMUX(JH7100_ISPCLK_ISP0_MIPI, "isp0_mipi", CLK_IGNORE_UNUSED, 2, + JH7100_ISPCLK_MIPI_RX0_PXL, + JH7100_ISPCLK_MIPI_RX1_PXL,), + + JH7100_GDIV(JH7100_ISPCLK_ISP1, "isp1", CLK_IGNORE_UNUSED, 0x3, JH7100_ISPCLK_ISPCORE_2X), + JH7100_GATE(JH7100_ISPCLK_ISP1_2X, "isp1_2x", CLK_IGNORE_UNUSED, JH7100_ISPCLK_ISPCORE_2X), + JH7100_GMUX(JH7100_ISPCLK_ISP1_MIPI, "isp1_mipi", CLK_IGNORE_UNUSED, 2, //0x50 + JH7100_ISPCLK_MIPI_RX0_PXL, + JH7100_ISPCLK_MIPI_RX1_PXL,), + + JH7100__DIV(JH7100_ISPCLK_DOM4_APB, "dom4_apb", 0x7, JH7100_ISPCLK_ISPSLV_AXI), + JH7100_GATE(JH7100_ISPCLK_CSI2RX_APB, "csi2rx_apb", CLK_IGNORE_UNUSED, JH7100_ISPCLK_DOM4_APB), + JH7100__MUX(JH7100_ISPCLK_VIN_AXI_WR, "vin_axi_wr", 3, + JH7100_ISPCLK_MIPI_RX0_PXL, + JH7100_ISPCLK_MIPI_RX1_PXL, + JH7100_ISPCLK_DVP), + JH7100__MUX(JH7100_ISPCLK_VIN_AXI_RD, "vin_axi_rd", 2, //0x60 + JH7100_ISPCLK_MIPI_RX0_PXL, + JH7100_ISPCLK_MIPI_RX1_PXL), + JH7100__MUX(JH7100_ISPCLK_C_ISP0, "c_isp0", 4, + JH7100_ISPCLK_MIPI_RX0_PXL, + JH7100_ISPCLK_MIPI_RX1_PXL, + JH7100_ISPCLK_DVP, + JH7100_ISPCLK_ISP0), + JH7100__MUX(JH7100_ISPCLK_C_ISP1, "c_isp1", 4, + JH7100_ISPCLK_MIPI_RX0_PXL, + JH7100_ISPCLK_MIPI_RX1_PXL, + JH7100_ISPCLK_DVP, + JH7100_ISPCLK_ISP1), +}; + +static struct clk_hw *jh7100_ispclk_get(struct of_phandle_args *clkspec, void *data) +{ + struct jh7100_clk_priv *priv = data; + unsigned int idx = clkspec->args[0]; + + if (idx < JH7100_ISPCLK_ISPCORE_2X) + return &priv->reg[idx].hw; + + if (idx < JH7100_ISPCLK_END) + return priv->pll[idx - JH7100_ISPCLK_ISPCORE_2X]; + + return ERR_PTR(-EINVAL); +} + +static int jh7100_ispclk_probe(struct platform_device *pdev) +{ + struct jh7100_clk_priv *priv; + unsigned int idx; + int ret; + + priv = devm_kzalloc(&pdev->dev, struct_size(priv, reg, JH7100_ISPCLK_ISPCORE_2X), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + spin_lock_init(&priv->rmw_lock); + priv->dev = &pdev->dev; + priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + priv->pll[0] = clk_hw_register_fixed_factor(priv->dev, "ispcore_2x", + "vin_src", 0, 1, 1); + if (IS_ERR(priv->pll[0])) + return PTR_ERR(priv->pll[0]); + + for (idx = 0; idx < JH7100_ISPCLK_ISPCORE_2X; idx++) { + u32 max = jh7100_ispclk_data[idx].max; + struct clk_parent_data parents[4] = {}; + struct clk_init_data init = { + .name = jh7100_ispclk_data[idx].name, + .ops = starfive_jh7100_clk_ops(max), + .parent_data = parents, + .num_parents = ((max & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT) + 1, + .flags = jh7100_ispclk_data[idx].flags, + }; + struct jh7100_clk *clk = &priv->reg[idx]; + unsigned int i; + + for (i = 0; i < init.num_parents; i++) { + unsigned int pidx = jh7100_ispclk_data[idx].parents[i]; + + if (pidx < JH7100_ISPCLK_ISPCORE_2X) + parents[i].hw = &priv->reg[pidx].hw; + else if (pidx < JH7100_ISPCLK_END) + parents[i].hw = priv->pll[pidx - JH7100_ISPCLK_ISPCORE_2X]; + else if (pidx == JH7100_ISPCLK_VIN_SRC) + parents[i].fw_name = "vin_src"; + else if (pidx == JH7100_ISPCLK_ISPSLV_AXI) + parents[i].fw_name = "ispslv_axi"; + } + + clk->hw.init = &init; + clk->idx = idx; + clk->max_div = max & JH7100_CLK_DIV_MASK; + + ret = devm_clk_hw_register(priv->dev, &clk->hw); + if (ret) + return ret; + } + + return devm_of_clk_add_hw_provider(priv->dev, jh7100_ispclk_get, priv); +} + +static const struct of_device_id jh7100_ispclk_match[] = { + { .compatible = "starfive,jh7100-ispclk" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, jh7100_ispclk_match); + +static struct platform_driver jh7100_ispclk_driver = { + .probe = jh7100_ispclk_probe, + .driver = { + .name = "clk-starfive-jh7100-isp", + .of_match_table = jh7100_ispclk_match, + }, +}; +module_platform_driver(jh7100_ispclk_driver); + +MODULE_AUTHOR("Emil Renner Berthing"); +MODULE_AUTHOR("Hal Feng"); +MODULE_DESCRIPTION("StarFive JH7100 isp clock driver"); +MODULE_LICENSE("GPL"); diff --git a/include/dt-bindings/clock/starfive-jh7100-isp.h b/include/dt-bindings/clock/starfive-jh7100-isp.h new file mode 100644 index 000000000000..7128cbc0a12e --- /dev/null +++ b/include/dt-bindings/clock/starfive-jh7100-isp.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* + * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk> + * Copyright (C) 2021 Hal Feng <hal.feng@starfivetech.com> + */ + +#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7100_ISP_H__ +#define __DT_BINDINGS_CLOCK_STARFIVE_JH7100_ISP_H__ + +#define JH7100_ISPCLK_DPHY_CFGCLK 0 +#define JH7100_ISPCLK_DPHY_REFCLK 1 +#define JH7100_ISPCLK_DPHY_TXCLKESC 2 +#define JH7100_ISPCLK_MIPI_RX0_PXL 3 +#define JH7100_ISPCLK_MIPI_RX1_PXL 4 +#define JH7100_ISPCLK_MIPI_RX0_PXL_0 5 +#define JH7100_ISPCLK_MIPI_RX0_PXL_1 6 +#define JH7100_ISPCLK_MIPI_RX0_PXL_2 7 +#define JH7100_ISPCLK_MIPI_RX0_PXL_3 8 +#define JH7100_ISPCLK_MIPI_RX0_SYS 9 +#define JH7100_ISPCLK_MIPI_RX1_PXL_0 10 +#define JH7100_ISPCLK_MIPI_RX1_PXL_1 11 +#define JH7100_ISPCLK_MIPI_RX1_PXL_2 12 +#define JH7100_ISPCLK_MIPI_RX1_PXL_3 13 +#define JH7100_ISPCLK_MIPI_RX1_SYS 14 +#define JH7100_ISPCLK_ISP0 15 +#define JH7100_ISPCLK_ISP0_2X 16 +#define JH7100_ISPCLK_ISP0_MIPI 17 +#define JH7100_ISPCLK_ISP1 18 +#define JH7100_ISPCLK_ISP1_2X 19 +#define JH7100_ISPCLK_ISP1_MIPI 20 +#define JH7100_ISPCLK_DOM4_APB 21 +#define JH7100_ISPCLK_CSI2RX_APB 22 +#define JH7100_ISPCLK_VIN_AXI_WR 23 +#define JH7100_ISPCLK_VIN_AXI_RD 24 +#define JH7100_ISPCLK_C_ISP0 25 +#define JH7100_ISPCLK_C_ISP1 26 + +#define JH7100_ISPCLK_ISPCORE_2X 27 + +#define JH7100_ISPCLK_END 28 + +#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7100_ISP_H__ */ |