mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
media: rockchip: rv1106 vicap support dvp
Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com> Change-Id: I8c5b3db27d4fef1f486763cf2018729b9745b4ea
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "dev.h"
|
||||
#include "procfs.h"
|
||||
#include <linux/kthread.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user