Lines Matching full:csi2

24 #include "ipu6-isys-csi2.h"
26 #include "ipu6-platform-isys-csi2-reg.h"
80 s64 ipu6_isys_csi2_get_link_freq(struct ipu6_isys_csi2 *csi2)
84 if (!csi2)
87 src_pad = media_entity_remote_source_pad_unique(&csi2->asd.sd.entity);
89 dev_err(&csi2->isys->adev->auxdev.dev,
91 csi2->asd.sd.name, PTR_ERR(src_pad));
102 struct ipu6_isys_csi2 *csi2 = to_ipu6_isys_csi2(asd);
103 struct device *dev = &csi2->isys->adev->auxdev.dev;
105 dev_dbg(dev, "csi2 subscribe event(type %u id %u)\n",
124 * The input system CSI2+ receiver has several
164 ipu6_isys_csi2_calc_timing(struct ipu6_isys_csi2 *csi2,
167 struct device *dev = &csi2->isys->adev->auxdev.dev;
170 link_freq = ipu6_isys_csi2_get_link_freq(csi2);
194 void ipu6_isys_register_errors(struct ipu6_isys_csi2 *csi2)
196 u32 irq = readl(csi2->base + CSI_PORT_REG_BASE_IRQ_CSI +
198 struct ipu6_isys *isys = csi2->isys;
201 mask = isys->pdata->ipdata->csi2.irq_mask;
202 writel(irq & mask, csi2->base + CSI_PORT_REG_BASE_IRQ_CSI +
204 csi2->receiver_errors |= irq & mask;
207 void ipu6_isys_csi2_error(struct ipu6_isys_csi2 *csi2)
209 struct device *dev = &csi2->isys->adev->auxdev.dev;
215 ipu6_isys_register_errors(csi2);
216 status = csi2->receiver_errors;
217 csi2->receiver_errors = 0;
222 dev_err_ratelimited(dev, "csi2-%i error: %s\n",
223 csi2->port, errors[i].error_string);
232 struct ipu6_isys_csi2 *csi2 = to_ipu6_isys_csi2(asd);
233 struct ipu6_isys *isys = csi2->isys;
241 dev_dbg(dev, "stream %s CSI2-%u with %u lanes\n", enable ? "on" : "off",
242 csi2->port, nlanes);
244 cfg.port = csi2->port;
247 mask = isys->pdata->ipdata->csi2.irq_mask;
248 nports = isys->pdata->ipdata->csi2.nports;
251 writel(0, csi2->base + CSI_REG_CSI_FE_ENABLE);
252 writel(0, csi2->base + CSI_REG_PPI2CSI_ENABLE);
255 csi2->base + CSI_PORT_REG_BASE_IRQ_CSI +
258 csi2->base + CSI_PORT_REG_BASE_IRQ_CSI +
261 csi2->base + CSI_PORT_REG_BASE_IRQ_CSI_SYNC +
264 csi2->base + CSI_PORT_REG_BASE_IRQ_CSI_SYNC +
270 (isys->pdata->ipdata->csi2.fw_access_port_ofs,
271 csi2->port));
273 CSI_REG_HUB_DRV_ACCESS_PORT(csi2->port));
279 writel(0x1, csi2->base + CSI_REG_PORT_GPREG_SRST);
281 writel(0x0, csi2->base + CSI_REG_PORT_GPREG_SRST);
287 (isys->pdata->ipdata->csi2.fw_access_port_ofs, i));
292 csi2->base + CSI_PORT_REG_BASE_IRQ_CSI +
295 csi2->base + CSI_PORT_REG_BASE_IRQ_CSI +
298 csi2->base + CSI_PORT_REG_BASE_IRQ_CSI +
301 csi2->base + CSI_PORT_REG_BASE_IRQ_CSI +
304 csi2->base + CSI_PORT_REG_BASE_IRQ_CSI +
308 * Using event from firmware instead of irq to handle CSI2 sync event
309 * which can reduce system wakeups. If CSI2 sync irq enabled, we need
310 * disable the firmware CSI2 sync event to avoid duplicate handling.
312 writel(0xffffffff, csi2->base + CSI_PORT_REG_BASE_IRQ_CSI_SYNC +
314 writel(0, csi2->base + CSI_PORT_REG_BASE_IRQ_CSI_SYNC +
316 writel(0xffffffff, csi2->base + CSI_PORT_REG_BASE_IRQ_CSI_SYNC +
318 writel(0, csi2->base + CSI_PORT_REG_BASE_IRQ_CSI_SYNC +
320 writel(0xffffffff, csi2->base + CSI_PORT_REG_BASE_IRQ_CSI_SYNC +
324 writel(0, csi2->base + CSI_REG_CSI_FE_MODE);
325 writel(CSI_SENSOR_INPUT, csi2->base + CSI_REG_CSI_FE_MUX_CTRL);
327 csi2->base + CSI_REG_CSI_FE_SYNC_CNTR_SEL);
329 csi2->base + CSI_REG_PPI2CSI_CONFIG_PPI_INTF);
331 writel(1, csi2->base + CSI_REG_PPI2CSI_ENABLE);
332 writel(1, csi2->base + CSI_REG_CSI_FE_ENABLE);
336 dev_err(dev, "csi-%d phy power up failed %d\n", csi2->port,
347 struct ipu6_isys_csi2 *csi2 = to_ipu6_isys_csi2(asd);
361 ret = ipu6_isys_csi2_calc_timing(csi2, &timing, CSI2_ACCINV);
365 ret = ipu6_isys_csi2_set_stream(sd, &timing, csi2->nlanes, true);
512 void ipu6_isys_csi2_cleanup(struct ipu6_isys_csi2 *csi2)
514 if (!csi2->isys)
517 v4l2_device_unregister_subdev(&csi2->asd.sd);
518 v4l2_subdev_cleanup(&csi2->asd.sd);
519 ipu6_isys_subdev_cleanup(&csi2->asd);
520 csi2->isys = NULL;
523 int ipu6_isys_csi2_init(struct ipu6_isys_csi2 *csi2,
530 csi2->isys = isys;
531 csi2->base = base;
532 csi2->port = index;
534 csi2->asd.sd.entity.ops = &csi2_entity_ops;
535 csi2->asd.isys = isys;
536 ret = ipu6_isys_subdev_init(&csi2->asd, &csi2_sd_ops, 0,
541 csi2->asd.source = IPU6_FW_ISYS_STREAM_SRC_CSI2_PORT0 + index;
542 csi2->asd.supported_codes = csi2_supported_codes;
543 snprintf(csi2->asd.sd.name, sizeof(csi2->asd.sd.name),
544 IPU6_ISYS_ENTITY_PREFIX " CSI2 %u", index);
545 v4l2_set_subdevdata(&csi2->asd.sd, &csi2->asd);
546 ret = v4l2_subdev_init_finalize(&csi2->asd.sd);
552 ret = v4l2_device_register_subdev(&isys->v4l2_dev, &csi2->asd.sd);
561 ipu6_isys_csi2_cleanup(csi2);
570 struct ipu6_isys_csi2 *csi2 = ipu6_isys_subdev_to_csi2(stream->asd);
578 dev_dbg(dev, "sof_event::csi2-%i sequence: %i, vc: %d\n",
579 csi2->port, ev.u.frame_sync.frame_sequence, stream->vc);
585 struct ipu6_isys_csi2 *csi2 = ipu6_isys_subdev_to_csi2(stream->asd);
588 dev_dbg(dev, "eof_event::csi2-%i sequence: %i\n",
589 csi2->port, frame_sequence);
593 struct ipu6_isys_csi2 *csi2,
598 struct device *dev = &csi2->isys->adev->auxdev.dev;
609 pad = media_pad_remote_pad_first(&csi2->asd.pad[CSI2_PAD_SINK]);
635 if (desc_entry->bus.csi2.vc >= NR_OF_CSI2_VC) {
636 dev_err(dev, "invalid vc %d\n", desc_entry->bus.csi2.vc);