mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
phy: rockchip: csi2-dphy: support rk3562
Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com> Change-Id: I938047b37e2feba021a19f953f859679468fee1a
This commit is contained in:
@@ -19,6 +19,7 @@ enum csi2_dphy_chip_id {
|
||||
CHIP_ID_RK3588 = 0x1,
|
||||
CHIP_ID_RK3588_DCPHY = 0x2,
|
||||
CHIP_ID_RV1106 = 0x3,
|
||||
CHIP_ID_RK3562 = 0x4,
|
||||
};
|
||||
|
||||
enum csi2_dphy_rx_pads {
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
#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)
|
||||
@@ -156,6 +160,15 @@ enum grf_reg_id {
|
||||
/* 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 {
|
||||
@@ -422,6 +435,45 @@ static const struct csi2dphy_reg rv1106_csi2dphy_regs[] = {
|
||||
[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. */
|
||||
static const struct hsfreq_range rk3568_csi2_dphy_hw_hsfreq_ranges[] = {
|
||||
{ 109, 0x02}, { 149, 0x03}, { 199, 0x06}, { 249, 0x06},
|
||||
@@ -525,15 +577,21 @@ static void csi2_dphy_config_dual_mode(struct csi2_dphy *dphy,
|
||||
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)
|
||||
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)
|
||||
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);
|
||||
@@ -562,6 +620,8 @@ static void csi2_dphy_config_dual_mode(struct csi2_dphy *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:
|
||||
@@ -579,21 +639,37 @@ static void csi2_dphy_config_dual_mode(struct csi2_dphy *dphy,
|
||||
} 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:
|
||||
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);
|
||||
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:
|
||||
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);
|
||||
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;
|
||||
@@ -822,6 +898,11 @@ 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 = {
|
||||
.hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges,
|
||||
.num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges),
|
||||
@@ -855,6 +936,17 @@ static const struct dphy_hw_drv_data rv1106_csi2_dphy_hw_drv_data = {
|
||||
.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,
|
||||
.grf_regs = 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",
|
||||
@@ -868,6 +960,10 @@ static const struct of_device_id rockchip_csi2_dphy_hw_match_id[] = {
|
||||
.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,
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rockchip_csi2_dphy_hw_match_id);
|
||||
|
||||
@@ -697,6 +697,11 @@ static struct dphy_drv_data rv1106_dphy_drv_data = {
|
||||
.vendor = PHY_VENDOR_INNO,
|
||||
};
|
||||
|
||||
static struct dphy_drv_data rk3562_dphy_drv_data = {
|
||||
.dev_name = "csi2dphy",
|
||||
.vendor = PHY_VENDOR_INNO,
|
||||
};
|
||||
|
||||
static const struct of_device_id rockchip_csi2_dphy_match_id[] = {
|
||||
{
|
||||
.compatible = "rockchip,rk3568-csi2-dphy",
|
||||
@@ -710,6 +715,10 @@ static const struct of_device_id rockchip_csi2_dphy_match_id[] = {
|
||||
.compatible = "rockchip,rv1106-csi2-dphy",
|
||||
.data = &rv1106_dphy_drv_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3562-csi2-dphy",
|
||||
.data = &rk3562_dphy_drv_data,
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rockchip_csi2_dphy_match_id);
|
||||
|
||||
Reference in New Issue
Block a user