1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Rockchip isp1 driver
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * This software is available to you under a choice of one of two
7*4882a593Smuzhiyun * licenses. You may choose to be licensed under the terms of the GNU
8*4882a593Smuzhiyun * General Public License (GPL) Version 2, available from the file
9*4882a593Smuzhiyun * COPYING in the main directory of this source tree, or the
10*4882a593Smuzhiyun * OpenIB.org BSD license below:
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun * Redistribution and use in source and binary forms, with or
13*4882a593Smuzhiyun * without modification, are permitted provided that the following
14*4882a593Smuzhiyun * conditions are met:
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun * - Redistributions of source code must retain the above
17*4882a593Smuzhiyun * copyright notice, this list of conditions and the following
18*4882a593Smuzhiyun * disclaimer.
19*4882a593Smuzhiyun *
20*4882a593Smuzhiyun * - Redistributions in binary form must reproduce the above
21*4882a593Smuzhiyun * copyright notice, this list of conditions and the following
22*4882a593Smuzhiyun * disclaimer in the documentation and/or other materials
23*4882a593Smuzhiyun * provided with the distribution.
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26*4882a593Smuzhiyun * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27*4882a593Smuzhiyun * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28*4882a593Smuzhiyun * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29*4882a593Smuzhiyun * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30*4882a593Smuzhiyun * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31*4882a593Smuzhiyun * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32*4882a593Smuzhiyun * SOFTWARE.
33*4882a593Smuzhiyun */
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun #include <linux/clk.h>
36*4882a593Smuzhiyun #include <linux/interrupt.h>
37*4882a593Smuzhiyun #include <linux/io.h>
38*4882a593Smuzhiyun #include <linux/module.h>
39*4882a593Smuzhiyun #include <linux/of.h>
40*4882a593Smuzhiyun #include <linux/of_address.h>
41*4882a593Smuzhiyun #include <linux/of_gpio.h>
42*4882a593Smuzhiyun #include <linux/of_graph.h>
43*4882a593Smuzhiyun #include <linux/of_platform.h>
44*4882a593Smuzhiyun #include <linux/of_reserved_mem.h>
45*4882a593Smuzhiyun #include <linux/pm_runtime.h>
46*4882a593Smuzhiyun #include <linux/pinctrl/consumer.h>
47*4882a593Smuzhiyun #include <linux/regmap.h>
48*4882a593Smuzhiyun #include <dt-bindings/soc/rockchip-system-status.h>
49*4882a593Smuzhiyun #include <soc/rockchip/rockchip-system-status.h>
50*4882a593Smuzhiyun #include "common.h"
51*4882a593Smuzhiyun #include "isp_ispp.h"
52*4882a593Smuzhiyun #include "regs.h"
53*4882a593Smuzhiyun #include "rkisp.h"
54*4882a593Smuzhiyun #include "version.h"
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun #define RKISP_VERNO_LEN 10
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun int rkisp_debug;
59*4882a593Smuzhiyun module_param_named(debug, rkisp_debug, int, 0644);
60*4882a593Smuzhiyun MODULE_PARM_DESC(debug, "Debug level (0-1)");
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun bool rkisp_monitor;
63*4882a593Smuzhiyun module_param_named(monitor, rkisp_monitor, bool, 0644);
64*4882a593Smuzhiyun MODULE_PARM_DESC(monitor, "rkisp abnormal restart monitor");
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun bool rkisp_irq_dbg;
67*4882a593Smuzhiyun module_param_named(irq_dbg, rkisp_irq_dbg, bool, 0644);
68*4882a593Smuzhiyun MODULE_PARM_DESC(irq_dbg, "rkisp interrupt runtime");
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun static bool rkisp_rdbk_auto;
71*4882a593Smuzhiyun module_param_named(rdbk_auto, rkisp_rdbk_auto, bool, 0644);
72*4882a593Smuzhiyun MODULE_PARM_DESC(irq_dbg, "rkisp and vicap auto readback mode");
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun static bool rkisp_clk_dbg;
75*4882a593Smuzhiyun module_param_named(clk_dbg, rkisp_clk_dbg, bool, 0644);
76*4882a593Smuzhiyun MODULE_PARM_DESC(clk_dbg, "rkisp clk set by user");
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun static char rkisp_version[RKISP_VERNO_LEN];
79*4882a593Smuzhiyun module_param_string(version, rkisp_version, RKISP_VERNO_LEN, 0444);
80*4882a593Smuzhiyun MODULE_PARM_DESC(version, "version number");
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun u64 rkisp_debug_reg = 0xFFFFFFFFFLL;
83*4882a593Smuzhiyun module_param_named(debug_reg, rkisp_debug_reg, ullong, 0644);
84*4882a593Smuzhiyun MODULE_PARM_DESC(debug_reg, "rkisp debug register");
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun static unsigned int rkisp_wait_line;
87*4882a593Smuzhiyun module_param_named(wait_line, rkisp_wait_line, uint, 0644);
88*4882a593Smuzhiyun MODULE_PARM_DESC(wait_line, "rkisp wait line to buf done early");
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun static unsigned int rkisp_wrap_line;
91*4882a593Smuzhiyun module_param_named(wrap_line, rkisp_wrap_line, uint, 0644);
92*4882a593Smuzhiyun MODULE_PARM_DESC(wrap_line, "rkisp wrap line for mpp");
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun static DEFINE_MUTEX(rkisp_dev_mutex);
95*4882a593Smuzhiyun static LIST_HEAD(rkisp_device_list);
96*4882a593Smuzhiyun
rkisp_set_clk_rate(struct clk * clk,unsigned long rate)97*4882a593Smuzhiyun void rkisp_set_clk_rate(struct clk *clk, unsigned long rate)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun if (rkisp_clk_dbg)
100*4882a593Smuzhiyun return;
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun clk_set_rate(clk, rate);
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun
__rkisp_clr_unready_dev(void)105*4882a593Smuzhiyun static int __maybe_unused __rkisp_clr_unready_dev(void)
106*4882a593Smuzhiyun {
107*4882a593Smuzhiyun struct rkisp_device *isp_dev;
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun mutex_lock(&rkisp_dev_mutex);
110*4882a593Smuzhiyun list_for_each_entry(isp_dev, &rkisp_device_list, list)
111*4882a593Smuzhiyun v4l2_async_notifier_clr_unready_dev(&isp_dev->notifier);
112*4882a593Smuzhiyun mutex_unlock(&rkisp_dev_mutex);
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun return 0;
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun
rkisp_clr_unready_dev_param_set(const char * val,const struct kernel_param * kp)117*4882a593Smuzhiyun static int rkisp_clr_unready_dev_param_set(const char *val, const struct kernel_param *kp)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun #ifdef MODULE
120*4882a593Smuzhiyun __rkisp_clr_unready_dev();
121*4882a593Smuzhiyun #endif
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun return 0;
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun module_param_call(clr_unready_dev, rkisp_clr_unready_dev_param_set, NULL, NULL, 0200);
127*4882a593Smuzhiyun MODULE_PARM_DESC(clr_unready_dev, "clear unready devices");
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun /**************************** pipeline operations *****************************/
130*4882a593Smuzhiyun
__isp_pipeline_prepare(struct rkisp_pipeline * p,struct media_entity * me)131*4882a593Smuzhiyun static int __isp_pipeline_prepare(struct rkisp_pipeline *p,
132*4882a593Smuzhiyun struct media_entity *me)
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun struct rkisp_device *dev = container_of(p, struct rkisp_device, pipe);
135*4882a593Smuzhiyun struct v4l2_subdev *sd;
136*4882a593Smuzhiyun int i;
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun p->num_subdevs = 0;
139*4882a593Smuzhiyun memset(p->subdevs, 0, sizeof(p->subdevs));
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun if (!(dev->isp_inp & (INP_CSI | INP_DVP | INP_LVDS | INP_CIF)))
142*4882a593Smuzhiyun return 0;
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun while (1) {
145*4882a593Smuzhiyun struct media_pad *pad = NULL;
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun /* Find remote source pad */
148*4882a593Smuzhiyun for (i = 0; i < me->num_pads; i++) {
149*4882a593Smuzhiyun struct media_pad *spad = &me->pads[i];
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun if (!(spad->flags & MEDIA_PAD_FL_SINK))
152*4882a593Smuzhiyun continue;
153*4882a593Smuzhiyun pad = rkisp_media_entity_remote_pad(spad);
154*4882a593Smuzhiyun if (pad)
155*4882a593Smuzhiyun break;
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun if (!pad)
159*4882a593Smuzhiyun break;
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun sd = media_entity_to_v4l2_subdev(pad->entity);
162*4882a593Smuzhiyun if (sd != &dev->isp_sdev.sd)
163*4882a593Smuzhiyun p->subdevs[p->num_subdevs++] = sd;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun me = &sd->entity;
166*4882a593Smuzhiyun if (me->num_pads == 1)
167*4882a593Smuzhiyun break;
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun if (!p->num_subdevs)
170*4882a593Smuzhiyun return -EINVAL;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun return 0;
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun
__isp_pipeline_s_isp_clk(struct rkisp_pipeline * p)175*4882a593Smuzhiyun static int __isp_pipeline_s_isp_clk(struct rkisp_pipeline *p)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun struct rkisp_device *dev = container_of(p, struct rkisp_device, pipe);
178*4882a593Smuzhiyun struct rkisp_hw_dev *hw_dev = dev->hw_dev;
179*4882a593Smuzhiyun struct v4l2_subdev *sd;
180*4882a593Smuzhiyun struct v4l2_ctrl *ctrl;
181*4882a593Smuzhiyun u64 data_rate = 0;
182*4882a593Smuzhiyun int i, fps;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun hw_dev->isp_size[dev->dev_id].is_on = true;
185*4882a593Smuzhiyun if (hw_dev->is_runing) {
186*4882a593Smuzhiyun if (dev->isp_ver >= ISP_V30 && !rkisp_clk_dbg)
187*4882a593Smuzhiyun hw_dev->is_dvfs = true;
188*4882a593Smuzhiyun return 0;
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun if (dev->isp_inp & (INP_RAWRD0 | INP_RAWRD1 | INP_RAWRD2) ||
192*4882a593Smuzhiyun (dev->is_pre_on && hw_dev->dev_num > 1)) {
193*4882a593Smuzhiyun if (dev->isp_ver < ISP_V30 || dev->is_pre_on) {
194*4882a593Smuzhiyun /* isp with mipi no support dvfs, calculate max data rate */
195*4882a593Smuzhiyun for (i = 0; i < hw_dev->dev_num; i++) {
196*4882a593Smuzhiyun fps = hw_dev->isp_size[i].fps;
197*4882a593Smuzhiyun if (!fps)
198*4882a593Smuzhiyun fps = 30;
199*4882a593Smuzhiyun data_rate += (fps * hw_dev->isp_size[i].size);
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun } else {
202*4882a593Smuzhiyun i = dev->dev_id;
203*4882a593Smuzhiyun fps = hw_dev->isp_size[i].fps;
204*4882a593Smuzhiyun if (!fps)
205*4882a593Smuzhiyun fps = 30;
206*4882a593Smuzhiyun data_rate = fps * hw_dev->isp_size[i].size;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun goto end;
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun if (dev->isp_inp == INP_DMARX_ISP && dev->hw_dev->clks[0]) {
212*4882a593Smuzhiyun rkisp_set_clk_rate(hw_dev->clks[0], 400 * 1000000UL);
213*4882a593Smuzhiyun return 0;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun /* find the subdev of active sensor or vicap itf */
217*4882a593Smuzhiyun sd = p->subdevs[0];
218*4882a593Smuzhiyun for (i = 0; i < p->num_subdevs; i++) {
219*4882a593Smuzhiyun sd = p->subdevs[i];
220*4882a593Smuzhiyun if (sd->entity.function == MEDIA_ENT_F_CAM_SENSOR ||
221*4882a593Smuzhiyun sd->entity.function == MEDIA_ENT_F_PROC_VIDEO_COMPOSER)
222*4882a593Smuzhiyun break;
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun if (i == p->num_subdevs) {
226*4882a593Smuzhiyun v4l2_warn(&dev->v4l2_dev, "No active sensor\n");
227*4882a593Smuzhiyun return -EPIPE;
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun ctrl = v4l2_ctrl_find(sd->ctrl_handler, V4L2_CID_PIXEL_RATE);
231*4882a593Smuzhiyun if (!ctrl) {
232*4882a593Smuzhiyun v4l2_warn(&dev->v4l2_dev, "No pixel rate control in subdev\n");
233*4882a593Smuzhiyun return -EPIPE;
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun /* calculate data rate */
237*4882a593Smuzhiyun data_rate = v4l2_ctrl_g_ctrl_int64(ctrl) *
238*4882a593Smuzhiyun dev->isp_sdev.in_fmt.bus_width;
239*4882a593Smuzhiyun data_rate >>= 3;
240*4882a593Smuzhiyun end:
241*4882a593Smuzhiyun do_div(data_rate, 1000 * 1000);
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun /* increase 25% margin */
244*4882a593Smuzhiyun data_rate += data_rate >> 2;
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun /* compare with isp clock adjustment table */
247*4882a593Smuzhiyun for (i = 0; i < hw_dev->num_clk_rate_tbl; i++)
248*4882a593Smuzhiyun if (data_rate <= hw_dev->clk_rate_tbl[i].clk_rate)
249*4882a593Smuzhiyun break;
250*4882a593Smuzhiyun if (i == hw_dev->num_clk_rate_tbl)
251*4882a593Smuzhiyun i--;
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun /* set isp clock rate */
254*4882a593Smuzhiyun rkisp_set_clk_rate(hw_dev->clks[0], hw_dev->clk_rate_tbl[i].clk_rate * 1000000UL);
255*4882a593Smuzhiyun if (hw_dev->is_unite)
256*4882a593Smuzhiyun rkisp_set_clk_rate(hw_dev->clks[5], hw_dev->clk_rate_tbl[i].clk_rate * 1000000UL);
257*4882a593Smuzhiyun /* aclk equal to core clk */
258*4882a593Smuzhiyun if (dev->isp_ver == ISP_V32)
259*4882a593Smuzhiyun rkisp_set_clk_rate(hw_dev->clks[1], hw_dev->clk_rate_tbl[i].clk_rate * 1000000UL);
260*4882a593Smuzhiyun dev_info(hw_dev->dev, "set isp clk = %luHz\n", clk_get_rate(hw_dev->clks[0]));
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun return 0;
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun
rkisp_pipeline_open(struct rkisp_pipeline * p,struct media_entity * me,bool prepare)265*4882a593Smuzhiyun static int rkisp_pipeline_open(struct rkisp_pipeline *p,
266*4882a593Smuzhiyun struct media_entity *me,
267*4882a593Smuzhiyun bool prepare)
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun int ret;
270*4882a593Smuzhiyun struct rkisp_device *dev = container_of(p, struct rkisp_device, pipe);
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun if (WARN_ON(!p || !me))
273*4882a593Smuzhiyun return -EINVAL;
274*4882a593Smuzhiyun if (atomic_inc_return(&p->power_cnt) > 1)
275*4882a593Smuzhiyun return 0;
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun /* go through media graphic and get subdevs */
278*4882a593Smuzhiyun if (prepare) {
279*4882a593Smuzhiyun ret = __isp_pipeline_prepare(p, me);
280*4882a593Smuzhiyun if (ret < 0)
281*4882a593Smuzhiyun return ret;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun ret = __isp_pipeline_s_isp_clk(p);
285*4882a593Smuzhiyun if (ret < 0)
286*4882a593Smuzhiyun return ret;
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun if (dev->isp_inp & (INP_CSI | INP_RAWRD0 | INP_RAWRD1 | INP_RAWRD2 | INP_CIF))
289*4882a593Smuzhiyun rkisp_csi_config_patch(dev);
290*4882a593Smuzhiyun return 0;
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun
rkisp_pipeline_close(struct rkisp_pipeline * p)293*4882a593Smuzhiyun static int rkisp_pipeline_close(struct rkisp_pipeline *p)
294*4882a593Smuzhiyun {
295*4882a593Smuzhiyun struct rkisp_device *dev = container_of(p, struct rkisp_device, pipe);
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun if (atomic_dec_return(&p->power_cnt))
298*4882a593Smuzhiyun return 0;
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun rkisp_rx_buf_pool_free(dev);
301*4882a593Smuzhiyun dev->hw_dev->isp_size[dev->dev_id].is_on = false;
302*4882a593Smuzhiyun if (dev->hw_dev->is_runing && (dev->isp_ver >= ISP_V30) && !rkisp_clk_dbg)
303*4882a593Smuzhiyun dev->hw_dev->is_dvfs = true;
304*4882a593Smuzhiyun return 0;
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun /*
308*4882a593Smuzhiyun * stream-on order: isp_subdev, mipi dphy, sensor
309*4882a593Smuzhiyun * stream-off order: mipi dphy, sensor, isp_subdev
310*4882a593Smuzhiyun */
rkisp_pipeline_set_stream(struct rkisp_pipeline * p,bool on)311*4882a593Smuzhiyun static int rkisp_pipeline_set_stream(struct rkisp_pipeline *p, bool on)
312*4882a593Smuzhiyun {
313*4882a593Smuzhiyun struct rkisp_device *dev = container_of(p, struct rkisp_device, pipe);
314*4882a593Smuzhiyun int i, ret;
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun if ((on && atomic_inc_return(&p->stream_cnt) > 1) ||
317*4882a593Smuzhiyun (!on && atomic_dec_return(&p->stream_cnt) > 0))
318*4882a593Smuzhiyun return 0;
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun if (on) {
321*4882a593Smuzhiyun if (dev->vs_irq >= 0)
322*4882a593Smuzhiyun enable_irq(dev->vs_irq);
323*4882a593Smuzhiyun rockchip_set_system_status(SYS_STATUS_ISP);
324*4882a593Smuzhiyun ret = v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream, true);
325*4882a593Smuzhiyun if (ret < 0)
326*4882a593Smuzhiyun goto err;
327*4882a593Smuzhiyun /* phy -> sensor */
328*4882a593Smuzhiyun for (i = 0; i < p->num_subdevs; ++i) {
329*4882a593Smuzhiyun if ((dev->vicap_in.merge_num > 1) &&
330*4882a593Smuzhiyun (p->subdevs[i]->entity.function == MEDIA_ENT_F_CAM_SENSOR))
331*4882a593Smuzhiyun continue;
332*4882a593Smuzhiyun ret = v4l2_subdev_call(p->subdevs[i], video, s_stream, on);
333*4882a593Smuzhiyun if (on && ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
334*4882a593Smuzhiyun goto err_stream_off;
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun } else {
337*4882a593Smuzhiyun if (dev->hw_dev->monitor.is_en) {
338*4882a593Smuzhiyun dev->hw_dev->monitor.is_en = 0;
339*4882a593Smuzhiyun dev->hw_dev->monitor.state = ISP_STOP;
340*4882a593Smuzhiyun if (!completion_done(&dev->hw_dev->monitor.cmpl))
341*4882a593Smuzhiyun complete(&dev->hw_dev->monitor.cmpl);
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun /* sensor -> phy */
344*4882a593Smuzhiyun for (i = p->num_subdevs - 1; i >= 0; --i) {
345*4882a593Smuzhiyun if ((dev->vicap_in.merge_num > 1) &&
346*4882a593Smuzhiyun (p->subdevs[i]->entity.function == MEDIA_ENT_F_CAM_SENSOR))
347*4882a593Smuzhiyun continue;
348*4882a593Smuzhiyun v4l2_subdev_call(p->subdevs[i], video, s_stream, on);
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun if (dev->vs_irq >= 0)
351*4882a593Smuzhiyun disable_irq(dev->vs_irq);
352*4882a593Smuzhiyun v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream, false);
353*4882a593Smuzhiyun rockchip_clear_system_status(SYS_STATUS_ISP);
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun return 0;
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun err_stream_off:
359*4882a593Smuzhiyun for (--i; i >= 0; --i)
360*4882a593Smuzhiyun v4l2_subdev_call(p->subdevs[i], video, s_stream, false);
361*4882a593Smuzhiyun v4l2_subdev_call(&dev->isp_sdev.sd, video, s_stream, false);
362*4882a593Smuzhiyun err:
363*4882a593Smuzhiyun rockchip_clear_system_status(SYS_STATUS_ISP);
364*4882a593Smuzhiyun atomic_dec_return(&p->stream_cnt);
365*4882a593Smuzhiyun return ret;
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun /***************************** media controller *******************************/
369*4882a593Smuzhiyun /* See http://opensource.rock-chips.com/wiki_Rockchip-isp1 for Topology */
370*4882a593Smuzhiyun
rkisp_create_links(struct rkisp_device * dev)371*4882a593Smuzhiyun static int rkisp_create_links(struct rkisp_device *dev)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun unsigned int s, pad;
374*4882a593Smuzhiyun int ret = 0;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun /* sensor links(or mipi-phy) */
377*4882a593Smuzhiyun for (s = 0; s < dev->num_sensors; ++s) {
378*4882a593Smuzhiyun struct rkisp_sensor_info *sensor = &dev->sensors[s];
379*4882a593Smuzhiyun u32 type = sensor->sd->entity.function;
380*4882a593Smuzhiyun bool en = s ? 0 : true;
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun for (pad = 0; pad < sensor->sd->entity.num_pads; pad++)
383*4882a593Smuzhiyun if (sensor->sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE)
384*4882a593Smuzhiyun break;
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun if (pad == sensor->sd->entity.num_pads) {
387*4882a593Smuzhiyun dev_err(dev->dev, "failed to find src pad for %s\n",
388*4882a593Smuzhiyun sensor->sd->name);
389*4882a593Smuzhiyun return -ENXIO;
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun /* sensor link -> isp */
393*4882a593Smuzhiyun if (type == MEDIA_ENT_F_CAM_SENSOR) {
394*4882a593Smuzhiyun dev->isp_inp = INP_DVP;
395*4882a593Smuzhiyun ret = media_create_pad_link(&sensor->sd->entity, pad,
396*4882a593Smuzhiyun &dev->isp_sdev.sd.entity, RKISP_ISP_PAD_SINK, en);
397*4882a593Smuzhiyun } else if (type == MEDIA_ENT_F_PROC_VIDEO_COMPOSER) {
398*4882a593Smuzhiyun dev->isp_inp = INP_CIF;
399*4882a593Smuzhiyun ret = media_create_pad_link(&sensor->sd->entity, pad,
400*4882a593Smuzhiyun &dev->isp_sdev.sd.entity, RKISP_ISP_PAD_SINK, en);
401*4882a593Smuzhiyun } else {
402*4882a593Smuzhiyun v4l2_subdev_call(sensor->sd, pad,
403*4882a593Smuzhiyun get_mbus_config, 0, &sensor->mbus);
404*4882a593Smuzhiyun if (sensor->mbus.type == V4L2_MBUS_CCP2) {
405*4882a593Smuzhiyun /* mipi-phy lvds link -> isp */
406*4882a593Smuzhiyun dev->isp_inp = INP_LVDS;
407*4882a593Smuzhiyun ret = media_create_pad_link(&sensor->sd->entity, pad,
408*4882a593Smuzhiyun &dev->isp_sdev.sd.entity, RKISP_ISP_PAD_SINK, en);
409*4882a593Smuzhiyun } else {
410*4882a593Smuzhiyun /* mipi-phy link -> csi -> isp */
411*4882a593Smuzhiyun dev->isp_inp = INP_CSI;
412*4882a593Smuzhiyun ret = media_create_pad_link(&sensor->sd->entity,
413*4882a593Smuzhiyun pad, &dev->csi_dev.sd.entity, CSI_SINK, en);
414*4882a593Smuzhiyun ret |= media_create_pad_link(&dev->csi_dev.sd.entity, CSI_SRC_CH0,
415*4882a593Smuzhiyun &dev->isp_sdev.sd.entity, RKISP_ISP_PAD_SINK, en);
416*4882a593Smuzhiyun dev->csi_dev.sink[0].linked = en;
417*4882a593Smuzhiyun dev->csi_dev.sink[0].index = BIT(0);
418*4882a593Smuzhiyun }
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun if (ret)
421*4882a593Smuzhiyun dev_err(dev->dev, "failed to create link for %s\n", sensor->sd->name);
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun return ret;
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun
_set_pipeline_default_fmt(struct rkisp_device * dev,bool is_init)426*4882a593Smuzhiyun static int _set_pipeline_default_fmt(struct rkisp_device *dev, bool is_init)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun struct v4l2_subdev *isp;
429*4882a593Smuzhiyun struct v4l2_subdev_format fmt;
430*4882a593Smuzhiyun struct v4l2_subdev_selection sel;
431*4882a593Smuzhiyun u32 i, width, height, code;
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun memset(&sel, 0, sizeof(sel));
434*4882a593Smuzhiyun memset(&fmt, 0, sizeof(fmt));
435*4882a593Smuzhiyun isp = &dev->isp_sdev.sd;
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun if (dev->active_sensor) {
438*4882a593Smuzhiyun fmt = dev->active_sensor->fmt[0];
439*4882a593Smuzhiyun if (!is_init &&
440*4882a593Smuzhiyun fmt.format.code == dev->isp_sdev.in_frm.code &&
441*4882a593Smuzhiyun fmt.format.width == dev->isp_sdev.in_frm.width &&
442*4882a593Smuzhiyun fmt.format.height == dev->isp_sdev.in_frm.height)
443*4882a593Smuzhiyun return 0;
444*4882a593Smuzhiyun } else {
445*4882a593Smuzhiyun fmt.format = dev->isp_sdev.in_frm;
446*4882a593Smuzhiyun }
447*4882a593Smuzhiyun code = fmt.format.code;
448*4882a593Smuzhiyun fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
449*4882a593Smuzhiyun fmt.pad = RKISP_ISP_PAD_SINK;
450*4882a593Smuzhiyun /* isp input format information from sensor */
451*4882a593Smuzhiyun v4l2_subdev_call(isp, pad, set_fmt, NULL, &fmt);
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun rkisp_align_sensor_resolution(dev, &sel.r, false);
454*4882a593Smuzhiyun width = sel.r.width;
455*4882a593Smuzhiyun height = sel.r.height;
456*4882a593Smuzhiyun sel.target = V4L2_SEL_TGT_CROP;
457*4882a593Smuzhiyun sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
458*4882a593Smuzhiyun sel.pad = RKISP_ISP_PAD_SINK;
459*4882a593Smuzhiyun /* image resolution processed by isp */
460*4882a593Smuzhiyun v4l2_subdev_call(isp, pad, set_selection, NULL, &sel);
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun /* change fmt&size for RKISP_ISP_PAD_SOURCE_PATH */
463*4882a593Smuzhiyun if ((code & RKISP_MEDIA_BUS_FMT_MASK) == RKISP_MEDIA_BUS_FMT_BAYER)
464*4882a593Smuzhiyun fmt.format.code = MEDIA_BUS_FMT_YUYV8_2X8;
465*4882a593Smuzhiyun
466*4882a593Smuzhiyun sel.r.left = 0;
467*4882a593Smuzhiyun sel.r.top = 0;
468*4882a593Smuzhiyun fmt.format.width = width;
469*4882a593Smuzhiyun fmt.format.height = height;
470*4882a593Smuzhiyun fmt.pad = RKISP_ISP_PAD_SOURCE_PATH;
471*4882a593Smuzhiyun sel.pad = RKISP_ISP_PAD_SOURCE_PATH;
472*4882a593Smuzhiyun v4l2_subdev_call(isp, pad, set_fmt, NULL, &fmt);
473*4882a593Smuzhiyun v4l2_subdev_call(isp, pad, set_selection, NULL, &sel);
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun /* change fmt&size of MP/SP */
476*4882a593Smuzhiyun rkisp_set_stream_def_fmt(dev, RKISP_STREAM_MP,
477*4882a593Smuzhiyun width, height, V4L2_PIX_FMT_NV12);
478*4882a593Smuzhiyun if (dev->isp_ver != ISP_V10_1)
479*4882a593Smuzhiyun rkisp_set_stream_def_fmt(dev, RKISP_STREAM_SP,
480*4882a593Smuzhiyun width, height, V4L2_PIX_FMT_NV12);
481*4882a593Smuzhiyun if ((dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) &&
482*4882a593Smuzhiyun dev->isp_inp == INP_CSI && dev->active_sensor) {
483*4882a593Smuzhiyun width = dev->active_sensor->fmt[1].format.width;
484*4882a593Smuzhiyun height = dev->active_sensor->fmt[1].format.height;
485*4882a593Smuzhiyun code = dev->active_sensor->fmt[1].format.code;
486*4882a593Smuzhiyun rkisp_set_stream_def_fmt(dev, RKISP_STREAM_DMATX0,
487*4882a593Smuzhiyun width, height, rkisp_mbus_pixelcode_to_v4l2(code));
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun width = dev->active_sensor->fmt[3].format.width;
490*4882a593Smuzhiyun height = dev->active_sensor->fmt[3].format.height;
491*4882a593Smuzhiyun code = dev->active_sensor->fmt[3].format.code;
492*4882a593Smuzhiyun rkisp_set_stream_def_fmt(dev, RKISP_STREAM_DMATX2,
493*4882a593Smuzhiyun width, height, rkisp_mbus_pixelcode_to_v4l2(code));
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun width = dev->active_sensor->fmt[4].format.width;
496*4882a593Smuzhiyun height = dev->active_sensor->fmt[4].format.height;
497*4882a593Smuzhiyun code = dev->active_sensor->fmt[4].format.code;
498*4882a593Smuzhiyun rkisp_set_stream_def_fmt(dev, RKISP_STREAM_DMATX3,
499*4882a593Smuzhiyun width, height, rkisp_mbus_pixelcode_to_v4l2(code));
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun if (dev->isp_ver == ISP_V20 &&
503*4882a593Smuzhiyun dev->isp_inp == INP_CSI && dev->active_sensor) {
504*4882a593Smuzhiyun width = dev->active_sensor->fmt[2].format.width;
505*4882a593Smuzhiyun height = dev->active_sensor->fmt[2].format.height;
506*4882a593Smuzhiyun code = dev->active_sensor->fmt[2].format.code;
507*4882a593Smuzhiyun rkisp_set_stream_def_fmt(dev, RKISP_STREAM_DMATX1,
508*4882a593Smuzhiyun width, height, rkisp_mbus_pixelcode_to_v4l2(code));
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun if (dev->isp_ver == ISP_V30) {
512*4882a593Smuzhiyun struct v4l2_pix_format_mplane pixm = {
513*4882a593Smuzhiyun .width = width,
514*4882a593Smuzhiyun .height = height,
515*4882a593Smuzhiyun .pixelformat = rkisp_mbus_pixelcode_to_v4l2(code),
516*4882a593Smuzhiyun };
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun for (i = RKISP_STREAM_RAWRD0; i <= RKISP_STREAM_RAWRD2; i++)
519*4882a593Smuzhiyun rkisp_dmarx_set_fmt(&dev->dmarx_dev.stream[i], pixm);
520*4882a593Smuzhiyun rkisp_set_stream_def_fmt(dev, RKISP_STREAM_FBC,
521*4882a593Smuzhiyun width, height, V4L2_PIX_FMT_FBC0);
522*4882a593Smuzhiyun #ifdef RKISP_STREAM_BP_EN
523*4882a593Smuzhiyun rkisp_set_stream_def_fmt(dev, RKISP_STREAM_BP,
524*4882a593Smuzhiyun width, height, V4L2_PIX_FMT_NV12);
525*4882a593Smuzhiyun #endif
526*4882a593Smuzhiyun }
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun if (dev->isp_ver == ISP_V32 || dev->isp_ver == ISP_V32_L) {
529*4882a593Smuzhiyun struct v4l2_pix_format_mplane pixm = {
530*4882a593Smuzhiyun .width = width,
531*4882a593Smuzhiyun .height = height,
532*4882a593Smuzhiyun .pixelformat = rkisp_mbus_pixelcode_to_v4l2(code),
533*4882a593Smuzhiyun };
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun rkisp_dmarx_set_fmt(&dev->dmarx_dev.stream[RKISP_STREAM_RAWRD0], pixm);
536*4882a593Smuzhiyun rkisp_dmarx_set_fmt(&dev->dmarx_dev.stream[RKISP_STREAM_RAWRD2], pixm);
537*4882a593Smuzhiyun if (dev->isp_ver == ISP_V32) {
538*4882a593Smuzhiyun rkisp_set_stream_def_fmt(dev, RKISP_STREAM_BP,
539*4882a593Smuzhiyun width, height, V4L2_PIX_FMT_NV12);
540*4882a593Smuzhiyun rkisp_set_stream_def_fmt(dev, RKISP_STREAM_MPDS,
541*4882a593Smuzhiyun width / 4, height / 4, V4L2_PIX_FMT_NV12);
542*4882a593Smuzhiyun rkisp_set_stream_def_fmt(dev, RKISP_STREAM_BPDS,
543*4882a593Smuzhiyun width / 4, height / 4, V4L2_PIX_FMT_NV12);
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun return 0;
547*4882a593Smuzhiyun }
548*4882a593Smuzhiyun
subdev_notifier_complete(struct v4l2_async_notifier * notifier)549*4882a593Smuzhiyun static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
550*4882a593Smuzhiyun {
551*4882a593Smuzhiyun struct rkisp_device *dev;
552*4882a593Smuzhiyun int ret;
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun dev = container_of(notifier, struct rkisp_device, notifier);
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun mutex_lock(&dev->media_dev.graph_mutex);
557*4882a593Smuzhiyun ret = rkisp_create_links(dev);
558*4882a593Smuzhiyun if (ret < 0)
559*4882a593Smuzhiyun goto unlock;
560*4882a593Smuzhiyun ret = v4l2_device_register_subdev_nodes(&dev->v4l2_dev);
561*4882a593Smuzhiyun if (ret < 0)
562*4882a593Smuzhiyun goto unlock;
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun if (dev->isp_inp) {
565*4882a593Smuzhiyun ret = rkisp_update_sensor_info(dev);
566*4882a593Smuzhiyun if (ret < 0) {
567*4882a593Smuzhiyun v4l2_err(&dev->v4l2_dev, "update sensor failed\n");
568*4882a593Smuzhiyun goto unlock;
569*4882a593Smuzhiyun }
570*4882a593Smuzhiyun dev->is_hw_link = true;
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun ret = _set_pipeline_default_fmt(dev, true);
574*4882a593Smuzhiyun if (ret < 0)
575*4882a593Smuzhiyun goto unlock;
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun v4l2_info(&dev->v4l2_dev, "Async subdev notifier completed\n");
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun unlock:
580*4882a593Smuzhiyun mutex_unlock(&dev->media_dev.graph_mutex);
581*4882a593Smuzhiyun if (!ret && dev->is_thunderboot)
582*4882a593Smuzhiyun schedule_work(&dev->cap_dev.fast_work);
583*4882a593Smuzhiyun return ret;
584*4882a593Smuzhiyun }
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun struct rkisp_async_subdev {
587*4882a593Smuzhiyun struct v4l2_async_subdev asd;
588*4882a593Smuzhiyun struct v4l2_mbus_config mbus;
589*4882a593Smuzhiyun };
590*4882a593Smuzhiyun
subdev_notifier_bound(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)591*4882a593Smuzhiyun static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
592*4882a593Smuzhiyun struct v4l2_subdev *subdev,
593*4882a593Smuzhiyun struct v4l2_async_subdev *asd)
594*4882a593Smuzhiyun {
595*4882a593Smuzhiyun struct rkisp_device *isp_dev = container_of(notifier,
596*4882a593Smuzhiyun struct rkisp_device, notifier);
597*4882a593Smuzhiyun struct rkisp_async_subdev *s_asd = container_of(asd,
598*4882a593Smuzhiyun struct rkisp_async_subdev, asd);
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun if (isp_dev->num_sensors == ARRAY_SIZE(isp_dev->sensors))
601*4882a593Smuzhiyun return -EBUSY;
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun isp_dev->sensors[isp_dev->num_sensors].mbus = s_asd->mbus;
604*4882a593Smuzhiyun isp_dev->sensors[isp_dev->num_sensors].sd = subdev;
605*4882a593Smuzhiyun ++isp_dev->num_sensors;
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun v4l2_dbg(1, rkisp_debug, subdev, "Async registered subdev\n");
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun return 0;
610*4882a593Smuzhiyun }
611*4882a593Smuzhiyun
rkisp_fwnode_parse(struct device * dev,struct v4l2_fwnode_endpoint * vep,struct v4l2_async_subdev * asd)612*4882a593Smuzhiyun static int rkisp_fwnode_parse(struct device *dev,
613*4882a593Smuzhiyun struct v4l2_fwnode_endpoint *vep,
614*4882a593Smuzhiyun struct v4l2_async_subdev *asd)
615*4882a593Smuzhiyun {
616*4882a593Smuzhiyun struct rkisp_async_subdev *rk_asd =
617*4882a593Smuzhiyun container_of(asd, struct rkisp_async_subdev, asd);
618*4882a593Smuzhiyun struct v4l2_fwnode_bus_parallel *bus = &vep->bus.parallel;
619*4882a593Smuzhiyun
620*4882a593Smuzhiyun /*
621*4882a593Smuzhiyun * MIPI sensor is linked with a mipi dphy and its media bus config can
622*4882a593Smuzhiyun * not be get in here
623*4882a593Smuzhiyun */
624*4882a593Smuzhiyun if (vep->bus_type != V4L2_MBUS_BT656 &&
625*4882a593Smuzhiyun vep->bus_type != V4L2_MBUS_PARALLEL)
626*4882a593Smuzhiyun return 0;
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun rk_asd->mbus.flags = bus->flags;
629*4882a593Smuzhiyun rk_asd->mbus.type = vep->bus_type;
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun return 0;
632*4882a593Smuzhiyun }
633*4882a593Smuzhiyun
subdev_notifier_unbind(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)634*4882a593Smuzhiyun static void subdev_notifier_unbind(struct v4l2_async_notifier *notifier,
635*4882a593Smuzhiyun struct v4l2_subdev *subdev,
636*4882a593Smuzhiyun struct v4l2_async_subdev *asd)
637*4882a593Smuzhiyun {
638*4882a593Smuzhiyun struct rkisp_device *isp_dev = container_of(notifier, struct rkisp_device, notifier);
639*4882a593Smuzhiyun struct rkisp_isp_subdev *isp_sdev = &isp_dev->isp_sdev;
640*4882a593Smuzhiyun struct v4l2_subdev *isp_sd = &isp_sdev->sd;
641*4882a593Smuzhiyun int i;
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun for (i = 0; i < isp_dev->num_sensors; i++) {
644*4882a593Smuzhiyun if (isp_dev->sensors[i].sd == subdev) {
645*4882a593Smuzhiyun media_entity_call(&isp_sd->entity, link_setup,
646*4882a593Smuzhiyun isp_sd->entity.pads, subdev->entity.pads, 0);
647*4882a593Smuzhiyun isp_dev->sensors[i].sd = NULL;
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun }
650*4882a593Smuzhiyun }
651*4882a593Smuzhiyun
652*4882a593Smuzhiyun static const struct v4l2_async_notifier_operations subdev_notifier_ops = {
653*4882a593Smuzhiyun .bound = subdev_notifier_bound,
654*4882a593Smuzhiyun .complete = subdev_notifier_complete,
655*4882a593Smuzhiyun .unbind = subdev_notifier_unbind,
656*4882a593Smuzhiyun };
657*4882a593Smuzhiyun
isp_subdev_notifier(struct rkisp_device * isp_dev)658*4882a593Smuzhiyun static int isp_subdev_notifier(struct rkisp_device *isp_dev)
659*4882a593Smuzhiyun {
660*4882a593Smuzhiyun struct v4l2_async_notifier *ntf = &isp_dev->notifier;
661*4882a593Smuzhiyun struct device *dev = isp_dev->dev;
662*4882a593Smuzhiyun int ret;
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun v4l2_async_notifier_init(ntf);
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun ret = v4l2_async_notifier_parse_fwnode_endpoints(
667*4882a593Smuzhiyun dev, ntf, sizeof(struct rkisp_async_subdev),
668*4882a593Smuzhiyun rkisp_fwnode_parse);
669*4882a593Smuzhiyun if (ret < 0)
670*4882a593Smuzhiyun return ret;
671*4882a593Smuzhiyun
672*4882a593Smuzhiyun ntf->ops = &subdev_notifier_ops;
673*4882a593Smuzhiyun
674*4882a593Smuzhiyun return v4l2_async_notifier_register(&isp_dev->v4l2_dev, ntf);
675*4882a593Smuzhiyun }
676*4882a593Smuzhiyun
677*4882a593Smuzhiyun /***************************** platform deive *******************************/
678*4882a593Smuzhiyun
rkisp_register_platform_subdevs(struct rkisp_device * dev)679*4882a593Smuzhiyun static int rkisp_register_platform_subdevs(struct rkisp_device *dev)
680*4882a593Smuzhiyun {
681*4882a593Smuzhiyun int ret;
682*4882a593Smuzhiyun
683*4882a593Smuzhiyun ret = rkisp_register_isp_subdev(dev, &dev->v4l2_dev);
684*4882a593Smuzhiyun if (ret < 0)
685*4882a593Smuzhiyun return ret;
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun ret = rkisp_register_csi_subdev(dev, &dev->v4l2_dev);
688*4882a593Smuzhiyun if (ret < 0)
689*4882a593Smuzhiyun goto err_unreg_isp_subdev;
690*4882a593Smuzhiyun
691*4882a593Smuzhiyun ret = rkisp_register_bridge_subdev(dev, &dev->v4l2_dev);
692*4882a593Smuzhiyun if (ret < 0)
693*4882a593Smuzhiyun goto err_unreg_csi_subdev;
694*4882a593Smuzhiyun
695*4882a593Smuzhiyun ret = rkisp_register_stream_vdevs(dev);
696*4882a593Smuzhiyun if (ret < 0)
697*4882a593Smuzhiyun goto err_unreg_bridge_subdev;
698*4882a593Smuzhiyun
699*4882a593Smuzhiyun ret = rkisp_register_dmarx_vdev(dev);
700*4882a593Smuzhiyun if (ret < 0)
701*4882a593Smuzhiyun goto err_unreg_stream_vdev;
702*4882a593Smuzhiyun
703*4882a593Smuzhiyun ret = rkisp_register_stats_vdev(&dev->stats_vdev, &dev->v4l2_dev, dev);
704*4882a593Smuzhiyun if (ret < 0)
705*4882a593Smuzhiyun goto err_unreg_dmarx_vdev;
706*4882a593Smuzhiyun
707*4882a593Smuzhiyun ret = rkisp_register_params_vdev(&dev->params_vdev, &dev->v4l2_dev, dev);
708*4882a593Smuzhiyun if (ret < 0)
709*4882a593Smuzhiyun goto err_unreg_stats_vdev;
710*4882a593Smuzhiyun
711*4882a593Smuzhiyun ret = rkisp_register_luma_vdev(&dev->luma_vdev, &dev->v4l2_dev, dev);
712*4882a593Smuzhiyun if (ret < 0)
713*4882a593Smuzhiyun goto err_unreg_params_vdev;
714*4882a593Smuzhiyun
715*4882a593Smuzhiyun ret = isp_subdev_notifier(dev);
716*4882a593Smuzhiyun if (ret < 0) {
717*4882a593Smuzhiyun v4l2_err(&dev->v4l2_dev,
718*4882a593Smuzhiyun "Failed to register subdev notifier(%d)\n", ret);
719*4882a593Smuzhiyun goto err_unreg_luma_vdev;
720*4882a593Smuzhiyun }
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun return 0;
723*4882a593Smuzhiyun err_unreg_luma_vdev:
724*4882a593Smuzhiyun rkisp_unregister_luma_vdev(&dev->luma_vdev);
725*4882a593Smuzhiyun err_unreg_params_vdev:
726*4882a593Smuzhiyun rkisp_unregister_params_vdev(&dev->params_vdev);
727*4882a593Smuzhiyun err_unreg_stats_vdev:
728*4882a593Smuzhiyun rkisp_unregister_stats_vdev(&dev->stats_vdev);
729*4882a593Smuzhiyun err_unreg_dmarx_vdev:
730*4882a593Smuzhiyun rkisp_unregister_dmarx_vdev(dev);
731*4882a593Smuzhiyun err_unreg_stream_vdev:
732*4882a593Smuzhiyun rkisp_unregister_stream_vdevs(dev);
733*4882a593Smuzhiyun err_unreg_bridge_subdev:
734*4882a593Smuzhiyun rkisp_unregister_bridge_subdev(dev);
735*4882a593Smuzhiyun err_unreg_csi_subdev:
736*4882a593Smuzhiyun rkisp_unregister_csi_subdev(dev);
737*4882a593Smuzhiyun err_unreg_isp_subdev:
738*4882a593Smuzhiyun rkisp_unregister_isp_subdev(dev);
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun return ret;
741*4882a593Smuzhiyun }
742*4882a593Smuzhiyun
rkisp_vs_irq_parse(struct device * dev)743*4882a593Smuzhiyun static int rkisp_vs_irq_parse(struct device *dev)
744*4882a593Smuzhiyun {
745*4882a593Smuzhiyun int ret;
746*4882a593Smuzhiyun int vs_irq;
747*4882a593Smuzhiyun unsigned long vs_irq_flags;
748*4882a593Smuzhiyun struct gpio_desc *vs_irq_gpio;
749*4882a593Smuzhiyun struct rkisp_device *isp_dev = dev_get_drvdata(dev);
750*4882a593Smuzhiyun
751*4882a593Smuzhiyun /* this irq recevice the message of sensor vs from preisp */
752*4882a593Smuzhiyun isp_dev->vs_irq = -1;
753*4882a593Smuzhiyun vs_irq_gpio = devm_gpiod_get(dev, "vsirq", GPIOD_IN);
754*4882a593Smuzhiyun if (!IS_ERR(vs_irq_gpio)) {
755*4882a593Smuzhiyun vs_irq_flags = IRQF_TRIGGER_RISING |
756*4882a593Smuzhiyun IRQF_ONESHOT | IRQF_SHARED;
757*4882a593Smuzhiyun
758*4882a593Smuzhiyun vs_irq = gpiod_to_irq(vs_irq_gpio);
759*4882a593Smuzhiyun if (vs_irq < 0) {
760*4882a593Smuzhiyun dev_err(dev, "GPIO to interrupt failed\n");
761*4882a593Smuzhiyun return vs_irq;
762*4882a593Smuzhiyun }
763*4882a593Smuzhiyun
764*4882a593Smuzhiyun dev_info(dev, "register_irq: %d\n", vs_irq);
765*4882a593Smuzhiyun ret = devm_request_irq(dev,
766*4882a593Smuzhiyun vs_irq,
767*4882a593Smuzhiyun rkisp_vs_isr_handler,
768*4882a593Smuzhiyun vs_irq_flags,
769*4882a593Smuzhiyun "vs_irq_gpio_int",
770*4882a593Smuzhiyun dev);
771*4882a593Smuzhiyun if (ret) {
772*4882a593Smuzhiyun dev_err(dev, "devm_request_irq failed: %d\n", ret);
773*4882a593Smuzhiyun return ret;
774*4882a593Smuzhiyun } else {
775*4882a593Smuzhiyun disable_irq(vs_irq);
776*4882a593Smuzhiyun isp_dev->vs_irq = vs_irq;
777*4882a593Smuzhiyun isp_dev->vs_irq_gpio = vs_irq_gpio;
778*4882a593Smuzhiyun dev_info(dev, "vs_gpio_int interrupt is hooked\n");
779*4882a593Smuzhiyun }
780*4882a593Smuzhiyun }
781*4882a593Smuzhiyun
782*4882a593Smuzhiyun return 0;
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun static const struct media_device_ops rkisp_media_ops = {
786*4882a593Smuzhiyun .link_notify = v4l2_pipeline_link_notify,
787*4882a593Smuzhiyun };
788*4882a593Smuzhiyun
rkisp_get_reserved_mem(struct rkisp_device * isp_dev)789*4882a593Smuzhiyun static int rkisp_get_reserved_mem(struct rkisp_device *isp_dev)
790*4882a593Smuzhiyun {
791*4882a593Smuzhiyun struct device *dev = isp_dev->dev;
792*4882a593Smuzhiyun struct device_node *np;
793*4882a593Smuzhiyun struct resource r;
794*4882a593Smuzhiyun int ret;
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun /* Get reserved memory region from Device-tree */
797*4882a593Smuzhiyun np = of_parse_phandle(dev->of_node, "memory-region-thunderboot", 0);
798*4882a593Smuzhiyun if (!np) {
799*4882a593Smuzhiyun dev_info(dev, "No memory-region-thunderboot specified\n");
800*4882a593Smuzhiyun return 0;
801*4882a593Smuzhiyun }
802*4882a593Smuzhiyun
803*4882a593Smuzhiyun ret = of_address_to_resource(np, 0, &r);
804*4882a593Smuzhiyun if (ret) {
805*4882a593Smuzhiyun dev_err(dev, "No memory address assigned to the region\n");
806*4882a593Smuzhiyun return ret;
807*4882a593Smuzhiyun }
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun isp_dev->resmem_pa = r.start;
810*4882a593Smuzhiyun isp_dev->resmem_size = resource_size(&r);
811*4882a593Smuzhiyun isp_dev->resmem_addr = dma_map_single(dev, phys_to_virt(r.start),
812*4882a593Smuzhiyun sizeof(struct rkisp_thunderboot_resmem_head),
813*4882a593Smuzhiyun DMA_BIDIRECTIONAL);
814*4882a593Smuzhiyun ret = dma_mapping_error(dev, isp_dev->resmem_addr);
815*4882a593Smuzhiyun isp_dev->is_thunderboot = true;
816*4882a593Smuzhiyun dev_info(dev, "Allocated reserved memory, paddr: 0x%x\n", (u32)isp_dev->resmem_pa);
817*4882a593Smuzhiyun return ret;
818*4882a593Smuzhiyun }
819*4882a593Smuzhiyun
rkisp_plat_probe(struct platform_device * pdev)820*4882a593Smuzhiyun static int rkisp_plat_probe(struct platform_device *pdev)
821*4882a593Smuzhiyun {
822*4882a593Smuzhiyun struct device *dev = &pdev->dev;
823*4882a593Smuzhiyun struct v4l2_device *v4l2_dev;
824*4882a593Smuzhiyun struct rkisp_device *isp_dev;
825*4882a593Smuzhiyun int i, ret, mult = 1;
826*4882a593Smuzhiyun
827*4882a593Smuzhiyun snprintf(rkisp_version, sizeof(rkisp_version),
828*4882a593Smuzhiyun "v%02x.%02x.%02x",
829*4882a593Smuzhiyun RKISP_DRIVER_VERSION >> 16,
830*4882a593Smuzhiyun (RKISP_DRIVER_VERSION & 0xff00) >> 8,
831*4882a593Smuzhiyun RKISP_DRIVER_VERSION & 0x00ff);
832*4882a593Smuzhiyun
833*4882a593Smuzhiyun dev_info(dev, "rkisp driver version: %s\n", rkisp_version);
834*4882a593Smuzhiyun
835*4882a593Smuzhiyun isp_dev = devm_kzalloc(dev, sizeof(*isp_dev), GFP_KERNEL);
836*4882a593Smuzhiyun if (!isp_dev)
837*4882a593Smuzhiyun return -ENOMEM;
838*4882a593Smuzhiyun
839*4882a593Smuzhiyun dev_set_drvdata(dev, isp_dev);
840*4882a593Smuzhiyun isp_dev->dev = dev;
841*4882a593Smuzhiyun ret = rkisp_attach_hw(isp_dev);
842*4882a593Smuzhiyun if (ret)
843*4882a593Smuzhiyun return ret;
844*4882a593Smuzhiyun
845*4882a593Smuzhiyun if (isp_dev->hw_dev->is_unite)
846*4882a593Smuzhiyun mult = 2;
847*4882a593Smuzhiyun isp_dev->sw_base_addr = devm_kzalloc(dev, RKISP_ISP_SW_MAX_SIZE * mult, GFP_KERNEL);
848*4882a593Smuzhiyun if (!isp_dev->sw_base_addr)
849*4882a593Smuzhiyun return -ENOMEM;
850*4882a593Smuzhiyun
851*4882a593Smuzhiyun ret = rkisp_vs_irq_parse(dev);
852*4882a593Smuzhiyun if (ret)
853*4882a593Smuzhiyun return ret;
854*4882a593Smuzhiyun
855*4882a593Smuzhiyun snprintf(isp_dev->media_dev.model, sizeof(isp_dev->media_dev.model),
856*4882a593Smuzhiyun "%s%d", DRIVER_NAME, isp_dev->dev_id);
857*4882a593Smuzhiyun if (!isp_dev->hw_dev->is_unite)
858*4882a593Smuzhiyun strscpy(isp_dev->name, dev_name(dev), sizeof(isp_dev->name));
859*4882a593Smuzhiyun else
860*4882a593Smuzhiyun snprintf(isp_dev->name, sizeof(isp_dev->name),
861*4882a593Smuzhiyun "%s%d", "rkisp-unite", isp_dev->dev_id);
862*4882a593Smuzhiyun strscpy(isp_dev->media_dev.driver_name, isp_dev->name,
863*4882a593Smuzhiyun sizeof(isp_dev->media_dev.driver_name));
864*4882a593Smuzhiyun
865*4882a593Smuzhiyun ret = rkisp_get_reserved_mem(isp_dev);
866*4882a593Smuzhiyun if (ret)
867*4882a593Smuzhiyun return ret;
868*4882a593Smuzhiyun
869*4882a593Smuzhiyun mutex_init(&isp_dev->apilock);
870*4882a593Smuzhiyun mutex_init(&isp_dev->iqlock);
871*4882a593Smuzhiyun atomic_set(&isp_dev->pipe.power_cnt, 0);
872*4882a593Smuzhiyun atomic_set(&isp_dev->pipe.stream_cnt, 0);
873*4882a593Smuzhiyun init_waitqueue_head(&isp_dev->sync_onoff);
874*4882a593Smuzhiyun isp_dev->pipe.open = rkisp_pipeline_open;
875*4882a593Smuzhiyun isp_dev->pipe.close = rkisp_pipeline_close;
876*4882a593Smuzhiyun isp_dev->pipe.set_stream = rkisp_pipeline_set_stream;
877*4882a593Smuzhiyun
878*4882a593Smuzhiyun if (isp_dev->isp_ver == ISP_V20 || isp_dev->isp_ver == ISP_V21) {
879*4882a593Smuzhiyun atomic_set(&isp_dev->hdr.refcnt, 0);
880*4882a593Smuzhiyun for (i = 0; i < HDR_DMA_MAX; i++) {
881*4882a593Smuzhiyun INIT_LIST_HEAD(&isp_dev->hdr.q_tx[i]);
882*4882a593Smuzhiyun INIT_LIST_HEAD(&isp_dev->hdr.q_rx[i]);
883*4882a593Smuzhiyun }
884*4882a593Smuzhiyun }
885*4882a593Smuzhiyun
886*4882a593Smuzhiyun isp_dev->media_dev.dev = dev;
887*4882a593Smuzhiyun isp_dev->media_dev.ops = &rkisp_media_ops;
888*4882a593Smuzhiyun
889*4882a593Smuzhiyun v4l2_dev = &isp_dev->v4l2_dev;
890*4882a593Smuzhiyun v4l2_dev->mdev = &isp_dev->media_dev;
891*4882a593Smuzhiyun strlcpy(v4l2_dev->name, isp_dev->name, sizeof(v4l2_dev->name));
892*4882a593Smuzhiyun v4l2_ctrl_handler_init(&isp_dev->ctrl_handler, 5);
893*4882a593Smuzhiyun v4l2_dev->ctrl_handler = &isp_dev->ctrl_handler;
894*4882a593Smuzhiyun
895*4882a593Smuzhiyun ret = v4l2_device_register(isp_dev->dev, &isp_dev->v4l2_dev);
896*4882a593Smuzhiyun if (ret < 0) {
897*4882a593Smuzhiyun v4l2_err(v4l2_dev, "Failed to register v4l2 device:%d\n", ret);
898*4882a593Smuzhiyun return ret;
899*4882a593Smuzhiyun }
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun media_device_init(&isp_dev->media_dev);
902*4882a593Smuzhiyun ret = media_device_register(&isp_dev->media_dev);
903*4882a593Smuzhiyun if (ret < 0) {
904*4882a593Smuzhiyun v4l2_err(v4l2_dev, "Failed to register media device:%d\n", ret);
905*4882a593Smuzhiyun goto err_unreg_v4l2_dev;
906*4882a593Smuzhiyun }
907*4882a593Smuzhiyun
908*4882a593Smuzhiyun pm_runtime_enable(dev);
909*4882a593Smuzhiyun /* create & register platefom subdev (from of_node) */
910*4882a593Smuzhiyun ret = rkisp_register_platform_subdevs(isp_dev);
911*4882a593Smuzhiyun if (ret < 0) {
912*4882a593Smuzhiyun v4l2_err(v4l2_dev, "Failed to register platform subdevs:%d\n", ret);
913*4882a593Smuzhiyun goto err_unreg_media_dev;
914*4882a593Smuzhiyun }
915*4882a593Smuzhiyun rkisp_wait_line = 0;
916*4882a593Smuzhiyun of_property_read_u32(dev->of_node, "wait-line", &rkisp_wait_line);
917*4882a593Smuzhiyun
918*4882a593Smuzhiyun rkisp_proc_init(isp_dev);
919*4882a593Smuzhiyun
920*4882a593Smuzhiyun mutex_lock(&rkisp_dev_mutex);
921*4882a593Smuzhiyun list_add_tail(&isp_dev->list, &rkisp_device_list);
922*4882a593Smuzhiyun mutex_unlock(&rkisp_dev_mutex);
923*4882a593Smuzhiyun isp_dev->is_probe_end = true;
924*4882a593Smuzhiyun return 0;
925*4882a593Smuzhiyun
926*4882a593Smuzhiyun err_unreg_media_dev:
927*4882a593Smuzhiyun media_device_unregister(&isp_dev->media_dev);
928*4882a593Smuzhiyun err_unreg_v4l2_dev:
929*4882a593Smuzhiyun v4l2_device_unregister(&isp_dev->v4l2_dev);
930*4882a593Smuzhiyun return ret;
931*4882a593Smuzhiyun }
932*4882a593Smuzhiyun
rkisp_plat_remove(struct platform_device * pdev)933*4882a593Smuzhiyun static int rkisp_plat_remove(struct platform_device *pdev)
934*4882a593Smuzhiyun {
935*4882a593Smuzhiyun struct rkisp_device *isp_dev = platform_get_drvdata(pdev);
936*4882a593Smuzhiyun
937*4882a593Smuzhiyun isp_dev->is_hw_link = false;
938*4882a593Smuzhiyun isp_dev->hw_dev->isp[isp_dev->dev_id] = NULL;
939*4882a593Smuzhiyun
940*4882a593Smuzhiyun pm_runtime_disable(&pdev->dev);
941*4882a593Smuzhiyun
942*4882a593Smuzhiyun rkisp_proc_cleanup(isp_dev);
943*4882a593Smuzhiyun media_device_unregister(&isp_dev->media_dev);
944*4882a593Smuzhiyun v4l2_async_notifier_unregister(&isp_dev->notifier);
945*4882a593Smuzhiyun v4l2_async_notifier_cleanup(&isp_dev->notifier);
946*4882a593Smuzhiyun v4l2_device_unregister(&isp_dev->v4l2_dev);
947*4882a593Smuzhiyun v4l2_ctrl_handler_free(&isp_dev->ctrl_handler);
948*4882a593Smuzhiyun rkisp_unregister_luma_vdev(&isp_dev->luma_vdev);
949*4882a593Smuzhiyun rkisp_unregister_params_vdev(&isp_dev->params_vdev);
950*4882a593Smuzhiyun rkisp_unregister_stats_vdev(&isp_dev->stats_vdev);
951*4882a593Smuzhiyun rkisp_unregister_dmarx_vdev(isp_dev);
952*4882a593Smuzhiyun rkisp_unregister_stream_vdevs(isp_dev);
953*4882a593Smuzhiyun rkisp_unregister_bridge_subdev(isp_dev);
954*4882a593Smuzhiyun rkisp_unregister_csi_subdev(isp_dev);
955*4882a593Smuzhiyun rkisp_unregister_isp_subdev(isp_dev);
956*4882a593Smuzhiyun media_device_cleanup(&isp_dev->media_dev);
957*4882a593Smuzhiyun return 0;
958*4882a593Smuzhiyun }
959*4882a593Smuzhiyun
rkisp_runtime_suspend(struct device * dev)960*4882a593Smuzhiyun static int __maybe_unused rkisp_runtime_suspend(struct device *dev)
961*4882a593Smuzhiyun {
962*4882a593Smuzhiyun struct rkisp_device *isp_dev = dev_get_drvdata(dev);
963*4882a593Smuzhiyun int ret;
964*4882a593Smuzhiyun
965*4882a593Smuzhiyun mutex_lock(&isp_dev->hw_dev->dev_lock);
966*4882a593Smuzhiyun ret = pm_runtime_put_sync(isp_dev->hw_dev->dev);
967*4882a593Smuzhiyun mutex_unlock(&isp_dev->hw_dev->dev_lock);
968*4882a593Smuzhiyun return (ret > 0) ? 0 : ret;
969*4882a593Smuzhiyun }
970*4882a593Smuzhiyun
rkisp_runtime_resume(struct device * dev)971*4882a593Smuzhiyun static int __maybe_unused rkisp_runtime_resume(struct device *dev)
972*4882a593Smuzhiyun {
973*4882a593Smuzhiyun struct rkisp_device *isp_dev = dev_get_drvdata(dev);
974*4882a593Smuzhiyun int ret;
975*4882a593Smuzhiyun
976*4882a593Smuzhiyun /* power on to config default format from sensor */
977*4882a593Smuzhiyun if (isp_dev->isp_inp & (INP_CSI | INP_DVP | INP_LVDS | INP_CIF) &&
978*4882a593Smuzhiyun rkisp_update_sensor_info(isp_dev) >= 0)
979*4882a593Smuzhiyun _set_pipeline_default_fmt(isp_dev, false);
980*4882a593Smuzhiyun
981*4882a593Smuzhiyun if (isp_dev->hw_dev->is_assigned_clk)
982*4882a593Smuzhiyun rkisp_clk_dbg = true;
983*4882a593Smuzhiyun isp_dev->cap_dev.wait_line = rkisp_wait_line;
984*4882a593Smuzhiyun isp_dev->cap_dev.wrap_line = rkisp_wrap_line;
985*4882a593Smuzhiyun isp_dev->is_rdbk_auto = rkisp_rdbk_auto;
986*4882a593Smuzhiyun mutex_lock(&isp_dev->hw_dev->dev_lock);
987*4882a593Smuzhiyun ret = pm_runtime_get_sync(isp_dev->hw_dev->dev);
988*4882a593Smuzhiyun mutex_unlock(&isp_dev->hw_dev->dev_lock);
989*4882a593Smuzhiyun return (ret > 0) ? 0 : ret;
990*4882a593Smuzhiyun }
991*4882a593Smuzhiyun
992*4882a593Smuzhiyun #ifndef MODULE
rkisp_clr_unready_dev(void)993*4882a593Smuzhiyun static int __init rkisp_clr_unready_dev(void)
994*4882a593Smuzhiyun {
995*4882a593Smuzhiyun __rkisp_clr_unready_dev();
996*4882a593Smuzhiyun
997*4882a593Smuzhiyun return 0;
998*4882a593Smuzhiyun }
999*4882a593Smuzhiyun late_initcall_sync(rkisp_clr_unready_dev);
1000*4882a593Smuzhiyun #endif
1001*4882a593Smuzhiyun
1002*4882a593Smuzhiyun static const struct dev_pm_ops rkisp_plat_pm_ops = {
1003*4882a593Smuzhiyun SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1004*4882a593Smuzhiyun pm_runtime_force_resume)
1005*4882a593Smuzhiyun SET_RUNTIME_PM_OPS(rkisp_runtime_suspend, rkisp_runtime_resume, NULL)
1006*4882a593Smuzhiyun };
1007*4882a593Smuzhiyun
1008*4882a593Smuzhiyun static const struct of_device_id rkisp_plat_of_match[] = {
1009*4882a593Smuzhiyun {
1010*4882a593Smuzhiyun .compatible = "rockchip,rkisp-vir",
1011*4882a593Smuzhiyun }, {
1012*4882a593Smuzhiyun .compatible = "rockchip,rv1126-rkisp-vir",
1013*4882a593Smuzhiyun },
1014*4882a593Smuzhiyun {},
1015*4882a593Smuzhiyun };
1016*4882a593Smuzhiyun
1017*4882a593Smuzhiyun struct platform_driver rkisp_plat_drv = {
1018*4882a593Smuzhiyun .driver = {
1019*4882a593Smuzhiyun .name = DRIVER_NAME,
1020*4882a593Smuzhiyun .of_match_table = of_match_ptr(rkisp_plat_of_match),
1021*4882a593Smuzhiyun .pm = &rkisp_plat_pm_ops,
1022*4882a593Smuzhiyun },
1023*4882a593Smuzhiyun .probe = rkisp_plat_probe,
1024*4882a593Smuzhiyun .remove = rkisp_plat_remove,
1025*4882a593Smuzhiyun };
1026*4882a593Smuzhiyun
1027*4882a593Smuzhiyun MODULE_AUTHOR("Rockchip Camera/ISP team");
1028*4882a593Smuzhiyun MODULE_DESCRIPTION("Rockchip ISP platform driver");
1029*4882a593Smuzhiyun MODULE_LICENSE("Dual BSD/GPL");
1030*4882a593Smuzhiyun MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
1031