Lines Matching defs:vin
19 #include "rcar-vin.h"
147 static void rvin_write(struct rvin_dev *vin, u32 value, u32 offset)
149 iowrite32(value, vin->base + offset);
152 static u32 rvin_read(struct rvin_dev *vin, u32 offset)
154 return ioread32(vin->base + offset);
479 static void rvin_set_coeff(struct rvin_dev *vin, unsigned short xs)
500 rvin_write(vin, p_set->coeff_set[0], VNC1A_REG);
501 rvin_write(vin, p_set->coeff_set[1], VNC1B_REG);
502 rvin_write(vin, p_set->coeff_set[2], VNC1C_REG);
504 rvin_write(vin, p_set->coeff_set[3], VNC2A_REG);
505 rvin_write(vin, p_set->coeff_set[4], VNC2B_REG);
506 rvin_write(vin, p_set->coeff_set[5], VNC2C_REG);
508 rvin_write(vin, p_set->coeff_set[6], VNC3A_REG);
509 rvin_write(vin, p_set->coeff_set[7], VNC3B_REG);
510 rvin_write(vin, p_set->coeff_set[8], VNC3C_REG);
512 rvin_write(vin, p_set->coeff_set[9], VNC4A_REG);
513 rvin_write(vin, p_set->coeff_set[10], VNC4B_REG);
514 rvin_write(vin, p_set->coeff_set[11], VNC4C_REG);
516 rvin_write(vin, p_set->coeff_set[12], VNC5A_REG);
517 rvin_write(vin, p_set->coeff_set[13], VNC5B_REG);
518 rvin_write(vin, p_set->coeff_set[14], VNC5C_REG);
520 rvin_write(vin, p_set->coeff_set[15], VNC6A_REG);
521 rvin_write(vin, p_set->coeff_set[16], VNC6B_REG);
522 rvin_write(vin, p_set->coeff_set[17], VNC6C_REG);
524 rvin_write(vin, p_set->coeff_set[18], VNC7A_REG);
525 rvin_write(vin, p_set->coeff_set[19], VNC7B_REG);
526 rvin_write(vin, p_set->coeff_set[20], VNC7C_REG);
528 rvin_write(vin, p_set->coeff_set[21], VNC8A_REG);
529 rvin_write(vin, p_set->coeff_set[22], VNC8B_REG);
530 rvin_write(vin, p_set->coeff_set[23], VNC8C_REG);
533 static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin)
539 crop_height = vin->crop.height;
540 if (V4L2_FIELD_HAS_BOTH(vin->format.field))
544 if (crop_height != vin->compose.height)
545 ys = (4096 * crop_height) / vin->compose.height;
546 rvin_write(vin, ys, VNYS_REG);
549 if (vin->crop.width != vin->compose.width)
550 xs = (4096 * vin->crop.width) / vin->compose.width;
556 rvin_write(vin, xs, VNXS_REG);
562 rvin_set_coeff(vin, xs);
565 rvin_write(vin, 0, VNSPPOC_REG);
566 rvin_write(vin, 0, VNSLPOC_REG);
567 rvin_write(vin, vin->format.width - 1, VNEPPOC_REG);
569 if (V4L2_FIELD_HAS_BOTH(vin->format.field))
570 rvin_write(vin, vin->format.height / 2 - 1, VNELPOC_REG);
572 rvin_write(vin, vin->format.height - 1, VNELPOC_REG);
574 vin_dbg(vin,
576 vin->crop.width, vin->crop.height, vin->crop.left,
577 vin->crop.top, ys, xs, vin->format.width, vin->format.height,
581 void rvin_crop_scale_comp(struct rvin_dev *vin)
587 rvin_write(vin, vin->crop.left, VNSPPRC_REG);
588 rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
589 rvin_write(vin, vin->crop.top, VNSLPRC_REG);
590 rvin_write(vin, vin->crop.top + vin->crop.height - 1, VNELPRC_REG);
593 if (vin->info->model != RCAR_GEN3)
594 rvin_crop_scale_comp_gen2(vin);
596 fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
597 stride = vin->format.bytesperline / fmt->bpp;
602 switch (vin->format.pixelformat) {
613 rvin_write(vin, stride, VNIS_REG);
620 static int rvin_setup(struct rvin_dev *vin)
625 switch (vin->format.field) {
636 if (!vin->info->use_mc && vin->std & V4L2_STD_525_60)
660 switch (vin->mbus_code) {
672 if (!vin->is_csi &&
673 vin->parallel->mbus_type == V4L2_MBUS_BT656)
685 if (!vin->is_csi &&
686 vin->parallel->mbus_type == V4L2_MBUS_BT656)
704 if (vin->info->model == RCAR_GEN3)
709 if (!vin->is_csi) {
711 if (!(vin->parallel->bus.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
715 if (!(vin->parallel->bus.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
719 if (vin->parallel->bus.flags & V4L2_MBUS_DATA_ENABLE_LOW)
722 switch (vin->mbus_code) {
724 if (vin->parallel->bus.bus_width == 8 &&
725 vin->parallel->bus.data_shift == 8)
736 switch (vin->format.pixelformat) {
739 rvin_write(vin,
740 ALIGN(vin->format.bytesperline * vin->format.height,
742 dmr = vin->format.pixelformat == V4L2_PIX_FMT_NV12 ?
765 dmr = (vin->alpha ? VNDMR_ABIT : 0) | VNDMR_DTMD_ARGB;
768 dmr = VNDMR_A8BIT(vin->alpha) | VNDMR_EXRGB | VNDMR_DTMD_ARGB;
777 vin_err(vin, "Invalid pixelformat (0x%x)\n",
778 vin->format.pixelformat);
789 if (vin->info->model == RCAR_GEN3) {
791 if (vin->is_csi)
801 rvin_write(vin, interrupts, VNINTS_REG);
803 rvin_write(vin, interrupts, VNIE_REG);
805 rvin_write(vin, dmr, VNDMR_REG);
806 rvin_write(vin, dmr2, VNDMR2_REG);
809 rvin_write(vin, vnmc | VNMC_ME, VNMC_REG);
814 static void rvin_disable_interrupts(struct rvin_dev *vin)
816 rvin_write(vin, 0, VNIE_REG);
819 static u32 rvin_get_interrupt_status(struct rvin_dev *vin)
821 return rvin_read(vin, VNINTS_REG);
824 static void rvin_ack_interrupt(struct rvin_dev *vin)
826 rvin_write(vin, rvin_read(vin, VNINTS_REG), VNINTS_REG);
829 static bool rvin_capture_active(struct rvin_dev *vin)
831 return rvin_read(vin, VNMS_REG) & VNMS_CA;
834 static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms)
836 if (vin->format.field == V4L2_FIELD_ALTERNATE) {
843 return vin->format.field;
846 static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr)
852 fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
858 offsetx = vin->compose.left * fmt->bpp;
859 offsety = vin->compose.top * vin->format.bytesperline;
869 rvin_write(vin, offset, VNMB_REG(slot));
878 static void rvin_fill_hw_slot(struct rvin_dev *vin, int slot)
886 if (WARN_ON(vin->buf_hw[slot].buffer))
891 if (vin->buf_hw[prev].type == HALF_TOP) {
892 vbuf = vin->buf_hw[prev].buffer;
893 vin->buf_hw[slot].buffer = vbuf;
894 vin->buf_hw[slot].type = HALF_BOTTOM;
895 switch (vin->format.pixelformat) {
898 phys_addr = vin->buf_hw[prev].phys +
899 vin->format.sizeimage / 4;
902 phys_addr = vin->buf_hw[prev].phys +
903 vin->format.sizeimage / 2;
906 } else if (list_empty(&vin->buf_list)) {
907 vin->buf_hw[slot].buffer = NULL;
908 vin->buf_hw[slot].type = FULL;
909 phys_addr = vin->scratch_phys;
912 buf = list_entry(vin->buf_list.next, struct rvin_buffer, list);
915 vin->buf_hw[slot].buffer = vbuf;
917 vin->buf_hw[slot].type =
918 V4L2_FIELD_IS_SEQUENTIAL(vin->format.field) ?
925 vin_dbg(vin, "Filling HW slot: %d type: %d buffer: %p\n",
926 slot, vin->buf_hw[slot].type, vin->buf_hw[slot].buffer);
928 vin->buf_hw[slot].phys = phys_addr;
929 rvin_set_slot_addr(vin, slot, phys_addr);
932 static int rvin_capture_start(struct rvin_dev *vin)
937 vin->buf_hw[slot].buffer = NULL;
938 vin->buf_hw[slot].type = FULL;
942 rvin_fill_hw_slot(vin, slot);
944 rvin_crop_scale_comp(vin);
946 ret = rvin_setup(vin);
950 vin_dbg(vin, "Starting to capture\n");
953 rvin_write(vin, VNFC_C_FRAME, VNFC_REG);
955 vin->state = STARTING;
960 static void rvin_capture_stop(struct rvin_dev *vin)
963 rvin_write(vin, 0, VNFC_REG);
966 rvin_write(vin, rvin_read(vin, VNMC_REG) & ~VNMC_ME, VNMC_REG);
978 struct rvin_dev *vin = data;
984 spin_lock_irqsave(&vin->qlock, flags);
986 int_status = rvin_get_interrupt_status(vin);
990 rvin_ack_interrupt(vin);
994 if (vin->state == STOPPED) {
995 vin_dbg(vin, "IRQ while state stopped\n");
1000 if (vin->state == STOPPING) {
1001 vin_dbg(vin, "IRQ while state stopping\n");
1006 vnms = rvin_read(vin, VNMS_REG);
1013 if (vin->state == STARTING) {
1015 vin_dbg(vin, "Starting sync slot: %d\n", slot);
1019 vin_dbg(vin, "Capture start synced!\n");
1020 vin->state = RUNNING;
1024 if (vin->buf_hw[slot].buffer) {
1029 if (vin->buf_hw[slot].type == HALF_TOP) {
1030 vin->buf_hw[slot].buffer = NULL;
1031 rvin_fill_hw_slot(vin, slot);
1035 vin->buf_hw[slot].buffer->field =
1036 rvin_get_active_field(vin, vnms);
1037 vin->buf_hw[slot].buffer->sequence = vin->sequence;
1038 vin->buf_hw[slot].buffer->vb2_buf.timestamp = ktime_get_ns();
1039 vb2_buffer_done(&vin->buf_hw[slot].buffer->vb2_buf,
1041 vin->buf_hw[slot].buffer = NULL;
1044 vin_dbg(vin, "Dropping frame %u\n", vin->sequence);
1047 vin->sequence++;
1050 rvin_fill_hw_slot(vin, slot);
1052 spin_unlock_irqrestore(&vin->qlock, flags);
1058 static void return_all_buffers(struct rvin_dev *vin,
1066 freed[i] = vin->buf_hw[i].buffer;
1067 vin->buf_hw[i].buffer = NULL;
1080 list_for_each_entry_safe(buf, node, &vin->buf_list, list) {
1091 struct rvin_dev *vin = vb2_get_drv_priv(vq);
1095 return sizes[0] < vin->format.sizeimage ? -EINVAL : 0;
1098 sizes[0] = vin->format.sizeimage;
1105 struct rvin_dev *vin = vb2_get_drv_priv(vb->vb2_queue);
1106 unsigned long size = vin->format.sizeimage;
1109 vin_err(vin, "buffer too small (%lu < %lu)\n",
1122 struct rvin_dev *vin = vb2_get_drv_priv(vb->vb2_queue);
1125 spin_lock_irqsave(&vin->qlock, flags);
1127 list_add_tail(to_buf_list(vbuf), &vin->buf_list);
1129 spin_unlock_irqrestore(&vin->qlock, flags);
1132 static int rvin_mc_validate_format(struct rvin_dev *vin, struct v4l2_subdev *sd,
1151 if (vin->format.pixelformat != V4L2_PIX_FMT_SBGGR8)
1155 if (vin->format.pixelformat != V4L2_PIX_FMT_SGBRG8)
1159 if (vin->format.pixelformat != V4L2_PIX_FMT_SGRBG8)
1163 if (vin->format.pixelformat != V4L2_PIX_FMT_SRGGB8)
1169 vin->mbus_code = fmt.format.code;
1183 switch (vin->format.field) {
1205 if (fmt.format.width != vin->format.width ||
1206 fmt.format.height != vin->format.height ||
1207 fmt.format.code != vin->mbus_code)
1213 static int rvin_set_stream(struct rvin_dev *vin, int on)
1222 if (!vin->info->use_mc) {
1223 ret = v4l2_subdev_call(vin->parallel->subdev, video, s_stream,
1229 pad = media_entity_remote_pad(&vin->pad);
1236 media_pipeline_stop(&vin->vdev.entity);
1240 ret = rvin_mc_validate_format(vin, sd, pad);
1250 mdev = vin->vdev.entity.graph_obj.mdev;
1252 pipe = sd->entity.pipe ? sd->entity.pipe : &vin->vdev.pipe;
1253 ret = __media_pipeline_start(&vin->vdev.entity, pipe);
1262 media_pipeline_stop(&vin->vdev.entity);
1269 struct rvin_dev *vin = vb2_get_drv_priv(vq);
1274 vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage,
1275 &vin->scratch_phys, GFP_KERNEL);
1276 if (!vin->scratch) {
1277 spin_lock_irqsave(&vin->qlock, flags);
1278 return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
1279 spin_unlock_irqrestore(&vin->qlock, flags);
1280 vin_err(vin, "Failed to allocate scratch buffer\n");
1284 ret = rvin_set_stream(vin, 1);
1286 spin_lock_irqsave(&vin->qlock, flags);
1287 return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
1288 spin_unlock_irqrestore(&vin->qlock, flags);
1292 spin_lock_irqsave(&vin->qlock, flags);
1294 vin->sequence = 0;
1296 ret = rvin_capture_start(vin);
1298 return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
1299 rvin_set_stream(vin, 0);
1302 spin_unlock_irqrestore(&vin->qlock, flags);
1305 dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
1306 vin->scratch_phys);
1313 struct rvin_dev *vin = vb2_get_drv_priv(vq);
1317 spin_lock_irqsave(&vin->qlock, flags);
1319 vin->state = STOPPING;
1324 rvin_capture_stop(vin);
1327 if (!rvin_capture_active(vin)) {
1328 vin->state = STOPPED;
1332 spin_unlock_irqrestore(&vin->qlock, flags);
1334 spin_lock_irqsave(&vin->qlock, flags);
1337 if (vin->state != STOPPED) {
1343 vin_err(vin, "Failed stop HW, something is seriously broken\n");
1344 vin->state = STOPPED;
1348 return_all_buffers(vin, VB2_BUF_STATE_ERROR);
1350 spin_unlock_irqrestore(&vin->qlock, flags);
1352 rvin_set_stream(vin, 0);
1355 rvin_disable_interrupts(vin);
1358 dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
1359 vin->scratch_phys);
1372 void rvin_dma_unregister(struct rvin_dev *vin)
1374 mutex_destroy(&vin->lock);
1376 v4l2_device_unregister(&vin->v4l2_dev);
1379 int rvin_dma_register(struct rvin_dev *vin, int irq)
1381 struct vb2_queue *q = &vin->queue;
1385 ret = v4l2_device_register(vin->dev, &vin->v4l2_dev);
1389 mutex_init(&vin->lock);
1390 INIT_LIST_HEAD(&vin->buf_list);
1392 spin_lock_init(&vin->qlock);
1394 vin->state = STOPPED;
1397 vin->buf_hw[i].buffer = NULL;
1402 q->lock = &vin->lock;
1403 q->drv_priv = vin;
1409 q->dev = vin->dev;
1413 vin_err(vin, "failed to initialize VB2 queue\n");
1418 ret = devm_request_irq(vin->dev, irq, rvin_irq, IRQF_SHARED,
1419 KBUILD_MODNAME, vin);
1421 vin_err(vin, "failed to request irq\n");
1427 rvin_dma_unregister(vin);
1441 int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel)
1446 ret = pm_runtime_get_sync(vin->dev);
1448 pm_runtime_put_noidle(vin->dev);
1453 vnmc = rvin_read(vin, VNMC_REG);
1454 rvin_write(vin, vnmc & ~VNMC_VUP, VNMC_REG);
1458 rvin_write(vin, ifmd, VNCSI_IFMD_REG);
1460 vin_dbg(vin, "Set IFMD 0x%x\n", ifmd);
1463 rvin_write(vin, vnmc, VNMC_REG);
1465 pm_runtime_put(vin->dev);
1470 void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha)
1475 spin_lock_irqsave(&vin->qlock, flags);
1477 vin->alpha = alpha;
1479 if (vin->state == STOPPED)
1482 switch (vin->format.pixelformat) {
1484 dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_ABIT;
1485 if (vin->alpha)
1489 dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_A8BIT_MASK;
1490 dmr |= VNDMR_A8BIT(vin->alpha);
1496 rvin_write(vin, dmr, VNDMR_REG);
1498 spin_unlock_irqrestore(&vin->qlock, flags);