mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
phy: rockchip: csi2-dphy: support rk3588 dphy driver
Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com> Change-Id: I2d512525ed95ab7f8bf0f9f614e0f817f2fa841f
This commit is contained in:
@@ -90,6 +90,7 @@ struct dphy_hw_drv_data {
|
||||
struct csi2_dphy_hw {
|
||||
struct device *dev;
|
||||
struct regmap *regmap_grf;
|
||||
struct regmap *regmap_sys_grf;
|
||||
const struct grf_reg *grf_regs;
|
||||
const struct txrx_reg *txrx_regs;
|
||||
const struct csi2dphy_reg *csi2dphy_regs;
|
||||
@@ -110,6 +111,4 @@ struct csi2_dphy_hw {
|
||||
int (*stream_off)(struct csi2_dphy *dphy, struct v4l2_subdev *sd);
|
||||
};
|
||||
|
||||
extern struct platform_driver rockchip_csi2_dphy_driver;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,11 +28,16 @@
|
||||
#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)
|
||||
|
||||
/*GRF REG BIT DEFINE */
|
||||
#define GRF_CSI2PHY_LANE_SEL_SPLIT (0x1)
|
||||
#define GRF_CSI2PHY_SEL_SPLIT_0_1 (0x0)
|
||||
#define GRF_CSI2PHY_SEL_SPLIT_2_3 BIT(0)
|
||||
|
||||
/*RK3588 DCPHY GRF REG OFFSET */
|
||||
#define GRF_DCPHY_CON0 (0x0)
|
||||
|
||||
/* PHY REG OFFSET */
|
||||
@@ -40,6 +45,7 @@
|
||||
#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_WR_THS_SETTLE (0x160)
|
||||
#define CSI2_DPHY_CLK_CALIB_EN (0x168)
|
||||
@@ -54,7 +60,7 @@
|
||||
#define CSI2_DPHY_CLK1_WR_THS_SETTLE (0x3e0)
|
||||
#define CSI2_DPHY_CLK1_CALIB_EN (0x3e8)
|
||||
|
||||
#define CSI2_DCPHY_CLK_WR_THS_SETTLE (0xB20)
|
||||
#define CSI2_DCPHY_CLK_WR_THS_SETTLE (0xB30)
|
||||
#define CSI2_DCPHY_LANE0_WR_THS_SETTLE (0xC30)
|
||||
#define CSI2_DCPHY_LANE0_WR_ERR_SOT_SYNC (0xC34)
|
||||
#define CSI2_DCPHY_LANE1_WR_THS_SETTLE (0xD30)
|
||||
@@ -146,9 +152,14 @@ enum grf_reg_id {
|
||||
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,
|
||||
};
|
||||
|
||||
enum csi2dphy_reg_id {
|
||||
@@ -174,6 +185,7 @@ enum csi2dphy_reg_id {
|
||||
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,
|
||||
@@ -198,13 +210,23 @@ struct hsfreq_range {
|
||||
u16 cfg_bit;
|
||||
};
|
||||
|
||||
static inline void write_sys_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);
|
||||
|
||||
if (reg->shift)
|
||||
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);
|
||||
|
||||
if (reg->offset)
|
||||
if (reg->shift)
|
||||
regmap_write(hw->regmap_grf, reg->offset, val);
|
||||
}
|
||||
|
||||
@@ -213,7 +235,7 @@ static inline u32 read_grf_reg(struct csi2_dphy_hw *hw, int index)
|
||||
const struct grf_reg *reg = &hw->grf_regs[index];
|
||||
unsigned int val = 0;
|
||||
|
||||
if (reg->offset) {
|
||||
if (reg->shift) {
|
||||
regmap_read(hw->regmap_grf, reg->offset, &val);
|
||||
val = (val >> reg->shift) & reg->mask;
|
||||
}
|
||||
@@ -321,6 +343,41 @@ static const struct csi2dphy_reg rk3568_csi2dphy_regs[] = {
|
||||
[CSI2PHY_CLK1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CALIB_EN),
|
||||
};
|
||||
|
||||
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),
|
||||
};
|
||||
|
||||
static const struct grf_reg rk3588_grf_dcphy_regs[] = {
|
||||
[GRF_CPHY_MODE] = GRF_REG(GRF_DCPHY_CON0, 9, 0),
|
||||
};
|
||||
@@ -410,6 +467,17 @@ static struct csi2_sensor *sd_to_sensor(struct csi2_dphy *dphy,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -427,37 +495,78 @@ static void csi2_dphy_config_dual_mode(struct csi2_dphy *dphy,
|
||||
|
||||
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);
|
||||
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 {
|
||||
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_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 {
|
||||
write_sys_grf_reg(hw, GRF_DPHY_CSIHOST2_SEL, 0x0);
|
||||
write_sys_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 {
|
||||
write_sys_grf_reg(hw, GRF_DPHY_CSIHOST3_SEL, 0x1);
|
||||
write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
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);
|
||||
break;
|
||||
case 5:
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,13 +599,15 @@ static int csi2_dphy_hw_stream_on(struct csi2_dphy *dphy,
|
||||
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 (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);
|
||||
write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(6));
|
||||
}
|
||||
}
|
||||
val |= pre_val;
|
||||
write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, val);
|
||||
@@ -532,7 +643,7 @@ static int csi2_dphy_hw_stream_on(struct csi2_dphy *dphy,
|
||||
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);
|
||||
@@ -540,7 +651,7 @@ static int csi2_dphy_hw_stream_on(struct csi2_dphy *dphy,
|
||||
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);
|
||||
@@ -576,13 +687,13 @@ static int csi2_dphy_hw_stream_on(struct csi2_dphy *dphy,
|
||||
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);
|
||||
@@ -607,6 +718,7 @@ static int csi2_dphy_hw_stream_off(struct csi2_dphy *dphy,
|
||||
mutex_lock(&hw->mutex);
|
||||
|
||||
write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, 0x01);
|
||||
csi2_dphy_hw_do_reset(hw);
|
||||
usleep_range(500, 1000);
|
||||
|
||||
mutex_unlock(&hw->mutex);
|
||||
@@ -774,6 +886,11 @@ static void rk3568_csi2_dphy_hw_individual_init(struct csi2_dphy_hw *hw)
|
||||
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 rk3588_csi2_dcphy_hw_individual_init(struct csi2_dphy_hw *hw)
|
||||
{
|
||||
hw->grf_regs = rk3588_grf_dcphy_regs;
|
||||
@@ -790,6 +907,17 @@ static const struct dphy_hw_drv_data rk3568_csi2_dphy_hw_drv_data = {
|
||||
.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,
|
||||
.grf_regs = 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 rk3588_csi2_dcphy_hw_drv_data = {
|
||||
.hsfreq_ranges = rk3588_csi2_dcphy_d_hw_hsfreq_ranges,
|
||||
.num_hsfreq_ranges = ARRAY_SIZE(rk3588_csi2_dcphy_d_hw_hsfreq_ranges),
|
||||
@@ -808,6 +936,10 @@ 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,rk3588-csi2-dcphy-hw",
|
||||
.data = &rk3588_csi2_dcphy_hw_drv_data,
|
||||
@@ -836,17 +968,24 @@ static int rockchip_csi2_dphy_hw_probe(struct platform_device *pdev)
|
||||
|
||||
drv_data = of_id->data;
|
||||
|
||||
grf = syscon_node_to_regmap(dev->parent->of_node);
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
@@ -470,7 +470,7 @@ static int rockchip_csi2_dphy_attach_hw(struct csi2_dphy *dphy)
|
||||
enum csi2_dphy_lane_mode target_mode;
|
||||
int i;
|
||||
|
||||
if (dphy->phy_index == 0)
|
||||
if (dphy->phy_index % 3 == 0)
|
||||
target_mode = LANE_MODE_FULL;
|
||||
else
|
||||
target_mode = LANE_MODE_SPLIT;
|
||||
|
||||
Reference in New Issue
Block a user