From 829193343008653286ff210c0ece5872bde3aacf Mon Sep 17 00:00:00 2001 From: Jianwei Fan Date: Sat, 23 Mar 2024 16:00:13 +0800 Subject: [PATCH] video: rockchip: vehicle: add rk3576 support image reverse Signed-off-by: Jianwei Fan Change-Id: I5319bc7df0af265da1617b4df241d888f0bdedb5 --- .../vehicle/vehicle-csi2-dphy-common.h | 4 + drivers/video/rockchip/vehicle/vehicle_cif.c | 482 ++++++++++++++++-- drivers/video/rockchip/vehicle/vehicle_cif.h | 2 + 3 files changed, 439 insertions(+), 49 deletions(-) diff --git a/drivers/video/rockchip/vehicle/vehicle-csi2-dphy-common.h b/drivers/video/rockchip/vehicle/vehicle-csi2-dphy-common.h index 8f7ac2429bef..9a5810ae13b9 100644 --- a/drivers/video/rockchip/vehicle/vehicle-csi2-dphy-common.h +++ b/drivers/video/rockchip/vehicle/vehicle-csi2-dphy-common.h @@ -26,6 +26,9 @@ #define GRF_DPHY_CON0 (0x0) #define GRF_SOC_CON2 (0x0308) +/*RK3576 DPHY GRF REG OFFSET */ +#define GRF_SOC_CON5_RK3576 (0x14) + /*GRF REG BIT DEFINE */ #define GRF_CSI2PHY_LANE_SEL_SPLIT (0x1) #define GRF_CSI2PHY_SEL_SPLIT_0_1 (0x0) @@ -308,6 +311,7 @@ enum csi2_dphy_chip_id { CHIP_ID_RK3588_DCPHY = 0x2, CHIP_ID_RV1106 = 0x3, CHIP_ID_RK3562 = 0x4, + CHIP_ID_RK3576 = 0x5, }; enum csi2_dphy_rx_pads { diff --git a/drivers/video/rockchip/vehicle/vehicle_cif.c b/drivers/video/rockchip/vehicle/vehicle_cif.c index 22defc8e7204..4420c9bd2d3a 100644 --- a/drivers/video/rockchip/vehicle/vehicle_cif.c +++ b/drivers/video/rockchip/vehicle/vehicle_cif.c @@ -104,6 +104,28 @@ static const char * const rk3562_cif_rsts[] = { "rst_cif_i3", }; +static const char * const rk3576_cif_clks[] = { + "aclk_cif", + "hclk_cif", + "dclk_cif", + "i0clk_cif", + "i1clk_cif", + "i2clk_cif", + "i3clk_cif", + "i4clk_cif", +}; + +static const char * const rk3576_cif_rsts[] = { + "rst_cif_a", + "rst_cif_h", + "rst_cif_d", + "rst_cif_iclk0", + "rst_cif_iclk1", + "rst_cif_iclk2", + "rst_cif_iclk3", + "rst_cif_iclk4", +}; + //define dphy and csi clks/rst static struct clk_bulk_data rk3568_csi2_dphy_hw_clks[] = { { .id = "pclk" }, @@ -156,6 +178,27 @@ static const char * const rk3562_csi2_rsts[] = { "srst_csihost_p", }; +static struct clk_bulk_data rk3576_csi2_dphy_hw_clks[] = { + { .id = "pclk" }, +}; + +static const char * const rk3576_csi2_dphy_hw_rsts[] = { + "srst_p_csiphy", +}; + +static struct clk_bulk_data rk3576_csi2_clks[] = { + { .id = "pclk_csi2host" }, +}; + +static struct clk_bulk_data rk3576_csi2_dcphy_clks[] = { + { .id = "pclk_csi2host" }, + { .id = "iclk_csi2host" }, +}; + +static const char * const rk3576_csi2_rsts[] = { + "srst_csihost_p", +}; + //define cif regs static const struct vehicle_cif_reg rk3568_cif_regs[] = { [CIF_REG_DVP_CTRL] = CIF_REG_NAME(CIF_CTRL, "CIF_REG_DVP_CTRL"), @@ -610,6 +653,138 @@ static const struct vehicle_cif_reg rk3562_cif_regs[] = { [CIF_REG_TOISP0_CROP] = CIF_REG_NAME(TOISP0_CROP, "CIF_REG_TOISP0_CROP"), }; +static const struct vehicle_cif_reg rk3576_cif_regs[] = { + [CIF_REG_DVP_CTRL] = CIF_REG_NAME(DVP_CTRL, "CIF_REG_DVP_CTRL"), + [CIF_REG_DVP_INTEN] = CIF_REG_NAME(DVP_INTEN, "CIF_REG_DVP_INTEN"), + [CIF_REG_DVP_INTSTAT] = CIF_REG_NAME(DVP_INTSTAT, "CIF_REG_DVP_INTSTAT"), + [CIF_REG_DVP_FOR] = CIF_REG_NAME(DVP_FOR, "CIF_REG_DVP_FOR"), + [CIF_REG_DVP_SAV_EAV] = CIF_REG_NAME(DVP_SAV_EAV, "CIF_REG_DVP_SAV_EAV"), + [CIF_REG_DVP_FRM0_ADDR_Y] = CIF_REG_NAME(DVP_FRM0_ADDR_Y_ID0, "CIF_REG_DVP_FRM0_ADDR_Y"), + [CIF_REG_DVP_FRM0_ADDR_UV] = CIF_REG_NAME(DVP_FRM0_ADDR_UV_ID0, "CIF_REG_DVP_FRM0_ADDR_UV"), + [CIF_REG_DVP_FRM1_ADDR_Y] = CIF_REG_NAME(DVP_FRM1_ADDR_Y_ID0, "CIF_REG_DVP_FRM1_ADDR_Y"), + [CIF_REG_DVP_FRM1_ADDR_UV] = CIF_REG_NAME(DVP_FRM1_ADDR_UV_ID0, "CIF_REG_DVP_FRM1_ADDR_UV"), + [CIF_REG_DVP_VIR_LINE_WIDTH] = CIF_REG_NAME(DVP_VIR_LINE_WIDTH, + "CIF_REG_DVP_VIR_LINE_WIDTH"), + [CIF_REG_DVP_SET_SIZE] = CIF_REG_NAME(DVP_CROP_SIZE, "CIF_REG_DVP_SET_SIZE"), + [CIF_REG_DVP_CROP] = CIF_REG_NAME(DVP_CROP, "CIF_REG_DVP_CROP"), + [CIF_REG_DVP_LINE_INT_NUM] = CIF_REG_NAME(DVP_LINE_INT_NUM_01, "CIF_REG_DVP_LINE_INT_NUM"), + [CIF_REG_DVP_LINE_CNT] = CIF_REG_NAME(DVP_LINE_CNT_01, "CIF_REG_DVP_LINE_CNT"), + [CIF_REG_MIPI_LVDS_ID0_CTRL0] = CIF_REG_NAME(CSI_MIPI0_ID0_CTRL0, + "CIF_REG_MIPI_LVDS_ID0_CTRL0"), + [CIF_REG_MIPI_LVDS_ID0_CTRL1] = CIF_REG_NAME(CSI_MIPI0_ID0_CTRL1, + "CIF_REG_MIPI_LVDS_ID0_CTRL1"), + [CIF_REG_MIPI_LVDS_ID1_CTRL0] = CIF_REG_NAME(CSI_MIPI0_ID1_CTRL0, + "CIF_REG_MIPI_LVDS_ID1_CTRL0"), + [CIF_REG_MIPI_LVDS_ID1_CTRL1] = CIF_REG_NAME(CSI_MIPI0_ID1_CTRL1, + "CIF_REG_MIPI_LVDS_ID1_CTRL1"), + [CIF_REG_MIPI_LVDS_ID2_CTRL0] = CIF_REG_NAME(CSI_MIPI0_ID2_CTRL0, + "CIF_REG_MIPI_LVDS_ID2_CTRL0"), + [CIF_REG_MIPI_LVDS_ID2_CTRL1] = CIF_REG_NAME(CSI_MIPI0_ID2_CTRL1, + "CIF_REG_MIPI_LVDS_ID2_CTRL1"), + [CIF_REG_MIPI_LVDS_ID3_CTRL0] = CIF_REG_NAME(CSI_MIPI0_ID3_CTRL0, + "CIF_REG_MIPI_LVDS_ID3_CTRL0"), + [CIF_REG_MIPI_LVDS_ID3_CTRL1] = CIF_REG_NAME(CSI_MIPI0_ID3_CTRL1, + "CIF_REG_MIPI_LVDS_ID3_CTRL1"), + [CIF_REG_MIPI_LVDS_CTRL] = CIF_REG_NAME(CSI_MIPI0_CTRL, "CIF_REG_MIPI_LVDS_CTRL"), + [CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID0] = CIF_REG_NAME(CSI_MIPI0_FRM0_ADDR_Y_ID0, + "CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID0"), + [CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID0] = CIF_REG_NAME(CSI_MIPI0_FRM1_ADDR_Y_ID0, + "CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID0"), + [CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID0] = CIF_REG_NAME(CSI_MIPI0_FRM0_ADDR_UV_ID0, + "CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID0"), + [CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID0] = CIF_REG_NAME(CSI_MIPI0_FRM1_ADDR_UV_ID0, + "CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID0"), + [CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID0] = CIF_REG_NAME(CSI_MIPI0_VLW_ID0, + "CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID0"), + [CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID1] = CIF_REG_NAME(CSI_MIPI0_FRM0_ADDR_Y_ID1, + "CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID1"), + [CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID1] = CIF_REG_NAME(CSI_MIPI0_FRM1_ADDR_Y_ID1, + "CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID1"), + [CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID1] = CIF_REG_NAME(CSI_MIPI0_FRM0_ADDR_UV_ID1, + "CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID1"), + [CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID1] = CIF_REG_NAME(CSI_MIPI0_FRM1_ADDR_UV_ID1, + "CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID1"), + [CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID1] = CIF_REG_NAME(CSI_MIPI0_VLW_ID1, + "CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID1"), + [CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID2] = CIF_REG_NAME(CSI_MIPI0_FRM0_ADDR_Y_ID2, + "CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID2"), + [CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID2] = CIF_REG_NAME(CSI_MIPI0_FRM1_ADDR_Y_ID2, + "CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID2"), + [CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID2] = CIF_REG_NAME(CSI_MIPI0_FRM0_ADDR_UV_ID2, + "CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID2"), + [CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID2] = CIF_REG_NAME(CSI_MIPI0_FRM1_ADDR_UV_ID2, + "CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID2"), + [CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID2] = CIF_REG_NAME(CSI_MIPI0_VLW_ID2, + "CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID2"), + [CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID3] = CIF_REG_NAME(CSI_MIPI0_FRM0_ADDR_Y_ID3, + "CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID3"), + [CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID3] = CIF_REG_NAME(CSI_MIPI0_FRM1_ADDR_Y_ID3, + "CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID3"), + [CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID3] = CIF_REG_NAME(CSI_MIPI0_FRM0_ADDR_UV_ID3, + "CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID3"), + [CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID3] = CIF_REG_NAME(CSI_MIPI0_FRM1_ADDR_UV_ID3, + "CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID3"), + [CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID3] = CIF_REG_NAME(CSI_MIPI0_VLW_ID3, + "CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID3"), + [CIF_REG_MIPI_LVDS_INTEN] = CIF_REG_NAME(CSI_MIPI0_INTEN, "CIF_REG_MIPI_LVDS_INTEN"), + [CIF_REG_MIPI_LVDS_INTSTAT] = CIF_REG_NAME(CSI_MIPI0_INTSTAT, "CIF_REG_MIPI_LVDS_INTSTAT"), + [CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID0_1] = CIF_REG_NAME(CSI_MIPI0_LINE_INT_NUM_ID0_1_RK3576, + "CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID0_1"), + [CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID2_3] = CIF_REG_NAME(CSI_MIPI0_LINE_INT_NUM_ID2_3_RK3576, + "CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID2_3"), + [CIF_REG_MIPI_LVDS_LINE_LINE_CNT_ID0_1] = CIF_REG_NAME(CSI_MIPI0_LINE_CNT_ID0_1_RK3576, + "CIF_REG_MIPI_LVDS_LINE_LINE_CNT_ID0_1"), + [CIF_REG_MIPI_LVDS_LINE_LINE_CNT_ID2_3] = CIF_REG_NAME(CSI_MIPI0_LINE_CNT_ID2_3_RK3576, + "CIF_REG_MIPI_LVDS_LINE_LINE_CNT_ID2_3"), + [CIF_REG_MIPI_LVDS_ID0_CROP_START] = CIF_REG_NAME(CSI_MIPI0_ID0_CROP_START_RK3576, + "CIF_REG_MIPI_LVDS_ID0_CROP_START"), + [CIF_REG_MIPI_LVDS_ID1_CROP_START] = CIF_REG_NAME(CSI_MIPI0_ID1_CROP_START_RK3576, + "CIF_REG_MIPI_LVDS_ID1_CROP_START"), + [CIF_REG_MIPI_LVDS_ID2_CROP_START] = CIF_REG_NAME(CSI_MIPI0_ID2_CROP_START_RK3576, + "CIF_REG_MIPI_LVDS_ID2_CROP_START"), + [CIF_REG_MIPI_LVDS_ID3_CROP_START] = CIF_REG_NAME(CSI_MIPI0_ID3_CROP_START_RK3576, + "CIF_REG_MIPI_LVDS_ID3_CROP_START"), + [CIF_REG_MIPI_FRAME_NUM_VC0] = CIF_REG_NAME(CSI_MIPI0_FRAME_NUM_VC0_RK3576, + "CIF_REG_MIPI_FRAME_NUM_VC0"), + [CIF_REG_MIPI_FRAME_NUM_VC1] = CIF_REG_NAME(CSI_MIPI0_FRAME_NUM_VC1_RK3576, + "CIF_REG_MIPI_FRAME_NUM_VC1"), + [CIF_REG_MIPI_FRAME_NUM_VC2] = CIF_REG_NAME(CSI_MIPI0_FRAME_NUM_VC2_RK3576, + "CIF_REG_MIPI_FRAME_NUM_VC2"), + [CIF_REG_MIPI_FRAME_NUM_VC3] = CIF_REG_NAME(CSI_MIPI0_FRAME_NUM_VC3_RK3576, + "CIF_REG_MIPI_FRAME_NUM_VC3"), + [CIF_REG_MIPI_EFFECT_CODE_ID0] = CIF_REG_NAME(CSI_MIPI0_EFFECT_CODE_ID0_RK3576, + "CIF_REG_MIPI_EFFECT_CODE_ID0"), + [CIF_REG_MIPI_EFFECT_CODE_ID1] = CIF_REG_NAME(CSI_MIPI0_EFFECT_CODE_ID1_RK3576, + "CIF_REG_MIPI_EFFECT_CODE_ID1"), + [CIF_REG_MIPI_EFFECT_CODE_ID2] = CIF_REG_NAME(CSI_MIPI0_EFFECT_CODE_ID2_RK3576, + "CIF_REG_MIPI_EFFECT_CODE_ID2"), + [CIF_REG_MIPI_EFFECT_CODE_ID3] = CIF_REG_NAME(CSI_MIPI0_EFFECT_CODE_ID3_RK3576, + "CIF_REG_MIPI_EFFECT_CODE_ID3"), + [CIF_REG_MIPI_ON_PAD] = CIF_REG_NAME(CSI_MIPI0_ON_PAD_RK3576, "CIF_REG_MIPI_ON_PAD"), + [CIF_REG_MIPI_SET_SIZE_ID0] = CIF_REG_NAME(CSI_MIPI0_SET_FRAME_SIZE_ID0_RK3576, + "CIF_REG_MIPI_SET_SIZE_ID0"), + [CIF_REG_MIPI_SET_SIZE_ID1] = CIF_REG_NAME(CSI_MIPI0_SET_FRAME_SIZE_ID1_RK3576, + "CIF_REG_MIPI_SET_SIZE_ID1"), + [CIF_REG_MIPI_SET_SIZE_ID2] = CIF_REG_NAME(CSI_MIPI0_SET_FRAME_SIZE_ID2_RK3576, + "CIF_REG_MIPI_SET_SIZE_ID2"), + [CIF_REG_MIPI_SET_SIZE_ID3] = CIF_REG_NAME(CSI_MIPI0_SET_FRAME_SIZE_ID3_RK3576, + "CIF_REG_MIPI_SET_SIZE_ID3"), + [CIF_REG_GLB_CTRL] = CIF_REG_NAME(GLB_CTRL, "CIF_REG_GLB_CTRL"), + [CIF_REG_GLB_INTEN] = CIF_REG_NAME(GLB_INTEN, "CIF_REG_GLB_INTEN"), + [CIF_REG_GLB_INTST] = CIF_REG_NAME(GLB_INTST, "CIF_REG_GLB_INTST"), + [CIF_REG_SCL_CH_CTRL] = CIF_REG_NAME(SCL_CH_CTRL, "CIF_REG_SCL_CH_CTRL"), + [CIF_REG_SCL_CTRL] = CIF_REG_NAME(SCL_CTRL, "CIF_REG_SCL_CTRL"), + [CIF_REG_SCL_FRM0_ADDR_CH0] = CIF_REG_NAME(SCL_FRM0_ADDR_CH0, "CIF_REG_SCL_FRM0_ADDR_CH0"), + [CIF_REG_SCL_FRM1_ADDR_CH0] = CIF_REG_NAME(SCL_FRM1_ADDR_CH0, "CIF_REG_SCL_FRM1_ADDR_CH0"), + [CIF_REG_SCL_VLW_CH0] = CIF_REG_NAME(SCL_VLW_CH0, "CIF_REG_SCL_VLW_CH0"), + [CIF_REG_SCL_BLC_CH0] = CIF_REG_NAME(SCL_BLC_CH0, "CIF_REG_SCL_BLC_CH0"), + [CIF_REG_TOISP0_CTRL] = CIF_REG_NAME(TOISP0_CH_CTRL, "CIF_REG_TOISP0_CTRL"), + [CIF_REG_TOISP0_SIZE] = CIF_REG_NAME(TOISP0_CROP_SIZE, "CIF_REG_TOISP0_SIZE"), + [CIF_REG_TOISP0_CROP] = CIF_REG_NAME(TOISP0_CROP, "CIF_REG_TOISP0_CROP"), + [CIF_REG_GRF_CIFIO_CON] = CIF_REG_NAME(CIF_GRF_IOC_MISC_CON1_RK3576, + "CIF_REG_GRF_CIFIO_CON"), +}; + //define dphy and csi regs static const struct grf_reg rk3568_grf_dphy_regs[] = { [GRF_DPHY_CSI2PHY_FORCERXMODE] = GRF_REG(GRF_VI_CON0, 4, 0), @@ -779,6 +954,19 @@ static const struct csi2dphy_reg rk3562_csi2dphy_regs[] = { [CSI2PHY_CLK1_LANE_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_LANE_EN), }; +static const struct grf_reg rk3576_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_CON5_RK3576, 1, 1), + [GRF_DPHY_CSI2PHY1_LANE_SEL] = GRF_REG(GRF_SOC_CON5_RK3576, 1, 2), +}; + //define dcphy params static struct rkmodule_csi_dphy_param rk3588_dcphy_param = { .vendor = PHY_VENDOR_SAMSUNG, @@ -886,6 +1074,36 @@ static struct csi2_dphy_hw rk3562_csi2_dphy_hw = { .chip_id = CHIP_ID_RK3562, }; +static struct csi2_dphy_hw rk3576_csi2_dphy_hw = { + .dphy_clks = rk3576_csi2_dphy_hw_clks, + .num_dphy_clks = ARRAY_SIZE(rk3576_csi2_dphy_hw_clks), + .dphy_rsts = rk3576_csi2_dphy_hw_rsts, + .num_dphy_rsts = ARRAY_SIZE(rk3576_csi2_dphy_hw_rsts), + .csi2_clks = rk3576_csi2_clks, + .num_csi2_clks = ARRAY_SIZE(rk3576_csi2_clks), + .csi2_rsts = rk3576_csi2_rsts, + .num_csi2_rsts = ARRAY_SIZE(rk3576_csi2_rsts), + .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 = rk3576_grf_dphy_regs, + .chip_id = CHIP_ID_RK3576, +}; + +static struct csi2_dphy_hw rk3576_csi2_dcphy_hw = { + .dphy_clks = rk3576_csi2_dphy_hw_clks, + .num_dphy_clks = ARRAY_SIZE(rk3576_csi2_dphy_hw_clks), + .csi2_clks = rk3576_csi2_dcphy_clks, + .num_csi2_clks = ARRAY_SIZE(rk3576_csi2_dcphy_clks), + .csi2_rsts = rk3576_csi2_rsts, + .num_csi2_rsts = ARRAY_SIZE(rk3576_csi2_rsts), + .hsfreq_ranges = rk3588_csi2_dcphy_d_hw_hsfreq_ranges, + .num_hsfreq_ranges = ARRAY_SIZE(rk3588_csi2_dcphy_d_hw_hsfreq_ranges), + .csi2dphy_regs = rk3588_csi2dcphy_regs, + .grf_regs = rk3588_grf_dcphy_regs, + .chip_id = CHIP_ID_RK3588_DCPHY, +}; + static const struct cif_input_fmt in_fmts[] = { { .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, @@ -1251,12 +1469,16 @@ static void rkcif_write_reg(struct vehicle_cif *cif, csi_offset = cif->csi_host_idx * 0x200; else csi_offset = 0x500; + } else if (cif->chip_id == CHIP_RK3576_VEHICLE_CIF) { + if (cif->csi_host_idx < 2) + csi_offset = cif->csi_host_idx * 0x200; + else + csi_offset = 0x100 + cif->csi_host_idx * 0x100; } } if (index < CIF_REG_INDEX_MAX) { - if (index == CIF_REG_DVP_CTRL || - ((index != CIF_REG_DVP_CTRL) && (reg->offset != 0x0))) { + if (index == CIF_REG_GLB_CTRL || index == CIF_REG_DVP_CTRL || reg->offset != 0x0) { write_reg(base, reg->offset + csi_offset, val); } else { VEHICLE_INFO("write index(%d) reg[%s]: 0x%x failed, maybe useless!!!\n", @@ -1285,12 +1507,16 @@ static void rkcif_write_reg_or(struct vehicle_cif *cif, csi_offset = cif->csi_host_idx * 0x200; else csi_offset = 0x500; + } else if (cif->chip_id == CHIP_RK3576_VEHICLE_CIF) { + if (cif->csi_host_idx < 2) + csi_offset = cif->csi_host_idx * 0x200; + else + csi_offset = 0x100 + cif->csi_host_idx * 0x100; } } if (index < CIF_REG_INDEX_MAX) { - if (index == CIF_REG_DVP_CTRL || - ((index != CIF_REG_DVP_CTRL) && (reg->offset != 0x0))) { + if (index == CIF_REG_GLB_CTRL || index == CIF_REG_DVP_CTRL || reg->offset != 0x0) { reg_val = read_reg(base, reg->offset + csi_offset); reg_val |= val; write_reg(base, reg->offset + csi_offset, reg_val); @@ -1321,12 +1547,16 @@ static void rkcif_write_reg_and(struct vehicle_cif *cif, csi_offset = cif->csi_host_idx * 0x200; else csi_offset = 0x500; + } else if (cif->chip_id == CHIP_RK3576_VEHICLE_CIF) { + if (cif->csi_host_idx < 2) + csi_offset = cif->csi_host_idx * 0x200; + else + csi_offset = 0x100 + cif->csi_host_idx * 0x100; } } if (index < CIF_REG_INDEX_MAX) { - if (index == CIF_REG_DVP_CTRL || - ((index != CIF_REG_DVP_CTRL) && (reg->offset != 0x0))) { + if (index == CIF_REG_GLB_CTRL || index == CIF_REG_DVP_CTRL || reg->offset != 0x0) { reg_val = read_reg(base, reg->offset + csi_offset); reg_val &= val; write_reg(base, reg->offset + csi_offset, reg_val); @@ -1357,12 +1587,16 @@ static unsigned int rkcif_read_reg(struct vehicle_cif *cif, csi_offset = cif->csi_host_idx * 0x200; else csi_offset = 0x500; + } else if (cif->chip_id == CHIP_RK3576_VEHICLE_CIF) { + if (cif->csi_host_idx < 2) + csi_offset = cif->csi_host_idx * 0x200; + else + csi_offset = 0x100 + cif->csi_host_idx * 0x100; } } if (index < CIF_REG_INDEX_MAX) { - if (index == CIF_REG_DVP_CTRL || - ((index != CIF_REG_DVP_CTRL) && (reg->offset != 0x0))) + if (index == CIF_REG_GLB_CTRL || index == CIF_REG_DVP_CTRL || reg->offset != 0x0) val = read_reg(base, reg->offset + csi_offset); else VEHICLE_INFO("read index(%d) reg[%s]: 0x%x failed, maybe useless!!!\n", @@ -1580,6 +1814,9 @@ static int cif_stream_setup(struct vehicle_cif *cif) | sav_detect | multi_id_mode | bt1120_edge_mode; } + if (cif->chip_id >= CHIP_RK3576_VEHICLE_CIF) + val |= DVP_UVDS_EN; + rkcif_write_reg(cif, CIF_REG_DVP_FOR, val); rkcif_write_reg(cif, CIF_REG_DVP_VIR_LINE_WIDTH, cfg->width); @@ -1600,9 +1837,12 @@ static int cif_stream_setup(struct vehicle_cif *cif) /* enable line int for sof */ rkcif_write_reg(cif, CIF_REG_DVP_LINE_INT_NUM, 0x1); rkcif_write_reg(cif, CIF_REG_DVP_INTEN, LINE_INT_EN); - } else { + } else if (cif->chip_id < CHIP_RK3576_VEHICLE_CIF) { rkcif_write_reg(cif, CIF_REG_DVP_INTSTAT, 0x3c3ffff); rkcif_write_reg_or(cif, CIF_REG_DVP_INTEN, 0x033ffff);//0x3c3ffff + } else { + rkcif_write_reg(cif, CIF_REG_DVP_INTSTAT, 0x3c3ffff); + rkcif_write_reg_or(cif, CIF_REG_DVP_INTEN, 0x3c3ff0f); } cif->interlaced_enable = false; @@ -1653,12 +1893,14 @@ static void csi2_dphy_config_dual_mode(struct vehicle_cif *cif) csi2_dphy_write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN, GENMASK(cif->cif_cfg.lanes - 1, 0)); csi2_dphy_write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE_EN, 0x1); - if (cif->chip_id != CHIP_RK3588_VEHICLE_CIF) + if (cif->chip_id != CHIP_RK3588_VEHICLE_CIF && + cif->chip_id != CHIP_RK3576_VEHICLE_CIF) csi2_dphy_write_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val); else csi2_dphy_write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY_LANE_SEL, val); } else { - if (cif->chip_id <= CHIP_ID_RK3588) { + if (cif->chip_id <= CHIP_RK3588_VEHICLE_CIF || + cif->chip_id == CHIP_RK3576_VEHICLE_CIF) { csi2_dphy_write_grf_reg(hw, GRF_DPHY_CSI2PHY_DATALANE_EN, GENMASK(cif->cif_cfg.lanes - 1, 0)); csi2_dphy_write_grf_reg(hw, GRF_DPHY_CSI2PHY_CLKLANE_EN, 0x1); @@ -1667,7 +1909,8 @@ static void csi2_dphy_config_dual_mode(struct vehicle_cif *cif) GENMASK(cif->cif_cfg.lanes - 1, 0)); csi2_dphy_write_grf_reg(hw, GRF_DPHY1_CSI2PHY_CLKLANE_EN, 0x1); } - if (cif->chip_id != CHIP_RK3588_VEHICLE_CIF) + if (cif->chip_id != CHIP_RK3588_VEHICLE_CIF && + cif->chip_id != CHIP_RK3576_VEHICLE_CIF) csi2_dphy_write_grf_reg(hw, GRF_DPHY_CSI2PHY1_LANE_SEL, val); else csi2_dphy_write_sys_grf_reg(hw, GRF_DPHY_CSI2PHY1_LANE_SEL, val); @@ -1865,6 +2108,11 @@ static int vehicle_samsung_dcphy_rx_config_common(struct vehicle_cif *cif) regmap_write(samsung->regmap, RX_COMBO_S0D0_ANA_CON7, 0x40); regmap_write(samsung->regmap, RX_COMBO_S0D0_DESKEW_CON2, hw->dphy_param->skew_data_cal_clk[0]); + if (hw->data_rate_mbps >= 1500 && + cif->chip_id >= CHIP_RK3576_VEHICLE_CIF) { + regmap_write(samsung->regmap, RX_COMBO_S0D0_DESKEW_CON0, BIT(0)); + regmap_write(samsung->regmap, RX_COMBO_S0D0_DESKEW_CON4, 0x81A); + } } if (cif->cif_cfg.lanes > 0x01) { regmap_write(samsung->regmap, RX_COMBO_S0D1_GNR_CON1, 0x1450); @@ -1877,6 +2125,11 @@ static int vehicle_samsung_dcphy_rx_config_common(struct vehicle_cif *cif) regmap_write(samsung->regmap, RX_COMBO_S0D1_ANA_CON7, 0x40); regmap_write(samsung->regmap, RX_COMBO_S0D1_DESKEW_CON2, hw->dphy_param->skew_data_cal_clk[1]); + if (hw->data_rate_mbps >= 1500 && + cif->chip_id >= CHIP_RK3576_VEHICLE_CIF) { + regmap_write(samsung->regmap, RX_COMBO_S0D1_DESKEW_CON0, BIT(0)); + regmap_write(samsung->regmap, RX_COMBO_S0D1_DESKEW_CON4, 0x81A); + } } if (cif->cif_cfg.lanes > 0x02) { regmap_write(samsung->regmap, RX_COMBO_S0D2_GNR_CON1, 0x1450); @@ -1889,6 +2142,11 @@ static int vehicle_samsung_dcphy_rx_config_common(struct vehicle_cif *cif) regmap_write(samsung->regmap, RX_COMBO_S0D2_ANA_CON7, 0x40); regmap_write(samsung->regmap, RX_COMBO_S0D2_DESKEW_CON2, hw->dphy_param->skew_data_cal_clk[2]); + if (hw->data_rate_mbps >= 1500 && + cif->chip_id >= CHIP_RK3576_VEHICLE_CIF) { + regmap_write(samsung->regmap, RX_COMBO_S0D2_DESKEW_CON0, BIT(0)); + regmap_write(samsung->regmap, RX_COMBO_S0D2_DESKEW_CON4, 0x81A); + } } if (cif->cif_cfg.lanes > 0x03) { regmap_write(samsung->regmap, RX_S0D3_GNR_CON1, 0x1450); @@ -1900,6 +2158,11 @@ static int vehicle_samsung_dcphy_rx_config_common(struct vehicle_cif *cif) (hw->dphy_param->lp_escclk_pol_sel[3] << 11)); regmap_write(samsung->regmap, RX_S0D3_DESKEW_CON2, hw->dphy_param->skew_data_cal_clk[3]); + if (hw->data_rate_mbps >= 1500 && + cif->chip_id >= CHIP_RK3576_VEHICLE_CIF) { + regmap_write(samsung->regmap, RX_S0D3_DESKEW_CON0, BIT(0)); + regmap_write(samsung->regmap, RX_S0D3_DESKEW_CON4, 0x81A); + } } } @@ -2911,20 +3174,31 @@ static int vehicle_cif_csi_channel_set_v1(struct vehicle_cif *cif, rkcif_write_reg_or(cif, CIF_REG_MIPI_LVDS_INTEN, CSI_DMA_END_INTEN(channel->id)); - val = CIF_MIPI_LVDS_SW_PRESS_VALUE_RK3588(0x3) | - CIF_MIPI_LVDS_SW_PRESS_ENABLE | - CIF_MIPI_LVDS_SW_HURRY_VALUE_RK3588(0x3) | - CIF_MIPI_LVDS_SW_HURRY_ENABLE | - CIF_MIPI_LVDS_SW_WATER_LINE_25 | - CIF_MIPI_LVDS_SW_WATER_LINE_ENABLE; + if (cif->chip_id > CHIP_RK3562_VEHICLE_CIF) { + val = CIF_MIPI_LVDS_SW_WATER_LINE_ENABLE | + (CIF_MIPI_LVDS_SW_WATER_LINE_25 << 19); - rkcif_write_reg(cif, CIF_REG_MIPI_LVDS_CTRL, val); + rkcif_write_reg(cif, CIF_REG_MIPI_LVDS_CTRL, val); + } else { + val = CIF_MIPI_LVDS_SW_PRESS_VALUE_RK3588(0x3) | + CIF_MIPI_LVDS_SW_PRESS_ENABLE | + CIF_MIPI_LVDS_SW_HURRY_VALUE_RK3588(0x3) | + CIF_MIPI_LVDS_SW_HURRY_ENABLE | + CIF_MIPI_LVDS_SW_WATER_LINE_25 | + CIF_MIPI_LVDS_SW_WATER_LINE_ENABLE; + + rkcif_write_reg(cif, CIF_REG_MIPI_LVDS_CTRL, val); + } rkcif_write_reg_or(cif, CIF_REG_MIPI_LVDS_INTEN, CSI_ALL_ERROR_INTEN_V1); - rkcif_write_reg(cif, get_reg_index_of_id_ctrl1(channel->id), - channel->width | (channel->height << 16)); + if (cif->chip_id < CHIP_RK3576_VEHICLE_CIF) + rkcif_write_reg(cif, get_reg_index_of_id_ctrl1(channel->id), + (channel->width) | (channel->height << 16)); + else + rkcif_write_reg(cif, CIF_REG_MIPI_SET_SIZE_ID0 + channel->id, + (channel->width) | (channel->height << 16)); rkcif_write_reg(cif, get_reg_index_of_frm0_y_vlw(channel->id), channel->virtual_width); @@ -3001,7 +3275,7 @@ static int vehicle_csi2_dphy_stream_stop(struct vehicle_cif *cif) mutex_lock(&hw->mutex); write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, 0x01); - if (cif->dphy_hw->chip_id == CHIP_ID_RK3588) + if (cif->dphy_hw->chip_id >= CHIP_ID_RK3588) vehicle_csi2_dphy_hw_do_reset(cif); usleep_range(500, 1000); @@ -3266,34 +3540,70 @@ static int vehicle_cif_csi2_s_stream_v1(struct vehicle_cif *cif, channel = &cif->channels[0]; if (enable) { - val = CSI_ENABLE_CAPTURE | CSI_DMA_ENABLE | - channel->cmd_mode_en << 26 | CSI_ENABLE_CROP_V1 | - channel->id << 8 | channel->data_type << 10; + if (cif->chip_id <= CHIP_RK3562_VEHICLE_CIF) { + val = CSI_ENABLE_CAPTURE | CSI_DMA_ENABLE | + channel->cmd_mode_en << 26 | CSI_ENABLE_CROP_V1 | + channel->id << 8 | channel->data_type << 10; - infmt = find_input_fmt(cif->cif_cfg.mbus_code); - if (!infmt) { - VEHICLE_INFO("Input fmt is invalid, use default!\n"); - val |= CSI_YUV_INPUT_ORDER_UYVY; + infmt = find_input_fmt(cif->cif_cfg.mbus_code); + if (!infmt) { + VEHICLE_INFO("Input fmt is invalid, use default!\n"); + val |= CSI_YUV_INPUT_ORDER_UYVY; + } else { + val |= infmt->csi_yuv_order | infmt->csi_fmt_val; + } + + if (cfg->output_format == CIF_OUTPUT_FORMAT_420) { + if (find_output_fmt(V4L2_PIX_FMT_NV12)) + val |= CSI_WRDDR_TYPE_YUV420SP_RK3588 | + CSI_YUV_OUTPUT_ORDER_UYVY; + } else { + if (find_output_fmt(V4L2_PIX_FMT_NV16)) + val |= CSI_WRDDR_TYPE_YUV422SP_RK3588 | + CSI_YUV_OUTPUT_ORDER_UYVY; + } + + rkcif_write_reg(cif, get_reg_index_of_id_ctrl0(channel->id), val); } else { - val |= infmt->csi_yuv_order | infmt->csi_fmt_val; + val = CSI_ENABLE_CAPTURE | CSI_DMA_ENABLE_RK3576 | + CSI_ENABLE_CROP_RK3576; + + infmt = find_input_fmt(cif->cif_cfg.mbus_code); + if (!infmt) { + VEHICLE_INFO("Input fmt is invalid, use default!\n"); + val |= CSI_YUV_INPUT_ORDER_UYVY; + } else { + val |= (infmt->csi_yuv_order >> 4) | (infmt->csi_fmt_val << 4); + } + if (cfg->output_format == CIF_OUTPUT_FORMAT_420) { + if (find_output_fmt(V4L2_PIX_FMT_NV12)) + val |= CSI_WRDDR_TYPE_YUV420SP_RK3588 << 3 | + CSI_YUV_OUTPUT_ORDER_UYVY >> 4; + } else { + if (find_output_fmt(V4L2_PIX_FMT_NV16)) + val |= CSI_WRDDR_TYPE_YUV422SP_RK3588 << 3 | + CSI_YUV_OUTPUT_ORDER_UYVY >> 4; + } + + if (cfg->output_format == CIF_OUTPUT_FORMAT_420) + val |= CSI_UVDS_EN; + rkcif_write_reg(cif, get_reg_index_of_id_ctrl0(channel->id), val); + + val = channel->data_type << 2; + rkcif_write_reg(cif, get_reg_index_of_id_ctrl1(channel->id), val); + } - if (cfg->output_format == CIF_OUTPUT_FORMAT_420) { - if (find_output_fmt(V4L2_PIX_FMT_NV12)) - val |= CSI_WRDDR_TYPE_YUV420SP_RK3588 | CSI_YUV_OUTPUT_ORDER_UYVY; - } else { - if (find_output_fmt(V4L2_PIX_FMT_NV16)) - val |= CSI_WRDDR_TYPE_YUV422SP_RK3588 | CSI_YUV_OUTPUT_ORDER_UYVY; - } - - rkcif_write_reg(cif, get_reg_index_of_id_ctrl0(channel->id), val); rkcif_write_reg(cif, CIF_REG_MIPI_EFFECT_CODE_ID0, 0x02410251); rkcif_write_reg(cif, CIF_REG_MIPI_EFFECT_CODE_ID1, 0x02420252); cif->state = RKCIF_STATE_STREAMING; } else { id = channel->id; val = rkcif_read_reg(cif, get_reg_index_of_id_ctrl0(id)); - val &= ~CSI_ENABLE_CAPTURE; + if (cif->chip_id >= CHIP_RK3576_VEHICLE_CIF) + val &= ~(CSI_ENABLE_CAPTURE | CSI_DMA_ENABLE_RK3576); + else + val &= ~(CSI_ENABLE_CAPTURE | CSI_DMA_ENABLE); rkcif_write_reg(cif, get_reg_index_of_id_ctrl0(id), val); @@ -3308,7 +3618,9 @@ static int vehicle_cif_csi2_s_stream_v1(struct vehicle_cif *cif, CSI_LINE_INTEN(id))); rkcif_write_reg_and(cif, CIF_REG_MIPI_LVDS_INTEN, - ~CSI_ALL_ERROR_INTEN); + ~CSI_ALL_ERROR_INTEN_V1); + rkcif_write_reg_and(cif, CIF_REG_MIPI_LVDS_CTRL, + ~CSI_ENABLE_CAPTURE); cif->state = RKCIF_STATE_READY; } @@ -3542,10 +3854,10 @@ static int vehicle_cif_s_stream(struct vehicle_cif *cif, int enable) } dma_en = DVP_DMA_EN; - if (cif->chip_id < CHIP_RK3588_VEHICLE_CIF) + if (cif->chip_id < CHIP_RK3588_VEHICLE_CIF) { rkcif_write_reg(cif, CIF_REG_DVP_CTRL, AXI_BURST_16 | MODE_PINGPONG | ENABLE_CAPTURE); - else + } else if (cif->chip_id == CHIP_RK3588_VEHICLE_CIF) { rkcif_write_reg(cif, CIF_REG_DVP_CTRL, DVP_SW_WATER_LINE_25 | dma_en @@ -3555,6 +3867,15 @@ static int vehicle_cif_s_stream(struct vehicle_cif *cif, int enable) | DVP_SW_PRESS_VALUE(3) | DVP_SW_HURRY_VALUE(3) | ENABLE_CAPTURE); + } else { + dma_en = DVP_SW_DMA_EN_RK3676(0); + rkcif_write_reg(cif, CIF_REG_DVP_CTRL, + DVP_SW_WATER_LINE_25_RK3576 + | DVP_SW_CAP_EN_RK3576(0) + | dma_en + | ENABLE_CAPTURE); + } + cif->frame_idx = 0; cif->state = RKCIF_STATE_STREAMING; } else { @@ -4687,7 +5008,8 @@ int vehicle_cif_reverse_open(struct vehicle_cfg *v_cfg) /* 0. set csi2 & dphy clk */ vehicle_csi2_hw_soft_reset(cif); - if (cif->dphy_hw->chip_id == CHIP_ID_RK3588) + if (cif->dphy_hw->chip_id == CHIP_ID_RK3588 || + cif->dphy_hw->chip_id >= CHIP_ID_RK3562) vehicle_csi2_dphy_hw_do_reset(cif); if (!cif->dphy_hw->on) @@ -4784,7 +5106,8 @@ int vehicle_cif_reverse_close(void) if (cif->cif_cfg.type == V4L2_MBUS_CSI2_DPHY) { vehicle_cif_csi_stream_stop(cif); vehicle_csi2_hw_soft_reset(cif); - if (cif->dphy_hw->chip_id == CHIP_ID_RK3588) + if (cif->dphy_hw->chip_id == CHIP_ID_RK3588 || + cif->dphy_hw->chip_id >= CHIP_ID_RK3562) vehicle_csi2_dphy_hw_do_reset(cif); if (cif->dphy_hw->on) vehicle_csi2_clk_ctrl(cif, 0); @@ -4885,7 +5208,22 @@ static int cif_parse_dt(struct vehicle_cif *cif) syscon_regmap_lookup_by_phandle(phy_node, "rockchip,dphy-grf"); if (IS_ERR(cif->regmap_dphy_grf)) VEHICLE_INFO("unable to get rockchip,dphy-grf\n"); - } else if (cif->chip_id != CHIP_RK3588_VEHICLE_CIF) { + } else if (cif->chip_id == CHIP_RK3576_VEHICLE_CIF && + cif->csi_host_idx != RKCIF_MIPI0_CSI2) { + node = of_parse_phandle(phy_node, "rockchip,csi2-dphy", 0); + cif->csi2_dphy_base = of_iomap(node, 0); + + cif->regmap_dphy_grf = + syscon_regmap_lookup_by_phandle(phy_node, "rockchip,dphy-grf"); + if (IS_ERR(cif->regmap_dphy_grf)) + VEHICLE_INFO("unable to get rockchip,dphy-grf\n"); + + cif->dphy_sys_grf = + syscon_regmap_lookup_by_phandle(phy_node, "rockchip,sys-grf"); + if (IS_ERR(cif->dphy_sys_grf)) + VEHICLE_INFO("unable to get rockchip,sys-grf\n"); + } else if (cif->chip_id != CHIP_RK3588_VEHICLE_CIF && + cif->chip_id != CHIP_RK3576_VEHICLE_CIF) { node = of_parse_phandle(phy_node, "rockchip,csi2-dphy", 0); cif->csi2_dphy_base = of_iomap(node, 0); } @@ -4989,6 +5327,11 @@ int vehicle_cif_init(struct vehicle_cif *cif) dphy_hw = &rk3588_csi2_dphy_hw; } else if (cif->chip_id == CHIP_RK3562_VEHICLE_CIF) { dphy_hw = &rk3562_csi2_dphy_hw; + } else if (cif->chip_id == CHIP_RK3576_VEHICLE_CIF) { + if (cif->csi_host_idx == RKCIF_MIPI0_CSI2) + dphy_hw = &rk3576_csi2_dcphy_hw; + else + dphy_hw = &rk3576_csi2_dphy_hw; } else { dphy_hw = &rk3568_csi2_dphy_hw; } @@ -5001,6 +5344,9 @@ int vehicle_cif_init(struct vehicle_cif *cif) } else if (cif->chip_id == CHIP_RK3562_VEHICLE_CIF) { clk->clks_num = ARRAY_SIZE(rk3562_cif_clks); clk->rsts_num = ARRAY_SIZE(rk3562_cif_rsts); + } else if (cif->chip_id == CHIP_RK3576_VEHICLE_CIF) { + clk->clks_num = ARRAY_SIZE(rk3576_cif_clks); + clk->rsts_num = ARRAY_SIZE(rk3576_cif_rsts); } else { clk->clks_num = ARRAY_SIZE(rk3568_cif_clks); clk->rsts_num = ARRAY_SIZE(rk3568_cif_rsts); @@ -5020,6 +5366,11 @@ int vehicle_cif_init(struct vehicle_cif *cif) cif->dphy_hw->phy_index = 3; else cif->dphy_hw->phy_index = 0; + } else if (cif->dphy_hw->chip_id == CHIP_ID_RK3576) { + if (cif->csi_host_idx >= RKCIF_MIPI3_CSI2) + cif->dphy_hw->phy_index = 3; + else + cif->dphy_hw->phy_index = 0; } else { cif->dphy_hw->phy_index = 0; } @@ -5041,7 +5392,8 @@ int vehicle_cif_init(struct vehicle_cif *cif) } /* csi2 mipidphy rsts */ if (cif->dphy_hw->chip_id == CHIP_ID_RK3588 || - cif->dphy_hw->chip_id == CHIP_ID_RK3562) { + cif->dphy_hw->chip_id == CHIP_ID_RK3562 || + cif->dphy_hw->chip_id == CHIP_ID_RK3576) { for (i = 0; i < dphy_hw->num_dphy_rsts; i++) { struct reset_control *rst = NULL; @@ -5118,6 +5470,17 @@ int vehicle_cif_init(struct vehicle_cif *cif) clk->clks[i] = tmp_cif_clk; clk->on = false; } + } else if (cif->chip_id == CHIP_RK3576_VEHICLE_CIF) { + for (i = 0; i < clk->clks_num; i++) { + tmp_cif_clk = devm_clk_get(dev, rk3576_cif_clks[i]); + + if (IS_ERR(tmp_cif_clk)) { + dev_err(dev, "failed to get %s\n", rk3576_cif_clks[i]); + return PTR_ERR(tmp_cif_clk); + } + clk->clks[i] = tmp_cif_clk; + clk->on = false; + } } else { for (i = 0; i < clk->clks_num; i++) { tmp_cif_clk = devm_clk_get(dev, rk3568_cif_clks[i]); @@ -5156,6 +5519,18 @@ int vehicle_cif_init(struct vehicle_cif *cif) } clk->cif_rst[i] = rst; } + } else if (cif->chip_id == CHIP_RK3576_VEHICLE_CIF) { + for (i = 0; i < clk->rsts_num; i++) { + struct reset_control *rst = NULL; + + if (rk3576_cif_rsts[i]) + rst = devm_reset_control_get(dev, rk3576_cif_rsts[i]); + if (IS_ERR(rst)) { + dev_err(dev, "failed to get %s\n", rk3576_cif_rsts[i]); + return PTR_ERR(rst); + } + clk->cif_rst[i] = rst; + } } else { for (i = 0; i < clk->rsts_num; i++) { struct reset_control *rst = NULL; @@ -5218,6 +5593,8 @@ int vehicle_cif_init(struct vehicle_cif *cif) cif->cif_regs = rk3588_cif_regs; else if (cif->chip_id == CHIP_RK3562_VEHICLE_CIF) cif->cif_regs = rk3562_cif_regs; + else if (cif->chip_id == CHIP_RK3576_VEHICLE_CIF) + cif->cif_regs = rk3576_cif_regs; else cif->cif_regs = rk3568_cif_regs; @@ -5225,7 +5602,8 @@ int vehicle_cif_init(struct vehicle_cif *cif) /* 5. set csi2-mipi-dphy reg */ if (cif->dphy_hw->chip_id == CHIP_ID_RK3588 || cif->dphy_hw->chip_id == CHIP_ID_RK3568 || - cif->dphy_hw->chip_id == CHIP_ID_RK3562) + cif->dphy_hw->chip_id == CHIP_ID_RK3562 || + cif->dphy_hw->chip_id == CHIP_ID_RK3576) cif->dphy_hw->csi2_dphy_base = cif->csi2_dphy_base; /* 7. set mipi-csi2 reg */ @@ -5237,6 +5615,11 @@ int vehicle_cif_init(struct vehicle_cif *cif) cif->dphy_hw->regmap_grf = cif->regmap_dphy_grf; cif->dphy_hw->regmap_sys_grf = cif->regmap_grf; } + } else if (cif->chip_id == CHIP_RK3576_VEHICLE_CIF) { + if (cif->dphy_hw->chip_id == CHIP_ID_RK3576) { + cif->dphy_hw->regmap_grf = cif->regmap_dphy_grf; + cif->dphy_hw->regmap_sys_grf = cif->dphy_sys_grf; + } } else { cif->dphy_hw->regmap_grf = cif->regmap_grf; } @@ -5306,7 +5689,8 @@ int vehicle_cif_deinit(struct vehicle_cif *cif) clk_put(dphy_hw->dphy_clks[i].clk); /* dphy rsts release */ if (cif->dphy_hw->chip_id == CHIP_ID_RK3588 || - cif->dphy_hw->chip_id == CHIP_ID_RK3562) { + cif->dphy_hw->chip_id == CHIP_ID_RK3562 || + cif->dphy_hw->chip_id == CHIP_ID_RK3576) { for (i = 0; i < dphy_hw->num_dphy_rsts; i++) reset_control_put(dphy_hw->dphy_rst[i]); } diff --git a/drivers/video/rockchip/vehicle/vehicle_cif.h b/drivers/video/rockchip/vehicle/vehicle_cif.h index 3c75694acd89..f31de6a63366 100644 --- a/drivers/video/rockchip/vehicle/vehicle_cif.h +++ b/drivers/video/rockchip/vehicle/vehicle_cif.h @@ -16,6 +16,7 @@ enum vehicle_rkcif_chip_id { CHIP_RK3568_VEHICLE_CIF = 0x0, CHIP_RK3588_VEHICLE_CIF, CHIP_RK3562_VEHICLE_CIF, + CHIP_RK3576_VEHICLE_CIF, }; enum rkcif_csi_host_idx { @@ -128,6 +129,7 @@ struct vehicle_cif { const struct vehicle_cif_reg *cif_regs; struct regmap *regmap_grf; struct regmap *regmap_dphy_grf; + struct regmap *dphy_sys_grf; unsigned int frame_idx; struct vehicle_rkcif_dummy_buffer dummy_buf; struct csi2_dphy_hw *dphy_hw;