summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHal Feng <hal.feng@starfivetech.com>2021-12-30 05:26:31 +0300
committerMichaelZhuxx <michael.zhu@starfivetech.com>2022-01-04 14:47:25 +0300
commit45d1740c6893e4b89f33c1b391f8372608b997b8 (patch)
tree2d7a524501e33f91339d14b8dbd52be562411018
parent016794a1040c8e1ab002f3aa41659589385eb63b (diff)
downloadlinux-45d1740c6893e4b89f33c1b391f8372608b997b8.tar.xz
media/starfive: use clock and reset api
Signed-off-by: Hal Feng <hal.feng@starfivetech.com> Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-rw-r--r--arch/riscv/boot/dts/starfive/jh7100-common.dtsi1
-rw-r--r--arch/riscv/boot/dts/starfive/jh7100.dtsi144
-rw-r--r--arch/riscv/boot/dts/starfive/starfive_vic7100_clk.dtsi81
-rw-r--r--drivers/clk/starfive/Kconfig7
-rw-r--r--drivers/clk/starfive/Makefile1
-rw-r--r--drivers/clk/starfive/clk-starfive-jh7100-isp.c170
-rwxr-xr-xdrivers/media/platform/starfive/stf_csi_hw_ops.c44
-rwxr-xr-xdrivers/media/platform/starfive/stf_csiphy_hw_ops.c13
-rwxr-xr-xdrivers/media/platform/starfive/stf_isp_hw_ops.c15
-rwxr-xr-xdrivers/media/platform/starfive/stf_vin_hw_ops.c33
-rwxr-xr-xdrivers/media/platform/starfive/stfcamss.c138
-rw-r--r--drivers/media/platform/starfive/stfcamss.h55
-rw-r--r--drivers/reset/starfive/Kconfig7
-rw-r--r--drivers/reset/starfive/Makefile1
-rw-r--r--drivers/reset/starfive/reset-starfive-jh7100-isp.c58
-rw-r--r--include/dt-bindings/clock/starfive-jh7100-isp.h42
-rw-r--r--include/dt-bindings/reset/starfive-jh7100-isp.h34
17 files changed, 630 insertions, 214 deletions
diff --git a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
index a3cad6db9bf6..ee62e5485b3c 100644
--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
@@ -9,7 +9,6 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/pinctrl/pinctrl-starfive.h>
-#include <dt-bindings/starfive_fb.h>
/ {
aliases {
diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
index 5b463e89b16b..9ce9d0c6f316 100644
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -8,8 +8,10 @@
#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>
+#include <dt-bindings/reset/starfive-jh7100-isp.h>
#include <dt-bindings/starfive_fb.h>
/ {
@@ -397,6 +399,21 @@
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>;
+ };
+
+ isprst: reset-controller@19820000 {
+ compatible = "starfive,jh7100-isprst";
+ reg = <0x0 0x19820000 0x0 0x10000>;
+ #reset-cells = <1>;
+ };
+
vin_sysctl: vin_sysctl@19800000 {
compatible = "starfive,stf-vin";
reg = <0x0 0x19800000 0x0 0x10000>,
@@ -421,56 +438,83 @@
<&clkgen JH7100_CLK_ISP1_AXI>,
<&clkgen JH7100_CLK_ISP1NOC_AXI>,
<&clkgen JH7100_CLK_VIN_AXI>,
- <&clkgen JH7100_CLK_VINNOC_AXI>;
- // <&clkgen JH7100_CLK_CSI2RX_APB>,
- // <&clkgen JH7100_CLK_MIPI_RX0_PXL_0>,
- // <&clkgen JH7100_CLK_MIPI_RX0_PXL_1>,
- // <&clkgen JH7100_CLK_MIPI_RX0_PXL_2>,
- // <&clkgen JH7100_CLK_MIPI_RX0_PXL_3>,
- // <&clkgen JH7100_CLK_MIPI_RX0_SYS>,
- // <&clkgen JH7100_CLK_MIPI_RX1_PXL_0>,
- // <&clkgen JH7100_CLK_MIPI_RX1_PXL_1>,
- // <&clkgen JH7100_CLK_MIPI_RX1_PXL_2>,
- // <&clkgen JH7100_CLK_MIPI_RX1_PXL_3>,
- // <&clkgen JH7100_CLK_MIPI_RX1_SYS>,
- // <&clkgen JH7100_CLK_DPHY_CFGCLK>,
- // <&clkgen JH7100_CLK_DPHY_REFCLK>,
- // <&clkgen JH7100_CLK_DPHY_TXCLKESC>,
- // <&clkgen JH7100_CLK_ISP0_CTRL>,
- // <&clkgen JH7100_CLK_ISP0_2X_CTRL>,
- // <&clkgen JH7100_CLK_ISP0_MIPI_CTRL>,
- // <&clkgen JH7100_CLK_ISP1_CTRL>,
- // <&clkgen JH7100_CLK_ISP1_2X_CTRL>,
- // <&clkgen JH7100_CLK_ISP1_MIPI_CTRL>;
-
- clock-names = "vin_src",
- "isp0_axi",
- "isp0noc_axi",
- "ispslv_axi",
- "isp1_axi",
- "isp1noc_axi",
- "vin_axi",
- "vinnoc_axi";
- // "csi2rx_apb_clk",
- // "mipirx0_pixel0",
- // "mipirx0_pixel1",
- // "mipirx0_pixel2",
- // "mipirx0_pixel3",
- // "mipirx0_sys",
- // "mipirx1_pixel0",
- // "mipirx1_pixel1",
- // "mipirx1_pixel2",
- // "mipirx1_pixel3",
- // "mipirx1_sys",
- // "csidphy_cfgclk",
- // "csidphy_regclk",
- // "csidphy_txclkesc",
- // "isp0_ctrl",
- // "isp0_2x_ctrl",
- // "isp0_mipi_ctrl",
- // "isp1_ctrl",
- // "isp1_2x_ctrl",
- // "isp1_mipi_ctrl";
+ <&clkgen JH7100_CLK_VINNOC_AXI>,
+ <&ispclk JH7100_ISPCLK_DPHY_CFGCLK>,
+ <&ispclk JH7100_ISPCLK_DPHY_REFCLK>,
+ <&ispclk JH7100_ISPCLK_DPHY_TXCLKESC>,
+ <&ispclk JH7100_ISPCLK_MIPI_RX0_PXL>,
+ <&ispclk JH7100_ISPCLK_MIPI_RX1_PXL>,
+ <&ispclk JH7100_ISPCLK_MIPI_RX0_PXL_0>,
+ <&ispclk JH7100_ISPCLK_MIPI_RX0_PXL_1>,
+ <&ispclk JH7100_ISPCLK_MIPI_RX0_PXL_2>,
+ <&ispclk JH7100_ISPCLK_MIPI_RX0_PXL_3>,
+ <&ispclk JH7100_ISPCLK_MIPI_RX0_SYS>,
+ <&ispclk JH7100_ISPCLK_MIPI_RX1_PXL_0>,
+ <&ispclk JH7100_ISPCLK_MIPI_RX1_PXL_1>,
+ <&ispclk JH7100_ISPCLK_MIPI_RX1_PXL_2>,
+ <&ispclk JH7100_ISPCLK_MIPI_RX1_PXL_3>,
+ <&ispclk JH7100_ISPCLK_MIPI_RX1_SYS>,
+ <&ispclk JH7100_ISPCLK_ISP0>,
+ <&ispclk JH7100_ISPCLK_ISP0_2X>,
+ <&ispclk JH7100_ISPCLK_ISP0_MIPI>,
+ <&ispclk JH7100_ISPCLK_ISP1>,
+ <&ispclk JH7100_ISPCLK_ISP1_2X>,
+ <&ispclk JH7100_ISPCLK_ISP1_MIPI>,
+ <&ispclk JH7100_ISPCLK_DOM4_APB>,
+ <&ispclk JH7100_ISPCLK_CSI2RX_APB>,
+ <&ispclk JH7100_ISPCLK_VIN_AXI_WR>,
+ <&ispclk JH7100_ISPCLK_VIN_AXI_RD>,
+ <&ispclk JH7100_ISPCLK_C_ISP0>,
+ <&ispclk JH7100_ISPCLK_C_ISP1>;
+
+ clock-names = "vin_src", "isp0_axi", "isp0noc_axi", "ispslv_axi",
+ "isp1_axi", "isp1noc_axi", "vin_axi", "vinnoc_axi",
+ "dphy_cfgclk", "dphy_refclk", "dphy_txclkesc", "mipi_rx0_pxl",
+ "mipi_rx1_pxl", "mipi_rx0_pxl_0", "mipi_rx0_pxl_1", "mipi_rx0_pxl_2",
+ "mipi_rx0_pxl_3", "mipi_rx0_sys", "mipi_rx1_pxl_0", "mipi_rx1_pxl_1",
+ "mipi_rx1_pxl_2", "mipi_rx1_pxl_3", "mipi_rx1_sys", "isp0",
+ "isp0_2x", "isp0_mipi", "isp1", "isp1_2x",
+ "isp1_mipi", "dom4_apb", "csi2rx_apb", "vin_axi_wr",
+ "vin_axi_rd", "c_isp0", "c_isp1";
+
+ resets = <&rstgen JH7100_RSTN_VIN_SRC>,
+ <&rstgen JH7100_RSTN_ISPSLV_AXI>,
+ <&rstgen JH7100_RSTN_VIN_AXI>,
+ <&rstgen JH7100_RSTN_VINNOC_AXI>,
+ <&rstgen JH7100_RSTN_ISP0_AXI>,
+ <&rstgen JH7100_RSTN_ISP0NOC_AXI>,
+ <&rstgen JH7100_RSTN_ISP1_AXI>,
+ <&rstgen JH7100_RSTN_ISP1NOC_AXI>,
+ <&isprst JH7100_ISPRSTN_SYS_CLK>,
+ <&isprst JH7100_ISPRSTN_PCLK>,
+ <&isprst JH7100_ISPRSTN_SYS_CLK_1>,
+ <&isprst JH7100_ISPRSTN_PIXEL_CLK_IF0>,
+ <&isprst JH7100_ISPRSTN_PIXEL_CLK_IF1>,
+ <&isprst JH7100_ISPRSTN_PIXEL_CLK_IF2>,
+ <&isprst JH7100_ISPRSTN_PIXEL_CLK_IF3>,
+ <&isprst JH7100_ISPRSTN_PIXEL_CLK_IF10>,
+ <&isprst JH7100_ISPRSTN_PIXEL_CLK_IF11>,
+ <&isprst JH7100_ISPRSTN_PIXEL_CLK_IF12>,
+ <&isprst JH7100_ISPRSTN_PIXEL_CLK_IF13>,
+ <&isprst JH7100_ISPRST_ISP_0>,
+ <&isprst JH7100_ISPRST_ISP_1>,
+ <&isprst JH7100_ISPRST_P_AXIRD>,
+ <&isprst JH7100_ISPRST_P_AXIWR>,
+ <&isprst JH7100_ISPRST_P_ISP0>,
+ <&isprst JH7100_ISPRST_P_ISP1>,
+ <&isprst JH7100_ISPRST_DPHY_HW_RSTN>,
+ <&isprst JH7100_ISPRST_DPHY_RST09_ALWY_ON>,
+ <&isprst JH7100_ISPRST_C_ISP0>,
+ <&isprst JH7100_ISPRST_C_ISP1>;
+
+ reset-names = "vin_src", "ispslv_axi", "vin_axi", "vinnoc_axi",
+ "isp0_axi", "isp0noc_axi", "isp1_axi", "isp1noc_axi",
+ "sys_clk", "pclk", "sys_clk_1", "pixel_clk_if0",
+ "pixel_clk_if1", "pixel_clk_if2", "pixel_clk_if3", "pixel_clk_if10",
+ "pixel_clk_if11", "pixel_clk_if12", "pixel_clk_if13", "isp_0",
+ "isp_1", "p_axird", "p_axiwr", "p_isp0",
+ "p_isp1", "dphy_hw_rstn", "dphy_rst09_alwy_on", "c_isp0",
+ "c_isp1";
ports {
#address-cells = <1>;
diff --git a/arch/riscv/boot/dts/starfive/starfive_vic7100_clk.dtsi b/arch/riscv/boot/dts/starfive/starfive_vic7100_clk.dtsi
index 6fe645c884e0..fd41a4492c7c 100644
--- a/arch/riscv/boot/dts/starfive/starfive_vic7100_clk.dtsi
+++ b/arch/riscv/boot/dts/starfive/starfive_vic7100_clk.dtsi
@@ -1,33 +1,4 @@
/ {
- hfclk: hfclk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <25000000>;
- clock-output-names = "hfclk";
- };
- rtcclk: rtcclk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <6250000>;
- clock-output-names = "rtcclk";
- };
- axiclk: axiclk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <500000000>;
- clock-output-names = "axiclk";
- };
-
- ahb0clk: ahb0clk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <250000000>;
- };
- ahb2clk: ahb2clk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <125000000>;
- };
apb1clk: apb1clk {
#clock-cells = <0>;
compatible = "fixed-clock";
@@ -38,63 +9,11 @@
compatible = "fixed-clock";
clock-frequency = <125000000>;
};
- jpuclk: jpuclk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <333333333>;
- };
- vpuclk: vpuclk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <400000000>;
- };
- gmacclk: gmacclk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <25000000>;
- };
- qspi_clk: qspi-clk@0 {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <50000000>;
- };
uartclk: uartclk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <100000000>;
};
- hs_uartclk: hs_uartclk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <74250000>;
- };
- dwmmc_biuclk: dwmmc_biuclk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <100000000>;
- };
-/*
- dwmmc_ciuclk: dwmmc_ciuclk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <100000000>;
- };
-*/
- pwmclk: pwmclk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <125000000>;
- };
- spiclk: spiclk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <50000000>;
- };
- audioclk: audioclk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <12288000>;
- };
clk_ext_camera: clk-ext-camera {
#clock-cells = <0>;
compatible = "fixed-clock";
diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index 532b6957742b..be45af0e7658 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -14,3 +14,10 @@ config CLK_STARFIVE_JH7100_AUDIO
default SOC_STARFIVE
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..3852923efdc3
--- /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] = devm_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/drivers/media/platform/starfive/stf_csi_hw_ops.c b/drivers/media/platform/starfive/stf_csi_hw_ops.c
index ce72499bb589..ed988e648944 100755
--- a/drivers/media/platform/starfive/stf_csi_hw_ops.c
+++ b/drivers/media/platform/starfive/stf_csi_hw_ops.c
@@ -6,6 +6,7 @@
*
*/
#include "stfcamss.h"
+#include <linux/clk.h>
#define CSI2RX_DEVICE_CFG_REG 0x000
@@ -68,10 +69,10 @@ static int stf_csi_clk_enable(struct stf_csi_dev *csi_dev)
struct stf_vin_dev *vin = stfcamss->vin;
int ret = 0;
-// #ifdef USE_CLK_TREE
-#if 0
+#ifdef USE_CLK_TREE
+ clk_set_rate(stfcamss->sys_clk[STFCLK_DOM4_APB_CLK].clk, 400000000);
// enable clk
- ret = stfcamss_enable_clocks(1, &stfcamss->sys_clk[STFCLK_CSI_2RX_APH_CLK],
+ ret = stfcamss_enable_clocks(1, &stfcamss->sys_clk[STFCLK_CSI_2RX_APB_CLK],
stfcamss->dev);
if (ret < 0) {
st_err(ST_CSI, "%s enable clk failed\n", __func__);
@@ -82,8 +83,9 @@ static int stf_csi_clk_enable(struct stf_csi_dev *csi_dev)
#endif
if (csi_dev->id == 0) {
- // #ifdef USE_CLK_TREE
- #if 0
+ #ifdef USE_CLK_TREE
+ clk_set_rate(stfcamss->sys_clk[STFCLK_MIPIRX0_PIXEL].clk, 400000000);
+ clk_set_rate(stfcamss->sys_clk[STFCLK_MIPIRX0_SYS].clk, 400000000);
// enable clk
ret = stfcamss_enable_clocks(5, &stfcamss->sys_clk[STFCLK_MIPIRX0_PIXEL0],
stfcamss->dev);
@@ -100,8 +102,9 @@ static int stf_csi_clk_enable(struct stf_csi_dev *csi_dev)
reg_set_highest_bit(vin->clkgen_base, CLK_MIPI_RX0_SYS0_CTRL);
#endif
} else {
- // #ifdef USE_CLK_TREE
- #if 0
+ #ifdef USE_CLK_TREE
+ clk_set_rate(stfcamss->sys_clk[STFCLK_MIPIRX1_PIXEL].clk, 400000000);
+ clk_set_rate(stfcamss->sys_clk[STFCLK_MIPIRX1_SYS].clk, 400000000);
// enable clk
ret = stfcamss_enable_clocks(5, &stfcamss->sys_clk[STFCLK_MIPIRX1_PIXEL0],
stfcamss->dev);
@@ -127,17 +130,15 @@ static int stf_csi_clk_disable(struct stf_csi_dev *csi_dev)
struct stfcamss *stfcamss = csi_dev->stfcamss;
struct stf_vin_dev *vin = stfcamss->vin;
-// #ifdef USE_CLK_TREE
-#if 0
- stfcamss_disable_clocks(1, &stfcamss->sys_clk[STFCLK_CSI_2RX_APH_CLK]);
+#ifdef USE_CLK_TREE
+ stfcamss_disable_clocks(1, &stfcamss->sys_clk[STFCLK_CSI_2RX_APB_CLK]);
#else
// reg_clr_highest_bit(vin->clkgen_base, CLK_CSI2RX0_APB_CTRL);
apb_clk_set(vin, 0);
#endif
if (csi_dev->id == 0) {
- // #ifdef USE_CLK_TREE
- #if 0
+ #ifdef USE_CLK_TREE
// disable clk
stfcamss_disable_clocks(5, &stfcamss->sys_clk[STFCLK_MIPIRX0_PIXEL0]);
#else
@@ -148,8 +149,7 @@ static int stf_csi_clk_disable(struct stf_csi_dev *csi_dev)
reg_clr_highest_bit(vin->clkgen_base, CLK_MIPI_RX0_SYS0_CTRL);
#endif
} else {
- // #ifdef USE_CLK_TREE
- #if 0
+ #ifdef USE_CLK_TREE
// disable clk
stfcamss_disable_clocks(5, &stfcamss->sys_clk[STFCLK_MIPIRX1_PIXEL0]);
#else
@@ -176,9 +176,11 @@ static int stf_csi_config_set(struct stf_csi_dev *csi_dev)
st_info(ST_CSI, "%s, %d: need todo\n", __func__, __LINE__);
break;
case SENSOR_ISP0:
- // #ifdef USE_CLK_TREE
- #if 0
- st_err(ST_CSI, "%s, %d: need todo\n", __func__, __LINE__);
+ #ifdef USE_CLK_TREE
+ clk_set_parent(csi_dev->stfcamss->sys_clk[STFCLK_ISP0_MIPI_CTRL].clk,
+ csi_dev->stfcamss->sys_clk[STFCLK_MIPIRX0_PIXEL + csi_dev->id].clk );
+ clk_set_parent(csi_dev->stfcamss->sys_clk[STFCLK_C_ISP0_CTRL].clk,
+ csi_dev->stfcamss->sys_clk[STFCLK_MIPIRX0_PIXEL + csi_dev->id].clk);
#else
reg_set_bit(vin->clkgen_base, CLK_ISP0_MIPI_CTRL, BIT(24),
csi_dev->id << 24);
@@ -191,9 +193,11 @@ static int stf_csi_config_set(struct stf_csi_dev *csi_dev)
0xF, mipi_channel_sel);
break;
case SENSOR_ISP1:
- // #ifdef USE_CLK_TREE
- #if 0
- st_err(ST_CSI, "%s, %d: need todo\n", __func__, __LINE__);
+ #ifdef USE_CLK_TREE
+ clk_set_parent(csi_dev->stfcamss->sys_clk[STFCLK_ISP1_MIPI_CTRL].clk,
+ csi_dev->stfcamss->sys_clk[STFCLK_MIPIRX0_PIXEL + csi_dev->id].clk );
+ clk_set_parent(csi_dev->stfcamss->sys_clk[STFCLK_C_ISP1_CTRL].clk,
+ csi_dev->stfcamss->sys_clk[STFCLK_MIPIRX0_PIXEL + csi_dev->id].clk);
#else
reg_set_bit(vin->clkgen_base, CLK_ISP1_MIPI_CTRL,
BIT(24), csi_dev->id << 24);
diff --git a/drivers/media/platform/starfive/stf_csiphy_hw_ops.c b/drivers/media/platform/starfive/stf_csiphy_hw_ops.c
index 43b82ad3b791..a345855f058f 100755
--- a/drivers/media/platform/starfive/stf_csiphy_hw_ops.c
+++ b/drivers/media/platform/starfive/stf_csiphy_hw_ops.c
@@ -4,6 +4,7 @@
*/
#include "stfcamss.h"
#include <linux/sort.h>
+#include <linux/clk.h>
static int stf_csiphy_clk_set(struct stf_csiphy_dev *csiphy_dev, int on)
{
@@ -62,13 +63,13 @@ exit:
static int stf_csiphy_clk_enable(struct stf_csiphy_dev *csiphy_dev)
{
-
-
-// #ifdef USE_CLK_TREE
-#if 0
+#ifdef USE_CLK_TREE
// enable clk
struct stfcamss *stfcamss = csiphy_dev->stfcamss;
int ret = 0;
+ clk_set_rate(stfcamss->sys_clk[STFCLK_CSIDPHY_CFGCLK].clk, 100000000);
+ clk_set_rate(stfcamss->sys_clk[STFCLK_CSIDPHY_REFCLK].clk, 50000000);
+ clk_set_rate(stfcamss->sys_clk[STFCLK_CSIDPHY_TXCLKESC].clk, 20000000);
ret = stfcamss_enable_clocks(3, &stfcamss->sys_clk[STFCLK_CSIDPHY_CFGCLK],
stfcamss->dev);
if (ret < 0) {
@@ -83,9 +84,7 @@ static int stf_csiphy_clk_enable(struct stf_csiphy_dev *csiphy_dev)
static int stf_csiphy_clk_disable(struct stf_csiphy_dev *csiphy_dev)
{
-
-// #ifdef USE_CLK_TREE
-#if 0
+#ifdef USE_CLK_TREE
struct stfcamss *stfcamss = csiphy_dev->stfcamss;
stfcamss_disable_clocks(3, &stfcamss->sys_clk[STFCLK_CSIDPHY_CFGCLK]);
return 0;
diff --git a/drivers/media/platform/starfive/stf_isp_hw_ops.c b/drivers/media/platform/starfive/stf_isp_hw_ops.c
index d019fd9af608..ae2fe84c2292 100755
--- a/drivers/media/platform/starfive/stf_isp_hw_ops.c
+++ b/drivers/media/platform/starfive/stf_isp_hw_ops.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <video/stf-vin.h>
#include <linux/delay.h>
+#include <linux/clk.h>
static const regval_t isp_sc2235_reg_config_list[] = {
{0x00000014, 0x00000008, 0, 0},
@@ -174,9 +175,9 @@ static int stf_isp_clk_enable(struct stf_isp_dev *isp_dev)
int ret = 0;
if (isp_dev->id == 0) {
- // #ifdef USE_CLK_TREE
-#if 0
+#ifdef USE_CLK_TREE
// enable clk
+ clk_set_rate(stfcamss->sys_clk[STFCLK_ISP0_CTRL].clk, 400000000);
ret = stfcamss_enable_clocks(3, &stfcamss->sys_clk[STFCLK_ISP0_CTRL],
stfcamss->dev);
if (ret < 0) {
@@ -189,9 +190,9 @@ static int stf_isp_clk_enable(struct stf_isp_dev *isp_dev)
reg_set_highest_bit(vin->clkgen_base, CLK_ISP0_MIPI_CTRL);
#endif
} else {
- //#ifdef USE_CLK_TREE
-#if 0
+#ifdef USE_CLK_TREE
// enable clk
+ clk_set_rate(stfcamss->sys_clk[STFCLK_ISP1_CTRL].clk, 400000000);
ret = stfcamss_enable_clocks(3, &stfcamss->sys_clk[STFCLK_ISP1_CTRL],
stfcamss->dev);
if (ret < 0) {
@@ -214,8 +215,7 @@ static int stf_isp_clk_disable(struct stf_isp_dev *isp_dev)
struct stf_vin_dev *vin = stfcamss->vin;
if (isp_dev->id == 0) {
- // #ifdef USE_CLK_TREE
-#if 0
+#ifdef USE_CLK_TREE
stfcamss_disable_clocks(3, &stfcamss->sys_clk[STFCLK_ISP0_CTRL]);
#else
reg_clr_highest_bit(vin->clkgen_base, CLK_ISP0_CTRL);
@@ -223,8 +223,7 @@ static int stf_isp_clk_disable(struct stf_isp_dev *isp_dev)
reg_clr_highest_bit(vin->clkgen_base, CLK_ISP0_MIPI_CTRL);
#endif
} else {
- // #ifdef USE_CLK_TREE
-#if 0
+#ifdef USE_CLK_TREE
stfcamss_disable_clocks(3, &stfcamss->sys_clk[STFCLK_ISP1_CTRL]);
#else
reg_clr_highest_bit(vin->clkgen_base, CLK_ISP1_CTRL);
diff --git a/drivers/media/platform/starfive/stf_vin_hw_ops.c b/drivers/media/platform/starfive/stf_vin_hw_ops.c
index e75ec940e424..f593be653813 100755
--- a/drivers/media/platform/starfive/stf_vin_hw_ops.c
+++ b/drivers/media/platform/starfive/stf_vin_hw_ops.c
@@ -3,6 +3,7 @@
* Copyright (C) 2021 StarFive Technology Co., Ltd.
*/
#include "stfcamss.h"
+#include <linux/reset.h>
static int vin_rstgen_assert_reset(struct stf_vin_dev *vin)
{
@@ -89,6 +90,7 @@ static int stf_vin_clk_init(struct stf_vin2_dev *vin_dev)
struct stfcamss *stfcamss = vin_dev->stfcamss;
struct stf_vin_dev *vin = stfcamss->vin;
int ret = 0;
+ int i;
#ifdef USE_CLK_TREE
// enable clk
@@ -99,19 +101,29 @@ static int stf_vin_clk_init(struct stf_vin2_dev *vin_dev)
return ret;
}
- vin_rstgen_assert_reset(vin);
+ for (i = STFRST_VIN_SRC; i <= STFRST_ISP1NOC_AXI; i++) {
+ ret = reset_control_reset(stfcamss->sys_rst[i].rst);
+ if(ret){
+ st_err(ST_VIN, "%s reset rst %d failed\n", __func__, i);
+ return ret;
+ }
+ }
// hold vin resets for sub modules before csi2rx controller get configed
- reg_write(vin->rstgen_base, SOFTWARE_RESET_ASSERT0, 0xffffffff);
- mdelay(10);
+ for(i = STFRST_SYS_CLK; i <= STFRST_C_ISP1; i++) {
+ reset_control_assert(stfcamss->sys_rst[i].rst);
+ }
// clear reset for all vin submodules
// except dphy-rx (follow lunhai's advice)
- reg_write(vin->rstgen_base, SOFTWARE_RESET_ASSERT0, 1 << 17);
- mdelay(10);
+ for(i = STFRST_SYS_CLK; i <= STFRST_C_ISP1; i++) {
+ if(i != STFRST_DPHY_HW_RSTN) {
+ reset_control_deassert(stfcamss->sys_rst[i].rst);
+ }
+ }
// disable clk
- stfcamss_disable_clocks(8, &stfcamss->sys_clk[STFCLK_VIN_SRC]);
+ // stfcamss_disable_clocks(8, &stfcamss->sys_clk[STFCLK_VIN_SRC]);
return ret;
#else
val = ioread32(vin->vin_top_clkgen_base + 0x124) >> 24;
@@ -166,6 +178,7 @@ static int stf_vin_clk_enable(struct stf_vin2_dev *vin_dev)
struct stfcamss *stfcamss = vin_dev->stfcamss;
struct stf_vin_dev *vin = stfcamss->vin;
int ret = 0;
+ int i;
#ifdef USE_CLK_TREE
// enable clk
@@ -177,10 +190,14 @@ static int stf_vin_clk_enable(struct stf_vin2_dev *vin_dev)
}
/* rst disable */
- reg_write(vin->rstgen_base, SOFTWARE_RESET_ASSERT0, 0xFFFFFFFF);
+ for(i = STFRST_SYS_CLK; i <= STFRST_C_ISP1; i++) {
+ reset_control_assert(stfcamss->sys_rst[i].rst);
+ }
/* rst enable */
- reg_write(vin->rstgen_base, SOFTWARE_RESET_ASSERT0, 0x0);
+ for(i = STFRST_SYS_CLK; i <= STFRST_C_ISP1; i++) {
+ reset_control_deassert(stfcamss->sys_rst[i].rst);
+ }
return ret;
#else
diff --git a/drivers/media/platform/starfive/stfcamss.c b/drivers/media/platform/starfive/stfcamss.c
index 96c9156d4e7d..91235be2781a 100755
--- a/drivers/media/platform/starfive/stfcamss.c
+++ b/drivers/media/platform/starfive/stfcamss.c
@@ -46,15 +46,17 @@ static const struct reg_name mem_reg_name[] = {
#ifndef CONFIG_VIDEO_CADENCE_CSI2RX
{"mipi0"},
#endif
- {"vclk"},
- {"vrst"},
{"mipi1"},
{"sctrl"},
{"isp0"},
{"isp1"},
- // {"tclk"},
- // {"trst"},
- // {"iopad"}
+#ifndef USE_CLK_TREE
+ {"vclk"},
+ {"vrst"},
+ {"tclk"},
+ {"trst"},
+ {"iopad"},
+#endif
};
char * clocks[] = {
@@ -66,27 +68,68 @@ char * clocks[] = {
"isp1noc_axi",
"vin_axi",
"vinnoc_axi",
- // "csi2rx_apb_clk",
- // "mipirx0_pixel0",
- // "mipirx0_pixel1",
- // "mipirx0_pixel2",
- // "mipirx0_pixel3",
- // "mipirx0_sys",
- // "mipirx1_pixel0",
- // "mipirx1_pixel1",
- // "mipirx1_pixel2",
- // "mipirx1_pixel3",
- // "mipirx1_sys",
- // "csidphy_cfgclk",
- // "csidphy_regclk",
- // "csidphy_txclkesc",
- // "isp0_ctrl",
- // "isp0_2x_ctrl",
- // "isp0_mipi_ctrl",
- // "isp1_ctrl",
- // "isp1_2x_ctrl",
- // "isp1_mipi_ctrl",
+ "dphy_cfgclk",
+ "dphy_refclk",
+ "dphy_txclkesc",
+ "mipi_rx0_pxl",
+ "mipi_rx1_pxl",
+ "mipi_rx0_pxl_0",
+ "mipi_rx0_pxl_1",
+ "mipi_rx0_pxl_2",
+ "mipi_rx0_pxl_3",
+ "mipi_rx0_sys",
+ "mipi_rx1_pxl_0",
+ "mipi_rx1_pxl_1",
+ "mipi_rx1_pxl_2",
+ "mipi_rx1_pxl_3",
+ "mipi_rx1_sys",
+ "isp0",
+ "isp0_2x",
+ "isp0_mipi",
+ "isp1",
+ "isp1_2x",
+ "isp1_mipi",
+ "dom4_apb",
+ "csi2rx_apb",
+ "vin_axi_wr",
+ "vin_axi_rd",
+ "c_isp0",
+ "c_isp1",
+
+ NULL,
+};
+char * resets[]={
+ "vin_src",
+ "ispslv_axi",
+ "vin_axi",
+ "vinnoc_axi",
+ "isp0_axi",
+ "isp0noc_axi",
+ "isp1_axi",
+ "isp1noc_axi",
+ "sys_clk",
+ "pclk",
+ "sys_clk_1",
+ "pixel_clk_if0",
+ "pixel_clk_if1",
+ "pixel_clk_if2",
+ "pixel_clk_if3",
+ "pixel_clk_if10",
+ "pixel_clk_if11",
+ "pixel_clk_if12",
+ "pixel_clk_if13",
+ "isp_0",
+ "isp_1",
+ "p_axird",
+ "p_axiwr",
+ "p_isp0",
+ "p_isp1",
+ "dphy_hw_rstn",
+ "dphy_rst09_alwy_on",
+ "c_isp0",
+ "c_isp1",
+
NULL,
};
@@ -164,14 +207,6 @@ int stfcamss_get_mem_res(struct platform_device *pdev, struct stf_vin_dev *vin)
st_err(ST_CAMSS, "Could not match resource name\n");
}
- #ifdef USE_CLK_TREE
- // vin->clkgen_base = ioremap(ISP_BASE_CLKGEN_ADDR, REG_B_LEN);
- // vin->rstgen_base = ioremap(ISP_BASE_RSTGEN_ADDR, REG_B_LEN);
- vin->vin_top_clkgen_base = ioremap(VIN_TOP_CLKGEN_BASE_ADDR, 0x10000);
- vin->vin_top_rstgen_base = ioremap(VIN_TOP_RSTGEN_BASE_ADDR, 0x10000);
- vin->vin_top_iopad_base = ioremap(VIN_TOP_IOPAD_BASE_ADDR, 0x10000);
- #endif
-
return 0;
}
@@ -1088,6 +1123,33 @@ static int stfcamss_probe(struct platform_device *pdev)
clock->name = clocks[i];
}
+ /* Resets */
+
+ stfcamss->nrsts = 0;
+ while (resets[stfcamss->nrsts])
+ stfcamss->nrsts++;
+
+ st_info(ST_CAMSS, "stfcamss->nrsts %d\n", stfcamss->nrsts);
+ 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)) {
+ ret = -ENOMEM;
+ st_err(ST_CAMSS, "get %s resets name failed\n", resets[i]);
+ goto err_cam_rst;
+ }
+ st_debug(ST_CAMSS, "get %s resets name: \n", resets[i]);
+
+ reset->name = resets[i];
+ }
+
ret = stfcamss_get_mem_res(pdev, vin);
if (ret) {
st_err(ST_CAMSS, "Could not map registers\n");
@@ -1190,9 +1252,15 @@ err_cam_noti_med:
media_device_cleanup(&stfcamss->media_dev);
err_cam_noti:
v4l2_async_notifier_cleanup(&stfcamss->notifier);
- i = stfcamss->nclks;
+err_cam_rst:
+ for (i = stfcamss->nrsts; i > 0; i--) {
+ struct stfcamss_rst *reset = &stfcamss->sys_rst[i];
+
+ reset_control_put(reset->rst);
+ st_debug(ST_CAMSS, "put %s reset\n", reset->name);
+ }
err_cam_clk:
- for (; i > 0; i--) {
+ for (i = stfcamss->nclks; i > 0; i--) {
struct stfcamss_clk *clock = &stfcamss->sys_clk[i];
devm_clk_put(dev, clock->clk);
diff --git a/drivers/media/platform/starfive/stfcamss.h b/drivers/media/platform/starfive/stfcamss.h
index df23ad86cdac..37a48ac5a61e 100644
--- a/drivers/media/platform/starfive/stfcamss.h
+++ b/drivers/media/platform/starfive/stfcamss.h
@@ -48,7 +48,11 @@ enum stf_clk_num {
STFCLK_ISP1NOC_AXI,
STFCLK_VIN_AXI,
STFCLK_VINNOC_AXI,
- STFCLK_CSI_2RX_APH_CLK,
+ STFCLK_CSIDPHY_CFGCLK,
+ STFCLK_CSIDPHY_REFCLK,
+ STFCLK_CSIDPHY_TXCLKESC,
+ STFCLK_MIPIRX0_PIXEL,
+ STFCLK_MIPIRX1_PIXEL,
STFCLK_MIPIRX0_PIXEL0,
STFCLK_MIPIRX0_PIXEL1,
STFCLK_MIPIRX0_PIXEL2,
@@ -59,23 +63,64 @@ enum stf_clk_num {
STFCLK_MIPIRX1_PIXEL2,
STFCLK_MIPIRX1_PIXEL3,
STFCLK_MIPIRX1_SYS,
- STFCLK_CSIDPHY_CFGCLK,
- STFCLK_CSIDPHY_REFCLK,
- STFCLK_CSIDPHY_TXCLKESC,
STFCLK_ISP0_CTRL,
STFCLK_ISP0_2X_CTRL,
STFCLK_ISP0_MIPI_CTRL,
STFCLK_ISP1_CTRL,
STFCLK_ISP1_2X_CTRL,
STFCLK_ISP1_MIPI_CTRL,
+ STFCLK_DOM4_APB_CLK,
+ STFCLK_CSI_2RX_APB_CLK,
+ STFCLK_VIN_AXI_WR_CTRL,
+ STFCLK_VIN_AXI_RD_CTRL,
+ STFCLK_C_ISP0_CTRL,
+ STFCLK_C_ISP1_CTRL,
STFCLK_NUM
};
+enum stf_rst_num {
+ STFRST_VIN_SRC = 0,
+ STFRST_ISPSLV_AXI,
+ STFRST_VIN_AXI,
+ STFRST_VINNOC_AXI,
+ STFRST_ISP0_AXI,
+ STFRST_ISP0NOC_AXI,
+ STFRST_ISP1_AXI,
+ STFRST_ISP1NOC_AXI,
+ STFRST_SYS_CLK,
+ STFRST_PCLK,
+ STFRST_SYS_CLK_1,
+ STFRST_PIXEL_CLK_IF0,
+ STFRST_PIXEL_CLK_IF1,
+ STFRST_PIXEL_CLK_IF2,
+ STFRST_PIXEL_CLK_IF3,
+ STFRST_PIXEL_CLK_IF10,
+ STFRST_PIXEL_CLK_IF11,
+ STFRST_PIXEL_CLK_IF12,
+ STFRST_PIXEL_CLK_IF13,
+ STFRST_ISP_0,
+ STFRST_ISP_1,
+ STFRST_P_AXIRD,
+ STFRST_P_AXIWR,
+ STFRST_P_ISP0,
+ STFRST_P_ISP1,
+ STFRST_DPHY_HW_RSTN,
+ STFRST_DPHY_RST09_ALWY_ON,
+ STFRST_C_ISP0,
+ STFRST_C_ISP1,
+ STFRST_NUM
+};
+
struct stfcamss_clk {
struct clk *clk;
const char *name;
};
+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;
@@ -92,6 +137,8 @@ struct stfcamss {
struct v4l2_async_notifier notifier;
struct stfcamss_clk *sys_clk;
int nclks;
+ struct stfcamss_rst *sys_rst;
+ int nrsts;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_entry;
struct dentry *vin_debugfs;
diff --git a/drivers/reset/starfive/Kconfig b/drivers/reset/starfive/Kconfig
index f8d463196119..2ecbd6faadc9 100644
--- a/drivers/reset/starfive/Kconfig
+++ b/drivers/reset/starfive/Kconfig
@@ -13,3 +13,10 @@ config RESET_STARFIVE_JH7100_AUDIO
default SOC_STARFIVE
help
This enables the audio reset driver for the StarFive JH7100 SoC.
+
+config RESET_STARFIVE_JH7100_ISP
+ tristate "StarFive JH7100 Isp Reset Driver"
+ depends on RESET_STARFIVE_JH7100
+ default SOC_STARFIVE
+ help
+ This enables the isp reset driver for the StarFive JH7100 SoC.
diff --git a/drivers/reset/starfive/Makefile b/drivers/reset/starfive/Makefile
index d3a55a75dd0f..59214d1404a7 100644
--- a/drivers/reset/starfive/Makefile
+++ b/drivers/reset/starfive/Makefile
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
obj-$(CONFIG_RESET_STARFIVE_JH7100_AUDIO) += reset-starfive-jh7100-audio.o
+obj-$(CONFIG_RESET_STARFIVE_JH7100_ISP) += reset-starfive-jh7100-isp.o
diff --git a/drivers/reset/starfive/reset-starfive-jh7100-isp.c b/drivers/reset/starfive/reset-starfive-jh7100-isp.c
new file mode 100644
index 000000000000..11761f1b068c
--- /dev/null
+++ b/drivers/reset/starfive/reset-starfive-jh7100-isp.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Isp reset driver for the StarFive JH7100 SoC
+ *
+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
+ * Copyright (C) 2021 Hal Feng <hal.feng@starfivetech.com>
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/reset/starfive-jh7100-isp.h>
+
+#include "reset-starfive-jh7100.h"
+
+/* register offsets */
+#define JH7100_ISPRST_ASSERT0 0x00
+#define JH7100_ISPRST_STATUS0 0x04
+
+/*
+ * Writing a 1 to the n'th bit of the ASSERT register asserts
+ * line n, and writing a 0 deasserts the same line.
+ * Most reset lines have their status inverted so a 0 bit in the STATUS
+ * register means the line is asserted and a 1 means it's deasserted. A few
+ * lines don't though, so store the expected value of the status registers when
+ * all lines are asserted.
+ */
+static const u32 jh7100_isprst_asserted[1] = {
+ 0,
+};
+
+static int jh7100_isprst_probe(struct platform_device *pdev)
+{
+ return reset_starfive_jh7100_generic_probe(pdev, jh7100_isprst_asserted,
+ JH7100_ISPRST_STATUS0, JH7100_ISPRSTN_END);
+}
+
+static const struct of_device_id jh7100_isprst_dt_ids[] = {
+ { .compatible = "starfive,jh7100-isprst" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jh7100_isprst_dt_ids);
+
+static struct platform_driver jh7100_isprst_driver = {
+ .probe = jh7100_isprst_probe,
+ .driver = {
+ .name = "jh7100-reset-isp",
+ .of_match_table = jh7100_isprst_dt_ids,
+ },
+};
+module_platform_driver(jh7100_isprst_driver);
+
+MODULE_AUTHOR("Emil Renner Berthing");
+MODULE_AUTHOR("Hal Feng");
+MODULE_DESCRIPTION("StarFive JH7100 isp reset 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__ */
diff --git a/include/dt-bindings/reset/starfive-jh7100-isp.h b/include/dt-bindings/reset/starfive-jh7100-isp.h
new file mode 100644
index 000000000000..c8bbe3034486
--- /dev/null
+++ b/include/dt-bindings/reset/starfive-jh7100-isp.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2021 Emil Renner Berthing
+ * Copyright (C) 2021 Hal Feng
+ */
+
+#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7100_ISP_H__
+#define __DT_BINDINGS_RESET_STARFIVE_JH7100_ISP_H__
+
+#define JH7100_ISPRSTN_SYS_CLK 0
+#define JH7100_ISPRSTN_PCLK 1
+#define JH7100_ISPRSTN_SYS_CLK_1 2
+#define JH7100_ISPRSTN_PIXEL_CLK_IF0 3
+#define JH7100_ISPRSTN_PIXEL_CLK_IF1 4
+#define JH7100_ISPRSTN_PIXEL_CLK_IF2 5
+#define JH7100_ISPRSTN_PIXEL_CLK_IF3 6
+#define JH7100_ISPRSTN_PIXEL_CLK_IF10 7
+#define JH7100_ISPRSTN_PIXEL_CLK_IF11 8
+#define JH7100_ISPRSTN_PIXEL_CLK_IF12 9
+#define JH7100_ISPRSTN_PIXEL_CLK_IF13 10
+#define JH7100_ISPRST_ISP_0 11
+#define JH7100_ISPRST_ISP_1 12
+#define JH7100_ISPRST_P_AXIRD 13
+#define JH7100_ISPRST_P_AXIWR 14
+#define JH7100_ISPRST_P_ISP0 15
+#define JH7100_ISPRST_P_ISP1 16
+#define JH7100_ISPRST_DPHY_HW_RSTN 17
+#define JH7100_ISPRST_DPHY_RST09_ALWY_ON 18
+#define JH7100_ISPRST_C_ISP0 19
+#define JH7100_ISPRST_C_ISP1 20
+
+#define JH7100_ISPRSTN_END 21
+
+#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7100_ISP_H__ */