1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2022 Rockchip Electronics Co., Ltd */
3
4 #include <linux/of.h>
5 #include <linux/of_platform.h>
6 #include <soc/rockchip/rockchip_dvbm.h>
7
8 #include "dev.h"
9 #include "regs.h"
10
11 static struct dvbm_port *g_dvbm;
12
rkisp_dvbm_get(struct rkisp_device * dev)13 int rkisp_dvbm_get(struct rkisp_device *dev)
14 {
15 struct device_node *np = dev->dev->of_node;
16 struct device_node *np_dvbm = of_parse_phandle(np, "dvbm", 0);
17 int ret = -EINVAL;
18
19 g_dvbm = NULL;
20 if (dev->isp_ver != ISP_V32)
21 goto end;
22
23 if (!np_dvbm || !of_device_is_available(np_dvbm)) {
24 dev_warn(dev->dev, "failed to get dvbm node\n");
25 } else {
26 struct platform_device *p_dvbm = of_find_device_by_node(np_dvbm);
27
28 g_dvbm = rk_dvbm_get_port(p_dvbm, DVBM_ISP_PORT);
29 of_node_put(np_dvbm);
30 }
31
32 end:
33 return ret;
34 }
35
rkisp_dvbm_init(struct rkisp_stream * stream)36 int rkisp_dvbm_init(struct rkisp_stream *stream)
37 {
38 struct rkisp_device *dev = stream->ispdev;
39 struct rkisp_dummy_buffer *buf = &stream->dummy_buf;
40 struct dvbm_isp_cfg_t dvbm_cfg;
41 u32 width, height, wrap_line;
42
43 if (!g_dvbm)
44 return -EINVAL;
45
46 width = stream->out_fmt.plane_fmt[0].bytesperline;
47 height = stream->out_fmt.height;
48 wrap_line = dev->cap_dev.wrap_line;
49 dvbm_cfg.dma_addr = buf->dma_addr;
50 dvbm_cfg.ybuf_bot = 0;
51 dvbm_cfg.ybuf_top = width * wrap_line;
52 dvbm_cfg.ybuf_lstd = width;
53 dvbm_cfg.ybuf_fstd = width * height;
54 dvbm_cfg.cbuf_bot = dvbm_cfg.ybuf_top;
55 dvbm_cfg.cbuf_top = dvbm_cfg.cbuf_bot + (width * wrap_line / 2);
56 dvbm_cfg.cbuf_lstd = width;
57 dvbm_cfg.cbuf_fstd = dvbm_cfg.ybuf_fstd / 2;
58
59 rk_dvbm_ctrl(g_dvbm, DVBM_ISP_SET_CFG, &dvbm_cfg);
60 rk_dvbm_link(g_dvbm);
61 return 0;
62 }
63
rkisp_dvbm_deinit(void)64 void rkisp_dvbm_deinit(void)
65 {
66 if (g_dvbm)
67 rk_dvbm_unlink(g_dvbm);
68 }
69
rkisp_dvbm_event(struct rkisp_device * dev,u32 event)70 int rkisp_dvbm_event(struct rkisp_device *dev, u32 event)
71 {
72 enum dvbm_cmd cmd;
73 u32 seq;
74
75 if (!g_dvbm || dev->isp_ver != ISP_V32 ||
76 !dev->cap_dev.wrap_line)
77 return -EINVAL;
78
79 rkisp_dmarx_get_frame(dev, &seq, NULL, NULL, true);
80
81 switch (event) {
82 case CIF_ISP_V_START:
83 cmd = DVBM_ISP_FRM_START;
84 break;
85 case CIF_MI_MP_FRAME:
86 cmd = DVBM_ISP_FRM_END;
87 break;
88 default:
89 return -EINVAL;
90 }
91
92 return rk_dvbm_ctrl(g_dvbm, cmd, &seq);
93 }
94