1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd. */
3
4 #include <linux/delay.h>
5 #include <linux/pm_runtime.h>
6 #include <media/v4l2-common.h>
7 #include <media/v4l2-event.h>
8 #include <media/v4l2-fh.h>
9 #include <media/v4l2-ioctl.h>
10 #include <media/v4l2-subdev.h>
11 #include <media/videobuf2-dma-contig.h>
12 #include <linux/dma-iommu.h>
13 #include <linux/rk-camera-module.h>
14 #include "dev.h"
15 #include "regs.h"
16
17 static inline
to_bridge_buf(struct rkisp_ispp_buf * dbufs)18 struct rkisp_bridge_buf *to_bridge_buf(struct rkisp_ispp_buf *dbufs)
19 {
20 return container_of(dbufs, struct rkisp_bridge_buf, dbufs);
21 }
22
crop_on(struct rkisp_bridge_device * dev)23 static void crop_on(struct rkisp_bridge_device *dev)
24 {
25 struct rkisp_device *ispdev = dev->ispdev;
26 u32 src_w = ispdev->isp_sdev.out_crop.width;
27 u32 src_h = ispdev->isp_sdev.out_crop.height;
28 u32 dest_w = dev->crop.width;
29 u32 dest_h = dev->crop.height;
30 u32 left = dev->crop.left;
31 u32 top = dev->crop.top;
32 u32 ctrl = CIF_DUAL_CROP_CFG_UPD;
33
34 rkisp_write(ispdev, CIF_DUAL_CROP_M_H_OFFS, left, false);
35 rkisp_write(ispdev, CIF_DUAL_CROP_M_V_OFFS, top, false);
36 rkisp_write(ispdev, CIF_DUAL_CROP_M_H_SIZE, dest_w, false);
37 rkisp_write(ispdev, CIF_DUAL_CROP_M_V_SIZE, dest_h, false);
38 ctrl |= rkisp_read(ispdev, CIF_DUAL_CROP_CTRL, true);
39 if (src_w == dest_w && src_h == dest_h)
40 ctrl &= ~(CIF_DUAL_CROP_MP_MODE_YUV | CIF_DUAL_CROP_MP_MODE_RAW);
41 else
42 ctrl |= CIF_DUAL_CROP_MP_MODE_YUV;
43 rkisp_write(ispdev, CIF_DUAL_CROP_CTRL, ctrl, false);
44 }
45
crop_off(struct rkisp_bridge_device * dev)46 static void crop_off(struct rkisp_bridge_device *dev)
47 {
48 struct rkisp_device *ispdev = dev->ispdev;
49 u32 ctrl = CIF_DUAL_CROP_GEN_CFG_UPD;
50
51 ctrl = rkisp_read(ispdev, CIF_DUAL_CROP_CTRL, true);
52 ctrl &= ~(CIF_DUAL_CROP_MP_MODE_YUV | CIF_DUAL_CROP_MP_MODE_RAW);
53 rkisp_write(ispdev, CIF_DUAL_CROP_CTRL, ctrl, false);
54 }
55
bridge_start(struct rkisp_bridge_device * dev)56 static int bridge_start(struct rkisp_bridge_device *dev)
57 {
58 crop_on(dev);
59 dev->ops->config(dev);
60
61 rkisp_stats_first_ddr_config(&dev->ispdev->stats_vdev);
62 if (!dev->ispdev->hw_dev->is_mi_update)
63 force_cfg_update(dev->ispdev);
64
65 dev->ispdev->skip_frame = 0;
66 dev->en = true;
67 return 0;
68 }
69
bridge_stop(struct rkisp_bridge_device * dev)70 static int bridge_stop(struct rkisp_bridge_device *dev)
71 {
72 int ret;
73
74 dev->stopping = true;
75 if (dev->ispdev->hw_dev->is_single)
76 dev->ops->disable(dev);
77 ret = wait_event_timeout(dev->done, !dev->en,
78 msecs_to_jiffies(1000));
79 if (!ret)
80 v4l2_warn(&dev->sd,
81 "%s timeout ret:%d\n", __func__, ret);
82 crop_off(dev);
83 dev->stopping = false;
84 dev->en = false;
85 dev->ops->disable(dev);
86 dev->ispdev->irq_ends_mask &= ~ISP_FRAME_MP;
87 return 0;
88 }
89
bridge_update_mi(struct rkisp_bridge_device * br)90 static void bridge_update_mi(struct rkisp_bridge_device *br)
91 {
92 struct rkisp_device *dev = br->ispdev;
93 struct rkisp_hw_dev *hw = dev->hw_dev;
94 struct rkisp_bridge_buf *buf;
95 u32 val;
96
97 if (hw->nxt_buf) {
98 buf = to_bridge_buf(hw->nxt_buf);
99 val = buf->dummy[GROUP_BUF_PIC].dma_addr;
100 rkisp_write(dev, br->cfg->reg.y0_base, val, true);
101 val += br->cfg->offset;
102 rkisp_write(dev, br->cfg->reg.uv0_base, val, true);
103 }
104
105 v4l2_dbg(2, rkisp_debug, &br->sd,
106 "update pic(shd:0x%x base:0x%x)\n",
107 rkisp_read(dev, br->cfg->reg.y0_base_shd, true),
108 rkisp_read(dev, br->cfg->reg.y0_base, true));
109 }
110
bridge_frame_end(struct rkisp_bridge_device * dev,u32 state)111 static int bridge_frame_end(struct rkisp_bridge_device *dev, u32 state)
112 {
113 struct rkisp_device *ispdev = dev->ispdev;
114 struct rkisp_hw_dev *hw = ispdev->hw_dev;
115 struct v4l2_subdev *sd = v4l2_get_subdev_hostdata(&dev->sd);
116 unsigned long lock_flags = 0;
117 u64 ns = ktime_get_ns();
118
119 if (dev->stopping) {
120 if (!hw->is_single) {
121 dev->en = false;
122 dev->stopping = false;
123 dev->ops->disable(dev);
124 wake_up(&dev->done);
125 } else if (dev->ops->is_stopped(dev)) {
126 dev->en = false;
127 dev->stopping = false;
128 wake_up(&dev->done);
129 }
130 }
131
132 if (!dev->en) {
133 ispdev->irq_ends_mask &= ~ISP_FRAME_MP;
134 return 0;
135 }
136
137 rkisp_dmarx_get_frame(ispdev, &dev->dbg.id, NULL, NULL, true);
138 dev->dbg.interval = ns - dev->dbg.timestamp;
139 dev->dbg.timestamp = ns;
140 if (hw->cur_buf && hw->nxt_buf) {
141 if (ispdev->skip_frame > 0) {
142 ispdev->skip_frame--;
143 spin_lock_irqsave(&hw->buf_lock, lock_flags);
144 list_add_tail(&hw->cur_buf->list, &hw->list);
145 spin_unlock_irqrestore(&hw->buf_lock, lock_flags);
146 } else {
147 ns = 0;
148 rkisp_dmarx_get_frame(ispdev, &hw->cur_buf->frame_id,
149 NULL, &ns, true);
150 if (!ns)
151 ns = ktime_get_ns();
152 hw->cur_buf->frame_timestamp = ns;
153 hw->cur_buf->index = ispdev->dev_id;
154 v4l2_subdev_call(sd, video, s_rx_buffer, hw->cur_buf, NULL);
155 }
156 hw->cur_buf = NULL;
157 } else {
158 v4l2_dbg(1, rkisp_debug, &dev->sd, "lost frm_id %d\n", dev->dbg.id);
159 dev->dbg.frameloss++;
160 }
161
162 if (hw->nxt_buf) {
163 hw->cur_buf = hw->nxt_buf;
164 hw->nxt_buf = NULL;
165 }
166
167 return 0;
168 }
169
config_mp(struct rkisp_bridge_device * dev)170 static int config_mp(struct rkisp_bridge_device *dev)
171 {
172 u32 w = dev->crop.width;
173 u32 h = dev->crop.height;
174 u32 val;
175
176 val = w * h;
177 rkisp_write(dev->ispdev, CIF_MI_MP_Y_SIZE_INIT, val, false);
178 val = (dev->work_mode & ISP_ISPP_422) ? val : val / 2;
179 rkisp_write(dev->ispdev, CIF_MI_MP_CB_SIZE_INIT, val, false);
180 rkisp_write(dev->ispdev, CIF_MI_MP_CR_SIZE_INIT, 0, false);
181 rkisp_write(dev->ispdev, CIF_MI_MP_Y_OFFS_CNT_INIT, 0, false);
182 rkisp_write(dev->ispdev, CIF_MI_MP_CB_OFFS_CNT_INIT, 0, false);
183 rkisp_write(dev->ispdev, CIF_MI_MP_CR_OFFS_CNT_INIT, 0, false);
184
185 rkisp_write(dev->ispdev, ISP_MPFBC_BASE,
186 dev->work_mode & ISP_ISPP_422, false);
187 rkisp_set_bits(dev->ispdev, CIF_MI_CTRL, MI_CTRL_MP_FMT_MASK,
188 MI_CTRL_MP_WRITE_YUV_SPLA | CIF_MI_CTRL_MP_ENABLE |
189 CIF_MI_MP_AUTOUPDATE_ENABLE, false);
190 dev->ispdev->irq_ends_mask |= ISP_FRAME_MP;
191 return 0;
192 }
193
disable_mp(struct rkisp_bridge_device * dev)194 static void disable_mp(struct rkisp_bridge_device *dev)
195 {
196 rkisp_clear_bits(dev->ispdev, CIF_MI_CTRL,
197 CIF_MI_CTRL_MP_ENABLE | CIF_MI_CTRL_RAW_ENABLE, false);
198 }
199
is_stopped_mp(struct rkisp_bridge_device * dev)200 static bool is_stopped_mp(struct rkisp_bridge_device *dev)
201 {
202 bool en = true;
203
204 if (dev->ispdev->hw_dev->is_single)
205 en = mp_is_stream_stopped(dev->ispdev->base_addr);
206 return en;
207 }
208
209 static struct rkisp_bridge_ops mp_ops = {
210 .config = config_mp,
211 .disable = disable_mp,
212 .is_stopped = is_stopped_mp,
213 .frame_end = bridge_frame_end,
214 .update_mi = bridge_update_mi,
215 .start = bridge_start,
216 .stop = bridge_stop,
217 };
218
219 static struct rkisp_bridge_config mp_cfg = {
220 .frame_end_id = MI_MP_FRAME,
221 .reg = {
222 .y0_base = MI_MP_WR_Y_BASE,
223 .uv0_base = MI_MP_WR_CB_BASE,
224 .y1_base = MI_MP_WR_Y_BASE2,
225 .uv1_base = MI_MP_WR_CB_BASE2,
226
227 .y0_base_shd = MI_MP_WR_Y_BASE_SHD,
228 .uv0_base_shd = MI_MP_WR_CB_BASE_SHD,
229 },
230 };
231
rkisp_bridge_init_ops_v30(struct rkisp_bridge_device * dev)232 void rkisp_bridge_init_ops_v30(struct rkisp_bridge_device *dev)
233 {
234 dev->ops = &mp_ops;
235 dev->cfg = &mp_cfg;
236 }
237