diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 4201b93b429b..03091b4c243c 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -2917,6 +2917,8 @@ static void rkcif_stream_stop(struct rkcif_stream *stream) rkcif_write_register(cif_dev, CIF_REG_DVP_INTEN, 0x0); rkcif_write_register(cif_dev, CIF_REG_DVP_INTSTAT, 0x3ff); rkcif_write_register(cif_dev, CIF_REG_DVP_FRAME_STATUS, 0x0); + if (IS_ENABLED(CONFIG_CPU_RV1106)) + rkcif_config_dvp_pin(cif_dev, false); } } stream->cifdev->id_use_cnt--; @@ -4183,6 +4185,9 @@ static int rkcif_stream_start(struct rkcif_stream *stream, unsigned int mode) rkcif_enable_dvp_clk_dual_edge(dev, false); } + if (IS_ENABLED(CONFIG_CPU_RV1106)) + rkcif_config_dvp_pin(dev, true); + if (mbus_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) rkcif_config_dvp_clk_sampling_edge(dev, RKCIF_CLK_RISING); else diff --git a/drivers/media/platform/rockchip/cif/dev.c b/drivers/media/platform/rockchip/cif/dev.c index b6f50007533f..0ae598b92392 100644 --- a/drivers/media/platform/rockchip/cif/dev.c +++ b/drivers/media/platform/rockchip/cif/dev.c @@ -27,6 +27,7 @@ #include "dev.h" #include "procfs.h" #include +#include "../../../../phy/rockchip/phy-rockchip-csi2-dphy-common.h" #define RKCIF_VERNO_LEN 10 @@ -770,6 +771,12 @@ void rkcif_enable_dvp_clk_dual_edge(struct rkcif_device *dev, bool on) else val = RK3588_CIF_PCLK_SINGLE_EDGE; rkcif_write_grf_reg(dev, CIF_REG_GRF_CIFIO_CON, val); + } else if (dev->chip_id == CHIP_RV1106_CIF) { + if (on) + val = RV1106_CIF_PCLK_DUAL_EDGE; + else + val = RV1106_CIF_PCLK_SINGLE_EDGE; + rkcif_write_grf_reg(dev, CIF_REG_GRF_CIFIO_CON, val); } } @@ -804,10 +811,38 @@ void rkcif_config_dvp_clk_sampling_edge(struct rkcif_device *dev, else val = RK3588_CIF_PCLK_SAMPLING_EDGE_FALLING; } + if (dev->chip_id == CHIP_RV1106_CIF) { + if (dev->dphy_hw) { + if (edge == RKCIF_CLK_RISING) + val = RV1106_CIF_PCLK_EDGE_RISING_M0; + else + val = RV1106_CIF_PCLK_EDGE_FALLING_M0; + } else { + if (edge == RKCIF_CLK_RISING) + val = RV1106_CIF_PCLK_EDGE_RISING_M1; + else + val = RV1106_CIF_PCLK_EDGE_FALLING_M1; + rkcif_write_grf_reg(dev, CIF_REG_GRF_CIFIO_VENC, val); + return; + } + } rkcif_write_grf_reg(dev, CIF_REG_GRF_CIFIO_CON, val); } } +void rkcif_config_dvp_pin(struct rkcif_device *dev, bool on) +{ + if (dev->dphy_hw && dev->dphy_hw->ttl_mode_enable && dev->dphy_hw->ttl_mode_disable) { + rkcif_write_grf_reg(dev, CIF_REG_GRF_CIFIO_CON, RV1106_CIF_GRF_SEL_M0); + if (on) + dev->dphy_hw->ttl_mode_enable(dev->dphy_hw); + else + dev->dphy_hw->ttl_mode_disable(dev->dphy_hw); + } else { + rkcif_write_grf_reg(dev, CIF_REG_GRF_CIFIO_CON, RV1106_CIF_GRF_SEL_M1); + } +} + /**************************** pipeline operations *****************************/ static int __cif_pipeline_prepare(struct rkcif_pipeline *p, struct media_entity *me) @@ -1624,6 +1659,37 @@ static irqreturn_t rkcif_irq_lite_handler(int irq, struct rkcif_device *cif_dev) return IRQ_HANDLED; } +static void rkcif_attach_dphy_hw(struct rkcif_device *cif_dev) +{ + struct platform_device *plat_dev; + struct device *dev = cif_dev->dev; + struct device_node *np; + struct csi2_dphy_hw *dphy_hw; + + np = of_parse_phandle(dev->of_node, "rockchip,dphy_hw", 0); + if (!np || !of_device_is_available(np)) { + dev_err(dev, + "failed to get dphy hw node\n"); + return; + } + + plat_dev = of_find_device_by_node(np); + of_node_put(np); + if (!plat_dev) { + dev_err(dev, + "failed to get dphy hw from node\n"); + return; + } + + dphy_hw = platform_get_drvdata(plat_dev); + if (!dphy_hw) { + dev_err(dev, + "failed attach dphy hw\n"); + return; + } + cif_dev->dphy_hw = dphy_hw; +} + int rkcif_attach_hw(struct rkcif_device *cif_dev) { struct device_node *np; @@ -1658,6 +1724,8 @@ int rkcif_attach_hw(struct rkcif_device *cif_dev) cif_dev->hw_dev = hw; cif_dev->chip_id = hw->chip_id; dev_info(cif_dev->dev, "attach to cif hw node\n"); + if (IS_ENABLED(CONFIG_CPU_RV1106)) + rkcif_attach_dphy_hw(cif_dev); return 0; } diff --git a/drivers/media/platform/rockchip/cif/dev.h b/drivers/media/platform/rockchip/cif/dev.h index 4c2e8c54ec3f..6158ed52edc0 100644 --- a/drivers/media/platform/rockchip/cif/dev.h +++ b/drivers/media/platform/rockchip/cif/dev.h @@ -803,6 +803,7 @@ struct rkcif_device { unsigned int wait_line_cache; struct rkcif_dummy_buffer dummy_buf; struct completion cmpl_ntf; + struct csi2_dphy_hw *dphy_hw; bool is_start_hdr; bool reset_work_cancel; bool iommu_en; @@ -883,4 +884,6 @@ void rkcif_do_soft_reset(struct rkcif_device *dev); u32 rkcif_mbus_pixelcode_to_v4l2(u32 pixelcode); +void rkcif_config_dvp_pin(struct rkcif_device *dev, bool on); + #endif diff --git a/drivers/media/platform/rockchip/cif/hw.c b/drivers/media/platform/rockchip/cif/hw.c index fdb15a32c321..af28cfee60ec 100644 --- a/drivers/media/platform/rockchip/cif/hw.c +++ b/drivers/media/platform/rockchip/cif/hw.c @@ -862,6 +862,8 @@ static const struct cif_reg rv1106_cif_regs[] = { [CIF_REG_TOISP0_CTRL] = CIF_REG(TOISP0_CH_CTRL), [CIF_REG_TOISP0_SIZE] = CIF_REG(TOISP0_CROP_SIZE), [CIF_REG_TOISP0_CROP] = CIF_REG(TOISP0_CROP), + [CIF_REG_GRF_CIFIO_CON] = CIF_REG(RV1106_CIF_GRF_VI_CON), + [CIF_REG_GRF_CIFIO_VENC] = CIF_REG(RV1106_CIF_GRF_VENC_WRAPPER), }; static const struct rkcif_hw_match_data px30_cif_match_data = { diff --git a/drivers/media/platform/rockchip/cif/mipi-csi2.c b/drivers/media/platform/rockchip/cif/mipi-csi2.c index 94c4b192cc67..ff54f7843b62 100644 --- a/drivers/media/platform/rockchip/cif/mipi-csi2.c +++ b/drivers/media/platform/rockchip/cif/mipi-csi2.c @@ -45,7 +45,7 @@ static inline struct csi2_dev *sd_to_dev(struct v4l2_subdev *sdev) return container_of(sdev, struct csi2_dev, sd); } -static struct csi2_sensor *sd_to_sensor(struct csi2_dev *csi2, +static struct csi2_sensor_info *sd_to_sensor(struct csi2_dev *csi2, struct v4l2_subdev *sd) { int i; @@ -106,8 +106,8 @@ static void get_remote_terminal_sensor(struct v4l2_subdev *sd, static void csi2_update_sensor_info(struct csi2_dev *csi2) { - struct csi2_sensor *sensor = &csi2->sensors[0]; struct v4l2_subdev *terminal_sensor_sd = NULL; + struct csi2_sensor_info *sensor = &csi2->sensors[0]; struct v4l2_mbus_config mbus; int ret = 0; @@ -659,7 +659,7 @@ csi2_notifier_bound(struct v4l2_async_notifier *notifier, struct csi2_dev *csi2 = container_of(notifier, struct csi2_dev, notifier); - struct csi2_sensor *sensor; + struct csi2_sensor_info *sensor; struct media_link *link; unsigned int pad, ret; @@ -715,7 +715,7 @@ static void csi2_notifier_unbind(struct v4l2_async_notifier *notifier, struct csi2_dev *csi2 = container_of(notifier, struct csi2_dev, notifier); - struct csi2_sensor *sensor = sd_to_sensor(csi2, sd); + struct csi2_sensor_info *sensor = sd_to_sensor(csi2, sd); sensor->sd = NULL; diff --git a/drivers/media/platform/rockchip/cif/mipi-csi2.h b/drivers/media/platform/rockchip/cif/mipi-csi2.h index 4ee4a33d1d5e..cd8dceb5d8ea 100644 --- a/drivers/media/platform/rockchip/cif/mipi-csi2.h +++ b/drivers/media/platform/rockchip/cif/mipi-csi2.h @@ -117,7 +117,7 @@ struct csi2_match_data { int num_pads; }; -struct csi2_sensor { +struct csi2_sensor_info { struct v4l2_subdev *sd; struct v4l2_mbus_config mbus; int lanes; @@ -147,8 +147,8 @@ struct csi2_dev { int stream_count; struct v4l2_subdev *src_sd; bool sink_linked[CSI2_NUM_SRC_PADS]; - struct csi2_sensor sensors[MAX_CSI2_SENSORS]; bool is_check_sot_sync; + struct csi2_sensor_info sensors[MAX_CSI2_SENSORS]; const struct csi2_match_data *match_data; int num_sensors; atomic_t frm_sync_seq; diff --git a/drivers/media/platform/rockchip/cif/regs.h b/drivers/media/platform/rockchip/cif/regs.h index 54709bab1048..2d913519c85a 100644 --- a/drivers/media/platform/rockchip/cif/regs.h +++ b/drivers/media/platform/rockchip/cif/regs.h @@ -162,6 +162,7 @@ enum cif_reg_index { /* reg belowed is in grf */ CIF_REG_GRF_CIFIO_CON, CIF_REG_GRF_CIFIO_CON1, + CIF_REG_GRF_CIFIO_VENC, /* reg global control */ CIF_REG_GLB_CTRL, CIF_REG_GLB_INTEN, @@ -1042,7 +1043,16 @@ enum cif_reg_index { #define RK3588_CIF_PCLK_SAMPLING_EDGE_FALLING (0x00100010) #define RK3588_CIF_PCLK_SINGLE_EDGE (0x00200000) #define RK3588_CIF_PCLK_DUAL_EDGE (0x00200020) - +#define RV1106_CIF_GRF_VI_CON (0x50038) +#define RV1106_CIF_GRF_VENC_WRAPPER (0x10008) +#define RV1106_CIF_PCLK_SINGLE_EDGE (0x00040000) +#define RV1106_CIF_PCLK_DUAL_EDGE (0x00040004) +#define RV1106_CIF_PCLK_EDGE_RISING_M0 (0x00020000) +#define RV1106_CIF_PCLK_EDGE_FALLING_M0 (0x00020002) +#define RV1106_CIF_PCLK_EDGE_RISING_M1 (0x00010000) +#define RV1106_CIF_PCLK_EDGE_FALLING_M1 (0x00010001) +#define RV1106_CIF_GRF_SEL_M0 (0x00010000) +#define RV1106_CIF_GRF_SEL_M1 (0x00010001) /*toisp*/ #define TOISP_FS_CH0(index) (0x1 << (14 + index * 3))