diff options
author | Hu Kejun <william.hu@rock-chips.com> | 2018-10-09 20:00:56 +0800 |
---|---|---|
committer | Tao Huang <huangtao@rock-chips.com> | 2018-10-16 10:13:07 +0800 |
commit | 2b921a63d2d1e435ce3be93aaab8130872f84af6 (patch) | |
tree | 6828b5d7eb6e73dcbfb70205adc4b70564dfa775 /drivers/media/platform/rockchip | |
parent | 06ec79c3ad0e534df00da292c6288ea80b3a4c9f (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.c | 4 | ||||
-rw-r--r-- | drivers/media/platform/rockchip/isp1/dev.c | 39 | ||||
-rw-r--r-- | drivers/media/platform/rockchip/isp1/dev.h | 3 | ||||
-rw-r--r-- | drivers/media/platform/rockchip/isp1/isp_params.c | 6 | ||||
-rw-r--r-- | drivers/media/platform/rockchip/isp1/isp_stats.c | 3 | ||||
-rw-r--r-- | drivers/media/platform/rockchip/isp1/regs.h | 28 | ||||
-rw-r--r-- | drivers/media/platform/rockchip/isp1/rkisp1.c | 82 | ||||
-rw-r--r-- | drivers/media/platform/rockchip/isp1/rkisp1.h | 3 |
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 |