Lines Matching defs:vin

19 #include "rcar-vin.h"
159 static void rvin_write(struct rvin_dev *vin, u32 value, u32 offset)
161 iowrite32(value, vin->base + offset);
164 static u32 rvin_read(struct rvin_dev *vin, u32 offset)
166 return ioread32(vin->base + offset);
173 static bool rvin_scaler_needed(const struct rvin_dev *vin)
175 return !(vin->crop.width == vin->format.width &&
176 vin->compose.width == vin->format.width &&
177 vin->crop.height == vin->format.height &&
178 vin->compose.height == vin->format.height);
499 static void rvin_set_coeff(struct rvin_dev *vin, unsigned short xs)
520 rvin_write(vin, p_set->coeff_set[0], VNC1A_REG);
521 rvin_write(vin, p_set->coeff_set[1], VNC1B_REG);
522 rvin_write(vin, p_set->coeff_set[2], VNC1C_REG);
524 rvin_write(vin, p_set->coeff_set[3], VNC2A_REG);
525 rvin_write(vin, p_set->coeff_set[4], VNC2B_REG);
526 rvin_write(vin, p_set->coeff_set[5], VNC2C_REG);
528 rvin_write(vin, p_set->coeff_set[6], VNC3A_REG);
529 rvin_write(vin, p_set->coeff_set[7], VNC3B_REG);
530 rvin_write(vin, p_set->coeff_set[8], VNC3C_REG);
532 rvin_write(vin, p_set->coeff_set[9], VNC4A_REG);
533 rvin_write(vin, p_set->coeff_set[10], VNC4B_REG);
534 rvin_write(vin, p_set->coeff_set[11], VNC4C_REG);
536 rvin_write(vin, p_set->coeff_set[12], VNC5A_REG);
537 rvin_write(vin, p_set->coeff_set[13], VNC5B_REG);
538 rvin_write(vin, p_set->coeff_set[14], VNC5C_REG);
540 rvin_write(vin, p_set->coeff_set[15], VNC6A_REG);
541 rvin_write(vin, p_set->coeff_set[16], VNC6B_REG);
542 rvin_write(vin, p_set->coeff_set[17], VNC6C_REG);
544 rvin_write(vin, p_set->coeff_set[18], VNC7A_REG);
545 rvin_write(vin, p_set->coeff_set[19], VNC7B_REG);
546 rvin_write(vin, p_set->coeff_set[20], VNC7C_REG);
548 rvin_write(vin, p_set->coeff_set[21], VNC8A_REG);
549 rvin_write(vin, p_set->coeff_set[22], VNC8B_REG);
550 rvin_write(vin, p_set->coeff_set[23], VNC8C_REG);
553 void rvin_scaler_gen2(struct rvin_dev *vin)
559 crop_height = vin->crop.height;
560 if (V4L2_FIELD_HAS_BOTH(vin->format.field))
564 if (crop_height != vin->compose.height)
565 ys = (4096 * crop_height) / vin->compose.height;
566 rvin_write(vin, ys, VNYS_REG);
569 if (vin->crop.width != vin->compose.width)
570 xs = (4096 * vin->crop.width) / vin->compose.width;
576 rvin_write(vin, xs, VNXS_REG);
582 rvin_set_coeff(vin, xs);
585 rvin_write(vin, 0, VNSPPOC_REG);
586 rvin_write(vin, 0, VNSLPOC_REG);
587 rvin_write(vin, vin->format.width - 1, VNEPPOC_REG);
589 if (V4L2_FIELD_HAS_BOTH(vin->format.field))
590 rvin_write(vin, vin->format.height / 2 - 1, VNELPOC_REG);
592 rvin_write(vin, vin->format.height - 1, VNELPOC_REG);
594 vin_dbg(vin,
596 vin->crop.width, vin->crop.height, vin->crop.left,
597 vin->crop.top, ys, xs, vin->format.width, vin->format.height,
617 void rvin_scaler_gen3(struct rvin_dev *vin)
623 vnmc = rvin_read(vin, VNMC_REG);
626 if (!rvin_scaler_needed(vin)) {
627 rvin_write(vin, vnmc & ~VNMC_SCLE, VNMC_REG);
631 ratio_h = rvin_uds_scale_ratio(vin->crop.width, vin->compose.width);
634 ratio_v = rvin_uds_scale_ratio(vin->crop.height, vin->compose.height);
637 clip_size = vin->compose.width << 16;
639 switch (vin->format.field) {
645 clip_size |= vin->compose.height / 2;
648 clip_size |= vin->compose.height;
652 rvin_write(vin, vnmc | VNMC_SCLE, VNMC_REG);
653 rvin_write(vin, VNUDS_CTRL_AMD, VNUDS_CTRL_REG);
654 rvin_write(vin, (ratio_h << 16) | ratio_v, VNUDS_SCALE_REG);
655 rvin_write(vin, (bwidth_h << 16) | bwidth_v, VNUDS_PASS_BWIDTH_REG);
656 rvin_write(vin, clip_size, VNUDS_CLIP_SIZE_REG);
658 vin_dbg(vin, "Pre-Clip: %ux%u@%u:%u Post-Clip: %ux%u@%u:%u\n",
659 vin->crop.width, vin->crop.height, vin->crop.left,
660 vin->crop.top, vin->compose.width, vin->compose.height,
661 vin->compose.left, vin->compose.top);
664 void rvin_crop_scale_comp(struct rvin_dev *vin)
670 rvin_write(vin, vin->crop.left, VNSPPRC_REG);
671 rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
672 rvin_write(vin, vin->crop.top, VNSLPRC_REG);
673 rvin_write(vin, vin->crop.top + vin->crop.height - 1, VNELPRC_REG);
675 if (vin->scaler)
676 vin->scaler(vin);
678 fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
679 stride = vin->format.bytesperline / fmt->bpp;
684 switch (vin->format.pixelformat) {
696 rvin_write(vin, stride, VNIS_REG);
703 static int rvin_setup(struct rvin_dev *vin)
708 switch (vin->format.field) {
719 if (!vin->info->use_mc && vin->std & V4L2_STD_525_60)
743 switch (vin->mbus_code) {
755 if (!vin->is_csi &&
756 vin->parallel.mbus_type == V4L2_MBUS_BT656)
768 if (!vin->is_csi &&
769 vin->parallel.mbus_type == V4L2_MBUS_BT656)
788 if (vin->info->model == RCAR_GEN3) {
794 if (vin->is_csi) {
795 vin_err(vin, "Invalid setting in MIPI CSI2\n");
800 if (!vin->is_csi) {
801 vin_err(vin, "Invalid setting in Digital Pins\n");
811 if (vin->info->model == RCAR_GEN3)
816 if (!vin->is_csi) {
818 if (!(vin->parallel.bus.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
822 if (!(vin->parallel.bus.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
826 if (vin->parallel.bus.flags & V4L2_MBUS_DATA_ENABLE_LOW)
829 switch (vin->mbus_code) {
831 if (vin->parallel.bus.bus_width == 8 &&
832 vin->parallel.bus.data_shift == 8)
843 switch (vin->format.pixelformat) {
846 rvin_write(vin,
847 ALIGN(vin->format.bytesperline * vin->format.height,
849 dmr = vin->format.pixelformat == V4L2_PIX_FMT_NV12 ?
872 dmr = (vin->alpha ? VNDMR_ABIT : 0) | VNDMR_DTMD_ARGB;
875 dmr = VNDMR_A8BIT(vin->alpha) | VNDMR_EXRGB | VNDMR_DTMD_ARGB;
892 vin_err(vin, "Invalid pixelformat (0x%x)\n",
893 vin->format.pixelformat);
900 if (!vin->info->use_isp) {
905 if (vin->info->model == RCAR_GEN3) {
907 if (vin->is_csi)
918 rvin_write(vin, interrupts, VNINTS_REG);
920 rvin_write(vin, interrupts, VNIE_REG);
922 rvin_write(vin, dmr, VNDMR_REG);
923 rvin_write(vin, dmr2, VNDMR2_REG);
926 rvin_write(vin, vnmc | VNMC_ME, VNMC_REG);
931 static void rvin_disable_interrupts(struct rvin_dev *vin)
933 rvin_write(vin, 0, VNIE_REG);
936 static u32 rvin_get_interrupt_status(struct rvin_dev *vin)
938 return rvin_read(vin, VNINTS_REG);
941 static void rvin_ack_interrupt(struct rvin_dev *vin)
943 rvin_write(vin, rvin_read(vin, VNINTS_REG), VNINTS_REG);
946 static bool rvin_capture_active(struct rvin_dev *vin)
948 return rvin_read(vin, VNMS_REG) & VNMS_CA;
951 static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms)
953 if (vin->format.field == V4L2_FIELD_ALTERNATE) {
960 return vin->format.field;
963 static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr)
969 fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
975 offsetx = vin->compose.left * fmt->bpp;
976 offsety = vin->compose.top * vin->format.bytesperline;
986 rvin_write(vin, offset, VNMB_REG(slot));
995 static void rvin_fill_hw_slot(struct rvin_dev *vin, int slot)
1003 if (WARN_ON(vin->buf_hw[slot].buffer))
1008 if (vin->buf_hw[prev].type == HALF_TOP) {
1009 vbuf = vin->buf_hw[prev].buffer;
1010 vin->buf_hw[slot].buffer = vbuf;
1011 vin->buf_hw[slot].type = HALF_BOTTOM;
1012 switch (vin->format.pixelformat) {
1015 phys_addr = vin->buf_hw[prev].phys +
1016 vin->format.sizeimage / 4;
1019 phys_addr = vin->buf_hw[prev].phys +
1020 vin->format.sizeimage / 2;
1023 } else if ((vin->state != STOPPED && vin->state != RUNNING) ||
1024 list_empty(&vin->buf_list)) {
1025 vin->buf_hw[slot].buffer = NULL;
1026 vin->buf_hw[slot].type = FULL;
1027 phys_addr = vin->scratch_phys;
1030 buf = list_entry(vin->buf_list.next, struct rvin_buffer, list);
1033 vin->buf_hw[slot].buffer = vbuf;
1035 vin->buf_hw[slot].type =
1036 V4L2_FIELD_IS_SEQUENTIAL(vin->format.field) ?
1043 vin_dbg(vin, "Filling HW slot: %d type: %d buffer: %p\n",
1044 slot, vin->buf_hw[slot].type, vin->buf_hw[slot].buffer);
1046 vin->buf_hw[slot].phys = phys_addr;
1047 rvin_set_slot_addr(vin, slot, phys_addr);
1050 static int rvin_capture_start(struct rvin_dev *vin)
1055 vin->buf_hw[slot].buffer = NULL;
1056 vin->buf_hw[slot].type = FULL;
1060 rvin_fill_hw_slot(vin, slot);
1062 ret = rvin_setup(vin);
1066 rvin_crop_scale_comp(vin);
1068 vin_dbg(vin, "Starting to capture\n");
1071 rvin_write(vin, VNFC_C_FRAME, VNFC_REG);
1073 vin->state = STARTING;
1078 static void rvin_capture_stop(struct rvin_dev *vin)
1081 rvin_write(vin, 0, VNFC_REG);
1084 rvin_write(vin, rvin_read(vin, VNMC_REG) & ~VNMC_ME, VNMC_REG);
1096 struct rvin_dev *vin = data;
1102 spin_lock_irqsave(&vin->qlock, flags);
1104 int_status = rvin_get_interrupt_status(vin);
1108 rvin_ack_interrupt(vin);
1116 if (vin->state == STOPPED) {
1117 vin_dbg(vin, "IRQ while state stopped\n");
1122 vnms = rvin_read(vin, VNMS_REG);
1129 if (vin->state == STARTING) {
1131 vin_dbg(vin, "Starting sync slot: %d\n", slot);
1135 vin_dbg(vin, "Capture start synced!\n");
1136 vin->state = RUNNING;
1140 if (vin->buf_hw[slot].buffer) {
1145 if (vin->buf_hw[slot].type == HALF_TOP) {
1146 vin->buf_hw[slot].buffer = NULL;
1147 rvin_fill_hw_slot(vin, slot);
1151 vin->buf_hw[slot].buffer->field =
1152 rvin_get_active_field(vin, vnms);
1153 vin->buf_hw[slot].buffer->sequence = vin->sequence;
1154 vin->buf_hw[slot].buffer->vb2_buf.timestamp = ktime_get_ns();
1155 vb2_buffer_done(&vin->buf_hw[slot].buffer->vb2_buf,
1157 vin->buf_hw[slot].buffer = NULL;
1160 vin_dbg(vin, "Dropping frame %u\n", vin->sequence);
1163 vin->sequence++;
1166 rvin_fill_hw_slot(vin, slot);
1168 spin_unlock_irqrestore(&vin->qlock, flags);
1173 static void return_unused_buffers(struct rvin_dev *vin,
1179 spin_lock_irqsave(&vin->qlock, flags);
1181 list_for_each_entry_safe(buf, node, &vin->buf_list, list) {
1186 spin_unlock_irqrestore(&vin->qlock, flags);
1194 struct rvin_dev *vin = vb2_get_drv_priv(vq);
1198 return sizes[0] < vin->format.sizeimage ? -EINVAL : 0;
1201 sizes[0] = vin->format.sizeimage;
1208 struct rvin_dev *vin = vb2_get_drv_priv(vb->vb2_queue);
1209 unsigned long size = vin->format.sizeimage;
1212 vin_err(vin, "buffer too small (%lu < %lu)\n",
1225 struct rvin_dev *vin = vb2_get_drv_priv(vb->vb2_queue);
1228 spin_lock_irqsave(&vin->qlock, flags);
1230 list_add_tail(to_buf_list(vbuf), &vin->buf_list);
1232 spin_unlock_irqrestore(&vin->qlock, flags);
1235 static int rvin_mc_validate_format(struct rvin_dev *vin, struct v4l2_subdev *sd,
1254 if (vin->format.pixelformat != V4L2_PIX_FMT_SBGGR8)
1258 if (vin->format.pixelformat != V4L2_PIX_FMT_SGBRG8)
1262 if (vin->format.pixelformat != V4L2_PIX_FMT_SGRBG8)
1266 if (vin->format.pixelformat != V4L2_PIX_FMT_SRGGB8)
1270 if (vin->format.pixelformat != V4L2_PIX_FMT_GREY)
1276 vin->mbus_code = fmt.format.code;
1290 switch (vin->format.field) {
1312 if (rvin_scaler_needed(vin)) {
1314 if (vin->info->model == RCAR_GEN3 &&
1315 vin->format.pixelformat == V4L2_PIX_FMT_NV12)
1318 if (!vin->scaler)
1321 if (vin->format.pixelformat == V4L2_PIX_FMT_NV12) {
1322 if (ALIGN(fmt.format.width, 32) != vin->format.width ||
1323 ALIGN(fmt.format.height, 32) != vin->format.height)
1326 if (fmt.format.width != vin->format.width ||
1327 fmt.format.height != vin->format.height)
1332 if (fmt.format.code != vin->mbus_code)
1338 static int rvin_set_stream(struct rvin_dev *vin, int on)
1345 if (!vin->info->use_mc) {
1346 ret = v4l2_subdev_call(vin->parallel.subdev, video, s_stream,
1352 pad = media_pad_remote_pad_first(&vin->pad);
1359 video_device_pipeline_stop(&vin->vdev);
1363 ret = rvin_mc_validate_format(vin, sd, pad);
1367 ret = video_device_pipeline_alloc_start(&vin->vdev);
1375 video_device_pipeline_stop(&vin->vdev);
1380 int rvin_start_streaming(struct rvin_dev *vin)
1385 ret = rvin_set_stream(vin, 1);
1389 spin_lock_irqsave(&vin->qlock, flags);
1391 vin->sequence = 0;
1393 ret = rvin_capture_start(vin);
1395 rvin_set_stream(vin, 0);
1397 spin_unlock_irqrestore(&vin->qlock, flags);
1404 struct rvin_dev *vin = vb2_get_drv_priv(vq);
1408 vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage,
1409 &vin->scratch_phys, GFP_KERNEL);
1410 if (!vin->scratch)
1413 ret = rvin_start_streaming(vin);
1419 dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
1420 vin->scratch_phys);
1422 return_unused_buffers(vin, VB2_BUF_STATE_QUEUED);
1427 void rvin_stop_streaming(struct rvin_dev *vin)
1433 spin_lock_irqsave(&vin->qlock, flags);
1435 if (vin->state == STOPPED) {
1436 spin_unlock_irqrestore(&vin->qlock, flags);
1440 vin->state = STOPPING;
1447 if (vin->buf_hw[i].buffer)
1453 spin_unlock_irqrestore(&vin->qlock, flags);
1455 spin_lock_irqsave(&vin->qlock, flags);
1462 rvin_capture_stop(vin);
1465 if (!rvin_capture_active(vin)) {
1466 vin->state = STOPPED;
1470 spin_unlock_irqrestore(&vin->qlock, flags);
1472 spin_lock_irqsave(&vin->qlock, flags);
1475 if (!buffersFreed || vin->state != STOPPED) {
1481 vin_err(vin, "Failed stop HW, something is seriously broken\n");
1482 vin->state = STOPPED;
1485 spin_unlock_irqrestore(&vin->qlock, flags);
1489 return_unused_buffers(vin, VB2_BUF_STATE_ERROR);
1491 if (vin->buf_hw[i].buffer)
1492 vb2_buffer_done(&vin->buf_hw[i].buffer->vb2_buf,
1497 rvin_set_stream(vin, 0);
1500 rvin_disable_interrupts(vin);
1505 struct rvin_dev *vin = vb2_get_drv_priv(vq);
1507 rvin_stop_streaming(vin);
1510 dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
1511 vin->scratch_phys);
1513 return_unused_buffers(vin, VB2_BUF_STATE_ERROR);
1526 void rvin_dma_unregister(struct rvin_dev *vin)
1528 mutex_destroy(&vin->lock);
1530 v4l2_device_unregister(&vin->v4l2_dev);
1533 int rvin_dma_register(struct rvin_dev *vin, int irq)
1535 struct vb2_queue *q = &vin->queue;
1539 ret = v4l2_device_register(vin->dev, &vin->v4l2_dev);
1543 mutex_init(&vin->lock);
1544 INIT_LIST_HEAD(&vin->buf_list);
1546 spin_lock_init(&vin->qlock);
1548 vin->state = STOPPED;
1551 vin->buf_hw[i].buffer = NULL;
1556 q->lock = &vin->lock;
1557 q->drv_priv = vin;
1563 q->dev = vin->dev;
1567 vin_err(vin, "failed to initialize VB2 queue\n");
1572 ret = devm_request_irq(vin->dev, irq, rvin_irq, IRQF_SHARED,
1573 KBUILD_MODNAME, vin);
1575 vin_err(vin, "failed to request irq\n");
1581 rvin_dma_unregister(vin);
1595 int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel)
1602 ret = pm_runtime_resume_and_get(vin->dev);
1607 vnmc = rvin_read(vin, VNMC_REG);
1608 rvin_write(vin, vnmc & ~VNMC_VUP, VNMC_REG);
1616 for (route = vin->info->routes; route->chsel; route++) {
1628 rvin_write(vin, ifmd, VNCSI_IFMD_REG);
1631 vin_dbg(vin, "Set IFMD 0x%x\n", ifmd);
1633 vin->chsel = chsel;
1636 rvin_write(vin, vnmc, VNMC_REG);
1638 pm_runtime_put(vin->dev);
1643 void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha)
1648 spin_lock_irqsave(&vin->qlock, flags);
1650 vin->alpha = alpha;
1652 if (vin->state == STOPPED)
1655 switch (vin->format.pixelformat) {
1657 dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_ABIT;
1658 if (vin->alpha)
1662 dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_A8BIT_MASK;
1663 dmr |= VNDMR_A8BIT(vin->alpha);
1669 rvin_write(vin, dmr, VNDMR_REG);
1671 spin_unlock_irqrestore(&vin->qlock, flags);