Lines Matching +full:rp1 +full:- +full:cfe
1 // SPDX-License-Identifier: GPL-2.0-only
3 * RP1 CSI-2 Driver
5 * Copyright (c) 2021-2024 Raspberry Pi Ltd.
6 * Copyright (c) 2023-2024 Ideas on Board Oy
14 #include <media/videobuf2-dma-contig.h>
16 #include "cfe.h"
19 #include "cfe-trace.h"
23 MODULE_PARM_DESC(track_csi2_errors, "track csi-2 errors");
25 #define csi2_dbg(csi2, fmt, arg...) dev_dbg((csi2)->v4l2_dev->dev, fmt, ##arg)
26 #define csi2_err(csi2, fmt, arg...) dev_err((csi2)->v4l2_dev->dev, fmt, ##arg)
28 /* CSI2-DMA registers */
111 return readl(csi2->base + offset); in csi2_reg_read()
116 writel(val, csi2->base + offset); in csi2_reg_write()
130 struct csi2_device *csi2 = s->private; in csi2_regs_show()
133 ret = pm_runtime_resume_and_get(csi2->v4l2_dev->dev); in csi2_regs_show()
166 pm_runtime_put(csi2->v4l2_dev->dev); in csi2_regs_show()
175 struct csi2_device *csi2 = s->private; in csi2_errors_show()
181 spin_lock_irqsave(&csi2->errors_lock, flags); in csi2_errors_show()
183 memcpy(discards_table, csi2->discards_table, sizeof(discards_table)); in csi2_errors_show()
184 memcpy(discards_dt_table, csi2->discards_dt_table, in csi2_errors_show()
186 overflows = csi2->overflows; in csi2_errors_show()
188 csi2->overflows = 0; in csi2_errors_show()
189 memset(csi2->discards_table, 0, sizeof(discards_table)); in csi2_errors_show()
190 memset(csi2->discards_dt_table, 0, sizeof(discards_dt_table)); in csi2_errors_show()
192 spin_unlock_irqrestore(&csi2->errors_lock, flags); in csi2_errors_show()
219 spin_lock(&csi2->errors_lock); in csi2_isr_handle_errors()
222 csi2->overflows++; in csi2_isr_handle_errors()
252 csi2->discards_table[vc][i] += amount; in csi2_isr_handle_errors()
253 csi2->discards_dt_table[i] = dt; in csi2_isr_handle_errors()
256 spin_unlock(&csi2->errors_lock); in csi2_isr_handle_errors()
348 csi2->num_lines[channel] = height; in csi2_start_channel()
355 /* Channel disable. Use FORCE to allow stopping mid-frame. */ in csi2_stop_channel()
368 dphy_start(&csi2->dphy); in csi2_open_rx()
375 dphy_stop(&csi2->dphy); in csi2_close_rx()
410 if (format->pad == CSI2_PAD_SINK) { in csi2_pad_set_fmt()
415 cfe_fmt = find_format_by_code(format->format.code); in csi2_pad_set_fmt()
418 format->format.code = cfe_fmt->code; in csi2_pad_set_fmt()
423 fmt = v4l2_subdev_state_get_format(state, format->pad, in csi2_pad_set_fmt()
424 format->stream); in csi2_pad_set_fmt()
426 return -EINVAL; in csi2_pad_set_fmt()
428 *fmt = format->format; in csi2_pad_set_fmt()
431 format->pad, in csi2_pad_set_fmt()
432 format->stream); in csi2_pad_set_fmt()
434 return -EINVAL; in csi2_pad_set_fmt()
436 format->format.field = V4L2_FIELD_NONE; in csi2_pad_set_fmt()
438 *fmt = format->format; in csi2_pad_set_fmt()
447 format->pad, in csi2_pad_set_fmt()
448 format->stream); in csi2_pad_set_fmt()
450 return -EINVAL; in csi2_pad_set_fmt()
452 source_fmt = v4l2_subdev_state_get_format(state, format->pad, in csi2_pad_set_fmt()
453 format->stream); in csi2_pad_set_fmt()
455 return -EINVAL; in csi2_pad_set_fmt()
457 sink_code = sink_fmt->code; in csi2_pad_set_fmt()
458 code = format->format.code; in csi2_pad_set_fmt()
462 * - The sink's mbus code in csi2_pad_set_fmt()
463 * - The 16-bit version of the sink's mbus code in csi2_pad_set_fmt()
464 * - The compressed version of the sink's mbus code in csi2_pad_set_fmt()
469 source_fmt->code = code; in csi2_pad_set_fmt()
471 format->format.code = source_fmt->code; in csi2_pad_set_fmt()
491 for (unsigned int i = 0; i < routing->num_routes; ++i) { in csi2_set_routing()
492 const struct v4l2_subdev_route *route = &routing->routes[i]; in csi2_set_routing()
494 if (route->source_stream != 0) in csi2_set_routing()
495 return -EINVAL; in csi2_set_routing()
530 spin_lock_init(&csi2->errors_lock); in csi2_init()
532 csi2->dphy.dev = csi2->v4l2_dev->dev; in csi2_init()
533 dphy_probe(&csi2->dphy); in csi2_init()
541 csi2->pad[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK; in csi2_init()
545 csi2->pad[i].flags = MEDIA_PAD_FL_SOURCE; in csi2_init()
547 ret = media_entity_pads_init(&csi2->sd.entity, ARRAY_SIZE(csi2->pad), in csi2_init()
548 csi2->pad); in csi2_init()
553 v4l2_subdev_init(&csi2->sd, &csi2_subdev_ops); in csi2_init()
554 csi2->sd.internal_ops = &csi2_internal_ops; in csi2_init()
555 csi2->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in csi2_init()
556 csi2->sd.entity.ops = &csi2_entity_ops; in csi2_init()
557 csi2->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS; in csi2_init()
558 csi2->sd.owner = THIS_MODULE; in csi2_init()
559 snprintf(csi2->sd.name, sizeof(csi2->sd.name), "csi2"); in csi2_init()
561 ret = v4l2_subdev_init_finalize(&csi2->sd); in csi2_init()
565 ret = v4l2_device_register_subdev(csi2->v4l2_dev, &csi2->sd); in csi2_init()
574 v4l2_subdev_cleanup(&csi2->sd); in csi2_init()
576 media_entity_cleanup(&csi2->sd.entity); in csi2_init()
583 v4l2_device_unregister_subdev(&csi2->sd); in csi2_uninit()
584 v4l2_subdev_cleanup(&csi2->sd); in csi2_uninit()
585 media_entity_cleanup(&csi2->sd.entity); in csi2_uninit()