From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c | 738 ++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 654 insertions(+), 84 deletions(-)
diff --git a/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c b/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c
index 0755823..4aada19 100644
--- a/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c
+++ b/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c
@@ -21,11 +21,24 @@
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-device.h>
+#include <linux/reset.h>
#include "phy-rockchip-csi2-dphy-common.h"
+
+/* RK3562 DPHY GRF REG OFFSET */
+#define RK3562_GRF_VI_CON0 (0x0520)
+#define RK3562_GRF_VI_CON1 (0x0524)
/* GRF REG OFFSET */
#define GRF_VI_CON0 (0x0340)
#define GRF_VI_CON1 (0x0344)
+
+/*RK3588 DPHY GRF REG OFFSET */
+#define GRF_DPHY_CON0 (0x0)
+#define GRF_SOC_CON2 (0x0308)
+
+/*RV1106 DPHY GRF REG OFFSET */
+#define GRF_VI_MISC_CON0 (0x50000)
+#define GRF_VI_CSIPHY_CON5 (0x50014)
/*GRF REG BIT DEFINE */
#define GRF_CSI2PHY_LANE_SEL_SPLIT (0x1)
@@ -37,7 +50,11 @@
#define CSI2_DPHY_CTRL_PWRCTL \
CSI2_DPHY_CTRL_INVALID_OFFSET
#define CSI2_DPHY_CTRL_LANE_ENABLE (0x00)
+#define CSI2_DPHY_CLK1_LANE_EN (0x2C)
#define CSI2_DPHY_DUAL_CAL_EN (0x80)
+#define CSI2_DPHY_CLK_INV (0X84)
+
+#define CSI2_DPHY_CLK_CONTINUE_MODE (0x128)
#define CSI2_DPHY_CLK_WR_THS_SETTLE (0x160)
#define CSI2_DPHY_CLK_CALIB_EN (0x168)
#define CSI2_DPHY_LANE0_WR_THS_SETTLE (0x1e0)
@@ -48,8 +65,14 @@
#define CSI2_DPHY_LANE2_CALIB_EN (0x2e8)
#define CSI2_DPHY_LANE3_WR_THS_SETTLE (0x360)
#define CSI2_DPHY_LANE3_CALIB_EN (0x368)
+#define CSI2_DPHY_CLK1_CONTINUE_MODE (0x3a8)
#define CSI2_DPHY_CLK1_WR_THS_SETTLE (0x3e0)
#define CSI2_DPHY_CLK1_CALIB_EN (0x3e8)
+
+#define CSI2_DPHY_PATH0_MODE_SEL (0x44C)
+#define CSI2_DPHY_PATH0_LVDS_MODE_SEL (0x480)
+#define CSI2_DPHY_PATH1_MODE_SEL (0x84C)
+#define CSI2_DPHY_PATH1_LVDS_MODE_SEL (0x880)
/* PHY REG BIT DEFINE */
#define CSI2_DPHY_LANE_MODE_FULL (0x4)
@@ -128,8 +151,26 @@
GRF_DPHY_ISP_CSI2PHY_SEL,
GRF_DPHY_CIF_CSI2PHY_SEL,
GRF_DPHY_CSI2PHY_LANE_SEL,
+ GRF_DPHY_CSI2PHY1_LANE_SEL,
GRF_DPHY_CSI2PHY_DATALANE_EN0,
GRF_DPHY_CSI2PHY_DATALANE_EN1,
+ GRF_CPHY_MODE,
+ GRF_DPHY_CSIHOST2_SEL,
+ GRF_DPHY_CSIHOST3_SEL,
+ GRF_DPHY_CSIHOST4_SEL,
+ GRF_DPHY_CSIHOST5_SEL,
+ /* below is for rv1106 only */
+ GRF_MIPI_HOST0_SEL,
+ GRF_LVDS_HOST0_SEL,
+ /* below is for rk3562 */
+ GRF_DPHY1_CLK_INV_SEL,
+ GRF_DPHY1_CLK1_INV_SEL,
+ GRF_DPHY1_CSI2PHY_CLKLANE1_EN,
+ GRF_DPHY1_CSI2PHY_FORCERXMODE,
+ GRF_DPHY1_CSI2PHY_CLKLANE_EN,
+ GRF_DPHY1_CSI2PHY_DATALANE_EN,
+ GRF_DPHY1_CSI2PHY_DATALANE_EN0,
+ GRF_DPHY1_CSI2PHY_DATALANE_EN1,
};
enum csi2dphy_reg_id {
@@ -152,7 +193,30 @@
//rk3568 only
CSI2PHY_DUAL_CLK_EN,
CSI2PHY_CLK1_THS_SETTLE,
- CSI2PHY_CLK1_CALIB_ENABLE
+ CSI2PHY_CLK1_CALIB_ENABLE,
+ //rk3588
+ CSI2PHY_CLK_LANE_ENABLE,
+ CSI2PHY_CLK1_LANE_ENABLE,
+ CSI2PHY_DATA_LANE0_ENABLE,
+ CSI2PHY_DATA_LANE1_ENABLE,
+ CSI2PHY_DATA_LANE2_ENABLE,
+ CSI2PHY_DATA_LANE3_ENABLE,
+ CSI2PHY_LANE0_ERR_SOT_SYNC,
+ CSI2PHY_LANE1_ERR_SOT_SYNC,
+ CSI2PHY_LANE2_ERR_SOT_SYNC,
+ CSI2PHY_LANE3_ERR_SOT_SYNC,
+ CSI2PHY_S0C_GNR_CON1,
+ CSI2PHY_COMBO_S0D0_GNR_CON1,
+ CSI2PHY_COMBO_S0D1_GNR_CON1,
+ CSI2PHY_COMBO_S0D2_GNR_CON1,
+ CSI2PHY_S0D3_GNR_CON1,
+ CSI2PHY_PATH0_MODEL,
+ CSI2PHY_PATH0_LVDS_MODEL,
+ CSI2PHY_PATH1_MODEL,
+ CSI2PHY_PATH1_LVDS_MODEL,
+ CSI2PHY_CLK_INV,
+ CSI2PHY_CLK_CONTINUE_MODE,
+ CSI2PHY_CLK1_CONTINUE_MODE,
};
#define HIWORD_UPDATE(val, mask, shift) \
@@ -166,25 +230,49 @@
struct hsfreq_range {
u32 range_h;
- u8 cfg_bit;
+ u16 cfg_bit;
};
+
+static inline void write_sys_grf_reg(struct csi2_dphy_hw *hw,
+ int index, u8 value)
+{
+ const struct grf_reg *reg = NULL;
+ unsigned int val = 0;
+
+ if (index >= hw->drv_data->num_grf_regs)
+ return;
+
+ reg = &hw->grf_regs[index];
+ val = HIWORD_UPDATE(value, reg->mask, reg->shift);
+ if (reg->mask)
+ regmap_write(hw->regmap_sys_grf, reg->offset, val);
+}
static inline void write_grf_reg(struct csi2_dphy_hw *hw,
int index, u8 value)
{
- const struct grf_reg *reg = &hw->grf_regs[index];
- unsigned int val = HIWORD_UPDATE(value, reg->mask, reg->shift);
+ const struct grf_reg *reg = NULL;
+ unsigned int val = 0;
- if (reg->offset)
+ if (index >= hw->drv_data->num_grf_regs)
+ return;
+
+ reg = &hw->grf_regs[index];
+ val = HIWORD_UPDATE(value, reg->mask, reg->shift);
+ if (reg->mask)
regmap_write(hw->regmap_grf, reg->offset, val);
}
static inline u32 read_grf_reg(struct csi2_dphy_hw *hw, int index)
{
- const struct grf_reg *reg = &hw->grf_regs[index];
+ const struct grf_reg *reg = NULL;
unsigned int val = 0;
- if (reg->offset) {
+ if (index >= hw->drv_data->num_grf_regs)
+ return -EINVAL;
+
+ reg = &hw->grf_regs[index];
+ if (reg->mask) {
regmap_read(hw->regmap_grf, reg->offset, &val);
val = (val >> reg->shift) & reg->mask;
}
@@ -195,20 +283,46 @@
static inline void write_csi2_dphy_reg(struct csi2_dphy_hw *hw,
int index, u32 value)
{
- const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index];
+ const struct csi2dphy_reg *reg = NULL;
+ if (index >= hw->drv_data->num_csi2dphy_regs)
+ return;
+
+ reg = &hw->csi2dphy_regs[index];
if ((index == CSI2PHY_REG_CTRL_LANE_ENABLE) ||
+ (index == CSI2PHY_CLK_LANE_ENABLE) ||
(index != CSI2PHY_REG_CTRL_LANE_ENABLE &&
reg->offset != 0x0))
writel(value, hw->hw_base_addr + reg->offset);
}
+static inline void write_csi2_dphy_reg_mask(struct csi2_dphy_hw *hw,
+ int index, u32 value, u32 mask)
+{
+ const struct csi2dphy_reg *reg = NULL;
+ u32 read_val = 0;
+
+ if (index >= hw->drv_data->num_csi2dphy_regs)
+ return;
+
+ reg = &hw->csi2dphy_regs[index];
+ read_val = readl(hw->hw_base_addr + reg->offset);
+ read_val &= ~mask;
+ read_val |= value;
+ writel(read_val, hw->hw_base_addr + reg->offset);
+}
+
static inline void read_csi2_dphy_reg(struct csi2_dphy_hw *hw,
int index, u32 *value)
{
- const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index];
+ const struct csi2dphy_reg *reg = NULL;
+ if (index >= hw->drv_data->num_csi2dphy_regs)
+ return;
+
+ reg = &hw->csi2dphy_regs[index];
if ((index == CSI2PHY_REG_CTRL_LANE_ENABLE) ||
+ (index == CSI2PHY_CLK_LANE_ENABLE) ||
(index != CSI2PHY_REG_CTRL_LANE_ENABLE &&
reg->offset != 0x0))
*value = readl(hw->hw_base_addr + reg->offset);
@@ -280,8 +394,116 @@
[CSI2PHY_CLK1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CALIB_EN),
};
-static const struct clk_bulk_data rk3568_csi2_dphy_hw_clks[] = {
- { .id = "pclk" },
+static const struct grf_reg rk3588_grf_dphy_regs[] = {
+ [GRF_DPHY_CSI2PHY_FORCERXMODE] = GRF_REG(GRF_DPHY_CON0, 4, 0),
+ [GRF_DPHY_CSI2PHY_DATALANE_EN] = GRF_REG(GRF_DPHY_CON0, 4, 4),
+ [GRF_DPHY_CSI2PHY_DATALANE_EN0] = GRF_REG(GRF_DPHY_CON0, 2, 4),
+ [GRF_DPHY_CSI2PHY_DATALANE_EN1] = GRF_REG(GRF_DPHY_CON0, 2, 6),
+ [GRF_DPHY_CSI2PHY_CLKLANE_EN] = GRF_REG(GRF_DPHY_CON0, 1, 8),
+ [GRF_DPHY_CLK_INV_SEL] = GRF_REG(GRF_DPHY_CON0, 1, 9),
+ [GRF_DPHY_CSI2PHY_CLKLANE1_EN] = GRF_REG(GRF_DPHY_CON0, 1, 10),
+ [GRF_DPHY_CLK1_INV_SEL] = GRF_REG(GRF_DPHY_CON0, 1, 11),
+ [GRF_DPHY_CSI2PHY_LANE_SEL] = GRF_REG(GRF_SOC_CON2, 1, 6),
+ [GRF_DPHY_CSI2PHY1_LANE_SEL] = GRF_REG(GRF_SOC_CON2, 1, 7),
+ [GRF_DPHY_CSIHOST2_SEL] = GRF_REG(GRF_SOC_CON2, 1, 8),
+ [GRF_DPHY_CSIHOST3_SEL] = GRF_REG(GRF_SOC_CON2, 1, 9),
+ [GRF_DPHY_CSIHOST4_SEL] = GRF_REG(GRF_SOC_CON2, 1, 10),
+ [GRF_DPHY_CSIHOST5_SEL] = GRF_REG(GRF_SOC_CON2, 1, 11),
+};
+
+static const struct csi2dphy_reg rk3588_csi2dphy_regs[] = {
+ [CSI2PHY_REG_CTRL_LANE_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CTRL_LANE_ENABLE),
+ [CSI2PHY_DUAL_CLK_EN] = CSI2PHY_REG(CSI2_DPHY_DUAL_CAL_EN),
+ [CSI2PHY_CLK_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_CLK_WR_THS_SETTLE),
+ [CSI2PHY_CLK_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK_CALIB_EN),
+ [CSI2PHY_LANE0_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE0_WR_THS_SETTLE),
+ [CSI2PHY_LANE0_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE0_CALIB_EN),
+ [CSI2PHY_LANE1_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE1_WR_THS_SETTLE),
+ [CSI2PHY_LANE1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE1_CALIB_EN),
+ [CSI2PHY_LANE2_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE2_WR_THS_SETTLE),
+ [CSI2PHY_LANE2_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE2_CALIB_EN),
+ [CSI2PHY_LANE3_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE3_WR_THS_SETTLE),
+ [CSI2PHY_LANE3_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE3_CALIB_EN),
+ [CSI2PHY_CLK1_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_WR_THS_SETTLE),
+ [CSI2PHY_CLK1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CALIB_EN),
+ [CSI2PHY_CLK1_LANE_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_LANE_EN),
+ [CSI2PHY_CLK_CONTINUE_MODE] = CSI2PHY_REG(CSI2_DPHY_CLK_CONTINUE_MODE),
+ [CSI2PHY_CLK1_CONTINUE_MODE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CONTINUE_MODE),
+};
+
+static const struct grf_reg rv1106_grf_dphy_regs[] = {
+ [GRF_DPHY_CSI2PHY_FORCERXMODE] = GRF_REG(GRF_VI_CSIPHY_CON5, 4, 0),
+ [GRF_DPHY_CSI2PHY_CLKLANE_EN] = GRF_REG(GRF_VI_CSIPHY_CON5, 1, 8),
+ [GRF_DPHY_CSI2PHY_DATALANE_EN] = GRF_REG(GRF_VI_CSIPHY_CON5, 4, 4),
+ [GRF_DPHY_CSI2PHY_DATALANE_EN0] = GRF_REG(GRF_VI_CSIPHY_CON5, 2, 4),
+ [GRF_DPHY_CSI2PHY_DATALANE_EN1] = GRF_REG(GRF_VI_CSIPHY_CON5, 2, 6),
+ [GRF_DPHY_CLK_INV_SEL] = GRF_REG(GRF_VI_CSIPHY_CON5, 1, 9),
+ [GRF_DPHY_CSI2PHY_CLKLANE1_EN] = GRF_REG(GRF_VI_CSIPHY_CON5, 1, 10),
+ [GRF_DPHY_CLK1_INV_SEL] = GRF_REG(GRF_VI_CSIPHY_CON5, 1, 11),
+ [GRF_MIPI_HOST0_SEL] = GRF_REG(GRF_VI_MISC_CON0, 1, 0),
+ [GRF_LVDS_HOST0_SEL] = GRF_REG(GRF_VI_MISC_CON0, 1, 2),
+};
+
+static const struct csi2dphy_reg rv1106_csi2dphy_regs[] = {
+ [CSI2PHY_REG_CTRL_LANE_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CTRL_LANE_ENABLE),
+ [CSI2PHY_DUAL_CLK_EN] = CSI2PHY_REG(CSI2_DPHY_DUAL_CAL_EN),
+ [CSI2PHY_CLK_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_CLK_WR_THS_SETTLE),
+ [CSI2PHY_CLK_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK_CALIB_EN),
+ [CSI2PHY_LANE0_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE0_WR_THS_SETTLE),
+ [CSI2PHY_LANE0_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE0_CALIB_EN),
+ [CSI2PHY_LANE1_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE1_WR_THS_SETTLE),
+ [CSI2PHY_LANE1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE1_CALIB_EN),
+ [CSI2PHY_LANE2_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE2_WR_THS_SETTLE),
+ [CSI2PHY_LANE2_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE2_CALIB_EN),
+ [CSI2PHY_LANE3_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE3_WR_THS_SETTLE),
+ [CSI2PHY_LANE3_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE3_CALIB_EN),
+ [CSI2PHY_CLK1_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_WR_THS_SETTLE),
+ [CSI2PHY_CLK1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CALIB_EN),
+ [CSI2PHY_CLK1_LANE_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_LANE_EN),
+ [CSI2PHY_PATH0_MODEL] = CSI2PHY_REG(CSI2_DPHY_PATH0_MODE_SEL),
+ [CSI2PHY_PATH0_LVDS_MODEL] = CSI2PHY_REG(CSI2_DPHY_PATH0_LVDS_MODE_SEL),
+ [CSI2PHY_PATH1_MODEL] = CSI2PHY_REG(CSI2_DPHY_PATH1_MODE_SEL),
+ [CSI2PHY_PATH1_LVDS_MODEL] = CSI2PHY_REG(CSI2_DPHY_PATH1_LVDS_MODE_SEL),
+ [CSI2PHY_CLK_INV] = CSI2PHY_REG(CSI2_DPHY_CLK_INV),
+};
+
+static const struct grf_reg rk3562_grf_dphy_regs[] = {
+ [GRF_DPHY_CSI2PHY_FORCERXMODE] = GRF_REG(RK3562_GRF_VI_CON0, 4, 0),
+ [GRF_DPHY_CSI2PHY_DATALANE_EN] = GRF_REG(RK3562_GRF_VI_CON0, 4, 4),
+ [GRF_DPHY_CSI2PHY_DATALANE_EN0] = GRF_REG(RK3562_GRF_VI_CON0, 2, 4),
+ [GRF_DPHY_CSI2PHY_DATALANE_EN1] = GRF_REG(RK3562_GRF_VI_CON0, 2, 6),
+ [GRF_DPHY_CSI2PHY_CLKLANE_EN] = GRF_REG(RK3562_GRF_VI_CON0, 1, 8),
+ [GRF_DPHY_CLK_INV_SEL] = GRF_REG(RK3562_GRF_VI_CON0, 1, 9),
+ [GRF_DPHY_CSI2PHY_CLKLANE1_EN] = GRF_REG(RK3562_GRF_VI_CON0, 1, 10),
+ [GRF_DPHY_CLK1_INV_SEL] = GRF_REG(RK3562_GRF_VI_CON0, 1, 11),
+ [GRF_DPHY_CSI2PHY_LANE_SEL] = GRF_REG(RK3562_GRF_VI_CON0, 1, 12),
+ [GRF_DPHY_CSI2PHY1_LANE_SEL] = GRF_REG(RK3562_GRF_VI_CON0, 1, 13),
+ [GRF_DPHY1_CSI2PHY_FORCERXMODE] = GRF_REG(RK3562_GRF_VI_CON1, 4, 0),
+ [GRF_DPHY1_CSI2PHY_DATALANE_EN] = GRF_REG(RK3562_GRF_VI_CON1, 4, 4),
+ [GRF_DPHY1_CSI2PHY_DATALANE_EN0] = GRF_REG(RK3562_GRF_VI_CON1, 2, 4),
+ [GRF_DPHY1_CSI2PHY_DATALANE_EN1] = GRF_REG(RK3562_GRF_VI_CON1, 2, 6),
+ [GRF_DPHY1_CSI2PHY_CLKLANE_EN] = GRF_REG(RK3562_GRF_VI_CON1, 1, 8),
+ [GRF_DPHY1_CLK_INV_SEL] = GRF_REG(RK3562_GRF_VI_CON1, 1, 9),
+ [GRF_DPHY1_CSI2PHY_CLKLANE1_EN] = GRF_REG(RK3562_GRF_VI_CON1, 1, 10),
+ [GRF_DPHY1_CLK1_INV_SEL] = GRF_REG(RK3562_GRF_VI_CON1, 1, 11),
+};
+
+static const struct csi2dphy_reg rk3562_csi2dphy_regs[] = {
+ [CSI2PHY_REG_CTRL_LANE_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CTRL_LANE_ENABLE),
+ [CSI2PHY_DUAL_CLK_EN] = CSI2PHY_REG(CSI2_DPHY_DUAL_CAL_EN),
+ [CSI2PHY_CLK_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_CLK_WR_THS_SETTLE),
+ [CSI2PHY_CLK_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK_CALIB_EN),
+ [CSI2PHY_LANE0_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE0_WR_THS_SETTLE),
+ [CSI2PHY_LANE0_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE0_CALIB_EN),
+ [CSI2PHY_LANE1_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE1_WR_THS_SETTLE),
+ [CSI2PHY_LANE1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE1_CALIB_EN),
+ [CSI2PHY_LANE2_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE2_WR_THS_SETTLE),
+ [CSI2PHY_LANE2_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE2_CALIB_EN),
+ [CSI2PHY_LANE3_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_LANE3_WR_THS_SETTLE),
+ [CSI2PHY_LANE3_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_LANE3_CALIB_EN),
+ [CSI2PHY_CLK1_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_WR_THS_SETTLE),
+ [CSI2PHY_CLK1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CALIB_EN),
+ [CSI2PHY_CLK1_LANE_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_LANE_EN),
};
/* These tables must be sorted by .range_h ascending. */
@@ -321,6 +543,51 @@
return NULL;
}
+static unsigned char get_lvds_data_width(u32 pixelformat)
+{
+ switch (pixelformat) {
+ /* csi raw8 */
+ case MEDIA_BUS_FMT_SBGGR8_1X8:
+ case MEDIA_BUS_FMT_SGBRG8_1X8:
+ case MEDIA_BUS_FMT_SGRBG8_1X8:
+ case MEDIA_BUS_FMT_SRGGB8_1X8:
+ return 0x2;
+ /* csi raw10 */
+ case MEDIA_BUS_FMT_SBGGR10_1X10:
+ case MEDIA_BUS_FMT_SGBRG10_1X10:
+ case MEDIA_BUS_FMT_SGRBG10_1X10:
+ case MEDIA_BUS_FMT_SRGGB10_1X10:
+ return 0x0;
+ /* csi raw12 */
+ case MEDIA_BUS_FMT_SBGGR12_1X12:
+ case MEDIA_BUS_FMT_SGBRG12_1X12:
+ case MEDIA_BUS_FMT_SGRBG12_1X12:
+ case MEDIA_BUS_FMT_SRGGB12_1X12:
+ return 0x1;
+ /* csi uyvy 422 */
+ case MEDIA_BUS_FMT_UYVY8_2X8:
+ case MEDIA_BUS_FMT_VYUY8_2X8:
+ case MEDIA_BUS_FMT_YUYV8_2X8:
+ case MEDIA_BUS_FMT_YVYU8_2X8:
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ return 0x2;
+
+ default:
+ return 0x2;
+ }
+}
+
+static void csi2_dphy_hw_do_reset(struct csi2_dphy_hw *hw)
+{
+ if (hw->rsts_bulk)
+ reset_control_assert(hw->rsts_bulk);
+
+ udelay(5);
+
+ if (hw->rsts_bulk)
+ reset_control_deassert(hw->rsts_bulk);
+}
+
static void csi2_dphy_config_dual_mode(struct csi2_dphy *dphy,
struct csi2_sensor *sensor)
{
@@ -337,38 +604,108 @@
is_cif = false;
if (hw->lane_mode == LANE_MODE_FULL) {
- val = ~GRF_CSI2PHY_LANE_SEL_SPLIT;
- write_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
- write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN,
- GENMASK(sensor->lanes - 1, 0));
- write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE_EN, 0x1);
+ val = !GRF_CSI2PHY_LANE_SEL_SPLIT;
+ if (dphy->phy_index < 3) {
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN,
+ GENMASK(sensor->lanes - 1, 0));
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE_EN, 0x1);
+ if (hw->drv_data->chip_id != CHIP_ID_RK3588)
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
+ else
+ write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
+ } else {
+ if (hw->drv_data->chip_id <= CHIP_ID_RK3588) {
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN,
+ GENMASK(sensor->lanes - 1, 0));
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE_EN, 0x1);
+ } else {
+ write_grf_reg(hw, GRF_DPHY1_CSI2PHY_DATALANE_EN,
+ GENMASK(sensor->lanes - 1, 0));
+ write_grf_reg(hw, GRF_DPHY1_CSI2PHY_CLKLANE_EN, 0x1);
+ }
+ if (hw->drv_data->chip_id != CHIP_ID_RK3588)
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY1_LANE_SEL, val);
+ else
+ write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY1_LANE_SEL, val);
+ }
} else {
val = GRF_CSI2PHY_LANE_SEL_SPLIT;
- write_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
- if (dphy->phy_index == DPHY1) {
+ switch (dphy->phy_index) {
+ case 1:
write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN0,
GENMASK(sensor->lanes - 1, 0));
write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE_EN, 0x1);
- if (is_cif)
- write_grf_reg(hw, GRF_DPHY_CIF_CSI2PHY_SEL,
- GRF_CSI2PHY_SEL_SPLIT_0_1);
- else
- write_grf_reg(hw, GRF_DPHY_ISP_CSI2PHY_SEL,
- GRF_CSI2PHY_SEL_SPLIT_0_1);
- }
-
- if (dphy->phy_index == DPHY2) {
+ if (hw->drv_data->chip_id < CHIP_ID_RK3588) {
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
+ if (is_cif)
+ write_grf_reg(hw, GRF_DPHY_CIF_CSI2PHY_SEL,
+ GRF_CSI2PHY_SEL_SPLIT_0_1);
+ else
+ write_grf_reg(hw, GRF_DPHY_ISP_CSI2PHY_SEL,
+ GRF_CSI2PHY_SEL_SPLIT_0_1);
+ } else if (hw->drv_data->chip_id == CHIP_ID_RK3588) {
+ write_sys_grf_reg(hw, GRF_DPHY_CSIHOST2_SEL, 0x0);
+ write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
+ } else if (hw->drv_data->chip_id == CHIP_ID_RV1106) {
+ if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY)
+ write_grf_reg(hw, GRF_MIPI_HOST0_SEL, 0x1);
+ else
+ write_grf_reg(hw, GRF_LVDS_HOST0_SEL, 0x1);
+ } else if (hw->drv_data->chip_id == CHIP_ID_RK3562) {
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
+ }
+ break;
+ case 2:
write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN1,
GENMASK(sensor->lanes - 1, 0));
write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE1_EN, 0x1);
- if (is_cif)
- write_grf_reg(hw, GRF_DPHY_CIF_CSI2PHY_SEL,
- GRF_CSI2PHY_SEL_SPLIT_2_3);
- else
- write_grf_reg(hw, GRF_DPHY_ISP_CSI2PHY_SEL,
- GRF_CSI2PHY_SEL_SPLIT_2_3);
- }
+ if (hw->drv_data->chip_id < CHIP_ID_RK3588) {
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
+ if (is_cif)
+ write_grf_reg(hw, GRF_DPHY_CIF_CSI2PHY_SEL,
+ GRF_CSI2PHY_SEL_SPLIT_2_3);
+ else
+ write_grf_reg(hw, GRF_DPHY_ISP_CSI2PHY_SEL,
+ GRF_CSI2PHY_SEL_SPLIT_2_3);
+ } else if (hw->drv_data->chip_id == CHIP_ID_RK3588) {
+ write_sys_grf_reg(hw, GRF_DPHY_CSIHOST3_SEL, 0x1);
+ write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
+ } else if (hw->drv_data->chip_id == CHIP_ID_RK3562) {
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
+ }
+ break;
+ case 4:
+ if (hw->drv_data->chip_id == CHIP_ID_RK3588) {
+ write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY1_LANE_SEL, val);
+ write_sys_grf_reg(hw, GRF_DPHY_CSIHOST4_SEL, 0x0);
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN0,
+ GENMASK(sensor->lanes - 1, 0));
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE_EN, 0x1);
+ } else if (hw->drv_data->chip_id == CHIP_ID_RK3562) {
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY1_LANE_SEL, val);
+ write_grf_reg(hw, GRF_DPHY1_CSI2PHY_DATALANE_EN0,
+ GENMASK(sensor->lanes - 1, 0));
+ write_grf_reg(hw, GRF_DPHY1_CSI2PHY_CLKLANE_EN, 0x1);
+ }
+ break;
+ case 5:
+ if (hw->drv_data->chip_id == CHIP_ID_RK3588) {
+ write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY1_LANE_SEL, val);
+ write_sys_grf_reg(hw, GRF_DPHY_CSIHOST5_SEL, 0x1);
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN1,
+ GENMASK(sensor->lanes - 1, 0));
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE1_EN, 0x1);
+ } else if (hw->drv_data->chip_id == CHIP_ID_RK3562) {
+ write_grf_reg(hw, GRF_DPHY_CSI2PHY1_LANE_SEL, val);
+ write_grf_reg(hw, GRF_DPHY1_CSI2PHY_DATALANE_EN1,
+ GENMASK(sensor->lanes - 1, 0));
+ write_grf_reg(hw, GRF_DPHY1_CSI2PHY_CLKLANE1_EN, 0x1);
+ }
+ break;
+ default:
+ break;
+ };
}
}
@@ -376,13 +713,20 @@
struct v4l2_subdev *sd)
{
struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
- struct csi2_sensor *sensor = sd_to_sensor(dphy, sensor_sd);
+ struct csi2_sensor *sensor;
struct csi2_dphy_hw *hw = dphy->dphy_hw;
const struct dphy_hw_drv_data *drv_data = hw->drv_data;
const struct hsfreq_range *hsfreq_ranges = drv_data->hsfreq_ranges;
int num_hsfreq_ranges = drv_data->num_hsfreq_ranges;
int i, hsfreq = 0;
u32 val = 0, pre_val;
+ u8 lvds_width = 0;
+
+ if (!sensor_sd)
+ return -ENODEV;
+ sensor = sd_to_sensor(dphy, sensor_sd);
+ if (!sensor)
+ return -ENODEV;
mutex_lock(&hw->mutex);
@@ -397,35 +741,47 @@
val |= (GENMASK(sensor->lanes - 1, 0) <<
CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT) |
(0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
+ if (sensor->mbus.flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)
+ write_csi2_dphy_reg(hw, CSI2PHY_CLK_CONTINUE_MODE, 0x30);
} else {
if (!(pre_val & (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT)))
val |= (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
- if (dphy->phy_index == DPHY1)
+ if (dphy->phy_index % 3 == DPHY1) {
val |= (GENMASK(sensor->lanes - 1, 0) <<
CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT);
+ if (sensor->mbus.flags &
+ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)
+ write_csi2_dphy_reg(
+ hw, CSI2PHY_CLK_CONTINUE_MODE, 0x30);
+ }
- if (dphy->phy_index == DPHY2)
+ if (dphy->phy_index % 3 == DPHY2) {
val |= (GENMASK(sensor->lanes - 1, 0) <<
CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT);
+ if (hw->drv_data->chip_id >= CHIP_ID_RK3588)
+ write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(6));
+ if (sensor->mbus.flags &
+ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)
+ write_csi2_dphy_reg(
+ hw, CSI2PHY_CLK1_CONTINUE_MODE, 0x30);
+ }
}
val |= pre_val;
write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, val);
- if (sensor->mbus.type == V4L2_MBUS_CSI2) {
- /* Reset dphy digital part */
- if (hw->lane_mode == LANE_MODE_FULL) {
- write_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, 0x1e);
- write_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, 0x1f);
- } else {
- read_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, &val);
- if (!(val & CSI2_DPHY_LANE_DUAL_MODE_EN)) {
- write_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, 0x5e);
- write_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, 0x5f);
- }
+ /* Reset dphy digital part */
+ if (hw->lane_mode == LANE_MODE_FULL) {
+ write_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, 0x1e);
+ write_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, 0x1f);
+ } else {
+ read_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, &val);
+ if (!(val & CSI2_DPHY_LANE_DUAL_MODE_EN)) {
+ write_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, 0x5e);
+ write_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, 0x5f);
}
- csi2_dphy_config_dual_mode(dphy, sensor);
}
+ csi2_dphy_config_dual_mode(dphy, sensor);
/* not into receive mode/wait stopstate */
write_grf_reg(hw, GRF_DPHY_CSI2PHY_FORCERXMODE, 0x0);
@@ -443,7 +799,7 @@
if (sensor->lanes > 0x03)
write_csi2_dphy_reg(hw, CSI2PHY_LANE3_CALIB_ENABLE, 0x80);
} else {
- if (dphy->phy_index == DPHY1) {
+ if (dphy->phy_index % 3 == DPHY1) {
write_csi2_dphy_reg(hw, CSI2PHY_CLK_CALIB_ENABLE, 0x80);
if (sensor->lanes > 0x00)
write_csi2_dphy_reg(hw, CSI2PHY_LANE0_CALIB_ENABLE, 0x80);
@@ -451,7 +807,7 @@
write_csi2_dphy_reg(hw, CSI2PHY_LANE1_CALIB_ENABLE, 0x80);
}
- if (dphy->phy_index == DPHY2) {
+ if (dphy->phy_index % 3 == DPHY2) {
write_csi2_dphy_reg(hw, CSI2PHY_CLK1_CALIB_ENABLE, 0x80);
if (sensor->lanes > 0x00)
write_csi2_dphy_reg(hw, CSI2PHY_LANE2_CALIB_ENABLE, 0x80);
@@ -487,16 +843,43 @@
if (sensor->lanes > 0x03)
csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_DATA3);
} else {
- if (dphy->phy_index == DPHY1) {
+ if (dphy->phy_index % 3 == DPHY1) {
csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_CLOCK);
csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_DATA0);
csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_DATA1);
}
- if (dphy->phy_index == DPHY2) {
+ if (dphy->phy_index % 3 == DPHY2) {
csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_CLOCK1);
csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_DATA2);
csi_mipidphy_wr_ths_settle(hw, hsfreq, CSI2_DPHY_LANE_DATA3);
+ }
+ }
+
+ if (hw->drv_data->chip_id == CHIP_ID_RV1106) {
+ if (dphy->phy_index % 3 == DPHY0 ||
+ dphy->phy_index % 3 == DPHY1) {
+ if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
+ write_csi2_dphy_reg(hw, CSI2PHY_PATH0_MODEL, 0x2);
+ } else {
+ write_csi2_dphy_reg(hw, CSI2PHY_PATH0_MODEL, 0x4);
+ lvds_width = get_lvds_data_width(sensor->format.code);
+ write_csi2_dphy_reg(hw, CSI2PHY_PATH0_LVDS_MODEL, (lvds_width << 4) | 0X0f);
+ }
+ } else {
+ if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
+ write_csi2_dphy_reg(hw, CSI2PHY_PATH1_MODEL, 0x2);
+ } else {
+ write_csi2_dphy_reg(hw, CSI2PHY_PATH1_MODEL, 0x4);
+ lvds_width = get_lvds_data_width(sensor->format.code);
+ write_csi2_dphy_reg(hw, CSI2PHY_PATH1_LVDS_MODEL, (lvds_width << 4) | 0X0f);
+ }
+ }
+ if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
+ if (hw->lane_mode == LANE_MODE_FULL)
+ write_csi2_dphy_reg(hw, CSI2PHY_CLK_INV, 0x04);
+ else
+ write_csi2_dphy_reg(hw, CSI2PHY_CLK_INV, 0x14);
}
}
@@ -518,11 +901,112 @@
mutex_lock(&hw->mutex);
write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, 0x01);
- usleep_range(500, 1000);
+ csi2_dphy_hw_do_reset(hw);
mutex_unlock(&hw->mutex);
return 0;
+}
+
+static int csi2_dphy_hw_quick_stream_on(struct csi2_dphy *dphy,
+ struct v4l2_subdev *sd)
+{
+ struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
+ struct csi2_sensor *sensor;
+ struct csi2_dphy_hw *hw = dphy->dphy_hw;
+ u32 val = 0, pre_val = 0;
+
+ if (!sensor_sd)
+ return -ENODEV;
+ sensor = sd_to_sensor(dphy, sensor_sd);
+ if (!sensor)
+ return -ENODEV;
+
+ read_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, &pre_val);
+ if (hw->lane_mode == LANE_MODE_FULL) {
+ val |= (GENMASK(sensor->lanes - 1, 0) <<
+ CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT) |
+ (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
+ } else {
+ if (!(pre_val & (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT)))
+ val |= (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
+
+ if (dphy->phy_index % 3 == DPHY1)
+ val |= (GENMASK(sensor->lanes - 1, 0) <<
+ CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT);
+
+ if (dphy->phy_index % 3 == DPHY2) {
+ val |= (GENMASK(sensor->lanes - 1, 0) <<
+ CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT);
+ if (hw->drv_data->chip_id >= CHIP_ID_RK3588)
+ write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(6));
+ }
+ }
+ pre_val |= val;
+ write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, pre_val);
+ return 0;
+}
+
+static int csi2_dphy_hw_quick_stream_off(struct csi2_dphy *dphy,
+ struct v4l2_subdev *sd)
+{
+ struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
+ struct csi2_sensor *sensor;
+ struct csi2_dphy_hw *hw = dphy->dphy_hw;
+ u32 val = 0, pre_val = 0;
+
+ if (!sensor_sd)
+ return -ENODEV;
+ sensor = sd_to_sensor(dphy, sensor_sd);
+ if (!sensor)
+ return -ENODEV;
+
+ read_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, &pre_val);
+ if (hw->lane_mode == LANE_MODE_FULL) {
+ val |= (GENMASK(sensor->lanes - 1, 0) <<
+ CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT) |
+ (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
+ } else {
+ if (!(pre_val & (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT)))
+ val |= (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT);
+
+ if (dphy->phy_index % 3 == DPHY1)
+ val |= (GENMASK(sensor->lanes - 1, 0) <<
+ CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT);
+
+ if (dphy->phy_index % 3 == DPHY2) {
+ val |= (GENMASK(sensor->lanes - 1, 0) <<
+ CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT);
+ if (hw->drv_data->chip_id >= CHIP_ID_RK3588)
+ write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(6));
+ }
+ }
+ pre_val &= ~val;
+ write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, pre_val);
+ return 0;
+}
+
+static int csi2_dphy_hw_ttl_mode_enable(struct csi2_dphy_hw *hw)
+{
+ int ret = 0;
+
+ ret = clk_bulk_prepare_enable(hw->num_clks, hw->clks_bulk);
+ if (ret) {
+ dev_err(hw->dev, "failed to enable clks\n");
+ return ret;
+ }
+
+ write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, 0x7d);
+ write_csi2_dphy_reg(hw, CSI2PHY_DUAL_CLK_EN, 0x5f);
+ write_csi2_dphy_reg(hw, CSI2PHY_PATH0_MODEL, 0x1);
+ write_csi2_dphy_reg(hw, CSI2PHY_PATH1_MODEL, 0x1);
+ return ret;
+}
+
+static void csi2_dphy_hw_ttl_mode_disable(struct csi2_dphy_hw *hw)
+{
+ write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, 0x01);
+ clk_bulk_disable_unprepare(hw->num_clks, hw->clks_bulk);
}
static void rk3568_csi2_dphy_hw_individual_init(struct csi2_dphy_hw *hw)
@@ -530,21 +1014,89 @@
hw->grf_regs = rk3568_grf_dphy_regs;
}
+static void rk3588_csi2_dphy_hw_individual_init(struct csi2_dphy_hw *hw)
+{
+ hw->grf_regs = rk3588_grf_dphy_regs;
+}
+
+static void rv1106_csi2_dphy_hw_individual_init(struct csi2_dphy_hw *hw)
+{
+ hw->grf_regs = rv1106_grf_dphy_regs;
+}
+
+static void rk3562_csi2_dphy_hw_individual_init(struct csi2_dphy_hw *hw)
+{
+ hw->grf_regs = rk3562_grf_dphy_regs;
+}
+
static const struct dphy_hw_drv_data rk3568_csi2_dphy_hw_drv_data = {
- .clks = rk3568_csi2_dphy_hw_clks,
- .num_clks = ARRAY_SIZE(rk3568_csi2_dphy_hw_clks),
.hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges,
.num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges),
.csi2dphy_regs = rk3568_csi2dphy_regs,
+ .num_csi2dphy_regs = ARRAY_SIZE(rk3568_csi2dphy_regs),
.grf_regs = rk3568_grf_dphy_regs,
+ .num_grf_regs = ARRAY_SIZE(rk3568_grf_dphy_regs),
.individual_init = rk3568_csi2_dphy_hw_individual_init,
.chip_id = CHIP_ID_RK3568,
+ .stream_on = csi2_dphy_hw_stream_on,
+ .stream_off = csi2_dphy_hw_stream_off,
+};
+
+static const struct dphy_hw_drv_data rk3588_csi2_dphy_hw_drv_data = {
+ .hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges,
+ .num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges),
+ .csi2dphy_regs = rk3588_csi2dphy_regs,
+ .num_csi2dphy_regs = ARRAY_SIZE(rk3588_csi2dphy_regs),
+ .grf_regs = rk3588_grf_dphy_regs,
+ .num_grf_regs = ARRAY_SIZE(rk3588_grf_dphy_regs),
+ .individual_init = rk3588_csi2_dphy_hw_individual_init,
+ .chip_id = CHIP_ID_RK3588,
+ .stream_on = csi2_dphy_hw_stream_on,
+ .stream_off = csi2_dphy_hw_stream_off,
+};
+
+static const struct dphy_hw_drv_data rv1106_csi2_dphy_hw_drv_data = {
+ .hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges,
+ .num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges),
+ .csi2dphy_regs = rv1106_csi2dphy_regs,
+ .num_csi2dphy_regs = ARRAY_SIZE(rv1106_csi2dphy_regs),
+ .grf_regs = rv1106_grf_dphy_regs,
+ .num_grf_regs = ARRAY_SIZE(rv1106_grf_dphy_regs),
+ .individual_init = rv1106_csi2_dphy_hw_individual_init,
+ .chip_id = CHIP_ID_RV1106,
+ .stream_on = csi2_dphy_hw_stream_on,
+ .stream_off = csi2_dphy_hw_stream_off,
+};
+
+static const struct dphy_hw_drv_data rk3562_csi2_dphy_hw_drv_data = {
+ .hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges,
+ .num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges),
+ .csi2dphy_regs = rk3562_csi2dphy_regs,
+ .num_csi2dphy_regs = ARRAY_SIZE(rk3562_csi2dphy_regs),
+ .grf_regs = rk3562_grf_dphy_regs,
+ .num_grf_regs = ARRAY_SIZE(rk3562_grf_dphy_regs),
+ .individual_init = rk3562_csi2_dphy_hw_individual_init,
+ .chip_id = CHIP_ID_RK3562,
+ .stream_on = csi2_dphy_hw_stream_on,
+ .stream_off = csi2_dphy_hw_stream_off,
};
static const struct of_device_id rockchip_csi2_dphy_hw_match_id[] = {
{
.compatible = "rockchip,rk3568-csi2-dphy-hw",
.data = &rk3568_csi2_dphy_hw_drv_data,
+ },
+ {
+ .compatible = "rockchip,rk3588-csi2-dphy-hw",
+ .data = &rk3588_csi2_dphy_hw_drv_data,
+ },
+ {
+ .compatible = "rockchip,rv1106-csi2-dphy-hw",
+ .data = &rv1106_csi2_dphy_hw_drv_data,
+ },
+ {
+ .compatible = "rockchip,rk3562-csi2-dphy-hw",
+ .data = &rk3562_csi2_dphy_hw_drv_data,
},
{}
};
@@ -558,7 +1110,6 @@
struct resource *res;
const struct of_device_id *of_id;
const struct dphy_hw_drv_data *drv_data;
- int ret;
dphy_hw = devm_kzalloc(dev, sizeof(*dphy_hw), GFP_KERNEL);
if (!dphy_hw)
@@ -569,39 +1120,38 @@
if (!of_id)
return -EINVAL;
- grf = syscon_node_to_regmap(dev->parent->of_node);
+ drv_data = of_id->data;
+
+ grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "rockchip,grf");
if (IS_ERR(grf)) {
- grf = syscon_regmap_lookup_by_phandle(dev->of_node,
- "rockchip,grf");
- if (IS_ERR(grf)) {
- dev_err(dev, "Can't find GRF syscon\n");
- return -ENODEV;
- }
+ dev_err(dev, "Can't find GRF syscon\n");
+ return -ENODEV;
}
dphy_hw->regmap_grf = grf;
- drv_data = of_id->data;
- dphy_hw->num_clks = drv_data->num_clks;
- dphy_hw->clks = devm_kmemdup(dev, drv_data->clks,
- drv_data->num_clks * sizeof(struct clk_bulk_data),
- GFP_KERNEL);
- if (!dphy_hw->clks) {
- dev_err(dev, "failed to acquire csi2 dphy clks mem\n");
- return -ENOMEM;
+ if (drv_data->chip_id == CHIP_ID_RK3588) {
+ grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "rockchip,sys_grf");
+ if (IS_ERR(grf)) {
+ dev_err(dev, "Can't find SYS GRF syscon\n");
+ return -ENODEV;
+ }
+ dphy_hw->regmap_sys_grf = grf;
}
- ret = devm_clk_bulk_get(dev, dphy_hw->num_clks, dphy_hw->clks);
- if (ret == -EPROBE_DEFER) {
- dev_err(dev, "get csi2 dphy clks failed\n");
- return -EPROBE_DEFER;
- }
- if (ret)
- dphy_hw->num_clks = 0;
+
+ dphy_hw->num_clks = devm_clk_bulk_get_all(dev, &dphy_hw->clks_bulk);
+ if (dphy_hw->num_clks < 0)
+ dev_err(dev, "failed to get csi2 clks\n");
+
+ dphy_hw->rsts_bulk = devm_reset_control_array_get_optional_exclusive(dev);
+ if (IS_ERR(dphy_hw->rsts_bulk))
+ dev_err_probe(dev, PTR_ERR(dphy_hw->rsts_bulk), "failed to get dphy reset\n");
dphy_hw->dphy_dev_num = 0;
dphy_hw->drv_data = drv_data;
dphy_hw->lane_mode = LANE_MODE_UNDEF;
dphy_hw->grf_regs = drv_data->grf_regs;
- dphy_hw->txrx_regs = drv_data->txrx_regs;
dphy_hw->csi2dphy_regs = drv_data->csi2dphy_regs;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -616,8 +1166,18 @@
return -ENODEV;
}
}
- dphy_hw->stream_on = csi2_dphy_hw_stream_on;
- dphy_hw->stream_off = csi2_dphy_hw_stream_off;
+ dphy_hw->stream_on = drv_data->stream_on;
+ dphy_hw->stream_off = drv_data->stream_off;
+ dphy_hw->quick_stream_on = csi2_dphy_hw_quick_stream_on;
+ dphy_hw->quick_stream_off = csi2_dphy_hw_quick_stream_off;
+
+ if (drv_data->chip_id == CHIP_ID_RV1106) {
+ dphy_hw->ttl_mode_enable = csi2_dphy_hw_ttl_mode_enable;
+ dphy_hw->ttl_mode_disable = csi2_dphy_hw_ttl_mode_disable;
+ } else {
+ dphy_hw->ttl_mode_enable = NULL;
+ dphy_hw->ttl_mode_disable = NULL;
+ }
atomic_set(&dphy_hw->stream_cnt, 0);
@@ -626,8 +1186,6 @@
platform_set_drvdata(pdev, dphy_hw);
pm_runtime_enable(&pdev->dev);
-
- platform_driver_register(&rockchip_csi2_dphy_driver);
dev_info(dev, "csi2 dphy hw probe successfully!\n");
@@ -652,7 +1210,19 @@
.of_match_table = rockchip_csi2_dphy_hw_match_id,
},
};
+
+int rockchip_csi2_dphy_hw_init(void)
+{
+ return platform_driver_register(&rockchip_csi2_dphy_hw_driver);
+}
+
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
+subsys_initcall(rockchip_csi2_dphy_hw_init);
+#else
+#if !defined(CONFIG_VIDEO_REVERSE_IMAGE)
module_platform_driver(rockchip_csi2_dphy_hw_driver);
+#endif
+#endif
MODULE_AUTHOR("Rockchip Camera/ISP team");
MODULE_DESCRIPTION("Rockchip MIPI CSI2 DPHY HW driver");
--
Gitblit v1.6.2