summaryrefslogtreecommitdiff
path: root/drivers/media/platform/rockchip
diff options
context:
space:
mode:
authorHu Kejun <william.hu@rock-chips.com>2018-10-09 20:00:56 +0800
committerTao Huang <huangtao@rock-chips.com>2018-10-16 10:13:07 +0800
commit2b921a63d2d1e435ce3be93aaab8130872f84af6 (patch)
tree6828b5d7eb6e73dcbfb70205adc4b70564dfa775 /drivers/media/platform/rockchip
parent06ec79c3ad0e534df00da292c6288ea80b3a4c9f (diff)
media: rockchip: isp1: Support for RK1808
Change-Id: I652237cf447ce16c7a8f14a8f2608f1c16f62480 Signed-off-by: Hu Kejun <william.hu@rock-chips.com>
Diffstat (limited to 'drivers/media/platform/rockchip')
-rw-r--r--drivers/media/platform/rockchip/isp1/capture.c4
-rw-r--r--drivers/media/platform/rockchip/isp1/dev.c39
-rw-r--r--drivers/media/platform/rockchip/isp1/dev.h3
-rw-r--r--drivers/media/platform/rockchip/isp1/isp_params.c6
-rw-r--r--drivers/media/platform/rockchip/isp1/isp_stats.c3
-rw-r--r--drivers/media/platform/rockchip/isp1/regs.h28
-rw-r--r--drivers/media/platform/rockchip/isp1/rkisp1.c82
-rw-r--r--drivers/media/platform/rockchip/isp1/rkisp1.h3
8 files changed, 140 insertions, 28 deletions
diff --git a/drivers/media/platform/rockchip/isp1/capture.c b/drivers/media/platform/rockchip/isp1/capture.c
index 6496cefcff86..db69956037d4 100644
--- a/drivers/media/platform/rockchip/isp1/capture.c
+++ b/drivers/media/platform/rockchip/isp1/capture.c
@@ -759,7 +759,9 @@ static u32 calc_burst_len(struct rkisp1_stream *stream)
int i;
/* MI128bit and MI64bit */
- bus = (dev->isp_ver == ISP_V12) ? 16 : 8;
+ bus = 8;
+ if (dev->isp_ver == ISP_V12 || dev->isp_ver == ISP_V13)
+ bus = 16;
/* y/c base addr: burstN * bus alignment */
cb_offs = y_size;
diff --git a/drivers/media/platform/rockchip/isp1/dev.c b/drivers/media/platform/rockchip/isp1/dev.c
index 86bb038720fd..5021f3472793 100644
--- a/drivers/media/platform/rockchip/isp1/dev.c
+++ b/drivers/media/platform/rockchip/isp1/dev.c
@@ -484,6 +484,13 @@ err_cleanup_ctx:
return ret;
}
+static const char * const rk1808_isp_clks[] = {
+ "clk_isp",
+ "aclk_isp",
+ "hclk_isp",
+ "pclk_isp",
+};
+
static const char * const rk3288_isp_clks[] = {
"clk_isp",
"aclk_isp",
@@ -509,6 +516,11 @@ static const char * const rk3399_isp_clks[] = {
};
/* isp clock adjustment table (MHz) */
+static const unsigned int rk1808_isp_clk_rate[] = {
+ 400, 500, 600
+};
+
+/* isp clock adjustment table (MHz) */
static const unsigned int rk3288_isp_clk_rate[] = {
384, 500, 594
};
@@ -523,6 +535,14 @@ static const unsigned int rk3399_isp_clk_rate[] = {
300, 400, 600
};
+static const struct isp_match_data rk1808_isp_match_data = {
+ .clks = rk1808_isp_clks,
+ .num_clks = ARRAY_SIZE(rk1808_isp_clks),
+ .isp_ver = ISP_V13,
+ .clk_rate_tbl = rk1808_isp_clk_rate,
+ .num_clk_rate_tbl = ARRAY_SIZE(rk1808_isp_clk_rate),
+};
+
static const struct isp_match_data rk3288_isp_match_data = {
.clks = rk3288_isp_clks,
.num_clks = ARRAY_SIZE(rk3288_isp_clks),
@@ -549,6 +569,9 @@ static const struct isp_match_data rk3399_isp_match_data = {
static const struct of_device_id rkisp1_plat_of_match[] = {
{
+ .compatible = "rockchip,rk1808-rkisp1",
+ .data = &rk1808_isp_match_data,
+ }, {
.compatible = "rockchip,rk3288-rkisp1",
.data = &rk3288_isp_match_data,
}, {
@@ -566,14 +589,24 @@ static irqreturn_t rkisp1_irq_handler(int irq, void *ctx)
struct device *dev = ctx;
struct rkisp1_device *rkisp1_dev = dev_get_drvdata(dev);
unsigned int mis_val;
+ unsigned int err1, err2, err3;
mis_val = readl(rkisp1_dev->base_addr + CIF_ISP_MIS);
if (mis_val)
rkisp1_isp_isr(mis_val, rkisp1_dev);
- mis_val = readl(rkisp1_dev->base_addr + CIF_MIPI_MIS);
- if (mis_val)
- rkisp1_mipi_isr(mis_val, rkisp1_dev);
+ if (rkisp1_dev->isp_ver == ISP_V13) {
+ err1 = readl(rkisp1_dev->base_addr + CIF_ISP_CSI0_ERR1);
+ err2 = readl(rkisp1_dev->base_addr + CIF_ISP_CSI0_ERR2);
+ err3 = readl(rkisp1_dev->base_addr + CIF_ISP_CSI0_ERR3);
+
+ if (err1 || err2 || err3)
+ rkisp1_mipi_v13_isr(err1, err2, err3, rkisp1_dev);
+ } else {
+ mis_val = readl(rkisp1_dev->base_addr + CIF_MIPI_MIS);
+ if (mis_val)
+ rkisp1_mipi_isr(mis_val, rkisp1_dev);
+ }
mis_val = readl(rkisp1_dev->base_addr + CIF_MI_MIS);
if (mis_val)
diff --git a/drivers/media/platform/rockchip/isp1/dev.h b/drivers/media/platform/rockchip/isp1/dev.h
index 8d117bfecdd9..619f8f09f1ef 100644
--- a/drivers/media/platform/rockchip/isp1/dev.h
+++ b/drivers/media/platform/rockchip/isp1/dev.h
@@ -59,7 +59,8 @@
enum rkisp1_isp_ver {
ISP_V10 = 0,
ISP_V11,
- ISP_V12
+ ISP_V12,
+ ISP_V13
};
/*
diff --git a/drivers/media/platform/rockchip/isp1/isp_params.c b/drivers/media/platform/rockchip/isp1/isp_params.c
index 8fa617a8192d..66cb4e1ba48c 100644
--- a/drivers/media/platform/rockchip/isp1/isp_params.c
+++ b/drivers/media/platform/rockchip/isp1/isp_params.c
@@ -1688,7 +1688,8 @@ void rkisp1_params_config_parameter(struct rkisp1_isp_params_vdev *params_vdev)
memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight));
ops->hst_config(params_vdev, &hst);
- if (params_vdev->dev->isp_ver == ISP_V12) {
+ if (params_vdev->dev->isp_ver == ISP_V12 ||
+ params_vdev->dev->isp_ver == ISP_V13) {
isp_param_set_bits(params_vdev, CIF_ISP_HIST_CTRL_V12,
~CIF_ISP_HIST_CTRL_MODE_MASK_V12 |
hst_params_default_config.mode);
@@ -1957,7 +1958,8 @@ static void rkisp1_init_params_vdev(struct rkisp1_isp_params_vdev *params_vdev)
params_vdev->vdev_fmt.fmt.meta.buffersize =
sizeof(struct rkisp1_isp_params_cfg);
- if (params_vdev->dev->isp_ver == ISP_V12) {
+ if (params_vdev->dev->isp_ver == ISP_V12 ||
+ params_vdev->dev->isp_ver == ISP_V13) {
params_vdev->ops = &rkisp1_v12_isp_params_ops;
params_vdev->config = &rkisp1_v12_isp_params_config;
} else {
diff --git a/drivers/media/platform/rockchip/isp1/isp_stats.c b/drivers/media/platform/rockchip/isp1/isp_stats.c
index 5f8f46b98e3a..cfacbc58fee4 100644
--- a/drivers/media/platform/rockchip/isp1/isp_stats.c
+++ b/drivers/media/platform/rockchip/isp1/isp_stats.c
@@ -530,7 +530,8 @@ static void rkisp1_init_stats_vdev(struct rkisp1_isp_stats_vdev *stats_vdev)
stats_vdev->vdev_fmt.fmt.meta.buffersize =
sizeof(struct rkisp1_stat_buffer);
- if (stats_vdev->dev->isp_ver == ISP_V12) {
+ if (stats_vdev->dev->isp_ver == ISP_V12 ||
+ stats_vdev->dev->isp_ver == ISP_V13) {
stats_vdev->ops = &rkisp1_v12_stats_ops;
stats_vdev->config = &rkisp1_v12_stats_config;
} else {
diff --git a/drivers/media/platform/rockchip/isp1/regs.h b/drivers/media/platform/rockchip/isp1/regs.h
index bacc967742e6..44232d30e1db 100644
--- a/drivers/media/platform/rockchip/isp1/regs.h
+++ b/drivers/media/platform/rockchip/isp1/regs.h
@@ -716,6 +716,12 @@
#define CIF_ISP_DPF_SPATIAL_COEFF_MAX 0x1F
#define CIF_ISP_DPF_NLL_COEFF_N_MAX 0x3FF
+/* CSI0 */
+#define CIF_ISP_CSI0_IMASK_LINECNT BIT(12)
+#define CIF_ISP_CSI0_IMASK_RAW1_OUT_V_END BIT(11)
+#define CIF_ISP_CSI0_IMASK_RAW0_OUT_V_END BIT(10)
+#define CIF_ISP_CSI0_IMASK_FRAME_END(a) (((a) & 0x3F) << 0)
+
/* =================================================================== */
/* CIF Registers */
/* =================================================================== */
@@ -1437,6 +1443,28 @@
#define CIF_ISP_CSI0_BASE 0x00007000
#define CIF_ISP_CSI0_CTRL0 (CIF_ISP_CSI0_BASE + 0x00000000)
+#define CIF_ISP_CSI0_CTRL1 (CIF_ISP_CSI0_BASE + 0x00000004)
+#define CIF_ISP_CSI0_CTRL2 (CIF_ISP_CSI0_BASE + 0x00000008)
+#define CIF_ISP_CSI0_CSI2_RESETN (CIF_ISP_CSI0_BASE + 0x00000010)
+#define CIF_ISP_CSI0_PHY_STATE_RO (CIF_ISP_CSI0_BASE + 0x00000014)
+#define CIF_ISP_CSI0_DATA_IDS_1 (CIF_ISP_CSI0_BASE + 0x00000018)
+#define CIF_ISP_CSI0_DATA_IDS_2 (CIF_ISP_CSI0_BASE + 0x0000001c)
+#define CIF_ISP_CSI0_ERR1 (CIF_ISP_CSI0_BASE + 0x00000020)
+#define CIF_ISP_CSI0_ERR2 (CIF_ISP_CSI0_BASE + 0x00000024)
+#define CIF_ISP_CSI0_ERR3 (CIF_ISP_CSI0_BASE + 0x00000028)
+#define CIF_ISP_CSI0_MASK1 (CIF_ISP_CSI0_BASE + 0x0000002c)
+#define CIF_ISP_CSI0_MASK2 (CIF_ISP_CSI0_BASE + 0x00000030)
+#define CIF_ISP_CSI0_MASK3 (CIF_ISP_CSI0_BASE + 0x00000034)
+#define CIF_ISP_CSI0_SET_HEARDER (CIF_ISP_CSI0_BASE + 0x00000038)
+#define CIF_ISP_CSI0_CUR_HEADER_RO (CIF_ISP_CSI0_BASE + 0x0000003c)
+#define CIF_ISP_CSI0_DMATX0_CTRL (CIF_ISP_CSI0_BASE + 0x00000040)
+#define CIF_ISP_CSI0_DMATX0_LINECNT_RO (CIF_ISP_CSI0_BASE + 0x00000044)
+#define CIF_ISP_CSI0_DMATX0_PIC_SIZE (CIF_ISP_CSI0_BASE + 0x00000048)
+#define CIF_ISP_CSI0_DMATX0_PIC_OFF (CIF_ISP_CSI0_BASE + 0x0000004c)
+#define CIF_ISP_CSI0_FRAME_NUM_RO (CIF_ISP_CSI0_BASE + 0x00000070)
+#define CIF_ISP_CSI0_ISP_LINECNT_RO (CIF_ISP_CSI0_BASE + 0x00000074)
+#define CIF_ISP_CSI0_TX_IBUF_STATUS_RO (CIF_ISP_CSI0_BASE + 0x00000078)
+#define CIF_ISP_CSI0_VERSION (CIF_ISP_CSI0_BASE + 0x0000007c)
void disable_dcrop(struct rkisp1_stream *stream, bool async);
void config_dcrop(struct rkisp1_stream *stream, struct v4l2_rect *rect,
diff --git a/drivers/media/platform/rockchip/isp1/rkisp1.c b/drivers/media/platform/rockchip/isp1/rkisp1.c
index d0b0025a63f9..77b3aef2bc1d 100644
--- a/drivers/media/platform/rockchip/isp1/rkisp1.c
+++ b/drivers/media/platform/rockchip/isp1/rkisp1.c
@@ -45,6 +45,8 @@
#define CIF_ISP_INPUT_H_MAX 3312
#define CIF_ISP_INPUT_W_MAX_V12 3264
#define CIF_ISP_INPUT_H_MAX_V12 2448
+#define CIF_ISP_INPUT_W_MAX_V13 1920
+#define CIF_ISP_INPUT_H_MAX_V13 1080
#define CIF_ISP_INPUT_W_MIN 32
#define CIF_ISP_INPUT_H_MIN 16
#define CIF_ISP_OUTPUT_W_MAX CIF_ISP_INPUT_W_MAX
@@ -298,28 +300,49 @@ static int rkisp1_config_mipi(struct rkisp1_device *dev)
return -EINVAL;
}
- mipi_ctrl = CIF_MIPI_CTRL_NUM_LANES(lanes - 1) |
- CIF_MIPI_CTRL_SHUTDOWNLANES(0xf) |
- CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP |
- CIF_MIPI_CTRL_CLOCKLANE_ENA;
+ if (dev->isp_ver == ISP_V13) {
+ /* csi2host enable */
+ writel(1, base + CIF_ISP_CSI0_CTRL0);
- writel(mipi_ctrl, base + CIF_MIPI_CTRL);
- if (dev->isp_ver == ISP_V12)
- writel(0, base + CIF_ISP_CSI0_CTRL0);
+ /* lanes */
+ writel(lanes - 1, base + CIF_ISP_CSI0_CTRL1);
- /* Configure Data Type and Virtual Channel */
- writel(CIF_MIPI_DATA_SEL_DT(in_fmt->mipi_dt) | CIF_MIPI_DATA_SEL_VC(0),
- base + CIF_MIPI_IMG_DATA_SEL);
+ /* linecnt */
+ writel(0x3FFF, base + CIF_ISP_CSI0_CTRL2);
- /* Clear MIPI interrupts */
- writel(~0, base + CIF_MIPI_ICR);
- /*
- * Disable CIF_MIPI_ERR_DPHY interrupt here temporary for
- * isp bus may be dead when switch isp.
- */
- writel(CIF_MIPI_FRAME_END | CIF_MIPI_ERR_CSI | CIF_MIPI_ERR_DPHY |
- CIF_MIPI_SYNC_FIFO_OVFLW(0x03) | CIF_MIPI_ADD_DATA_OVFLW,
- base + CIF_MIPI_IMSC);
+ /* Configure Data Type and Virtual Channel */
+ writel(CIF_MIPI_DATA_SEL_DT(in_fmt->mipi_dt) | CIF_MIPI_DATA_SEL_VC(0),
+ base + CIF_ISP_CSI0_DATA_IDS_1);
+
+ /* interrupts */
+ writel(CIF_ISP_CSI0_IMASK_FRAME_END(0x3F) |
+ CIF_ISP_CSI0_IMASK_LINECNT,
+ base + CIF_ISP_CSI0_MASK3);
+
+ } else {
+ mipi_ctrl = CIF_MIPI_CTRL_NUM_LANES(lanes - 1) |
+ CIF_MIPI_CTRL_SHUTDOWNLANES(0xf) |
+ CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP |
+ CIF_MIPI_CTRL_CLOCKLANE_ENA;
+
+ writel(mipi_ctrl, base + CIF_MIPI_CTRL);
+ if (dev->isp_ver == ISP_V12)
+ writel(0, base + CIF_ISP_CSI0_CTRL0);
+
+ /* Configure Data Type and Virtual Channel */
+ writel(CIF_MIPI_DATA_SEL_DT(in_fmt->mipi_dt) | CIF_MIPI_DATA_SEL_VC(0),
+ base + CIF_MIPI_IMG_DATA_SEL);
+
+ /* Clear MIPI interrupts */
+ writel(~0, base + CIF_MIPI_ICR);
+ /*
+ * Disable CIF_MIPI_ERR_DPHY interrupt here temporary for
+ * isp bus may be dead when switch isp.
+ */
+ writel(CIF_MIPI_FRAME_END | CIF_MIPI_ERR_CSI | CIF_MIPI_ERR_DPHY |
+ CIF_MIPI_SYNC_FIFO_OVFLW(0x03) | CIF_MIPI_ADD_DATA_OVFLW,
+ base + CIF_MIPI_IMSC);
+ }
v4l2_dbg(1, rkisp1_debug, &dev->v4l2_dev, "\n MIPI_CTRL 0x%08x\n"
" MIPI_IMG_DATA_SEL 0x%08x\n"
@@ -477,7 +500,7 @@ static void rkisp1_config_clk(struct rkisp1_device *dev)
writel(val, dev->base_addr + CIF_ICCL);
- if (dev->isp_ver == ISP_V12) {
+ if (dev->isp_ver == ISP_V12 || dev->isp_ver == ISP_V13) {
val = CIF_CLK_CTRL_MI_Y12 | CIF_CLK_CTRL_MI_SP |
CIF_CLK_CTRL_MI_RAW0 | CIF_CLK_CTRL_MI_RAW1 |
CIF_CLK_CTRL_MI_READ | CIF_CLK_CTRL_MI_RAWRD |
@@ -783,6 +806,13 @@ static void rkisp1_isp_sd_try_fmt(struct v4l2_subdev *sd,
fmt->height = clamp_t(u32, fmt->height,
CIF_ISP_INPUT_H_MIN,
CIF_ISP_INPUT_H_MAX_V12);
+ } else if (isp_dev->isp_ver == ISP_V13) {
+ fmt->width = clamp_t(u32, fmt->width,
+ CIF_ISP_INPUT_W_MIN,
+ CIF_ISP_INPUT_W_MAX_V13);
+ fmt->height = clamp_t(u32, fmt->height,
+ CIF_ISP_INPUT_H_MIN,
+ CIF_ISP_INPUT_H_MAX_V13);
} else {
fmt->width = clamp_t(u32, fmt->width,
CIF_ISP_INPUT_W_MIN,
@@ -1210,6 +1240,18 @@ void rkisp1_mipi_isr(unsigned int mis, struct rkisp1_device *dev)
}
}
+void rkisp1_mipi_v13_isr(unsigned int err1, unsigned int err2,
+ unsigned int err3, struct rkisp1_device *dev)
+{
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+
+ if (err1)
+ v4l2_warn(v4l2_dev, "MIPI error: err1: 0x%08x\n", err1);
+
+ if (err2)
+ v4l2_warn(v4l2_dev, "MIPI error: err2: 0x%08x\n", err2);
+}
+
void rkisp1_isp_isr(unsigned int isp_mis, struct rkisp1_device *dev)
{
void __iomem *base = dev->base_addr;
diff --git a/drivers/media/platform/rockchip/isp1/rkisp1.h b/drivers/media/platform/rockchip/isp1/rkisp1.h
index 3ea008e899d9..054235be88e7 100644
--- a/drivers/media/platform/rockchip/isp1/rkisp1.h
+++ b/drivers/media/platform/rockchip/isp1/rkisp1.h
@@ -109,6 +109,9 @@ void rkisp1_unregister_isp_subdev(struct rkisp1_device *isp_dev);
void rkisp1_mipi_isr(unsigned int mipi_mis, struct rkisp1_device *dev);
+void rkisp1_mipi_v13_isr(unsigned int err1, unsigned int err2,
+ unsigned int err3, struct rkisp1_device *dev);
+
void rkisp1_isp_isr(unsigned int isp_mis, struct rkisp1_device *dev);
static inline